[
  {
    "path": ".devcontainer/Dockerfile",
    "content": "FROM buildpack-deps:jammy-curl\n\nARG TARGETARCH\n\n# common tools\nRUN apt update && export DEBIAN_FRONTEND=noninteractive \\\n    && apt -y install --no-install-recommends apt-utils vim htop telnet socat expect-dev tini psmisc libgit2-dev \\\n    python3 python3-pip libx11-dev libxtst-dev libxext-dev libxrandr-dev libxinerama-dev libxi-dev \\\n    libx11-6 libxrandr2 libxext6 libxrender1 libxfixes3 libxss1 libxtst6 libxi6 \\\n    xvfb x11vnc novnc xfce4 xfce4-terminal dbus-x11 dnsmasq gettext-base\n\n# build tools\nRUN apt update && export DEBIAN_FRONTEND=noninteractive \\\n    && apt -y install --no-install-recommends openjdk-11-jdk protobuf-compiler libprotobuf-dev\n\n# Mount-s3 (AWS S3 FUSE driver)\nRUN /bin/bash -c 'apt update && export DEBIAN_FRONTEND=noninteractive \\\n    && apt -y install --no-install-recommends fuse libfuse2 \\\n    && MOUNT_S3_ARCH=$([ \"$TARGETARCH\" = \"amd64\" ] && echo \"x86_64\" || echo \"arm64\") \\\n    && wget https://s3.amazonaws.com/mountpoint-s3-release/1.20.0/${MOUNT_S3_ARCH}/mount-s3-1.20.0-${MOUNT_S3_ARCH}.deb \\\n    && apt install -y ./mount-s3-1.20.0-${MOUNT_S3_ARCH}.deb \\\n    && rm -f mount-s3-1.20.0-${MOUNT_S3_ARCH}.deb'\n# Telepresence\nRUN curl -fL https://app.getambassador.io/download/tel2oss/releases/download/v2.17.0/telepresence-linux-${TARGETARCH} -o /usr/local/bin/telepresence && \\\n    chmod a+x /usr/local/bin/telepresence\n\nRUN echo \"address=/proxy.localhost/127.0.0.1\" >> /etc/dnsmasq.conf\n\nCMD [\"sh\", \"-c\", \"service dnsmasq start && echo 'nameserver 127.0.0.1' > /etc/resolv.conf && tail -f /dev/null\"]"
  },
  {
    "path": ".devcontainer/buildkitd.toml",
    "content": "insecure-entitlements = [ \"network.host\", \"security.insecure\" ]\n\n[registry.\"registry:5000\"]\n  http = true\n  insecure = true"
  },
  {
    "path": ".devcontainer/devcontainer.build.json",
    "content": "{\n  // Duplicate of devcontainer.json but without docker compose\n  // Docker compose is not supported for building and pushing the devcontainer image\n  \"name\": \"Daytona\",\n  \"build\": {\n    \"dockerfile\": \"Dockerfile\",\n    \"context\": \".\"\n  },\n  \"workspaceFolder\": \"/workspaces/daytona\",\n  // Configure tool-specific properties.\n  \"containerEnv\": {\n    \"COREPACK_ENABLE_DOWNLOAD_PROMPT\": \"0\"\n  },\n  \"remoteEnv\": {\n    \"NX_DAEMON\": \"true\",\n    \"NODE_ENV\": \"development\",\n    \"POETRY_VIRTUALENVS_IN_PROJECT\": \"true\"\n  },\n  \"customizations\": {\n    // Configure properties specific to VS Code.\n    \"vscode\": {\n      // Add the IDs of extensions you want installed when the container is created.\n      \"extensions\": [\n        \"dbaeumer.vscode-eslint\",\n        \"esbenp.prettier-vscode\",\n        \"nrwl.angular-console\",\n        \"astro-build.astro-vscode\",\n        \"unifiedjs.vscode-mdx\",\n        \"timonwong.shellcheck\",\n        \"foxundermoon.shell-format\",\n        \"cschlosser.doxdocgen\",\n        \"ms-python.python\",\n        \"ms-toolsai.jupyter\",\n        \"bradlc.vscode-tailwindcss\",\n        \"shopify.ruby-lsp\",\n        \"castwide.solargraph\"\n      ],\n      \"settings\": {\n        \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n        \"python.defaultInterpreterPath\": \"${containerWorkspaceFolder}/.venv/bin/python\",\n        \"python.terminal.activateEnvironment\": true,\n        \"python.terminal.activateEnvInCurrentTerminal\": true\n      }\n    }\n  },\n  \"features\": {\n    \"ghcr.io/devcontainers/features/common-utils:2.5.3\": {\n      \"installZsh\": \"true\",\n      \"username\": \"daytona\",\n      \"uid\": \"1000\",\n      \"gid\": \"1000\",\n      \"upgradePackages\": \"false\"\n    },\n    \"ghcr.io/devcontainers/features/docker-in-docker:2.12.2\": {\n      \"version\": \"24.0.7\",\n      \"moby\": false,\n      \"dockerDashComposeVersion\": \"v2\"\n    },\n    \"ghcr.io/devcontainers/features/go:1.3.2\": {\n      \"version\": \"1.23.5\",\n      \"golangciLintVersion\": \"1.63.4\"\n    },\n    \"ghcr.io/devcontainers/features/node:1.6.2\": {\n      \"version\": \"22.14.0\",\n      \"installYarnUsingApt\": false\n    },\n    \"ghcr.io/devcontainers/features/ruby:1\": {\n      \"version\": \"3.4.5\"\n    },\n    \"./tools-feature\": {\n      \"pipPackages\": [\"poetry==2.1.3\"],\n      \"goTools\": [\"github.com/swaggo/swag/cmd/swag@v1.16.4\", \"github.com/mitranim/gow@latest\"]\n    }\n  },\n  \"onCreateCommand\": {\n    // \"install-deps\": \"git config --global --add safe.directory ${containerWorkspaceFolder} && yarn\",\n    \"env\": \"test -f .env.local || touch .env.local\"\n  },\n  \"postStartCommand\": \"yarn && poetry lock && poetry install && bundle install\",\n  \"postAttachCommand\": \"\",\n  \"forwardPorts\": [5556, \"pgadmin:80\", \"registry-ui:5100\", \"maildev:1080\", \"minio:9000\", \"minio:9001\", \"jaeger:16686\"],\n  // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.\n  \"remoteUser\": \"daytona\"\n}\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "{\n  \"name\": \"Daytona\",\n  \"dockerComposeFile\": \"docker-compose.yaml\",\n  \"service\": \"app\",\n  \"workspaceFolder\": \"/workspaces/daytona\",\n  // Configure tool-specific properties.\n  \"containerEnv\": {\n    \"COREPACK_ENABLE_DOWNLOAD_PROMPT\": \"0\"\n  },\n  \"remoteEnv\": {\n    \"NX_DAEMON\": \"true\",\n    \"NODE_ENV\": \"development\",\n    \"POETRY_VIRTUALENVS_IN_PROJECT\": \"true\",\n    \"RUBYLIB\": \"${containerWorkspaceFolder}/libs/sdk-ruby/lib:${containerWorkspaceFolder}/libs/api-client-ruby/lib:${containerWorkspaceFolder}/libs/toolbox-api-client-ruby/lib\",\n    \"BUNDLE_GEMFILE\": \"${containerWorkspaceFolder}/Gemfile\"\n  },\n  \"customizations\": {\n    // Configure properties specific to VS Code.\n    \"vscode\": {\n      // Add the IDs of extensions you want installed when the container is created.\n      \"extensions\": [\n        \"dbaeumer.vscode-eslint\",\n        \"esbenp.prettier-vscode\",\n        \"nrwl.angular-console\",\n        \"astro-build.astro-vscode\",\n        \"unifiedjs.vscode-mdx\",\n        \"timonwong.shellcheck\",\n        \"foxundermoon.shell-format\",\n        \"cschlosser.doxdocgen\",\n        \"ms-python.python\",\n        \"ms-toolsai.jupyter\",\n        \"bradlc.vscode-tailwindcss\",\n        \"shopify.ruby-lsp\",\n        \"castwide.solargraph\"\n      ],\n      \"settings\": {\n        \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n        \"python.defaultInterpreterPath\": \"${containerWorkspaceFolder}/.venv/bin/python\",\n        \"python.terminal.activateEnvironment\": true,\n        \"python.terminal.activateEnvInCurrentTerminal\": true\n      }\n    }\n  },\n  \"features\": {\n    \"ghcr.io/devcontainers/features/common-utils:2.5.3\": {\n      \"installZsh\": \"true\",\n      \"username\": \"daytona\",\n      \"uid\": \"1000\",\n      \"gid\": \"1000\",\n      \"upgradePackages\": \"false\"\n    },\n    \"ghcr.io/devcontainers/features/docker-in-docker:2.12.2\": {\n      \"version\": \"28.4.0\",\n      \"moby\": false,\n      \"dockerDashComposeVersion\": \"v2\"\n    },\n    \"ghcr.io/devcontainers/features/go:1.3.2\": {\n      \"version\": \"1.25.4\",\n      \"golangciLintVersion\": \"2.6.2\"\n    },\n    \"ghcr.io/devcontainers/features/node:1.6.2\": {\n      \"version\": \"22.14.0\",\n      \"installYarnUsingApt\": false\n    },\n    \"ghcr.io/devcontainers/features/ruby:1\": {\n      \"version\": \"3.4.5\"\n    },\n    \"./tools-feature\": {\n      \"pipPackages\": [\n        \"poetry==2.1.3\"\n      ],\n      \"goTools\": [\n        \"github.com/swaggo/swag/cmd/swag@v1.16.4\",\n        \"github.com/mitranim/gow@latest\",\n        \"github.com/princjef/gomarkdoc/cmd/gomarkdoc@v1.1.0\"\n      ]\n    }\n  },\n  \"onCreateCommand\": {\n    // \"install-deps\": \"git config --global --add safe.directory ${containerWorkspaceFolder} && yarn\",\n    \"env\": \"test -f .env.local || touch .env.local\"\n  },\n  \"postStartCommand\": \"yarn && poetry lock && poetry install && bundle install && docker buildx create --name builder --driver-opt network=host --config .devcontainer/buildkitd.toml --driver docker-container --use\",\n  \"postAttachCommand\": \"\",\n  \"forwardPorts\": [\n    5556,\n    \"pgadmin:80\",\n    \"registry-ui:5100\",\n    \"maildev:1080\",\n    \"minio:9000\",\n    \"minio:9001\",\n    \"jaeger:16686\"\n  ],\n  // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.\n  \"remoteUser\": \"daytona\"\n}"
  },
  {
    "path": ".devcontainer/dex/config.yaml",
    "content": "# config.yaml\nissuer: http://localhost:5556/dex\nstorage:\n  type: memory\nweb:\n  http: 0.0.0.0:5556\n  allowedOrigins: ['*']\n  allowedHeaders: ['x-requested-with']\nstaticClients:\n  - id: daytona\n    redirectURIs:\n      - 'http://localhost:3000'\n      - 'http://localhost:3000/api/oauth2-redirect.html'\n      - 'http://localhost:3009/callback'\n      - 'http://proxy.localhost:4000/callback'\n    name: 'Daytona'\n    public: true\nenablePasswordDB: true\nstaticPasswords:\n  - email: 'dev@daytona.io'\n    # password generated with:\n    # echo password | htpasswd -BinC 10 admin | cut -d: -f2\n    hash: '$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W'\n    username: 'admin'\n    userID: '1234'\n"
  },
  {
    "path": ".devcontainer/docker-compose.yaml",
    "content": "version: '3.8'\n\nservices:\n  app:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    privileged: true\n    volumes:\n      - ..:/workspaces/daytona\n\n  dex:\n    image: dexidp/dex:v2.42.0\n    volumes:\n      - ./dex/config.yaml:/etc/dex/config.yaml\n    command: ['dex', 'serve', '/etc/dex/config.yaml']\n    network_mode: service:app\n\n  db:\n    image: postgres:18\n    environment:\n      - POSTGRES_PASSWORD=pass\n      - POSTGRES_USER=user\n      - POSTGRES_DB=application_ctx\n\n  pgadmin:\n    image: dpage/pgadmin4:9.2.0\n    entrypoint: ['sh', '-c', 'chmod 600 /pgpass && exec /entrypoint.sh']\n    environment:\n      PGADMIN_DEFAULT_EMAIL: dev@daytona.io\n      PGADMIN_DEFAULT_PASSWORD: pgadmin\n      PGADMIN_CONFIG_SERVER_MODE: 'False'\n      PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: 'False'\n    user: root\n    volumes:\n      - ./pgadmin4/servers.json:/pgadmin4/servers.json\n      - ./pgadmin4/pgpass:/pgpass\n    depends_on:\n      - db\n\n  redis:\n    image: redis:latest\n\n  registry-ui:\n    image: joxit/docker-registry-ui:main\n    restart: always\n    environment:\n      - SINGLE_REGISTRY=true\n      - REGISTRY_TITLE=Docker Registry UI\n      - DELETE_IMAGES=true\n      - SHOW_CONTENT_DIGEST=true\n      - NGINX_PROXY_PASS_URL=http://registry:5000\n      - SHOW_CATALOG_NB_TAGS=true\n      - CATALOG_MIN_BRANCHES=1\n      - CATALOG_MAX_BRANCHES=1\n      - TAGLIST_PAGE_SIZE=100\n      - REGISTRY_SECURED=false\n      - CATALOG_ELEMENTS_LIMIT=1000\n\n  registry:\n    image: registry:2.8.2\n    restart: always\n    environment:\n      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://registry-ui.example.com]'\n      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'\n      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'\n      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'\n      REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'\n      REGISTRY_STORAGE_DELETE_ENABLED: 'true'\n    volumes:\n      - registry:/var/lib/registry\n\n  maildev:\n    image: maildev/maildev\n\n  minio:\n    image: minio/minio:latest\n    environment:\n      - MINIO_ROOT_USER=minioadmin\n      - MINIO_ROOT_PASSWORD=minioadmin\n      - MINIO_IDENTITY_STS_EXPIRY=\"24h\"\n    volumes:\n      - minio_data:/data\n    command: server /data --console-address \":9001\"\n\n  jaeger:\n    image: jaegertracing/all-in-one:1.74.0\n\n  otel-collector:\n    image: otel/opentelemetry-collector-contrib:0.138.0\n    volumes:\n      - ./otel/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml\n\nvolumes:\n  registry: {}\n  minio_data: {}\n"
  },
  {
    "path": ".devcontainer/otel/otel-collector-config.yaml",
    "content": "receivers:\n  otlp:\n    protocols:\n      grpc:\n        endpoint: 0.0.0.0:4317\n      http:\n        endpoint: 0.0.0.0:4318\n\nprocessors:\n  batch:\n\nexporters:\n  # Logs to console\n  debug:\n    verbosity: detailed\n\n  # Metrics to Prometheus endpoint\n  prometheus:\n    endpoint: 0.0.0.0:9090\n    namespace: otel\n\n  # Traces to Jaeger\n  otlp/jaeger:\n    endpoint: jaeger:4317\n    tls:\n      insecure: true\n\nservice:\n  pipelines:\n    traces:\n      receivers: [otlp]\n      processors: [batch]\n      exporters: [otlp/jaeger]\n\n    metrics:\n      receivers: [otlp]\n      processors: [batch]\n      exporters: [prometheus]\n\n    logs:\n      receivers: [otlp]\n      processors: [batch]\n      exporters: [debug]\n"
  },
  {
    "path": ".devcontainer/pgadmin4/pgpass",
    "content": "db:5432:*:user:pass"
  },
  {
    "path": ".devcontainer/pgadmin4/servers.json",
    "content": "{\n  \"Servers\": {\n    \"1\": {\n      \"Name\": \"Daytona\",\n      \"Group\": \"Servers\",\n      \"Host\": \"db\",\n      \"Port\": 5432,\n      \"MaintenanceDB\": \"postgres\",\n      \"Username\": \"user\",\n      \"PassFile\": \"/pgpass\"\n    }\n  }\n}\n"
  },
  {
    "path": ".devcontainer/tools-feature/devcontainer-feature.json",
    "content": "{\n  \"name\": \"Development tools\",\n  \"id\": \"tools\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Installs development tools.\",\n  \"options\": {\n    \"pipPackages\": {\n      \"type\": \"array\",\n      \"description\": \"List of pip packages to install\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"goTools\": {\n      \"type\": \"array\",\n      \"description\": \"List of Go tools to install\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    }\n  },\n  \"installsAfter\": [\n    \"ghcr.io/devcontainers/features/go\",\n    \"ghcr.io/devcontainers/features/python\",\n    \"ghcr.io/devcontainers/features/ruby\",\n    \"ghcr.io/devcontainers/features/docker-in-docker\"\n  ]\n}\n"
  },
  {
    "path": ".devcontainer/tools-feature/install.sh",
    "content": "#!/bin/bash\n# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: AGPL-3.0\n\nset -e\n\necho \"Installing Python packages and Go tools...\"\n\nUSERNAME=\"${USERNAME:-\"${_REMOTE_USER:-\"automatic\"}\"}\"\n\n# Determine the appropriate non-root user\nif [ \"${USERNAME}\" = \"auto\" ] || [ \"${USERNAME}\" = \"automatic\" ]; then\n    USERNAME=\"\"\n    POSSIBLE_USERS=(\"vscode\" \"node\" \"codespace\" \"$(awk -v val=1000 -F \":\" '$3==val{print $1}' /etc/passwd)\")\n    for CURRENT_USER in \"${POSSIBLE_USERS[@]}\"; do\n        if id -u \"${CURRENT_USER}\" > /dev/null 2>&1; then\n            USERNAME=${CURRENT_USER}\n            break\n        fi\n    done\n    if [ \"${USERNAME}\" = \"\" ]; then\n        USERNAME=root\n    fi\nelif [ \"${USERNAME}\" = \"none\" ] || ! id -u \"${USERNAME}\" > /dev/null 2>&1; then\n    USERNAME=root\nfi\n\nexport GOROOT=\"${TARGET_GOROOT:-\"/usr/local/go\"}\"\nexport GOPATH=\"${TARGET_GOPATH:-\"/go\"}\"\nexport GOCACHE=/tmp/gotools/cache\n\n\nsudo -E -u \"${USERNAME}\" bash -c '\nexport PATH=$GOROOT/bin:$PATH\nexport HOME=/home/${USER}\n\n# Install pip packages\nif [ -n \"$PIPPACKAGES\" ]; then\n    echo \"Installing pip packages: $PIPPACKAGES\"\n    IFS=',' read -ra PACKAGES <<< \"${PIPPACKAGES}\"\n    pip3 install --no-cache-dir \"${PACKAGES[@]}\"\nelse\n    echo \"No pip packages specified. Skipping.\"\nfi\n\n# Install Go tools\nif [ -n \"$GOTOOLS\" ]; then\n    echo \"Installing Go tools: $GOTOOLS\"\n    IFS=',' read -ra TOOLS <<< \"${GOTOOLS}\"\n    for tool in \"${TOOLS[@]}\"; do\n        go install $tool\n    done\nelse\n    echo \"No Go tools specified. Skipping.\"\nfi\n'\n\n# Set insecure registry\ncat > /etc/docker/daemon.json <<EOF \n{\n  \"insecure-registries\": [\"registry:5000\"]\n}\nEOF\n"
  },
  {
    "path": ".dockerignore",
    "content": ".claude\n.devcontainer\n.github\n.husky\n.vscode\n.nx\nexamples\nfunctions\nimages\nnode_modules\n.env.local\ndist\n!dist/libs/computer-use-amd64\n!dist/apps/runner-amd64\n!dist/apps/snapshot-manager\ndocker\n.tmp\nlibs\n!libs/sdk-typescript\n!libs/computer-use\n!libs/common-go\n!libs/api-client\n!libs/analytics-api-client\n!libs/runner-api-client\n!libs/api-client-go\n!libs/toolbox-api-client-go\n!libs/toolbox-api-client\n!libs/sdk-go\nDockerfile"
  },
  {
    "path": ".editorconfig",
    "content": "# Editor configuration, see http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.md]\nmax_line_length = off\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".gitattributes",
    "content": "apps/runner/pkg/api/docs/** linguist-generated=true\napps/daemon/pkg/toolbox/docs/** linguist-generated=true\nlibs/api-client/** linguist-generated=true\nlibs/api-client-go/** linguist-generated=true\nlibs/api-client-python/** linguist-generated=true\nlibs/api-client-python-async/** linguist-generated=true\nlibs/api-client-ruby/** linguist-generated=true\nlibs/runner-api-client/** linguist-generated=true\nlibs/toolbox-api-client/** linguist-generated=true\nlibs/toolbox-api-client-go/** linguist-generated=true\nlibs/toolbox-api-client-python/** linguist-generated=true\nlibs/toolbox-api-client-python-async/** linguist-generated=true\nlibs/toolbox-api-client-ruby/** linguist-generated=true\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "# CODEOWNERS — Daytona\n# These owners are automatically requested for review on PRs that modify the listed files.\n\n# Security and compliance policies\nSECURITY.md          @aprojic\nCODE_OF_CONDUCT.md   @aprojic\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\ntype: Bug\nassignees: ''\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n\n1. Use these parameters '...'\n2. Click on '...'\n3. Execute the following command '...'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Environment (required fields):**\n\n- Deployment: [Production/OSS]\n- Daytona client: [e.g. Python SDK v0.0.1 or Daytona CLI v0.0.1]\n- Daytona Version: [Found in the dashboard]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\ntype: Feature\nassignees: ''\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/actions/setup-toolchain/action.yml",
    "content": "name: Setup Toolchain\ndescription: Shared setup for Go, Node, Python, Ruby, Java and project dependencies\n\ninputs:\n  install-go:\n    description: Install Go\n    default: 'true'\n  go-cache:\n    description: Enable Go module caching via actions/setup-go\n    default: 'true'\n  install-node:\n    description: Install Node.js\n    default: 'true'\n  install-python:\n    description: Install Python\n    default: 'true'\n  install-ruby:\n    description: Install Ruby\n    default: 'true'\n  install-java:\n    description: Install Java\n    default: 'true'\n  install-poetry:\n    description: Install Poetry\n    default: 'true'\n  install-swag:\n    description: Install swag CLI\n    default: 'true'\n  run-yarn-install:\n    description: Run yarn install --immutable\n    default: 'true'\n  run-poetry-install:\n    description: Run poetry lock && poetry install\n    default: 'true'\n  run-go-work-sync:\n    description: Run go work sync\n    default: 'true'\n\nruns:\n  using: composite\n  steps:\n    - name: Validate toolchain inputs\n      shell: bash\n      run: |\n        if [ \"${{ inputs.install-poetry }}\" = \"true\" ] && [ \"${{ inputs.install-python }}\" != \"true\" ]; then\n          echo \"Error: install-poetry is 'true' but install-python is not 'true'. Please enable install-python when using install-poetry.\" >&2\n          exit 1\n        fi\n        if [ \"${{ inputs.install-swag }}\" = \"true\" ] && [ \"${{ inputs.install-go }}\" != \"true\" ]; then\n          echo \"Error: install-swag is 'true' but install-go is not 'true'. Please enable install-go when using install-swag.\" >&2\n          exit 1\n        fi\n\n    - uses: actions/setup-go@v5\n      if: inputs.install-go == 'true'\n      with:\n        go-version-file: go.work\n        cache: ${{ inputs.go-cache }}\n        cache-dependency-path: |\n          **/go.sum\n\n    - uses: actions/setup-java@v4\n      if: inputs.install-java == 'true'\n      with:\n        java-version: 21\n        distribution: 'temurin'\n\n    - uses: actions/setup-python@v5\n      if: inputs.install-python == 'true'\n      with:\n        python-version: '3.12'\n\n    - uses: ruby/setup-ruby@v1\n      if: inputs.install-ruby == 'true'\n      with:\n        ruby-version: '3.4.5'\n        bundler-cache: false\n\n    - name: Bundle install\n      if: inputs.install-ruby == 'true'\n      shell: bash\n      run: |\n        bundle install\n\n    - uses: actions/setup-node@v4\n      if: inputs.install-node == 'true'\n      with:\n        node-version: 22\n\n    - name: System dependencies\n      shell: bash\n      run: |\n        sudo apt-get update && sudo apt-get install -y gcc libx11-dev libxtst-dev\n        if [[ \"${{ inputs.install-node }}\" == 'true' || \"${{ inputs.run-yarn-install }}\" == 'true' ]]; then\n          corepack enable\n        fi\n\n    - name: Install Poetry\n      if: inputs.install-poetry == 'true' && inputs.install-python == 'true'\n      shell: bash\n      run: |\n        python3 -m pip install --upgrade pip\n        python3 -m pip install \"poetry==2.1.3\"\n\n    - name: Install swag\n      if: inputs.install-swag == 'true' && inputs.install-go == 'true'\n      shell: bash\n      run: go install github.com/swaggo/swag/cmd/swag@v1.16.4\n\n    - name: Get yarn cache directory\n      if: inputs.run-yarn-install == 'true'\n      id: yarn-cache\n      shell: bash\n      run: echo \"dir=$(yarn config get cacheFolder)\" >> $GITHUB_OUTPUT\n\n    - uses: actions/cache@v4\n      if: inputs.run-yarn-install == 'true'\n      with:\n        path: ${{ steps.yarn-cache.outputs.dir }}\n        key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock') }}\n        restore-keys: yarn-${{ runner.os }}-${{ runner.arch }}-\n\n    - name: Yarn install\n      if: inputs.run-yarn-install == 'true'\n      shell: bash\n      run: yarn install --immutable\n\n    - name: Cache Poetry virtualenv\n      if: inputs.run-poetry-install == 'true'\n      uses: actions/cache@v4\n      with:\n        path: .venv\n        key: poetry-venv-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('poetry.lock') }}\n        restore-keys: poetry-venv-${{ runner.os }}-${{ runner.arch }}-\n\n    - name: Poetry install\n      if: inputs.run-poetry-install == 'true'\n      shell: bash\n      run: |\n        poetry lock\n        poetry install\n\n    - name: Go work sync\n      if: inputs.run-go-work-sync == 'true'\n      shell: bash\n      run: |\n        GONOSUMDB=github.com/daytonaio/daytona go work sync\n        go env -w GOFLAGS=\"-buildvcs=false\"\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "## Description\n\nPlease include a summary of the change or the feature being introduced. Include relevant motivation and context. List any dependencies that are required for this change.\n\n## Documentation\n\n- [ ] This change requires a documentation update\n- [ ] I have made corresponding changes to the documentation\n\n## Related Issue(s)\n\nThis PR addresses issue #X\n\n## Screenshots\n\nIf relevant, please add screenshots.\n\n## Notes\n\nPlease add any relevant notes if necessary.\n"
  },
  {
    "path": ".github/workflows/build_devcontainer.yaml",
    "content": "name: 'Build devcontainer image'\non:\n  push:\n    branches:\n      - main\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout (GitHub)\n        uses: actions/checkout@v4\n      - name: Set up QEMU for multi-architecture builds\n        uses: docker/setup-qemu-action@v3\n      - name: Setup Docker buildx for multi-architecture builds\n        uses: docker/setup-buildx-action@v3\n        with:\n          use: true\n      - name: Login to GitHub Container Registry\n        uses: docker/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.repository_owner }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n      - name: Build and release devcontainer Multi-Platform\n        uses: devcontainers/ci@v0.3\n        env:\n          # see: https://github.com/devcontainers/ci/issues/191#issuecomment-1603857155\n          BUILDX_NO_DEFAULT_ATTESTATIONS: true\n        with:\n          imageName: ghcr.io/daytonaio/daytona-devcontainer\n          cacheFrom: ghcr.io/daytonaio/daytona-devcontainer\n          platform: linux/amd64,linux/arm64\n          imageTag: main,latest\n          configFile: .devcontainer/devcontainer.build.json\n"
  },
  {
    "path": ".github/workflows/default_image_publish.yaml",
    "content": "name: Default Snapshot Images Publish\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: Version to release (e.g., \"0.1.2\")\n        required: true\n        default: '0.0.0-dev'\n      push_latest:\n        description: Push latest tags (disable for rc/pre-release)\n        type: boolean\n        default: true\n\nenv:\n  VERSION: ${{ inputs.version }}\n  BUILDX_NO_DEFAULT_ATTESTATIONS: 1\n  REGISTRY_IMAGE: daytonaio/sandbox\n\njobs:\n  docker_build:\n    strategy:\n      fail-fast: false\n      matrix:\n        include:\n          - runner: [self-hosted, Linux, ARM64, github-actions-runner-arm]\n            platform: linux/arm64\n          - runner: [self-hosted, Linux, X64, github-actions-runner-amd64]\n            platform: linux/amd64\n\n    runs-on: ${{ matrix.runner }}\n\n    steps:\n      - name: Prepare\n        run: |\n          platform=${{ matrix.platform }}\n          echo \"PLATFORM_PAIR=${platform//\\//-}\" >> $GITHUB_ENV\n\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Log in to Docker Hub\n        uses: docker/login-action@v3\n        with:\n          registry: docker.io\n          username: daytonaio\n          password: ${{ secrets.DOCKER_TOKEN }}\n\n      - name: Build and push sandbox by digest\n        id: build-sandbox\n        uses: docker/build-push-action@v6\n        with:\n          context: ./images/sandbox\n          file: ./images/sandbox/Dockerfile\n          platforms: ${{ matrix.platform }}\n          tags: ${{ env.REGISTRY_IMAGE }}\n          outputs: type=image,push-by-digest=true,name-canonical=true,push=true\n          cache-from: type=registry,ref=daytonaio/sandbox:buildcache-${{ env.PLATFORM_PAIR }}\n          cache-to: type=registry,ref=daytonaio/sandbox:buildcache-${{ env.PLATFORM_PAIR }},mode=max\n\n      - name: Export sandbox digest\n        run: |\n          mkdir -p ${{ runner.temp }}/digests/sandbox\n          digest=\"${{ steps.build-sandbox.outputs.digest }}\"\n          touch \"${{ runner.temp }}/digests/sandbox/${digest#sha256:}\"\n\n      - name: Build and push sandbox-slim by digest\n        id: build-sandbox-slim\n        uses: docker/build-push-action@v6\n        with:\n          context: ./images/sandbox-slim\n          file: ./images/sandbox-slim/Dockerfile\n          platforms: ${{ matrix.platform }}\n          tags: ${{ env.REGISTRY_IMAGE }}\n          outputs: type=image,push-by-digest=true,name-canonical=true,push=true\n          cache-from: type=registry,ref=daytonaio/sandbox:buildcache-slim-${{ env.PLATFORM_PAIR }}\n          cache-to: type=registry,ref=daytonaio/sandbox:buildcache-slim-${{ env.PLATFORM_PAIR }},mode=max\n\n      - name: Export sandbox-slim digest\n        run: |\n          mkdir -p ${{ runner.temp }}/digests/sandbox-slim\n          digest=\"${{ steps.build-sandbox-slim.outputs.digest }}\"\n          touch \"${{ runner.temp }}/digests/sandbox-slim/${digest#sha256:}\"\n\n      - name: Upload sandbox digest\n        uses: actions/upload-artifact@v4\n        with:\n          name: digests-default-${{ env.PLATFORM_PAIR }}\n          path: ${{ runner.temp }}/digests/sandbox/*\n          if-no-files-found: error\n          retention-days: 1\n\n      - name: Upload sandbox-slim digest\n        uses: actions/upload-artifact@v4\n        with:\n          name: digests-slim-${{ env.PLATFORM_PAIR }}\n          path: ${{ runner.temp }}/digests/sandbox-slim/*\n          if-no-files-found: error\n          retention-days: 1\n\n  docker_manifest:\n    needs: docker_build\n    runs-on: [self-hosted, Linux, X64, github-actions-runner-amd64]\n\n    steps:\n      - name: Download sandbox digests\n        uses: actions/download-artifact@v4\n        with:\n          path: ${{ runner.temp }}/digests/sandbox\n          pattern: digests-default-*\n          merge-multiple: true\n\n      - name: Download sandbox-slim digests\n        uses: actions/download-artifact@v4\n        with:\n          path: ${{ runner.temp }}/digests/sandbox-slim\n          pattern: digests-slim-*\n          merge-multiple: true\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Log in to Docker Hub\n        uses: docker/login-action@v3\n        with:\n          registry: docker.io\n          username: daytonaio\n          password: ${{ secrets.DOCKER_TOKEN }}\n\n      - name: Create and push sandbox manifest\n        working-directory: ${{ runner.temp }}/digests/sandbox\n        run: |\n          TAGS=\"-t ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}\"\n          if [ \"${{ inputs.push_latest }}\" = \"true\" ]; then\n            TAGS=\"$TAGS -t ${{ env.REGISTRY_IMAGE }}:latest\"\n          fi\n          docker buildx imagetools create $TAGS \\\n            $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)\n\n      - name: Create and push sandbox-slim manifest\n        working-directory: ${{ runner.temp }}/digests/sandbox-slim\n        run: |\n          TAGS=\"-t ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}-slim\"\n          if [ \"${{ inputs.push_latest }}\" = \"true\" ]; then\n            TAGS=\"$TAGS -t ${{ env.REGISTRY_IMAGE }}:latest-slim\"\n          fi\n          docker buildx imagetools create $TAGS \\\n            $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)\n\n      - name: Inspect images\n        run: |\n          docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}\n          docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ env.VERSION }}-slim\n"
  },
  {
    "path": ".github/workflows/pr_checks.yaml",
    "content": "name: '[PR] Validate code'\n\non:\n  pull_request:\n    branches:\n      - main\n\npermissions:\n  contents: read\n\nconcurrency:\n  # New commit on branch cancels running workflows of the same branch\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\nenv:\n  POETRY_VIRTUALENVS_IN_PROJECT: true\n\njobs:\n  go-work:\n    name: Go work\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.work\n          cache: true\n          cache-dependency-path: '**/go.sum'\n      - name: go work\n        run: |\n          GONOSUMDB=github.com/daytonaio/daytona go work sync\n          git diff --exit-code -- 'go.work*' '*/go.mod' '*/go.sum' || (echo \"Go workspace files are not up to date! Please run 'go work sync' and commit the changes.\" && exit 1)\n\n  cli-docs:\n    name: CLI docs\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n      - run: corepack enable\n      - name: Get yarn cache directory\n        id: yarn-cache\n        run: echo \"dir=$(yarn config get cacheFolder)\" >> $GITHUB_OUTPUT\n      - uses: actions/cache@v4\n        with:\n          path: ${{ steps.yarn-cache.outputs.dir }}\n          key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock') }}\n          restore-keys: yarn-${{ runner.os }}-${{ runner.arch }}-\n      - run: yarn install --immutable\n      - name: Check CLI reference docs are up to date\n        run: |\n          cd apps/docs\n          node tools/update-cli-reference.js --local\n          git diff --exit-code -- src/content/docs/en/tools/cli.mdx || (echo \"CLI reference docs on the docs site are out of sync! Please run 'cd apps/docs && node tools/update-cli-reference.js --local' and commit the changes.\" && exit 1)\n\n  golangci:\n    name: Go lint\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        working-directory: [apps/daemon, apps/runner, apps/cli, apps/proxy, libs/sdk-go, apps/otel-collector/exporter]\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.work\n          cache: true\n          cache-dependency-path: '**/go.sum'\n      - name: golangci-lint\n        uses: golangci/golangci-lint-action@v9\n        with:\n          version: v2.6.2\n          working-directory: ${{ matrix.working-directory }}\n          args: --timeout=5m ./...\n      - name: format\n        run: |\n          cd ${{ matrix.working-directory }}\n          go fmt ./...\n          git diff --exit-code '**/*.go' || (echo \"Code is not formatted! Please run 'go fmt ./...' and commit\" && exit 1)\n\n  lint-computer-use:\n    name: Go lint (Computer Use)\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.work\n          cache: true\n          cache-dependency-path: '**/go.sum'\n      - name: format\n        run: |\n          sudo apt-get update && sudo apt-get install -y gcc libx11-dev libxtst-dev\n          cd libs/computer-use\n          go fmt ./...\n          git diff --exit-code '**/*.go' || (echo \"Code is not formatted! Please run 'go fmt ./...' and commit\" && exit 1)\n      - name: golangci-lint\n        uses: golangci/golangci-lint-action@v9\n        with:\n          version: v2.6.2\n          working-directory: libs/computer-use\n          args: --timeout=5m ./...\n\n  lint-python:\n    name: Python lint\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-python@v5\n        with:\n          python-version: '3.12'\n      - name: Install Dependencies\n        run: |\n          corepack enable\n          python -m pip install --upgrade pip\n          pip install \"poetry==2.1.3\"\n          poetry install\n      - name: Get yarn cache directory\n        id: yarn-cache\n        run: echo \"dir=$(yarn config get cacheFolder)\" >> $GITHUB_OUTPUT\n      - uses: actions/cache@v4\n        with:\n          path: ${{ steps.yarn-cache.outputs.dir }}\n          key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock') }}\n          restore-keys: yarn-${{ runner.os }}-${{ runner.arch }}-\n      - run: yarn install --immutable\n      - name: Lint Python Code\n        run: |\n          source \"$(poetry env info --path)/bin/activate\"\n          yarn lint:py\n\n  format-lint-api-clients:\n    name: Format, lint and generate API clients\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ./.github/actions/setup-toolchain\n        with:\n          run-go-work-sync: 'false'\n      - name: generate-api-clients\n        run: |\n          source \"$(poetry env info --path)/bin/activate\"\n          go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@v1.1.0\n          echo -e 'DEFAULT_PACKAGE_VERSION=0.0.0-dev\\nDEFAULT_GEM_VERSION=0.0.0.pre.dev\\n\\nPYPI_PKG_VERSION=\\nNPM_PKG_VERSION=\\nNPM_TAG=\\nPYPI_TOKEN=\\nNPM_TOKEN=' > .env\n          mkdir -p dist/apps/api\n          yarn generate:api-client\n          yarn lint:fix\n          yarn format\n          poetry lock\n          yarn docs\n          GONOSUMDB=github.com/daytonaio/daytona go work sync\n          git diff --exit-code || (echo \"Code not formatted or linting errors! Hint: 'yarn generate:api-client', 'yarn lint:fix', 'yarn docs' and commit\" && exit 1)\n\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ./.github/actions/setup-toolchain\n      - name: Build all\n        run: |\n          source \"$(poetry env info --path)/bin/activate\"\n          VERSION=0.0.0-dev yarn build --nxBail=true\n\n  license-check:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Check AGPL License Headers\n        uses: apache/skywalking-eyes/header@main\n        with:\n          token: ${{ github.token }}\n          config: .licenserc.yaml\n          mode: 'check'\n\n      - name: Check Apache License Headers\n        uses: apache/skywalking-eyes/header@main\n        with:\n          token: ${{ github.token }}\n          config: .licenserc-clients.yaml\n          mode: 'check'\n"
  },
  {
    "path": ".github/workflows/prepare-release.yaml",
    "content": "name: Prepare Release\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: Version to release (start with \"v\")\n        required: true\n        default: 'v0.0.0-dev'\n\nenv:\n  VERSION: ${{ inputs.version }}\n  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\njobs:\n  prepare:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-tags: true\n          fetch-depth: 0\n\n      - uses: ./.github/actions/setup-toolchain\n      - uses: dev-hanz-ops/install-gh-cli-action@v0.2.1\n\n      - name: Configure git\n        run: |\n          git config --global --add safe.directory $GITHUB_WORKSPACE\n          git config --global user.name \"Daytona Release Bot\"\n          git config --global user.email \"daytona-release@users.noreply.github.com\"\n\n      - name: Create release branch\n        run: |\n          git checkout -b prepare-release-${{ inputs.version }}\n\n      - name: Prepare release\n        run: |\n          VERSION=${{ inputs.version }} yarn prepare-release\n\n      - name: Push branch and create PR\n        run: |\n          git push origin prepare-release-${{ inputs.version }}\n          gh pr create \\\n            --title \"chore: prepare release ${{ inputs.version }}\" \\\n            --body \"Automated PR to prepare release ${{ inputs.version }}\" \\\n            --base main \\\n            --head prepare-release-${{ inputs.version }}\n"
  },
  {
    "path": ".github/workflows/release.yaml",
    "content": "name: Release\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: Version to release (start with \"v\")\n        required: true\n        default: 'v0.0.0-dev'\n\nenv:\n  VERSION: ${{ inputs.version }}\n  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n  BUILDX_NO_DEFAULT_ATTESTATIONS: 1\n  DAYTONA_API_URL: ${{ secrets.DAYTONA_API_URL }}\n  DAYTONA_AUTH0_DOMAIN: ${{ secrets.DAYTONA_AUTH0_DOMAIN }}\n  DAYTONA_AUTH0_CLIENT_ID: ${{ secrets.DAYTONA_AUTH0_CLIENT_ID }}\n  DAYTONA_AUTH0_CALLBACK_PORT: ${{ secrets.DAYTONA_AUTH0_CALLBACK_PORT }}\n  DAYTONA_AUTH0_CLIENT_SECRET: ${{ secrets.DAYTONA_AUTH0_CLIENT_SECRET }}\n  DAYTONA_AUTH0_AUDIENCE: ${{ secrets.DAYTONA_AUTH0_AUDIENCE }}\n  POETRY_VIRTUALENVS_IN_PROJECT: true\n  GONOSUMDB: github.com/daytonaio/daytona\n\njobs:\n  publish:\n    runs-on: [self-hosted, Linux, X64, github-actions-runner-amd64]\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-tags: true\n          fetch-depth: 0\n\n      - uses: ./.github/actions/setup-toolchain\n        with:\n          run-go-work-sync: 'false'\n\n      - uses: dev-hanz-ops/install-gh-cli-action@v0.2.1\n\n      - name: Configure git\n        run: |\n          git config --global --add safe.directory $GITHUB_WORKSPACE\n          git config --global user.name \"Daytona Release Bot\"\n          git config --global user.email \"daytona-release@users.noreply.github.com\"\n\n      - name: Tag Go modules\n        run: |\n          git tag libs/api-client-go/${{ inputs.version }}\n          git tag libs/toolbox-api-client-go/${{ inputs.version }}\n          git tag libs/sdk-go/${{ inputs.version }}\n          git push origin libs/api-client-go/${{ inputs.version }} libs/toolbox-api-client-go/${{ inputs.version }} libs/sdk-go/${{ inputs.version }}\n\n      - name: Go work sync\n        run: |\n          GONOSUMDB=github.com/daytonaio/daytona go work sync\n          go env -w GOFLAGS=\"-buildvcs=false\"\n\n        # Write version to required folders so nx release can run\n      - name: Write package.json to required folders\n        run: |\n          mkdir dist\n          echo '{\n            \"name\": \"api\",\n            \"version\": \"0.0.0\"\n          }' > dist/package.json\n          echo '{\n            \"name\": \"api\",\n            \"version\": \"0.0.0\"\n          }' > apps/api/package.json\n          echo '{\n            \"name\": \"dashboard\",\n            \"version\": \"0.0.0\"\n          }' > apps/dashboard/package.json\n          echo '{\n            \"name\": \"docs\",\n            \"version\": \"0.0.0\"\n          }' > apps/docs/package.json\n          echo '{\n            \"name\": \"runner\",\n            \"version\": \"0.0.0\"\n          }' > apps/runner/package.json\n\n      - name: Create release\n        run: yarn nx release ${{ inputs.version }} --skip-publish --verbose\n\n  build_projects:\n    needs: publish\n    runs-on: [self-hosted, Linux, X64, github-actions-runner-amd64]\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-tags: true\n          fetch-depth: 0\n\n      - uses: ./.github/actions/setup-toolchain\n      - uses: dev-hanz-ops/install-gh-cli-action@v0.2.1\n\n      - name: Install gettext\n        run: sudo apt-get install -y gettext\n\n      - name: Configure git\n        run: |\n          git config --global --add safe.directory $GITHUB_WORKSPACE\n          git config --global user.name \"Daytona Release Bot\"\n          git config --global user.email \"daytona-release@users.noreply.github.com\"\n\n      - name: Build projects\n        run: |\n          source \"$(poetry env info --path)/bin/activate\"\n          yarn build:production\n          yarn nx build-amd64 runner --configuration=production --nxBail=true\n\n      - name: Build runner .deb package\n        run: VERSION=\"${VERSION#v}\" yarn nx package-deb runner\n\n      - name: Build CLI\n        run: |\n          cd ./apps/cli\n          GOOS=linux GOARCH=amd64 ./hack/build.sh --skip-env-file\n          GOOS=linux GOARCH=arm64 ./hack/build.sh --skip-env-file\n          GOOS=darwin GOARCH=amd64 ./hack/build.sh --skip-env-file\n          GOOS=darwin GOARCH=arm64 ./hack/build.sh --skip-env-file\n          GOOS=windows GOARCH=amd64 ./hack/build.sh --skip-env-file\n          GOOS=windows GOARCH=arm64 ./hack/build.sh --skip-env-file\n          cd ../..\n\n      - name: Upload runner to release assets\n        run: |\n          gh release upload ${{ inputs.version }} dist/apps/runner-amd64#daytona-runner-${{ inputs.version }}-amd64 --clobber\n\n      - name: Upload runner .deb to release assets\n        run: |\n          DEB_VERSION=\"${VERSION#v}\"\n          gh release upload ${{ inputs.version }} \"dist/apps/runner-deb/daytona-runner_${DEB_VERSION}_amd64.deb#daytona-runner-${DEB_VERSION}-amd64.deb\" --clobber\n\n      - name: Upload daemon to release assets\n        run: |\n          gh release upload ${{ inputs.version }} dist/apps/daemon-amd64#daytona-daemon-${{ inputs.version }}-amd64 --clobber\n\n      - name: Upload CLI to release assets\n        run: |\n          gh release upload ${{ inputs.version }} dist/apps/cli/daytona-linux-amd64#daytona-cli-${{ inputs.version }}-linux-amd64 --clobber\n          gh release upload ${{ inputs.version }} dist/apps/cli/daytona-linux-arm64#daytona-cli-${{ inputs.version }}-linux-arm64 --clobber\n          gh release upload ${{ inputs.version }} dist/apps/cli/daytona-darwin-amd64#daytona-cli-${{ inputs.version }}-darwin-amd64 --clobber\n          gh release upload ${{ inputs.version }} dist/apps/cli/daytona-darwin-arm64#daytona-cli-${{ inputs.version }}-darwin-arm64 --clobber\n          gh release upload ${{ inputs.version }} dist/apps/cli/daytona-windows-amd64.exe#daytona-cli-${{ inputs.version }}-windows-amd64.exe --clobber\n          gh release upload ${{ inputs.version }} dist/apps/cli/daytona-windows-arm64.exe#daytona-cli-${{ inputs.version }}-windows-arm64.exe --clobber\n\n      - name: Upload computer-use artifact\n        uses: actions/upload-artifact@v4\n        with:\n          name: computer-use-amd64\n          path: dist/libs/computer-use-amd64\n          retention-days: 1\n          overwrite: true\n\n      - name: Upload runner artifact\n        uses: actions/upload-artifact@v4\n        with:\n          name: runner-amd64\n          path: dist/apps/runner-amd64\n          retention-days: 1\n          overwrite: true\n\n  # Separately build docker images for AMD64 and ARM64\n  docker_build:\n    needs: build_projects\n    runs-on: ${{ matrix.runner }}\n    strategy:\n      matrix:\n        include:\n          - runner: [self-hosted, Linux, X64, github-actions-runner-amd64]\n            arch: amd64\n          - runner: [self-hosted, Linux, ARM64, github-actions-runner-arm]\n            arch: arm64\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-tags: true\n          fetch-depth: 0\n\n      - name: Download computer-use artifact\n        uses: actions/download-artifact@v4\n        with:\n          name: computer-use-amd64\n          path: dist/libs/\n\n      - name: Download runner artifact\n        uses: actions/download-artifact@v4\n        with:\n          name: runner-amd64\n          path: dist/apps/\n\n      - name: Check artifacts\n        run: |\n          ls -la dist/libs/\n          ls -la dist/apps/\n\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.work\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n\n      - name: Generate go.work.sum\n        run: GONOSUMDB=github.com/daytonaio/daytona go work sync\n\n      - name: Log in to the Container registry\n        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1\n        with:\n          registry: docker.io\n          username: daytonaio\n          password: ${{ secrets.DOCKER_TOKEN }}\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Project dependencies\n        run: corepack enable\n      - name: Get yarn cache directory\n        id: yarn-cache\n        run: echo \"dir=$(yarn config get cacheFolder)\" >> $GITHUB_OUTPUT\n      - uses: actions/cache@v4\n        with:\n          path: ${{ steps.yarn-cache.outputs.dir }}\n          key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock') }}\n          restore-keys: yarn-${{ runner.os }}-${{ runner.arch }}-\n      - run: yarn install --immutable\n\n      - name: Publish docker images\n        run: |\n          VERSION=${{ inputs.version }} ARCH=\"-${{ matrix.arch }}\" yarn docker:production\n\n  # Push combined manifest\n  docker_push_manifest:\n    needs: docker_build\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n      - name: Project dependencies\n        run: corepack enable\n      - name: Get yarn cache directory\n        id: yarn-cache\n        run: echo \"dir=$(yarn config get cacheFolder)\" >> $GITHUB_OUTPUT\n      - uses: actions/cache@v4\n        with:\n          path: ${{ steps.yarn-cache.outputs.dir }}\n          key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock') }}\n          restore-keys: yarn-${{ runner.os }}-${{ runner.arch }}-\n      - run: yarn install --immutable\n      - name: Log in to the Container registry\n        uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1\n        with:\n          registry: docker.io\n          username: daytonaio\n          password: ${{ secrets.DOCKER_TOKEN }}\n      - name: Push manifest\n        run: |\n          VERSION=${{ inputs.version }} yarn push-manifest\n\n  sync_gosum:\n    needs: build_projects\n    runs-on: [self-hosted, Linux, X64, github-actions-runner-amd64]\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-tags: true\n          fetch-depth: 0\n\n      - uses: actions/setup-go@v5\n        with:\n          go-version-file: go.work\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n      - uses: dev-hanz-ops/install-gh-cli-action@v0.2.1\n\n      - name: Configure git\n        run: |\n          git config --global user.name \"Daytona Release Bot\"\n          git config --global user.email \"daytona-release@users.noreply.github.com\"\n\n      - name: Project dependencies\n        run: corepack enable\n      - name: Get yarn cache directory\n        id: yarn-cache\n        run: echo \"dir=$(yarn config get cacheFolder)\" >> $GITHUB_OUTPUT\n      - uses: actions/cache@v4\n        with:\n          path: ${{ steps.yarn-cache.outputs.dir }}\n          key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock') }}\n          restore-keys: yarn-${{ runner.os }}-${{ runner.arch }}-\n      - run: yarn install --immutable\n\n      - name: Sync go.sum and create PR\n        run: |\n          git checkout -b sync-gosum-${{ inputs.version }}\n          GONOSUMDB=github.com/daytonaio/daytona go work sync\n          if git diff --quiet -- **/go.sum; then\n            echo \"No go.sum changes detected; skipping commit and PR creation.\"\n          else\n            git add **/go.sum\n            git commit -s -m \"chore: sync go.sum for ${{ inputs.version }}\"\n            git push origin sync-gosum-${{ inputs.version }}\n            gh pr create \\\n              --title \"chore: sync go.sum for ${{ inputs.version }}\" \\\n              --body \"Automated PR to sync go.sum after release ${{ inputs.version }}\" \\\n              --base main \\\n              --head sync-gosum-${{ inputs.version }}\n          fi\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/sdk_publish.yaml",
    "content": "name: SDK and CLI Publish\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: Version to release (start with \"v\")\n        required: true\n        default: 'v0.0.0-dev'\n      pypi_pkg_version:\n        description: 'PyPI package version (default: version)'\n        required: false\n      npm_pkg_version:\n        description: 'NPM package version (default: version)'\n        required: false\n      npm_tag:\n        description: 'NPM tag (default: latest)'\n        required: false\n        default: 'latest'\n      rubygems_pkg_version:\n        description: 'RubyGems package version (default: version)'\n        required: false\n\nenv:\n  VERSION: ${{ inputs.version }}\n  PYPI_PKG_VERSION: ${{ inputs.pypi_pkg_version || inputs.version}}\n  NPM_PKG_VERSION: ${{ inputs.npm_pkg_version || inputs.version}}\n  RUBYGEMS_PKG_VERSION: ${{ inputs.rubygems_pkg_version || inputs.version}}\n  NPM_TAG: ${{ inputs.npm_tag }}\n  NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n  PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}\n  RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}\n  POETRY_VIRTUALENVS_IN_PROJECT: true\n\njobs:\n  publish:\n    runs-on: [self-hosted, Linux, X64, github-actions-runner-amd64]\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-tags: true\n          fetch-depth: 0\n\n      - uses: ./.github/actions/setup-toolchain\n        with:\n          install-swag: 'false'\n      - uses: dev-hanz-ops/install-gh-cli-action@v0.2.1\n\n      - name: Configure git\n        run: |\n          git config --global --add safe.directory $GITHUB_WORKSPACE\n          git config --global user.name \"Daytona Release Bot\"\n          git config --global user.email \"daytona-release@users.noreply.github.com\"\n\n      - name: Configure RubyGems credentials\n        run: |\n          mkdir -p ~/.gem\n          echo \"---\" > ~/.gem/credentials\n          echo \":rubygems_api_key: $RUBYGEMS_API_KEY\" >> ~/.gem/credentials\n          chmod 0600 ~/.gem/credentials\n\n      - name: Publish projects\n        run: |\n          source \"$(poetry env info --path)/bin/activate\"\n          yarn publish\n\n  update-homebrew-tap:\n    if: ${{ inputs.npm_tag == 'latest' }}\n    needs: publish\n    runs-on: [self-hosted, Linux, X64, github-actions-runner-amd64]\n    name: Update Homebrew CLI tap\n    steps:\n      - name: Update version\n        run: |\n          curl -f -X POST -H \"Accept: application/vnd.github+json\" \\\n          -H \"Authorization: Bearer ${{ secrets.GITHUBBOT_TOKEN }}\" \\\n          https://api.github.com/repos/daytonaio/homebrew-cli/dispatches \\\n          -d \"{\\\"event_type\\\": \\\"update-version\\\", \\\"client_payload\\\": {\\\"version\\\": \\\"${{ env.VERSION }}\\\"}}\"\n"
  },
  {
    "path": ".github/workflows/translate.yaml",
    "content": "name: GT Translate\non:\n  push:\n    branches: [main]\n\njobs:\n  translate:\n    runs-on: ubuntu-latest\n    if: ${{ github.event.head_commit.author.name != 'github-actions[bot]' && !contains(github.event.head_commit.message, 'gt-translate/') }}\n    permissions:\n      contents: write\n      pull-requests: write\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: generaltranslation/translate@v0\n        with:\n          gt_api_key: ${{ secrets.GT_API_KEY }}\n          gt_project_id: ${{ secrets.GT_PROJECT_ID }}\n          config: 'apps/docs/gt.config.json'\n          inline: true\n          timeout: 3600\n          pr_branch: 'gt-translate/${{ github.ref_name }}'\n"
  },
  {
    "path": ".gitignore",
    "content": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# compiled output\ndist\ntmp\nout-tsc\n\n# dependencies\nnode_modules\npackage-lock.json\n\n# IDEs and editors\n/.idea\n.project\n.classpath\n.c9/\n*.launch\n.settings/\n*.sublime-workspace\n.cursor\n\n# IDE - VSCode\n.vscode/*\n!.vscode/settings.json\n!.vscode/tasks.json\n!.vscode/launch.json\n!.vscode/extensions.json\n\n# misc\n/.sass-cache\n/connect.lock\n/coverage\n/libpeerconnection.log\nnpm-debug.log\nyarn-error.log\ntestem.log\n/typings\n\n# System Files\n.DS_Store\nThumbs.db\n\n.nx/cache\n.nx/workspace-data\n\nvite.config.*.timestamp*\nvitest.config.*.timestamp*\n\n# yarn\n# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored\n.pnp.*\n.yarn/*\n!.yarn/patches\n!.yarn/plugins\n!.yarn/releases\n!.yarn/sdks\n!.yarn/versions\n\n.eslintcache\n.tmp/\n.env.local\n\n# Python package metadata\n*.egg-info/\n*.egg\n*.pyc\n__pycache__/\n\n# Ruby gem artifacts\n*.gem\n**/.bundle/\n**/vendor/bundle\n**/Gemfile.lock\n!/Gemfile.lock\n\nexamples/**/*.png\n\n**/.venv\n**/poetry.lock\n!/poetry.lock\n.astro\n.github/instructions/nx.instructions.md\n\ngo.work.sum\n\n.claude/worktrees"
  },
  {
    "path": ".golangci.yaml",
    "content": "version: '2'\nrun:\n  build-tags:\n    - testing\nlinters:\n  settings:\n    errcheck:\n      exclude-functions:\n        - (*github.com/gin-gonic/gin.Context).AbortWithError\n        - (*github.com/gin-gonic/gin.Context).Error\n        - io.Copy\n        - syscall.Syscall\n        - (github.com/gliderlabs/ssh.Session).Exit\n        - (io.Writer).Write\n  exclusions:\n    generated: lax\n    presets:\n      - comments\n      - common-false-positives\n      - legacy\n      - std-error-handling\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\nformatters:\n  exclusions:\n    generated: lax\n    paths:\n      - third_party$\n      - builtin$\n      - examples$\n"
  },
  {
    "path": ".husky/.gitignore",
    "content": "_\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/bin/sh\n\nyarn lint-staged\n"
  },
  {
    "path": ".licenserc-clients.yaml",
    "content": "header:\n  license:\n    spdx-id: Apache-2.0\n    copyright-owner: Daytona Platforms Inc.\n    content: |\n      Copyright Daytona Platforms Inc.\n      SPDX-License-Identifier: Apache-2.0\n    pattern: |\n      Copyright (\\d{4} )?Daytona Platforms Inc\\.\n      SPDX-License-Identifier: Apache-2\\.0\n  paths:\n    - 'libs/**/*.go'\n    - 'libs/**/*.sh'\n    - 'libs/**/*.js'\n    - 'libs/**/*.ts'\n    - 'libs/**/*.tsx'\n    - 'libs/**/*.py'\n    - 'guides/**/*.py'\n    - 'guides/**/*.ts'\n    - 'guides/**/*.go'\n    - 'guides/**/*.js'\n\n  paths-ignore:\n    - 'libs/analytics-api-client/**'\n    - 'libs/api-client/**'\n    - 'libs/runner-api-client/**'\n    - 'libs/api-client-go/**'\n    - 'libs/api-client-python/**'\n    - 'libs/api-client-python-async/**'\n    - 'libs/api-client-ruby/**'\n    - 'apps/docs/**'\n    - 'libs/computer-use/**'\n    - 'hack/**'\n    - 'libs/toolbox-api-client/**'\n    - 'libs/toolbox-api-client-python/**'\n    - 'libs/toolbox-api-client-python-async/**'\n    - 'libs/toolbox-api-client-ruby/**'\n    - 'libs/toolbox-api-client-go/**'\n\n  comment: on-failure\n"
  },
  {
    "path": ".licenserc.yaml",
    "content": "header:\n  license:\n    spdx-id: AGPL-3.0\n    copyright-owner: Daytona Platforms Inc.\n    content: |\n      Copyright Daytona Platforms Inc.\n      SPDX-License-Identifier: AGPL-3.0\n    pattern: |\n      Copyright (\\d{4} )?Daytona Platforms Inc\\.\n      SPDX-License-Identifier: AGPL-3\\.0\n  paths:\n    - '**/*.go'\n    - '**/*.sh'\n    - '**/*.js'\n    - '**/*.ts'\n    - '**/*.tsx'\n    - '**/*.py'\n\n  paths-ignore:\n    - 'libs/**'\n    - '!libs/computer-use/**'\n    - 'apps/api/src/generate-openapi.ts'\n    - 'apps/runner/pkg/api/docs/docs.go'\n    - 'examples/**'\n    - 'apps/docs/**'\n    - 'hack/**'\n    - 'guides/**'\n    - 'apps/daemon/pkg/toolbox/docs/docs.go'\n    - 'apps/dashboard/public/mockServiceWorker.js'\n\n  comment: on-failure\n"
  },
  {
    "path": ".markdownlint-cli2.jsonc",
    "content": "{\n  \"$schema\": \"https://raw.githubusercontent.com/DavidAnson/markdownlint-cli2/24eb4dce508ab81398d14d75179123fca425f12d/schema/markdownlint-cli2-config-schema.json\",\n  \"config\": {\n    \"no-emphasis-as-heading\": false,\n    \"line-length\": false,\n    \"no-inline-html\": false,\n    \"first-line-h1\": false,\n    \"no-bare-urls\": false,\n    \"no-duplicate-heading\": false,\n    \"emphasis-style\": {\n      \"style\": \"underscore\",\n    },\n    \"ol-prefix\": false,\n    \"fenced-code-language\": false,\n    \"single-title\": false,\n    \"heading-increment\": false,\n    \"table-column-count\": false,\n    \"table-pipe-style\": false,\n    \"no-empty-links\": false,\n  },\n  \"ignores\": [\n    \"**/node_modules/**\",\n    \"**/apps/docs/**\",\n    \"**/.venv/**\",\n    \"**/libs/toolbox-api-client-go/**\"\n  ],\n}"
  },
  {
    "path": ".npmrc",
    "content": "# Expose Astro dependencies for \\`pnpm\\` users\nshamefully-hoist=true"
  },
  {
    "path": ".nxignore",
    "content": ".claude/\nexamples/"
  },
  {
    "path": ".prettierignore",
    "content": "# Add files here to ignore them from prettier formatting\n/dist\n/coverage\n/.nx/cache\n/.nx/workspace-data\n*.md\n\nlibs/*api-client*/**"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"singleQuote\": true,\n  \"semi\": false,\n  \"tabWidth\": 2,\n  \"printWidth\": 120\n}\n"
  },
  {
    "path": ".rubocop.yml",
    "content": "AllCops:\n  NewCops: enable\n  TargetRubyVersion: 3.2\n\nLayout/LineLength:\n  AllowedPatterns: ['\\A\\s*#']\n  AllowCopDirectives: true\n\nStyle/Documentation:\n  Enabled: false\n\nStyle/AccessorGrouping:\n  EnforcedStyle: separated\n\n# Relax some metrics for examples\nMetrics/MethodLength:\n  Max: 25\n  Exclude:\n    - 'examples/**/*'\n\nMetrics/AbcSize:\n  Max: 25\n  Exclude:\n    - 'examples/**/*'\n\nMetrics/CyclomaticComplexity:\n  Exclude:\n    - 'examples/**/*'\n\nMetrics/PerceivedComplexity:\n  Exclude:\n    - 'examples/**/*'\n\nMetrics/BlockLength:\n  Exclude:\n    - 'examples/**/*'\n\nMetrics/ClassLength:\n  Exclude:\n    - 'examples/**/*'\n\n# Examples can use any style for string concatenation\nStyle/StringConcatenation:\n  Exclude:\n    - 'examples/**/*'\n\n# Examples don't need execute permissions\nLint/ScriptPermission:\n  Exclude:\n    - 'examples/**/*'\n"
  },
  {
    "path": ".verdaccio/config.yml",
    "content": "# path to a directory with all packages\nstorage: ../tmp/local-registry/storage\n\n# a list of other known repositories we can talk to\nuplinks:\n  npmjs:\n    url: https://registry.npmjs.org/\n    maxage: 60m\n\npackages:\n  '**':\n    # give all users (including non-authenticated users) full access\n    # because it is a local registry\n    access: $all\n    publish: $all\n    unpublish: $all\n\n    # if package is not available locally, proxy requests to npm registry\n    proxy: npmjs\n\n# log settings\nlog:\n  type: stdout\n  format: pretty\n  level: warn\n\npublish:\n  allow_offline: true # set offline to true to allow publish offline\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n  // Use IntelliSense to learn about possible attributes.\n  // Hover to view descriptions of existing attributes.\n  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"command\": \"yarn serve\",\n      \"name\": \"Debug\",\n      \"request\": \"launch\",\n      \"type\": \"node-terminal\"\n    },\n    {\n      \"command\": \"yarn serve:skip-runner\",\n      \"name\": \"Debug - Skip Runner\",\n      \"request\": \"launch\",\n      \"type\": \"node-terminal\"\n    },\n    {\n      \"command\": \"yarn serve:skip-proxy\",\n      \"name\": \"Debug - Skip Proxy\",\n      \"request\": \"launch\",\n      \"type\": \"node-terminal\"\n    },\n    {\n      \"name\": \"Runner\",\n      \"type\": \"go\",\n      \"request\": \"launch\",\n      \"mode\": \"debug\",\n      \"program\": \"${workspaceFolder}/apps/runner/cmd/runner\",\n      \"console\": \"integratedTerminal\",\n      \"envFile\": \"${workspaceFolder}/apps/runner/.env\",\n      \"output\": \"${workspaceFolder}/dist/apps/runner\",\n      \"preLaunchTask\": \"debug-build-runner\"\n    },\n    {\n      \"name\": \"Daemon\",\n      \"type\": \"go\",\n      \"request\": \"launch\",\n      \"mode\": \"debug\",\n      \"program\": \"${workspaceFolder}/apps/daemon/cmd/daemon\",\n      \"console\": \"integratedTerminal\",\n      \"output\": \"${workspaceFolder}/dist/apps/daemon\"\n    },\n    {\n      \"name\": \"Proxy\",\n      \"type\": \"go\",\n      \"request\": \"launch\",\n      \"mode\": \"debug\",\n      \"program\": \"${workspaceFolder}/apps/proxy/cmd/proxy\",\n      \"console\": \"integratedTerminal\",\n      \"envFile\": [\n        \"${workspaceFolder}/apps/proxy/.env\",\n        \"${workspaceFolder}/apps/proxy/.env.local\"\n      ],\n      \"output\": \"${workspaceFolder}/dist/apps/proxy\"\n    }\n  ]\n}"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"files.watcherExclude\": {\n    \"**/libs/api-client*/**\": true\n  }\n}\n"
  },
  {
    "path": ".vscode/tasks.json",
    "content": "{\n  \"version\": \"2.0.0\",\n  \"tasks\": [\n    {\n      \"label\": \"debug-build-runner\",\n      \"type\": \"shell\",\n      \"command\": \"yarn nx build runner --output-style=stream\",\n      \"group\": {\n        \"kind\": \"build\",\n        \"isDefault\": true\n      },\n      \"presentation\": {\n        \"reveal\": \"silent\"\n      },\n      \"problemMatcher\": [\"$go\"]\n    }\n  ]\n}\n"
  },
  {
    "path": ".yarnrc.yml",
    "content": "enableInlineHunks: true\n\nnodeLinker: node-modules\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "\n# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, caste, color, religion, or sexual\nidentity and orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the overall\n  community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or advances of\n  any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email address,\n  without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official email address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\ncodeofconduct@daytona.io.\n\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series of\nactions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or permanent\nban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within the\ncommunity.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.1, available at\n[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].\n\nCommunity Impact Guidelines were inspired by\n[Mozilla's code of conduct enforcement ladder][Mozilla CoC].\n\nFor answers to common questions about this code of conduct, see the FAQ at\n[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at\n[https://www.contributor-covenant.org/translations][translations].\n\n[homepage]: https://www.contributor-covenant.org\n[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html\n[Mozilla CoC]: https://github.com/mozilla/diversity\n[FAQ]: https://www.contributor-covenant.org/faq\n[translations]: https://www.contributor-covenant.org/translations\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Daytona\n\nThe team at Daytona welcomes contributions from the community. There are many ways to get involved!\n\nThanks for taking the time to contribute! ❤️\n\n> And if you like the project but don't have time to contribute, that's perfectly okay. There are other simple ways to support the project and show your appreciation, which we would greatly appreciate:\n>\n> - Star the project\n> - Tweet about it\n> - Contribute to our [Docs](https://github.com/daytonaio/docs/)\n> - Refer this project in your project's readme\n> - Mention the project at local meetups and tell your friends/colleagues\n\n## Code of Conduct\n\nThis project and everyone participating in it is governed by the\n[Daytona Code of Conduct](https://github.com/daytonaio/daytona?tab=coc-ov-file#readme).\nBy participating, you are expected to uphold this code. Please report unacceptable behavior\nto [info@daytona.io](mailto:info@daytona.io).\n\n## Provide Feedback\n\nYou might find things that can be improved while you are using Daytona. You can help by [submitting an issue](https://github.com/daytonaio/daytona/issues/new) when:\n\n- A new feature or an enhancement to an existing feature will improve the utility or usability of Daytona.\n- Daytona crashes, or you encounter a bug that can only be resolved by restarting Daytona.\n- An error occurs that is unrecoverable, causes Sandbox integrity problems or loss, or generally prevents you from using a Sandbox.\n\nBefore creating a new issue, please confirm that an existing issue doesn't already exist.\n\nWe will then take care of the issue as soon as possible.\n\n## Participate in the Community\n\nYou can engage with our community by:\n\n- Helping other users on [Daytona Community Slack](https://go.daytona.io/slack).\n- Improving [documentation](https://github.com/daytonaio/docs/)\n- Participating in general discussions about development and DevOps\n- Authoring new Daytona Plugins and sharing those Plugins\n- Authoring new dev containers and sharing examples\n\n## Contributing Code\n\nYou can contribute to Daytona by:\n\n- Enhancing current functionality\n- Fixing bugs\n- Adding new features and capabilities\n\nBefore starting your contribution, especially for core features, we encourage you to reach out to us on [Slack](https://go.daytona.io/slack). This allows us to ensure that your proposed feature aligns with the project's roadmap and goals. Developers are the key to making Daytona the best tool it can be, and we value input from the community.\n\nWe look forward to working with you to improve Daytona and make development environments as easy as possible for developers everywhere.\n\n### Steps to Contribute Code\n\nFollow the following steps to ensure your contribution goes smoothly.\n\n1. Read and follow the steps outlined in the [Daytona Contributing Policy](README.md#contributing).\n1. Configure your development environment by either following the guide below.\n1. [Fork](https://help.github.com/articles/working-with-forks/) the GitHub Repository allowing you to make the changes in your own copy of the repository.\n1. Create a [GitHub issue](https://github.com/daytonaio/daytona/issues) if one doesn't exist already.\n1. [Prepare your changes](/PREPARING_YOUR_CHANGES.md) and ensure your commits are descriptive. The document contains an optional commit template, if desired.\n1. Ensure that you sign off on all your commits to comply with the DCO v1.1. We have more details in [Prepare your changes](/PREPARING_YOUR_CHANGES.md).\n1. Ensure to generate new docs after making command related changes, by running `./hack/generate-cli-docs.sh` in the daytona root directory.\n1. Ensure to generate a new API client after making changes related to the API spec, by running `./hack/swagger.sh` in the daytona root directory.\n1. Ensure that you are using `yarn` as the package manager for any Node.js dependencies.\n1. Ensure that you have no lint errors. We use `golangci-lint` as our linter which you can install by following instructions found [here](https://golangci-lint.run/welcome/install/#local-installation) (or simply open Daytona in a Dev Container). You can check for linting errors by running `golangci-lint run` in the root of the project.\n1. Create a pull request on GitHub. If you're new to GitHub, read about [pull requests](https://help.github.com/articles/about-pull-requests/). You are welcome to submit your pull request for commentary or review before it is complete by creating a [draft pull request](https://help.github.com/en/articles/about-pull-requests#draft-pull-requests). Please include specific questions or items you'd like feedback on.\n1. A member of the Daytona team will review your PR within three business days (excluding any holidays) and either merge, comment, and/or assign someone for review.\n1. Work with the reviewer to complete a code review. For each change, create a new commit and push it to make changes to your pull request. When necessary, the reviewer can trigger CI to run tests prior to merging.\n1. Once you believe your pull request is ready to be reviewed, ensure the pull request is no longer a draft by [marking it ready for review](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request).\n1. The reviewer will look over your contribution and either approve it or provide comments letting you know if there is anything left to do. We try to give you the opportunity to make the required changes yourself, but in some cases, we may perform the changes ourselves if it makes sense to (minor changes or for urgent issues). We do our best to review PRs promptly, but complex changes could require more time.\n1. After completing your review, a Daytona team member will trigger merge to run all tests. Upon passing, your change will be merged into `main`, and your pull requests will be closed. All merges to `main` create a new release, and all final changes are attributed to you.\n\nNote: In some cases, we might decide that a PR should be closed without merging. We'll make sure to provide clear reasoning when this happens.\n\n### Coding Style and Conventions\n\nTo make the code base consistent, we follow a few guidelines and conventions listed below.\n\nIt is possible that the code base does not currently comply with all these guidelines.\nWhile working on a PR, if you see something that can be refactored to comply, go ahead, but keep in mind that we are not looking for massive PRs that only address that.\n\nAPI and service method conventions:\n\n1. Avoid using model names in service methods\n   - e.g. `Create` instead of `CreateSandbox`, `Find` instead of `FindSandbox`\n1. Use appropriate verbs in the UI\n   - e.g. `Create API Key` instead of `Generate API Key` since the method is called `Create`\n1. Refer to the table below for a connection between API and service methods\n\n| HTTP Method | Controller / Service / Store |\n| ----------- | ---------------------------- |\n| POST        | Create or Update             |\n| DELETE      | Delete                       |\n| PUT         | Save                         |\n| GET         | Find or List                 |\n\n#### What Does Contributing Mean for You?\n\nHere is what being a contributor means for you:\n\n- License all our contributions to the project under the AGPL 3.0 License or the Apache 2.0 License\n- Have the legal rights to license our contributions ourselves, or get permission to license them from our employers, clients, or others who may have them\n\nFor more information, see the [README](README.md) and feel free to reach out to us on [Slack](https://go.daytona.io/slack).\n"
  },
  {
    "path": "COPYRIGHT",
    "content": "Copyrights in the Daytona software are retained by their contributors.\nNo copyright assignment is required to contribute to Daytona software.\n\nWhen we refer to the 'Daytona software authors', we mean anyone who\nhas contributed to this repository.\n\nUnless otherwise noted, such as with a LICENSE file in a directory, or a\nspecific copyright notice on a file, all files in this repository are\nlicensed under the AGPL 3.0 license.\n"
  },
  {
    "path": "Gemfile",
    "content": "# frozen_string_literal: true\n\nsource 'https://rubygems.org'\n\n# Local gems from libs\ngem 'daytona_api_client', '>= 0.0.0.pre.dev', path: 'libs/api-client-ruby'\ngem 'daytona_toolbox_api_client', '>= 0.0.0.pre.dev', path: 'libs/toolbox-api-client-ruby'\ngem 'daytona', '>= 0.0.0.pre.dev', path: 'libs/sdk-ruby'\n\n# Shared development dependencies\ngroup :development do\n  gem 'pry', '~> 0.15'\n  gem 'pry-byebug'\n  gem 'rake', '~> 13.0'\n  gem 'rspec', '~> 3.6', '>= 3.6.0'\n  gem 'rubocop', '1.84.2'\n  gem 'rubocop-rake', '~> 0.7'\n  gem 'solargraph', '~> 0.57'\n  gem 'webmock', '~> 3.25'\n  gem 'yard-markdown', '~> 0.5.0'\nend\n"
  },
  {
    "path": "Gemfile.lock",
    "content": "PATH\n  remote: libs/api-client-ruby\n  specs:\n    daytona_api_client (0.0.0.pre.dev)\n      typhoeus (~> 1.0, >= 1.0.1)\n\nPATH\n  remote: libs/sdk-ruby\n  specs:\n    daytona (0.0.0.pre.dev)\n      aws-sdk-s3 (~> 1.0)\n      daytona_api_client (= 0.0.0.pre.dev)\n      daytona_toolbox_api_client (= 0.0.0.pre.dev)\n      dotenv (~> 2.0)\n      opentelemetry-exporter-otlp (~> 0.29)\n      opentelemetry-exporter-otlp-metrics (~> 0.1)\n      opentelemetry-metrics-sdk (~> 0.2)\n      opentelemetry-sdk (~> 1.4)\n      toml (~> 0.3)\n      websocket-client-simple (~> 0.6)\n\nPATH\n  remote: libs/toolbox-api-client-ruby\n  specs:\n    daytona_toolbox_api_client (0.0.0.pre.dev)\n      typhoeus (~> 1.0, >= 1.0.1)\n\nGEM\n  remote: https://rubygems.org/\n  specs:\n    addressable (2.8.8)\n      public_suffix (>= 2.0.2, < 8.0)\n    ast (2.4.3)\n    aws-eventstream (1.4.0)\n    aws-partitions (1.1209.0)\n    aws-sdk-core (3.241.4)\n      aws-eventstream (~> 1, >= 1.3.0)\n      aws-partitions (~> 1, >= 1.992.0)\n      aws-sigv4 (~> 1.9)\n      base64\n      bigdecimal\n      jmespath (~> 1, >= 1.6.1)\n      logger\n    aws-sdk-kms (1.121.0)\n      aws-sdk-core (~> 3, >= 3.241.4)\n      aws-sigv4 (~> 1.5)\n    aws-sdk-s3 (1.212.0)\n      aws-sdk-core (~> 3, >= 3.241.4)\n      aws-sdk-kms (~> 1)\n      aws-sigv4 (~> 1.5)\n    aws-sigv4 (1.12.1)\n      aws-eventstream (~> 1, >= 1.0.2)\n    backport (1.2.0)\n    base64 (0.3.0)\n    benchmark (0.5.0)\n    bigdecimal (4.0.1)\n    byebug (13.0.0)\n      reline (>= 0.6.0)\n    coderay (1.1.3)\n    crack (1.0.1)\n      bigdecimal\n      rexml\n    csv (3.3.5)\n    diff-lcs (1.6.2)\n    dotenv (2.8.1)\n    ethon (0.15.0)\n      ffi (>= 1.15.0)\n    event_emitter (0.2.6)\n    ffi (1.17.3-aarch64-linux-gnu)\n    ffi (1.17.3-aarch64-linux-musl)\n    ffi (1.17.3-arm-linux-gnu)\n    ffi (1.17.3-arm-linux-musl)\n    ffi (1.17.3-arm64-darwin)\n    ffi (1.17.3-x86_64-darwin)\n    ffi (1.17.3-x86_64-linux-gnu)\n    ffi (1.17.3-x86_64-linux-musl)\n    google-protobuf (4.33.5)\n      bigdecimal\n      rake (>= 13)\n    google-protobuf (4.33.5-aarch64-linux-gnu)\n      bigdecimal\n      rake (>= 13)\n    google-protobuf (4.33.5-aarch64-linux-musl)\n      bigdecimal\n      rake (>= 13)\n    google-protobuf (4.33.5-arm64-darwin)\n      bigdecimal\n      rake (>= 13)\n    google-protobuf (4.33.5-x86_64-darwin)\n      bigdecimal\n      rake (>= 13)\n    google-protobuf (4.33.5-x86_64-linux-gnu)\n      bigdecimal\n      rake (>= 13)\n    google-protobuf (4.33.5-x86_64-linux-musl)\n      bigdecimal\n      rake (>= 13)\n    googleapis-common-protos-types (1.22.0)\n      google-protobuf (~> 4.26)\n    hashdiff (1.2.1)\n    io-console (0.8.2)\n    jaro_winkler (1.6.1)\n    jmespath (1.6.2)\n    json (2.18.0)\n    kramdown (2.5.2)\n      rexml (>= 3.4.4)\n    kramdown-parser-gfm (1.1.0)\n      kramdown (~> 2.0)\n    language_server-protocol (3.17.0.5)\n    lint_roller (1.1.0)\n    logger (1.7.0)\n    method_source (1.1.0)\n    mutex_m (0.3.0)\n    nokogiri (1.19.1-aarch64-linux-gnu)\n      racc (~> 1.4)\n    nokogiri (1.19.1-aarch64-linux-musl)\n      racc (~> 1.4)\n    nokogiri (1.19.1-arm-linux-gnu)\n      racc (~> 1.4)\n    nokogiri (1.19.1-arm-linux-musl)\n      racc (~> 1.4)\n    nokogiri (1.19.1-arm64-darwin)\n      racc (~> 1.4)\n    nokogiri (1.19.1-x86_64-darwin)\n      racc (~> 1.4)\n    nokogiri (1.19.1-x86_64-linux-gnu)\n      racc (~> 1.4)\n    nokogiri (1.19.1-x86_64-linux-musl)\n      racc (~> 1.4)\n    observer (0.1.2)\n    open3 (0.2.1)\n    opentelemetry-api (1.7.0)\n    opentelemetry-common (0.23.0)\n      opentelemetry-api (~> 1.0)\n    opentelemetry-exporter-otlp (0.31.1)\n      google-protobuf (>= 3.18)\n      googleapis-common-protos-types (~> 1.3)\n      opentelemetry-api (~> 1.1)\n      opentelemetry-common (~> 0.20)\n      opentelemetry-sdk (~> 1.10)\n      opentelemetry-semantic_conventions\n    opentelemetry-exporter-otlp-metrics (0.6.1)\n      google-protobuf (>= 3.18, < 5.0)\n      googleapis-common-protos-types (~> 1.3)\n      opentelemetry-api (~> 1.1)\n      opentelemetry-common (~> 0.20)\n      opentelemetry-metrics-api (~> 0.2)\n      opentelemetry-metrics-sdk (~> 0.5)\n      opentelemetry-sdk (~> 1.2)\n      opentelemetry-semantic_conventions\n    opentelemetry-metrics-api (0.4.0)\n      opentelemetry-api (~> 1.0)\n    opentelemetry-metrics-sdk (0.11.2)\n      opentelemetry-api (~> 1.1)\n      opentelemetry-metrics-api (~> 0.2)\n      opentelemetry-sdk (~> 1.2)\n    opentelemetry-registry (0.4.0)\n      opentelemetry-api (~> 1.1)\n    opentelemetry-sdk (1.10.0)\n      opentelemetry-api (~> 1.1)\n      opentelemetry-common (~> 0.20)\n      opentelemetry-registry (~> 0.2)\n      opentelemetry-semantic_conventions\n    opentelemetry-semantic_conventions (1.36.0)\n      opentelemetry-api (~> 1.0)\n    ostruct (0.6.3)\n    parallel (1.27.0)\n    parser (3.3.10.1)\n      ast (~> 2.4.1)\n      racc\n    parslet (2.0.0)\n    prism (1.8.0)\n    pry (0.16.0)\n      coderay (~> 1.1)\n      method_source (~> 1.0)\n      reline (>= 0.6.0)\n    pry-byebug (3.12.0)\n      byebug (~> 13.0)\n      pry (>= 0.13, < 0.17)\n    public_suffix (7.0.2)\n    racc (1.8.1)\n    rainbow (3.1.1)\n    rake (13.3.1)\n    rbs (3.10.2)\n      logger\n    regexp_parser (2.11.3)\n    reline (0.6.3)\n      io-console (~> 0.5)\n    reverse_markdown (3.0.2)\n      nokogiri\n    rexml (3.4.4)\n    rspec (3.13.2)\n      rspec-core (~> 3.13.0)\n      rspec-expectations (~> 3.13.0)\n      rspec-mocks (~> 3.13.0)\n    rspec-core (3.13.6)\n      rspec-support (~> 3.13.0)\n    rspec-expectations (3.13.5)\n      diff-lcs (>= 1.2.0, < 2.0)\n      rspec-support (~> 3.13.0)\n    rspec-mocks (3.13.7)\n      diff-lcs (>= 1.2.0, < 2.0)\n      rspec-support (~> 3.13.0)\n    rspec-support (3.13.6)\n    rubocop (1.84.2)\n      json (~> 2.3)\n      language_server-protocol (~> 3.17.0.2)\n      lint_roller (~> 1.1.0)\n      parallel (~> 1.10)\n      parser (>= 3.3.0.2)\n      rainbow (>= 2.2.2, < 4.0)\n      regexp_parser (>= 2.9.3, < 3.0)\n      rubocop-ast (>= 1.49.0, < 2.0)\n      ruby-progressbar (~> 1.7)\n      unicode-display_width (>= 2.4.0, < 4.0)\n    rubocop-ast (1.49.0)\n      parser (>= 3.3.7.2)\n      prism (~> 1.7)\n    rubocop-rake (0.7.1)\n      lint_roller (~> 1.1)\n      rubocop (>= 1.72.1)\n    ruby-progressbar (1.13.0)\n    solargraph (0.58.2)\n      ast (~> 2.4.3)\n      backport (~> 1.2)\n      benchmark (~> 0.4)\n      bundler (>= 2.0)\n      diff-lcs (~> 1.4)\n      jaro_winkler (~> 1.6, >= 1.6.1)\n      kramdown (~> 2.3)\n      kramdown-parser-gfm (~> 1.1)\n      logger (~> 1.6)\n      observer (~> 0.1)\n      open3 (~> 0.2.1)\n      ostruct (~> 0.6)\n      parser (~> 3.0)\n      prism (~> 1.4)\n      rbs (>= 3.6.1, <= 4.0.0.dev.4)\n      reverse_markdown (~> 3.0)\n      rubocop (~> 1.76)\n      thor (~> 1.0)\n      tilt (~> 2.0)\n      yard (~> 0.9, >= 0.9.24)\n      yard-activesupport-concern (~> 0.0)\n      yard-solargraph (~> 0.1)\n    thor (1.5.0)\n    tilt (2.7.0)\n    toml (0.3.0)\n      parslet (>= 1.8.0, < 3.0.0)\n    typhoeus (1.5.0)\n      ethon (>= 0.9.0, < 0.16.0)\n    unicode-display_width (3.2.0)\n      unicode-emoji (~> 4.1)\n    unicode-emoji (4.2.0)\n    webmock (3.26.1)\n      addressable (>= 2.8.0)\n      crack (>= 0.3.2)\n      hashdiff (>= 0.4.0, < 2.0.0)\n    websocket (1.2.11)\n    websocket-client-simple (0.9.0)\n      base64\n      event_emitter\n      mutex_m\n      websocket\n    yard (0.9.38)\n    yard-activesupport-concern (0.0.1)\n      yard (>= 0.8)\n    yard-markdown (0.5.0)\n      csv\n      yard\n    yard-solargraph (0.1.0)\n      yard (~> 0.9)\n\nPLATFORMS\n  aarch64-linux\n  aarch64-linux-gnu\n  aarch64-linux-musl\n  arm-linux-gnu\n  arm-linux-musl\n  arm64-darwin\n  x86_64-darwin\n  x86_64-linux-gnu\n  x86_64-linux-musl\n\nDEPENDENCIES\n  daytona (>= 0.0.0.pre.dev)!\n  daytona_api_client (>= 0.0.0.pre.dev)!\n  daytona_toolbox_api_client (>= 0.0.0.pre.dev)!\n  pry (~> 0.15)\n  pry-byebug\n  rake (~> 13.0)\n  rspec (~> 3.6, >= 3.6.0)\n  rubocop (= 1.84.2)\n  rubocop-rake (~> 0.7)\n  solargraph (~> 0.57)\n  webmock (~> 3.25)\n  yard-markdown (~> 0.5.0)\n\nBUNDLED WITH\n   2.6.9\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU Affero General Public License is a free, copyleft license for\nsoftware and other kinds of works, specifically designed to ensure\ncooperation with the community in the case of network server software.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nour General Public Licenses are intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  Developers that use our General Public Licenses protect your rights\nwith two steps: (1) assert copyright on the software, and (2) offer\nyou this License which gives you legal permission to copy, distribute\nand/or modify the software.\n\n  A secondary benefit of defending all users' freedom is that\nimprovements made in alternate versions of the program, if they\nreceive widespread use, become available for other developers to\nincorporate.  Many developers of free software are heartened and\nencouraged by the resulting cooperation.  However, in the case of\nsoftware used on network servers, this result may fail to come about.\nThe GNU General Public License permits making a modified version and\nletting the public access it on a server without ever releasing its\nsource code to the public.\n\n  The GNU Affero General Public License is designed specifically to\nensure that, in such cases, the modified source code becomes available\nto the community.  It requires the operator of a network server to\nprovide the source code of the modified version running there to the\nusers of that server.  Therefore, public use of a modified version, on\na publicly accessible server, gives the public access to the source\ncode of the modified version.\n\n  An older license, called the Affero General Public License and\npublished by Affero, was designed to accomplish similar goals.  This is\na different license, not a version of the Affero GPL, but Affero has\nreleased a new version of the Affero GPL which permits relicensing under\nthis license.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU Affero General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Remote Network Interaction; Use with the GNU General Public License.\n\n  Notwithstanding any other provision of this License, if you modify the\nProgram, your modified version must prominently offer all users\ninteracting with it remotely through a computer network (if your version\nsupports such interaction) an opportunity to receive the Corresponding\nSource of your version by providing access to the Corresponding Source\nfrom a network server at no charge, through some standard or customary\nmeans of facilitating copying of software.  This Corresponding Source\nshall include the Corresponding Source for any work covered by version 3\nof the GNU General Public License that is incorporated pursuant to the\nfollowing paragraph.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the work with which it is combined will remain governed by version\n3 of the GNU General Public License.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU Affero General Public License from time to time.  Such new versions\nwill be similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU Affero General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU Affero General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU Affero General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Affero General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU Affero General Public License for more details.\n\n    You should have received a copy of the GNU Affero General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If your software can interact with users remotely through a computer\nnetwork, you should also make sure that it provides a way for users to\nget its source.  For example, if your program is a web application, its\ninterface could display a \"Source\" link that leads users to an archive\nof the code.  There are many ways you could offer source, and different\nsolutions will be better for different programs; see section 13 for the\nspecific requirements.\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU AGPL, see\n<https://www.gnu.org/licenses/>."
  },
  {
    "path": "NOTICE",
    "content": "Daytona\nCopyright the various Daytona software authors.\n\nThe initial developer of the software is Daytona Platforms, Inc. (https://daytona.io).\nCopyright 2025 Daytona Platforms, Inc. All Rights Reserved.\n"
  },
  {
    "path": "PACKAGING.md",
    "content": "# Packaging Guidelines for Daytona\n\nThe Daytona team appreciates any efforts to make our software more accessible to users on various platforms.\nWhile we encourage packaging and distribution of our open-source project, we have some important guidelines, particularly regarding naming.\n\n## Critical Naming Guideline\n\n**Important**: While you are free to package and distribute our software, you **MUST NOT** name your package `daytona` or, in any way, suggest that, the package you distribute, is an official distribution of `daytona`. This restriction is to prevent confusion and maintain the integrity of our project identity.\n\n- Acceptable: \"unofficial-daytona-package\", \"unofficial-daytona-distribution\", etc.\n- Not Acceptable: \"daytona\", \"official-daytona\", etc.\n\n## General Guidelines\n\n1. **License Compliance**: Ensure that the AGPL 3.0/Apache 2.0 license is included with the package and that all copyright notices are preserved.\n\n2. **Version Accuracy**: Use the exact version number of Daytona that you are packaging. Do not modify the version number or add custom suffixes without explicit permission.\n\n3. **Dependencies**: Include all necessary dependencies as specified in our project documentation. Do not add extra dependencies without consulting the project maintainers.\n\n4. **Modifications**: If you need to make any modifications to the source code for packaging purposes, please document these changes clearly and consider submitting them as pull requests to the main project.\n\n5. **Standard Note**: Please include the following standard note in your package description or metadata:\n\n   ```\n   This package contains an unofficial distribution of Daytona, an open source project\n   developed by Daytona Platforms Inc. This package is not officially supported or endorsed\n   by the Daytona project. For the official version, please visit https://github.com/daytonaio/daytona.\n   ```\n\n## Feedback and Questions\n\nIf you have any questions about packaging Daytona or need clarification on these guidelines, especially regarding naming conventions, please open an issue in our GitHub repository.\n\nWe appreciate your contribution to making Daytona more accessible to users across different platforms, while respecting our project's identity!\n"
  },
  {
    "path": "PREPARING_YOUR_CHANGES.md",
    "content": "# Preparing Your Changes\n\nThis document contains information related to preparing changes for a pull request. Here's a quick checklist for a good PR, more details below:\n\n1. A discussion around the change on [Slack](https://go.daytona.io/slack) or in an issue.\n1. A GitHub Issue with a good description associated with the PR\n1. One feature/change per PR\n1. One commit per PR\n1. PR rebased on main (git rebase, not git pull)\n1. Good descriptive commit message, with link to issue\n1. No changes to code not directly related to your PR\n1. Includes functional/integration test\n1. Includes documentation\n\n## Commit Message Format\n\nWe do not require a particular commit message format of any kind, but we do require that individual commits be descriptive, relative to size and impact.\nFor example, if a descriptive title covers what the commit does in practice, then an additional description below the title is not required.\nHowever, if the commit has an out-sized impact relative to other commits, its description will need to reflect that.\n\nReviewers may ask you to amend your commits if they are not descriptive enough.\nSince the descriptiveness of a commit is subjective, please feel free to talk to us on [Slack](https://go.daytona.io/slack) if you have any questions.\n\n### Optional Commit Template\n\nIf you would like an optional commit template, see the following:\n\n```text\n<present-tense-verb-with-capitalized-first-letter> <everything-else-without-punctuation-at-the-end>\n\n<sentences-in-paragraph-format-or-bullet-points>\n```\n\n## Squashed Commits\n\nWe require that you squash all changes to a single commit. You can do this with the `git rebase -i HEAD~X` command where X is the number of commits you want to squash. See the [Git Documentation](https://git-scm.com/book/en/v2/Git-Branching-Rebasing) for more details.\n\n## Developer's Certificate of Origin\n\nAny contributions to Daytona must only contain code that can legally be contributed to Daytona, and which the Daytona project can distribute under its license.\n\nPrior to contributing to Daytona please read the [Developer's Certificate of Origin](https://developercertificate.org/) and sign-off all commits with the `--signoff` option provided by `git commit`. For example:\n\n```\ngit commit --signoff --message \"This is the commit message\"\n```\n\nThis option adds a `Signed-off-by` trailer at the end of the commit log message.\n\n## DCO Policy on Real Names\n\nThe DCO is a representation by someone stating they have the right to contribute the code they have proposed and is important for legal purposes. We have adopted the CNCF DCO Guidelines (https://github.com/cncf/foundation/blob/main/dco-guidelines.md). Which for simplicity we will include here in full:\n\n### DCO Guidelines v1.1\n\nThe DCO is a representation by someone stating they have the right to contribute the code they have proposed for acceptance into a project: https://developercertificate.org\n\nThat representation is important for legal purposes and was the community-developed outcome after a $1 billion [lawsuit](https://en.wikipedia.org/wiki/SCO%E2%80%93Linux_disputes) by SCO against IBM. The representation is designed to prevent issues but also keep the burden on contributors low. It has proven very adaptable to other projects, is built into git itself (and now also GitHub), and is in use by thousands of projects to avoid more burdensome requirements to contribute (such as a CLA).\n\n### DCO and Real Names\n\nThe DCO requires the use of a real name that can be used to identify someone in case there is an issue about a contribution they made.\n\n**A real name does not require a legal name, nor a birth name, nor any name that appears on an official ID (e.g. a passport). Your real name is the name you convey to people in the community for them to use to identify you as you. The key concern is that your identification is sufficient enough to contact you if an issue were to arise in the future about your contribution.**\n\nYour real name should not be an anonymous id or false name that misrepresents who you are.\n"
  },
  {
    "path": "PUBLISHING.md",
    "content": "# Publishing Daytona SDKs\n\nThis document describes how to publish the Daytona SDKs (Python, TypeScript, and Ruby) to their respective package registries.\n\n## Table of Contents\n\n- [Prerequisites](#prerequisites)\n- [Python SDK (PyPI)](#python-sdk-pypi)\n- [TypeScript SDK (npm)](#typescript-sdk-npm)\n- [Ruby SDK (RubyGems)](#ruby-sdk-rubygems)\n- [Automated Publishing (CI/CD)](#automated-publishing-cicd)\n- [Version Management](#version-management)\n\n## Prerequisites\n\nBefore publishing any SDK, ensure you have:\n\n1. **Maintainer Access**: Write access to the Daytona repository\n2. **Package Registry Credentials**:\n   - PyPI: Token with upload permissions\n   - npm: Token with publish permissions\n   - RubyGems: API key with push permissions\n3. **Local Development Setup**:\n   - All dependencies installed (`yarn install`)\n   - SDKs built successfully\n   - Tests passing\n\n## Python SDK (PyPI)\n\n### Using Nx\n\n```bash\n# From repository root\nexport PYPI_TOKEN=\"your-pypi-token\"\nexport PYPI_PKG_VERSION=\"X.Y.Z\" # pre-release format example: \"X.Y.Za1\"\nyarn nx publish sdk-python\n```\n\n**Note**: [Guide](https://packaging.python.org/en/latest/discussions/versioning/) for versioning Python packages.\n\n## TypeScript SDK (npm)\n\n### Using Nx\n\n```bash\n# From repository root\nexport NPM_TOKEN=\"your-npm-token\"\nexport NPM_PKG_VERSION=\"X.Y.Z\" # pre-release format example: \"X.Y.Z-alpha.1\"\nexport NPM_TAG=\"latest\"  # or \"beta\", \"alpha\", etc.\nyarn nx publish sdk-typescript\n```\n\n**Note**: NPM packages must have [SemVer-aligned formats](https://semver.org/).\n\n## Ruby SDK (RubyGems)\n\n### Using Nx\n\n```bash\n# From repository root\nexport RUBYGEMS_API_KEY=\"your-rubygems-api-key\"\nexport RUBYGEMS_PKG_VERSION=\"X.Y.Z\" # pre-release format example: \"X.Y.Z.alpha.1\"\nyarn nx publish sdk-ruby\n```\n\n**Note**: [Guide](https://guides.rubygems.org/patterns/#prerelease-gems) for versioning Ruby gems.\n\n## Automated Publishing (CI/CD)\n\n### GitHub Actions Workflow\n\nThe repository includes a GitHub Actions workflow for automated publishing: `.github/workflows/sdk_publish.yaml`\n\n#### Triggering a Release\n\n1. Go to **Actions** → **SDK and CLI Publish** in the GitHub repository\n2. Click **Run workflow**\n3. Fill in the parameters:\n   - **version**: The version to release (e.g., `v0.126.0`)\n   - **pypi_pkg_version**: (Optional) Override PyPI version\n   - **npm_pkg_version**: (Optional) Override npm version\n   - **rubygems_pkg_version**: (Optional) Override RubyGems version\n   - **npm_tag**: npm dist-tag (default: `latest`)\n\n#### Required Secrets\n\nEnsure these secrets are configured in GitHub repository settings:\n\n- `PYPI_TOKEN`: PyPI API token\n- `NPM_TOKEN`: npm access token\n- `RUBYGEMS_API_KEY`: RubyGems API key\n- `GITHUBBOT_TOKEN`: GitHub token for Homebrew tap updates\n\n### What the Workflow Does\n\n1. Checks out the code\n2. Sets up all required environments (Go, Java, Python, Node.js, Ruby)\n3. Installs dependencies\n4. Configures credentials for all package registries\n5. Runs `yarn publish` which uses Nx to publish all SDKs in the correct order\n6. Updates the Homebrew tap (for the CLI)\n\n## Version Management\n\n### Version Format\n\n`MAJOR.MINOR.PATCH` releases follow semantics:\n\n- **MAJOR**: Breaking changes\n- **MINOR**: New features (backward compatible)\n- **PATCH**: Bug fixes (backward compatible)\n\nPrerelease formats depend on SDK language:\n\n1. For **Typescript** (npm) follow semantic versioning ([SemVer](https://semver.org/)): `MAJOR.MINOR.PATCH`\n\n   For pre-releases, use:\n\n   - `0.126.0-alpha.1` - Alpha release\n   - `0.126.0-beta.1` - Beta release\n   - `0.126.0-rc.1` - Release candidate\n\n2. For **Python** (PyPI) follow Python packages versioning [guide](https://packaging.python.org/en/latest/discussions/versioning/):\n\n   For pre-releases, use:\n\n   - `1.2.0a1` - Alpha release\n   - `1.2.0b1` - Beta release\n   - `1.2.0rc1` - Release candidate\n\n3. For **Ruby** (gem) follow Ruby gems versioning [guide](https://guides.rubygems.org/patterns/#prerelease-gems):\n\n   For pre-releases, use:\n\n   - `0.126.0.alpha.1` - Alpha release\n   - `0.126.0.beta.1` - Beta release\n   - `0.126.0.rc.1` - Release candidate\n\n### Checking Published Versions\n\n#### PyPI\n\n```bash\npip index versions daytona\n# or\ncurl -s https://pypi.org/pypi/daytona/json | jq -r .info.version\n```\n\n#### npm\n\n```bash\nnpm view @daytonaio/sdk version\n# or\nnpm info @daytonaio/sdk\n```\n\n#### RubyGems\n\n```bash\ngem search daytona --remote --exact\n# or\ngem info daytona --remote\n```\n\n## References\n\n- [Semantic Versioning](https://semver.org/)\n- [Python packages versioning](https://packaging.python.org/en/latest/discussions/versioning/)\n- [Ruby gems versioning guide](https://guides.rubygems.org/patterns/#prerelease-gems)\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n\n[![Documentation](https://img.shields.io/github/v/release/daytonaio/docs?label=Docs&color=23cc71)](https://www.daytona.io/docs)\n![License](https://img.shields.io/badge/License-AGPL--3-blue)\n[![Go Report Card](https://goreportcard.com/badge/github.com/daytonaio/daytona)](https://goreportcard.com/report/github.com/daytonaio/daytona)\n[![Issues - daytona](https://img.shields.io/github/issues/daytonaio/daytona)](https://github.com/daytonaio/daytona/issues)\n![GitHub Release](https://img.shields.io/github/v/release/daytonaio/daytona)\n\n</div>\n\n&nbsp;\n\n<div align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/daytonaio/daytona/raw/main/assets/images/Daytona-logotype-white.png\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/daytonaio/daytona/raw/main/assets/images/Daytona-logotype-black.png\">\n    <img alt=\"Daytona logo\" src=\"https://github.com/daytonaio/daytona/raw/main/assets/images/Daytona-logotype-black.png\" width=\"50%\">\n  </picture>\n</div>\n\n<h3 align=\"center\">\n  Run AI Code.\n  <br/>\n  Secure and Elastic Infrastructure for\n  Running Your AI-Generated Code.\n</h3>\n\n<p align=\"center\">\n    <a href=\"https://www.daytona.io/docs\"> Documentation </a>·\n    <a href=\"https://github.com/daytonaio/daytona/issues/new?assignees=&labels=bug&projects=&template=bug_report.md&title=%F0%9F%90%9B+Bug+Report%3A+\"> Report Bug </a>·\n    <a href=\"https://github.com/daytonaio/daytona/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.md&title=%F0%9F%9A%80+Feature%3A+\"> Request Feature </a>·\n    <a href=\"https://go.daytona.io/slack\"> Join our Slack </a>·\n    <a href=\"https://x.com/daytonaio\"> Connect on X </a>\n</p>\n\n<p align=\"center\">\n    <a href=\"https://www.producthunt.com/posts/daytona-2?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-daytona&#0045;2\" target=\"_blank\"><img src=\"https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=957617&theme=neutral&period=daily&t=1746176740150\" alt=\"Daytona&#0032; - Secure&#0032;and&#0032;elastic&#0032;infra&#0032;for&#0032;running&#0032;your&#0032;AI&#0045;generated&#0032;code&#0046; | Product Hunt\" style=\"width: 250px; height: 54px;\" width=\"250\" height=\"54\" /></a>\n    <a href=\"https://www.producthunt.com/posts/daytona-2?embed=true&utm_source=badge-top-post-topic-badge&utm_medium=badge&utm_souce=badge-daytona&#0045;2\" target=\"_blank\"><img src=\"https://api.producthunt.com/widgets/embed-image/v1/top-post-topic-badge.svg?post_id=957617&theme=neutral&period=monthly&topic_id=237&t=1746176740150\" alt=\"Daytona&#0032; - Secure&#0032;and&#0032;elastic&#0032;infra&#0032;for&#0032;running&#0032;your&#0032;AI&#0045;generated&#0032;code&#0046; | Product Hunt\" style=\"width: 250px; height: 54px;\" width=\"250\" height=\"54\" /></a>\n</p>\n\n---\n\n## Installation\n\n### Python SDK\n\n```bash\npip install daytona\n```\n\n### TypeScript SDK\n\n```bash\nnpm install @daytonaio/sdk\n```\n\n---\n\n## Features\n\n- **Lightning-Fast Infrastructure**: Sub-90ms Sandbox creation from code to execution.\n- **Separated & Isolated Runtime**: Execute AI-generated code with zero risk to your infrastructure.\n- **Massive Parallelization for Concurrent AI Workflows**: Fork Sandbox filesystem and memory state (Coming soon!)\n- **Programmatic Control**: File, Git, LSP, and Execute API\n- **Unlimited Persistence**: Your Sandboxes can live forever\n- **OCI/Docker Compatibility**: Use any OCI/Docker image to create a Sandbox\n\n---\n\n## Quick Start\n\n1. Create an account at https://app.daytona.io\n1. Generate a [new API key](https://app.daytona.io/dashboard/keys)\n1. Follow the [Getting Started docs](https://www.daytona.io/docs/getting-started/) to start using the Daytona SDK\n\n## Creating your first Sandbox\n\n### Python SDK\n\n```py\nfrom daytona import Daytona, DaytonaConfig, CreateSandboxBaseParams\n\n# Initialize the Daytona client\ndaytona = Daytona(DaytonaConfig(api_key=\"YOUR_API_KEY\"))\n\n# Create the Sandbox instance\nsandbox = daytona.create(CreateSandboxBaseParams(language=\"python\"))\n\n# Run code securely inside the Sandbox\nresponse = sandbox.process.code_run('print(\"Sum of 3 and 4 is \" + str(3 + 4))')\nif response.exit_code != 0:\n    print(f\"Error running code: {response.exit_code} {response.result}\")\nelse:\n    print(response.result)\n\n# Clean up the Sandbox\ndaytona.delete(sandbox)\n```\n\n### Typescript SDK\n\n```jsx\nimport { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  // Initialize the Daytona client\n  const daytona = new Daytona({\n    apiKey: 'YOUR_API_KEY',\n  })\n\n  let sandbox\n  try {\n    // Create the Sandbox instance\n    sandbox = await daytona.create({\n      language: 'typescript',\n    })\n    // Run code securely inside the Sandbox\n    const response = await sandbox.process.codeRun('console.log(\"Sum of 3 and 4 is \" + (3 + 4))')\n    if (response.exitCode !== 0) {\n      console.error('Error running code:', response.exitCode, response.result)\n    } else {\n      console.log(response.result)\n    }\n  } catch (error) {\n    console.error('Sandbox flow error:', error)\n  } finally {\n    if (sandbox) await daytona.delete(sandbox)\n  }\n}\n\nmain().catch(console.error)\n```\n\n### Go SDK\n\n```go\npackage main\n\nimport (\n \"context\"\n \"fmt\"\n \"log\"\n \"time\"\n\n \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n // Initialize the Daytona client with DAYTONA_API_KEY in env\n  // Alternative is to use daytona.NewClientWithConfig(...) for more specific config\n client, err := daytona.NewClient()\n if err != nil {\n  log.Fatalf(\"Failed to create client: %v\", err)\n }\n\n ctx := context.Background()\n\n // Create the Sandbox instance\n params := types.SnapshotParams{\n  SandboxBaseParams: types.SandboxBaseParams{\n   Language: types.CodeLanguagePython,\n  },\n }\n\n sandbox, err := client.Create(ctx, params, daytona.WithTimeout(90*time.Second))\n if err != nil {\n  log.Fatalf(\"Failed to create sandbox: %v\", err)\n }\n\n // Run code securely inside the Sandbox\n response, err := sandbox.Process.ExecuteCommand(ctx, `python3 -c \"print('Sum of 3 and 4 is', 3 + 4)\"`)\n if err != nil {\n  log.Fatalf(\"Failed to execute command: %v\", err)\n }\n\n if response.ExitCode != 0 {\n  fmt.Printf(\"Error running code: %d %s\\n\", response.ExitCode, response.Result)\n } else {\n  fmt.Println(response.Result)\n }\n\n // Clean up the Sandbox\n if err := sandbox.Delete(ctx); err != nil {\n  log.Fatalf(\"Failed to delete sandbox: %v\", err)\n }\n}\n```\n\n---\n\n## Contributing\n\nDaytona is Open Source under the [GNU AFFERO GENERAL PUBLIC LICENSE](LICENSE), and is the [copyright of its contributors](NOTICE). If you would like to contribute to the software, read the Developer Certificate of Origin Version 1.1 (https://developercertificate.org/). Afterwards, navigate to the [contributing guide](CONTRIBUTING.md) to get started.\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Reporting a Vulnerability\n\nAt Daytona, we take security seriously. If you believe you have found a security vulnerability in any Daytona-owned repository or service, please report it responsibly.\n\n**Please do NOT report security vulnerabilities through public GitHub issues.**\n\nInstead, please email us at: **security@daytona.io**\n\nYou can also report vulnerabilities privately through [GitHub's security advisory feature](https://github.com/daytonaio/daytona/security/advisories/new).\n\nPlease include:\n\n- Description of the vulnerability\n- Steps to reproduce\n- Impact assessment\n- Any relevant screenshots or proof-of-concept\n\nWe will acknowledge receipt within 2 business days and provide an initial assessment within 5 business days.\n\n## Scope\n\nThe following assets and areas are in scope for vulnerability reports:\n\n- **Daytona platform** — app.daytona.io, including the web application and management interfaces\n- **API and SDK** — all documented and undocumented API endpoints, client SDKs\n- **Sandbox runtime isolation** — escape from sandbox to host, cross-tenant access, isolation boundary bypasses\n- **Authentication and authorization** — SSO, API key management, session handling, privilege escalation across accounts or organizations\n- **Secrets management** — scoped secret injection, unauthorized access to secrets, leakage across sandbox boundaries\n- **Public GitHub repositories** — any repository under the [daytonaio](https://github.com/daytonaio) organization\n\n## Excluded Submission Types\n\nThe following categories are excluded from this program. Reports in these categories will be closed without further assessment unless they demonstrate impact beyond what is described.\n\n1. **In-sandbox privilege escalation, root access, or capability use** — Daytona sandboxes provide full root access within user-namespace isolation by design. Findings that chain to host escape or cross-sandbox access remain in scope.\n2. **Findings within the reporter's own sandbox** that do not demonstrate impact beyond that sandbox's isolation boundary.\n3. **Denial of service** — DoS, DDoS, resource exhaustion, volumetric testing, or network flooding.\n4. **Rate limiting observations** that do not demonstrate resource exhaustion, financial impact, or abuse potential.\n5. **Social engineering** — phishing, vishing, pretexting, or any form of social engineering targeting Daytona employees or users.\n6. **Physical security testing** of offices, data centers, or personnel.\n7. **Marketing and documentation sites** — findings against daytona.io or docs.daytona.io, excluding subdomain takeover vulnerabilities.\n8. **Third-party services** — vulnerabilities in services or platforms not owned or operated by Daytona.\n9. **Known public files or directories** — e.g., robots.txt, .well-known, or other intentionally public resources.\n10. **DNSSEC or TLS cipher suite configuration suggestions** without a demonstrated exploit path.\n11. **Missing Secure/HTTPOnly flags** on non-sensitive cookies.\n12. **CSRF on unauthenticated or public-facing forms.**\n13. **Outdated browsers and platforms** — vulnerabilities only affecting unpatched or end-of-life software.\n14. **Automated scan output** — reports generated solely by automated tools without validated proof of impact.\n15. **Best practice recommendations** without demonstrable security impact.\n16. **Spam or service degradation** — testing that results in sending unsolicited messages or degradation of service to other users.\n\n## Supported Versions\n\nWe accept vulnerability reports for the latest stable release of Daytona.\n\n## Safe Harbor\n\nDaytona supports safe harbor for security researchers who act in good faith and in accordance with this policy.\n\nWe will not pursue legal action against researchers who:\n\n- Make a good-faith effort to avoid privacy violations, data destruction, and service disruption\n- Only access data to the extent necessary to demonstrate the vulnerability\n- Do not exfiltrate, retain, or disclose any user data encountered during research\n- Report findings promptly through the channels listed above\n- Do not disclose findings publicly before coordinated resolution (see Disclosure Timeline below)\n- Comply with all applicable laws\n\nIf legal action is initiated by a third party against a researcher for activities conducted in accordance with this policy, we will take steps to make it known that the research was authorized.\n\nThis safe harbor applies to all Daytona services and assets listed in the Scope section.\n\n## Disclosure Timeline\n\nWe follow a coordinated disclosure process:\n\n- **90 days** — We target remediation within 90 days of a validated report. Complex issues may require additional time, and we will communicate timelines transparently.\n- **30 days post-patch** — After a fix is released, we ask that researchers wait 30 days before public disclosure to allow users to update.\n- **No response** — If we fail to acknowledge or respond to a report within 90 days, the researcher may proceed with public disclosure after providing 14 days advance written notice to security@daytona.io.\n\n## Rewards\n\nWe offer rewards from $100 to $1,000 for valid, original findings that demonstrate real security impact. Severity, exploitability, and report quality are all considered. Duplicate reports are credited to the first submission.\n"
  },
  {
    "path": "apps/api/Dockerfile",
    "content": "FROM node:24-slim AS daytona\n\nENV CI=true\n\n# Install dependencies (apt instead of apk)\nRUN apt-get update && apt-get install -y --no-install-recommends bash curl && \\\n  rm -rf /var/lib/apt/lists/*\nRUN npm install -g corepack && corepack enable\n\nWORKDIR /daytona\n\n# Yarn caching layer\nCOPY package.json yarn.lock .yarnrc.yml ./\nRUN yarn install --immutable\n\n# Nx + TS config\nCOPY nx.json tsconfig.base.json ./\n\n# App source\nCOPY apps/api/ apps/api/\nCOPY apps/dashboard/ apps/dashboard/\n\n# Lib dependencies\nCOPY libs/runner-api-client/ libs/runner-api-client/\nCOPY libs/api-client/ libs/api-client/\nCOPY libs/analytics-api-client/ libs/analytics-api-client/\nCOPY libs/toolbox-api-client/ libs/toolbox-api-client/\nCOPY libs/sdk-typescript/ libs/sdk-typescript/\n\nENV NX_DAEMON=false\n\nRUN yarn nx build api --configuration=production --nxBail=true\n\nRUN VITE_BASE_API_URL=%DAYTONA_BASE_API_URL% yarn nx build dashboard --configuration=production --nxBail=true --output-style=stream\n\nARG VERSION=0.0.1\nENV VERSION=${VERSION}\n\nHEALTHCHECK CMD [ \"curl\", \"-f\", \"http://localhost:3000/api/config\" ]\n\nENTRYPOINT [\"node\", \"dist/apps/api/main.js\"]\n"
  },
  {
    "path": "apps/api/eslint.config.mjs",
    "content": "import baseConfig from '../../eslint.config.mjs'\n\nexport default [\n  ...baseConfig,\n  {\n    files: ['**/*.ts'],\n    rules: {\n      'no-restricted-syntax': [\n        'error',\n        {\n          selector:\n            'Decorator[expression.callee.name=\"InjectRepository\"] > CallExpression > Identifier[name=\"Sandbox\"]',\n          message: 'Do not use @InjectRepository(Sandbox). Use the custom SandboxRepository instead.',\n        },\n      ],\n    },\n  },\n]\n"
  },
  {
    "path": "apps/api/jest.config.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport default {\n  displayName: 'daytona',\n  preset: '../../jest.preset.js',\n  testEnvironment: 'node',\n  transform: {\n    '^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],\n  },\n  moduleFileExtensions: ['ts', 'js', 'html'],\n  coverageDirectory: '../../coverage/apps/daytona',\n}\n"
  },
  {
    "path": "apps/api/project.json",
    "content": "{\n  \"name\": \"api\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"sourceRoot\": \"apps/api/src\",\n  \"projectType\": \"application\",\n  \"tags\": [],\n  \"targets\": {\n    \"build\": {\n      \"executor\": \"@nx/webpack:webpack\",\n      \"options\": {\n        \"outputPath\": \"dist/apps/api\",\n        \"deleteOutputPath\": false,\n        \"main\": \"apps/api/src/main.ts\",\n        \"tsConfig\": \"apps/api/tsconfig.app.json\",\n        \"generatePackageJson\": true,\n        \"target\": \"node\",\n        \"compiler\": \"tsc\",\n        \"sourceMap\": true,\n        \"webpackConfig\": \"apps/api/webpack.config.js\",\n        \"assets\": [\n          {\n            \"input\": \"apps/api/src/assets\",\n            \"glob\": \"**/*\",\n            \"output\": \"./assets/\"\n          }\n        ]\n      },\n      \"configurations\": {\n        \"production\": {\n          \"optimization\": true,\n          \"extractLicenses\": true,\n          \"inspect\": false\n        }\n      }\n    },\n    \"openapi\": {\n      \"executor\": \"nx:run-commands\",\n      \"cache\": true,\n      \"inputs\": [\n        \"{projectRoot}/src/**/*.ts\",\n        \"!{projectRoot}/src/**/*.spec.ts\",\n        \"{projectRoot}/tsconfig.app.json\",\n        {\n          \"dependentTasksOutputFiles\": \"**/*\",\n          \"transitive\": true\n        }\n      ],\n      \"outputs\": [\"{workspaceRoot}/dist/apps/api/openapi.json\", \"{workspaceRoot}/dist/apps/api/openapi.3.1.0.json\"],\n      \"options\": {\n        \"commands\": [\n          \"mkdir -p dist/apps/api\",\n          \"yarn ts-node apps/api/src/generate-openapi.ts -o dist/apps/api/openapi.json\"\n        ],\n        \"parallel\": false,\n        \"env\": {\n          \"TS_NODE_PROJECT\": \"apps/api/tsconfig.app.json\",\n          \"NODE_OPTIONS\": \"--require tsconfig-paths/register\",\n          \"SKIP_CONNECTIONS\": \"true\"\n        }\n      }\n    },\n    \"serve\": {\n      \"executor\": \"@nx/js:node\",\n      \"defaultConfiguration\": \"development\",\n      \"dependsOn\": [\"build\"],\n      \"options\": {\n        \"buildTarget\": \"api:build\",\n        \"runBuildTargetDependencies\": false,\n        \"watch\": true\n      },\n      \"configurations\": {\n        \"development\": {\n          \"buildTarget\": \"api:build:development\"\n        },\n        \"production\": {\n          \"buildTarget\": \"api:build:production\"\n        }\n      }\n    },\n    \"format\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cd {projectRoot} && prettier --write \\\"**/*.{ts,json,mjs}\\\" --config ../../.prettierrc\"\n      }\n    },\n    \"test\": {\n      \"options\": {\n        \"passWithNoTests\": true\n      }\n    },\n    \"check-version-env\": {},\n    \"docker\": {\n      \"options\": {\n        \"target\": \"daytona\"\n      },\n      \"dependsOn\": [\n        {\n          \"target\": \"build-amd64\",\n          \"projects\": \"runner\"\n        }\n      ]\n    },\n    \"push-manifest\": {},\n    \"lint\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"bash apps/api/scripts/validate-migration-paths.sh $(find apps/api/src/migrations -name '*-migration.ts' -type f)\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/scripts/validate-migration-paths.sh",
    "content": "#!/bin/bash\n\n# Copyright Daytona Platforms Inc.\n# SPDX-License-Identifier: AGPL-3.0\n\n# Fails if any migration file is placed directly under\n# apps/api/src/migrations/ instead of pre-deploy/ or post-deploy/.\n# Legacy migrations (timestamp <= LEGACY_CUTOFF) are excluded.\n\n# Exit on error\nset -e\n\nLEGACY_CUTOFF=1770880371265\n\nforbidden=()\n\nfor f in \"$@\"; do\n  rel=\"$(realpath --relative-to=\"$PWD\" \"$f\")\"\n\n  case \"$rel\" in\n    apps/api/src/migrations/pre-deploy/*-migration.ts) ;;\n    apps/api/src/migrations/post-deploy/*-migration.ts) ;;\n    apps/api/src/migrations/*/*-migration.ts)\n      forbidden+=(\"$rel\")\n      ;;\n    apps/api/src/migrations/*-migration.ts)\n      timestamp=$(basename \"$rel\" | grep -oP '^\\d+')\n      if [ -n \"$timestamp\" ] && [ \"$timestamp\" -le \"$LEGACY_CUTOFF\" ]; then\n        continue\n      fi\n      forbidden+=(\"$rel\")\n      ;;\n  esac\ndone\n\nif [ ${#forbidden[@]} -gt 0 ]; then\n  echo \"Migration files must be placed in one of:\" >&2\n  echo \"  - apps/api/src/migrations/pre-deploy/\" >&2\n  echo \"  - apps/api/src/migrations/post-deploy/\" >&2\n  echo \"\" >&2\n  echo \"Invalid paths:\" >&2\n  for p in \"${forbidden[@]}\"; do\n    echo \"  - $p\" >&2\n  done\n  echo \"\" >&2\n  echo \"See apps/api/src/migrations/README.md for more information.\" >&2\n  exit 1\nfi\n"
  },
  {
    "path": "apps/api/src/admin/admin.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { AdminRunnerController } from './controllers/runner.controller'\nimport { AdminSandboxController } from './controllers/sandbox.controller'\nimport { SandboxModule } from '../sandbox/sandbox.module'\nimport { RegionModule } from '../region/region.module'\nimport { OrganizationModule } from '../organization/organization.module'\n\n@Module({\n  imports: [SandboxModule, RegionModule, OrganizationModule],\n  controllers: [AdminRunnerController, AdminSandboxController],\n})\nexport class AdminModule {}\n"
  },
  {
    "path": "apps/api/src/admin/controllers/runner.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Body,\n  Controller,\n  Delete,\n  Get,\n  HttpCode,\n  NotFoundException,\n  Param,\n  ParseUUIDPipe,\n  Patch,\n  Post,\n  Query,\n  UseGuards,\n} from '@nestjs/common'\nimport { ApiBearerAuth, ApiOAuth2, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'\nimport { AdminCreateRunnerDto } from '../dto/create-runner.dto'\nimport { Audit, MASKED_AUDIT_VALUE, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { SystemActionGuard } from '../../auth/system-action.guard'\nimport { RequiredApiRole } from '../../common/decorators/required-role.decorator'\nimport { RegionService } from '../../region/services/region.service'\nimport { CreateRunnerResponseDto } from '../../sandbox/dto/create-runner-response.dto'\nimport { RunnerFullDto } from '../../sandbox/dto/runner-full.dto'\nimport { RunnerDto } from '../../sandbox/dto/runner.dto'\nimport { RunnerService } from '../../sandbox/services/runner.service'\nimport { SystemRole } from '../../user/enums/system-role.enum'\n\n@ApiTags('admin')\n@Controller('admin/runners')\n@UseGuards(CombinedAuthGuard, SystemActionGuard)\n@RequiredApiRole([SystemRole.ADMIN])\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class AdminRunnerController {\n  constructor(\n    private readonly runnerService: RunnerService,\n    private readonly regionService: RegionService,\n  ) {}\n\n  @Post()\n  @HttpCode(201)\n  @ApiOperation({\n    summary: 'Create runner',\n    operationId: 'adminCreateRunner',\n  })\n  @ApiResponse({\n    status: 201,\n    type: CreateRunnerResponseDto,\n  })\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.RUNNER,\n    targetIdFromResult: (result: RunnerDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<AdminCreateRunnerDto>) => ({\n        domain: req.body?.domain,\n        apiUrl: req.body?.apiUrl,\n        proxyUrl: req.body?.proxyUrl,\n        regionId: req.body?.regionId,\n        name: req.body?.name,\n        apiKey: MASKED_AUDIT_VALUE,\n        apiVersion: req.body?.apiVersion,\n      }),\n    },\n  })\n  async create(@Body() createRunnerDto: AdminCreateRunnerDto): Promise<CreateRunnerResponseDto> {\n    const region = await this.regionService.findOne(createRunnerDto.regionId)\n\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n\n    const { runner, apiKey } = await this.runnerService.create({\n      domain: createRunnerDto.domain,\n      apiUrl: createRunnerDto.apiUrl,\n      proxyUrl: createRunnerDto.proxyUrl,\n      regionId: createRunnerDto.regionId,\n      name: createRunnerDto.name,\n      apiKey: createRunnerDto.apiKey,\n      apiVersion: createRunnerDto.apiVersion,\n      cpu: createRunnerDto.cpu,\n      memoryGiB: createRunnerDto.memoryGiB,\n      diskGiB: createRunnerDto.diskGiB,\n    })\n\n    return CreateRunnerResponseDto.fromRunner(runner, apiKey)\n  }\n\n  @Get(':id')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Get runner by ID',\n    operationId: 'adminGetRunnerById',\n  })\n  @ApiResponse({\n    status: 200,\n    type: RunnerFullDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Runner ID',\n    type: String,\n  })\n  async getRunnerById(@Param('id', ParseUUIDPipe) id: string): Promise<RunnerFullDto> {\n    return this.runnerService.findOneFullOrFail(id)\n  }\n\n  @Get()\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'List all runners',\n    operationId: 'adminListRunners',\n  })\n  @ApiResponse({\n    status: 200,\n    type: [RunnerFullDto],\n  })\n  @ApiQuery({\n    name: 'regionId',\n    description: 'Filter runners by region ID',\n    type: String,\n    required: false,\n  })\n  async findAll(@Query('regionId') regionId?: string): Promise<RunnerFullDto[]> {\n    if (regionId) {\n      return this.runnerService.findAllByRegionFull(regionId)\n    }\n    return this.runnerService.findAllFull()\n  }\n\n  @Patch(':id/scheduling')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Update runner scheduling status',\n    operationId: 'adminUpdateRunnerScheduling',\n  })\n  @ApiResponse({\n    status: 204,\n  })\n  @Audit({\n    action: AuditAction.UPDATE_SCHEDULING,\n    targetType: AuditTarget.RUNNER,\n    targetIdFromRequest: (req) => req.params.id,\n    requestMetadata: {\n      body: (req: TypedRequest<{ unschedulable: boolean }>) => ({\n        unschedulable: req.body?.unschedulable,\n      }),\n    },\n  })\n  async updateSchedulingStatus(\n    @Param('id', ParseUUIDPipe) id: string,\n    @Body('unschedulable') unschedulable: boolean,\n  ): Promise<void> {\n    await this.runnerService.updateSchedulingStatus(id, unschedulable)\n  }\n\n  @Delete(':id')\n  @HttpCode(204)\n  @ApiOperation({\n    summary: 'Delete runner',\n    operationId: 'adminDeleteRunner',\n  })\n  @ApiResponse({\n    status: 204,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Runner ID',\n    type: String,\n  })\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.RUNNER,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  async delete(@Param('id', ParseUUIDPipe) id: string): Promise<void> {\n    return this.runnerService.remove(id)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/admin/controllers/sandbox.controller.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, HttpCode, NotFoundException, Param, Post, UseGuards } from '@nestjs/common'\nimport { ApiBearerAuth, ApiOAuth2, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger'\nimport { Audit } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { SystemActionGuard } from '../../auth/system-action.guard'\nimport { RequiredApiRole } from '../../common/decorators/required-role.decorator'\nimport { OrganizationService } from '../../organization/services/organization.service'\nimport { SandboxDto } from '../../sandbox/dto/sandbox.dto'\nimport { SandboxService } from '../../sandbox/services/sandbox.service'\nimport { SystemRole } from '../../user/enums/system-role.enum'\n\n@ApiTags('admin')\n@Controller('admin/sandbox')\n@UseGuards(CombinedAuthGuard, SystemActionGuard)\n@RequiredApiRole([SystemRole.ADMIN])\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class AdminSandboxController {\n  constructor(\n    private readonly sandboxService: SandboxService,\n    private readonly organizationService: OrganizationService,\n  ) {}\n\n  @Post(':sandboxId/recover')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Recover sandbox from error state as an admin',\n    operationId: 'adminRecoverSandbox',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Recovery initiated',\n    type: SandboxDto,\n  })\n  @Audit({\n    action: AuditAction.RECOVER,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n  })\n  async recoverSandbox(@Param('sandboxId') sandboxId: string): Promise<SandboxDto> {\n    const organization = await this.organizationService.findBySandboxId(sandboxId)\n    if (!organization) {\n      throw new NotFoundException('Sandbox not found')\n    }\n    const recoveredSandbox = await this.sandboxService.recover(sandboxId, organization)\n    return this.sandboxService.toSandboxDto(recoveredSandbox)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/admin/dto/create-runner.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsNumber, IsOptional, IsString } from 'class-validator'\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { CreateRunnerDto } from '../../sandbox/dto/create-runner.dto'\n\n@ApiSchema({ name: 'AdminCreateRunner' })\nexport class AdminCreateRunnerDto extends CreateRunnerDto {\n  @IsString()\n  @ApiProperty()\n  apiKey: string\n\n  @IsString()\n  @ApiProperty({\n    description: 'The api version of the runner to create',\n    pattern: '^(0|2)$',\n    example: '2',\n  })\n  apiVersion: '0' | '2'\n\n  @ApiProperty({\n    required: false,\n    description: 'The domain of the runner',\n    example: 'runner1.example.com',\n  })\n  @IsString()\n  @IsOptional()\n  domain?: string\n\n  @IsString()\n  @ApiProperty({\n    description: 'The API URL of the runner',\n    example: 'https://api.runner1.example.com',\n    required: false,\n  })\n  @IsOptional()\n  apiUrl?: string\n\n  @IsString()\n  @ApiProperty({\n    description: 'The proxy URL of the runner',\n    example: 'https://proxy.runner1.example.com',\n    required: false,\n  })\n  @IsOptional()\n  proxyUrl?: string\n\n  @IsNumber()\n  @ApiProperty({\n    description: 'The CPU capacity of the runner',\n    example: 8,\n    required: false,\n  })\n  @IsOptional()\n  cpu?: number\n\n  @IsNumber()\n  @ApiProperty({\n    description: 'The memory capacity of the runner in GiB',\n    example: 16,\n    required: false,\n  })\n  @IsOptional()\n  memoryGiB?: number\n\n  @IsNumber()\n  @ApiProperty({\n    description: 'The disk capacity of the runner in GiB',\n    example: 100,\n    required: false,\n  })\n  @IsOptional()\n  diskGiB?: number\n}\n"
  },
  {
    "path": "apps/api/src/analytics/analytics.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { AnalyticsService } from './services/analytics.service'\n\n@Module({\n  imports: [TypeOrmModule.forFeature([AnalyticsService])],\n  providers: [AnalyticsService],\n  exports: [AnalyticsService],\n})\nexport class AnalyticsModule {}\n"
  },
  {
    "path": "apps/api/src/analytics/services/analytics.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport { SandboxEvents } from '../../sandbox/constants/sandbox-events.constants'\nimport { SandboxCreatedEvent } from '../../sandbox/events/sandbox-create.event'\nimport { SandboxDesiredStateUpdatedEvent } from '../../sandbox/events/sandbox-desired-state-updated.event'\nimport { SandboxDestroyedEvent } from '../../sandbox/events/sandbox-destroyed.event'\nimport { SandboxPublicStatusUpdatedEvent } from '../../sandbox/events/sandbox-public-status-updated.event'\nimport { SandboxStartedEvent } from '../../sandbox/events/sandbox-started.event'\nimport { SandboxStateUpdatedEvent } from '../../sandbox/events/sandbox-state-updated.event'\nimport { SandboxStoppedEvent } from '../../sandbox/events/sandbox-stopped.event'\nimport { PostHog } from 'posthog-node'\nimport { OnAsyncEvent } from '../../common/decorators/on-async-event.decorator'\nimport { Organization } from '../../organization/entities/organization.entity'\nimport { OrganizationEvents } from '../../organization/constants/organization-events.constant'\nimport { TypedConfigService } from '../../config/typed-config.service'\n\n@Injectable()\nexport class AnalyticsService {\n  private readonly logger = new Logger(AnalyticsService.name)\n  private readonly posthog?: PostHog\n\n  constructor(private readonly configService: TypedConfigService) {\n    if (!this.configService.get('posthog.apiKey')) {\n      return\n    }\n\n    if (!this.configService.get('posthog.host')) {\n      return\n    }\n\n    // Initialize PostHog client\n    this.posthog = new PostHog(this.configService.get('posthog.apiKey'), {\n      host: this.configService.get('posthog.host'),\n    })\n  }\n\n  @OnEvent(SandboxEvents.CREATED)\n  async handleSandboxCreatedEvent(event: SandboxCreatedEvent) {\n    this.logger.debug(`Sandbox created: ${JSON.stringify(event)}`)\n  }\n\n  @OnEvent(SandboxEvents.STARTED)\n  async handleSandboxStartedEvent(event: SandboxStartedEvent) {\n    this.logger.debug(`Sandbox started: ${JSON.stringify(event)}`)\n  }\n\n  @OnEvent(SandboxEvents.STOPPED)\n  async handleSandboxStoppedEvent(event: SandboxStoppedEvent) {\n    this.logger.debug(`Sandbox stopped: ${JSON.stringify(event)}`)\n  }\n\n  @OnEvent(SandboxEvents.DESTROYED)\n  async handleSandboxDestroyedEvent(event: SandboxDestroyedEvent) {\n    this.logger.debug(`Sandbox destroyed: ${JSON.stringify(event)}`)\n  }\n\n  @OnEvent(SandboxEvents.PUBLIC_STATUS_UPDATED)\n  async handleSandboxPublicStatusUpdatedEvent(event: SandboxPublicStatusUpdatedEvent) {\n    this.logger.debug(`Sandbox public status updated: ${JSON.stringify(event)}`)\n  }\n\n  @OnEvent(SandboxEvents.DESIRED_STATE_UPDATED)\n  async handleSandboxDesiredStateUpdatedEvent(event: SandboxDesiredStateUpdatedEvent) {\n    this.logger.debug(`Sandbox desired state updated: ${JSON.stringify(event)}`)\n  }\n\n  @OnEvent(SandboxEvents.STATE_UPDATED)\n  async handleSandboxStateUpdatedEvent(event: SandboxStateUpdatedEvent) {\n    this.logger.debug(`Sandbox state updated: ${JSON.stringify(event)}`)\n  }\n\n  @OnAsyncEvent({\n    event: OrganizationEvents.CREATED,\n  })\n  async handlePersonalOrganizationCreatedEvent(payload: Organization) {\n    if (!payload.personal) {\n      return\n    }\n\n    if (!this.posthog) {\n      return\n    }\n\n    this.posthog.groupIdentify({\n      groupType: 'organization',\n      groupKey: payload.id,\n      properties: {\n        name: `Personal - ${payload.createdBy}`,\n        created_at: payload.createdAt,\n        created_by: payload.createdBy,\n        personal: payload.personal,\n        environment: this.configService.get('posthog.environment'),\n      },\n    })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/api-key/api-key.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Post, Get, Delete, Param, Body, UseGuards, ForbiddenException, HttpCode } from '@nestjs/common'\nimport { ApiKeyService } from './api-key.service'\nimport { CreateApiKeyDto } from './dto/create-api-key.dto'\nimport { ApiHeader, ApiOAuth2, ApiOperation, ApiResponse, ApiTags, ApiBearerAuth } from '@nestjs/swagger'\nimport { ApiKeyResponseDto } from './dto/api-key-response.dto'\nimport { ApiKeyListDto } from './dto/api-key-list.dto'\nimport { CombinedAuthGuard } from '../auth/combined-auth.guard'\nimport { CustomHeaders } from '../common/constants/header.constants'\nimport { AuthContext } from '../common/decorators/auth-context.decorator'\nimport { AuthContext as IAuthContext } from '../common/interfaces/auth-context.interface'\nimport { OrganizationAuthContext } from '../common/interfaces/auth-context.interface'\nimport { OrganizationMemberRole } from '../organization/enums/organization-member-role.enum'\nimport { OrganizationResourcePermission } from '../organization/enums/organization-resource-permission.enum'\nimport { OrganizationResourceActionGuard } from '../organization/guards/organization-resource-action.guard'\nimport { SystemRole } from '../user/enums/system-role.enum'\nimport { Audit, TypedRequest } from '../audit/decorators/audit.decorator'\nimport { AuditAction } from '../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../audit/enums/audit-target.enum'\nimport { ApiKey } from './api-key.entity'\nimport { AuthenticatedRateLimitGuard } from '../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('api-keys')\n@Controller('api-keys')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class ApiKeyController {\n  constructor(private readonly apiKeyService: ApiKeyService) {}\n\n  @Post()\n  @ApiOperation({\n    summary: 'Create API key',\n    operationId: 'createApiKey',\n  })\n  @ApiResponse({\n    status: 201,\n    description: 'API key created successfully.',\n    type: ApiKeyResponseDto,\n  })\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.API_KEY,\n    targetIdFromResult: (result: ApiKeyResponseDto) => result?.name,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateApiKeyDto>) => ({\n        name: req.body?.name,\n        permissions: req.body?.permissions,\n        expiresAt: req.body?.expiresAt,\n      }),\n    },\n  })\n  async createApiKey(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Body() createApiKeyDto: CreateApiKeyDto,\n  ): Promise<ApiKeyResponseDto> {\n    this.validateRequestedApiKeyPermissions(authContext, createApiKeyDto.permissions)\n\n    const { apiKey, value } = await this.apiKeyService.createApiKey(\n      authContext.organizationId,\n      authContext.userId,\n      createApiKeyDto.name,\n      createApiKeyDto.permissions,\n      createApiKeyDto.expiresAt,\n    )\n\n    return ApiKeyResponseDto.fromApiKey(apiKey, value)\n  }\n\n  @Get()\n  @ApiOperation({\n    summary: 'List API keys',\n    operationId: 'listApiKeys',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'API keys retrieved successfully.',\n    type: [ApiKeyListDto],\n  })\n  @ApiResponse({ status: 500, description: 'Error fetching API keys.' })\n  async getApiKeys(@AuthContext() authContext: OrganizationAuthContext): Promise<ApiKeyListDto[]> {\n    let apiKeys: ApiKey[] = []\n\n    if (authContext.role === SystemRole.ADMIN || authContext.organizationUser?.role === OrganizationMemberRole.OWNER) {\n      apiKeys = await this.apiKeyService.getApiKeys(authContext.organizationId)\n    } else {\n      apiKeys = await this.apiKeyService.getApiKeys(authContext.organizationId, authContext.userId)\n    }\n\n    return apiKeys.map((apiKey) => ApiKeyListDto.fromApiKey(apiKey))\n  }\n\n  @Get('current')\n  @ApiOperation({\n    summary: \"Get current API key's details\",\n    operationId: 'getCurrentApiKey',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'API key retrieved successfully.',\n    type: ApiKeyListDto,\n  })\n  async getCurrentApiKey(@AuthContext() authContext: IAuthContext): Promise<ApiKeyListDto> {\n    if (!authContext.apiKey) {\n      throw new ForbiddenException('Authenticate with an API key to use this endpoint')\n    }\n\n    return ApiKeyListDto.fromApiKey(authContext.apiKey)\n  }\n\n  @Get(':name')\n  @ApiOperation({\n    summary: 'Get API key',\n    operationId: 'getApiKey',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'API key retrieved successfully.',\n    type: ApiKeyListDto,\n  })\n  async getApiKey(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('name') name: string,\n  ): Promise<ApiKeyListDto> {\n    const apiKey = await this.apiKeyService.getApiKeyByName(authContext.organizationId, authContext.userId, name)\n    return ApiKeyListDto.fromApiKey(apiKey)\n  }\n\n  @Delete(':name')\n  @ApiOperation({\n    summary: 'Delete API key',\n    operationId: 'deleteApiKey',\n  })\n  @ApiResponse({ status: 204, description: 'API key deleted successfully.' })\n  @HttpCode(204)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.API_KEY,\n    targetIdFromRequest: (req) => req.params.name,\n  })\n  async deleteApiKey(@AuthContext() authContext: OrganizationAuthContext, @Param('name') name: string) {\n    await this.apiKeyService.deleteApiKey(authContext.organizationId, authContext.userId, name)\n  }\n\n  @Delete(':userId/:name')\n  @ApiOperation({\n    summary: 'Delete API key for user',\n    operationId: 'deleteApiKeyForUser',\n  })\n  @ApiResponse({ status: 204, description: 'API key deleted successfully.' })\n  @HttpCode(204)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.API_KEY,\n    targetIdFromRequest: (req) => req.params.name,\n    requestMetadata: {\n      params: (req) => ({\n        userId: req.params.userId,\n      }),\n    },\n  })\n  async deleteApiKeyForUser(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('userId') userId: string,\n    @Param('name') name: string,\n  ) {\n    if (\n      userId !== authContext.userId &&\n      authContext.role !== SystemRole.ADMIN &&\n      authContext.organizationUser?.role !== OrganizationMemberRole.OWNER\n    ) {\n      throw new ForbiddenException('Incorrect user ID provided')\n    }\n\n    await this.apiKeyService.deleteApiKey(authContext.organizationId, userId, name)\n  }\n\n  private validateRequestedApiKeyPermissions(\n    authContext: OrganizationAuthContext,\n    requestedPermissions: OrganizationResourcePermission[],\n  ): void {\n    if (authContext.role === SystemRole.ADMIN) {\n      return\n    }\n\n    if (!authContext.organizationUser) {\n      throw new ForbiddenException(`Insufficient permissions for assigning: ${requestedPermissions.join(', ')}`)\n    }\n\n    if (authContext.organizationUser.role === OrganizationMemberRole.OWNER) {\n      return\n    }\n\n    const organizationUserPermissions = new Set(\n      authContext.organizationUser.assignedRoles.flatMap((role) => role.permissions),\n    )\n\n    const forbiddenPermissions = requestedPermissions.filter(\n      (permission) => !organizationUserPermissions.has(permission),\n    )\n\n    if (forbiddenPermissions.length) {\n      throw new ForbiddenException(`Insufficient permissions for assigning: ${forbiddenPermissions.join(', ')}`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/api-key/api-key.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, Entity, Index, PrimaryColumn } from 'typeorm'\nimport { OrganizationResourcePermission } from '../organization/enums/organization-resource-permission.enum'\n\n@Entity()\n@Index('api_key_org_user_idx', ['organizationId', 'userId'])\nexport class ApiKey {\n  @PrimaryColumn({\n    type: 'uuid',\n  })\n  organizationId: string\n\n  @PrimaryColumn()\n  userId: string\n\n  @PrimaryColumn()\n  name: string\n\n  @Column({ unique: true, default: '' })\n  keyHash: string\n\n  @Column({\n    default: '',\n  })\n  keyPrefix: string\n\n  @Column({\n    default: '',\n  })\n  keySuffix: string\n\n  @Column({\n    type: 'enum',\n    enum: OrganizationResourcePermission,\n    array: true,\n  })\n  permissions: OrganizationResourcePermission[]\n\n  @Column()\n  createdAt: Date\n\n  @Column({ nullable: true })\n  lastUsedAt?: Date\n\n  @Column({ nullable: true })\n  expiresAt?: Date\n}\n"
  },
  {
    "path": "apps/api/src/api-key/api-key.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { ApiKeyController } from './api-key.controller'\nimport { ApiKeyService } from './api-key.service'\nimport { ApiKey } from './api-key.entity'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { OrganizationModule } from '../organization/organization.module'\nimport { RedisLockProvider } from '../sandbox/common/redis-lock.provider'\n\n@Module({\n  imports: [OrganizationModule, TypeOrmModule.forFeature([ApiKey])],\n  controllers: [ApiKeyController],\n  providers: [ApiKeyService, RedisLockProvider],\n  exports: [ApiKeyService],\n})\nexport class ApiKeyModule {}\n"
  },
  {
    "path": "apps/api/src/api-key/api-key.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ConflictException, Injectable, Logger, NotFoundException } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { EntityManager, Repository, ArrayOverlap } from 'typeorm'\nimport { ApiKey } from './api-key.entity'\nimport { OrganizationResourcePermission } from '../organization/enums/organization-resource-permission.enum'\nimport { RedisLockProvider } from '../sandbox/common/redis-lock.provider'\nimport { OnAsyncEvent } from '../common/decorators/on-async-event.decorator'\nimport { OrganizationEvents } from '../organization/constants/organization-events.constant'\nimport { OrganizationResourcePermissionsUnassignedEvent } from '../organization/events/organization-resource-permissions-unassigned.event'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\nimport { generateApiKeyHash, generateApiKeyValue } from '../common/utils/api-key'\n\n@Injectable()\nexport class ApiKeyService {\n  private readonly logger = new Logger(ApiKeyService.name)\n\n  constructor(\n    @InjectRepository(ApiKey)\n    private apiKeyRepository: Repository<ApiKey>,\n    private readonly redisLockProvider: RedisLockProvider,\n    @InjectRedis() private readonly redis: Redis,\n  ) {}\n\n  private getApiKeyPrefix(value: string): string {\n    return value.substring(0, 3)\n  }\n\n  private getApiKeySuffix(value: string): string {\n    return value.slice(-3)\n  }\n\n  async createApiKey(\n    organizationId: string,\n    userId: string,\n    name: string,\n    permissions: OrganizationResourcePermission[],\n    expiresAt?: Date,\n    apiKeyValue?: string,\n  ): Promise<{ apiKey: ApiKey; value: string }> {\n    const existingKey = await this.apiKeyRepository.findOne({ where: { organizationId, userId, name } })\n    if (existingKey) {\n      throw new ConflictException('API key with this name already exists')\n    }\n\n    const value = apiKeyValue || generateApiKeyValue()\n\n    const apiKey = await this.apiKeyRepository.save({\n      organizationId,\n      userId,\n      name,\n      keyHash: generateApiKeyHash(value),\n      keyPrefix: this.getApiKeyPrefix(value),\n      keySuffix: this.getApiKeySuffix(value),\n      permissions,\n      createdAt: new Date(),\n      expiresAt,\n    })\n\n    return { apiKey, value }\n  }\n\n  async getApiKeys(organizationId: string, userId?: string): Promise<ApiKey[]> {\n    const apiKeys = await this.apiKeyRepository.find({\n      where: { organizationId, userId },\n      order: {\n        lastUsedAt: {\n          direction: 'DESC',\n          nulls: 'LAST',\n        },\n        createdAt: 'DESC',\n      },\n    })\n\n    return apiKeys\n  }\n\n  async getApiKeyByName(organizationId: string, userId: string, name: string): Promise<ApiKey> {\n    const apiKey = await this.apiKeyRepository.findOne({\n      where: {\n        organizationId,\n        userId,\n        name,\n      },\n    })\n\n    if (!apiKey) {\n      throw new NotFoundException('API key not found')\n    }\n\n    return apiKey\n  }\n\n  async getApiKeyByValue(value: string): Promise<ApiKey> {\n    const apiKey = await this.apiKeyRepository.findOne({\n      where: {\n        keyHash: generateApiKeyHash(value),\n      },\n    })\n\n    if (!apiKey) {\n      throw new NotFoundException('API key not found')\n    }\n\n    return apiKey\n  }\n\n  async deleteApiKey(organizationId: string, userId: string, name: string): Promise<void> {\n    const apiKey = await this.apiKeyRepository.findOne({ where: { organizationId, userId, name } })\n\n    if (!apiKey) {\n      throw new NotFoundException('API key not found')\n    }\n\n    await this.deleteWithEntityManager(this.apiKeyRepository.manager, apiKey)\n  }\n\n  async updateLastUsedAt(organizationId: string, userId: string, name: string, lastUsedAt: Date): Promise<void> {\n    const cooldownKey = `api-key-last-used-update-${organizationId}-${userId}-${name}`\n\n    const aquired = await this.redisLockProvider.lock(cooldownKey, 10)\n\n    // redis for cooldown period - 10 seconds\n    // prevents database flooding when multiple requests are made at the same time\n    if (!aquired) {\n      return\n    }\n\n    await this.apiKeyRepository.update(\n      {\n        organizationId,\n        userId,\n        name,\n      },\n      { lastUsedAt },\n    )\n  }\n\n  private async deleteWithEntityManager(entityManager: EntityManager, apiKey: ApiKey): Promise<void> {\n    await entityManager.remove(apiKey)\n    // Invalidate cache when API key is deleted\n    await this.invalidateApiKeyCache(apiKey.keyHash)\n  }\n\n  private async invalidateApiKeyCache(keyHash: string): Promise<void> {\n    try {\n      const cacheKey = `api-key:validation:${keyHash}`\n      await this.redis.del(cacheKey)\n      this.logger.debug(`Invalidated cache for API key: ${cacheKey}`)\n    } catch (error) {\n      this.logger.error('Error invalidating API key cache:', error)\n    }\n  }\n\n  @OnAsyncEvent({\n    event: OrganizationEvents.PERMISSIONS_UNASSIGNED,\n  })\n  async handleOrganizationResourcePermissionsUnassignedEvent(\n    payload: OrganizationResourcePermissionsUnassignedEvent,\n  ): Promise<void> {\n    const apiKeysToRevoke = await this.apiKeyRepository.find({\n      where: {\n        organizationId: payload.organizationId,\n        userId: payload.userId,\n        permissions: ArrayOverlap(payload.unassignedPermissions),\n      },\n    })\n\n    await Promise.all(apiKeysToRevoke.map((apiKey) => this.deleteWithEntityManager(payload.entityManager, apiKey)))\n  }\n}\n"
  },
  {
    "path": "apps/api/src/api-key/dto/api-key-list.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { ApiKey } from '../api-key.entity'\n\n@ApiSchema({ name: 'ApiKeyList' })\nexport class ApiKeyListDto {\n  @ApiProperty({\n    description: 'The name of the API key',\n    example: 'My API Key',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'The masked API key value',\n    example: 'bb_********************def',\n  })\n  value: string\n\n  @ApiProperty({\n    description: 'When the API key was created',\n    example: '2024-03-14T12:00:00.000Z',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'The list of organization resource permissions assigned to the API key',\n    enum: OrganizationResourcePermission,\n    isArray: true,\n  })\n  permissions: OrganizationResourcePermission[]\n\n  @ApiProperty({\n    description: 'When the API key was last used',\n    example: '2024-03-14T12:00:00.000Z',\n    nullable: true,\n  })\n  lastUsedAt?: Date\n\n  @ApiProperty({\n    description: 'When the API key expires',\n    example: '2024-03-14T12:00:00.000Z',\n    nullable: true,\n  })\n  expiresAt?: Date\n\n  @ApiProperty({\n    description: 'The user ID of the user who created the API key',\n    example: '123',\n  })\n  userId: string\n\n  constructor(partial: Partial<ApiKeyListDto>) {\n    Object.assign(this, partial)\n  }\n\n  static fromApiKey(apiKey: ApiKey): ApiKeyListDto {\n    const maskedValue = `${apiKey.keyPrefix}********************${apiKey.keySuffix}`\n\n    return new ApiKeyListDto({\n      name: apiKey.name,\n      value: maskedValue,\n      createdAt: apiKey.createdAt,\n      permissions: apiKey.permissions,\n      lastUsedAt: apiKey.lastUsedAt,\n      expiresAt: apiKey.expiresAt,\n      userId: apiKey.userId,\n    })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/api-key/dto/api-key-response.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { ApiKey } from '../api-key.entity'\n\n@ApiSchema({ name: 'ApiKeyResponse' })\nexport class ApiKeyResponseDto {\n  @ApiProperty({\n    description: 'The name of the API key',\n    example: 'My API Key',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'The API key value',\n    example: 'bb_sk_1234567890abcdef',\n  })\n  value: string\n\n  @ApiProperty({\n    description: 'When the API key was created',\n    example: '2024-03-14T12:00:00.000Z',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'The list of organization resource permissions assigned to the API key',\n    enum: OrganizationResourcePermission,\n    isArray: true,\n  })\n  permissions: OrganizationResourcePermission[]\n\n  @ApiProperty({\n    description: 'When the API key expires',\n    example: '2025-06-09T12:00:00.000Z',\n    nullable: true,\n  })\n  expiresAt?: Date\n\n  static fromApiKey(apiKey: ApiKey, value: string): ApiKeyResponseDto {\n    return {\n      name: apiKey.name,\n      value,\n      createdAt: apiKey.createdAt,\n      permissions: apiKey.permissions,\n      expiresAt: apiKey.expiresAt,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/api-key/dto/create-api-key.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsArray, IsDate, IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator'\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { Type } from 'class-transformer'\n\n@ApiSchema({ name: 'CreateApiKey' })\nexport class CreateApiKeyDto {\n  @ApiProperty({\n    description: 'The name of the API key',\n    example: 'My API Key',\n    required: true,\n  })\n  @IsNotEmpty()\n  @IsString()\n  name: string\n\n  @ApiProperty({\n    description: 'The list of organization resource permissions explicitly assigned to the API key',\n    enum: OrganizationResourcePermission,\n    isArray: true,\n    required: true,\n  })\n  @IsArray()\n  @IsEnum(OrganizationResourcePermission, { each: true })\n  permissions: OrganizationResourcePermission[]\n\n  @ApiPropertyOptional({\n    description: 'When the API key expires',\n    example: '2025-06-09T12:00:00.000Z',\n    nullable: true,\n  })\n  @IsOptional()\n  @Type(() => Date)\n  @IsDate()\n  expiresAt?: Date\n}\n"
  },
  {
    "path": "apps/api/src/app.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module, NestModule, MiddlewareConsumer, RequestMethod, ExecutionContext } from '@nestjs/common'\nimport { VersionHeaderMiddleware } from './common/middleware/version-header.middleware'\nimport { FailedAuthRateLimitMiddleware } from './common/middleware/failed-auth-rate-limit.middleware'\nimport { AppService } from './app.service'\nimport { UserModule } from './user/user.module'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { SandboxModule } from './sandbox/sandbox.module'\nimport { AuthModule } from './auth/auth.module'\nimport { ServeStaticModule } from '@nestjs/serve-static'\nimport { join } from 'path'\nimport { ApiKeyModule } from './api-key/api-key.module'\nimport { seconds, ThrottlerModule } from '@nestjs/throttler'\nimport { DockerRegistryModule } from './docker-registry/docker-registry.module'\nimport { RedisModule, getRedisConnectionToken } from '@nestjs-modules/ioredis'\nimport { ScheduleModule } from '@nestjs/schedule'\nimport { EventEmitterModule } from '@nestjs/event-emitter'\nimport { UsageModule } from './usage/usage.module'\nimport { AnalyticsModule } from './analytics/analytics.module'\nimport { OrganizationModule } from './organization/organization.module'\nimport { EmailModule } from './email/email.module'\nimport { TypedConfigService } from './config/typed-config.service'\nimport { TypedConfigModule } from './config/typed-config.module'\nimport { NotificationModule } from './notification/notification.module'\nimport { WebhookModule } from './webhook/webhook.module'\nimport { ObjectStorageModule } from './object-storage/object-storage.module'\nimport { CustomNamingStrategy } from './common/utils/naming-strategy.util'\nimport { MaintenanceMiddleware } from './common/middleware/maintenance.middleware'\nimport { AuditModule } from './audit/audit.module'\nimport { HealthModule } from './health/health.module'\nimport { OpenFeatureModule } from '@openfeature/nestjs-sdk'\nimport { OpenFeaturePostHogProvider } from './common/providers/openfeature-posthog.provider'\nimport { LoggerModule } from 'nestjs-pino'\nimport { getPinoTransport, swapMessageAndObject } from './common/utils/pino.util'\nimport { Redis } from 'ioredis'\nimport { ThrottlerStorageRedisService } from '@nest-lab/throttler-storage-redis'\nimport { RegionModule } from './region/region.module'\nimport { BodyParserErrorModule } from './common/modules/body-parser-error.module'\nimport { AdminModule } from './admin/admin.module'\nimport { ClickHouseModule } from './clickhouse/clickhouse.module'\nimport { SandboxTelemetryModule } from './sandbox-telemetry/sandbox-telemetry.module'\n\n@Module({\n  imports: [\n    LoggerModule.forRootAsync({\n      useFactory: (configService: TypedConfigService) => {\n        const logConfig = configService.get('log')\n        const isProduction = configService.get('production')\n        return {\n          pinoHttp: {\n            autoLogging: logConfig.requests.enabled,\n            level: logConfig.level,\n            hooks: {\n              logMethod: swapMessageAndObject,\n            },\n            quietReqLogger: true,\n            transport: getPinoTransport(isProduction, logConfig),\n          },\n        }\n      },\n      inject: [TypedConfigService],\n    }),\n    TypedConfigModule.forRoot({\n      isGlobal: true,\n    }),\n    TypeOrmModule.forRootAsync({\n      inject: [TypedConfigService],\n      useFactory: (configService: TypedConfigService) => {\n        return {\n          type: 'postgres',\n          host: configService.getOrThrow('database.host'),\n          port: configService.getOrThrow('database.port'),\n          username: configService.getOrThrow('database.username'),\n          password: configService.getOrThrow('database.password'),\n          database: configService.getOrThrow('database.database'),\n          autoLoadEntities: true,\n          migrations: [join(__dirname, 'migrations/**/*-migration.{ts,js}')],\n          migrationsRun: configService.get('runMigrations') || !configService.getOrThrow('production'),\n          namingStrategy: new CustomNamingStrategy(),\n          manualInitialization: configService.get('skipConnections'),\n          ssl: configService.get('database.tls.enabled')\n            ? {\n                rejectUnauthorized: configService.get('database.tls.rejectUnauthorized'),\n              }\n            : undefined,\n          extra: {\n            max: configService.get('database.pool.max'),\n            min: configService.get('database.pool.min'),\n            idleTimeoutMillis: configService.get('database.pool.idleTimeoutMillis'),\n            connectionTimeoutMillis: configService.get('database.pool.connectionTimeoutMillis'),\n          },\n          cache: {\n            type: 'ioredis',\n            ignoreErrors: true,\n            options: configService.getRedisConfig({ keyPrefix: 'typeorm:' }),\n          },\n          entitySkipConstructor: true,\n        }\n      },\n    }),\n    BodyParserErrorModule,\n    ServeStaticModule.forRoot({\n      rootPath: join(__dirname, '..'),\n      exclude: ['/api/{*path}'],\n      renderPath: '/runner-amd64',\n      serveStaticOptions: {\n        cacheControl: false,\n      },\n    }),\n    ServeStaticModule.forRoot({\n      rootPath: join(__dirname, '..', 'dashboard'),\n      exclude: ['/api/{*path}'],\n      renderPath: '/',\n      serveStaticOptions: {\n        cacheControl: false,\n      },\n    }),\n    RedisModule.forRootAsync({\n      inject: [TypedConfigService],\n      useFactory: (configService: TypedConfigService) => ({\n        type: 'single',\n        options: configService.getRedisConfig(),\n      }),\n    }),\n    RedisModule.forRootAsync(\n      {\n        inject: [TypedConfigService],\n        useFactory: (configService: TypedConfigService) => ({\n          type: 'single',\n          options: configService.getRedisConfig({ db: 1 }),\n        }),\n      },\n      'throttler',\n    ),\n    ThrottlerModule.forRootAsync({\n      useFactory: async (redis: Redis, configService: TypedConfigService) => {\n        const rateLimit = configService.get('rateLimit')\n        const throttlers = [\n          { name: 'anonymous', config: rateLimit.anonymous },\n          { name: 'failed-auth', config: rateLimit.failedAuth },\n          { name: 'authenticated', config: rateLimit.authenticated },\n          { name: 'sandbox-create', config: rateLimit.sandboxCreate },\n          { name: 'sandbox-lifecycle', config: rateLimit.sandboxLifecycle },\n        ]\n          .filter(({ config }) => config.ttl !== undefined && config.limit !== undefined)\n          .map(({ name, config }) => ({\n            name,\n            ttl: seconds(config.ttl),\n            limit: config.limit,\n          }))\n\n        return {\n          throttlers,\n          storage: new ThrottlerStorageRedisService(redis),\n        }\n      },\n      inject: [getRedisConnectionToken('throttler'), TypedConfigService],\n    }),\n    EventEmitterModule.forRoot({\n      maxListeners: 100,\n    }),\n    ApiKeyModule,\n    AuthModule,\n    UserModule,\n    SandboxModule,\n    DockerRegistryModule,\n    ScheduleModule.forRoot(),\n    UsageModule,\n    AnalyticsModule,\n    OrganizationModule,\n    RegionModule,\n    AdminModule,\n    EmailModule.forRootAsync({\n      inject: [TypedConfigService],\n      useFactory: (configService: TypedConfigService) => {\n        return {\n          host: configService.get('smtp.host'),\n          port: configService.get('smtp.port'),\n          user: configService.get('smtp.user'),\n          password: configService.get('smtp.password'),\n          secure: configService.get('smtp.secure'),\n          from: configService.get('smtp.from'),\n          dashboardUrl: configService.getOrThrow('dashboardUrl'),\n        }\n      },\n    }),\n    NotificationModule,\n    WebhookModule,\n    ObjectStorageModule,\n    AuditModule,\n    HealthModule,\n    ClickHouseModule,\n    SandboxTelemetryModule,\n    OpenFeatureModule.forRoot({\n      contextFactory: (request: ExecutionContext) => {\n        const req = request.switchToHttp().getRequest()\n\n        return {\n          targetingKey: req.user?.userId,\n          organizationId: req.user?.organizationId,\n        }\n      },\n      defaultProvider: new OpenFeaturePostHogProvider({\n        clientOptions: {\n          host: process.env.POSTHOG_HOST,\n        },\n        apiKey: process.env.POSTHOG_API_KEY,\n      }),\n    }),\n  ],\n  controllers: [],\n  providers: [AppService],\n})\nexport class AppModule implements NestModule {\n  configure(consumer: MiddlewareConsumer) {\n    consumer.apply(VersionHeaderMiddleware).forRoutes({ path: '{*path}', method: RequestMethod.ALL })\n    consumer.apply(FailedAuthRateLimitMiddleware).forRoutes({ path: '{*path}', method: RequestMethod.ALL })\n    consumer.apply(MaintenanceMiddleware).forRoutes({ path: '{*path}', method: RequestMethod.ALL })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/app.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, OnApplicationBootstrap, OnApplicationShutdown } from '@nestjs/common'\nimport { DockerRegistryService } from './docker-registry/services/docker-registry.service'\nimport { RegistryType } from './docker-registry/enums/registry-type.enum'\nimport { OrganizationService } from './organization/services/organization.service'\nimport { UserService } from './user/user.service'\nimport { ApiKeyService } from './api-key/api-key.service'\nimport { EventEmitterReadinessWatcher } from '@nestjs/event-emitter'\nimport { SnapshotService } from './sandbox/services/snapshot.service'\nimport { SystemRole } from './user/enums/system-role.enum'\nimport { TypedConfigService } from './config/typed-config.service'\nimport { SchedulerRegistry } from '@nestjs/schedule'\nimport { RegionService } from './region/services/region.service'\nimport { RunnerService } from './sandbox/services/runner.service'\nimport { RunnerAdapterFactory } from './sandbox/runner-adapter/runnerAdapter'\nimport { RegionType } from './region/enums/region-type.enum'\nimport { RunnerState } from './sandbox/enums/runner-state.enum'\n\nexport const DAYTONA_ADMIN_USER_ID = 'daytona-admin'\n\n@Injectable()\nexport class AppService implements OnApplicationBootstrap, OnApplicationShutdown {\n  private readonly logger = new Logger(AppService.name)\n\n  constructor(\n    private readonly dockerRegistryService: DockerRegistryService,\n    private readonly configService: TypedConfigService,\n    private readonly userService: UserService,\n    private readonly organizationService: OrganizationService,\n    private readonly apiKeyService: ApiKeyService,\n    private readonly eventEmitterReadinessWatcher: EventEmitterReadinessWatcher,\n    private readonly snapshotService: SnapshotService,\n    private readonly schedulerRegistry: SchedulerRegistry,\n    private readonly regionService: RegionService,\n    private readonly runnerService: RunnerService,\n    private readonly runnerAdapterFactory: RunnerAdapterFactory,\n  ) {}\n\n  async onApplicationShutdown(signal?: string) {\n    this.logger.log(`Received shutdown signal: ${signal}. Shutting down gracefully...`)\n    await this.stopAllCronJobs()\n  }\n\n  async onApplicationBootstrap() {\n    if (this.configService.get('disableCronJobs') || this.configService.get('maintananceMode')) {\n      await this.stopAllCronJobs()\n    }\n\n    await this.eventEmitterReadinessWatcher.waitUntilReady()\n\n    await this.initializeDefaultRegion()\n    await this.initializeAdminUser()\n    await this.initializeTransientRegistry()\n    await this.initializeBackupRegistry()\n    await this.initializeInternalRegistry()\n    await this.initializeBackupRegistry()\n\n    // Default runner init is not awaited because v2 runners depend on the API to be ready\n    this.initializeDefaultRunner()\n      .then(() => this.initializeDefaultSnapshot())\n      .catch((error) => {\n        this.logger.error('Error initializing default runner', error)\n      })\n  }\n\n  private async stopAllCronJobs(): Promise<void> {\n    for (const cronName of this.schedulerRegistry.getCronJobs().keys()) {\n      this.logger.debug(`Stopping cron job: ${cronName}`)\n      this.schedulerRegistry.deleteCronJob(cronName)\n    }\n  }\n\n  private async initializeDefaultRegion(): Promise<void> {\n    const existingRegion = await this.regionService.findOne(this.configService.getOrThrow('defaultRegion.id'))\n    if (existingRegion) {\n      return\n    }\n\n    this.logger.log('Initializing default region...')\n\n    await this.regionService.create(\n      {\n        id: this.configService.getOrThrow('defaultRegion.id'),\n        name: this.configService.getOrThrow('defaultRegion.name'),\n        enforceQuotas: this.configService.getOrThrow('defaultRegion.enforceQuotas'),\n        regionType: RegionType.SHARED,\n      },\n      null,\n    )\n\n    this.logger.log(`Default region created successfully: ${this.configService.getOrThrow('defaultRegion.name')}`)\n  }\n\n  private async initializeDefaultRunner(): Promise<void> {\n    if (!this.configService.get('defaultRunner.name')) {\n      return\n    }\n\n    const defaultRegionId = this.configService.getOrThrow('defaultRegion.id')\n\n    const existingRunners = await this.runnerService.findAllByRegion(defaultRegionId)\n    if (\n      existingRunners.length > 0 &&\n      existingRunners.some((r) => r.name === this.configService.get('defaultRunner.name'))\n    ) {\n      return\n    }\n\n    this.logger.log(`Creating default runner: ${this.configService.getOrThrow('defaultRunner.name')}`)\n\n    const runnerVersion = this.configService.getOrThrow('defaultRunner.apiVersion')\n\n    if (runnerVersion === '0') {\n      const { runner } = await this.runnerService.create({\n        apiUrl: this.configService.getOrThrow('defaultRunner.apiUrl'),\n        proxyUrl: this.configService.getOrThrow('defaultRunner.proxyUrl'),\n        apiKey: this.configService.getOrThrow('defaultRunner.apiKey'),\n        cpu: this.configService.getOrThrow('defaultRunner.cpu'),\n        memoryGiB: this.configService.getOrThrow('defaultRunner.memory'),\n        diskGiB: this.configService.getOrThrow('defaultRunner.disk'),\n        regionId: this.configService.getOrThrow('defaultRegion.id'),\n        domain: this.configService.getOrThrow('defaultRunner.domain'),\n        apiVersion: runnerVersion,\n        name: this.configService.getOrThrow('defaultRunner.name'),\n      })\n\n      const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n      this.logger.log(`Waiting for runner ${runner.name} to be healthy...`)\n      for (let i = 0; i < 30; i++) {\n        try {\n          await runnerAdapter.healthCheck()\n          this.logger.log(`Runner ${runner.name} is healthy`)\n          return\n        } catch {\n          // ignore\n        }\n        await new Promise((resolve) => setTimeout(resolve, 1000))\n      }\n    } else if (runnerVersion === '2') {\n      const { runner } = await this.runnerService.create({\n        apiKey: this.configService.getOrThrow('defaultRunner.apiKey'),\n        regionId: this.configService.getOrThrow('defaultRegion.id'),\n        apiVersion: runnerVersion,\n        name: this.configService.getOrThrow('defaultRunner.name'),\n      })\n\n      this.logger.log(`Waiting for runner ${runner.name} to be healthy...`)\n      for (let i = 0; i < 30; i++) {\n        const { state } = await this.runnerService.findOneFullOrFail(runner.id)\n        if (state === RunnerState.READY) {\n          this.logger.log(`Runner ${runner.name} is healthy`)\n          return\n        }\n        await new Promise((resolve) => setTimeout(resolve, 1000))\n      }\n    }\n\n    this.logger.log(\n      `Default runner ${this.configService.getOrThrow('defaultRunner.name')} created successfully but didn't pass health check`,\n    )\n  }\n\n  private async initializeAdminUser(): Promise<void> {\n    if (await this.userService.findOne(DAYTONA_ADMIN_USER_ID)) {\n      return\n    }\n\n    const user = await this.userService.create({\n      id: DAYTONA_ADMIN_USER_ID,\n      name: 'Daytona Admin',\n      personalOrganizationQuota: {\n        totalCpuQuota: this.configService.getOrThrow('admin.totalCpuQuota'),\n        totalMemoryQuota: this.configService.getOrThrow('admin.totalMemoryQuota'),\n        totalDiskQuota: this.configService.getOrThrow('admin.totalDiskQuota'),\n        maxCpuPerSandbox: this.configService.getOrThrow('admin.maxCpuPerSandbox'),\n        maxMemoryPerSandbox: this.configService.getOrThrow('admin.maxMemoryPerSandbox'),\n        maxDiskPerSandbox: this.configService.getOrThrow('admin.maxDiskPerSandbox'),\n        snapshotQuota: this.configService.getOrThrow('admin.snapshotQuota'),\n        maxSnapshotSize: this.configService.getOrThrow('admin.maxSnapshotSize'),\n        volumeQuota: this.configService.getOrThrow('admin.volumeQuota'),\n      },\n      personalOrganizationDefaultRegionId: this.configService.getOrThrow('defaultRegion.id'),\n      role: SystemRole.ADMIN,\n    })\n    const personalOrg = await this.organizationService.findPersonal(user.id)\n    const { value } = await this.apiKeyService.createApiKey(\n      personalOrg.id,\n      user.id,\n      DAYTONA_ADMIN_USER_ID,\n      [],\n      undefined,\n      this.configService.getOrThrow('admin.apiKey'),\n    )\n    this.logger.log(\n      `\n=========================================\n=========================================\nAdmin user created with API key: ${value}\n=========================================\n=========================================`,\n    )\n  }\n\n  private async initializeTransientRegistry(): Promise<void> {\n    const existingRegistry = await this.dockerRegistryService.getAvailableTransientRegistry(\n      this.configService.getOrThrow('defaultRegion.id'),\n    )\n    if (existingRegistry) {\n      return\n    }\n\n    const registryUrl = this.configService.getOrThrow('transientRegistry.url')\n    const registryAdmin = this.configService.getOrThrow('transientRegistry.admin')\n    const registryPassword = this.configService.getOrThrow('transientRegistry.password')\n    const registryProjectId = this.configService.getOrThrow('transientRegistry.projectId')\n\n    if (!registryUrl || !registryAdmin || !registryPassword || !registryProjectId) {\n      this.logger.warn('Registry configuration not found, skipping transient registry setup')\n      return\n    }\n\n    this.logger.log('Initializing default transient registry...')\n\n    await this.dockerRegistryService.create({\n      name: 'Transient Registry',\n      url: registryUrl,\n      username: registryAdmin,\n      password: registryPassword,\n      project: registryProjectId,\n      registryType: RegistryType.TRANSIENT,\n      isDefault: true,\n    })\n\n    this.logger.log('Default transient registry initialized successfully')\n  }\n\n  private async initializeInternalRegistry(): Promise<void> {\n    const existingRegistry = await this.dockerRegistryService.getAvailableInternalRegistry(\n      this.configService.getOrThrow('defaultRegion.id'),\n    )\n    if (existingRegistry) {\n      return\n    }\n\n    const registryUrl = this.configService.getOrThrow('internalRegistry.url')\n    const registryAdmin = this.configService.getOrThrow('internalRegistry.admin')\n    const registryPassword = this.configService.getOrThrow('internalRegistry.password')\n    const registryProjectId = this.configService.getOrThrow('internalRegistry.projectId')\n\n    if (!registryUrl || !registryAdmin || !registryPassword || !registryProjectId) {\n      this.logger.warn('Registry configuration not found, skipping internal registry setup')\n      return\n    }\n\n    this.logger.log('Initializing default internal registry...')\n\n    await this.dockerRegistryService.create({\n      name: 'Internal Registry',\n      url: registryUrl,\n      username: registryAdmin,\n      password: registryPassword,\n      project: registryProjectId,\n      registryType: RegistryType.INTERNAL,\n      isDefault: true,\n    })\n\n    this.logger.log('Default internal registry initialized successfully')\n  }\n\n  private async initializeBackupRegistry(): Promise<void> {\n    const existingRegistry = await this.dockerRegistryService.getAvailableBackupRegistry(\n      this.configService.getOrThrow('defaultRegion.id'),\n    )\n    if (existingRegistry) {\n      return\n    }\n\n    const registryUrl = this.configService.getOrThrow('internalRegistry.url')\n    const registryAdmin = this.configService.getOrThrow('internalRegistry.admin')\n    const registryPassword = this.configService.getOrThrow('internalRegistry.password')\n    const registryProjectId = this.configService.getOrThrow('internalRegistry.projectId')\n\n    if (!registryUrl || !registryAdmin || !registryPassword || !registryProjectId) {\n      this.logger.warn('Registry configuration not found, skipping backup registry setup')\n      return\n    }\n\n    this.logger.log('Initializing default backup registry...')\n\n    await this.dockerRegistryService.create(\n      {\n        name: 'Backup Registry',\n        url: registryUrl,\n        username: registryAdmin,\n        password: registryPassword,\n        project: registryProjectId,\n        registryType: RegistryType.BACKUP,\n        isDefault: true,\n      },\n      undefined,\n      true,\n    )\n\n    this.logger.log('Default backup registry initialized successfully')\n  }\n\n  private async initializeDefaultSnapshot(): Promise<void> {\n    const adminPersonalOrg = await this.organizationService.findPersonal(DAYTONA_ADMIN_USER_ID)\n\n    try {\n      const existingSnapshot = await this.snapshotService.getSnapshotByName(\n        this.configService.getOrThrow('defaultSnapshot'),\n        adminPersonalOrg.id,\n      )\n      if (existingSnapshot) {\n        return\n      }\n    } catch {\n      this.logger.log('Default snapshot not found, creating...')\n    }\n\n    const defaultSnapshot = this.configService.getOrThrow('defaultSnapshot')\n\n    await this.snapshotService.createFromPull(\n      adminPersonalOrg,\n      {\n        name: defaultSnapshot,\n        imageName: defaultSnapshot,\n      },\n      true,\n    )\n\n    this.logger.log('Default snapshot created successfully')\n  }\n}\n"
  },
  {
    "path": "apps/api/src/assets/.gitkeep",
    "content": ""
  },
  {
    "path": "apps/api/src/assets/templates/organization-invitation.template.ejs",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <title>Daytona Organization Invitation</title>\n</head>\n<body style=\"box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', serif; font-size: 14px; line-height: 1.5; color: rgb(36, 41, 46); margin: 0px; background-color: rgb(255, 255, 255); width: 100%; max-width: 100%;\">\n  <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:980px; margin-right:auto; margin-left:auto; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" width=\"100%\" align=\"center\">\n    <tbody>\n      <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n        <td style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:16px\" valign=\"top\" align=\"center\">\n          <center style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n            <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" width=\"100%\" align=\"center\">\n              <tbody>\n                <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                  <td style=\"box-sizing:border-box; border-radius:6px!important; display:block!important; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0; border:1px solid #e1e4e8\">\n                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; text-align:center!important; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" align=\"center\">\n                      <tbody>\n                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                          <td style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:32px 16px\">\n                            <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" width=\"100%\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                              <tbody>\n                                <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                  <td style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" align=\"center\">\n                                    <img style=\"box-sizing:border-box; display:inline-block; overflow:hidden; line-height:1; vertical-align:middle; border-radius:6px; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; border:1px solid #e1e4e8; max-width:100%; height:auto; width:72px; height:72px\" alt=\"Daytona logo\" src=\"https://www.daytona.io/brand/social-daytona-icon-light.png\" data-imagetype=\"External\"> \n                                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                      <tbody style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                          <td style=\"font-size:20px; line-height:20px; box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" height=\"20\">&nbsp;</td>\n                                        </tr>\n                                      </tbody>\n                                    </table>\n                                    <h1 style=\"box-sizing:border-box; margin-top:0; margin-bottom:0; font-size:24px; font-weight:600; line-height:1.25!important; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\"><% if (invitedBy) { %><%= invitedBy %> has invited you to join the <%= organizationName %> organization<% } else { %>You have been invited to join the <%= organizationName %> organization<% } %></h1>\n                                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                      <tbody style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                          <td style=\"font-size:32px; line-height:32px; box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" height=\"16\">&nbsp;</td>\n                                        </tr>\n                                      </tbody>\n                                    </table>\n                                    <p style=\"box-sizing:border-box; margin-top:0; margin-bottom:0; font-size:16px; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">This invitation expires on <%= expiresAt %></p>\n                                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                      <tbody style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                          <td style=\"font-size:32px; line-height:32px; box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" height=\"20\">&nbsp;</td>\n                                        </tr>\n                                      </tbody>\n                                    </table>\n                                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" width=\"100%\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                                      <tbody>\n                                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                          <td style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" align=\"center\">\n                                            <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" width=\"100%\">\n                                              <tbody>\n                                                <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                                  <td style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\">\n                                                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n                                                      <tbody>\n                                                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                                          <td style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" align=\"center\"><a style=\"background-color:rgb(0, 128, 255)!important; box-sizing:border-box; color:#fff; text-decoration:none; display:inline-block; font-size:16px; font-weight:500; line-height:1.5; white-space:nowrap; vertical-align:middle; border-radius:4px; box-shadow:0 1px 0 rgba(27,31,35,.1),inset 0 1px 0 rgba(255,255,255,.03); font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:10px 12px; margin:0; border:1px solid rgb(0, 128, 255)\" href=\"<%= invitationLink %>\">Join <%= organizationName %></a> </td>\n                                                        </tr>\n                                                      </tbody>\n                                                    </table>\n                                                  </td>\n                                                </tr>\n                                              </tbody>\n                                            </table>\n                                          </td>\n                                        </tr>\n                                      </tbody>\n                                    </table>\n                                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                      <tbody style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                                          <td style=\"font-size:32px; line-height:32px; box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" height=\"16\">&nbsp;</td>\n                                        </tr>\n                                      </tbody>\n                                    </table>\n                                    <p style=\"box-sizing:border-box; margin-top:0; margin-bottom:0; font-size:16px; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">Button not working? Paste the following link into your browser:<br style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\"><a style=\"background-color:transparent; box-sizing:border-box; color:rgb(0, 128, 255); text-decoration:none; word-break: break-all; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" href=\"<%= invitationLink %>\"><%= invitationLink %></a> </p>\n                                  </td>\n                                </tr>\n                              </tbody>\n                            </table>\n                          </td>\n                        </tr>\n                      </tbody>\n                    </table>\n                  </td>\n                </tr>\n              </tbody>\n            </table>\n            <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; text-align:center!important; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\" width=\"100%\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n              <tbody>\n                <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                  <td style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" align=\"center\">\n                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                      <tbody style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                          <td style=\"font-size:16px; line-height:16px; box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" height=\"8\">&nbsp;</td>\n                        </tr>\n                      </tbody>\n                    </table>\n                    <p style=\"box-sizing:border-box; margin-top:0; margin-bottom:0; font-size:12px!important; color:#9a9ea6; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">* If you were not expecting this invitation, please disregard this email.</p>\n                    <table style=\"box-sizing:border-box; border-spacing:0; border-collapse:collapse; width:100%!important; max-width:100%!important; margin:0; padding:0; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                      <tbody style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                        <tr style=\"box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">\n                          <td style=\"font-size:16px; line-height:16px; box-sizing:border-box; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important; padding:0\" height=\"16\">&nbsp;</td>\n                        </tr>\n                      </tbody>\n                    </table>\n                    <p style=\"box-sizing:border-box; margin-top:0; margin-bottom:0; color:#9a9ea6; font-size:12px!important; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'!important\">Copyright © <%= new Date().getFullYear() %> Daytona Platforms, Inc. All Rights Reserved</p>\n                  </td>\n                </tr>\n              </tbody>\n            </table>\n          </center>\n        </td>\n      </tr>\n    </tbody>\n  </table>\n  <div style=\"display: none; white-space: nowrap; box-sizing: border-box; font: 15px / 0 apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', serif;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>\n</body>\n</html>"
  },
  {
    "path": "apps/api/src/audit/adapters/audit-opensearch.adapter.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BadRequestException, Logger, OnModuleInit } from '@nestjs/common'\nimport { errors } from '@opensearch-project/opensearch'\nimport { AuditLog } from '../entities/audit-log.entity'\nimport { PaginatedList } from '../../common/interfaces/paginated-list.interface'\nimport { AuditLogStorageAdapter } from '../interfaces/audit-storage.interface'\nimport { AuditLogFilter } from '../interfaces/audit-filter.interface'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { OpensearchClient } from 'nestjs-opensearch'\nimport { PolicyEnvelope } from '@opensearch-project/opensearch/api/_types/ism._common.js'\nimport { QueryContainer } from '@opensearch-project/opensearch/api/_types/_common.query_dsl.js'\nimport { Bulk_RequestBody, Search_RequestBody, Search_Response } from '@opensearch-project/opensearch/api/index.js'\nimport { TotalHits } from '@opensearch-project/opensearch/api/_types/_core.search.js'\nimport { isMatch } from 'es-toolkit/compat'\n\n// Safe limit for offset-based pagination to avoid hitting OpenSearch's 10000 limit\nconst MAX_OFFSET_PAGINATION_LIMIT = 10000\n\nexport class AuditOpenSearchStorageAdapter implements AuditLogStorageAdapter, OnModuleInit {\n  private readonly logger = new Logger(AuditOpenSearchStorageAdapter.name)\n  private indexName: string\n\n  constructor(\n    private readonly configService: TypedConfigService,\n    private readonly client: OpensearchClient,\n  ) {\n    this.indexName = configService.getOrThrow('audit.publish.opensearchIndexName')\n  }\n\n  async onModuleInit(): Promise<void> {\n    await this.putIndexTemplate()\n    await this.setupISM()\n    await this.createDataStream()\n\n    this.logger.log('OpenSearch audit storage adapter initialized')\n  }\n\n  async write(auditLogs: AuditLog[]): Promise<void> {\n    try {\n      const documents = auditLogs.map((auditLog) => ({\n        '@timestamp': new Date(), // Required field for data streams\n        ...auditLog,\n      }))\n\n      // Include document ID to prevent duplicates\n      const bulkBody: Bulk_RequestBody = documents.flatMap((document) => [\n        { create: { _index: this.indexName, _id: document.id } },\n        document,\n      ])\n\n      const response = await this.client.bulk({\n        body: bulkBody,\n        refresh: false,\n      })\n\n      if (response.body.errors) {\n        const errors = response.body.items\n          .filter((item: any) => item.create?.error)\n          .map((item: any) => item.create.error)\n\n        // Check if any errors are not 409 (idempotent errors are OK) or version conflicts (also idempotent)\n        const nonIdempotentErrors = errors.filter(\n          (error: any) => error.status !== 409 && error.type !== 'version_conflict_engine_exception',\n        )\n\n        if (nonIdempotentErrors.length > 0) {\n          throw new Error(`OpenSearch bulk operation failed: ${JSON.stringify(nonIdempotentErrors)}`)\n        }\n      }\n\n      this.logger.debug(`Saved ${auditLogs.length} audit logs to OpenSearch`)\n    } catch (error) {\n      this.logger.error(`Failed to save audit log to OpenSearch: ${error.message}`)\n      throw error\n    }\n  }\n\n  async getAllLogs(\n    page?: number,\n    limit?: number,\n    filters?: AuditLogFilter,\n    nextToken?: string,\n  ): Promise<PaginatedList<AuditLog>> {\n    const query = this.buildDateRangeQuery(filters)\n    const searchBody = this.buildSearchBody(query, page, limit, nextToken)\n    const response = await this.executeSearch(searchBody)\n    return this.processSearchResponse(response, page, limit, nextToken, query)\n  }\n\n  async getOrganizationLogs(\n    organizationId: string,\n    page?: number,\n    limit?: number,\n    filters?: AuditLogFilter,\n    nextToken?: string,\n  ): Promise<PaginatedList<AuditLog>> {\n    if (!organizationId) {\n      throw new Error('Organization ID is required')\n    }\n\n    const query = this.buildOrganizationQuery(organizationId, filters)\n    const searchBody = this.buildSearchBody(query, page, limit, nextToken)\n    const response = await this.executeSearch(searchBody)\n    return this.processSearchResponse(response, page, limit, nextToken, query)\n  }\n\n  private async createDataStream() {\n    try {\n      await this.client.indices.createDataStream({ name: this.indexName })\n      this.logger.debug(`Created data stream: ${this.indexName}.`)\n    } catch (error) {\n      if (error instanceof errors.ResponseError && error.body.error.type === 'resource_already_exists_exception') {\n        this.logger.debug(`Data stream already exists: ${this.indexName}. Skipping creation.`)\n        return\n      }\n      throw error\n    }\n  }\n\n  private async putIndexTemplate() {\n    const templateName = `${this.indexName}-template`\n    await this.client.indices.putIndexTemplate({\n      name: templateName,\n      body: {\n        index_patterns: [`${this.indexName}*`],\n        data_stream: {},\n        template: {\n          settings: {\n            index: {\n              number_of_shards: 1,\n              number_of_replicas: 1,\n            },\n          },\n          mappings: {\n            dynamic: 'true',\n            dynamic_templates: [\n              {\n                ids_as_keyword: {\n                  match: '*Id',\n                  mapping: { type: 'keyword', index: true },\n                },\n              },\n              {\n                default_strings: {\n                  match: '*',\n                  match_mapping_type: 'string',\n                  mapping: { type: 'keyword', index: false },\n                },\n              },\n              {\n                non_queryable_fields: {\n                  match: '*',\n                  match_mapping_type: 'object',\n                  mapping: {\n                    type: 'object',\n                    enabled: false,\n                  },\n                },\n              },\n            ],\n            properties: {\n              id: { type: 'keyword' },\n              actorEmail: { type: 'keyword' },\n              action: { type: 'keyword' },\n              targetType: { type: 'keyword' },\n              statusCode: { type: 'integer' },\n              createdAt: { type: 'date' },\n            },\n          },\n        },\n      },\n    })\n  }\n\n  private mapSourceToAuditLog(source: any): AuditLog {\n    return new AuditLog({\n      id: source.id,\n      actorId: source.actorId,\n      actorEmail: source.actorEmail,\n      organizationId: source.organizationId,\n      action: source.action,\n      targetType: source.targetType,\n      targetId: source.targetId,\n      statusCode: source.statusCode,\n      errorMessage: source.errorMessage,\n      ipAddress: source.ipAddress,\n      userAgent: source.userAgent,\n      source: source.source,\n      metadata: source.metadata,\n      createdAt: new Date(source.createdAt),\n    })\n  }\n\n  private async setupISM(): Promise<void> {\n    try {\n      const retentionDays = this.configService.get('audit.retentionDays') || 0\n      if (!retentionDays || retentionDays < 1) {\n        this.logger.debug('Audit log retention not configured, skipping ISM setup')\n        return\n      }\n\n      await this.createISMPolicy(retentionDays)\n      await this.applyISMPolicyToIndexTemplate()\n\n      this.logger.debug(`OpenSearch ISM policy configured for ${retentionDays} days retention`)\n    } catch (error) {\n      this.logger.warn(`Failed to setup ISM policy: ${error.message}`)\n    }\n  }\n\n  private async createISMPolicy(retentionDays: number): Promise<void> {\n    const policyName = `${this.indexName}-lifecycle-policy`\n\n    const policy: PolicyEnvelope = {\n      policy: {\n        description: `Lifecycle policy for audit logs with ${retentionDays} days retention`,\n        default_state: 'hot',\n        states: [\n          {\n            name: 'hot',\n            actions: [\n              {\n                rollover: {\n                  // incorrect client type definitions\n                  // ref: https://github.com/opensearch-project/opensearch-js/issues/1001\n                  min_index_age: '30d' as any,\n                  min_primary_shard_size: '20gb' as any,\n                  min_doc_count: 20_000_000,\n                },\n              },\n            ],\n            transitions: [\n              {\n                state_name: 'delete',\n                conditions: {\n                  min_index_age: `${retentionDays}d`, // Delete after retention period\n                },\n              },\n            ],\n          },\n          {\n            name: 'delete',\n            actions: [\n              {\n                delete: {},\n              },\n            ],\n          },\n        ],\n        ism_template: [\n          {\n            index_patterns: [`${this.indexName}*`],\n            priority: 100,\n          },\n        ],\n      },\n    }\n\n    try {\n      // Check does policy already exist\n      const existingPolicy = await this.client.ism.getPolicy({\n        policy_id: policyName,\n      })\n\n      // Check does policy need to be updated\n      if (isMatch(existingPolicy.body, policy)) {\n        this.logger.debug(`ISM policy ${policyName} is up to date`)\n      } else {\n        this.logger.debug(`ISM policy ${policyName} is out of date. Updating it.`)\n        await this.client.ism.putPolicy({\n          policy_id: policyName,\n          if_primary_term: existingPolicy.body._primary_term,\n          if_seq_no: existingPolicy.body._seq_no,\n          body: policy,\n        })\n        this.logger.debug(`ISM policy ${policyName} updated`)\n      }\n    } catch (error) {\n      if (error instanceof errors.ResponseError && error.statusCode === 404) {\n        this.logger.debug(`ISM policy ${policyName} not found, creating it.`)\n        await this.client.ism.putPolicy({\n          policy_id: policyName,\n          body: policy,\n        })\n        this.logger.debug(`ISM policy ${policyName} created`)\n        return\n      }\n      this.logger.error(`Failed to create ISM policy`, error)\n      throw error\n    }\n  }\n\n  private async applyISMPolicyToIndexTemplate(): Promise<void> {\n    const templateName = `${this.indexName}-template`\n    const policyName = `${this.indexName}-lifecycle-policy`\n\n    try {\n      // Get existing template\n      const existingTemplate = await this.client.indices.getIndexTemplate({\n        name: templateName,\n      })\n\n      if (!existingTemplate.body?.index_templates?.[0]) {\n        this.logger.debug(`Index template ${templateName} not found, cannot apply ILM policy`)\n        return\n      }\n\n      // Update template with ILM policy\n      const template = existingTemplate.body.index_templates[0].index_template\n\n      // Add ILM settings to the template\n      if (!template.template) template.template = {}\n      if (!template.template.settings) template.template.settings = {}\n      if (!template.template.settings.index) template.template.settings.index = {}\n\n      template.template.settings.index = {\n        ...template.template.settings.index,\n        'plugins.index_state_management.policy_id': policyName,\n        'plugins.index_state_management.rollover_alias': this.indexName,\n        number_of_shards: 1,\n        number_of_replicas: 1,\n        refresh_interval: '5s',\n      }\n\n      // Update the template\n      await this.client.indices.putIndexTemplate({\n        name: templateName,\n        body: template,\n      })\n\n      this.logger.debug(`Applied ILM policy ${policyName} to index template ${templateName}`)\n    } catch (error) {\n      this.logger.error(`Failed to apply ILM policy to index template: ${error.message}`)\n    }\n  }\n\n  private buildDateRangeQuery(filters?: AuditLogFilter): QueryContainer {\n    return {\n      bool: {\n        filter: [\n          {\n            range: {\n              createdAt: {\n                gte: filters?.from?.toISOString(),\n                lte: filters?.to?.toISOString(),\n              },\n            },\n          },\n        ],\n      },\n    }\n  }\n\n  private buildOrganizationQuery(organizationId: string, filters?: AuditLogFilter): QueryContainer {\n    return {\n      bool: {\n        filter: [\n          {\n            term: { organizationId },\n          },\n          {\n            range: {\n              createdAt: {\n                gte: filters?.from?.toISOString(),\n                lte: filters?.to?.toISOString(),\n              },\n            },\n          },\n        ],\n      },\n    }\n  }\n\n  private buildSearchBody(\n    query: QueryContainer,\n    page?: number,\n    limit?: number,\n    nextToken?: string,\n  ): Search_RequestBody {\n    const size = limit\n    const searchBody: Search_RequestBody = {\n      query,\n      sort: [{ createdAt: { order: 'desc' } }, { id: { order: 'desc' } }],\n      size: size + 1, // Request one extra to check if there are more results\n    }\n\n    if (nextToken) {\n      // Cursor-based pagination using search_after\n      try {\n        const searchAfter = JSON.parse(Buffer.from(nextToken, 'base64').toString())\n        searchBody.search_after = searchAfter\n        this.logger.debug(`Using cursor-based pagination with search_after: ${JSON.stringify(searchAfter)}`)\n      } catch {\n        throw new BadRequestException(`Invalid nextToken provided: ${nextToken}`)\n      }\n    } else {\n      // Offset-based pagination - only use when within safe limits\n      const from = (page - 1) * limit\n      if (from + size <= MAX_OFFSET_PAGINATION_LIMIT) {\n        searchBody.from = from\n        this.logger.debug(`Using offset-based pagination: from=${from}, size=${size + 1}`)\n      } else {\n        throw new BadRequestException(\n          `Offset-based pagination not supported for page ${page} with limit ${limit}. Please use cursor-based pagination with nextToken parameter instead.`,\n        )\n      }\n    }\n\n    return searchBody\n  }\n\n  private async executeSearch(searchBody: Search_RequestBody) {\n    return await this.client.search({\n      index: this.indexName,\n      body: searchBody,\n      track_total_hits: MAX_OFFSET_PAGINATION_LIMIT,\n    })\n  }\n\n  private async processSearchResponse(\n    response: Search_Response,\n    page?: number,\n    limit?: number,\n    nextToken?: string,\n    query?: QueryContainer,\n  ): Promise<PaginatedList<AuditLog>> {\n    const size = limit\n    const hits = response.body.hits?.hits || []\n    const totalHits = response.body.hits?.total as TotalHits\n    const hasMore = hits.length > size\n    const items = hasMore ? hits.slice(0, size) : hits\n\n    // Generate nextToken when there are more results and we're approaching limits\n    let nextTokenResult: string | undefined\n    const currentOffset = nextToken ? 0 : (page - 1) * limit // If using cursor, we don't know the exact offset\n    const nextPageOffset = currentOffset + limit\n    const wouldExceedLimit = nextPageOffset >= MAX_OFFSET_PAGINATION_LIMIT\n\n    // Only generate nextToken if we're already using cursor pagination OR if the next page would exceed the limit\n    if (hasMore && items.length > 0 && (nextToken || wouldExceedLimit)) {\n      const lastItem = items[items.length - 1]\n      const searchAfter = [lastItem._source.createdAt, lastItem._source.id]\n      nextTokenResult = Buffer.from(JSON.stringify(searchAfter)).toString('base64')\n    }\n\n    let total = totalHits?.value\n    let totalPages = Math.ceil(total / limit)\n    if (totalHits?.relation === 'gte') {\n      // TODO: This should be cached to avoid hitting OpenSearch for every request\n      const totalResponse = await this.client.count({\n        index: this.indexName,\n        body: { query },\n      })\n      total = totalResponse.body.count\n      totalPages = Math.ceil(total / limit)\n    }\n\n    return {\n      items: items.map((hit) => this.mapSourceToAuditLog(hit._source)),\n      total,\n      page: page || 1,\n      totalPages,\n      nextToken: nextTokenResult,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/adapters/audit-typeorm.adapter.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Logger } from '@nestjs/common'\nimport { AuditLogStorageAdapter } from '../interfaces/audit-storage.interface'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { AuditLog } from '../entities/audit-log.entity'\nimport { FindManyOptions, Repository } from 'typeorm'\nimport { PaginatedList } from '../../common/interfaces/paginated-list.interface'\nimport { AuditLogFilter } from '../interfaces/audit-filter.interface'\nimport { createRangeFilter } from '../../common/utils/range-filter'\n\nexport class AuditTypeormStorageAdapter implements AuditLogStorageAdapter {\n  private readonly logger = new Logger(AuditTypeormStorageAdapter.name)\n\n  constructor(\n    @InjectRepository(AuditLog)\n    private readonly auditLogRepository: Repository<AuditLog>,\n  ) {}\n\n  async write(auditLogs: AuditLog[]): Promise<void> {\n    throw new Error('Typeorm adapter does not support writing audit logs.')\n  }\n\n  async getAllLogs(page?: number, limit = 1000, filters?: AuditLogFilter): Promise<PaginatedList<AuditLog>> {\n    const options: FindManyOptions<AuditLog> = {\n      order: {\n        createdAt: 'DESC',\n      },\n      skip: (page - 1) * limit,\n      take: limit,\n      where: {\n        createdAt: createRangeFilter(filters?.from, filters?.to),\n      },\n    }\n\n    const [items, total] = await this.auditLogRepository.findAndCount(options)\n\n    return {\n      items,\n      total,\n      page: page,\n      totalPages: Math.ceil(total / limit),\n    }\n  }\n\n  async getOrganizationLogs(\n    organizationId: string,\n    page?: number,\n    limit = 1000,\n    filters?: AuditLogFilter,\n  ): Promise<PaginatedList<AuditLog>> {\n    const options: FindManyOptions<AuditLog> = {\n      order: {\n        createdAt: 'DESC',\n      },\n      skip: (page - 1) * limit,\n      take: limit,\n      where: [\n        {\n          organizationId,\n          createdAt: createRangeFilter(filters?.from, filters?.to),\n        },\n      ],\n    }\n\n    const [items, total] = await this.auditLogRepository.findAndCount(options)\n\n    return {\n      items,\n      total,\n      page: page,\n      totalPages: Math.ceil(total / limit),\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/audit.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { OrganizationModule } from '../organization/organization.module'\nimport { AuditLog } from './entities/audit-log.entity'\nimport { AuditService } from './services/audit.service'\nimport { AuditInterceptor } from './interceptors/audit.interceptor'\nimport { AuditLogSubscriber } from './subscribers/audit-log.subscriber'\nimport { RedisLockProvider } from '../sandbox/common/redis-lock.provider'\nimport { AuditController } from './controllers/audit.controller'\nimport { AuditKafkaConsumerController } from './publishers/kafka/audit-kafka-consumer.controller'\nimport { ClientsModule, Transport } from '@nestjs/microservices'\nimport { TypedConfigService } from '../config/typed-config.service'\nimport { Partitioners } from 'kafkajs'\nimport { OpensearchModule } from 'nestjs-opensearch'\nimport { AuditStorageAdapterProvider } from './providers/audit-storage.provider'\nimport { AuditPublisherProvider } from './providers/audit-publisher.provider'\nimport { AUDIT_KAFKA_SERVICE } from './constants/audit-tokens'\n\n@Module({\n  imports: [\n    OrganizationModule,\n    TypeOrmModule.forFeature([AuditLog]),\n    ClientsModule.registerAsync([\n      {\n        name: AUDIT_KAFKA_SERVICE,\n        inject: [TypedConfigService],\n        useFactory: (configService: TypedConfigService) => {\n          return {\n            transport: Transport.KAFKA,\n            options: {\n              producerOnlyMode: true,\n              client: configService.getKafkaClientConfig(),\n              producer: {\n                allowAutoTopicCreation: true,\n                createPartitioner: Partitioners.DefaultPartitioner,\n                idempotent: true,\n              },\n            },\n          }\n        },\n      },\n    ]),\n    OpensearchModule.forRootAsync({\n      inject: [TypedConfigService],\n      useFactory: (configService: TypedConfigService) => {\n        return configService.getOpenSearchConfig()\n      },\n    }),\n  ],\n  controllers: [AuditController, AuditKafkaConsumerController],\n  providers: [\n    AuditService,\n    AuditInterceptor,\n    AuditLogSubscriber,\n    RedisLockProvider,\n    AuditStorageAdapterProvider,\n    AuditPublisherProvider,\n  ],\n  exports: [AuditService, AuditInterceptor],\n})\nexport class AuditModule {}\n"
  },
  {
    "path": "apps/api/src/audit/constants/audit-log-events.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const AuditLogEvents = {\n  CREATED: 'audit-log.created',\n  UPDATED: 'audit-log.updated',\n} as const\n"
  },
  {
    "path": "apps/api/src/audit/constants/audit-tokens.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const AUDIT_STORAGE_ADAPTER = 'AUDIT_STORAGE_ADAPTER'\nexport const AUDIT_LOG_PUBLISHER = 'AUDIT_LOG_PUBLISHER'\nexport const AUDIT_KAFKA_SERVICE = 'AUDIT_KAFKA_SERVICE'\nexport const AUDIT_KAFKA_TOPIC = 'audit-logs'\n"
  },
  {
    "path": "apps/api/src/audit/controllers/audit.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Get, Param, Query, UseGuards } from '@nestjs/common'\nimport { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiOAuth2, ApiParam } from '@nestjs/swagger'\nimport { AuditLogDto } from '../dto/audit-log.dto'\nimport { PaginatedAuditLogsDto } from '../dto/paginated-audit-logs.dto'\nimport { AuditService } from '../services/audit.service'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { SystemActionGuard } from '../../auth/system-action.guard'\nimport { RequiredSystemRole } from '../../common/decorators/required-role.decorator'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { RequiredOrganizationResourcePermissions } from '../../organization/decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { ListAuditLogsQueryDto } from '../dto/list-audit-logs-query.dto'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('audit')\n@Controller('audit')\n@UseGuards(CombinedAuthGuard, SystemActionGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class AuditController {\n  constructor(private readonly auditService: AuditService) {}\n\n  @Get()\n  @ApiOperation({\n    summary: 'Get all audit logs',\n    operationId: 'getAllAuditLogs',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Paginated list of all audit logs',\n    type: PaginatedAuditLogsDto,\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  async getAllLogs(@Query() query: ListAuditLogsQueryDto): Promise<PaginatedAuditLogsDto> {\n    const result = await this.auditService.getAllLogs(\n      query.page,\n      query.limit,\n      {\n        from: query.from,\n        to: query.to,\n      },\n      query.nextToken,\n    )\n    return {\n      items: result.items.map(AuditLogDto.fromAuditLog),\n      total: result.total,\n      page: result.page,\n      totalPages: result.totalPages,\n      nextToken: result.nextToken,\n    }\n  }\n\n  @Get('/organizations/:organizationId')\n  @ApiOperation({\n    summary: 'Get audit logs for organization',\n    operationId: 'getOrganizationAuditLogs',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Paginated list of organization audit logs',\n    type: PaginatedAuditLogsDto,\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.READ_AUDIT_LOGS])\n  async getOrganizationLogs(\n    @Param('organizationId') organizationId: string,\n    @Query() query: ListAuditLogsQueryDto,\n  ): Promise<PaginatedAuditLogsDto> {\n    const result = await this.auditService.getOrganizationLogs(\n      organizationId,\n      query.page,\n      query.limit,\n      {\n        from: query.from,\n        to: query.to,\n      },\n      query.nextToken,\n    )\n    return {\n      items: result.items.map(AuditLogDto.fromAuditLog),\n      total: result.total,\n      page: result.page,\n      totalPages: result.totalPages,\n      nextToken: result.nextToken,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/decorators/audit.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SetMetadata } from '@nestjs/common'\nimport { Request } from 'express'\nimport { AuditAction } from '../enums/audit-action.enum'\nimport { AuditTarget } from '../enums/audit-target.enum'\n\nexport type TypedRequest<T> = Omit<Request, 'body'> & { body: T }\n\nexport const MASKED_AUDIT_VALUE = '********'\n\nexport interface AuditContext {\n  action: AuditAction\n  targetType?: AuditTarget\n  targetIdFromRequest?: (req: Request) => string | null | undefined\n  targetIdFromResult?: (result: any) => string | null | undefined\n  requestMetadata?: Record<string, (req: Request) => any>\n}\n\nexport const AUDIT_CONTEXT_KEY = 'audit_context'\n\nexport const Audit = (context: AuditContext) => SetMetadata(AUDIT_CONTEXT_KEY, context)\n"
  },
  {
    "path": "apps/api/src/audit/dto/audit-log.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { AuditLog, AuditLogMetadata } from '../entities/audit-log.entity'\n\n@ApiSchema({ name: 'AuditLog' })\nexport class AuditLogDto {\n  @ApiProperty()\n  id: string\n\n  @ApiProperty()\n  actorId: string\n\n  @ApiProperty()\n  actorEmail: string\n\n  @ApiPropertyOptional()\n  organizationId?: string\n\n  @ApiProperty()\n  action: string\n\n  @ApiPropertyOptional()\n  targetType?: string\n\n  @ApiPropertyOptional()\n  targetId?: string\n\n  @ApiPropertyOptional()\n  statusCode?: number\n\n  @ApiPropertyOptional()\n  errorMessage?: string\n\n  @ApiPropertyOptional()\n  ipAddress?: string\n\n  @ApiPropertyOptional()\n  userAgent?: string\n\n  @ApiPropertyOptional()\n  source?: string\n\n  @ApiPropertyOptional({\n    type: 'object',\n    additionalProperties: true,\n  })\n  metadata?: AuditLogMetadata\n\n  @ApiProperty()\n  createdAt: Date\n\n  static fromAuditLog(auditLog: AuditLog): AuditLogDto {\n    return {\n      id: auditLog.id,\n      actorId: auditLog.actorId,\n      actorEmail: auditLog.actorEmail,\n      organizationId: auditLog.organizationId,\n      action: auditLog.action,\n      targetType: auditLog.targetType,\n      targetId: auditLog.targetId,\n      statusCode: auditLog.statusCode,\n      errorMessage: auditLog.errorMessage,\n      ipAddress: auditLog.ipAddress,\n      userAgent: auditLog.userAgent,\n      source: auditLog.source,\n      metadata: auditLog.metadata,\n      createdAt: auditLog.createdAt,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/dto/create-audit-log-internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AuditLogMetadata } from '../entities/audit-log.entity'\nimport { AuditAction } from '../enums/audit-action.enum'\nimport { AuditTarget } from '../enums/audit-target.enum'\n\nexport class CreateAuditLogInternalDto {\n  actorId: string\n  actorEmail: string\n  organizationId?: string\n  action: AuditAction\n  targetType?: AuditTarget\n  targetId?: string\n  statusCode?: number\n  errorMessage?: string\n  ipAddress?: string\n  userAgent?: string\n  source?: string\n  metadata?: AuditLogMetadata\n}\n"
  },
  {
    "path": "apps/api/src/audit/dto/create-audit-log.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsEnum, IsOptional } from 'class-validator'\nimport { AuditAction } from '../enums/audit-action.enum'\nimport { AuditTarget } from '../enums/audit-target.enum'\n\n@ApiSchema({ name: 'CreateAuditLog' })\nexport class CreateAuditLogDto {\n  @ApiProperty()\n  actorId: string\n\n  @ApiProperty()\n  actorEmail: string\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  organizationId?: string\n\n  @ApiProperty({\n    enum: AuditAction,\n  })\n  @IsEnum(AuditAction)\n  action: AuditAction\n\n  @ApiPropertyOptional({\n    enum: AuditTarget,\n  })\n  @IsOptional()\n  @IsEnum(AuditTarget)\n  targetType?: AuditTarget\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  targetId?: string\n}\n"
  },
  {
    "path": "apps/api/src/audit/dto/list-audit-logs-query.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { PageNumber } from '../../common/decorators/page-number.decorator'\nimport { PageLimit } from '../../common/decorators/page-limit.decorator'\nimport { IsDate, IsOptional, IsString } from 'class-validator'\nimport { Type } from 'class-transformer'\n\n@ApiSchema({ name: 'ListAuditLogsQuery' })\nexport class ListAuditLogsQueryDto {\n  @PageNumber(1)\n  page = 1\n\n  @PageLimit(100)\n  limit = 100\n\n  @ApiPropertyOptional({ type: String, format: 'date-time', description: 'From date (ISO 8601 format)' })\n  @IsOptional()\n  @Type(() => Date)\n  @IsDate()\n  from?: Date\n\n  @ApiPropertyOptional({ type: String, format: 'date-time', description: 'To date (ISO 8601 format)' })\n  @IsOptional()\n  @Type(() => Date)\n  @IsDate()\n  to?: Date\n\n  @ApiPropertyOptional({\n    type: String,\n    description: 'Token for cursor-based pagination. When provided, takes precedence over page parameter.',\n  })\n  @IsOptional()\n  @IsString()\n  nextToken?: string\n}\n"
  },
  {
    "path": "apps/api/src/audit/dto/paginated-audit-logs.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { AuditLogDto } from './audit-log.dto'\n\n@ApiSchema({ name: 'PaginatedAuditLogs' })\nexport class PaginatedAuditLogsDto {\n  @ApiProperty({ type: [AuditLogDto] })\n  items: AuditLogDto[]\n\n  @ApiProperty()\n  total: number\n\n  @ApiProperty()\n  page: number\n\n  @ApiProperty()\n  totalPages: number\n\n  @ApiProperty({ required: false, description: 'Token for next page in cursor-based pagination' })\n  nextToken?: string\n}\n"
  },
  {
    "path": "apps/api/src/audit/dto/update-audit-log-internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class UpdateAuditLogInternalDto {\n  statusCode?: number\n  errorMessage?: string\n  targetId?: string\n  organizationId?: string\n}\n"
  },
  {
    "path": "apps/api/src/audit/entities/audit-log.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, Index } from 'typeorm'\nimport { v4 } from 'uuid'\n\nexport type AuditLogMetadata = Record<string, any>\n\n@Entity()\n@Index(['createdAt'])\n@Index(['organizationId', 'createdAt'])\nexport class AuditLog {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column()\n  actorId: string\n\n  @Column({\n    default: '',\n  })\n  actorEmail: string\n\n  @Column({ nullable: true })\n  organizationId?: string\n\n  @Column()\n  action: string\n\n  @Column({ nullable: true })\n  targetType?: string\n\n  @Column({ nullable: true })\n  targetId?: string\n\n  @Column({ nullable: true })\n  statusCode?: number\n\n  @Column({ nullable: true })\n  errorMessage?: string\n\n  @Column({ nullable: true })\n  ipAddress?: string\n\n  @Column({ type: 'text', nullable: true })\n  userAgent?: string\n\n  @Column({ nullable: true })\n  source?: string\n\n  @Column({ type: 'jsonb', nullable: true })\n  metadata?: AuditLogMetadata\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  constructor(params: {\n    id?: string\n    actorId: string\n    actorEmail: string\n    organizationId?: string\n    action: string\n    targetType?: string\n    targetId?: string\n    statusCode?: number\n    errorMessage?: string\n    ipAddress?: string\n    userAgent?: string\n    source?: string\n    metadata?: AuditLogMetadata\n    createdAt?: Date\n  }) {\n    this.id = params.id || v4()\n    this.actorId = params.actorId\n    this.actorEmail = params.actorEmail\n    this.organizationId = params.organizationId\n    this.action = params.action\n    this.targetType = params.targetType\n    this.targetId = params.targetId\n    this.statusCode = params.statusCode\n    this.errorMessage = params.errorMessage\n    this.ipAddress = params.ipAddress\n    this.userAgent = params.userAgent\n    this.source = params.source\n    this.metadata = params.metadata\n    this.createdAt = params.createdAt || new Date()\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/enums/audit-action.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum AuditAction {\n  CREATE = 'create',\n  READ = 'read',\n  UPDATE = 'update',\n  DELETE = 'delete',\n  LOGIN = 'login',\n  SET_DEFAULT = 'set_default',\n  UPDATE_ACCESS = 'update_access',\n  UPDATE_QUOTA = 'update_quota',\n  UPDATE_REGION_QUOTA = 'update_region_quota',\n  SUSPEND = 'suspend',\n  UNSUSPEND = 'unsuspend',\n  ACCEPT = 'accept',\n  DECLINE = 'decline',\n  LINK_ACCOUNT = 'link_account',\n  UNLINK_ACCOUNT = 'unlink_account',\n  LEAVE_ORGANIZATION = 'leave_organization',\n  REGENERATE_KEY_PAIR = 'regenerate_key_pair',\n  UPDATE_SCHEDULING = 'update_scheduling',\n  UPDATE_DRAINING = 'update_draining',\n  START = 'start',\n  STOP = 'stop',\n  RESIZE = 'resize',\n  REPLACE_LABELS = 'replace_labels',\n  CREATE_BACKUP = 'create_backup',\n  UPDATE_PUBLIC_STATUS = 'update_public_status',\n  SET_AUTO_STOP_INTERVAL = 'set_auto_stop_interval',\n  SET_AUTO_ARCHIVE_INTERVAL = 'set_auto_archive_interval',\n  SET_AUTO_DELETE_INTERVAL = 'set_auto_delete_interval',\n  ARCHIVE = 'archive',\n  GET_PORT_PREVIEW_URL = 'get_port_preview_url',\n  SET_GENERAL_STATUS = 'set_general_status',\n  ACTIVATE = 'activate',\n  DEACTIVATE = 'deactivate',\n  UPDATE_NETWORK_SETTINGS = 'update_network_settings',\n  SEND_WEBHOOK_MESSAGE = 'send_webhook_message',\n  INITIALIZE_WEBHOOKS = 'initialize_webhooks',\n  UPDATE_SANDBOX_DEFAULT_LIMITED_NETWORK_EGRESS = 'update_sandbox_default_limited_network_egress',\n  CREATE_SSH_ACCESS = 'create_ssh_access',\n  REVOKE_SSH_ACCESS = 'revoke_ssh_access',\n  RECOVER = 'recover',\n  REGENERATE_PROXY_API_KEY = 'regenerate_proxy_api_key',\n  REGENERATE_SSH_GATEWAY_API_KEY = 'regenerate_ssh_gateway_api_key',\n  REGENERATE_SNAPSHOT_MANAGER_CREDENTIALS = 'regenerate_snapshot_manager_credentials',\n  // toolbox actions (must be prefixed with 'toolbox_')\n  TOOLBOX_DELETE_FILE = 'toolbox_delete_file',\n  TOOLBOX_DOWNLOAD_FILE = 'toolbox_download_file',\n  TOOLBOX_CREATE_FOLDER = 'toolbox_create_folder',\n  TOOLBOX_MOVE_FILE = 'toolbox_move_file',\n  TOOLBOX_SET_FILE_PERMISSIONS = 'toolbox_set_file_permissions',\n  TOOLBOX_REPLACE_IN_FILES = 'toolbox_replace_in_files',\n  TOOLBOX_UPLOAD_FILE = 'toolbox_upload_file',\n  TOOLBOX_BULK_UPLOAD_FILES = 'toolbox_bulk_upload_files',\n  TOOLBOX_GIT_ADD_FILES = 'toolbox_git_add_files',\n  TOOLBOX_GIT_CREATE_BRANCH = 'toolbox_git_create_branch',\n  TOOLBOX_GIT_DELETE_BRANCH = 'toolbox_git_delete_branch',\n  TOOLBOX_GIT_CLONE_REPOSITORY = 'toolbox_git_clone_repository',\n  TOOLBOX_GIT_COMMIT_CHANGES = 'toolbox_git_commit_changes',\n  TOOLBOX_GIT_PULL_CHANGES = 'toolbox_git_pull_changes',\n  TOOLBOX_GIT_PUSH_CHANGES = 'toolbox_git_push_changes',\n  TOOLBOX_GIT_CHECKOUT_BRANCH = 'toolbox_git_checkout_branch',\n  TOOLBOX_EXECUTE_COMMAND = 'toolbox_execute_command',\n  TOOLBOX_CREATE_SESSION = 'toolbox_create_session',\n  TOOLBOX_SESSION_EXECUTE_COMMAND = 'toolbox_session_execute_command',\n  TOOLBOX_DELETE_SESSION = 'toolbox_delete_session',\n  TOOLBOX_COMPUTER_USE_START = 'toolbox_computer_use_start',\n  TOOLBOX_COMPUTER_USE_STOP = 'toolbox_computer_use_stop',\n  TOOLBOX_COMPUTER_USE_RESTART_PROCESS = 'toolbox_computer_use_restart_process',\n}\n"
  },
  {
    "path": "apps/api/src/audit/enums/audit-target.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum AuditTarget {\n  API_KEY = 'api_key',\n  ORGANIZATION = 'organization',\n  ORGANIZATION_INVITATION = 'organization_invitation',\n  ORGANIZATION_ROLE = 'organization_role',\n  ORGANIZATION_USER = 'organization_user',\n  DOCKER_REGISTRY = 'docker_registry',\n  RUNNER = 'runner',\n  SANDBOX = 'sandbox',\n  SNAPSHOT = 'snapshot',\n  USER = 'user',\n  VOLUME = 'volume',\n  REGION = 'region',\n}\n"
  },
  {
    "path": "apps/api/src/audit/events/audit-log-created.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AuditLog } from '../entities/audit-log.entity'\n\nexport class AuditLogCreatedEvent {\n  constructor(public readonly auditLog: AuditLog) {}\n}\n"
  },
  {
    "path": "apps/api/src/audit/events/audit-log-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AuditLog } from '../entities/audit-log.entity'\n\nexport class AuditLogUpdatedEvent {\n  constructor(public readonly auditLog: AuditLog) {}\n}\n"
  },
  {
    "path": "apps/api/src/audit/interceptors/audit.interceptor.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Injectable,\n  NestInterceptor,\n  ExecutionContext,\n  CallHandler,\n  Logger,\n  UnauthorizedException,\n  InternalServerErrorException,\n  HttpException,\n  HttpStatus,\n} from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { Request, Response } from 'express'\nimport { Observable, Subscriber, firstValueFrom } from 'rxjs'\nimport { AUDIT_CONTEXT_KEY, AuditContext } from '../decorators/audit.decorator'\nimport { AuditLog, AuditLogMetadata } from '../entities/audit-log.entity'\nimport { AuditAction } from '../enums/audit-action.enum'\nimport { AuditService } from '../services/audit.service'\nimport { AuthContext } from '../../common/interfaces/auth-context.interface'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { TypedConfigService } from '../../config/typed-config.service'\n\ntype RequestWithUser = Request & {\n  user?: AuthContext\n}\n\n@Injectable()\nexport class AuditInterceptor implements NestInterceptor {\n  private readonly logger = new Logger(AuditInterceptor.name)\n\n  constructor(\n    private readonly reflector: Reflector,\n    private readonly auditService: AuditService,\n    private readonly configService: TypedConfigService,\n  ) {}\n\n  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {\n    const request = context.switchToHttp().getRequest<RequestWithUser>()\n    const response = context.switchToHttp().getResponse<Response>()\n\n    const auditContext = this.reflector.get<AuditContext>(AUDIT_CONTEXT_KEY, context.getHandler())\n\n    // Non-audited request\n    if (!auditContext) {\n      return next.handle()\n    }\n\n    // Toolbox requests are not audited by default\n    if (this.isToolboxAction(auditContext.action) && !this.configService.get('audit.toolboxRequestsEnabled')) {\n      return next.handle()\n    }\n\n    if (!request.user) {\n      this.logger.error('No user context found for audited request:', request.url)\n      throw new UnauthorizedException()\n    }\n\n    return new Observable((observer) => {\n      this.handleAuditedRequest(auditContext, request, response, next, observer)\n    })\n  }\n\n  // An audit log must be created before the request is passed to the request handler\n  // After the request handler returns, the audit log is optimistically updated with the outcome\n  private async handleAuditedRequest(\n    auditContext: AuditContext,\n    request: RequestWithUser,\n    response: Response,\n    next: CallHandler,\n    observer: Subscriber<any>,\n  ): Promise<void> {\n    try {\n      const auditLog = await this.auditService.createLog({\n        actorId: request.user.userId,\n        actorEmail: request.user.email,\n        organizationId: request.user.organizationId,\n        action: auditContext.action,\n        targetType: auditContext.targetType,\n        targetId: this.resolveTargetId(auditContext, request),\n        ipAddress: request.ip,\n        userAgent: request.get('user-agent'),\n        source: request.get(CustomHeaders.SOURCE.name),\n        metadata: this.resolveRequestMetadata(auditContext, request),\n      })\n\n      try {\n        const result = await firstValueFrom(next.handle())\n\n        const organizationId = this.resolveOrganizationId(request, result)\n        const targetId = this.resolveTargetId(auditContext, request, result)\n        const statusCode = response.statusCode || HttpStatus.NO_CONTENT\n        await this.recordHandlerSuccess(auditLog, organizationId, targetId, statusCode)\n\n        observer.next(result)\n        observer.complete()\n      } catch (handlerError) {\n        const errorMessage =\n          handlerError instanceof HttpException ? handlerError.message : 'An unexpected error occurred.'\n        const statusCode = this.resolveErrorStatusCode(handlerError)\n        await this.recordHandlerError(auditLog, errorMessage, statusCode)\n\n        observer.error(handlerError)\n      }\n    } catch (createLogError) {\n      this.logger.error('Failed to create audit log:', createLogError)\n      observer.error(new InternalServerErrorException())\n    }\n  }\n\n  private resolveOrganizationId(request: RequestWithUser, result?: any): string | null {\n    return result?.organizationId || request.user.organizationId\n  }\n\n  /**\n   * Resolves the identifier of the target resource from the initial request or the response object.\n   *\n   * Prioritizes resolving the ID from the response object as the request may not include a unique resource identifier (e.g. delete sandbox by name).\n   */\n  private resolveTargetId(auditContext: AuditContext, request: RequestWithUser, result?: any): string | null {\n    if (auditContext.targetIdFromResult && result) {\n      const targetId = auditContext.targetIdFromResult(result)\n      if (targetId) {\n        return targetId\n      }\n    }\n\n    if (auditContext.targetIdFromRequest) {\n      const targetId = auditContext.targetIdFromRequest(request)\n      if (targetId) {\n        return targetId\n      }\n    }\n\n    return null\n  }\n\n  private resolveRequestMetadata(auditContext: AuditContext, request: RequestWithUser): AuditLogMetadata | null {\n    if (!auditContext.requestMetadata) {\n      return null\n    }\n\n    const resolvedMetadata: AuditLogMetadata = {}\n\n    for (const [key, resolver] of Object.entries(auditContext.requestMetadata)) {\n      try {\n        resolvedMetadata[key] = resolver(request)\n      } catch (error) {\n        this.logger.warn(`Failed to resolve audit log metadata key \"${key}\":`, error)\n        resolvedMetadata[key] = null\n      }\n    }\n\n    return Object.keys(resolvedMetadata).length > 0 ? resolvedMetadata : null\n  }\n\n  private isToolboxAction(action: AuditAction): boolean {\n    return action.startsWith('toolbox_')\n  }\n\n  private async recordHandlerSuccess(\n    auditLog: AuditLog,\n    organizationId: string | null,\n    targetId: string | null,\n    statusCode: number,\n  ): Promise<void> {\n    try {\n      await this.auditService.updateLog(auditLog.id, {\n        organizationId,\n        targetId,\n        statusCode,\n      })\n    } catch (error) {\n      this.logger.error('Failed to record handler result:', error)\n    }\n  }\n\n  private async recordHandlerError(auditLog: AuditLog, errorMessage: string, statusCode: number): Promise<void> {\n    try {\n      await this.auditService.updateLog(auditLog.id, {\n        errorMessage,\n        statusCode,\n      })\n    } catch (error) {\n      this.logger.error('Failed to record handler error:', error)\n    }\n  }\n\n  private resolveErrorStatusCode(error: any): number {\n    if (error instanceof HttpException) {\n      return error.getStatus()\n    }\n\n    return HttpStatus.INTERNAL_SERVER_ERROR\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/interfaces/audit-filter.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface AuditLogFilter {\n  from?: Date\n  to?: Date\n}\n"
  },
  {
    "path": "apps/api/src/audit/interfaces/audit-publisher.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AuditLog } from '../entities/audit-log.entity'\n\n/**\n * Interface for audit log publisher operations\n * Handles publishing audit logs\n */\nexport interface AuditLogPublisher {\n  /**\n   * Publish audit logs\n   */\n  write(auditLogs: AuditLog[]): Promise<void>\n}\n"
  },
  {
    "path": "apps/api/src/audit/interfaces/audit-storage.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AuditLog } from '../entities/audit-log.entity'\nimport { PaginatedList } from '../../common/interfaces/paginated-list.interface'\nimport { AuditLogFilter } from './audit-filter.interface'\n\n/**\n * Interface for audit log storage operations\n * Handles persistent storage and audit logs queries\n */\nexport interface AuditLogStorageAdapter {\n  /**\n   * Write audit logs to storage\n   */\n  write(auditLogs: AuditLog[]): Promise<void>\n\n  /**\n   * Get all audit logs\n   * @param page - Page number (1-based) for offset-based pagination\n   * @param limit - Number of items per page\n   * @param filters - Optional filters\n   * @param nextToken - Cursor token for cursor-based pagination (takes precedence over page)\n   */\n  getAllLogs(\n    page?: number,\n    limit?: number,\n    filters?: AuditLogFilter,\n    nextToken?: string,\n  ): Promise<PaginatedList<AuditLog>>\n\n  /**\n   * Get audit logs for organization\n   * @param organizationId - Organization ID\n   * @param page - Page number (1-based) for offset-based pagination\n   * @param limit - Number of items per page\n   * @param filters - Optional filters\n   * @param nextToken - Cursor token for cursor-based pagination (takes precedence over page)\n   */\n  getOrganizationLogs(\n    organizationId: string,\n    page?: number,\n    limit?: number,\n    filters?: AuditLogFilter,\n    nextToken?: string,\n  ): Promise<PaginatedList<AuditLog>>\n}\n"
  },
  {
    "path": "apps/api/src/audit/providers/audit-publisher.provider.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Provider } from '@nestjs/common'\nimport { AuditKafkaPublisher } from '../publishers/kafka/audit-kafka-publisher'\nimport { AuditDirectPublisher } from '../publishers/audit-direct-publisher'\nimport { AuditLogStorageAdapter } from '../interfaces/audit-storage.interface'\nimport { AuditLogPublisher } from '../interfaces/audit-publisher.interface'\nimport { AUDIT_KAFKA_SERVICE, AUDIT_STORAGE_ADAPTER, AUDIT_LOG_PUBLISHER } from '../constants/audit-tokens'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { ClientKafka } from '@nestjs/microservices'\n\nexport const AuditPublisherProvider: Provider = {\n  provide: AUDIT_LOG_PUBLISHER,\n  useFactory: (\n    configService: TypedConfigService,\n    kafkaService: ClientKafka,\n    auditStorageAdapter: AuditLogStorageAdapter,\n  ): AuditLogPublisher => {\n    const auditConfig = configService.get('audit')\n\n    if (!auditConfig.publish.enabled) {\n      return\n    }\n\n    switch (auditConfig.publish.mode) {\n      case 'direct':\n        return new AuditDirectPublisher(auditStorageAdapter)\n      case 'kafka':\n        if (!configService.get('kafka.enabled')) {\n          throw new Error('Kafka must be enabled to publish audit logs to Kafka')\n        }\n        return new AuditKafkaPublisher(kafkaService)\n      default:\n        throw new Error(`Invalid publish mode: ${auditConfig.publish.mode}`)\n    }\n  },\n  inject: [TypedConfigService, AUDIT_KAFKA_SERVICE, AUDIT_STORAGE_ADAPTER],\n}\n"
  },
  {
    "path": "apps/api/src/audit/providers/audit-storage.provider.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Provider } from '@nestjs/common'\nimport { getRepositoryToken } from '@nestjs/typeorm'\nimport { AuditOpenSearchStorageAdapter } from '../adapters/audit-opensearch.adapter'\nimport { AuditLogStorageAdapter } from '../interfaces/audit-storage.interface'\nimport { AUDIT_STORAGE_ADAPTER } from '../constants/audit-tokens'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { OpensearchClient } from 'nestjs-opensearch'\nimport { AuditTypeormStorageAdapter } from '../adapters/audit-typeorm.adapter'\nimport { Repository } from 'typeorm'\nimport { AuditLog } from '../entities/audit-log.entity'\n\nexport const AuditStorageAdapterProvider: Provider = {\n  provide: AUDIT_STORAGE_ADAPTER,\n  useFactory: (\n    configService: TypedConfigService,\n    opensearchClient: OpensearchClient,\n    auditLogRepository: Repository<AuditLog>,\n  ): AuditLogStorageAdapter => {\n    const auditConfig = configService.get('audit')\n\n    if (auditConfig.publish.enabled) {\n      switch (auditConfig.publish.storageAdapter) {\n        case 'opensearch': {\n          return new AuditOpenSearchStorageAdapter(configService, opensearchClient)\n        }\n        default:\n          throw new Error(`Invalid storage adapter: ${auditConfig.publish.storageAdapter}`)\n      }\n    } else {\n      return new AuditTypeormStorageAdapter(auditLogRepository)\n    }\n  },\n  inject: [TypedConfigService, OpensearchClient, getRepositoryToken(AuditLog)],\n}\n"
  },
  {
    "path": "apps/api/src/audit/publishers/audit-direct-publisher.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, Inject, OnModuleInit } from '@nestjs/common'\nimport { AuditLog } from '../entities/audit-log.entity'\nimport { AuditLogPublisher } from '../interfaces/audit-publisher.interface'\nimport { AuditLogStorageAdapter } from '../interfaces/audit-storage.interface'\nimport { AUDIT_STORAGE_ADAPTER } from '../constants/audit-tokens'\n\n@Injectable()\nexport class AuditDirectPublisher implements AuditLogPublisher, OnModuleInit {\n  private readonly logger = new Logger(AuditDirectPublisher.name)\n\n  constructor(@Inject(AUDIT_STORAGE_ADAPTER) private readonly storageAdapter: AuditLogStorageAdapter) {}\n\n  async onModuleInit(): Promise<void> {\n    this.logger.log('Direct storage publisher initialized')\n  }\n\n  async write(auditLogs: AuditLog[]): Promise<void> {\n    await this.storageAdapter.write(auditLogs)\n    this.logger.debug(\n      `Written ${auditLogs.length} audit logs directly to ${this.storageAdapter.constructor.name} publisher`,\n    )\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/publishers/kafka/audit-kafka-consumer.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Inject, Logger, UseFilters } from '@nestjs/common'\nimport { Ctx, EventPattern, KafkaContext, Payload } from '@nestjs/microservices'\nimport { AuditLog } from '../../entities/audit-log.entity'\nimport { AuditLogStorageAdapter } from '../../interfaces/audit-storage.interface'\nimport { AutoCommitOffset } from '../../../common/decorators/autocommit-offset.decorator'\nimport { AUDIT_KAFKA_TOPIC, AUDIT_STORAGE_ADAPTER } from '../../constants/audit-tokens'\nimport { KafkaMaxRetryExceptionFilter } from '../../../filters/kafka-exception.filter'\n\n@Controller('kafka-audit')\n@UseFilters(new KafkaMaxRetryExceptionFilter({ retries: 3, sendToDlq: true }))\nexport class AuditKafkaConsumerController {\n  private readonly logger = new Logger(AuditKafkaConsumerController.name)\n\n  constructor(@Inject(AUDIT_STORAGE_ADAPTER) private readonly auditStorageAdapter: AuditLogStorageAdapter) {}\n\n  @EventPattern(AUDIT_KAFKA_TOPIC)\n  @AutoCommitOffset()\n  public async handleAuditLogMessage(@Payload() message: AuditLog, @Ctx() context: KafkaContext): Promise<void> {\n    this.logger.debug('Handling audit log message', { message })\n    await this.auditStorageAdapter.write([message])\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/publishers/kafka/audit-kafka-publisher.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Logger, OnModuleInit } from '@nestjs/common'\nimport { ClientKafkaProxy } from '@nestjs/microservices'\nimport { CompressionTypes, Message } from 'kafkajs'\nimport { AuditLog } from '../../entities/audit-log.entity'\nimport { AuditLogPublisher } from '../../interfaces/audit-publisher.interface'\nimport { AUDIT_KAFKA_TOPIC } from '../../constants/audit-tokens'\n\nexport class AuditKafkaPublisher implements AuditLogPublisher, OnModuleInit {\n  private readonly logger = new Logger(AuditKafkaPublisher.name)\n\n  constructor(private readonly kafkaService: ClientKafkaProxy) {}\n\n  async onModuleInit() {\n    await this.kafkaService.connect()\n    this.logger.debug('Kafka audit log publisher initialized')\n  }\n\n  async write(auditLogs: AuditLog[]): Promise<void> {\n    const messages: Message[] = auditLogs.map((auditLog) => ({\n      key: auditLog.organizationId,\n      value: JSON.stringify(auditLog),\n    }))\n\n    try {\n      await this.kafkaService.producer.send({\n        topic: AUDIT_KAFKA_TOPIC,\n        messages: messages,\n        acks: -1,\n        compression: CompressionTypes.GZIP,\n      })\n    } catch (error) {\n      this.logger.error('Failed to write audit log to Kafka:', error)\n      throw error\n    }\n    this.logger.debug(`${auditLogs.length} audit logs written to Kafka`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/services/audit.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Inject, Injectable, Logger, NotFoundException, OnApplicationBootstrap, Optional } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Cron, CronExpression, SchedulerRegistry } from '@nestjs/schedule'\nimport { LessThan, Repository, IsNull, Not } from 'typeorm'\nimport { CreateAuditLogInternalDto } from '../dto/create-audit-log-internal.dto'\nimport { UpdateAuditLogInternalDto } from '../dto/update-audit-log-internal.dto'\nimport { AuditLog } from '../entities/audit-log.entity'\nimport { PaginatedList } from '../../common/interfaces/paginated-list.interface'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { RedisLockProvider } from '../../sandbox/common/redis-lock.provider'\nimport { AUDIT_LOG_PUBLISHER, AUDIT_STORAGE_ADAPTER } from '../constants/audit-tokens'\nimport { AuditLogStorageAdapter } from '../interfaces/audit-storage.interface'\nimport { AuditLogPublisher } from '../interfaces/audit-publisher.interface'\nimport { AuditLogFilter } from '../interfaces/audit-filter.interface'\nimport { DistributedLock } from '../../common/decorators/distributed-lock.decorator'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\n\n@Injectable()\nexport class AuditService implements OnApplicationBootstrap {\n  private readonly logger = new Logger(AuditService.name)\n\n  constructor(\n    @InjectRepository(AuditLog)\n    private readonly auditLogRepository: Repository<AuditLog>,\n    private readonly configService: TypedConfigService,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly schedulerRegistry: SchedulerRegistry,\n    @Inject(AUDIT_STORAGE_ADAPTER)\n    private readonly auditStorageAdapter: AuditLogStorageAdapter,\n    @Optional()\n    @Inject(AUDIT_LOG_PUBLISHER)\n    private readonly auditLogPublisher?: AuditLogPublisher,\n  ) {}\n\n  onApplicationBootstrap() {\n    const auditConfig = this.configService.get('audit')\n\n    // Enable publish cron job if publish is enabled\n    if (auditConfig.publish.enabled) {\n      this.schedulerRegistry.getCronJob('publish-audit-logs').start()\n      return\n    }\n\n    // Enable cleanup cron job if retention days is configured and publish is disabled\n    if (auditConfig.retentionDays && auditConfig.retentionDays > 0) {\n      this.schedulerRegistry.getCronJob('cleanup-old-audit-logs').start()\n    }\n\n    const batchSize = this.configService.getOrThrow('audit.publish.batchSize')\n\n    if (batchSize > 50000) {\n      throw new Error('Audit publish batch size cannot be greater than 50000')\n    }\n  }\n\n  async createLog(createDto: CreateAuditLogInternalDto): Promise<AuditLog> {\n    const auditLog = new AuditLog(createDto)\n\n    await this.auditLogRepository.insert(auditLog)\n    return auditLog\n  }\n\n  async updateLog(id: string, updateDto: UpdateAuditLogInternalDto): Promise<AuditLog> {\n    const auditLog = await this.auditLogRepository.findOne({ where: { id } })\n    if (!auditLog) {\n      throw new NotFoundException(`Audit log with ID ${id} not found`)\n    }\n\n    if (updateDto.statusCode) {\n      auditLog.statusCode = updateDto.statusCode\n    }\n\n    if (updateDto.errorMessage) {\n      auditLog.errorMessage = updateDto.errorMessage\n    }\n\n    if (updateDto.targetId) {\n      auditLog.targetId = updateDto.targetId\n    }\n\n    if (updateDto.organizationId) {\n      auditLog.organizationId = updateDto.organizationId\n    }\n\n    if (this.configService.get('audit.consoleLogEnabled')) {\n      this.logger.log(`AUDIT_ENTRY: ${JSON.stringify(auditLog)}`)\n    }\n\n    return this.auditLogRepository.save(auditLog)\n  }\n\n  async getAllLogs(\n    page = 1,\n    limit = 10,\n    filters?: AuditLogFilter,\n    nextToken?: string,\n  ): Promise<PaginatedList<AuditLog>> {\n    return this.auditStorageAdapter.getAllLogs(page, limit, filters, nextToken)\n  }\n\n  async getOrganizationLogs(\n    organizationId: string,\n    page = 1,\n    limit = 10,\n    filters?: AuditLogFilter,\n    nextToken?: string,\n  ): Promise<PaginatedList<AuditLog>> {\n    return this.auditStorageAdapter.getOrganizationLogs(organizationId, page, limit, filters, nextToken)\n  }\n\n  @Cron(CronExpression.EVERY_DAY_AT_2AM, {\n    name: 'cleanup-old-audit-logs',\n    waitForCompletion: true,\n    disabled: true,\n  })\n  @DistributedLock()\n  @LogExecution('cleanup-old-audit-logs')\n  async cleanupOldAuditLogs(): Promise<void> {\n    try {\n      const retentionDays = this.configService.get('audit.retentionDays')\n      if (!retentionDays) {\n        return\n      }\n\n      const cutoffDate = new Date(Date.now() - retentionDays * 24 * 60 * 60 * 1000)\n      this.logger.log(`Starting cleanup of audit logs older than ${retentionDays} days`)\n\n      const deletedLogs = await this.auditLogRepository.delete({\n        createdAt: LessThan(cutoffDate),\n      })\n\n      const totalDeleted = deletedLogs.affected\n\n      this.logger.log(`Completed cleanup of audit logs older than ${retentionDays} days (${totalDeleted} logs deleted)`)\n    } catch (error) {\n      this.logger.error(`An error occurred during cleanup of old audit logs: ${error.message}`, error.stack)\n    }\n  }\n\n  // Resolve dangling audit logs where status code is not set and created at is more than half an hour ago\n  @Cron(CronExpression.EVERY_MINUTE, {\n    name: 'resolve-dangling-audit-logs',\n    waitForCompletion: true,\n  })\n  @DistributedLock()\n  @WithInstrumentation()\n  @LogExecution('resolve-dangling-audit-logs')\n  async resolveDanglingLogs() {\n    const danglingLogs = await this.auditLogRepository.find({\n      where: {\n        statusCode: IsNull(),\n        createdAt: LessThan(new Date(Date.now() - 30 * 60 * 1000)),\n      },\n    })\n\n    for (const log of danglingLogs) {\n      // set status code to unknown\n      log.statusCode = 0\n      await this.auditLogRepository.save(log)\n      if (this.configService.get('audit.consoleLogEnabled')) {\n        this.logger.log(`AUDIT_ENTRY: ${JSON.stringify(log)}`)\n      }\n    }\n    this.logger.debug(`Resolved ${danglingLogs.length} dangling audit logs`)\n  }\n\n  @Cron(CronExpression.EVERY_SECOND, {\n    name: 'publish-audit-logs',\n    waitForCompletion: true,\n    disabled: true,\n  })\n  @LogExecution('publish-audit-logs')\n  @DistributedLock()\n  @WithInstrumentation()\n  async publishAuditLogs() {\n    // Safeguard\n    if (!this.auditLogPublisher) {\n      this.logger.warn('Audit log publisher not configured, skipping publish')\n      return\n    }\n\n    const auditLogs = await this.auditLogRepository.find({\n      where: {\n        statusCode: Not(IsNull()),\n      },\n      take: this.configService.getOrThrow('audit.publish.batchSize'),\n      order: {\n        createdAt: 'ASC',\n      },\n    })\n\n    if (auditLogs.length === 0) {\n      return\n    }\n\n    await this.auditLogPublisher.write(auditLogs)\n    await this.auditLogRepository.delete(auditLogs.map((log) => log.id))\n  }\n}\n"
  },
  {
    "path": "apps/api/src/audit/subscribers/audit-log.subscriber.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ForbiddenException, Inject, Logger } from '@nestjs/common'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { DataSource, EntitySubscriberInterface, EventSubscriber, UpdateEvent } from 'typeorm'\nimport { AuditLog } from '../entities/audit-log.entity'\n\n@EventSubscriber()\nexport class AuditLogSubscriber implements EntitySubscriberInterface<AuditLog> {\n  private readonly logger = new Logger(AuditLogSubscriber.name)\n\n  @Inject(EventEmitter2)\n  private eventEmitter: EventEmitter2\n\n  constructor(dataSource: DataSource) {\n    dataSource.subscribers.push(this)\n  }\n\n  listenTo() {\n    return AuditLog\n  }\n\n  beforeUpdate(event: UpdateEvent<AuditLog>) {\n    const existingEntity = event.databaseEntity as AuditLog\n\n    if (!existingEntity) {\n      // This should not happen, throw exception as a fail-safe\n      this.logger.warn('Could not find existing audit log entity, beforeUpdate event:', event)\n      throw new ForbiddenException()\n    }\n\n    if (existingEntity.statusCode) {\n      throw new ForbiddenException('Finalized audit logs are immutable.')\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/auth/api-key.strategy.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, UnauthorizedException, Logger, OnModuleInit } from '@nestjs/common'\nimport { PassportStrategy } from '@nestjs/passport'\nimport { Strategy } from 'passport-http-bearer'\nimport { ApiKeyService } from '../api-key/api-key.service'\nimport { ApiKey } from '../api-key/api-key.entity'\nimport { UserService } from '../user/user.service'\nimport { AuthContextType } from '../common/interfaces/auth-context.interface'\nimport { TypedConfigService } from '../config/typed-config.service'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\nimport { SystemRole } from '../user/enums/system-role.enum'\nimport { RunnerService } from '../sandbox/services/runner.service'\nimport { generateApiKeyHash } from '../common/utils/api-key'\nimport { RegionService } from '../region/services/region.service'\nimport { JWT_REGEX } from './constants/jwt-regex.constant'\n\ntype UserCache = {\n  userId: string\n  role: SystemRole\n  email: string\n}\n\n@Injectable()\nexport class ApiKeyStrategy extends PassportStrategy(Strategy, 'api-key') implements OnModuleInit {\n  private readonly logger = new Logger(ApiKeyStrategy.name)\n\n  constructor(\n    @InjectRedis() private readonly redis: Redis,\n    private readonly apiKeyService: ApiKeyService,\n    private readonly userService: UserService,\n    private readonly configService: TypedConfigService,\n    private readonly runnerService: RunnerService,\n    private readonly regionService: RegionService,\n  ) {\n    super()\n    this.logger.log('ApiKeyStrategy constructor called')\n  }\n\n  onModuleInit() {\n    this.logger.log('ApiKeyStrategy initialized')\n  }\n\n  async validate(token: string): Promise<AuthContextType | null> {\n    this.logger.debug('Validate method called')\n    this.logger.debug(`Validating API key: ${token.substring(0, 8)}...`)\n\n    const sshGatewayApiKey = this.configService.getOrThrow('sshGateway.apiKey')\n    if (sshGatewayApiKey === token) {\n      return {\n        role: 'ssh-gateway',\n      }\n    }\n\n    const proxyApiKey = this.configService.getOrThrow('proxy.apiKey')\n    if (proxyApiKey === token) {\n      return {\n        role: 'proxy',\n      }\n    }\n\n    const otelCollectorApiKey = this.configService.get('otelCollector.apiKey')\n    if (otelCollectorApiKey && otelCollectorApiKey === token) {\n      return {\n        role: 'otel-collector',\n      }\n    }\n\n    const healthCheckApiKey = this.configService.get('healthCheck.apiKey')\n    if (healthCheckApiKey && healthCheckApiKey === token) {\n      return {\n        role: 'health-check',\n      }\n    }\n\n    // Tokens matching JWT structure are not API keys — skip DB lookups and delegate to the JWT strategy.\n    if (JWT_REGEX.test(token)) {\n      return null\n    }\n\n    try {\n      let apiKey = await this.getApiKeyCache(token)\n      if (!apiKey) {\n        // Cache miss - validate from database\n        apiKey = await this.apiKeyService.getApiKeyByValue(token)\n        this.logger.debug(`API key found for userId: ${apiKey.userId}`)\n\n        // Check expiry BEFORE caching to prevent storing expired keys\n        if (apiKey.expiresAt && apiKey.expiresAt < new Date()) {\n          throw new UnauthorizedException('This API key has expired')\n        }\n\n        const validationCacheTtl = this.configService.get('apiKey.validationCacheTtlSeconds')\n        const cacheKey = this.generateValidationCacheKey(token)\n        await this.redis.setex(cacheKey, validationCacheTtl, JSON.stringify(apiKey))\n      }\n      if (apiKey.expiresAt && apiKey.expiresAt < new Date()) {\n        throw new UnauthorizedException('This API key has expired')\n      }\n\n      this.logger.debug(`Updating last used timestamp for API key: ${token.substring(0, 8)}...`)\n      await this.apiKeyService.updateLastUsedAt(apiKey.organizationId, apiKey.userId, apiKey.name, new Date())\n\n      let userCache = await this.getUserCache(apiKey.userId)\n      if (!userCache) {\n        const user = await this.userService.findOne(apiKey.userId)\n        if (!user) {\n          this.logger.error(`Api key has invalid user: ${apiKey.keySuffix} - ${apiKey.userId}`)\n          throw new UnauthorizedException('User not found')\n        }\n        userCache = {\n          userId: user.id,\n          role: user.role,\n          email: user.email,\n        }\n        const userCacheTtl = this.configService.get('apiKey.userCacheTtlSeconds')\n        await this.redis.setex(this.generateUserCacheKey(apiKey.userId), userCacheTtl, JSON.stringify(userCache))\n      }\n\n      const result = {\n        userId: userCache.userId,\n        role: userCache.role,\n        email: userCache.email,\n        apiKey,\n        organizationId: apiKey.organizationId,\n      }\n\n      this.logger.debug('Authentication successful', result)\n      return result\n    } catch (error) {\n      this.logger.debug('Error checking user API key:', error)\n      // Continue to check runner API keys if user check fails\n    }\n\n    try {\n      const runner = await this.runnerService.findByApiKey(token)\n      if (runner) {\n        this.logger.debug(`Runner API key found for runner: ${runner.id}`)\n        return {\n          role: 'runner',\n          runnerId: runner.id,\n          runner,\n        }\n      }\n    } catch (error) {\n      this.logger.debug('Error checking runner API key:', error)\n    }\n\n    try {\n      const region = await this.regionService.findOneByProxyApiKey(token)\n      if (region) {\n        this.logger.debug(`Region proxy API key found for region: ${region.id}`)\n        return {\n          role: 'region-proxy',\n          regionId: region.id,\n        }\n      }\n    } catch (error) {\n      this.logger.debug('Error checking region proxy API key:', error)\n    }\n\n    try {\n      const region = await this.regionService.findOneBySshGatewayApiKey(token)\n      if (region) {\n        this.logger.debug(`Region SSH gateway API key found for region: ${region.id}`)\n        return {\n          role: 'region-ssh-gateway',\n          regionId: region.id,\n        }\n      }\n    } catch (error) {\n      this.logger.debug('Error checking region SSH gateway API key:', error)\n    }\n\n    return null\n  }\n\n  private async getUserCache(userId: string): Promise<UserCache | null> {\n    try {\n      const userCacheRaw = await this.redis.get(`api-key:user:${userId}`)\n      if (userCacheRaw) {\n        return JSON.parse(userCacheRaw)\n      }\n      return null\n    } catch (error) {\n      this.logger.error('Error getting user cache:', error)\n      return null\n    }\n  }\n\n  private async getApiKeyCache(token: string): Promise<ApiKey | null> {\n    try {\n      const cacheKey = this.generateValidationCacheKey(token)\n      const cached = await this.redis.get(cacheKey)\n      if (cached) {\n        this.logger.debug('Using cached API key validation')\n        const apiKey = JSON.parse(cached)\n        // Parse Date fields from cached data\n        if (apiKey.createdAt) {\n          apiKey.createdAt = new Date(apiKey.createdAt)\n        }\n        if (apiKey.lastUsedAt) {\n          apiKey.lastUsedAt = new Date(apiKey.lastUsedAt)\n        }\n        if (apiKey.expiresAt) {\n          apiKey.expiresAt = new Date(apiKey.expiresAt)\n        }\n        return apiKey\n      }\n      return null\n    } catch (error) {\n      this.logger.error('Error getting API key cache:', error)\n      return null\n    }\n  }\n\n  private generateValidationCacheKey(token: string): string {\n    return `api-key:validation:${generateApiKeyHash(token)}`\n  }\n\n  private generateUserCacheKey(userId: string): string {\n    return `api-key:user:${userId}`\n  }\n}\n"
  },
  {
    "path": "apps/api/src/auth/auth.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { PassportModule } from '@nestjs/passport'\nimport { JwtStrategy } from './jwt.strategy'\nimport { ApiKeyStrategy } from './api-key.strategy'\nimport { UserModule } from '../user/user.module'\nimport { ApiKeyModule } from '../api-key/api-key.module'\nimport { SandboxModule } from '../sandbox/sandbox.module'\nimport { TypedConfigService } from '../config/typed-config.service'\nimport { HttpModule, HttpService } from '@nestjs/axios'\nimport { OidcMetadata } from 'oidc-client-ts'\nimport { firstValueFrom } from 'rxjs'\nimport { UserService } from '../user/user.service'\nimport { TypedConfigModule } from '../config/typed-config.module'\nimport { catchError, map } from 'rxjs/operators'\nimport { FailedAuthTrackerService } from './failed-auth-tracker.service'\nimport { RegionModule } from '../region/region.module'\n@Module({\n  imports: [\n    PassportModule.register({\n      defaultStrategy: ['jwt', 'api-key'],\n      property: 'user',\n      session: false,\n    }),\n    TypedConfigModule,\n    UserModule,\n    ApiKeyModule,\n    SandboxModule,\n    RegionModule,\n    HttpModule,\n  ],\n  providers: [\n    ApiKeyStrategy,\n    {\n      provide: JwtStrategy,\n      useFactory: async (userService: UserService, httpService: HttpService, configService: TypedConfigService) => {\n        if (configService.get('skipConnections')) {\n          return\n        }\n\n        // Get the OpenID configuration from the issuer\n        const discoveryUrl = `${configService.get('oidc.issuer')}/.well-known/openid-configuration`\n        const metadata = await firstValueFrom(\n          httpService.get(discoveryUrl).pipe(\n            map((response) => response.data as OidcMetadata),\n            catchError((error) => {\n              throw new Error(`Failed to fetch OpenID configuration: ${error.message}`)\n            }),\n          ),\n        )\n\n        let jwksUri = metadata.jwks_uri\n\n        const internalIssuer = configService.getOrThrow('oidc.issuer')\n        const publicIssuer = configService.get('oidc.publicIssuer')\n        if (publicIssuer) {\n          // Replace localhost URLs with Docker network URLs for internal API use\n          jwksUri = metadata.jwks_uri.replace(publicIssuer, internalIssuer)\n        }\n        return new JwtStrategy(\n          {\n            audience: configService.get('oidc.audience'),\n            issuer: metadata.issuer,\n            jwksUri: jwksUri,\n          },\n          userService,\n          configService,\n        )\n      },\n      inject: [UserService, HttpService, TypedConfigService],\n    },\n    FailedAuthTrackerService,\n  ],\n  exports: [PassportModule, JwtStrategy, ApiKeyStrategy, FailedAuthTrackerService],\n})\nexport class AuthModule {}\n"
  },
  {
    "path": "apps/api/src/auth/combined-auth.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, UnauthorizedException } from '@nestjs/common'\nimport { AuthGuard } from '@nestjs/passport'\n\n/**\n * Main authentication guard for the application.\n *\n * Strategies are tried in array order.\n * On first success, the rest are skipped.\n *\n * `handleRequest` is invoked once — either when a strategy succeeds or when all strategies fail.\n * It returns the authenticated user object or throws a generic `UnauthorizedException`.\n */\n@Injectable()\nexport class CombinedAuthGuard extends AuthGuard(['api-key', 'jwt']) {\n  private readonly logger = new Logger(CombinedAuthGuard.name)\n\n  handleRequest(err: any, user: any) {\n    if (err || !user) {\n      this.logger.debug('Authentication failed', { err, user })\n      throw new UnauthorizedException('Invalid credentials')\n    }\n\n    return user\n  }\n}\n"
  },
  {
    "path": "apps/api/src/auth/constants/jwt-regex.constant.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Matches the structure of a JWT token: three base64url-encoded segments\n * separated by dots (header.payload.signature).\n *\n * Both header and payload must start with `eyJ` — the base64url encoding of `{\"`,\n * which is guaranteed since both are JSON objects.\n *\n * The signature segment has no prefix constraint since it is raw bytes.\n */\nexport const JWT_REGEX = /^eyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/\n"
  },
  {
    "path": "apps/api/src/auth/failed-auth-tracker.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Inject, Logger } from '@nestjs/common'\nimport { getRedisConnectionToken } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { Request, Response } from 'express'\nimport { ThrottlerException } from '@nestjs/throttler'\nimport { TypedConfigService } from '../config/typed-config.service'\nimport { setRateLimitHeaders } from '../common/utils/rate-limit-headers.util'\n\n/**\n * Service to track failed authentication attempts across all auth guards.\n * Shared logic for both JWT and API key authentication failures.\n */\n@Injectable()\nexport class FailedAuthTrackerService {\n  private readonly logger = new Logger(FailedAuthTrackerService.name)\n\n  constructor(\n    @Inject(getRedisConnectionToken('throttler')) private readonly redis: Redis,\n    private readonly configService: TypedConfigService,\n  ) {}\n\n  async incrementFailedAuth(request: Request, response: Response): Promise<void> {\n    try {\n      const ip = request.ips.length ? request.ips[0] : request.ip\n      const throttlerName = 'failed-auth'\n      const tracker = `${throttlerName}:${ip}`\n\n      // Get failed-auth config from TypedConfigService\n      const failedAuthConfig = this.configService.get('rateLimit.failedAuth')\n      if (!failedAuthConfig || !failedAuthConfig.ttl || !failedAuthConfig.limit) {\n        // If failed-auth throttler is not configured, skip tracking\n        return\n      }\n\n      const limit = failedAuthConfig.limit\n      const ttl = failedAuthConfig.ttl * 1000 // Convert seconds to milliseconds\n\n      const keyPrefix = this.redis.options.keyPrefix || ''\n      const key = `${throttlerName}-${tracker}`\n      const hitKey = `${keyPrefix}{${key}:${throttlerName}}:hits`\n      const blockedKey = `${keyPrefix}{${key}:${throttlerName}}:blocked`\n\n      // Increment hits\n      const hits = await this.redis.incr(hitKey)\n      if (hits === 1) {\n        await this.redis.pexpire(hitKey, ttl)\n      }\n      const ttlRemaining = await this.redis.pttl(hitKey)\n\n      // Set rate limit headers\n      setRateLimitHeaders(response, {\n        throttlerName,\n        limit,\n        remaining: Math.max(0, limit - hits),\n        resetSeconds: Math.ceil(ttlRemaining / 1000),\n      })\n\n      // Check if blocked\n      if (hits >= limit) {\n        await this.redis.set(blockedKey, '1', 'PX', ttl)\n        setRateLimitHeaders(response, {\n          throttlerName,\n          limit,\n          remaining: 0,\n          resetSeconds: Math.ceil(ttl / 1000),\n          retryAfterSeconds: Math.ceil(ttl / 1000),\n        })\n        throw new ThrottlerException()\n      }\n    } catch (error) {\n      if (error instanceof ThrottlerException) {\n        throw error\n      }\n      // Log error but don't block auth if rate limiting has issues\n      this.logger.error('Failed to track authentication failure:', error)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/auth/get-auth-context.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ExecutionContext, UnauthorizedException } from '@nestjs/common'\nimport { BaseAuthContext } from '../common/interfaces/auth-context.interface'\n\nexport function getAuthContext<T extends BaseAuthContext>(\n  context: ExecutionContext,\n  isFunction: (user: BaseAuthContext) => user is T,\n): T {\n  const request = context.switchToHttp().getRequest()\n\n  if (request.user && isFunction(request.user)) {\n    return request.user\n  }\n\n  throw new UnauthorizedException('Unauthorized')\n}\n"
  },
  {
    "path": "apps/api/src/auth/health-check.guard.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext, Logger, CanActivate } from '@nestjs/common'\nimport { getAuthContext } from './get-auth-context'\nimport { isHealthCheckContext } from '../common/interfaces/health-check-context.interface'\n\n@Injectable()\nexport class HealthCheckGuard implements CanActivate {\n  protected readonly logger = new Logger(HealthCheckGuard.name)\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    // Throws if not health check context\n    getAuthContext(context, isHealthCheckContext)\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/auth/jwt.strategy.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { PassportStrategy } from '@nestjs/passport'\nimport { ExtractJwt, Strategy } from 'passport-jwt'\nimport { passportJwtSecret } from 'jwks-rsa'\nimport { createRemoteJWKSet, JWTPayload, jwtVerify } from 'jose'\nimport { UserService } from '../user/user.service'\nimport { AuthContext } from '../common/interfaces/auth-context.interface'\nimport { Request } from 'express'\nimport { CustomHeaders } from '../common/constants/header.constants'\nimport { TypedConfigService } from '../config/typed-config.service'\n\ninterface JwtStrategyConfig {\n  jwksUri: string\n  audience: string\n  issuer: string\n}\n\n@Injectable()\nexport class JwtStrategy extends PassportStrategy(Strategy) {\n  private readonly logger = new Logger(JwtStrategy.name)\n  private JWKS: ReturnType<typeof createRemoteJWKSet>\n\n  constructor(\n    private readonly options: JwtStrategyConfig,\n    private readonly userService: UserService,\n    private readonly configService: TypedConfigService,\n  ) {\n    super({\n      secretOrKeyProvider: passportJwtSecret({\n        cache: true,\n        rateLimit: true,\n        jwksRequestsPerMinute: 5,\n        jwksUri: options.jwksUri,\n      }),\n      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),\n      audience: options.audience,\n      issuer: options.issuer,\n      algorithms: ['RS256'],\n      passReqToCallback: true,\n    })\n    this.JWKS = createRemoteJWKSet(new URL(options.jwksUri))\n    this.logger.debug('JwtStrategy initialized')\n  }\n\n  async validate(request: Request, payload: any): Promise<AuthContext> {\n    // OKTA does not return the userId in access_token sub claim\n    // real userId is in the uid claim and email is in the sub claim\n    let userId = payload.sub\n    let email = payload.email\n    if (payload.cid && payload.uid) {\n      userId = payload.uid\n      email = payload.sub\n    }\n    let user = await this.userService.findOne(userId)\n\n    if (user && !user.emailVerified && payload.email_verified) {\n      await this.userService.update(user.id, {\n        emailVerified: payload.email_verified,\n      })\n    }\n\n    if (!user) {\n      user = await this.userService.create({\n        id: userId,\n        name: payload.name || payload.username || 'Unknown',\n        email: email || '',\n        emailVerified: payload.email_verified || false,\n        personalOrganizationQuota: this.configService.getOrThrow('defaultOrganizationQuota'),\n      })\n      this.logger.debug(`Created new user with ID: ${userId}`)\n    } else if (user.name === 'Unknown' || !user.email) {\n      await this.userService.update(user.id, {\n        name: payload.name || payload.username || 'Unknown',\n        email: email || '',\n      })\n      this.logger.debug(`Updated name and email address for existing user with ID: ${userId}`)\n    } else if (user.email !== email) {\n      await this.userService.update(user.id, {\n        email: email || '',\n      })\n      this.logger.debug(`Updated email address for existing user with ID: ${userId}`)\n    }\n\n    const organizationId = request.get(CustomHeaders.ORGANIZATION_ID.name)\n\n    return {\n      userId: user.id,\n      role: user.role,\n      email: user.email,\n      organizationId,\n    }\n  }\n\n  async verifyToken(token: string): Promise<JWTPayload> {\n    const { payload } = await jwtVerify(token, this.JWKS, {\n      audience: this.options.audience,\n      issuer: this.options.issuer,\n      algorithms: ['RS256'],\n    })\n    return payload\n  }\n}\n"
  },
  {
    "path": "apps/api/src/auth/or.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext, Logger, CanActivate, Type, mixin } from '@nestjs/common'\nimport { ModuleRef } from '@nestjs/core'\n\n/**\n * Creates an OrGuard that allows access if at least one of the provided guards allows access.\n * It tries each guard in sequence and returns true on the first successful guard.\n * If all guards fail, it returns false.\n *\n * Usage:\n * ```typescript\n * @UseGuards(OrGuard([GuardA, GuardB]))\n * ```\n */\nexport function OrGuard(guards: Type<CanActivate>[]): Type<CanActivate> {\n  @Injectable()\n  class OrGuardMixin implements CanActivate {\n    protected readonly logger = new Logger(`OrGuard`)\n\n    constructor(private readonly moduleRef: ModuleRef) {}\n\n    async canActivate(context: ExecutionContext): Promise<boolean> {\n      for (const GuardClass of guards) {\n        try {\n          const guard = this.moduleRef.get(GuardClass, { strict: false })\n          const result = await guard.canActivate(context)\n\n          if (result) {\n            this.logger.debug(`Guard ${GuardClass.name} succeeded`)\n            return true\n          }\n        } catch (error) {\n          this.logger.debug(`Guard ${GuardClass.name} failed: ${error.message}`)\n        }\n      }\n\n      this.logger.debug('All guards in OrGuard failed')\n      return false\n    }\n  }\n\n  return mixin(OrGuardMixin)\n}\n"
  },
  {
    "path": "apps/api/src/auth/otel-collector.guard.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext, Logger, CanActivate } from '@nestjs/common'\nimport { getAuthContext } from './get-auth-context'\nimport { isOtelCollectorContext } from '../common/interfaces/otel-collector-context.interface'\n\n@Injectable()\nexport class OtelCollectorGuard implements CanActivate {\n  protected readonly logger = new Logger(OtelCollectorGuard.name)\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    // Throws if not otel collector context\n    getAuthContext(context, isOtelCollectorContext)\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/auth/runner-auth.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, CanActivate, ExecutionContext, Logger } from '@nestjs/common'\nimport { isRunnerContext } from '../common/interfaces/runner-context.interface'\nimport { getAuthContext } from './get-auth-context'\n\n@Injectable()\nexport class RunnerAuthGuard implements CanActivate {\n  private readonly logger = new Logger(RunnerAuthGuard.name)\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    // Throws if not runner context\n    getAuthContext(context, isRunnerContext)\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/auth/system-action.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext, Logger, CanActivate } from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { RequiredSystemRole, RequiredApiRole } from '../common/decorators/required-role.decorator'\nimport { SystemRole } from '../user/enums/system-role.enum'\nimport { ApiRole, AuthContext } from '../common/interfaces/auth-context.interface'\n\n@Injectable()\nexport class SystemActionGuard implements CanActivate {\n  protected readonly logger = new Logger(SystemActionGuard.name)\n\n  constructor(private readonly reflector: Reflector) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    // TODO: initialize authContext safely\n    const authContext: AuthContext = request.user\n\n    let requiredRole: SystemRole | SystemRole[] | ApiRole | ApiRole[] =\n      this.reflector.get(RequiredSystemRole, context.getHandler()) ||\n      this.reflector.get(RequiredSystemRole, context.getClass())\n\n    if (!requiredRole) {\n      requiredRole =\n        this.reflector.get(RequiredApiRole, context.getHandler()) ||\n        this.reflector.get(RequiredApiRole, context.getClass())\n      if (!requiredRole) {\n        return true\n      }\n    }\n\n    if (!Array.isArray(requiredRole)) {\n      requiredRole = [requiredRole]\n    }\n\n    return (requiredRole as string[]).includes(authContext.role as string)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/clickhouse/clickhouse.module.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module, Global } from '@nestjs/common'\nimport { ClickHouseService } from './clickhouse.service'\n\n@Global()\n@Module({\n  providers: [ClickHouseService],\n  exports: [ClickHouseService],\n})\nexport class ClickHouseModule {}\n"
  },
  {
    "path": "apps/api/src/clickhouse/clickhouse.service.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, OnModuleDestroy } from '@nestjs/common'\nimport { createClient, ClickHouseClient } from '@clickhouse/client'\nimport { TypedConfigService } from '../config/typed-config.service'\n\n@Injectable()\nexport class ClickHouseService implements OnModuleDestroy {\n  private readonly logger = new Logger(ClickHouseService.name)\n  private client: ClickHouseClient | null = null\n\n  constructor(private readonly configService: TypedConfigService) {}\n\n  private getClient(): ClickHouseClient | null {\n    if (this.client) {\n      return this.client\n    }\n\n    const config = this.configService.getClickHouseConfig()\n    if (!config) {\n      return null\n    }\n\n    this.client = createClient({\n      url: config.url,\n      username: config.username,\n      password: config.password,\n      database: config.database,\n    })\n\n    return this.client\n  }\n\n  async onModuleDestroy() {\n    if (this.client) {\n      await this.client.close()\n    }\n  }\n\n  isConfigured(): boolean {\n    return this.configService.getClickHouseConfig() !== null\n  }\n\n  async query<T>(query: string, params?: Record<string, unknown>): Promise<T[]> {\n    const client = this.getClient()\n    if (!client) {\n      this.logger.warn('ClickHouse is not configured')\n      return []\n    }\n\n    try {\n      const result = await client.query({\n        query,\n        query_params: params,\n        format: 'JSONEachRow',\n        clickhouse_settings: {\n          date_time_input_format: 'best_effort',\n        },\n      })\n\n      return (await result.json()) as T[]\n    } catch (error) {\n      this.logger.error('ClickHouse query failed:', error)\n      throw error\n    }\n  }\n\n  async queryOne<T>(query: string, params?: Record<string, unknown>): Promise<T | null> {\n    const results = await this.query<T>(query, params)\n    return results.length > 0 ? results[0] : null\n  }\n}\n"
  },
  {
    "path": "apps/api/src/clickhouse/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport * from './clickhouse.module'\nexport * from './clickhouse.service'\n"
  },
  {
    "path": "apps/api/src/common/constants/constants.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const SANDBOX_EVENT_CHANNEL = 'sandbox.event.channel'\n"
  },
  {
    "path": "apps/api/src/common/constants/error-messages.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const UPGRADE_TIER_MESSAGE = (dashboardUrl: string) =>\n  `To increase concurrency limits, upgrade your organization's Tier by visiting ${dashboardUrl}/limits.`\n\nexport const ARCHIVE_SANDBOXES_MESSAGE = 'Consider archiving your unused Sandboxes to free up available storage.'\n\nexport const PER_SANDBOX_LIMIT_MESSAGE =\n  'Need higher resource limits per-sandbox? Contact us at support@daytona.io and let us know about your use case.'\n"
  },
  {
    "path": "apps/api/src/common/constants/feature-flags.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const FeatureFlags = {\n  ORGANIZATION_INFRASTRUCTURE: 'organization_infrastructure',\n  SANDBOX_RESIZE: 'sandbox_resize',\n} as const\n"
  },
  {
    "path": "apps/api/src/common/constants/header.constants.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const CustomHeaders: {\n  [key: string]: {\n    name: string\n    description?: string\n    required?: boolean\n    schema?: {\n      type?: string\n    }\n  }\n} = {\n  ORGANIZATION_ID: {\n    name: 'X-Daytona-Organization-ID',\n    description: 'Use with JWT to specify the organization ID',\n    required: false,\n    schema: {\n      type: 'string',\n    },\n  },\n  SOURCE: {\n    name: 'X-Daytona-Source',\n    description: 'Use to specify the source of the request',\n    required: false,\n    schema: {\n      type: 'string',\n    },\n  },\n  SDK_VERSION: {\n    name: 'X-Daytona-SDK-Version',\n    description: 'Use to specify the version of the SDK',\n    required: false,\n    schema: {\n      type: 'string',\n    },\n  },\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/auth-context.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { createParamDecorator, ExecutionContext } from '@nestjs/common'\n\nexport const AuthContext = createParamDecorator((data: unknown, ctx: ExecutionContext) => {\n  const request = ctx.switchToHttp().getRequest()\n  return request.user\n})\n"
  },
  {
    "path": "apps/api/src/common/decorators/autocommit-offset.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { KafkaContext } from '@nestjs/microservices'\n\n/**\n * Auto commit offset decorator for Kafka messages. The offset is committed only if the method completes successfully.\n * @returns A decorator function that commits the offset of the Kafka message.\n */\nexport function AutoCommitOffset(): MethodDecorator {\n  return function (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor {\n    const originalMethod = descriptor.value\n\n    descriptor.value = async function (...args: any[]) {\n      const result = await originalMethod.apply(this, args)\n\n      // Find KafkaContext in arguments\n      const context = args.find((arg) => arg instanceof KafkaContext)\n\n      if (context) {\n        const message = context.getMessage()\n        const partition = context.getPartition()\n        const topic = context.getTopic()\n        const consumer = context.getConsumer()\n\n        await consumer.commitOffsets([\n          {\n            topic,\n            partition,\n            offset: String(Number(message.offset) + 1),\n          },\n        ])\n      }\n\n      return result\n    }\n\n    return descriptor\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/distributed-lock.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { RedisLockProvider } from '../../sandbox/common/redis-lock.provider'\n\ntype DistributedLockOptions = {\n  lockKey?: string\n  lockTtl?: number\n}\n\n/**\n * Redis lock decorator for exclusive execution. The lock is released automatically when the method completes.\n * redisLockProvider is required to be injected in the class.\n * @param options - The options for the Redis lock\n * @param options.lockKey - The key to use for the Redis lock\n * @param options.lockTtl - Time to live for the lock in seconds\n * @returns A decorator function that handles Redis locking\n */\nexport function DistributedLock(options?: DistributedLockOptions): MethodDecorator {\n  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n    const originalMethod = descriptor.value\n\n    descriptor.value = async function (...args: any[]) {\n      if (!this.redisLockProvider) {\n        throw new Error(`@DistributedLock requires 'redisLockProvider' property on ${target.constructor.name}`)\n      }\n\n      const redisLockProvider: RedisLockProvider = this.redisLockProvider\n\n      // Generate lock key\n      const lockKey = `lock:${options?.lockKey ?? target.constructor.name}.${propertyKey}`\n\n      // Set default TTL if not provided\n      const lockTtlMs = options?.lockTtl || 30 // 30 seconds default\n\n      const hasLock = await redisLockProvider.lock(lockKey, lockTtlMs)\n      if (!hasLock) {\n        return\n      }\n      try {\n        return await originalMethod.apply(this, args)\n      } finally {\n        await redisLockProvider.unlock(lockKey)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/log-execution.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Logger } from '@nestjs/common'\n\n// Parse threshold once at module load time\nlet LOG_THRESHOLD = parseInt(process.env.LOG_EXECUTION_THRESHOLD_MILLISECONDS, 10)\nif (isNaN(LOG_THRESHOLD) || LOG_THRESHOLD <= 0) {\n  LOG_THRESHOLD = 1000 // Default to 1000ms if not set or invalid\n}\n\nexport function LogExecution(name?: string) {\n  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n    const shouldLogExecutions = process.env.LOG_EXECUTIONS === 'true'\n    if (!shouldLogExecutions) {\n      return descriptor\n    }\n\n    // Wrap the original method with logging\n    const originalMethod = descriptor.value\n    const logger = new Logger(`Function:${target.constructor.name}`)\n\n    descriptor.value = async function (...args: any[]) {\n      const startTime = Date.now()\n      const functionName = name || propertyKey\n\n      try {\n        const result = await originalMethod.apply(this, args)\n        const duration = Date.now() - startTime\n\n        if (duration > LOG_THRESHOLD) {\n          logger.warn(`Function ${functionName} took a long time: ${duration}ms`)\n        }\n\n        return result\n      } catch (error) {\n        const duration = Date.now() - startTime\n        logger.error(`Failed function: ${functionName} (took ${duration}ms)`, error.stack)\n        throw error\n      }\n    }\n\n    return descriptor\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/on-async-event.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OnEvent, OnEventMetadata } from '@nestjs/event-emitter'\n\nexport function OnAsyncEvent({ event, options = {} }: OnEventMetadata): MethodDecorator {\n  return OnEvent(event, {\n    ...options,\n    promisify: true,\n    suppressErrors: false,\n  })\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/otel.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { trace, context, metrics, SpanStatusCode, Histogram } from '@opentelemetry/api'\nimport { applyDecorators } from '@nestjs/common'\n\n// Lazy initialization to ensure SDK is started before getting tracer/meter\nconst getTracer = () => trace.getTracer('')\nconst getMeter = () => metrics.getMeter('')\n\nconst executionHistograms = new Map<string, Histogram>()\n\n/**\n * Configuration options for span instrumentation\n */\nexport interface SpanConfig {\n  /**\n   * Custom name for the span. If not provided, uses `ClassName.methodName` format\n   */\n  name?: string\n  /**\n   * Additional attributes to attach to the span\n   */\n  attributes?: Record<string, string>\n}\n\n/**\n * Configuration options for metric instrumentation\n */\nexport interface MetricConfig {\n  /**\n   * Custom name for the metric. If not provided, uses `ClassName.methodName` format\n   */\n  name?: string\n  /**\n   * Description for the metrics being collected\n   */\n  description?: string\n  /**\n   * Additional labels to attach to the metrics\n   */\n  labels?: Record<string, string>\n}\n\n/**\n * Configuration options for the combined instrumentation decorator\n */\nexport interface InstrumentationConfig {\n  /**\n   * Custom name for the span and metric. If not provided, uses `ClassName.methodName` format\n   */\n  name?: string\n  /**\n   * Description for the metrics being collected\n   */\n  description?: string\n  /**\n   * Additional labels/attributes to attach to spans and metrics\n   */\n  labels?: Record<string, string>\n  /**\n   * Enable trace collection (default: true)\n   */\n  enableTraces?: boolean\n  /**\n   * Enable metrics collection (default: true)\n   */\n  enableMetrics?: boolean\n}\n\n/**\n * Converts a string to snake_case for Prometheus-friendly metric names\n */\nfunction toSnakeCase(str: string): string {\n  return str\n    .replace(/([A-Z])/g, '_$1')\n    .toLowerCase()\n    .replace(/^_/, '')\n    .replace(/\\./g, '_')\n}\n\n/**\n * Decorator for instrumenting methods with OpenTelemetry spans (traces only)\n *\n * @param config - Configuration object or string name for the span\n *\n */\nexport function WithSpan(config?: string | SpanConfig) {\n  return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n    const originalMethod = descriptor.value\n    const methodName = String(propertyKey)\n\n    descriptor.value = async function (...args: any[]) {\n      const cfg: SpanConfig = typeof config === 'string' ? { name: config } : config || {}\n      const { name, attributes = {} } = cfg\n\n      const spanName = name || `${target.constructor.name}.${methodName}`\n\n      const allAttributes = {\n        component: target.constructor.name,\n        method: methodName,\n        ...attributes,\n      }\n\n      const span = getTracer().startSpan(\n        spanName,\n        {\n          attributes: allAttributes,\n        },\n        context.active(),\n      )\n\n      return context.with(trace.setSpan(context.active(), span), async () => {\n        try {\n          const result = await originalMethod.apply(this, args)\n          span.setStatus({ code: SpanStatusCode.OK })\n          return result\n        } catch (error) {\n          span.setStatus({\n            code: SpanStatusCode.ERROR,\n            message: error instanceof Error ? error.message : String(error),\n          })\n          span.recordException(error instanceof Error ? error : new Error(String(error)))\n          throw error\n        } finally {\n          span.end()\n        }\n      })\n    }\n  }\n}\n\n/**\n * Decorator for instrumenting methods with OpenTelemetry metrics (metrics only)\n *\n * Collects two metrics:\n * - Counter: `{name}_executions` - tracks number of executions with status (success/error)\n * - Histogram: `{name}_duration` - tracks execution duration in milliseconds\n *\n * @param config - Configuration object or string name for the metric\n *\n */\nexport function WithMetric(config?: string | MetricConfig) {\n  return (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {\n    const originalMethod = descriptor.value\n    const methodName = String(propertyKey)\n\n    descriptor.value = async function (...args: any[]) {\n      const cfg: MetricConfig = typeof config === 'string' ? { name: config } : config || {}\n      const { name, description, labels = {} } = cfg\n\n      const metricName = toSnakeCase(name || `${target.constructor.name}.${methodName}`)\n      const allLabels = {\n        component: target.constructor.name,\n        method: methodName,\n        ...labels,\n      }\n\n      // Get or create histogram for this method\n      if (!executionHistograms.has(metricName)) {\n        executionHistograms.set(\n          metricName,\n          getMeter().createHistogram(`${metricName}_duration`, {\n            description: description || `Duration of executions for ${metricName}`,\n            unit: 'ms',\n          }),\n        )\n      }\n      const histogram = executionHistograms.get(metricName)\n      if (!histogram) {\n        throw new Error(`Histogram not found for metric: ${metricName}`)\n      }\n\n      const startTime = Date.now()\n\n      let status: 'success' | 'error' = 'success'\n      try {\n        const result = await originalMethod.apply(this, args)\n        return result\n      } catch (error) {\n        status = 'error'\n        throw error\n      } finally {\n        const duration = Date.now() - startTime\n        histogram.record(duration, { ...allLabels, status })\n      }\n    }\n  }\n}\n\n/**\n * Decorator for instrumenting methods with both OpenTelemetry traces and metrics\n *\n * This decorator composes @WithSpan and @WithMetric to provide both trace and metric collection.\n * You can selectively enable/disable traces or metrics using the config options.\n *\n * @param config - Configuration object or string name for the instrumentation\n */\nexport function WithInstrumentation(config?: string | InstrumentationConfig): MethodDecorator {\n  const cfg: InstrumentationConfig = typeof config === 'string' ? { name: config } : config || {}\n  const { enableTraces = true, enableMetrics = true, name, description, labels } = cfg\n\n  const decorators: MethodDecorator[] = []\n\n  if (enableTraces) {\n    decorators.push(WithSpan({ name, attributes: labels }))\n  }\n\n  if (enableMetrics) {\n    decorators.push(WithMetric({ name, description, labels }))\n  }\n\n  return applyDecorators(...decorators)\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/page-limit.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { applyDecorators } from '@nestjs/common'\nimport { ApiProperty } from '@nestjs/swagger'\nimport { IsOptional, IsInt, Min, Max } from 'class-validator'\nimport { Type } from 'class-transformer'\n\nexport function PageLimit(defaultValue = 100) {\n  return applyDecorators(\n    ApiProperty({\n      name: 'limit',\n      description: 'Number of results per page',\n      required: false,\n      type: Number,\n      minimum: 1,\n      maximum: 200,\n      default: defaultValue,\n    }),\n    IsOptional(),\n    Type(() => Number),\n    IsInt(),\n    Min(1),\n    Max(200),\n  )\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/page-number.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { applyDecorators } from '@nestjs/common'\nimport { ApiProperty } from '@nestjs/swagger'\nimport { IsOptional, IsInt, Min } from 'class-validator'\nimport { Type } from 'class-transformer'\n\nexport function PageNumber(defaultValue = 1) {\n  return applyDecorators(\n    ApiProperty({\n      name: 'page',\n      description: 'Page number of the results',\n      required: false,\n      type: Number,\n      minimum: 1,\n      default: defaultValue,\n    }),\n    IsOptional(),\n    Type(() => Number),\n    IsInt(),\n    Min(1),\n  )\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/required-role.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Reflector } from '@nestjs/core'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { ApiRole } from '../interfaces/auth-context.interface'\n\nexport const RequiredSystemRole = Reflector.createDecorator<SystemRole | SystemRole[]>()\nexport const RequiredApiRole = Reflector.createDecorator<ApiRole | ApiRole[]>()\n"
  },
  {
    "path": "apps/api/src/common/decorators/runner-context.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { createParamDecorator, ExecutionContext } from '@nestjs/common'\nimport { RunnerContext } from '../interfaces/runner-context.interface'\n\nexport const RunnerContextDecorator = createParamDecorator((data: unknown, ctx: ExecutionContext): RunnerContext => {\n  const request = ctx.switchToHttp().getRequest()\n  return request.user as RunnerContext\n})\n"
  },
  {
    "path": "apps/api/src/common/decorators/throttler-scope.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SetMetadata } from '@nestjs/common'\n\nexport const THROTTLER_SCOPE_KEY = 'throttler:scope'\n\n/**\n * Marks a route or controller with specific throttler scopes.\n * Only the specified throttlers will be applied to this route.\n * The 'authenticated' throttler always applies to authenticated routes.\n *\n * @example\n * // Apply sandbox-create throttler\n * @ThrottlerScope('sandbox-create')\n * @Post()\n * createSandbox() {}\n *\n * @example\n * // Apply multiple throttlers\n * @ThrottlerScope('sandbox-create', 'sandbox-lifecycle')\n * @Post()\n * createAndStart() {}\n */\nexport const ThrottlerScope = (...scopes: string[]) => SetMetadata(THROTTLER_SCOPE_KEY, scopes)\n"
  },
  {
    "path": "apps/api/src/common/decorators/to-array.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Transform } from 'class-transformer'\n\n/**\n * Decorator that transforms a value to an array. Useful for query parameters that can be a single value or an array of values.\n *\n * If the value is a primitive, it will return a single element array. If the value is already an array, it will return it as is.\n */\nexport function ToArray() {\n  return Transform(({ value }) => {\n    return value ? (Array.isArray(value) ? value : [value]) : undefined\n  })\n}\n"
  },
  {
    "path": "apps/api/src/common/decorators/track-job-execution.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Track job execution in activeJobs set.\n * @returns A decorator function that tracks execution of a job.\n */\nexport function TrackJobExecution() {\n  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n    const original = descriptor.value\n\n    descriptor.value = async function (...args: any[]) {\n      if (!this.activeJobs) {\n        throw new Error(`@TrackExecution requires 'activeJobs' property on ${target.constructor.name}`)\n      }\n\n      this.activeJobs.add(propertyKey)\n      try {\n        return await original.apply(this, args)\n      } finally {\n        this.activeJobs.delete(propertyKey)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/dto/url.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsString } from 'class-validator'\n\n@ApiSchema({ name: 'Url' })\nexport class UrlDto {\n  @ApiProperty({\n    description: 'URL response',\n  })\n  @IsString()\n  url: string\n\n  constructor(url: string) {\n    this.url = url\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/guards/anonymous-rate-limit.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext } from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { ThrottlerGuard, ThrottlerModuleOptions, ThrottlerRequest, ThrottlerStorage } from '@nestjs/throttler'\nimport { Request } from 'express'\n\n@Injectable()\nexport class AnonymousRateLimitGuard extends ThrottlerGuard {\n  constructor(options: ThrottlerModuleOptions, storageService: ThrottlerStorage, reflector: Reflector) {\n    super(options, storageService, reflector)\n  }\n\n  protected async getTracker(req: Request): Promise<string> {\n    // For anonymous requests, use IP address as tracker\n    const ip = req.ips.length ? req.ips[0] : req.ip\n    return `anonymous:${ip}`\n  }\n\n  protected generateKey(context: ExecutionContext, suffix: string, name: string): string {\n    // Override to make rate limiting per-rate-limit-type, not per-route\n    // This ensures all routes share the same counter for anonymous rate limiting\n    return `${name}-${suffix}`\n  }\n\n  async handleRequest(requestProps: ThrottlerRequest): Promise<boolean> {\n    const { throttler } = requestProps\n\n    // Apply anonymous throttler to ALL requests (with or without Bearer tokens)\n    // This ensures we catch invalid/malicious tokens before they reach authentication\n    if (throttler.name === 'anonymous') {\n      return super.handleRequest(requestProps)\n    }\n\n    // Skip other throttlers in this guard\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/guards/authenticated-rate-limit.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, Inject, ExecutionContext, Optional } from '@nestjs/common'\nimport { ThrottlerGuard, ThrottlerRequest, ThrottlerModuleOptions, ThrottlerStorage } from '@nestjs/throttler'\nimport { Reflector } from '@nestjs/core'\nimport { Request } from 'express'\nimport { getRedisConnectionToken } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { OrganizationService } from '../../organization/services/organization.service'\nimport { THROTTLER_SCOPE_KEY } from '../decorators/throttler-scope.decorator'\n\n@Injectable()\nexport class AuthenticatedRateLimitGuard extends ThrottlerGuard {\n  private readonly logger = new Logger(AuthenticatedRateLimitGuard.name)\n\n  constructor(\n    options: ThrottlerModuleOptions,\n    storageService: ThrottlerStorage,\n    reflector: Reflector,\n    @Inject(getRedisConnectionToken('throttler')) private readonly redis: Redis,\n    @Optional() private readonly organizationService?: OrganizationService,\n  ) {\n    super(options, storageService, reflector)\n  }\n\n  protected async getTracker(req: Request): Promise<string> {\n    const user = req.user as any\n\n    // Track by organization ID when available (shared quota per org)\n    if (user?.organizationId) {\n      return `auth:org:${user.organizationId}`\n    }\n\n    // Fallback to user ID for non-org routes (e.g., /users/me)\n    if (user?.userId) {\n      return `auth:user:${user.userId}`\n    }\n\n    // Ultimate fallback (shouldn't happen in normal flow)\n    const ip = req.ips.length ? req.ips[0] : req.ip\n    return `fallback:${ip}`\n  }\n\n  protected generateKey(context: ExecutionContext, suffix: string, name: string): string {\n    // Override to make rate limiting per-rate-limit-type, not per-route\n    // This ensures all routes share the same counter per rate limit type (authenticated, sandbox-create, sandbox-lifecycle)\n    return `${name}-${suffix}`\n  }\n\n  async handleRequest(requestProps: ThrottlerRequest): Promise<boolean> {\n    const { context, throttler } = requestProps\n    const request = context.switchToHttp().getRequest<Request>()\n    const isAuthenticated = request.user && this.isValidAuthContext(request.user)\n\n    // Skip rate limiting for M2M system roles (checked AFTER auth runs)\n    if (this.isSystemRole(request.user)) {\n      return true\n    }\n\n    // Skip anonymous throttler (handled by AnonymousRateLimitGuard on public routes)\n    if (throttler.name === 'anonymous') {\n      return true\n    }\n\n    // Skip failed-auth throttler (handled by FailedAuthRateLimitMiddleware and auth guards)\n    if (throttler.name === 'failed-auth') {\n      return true\n    }\n\n    // Check authenticated throttlers\n    const authenticatedThrottlers = ['authenticated', 'sandbox-create', 'sandbox-lifecycle']\n    if (authenticatedThrottlers.includes(throttler.name)) {\n      if (isAuthenticated) {\n        // Only 'authenticated' applies to all routes by default\n        // 'sandbox-create' and 'sandbox-lifecycle' only apply if explicitly configured via @SkipThrottle or @Throttle\n        const isDefaultThrottler = throttler.name === 'authenticated'\n\n        if (!isDefaultThrottler) {\n          // Sandbox throttlers (sandbox-create, sandbox-lifecycle) are opt-in only\n          // Check if this route declares this throttler scope via @ThrottlerScope() decorator\n          const scopes = this.reflector.getAllAndOverride<string[]>(THROTTLER_SCOPE_KEY, [\n            context.getHandler(),\n            context.getClass(),\n          ])\n\n          // If the route hasn't declared this throttler in its scope, skip it\n          if (!scopes || !scopes.includes(throttler.name)) {\n            return true\n          }\n        }\n\n        const user = request.user as any\n        const orgId = user?.organizationId\n        if (orgId) {\n          const orgLimits = await this.getCachedOrganizationRateLimits(orgId)\n          if (orgLimits) {\n            const customLimit =\n              throttler.name === 'authenticated'\n                ? orgLimits.authenticated\n                : throttler.name === 'sandbox-create'\n                  ? orgLimits.sandboxCreate\n                  : throttler.name === 'sandbox-lifecycle'\n                    ? orgLimits.sandboxLifecycle\n                    : undefined\n\n            const customTtlSeconds =\n              throttler.name === 'authenticated'\n                ? orgLimits.authenticatedTtlSeconds\n                : throttler.name === 'sandbox-create'\n                  ? orgLimits.sandboxCreateTtlSeconds\n                  : throttler.name === 'sandbox-lifecycle'\n                    ? orgLimits.sandboxLifecycleTtlSeconds\n                    : undefined\n\n            if (customLimit != null || customTtlSeconds != null) {\n              const modifiedProps = {\n                ...requestProps,\n                ...(customLimit != null && { limit: customLimit }),\n                ...(customTtlSeconds != null && {\n                  ttl: customTtlSeconds * 1000,\n                  blockDuration: customTtlSeconds * 1000,\n                }),\n              }\n              return super.handleRequest(modifiedProps)\n            }\n          }\n        }\n        return super.handleRequest(requestProps)\n      }\n      return true\n    }\n\n    // For any other throttlers, defer to base ThrottlerGuard\n    if (isAuthenticated) {\n      return super.handleRequest(requestProps)\n    }\n    return true\n  }\n\n  private isValidAuthContext(user: any): boolean {\n    return user && (user.userId || user.role)\n  }\n\n  private isSystemRole(user: any): boolean {\n    // Skip rate limiting for M2M system roles (proxy, runner, ssh-gateway)\n    return user?.role === 'ssh-gateway' || user?.role === 'proxy' || user?.role === 'runner'\n  }\n\n  private async getCachedOrganizationRateLimits(organizationId: string): Promise<{\n    authenticated: number | null\n    sandboxCreate: number | null\n    sandboxLifecycle: number | null\n    authenticatedTtlSeconds: number | null\n    sandboxCreateTtlSeconds: number | null\n    sandboxLifecycleTtlSeconds: number | null\n  } | null> {\n    // If OrganizationService is not available (e.g., in UserModule), use default rate limits\n    if (!this.organizationService) {\n      return null\n    }\n\n    try {\n      const cacheKey = `organization:rate-limits:${organizationId}`\n      const cachedLimits = await this.redis.get(cacheKey)\n\n      if (cachedLimits) {\n        return JSON.parse(cachedLimits)\n      }\n\n      const organization = await this.organizationService.findOne(organizationId)\n      if (organization) {\n        const limits = {\n          authenticated: organization.authenticatedRateLimit,\n          sandboxCreate: organization.sandboxCreateRateLimit,\n          sandboxLifecycle: organization.sandboxLifecycleRateLimit,\n          authenticatedTtlSeconds: organization.authenticatedRateLimitTtlSeconds,\n          sandboxCreateTtlSeconds: organization.sandboxCreateRateLimitTtlSeconds,\n          sandboxLifecycleTtlSeconds: organization.sandboxLifecycleRateLimitTtlSeconds,\n        }\n        await this.redis.set(cacheKey, JSON.stringify(limits), 'EX', 60)\n        return limits\n      }\n\n      return null\n    } catch (error) {\n      this.logger.error('Error getting cached organization rate limits:', error)\n      return null\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/interceptors/content-type.interceptors.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common'\nimport { Observable } from 'rxjs'\n\n@Injectable()\nexport class ContentTypeInterceptor implements NestInterceptor {\n  private readonly logger = new Logger(ContentTypeInterceptor.name)\n\n  async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {\n    const request = context.switchToHttp().getRequest()\n\n    // Check if we have raw body data but no parsed body\n    if (request.readable) {\n      // Create a promise to handle the body parsing\n      await new Promise<void>((resolve, reject) => {\n        let rawBody = ''\n\n        // Collect the raw body data\n        request.on('data', (chunk: Buffer) => {\n          rawBody += chunk.toString()\n        })\n\n        // Once we have all the data, try to parse it as JSON\n        request.on('end', () => {\n          try {\n            if (rawBody) {\n              request.body = JSON.parse(rawBody)\n              request.headers['content-type'] = 'application/json'\n            }\n            resolve()\n          } catch (e) {\n            this.logger.error('Failed to parse JSON body:', e)\n            resolve() // Still resolve even on error to prevent hanging\n          }\n        })\n\n        // Handle potential errors\n        request.on('error', (error) => {\n          this.logger.error('Error reading request body:', error)\n          reject(error)\n        })\n      })\n    }\n\n    // Add Content-Type header if it's missing and there's a request body\n    if (request.body && Object.keys(request.body).length > 0 && !request.get('content-type')) {\n      request.headers['content-type'] = 'application/json'\n    }\n\n    return next.handle()\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/auth-context.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiKey } from '../../api-key/api-key.entity'\nimport { OrganizationUser } from '../../organization/entities/organization-user.entity'\nimport { Organization } from '../../organization/entities/organization.entity'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { ProxyContext } from './proxy-context.interface'\nimport { RunnerContext } from './runner-context.interface'\nimport { SshGatewayContext } from './ssh-gateway-context.interface'\nimport { RegionProxyContext } from './region-proxy.interface'\nimport { RegionSSHGatewayContext } from './region-ssh-gateway.interface'\nimport { OtelCollectorContext } from './otel-collector-context.interface'\nimport { HealthCheckContext } from './health-check-context.interface'\n\nexport interface BaseAuthContext {\n  role: ApiRole\n}\n\nexport type ApiRole =\n  | SystemRole\n  | 'proxy'\n  | 'runner'\n  | 'ssh-gateway'\n  | 'region-proxy'\n  | 'region-ssh-gateway'\n  | 'otel-collector'\n  | 'health-check'\n\nexport interface AuthContext extends BaseAuthContext {\n  userId: string\n  email: string\n  apiKey?: ApiKey\n  organizationId?: string\n  runnerId?: string\n}\n\nexport function isAuthContext(user: BaseAuthContext): user is AuthContext {\n  return 'userId' in user\n}\n\nexport interface OrganizationAuthContext extends AuthContext {\n  organizationId: string\n  organization: Organization\n  organizationUser?: OrganizationUser\n}\n\nexport function isOrganizationAuthContext(user: BaseAuthContext): user is OrganizationAuthContext {\n  return 'organizationId' in user\n}\n\nexport type AuthContextType =\n  | AuthContext\n  | OrganizationAuthContext\n  | ProxyContext\n  | RunnerContext\n  | SshGatewayContext\n  | RegionProxyContext\n  | RegionSSHGatewayContext\n  | OtelCollectorContext\n  | HealthCheckContext\n"
  },
  {
    "path": "apps/api/src/common/interfaces/health-check-context.interface.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BaseAuthContext } from './auth-context.interface'\n\nexport interface HealthCheckContext extends BaseAuthContext {\n  role: 'health-check'\n}\n\nexport function isHealthCheckContext(user: BaseAuthContext): user is HealthCheckContext {\n  return 'role' in user && user.role === 'health-check'\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/otel-collector-context.interface.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BaseAuthContext } from './auth-context.interface'\n\nexport interface OtelCollectorContext extends BaseAuthContext {\n  role: 'otel-collector'\n}\n\nexport function isOtelCollectorContext(user: BaseAuthContext): user is OtelCollectorContext {\n  return 'role' in user && user.role === 'otel-collector'\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/otel-config.interface.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface OTELConfig {\n  enabled: boolean\n  endpoint: string\n  headers: Record<string, string>\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/paginated-list.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface PaginatedList<T> {\n  items: T[]\n  total: number\n  page: number\n  totalPages: number\n  nextToken?: string\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/proxy-context.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BaseAuthContext } from './auth-context.interface'\n\nexport interface ProxyContext extends BaseAuthContext {\n  role: 'proxy'\n}\n\nexport function isProxyContext(user: BaseAuthContext): user is ProxyContext {\n  return 'role' in user && user.role === 'proxy'\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/region-proxy.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BaseAuthContext } from './auth-context.interface'\n\nexport interface RegionProxyContext extends BaseAuthContext {\n  role: 'region-proxy'\n  regionId: string\n}\n\nexport function isRegionProxyContext(user: BaseAuthContext): user is RegionProxyContext {\n  return 'role' in user && user.role === 'region-proxy'\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/region-ssh-gateway.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BaseAuthContext } from './auth-context.interface'\n\nexport interface RegionSSHGatewayContext extends BaseAuthContext {\n  role: 'region-ssh-gateway'\n  regionId: string\n}\n\nexport function isRegionSSHGatewayContext(user: BaseAuthContext): user is RegionSSHGatewayContext {\n  return 'role' in user && user.role === 'region-ssh-gateway'\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/runner-context.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BaseAuthContext } from './auth-context.interface'\nimport { Runner } from '../../sandbox/entities/runner.entity'\n\nexport interface RunnerContext extends BaseAuthContext {\n  role: 'runner'\n  runnerId: string\n  runner: Runner\n}\n\nexport function isRunnerContext(user: BaseAuthContext): user is RunnerContext {\n  return 'role' in user && user.role === 'runner'\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/ssh-gateway-context.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BaseAuthContext } from './auth-context.interface'\n\nexport interface SshGatewayContext extends BaseAuthContext {\n  role: 'ssh-gateway'\n}\n\nexport function isSshGatewayContext(user: BaseAuthContext): user is SshGatewayContext {\n  return 'role' in user && user.role === 'ssh-gateway'\n}\n"
  },
  {
    "path": "apps/api/src/common/interfaces/trackable-job-executions.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface TrackableJobExecutions {\n  activeJobs: Set<string>\n}\n"
  },
  {
    "path": "apps/api/src/common/middleware/failed-auth-rate-limit.middleware.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, NestMiddleware, Inject, Logger } from '@nestjs/common'\nimport { Request, Response, NextFunction } from 'express'\nimport { ThrottlerException } from '@nestjs/throttler'\nimport { getRedisConnectionToken } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { setRateLimitHeaders } from '../utils/rate-limit-headers.util'\n\n/**\n * Middleware that checks if an IP is blocked due to too many failed auth attempts.\n * Runs BEFORE auth guards to block requests early and prevent wasting resources on auth.\n *\n * Flow:\n * 1. Request comes in\n * 2. This middleware checks Redis if IP has exceeded failed auth limit (isBlocked)\n * 3. If blocked: return 429 with rate limit headers immediately\n * 4. If not blocked: continue to auth guards\n */\n@Injectable()\nexport class FailedAuthRateLimitMiddleware implements NestMiddleware {\n  private readonly logger = new Logger(FailedAuthRateLimitMiddleware.name)\n\n  constructor(\n    @Inject(getRedisConnectionToken('throttler')) private readonly redis: Redis,\n    private readonly configService: TypedConfigService,\n  ) {}\n\n  async use(req: Request, res: Response, next: NextFunction) {\n    const ip = req.ips.length ? req.ips[0] : req.ip\n    const throttlerName = 'failed-auth'\n    const tracker = `${throttlerName}:${ip}`\n\n    // Get failed-auth config from TypedConfigService\n    const failedAuthConfig = this.configService.get('rateLimit.failedAuth')\n\n    if (!failedAuthConfig || !failedAuthConfig.ttl || !failedAuthConfig.limit) {\n      // If failed-auth throttler is not configured, skip\n      return next()\n    }\n\n    try {\n      // Build the Redis key (same format as ThrottlerStorageRedisService)\n      const keyPrefix = this.redis.options.keyPrefix || ''\n      const key = `${throttlerName}-${tracker}`\n      const blockedKey = `${keyPrefix}{${key}:${throttlerName}}:blocked`\n\n      // Check if IP is blocked\n      const isBlocked = await this.redis.get(blockedKey)\n\n      if (isBlocked) {\n        // Get TTL for the blocked key\n        const ttl = await this.redis.pttl(blockedKey)\n        const ttlSeconds = Math.ceil(ttl / 1000)\n\n        // Set rate limit headers to inform client\n        setRateLimitHeaders(res, {\n          throttlerName,\n          limit: failedAuthConfig.limit,\n          remaining: 0,\n          resetSeconds: ttlSeconds,\n          retryAfterSeconds: ttlSeconds,\n        })\n\n        throw new ThrottlerException()\n      }\n\n      // Not blocked, continue to auth guards\n      next()\n    } catch (error) {\n      if (error instanceof ThrottlerException) {\n        throw error\n      }\n      // If there's an error checking the rate limit, log it and allow the request to continue\n      // We don't want rate limiting failures to block legitimate requests\n      this.logger.error('Failed to check failed-auth rate limit:', error)\n      next()\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/middleware/maintenance.middleware.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, NestMiddleware, HttpException, HttpStatus } from '@nestjs/common'\nimport { Request, Response, NextFunction } from 'express'\nimport { TypedConfigService } from '../../config/typed-config.service'\n\n@Injectable()\nexport class MaintenanceMiddleware implements NestMiddleware {\n  constructor(private readonly configService: TypedConfigService) {}\n\n  use(req: Request, res: Response, next: NextFunction) {\n    const isMaintenanceMode = this.configService.get('maintananceMode')\n\n    if (isMaintenanceMode) {\n      throw new HttpException(\n        {\n          statusCode: HttpStatus.SERVICE_UNAVAILABLE,\n          message: 'Service is currently under maintenance. Please try again later.',\n          error: 'Service Unavailable',\n        },\n        HttpStatus.SERVICE_UNAVAILABLE,\n      )\n    }\n\n    next()\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/middleware/version-header.middleware.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, NestMiddleware } from '@nestjs/common'\nimport { Request, Response, NextFunction } from 'express'\nimport { TypedConfigService } from '../../config/typed-config.service'\n\n@Injectable()\nexport class VersionHeaderMiddleware implements NestMiddleware {\n  private readonly version: string | undefined\n\n  constructor(private readonly configService: TypedConfigService) {\n    this.version = this.configService.get('version')\n  }\n\n  use(req: Request, res: Response, next: NextFunction) {\n    if (this.version) {\n      res.setHeader('X-Daytona-Api-Version', `${this.version}`)\n    }\n    next()\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/modules/body-parser-error.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module, OnModuleInit, BadRequestException } from '@nestjs/common'\nimport { HttpAdapterHost } from '@nestjs/core'\nimport { Request, Response, NextFunction } from 'express'\n@Module({})\nexport class BodyParserErrorModule implements OnModuleInit {\n  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}\n\n  onModuleInit() {\n    const app = this.httpAdapterHost.httpAdapter.getInstance()\n\n    app.use((err: Error & { body?: unknown }, req: Request, res: Response, next: NextFunction) => {\n      if (err instanceof SyntaxError && 'body' in err) {\n        const response = new BadRequestException('Invalid JSON in request body').getResponse()\n        return res.status(400).json(response)\n      }\n\n      next(err)\n    })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/providers/openfeature-posthog.provider.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { EvaluationContext, Provider, ResolutionDetails, Hook, JsonValue, Logger } from '@openfeature/server-sdk'\nimport { TypeMismatchError, StandardResolutionReasons, ErrorCode } from '@openfeature/server-sdk'\nimport { PostHog } from 'posthog-node'\nimport type { PostHogOptions } from 'posthog-node'\n\nexport interface OpenFeaturePostHogProviderConfig {\n  /** PostHog project API key (starts with phc_) - if not provided, all flags return default values */\n  apiKey?: string\n  /** Optional PostHog client options */\n  clientOptions?: PostHogOptions\n  /** Whether to evaluate flags locally (default: false) */\n  evaluateLocally?: boolean\n}\n\nexport class OpenFeaturePostHogProvider implements Provider {\n  readonly metadata = {\n    name: 'simple-posthog-provider',\n  } as const\n\n  private readonly client?: PostHog\n  private readonly evaluateLocally: boolean\n  private readonly isConfigured: boolean\n\n  constructor(config: OpenFeaturePostHogProviderConfig = {}) {\n    this.evaluateLocally = config.evaluateLocally ?? false\n    this.isConfigured = !!config.apiKey\n\n    if (config.apiKey) {\n      try {\n        this.client = new PostHog(config.apiKey, config.clientOptions)\n      } catch (error) {\n        console.warn('Failed to initialize PostHog client:', error)\n      }\n    }\n  }\n\n  async resolveBooleanEvaluation(\n    flagKey: string,\n    defaultValue: boolean,\n    context: EvaluationContext,\n    logger: Logger,\n  ): Promise<ResolutionDetails<boolean>> {\n    logger.debug(`Evaluating flag ${flagKey} with context and default value:`, context, defaultValue)\n    const result = await this.evaluateFlag(flagKey, defaultValue, context, logger)\n\n    if (typeof result.value === 'boolean') {\n      return result as ResolutionDetails<boolean>\n    }\n\n    throw new TypeMismatchError(`Flag ${flagKey} expected boolean, got ${typeof result.value}`)\n  }\n\n  async resolveStringEvaluation(\n    flagKey: string,\n    defaultValue: string,\n    context: EvaluationContext,\n    logger: Logger,\n  ): Promise<ResolutionDetails<string>> {\n    const result = await this.evaluateFlag(flagKey, defaultValue, context, logger)\n\n    if (typeof result.value === 'string') {\n      return result as ResolutionDetails<string>\n    }\n\n    throw new TypeMismatchError(`Flag ${flagKey} expected string, got ${typeof result.value}`)\n  }\n\n  async resolveNumberEvaluation(\n    flagKey: string,\n    defaultValue: number,\n    context: EvaluationContext,\n    logger: Logger,\n  ): Promise<ResolutionDetails<number>> {\n    const result = await this.evaluateFlag(flagKey, defaultValue, context, logger)\n\n    if (typeof result.value === 'number') {\n      return result as ResolutionDetails<number>\n    }\n\n    throw new TypeMismatchError(`Flag ${flagKey} expected number, got ${typeof result.value}`)\n  }\n\n  async resolveObjectEvaluation<T extends JsonValue>(\n    flagKey: string,\n    defaultValue: T,\n    context: EvaluationContext,\n    logger: Logger,\n  ): Promise<ResolutionDetails<T>> {\n    // If PostHog is not configured, return default value\n    if (!this.isConfigured || !this.client) {\n      logger.debug(`PostHog not configured, returning default value for flag ${flagKey}`)\n      return {\n        value: defaultValue,\n        reason: StandardResolutionReasons.DEFAULT,\n      }\n    }\n\n    const targetingKey = this.getTargetingKey(context)\n\n    if (!targetingKey) {\n      return {\n        value: defaultValue,\n        reason: StandardResolutionReasons.ERROR,\n        errorCode: ErrorCode.GENERAL,\n      }\n    }\n\n    try {\n      const flagContext = this.buildFlagContext(context)\n      const payload = await this.client.getFeatureFlagPayload(flagKey, targetingKey, undefined, {\n        onlyEvaluateLocally: this.evaluateLocally,\n        sendFeatureFlagEvents: true,\n        ...flagContext,\n      })\n\n      if (payload === undefined) {\n        return {\n          value: defaultValue,\n          reason: StandardResolutionReasons.DEFAULT,\n          errorCode: ErrorCode.FLAG_NOT_FOUND,\n        }\n      }\n\n      return {\n        value: payload as T,\n        reason: StandardResolutionReasons.TARGETING_MATCH,\n      }\n    } catch (error) {\n      logger.error(`Error evaluating flag ${flagKey}:`, error)\n      return {\n        value: defaultValue,\n        reason: StandardResolutionReasons.ERROR,\n        errorCode: ErrorCode.GENERAL,\n      }\n    }\n  }\n\n  private async evaluateFlag(\n    flagKey: string,\n    defaultValue: any,\n    context: EvaluationContext,\n    logger: Logger,\n  ): Promise<ResolutionDetails<any>> {\n    // If PostHog is not configured, return default value\n    if (!this.isConfigured || !this.client) {\n      logger.debug(`PostHog not configured, returning default value for flag ${flagKey}`)\n      return {\n        value: defaultValue,\n        reason: StandardResolutionReasons.DEFAULT,\n      }\n    }\n\n    const targetingKey = this.getTargetingKey(context)\n\n    if (!targetingKey) {\n      logger.warn('No targetingKey provided in context')\n      return {\n        value: defaultValue,\n        reason: StandardResolutionReasons.ERROR,\n        errorCode: ErrorCode.GENERAL,\n      }\n    }\n\n    try {\n      const flagContext = this.buildFlagContext(context)\n      const flagValue = await this.client.getFeatureFlag(flagKey, targetingKey, {\n        onlyEvaluateLocally: this.evaluateLocally,\n        sendFeatureFlagEvents: true,\n        ...flagContext,\n      })\n\n      if (flagValue === undefined) {\n        return {\n          value: defaultValue,\n          reason: StandardResolutionReasons.DEFAULT,\n          errorCode: ErrorCode.FLAG_NOT_FOUND,\n        }\n      }\n\n      return {\n        value: flagValue,\n        reason: StandardResolutionReasons.TARGETING_MATCH,\n      }\n    } catch (error) {\n      logger.error(`Error evaluating flag ${flagKey}:`, error)\n      return {\n        value: defaultValue,\n        reason: StandardResolutionReasons.ERROR,\n        errorCode: ErrorCode.GENERAL,\n      }\n    }\n  }\n\n  private getTargetingKey(context: EvaluationContext): string | undefined {\n    return context.targetingKey\n  }\n\n  private buildFlagContext(context: EvaluationContext) {\n    const flagContext: {\n      groups?: Record<string, string>\n      groupProperties?: Record<string, Record<string, string>>\n      personProperties?: Record<string, string>\n    } = {}\n\n    // Extract groups from context\n    if (context.groups) {\n      flagContext.groups = context.groups as Record<string, string>\n    }\n\n    // Extract custom properties\n    if (context.personProperties) {\n      flagContext.personProperties = context.personProperties as Record<string, string>\n    }\n\n    if (context.groupProperties) {\n      flagContext.groupProperties = context.groupProperties as Record<string, Record<string, string>>\n    }\n\n    // Use organizationId from context attributes\n    if (context.organizationId && !flagContext.groups?.organization) {\n      flagContext.groups = {\n        ...flagContext.groups,\n        organization: context.organizationId as string,\n      }\n    }\n\n    return flagContext\n  }\n\n  get hooks(): Hook[] {\n    return []\n  }\n\n  async onClose(): Promise<void> {\n    if (this.client) {\n      await this.client.shutdown()\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/repositories/base.repository.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Repository,\n  DataSource,\n  FindOptionsWhere,\n  FindOneOptions,\n  FindManyOptions,\n  EntityTarget,\n  SelectQueryBuilder,\n  DeleteResult,\n} from 'typeorm'\nimport { ObjectLiteral } from 'typeorm/common/ObjectLiteral'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\n\n/**\n * Abstract base repository class that provides common CRUD operations with event emission.\n *\n * @template TEntity - The entity class this repository manages\n */\nexport abstract class BaseRepository<TEntity extends ObjectLiteral> {\n  protected repository: Repository<TEntity>\n\n  constructor(\n    protected readonly dataSource: DataSource,\n    protected readonly eventEmitter: EventEmitter2,\n    protected readonly entityClass: EntityTarget<TEntity>,\n  ) {\n    this.repository = this.dataSource.getRepository(entityClass)\n  }\n\n  /**\n   * See reference for {@link Repository.findOne}\n   */\n  async findOne(options: FindOneOptions<TEntity>): Promise<TEntity | null> {\n    return this.repository.findOne(options)\n  }\n\n  /**\n   * See reference for {@link Repository.findOneBy}\n   */\n  async findOneBy(where: FindOptionsWhere<TEntity> | FindOptionsWhere<TEntity>[]): Promise<TEntity | null> {\n    return this.repository.findOneBy(where)\n  }\n\n  /**\n   * See reference for {@link Repository.findOneByOrFail}\n   */\n  async findOneByOrFail(where: FindOptionsWhere<TEntity> | FindOptionsWhere<TEntity>[]): Promise<TEntity> {\n    return this.repository.findOneByOrFail(where)\n  }\n\n  /**\n   * See reference for {@link Repository.findOneOrFail}\n   */\n  async findOneOrFail(options: FindOneOptions<TEntity>): Promise<TEntity> {\n    return this.repository.findOneOrFail(options)\n  }\n\n  /**\n   * See reference for {@link Repository.find}\n   */\n  async find(options?: FindManyOptions<TEntity>): Promise<TEntity[]> {\n    return this.repository.find(options)\n  }\n\n  /**\n   * See reference for {@link Repository.findAndCount}\n   */\n  async findAndCount(options?: FindManyOptions<TEntity>): Promise<[TEntity[], number]> {\n    return this.repository.findAndCount(options)\n  }\n\n  /**\n   * See reference for {@link Repository.count}\n   */\n  async count(options?: FindManyOptions<TEntity>): Promise<number> {\n    return this.repository.count(options)\n  }\n\n  /**\n   * Returns the entity manager for the repository. Use this only when you need to perform raw SQL queries.\n   *\n   * See reference for {@link Repository.manager}\n   */\n  get manager() {\n    return this.repository.manager\n  }\n\n  /**\n   * See reference for {@link Repository.createQueryBuilder}\n   */\n  createQueryBuilder(alias?: string): SelectQueryBuilder<TEntity> {\n    return this.repository.createQueryBuilder(alias)\n  }\n\n  /**\n   * See reference for {@link Repository.delete}\n   */\n  async delete(criteria: FindOptionsWhere<TEntity> | FindOptionsWhere<TEntity>[]): Promise<DeleteResult> {\n    return this.repository.delete(criteria)\n  }\n\n  /**\n   * Inserts a new entity into the database.\n   *\n   * Uses {@link Repository.insert} to insert the entity into the database.\n   *\n   * @returns The inserted entity.\n   */\n  abstract insert(entity: TEntity): Promise<TEntity>\n\n  /**\n   * Partially updates an entity in the database.\n   *\n   * Uses {@link Repository.update} to update the entity in the database.\n   *\n   * @param id - The ID of the entity to update.\n   * @param params.updateData - The partial data to update.\n   * @param params.entity - Optional pre-fetched entity to use instead of fetching from the database when not performing a raw update.\n   * @param raw - If true, performs only the database update via {@link Repository.update},\n   *   skipping entity fetching, domain logic (validation, derived fields), and event emission.\n   *\n   * @returns The updated entity or void if `raw` is true.\n   */\n  abstract update(id: string, params: { updateData: Partial<TEntity>; entity?: TEntity }, raw: true): Promise<void>\n  abstract update(id: string, params: { updateData: Partial<TEntity>; entity?: TEntity }, raw?: false): Promise<TEntity>\n  abstract update(\n    id: string,\n    params: { updateData: Partial<TEntity>; entity?: TEntity },\n    raw?: boolean,\n  ): Promise<TEntity | void>\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/api-key.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as crypto from 'crypto'\n\nexport function generateRandomString(size: number): string {\n  return crypto.randomBytes(size).toString('hex')\n}\n\nexport function generateApiKeyValue(): string {\n  return `dtn_${generateRandomString(32)}`\n}\n\nexport function generateApiKeyHash(value: string): string {\n  return crypto.createHash('sha256').update(value).digest('hex')\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/app-mode.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\ntype AppMode = 'api' | 'worker' | 'all'\n\nlet appMode = process.env.APP_MODE as AppMode\n\n// Default to all mode if no app mode is set\nif (!appMode) {\n  appMode = 'all'\n}\n\n// Validate app mode\nif (!Object.values(['api', 'worker', 'all']).includes(appMode)) {\n  throw new Error(`Invalid app mode: ${appMode}`)\n}\n\n/**\n * Returns true if the API should be started\n */\nexport function isApiEnabled(): boolean {\n  return appMode === 'api' || appMode === 'all'\n}\n\n/**\n * Returns true if the worker should be started\n */\nexport function isWorkerEnabled(): boolean {\n  return appMode === 'worker' || appMode === 'all'\n}\n\n/**\n * Returns the app mode\n */\nexport function getAppMode(): AppMode {\n  return appMode\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/delete-s3-bucket.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  S3Client,\n  ListObjectsV2Command,\n  DeleteObjectsCommand,\n  ListObjectVersionsCommand,\n  DeleteBucketCommand,\n} from '@aws-sdk/client-s3'\n\nexport async function deleteS3Bucket(s3: S3Client, bucket: string): Promise<void> {\n  // First delete all object versions & delete markers (if any exist)\n  let keyMarker: string | undefined\n  let versionIdMarker: string | undefined\n  do {\n    const versions = await s3.send(\n      new ListObjectVersionsCommand({\n        Bucket: bucket,\n        KeyMarker: keyMarker,\n        VersionIdMarker: versionIdMarker,\n      }),\n    )\n    const items = [\n      ...(versions.Versions || []).map((v) => ({ Key: v.Key, VersionId: v.VersionId })),\n      ...(versions.DeleteMarkers || []).map((d) => ({ Key: d.Key, VersionId: d.VersionId })),\n    ]\n    if (items.length) {\n      await s3.send(\n        new DeleteObjectsCommand({\n          Bucket: bucket,\n          Delete: { Objects: items, Quiet: true },\n        }),\n      )\n    }\n    keyMarker = versions.NextKeyMarker\n    versionIdMarker = versions.NextVersionIdMarker\n  } while (keyMarker || versionIdMarker)\n\n  // Then delete any remaining live objects (for unversioned buckets)\n  let continuationToken: string | undefined\n  do {\n    const list = await s3.send(\n      new ListObjectsV2Command({\n        Bucket: bucket,\n        ContinuationToken: continuationToken,\n      }),\n    )\n    if (list.Contents && list.Contents.length) {\n      await s3.send(\n        new DeleteObjectsCommand({\n          Bucket: bucket,\n          Delete: {\n            Objects: list.Contents.map((o) => ({ Key: o.Key })),\n            Quiet: true,\n          },\n        }),\n      )\n    }\n    continuationToken = list.NextContinuationToken\n  } while (continuationToken)\n\n  // Finally delete the (now-empty) bucket\n  await s3.send(new DeleteBucketCommand({ Bucket: bucket }))\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/docker-image.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Interface representing parsed Docker image information\n */\nexport interface DockerImageInfo {\n  /** The full registry hostname (e.g. 'registry:5000' or 'docker.io') */\n  registry?: string\n  /** The project/organization name (e.g. 'test' in 'registry:5000/test/image') */\n  project?: string\n  /** The repository/image name (e.g. 'image' in 'registry:5000/test/image') */\n  repository: string\n  /** The tag or digest (e.g. 'latest' or 'sha256:123...') */\n  tag?: string\n  /** The full original image name */\n  originalName: string\n}\n\nexport class DockerImage implements DockerImageInfo {\n  registry?: string\n  project?: string\n  repository: string\n  tag?: string\n  originalName: string\n\n  constructor(info: DockerImageInfo) {\n    this.registry = info.registry\n    this.project = info.project\n    this.repository = info.repository\n    this.tag = info.tag\n    this.originalName = info.originalName\n  }\n\n  getFullName(): string {\n    let name = this.repository\n    if (this.project) {\n      name = `${this.project}/${name}`\n    }\n    if (this.registry) {\n      name = `${this.registry}/${name}`\n    }\n    if (this.tag) {\n      name = `${name}:${this.tag}`\n    }\n    return name\n  }\n}\n\n/**\n * Parses a Docker image name into its component parts\n *\n * @param imageName - The full image name (e.g. 'registry:5000/test/image:latest')\n * @returns Parsed image information\n *\n * Examples:\n * - registry:5000/test/image:latest -> { registry: 'registry:5000', project: 'test', repository: 'image', tag: 'latest' }\n * - docker.io/library/ubuntu:20.04 -> { registry: 'docker.io', project: 'library', repository: 'ubuntu', tag: '20.04' }\n * - ubuntu:20.04 -> { registry: undefined, project: undefined, repository: 'ubuntu', tag: '20.04' }\n * - ubuntu -> { registry: undefined, project: undefined, repository: 'ubuntu', tag: undefined }\n */\nexport function parseDockerImage(imageName: string): DockerImage {\n  // Handle empty or invalid input\n  if (!imageName) {\n    throw new Error('Image name cannot be empty')\n  }\n\n  const result: DockerImageInfo = {\n    originalName: imageName,\n    repository: '',\n  }\n\n  // Check for digest format first\n  let parts: string[] = []\n  if (imageName.includes('@sha256:')) {\n    const [nameWithoutDigest, digest] = imageName.split('@sha256:')\n    if (!nameWithoutDigest || !digest || !/^[a-f0-9]{64}$/.test(digest)) {\n      throw new Error('Invalid digest format. Must be image@sha256:64_hex_characters')\n    }\n    result.tag = `sha256:${digest}`\n    // Split remaining parts\n    parts = nameWithoutDigest.split('/')\n\n    // Throw if a part is empty\n    if (parts.some((part) => part === '')) {\n      throw new Error('Invalid image name. A part is empty')\n    }\n  } else {\n    const lastSlashIndex = imageName.lastIndexOf('/')\n    const lastColonIndex = imageName.lastIndexOf(':')\n    const hasTag = lastColonIndex > lastSlashIndex\n\n    const nameWithoutTag = hasTag ? imageName.substring(0, lastColonIndex) : imageName\n    if (hasTag) {\n      result.tag = imageName.substring(lastColonIndex + 1)\n    }\n    // Split remaining parts\n    parts = nameWithoutTag.split('/')\n  }\n\n  // Check if first part looks like a registry hostname (contains '.' or ':' or is 'localhost')\n  if (parts.length >= 2 && (parts[0].includes('.') || parts[0].includes(':') || parts[0] === 'localhost')) {\n    result.registry = parts[0]\n    parts.shift() // Remove registry part\n  }\n\n  // Handle remaining parts\n  if (parts.length >= 2) {\n    // Format: [registry/]project/repository\n    result.project = parts.slice(0, -1).join('/')\n    result.repository = parts[parts.length - 1]\n  } else {\n    // Format: repository\n    result.repository = parts[0]\n  }\n\n  return new DockerImage(result)\n}\n\n/**\n * Checks if the Dockerfile content contains any FROM images that may require registry credentials.\n * This includes:\n * - Private registry images (e.g., 'myregistry.com/image', 'registry:5000/image')\n * - Private Docker Hub images (e.g., 'username/my-private-image')\n *\n * @param dockerfileContent - The full Dockerfile content as a string\n * @returns true if any FROM image may require credentials, false otherwise\n *\n * Example:\n * - FROM node:18 -> false (public Docker Hub library image)\n * - FROM username/my-image:0.0.1 -> true (private Docker Hub image)\n * - FROM myregistry.com/myimage:latest -> true (private registry)\n * - FROM registry:5000/test/image -> true (private registry)\n */\nexport function checkDockerfileHasRegistryPrefix(dockerfileContent: string): boolean {\n  const lines = dockerfileContent.split('\\n')\n\n  // Regex to match FROM statements\n  const fromRegex = /^\\s*FROM\\s+(?:--[a-z-]+=[^\\s]+\\s+)*([^\\s]+)(?:\\s+AS\\s+[^\\s]+)?/i\n\n  for (const line of lines) {\n    // Remove inline comments (everything after #)\n    const lineWithoutComment = line.split('#')[0]\n    const trimmedLine = lineWithoutComment.trim()\n\n    // Skip empty lines and comment-only lines\n    if (!trimmedLine) {\n      continue\n    }\n\n    const match = fromRegex.exec(trimmedLine)\n    if (match && match[1]) {\n      const imageName = match[1].trim()\n\n      // Check if image has a path component (contains '/')\n      // This covers both private registries and private Docker Hub images (namespace/image)\n      if (imageName.includes('/')) {\n        return true\n      }\n    }\n  }\n\n  return false\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/email.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class EmailUtils {\n  static normalize(email: string): string {\n    return email.toLowerCase().trim()\n  }\n\n  static areEqual(email1: string, email2: string): boolean {\n    return this.normalize(email1) === this.normalize(email2)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/from-axios-error.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport function fromAxiosError(error: any): Error {\n  return new Error(error.response?.data?.message || error.response?.data || error.message || error)\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/naming-strategy.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DefaultNamingStrategy, NamingStrategyInterface, Table } from 'typeorm'\n\nexport class CustomNamingStrategy extends DefaultNamingStrategy implements NamingStrategyInterface {\n  primaryKeyName(tableOrName: Table | string, columnNames: string[]) {\n    const table = tableOrName instanceof Table ? tableOrName.name : tableOrName\n    const columnsSnakeCase = columnNames.join('_')\n    return `${table}_${columnsSnakeCase}_pk`\n  }\n\n  foreignKeyName(tableOrName: Table | string, columnNames: string[]): string {\n    const table = tableOrName instanceof Table ? tableOrName.name : tableOrName\n    const columnsSnakeCase = columnNames.join('_')\n    return `${table}_${columnsSnakeCase}_fk`\n  }\n\n  uniqueConstraintName(tableOrName: Table | string, columnNames: string[]): string {\n    const table = tableOrName instanceof Table ? tableOrName.name : tableOrName\n    const columnsSnakeCase = columnNames.join('_')\n    return `${table}_${columnsSnakeCase}_unique`\n  }\n\n  indexName(tableOrName: Table | string, columnNames: string[]): string {\n    const table = tableOrName instanceof Table ? tableOrName.name : tableOrName\n    const columnsSnakeCase = columnNames.join('_')\n    return `${table}_${columnsSnakeCase}_index`\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/pino.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport pino, { TransportSingleOptions } from 'pino'\nimport { TypedConfigService } from '../../config/typed-config.service'\n\n/*\n * This is a workaround to swap the message and object in the arguments array.\n * It is needed because the logger in nestjs-pino is not compatible with nestjs console logger.\n * ref: https://github.com/iamolegga/nestjs-pino/issues/2004\n *\n */\nexport function swapMessageAndObject(\n  this: pino.Logger,\n  args: Parameters<pino.LogFn>,\n  method: pino.LogFn,\n  level: number,\n): void {\n  // Type guard helper\n  const isPlainObject = (val: unknown): val is Record<string, unknown> => {\n    return typeof val === 'object' && val !== null && !Array.isArray(val)\n  }\n\n  // NestJS Logger adds context as first arg, so check args[1] and args[2]\n  if (args.length >= 3 && isPlainObject(args[0])) {\n    const contextObj = args[0]\n    const firstArg: unknown = args[1]\n    const secondArg: unknown = args[2]\n\n    // Case 1: message + Error\n    if (typeof firstArg === 'string' && secondArg instanceof Error) {\n      method.apply(this, [{ ...contextObj, err: secondArg }, firstArg, ...args.slice(3)])\n      return\n    }\n\n    // Case 2: message + additional context object\n    if (typeof firstArg === 'string' && isPlainObject(secondArg)) {\n      method.apply(this, [{ ...contextObj, ...secondArg }, firstArg, ...args.slice(3)])\n      return\n    }\n\n    // Case 3: message + stack trace string\n    if (\n      typeof firstArg === 'string' &&\n      typeof secondArg === 'string' &&\n      secondArg.includes('\\n') &&\n      secondArg.includes('at ')\n    ) {\n      method.apply(this, [{ ...contextObj, stack: secondArg }, firstArg, ...args.slice(3)])\n      return\n    }\n  }\n\n  // Handle case without context (direct Pino usage)\n  if (args.length >= 2) {\n    const firstArg: unknown = args[0]\n    const secondArg: unknown = args[1]\n\n    // Case 1: message + Error\n    if (typeof firstArg === 'string' && secondArg instanceof Error) {\n      method.apply(this, [{ err: secondArg }, firstArg, ...args.slice(2)])\n      return\n    }\n\n    // Case 2: message + additional context object\n    if (typeof firstArg === 'string' && isPlainObject(secondArg)) {\n      method.apply(this, [secondArg, firstArg, ...args.slice(2)])\n      return\n    }\n\n    // Case 3: message + stack trace string\n    if (\n      typeof firstArg === 'string' &&\n      typeof secondArg === 'string' &&\n      secondArg.includes('\\n') &&\n      secondArg.includes('at ')\n    ) {\n      method.apply(this, [{ stack: secondArg }, firstArg, ...args.slice(2)])\n      return\n    }\n  }\n\n  // Default behavior for other cases\n  method.apply(this, args)\n}\n\ntype LogConfig = ReturnType<typeof TypedConfigService.prototype.get<'log'>>\n\n/*\n * Get the pino transport based on the configuration\n * @param isProduction - whether the application is in production mode\n * @param logConfig - the log configuration\n * @returns the pino transport\n */\nexport function getPinoTransport(\n  isProduction: boolean,\n  logConfig: LogConfig,\n): TransportSingleOptions<Record<string, any>> {\n  switch (true) {\n    // if console disabled, set destination to /dev/null\n    case logConfig.console.disabled:\n      return {\n        target: 'pino/file',\n        options: {\n          destination: '/dev/null',\n        },\n      }\n    // if production mode, no transport => raw NDJSON\n    case isProduction:\n      return undefined\n    // if non-production use pino-pretty\n    default:\n      return {\n        target: 'pino-pretty',\n        options: {\n          colorize: true,\n          singleLine: true,\n          ignore: 'pid,hostname',\n        },\n      }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/range-filter.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MoreThanOrEqual, LessThanOrEqual, Between } from 'typeorm'\n\n/**\n * Creates a TypeORM range filter from min/max values\n * @param minValue - Minimum value (inclusive)\n * @param maxValue - Maximum value (inclusive)\n * @returns TypeORM comparison operator (Between, MoreThanOrEqual, LessThanOrEqual, or undefined)\n */\nexport function createRangeFilter<T>(minValue?: T, maxValue?: T) {\n  if (minValue !== undefined && maxValue !== undefined) {\n    return Between(minValue, maxValue)\n  } else if (minValue !== undefined) {\n    return MoreThanOrEqual(minValue)\n  } else if (maxValue !== undefined) {\n    return LessThanOrEqual(maxValue)\n  }\n  return undefined\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/rate-limit-headers.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Response } from 'express'\n\n/**\n * Utility functions for setting rate limit headers consistently across middleware and services\n */\n\nexport interface RateLimitHeadersOptions {\n  throttlerName: string\n  limit: number\n  remaining: number\n  resetSeconds: number\n  retryAfterSeconds?: number\n}\n\n/**\n * Sets standard rate limit headers on a response\n * Follows the pattern: X-RateLimit-{Limit|Remaining|Reset}-{throttlerName}\n */\nexport function setRateLimitHeaders(response: Response, options: RateLimitHeadersOptions): void {\n  const { throttlerName, limit, remaining, resetSeconds, retryAfterSeconds } = options\n\n  response.setHeader(`X-RateLimit-Limit-${throttlerName}`, limit.toString())\n  response.setHeader(`X-RateLimit-Remaining-${throttlerName}`, remaining.toString())\n  response.setHeader(`X-RateLimit-Reset-${throttlerName}`, resetSeconds.toString())\n\n  if (retryAfterSeconds !== undefined) {\n    response.setHeader('Retry-After', retryAfterSeconds.toString())\n  }\n}\n"
  },
  {
    "path": "apps/api/src/common/utils/uuid.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport function isValidUuid(value: string): boolean {\n  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)\n}\n"
  },
  {
    "path": "apps/api/src/config/config.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Get } from '@nestjs/common'\nimport { TypedConfigService } from './typed-config.service'\nimport { ApiOperation, ApiTags, ApiResponse } from '@nestjs/swagger'\nimport { ConfigurationDto } from './dto/configuration.dto'\n\n@ApiTags('config')\n@Controller('config')\nexport class ConfigController {\n  constructor(private readonly configService: TypedConfigService) {}\n\n  @Get()\n  @ApiOperation({ summary: 'Get config' })\n  @ApiResponse({\n    status: 200,\n    description: 'Daytona configuration',\n    type: ConfigurationDto,\n  })\n  getConfig() {\n    return new ConfigurationDto(this.configService)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/config/configuration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nconst configuration = {\n  production: process.env.NODE_ENV === 'production',\n  version: process.env.VERSION || '0.0.0-dev',\n  environment: process.env.ENVIRONMENT,\n  runMigrations: process.env.RUN_MIGRATIONS === 'true',\n  port: parseInt(process.env.PORT, 10),\n  appUrl: process.env.APP_URL,\n  database: {\n    host: process.env.DB_HOST,\n    port: parseInt(process.env.DB_PORT || '5432', 10),\n    username: process.env.DB_USERNAME,\n    password: process.env.DB_PASSWORD,\n    database: process.env.DB_DATABASE,\n    tls: {\n      enabled: process.env.DB_TLS_ENABLED === 'true',\n      rejectUnauthorized: process.env.DB_TLS_REJECT_UNAUTHORIZED !== 'false',\n    },\n    pool: {\n      max: process.env.DB_POOL_MAX && parseInt(process.env.DB_POOL_MAX, 10),\n      min: process.env.DB_POOL_MIN && parseInt(process.env.DB_POOL_MIN, 10),\n      idleTimeoutMillis: process.env.DB_POOL_IDLE_TIMEOUT_MS && parseInt(process.env.DB_POOL_IDLE_TIMEOUT_MS, 10),\n      connectionTimeoutMillis:\n        process.env.DB_POOL_CONNECTION_TIMEOUT_MS && parseInt(process.env.DB_POOL_CONNECTION_TIMEOUT_MS, 10),\n    },\n  },\n  redis: {\n    host: process.env.REDIS_HOST,\n    port: parseInt(process.env.REDIS_PORT || '6379', 10),\n    username: process.env.REDIS_USERNAME,\n    password: process.env.REDIS_PASSWORD,\n    tls: process.env.REDIS_TLS === 'true' ? {} : undefined,\n  },\n  posthog: {\n    apiKey: process.env.POSTHOG_API_KEY,\n    host: process.env.POSTHOG_HOST,\n    environment: process.env.POSTHOG_ENVIRONMENT,\n  },\n  oidc: {\n    clientId: process.env.OIDC_CLIENT_ID || process.env.OID_CLIENT_ID,\n    issuer: process.env.OIDC_ISSUER_BASE_URL || process.env.OID_ISSUER_BASE_URL,\n    publicIssuer: process.env.PUBLIC_OIDC_DOMAIN,\n    audience: process.env.OIDC_AUDIENCE || process.env.OID_AUDIENCE,\n    managementApi: {\n      enabled: process.env.OIDC_MANAGEMENT_API_ENABLED === 'true',\n      clientId: process.env.OIDC_MANAGEMENT_API_CLIENT_ID,\n      clientSecret: process.env.OIDC_MANAGEMENT_API_CLIENT_SECRET,\n      audience: process.env.OIDC_MANAGEMENT_API_AUDIENCE,\n    },\n  },\n  smtp: {\n    host: process.env.SMTP_HOST,\n    port: parseInt(process.env.SMTP_PORT || '587', 10),\n    user: process.env.SMTP_USER,\n    password: process.env.SMTP_PASSWORD,\n    secure: process.env.SMTP_SECURE === 'true',\n    from: process.env.SMTP_EMAIL_FROM || 'noreply@mail.daytona.io',\n  },\n  defaultSnapshot: process.env.DEFAULT_SNAPSHOT,\n  dashboardUrl: process.env.DASHBOARD_URL,\n  // Default to empty string - dashboard will then hit '/api'\n  dashboardBaseApiUrl: process.env.DASHBOARD_BASE_API_URL || '',\n  transientRegistry: {\n    url: process.env.TRANSIENT_REGISTRY_URL,\n    admin: process.env.TRANSIENT_REGISTRY_ADMIN,\n    password: process.env.TRANSIENT_REGISTRY_PASSWORD,\n    projectId: process.env.TRANSIENT_REGISTRY_PROJECT_ID,\n  },\n  internalRegistry: {\n    url: process.env.INTERNAL_REGISTRY_URL,\n    admin: process.env.INTERNAL_REGISTRY_ADMIN,\n    password: process.env.INTERNAL_REGISTRY_PASSWORD,\n    projectId: process.env.INTERNAL_REGISTRY_PROJECT_ID,\n  },\n  s3: {\n    endpoint: process.env.S3_ENDPOINT,\n    stsEndpoint: process.env.S3_STS_ENDPOINT,\n    region: process.env.S3_REGION,\n    accessKey: process.env.S3_ACCESS_KEY,\n    secretKey: process.env.S3_SECRET_KEY,\n    defaultBucket: process.env.S3_DEFAULT_BUCKET,\n    accountId: process.env.S3_ACCOUNT_ID,\n    roleName: process.env.S3_ROLE_NAME,\n  },\n  notificationGatewayDisabled: process.env.NOTIFICATION_GATEWAY_DISABLED === 'true',\n  skipConnections: process.env.SKIP_CONNECTIONS === 'true',\n  maxAutoArchiveInterval: parseInt(process.env.MAX_AUTO_ARCHIVE_INTERVAL || '43200', 10),\n  maintananceMode: process.env.MAINTENANCE_MODE === 'true',\n  disableCronJobs: process.env.DISABLE_CRON_JOBS === 'true',\n  appRole: process.env.APP_ROLE || 'all',\n  proxy: {\n    domain: process.env.PROXY_DOMAIN,\n    protocol: process.env.PROXY_PROTOCOL,\n    apiKey: process.env.PROXY_API_KEY,\n    templateUrl: process.env.PROXY_TEMPLATE_URL,\n    toolboxUrl:\n      (process.env.PROXY_TOOLBOX_BASE_URL || `${process.env.PROXY_PROTOCOL}://${process.env.PROXY_DOMAIN}`) +\n      '/toolbox',\n  },\n  audit: {\n    toolboxRequestsEnabled: process.env.AUDIT_TOOLBOX_REQUESTS_ENABLED === 'true',\n    retentionDays: process.env.AUDIT_LOG_RETENTION_DAYS\n      ? parseInt(process.env.AUDIT_LOG_RETENTION_DAYS, 10)\n      : undefined,\n    consoleLogEnabled: process.env.AUDIT_CONSOLE_LOG_ENABLED === 'true',\n    publish: {\n      enabled: process.env.AUDIT_PUBLISH_ENABLED === 'true',\n      batchSize: process.env.AUDIT_PUBLISH_BATCH_SIZE ? parseInt(process.env.AUDIT_PUBLISH_BATCH_SIZE, 10) : 1000,\n      mode: (process.env.AUDIT_PUBLISH_MODE || 'direct') as 'direct' | 'kafka',\n      storageAdapter: process.env.AUDIT_PUBLISH_STORAGE_ADAPTER || 'opensearch',\n      opensearchIndexName: process.env.AUDIT_PUBLISH_OPENSEARCH_INDEX_NAME || 'audit-logs',\n    },\n  },\n  kafka: {\n    enabled: process.env.KAFKA_ENABLED === 'true',\n    brokers: process.env.KAFKA_BROKERS || 'localhost:9092',\n    clientId: process.env.KAFKA_CLIENT_ID,\n    sasl: {\n      mechanism: process.env.KAFKA_SASL_MECHANISM,\n      username: process.env.KAFKA_SASL_USERNAME,\n      password: process.env.KAFKA_SASL_PASSWORD,\n    },\n    tls: {\n      enabled: process.env.KAFKA_TLS_ENABLED === 'true',\n      rejectUnauthorized: process.env.KAFKA_TLS_REJECT_UNAUTHORIZED !== 'false',\n    },\n  },\n  opensearch: {\n    nodes: process.env.OPENSEARCH_NODES || 'https://localhost:9200',\n    username: process.env.OPENSEARCH_USERNAME,\n    password: process.env.OPENSEARCH_PASSWORD,\n    aws: {\n      roleArn: process.env.OPENSEARCH_AWS_ROLE_ARN,\n      region: process.env.OPENSEARCH_AWS_REGION,\n    },\n    tls: {\n      rejectUnauthorized: process.env.OPENSEARCH_TLS_REJECT_UNAUTHORIZED !== 'false',\n    },\n  },\n  cronTimeZone: process.env.CRON_TIMEZONE,\n  maxConcurrentBackupsPerRunner: parseInt(process.env.MAX_CONCURRENT_BACKUPS_PER_RUNNER || '6', 10),\n  webhook: {\n    authToken: process.env.SVIX_AUTH_TOKEN,\n    serverUrl: process.env.SVIX_SERVER_URL,\n  },\n  healthCheck: {\n    apiKey: process.env.HEALTH_CHECK_API_KEY,\n  },\n  sshGateway: {\n    apiKey: process.env.SSH_GATEWAY_API_KEY,\n    command: process.env.SSH_GATEWAY_COMMAND,\n    publicKey: process.env.SSH_GATEWAY_PUBLIC_KEY,\n    url: process.env.SSH_GATEWAY_URL,\n  },\n  organizationSandboxDefaultLimitedNetworkEgress:\n    process.env.ORGANIZATION_SANDBOX_DEFAULT_LIMITED_NETWORK_EGRESS === 'true',\n  pylonAppId: process.env.PYLON_APP_ID,\n  billingApiUrl: process.env.BILLING_API_URL,\n  analyticsApiUrl: process.env.ANALYTICS_API_URL,\n  defaultRunner: {\n    domain: process.env.DEFAULT_RUNNER_DOMAIN,\n    apiKey: process.env.DEFAULT_RUNNER_API_KEY,\n    proxyUrl: process.env.DEFAULT_RUNNER_PROXY_URL,\n    apiUrl: process.env.DEFAULT_RUNNER_API_URL,\n    cpu: parseInt(process.env.DEFAULT_RUNNER_CPU || '4', 10),\n    memory: parseInt(process.env.DEFAULT_RUNNER_MEMORY || '8', 10),\n    disk: parseInt(process.env.DEFAULT_RUNNER_DISK || '50', 10),\n    apiVersion: (process.env.DEFAULT_RUNNER_API_VERSION || '2') as '0' | '2',\n    name: process.env.DEFAULT_RUNNER_NAME,\n  },\n  runnerScore: {\n    thresholds: {\n      declarativeBuild: parseInt(process.env.RUNNER_DECLARATIVE_BUILD_SCORE_THRESHOLD || '10', 10),\n      availability: parseInt(process.env.RUNNER_AVAILABILITY_SCORE_THRESHOLD || '10', 10),\n      start: parseInt(process.env.RUNNER_START_SCORE_THRESHOLD || '3', 10),\n    },\n    weights: {\n      cpuUsage: parseFloat(process.env.RUNNER_CPU_USAGE_WEIGHT || '0.25'),\n      memoryUsage: parseFloat(process.env.RUNNER_MEMORY_USAGE_WEIGHT || '0.4'),\n      diskUsage: parseFloat(process.env.RUNNER_DISK_USAGE_WEIGHT || '0.4'),\n      allocatedCpu: parseFloat(process.env.RUNNER_ALLOCATED_CPU_WEIGHT || '0.03'),\n      allocatedMemory: parseFloat(process.env.RUNNER_ALLOCATED_MEMORY_WEIGHT || '0.03'),\n      allocatedDisk: parseFloat(process.env.RUNNER_ALLOCATED_DISK_WEIGHT || '0.03'),\n      startedSandboxes: parseFloat(process.env.RUNNER_STARTED_SANDBOXES_WEIGHT || '0.1'),\n    },\n    penalty: {\n      exponents: {\n        cpuLoadAvg: parseFloat(process.env.RUNNER_CPU_LOAD_AVG_PENALTY_EXPONENT || '0.1'),\n        cpu: parseFloat(process.env.RUNNER_CPU_PENALTY_EXPONENT || '0.15'),\n        memory: parseFloat(process.env.RUNNER_MEMORY_PENALTY_EXPONENT || '0.15'),\n        disk: parseFloat(process.env.RUNNER_DISK_PENALTY_EXPONENT || '0.15'),\n      },\n      thresholds: {\n        // cpuLoadAvg is a normalized per-CPU load average (e.g. load_avg / num_cpus), not a percentage like the cpu/memory/disk thresholds below.\n        cpuLoadAvg: parseFloat(process.env.RUNNER_CPU_LOAD_AVG_PENALTY_THRESHOLD || '0.7'),\n        cpu: parseInt(process.env.RUNNER_CPU_PENALTY_THRESHOLD || '90', 10),\n        memory: parseInt(process.env.RUNNER_MEMORY_PENALTY_THRESHOLD || '75', 10),\n        disk: parseInt(process.env.RUNNER_DISK_PENALTY_THRESHOLD || '75', 10),\n      },\n    },\n    targetValues: {\n      optimal: {\n        cpu: parseInt(process.env.RUNNER_OPTIMAL_CPU || '0', 10),\n        memory: parseInt(process.env.RUNNER_OPTIMAL_MEMORY || '0', 10),\n        disk: parseInt(process.env.RUNNER_OPTIMAL_DISK || '0', 10),\n        allocCpu: parseInt(process.env.RUNNER_OPTIMAL_ALLOC_CPU || '100', 10),\n        allocMem: parseInt(process.env.RUNNER_OPTIMAL_ALLOC_MEM || '100', 10),\n        allocDisk: parseInt(process.env.RUNNER_OPTIMAL_ALLOC_DISK || '100', 10),\n        startedSandboxes: parseInt(process.env.RUNNER_OPTIMAL_STARTED_SANDBOXES || '0', 10),\n      },\n      critical: {\n        cpu: parseInt(process.env.RUNNER_CRITICAL_CPU || '100', 10),\n        memory: parseInt(process.env.RUNNER_CRITICAL_MEMORY || '100', 10),\n        disk: parseInt(process.env.RUNNER_CRITICAL_DISK || '100', 10),\n        allocCpu: parseInt(process.env.RUNNER_CRITICAL_ALLOC_CPU || '500', 10),\n        allocMem: parseInt(process.env.RUNNER_CRITICAL_ALLOC_MEM || '500', 10),\n        allocDisk: parseInt(process.env.RUNNER_CRITICAL_ALLOC_DISK || '500', 10),\n        startedSandboxes: parseInt(process.env.RUNNER_CRITICAL_STARTED_SANDBOXES || '100', 10),\n      },\n    },\n  },\n  rateLimit: {\n    anonymous: {\n      ttl: process.env.RATE_LIMIT_ANONYMOUS_TTL ? parseInt(process.env.RATE_LIMIT_ANONYMOUS_TTL, 10) : undefined,\n      limit: process.env.RATE_LIMIT_ANONYMOUS_LIMIT ? parseInt(process.env.RATE_LIMIT_ANONYMOUS_LIMIT, 10) : undefined,\n    },\n    failedAuth: {\n      ttl: process.env.RATE_LIMIT_FAILED_AUTH_TTL ? parseInt(process.env.RATE_LIMIT_FAILED_AUTH_TTL, 10) : undefined,\n      limit: process.env.RATE_LIMIT_FAILED_AUTH_LIMIT\n        ? parseInt(process.env.RATE_LIMIT_FAILED_AUTH_LIMIT, 10)\n        : undefined,\n    },\n    authenticated: {\n      ttl: process.env.RATE_LIMIT_AUTHENTICATED_TTL\n        ? parseInt(process.env.RATE_LIMIT_AUTHENTICATED_TTL, 10)\n        : undefined,\n      limit: process.env.RATE_LIMIT_AUTHENTICATED_LIMIT\n        ? parseInt(process.env.RATE_LIMIT_AUTHENTICATED_LIMIT, 10)\n        : undefined,\n    },\n    sandboxCreate: {\n      ttl: process.env.RATE_LIMIT_SANDBOX_CREATE_TTL\n        ? parseInt(process.env.RATE_LIMIT_SANDBOX_CREATE_TTL, 10)\n        : undefined,\n      limit: process.env.RATE_LIMIT_SANDBOX_CREATE_LIMIT\n        ? parseInt(process.env.RATE_LIMIT_SANDBOX_CREATE_LIMIT, 10)\n        : undefined,\n    },\n    sandboxLifecycle: {\n      ttl: process.env.RATE_LIMIT_SANDBOX_LIFECYCLE_TTL\n        ? parseInt(process.env.RATE_LIMIT_SANDBOX_LIFECYCLE_TTL, 10)\n        : undefined,\n      limit: process.env.RATE_LIMIT_SANDBOX_LIFECYCLE_LIMIT\n        ? parseInt(process.env.RATE_LIMIT_SANDBOX_LIFECYCLE_LIMIT, 10)\n        : undefined,\n    },\n  },\n  log: {\n    console: {\n      disabled: process.env.LOG_CONSOLE_DISABLED === 'true',\n    },\n    level: process.env.LOG_LEVEL || 'info',\n    requests: {\n      enabled: process.env.LOG_REQUESTS_ENABLED === 'true',\n    },\n  },\n  defaultOrganizationQuota: {\n    totalCpuQuota: parseInt(process.env.DEFAULT_ORG_QUOTA_TOTAL_CPU_QUOTA || '10', 10),\n    totalMemoryQuota: parseInt(process.env.DEFAULT_ORG_QUOTA_TOTAL_MEMORY_QUOTA || '10', 10),\n    totalDiskQuota: parseInt(process.env.DEFAULT_ORG_QUOTA_TOTAL_DISK_QUOTA || '30', 10),\n    maxCpuPerSandbox: parseInt(process.env.DEFAULT_ORG_QUOTA_MAX_CPU_PER_SANDBOX || '4', 10),\n    maxMemoryPerSandbox: parseInt(process.env.DEFAULT_ORG_QUOTA_MAX_MEMORY_PER_SANDBOX || '8', 10),\n    maxDiskPerSandbox: parseInt(process.env.DEFAULT_ORG_QUOTA_MAX_DISK_PER_SANDBOX || '10', 10),\n    snapshotQuota: parseInt(process.env.DEFAULT_ORG_QUOTA_SNAPSHOT_QUOTA || '100', 10),\n    maxSnapshotSize: parseInt(process.env.DEFAULT_ORG_QUOTA_MAX_SNAPSHOT_SIZE || '20', 10),\n    volumeQuota: parseInt(process.env.DEFAULT_ORG_QUOTA_VOLUME_QUOTA || '100', 10),\n  },\n  defaultRegion: {\n    id: process.env.DEFAULT_REGION_ID || 'us',\n    name: process.env.DEFAULT_REGION_NAME || 'us',\n    enforceQuotas: process.env.DEFAULT_REGION_ENFORCE_QUOTAS === 'true',\n  },\n  admin: {\n    apiKey: process.env.ADMIN_API_KEY,\n    totalCpuQuota: parseInt(process.env.ADMIN_TOTAL_CPU_QUOTA || '0', 10),\n    totalMemoryQuota: parseInt(process.env.ADMIN_TOTAL_MEMORY_QUOTA || '0', 10),\n    totalDiskQuota: parseInt(process.env.ADMIN_TOTAL_DISK_QUOTA || '0', 10),\n    maxCpuPerSandbox: parseInt(process.env.ADMIN_MAX_CPU_PER_SANDBOX || '0', 10),\n    maxMemoryPerSandbox: parseInt(process.env.ADMIN_MAX_MEMORY_PER_SANDBOX || '0', 10),\n    maxDiskPerSandbox: parseInt(process.env.ADMIN_MAX_DISK_PER_SANDBOX || '0', 10),\n    snapshotQuota: parseInt(process.env.ADMIN_SNAPSHOT_QUOTA || '100', 10),\n    maxSnapshotSize: parseInt(process.env.ADMIN_MAX_SNAPSHOT_SIZE || '100', 10),\n    volumeQuota: parseInt(process.env.ADMIN_VOLUME_QUOTA || '0', 10),\n  },\n  skipUserEmailVerification: process.env.SKIP_USER_EMAIL_VERIFICATION === 'true',\n  apiKey: {\n    validationCacheTtlSeconds: parseInt(process.env.API_KEY_VALIDATION_CACHE_TTL_SECONDS || '10', 10),\n    userCacheTtlSeconds: parseInt(process.env.API_KEY_USER_CACHE_TTL_SECONDS || '60', 10),\n  },\n  runnerHealthTimeout: parseInt(process.env.RUNNER_HEALTH_TIMEOUT_SECONDS || '3', 10),\n  warmPool: {\n    candidateLimit: parseInt(process.env.WARM_POOL_CANDIDATE_LIMIT || '300', 10),\n  },\n  sandboxOtel: {\n    endpointUrl: process.env.SANDBOX_OTEL_ENDPOINT_URL,\n  },\n  otelCollector: {\n    apiKey: process.env.OTEL_COLLECTOR_API_KEY,\n  },\n  clickhouse: {\n    host: process.env.CLICKHOUSE_HOST,\n    port: parseInt(process.env.CLICKHOUSE_PORT || '8123', 10),\n    database: process.env.CLICKHOUSE_DATABASE || 'otel',\n    username: process.env.CLICKHOUSE_USERNAME || 'default',\n    password: process.env.CLICKHOUSE_PASSWORD,\n    protocol: process.env.CLICKHOUSE_PROTOCOL || 'https',\n  },\n  encryption: {\n    key: process.env.ENCRYPTION_KEY,\n    salt: process.env.ENCRYPTION_SALT,\n  },\n}\n\nexport { configuration }\n"
  },
  {
    "path": "apps/api/src/config/dto/configuration.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiExtraModels, ApiProperty, ApiPropertyOptional, ApiSchema, getSchemaPath } from '@nestjs/swagger'\nimport { IsBoolean, IsNumber, IsOptional, IsString } from 'class-validator'\nimport { TypedConfigService } from '../typed-config.service'\n\n@ApiSchema({ name: 'Announcement' })\nexport class Announcement {\n  @ApiProperty({\n    description: 'The announcement text',\n    example: 'New feature available!',\n  })\n  @IsString()\n  text: string\n\n  @ApiPropertyOptional({\n    description: 'URL to learn more about the announcement',\n    example: 'https://example.com/learn-more',\n  })\n  @IsString()\n  @IsOptional()\n  learnMoreUrl?: string\n}\n\n@ApiSchema({ name: 'PosthogConfig' })\nexport class PosthogConfig {\n  @ApiProperty({\n    description: 'PostHog API key',\n    example: 'phc_abc123',\n  })\n  @IsString()\n  apiKey: string\n\n  @ApiProperty({\n    description: 'PostHog host URL',\n    example: 'https://app.posthog.com',\n  })\n  @IsString()\n  host: string\n}\n\n@ApiSchema({ name: 'RateLimitEntry' })\nexport class RateLimitEntry {\n  @ApiPropertyOptional({\n    description: 'Rate limit TTL in seconds',\n    example: 60,\n  })\n  @IsNumber()\n  @IsOptional()\n  ttl?: number\n\n  @ApiPropertyOptional({\n    description: 'Rate limit max requests',\n    example: 100,\n  })\n  @IsNumber()\n  @IsOptional()\n  limit?: number\n}\n\n@ApiSchema({ name: 'RateLimitConfig' })\nexport class RateLimitConfig {\n  @ApiPropertyOptional({\n    description: 'Failed authentication rate limit',\n    type: RateLimitEntry,\n  })\n  @IsOptional()\n  failedAuth?: RateLimitEntry\n\n  @ApiPropertyOptional({\n    description: 'Authenticated rate limit',\n    type: RateLimitEntry,\n  })\n  @IsOptional()\n  authenticated?: RateLimitEntry\n\n  @ApiPropertyOptional({\n    description: 'Sandbox create rate limit',\n    type: RateLimitEntry,\n  })\n  @IsOptional()\n  sandboxCreate?: RateLimitEntry\n\n  @ApiPropertyOptional({\n    description: 'Sandbox lifecycle rate limit',\n    type: RateLimitEntry,\n  })\n  @IsOptional()\n  sandboxLifecycle?: RateLimitEntry\n}\n\n@ApiSchema({ name: 'OidcConfig' })\nexport class OidcConfig {\n  @ApiProperty({\n    description: 'OIDC issuer',\n    example: 'https://auth.example.com',\n  })\n  @IsString()\n  issuer: string\n\n  @ApiProperty({\n    description: 'OIDC client ID',\n    example: 'daytona-client',\n  })\n  @IsString()\n  clientId: string\n\n  @ApiProperty({\n    description: 'OIDC audience',\n    example: 'daytona-api',\n  })\n  @IsString()\n  audience: string\n}\n\n@ApiExtraModels(Announcement)\n@ApiSchema({ name: 'DaytonaConfiguration' })\nexport class ConfigurationDto {\n  @ApiProperty({\n    description: 'Daytona version',\n    example: '0.0.1',\n  })\n  @IsString()\n  version: string\n\n  @ApiPropertyOptional({\n    description: 'PostHog configuration',\n    type: PosthogConfig,\n  })\n  posthog?: PosthogConfig\n\n  @ApiProperty({\n    description: 'OIDC configuration',\n    type: OidcConfig,\n  })\n  oidc: OidcConfig\n\n  @ApiProperty({\n    description: 'Whether linked accounts are enabled',\n    example: true,\n  })\n  @IsBoolean()\n  linkedAccountsEnabled: boolean\n\n  @ApiProperty({\n    description: 'System announcements',\n    type: 'object',\n    additionalProperties: { $ref: getSchemaPath(Announcement) },\n    example: { 'feature-update': { text: 'New feature available!', learnMoreUrl: 'https://example.com' } },\n  })\n  announcements: Record<string, Announcement>\n\n  @ApiPropertyOptional({\n    description: 'Pylon application ID',\n    example: 'pylon-app-123',\n  })\n  @IsString()\n  @IsOptional()\n  pylonAppId?: string\n\n  @ApiProperty({\n    description: 'Proxy template URL',\n    example: 'https://{{PORT}}-{{sandboxId}}.proxy.example.com',\n  })\n  @IsString()\n  proxyTemplateUrl: string\n\n  @ApiProperty({\n    description: 'Toolbox template URL',\n    example: 'https://proxy.example.com/toolbox',\n  })\n  @IsString()\n  proxyToolboxUrl: string\n\n  @ApiProperty({\n    description: 'Default snapshot for sandboxes',\n    example: 'ubuntu:22.04',\n  })\n  @IsString()\n  defaultSnapshot: string\n\n  @ApiProperty({\n    description: 'Dashboard URL',\n    example: 'https://dashboard.example.com',\n  })\n  @IsString()\n  dashboardUrl: string\n\n  @ApiProperty({\n    description: 'Maximum auto-archive interval in minutes',\n    example: 43200,\n  })\n  @IsNumber()\n  maxAutoArchiveInterval: number\n\n  @ApiProperty({\n    description: 'Whether maintenance mode is enabled',\n    example: false,\n  })\n  @IsBoolean()\n  maintananceMode: boolean\n\n  @ApiProperty({\n    description: 'Current environment',\n    example: 'production',\n  })\n  @IsString()\n  environment: string\n\n  @ApiPropertyOptional({\n    description: 'Billing API URL',\n    example: 'https://billing.example.com',\n  })\n  @IsString()\n  @IsOptional()\n  billingApiUrl?: string\n\n  @ApiPropertyOptional({\n    description: 'Analytics API URL',\n    example: 'https://analytics.example.com',\n  })\n  @IsString()\n  @IsOptional()\n  analyticsApiUrl?: string\n\n  @ApiPropertyOptional({\n    description: 'SSH Gateway command',\n    example: 'ssh -p 2222 {{TOKEN}}@localhost',\n  })\n  @IsOptional()\n  @IsString()\n  sshGatewayCommand?: string\n\n  @ApiPropertyOptional({\n    description: 'Base64 encoded SSH Gateway public key',\n    example: 'ssh-gateway-public-key',\n  })\n  @IsOptional()\n  @IsString()\n  sshGatewayPublicKey?: string\n\n  @ApiPropertyOptional({\n    description: 'Rate limit configuration',\n    type: RateLimitConfig,\n  })\n  @IsOptional()\n  rateLimit?: RateLimitConfig\n\n  constructor(configService: TypedConfigService) {\n    this.version = configService.getOrThrow('version')\n\n    this.oidc = {\n      issuer: configService.get('oidc.publicIssuer') || configService.getOrThrow('oidc.issuer'),\n      clientId: configService.getOrThrow('oidc.clientId'),\n      audience: configService.getOrThrow('oidc.audience'),\n    }\n    this.linkedAccountsEnabled = configService.get('oidc.managementApi.enabled')\n    this.proxyTemplateUrl = configService.getOrThrow('proxy.templateUrl')\n    this.proxyToolboxUrl = configService.getOrThrow('proxy.toolboxUrl')\n    this.defaultSnapshot = configService.getOrThrow('defaultSnapshot')\n    this.dashboardUrl = configService.getOrThrow('dashboardUrl')\n    this.maxAutoArchiveInterval = configService.getOrThrow('maxAutoArchiveInterval')\n    this.maintananceMode = configService.getOrThrow('maintananceMode')\n    this.environment = configService.getOrThrow('environment')\n\n    this.sshGatewayCommand = configService.get('sshGateway.command')\n    this.sshGatewayPublicKey = configService.get('sshGateway.publicKey')\n\n    if (configService.get('billingApiUrl')) {\n      this.billingApiUrl = configService.get('billingApiUrl')\n    }\n\n    if (configService.get('analyticsApiUrl')) {\n      this.analyticsApiUrl = configService.get('analyticsApiUrl')\n    }\n\n    if (configService.get('posthog.apiKey')) {\n      this.posthog = {\n        apiKey: configService.get('posthog.apiKey'),\n        host: configService.get('posthog.host'),\n      }\n    }\n    if (configService.get('pylonAppId')) {\n      this.pylonAppId = configService.get('pylonAppId')\n    }\n    // TODO: announcements\n    this.announcements = {}\n\n    this.rateLimit = {\n      authenticated: {\n        ttl: configService.get('rateLimit.authenticated.ttl'),\n        limit: configService.get('rateLimit.authenticated.limit'),\n      },\n      sandboxCreate: {\n        ttl: configService.get('rateLimit.sandboxCreate.ttl'),\n        limit: configService.get('rateLimit.sandboxCreate.limit'),\n      },\n      sandboxLifecycle: {\n        ttl: configService.get('rateLimit.sandboxLifecycle.ttl'),\n        limit: configService.get('rateLimit.sandboxLifecycle.limit'),\n      },\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/config/typed-config.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Global, Module, DynamicModule } from '@nestjs/common'\nimport { ConfigModule as NestConfigModule, ConfigModuleOptions } from '@nestjs/config'\nimport { TypedConfigService } from './typed-config.service'\nimport { configuration } from './configuration'\nimport { ConfigController } from './config.controller'\n\n@Global()\n@Module({\n  imports: [\n    NestConfigModule.forRoot({\n      isGlobal: true,\n      load: [() => configuration],\n    }),\n  ],\n  controllers: [ConfigController],\n  providers: [TypedConfigService],\n  exports: [TypedConfigService],\n})\nexport class TypedConfigModule {\n  static forRoot(options: Partial<ConfigModuleOptions> = {}): DynamicModule {\n    return {\n      module: TypedConfigModule,\n      imports: [\n        NestConfigModule.forRoot({\n          ...options,\n        }),\n      ],\n      providers: [TypedConfigService],\n      exports: [TypedConfigService],\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/config/typed-config.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ConfigService } from '@nestjs/config'\nimport { Injectable } from '@nestjs/common'\nimport { configuration } from './configuration'\nimport { KafkaConfig, Mechanism, SASLOptions } from 'kafkajs'\nimport { AwsSigv4Signer, AwsSigv4SignerResponse } from '@opensearch-project/opensearch/aws'\nimport { defaultProvider } from '@aws-sdk/credential-provider-node'\nimport { fromTemporaryCredentials } from '@aws-sdk/credential-providers'\nimport { ClientOptions } from '@opensearch-project/opensearch'\nimport { RedisOptions } from 'ioredis'\n\ntype Configuration = typeof configuration\n\n// Helper type to get nested property paths\ntype Paths<T> = T extends object\n  ? {\n      [K in keyof T]: K extends string ? (T[K] extends object ? `${K}` | `${K}.${Paths<T[K]>}` : `${K}`) : never\n    }[keyof T]\n  : never\n\n// Helper type to get the type of a property at a given path\ntype PathValue<T, P extends string> = P extends `${infer K}.${infer Rest}`\n  ? K extends keyof T\n    ? T[K] extends object\n      ? PathValue<T[K], Rest>\n      : never\n    : never\n  : P extends keyof T\n    ? T[P]\n    : never\n\n@Injectable()\nexport class TypedConfigService {\n  constructor(private configService: ConfigService) {}\n\n  /**\n   * Get a configuration value with type safety\n   * @param key The configuration key (can be nested using dot notation)\n   * @returns The configuration value with proper typing\n   */\n  get<K extends Paths<Configuration>>(key: K): PathValue<Configuration, K> {\n    return this.configService.get(key)\n  }\n\n  /**\n   * Get a configuration value with type safety, throwing an error if undefined\n   * @param key The configuration key (can be nested using dot notation)\n   * @returns The configuration value with proper typing\n   * @throws Error if the configuration value is undefined\n   */\n  getOrThrow<K extends Paths<Configuration>>(key: K): NonNullable<PathValue<Configuration, K>> {\n    const value = this.get(key)\n    if (value === undefined) {\n      throw new Error(`Configuration key \"${key}\" is undefined`)\n    }\n    return value as NonNullable<PathValue<Configuration, K>>\n  }\n\n  /**\n   * Get the Kafka configuration\n   * @returns The Kafka configuration\n   */\n  getKafkaClientConfig(): KafkaConfig {\n    const mechanism = this.get('kafka.sasl.mechanism') || 'plain'\n    const username = this.get('kafka.sasl.username')\n    const password = this.get('kafka.sasl.password')\n\n    if (mechanism !== 'plain' && mechanism !== 'scram-sha-256' && mechanism !== 'scram-sha-512') {\n      throw new Error(`Invalid Kafka SASL mechanism: ${mechanism}`)\n    }\n    const sasl: SASLOptions | Mechanism | undefined =\n      username && password\n        ? ({\n            mechanism,\n            username,\n            password,\n          } as SASLOptions)\n        : undefined\n\n    return {\n      brokers: this.get('kafka.brokers')\n        .split(',')\n        .map((broker) => broker.trim()),\n      ssl: this.get('kafka.tls.enabled')\n        ? {\n            rejectUnauthorized: this.get('kafka.tls.rejectUnauthorized'),\n          }\n        : undefined,\n      sasl,\n    }\n  }\n\n  /**\n   * Get the OpenSearch configuration\n   * @returns The OpenSearch configuration\n   */\n  getOpenSearchConfig(): ClientOptions {\n    const nodes = this.get('opensearch.nodes')\n      .split(',')\n      .map((node) => node.trim())\n    const username = this.get('opensearch.username')\n    const password = this.get('opensearch.password')\n\n    // Basic auth\n    if (username && password) {\n      return {\n        nodes,\n        auth: {\n          username,\n          password,\n        },\n        ssl: {\n          rejectUnauthorized: this.get('opensearch.tls.rejectUnauthorized'),\n        },\n      }\n    }\n\n    // AWS Sigv4 auth\n    try {\n      let signer: AwsSigv4SignerResponse\n      if (this.get('opensearch.aws.roleArn')) {\n        signer = AwsSigv4Signer({\n          getCredentials: fromTemporaryCredentials({\n            params: {\n              RoleArn: this.get('opensearch.aws.roleArn'),\n              RoleSessionName: 'daytona-opensearch',\n            },\n          }),\n          service: 'es',\n          region: this.get('opensearch.aws.region'),\n        })\n      } else {\n        signer = AwsSigv4Signer({\n          getCredentials() {\n            const credentialsProvider = defaultProvider()\n            return credentialsProvider()\n          },\n          service: 'es',\n          region: this.get('opensearch.aws.region'),\n        })\n      }\n      return {\n        nodes,\n        ssl: {\n          rejectUnauthorized: this.get('opensearch.tls.rejectUnauthorized'),\n        },\n        ...signer,\n      }\n      // Try without auth if AWS credentials are not available\n    } catch {\n      return {\n        nodes,\n        ssl: {\n          rejectUnauthorized: this.get('opensearch.tls.rejectUnauthorized'),\n        },\n      }\n    }\n  }\n\n  /**\n   * Get the Redis configuration\n   * @param overrides Optional overrides for the Redis configuration\n   * @returns The Redis configuration\n   */\n  getRedisConfig(overrides?: Partial<RedisOptions>): RedisOptions {\n    return {\n      host: this.getOrThrow('redis.host'),\n      port: this.getOrThrow('redis.port'),\n      username: this.get('redis.username'),\n      password: this.get('redis.password'),\n      tls: this.get('redis.tls'),\n      lazyConnect: this.get('skipConnections'),\n      ...overrides,\n    }\n  }\n\n  /**\n   * Get the ClickHouse configuration\n   * @returns The ClickHouse configuration\n   */\n  getClickHouseConfig() {\n    const host = this.get('clickhouse.host')\n    if (!host) {\n      return null\n    }\n    return {\n      url: `${this.get('clickhouse.protocol')}://${host}:${this.get('clickhouse.port')}`,\n      username: this.get('clickhouse.username'),\n      password: this.get('clickhouse.password'),\n      database: this.get('clickhouse.database'),\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/controllers/docker-registry.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Controller,\n  Get,\n  Post,\n  Body,\n  Patch,\n  Param,\n  Delete,\n  UseGuards,\n  HttpCode,\n  ForbiddenException,\n  Query,\n} from '@nestjs/common'\nimport {\n  ApiTags,\n  ApiOperation,\n  ApiResponse,\n  ApiOAuth2,\n  ApiHeader,\n  ApiParam,\n  ApiBearerAuth,\n  ApiQuery,\n} from '@nestjs/swagger'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { DockerRegistryService } from '../services/docker-registry.service'\nimport { CreateDockerRegistryDto } from '../dto/create-docker-registry.dto'\nimport { UpdateDockerRegistryDto } from '../dto/update-docker-registry.dto'\nimport { DockerRegistryDto } from '../dto/docker-registry.dto'\nimport { RegistryPushAccessDto } from '../../sandbox/dto/registry-push-access-dto'\nimport { DockerRegistryAccessGuard } from '../guards/docker-registry-access.guard'\nimport { DockerRegistry } from '../decorators/docker-registry.decorator'\nimport { DockerRegistry as DockerRegistryEntity } from '../entities/docker-registry.entity'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { RequiredOrganizationResourcePermissions } from '../../organization/decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { SystemActionGuard } from '../../auth/system-action.guard'\nimport { RequiredSystemRole } from '../../common/decorators/required-role.decorator'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { Audit, MASKED_AUDIT_VALUE, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { RegistryType } from '../enums/registry-type.enum'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('docker-registry')\n@Controller('docker-registry')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, SystemActionGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class DockerRegistryController {\n  constructor(private readonly dockerRegistryService: DockerRegistryService) {}\n\n  @Post()\n  @ApiOperation({\n    summary: 'Create registry',\n    operationId: 'createRegistry',\n  })\n  @ApiResponse({\n    status: 201,\n    description: 'The docker registry has been successfully created.',\n    type: DockerRegistryDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_REGISTRIES])\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.DOCKER_REGISTRY,\n    targetIdFromResult: (result: DockerRegistryDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateDockerRegistryDto>) => ({\n        name: req.body?.name,\n        username: req.body?.username,\n        password: req.body?.password ? MASKED_AUDIT_VALUE : undefined,\n        url: req.body?.url,\n        project: req.body?.project,\n        registryType: req.body?.registryType,\n        isDefault: req.body?.isDefault,\n      }),\n    },\n  })\n  async create(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Body() createDockerRegistryDto: CreateDockerRegistryDto,\n  ): Promise<DockerRegistryDto> {\n    if (createDockerRegistryDto.registryType !== RegistryType.ORGANIZATION && authContext.role !== SystemRole.ADMIN) {\n      throw new ForbiddenException(\n        `Insufficient permissions for creating ${createDockerRegistryDto.registryType} registries`,\n      )\n    }\n\n    if (createDockerRegistryDto.isDefault && authContext.role !== SystemRole.ADMIN) {\n      throw new ForbiddenException('Insufficient permissions for setting a default registry')\n    }\n\n    const dockerRegistry = await this.dockerRegistryService.create(createDockerRegistryDto, authContext.organizationId)\n    return DockerRegistryDto.fromDockerRegistry(dockerRegistry)\n  }\n\n  @Get()\n  @ApiOperation({\n    summary: 'List registries',\n    operationId: 'listRegistries',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of all docker registries',\n    type: [DockerRegistryDto],\n  })\n  async findAll(@AuthContext() authContext: OrganizationAuthContext): Promise<DockerRegistryDto[]> {\n    const dockerRegistries = await this.dockerRegistryService.findAll(\n      authContext.organizationId,\n      // only include registries manually created by the organization\n      RegistryType.ORGANIZATION,\n    )\n    return dockerRegistries.map(DockerRegistryDto.fromDockerRegistry)\n  }\n\n  @Get('registry-push-access')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Get temporary registry access for pushing snapshots',\n    operationId: 'getTransientPushAccess',\n  })\n  @ApiQuery({\n    name: 'regionId',\n    required: false,\n    description: 'ID of the region where the snapshot will be available (defaults to organization default region)',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Temporary registry access has been generated',\n    type: RegistryPushAccessDto,\n  })\n  async getTransientPushAccess(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Query('regionId') regionId?: string,\n  ): Promise<RegistryPushAccessDto> {\n    return this.dockerRegistryService.getRegistryPushAccess(authContext.organizationId, authContext.userId, regionId)\n  }\n\n  @Get(':id')\n  @ApiOperation({\n    summary: 'Get registry',\n    operationId: 'getRegistry',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'ID of the docker registry',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The docker registry',\n    type: DockerRegistryDto,\n  })\n  @UseGuards(DockerRegistryAccessGuard)\n  async findOne(@DockerRegistry() registry: DockerRegistryEntity): Promise<DockerRegistryDto> {\n    return DockerRegistryDto.fromDockerRegistry(registry)\n  }\n\n  @Patch(':id')\n  @ApiOperation({\n    summary: 'Update registry',\n    operationId: 'updateRegistry',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'ID of the docker registry',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The docker registry has been successfully updated.',\n    type: DockerRegistryDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_REGISTRIES])\n  @UseGuards(DockerRegistryAccessGuard)\n  @Audit({\n    action: AuditAction.UPDATE,\n    targetType: AuditTarget.DOCKER_REGISTRY,\n    targetIdFromRequest: (req) => req.params.id,\n    requestMetadata: {\n      body: (req: TypedRequest<UpdateDockerRegistryDto>) => ({\n        name: req.body?.name,\n        url: req.body?.url,\n        username: req.body?.username,\n        password: req.body?.password ? MASKED_AUDIT_VALUE : undefined,\n        project: req.body?.project,\n      }),\n    },\n  })\n  async update(\n    @Param('id') registryId: string,\n    @Body() updateDockerRegistryDto: UpdateDockerRegistryDto,\n  ): Promise<DockerRegistryDto> {\n    const dockerRegistry = await this.dockerRegistryService.update(registryId, updateDockerRegistryDto)\n    return DockerRegistryDto.fromDockerRegistry(dockerRegistry)\n  }\n\n  @Delete(':id')\n  @ApiOperation({\n    summary: 'Delete registry',\n    operationId: 'deleteRegistry',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'ID of the docker registry',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'The docker registry has been successfully deleted.',\n  })\n  @HttpCode(204)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.DELETE_REGISTRIES])\n  @UseGuards(DockerRegistryAccessGuard)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.DOCKER_REGISTRY,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  async remove(@Param('id') registryId: string): Promise<void> {\n    return this.dockerRegistryService.remove(registryId)\n  }\n\n  @Post(':id/set-default')\n  @ApiOperation({\n    summary: 'Set default registry',\n    operationId: 'setDefaultRegistry',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'ID of the docker registry',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The docker registry has been set as default.',\n    type: DockerRegistryDto,\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @UseGuards(DockerRegistryAccessGuard)\n  @Audit({\n    action: AuditAction.SET_DEFAULT,\n    targetType: AuditTarget.DOCKER_REGISTRY,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  async setDefault(@Param('id') registryId: string): Promise<DockerRegistryDto> {\n    const dockerRegistry = await this.dockerRegistryService.setDefault(registryId)\n    return DockerRegistryDto.fromDockerRegistry(dockerRegistry)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/decorators/docker-registry.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { createParamDecorator, ExecutionContext } from '@nestjs/common'\n\nexport const DockerRegistry = createParamDecorator((data: unknown, ctx: ExecutionContext) => {\n  const request = ctx.switchToHttp().getRequest()\n  return request.dockerRegistry\n})\n"
  },
  {
    "path": "apps/api/src/docker-registry/docker-registry.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { DockerRegistry } from './entities/docker-registry.entity'\nimport { DockerRegistryService } from './services/docker-registry.service'\nimport { DockerRegistryController } from './controllers/docker-registry.controller'\nimport { HttpModule } from '@nestjs/axios'\nimport { DockerRegistryProvider } from './providers/docker-registry.provider'\nimport { DOCKER_REGISTRY_PROVIDER } from './providers/docker-registry.provider.interface'\nimport { OrganizationModule } from '../organization/organization.module'\nimport { RegionModule } from '../region/region.module'\n\n@Module({\n  imports: [OrganizationModule, RegionModule, TypeOrmModule.forFeature([DockerRegistry]), HttpModule],\n  controllers: [DockerRegistryController],\n  providers: [\n    {\n      provide: DOCKER_REGISTRY_PROVIDER,\n      useClass: DockerRegistryProvider,\n    },\n    DockerRegistryService,\n  ],\n  exports: [DockerRegistryService],\n})\nexport class DockerRegistryModule {}\n"
  },
  {
    "path": "apps/api/src/docker-registry/dto/create-docker-registry-internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { RegistryType } from '../enums/registry-type.enum'\n\nexport class CreateDockerRegistryInternalDto {\n  name: string\n  url: string\n  username: string\n  password: string\n  project?: string\n  registryType: RegistryType\n  isDefault?: boolean\n  regionId?: string | null\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/dto/create-docker-registry.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsString, IsUrl, IsEnum, IsOptional, IsBoolean } from 'class-validator'\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { RegistryType } from './../../docker-registry/enums/registry-type.enum'\n\n@ApiSchema({ name: 'CreateDockerRegistry' })\nexport class CreateDockerRegistryDto {\n  @ApiProperty({ description: 'Registry name' })\n  @IsString()\n  name: string\n\n  @ApiProperty({ description: 'Registry URL' })\n  @IsUrl()\n  url: string\n\n  @ApiProperty({ description: 'Registry username' })\n  @IsString()\n  username: string\n\n  @ApiProperty({ description: 'Registry password' })\n  @IsString()\n  password: string\n\n  @ApiPropertyOptional({ description: 'Registry project' })\n  @IsString()\n  @IsOptional()\n  project?: string\n\n  @ApiProperty({\n    description: 'Registry type',\n    enum: RegistryType,\n    default: RegistryType.ORGANIZATION,\n  })\n  @IsEnum(RegistryType)\n  registryType: RegistryType\n\n  @ApiPropertyOptional({ description: 'Set as default registry' })\n  @IsBoolean()\n  @IsOptional()\n  isDefault?: boolean\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/dto/docker-registry.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { RegistryType } from './../../docker-registry/enums/registry-type.enum'\nimport { DockerRegistry } from '../entities/docker-registry.entity'\n\n@ApiSchema({ name: 'DockerRegistry' })\nexport class DockerRegistryDto {\n  @ApiProperty({\n    description: 'Registry ID',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Registry name',\n    example: 'My Docker Hub',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Registry URL',\n    example: 'https://registry.hub.docker.com',\n  })\n  url: string\n\n  @ApiProperty({\n    description: 'Registry username',\n    example: 'username',\n  })\n  username: string\n\n  @ApiProperty({\n    description: 'Registry project',\n    example: 'my-project',\n  })\n  project: string\n\n  @ApiProperty({\n    description: 'Registry type',\n    enum: RegistryType,\n    example: RegistryType.INTERNAL,\n  })\n  registryType: RegistryType\n\n  @ApiProperty({\n    description: 'Creation timestamp',\n    example: '2024-01-31T12:00:00Z',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'Last update timestamp',\n    example: '2024-01-31T12:00:00Z',\n  })\n  updatedAt: Date\n\n  static fromDockerRegistry(dockerRegistry: DockerRegistry): DockerRegistryDto {\n    const dto: DockerRegistryDto = {\n      id: dockerRegistry.id,\n      name: dockerRegistry.name,\n      url: dockerRegistry.url,\n      username: dockerRegistry.username,\n      project: dockerRegistry.project,\n      registryType: dockerRegistry.registryType,\n      createdAt: dockerRegistry.createdAt,\n      updatedAt: dockerRegistry.updatedAt,\n    }\n\n    return dto\n  }\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/dto/update-docker-registry.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsString, IsOptional, IsUrl } from 'class-validator'\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'UpdateDockerRegistry' })\nexport class UpdateDockerRegistryDto {\n  @ApiProperty({ description: 'Registry name' })\n  @IsString()\n  name: string\n\n  @ApiProperty({ description: 'Registry URL' })\n  @IsUrl()\n  url: string\n\n  @ApiProperty({ description: 'Registry username' })\n  @IsString()\n  username: string\n\n  @ApiPropertyOptional({ description: 'Registry password' })\n  @IsString()\n  @IsOptional()\n  password?: string\n\n  @ApiPropertyOptional({ description: 'Registry project' })\n  @IsString()\n  @IsOptional()\n  project?: string\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/entities/docker-registry.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { RegistryType } from './../../docker-registry/enums/registry-type.enum'\nimport { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'\n\n@Entity()\n@Index(['organizationId', 'registryType'])\n@Index(['region', 'registryType'])\n@Index(['registryType', 'isDefault'])\nexport class DockerRegistry {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column()\n  name: string\n\n  @Column()\n  url: string\n\n  @Column()\n  username: string\n\n  @Column()\n  password: string\n\n  @Column({ default: false })\n  isDefault: boolean\n\n  @Column({ default: false })\n  isFallback: boolean\n\n  @Column({ default: '' })\n  project: string\n\n  @Column({ nullable: true, type: 'uuid' })\n  organizationId?: string\n\n  @Column({ nullable: true })\n  region: string | null\n\n  @Column({\n    type: 'enum',\n    enum: RegistryType,\n    default: RegistryType.INTERNAL,\n  })\n  registryType: RegistryType\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/enums/registry-type.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum RegistryType {\n  INTERNAL = 'internal', // Used for internal snapshots\n  ORGANIZATION = 'organization',\n  TRANSIENT = 'transient',\n  BACKUP = 'backup',\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/guards/docker-registry-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, CanActivate, ExecutionContext, NotFoundException, ForbiddenException } from '@nestjs/common'\nimport { DockerRegistryService } from '../services/docker-registry.service'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { RegistryType } from '../enums/registry-type.enum'\n\n@Injectable()\nexport class DockerRegistryAccessGuard implements CanActivate {\n  constructor(private readonly dockerRegistryService: DockerRegistryService) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    const dockerRegistryId: string = request.params.dockerRegistryId || request.params.registryId || request.params.id\n\n    // TODO: initialize authContext safely\n    const authContext: OrganizationAuthContext = request.user\n\n    try {\n      const dockerRegistry = await this.dockerRegistryService.findOneOrFail(dockerRegistryId)\n      if (authContext.role !== SystemRole.ADMIN && dockerRegistry.organizationId !== authContext.organizationId) {\n        throw new ForbiddenException('Request organization ID does not match resource organization ID')\n      }\n      if (authContext.role !== SystemRole.ADMIN && dockerRegistry.registryType !== RegistryType.ORGANIZATION) {\n        // only allow access to registries manually created by the organization\n        throw new ForbiddenException(`Requested registry is not type \"${RegistryType.ORGANIZATION}\"`)\n      }\n      request.dockerRegistry = dockerRegistry\n      return true\n    } catch (error) {\n      throw new NotFoundException(`Docker registry with ID ${dockerRegistryId} not found`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/providers/docker-registry.provider.interface.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const DOCKER_REGISTRY_PROVIDER = 'DOCKER_REGISTRY_PROVIDER'\n\nexport interface IDockerRegistryProvider {\n  createRobotAccount(\n    url: string,\n    auth: { username: string; password: string },\n    robotConfig: {\n      name: string\n      description: string\n      duration: number\n      level: string\n      permissions: Array<{\n        kind: string\n        namespace: string\n        access: Array<{ resource: string; action: string }>\n      }>\n    },\n  ): Promise<{ name: string; secret: string }>\n\n  deleteArtifact(\n    baseUrl: string,\n    auth: { username: string; password: string },\n    params: { project: string; repository: string; tag: string },\n  ): Promise<void>\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/providers/docker-registry.provider.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable } from '@nestjs/common'\nimport { HttpService } from '@nestjs/axios'\nimport { firstValueFrom } from 'rxjs'\nimport { IDockerRegistryProvider } from './docker-registry.provider.interface'\n\n@Injectable()\nexport class DockerRegistryProvider implements IDockerRegistryProvider {\n  constructor(private readonly httpService: HttpService) {}\n\n  async createRobotAccount(\n    url: string,\n    auth: { username: string; password: string },\n    robotConfig: {\n      name: string\n      description: string\n      duration: number\n      level: string\n      permissions: Array<{\n        kind: string\n        namespace: string\n        access: Array<{ resource: string; action: string }>\n      }>\n    },\n  ): Promise<{ name: string; secret: string }> {\n    const response = await firstValueFrom(this.httpService.post(url, robotConfig, { auth }))\n    return {\n      name: response.data.name,\n      secret: response.data.secret,\n    }\n  }\n\n  async deleteArtifact(\n    baseUrl: string,\n    auth: { username: string; password: string },\n    params: { project: string; repository: string; tag: string },\n  ): Promise<void> {\n    const url = `${baseUrl}/api/v2.0/projects/${params.project}/repositories/${params.repository}/artifacts/${params.tag}`\n\n    try {\n      await firstValueFrom(this.httpService.delete(url, { auth }))\n    } catch (error) {\n      if (error.response?.status === 404) {\n        return // Artifact not found, consider it a success\n      }\n      throw error\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/providers/mock-docker-registry.provider.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IDockerRegistryProvider } from './docker-registry.provider.interface'\n\nexport class MockDockerRegistryProvider implements IDockerRegistryProvider {\n  async createRobotAccount(): Promise<{ name: string; secret: string }> {\n    return {\n      name: 'mock-robot',\n      secret: 'mock-secret',\n    }\n  }\n\n  async deleteArtifact(): Promise<void> {\n    return Promise.resolve()\n  }\n}\n"
  },
  {
    "path": "apps/api/src/docker-registry/services/docker-registry.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ForbiddenException, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { EntityManager, FindOptionsWhere, IsNull, Repository } from 'typeorm'\nimport { DockerRegistry } from '../entities/docker-registry.entity'\nimport { CreateDockerRegistryInternalDto } from '../dto/create-docker-registry-internal.dto'\nimport { UpdateDockerRegistryDto } from '../dto/update-docker-registry.dto'\nimport { ApiOAuth2 } from '@nestjs/swagger'\nimport { RegistryPushAccessDto } from '../../sandbox/dto/registry-push-access-dto'\nimport {\n  DOCKER_REGISTRY_PROVIDER,\n  IDockerRegistryProvider,\n} from './../../docker-registry/providers/docker-registry.provider.interface'\nimport { RegistryType } from './../../docker-registry/enums/registry-type.enum'\nimport { parseDockerImage, checkDockerfileHasRegistryPrefix } from '../../common/utils/docker-image.util'\nimport axios from 'axios'\nimport { OnAsyncEvent } from '../../common/decorators/on-async-event.decorator'\nimport { RegionEvents } from '../../region/constants/region-events.constant'\nimport { RegionCreatedEvent } from '../../region/events/region-created.event'\nimport { RegionDeletedEvent } from '../../region/events/region-deleted.event'\nimport { RegionService } from '../../region/services/region.service'\nimport {\n  RegionSnapshotManagerCredsRegeneratedEvent,\n  RegionSnapshotManagerUpdatedEvent,\n} from '../../region/events/region-snapshot-manager-creds.event'\n\nconst AXIOS_TIMEOUT_MS = 3000\nconst DOCKER_HUB_REGISTRY = 'registry-1.docker.io'\nconst DOCKER_HUB_URL = 'docker.io'\n\n/**\n * Normalizes Docker Hub URLs to 'docker.io' for storage.\n * Empty URLs are assumed to be Docker Hub.\n */\nfunction normalizeRegistryUrl(url: string): string {\n  if (!url || url.trim() === '' || url.toLowerCase().includes('docker.io')) {\n    return DOCKER_HUB_URL\n  }\n  // Strip trailing slashes for consistent matching\n  return url.trim().replace(/\\/+$/, '')\n}\n\nexport interface ImageDetails {\n  digest: string\n  sizeGB: number\n  entrypoint: string[]\n  cmd: string[]\n  env: string[]\n  workingDir?: string\n  user?: string\n}\n\n@Injectable()\n@ApiOAuth2(['openid', 'profile', 'email'])\nexport class DockerRegistryService {\n  private readonly logger = new Logger(DockerRegistryService.name)\n\n  constructor(\n    @InjectRepository(DockerRegistry)\n    private readonly dockerRegistryRepository: Repository<DockerRegistry>,\n    @Inject(DOCKER_REGISTRY_PROVIDER)\n    private readonly dockerRegistryProvider: IDockerRegistryProvider,\n    private readonly regionService: RegionService,\n  ) {}\n\n  async create(\n    createDto: CreateDockerRegistryInternalDto,\n    organizationId?: string,\n    isFallback = false,\n    entityManager?: EntityManager,\n  ): Promise<DockerRegistry> {\n    const repository = entityManager ? entityManager.getRepository(DockerRegistry) : this.dockerRegistryRepository\n\n    //  set some limit to the number of registries\n    if (organizationId) {\n      const registries = await repository.find({\n        where: { organizationId },\n      })\n      if (registries.length >= 100) {\n        throw new ForbiddenException('You have reached the maximum number of registries')\n      }\n    }\n\n    const registry = repository.create({\n      ...createDto,\n      url: normalizeRegistryUrl(createDto.url),\n      region: createDto.regionId,\n      organizationId,\n      isFallback,\n    })\n    return repository.save(registry)\n  }\n\n  async findAll(organizationId: string, registryType: RegistryType): Promise<DockerRegistry[]> {\n    return this.dockerRegistryRepository.find({\n      where: { organizationId, registryType },\n      order: {\n        createdAt: 'DESC',\n      },\n    })\n  }\n\n  async findOne(registryId: string): Promise<DockerRegistry | null> {\n    return this.dockerRegistryRepository.findOne({\n      where: { id: registryId },\n    })\n  }\n\n  async findOneOrFail(registryId: string): Promise<DockerRegistry> {\n    return this.dockerRegistryRepository.findOneOrFail({\n      where: { id: registryId },\n    })\n  }\n\n  async update(registryId: string, updateDto: UpdateDockerRegistryDto): Promise<DockerRegistry> {\n    const registry = await this.dockerRegistryRepository.findOne({\n      where: { id: registryId },\n    })\n\n    if (!registry) {\n      throw new NotFoundException(`Docker registry with ID ${registryId} not found`)\n    }\n\n    registry.name = updateDto.name\n    registry.url = normalizeRegistryUrl(updateDto.url)\n    registry.username = updateDto.username\n    if (updateDto.password) {\n      registry.password = updateDto.password\n    }\n    registry.project = updateDto.project\n\n    return this.dockerRegistryRepository.save(registry)\n  }\n\n  async remove(registryId: string): Promise<void> {\n    const registry = await this.dockerRegistryRepository.findOne({\n      where: { id: registryId },\n    })\n\n    if (!registry) {\n      throw new NotFoundException(`Docker registry with ID ${registryId} not found`)\n    }\n\n    await this.dockerRegistryRepository.remove(registry)\n  }\n\n  async setDefault(registryId: string): Promise<DockerRegistry> {\n    const registry = await this.dockerRegistryRepository.findOne({\n      where: { id: registryId },\n    })\n\n    if (!registry) {\n      throw new NotFoundException(`Docker registry with ID ${registryId} not found`)\n    }\n\n    await this.unsetDefaultRegistry()\n\n    registry.isDefault = true\n    return this.dockerRegistryRepository.save(registry)\n  }\n\n  private async unsetDefaultRegistry(): Promise<void> {\n    await this.dockerRegistryRepository.update({ isDefault: true }, { isDefault: false })\n  }\n\n  /**\n   * Returns an available internal registry for storing snapshots.\n   *\n   * If a snapshot manager _is_ configured for the region identified by the provided _regionId_, only an internal registry that matches the region snapshot manager can be returned.\n   * If no matching internal registry is found, _null_ will be returned.\n   *\n   * If a snapshot manager _is not_ configured for the provided region, the default internal registry will be returned (if available).\n   * If no default internal registry is found, _null_ will be returned.\n   *\n   * @param regionId - The ID of the region.\n   */\n  async getAvailableInternalRegistry(regionId: string): Promise<DockerRegistry | null> {\n    const region = await this.regionService.findOne(regionId)\n    if (!region) {\n      return null\n    }\n\n    if (region.snapshotManagerUrl) {\n      return this.dockerRegistryRepository.findOne({\n        where: { region: regionId, registryType: RegistryType.INTERNAL },\n      })\n    }\n\n    return this.dockerRegistryRepository.findOne({\n      where: { isDefault: true, registryType: RegistryType.INTERNAL },\n    })\n  }\n\n  /**\n   * Returns an available transient registry for pushing snapshots.\n   *\n   * If a snapshot manager _is_ configured for the region identified by the provided _regionId_, only a transient registry that matches the region snapshot manager can be returned.\n   * If no matching transient registry is found, _null_ will be returned.\n   *\n   * If a snapshot manager _is not_ configured for the provided region or no region is provided, the default transient registry will be returned (if available).\n   * If no default transient registry is found, _null_ will be returned.\n   *\n   * @param regionId - (Optional) The ID of the region.\n   */\n  async getAvailableTransientRegistry(regionId?: string): Promise<DockerRegistry | null> {\n    if (regionId) {\n      const region = await this.regionService.findOne(regionId)\n      if (!region) {\n        return null\n      }\n\n      if (region.snapshotManagerUrl) {\n        return this.dockerRegistryRepository.findOne({\n          where: { region: regionId, registryType: RegistryType.TRANSIENT },\n        })\n      }\n    }\n\n    return this.dockerRegistryRepository.findOne({\n      where: { isDefault: true, registryType: RegistryType.TRANSIENT },\n    })\n  }\n\n  async getDefaultDockerHubRegistry(): Promise<DockerRegistry | null> {\n    return this.dockerRegistryRepository.findOne({\n      where: {\n        organizationId: IsNull(),\n        registryType: RegistryType.INTERNAL,\n        url: DOCKER_HUB_URL,\n        project: '',\n      },\n    })\n  }\n\n  /**\n   * Returns an available backup registry for storing snapshots.\n   *\n   * If a snapshot manager _is_ configured for the region identified by the provided _preferredRegionId_, only a backup registry that matches the region snapshot manager can be returned.\n   * If no matching backup registry is found, _null_ will be returned.\n   *\n   * If a snapshot manager _is not_ configured for the provided region, a backup registry in the preferred region will be returned (if available).\n   * If no backup registry is found in the preferred region, a fallback backup registry will be returned (if available).\n   * If no fallback backup registry is found, _null_ will be returned.\n   *\n   * @param preferredRegionId - The ID of the preferred region.\n   */\n  async getAvailableBackupRegistry(preferredRegionId: string): Promise<DockerRegistry | null> {\n    const region = await this.regionService.findOne(preferredRegionId)\n    if (!region) {\n      return null\n    }\n\n    if (region.snapshotManagerUrl) {\n      return this.dockerRegistryRepository.findOne({\n        where: { region: preferredRegionId, registryType: RegistryType.BACKUP },\n      })\n    }\n\n    const registries = await this.dockerRegistryRepository.find({\n      where: { registryType: RegistryType.BACKUP, isDefault: true },\n    })\n\n    if (registries.length === 0) {\n      return null\n    }\n\n    // Filter registries by preferred region\n    const preferredRegionRegistries = registries.filter((registry) => registry.region === preferredRegionId)\n\n    // If we have registries in the preferred region, randomly select one\n    if (preferredRegionRegistries.length > 0) {\n      const randomIndex = Math.floor(Math.random() * preferredRegionRegistries.length)\n      return preferredRegionRegistries[randomIndex]\n    }\n\n    // If no registry found in preferred region, try to find a fallback registry\n    const fallbackRegistries = registries.filter((registry) => registry.isFallback === true)\n\n    if (fallbackRegistries.length > 0) {\n      const randomIndex = Math.floor(Math.random() * fallbackRegistries.length)\n      return fallbackRegistries[randomIndex]\n    }\n\n    // If no fallback registry found either, throw an error\n    throw new Error('No backup registry available')\n  }\n\n  /**\n   * Returns an internal registry that matches the snapshot ref.\n   *\n   * If no matching internal registry is found, _null_ will be returned.\n   *\n   * @param ref - The snapshot ref.\n   * @param regionId - The ID of the region which needs access to the internal registry.\n   */\n  async findInternalRegistryBySnapshotRef(ref: string, regionId: string): Promise<DockerRegistry | null> {\n    const region = await this.regionService.findOne(regionId)\n    if (!region) {\n      return null\n    }\n\n    let registries: DockerRegistry[]\n\n    if (region.snapshotManagerUrl) {\n      registries = await this.dockerRegistryRepository.find({\n        where: {\n          region: regionId,\n          registryType: RegistryType.INTERNAL,\n        },\n      })\n    } else {\n      registries = await this.dockerRegistryRepository.find({\n        where: {\n          organizationId: IsNull(),\n          registryType: RegistryType.INTERNAL,\n        },\n      })\n    }\n\n    return this.findRegistryByUrlMatch(registries, ref)\n  }\n\n  /**\n   * Returns a source registry that matches the snapshot image name and can be used to pull the image.\n   *\n   * If no matching source registry is found, _null_ will be returned.\n   *\n   * @param imageName - The user-provided image.\n   * @param regionId - The ID of the region which needs access to the source registry.\n   */\n  async findSourceRegistryBySnapshotImageName(\n    imageName: string,\n    regionId: string,\n    organizationId?: string,\n  ): Promise<DockerRegistry | null> {\n    const region = await this.regionService.findOne(regionId)\n    if (!region) {\n      return null\n    }\n\n    const whereCondition: FindOptionsWhere<DockerRegistry>[] = []\n\n    if (region.organizationId) {\n      // registries manually added by the organization\n      whereCondition.push({\n        organizationId: region.organizationId,\n        registryType: RegistryType.ORGANIZATION,\n      })\n    }\n\n    if (organizationId) {\n      whereCondition.push({\n        organizationId: organizationId,\n        registryType: RegistryType.ORGANIZATION,\n      })\n    }\n\n    if (region.snapshotManagerUrl) {\n      // internal registry associated with region snapshot manager\n      whereCondition.push({\n        region: regionId,\n        registryType: RegistryType.INTERNAL,\n      })\n    } else {\n      // shared internal registries\n      whereCondition.push({\n        organizationId: IsNull(),\n        registryType: RegistryType.INTERNAL,\n      })\n    }\n\n    const registries = await this.dockerRegistryRepository.find({\n      where: whereCondition,\n    })\n\n    // Prioritize ORGANIZATION registries over others\n    // This ensures user-configured credentials take precedence over shared internal ones\n    const priority: Partial<Record<RegistryType, number>> = {\n      [RegistryType.ORGANIZATION]: 0,\n    }\n    const sortedRegistries = [...registries].sort(\n      (a, b) => (priority[a.registryType] ?? 1) - (priority[b.registryType] ?? 1),\n    )\n\n    return this.findRegistryByUrlMatch(sortedRegistries, imageName)\n  }\n\n  /**\n   * Returns a transient registry that matches the snapshot image name.\n   *\n   * If no matching transient registry is found, _null_ will be returned.\n   *\n   * @param imageName - The user-provided image.\n   * @param regionId - The ID of the region which needs access to the transient registry.\n   */\n  async findTransientRegistryBySnapshotImageName(imageName: string, regionId: string): Promise<DockerRegistry | null> {\n    const region = await this.regionService.findOne(regionId)\n    if (!region) {\n      return null\n    }\n\n    let registries: DockerRegistry[]\n\n    if (region.snapshotManagerUrl) {\n      registries = await this.dockerRegistryRepository.find({\n        where: {\n          region: regionId,\n          registryType: RegistryType.TRANSIENT,\n        },\n      })\n    } else {\n      registries = await this.dockerRegistryRepository.find({\n        where: {\n          organizationId: IsNull(),\n          registryType: RegistryType.TRANSIENT,\n        },\n      })\n    }\n\n    return this.findRegistryByUrlMatch(registries, imageName)\n  }\n\n  async getRegistryPushAccess(\n    organizationId: string,\n    userId: string,\n    regionId?: string,\n  ): Promise<RegistryPushAccessDto> {\n    const transientRegistry = await this.getAvailableTransientRegistry(regionId)\n    if (!transientRegistry) {\n      throw new Error('No default transient registry configured')\n    }\n\n    const uniqueId = crypto.randomUUID().replace(/-/g, '').slice(0, 12)\n    const robotName = `temp-push-robot-${uniqueId}`\n    const expiresAt = new Date()\n    expiresAt.setHours(expiresAt.getHours() + 1) // Token valid for 1 hour\n\n    const url = this.getRegistryUrl(transientRegistry) + '/api/v2.0/robots'\n\n    try {\n      const response = await this.dockerRegistryProvider.createRobotAccount(\n        url,\n        {\n          username: transientRegistry.username,\n          password: transientRegistry.password,\n        },\n        {\n          name: robotName,\n          description: `Temporary push access for user ${userId} in organization ${organizationId}`,\n          duration: 3600,\n          level: 'project',\n          permissions: [\n            {\n              kind: 'project',\n              namespace: transientRegistry.project,\n              access: [{ resource: 'repository', action: 'push' }],\n            },\n          ],\n        },\n      )\n\n      return {\n        username: response.name,\n        secret: response.secret,\n        registryId: transientRegistry.id,\n        registryUrl: new URL(url).host,\n        project: transientRegistry.project,\n        expiresAt: expiresAt.toISOString(),\n      }\n    } catch (error) {\n      let errorMessage = `Failed to generate push token: ${error.message}`\n      if (error.response) {\n        errorMessage += ` - ${error.response.data.message || error.response.statusText}`\n      }\n      throw new Error(errorMessage)\n    }\n  }\n\n  async removeImage(imageName: string, registryId: string): Promise<void> {\n    const registry = await this.findOne(registryId)\n    if (!registry) {\n      throw new Error('Registry not found')\n    }\n\n    const parsedImage = parseDockerImage(imageName)\n    if (!parsedImage.project) {\n      throw new Error('Invalid image name format. Expected: [registry]/project/repository[:tag]')\n    }\n\n    try {\n      await this.dockerRegistryProvider.deleteArtifact(\n        this.getRegistryUrl(registry),\n        {\n          username: registry.username,\n          password: registry.password,\n        },\n        {\n          project: parsedImage.project,\n          repository: parsedImage.repository,\n          tag: parsedImage.tag,\n        },\n      )\n    } catch (error) {\n      const message = error.response?.data?.message || error.message\n      throw new Error(`Failed to remove image ${imageName}: ${message}`)\n    }\n  }\n\n  getRegistryUrl(registry: DockerRegistry): string {\n    // Dev mode\n    if (registry.url.startsWith('localhost:') || registry.url.startsWith('registry:')) {\n      return `http://${registry.url}`\n    }\n\n    if (registry.url.startsWith('localhost') || registry.url.startsWith('127.0.0.1')) {\n      return `http://${registry.url}`\n    }\n\n    return registry.url.startsWith('http') ? registry.url : `https://${registry.url}`\n  }\n\n  public async findRegistryByImageName(\n    imageName: string,\n    regionId: string,\n    organizationId?: string,\n  ): Promise<DockerRegistry | null> {\n    // Parse the image to extract potential registry hostname\n    const parsedImage = parseDockerImage(imageName)\n\n    if (parsedImage.registry) {\n      // Image has registry prefix, try to find matching registry in database first\n      const registry = await this.findSourceRegistryBySnapshotImageName(imageName, regionId, organizationId)\n      if (registry) {\n        return registry\n      }\n      // Not found in database, create temporary registry config for public access\n      return this.createTemporaryRegistryConfig(parsedImage.registry)\n    } else {\n      // Image has no registry prefix (e.g., \"alpine:3.21\")\n      // Create temporary Docker Hub config\n      return this.createTemporaryRegistryConfig('docker.io')\n    }\n  }\n\n  /**\n   * Finds a registry with a URL that matches the start of the target string.\n   *\n   * @param registries - The list of registries to search.\n   * @param targetString - The string to match against registry URLs.\n   * @returns The matching registry, or null if no match is found.\n   */\n  private findRegistryByUrlMatch(registries: DockerRegistry[], targetString: string): DockerRegistry | null {\n    for (const registry of registries) {\n      const strippedUrl = registry.url.replace(/^(https?:\\/\\/)/, '').replace(/\\/+$/, '')\n      if (targetString.startsWith(strippedUrl)) {\n        // Ensure match is at a proper boundary (followed by '/', ':', or end-of-string)\n        // to prevent \"registry.depot.dev\" from matching \"registry.depot.dev-evil.com/...\"\n        const nextChar = targetString[strippedUrl.length]\n        if (nextChar === undefined || nextChar === '/' || nextChar === ':') {\n          return registry\n        }\n      }\n    }\n    return null\n  }\n\n  private createTemporaryRegistryConfig(registryOrigin: string): DockerRegistry {\n    const registry = new DockerRegistry()\n    registry.id = `temp-${registryOrigin}`\n    registry.name = `Temporary ${registryOrigin}`\n    registryOrigin = registryOrigin.replace(/^(https?:\\/\\/)/, '')\n    registry.url = `https://${registryOrigin}`\n    registry.username = ''\n    registry.password = ''\n    registry.project = ''\n    registry.isDefault = false\n    registry.registryType = RegistryType.INTERNAL\n    return registry\n  }\n\n  private async getDockerHubToken(repository: string): Promise<string | null> {\n    try {\n      const tokenUrl = `https://auth.docker.io/token?service=${DOCKER_HUB_REGISTRY}&scope=repository:${repository}:pull`\n      const response = await axios.get(tokenUrl, { timeout: 10000 })\n      return response.data.token\n    } catch (error) {\n      this.logger.warn(`Failed to get Docker Hub token: ${error.message}`)\n      return null\n    }\n  }\n\n  private async deleteRepositoryWithPrefix(\n    repository: string,\n    prefix: string,\n    registry: DockerRegistry,\n  ): Promise<void> {\n    const registryUrl = this.getRegistryUrl(registry)\n    const encodedCredentials = Buffer.from(`${registry.username}:${registry.password}`).toString('base64')\n    const repoPath = `${registry.project}/${prefix}${repository}`\n\n    try {\n      // Step 1: List all tags in the repository\n      const tagsUrl = `${registryUrl}/v2/${repoPath}/tags/list`\n\n      const tagsResponse = await axios({\n        method: 'get',\n        url: tagsUrl,\n        headers: {\n          Authorization: `Basic ${encodedCredentials}`,\n        },\n        validateStatus: (status) => status < 500,\n        timeout: AXIOS_TIMEOUT_MS,\n      })\n\n      if (tagsResponse.status === 404) {\n        return\n      }\n\n      if (tagsResponse.status >= 300) {\n        this.logger.error(`Error listing tags in repository ${repoPath}: ${tagsResponse.statusText}`)\n        throw new Error(`Failed to list tags in repository ${repoPath}: ${tagsResponse.statusText}`)\n      }\n\n      const tags = tagsResponse.data.tags || []\n\n      if (tags.length === 0) {\n        this.logger.debug(`Repository ${repoPath} has no tags to delete`)\n        return\n      }\n\n      if (tags.length > 500) {\n        this.logger.warn(`Repository ${repoPath} has more than 500 tags, skipping cleanup`)\n        return\n      }\n\n      // Step 2: Delete each tag\n      for (const tag of tags) {\n        try {\n          // Get the digest for this tag\n          const manifestUrl = `${registryUrl}/v2/${repoPath}/manifests/${tag}`\n\n          const manifestResponse = await axios({\n            method: 'head',\n            url: manifestUrl,\n            headers: {\n              Authorization: `Basic ${encodedCredentials}`,\n              Accept: 'application/vnd.docker.distribution.manifest.v2+json',\n            },\n            validateStatus: (status) => status < 500,\n            timeout: AXIOS_TIMEOUT_MS,\n          })\n\n          if (manifestResponse.status >= 300) {\n            this.logger.warn(`Couldn't get manifest for tag ${tag}: ${manifestResponse.statusText}`)\n            continue\n          }\n\n          const digest = manifestResponse.headers['docker-content-digest']\n          if (!digest) {\n            this.logger.warn(`Docker content digest not found for tag ${tag}`)\n            continue\n          }\n\n          // Delete the manifest\n          const deleteUrl = `${registryUrl}/v2/${repoPath}/manifests/${digest}`\n\n          const deleteResponse = await axios({\n            method: 'delete',\n            url: deleteUrl,\n            headers: {\n              Authorization: `Basic ${encodedCredentials}`,\n            },\n            validateStatus: (status) => status < 500,\n            timeout: AXIOS_TIMEOUT_MS,\n          })\n\n          if (deleteResponse.status < 300) {\n            this.logger.debug(`Deleted tag ${tag} from repository ${repoPath}`)\n          } else {\n            this.logger.warn(`Failed to delete tag ${tag}: ${deleteResponse.statusText}`)\n          }\n        } catch (error) {\n          this.logger.warn(`Exception when deleting tag ${tag}: ${error.message}`)\n          // Continue with other tags\n        }\n      }\n\n      this.logger.debug(`Repository ${repoPath} cleanup completed`)\n    } catch (error) {\n      this.logger.error(`Exception when deleting repository ${repoPath}: ${error.message}`)\n      throw error\n    }\n  }\n\n  async deleteSandboxRepository(repository: string, registry: DockerRegistry): Promise<void> {\n    try {\n      // Delete both backup and snapshot repositories - necessary due to renaming\n      await this.deleteRepositoryWithPrefix(repository, 'backup-', registry)\n      await this.deleteRepositoryWithPrefix(repository, 'snapshot-', registry)\n    } catch (error) {\n      this.logger.error(`Failed to delete repositories for ${repository}: ${error.message}`)\n      throw error\n    }\n  }\n\n  async deleteBackupImageFromRegistry(imageName: string, registry: DockerRegistry): Promise<void> {\n    const parsedImage = parseDockerImage(imageName)\n    if (!parsedImage.project || !parsedImage.tag) {\n      throw new Error('Invalid image name format. Expected: [registry]/project/repository:tag')\n    }\n\n    const registryUrl = this.getRegistryUrl(registry)\n    const repoPath = `${parsedImage.project}/${parsedImage.repository}`\n\n    // First, get the digest for the tag using the manifests endpoint\n    const manifestUrl = `${registryUrl}/v2/${repoPath}/manifests/${parsedImage.tag}`\n    const encodedCredentials = Buffer.from(`${registry.username}:${registry.password}`).toString('base64')\n\n    try {\n      // Get the digest from the headers\n      const manifestResponse = await axios({\n        method: 'head', // Using HEAD request to only fetch headers\n        url: manifestUrl,\n        headers: {\n          Authorization: `Basic ${encodedCredentials}`,\n          Accept: 'application/vnd.docker.distribution.manifest.v2+json',\n        },\n        validateStatus: (status) => status < 500,\n        timeout: AXIOS_TIMEOUT_MS,\n      })\n\n      if (manifestResponse.status >= 300) {\n        this.logger.error(`Error getting manifest for image ${imageName}: ${manifestResponse.statusText}`)\n        throw new Error(`Failed to get manifest for image ${imageName}: ${manifestResponse.statusText}`)\n      }\n\n      // Extract the digest from headers\n      const digest = manifestResponse.headers['docker-content-digest']\n      if (!digest) {\n        throw new Error(`Docker content digest not found for image ${imageName}`)\n      }\n\n      // Now delete the image using the digest\n      const deleteUrl = `${registryUrl}/v2/${repoPath}/manifests/${digest}`\n\n      const deleteResponse = await axios({\n        method: 'delete',\n        url: deleteUrl,\n        headers: {\n          Authorization: `Basic ${encodedCredentials}`,\n        },\n        validateStatus: (status) => status < 500,\n        timeout: AXIOS_TIMEOUT_MS,\n      })\n\n      if (deleteResponse.status < 300) {\n        this.logger.debug(`Image ${imageName} removed from the registry`)\n        return\n      }\n\n      this.logger.error(`Error removing image ${imageName} from registry: ${deleteResponse.statusText}`)\n      throw new Error(`Failed to remove image ${imageName} from registry: ${deleteResponse.statusText}`)\n    } catch (error) {\n      this.logger.error(`Exception when deleting image ${imageName}: ${error.message}`)\n      throw error\n    }\n  }\n\n  /**\n   * Gets source registries for building a Docker image from a Dockerfile\n   * If the Dockerfile has images with registry prefixes, returns all user registries\n   *\n   * @param dockerfileContent - The Dockerfile content\n   * @param organizationId - The organization ID\n   * @returns Array of source registries (private registries + default Docker Hub)\n   */\n  async getSourceRegistriesForDockerfile(dockerfileContent: string, organizationId: string): Promise<DockerRegistry[]> {\n    const sourceRegistries: DockerRegistry[] = []\n\n    // Check if Dockerfile has any images with a registry prefix\n    // If so, include all user's registries (we can't reliably match specific registries)\n    if (checkDockerfileHasRegistryPrefix(dockerfileContent)) {\n      const userRegistries = await this.findAll(organizationId, RegistryType.ORGANIZATION)\n      sourceRegistries.push(...userRegistries)\n    }\n\n    // Add default Docker Hub registry only if user doesn't have their own Docker Hub credentials\n    // The auth configs map is keyed by URL, so adding the default last would override user credentials\n    const userHasDockerHubCreds = sourceRegistries.some((registry) => registry.url.includes('docker.io'))\n\n    if (!userHasDockerHubCreds) {\n      const defaultDockerHubRegistry = await this.getDefaultDockerHubRegistry()\n      if (defaultDockerHubRegistry) {\n        sourceRegistries.push(defaultDockerHubRegistry)\n      }\n    }\n\n    return sourceRegistries\n  }\n\n  @OnAsyncEvent({\n    event: RegionEvents.SNAPSHOT_MANAGER_CREDENTIALS_REGENERATED,\n  })\n  private async _handleRegionSnapshotManagerCredsRegenerated(\n    payload: RegionSnapshotManagerCredsRegeneratedEvent,\n  ): Promise<void> {\n    const { regionId, snapshotManagerUrl, username, password, entityManager } = payload\n\n    const em = entityManager ?? this.dockerRegistryRepository.manager\n\n    const registries = await em.count(DockerRegistry, {\n      where: { region: regionId, url: snapshotManagerUrl },\n    })\n\n    if (registries === 0) {\n      throw new NotFoundException(`No registries found for region ${regionId} with URL ${snapshotManagerUrl}`)\n    }\n\n    await em.update(DockerRegistry, { region: regionId, url: snapshotManagerUrl }, { username, password })\n  }\n\n  @OnAsyncEvent({\n    event: RegionEvents.SNAPSHOT_MANAGER_UPDATED,\n  })\n  private async _handleRegionSnapshotManagerUpdated(payload: RegionSnapshotManagerUpdatedEvent): Promise<void> {\n    const {\n      region,\n      organizationId,\n      snapshotManagerUrl,\n      prevSnapshotManagerUrl,\n      entityManager,\n      newUsername,\n      newPassword,\n    } = payload\n\n    const em = entityManager ?? this.dockerRegistryRepository.manager\n\n    if (prevSnapshotManagerUrl) {\n      // Update old registries associated with previous snapshot manager URL\n      if (snapshotManagerUrl) {\n        await em.update(\n          DockerRegistry,\n          {\n            region: region.id,\n            url: prevSnapshotManagerUrl,\n          },\n          {\n            url: snapshotManagerUrl,\n            username: newUsername,\n            password: newPassword,\n          },\n        )\n      } else {\n        // If snapshot manager URL is removed, delete associated registries\n        await em.delete(DockerRegistry, {\n          region: region.id,\n          url: prevSnapshotManagerUrl,\n        })\n      }\n\n      return\n    }\n\n    const registries = await em.count(DockerRegistry, {\n      where: { region: region.id, url: snapshotManagerUrl },\n    })\n\n    if (registries === 0) {\n      await this._handleRegionCreatedEvent(\n        new RegionCreatedEvent(entityManager, region, organizationId, newUsername, newPassword),\n      )\n    }\n  }\n\n  @OnAsyncEvent({\n    event: RegionEvents.CREATED,\n  })\n  private async _handleRegionCreatedEvent(payload: RegionCreatedEvent): Promise<void> {\n    const { entityManager, region, organizationId, snapshotManagerUsername, snapshotManagerPassword } = payload\n\n    if (!region.snapshotManagerUrl || !snapshotManagerUsername || !snapshotManagerPassword) {\n      return\n    }\n\n    await this.create(\n      {\n        name: `${region.name}-backup`,\n        url: region.snapshotManagerUrl,\n        username: snapshotManagerUsername,\n        password: snapshotManagerPassword,\n        registryType: RegistryType.BACKUP,\n        regionId: region.id,\n      },\n      organizationId ?? undefined,\n      false,\n      entityManager,\n    )\n\n    await this.create(\n      {\n        name: `${region.name}-internal`,\n        url: region.snapshotManagerUrl,\n        username: snapshotManagerUsername,\n        password: snapshotManagerPassword,\n        registryType: RegistryType.INTERNAL,\n        regionId: region.id,\n      },\n      organizationId ?? undefined,\n      false,\n      entityManager,\n    )\n\n    await this.create(\n      {\n        name: `${region.name}-transient`,\n        url: region.snapshotManagerUrl,\n        username: snapshotManagerUsername,\n        password: snapshotManagerPassword,\n        registryType: RegistryType.TRANSIENT,\n        regionId: region.id,\n      },\n      organizationId ?? undefined,\n      false,\n      entityManager,\n    )\n  }\n\n  @OnAsyncEvent({\n    event: RegionEvents.DELETED,\n  })\n  async handleRegionDeletedEvent(payload: RegionDeletedEvent): Promise<void> {\n    const { entityManager, region } = payload\n\n    if (!region.snapshotManagerUrl) {\n      return\n    }\n\n    const repository = entityManager.getRepository(DockerRegistry)\n    await repository.delete({ region: region.id })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/email/constants.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const EMAIL_MODULE_OPTIONS = 'EMAIL_MODULE_OPTIONS'\n"
  },
  {
    "path": "apps/api/src/email/email.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DynamicModule, Module } from '@nestjs/common'\nimport { EmailService } from './services/email.service'\nimport { EMAIL_MODULE_OPTIONS } from './constants'\n\nexport interface EmailModuleOptions {\n  host: string\n  port: number\n  user?: string\n  password?: string\n  secure?: boolean\n  from: string\n  dashboardUrl: string\n}\n\n@Module({})\nexport class EmailModule {\n  static forRoot(options: EmailModuleOptions): DynamicModule {\n    return {\n      module: EmailModule,\n      providers: [\n        {\n          provide: EMAIL_MODULE_OPTIONS,\n          useValue: options,\n        },\n        EmailService,\n      ],\n      exports: [EmailService],\n    }\n  }\n\n  static forRootAsync(options: {\n    useFactory: (...args: any[]) => Promise<EmailModuleOptions> | EmailModuleOptions\n    inject?: any[]\n  }): DynamicModule {\n    return {\n      module: EmailModule,\n      providers: [\n        {\n          provide: EMAIL_MODULE_OPTIONS,\n          useFactory: options.useFactory,\n          inject: options.inject || [],\n        },\n        EmailService,\n      ],\n      exports: [EmailService],\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/email/services/email.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Inject, Injectable, Logger } from '@nestjs/common'\nimport { renderFile } from 'ejs'\nimport { createTransport, Transporter } from 'nodemailer'\nimport path from 'path'\nimport { OnAsyncEvent } from '../../common/decorators/on-async-event.decorator'\nimport { OrganizationEvents } from '../../organization/constants/organization-events.constant'\nimport { OrganizationInvitationCreatedEvent } from '../../organization/events/organization-invitation-created.event'\nimport { EmailModuleOptions } from '../email.module'\n\n@Injectable()\nexport class EmailService {\n  private readonly transporter: Transporter | null\n  private readonly logger = new Logger(EmailService.name)\n\n  constructor(@Inject('EMAIL_MODULE_OPTIONS') private readonly options: EmailModuleOptions) {\n    const { host, port, user, password, secure, from, dashboardUrl } = this.options\n\n    if (!host || !port || !from) {\n      this.logger.warn('Email configuration not found, email functionality will be disabled')\n      this.transporter = null\n      return\n    }\n\n    this.transporter = createTransport({\n      host,\n      port,\n      auth: user && password ? { user, pass: password } : undefined,\n      secure,\n    })\n  }\n\n  @OnAsyncEvent({\n    event: OrganizationEvents.INVITATION_CREATED,\n  })\n  async handleOrganizationInvitationCreated(payload: OrganizationInvitationCreatedEvent): Promise<void> {\n    if (!this.transporter) {\n      this.logger.warn('Failed to send organization invitation email, email configuration not found')\n      return\n    }\n\n    try {\n      await this.transporter.sendMail({\n        from: this.options.from,\n        to: payload.inviteeEmail,\n        subject: 'Invitation to join a Daytona organization',\n        html: await renderFile(path.join(__dirname, 'assets/templates/organization-invitation.template.ejs'), {\n          organizationName: payload.organizationName,\n          invitedBy: payload.invitedBy,\n          invitationLink: `${this.options.dashboardUrl}/user/invitations?id=${payload.invitationId}`,\n          expiresAt: new Date(payload.expiresAt).toLocaleDateString('en-US', {\n            year: 'numeric',\n            month: 'long',\n            day: 'numeric',\n          }),\n        }),\n      })\n    } catch (error) {\n      // TODO: resilient email sending\n      this.logger.error(`Failed to send organization invitation email to ${payload.inviteeEmail}`, error)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/encryption/encryption.module.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { EncryptionService } from './encryption.service'\n\n@Module({\n  providers: [EncryptionService],\n  exports: [EncryptionService],\n})\nexport class EncryptionModule {}\n"
  },
  {
    "path": "apps/api/src/encryption/encryption.service.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { createCipheriv, createDecipheriv, randomBytes, scrypt } from 'crypto'\nimport { promisify } from 'node:util'\nimport { TypedConfigService } from '../config/typed-config.service'\n\nexport interface EncryptedData {\n  data: string\n  iv: string\n}\n\n@Injectable()\nexport class EncryptionService {\n  private readonly algorithm = 'aes-256-ctr'\n  private readonly encoding = 'base64'\n  private readonly secret: string\n  private readonly salt: string\n  private readonly logger = new Logger(EncryptionService.name)\n\n  constructor(configService: TypedConfigService) {\n    this.logger.debug('Initializing encryption service')\n    this.secret = configService.getOrThrow('encryption.key')\n    this.salt = configService.getOrThrow('encryption.salt')\n  }\n\n  public async encrypt(input: string): Promise<string> {\n    const key = (await promisify(scrypt)(this.secret, this.salt, 32)) as Buffer\n    const iv = randomBytes(16)\n    const cipher = createCipheriv(this.algorithm, key, iv)\n\n    return this.serialize({\n      data: Buffer.concat([cipher.update(input), cipher.final()]).toString(this.encoding),\n      iv: iv.toString(this.encoding),\n    })\n  }\n\n  /**\n   * Decrypts the input string. If backwardsCompatible is true, it will return the input string\n   * as is if decryption fails (for handling unencrypted data).\n   */\n  public async decrypt(input: string, backwardsCompatible = false): Promise<string> {\n    if (backwardsCompatible) {\n      try {\n        return await this._decrypt(input)\n      } catch {\n        return input\n      }\n    }\n\n    return this._decrypt(input)\n  }\n\n  private async _decrypt(input: string): Promise<string> {\n    const encryptedData = this.deserialize(input)\n    const key = (await promisify(scrypt)(this.secret, this.salt, 32)) as Buffer\n    const encrypted = Buffer.from(encryptedData.data, this.encoding)\n    const iv = Buffer.from(encryptedData.iv, this.encoding)\n    const decipher = createDecipheriv(this.algorithm, key, iv)\n\n    const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()])\n    return decrypted.toString()\n  }\n\n  private serialize(data: EncryptedData): string {\n    return JSON.stringify(data)\n  }\n\n  private deserialize(data: string): EncryptedData {\n    return JSON.parse(data)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/exceptions/bad-request.exception.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { HttpException, HttpStatus } from '@nestjs/common'\n\nexport class BadRequestError extends HttpException {\n  constructor(message: string) {\n    super(message, HttpStatus.BAD_REQUEST)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/exceptions/forbidden-operation.exception.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { HttpException, HttpStatus } from '@nestjs/common'\n\nexport class ForbiddenOperationError extends HttpException {\n  constructor(message: string) {\n    super(message, HttpStatus.FORBIDDEN)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/exceptions/not-found.exception.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { HttpException, HttpStatus } from '@nestjs/common'\n\nexport class ResourceNotFoundError extends HttpException {\n  constructor(message: string) {\n    super(message, HttpStatus.NOT_FOUND)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/exceptions/sandbox-error.exception.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { HttpException, HttpStatus } from '@nestjs/common'\n\nexport class SandboxError extends HttpException {\n  constructor(message: string) {\n    super(message, HttpStatus.BAD_REQUEST)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/filters/all-exceptions.filter.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { join } from 'node:path'\nimport { STATUS_CODES } from 'node:http'\nimport { Request, Response } from 'express'\nimport {\n  ExceptionFilter,\n  Catch,\n  ArgumentsHost,\n  HttpException,\n  Logger,\n  HttpStatus,\n  NotFoundException,\n  UnauthorizedException,\n} from '@nestjs/common'\nimport { FailedAuthTrackerService } from '../auth/failed-auth-tracker.service'\n\n@Catch()\nexport class AllExceptionsFilter implements ExceptionFilter {\n  private readonly logger = new Logger(AllExceptionsFilter.name)\n\n  constructor(private readonly failedAuthTracker: FailedAuthTrackerService) {}\n\n  async catch(exception: unknown, host: ArgumentsHost): Promise<void> {\n    const ctx = host.switchToHttp()\n    const response = ctx.getResponse<Response>()\n    const request = ctx.getRequest<Request>()\n\n    let statusCode: number\n    let error: string\n    let message: string\n\n    // If the exception is a NotFoundException and the request path is not an API request, serve the dashboard index.html file\n    if (exception instanceof NotFoundException && !request.path.startsWith('/api/')) {\n      const response = ctx.getResponse()\n      response.sendFile(join(__dirname, '..', 'dashboard', 'index.html'))\n      return\n    }\n\n    // Track failed authentication attempts\n    if (exception instanceof UnauthorizedException) {\n      try {\n        await this.failedAuthTracker.incrementFailedAuth(request, response)\n      } catch (error) {\n        this.logger.error('Failed to track authentication failure:', error)\n      }\n    }\n\n    if (exception instanceof HttpException) {\n      statusCode = exception.getStatus()\n      error = STATUS_CODES[statusCode]\n      const exceptionResponse = exception.getResponse()\n      if (typeof exceptionResponse === 'string') {\n        message = exceptionResponse\n      } else {\n        const responseMessage = (exceptionResponse as Record<string, unknown>).message\n        message = Array.isArray(responseMessage)\n          ? responseMessage.join(', ')\n          : (responseMessage as string) || exception.message\n      }\n    } else {\n      this.logger.error(exception)\n      error = STATUS_CODES[HttpStatus.INTERNAL_SERVER_ERROR]\n      message = 'An unexpected error occurred.'\n      statusCode = HttpStatus.INTERNAL_SERVER_ERROR\n    }\n\n    response.status(statusCode).json({\n      path: request.url,\n      timestamp: new Date().toISOString(),\n      statusCode,\n      error,\n      message,\n    })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/filters/kafka-exception.filter.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Catch, ArgumentsHost, Logger } from '@nestjs/common'\nimport { KafkaContext } from '@nestjs/microservices'\nimport NodeCache from 'node-cache'\n\ninterface KafkaMaxRetryOptions {\n  retries?: number\n  sendToDlq?: boolean\n  commitOffset?: boolean\n}\n\n@Catch()\nexport class KafkaMaxRetryExceptionFilter {\n  private readonly logger = new Logger(KafkaMaxRetryExceptionFilter.name)\n  private readonly maxRetries: number\n  private readonly sendToDlq: boolean\n  private readonly dlqTopicSuffix = '.dlq'\n  private readonly commitOffset: boolean\n  private readonly retryTracker: NodeCache\n\n  constructor(options: KafkaMaxRetryOptions = {}) {\n    this.maxRetries = options.retries ?? 3\n    this.sendToDlq = options.sendToDlq ?? false\n    this.commitOffset = options.commitOffset ?? true\n\n    // Initialize retry tracker with 5 minutes TTL\n    this.retryTracker = new NodeCache({\n      stdTTL: 300,\n      checkperiod: 60,\n      useClones: false,\n    })\n  }\n\n  async catch(exception: unknown, host: ArgumentsHost) {\n    try {\n      const kafkaContext = host.switchToRpc().getContext<KafkaContext>()\n      const message = kafkaContext.getMessage()\n      const messageKey = this.createMessageKey(kafkaContext)\n\n      this.logger.debug('Processing message', { messageKey, offset: message.offset })\n\n      const currentRetryCount = (this.retryTracker.get(messageKey) as number) || 0\n\n      if (currentRetryCount >= this.maxRetries) {\n        await this.handleMaxRetriesExceeded(kafkaContext, message, messageKey, currentRetryCount, exception)\n        return\n      }\n\n      // Allow retry\n      this.retryTracker.set(messageKey, currentRetryCount + 1, 300) // 5 minutes TTL\n      this.logger.debug(`Allowing retry ${currentRetryCount + 1}/${this.maxRetries} for message ${messageKey}`)\n      throw exception\n    } catch (filterError) {\n      this.logger.error('Error in filter:', filterError)\n      throw exception\n    }\n  }\n\n  private createMessageKey(context: KafkaContext): string {\n    return `${context.getTopic()}-${context.getPartition()}-${context.getMessage().offset}`\n  }\n\n  private async handleMaxRetriesExceeded(\n    context: KafkaContext,\n    message: any,\n    messageKey: string,\n    retryCount: number,\n    exception: unknown,\n  ): Promise<void> {\n    this.logger.warn(`Max retries (${this.maxRetries}) exceeded for message ${messageKey}`)\n\n    // Clean up retry tracker\n    this.retryTracker.del(messageKey)\n\n    if (this.sendToDlq) {\n      await this.sendToDLQ(context, message, retryCount, exception)\n    }\n\n    if (this.commitOffset) {\n      await this.commitMessageOffset(context, messageKey)\n    }\n  }\n\n  private async sendToDLQ(context: KafkaContext, message: any, retryCount: number, exception: unknown): Promise<void> {\n    try {\n      const producer = context.getProducer()\n      if (!producer) {\n        this.logger.warn('Producer not available, cannot send to DLQ')\n        return\n      }\n\n      const dlqTopic = `${context.getTopic()}${this.dlqTopicSuffix}`\n      const dlqMessage = this.createDLQMessage(message, retryCount, context, exception)\n\n      await producer.send({\n        topic: dlqTopic,\n        messages: [dlqMessage],\n      })\n\n      this.logger.log(`Message sent to DLQ: ${dlqTopic}`)\n    } catch (error) {\n      this.logger.error('Failed to send message to DLQ:', error)\n    }\n  }\n\n  private createDLQMessage(message: any, retryCount: number, context: KafkaContext, exception: unknown) {\n    return {\n      value: JSON.stringify(message.value),\n      headers: {\n        ...message.headers,\n        'retry-count': retryCount.toString(),\n        'original-topic': context.getTopic(),\n        'original-offset': String(message.offset),\n        'failed-at': new Date().toISOString(),\n        'error-type': exception instanceof Error ? exception.constructor.name : typeof exception,\n        'error-message': exception instanceof Error ? exception.message : String(exception),\n        'error-stack': exception instanceof Error ? exception.stack : undefined,\n      },\n    }\n  }\n\n  private async commitMessageOffset(context: KafkaContext, messageKey: string): Promise<void> {\n    try {\n      const consumer = context.getConsumer()\n      if (!consumer) {\n        this.logger.warn('Consumer not available, cannot commit offset')\n        return\n      }\n\n      await consumer.commitOffsets([\n        {\n          topic: context.getTopic(),\n          partition: context.getPartition(),\n          offset: String(Number(context.getMessage().offset) + 1),\n        },\n      ])\n\n      this.logger.log(`Offset committed for message ${messageKey}`)\n    } catch (error) {\n      this.logger.error(`Failed to commit offset for message ${messageKey}:`, error)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/generate-openapi.ts",
    "content": "#!/usr/bin/env ts-node\nimport * as fs from 'fs'\nimport * as path from 'path'\nimport { NestFactory } from '@nestjs/core'\nimport { AppModule } from './app.module'\nimport { SwaggerModule } from '@nestjs/swagger'\nimport { getOpenApiConfig } from './openapi.config'\nimport { addWebhookDocumentation } from './openapi-webhooks'\nimport {\n  SandboxCreatedWebhookDto,\n  SandboxStateUpdatedWebhookDto,\n  SnapshotCreatedWebhookDto,\n  SnapshotStateUpdatedWebhookDto,\n  SnapshotRemovedWebhookDto,\n  VolumeCreatedWebhookDto,\n  VolumeStateUpdatedWebhookDto,\n} from './webhook/dto/webhook-event-payloads.dto'\n\nasync function generateOpenAPI() {\n  try {\n    const app = await NestFactory.create(AppModule, {\n      logger: ['error'], // Reduce logging noise\n    })\n\n    const config = getOpenApiConfig('http://localhost:3000')\n\n    const document = {\n      ...SwaggerModule.createDocument(app, config),\n    }\n    const openapiPath = './dist/apps/api/openapi.json'\n    fs.mkdirSync(path.dirname(openapiPath), { recursive: true })\n    fs.writeFileSync(openapiPath, JSON.stringify(document, null, 2))\n\n    // Generate 3.1.0 version of the OpenAPI specification\n    // Needed for the webhook documentation\n    const document_3_1_0 = {\n      ...SwaggerModule.createDocument(app, config, {\n        extraModels: [\n          SandboxCreatedWebhookDto,\n          SandboxStateUpdatedWebhookDto,\n          SnapshotCreatedWebhookDto,\n          SnapshotStateUpdatedWebhookDto,\n          SnapshotRemovedWebhookDto,\n          VolumeCreatedWebhookDto,\n          VolumeStateUpdatedWebhookDto,\n        ],\n      }),\n      openapi: '3.1.0',\n    }\n    const documentWithWebhooks = addWebhookDocumentation(document_3_1_0)\n    const openapi310Path = './dist/apps/api/openapi.3.1.0.json'\n    fs.mkdirSync(path.dirname(openapi310Path), { recursive: true })\n    fs.writeFileSync(openapi310Path, JSON.stringify(documentWithWebhooks, null, 2))\n\n    await app.close()\n    console.log('OpenAPI specification generated successfully!')\n    clearTimeout(timeout)\n    process.exit(0)\n  } catch (error) {\n    console.error('Failed to generate OpenAPI specification:', error)\n    clearTimeout(timeout)\n    process.exit(1)\n  }\n}\n\n// Add timeout to prevent hanging\nconst timeout = setTimeout(() => {\n  console.error('Generation timed out after 30 seconds')\n  process.exit(1)\n}, 30000)\n\n// Clear timeout if process exits normally\nprocess.on('exit', () => {\n  clearTimeout(timeout)\n})\n\ngenerateOpenAPI()\n"
  },
  {
    "path": "apps/api/src/health/health.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Get, Logger, ServiceUnavailableException, UseGuards } from '@nestjs/common'\nimport { HealthCheckService, HealthCheck, TypeOrmHealthIndicator } from '@nestjs/terminus'\nimport { RedisHealthIndicator } from './redis.health'\nimport { AnonymousRateLimitGuard } from '../common/guards/anonymous-rate-limit.guard'\nimport { AuthenticatedRateLimitGuard } from '../common/guards/authenticated-rate-limit.guard'\nimport { CombinedAuthGuard } from '../auth/combined-auth.guard'\nimport { HealthCheckGuard } from '../auth/health-check.guard'\n\n@Controller('health')\nexport class HealthController {\n  private readonly logger = new Logger(HealthController.name)\n\n  constructor(\n    private health: HealthCheckService,\n    private db: TypeOrmHealthIndicator,\n    private redis: RedisHealthIndicator,\n  ) {}\n\n  @Get()\n  @UseGuards(AnonymousRateLimitGuard)\n  live() {\n    return { status: 'ok' }\n  }\n\n  @Get('ready')\n  @UseGuards(CombinedAuthGuard, HealthCheckGuard, AuthenticatedRateLimitGuard)\n  @HealthCheck()\n  async check() {\n    try {\n      const result = await this.health.check([() => this.db.pingCheck('database'), () => this.redis.isHealthy('redis')])\n      return { status: result.status }\n    } catch (error) {\n      this.logger.error(error)\n      throw new ServiceUnavailableException()\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/health/health.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { TerminusModule } from '@nestjs/terminus'\nimport { HealthController } from './health.controller'\nimport { RedisModule } from '@nestjs-modules/ioredis'\nimport { RedisHealthIndicator } from './redis.health'\n\n@Module({\n  imports: [TerminusModule, RedisModule],\n  controllers: [HealthController],\n  providers: [RedisHealthIndicator],\n})\nexport class HealthModule {}\n"
  },
  {
    "path": "apps/api/src/health/redis.health.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable } from '@nestjs/common'\nimport { HealthIndicatorService } from '@nestjs/terminus'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\n\n@Injectable()\nexport class RedisHealthIndicator {\n  private readonly redis: Redis\n  constructor(\n    @InjectRedis() redis: Redis,\n    private readonly healthIndicatorService: HealthIndicatorService,\n  ) {\n    this.redis = redis.duplicate({\n      commandTimeout: 1000,\n    })\n  }\n\n  async isHealthy(key: string) {\n    // Start the health indicator check for the given key\n    const indicator = this.healthIndicatorService.check(key)\n\n    try {\n      await this.redis.ping()\n      return indicator.up()\n    } catch (error) {\n      return indicator.down(error)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/interceptors/metrics.interceptor.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Injectable,\n  NestInterceptor,\n  ExecutionContext,\n  CallHandler,\n  OnApplicationShutdown,\n  Logger,\n} from '@nestjs/common'\nimport { Observable } from 'rxjs'\nimport { tap } from 'rxjs/operators'\nimport { PostHog } from 'posthog-node'\nimport { SandboxDto } from '../sandbox/dto/sandbox.dto'\nimport { DockerRegistryDto } from '../docker-registry/dto/docker-registry.dto'\nimport { CreateSandboxDto } from '../sandbox/dto/create-sandbox.dto'\nimport { Request } from 'express'\nimport { CreateSnapshotDto } from '../sandbox/dto/create-snapshot.dto'\nimport { SnapshotDto } from '../sandbox/dto/snapshot.dto'\nimport { CreateOrganizationDto } from '../organization/dto/create-organization.dto'\nimport { UpdateOrganizationQuotaDto } from '../organization/dto/update-organization-quota.dto'\nimport { OrganizationDto } from '../organization/dto/organization.dto'\nimport { UpdateOrganizationMemberAccessDto } from '../organization/dto/update-organization-member-access.dto'\nimport { CreateOrganizationRoleDto } from '../organization/dto/create-organization-role.dto'\nimport { UpdateOrganizationRoleDto } from '../organization/dto/update-organization-role.dto'\nimport { CreateOrganizationInvitationDto } from '../organization/dto/create-organization-invitation.dto'\nimport { UpdateOrganizationInvitationDto } from '../organization/dto/update-organization-invitation.dto'\nimport { CustomHeaders } from '../common/constants/header.constants'\nimport { CreateVolumeDto } from '../sandbox/dto/create-volume.dto'\nimport { VolumeDto } from '../sandbox/dto/volume.dto'\nimport { CreateWorkspaceDto } from '../sandbox/dto/create-workspace.deprecated.dto'\nimport { WorkspaceDto } from '../sandbox/dto/workspace.deprecated.dto'\nimport { TypedConfigService } from '../config/typed-config.service'\nimport { UpdateOrganizationRegionQuotaDto } from '../organization/dto/update-organization-region-quota.dto'\nimport { UpdateOrganizationDefaultRegionDto } from '../organization/dto/update-organization-default-region.dto'\n\ntype RequestWithUser = Request & { user?: { userId: string; organizationId: string } }\ntype CommonCaptureProps = {\n  organizationId?: string\n  distinctId: string\n  durationMs: number\n  statusCode: number\n  userAgent: string\n  error?: string\n  source: string\n  isDeprecated?: boolean\n  sdkVersion?: string\n  environment?: string\n}\n\n@Injectable()\nexport class MetricsInterceptor implements NestInterceptor, OnApplicationShutdown {\n  private readonly posthog?: PostHog\n  private readonly version: string\n  private readonly logger = new Logger(MetricsInterceptor.name)\n\n  constructor(private readonly configService: TypedConfigService) {\n    this.version = this.configService.getOrThrow('version')\n\n    if (!this.configService.get('posthog.apiKey')) {\n      this.logger.warn('POSTHOG_API_KEY is not set, metrics will not be recorded')\n      return\n    }\n\n    if (!this.configService.get('posthog.host')) {\n      this.logger.warn('POSTHOG_HOST is not set, metrics will not be recorded')\n      return\n    }\n\n    // Initialize PostHog client\n    // Make sure to set POSTHOG_API_KEY in your environment variables\n    this.posthog = new PostHog(this.configService.getOrThrow('posthog.apiKey'), {\n      host: this.configService.getOrThrow('posthog.host'),\n    })\n  }\n\n  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {\n    if (!this.posthog) {\n      return next.handle()\n    }\n\n    const request = context.switchToHttp().getRequest()\n    const startTime = Date.now()\n\n    return next.handle().pipe(\n      tap({\n        next: (response) => {\n          // For DELETE requests or empty responses, pass an empty object with statusCode\n          const responseObj = response || { statusCode: 204 }\n          this.recordMetrics(request, responseObj, startTime).catch((err) => this.logger.error(err))\n        },\n        error: (error) => {\n          this.recordMetrics(\n            request,\n            { statusCode: error.status || 500 },\n            startTime,\n            error.message || JSON.stringify(error),\n          ).catch((err) => this.logger.error(err))\n        },\n      }),\n    )\n  }\n\n  private async recordMetrics(request: RequestWithUser, response: any, startTime: number, error?: string) {\n    const durationMs = Date.now() - startTime\n    const statusCode = error ? response.statusCode : response.statusCode || (request.method === 'DELETE' ? 204 : 200) // Default to 204 for DELETE requests\n    const distinctId = request.user?.userId || 'anonymous'\n    const userAgent = request.get('user-agent')\n    const source = request.get(CustomHeaders.SOURCE.name)\n    const sdkVersion = request.get(CustomHeaders.SDK_VERSION.name)\n\n    const props: CommonCaptureProps = {\n      distinctId,\n      organizationId: request.user?.organizationId,\n      durationMs,\n      statusCode,\n      userAgent,\n      error,\n      source: Array.isArray(source) ? source[0] : source,\n      isDeprecated: request.route.path.includes('/workspace') || request.route.path.includes('/images'),\n      sdkVersion,\n      environment: this.configService.get('posthog.environment'),\n    }\n\n    switch (request.method) {\n      case 'POST':\n        switch (request.route.path) {\n          case '/api/api-keys':\n            this.captureCreateApiKey(props)\n            break\n          case '/api/snapshots':\n            this.captureCreateSnapshot(props, request.body, response)\n            break\n          case '/api/snapshots/:snapshotId/activate':\n            this.captureActivateSnapshot(props, request.params.snapshotId)\n            break\n          case '/api/snapshots/:snapshotId/deactivate':\n            this.captureDeactivateSnapshot(props, request.params.snapshotId)\n            break\n          case '/api/docker-registry':\n            this.captureCreateDockerRegistry(props, response)\n            break\n          case '/api/sandbox':\n            this.captureCreateSandbox(props, request.body, response)\n            break\n          case '/api/workspace':\n            this.captureCreateWorkspace_deprecated(props, request.body, response)\n            break\n          case '/api/sandbox/:sandboxIdOrName/start':\n          case '/api/workspace/:workspaceId/start':\n            this.captureStartSandbox(props, request.params.sandboxIdOrName || request.params.workspaceId)\n            break\n          case '/api/sandbox/:sandboxIdOrName/stop':\n          case '/api/workspace/:workspaceId/stop':\n            this.captureStopSandbox(props, request.params.sandboxIdOrName || request.params.workspaceId)\n            break\n          case '/api/sandbox/:sandboxIdOrName/resize':\n            this.captureResizeSandbox(props, request.params.sandboxIdOrName, request.body)\n            break\n          case '/api/sandbox/:sandboxIdOrName/archive':\n          case '/api/workspace/:workspaceId/archive':\n            this.captureArchiveSandbox(props, request.params.sandboxIdOrName || request.params.workspaceId)\n            break\n          case '/api/sandbox/:sandboxIdOrName/backup':\n            this.captureCreateBackup(props, request.params.sandboxIdOrName)\n            break\n          case '/api/sandbox/:sandboxIdOrName/public/:isPublic':\n          case '/api/workspace/:workspaceId/public/:isPublic':\n            this.captureUpdatePublicStatus(\n              props,\n              request.params.sandboxIdOrName || request.params.workspaceId,\n              request.params.isPublic === 'true',\n            )\n            break\n          case '/api/sandbox/:sandboxIdOrName/autostop/:interval':\n          case '/api/workspace/:workspaceId/autostop/:interval':\n            this.captureSetAutostopInterval(\n              props,\n              request.params.sandboxIdOrName || request.params.workspaceId,\n              parseInt(request.params.interval),\n            )\n            break\n          case '/api/sandbox/:sandboxIdOrName/autoarchive/:interval':\n          case '/api/workspace/:workspaceId/autoarchive/:interval':\n            this.captureSetAutoArchiveInterval(\n              props,\n              request.params.sandboxIdOrName || request.params.workspaceId,\n              parseInt(request.params.interval),\n            )\n            break\n          case '/api/sandbox/:sandboxIdOrName/autodelete/:interval':\n            this.captureSetAutoDeleteInterval(props, request.params.sandboxIdOrName, parseInt(request.params.interval))\n            break\n          case '/api/organizations/invitations/:invitationId/accept':\n            this.captureAcceptInvitation(props, request.params.invitationId)\n            break\n          case '/api/organizations/invitations/:invitationId/decline':\n            this.captureDeclineInvitation(props, request.params.invitationId)\n            break\n          case '/api/organizations':\n            this.captureCreateOrganization(props, request.body, response)\n            break\n          case '/api/organizations/:organizationId/leave':\n            this.captureLeaveOrganization(props, request.params.organizationId)\n            break\n          case '/api/organizations/:organizationId/users/:userId/access':\n            this.captureUpdateOrganizationUserAccess(\n              props,\n              request.params.organizationId,\n              request.params.userId,\n              request.body,\n            )\n            break\n          case '/api/organizations/:organizationId/roles':\n            this.captureCreateOrganizationRole(props, request.params.organizationId, request.body)\n            break\n          case '/api/organizations/:organizationId/invitations':\n            this.captureCreateOrganizationInvitation(props, request.params.organizationId, request.body)\n            break\n          case '/api/organizations/:organizationId/invitations/:invitationId/cancel':\n            this.captureCancelOrganizationInvitation(props, request.params.organizationId, request.params.invitationId)\n            break\n          case '/api/volumes':\n            this.captureCreateVolume(props, request.body, response)\n            break\n        }\n        break\n      case 'DELETE':\n        switch (request.route.path) {\n          case '/api/sandbox/:sandboxIdOrName':\n          case '/api/workspace/:workspaceId':\n            this.captureDeleteSandbox(props, request.params.sandboxIdOrName || request.params.workspaceId)\n            break\n          case '/api/snapshots/:snapshotId':\n            this.captureDeleteSnapshot(props, request.params.snapshotId)\n            break\n          case '/api/organizations/:organizationId':\n            this.captureDeleteOrganization(props, request.params.organizationId)\n            break\n          case '/api/organizations/:organizationId/users/:userId':\n            this.captureDeleteOrganizationUser(props, request.params.organizationId, request.params.userId)\n            break\n          case '/api/organizations/:organizationId/roles/:roleId':\n            this.captureDeleteOrganizationRole(props, request.params.organizationId, request.params.roleId)\n            break\n          case '/api/volumes/:volumeId':\n            this.captureDeleteVolume(props, request.params.volumeId)\n            break\n        }\n        break\n      case 'PUT':\n        switch (request.route.path) {\n          case '/api/sandbox/:sandboxIdOrName/labels':\n          case '/api/workspace/:workspaceId/labels':\n            this.captureUpdateSandboxLabels(props, request.params.sandboxIdOrName || request.params.workspaceId)\n            break\n          case '/api/organizations/:organizationId/roles/:roleId':\n            this.captureUpdateOrganizationRole(\n              props,\n              request.params.organizationId,\n              request.params.roleId,\n              request.body,\n            )\n            break\n          case '/api/organizations/:organizationId/invitations/:invitationId':\n            this.captureUpdateOrganizationInvitation(\n              props,\n              request.params.organizationId,\n              request.params.invitationId,\n              request.body,\n            )\n            break\n          case '/api/organizations/:organizationId/experimental-config':\n            this.captureUpdateOrganizationExperimentalConfig(props, request.body)\n            break\n        }\n        break\n      case 'PATCH':\n        switch (request.route.path) {\n          case '/api/organizations/:organizationId/default-region':\n            this.captureSetOrganizationDefaultRegion(props, request.params.organizationId, request.body)\n            break\n          case '/api/organizations/:organizationId/quota':\n            this.captureUpdateOrganizationQuota(props, request.params.organizationId, request.body)\n            break\n          case '/api/organizations/:organizationId/quota/:regionId':\n            this.captureUpdateOrganizationRegionQuota(\n              props,\n              request.params.organizationId,\n              request.params.regionId,\n              request.body,\n            )\n            break\n        }\n        break\n    }\n\n    if (!request.route.path.startsWith('/api/toolbox/:sandboxId/toolbox')) {\n      return\n    }\n\n    const path = request.route.path.replace('/api/toolbox/:sandboxId/toolbox', '')\n\n    switch (path) {\n      case '/project-dir':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'project-dir_get')\n        break\n      case '/files':\n        switch (request.method) {\n          case 'GET':\n            this.captureToolboxCommand(props, request.params.sandboxId, 'files_list')\n            break\n          case 'DELETE':\n            this.captureToolboxCommand(props, request.params.sandboxId, 'files_delete')\n            break\n        }\n        break\n      case '/files/download':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_download')\n        break\n      case '/files/find':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_find')\n        break\n      case '/files/folder':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_folder_create')\n        break\n      case '/files/info':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_info')\n        break\n      case '/files/move':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_move')\n        break\n      case '/files/permissions':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_permissions')\n        break\n      case '/files/replace':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_replace')\n        break\n      case '/files/search':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_search')\n        break\n      case '/files/upload':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'files_upload')\n        break\n      case '/git/add':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'git_add')\n        break\n      case '/git/branches':\n        switch (request.method) {\n          case 'GET':\n            this.captureToolboxCommand(props, request.params.sandboxId, 'git_branches_list')\n            break\n          case 'POST':\n            this.captureToolboxCommand(props, request.params.sandboxId, 'git_branches_create')\n            break\n        }\n        break\n      case '/git/clone':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'git_clone')\n        break\n      case '/git/commit':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'git_commit')\n        break\n      case '/git/history':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'git_history')\n        break\n      case '/git/pull':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'git_pull')\n        break\n      case '/git/push':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'git_push')\n        break\n      case '/git/status':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'git_status')\n        break\n      case '/process/execute':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'process_execute', {\n          command: request.body.command,\n          cwd: request.body.cwd,\n          exit_code: response.exitCode,\n          timeout_sec: request.body.timeout,\n        })\n        break\n      case '/process/session':\n        switch (request.method) {\n          case 'GET':\n            this.captureToolboxCommand(props, request.params.sandboxId, 'process_session_list')\n            break\n          case 'POST':\n            this.captureToolboxCommand(props, request.params.sandboxId, 'process_session_create', {\n              session_id: request.body.sessionId,\n            })\n            break\n        }\n        break\n      case '/process/session/:sessionId':\n        switch (request.method) {\n          case 'GET':\n            this.captureToolboxCommand(props, request.params.sandboxId, 'process_session_get', {\n              session_id: request.params.sessionId,\n            })\n            break\n          case 'DELETE':\n            this.captureToolboxCommand(props, request.params.sandboxId, 'process_session_delete', {\n              session_id: request.params.sessionId,\n            })\n            break\n        }\n        break\n      case '/process/session/:sessionId/exec':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'process_session_execute', {\n          session_id: request.params.sessionId,\n          command: request.body.command,\n        })\n        break\n      case '/process/session/:sessionId/command/:commandId':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'process_session_command_get', {\n          session_id: request.params.sessionId,\n          command_id: request.params.commandId,\n        })\n        break\n      case '/process/session/:sessionId/command/:commandId/logs':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'process_session_command_logs', {\n          session_id: request.params.sessionId,\n          command_id: request.params.commandId,\n        })\n        break\n      case '/lsp/completions':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'lsp_completions')\n        break\n      case '/lsp/did-close':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'lsp_did_close')\n        break\n      case '/lsp/did-open':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'lsp_did_open')\n        break\n      case '/lsp/document-symbols':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'lsp_document_symbols')\n        break\n      case '/lsp/start':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'lsp_start', {\n          language_id: request.body.languageId,\n        })\n        break\n      case '/lsp/stop':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'lsp_stop', {\n          language_id: request.body.languageId,\n        })\n        break\n      case '/lsp/sandbox-symbols':\n        this.captureToolboxCommand(props, request.params.sandboxId, 'lsp_sandbox_symbols', {\n          language_id: request.query.languageId,\n          path_to_project: request.query.pathToProject,\n          query: request.query.query,\n        })\n        break\n    }\n  }\n\n  private captureCreateApiKey(props: CommonCaptureProps) {\n    this.capture('api_api_key_created', props, 'api_api_key_creation_failed')\n  }\n\n  private captureCreateDockerRegistry(props: CommonCaptureProps, response: DockerRegistryDto) {\n    this.capture('api_docker_registry_created', props, 'api_docker_registry_creation_failed', {\n      registry_name: response.name,\n      registry_url: response.url,\n    })\n  }\n\n  private captureCreateSnapshot(props: CommonCaptureProps, request: CreateSnapshotDto, response: SnapshotDto) {\n    this.capture('api_snapshot_created', props, 'api_snapshot_creation_failed', {\n      snapshot_id: response.id,\n      snapshot_name: request.name,\n      snapshot_image_name: request.imageName,\n      snapshot_entrypoint: request.entrypoint,\n      snapshot_cpu: request.cpu,\n      snapshot_gpu: request.gpu,\n      snapshot_memory: request.memory,\n      snapshot_disk: request.disk,\n      snapshot_is_build: request.buildInfo ? true : false,\n      snapshot_build_info_context_hashes_length: request.buildInfo?.contextHashes?.length,\n    })\n  }\n\n  private captureActivateSnapshot(props: CommonCaptureProps, snapshotId: string) {\n    this.capture('api_snapshot_activated', props, 'api_snapshot_activation_failed', {\n      snapshot_id: snapshotId,\n    })\n  }\n\n  private captureDeactivateSnapshot(props: CommonCaptureProps, snapshotId: string) {\n    this.capture('api_snapshot_deactivated', props, 'api_snapshot_deactivation_failed', {\n      snapshot_id: snapshotId,\n    })\n  }\n\n  private captureDeleteSnapshot(props: CommonCaptureProps, snapshotId: string) {\n    this.capture('api_snapshot_deleted', props, 'api_snapshot_deletion_failed', {\n      snapshot_id: snapshotId,\n    })\n  }\n\n  private captureCreateSandbox(props: CommonCaptureProps, request: CreateSandboxDto, response: SandboxDto) {\n    const envVarsLength = request.env ? Object.keys(request.env).length : 0\n\n    const records = {\n      sandbox_id: response.id,\n      sandbox_name_request: request.name,\n      sandbox_name: response.name,\n      sandbox_snapshot_request: request.snapshot,\n      sandbox_snapshot: response.snapshot,\n      sandbox_user_request: request.user,\n      sandbox_user: response.user,\n      sandbox_cpu_request: request.cpu,\n      sandbox_cpu: response.cpu,\n      sandbox_gpu_request: request.gpu,\n      sandbox_gpu: response.gpu,\n      sandbox_memory_mb_request: request.memory * 1024,\n      sandbox_memory_mb: response.memory * 1024,\n      sandbox_disk_gb_request: request.disk,\n      sandbox_disk_gb: response.disk,\n      sandbox_target_request: request.target,\n      sandbox_target: response.target,\n      sandbox_auto_stop_interval_min_request: request.autoStopInterval,\n      sandbox_auto_stop_interval_min: response.autoStopInterval,\n      sandbox_auto_archive_interval_min_request: request.autoArchiveInterval,\n      sandbox_auto_archive_interval_min: response.autoArchiveInterval,\n      sandbox_auto_delete_interval_min_request: request.autoDeleteInterval,\n      sandbox_auto_delete_interval_min: response.autoDeleteInterval,\n      sandbox_public_request: request.public,\n      sandbox_public: response.public,\n      sandbox_labels_request: request.labels,\n      sandbox_labels: response.labels,\n      sandbox_env_vars_length_request: envVarsLength,\n      sandbox_volumes_length_request: request.volumes?.length,\n      sandbox_daemon_version: response.daemonVersion,\n      sandbox_network_block_all_request: request.networkBlockAll,\n      sandbox_network_block_all: response.networkBlockAll,\n      sandbox_network_allow_list_set_request: !!request.networkAllowList,\n      sandbox_network_allow_list_set: !!response.networkAllowList,\n    }\n\n    if (request.buildInfo) {\n      records['sandbox_is_dynamic_build'] = true\n      records['sandbox_build_info_context_hashes_length'] = request.buildInfo.contextHashes?.length\n    }\n\n    this.capture('api_sandbox_created', props, 'api_sandbox_creation_failed', records)\n  }\n\n  private captureCreateWorkspace_deprecated(\n    props: CommonCaptureProps,\n    request: CreateWorkspaceDto,\n    response: WorkspaceDto,\n  ) {\n    const envVarsLength = request.env ? Object.keys(request.env).length : 0\n\n    const records = {\n      sandbox_id: response.id,\n      sandbox_snapshot_request: request.image,\n      sandbox_snapshot: response.snapshot,\n      sandbox_user_request: request.user,\n      sandbox_user: response.user,\n      sandbox_cpu_request: request.cpu,\n      sandbox_cpu: response.cpu,\n      sandbox_gpu_request: request.gpu,\n      sandbox_gpu: response.gpu,\n      sandbox_memory_mb_request: request.memory * 1024,\n      sandbox_memory_mb: response.memory * 1024,\n      sandbox_disk_gb_request: request.disk,\n      sandbox_disk_gb: response.disk,\n      sandbox_target_request: request.target,\n      sandbox_target: response.target,\n      sandbox_auto_stop_interval_min_request: request.autoStopInterval,\n      sandbox_auto_stop_interval_min: response.autoStopInterval,\n      sandbox_auto_archive_interval_min_request: request.autoArchiveInterval,\n      sandbox_auto_archive_interval_min: response.autoArchiveInterval,\n      sandbox_public_request: request.public,\n      sandbox_public: response.public,\n      sandbox_labels_request: request.labels,\n      sandbox_labels: response.labels,\n      sandbox_env_vars_length_request: envVarsLength,\n      sandbox_volumes_length_request: request.volumes?.length,\n      sandbox_daemon_version: response.daemonVersion,\n    }\n\n    if (request.buildInfo) {\n      records['sandbox_is_dynamic_build'] = true\n      records['sandbox_build_info_context_hashes_length'] = request.buildInfo.contextHashes?.length\n    }\n\n    this.capture('api_sandbox_created', props, 'api_sandbox_creation_failed', records)\n  }\n\n  private captureDeleteSandbox(props: CommonCaptureProps, sandboxId: string) {\n    this.capture('api_sandbox_deleted', props, 'api_sandbox_deletion_failed', {\n      sandbox_id: sandboxId,\n    })\n  }\n\n  private captureStartSandbox(props: CommonCaptureProps, sandboxId: string) {\n    this.capture('api_sandbox_started', props, 'api_sandbox_start_failed', {\n      sandbox_id: sandboxId,\n    })\n  }\n\n  private captureStopSandbox(props: CommonCaptureProps, sandboxId: string) {\n    this.capture('api_sandbox_stopped', props, 'api_sandbox_stop_failed', {\n      sandbox_id: sandboxId,\n    })\n  }\n\n  private captureResizeSandbox(\n    props: CommonCaptureProps,\n    sandboxId: string,\n    body: { cpu?: number; memory?: number; disk?: number },\n  ) {\n    this.capture('api_sandbox_resized', props, 'api_sandbox_resize_failed', {\n      sandbox_id: sandboxId,\n      cpu: body?.cpu,\n      memory: body?.memory,\n      disk: body?.disk,\n    })\n  }\n\n  private captureArchiveSandbox(props: CommonCaptureProps, sandboxId: string) {\n    this.capture('api_sandbox_archived', props, 'api_sandbox_archive_failed', {\n      sandbox_id: sandboxId,\n    })\n  }\n\n  private captureCreateBackup(props: CommonCaptureProps, sandboxId: string) {\n    this.capture('api_sandbox_backup_created', props, 'api_sandbox_backup_creation_failed', {\n      sandbox_id: sandboxId,\n    })\n  }\n\n  private captureUpdatePublicStatus(props: CommonCaptureProps, sandboxId: string, isPublic: boolean) {\n    this.capture('api_sandbox_public_status_updated', props, 'api_sandbox_public_status_update_failed', {\n      sandbox_id: sandboxId,\n      sandbox_public: isPublic,\n    })\n  }\n\n  private captureSetAutostopInterval(props: CommonCaptureProps, sandboxId: string, interval: number) {\n    this.capture('api_sandbox_autostop_interval_updated', props, 'api_sandbox_autostop_interval_update_failed', {\n      sandbox_id: sandboxId,\n      sandbox_autostop_interval: interval,\n    })\n  }\n\n  private captureSetAutoArchiveInterval(props: CommonCaptureProps, sandboxId: string, interval: number) {\n    this.capture('api_sandbox_autoarchive_interval_updated', props, 'api_sandbox_autoarchive_interval_update_failed', {\n      sandbox_id: sandboxId,\n      sandbox_autoarchive_interval: interval,\n    })\n  }\n\n  private captureSetAutoDeleteInterval(props: CommonCaptureProps, sandboxId: string, interval: number) {\n    this.capture('api_sandbox_autodelete_interval_updated', props, 'api_sandbox_autodelete_interval_update_failed', {\n      sandbox_id: sandboxId,\n      sandbox_autodelete_interval: interval,\n    })\n  }\n\n  private captureUpdateSandboxLabels(props: CommonCaptureProps, sandboxId: string) {\n    this.capture('api_sandbox_labels_update', props, 'api_sandbox_labels_update_failed', {\n      sandbox_id: sandboxId,\n    })\n  }\n\n  private captureAcceptInvitation(props: CommonCaptureProps, invitationId: string) {\n    this.capture('api_invitation_accepted', props, 'api_invitation_accept_failed', {\n      invitation_id: invitationId,\n    })\n  }\n\n  private captureDeclineInvitation(props: CommonCaptureProps, invitationId: string) {\n    this.capture('api_invitation_declined', props, 'api_invitation_decline_failed', {\n      invitation_id: invitationId,\n    })\n  }\n\n  private captureCreateOrganization(\n    props: CommonCaptureProps,\n    request: CreateOrganizationDto,\n    response: OrganizationDto,\n  ) {\n    if (!this.posthog) {\n      return\n    }\n\n    this.posthog.groupIdentify({\n      groupType: 'organization',\n      groupKey: response.id,\n      properties: {\n        name: request.name,\n        created_at: response.createdAt,\n        created_by: response.createdBy,\n        personal: response.personal,\n        environment: this.configService.get('posthog.environment'),\n      },\n    })\n\n    this.capture('api_organization_created', props, 'api_organization_creation_failed', {\n      organization_id: response.id,\n      organization_name: request.name,\n      organization_default_region_id: request.defaultRegionId,\n    })\n  }\n\n  private captureLeaveOrganization(props: CommonCaptureProps, organizationId: string) {\n    this.capture('api_organization_left', props, 'api_organization_leave_failed', {\n      organization_id: organizationId,\n    })\n  }\n\n  private captureSetOrganizationDefaultRegion(\n    props: CommonCaptureProps,\n    organizationId: string,\n    request: UpdateOrganizationDefaultRegionDto,\n  ) {\n    this.capture('api_organization_default_region_set', props, 'api_organization_default_region_set_failed', {\n      organization_id: organizationId,\n      organization_default_region_id: request.defaultRegionId,\n    })\n  }\n\n  private captureUpdateOrganizationQuota(\n    props: CommonCaptureProps,\n    organizationId: string,\n    request: UpdateOrganizationQuotaDto,\n  ) {\n    this.capture('api_organization_quota_updated', props, 'api_organization_quota_update_failed', {\n      organization_id: organizationId,\n      organization_max_cpu_per_sandbox: request.maxCpuPerSandbox,\n      organization_max_memory_per_sandbox_mb: request.maxMemoryPerSandbox ? request.maxMemoryPerSandbox * 1024 : null,\n      organization_max_disk_per_sandbox_gb: request.maxDiskPerSandbox,\n      organization_snapshot_quota: request.snapshotQuota,\n      organization_max_snapshot_size_mb: request.maxSnapshotSize ? request.maxSnapshotSize * 1024 : null,\n      organization_volume_quota: request.volumeQuota,\n    })\n  }\n\n  private captureUpdateOrganizationRegionQuota(\n    props: CommonCaptureProps,\n    organizationId: string,\n    regionId: string,\n    request: UpdateOrganizationRegionQuotaDto,\n  ) {\n    this.capture('api_organization_region_quota_updated', props, 'api_organization_region_quota_update_failed', {\n      organization_id: organizationId,\n      organization_region_id: regionId,\n      organization_region_total_cpu_quota: request.totalCpuQuota,\n      organization_region_total_memory_quota_mb: request.totalMemoryQuota ? request.totalMemoryQuota * 1024 : null,\n      organization_region_total_disk_quota_gb: request.totalDiskQuota,\n    })\n  }\n\n  private captureDeleteOrganization(props: CommonCaptureProps, organizationId: string) {\n    this.capture('api_organization_deleted', props, 'api_organization_deletion_failed', {\n      organization_id: organizationId,\n    })\n  }\n\n  private captureUpdateOrganizationUserAccess(\n    props: CommonCaptureProps,\n    organizationId: string,\n    userId: string,\n    request: UpdateOrganizationMemberAccessDto,\n  ) {\n    this.capture('api_organization_user_access_updated', props, 'api_organization_user_access_update_failed', {\n      organization_id: organizationId,\n      organization_user_id: userId,\n      organization_user_role: request.role,\n      organization_user_assigned_role_ids: request.assignedRoleIds,\n    })\n  }\n\n  private captureDeleteOrganizationUser(props: CommonCaptureProps, organizationId: string, userId: string) {\n    this.capture('api_organization_user_deleted', props, 'api_organization_user_deletion_failed', {\n      organization_id: organizationId,\n      organization_user_id: userId,\n    })\n  }\n\n  private captureCreateOrganizationRole(\n    props: CommonCaptureProps,\n    organizationId: string,\n    request: CreateOrganizationRoleDto,\n  ) {\n    this.capture('api_organization_role_created', props, 'api_organization_role_creation_failed', {\n      organization_id: organizationId,\n      organization_role_name: request.name,\n      organization_role_description: request.description,\n      organization_role_permissions: request.permissions,\n    })\n  }\n\n  private captureDeleteOrganizationRole(props: CommonCaptureProps, organizationId: string, roleId: string) {\n    this.capture('api_organization_role_deleted', props, 'api_organization_role_deletion_failed', {\n      organization_id: organizationId,\n      organization_role_id: roleId,\n    })\n  }\n\n  private captureUpdateOrganizationRole(\n    props: CommonCaptureProps,\n    organizationId: string,\n    roleId: string,\n    request: UpdateOrganizationRoleDto,\n  ) {\n    this.capture('api_organization_role_updated', props, 'api_organization_role_update_failed', {\n      organization_id: organizationId,\n      organization_role_id: roleId,\n      organization_role_name: request.name,\n      organization_role_description: request.description,\n      organization_role_permissions: request.permissions,\n    })\n  }\n\n  private captureCreateOrganizationInvitation(\n    props: CommonCaptureProps,\n    organizationId: string,\n    request: CreateOrganizationInvitationDto,\n  ) {\n    this.capture('api_organization_invitation_created', props, 'api_organization_invitation_creation_failed', {\n      organization_id: organizationId,\n      organization_invitation_email: request.email,\n      organization_invitation_role: request.role,\n      organization_invitation_assigned_role_ids: request.assignedRoleIds,\n      organization_invitation_expires_at: request.expiresAt,\n    })\n  }\n\n  private captureUpdateOrganizationInvitation(\n    props: CommonCaptureProps,\n    organizationId: string,\n    invitationId: string,\n    request: UpdateOrganizationInvitationDto,\n  ) {\n    this.capture('api_organization_invitation_updated', props, 'api_organization_invitation_update_failed', {\n      organization_id: organizationId,\n      organization_invitation_id: invitationId,\n      organization_invitation_expires_at: request.expiresAt,\n      organization_invitation_role: request.role,\n      organization_invitation_assigned_role_ids: request.assignedRoleIds,\n    })\n  }\n\n  private captureCancelOrganizationInvitation(props: CommonCaptureProps, organizationId: string, invitationId: string) {\n    this.capture('api_organization_invitation_canceled', props, 'api_organization_invitation_cancel_failed', {\n      organization_id: organizationId,\n      organization_invitation_id: invitationId,\n    })\n  }\n\n  private captureCreateVolume(props: CommonCaptureProps, request: CreateVolumeDto, response: VolumeDto) {\n    this.capture('api_volume_created', props, 'api_volume_creation_failed', {\n      volume_id: response.id,\n      volume_name_request_set: !!request.name,\n    })\n  }\n\n  private captureDeleteVolume(props: CommonCaptureProps, volumeId: string) {\n    this.capture('api_volume_deleted', props, 'api_volume_deletion_failed', {\n      volume_id: volumeId,\n    })\n  }\n\n  private captureUpdateOrganizationExperimentalConfig(\n    props: CommonCaptureProps,\n    experimentalConfig: Record<string, any> | null,\n  ) {\n    this.capture(\n      'api_organization_experimental_config_updated',\n      props,\n      'api_organization_experimental_config_update_failed',\n      {\n        experimental_config_empty: !experimentalConfig,\n        experimental_config_otel_set: !!experimentalConfig?.otel,\n      },\n    )\n  }\n\n  private captureToolboxCommand(\n    props: CommonCaptureProps,\n    sandboxId: string,\n    command: string,\n    extraProps?: Record<string, any>,\n  ) {\n    this.capture('api_toolbox_command', props, 'api_toolbox_command_failed', {\n      sandbox_id: sandboxId,\n      toolbox_command: command,\n      ...extraProps,\n    })\n  }\n\n  private capture(event: string, props: CommonCaptureProps, errorEvent?: string, extraProps?: Record<string, any>) {\n    if (!this.posthog) {\n      return\n    }\n\n    this.posthog.capture({\n      distinctId: props.distinctId,\n      event: props.error ? errorEvent || event : event,\n      groups: this.captureCommonGroups(props),\n      properties: { ...this.captureCommonProperties(props), ...extraProps },\n    })\n  }\n\n  private captureCommonProperties(props: CommonCaptureProps) {\n    return {\n      duration_ms: props.durationMs,\n      status_code: props.statusCode,\n      user_agent: props.userAgent,\n      error: props.error,\n      source: props.source,\n      is_deprecated: props.isDeprecated,\n      sdk_version: props.sdkVersion,\n      environment: props.environment,\n      daytona_version: this.version,\n    }\n  }\n\n  private captureCommonGroups(props: CommonCaptureProps) {\n    return props.organizationId ? { organization: props.organizationId } : undefined\n  }\n\n  onApplicationShutdown(/*signal?: string*/) {\n    if (this.posthog) {\n      this.posthog.shutdown()\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/main.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { otelSdk } from './tracing'\nimport { readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'\nimport { NestFactory } from '@nestjs/core'\nimport { NestExpressApplication } from '@nestjs/platform-express'\nimport { AppModule } from './app.module'\nimport { SwaggerModule } from '@nestjs/swagger'\nimport { INestApplication, Logger, ValidationPipe } from '@nestjs/common'\nimport { AllExceptionsFilter } from './filters/all-exceptions.filter'\nimport { MetricsInterceptor } from './interceptors/metrics.interceptor'\nimport { HttpsOptions } from '@nestjs/common/interfaces/external/https-options.interface'\nimport { TypedConfigService } from './config/typed-config.service'\nimport { FailedAuthTrackerService } from './auth/failed-auth-tracker.service'\nimport { DataSource, MigrationExecutor } from 'typeorm'\nimport { getOpenApiConfig } from './openapi.config'\nimport { AuditInterceptor } from './audit/interceptors/audit.interceptor'\nimport { join } from 'node:path'\nimport { ApiKeyService } from './api-key/api-key.service'\nimport { DAYTONA_ADMIN_USER_ID } from './app.service'\nimport { OrganizationService } from './organization/services/organization.service'\nimport { MicroserviceOptions, Transport } from '@nestjs/microservices'\nimport { Partitioners } from 'kafkajs'\nimport { isApiEnabled, isWorkerEnabled } from './common/utils/app-mode'\nimport cluster from 'node:cluster'\nimport { Logger as PinoLogger, LoggerErrorInterceptor } from 'nestjs-pino'\n\n// https options\nconst httpsEnabled = process.env.CERT_PATH && process.env.CERT_KEY_PATH\nconst httpsOptions: HttpsOptions = {\n  cert: process.env.CERT_PATH ? readFileSync(process.env.CERT_PATH) : undefined,\n  key: process.env.CERT_KEY_PATH ? readFileSync(process.env.CERT_KEY_PATH) : undefined,\n}\n\nasync function bootstrap() {\n  if (process.env.OTEL_ENABLED === 'true') {\n    await otelSdk.start()\n  }\n  const app = await NestFactory.create<NestExpressApplication>(AppModule, {\n    bufferLogs: true,\n    httpsOptions: httpsEnabled ? httpsOptions : undefined,\n  })\n  app.useLogger(app.get(PinoLogger))\n  app.flushLogs()\n  app.enableCors({\n    origin: true,\n    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',\n    credentials: true,\n  })\n\n  const configService = app.get(TypedConfigService)\n  const failedAuthTracker = app.get(FailedAuthTrackerService)\n  app.set('trust proxy', true)\n  app.useGlobalFilters(new AllExceptionsFilter(failedAuthTracker))\n  app.useGlobalInterceptors(new LoggerErrorInterceptor())\n  app.useGlobalInterceptors(new MetricsInterceptor(configService))\n  app.useGlobalInterceptors(app.get(AuditInterceptor))\n  app.useGlobalPipes(\n    new ValidationPipe({\n      transform: true,\n    }),\n  )\n\n  // Runtime flags for migrations for run and revert migrations\n  if (process.argv.length > 2) {\n    if (process.argv[2].startsWith('--migration-')) {\n      const dataSource = app.get(DataSource)\n      dataSource.setOptions({ logging: true })\n      const migrationExecutor = new MigrationExecutor(dataSource)\n\n      switch (process.argv[2]) {\n        case '--migration-run':\n          await migrationExecutor.executePendingMigrations()\n          break\n        case '--migration-revert':\n          await migrationExecutor.undoLastMigration()\n          break\n        default:\n          Logger.error('Invalid migration flag')\n          process.exit(1)\n      }\n    } else if (process.argv[2] === '--create-admin-api-key') {\n      if (process.argv.length < 4) {\n        Logger.error('Invalid flag. API key name is required.')\n        process.exit(1)\n      }\n      await createAdminApiKey(app, process.argv[3])\n    } else {\n      Logger.error('Invalid flag')\n      process.exit(1)\n    }\n\n    process.exit(0)\n  }\n\n  const globalPrefix = 'api'\n  app.setGlobalPrefix(globalPrefix)\n\n  const documentFactory = () => SwaggerModule.createDocument(app, getOpenApiConfig(configService.get('oidc.issuer')))\n  SwaggerModule.setup('api', app, documentFactory, {\n    swaggerOptions: {\n      initOAuth: {\n        clientId: configService.get('oidc.clientId'),\n        appName: 'Daytona AI',\n        scopes: ['openid', 'profile', 'email'],\n        additionalQueryStringParams: {\n          audience: configService.get('oidc.audience'),\n        },\n      },\n    },\n  })\n\n  // Replace dashboard api url before serving\n  if (configService.get('production')) {\n    const dashboardDir = join(__dirname, '..', 'dashboard')\n    const replaceInDirectory = (dir: string) => {\n      for (const file of readdirSync(dir)) {\n        const filePath = join(dir, file)\n        if (statSync(filePath).isDirectory()) {\n          if (file === 'assets') {\n            replaceInDirectory(filePath)\n          }\n          continue\n        }\n        Logger.log(`Replacing %DAYTONA_BASE_API_URL% in ${filePath}`)\n        const fileContent = readFileSync(filePath, 'utf8')\n        const newFileContent = fileContent.replaceAll(\n          '%DAYTONA_BASE_API_URL%',\n          configService.get('dashboardBaseApiUrl'),\n        )\n        writeFileSync(filePath, newFileContent)\n      }\n    }\n    replaceInDirectory(dashboardDir)\n  }\n\n  // Starts listening for shutdown hooks\n  app.enableShutdownHooks()\n\n  const host = '0.0.0.0'\n  const port = configService.get('port')\n\n  if (isApiEnabled()) {\n    await app.listen(port, host)\n    Logger.log(`🚀 Daytona API is running on: http://${host}:${port}/${globalPrefix}`)\n  } else {\n    await app.init()\n    app.flushLogs()\n  }\n\n  if (isWorkerEnabled() && configService.get('kafka.enabled')) {\n    app.connectMicroservice<MicroserviceOptions>({\n      transport: Transport.KAFKA,\n      options: {\n        client: configService.getKafkaClientConfig(),\n        producer: {\n          allowAutoTopicCreation: true,\n          createPartitioner: Partitioners.DefaultPartitioner,\n          idempotent: true,\n        },\n        consumer: {\n          allowAutoTopicCreation: true,\n          groupId: 'daytona',\n        },\n        run: {\n          autoCommit: false,\n        },\n        subscribe: {\n          fromBeginning: true,\n        },\n      },\n    })\n    await app.startAllMicroservices()\n  }\n\n  // If app running in cluster mode, send ready signal\n  if (cluster.isWorker) {\n    process.send('ready')\n  }\n}\n\nasync function createAdminApiKey(app: INestApplication, apiKeyName: string) {\n  const apiKeyService = app.get(ApiKeyService)\n  const organizationService = app.get(OrganizationService)\n\n  const personalOrg = await organizationService.findPersonal(DAYTONA_ADMIN_USER_ID)\n  const { value } = await apiKeyService.createApiKey(personalOrg.id, DAYTONA_ADMIN_USER_ID, apiKeyName, [])\n  Logger.log(\n    `\n=========================================\n=========================================\nAdmin API key created: ${value}\n=========================================\n=========================================`,\n  )\n}\n\nbootstrap()\n"
  },
  {
    "path": "apps/api/src/migrations/1741087887225-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1741087887225 implements MigrationInterface {\n  name = 'Migration1741087887225'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`CREATE SCHEMA IF NOT EXISTS \"public\"`)\n    await queryRunner.query(\n      `CREATE TABLE \"user\" (\"id\" character varying NOT NULL, \"name\" character varying NOT NULL, \"keyPair\" text, \"publicKeys\" text NOT NULL, \"total_cpu_quota\" integer NOT NULL DEFAULT '10', \"total_memory_quota\" integer NOT NULL DEFAULT '40', \"total_disk_quota\" integer NOT NULL DEFAULT '100', \"max_cpu_per_workspace\" integer NOT NULL DEFAULT '2', \"max_memory_per_workspace\" integer NOT NULL DEFAULT '4', \"max_disk_per_workspace\" integer NOT NULL DEFAULT '10', \"max_concurrent_workspaces\" integer NOT NULL DEFAULT '10', \"workspace_quota\" integer NOT NULL DEFAULT '0', \"image_quota\" integer NOT NULL DEFAULT '5', \"max_image_size\" integer NOT NULL DEFAULT '2', \"total_image_size\" integer NOT NULL DEFAULT '5', CONSTRAINT \"PK_cace4a159ff9f2512dd42373760\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"team\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"name\" character varying NOT NULL, CONSTRAINT \"PK_f57d8293406df4af348402e4b74\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"workspace_usage_periods\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"workspaceId\" character varying NOT NULL, \"startAt\" TIMESTAMP NOT NULL, \"endAt\" TIMESTAMP, \"cpu\" double precision NOT NULL, \"gpu\" double precision NOT NULL, \"mem\" double precision NOT NULL, \"disk\" double precision NOT NULL, \"storage\" double precision NOT NULL, \"region\" character varying NOT NULL, CONSTRAINT \"PK_b8d71f79ee638064397f678e877\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(`CREATE TYPE \"node_class_enum\" AS ENUM('small', 'medium', 'large')`)\n    await queryRunner.query(`CREATE TYPE \"node_region_enum\" AS ENUM('eu', 'us', 'asia')`)\n    await queryRunner.query(\n      `CREATE TYPE \"node_state_enum\" AS ENUM('initializing', 'ready', 'disabled', 'decommissioned', 'unresponsive')`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"node\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"domain\" character varying NOT NULL, \"apiUrl\" character varying NOT NULL, \"apiKey\" character varying NOT NULL, \"cpu\" integer NOT NULL, \"memory\" integer NOT NULL, \"disk\" integer NOT NULL, \"gpu\" integer NOT NULL, \"gpuType\" character varying NOT NULL, \"class\" \"node_class_enum\" NOT NULL DEFAULT 'small', \"used\" integer NOT NULL DEFAULT '0', \"capacity\" integer NOT NULL, \"region\" \"node_region_enum\" NOT NULL, \"state\" \"node_state_enum\" NOT NULL DEFAULT 'initializing', \"lastChecked\" TIMESTAMP, \"unschedulable\" boolean NOT NULL DEFAULT false, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"UQ_330d74ac3d0e349b4c73c62ad6d\" UNIQUE (\"domain\"), CONSTRAINT \"PK_8c8caf5f29d25264abe9eaf94dd\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"image_node_state_enum\" AS ENUM('pulling_image', 'ready', 'error', 'removing')`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"image_node\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"state\" \"image_node_state_enum\" NOT NULL DEFAULT 'pulling_image', \"errorReason\" character varying, \"image\" character varying NOT NULL, \"internalImageName\" character varying NOT NULL DEFAULT '', \"nodeId\" character varying NOT NULL, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_6c66fc8bd2b9fb41362a50fddd0\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"image_state_enum\" AS ENUM('pending', 'pulling_image', 'pending_validation', 'validating', 'active', 'error', 'removing')`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"image\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"userId\" character varying NOT NULL, \"general\" boolean NOT NULL DEFAULT false, \"name\" character varying NOT NULL, \"internalName\" character varying, \"enabled\" boolean NOT NULL DEFAULT true, \"state\" \"image_state_enum\" NOT NULL DEFAULT 'pending', \"errorReason\" character varying, \"size\" double precision, \"entrypoint\" character varying, \"internalRegistryId\" character varying, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), \"lastUsedAt\" TIMESTAMP, CONSTRAINT \"UQ_9db6fbe71409d80375c32826db3\" UNIQUE (\"userId\", \"name\"), CONSTRAINT \"PK_d6db1ab4ee9ad9dbe86c64e4cc3\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(`CREATE TYPE \"workspace_region_enum\" AS ENUM('eu', 'us', 'asia')`)\n    await queryRunner.query(`CREATE TYPE \"workspace_class_enum\" AS ENUM('small', 'medium', 'large')`)\n    await queryRunner.query(\n      `CREATE TYPE \"workspace_state_enum\" AS ENUM('creating', 'restoring', 'destroyed', 'destroying', 'started', 'stopped', 'starting', 'stopping', 'resizing', 'error', 'unknown', 'pulling_image', 'archiving', 'archived')`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"workspace_desiredstate_enum\" AS ENUM('destroyed', 'started', 'stopped', 'resized', 'archived')`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"workspace_snapshotstate_enum\" AS ENUM('None', 'Pending', 'InProgress', 'Completed', 'Error')`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"workspace\" (\"id\" character varying NOT NULL, \"name\" character varying NOT NULL, \"userId\" character varying NOT NULL, \"region\" \"workspace_region_enum\" NOT NULL DEFAULT 'eu', \"nodeId\" uuid, \"prevNodeId\" uuid, \"class\" \"workspace_class_enum\" NOT NULL DEFAULT 'small', \"state\" \"workspace_state_enum\" NOT NULL DEFAULT 'unknown', \"desiredState\" \"workspace_desiredstate_enum\" NOT NULL DEFAULT 'started', \"image\" character varying NOT NULL, \"osUser\" character varying NOT NULL, \"errorReason\" character varying, \"env\" text NOT NULL DEFAULT '{}', \"public\" boolean NOT NULL DEFAULT false, \"labels\" jsonb, \"snapshotRegistryId\" character varying, \"snapshotImage\" character varying, \"lastSnapshotAt\" TIMESTAMP, \"snapshotState\" \"workspace_snapshotstate_enum\" NOT NULL DEFAULT 'None', \"existingSnapshotImages\" jsonb NOT NULL DEFAULT '[]', \"cpu\" integer NOT NULL DEFAULT '2', \"gpu\" integer NOT NULL DEFAULT '0', \"mem\" integer NOT NULL DEFAULT '4', \"disk\" integer NOT NULL DEFAULT '10', \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), \"lastActivityAt\" TIMESTAMP, \"autoStopInterval\" integer NOT NULL DEFAULT '15', CONSTRAINT \"PK_ca86b6f9b3be5fe26d307d09b49\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"docker_registry\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"name\" character varying NOT NULL, \"url\" character varying NOT NULL, \"username\" character varying NOT NULL, \"password\" character varying NOT NULL, \"isDefault\" boolean NOT NULL DEFAULT false, \"project\" character varying NOT NULL, \"userId\" character varying, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_4ad72294240279415eb57799798\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"api_key\" (\"userId\" character varying NOT NULL, \"name\" character varying NOT NULL, \"value\" character varying NOT NULL, \"createdAt\" TIMESTAMP NOT NULL, CONSTRAINT \"UQ_4b0873b633484d5de20b2d8f852\" UNIQUE (\"value\"), CONSTRAINT \"PK_1df0337a701df00e9b2a16c8a0b\" PRIMARY KEY (\"userId\", \"name\"))`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP TABLE \"api_key\"`)\n    await queryRunner.query(`DROP TABLE \"docker_registry\"`)\n    await queryRunner.query(`DROP TABLE \"workspace\"`)\n    await queryRunner.query(`DROP TYPE \"workspace_snapshotstate_enum\"`)\n    await queryRunner.query(`DROP TYPE \"workspace_desiredstate_enum\"`)\n    await queryRunner.query(`DROP TYPE \"workspace_state_enum\"`)\n    await queryRunner.query(`DROP TYPE \"workspace_class_enum\"`)\n    await queryRunner.query(`DROP TYPE \"workspace_region_enum\"`)\n    await queryRunner.query(`DROP TABLE \"image\"`)\n    await queryRunner.query(`DROP TYPE \"image_state_enum\"`)\n    await queryRunner.query(`DROP TABLE \"image_node\"`)\n    await queryRunner.query(`DROP TYPE \"image_node_state_enum\"`)\n    await queryRunner.query(`DROP TABLE \"node\"`)\n    await queryRunner.query(`DROP TYPE \"node_state_enum\"`)\n    await queryRunner.query(`DROP TYPE \"node_region_enum\"`)\n    await queryRunner.query(`DROP TYPE \"node_class_enum\"`)\n    await queryRunner.query(`DROP TABLE \"workspace_usage_periods\"`)\n    await queryRunner.query(`DROP TABLE \"team\"`)\n    await queryRunner.query(`DROP TABLE \"user\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1741088165704-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1741088165704 implements MigrationInterface {\n  name = 'Migration1741088165704'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"image\" DROP COLUMN \"internalRegistryId\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"docker_registry_registrytype_enum\" AS ENUM('internal', 'user', 'public', 'transient')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"docker_registry\" ADD \"registryType\" \"public\".\"docker_registry_registrytype_enum\" NOT NULL DEFAULT 'internal'`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" DROP COLUMN \"registryType\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"docker_registry_registrytype_enum\"`)\n    await queryRunner.query(`ALTER TABLE \"image\" ADD \"internalRegistryId\" character varying`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1741088883000-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1741088883000 implements MigrationInterface {\n  name = 'Migration1741088883000'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // organizations\n    await queryRunner.query(\n      `CREATE TABLE \"organization\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"name\" character varying NOT NULL, \"createdBy\" character varying NOT NULL, \"personal\" boolean NOT NULL DEFAULT false, \"telemetryEnabled\" boolean NOT NULL DEFAULT true, \"total_cpu_quota\" integer NOT NULL DEFAULT '10', \"total_memory_quota\" integer NOT NULL DEFAULT '40', \"total_disk_quota\" integer NOT NULL DEFAULT '100', \"max_cpu_per_workspace\" integer NOT NULL DEFAULT '2', \"max_memory_per_workspace\" integer NOT NULL DEFAULT '4', \"max_disk_per_workspace\" integer NOT NULL DEFAULT '10', \"max_concurrent_workspaces\" integer NOT NULL DEFAULT '10', \"workspace_quota\" integer NOT NULL DEFAULT '0', \"image_quota\" integer NOT NULL DEFAULT '5', \"max_image_size\" integer NOT NULL DEFAULT '2', \"total_image_size\" integer NOT NULL DEFAULT '5', \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"organization_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n\n    // organization users\n    await queryRunner.query(`CREATE TYPE \"public\".\"organization_user_role_enum\" AS ENUM('owner', 'member')`)\n    await queryRunner.query(\n      `CREATE TABLE \"organization_user\" (\"organizationId\" uuid NOT NULL, \"userId\" character varying NOT NULL, \"role\" \"public\".\"organization_user_role_enum\" NOT NULL DEFAULT 'member', \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"organization_user_organizationId_userId_pk\" PRIMARY KEY (\"organizationId\", \"userId\"))`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_user\" ADD CONSTRAINT \"organization_user_organizationId_fk\" FOREIGN KEY (\"organizationId\") REFERENCES \"organization\"(\"id\") ON DELETE CASCADE ON UPDATE NO ACTION`,\n    )\n\n    // organization invitations\n    await queryRunner.query(`CREATE TYPE \"public\".\"organization_invitation_role_enum\" AS ENUM('owner', 'member')`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"organization_invitation_status_enum\" AS ENUM('pending', 'accepted', 'declined', 'cancelled')`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"organization_invitation\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"organizationId\" uuid NOT NULL, \"email\" character varying NOT NULL, \"role\" \"public\".\"organization_invitation_role_enum\" NOT NULL DEFAULT 'member', \"expiresAt\" TIMESTAMP NOT NULL, \"status\" \"public\".\"organization_invitation_status_enum\" NOT NULL DEFAULT 'pending', \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"organization_invitation_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_invitation\" ADD CONSTRAINT \"organization_invitation_organizationId_fk\" FOREIGN KEY (\"organizationId\") REFERENCES \"organization\"(\"id\") ON DELETE CASCADE ON UPDATE NO ACTION`,\n    )\n\n    // organization roles\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"organization_role_permissions_enum\" AS ENUM('write:registries', 'delete:registries', 'write:images', 'delete:images', 'write:sandboxes', 'delete:sandboxes')`,\n    )\n    await queryRunner.query(\n      `CREATE TABLE \"organization_role\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"name\" character varying NOT NULL, \"description\" character varying NOT NULL, \"permissions\" \"public\".\"organization_role_permissions_enum\" array NOT NULL, \"isGlobal\" boolean NOT NULL DEFAULT false, \"organizationId\" uuid, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"organization_role_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role\" ADD CONSTRAINT \"organization_role_organizationId_fk\" FOREIGN KEY (\"organizationId\") REFERENCES \"organization\"(\"id\") ON DELETE CASCADE ON UPDATE NO ACTION`,\n    )\n\n    // organization role assignments for members\n    await queryRunner.query(\n      `CREATE TABLE \"organization_role_assignment\" (\"organizationId\" uuid NOT NULL, \"userId\" character varying NOT NULL, \"roleId\" uuid NOT NULL, CONSTRAINT \"organization_role_assignment_organizationId_userId_roleId_pk\" PRIMARY KEY (\"organizationId\", \"userId\", \"roleId\"))`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment\" ADD CONSTRAINT \"organization_role_assignment_organizationId_userId_fk\" FOREIGN KEY (\"organizationId\", \"userId\") REFERENCES \"organization_user\"(\"organizationId\",\"userId\") ON DELETE CASCADE ON UPDATE CASCADE`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment\" ADD CONSTRAINT \"organization_role_assignment_roleId_fk\" FOREIGN KEY (\"roleId\") REFERENCES \"organization_role\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE`,\n    )\n    await queryRunner.query(\n      `CREATE INDEX \"organization_role_assignment_organizationId_userId_index\" ON \"organization_role_assignment\" (\"organizationId\", \"userId\") `,\n    )\n    await queryRunner.query(\n      `CREATE INDEX \"organization_role_assignment_roleId_index\" ON \"organization_role_assignment\" (\"roleId\") `,\n    )\n\n    // organization role assignments for invitations\n    await queryRunner.query(\n      `CREATE TABLE \"organization_role_assignment_invitation\" (\"invitationId\" uuid NOT NULL, \"roleId\" uuid NOT NULL, CONSTRAINT \"organization_role_assignment_invitation_invitationId_roleId_pk\" PRIMARY KEY (\"invitationId\", \"roleId\"))`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment_invitation\" ADD CONSTRAINT \"organization_role_assignment_invitation_invitationId_fk\" FOREIGN KEY (\"invitationId\") REFERENCES \"organization_invitation\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment_invitation\" ADD CONSTRAINT \"organization_role_assignment_invitation_roleId_fk\" FOREIGN KEY (\"roleId\") REFERENCES \"organization_role\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE`,\n    )\n    await queryRunner.query(\n      `CREATE INDEX \"organization_role_assignment_invitation_invitationId_index\" ON \"organization_role_assignment_invitation\" (\"invitationId\") `,\n    )\n    await queryRunner.query(\n      `CREATE INDEX \"organization_role_assignment_invitation_roleId_index\" ON \"organization_role_assignment_invitation\" (\"roleId\") `,\n    )\n\n    // create personal organizations\n    await queryRunner.query(`\n        INSERT INTO \"organization\" (\n          name, \n          personal,\n          \"createdBy\", \n          total_cpu_quota,\n          total_memory_quota,\n          total_disk_quota,\n          max_cpu_per_workspace,\n          max_memory_per_workspace,\n          max_disk_per_workspace,\n          max_concurrent_workspaces,\n          workspace_quota,\n          image_quota,\n          max_image_size,\n          total_image_size\n        )\n        SELECT \n          'Personal',\n          true,\n          u.id,\n          u.total_cpu_quota,\n          u.total_memory_quota,\n          u.total_disk_quota,\n          u.max_cpu_per_workspace,\n          u.max_memory_per_workspace,\n          u.max_disk_per_workspace,\n          u.max_concurrent_workspaces,\n          u.workspace_quota,\n          u.image_quota,\n          u.max_image_size,\n          u.total_image_size\n        FROM \"user\" u\n    `)\n    await queryRunner.query(`\n        INSERT INTO \"organization_user\" (\"organizationId\", \"userId\", role)\n        SELECT \n          o.id,\n          o.\"createdBy\",\n          'owner'\n        FROM \"organization\" o\n        WHERE o.personal = true\n    `)\n\n    // drop user quotas\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"total_cpu_quota\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"total_memory_quota\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"total_disk_quota\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"max_cpu_per_workspace\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"max_memory_per_workspace\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"max_disk_per_workspace\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"max_concurrent_workspaces\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"workspace_quota\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"image_quota\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"max_image_size\"`)\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"total_image_size\"`)\n\n    // move existing api keys to corresponding personal organizations\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD \"organizationId\" uuid NULL`)\n    await queryRunner.query(`\n        UPDATE \"api_key\" ak\n        SET \"organizationId\" = (\n          SELECT o.id \n          FROM \"organization\" o\n          WHERE o.\"createdBy\" = ak.\"userId\" \n          AND o.personal = true\n          LIMIT 1\n        )\n    `)\n    await queryRunner.query(`ALTER TABLE \"api_key\" ALTER COLUMN \"organizationId\" SET NOT NULL`)\n\n    // update api key primary key\n    await queryRunner.query(`\n        DO $$\n        DECLARE\n            constraint_name text;\n        BEGIN\n            SELECT tc.constraint_name INTO constraint_name\n            FROM information_schema.table_constraints tc\n            WHERE tc.table_name = 'api_key' \n            AND tc.constraint_type = 'PRIMARY KEY';\n            IF constraint_name IS NOT NULL THEN\n            EXECUTE format('ALTER TABLE \"api_key\" DROP CONSTRAINT \"%s\"', constraint_name);\n            END IF;\n        END $$;\n    `)\n    await queryRunner.query(\n      `ALTER TABLE \"api_key\" ADD CONSTRAINT \"api_key_userId_name_organizationId_pk\" PRIMARY KEY (\"userId\", \"name\", \"organizationId\")`,\n    )\n\n    // api key permissions\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"api_key_permissions_enum\" AS ENUM('write:registries', 'delete:registries', 'write:images', 'delete:images', 'write:sandboxes', 'delete:sandboxes')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD \"permissions\" \"public\".\"api_key_permissions_enum\" array NULL`)\n    await queryRunner.query(`\n      UPDATE api_key\n      SET permissions = ARRAY[\n        'write:registries',\n        'delete:registries', \n        'write:images',\n        'delete:images',\n        'write:sandboxes',\n        'delete:sandboxes'\n      ]::api_key_permissions_enum[]\n    `)\n    await queryRunner.query(`ALTER TABLE \"api_key\" ALTER COLUMN \"permissions\" SET NOT NULL`)\n\n    // modify docker registry type enum\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"docker_registry_registrytype_enum\" RENAME TO \"docker_registry_registrytype_enum_old\"`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"docker_registry_registrytype_enum\" AS ENUM('internal', 'organization', 'public', 'transient')`,\n    )\n    await queryRunner.query(`\n      CREATE OR REPLACE FUNCTION migrate_registry_type(old_type text) \n      RETURNS \"public\".\"docker_registry_registrytype_enum\" AS $$\n      BEGIN\n        IF old_type = 'user' THEN\n          RETURN 'organization'::\"public\".\"docker_registry_registrytype_enum\";\n        ELSE\n          RETURN old_type::\"public\".\"docker_registry_registrytype_enum\";\n        END IF;\n      END;\n      $$ LANGUAGE plpgsql;\n    `)\n    await queryRunner.query(`\n      ALTER TABLE \"docker_registry\" \n      ALTER COLUMN \"registryType\" TYPE \"public\".\"docker_registry_registrytype_enum\" \n      USING migrate_registry_type(\"registryType\"::text)\n    `)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" SET DEFAULT 'internal'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"docker_registry_registrytype_enum_old\"`)\n    await queryRunner.query(`DROP FUNCTION migrate_registry_type`)\n\n    // move existing docker registries to corresponding personal organizations\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ADD \"organizationId\" uuid NULL`)\n    await queryRunner.query(`UPDATE \"docker_registry\" SET \"organizationId\" = NULL WHERE \"userId\" = 'system'`)\n    await queryRunner.query(`\n        UPDATE \"docker_registry\" dr\n        SET \"organizationId\" = (\n          SELECT o.id \n          FROM \"organization\" o\n          WHERE o.\"createdBy\" = dr.\"userId\" \n          AND o.personal = true\n          LIMIT 1\n        )\n    `)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" DROP COLUMN \"userId\"`)\n\n    // move existing images to corresponding personal organizations\n    await queryRunner.query(`ALTER TABLE \"image\" ADD \"organizationId\" uuid NULL`)\n    await queryRunner.query(`\n        UPDATE \"image\" i\n        SET \"organizationId\" = (\n          SELECT o.id \n          FROM \"organization\" o\n          WHERE o.\"createdBy\" = i.\"userId\" \n          AND o.personal = true\n          LIMIT 1\n        )\n    `)\n\n    // update image unique constraint\n    await queryRunner.query(`\n        DO $$\n        DECLARE\n            constraint_name text;\n        BEGIN\n            SELECT tc.constraint_name INTO constraint_name\n            FROM information_schema.table_constraints tc\n            WHERE tc.table_name = 'image' \n            AND tc.constraint_type = 'UNIQUE' \n            AND tc.constraint_name LIKE '%name%';\n            \n            IF constraint_name IS NOT NULL THEN\n            EXECUTE format('ALTER TABLE \"image\" DROP CONSTRAINT \"%s\"', constraint_name);\n            END IF;\n        END $$;\n    `)\n    await queryRunner.query(\n      `ALTER TABLE \"image\" ADD CONSTRAINT \"image_organizationId_name_unique\" UNIQUE (\"organizationId\", \"name\")`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image\" DROP COLUMN \"userId\"`)\n\n    // move existing workspaces to corresponding personal organizations\n    await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"organizationId\" uuid NULL`)\n    await queryRunner.query(`\n        UPDATE \"workspace\" w\n        SET \"organizationId\" = (\n          SELECT o.id \n          FROM \"organization\" o\n          WHERE o.\"createdBy\" = w.\"userId\" \n          AND o.personal = true\n          LIMIT 1\n        )\n        WHERE w.\"userId\" != 'unassigned'\n    `)\n    await queryRunner.query(`\n        UPDATE \"workspace\" w\n        SET \"organizationId\" = '00000000-0000-0000-0000-000000000000'\n        WHERE w.\"userId\" = 'unassigned'\n    `)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"organizationId\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"userId\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // workspaces\n    await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"userId\" character varying NULL`)\n    await queryRunner.query(`\n        UPDATE \"workspace\" w\n        SET \"userId\" = 'unassigned'\n        WHERE w.\"organizationId\" = '00000000-0000-0000-0000-000000000000'\n    `)\n    await queryRunner.query(`\n        UPDATE \"workspace\" w\n        SET \"userId\" = (\n          SELECT o.\"createdBy\" \n          FROM \"organization\" o\n          WHERE o.id = w.\"organizationId\"\n        )\n        WHERE w.\"organizationId\" != '00000000-0000-0000-0000-000000000000'\n    `)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"userId\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"organizationId\"`)\n\n    // images\n    await queryRunner.query(`ALTER TABLE \"image\" ADD \"userId\" character varying NULL`)\n    await queryRunner.query(`\n        UPDATE \"image\" i\n        SET \"userId\" = (\n          SELECT o.\"createdBy\" \n          FROM \"organization\" o\n          WHERE o.id = i.\"organizationId\"\n        )\n    `)\n    await queryRunner.query(`ALTER TABLE \"image\" ALTER COLUMN \"userId\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"image\" DROP CONSTRAINT \"image_organizationId_name_unique\"`)\n    await queryRunner.query(`ALTER TABLE \"image\" ADD CONSTRAINT \"image_userId_name_unique\" UNIQUE (\"userId\", \"name\")`)\n    await queryRunner.query(`ALTER TABLE \"image\" DROP COLUMN \"organizationId\"`)\n\n    // docker registries\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"docker_registry_registrytype_enum\" RENAME TO \"docker_registry_registrytype_enum_old\"`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"docker_registry_registrytype_enum\" AS ENUM('internal', 'user', 'public', 'transient')`,\n    )\n    await queryRunner.query(`\n    CREATE OR REPLACE FUNCTION rollback_registry_type(new_type text) \n    RETURNS \"public\".\"docker_registry_registrytype_enum\" AS $$\n    BEGIN\n      IF new_type = 'organization' THEN\n        RETURN 'user'::\"public\".\"docker_registry_registrytype_enum\";\n      ELSE\n        RETURN new_type::\"public\".\"docker_registry_registrytype_enum\";\n      END IF;\n    END;\n    $$ LANGUAGE plpgsql;\n  `)\n    await queryRunner.query(`\n    ALTER TABLE \"docker_registry\" \n    ALTER COLUMN \"registryType\" TYPE \"public\".\"docker_registry_registrytype_enum\" \n    USING rollback_registry_type(\"registryType\"::text)\n  `)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" SET DEFAULT 'internal'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"docker_registry_registrytype_enum_old\"`)\n    await queryRunner.query(`DROP FUNCTION rollback_registry_type`)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ADD \"userId\" character varying NULL`)\n    await queryRunner.query(`\n        UPDATE \"docker_registry\" dr\n        SET \"userId\" = (\n          SELECT o.\"createdBy\" \n          FROM \"organization\" o\n          WHERE o.id = dr.\"organizationId\"\n        )\n    `)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" DROP COLUMN \"organizationId\"`)\n\n    // api keys\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP CONSTRAINT \"api_key_userId_name_organizationId_pk\"`)\n    await queryRunner.query(\n      `ALTER TABLE \"api_key\" ADD CONSTRAINT \"api_key_userId_name_pk\" PRIMARY KEY (\"userId\", \"name\")`,\n    )\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP COLUMN \"organizationId\"`)\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP COLUMN \"permissions\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"api_key_permissions_enum\"`)\n\n    // user quotas\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"total_cpu_quota\" integer NOT NULL DEFAULT '10'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"total_memory_quota\" integer NOT NULL DEFAULT '40'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"total_disk_quota\" integer NOT NULL DEFAULT '100'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"max_cpu_per_workspace\" integer NOT NULL DEFAULT '2'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"max_memory_per_workspace\" integer NOT NULL DEFAULT '4'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"max_disk_per_workspace\" integer NOT NULL DEFAULT '10'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"max_concurrent_workspaces\" integer NOT NULL DEFAULT '10'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"workspace_quota\" integer NOT NULL DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"image_quota\" integer NOT NULL DEFAULT '5'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"max_image_size\" integer NOT NULL DEFAULT '2'`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"total_image_size\" integer NOT NULL DEFAULT '5'`)\n    await queryRunner.query(`\n        UPDATE \"user\" u\n        SET \n          total_cpu_quota = (\n            SELECT o.total_cpu_quota\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          total_memory_quota = (\n            SELECT o.total_memory_quota\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          total_disk_quota = (\n            SELECT o.total_disk_quota\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          max_cpu_per_workspace = (\n            SELECT o.max_cpu_per_workspace\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          max_memory_per_workspace = (\n            SELECT o.max_memory_per_workspace\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          max_disk_per_workspace = (\n            SELECT o.max_disk_per_workspace\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          max_concurrent_workspaces = (\n            SELECT o.max_concurrent_workspaces\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          workspace_quota = (\n            SELECT o.workspace_quota\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          image_quota = (\n            SELECT o.image_quota\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          max_image_size = (\n            SELECT o.max_image_size\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          ),\n          total_image_size = (\n            SELECT o.total_image_size\n            FROM \"organization\" o\n            WHERE o.\"createdBy\" = u.id\n            AND o.personal = true\n            LIMIT 1\n          )\n    `)\n\n    // drop organization tables and related constraints\n    await queryRunner.query(`DROP INDEX \"organization_role_assignment_invitation_roleId_index\"`)\n    await queryRunner.query(`DROP INDEX \"organization_role_assignment_invitation_invitationId_index\"`)\n    await queryRunner.query(`DROP TABLE \"organization_role_assignment_invitation\"`)\n    await queryRunner.query(`DROP INDEX \"organization_role_assignment_roleId_index\"`)\n    await queryRunner.query(`DROP INDEX \"organization_role_assignment_organizationId_userId_index\"`)\n    await queryRunner.query(`DROP TABLE \"organization_role_assignment\"`)\n    await queryRunner.query(`DROP TABLE \"organization_role\"`)\n    await queryRunner.query(`DROP TYPE \"organization_role_permissions_enum\"`)\n    await queryRunner.query(`DROP TABLE \"organization_invitation\"`)\n    await queryRunner.query(`DROP TYPE \"organization_invitation_status_enum\"`)\n    await queryRunner.query(`DROP TYPE \"organization_invitation_role_enum\"`)\n    await queryRunner.query(`DROP TABLE \"organization_user\"`)\n    await queryRunner.query(`DROP TYPE \"organization_user_role_enum\"`)\n    await queryRunner.query(`DROP TABLE \"organization\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1741088883001-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1741088883001 implements MigrationInterface {\n  name = 'Migration1741088883001'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"email\" character varying NOT NULL DEFAULT ''`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"email\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1741088883002-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport { GlobalOrganizationRolesIds } from '../organization/constants/global-organization-roles.constant'\nimport { OrganizationResourcePermission } from '../organization/enums/organization-resource-permission.enum'\n\nexport class Migration1741088883002 implements MigrationInterface {\n  name = 'Migration1741088883002'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`\n      INSERT INTO \"organization_role\" \n        (\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\")\n      VALUES \n        (\n          '${GlobalOrganizationRolesIds.DEVELOPER}',\n          'Developer', \n          'Grants the ability to create sandboxes and keys in the organization', \n          ARRAY[\n            '${OrganizationResourcePermission.WRITE_SANDBOXES}'\n          ]::organization_role_permissions_enum[],\n          TRUE\n        )\n    `)\n\n    await queryRunner.query(`\n      INSERT INTO \"organization_role\" \n        (\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\")\n      VALUES \n        (\n          '${GlobalOrganizationRolesIds.SANDBOXES_ADMIN}',\n          'Sandboxes Admin', \n          'Grants admin access to sandboxes in the organization', \n          ARRAY[\n            '${OrganizationResourcePermission.WRITE_SANDBOXES}',\n            '${OrganizationResourcePermission.DELETE_SANDBOXES}'\n          ]::organization_role_permissions_enum[],\n          TRUE\n        )\n    `)\n\n    await queryRunner.query(`\n      INSERT INTO \"organization_role\" \n        (\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\")\n      VALUES \n        (\n          '${GlobalOrganizationRolesIds.SNAPSHOTS_ADMIN}',\n          'Images Admin', \n          'Grants admin access to images in the organization', \n          ARRAY[\n            'write:images',\n            'delete:images'\n          ]::organization_role_permissions_enum[],\n          TRUE\n        )\n    `)\n\n    await queryRunner.query(`\n      INSERT INTO \"organization_role\" \n        (\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\")\n      VALUES \n        (\n          '${GlobalOrganizationRolesIds.REGISTRIES_ADMIN}',\n          'Registries Admin', \n          'Grants admin access to registries in the organization', \n          ARRAY[\n            '${OrganizationResourcePermission.WRITE_REGISTRIES}',\n            '${OrganizationResourcePermission.DELETE_REGISTRIES}'\n          ]::organization_role_permissions_enum[],\n          TRUE\n        )\n    `)\n\n    await queryRunner.query(`\n      INSERT INTO \"organization_role\" \n        (\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\")\n      VALUES \n        (\n          '${GlobalOrganizationRolesIds.SUPER_ADMIN}',\n          'Super Admin', \n          'Grants full access to all resources in the organization', \n          ARRAY[\n            '${OrganizationResourcePermission.WRITE_REGISTRIES}',\n            '${OrganizationResourcePermission.DELETE_REGISTRIES}',\n            'write:images',\n            'delete:images',\n            '${OrganizationResourcePermission.WRITE_SANDBOXES}',\n            '${OrganizationResourcePermission.DELETE_SANDBOXES}'\n          ]::organization_role_permissions_enum[],\n          TRUE\n        )\n    `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DELETE FROM \"organization_role\" WHERE \"isGlobal\" = TRUE`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1741877019888-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1741877019888 implements MigrationInterface {\n  name = 'Migration1741877019888'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`CREATE TYPE \"public\".\"warm_pool_target_enum\" AS ENUM('eu', 'us', 'asia')`)\n    await queryRunner.query(`CREATE TYPE \"public\".\"warm_pool_class_enum\" AS ENUM('small', 'medium', 'large')`)\n    await queryRunner.query(\n      `CREATE TABLE \"warm_pool\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"pool\" integer NOT NULL, \"image\" character varying NOT NULL, \"target\" \"public\".\"warm_pool_target_enum\" NOT NULL DEFAULT 'eu', \"cpu\" integer NOT NULL, \"mem\" integer NOT NULL, \"disk\" integer NOT NULL, \"gpu\" integer NOT NULL, \"gpuType\" character varying NOT NULL, \"class\" \"public\".\"warm_pool_class_enum\" NOT NULL DEFAULT 'small', \"osUser\" character varying NOT NULL, \"errorReason\" character varying, \"env\" text NOT NULL DEFAULT '{}', \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"PK_fb06a13baeb3ac0ced145345d90\" PRIMARY KEY (\"id\"))`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP TABLE \"warm_pool\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"warm_pool_class_enum\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"warm_pool_target_enum\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1742215525714-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1742215525714 implements MigrationInterface {\n  name = 'Migration1742215525714'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"image_quota\" SET DEFAULT '0'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"image_quota\" SET DEFAULT '5'`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1742475055353-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1742475055353 implements MigrationInterface {\n  name = 'Migration1742475055353'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`CREATE TYPE \"public\".\"user_role_enum\" AS ENUM('admin', 'user')`)\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"role\" \"public\".\"user_role_enum\" NOT NULL DEFAULT 'user'`)\n\n    await queryRunner.query(`UPDATE \"user\" SET \"role\" = 'admin' WHERE \"id\" = 'daytona-admin'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"role\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"user_role_enum\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1742831092942-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1742831092942 implements MigrationInterface {\n  name = 'Migration1742831092942'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"pending\" boolean NOT NULL DEFAULT false`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"pending\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1743593463168-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1743593463168 implements MigrationInterface {\n  name = 'Migration1743593463168'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `ALTER TABLE \"organization_invitation\" ADD \"invitedBy\" character varying NOT NULL DEFAULT ''`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization_invitation\" DROP COLUMN \"invitedBy\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1743683015304-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1743683015304 implements MigrationInterface {\n  name = 'Migration1743683015304'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"name\"`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP CONSTRAINT \"PK_ca86b6f9b3be5fe26d307d09b49\"`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"id\" SET DEFAULT uuid_generate_v4()`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ADD CONSTRAINT \"workspace_id_pk\" PRIMARY KEY (\"id\")`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP CONSTRAINT \"workspace_id_pk\"`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"id\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"workspace\" ADD CONSTRAINT \"PK_ca86b6f9b3be5fe26d307d09b49\" PRIMARY KEY (\"id\")`,\n    )\n    await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"name\" character varying NOT NULL DEFAULT ''`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"name\" DROP DEFAULT`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1744028841133-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1744028841133 implements MigrationInterface {\n  name = 'Migration1744028841133'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace_usage_periods\" DROP COLUMN \"storage\"`)\n    await queryRunner.query(`ALTER TABLE \"workspace_usage_periods\" ADD \"organizationId\" character varying NOT NULL`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace_usage_periods\" DROP COLUMN \"organizationId\"`)\n    await queryRunner.query(`ALTER TABLE \"workspace_usage_periods\" ADD \"storage\" double precision NOT NULL`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1744114341077-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1744114341077 implements MigrationInterface {\n  name = 'Migration1744114341077'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment\" DROP CONSTRAINT \"organization_role_assignment_roleId_fk\"`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment_invitation\" DROP CONSTRAINT \"organization_role_assignment_invitation_roleId_fk\"`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"workspace\" ADD \"authToken\" character varying NOT NULL DEFAULT MD5(random()::text)`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment\" ADD CONSTRAINT \"organization_role_assignment_roleId_fk\" FOREIGN KEY (\"roleId\") REFERENCES \"organization_role\"(\"id\") ON DELETE NO ACTION ON UPDATE NO ACTION`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment_invitation\" ADD CONSTRAINT \"organization_role_assignment_invitation_roleId_fk\" FOREIGN KEY (\"roleId\") REFERENCES \"organization_role\"(\"id\") ON DELETE NO ACTION ON UPDATE NO ACTION`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment_invitation\" DROP CONSTRAINT \"organization_role_assignment_invitation_roleId_fk\"`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment\" DROP CONSTRAINT \"organization_role_assignment_roleId_fk\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"authToken\"`)\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment_invitation\" ADD CONSTRAINT \"organization_role_assignment_invitation_roleId_fk\" FOREIGN KEY (\"roleId\") REFERENCES \"organization_role\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment\" ADD CONSTRAINT \"organization_role_assignment_roleId_fk\" FOREIGN KEY (\"roleId\") REFERENCES \"organization_role\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE`,\n    )\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1744378115901-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1744378115901 implements MigrationInterface {\n  name = 'Migration1744378115901'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"suspended\" boolean NOT NULL DEFAULT false`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"suspensionReason\" character varying`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"suspendedUntil\" TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"suspendedAt\" TIMESTAMP`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"suspendedAt\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"suspendedUntil\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"suspensionReason\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"suspended\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1744808444807-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1744808444807 implements MigrationInterface {\n  name = 'Migration1744808444807'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TABLE \"volume\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"organizationId\" uuid, \"name\" character varying NOT NULL, \"state\" character varying NOT NULL, \"errorReason\" character varying, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), \"lastUsedAt\" TIMESTAMP, CONSTRAINT \"volume_organizationId_name_unique\" UNIQUE (\"organizationId\", \"name\"), CONSTRAINT \"volume_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"authToken\" SET DEFAULT MD5(random()::text)`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"authToken\" SET DEFAULT md5((random()))`)\n    await queryRunner.query(`DROP TABLE \"volume\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1744868914148-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport { GlobalOrganizationRolesIds } from '../organization/constants/global-organization-roles.constant'\nimport { OrganizationResourcePermission } from '../organization/enums/organization-resource-permission.enum'\n\nexport class Migration1744868914148 implements MigrationInterface {\n  name = 'Migration1744868914148'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // update enums\n    await queryRunner.query(`ALTER TYPE \"public\".\"api_key_permissions_enum\" RENAME TO \"api_key_permissions_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"api_key_permissions_enum\" AS ENUM('write:registries', 'delete:registries', 'write:images', 'delete:images', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"api_key\" ALTER COLUMN \"permissions\" TYPE \"public\".\"api_key_permissions_enum\"[] USING \"permissions\"::\"text\"::\"public\".\"api_key_permissions_enum\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"api_key_permissions_enum_old\"`)\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum\" RENAME TO \"organization_role_permissions_enum_old\"`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"organization_role_permissions_enum\" AS ENUM('write:registries', 'delete:registries', 'write:images', 'delete:images', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role\" ALTER COLUMN \"permissions\" TYPE \"public\".\"organization_role_permissions_enum\"[] USING \"permissions\"::\"text\"::\"public\".\"organization_role_permissions_enum\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"organization_role_permissions_enum_old\"`)\n\n    // add volumes admin role\n    await queryRunner.query(`\n            INSERT INTO \"organization_role\" \n              (\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\")\n            VALUES \n              (\n                '${GlobalOrganizationRolesIds.VOLUMES_ADMIN}',    \n                'Volumes Admin', \n                'Grants admin access to volumes in the organization', \n                ARRAY[\n                  '${OrganizationResourcePermission.READ_VOLUMES}',\n                  '${OrganizationResourcePermission.WRITE_VOLUMES}',\n                  '${OrganizationResourcePermission.DELETE_VOLUMES}'\n                ]::organization_role_permissions_enum[],\n                TRUE\n              )\n          `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // remove volumes admin role\n    await queryRunner.query(\n      `DELETE FROM \"organization_role\" WHERE \"id\" = '${GlobalOrganizationRolesIds.VOLUMES_ADMIN}'`,\n    )\n\n    // revert enums\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"organization_role_permissions_enum_old\" AS ENUM('write:registries', 'delete:registries', 'write:images', 'delete:images', 'write:sandboxes', 'delete:sandboxes')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role\" ALTER COLUMN \"permissions\" TYPE \"public\".\"organization_role_permissions_enum_old\"[] USING \"permissions\"::\"text\"::\"public\".\"organization_role_permissions_enum_old\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"organization_role_permissions_enum\"`)\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum_old\" RENAME TO \"organization_role_permissions_enum\"`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"api_key_permissions_enum_old\" AS ENUM('write:registries', 'delete:registries', 'write:images', 'delete:images', 'write:sandboxes', 'delete:sandboxes')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"api_key\" ALTER COLUMN \"permissions\" TYPE \"public\".\"api_key_permissions_enum_old\"[] USING \"permissions\"::\"text\"::\"public\".\"api_key_permissions_enum_old\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"api_key_permissions_enum\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"api_key_permissions_enum_old\" RENAME TO \"api_key_permissions_enum\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1744971114480-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1744971114480 implements MigrationInterface {\n  name = 'Migration1744971114480'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"volumes\" jsonb NOT NULL DEFAULT '[]'`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"authToken\" SET DEFAULT MD5(random()::text)`)\n    await queryRunner.query(`ALTER TABLE \"volume\" DROP COLUMN \"state\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"volume_state_enum\" AS ENUM('creating', 'ready', 'pending_create', 'pending_delete', 'deleting', 'deleted', 'error')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"volume\" ADD \"state\" \"public\".\"volume_state_enum\" NOT NULL DEFAULT 'pending_create'`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"volume\" DROP COLUMN \"state\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"volume_state_enum\"`)\n    await queryRunner.query(`ALTER TABLE \"volume\" ADD \"state\" character varying NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"authToken\" SET DEFAULT md5((random()))`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"volumes\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1745393243334-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1745393243334 implements MigrationInterface {\n  name = 'Migration1745393243334'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // First, get all images with their current entrypoint values\n    const images = await queryRunner.query(`SELECT id, entrypoint FROM \"image\" WHERE entrypoint IS NOT NULL`)\n\n    // Rename the column to avoid data loss\n    await queryRunner.query(`ALTER TABLE \"image\" RENAME COLUMN \"entrypoint\" TO \"entrypoint_old\"`)\n\n    // Add the new jsonb column\n    await queryRunner.query(`ALTER TABLE \"image\" ADD \"entrypoint\" text[]`)\n\n    // Update each image to convert the string entrypoint to a JSON array\n    for (const image of images) {\n      const entrypointValue = image.entrypoint\n      if (entrypointValue) {\n        // Convert the string to a JSON array with a single element\n        await queryRunner.query(`UPDATE \"image\" SET \"entrypoint\" = $1 WHERE id = $2`, [\n          entrypointValue.split(' '),\n          image.id,\n        ])\n      }\n    }\n\n    // Drop the old column\n    await queryRunner.query(`ALTER TABLE \"image\" DROP COLUMN \"entrypoint_old\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // First, get all images with their current entrypoint values\n    const images = await queryRunner.query(`SELECT id, entrypoint FROM \"image\" WHERE entrypoint IS NOT NULL`)\n\n    // Rename the column to avoid data loss\n    await queryRunner.query(`ALTER TABLE \"image\" RENAME COLUMN \"entrypoint\" TO \"entrypoint_old\"`)\n\n    // Add the new character varying column\n    await queryRunner.query(`ALTER TABLE \"image\" ADD \"entrypoint\" character varying`)\n\n    // Update each image to convert the JSON array to a string\n    for (const image of images) {\n      const entrypointArray = image.entrypoint_old\n      if (entrypointArray && Array.isArray(entrypointArray) && entrypointArray.length > 0) {\n        // Take the first element of the array as the string value\n        await queryRunner.query(`UPDATE \"image\" SET \"entrypoint\" = $1 WHERE id = $2`, [entrypointArray[0], image.id])\n      }\n    }\n\n    // Drop the old column\n    await queryRunner.query(`ALTER TABLE \"image\" DROP COLUMN \"entrypoint_old\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1745494761360-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1745494761360 implements MigrationInterface {\n  name = 'Migration1745494761360'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"emailVerified\" boolean NOT NULL DEFAULT false`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"emailVerified\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1745574377029-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1745574377029 implements MigrationInterface {\n  name = 'Migration1745574377029'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TABLE \"build_info\" (\"imageRef\" character varying NOT NULL, \"dockerfileContent\" text, \"contextHashes\" text, \"lastUsedAt\" TIMESTAMP NOT NULL DEFAULT now(), \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"build_info_imageRef_pk\" PRIMARY KEY (\"imageRef\"))`,\n    )\n    await queryRunner.renameColumn('image_node', 'internalImageName', 'imageRef')\n    await queryRunner.query(`ALTER TABLE \"image_node\" DROP COLUMN \"image\"`)\n    await queryRunner.query(`ALTER TABLE \"image\" ADD \"buildInfoImageRef\" character varying`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"buildInfoImageRef\" character varying`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"image_node_state_enum\" RENAME TO \"image_node_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"image_node_state_enum\" AS ENUM('pulling_image', 'building_image', 'ready', 'error', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image_node\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"image_node\" ALTER COLUMN \"state\" TYPE \"public\".\"image_node_state_enum\" USING \"state\"::\"text\"::\"public\".\"image_node_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image_node\" ALTER COLUMN \"state\" SET DEFAULT 'pulling_image'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"image_node_state_enum_old\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"image_state_enum\" RENAME TO \"image_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"image_state_enum\" AS ENUM('build_pending', 'building', 'pending', 'pulling_image', 'pending_validation', 'validating', 'active', 'error', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"image\" ALTER COLUMN \"state\" TYPE \"public\".\"image_state_enum\" USING \"state\"::\"text\"::\"public\".\"image_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"image_state_enum_old\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"workspace_state_enum\" RENAME TO \"workspace_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"workspace_state_enum\" AS ENUM('creating', 'restoring', 'destroyed', 'destroying', 'started', 'stopped', 'starting', 'stopping', 'resizing', 'error', 'pending_build', 'building_image', 'unknown', 'pulling_image', 'archiving', 'archived')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"workspace\" ALTER COLUMN \"state\" TYPE \"public\".\"workspace_state_enum\" USING \"state\"::\"text\"::\"public\".\"workspace_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"state\" SET DEFAULT 'unknown'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"workspace_state_enum_old\"`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"image\" DROP NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"authToken\" SET DEFAULT MD5(random()::text)`)\n    await queryRunner.query(\n      `ALTER TABLE \"image\" ADD CONSTRAINT \"image_buildInfoImageRef_fk\" FOREIGN KEY (\"buildInfoImageRef\") REFERENCES \"build_info\"(\"imageRef\") ON DELETE NO ACTION ON UPDATE NO ACTION`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"workspace\" ADD CONSTRAINT \"workspace_buildInfoImageRef_fk\" FOREIGN KEY (\"buildInfoImageRef\") REFERENCES \"build_info\"(\"imageRef\") ON DELETE NO ACTION ON UPDATE NO ACTION`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP CONSTRAINT \"workspace_buildInfoImageRef_fk\"`)\n    await queryRunner.query(`ALTER TABLE \"image\" DROP CONSTRAINT \"image_buildInfoImageRef_fk\"`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"authToken\" SET DEFAULT md5((random()))`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"image\" SET NOT NULL`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"workspace_state_enum_old\" AS ENUM('archived', 'archiving', 'creating', 'destroyed', 'destroying', 'error', 'pulling_image', 'resizing', 'restoring', 'started', 'starting', 'stopped', 'stopping', 'unknown')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"workspace\" ALTER COLUMN \"state\" TYPE \"public\".\"workspace_state_enum_old\" USING \"state\"::\"text\"::\"public\".\"workspace_state_enum_old\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"workspace\" ALTER COLUMN \"state\" SET DEFAULT 'unknown'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"workspace_state_enum\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"workspace_state_enum_old\" RENAME TO \"workspace_state_enum\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"image_state_enum_old\" AS ENUM('active', 'error', 'pending', 'pending_validation', 'pulling_image', 'removing', 'validating')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"image\" ALTER COLUMN \"state\" TYPE \"public\".\"image_state_enum_old\" USING \"state\"::\"text\"::\"public\".\"image_state_enum_old\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"image_state_enum\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"image_state_enum_old\" RENAME TO \"image_state_enum\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"image_node_state_enum_old\" AS ENUM('error', 'pulling_image', 'ready', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image_node\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"image_node\" ALTER COLUMN \"state\" TYPE \"public\".\"image_node_state_enum_old\" USING \"state\"::\"text\"::\"public\".\"image_node_state_enum_old\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"image_node\" ALTER COLUMN \"state\" SET DEFAULT 'pulling_image'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"image_node_state_enum\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"image_node_state_enum_old\" RENAME TO \"image_node_state_enum\"`)\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"buildInfoImageRef\"`)\n    await queryRunner.query(`ALTER TABLE \"image\" DROP COLUMN \"buildInfoImageRef\"`)\n    await queryRunner.renameColumn('image_node', 'imageRef', 'internalImageName')\n    await queryRunner.query(`ALTER TABLE \"image_node\" ADD \"image\" character varying NOT NULL`)\n    await queryRunner.query(`DROP TABLE \"build_info\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1745840296260-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport * as crypto from 'crypto'\n\nexport class Migration1745840296260 implements MigrationInterface {\n  name = 'Migration1745840296260'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Add the new columns\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD \"keyHash\" character varying NOT NULL DEFAULT ''`)\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD \"keyPrefix\" character varying NOT NULL DEFAULT ''`)\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD \"keySuffix\" character varying NOT NULL DEFAULT ''`)\n\n    // Get all existing API keys\n    const existingKeys = await queryRunner.query(`SELECT \"value\" FROM \"api_key\"`)\n\n    // Update each key with its hash, prefix, and suffix\n    for (const key of existingKeys) {\n      const value = key.value\n      const keyHash = crypto.createHash('sha256').update(value).digest('hex')\n      const keyPrefix = value.substring(0, 3)\n      const keySuffix = value.slice(-3)\n\n      await queryRunner.query(\n        `UPDATE \"api_key\" \n                SET \"keyHash\" = $1, \n                    \"keyPrefix\" = $2, \n                    \"keySuffix\" = $3 \n                WHERE \"value\" = $4`,\n        [keyHash, keyPrefix, keySuffix, value],\n      )\n    }\n\n    // Drop value column and its unique constraint\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP CONSTRAINT \"UQ_4b0873b633484d5de20b2d8f852\"`)\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP COLUMN \"value\"`)\n\n    // Add unique constraint\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD CONSTRAINT \"api_key_keyHash_unique\" UNIQUE (\"keyHash\")`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Revert the schema changes\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP CONSTRAINT \"api_key_keyHash_unique\"`)\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP COLUMN \"keySuffix\"`)\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP COLUMN \"keyPrefix\"`)\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP COLUMN \"keyHash\"`)\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD \"value\" character varying NOT NULL DEFAULT ''`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1745864972652-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1745864972652 implements MigrationInterface {\n  name = 'Migration1745864972652'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`\n            ALTER TABLE \"workspace\"\n              ALTER COLUMN \"env\" DROP DEFAULT,\n              ALTER COLUMN \"env\" TYPE jsonb USING \"env\"::jsonb,\n              ALTER COLUMN \"env\" SET DEFAULT '{}'::jsonb,\n              ALTER COLUMN \"env\" SET NOT NULL;\n          `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`\n            ALTER TABLE \"workspace\"\n              ALTER COLUMN \"env\" DROP DEFAULT,\n              ALTER COLUMN \"env\" TYPE text USING \"env\"::text,\n              ALTER COLUMN \"env\" SET DEFAULT '{}'::text,\n              ALTER COLUMN \"env\" SET NOT NULL;\n          `)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1746354231722-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1746354231722 implements MigrationInterface {\n  name = 'Migration1746354231722'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"image\" ADD \"buildNodeId\" character varying`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"image\" DROP COLUMN \"buildNodeId\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1746604150910-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1746604150910 implements MigrationInterface {\n  name = 'Migration1746604150910'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"volume_quota\" integer NOT NULL DEFAULT '10'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"volume_quota\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1747658203010-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1747658203010 implements MigrationInterface {\n  name = 'Migration1747658203010'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD \"lastUsedAt\" TIMESTAMP`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP COLUMN \"lastUsedAt\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1748006546552-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1748006546552 implements MigrationInterface {\n  name = 'Migration1748006546552'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"max_concurrent_workspaces\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"workspace_quota\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"total_image_size\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"total_memory_quota\" SET DEFAULT '10'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"total_disk_quota\" SET DEFAULT '30'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"max_cpu_per_workspace\" SET DEFAULT '4'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"max_memory_per_workspace\" SET DEFAULT '8'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"max_image_size\" SET DEFAULT '20'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"image_quota\" SET DEFAULT '100'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"volume_quota\" SET DEFAULT '100'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"volume_quota\" SET DEFAULT '10'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"image_quota\" SET DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"max_image_size\" SET DEFAULT '2'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"max_memory_per_workspace\" SET DEFAULT '4'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"max_cpu_per_workspace\" SET DEFAULT '2'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"total_disk_quota\" SET DEFAULT '100'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"total_memory_quota\" SET DEFAULT '40'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"total_image_size\" integer NOT NULL DEFAULT '5'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"workspace_quota\" integer NOT NULL DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"max_concurrent_workspaces\" integer NOT NULL DEFAULT '10'`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1748866194353-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1748866194353 implements MigrationInterface {\n  name = 'Migration1748866194353'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"autoArchiveInterval\" integer NOT NULL DEFAULT '10080'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"autoArchiveInterval\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1749474791343-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1749474791343 implements MigrationInterface {\n  name = 'Migration1749474791343'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"api_key\" ADD \"expiresAt\" TIMESTAMP`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"api_key\" DROP COLUMN \"expiresAt\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1749474791344-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1749474791344 implements MigrationInterface {\n  name = 'Migration1749474791344'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Snapshot to backup rename\n    await queryRunner.renameColumn('workspace', 'snapshotRegistryId', 'backupRegistryId')\n    await queryRunner.renameColumn('workspace', 'snapshotImage', 'backupImage')\n    await queryRunner.renameColumn('workspace', 'lastSnapshotAt', 'lastBackupAt')\n    await queryRunner.renameColumn('workspace', 'snapshotState', 'backupState')\n    await queryRunner.renameColumn('workspace', 'existingSnapshotImages', 'existingBackupImages')\n\n    // Node to runner rename\n    await queryRunner.renameColumn('image', 'buildNodeId', 'buildRunnerId')\n    await queryRunner.renameTable('image_node', 'image_runner')\n    await queryRunner.renameColumn('image_runner', 'nodeId', 'runnerId')\n    await queryRunner.renameTable('node', 'runner')\n    await queryRunner.renameColumn('workspace', 'nodeId', 'runnerId')\n    await queryRunner.renameColumn('workspace', 'prevNodeId', 'prevRunnerId')\n\n    // Image to snapshot rename\n    await queryRunner.renameColumn('warm_pool', 'image', 'snapshot')\n    await queryRunner.renameColumn('organization', 'image_quota', 'snapshot_quota')\n    await queryRunner.renameColumn('organization', 'max_image_size', 'max_snapshot_size')\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum\" RENAME VALUE 'write:images' TO 'write:snapshots'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum\" RENAME VALUE 'delete:images' TO 'delete:snapshots'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"api_key_permissions_enum\" RENAME VALUE 'write:images' TO 'write:snapshots'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"api_key_permissions_enum\" RENAME VALUE 'delete:images' TO 'delete:snapshots'`,\n    )\n    await queryRunner.renameTable('image_runner', 'snapshot_runner')\n    await queryRunner.renameColumn('snapshot_runner', 'imageRef', 'snapshotRef')\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"snapshot_runner_state_enum\" RENAME VALUE 'pulling_image' TO 'pulling_snapshot'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"snapshot_runner_state_enum\" RENAME VALUE 'building_image' TO 'building_snapshot'`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot_runner\" ALTER COLUMN \"state\" SET DEFAULT 'pulling_snapshot'`)\n    await queryRunner.renameColumn('build_info', 'imageRef', 'snapshotRef')\n    await queryRunner.renameTable('image', 'snapshot')\n    await queryRunner.renameColumn('snapshot', 'buildInfoImageRef', 'buildInfoSnapshotRef')\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME VALUE 'pulling_image' TO 'pulling'`)\n    await queryRunner.renameColumn('workspace', 'image', 'snapshot')\n    await queryRunner.renameColumn('workspace', 'buildInfoImageRef', 'buildInfoSnapshotRef')\n    await queryRunner.renameColumn('workspace', 'backupImage', 'backupSnapshot')\n    await queryRunner.renameColumn('workspace', 'existingBackupImages', 'existingBackupSnapshots')\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"workspace_state_enum\" RENAME VALUE 'pulling_image' TO 'pulling_snapshot'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"workspace_state_enum\" RENAME VALUE 'building_image' TO 'building_snapshot'`,\n    )\n\n    // Workspace to sandbox rename\n    await queryRunner.renameTable('workspace', 'sandbox')\n    await queryRunner.renameTable('workspace_usage_periods', 'sandbox_usage_periods')\n    await queryRunner.renameColumn('sandbox_usage_periods', 'workspaceId', 'sandboxId')\n    await queryRunner.renameColumn('organization', 'max_cpu_per_workspace', 'max_cpu_per_sandbox')\n    await queryRunner.renameColumn('organization', 'max_memory_per_workspace', 'max_memory_per_sandbox')\n    await queryRunner.renameColumn('organization', 'max_disk_per_workspace', 'max_disk_per_sandbox')\n\n    // Snapshot fields\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"imageName\" character varying NOT NULL DEFAULT ''`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"cpu\" integer NOT NULL DEFAULT '1'`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"gpu\" integer NOT NULL DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"mem\" integer NOT NULL DEFAULT '1'`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"disk\" integer NOT NULL DEFAULT '3'`)\n    await queryRunner.query(`UPDATE \"snapshot\" SET \"imageName\" = \"name\"`)\n\n    // Add hideFromUsers column\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"hideFromUsers\" boolean NOT NULL DEFAULT false`)\n\n    // Set hideFromUsers to true for general snapshots with names starting with \"daytonaio/\"\n    await queryRunner.query(\n      `UPDATE \"snapshot\" SET \"hideFromUsers\" = true WHERE \"general\" = true AND \"name\" LIKE 'daytonaio/%'`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Remove hideFromUsers column\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"hideFromUsers\"`)\n\n    // Snapshot fields\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"disk\"`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"mem\"`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"gpu\"`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"cpu\"`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"imageName\"`)\n\n    // Revert workspace to sandbox rename\n    await queryRunner.renameColumn('organization', 'max_disk_per_sandbox', 'max_disk_per_workspace')\n    await queryRunner.renameColumn('organization', 'max_memory_per_sandbox', 'max_memory_per_workspace')\n    await queryRunner.renameColumn('organization', 'max_cpu_per_sandbox', 'max_cpu_per_workspace')\n    await queryRunner.renameColumn('sandbox_usage_periods', 'sandboxId', 'workspaceId')\n    await queryRunner.renameTable('sandbox_usage_periods', 'workspace_usage_periods')\n    await queryRunner.renameTable('sandbox', 'workspace')\n\n    // Revert image to snapshot rename\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"workspace_state_enum\" RENAME VALUE 'pulling_snapshot' TO 'pulling_image'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"workspace_state_enum\" RENAME VALUE 'building_snapshot' TO 'building_image'`,\n    )\n    await queryRunner.renameColumn('workspace', 'existingBackupSnapshots', 'existingBackupImages')\n    await queryRunner.renameColumn('workspace', 'backupSnapshot', 'backupImage')\n    await queryRunner.renameColumn('workspace', 'buildInfoSnapshotRef', 'buildInfoImageRef')\n    await queryRunner.renameColumn('workspace', 'snapshot', 'image')\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME VALUE 'pulling' TO 'pulling_image'`)\n    await queryRunner.renameColumn('snapshot', 'buildInfoSnapshotRef', 'buildInfoImageRef')\n    await queryRunner.renameTable('snapshot', 'image')\n    await queryRunner.renameColumn('build_info', 'snapshotRef', 'imageRef')\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"snapshot_runner_state_enum\" RENAME VALUE 'pulling_snapshot' TO 'pulling_image'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"snapshot_runner_state_enum\" RENAME VALUE 'building_snapshot' TO 'building_image'`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot_runner\" ALTER COLUMN \"state\" SET DEFAULT 'pulling_image'`)\n    await queryRunner.renameColumn('snapshot_runner', 'snapshotRef', 'imageRef')\n    await queryRunner.renameTable('snapshot_runner', 'image_runner')\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"api_key_permissions_enum\" RENAME VALUE 'write:snapshots' TO 'write:images'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"api_key_permissions_enum\" RENAME VALUE 'delete:snapshots' TO 'delete:images'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum\" RENAME VALUE 'write:snapshots' TO 'write:images'`,\n    )\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum\" RENAME VALUE 'delete:snapshots' TO 'delete:images'`,\n    )\n    await queryRunner.renameColumn('organization', 'max_snapshot_size', 'max_image_size')\n    await queryRunner.renameColumn('organization', 'snapshot_quota', 'image_quota')\n    await queryRunner.renameColumn('warm_pool', 'snapshot', 'image')\n\n    // Revert node to runner rename\n    await queryRunner.renameColumn('workspace', 'prevRunnerId', 'prevNodeId')\n    await queryRunner.renameColumn('workspace', 'runnerId', 'nodeId')\n    await queryRunner.renameTable('runner', 'node')\n    await queryRunner.renameColumn('image_runner', 'runnerId', 'nodeId')\n    await queryRunner.renameTable('image_runner', 'image_node')\n    await queryRunner.renameColumn('image', 'buildRunnerId', 'buildNodeId')\n\n    // Revert snapshot to backup rename\n    await queryRunner.renameColumn('workspace', 'existingBackupImages', 'existingSnapshotImages')\n    await queryRunner.renameColumn('workspace', 'backupState', 'snapshotState')\n    await queryRunner.renameColumn('workspace', 'lastBackupAt', 'lastSnapshotAt')\n    await queryRunner.renameColumn('workspace', 'backupImage', 'snapshotImage')\n    await queryRunner.renameColumn('workspace', 'backupRegistryId', 'snapshotRegistryId')\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1749474791345-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1749474791345 implements MigrationInterface {\n  name = 'Migration1749474791345'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // For sandbox_state_enum\n    await queryRunner.query(`ALTER TYPE \"public\".\"sandbox_state_enum\" RENAME TO \"sandbox_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"sandbox_state_enum\" AS ENUM('creating', 'restoring', 'destroyed', 'destroying', 'started', 'stopped', 'starting', 'stopping', 'error', 'build_failed', 'pending_build', 'building_snapshot', 'unknown', 'pulling_snapshot', 'archiving', 'archived')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" TYPE \"public\".\"sandbox_state_enum\" USING \"state\"::\"text\"::\"public\".\"sandbox_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" SET DEFAULT 'unknown'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"sandbox_state_enum_old\"`)\n\n    // For snapshot_state_enum\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME TO \"snapshot_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"snapshot_state_enum\" AS ENUM('build_pending', 'building', 'pending', 'pulling', 'pending_validation', 'validating', 'active', 'error', 'build_failed', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" TYPE \"public\".\"snapshot_state_enum\" USING \"state\"::\"text\"::\"public\".\"snapshot_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"snapshot_state_enum_old\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // For snapshot_state_enum - recreate without build_failed\n    await queryRunner.query(`UPDATE \"snapshot\" SET \"state\" = 'error' WHERE \"state\" = 'build_failed'`)\n\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME TO \"snapshot_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"snapshot_state_enum\" AS ENUM('build_pending', 'building', 'pending', 'pulling', 'pending_validation', 'validating', 'active', 'error', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" TYPE \"public\".\"snapshot_state_enum\" USING \"state\"::\"text\"::\"public\".\"snapshot_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"snapshot_state_enum_old\"`)\n\n    // For sandbox_state_enum - recreate without build_failed\n    await queryRunner.query(`UPDATE \"sandbox\" SET \"state\" = 'error' WHERE \"state\" = 'build_failed'`)\n\n    await queryRunner.query(`ALTER TYPE \"public\".\"sandbox_state_enum\" RENAME TO \"sandbox_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"sandbox_state_enum\" AS ENUM('creating', 'restoring', 'destroyed', 'destroying', 'started', 'stopped', 'starting', 'stopping', 'error', 'pending_build', 'building_snapshot', 'unknown', 'pulling_snapshot', 'archiving', 'archived')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" TYPE \"public\".\"sandbox_state_enum\" USING \"state\"::\"text\"::\"public\".\"sandbox_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" SET DEFAULT 'unknown'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"sandbox_state_enum_old\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1750077343089-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1750077343089 implements MigrationInterface {\n  name = 'Migration1750077343089'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ADD \"daemonVersion\" character varying`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP COLUMN \"daemonVersion\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1750436374899-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1750436374899 implements MigrationInterface {\n  name = 'Migration1750436374899'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TABLE \"audit_log\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"actorId\" character varying NOT NULL, \"actorEmail\" character varying NOT NULL DEFAULT '', \"organizationId\" character varying, \"action\" character varying NOT NULL, \"targetType\" character varying, \"targetId\" character varying, \"statusCode\" integer, \"errorMessage\" character varying, \"ipAddress\" character varying, \"userAgent\" text, \"source\" character varying, \"metadata\" jsonb, \"createdAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT \"audit_log_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `CREATE INDEX \"audit_log_organizationId_createdAt_index\" ON \"audit_log\" (\"organizationId\", \"createdAt\") `,\n    )\n    await queryRunner.query(`CREATE INDEX \"audit_log_createdAt_index\" ON \"audit_log\" (\"createdAt\") `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP INDEX \"public\".\"audit_log_createdAt_index\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"audit_log_organizationId_createdAt_index\"`)\n    await queryRunner.query(`DROP TABLE \"audit_log\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1750668569562-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1750668569562 implements MigrationInterface {\n  name = 'Migration1750668569562'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ADD \"autoDeleteInterval\" integer NOT NULL DEFAULT '-1'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP COLUMN \"autoDeleteInterval\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1750751712412-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1750751712412 implements MigrationInterface {\n  name = 'Migration1750751712412'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME TO \"snapshot_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"snapshot_state_enum\" AS ENUM('build_pending', 'building', 'pending', 'pulling', 'pending_validation', 'validating', 'active', 'inactive', 'error', 'build_failed', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" TYPE \"public\".\"snapshot_state_enum\" USING \"state\"::\"text\"::\"public\".\"snapshot_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"snapshot_state_enum_old\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"snapshot_state_enum_old\" AS ENUM('active', 'build_failed', 'build_pending', 'building', 'error', 'pending', 'pending_validation', 'pulling', 'removing', 'validating')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" TYPE \"public\".\"snapshot_state_enum_old\" USING \"state\"::\"text\"::\"public\".\"snapshot_state_enum_old\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"snapshot_state_enum\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum_old\" RENAME TO \"snapshot_state_enum\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1751456907334-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport { GlobalOrganizationRolesIds } from '../organization/constants/global-organization-roles.constant'\nimport { OrganizationResourcePermission } from '../organization/enums/organization-resource-permission.enum'\n\nexport class Migration1751456907334 implements MigrationInterface {\n  name = 'Migration1751456907334'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // update enums\n    await queryRunner.query(`ALTER TYPE \"public\".\"api_key_permissions_enum\" RENAME TO \"api_key_permissions_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"api_key_permissions_enum\" AS ENUM('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'read:audit_logs')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"api_key\" ALTER COLUMN \"permissions\" TYPE \"public\".\"api_key_permissions_enum\"[] USING \"permissions\"::\"text\"::\"public\".\"api_key_permissions_enum\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"api_key_permissions_enum_old\"`)\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum\" RENAME TO \"organization_role_permissions_enum_old\"`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"organization_role_permissions_enum\" AS ENUM('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'read:audit_logs')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role\" ALTER COLUMN \"permissions\" TYPE \"public\".\"organization_role_permissions_enum\"[] USING \"permissions\"::\"text\"::\"public\".\"organization_role_permissions_enum\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"organization_role_permissions_enum_old\"`)\n\n    // add auditor role\n    await queryRunner.query(`\n        INSERT INTO \"organization_role\" \n          (\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\")\n        VALUES \n          (\n            '${GlobalOrganizationRolesIds.AUDITOR}',    \n            'Auditor', \n            'Grants access to audit logs in the organization', \n            ARRAY[\n              '${OrganizationResourcePermission.READ_AUDIT_LOGS}'\n            ]::organization_role_permissions_enum[],\n            TRUE\n          )\n      `)\n\n    // update organization role foreign keys\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment\" DROP CONSTRAINT \"organization_role_assignment_roleId_fk\"`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment\" ADD CONSTRAINT \"organization_role_assignment_roleId_fk\" FOREIGN KEY (\"roleId\") REFERENCES \"organization_role\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment_invitation\" DROP CONSTRAINT \"organization_role_assignment_invitation_roleId_fk\"`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role_assignment_invitation\" ADD CONSTRAINT \"organization_role_assignment_invitation_roleId_fk\" FOREIGN KEY (\"roleId\") REFERENCES \"organization_role\"(\"id\") ON DELETE CASCADE ON UPDATE CASCADE`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // delete auditor role\n    await queryRunner.query(`DELETE FROM \"organization_role\" WHERE \"id\" = '${GlobalOrganizationRolesIds.AUDITOR}'`)\n\n    // remove read:audit_logs permission from api keys and organization roles\n    await queryRunner.query(\n      `UPDATE \"api_key\" SET \"permissions\" = array_remove(\"permissions\", '${OrganizationResourcePermission.READ_AUDIT_LOGS}')`,\n    )\n    await queryRunner.query(\n      `UPDATE \"organization_role\" SET \"permissions\" = array_remove(\"permissions\", '${OrganizationResourcePermission.READ_AUDIT_LOGS}')`,\n    )\n\n    // revert enums\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"organization_role_permissions_enum_old\" AS ENUM('delete:registries', 'delete:sandboxes', 'delete:snapshots', 'delete:volumes', 'read:volumes', 'write:registries', 'write:sandboxes', 'write:snapshots', 'write:volumes')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role\" ALTER COLUMN \"permissions\" TYPE \"public\".\"organization_role_permissions_enum_old\"[] USING \"permissions\"::\"text\"::\"public\".\"organization_role_permissions_enum_old\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"organization_role_permissions_enum\"`)\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum_old\" RENAME TO \"organization_role_permissions_enum\"`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"api_key_permissions_enum_old\" AS ENUM('delete:registries', 'delete:sandboxes', 'delete:snapshots', 'delete:volumes', 'read:volumes', 'write:registries', 'write:sandboxes', 'write:snapshots', 'write:volumes')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"api_key\" ALTER COLUMN \"permissions\" TYPE \"public\".\"api_key_permissions_enum_old\"[] USING \"permissions\"::\"text\"::\"public\".\"api_key_permissions_enum_old\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"api_key_permissions_enum\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"api_key_permissions_enum_old\" RENAME TO \"api_key_permissions_enum\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1752494676200-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1752494676200 implements MigrationInterface {\n  name = 'Migration1752494676200'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP TABLE \"team\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TABLE \"team\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"name\" character varying NOT NULL, CONSTRAINT \"PK_f57d8293406df4af348402e4b74\" PRIMARY KEY (\"id\"))`,\n    )\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1752494676205-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1752494676205 implements MigrationInterface {\n  name = 'Migration1752494676205'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Convert runner.region from enum to varchar\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"region\" TYPE varchar USING \"region\"::text`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"region\" SET DEFAULT 'us'`)\n\n    // Convert sandbox.region from enum to varchar\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"region\" TYPE varchar USING \"region\"::text`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"region\" SET DEFAULT 'us'`)\n\n    // Convert warm_pool.target from enum to varchar\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"target\" TYPE varchar USING \"target\"::text`)\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"target\" SET DEFAULT 'us'`)\n\n    // Drop the enum type if it exists\n    await queryRunner.query(`DROP TYPE IF EXISTS \"public\".\"runner_region_enum\"`)\n    await queryRunner.query(`DROP TYPE IF EXISTS \"public\".\"sandbox_region_enum\"`)\n    await queryRunner.query(`DROP TYPE IF EXISTS \"public\".\"warm_pool_target_enum\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Recreate the enum type\n    await queryRunner.query(`CREATE TYPE \"public\".\"warm_pool_target_enum\" AS ENUM('eu', 'us', 'asia')`)\n    await queryRunner.query(`CREATE TYPE \"public\".\"sandbox_region_enum\" AS ENUM('eu', 'us', 'asia')`)\n    await queryRunner.query(`CREATE TYPE \"public\".\"runner_region_enum\" AS ENUM('eu', 'us', 'asia')`)\n\n    // Convert back to enum for runner.region\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"region\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"runner\" ALTER COLUMN \"region\" TYPE \"public\".\"runner_region_enum\" USING \"region\"::\"public\".\"runner_region_enum\"`,\n    )\n\n    // Convert back to enum for sandbox.region\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"region\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"sandbox\" ALTER COLUMN \"region\" TYPE \"public\".\"sandbox_region_enum\" USING \"region\"::\"public\".\"sandbox_region_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"region\" SET DEFAULT 'eu'`)\n\n    // Convert back to enum for warm_pool.target\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"target\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"warm_pool\" ALTER COLUMN \"target\" TYPE \"public\".\"warm_pool_target_enum\" USING \"target\"::\"public\".\"warm_pool_target_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"target\" SET DEFAULT 'eu'`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1752848014862-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1752848014862 implements MigrationInterface {\n  name = 'Migration1752848014862'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"lastChecked\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"sandbox_usage_periods\" ALTER COLUMN \"startAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"sandbox_usage_periods\" ALTER COLUMN \"endAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"snapshot_runner\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"snapshot_runner\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"lastActivityAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"lastBackupAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"build_info\" ALTER COLUMN \"lastUsedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"build_info\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"build_info\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"volume\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"volume\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"organization_user\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"organization_user\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(\n      `ALTER TABLE \"organization_invitation\" ALTER COLUMN \"expiresAt\" TYPE TIMESTAMP WITH TIME ZONE`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_invitation\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_invitation\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`,\n    )\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"suspendedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"suspendedUntil\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"organization_role\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n    await queryRunner.query(`ALTER TABLE \"organization_role\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP WITH TIME ZONE`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization_role\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization_role\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"suspendedUntil\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"suspendedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization_invitation\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization_invitation\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization_invitation\" ALTER COLUMN \"expiresAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization_user\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"organization_user\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"volume\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"volume\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"imageName\" SET DEFAULT ''`)\n    await queryRunner.query(`ALTER TABLE \"build_info\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"build_info\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"build_info\" ALTER COLUMN \"lastUsedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"lastBackupAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"lastActivityAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"snapshot_runner\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"snapshot_runner\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"sandbox_usage_periods\" ALTER COLUMN \"endAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"sandbox_usage_periods\" ALTER COLUMN \"startAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"lastChecked\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"updatedAt\" TYPE TIMESTAMP`)\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"createdAt\" TYPE TIMESTAMP`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1753099115783-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1753099115783 implements MigrationInterface {\n  name = 'Migration1753099115783'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"enabled\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"enabled\" boolean NOT NULL DEFAULT true`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1753100751730-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1753100751730 implements MigrationInterface {\n  name = 'Migration1753100751730'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.renameColumn('runner', 'memory', 'memoryGiB')\n    await queryRunner.renameColumn('runner', 'disk', 'diskGiB')\n    await queryRunner.query(\n      `ALTER TABLE \"runner\" ADD \"currentCpuUsagePercentage\" double precision NOT NULL DEFAULT '0'`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"runner\" ADD \"currentMemoryUsagePercentage\" double precision NOT NULL DEFAULT '0'`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"runner\" ADD \"currentDiskUsagePercentage\" double precision NOT NULL DEFAULT '0'`,\n    )\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"currentAllocatedCpu\" integer NOT NULL DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"currentAllocatedMemoryGiB\" integer NOT NULL DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"currentAllocatedDiskGiB\" integer NOT NULL DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"currentSnapshotCount\" integer NOT NULL DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"availabilityScore\" integer NOT NULL DEFAULT '0'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"availabilityScore\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentSnapshotCount\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentAllocatedDiskGiB\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentAllocatedMemoryGiB\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentAllocatedCpu\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentDiskUsagePercentage\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentMemoryUsagePercentage\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentCpuUsagePercentage\"`)\n    await queryRunner.renameColumn('runner', 'diskGiB', 'disk')\n    await queryRunner.renameColumn('runner', 'memoryGiB', 'memory')\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1753100751731-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport { GlobalOrganizationRolesIds } from '../organization/constants/global-organization-roles.constant'\n\nexport class Migration1753100751731 implements MigrationInterface {\n  name = 'Migration1753100751731'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`\n      UPDATE \"organization_role\" \n      SET \"name\" = 'Snapshots Admin', \"description\" = 'Grants admin access to snapshots in the organization'\n      WHERE \"id\" = '${GlobalOrganizationRolesIds.SNAPSHOTS_ADMIN}'\n    `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`\n      UPDATE \"organization_role\" \n      SET \"name\" = 'Images Admin', \"description\" = 'Grants admin access to images in the organization'\n      WHERE \"id\" = '${GlobalOrganizationRolesIds.SNAPSHOTS_ADMIN}'\n    `)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1753185133351-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1753185133351 implements MigrationInterface {\n  name = 'Migration1753185133351'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"version\" character varying NOT NULL DEFAULT '0'`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"proxyUrl\" character varying NOT NULL DEFAULT ''`)\n    // Copy apiUrl to proxyUrl for all existing records\n    await queryRunner.query(`UPDATE \"runner\" SET \"proxyUrl\" = \"apiUrl\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"version\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"proxyUrl\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1753274135567-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1753274135567 implements MigrationInterface {\n  name = 'Migration1753274135567'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"project\" SET DEFAULT ''`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"project\" DROP DEFAULT`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1753430929609-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1753430929609 implements MigrationInterface {\n  name = 'Migration1753430929609'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"user\" ADD \"createdAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now()`)\n\n    // For existing users, set createdAt to match their personal organization's createdAt\n    await queryRunner.query(`\n        UPDATE \"user\" u \n        SET \"createdAt\" = o.\"createdAt\" \n        FROM \"organization\" o \n        WHERE o.\"createdBy\" = u.id \n          AND o.personal = true;\n    `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"user\" DROP COLUMN \"createdAt\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1753717830378-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1753717830378 implements MigrationInterface {\n  name = 'Migration1753717830378'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ADD \"networkBlockAll\" boolean NOT NULL DEFAULT false`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ADD \"networkAllowList\" character varying`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP COLUMN \"networkAllowList\"`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP COLUMN \"networkBlockAll\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1754042247109-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1754042247109 implements MigrationInterface {\n  name = 'Migration1754042247109'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `ALTER TABLE \"organization\" ADD \"suspensionCleanupGracePeriodHours\" integer NOT NULL DEFAULT '24'`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"suspensionCleanupGracePeriodHours\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1755003696741-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1755003696741 implements MigrationInterface {\n  name = 'Migration1755003696741'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ADD \"backupErrorReason\" text`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP COLUMN \"backupErrorReason\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1755356869493-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1755356869493 implements MigrationInterface {\n  name = 'Migration1755356869493'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TABLE \"webhook_initialization\" (\"organizationId\" character varying NOT NULL, \"svixApplicationId\" character varying, \"lastError\" text, \"retryCount\" integer NOT NULL DEFAULT '0', \"createdAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT \"webhook_initialization_organizationId_pk\" PRIMARY KEY (\"organizationId\"))`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP TABLE \"webhook_initialization\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1755464957487-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1755464957487 implements MigrationInterface {\n  name = 'Migration1755464957487'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TABLE \"ssh_access\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"sandboxId\" character varying NOT NULL, \"token\" text NOT NULL, \"expiresAt\" TIMESTAMP NOT NULL, \"createdAt\" TIMESTAMP NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT \"ssh_access_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"ssh_access\" ADD CONSTRAINT \"ssh_access_sandboxId_fk\" FOREIGN KEY (\"sandboxId\") REFERENCES \"sandbox\"(\"id\") ON DELETE CASCADE ON UPDATE NO ACTION`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"sandbox\" ADD \"sshPass\" character varying(32) NOT NULL DEFAULT REPLACE(uuid_generate_v4()::text, '-', '')`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP COLUMN \"sshPass\"`)\n    await queryRunner.query(`ALTER TABLE \"ssh_access\" DROP CONSTRAINT \"ssh_access_sandboxId_fk\"`)\n    await queryRunner.query(`DROP TABLE \"ssh_access\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1755521645207-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1755521645207 implements MigrationInterface {\n  name = 'Migration1755521645207'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TABLE \"sandbox_usage_periods_archive\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"sandboxId\" character varying NOT NULL, \"organizationId\" character varying NOT NULL, \"startAt\" TIMESTAMP WITH TIME ZONE NOT NULL, \"endAt\" TIMESTAMP WITH TIME ZONE NOT NULL, \"cpu\" double precision NOT NULL, \"gpu\" double precision NOT NULL, \"mem\" double precision NOT NULL, \"disk\" double precision NOT NULL, \"region\" character varying NOT NULL, CONSTRAINT \"sandbox_usage_periods_archive_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP TABLE \"sandbox_usage_periods_archive\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1755860619921-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1755860619921 implements MigrationInterface {\n  name = 'Migration1755860619921'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `ALTER TABLE \"organization\" ADD \"sandboxLimitedNetworkEgress\" boolean NOT NULL DEFAULT false`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"sandboxLimitedNetworkEgress\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1757513754037-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1757513754037 implements MigrationInterface {\n  name = 'Migration1757513754037'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ADD \"region\" character varying`)\n\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"docker_registry_registrytype_enum\" RENAME TO \"docker_registry_registrytype_enum_old\"`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"docker_registry_registrytype_enum\" AS ENUM('internal', 'organization', 'transient', 'backup')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" TYPE \"public\".\"docker_registry_registrytype_enum\" USING \"registryType\"::\"text\"::\"public\".\"docker_registry_registrytype_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" SET DEFAULT 'internal'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"docker_registry_registrytype_enum_old\"`)\n\n    // Create the base default registry by copying from the default internal one\n    await queryRunner.query(`\n          INSERT INTO public.docker_registry (\n            name, url, username, password, \"isDefault\", project, \"createdAt\", \"updatedAt\", \"registryType\", \"organizationId\", \"region\"\n          )\n          SELECT\n            'Backup Registry' AS name,\n            url,\n            username,\n            password,\n            \"isDefault\",\n            project,\n            now() AS \"createdAt\",\n            now() AS \"updatedAt\",\n            'backup' AS \"registryType\",\n            \"organizationId\",\n            \"region\"\n          FROM public.docker_registry\n          WHERE \"registryType\" = 'internal'\n            AND \"isDefault\" = true\n          ORDER BY \"createdAt\" ASC\n          LIMIT 1\n        `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`\n      DELETE FROM public.docker_registry\n      WHERE \"registryType\" = 'backup'\n    `)\n\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"docker_registry_registrytype_enum_old\" AS ENUM('internal', 'organization', 'transient', 'backup')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" TYPE \"public\".\"docker_registry_registrytype_enum_old\" USING \"registryType\"::\"text\"::\"public\".\"docker_registry_registrytype_enum_old\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ALTER COLUMN \"registryType\" SET DEFAULT 'internal'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"docker_registry_registrytype_enum\"`)\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"docker_registry_registrytype_enum_old\" RENAME TO \"docker_registry_registrytype_enum\"`,\n    )\n\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" DROP COLUMN \"region\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1757513754038-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1757513754038 implements MigrationInterface {\n  name = 'Migration1757513754038'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" ADD \"isFallback\" boolean NOT NULL DEFAULT false`)\n\n    // Update existing registries that have isDefault = true and region = null to be fallback registries\n    await queryRunner.query(`\n      UPDATE \"docker_registry\"\n      SET \"isFallback\" = true\n      WHERE \"isDefault\" = true AND \"region\" IS NULL AND \"registryType\" = 'backup'\n    `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"docker_registry\" DROP COLUMN \"isFallback\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1759241690773-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1759241690773 implements MigrationInterface {\n  name = 'Migration1759241690773'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"used\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"capacity\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"capacity\" integer NOT NULL DEFAULT '1000'`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"used\" integer NOT NULL DEFAULT '0'`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1759768058397-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1759768058397 implements MigrationInterface {\n  name = 'Migration1759768058397'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ADD \"name\" character varying`)\n    await queryRunner.query(`UPDATE \"sandbox\" SET \"name\" = \"id\"`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"name\" SET NOT NULL`)\n    await queryRunner.query(\n      `ALTER TABLE \"sandbox\" ALTER COLUMN \"name\" SET DEFAULT 'sandbox-' || substring(gen_random_uuid()::text, 1, 10)`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"sandbox\" ADD CONSTRAINT \"sandbox_organizationId_name_unique\" UNIQUE (\"organizationId\", \"name\")`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP CONSTRAINT \"sandbox_organizationId_name_unique\"`)\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP COLUMN \"name\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1761912147638-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport { configuration } from '../config/configuration'\n\nexport class Migration1761912147638 implements MigrationInterface {\n  name = 'Migration1761912147638'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"defaultRegion\" character varying NULL`)\n    await queryRunner.query(`UPDATE \"organization\" SET \"defaultRegion\" = '${configuration.defaultRegion.id}'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"defaultRegion\" SET NOT NULL`)\n\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"region\" DROP DEFAULT`)\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"target\" DROP DEFAULT`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"defaultRegion\"`)\n\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"region\" SET DEFAULT 'us'`)\n    await queryRunner.query(`ALTER TABLE \"warm_pool\" ALTER COLUMN \"target\" SET DEFAULT 'us'`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1761912147639-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1761912147639 implements MigrationInterface {\n  name = 'Migration1761912147639'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.renameColumn('snapshot', 'internalName', 'ref')\n    await queryRunner.renameColumn('snapshot', 'buildRunnerId', 'initialRunnerId')\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"skipValidation\" boolean NOT NULL DEFAULT false`)\n\n    // Update snapshot states\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME TO \"snapshot_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"snapshot_state_enum\" AS ENUM('pending', 'pulling', 'pending_validation', 'validating', 'active', 'inactive', 'building', 'error', 'build_failed', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" TYPE \"public\".\"snapshot_state_enum\" USING \"state\"::\"text\"::\"public\".\"snapshot_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"snapshot_state_enum_old\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Revert snapshot states\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME TO \"snapshot_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"snapshot_state_enum\" AS ENUM('build_pending', 'pending', 'pulling', 'pending_validation', 'validating', 'active', 'inactive', 'building', 'error', 'build_failed', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" TYPE \"public\".\"snapshot_state_enum\" USING \"state\"::\"text\"::\"public\".\"snapshot_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"snapshot_state_enum_old\"`)\n\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"skipValidation\"`)\n    await queryRunner.renameColumn('snapshot', 'initialRunnerId', 'buildRunnerId')\n    await queryRunner.renameColumn('snapshot', 'ref', 'internalName')\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1763561822000-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1763561822000 implements MigrationInterface {\n  name = 'Migration1763561822000'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"authenticated_rate_limit\" integer`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"sandbox_create_rate_limit\" integer`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"sandbox_lifecycle_rate_limit\" integer`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"sandbox_lifecycle_rate_limit\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"sandbox_create_rate_limit\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"authenticated_rate_limit\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1764073472179-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport { configuration } from '../config/configuration'\n\nexport class Migration1764073472179 implements MigrationInterface {\n  name = 'Migration1764073472179'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Create region table\n    await queryRunner.query(\n      `CREATE TABLE \"region\" (\"id\" character varying NOT NULL, \"name\" character varying NOT NULL, \"organizationId\" uuid, \"hidden\" boolean NOT NULL DEFAULT false, \"enforceQuotas\" boolean NOT NULL DEFAULT true, \"createdAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT \"region_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n\n    // Add unique constraints for region name\n    await queryRunner.query(\n      `CREATE UNIQUE INDEX \"region_organizationId_null_name_unique\" ON \"region\" (\"name\") WHERE \"organizationId\" IS NULL`,\n    )\n    await queryRunner.query(\n      `CREATE UNIQUE INDEX \"region_organizationId_name_unique\" ON \"region\" (\"organizationId\", \"name\") WHERE \"organizationId\" IS NOT NULL`,\n    )\n\n    // Expand organization table with defaultRegionId column (make it nullable)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"defaultRegionId\" character varying NULL`)\n    await queryRunner.query(`UPDATE \"organization\" SET \"defaultRegionId\" = \"defaultRegion\"`)\n\n    // Add default value for required defaultRegion column before dropping it in the contract migration\n    await queryRunner.query(\n      `ALTER TABLE \"organization\" ALTER COLUMN \"defaultRegion\" SET DEFAULT '${configuration.defaultRegion.id}'`,\n    )\n\n    // Create region_quota table\n    await queryRunner.query(\n      `CREATE TABLE \"region_quota\" (\"organizationId\" uuid NOT NULL, \"regionId\" character varying NOT NULL, \"total_cpu_quota\" integer NOT NULL DEFAULT '10', \"total_memory_quota\" integer NOT NULL DEFAULT '10', \"total_disk_quota\" integer NOT NULL DEFAULT '30', \"createdAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT \"region_quota_organizationId_regionId_pk\" PRIMARY KEY (\"organizationId\", \"regionId\"))`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"region_quota\" ADD CONSTRAINT \"region_quota_organizationId_fk\" FOREIGN KEY (\"organizationId\") REFERENCES \"organization\"(\"id\") ON DELETE CASCADE ON UPDATE NO ACTION`,\n    )\n\n    // For existing organizations, migrate their region-specific quotas to their default region\n    await queryRunner.query(`\n            INSERT INTO \"region_quota\" (\"organizationId\", \"regionId\", \"total_cpu_quota\", \"total_memory_quota\", \"total_disk_quota\")\n            SELECT \n              o.\"id\" as \"organizationId\",\n              o.\"defaultRegionId\" as \"regionId\",\n              o.\"total_cpu_quota\",\n              o.\"total_memory_quota\",\n              o.\"total_disk_quota\"\n            FROM \"organization\" o\n          `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Drop region table\n    await queryRunner.query(`DROP TABLE \"region\"`)\n\n    // Drop defaultRegionId column from organization table\n    await queryRunner.dropColumn('organization', 'defaultRegionId')\n\n    // Drop region_quota table\n    await queryRunner.query(`DROP TABLE \"region_quota\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1764073472180-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport { configuration } from '../config/configuration'\n\nexport class Migration1764073472180 implements MigrationInterface {\n  name = 'Migration1764073472180'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Remove defaultRegion column from organization table\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"defaultRegion\"`)\n\n    // Remove region-specific quotas from organization table\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"total_cpu_quota\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"total_memory_quota\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"total_disk_quota\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Restore defaultRegion column to organization table\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"defaultRegion\" character varying NULL`)\n    await queryRunner.query(`UPDATE \"organization\" SET \"defaultRegion\" = \"defaultRegionId\"`)\n    await queryRunner.query(\n      `ALTER TABLE \"organization\" ALTER COLUMN \"defaultRegion\" SET DEFAULT '${configuration.defaultRegion.id}'`,\n    )\n    await queryRunner.query(`ALTER TABLE \"organization\" ALTER COLUMN \"defaultRegion\" SET NOT NULL`)\n\n    // Restore region-specific quotas to organization table\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"total_disk_quota\" integer NOT NULL DEFAULT '30'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"total_memory_quota\" integer NOT NULL DEFAULT '10'`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"total_cpu_quota\" integer NOT NULL DEFAULT '10'`)\n\n    // For each organization, restore region-specific quotas by taking the maximum values among all region quotas\n    await queryRunner.query(`\n      UPDATE \"organization\" o\n      SET \n        \"total_cpu_quota\" = COALESCE(q.\"total_cpu_quota\", 10),\n        \"total_memory_quota\" = COALESCE(q.\"total_memory_quota\", 10),\n        \"total_disk_quota\" = COALESCE(q.\"total_disk_quota\", 30)\n      FROM (\n        SELECT \n          \"organizationId\",\n          MAX(\"total_cpu_quota\") as \"total_cpu_quota\",\n          MAX(\"total_memory_quota\") as \"total_memory_quota\",\n          MAX(\"total_disk_quota\") as \"total_disk_quota\"\n        FROM \"region_quota\"\n        GROUP BY \"organizationId\"\n      ) q\n      WHERE o.\"id\" = q.\"organizationId\"\n    `)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1764844895057-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\nimport { GlobalOrganizationRolesIds } from '../organization/constants/global-organization-roles.constant'\nimport { OrganizationResourcePermission } from '../organization/enums/organization-resource-permission.enum'\n\nexport class Migration1764844895057 implements MigrationInterface {\n  name = 'Migration1764844895057'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // add region type field with its type and constraints\n    await queryRunner.query(`CREATE TYPE \"public\".\"region_regiontype_enum\" AS ENUM('shared', 'dedicated', 'custom')`)\n    await queryRunner.query(`ALTER TABLE \"region\" ADD \"regionType\" \"public\".\"region_regiontype_enum\"`)\n    await queryRunner.query(\n      `ALTER TABLE \"region\" ADD CONSTRAINT \"region_not_custom\" CHECK (\"organizationId\" IS NOT NULL OR \"regionType\" != 'custom')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"region\" ADD CONSTRAINT \"region_not_shared\" CHECK (\"organizationId\" IS NULL OR \"regionType\" != 'shared')`,\n    )\n    await queryRunner.query(`UPDATE \"region\" SET \"regionType\" = 'custom' WHERE \"organizationId\" IS NOT NULL`)\n    await queryRunner.query(`UPDATE \"region\" SET \"regionType\" = 'shared' WHERE \"organizationId\" IS NULL`)\n    await queryRunner.query(`ALTER TABLE \"region\" ALTER COLUMN \"regionType\" SET NOT NULL`)\n\n    // update api key permission enum\n    await queryRunner.query(`ALTER TYPE \"public\".\"api_key_permissions_enum\" RENAME TO \"api_key_permissions_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"api_key_permissions_enum\" AS ENUM('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"api_key\" ALTER COLUMN \"permissions\" TYPE \"public\".\"api_key_permissions_enum\"[] USING \"permissions\"::\"text\"::\"public\".\"api_key_permissions_enum\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"api_key_permissions_enum_old\"`)\n\n    // update organization role permission enum\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum\" RENAME TO \"organization_role_permissions_enum_old\"`,\n    )\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"organization_role_permissions_enum\" AS ENUM('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role\" ALTER COLUMN \"permissions\" TYPE \"public\".\"organization_role_permissions_enum\"[] USING \"permissions\"::\"text\"::\"public\".\"organization_role_permissions_enum\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"organization_role_permissions_enum_old\"`)\n\n    // add infrastructure admin role\n    await queryRunner.query(`\n      INSERT INTO \"organization_role\" \n        (\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\")\n      VALUES \n        (\n          '${GlobalOrganizationRolesIds.INFRASTRUCTURE_ADMIN}',    \n          'Infrastructure Admin', \n          'Grants admin access to infrastructure in the organization', \n          ARRAY[\n            '${OrganizationResourcePermission.WRITE_REGIONS}',\n            '${OrganizationResourcePermission.DELETE_REGIONS}',\n            '${OrganizationResourcePermission.READ_RUNNERS}',\n            '${OrganizationResourcePermission.WRITE_RUNNERS}',\n            '${OrganizationResourcePermission.DELETE_RUNNERS}'\n          ]::organization_role_permissions_enum[],\n          TRUE\n        )\n    `)\n\n    // add runner name field\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"name\" character varying`)\n    await queryRunner.query(`UPDATE \"runner\" SET \"name\" = \"id\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"name\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD CONSTRAINT \"runner_region_name_unique\" UNIQUE (\"region\", \"name\")`)\n\n    // create new index for runner\n    await queryRunner.query(\n      `CREATE INDEX \"runner_state_unschedulable_region_index\" ON \"runner\" (\"state\", \"unschedulable\", \"region\") `,\n    )\n\n    // add region proxy and ssh gateway fields\n    await queryRunner.query(`ALTER TABLE \"region\" ADD \"proxyUrl\" character varying`)\n    await queryRunner.query(`ALTER TABLE \"region\" ADD \"toolboxProxyUrl\" character varying`)\n    await queryRunner.query(`ALTER TABLE \"region\" ADD \"proxyApiKeyHash\" character varying`)\n    await queryRunner.query(`ALTER TABLE \"region\" ADD \"sshGatewayUrl\" character varying`)\n    await queryRunner.query(`ALTER TABLE \"region\" ADD \"sshGatewayApiKeyHash\" character varying`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"proxyUrl\" DROP DEFAULT`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"region\" DROP DEFAULT`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // remove region proxy and ssh gateway fields\n    await queryRunner.query(`ALTER TABLE \"region\" DROP COLUMN \"sshGatewayApiKeyHash\"`)\n    await queryRunner.query(`ALTER TABLE \"region\" DROP COLUMN \"sshGatewayUrl\"`)\n    await queryRunner.query(`ALTER TABLE \"region\" DROP COLUMN \"proxyApiKeyHash\"`)\n    await queryRunner.query(`ALTER TABLE \"region\" DROP COLUMN \"toolboxProxyUrl\"`)\n    await queryRunner.query(`ALTER TABLE \"region\" DROP COLUMN \"proxyUrl\"`)\n\n    // drop region type field\n    await queryRunner.query(`ALTER TABLE \"region\" DROP COLUMN \"regionType\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"region_regiontype_enum\"`)\n\n    // remove infrastructure admin role\n    await queryRunner.query(\n      `DELETE FROM \"organization_role\" WHERE \"id\" = '${GlobalOrganizationRolesIds.INFRASTRUCTURE_ADMIN}'`,\n    )\n\n    // revert api key permission enum\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"api_key_permissions_enum_old\" AS ENUM('delete:registries', 'delete:sandboxes', 'delete:snapshots', 'delete:volumes', 'read:audit_logs', 'read:volumes', 'write:registries', 'write:sandboxes', 'write:snapshots', 'write:volumes')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"api_key\" ALTER COLUMN \"permissions\" TYPE \"public\".\"api_key_permissions_enum_old\"[] USING \"permissions\"::\"text\"::\"public\".\"api_key_permissions_enum_old\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"api_key_permissions_enum\"`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"api_key_permissions_enum_old\" RENAME TO \"api_key_permissions_enum\"`)\n\n    // revert organization role permission enum\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"organization_role_permissions_enum_old\" AS ENUM('delete:registries', 'delete:sandboxes', 'delete:snapshots', 'delete:volumes', 'read:audit_logs', 'read:volumes', 'write:registries', 'write:sandboxes', 'write:snapshots', 'write:volumes')`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"organization_role\" ALTER COLUMN \"permissions\" TYPE \"public\".\"organization_role_permissions_enum_old\"[] USING \"permissions\"::\"text\"::\"public\".\"organization_role_permissions_enum_old\"[]`,\n    )\n    await queryRunner.query(`DROP TYPE \"public\".\"organization_role_permissions_enum\"`)\n    await queryRunner.query(\n      `ALTER TYPE \"public\".\"organization_role_permissions_enum_old\" RENAME TO \"organization_role_permissions_enum\"`,\n    )\n\n    // drop runner name field\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"name\"`)\n\n    // drop new index for runner\n    await queryRunner.query(`DROP INDEX \"public\".\"runner_state_unschedulable_region_index\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1764844895058-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1764844895058 implements MigrationInterface {\n  name = 'Migration1764844895058'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // drop region hidden field\n    await queryRunner.query(`ALTER TABLE \"region\" DROP COLUMN \"hidden\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // revert drop region hidden field\n    await queryRunner.query(`ALTER TABLE \"region\" ADD \"hidden\" boolean NOT NULL DEFAULT false`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1765282546000-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1765282546000 implements MigrationInterface {\n  name = 'Migration1765282546000'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Remove skipValidation column\n    await queryRunner.query(`ALTER TABLE \"snapshot\" DROP COLUMN \"skipValidation\"`)\n\n    // Update any snapshots in VALIDATING or PENDING_VALIDATION state to PENDING\n    await queryRunner.query(`UPDATE \"snapshot\" SET \"state\" = 'pending' WHERE \"state\" = 'validating'`)\n    await queryRunner.query(`UPDATE \"snapshot\" SET \"state\" = 'pending' WHERE \"state\" = 'pending_validation'`)\n\n    // Update snapshot_state_enum to remove VALIDATING and PENDING_VALIDATION\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME TO \"snapshot_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"snapshot_state_enum\" AS ENUM('pending', 'pulling', 'active', 'inactive', 'building', 'error', 'build_failed', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" TYPE \"public\".\"snapshot_state_enum\" USING \"state\"::\"text\"::\"public\".\"snapshot_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"snapshot_state_enum_old\"`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Revert snapshot_state_enum to include VALIDATING and PENDING_VALIDATION\n    await queryRunner.query(`ALTER TYPE \"public\".\"snapshot_state_enum\" RENAME TO \"snapshot_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"snapshot_state_enum\" AS ENUM('pending', 'pulling', 'pending_validation', 'validating', 'active', 'inactive', 'building', 'error', 'build_failed', 'removing')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" TYPE \"public\".\"snapshot_state_enum\" USING \"state\"::\"text\"::\"public\".\"snapshot_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ALTER COLUMN \"state\" SET DEFAULT 'pending'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"snapshot_state_enum_old\"`)\n\n    // Re-add skipValidation column\n    await queryRunner.query(`ALTER TABLE \"snapshot\" ADD \"skipValidation\" boolean NOT NULL DEFAULT false`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1765366773736-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1765366773736 implements MigrationInterface {\n  name = 'Migration1765366773736'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ADD \"recoverable\" boolean NOT NULL DEFAULT false`)\n\n    // Update existing sandboxes with recoverable error reasons to set recoverable = true\n    await queryRunner.query(`\n            UPDATE \"sandbox\" \n            SET \"recoverable\" = true \n            WHERE \"state\" = 'error' \n            AND (\n                LOWER(\"errorReason\") LIKE '%no space left on device%'\n                OR LOWER(\"errorReason\") LIKE '%storage limit%'\n                OR LOWER(\"errorReason\") LIKE '%disk quota exceeded%'\n            )\n        `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"sandbox\" DROP COLUMN \"recoverable\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1765400000000-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1765400000000 implements MigrationInterface {\n  name = 'Migration1765400000000'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Normalize Docker Hub URLs to 'docker.io' for consistency\n    // The runner will convert to 'index.docker.io/v1/' for builds where needed\n    await queryRunner.query(`\n      UPDATE \"docker_registry\"\n      SET \"url\" = 'docker.io'\n      WHERE LOWER(\"url\") LIKE '%docker.io%'\n    `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Cannot reliably reverse this migration as we don't know the original URLs\n    // This is a one-way normalization\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1765806205881-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1765806205881 implements MigrationInterface {\n  name = 'Migration1765806205881'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Create snapshot_region table\n    await queryRunner.query(`\n        CREATE TABLE \"snapshot_region\" (\n          \"snapshotId\" uuid NOT NULL,\n          \"regionId\" character varying NOT NULL,\n          \"createdAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),\n          \"updatedAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),\n          CONSTRAINT \"PK_snapshot_region\" PRIMARY KEY (\"snapshotId\", \"regionId\")\n        )\n      `)\n\n    // Add foreign key constraints\n    await queryRunner.query(`\n        ALTER TABLE \"snapshot_region\"\n        ADD CONSTRAINT \"FK_snapshot_region_snapshot\"\n        FOREIGN KEY (\"snapshotId\") REFERENCES \"snapshot\"(\"id\") ON DELETE CASCADE ON UPDATE NO ACTION\n      `)\n\n    await queryRunner.query(`\n        ALTER TABLE \"snapshot_region\"\n        ADD CONSTRAINT \"FK_snapshot_region_region\"\n        FOREIGN KEY (\"regionId\") REFERENCES \"region\"(\"id\") ON DELETE CASCADE ON UPDATE NO ACTION\n      `)\n\n    // Migrate existing snapshots: add snapshot_region entries based on organization's default region\n    await queryRunner.query(`\n        INSERT INTO \"snapshot_region\" (\"snapshotId\", \"regionId\")\n        SELECT s.id, o.\"defaultRegionId\"\n        FROM \"snapshot\" s\n        INNER JOIN \"organization\" o ON s.\"organizationId\" = o.id\n        WHERE o.\"defaultRegionId\" IS NOT NULL\n      `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Drop foreign key constraints\n    await queryRunner.query(`ALTER TABLE \"snapshot_region\" DROP CONSTRAINT \"FK_snapshot_region_region\"`)\n    await queryRunner.query(`ALTER TABLE \"snapshot_region\" DROP CONSTRAINT \"FK_snapshot_region_snapshot\"`)\n\n    // Drop snapshot_region table\n    await queryRunner.query(`DROP TABLE \"snapshot_region\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1766415256696-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1766415256696 implements MigrationInterface {\n  name = 'Migration1766415256696'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // region snapshot manager field\n    await queryRunner.query(`ALTER TABLE \"region\" ADD \"snapshotManagerUrl\" character varying`)\n\n    // docker registry indexes\n    await queryRunner.query(\n      `CREATE INDEX \"docker_registry_registryType_isDefault_index\" ON \"docker_registry\" (\"registryType\", \"isDefault\") `,\n    )\n    await queryRunner.query(\n      `CREATE INDEX \"docker_registry_region_registryType_index\" ON \"docker_registry\" (\"region\", \"registryType\") `,\n    )\n    await queryRunner.query(\n      `CREATE INDEX \"docker_registry_organizationId_registryType_index\" ON \"docker_registry\" (\"organizationId\", \"registryType\") `,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // drop region snapshot manager field\n    await queryRunner.query(`ALTER TABLE \"region\" DROP COLUMN \"snapshotManagerUrl\"`)\n\n    // drop docker registry indexes\n    await queryRunner.query(`DROP INDEX \"public\".\"docker_registry_organizationId_registryType_index\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"docker_registry_region_registryType_index\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"docker_registry_registryType_isDefault_index\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1767830400000-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1767830400000 implements MigrationInterface {\n  name = 'Migration1767830400000'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"currentStartedSandboxes\" integer NOT NULL DEFAULT 0`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentStartedSandboxes\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1768306129179-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1768306129179 implements MigrationInterface {\n  name = 'Migration1768306129179'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"job_status_enum\" AS ENUM('PENDING', 'IN_PROGRESS', 'COMPLETED', 'FAILED')`,\n    )\n    await queryRunner.query(`CREATE TYPE \"public\".\"job_resourcetype_enum\" AS ENUM('SANDBOX', 'SNAPSHOT', 'BACKUP')`)\n    await queryRunner.query(\n      `CREATE TABLE \"job\" (\"id\" uuid NOT NULL DEFAULT uuid_generate_v4(), \"version\" integer NOT NULL, \"type\" character varying NOT NULL, \"status\" \"public\".\"job_status_enum\" NOT NULL DEFAULT 'PENDING', \"runnerId\" character varying NOT NULL, \"resourceType\" \"public\".\"job_resourcetype_enum\" NOT NULL, \"resourceId\" character varying NOT NULL, \"payload\" character varying, \"resultMetadata\" character varying, \"traceContext\" jsonb, \"errorMessage\" text, \"startedAt\" TIMESTAMP WITH TIME ZONE, \"completedAt\" TIMESTAMP WITH TIME ZONE, \"createdAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), \"updatedAt\" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT \"job_id_pk\" PRIMARY KEY (\"id\"))`,\n    )\n    await queryRunner.query(\n      `CREATE UNIQUE INDEX \"IDX_UNIQUE_INCOMPLETE_JOB\" ON \"job\" (\"resourceType\", \"resourceId\", \"runnerId\") WHERE \"completedAt\" IS NULL`,\n    )\n    await queryRunner.query(`CREATE INDEX \"job_resourceType_resourceId_index\" ON \"job\" (\"resourceType\", \"resourceId\") `)\n    await queryRunner.query(`CREATE INDEX \"job_status_createdAt_index\" ON \"job\" (\"status\", \"createdAt\") `)\n    await queryRunner.query(`CREATE INDEX \"job_runnerId_status_index\" ON \"job\" (\"runnerId\", \"status\") `)\n    await queryRunner.query(`ALTER TABLE \"runner\" RENAME COLUMN \"version\" TO \"apiVersion\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"appVersion\" character varying DEFAULT 'v0.0.0-dev'`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"domain\" DROP NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP CONSTRAINT \"UQ_330d74ac3d0e349b4c73c62ad6d\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"apiUrl\" DROP NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"proxyUrl\" DROP NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"cpu\" TYPE double precision`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"memoryGiB\" TYPE double precision`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"diskGiB\" TYPE double precision`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"gpu\" DROP NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"gpuType\" DROP NOT NULL`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"gpuType\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"gpu\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"diskGiB\" TYPE integer`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"memoryGiB\" TYPE integer`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"cpu\" TYPE integer`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"proxyUrl\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"apiUrl\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD CONSTRAINT \"UQ_330d74ac3d0e349b4c73c62ad6d\" UNIQUE (\"domain\")`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"domain\" SET NOT NULL`)\n    await queryRunner.query(`ALTER TABLE \"runner\" RENAME COLUMN \"apiVersion\" TO \"version\"`)\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"appVersion\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"job_runnerId_status_index\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"job_status_createdAt_index\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"job_resourceType_resourceId_index\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"IDX_UNIQUE_INCOMPLETE_JOB\"`)\n    await queryRunner.query(`DROP TABLE \"job\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"job_resourcetype_enum\"`)\n    await queryRunner.query(`DROP TYPE \"public\".\"job_status_enum\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1768461678804-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1768461678804 implements MigrationInterface {\n  name = 'Migration1768461678804'\n\n  // TODO: Add migrationsTransactionMode: 'each', to data-source.ts\n  // TypeORM currently does not support non-transactional reverts\n  // Needed because CREATE/DROP INDEX CONCURRENTLY cannot run inside a transaction\n  // public readonly transaction = false\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`\n      CREATE INDEX IF NOT EXISTS \"idx_sandbox_volumes_gin\"\n      ON \"sandbox\"\n      USING GIN (\"volumes\" jsonb_path_ops)\n      WHERE \"desiredState\" <> 'destroyed';\n    `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`\n      DROP INDEX IF EXISTS \"idx_sandbox_volumes_gin\";\n    `)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1768475454675-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1768475454675 implements MigrationInterface {\n  name = 'Migration1768475454675'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `CREATE INDEX \"idx_region_custom\" ON \"region\" (\"organizationId\") WHERE \"regionType\" = 'custom'`,\n    )\n    await queryRunner.query(\n      `CREATE UNIQUE INDEX \"region_sshGatewayApiKeyHash_unique\" ON \"region\" (\"sshGatewayApiKeyHash\") WHERE \"sshGatewayApiKeyHash\" IS NOT NULL`,\n    )\n    await queryRunner.query(\n      `CREATE UNIQUE INDEX \"region_proxyApiKeyHash_unique\" ON \"region\" (\"proxyApiKeyHash\") WHERE \"proxyApiKeyHash\" IS NOT NULL`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP INDEX \"public\".\"region_proxyApiKeyHash_unique\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"region_sshGatewayApiKeyHash_unique\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"idx_region_custom\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1768485728153-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1768485728153 implements MigrationInterface {\n  name = 'Migration1768485728153'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Note: not using CONCURRENTLY + skipping transactions because of reverting issue: https://github.com/typeorm/typeorm/issues/9981\n\n    await queryRunner.query(`CREATE INDEX \"api_key_org_user_idx\" ON \"api_key\" (\"organizationId\", \"userId\") `)\n    await queryRunner.query(\n      `CREATE INDEX \"warm_pool_find_idx\" ON \"warm_pool\" (\"snapshot\", \"target\", \"class\", \"cpu\", \"mem\", \"disk\", \"gpu\", \"osUser\", \"env\") `,\n    )\n    await queryRunner.query(`CREATE INDEX \"snapshot_runner_state_idx\" ON \"snapshot_runner\" (\"state\") `)\n    await queryRunner.query(`CREATE INDEX \"snapshot_runner_runnerid_idx\" ON \"snapshot_runner\" (\"runnerId\") `)\n    await queryRunner.query(\n      `CREATE INDEX \"snapshot_runner_runnerid_snapshotref_idx\" ON \"snapshot_runner\" (\"runnerId\", \"snapshotRef\") `,\n    )\n    await queryRunner.query(`CREATE INDEX \"snapshot_runner_snapshotref_idx\" ON \"snapshot_runner\" (\"snapshotRef\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_pending_idx\" ON \"sandbox\" (\"id\") WHERE \"pending\" = true`)\n    await queryRunner.query(\n      `CREATE INDEX \"sandbox_active_only_idx\" ON \"sandbox\" (\"id\") WHERE \"state\" <> ALL (ARRAY['destroyed'::sandbox_state_enum, 'archived'::sandbox_state_enum])`,\n    )\n    await queryRunner.query(\n      `CREATE INDEX \"sandbox_runner_state_desired_idx\" ON \"sandbox\" (\"runnerId\", \"state\", \"desiredState\") WHERE \"pending\" = false`,\n    )\n    await queryRunner.query(`CREATE INDEX \"sandbox_backupstate_idx\" ON \"sandbox\" (\"backupState\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_resources_idx\" ON \"sandbox\" (\"cpu\", \"mem\", \"disk\", \"gpu\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_region_idx\" ON \"sandbox\" (\"region\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_organizationid_idx\" ON \"sandbox\" (\"organizationId\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_runner_state_idx\" ON \"sandbox\" (\"runnerId\", \"state\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_runnerid_idx\" ON \"sandbox\" (\"runnerId\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_snapshot_idx\" ON \"sandbox\" (\"snapshot\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_desiredstate_idx\" ON \"sandbox\" (\"desiredState\") `)\n    await queryRunner.query(`CREATE INDEX \"sandbox_state_idx\" ON \"sandbox\" (\"state\") `)\n    await queryRunner.query(`CREATE INDEX \"snapshot_state_idx\" ON \"snapshot\" (\"state\") `)\n    await queryRunner.query(`CREATE INDEX \"snapshot_name_idx\" ON \"snapshot\" (\"name\") `)\n    await queryRunner.query(\n      `CREATE INDEX \"sandbox_labels_gin_full_idx\" ON \"sandbox\" USING gin (\"labels\" jsonb_path_ops)`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_labels_gin_full_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"snapshot_name_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"snapshot_state_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_state_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_desiredstate_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_snapshot_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_runnerid_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_runner_state_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_organizationid_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_region_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_resources_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_backupstate_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_runner_state_desired_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_active_only_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"sandbox_pending_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"snapshot_runner_snapshotref_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"snapshot_runner_runnerid_snapshotref_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"snapshot_runner_runnerid_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"snapshot_runner_state_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"warm_pool_find_idx\"`)\n    await queryRunner.query(`DROP INDEX \"public\".\"api_key_org_user_idx\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1768583941244-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1768583941244 implements MigrationInterface {\n  name = 'Migration1768583941244'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"currentCpuLoadAverage\" double precision NOT NULL DEFAULT '0'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"currentCpuLoadAverage\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1769516172576-migration.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1769516172576 implements MigrationInterface {\n  name = 'Migration1769516172576'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // For sandbox_state_enum - add 'resizing' value\n    await queryRunner.query(`ALTER TYPE \"public\".\"sandbox_state_enum\" ADD VALUE IF NOT EXISTS 'resizing'`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    // Drop any index with explicit desiredState enum type cast in WHERE clause (required for enum swap)\n\n    // For sandbox_state_enum - remove 'resizing' value\n    await queryRunner.query(`UPDATE \"sandbox\" SET \"state\" = 'stopped' WHERE \"state\" = 'resizing'`)\n    await queryRunner.query(`ALTER TYPE \"public\".\"sandbox_state_enum\" RENAME TO \"sandbox_state_enum_old\"`)\n    await queryRunner.query(\n      `CREATE TYPE \"public\".\"sandbox_state_enum\" AS ENUM('creating', 'restoring', 'destroyed', 'destroying', 'started', 'stopped', 'starting', 'stopping', 'error', 'build_failed', 'pending_build', 'building_snapshot', 'unknown', 'pulling_snapshot', 'archiving', 'archived')`,\n    )\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" DROP DEFAULT`)\n    await queryRunner.query(\n      `ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" TYPE \"public\".\"sandbox_state_enum\" USING \"state\"::\"text\"::\"public\".\"sandbox_state_enum\"`,\n    )\n    await queryRunner.query(`ALTER TABLE \"sandbox\" ALTER COLUMN \"state\" SET DEFAULT 'unknown'`)\n    await queryRunner.query(`DROP TYPE \"public\".\"sandbox_state_enum_old\"`)\n\n    // Recreate the indices that were dropped\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1769516172577-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1769516172577 implements MigrationInterface {\n  name = 'Migration1769516172577'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"draining\" boolean NOT NULL DEFAULT false`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"draining\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1770043707083-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1770043707083 implements MigrationInterface {\n  name = 'Migration1770043707083'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"experimentalConfig\" jsonb`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"experimentalConfig\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1770212429837-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1770212429837 implements MigrationInterface {\n  name = 'Migration1770212429837'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"authenticated_rate_limit_ttl_seconds\" integer`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"sandbox_create_rate_limit_ttl_seconds\" integer`)\n    await queryRunner.query(`ALTER TABLE \"organization\" ADD \"sandbox_lifecycle_rate_limit_ttl_seconds\" integer`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"sandbox_lifecycle_rate_limit_ttl_seconds\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"sandbox_create_rate_limit_ttl_seconds\"`)\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"authenticated_rate_limit_ttl_seconds\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1770823569571-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1770823569571 implements MigrationInterface {\n  name = 'Migration1770823569571'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Note: not using CONCURRENTLY + skipping transactions because of reverting issue: https://github.com/typeorm/typeorm/issues/9981\n    await queryRunner.query(`CREATE INDEX \"idx_sandbox_authtoken\" ON \"sandbox\" (\"authToken\") `)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP INDEX \"public\".\"idx_sandbox_authtoken\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/1770880371265-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1770880371265 implements MigrationInterface {\n  name = 'Migration1770880371265'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    // Note: not using CONCURRENTLY + skipping transactions because of reverting issue: https://github.com/typeorm/typeorm/issues/9981\n    await queryRunner.query(\n      `CREATE INDEX \"idx_sandbox_usage_periods_sandbox_end\" ON \"sandbox_usage_periods\" (\"sandboxId\", \"endAt\") `,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`DROP INDEX \"public\".\"idx_sandbox_usage_periods_sandbox_end\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/README.md",
    "content": "# Database Migrations\n\nThis project uses the **Expand and Contract** pattern for database migrations to support zero-downtime deployments.\n\n## Overview\n\nThe expand and contract pattern splits database changes into two phases:\n\n- **Pre-deploy (Expand)**: Additive, non-breaking changes that are backwards compatible with the current API version\n- **Post-deploy (Contract)**: Breaking changes that require the new API version to be deployed first\n\nThis allows the database and API to be updated independently while maintaining compatibility during the deployment window.\n\n## Migration Folders\n\n- `pre-deploy/` - Migrations that run **before** the API is deployed\n- `post-deploy/` - Migrations that run **after** the API is deployed\n\nNote: Root folder migrations (not in pre-deploy or post-deploy) are legacy migrations created before the expand-and-contract pattern was introduced. These run during `migration:run:init` only.\n\n## Developer Workflow\n\n### 1. Make Changes to Database Entities\n\nModify the TypeORM entity files in `src/**/*.entity.ts` as needed.\n\n### 2. Generate Migrations\n\nRun the migration generator:\n\n```bash\nnpm run migration:generate\n```\n\nThis creates the **same autogenerated migration in both** `pre-deploy/` and `post-deploy/` folders with a timestamp prefix.\n\n### 3. Analyze and Adjust Migrations\n\n**This is the critical step.** You MUST analyze the generated migrations and determine:\n\n- Which changes are safe to run before the API deployment (pre-deploy)\n- Which changes require the new API to be running first (post-deploy)\n- Whether manual adjustments are needed for zero-downtime compatibility\n\n#### Example Scenarios\n\n**Adding a new field (Pre-deploy only)**\n\nWhen adding a new nullable column or a column with a default value:\n\n```typescript\n// pre-deploy/migration.ts\npublic async up(queryRunner: QueryRunner): Promise<void> {\n  await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"description\" varchar NULL`);\n}\n```\n\n```typescript\n// post-deploy/migration.ts\n// DELETE the generated migration - no post-deploy changes needed\n```\n\nThe new column can be added before the API deployment since the old API will simply ignore it.\n\n---\n\n**Dropping a field (Post-deploy only)**\n\nWhen removing a column:\n\n```typescript\n// pre-deploy/migration.ts\n// DELETE the generated migration - no pre-deploy changes needed\n```\n\n```typescript\n// post-deploy/migration.ts\npublic async up(queryRunner: QueryRunner): Promise<void> {\n  await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"legacy_field\"`);\n}\n```\n\nThe column must only be dropped after the new API is deployed, since the old API may still be reading from it.\n\n---\n\n**Renaming a field (Expand then Contract)**\n\nRenaming requires both phases to maintain zero-downtime. Use a **database trigger** to keep columns synchronized automatically:\n\n```typescript\n// pre-deploy/migration.ts (Expand)\npublic async up(queryRunner: QueryRunner): Promise<void> {\n  // Add new column\n  await queryRunner.query(`ALTER TABLE \"workspace\" ADD \"display_name\" varchar NULL`);\n  // Copy existing data\n  await queryRunner.query(`UPDATE \"workspace\" SET \"display_name\" = \"name\"`);\n  // Create trigger to keep columns in sync during transition\n  await queryRunner.query(`\n    CREATE OR REPLACE FUNCTION sync_workspace_name()\n    RETURNS TRIGGER AS $$\n    BEGIN\n      IF NEW.display_name IS NOT NULL THEN\n        NEW.name := NEW.display_name;\n      ELSIF NEW.name IS NOT NULL THEN\n        NEW.display_name := NEW.name;\n      END IF;\n      RETURN NEW;\n    END;\n    $$ LANGUAGE plpgsql;\n  `);\n  await queryRunner.query(`\n    CREATE TRIGGER workspace_name_sync\n    BEFORE INSERT OR UPDATE ON \"workspace\"\n    FOR EACH ROW EXECUTE FUNCTION sync_workspace_name();\n  `);\n}\n```\n\n```typescript\n// post-deploy/migration.ts (Contract)\npublic async up(queryRunner: QueryRunner): Promise<void> {\n  // Remove trigger and old column\n  await queryRunner.query(`DROP TRIGGER workspace_name_sync ON \"workspace\"`);\n  await queryRunner.query(`DROP FUNCTION sync_workspace_name()`);\n  await queryRunner.query(`ALTER TABLE \"workspace\" DROP COLUMN \"name\"`);\n}\n```\n\n**How the trigger works:**\n\nThe trigger intercepts every INSERT and UPDATE on the table and automatically copies the value between columns:\n\n| API Version | Writes to | Trigger copies to | Result |\n|-------------|-----------|-------------------|--------|\n| Old API | `name` | `display_name` | Both columns have the value |\n| New API | `display_name` | `name` | Both columns have the value |\n\n**Deployment timeline:**\n\n1. **Pre-deploy migration runs** → Trigger is active, both columns exist\n2. **Rolling deployment begins** → Mix of old and new API instances, trigger keeps data in sync\n3. **Rolling deployment completes** → All instances are new API\n4. **Post-deploy migration runs** → Trigger and old column are removed\n\n**New API code changes:**\n\nThe new API should read from and write to `display_name` only. The trigger handles backward compatibility with old API instances—no dual-write logic needed in application code.\n\n## Migration Scripts\n\n### `npm run migration:run:init`\n\nRuns **all migrations** from both pre-deploy and post-deploy folders. Use this for:\n\n- Initial database setup\n- Development environments\n- Fresh database instances\n\n### `npm run migration:run:pre-deploy`\n\nRuns only migrations in the `pre-deploy/` folder. Use this:\n\n- **Before** deploying a new API version\n- As part of your CI/CD pipeline, before the rolling update begins\n\n### `npm run migration:run:post-deploy`\n\nRuns only migrations in the `post-deploy/` folder. Use this:\n\n- **After** the new API version is fully deployed\n- As part of your CI/CD pipeline, after the rolling update completes\n\n## Reverting Migrations\n\n```bash\nnpm run migration:revert\n```\n\nThis reverts the **last executed migration** from either folder (based on the combined migration history in the database).\n\n**Important behaviors:**\n\n- Reverts one migration at a time - run multiple times to revert multiple migrations\n- Uses the combined data-source that sees all migrations\n- The revert order follows the execution timestamp, not the folder structure\n- Always test revert scripts in development before relying on them in production\n\n**Recommendation:** After reverting, you may need to also revert the corresponding entity changes and regenerate migrations to keep everything in sync.\n"
  },
  {
    "path": "apps/api/src/migrations/data-source.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DataSource, DataSourceOptions } from 'typeorm'\nimport { CustomNamingStrategy } from '../common/utils/naming-strategy.util'\nimport { join } from 'path'\nimport { config } from 'dotenv'\n\nconfig({ path: [join(__dirname, '../../.env'), join(__dirname, '../../.env.local')] })\n\nexport const baseDataSourceOptions: DataSourceOptions = {\n  type: 'postgres' as const,\n  host: process.env.DB_HOST,\n  port: parseInt(process.env.DB_PORT!, 10),\n  username: process.env.DB_USERNAME,\n  password: process.env.DB_PASSWORD,\n  database: process.env.DB_DATABASE,\n  synchronize: false,\n  migrationsRun: false,\n  logging: process.env.DB_LOGGING === 'true',\n  namingStrategy: new CustomNamingStrategy(),\n  entities: [join(__dirname, '../**/*.entity.ts')],\n  entitySkipConstructor: true,\n}\n\nconst AppDataSource = new DataSource({\n  ...baseDataSourceOptions,\n  migrations: [join(__dirname, '**/*-migration.{ts,js}')],\n})\n\nexport default AppDataSource\n"
  },
  {
    "path": "apps/api/src/migrations/post-deploy/data-source.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { join } from 'path'\nimport { DataSource } from 'typeorm'\nimport { baseDataSourceOptions } from '../data-source'\n\nconst PostDeployDataSource = new DataSource({\n  ...baseDataSourceOptions,\n  migrations: [join(__dirname, '*-migration.{ts,js}')],\n})\n\nexport default PostDeployDataSource\n"
  },
  {
    "path": "apps/api/src/migrations/pre-deploy/1770900000000-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1770900000000 implements MigrationInterface {\n  name = 'Migration1770900000000'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `ALTER TABLE \"organization\" ADD \"snapshot_deactivation_timeout_minutes\" integer NOT NULL DEFAULT 20160`,\n    )\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"organization\" DROP COLUMN \"snapshot_deactivation_timeout_minutes\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/pre-deploy/1773744656413-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1773744656413 implements MigrationInterface {\n  name = 'Migration1773744656413'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"currentAllocatedCpu\" TYPE double precision`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"currentAllocatedMemoryGiB\" TYPE double precision`)\n    await queryRunner.query(`ALTER TABLE \"runner\" ALTER COLUMN \"currentAllocatedDiskGiB\" TYPE double precision`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(\n      `ALTER TABLE \"runner\" ALTER COLUMN \"currentAllocatedDiskGiB\" TYPE integer USING ROUND(\"currentAllocatedDiskGiB\")::integer`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"runner\" ALTER COLUMN \"currentAllocatedMemoryGiB\" TYPE integer USING ROUND(\"currentAllocatedMemoryGiB\")::integer`,\n    )\n    await queryRunner.query(\n      `ALTER TABLE \"runner\" ALTER COLUMN \"currentAllocatedCpu\" TYPE integer USING ROUND(\"currentAllocatedCpu\")::integer`,\n    )\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/pre-deploy/1773916204375-migration.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MigrationInterface, QueryRunner } from 'typeorm'\n\nexport class Migration1773916204375 implements MigrationInterface {\n  name = 'Migration1773916204375'\n\n  public async up(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" ADD \"serviceHealth\" jsonb`)\n  }\n\n  public async down(queryRunner: QueryRunner): Promise<void> {\n    await queryRunner.query(`ALTER TABLE \"runner\" DROP COLUMN \"serviceHealth\"`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/migrations/pre-deploy/data-source.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { join } from 'path'\nimport { DataSource } from 'typeorm'\nimport { baseDataSourceOptions } from '../data-source'\n\nconst PreDeployDataSource = new DataSource({\n  ...baseDataSourceOptions,\n  migrations: [join(__dirname, '*-migration.{ts,js}')],\n})\n\nexport default PreDeployDataSource\n"
  },
  {
    "path": "apps/api/src/notification/emitters/notification-redis.emitter.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, OnModuleInit } from '@nestjs/common'\nimport { Emitter } from '@socket.io/redis-emitter'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\nimport { NotificationEmitter } from '../gateways/notification-emitter.abstract'\nimport { SandboxDto } from '../../sandbox/dto/sandbox.dto'\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\nimport { SandboxDesiredState } from '../../sandbox/enums/sandbox-desired-state.enum'\nimport { SandboxEvents } from '../../sandbox/constants/sandbox-events.constants'\nimport { SnapshotDto } from '../../sandbox/dto/snapshot.dto'\nimport { SnapshotState } from '../../sandbox/enums/snapshot-state.enum'\nimport { SnapshotEvents } from '../../sandbox/constants/snapshot-events'\nimport { VolumeDto } from '../../sandbox/dto/volume.dto'\nimport { VolumeState } from '../../sandbox/enums/volume-state.enum'\nimport { VolumeEvents } from '../../sandbox/constants/volume-events'\nimport { RunnerDto } from '../../sandbox/dto/runner.dto'\nimport { RunnerState } from '../../sandbox/enums/runner-state.enum'\nimport { RunnerEvents } from '../../sandbox/constants/runner-events'\n\n@Injectable()\nexport class NotificationRedisEmitter extends NotificationEmitter implements OnModuleInit {\n  private readonly logger = new Logger(NotificationRedisEmitter.name)\n  private emitter: Emitter\n\n  constructor(@InjectRedis() private readonly redis: Redis) {\n    super()\n  }\n\n  onModuleInit() {\n    this.emitter = new Emitter(this.redis.duplicate())\n    this.logger.debug('Socket.io Redis emitter initialized (publish-only)')\n  }\n\n  emitSandboxCreated(sandbox: SandboxDto) {\n    this.emitter.to(sandbox.organizationId).emit(SandboxEvents.CREATED, sandbox)\n  }\n\n  emitSandboxStateUpdated(sandbox: SandboxDto, oldState: SandboxState, newState: SandboxState) {\n    this.emitter.to(sandbox.organizationId).emit(SandboxEvents.STATE_UPDATED, { sandbox, oldState, newState })\n  }\n\n  emitSandboxDesiredStateUpdated(\n    sandbox: SandboxDto,\n    oldDesiredState: SandboxDesiredState,\n    newDesiredState: SandboxDesiredState,\n  ) {\n    this.emitter\n      .to(sandbox.organizationId)\n      .emit(SandboxEvents.DESIRED_STATE_UPDATED, { sandbox, oldDesiredState, newDesiredState })\n  }\n\n  emitSnapshotCreated(snapshot: SnapshotDto) {\n    this.emitter.to(snapshot.organizationId).emit(SnapshotEvents.CREATED, snapshot)\n  }\n\n  emitSnapshotStateUpdated(snapshot: SnapshotDto, oldState: SnapshotState, newState: SnapshotState) {\n    this.emitter\n      .to(snapshot.organizationId)\n      .emit(SnapshotEvents.STATE_UPDATED, { snapshot: snapshot, oldState, newState })\n  }\n\n  emitSnapshotRemoved(snapshot: SnapshotDto) {\n    this.emitter.to(snapshot.organizationId).emit(SnapshotEvents.REMOVED, snapshot)\n  }\n\n  emitVolumeCreated(volume: VolumeDto) {\n    this.emitter.to(volume.organizationId).emit(VolumeEvents.CREATED, volume)\n  }\n\n  emitVolumeStateUpdated(volume: VolumeDto, oldState: VolumeState, newState: VolumeState) {\n    this.emitter.to(volume.organizationId).emit(VolumeEvents.STATE_UPDATED, { volume, oldState, newState })\n  }\n\n  emitVolumeLastUsedAtUpdated(volume: VolumeDto) {\n    this.emitter.to(volume.organizationId).emit(VolumeEvents.LAST_USED_AT_UPDATED, volume)\n  }\n\n  emitRunnerCreated(runner: RunnerDto, organizationId: string | null) {\n    if (!organizationId) {\n      return\n    }\n    this.emitter.to(organizationId).emit(RunnerEvents.CREATED, runner)\n  }\n\n  emitRunnerStateUpdated(\n    runner: RunnerDto,\n    organizationId: string | null,\n    oldState: RunnerState,\n    newState: RunnerState,\n  ) {\n    if (!organizationId) {\n      return\n    }\n    this.emitter.to(organizationId).emit(RunnerEvents.STATE_UPDATED, { runner, oldState, newState })\n  }\n\n  emitRunnerUnschedulableUpdated(runner: RunnerDto, organizationId: string | null) {\n    if (!organizationId) {\n      return\n    }\n    this.emitter.to(organizationId).emit(RunnerEvents.UNSCHEDULABLE_UPDATED, runner)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/notification/gateways/notification-emitter.abstract.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SandboxDto } from '../../sandbox/dto/sandbox.dto'\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\nimport { SandboxDesiredState } from '../../sandbox/enums/sandbox-desired-state.enum'\nimport { SnapshotDto } from '../../sandbox/dto/snapshot.dto'\nimport { SnapshotState } from '../../sandbox/enums/snapshot-state.enum'\nimport { VolumeDto } from '../../sandbox/dto/volume.dto'\nimport { VolumeState } from '../../sandbox/enums/volume-state.enum'\nimport { RunnerDto } from '../../sandbox/dto/runner.dto'\nimport { RunnerState } from '../../sandbox/enums/runner-state.enum'\n\nexport abstract class NotificationEmitter {\n  abstract emitSandboxCreated(sandbox: SandboxDto): void\n  abstract emitSandboxStateUpdated(sandbox: SandboxDto, oldState: SandboxState, newState: SandboxState): void\n  abstract emitSandboxDesiredStateUpdated(\n    sandbox: SandboxDto,\n    oldDesiredState: SandboxDesiredState,\n    newDesiredState: SandboxDesiredState,\n  ): void\n  abstract emitSnapshotCreated(snapshot: SnapshotDto): void\n  abstract emitSnapshotStateUpdated(snapshot: SnapshotDto, oldState: SnapshotState, newState: SnapshotState): void\n  abstract emitSnapshotRemoved(snapshot: SnapshotDto): void\n  abstract emitVolumeCreated(volume: VolumeDto): void\n  abstract emitVolumeStateUpdated(volume: VolumeDto, oldState: VolumeState, newState: VolumeState): void\n  abstract emitVolumeLastUsedAtUpdated(volume: VolumeDto): void\n  abstract emitRunnerCreated(runner: RunnerDto, organizationId: string | null): void\n  abstract emitRunnerStateUpdated(\n    runner: RunnerDto,\n    organizationId: string | null,\n    oldState: RunnerState,\n    newState: RunnerState,\n  ): void\n  abstract emitRunnerUnschedulableUpdated(runner: RunnerDto, organizationId: string | null): void\n}\n"
  },
  {
    "path": "apps/api/src/notification/gateways/notification.gateway.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Logger, OnModuleInit, UnauthorizedException } from '@nestjs/common'\nimport { WebSocketGateway, WebSocketServer, OnGatewayInit } from '@nestjs/websockets'\nimport { Server, Socket } from 'socket.io'\nimport { createAdapter } from '@socket.io/redis-adapter'\nimport { SandboxEvents } from '../../sandbox/constants/sandbox-events.constants'\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\nimport { SandboxDto } from '../../sandbox/dto/sandbox.dto'\nimport { SnapshotDto } from '../../sandbox/dto/snapshot.dto'\nimport { SnapshotEvents } from '../../sandbox/constants/snapshot-events'\nimport { SnapshotState } from '../../sandbox/enums/snapshot-state.enum'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\nimport { JwtStrategy } from '../../auth/jwt.strategy'\nimport { ApiKeyStrategy } from '../../auth/api-key.strategy'\nimport { isAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { VolumeEvents } from '../../sandbox/constants/volume-events'\nimport { VolumeDto } from '../../sandbox/dto/volume.dto'\nimport { VolumeState } from '../../sandbox/enums/volume-state.enum'\nimport { SandboxDesiredState } from '../../sandbox/enums/sandbox-desired-state.enum'\nimport { RunnerDto } from '../../sandbox/dto/runner.dto'\nimport { RunnerState } from '../../sandbox/enums/runner-state.enum'\nimport { RunnerEvents } from '../../sandbox/constants/runner-events'\nimport { NotificationEmitter } from './notification-emitter.abstract'\n\n@WebSocketGateway({\n  path: '/api/socket.io/',\n  transports: ['websocket'],\n})\nexport class NotificationGateway extends NotificationEmitter implements OnGatewayInit, OnModuleInit {\n  private readonly logger = new Logger(NotificationGateway.name)\n\n  @WebSocketServer()\n  server: Server\n\n  constructor(\n    private readonly jwtStrategy: JwtStrategy,\n    private readonly apiKeyStrategy: ApiKeyStrategy,\n    @InjectRedis() private readonly redis: Redis,\n  ) {\n    super()\n  }\n\n  onModuleInit() {\n    const pubClient = this.redis.duplicate()\n    const subClient = pubClient.duplicate()\n    this.server.adapter(createAdapter(pubClient, subClient))\n    this.logger.debug('Socket.io initialized with Redis adapter')\n  }\n\n  afterInit(server: Server) {\n    this.logger.debug('WebSocket Gateway initialized')\n\n    server.use(async (socket: Socket, next) => {\n      const token = socket.handshake.auth.token\n      if (!token) {\n        return next(new UnauthorizedException())\n      }\n\n      // Try JWT authentication first\n      try {\n        const payload = await this.jwtStrategy.verifyToken(token)\n\n        // Join the user room for user scoped notifications\n        await socket.join(payload.sub)\n\n        // Join the organization room for organization scoped notifications\n        const organizationId = socket.handshake.query.organizationId as string | undefined\n        if (organizationId) {\n          await socket.join(organizationId)\n        }\n\n        return next()\n      } catch {\n        // JWT failed, try API key authentication\n      }\n\n      // Try API key authentication\n      try {\n        const authContext = await this.apiKeyStrategy.validate(token)\n\n        if (isAuthContext(authContext)) {\n          // Join the user room for user scoped notifications\n          await socket.join(authContext.userId)\n\n          // Join the organization room for organization scoped notifications\n          if (authContext.organizationId) {\n            await socket.join(authContext.organizationId)\n          }\n\n          return next()\n        }\n\n        return next(new UnauthorizedException())\n      } catch {\n        return next(new UnauthorizedException())\n      }\n    })\n  }\n\n  emitSandboxCreated(sandbox: SandboxDto) {\n    this.server.to(sandbox.organizationId).emit(SandboxEvents.CREATED, sandbox)\n  }\n\n  emitSandboxStateUpdated(sandbox: SandboxDto, oldState: SandboxState, newState: SandboxState) {\n    this.server.to(sandbox.organizationId).emit(SandboxEvents.STATE_UPDATED, { sandbox, oldState, newState })\n  }\n\n  emitSandboxDesiredStateUpdated(\n    sandbox: SandboxDto,\n    oldDesiredState: SandboxDesiredState,\n    newDesiredState: SandboxDesiredState,\n  ) {\n    this.server\n      .to(sandbox.organizationId)\n      .emit(SandboxEvents.DESIRED_STATE_UPDATED, { sandbox, oldDesiredState, newDesiredState })\n  }\n\n  emitSnapshotCreated(snapshot: SnapshotDto) {\n    this.server.to(snapshot.organizationId).emit(SnapshotEvents.CREATED, snapshot)\n  }\n\n  emitSnapshotStateUpdated(snapshot: SnapshotDto, oldState: SnapshotState, newState: SnapshotState) {\n    this.server\n      .to(snapshot.organizationId)\n      .emit(SnapshotEvents.STATE_UPDATED, { snapshot: snapshot, oldState, newState })\n  }\n\n  emitSnapshotRemoved(snapshot: SnapshotDto) {\n    this.server.to(snapshot.organizationId).emit(SnapshotEvents.REMOVED, snapshot)\n  }\n\n  emitVolumeCreated(volume: VolumeDto) {\n    this.server.to(volume.organizationId).emit(VolumeEvents.CREATED, volume)\n  }\n\n  emitVolumeStateUpdated(volume: VolumeDto, oldState: VolumeState, newState: VolumeState) {\n    this.server.to(volume.organizationId).emit(VolumeEvents.STATE_UPDATED, { volume, oldState, newState })\n  }\n\n  emitVolumeLastUsedAtUpdated(volume: VolumeDto) {\n    this.server.to(volume.organizationId).emit(VolumeEvents.LAST_USED_AT_UPDATED, volume)\n  }\n\n  emitRunnerCreated(runner: RunnerDto, organizationId: string | null) {\n    if (!organizationId) {\n      return\n    }\n    this.server.to(organizationId).emit(RunnerEvents.CREATED, runner)\n  }\n\n  emitRunnerStateUpdated(\n    runner: RunnerDto,\n    organizationId: string | null,\n    oldState: RunnerState,\n    newState: RunnerState,\n  ) {\n    if (!organizationId) {\n      return\n    }\n    this.server.to(organizationId).emit(RunnerEvents.STATE_UPDATED, { runner, oldState, newState })\n  }\n\n  emitRunnerUnschedulableUpdated(runner: RunnerDto, organizationId: string | null) {\n    if (!organizationId) {\n      return\n    }\n    this.server.to(organizationId).emit(RunnerEvents.UNSCHEDULABLE_UPDATED, runner)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/notification/notification.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { NotificationService } from './services/notification.service'\nimport { NotificationGateway } from './gateways/notification.gateway'\nimport { NotificationRedisEmitter } from './emitters/notification-redis.emitter'\nimport { NotificationEmitter } from './gateways/notification-emitter.abstract'\nimport { OrganizationModule } from '../organization/organization.module'\nimport { SandboxModule } from '../sandbox/sandbox.module'\nimport { RedisModule } from '@nestjs-modules/ioredis'\nimport { AuthModule } from '../auth/auth.module'\nimport { RegionModule } from '../region/region.module'\nimport { isApiEnabled } from '../common/utils/app-mode'\n\nconst gatewayEnabled = isApiEnabled() && process.env.NOTIFICATION_GATEWAY_DISABLED !== 'true'\n\n@Module({\n  imports: [OrganizationModule, SandboxModule, RedisModule, AuthModule, RegionModule],\n  providers: [\n    NotificationService,\n    ...(gatewayEnabled\n      ? [NotificationGateway, { provide: NotificationEmitter, useExisting: NotificationGateway }]\n      : [{ provide: NotificationEmitter, useClass: NotificationRedisEmitter }]),\n  ],\n  exports: [NotificationService],\n})\nexport class NotificationModule {}\n"
  },
  {
    "path": "apps/api/src/notification/services/notification.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable } from '@nestjs/common'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport { NotificationEmitter } from '../gateways/notification-emitter.abstract'\nimport { SandboxEvents } from '../../sandbox/constants/sandbox-events.constants'\nimport { SandboxCreatedEvent } from '../../sandbox/events/sandbox-create.event'\nimport { SandboxStateUpdatedEvent } from '../../sandbox/events/sandbox-state-updated.event'\nimport { SnapshotCreatedEvent } from '../../sandbox/events/snapshot-created.event'\nimport { SnapshotEvents } from '../../sandbox/constants/snapshot-events'\nimport { SnapshotDto } from '../../sandbox/dto/snapshot.dto'\nimport { SnapshotStateUpdatedEvent } from '../../sandbox/events/snapshot-state-updated.event'\nimport { SnapshotRemovedEvent } from '../../sandbox/events/snapshot-removed.event'\nimport { VolumeEvents } from '../../sandbox/constants/volume-events'\nimport { VolumeCreatedEvent } from '../../sandbox/events/volume-created.event'\nimport { VolumeDto } from '../../sandbox/dto/volume.dto'\nimport { VolumeStateUpdatedEvent } from '../../sandbox/events/volume-state-updated.event'\nimport { VolumeLastUsedAtUpdatedEvent } from '../../sandbox/events/volume-last-used-at-updated.event'\nimport { SandboxDesiredStateUpdatedEvent } from '../../sandbox/events/sandbox-desired-state-updated.event'\nimport { RunnerEvents } from '../../sandbox/constants/runner-events'\nimport { RunnerDto } from '../../sandbox/dto/runner.dto'\nimport { RunnerCreatedEvent } from '../../sandbox/events/runner-created.event'\nimport { RunnerStateUpdatedEvent } from '../../sandbox/events/runner-state-updated.event'\nimport { RunnerUnschedulableUpdatedEvent } from '../../sandbox/events/runner-unschedulable-updated.event'\nimport { RegionService } from '../../region/services/region.service'\nimport { SandboxService } from '../../sandbox/services/sandbox.service'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { SANDBOX_EVENT_CHANNEL } from '../../common/constants/constants'\n\n@Injectable()\nexport class NotificationService {\n  constructor(\n    private readonly notificationEmitter: NotificationEmitter,\n    private readonly regionService: RegionService,\n    private readonly sandboxService: SandboxService,\n    @InjectRedis() private readonly redis: Redis,\n  ) {}\n\n  @OnEvent(SandboxEvents.CREATED)\n  async handleSandboxCreated(event: SandboxCreatedEvent) {\n    const dto = await this.sandboxService.toSandboxDto(event.sandbox)\n    this.notificationEmitter.emitSandboxCreated(dto)\n  }\n\n  @OnEvent(SandboxEvents.STATE_UPDATED)\n  async handleSandboxStateUpdated(event: SandboxStateUpdatedEvent) {\n    const dto = await this.sandboxService.toSandboxDto(event.sandbox)\n    this.notificationEmitter.emitSandboxStateUpdated(dto, event.oldState, event.newState)\n    this.redis.publish(SANDBOX_EVENT_CHANNEL, JSON.stringify(event))\n  }\n\n  @OnEvent(SandboxEvents.DESIRED_STATE_UPDATED)\n  async handleSandboxDesiredStateUpdated(event: SandboxDesiredStateUpdatedEvent) {\n    const dto = await this.sandboxService.toSandboxDto(event.sandbox)\n    this.notificationEmitter.emitSandboxDesiredStateUpdated(dto, event.oldDesiredState, event.newDesiredState)\n    this.redis.publish(SANDBOX_EVENT_CHANNEL, JSON.stringify(event))\n  }\n\n  @OnEvent(SnapshotEvents.CREATED)\n  async handleSnapshotCreated(event: SnapshotCreatedEvent) {\n    const dto = SnapshotDto.fromSnapshot(event.snapshot)\n    this.notificationEmitter.emitSnapshotCreated(dto)\n  }\n\n  @OnEvent(SnapshotEvents.STATE_UPDATED)\n  async handleSnapshotStateUpdated(event: SnapshotStateUpdatedEvent) {\n    const dto = SnapshotDto.fromSnapshot(event.snapshot)\n    this.notificationEmitter.emitSnapshotStateUpdated(dto, event.oldState, event.newState)\n  }\n\n  @OnEvent(SnapshotEvents.REMOVED)\n  async handleSnapshotRemoved(event: SnapshotRemovedEvent) {\n    const dto = SnapshotDto.fromSnapshot(event.snapshot)\n    this.notificationEmitter.emitSnapshotRemoved(dto)\n  }\n\n  @OnEvent(VolumeEvents.CREATED)\n  async handleVolumeCreated(event: VolumeCreatedEvent) {\n    const dto = VolumeDto.fromVolume(event.volume)\n    this.notificationEmitter.emitVolumeCreated(dto)\n  }\n\n  @OnEvent(VolumeEvents.STATE_UPDATED)\n  async handleVolumeStateUpdated(event: VolumeStateUpdatedEvent) {\n    const dto = VolumeDto.fromVolume(event.volume)\n    this.notificationEmitter.emitVolumeStateUpdated(dto, event.oldState, event.newState)\n  }\n\n  @OnEvent(VolumeEvents.LAST_USED_AT_UPDATED)\n  async handleVolumeLastUsedAtUpdated(event: VolumeLastUsedAtUpdatedEvent) {\n    const dto = VolumeDto.fromVolume(event.volume)\n    this.notificationEmitter.emitVolumeLastUsedAtUpdated(dto)\n  }\n\n  @OnEvent(RunnerEvents.CREATED)\n  async handleRunnerCreated(event: RunnerCreatedEvent) {\n    const dto = RunnerDto.fromRunner(event.runner)\n    const organizationId = await this.regionService.getOrganizationId(event.runner.region)\n    if (organizationId !== undefined) {\n      this.notificationEmitter.emitRunnerCreated(dto, organizationId)\n    }\n  }\n\n  @OnEvent(RunnerEvents.STATE_UPDATED)\n  async handleRunnerStateUpdated(event: RunnerStateUpdatedEvent) {\n    const dto = RunnerDto.fromRunner(event.runner)\n    const organizationId = await this.regionService.getOrganizationId(event.runner.region)\n    if (organizationId !== undefined) {\n      this.notificationEmitter.emitRunnerStateUpdated(dto, organizationId, event.oldState, event.newState)\n    }\n  }\n\n  @OnEvent(RunnerEvents.UNSCHEDULABLE_UPDATED)\n  async handleRunnerUnschedulableUpdated(event: RunnerUnschedulableUpdatedEvent) {\n    const dto = RunnerDto.fromRunner(event.runner)\n    const organizationId = await this.regionService.getOrganizationId(event.runner.region)\n    if (organizationId !== undefined) {\n      this.notificationEmitter.emitRunnerUnschedulableUpdated(dto, organizationId)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/object-storage/controllers/object-storage.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Get, UseGuards, HttpCode } from '@nestjs/common'\nimport { ApiOAuth2, ApiTags, ApiOperation, ApiResponse, ApiHeader, ApiBearerAuth } from '@nestjs/swagger'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { ObjectStorageService } from '../services/object-storage.service'\nimport { StorageAccessDto } from '../../sandbox/dto/storage-access-dto'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('object-storage')\n@Controller('object-storage')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class ObjectStorageController {\n  constructor(private readonly objectStorageService: ObjectStorageService) {}\n\n  @Get('push-access')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Get temporary storage access for pushing objects',\n    operationId: 'getPushAccess',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Temporary storage access has been generated',\n    type: StorageAccessDto,\n  })\n  async getPushAccess(@AuthContext() authContext: OrganizationAuthContext): Promise<StorageAccessDto> {\n    return this.objectStorageService.getPushAccess(authContext.organizationId)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/object-storage/object-storage.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { ObjectStorageController } from './controllers/object-storage.controller'\nimport { ObjectStorageService } from './services/object-storage.service'\nimport { ConfigModule } from '@nestjs/config'\nimport { OrganizationModule } from '../organization/organization.module'\n\n@Module({\n  imports: [ConfigModule, OrganizationModule],\n  controllers: [ObjectStorageController],\n  providers: [ObjectStorageService],\n  exports: [ObjectStorageService],\n})\nexport class ObjectStorageModule {}\n"
  },
  {
    "path": "apps/api/src/object-storage/services/object-storage.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BadRequestException, Injectable, Logger, ServiceUnavailableException } from '@nestjs/common'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { StorageAccessDto } from '../../sandbox/dto/storage-access-dto'\nimport axios from 'axios'\nimport * as aws4 from 'aws4'\nimport * as xml2js from 'xml2js'\nimport { STSClient, AssumeRoleCommand } from '@aws-sdk/client-sts'\n\ninterface S3Config {\n  endpoint: string\n  stsEndpoint: string\n  accessKey: string\n  secretKey: string\n  bucket: string\n  region: string\n  accountId?: string\n  roleName?: string\n  organizationId: string\n  policy: any\n}\n\n@Injectable()\nexport class ObjectStorageService {\n  private readonly logger = new Logger(ObjectStorageService.name)\n\n  constructor(private readonly configService: TypedConfigService) {}\n\n  async getPushAccess(organizationId: string): Promise<StorageAccessDto> {\n    if (!this.configService.get('s3.endpoint')) {\n      throw new ServiceUnavailableException('Object storage is not configured')\n    }\n\n    try {\n      const bucket = this.configService.getOrThrow('s3.defaultBucket')\n      const s3Config: S3Config = {\n        endpoint: this.configService.getOrThrow('s3.endpoint'),\n        stsEndpoint: this.configService.getOrThrow('s3.stsEndpoint'),\n        accessKey: this.configService.getOrThrow('s3.accessKey'),\n        secretKey: this.configService.getOrThrow('s3.secretKey'),\n        bucket,\n        region: this.configService.getOrThrow('s3.region'),\n        accountId: this.configService.getOrThrow('s3.accountId'),\n        roleName: this.configService.getOrThrow('s3.roleName'),\n        organizationId,\n        policy: {\n          Version: '2012-10-17',\n          Statement: [\n            {\n              Effect: 'Allow',\n              Action: ['s3:PutObject', 's3:GetObject'],\n              Resource: [`arn:aws:s3:::${bucket}/${organizationId}/*`],\n            },\n            // ListBucket only shows object keys and some metadata, not the actual objects\n            {\n              Effect: 'Allow',\n              Action: ['s3:ListBucket'],\n              Resource: [`arn:aws:s3:::${bucket}`],\n            },\n          ],\n        },\n      }\n\n      const isMinioServer = s3Config.endpoint.includes('minio')\n\n      if (isMinioServer) {\n        return this.getMinioCredentials(s3Config)\n      } else {\n        return this.getAwsCredentials(s3Config)\n      }\n    } catch (error) {\n      this.logger.error('Storage push access error:', error.response?.data || error.message)\n      throw new BadRequestException(`Failed to get temporary credentials: ${error.message}`)\n    }\n  }\n\n  private async getMinioCredentials(config: S3Config): Promise<StorageAccessDto> {\n    const body = new URLSearchParams({\n      Action: 'AssumeRole',\n      Version: '2011-06-15',\n      DurationSeconds: '3600', // 1 hour (in seconds)\n      Policy: JSON.stringify(config.policy),\n    })\n\n    const requestOptions = {\n      host: new URL(config.endpoint).hostname,\n      path: '/minio/v1/assume-role',\n      service: 'sts',\n      method: 'POST',\n      body: body.toString(),\n      headers: {\n        'Content-Type': 'application/x-www-form-urlencoded',\n      },\n    }\n\n    aws4.sign(requestOptions, {\n      accessKeyId: config.accessKey,\n      secretAccessKey: config.secretKey,\n    })\n\n    const response = await axios.post(config.stsEndpoint, body.toString(), {\n      headers: requestOptions.headers,\n    })\n\n    const parser = new xml2js.Parser({ explicitArray: false })\n    const parsedData = await parser.parseStringPromise(response.data)\n\n    if (!parsedData.AssumeRoleResponse.AssumeRoleResult.Credentials) {\n      throw new BadRequestException('MinIO STS response did not return expected credentials')\n    }\n\n    const creds = parsedData.AssumeRoleResponse.AssumeRoleResult.Credentials\n\n    return {\n      accessKey: creds.AccessKeyId,\n      secret: creds.SecretAccessKey,\n      sessionToken: creds.SessionToken,\n      storageUrl: config.endpoint,\n      organizationId: config.organizationId,\n      bucket: config.bucket,\n    }\n  }\n\n  private async getAwsCredentials(config: S3Config): Promise<StorageAccessDto> {\n    try {\n      const stsClient = new STSClient({\n        region: config.region,\n        endpoint: config.stsEndpoint,\n        credentials: {\n          accessKeyId: config.accessKey,\n          secretAccessKey: config.secretKey,\n        },\n        maxAttempts: 3,\n      })\n\n      const command = new AssumeRoleCommand({\n        RoleArn: `arn:aws:iam::${config.accountId}:role/${config.roleName}`,\n        RoleSessionName: `daytona-${config.organizationId}-${Date.now()}`,\n        DurationSeconds: 3600, // One hour\n        Policy: JSON.stringify(config.policy),\n      })\n\n      try {\n        const response = await stsClient.send(command)\n\n        if (!response.Credentials) {\n          throw new BadRequestException('AWS STS response did not return expected credentials')\n        }\n\n        return {\n          accessKey: response.Credentials.AccessKeyId,\n          secret: response.Credentials.SecretAccessKey,\n          sessionToken: response.Credentials.SessionToken,\n          storageUrl: config.endpoint,\n          organizationId: config.organizationId,\n          bucket: config.bucket,\n        }\n      } catch (error: any) {\n        throw new BadRequestException(`Failed to assume role: ${error.message || 'Unknown AWS error'}`)\n      }\n    } catch (error: any) {\n      this.logger.error(`AWS STS client setup error: ${error.message}`, error.stack)\n      throw new BadRequestException(`Failed to setup AWS client: ${error.message}`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/openapi-webhooks.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OpenAPIObject, getSchemaPath } from '@nestjs/swagger'\nimport { WebhookEvent } from './webhook/constants/webhook-events.constants'\nimport {\n  SandboxCreatedWebhookDto,\n  SandboxStateUpdatedWebhookDto,\n  SnapshotCreatedWebhookDto,\n  SnapshotStateUpdatedWebhookDto,\n  SnapshotRemovedWebhookDto,\n  VolumeCreatedWebhookDto,\n  VolumeStateUpdatedWebhookDto,\n} from './webhook/dto/webhook-event-payloads.dto'\n\nexport interface OpenAPIObjectWithWebhooks extends OpenAPIObject {\n  webhooks?: {\n    [key: string]: {\n      post: {\n        requestBody: {\n          description: string\n          content: {\n            'application/json': {\n              schema: any\n            }\n          }\n        }\n        responses: {\n          [statusCode: string]: {\n            description: string\n          }\n        }\n      }\n    }\n  }\n}\n\nexport function addWebhookDocumentation(document: OpenAPIObject): OpenAPIObjectWithWebhooks {\n  return {\n    ...document,\n    webhooks: {\n      [WebhookEvent.SANDBOX_CREATED]: {\n        post: {\n          requestBody: {\n            description: 'Sandbox created event',\n            content: {\n              'application/json': {\n                schema: { $ref: getSchemaPath(SandboxCreatedWebhookDto) },\n              },\n            },\n          },\n          responses: {\n            '200': {\n              description: 'Webhook received successfully',\n            },\n          },\n        },\n      },\n      [WebhookEvent.SANDBOX_STATE_UPDATED]: {\n        post: {\n          requestBody: {\n            description: 'Sandbox state updated event',\n            content: {\n              'application/json': {\n                schema: { $ref: getSchemaPath(SandboxStateUpdatedWebhookDto) },\n              },\n            },\n          },\n          responses: {\n            '200': {\n              description: 'Webhook received successfully',\n            },\n          },\n        },\n      },\n      [WebhookEvent.SNAPSHOT_CREATED]: {\n        post: {\n          requestBody: {\n            description: 'Snapshot created event',\n            content: {\n              'application/json': {\n                schema: { $ref: getSchemaPath(SnapshotCreatedWebhookDto) },\n              },\n            },\n          },\n          responses: {\n            '200': {\n              description: 'Webhook received successfully',\n            },\n          },\n        },\n      },\n      [WebhookEvent.SNAPSHOT_STATE_UPDATED]: {\n        post: {\n          requestBody: {\n            description: 'Snapshot state updated event',\n            content: {\n              'application/json': {\n                schema: { $ref: getSchemaPath(SnapshotStateUpdatedWebhookDto) },\n              },\n            },\n          },\n          responses: {\n            '200': {\n              description: 'Webhook received successfully',\n            },\n          },\n        },\n      },\n      [WebhookEvent.SNAPSHOT_REMOVED]: {\n        post: {\n          requestBody: {\n            description: 'Snapshot removed event',\n            content: {\n              'application/json': {\n                schema: { $ref: getSchemaPath(SnapshotRemovedWebhookDto) },\n              },\n            },\n          },\n          responses: {\n            '200': {\n              description: 'Webhook received successfully',\n            },\n          },\n        },\n      },\n      [WebhookEvent.VOLUME_CREATED]: {\n        post: {\n          requestBody: {\n            description: 'Volume created event',\n            content: {\n              'application/json': {\n                schema: { $ref: getSchemaPath(VolumeCreatedWebhookDto) },\n              },\n            },\n          },\n          responses: {\n            '200': {\n              description: 'Webhook received successfully',\n            },\n          },\n        },\n      },\n      [WebhookEvent.VOLUME_STATE_UPDATED]: {\n        post: {\n          requestBody: {\n            description: 'Volume state updated event',\n            content: {\n              'application/json': {\n                schema: { $ref: getSchemaPath(VolumeStateUpdatedWebhookDto) },\n              },\n            },\n          },\n          responses: {\n            '200': {\n              description: 'Webhook received successfully',\n            },\n          },\n        },\n      },\n    },\n  }\n}\n"
  },
  {
    "path": "apps/api/src/openapi.config.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DocumentBuilder } from '@nestjs/swagger'\n\nconst getOpenApiConfig = (oidcIssuer: string) =>\n  new DocumentBuilder()\n    .setTitle('Daytona')\n    .addServer('http://localhost:3000')\n    .setDescription('Daytona AI platform API Docs')\n    .setContact('Daytona Platforms Inc.', 'https://www.daytona.io', 'support@daytona.com')\n    .setVersion('1.0')\n    .addBearerAuth({\n      type: 'http',\n      scheme: 'bearer',\n      description: 'API Key access',\n    })\n    .addOAuth2({\n      type: 'openIdConnect',\n      flows: undefined,\n      openIdConnectUrl: `${oidcIssuer}/.well-known/openid-configuration`,\n    })\n    .build()\n\nexport { getOpenApiConfig }\n"
  },
  {
    "path": "apps/api/src/organization/constants/global-organization-roles.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const GlobalOrganizationRolesIds = {\n  DEVELOPER: '00000000-0000-0000-0000-000000000001',\n  SANDBOXES_ADMIN: '00000000-0000-0000-0000-000000000002',\n  SNAPSHOTS_ADMIN: '00000000-0000-0000-0000-000000000003',\n  REGISTRIES_ADMIN: '00000000-0000-0000-0000-000000000004',\n  SUPER_ADMIN: '00000000-0000-0000-0000-000000000005',\n  VOLUMES_ADMIN: '00000000-0000-0000-0000-000000000006',\n  AUDITOR: '00000000-0000-0000-0000-000000000007',\n  INFRASTRUCTURE_ADMIN: '00000000-0000-0000-0000-000000000008',\n} as const\n"
  },
  {
    "path": "apps/api/src/organization/constants/organization-events.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const OrganizationEvents = {\n  INVITATION_CREATED: 'invitation.created',\n  INVITATION_ACCEPTED: 'invitation.accepted',\n  INVITATION_DECLINED: 'invitation.declined',\n  INVITATION_CANCELLED: 'invitation.cancelled',\n  CREATED: 'organization.created',\n  SUSPENDED_SANDBOX_STOPPED: 'organization.suspended-sandbox-stopped',\n  SUSPENDED_SNAPSHOT_DEACTIVATED: 'organization.suspended-snapshot-deactivated',\n  PERMISSIONS_UNASSIGNED: 'permissions.unassigned',\n} as const\n"
  },
  {
    "path": "apps/api/src/organization/constants/sandbox-states-consuming-compute.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\n\nexport const SANDBOX_STATES_CONSUMING_COMPUTE: SandboxState[] = [\n  SandboxState.CREATING,\n  SandboxState.RESTORING,\n  SandboxState.STARTED,\n  SandboxState.STARTING,\n  SandboxState.STOPPING,\n  SandboxState.PENDING_BUILD,\n  SandboxState.BUILDING_SNAPSHOT,\n  SandboxState.UNKNOWN,\n  SandboxState.PULLING_SNAPSHOT,\n]\n"
  },
  {
    "path": "apps/api/src/organization/constants/sandbox-states-consuming-disk.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\nimport { SANDBOX_STATES_CONSUMING_COMPUTE } from './sandbox-states-consuming-compute.constant'\n\nexport const SANDBOX_STATES_CONSUMING_DISK: SandboxState[] = [\n  ...SANDBOX_STATES_CONSUMING_COMPUTE,\n  SandboxState.STOPPED,\n  SandboxState.ARCHIVING,\n  SandboxState.RESIZING,\n]\n"
  },
  {
    "path": "apps/api/src/organization/constants/snapshot-states-consuming-resources.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SnapshotState } from '../../sandbox/enums/snapshot-state.enum'\n\nexport const SNAPSHOT_STATES_CONSUMING_RESOURCES: SnapshotState[] = [\n  SnapshotState.BUILDING,\n  SnapshotState.PENDING,\n  SnapshotState.PULLING,\n  SnapshotState.ACTIVE,\n]\n"
  },
  {
    "path": "apps/api/src/organization/constants/volume-states-consuming-resources.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { VolumeState } from '../../sandbox/enums/volume-state.enum'\n\nexport const VOLUME_STATES_CONSUMING_RESOURCES: VolumeState[] = [\n  VolumeState.CREATING,\n  VolumeState.READY,\n  VolumeState.PENDING_CREATE,\n  VolumeState.PENDING_DELETE,\n  VolumeState.DELETING,\n]\n"
  },
  {
    "path": "apps/api/src/organization/controllers/organization-invitation.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Body, Controller, Get, Param, Post, Put, UseGuards } from '@nestjs/common'\nimport { AuthGuard } from '@nestjs/passport'\nimport { ApiOAuth2, ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBearerAuth } from '@nestjs/swagger'\nimport { RequiredOrganizationMemberRole } from '../decorators/required-organization-member-role.decorator'\nimport { CreateOrganizationInvitationDto } from '../dto/create-organization-invitation.dto'\nimport { UpdateOrganizationInvitationDto } from '../dto/update-organization-invitation.dto'\nimport { OrganizationInvitationDto } from '../dto/organization-invitation.dto'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationActionGuard } from '../guards/organization-action.guard'\nimport { OrganizationInvitationService } from '../services/organization-invitation.service'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { AuthContext as IAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('organizations')\n@Controller('organizations/:organizationId/invitations')\n@UseGuards(AuthGuard('jwt'), AuthenticatedRateLimitGuard, OrganizationActionGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class OrganizationInvitationController {\n  constructor(private readonly organizationInvitationService: OrganizationInvitationService) {}\n\n  @Post()\n  @ApiOperation({\n    summary: 'Create organization invitation',\n    operationId: 'createOrganizationInvitation',\n  })\n  @ApiResponse({\n    status: 201,\n    description: 'Organization invitation created successfully',\n    type: OrganizationInvitationDto,\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.ORGANIZATION_INVITATION,\n    targetIdFromResult: (result: OrganizationInvitationDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateOrganizationInvitationDto>) => ({\n        email: req.body?.email,\n        role: req.body?.role,\n        assignedRoleIds: req.body?.assignedRoleIds,\n        expiresAt: req.body?.expiresAt,\n      }),\n    },\n  })\n  async create(\n    @AuthContext() authContext: IAuthContext,\n    @Param('organizationId') organizationId: string,\n    @Body() createOrganizationInvitationDto: CreateOrganizationInvitationDto,\n  ): Promise<OrganizationInvitationDto> {\n    const invitation = await this.organizationInvitationService.create(\n      organizationId,\n      createOrganizationInvitationDto,\n      authContext.email,\n    )\n    return OrganizationInvitationDto.fromOrganizationInvitation(invitation)\n  }\n\n  @Put('/:invitationId')\n  @ApiOperation({\n    summary: 'Update organization invitation',\n    operationId: 'updateOrganizationInvitation',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Organization invitation updated successfully',\n    type: OrganizationInvitationDto,\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'invitationId',\n    description: 'Invitation ID',\n    type: 'string',\n  })\n  @RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n  @Audit({\n    action: AuditAction.UPDATE,\n    targetType: AuditTarget.ORGANIZATION_INVITATION,\n    targetIdFromRequest: (req) => req.params.invitationId,\n    requestMetadata: {\n      body: (req: TypedRequest<UpdateOrganizationInvitationDto>) => ({\n        role: req.body?.role,\n        assignedRoleIds: req.body?.assignedRoleIds,\n        expiresAt: req.body?.expiresAt,\n      }),\n    },\n  })\n  async update(\n    @Param('organizationId') organizationId: string,\n    @Param('invitationId') invitationId: string,\n    @Body() updateOrganizationInvitationDto: UpdateOrganizationInvitationDto,\n  ): Promise<OrganizationInvitationDto> {\n    const invitation = await this.organizationInvitationService.update(invitationId, updateOrganizationInvitationDto)\n    return OrganizationInvitationDto.fromOrganizationInvitation(invitation)\n  }\n\n  @Get()\n  @ApiOperation({\n    summary: 'List pending organization invitations',\n    operationId: 'listOrganizationInvitations',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of pending organization invitations',\n    type: [OrganizationInvitationDto],\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  async findPending(@Param('organizationId') organizationId: string): Promise<OrganizationInvitationDto[]> {\n    const invitations = await this.organizationInvitationService.findPending(organizationId)\n    return invitations.map(OrganizationInvitationDto.fromOrganizationInvitation)\n  }\n\n  @Post('/:invitationId/cancel')\n  @ApiOperation({\n    summary: 'Cancel organization invitation',\n    operationId: 'cancelOrganizationInvitation',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Organization invitation cancelled successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'invitationId',\n    description: 'Invitation ID',\n    type: 'string',\n  })\n  @RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.ORGANIZATION_INVITATION,\n    targetIdFromRequest: (req) => req.params.invitationId,\n  })\n  async cancel(\n    @Param('organizationId') organizationId: string,\n    @Param('invitationId') invitationId: string,\n  ): Promise<void> {\n    return this.organizationInvitationService.cancel(invitationId)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/controllers/organization-region.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Controller,\n  Get,\n  Logger,\n  UseGuards,\n  HttpCode,\n  Post,\n  UseInterceptors,\n  Body,\n  Param,\n  NotFoundException,\n  Delete,\n  Patch,\n} from '@nestjs/common'\nimport { ApiOAuth2, ApiResponse, ApiOperation, ApiTags, ApiBearerAuth, ApiParam, ApiHeader } from '@nestjs/swagger'\nimport { RequiredOrganizationResourcePermissions } from '../decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../enums/organization-resource-permission.enum'\nimport { OrganizationResourceActionGuard } from '../guards/organization-resource-action.guard'\nimport { OrganizationService } from '../services/organization.service'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { ContentTypeInterceptor } from '../../common/interceptors/content-type.interceptors'\nimport { CreateRegionDto, CreateRegionResponseDto } from '../../region/dto/create-region.dto'\nimport { RegionDto } from '../../region/dto/region.dto'\nimport { RegionService } from '../../region/services/region.service'\nimport { RegionAccessGuard } from '../../region/guards/region-access.guard'\nimport { RegenerateApiKeyResponseDto } from '../../region/dto/regenerate-api-key.dto'\nimport { RegionType } from '../../region/enums/region-type.enum'\nimport { RequireFlagsEnabled } from '@openfeature/nestjs-sdk'\nimport { FeatureFlags } from '../../common/constants/feature-flags'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SnapshotManagerCredentialsDto } from '../../region/dto/snapshot-manager-credentials.dto'\nimport { UpdateRegionDto } from '../../region/dto/update-region.dto'\n\n@ApiTags('organizations')\n@Controller('regions')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, OrganizationResourceActionGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class OrganizationRegionController {\n  private readonly logger = new Logger(OrganizationRegionController.name)\n\n  constructor(\n    private readonly regionService: RegionService,\n    private readonly organizationService: OrganizationService,\n  ) {}\n\n  @Get()\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'List all available regions for the organization',\n    operationId: 'listAvailableRegions',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of all available regions',\n    type: [RegionDto],\n  })\n  async listAvailableRegions(@AuthContext() authContext: OrganizationAuthContext): Promise<RegionDto[]> {\n    return this.organizationService.listAvailableRegions(authContext.organizationId)\n  }\n\n  @Post()\n  @HttpCode(201)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: 'Create a new region',\n    operationId: 'createRegion',\n  })\n  @ApiResponse({\n    status: 201,\n    description: 'The region has been successfully created.',\n    type: CreateRegionResponseDto,\n  })\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.REGION,\n    targetIdFromResult: (result: RegionDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateRegionDto>) => ({\n        name: req.body?.name,\n      }),\n    },\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_REGIONS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async createRegion(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Body() createRegionDto: CreateRegionDto,\n  ): Promise<CreateRegionResponseDto> {\n    return await this.regionService.create(\n      {\n        ...createRegionDto,\n        enforceQuotas: false,\n        regionType: RegionType.CUSTOM,\n      },\n      authContext.organizationId,\n    )\n  }\n\n  @Get(':id')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Get region by ID',\n    operationId: 'getRegionById',\n  })\n  @ApiResponse({\n    status: 200,\n    type: RegionDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Region ID',\n    type: String,\n  })\n  @UseGuards(RegionAccessGuard)\n  async getRegionById(@Param('id') id: string): Promise<RegionDto> {\n    const region = await this.regionService.findOne(id)\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n    return RegionDto.fromRegion(region)\n  }\n\n  @Delete(':id')\n  @HttpCode(204)\n  @ApiOperation({\n    summary: 'Delete a region',\n    operationId: 'deleteRegion',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'The region has been successfully deleted.',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Region ID',\n  })\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.REGION,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  @UseGuards(RegionAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.DELETE_REGIONS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async deleteRegion(@Param('id') id: string): Promise<void> {\n    await this.regionService.delete(id)\n  }\n\n  @Post(':id/regenerate-proxy-api-key')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: 'Regenerate proxy API key for a region',\n    operationId: 'regenerateProxyApiKey',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The proxy API key has been successfully regenerated.',\n    type: RegenerateApiKeyResponseDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Region ID',\n    type: String,\n  })\n  @Audit({\n    action: AuditAction.REGENERATE_PROXY_API_KEY,\n    targetType: AuditTarget.REGION,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  @UseGuards(RegionAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_REGIONS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async regenerateProxyApiKey(@Param('id') id: string): Promise<RegenerateApiKeyResponseDto> {\n    const apiKey = await this.regionService.regenerateProxyApiKey(id)\n    return new RegenerateApiKeyResponseDto(apiKey)\n  }\n\n  @Patch(':id')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: 'Update region configuration',\n    operationId: 'updateRegion',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Region ID',\n    type: String,\n  })\n  @Audit({\n    action: AuditAction.UPDATE,\n    targetType: AuditTarget.REGION,\n    targetIdFromRequest: (req) => req.params.id,\n    requestMetadata: {\n      body: (req: TypedRequest<UpdateRegionDto>) => ({\n        ...req.body,\n      }),\n    },\n  })\n  @UseGuards(RegionAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_REGIONS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async updateRegion(@Param('id') id: string, @Body() updateRegionDto: UpdateRegionDto): Promise<void> {\n    return await this.regionService.update(id, updateRegionDto)\n  }\n\n  @Post(':id/regenerate-ssh-gateway-api-key')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: 'Regenerate SSH gateway API key for a region',\n    operationId: 'regenerateSshGatewayApiKey',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The SSH gateway API key has been successfully regenerated.',\n    type: RegenerateApiKeyResponseDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Region ID',\n    type: String,\n  })\n  @Audit({\n    action: AuditAction.REGENERATE_SSH_GATEWAY_API_KEY,\n    targetType: AuditTarget.REGION,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  @UseGuards(RegionAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_REGIONS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async regenerateSshGatewayApiKey(@Param('id') id: string): Promise<RegenerateApiKeyResponseDto> {\n    const apiKey = await this.regionService.regenerateSshGatewayApiKey(id)\n    return new RegenerateApiKeyResponseDto(apiKey)\n  }\n\n  @Post(':id/regenerate-snapshot-manager-credentials')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: 'Regenerate snapshot manager credentials for a region',\n    operationId: 'regenerateSnapshotManagerCredentials',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The snapshot manager credentials have been successfully regenerated.',\n    type: SnapshotManagerCredentialsDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Region ID',\n    type: String,\n  })\n  @Audit({\n    action: AuditAction.REGENERATE_SNAPSHOT_MANAGER_CREDENTIALS,\n    targetType: AuditTarget.REGION,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  @UseGuards(RegionAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_REGIONS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async regenerateSnapshotManagerCredentials(@Param('id') id: string): Promise<SnapshotManagerCredentialsDto> {\n    return await this.regionService.regenerateSnapshotManagerCredentials(id)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/controllers/organization-role.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Body, Controller, Delete, Get, Param, Post, Put, UseGuards } from '@nestjs/common'\nimport { AuthGuard } from '@nestjs/passport'\nimport { ApiOAuth2, ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBearerAuth } from '@nestjs/swagger'\nimport { RequiredOrganizationMemberRole } from '../decorators/required-organization-member-role.decorator'\nimport { CreateOrganizationRoleDto } from '../dto/create-organization-role.dto'\nimport { UpdateOrganizationRoleDto } from '../dto/update-organization-role.dto'\nimport { OrganizationRoleDto } from '../dto/organization-role.dto'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationActionGuard } from '../guards/organization-action.guard'\nimport { OrganizationRoleService } from '../services/organization-role.service'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('organizations')\n@Controller('organizations/:organizationId/roles')\n@UseGuards(AuthGuard('jwt'), AuthenticatedRateLimitGuard, OrganizationActionGuard)\n@RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class OrganizationRoleController {\n  constructor(private readonly organizationRoleService: OrganizationRoleService) {}\n\n  @Post()\n  @ApiOperation({\n    summary: 'Create organization role',\n    operationId: 'createOrganizationRole',\n  })\n  @ApiResponse({\n    status: 201,\n    description: 'Organization role created successfully',\n    type: OrganizationRoleDto,\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.ORGANIZATION_ROLE,\n    targetIdFromResult: (result: OrganizationRoleDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateOrganizationRoleDto>) => ({\n        name: req.body?.name,\n        description: req.body?.description,\n        permissions: req.body?.permissions,\n      }),\n    },\n  })\n  async create(\n    @Param('organizationId') organizationId: string,\n    @Body() createOrganizationRoleDto: CreateOrganizationRoleDto,\n  ): Promise<OrganizationRoleDto> {\n    const role = await this.organizationRoleService.create(organizationId, createOrganizationRoleDto)\n    return OrganizationRoleDto.fromOrganizationRole(role)\n  }\n\n  @Get()\n  @ApiOperation({\n    summary: 'List organization roles',\n    operationId: 'listOrganizationRoles',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of organization roles',\n    type: [OrganizationRoleDto],\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  async findAll(@Param('organizationId') organizationId: string): Promise<OrganizationRoleDto[]> {\n    const roles = await this.organizationRoleService.findAll(organizationId)\n    return roles.map(OrganizationRoleDto.fromOrganizationRole)\n  }\n\n  @Put('/:roleId')\n  @ApiOperation({\n    summary: 'Update organization role',\n    operationId: 'updateOrganizationRole',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Role updated successfully',\n    type: OrganizationRoleDto,\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'roleId',\n    description: 'Role ID',\n    type: 'string',\n  })\n  @Audit({\n    action: AuditAction.UPDATE,\n    targetType: AuditTarget.ORGANIZATION_ROLE,\n    targetIdFromRequest: (req) => req.params.roleId,\n    requestMetadata: {\n      body: (req: TypedRequest<UpdateOrganizationRoleDto>) => ({\n        name: req.body?.name,\n        description: req.body?.description,\n        permissions: req.body?.permissions,\n      }),\n    },\n  })\n  async updateRole(\n    @Param('organizationId') organizationId: string,\n    @Param('roleId') roleId: string,\n    @Body() updateOrganizationRoleDto: UpdateOrganizationRoleDto,\n  ): Promise<OrganizationRoleDto> {\n    const updatedRole = await this.organizationRoleService.update(roleId, updateOrganizationRoleDto)\n    return OrganizationRoleDto.fromOrganizationRole(updatedRole)\n  }\n\n  @Delete('/:roleId')\n  @ApiOperation({\n    summary: 'Delete organization role',\n    operationId: 'deleteOrganizationRole',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Organization role deleted successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'roleId',\n    description: 'Role ID',\n    type: 'string',\n  })\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.ORGANIZATION_ROLE,\n    targetIdFromRequest: (req) => req.params.roleId,\n  })\n  async delete(@Param('organizationId') organizationId: string, @Param('roleId') roleId: string): Promise<void> {\n    return this.organizationRoleService.delete(roleId)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/controllers/organization-user.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Body, Controller, Delete, ForbiddenException, Get, Param, Post, UseGuards } from '@nestjs/common'\nimport { AuthGuard } from '@nestjs/passport'\nimport { ApiOAuth2, ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBearerAuth } from '@nestjs/swagger'\nimport { RequiredOrganizationMemberRole } from '../decorators/required-organization-member-role.decorator'\nimport { UpdateOrganizationMemberAccessDto } from '../dto/update-organization-member-access.dto'\nimport { OrganizationUserDto } from '../dto/organization-user.dto'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationActionGuard } from '../guards/organization-action.guard'\nimport { OrganizationUserService } from '../services/organization-user.service'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { AuthContext as IAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('organizations')\n@Controller('organizations/:organizationId/users')\n@UseGuards(AuthGuard('jwt'), AuthenticatedRateLimitGuard, OrganizationActionGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class OrganizationUserController {\n  constructor(private readonly organizationUserService: OrganizationUserService) {}\n\n  @Get()\n  @ApiOperation({\n    summary: 'List organization members',\n    operationId: 'listOrganizationMembers',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of organization members',\n    type: [OrganizationUserDto],\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  async findAll(@Param('organizationId') organizationId: string): Promise<OrganizationUserDto[]> {\n    return this.organizationUserService.findAll(organizationId)\n  }\n\n  @Post('/:userId/access')\n  @ApiOperation({\n    summary: 'Update access for organization member',\n    operationId: 'updateAccessForOrganizationMember',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Access updated successfully',\n    type: OrganizationUserDto,\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'userId',\n    description: 'User ID',\n    type: 'string',\n  })\n  @RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n  @Audit({\n    action: AuditAction.UPDATE_ACCESS,\n    targetType: AuditTarget.ORGANIZATION_USER,\n    targetIdFromRequest: (req) => req.params.userId,\n    requestMetadata: {\n      body: (req: TypedRequest<UpdateOrganizationMemberAccessDto>) => ({\n        role: req.body?.role,\n        assignedRoleIds: req.body?.assignedRoleIds,\n      }),\n    },\n  })\n  async updateAccess(\n    @AuthContext() authContext: IAuthContext,\n    @Param('organizationId') organizationId: string,\n    @Param('userId') userId: string,\n    @Body() dto: UpdateOrganizationMemberAccessDto,\n  ): Promise<OrganizationUserDto> {\n    if (authContext.userId === userId) {\n      throw new ForbiddenException('You cannot update your own access')\n    }\n\n    return this.organizationUserService.updateAccess(organizationId, userId, dto.role, dto.assignedRoleIds)\n  }\n\n  @Delete('/:userId')\n  @ApiOperation({\n    summary: 'Delete organization member',\n    operationId: 'deleteOrganizationMember',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'User removed from organization successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'userId',\n    description: 'User ID',\n    type: 'string',\n  })\n  @RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.ORGANIZATION_USER,\n    targetIdFromRequest: (req) => req.params.userId,\n  })\n  async delete(@Param('organizationId') organizationId: string, @Param('userId') userId: string): Promise<void> {\n    return this.organizationUserService.delete(organizationId, userId)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/controllers/organization.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Body,\n  Controller,\n  Delete,\n  ForbiddenException,\n  Get,\n  HttpCode,\n  NotFoundException,\n  Param,\n  Patch,\n  Post,\n  Put,\n  UseGuards,\n} from '@nestjs/common'\nimport { AuthGuard } from '@nestjs/passport'\nimport { ApiOAuth2, ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody, ApiBearerAuth } from '@nestjs/swagger'\nimport { RequiredOrganizationMemberRole } from '../decorators/required-organization-member-role.decorator'\nimport { CreateOrganizationDto } from '../dto/create-organization.dto'\nimport { OrganizationDto } from '../dto/organization.dto'\nimport { OrganizationInvitationDto } from '../dto/organization-invitation.dto'\nimport { OrganizationUsageOverviewDto } from '../dto/organization-usage-overview.dto'\nimport { UpdateOrganizationQuotaDto } from '../dto/update-organization-quota.dto'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationActionGuard } from '../guards/organization-action.guard'\nimport { OrganizationService } from '../services/organization.service'\nimport { OrganizationUserService } from '../services/organization-user.service'\nimport { OrganizationInvitationService } from '../services/organization-invitation.service'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { AuthContext as IAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SystemActionGuard } from '../../auth/system-action.guard'\nimport { RequiredApiRole, RequiredSystemRole } from '../../common/decorators/required-role.decorator'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { OrganizationSuspensionDto } from '../dto/organization-suspension.dto'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { UserService } from '../../user/user.service'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { EmailUtils } from '../../common/utils/email.util'\nimport { OrganizationUsageService } from '../services/organization-usage.service'\nimport { OrganizationSandboxDefaultLimitedNetworkEgressDto } from '../dto/organization-sandbox-default-limited-network-egress.dto'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\nimport { UpdateOrganizationRegionQuotaDto } from '../dto/update-organization-region-quota.dto'\nimport { UpdateOrganizationDefaultRegionDto } from '../dto/update-organization-default-region.dto'\nimport { RegionQuotaDto } from '../dto/region-quota.dto'\nimport { RequireFlagsEnabled } from '@openfeature/nestjs-sdk'\nimport { OrGuard } from '../../auth/or.guard'\nimport { OtelCollectorGuard } from '../../auth/otel-collector.guard'\nimport { OtelConfigDto } from '../dto/otel-config.dto'\n\n@ApiTags('organizations')\n@Controller('organizations')\n// TODO: Rethink this. Can we allow access to these methods with API keys as well?\n// @UseGuards(AuthGuard('jwt'))\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class OrganizationController {\n  constructor(\n    private readonly organizationService: OrganizationService,\n    private readonly organizationUserService: OrganizationUserService,\n    private readonly organizationInvitationService: OrganizationInvitationService,\n    private readonly organizationUsageService: OrganizationUsageService,\n    private readonly userService: UserService,\n    private readonly configService: TypedConfigService,\n  ) {}\n\n  @Get('/invitations')\n  @ApiOperation({\n    summary: 'List organization invitations for authenticated user',\n    operationId: 'listOrganizationInvitationsForAuthenticatedUser',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of organization invitations',\n    type: [OrganizationInvitationDto],\n  })\n  @UseGuards(AuthGuard('jwt'))\n  async findInvitationsByUser(@AuthContext() authContext: IAuthContext): Promise<OrganizationInvitationDto[]> {\n    const invitations = await this.organizationInvitationService.findByUser(authContext.userId)\n    return invitations.map(OrganizationInvitationDto.fromOrganizationInvitation)\n  }\n\n  @Get('/invitations/count')\n  @ApiOperation({\n    summary: 'Get count of organization invitations for authenticated user',\n    operationId: 'getOrganizationInvitationsCountForAuthenticatedUser',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Count of organization invitations',\n    type: Number,\n  })\n  @UseGuards(AuthGuard('jwt'))\n  async getInvitationsCountByUser(@AuthContext() authContext: IAuthContext): Promise<number> {\n    return this.organizationInvitationService.getCountByUser(authContext.userId)\n  }\n\n  @Post('/invitations/:invitationId/accept')\n  @ApiOperation({\n    summary: 'Accept organization invitation',\n    operationId: 'acceptOrganizationInvitation',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Organization invitation accepted successfully',\n    type: OrganizationInvitationDto,\n  })\n  @ApiParam({\n    name: 'invitationId',\n    description: 'Invitation ID',\n    type: 'string',\n  })\n  @UseGuards(AuthGuard('jwt'))\n  @Audit({\n    action: AuditAction.ACCEPT,\n    targetType: AuditTarget.ORGANIZATION_INVITATION,\n    targetIdFromRequest: (req) => req.params.invitationId,\n  })\n  async acceptInvitation(\n    @AuthContext() authContext: IAuthContext,\n    @Param('invitationId') invitationId: string,\n  ): Promise<OrganizationInvitationDto> {\n    try {\n      const invitation = await this.organizationInvitationService.findOneOrFail(invitationId)\n      if (!EmailUtils.areEqual(invitation.email, authContext.email)) {\n        throw new ForbiddenException('User email does not match invitation email')\n      }\n    } catch (error) {\n      throw new NotFoundException(`Organization invitation with ID ${invitationId} not found`)\n    }\n\n    const acceptedInvitation = await this.organizationInvitationService.accept(invitationId, authContext.userId)\n    return OrganizationInvitationDto.fromOrganizationInvitation(acceptedInvitation)\n  }\n\n  @Post('/invitations/:invitationId/decline')\n  @ApiOperation({\n    summary: 'Decline organization invitation',\n    operationId: 'declineOrganizationInvitation',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Organization invitation declined successfully',\n  })\n  @ApiParam({\n    name: 'invitationId',\n    description: 'Invitation ID',\n    type: 'string',\n  })\n  @UseGuards(AuthGuard('jwt'))\n  @Audit({\n    action: AuditAction.DECLINE,\n    targetType: AuditTarget.ORGANIZATION_INVITATION,\n    targetIdFromRequest: (req) => req.params.invitationId,\n  })\n  async declineInvitation(\n    @AuthContext() authContext: IAuthContext,\n    @Param('invitationId') invitationId: string,\n  ): Promise<void> {\n    try {\n      const invitation = await this.organizationInvitationService.findOneOrFail(invitationId)\n      if (!EmailUtils.areEqual(invitation.email, authContext.email)) {\n        throw new ForbiddenException('User email does not match invitation email')\n      }\n    } catch (error) {\n      throw new NotFoundException(`Organization invitation with ID ${invitationId} not found`)\n    }\n\n    return this.organizationInvitationService.decline(invitationId)\n  }\n\n  @Post()\n  @ApiOperation({\n    summary: 'Create organization',\n    operationId: 'createOrganization',\n  })\n  @ApiResponse({\n    status: 201,\n    description: 'Organization created successfully',\n    type: OrganizationDto,\n  })\n  @UseGuards(AuthGuard('jwt'))\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromResult: (result: OrganizationDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateOrganizationDto>) => ({\n        name: req.body?.name,\n        defaultRegionId: req.body?.defaultRegionId,\n      }),\n    },\n  })\n  async create(\n    @AuthContext() authContext: IAuthContext,\n    @Body() createOrganizationDto: CreateOrganizationDto,\n  ): Promise<OrganizationDto> {\n    const user = await this.userService.findOne(authContext.userId)\n    if (!user.emailVerified && !this.configService.get('skipUserEmailVerification')) {\n      throw new ForbiddenException('Please verify your email address')\n    }\n\n    const organization = await this.organizationService.create(createOrganizationDto, authContext.userId, false, true)\n    return OrganizationDto.fromOrganization(organization)\n  }\n\n  @Patch('/:organizationId/default-region')\n  @HttpCode(204)\n  @ApiOperation({\n    summary: 'Set default region for organization',\n    operationId: 'setOrganizationDefaultRegion',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Default region set successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiBody({\n    type: UpdateOrganizationDefaultRegionDto,\n    required: true,\n  })\n  @UseGuards(AuthGuard('jwt'), AuthenticatedRateLimitGuard, OrganizationActionGuard)\n  @RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n  @Audit({\n    action: AuditAction.UPDATE,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n    requestMetadata: {\n      body: (req: TypedRequest<UpdateOrganizationDefaultRegionDto>) => ({\n        defaultRegionId: req.body?.defaultRegionId,\n      }),\n    },\n  })\n  async setDefaultRegion(\n    @Param('organizationId') organizationId: string,\n    @Body() updateDto: UpdateOrganizationDefaultRegionDto,\n  ): Promise<void> {\n    await this.organizationService.setDefaultRegion(organizationId, updateDto.defaultRegionId)\n  }\n\n  @Get()\n  @ApiOperation({\n    summary: 'List organizations',\n    operationId: 'listOrganizations',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of organizations',\n    type: [OrganizationDto],\n  })\n  @UseGuards(AuthGuard('jwt'))\n  async findAll(@AuthContext() authContext: IAuthContext): Promise<OrganizationDto[]> {\n    const organizations = await this.organizationService.findByUser(authContext.userId)\n    return organizations.map(OrganizationDto.fromOrganization)\n  }\n\n  @Get('/:organizationId')\n  @ApiOperation({\n    summary: 'Get organization by ID',\n    operationId: 'getOrganization',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Organization details',\n    type: OrganizationDto,\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @UseGuards(AuthGuard('jwt'), OrganizationActionGuard)\n  async findOne(@Param('organizationId') organizationId: string): Promise<OrganizationDto> {\n    const organization = await this.organizationService.findOne(organizationId)\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n\n    return OrganizationDto.fromOrganization(organization)\n  }\n\n  @Delete('/:organizationId')\n  @ApiOperation({\n    summary: 'Delete organization',\n    operationId: 'deleteOrganization',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Organization deleted successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @UseGuards(AuthGuard('jwt'), OrganizationActionGuard)\n  @RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n  })\n  async delete(@Param('organizationId') organizationId: string): Promise<void> {\n    return this.organizationService.delete(organizationId)\n  }\n\n  @Get('/:organizationId/usage')\n  @ApiOperation({\n    summary: 'Get organization current usage overview',\n    operationId: 'getOrganizationUsageOverview',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Current usage overview',\n    type: OrganizationUsageOverviewDto,\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @UseGuards(AuthGuard('jwt'), OrganizationActionGuard)\n  async getUsageOverview(@Param('organizationId') organizationId: string): Promise<OrganizationUsageOverviewDto> {\n    return this.organizationUsageService.getUsageOverview(organizationId)\n  }\n\n  @Patch('/:organizationId/quota')\n  @HttpCode(204)\n  @ApiOperation({\n    summary: 'Update organization quota',\n    operationId: 'updateOrganizationQuota',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Organization quota updated successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @UseGuards(CombinedAuthGuard, AuthenticatedRateLimitGuard, SystemActionGuard)\n  @Audit({\n    action: AuditAction.UPDATE_QUOTA,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n    requestMetadata: {\n      body: (req: TypedRequest<UpdateOrganizationQuotaDto>) => ({\n        maxCpuPerSandbox: req.body?.maxCpuPerSandbox,\n        maxMemoryPerSandbox: req.body?.maxMemoryPerSandbox,\n        maxDiskPerSandbox: req.body?.maxDiskPerSandbox,\n        snapshotQuota: req.body?.snapshotQuota,\n        maxSnapshotSize: req.body?.maxSnapshotSize,\n        volumeQuota: req.body?.volumeQuota,\n      }),\n    },\n  })\n  async updateOrganizationQuota(\n    @Param('organizationId') organizationId: string,\n    @Body() updateDto: UpdateOrganizationQuotaDto,\n  ): Promise<void> {\n    await this.organizationService.updateQuota(organizationId, updateDto)\n  }\n\n  @Patch('/:organizationId/quota/:regionId')\n  @HttpCode(204)\n  @ApiOperation({\n    summary: 'Update organization region quota',\n    operationId: 'updateOrganizationRegionQuota',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Region quota updated successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'regionId',\n    description: 'ID of the region where the updated quota will be applied',\n    type: 'string',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @UseGuards(CombinedAuthGuard, AuthenticatedRateLimitGuard, SystemActionGuard)\n  @Audit({\n    action: AuditAction.UPDATE_REGION_QUOTA,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n    requestMetadata: {\n      params: (req) => ({\n        regionId: req.params.regionId,\n      }),\n      body: (req: TypedRequest<UpdateOrganizationRegionQuotaDto>) => ({\n        totalCpuQuota: req.body?.totalCpuQuota,\n        totalMemoryQuota: req.body?.totalMemoryQuota,\n        totalDiskQuota: req.body?.totalDiskQuota,\n      }),\n    },\n  })\n  async updateOrganizationRegionQuota(\n    @Param('organizationId') organizationId: string,\n    @Param('regionId') regionId: string,\n    @Body() updateDto: UpdateOrganizationRegionQuotaDto,\n  ): Promise<void> {\n    await this.organizationService.updateRegionQuota(organizationId, regionId, updateDto)\n  }\n\n  @Post('/:organizationId/leave')\n  @ApiOperation({\n    summary: 'Leave organization',\n    operationId: 'leaveOrganization',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Organization left successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @UseGuards(AuthGuard('jwt'), OrganizationActionGuard)\n  @Audit({\n    action: AuditAction.LEAVE_ORGANIZATION,\n  })\n  async leave(\n    @AuthContext() authContext: IAuthContext,\n    @Param('organizationId') organizationId: string,\n  ): Promise<void> {\n    return this.organizationUserService.delete(organizationId, authContext.userId)\n  }\n\n  @Post('/:organizationId/suspend')\n  @ApiOperation({\n    summary: 'Suspend organization',\n    operationId: 'suspendOrganization',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Organization suspended successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiBody({\n    type: OrganizationSuspensionDto,\n    required: false,\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @UseGuards(CombinedAuthGuard, AuthenticatedRateLimitGuard, SystemActionGuard)\n  @Audit({\n    action: AuditAction.SUSPEND,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n    requestMetadata: {\n      body: (req: TypedRequest<OrganizationSuspensionDto>) => ({\n        reason: req.body?.reason,\n        until: req.body?.until,\n      }),\n    },\n  })\n  async suspend(\n    @Param('organizationId') organizationId: string,\n    @Body() organizationSuspensionDto?: OrganizationSuspensionDto,\n  ): Promise<void> {\n    return this.organizationService.suspend(\n      organizationId,\n      organizationSuspensionDto?.reason,\n      organizationSuspensionDto?.until,\n      organizationSuspensionDto?.suspensionCleanupGracePeriodHours,\n    )\n  }\n\n  @Post('/:organizationId/unsuspend')\n  @ApiOperation({\n    summary: 'Unsuspend organization',\n    operationId: 'unsuspendOrganization',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Organization unsuspended successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @UseGuards(CombinedAuthGuard, AuthenticatedRateLimitGuard, SystemActionGuard)\n  @Audit({\n    action: AuditAction.UNSUSPEND,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n  })\n  async unsuspend(@Param('organizationId') organizationId: string): Promise<void> {\n    return this.organizationService.unsuspend(organizationId)\n  }\n\n  @Get('/by-sandbox-id/:sandboxId')\n  @ApiOperation({\n    summary: 'Get organization by sandbox ID',\n    operationId: 'getOrganizationBySandboxId',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Organization',\n    type: OrganizationDto,\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'Sandbox ID',\n    type: 'string',\n  })\n  @RequiredApiRole([SystemRole.ADMIN, 'proxy'])\n  @UseGuards(CombinedAuthGuard, AuthenticatedRateLimitGuard, SystemActionGuard)\n  async getBySandboxId(@Param('sandboxId') sandboxId: string): Promise<OrganizationDto> {\n    const organization = await this.organizationService.findBySandboxId(sandboxId)\n    if (!organization) {\n      throw new NotFoundException(`Organization with sandbox ID ${sandboxId} not found`)\n    }\n\n    return OrganizationDto.fromOrganization(organization)\n  }\n\n  @Get('/region-quota/by-sandbox-id/:sandboxId')\n  @ApiOperation({\n    summary: 'Get region quota by sandbox ID',\n    operationId: 'getRegionQuotaBySandboxId',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Region quota',\n    type: RegionQuotaDto,\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'Sandbox ID',\n    type: 'string',\n  })\n  @RequiredApiRole([SystemRole.ADMIN, 'proxy'])\n  @UseGuards(CombinedAuthGuard, AuthenticatedRateLimitGuard, SystemActionGuard)\n  async getRegionQuotaBySandboxId(@Param('sandboxId') sandboxId: string): Promise<RegionQuotaDto> {\n    const regionQuota = await this.organizationService.getRegionQuotaBySandboxId(sandboxId)\n    if (!regionQuota) {\n      throw new NotFoundException(`Region quota for sandbox with ID ${sandboxId} not found`)\n    }\n\n    return regionQuota\n  }\n\n  @Get('/otel-config/by-sandbox-auth-token/:authToken')\n  @ApiOperation({\n    summary: 'Get organization OTEL config by sandbox auth token',\n    operationId: 'getOrganizationOtelConfigBySandboxAuthToken',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'OTEL Config',\n    type: OtelConfigDto,\n  })\n  @ApiParam({\n    name: 'authToken',\n    description: 'Sandbox Auth Token',\n    type: 'string',\n  })\n  @RequiredApiRole([SystemRole.ADMIN, 'otel-collector'])\n  @UseGuards(CombinedAuthGuard, OrGuard([SystemActionGuard, OtelCollectorGuard]))\n  async getOtelConfigBySandboxAuthToken(@Param('authToken') authToken: string): Promise<OtelConfigDto> {\n    const otelConfigDto = await this.organizationService.getOtelConfigBySandboxAuthToken(authToken)\n    if (!otelConfigDto) {\n      throw new NotFoundException(`Organization OTEL config with sandbox auth token ${authToken} not found`)\n    }\n\n    return otelConfigDto\n  }\n\n  @Post('/:organizationId/sandbox-default-limited-network-egress')\n  @ApiOperation({\n    summary: 'Update sandbox default limited network egress',\n    operationId: 'updateSandboxDefaultLimitedNetworkEgress',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Sandbox default limited network egress updated successfully',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @UseGuards(CombinedAuthGuard, SystemActionGuard)\n  @Audit({\n    action: AuditAction.UPDATE_SANDBOX_DEFAULT_LIMITED_NETWORK_EGRESS,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n    requestMetadata: {\n      body: (req: TypedRequest<OrganizationSandboxDefaultLimitedNetworkEgressDto>) => ({\n        sandboxDefaultLimitedNetworkEgress: req.body?.sandboxDefaultLimitedNetworkEgress,\n      }),\n    },\n  })\n  async updateSandboxDefaultLimitedNetworkEgress(\n    @Param('organizationId') organizationId: string,\n    @Body() body: OrganizationSandboxDefaultLimitedNetworkEgressDto,\n  ): Promise<void> {\n    return this.organizationService.updateSandboxDefaultLimitedNetworkEgress(\n      organizationId,\n      body.sandboxDefaultLimitedNetworkEgress,\n    )\n  }\n\n  @Put('/:organizationId/experimental-config')\n  @ApiOperation({\n    summary: 'Update experimental configuration',\n    operationId: 'updateExperimentalConfig',\n  })\n  @ApiParam({\n    name: 'organizationId',\n    description: 'Organization ID',\n    type: 'string',\n  })\n  @ApiBody({\n    description: 'Experimental configuration as a JSON object. Set to null to clear the configuration.',\n    required: false,\n    schema: {\n      additionalProperties: true,\n      example: {\n        otel: {\n          endpoint: 'http://otel-collector:4317',\n          headers: {\n            'api-key': 'XXX',\n          },\n        },\n      },\n    },\n  })\n  @RequiredOrganizationMemberRole(OrganizationMemberRole.OWNER)\n  @UseGuards(AuthGuard('jwt'), OrganizationActionGuard)\n  @RequireFlagsEnabled({ flags: [{ flagKey: 'organization_experiments', defaultValue: true }] })\n  async updateExperimentalConfig(\n    @Param('organizationId') organizationId: string,\n    @Body() experimentalConfig: Record<string, any> | null,\n  ): Promise<void> {\n    await this.organizationService.updateExperimentalConfig(organizationId, experimentalConfig)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/decorators/required-organization-member-role.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Reflector } from '@nestjs/core'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\n\nexport const RequiredOrganizationMemberRole = Reflector.createDecorator<OrganizationMemberRole>()\n"
  },
  {
    "path": "apps/api/src/organization/decorators/required-organization-resource-permissions.decorator.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Reflector } from '@nestjs/core'\nimport { OrganizationResourcePermission } from '../enums/organization-resource-permission.enum'\n\nexport const RequiredOrganizationResourcePermissions = Reflector.createDecorator<OrganizationResourcePermission[]>()\n"
  },
  {
    "path": "apps/api/src/organization/dto/create-organization-invitation.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { Type } from 'class-transformer'\nimport { IsArray, IsDate, IsEmail, IsEnum, IsOptional, IsString } from 'class-validator'\nimport { GlobalOrganizationRolesIds } from '../constants/global-organization-roles.constant'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\n\n@ApiSchema({ name: 'CreateOrganizationInvitation' })\nexport class CreateOrganizationInvitationDto {\n  @ApiProperty({\n    description: 'Email address of the invitee',\n    example: 'mail@example.com',\n    required: true,\n  })\n  @IsString()\n  @IsEmail()\n  email: string\n\n  @ApiProperty({\n    description: 'Organization member role for the invitee',\n    enum: OrganizationMemberRole,\n    default: OrganizationMemberRole.MEMBER,\n  })\n  @IsEnum(OrganizationMemberRole)\n  role: OrganizationMemberRole\n\n  @ApiProperty({\n    description: 'Array of assigned role IDs for the invitee',\n    type: [String],\n    default: [GlobalOrganizationRolesIds.DEVELOPER],\n  })\n  @IsArray()\n  @IsString({ each: true })\n  assignedRoleIds: string[]\n\n  @ApiPropertyOptional({\n    description: 'Expiration date of the invitation',\n    example: '2021-12-31T23:59:59Z',\n  })\n  @IsOptional()\n  @Type(() => Date)\n  @IsDate()\n  expiresAt?: Date\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/create-organization-quota.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsNumber, IsOptional } from 'class-validator'\n\n@ApiSchema({ name: 'CreateOrganizationQuota' })\nexport class CreateOrganizationQuotaDto {\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  totalCpuQuota?: number\n\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  totalMemoryQuota?: number\n\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  totalDiskQuota?: number\n\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  maxCpuPerSandbox?: number\n\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  maxMemoryPerSandbox?: number\n\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  maxDiskPerSandbox?: number\n\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  snapshotQuota?: number\n\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  maxSnapshotSize?: number\n\n  @ApiPropertyOptional()\n  @IsNumber()\n  @IsOptional()\n  volumeQuota?: number\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/create-organization-role.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { ArrayNotEmpty, IsArray, IsEnum, IsString } from 'class-validator'\nimport { OrganizationResourcePermission } from '../enums/organization-resource-permission.enum'\n\n@ApiSchema({ name: 'CreateOrganizationRole' })\nexport class CreateOrganizationRoleDto {\n  @ApiProperty({\n    description: 'The name of the role',\n    example: 'Maintainer',\n    required: true,\n  })\n  @IsString()\n  name: string\n\n  @ApiProperty({\n    description: 'The description of the role',\n    example: 'Can manage all resources',\n  })\n  @IsString()\n  description: string\n\n  @ApiProperty({\n    description: 'The list of permissions assigned to the role',\n    enum: OrganizationResourcePermission,\n    isArray: true,\n    required: true,\n  })\n  @IsArray()\n  @ArrayNotEmpty()\n  @IsEnum(OrganizationResourcePermission, { each: true })\n  permissions: OrganizationResourcePermission[]\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/create-organization.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsNotEmpty, IsString } from 'class-validator'\n\n@ApiSchema({ name: 'CreateOrganization' })\nexport class CreateOrganizationDto {\n  @ApiProperty({\n    description: 'The name of organization',\n    example: 'My Organization',\n    required: true,\n  })\n  @IsString()\n  @IsNotEmpty()\n  name: string\n\n  @ApiProperty({\n    description: 'The ID of the default region for the organization',\n    example: 'us',\n    required: true,\n  })\n  @IsString()\n  @IsNotEmpty()\n  defaultRegionId: string\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/create-organization.internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface CreateOrganizationInternalDto {\n  name: string\n  defaultRegionId?: string\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/organization-invitation.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { OrganizationRoleDto } from './organization-role.dto'\nimport { OrganizationInvitationStatus } from '../enums/organization-invitation-status.enum'\nimport { OrganizationInvitation } from '../entities/organization-invitation.entity'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\n\n@ApiSchema({ name: 'OrganizationInvitation' })\nexport class OrganizationInvitationDto {\n  @ApiProperty({\n    description: 'Invitation ID',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Email address of the invitee',\n  })\n  email: string\n\n  @ApiProperty({\n    description: 'Email address of the inviter',\n  })\n  invitedBy: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'Organization name',\n  })\n  organizationName: string\n\n  @ApiProperty({\n    description: 'Expiration date of the invitation',\n  })\n  expiresAt: Date\n\n  @ApiProperty({\n    description: 'Invitation status',\n    enum: OrganizationInvitationStatus,\n  })\n  status: OrganizationInvitationStatus\n\n  @ApiProperty({\n    description: 'Member role',\n    enum: OrganizationMemberRole,\n  })\n  role: OrganizationMemberRole\n\n  @ApiProperty({\n    description: 'Assigned roles',\n    type: [OrganizationRoleDto],\n  })\n  assignedRoles: OrganizationRoleDto[]\n\n  @ApiProperty({\n    description: 'Creation timestamp',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'Last update timestamp',\n  })\n  updatedAt: Date\n\n  static fromOrganizationInvitation(invitation: OrganizationInvitation): OrganizationInvitationDto {\n    const dto: OrganizationInvitationDto = {\n      id: invitation.id,\n      email: invitation.email,\n      invitedBy: invitation.invitedBy,\n      organizationId: invitation.organizationId,\n      organizationName: invitation.organization.name,\n      expiresAt: invitation.expiresAt,\n      status: invitation.status,\n      role: invitation.role,\n      assignedRoles: invitation.assignedRoles.map(OrganizationRoleDto.fromOrganizationRole),\n      createdAt: invitation.createdAt,\n      updatedAt: invitation.updatedAt,\n    }\n\n    return dto\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/organization-role.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { OrganizationRole } from '../entities/organization-role.entity'\nimport { OrganizationResourcePermission } from '../enums/organization-resource-permission.enum'\n\n@ApiSchema({ name: 'OrganizationRole' })\nexport class OrganizationRoleDto {\n  @ApiProperty({\n    description: 'Role ID',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Role name',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Role description',\n  })\n  description: string\n\n  @ApiProperty({\n    description: 'Roles assigned to the user',\n    enum: OrganizationResourcePermission,\n    isArray: true,\n  })\n  permissions: OrganizationResourcePermission[]\n\n  @ApiProperty({\n    description: 'Global role flag',\n  })\n  isGlobal: boolean\n\n  @ApiProperty({\n    description: 'Creation timestamp',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'Last update timestamp',\n  })\n  updatedAt: Date\n\n  static fromOrganizationRole(role: OrganizationRole): OrganizationRoleDto {\n    const dto: OrganizationRoleDto = {\n      id: role.id,\n      name: role.name,\n      description: role.description,\n      permissions: role.permissions,\n      isGlobal: role.isGlobal,\n      createdAt: role.createdAt,\n      updatedAt: role.updatedAt,\n    }\n\n    return dto\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/organization-sandbox-default-limited-network-egress.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'OrganizationSandboxDefaultLimitedNetworkEgress' })\nexport class OrganizationSandboxDefaultLimitedNetworkEgressDto {\n  @ApiProperty({\n    description: 'Sandbox default limited network egress',\n  })\n  sandboxDefaultLimitedNetworkEgress: boolean\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/organization-suspension.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsNumber, IsOptional, Min } from 'class-validator'\n\n@ApiSchema({ name: 'OrganizationSuspension' })\nexport class OrganizationSuspensionDto {\n  @ApiProperty({\n    description: 'Suspension reason',\n  })\n  reason: string\n\n  @ApiProperty({\n    description: 'Suspension until',\n  })\n  @IsOptional()\n  until?: Date\n\n  @ApiPropertyOptional({\n    description: 'Suspension cleanup grace period hours',\n    type: 'number',\n    minimum: 0,\n  })\n  @IsOptional()\n  @IsNumber()\n  @Min(0)\n  suspensionCleanupGracePeriodHours?: number\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/organization-usage-overview.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'RegionUsageOverview' })\nexport class RegionUsageOverviewDto {\n  @ApiProperty()\n  regionId: string\n\n  @ApiProperty()\n  totalCpuQuota: number\n  @ApiProperty()\n  currentCpuUsage: number\n\n  @ApiProperty()\n  totalMemoryQuota: number\n  @ApiProperty()\n  currentMemoryUsage: number\n\n  @ApiProperty()\n  totalDiskQuota: number\n  @ApiProperty()\n  currentDiskUsage: number\n}\n\n@ApiSchema({ name: 'OrganizationUsageOverview' })\nexport class OrganizationUsageOverviewDto {\n  @ApiProperty({\n    type: [RegionUsageOverviewDto],\n  })\n  regionUsage: RegionUsageOverviewDto[]\n\n  // Snapshot usage\n  @ApiProperty()\n  totalSnapshotQuota: number\n  @ApiProperty()\n  currentSnapshotUsage: number\n\n  // Volume usage\n  @ApiProperty()\n  totalVolumeQuota: number\n  @ApiProperty()\n  currentVolumeUsage: number\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/organization-user.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationRoleDto } from './organization-role.dto'\nimport { OrganizationUser } from '../entities/organization-user.entity'\nimport { User } from '../../user/user.entity'\n\n@ApiSchema({ name: 'OrganizationUser' })\nexport class OrganizationUserDto {\n  @ApiProperty({\n    description: 'User ID',\n  })\n  userId: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'User name',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'User email',\n  })\n  email: string\n\n  @ApiProperty({\n    description: 'Member role',\n    enum: OrganizationMemberRole,\n  })\n  role: OrganizationMemberRole\n\n  @ApiProperty({\n    description: 'Roles assigned to the user',\n    type: [OrganizationRoleDto],\n  })\n  assignedRoles: OrganizationRoleDto[]\n\n  @ApiProperty({\n    description: 'Creation timestamp',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'Last update timestamp',\n  })\n  updatedAt: Date\n\n  static fromEntities(organizationUser: OrganizationUser, user: User | null | undefined): OrganizationUserDto {\n    const dto: OrganizationUserDto = {\n      ...organizationUser,\n      assignedRoles: organizationUser.assignedRoles.map(OrganizationRoleDto.fromOrganizationRole),\n      name: user ? user.name : '',\n      email: user ? user.email : '',\n    }\n\n    return dto\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/organization.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { Organization } from '../entities/organization.entity'\n\n@ApiSchema({ name: 'Organization' })\nexport class OrganizationDto {\n  @ApiProperty({\n    description: 'Organization ID',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Organization name',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'User ID of the organization creator',\n  })\n  createdBy: string\n\n  @ApiProperty({\n    description: 'Personal organization flag',\n  })\n  personal: boolean\n\n  @ApiProperty({\n    description: 'Creation timestamp',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'Last update timestamp',\n  })\n  updatedAt: Date\n\n  @ApiProperty({\n    description: 'Suspended flag',\n  })\n  suspended: boolean\n\n  @ApiProperty({\n    description: 'Suspended at',\n  })\n  suspendedAt?: Date\n\n  @ApiProperty({\n    description: 'Suspended reason',\n  })\n  suspensionReason?: string\n\n  @ApiProperty({\n    description: 'Suspended until',\n  })\n  suspendedUntil?: Date\n\n  @ApiProperty({\n    description: 'Suspension cleanup grace period hours',\n  })\n  suspensionCleanupGracePeriodHours?: number\n\n  @ApiProperty({\n    description: 'Max CPU per sandbox',\n  })\n  maxCpuPerSandbox: number\n\n  @ApiProperty({\n    description: 'Max memory per sandbox',\n  })\n  maxMemoryPerSandbox: number\n\n  @ApiProperty({\n    description: 'Max disk per sandbox',\n  })\n  maxDiskPerSandbox: number\n\n  @ApiProperty({\n    description: 'Time in minutes before an unused snapshot is deactivated',\n    default: 20160,\n  })\n  snapshotDeactivationTimeoutMinutes: number\n\n  @ApiProperty({\n    description: 'Sandbox default network block all',\n  })\n  sandboxLimitedNetworkEgress: boolean\n\n  @ApiPropertyOptional({\n    description: 'Default region ID',\n    required: false,\n  })\n  defaultRegionId?: string\n\n  @ApiProperty({\n    description: 'Authenticated rate limit per minute',\n    nullable: true,\n  })\n  authenticatedRateLimit: number | null\n\n  @ApiProperty({\n    description: 'Sandbox create rate limit per minute',\n    nullable: true,\n  })\n  sandboxCreateRateLimit: number | null\n\n  @ApiProperty({\n    description: 'Sandbox lifecycle rate limit per minute',\n    nullable: true,\n  })\n  sandboxLifecycleRateLimit: number | null\n\n  @ApiProperty({\n    description: 'Experimental configuration',\n  })\n  experimentalConfig: Record<string, any> | null\n\n  @ApiProperty({\n    description: 'Authenticated rate limit TTL in seconds',\n    nullable: true,\n  })\n  authenticatedRateLimitTtlSeconds: number | null\n\n  @ApiProperty({\n    description: 'Sandbox create rate limit TTL in seconds',\n    nullable: true,\n  })\n  sandboxCreateRateLimitTtlSeconds: number | null\n\n  @ApiProperty({\n    description: 'Sandbox lifecycle rate limit TTL in seconds',\n    nullable: true,\n  })\n  sandboxLifecycleRateLimitTtlSeconds: number | null\n\n  static fromOrganization(organization: Organization): OrganizationDto {\n    const experimentalConfig = organization._experimentalConfig\n    if (experimentalConfig && experimentalConfig.otel && experimentalConfig.otel.headers) {\n      experimentalConfig.otel.headers = Object.entries(experimentalConfig.otel.headers).reduce(\n        (acc, [key]) => {\n          acc[key] = '******'\n          return acc\n        },\n        {} as Record<string, string>,\n      )\n    }\n\n    const dto: OrganizationDto = {\n      id: organization.id,\n      name: organization.name,\n      createdBy: organization.createdBy,\n      personal: organization.personal,\n      createdAt: organization.createdAt,\n      updatedAt: organization.updatedAt,\n      suspended: organization.suspended,\n      suspensionReason: organization.suspensionReason,\n      suspendedAt: organization.suspendedAt,\n      suspendedUntil: organization.suspendedUntil,\n      suspensionCleanupGracePeriodHours: organization.suspensionCleanupGracePeriodHours,\n      maxCpuPerSandbox: organization.maxCpuPerSandbox,\n      maxMemoryPerSandbox: organization.maxMemoryPerSandbox,\n      maxDiskPerSandbox: organization.maxDiskPerSandbox,\n      snapshotDeactivationTimeoutMinutes: organization.snapshotDeactivationTimeoutMinutes,\n      sandboxLimitedNetworkEgress: organization.sandboxLimitedNetworkEgress,\n      defaultRegionId: organization.defaultRegionId,\n      authenticatedRateLimit: organization.authenticatedRateLimit,\n      sandboxCreateRateLimit: organization.sandboxCreateRateLimit,\n      sandboxLifecycleRateLimit: organization.sandboxLifecycleRateLimit,\n      experimentalConfig,\n      authenticatedRateLimitTtlSeconds: organization.authenticatedRateLimitTtlSeconds,\n      sandboxCreateRateLimitTtlSeconds: organization.sandboxCreateRateLimitTtlSeconds,\n      sandboxLifecycleRateLimitTtlSeconds: organization.sandboxLifecycleRateLimitTtlSeconds,\n    }\n\n    return dto\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/otel-config.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'OtelConfig' })\nexport class OtelConfigDto {\n  @ApiProperty({\n    description: 'Endpoint',\n  })\n  endpoint: string\n\n  @ApiProperty({\n    description: 'Headers',\n    example: {\n      'x-api-key': 'my-api-key',\n    },\n    nullable: true,\n    required: false,\n    additionalProperties: { type: 'string' },\n  })\n  headers?: Record<string, string>\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/region-quota.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { RegionQuota } from '../entities/region-quota.entity'\n\n@ApiSchema({ name: 'RegionQuota' })\nexport class RegionQuotaDto {\n  @ApiProperty()\n  organizationId: string\n\n  @ApiProperty()\n  regionId: string\n\n  @ApiProperty()\n  totalCpuQuota: number\n\n  @ApiProperty()\n  totalMemoryQuota: number\n\n  @ApiProperty()\n  totalDiskQuota: number\n\n  constructor(regionQuota: RegionQuota) {\n    this.organizationId = regionQuota.organizationId\n    this.regionId = regionQuota.regionId\n    this.totalCpuQuota = regionQuota.totalCpuQuota\n    this.totalMemoryQuota = regionQuota.totalMemoryQuota\n    this.totalDiskQuota = regionQuota.totalDiskQuota\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/sandbox-usage-overview-internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type SandboxUsageOverviewInternalDto = {\n  currentCpuUsage: number\n  currentMemoryUsage: number\n  currentDiskUsage: number\n}\n\nexport type PendingSandboxUsageOverviewInternalDto = {\n  pendingCpuUsage: number | null\n  pendingMemoryUsage: number | null\n  pendingDiskUsage: number | null\n}\n\nexport type SandboxUsageOverviewWithPendingInternalDto = SandboxUsageOverviewInternalDto &\n  PendingSandboxUsageOverviewInternalDto\n"
  },
  {
    "path": "apps/api/src/organization/dto/snapshot-usage-overview-internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type SnapshotUsageOverviewInternalDto = {\n  currentSnapshotUsage: number\n}\n\nexport type PendingSnapshotUsageOverviewInternalDto = {\n  pendingSnapshotUsage: number | null\n}\n\nexport type SnapshotUsageOverviewWithPendingInternalDto = SnapshotUsageOverviewInternalDto &\n  PendingSnapshotUsageOverviewInternalDto\n"
  },
  {
    "path": "apps/api/src/organization/dto/update-organization-default-region.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsNotEmpty, IsString } from 'class-validator'\n\n@ApiSchema({ name: 'UpdateOrganizationDefaultRegion' })\nexport class UpdateOrganizationDefaultRegionDto {\n  @ApiProperty({\n    description: 'The ID of the default region for the organization',\n    example: 'us',\n    required: true,\n  })\n  @IsString()\n  @IsNotEmpty()\n  defaultRegionId: string\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/update-organization-invitation.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { Type } from 'class-transformer'\nimport { IsDate, IsEnum, IsOptional, IsString } from 'class-validator'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\n\n@ApiSchema({ name: 'UpdateOrganizationInvitation' })\nexport class UpdateOrganizationInvitationDto {\n  @ApiProperty({\n    description: 'Organization member role',\n    enum: OrganizationMemberRole,\n  })\n  @IsEnum(OrganizationMemberRole)\n  role: OrganizationMemberRole\n\n  @ApiProperty({\n    description: 'Array of role IDs',\n    type: [String],\n  })\n  @IsString({ each: true })\n  assignedRoleIds: string[]\n\n  @ApiPropertyOptional({\n    description: 'Expiration date of the invitation',\n    example: '2021-12-31T23:59:59Z',\n  })\n  @IsOptional()\n  @Type(() => Date)\n  @IsDate()\n  expiresAt?: Date\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/update-organization-member-access.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsArray, IsEnum, IsString } from 'class-validator'\nimport { GlobalOrganizationRolesIds } from '../constants/global-organization-roles.constant'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\n\n@ApiSchema({ name: 'UpdateOrganizationMemberAccess' })\nexport class UpdateOrganizationMemberAccessDto {\n  @ApiProperty({\n    description: 'Organization member role',\n    enum: OrganizationMemberRole,\n    default: OrganizationMemberRole.MEMBER,\n  })\n  @IsEnum(OrganizationMemberRole)\n  role: OrganizationMemberRole\n\n  @ApiProperty({\n    description: 'Array of assigned role IDs',\n    type: [String],\n    default: [GlobalOrganizationRolesIds.DEVELOPER],\n  })\n  @IsArray()\n  @IsString({ each: true })\n  assignedRoleIds: string[]\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/update-organization-quota.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'UpdateOrganizationQuota' })\nexport class UpdateOrganizationQuotaDto {\n  @ApiProperty({ nullable: true })\n  maxCpuPerSandbox?: number\n\n  @ApiProperty({ nullable: true })\n  maxMemoryPerSandbox?: number\n\n  @ApiProperty({ nullable: true })\n  maxDiskPerSandbox?: number\n\n  @ApiProperty({ nullable: true })\n  snapshotQuota?: number\n\n  @ApiProperty({ nullable: true })\n  maxSnapshotSize?: number\n\n  @ApiProperty({ nullable: true })\n  volumeQuota?: number\n\n  @ApiProperty({ nullable: true })\n  authenticatedRateLimit?: number\n\n  @ApiProperty({ nullable: true })\n  sandboxCreateRateLimit?: number\n\n  @ApiProperty({ nullable: true })\n  sandboxLifecycleRateLimit?: number\n\n  @ApiProperty({ nullable: true })\n  authenticatedRateLimitTtlSeconds?: number\n\n  @ApiProperty({ nullable: true })\n  sandboxCreateRateLimitTtlSeconds?: number\n\n  @ApiProperty({ nullable: true })\n  sandboxLifecycleRateLimitTtlSeconds?: number\n\n  @ApiProperty({ nullable: true, description: 'Time in minutes before an unused snapshot is deactivated' })\n  snapshotDeactivationTimeoutMinutes?: number\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/update-organization-region-quota.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'UpdateOrganizationRegionQuota' })\nexport class UpdateOrganizationRegionQuotaDto {\n  @ApiProperty({ nullable: true })\n  totalCpuQuota?: number\n\n  @ApiProperty({ nullable: true })\n  totalMemoryQuota?: number\n\n  @ApiProperty({ nullable: true })\n  totalDiskQuota?: number\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/update-organization-role.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { ArrayNotEmpty, IsArray, IsEnum, IsString } from 'class-validator'\nimport { OrganizationResourcePermission } from '../enums/organization-resource-permission.enum'\n\n@ApiSchema({ name: 'UpdateOrganizationRole' })\nexport class UpdateOrganizationRoleDto {\n  @ApiProperty({\n    description: 'The name of the role',\n    example: 'Maintainer',\n    required: true,\n  })\n  @IsString()\n  name: string\n\n  @ApiProperty({\n    description: 'The description of the role',\n    example: 'Can manage all resources',\n  })\n  @IsString()\n  description: string\n\n  @ApiProperty({\n    description: 'The list of permissions assigned to the role',\n    enum: OrganizationResourcePermission,\n    isArray: true,\n    required: true,\n  })\n  @IsArray()\n  @ArrayNotEmpty()\n  @IsEnum(OrganizationResourcePermission, { each: true })\n  permissions: OrganizationResourcePermission[]\n}\n"
  },
  {
    "path": "apps/api/src/organization/dto/volume-usage-overview-internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type VolumeUsageOverviewInternalDto = {\n  currentVolumeUsage: number\n}\n\nexport type PendingVolumeUsageOverviewInternalDto = {\n  pendingVolumeUsage: number | null\n}\n\nexport type VolumeUsageOverviewWithPendingInternalDto = VolumeUsageOverviewInternalDto &\n  PendingVolumeUsageOverviewInternalDto\n"
  },
  {
    "path": "apps/api/src/organization/entities/organization-invitation.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Column,\n  CreateDateColumn,\n  Entity,\n  JoinColumn,\n  JoinTable,\n  ManyToMany,\n  ManyToOne,\n  PrimaryGeneratedColumn,\n} from 'typeorm'\nimport { Organization } from './organization.entity'\nimport { OrganizationInvitationStatus } from '../enums/organization-invitation-status.enum'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationRole } from './organization-role.entity'\n\n@Entity()\nexport class OrganizationInvitation {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column()\n  organizationId: string\n\n  @Column()\n  email: string\n\n  @Column({\n    default: '',\n  })\n  invitedBy: string\n\n  @Column({\n    type: 'enum',\n    enum: OrganizationMemberRole,\n    default: OrganizationMemberRole.MEMBER,\n  })\n  role: OrganizationMemberRole\n\n  @ManyToMany(() => OrganizationRole, (role) => role.invitations, {\n    cascade: true,\n    onDelete: 'CASCADE',\n  })\n  @JoinTable({\n    name: 'organization_role_assignment_invitation',\n    joinColumn: {\n      name: 'invitationId',\n      referencedColumnName: 'id',\n    },\n    inverseJoinColumn: {\n      name: 'roleId',\n      referencedColumnName: 'id',\n    },\n  })\n  assignedRoles: OrganizationRole[]\n\n  @Column({\n    type: 'timestamp with time zone',\n  })\n  expiresAt: Date\n\n  @Column({\n    type: 'enum',\n    enum: OrganizationInvitationStatus,\n    default: OrganizationInvitationStatus.PENDING,\n  })\n  status: OrganizationInvitationStatus\n\n  @ManyToOne(() => Organization, { onDelete: 'CASCADE' })\n  @JoinColumn({ name: 'organizationId' })\n  organization: Organization\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/organization/entities/organization-role.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, JoinColumn, ManyToMany, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'\nimport { Organization } from './organization.entity'\nimport { OrganizationUser } from './organization-user.entity'\nimport { OrganizationResourcePermission } from '../enums/organization-resource-permission.enum'\nimport { OrganizationInvitation } from './organization-invitation.entity'\n\n@Entity()\nexport class OrganizationRole {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column()\n  name: string\n\n  @Column()\n  description: string\n\n  @Column({\n    type: 'enum',\n    enum: OrganizationResourcePermission,\n    array: true,\n  })\n  permissions: OrganizationResourcePermission[]\n\n  @Column({ default: false })\n  isGlobal: boolean\n\n  @Column({\n    nullable: true,\n  })\n  organizationId?: string\n\n  @ManyToOne(() => Organization, { onDelete: 'CASCADE' })\n  @JoinColumn({ name: 'organizationId' })\n  organization: Organization\n\n  @ManyToMany(() => OrganizationUser, (user) => user.assignedRoles)\n  users: OrganizationUser[]\n\n  @ManyToMany(() => OrganizationInvitation, (invitation) => invitation.assignedRoles)\n  invitations: OrganizationInvitation[]\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/organization/entities/organization-user.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, PrimaryColumn } from 'typeorm'\nimport { Organization } from './organization.entity'\nimport { OrganizationRole } from './organization-role.entity'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\n\n@Entity()\nexport class OrganizationUser {\n  @PrimaryColumn()\n  organizationId: string\n\n  @PrimaryColumn()\n  userId: string\n\n  @Column({\n    type: 'enum',\n    enum: OrganizationMemberRole,\n    default: OrganizationMemberRole.MEMBER,\n  })\n  role: OrganizationMemberRole\n\n  @ManyToOne(() => Organization, (organization) => organization.users, {\n    onDelete: 'CASCADE',\n  })\n  @JoinColumn({ name: 'organizationId' })\n  organization: Organization\n\n  @ManyToMany(() => OrganizationRole, (role) => role.users, {\n    cascade: true,\n    onDelete: 'CASCADE',\n  })\n  @JoinTable({\n    name: 'organization_role_assignment',\n    joinColumns: [\n      { name: 'organizationId', referencedColumnName: 'organizationId' },\n      { name: 'userId', referencedColumnName: 'userId' },\n    ],\n    inverseJoinColumns: [{ name: 'roleId', referencedColumnName: 'id' }],\n  })\n  assignedRoles: OrganizationRole[]\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/organization/entities/organization.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'\nimport { OrganizationUser } from './organization-user.entity'\nimport { OrganizationRole } from './organization-role.entity'\nimport { OrganizationInvitation } from './organization-invitation.entity'\nimport { RegionQuota } from './region-quota.entity'\n\n@Entity()\nexport class Organization {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column()\n  name: string\n\n  @Column()\n  createdBy: string\n\n  @Column({\n    default: false,\n  })\n  personal: boolean\n\n  @Column({\n    default: true,\n  })\n  telemetryEnabled: boolean\n\n  @Column({ nullable: true })\n  defaultRegionId?: string\n\n  @Column({\n    type: 'int',\n    default: 4,\n    name: 'max_cpu_per_sandbox',\n  })\n  maxCpuPerSandbox: number\n\n  @Column({\n    type: 'int',\n    default: 8,\n    name: 'max_memory_per_sandbox',\n  })\n  maxMemoryPerSandbox: number\n\n  @Column({\n    type: 'int',\n    default: 10,\n    name: 'max_disk_per_sandbox',\n  })\n  maxDiskPerSandbox: number\n\n  @Column({\n    type: 'int',\n    default: 20,\n    name: 'max_snapshot_size',\n  })\n  maxSnapshotSize: number\n\n  @Column({\n    type: 'int',\n    default: 100,\n    name: 'snapshot_quota',\n  })\n  snapshotQuota: number\n\n  @Column({\n    type: 'int',\n    default: 100,\n    name: 'volume_quota',\n  })\n  volumeQuota: number\n\n  @Column({\n    type: 'int',\n    nullable: true,\n    name: 'authenticated_rate_limit',\n  })\n  authenticatedRateLimit: number | null\n\n  @Column({\n    type: 'int',\n    nullable: true,\n    name: 'sandbox_create_rate_limit',\n  })\n  sandboxCreateRateLimit: number | null\n\n  @Column({\n    type: 'int',\n    nullable: true,\n    name: 'sandbox_lifecycle_rate_limit',\n  })\n  sandboxLifecycleRateLimit: number | null\n\n  @Column({\n    type: 'int',\n    nullable: true,\n    name: 'authenticated_rate_limit_ttl_seconds',\n  })\n  authenticatedRateLimitTtlSeconds: number | null\n\n  @Column({\n    type: 'int',\n    nullable: true,\n    name: 'sandbox_create_rate_limit_ttl_seconds',\n  })\n  sandboxCreateRateLimitTtlSeconds: number | null\n\n  @Column({\n    type: 'int',\n    nullable: true,\n    name: 'sandbox_lifecycle_rate_limit_ttl_seconds',\n  })\n  sandboxLifecycleRateLimitTtlSeconds: number | null\n\n  @OneToMany(() => RegionQuota, (quota) => quota.organization, {\n    cascade: true,\n    onDelete: 'CASCADE',\n  })\n  regionQuotas: RegionQuota[]\n\n  @OneToMany(() => OrganizationRole, (organizationRole) => organizationRole.organization, {\n    cascade: true,\n    onDelete: 'CASCADE',\n  })\n  roles: OrganizationRole[]\n\n  @OneToMany(() => OrganizationUser, (user) => user.organization, {\n    cascade: true,\n    onDelete: 'CASCADE',\n  })\n  users: OrganizationUser[]\n\n  @OneToMany(() => OrganizationInvitation, (invitation) => invitation.organization, {\n    cascade: true,\n    onDelete: 'CASCADE',\n  })\n  invitations: OrganizationInvitation[]\n\n  @Column({\n    default: false,\n  })\n  suspended: boolean\n\n  @Column({\n    nullable: true,\n    type: 'timestamp with time zone',\n  })\n  suspendedAt?: Date\n\n  @Column({\n    nullable: true,\n  })\n  suspensionReason?: string\n\n  @Column({\n    type: 'int',\n    default: 24,\n  })\n  suspensionCleanupGracePeriodHours: number\n\n  @Column({\n    nullable: true,\n    type: 'timestamp with time zone',\n  })\n  suspendedUntil?: Date\n\n  @Column({\n    type: 'int',\n    default: 20160,\n    name: 'snapshot_deactivation_timeout_minutes',\n  })\n  snapshotDeactivationTimeoutMinutes: number\n\n  @Column({\n    default: false,\n  })\n  sandboxLimitedNetworkEgress: boolean\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  @Column({\n    type: 'jsonb',\n    nullable: true,\n    name: 'experimentalConfig',\n  })\n  // configuration for experimental features\n  _experimentalConfig: Record<string, any> | null\n\n  get sandboxMetadata(): Record<string, string> {\n    return {\n      organizationId: this.id,\n      organizationName: this.name,\n      limitNetworkEgress: String(this.sandboxLimitedNetworkEgress),\n    }\n  }\n\n  constructor(defaultRegionId?: string) {\n    if (defaultRegionId) {\n      this.defaultRegionId = defaultRegionId\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/entities/region-quota.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryColumn, UpdateDateColumn } from 'typeorm'\nimport { Organization } from './organization.entity'\n\n@Entity()\nexport class RegionQuota {\n  @PrimaryColumn()\n  organizationId: string\n\n  @PrimaryColumn()\n  regionId: string\n\n  @ManyToOne(() => Organization, (organization) => organization.regionQuotas, {\n    onDelete: 'CASCADE',\n  })\n  @JoinColumn({ name: 'organizationId' })\n  organization: Organization\n\n  @Column({\n    type: 'int',\n    default: 10,\n    name: 'total_cpu_quota',\n  })\n  totalCpuQuota: number\n\n  @Column({\n    type: 'int',\n    default: 10,\n    name: 'total_memory_quota',\n  })\n  totalMemoryQuota: number\n\n  @Column({\n    type: 'int',\n    default: 30,\n    name: 'total_disk_quota',\n  })\n  totalDiskQuota: number\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  constructor(\n    organizationId: string,\n    regionId: string,\n    totalCpuQuota: number,\n    totalMemoryQuota: number,\n    totalDiskQuota: number,\n  ) {\n    this.organizationId = organizationId\n    this.regionId = regionId\n    this.totalCpuQuota = totalCpuQuota\n    this.totalMemoryQuota = totalMemoryQuota\n    this.totalDiskQuota = totalDiskQuota\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/enums/organization-invitation-status.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum OrganizationInvitationStatus {\n  PENDING = 'pending',\n  ACCEPTED = 'accepted',\n  DECLINED = 'declined',\n  CANCELLED = 'cancelled',\n}\n"
  },
  {
    "path": "apps/api/src/organization/enums/organization-member-role.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum OrganizationMemberRole {\n  OWNER = 'owner',\n  MEMBER = 'member',\n}\n"
  },
  {
    "path": "apps/api/src/organization/enums/organization-resource-permission.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/*\n  IMPORTANT: When adding a new permission, make sure to update apps/dashboard/src/constants/CreateApiKeyPermissionsGroups.ts accordingly\n*/\nexport enum OrganizationResourcePermission {\n  // docker registries\n  WRITE_REGISTRIES = 'write:registries',\n  DELETE_REGISTRIES = 'delete:registries',\n\n  // snapshots\n  WRITE_SNAPSHOTS = 'write:snapshots',\n  DELETE_SNAPSHOTS = 'delete:snapshots',\n\n  // sandboxes\n  WRITE_SANDBOXES = 'write:sandboxes',\n  DELETE_SANDBOXES = 'delete:sandboxes',\n\n  // volumes\n  READ_VOLUMES = 'read:volumes',\n  WRITE_VOLUMES = 'write:volumes',\n  DELETE_VOLUMES = 'delete:volumes',\n\n  // regions\n  WRITE_REGIONS = 'write:regions',\n  DELETE_REGIONS = 'delete:regions',\n\n  // runners\n  READ_RUNNERS = 'read:runners',\n  WRITE_RUNNERS = 'write:runners',\n  DELETE_RUNNERS = 'delete:runners',\n\n  // audit\n  READ_AUDIT_LOGS = 'read:audit_logs',\n}\n"
  },
  {
    "path": "apps/api/src/organization/events/organization-invitation-accepted.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationRole } from '../entities/organization-role.entity'\n\nexport class OrganizationInvitationAcceptedEvent {\n  constructor(\n    public readonly entityManager: EntityManager,\n    public readonly organizationId: string,\n    public readonly userId: string,\n    public readonly role: OrganizationMemberRole,\n    public readonly assignedRoles: OrganizationRole[],\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/organization/events/organization-invitation-created.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class OrganizationInvitationCreatedEvent {\n  constructor(\n    public readonly organizationName: string,\n    public readonly invitedBy: string,\n    public readonly inviteeEmail: string,\n    public readonly invitationId: string,\n    public readonly expiresAt: Date,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/organization/events/organization-resource-permissions-unassigned.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm'\nimport { OrganizationResourcePermission } from '../enums/organization-resource-permission.enum'\n\nexport class OrganizationResourcePermissionsUnassignedEvent {\n  constructor(\n    public readonly entityManager: EntityManager,\n    public readonly organizationId: string,\n    public readonly userId: string,\n    public readonly unassignedPermissions: OrganizationResourcePermission[],\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/organization/events/organization-suspended-sandbox-stopped.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class OrganizationSuspendedSandboxStoppedEvent {\n  constructor(public readonly sandboxId: string) {}\n}\n"
  },
  {
    "path": "apps/api/src/organization/events/organization-suspended-snapshot-deactivated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class OrganizationSuspendedSnapshotDeactivatedEvent {\n  constructor(public readonly snapshotId: string) {}\n}\n"
  },
  {
    "path": "apps/api/src/organization/exceptions/DefaultRegionRequiredException.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { HttpException, HttpStatus } from '@nestjs/common'\n\nexport class DefaultRegionRequiredException extends HttpException {\n  constructor(\n    message = 'This organization does not have a default region. Please open the Daytona Dashboard to set a default region.',\n  ) {\n    super(message, HttpStatus.PRECONDITION_REQUIRED)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/guards/organization-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CanActivate, ExecutionContext, Injectable, Logger } from '@nestjs/common'\nimport { OrganizationService } from '../services/organization.service'\nimport { OrganizationUserService } from '../services/organization-user.service'\nimport { AuthContext, OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\nimport { Organization } from '../entities/organization.entity'\nimport { OrganizationUser } from '../entities/organization-user.entity'\n\n@Injectable()\nexport class OrganizationAccessGuard implements CanActivate {\n  protected readonly logger = new Logger(OrganizationAccessGuard.name)\n  @InjectRedis() private readonly redis: Redis\n\n  constructor(\n    private readonly organizationService: OrganizationService,\n    private readonly organizationUserService: OrganizationUserService,\n  ) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    // TODO: initialize authContext safely\n    const authContext: AuthContext = request.user\n\n    if (!authContext) {\n      this.logger.warn('User object is undefined. Authentication may not be set up correctly.')\n      return false\n    }\n\n    // note: semantic parameter names must be used (avoid :id)\n    const organizationIdParam = request.params.organizationId || request.params.orgId\n\n    if (\n      authContext.role !== 'ssh-gateway' &&\n      authContext.role !== 'runner' &&\n      authContext.role !== 'proxy' &&\n      authContext.role !== 'region-proxy' &&\n      authContext.role !== 'region-ssh-gateway' &&\n      !organizationIdParam &&\n      !authContext.organizationId\n    ) {\n      this.logger.warn('Organization ID missing from the request context.')\n      return false\n    }\n\n    if (\n      organizationIdParam &&\n      authContext.apiKey &&\n      authContext.apiKey.organizationId !== organizationIdParam &&\n      authContext.role !== SystemRole.ADMIN &&\n      authContext.role !== 'ssh-gateway'\n    ) {\n      this.logger.warn(\n        `Organization ID mismatch in the request context. Expected: ${organizationIdParam}, Actual: ${authContext.apiKey.organizationId}`,\n      )\n      return false\n    }\n\n    const organizationId = organizationIdParam || authContext.organizationId\n\n    const organization = await this.getCachedOrganization(organizationId)\n\n    if (!organization) {\n      this.logger.warn(`Organization not found. Organization ID: ${organizationId}`)\n      return false\n    }\n\n    const organizationAuthContext: OrganizationAuthContext = {\n      ...authContext,\n      organizationId,\n      organization,\n    }\n    request.user = organizationAuthContext\n\n    if (authContext.role === SystemRole.ADMIN) {\n      return true\n    }\n\n    const organizationUser = await this.getCachedOrganizationUser(organizationId, authContext.userId)\n\n    if (!organizationUser) {\n      this.logger.warn(\n        `Organization user not found. User ID: ${authContext.userId}, Organization ID: ${organizationId}`,\n      )\n      return false\n    }\n\n    organizationAuthContext.organizationUser = organizationUser\n    request.user = organizationAuthContext\n\n    return true\n  }\n\n  private async getCachedOrganization(organizationId: string): Promise<Organization | null> {\n    try {\n      const cachedOrganization = await this.redis.get(`organization:${organizationId}`)\n      if (cachedOrganization) {\n        return JSON.parse(cachedOrganization)\n      }\n      const organization = await this.organizationService.findOne(organizationId)\n      if (organization) {\n        await this.redis.set(`organization:${organizationId}`, JSON.stringify(organization), 'EX', 10)\n        return organization\n      }\n      return null\n    } catch (error) {\n      this.logger.error('Error getting cached organization:', error)\n      return null\n    }\n  }\n\n  private async getCachedOrganizationUser(organizationId: string, userId: string): Promise<OrganizationUser | null> {\n    try {\n      const cachedOrganizationUser = await this.redis.get(`organization-user:${organizationId}:${userId}`)\n      if (cachedOrganizationUser) {\n        return JSON.parse(cachedOrganizationUser)\n      }\n      const organizationUser = await this.organizationUserService.findOne(organizationId, userId)\n      if (organizationUser) {\n        await this.redis.set(\n          `organization-user:${organizationId}:${userId}`,\n          JSON.stringify(organizationUser),\n          'EX',\n          10,\n        )\n        return organizationUser\n      }\n      return null\n    } catch (ex) {\n      this.logger.error('Error getting cached organization user:', ex)\n      return null\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/guards/organization-action.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext, Logger } from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { OrganizationAccessGuard } from './organization-access.guard'\nimport { RequiredOrganizationMemberRole } from '../decorators/required-organization-member-role.decorator'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationService } from '../services/organization.service'\nimport { OrganizationUserService } from '../services/organization-user.service'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\n\n@Injectable()\nexport class OrganizationActionGuard extends OrganizationAccessGuard {\n  protected readonly logger = new Logger(OrganizationActionGuard.name)\n\n  constructor(\n    organizationService: OrganizationService,\n    organizationUserService: OrganizationUserService,\n    private readonly reflector: Reflector,\n  ) {\n    super(organizationService, organizationUserService)\n  }\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    if (!(await super.canActivate(context))) {\n      return false\n    }\n\n    const request = context.switchToHttp().getRequest()\n    // TODO: initialize authContext safely\n    const authContext: OrganizationAuthContext = request.user\n\n    if (authContext.role === SystemRole.ADMIN) {\n      return true\n    }\n\n    if (!authContext.organizationUser) {\n      return false\n    }\n\n    const requiredRole = this.reflector.get(RequiredOrganizationMemberRole, context.getHandler())\n    if (!requiredRole) {\n      return true\n    }\n\n    if (requiredRole === OrganizationMemberRole.OWNER) {\n      return authContext.organizationUser.role === OrganizationMemberRole.OWNER\n    }\n\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/guards/organization-resource-action.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext, Logger } from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { OrganizationAccessGuard } from './organization-access.guard'\nimport { RequiredOrganizationResourcePermissions } from '../decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationService } from '../services/organization.service'\nimport { OrganizationUserService } from '../services/organization-user.service'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\n\n@Injectable()\nexport class OrganizationResourceActionGuard extends OrganizationAccessGuard {\n  protected readonly logger = new Logger(OrganizationResourceActionGuard.name)\n\n  constructor(\n    organizationService: OrganizationService,\n    organizationUserService: OrganizationUserService,\n    private readonly reflector: Reflector,\n  ) {\n    super(organizationService, organizationUserService)\n  }\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const canActivate = await super.canActivate(context)\n\n    const request = context.switchToHttp().getRequest()\n    // TODO: initialize authContext safely\n    const authContext: OrganizationAuthContext = request.user\n\n    if (authContext.role === SystemRole.ADMIN) {\n      return true\n    }\n\n    if (!canActivate) {\n      return false\n    }\n\n    if (!authContext.organizationUser) {\n      return false\n    }\n\n    if (authContext.organizationUser.role === OrganizationMemberRole.OWNER && !authContext.apiKey) {\n      return true\n    }\n\n    const requiredPermissions =\n      this.reflector.get(RequiredOrganizationResourcePermissions, context.getHandler()) ||\n      this.reflector.get(RequiredOrganizationResourcePermissions, context.getClass())\n\n    if (!requiredPermissions) {\n      return true\n    }\n\n    const assignedPermissions = authContext.apiKey\n      ? new Set(authContext.apiKey.permissions)\n      : new Set(authContext.organizationUser.assignedRoles.flatMap((role) => role.permissions))\n\n    return requiredPermissions.every((permission) => assignedPermissions.has(permission))\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/helpers/organization-usage.helper.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type OrganizationUsageQuotaType = 'cpu' | 'memory' | 'disk' | 'snapshot_count' | 'volume_count'\nexport type OrganizationUsageResourceType = 'sandbox' | 'snapshot' | 'volume'\n\nconst QUOTA_TO_RESOURCE_MAP: Record<OrganizationUsageQuotaType, OrganizationUsageResourceType> = {\n  cpu: 'sandbox',\n  memory: 'sandbox',\n  disk: 'sandbox',\n  snapshot_count: 'snapshot',\n  volume_count: 'volume',\n} as const\n\nexport function getResourceTypeFromQuota(quotaType: OrganizationUsageQuotaType): OrganizationUsageResourceType {\n  return QUOTA_TO_RESOURCE_MAP[quotaType]\n}\n"
  },
  {
    "path": "apps/api/src/organization/organization.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { OrganizationController } from './controllers/organization.controller'\nimport { OrganizationRoleController } from './controllers/organization-role.controller'\nimport { OrganizationUserController } from './controllers/organization-user.controller'\nimport { OrganizationInvitationController } from './controllers/organization-invitation.controller'\nimport { Organization } from './entities/organization.entity'\nimport { OrganizationRole } from './entities/organization-role.entity'\nimport { OrganizationUser } from './entities/organization-user.entity'\nimport { OrganizationInvitation } from './entities/organization-invitation.entity'\nimport { OrganizationService } from './services/organization.service'\nimport { OrganizationRoleService } from './services/organization-role.service'\nimport { OrganizationUserService } from './services/organization-user.service'\nimport { OrganizationInvitationService } from './services/organization-invitation.service'\nimport { UserModule } from '../user/user.module'\nimport { Sandbox } from '../sandbox/entities/sandbox.entity'\nimport { Snapshot } from '../sandbox/entities/snapshot.entity'\nimport { Volume } from '../sandbox/entities/volume.entity'\nimport { RedisLockProvider } from '../sandbox/common/redis-lock.provider'\nimport { SnapshotRunner } from '../sandbox/entities/snapshot-runner.entity'\nimport { OrganizationUsageService } from './services/organization-usage.service'\nimport { DataSource } from 'typeorm'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { SandboxRepository } from '../sandbox/repositories/sandbox.repository'\nimport { SandboxLookupCacheInvalidationService } from '../sandbox/services/sandbox-lookup-cache-invalidation.service'\nimport { RegionQuota } from './entities/region-quota.entity'\nimport { RegionModule } from '../region/region.module'\nimport { OrganizationRegionController } from './controllers/organization-region.controller'\nimport { Region } from '../region/entities/region.entity'\nimport { EncryptionModule } from '../encryption/encryption.module'\n\n@Module({\n  imports: [\n    UserModule,\n    RegionModule,\n    TypeOrmModule.forFeature([\n      Organization,\n      OrganizationRole,\n      OrganizationUser,\n      OrganizationInvitation,\n      Sandbox,\n      Snapshot,\n      Volume,\n      SnapshotRunner,\n      RegionQuota,\n      Region,\n    ]),\n    EncryptionModule,\n  ],\n  controllers: [\n    OrganizationController,\n    OrganizationRoleController,\n    OrganizationUserController,\n    OrganizationInvitationController,\n    OrganizationRegionController,\n  ],\n  providers: [\n    OrganizationService,\n    OrganizationRoleService,\n    OrganizationUserService,\n    OrganizationInvitationService,\n    OrganizationUsageService,\n    RedisLockProvider,\n    SandboxLookupCacheInvalidationService,\n    {\n      provide: SandboxRepository,\n      inject: [DataSource, EventEmitter2, SandboxLookupCacheInvalidationService],\n      useFactory: (\n        dataSource: DataSource,\n        eventEmitter: EventEmitter2,\n        sandboxLookupCacheInvalidationService: SandboxLookupCacheInvalidationService,\n      ) => new SandboxRepository(dataSource, eventEmitter, sandboxLookupCacheInvalidationService),\n    },\n  ],\n  exports: [\n    OrganizationService,\n    OrganizationRoleService,\n    OrganizationUserService,\n    OrganizationInvitationService,\n    OrganizationUsageService,\n  ],\n})\nexport class OrganizationModule {}\n"
  },
  {
    "path": "apps/api/src/organization/services/organization-invitation.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  BadRequestException,\n  ConflictException,\n  ForbiddenException,\n  Injectable,\n  NotFoundException,\n} from '@nestjs/common'\nimport { ConfigService } from '@nestjs/config'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { DataSource, MoreThan, Repository } from 'typeorm'\nimport { OrganizationRoleService } from './organization-role.service'\nimport { OrganizationUserService } from './organization-user.service'\nimport { OrganizationService } from './organization.service'\nimport { OrganizationEvents } from '../constants/organization-events.constant'\nimport { CreateOrganizationInvitationDto } from '../dto/create-organization-invitation.dto'\nimport { UpdateOrganizationInvitationDto } from '../dto/update-organization-invitation.dto'\nimport { OrganizationInvitation } from '../entities/organization-invitation.entity'\nimport { OrganizationInvitationStatus } from '../enums/organization-invitation-status.enum'\nimport { OrganizationInvitationAcceptedEvent } from '../events/organization-invitation-accepted.event'\nimport { OrganizationInvitationCreatedEvent } from '../events/organization-invitation-created.event'\nimport { UserService } from '../../user/user.service'\nimport { EmailUtils } from '../../common/utils/email.util'\n\n@Injectable()\nexport class OrganizationInvitationService {\n  constructor(\n    @InjectRepository(OrganizationInvitation)\n    private readonly organizationInvitationRepository: Repository<OrganizationInvitation>,\n    private readonly organizationService: OrganizationService,\n    private readonly organizationUserService: OrganizationUserService,\n    private readonly organizationRoleService: OrganizationRoleService,\n    private readonly userService: UserService,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly dataSource: DataSource,\n    private readonly configService: ConfigService,\n  ) {}\n\n  async create(\n    organizationId: string,\n    createOrganizationInvitationDto: CreateOrganizationInvitationDto,\n    invitedBy: string,\n  ): Promise<OrganizationInvitation> {\n    const organization = await this.organizationService.findOne(organizationId)\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n    if (organization.personal) {\n      throw new ForbiddenException('Cannot invite users to personal organization')\n    }\n\n    const normalizedEmail = EmailUtils.normalize(createOrganizationInvitationDto.email)\n\n    const existingUser = await this.userService.findOneByEmail(normalizedEmail, true)\n    if (existingUser) {\n      const organizationUser = await this.organizationUserService.findOne(organizationId, existingUser.id)\n      if (organizationUser) {\n        throw new ConflictException(`User with email ${normalizedEmail} is already associated with this organization`)\n      }\n    }\n\n    const existingInvitation = await this.organizationInvitationRepository.findOne({\n      where: {\n        organizationId,\n        email: normalizedEmail,\n        status: OrganizationInvitationStatus.PENDING,\n        expiresAt: MoreThan(new Date()),\n      },\n    })\n    if (existingInvitation) {\n      throw new ConflictException(`User with email \"${normalizedEmail}\" already invited to this organization`)\n    }\n\n    let invitation = new OrganizationInvitation()\n    invitation.organizationId = organizationId\n    invitation.organization = organization\n    invitation.email = normalizedEmail\n    invitation.expiresAt = createOrganizationInvitationDto.expiresAt || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)\n    invitation.role = createOrganizationInvitationDto.role\n    invitation.invitedBy = invitedBy\n\n    const assignedRoles = await this.organizationRoleService.findByIds(createOrganizationInvitationDto.assignedRoleIds)\n    if (assignedRoles.length !== createOrganizationInvitationDto.assignedRoleIds.length) {\n      throw new BadRequestException('One or more role IDs are invalid')\n    }\n    invitation.assignedRoles = assignedRoles\n\n    invitation = await this.organizationInvitationRepository.save(invitation)\n\n    this.eventEmitter.emit(\n      OrganizationEvents.INVITATION_CREATED,\n      new OrganizationInvitationCreatedEvent(\n        invitation.organization.name,\n        invitation.invitedBy,\n        invitation.email,\n        invitation.id,\n        invitation.expiresAt,\n      ),\n    )\n\n    return invitation\n  }\n\n  async update(\n    invitationId: string,\n    updateOrganizationInvitationDto: UpdateOrganizationInvitationDto,\n  ): Promise<OrganizationInvitation> {\n    const invitation = await this.organizationInvitationRepository.findOne({\n      where: { id: invitationId },\n      relations: {\n        organization: true,\n        assignedRoles: true,\n      },\n    })\n\n    if (!invitation) {\n      throw new NotFoundException(`Invitation with ID ${invitationId} not found`)\n    }\n\n    if (invitation.expiresAt && invitation.expiresAt < new Date()) {\n      throw new ForbiddenException(`Invitation with ID ${invitationId} is expired`)\n    }\n\n    if (invitation.status !== OrganizationInvitationStatus.PENDING) {\n      throw new ForbiddenException(`Invitation with ID ${invitationId} is already ${invitation.status}`)\n    }\n\n    if (updateOrganizationInvitationDto.expiresAt) {\n      invitation.expiresAt = updateOrganizationInvitationDto.expiresAt\n    }\n    invitation.role = updateOrganizationInvitationDto.role\n\n    const assignedRoles = await this.organizationRoleService.findByIds(updateOrganizationInvitationDto.assignedRoleIds)\n    if (assignedRoles.length !== updateOrganizationInvitationDto.assignedRoleIds.length) {\n      throw new BadRequestException('One or more role IDs are invalid')\n    }\n    invitation.assignedRoles = assignedRoles\n\n    return this.organizationInvitationRepository.save(invitation)\n  }\n\n  async findPending(organizationId: string): Promise<OrganizationInvitation[]> {\n    return this.organizationInvitationRepository.find({\n      where: {\n        organizationId,\n        status: OrganizationInvitationStatus.PENDING,\n        expiresAt: MoreThan(new Date()),\n      },\n      relations: {\n        organization: true,\n        assignedRoles: true,\n      },\n    })\n  }\n\n  async findByUser(userId: string): Promise<OrganizationInvitation[]> {\n    const user = await this.userService.findOne(userId)\n\n    if (!user) {\n      throw new NotFoundException(`User with ID ${userId} not found`)\n    }\n\n    return this.organizationInvitationRepository.find({\n      where: {\n        email: EmailUtils.normalize(user.email),\n        status: OrganizationInvitationStatus.PENDING,\n        expiresAt: MoreThan(new Date()),\n      },\n      relations: {\n        organization: true,\n        assignedRoles: true,\n      },\n    })\n  }\n\n  async getCountByUser(userId: string): Promise<number> {\n    const user = await this.userService.findOne(userId)\n\n    if (!user) {\n      throw new NotFoundException(`User with ID ${userId} not found`)\n    }\n\n    return this.organizationInvitationRepository.count({\n      where: {\n        email: EmailUtils.normalize(user.email),\n        status: OrganizationInvitationStatus.PENDING,\n        expiresAt: MoreThan(new Date()),\n      },\n    })\n  }\n\n  async findOneOrFail(invitationId: string): Promise<OrganizationInvitation> {\n    return this.organizationInvitationRepository.findOneOrFail({\n      where: { id: invitationId },\n      relations: {\n        organization: true,\n        assignedRoles: true,\n      },\n    })\n  }\n\n  async accept(invitationId: string, userId: string): Promise<OrganizationInvitation> {\n    const invitation = await this.prepareStatusUpdate(invitationId, OrganizationInvitationStatus.ACCEPTED)\n\n    await this.dataSource.transaction(async (em) => {\n      await em.save(invitation)\n      await this.eventEmitter.emitAsync(\n        OrganizationEvents.INVITATION_ACCEPTED,\n        new OrganizationInvitationAcceptedEvent(\n          em,\n          invitation.organizationId,\n          userId,\n          invitation.role,\n          invitation.assignedRoles,\n        ),\n      )\n    })\n    return invitation\n  }\n\n  async decline(invitationId: string): Promise<void> {\n    const invitation = await this.prepareStatusUpdate(invitationId, OrganizationInvitationStatus.DECLINED)\n    await this.organizationInvitationRepository.save(invitation)\n  }\n\n  async cancel(invitationId: string): Promise<void> {\n    const invitation = await this.prepareStatusUpdate(invitationId, OrganizationInvitationStatus.CANCELLED)\n    await this.organizationInvitationRepository.save(invitation)\n  }\n\n  private async prepareStatusUpdate(\n    invitationId: string,\n    newStatus: OrganizationInvitationStatus,\n  ): Promise<OrganizationInvitation> {\n    const invitation = await this.organizationInvitationRepository.findOne({\n      where: { id: invitationId },\n      relations: {\n        organization: true,\n        assignedRoles: true,\n      },\n    })\n\n    if (!invitation) {\n      throw new NotFoundException(`Invitation with ID ${invitationId} not found`)\n    }\n\n    if (invitation.expiresAt && invitation.expiresAt < new Date()) {\n      throw new ForbiddenException(`Invitation with ID ${invitationId} is expired`)\n    }\n\n    if (invitation.status !== OrganizationInvitationStatus.PENDING) {\n      throw new ForbiddenException(`Invitation with ID ${invitationId} is already ${invitation.status}`)\n    }\n\n    invitation.status = newStatus\n    return invitation\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/services/organization-role.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ForbiddenException, Injectable, NotFoundException } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { In, Repository } from 'typeorm'\nimport { CreateOrganizationRoleDto } from '../dto/create-organization-role.dto'\nimport { UpdateOrganizationRoleDto } from '../dto/update-organization-role.dto'\nimport { OrganizationRole } from '../entities/organization-role.entity'\n\n@Injectable()\nexport class OrganizationRoleService {\n  constructor(\n    @InjectRepository(OrganizationRole)\n    private readonly organizationRoleRepository: Repository<OrganizationRole>,\n  ) {}\n\n  async create(\n    organizationId: string,\n    createOrganizationRoleDto: CreateOrganizationRoleDto,\n  ): Promise<OrganizationRole> {\n    const role = new OrganizationRole()\n    role.organizationId = organizationId\n    role.name = createOrganizationRoleDto.name\n    role.description = createOrganizationRoleDto.description\n    role.permissions = createOrganizationRoleDto.permissions\n    return this.organizationRoleRepository.save(role)\n  }\n\n  async findAll(organizationId: string): Promise<OrganizationRole[]> {\n    return this.organizationRoleRepository.find({\n      where: [{ organizationId }, { isGlobal: true }],\n      order: {\n        id: 'ASC',\n      },\n    })\n  }\n\n  async findByIds(roleIds: string[]): Promise<OrganizationRole[]> {\n    if (roleIds.length === 0) {\n      return []\n    }\n\n    return this.organizationRoleRepository.find({\n      where: {\n        id: In(roleIds),\n      },\n    })\n  }\n\n  async update(roleId: string, updateOrganizationRoleDto: UpdateOrganizationRoleDto): Promise<OrganizationRole> {\n    const role = await this.organizationRoleRepository.findOne({\n      where: { id: roleId },\n    })\n\n    if (!role) {\n      throw new NotFoundException(`Organization role with ID ${roleId} not found`)\n    }\n\n    if (role.isGlobal) {\n      throw new ForbiddenException('Global roles cannot be updated')\n    }\n\n    role.name = updateOrganizationRoleDto.name\n    role.description = updateOrganizationRoleDto.description\n    role.permissions = updateOrganizationRoleDto.permissions\n\n    return this.organizationRoleRepository.save(role)\n  }\n\n  async delete(roleId: string): Promise<void> {\n    const role = await this.organizationRoleRepository.findOne({\n      where: { id: roleId },\n    })\n\n    if (!role) {\n      throw new NotFoundException(`Organization role with ID ${roleId} not found`)\n    }\n\n    if (role.isGlobal) {\n      throw new ForbiddenException('Global roles cannot be deleted')\n    }\n\n    await this.organizationRoleRepository.remove(role)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/services/organization-usage.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BadRequestException, Injectable, Logger, NotFoundException } from '@nestjs/common'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { In, Repository } from 'typeorm'\nimport { SANDBOX_STATES_CONSUMING_COMPUTE } from '../constants/sandbox-states-consuming-compute.constant'\nimport { SANDBOX_STATES_CONSUMING_DISK } from '../constants/sandbox-states-consuming-disk.constant'\nimport { SNAPSHOT_STATES_CONSUMING_RESOURCES } from '../constants/snapshot-states-consuming-resources.constant'\nimport { VOLUME_STATES_CONSUMING_RESOURCES } from '../constants/volume-states-consuming-resources.constant'\nimport { OrganizationUsageOverviewDto, RegionUsageOverviewDto } from '../dto/organization-usage-overview.dto'\nimport {\n  PendingSandboxUsageOverviewInternalDto,\n  SandboxUsageOverviewInternalDto,\n  SandboxUsageOverviewWithPendingInternalDto,\n} from '../dto/sandbox-usage-overview-internal.dto'\nimport {\n  PendingSnapshotUsageOverviewInternalDto,\n  SnapshotUsageOverviewInternalDto,\n  SnapshotUsageOverviewWithPendingInternalDto,\n} from '../dto/snapshot-usage-overview-internal.dto'\nimport {\n  PendingVolumeUsageOverviewInternalDto,\n  VolumeUsageOverviewInternalDto,\n  VolumeUsageOverviewWithPendingInternalDto,\n} from '../dto/volume-usage-overview-internal.dto'\nimport { Organization } from '../entities/organization.entity'\nimport { OrganizationUsageQuotaType, OrganizationUsageResourceType } from '../helpers/organization-usage.helper'\nimport { RedisLockProvider } from '../../sandbox/common/redis-lock.provider'\nimport { SandboxEvents } from '../../sandbox/constants/sandbox-events.constants'\nimport { SnapshotEvents } from '../../sandbox/constants/snapshot-events'\nimport { VolumeEvents } from '../../sandbox/constants/volume-events'\nimport { Snapshot } from '../../sandbox/entities/snapshot.entity'\nimport { Volume } from '../../sandbox/entities/volume.entity'\nimport { SandboxCreatedEvent } from '../../sandbox/events/sandbox-create.event'\nimport { SandboxStateUpdatedEvent } from '../../sandbox/events/sandbox-state-updated.event'\nimport { SnapshotCreatedEvent } from '../../sandbox/events/snapshot-created.event'\nimport { SnapshotStateUpdatedEvent } from '../../sandbox/events/snapshot-state-updated.event'\nimport { VolumeCreatedEvent } from '../../sandbox/events/volume-created.event'\nimport { VolumeStateUpdatedEvent } from '../../sandbox/events/volume-state-updated.event'\nimport { SandboxDesiredState } from '../../sandbox/enums/sandbox-desired-state.enum'\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\nimport { OrganizationService } from './organization.service'\nimport { SandboxRepository } from '../../sandbox/repositories/sandbox.repository'\n\n@Injectable()\nexport class OrganizationUsageService {\n  private readonly logger = new Logger(OrganizationUsageService.name)\n\n  /**\n   * Time-to-live for cached quota usage values\n   */\n  private readonly CACHE_TTL_SECONDS = 60\n\n  /**\n   * Cache is considered stale if it was last populated from db more than `CACHE_MAX_AGE_MS` ago\n   */\n  private readonly CACHE_MAX_AGE_MS = 60 * 60 * 1000\n\n  constructor(\n    @InjectRedis() private readonly redis: Redis,\n    @InjectRepository(Organization)\n    private readonly organizationRepository: Repository<Organization>,\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    @InjectRepository(Volume)\n    private readonly volumeRepository: Repository<Volume>,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly organizationService: OrganizationService,\n  ) {}\n\n  /**\n   * Get the current usage overview for all organization quotas.\n   *\n   * @param organizationId\n   * @param organization - Provide the organization entity to avoid fetching it from the database (optional)\n   */\n  async getUsageOverview(organizationId: string, organization?: Organization): Promise<OrganizationUsageOverviewDto> {\n    if (organization && organization.id !== organizationId) {\n      throw new BadRequestException('Organization ID mismatch')\n    }\n\n    if (!organization) {\n      organization = await this.organizationRepository.findOne({ where: { id: organizationId } })\n    }\n\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n\n    const regionQuotas = await this.organizationService.getRegionQuotas(organizationId)\n\n    const regionUsage: RegionUsageOverviewDto[] = await Promise.all(\n      regionQuotas.map(async (rq) => {\n        const sandboxUsage = await this.getSandboxUsageOverview(organizationId, rq.regionId)\n\n        const usage: RegionUsageOverviewDto = {\n          regionId: rq.regionId,\n          totalCpuQuota: rq.totalCpuQuota,\n          totalMemoryQuota: rq.totalMemoryQuota,\n          totalDiskQuota: rq.totalDiskQuota,\n          currentCpuUsage: sandboxUsage.currentCpuUsage,\n          currentMemoryUsage: sandboxUsage.currentMemoryUsage,\n          currentDiskUsage: sandboxUsage.currentDiskUsage,\n        }\n\n        return usage\n      }),\n    )\n\n    const snapshotUsage = await this.getSnapshotUsageOverview(organizationId)\n    const volumeUsage = await this.getVolumeUsageOverview(organizationId)\n\n    return {\n      regionUsage,\n      totalSnapshotQuota: organization.snapshotQuota,\n      totalVolumeQuota: organization.volumeQuota,\n      currentSnapshotUsage: snapshotUsage.currentSnapshotUsage,\n      currentVolumeUsage: volumeUsage.currentVolumeUsage,\n    }\n  }\n\n  /**\n   * Get the current and pending usage overview for sandbox-related organization quotas in a specific region.\n   *\n   * @param organizationId\n   * @param regionId\n   * @param excludeSandboxId - If provided, the usage overview will exclude the current usage of the sandbox with the given ID\n   */\n  async getSandboxUsageOverview(\n    organizationId: string,\n    regionId: string,\n    excludeSandboxId?: string,\n  ): Promise<SandboxUsageOverviewWithPendingInternalDto> {\n    let cachedUsageOverview = await this.getCachedSandboxUsageOverview(organizationId, regionId)\n\n    // cache hit\n    if (cachedUsageOverview) {\n      if (excludeSandboxId) {\n        return await this.excludeSandboxFromUsageOverview(cachedUsageOverview, excludeSandboxId)\n      }\n\n      return cachedUsageOverview\n    }\n\n    // cache miss, wait for lock\n    const lockKey = `org:${organizationId}:fetch-sandbox-usage-from-db`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    try {\n      // check if cache was updated while waiting for lock\n      cachedUsageOverview = await this.getCachedSandboxUsageOverview(organizationId, regionId)\n\n      // cache hit\n      if (cachedUsageOverview) {\n        if (excludeSandboxId) {\n          return await this.excludeSandboxFromUsageOverview(cachedUsageOverview, excludeSandboxId)\n        }\n\n        return cachedUsageOverview\n      }\n\n      // cache miss, fetch from db\n      const usageOverview = await this.fetchSandboxUsageFromDb(organizationId, regionId)\n\n      // get pending usage separately since it's not stored in DB\n      const pendingUsageOverview = await this.getCachedPendingSandboxUsageOverview(organizationId, regionId)\n\n      const combinedUsageOverview: SandboxUsageOverviewWithPendingInternalDto = {\n        ...usageOverview,\n        ...pendingUsageOverview,\n      }\n\n      if (excludeSandboxId) {\n        return await this.excludeSandboxFromUsageOverview(combinedUsageOverview, excludeSandboxId)\n      }\n\n      return combinedUsageOverview\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  /**\n   * Get the current and pending usage overview for snapshot-related organization quotas.\n   *\n   * @param organizationId\n   */\n  async getSnapshotUsageOverview(organizationId: string): Promise<SnapshotUsageOverviewWithPendingInternalDto> {\n    let cachedUsageOverview = await this.getCachedSnapshotUsageOverview(organizationId)\n\n    // cache hit\n    if (cachedUsageOverview) {\n      return cachedUsageOverview\n    }\n\n    // cache miss, wait for lock\n    const lockKey = `org:${organizationId}:fetch-snapshot-usage-from-db`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    try {\n      // check if cache was updated while waiting for lock\n      cachedUsageOverview = await this.getCachedSnapshotUsageOverview(organizationId)\n\n      // cache hit\n      if (cachedUsageOverview) {\n        return cachedUsageOverview\n      }\n\n      // cache miss, fetch from db\n      const usageOverview = await this.fetchSnapshotUsageFromDb(organizationId)\n\n      // get pending usage separately since it's not stored in DB\n      const pendingUsageOverview = await this.getCachedPendingSnapshotUsageOverview(organizationId)\n\n      return {\n        ...usageOverview,\n        ...pendingUsageOverview,\n      }\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  /**\n   * Get the current and pending usage overview for volume-related organization quotas.\n   *\n   * @param organizationId\n   */\n  async getVolumeUsageOverview(organizationId: string): Promise<VolumeUsageOverviewWithPendingInternalDto> {\n    let cachedUsageOverview = await this.getCachedVolumeUsageOverview(organizationId)\n\n    // cache hit\n    if (cachedUsageOverview) {\n      return cachedUsageOverview\n    }\n\n    // cache miss, wait for lock\n    const lockKey = `org:${organizationId}:fetch-volume-usage-from-db`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    try {\n      // check if cache was updated while waiting for lock\n      cachedUsageOverview = await this.getCachedVolumeUsageOverview(organizationId)\n\n      // cache hit\n      if (cachedUsageOverview) {\n        return cachedUsageOverview\n      }\n\n      // cache miss, fetch from db\n      const usageOverview = await this.fetchVolumeUsageFromDb(organizationId)\n\n      // get pending usage separately since it's not stored in DB\n      const pendingUsageOverview = await this.getCachedPendingVolumeUsageOverview(organizationId)\n\n      return {\n        ...usageOverview,\n        ...pendingUsageOverview,\n      }\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  /**\n   * Exclude the current usage of a specific sandbox from the usage overview.\n   *\n   * @param usageOverview\n   * @param excludeSandboxId\n   */\n  private async excludeSandboxFromUsageOverview<T extends SandboxUsageOverviewInternalDto>(\n    usageOverview: T,\n    excludeSandboxId: string,\n  ): Promise<T> {\n    const excludedSandbox = await this.sandboxRepository.findOne({\n      where: { id: excludeSandboxId },\n    })\n\n    if (!excludedSandbox) {\n      return usageOverview\n    }\n\n    let cpuToSubtract = 0\n    let memToSubtract = 0\n    let diskToSubtract = 0\n\n    if (SANDBOX_STATES_CONSUMING_COMPUTE.includes(excludedSandbox.state)) {\n      cpuToSubtract = excludedSandbox.cpu\n      memToSubtract = excludedSandbox.mem\n    }\n\n    if (SANDBOX_STATES_CONSUMING_DISK.includes(excludedSandbox.state)) {\n      diskToSubtract = excludedSandbox.disk\n    }\n\n    return {\n      ...usageOverview,\n      currentCpuUsage: Math.max(0, usageOverview.currentCpuUsage - cpuToSubtract),\n      currentMemoryUsage: Math.max(0, usageOverview.currentMemoryUsage - memToSubtract),\n      currentDiskUsage: Math.max(0, usageOverview.currentDiskUsage - diskToSubtract),\n    }\n  }\n\n  /**\n   * Get the cached current and pending usage overview for sandbox-related organization quotas in a specific region.\n   *\n   * @param organizationId\n   * @param regionId\n   */\n  private async getCachedSandboxUsageOverview(\n    organizationId: string,\n    regionId: string,\n  ): Promise<SandboxUsageOverviewWithPendingInternalDto | null> {\n    const script = `\n      return {\n        redis.call(\"GET\", KEYS[1]),\n        redis.call(\"GET\", KEYS[2]),\n        redis.call(\"GET\", KEYS[3]),\n        redis.call(\"GET\", KEYS[4]),\n        redis.call(\"GET\", KEYS[5]),\n        redis.call(\"GET\", KEYS[6])\n      }\n    `\n\n    const result = (await this.redis.eval(\n      script,\n      6,\n      this.getCurrentQuotaUsageCacheKey(organizationId, 'cpu', regionId),\n      this.getCurrentQuotaUsageCacheKey(organizationId, 'memory', regionId),\n      this.getCurrentQuotaUsageCacheKey(organizationId, 'disk', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'cpu', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'memory', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'disk', regionId),\n    )) as (string | null)[]\n\n    const [cpuUsage, memoryUsage, diskUsage, pendingCpuUsage, pendingMemoryUsage, pendingDiskUsage] = result\n\n    // Cache miss\n    if (cpuUsage === null || memoryUsage === null || diskUsage === null) {\n      return null\n    }\n\n    // Check cache staleness for current usage\n    const isStale = await this.isCacheStale(organizationId, 'sandbox', regionId)\n\n    if (isStale) {\n      return null\n    }\n\n    // Validate current usage values are non-negative numbers\n    const parsedCpuUsage = this.parseNonNegativeCachedValue(cpuUsage)\n    const parsedMemoryUsage = this.parseNonNegativeCachedValue(memoryUsage)\n    const parsedDiskUsage = this.parseNonNegativeCachedValue(diskUsage)\n\n    if (parsedCpuUsage === null || parsedMemoryUsage === null || parsedDiskUsage === null) {\n      return null\n    }\n\n    // Parse pending usage values (null is acceptable)\n    const parsedPendingCpuUsage = this.parseNonNegativeCachedValue(pendingCpuUsage)\n    const parsedPendingMemoryUsage = this.parseNonNegativeCachedValue(pendingMemoryUsage)\n    const parsedPendingDiskUsage = this.parseNonNegativeCachedValue(pendingDiskUsage)\n\n    return {\n      currentCpuUsage: parsedCpuUsage,\n      currentMemoryUsage: parsedMemoryUsage,\n      currentDiskUsage: parsedDiskUsage,\n      pendingCpuUsage: parsedPendingCpuUsage,\n      pendingMemoryUsage: parsedPendingMemoryUsage,\n      pendingDiskUsage: parsedPendingDiskUsage,\n    }\n  }\n\n  /**\n   * Get the cached pending usage overview for sandbox-related organization quotas in a specific region.\n   *\n   * @param organizationId\n   * @param regionId\n   */\n  private async getCachedPendingSandboxUsageOverview(\n    organizationId: string,\n    regionId: string,\n  ): Promise<PendingSandboxUsageOverviewInternalDto> {\n    const script = `\n      return {\n        redis.call(\"GET\", KEYS[1]),\n        redis.call(\"GET\", KEYS[2]),\n        redis.call(\"GET\", KEYS[3])\n      }\n    `\n    const result = (await this.redis.eval(\n      script,\n      3,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'cpu', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'memory', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'disk', regionId),\n    )) as (string | null)[]\n\n    const [pendingCpuUsage, pendingMemoryUsage, pendingDiskUsage] = result\n\n    const parsedPendingCpuUsage = this.parseNonNegativeCachedValue(pendingCpuUsage)\n    const parsedPendingMemoryUsage = this.parseNonNegativeCachedValue(pendingMemoryUsage)\n    const parsedPendingDiskUsage = this.parseNonNegativeCachedValue(pendingDiskUsage)\n\n    return {\n      pendingCpuUsage: parsedPendingCpuUsage,\n      pendingMemoryUsage: parsedPendingMemoryUsage,\n      pendingDiskUsage: parsedPendingDiskUsage,\n    }\n  }\n\n  /**\n   * Get the cached overview for current and pending usage for snapshot-related organization quotas.\n   *\n   * @param organizationId\n   */\n  private async getCachedSnapshotUsageOverview(\n    organizationId: string,\n  ): Promise<SnapshotUsageOverviewWithPendingInternalDto | null> {\n    const script = `\n      return {\n        redis.call(\"GET\", KEYS[1]),\n        redis.call(\"GET\", KEYS[2])\n      }\n    `\n    const result = (await this.redis.eval(\n      script,\n      2,\n      this.getCurrentQuotaUsageCacheKey(organizationId, 'snapshot_count'),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'snapshot_count'),\n    )) as (string | null)[]\n\n    const [currentSnapshotUsage, pendingSnapshotUsage] = result\n\n    // Cache miss\n    if (currentSnapshotUsage === null) {\n      return null\n    }\n\n    // Check cache staleness for current usage\n    const isStale = await this.isCacheStale(organizationId, 'snapshot')\n\n    if (isStale) {\n      return null\n    }\n\n    // Validate current usage values are non-negative numbers\n    const parsedCurrentSnapshotUsage = this.parseNonNegativeCachedValue(currentSnapshotUsage)\n\n    if (parsedCurrentSnapshotUsage === null) {\n      return null\n    }\n\n    // Parse pending usage values (null is acceptable)\n    const parsedPendingSnapshotUsage = this.parseNonNegativeCachedValue(pendingSnapshotUsage)\n\n    return {\n      currentSnapshotUsage: parsedCurrentSnapshotUsage,\n      pendingSnapshotUsage: parsedPendingSnapshotUsage,\n    }\n  }\n\n  /**\n   * Get the cached pending usage overview for snapshot-related organization quotas.\n   *\n   * @param organizationId\n   */\n  private async getCachedPendingSnapshotUsageOverview(\n    organizationId: string,\n  ): Promise<PendingSnapshotUsageOverviewInternalDto> {\n    const script = `\n      return {\n        redis.call(\"GET\", KEYS[1])\n      }\n    `\n    const result = (await this.redis.eval(\n      script,\n      1,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'snapshot_count'),\n    )) as (string | null)[]\n\n    const [pendingSnapshotUsage] = result\n\n    // Parse pending usage values (null is acceptable)\n    const parsedPendingSnapshotUsage = this.parseNonNegativeCachedValue(pendingSnapshotUsage)\n\n    return {\n      pendingSnapshotUsage: parsedPendingSnapshotUsage,\n    }\n  }\n\n  /**\n   * Get the cached overview for current and pending usage for volume-related organization quotas.\n   *\n   * @param organizationId\n   */\n  private async getCachedVolumeUsageOverview(\n    organizationId: string,\n  ): Promise<VolumeUsageOverviewWithPendingInternalDto | null> {\n    const script = `\n    return {\n      redis.call(\"GET\", KEYS[1]),\n      redis.call(\"GET\", KEYS[2])\n    }\n  `\n\n    const result = (await this.redis.eval(\n      script,\n      2,\n      this.getCurrentQuotaUsageCacheKey(organizationId, 'volume_count'),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'volume_count'),\n    )) as (string | null)[]\n\n    const [currentVolumeUsage, pendingVolumeUsage] = result\n\n    if (currentVolumeUsage === null) {\n      return null\n    }\n\n    // Check cache staleness for current usage\n    const isStale = await this.isCacheStale(organizationId, 'volume')\n\n    if (isStale) {\n      return null\n    }\n\n    // Validate current usage values are non-negative numbers\n    const parsedCurrentVolumeUsage = this.parseNonNegativeCachedValue(currentVolumeUsage)\n\n    if (parsedCurrentVolumeUsage === null) {\n      return null\n    }\n\n    // Parse pending usage values (null is acceptable)\n    const parsedPendingVolumeUsage = this.parseNonNegativeCachedValue(pendingVolumeUsage)\n\n    return {\n      currentVolumeUsage: parsedCurrentVolumeUsage,\n      pendingVolumeUsage: parsedPendingVolumeUsage,\n    }\n  }\n\n  /**\n   * Get the cached pending usage overview for volume-related organization quotas.\n   *\n   * @param organizationId\n   */\n  private async getCachedPendingVolumeUsageOverview(\n    organizationId: string,\n  ): Promise<PendingVolumeUsageOverviewInternalDto> {\n    const script = `\n      return {\n        redis.call(\"GET\", KEYS[1])\n      }\n    `\n\n    const result = (await this.redis.eval(\n      script,\n      1,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'volume_count'),\n    )) as (string | null)[]\n\n    const [pendingVolumeUsage] = result\n\n    // Parse pending usage values (null is acceptable)\n    const parsedPendingVolumeUsage = this.parseNonNegativeCachedValue(pendingVolumeUsage)\n\n    return {\n      pendingVolumeUsage: parsedPendingVolumeUsage,\n    }\n  }\n\n  /**\n   * Attempts to parse a given value to a non-negative number.\n   *\n   * @param value - The value to parse.\n   * @returns The parsed non-negative number or `null` if the given value is null or not a non-negative number.\n   */\n  private parseNonNegativeCachedValue(value: string | null): number | null {\n    if (value === null) {\n      return null\n    }\n\n    const parsedValue = Number(value)\n\n    if (isNaN(parsedValue) || parsedValue < 0) {\n      return null\n    }\n\n    return parsedValue\n  }\n\n  /**\n   * Fetch the current usage overview for sandbox-related organization quotas in a specific region from the database and cache the results.\n   *\n   * @param organizationId\n   * @param regionId\n   */\n  async fetchSandboxUsageFromDb(organizationId: string, regionId: string): Promise<SandboxUsageOverviewInternalDto> {\n    // fetch from db\n    // For CPU/memory, we need to also count RESIZING sandboxes that were hot resizing (desiredState = 'started')\n    // since they are still running and consuming compute resources\n    const sandboxUsageMetrics: {\n      used_cpu: number\n      used_mem: number\n      used_disk: number\n    } = await this.sandboxRepository\n      .createQueryBuilder('sandbox')\n      .select([\n        `SUM(CASE WHEN sandbox.state IN (:...statesConsumingCompute) OR (sandbox.state = :resizingState AND sandbox.\"desiredState\" = :startedDesiredState) THEN sandbox.cpu ELSE 0 END) as used_cpu`,\n        `SUM(CASE WHEN sandbox.state IN (:...statesConsumingCompute) OR (sandbox.state = :resizingState AND sandbox.\"desiredState\" = :startedDesiredState) THEN sandbox.mem ELSE 0 END) as used_mem`,\n        'SUM(CASE WHEN sandbox.state IN (:...statesConsumingDisk) THEN sandbox.disk ELSE 0 END) as used_disk',\n      ])\n      .where('sandbox.organizationId = :organizationId', { organizationId })\n      .andWhere('sandbox.region = :regionId', { regionId })\n      .setParameter('statesConsumingCompute', SANDBOX_STATES_CONSUMING_COMPUTE)\n      .setParameter('statesConsumingDisk', SANDBOX_STATES_CONSUMING_DISK)\n      .setParameter('resizingState', SandboxState.RESIZING)\n      .setParameter('startedDesiredState', SandboxDesiredState.STARTED)\n      .getRawOne()\n\n    const cpuUsage = Number(sandboxUsageMetrics.used_cpu) || 0\n    const memoryUsage = Number(sandboxUsageMetrics.used_mem) || 0\n    const diskUsage = Number(sandboxUsageMetrics.used_disk) || 0\n\n    // cache the results\n    const cpuCacheKey = this.getCurrentQuotaUsageCacheKey(organizationId, 'cpu', regionId)\n    const memoryCacheKey = this.getCurrentQuotaUsageCacheKey(organizationId, 'memory', regionId)\n    const diskCacheKey = this.getCurrentQuotaUsageCacheKey(organizationId, 'disk', regionId)\n\n    await this.redis\n      .multi()\n      .setex(cpuCacheKey, this.CACHE_TTL_SECONDS, cpuUsage)\n      .setex(memoryCacheKey, this.CACHE_TTL_SECONDS, memoryUsage)\n      .setex(diskCacheKey, this.CACHE_TTL_SECONDS, diskUsage)\n      .exec()\n\n    await this.resetCacheStaleness(organizationId, 'sandbox', regionId)\n\n    return {\n      currentCpuUsage: cpuUsage,\n      currentMemoryUsage: memoryUsage,\n      currentDiskUsage: diskUsage,\n    }\n  }\n\n  /**\n   * Fetch the current usage overview for snapshot-related organization quotas from the database and cache the results.\n   *\n   * @param organizationId\n   */\n  private async fetchSnapshotUsageFromDb(organizationId: string): Promise<SnapshotUsageOverviewInternalDto> {\n    // fetch from db\n    const snapshotUsage = await this.snapshotRepository.count({\n      where: {\n        organizationId,\n        state: In(SNAPSHOT_STATES_CONSUMING_RESOURCES),\n      },\n    })\n\n    // cache the result\n    const cacheKey = this.getCurrentQuotaUsageCacheKey(organizationId, 'snapshot_count')\n    await this.redis.setex(cacheKey, this.CACHE_TTL_SECONDS, snapshotUsage)\n\n    await this.resetCacheStaleness(organizationId, 'snapshot')\n\n    return {\n      currentSnapshotUsage: snapshotUsage,\n    }\n  }\n\n  /**\n   * Fetch the current usage overview for volume-related organization quotas from the database and cache the results.\n   *\n   * @param organizationId\n   */\n  private async fetchVolumeUsageFromDb(organizationId: string): Promise<VolumeUsageOverviewInternalDto> {\n    // fetch from db\n    const volumeUsage = await this.volumeRepository.count({\n      where: {\n        organizationId,\n        state: In(VOLUME_STATES_CONSUMING_RESOURCES),\n      },\n    })\n\n    // cache the result\n    const cacheKey = this.getCurrentQuotaUsageCacheKey(organizationId, 'volume_count')\n    await this.redis.setex(cacheKey, this.CACHE_TTL_SECONDS, volumeUsage)\n\n    await this.resetCacheStaleness(organizationId, 'volume')\n\n    return {\n      currentVolumeUsage: volumeUsage,\n    }\n  }\n\n  /**\n   * Get the cache key for the current usage of a given organization quota.\n   */\n  private getCurrentQuotaUsageCacheKey(\n    organizationId: string,\n    quotaType: 'cpu' | 'memory' | 'disk',\n    regionId: string,\n  ): string\n  private getCurrentQuotaUsageCacheKey(organizationId: string, quotaType: 'snapshot_count' | 'volume_count'): string\n  private getCurrentQuotaUsageCacheKey(\n    organizationId: string,\n    quotaType: OrganizationUsageQuotaType,\n    regionId?: string,\n  ): string {\n    return `org:${organizationId}${regionId ? `:region:${regionId}` : ''}:quota:${quotaType}:usage`\n  }\n\n  /**\n   * Get the cache key for the pending usage of a given organization quota.\n   */\n  private getPendingQuotaUsageCacheKey(\n    organizationId: string,\n    quotaType: 'cpu' | 'memory' | 'disk',\n    regionId: string,\n  ): string\n  private getPendingQuotaUsageCacheKey(organizationId: string, quotaType: 'snapshot_count' | 'volume_count'): string\n  private getPendingQuotaUsageCacheKey(\n    organizationId: string,\n    quotaType: OrganizationUsageQuotaType,\n    regionId?: string,\n  ): string {\n    return `org:${organizationId}${regionId ? `:region:${regionId}` : ''}:quota:${quotaType}:pending`\n  }\n\n  /**\n   * Updates the current usage of a given organization quota in the cache. If cache is not present, this method is a no-op.\n   *\n   * If the corresponding quota type has pending usage in the cache and the delta is positive, the pending usage is decremented accordingly.\n   */\n  private async updateCurrentQuotaUsage(\n    organizationId: string,\n    quotaType: 'cpu' | 'memory' | 'disk',\n    delta: number,\n    regionId: string,\n  ): Promise<void>\n  private async updateCurrentQuotaUsage(\n    organizationId: string,\n    quotaType: 'snapshot_count' | 'volume_count',\n    delta: number,\n  ): Promise<void>\n  private async updateCurrentQuotaUsage(\n    organizationId: string,\n    quotaType: OrganizationUsageQuotaType,\n    delta: number,\n    regionId?: string,\n  ): Promise<void> {\n    const script = `\n      local cacheKey = KEYS[1]\n      local pendingCacheKey = KEYS[2]\n      local delta = tonumber(ARGV[1])\n      local ttl = tonumber(ARGV[2])\n\n      if redis.call(\"EXISTS\", cacheKey) == 1 then\n        redis.call(\"INCRBY\", cacheKey, delta)\n        redis.call(\"EXPIRE\", cacheKey, ttl)\n      end\n\n      local pending = tonumber(redis.call(\"GET\", pendingCacheKey))\n      if pending and pending > 0 and delta > 0 then\n        redis.call(\"DECRBY\", pendingCacheKey, delta)\n      end\n    `\n\n    let currentQuotaUsageCacheKey = ''\n    let pendingQuotaUsageCacheKey = ''\n\n    switch (quotaType) {\n      case 'cpu':\n      case 'memory':\n      case 'disk':\n        currentQuotaUsageCacheKey = this.getCurrentQuotaUsageCacheKey(organizationId, quotaType, regionId)\n        pendingQuotaUsageCacheKey = this.getPendingQuotaUsageCacheKey(organizationId, quotaType, regionId)\n        break\n      case 'snapshot_count':\n      case 'volume_count':\n        currentQuotaUsageCacheKey = this.getCurrentQuotaUsageCacheKey(organizationId, quotaType)\n        pendingQuotaUsageCacheKey = this.getPendingQuotaUsageCacheKey(organizationId, quotaType)\n        break\n    }\n\n    await this.redis.eval(\n      script,\n      2,\n      currentQuotaUsageCacheKey,\n      pendingQuotaUsageCacheKey,\n      delta.toString(),\n      this.CACHE_TTL_SECONDS.toString(),\n    )\n  }\n\n  /**\n   * Increments the pending usage for sandbox-related organization quotas in a specific region.\n   *\n   * Pending usage is used to protect against race conditions to prevent quota abuse.\n   *\n   * If a user action will result in increased quota usage, we will first increment the pending usage.\n   *\n   * When the user action is complete, this pending usage will be transfered to the actual usage.\n   *\n   * As a safeguard, an expiration time is set on the pending usage cache to prevent lockout for new operations.\n   *\n   * @param organizationId\n   * @param regionId\n   * @param cpu - The amount of CPU to increment.\n   * @param memory - The amount of memory to increment.\n   * @param disk - The amount of disk to increment.\n   * @param excludeSandboxId - If provided, pending usage will be incremented only for quotas that are not consumed by the sandbox in its current state.\n   * @returns an object with the boolean values indicating if the pending usage was incremented for each quota type\n   */\n  async incrementPendingSandboxUsage(\n    organizationId: string,\n    regionId: string,\n    cpu: number,\n    memory: number,\n    disk: number,\n    excludeSandboxId?: string,\n  ): Promise<{\n    cpuIncremented: boolean\n    memoryIncremented: boolean\n    diskIncremented: boolean\n  }> {\n    // determine for which quota types we should increment the pending usage\n    let shouldIncrementCpu = true\n    let shouldIncrementMemory = true\n    let shouldIncrementDisk = true\n\n    if (excludeSandboxId) {\n      const excludedSandbox = await this.sandboxRepository.findOne({\n        where: { id: excludeSandboxId },\n      })\n\n      if (excludedSandbox) {\n        if (SANDBOX_STATES_CONSUMING_COMPUTE.includes(excludedSandbox.state)) {\n          shouldIncrementCpu = false\n          shouldIncrementMemory = false\n        }\n\n        if (SANDBOX_STATES_CONSUMING_DISK.includes(excludedSandbox.state)) {\n          shouldIncrementDisk = false\n        }\n      }\n    }\n\n    // increment the pending usage for necessary quota types\n    const script = `\n      local cpuKey = KEYS[1]\n      local memoryKey = KEYS[2]\n      local diskKey = KEYS[3]\n\n      local shouldIncrementCpu = ARGV[1] == \"true\"\n      local shouldIncrementMemory = ARGV[2] == \"true\"\n      local shouldIncrementDisk = ARGV[3] == \"true\"\n\n      local cpuIncrement = tonumber(ARGV[4])\n      local memoryIncrement = tonumber(ARGV[5])\n      local diskIncrement = tonumber(ARGV[6])\n\n      local ttl = tonumber(ARGV[7])\n    \n      if shouldIncrementCpu then\n        redis.call(\"INCRBY\", cpuKey, cpuIncrement)\n        redis.call(\"EXPIRE\", cpuKey, ttl)\n      end\n\n      if shouldIncrementMemory then\n        redis.call(\"INCRBY\", memoryKey, memoryIncrement)\n        redis.call(\"EXPIRE\", memoryKey, ttl)\n      end\n\n      if shouldIncrementDisk then\n        redis.call(\"INCRBY\", diskKey, diskIncrement)\n        redis.call(\"EXPIRE\", diskKey, ttl)\n      end\n    `\n\n    await this.redis.eval(\n      script,\n      3,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'cpu', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'memory', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'disk', regionId),\n      shouldIncrementCpu.toString(),\n      shouldIncrementMemory.toString(),\n      shouldIncrementDisk.toString(),\n      cpu.toString(),\n      memory.toString(),\n      disk.toString(),\n      this.CACHE_TTL_SECONDS.toString(),\n    )\n\n    return {\n      cpuIncremented: shouldIncrementCpu,\n      memoryIncremented: shouldIncrementMemory,\n      diskIncremented: shouldIncrementDisk,\n    }\n  }\n\n  /**\n   * Decrements the pending usage for sandbox-related organization quotas in a specific region.\n   *\n   * Use this method to roll back pending usage after incrementing it for an action that was subsequently rejected.\n   *\n   * Pending usage is used to protect against race conditions to prevent quota abuse.\n   *\n   * If a user action will result in increased quota usage, we will first increment the pending usage.\n   *\n   * When the user action is complete, this pending usage will be transfered to the actual usage.\n   *\n   * @param organizationId\n   * @param regionId\n   * @param cpu - If provided, the amount of CPU to decrement.\n   * @param memory - If provided, the amount of memory to decrement.\n   * @param disk - If provided, the amount of disk to decrement.\n   */\n  async decrementPendingSandboxUsage(\n    organizationId: string,\n    regionId: string,\n    cpu?: number,\n    memory?: number,\n    disk?: number,\n  ): Promise<void> {\n    // decrement the pending usage for necessary quota types\n    const script = `\n      local cpuKey = KEYS[1]\n      local memoryKey = KEYS[2] \n      local diskKey = KEYS[3]\n\n      local cpuDecrement = tonumber(ARGV[1])\n      local memoryDecrement = tonumber(ARGV[2])\n      local diskDecrement = tonumber(ARGV[3])\n      \n      if cpuDecrement then\n        redis.call(\"DECRBY\", cpuKey, cpuDecrement)\n      end\n\n      if memoryDecrement then\n        redis.call(\"DECRBY\", memoryKey, memoryDecrement)\n      end\n\n      if diskDecrement then\n        redis.call(\"DECRBY\", diskKey, diskDecrement)\n      end\n    `\n\n    await this.redis.eval(\n      script,\n      3,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'cpu', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'memory', regionId),\n      this.getPendingQuotaUsageCacheKey(organizationId, 'disk', regionId),\n      cpu?.toString() ?? '0',\n      memory?.toString() ?? '0',\n      disk?.toString() ?? '0',\n    )\n  }\n\n  /**\n   * Increments the pending usage for snapshot-related organization quotas.\n   *\n   * Pending usage is used to protect against race conditions to prevent quota abuse.\n   *\n   * If a user action will result in increased quota usage, we will first increment the pending usage.\n   *\n   * When the user action is complete, this pending usage will be transfered to the actual usage.\n   *\n   * As a safeguard, an expiration time is set on the pending usage cache to prevent lockout for new operations.\n   *\n   * @param organizationId\n   * @param snapshotCount - The count of snapshots to increment.\n   */\n  async incrementPendingSnapshotUsage(organizationId: string, snapshotCount: number): Promise<void> {\n    const script = `\n      local snapshotCountKey = KEYS[1]\n\n      local snapshotCountIncrement = tonumber(ARGV[1])\n      local ttl = tonumber(ARGV[2])\n    \n      redis.call(\"INCRBY\", snapshotCountKey, snapshotCountIncrement)\n      redis.call(\"EXPIRE\", snapshotCountKey, ttl)\n    `\n\n    await this.redis.eval(\n      script,\n      1,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'snapshot_count'),\n      snapshotCount.toString(),\n      this.CACHE_TTL_SECONDS.toString(),\n    )\n  }\n\n  /**\n   * Decrements the pending usage for snapshot-related organization quotas.\n   *\n   * Use this method to roll back pending usage after incrementing it for an action that was subsequently rejected.\n   *\n   * Pending usage is used to protect against race conditions to prevent quota abuse.\n   *\n   * If a user action will result in increased quota usage, we will first increment the pending usage.\n   *\n   * When the user action is complete, this pending usage will be transfered to the actual usage.\n   *\n   * @param organizationId\n   * @param snapshotCount - If provided, the count of snapshots to decrement.\n   */\n  async decrementPendingSnapshotUsage(organizationId: string, snapshotCount?: number): Promise<void> {\n    // decrement the pending usage for necessary quota types\n    const script = `\n      local snapshotCountKey = KEYS[1]\n\n      local snapshotCountDecrement = tonumber(ARGV[1])\n      \n      if snapshotCountDecrement then\n        redis.call(\"DECRBY\", snapshotCountKey, snapshotCountDecrement)\n      end\n    `\n\n    await this.redis.eval(\n      script,\n      1,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'snapshot_count'),\n      snapshotCount?.toString() ?? '0',\n    )\n  }\n\n  /**\n   * Increments the pending usage for volume-related organization quotas.\n   *\n   * Pending usage is used to protect against race conditions to prevent quota abuse.\n   *\n   * If a user action will result in increased quota usage, we will first increment the pending usage.\n   *\n   * When the user action is complete, this pending usage will be transfered to the actual usage.\n   *\n   * As a safeguard, an expiration time is set on the pending usage cache to prevent lockout for new operations.\n   *\n   * @param organizationId\n   * @param volumeCount - The count of volumes to increment.\n   */\n  async incrementPendingVolumeUsage(organizationId: string, volumeCount: number): Promise<void> {\n    const script = `\n      local volumeCountKey = KEYS[1]\n\n      local volumeCountIncrement = tonumber(ARGV[1])\n      local ttl = tonumber(ARGV[2])\n    \n      redis.call(\"INCRBY\", volumeCountKey, volumeCountIncrement)\n      redis.call(\"EXPIRE\", volumeCountKey, ttl)\n    `\n\n    await this.redis.eval(\n      script,\n      1,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'volume_count'),\n      volumeCount.toString(),\n      this.CACHE_TTL_SECONDS.toString(),\n    )\n  }\n\n  /**\n   * Decrements the pending usage for volume-related organization quotas.\n   *\n   * Use this method to roll back pending usage after incrementing it for an action that was subsequently rejected.\n   *\n   * Pending usage is used to protect against race conditions to prevent quota abuse.\n   *\n   * If a user action will result in increased quota usage, we will first increment the pending usage.\n   *\n   * When the user action is complete, this pending usage will be transfered to the actual usage.\n   *\n   * @param organizationId\n   * @param volumeCount - If provided, the count of volumes to decrement.\n   */\n  async decrementPendingVolumeUsage(organizationId: string, volumeCount?: number): Promise<void> {\n    // decrement the pending usage for necessary quota types\n    const script = `\n      local volumeCountKey = KEYS[1]\n\n      local volumeCountDecrement = tonumber(ARGV[1])\n\n      if volumeCountDecrement then\n        redis.call(\"DECRBY\", volumeCountKey, volumeCountDecrement)\n      end\n    `\n\n    await this.redis.eval(\n      script,\n      1,\n      this.getPendingQuotaUsageCacheKey(organizationId, 'volume_count'),\n      volumeCount?.toString() ?? '0',\n    )\n  }\n\n  /**\n   * Apply usage change after resize completes successfully.\n   * Updates current usage and clears pending by the deltas.\n   * Supports both positive (increase) and negative (decrease) deltas.\n   * @param organizationId\n   * @param regionId\n   * @param cpuDelta\n   * @param memDelta\n   * @param diskDelta\n   */\n  async applyResizeUsageChange(\n    organizationId: string,\n    regionId: string,\n    cpuDelta: number,\n    memDelta: number,\n    diskDelta: number,\n  ): Promise<void> {\n    if (cpuDelta !== 0) {\n      await this.updateCurrentQuotaUsage(organizationId, 'cpu', cpuDelta, regionId)\n    }\n    if (memDelta !== 0) {\n      await this.updateCurrentQuotaUsage(organizationId, 'memory', memDelta, regionId)\n    }\n    if (diskDelta !== 0) {\n      await this.updateCurrentQuotaUsage(organizationId, 'disk', diskDelta, regionId)\n    }\n  }\n\n  /**\n   * Get the cache key for the timestamp of the last time the cached usage of organization quotas for a given resource type was populated from the database.\n   *\n   * @param organizationId\n   * @param resourceType\n   * @param regionId\n   */\n  private getCacheStalenessKey(\n    organizationId: string,\n    resourceType: OrganizationUsageResourceType,\n    regionId?: string,\n  ): string {\n    return `org:${organizationId}${regionId ? `:region:${regionId}` : ''}:resource:${resourceType}:usage:fetched_at`\n  }\n\n  /**\n   * Reset the timestamp of the last time the cached usage of organization quotas for a given resource type was populated from the database.\n   */\n  private resetCacheStaleness(organizationId: string, resourceType: 'sandbox', regionId: string): Promise<void>\n  private resetCacheStaleness(organizationId: string, resourceType: 'snapshot' | 'volume'): Promise<void>\n  private async resetCacheStaleness(\n    organizationId: string,\n    resourceType: OrganizationUsageResourceType,\n    regionId?: string,\n  ): Promise<void> {\n    const cacheKey = this.getCacheStalenessKey(organizationId, resourceType, regionId)\n    await this.redis.set(cacheKey, Date.now())\n  }\n\n  /**\n   * Check if the cached usage of organization quotas for a given resource type was last populated from the database more than CACHE_MAX_AGE_MS ago.\n   *\n   * @returns `true` if the cached usage is stale, `false` otherwise\n   */\n  private async isCacheStale(organizationId: string, resourceType: 'sandbox', regionId: string): Promise<boolean>\n  private async isCacheStale(organizationId: string, resourceType: 'snapshot' | 'volume'): Promise<boolean>\n  private async isCacheStale(\n    organizationId: string,\n    resourceType: OrganizationUsageResourceType,\n    regionId?: string,\n  ): Promise<boolean> {\n    const cacheKey = this.getCacheStalenessKey(organizationId, resourceType, regionId)\n    const cachedData = await this.redis.get(cacheKey)\n\n    if (!cachedData) {\n      return true\n    }\n\n    const lastFetchedAtTimestamp = Number(cachedData)\n    if (isNaN(lastFetchedAtTimestamp)) {\n      return true\n    }\n\n    return Date.now() - lastFetchedAtTimestamp > this.CACHE_MAX_AGE_MS\n  }\n\n  @OnEvent(SandboxEvents.CREATED)\n  async handleSandboxCreated(event: SandboxCreatedEvent) {\n    const lockKey = `sandbox:${event.sandbox.id}:quota-usage-update`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    try {\n      await this.updateCurrentQuotaUsage(event.sandbox.organizationId, 'cpu', event.sandbox.cpu, event.sandbox.region)\n      await this.updateCurrentQuotaUsage(\n        event.sandbox.organizationId,\n        'memory',\n        event.sandbox.mem,\n        event.sandbox.region,\n      )\n      await this.updateCurrentQuotaUsage(event.sandbox.organizationId, 'disk', event.sandbox.disk, event.sandbox.region)\n    } catch (error) {\n      this.logger.warn(\n        `Error updating cached sandbox quota usage for organization ${event.sandbox.organizationId} in region ${event.sandbox.region}`,\n        error,\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @OnEvent(SandboxEvents.STATE_UPDATED)\n  async handleSandboxStateUpdated(event: SandboxStateUpdatedEvent) {\n    if (event.oldState === SandboxState.RESIZING || event.newState === SandboxState.RESIZING) {\n      return\n    }\n\n    const lockKey = `sandbox:${event.sandbox.id}:quota-usage-update`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    // Special case for warm pool sandboxes (otherwise the quota usage deltas would be 0 due to the \"unchanged\" state)\n    if (event.oldState === event.newState && event.newState === SandboxState.STARTED) {\n      try {\n        await this.updateCurrentQuotaUsage(event.sandbox.organizationId, 'cpu', event.sandbox.cpu, event.sandbox.region)\n        await this.updateCurrentQuotaUsage(\n          event.sandbox.organizationId,\n          'memory',\n          event.sandbox.mem,\n          event.sandbox.region,\n        )\n        await this.updateCurrentQuotaUsage(\n          event.sandbox.organizationId,\n          'disk',\n          event.sandbox.disk,\n          event.sandbox.region,\n        )\n        return\n      } catch (error) {\n        this.logger.warn(\n          `Error updating cached sandbox quota usage for organization ${event.sandbox.organizationId} in region ${event.sandbox.region}`,\n          error,\n        )\n        return\n      } finally {\n        await this.redisLockProvider.unlock(lockKey)\n      }\n    }\n\n    try {\n      const cpuDelta = this.calculateQuotaUsageDelta(\n        event.sandbox.cpu,\n        event.oldState,\n        event.newState,\n        SANDBOX_STATES_CONSUMING_COMPUTE,\n      )\n\n      const memDelta = this.calculateQuotaUsageDelta(\n        event.sandbox.mem,\n        event.oldState,\n        event.newState,\n        SANDBOX_STATES_CONSUMING_COMPUTE,\n      )\n\n      const diskDelta = this.calculateQuotaUsageDelta(\n        event.sandbox.disk,\n        event.oldState,\n        event.newState,\n        SANDBOX_STATES_CONSUMING_DISK,\n      )\n\n      if (cpuDelta !== 0) {\n        await this.updateCurrentQuotaUsage(event.sandbox.organizationId, 'cpu', cpuDelta, event.sandbox.region)\n      }\n\n      if (memDelta !== 0) {\n        await this.updateCurrentQuotaUsage(event.sandbox.organizationId, 'memory', memDelta, event.sandbox.region)\n      }\n\n      if (diskDelta !== 0) {\n        await this.updateCurrentQuotaUsage(event.sandbox.organizationId, 'disk', diskDelta, event.sandbox.region)\n      }\n    } catch (error) {\n      this.logger.warn(\n        `Error updating cached sandbox quota usage for organization ${event.sandbox.organizationId} in region ${event.sandbox.region}`,\n        error,\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @OnEvent(SnapshotEvents.CREATED)\n  async handleSnapshotCreated(event: SnapshotCreatedEvent) {\n    const lockKey = `snapshot:${event.snapshot.id}:quota-usage-update`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    try {\n      await this.updateCurrentQuotaUsage(event.snapshot.organizationId, 'snapshot_count', 1)\n    } catch (error) {\n      this.logger.warn(\n        `Error updating cached snapshot quota usage for organization ${event.snapshot.organizationId}`,\n        error,\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @OnEvent(SnapshotEvents.STATE_UPDATED)\n  async handleSnapshotStateUpdated(event: SnapshotStateUpdatedEvent) {\n    const lockKey = `snapshot:${event.snapshot.id}:quota-usage-update`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    try {\n      const countDelta = this.calculateQuotaUsageDelta(\n        1,\n        event.oldState,\n        event.newState,\n        SNAPSHOT_STATES_CONSUMING_RESOURCES,\n      )\n\n      if (countDelta !== 0) {\n        await this.updateCurrentQuotaUsage(event.snapshot.organizationId, 'snapshot_count', countDelta)\n      }\n    } catch (error) {\n      this.logger.warn(\n        `Error updating cached snapshot quota usage for organization ${event.snapshot.organizationId}`,\n        error,\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @OnEvent(VolumeEvents.CREATED)\n  async handleVolumeCreated(event: VolumeCreatedEvent) {\n    const lockKey = `volume:${event.volume.id}:quota-usage-update`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    try {\n      await this.updateCurrentQuotaUsage(event.volume.organizationId, 'volume_count', 1)\n    } catch (error) {\n      this.logger.warn(\n        `Error updating cached volume quota usage for organization ${event.volume.organizationId}`,\n        error,\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @OnEvent(VolumeEvents.STATE_UPDATED)\n  async handleVolumeStateUpdated(event: VolumeStateUpdatedEvent) {\n    const lockKey = `volume:${event.volume.id}:quota-usage-update`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    try {\n      const countDelta = this.calculateQuotaUsageDelta(\n        1,\n        event.oldState,\n        event.newState,\n        VOLUME_STATES_CONSUMING_RESOURCES,\n      )\n\n      if (countDelta !== 0) {\n        await this.updateCurrentQuotaUsage(event.volume.organizationId, 'volume_count', countDelta)\n      }\n    } catch (error) {\n      this.logger.warn(\n        `Error updating cached volume quota usage for organization ${event.volume.organizationId}`,\n        error,\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  private calculateQuotaUsageDelta<TState>(\n    resourceAmount: number,\n    oldState: TState,\n    newState: TState,\n    statesConsumingResource: TState[],\n  ): number {\n    const wasConsumingResource = statesConsumingResource.includes(oldState)\n    const isConsumingResource = statesConsumingResource.includes(newState)\n\n    if (!wasConsumingResource && isConsumingResource) {\n      return resourceAmount\n    }\n\n    if (wasConsumingResource && !isConsumingResource) {\n      return -resourceAmount\n    }\n\n    return 0\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/services/organization-user.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BadRequestException, ForbiddenException, Injectable, NotFoundException } from '@nestjs/common'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { DataSource, EntityManager, Repository } from 'typeorm'\nimport { OrganizationRoleService } from './organization-role.service'\nimport { OrganizationEvents } from '../constants/organization-events.constant'\nimport { OrganizationUserDto } from '../dto/organization-user.dto'\nimport { OrganizationUser } from '../entities/organization-user.entity'\nimport { OrganizationRole } from '../entities/organization-role.entity'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OrganizationResourcePermission } from '../enums/organization-resource-permission.enum'\nimport { OrganizationInvitationAcceptedEvent } from '../events/organization-invitation-accepted.event'\nimport { OrganizationResourcePermissionsUnassignedEvent } from '../events/organization-resource-permissions-unassigned.event'\nimport { OnAsyncEvent } from '../../common/decorators/on-async-event.decorator'\nimport { UserService } from '../../user/user.service'\nimport { UserEvents } from '../../user/constants/user-events.constant'\nimport { UserDeletedEvent } from '../../user/events/user-deleted.event'\n\n@Injectable()\nexport class OrganizationUserService {\n  constructor(\n    @InjectRepository(OrganizationUser)\n    private readonly organizationUserRepository: Repository<OrganizationUser>,\n    private readonly organizationRoleService: OrganizationRoleService,\n    private readonly userService: UserService,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly dataSource: DataSource,\n  ) {}\n\n  async findAll(organizationId: string): Promise<OrganizationUserDto[]> {\n    const organizationUsers = await this.organizationUserRepository.find({\n      where: { organizationId },\n      relations: {\n        assignedRoles: true,\n      },\n    })\n\n    const userIds = organizationUsers.map((orgUser) => orgUser.userId)\n\n    const users = await this.userService.findByIds(userIds)\n    const userMap = new Map(users.map((user) => [user.id, user]))\n\n    const dtos: OrganizationUserDto[] = organizationUsers.map((orgUser) => {\n      const user = userMap.get(orgUser.userId)\n      return OrganizationUserDto.fromEntities(orgUser, user)\n    })\n\n    return dtos\n  }\n\n  async findOne(organizationId: string, userId: string): Promise<OrganizationUser | null> {\n    return this.organizationUserRepository.findOne({\n      where: { organizationId, userId },\n      relations: {\n        assignedRoles: true,\n      },\n    })\n  }\n\n  async exists(organizationId: string, userId: string): Promise<boolean> {\n    return this.organizationUserRepository.exists({\n      where: { organizationId, userId },\n    })\n  }\n\n  async updateAccess(\n    organizationId: string,\n    userId: string,\n    role: OrganizationMemberRole,\n    assignedRoleIds: string[],\n  ): Promise<OrganizationUserDto> {\n    let organizationUser = await this.organizationUserRepository.findOne({\n      where: {\n        organizationId,\n        userId,\n      },\n      relations: {\n        assignedRoles: true,\n      },\n    })\n\n    if (!organizationUser) {\n      throw new NotFoundException(`User with ID ${userId} not found in organization with ID ${organizationId}`)\n    }\n\n    // validate role\n    if (organizationUser.role === OrganizationMemberRole.OWNER && role !== OrganizationMemberRole.OWNER) {\n      const ownersCount = await this.organizationUserRepository.count({\n        where: {\n          organizationId,\n          role: OrganizationMemberRole.OWNER,\n        },\n      })\n\n      if (ownersCount === 1) {\n        throw new ForbiddenException('The organization must have at least one owner')\n      }\n    }\n\n    // validate assignments\n    const assignedRoles = await this.organizationRoleService.findByIds(assignedRoleIds)\n    if (assignedRoles.length !== assignedRoleIds.length) {\n      throw new BadRequestException('One or more role IDs are invalid')\n    }\n\n    // check if any previous permissions are not present in the new assignments, api keys with those permissions will be revoked\n    let permissionsToRevoke: OrganizationResourcePermission[] = []\n    if (role !== OrganizationMemberRole.OWNER) {\n      const prevPermissions = this.getAssignedPermissions(organizationUser.role, organizationUser.assignedRoles)\n      const newPermissions = this.getAssignedPermissions(role, assignedRoles)\n      permissionsToRevoke = Array.from(prevPermissions).filter((permission) => !newPermissions.has(permission))\n    }\n\n    organizationUser.role = role\n    organizationUser.assignedRoles = assignedRoles\n\n    if (permissionsToRevoke.length > 0) {\n      await this.dataSource.transaction(async (em) => {\n        organizationUser = await em.save(organizationUser)\n        await this.eventEmitter.emitAsync(\n          OrganizationEvents.PERMISSIONS_UNASSIGNED,\n          new OrganizationResourcePermissionsUnassignedEvent(em, organizationId, userId, permissionsToRevoke),\n        )\n      })\n    } else {\n      organizationUser = await this.organizationUserRepository.save(organizationUser)\n    }\n\n    const user = await this.userService.findOne(userId)\n\n    return OrganizationUserDto.fromEntities(organizationUser, user)\n  }\n\n  async delete(organizationId: string, userId: string): Promise<void> {\n    const organizationUser = await this.organizationUserRepository.findOne({\n      where: {\n        organizationId,\n        userId,\n      },\n    })\n\n    if (!organizationUser) {\n      throw new NotFoundException(`User with ID ${userId} not found in organization with ID ${organizationId}`)\n    }\n\n    await this.removeWithEntityManager(this.organizationUserRepository.manager, organizationUser)\n  }\n\n  private async removeWithEntityManager(\n    entityManager: EntityManager,\n    organizationUser: OrganizationUser,\n    force = false,\n  ): Promise<void> {\n    if (!force) {\n      if (organizationUser.role === OrganizationMemberRole.OWNER) {\n        const ownersCount = await entityManager.count(OrganizationUser, {\n          where: {\n            organizationId: organizationUser.organizationId,\n            role: OrganizationMemberRole.OWNER,\n          },\n        })\n\n        if (ownersCount === 1) {\n          throw new ForbiddenException(\n            `Organization with ID ${organizationUser.organizationId} must have at least one owner`,\n          )\n        }\n      }\n    }\n\n    await entityManager.remove(organizationUser)\n  }\n\n  private async createWithEntityManager(\n    entityManager: EntityManager,\n    organizationId: string,\n    userId: string,\n    role: OrganizationMemberRole,\n    assignedRoles: OrganizationRole[],\n  ): Promise<OrganizationUser> {\n    const organizationUser = new OrganizationUser()\n    organizationUser.organizationId = organizationId\n    organizationUser.userId = userId\n    organizationUser.role = role\n    organizationUser.assignedRoles = assignedRoles\n    return entityManager.save(organizationUser)\n  }\n\n  @OnAsyncEvent({\n    event: OrganizationEvents.INVITATION_ACCEPTED,\n  })\n  async handleOrganizationInvitationAcceptedEvent(\n    payload: OrganizationInvitationAcceptedEvent,\n  ): Promise<OrganizationUser> {\n    return this.createWithEntityManager(\n      payload.entityManager,\n      payload.organizationId,\n      payload.userId,\n      payload.role,\n      payload.assignedRoles,\n    )\n  }\n\n  @OnAsyncEvent({\n    event: UserEvents.DELETED,\n  })\n  async handleUserDeletedEvent(payload: UserDeletedEvent): Promise<void> {\n    const memberships = await payload.entityManager.find(OrganizationUser, {\n      where: {\n        userId: payload.userId,\n        organization: {\n          personal: false,\n        },\n      },\n      relations: {\n        organization: true,\n      },\n    })\n\n    /*\n    // TODO\n    // user deletion will fail if the user is the only owner of some non-personal organization\n    // potential improvements:\n    //  - auto-delete the organization if there are no other members\n    //  - auto-promote a new owner if there are other members\n    */\n    await Promise.all(memberships.map((membership) => this.removeWithEntityManager(payload.entityManager, membership)))\n  }\n\n  private getAssignedPermissions(\n    role: OrganizationMemberRole,\n    assignedRoles: OrganizationRole[],\n  ): Set<OrganizationResourcePermission> {\n    if (role === OrganizationMemberRole.OWNER) {\n      return new Set(Object.values(OrganizationResourcePermission))\n    }\n\n    return new Set(assignedRoles.flatMap((role) => role.permissions))\n  }\n}\n"
  },
  {
    "path": "apps/api/src/organization/services/organization.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  ForbiddenException,\n  Injectable,\n  NotFoundException,\n  Logger,\n  OnModuleInit,\n  OnApplicationShutdown,\n  ConflictException,\n} from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { EntityManager, In, Not, Repository } from 'typeorm'\nimport { CreateOrganizationInternalDto } from '../dto/create-organization.internal.dto'\nimport { UpdateOrganizationQuotaDto } from '../dto/update-organization-quota.dto'\nimport { Organization } from '../entities/organization.entity'\nimport { OrganizationUser } from '../entities/organization-user.entity'\nimport { OrganizationMemberRole } from '../enums/organization-member-role.enum'\nimport { OnAsyncEvent } from '../../common/decorators/on-async-event.decorator'\nimport { UserEvents } from '../../user/constants/user-events.constant'\nimport { UserCreatedEvent } from '../../user/events/user-created.event'\nimport { UserDeletedEvent } from '../../user/events/user-deleted.event'\nimport { Snapshot } from '../../sandbox/entities/snapshot.entity'\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { OrganizationEvents } from '../constants/organization-events.constant'\nimport { CreateOrganizationQuotaDto } from '../dto/create-organization-quota.dto'\nimport { UserEmailVerifiedEvent } from '../../user/events/user-email-verified.event'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { RedisLockProvider } from '../../sandbox/common/redis-lock.provider'\nimport { OrganizationSuspendedSandboxStoppedEvent } from '../events/organization-suspended-sandbox-stopped.event'\nimport { SandboxDesiredState } from '../../sandbox/enums/sandbox-desired-state.enum'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { SnapshotState } from '../../sandbox/enums/snapshot-state.enum'\nimport { OrganizationSuspendedSnapshotDeactivatedEvent } from '../events/organization-suspended-snapshot-deactivated.event'\nimport { TrackJobExecution } from '../../common/decorators/track-job-execution.decorator'\nimport { TrackableJobExecutions } from '../../common/interfaces/trackable-job-executions'\nimport { setTimeout } from 'timers/promises'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\nimport { RegionQuota } from '../entities/region-quota.entity'\nimport { UpdateOrganizationRegionQuotaDto } from '../dto/update-organization-region-quota.dto'\nimport { RegionService } from '../../region/services/region.service'\nimport { Region } from '../../region/entities/region.entity'\nimport { RegionQuotaDto } from '../dto/region-quota.dto'\nimport { RegionType } from '../../region/enums/region-type.enum'\nimport { RegionDto } from '../../region/dto/region.dto'\nimport { EncryptionService } from '../../encryption/encryption.service'\nimport { OtelConfigDto } from '../dto/otel-config.dto'\nimport { sandboxLookupCacheKeyByAuthToken } from '../../sandbox/utils/sandbox-lookup-cache.util'\nimport { SandboxRepository } from '../../sandbox/repositories/sandbox.repository'\n\n@Injectable()\nexport class OrganizationService implements OnModuleInit, TrackableJobExecutions, OnApplicationShutdown {\n  activeJobs = new Set<string>()\n  private readonly logger = new Logger(OrganizationService.name)\n  private defaultOrganizationQuota: CreateOrganizationQuotaDto\n  private defaultSandboxLimitedNetworkEgress: boolean\n\n  constructor(\n    @InjectRepository(Organization)\n    private readonly organizationRepository: Repository<Organization>,\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly configService: TypedConfigService,\n    private readonly redisLockProvider: RedisLockProvider,\n    @InjectRepository(RegionQuota)\n    private readonly regionQuotaRepository: Repository<RegionQuota>,\n    @InjectRepository(Region)\n    private readonly regionRepository: Repository<Region>,\n    private readonly regionService: RegionService,\n    private readonly encryptionService: EncryptionService,\n  ) {\n    this.defaultOrganizationQuota = this.configService.getOrThrow('defaultOrganizationQuota')\n    this.defaultSandboxLimitedNetworkEgress = this.configService.getOrThrow(\n      'organizationSandboxDefaultLimitedNetworkEgress',\n    )\n  }\n\n  async onApplicationShutdown() {\n    //  wait for all active jobs to finish\n    while (this.activeJobs.size > 0) {\n      this.logger.log(`Waiting for ${this.activeJobs.size} active jobs to finish`)\n      await setTimeout(1000)\n    }\n  }\n\n  async onModuleInit(): Promise<void> {\n    await this.stopSuspendedOrganizationSandboxes()\n  }\n\n  async create(\n    createOrganizationDto: CreateOrganizationInternalDto,\n    createdBy: string,\n    personal = false,\n    creatorEmailVerified = false,\n  ): Promise<Organization> {\n    return this.createWithEntityManager(\n      this.organizationRepository.manager,\n      createOrganizationDto,\n      createdBy,\n      creatorEmailVerified,\n      personal,\n    )\n  }\n\n  async findByUser(userId: string): Promise<Organization[]> {\n    return this.organizationRepository.find({\n      where: {\n        users: {\n          userId,\n        },\n      },\n    })\n  }\n\n  async findOne(organizationId: string): Promise<Organization | null> {\n    return this.organizationRepository.findOne({\n      where: { id: organizationId },\n    })\n  }\n\n  async findBySandboxId(sandboxId: string): Promise<Organization | null> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: { id: sandboxId },\n    })\n\n    if (!sandbox) {\n      return null\n    }\n\n    return this.organizationRepository.findOne({ where: { id: sandbox.organizationId } })\n  }\n\n  async findBySandboxAuthToken(authToken: string): Promise<Organization | null> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: { authToken },\n      cache: {\n        id: sandboxLookupCacheKeyByAuthToken({ authToken }),\n        milliseconds: 10_000,\n      },\n    })\n\n    if (!sandbox) {\n      return null\n    }\n\n    return this.organizationRepository.findOne({ where: { id: sandbox.organizationId } })\n  }\n\n  async findPersonal(userId: string): Promise<Organization> {\n    return this.findPersonalWithEntityManager(this.organizationRepository.manager, userId)\n  }\n\n  async delete(organizationId: string): Promise<void> {\n    const organization = await this.organizationRepository.findOne({ where: { id: organizationId } })\n\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n\n    return this.removeWithEntityManager(this.organizationRepository.manager, organization)\n  }\n\n  async updateQuota(organizationId: string, updateDto: UpdateOrganizationQuotaDto): Promise<void> {\n    const organization = await this.organizationRepository.findOne({ where: { id: organizationId } })\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n\n    organization.maxCpuPerSandbox = updateDto.maxCpuPerSandbox ?? organization.maxCpuPerSandbox\n    organization.maxMemoryPerSandbox = updateDto.maxMemoryPerSandbox ?? organization.maxMemoryPerSandbox\n    organization.maxDiskPerSandbox = updateDto.maxDiskPerSandbox ?? organization.maxDiskPerSandbox\n    organization.maxSnapshotSize = updateDto.maxSnapshotSize ?? organization.maxSnapshotSize\n    organization.volumeQuota = updateDto.volumeQuota ?? organization.volumeQuota\n    organization.snapshotQuota = updateDto.snapshotQuota ?? organization.snapshotQuota\n    organization.authenticatedRateLimit = updateDto.authenticatedRateLimit ?? organization.authenticatedRateLimit\n    organization.sandboxCreateRateLimit = updateDto.sandboxCreateRateLimit ?? organization.sandboxCreateRateLimit\n    organization.sandboxLifecycleRateLimit =\n      updateDto.sandboxLifecycleRateLimit ?? organization.sandboxLifecycleRateLimit\n    organization.authenticatedRateLimitTtlSeconds =\n      updateDto.authenticatedRateLimitTtlSeconds ?? organization.authenticatedRateLimitTtlSeconds\n    organization.sandboxCreateRateLimitTtlSeconds =\n      updateDto.sandboxCreateRateLimitTtlSeconds ?? organization.sandboxCreateRateLimitTtlSeconds\n    organization.sandboxLifecycleRateLimitTtlSeconds =\n      updateDto.sandboxLifecycleRateLimitTtlSeconds ?? organization.sandboxLifecycleRateLimitTtlSeconds\n    organization.snapshotDeactivationTimeoutMinutes =\n      updateDto.snapshotDeactivationTimeoutMinutes ?? organization.snapshotDeactivationTimeoutMinutes\n\n    await this.organizationRepository.save(organization)\n  }\n\n  async updateRegionQuota(\n    organizationId: string,\n    regionId: string,\n    updateDto: UpdateOrganizationRegionQuotaDto,\n  ): Promise<void> {\n    const regionQuota = await this.regionQuotaRepository.findOne({ where: { organizationId, regionId } })\n    if (!regionQuota) {\n      throw new NotFoundException('Region not found')\n    }\n\n    regionQuota.totalCpuQuota = updateDto.totalCpuQuota ?? regionQuota.totalCpuQuota\n    regionQuota.totalMemoryQuota = updateDto.totalMemoryQuota ?? regionQuota.totalMemoryQuota\n    regionQuota.totalDiskQuota = updateDto.totalDiskQuota ?? regionQuota.totalDiskQuota\n\n    await this.regionQuotaRepository.save(regionQuota)\n  }\n\n  async getRegionQuotas(organizationId: string): Promise<RegionQuotaDto[]> {\n    const regionQuotas = await this.regionQuotaRepository.find({ where: { organizationId } })\n    return regionQuotas.map((regionQuota) => new RegionQuotaDto(regionQuota))\n  }\n\n  async getRegionQuota(organizationId: string, regionId: string): Promise<RegionQuotaDto | null> {\n    const regionQuota = await this.regionQuotaRepository.findOne({ where: { organizationId, regionId } })\n    if (!regionQuota) {\n      return null\n    }\n    return new RegionQuotaDto(regionQuota)\n  }\n\n  async getRegionQuotaBySandboxId(sandboxId: string): Promise<RegionQuotaDto | null> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: { id: sandboxId },\n    })\n    if (!sandbox) {\n      return null\n    }\n    return this.getRegionQuota(sandbox.organizationId, sandbox.region)\n  }\n\n  /**\n   * Lists all available regions for the organization.\n   *\n   * A region is available for the organization if either:\n   * - It is directly associated with the organization, or\n   * - It is not associated with any organization, but the organization has quotas allocated for the region or quotas are not enforced for the region\n   *\n   * @param organizationId - The organization ID.\n   * @returns The available regions\n   */\n  async listAvailableRegions(organizationId: string): Promise<RegionDto[]> {\n    const regions = await this.regionRepository\n      .createQueryBuilder('region')\n      .where('region.\"regionType\" = :customRegionType AND region.\"organizationId\" = :organizationId', {\n        customRegionType: RegionType.CUSTOM,\n        organizationId,\n      })\n      .orWhere('region.\"regionType\" IN (:...otherRegionTypes) AND region.\"enforceQuotas\" = false', {\n        otherRegionTypes: [RegionType.DEDICATED, RegionType.SHARED],\n      })\n      .orWhere(\n        'region.\"regionType\" IN (:...otherRegionTypes) AND region.\"enforceQuotas\" = true AND EXISTS (SELECT 1 FROM region_quota rq WHERE rq.\"regionId\" = region.\"id\" AND rq.\"organizationId\" = :organizationId)',\n        {\n          otherRegionTypes: [RegionType.DEDICATED, RegionType.SHARED],\n          organizationId,\n        },\n      )\n      .orderBy(\n        `CASE region.\"regionType\" \n          WHEN '${RegionType.CUSTOM}' THEN 1 \n          WHEN '${RegionType.DEDICATED}' THEN 2 \n          WHEN '${RegionType.SHARED}' THEN 3 \n          ELSE 4 \n        END`,\n      )\n      .getMany()\n\n    return regions.map(RegionDto.fromRegion)\n  }\n\n  async suspend(\n    organizationId: string,\n    suspensionReason?: string,\n    suspendedUntil?: Date,\n    suspensionCleanupGracePeriodHours?: number,\n  ): Promise<void> {\n    const organization = await this.organizationRepository.findOne({ where: { id: organizationId } })\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n\n    organization.suspended = true\n    organization.suspensionReason = suspensionReason || null\n    organization.suspendedUntil = suspendedUntil || null\n    organization.suspendedAt = new Date()\n    if (suspensionCleanupGracePeriodHours) {\n      organization.suspensionCleanupGracePeriodHours = suspensionCleanupGracePeriodHours\n    }\n\n    await this.organizationRepository.save(organization)\n  }\n\n  async unsuspend(organizationId: string): Promise<void> {\n    const organization = await this.organizationRepository.findOne({ where: { id: organizationId } })\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n\n    organization.suspended = false\n    organization.suspensionReason = null\n    organization.suspendedUntil = null\n    organization.suspendedAt = null\n\n    await this.organizationRepository.save(organization)\n  }\n\n  async updateSandboxDefaultLimitedNetworkEgress(\n    organizationId: string,\n    sandboxDefaultLimitedNetworkEgress: boolean,\n  ): Promise<void> {\n    const organization = await this.organizationRepository.findOne({ where: { id: organizationId } })\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n    organization.sandboxLimitedNetworkEgress = sandboxDefaultLimitedNetworkEgress\n\n    await this.organizationRepository.save(organization)\n  }\n\n  /**\n   * @param organizationId - The ID of the organization.\n   * @param defaultRegionId - The ID of the region to set as the default region.\n   * @throws {NotFoundException} If the organization is not found.\n   * @throws {ConflictException} If the organization already has a default region set.\n   */\n  async setDefaultRegion(organizationId: string, defaultRegionId: string): Promise<void> {\n    const organization = await this.organizationRepository.findOne({ where: { id: organizationId } })\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n\n    if (organization.defaultRegionId) {\n      throw new ConflictException('Organization already has a default region set')\n    }\n\n    const defaultRegion = await this.validateOrganizationDefaultRegion(defaultRegionId)\n    organization.defaultRegionId = defaultRegionId\n\n    if (defaultRegion.enforceQuotas) {\n      const regionQuota = new RegionQuota(\n        organization.id,\n        defaultRegionId,\n        this.defaultOrganizationQuota.totalCpuQuota,\n        this.defaultOrganizationQuota.totalMemoryQuota,\n        this.defaultOrganizationQuota.totalDiskQuota,\n      )\n      if (organization.regionQuotas) {\n        organization.regionQuotas = [...organization.regionQuotas, regionQuota]\n      } else {\n        organization.regionQuotas = [regionQuota]\n      }\n    }\n\n    await this.organizationRepository.save(organization)\n  }\n\n  async updateExperimentalConfig(\n    organizationId: string,\n    experimentalConfig: Record<string, any> | null,\n  ): Promise<void> {\n    const organization = await this.organizationRepository.findOne({ where: { id: organizationId } })\n    if (!organization) {\n      throw new NotFoundException(`Organization with ID ${organizationId} not found`)\n    }\n\n    const existingConfig = organization._experimentalConfig\n\n    organization._experimentalConfig = await this.validatedExperimentalConfig(experimentalConfig)\n\n    // If experimentalConfig contains redacted fields, we need to preserve the existing encrypted values\n    if (experimentalConfig && experimentalConfig.otel && experimentalConfig.otel.headers) {\n      if (existingConfig && existingConfig.otel && existingConfig.otel.headers) {\n        for (const [key, value] of Object.entries(experimentalConfig.otel.headers)) {\n          if (\n            typeof value === 'string' &&\n            value.match(/\\*/g)?.length === value.length &&\n            existingConfig.otel.headers[key]\n          ) {\n            organization._experimentalConfig.otel.headers[key] = existingConfig.otel.headers[key]\n          }\n        }\n      }\n    }\n\n    await this.organizationRepository.save(organization)\n  }\n\n  async getOtelConfigBySandboxAuthToken(sandboxAuthToken: string): Promise<OtelConfigDto | null> {\n    const organization = await this.findBySandboxAuthToken(sandboxAuthToken)\n    if (!organization) {\n      return null\n    }\n\n    if (!organization._experimentalConfig || !organization._experimentalConfig.otel) {\n      return null\n    }\n\n    const otelConfig = organization._experimentalConfig.otel\n    const decryptedHeaders: Record<string, string> = {}\n    if (otelConfig.headers && typeof otelConfig.headers === 'object') {\n      for (const [key, value] of Object.entries(otelConfig.headers)) {\n        if (typeof key === 'string' && key.trim() && typeof value === 'string' && value.trim()) {\n          decryptedHeaders[key] = await this.encryptionService.decrypt(value)\n        }\n      }\n    }\n\n    return {\n      endpoint: otelConfig.endpoint,\n      headers: Object.keys(decryptedHeaders).length > 0 ? decryptedHeaders : undefined,\n    }\n  }\n\n  private async validatedExperimentalConfig(\n    experimentalConfig: Record<string, any> | null,\n  ): Promise<Record<string, any> | null> {\n    if (!experimentalConfig) {\n      return null\n    }\n\n    if (!experimentalConfig.otel) {\n      return experimentalConfig\n    }\n\n    const otelConfig = { ...experimentalConfig.otel }\n    if (typeof otelConfig.endpoint !== 'string' || !otelConfig.endpoint.trim()) {\n      throw new ForbiddenException('Invalid OpenTelemetry endpoint')\n    }\n\n    if (otelConfig.headers && typeof otelConfig.headers === 'object') {\n      const headers: Record<string, string> = {}\n      for (const [key, value] of Object.entries(otelConfig.headers)) {\n        if (typeof key === 'string' && key.trim() && typeof value === 'string' && value.trim()) {\n          headers[key] = await this.encryptionService.encrypt(value)\n        }\n      }\n      otelConfig.headers = headers\n    } else {\n      otelConfig.headers = {}\n    }\n\n    return {\n      ...experimentalConfig,\n      otel: otelConfig,\n    }\n  }\n\n  private async createWithEntityManager(\n    entityManager: EntityManager,\n    createOrganizationDto: CreateOrganizationInternalDto,\n    createdBy: string,\n    creatorEmailVerified: boolean,\n    personal = false,\n    quota: CreateOrganizationQuotaDto = this.defaultOrganizationQuota,\n    sandboxLimitedNetworkEgress: boolean = this.defaultSandboxLimitedNetworkEgress,\n  ): Promise<Organization> {\n    if (personal) {\n      const count = await entityManager.count(Organization, {\n        where: { createdBy, personal: true },\n      })\n      if (count > 0) {\n        throw new ForbiddenException('Personal organization already exists')\n      }\n    }\n\n    // set some limit to the number of created organizations\n    const createdCount = await entityManager.count(Organization, {\n      where: { createdBy },\n    })\n    if (createdCount >= 10) {\n      throw new ForbiddenException('You have reached the maximum number of created organizations')\n    }\n\n    let organization = new Organization(createOrganizationDto.defaultRegionId)\n\n    organization.name = createOrganizationDto.name\n    organization.createdBy = createdBy\n    organization.personal = personal\n\n    organization.maxCpuPerSandbox = quota.maxCpuPerSandbox\n    organization.maxMemoryPerSandbox = quota.maxMemoryPerSandbox\n    organization.maxDiskPerSandbox = quota.maxDiskPerSandbox\n    organization.snapshotQuota = quota.snapshotQuota\n    organization.maxSnapshotSize = quota.maxSnapshotSize\n    organization.volumeQuota = quota.volumeQuota\n\n    if (!creatorEmailVerified && !this.configService.get('skipUserEmailVerification')) {\n      organization.suspended = true\n      organization.suspendedAt = new Date()\n      organization.suspensionReason = 'Please verify your email address'\n    } else if (this.configService.get('billingApiUrl') && !personal) {\n      organization.suspended = true\n      organization.suspendedAt = new Date()\n      organization.suspensionReason = 'Payment method required'\n    }\n\n    organization.sandboxLimitedNetworkEgress = sandboxLimitedNetworkEgress\n\n    const owner = new OrganizationUser()\n    owner.userId = createdBy\n    owner.role = OrganizationMemberRole.OWNER\n\n    organization.users = [owner]\n\n    if (createOrganizationDto.defaultRegionId) {\n      const defaultRegion = await this.validateOrganizationDefaultRegion(createOrganizationDto.defaultRegionId)\n\n      if (defaultRegion.enforceQuotas) {\n        const regionQuota = new RegionQuota(\n          organization.id,\n          createOrganizationDto.defaultRegionId,\n          quota.totalCpuQuota,\n          quota.totalMemoryQuota,\n          quota.totalDiskQuota,\n        )\n        organization.regionQuotas = [regionQuota]\n      }\n    }\n\n    await entityManager.transaction(async (em) => {\n      organization = await em.save(organization)\n      await this.eventEmitter.emitAsync(OrganizationEvents.CREATED, organization)\n    })\n\n    return organization\n  }\n\n  private async removeWithEntityManager(\n    entityManager: EntityManager,\n    organization: Organization,\n    force = false,\n  ): Promise<void> {\n    if (!force) {\n      if (organization.personal) {\n        throw new ForbiddenException('Cannot delete personal organization')\n      }\n    }\n    await entityManager.remove(organization)\n  }\n\n  private async unsuspendPersonalWithEntityManager(entityManager: EntityManager, userId: string): Promise<void> {\n    const organization = await this.findPersonalWithEntityManager(entityManager, userId)\n\n    organization.suspended = false\n    organization.suspendedAt = null\n    organization.suspensionReason = null\n    organization.suspendedUntil = null\n    await entityManager.save(organization)\n  }\n\n  private async findPersonalWithEntityManager(entityManager: EntityManager, userId: string): Promise<Organization> {\n    const organization = await entityManager.findOne(Organization, {\n      where: { createdBy: userId, personal: true },\n    })\n\n    if (!organization) {\n      throw new NotFoundException(`Personal organization for user ${userId} not found`)\n    }\n\n    return organization\n  }\n\n  /**\n   * @throws NotFoundException - If the region is not found or not available to the organization\n   */\n  async validateOrganizationDefaultRegion(defaultRegionId: string): Promise<Region> {\n    const region = await this.regionService.findOne(defaultRegionId)\n    if (!region || region.regionType !== RegionType.SHARED) {\n      throw new NotFoundException('Region not found')\n    }\n\n    return region\n  }\n\n  @Cron(CronExpression.EVERY_MINUTE, { name: 'stop-suspended-organization-sandboxes' })\n  @TrackJobExecution()\n  @LogExecution('stop-suspended-organization-sandboxes')\n  @WithInstrumentation()\n  async stopSuspendedOrganizationSandboxes(): Promise<void> {\n    //  lock the sync to only run one instance at a time\n    const lockKey = 'stop-suspended-organization-sandboxes'\n    if (!(await this.redisLockProvider.lock(lockKey, 60))) {\n      return\n    }\n\n    const queryResult = await this.organizationRepository\n      .createQueryBuilder('organization')\n      .select('id')\n      .where('suspended = true')\n      .andWhere(`\"suspendedAt\" < NOW() - INTERVAL '1 hour' * \"suspensionCleanupGracePeriodHours\"`)\n      .andWhere(`\"suspendedAt\" > NOW() - INTERVAL '7 day'`)\n      .andWhereExists(\n        this.sandboxRepository\n          .createQueryBuilder('sandbox')\n          .select('1')\n          .where(\n            `\"sandbox\".\"organizationId\" = \"organization\".\"id\" AND \"sandbox\".\"desiredState\" = '${SandboxDesiredState.STARTED}' and \"sandbox\".\"state\" NOT IN ('${SandboxState.ERROR}', '${SandboxState.BUILD_FAILED}')`,\n          ),\n      )\n      .take(100)\n      .getRawMany()\n\n    const suspendedOrganizationIds = queryResult.map((result) => result.id)\n\n    // Skip if no suspended organizations found to avoid empty IN clause\n    if (suspendedOrganizationIds.length === 0) {\n      await this.redisLockProvider.unlock(lockKey)\n      return\n    }\n\n    const sandboxes = await this.sandboxRepository.find({\n      where: {\n        organizationId: In(suspendedOrganizationIds),\n        desiredState: SandboxDesiredState.STARTED,\n        state: Not(In([SandboxState.ERROR, SandboxState.BUILD_FAILED])),\n      },\n    })\n\n    sandboxes.map((sandbox) =>\n      this.eventEmitter.emitAsync(\n        OrganizationEvents.SUSPENDED_SANDBOX_STOPPED,\n        new OrganizationSuspendedSandboxStoppedEvent(sandbox.id),\n      ),\n    )\n\n    await this.redisLockProvider.unlock(lockKey)\n  }\n\n  @Cron(CronExpression.EVERY_MINUTE, { name: 'deactivate-suspended-organization-snapshots' })\n  @TrackJobExecution()\n  @LogExecution('deactivate-suspended-organization-snapshots')\n  @WithInstrumentation()\n  async deactivateSuspendedOrganizationSnapshots(): Promise<void> {\n    //  lock the sync to only run one instance at a time\n    const lockKey = 'deactivate-suspended-organization-snapshots'\n    if (!(await this.redisLockProvider.lock(lockKey, 60))) {\n      return\n    }\n\n    const queryResult = await this.organizationRepository\n      .createQueryBuilder('organization')\n      .select('id')\n      .where('suspended = true')\n      .andWhere(`\"suspendedAt\" < NOW() - INTERVAL '1 hour' * \"suspensionCleanupGracePeriodHours\"`)\n      .andWhere(`\"suspendedAt\" > NOW() - INTERVAL '7 day'`)\n      .andWhereExists(\n        this.snapshotRepository\n          .createQueryBuilder('snapshot')\n          .select('1')\n          .where('snapshot.organizationId = organization.id')\n          .andWhere(`snapshot.state = '${SnapshotState.ACTIVE}'`)\n          .andWhere(`snapshot.general = false`),\n      )\n      .take(100)\n      .getRawMany()\n\n    const suspendedOrganizationIds = queryResult.map((result) => result.id)\n\n    // Skip if no suspended organizations found to avoid empty IN clause\n    if (suspendedOrganizationIds.length === 0) {\n      await this.redisLockProvider.unlock(lockKey)\n      return\n    }\n\n    const snapshotQueryResult = await this.snapshotRepository\n      .createQueryBuilder('snapshot')\n      .select('id')\n      .where('snapshot.organizationId IN (:...suspendedOrgIds)', { suspendedOrgIds: suspendedOrganizationIds })\n      .andWhere(`snapshot.state = '${SnapshotState.ACTIVE}'`)\n      .andWhere(`snapshot.general = false`)\n      .take(100)\n      .getRawMany()\n\n    const snapshotIds = snapshotQueryResult.map((result) => result.id)\n\n    snapshotIds.map((id) =>\n      this.eventEmitter.emitAsync(\n        OrganizationEvents.SUSPENDED_SNAPSHOT_DEACTIVATED,\n        new OrganizationSuspendedSnapshotDeactivatedEvent(id),\n      ),\n    )\n\n    await this.redisLockProvider.unlock(lockKey)\n  }\n\n  @OnAsyncEvent({\n    event: UserEvents.CREATED,\n  })\n  @TrackJobExecution()\n  async handleUserCreatedEvent(payload: UserCreatedEvent): Promise<Organization> {\n    return this.createWithEntityManager(\n      payload.entityManager,\n      {\n        name: 'Personal',\n        defaultRegionId: payload.personalOrganizationDefaultRegionId,\n      },\n      payload.user.id,\n      payload.user.role === SystemRole.ADMIN ? true : payload.user.emailVerified,\n      true,\n      payload.personalOrganizationQuota,\n      payload.user.role === SystemRole.ADMIN ? false : undefined,\n    )\n  }\n\n  @OnAsyncEvent({\n    event: UserEvents.EMAIL_VERIFIED,\n  })\n  @TrackJobExecution()\n  async handleUserEmailVerifiedEvent(payload: UserEmailVerifiedEvent): Promise<void> {\n    await this.unsuspendPersonalWithEntityManager(payload.entityManager, payload.userId)\n  }\n\n  @OnAsyncEvent({\n    event: UserEvents.DELETED,\n  })\n  @TrackJobExecution()\n  async handleUserDeletedEvent(payload: UserDeletedEvent): Promise<void> {\n    const organization = await this.findPersonalWithEntityManager(payload.entityManager, payload.userId)\n\n    await this.removeWithEntityManager(payload.entityManager, organization, true)\n  }\n\n  assertOrganizationIsNotSuspended(organization: Organization): void {\n    if (!organization.suspended) {\n      return\n    }\n\n    if (organization.suspendedUntil ? organization.suspendedUntil > new Date() : true) {\n      if (organization.suspensionReason) {\n        throw new ForbiddenException(`Organization is suspended: ${organization.suspensionReason}`)\n      } else {\n        throw new ForbiddenException('Organization is suspended')\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/region/constants/region-events.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const RegionEvents = {\n  CREATED: 'region.created',\n  DELETED: 'region.deleted',\n  SNAPSHOT_MANAGER_CREDENTIALS_REGENERATED: 'region.snapshot-manager-credentials-regenerated',\n  SNAPSHOT_MANAGER_UPDATED: 'region.snapshot-manager-updated',\n} as const\n"
  },
  {
    "path": "apps/api/src/region/constants/region-name-regex.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const REGION_NAME_REGEX = /^[a-zA-Z0-9_.-]+$/\n"
  },
  {
    "path": "apps/api/src/region/controllers/region.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Get, Logger, HttpCode } from '@nestjs/common'\nimport { ApiOAuth2, ApiResponse, ApiOperation, ApiTags, ApiBearerAuth } from '@nestjs/swagger'\nimport { RegionDto } from '../dto/region.dto'\nimport { RegionType } from '../enums/region-type.enum'\nimport { RegionService } from '../services/region.service'\n\n@ApiTags('regions')\n@Controller('shared-regions')\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class RegionController {\n  private readonly logger = new Logger(RegionController.name)\n\n  constructor(private readonly regionService: RegionService) {}\n\n  @Get()\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'List all shared regions',\n    operationId: 'listSharedRegions',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of all shared regions',\n    type: [RegionDto],\n  })\n  async listRegions(): Promise<RegionDto[]> {\n    return this.regionService.findAllByRegionType(RegionType.SHARED)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/region/dto/create-region-internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { RegionType } from '../enums/region-type.enum'\n\nexport class CreateRegionInternalDto {\n  id?: string\n  name: string\n  enforceQuotas: boolean\n  regionType: RegionType\n  proxyUrl?: string | null\n  sshGatewayUrl?: string | null\n  snapshotManagerUrl?: string | null\n}\n"
  },
  {
    "path": "apps/api/src/region/dto/create-region.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsString, IsNotEmpty } from 'class-validator'\n\n@ApiSchema({ name: 'CreateRegion' })\nexport class CreateRegionDto {\n  @ApiProperty({\n    description: 'Region name',\n    example: 'us-east-1',\n  })\n  @IsString()\n  @IsNotEmpty()\n  name: string\n\n  @ApiProperty({\n    description: 'Proxy URL for the region',\n    example: 'https://proxy.example.com',\n    nullable: true,\n    required: false,\n  })\n  proxyUrl?: string\n\n  @ApiProperty({\n    description: 'SSH Gateway URL for the region',\n    example: 'ssh://ssh-gateway.example.com',\n    nullable: true,\n    required: false,\n  })\n  sshGatewayUrl?: string\n\n  @ApiProperty({\n    description: 'Snapshot Manager URL for the region',\n    example: 'https://snapshot-manager.example.com',\n    nullable: true,\n    required: false,\n  })\n  snapshotManagerUrl?: string\n}\n\n@ApiSchema({ name: 'CreateRegionResponse' })\nexport class CreateRegionResponseDto {\n  @ApiProperty({\n    description: 'ID of the created region',\n    example: 'region_12345',\n  })\n  @IsString()\n  @IsNotEmpty()\n  id: string\n\n  @ApiProperty({\n    description: 'Proxy API key for the region',\n    example: 'proxy-api-key-xyz',\n    nullable: true,\n    required: false,\n  })\n  proxyApiKey?: string\n\n  @ApiProperty({\n    description: 'SSH Gateway API key for the region',\n    example: 'ssh-gateway-api-key-abc',\n    nullable: true,\n    required: false,\n  })\n  sshGatewayApiKey?: string\n\n  @ApiProperty({\n    description: 'Snapshot Manager username for the region',\n    example: 'daytona',\n    nullable: true,\n    required: false,\n  })\n  snapshotManagerUsername?: string\n\n  @ApiProperty({\n    description: 'Snapshot Manager password for the region',\n    nullable: true,\n    required: false,\n  })\n  snapshotManagerPassword?: string\n\n  constructor(params: {\n    id: string\n    proxyApiKey?: string\n    sshGatewayApiKey?: string\n    snapshotManagerUsername?: string\n    snapshotManagerPassword?: string\n  }) {\n    this.id = params.id\n    this.proxyApiKey = params.proxyApiKey\n    this.sshGatewayApiKey = params.sshGatewayApiKey\n    this.snapshotManagerUsername = params.snapshotManagerUsername\n    this.snapshotManagerPassword = params.snapshotManagerPassword\n  }\n}\n"
  },
  {
    "path": "apps/api/src/region/dto/create-region.internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface CreateRegionInternalDto {\n  id?: string\n  name: string\n  enforceQuotas: boolean\n}\n"
  },
  {
    "path": "apps/api/src/region/dto/regenerate-api-key.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsString, IsNotEmpty } from 'class-validator'\n\n@ApiSchema({ name: 'RegenerateApiKeyResponse' })\nexport class RegenerateApiKeyResponseDto {\n  @ApiProperty({\n    description: 'The newly generated API key',\n    example: 'api-key-xyz123',\n  })\n  @IsString()\n  @IsNotEmpty()\n  apiKey: string\n\n  constructor(apiKey: string) {\n    this.apiKey = apiKey\n  }\n}\n"
  },
  {
    "path": "apps/api/src/region/dto/region.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsEnum } from 'class-validator'\nimport { Region } from '../entities/region.entity'\nimport { RegionType } from '../enums/region-type.enum'\n\n@ApiSchema({ name: 'Region' })\nexport class RegionDto {\n  @ApiProperty({\n    description: 'Region ID',\n    example: '123456789012',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Region name',\n    example: 'us-east-1',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n    nullable: true,\n    required: false,\n  })\n  organizationId: string | null\n\n  @ApiProperty({\n    description: 'The type of the region',\n    enum: RegionType,\n    enumName: 'RegionType',\n    example: Object.values(RegionType)[0],\n  })\n  @IsEnum(RegionType)\n  regionType: RegionType\n\n  @ApiProperty({\n    description: 'Creation timestamp',\n    example: '2023-01-01T00:00:00.000Z',\n  })\n  createdAt: string\n\n  @ApiProperty({\n    description: 'Last update timestamp',\n    example: '2023-01-01T00:00:00.000Z',\n  })\n  updatedAt: string\n\n  @ApiProperty({\n    description: 'Proxy URL for the region',\n    example: 'https://proxy.example.com',\n    nullable: true,\n    required: false,\n  })\n  proxyUrl?: string | null\n\n  @ApiProperty({\n    description: 'SSH Gateway URL for the region',\n    example: 'http://ssh-gateway.example.com',\n    nullable: true,\n    required: false,\n  })\n  sshGatewayUrl?: string | null\n\n  @ApiProperty({\n    description: 'Snapshot Manager URL for the region',\n    example: 'http://snapshot-manager.example.com',\n    nullable: true,\n    required: false,\n  })\n  snapshotManagerUrl?: string | null\n\n  static fromRegion(region: Region): RegionDto {\n    return {\n      id: region.id,\n      name: region.name,\n      organizationId: region.organizationId,\n      regionType: region.regionType,\n      createdAt: region.createdAt?.toISOString(),\n      updatedAt: region.updatedAt?.toISOString(),\n      proxyUrl: region.proxyUrl,\n      sshGatewayUrl: region.sshGatewayUrl,\n      snapshotManagerUrl: region.snapshotManagerUrl,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/region/dto/snapshot-manager-credentials.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiSchema, ApiProperty } from '@nestjs/swagger'\nimport { IsString, IsNotEmpty } from 'class-validator'\n\n@ApiSchema({ name: 'SnapshotManagerCredentials' })\nexport class SnapshotManagerCredentialsDto {\n  @ApiProperty({\n    description: 'Snapshot Manager username for the region',\n    example: 'daytona',\n  })\n  @IsString()\n  @IsNotEmpty()\n  username: string\n\n  @ApiProperty({\n    description: 'Snapshot Manager password for the region',\n  })\n  @IsString()\n  @IsNotEmpty()\n  password: string\n\n  constructor(params: { username: string; password: string }) {\n    this.username = params.username\n    this.password = params.password\n  }\n}\n"
  },
  {
    "path": "apps/api/src/region/dto/update-region.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'UpdateRegion' })\nexport class UpdateRegionDto {\n  @ApiProperty({\n    description: 'Proxy URL for the region',\n    example: 'https://proxy.example.com',\n    nullable: true,\n    required: false,\n  })\n  proxyUrl?: string\n\n  @ApiProperty({\n    description: 'SSH Gateway URL for the region',\n    example: 'ssh://ssh-gateway.example.com',\n    nullable: true,\n    required: false,\n  })\n  sshGatewayUrl?: string\n\n  @ApiProperty({\n    description: 'Snapshot Manager URL for the region',\n    example: 'https://snapshot-manager.example.com',\n    nullable: true,\n    required: false,\n  })\n  snapshotManagerUrl?: string\n}\n"
  },
  {
    "path": "apps/api/src/region/entities/region.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  BeforeInsert,\n  BeforeUpdate,\n  Check,\n  Column,\n  CreateDateColumn,\n  Entity,\n  Index,\n  PrimaryColumn,\n  UpdateDateColumn,\n} from 'typeorm'\nimport { nanoid } from 'nanoid'\nimport { RegionType } from '../enums/region-type.enum'\n\n@Entity()\n@Index('region_organizationId_name_unique', ['organizationId', 'name'], {\n  unique: true,\n  where: '\"organizationId\" IS NOT NULL',\n})\n@Index('region_organizationId_null_name_unique', ['name'], {\n  unique: true,\n  where: '\"organizationId\" IS NULL',\n})\n@Index('region_proxyApiKeyHash_unique', ['proxyApiKeyHash'], {\n  unique: true,\n  where: '\"proxyApiKeyHash\" IS NOT NULL',\n})\n@Index('region_sshGatewayApiKeyHash_unique', ['sshGatewayApiKeyHash'], {\n  unique: true,\n  where: '\"sshGatewayApiKeyHash\" IS NOT NULL',\n})\n@Index('idx_region_custom', ['organizationId'], {\n  where: '\"regionType\" = \\'custom\\'',\n})\n@Check('region_not_shared', '\"organizationId\" IS NULL OR \"regionType\" != \\'shared\\'')\n@Check('region_not_custom', '\"organizationId\" IS NOT NULL OR \"regionType\" != \\'custom\\'')\nexport class Region {\n  @PrimaryColumn()\n  id: string\n\n  @Column()\n  name: string\n\n  @Column({\n    type: 'uuid',\n    nullable: true,\n  })\n  organizationId: string | null\n\n  @Column({\n    type: 'enum',\n    enum: RegionType,\n  })\n  regionType: RegionType\n\n  @Column({\n    type: 'boolean',\n    default: true,\n  })\n  enforceQuotas: boolean\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  @Column({ nullable: true })\n  proxyUrl: string | null\n\n  @Column({ nullable: true })\n  toolboxProxyUrl: string | null\n\n  @Column({ nullable: true })\n  proxyApiKeyHash: string | null\n\n  @Column({ nullable: true })\n  sshGatewayUrl: string | null\n\n  @Column({ nullable: true })\n  sshGatewayApiKeyHash: string | null\n\n  @Column({ nullable: true })\n  snapshotManagerUrl: string | null\n\n  constructor(params: {\n    name: string\n    enforceQuotas: boolean\n    regionType: RegionType\n    id?: string\n    organizationId?: string | null\n    proxyUrl?: string | null\n    toolboxProxyUrl?: string | null\n    sshGatewayUrl?: string | null\n    proxyApiKeyHash?: string | null\n    sshGatewayApiKeyHash?: string | null\n    snapshotManagerUrl?: string | null\n  }) {\n    this.name = params.name\n    this.enforceQuotas = params.enforceQuotas\n    this.regionType = params.regionType\n\n    if (params.id) {\n      this.id = params.id\n    } else {\n      this.id = this.name.toLowerCase() + '_' + nanoid(4)\n    }\n    if (params.organizationId) {\n      this.organizationId = params.organizationId\n    }\n\n    this.proxyUrl = params.proxyUrl ?? null\n    this.toolboxProxyUrl = params.toolboxProxyUrl ?? params.proxyUrl ?? null\n    this.sshGatewayUrl = params.sshGatewayUrl ?? null\n    this.proxyApiKeyHash = params.proxyApiKeyHash ?? null\n    this.sshGatewayApiKeyHash = params.sshGatewayApiKeyHash ?? null\n    this.snapshotManagerUrl = params.snapshotManagerUrl ?? null\n  }\n\n  @BeforeInsert()\n  @BeforeUpdate()\n  validateRegionType() {\n    if (this.regionType === RegionType.SHARED) {\n      if (this.organizationId) {\n        throw new Error('Shared regions cannot be associated with an organization.')\n      }\n    }\n    if (this.regionType === RegionType.CUSTOM) {\n      if (!this.organizationId) {\n        throw new Error('Custom regions must be associated with an organization.')\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/region/enums/region-type.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum RegionType {\n  /**\n   * Shared by all organizations.\n   */\n  SHARED = 'shared',\n  /**\n   * Dedicated to specific organizations.\n   */\n  DEDICATED = 'dedicated',\n  /**\n   * Created by and owned by a specific organization.\n   */\n  CUSTOM = 'custom',\n}\n"
  },
  {
    "path": "apps/api/src/region/events/region-created.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm'\nimport { Region } from '../entities/region.entity'\n\nexport class RegionCreatedEvent {\n  constructor(\n    public readonly entityManager: EntityManager,\n    public readonly region: Region,\n    public readonly organizationId: string | null,\n    public readonly snapshotManagerUsername?: string,\n    public readonly snapshotManagerPassword?: string,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/region/events/region-deleted.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm'\nimport { Region } from '../entities/region.entity'\n\nexport class RegionDeletedEvent {\n  constructor(\n    public readonly entityManager: EntityManager,\n    public readonly region: Region,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/region/events/region-snapshot-manager-creds.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm'\nimport { Region } from '../entities/region.entity'\n\nexport class RegionSnapshotManagerCredsRegeneratedEvent {\n  constructor(\n    public readonly regionId: string,\n    public readonly snapshotManagerUrl: string,\n    public readonly username: string,\n    public readonly password: string,\n    public readonly entityManager?: EntityManager,\n  ) {}\n}\n\nexport class RegionSnapshotManagerUpdatedEvent {\n  constructor(\n    public readonly region: Region,\n    public readonly organizationId: string,\n    public readonly snapshotManagerUrl: string | null,\n    public readonly prevSnapshotManagerUrl: string | null,\n    public readonly newUsername?: string,\n    public readonly newPassword?: string,\n    public readonly entityManager?: EntityManager,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/region/guards/region-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Injectable,\n  CanActivate,\n  ExecutionContext,\n  NotFoundException,\n  ForbiddenException,\n  Logger,\n} from '@nestjs/common'\nimport { RegionService } from '../services/region.service'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { RegionType } from '../enums/region-type.enum'\n\n@Injectable()\nexport class RegionAccessGuard implements CanActivate {\n  private readonly logger = new Logger(RegionAccessGuard.name)\n\n  constructor(private readonly regionService: RegionService) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    const regionId: string = request.params.regionId || request.params.id\n\n    // TODO: initialize authContext safely\n    const authContext: OrganizationAuthContext = request.user\n\n    try {\n      const region = await this.regionService.findOne(regionId)\n      if (!region) {\n        throw new NotFoundException('Region not found')\n      }\n      if (authContext.role !== SystemRole.ADMIN && region.organizationId !== authContext.organizationId) {\n        throw new ForbiddenException('Request organization ID does not match resource organization ID')\n      }\n      if (authContext.role !== SystemRole.ADMIN && region.regionType !== RegionType.CUSTOM) {\n        throw new ForbiddenException('Region is not a custom region')\n      }\n      return true\n    } catch (error) {\n      if (!(error instanceof NotFoundException)) {\n        this.logger.error(error)\n      }\n      throw new NotFoundException('Region not found')\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/region/region.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { Region } from './entities/region.entity'\nimport { RegionService } from './services/region.service'\nimport { Runner } from '../sandbox/entities/runner.entity'\nimport { RegionController } from './controllers/region.controller'\nimport { Snapshot } from '../sandbox/entities/snapshot.entity'\n\n@Module({\n  imports: [TypeOrmModule.forFeature([Region, Runner, Snapshot])],\n  controllers: [RegionController],\n  providers: [RegionService],\n  exports: [RegionService],\n})\nexport class RegionModule {}\n"
  },
  {
    "path": "apps/api/src/region/services/region.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\nimport {\n  Injectable,\n  Logger,\n  NotFoundException,\n  ConflictException,\n  BadRequestException,\n  HttpException,\n  HttpStatus,\n} from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { DataSource, In, IsNull, Like, Repository } from 'typeorm'\nimport { REGION_NAME_REGEX } from '../constants/region-name-regex.constant'\nimport { CreateRegionInternalDto } from '../dto/create-region-internal.dto'\nimport { Region } from '../entities/region.entity'\nimport { Runner } from '../../sandbox/entities/runner.entity'\nimport { RegionType } from '../enums/region-type.enum'\nimport { CreateRegionResponseDto } from '../dto/create-region.dto'\nimport { generateApiKeyHash, generateApiKeyValue, generateRandomString } from '../../common/utils/api-key'\nimport { RegionDto } from '../dto/region.dto'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { RegionEvents } from '../constants/region-events.constant'\nimport { RegionCreatedEvent } from '../events/region-created.event'\nimport { RegionDeletedEvent } from '../events/region-deleted.event'\nimport { SnapshotManagerCredentialsDto } from '../dto/snapshot-manager-credentials.dto'\nimport {\n  RegionSnapshotManagerCredsRegeneratedEvent,\n  RegionSnapshotManagerUpdatedEvent,\n} from '../events/region-snapshot-manager-creds.event'\nimport { UpdateRegionDto } from '../dto/update-region.dto'\nimport { Snapshot } from '../../sandbox/entities/snapshot.entity'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { toolboxProxyUrlCacheKey } from '../../sandbox/utils/sandbox-lookup-cache.util'\n\n@Injectable()\nexport class RegionService {\n  private readonly logger = new Logger(RegionService.name)\n\n  constructor(\n    @InjectRepository(Region)\n    private readonly regionRepository: Repository<Region>,\n    @InjectRepository(Runner)\n    private readonly runnerRepository: Repository<Runner>,\n    private readonly dataSource: DataSource,\n    private readonly eventEmitter: EventEmitter2,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    @InjectRedis() private readonly redis: Redis,\n  ) {}\n\n  /**\n   * @param createRegionDto - The region details.\n   * @param organizationId - The ID of the organization, or null for regions not associated with an organization.\n   * @throws {BadRequestException} If the region name is invalid.\n   * @throws {ConflictException} If the region with the same ID already exists or region with the same name already exists in the organization.\n   */\n  async create(\n    createRegionDto: CreateRegionInternalDto,\n    organizationId: string | null,\n  ): Promise<CreateRegionResponseDto> {\n    if (!REGION_NAME_REGEX.test(createRegionDto.name)) {\n      throw new BadRequestException('Region name must contain only letters, numbers, underscores, periods, and hyphens')\n    }\n    if (createRegionDto.name.length < 2 || createRegionDto.name.length > 255) {\n      throw new BadRequestException('Region name must be between 3 and 255 characters')\n    }\n\n    if (createRegionDto.id) {\n      const existingRegion = await this.findOne(createRegionDto.id)\n      if (existingRegion) {\n        throw new ConflictException(`Region with id ${createRegionDto.id} already exists`)\n      }\n    }\n\n    try {\n      const proxyApiKey = createRegionDto.proxyUrl ? generateApiKeyValue() : undefined\n      const sshGatewayApiKey = createRegionDto.sshGatewayUrl ? generateApiKeyValue() : undefined\n\n      const snapshotManagerUsername = createRegionDto.snapshotManagerUrl ? 'daytona' : undefined\n      const snapshotManagerPassword = createRegionDto.snapshotManagerUrl ? generateRandomString(16) : undefined\n\n      const region = new Region({\n        name: createRegionDto.name,\n        enforceQuotas: createRegionDto.enforceQuotas,\n        regionType: createRegionDto.regionType,\n        id: createRegionDto.id,\n        organizationId,\n        proxyUrl: createRegionDto.proxyUrl,\n        sshGatewayUrl: createRegionDto.sshGatewayUrl,\n        proxyApiKeyHash: proxyApiKey ? generateApiKeyHash(proxyApiKey) : null,\n        sshGatewayApiKeyHash: sshGatewayApiKey ? generateApiKeyHash(sshGatewayApiKey) : null,\n        snapshotManagerUrl: createRegionDto.snapshotManagerUrl,\n      })\n\n      await this.dataSource.transaction(async (em) => {\n        await em.save(region)\n        await this.eventEmitter.emitAsync(\n          RegionEvents.CREATED,\n          new RegionCreatedEvent(em, region, organizationId, snapshotManagerUsername, snapshotManagerPassword),\n        )\n      })\n\n      return new CreateRegionResponseDto({\n        id: region.id,\n        proxyApiKey,\n        sshGatewayApiKey,\n        snapshotManagerUsername,\n        snapshotManagerPassword,\n      })\n    } catch (error) {\n      if (error.code === '23505') {\n        throw new ConflictException(`Region with name ${createRegionDto.name} already exists`)\n      }\n      throw error\n    }\n  }\n\n  /**\n   * @param id - The ID of the region.\n   * @returns The region if found, or null otherwise.\n   */\n  async findOne(id: string, cache = false): Promise<Region | null> {\n    return await this.regionRepository.findOne({\n      where: {\n        id,\n      },\n      cache: cache\n        ? {\n            id: `region:${id}`,\n            milliseconds: 30000,\n          }\n        : undefined,\n    })\n  }\n\n  /**\n   * @param name - The name of the region.\n   * @param organizationId - The organization ID, or null for regions not associated with an organization.\n   * @returns The region if found, or null otherwise.\n   */\n  async findOneByName(name: string, organizationId: string | null): Promise<Region | null> {\n    return await this.regionRepository.findOne({\n      where: [{ name, organizationId: organizationId ?? IsNull() }],\n    })\n  }\n\n  /**\n   * @param proxyApiKey - The proxy API key.\n   * @returns The region if found, or null otherwise.\n   */\n  async findOneByProxyApiKey(proxyApiKey: string): Promise<Region | null> {\n    return await this.regionRepository.findOne({\n      where: { proxyApiKeyHash: generateApiKeyHash(proxyApiKey) },\n    })\n  }\n\n  /**\n   * @param sshGatewayApiKey - The SSH gateway API key.\n   * @returns The region if found, or null otherwise.\n   */\n  async findOneBySshGatewayApiKey(sshGatewayApiKey: string): Promise<Region | null> {\n    return await this.regionRepository.findOne({\n      where: { sshGatewayApiKeyHash: generateApiKeyHash(sshGatewayApiKey) },\n    })\n  }\n\n  /**\n   * @param regionId - The ID of the region.\n   * @returns The organization ID or null for for regions not associated with an organization if the region is found, or undefined if the region is not found.\n   */\n  async getOrganizationId(regionId: string): Promise<string | null | undefined> {\n    const region = await this.regionRepository.findOne({\n      where: {\n        id: regionId,\n      },\n      select: ['organizationId'],\n      loadEagerRelations: false,\n    })\n\n    if (!region) {\n      return undefined\n    }\n\n    return region.organizationId ?? null\n  }\n\n  /**\n   * @param organizationId - The organization ID of the regions to find.\n   * @param regionType - If provided, only return regions of the specified type.\n   * @returns The regions found ordered by name ascending.\n   */\n  async findAllByOrganization(organizationId: string, regionType?: RegionType): Promise<Region[]> {\n    return this.regionRepository.find({\n      where: {\n        organizationId,\n        ...(regionType ? { regionType } : {}),\n      },\n      order: {\n        name: 'ASC',\n      },\n    })\n  }\n\n  /**\n   * @param type - The type of the regions to find.\n   * @returns The regions found ordered by name ascending.\n   */\n  async findAllByRegionType(regionType: RegionType): Promise<RegionDto[]> {\n    const regions = await this.regionRepository.find({\n      where: {\n        regionType,\n      },\n      order: {\n        name: 'ASC',\n      },\n    })\n\n    return regions.map(RegionDto.fromRegion)\n  }\n\n  /**\n   * @param ids - The IDs of the regions to find.\n   * @returns The regions found.\n   */\n  async findByIds(ids: string[]): Promise<Region[]> {\n    if (ids.length === 0) {\n      return []\n    }\n\n    return this.regionRepository.find({\n      where: {\n        id: In(ids),\n      },\n    })\n  }\n\n  /**\n   * @param id - The ID of the region to delete.\n   * @throws {NotFoundException} If the region is not found.\n   */\n  async delete(id: string): Promise<void> {\n    const region = await this.findOne(id)\n\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n\n    const runnerCount = await this.runnerRepository.count({\n      where: {\n        region: id,\n      },\n    })\n\n    if (runnerCount > 0) {\n      throw new HttpException(\n        'Cannot delete region which has runners associated with it',\n        HttpStatus.PRECONDITION_REQUIRED,\n      )\n    }\n\n    await this.dataSource.transaction(async (em) => {\n      await this.eventEmitter.emitAsync(RegionEvents.DELETED, new RegionDeletedEvent(em, region))\n      await em.remove(region)\n    })\n\n    this.redis.del(toolboxProxyUrlCacheKey(id)).catch((err) => {\n      this.logger.warn(`Failed to invalidate toolbox proxy URL cache for region ${id}: ${err.message}`)\n    })\n  }\n\n  async update(regionId: string, updateRegion: UpdateRegionDto): Promise<void> {\n    const region = await this.findOne(regionId)\n\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n\n    await this.dataSource.transaction(async (em) => {\n      if (updateRegion.proxyUrl !== undefined) {\n        region.proxyUrl = updateRegion.proxyUrl ?? null\n        region.toolboxProxyUrl = updateRegion.proxyUrl ?? null\n      }\n\n      if (updateRegion.sshGatewayUrl !== undefined) {\n        region.sshGatewayUrl = updateRegion.sshGatewayUrl ?? null\n      }\n\n      if (updateRegion.snapshotManagerUrl !== undefined) {\n        if (region.snapshotManagerUrl) {\n          // If snapshots already exist, prevent changing the snapshot manager URL\n          const exists = await this.snapshotRepository.exists({\n            where: {\n              ref: Like(`${region.snapshotManagerUrl.replace(/^https?:\\/\\//, '')}%`),\n            },\n          })\n          if (exists) {\n            throw new BadRequestException(\n              'Cannot change snapshot manager URL for region with existing snapshots. Please delete existing snapshots first.',\n            )\n          }\n        }\n\n        const prevSnapshotManagerUrl = region.snapshotManagerUrl\n        region.snapshotManagerUrl = updateRegion.snapshotManagerUrl ?? null\n\n        let newUsername: string | undefined = undefined\n        let newPassword: string | undefined = undefined\n\n        // If the region did not have a snapshot manager, create new credentials\n        if (!prevSnapshotManagerUrl) {\n          newUsername = 'daytona'\n          newPassword = generateRandomString(16)\n        }\n\n        await this.eventEmitter.emitAsync(\n          RegionEvents.SNAPSHOT_MANAGER_UPDATED,\n          new RegionSnapshotManagerUpdatedEvent(\n            region,\n            region.organizationId,\n            region.snapshotManagerUrl,\n            prevSnapshotManagerUrl,\n            newUsername,\n            newPassword,\n            em,\n          ),\n        )\n      }\n\n      await em.save(region)\n    })\n\n    if (updateRegion.proxyUrl !== undefined) {\n      this.redis.del(toolboxProxyUrlCacheKey(regionId)).catch((err) => {\n        this.logger.warn(`Failed to invalidate toolbox proxy URL cache for region ${regionId}: ${err.message}`)\n      })\n    }\n  }\n\n  /**\n   * @param regionId - The ID of the region.\n   * @throws {NotFoundException} If the region is not found.\n   * @throws {BadRequestException} If the region does not have a proxy URL configured.\n   * @returns The newly generated proxy API key.\n   */\n  async regenerateProxyApiKey(regionId: string): Promise<string> {\n    const region = await this.findOne(regionId)\n\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n\n    if (!region.proxyUrl) {\n      throw new BadRequestException('Region does not have a proxy URL configured')\n    }\n\n    const newApiKey = generateApiKeyValue()\n    region.proxyApiKeyHash = generateApiKeyHash(newApiKey)\n\n    await this.regionRepository.save(region)\n\n    return newApiKey\n  }\n\n  /**\n   * @param regionId - The ID of the region.\n   * @throws {NotFoundException} If the region is not found.\n   * @throws {BadRequestException} If the region does not have an SSH gateway URL configured.\n   * @returns The newly generated SSH gateway API key.\n   */\n  async regenerateSshGatewayApiKey(regionId: string): Promise<string> {\n    const region = await this.findOne(regionId)\n\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n\n    if (!region.sshGatewayUrl) {\n      throw new BadRequestException('Region does not have an SSH gateway URL configured')\n    }\n\n    const newApiKey = generateApiKeyValue()\n    region.sshGatewayApiKeyHash = generateApiKeyHash(newApiKey)\n\n    await this.regionRepository.save(region)\n\n    return newApiKey\n  }\n\n  /**\n   * @param regionId - The ID of the region.\n   * @throws {NotFoundException} If the region is not found.\n   * @throws {BadRequestException} If the region does not have a snapshot manager URL configured.\n   * @returns The newly generated snapshot manager credentials.\n   */\n  async regenerateSnapshotManagerCredentials(regionId: string): Promise<SnapshotManagerCredentialsDto> {\n    const region = await this.findOne(regionId)\n\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n\n    if (!region.snapshotManagerUrl) {\n      throw new BadRequestException('Region does not have a snapshot manager URL configured')\n    }\n\n    const newUsername = 'daytona'\n    const newPassword = generateRandomString(16)\n\n    await this.eventEmitter.emitAsync(\n      RegionEvents.SNAPSHOT_MANAGER_CREDENTIALS_REGENERATED,\n      new RegionSnapshotManagerCredsRegeneratedEvent(regionId, region.snapshotManagerUrl, newUsername, newPassword),\n    )\n\n    return new SnapshotManagerCredentialsDto({\n      username: newUsername,\n      password: newPassword,\n    })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/common/redis-lock.provider.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Injectable } from '@nestjs/common'\nimport { Redis } from 'ioredis'\n\ntype Acquired = boolean\n\nexport class LockCode {\n  constructor(private readonly code: string) {}\n\n  public getCode(): string {\n    return this.code\n  }\n}\n\n@Injectable()\nexport class RedisLockProvider {\n  constructor(@InjectRedis() private readonly redis: Redis) {}\n\n  async lock(key: string, ttl: number, code?: LockCode | null): Promise<Acquired> {\n    const keyValue = code ? code.getCode() : '1'\n    const acquired = await this.redis.set(key, keyValue, 'EX', ttl, 'NX')\n    return !!acquired\n  }\n\n  async getCode(key: string): Promise<LockCode | null> {\n    const keyValue = await this.redis.get(key)\n    return keyValue ? new LockCode(keyValue) : null\n  }\n\n  async unlock(key: string): Promise<void> {\n    await this.redis.del(key)\n  }\n\n  async isLocked(key: string): Promise<boolean> {\n    const exists = await this.redis.exists(key)\n    return exists === 1\n  }\n\n  async waitForLock(key: string, ttl: number): Promise<void> {\n    while (true) {\n      const acquired = await this.lock(key, ttl)\n      if (acquired) break\n      await new Promise((resolve) => setTimeout(resolve, 50))\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/common/runner-service-info.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type RunnerServiceInfo = {\n  serviceName: string\n  healthy: boolean\n  errorReason?: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/constants/errors-for-recovery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n// Substrings in an error message that should trigger an automatic restore\nexport const RECOVERY_ERROR_SUBSTRINGS: string[] = ['Can not connect to the Docker daemon']\n"
  },
  {
    "path": "apps/api/src/sandbox/constants/runner-events.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const RunnerEvents = {\n  CREATED: 'runner.created',\n  STATE_UPDATED: 'runner.state.updated',\n  UNSCHEDULABLE_UPDATED: 'runner.unschedulable.updated',\n  DELETED: 'runner.deleted',\n} as const\n"
  },
  {
    "path": "apps/api/src/sandbox/constants/runner-name-regex.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const RUNNER_NAME_REGEX = /^[a-zA-Z0-9_.-]+$/\n"
  },
  {
    "path": "apps/api/src/sandbox/constants/sandbox-events.constants.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const SandboxEvents = {\n  ARCHIVED: 'sandbox.archived',\n  STATE_UPDATED: 'sandbox.state.updated',\n  DESIRED_STATE_UPDATED: 'sandbox.desired-state.updated',\n  CREATED: 'sandbox.created',\n  STARTED: 'sandbox.started',\n  STOPPED: 'sandbox.stopped',\n  DESTROYED: 'sandbox.destroyed',\n  PUBLIC_STATUS_UPDATED: 'sandbox.public-status.updated',\n  ORGANIZATION_UPDATED: 'sandbox.organization.updated',\n  BACKUP_CREATED: 'sandbox.backup.created',\n} as const\n"
  },
  {
    "path": "apps/api/src/sandbox/constants/sandbox.constants.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION = '00000000-0000-0000-0000-000000000000'\n"
  },
  {
    "path": "apps/api/src/sandbox/constants/snapshot-events.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const SnapshotEvents = {\n  CREATED: 'snapshot.created',\n  ACTIVATED: 'snapshot.activated',\n  STATE_UPDATED: 'snapshot.state.updated',\n  REMOVED: 'snapshot.removed',\n} as const\n"
  },
  {
    "path": "apps/api/src/sandbox/constants/volume-events.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const VolumeEvents = {\n  CREATED: 'volume.created',\n  STATE_UPDATED: 'volume.state.updated',\n  LAST_USED_AT_UPDATED: 'volume.lastUsedAt.updated',\n} as const\n"
  },
  {
    "path": "apps/api/src/sandbox/constants/warmpool-events.constants.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const WarmPoolEvents = {\n  TOPUP_REQUESTED: 'warmpool.topup-requested',\n} as const\n"
  },
  {
    "path": "apps/api/src/sandbox/controllers/job.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Get, Post, Body, Param, Query, UseGuards, Logger, Req, NotFoundException } from '@nestjs/common'\nimport { Request } from 'express'\nimport { ApiOAuth2, ApiTags, ApiOperation, ApiBearerAuth, ApiResponse, ApiParam, ApiQuery } from '@nestjs/swagger'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { RunnerAuthGuard } from '../../auth/runner-auth.guard'\nimport { RunnerContextDecorator } from '../../common/decorators/runner-context.decorator'\nimport { RunnerContext } from '../../common/interfaces/runner-context.interface'\nimport {\n  JobDto,\n  JobStatus,\n  ListJobsQueryDto,\n  PaginatedJobsDto,\n  PollJobsResponseDto,\n  UpdateJobStatusDto,\n} from '../dto/job.dto'\nimport { JobService } from '../services/job.service'\nimport { JobAccessGuard } from '../guards/job-access.guard'\n\n@ApiTags('jobs')\n@Controller('jobs')\n@UseGuards(CombinedAuthGuard, RunnerAuthGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class JobController {\n  private readonly logger = new Logger(JobController.name)\n\n  constructor(private readonly jobService: JobService) {}\n\n  @Get()\n  @ApiOperation({\n    summary: 'List jobs for the runner',\n    operationId: 'listJobs',\n    description: 'Returns a paginated list of jobs for the runner, optionally filtered by status.',\n  })\n  @ApiQuery({\n    name: 'status',\n    required: false,\n    enum: JobStatus,\n    enumName: 'JobStatus',\n    example: JobStatus.PENDING,\n    description: 'Filter jobs by status',\n  })\n  @ApiQuery({\n    name: 'limit',\n    required: false,\n    type: Number,\n    description: 'Maximum number of jobs to return (default: 100, max: 500)',\n  })\n  @ApiQuery({\n    name: 'offset',\n    required: false,\n    type: Number,\n    description: 'Number of jobs to skip for pagination (default: 0)',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of jobs for the runner',\n    type: PaginatedJobsDto,\n  })\n  async listJobs(\n    @RunnerContextDecorator() runnerContext: RunnerContext,\n    @Query() query: ListJobsQueryDto,\n  ): Promise<PaginatedJobsDto> {\n    return await this.jobService.findJobsForRunner(runnerContext.runnerId, query.status, query.page, query.limit)\n  }\n\n  @Get('poll')\n  @ApiOperation({\n    summary: 'Long poll for jobs',\n    operationId: 'pollJobs',\n    description:\n      'Long poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.',\n  })\n  @ApiQuery({\n    name: 'timeout',\n    required: false,\n    type: Number,\n    description: 'Timeout in seconds for long polling (default: 30, max: 60)',\n  })\n  @ApiQuery({\n    name: 'limit',\n    required: false,\n    type: Number,\n    description: 'Maximum number of jobs to return (default: 10, max: 100)',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of jobs for the runner',\n    type: PollJobsResponseDto,\n  })\n  async pollJobs(\n    @Req() req: Request,\n    @RunnerContextDecorator() runnerContext: RunnerContext,\n    @Query('timeout') timeout?: number,\n    @Query('limit') limit?: number,\n  ): Promise<PollJobsResponseDto> {\n    this.logger.debug(`Runner ${runnerContext.runnerId} polling for jobs (timeout: ${timeout}s, limit: ${limit})`)\n\n    const timeoutSeconds = timeout ? Math.min(Number(timeout), 60) : 30\n    const limitNumber = limit ? Math.min(Number(limit), 100) : 10\n\n    // Create AbortSignal from request's 'close' event\n    const abortController = new AbortController()\n    const onClose = () => {\n      this.logger.debug(`Runner ${runnerContext.runnerId} disconnected during polling, aborting`)\n      abortController.abort()\n    }\n    req.on('close', onClose)\n\n    try {\n      const jobs = await this.jobService.pollJobs(\n        runnerContext.runnerId,\n        limitNumber,\n        timeoutSeconds,\n        abortController.signal,\n      )\n      this.logger.debug(`Returning ${jobs.length} jobs to runner ${runnerContext.runnerId}`)\n      return { jobs }\n    } catch (error) {\n      if (abortController.signal.aborted) {\n        this.logger.debug(`Polling aborted for disconnected runner ${runnerContext.runnerId}`)\n        return { jobs: [] } // Return empty array on disconnect\n      }\n      this.logger.error(`Error polling jobs for runner ${runnerContext.runnerId}: ${error.message}`, error.stack)\n      throw error\n    } finally {\n      req.off('close', onClose)\n    }\n  }\n\n  @Get(':jobId')\n  @ApiOperation({\n    summary: 'Get job details',\n    operationId: 'getJob',\n  })\n  @ApiParam({\n    name: 'jobId',\n    description: 'ID of the job',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Job details',\n    type: JobDto,\n  })\n  @UseGuards(JobAccessGuard)\n  async getJob(@RunnerContextDecorator() runnerContext: RunnerContext, @Param('jobId') jobId: string): Promise<JobDto> {\n    this.logger.log(`Runner ${runnerContext.runnerId} fetching job ${jobId}`)\n\n    const job = await this.jobService.findOne(jobId)\n    if (!job) {\n      throw new NotFoundException(`Job ${jobId} not found`)\n    }\n\n    return new JobDto(job)\n  }\n\n  @Post(':jobId/status')\n  @ApiOperation({\n    summary: 'Update job status',\n    operationId: 'updateJobStatus',\n  })\n  @ApiParam({\n    name: 'jobId',\n    description: 'ID of the job',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Job status updated successfully',\n    type: JobDto,\n  })\n  @UseGuards(JobAccessGuard)\n  async updateJobStatus(\n    @RunnerContextDecorator() runnerContext: RunnerContext,\n    @Param('jobId') jobId: string,\n    @Body() updateJobStatusDto: UpdateJobStatusDto,\n  ): Promise<JobDto> {\n    this.logger.debug(`Runner ${runnerContext.runnerId} updating job ${jobId} status to ${updateJobStatusDto.status}`)\n\n    const job = await this.jobService.updateJobStatus(\n      jobId,\n      updateJobStatusDto.status,\n      updateJobStatusDto.errorMessage,\n      updateJobStatusDto.resultMetadata,\n    )\n\n    return new JobDto(job)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/controllers/preview.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport Redis from 'ioredis'\nimport { Controller, Get, Param, Logger, NotFoundException, UseGuards, Req } from '@nestjs/common'\nimport { SandboxService } from '../services/sandbox.service'\nimport { ApiResponse, ApiOperation, ApiParam, ApiTags, ApiOAuth2, ApiBearerAuth } from '@nestjs/swagger'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { OrganizationUserService } from '../../organization/services/organization-user.service'\n\n@ApiTags('preview')\n@Controller('preview')\nexport class PreviewController {\n  private readonly logger = new Logger(PreviewController.name)\n\n  constructor(\n    @InjectRedis() private readonly redis: Redis,\n    private readonly sandboxService: SandboxService,\n    private readonly organizationUserService: OrganizationUserService,\n  ) {}\n\n  @Get(':sandboxId/public')\n  @ApiOperation({\n    summary: 'Check if sandbox is public',\n    operationId: 'isSandboxPublic',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Public status of the sandbox',\n    type: Boolean,\n  })\n  async isSandboxPublic(@Param('sandboxId') sandboxId: string): Promise<boolean> {\n    const cached = await this.redis.get(`preview:public:${sandboxId}`)\n    if (cached) {\n      if (cached === '1') {\n        return true\n      }\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n\n    try {\n      const isPublic = await this.sandboxService.isSandboxPublic(sandboxId)\n      //  for private sandboxes, throw 404 as well\n      //  to prevent using the method to check if a sandbox exists\n      if (!isPublic) {\n        //  cache the result for 3 seconds to avoid unnecessary requests to the database\n        await this.redis.setex(`preview:public:${sandboxId}`, 3, '0')\n\n        throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n      }\n      //  cache the result for 3 seconds to avoid unnecessary requests to the database\n      await this.redis.setex(`preview:public:${sandboxId}`, 3, '1')\n      return true\n    } catch (ex) {\n      if (ex instanceof NotFoundException) {\n        //  cache the not found sandbox as well\n        //  as it is the same case as for the private sandboxes\n        await this.redis.setex(`preview:public:${sandboxId}`, 3, '0')\n        throw ex\n      }\n      throw ex\n    }\n  }\n\n  @Get(':sandboxId/validate/:authToken')\n  @ApiOperation({\n    summary: 'Check if sandbox auth token is valid',\n    operationId: 'isValidAuthToken',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'authToken',\n    description: 'Auth token of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox auth token validation status',\n    type: Boolean,\n  })\n  async isValidAuthToken(\n    @Param('sandboxId') sandboxId: string,\n    @Param('authToken') authToken: string,\n  ): Promise<boolean> {\n    const cached = await this.redis.get(`preview:token:${sandboxId}:${authToken}`)\n    if (cached) {\n      if (cached === '1') {\n        return true\n      }\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n    const sandbox = await this.sandboxService.findOne(sandboxId)\n    if (!sandbox) {\n      await this.redis.setex(`preview:token:${sandboxId}:${authToken}`, 3, '0')\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n    if (sandbox.authToken === authToken) {\n      await this.redis.setex(`preview:token:${sandboxId}:${authToken}`, 3, '1')\n      return true\n    }\n    await this.redis.setex(`preview:token:${sandboxId}:${authToken}`, 3, '0')\n    throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n  }\n\n  @Get(':sandboxId/access')\n  @ApiOperation({\n    summary: 'Check if user has access to the sandbox',\n    operationId: 'hasSandboxAccess',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'User access status to the sandbox',\n    type: Boolean,\n  })\n  @UseGuards(CombinedAuthGuard)\n  @ApiOAuth2(['openid', 'profile', 'email'])\n  @ApiBearerAuth()\n  async hasSandboxAccess(@Req() req: Request, @Param('sandboxId') sandboxId: string): Promise<boolean> {\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    const userId = req.user?.userId\n\n    const cached = await this.redis.get(`preview:access:${sandboxId}:${userId}`)\n    if (cached) {\n      if (cached === '1') {\n        return true\n      }\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n\n    const sandbox = await this.sandboxService.findOne(sandboxId)\n    const hasAccess = await this.organizationUserService.exists(sandbox.organizationId, userId)\n    if (!hasAccess) {\n      await this.redis.setex(`preview:token:${sandboxId}:${userId}`, 3, '0')\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n    //  if user has access, keep it in cache longer\n    await this.redis.setex(`preview:access:${sandboxId}:${userId}`, 30, '1')\n    return true\n  }\n\n  @Get(':signedPreviewToken/:port/sandbox-id')\n  @ApiOperation({\n    summary: 'Get sandbox ID from signed preview URL token',\n    operationId: 'getSandboxIdFromSignedPreviewUrlToken',\n  })\n  @ApiParam({\n    name: 'signedPreviewToken',\n    description: 'Signed preview URL token',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'port',\n    description: 'Port number to get sandbox ID from signed preview URL token',\n    type: 'number',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox ID from signed preview URL token',\n    type: String,\n  })\n  async getSandboxIdFromSignedPreviewUrlToken(\n    @Param('signedPreviewToken') signedPreviewToken: string,\n    @Param('port') port: number,\n  ): Promise<string> {\n    return this.sandboxService.getSandboxIdFromSignedPreviewUrlToken(signedPreviewToken, port)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/controllers/runner.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Body,\n  Controller,\n  Get,\n  Post,\n  Param,\n  Patch,\n  UseGuards,\n  Query,\n  Delete,\n  HttpCode,\n  NotFoundException,\n  ForbiddenException,\n  ParseUUIDPipe,\n} from '@nestjs/common'\nimport { CreateRunnerDto } from '../dto/create-runner.dto'\nimport { RunnerService } from '../services/runner.service'\nimport {\n  ApiOAuth2,\n  ApiTags,\n  ApiOperation,\n  ApiBearerAuth,\n  ApiResponse,\n  ApiQuery,\n  ApiParam,\n  ApiHeader,\n} from '@nestjs/swagger'\nimport { SystemActionGuard } from '../../auth/system-action.guard'\nimport { RequiredApiRole } from '../../common/decorators/required-role.decorator'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { ProxyGuard } from '../guards/proxy.guard'\nimport { RunnerDto } from '../dto/runner.dto'\nimport { RunnerSnapshotDto } from '../dto/runner-snapshot.dto'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { SshGatewayGuard } from '../guards/ssh-gateway.guard'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { OrGuard } from '../../auth/or.guard'\nimport { RunnerAuthGuard } from '../../auth/runner-auth.guard'\nimport { RunnerContextDecorator } from '../../common/decorators/runner-context.decorator'\nimport { RunnerContext } from '../../common/interfaces/runner-context.interface'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\nimport { RunnerAccessGuard } from '../guards/runner-access.guard'\nimport { RegionRunnerAccessGuard } from '../guards/region-runner-access.guard'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { RequiredOrganizationResourcePermissions } from '../../organization/decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { CreateRunnerResponseDto } from '../dto/create-runner-response.dto'\nimport { RegionSandboxAccessGuard } from '../guards/region-sandbox-access.guard'\nimport { RunnerFullDto } from '../dto/runner-full.dto'\nimport { RegionType } from '../../region/enums/region-type.enum'\nimport { RegionService } from '../../region/services/region.service'\nimport { RequireFlagsEnabled } from '@openfeature/nestjs-sdk'\nimport { FeatureFlags } from '../../common/constants/feature-flags'\nimport { RunnerHealthcheckDto } from '../dto/runner-health.dto'\n\n@ApiTags('runners')\n@Controller('runners')\n@UseGuards(CombinedAuthGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class RunnerController {\n  constructor(\n    private readonly runnerService: RunnerService,\n    private readonly regionService: RegionService,\n  ) {}\n\n  @Post()\n  @HttpCode(201)\n  @ApiOperation({\n    summary: 'Create runner',\n    operationId: 'createRunner',\n  })\n  @ApiResponse({\n    status: 201,\n    type: CreateRunnerResponseDto,\n  })\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.RUNNER,\n    targetIdFromResult: (result: CreateRunnerResponseDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateRunnerDto>) => ({\n        regionId: req.body?.regionId,\n        name: req.body?.name,\n      }),\n    },\n  })\n  @ApiHeader(CustomHeaders.ORGANIZATION_ID)\n  @UseGuards(OrganizationResourceActionGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_RUNNERS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async create(\n    @Body() createRunnerDto: CreateRunnerDto,\n    @AuthContext() authContext: OrganizationAuthContext,\n  ): Promise<CreateRunnerResponseDto> {\n    // validate that the runner region is a custom region owned by the organization\n    const region = await this.regionService.findOne(createRunnerDto.regionId)\n\n    if (!region || region.organizationId !== authContext.organizationId) {\n      throw new NotFoundException('Region not found')\n    }\n\n    if (region.regionType !== RegionType.CUSTOM) {\n      throw new ForbiddenException('Runner can only be created in a custom region')\n    }\n\n    // create the runner\n    const { runner, apiKey } = await this.runnerService.create({\n      regionId: createRunnerDto.regionId,\n      name: createRunnerDto.name,\n      apiVersion: '2',\n    })\n\n    return CreateRunnerResponseDto.fromRunner(runner, apiKey)\n  }\n\n  @Get('/me')\n  @UseGuards(RunnerAuthGuard)\n  @ApiOperation({\n    summary: 'Get info for authenticated runner',\n    operationId: 'getInfoForAuthenticatedRunner',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Runner info',\n    type: RunnerFullDto,\n  })\n  async getInfoForAuthenticatedRunner(@RunnerContextDecorator() runnerContext: RunnerContext): Promise<RunnerFullDto> {\n    return this.runnerService.findOneFullOrFail(runnerContext.runnerId)\n  }\n\n  @Get(':id')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Get runner by ID',\n    operationId: 'getRunnerById',\n  })\n  @ApiResponse({\n    status: 200,\n    type: RunnerDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Runner ID',\n    type: String,\n  })\n  @ApiHeader(CustomHeaders.ORGANIZATION_ID)\n  @UseGuards(OrganizationResourceActionGuard, RunnerAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.READ_RUNNERS])\n  async getRunnerById(@Param('id', ParseUUIDPipe) id: string): Promise<RunnerDto> {\n    const runner = await this.runnerService.findOneOrFail(id)\n    return RunnerDto.fromRunner(runner)\n  }\n\n  @Get(':id/full')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Get runner by ID',\n    operationId: 'getRunnerFullById',\n  })\n  @ApiResponse({\n    status: 200,\n    type: RunnerFullDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Runner ID',\n    type: String,\n  })\n  @UseGuards(OrGuard([SystemActionGuard, ProxyGuard, SshGatewayGuard, RegionRunnerAccessGuard]))\n  @RequiredApiRole([SystemRole.ADMIN])\n  async getRunnerByIdFull(@Param('id', ParseUUIDPipe) id: string): Promise<RunnerFullDto> {\n    const runner = await this.runnerService.findOneOrFail(id)\n    return RunnerFullDto.fromRunner(runner)\n  }\n\n  @Get()\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'List all runners',\n    operationId: 'listRunners',\n  })\n  @ApiResponse({\n    status: 200,\n    type: [RunnerDto],\n  })\n  @ApiHeader(CustomHeaders.ORGANIZATION_ID)\n  @UseGuards(OrganizationResourceActionGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.READ_RUNNERS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async findAll(@AuthContext() authContext: OrganizationAuthContext): Promise<RunnerDto[]> {\n    return this.runnerService.findAllByOrganization(authContext.organizationId, RegionType.CUSTOM)\n  }\n\n  @Patch(':id/scheduling')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Update runner scheduling status',\n    operationId: 'updateRunnerScheduling',\n  })\n  @ApiResponse({\n    status: 200,\n    type: RunnerDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Runner ID',\n    type: String,\n  })\n  @Audit({\n    action: AuditAction.UPDATE_SCHEDULING,\n    targetType: AuditTarget.RUNNER,\n    targetIdFromRequest: (req) => req.params.id,\n    requestMetadata: {\n      body: (req: TypedRequest<{ unschedulable: boolean }>) => ({\n        unschedulable: req.body?.unschedulable,\n      }),\n    },\n  })\n  @ApiHeader(CustomHeaders.ORGANIZATION_ID)\n  @UseGuards(OrganizationResourceActionGuard, RunnerAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_RUNNERS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async updateSchedulingStatus(\n    @Param('id', ParseUUIDPipe) id: string,\n    @Body('unschedulable') unschedulable: boolean,\n  ): Promise<RunnerDto> {\n    const updatedRunner = await this.runnerService.updateSchedulingStatus(id, unschedulable)\n    return RunnerDto.fromRunner(updatedRunner)\n  }\n\n  @Patch(':id/draining')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Update runner draining status',\n    operationId: 'updateRunnerDraining',\n  })\n  @ApiResponse({\n    status: 200,\n    type: RunnerDto,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Runner ID',\n    type: String,\n  })\n  @Audit({\n    action: AuditAction.UPDATE_DRAINING,\n    targetType: AuditTarget.RUNNER,\n    targetIdFromRequest: (req) => req.params.id,\n    requestMetadata: {\n      body: (req: TypedRequest<{ draining: boolean }>) => ({\n        draining: req.body?.draining,\n      }),\n    },\n  })\n  @ApiHeader(CustomHeaders.ORGANIZATION_ID)\n  @UseGuards(OrganizationResourceActionGuard, RunnerAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_RUNNERS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async updateDrainingStatus(\n    @Param('id', ParseUUIDPipe) id: string,\n    @Body('draining') draining: boolean,\n  ): Promise<RunnerDto> {\n    const updatedRunner = await this.runnerService.updateDrainingStatus(id, draining)\n    return RunnerDto.fromRunner(updatedRunner)\n  }\n\n  @Delete(':id')\n  @HttpCode(204)\n  @ApiOperation({\n    summary: 'Delete runner',\n    operationId: 'deleteRunner',\n  })\n  @ApiResponse({\n    status: 204,\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Runner ID',\n    type: String,\n  })\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.RUNNER,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  @ApiHeader(CustomHeaders.ORGANIZATION_ID)\n  @UseGuards(OrganizationResourceActionGuard, RunnerAccessGuard)\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.DELETE_RUNNERS])\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.ORGANIZATION_INFRASTRUCTURE, defaultValue: false }] })\n  async delete(@Param('id', ParseUUIDPipe) id: string): Promise<void> {\n    return this.runnerService.remove(id)\n  }\n\n  @Get('/by-sandbox/:sandboxId')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Get runner by sandbox ID',\n    operationId: 'getRunnerBySandboxId',\n  })\n  @ApiResponse({\n    status: 200,\n    type: RunnerFullDto,\n  })\n  @UseGuards(OrGuard([SystemActionGuard, ProxyGuard, SshGatewayGuard, RegionSandboxAccessGuard]))\n  @RequiredApiRole([SystemRole.ADMIN])\n  async getRunnerBySandboxId(@Param('sandboxId') sandboxId: string): Promise<RunnerFullDto> {\n    const runner = await this.runnerService.findBySandboxId(sandboxId)\n\n    if (!runner) {\n      throw new NotFoundException('Runner not found')\n    }\n\n    return RunnerFullDto.fromRunner(runner)\n  }\n\n  @Get('/by-snapshot-ref')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Get runners by snapshot ref',\n    operationId: 'getRunnersBySnapshotRef',\n  })\n  @ApiResponse({\n    status: 200,\n    type: [RunnerSnapshotDto],\n  })\n  @ApiQuery({\n    name: 'ref',\n    description: 'Snapshot ref',\n    type: String,\n    required: true,\n  })\n  @UseGuards(OrGuard([SystemActionGuard, ProxyGuard, SshGatewayGuard]))\n  @RequiredApiRole([SystemRole.ADMIN, 'proxy', 'ssh-gateway'])\n  async getRunnersBySnapshotRef(@Query('ref') ref: string): Promise<RunnerSnapshotDto[]> {\n    return this.runnerService.getRunnersBySnapshotRef(ref)\n  }\n\n  @Post('healthcheck')\n  @ApiOperation({\n    summary: 'Runner healthcheck',\n    operationId: 'runnerHealthcheck',\n    description:\n      'Endpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Healthcheck received',\n  })\n  async runnerHealthcheck(\n    @RunnerContextDecorator() runnerContext: RunnerContext,\n    @Body() healthcheck: RunnerHealthcheckDto,\n  ): Promise<void> {\n    await this.runnerService.updateRunnerHealth(\n      runnerContext.runnerId,\n      healthcheck.domain,\n      healthcheck.apiUrl,\n      healthcheck.proxyUrl,\n      healthcheck.serviceHealth,\n      healthcheck.metrics,\n      healthcheck.appVersion,\n    )\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/controllers/sandbox.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Controller,\n  Get,\n  Post,\n  Delete,\n  Body,\n  Param,\n  Query,\n  Logger,\n  UseGuards,\n  HttpCode,\n  UseInterceptors,\n  Put,\n  NotFoundException,\n  Res,\n  Request,\n  RawBodyRequest,\n  Next,\n  ParseBoolPipe,\n} from '@nestjs/common'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { SandboxService } from '../services/sandbox.service'\nimport { CreateSandboxDto } from '../dto/create-sandbox.dto'\nimport {\n  ApiOAuth2,\n  ApiResponse,\n  ApiQuery,\n  ApiOperation,\n  ApiParam,\n  ApiTags,\n  ApiHeader,\n  ApiBearerAuth,\n} from '@nestjs/swagger'\nimport { SandboxDto, SandboxLabelsDto } from '../dto/sandbox.dto'\nimport { ResizeSandboxDto } from '../dto/resize-sandbox.dto'\nimport { UpdateSandboxStateDto } from '../dto/update-sandbox-state.dto'\nimport { PaginatedSandboxesDto } from '../dto/paginated-sandboxes.dto'\nimport { RunnerService } from '../services/runner.service'\nimport { RunnerAuthGuard } from '../../auth/runner-auth.guard'\nimport { RunnerContextDecorator } from '../../common/decorators/runner-context.decorator'\nimport { RunnerContext } from '../../common/interfaces/runner-context.interface'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { ContentTypeInterceptor } from '../../common/interceptors/content-type.interceptors'\nimport { SandboxAccessGuard } from '../guards/sandbox-access.guard'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { RequiredOrganizationResourcePermissions } from '../../organization/decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { PortPreviewUrlDto, SignedPortPreviewUrlDto } from '../dto/port-preview-url.dto'\nimport { IncomingMessage, ServerResponse } from 'http'\nimport { NextFunction } from 'http-proxy-middleware/dist/types'\nimport { LogProxy } from '../proxy/log-proxy'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { SandboxStateUpdatedEvent } from '../events/sandbox-state-updated.event'\nimport { Audit, MASKED_AUDIT_VALUE, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\n// import { UpdateSandboxNetworkSettingsDto } from '../dto/update-sandbox-network-settings.dto'\nimport { SshAccessDto, SshAccessValidationDto } from '../dto/ssh-access.dto'\nimport { ListSandboxesQueryDto } from '../dto/list-sandboxes-query.dto'\nimport { ProxyGuard } from '../guards/proxy.guard'\nimport { OrGuard } from '../../auth/or.guard'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\nimport { SkipThrottle } from '@nestjs/throttler'\nimport { ThrottlerScope } from '../../common/decorators/throttler-scope.decorator'\nimport { SshGatewayGuard } from '../guards/ssh-gateway.guard'\nimport { ToolboxProxyUrlDto } from '../dto/toolbox-proxy-url.dto'\nimport { UrlDto } from '../../common/dto/url.dto'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { SANDBOX_EVENT_CHANNEL } from '../../common/constants/constants'\nimport { RequireFlagsEnabled } from '@openfeature/nestjs-sdk'\nimport { FeatureFlags } from '../../common/constants/feature-flags'\n\n@ApiTags('sandbox')\n@Controller('sandbox')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class SandboxController {\n  private readonly logger = new Logger(SandboxController.name)\n  private readonly sandboxCallbacks: Map<string, (event: SandboxStateUpdatedEvent) => void> = new Map()\n  private readonly redisSubscriber: Redis\n  constructor(\n    private readonly runnerService: RunnerService,\n    private readonly sandboxService: SandboxService,\n    @InjectRedis() private readonly redis: Redis,\n  ) {\n    this.redisSubscriber = this.redis.duplicate()\n    this.redisSubscriber.subscribe(SANDBOX_EVENT_CHANNEL)\n    this.redisSubscriber.on('message', (channel, message) => {\n      if (channel !== SANDBOX_EVENT_CHANNEL) {\n        return\n      }\n\n      try {\n        const event = JSON.parse(message) as SandboxStateUpdatedEvent\n        this.handleSandboxStateUpdated(event)\n      } catch (error) {\n        this.logger.error('Failed to parse sandbox state updated event:', error)\n        return\n      }\n    })\n  }\n\n  @Get()\n  @ApiOperation({\n    summary: 'List all sandboxes',\n    operationId: 'listSandboxes',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of all sandboxes',\n    type: [SandboxDto],\n  })\n  @ApiQuery({\n    name: 'verbose',\n    required: false,\n    type: Boolean,\n    description: 'Include verbose output',\n  })\n  @ApiQuery({\n    name: 'labels',\n    type: String,\n    required: false,\n    example: '{\"label1\": \"value1\", \"label2\": \"value2\"}',\n    description: 'JSON encoded labels to filter by',\n  })\n  @ApiQuery({\n    name: 'includeErroredDeleted',\n    required: false,\n    type: Boolean,\n    description: 'Include errored and deleted sandboxes',\n  })\n  async listSandboxes(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Query('verbose') verbose?: boolean,\n    @Query('labels') labelsQuery?: string,\n    @Query('includeErroredDeleted') includeErroredDeleted?: boolean,\n  ): Promise<SandboxDto[]> {\n    const labels = labelsQuery ? JSON.parse(labelsQuery) : undefined\n    const sandboxes = await this.sandboxService.findAllDeprecated(\n      authContext.organizationId,\n      labels,\n      includeErroredDeleted,\n    )\n\n    return this.sandboxService.toSandboxDtos(sandboxes)\n  }\n\n  @Get('paginated')\n  @ApiOperation({\n    summary: 'List all sandboxes paginated',\n    operationId: 'listSandboxesPaginated',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Paginated list of all sandboxes',\n    type: PaginatedSandboxesDto,\n  })\n  async listSandboxesPaginated(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Query() queryParams: ListSandboxesQueryDto,\n  ): Promise<PaginatedSandboxesDto> {\n    const {\n      page,\n      limit,\n      id,\n      name,\n      labels,\n      includeErroredDeleted: includeErroredDestroyed,\n      states,\n      snapshots,\n      regions,\n      minCpu,\n      maxCpu,\n      minMemoryGiB,\n      maxMemoryGiB,\n      minDiskGiB,\n      maxDiskGiB,\n      lastEventAfter,\n      lastEventBefore,\n      sort: sortField,\n      order: sortDirection,\n    } = queryParams\n\n    const result = await this.sandboxService.findAll(\n      authContext.organizationId,\n      page,\n      limit,\n      {\n        id,\n        name,\n        labels: labels ? JSON.parse(labels) : undefined,\n        includeErroredDestroyed,\n        states,\n        snapshots,\n        regionIds: regions,\n        minCpu,\n        maxCpu,\n        minMemoryGiB,\n        maxMemoryGiB,\n        minDiskGiB,\n        maxDiskGiB,\n        lastEventAfter,\n        lastEventBefore,\n      },\n      {\n        field: sortField,\n        direction: sortDirection,\n      },\n    )\n\n    return {\n      items: await this.sandboxService.toSandboxDtos(result.items),\n      total: result.total,\n      page: result.page,\n      totalPages: result.totalPages,\n    }\n  }\n\n  @Post()\n  @HttpCode(200) //  for Daytona Api compatibility\n  @UseInterceptors(ContentTypeInterceptor)\n  @SkipThrottle({ authenticated: true })\n  @ThrottlerScope('sandbox-create')\n  @ApiOperation({\n    summary: 'Create a new sandbox',\n    operationId: 'createSandbox',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The sandbox has been successfully created.',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateSandboxDto>) => ({\n        name: req.body?.name,\n        snapshot: req.body?.snapshot,\n        user: req.body?.user,\n        env: req.body?.env\n          ? Object.fromEntries(Object.keys(req.body?.env).map((key) => [key, MASKED_AUDIT_VALUE]))\n          : undefined,\n        labels: req.body?.labels,\n        public: req.body?.public,\n        class: req.body?.class,\n        target: req.body?.target,\n        cpu: req.body?.cpu,\n        gpu: req.body?.gpu,\n        memory: req.body?.memory,\n        disk: req.body?.disk,\n        autoStopInterval: req.body?.autoStopInterval,\n        autoArchiveInterval: req.body?.autoArchiveInterval,\n        autoDeleteInterval: req.body?.autoDeleteInterval,\n        volumes: req.body?.volumes,\n        buildInfo: req.body?.buildInfo,\n        networkBlockAll: req.body?.networkBlockAll,\n        networkAllowList: req.body?.networkAllowList,\n      }),\n    },\n  })\n  async createSandbox(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Body() createSandboxDto: CreateSandboxDto,\n  ): Promise<SandboxDto> {\n    const organization = authContext.organization\n    let sandbox: SandboxDto\n\n    if (createSandboxDto.buildInfo) {\n      if (createSandboxDto.snapshot) {\n        throw new BadRequestError('Cannot specify a snapshot when using a build info entry')\n      }\n      sandbox = await this.sandboxService.createFromBuildInfo(createSandboxDto, organization)\n    } else {\n      if (createSandboxDto.cpu || createSandboxDto.gpu || createSandboxDto.memory || createSandboxDto.disk) {\n        throw new BadRequestError('Cannot specify Sandbox resources when using a snapshot')\n      }\n      sandbox = await this.sandboxService.createFromSnapshot(createSandboxDto, organization)\n      if (sandbox.state === SandboxState.STARTED) {\n        return sandbox\n      }\n\n      await this.waitForSandboxStarted(sandbox, 30)\n    }\n\n    return sandbox\n  }\n\n  @Get('for-runner')\n  @UseGuards(RunnerAuthGuard)\n  @ApiOperation({\n    summary: 'Get sandboxes for the authenticated runner',\n    operationId: 'getSandboxesForRunner',\n  })\n  @ApiQuery({\n    name: 'states',\n    required: false,\n    type: String,\n    description: 'Comma-separated list of sandbox states to filter by',\n  })\n  @ApiQuery({\n    name: 'skipReconcilingSandboxes',\n    required: false,\n    type: Boolean,\n    description: 'Skip sandboxes where state differs from desired state',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of sandboxes for the authenticated runner',\n    type: [SandboxDto],\n  })\n  async getSandboxesForRunner(\n    @RunnerContextDecorator() runnerContext: RunnerContext,\n    @Query('states') states?: string,\n    @Query('skipReconcilingSandboxes') skipReconcilingSandboxes?: string,\n  ): Promise<SandboxDto[]> {\n    const stateArray = states\n      ? states.split(',').map((s) => {\n          if (!Object.values(SandboxState).includes(s as SandboxState)) {\n            throw new BadRequestError(`Invalid sandbox state: ${s}`)\n          }\n          return s as SandboxState\n        })\n      : undefined\n\n    const skip = skipReconcilingSandboxes === 'true'\n    const sandboxes = await this.sandboxService.findByRunnerId(runnerContext.runnerId, stateArray, skip)\n\n    return this.sandboxService.toSandboxDtos(sandboxes)\n  }\n\n  @Get(':sandboxIdOrName')\n  @ApiOperation({\n    summary: 'Get sandbox details',\n    operationId: 'getSandbox',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiQuery({\n    name: 'verbose',\n    required: false,\n    type: Boolean,\n    description: 'Include verbose output',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox details',\n    type: SandboxDto,\n  })\n  @UseGuards(SandboxAccessGuard)\n  async getSandbox(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    @Query('verbose') verbose?: boolean,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.findOneByIdOrName(sandboxIdOrName, authContext.organizationId)\n\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Delete(':sandboxIdOrName')\n  @SkipThrottle({ authenticated: true })\n  @ThrottlerScope('sandbox-lifecycle')\n  @ApiOperation({\n    summary: 'Delete sandbox',\n    operationId: 'deleteSandbox',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox has been deleted',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.DELETE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n  })\n  async deleteSandbox(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.destroy(sandboxIdOrName, authContext.organizationId)\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Post(':sandboxIdOrName/recover')\n  @HttpCode(200)\n  @SkipThrottle({ authenticated: true })\n  @ThrottlerScope('sandbox-lifecycle')\n  @ApiOperation({\n    summary: 'Recover sandbox from error state',\n    operationId: 'recoverSandbox',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Recovery initiated',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.RECOVER,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n  })\n  async recoverSandbox(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n  ): Promise<SandboxDto> {\n    const recoveredSandbox = await this.sandboxService.recover(sandboxIdOrName, authContext.organization)\n    let sandboxDto = await this.sandboxService.toSandboxDto(recoveredSandbox)\n\n    if (sandboxDto.state !== SandboxState.STARTED) {\n      sandboxDto = await this.waitForSandboxStarted(sandboxDto, 30)\n    }\n\n    return sandboxDto\n  }\n\n  @Post(':sandboxIdOrName/start')\n  @HttpCode(200)\n  @SkipThrottle({ authenticated: true })\n  @ThrottlerScope('sandbox-lifecycle')\n  @ApiOperation({\n    summary: 'Start sandbox',\n    operationId: 'startSandbox',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox has been started or is being restored from archived state',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.START,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n  })\n  async startSandbox(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n  ): Promise<SandboxDto> {\n    const sbx = await this.sandboxService.start(sandboxIdOrName, authContext.organization)\n    let sandbox = await this.sandboxService.toSandboxDto(sbx)\n\n    if (![SandboxState.ARCHIVED, SandboxState.RESTORING, SandboxState.STARTED].includes(sandbox.state)) {\n      sandbox = await this.waitForSandboxStarted(sandbox, 30)\n    }\n\n    return sandbox\n  }\n\n  @Post(':sandboxIdOrName/stop')\n  @HttpCode(200) //  for Daytona Api compatibility\n  @SkipThrottle({ authenticated: true })\n  @ThrottlerScope('sandbox-lifecycle')\n  @ApiOperation({\n    summary: 'Stop sandbox',\n    operationId: 'stopSandbox',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox has been stopped',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.STOP,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n  })\n  async stopSandbox(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.stop(sandboxIdOrName, authContext.organizationId)\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Post(':sandboxIdOrName/resize')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @SkipThrottle({ authenticated: true })\n  @ThrottlerScope('sandbox-lifecycle')\n  @ApiOperation({\n    summary: 'Resize sandbox resources',\n    operationId: 'resizeSandbox',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox has been resized',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @RequireFlagsEnabled({ flags: [{ flagKey: FeatureFlags.SANDBOX_RESIZE, defaultValue: false }] })\n  @Audit({\n    action: AuditAction.RESIZE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<ResizeSandboxDto>) => ({\n        cpu: req.body?.cpu,\n        memory: req.body?.memory,\n        disk: req.body?.disk,\n      }),\n    },\n  })\n  async resizeSandbox(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Body() resizeSandboxDto: ResizeSandboxDto,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.resize(sandboxIdOrName, resizeSandboxDto, authContext.organization)\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Put(':sandboxIdOrName/labels')\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: 'Replace sandbox labels',\n    operationId: 'replaceLabels',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Labels have been successfully replaced',\n    type: SandboxLabelsDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.REPLACE_LABELS,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<SandboxLabelsDto>) => ({\n        labels: req.body?.labels,\n      }),\n    },\n  })\n  async replaceLabels(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Body() labelsDto: SandboxLabelsDto,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.replaceLabels(\n      sandboxIdOrName,\n      labelsDto.labels,\n      authContext.organizationId,\n    )\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Put(':sandboxId/state')\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: 'Update sandbox state',\n    operationId: 'updateSandboxState',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox state has been successfully updated',\n  })\n  @UseGuards(RunnerAuthGuard)\n  @UseGuards(SandboxAccessGuard)\n  async updateSandboxState(\n    @Param('sandboxId') sandboxId: string,\n    @Body() updateStateDto: UpdateSandboxStateDto,\n  ): Promise<void> {\n    await this.sandboxService.updateState(\n      sandboxId,\n      updateStateDto.state,\n      updateStateDto.recoverable,\n      updateStateDto.errorReason,\n    )\n  }\n\n  @Post(':sandboxIdOrName/backup')\n  @ApiOperation({\n    summary: 'Create sandbox backup',\n    operationId: 'createBackup',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox backup has been initiated',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.CREATE_BACKUP,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n  })\n  async createBackup(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.createBackup(sandboxIdOrName, authContext.organizationId)\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Post(':sandboxIdOrName/public/:isPublic')\n  @ApiOperation({\n    summary: 'Update public status',\n    operationId: 'updatePublicStatus',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'isPublic',\n    description: 'Public status to set',\n    type: 'boolean',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Public status has been successfully updated',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.UPDATE_PUBLIC_STATUS,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n    requestMetadata: {\n      params: (req) => ({\n        isPublic: req.params.isPublic,\n      }),\n    },\n  })\n  async updatePublicStatus(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Param('isPublic') isPublic: boolean,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.updatePublicStatus(sandboxIdOrName, isPublic, authContext.organizationId)\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Post(':sandboxId/last-activity')\n  @ApiOperation({\n    summary: 'Update sandbox last activity',\n    operationId: 'updateLastActivity',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 201,\n    description: 'Last activity has been updated',\n  })\n  @UseGuards(OrGuard([SandboxAccessGuard, ProxyGuard, SshGatewayGuard]))\n  async updateLastActivity(@Param('sandboxId') sandboxId: string): Promise<void> {\n    await this.sandboxService.updateLastActivityAt(sandboxId, new Date())\n  }\n\n  @Post(':sandboxIdOrName/autostop/:interval')\n  @ApiOperation({\n    summary: 'Set sandbox auto-stop interval',\n    operationId: 'setAutostopInterval',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'interval',\n    description: 'Auto-stop interval in minutes (0 to disable)',\n    type: 'number',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Auto-stop interval has been set',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.SET_AUTO_STOP_INTERVAL,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n    requestMetadata: {\n      params: (req) => ({\n        interval: req.params.interval,\n      }),\n    },\n  })\n  async setAutostopInterval(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Param('interval') interval: number,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.setAutostopInterval(sandboxIdOrName, interval, authContext.organizationId)\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Post(':sandboxIdOrName/autoarchive/:interval')\n  @ApiOperation({\n    summary: 'Set sandbox auto-archive interval',\n    operationId: 'setAutoArchiveInterval',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'interval',\n    description: 'Auto-archive interval in minutes (0 means the maximum interval will be used)',\n    type: 'number',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Auto-archive interval has been set',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.SET_AUTO_ARCHIVE_INTERVAL,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n    requestMetadata: {\n      params: (req) => ({\n        interval: req.params.interval,\n      }),\n    },\n  })\n  async setAutoArchiveInterval(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Param('interval') interval: number,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.setAutoArchiveInterval(\n      sandboxIdOrName,\n      interval,\n      authContext.organizationId,\n    )\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Post(':sandboxIdOrName/autodelete/:interval')\n  @ApiOperation({\n    summary: 'Set sandbox auto-delete interval',\n    operationId: 'setAutoDeleteInterval',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'interval',\n    description:\n      'Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)',\n    type: 'number',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Auto-delete interval has been set',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.SET_AUTO_DELETE_INTERVAL,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n    requestMetadata: {\n      params: (req) => ({\n        interval: req.params.interval,\n      }),\n    },\n  })\n  async setAutoDeleteInterval(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Param('interval') interval: number,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.setAutoDeleteInterval(\n      sandboxIdOrName,\n      interval,\n      authContext.organizationId,\n    )\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  // TODO: Network settings endpoint will not be enabled for now\n  // @Post(':sandboxIdOrName/network-settings')\n  // @ApiOperation({\n  //   summary: 'Update sandbox network settings',\n  //   operationId: 'updateNetworkSettings',\n  // })\n  // @ApiParam({\n  //   name: 'sandboxIdOrName',\n  //   description: 'ID or name of the sandbox',\n  //   type: 'string',\n  // })\n  // @ApiResponse({\n  //   status: 200,\n  //   description: 'Network settings have been updated',\n  //   type: SandboxDto,\n  // })\n  // @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  // @UseGuards(SandboxAccessGuard)\n  // @Audit({\n  //   action: AuditAction.UPDATE_NETWORK_SETTINGS,\n  //   targetType: AuditTarget.SANDBOX,\n  //   targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n  //   targetIdFromResult: (result: SandboxDto) => result?.id,\n  //   requestMetadata: {\n  //     body: (req: TypedRequest<UpdateSandboxNetworkSettingsDto>) => ({\n  //       networkBlockAll: req.body?.networkBlockAll,\n  //       networkAllowList: req.body?.networkAllowList,\n  //     }),\n  //   },\n  // })\n  // async updateNetworkSettings(\n  //   @AuthContext() authContext: OrganizationAuthContext,\n  //   @Param('sandboxIdOrName') sandboxIdOrName: string,\n  //   @Body() networkSettings: UpdateSandboxNetworkSettingsDto,\n  // ): Promise<SandboxDto> {\n  //   const sandbox = await this.sandboxService.updateNetworkSettings(\n  //     sandboxIdOrName,\n  //     networkSettings.networkBlockAll,\n  //     networkSettings.networkAllowList,\n  //     authContext.organizationId,\n  //   )\n  //   return SandboxDto.fromSandbox(sandbox, '')\n  // }\n\n  @Post(':sandboxIdOrName/archive')\n  @HttpCode(200)\n  @SkipThrottle({ authenticated: true })\n  @ThrottlerScope('sandbox-lifecycle')\n  @ApiOperation({\n    summary: 'Archive sandbox',\n    operationId: 'archiveSandbox',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sandbox has been archived',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.ARCHIVE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n  })\n  async archiveSandbox(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.archive(sandboxIdOrName, authContext.organizationId)\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Get(':sandboxIdOrName/ports/:port/preview-url')\n  @ApiOperation({\n    summary: 'Get preview URL for a sandbox port',\n    operationId: 'getPortPreviewUrl',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'port',\n    description: 'Port number to get preview URL for',\n    type: 'number',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Preview URL for the specified port',\n    type: PortPreviewUrlDto,\n  })\n  @UseGuards(SandboxAccessGuard)\n  async getPortPreviewUrl(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Param('port') port: number,\n  ): Promise<PortPreviewUrlDto> {\n    return this.sandboxService.getPortPreviewUrl(sandboxIdOrName, authContext.organizationId, port)\n  }\n\n  @Get(':sandboxIdOrName/ports/:port/signed-preview-url')\n  @ApiOperation({\n    summary: 'Get signed preview URL for a sandbox port',\n    operationId: 'getSignedPortPreviewUrl',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'port',\n    description: 'Port number to get signed preview URL for',\n    type: 'integer',\n  })\n  @ApiQuery({\n    name: 'expiresInSeconds',\n    required: false,\n    type: 'integer',\n    description: 'Expiration time in seconds (default: 60 seconds)',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Signed preview URL for the specified port',\n    type: SignedPortPreviewUrlDto,\n  })\n  @UseGuards(SandboxAccessGuard)\n  async getSignedPortPreviewUrl(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Param('port') port: number,\n    @Query('expiresInSeconds') expiresInSeconds?: number,\n  ): Promise<SignedPortPreviewUrlDto> {\n    return this.sandboxService.getSignedPortPreviewUrl(\n      sandboxIdOrName,\n      authContext.organizationId,\n      port,\n      expiresInSeconds,\n    )\n  }\n\n  @Post(':sandboxIdOrName/ports/:port/signed-preview-url/:token/expire')\n  @ApiOperation({\n    summary: 'Expire signed preview URL for a sandbox port',\n    operationId: 'expireSignedPortPreviewUrl',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'port',\n    description: 'Port number to expire signed preview URL for',\n    type: 'integer',\n  })\n  @ApiParam({\n    name: 'token',\n    description: 'Token to expire signed preview URL for',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Signed preview URL has been expired',\n  })\n  @UseGuards(SandboxAccessGuard)\n  async expireSignedPortPreviewUrl(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Param('port') port: number,\n    @Param('token') token: string,\n  ): Promise<void> {\n    await this.sandboxService.expireSignedPreviewUrlToken(sandboxIdOrName, authContext.organizationId, token, port)\n  }\n\n  @Get(':sandboxIdOrName/build-logs')\n  @ApiOperation({\n    summary: 'Get build logs',\n    operationId: 'getBuildLogs',\n    deprecated: true,\n    description: 'This endpoint is deprecated. Use `getBuildLogsUrl` instead.',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Build logs stream',\n  })\n  @ApiQuery({\n    name: 'follow',\n    required: false,\n    type: Boolean,\n    description: 'Whether to follow the logs stream',\n  })\n  @UseGuards(SandboxAccessGuard)\n  async getBuildLogs(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Query('follow', new ParseBoolPipe({ optional: true })) follow?: boolean,\n  ): Promise<void> {\n    const sandbox = await this.sandboxService.findOneByIdOrName(sandboxIdOrName, authContext.organizationId)\n    if (!sandbox.runnerId) {\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxIdOrName} has no runner assigned`)\n    }\n\n    if (!sandbox.buildInfo) {\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxIdOrName} has no build info`)\n    }\n\n    const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n\n    if (!runner.apiUrl) {\n      throw new NotFoundException(`Runner for sandbox ${sandboxIdOrName} has no API URL`)\n    }\n\n    const logProxy = new LogProxy(\n      runner.apiUrl,\n      sandbox.buildInfo.snapshotRef.split(':')[0],\n      runner.apiKey,\n      follow === true,\n      req,\n      res,\n      next,\n    )\n    return logProxy.create()\n  }\n\n  @Get(':sandboxIdOrName/build-logs-url')\n  @ApiOperation({\n    summary: 'Get build logs URL',\n    operationId: 'getBuildLogsUrl',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Build logs URL',\n    type: UrlDto,\n  })\n  @UseGuards(SandboxAccessGuard)\n  async getBuildLogsUrl(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n  ): Promise<UrlDto> {\n    const buildLogsUrl = await this.sandboxService.getBuildLogsUrl(sandboxIdOrName, authContext.organizationId)\n\n    return new UrlDto(buildLogsUrl)\n  }\n\n  @Post(':sandboxIdOrName/ssh-access')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Create SSH access for sandbox',\n    operationId: 'createSshAccess',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiQuery({\n    name: 'expiresInMinutes',\n    required: false,\n    type: Number,\n    description: 'Expiration time in minutes (default: 60)',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'SSH access has been created',\n    type: SshAccessDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.CREATE_SSH_ACCESS,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SshAccessDto) => result?.sandboxId,\n    requestMetadata: {\n      query: (req) => ({\n        expiresInMinutes: req.query.expiresInMinutes,\n      }),\n    },\n  })\n  async createSshAccess(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Query('expiresInMinutes') expiresInMinutes?: number,\n  ): Promise<SshAccessDto> {\n    return await this.sandboxService.createSshAccess(sandboxIdOrName, expiresInMinutes, authContext.organizationId)\n  }\n\n  @Delete(':sandboxIdOrName/ssh-access')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Revoke SSH access for sandbox',\n    operationId: 'revokeSshAccess',\n  })\n  @ApiParam({\n    name: 'sandboxIdOrName',\n    description: 'ID or name of the sandbox',\n    type: 'string',\n  })\n  @ApiQuery({\n    name: 'token',\n    required: false,\n    type: String,\n    description: 'SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'SSH access has been revoked',\n    type: SandboxDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(SandboxAccessGuard)\n  @Audit({\n    action: AuditAction.REVOKE_SSH_ACCESS,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxIdOrName,\n    targetIdFromResult: (result: SandboxDto) => result?.id,\n    requestMetadata: {\n      query: (req) => ({\n        token: req.query.token,\n      }),\n    },\n  })\n  async revokeSshAccess(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('sandboxIdOrName') sandboxIdOrName: string,\n    @Query('token') token?: string,\n  ): Promise<SandboxDto> {\n    const sandbox = await this.sandboxService.revokeSshAccess(sandboxIdOrName, token, authContext.organizationId)\n    return this.sandboxService.toSandboxDto(sandbox)\n  }\n\n  @Get('ssh-access/validate')\n  @ApiOperation({\n    summary: 'Validate SSH access for sandbox',\n    operationId: 'validateSshAccess',\n  })\n  @ApiQuery({\n    name: 'token',\n    required: true,\n    type: String,\n    description: 'SSH access token to validate',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'SSH access validation result',\n    type: SshAccessValidationDto,\n  })\n  async validateSshAccess(@Query('token') token: string): Promise<SshAccessValidationDto> {\n    const result = await this.sandboxService.validateSshAccess(token)\n    return SshAccessValidationDto.fromValidationResult(result.valid, result.sandboxId)\n  }\n\n  @Get(':sandboxId/toolbox-proxy-url')\n  @ApiOperation({\n    summary: 'Get toolbox proxy URL for a sandbox',\n    operationId: 'getToolboxProxyUrl',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Toolbox proxy URL for the specified sandbox',\n    type: ToolboxProxyUrlDto,\n  })\n  @UseGuards(SandboxAccessGuard)\n  async getToolboxProxyUrl(@Param('sandboxId') sandboxId: string): Promise<ToolboxProxyUrlDto> {\n    const url = await this.sandboxService.getToolboxProxyUrl(sandboxId)\n    return new ToolboxProxyUrlDto(url)\n  }\n\n  // wait up to `timeoutSeconds` for the sandbox to start; if it doesn’t, return current sandbox\n  private async waitForSandboxStarted(sandbox: SandboxDto, timeoutSeconds: number): Promise<SandboxDto> {\n    let latestSandbox: Sandbox\n    const waitForStarted = new Promise<SandboxDto>((resolve, reject) => {\n      // eslint-disable-next-line\n      let timeout: NodeJS.Timeout\n      const handleStateUpdated = (event: SandboxStateUpdatedEvent) => {\n        if (event.sandbox.id !== sandbox.id) {\n          return\n        }\n        latestSandbox = event.sandbox\n        if (event.sandbox.state === SandboxState.STARTED) {\n          this.sandboxCallbacks.delete(sandbox.id)\n          clearTimeout(timeout)\n          resolve(this.sandboxService.toSandboxDto(event.sandbox))\n        }\n        if (event.sandbox.state === SandboxState.ERROR || event.sandbox.state === SandboxState.BUILD_FAILED) {\n          this.sandboxCallbacks.delete(sandbox.id)\n          clearTimeout(timeout)\n          reject(new BadRequestError(`Sandbox failed to start: ${event.sandbox.errorReason}`))\n        }\n      }\n\n      this.sandboxCallbacks.set(sandbox.id, handleStateUpdated)\n\n      timeout = setTimeout(() => {\n        this.sandboxCallbacks.delete(sandbox.id)\n        if (latestSandbox) {\n          resolve(this.sandboxService.toSandboxDto(latestSandbox))\n        } else {\n          resolve(sandbox)\n        }\n      }, timeoutSeconds * 1000)\n    })\n\n    return waitForStarted\n  }\n\n  private handleSandboxStateUpdated(event: SandboxStateUpdatedEvent) {\n    const callback = this.sandboxCallbacks.get(event.sandbox.id)\n    if (callback) {\n      callback(event)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/controllers/snapshot.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Body,\n  Controller,\n  Delete,\n  Get,\n  Param,\n  Patch,\n  Post,\n  Query,\n  UseGuards,\n  HttpCode,\n  ForbiddenException,\n  Logger,\n  NotFoundException,\n  Res,\n  Request,\n  RawBodyRequest,\n  Next,\n  ParseBoolPipe,\n} from '@nestjs/common'\nimport { IncomingMessage, ServerResponse } from 'http'\nimport { NextFunction } from 'express'\nimport { SnapshotService } from '../services/snapshot.service'\nimport { RunnerService } from '../services/runner.service'\nimport {\n  ApiOAuth2,\n  ApiTags,\n  ApiOperation,\n  ApiResponse,\n  ApiParam,\n  ApiQuery,\n  ApiHeader,\n  ApiBearerAuth,\n} from '@nestjs/swagger'\nimport { CreateSnapshotDto } from '../dto/create-snapshot.dto'\nimport { SnapshotDto } from '../dto/snapshot.dto'\nimport { PaginatedSnapshotsDto } from '../dto/paginated-snapshots.dto'\nimport { SnapshotAccessGuard } from '../guards/snapshot-access.guard'\nimport { SnapshotReadAccessGuard } from '../guards/snapshot-read-access.guard'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { RequiredOrganizationResourcePermissions } from '../../organization/decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { SystemActionGuard } from '../../auth/system-action.guard'\nimport { RequiredSystemRole } from '../../common/decorators/required-role.decorator'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { SetSnapshotGeneralStatusDto } from '../dto/update-snapshot.dto'\nimport { LogProxy } from '../proxy/log-proxy'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { ListSnapshotsQueryDto } from '../dto/list-snapshots-query.dto'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\nimport { UrlDto } from '../../common/dto/url.dto'\n\n@ApiTags('snapshots')\n@Controller('snapshots')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, SystemActionGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class SnapshotController {\n  private readonly logger = new Logger(SnapshotController.name)\n\n  constructor(\n    private readonly snapshotService: SnapshotService,\n    private readonly runnerService: RunnerService,\n  ) {}\n\n  @Post()\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Create a new snapshot',\n    operationId: 'createSnapshot',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The snapshot has been successfully created.',\n    type: SnapshotDto,\n  })\n  @ApiResponse({\n    status: 400,\n    description: 'Bad request - Snapshots with tag \":latest\" are not allowed',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SNAPSHOTS])\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.SNAPSHOT,\n    targetIdFromResult: (result: SnapshotDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateSnapshotDto>) => ({\n        name: req.body?.name,\n        imageName: req.body?.imageName,\n        entrypoint: req.body?.entrypoint,\n        general: req.body?.general,\n        cpu: req.body?.cpu,\n        memory: req.body?.memory,\n        disk: req.body?.disk,\n        gpu: req.body?.gpu,\n        buildInfo: req.body?.buildInfo,\n      }),\n    },\n  })\n  async createSnapshot(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Body() createSnapshotDto: CreateSnapshotDto,\n  ): Promise<SnapshotDto> {\n    if (createSnapshotDto.general && authContext.role !== SystemRole.ADMIN) {\n      throw new ForbiddenException('Insufficient permissions for creating general snapshots')\n    }\n\n    if (createSnapshotDto.buildInfo) {\n      if (createSnapshotDto.imageName) {\n        throw new BadRequestError('Cannot specify an image name when using a build info entry')\n      }\n      if (createSnapshotDto.entrypoint) {\n        throw new BadRequestError('Cannot specify an entrypoint when using a build info entry')\n      }\n    } else {\n      if (!createSnapshotDto.imageName) {\n        throw new BadRequestError('Must specify an image name when not using a build info entry')\n      }\n    }\n\n    // TODO: consider - if using transient registry, prepend the snapshot name with the username\n    const snapshot = createSnapshotDto.buildInfo\n      ? await this.snapshotService.createFromBuildInfo(authContext.organization, createSnapshotDto)\n      : await this.snapshotService.createFromPull(authContext.organization, createSnapshotDto)\n    return SnapshotDto.fromSnapshot(snapshot)\n  }\n\n  @Get('can-cleanup-image')\n  @ApiOperation({\n    summary: 'Check if an image can be cleaned up',\n    operationId: 'canCleanupImage',\n  })\n  @ApiQuery({\n    name: 'imageName',\n    required: true,\n    type: String,\n    description: 'Image name with tag to check',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Boolean indicating if image can be cleaned up',\n    type: Boolean,\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  async canCleanupImage(@Query('imageName') imageName: string): Promise<boolean> {\n    return this.snapshotService.canCleanupImage(imageName)\n  }\n\n  @Get(':id')\n  @ApiOperation({\n    summary: 'Get snapshot by ID or name',\n    operationId: 'getSnapshot',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Snapshot ID or name',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The snapshot',\n    type: SnapshotDto,\n  })\n  @ApiResponse({\n    status: 404,\n    description: 'Snapshot not found',\n  })\n  @UseGuards(SnapshotReadAccessGuard)\n  async getSnapshot(\n    @Param('id') snapshotIdOrName: string,\n    @AuthContext() authContext: OrganizationAuthContext,\n  ): Promise<SnapshotDto> {\n    const snapshot = await this.snapshotService.getSnapshotWithRegions(snapshotIdOrName, authContext.organizationId)\n    return SnapshotDto.fromSnapshot(snapshot)\n  }\n\n  @Delete(':id')\n  @ApiOperation({\n    summary: 'Delete snapshot',\n    operationId: 'removeSnapshot',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Snapshot ID',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Snapshot has been deleted',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.DELETE_SNAPSHOTS])\n  @UseGuards(SnapshotAccessGuard)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.SNAPSHOT,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  async removeSnapshot(@Param('id') snapshotId: string): Promise<void> {\n    await this.snapshotService.removeSnapshot(snapshotId)\n  }\n\n  @Get()\n  @ApiOperation({\n    summary: 'List all snapshots',\n    operationId: 'getAllSnapshots',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Paginated list of all snapshots',\n    type: PaginatedSnapshotsDto,\n  })\n  async getAllSnapshots(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Query() queryParams: ListSnapshotsQueryDto,\n  ): Promise<PaginatedSnapshotsDto> {\n    const { page, limit, name, sort, order } = queryParams\n\n    const result = await this.snapshotService.getAllSnapshots(\n      authContext.organizationId,\n      page,\n      limit,\n      { name },\n      { field: sort, direction: order },\n    )\n\n    return {\n      items: result.items.map(SnapshotDto.fromSnapshot),\n      total: result.total,\n      page: result.page,\n      totalPages: result.totalPages,\n    }\n  }\n\n  @Patch(':id/general')\n  @ApiOperation({\n    summary: 'Set snapshot general status',\n    operationId: 'setSnapshotGeneralStatus',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Snapshot ID',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Snapshot general status has been set',\n    type: SnapshotDto,\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @Audit({\n    action: AuditAction.SET_GENERAL_STATUS,\n    targetType: AuditTarget.SNAPSHOT,\n    targetIdFromRequest: (req) => req.params.id,\n    requestMetadata: {\n      body: (req: TypedRequest<SetSnapshotGeneralStatusDto>) => ({\n        general: req.body?.general,\n      }),\n    },\n  })\n  async setSnapshotGeneralStatus(\n    @Param('id') snapshotId: string,\n    @Body() dto: SetSnapshotGeneralStatusDto,\n  ): Promise<SnapshotDto> {\n    const snapshot = await this.snapshotService.setSnapshotGeneralStatus(snapshotId, dto.general)\n    return SnapshotDto.fromSnapshot(snapshot)\n  }\n\n  @Get(':id/build-logs')\n  @ApiOperation({\n    summary: 'Get snapshot build logs',\n    operationId: 'getSnapshotBuildLogs',\n    deprecated: true,\n    description: 'This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Snapshot ID',\n  })\n  @ApiQuery({\n    name: 'follow',\n    required: false,\n    type: Boolean,\n    description: 'Whether to follow the logs stream',\n  })\n  @UseGuards(SnapshotAccessGuard)\n  async getSnapshotBuildLogs(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n    @Param('id') snapshotId: string,\n    @Query('follow', new ParseBoolPipe({ optional: true })) follow?: boolean,\n  ): Promise<void> {\n    let snapshot = await this.snapshotService.getSnapshot(snapshotId)\n\n    // Check if the snapshot has build info\n    if (!snapshot.buildInfo) {\n      throw new NotFoundException(`Snapshot ${snapshotId} has no build info`)\n    }\n\n    if (snapshot.state == SnapshotState.ACTIVE) {\n      // Close the connection\n      res.end()\n      return\n    }\n\n    // Retry until a runner is assigned or timeout after 30 seconds\n    const startTime = Date.now()\n    const timeoutMs = 30 * 1000\n\n    while (!snapshot.initialRunnerId) {\n      if (Date.now() - startTime > timeoutMs) {\n        throw new NotFoundException(`Timeout waiting for build runner assignment for snapshot ${snapshotId}`)\n      }\n      await new Promise((resolve) => setTimeout(resolve, 1000))\n      snapshot = await this.snapshotService.getSnapshot(snapshotId)\n    }\n\n    const runner = await this.runnerService.findOneOrFail(snapshot.initialRunnerId)\n\n    if (!runner.apiUrl) {\n      throw new NotFoundException(`Build runner for snapshot ${snapshotId} has no API URL`)\n    }\n\n    const logProxy = new LogProxy(\n      runner.apiUrl,\n      snapshot.buildInfo.snapshotRef,\n      runner.apiKey,\n      follow === true,\n      req,\n      res,\n      next,\n    )\n    return logProxy.create()\n  }\n\n  @Get(':id/build-logs-url')\n  @ApiOperation({\n    summary: 'Get snapshot build logs URL',\n    operationId: 'getSnapshotBuildLogsUrl',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Snapshot ID',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The snapshot build logs URL',\n    type: UrlDto,\n  })\n  @UseGuards(SnapshotAccessGuard)\n  async getSnapshotBuildLogsUrl(@Param('id') snapshotId: string): Promise<UrlDto> {\n    let snapshot = await this.snapshotService.getSnapshot(snapshotId)\n\n    // Check if the snapshot has build info\n    if (!snapshot.buildInfo) {\n      throw new NotFoundException(`Snapshot ${snapshotId} has no build info`)\n    }\n\n    // Retry until a runner is assigned or timeout after 30 seconds\n    const startTime = Date.now()\n    const timeoutMs = 30 * 1000\n\n    while (!snapshot.initialRunnerId) {\n      if (Date.now() - startTime > timeoutMs) {\n        throw new NotFoundException(`Timeout waiting for build runner assignment for snapshot ${snapshotId}`)\n      }\n      await new Promise((resolve) => setTimeout(resolve, 1000))\n      snapshot = await this.snapshotService.getSnapshot(snapshotId)\n    }\n\n    const url = await this.snapshotService.getBuildLogsUrl(snapshot)\n    return new UrlDto(url)\n  }\n\n  @Post(':id/activate')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: 'Activate a snapshot',\n    operationId: 'activateSnapshot',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Snapshot ID',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The snapshot has been successfully activated.',\n    type: SnapshotDto,\n  })\n  @ApiResponse({\n    status: 400,\n    description: 'Bad request - Snapshot is already active, not in inactive state, or has associated snapshot runners',\n  })\n  @ApiResponse({\n    status: 404,\n    description: 'Snapshot not found',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SNAPSHOTS])\n  @UseGuards(SnapshotAccessGuard)\n  @Audit({\n    action: AuditAction.ACTIVATE,\n    targetType: AuditTarget.SNAPSHOT,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  async activateSnapshot(\n    @Param('id') snapshotId: string,\n    @AuthContext() authContext: OrganizationAuthContext,\n  ): Promise<SnapshotDto> {\n    const snapshot = await this.snapshotService.activateSnapshot(snapshotId, authContext.organization)\n    return SnapshotDto.fromSnapshot(snapshot)\n  }\n\n  @Post(':id/deactivate')\n  @HttpCode(204)\n  @ApiOperation({\n    summary: 'Deactivate a snapshot',\n    operationId: 'deactivateSnapshot',\n  })\n  @ApiParam({\n    name: 'id',\n    description: 'Snapshot ID',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'The snapshot has been successfully deactivated.',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SNAPSHOTS])\n  @UseGuards(SnapshotAccessGuard)\n  @Audit({\n    action: AuditAction.DEACTIVATE,\n    targetType: AuditTarget.SNAPSHOT,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  async deactivateSnapshot(@Param('id') snapshotId: string) {\n    await this.snapshotService.deactivateSnapshot(snapshotId)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/controllers/toolbox.deprecated.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Controller,\n  Get,\n  Post,\n  Delete,\n  Body,\n  Param,\n  Request,\n  Logger,\n  UseGuards,\n  HttpCode,\n  UseInterceptors,\n  RawBodyRequest,\n  BadRequestException,\n  Res,\n  Next,\n} from '@nestjs/common'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport {\n  ApiOAuth2,\n  ApiResponse,\n  ApiQuery,\n  ApiOperation,\n  ApiConsumes,\n  ApiBody,\n  ApiTags,\n  ApiParam,\n  ApiHeader,\n  ApiBearerAuth,\n} from '@nestjs/swagger'\nimport {\n  FileInfoDto,\n  MatchDto,\n  SearchFilesResponseDto,\n  ReplaceRequestDto,\n  ReplaceResultDto,\n  GitAddRequestDto,\n  GitBranchRequestDto,\n  GitDeleteBranchRequestDto,\n  GitCloneRequestDto,\n  GitCommitRequestDto,\n  GitCommitResponseDto,\n  GitRepoRequestDto,\n  GitStatusDto,\n  ListBranchResponseDto,\n  GitCommitInfoDto,\n  GitCheckoutRequestDto,\n  ExecuteRequestDto,\n  ExecuteResponseDto,\n  ProjectDirResponseDto,\n  CreateSessionRequestDto,\n  SessionExecuteRequestDto,\n  SessionExecuteResponseDto,\n  SessionDto,\n  CommandDto,\n  MousePositionDto,\n  MouseMoveRequestDto,\n  MouseMoveResponseDto,\n  MouseClickRequestDto,\n  MouseClickResponseDto,\n  MouseDragRequestDto,\n  MouseDragResponseDto,\n  MouseScrollRequestDto,\n  MouseScrollResponseDto,\n  KeyboardTypeRequestDto,\n  KeyboardPressRequestDto,\n  KeyboardHotkeyRequestDto,\n  ScreenshotResponseDto,\n  RegionScreenshotResponseDto,\n  CompressedScreenshotResponseDto,\n  DisplayInfoResponseDto,\n  WindowsResponseDto,\n  ComputerUseStartResponseDto,\n  ComputerUseStopResponseDto,\n  ComputerUseStatusResponseDto,\n  ProcessStatusResponseDto,\n  ProcessRestartResponseDto,\n  ProcessLogsResponseDto,\n  ProcessErrorsResponseDto,\n  UserHomeDirResponseDto,\n  WorkDirResponseDto,\n  PtyCreateRequestDto,\n  PtyCreateResponseDto,\n  PtySessionInfoDto,\n  PtyListResponseDto,\n  PtyResizeRequestDto,\n} from '../dto/toolbox.deprecated.dto'\nimport { ToolboxService } from '../services/toolbox.deprecated.service'\nimport { ContentTypeInterceptor } from '../../common/interceptors/content-type.interceptors'\nimport {\n  CompletionListDto,\n  LspCompletionParamsDto,\n  LspDocumentRequestDto,\n  LspSymbolDto,\n  LspServerRequestDto,\n} from '../dto/lsp.dto'\nimport { createProxyMiddleware, RequestHandler, fixRequestBody, Options } from 'http-proxy-middleware'\nimport { IncomingMessage } from 'http'\nimport { NextFunction } from 'express'\nimport { ServerResponse } from 'http'\nimport { SandboxAccessGuard } from '../guards/sandbox-access.guard'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { RequiredOrganizationResourcePermissions } from '../../organization/decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport followRedirects from 'follow-redirects'\nimport { UploadFileDto } from '../dto/upload-file.dto'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { Audit, MASKED_AUDIT_VALUE, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { DownloadFilesDto } from '../dto/download-files.dto'\nimport { SkipThrottle } from '@nestjs/throttler'\n\nfollowRedirects.maxRedirects = 10\nfollowRedirects.maxBodyLength = 50 * 1024 * 1024\n\ntype RunnerInfo = {\n  apiKey: string\n  apiUrl: string\n}\nconst RUNNER_INFO_CACHE_PREFIX = 'proxy:sandbox-runner-info:'\nconst RUNNER_INFO_CACHE_TTL = 2 * 60 // 2 minutes\n\n@ApiTags('toolbox')\n@Controller('toolbox')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@SkipThrottle({ anonymous: true, authenticated: true })\n@UseGuards(CombinedAuthGuard, OrganizationResourceActionGuard, SandboxAccessGuard)\n@RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class ToolboxController {\n  private readonly logger = new Logger(ToolboxController.name)\n  private readonly toolboxProxy: RequestHandler<\n    RawBodyRequest<IncomingMessage>,\n    ServerResponse<IncomingMessage>,\n    NextFunction\n  >\n  private readonly toolboxStreamProxy: RequestHandler<\n    RawBodyRequest<IncomingMessage>,\n    ServerResponse<IncomingMessage>,\n    NextFunction\n  >\n\n  constructor(\n    private readonly toolboxService: ToolboxService,\n    @InjectRedis() private readonly redis: Redis,\n  ) {\n    const commonProxyOptions: Options = {\n      router: async (req: RawBodyRequest<IncomingMessage>) => {\n        // eslint-disable-next-line no-useless-escape\n        const sandboxId = req.url.match(/^\\/api\\/toolbox\\/([^\\/]+)\\/toolbox/)?.[1]\n        try {\n          const runnerInfo = await this.getRunnerInfo(sandboxId)\n\n          // @ts-expect-error - used later to set request headers\n          req._runnerApiKey = runnerInfo.apiKey\n\n          return runnerInfo.apiUrl\n        } catch (err) {\n          // @ts-expect-error - used later to throw error\n          req._err = err\n        }\n\n        // Must return a valid url\n        return 'http://target-error'\n      },\n      pathRewrite: (path) => {\n        // eslint-disable-next-line no-useless-escape\n        const sandboxId = path.match(/^\\/api\\/toolbox\\/([^\\/]+)\\/toolbox/)?.[1]\n        const routePath = path.split(`/api/toolbox/${sandboxId}/toolbox`)[1]\n        const newPath = `/sandboxes/${sandboxId}/toolbox${routePath}`\n\n        // Handle files path which is served on /files/ in the daemon\n        // TODO: Circle back to this after daemon versioning\n        // We can then switch /files/ to /files and only perform this for older daemon versions\n        const url = new URL(`http://runner${newPath}`)\n        if (url.pathname.endsWith('/files')) {\n          url.pathname = url.pathname + '/'\n          return url.toString().replace('http://runner', '')\n        }\n\n        return newPath\n      },\n      changeOrigin: true,\n      autoRewrite: true,\n      proxyTimeout: 5 * 60 * 1000,\n      on: {\n        proxyReq: (proxyReq, req, res) => {\n          // @ts-expect-error - set when routing\n          if (req._err) {\n            res.writeHead(400, { 'Content-Type': 'application/json' })\n            // @ts-expect-error - set when routing\n            res.end(JSON.stringify(req._err))\n            return\n          }\n\n          // @ts-expect-error - set when routing\n          const runnerApiKey = req._runnerApiKey\n\n          try {\n            proxyReq.setHeader('Authorization', `Bearer ${runnerApiKey}`)\n          } catch {\n            // Ignore error - headers are already set\n            return\n          }\n          fixRequestBody(proxyReq, req)\n        },\n        proxyRes: (proxyRes, req, res) => {\n          // console.log('proxyRes', proxyRes)\n        },\n      },\n    }\n\n    this.toolboxProxy = createProxyMiddleware({\n      ...commonProxyOptions,\n      followRedirects: true,\n    })\n\n    this.toolboxStreamProxy = createProxyMiddleware({\n      ...commonProxyOptions,\n      followRedirects: false,\n    })\n  }\n\n  private async getRunnerInfo(sandboxId: string): Promise<RunnerInfo> {\n    let runnerInfo: RunnerInfo | null = null\n    try {\n      const cached: { value: RunnerInfo } = JSON.parse(await this.redis.get(`${RUNNER_INFO_CACHE_PREFIX}${sandboxId}`))\n      runnerInfo = cached.value\n    } catch {\n      // Ignore error and fetch from db\n    }\n\n    if (!runnerInfo) {\n      const runner = await this.toolboxService.getRunner(sandboxId)\n      if (!runner.proxyUrl) {\n        throw new BadRequestException('Runner proxy URL not found')\n      }\n\n      runnerInfo = {\n        apiKey: runner.apiKey,\n        apiUrl: runner.proxyUrl,\n      }\n      await this.redis.set(\n        `${RUNNER_INFO_CACHE_PREFIX}${sandboxId}`,\n        JSON.stringify({ value: runnerInfo }),\n        'EX',\n        RUNNER_INFO_CACHE_TTL,\n      )\n    }\n\n    return runnerInfo\n  }\n\n  @Get(':sandboxId/toolbox/project-dir')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get sandbox project dir',\n    operationId: 'getProjectDir_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Project directory retrieved successfully',\n    type: ProjectDirResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getProjectDir(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/user-home-dir')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get sandbox user home dir',\n    operationId: 'getUserHomeDir_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'User home directory retrieved successfully',\n    type: UserHomeDirResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getUserHomeDir(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/work-dir')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get sandbox work-dir',\n    operationId: 'getWorkDir_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Work-dir retrieved successfully',\n    type: WorkDirResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getWorkDir(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/files')\n  @ApiOperation({\n    summary: '[DEPRECATED] List files',\n    operationId: 'listFiles_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Files listed successfully',\n    type: [FileInfoDto],\n  })\n  @ApiQuery({ name: 'path', type: String, required: false })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async listFiles(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Delete(':sandboxId/toolbox/files')\n  @ApiOperation({\n    summary: '[DEPRECATED] Delete file',\n    description: 'Delete file inside sandbox',\n    operationId: 'deleteFile_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'File deleted successfully',\n  })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiQuery({ name: 'recursive', type: Boolean, required: false })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_DELETE_FILE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      query: (req) => ({\n        path: req.query.path,\n      }),\n    },\n  })\n  async deleteFile(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/files/download')\n  @ApiOperation({\n    summary: '[DEPRECATED] Download file',\n    description: 'Download file from sandbox',\n    operationId: 'downloadFile_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'File downloaded successfully',\n    schema: {\n      type: 'string',\n      format: 'binary',\n    },\n  })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_DOWNLOAD_FILE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      query: (req) => ({\n        path: req.query.path,\n      }),\n    },\n  })\n  async downloadFile(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/files/bulk-download')\n  @ApiOperation({\n    summary: '[DEPRECATED] Download multiple files',\n    description: 'Streams back a multipart/form-data bundle of the requested paths',\n    operationId: 'downloadFiles_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'A multipart/form-data response with each file as a part',\n    schema: {\n      type: 'string',\n      format: 'binary',\n    },\n  })\n  @ApiBody({\n    type: DownloadFilesDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async downloadFiles(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/files/find')\n  @ApiOperation({\n    summary: '[DEPRECATED] Search for text/pattern in files',\n    description: 'Search for text/pattern inside sandbox files',\n    operationId: 'findInFiles_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Search completed successfully',\n    type: [MatchDto],\n  })\n  @ApiQuery({ name: 'pattern', type: String, required: true })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async findInFiles(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/files/folder')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Create folder',\n    description: 'Create folder inside sandbox',\n    operationId: 'createFolder_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Folder created successfully',\n  })\n  @ApiQuery({ name: 'mode', type: String, required: true })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_CREATE_FOLDER,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      query: (req) => ({\n        path: req.query.path,\n        mode: req.query.mode,\n      }),\n    },\n  })\n  async createFolder(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/files/info')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get file info',\n    description: 'Get file info inside sandbox',\n    operationId: 'getFileInfo_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'File info retrieved successfully',\n    type: FileInfoDto,\n  })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getFileInfo(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/files/move')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Move file',\n    description: 'Move file inside sandbox',\n    operationId: 'moveFile_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'File moved successfully',\n  })\n  @ApiQuery({ name: 'destination', type: String, required: true })\n  @ApiQuery({ name: 'source', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_MOVE_FILE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      query: (req) => ({\n        destination: req.query.destination,\n        source: req.query.source,\n      }),\n    },\n  })\n  async moveFile(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/files/permissions')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Set file permissions',\n    description: 'Set file owner/group/permissions inside sandbox',\n    operationId: 'setFilePermissions_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'File permissions updated successfully',\n  })\n  @ApiQuery({ name: 'mode', type: String, required: false })\n  @ApiQuery({ name: 'group', type: String, required: false })\n  @ApiQuery({ name: 'owner', type: String, required: false })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_SET_FILE_PERMISSIONS,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      query: (req) => ({\n        mode: req.query.mode,\n        group: req.query.group,\n        owner: req.query.owner,\n        path: req.query.path,\n      }),\n    },\n  })\n  async setFilePermissions(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/files/replace')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Replace in files',\n    description: 'Replace text/pattern in multiple files inside sandbox',\n    operationId: 'replaceInFiles_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Text replaced successfully',\n    type: [ReplaceResultDto],\n  })\n  @ApiBody({\n    type: ReplaceRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_REPLACE_IN_FILES,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<ReplaceRequestDto>) => ({\n        files: req.body?.files,\n        pattern: req.body?.pattern,\n        newValue: req.body?.newValue,\n      }),\n    },\n  })\n  async replaceInFiles(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/files/search')\n  @ApiOperation({\n    summary: '[DEPRECATED] Search files',\n    description: 'Search for files inside sandbox',\n    operationId: 'searchFiles_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Search completed successfully',\n    type: SearchFilesResponseDto,\n  })\n  @ApiQuery({ name: 'pattern', type: String, required: true })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async searchFiles(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @HttpCode(200)\n  @Post(':sandboxId/toolbox/files/upload')\n  @ApiOperation({\n    summary: '[DEPRECATED] Upload file',\n    description: 'Upload file inside sandbox',\n    operationId: 'uploadFile_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'File uploaded successfully',\n  })\n  @ApiConsumes('multipart/form-data')\n  @ApiBody({\n    schema: {\n      type: 'object',\n      properties: {\n        file: {\n          type: 'string',\n          format: 'binary',\n        },\n      },\n    },\n  })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_UPLOAD_FILE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      query: (req) => ({\n        path: req.query.path,\n      }),\n    },\n  })\n  async uploadFile(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return this.toolboxProxy(req, res, next)\n  }\n\n  @HttpCode(200)\n  @Post(':sandboxId/toolbox/files/bulk-upload')\n  @ApiOperation({\n    summary: '[DEPRECATED] Upload multiple files',\n    description: 'Upload multiple files inside sandbox',\n    operationId: 'uploadFiles_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Files uploaded successfully',\n  })\n  @ApiConsumes('multipart/form-data')\n  @ApiBody({ type: [UploadFileDto] })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_BULK_UPLOAD_FILES,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n  })\n  async uploadFiles(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return this.toolboxStreamProxy(req, res, next)\n  }\n\n  // Git operations\n  @Post(':sandboxId/toolbox/git/add')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Add files',\n    description: 'Add files to git commit',\n    operationId: 'gitAddFiles_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Files added to git successfully',\n  })\n  @ApiBody({\n    type: GitAddRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_GIT_ADD_FILES,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<GitAddRequestDto>) => ({\n        path: req.body?.path,\n        files: req.body?.files,\n      }),\n    },\n  })\n  async gitAddFiles(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/git/branches')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get branch list',\n    description: 'Get branch list from git repository',\n    operationId: 'gitListBranches_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Branch list retrieved successfully',\n    type: ListBranchResponseDto,\n  })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async gitBranchList(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/git/branches')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Create branch',\n    description: 'Create branch on git repository',\n    operationId: 'gitCreateBranch_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Branch created successfully',\n  })\n  @ApiBody({\n    type: GitBranchRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_GIT_CREATE_BRANCH,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<GitBranchRequestDto>) => ({\n        path: req.body?.path,\n        name: req.body?.name,\n      }),\n    },\n  })\n  async gitCreateBranch(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Delete(':sandboxId/toolbox/git/branches')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Delete branch',\n    description: 'Delete branch on git repository',\n    operationId: 'gitDeleteBranch_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Branch deleted successfully',\n  })\n  @ApiBody({\n    type: GitDeleteBranchRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_GIT_DELETE_BRANCH,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<GitDeleteBranchRequestDto>) => ({\n        path: req.body?.path,\n        name: req.body?.name,\n      }),\n    },\n  })\n  async gitDeleteBranch(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/git/clone')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Clone repository',\n    description: 'Clone git repository',\n    operationId: 'gitCloneRepository_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Repository cloned successfully',\n  })\n  @ApiBody({\n    type: GitCloneRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_GIT_CLONE_REPOSITORY,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<GitCloneRequestDto>) => ({\n        url: req.body?.url,\n        path: req.body?.path,\n        username: req.body?.username,\n        password: req.body?.password ? MASKED_AUDIT_VALUE : undefined,\n        branch: req.body?.branch,\n        commit_id: req.body?.commit_id,\n      }),\n    },\n  })\n  async gitCloneRepository(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/git/commit')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Commit changes',\n    description: 'Commit changes to git repository',\n    operationId: 'gitCommitChanges_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Changes committed successfully',\n    type: GitCommitResponseDto,\n  })\n  @ApiBody({\n    type: GitCommitRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_GIT_COMMIT_CHANGES,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<GitCommitRequestDto>) => ({\n        path: req.body?.path,\n        message: req.body?.message,\n        author: req.body?.author,\n        email: req.body?.email,\n        allow_empty: req.body?.allow_empty,\n      }),\n    },\n  })\n  async gitCommitChanges(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/git/history')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get commit history',\n    description: 'Get commit history from git repository',\n    operationId: 'gitGetHistory_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Commit history retrieved successfully',\n    type: [GitCommitInfoDto],\n  })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async gitCommitHistory(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/git/pull')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Pull changes',\n    description: 'Pull changes from remote',\n    operationId: 'gitPullChanges_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Changes pulled successfully',\n  })\n  @ApiBody({\n    type: GitRepoRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_GIT_PULL_CHANGES,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<GitRepoRequestDto>) => ({\n        path: req.body?.path,\n        username: req.body?.username,\n        password: req.body?.password ? MASKED_AUDIT_VALUE : undefined,\n      }),\n    },\n  })\n  async gitPullChanges(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/git/push')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Push changes',\n    description: 'Push changes to remote',\n    operationId: 'gitPushChanges_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Changes pushed successfully',\n  })\n  @ApiBody({\n    type: GitRepoRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_GIT_PUSH_CHANGES,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<GitRepoRequestDto>) => ({\n        path: req.body?.path,\n        username: req.body?.username,\n        password: req.body?.password ? MASKED_AUDIT_VALUE : undefined,\n      }),\n    },\n  })\n  async gitPushChanges(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/git/checkout')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Checkout branch',\n    description: 'Checkout branch or commit in git repository',\n    operationId: 'gitCheckoutBranch_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Branch checked out successfully',\n  })\n  @ApiBody({\n    type: GitCheckoutRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_GIT_CHECKOUT_BRANCH,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<GitCheckoutRequestDto>) => ({\n        path: req.body?.path,\n        branch: req.body?.branch,\n      }),\n    },\n  })\n  async gitCheckoutBranch(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/git/status')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get git status',\n    description: 'Get status from git repository',\n    operationId: 'gitGetStatus_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Git status retrieved successfully',\n    type: GitStatusDto,\n  })\n  @ApiQuery({ name: 'path', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async gitStatus(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/process/execute')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Execute command',\n    description: 'Execute command synchronously inside sandbox',\n    operationId: 'executeCommand_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Command executed successfully',\n    type: ExecuteResponseDto,\n  })\n  @Audit({\n    action: AuditAction.TOOLBOX_EXECUTE_COMMAND,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<ExecuteRequestDto>) => ({\n        command: req.body?.command,\n        cwd: req.body?.cwd,\n        timeout: req.body?.timeout,\n      }),\n    },\n  })\n  async executeCommand(\n    @Param('sandboxId') sandboxId: string,\n    @Body() executeRequest: ExecuteRequestDto,\n  ): Promise<ExecuteResponseDto> {\n    const response = await this.toolboxService.forwardRequestToRunner(\n      sandboxId,\n      'POST',\n      '/toolbox/process/execute',\n      executeRequest,\n    )\n\n    // TODO: use new proxy - can't use it now because of this\n    return {\n      exitCode: response.exitCode ?? response.code,\n      result: response.result,\n    }\n  }\n\n  // Session management endpoints\n  @Get(':sandboxId/toolbox/process/session')\n  @ApiOperation({\n    summary: '[DEPRECATED] List sessions',\n    description: 'List all active sessions in the sandbox',\n    operationId: 'listSessions_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Sessions retrieved successfully',\n    type: [SessionDto],\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async listSessions(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/process/session/:sessionId')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get session',\n    description: 'Get session by ID',\n    operationId: 'getSession_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Session retrieved successfully',\n    type: SessionDto,\n  })\n  @ApiParam({ name: 'sessionId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getSession(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/process/session')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Create session',\n    description: 'Create a new session in the sandbox',\n    operationId: 'createSession_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n  })\n  @ApiBody({\n    type: CreateSessionRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_CREATE_SESSION,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateSessionRequestDto>) => ({\n        sessionId: req.body?.sessionId,\n      }),\n    },\n  })\n  async createSession(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/process/session/:sessionId/exec')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Execute command in session',\n    description: 'Execute a command in a specific session',\n    operationId: 'executeSessionCommand_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Command executed successfully',\n    type: SessionExecuteResponseDto,\n  })\n  @ApiResponse({\n    status: 202,\n    description: 'Command accepted and is being processed',\n    type: SessionExecuteResponseDto,\n  })\n  @ApiBody({\n    type: SessionExecuteRequestDto,\n  })\n  @ApiParam({ name: 'sessionId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_SESSION_EXECUTE_COMMAND,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      params: (req) => ({\n        sessionId: req.params.sessionId,\n      }),\n      body: (req: TypedRequest<SessionExecuteRequestDto>) => ({\n        command: req.body?.command,\n        runAsync: req.body?.runAsync,\n        async: req.body?.async,\n      }),\n    },\n  })\n  async executeSessionCommand(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Delete(':sandboxId/toolbox/process/session/:sessionId')\n  @ApiOperation({\n    summary: '[DEPRECATED] Delete session',\n    description: 'Delete a specific session',\n    operationId: 'deleteSession_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Session deleted successfully',\n  })\n  @ApiParam({ name: 'sessionId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_DELETE_SESSION,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      params: (req) => ({\n        sessionId: req.params.sessionId,\n      }),\n    },\n  })\n  async deleteSession(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/process/session/:sessionId/command/:commandId')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get session command',\n    description: 'Get session command by ID',\n    operationId: 'getSessionCommand_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Session command retrieved successfully',\n    type: CommandDto,\n  })\n  @ApiParam({ name: 'commandId', type: String, required: true })\n  @ApiParam({ name: 'sessionId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getSessionCommand(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/process/session/:sessionId/command/:commandId/logs')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get command logs',\n    description: 'Get logs for a specific command in a session',\n    operationId: 'getSessionCommandLogs_deprecated',\n    deprecated: true,\n  })\n  // When follow is true, the response is an octet stream\n  @ApiResponse({\n    status: 200,\n    description: 'Command log stream marked with stdout and stderr prefixes',\n    content: {\n      'text/plain': {\n        schema: {\n          type: 'string',\n        },\n      },\n    },\n  })\n  @ApiQuery({ name: 'follow', type: Boolean, required: false, description: 'Whether to stream the logs' })\n  @ApiParam({ name: 'commandId', type: String, required: true })\n  @ApiParam({ name: 'sessionId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getSessionCommandLogs(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return this.toolboxProxy(req, res, next)\n  }\n\n  // PTY endpoints\n  @Get(':sandboxId/toolbox/process/pty')\n  @ApiOperation({\n    summary: '[DEPRECATED] List PTY sessions',\n    description: 'List all active PTY sessions in the sandbox',\n    operationId: 'listPTYSessions_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'PTY sessions retrieved successfully',\n    type: PtyListResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async listPtySessions(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/process/pty')\n  @HttpCode(201)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Create PTY session',\n    description: 'Create a new PTY session in the sandbox',\n    operationId: 'createPTYSession_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 201,\n    description: 'PTY session created successfully',\n    type: PtyCreateResponseDto,\n  })\n  @ApiBody({\n    type: PtyCreateRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async createPtySession(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/process/pty/:sessionId')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get PTY session',\n    description: 'Get PTY session information by ID',\n    operationId: 'getPTYSession_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'PTY session retrieved successfully',\n    type: PtySessionInfoDto,\n  })\n  @ApiParam({ name: 'sessionId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getPtySession(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/process/pty/:sessionId/resize')\n  @ApiOperation({\n    summary: '[DEPRECATED] Resize PTY session',\n    description: 'Resize a PTY session',\n    operationId: 'resizePTYSession_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'PTY session resized successfully',\n    type: PtySessionInfoDto,\n  })\n  @ApiParam({ name: 'sessionId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @ApiBody({\n    type: PtyResizeRequestDto,\n  })\n  async resizePtySession(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Delete(':sandboxId/toolbox/process/pty/:sessionId')\n  @ApiOperation({\n    summary: '[DEPRECATED] Delete PTY session',\n    description: 'Delete a PTY session and terminate the associated process',\n    operationId: 'deletePTYSession_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'PTY session deleted successfully',\n  })\n  @ApiParam({ name: 'sessionId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async deletePtySession(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/lsp/completions')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Get Lsp Completions',\n    description:\n      'The Completion request is sent from the client to the server to compute completion items at a given cursor position.',\n    operationId: 'LspCompletions_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'OK',\n    type: CompletionListDto,\n  })\n  @ApiBody({\n    type: LspCompletionParamsDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getLspCompletions(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/lsp/did-close')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Call Lsp DidClose',\n    description:\n      'The document close notification is sent from the client to the server when the document got closed in the client.',\n    operationId: 'LspDidClose_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'OK',\n  })\n  @ApiBody({\n    type: LspDocumentRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async lspDidClose(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/lsp/did-open')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Call Lsp DidOpen',\n    description:\n      'The document open notification is sent from the client to the server to signal newly opened text documents.',\n    operationId: 'LspDidOpen_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'OK',\n  })\n  @ApiBody({\n    type: LspDocumentRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async lspDidOpen(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/lsp/document-symbols')\n  @ApiOperation({\n    summary: '[DEPRECATED] Call Lsp DocumentSymbols',\n    description: 'The document symbol request is sent from the client to the server.',\n    operationId: 'LspDocumentSymbols_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'OK',\n    type: [LspSymbolDto],\n  })\n  @ApiQuery({ name: 'uri', type: String, required: true })\n  @ApiQuery({ name: 'pathToProject', type: String, required: true })\n  @ApiQuery({ name: 'languageId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getLspDocumentSymbols(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/lsp/start')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Start Lsp server',\n    description: 'Start Lsp server process inside sandbox project',\n    operationId: 'LspStart_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'OK',\n  })\n  @ApiBody({\n    type: LspServerRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async startLspServer(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/lsp/stop')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Stop Lsp server',\n    description: 'Stop Lsp server process inside sandbox project',\n    operationId: 'LspStop_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'OK',\n  })\n  @ApiBody({\n    type: LspServerRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async stopLspServer(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/lsp/workspace-symbols')\n  @ApiOperation({\n    summary: '[DEPRECATED] Call Lsp WorkspaceSymbols',\n    description:\n      'The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.',\n    operationId: 'LspWorkspaceSymbols_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'OK',\n    type: [LspSymbolDto],\n  })\n  @ApiQuery({ name: 'query', type: String, required: true })\n  @ApiQuery({ name: 'pathToProject', type: String, required: true })\n  @ApiQuery({ name: 'languageId', type: String, required: true })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getLspWorkspaceSymbols(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  // Computer Use endpoints\n\n  // Computer use management endpoints\n  @Post(':sandboxId/toolbox/computeruse/start')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Start computer use processes',\n    description: 'Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)',\n    operationId: 'startComputerUse_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Computer use processes started successfully',\n    type: ComputerUseStartResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_COMPUTER_USE_START,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n  })\n  async startComputerUse(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/computeruse/stop')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Stop computer use processes',\n    description: 'Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)',\n    operationId: 'stopComputerUse_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Computer use processes stopped successfully',\n    type: ComputerUseStopResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_COMPUTER_USE_STOP,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n  })\n  async stopComputerUse(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/computeruse/status')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get computer use status',\n    description: 'Get status of all VNC desktop processes',\n    operationId: 'getComputerUseStatus_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Computer use status retrieved successfully',\n    type: ComputerUseStatusResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getComputerUseStatus(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/computeruse/process/:processName/status')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get process status',\n    description: 'Get status of a specific VNC process',\n    operationId: 'getProcessStatus_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Process status retrieved successfully',\n    type: ProcessStatusResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @ApiParam({ name: 'processName', type: String, required: true })\n  async getProcessStatus(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/computeruse/process/:processName/restart')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Restart process',\n    description: 'Restart a specific VNC process',\n    operationId: 'restartProcess_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Process restarted successfully',\n    type: ProcessRestartResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @ApiParam({ name: 'processName', type: String, required: true })\n  @Audit({\n    action: AuditAction.TOOLBOX_COMPUTER_USE_RESTART_PROCESS,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.sandboxId,\n    requestMetadata: {\n      params: (req) => ({\n        processName: req.params.processName,\n      }),\n    },\n  })\n  async restartProcess(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/computeruse/process/:processName/logs')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get process logs',\n    description: 'Get logs for a specific VNC process',\n    operationId: 'getProcessLogs_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Process logs retrieved successfully',\n    type: ProcessLogsResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @ApiParam({ name: 'processName', type: String, required: true })\n  async getProcessLogs(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/computeruse/process/:processName/errors')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get process errors',\n    description: 'Get error logs for a specific VNC process',\n    operationId: 'getProcessErrors_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Process errors retrieved successfully',\n    type: ProcessErrorsResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  @ApiParam({ name: 'processName', type: String, required: true })\n  async getProcessErrors(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  // Mouse endpoints\n  @Get(':sandboxId/toolbox/computeruse/mouse/position')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get mouse position',\n    description: 'Get current mouse cursor position',\n    operationId: 'getMousePosition_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Mouse position retrieved successfully',\n    type: MousePositionDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getMousePosition(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/computeruse/mouse/move')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Move mouse',\n    description: 'Move mouse cursor to specified coordinates',\n    operationId: 'moveMouse_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Mouse moved successfully',\n    type: MouseMoveResponseDto,\n  })\n  @ApiBody({\n    type: MouseMoveRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async moveMouse(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/computeruse/mouse/click')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Click mouse',\n    description: 'Click mouse at specified coordinates',\n    operationId: 'clickMouse_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Mouse clicked successfully',\n    type: MouseClickResponseDto,\n  })\n  @ApiBody({\n    type: MouseClickRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async clickMouse(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/computeruse/mouse/drag')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Drag mouse',\n    description: 'Drag mouse from start to end coordinates',\n    operationId: 'dragMouse_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Mouse dragged successfully',\n    type: MouseDragResponseDto,\n  })\n  @ApiBody({\n    type: MouseDragRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async dragMouse(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/computeruse/mouse/scroll')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Scroll mouse',\n    description: 'Scroll mouse at specified coordinates',\n    operationId: 'scrollMouse_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Mouse scrolled successfully',\n    type: MouseScrollResponseDto,\n  })\n  @ApiBody({\n    type: MouseScrollRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async scrollMouse(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  // Keyboard endpoints\n  @Post(':sandboxId/toolbox/computeruse/keyboard/type')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Type text',\n    description: 'Type text using keyboard',\n    operationId: 'typeText_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Text typed successfully',\n  })\n  @ApiBody({\n    type: KeyboardTypeRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async typeText(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/computeruse/keyboard/key')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Press key',\n    description: 'Press a key with optional modifiers',\n    operationId: 'pressKey_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Key pressed successfully',\n  })\n  @ApiBody({\n    type: KeyboardPressRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async pressKey(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Post(':sandboxId/toolbox/computeruse/keyboard/hotkey')\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Press hotkey',\n    description: 'Press a hotkey combination',\n    operationId: 'pressHotkey_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Hotkey pressed successfully',\n  })\n  @ApiBody({\n    type: KeyboardHotkeyRequestDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async pressHotkey(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  // Screenshot endpoints\n  @Get(':sandboxId/toolbox/computeruse/screenshot')\n  @ApiOperation({\n    summary: '[DEPRECATED] Take screenshot',\n    description: 'Take a screenshot of the entire screen',\n    operationId: 'takeScreenshot_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Screenshot taken successfully',\n    type: ScreenshotResponseDto,\n  })\n  @ApiQuery({ name: 'show_cursor', type: Boolean, required: false })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async takeScreenshot(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/computeruse/screenshot/region')\n  @ApiOperation({\n    summary: '[DEPRECATED] Take region screenshot',\n    description: 'Take a screenshot of a specific region',\n    operationId: 'takeRegionScreenshot_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Region screenshot taken successfully',\n    type: RegionScreenshotResponseDto,\n  })\n  @ApiQuery({ name: 'x', type: Number, required: true })\n  @ApiQuery({ name: 'y', type: Number, required: true })\n  @ApiQuery({ name: 'width', type: Number, required: true })\n  @ApiQuery({ name: 'height', type: Number, required: true })\n  @ApiQuery({ name: 'show_cursor', type: Boolean, required: false })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async takeRegionScreenshot(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/computeruse/screenshot/compressed')\n  @ApiOperation({\n    summary: '[DEPRECATED] Take compressed screenshot',\n    description: 'Take a compressed screenshot with format, quality, and scale options',\n    operationId: 'takeCompressedScreenshot_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Compressed screenshot taken successfully',\n    type: CompressedScreenshotResponseDto,\n  })\n  @ApiQuery({ name: 'show_cursor', type: Boolean, required: false })\n  @ApiQuery({ name: 'format', type: String, required: false })\n  @ApiQuery({ name: 'quality', type: Number, required: false })\n  @ApiQuery({ name: 'scale', type: Number, required: false })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async takeCompressedScreenshot(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/computeruse/screenshot/region/compressed')\n  @ApiOperation({\n    summary: '[DEPRECATED] Take compressed region screenshot',\n    description: 'Take a compressed screenshot of a specific region',\n    operationId: 'takeCompressedRegionScreenshot_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Compressed region screenshot taken successfully',\n    type: CompressedScreenshotResponseDto,\n  })\n  @ApiQuery({ name: 'x', type: Number, required: true })\n  @ApiQuery({ name: 'y', type: Number, required: true })\n  @ApiQuery({ name: 'width', type: Number, required: true })\n  @ApiQuery({ name: 'height', type: Number, required: true })\n  @ApiQuery({ name: 'show_cursor', type: Boolean, required: false })\n  @ApiQuery({ name: 'format', type: String, required: false })\n  @ApiQuery({ name: 'quality', type: Number, required: false })\n  @ApiQuery({ name: 'scale', type: Number, required: false })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async takeCompressedRegionScreenshot(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  // Display endpoints\n  @Get(':sandboxId/toolbox/computeruse/display/info')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get display info',\n    description: 'Get information about displays',\n    operationId: 'getDisplayInfo_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Display info retrieved successfully',\n    type: DisplayInfoResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getDisplayInfo(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n\n  @Get(':sandboxId/toolbox/computeruse/display/windows')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get windows',\n    description: 'Get list of open windows',\n    operationId: 'getWindows_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Windows list retrieved successfully',\n    type: WindowsResponseDto,\n  })\n  @ApiParam({ name: 'sandboxId', type: String, required: true })\n  async getWindows(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n  ): Promise<void> {\n    return await this.toolboxProxy(req, res, next)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/controllers/volume.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Controller,\n  Get,\n  Post,\n  Delete,\n  Body,\n  Param,\n  Logger,\n  UseGuards,\n  HttpCode,\n  UseInterceptors,\n  Query,\n} from '@nestjs/common'\nimport {\n  ApiOAuth2,\n  ApiResponse,\n  ApiOperation,\n  ApiParam,\n  ApiTags,\n  ApiHeader,\n  ApiQuery,\n  ApiBearerAuth,\n} from '@nestjs/swagger'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { VolumeService } from '../services/volume.service'\nimport { CreateVolumeDto } from '../dto/create-volume.dto'\nimport { ContentTypeInterceptor } from '../../common/interceptors/content-type.interceptors'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { RequiredOrganizationResourcePermissions } from '../../organization/decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { VolumeDto } from '../dto/volume.dto'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { VolumeAccessGuard } from '../guards/volume-access.guard'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('volumes')\n@Controller('volumes')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class VolumeController {\n  private readonly logger = new Logger(VolumeController.name)\n\n  constructor(private readonly volumeService: VolumeService) {}\n\n  @Get()\n  @ApiOperation({\n    summary: 'List all volumes',\n    operationId: 'listVolumes',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of all volumes',\n    type: [VolumeDto],\n  })\n  @ApiQuery({\n    name: 'includeDeleted',\n    required: false,\n    type: Boolean,\n    description: 'Include deleted volumes in the response',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.READ_VOLUMES])\n  async listVolumes(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Query('includeDeleted') includeDeleted = false,\n  ): Promise<VolumeDto[]> {\n    const volumes = await this.volumeService.findAll(authContext.organizationId, includeDeleted)\n    return volumes.map(VolumeDto.fromVolume)\n  }\n\n  @Post()\n  @HttpCode(200)\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: 'Create a new volume',\n    operationId: 'createVolume',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The volume has been successfully created.',\n    type: VolumeDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_VOLUMES])\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.VOLUME,\n    targetIdFromResult: (result: VolumeDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateVolumeDto>) => ({\n        name: req.body?.name,\n      }),\n    },\n  })\n  async createVolume(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Body() createVolumeDto: CreateVolumeDto,\n  ): Promise<VolumeDto> {\n    const volume = await this.volumeService.create(authContext.organization, createVolumeDto)\n    return VolumeDto.fromVolume(volume)\n  }\n\n  @Get(':volumeId')\n  @ApiOperation({\n    summary: 'Get volume details',\n    operationId: 'getVolume',\n  })\n  @ApiParam({\n    name: 'volumeId',\n    description: 'ID of the volume',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Volume details',\n    type: VolumeDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.READ_VOLUMES])\n  @UseGuards(VolumeAccessGuard)\n  async getVolume(@Param('volumeId') volumeId: string): Promise<VolumeDto> {\n    const volume = await this.volumeService.findOne(volumeId)\n    return VolumeDto.fromVolume(volume)\n  }\n\n  @Delete(':volumeId')\n  @ApiOperation({\n    summary: 'Delete volume',\n    operationId: 'deleteVolume',\n  })\n  @ApiParam({\n    name: 'volumeId',\n    description: 'ID of the volume',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Volume has been marked for deletion',\n  })\n  @ApiResponse({\n    status: 409,\n    description: 'Volume is in use by one or more sandboxes',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.DELETE_VOLUMES])\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.VOLUME,\n    targetIdFromRequest: (req) => req.params.volumeId,\n  })\n  @UseGuards(VolumeAccessGuard)\n  async deleteVolume(@Param('volumeId') volumeId: string): Promise<void> {\n    return this.volumeService.delete(volumeId)\n  }\n\n  @Get('by-name/:name')\n  @ApiOperation({\n    summary: 'Get volume details by name',\n    operationId: 'getVolumeByName',\n  })\n  @ApiParam({\n    name: 'name',\n    description: 'Name of the volume',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Volume details',\n    type: VolumeDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.READ_VOLUMES])\n  @UseGuards(VolumeAccessGuard)\n  async getVolumeByName(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('name') name: string,\n  ): Promise<VolumeDto> {\n    const volume = await this.volumeService.findByName(authContext.organizationId, name)\n    return VolumeDto.fromVolume(volume)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/controllers/workspace.deprecated.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Controller,\n  Get,\n  Post,\n  Delete,\n  Body,\n  Param,\n  Query,\n  Logger,\n  UseGuards,\n  HttpCode,\n  UseInterceptors,\n  Put,\n  NotFoundException,\n  ForbiddenException,\n  Res,\n  Request,\n  RawBodyRequest,\n  Next,\n  ParseBoolPipe,\n} from '@nestjs/common'\nimport Redis from 'ioredis'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { SandboxService as WorkspaceService } from '../services/sandbox.service'\nimport {\n  ApiOAuth2,\n  ApiResponse,\n  ApiQuery,\n  ApiOperation,\n  ApiParam,\n  ApiTags,\n  ApiHeader,\n  ApiBearerAuth,\n} from '@nestjs/swagger'\nimport { SandboxLabelsDto as WorkspaceLabelsDto } from '../dto/sandbox.dto'\nimport { WorkspaceDto } from '../dto/workspace.deprecated.dto'\nimport { RunnerService } from '../services/runner.service'\nimport { SandboxState as WorkspaceState } from '../enums/sandbox-state.enum'\nimport { ContentTypeInterceptor } from '../../common/interceptors/content-type.interceptors'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { SandboxAccessGuard as WorkspaceAccessGuard } from '../guards/sandbox-access.guard'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { AuthContext } from '../../common/decorators/auth-context.decorator'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { RequiredOrganizationResourcePermissions } from '../../organization/decorators/required-organization-resource-permissions.decorator'\nimport { OrganizationResourcePermission } from '../../organization/enums/organization-resource-permission.enum'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { WorkspacePortPreviewUrlDto } from '../dto/workspace-port-preview-url.deprecated.dto'\nimport { IncomingMessage, ServerResponse } from 'http'\nimport { NextFunction } from 'http-proxy-middleware/dist/types'\nimport { LogProxy } from '../proxy/log-proxy'\nimport { CreateWorkspaceDto } from '../dto/create-workspace.deprecated.dto'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { Audit, MASKED_AUDIT_VALUE, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('workspace')\n@Controller('workspace')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class WorkspaceController {\n  private readonly logger = new Logger(WorkspaceController.name)\n\n  constructor(\n    @InjectRedis() private readonly redis: Redis,\n    private readonly runnerService: RunnerService,\n    private readonly workspaceService: WorkspaceService,\n    private readonly configService: TypedConfigService,\n  ) {}\n\n  @Get()\n  @ApiOperation({\n    summary: '[DEPRECATED] List all workspaces',\n    operationId: 'listWorkspaces_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of all workspacees',\n    type: [WorkspaceDto],\n  })\n  @ApiQuery({\n    name: 'verbose',\n    required: false,\n    type: Boolean,\n    description: 'Include verbose output',\n  })\n  @ApiQuery({\n    name: 'labels',\n    type: String,\n    required: false,\n    example: '{\"label1\": \"value1\", \"label2\": \"value2\"}',\n    description: 'JSON encoded labels to filter by',\n  })\n  async listWorkspacees(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Query('verbose') verbose?: boolean,\n    @Query('labels') labelsQuery?: string,\n  ): Promise<WorkspaceDto[]> {\n    const labels = labelsQuery ? JSON.parse(labelsQuery) : {}\n    const workspacees = await this.workspaceService.findAllDeprecated(authContext.organizationId, labels)\n    const dtos = workspacees.map(async (workspace) => {\n      const dto = WorkspaceDto.fromSandbox(workspace)\n      return dto\n    })\n    return await Promise.all(dtos)\n  }\n\n  @Post()\n  @HttpCode(200) //  for Daytona Api compatibility\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Create a new workspace',\n    operationId: 'createWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'The workspace has been successfully created.',\n    type: WorkspaceDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromResult: (result: WorkspaceDto) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateWorkspaceDto>) => ({\n        image: req.body?.image,\n        user: req.body?.user,\n        env: req.body?.env\n          ? Object.fromEntries(Object.keys(req.body?.env).map((key) => [key, MASKED_AUDIT_VALUE]))\n          : undefined,\n        labels: req.body?.labels,\n        public: req.body?.public,\n        class: req.body?.class,\n        target: req.body?.target,\n        cpu: req.body?.cpu,\n        gpu: req.body?.gpu,\n        memory: req.body?.memory,\n        disk: req.body?.disk,\n        autoStopInterval: req.body?.autoStopInterval,\n        autoArchiveInterval: req.body?.autoArchiveInterval,\n        volumes: req.body?.volumes,\n        buildInfo: req.body?.buildInfo,\n      }),\n    },\n  })\n  async createWorkspace(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Body() createWorkspaceDto: CreateWorkspaceDto,\n  ): Promise<WorkspaceDto> {\n    if (createWorkspaceDto.buildInfo) {\n      throw new ForbiddenException('Build info is not supported in this deprecated API - please upgrade your client')\n    }\n\n    const organization = authContext.organization\n\n    const workspace = WorkspaceDto.fromSandboxDto(\n      await this.workspaceService.createFromSnapshot(\n        {\n          ...createWorkspaceDto,\n          snapshot: createWorkspaceDto.image,\n        },\n        organization,\n        true,\n      ),\n    )\n\n    // Wait for the workspace to start\n    const sandboxState = await this.waitForWorkspaceState(\n      workspace.id,\n      WorkspaceState.STARTED,\n      30000, // 30 seconds timeout\n    )\n    workspace.state = sandboxState\n\n    return workspace\n  }\n\n  @Get(':workspaceId')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get workspace details',\n    operationId: 'getWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiQuery({\n    name: 'verbose',\n    required: false,\n    type: Boolean,\n    description: 'Include verbose output',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Workspace details',\n    type: WorkspaceDto,\n  })\n  @UseGuards(WorkspaceAccessGuard)\n  async getWorkspace(\n    @Param('workspaceId') workspaceId: string,\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    @Query('verbose') verbose?: boolean,\n  ): Promise<WorkspaceDto> {\n    const workspace = await this.workspaceService.findOne(workspaceId, true)\n\n    return WorkspaceDto.fromSandbox(workspace)\n  }\n\n  @Delete(':workspaceId')\n  @ApiOperation({\n    summary: '[DEPRECATED] Delete workspace',\n    operationId: 'deleteWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Workspace has been deleted',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.DELETE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.DELETE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n  })\n  async removeWorkspace(\n    @Param('workspaceId') workspaceId: string,\n    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n    @Query('force') force?: boolean,\n  ): Promise<void> {\n    await this.workspaceService.destroy(workspaceId)\n  }\n\n  @Post(':workspaceId/start')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: '[DEPRECATED] Start workspace',\n    operationId: 'startWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Workspace has been started',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.START,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n  })\n  async startWorkspace(\n    @AuthContext() authContext: OrganizationAuthContext,\n    @Param('workspaceId') workspaceId: string,\n  ): Promise<void> {\n    await this.workspaceService.start(workspaceId, authContext.organization)\n  }\n\n  @Post(':workspaceId/stop')\n  @HttpCode(200) //  for Daytona Api compatibility\n  @ApiOperation({\n    summary: '[DEPRECATED] Stop workspace',\n    operationId: 'stopWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Workspace has been stopped',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.STOP,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n  })\n  async stopWorkspace(@Param('workspaceId') workspaceId: string): Promise<void> {\n    await this.workspaceService.stop(workspaceId)\n  }\n\n  @Put(':workspaceId/labels')\n  @UseInterceptors(ContentTypeInterceptor)\n  @ApiOperation({\n    summary: '[DEPRECATED] Replace workspace labels',\n    operationId: 'replaceLabelsWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Labels have been successfully replaced',\n    type: WorkspaceLabelsDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.REPLACE_LABELS,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n    requestMetadata: {\n      body: (req: TypedRequest<WorkspaceLabelsDto>) => ({\n        labels: req.body?.labels,\n      }),\n    },\n  })\n  async replaceLabels(\n    @Param('workspaceId') workspaceId: string,\n    @Body() labelsDto: WorkspaceLabelsDto,\n  ): Promise<WorkspaceLabelsDto> {\n    const { labels } = await this.workspaceService.replaceLabels(workspaceId, labelsDto.labels)\n    return { labels }\n  }\n\n  @Post(':workspaceId/backup')\n  @ApiOperation({\n    summary: '[DEPRECATED] Create workspace backup',\n    operationId: 'createBackupWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Workspace backup has been initiated',\n    type: WorkspaceDto,\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.CREATE_BACKUP,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n  })\n  async createBackup(@Param('workspaceId') workspaceId: string): Promise<void> {\n    await this.workspaceService.createBackup(workspaceId)\n  }\n\n  @Post(':workspaceId/public/:isPublic')\n  @ApiOperation({\n    summary: '[DEPRECATED] Update public status',\n    operationId: 'updatePublicStatusWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'isPublic',\n    description: 'Public status to set',\n    type: 'boolean',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.UPDATE_PUBLIC_STATUS,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n    requestMetadata: {\n      params: (req) => ({\n        isPublic: req.params.isPublic,\n      }),\n    },\n  })\n  async updatePublicStatus(\n    @Param('workspaceId') workspaceId: string,\n    @Param('isPublic') isPublic: boolean,\n  ): Promise<void> {\n    await this.workspaceService.updatePublicStatus(workspaceId, isPublic)\n  }\n\n  @Post(':workspaceId/autostop/:interval')\n  @ApiOperation({\n    summary: '[DEPRECATED] Set workspace auto-stop interval',\n    operationId: 'setAutostopIntervalWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'interval',\n    description: 'Auto-stop interval in minutes (0 to disable)',\n    type: 'number',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Auto-stop interval has been set',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.SET_AUTO_STOP_INTERVAL,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n    requestMetadata: {\n      params: (req) => ({\n        interval: req.params.interval,\n      }),\n    },\n  })\n  async setAutostopInterval(\n    @Param('workspaceId') workspaceId: string,\n    @Param('interval') interval: number,\n  ): Promise<void> {\n    await this.workspaceService.setAutostopInterval(workspaceId, interval)\n  }\n\n  @Post(':workspaceId/autoarchive/:interval')\n  @ApiOperation({\n    summary: '[DEPRECATED] Set workspace auto-archive interval',\n    operationId: 'setAutoArchiveIntervalWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'interval',\n    description: 'Auto-archive interval in minutes (0 means the maximum interval will be used)',\n    type: 'number',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Auto-archive interval has been set',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.SET_AUTO_ARCHIVE_INTERVAL,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n    requestMetadata: {\n      params: (req) => ({\n        interval: req.params.interval,\n      }),\n    },\n  })\n  async setAutoArchiveInterval(\n    @Param('workspaceId') workspaceId: string,\n    @Param('interval') interval: number,\n  ): Promise<void> {\n    await this.workspaceService.setAutoArchiveInterval(workspaceId, interval)\n  }\n\n  @Post(':workspaceId/archive')\n  @HttpCode(200)\n  @ApiOperation({\n    summary: '[DEPRECATED] Archive workspace',\n    operationId: 'archiveWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Workspace has been archived',\n  })\n  @RequiredOrganizationResourcePermissions([OrganizationResourcePermission.WRITE_SANDBOXES])\n  @UseGuards(WorkspaceAccessGuard)\n  @Audit({\n    action: AuditAction.ARCHIVE,\n    targetType: AuditTarget.SANDBOX,\n    targetIdFromRequest: (req) => req.params.workspaceId,\n  })\n  async archiveWorkspace(@Param('workspaceId') workspaceId: string): Promise<void> {\n    await this.workspaceService.archive(workspaceId)\n  }\n\n  @Get(':workspaceId/ports/:port/preview-url')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get preview URL for a workspace port',\n    operationId: 'getPortPreviewUrlWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'port',\n    description: 'Port number to get preview URL for',\n    type: 'number',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Preview URL for the specified port',\n    type: WorkspacePortPreviewUrlDto,\n  })\n  @UseGuards(WorkspaceAccessGuard)\n  async getPortPreviewUrl(\n    @Param('workspaceId') workspaceId: string,\n    @Param('port') port: number,\n  ): Promise<WorkspacePortPreviewUrlDto> {\n    if (port < 1 || port > 65535) {\n      throw new BadRequestError('Invalid port')\n    }\n\n    const proxyDomain = this.configService.getOrThrow('proxy.domain')\n    const proxyProtocol = this.configService.getOrThrow('proxy.protocol')\n    const workspace = await this.workspaceService.findOne(workspaceId)\n    if (!workspace) {\n      throw new NotFoundException(`Workspace with ID ${workspaceId} not found`)\n    }\n\n    return {\n      url: `${proxyProtocol}://${port}-${workspaceId}.${proxyDomain}`,\n      token: workspace.authToken,\n    }\n  }\n\n  @Get(':workspaceId/build-logs')\n  @ApiOperation({\n    summary: '[DEPRECATED] Get build logs',\n    operationId: 'getBuildLogsWorkspace_deprecated',\n    deprecated: true,\n  })\n  @ApiParam({\n    name: 'workspaceId',\n    description: 'ID of the workspace',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Build logs stream',\n  })\n  @ApiQuery({\n    name: 'follow',\n    required: false,\n    type: Boolean,\n    description: 'Whether to follow the logs stream',\n  })\n  @UseGuards(WorkspaceAccessGuard)\n  async getBuildLogs(\n    @Request() req: RawBodyRequest<IncomingMessage>,\n    @Res() res: ServerResponse<IncomingMessage>,\n    @Next() next: NextFunction,\n    @Param('workspaceId') workspaceId: string,\n    @Query('follow', new ParseBoolPipe({ optional: true })) follow?: boolean,\n  ): Promise<void> {\n    const workspace = await this.workspaceService.findOne(workspaceId)\n    if (!workspace || !workspace.runnerId) {\n      throw new NotFoundException(`Workspace with ID ${workspaceId} not found or has no runner assigned`)\n    }\n\n    if (!workspace.buildInfo) {\n      throw new NotFoundException(`Workspace with ID ${workspaceId} has no build info`)\n    }\n\n    const runner = await this.runnerService.findOneOrFail(workspace.runnerId)\n\n    if (!runner.apiUrl) {\n      throw new NotFoundException(`Runner for workspace ${workspaceId} has no API URL`)\n    }\n\n    const logProxy = new LogProxy(\n      runner.apiUrl,\n      workspace.buildInfo.snapshotRef.split(':')[0],\n      runner.apiKey,\n      follow === true,\n      req,\n      res,\n      next,\n    )\n    return logProxy.create()\n  }\n\n  private async waitForWorkspaceState(\n    workspaceId: string,\n    desiredState: WorkspaceState,\n    timeout: number,\n  ): Promise<WorkspaceState> {\n    const startTime = Date.now()\n\n    let workspaceState: WorkspaceState\n    while (Date.now() - startTime < timeout) {\n      const workspace = await this.workspaceService.findOne(workspaceId)\n      workspaceState = workspace.state\n      if (\n        workspaceState === desiredState ||\n        workspaceState === WorkspaceState.ERROR ||\n        workspaceState === WorkspaceState.BUILD_FAILED\n      ) {\n        return workspaceState\n      }\n      await new Promise((resolve) => setTimeout(resolve, 100)) // Wait 100 ms before checking again\n    }\n\n    return workspaceState\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/build-info.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'BuildInfo' })\nexport class BuildInfoDto {\n  @ApiPropertyOptional({\n    description: 'The Dockerfile content used for the build',\n    example: 'FROM node:14\\nWORKDIR /app\\nCOPY . .\\nRUN npm install\\nCMD [\"npm\", \"start\"]',\n  })\n  dockerfileContent?: string\n\n  @ApiPropertyOptional({\n    description: 'The context hashes used for the build',\n    type: [String],\n    example: ['hash1', 'hash2'],\n  })\n  contextHashes?: string[]\n\n  @ApiProperty({\n    description: 'The creation timestamp',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'The last update timestamp',\n  })\n  updatedAt: Date\n\n  @ApiProperty({\n    description: 'The snapshot reference',\n    example: 'daytonaio/sandbox:latest',\n  })\n  snapshotRef: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/create-build-info.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsNotEmpty, IsOptional, IsString } from 'class-validator'\n\n@ApiSchema({ name: 'CreateBuildInfo' })\nexport class CreateBuildInfoDto {\n  @ApiProperty({\n    description: 'The Dockerfile content used for the build',\n    example: 'FROM node:14\\nWORKDIR /app\\nCOPY . .\\nRUN npm install\\nCMD [\"npm\", \"start\"]',\n  })\n  @IsString()\n  @IsNotEmpty()\n  dockerfileContent: string\n\n  @ApiPropertyOptional({\n    description: 'The context hashes used for the build',\n    type: [String],\n    example: ['hash1', 'hash2'],\n  })\n  @IsString({ each: true })\n  @IsOptional()\n  contextHashes?: string[]\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/create-runner-internal.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type CreateRunnerV0InternalDto = {\n  domain: string\n  apiUrl: string\n  proxyUrl: string\n  cpu: number\n  memoryGiB: number\n  diskGiB: number\n  regionId: string\n  name: string\n  apiKey?: string\n  apiVersion: '0'\n  appVersion?: string\n}\n\nexport type CreateRunnerV2InternalDto = {\n  apiKey?: string\n  regionId: string\n  name: string\n  apiVersion: '2'\n  appVersion?: string\n}\n\nexport type CreateRunnerInternalDto = CreateRunnerV0InternalDto | CreateRunnerV2InternalDto\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/create-runner-response.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { Runner } from '../entities/runner.entity'\n\n@ApiSchema({ name: 'CreateRunnerResponse' })\nexport class CreateRunnerResponseDto {\n  @ApiProperty({\n    description: 'The ID of the runner',\n    example: 'runner123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'The API key for the runner',\n    example: 'dtn_1234567890',\n  })\n  apiKey: string\n\n  static fromRunner(runner: Runner, apiKey: string): CreateRunnerResponseDto {\n    return {\n      id: runner.id,\n      apiKey,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/create-runner.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsString } from 'class-validator'\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'CreateRunner' })\nexport class CreateRunnerDto {\n  @IsString()\n  @ApiProperty()\n  regionId: string\n\n  @IsString()\n  @ApiProperty()\n  name: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/create-sandbox.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsEnum, IsObject, IsOptional, IsString, IsNumber, IsBoolean, IsArray } from 'class-validator'\nimport { ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\nimport { SandboxVolume } from './sandbox.dto'\nimport { CreateBuildInfoDto } from './create-build-info.dto'\n\n@ApiSchema({ name: 'CreateSandbox' })\nexport class CreateSandboxDto {\n  @ApiPropertyOptional({\n    description: 'The name of the sandbox. If not provided, the sandbox ID will be used as the name',\n    example: 'MySandbox',\n  })\n  @IsOptional()\n  @IsString()\n  name?: string\n\n  @ApiPropertyOptional({\n    description: 'The ID or name of the snapshot used for the sandbox',\n    example: 'ubuntu-4vcpu-8ram-100gb',\n  })\n  @IsOptional()\n  @IsString()\n  snapshot?: string\n\n  @ApiPropertyOptional({\n    description: 'The user associated with the project',\n    example: 'daytona',\n  })\n  @IsOptional()\n  @IsString()\n  user?: string\n\n  @ApiPropertyOptional({\n    description: 'Environment variables for the sandbox',\n    type: 'object',\n    additionalProperties: { type: 'string' },\n    example: { NODE_ENV: 'production' },\n  })\n  @IsOptional()\n  @IsObject()\n  env?: { [key: string]: string }\n\n  @ApiPropertyOptional({\n    description: 'Labels for the sandbox',\n    type: 'object',\n    additionalProperties: { type: 'string' },\n    example: { 'daytona.io/public': 'true' },\n  })\n  @IsOptional()\n  @IsObject()\n  labels?: { [key: string]: string }\n\n  @ApiPropertyOptional({\n    description: 'Whether the sandbox http preview is publicly accessible',\n    example: false,\n  })\n  @IsOptional()\n  @IsBoolean()\n  public?: boolean\n\n  @ApiPropertyOptional({\n    description: 'Whether to block all network access for the sandbox',\n    example: false,\n  })\n  @IsOptional()\n  @IsBoolean()\n  networkBlockAll?: boolean\n\n  @ApiPropertyOptional({\n    description: 'Comma-separated list of allowed CIDR network addresses for the sandbox',\n    example: '192.168.1.0/16,10.0.0.0/24',\n  })\n  @IsOptional()\n  @IsString()\n  networkAllowList?: string\n\n  @ApiPropertyOptional({\n    description: 'The sandbox class type',\n    enum: SandboxClass,\n    example: Object.values(SandboxClass)[0],\n  })\n  @IsOptional()\n  @IsEnum(SandboxClass)\n  class?: SandboxClass\n\n  @ApiPropertyOptional({\n    description: 'The target (region) where the sandbox will be created',\n    example: 'us',\n  })\n  @IsOptional()\n  @IsString()\n  target?: string\n\n  @ApiPropertyOptional({\n    description: 'CPU cores allocated to the sandbox',\n    example: 2,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  cpu?: number\n\n  @ApiPropertyOptional({\n    description: 'GPU units allocated to the sandbox',\n    example: 1,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  gpu?: number\n\n  @ApiPropertyOptional({\n    description: 'Memory allocated to the sandbox in GB',\n    example: 1,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  memory?: number\n\n  @ApiPropertyOptional({\n    description: 'Disk space allocated to the sandbox in GB',\n    example: 3,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  disk?: number\n\n  @ApiPropertyOptional({\n    description: 'Auto-stop interval in minutes (0 means disabled)',\n    example: 30,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  autoStopInterval?: number\n\n  @ApiPropertyOptional({\n    description: 'Auto-archive interval in minutes (0 means the maximum interval will be used)',\n    example: 7 * 24 * 60,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  autoArchiveInterval?: number\n\n  @ApiPropertyOptional({\n    description:\n      'Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)',\n    example: 30,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  autoDeleteInterval?: number\n\n  @ApiPropertyOptional({\n    description: 'Array of volumes to attach to the sandbox',\n    type: [SandboxVolume],\n    required: false,\n  })\n  @IsOptional()\n  @IsArray()\n  volumes?: SandboxVolume[]\n\n  @ApiPropertyOptional({\n    description: 'Build information for the sandbox',\n    type: CreateBuildInfoDto,\n  })\n  @IsOptional()\n  @IsObject()\n  buildInfo?: CreateBuildInfoDto\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/create-snapshot.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsArray, IsObject, IsBoolean, IsNumber, IsOptional, IsString } from 'class-validator'\nimport { CreateBuildInfoDto } from './create-build-info.dto'\n\n@ApiSchema({ name: 'CreateSnapshot' })\nexport class CreateSnapshotDto {\n  @ApiProperty({\n    description: 'The name of the snapshot',\n    example: 'ubuntu-4vcpu-8ram-100gb',\n  })\n  @IsString()\n  name: string\n\n  @ApiPropertyOptional({\n    description: 'The image name of the snapshot',\n    example: 'ubuntu:22.04',\n  })\n  @IsOptional()\n  @IsString()\n  imageName?: string\n\n  @ApiPropertyOptional({\n    description: 'The entrypoint command for the snapshot',\n    example: 'sleep infinity',\n  })\n  @IsString({\n    each: true,\n  })\n  @IsArray()\n  @IsOptional()\n  entrypoint?: string[]\n\n  @ApiPropertyOptional({\n    description: 'Whether the snapshot is general',\n  })\n  @IsBoolean()\n  @IsOptional()\n  general?: boolean\n\n  @ApiPropertyOptional({\n    description: 'CPU cores allocated to the resulting sandbox',\n    example: 1,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  cpu?: number\n\n  @ApiPropertyOptional({\n    description: 'GPU units allocated to the resulting sandbox',\n    example: 0,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  gpu?: number\n\n  @ApiPropertyOptional({\n    description: 'Memory allocated to the resulting sandbox in GB',\n    example: 1,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  memory?: number\n\n  @ApiPropertyOptional({\n    description: 'Disk space allocated to the sandbox in GB',\n    example: 3,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  disk?: number\n\n  @ApiPropertyOptional({\n    description: 'Build information for the snapshot',\n    type: CreateBuildInfoDto,\n  })\n  @IsOptional()\n  @IsObject()\n  buildInfo?: CreateBuildInfoDto\n\n  @ApiPropertyOptional({\n    description:\n      'ID of the region where the snapshot will be available. Defaults to organization default region if not specified.',\n  })\n  @IsOptional()\n  @IsString()\n  regionId?: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/create-volume.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsString } from 'class-validator'\n\n@ApiSchema({ name: 'CreateVolume' })\nexport class CreateVolumeDto {\n  @ApiProperty()\n  @IsString()\n  name?: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/create-workspace.deprecated.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsEnum, IsObject, IsOptional, IsString, IsNumber, IsBoolean } from 'class-validator'\nimport { ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\nimport { SandboxVolume } from './sandbox.dto'\nimport { CreateBuildInfoDto } from './create-build-info.dto'\n\nenum RunnerRegion {\n  EU = 'eu',\n  US = 'us',\n  ASIA = 'asia',\n}\n@ApiSchema({ name: 'CreateWorkspace' })\nexport class CreateWorkspaceDto {\n  @ApiPropertyOptional({\n    description: 'The image used for the workspace',\n    example: 'daytonaio/workspace:latest',\n  })\n  @IsOptional()\n  @IsString()\n  image?: string\n\n  @ApiPropertyOptional({\n    description: 'The user associated with the project',\n    example: 'daytona',\n  })\n  @IsOptional()\n  @IsString()\n  user?: string\n\n  @ApiPropertyOptional({\n    description: 'Environment variables for the workspace',\n    type: 'object',\n    additionalProperties: { type: 'string' },\n    example: { NODE_ENV: 'production' },\n  })\n  @IsOptional()\n  @IsObject()\n  env?: { [key: string]: string }\n\n  @ApiPropertyOptional({\n    description: 'Labels for the workspace',\n    type: 'object',\n    additionalProperties: { type: 'string' },\n    example: { 'daytona.io/public': 'true' },\n  })\n  @IsOptional()\n  @IsObject()\n  labels?: { [key: string]: string }\n\n  @ApiPropertyOptional({\n    description: 'Whether the workspace http preview is publicly accessible',\n    example: false,\n  })\n  @IsOptional()\n  @IsBoolean()\n  public?: boolean\n\n  @ApiPropertyOptional({\n    description: 'The workspace class type',\n    enum: SandboxClass,\n    example: Object.values(SandboxClass)[0],\n  })\n  @IsOptional()\n  @IsEnum(SandboxClass)\n  class?: SandboxClass\n\n  @ApiPropertyOptional({\n    description: 'The target (region) where the workspace will be created',\n    enum: RunnerRegion,\n    example: Object.values(RunnerRegion)[0],\n  })\n  @IsOptional()\n  @IsEnum(RunnerRegion)\n  target?: RunnerRegion\n\n  @ApiPropertyOptional({\n    description: 'CPU cores allocated to the workspace',\n    example: 2,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  cpu?: number\n\n  @ApiPropertyOptional({\n    description: 'GPU units allocated to the workspace',\n    example: 1,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  gpu?: number\n\n  @ApiPropertyOptional({\n    description: 'Memory allocated to the workspace in GB',\n    example: 1,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  memory?: number\n\n  @ApiPropertyOptional({\n    description: 'Disk space allocated to the workspace in GB',\n    example: 3,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  disk?: number\n\n  @ApiPropertyOptional({\n    description: 'Auto-stop interval in minutes (0 means disabled)',\n    example: 30,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  autoStopInterval?: number\n\n  @ApiPropertyOptional({\n    description: 'Auto-archive interval in minutes (0 means the maximum interval will be used)',\n    example: 7 * 24 * 60,\n    type: 'integer',\n  })\n  @IsOptional()\n  @IsNumber()\n  autoArchiveInterval?: number\n\n  @ApiPropertyOptional({\n    description: 'Array of volumes to attach to the workspace',\n    type: [SandboxVolume],\n    required: false,\n  })\n  @IsOptional()\n  volumes?: SandboxVolume[]\n\n  @ApiPropertyOptional({\n    description: 'Build information for the workspace',\n    type: CreateBuildInfoDto,\n  })\n  @IsOptional()\n  @IsObject()\n  buildInfo?: CreateBuildInfoDto\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/download-files.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'DownloadFiles' })\nexport class DownloadFilesDto {\n  @ApiProperty({\n    description: 'List of remote file paths to download',\n    type: [String],\n  })\n  paths: string[]\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/job-type-map.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { JobType } from '../enums/job-type.enum'\nimport { ResourceType } from '../enums/resource-type.enum'\n\n/**\n * Type-safe mapping between JobType and its corresponding ResourceType(s) + Payload\n * This ensures compile-time safety when creating jobs\n * resourceType is an array of allowed ResourceTypes - the user can supply any of them\n */\nexport interface JobTypeMap {\n  [JobType.CREATE_SANDBOX]: {\n    resourceType: [ResourceType.SANDBOX]\n  }\n  [JobType.START_SANDBOX]: {\n    resourceType: [ResourceType.SANDBOX]\n  }\n  [JobType.STOP_SANDBOX]: {\n    resourceType: [ResourceType.SANDBOX]\n  }\n  [JobType.DESTROY_SANDBOX]: {\n    resourceType: [ResourceType.SANDBOX]\n  }\n  [JobType.RESIZE_SANDBOX]: {\n    resourceType: [ResourceType.SANDBOX]\n  }\n  [JobType.CREATE_BACKUP]: {\n    resourceType: [ResourceType.SANDBOX]\n  }\n  [JobType.BUILD_SNAPSHOT]: {\n    resourceType: [ResourceType.SANDBOX, ResourceType.SNAPSHOT]\n  }\n  [JobType.PULL_SNAPSHOT]: {\n    resourceType: [ResourceType.SNAPSHOT]\n  }\n  [JobType.REMOVE_SNAPSHOT]: {\n    resourceType: [ResourceType.SNAPSHOT]\n  }\n  [JobType.UPDATE_SANDBOX_NETWORK_SETTINGS]: {\n    resourceType: [ResourceType.SANDBOX]\n  }\n  [JobType.INSPECT_SNAPSHOT_IN_REGISTRY]: {\n    resourceType: [ResourceType.SNAPSHOT]\n  }\n  [JobType.RECOVER_SANDBOX]: {\n    resourceType: [ResourceType.SANDBOX]\n  }\n}\n\n/**\n * Helper type to extract the allowed resource types for a given JobType as a union\n */\nexport type ResourceTypeForJobType<T extends JobType> = JobTypeMap[T]['resourceType'][number]\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/job.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsEnum, IsObject, IsOptional, IsString } from 'class-validator'\nimport { JobType } from '../enums/job-type.enum'\nimport { JobStatus } from '../enums/job-status.enum'\nimport { ResourceType } from '../enums/resource-type.enum'\nimport { Job } from '../entities/job.entity'\nimport { PageNumber } from '../../common/decorators/page-number.decorator'\nimport { PageLimit } from '../../common/decorators/page-limit.decorator'\n\n// Re-export enums for convenience\nexport { JobType, JobStatus, ResourceType }\n\n@ApiSchema({ name: 'Job' })\nexport class JobDto {\n  @ApiProperty({\n    description: 'The ID of the job',\n    example: 'job123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'The type of the job',\n    enum: JobType,\n    enumName: 'JobType',\n    example: JobType.CREATE_SANDBOX,\n  })\n  @IsEnum(JobType)\n  type: JobType\n\n  @ApiProperty({\n    description: 'The status of the job',\n    enum: JobStatus,\n    enumName: 'JobStatus',\n    example: JobStatus.PENDING,\n  })\n  @IsEnum(JobStatus)\n  status: JobStatus\n\n  @ApiProperty({\n    description: 'The type of resource this job operates on',\n    enum: ResourceType,\n    example: ResourceType.SANDBOX,\n  })\n  @IsEnum(ResourceType)\n  resourceType: ResourceType\n\n  @ApiProperty({\n    description: 'The ID of the resource this job operates on (sandboxId, snapshotRef, etc.)',\n    example: 'sandbox123',\n  })\n  @IsString()\n  resourceId: string\n\n  @ApiPropertyOptional({\n    description: 'Job-specific JSON-encoded payload data (operational metadata)',\n  })\n  @IsOptional()\n  payload?: string\n\n  @ApiPropertyOptional({\n    description: 'OpenTelemetry trace context for distributed tracing (W3C Trace Context format)',\n    type: 'object',\n    additionalProperties: true,\n    example: { traceparent: '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01' },\n  })\n  @IsOptional()\n  @IsObject()\n  traceContext?: Record<string, string>\n\n  @ApiPropertyOptional({\n    description: 'Error message if the job failed',\n    example: 'Failed to create sandbox',\n  })\n  @IsOptional()\n  @IsString()\n  errorMessage?: string\n\n  @ApiProperty({\n    description: 'The creation timestamp of the job',\n    example: '2024-10-01T12:00:00Z',\n  })\n  createdAt: string\n\n  @ApiPropertyOptional({\n    description: 'The last update timestamp of the job',\n    example: '2024-10-01T12:00:00Z',\n  })\n  @IsOptional()\n  updatedAt?: string\n\n  constructor(job: Job) {\n    this.id = job.id\n    this.type = job.type\n    this.status = job.status\n    this.resourceType = job.resourceType\n    this.resourceId = job.resourceId\n    this.payload = job.payload || undefined\n    this.traceContext = job.traceContext || undefined\n    this.errorMessage = job.errorMessage || undefined\n    this.createdAt = job.createdAt.toISOString()\n    this.updatedAt = job.updatedAt?.toISOString()\n  }\n}\n\n@ApiSchema({ name: 'PollJobsRequest' })\nexport class PollJobsRequestDto {\n  @ApiPropertyOptional({\n    description: 'Timeout in seconds for long polling (default: 30)',\n    example: 30,\n  })\n  @IsOptional()\n  timeout?: number\n\n  @ApiPropertyOptional({\n    description: 'Maximum number of jobs to return',\n    example: 10,\n  })\n  @IsOptional()\n  limit?: number\n}\n\n@ApiSchema({ name: 'PollJobsResponse' })\nexport class PollJobsResponseDto {\n  @ApiProperty({\n    description: 'List of jobs',\n    type: [JobDto],\n  })\n  jobs: JobDto[]\n}\n\n@ApiSchema({ name: 'PaginatedJobs' })\nexport class PaginatedJobsDto {\n  @ApiProperty({ type: [JobDto] })\n  items: JobDto[]\n\n  @ApiProperty()\n  total: number\n\n  @ApiProperty()\n  page: number\n\n  @ApiProperty()\n  totalPages: number\n}\n\n@ApiSchema({ name: 'ListJobsQuery' })\nexport class ListJobsQueryDto {\n  @PageNumber(1)\n  page = 1\n\n  @PageLimit(100)\n  limit = 100\n\n  @ApiPropertyOptional({\n    description: 'Filter by job status',\n    enum: JobStatus,\n    enumName: 'JobStatus',\n    example: JobStatus.PENDING,\n  })\n  @IsOptional()\n  @IsEnum(JobStatus)\n  status?: JobStatus\n}\n\n@ApiSchema({ name: 'UpdateJobStatus' })\nexport class UpdateJobStatusDto {\n  @ApiProperty({\n    description: 'The new status of the job',\n    enum: JobStatus,\n    enumName: 'JobStatus',\n    example: JobStatus.IN_PROGRESS,\n  })\n  @IsEnum(JobStatus)\n  status: JobStatus\n\n  @ApiPropertyOptional({\n    description: 'Error message if the job failed',\n    example: 'Failed to create sandbox',\n  })\n  @IsOptional()\n  @IsString()\n  errorMessage?: string\n\n  @ApiPropertyOptional({\n    description: 'Result metadata for the job',\n  })\n  @IsOptional()\n  @IsString()\n  resultMetadata?: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/list-sandboxes-query.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsBoolean, IsInt, IsOptional, IsString, IsArray, IsEnum, IsDate, Min } from 'class-validator'\nimport { Type } from 'class-transformer'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { ToArray } from '../../common/decorators/to-array.decorator'\nimport { PageNumber } from '../../common/decorators/page-number.decorator'\nimport { PageLimit } from '../../common/decorators/page-limit.decorator'\n\nexport enum SandboxSortField {\n  ID = 'id',\n  NAME = 'name',\n  STATE = 'state',\n  SNAPSHOT = 'snapshot',\n  REGION = 'region',\n  UPDATED_AT = 'updatedAt',\n  CREATED_AT = 'createdAt',\n}\n\nexport enum SandboxSortDirection {\n  ASC = 'asc',\n  DESC = 'desc',\n}\n\nexport const DEFAULT_SANDBOX_SORT_FIELD = SandboxSortField.CREATED_AT\nexport const DEFAULT_SANDBOX_SORT_DIRECTION = SandboxSortDirection.DESC\n\nconst VALID_QUERY_STATES = Object.values(SandboxState).filter((state) => state !== SandboxState.DESTROYED)\n\n@ApiSchema({ name: 'ListSandboxesQuery' })\nexport class ListSandboxesQueryDto {\n  @PageNumber(1)\n  page = 1\n\n  @PageLimit(100)\n  limit = 100\n\n  @ApiProperty({\n    name: 'id',\n    description: 'Filter by partial ID match',\n    required: false,\n    type: String,\n    example: 'abc123',\n  })\n  @IsOptional()\n  @IsString()\n  id?: string\n\n  @ApiProperty({\n    name: 'name',\n    description: 'Filter by partial name match',\n    required: false,\n    type: String,\n    example: 'abc123',\n  })\n  @IsOptional()\n  @IsString()\n  name?: string\n\n  @ApiProperty({\n    name: 'labels',\n    description: 'JSON encoded labels to filter by',\n    required: false,\n    type: String,\n    example: '{\"label1\": \"value1\", \"label2\": \"value2\"}',\n  })\n  @IsOptional()\n  @IsString()\n  labels?: string\n\n  @ApiProperty({\n    name: 'includeErroredDeleted',\n    description: 'Include results with errored state and deleted desired state',\n    required: false,\n    type: Boolean,\n    default: false,\n  })\n  @IsOptional()\n  @Type(() => Boolean)\n  @IsBoolean()\n  includeErroredDeleted?: boolean\n\n  @ApiProperty({\n    name: 'states',\n    description: 'List of states to filter by',\n    required: false,\n    enum: VALID_QUERY_STATES,\n    isArray: true,\n  })\n  @IsOptional()\n  @ToArray()\n  @IsArray()\n  @IsEnum(VALID_QUERY_STATES, {\n    each: true,\n    message: `each value must be one of the following values: ${VALID_QUERY_STATES.join(', ')}`,\n  })\n  states?: SandboxState[]\n\n  @ApiProperty({\n    name: 'snapshots',\n    description: 'List of snapshot names to filter by',\n    required: false,\n    type: [String],\n  })\n  @IsOptional()\n  @ToArray()\n  @IsArray()\n  @IsString({ each: true })\n  snapshots?: string[]\n\n  @ApiProperty({\n    name: 'regions',\n    description: 'List of regions to filter by',\n    required: false,\n    type: [String],\n  })\n  @IsOptional()\n  @ToArray()\n  @IsArray()\n  @IsString({ each: true })\n  regions?: string[]\n\n  @ApiProperty({\n    name: 'minCpu',\n    description: 'Minimum CPU',\n    required: false,\n    type: Number,\n    minimum: 1,\n  })\n  @IsOptional()\n  @Type(() => Number)\n  @IsInt()\n  @Min(1)\n  minCpu?: number\n\n  @ApiProperty({\n    name: 'maxCpu',\n    description: 'Maximum CPU',\n    required: false,\n    type: Number,\n    minimum: 1,\n  })\n  @IsOptional()\n  @Type(() => Number)\n  @IsInt()\n  @Min(1)\n  maxCpu?: number\n\n  @ApiProperty({\n    name: 'minMemoryGiB',\n    description: 'Minimum memory in GiB',\n    required: false,\n    type: Number,\n    minimum: 1,\n  })\n  @IsOptional()\n  @Type(() => Number)\n  @IsInt()\n  @Min(1)\n  minMemoryGiB?: number\n\n  @ApiProperty({\n    name: 'maxMemoryGiB',\n    description: 'Maximum memory in GiB',\n    required: false,\n    type: Number,\n    minimum: 1,\n  })\n  @IsOptional()\n  @Type(() => Number)\n  @IsInt()\n  @Min(1)\n  maxMemoryGiB?: number\n\n  @ApiProperty({\n    name: 'minDiskGiB',\n    description: 'Minimum disk space in GiB',\n    required: false,\n    type: Number,\n    minimum: 1,\n  })\n  @IsOptional()\n  @Type(() => Number)\n  @IsInt()\n  @Min(1)\n  minDiskGiB?: number\n\n  @ApiProperty({\n    name: 'maxDiskGiB',\n    description: 'Maximum disk space in GiB',\n    required: false,\n    type: Number,\n    minimum: 1,\n  })\n  @IsOptional()\n  @Type(() => Number)\n  @IsInt()\n  @Min(1)\n  maxDiskGiB?: number\n\n  @ApiProperty({\n    name: 'lastEventAfter',\n    description: 'Include items with last event after this timestamp',\n    required: false,\n    type: String,\n    format: 'date-time',\n    example: '2024-01-01T00:00:00Z',\n  })\n  @IsOptional()\n  @Type(() => Date)\n  @IsDate()\n  lastEventAfter?: Date\n\n  @ApiProperty({\n    name: 'lastEventBefore',\n    description: 'Include items with last event before this timestamp',\n    required: false,\n    type: String,\n    format: 'date-time',\n    example: '2024-12-31T23:59:59Z',\n  })\n  @IsOptional()\n  @Type(() => Date)\n  @IsDate()\n  lastEventBefore?: Date\n\n  @ApiProperty({\n    name: 'sort',\n    description: 'Field to sort by',\n    required: false,\n    enum: SandboxSortField,\n    default: DEFAULT_SANDBOX_SORT_FIELD,\n  })\n  @IsOptional()\n  @IsEnum(SandboxSortField)\n  sort = DEFAULT_SANDBOX_SORT_FIELD\n\n  @ApiProperty({\n    name: 'order',\n    description: 'Direction to sort by',\n    required: false,\n    enum: SandboxSortDirection,\n    default: DEFAULT_SANDBOX_SORT_DIRECTION,\n  })\n  @IsOptional()\n  @IsEnum(SandboxSortDirection)\n  order = DEFAULT_SANDBOX_SORT_DIRECTION\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/list-snapshots-query.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsOptional, IsString, IsEnum } from 'class-validator'\nimport { PageNumber } from '../../common/decorators/page-number.decorator'\nimport { PageLimit } from '../../common/decorators/page-limit.decorator'\n\nexport enum SnapshotSortField {\n  NAME = 'name',\n  STATE = 'state',\n  LAST_USED_AT = 'lastUsedAt',\n  CREATED_AT = 'createdAt',\n}\n\nexport enum SnapshotSortDirection {\n  ASC = 'asc',\n  DESC = 'desc',\n}\n\n@ApiSchema({ name: 'ListSnapshotsQuery' })\nexport class ListSnapshotsQueryDto {\n  @PageNumber(1)\n  page = 1\n\n  @PageLimit(100)\n  limit = 100\n\n  @ApiProperty({\n    name: 'name',\n    description: 'Filter by partial name match',\n    required: false,\n    type: String,\n    example: 'abc123',\n  })\n  @IsOptional()\n  @IsString()\n  name?: string\n\n  @ApiProperty({\n    name: 'sort',\n    description: 'Field to sort by',\n    required: false,\n    enum: SnapshotSortField,\n    default: SnapshotSortField.LAST_USED_AT,\n  })\n  @IsOptional()\n  @IsEnum(SnapshotSortField)\n  sort = SnapshotSortField.LAST_USED_AT\n\n  @ApiProperty({\n    name: 'order',\n    description: 'Direction to sort by',\n    required: false,\n    enum: SnapshotSortDirection,\n    default: SnapshotSortDirection.DESC,\n  })\n  @IsOptional()\n  @IsEnum(SnapshotSortDirection)\n  order = SnapshotSortDirection.DESC\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/lsp.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsString, IsNumber, IsOptional, ValidateNested, IsArray, IsBoolean } from 'class-validator'\nimport { Type } from 'class-transformer'\n\n@ApiSchema({ name: 'LspServerRequest' })\nexport class LspServerRequestDto {\n  @ApiProperty({ description: 'Language identifier' })\n  @IsString()\n  languageId: string\n\n  @ApiProperty({ description: 'Path to the project' })\n  @IsString()\n  pathToProject: string\n}\n\n@ApiSchema({ name: 'LspDocumentRequest' })\nexport class LspDocumentRequestDto extends LspServerRequestDto {\n  @ApiProperty({ description: 'Document URI' })\n  @IsString()\n  uri: string\n}\n\n@ApiSchema({ name: 'Position' })\nexport class PositionDto {\n  @ApiProperty()\n  @IsNumber()\n  line: number\n\n  @ApiProperty()\n  @IsNumber()\n  character: number\n}\n\n@ApiSchema({ name: 'CompletionContext' })\nexport class CompletionContextDto {\n  @ApiProperty()\n  @IsNumber()\n  triggerKind: number\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  @IsString()\n  triggerCharacter?: string\n}\n\n@ApiSchema({ name: 'LspCompletionParams' })\nexport class LspCompletionParamsDto extends LspDocumentRequestDto {\n  @ApiProperty()\n  @ValidateNested()\n  @Type(() => PositionDto)\n  position: PositionDto\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  @ValidateNested()\n  @Type(() => CompletionContextDto)\n  context?: CompletionContextDto\n}\n\n@ApiSchema({ name: 'Range' })\nexport class RangeDto {\n  @ApiProperty()\n  @ValidateNested()\n  @Type(() => PositionDto)\n  start: PositionDto\n\n  @ApiProperty()\n  @ValidateNested()\n  @Type(() => PositionDto)\n  end: PositionDto\n}\n\n@ApiSchema({ name: 'CompletionItem' })\nexport class CompletionItemDto {\n  @ApiProperty()\n  @IsString()\n  label: string\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  @IsNumber()\n  kind?: number\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  @IsString()\n  detail?: string\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  documentation?: any\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  @IsString()\n  sortText?: string\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  @IsString()\n  filterText?: string\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  @IsString()\n  insertText?: string\n}\n\n@ApiSchema({ name: 'CompletionList' })\nexport class CompletionListDto {\n  @ApiProperty()\n  @IsBoolean()\n  isIncomplete: boolean\n\n  @ApiProperty({ type: [CompletionItemDto] })\n  @IsArray()\n  @ValidateNested({ each: true })\n  @Type(() => CompletionItemDto)\n  items: CompletionItemDto[]\n}\n\n@ApiSchema({ name: 'LspLocation' })\nexport class LspLocationDto {\n  @ApiProperty()\n  @ValidateNested()\n  @Type(() => RangeDto)\n  range: RangeDto\n\n  @ApiProperty()\n  @IsString()\n  uri: string\n}\n\n@ApiSchema({ name: 'LspSymbol' })\nexport class LspSymbolDto {\n  @ApiProperty()\n  @IsNumber()\n  kind: number\n\n  @ApiProperty()\n  @ValidateNested()\n  @Type(() => LspLocationDto)\n  location: LspLocationDto\n\n  @ApiProperty()\n  @IsString()\n  name: string\n}\n\n@ApiSchema({ name: 'WorkspaceSymbolParams' })\nexport class WorkspaceSymbolParamsDto {\n  @ApiProperty()\n  @IsString()\n  query: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/paginated-sandboxes.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { SandboxDto } from './sandbox.dto'\n\n@ApiSchema({ name: 'PaginatedSandboxes' })\nexport class PaginatedSandboxesDto {\n  @ApiProperty({ type: [SandboxDto] })\n  items: SandboxDto[]\n\n  @ApiProperty()\n  total: number\n\n  @ApiProperty()\n  page: number\n\n  @ApiProperty()\n  totalPages: number\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/paginated-snapshots.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { SnapshotDto } from './snapshot.dto'\n\n@ApiSchema({ name: 'PaginatedSnapshots' })\nexport class PaginatedSnapshotsDto {\n  @ApiProperty({ type: [SnapshotDto] })\n  items: SnapshotDto[]\n\n  @ApiProperty()\n  total: number\n\n  @ApiProperty()\n  page: number\n\n  @ApiProperty()\n  totalPages: number\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/port-preview-url.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsNumber, IsString } from 'class-validator'\n\n@ApiSchema({ name: 'PortPreviewUrl' })\nexport class PortPreviewUrlDto {\n  @ApiProperty({\n    description: 'ID of the sandbox',\n    example: '123456',\n  })\n  @IsString()\n  sandboxId: string\n\n  @ApiProperty({\n    description: 'Preview url',\n    example: 'https://{port}-{sandboxId}.{proxyDomain}',\n  })\n  @IsString()\n  url: string\n\n  @ApiProperty({\n    description: 'Access token',\n    example: 'ul67qtv-jl6wb9z5o3eii-ljqt9qed6l',\n  })\n  @IsString()\n  token: string\n}\n\n@ApiSchema({ name: 'SignedPortPreviewUrl' })\nexport class SignedPortPreviewUrlDto {\n  @ApiProperty({\n    description: 'ID of the sandbox',\n    example: '123456',\n  })\n  @IsString()\n  sandboxId: string\n\n  @ApiProperty({\n    description: 'Port number of the signed preview URL',\n    example: 3000,\n    type: 'integer',\n  })\n  @IsNumber()\n  port: number\n\n  @ApiProperty({\n    description: 'Token of the signed preview URL',\n    example: 'jl6wb9z5o3eii',\n  })\n  @IsString()\n  token: string\n\n  @ApiProperty({\n    description: 'Signed preview url',\n    example: 'https://{port}-{token}.{proxyDomain}',\n  })\n  @IsString()\n  url: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/registry-push-access-dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty } from '@nestjs/swagger'\n\nexport class RegistryPushAccessDto {\n  @ApiProperty({\n    description: 'Temporary username for registry authentication',\n    example: 'temp-user-123',\n  })\n  username: string\n\n  @ApiProperty({\n    description: 'Temporary secret for registry authentication',\n    example: 'eyJhbGciOiJIUzI1NiIs...',\n  })\n  secret: string\n\n  @ApiProperty({\n    description: 'Registry URL',\n    example: 'registry.example.com',\n  })\n  registryUrl: string\n\n  @ApiProperty({\n    description: 'Registry ID',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  registryId: string\n\n  @ApiProperty({\n    description: 'Registry project ID',\n    example: 'library',\n  })\n  project: string\n\n  @ApiProperty({\n    description: 'Token expiration time in ISO format',\n    example: '2023-12-31T23:59:59Z',\n  })\n  expiresAt: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/resize-sandbox.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsOptional, IsNumber, Min } from 'class-validator'\nimport { ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'ResizeSandbox' })\nexport class ResizeSandboxDto {\n  @ApiPropertyOptional({\n    description: 'CPU cores to allocate to the sandbox (minimum: 1)',\n    example: 2,\n    type: 'integer',\n    minimum: 1,\n  })\n  @IsOptional()\n  @IsNumber()\n  @Min(1)\n  cpu?: number\n\n  @ApiPropertyOptional({\n    description: 'Memory in GB to allocate to the sandbox (minimum: 1)',\n    example: 4,\n    type: 'integer',\n    minimum: 1,\n  })\n  @IsOptional()\n  @IsNumber()\n  @Min(1)\n  memory?: number\n\n  @ApiPropertyOptional({\n    description: 'Disk space in GB to allocate to the sandbox (can only be increased)',\n    example: 20,\n    type: 'integer',\n    minimum: 1,\n  })\n  @IsOptional()\n  @IsNumber()\n  @Min(1)\n  disk?: number\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/runner-full.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsEnum, IsOptional } from 'class-validator'\nimport { Runner } from '../entities/runner.entity'\nimport { RunnerDto } from './runner.dto'\nimport { RegionType } from '../../region/enums/region-type.enum'\n\n@ApiSchema({ name: 'RunnerFull' })\nexport class RunnerFullDto extends RunnerDto {\n  @ApiProperty({\n    description: 'The API key for the runner',\n    example: 'dtn_1234567890',\n  })\n  apiKey: string\n\n  @ApiPropertyOptional({\n    description: 'The region type of the runner',\n    enum: RegionType,\n    enumName: 'RegionType',\n    example: Object.values(RegionType)[0],\n  })\n  @IsOptional()\n  @IsEnum(RegionType)\n  regionType?: RegionType\n\n  static fromRunner(runner: Runner, regionType?: RegionType): RunnerFullDto {\n    return {\n      ...RunnerDto.fromRunner(runner),\n      apiKey: runner.apiKey,\n      regionType,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/runner-health.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsArray, IsBoolean, IsNumber, IsOptional, IsString, ValidateNested } from 'class-validator'\nimport { Type } from 'class-transformer'\n\n@ApiSchema({ name: 'RunnerHealthMetrics' })\nexport class RunnerHealthMetricsDto {\n  @ApiProperty({\n    description: 'Current CPU load average',\n    example: 0.98,\n  })\n  @IsNumber()\n  currentCpuLoadAverage: number\n\n  @ApiProperty({\n    description: 'Current CPU usage percentage',\n    example: 45.5,\n  })\n  @IsNumber()\n  currentCpuUsagePercentage: number\n\n  @ApiProperty({\n    description: 'Current memory usage percentage',\n    example: 60.2,\n  })\n  @IsNumber()\n  currentMemoryUsagePercentage: number\n\n  @ApiProperty({\n    description: 'Current disk usage percentage',\n    example: 35.8,\n  })\n  @IsNumber()\n  currentDiskUsagePercentage: number\n\n  @ApiProperty({\n    description: 'Currently allocated CPU cores',\n    example: 8,\n  })\n  @IsNumber()\n  currentAllocatedCpu: number\n\n  @ApiProperty({\n    description: 'Currently allocated memory in GiB',\n    example: 16,\n  })\n  @IsNumber()\n  currentAllocatedMemoryGiB: number\n\n  @ApiProperty({\n    description: 'Currently allocated disk in GiB',\n    example: 100,\n  })\n  @IsNumber()\n  currentAllocatedDiskGiB: number\n\n  @ApiProperty({\n    description: 'Number of snapshots currently stored',\n    example: 5,\n  })\n  @IsNumber()\n  currentSnapshotCount: number\n\n  @ApiProperty({\n    description: 'Number of started sandboxes',\n    example: 10,\n  })\n  @IsNumber()\n  currentStartedSandboxes: number\n\n  @ApiProperty({\n    description: 'Total CPU cores on the runner',\n    example: 8,\n  })\n  @IsNumber()\n  cpu: number\n\n  @ApiProperty({\n    description: 'Total RAM in GiB on the runner',\n    example: 16,\n  })\n  @IsNumber()\n  memoryGiB: number\n\n  @ApiProperty({\n    description: 'Total disk space in GiB on the runner',\n    example: 100,\n  })\n  @IsNumber()\n  diskGiB: number\n}\n\n@ApiSchema({ name: 'RunnerServiceHealth' })\nexport class RunnerServiceHealthDto {\n  @ApiProperty({\n    description: 'Name of the service being checked',\n    example: 'runner',\n  })\n  @IsString()\n  serviceName: string\n\n  @ApiProperty({\n    description: 'Whether the service is healthy',\n    example: false,\n  })\n  @IsBoolean()\n  healthy: boolean\n\n  @ApiPropertyOptional({\n    description: 'Error reason if the service is unhealthy',\n    example: 'Cannot connect to the runner',\n  })\n  @IsOptional()\n  @IsString()\n  errorReason?: string\n}\n\n@ApiSchema({ name: 'RunnerHealthcheck' })\nexport class RunnerHealthcheckDto {\n  @ApiPropertyOptional({\n    description: 'Runner metrics',\n    type: RunnerHealthMetricsDto,\n  })\n  @IsOptional()\n  metrics?: RunnerHealthMetricsDto\n\n  @ApiPropertyOptional({\n    description: 'Health status of individual services on the runner',\n    type: [RunnerServiceHealthDto],\n  })\n  @IsOptional()\n  @IsArray()\n  @ValidateNested({ each: true })\n  @Type(() => RunnerServiceHealthDto)\n  serviceHealth?: RunnerServiceHealthDto[]\n\n  @ApiPropertyOptional({\n    description: 'Runner domain',\n    example: 'runner-123.daytona.example.com',\n  })\n  @IsOptional()\n  domain?: string\n\n  @ApiPropertyOptional({\n    description: 'Runner proxy URL',\n    example: 'http://proxy.daytona.example.com:8080',\n  })\n  @IsOptional()\n  proxyUrl?: string\n\n  @ApiPropertyOptional({\n    description: 'Runner API URL',\n    example: 'http://api.daytona.example.com:8080',\n  })\n  @IsOptional()\n  apiUrl?: string\n\n  @ApiProperty({\n    description: 'Runner app version',\n    example: 'v0.0.0-dev',\n  })\n  @IsString()\n  appVersion: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/runner-snapshot.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'\n\nexport class RunnerSnapshotDto {\n  @ApiProperty({\n    description: 'Runner snapshot ID',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  runnerSnapshotId: string\n\n  @ApiProperty({\n    description: 'Runner ID',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  runnerId: string\n\n  @ApiPropertyOptional({\n    description: 'Runner domain',\n    example: 'runner.example.com',\n  })\n  runnerDomain?: string\n\n  constructor(runnerSnapshotId: string, runnerId: string, runnerDomain: string | null) {\n    this.runnerSnapshotId = runnerSnapshotId\n    this.runnerId = runnerId\n    this.runnerDomain = runnerDomain ?? undefined\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/runner-status.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'RunnerStatus' })\nexport class RunnerStatusDto {\n  @ApiProperty({\n    description: 'Current CPU usage percentage',\n    example: 45.6,\n  })\n  currentCpuUsagePercentage: number\n\n  @ApiProperty({\n    description: 'Current RAM usage percentage',\n    example: 68.2,\n  })\n  currentMemoryUsagePercentage: number\n\n  @ApiProperty({\n    description: 'Current disk usage percentage',\n    example: 33.8,\n  })\n  currentDiskUsagePercentage: number\n\n  @ApiProperty({\n    description: 'Current allocated CPU',\n    example: 4000,\n  })\n  currentAllocatedCpu: number\n\n  @ApiProperty({\n    description: 'Current allocated memory',\n    example: 8000,\n  })\n  currentAllocatedMemoryGiB: number\n\n  @ApiProperty({\n    description: 'Current allocated disk',\n    example: 50000,\n  })\n  currentAllocatedDiskGiB: number\n\n  @ApiProperty({\n    description: 'Current snapshot count',\n    example: 12,\n  })\n  currentSnapshotCount: number\n\n  @ApiProperty({\n    description: 'Runner status',\n    example: 'ok',\n  })\n  status: string\n\n  @ApiProperty({\n    description: 'Runner version',\n    example: '0.0.1',\n  })\n  version: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/runner.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsEnum, IsOptional } from 'class-validator'\nimport { Runner } from '../entities/runner.entity'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\nimport { RunnerState } from '../enums/runner-state.enum'\n\n@ApiSchema({ name: 'Runner' })\nexport class RunnerDto {\n  @ApiProperty({\n    description: 'The ID of the runner',\n    example: 'runner123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'The domain of the runner',\n    example: 'runner1.example.com',\n    required: false,\n  })\n  @IsOptional()\n  domain?: string\n\n  @ApiProperty({\n    description: 'The API URL of the runner',\n    example: 'https://api.runner1.example.com',\n    required: false,\n  })\n  @IsOptional()\n  apiUrl?: string\n\n  @ApiProperty({\n    description: 'The proxy URL of the runner',\n    example: 'https://proxy.runner1.example.com',\n    required: false,\n  })\n  @IsOptional()\n  proxyUrl?: string\n\n  @ApiProperty({\n    description: 'The CPU capacity of the runner',\n    example: 8,\n  })\n  cpu: number\n\n  @ApiProperty({\n    description: 'The memory capacity of the runner in GiB',\n    example: 16,\n  })\n  memory: number\n\n  @ApiProperty({\n    description: 'The disk capacity of the runner in GiB',\n    example: 100,\n  })\n  disk: number\n\n  @ApiProperty({\n    description: 'The GPU capacity of the runner',\n    example: 1,\n    required: false,\n  })\n  @IsOptional()\n  gpu?: number\n\n  @ApiProperty({\n    description: 'The type of GPU',\n    required: false,\n  })\n  @IsOptional()\n  gpuType?: string\n\n  @ApiProperty({\n    description: 'The class of the runner',\n    enum: SandboxClass,\n    enumName: 'SandboxClass',\n    example: SandboxClass.SMALL,\n  })\n  @IsEnum(SandboxClass)\n  class: SandboxClass\n\n  @ApiPropertyOptional({\n    description: 'Current CPU usage percentage',\n    example: 45.6,\n  })\n  currentCpuUsagePercentage: number\n\n  @ApiPropertyOptional({\n    description: 'Current RAM usage percentage',\n    example: 68.2,\n  })\n  currentMemoryUsagePercentage: number\n\n  @ApiPropertyOptional({\n    description: 'Current disk usage percentage',\n    example: 33.8,\n  })\n  currentDiskUsagePercentage: number\n\n  @ApiPropertyOptional({\n    description: 'Current allocated CPU',\n    example: 4000,\n  })\n  currentAllocatedCpu: number\n\n  @ApiPropertyOptional({\n    description: 'Current allocated memory in GiB',\n    example: 8000,\n  })\n  currentAllocatedMemoryGiB: number\n\n  @ApiPropertyOptional({\n    description: 'Current allocated disk in GiB',\n    example: 50000,\n  })\n  currentAllocatedDiskGiB: number\n\n  @ApiPropertyOptional({\n    description: 'Current snapshot count',\n    example: 12,\n  })\n  currentSnapshotCount: number\n\n  @ApiPropertyOptional({\n    description: 'Current number of started sandboxes',\n    example: 5,\n  })\n  currentStartedSandboxes: number\n\n  @ApiPropertyOptional({\n    description: 'Runner availability score',\n    example: 85,\n  })\n  availabilityScore: number\n\n  @ApiProperty({\n    description: 'The region of the runner',\n    example: 'us',\n  })\n  region: string\n\n  @ApiProperty({\n    description: 'The name of the runner',\n    example: 'runner1',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'The state of the runner',\n    enum: RunnerState,\n    enumName: 'RunnerState',\n    example: RunnerState.INITIALIZING,\n  })\n  @IsEnum(RunnerState)\n  state: RunnerState\n\n  @ApiPropertyOptional({\n    description: 'The last time the runner was checked',\n    example: '2024-10-01T12:00:00Z',\n    required: false,\n  })\n  @IsOptional()\n  lastChecked?: string\n\n  @ApiProperty({\n    description: 'Whether the runner is unschedulable',\n    example: false,\n  })\n  unschedulable: boolean\n\n  @ApiProperty({\n    description: 'The creation timestamp of the runner',\n    example: '2023-10-01T12:00:00Z',\n  })\n  createdAt: string\n\n  @ApiProperty({\n    description: 'The last update timestamp of the runner',\n    example: '2023-10-01T12:00:00Z',\n  })\n  updatedAt: string\n\n  @ApiProperty({\n    description: 'The version of the runner (deprecated in favor of apiVersion)',\n    example: '0',\n    deprecated: true,\n  })\n  version: string\n\n  @ApiProperty({\n    description: 'The api version of the runner',\n    example: '0',\n    deprecated: true,\n  })\n  apiVersion: string\n\n  @ApiPropertyOptional({\n    description: 'The app version of the runner',\n    example: 'v0.0.0-dev',\n    deprecated: true,\n  })\n  @IsOptional()\n  appVersion?: string\n\n  static fromRunner(runner: Runner): RunnerDto {\n    return {\n      id: runner.id,\n      domain: runner.domain,\n      apiUrl: runner.apiUrl,\n      proxyUrl: runner.proxyUrl,\n      cpu: runner.cpu,\n      memory: runner.memoryGiB,\n      disk: runner.diskGiB,\n      gpu: runner.gpu,\n      gpuType: runner.gpuType,\n      class: runner.class,\n      currentCpuUsagePercentage: runner.currentCpuUsagePercentage,\n      currentMemoryUsagePercentage: runner.currentMemoryUsagePercentage,\n      currentDiskUsagePercentage: runner.currentDiskUsagePercentage,\n      currentAllocatedCpu: runner.currentAllocatedCpu,\n      currentAllocatedMemoryGiB: runner.currentAllocatedMemoryGiB,\n      currentAllocatedDiskGiB: runner.currentAllocatedDiskGiB,\n      currentSnapshotCount: runner.currentSnapshotCount,\n      currentStartedSandboxes: runner.currentStartedSandboxes,\n      availabilityScore: runner.availabilityScore,\n      region: runner.region,\n      name: runner.name,\n      state: runner.state,\n      lastChecked: runner.lastChecked?.toISOString(),\n      unschedulable: runner.unschedulable,\n      createdAt: runner.createdAt.toISOString(),\n      updatedAt: runner.updatedAt.toISOString(),\n      version: runner.apiVersion,\n      apiVersion: runner.apiVersion,\n      appVersion: runner.appVersion,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/sandbox.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { IsEnum, IsOptional } from 'class-validator'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\nimport { BuildInfoDto } from './build-info.dto'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\n\n@ApiSchema({ name: 'SandboxVolume' })\nexport class SandboxVolume {\n  @ApiProperty({\n    description: 'The ID of the volume',\n    example: 'volume123',\n  })\n  volumeId: string\n\n  @ApiProperty({\n    description: 'The mount path for the volume',\n    example: '/data',\n  })\n  mountPath: string\n\n  @ApiPropertyOptional({\n    description:\n      'Optional subpath within the volume to mount. When specified, only this S3 prefix will be accessible. When omitted, the entire volume is mounted.',\n    example: 'users/alice',\n  })\n  subpath?: string\n}\n\n@ApiSchema({ name: 'Sandbox' })\nexport class SandboxDto {\n  @ApiProperty({\n    description: 'The ID of the sandbox',\n    example: 'sandbox123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'The organization ID of the sandbox',\n    example: 'organization123',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'The name of the sandbox',\n    example: 'MySandbox',\n  })\n  name: string\n\n  @ApiPropertyOptional({\n    description: 'The snapshot used for the sandbox',\n    example: 'daytonaio/sandbox:latest',\n  })\n  snapshot: string\n\n  @ApiProperty({\n    description: 'The user associated with the project',\n    example: 'daytona',\n  })\n  user: string\n\n  @ApiProperty({\n    description: 'Environment variables for the sandbox',\n    type: 'object',\n    additionalProperties: { type: 'string' },\n    example: { NODE_ENV: 'production' },\n  })\n  env: Record<string, string>\n\n  @ApiProperty({\n    description: 'Labels for the sandbox',\n    type: 'object',\n    additionalProperties: { type: 'string' },\n    example: { 'daytona.io/public': 'true' },\n  })\n  labels: { [key: string]: string }\n\n  @ApiProperty({\n    description: 'Whether the sandbox http preview is public',\n    example: false,\n  })\n  public: boolean\n\n  @ApiProperty({\n    description: 'Whether to block all network access for the sandbox',\n    example: false,\n  })\n  networkBlockAll: boolean\n\n  @ApiPropertyOptional({\n    description: 'Comma-separated list of allowed CIDR network addresses for the sandbox',\n    example: '192.168.1.0/16,10.0.0.0/24',\n  })\n  networkAllowList?: string\n\n  @ApiProperty({\n    description: 'The target environment for the sandbox',\n    example: 'local',\n  })\n  target: string\n\n  @ApiProperty({\n    description: 'The CPU quota for the sandbox',\n    example: 2,\n  })\n  cpu: number\n\n  @ApiProperty({\n    description: 'The GPU quota for the sandbox',\n    example: 0,\n  })\n  gpu: number\n\n  @ApiProperty({\n    description: 'The memory quota for the sandbox',\n    example: 4,\n  })\n  memory: number\n\n  @ApiProperty({\n    description: 'The disk quota for the sandbox',\n    example: 10,\n  })\n  disk: number\n\n  @ApiPropertyOptional({\n    description: 'The state of the sandbox',\n    enum: SandboxState,\n    enumName: 'SandboxState',\n    example: Object.values(SandboxState)[0],\n    required: false,\n  })\n  @IsEnum(SandboxState)\n  @IsOptional()\n  state?: SandboxState\n\n  @ApiPropertyOptional({\n    description: 'The desired state of the sandbox',\n    enum: SandboxDesiredState,\n    enumName: 'SandboxDesiredState',\n    example: Object.values(SandboxDesiredState)[0],\n    required: false,\n  })\n  @IsEnum(SandboxDesiredState)\n  @IsOptional()\n  desiredState?: SandboxDesiredState\n\n  @ApiPropertyOptional({\n    description: 'The error reason of the sandbox',\n    example: 'The sandbox is not running',\n    required: false,\n  })\n  @IsOptional()\n  errorReason?: string\n\n  @ApiPropertyOptional({\n    description: 'Whether the sandbox error is recoverable.',\n    example: true,\n    required: false,\n  })\n  @IsOptional()\n  recoverable?: boolean\n\n  @ApiPropertyOptional({\n    description: 'The state of the backup',\n    enum: BackupState,\n    example: Object.values(BackupState)[0],\n    required: false,\n  })\n  @IsEnum(BackupState)\n  @IsOptional()\n  backupState?: BackupState\n\n  @ApiPropertyOptional({\n    description: 'The creation timestamp of the last backup',\n    example: '2024-10-01T12:00:00Z',\n    required: false,\n  })\n  @IsOptional()\n  backupCreatedAt?: string\n\n  @ApiPropertyOptional({\n    description: 'Auto-stop interval in minutes (0 means disabled)',\n    example: 30,\n    required: false,\n  })\n  @IsOptional()\n  autoStopInterval?: number\n\n  @ApiPropertyOptional({\n    description: 'Auto-archive interval in minutes',\n    example: 7 * 24 * 60,\n    required: false,\n  })\n  @IsOptional()\n  autoArchiveInterval?: number\n\n  @ApiPropertyOptional({\n    description:\n      'Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)',\n    example: 30,\n    required: false,\n  })\n  @IsOptional()\n  autoDeleteInterval?: number\n\n  @ApiPropertyOptional({\n    description: 'Array of volumes attached to the sandbox',\n    type: [SandboxVolume],\n    required: false,\n  })\n  @IsOptional()\n  volumes?: SandboxVolume[]\n\n  @ApiPropertyOptional({\n    description: 'Build information for the sandbox',\n    type: BuildInfoDto,\n    required: false,\n  })\n  @IsOptional()\n  buildInfo?: BuildInfoDto\n\n  @ApiPropertyOptional({\n    description: 'The creation timestamp of the sandbox',\n    example: '2024-10-01T12:00:00Z',\n    required: false,\n  })\n  @IsOptional()\n  createdAt?: string\n\n  @ApiPropertyOptional({\n    description: 'The last update timestamp of the sandbox',\n    example: '2024-10-01T12:00:00Z',\n    required: false,\n  })\n  @IsOptional()\n  updatedAt?: string\n\n  @ApiPropertyOptional({\n    description: 'The class of the sandbox',\n    enum: SandboxClass,\n    example: Object.values(SandboxClass)[0],\n    required: false,\n    deprecated: true,\n  })\n  @IsEnum(SandboxClass)\n  @IsOptional()\n  class?: SandboxClass\n\n  @ApiPropertyOptional({\n    description: 'The version of the daemon running in the sandbox',\n    example: '1.0.0',\n    required: false,\n  })\n  @IsOptional()\n  daemonVersion?: string\n\n  @ApiPropertyOptional({\n    description: 'The runner ID of the sandbox',\n    example: 'runner123',\n    required: false,\n  })\n  @IsOptional()\n  runnerId?: string\n\n  @ApiProperty({\n    description: 'The toolbox proxy URL for the sandbox',\n    example: 'https://proxy.app.daytona.io/toolbox',\n  })\n  toolboxProxyUrl: string\n\n  static fromSandbox(sandbox: Sandbox, toolboxProxyUrl: string): SandboxDto {\n    return {\n      id: sandbox.id,\n      organizationId: sandbox.organizationId,\n      name: sandbox.name,\n      target: sandbox.region,\n      snapshot: sandbox.snapshot,\n      user: sandbox.osUser,\n      env: sandbox.env,\n      cpu: sandbox.cpu,\n      gpu: sandbox.gpu,\n      memory: sandbox.mem,\n      disk: sandbox.disk,\n      public: sandbox.public,\n      networkBlockAll: sandbox.networkBlockAll,\n      networkAllowList: sandbox.networkAllowList,\n      labels: sandbox.labels,\n      volumes: sandbox.volumes,\n      state: this.getSandboxState(sandbox),\n      desiredState: sandbox.desiredState,\n      errorReason: sandbox.errorReason,\n      recoverable: sandbox.recoverable,\n      backupState: sandbox.backupState,\n      backupCreatedAt: sandbox.lastBackupAt ? new Date(sandbox.lastBackupAt).toISOString() : undefined,\n      autoStopInterval: sandbox.autoStopInterval,\n      autoArchiveInterval: sandbox.autoArchiveInterval,\n      autoDeleteInterval: sandbox.autoDeleteInterval,\n      class: sandbox.class,\n      createdAt: sandbox.createdAt ? new Date(sandbox.createdAt).toISOString() : undefined,\n      updatedAt: sandbox.updatedAt ? new Date(sandbox.updatedAt).toISOString() : undefined,\n      buildInfo: sandbox.buildInfo\n        ? {\n            dockerfileContent: sandbox.buildInfo.dockerfileContent,\n            contextHashes: sandbox.buildInfo.contextHashes,\n            createdAt: sandbox.buildInfo.createdAt,\n            updatedAt: sandbox.buildInfo.updatedAt,\n            snapshotRef: sandbox.buildInfo.snapshotRef,\n          }\n        : undefined,\n      daemonVersion: sandbox.daemonVersion,\n      runnerId: sandbox.runnerId,\n      toolboxProxyUrl,\n    }\n  }\n\n  private static getSandboxState(sandbox: Sandbox): SandboxState {\n    switch (sandbox.state) {\n      case SandboxState.STARTED:\n        if (sandbox.desiredState === SandboxDesiredState.STOPPED) {\n          return SandboxState.STOPPING\n        }\n        if (sandbox.desiredState === SandboxDesiredState.DESTROYED) {\n          return SandboxState.DESTROYING\n        }\n        break\n      case SandboxState.STOPPED:\n        if (sandbox.desiredState === SandboxDesiredState.STARTED) {\n          return SandboxState.STARTING\n        }\n        if (sandbox.desiredState === SandboxDesiredState.DESTROYED) {\n          return SandboxState.DESTROYING\n        }\n        if (sandbox.desiredState === SandboxDesiredState.ARCHIVED) {\n          return SandboxState.ARCHIVING\n        }\n        break\n      case SandboxState.UNKNOWN:\n        if (sandbox.desiredState === SandboxDesiredState.STARTED) {\n          return SandboxState.CREATING\n        }\n        break\n    }\n    return sandbox.state\n  }\n}\n\n@ApiSchema({ name: 'SandboxLabels' })\nexport class SandboxLabelsDto {\n  @ApiProperty({\n    description: 'Key-value pairs of labels',\n    example: { environment: 'dev', team: 'backend' },\n    type: 'object',\n    additionalProperties: { type: 'string' },\n  })\n  labels: { [key: string]: string }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/snapshot.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { BuildInfoDto } from './build-info.dto'\nimport { IsOptional } from 'class-validator'\n\nexport class SnapshotDto {\n  @ApiProperty()\n  id: string\n\n  @ApiPropertyOptional()\n  organizationId?: string\n\n  @ApiProperty()\n  general: boolean\n\n  @ApiProperty()\n  name: string\n\n  @ApiPropertyOptional()\n  imageName?: string\n\n  @ApiProperty({\n    enum: SnapshotState,\n    enumName: 'SnapshotState',\n  })\n  state: SnapshotState\n\n  @ApiProperty({ nullable: true })\n  size?: number\n\n  @ApiProperty({ nullable: true })\n  entrypoint?: string[]\n\n  @ApiProperty()\n  cpu: number\n\n  @ApiProperty()\n  gpu: number\n\n  @ApiProperty()\n  mem: number\n\n  @ApiProperty()\n  disk: number\n\n  @ApiProperty({ nullable: true })\n  errorReason?: string\n\n  @ApiProperty()\n  createdAt: Date\n\n  @ApiProperty()\n  updatedAt: Date\n\n  @ApiProperty({ nullable: true })\n  lastUsedAt?: Date\n\n  @ApiPropertyOptional({\n    description: 'Build information for the snapshot',\n    type: BuildInfoDto,\n  })\n  buildInfo?: BuildInfoDto\n\n  @ApiPropertyOptional({\n    description: 'IDs of regions where the snapshot is available',\n    type: [String],\n  })\n  regionIds?: string[]\n\n  @ApiPropertyOptional({\n    description: 'The initial runner ID of the snapshot',\n    example: 'runner123',\n    required: false,\n  })\n  @IsOptional()\n  initialRunnerId?: string\n\n  @ApiPropertyOptional({\n    description: 'The snapshot reference',\n    example: 'daytonaio/sandbox:latest',\n    required: false,\n  })\n  @IsOptional()\n  ref?: string\n\n  static fromSnapshot(snapshot: Snapshot): SnapshotDto {\n    return {\n      id: snapshot.id,\n      organizationId: snapshot.organizationId,\n      general: snapshot.general,\n      name: snapshot.name,\n      imageName: snapshot.imageName,\n      state: snapshot.state,\n      size: snapshot.size,\n      entrypoint: snapshot.entrypoint,\n      cpu: snapshot.cpu,\n      gpu: snapshot.gpu,\n      mem: snapshot.mem,\n      disk: snapshot.disk,\n      errorReason: snapshot.errorReason,\n      createdAt: snapshot.createdAt,\n      updatedAt: snapshot.updatedAt,\n      lastUsedAt: snapshot.lastUsedAt,\n      buildInfo: snapshot.buildInfo\n        ? {\n            dockerfileContent: snapshot.buildInfo.dockerfileContent,\n            contextHashes: snapshot.buildInfo.contextHashes,\n            createdAt: snapshot.buildInfo.createdAt,\n            updatedAt: snapshot.buildInfo.updatedAt,\n            snapshotRef: snapshot.buildInfo.snapshotRef,\n          }\n        : undefined,\n      regionIds: snapshot.snapshotRegions?.map((sr) => sr.regionId) ?? undefined,\n      initialRunnerId: snapshot.initialRunnerId,\n      ref: snapshot.ref,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/ssh-access.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty } from '@nestjs/swagger'\nimport { SshAccess } from '../entities/ssh-access.entity'\n\nexport class SshAccessDto {\n  @ApiProperty({\n    description: 'Unique identifier for the SSH access',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'ID of the sandbox this SSH access is for',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  sandboxId: string\n\n  @ApiProperty({\n    description: 'SSH access token',\n    example: 'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz',\n  })\n  token: string\n\n  @ApiProperty({\n    description: 'When the SSH access expires',\n    example: '2025-01-01T12:00:00.000Z',\n  })\n  expiresAt: Date\n\n  @ApiProperty({\n    description: 'When the SSH access was created',\n    example: '2025-01-01T11:00:00.000Z',\n  })\n  createdAt: Date\n\n  @ApiProperty({\n    description: 'When the SSH access was last updated',\n    example: '2025-01-01T11:00:00.000Z',\n  })\n  updatedAt: Date\n\n  @ApiProperty({\n    description: 'SSH command to connect to the sandbox',\n    example: 'ssh -p 2222 token@localhost',\n  })\n  sshCommand: string\n\n  static fromSshAccess(sshAccess: SshAccess, sshGatewayUrl: string): SshAccessDto {\n    const dto = new SshAccessDto()\n    dto.id = sshAccess.id\n    dto.sandboxId = sshAccess.sandboxId\n    dto.token = sshAccess.token\n    dto.expiresAt = sshAccess.expiresAt\n    dto.createdAt = sshAccess.createdAt\n    dto.updatedAt = sshAccess.updatedAt\n    // Robustly extract host and port from sshGatewayUrl\n    let host: string\n    let port: string\n    try {\n      // If protocol is present, use URL\n      if (sshGatewayUrl.includes('://')) {\n        const url = new URL(sshGatewayUrl)\n        host = url.hostname\n        port = url.port || '22'\n      } else {\n        // No protocol, parse manually\n        const [hostPart, portPart] = sshGatewayUrl.split(':')\n        host = hostPart\n        port = portPart || '22'\n      }\n    } catch {\n      // Fallback: treat as host only\n      host = sshGatewayUrl\n      port = '22'\n    }\n\n    if (port === '22') {\n      dto.sshCommand = `ssh ${sshAccess.token}@${host}`\n    } else {\n      dto.sshCommand = `ssh -p ${port} ${sshAccess.token}@${host}`\n    }\n\n    return dto\n  }\n}\n\nexport class SshAccessValidationDto {\n  @ApiProperty({\n    description: 'Whether the SSH access token is valid',\n    example: true,\n  })\n  valid: boolean\n\n  @ApiProperty({\n    description: 'ID of the sandbox this SSH access is for',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  sandboxId: string\n\n  static fromValidationResult(valid: boolean, sandboxId: string): SshAccessValidationDto {\n    const dto = new SshAccessValidationDto()\n    dto.valid = valid\n    dto.sandboxId = sandboxId\n    return dto\n  }\n}\n\nexport class RevokeSshAccessDto {\n  @ApiProperty({\n    description: 'ID of the sandbox',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  sandboxId: string\n\n  @ApiProperty({\n    description: 'SSH access token to revoke',\n    example: 'abc123def456ghi789jkl012mno345pqr678stu901vwx234yz',\n  })\n  token: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/storage-access-dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty } from '@nestjs/swagger'\n\nexport class StorageAccessDto {\n  @ApiProperty({\n    description: 'Access key for storage authentication',\n    example: 'temp-user-123',\n  })\n  accessKey: string\n\n  @ApiProperty({\n    description: 'Secret key for storage authentication',\n    example: 'abchbGciOiJIUzI1NiIs...',\n  })\n  secret: string\n\n  @ApiProperty({\n    description: 'Session token for storage authentication',\n    example: 'eyJhbGciOiJIUzI1NiIs...',\n  })\n  sessionToken: string\n\n  @ApiProperty({\n    description: 'Storage URL',\n    example: 'storage.example.com',\n  })\n  storageUrl: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'S3 bucket name',\n    example: 'daytona',\n  })\n  bucket: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/toolbox-proxy-url.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'ToolboxProxyUrl' })\nexport class ToolboxProxyUrlDto {\n  @ApiProperty({\n    description: 'The toolbox proxy URL for the sandbox',\n    example: 'https://proxy.app.daytona.io/toolbox',\n  })\n  url: string\n\n  constructor(url: string) {\n    this.url = url\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/toolbox.deprecated.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsString, IsBoolean, IsOptional, IsArray } from 'class-validator'\n\n@ApiSchema({ name: 'FileInfo' })\nexport class FileInfoDto {\n  @ApiProperty()\n  name: string\n\n  @ApiProperty()\n  isDir: boolean\n\n  @ApiProperty()\n  size: number\n\n  @ApiProperty()\n  modTime: string\n\n  @ApiProperty()\n  mode: string\n\n  @ApiProperty()\n  permissions: string\n\n  @ApiProperty()\n  owner: string\n\n  @ApiProperty()\n  group: string\n}\n\n@ApiSchema({ name: 'Match' })\nexport class MatchDto {\n  @ApiProperty()\n  file: string\n\n  @ApiProperty()\n  line: number\n\n  @ApiProperty()\n  content: string\n}\n\n@ApiSchema({ name: 'SearchFilesResponse' })\nexport class SearchFilesResponseDto {\n  @ApiProperty({ type: [String] })\n  files: string[]\n}\n\n@ApiSchema({ name: 'ReplaceRequest' })\nexport class ReplaceRequestDto {\n  @ApiProperty({ type: [String] })\n  files: string[]\n\n  @ApiProperty()\n  pattern: string\n\n  @ApiProperty()\n  newValue: string\n}\n\n@ApiSchema({ name: 'ReplaceResult' })\nexport class ReplaceResultDto {\n  @ApiPropertyOptional()\n  file?: string\n\n  @ApiPropertyOptional()\n  success?: boolean\n\n  @ApiPropertyOptional()\n  error?: string\n}\n\n@ApiSchema({ name: 'GitAddRequest' })\nexport class GitAddRequestDto {\n  @ApiProperty()\n  path: string\n\n  @ApiProperty({\n    type: [String],\n    description: 'files to add (use . for all files)',\n  })\n  files: string[]\n}\n\n@ApiSchema({ name: 'GitBranchRequest' })\nexport class GitBranchRequestDto {\n  @ApiProperty()\n  path: string\n\n  @ApiProperty()\n  name: string\n}\n\n@ApiSchema({ name: 'GitDeleteBranchRequest' })\nexport class GitDeleteBranchRequestDto {\n  @ApiProperty()\n  path: string\n\n  @ApiProperty()\n  name: string\n}\n\n@ApiSchema({ name: 'GitCloneRequest' })\nexport class GitCloneRequestDto {\n  @ApiProperty()\n  url: string\n\n  @ApiProperty()\n  path: string\n\n  @ApiPropertyOptional()\n  username?: string\n\n  @ApiPropertyOptional()\n  password?: string\n\n  @ApiPropertyOptional()\n  branch?: string\n\n  @ApiPropertyOptional()\n  commit_id?: string\n}\n\n@ApiSchema({ name: 'GitCommitRequest' })\nexport class GitCommitRequestDto {\n  @ApiProperty()\n  path: string\n\n  @ApiProperty()\n  message: string\n\n  @ApiProperty()\n  author: string\n\n  @ApiProperty()\n  email: string\n\n  @ApiPropertyOptional({\n    description: 'Allow creating an empty commit when no changes are staged',\n    default: false,\n  })\n  allow_empty?: boolean\n}\n\n@ApiSchema({ name: 'GitCommitResponse' })\nexport class GitCommitResponseDto {\n  @ApiProperty()\n  hash: string\n}\n\n@ApiSchema({ name: 'GitCheckoutRequest' })\nexport class GitCheckoutRequestDto {\n  @ApiProperty()\n  path: string\n\n  @ApiProperty()\n  branch: string\n}\n\n@ApiSchema({ name: 'GitRepoRequest' })\nexport class GitRepoRequestDto {\n  @ApiProperty()\n  path: string\n\n  @ApiPropertyOptional()\n  username?: string\n\n  @ApiPropertyOptional()\n  password?: string\n}\n\n@ApiSchema({ name: 'FileStatus' })\nexport class FileStatusDto {\n  @ApiProperty()\n  name: string\n\n  @ApiProperty()\n  staging: string\n\n  @ApiProperty()\n  worktree: string\n\n  @ApiProperty()\n  extra: string\n}\n\n@ApiSchema({ name: 'GitStatus' })\nexport class GitStatusDto {\n  @ApiProperty()\n  currentBranch: string\n\n  @ApiProperty({\n    type: [FileStatusDto],\n  })\n  fileStatus: FileStatusDto[]\n\n  @ApiPropertyOptional()\n  ahead?: number\n\n  @ApiPropertyOptional()\n  behind?: number\n\n  @ApiPropertyOptional()\n  branchPublished?: boolean\n}\n\n@ApiSchema({ name: 'ListBranchResponse' })\nexport class ListBranchResponseDto {\n  @ApiProperty({ type: [String] })\n  branches: string[]\n}\n\n@ApiSchema({ name: 'GitCommitInfo' })\nexport class GitCommitInfoDto {\n  @ApiProperty()\n  hash: string\n\n  @ApiProperty()\n  message: string\n\n  @ApiProperty()\n  author: string\n\n  @ApiProperty()\n  email: string\n\n  @ApiProperty()\n  timestamp: string\n}\n\n@ApiSchema({ name: 'ExecuteRequest' })\nexport class ExecuteRequestDto {\n  @ApiProperty()\n  command: string\n\n  @ApiPropertyOptional({\n    description: 'Current working directory',\n  })\n  cwd?: string\n\n  @ApiPropertyOptional({\n    description: 'Timeout in seconds, defaults to 10 seconds',\n  })\n  timeout?: number\n}\n\n@ApiSchema({ name: 'ExecuteResponse' })\nexport class ExecuteResponseDto {\n  @ApiProperty({\n    type: Number,\n    description: 'Exit code',\n    example: 0,\n  })\n  exitCode: number\n\n  @ApiProperty({\n    type: String,\n    description: 'Command output',\n    example: 'Command output here',\n  })\n  result: string\n}\n\n@ApiSchema({ name: 'ProjectDirResponse' })\nexport class ProjectDirResponseDto {\n  @ApiPropertyOptional()\n  dir?: string\n}\n\n@ApiSchema({ name: 'UserHomeDirResponse' })\nexport class UserHomeDirResponseDto {\n  @ApiPropertyOptional()\n  dir?: string\n}\n\n@ApiSchema({ name: 'WorkDirResponse' })\nexport class WorkDirResponseDto {\n  @ApiPropertyOptional()\n  dir?: string\n}\n\n@ApiSchema({ name: 'CreateSessionRequest' })\nexport class CreateSessionRequestDto {\n  @ApiProperty({\n    description: 'The ID of the session',\n    example: 'session-123',\n  })\n  @IsString()\n  sessionId: string\n}\n\n@ApiSchema({ name: 'SessionExecuteRequest' })\nexport class SessionExecuteRequestDto {\n  @ApiProperty({\n    description: 'The command to execute',\n    example: 'ls -la',\n  })\n  @IsString()\n  command: string\n\n  @ApiPropertyOptional({\n    description: 'Whether to execute the command asynchronously',\n    example: false,\n  })\n  @IsBoolean()\n  @IsOptional()\n  runAsync?: boolean\n\n  @ApiPropertyOptional({\n    description: 'Deprecated: Use runAsync instead. Whether to execute the command asynchronously',\n    example: false,\n    deprecated: true,\n  })\n  @IsBoolean()\n  @IsOptional()\n  async?: boolean\n\n  constructor(partial: Partial<SessionExecuteRequestDto>) {\n    Object.assign(this, partial)\n    // Migrate async to runAsync if async is set and runAsync is not set\n    if (this.async !== undefined && this.runAsync === undefined) {\n      this.runAsync = this.async\n    }\n  }\n}\n\n@ApiSchema({ name: 'SessionExecuteResponse' })\nexport class SessionExecuteResponseDto {\n  @ApiPropertyOptional({\n    description: 'The ID of the executed command',\n    example: 'cmd-123',\n  })\n  @IsString()\n  @IsOptional()\n  cmdId?: string\n\n  @ApiPropertyOptional({\n    description: 'The output of the executed command marked with stdout and stderr prefixes',\n    example: 'total 20\\ndrwxr-xr-x  4 user group  128 Mar 15 10:30 .',\n  })\n  @IsString()\n  @IsOptional()\n  output?: string\n\n  @ApiPropertyOptional({\n    description: 'The exit code of the executed command',\n    example: 0,\n  })\n  @IsOptional()\n  exitCode?: number\n}\n\n@ApiSchema({ name: 'Command' })\nexport class CommandDto {\n  @ApiProperty({\n    description: 'The ID of the command',\n    example: 'cmd-123',\n  })\n  @IsString()\n  id: string\n\n  @ApiProperty({\n    description: 'The command that was executed',\n    example: 'ls -la',\n  })\n  @IsString()\n  command: string\n\n  @ApiPropertyOptional({\n    description: 'The exit code of the command',\n    example: 0,\n  })\n  @IsOptional()\n  exitCode?: number\n}\n\n@ApiSchema({ name: 'Session' })\nexport class SessionDto {\n  @ApiProperty({\n    description: 'The ID of the session',\n    example: 'session-123',\n  })\n  @IsString()\n  sessionId: string\n\n  @ApiProperty({\n    description: 'The list of commands executed in this session',\n    type: [CommandDto],\n    nullable: true,\n  })\n  @IsArray()\n  @IsOptional()\n  commands?: CommandDto[] | null\n}\n\n// Computer Use DTOs\n@ApiSchema({ name: 'MousePosition' })\nexport class MousePositionDto {\n  @ApiProperty({\n    description: 'The X coordinate of the mouse cursor position',\n    example: 100,\n  })\n  x: number\n\n  @ApiProperty({\n    description: 'The Y coordinate of the mouse cursor position',\n    example: 200,\n  })\n  y: number\n}\n\n@ApiSchema({ name: 'MouseMoveRequest' })\nexport class MouseMoveRequestDto {\n  @ApiProperty({\n    description: 'The target X coordinate to move the mouse cursor to',\n    example: 150,\n  })\n  x: number\n\n  @ApiProperty({\n    description: 'The target Y coordinate to move the mouse cursor to',\n    example: 250,\n  })\n  y: number\n}\n\n@ApiSchema({ name: 'MouseMoveResponse' })\nexport class MouseMoveResponseDto {\n  @ApiProperty({\n    description: 'The actual X coordinate where the mouse cursor ended up',\n    example: 150,\n  })\n  x: number\n\n  @ApiProperty({\n    description: 'The actual Y coordinate where the mouse cursor ended up',\n    example: 250,\n  })\n  y: number\n}\n\n@ApiSchema({ name: 'MouseClickRequest' })\nexport class MouseClickRequestDto {\n  @ApiProperty({\n    description: 'The X coordinate where to perform the mouse click',\n    example: 100,\n  })\n  x: number\n\n  @ApiProperty({\n    description: 'The Y coordinate where to perform the mouse click',\n    example: 200,\n  })\n  y: number\n\n  @ApiPropertyOptional({\n    description: 'The mouse button to click (left, right, middle). Defaults to left',\n    example: 'left',\n  })\n  button?: string\n\n  @ApiPropertyOptional({\n    description: 'Whether to perform a double-click instead of a single click',\n    example: false,\n  })\n  double?: boolean\n}\n\n@ApiSchema({ name: 'MouseClickResponse' })\nexport class MouseClickResponseDto {\n  @ApiProperty({\n    description: 'The actual X coordinate where the click occurred',\n    example: 100,\n  })\n  x: number\n\n  @ApiProperty({\n    description: 'The actual Y coordinate where the click occurred',\n    example: 200,\n  })\n  y: number\n}\n\n@ApiSchema({ name: 'MouseDragRequest' })\nexport class MouseDragRequestDto {\n  @ApiProperty({\n    description: 'The starting X coordinate for the drag operation',\n    example: 100,\n  })\n  startX: number\n\n  @ApiProperty({\n    description: 'The starting Y coordinate for the drag operation',\n    example: 200,\n  })\n  startY: number\n\n  @ApiProperty({\n    description: 'The ending X coordinate for the drag operation',\n    example: 300,\n  })\n  endX: number\n\n  @ApiProperty({\n    description: 'The ending Y coordinate for the drag operation',\n    example: 400,\n  })\n  endY: number\n\n  @ApiPropertyOptional({\n    description: 'The mouse button to use for dragging (left, right, middle). Defaults to left',\n    example: 'left',\n  })\n  button?: string\n}\n\n@ApiSchema({ name: 'MouseDragResponse' })\nexport class MouseDragResponseDto {\n  @ApiProperty({\n    description: 'The actual X coordinate where the drag ended',\n    example: 300,\n  })\n  x: number\n\n  @ApiProperty({\n    description: 'The actual Y coordinate where the drag ended',\n    example: 400,\n  })\n  y: number\n}\n\n@ApiSchema({ name: 'MouseScrollRequest' })\nexport class MouseScrollRequestDto {\n  @ApiProperty({\n    description: 'The X coordinate where to perform the scroll operation',\n    example: 100,\n  })\n  x: number\n\n  @ApiProperty({\n    description: 'The Y coordinate where to perform the scroll operation',\n    example: 200,\n  })\n  y: number\n\n  @ApiProperty({\n    description: 'The scroll direction (up, down)',\n    example: 'down',\n  })\n  direction: string\n\n  @ApiPropertyOptional({\n    description: 'The number of scroll units to scroll. Defaults to 1',\n    example: 3,\n  })\n  amount?: number\n}\n\n@ApiSchema({ name: 'MouseScrollResponse' })\nexport class MouseScrollResponseDto {\n  @ApiProperty({\n    description: 'Whether the mouse scroll operation was successful',\n    example: true,\n  })\n  success: boolean\n}\n\n@ApiSchema({ name: 'KeyboardTypeRequest' })\nexport class KeyboardTypeRequestDto {\n  @ApiProperty({\n    description: 'The text to type using the keyboard',\n    example: 'Hello, World!',\n  })\n  text: string\n\n  @ApiPropertyOptional({\n    description: 'Delay in milliseconds between keystrokes. Defaults to 0',\n    example: 100,\n  })\n  delay?: number\n}\n\n@ApiSchema({ name: 'KeyboardPressRequest' })\nexport class KeyboardPressRequestDto {\n  @ApiProperty({\n    description: 'The key to press (e.g., a, b, c, enter, space, etc.)',\n    example: 'enter',\n  })\n  key: string\n\n  @ApiPropertyOptional({\n    description: 'Array of modifier keys to press along with the main key (ctrl, alt, shift, cmd)',\n    type: [String],\n    example: ['ctrl', 'shift'],\n  })\n  modifiers?: string[]\n}\n\n@ApiSchema({ name: 'KeyboardHotkeyRequest' })\nexport class KeyboardHotkeyRequestDto {\n  @ApiProperty({\n    description: 'The hotkey combination to press (e.g., \"ctrl+c\", \"cmd+v\", \"alt+tab\")',\n    example: 'ctrl+c',\n  })\n  keys: string\n}\n\n@ApiSchema({ name: 'ScreenshotResponse' })\nexport class ScreenshotResponseDto {\n  @ApiProperty({\n    description: 'Base64 encoded screenshot image data',\n    example: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',\n  })\n  screenshot: string\n\n  @ApiPropertyOptional({\n    description: 'The current cursor position when the screenshot was taken',\n    example: { x: 500, y: 300 },\n  })\n  cursorPosition?: { x: number; y: number }\n\n  @ApiPropertyOptional({\n    description: 'The size of the screenshot data in bytes',\n    example: 24576,\n  })\n  sizeBytes?: number\n}\n\n@ApiSchema({ name: 'RegionScreenshotRequest' })\nexport class RegionScreenshotRequestDto {\n  @ApiProperty({\n    description: 'The X coordinate of the top-left corner of the region to capture',\n    example: 100,\n  })\n  x: number\n\n  @ApiProperty({\n    description: 'The Y coordinate of the top-left corner of the region to capture',\n    example: 100,\n  })\n  y: number\n\n  @ApiProperty({\n    description: 'The width of the region to capture in pixels',\n    example: 800,\n  })\n  width: number\n\n  @ApiProperty({\n    description: 'The height of the region to capture in pixels',\n    example: 600,\n  })\n  height: number\n}\n\n@ApiSchema({ name: 'RegionScreenshotResponse' })\nexport class RegionScreenshotResponseDto {\n  @ApiProperty({\n    description: 'Base64 encoded screenshot image data of the specified region',\n    example: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',\n  })\n  screenshot: string\n\n  @ApiPropertyOptional({\n    description: 'The current cursor position when the region screenshot was taken',\n    example: { x: 500, y: 300 },\n  })\n  cursorPosition?: { x: number; y: number }\n\n  @ApiPropertyOptional({\n    description: 'The size of the screenshot data in bytes',\n    example: 24576,\n  })\n  sizeBytes?: number\n}\n\n@ApiSchema({ name: 'CompressedScreenshotResponse' })\nexport class CompressedScreenshotResponseDto {\n  @ApiProperty({\n    description: 'Base64 encoded compressed screenshot image data',\n    example: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',\n  })\n  screenshot: string\n\n  @ApiPropertyOptional({\n    description: 'The current cursor position when the compressed screenshot was taken',\n    example: { x: 250, y: 150 },\n  })\n  cursorPosition?: { x: number; y: number }\n\n  @ApiPropertyOptional({\n    description: 'The size of the compressed screenshot data in bytes',\n    example: 12288,\n  })\n  sizeBytes?: number\n}\n\n@ApiSchema({ name: 'DisplayInfoResponse' })\nexport class DisplayInfoResponseDto {\n  @ApiProperty({\n    description: 'Array of display information for all connected displays',\n    type: [Object],\n    example: [\n      {\n        id: 0,\n        x: 0,\n        y: 0,\n        width: 1920,\n        height: 1080,\n        is_active: true,\n      },\n    ],\n  })\n  displays: Array<{ id: number; x: number; y: number; width: number; height: number; is_active: boolean }>\n}\n\n@ApiSchema({ name: 'WindowsResponse' })\nexport class WindowsResponseDto {\n  @ApiProperty({\n    description: 'Array of window information for all visible windows',\n    type: [Object],\n    example: [\n      {\n        id: 12345,\n        title: 'Terminal',\n      },\n    ],\n  })\n  windows: Array<{ id: number; title: string }>\n\n  @ApiProperty({\n    description: 'The total number of windows found',\n    example: 5,\n  })\n  count: number\n}\n\n// Computer Use Management Response DTOs\n\n@ApiSchema({ name: 'ComputerUseStartResponse' })\nexport class ComputerUseStartResponseDto {\n  @ApiProperty({\n    description: 'A message indicating the result of starting computer use processes',\n    example: 'Computer use processes started successfully',\n  })\n  message: string\n\n  @ApiProperty({\n    description: 'Status information about all VNC desktop processes after starting',\n    type: Object,\n    example: {\n      xvfb: { running: true, priority: 100, autoRestart: true, pid: 12345 },\n      xfce4: { running: true, priority: 200, autoRestart: true, pid: 12346 },\n      x11vnc: { running: true, priority: 300, autoRestart: true, pid: 12347 },\n      novnc: { running: true, priority: 400, autoRestart: true, pid: 12348 },\n    },\n  })\n  status: Record<string, any>\n}\n\n@ApiSchema({ name: 'ComputerUseStopResponse' })\nexport class ComputerUseStopResponseDto {\n  @ApiProperty({\n    description: 'A message indicating the result of stopping computer use processes',\n    example: 'Computer use processes stopped successfully',\n  })\n  message: string\n\n  @ApiProperty({\n    description: 'Status information about all VNC desktop processes after stopping',\n    type: Object,\n    example: {\n      xvfb: { running: false, priority: 100, autoRestart: true },\n      xfce4: { running: false, priority: 200, autoRestart: true },\n      x11vnc: { running: false, priority: 300, autoRestart: true },\n      novnc: { running: false, priority: 400, autoRestart: true },\n    },\n  })\n  status: Record<string, any>\n}\n\n@ApiSchema({ name: 'ComputerUseStatusResponse' })\nexport class ComputerUseStatusResponseDto {\n  @ApiProperty({\n    description: 'Status of computer use services (active, partial, inactive, error)',\n    example: 'active',\n    enum: ['active', 'partial', 'inactive', 'error'],\n  })\n  status: string\n}\n\n@ApiSchema({ name: 'ProcessStatusResponse' })\nexport class ProcessStatusResponseDto {\n  @ApiProperty({\n    description: 'The name of the VNC process being checked',\n    example: 'xfce4',\n  })\n  processName: string\n\n  @ApiProperty({\n    description: 'Whether the specified VNC process is currently running',\n    example: true,\n  })\n  running: boolean\n}\n\n@ApiSchema({ name: 'ProcessRestartResponse' })\nexport class ProcessRestartResponseDto {\n  @ApiProperty({\n    description: 'A message indicating the result of restarting the process',\n    example: 'Process xfce4 restarted successfully',\n  })\n  message: string\n\n  @ApiProperty({\n    description: 'The name of the VNC process that was restarted',\n    example: 'xfce4',\n  })\n  processName: string\n}\n\n@ApiSchema({ name: 'ProcessLogsResponse' })\nexport class ProcessLogsResponseDto {\n  @ApiProperty({\n    description: 'The name of the VNC process whose logs were retrieved',\n    example: 'novnc',\n  })\n  processName: string\n\n  @ApiProperty({\n    description: 'The log output from the specified VNC process',\n    example: '2024-01-15 10:30:45 [INFO] NoVNC server started on port 6080',\n  })\n  logs: string\n}\n\n@ApiSchema({ name: 'ProcessErrorsResponse' })\nexport class ProcessErrorsResponseDto {\n  @ApiProperty({\n    description: 'The name of the VNC process whose error logs were retrieved',\n    example: 'x11vnc',\n  })\n  processName: string\n\n  @ApiProperty({\n    description: 'The error log output from the specified VNC process',\n    example: '2024-01-15 10:30:45 [ERROR] Failed to bind to port 5901',\n  })\n  errors: string\n}\n\n// PTY DTOs\n@ApiSchema({ name: 'PtyCreateRequest' })\nexport class PtyCreateRequestDto {\n  @ApiProperty({\n    description: 'The unique identifier for the PTY session',\n    example: 'pty-session-12345',\n  })\n  id: string\n\n  @ApiPropertyOptional({\n    description: \"Starting directory for the PTY session, defaults to the sandbox's working directory\",\n    example: '/home/user',\n  })\n  cwd?: string\n\n  @ApiPropertyOptional({\n    description: 'Environment variables for the PTY session',\n    type: Object,\n    example: { TERM: 'xterm-256color', PS1: '\\\\u@daytona:\\\\w$ ' },\n  })\n  envs?: Record<string, string>\n\n  @ApiPropertyOptional({\n    description: 'Number of terminal columns',\n    example: 80,\n  })\n  cols?: number\n\n  @ApiPropertyOptional({\n    description: 'Number of terminal rows',\n    example: 24,\n  })\n  rows?: number\n\n  @ApiPropertyOptional({\n    description: 'Whether to start the PTY session lazily (only start when first client connects)',\n    example: false,\n    default: false,\n  })\n  lazyStart?: boolean\n}\n\n@ApiSchema({ name: 'PtyCreateResponse' })\nexport class PtyCreateResponseDto {\n  @ApiProperty({\n    description: 'The unique identifier for the created PTY session',\n    example: 'pty-session-12345',\n  })\n  sessionId: string\n}\n\n@ApiSchema({ name: 'PtySessionInfo' })\nexport class PtySessionInfoDto {\n  @ApiProperty({\n    description: 'The unique identifier for the PTY session',\n    example: 'pty-session-12345',\n  })\n  id: string\n\n  @ApiProperty({\n    description: \"Starting directory for the PTY session, defaults to the sandbox's working directory\",\n    example: '/home/user',\n  })\n  cwd: string\n\n  @ApiProperty({\n    description: 'Environment variables for the PTY session',\n    type: Object,\n    example: { TERM: 'xterm-256color', PS1: '\\\\u@daytona:\\\\w$ ' },\n  })\n  envs: Record<string, string>\n\n  @ApiProperty({\n    description: 'Number of terminal columns',\n    example: 80,\n  })\n  cols: number\n\n  @ApiProperty({\n    description: 'Number of terminal rows',\n    example: 24,\n  })\n  rows: number\n\n  @ApiProperty({\n    description: 'When the PTY session was created',\n    example: '2024-01-15T10:30:45Z',\n  })\n  createdAt: string\n\n  @ApiProperty({\n    description: 'Whether the PTY session is currently active',\n    example: true,\n  })\n  active: boolean\n\n  @ApiProperty({\n    description: 'Whether the PTY session uses lazy start (only start when first client connects)',\n    example: false,\n    default: false,\n  })\n  lazyStart: boolean\n}\n\n@ApiSchema({ name: 'PtyListResponse' })\nexport class PtyListResponseDto {\n  @ApiProperty({\n    description: 'List of active PTY sessions',\n    type: [PtySessionInfoDto],\n  })\n  sessions: PtySessionInfoDto[]\n}\n\n@ApiSchema({ name: 'PtyResizeRequest' })\nexport class PtyResizeRequestDto {\n  @ApiProperty({\n    description: 'Number of terminal columns',\n    example: 80,\n  })\n  cols: number\n\n  @ApiProperty({\n    description: 'Number of terminal rows',\n    example: 24,\n  })\n  rows: number\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/update-sandbox-network-settings.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsOptional, IsString, IsBoolean } from 'class-validator'\nimport { ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'UpdateSandboxNetworkSettings' })\nexport class UpdateSandboxNetworkSettingsDto {\n  @ApiPropertyOptional({\n    description: 'Whether to block all network access for the sandbox',\n    example: false,\n  })\n  @IsOptional()\n  @IsBoolean()\n  networkBlockAll?: boolean\n\n  @ApiPropertyOptional({\n    description: 'Comma-separated list of allowed CIDR network addresses for the sandbox',\n    example: '192.168.1.0/16,10.0.0.0/24',\n  })\n  @IsOptional()\n  @IsString()\n  networkAllowList?: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/update-sandbox-state.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'\nimport { IsBoolean, IsEnum, IsOptional, IsString } from 'class-validator'\nimport { SandboxState } from '../enums/sandbox-state.enum'\n\nexport class UpdateSandboxStateDto {\n  @IsEnum(SandboxState)\n  @ApiProperty({\n    description: 'The new state for the sandbox',\n    enum: SandboxState,\n    example: SandboxState.STARTED,\n  })\n  state: SandboxState\n\n  @IsOptional()\n  @IsString()\n  @ApiPropertyOptional({\n    description: 'Optional error message when reporting an error state',\n    example: 'Failed to pull snapshot image',\n  })\n  errorReason?: string\n\n  @IsOptional()\n  @IsBoolean()\n  @ApiPropertyOptional({\n    description: 'Whether the sandbox is recoverable',\n    example: true,\n  })\n  recoverable?: boolean\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/update-snapshot.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsBoolean } from 'class-validator'\n\n@ApiSchema({ name: 'SetSnapshotGeneralStatusDto' })\nexport class SetSnapshotGeneralStatusDto {\n  @ApiProperty({\n    description: 'Whether the snapshot is general',\n    example: true,\n  })\n  @IsBoolean()\n  general: boolean\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/upload-file.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'UploadFile' })\nexport class UploadFileDto {\n  @ApiProperty({ type: 'string', format: 'binary' })\n  file: any\n\n  @ApiProperty()\n  path: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/volume.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'\nimport { IsEnum } from 'class-validator'\nimport { VolumeState } from '../enums/volume-state.enum'\nimport { Volume } from '../entities/volume.entity'\n\nexport class VolumeDto {\n  @ApiProperty({\n    description: 'Volume ID',\n    example: 'vol-12345678',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Volume name',\n    example: 'my-volume',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'Volume state',\n    enum: VolumeState,\n    enumName: 'VolumeState',\n    example: VolumeState.READY,\n  })\n  @IsEnum(VolumeState)\n  state: VolumeState\n\n  @ApiProperty({\n    description: 'Creation timestamp',\n    example: '2023-01-01T00:00:00.000Z',\n  })\n  createdAt: string\n\n  @ApiProperty({\n    description: 'Last update timestamp',\n    example: '2023-01-01T00:00:00.000Z',\n  })\n  updatedAt: string\n\n  @ApiPropertyOptional({\n    description: 'Last used timestamp',\n    example: '2023-01-01T00:00:00.000Z',\n    nullable: true,\n  })\n  lastUsedAt?: string\n\n  @ApiProperty({\n    description: 'The error reason of the volume',\n    example: 'Error processing volume',\n    nullable: true,\n  })\n  errorReason?: string\n\n  static fromVolume(volume: Volume): VolumeDto {\n    return {\n      id: volume.id,\n      name: volume.name,\n      organizationId: volume.organizationId,\n      state: volume.state,\n      createdAt: volume.createdAt?.toISOString(),\n      updatedAt: volume.updatedAt?.toISOString(),\n      lastUsedAt: volume.lastUsedAt?.toISOString(),\n      errorReason: volume.errorReason,\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/workspace-port-preview-url.deprecated.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsString } from 'class-validator'\n\n@ApiSchema({ name: 'WorkspacePortPreviewUrl' })\nexport class WorkspacePortPreviewUrlDto {\n  @ApiProperty({\n    description: 'Preview url',\n    example: 'https://123456-mysandbox.runner.com',\n  })\n  @IsString()\n  url: string\n\n  @ApiProperty({\n    description: 'Access token',\n    example: 'ul67qtv-jl6wb9z5o3eii-ljqt9qed6l',\n  })\n  @IsString()\n  token: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/dto/workspace.deprecated.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { SandboxDto } from './sandbox.dto'\nimport { IsEnum, IsOptional } from 'class-validator'\nimport { BackupState as SnapshotState } from '../enums/backup-state.enum'\nimport { Sandbox } from '../entities/sandbox.entity'\n\n@ApiSchema({ name: 'SandboxInfo' })\nexport class SandboxInfoDto {\n  @ApiProperty({\n    description: 'The creation timestamp of the project',\n    example: '2023-10-01T12:00:00Z',\n  })\n  created: string\n\n  @ApiProperty({\n    description: 'Deprecated: The name of the sandbox',\n    example: 'MySandbox',\n    deprecated: true,\n    default: '',\n  })\n  name: string\n\n  @ApiPropertyOptional({\n    description: 'Additional metadata provided by the provider',\n    example: '{\"key\": \"value\"}',\n    required: false,\n  })\n  @IsOptional()\n  providerMetadata?: string\n}\n\n@ApiSchema({ name: 'Workspace' })\nexport class WorkspaceDto extends SandboxDto {\n  @ApiPropertyOptional({\n    description: 'The image used for the workspace',\n    example: 'daytonaio/workspace:latest',\n  })\n  image: string\n\n  @ApiPropertyOptional({\n    description: 'The state of the snapshot',\n    enum: SnapshotState,\n    example: Object.values(SnapshotState)[0],\n    required: false,\n  })\n  @IsEnum(SnapshotState)\n  snapshotState?: SnapshotState\n\n  @ApiPropertyOptional({\n    description: 'The creation timestamp of the last snapshot',\n    example: '2024-10-01T12:00:00Z',\n    required: false,\n  })\n  snapshotCreatedAt?: string\n\n  @ApiPropertyOptional({\n    description: 'Additional information about the sandbox',\n    type: SandboxInfoDto,\n    required: false,\n  })\n  @IsOptional()\n  info?: SandboxInfoDto\n\n  constructor() {\n    super()\n  }\n\n  static fromSandbox(sandbox: Sandbox): WorkspaceDto {\n    // Send empty string for toolboxProxyUrl as it is not needed in deprecated DTO\n    const dto = super.fromSandbox(sandbox, '')\n    return this.fromSandboxDto(dto)\n  }\n\n  static fromSandboxDto(sandboxDto: SandboxDto): WorkspaceDto {\n    return {\n      ...sandboxDto,\n      image: sandboxDto.snapshot,\n      snapshotState: sandboxDto.backupState,\n      snapshotCreatedAt: sandboxDto.backupCreatedAt,\n      info: {\n        name: sandboxDto.name,\n        created: sandboxDto.createdAt,\n        providerMetadata: JSON.stringify({\n          state: sandboxDto.state,\n          region: sandboxDto.target,\n          class: sandboxDto.class,\n          updatedAt: sandboxDto.updatedAt,\n          lastSnapshot: sandboxDto.backupCreatedAt,\n          cpu: sandboxDto.cpu,\n          gpu: sandboxDto.gpu,\n          memory: sandboxDto.memory,\n          disk: sandboxDto.disk,\n          autoStopInterval: sandboxDto.autoStopInterval,\n          autoArchiveInterval: sandboxDto.autoArchiveInterval,\n          daemonVersion: sandboxDto.daemonVersion,\n        }),\n      },\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/build-info.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, OneToMany, PrimaryColumn, UpdateDateColumn, BeforeInsert } from 'typeorm'\nimport { Snapshot } from './snapshot.entity'\nimport { Sandbox } from './sandbox.entity'\nimport { createHash } from 'crypto'\n\nexport function generateBuildInfoHash(dockerfileContent: string, contextHashes: string[] = []): string {\n  const sortedContextHashes = [...contextHashes].sort() || []\n  const combined = dockerfileContent + sortedContextHashes.join('')\n  const hash = createHash('sha256').update(combined).digest('hex')\n  return 'daytona-' + hash + ':daytona'\n}\n\n@Entity()\nexport class BuildInfo {\n  @PrimaryColumn()\n  snapshotRef: string\n\n  @Column({ type: 'text', nullable: true })\n  dockerfileContent?: string\n\n  @Column('simple-array', { nullable: true })\n  contextHashes?: string[]\n\n  @OneToMany(() => Snapshot, (snapshot) => snapshot.buildInfo)\n  snapshots: Snapshot[]\n\n  @OneToMany(() => Sandbox, (sandbox) => sandbox.buildInfo)\n  sandboxes: Sandbox[]\n\n  @Column({ type: 'timestamp with time zone', default: () => 'CURRENT_TIMESTAMP' })\n  lastUsedAt: Date\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  @BeforeInsert()\n  generateHash() {\n    this.snapshotRef = generateBuildInfoHash(this.dockerfileContent, this.contextHashes)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/job.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Check,\n  Column,\n  CreateDateColumn,\n  Entity,\n  Index,\n  PrimaryGeneratedColumn,\n  UpdateDateColumn,\n  VersionColumn,\n} from 'typeorm'\nimport { JobStatus } from '../enums/job-status.enum'\nimport { JobType } from '../enums/job-type.enum'\nimport { ResourceType } from '../enums/resource-type.enum'\nimport { v4 } from 'uuid'\n\n@Entity()\n@Index(['runnerId', 'status'])\n@Index(['status', 'createdAt'])\n@Index(['resourceType', 'resourceId'])\n@Index('IDX_UNIQUE_INCOMPLETE_JOB', ['resourceType', 'resourceId', 'runnerId'], {\n  unique: true,\n  where: '\"completedAt\" IS NULL',\n})\n// FIXME: Add this once https://github.com/typeorm/typeorm/issues/11714 is resolved\n// @Check(\n//   'VALIDATE_JOB_TYPE',\n//   `\"type\" IN (${Object.values(JobType)\n//     .map((v) => `'${v}'`)\n//     .join(', ')})`,\n// )\nexport class Job {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @VersionColumn()\n  version: number\n\n  @Column({\n    type: 'character varying',\n  })\n  type: JobType\n\n  @Column({\n    type: 'enum',\n    enum: JobStatus,\n    default: JobStatus.PENDING,\n  })\n  status: JobStatus\n\n  @Column()\n  runnerId: string\n\n  @Column({\n    type: 'enum',\n    enum: ResourceType,\n  })\n  resourceType: ResourceType\n\n  @Column()\n  resourceId: string\n\n  @Column({\n    nullable: true,\n  })\n  payload: string | null\n\n  @Column({\n    nullable: true,\n  })\n  resultMetadata: string | null\n\n  @Column({\n    type: 'jsonb',\n    nullable: true,\n  })\n  traceContext: Record<string, string> | null\n\n  @Column({\n    nullable: true,\n    type: 'text',\n  })\n  errorMessage: string | null\n\n  @Column({\n    nullable: true,\n    type: 'timestamp with time zone',\n  })\n  startedAt: Date | null\n\n  @Column({\n    nullable: true,\n    type: 'timestamp with time zone',\n  })\n  completedAt: Date | null\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  constructor(params: {\n    id?: string\n    type: JobType\n    status?: JobStatus\n    runnerId: string\n    resourceType: ResourceType\n    resourceId: string\n    payload?: string | null\n    traceContext?: Record<string, string> | null\n    errorMessage?: string | null\n    startedAt?: Date | null\n    completedAt?: Date | null\n  }) {\n    this.id = params.id || v4()\n    this.version = 1\n    this.type = params.type\n    this.status = params.status || JobStatus.PENDING\n    this.runnerId = params.runnerId\n    this.resourceType = params.resourceType\n    this.resourceId = params.resourceId\n    this.payload = params.payload || null\n    this.traceContext = params.traceContext || null\n    this.errorMessage = params.errorMessage || null\n    this.startedAt = params.startedAt || null\n    this.completedAt = params.completedAt || null\n    this.createdAt = new Date()\n    this.updatedAt = new Date()\n  }\n\n  getResultMetadata(): Record<string, any> | null {\n    if (!this.resultMetadata) {\n      return null\n    }\n\n    try {\n      return JSON.parse(this.resultMetadata)\n    } catch {\n      return null\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/runner.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn, Unique, UpdateDateColumn } from 'typeorm'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\nimport { RunnerState } from '../enums/runner-state.enum'\nimport { RunnerServiceInfo } from '../common/runner-service-info'\n\n@Entity()\n@Unique(['region', 'name'])\n@Index(['state', 'unschedulable', 'region'])\nexport class Runner {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column({\n    nullable: true,\n  })\n  domain: string | null\n\n  @Column({\n    nullable: true,\n  })\n  apiUrl: string | null\n\n  @Column({\n    nullable: true,\n  })\n  proxyUrl: string | null\n\n  @Column()\n  apiKey: string\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  cpu: number\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  memoryGiB: number\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  diskGiB: number\n\n  @Column({\n    nullable: true,\n  })\n  gpu: number | null\n\n  @Column({\n    nullable: true,\n  })\n  gpuType: string | null\n\n  @Column({\n    type: 'enum',\n    enum: SandboxClass,\n    default: SandboxClass.SMALL,\n  })\n  class: SandboxClass\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  currentCpuLoadAverage: number\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  currentCpuUsagePercentage: number\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  currentMemoryUsagePercentage: number\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  currentDiskUsagePercentage: number\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  currentAllocatedCpu: number\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  currentAllocatedMemoryGiB: number\n\n  @Column({\n    type: 'float',\n    default: 0,\n  })\n  currentAllocatedDiskGiB: number\n\n  @Column({\n    default: 0,\n  })\n  currentSnapshotCount: number\n\n  @Column({\n    default: 0,\n  })\n  currentStartedSandboxes: number\n\n  @Column({\n    default: 0,\n  })\n  availabilityScore: number\n\n  @Column()\n  region: string\n\n  @Column()\n  name: string\n\n  @Column({\n    type: 'enum',\n    enum: RunnerState,\n    default: RunnerState.INITIALIZING,\n  })\n  state: RunnerState\n\n  @Column({\n    default: 'v0.0.0-dev',\n    nullable: true,\n  })\n  appVersion: string | null\n\n  @Column({\n    default: '0',\n  })\n  apiVersion: string\n\n  @Column({\n    nullable: true,\n    type: 'timestamp with time zone',\n  })\n  lastChecked: Date\n\n  @Column({\n    default: false,\n  })\n  unschedulable: boolean\n\n  @Column({\n    default: false,\n  })\n  draining: boolean\n\n  @Column({\n    type: 'jsonb',\n    nullable: true,\n    default: null,\n  })\n  serviceHealth: RunnerServiceInfo[] | null\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  constructor(params: {\n    region: string\n    name: string\n    apiKey: string\n    apiVersion: string\n    cpu?: number\n    memoryGiB?: number\n    diskGiB?: number\n    domain?: string | null\n    apiUrl?: string\n    proxyUrl?: string\n    appVersion?: string | null\n  }) {\n    this.region = params.region\n    this.name = params.name\n    this.apiKey = params.apiKey\n    this.cpu = params.cpu ?? 0\n    this.memoryGiB = params.memoryGiB ?? 0\n    this.diskGiB = params.diskGiB ?? 0\n    this.domain = params.domain ?? null\n    this.apiUrl = params.apiUrl\n    this.proxyUrl = params.proxyUrl\n    this.class = SandboxClass.SMALL\n    this.apiVersion = params.apiVersion\n    this.appVersion = params.appVersion ?? null\n    this.gpu = null\n    this.gpuType = null\n\n    if (this.apiVersion === '0') {\n      if (!this.apiUrl) {\n        throw new Error('API URL is required for runner version 0')\n      }\n      if (!this.proxyUrl) {\n        this.proxyUrl = this.apiUrl\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/sandbox.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Column,\n  CreateDateColumn,\n  Entity,\n  Index,\n  JoinColumn,\n  ManyToOne,\n  PrimaryGeneratedColumn,\n  Unique,\n  UpdateDateColumn,\n} from 'typeorm'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { v4 as uuidv4 } from 'uuid'\nimport { SandboxVolume } from '../dto/sandbox.dto'\nimport { BuildInfo } from './build-info.entity'\nimport { nanoid } from 'nanoid'\n\n@Entity()\n@Unique(['organizationId', 'name'])\n@Index('sandbox_state_idx', ['state'])\n@Index('sandbox_desiredstate_idx', ['desiredState'])\n@Index('sandbox_snapshot_idx', ['snapshot'])\n@Index('sandbox_runnerid_idx', ['runnerId'])\n@Index('sandbox_runner_state_idx', ['runnerId', 'state'])\n@Index('sandbox_organizationid_idx', ['organizationId'])\n@Index('sandbox_region_idx', ['region'])\n@Index('sandbox_resources_idx', ['cpu', 'mem', 'disk', 'gpu'])\n@Index('sandbox_backupstate_idx', ['backupState'])\n@Index('sandbox_runner_state_desired_idx', ['runnerId', 'state', 'desiredState'], {\n  where: '\"pending\" = false',\n})\n@Index('sandbox_active_only_idx', ['id'], {\n  where: `\"state\" <> ALL (ARRAY['destroyed'::sandbox_state_enum, 'archived'::sandbox_state_enum])`,\n})\n@Index('sandbox_pending_idx', ['id'], {\n  where: `\"pending\" = true`,\n})\n@Index('idx_sandbox_authtoken', ['authToken'])\n@Index('sandbox_labels_gin_full_idx', { synchronize: false })\nexport class Sandbox {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column({\n    type: 'uuid',\n  })\n  organizationId: string\n\n  @Column()\n  name: string\n\n  @Column()\n  region: string\n\n  @Column({\n    type: 'uuid',\n    nullable: true,\n  })\n  runnerId?: string\n\n  //  this is the runnerId of the runner that was previously assigned to the sandbox\n  //  if something goes wrong with new runner assignment, we can revert to the previous runner\n  @Column({\n    type: 'uuid',\n    nullable: true,\n  })\n  prevRunnerId?: string\n\n  @Column({\n    type: 'enum',\n    enum: SandboxClass,\n    default: SandboxClass.SMALL,\n  })\n  class = SandboxClass.SMALL\n\n  @Column({\n    type: 'enum',\n    enum: SandboxState,\n    default: SandboxState.UNKNOWN,\n  })\n  state = SandboxState.UNKNOWN\n\n  @Column({\n    type: 'enum',\n    enum: SandboxDesiredState,\n    default: SandboxDesiredState.STARTED,\n  })\n  desiredState = SandboxDesiredState.STARTED\n\n  @Column({ nullable: true })\n  snapshot?: string\n\n  @Column()\n  osUser: string\n\n  @Column({ nullable: true })\n  errorReason?: string\n\n  @Column({ default: false, type: 'boolean' })\n  recoverable = false\n\n  @Column({\n    type: 'jsonb',\n    default: {},\n  })\n  env: { [key: string]: string } = {}\n\n  @Column({ default: false, type: 'boolean' })\n  public = false\n\n  @Column({ default: false, type: 'boolean' })\n  networkBlockAll = false\n\n  @Column({ nullable: true })\n  networkAllowList?: string\n\n  @Column('jsonb', { nullable: true })\n  labels: { [key: string]: string }\n\n  @Column({ nullable: true })\n  backupRegistryId: string | null\n\n  @Column({ nullable: true })\n  backupSnapshot: string | null\n\n  @Column({ nullable: true, type: 'timestamp with time zone' })\n  lastBackupAt: Date | null\n\n  @Column({\n    type: 'enum',\n    enum: BackupState,\n    default: BackupState.NONE,\n  })\n  backupState = BackupState.NONE\n\n  @Column({\n    type: 'text',\n    nullable: true,\n  })\n  backupErrorReason: string | null\n\n  @Column({\n    type: 'jsonb',\n    default: [],\n  })\n  existingBackupSnapshots: Array<{\n    snapshotName: string\n    createdAt: Date\n  }> = []\n\n  @Column({ type: 'int', default: 2 })\n  cpu = 2\n\n  @Column({ type: 'int', default: 0 })\n  gpu = 0\n\n  @Column({ type: 'int', default: 4 })\n  mem = 4\n\n  @Column({ type: 'int', default: 10 })\n  disk = 10\n\n  @Column({\n    type: 'jsonb',\n    default: [],\n  })\n  volumes: SandboxVolume[] = []\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  @Column({ nullable: true, type: 'timestamp with time zone' })\n  lastActivityAt?: Date\n\n  //  this is the interval in minutes after which the sandbox will be stopped if lastActivityAt is not updated\n  //  if set to 0, auto stop will be disabled\n  @Column({ default: 15, type: 'int' })\n  autoStopInterval: number | undefined = 15\n\n  //  this is the interval in minutes after which a continuously stopped workspace will be automatically archived\n  @Column({ default: 7 * 24 * 60, type: 'int' })\n  autoArchiveInterval: number | undefined = 7 * 24 * 60\n\n  //  this is the interval in minutes after which a continuously stopped workspace will be automatically deleted\n  //  if set to negative value, auto delete will be disabled\n  //  if set to 0, sandbox will be immediately deleted upon stopping\n  @Column({ default: -1, type: 'int' })\n  autoDeleteInterval: number | undefined = -1\n\n  @Column({ default: false, type: 'boolean' })\n  pending: boolean | undefined = false\n\n  @Column({ default: () => 'MD5(random()::text)', type: 'text' })\n  authToken = nanoid(32).toLocaleLowerCase()\n\n  @ManyToOne(() => BuildInfo, (buildInfo) => buildInfo.sandboxes, {\n    nullable: true,\n  })\n  @JoinColumn()\n  buildInfo?: BuildInfo\n\n  @Column({ nullable: true })\n  daemonVersion?: string\n\n  constructor(region: string, name?: string) {\n    this.id = uuidv4()\n    // Set name - use provided name or fallback to ID\n    this.name = name || this.id\n    this.region = region\n  }\n\n  /**\n   * Helper method that returns the update data needed for a backup state update.\n   */\n  static getBackupStateUpdate(\n    sandbox: Sandbox,\n    backupState: BackupState,\n    backupSnapshot?: string | null,\n    backupRegistryId?: string | null,\n    backupErrorReason?: string | null,\n  ): Partial<Sandbox> {\n    const update: Partial<Sandbox> = {\n      backupState,\n    }\n    switch (backupState) {\n      case BackupState.NONE:\n        update.backupSnapshot = null\n        break\n      case BackupState.COMPLETED: {\n        const now = new Date()\n        update.lastBackupAt = now\n        update.existingBackupSnapshots = [\n          ...sandbox.existingBackupSnapshots,\n          {\n            snapshotName: sandbox.backupSnapshot,\n            createdAt: now,\n          },\n        ]\n        update.backupErrorReason = null\n        break\n      }\n    }\n    if (backupSnapshot !== undefined) {\n      update.backupSnapshot = backupSnapshot\n    }\n    if (backupRegistryId !== undefined) {\n      update.backupRegistryId = backupRegistryId\n    }\n    if (backupErrorReason !== undefined) {\n      update.backupErrorReason = backupErrorReason\n    }\n    return update\n  }\n\n  /**\n   * Helper method that returns the update data needed for a soft delete operation.\n   */\n  static getSoftDeleteUpdate(sandbox: Sandbox): Partial<Sandbox> {\n    return {\n      pending: true,\n      desiredState: SandboxDesiredState.DESTROYED,\n      backupState: BackupState.NONE,\n      name: 'DESTROYED_' + sandbox.name + '_' + Date.now(),\n    }\n  }\n\n  /**\n   * Asserts that the current entity state is valid.\n   */\n  assertValid(): void {\n    this.validateDesiredStateTransition()\n  }\n\n  private validateDesiredStateTransition(): void {\n    switch (this.desiredState) {\n      case SandboxDesiredState.STARTED:\n        if (\n          [\n            SandboxState.STARTED,\n            SandboxState.STOPPED,\n            SandboxState.STARTING,\n            SandboxState.ARCHIVED,\n            SandboxState.CREATING,\n            SandboxState.UNKNOWN,\n            SandboxState.RESTORING,\n            SandboxState.PENDING_BUILD,\n            SandboxState.BUILDING_SNAPSHOT,\n            SandboxState.PULLING_SNAPSHOT,\n            SandboxState.ARCHIVING,\n            SandboxState.ERROR,\n            SandboxState.BUILD_FAILED,\n            SandboxState.RESIZING,\n          ].includes(this.state)\n        ) {\n          break\n        }\n        throw new Error(`Sandbox ${this.id} is not in a valid state to be started. State: ${this.state}`)\n      case SandboxDesiredState.STOPPED:\n        if (\n          [\n            SandboxState.STARTED,\n            SandboxState.STOPPING,\n            SandboxState.STOPPED,\n            SandboxState.ERROR,\n            SandboxState.BUILD_FAILED,\n            SandboxState.RESIZING,\n          ].includes(this.state)\n        ) {\n          break\n        }\n        throw new Error(`Sandbox ${this.id} is not in a valid state to be stopped. State: ${this.state}`)\n      case SandboxDesiredState.ARCHIVED:\n        if (\n          [\n            SandboxState.ARCHIVED,\n            SandboxState.ARCHIVING,\n            SandboxState.STOPPED,\n            SandboxState.ERROR,\n            SandboxState.BUILD_FAILED,\n          ].includes(this.state)\n        ) {\n          break\n        }\n        throw new Error(`Sandbox ${this.id} is not in a valid state to be archived. State: ${this.state}`)\n      case SandboxDesiredState.DESTROYED:\n        if (\n          [\n            SandboxState.DESTROYED,\n            SandboxState.DESTROYING,\n            SandboxState.STOPPED,\n            SandboxState.STARTED,\n            SandboxState.ARCHIVED,\n            SandboxState.ERROR,\n            SandboxState.BUILD_FAILED,\n            SandboxState.ARCHIVING,\n            SandboxState.PENDING_BUILD,\n          ].includes(this.state)\n        ) {\n          break\n        }\n        throw new Error(`Sandbox ${this.id} is not in a valid state to be destroyed. State: ${this.state}`)\n    }\n  }\n\n  /**\n   * Enforces domain invariants on the current entity state.\n   *\n   * @returns Additional field changes that invariant enforcement produced.\n   */\n  enforceInvariants(): Partial<Sandbox> {\n    const changes = this.getInvariantChanges()\n    Object.assign(this, changes)\n    return changes\n  }\n\n  private getInvariantChanges(): Partial<Sandbox> {\n    const changes: Partial<Sandbox> = {}\n\n    if (!this.pending && String(this.state) !== String(this.desiredState)) {\n      changes.pending = true\n    }\n    if (this.pending && String(this.state) === String(this.desiredState)) {\n      changes.pending = false\n    }\n    if (\n      this.state === SandboxState.ERROR ||\n      this.state === SandboxState.BUILD_FAILED ||\n      this.desiredState === SandboxDesiredState.ARCHIVED\n    ) {\n      changes.pending = false\n    }\n\n    if (this.state === SandboxState.DESTROYED || this.state === SandboxState.ARCHIVED) {\n      changes.runnerId = null\n    }\n\n    if (this.state === SandboxState.DESTROYED) {\n      changes.backupState = BackupState.NONE\n    }\n\n    return changes\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/snapshot-region.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CreateDateColumn, Entity, JoinColumn, ManyToOne, PrimaryColumn, UpdateDateColumn } from 'typeorm'\nimport { Snapshot } from './snapshot.entity'\nimport { Region } from '../../region/entities/region.entity'\n\n@Entity()\nexport class SnapshotRegion {\n  @PrimaryColumn('uuid')\n  snapshotId: string\n\n  @PrimaryColumn()\n  regionId: string\n\n  @ManyToOne(() => Snapshot, (snapshot) => snapshot.snapshotRegions, {\n    onDelete: 'CASCADE',\n  })\n  @JoinColumn({ name: 'snapshotId' })\n  snapshot: Snapshot\n\n  @ManyToOne(() => Region, {\n    onDelete: 'CASCADE',\n  })\n  @JoinColumn({ name: 'regionId' })\n  region: Region\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/snapshot-runner.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'\nimport { SnapshotRunnerState } from '../enums/snapshot-runner-state.enum'\n\n@Entity()\n@Index('snapshot_runner_snapshotref_idx', ['snapshotRef'])\n@Index('snapshot_runner_runnerid_snapshotref_idx', ['runnerId', 'snapshotRef'])\n@Index('snapshot_runner_runnerid_idx', ['runnerId'])\n@Index('snapshot_runner_state_idx', ['state'])\nexport class SnapshotRunner {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column({\n    type: 'enum',\n    enum: SnapshotRunnerState,\n    default: SnapshotRunnerState.PULLING_SNAPSHOT,\n  })\n  state: SnapshotRunnerState\n\n  @Column({ nullable: true })\n  errorReason?: string\n\n  @Column({\n    //  todo: remove default\n    default: '',\n  })\n  snapshotRef: string\n\n  @Column()\n  runnerId: string\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/snapshot.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Column,\n  CreateDateColumn,\n  Entity,\n  Index,\n  JoinColumn,\n  ManyToOne,\n  OneToMany,\n  PrimaryGeneratedColumn,\n  Unique,\n  UpdateDateColumn,\n} from 'typeorm'\nimport { SnapshotRunner } from './snapshot-runner.entity'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\nimport { BuildInfo } from './build-info.entity'\nimport { SnapshotRegion } from './snapshot-region.entity'\n\n@Entity()\n@Unique(['organizationId', 'name'])\n@Index('snapshot_name_idx', ['name'])\n@Index('snapshot_state_idx', ['state'])\nexport class Snapshot {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column({\n    nullable: true,\n    type: 'uuid',\n  })\n  organizationId?: string\n\n  //  general snapshot is available to all organizations\n  @Column({\n    type: 'boolean',\n    default: false,\n  })\n  general = false\n\n  @Column()\n  name: string\n\n  @Column()\n  imageName: string\n\n  @Column({ nullable: true })\n  ref?: string\n\n  @Column({\n    type: 'enum',\n    enum: SnapshotState,\n    default: SnapshotState.PENDING,\n  })\n  state = SnapshotState.PENDING\n\n  @Column({ nullable: true })\n  errorReason?: string\n\n  @Column({ type: 'float', nullable: true })\n  size?: number\n\n  @Column({ type: 'int', default: 1 })\n  cpu = 1\n\n  @Column({ type: 'int', default: 0 })\n  gpu = 0\n\n  @Column({ type: 'int', default: 1 })\n  mem = 1\n\n  @Column({ type: 'int', default: 3 })\n  disk = 3\n\n  @Column({ type: 'boolean', default: false })\n  hideFromUsers = false\n\n  @OneToMany(() => SnapshotRunner, (runner) => runner.snapshotRef)\n  runners: SnapshotRunner[]\n\n  @Column({ array: true, type: 'text', nullable: true })\n  entrypoint?: string[]\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  @Column({ nullable: true })\n  lastUsedAt?: Date\n\n  @ManyToOne(() => BuildInfo, (buildInfo) => buildInfo.snapshots, {\n    nullable: true,\n    eager: true,\n  })\n  @JoinColumn()\n  buildInfo?: BuildInfo\n\n  @Column({ nullable: true })\n  initialRunnerId?: string\n\n  @OneToMany(() => SnapshotRegion, (snapshotRegion) => snapshotRegion.snapshot, {\n    cascade: true,\n    onDelete: 'CASCADE',\n  })\n  snapshotRegions: SnapshotRegion[]\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/ssh-access.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Column,\n  CreateDateColumn,\n  Entity,\n  Generated,\n  JoinColumn,\n  ManyToOne,\n  PrimaryColumn,\n  UpdateDateColumn,\n} from 'typeorm'\nimport { Sandbox } from './sandbox.entity'\n\n@Entity()\nexport class SshAccess {\n  @PrimaryColumn()\n  @Generated('uuid')\n  id: string\n\n  @Column({\n    type: 'uuid',\n  })\n  sandboxId: string\n\n  @Column({\n    type: 'text',\n  })\n  token: string\n\n  @Column({\n    type: 'timestamp',\n  })\n  expiresAt: Date\n\n  @CreateDateColumn()\n  createdAt: Date\n\n  @UpdateDateColumn()\n  updatedAt: Date\n\n  @ManyToOne(() => Sandbox, { onDelete: 'CASCADE' })\n  @JoinColumn({ name: 'sandboxId' })\n  sandbox: Sandbox\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/volume.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, Unique, UpdateDateColumn } from 'typeorm'\nimport { VolumeState } from '../enums/volume-state.enum'\n\n@Entity()\n@Unique(['organizationId', 'name'])\nexport class Volume {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column({\n    nullable: true,\n    type: 'uuid',\n  })\n  organizationId?: string\n\n  @Column()\n  name: string\n\n  @Column({\n    type: 'enum',\n    enum: VolumeState,\n    default: VolumeState.PENDING_CREATE,\n  })\n  state: VolumeState\n\n  @Column({ nullable: true })\n  errorReason?: string\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n\n  @Column({ nullable: true })\n  lastUsedAt?: Date\n\n  public getBucketName(): string {\n    return `daytona-volume-${this.id}`\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/entities/warm-pool.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\n\n@Entity()\n@Index('warm_pool_find_idx', ['snapshot', 'target', 'class', 'cpu', 'mem', 'disk', 'gpu', 'osUser', 'env'])\nexport class WarmPool {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column()\n  pool: number\n\n  @Column()\n  snapshot: string\n\n  @Column()\n  target: string\n\n  @Column()\n  cpu: number\n\n  @Column()\n  mem: number\n\n  @Column()\n  disk: number\n\n  @Column()\n  gpu: number\n\n  @Column()\n  gpuType: string\n\n  @Column({\n    type: 'enum',\n    enum: SandboxClass,\n    default: SandboxClass.SMALL,\n  })\n  class: SandboxClass\n\n  @Column()\n  osUser: string\n\n  @Column({ nullable: true })\n  errorReason?: string\n\n  @Column({\n    type: 'simple-json',\n    default: {},\n  })\n  env: { [key: string]: string }\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/backup-state.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum BackupState {\n  NONE = 'None',\n  PENDING = 'Pending',\n  IN_PROGRESS = 'InProgress',\n  COMPLETED = 'Completed',\n  ERROR = 'Error',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/job-status.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum JobStatus {\n  PENDING = 'PENDING',\n  IN_PROGRESS = 'IN_PROGRESS',\n  COMPLETED = 'COMPLETED',\n  FAILED = 'FAILED',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/job-type.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum JobType {\n  CREATE_SANDBOX = 'CREATE_SANDBOX',\n  START_SANDBOX = 'START_SANDBOX',\n  STOP_SANDBOX = 'STOP_SANDBOX',\n  DESTROY_SANDBOX = 'DESTROY_SANDBOX',\n  RESIZE_SANDBOX = 'RESIZE_SANDBOX',\n  CREATE_BACKUP = 'CREATE_BACKUP',\n  BUILD_SNAPSHOT = 'BUILD_SNAPSHOT',\n  PULL_SNAPSHOT = 'PULL_SNAPSHOT',\n  RECOVER_SANDBOX = 'RECOVER_SANDBOX',\n  INSPECT_SNAPSHOT_IN_REGISTRY = 'INSPECT_SNAPSHOT_IN_REGISTRY',\n  REMOVE_SNAPSHOT = 'REMOVE_SNAPSHOT',\n  UPDATE_SANDBOX_NETWORK_SETTINGS = 'UPDATE_SANDBOX_NETWORK_SETTINGS',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/resource-type.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum ResourceType {\n  SANDBOX = 'SANDBOX',\n  SNAPSHOT = 'SNAPSHOT',\n  BACKUP = 'BACKUP',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/runner-state.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum RunnerState {\n  INITIALIZING = 'initializing',\n  READY = 'ready',\n  DISABLED = 'disabled',\n  DECOMMISSIONED = 'decommissioned',\n  UNRESPONSIVE = 'unresponsive',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/sandbox-class.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum SandboxClass {\n  SMALL = 'small',\n  MEDIUM = 'medium',\n  LARGE = 'large',\n}\n\nexport const SandboxClassData = {\n  [SandboxClass.SMALL]: {\n    cpu: 4,\n    memory: 8,\n    disk: 30,\n  },\n  [SandboxClass.MEDIUM]: {\n    cpu: 8,\n    memory: 16,\n    disk: 60,\n  },\n  [SandboxClass.LARGE]: {\n    cpu: 12,\n    memory: 24,\n    disk: 90,\n  },\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/sandbox-desired-state.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum SandboxDesiredState {\n  DESTROYED = 'destroyed',\n  STARTED = 'started',\n  STOPPED = 'stopped',\n  RESIZED = 'resized',\n  ARCHIVED = 'archived',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/sandbox-state.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum SandboxState {\n  CREATING = 'creating',\n  RESTORING = 'restoring',\n  DESTROYED = 'destroyed',\n  DESTROYING = 'destroying',\n  STARTED = 'started',\n  STOPPED = 'stopped',\n  STARTING = 'starting',\n  STOPPING = 'stopping',\n  ERROR = 'error',\n  BUILD_FAILED = 'build_failed',\n  PENDING_BUILD = 'pending_build',\n  BUILDING_SNAPSHOT = 'building_snapshot',\n  UNKNOWN = 'unknown',\n  PULLING_SNAPSHOT = 'pulling_snapshot',\n  ARCHIVED = 'archived',\n  ARCHIVING = 'archiving',\n  RESIZING = 'resizing',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/snapshot-runner-state.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum SnapshotRunnerState {\n  PULLING_SNAPSHOT = 'pulling_snapshot',\n  BUILDING_SNAPSHOT = 'building_snapshot',\n  READY = 'ready',\n  ERROR = 'error',\n  REMOVING = 'removing',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/snapshot-state.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum SnapshotState {\n  BUILDING = 'building',\n  PENDING = 'pending',\n  PULLING = 'pulling',\n  ACTIVE = 'active',\n  INACTIVE = 'inactive',\n  ERROR = 'error',\n  BUILD_FAILED = 'build_failed',\n  REMOVING = 'removing',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/enums/volume-state.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum VolumeState {\n  CREATING = 'creating',\n  READY = 'ready',\n  PENDING_CREATE = 'pending_create',\n  PENDING_DELETE = 'pending_delete',\n  DELETING = 'deleting',\n  DELETED = 'deleted',\n  ERROR = 'error',\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/errors/runner-api-error.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class RunnerApiError extends Error {\n  constructor(\n    message: string,\n    public readonly statusCode?: number,\n    public readonly code?: string,\n  ) {\n    super(message)\n    this.name = 'RunnerApiError'\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/errors/runner-not-ready.error.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class RunnerNotReadyError extends Error {\n  constructor(message: string) {\n    super(message)\n    this.name = 'RunnerNotReadyError'\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/errors/snapshot-state-error.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class SnapshotStateError extends Error {\n  constructor(public readonly errorReason: string) {\n    super(errorReason)\n    this.name = 'SnapshotStateError'\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/runner-created.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Runner } from '../entities/runner.entity'\n\nexport class RunnerCreatedEvent {\n  constructor(public readonly runner: Runner) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/runner-deleted.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm/entity-manager/EntityManager.js'\n\nexport class RunnerDeletedEvent {\n  constructor(\n    public readonly entityManager: EntityManager,\n    public readonly runnerId: string,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/runner-state-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Runner } from '../entities/runner.entity'\nimport { RunnerState } from '../enums/runner-state.enum'\n\nexport class RunnerStateUpdatedEvent {\n  constructor(\n    public readonly runner: Runner,\n    public readonly oldState: RunnerState,\n    public readonly newState: RunnerState,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/runner-unschedulable-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Runner } from '../entities/runner.entity'\n\nexport class RunnerUnschedulableUpdatedEvent {\n  constructor(\n    public readonly runner: Runner,\n    public readonly oldUnschedulable: boolean,\n    public readonly newUnschedulable: boolean,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-archived.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\n\nexport class SandboxArchivedEvent {\n  constructor(public readonly sandbox: Sandbox) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-backup-created.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\n\nexport class SandboxBackupCreatedEvent {\n  constructor(public readonly sandbox: Sandbox) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-create.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\n\nexport class SandboxCreatedEvent {\n  constructor(public readonly sandbox: Sandbox) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-desired-state-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\n\nexport class SandboxDesiredStateUpdatedEvent {\n  constructor(\n    public readonly sandbox: Sandbox,\n    public readonly oldDesiredState: SandboxDesiredState,\n    public readonly newDesiredState: SandboxDesiredState,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-destroyed.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\n\nexport class SandboxDestroyedEvent {\n  constructor(public readonly sandbox: Sandbox) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-organization-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\n\nexport class SandboxOrganizationUpdatedEvent {\n  constructor(\n    public readonly sandbox: Sandbox,\n    public readonly oldOrganizationId: string,\n    public readonly newOrganizationId: string,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-public-status-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\n\nexport class SandboxPublicStatusUpdatedEvent {\n  constructor(\n    public readonly sandbox: Sandbox,\n    public readonly oldStatus: boolean,\n    public readonly newStatus: boolean,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-started.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\n\nexport class SandboxStartedEvent {\n  constructor(public readonly sandbox: Sandbox) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-state-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { SandboxState } from '../enums/sandbox-state.enum'\n\nexport class SandboxStateUpdatedEvent {\n  constructor(\n    public readonly sandbox: Sandbox,\n    public readonly oldState: SandboxState,\n    public readonly newState: SandboxState,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/sandbox-stopped.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox } from '../entities/sandbox.entity'\n\nexport class SandboxStoppedEvent {\n  constructor(public readonly sandbox: Sandbox) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/snapshot-activated.event.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Snapshot } from '../entities/snapshot.entity'\n\nexport class SnapshotActivatedEvent {\n  constructor(public readonly snapshot: Snapshot) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/snapshot-created.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Snapshot } from '../entities/snapshot.entity'\n\nexport class SnapshotCreatedEvent {\n  constructor(public readonly snapshot: Snapshot) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/snapshot-removed.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Snapshot } from '../entities/snapshot.entity'\n\nexport class SnapshotRemovedEvent {\n  constructor(public readonly snapshot: Snapshot) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/snapshot-state-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\n\nexport class SnapshotStateUpdatedEvent {\n  constructor(\n    public readonly snapshot: Snapshot,\n    public readonly oldState: SnapshotState,\n    public readonly newState: SnapshotState,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/volume-created.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Volume } from '../entities/volume.entity'\n\nexport class VolumeCreatedEvent {\n  constructor(public readonly volume: Volume) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/volume-last-used-at-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Volume } from '../entities/volume.entity'\n\nexport class VolumeLastUsedAtUpdatedEvent {\n  constructor(public readonly volume: Volume) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/volume-state-updated.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Volume } from '../entities/volume.entity'\nimport { VolumeState } from '../enums/volume-state.enum'\n\nexport class VolumeStateUpdatedEvent {\n  constructor(\n    public readonly volume: Volume,\n    public readonly oldState: VolumeState,\n    public readonly newState: VolumeState,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/events/warmpool-topup-requested.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { WarmPool } from '../entities/warm-pool.entity'\n\nexport class WarmPoolTopUpRequested {\n  constructor(public readonly warmPool: WarmPool) {}\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/job-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Injectable,\n  CanActivate,\n  ExecutionContext,\n  NotFoundException,\n  ForbiddenException,\n  Logger,\n} from '@nestjs/common'\nimport { BaseAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { JobService } from '../services/job.service'\nimport { isRunnerContext, RunnerContext } from '../../common/interfaces/runner-context.interface'\n\n@Injectable()\nexport class JobAccessGuard implements CanActivate {\n  private readonly logger = new Logger(JobAccessGuard.name)\n\n  constructor(private readonly jobService: JobService) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    const jobId: string = request.params.jobId || request.params.id\n\n    // TODO: initialize authContext safely\n    const authContext: BaseAuthContext = request.user\n\n    try {\n      const job = await this.jobService.findOne(jobId)\n      if (!job) {\n        throw new NotFoundException('Job not found')\n      }\n\n      if (!isRunnerContext(authContext)) {\n        throw new ForbiddenException('User is not a runner')\n      }\n\n      const runnerContext = authContext as RunnerContext\n\n      if (runnerContext.runnerId !== job.runnerId) {\n        throw new ForbiddenException('Runner ID does not match job runner ID')\n      }\n\n      return true\n    } catch (error) {\n      if (!(error instanceof NotFoundException)) {\n        this.logger.error(error)\n      }\n      throw new NotFoundException('Job not found')\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/proxy.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext, Logger, CanActivate } from '@nestjs/common'\nimport { getAuthContext } from '../../auth/get-auth-context'\nimport { isProxyContext } from '../../common/interfaces/proxy-context.interface'\n\n@Injectable()\nexport class ProxyGuard implements CanActivate {\n  protected readonly logger = new Logger(ProxyGuard.name)\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    // Throws if not proxy context\n    getAuthContext(context, isProxyContext)\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/region-runner-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Injectable,\n  CanActivate,\n  ExecutionContext,\n  NotFoundException,\n  ForbiddenException,\n  Logger,\n} from '@nestjs/common'\nimport { RunnerService } from '../services/runner.service'\nimport { BaseAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { isRegionProxyContext, RegionProxyContext } from '../../common/interfaces/region-proxy.interface'\nimport {\n  isRegionSSHGatewayContext,\n  RegionSSHGatewayContext,\n} from '../../common/interfaces/region-ssh-gateway.interface'\n\n@Injectable()\nexport class RegionRunnerAccessGuard implements CanActivate {\n  private readonly logger = new Logger(RegionRunnerAccessGuard.name)\n\n  constructor(private readonly runnerService: RunnerService) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    const runnerId: string = request.params.runnerId || request.params.id\n\n    const authContext: BaseAuthContext = request.user\n\n    if (!isRegionProxyContext(authContext) && !isRegionSSHGatewayContext(authContext)) {\n      return false\n    }\n\n    try {\n      const regionContext = authContext as RegionProxyContext | RegionSSHGatewayContext\n      const runner = await this.runnerService.findOneOrFail(runnerId)\n      if (regionContext.regionId !== runner.region) {\n        throw new ForbiddenException('Region ID does not match runner region ID')\n      }\n      return true\n    } catch (error) {\n      if (!(error instanceof NotFoundException)) {\n        this.logger.error(error)\n      }\n      throw new NotFoundException('Runner not found')\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/region-sandbox-access.guard.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, CanActivate, ExecutionContext, NotFoundException, ForbiddenException } from '@nestjs/common'\nimport { SandboxService } from '../services/sandbox.service'\nimport { BaseAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { isRegionProxyContext, RegionProxyContext } from '../../common/interfaces/region-proxy.interface'\nimport {\n  isRegionSSHGatewayContext,\n  RegionSSHGatewayContext,\n} from '../../common/interfaces/region-ssh-gateway.interface'\n\n@Injectable()\nexport class RegionSandboxAccessGuard implements CanActivate {\n  constructor(private readonly sandboxService: SandboxService) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    const sandboxId: string = request.params.sandboxId || request.params.id\n\n    const authContext: BaseAuthContext = request.user\n\n    if (!isRegionProxyContext(authContext) && !isRegionSSHGatewayContext(authContext)) {\n      return false\n    }\n\n    try {\n      const regionContext = authContext as RegionProxyContext | RegionSSHGatewayContext\n      const sandboxRegionId = await this.sandboxService.getRegionId(sandboxId)\n      if (sandboxRegionId !== regionContext.regionId) {\n        throw new ForbiddenException(`Sandbox region ID does not match region ${regionContext.role} region ID`)\n      }\n      return true\n    } catch (error) {\n      if (!(error instanceof NotFoundException)) {\n        console.error(error)\n      }\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxId} not found`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/runner-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Injectable,\n  CanActivate,\n  ExecutionContext,\n  NotFoundException,\n  ForbiddenException,\n  Logger,\n} from '@nestjs/common'\nimport { RegionService } from '../../region/services/region.service'\nimport { RunnerService } from '../services/runner.service'\nimport { BaseAuthContext, OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { RegionType } from '../../region/enums/region-type.enum'\nimport { isRegionProxyContext } from '../../common/interfaces/region-proxy.interface'\nimport { isRegionSSHGatewayContext } from '../../common/interfaces/region-ssh-gateway.interface'\nimport { isProxyContext } from '../../common/interfaces/proxy-context.interface'\nimport { isSshGatewayContext } from '../../common/interfaces/ssh-gateway-context.interface'\n\n@Injectable()\nexport class RunnerAccessGuard implements CanActivate {\n  private readonly logger = new Logger(RunnerAccessGuard.name)\n\n  constructor(\n    private readonly runnerService: RunnerService,\n    private readonly regionService: RegionService,\n  ) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    const runnerId: string = request.params.runnerId || request.params.id\n\n    // TODO: initialize authContext safely\n    const authContext: BaseAuthContext = request.user\n\n    try {\n      const runner = await this.runnerService.findOneOrFail(runnerId)\n\n      switch (true) {\n        case isRegionProxyContext(authContext):\n        case isRegionSSHGatewayContext(authContext): {\n          // Use RunnerRegionAccessGuard to check access instead\n          return false\n        }\n        case isProxyContext(authContext):\n        case isSshGatewayContext(authContext):\n          return true\n        default: {\n          const orgAuthContext = authContext as OrganizationAuthContext\n\n          if (orgAuthContext.role !== SystemRole.ADMIN) {\n            const region = await this.regionService.findOne(runner.region)\n            if (!region) {\n              throw new NotFoundException('Region not found')\n            }\n            if (region.organizationId !== orgAuthContext.organizationId) {\n              throw new ForbiddenException('Request organization ID does not match resource organization ID')\n            }\n            if (region.regionType !== RegionType.CUSTOM) {\n              throw new ForbiddenException('Runner is not in a custom region')\n            }\n          }\n          return true\n        }\n      }\n    } catch (error) {\n      if (!(error instanceof NotFoundException)) {\n        this.logger.error(error)\n      }\n      throw new NotFoundException('Runner not found')\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/sandbox-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, CanActivate, ExecutionContext, NotFoundException, ForbiddenException } from '@nestjs/common'\nimport { SandboxService } from '../services/sandbox.service'\nimport { OrganizationAuthContext, BaseAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { isRunnerContext, RunnerContext } from '../../common/interfaces/runner-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { isProxyContext } from '../../common/interfaces/proxy-context.interface'\nimport { isSshGatewayContext } from '../../common/interfaces/ssh-gateway-context.interface'\nimport { isRegionProxyContext } from '../../common/interfaces/region-proxy.interface'\nimport { isRegionSSHGatewayContext } from '../../common/interfaces/region-ssh-gateway.interface'\n\n@Injectable()\nexport class SandboxAccessGuard implements CanActivate {\n  constructor(private readonly sandboxService: SandboxService) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    // TODO: remove deprecated request.params.workspaceId param once we remove the deprecated workspace controller\n    const sandboxIdOrName: string =\n      request.params.sandboxIdOrName || request.params.sandboxId || request.params.id || request.params.workspaceId\n\n    // TODO: initialize authContext safely\n    const authContext: BaseAuthContext = request.user\n\n    try {\n      switch (true) {\n        case isRunnerContext(authContext): {\n          // For runner authentication, verify that the runner ID matches the sandbox's runner ID\n          const runnerContext = authContext as RunnerContext\n          const sandboxRunnerId = await this.sandboxService.getRunnerId(sandboxIdOrName)\n          if (sandboxRunnerId !== runnerContext.runnerId) {\n            throw new ForbiddenException('Runner ID does not match sandbox runner ID')\n          }\n          break\n        }\n        case isRegionProxyContext(authContext):\n        case isRegionSSHGatewayContext(authContext): {\n          // Use RegionSandboxAccessGuard to check access instead\n          return false\n        }\n        case isProxyContext(authContext):\n        case isSshGatewayContext(authContext):\n          return true\n        default: {\n          // For user/organization authentication, check organization access\n          const orgAuthContext = authContext as OrganizationAuthContext\n          const sandboxOrganizationId = await this.sandboxService.getOrganizationId(\n            sandboxIdOrName,\n            orgAuthContext.organizationId,\n          )\n          if (orgAuthContext.role !== SystemRole.ADMIN && sandboxOrganizationId !== orgAuthContext.organizationId) {\n            throw new ForbiddenException('Request organization ID does not match resource organization ID')\n          }\n        }\n      }\n      return true\n    } catch (error) {\n      if (!(error instanceof NotFoundException)) {\n        console.error(error)\n      }\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxIdOrName} not found`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/snapshot-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, CanActivate, ExecutionContext, ForbiddenException, NotFoundException } from '@nestjs/common'\nimport { SnapshotService } from '../services/snapshot.service'\nimport {\n  BaseAuthContext,\n  isOrganizationAuthContext,\n  OrganizationAuthContext,\n} from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { isSshGatewayContext } from '../../common/interfaces/ssh-gateway-context.interface'\nimport { isProxyContext } from '../../common/interfaces/proxy-context.interface'\nimport { isRegionProxyContext, RegionProxyContext } from '../../common/interfaces/region-proxy.interface'\nimport {\n  isRegionSSHGatewayContext,\n  RegionSSHGatewayContext,\n} from '../../common/interfaces/region-ssh-gateway.interface'\n\n@Injectable()\nexport class SnapshotAccessGuard implements CanActivate {\n  constructor(private readonly snapshotService: SnapshotService) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    const snapshotId: string = request.params.snapshotId || request.params.id\n\n    let snapshot: Snapshot\n\n    // TODO: initialize authContext safely\n    const authContext: BaseAuthContext = request.user\n\n    try {\n      snapshot = await this.snapshotService.getSnapshot(snapshotId)\n    } catch {\n      if (!isOrganizationAuthContext(authContext)) {\n        throw new NotFoundException(`Snapshot with ID ${snapshotId} not found`)\n      }\n\n      // If not found by ID, try by name\n      snapshot = await this.snapshotService.getSnapshotByName(snapshotId, authContext.organizationId)\n    }\n\n    try {\n      switch (true) {\n        case isRegionProxyContext(authContext):\n        case isRegionSSHGatewayContext(authContext): {\n          // For region proxy/ssh gateway authentication, verify that the runner's region ID matches the region ID\n          const regionContext = authContext as RegionProxyContext | RegionSSHGatewayContext\n          const isAvailable = await this.snapshotService.isAvailableInRegion(snapshot.id, regionContext.regionId)\n          if (!isAvailable) {\n            throw new NotFoundException(`Snapshot is not available in region ${regionContext.regionId}`)\n          }\n          break\n        }\n        case isProxyContext(authContext):\n        case isSshGatewayContext(authContext):\n          break\n        default: {\n          // For user/organization authentication, check organization access\n          const orgAuthContext = authContext as OrganizationAuthContext\n          if (orgAuthContext.role !== SystemRole.ADMIN && snapshot.organizationId !== orgAuthContext.organizationId) {\n            throw new ForbiddenException('Request organization ID does not match resource organization ID')\n          }\n        }\n      }\n\n      request.snapshot = snapshot\n\n      return true\n    } catch (error) {\n      if (!(error instanceof NotFoundException)) {\n        console.error(error)\n      }\n      throw new NotFoundException(`Snapshot with ID or name ${snapshotId} not found`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/snapshot-read-access.guard.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, CanActivate, ExecutionContext, ForbiddenException, NotFoundException } from '@nestjs/common'\nimport { SnapshotService } from '../services/snapshot.service'\nimport {\n  BaseAuthContext,\n  isOrganizationAuthContext,\n  OrganizationAuthContext,\n} from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { isSshGatewayContext } from '../../common/interfaces/ssh-gateway-context.interface'\nimport { isProxyContext } from '../../common/interfaces/proxy-context.interface'\nimport { isRegionProxyContext, RegionProxyContext } from '../../common/interfaces/region-proxy.interface'\nimport {\n  isRegionSSHGatewayContext,\n  RegionSSHGatewayContext,\n} from '../../common/interfaces/region-ssh-gateway.interface'\n\n@Injectable()\nexport class SnapshotReadAccessGuard implements CanActivate {\n  constructor(private readonly snapshotService: SnapshotService) {}\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n    const snapshotId: string = request.params.snapshotId || request.params.id\n\n    let snapshot: Snapshot\n\n    const authContext: BaseAuthContext = request.user\n\n    try {\n      snapshot = await this.snapshotService.getSnapshot(snapshotId)\n    } catch {\n      if (!isOrganizationAuthContext(authContext)) {\n        throw new NotFoundException(`Snapshot with ID ${snapshotId} not found`)\n      }\n\n      snapshot = await this.snapshotService.getSnapshotByName(snapshotId, authContext.organizationId)\n    }\n\n    try {\n      switch (true) {\n        case isRegionProxyContext(authContext):\n        case isRegionSSHGatewayContext(authContext): {\n          const regionContext = authContext as RegionProxyContext | RegionSSHGatewayContext\n          const isAvailable = await this.snapshotService.isAvailableInRegion(snapshot.id, regionContext.regionId)\n          if (!isAvailable) {\n            throw new NotFoundException(`Snapshot is not available in region ${regionContext.regionId}`)\n          }\n          break\n        }\n        case isProxyContext(authContext):\n        case isSshGatewayContext(authContext):\n          break\n        default: {\n          const orgAuthContext = authContext as OrganizationAuthContext\n          if (\n            orgAuthContext.role !== SystemRole.ADMIN &&\n            snapshot.organizationId !== orgAuthContext.organizationId &&\n            !snapshot.general\n          ) {\n            throw new ForbiddenException('Request organization ID does not match resource organization ID')\n          }\n        }\n      }\n\n      request.snapshot = snapshot\n\n      return true\n    } catch (error) {\n      if (!(error instanceof NotFoundException)) {\n        console.error(error)\n      }\n      throw new NotFoundException(`Snapshot with ID or name ${snapshotId} not found`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/ssh-gateway.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, ExecutionContext, Logger, CanActivate } from '@nestjs/common'\nimport { getAuthContext } from '../../auth/get-auth-context'\nimport { isSshGatewayContext } from '../../common/interfaces/ssh-gateway-context.interface'\n\n@Injectable()\nexport class SshGatewayGuard implements CanActivate {\n  protected readonly logger = new Logger(SshGatewayGuard.name)\n\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    // Throws if not ssh gateway context\n    getAuthContext(context, isSshGatewayContext)\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/guards/volume-access.guard.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\nimport { Injectable, CanActivate, ExecutionContext, ForbiddenException, NotFoundException } from '@nestjs/common'\nimport { OrganizationAuthContext } from '../../common/interfaces/auth-context.interface'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { VolumeService } from '../services/volume.service'\n@Injectable()\nexport class VolumeAccessGuard implements CanActivate {\n  constructor(private readonly volumeService: VolumeService) {}\n  async canActivate(context: ExecutionContext): Promise<boolean> {\n    const request = context.switchToHttp().getRequest()\n\n    const volumeId = request.params.volumeId || request.params.id\n    const volumeName = request.params.name\n\n    if (!volumeId && !volumeName) {\n      throw new NotFoundException(`Volume not found`)\n    }\n\n    const authContext: OrganizationAuthContext = request.user\n\n    try {\n      const params = volumeId ? { id: volumeId } : { name: volumeName, organizationId: authContext.organizationId }\n      const volumeOrganizationId = await this.volumeService.getOrganizationId(params)\n\n      if (authContext.role !== SystemRole.ADMIN && volumeOrganizationId !== authContext.organizationId) {\n        throw new ForbiddenException('Request organization ID does not match resource organization ID')\n      }\n    } catch {\n      throw new NotFoundException(`Volume with ${volumeId ? 'ID' : 'name'} ${volumeId || volumeName} not found`)\n    }\n\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/backup.manager.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, OnApplicationShutdown } from '@nestjs/common'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { In, IsNull, LessThan, Not, Or } from 'typeorm'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { RunnerService } from '../services/runner.service'\nimport { RunnerState } from '../enums/runner-state.enum'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { DockerRegistryService } from '../../docker-registry/services/docker-registry.service'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION } from '../constants/sandbox.constants'\nimport { fromAxiosError } from '../../common/utils/from-axios-error'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport { SandboxEvents } from '../constants/sandbox-events.constants'\nimport { SandboxDestroyedEvent } from '../events/sandbox-destroyed.event'\nimport { SandboxBackupCreatedEvent } from '../events/sandbox-backup-created.event'\nimport { SandboxArchivedEvent } from '../events/sandbox-archived.event'\nimport { RunnerAdapterFactory } from '../runner-adapter/runnerAdapter'\nimport { TypedConfigService } from '../../config/typed-config.service'\n\nimport { TrackJobExecution } from '../../common/decorators/track-job-execution.decorator'\nimport { TrackableJobExecutions } from '../../common/interfaces/trackable-job-executions'\nimport { setTimeout } from 'timers/promises'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\nimport { DockerRegistry } from '../../docker-registry/entities/docker-registry.entity'\nimport { SandboxService } from '../services/sandbox.service'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\n\n@Injectable()\nexport class BackupManager implements TrackableJobExecutions, OnApplicationShutdown {\n  activeJobs = new Set<string>()\n\n  private readonly logger = new Logger(BackupManager.name)\n\n  constructor(\n    private readonly sandboxRepository: SandboxRepository,\n    private readonly sandboxService: SandboxService,\n    private readonly runnerService: RunnerService,\n    private readonly runnerAdapterFactory: RunnerAdapterFactory,\n    private readonly dockerRegistryService: DockerRegistryService,\n    @InjectRedis() private readonly redis: Redis,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly configService: TypedConfigService,\n  ) {}\n\n  //  on init\n  async onApplicationBootstrap() {\n    await this.adHocBackupCheck()\n  }\n\n  async onApplicationShutdown() {\n    //  wait for all active jobs to finish\n    while (this.activeJobs.size > 0) {\n      this.logger.log(`Waiting for ${this.activeJobs.size} active jobs to finish`)\n      await setTimeout(1000)\n    }\n  }\n\n  //  todo: make frequency configurable or more efficient\n  @Cron(CronExpression.EVERY_5_MINUTES, { name: 'ad-hoc-backup-check' })\n  @TrackJobExecution()\n  @LogExecution('ad-hoc-backup-check')\n  @WithInstrumentation()\n  async adHocBackupCheck(): Promise<void> {\n    const lockKey = 'ad-hoc-backup-check'\n    const hasLock = await this.redisLockProvider.lock(lockKey, 5 * 60)\n    if (!hasLock) {\n      return\n    }\n\n    // Get all ready runners\n    const readyRunners = await this.runnerService.findAllReady()\n\n    try {\n      // Process all runners in parallel\n      await Promise.all(\n        readyRunners.map(async (runner) => {\n          const sandboxes = await this.sandboxRepository.find({\n            where: {\n              runnerId: runner.id,\n              organizationId: Not(SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION),\n              state: SandboxState.STARTED,\n              backupState: In([BackupState.NONE, BackupState.COMPLETED]),\n              lastBackupAt: Or(IsNull(), LessThan(new Date(Date.now() - 1 * 60 * 60 * 1000))),\n              autoDeleteInterval: Not(0),\n            },\n            order: {\n              lastBackupAt: 'ASC',\n            },\n            //  todo: increase this number when backup is stable\n            take: 10,\n          })\n\n          await Promise.all(\n            sandboxes.map(async (sandbox) => {\n              const lockKey = `sandbox-backup-${sandbox.id}`\n              const hasLock = await this.redisLockProvider.lock(lockKey, 60)\n              if (!hasLock) {\n                return\n              }\n\n              try {\n                //  todo: remove the catch handler asap\n                await this.setBackupPending(sandbox).catch((error) => {\n                  if (error instanceof BadRequestError && error.message === 'A backup is already in progress') {\n                    return\n                  }\n                  this.logger.error(`Failed to create backup for sandbox ${sandbox.id}:`, fromAxiosError(error))\n                })\n              } catch (error) {\n                this.logger.error(`Error processing stop state for sandbox ${sandbox.id}:`, fromAxiosError(error))\n              } finally {\n                await this.redisLockProvider.unlock(lockKey)\n              }\n            }),\n          )\n        }),\n      )\n    } catch (error) {\n      this.logger.error(`Error processing backups: `, error)\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'check-backup-states' })\n  @TrackJobExecution()\n  @LogExecution('check-backup-states')\n  @WithInstrumentation()\n  async checkBackupStates(): Promise<void> {\n    //  lock the sync to only run one instance at a time\n    const lockKey = 'check-backup-states'\n    const hasLock = await this.redisLockProvider.lock(lockKey, 10)\n    if (!hasLock) {\n      return\n    }\n\n    try {\n      const sandboxes = await this.sandboxRepository\n        .createQueryBuilder('sandbox')\n        .innerJoin('runner', 'r', 'r.id = sandbox.runnerId')\n        .where('sandbox.state IN (:...states)', {\n          states: [SandboxState.ARCHIVING, SandboxState.STARTED, SandboxState.STOPPED],\n        })\n        .andWhere('sandbox.backupState IN (:...backupStates)', {\n          backupStates: [BackupState.PENDING, BackupState.IN_PROGRESS],\n        })\n        .andWhere('r.state = :ready', { ready: RunnerState.READY })\n        // Prioritize manual archival action, then auto-archive poller, then ad-hoc backup poller\n        .addSelect(\n          `\n          CASE sandbox.state\n            WHEN :archiving THEN 1\n            WHEN :stopped   THEN 2\n            WHEN :started   THEN 3\n            ELSE 999\n          END\n          `,\n          'state_priority',\n        )\n        .setParameters({\n          archiving: SandboxState.ARCHIVING,\n          stopped: SandboxState.STOPPED,\n          started: SandboxState.STARTED,\n        })\n        .orderBy('state_priority', 'ASC')\n        .addOrderBy('sandbox.lastBackupAt', 'ASC', 'NULLS FIRST') // Process sandboxes with no backups first\n        .addOrderBy('sandbox.createdAt', 'ASC') // For equal lastBackupAt, process older sandboxes first\n        .take(100)\n        .getMany()\n\n      await Promise.allSettled(\n        sandboxes.map(async (s) => {\n          const lockKey = `sandbox-backup-${s.id}`\n          const hasLock = await this.redisLockProvider.lock(lockKey, 60)\n          if (!hasLock) {\n            return\n          }\n\n          try {\n            //  get the latest sandbox state\n            const sandbox = await this.sandboxRepository.findOneByOrFail({\n              id: s.id,\n            })\n\n            try {\n              switch (sandbox.backupState) {\n                case BackupState.PENDING: {\n                  await this.handlePendingBackup(sandbox)\n                  break\n                }\n                case BackupState.IN_PROGRESS: {\n                  await this.checkBackupProgress(sandbox)\n                  break\n                }\n              }\n            } catch (error) {\n              //  if error, retry 10 times\n              const errorRetryKey = `${lockKey}-error-retry`\n              const errorRetryCount = await this.redis.get(errorRetryKey)\n              if (!errorRetryCount) {\n                await this.redis.setex(errorRetryKey, 300, '1')\n              } else if (parseInt(errorRetryCount) > 10) {\n                this.logger.error(`Error processing backup for sandbox ${sandbox.id}:`, fromAxiosError(error))\n                await this.sandboxService.updateSandboxBackupState(\n                  sandbox.id,\n                  BackupState.ERROR,\n                  undefined,\n                  undefined,\n                  fromAxiosError(error).message,\n                )\n              } else {\n                await this.redis.setex(errorRetryKey, 300, errorRetryCount + 1)\n              }\n            }\n          } catch (error) {\n            this.logger.error(`Error processing backup for sandbox ${s.id}:`, error)\n          } finally {\n            await this.redisLockProvider.unlock(lockKey)\n          }\n        }),\n      )\n    } catch (error) {\n      this.logger.error(`Error processing backups: `, error)\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'check-backup-states-errored-draining' })\n  @TrackJobExecution()\n  @LogExecution('check-backup-states-errored-draining')\n  @WithInstrumentation()\n  async checkBackupStatesForErroredDraining(): Promise<void> {\n    const lockKey = 'check-backup-states-errored-draining'\n    const hasLock = await this.redisLockProvider.lock(lockKey, 10)\n    if (!hasLock) {\n      return\n    }\n\n    try {\n      const sandboxes = await this.sandboxRepository\n        .createQueryBuilder('sandbox')\n        .innerJoin('runner', 'r', 'r.id = sandbox.runnerId')\n        .where('sandbox.state = :error', { error: SandboxState.ERROR })\n        .andWhere('sandbox.backupState IN (:...backupStates)', {\n          backupStates: [BackupState.PENDING, BackupState.IN_PROGRESS],\n        })\n        .andWhere('r.state = :ready', { ready: RunnerState.READY })\n        .andWhere('r.\"draining\" = true')\n        .addOrderBy('sandbox.lastBackupAt', 'ASC', 'NULLS FIRST')\n        .addOrderBy('sandbox.createdAt', 'ASC')\n        .take(100)\n        .getMany()\n\n      await Promise.allSettled(\n        sandboxes.map(async (s) => {\n          const lockKey = `sandbox-backup-${s.id}`\n          const hasLock = await this.redisLockProvider.lock(lockKey, 60)\n          if (!hasLock) {\n            return\n          }\n\n          try {\n            const sandbox = await this.sandboxRepository.findOneByOrFail({\n              id: s.id,\n            })\n\n            try {\n              switch (sandbox.backupState) {\n                case BackupState.PENDING: {\n                  await this.handlePendingBackup(sandbox)\n                  break\n                }\n                case BackupState.IN_PROGRESS: {\n                  await this.checkBackupProgress(sandbox)\n                  break\n                }\n              }\n            } catch (error) {\n              const errorRetryKey = `${lockKey}-error-retry`\n              const errorRetryCount = await this.redis.get(errorRetryKey)\n              if (!errorRetryCount) {\n                await this.redis.setex(errorRetryKey, 300, '1')\n              } else if (parseInt(errorRetryCount) > 10) {\n                this.logger.error(\n                  `Error processing backup for errored sandbox ${sandbox.id} on draining runner:`,\n                  fromAxiosError(error),\n                )\n                await this.sandboxService.updateSandboxBackupState(\n                  sandbox.id,\n                  BackupState.ERROR,\n                  undefined,\n                  undefined,\n                  fromAxiosError(error).message,\n                )\n              } else {\n                await this.redis.setex(errorRetryKey, 300, errorRetryCount + 1)\n              }\n            }\n          } catch (error) {\n            this.logger.error(`Error processing backup for errored sandbox ${s.id} on draining runner:`, error)\n          } finally {\n            await this.redisLockProvider.unlock(lockKey)\n          }\n        }),\n      )\n    } catch (error) {\n      this.logger.error(`Error processing backups for errored sandboxes on draining runners: `, error)\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'sync-stop-state-create-backups' })\n  @TrackJobExecution()\n  @LogExecution('sync-stop-state-create-backups')\n  @WithInstrumentation()\n  async syncStopStateCreateBackups(): Promise<void> {\n    const lockKey = 'sync-stop-state-create-backups'\n    const hasLock = await this.redisLockProvider.lock(lockKey, 10)\n    if (!hasLock) {\n      return\n    }\n\n    try {\n      const sandboxes = await this.sandboxRepository\n        .createQueryBuilder('sandbox')\n        .innerJoin('runner', 'r', 'r.id = sandbox.runnerId')\n        .where('sandbox.state IN (:...states)', { states: [SandboxState.ARCHIVING, SandboxState.STOPPED] })\n        .andWhere('sandbox.backupState = :none', { none: BackupState.NONE })\n        .andWhere('r.state = :ready', { ready: RunnerState.READY })\n        .take(100)\n        .getMany()\n\n      await Promise.allSettled(\n        sandboxes\n          .filter((sandbox) => sandbox.runnerId !== null)\n          .map(async (sandbox) => {\n            const lockKey = `sandbox-backup-${sandbox.id}`\n            const hasLock = await this.redisLockProvider.lock(lockKey, 30)\n            if (!hasLock) {\n              return\n            }\n\n            try {\n              await this.setBackupPending(sandbox)\n            } catch (error) {\n              this.logger.error(`Error processing backup for sandbox ${sandbox.id}:`, error)\n            } finally {\n              await this.redisLockProvider.unlock(lockKey)\n            }\n          }),\n      )\n    } catch (error) {\n      this.logger.error(`Error processing backups: `, error)\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  async setBackupPending(sandbox: Sandbox): Promise<void> {\n    if (sandbox.backupState === BackupState.COMPLETED) {\n      return\n    }\n\n    // Allow backups for STARTED sandboxes, STOPPED/ERROR sandboxes with runnerId, or ARCHIVING sandboxes\n    if (\n      !(\n        sandbox.state === SandboxState.STARTED ||\n        sandbox.state === SandboxState.ARCHIVING ||\n        (sandbox.state === SandboxState.STOPPED && sandbox.runnerId) ||\n        (sandbox.state === SandboxState.ERROR && sandbox.runnerId)\n      )\n    ) {\n      throw new BadRequestError('Sandbox must be started, stopped, or errored with assigned runner to create a backup')\n    }\n\n    if (sandbox.backupState === BackupState.IN_PROGRESS || sandbox.backupState === BackupState.PENDING) {\n      return\n    }\n\n    let registry: DockerRegistry | null = null\n\n    if (sandbox.backupRegistryId) {\n      registry = await this.dockerRegistryService.findOne(sandbox.backupRegistryId)\n    } else {\n      registry = await this.dockerRegistryService.getAvailableBackupRegistry(sandbox.region)\n    }\n\n    if (!registry) {\n      throw new BadRequestError('No backup registry configured')\n    }\n    // Generate backup snapshot name\n    const timestamp = new Date().toISOString().replace(/[:.]/g, '-')\n    const backupSnapshot = `${registry.url.replace('https://', '').replace('http://', '')}/${registry.project || 'daytona'}/backup-${sandbox.id}:${timestamp}`\n\n    await this.sandboxService.updateSandboxBackupState(sandbox.id, BackupState.PENDING, backupSnapshot, registry.id)\n  }\n\n  private async checkBackupProgress(sandbox: Sandbox): Promise<void> {\n    try {\n      const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n      const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n      // Get sandbox info from runner\n      const sandboxInfo = await runnerAdapter.sandboxInfo(sandbox.id)\n\n      switch (sandboxInfo.backupState) {\n        case BackupState.COMPLETED: {\n          await this.sandboxService.updateSandboxBackupState(sandbox.id, BackupState.COMPLETED)\n          break\n        }\n        case BackupState.ERROR: {\n          await this.sandboxService.updateSandboxBackupState(\n            sandbox.id,\n            BackupState.ERROR,\n            undefined,\n            undefined,\n            sandboxInfo.backupErrorReason,\n          )\n          break\n        }\n        // If backup state is none, retry the backup process by setting the backup state to pending\n        // This can happen if the runner is restarted or the operation is cancelled\n        case BackupState.NONE: {\n          await this.sandboxService.updateSandboxBackupState(sandbox.id, BackupState.PENDING)\n          break\n        }\n        // If still in progress or any other state, do nothing and wait for next sync\n      }\n    } catch (error) {\n      await this.sandboxService.updateSandboxBackupState(\n        sandbox.id,\n        BackupState.ERROR,\n        undefined,\n        undefined,\n        fromAxiosError(error).message,\n      )\n      throw error\n    }\n  }\n\n  private async deleteSandboxBackupRepositoryFromRegistry(sandbox: Sandbox): Promise<void> {\n    const registry = await this.dockerRegistryService.findOne(sandbox.backupRegistryId)\n\n    try {\n      await this.dockerRegistryService.deleteSandboxRepository(sandbox.id, registry)\n    } catch (error) {\n      this.logger.error(\n        `Failed to delete backup repository ${sandbox.id} from registry ${registry.id}:`,\n        fromAxiosError(error),\n      )\n    }\n  }\n\n  private async handlePendingBackup(sandbox: Sandbox): Promise<void> {\n    const lockKey = `runner-${sandbox.runnerId}-backup-lock`\n    try {\n      await this.redisLockProvider.waitForLock(lockKey, 10)\n\n      const backupsInProgress = await this.sandboxRepository.count({\n        where: {\n          runnerId: sandbox.runnerId,\n          backupState: BackupState.IN_PROGRESS,\n        },\n      })\n      if (backupsInProgress >= this.configService.getOrThrow('maxConcurrentBackupsPerRunner')) {\n        return\n      }\n\n      const registry = await this.dockerRegistryService.findOne(sandbox.backupRegistryId)\n      if (!registry) {\n        throw new Error('Registry not found')\n      }\n\n      const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n      const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n      //  check if backup is already in progress on the runner\n      const runnerSandbox = await runnerAdapter.sandboxInfo(sandbox.id)\n      if (runnerSandbox.backupState === BackupState.IN_PROGRESS) {\n        await this.sandboxService.updateSandboxBackupState(sandbox.id, BackupState.IN_PROGRESS)\n        return\n      }\n\n      // Initiate backup on runner\n      await runnerAdapter.createBackup(sandbox, sandbox.backupSnapshot, registry)\n\n      await this.sandboxService.updateSandboxBackupState(sandbox.id, BackupState.IN_PROGRESS)\n    } catch (error) {\n      if (error.response?.status === 400 && error.response?.data?.message.includes('A backup is already in progress')) {\n        await this.sandboxService.updateSandboxBackupState(sandbox.id, BackupState.IN_PROGRESS)\n        return\n      }\n      await this.sandboxService.updateSandboxBackupState(\n        sandbox.id,\n        BackupState.ERROR,\n        undefined,\n        undefined,\n        fromAxiosError(error).message,\n      )\n      throw error\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @OnEvent(SandboxEvents.ARCHIVED)\n  @TrackJobExecution()\n  private async handleSandboxArchivedEvent(event: SandboxArchivedEvent) {\n    this.setBackupPending(event.sandbox)\n  }\n\n  @OnEvent(SandboxEvents.DESTROYED)\n  @TrackJobExecution()\n  private async handleSandboxDestroyedEvent(event: SandboxDestroyedEvent) {\n    this.deleteSandboxBackupRepositoryFromRegistry(event.sandbox)\n  }\n\n  @OnEvent(SandboxEvents.BACKUP_CREATED)\n  @TrackJobExecution()\n  private async handleSandboxBackupCreatedEvent(event: SandboxBackupCreatedEvent) {\n    this.setBackupPending(event.sandbox)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/sandbox-actions/sandbox-archive.action.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable } from '@nestjs/common'\nimport { Sandbox } from '../../entities/sandbox.entity'\nimport { SandboxState } from '../../enums/sandbox-state.enum'\nimport { DONT_SYNC_AGAIN, SandboxAction, SyncState, SYNC_AGAIN } from './sandbox.action'\nimport { BackupState } from '../../enums/backup-state.enum'\nimport { LockCode, RedisLockProvider } from '../../common/redis-lock.provider'\nimport { RunnerService } from '../../services/runner.service'\nimport { SandboxRepository } from '../../repositories/sandbox.repository'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\nimport { RunnerAdapterFactory } from '../../runner-adapter/runnerAdapter'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { SandboxEvents } from '../../constants/sandbox-events.constants'\nimport { SandboxBackupCreatedEvent } from '../../events/sandbox-backup-created.event'\nimport { WithSpan } from '../../../common/decorators/otel.decorator'\n\n@Injectable()\nexport class SandboxArchiveAction extends SandboxAction {\n  constructor(\n    protected runnerService: RunnerService,\n    protected runnerAdapterFactory: RunnerAdapterFactory,\n    protected sandboxRepository: SandboxRepository,\n    protected readonly redisLockProvider: RedisLockProvider,\n    @InjectRedis() private readonly redis: Redis,\n    private readonly eventEmitter: EventEmitter2,\n  ) {\n    super(runnerService, runnerAdapterFactory, sandboxRepository, redisLockProvider)\n  }\n\n  @WithSpan()\n  async run(sandbox: Sandbox, lockCode: LockCode): Promise<SyncState> {\n    // Only proceed with archiving if the sandbox is in STOPPED, ARCHIVING or ERROR (runner draining) state.\n    // For all other states, do not proceed with archiving.\n    if (\n      sandbox.state !== SandboxState.STOPPED &&\n      sandbox.state !== SandboxState.ARCHIVING &&\n      sandbox.state !== SandboxState.ERROR\n    ) {\n      return DONT_SYNC_AGAIN\n    }\n\n    const lockKey = 'archive-lock-' + sandbox.runnerId\n    if (!(await this.redisLockProvider.lock(lockKey, 10))) {\n      return DONT_SYNC_AGAIN\n    }\n\n    const isFromErrorState = sandbox.state === SandboxState.ERROR\n\n    await this.redisLockProvider.unlock(lockKey)\n\n    //  if the backup state is error, we need to retry the backup\n    if (sandbox.backupState === BackupState.ERROR) {\n      const archiveErrorRetryKey = 'archive-error-retry-' + sandbox.id\n      const archiveErrorRetryCountRaw = await this.redis.get(archiveErrorRetryKey)\n      const archiveErrorRetryCount = archiveErrorRetryCountRaw ? parseInt(archiveErrorRetryCountRaw) : 0\n      //  if the archive error retry count is greater than 3, we need to mark the sandbox as error\n      if (archiveErrorRetryCount > 3) {\n        // Only transition to ERROR if not already in ERROR state\n        if (!isFromErrorState) {\n          await this.updateSandboxState(\n            sandbox,\n            SandboxState.ERROR,\n            lockCode,\n            undefined,\n            'Failed to archive sandbox after 3 retries',\n          )\n        }\n        await this.redis.del(archiveErrorRetryKey)\n        return DONT_SYNC_AGAIN\n      }\n      await this.redis.setex('archive-error-retry-' + sandbox.id, 720, String(archiveErrorRetryCount + 1))\n\n      // recreate the backup to retry\n      this.eventEmitter.emit(SandboxEvents.BACKUP_CREATED, new SandboxBackupCreatedEvent(sandbox))\n\n      return DONT_SYNC_AGAIN\n    }\n\n    if (sandbox.backupState !== BackupState.COMPLETED) {\n      return DONT_SYNC_AGAIN\n    }\n\n    //  when the backup is completed, destroy the sandbox on the runner\n    //  and deassociate the sandbox from the runner\n    const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    try {\n      const sandboxInfo = await runnerAdapter.sandboxInfo(sandbox.id)\n      this.logger.log(`sandbox info from runner: state: ${sandboxInfo.state}, backupState: ${sandboxInfo.backupState}`)\n      if (sandboxInfo.state === SandboxState.DESTROYED) {\n        if (isFromErrorState) {\n          this.logger.warn(`Transitioning sandbox ${sandbox.id} from ERROR to ARCHIVED state (runner draining)`)\n        }\n\n        await this.updateSandboxState(sandbox, SandboxState.ARCHIVED, lockCode, null)\n        return DONT_SYNC_AGAIN\n      }\n\n      if (sandboxInfo.state !== SandboxState.DESTROYING) {\n        await runnerAdapter.destroySandbox(sandbox.id)\n      }\n\n      return SYNC_AGAIN\n    } catch (error) {\n      //  fail for errors other than sandbox not found or sandbox already destroyed\n      if (\n        (error.response?.data?.statusCode === 400 &&\n          error.response?.data?.message.includes('Sandbox already destroyed')) ||\n        error.response?.status === 404 ||\n        error.statusCode === 404\n      ) {\n        //  if the sandbox is already destroyed, do nothing\n        if (isFromErrorState) {\n          this.logger.warn(`Transitioning sandbox ${sandbox.id} from ERROR to ARCHIVED state (runner draining)`)\n        }\n\n        await this.updateSandboxState(sandbox, SandboxState.ARCHIVED, lockCode, null)\n        return DONT_SYNC_AGAIN\n      }\n\n      throw error\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/sandbox-actions/sandbox-destroy.action.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable } from '@nestjs/common'\nimport { Sandbox } from '../../entities/sandbox.entity'\nimport { SandboxState } from '../../enums/sandbox-state.enum'\nimport { DONT_SYNC_AGAIN, SandboxAction, SyncState, SYNC_AGAIN } from './sandbox.action'\nimport { RunnerState } from '../../enums/runner-state.enum'\nimport { RunnerService } from '../../services/runner.service'\nimport { RunnerAdapterFactory } from '../../runner-adapter/runnerAdapter'\nimport { SandboxRepository } from '../../repositories/sandbox.repository'\nimport { LockCode, RedisLockProvider } from '../../common/redis-lock.provider'\nimport { WithSpan } from '../../../common/decorators/otel.decorator'\n\n@Injectable()\nexport class SandboxDestroyAction extends SandboxAction {\n  constructor(\n    protected runnerService: RunnerService,\n    protected runnerAdapterFactory: RunnerAdapterFactory,\n    protected sandboxRepository: SandboxRepository,\n    protected redisLockProvider: RedisLockProvider,\n  ) {\n    super(runnerService, runnerAdapterFactory, sandboxRepository, redisLockProvider)\n  }\n\n  @WithSpan()\n  async run(sandbox: Sandbox, lockCode: LockCode): Promise<SyncState> {\n    if (sandbox.state === SandboxState.DESTROYED) {\n      return DONT_SYNC_AGAIN\n    }\n\n    if (sandbox.state === SandboxState.ARCHIVED || sandbox.state === SandboxState.PENDING_BUILD) {\n      await this.updateSandboxState(sandbox, SandboxState.DESTROYED, lockCode)\n      return DONT_SYNC_AGAIN\n    }\n\n    const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n    if (runner.state !== RunnerState.READY) {\n      return DONT_SYNC_AGAIN\n    }\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    try {\n      const sandboxInfo = await runnerAdapter.sandboxInfo(sandbox.id)\n\n      if (sandboxInfo.state === SandboxState.DESTROYED) {\n        await this.updateSandboxState(sandbox, SandboxState.DESTROYED, lockCode)\n        return DONT_SYNC_AGAIN\n      }\n\n      if (sandbox.state !== SandboxState.DESTROYING) {\n        await runnerAdapter.destroySandbox(sandbox.id)\n        await this.updateSandboxState(sandbox, SandboxState.DESTROYING, lockCode)\n      }\n\n      return SYNC_AGAIN\n    } catch (error) {\n      //  if the sandbox is not found on runner, it is already destroyed\n      if (error.response?.status === 404 || error.statusCode === 404) {\n        await this.updateSandboxState(sandbox, SandboxState.DESTROYED, lockCode)\n        return DONT_SYNC_AGAIN\n      }\n\n      throw error\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/sandbox-actions/sandbox-start.action.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, NotFoundException } from '@nestjs/common'\nimport { SandboxRepository } from '../../repositories/sandbox.repository'\nimport { RECOVERY_ERROR_SUBSTRINGS } from '../../constants/errors-for-recovery'\nimport { Sandbox } from '../../entities/sandbox.entity'\nimport { SandboxState } from '../../enums/sandbox-state.enum'\nimport { DONT_SYNC_AGAIN, SandboxAction, SYNC_AGAIN, SyncState } from './sandbox.action'\nimport { SANDBOX_BUILD_INFO_CACHE_TTL_MS } from '../../utils/sandbox-lookup-cache.util'\nimport { SnapshotRunnerState } from '../../enums/snapshot-runner-state.enum'\nimport { BackupState } from '../../enums/backup-state.enum'\nimport { RunnerState } from '../../enums/runner-state.enum'\nimport { BuildInfo } from '../../entities/build-info.entity'\nimport { SnapshotService } from '../../services/snapshot.service'\nimport { DockerRegistryService } from '../../../docker-registry/services/docker-registry.service'\nimport { DockerRegistry } from '../../../docker-registry/entities/docker-registry.entity'\nimport { RunnerService } from '../../services/runner.service'\nimport { RunnerAdapterFactory } from '../../runner-adapter/runnerAdapter'\nimport { SnapshotStateError } from '../../errors/snapshot-state-error'\nimport { Snapshot } from '../../entities/snapshot.entity'\nimport { OrganizationService } from '../../../organization/services/organization.service'\nimport { TypedConfigService } from '../../../config/typed-config.service'\nimport { Runner } from '../../entities/runner.entity'\nimport { Organization } from '../../../organization/entities/organization.entity'\nimport { LockCode, RedisLockProvider } from '../../common/redis-lock.provider'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\nimport { WithSpan } from '../../../common/decorators/otel.decorator'\n\n@Injectable()\nexport class SandboxStartAction extends SandboxAction {\n  protected readonly logger = new Logger(SandboxStartAction.name)\n  constructor(\n    protected runnerService: RunnerService,\n    protected runnerAdapterFactory: RunnerAdapterFactory,\n    protected sandboxRepository: SandboxRepository,\n    protected readonly snapshotService: SnapshotService,\n    protected readonly dockerRegistryService: DockerRegistryService,\n    protected readonly organizationService: OrganizationService,\n    protected readonly configService: TypedConfigService,\n    protected readonly redisLockProvider: RedisLockProvider,\n    @InjectRedis() private readonly redis: Redis,\n  ) {\n    super(runnerService, runnerAdapterFactory, sandboxRepository, redisLockProvider)\n  }\n\n  @WithSpan()\n  async run(sandbox: Sandbox, lockCode: LockCode): Promise<SyncState> {\n    // Load buildInfo only for states that need it — avoids a JOIN+DISTINCT in the\n    // shared syncInstanceState query that stop/destroy/archive paths never use.\n    if (\n      sandbox.snapshot === null &&\n      [SandboxState.PENDING_BUILD, SandboxState.BUILDING_SNAPSHOT, SandboxState.UNKNOWN].includes(sandbox.state)\n    ) {\n      await this.loadBuildInfo(sandbox)\n    }\n\n    switch (sandbox.state) {\n      case SandboxState.PULLING_SNAPSHOT: {\n        if (!sandbox.runnerId) {\n          // Using the PULLING_SNAPSHOT state for the case where the runner isn't assigned yet as well\n          return this.handleUnassignedRunnerSandbox(sandbox, lockCode)\n        } else {\n          return this.handleRunnerSandboxStartedStateCheck(sandbox, lockCode)\n        }\n      }\n      case SandboxState.PENDING_BUILD: {\n        return this.handleUnassignedRunnerSandbox(sandbox, lockCode, true)\n      }\n      case SandboxState.BUILDING_SNAPSHOT: {\n        return this.handleRunnerSandboxBuildingSnapshotStateOnDesiredStateStart(sandbox, lockCode)\n      }\n      case SandboxState.UNKNOWN: {\n        return this.handleRunnerSandboxUnknownStateOnDesiredStateStart(sandbox, lockCode)\n      }\n      case SandboxState.ARCHIVED:\n      case SandboxState.ARCHIVING:\n      case SandboxState.STOPPED: {\n        return this.handleRunnerSandboxStoppedOrArchivedStateOnDesiredStateStart(sandbox, lockCode)\n      }\n      case SandboxState.RESTORING:\n      case SandboxState.CREATING:\n      case SandboxState.STARTING: {\n        return this.handleRunnerSandboxStartedStateCheck(sandbox, lockCode)\n      }\n      case SandboxState.ERROR: {\n        this.logger.error(`Sandbox ${sandbox.id} is in error state on desired state start`)\n        return DONT_SYNC_AGAIN\n      }\n    }\n\n    return DONT_SYNC_AGAIN\n  }\n\n  /**\n   * Loads the buildInfo relation for a sandbox.\n   * Uses QueryBuilder with getMany() to avoid the SELECT DISTINCT subquery\n   * that TypeORM generates when combining relations with findOne/LIMIT.\n   * Since sandbox.id is a PK and BuildInfo is @ManyToOne, at most one row is returned.\n   */\n  private async loadBuildInfo(sandbox: Sandbox): Promise<void> {\n    const [result] = await this.sandboxRepository\n      .createQueryBuilder('sandbox')\n      .leftJoinAndSelect('sandbox.buildInfo', 'buildInfo')\n      .where('sandbox.id = :id', { id: sandbox.id })\n      .cache(`sandbox:buildInfo:${sandbox.id}`, SANDBOX_BUILD_INFO_CACHE_TTL_MS)\n      .getMany()\n    sandbox.buildInfo = result?.buildInfo ?? null\n  }\n\n  private async handleRunnerSandboxBuildingSnapshotStateOnDesiredStateStart(\n    sandbox: Sandbox,\n    lockCode: LockCode,\n  ): Promise<SyncState> {\n    // Check for timeout - allow up to 60 minutes since the last sandbox update\n    const timeoutMinutes = 60\n    const timeoutMs = timeoutMinutes * 60 * 1000\n\n    if (sandbox.updatedAt && Date.now() - sandbox.updatedAt.getTime() > timeoutMs) {\n      await this.updateSandboxState(\n        sandbox,\n        SandboxState.BUILD_FAILED,\n        lockCode,\n        undefined,\n        'Timeout while building snapshot on runner',\n      )\n      return DONT_SYNC_AGAIN\n    }\n\n    const snapshotRunner = await this.runnerService.getSnapshotRunner(sandbox.runnerId, sandbox.buildInfo.snapshotRef)\n    if (snapshotRunner) {\n      switch (snapshotRunner.state) {\n        case SnapshotRunnerState.READY: {\n          // TODO: \"UNKNOWN\" should probably be changed to something else\n          await this.updateSandboxState(sandbox, SandboxState.UNKNOWN, lockCode)\n          return SYNC_AGAIN\n        }\n        case SnapshotRunnerState.ERROR: {\n          await this.updateSandboxState(\n            sandbox,\n            SandboxState.BUILD_FAILED,\n            lockCode,\n            undefined,\n            snapshotRunner.errorReason,\n          )\n          return DONT_SYNC_AGAIN\n        }\n      }\n    }\n    if (!snapshotRunner || snapshotRunner.state === SnapshotRunnerState.BUILDING_SNAPSHOT) {\n      // Sleep for a second and go back to syncing instance state\n      await new Promise((resolve) => setTimeout(resolve, 1000))\n      return SYNC_AGAIN\n    }\n\n    return DONT_SYNC_AGAIN\n  }\n\n  private async handleUnassignedRunnerSandbox(\n    sandbox: Sandbox,\n    lockCode: LockCode,\n    isBuild = false,\n  ): Promise<SyncState> {\n    // Get snapshot reference based on whether it's a pull or build operation\n    let snapshotRef: string\n\n    if (isBuild) {\n      snapshotRef = sandbox.buildInfo.snapshotRef\n    } else {\n      const snapshot = await this.snapshotService.getSnapshotByName(sandbox.snapshot, sandbox.organizationId)\n      snapshotRef = snapshot.ref\n    }\n\n    const declarativeBuildScoreThreshold = this.configService.get('runnerScore.thresholds.declarativeBuild')\n\n    // Try to assign an available runner with the snapshot already available\n    try {\n      const runner = await this.runnerService.getRandomAvailableRunner({\n        regions: [sandbox.region],\n        sandboxClass: sandbox.class,\n        snapshotRef: snapshotRef,\n        ...(isBuild &&\n          declarativeBuildScoreThreshold !== undefined && {\n            availabilityScoreThreshold: declarativeBuildScoreThreshold,\n          }),\n      })\n      if (runner) {\n        await this.updateSandboxState(sandbox, SandboxState.UNKNOWN, lockCode, runner.id)\n        return SYNC_AGAIN\n      }\n    } catch {\n      // Continue to next assignment method\n    }\n\n    // Try to assign an available runner that is currently processing the snapshot\n    const snapshotRunners = await this.runnerService.getSnapshotRunners(snapshotRef)\n    const targetState = isBuild ? SnapshotRunnerState.BUILDING_SNAPSHOT : SnapshotRunnerState.PULLING_SNAPSHOT\n    const targetSandboxState = isBuild ? SandboxState.BUILDING_SNAPSHOT : SandboxState.PULLING_SNAPSHOT\n    const errorSandboxState = isBuild ? SandboxState.BUILD_FAILED : SandboxState.ERROR\n\n    for (const snapshotRunner of snapshotRunners) {\n      // Consider removing the runner usage rate check or improving it\n      const runner = await this.runnerService.findOneOrFail(snapshotRunner.runnerId)\n\n      if (snapshotRunner.state === SnapshotRunnerState.ERROR) {\n        await this.updateSandboxState(sandbox, errorSandboxState, lockCode, runner.id, snapshotRunner.errorReason)\n        return DONT_SYNC_AGAIN\n      }\n\n      if (runner.unschedulable || runner.draining || runner.state !== RunnerState.READY) {\n        continue\n      }\n\n      if (declarativeBuildScoreThreshold === undefined || runner.availabilityScore >= declarativeBuildScoreThreshold) {\n        if (snapshotRunner.state === targetState) {\n          await this.updateSandboxState(sandbox, targetSandboxState, lockCode, runner.id)\n          return SYNC_AGAIN\n        }\n      }\n    }\n\n    // Get excluded runner IDs based on operation type\n    const excludedRunnerIds = await (isBuild\n      ? this.runnerService.getRunnersWithMultipleSnapshotsBuilding()\n      : this.runnerService.getRunnersWithMultipleSnapshotsPulling())\n\n    // Try to assign an available runner to start processing the snapshot\n    let runner: Runner\n\n    try {\n      runner = await this.runnerService.getRandomAvailableRunner({\n        regions: [sandbox.region],\n        sandboxClass: sandbox.class,\n        excludedRunnerIds: excludedRunnerIds,\n        ...(isBuild &&\n          declarativeBuildScoreThreshold !== undefined && {\n            availabilityScoreThreshold: declarativeBuildScoreThreshold,\n          }),\n      })\n    } catch {\n      // TODO: reconsider the timeout here\n      // No runners available, wait for 3 seconds and retry\n      await new Promise((resolve) => setTimeout(resolve, 3000))\n      return SYNC_AGAIN\n    }\n\n    if (isBuild) {\n      this.buildOnRunner(sandbox.buildInfo, runner, sandbox.organizationId)\n      await this.updateSandboxState(sandbox, SandboxState.BUILDING_SNAPSHOT, lockCode, runner.id)\n    } else {\n      const snapshot = await this.snapshotService.getSnapshotByName(sandbox.snapshot, sandbox.organizationId)\n      await this.runnerService.createSnapshotRunnerEntry(runner.id, snapshot.ref, SnapshotRunnerState.PULLING_SNAPSHOT)\n      this.pullSnapshotToRunner(snapshot, runner)\n      await this.updateSandboxState(sandbox, SandboxState.PULLING_SNAPSHOT, lockCode, runner.id)\n    }\n\n    return SYNC_AGAIN\n  }\n\n  async pullSnapshotToRunner(snapshot: Snapshot, runner: Runner) {\n    const internalRegistry = await this.dockerRegistryService.findInternalRegistryBySnapshotRef(\n      snapshot.ref,\n      runner.region,\n    )\n    if (!internalRegistry) {\n      throw new Error('No internal registry found for sandbox snapshot')\n    }\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    // Fire the pull request (runner returns 202 immediately)\n    await runnerAdapter.pullSnapshot(snapshot.ref, internalRegistry)\n\n    const pollTimeoutMs = 60 * 60 * 1_000 // 1 hour\n    const pollIntervalMs = 5 * 1_000 // 5 seconds\n    const startTime = Date.now()\n\n    while (Date.now() - startTime < pollTimeoutMs) {\n      try {\n        await runnerAdapter.getSnapshotInfo(snapshot.ref)\n        return\n      } catch (err) {\n        if (err instanceof SnapshotStateError) {\n          throw err\n        }\n      }\n      await new Promise((resolve) => setTimeout(resolve, pollIntervalMs))\n    }\n  }\n\n  // Initiates the snapshot build on the runner and creates an SnapshotRunner depending on the result\n  async buildOnRunner(buildInfo: BuildInfo, runner: Runner, organizationId: string) {\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    const sourceRegistries = await this.dockerRegistryService.getSourceRegistriesForDockerfile(\n      buildInfo.dockerfileContent,\n      organizationId,\n    )\n\n    // Fire build request (runner returns 202 immediately)\n    await runnerAdapter.buildSnapshot(\n      buildInfo,\n      organizationId,\n      sourceRegistries.length > 0 ? sourceRegistries : undefined,\n    )\n\n    const pollTimeoutMs = 60 * 60 * 1_000 // 1 hour\n    const pollIntervalMs = 5 * 1_000 // 5 seconds\n    const startTime = Date.now()\n\n    while (Date.now() - startTime < pollTimeoutMs) {\n      try {\n        await runnerAdapter.getSnapshotInfo(buildInfo.snapshotRef)\n        break\n      } catch (err) {\n        if (err instanceof SnapshotStateError) {\n          await this.runnerService.createSnapshotRunnerEntry(\n            runner.id,\n            buildInfo.snapshotRef,\n            SnapshotRunnerState.ERROR,\n            err.message,\n          )\n          return\n        }\n        await new Promise((resolve) => setTimeout(resolve, pollIntervalMs))\n      }\n    }\n\n    if (Date.now() - startTime >= pollTimeoutMs) {\n      await this.runnerService.createSnapshotRunnerEntry(\n        runner.id,\n        buildInfo.snapshotRef,\n        SnapshotRunnerState.ERROR,\n        'Timeout while building',\n      )\n      return\n    }\n\n    const exists = await runnerAdapter.snapshotExists(buildInfo.snapshotRef)\n    let state = SnapshotRunnerState.BUILDING_SNAPSHOT\n    if (exists) {\n      state = SnapshotRunnerState.READY\n    }\n\n    await this.runnerService.createSnapshotRunnerEntry(runner.id, buildInfo.snapshotRef, state)\n  }\n\n  private async handleRunnerSandboxUnknownStateOnDesiredStateStart(\n    sandbox: Sandbox,\n    lockCode: LockCode,\n  ): Promise<SyncState> {\n    const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n    if (runner.state !== RunnerState.READY) {\n      return DONT_SYNC_AGAIN\n    }\n\n    const organization = await this.organizationService.findOne(sandbox.organizationId)\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    let internalRegistry: DockerRegistry\n    let entrypoint: string[]\n    if (!sandbox.buildInfo) {\n      //  get internal snapshot name\n      const snapshot = await this.snapshotService.getSnapshotByName(sandbox.snapshot, sandbox.organizationId)\n      const snapshotRef = snapshot.ref\n\n      internalRegistry = await this.dockerRegistryService.findInternalRegistryBySnapshotRef(snapshotRef, runner.region)\n      if (!internalRegistry) {\n        throw new Error('No registry found for snapshot')\n      }\n\n      sandbox.snapshot = snapshotRef\n      entrypoint = snapshot.entrypoint\n    } else {\n      sandbox.snapshot = sandbox.buildInfo.snapshotRef\n      entrypoint = this.snapshotService.getEntrypointFromDockerfile(sandbox.buildInfo.dockerfileContent)\n    }\n\n    const metadata = {\n      ...organization?.sandboxMetadata,\n      sandboxName: sandbox.name,\n    }\n\n    const result = await runnerAdapter.createSandbox(\n      sandbox,\n      internalRegistry,\n      entrypoint,\n      metadata,\n      this.configService.get('sandboxOtel.endpointUrl'),\n    )\n\n    await this.updateSandboxState(sandbox, SandboxState.CREATING, lockCode, undefined, undefined, result?.daemonVersion)\n    //  sync states again immediately for sandbox\n    return SYNC_AGAIN\n  }\n\n  private async handleRunnerSandboxStoppedOrArchivedStateOnDesiredStateStart(\n    sandbox: Sandbox,\n    lockCode: LockCode,\n  ): Promise<SyncState> {\n    const organization = await this.organizationService.findOne(sandbox.organizationId)\n\n    //  check if sandbox is assigned to a runner and if that runner is unschedulable\n    //  if it is, move sandbox to prevRunnerId, and set runnerId to null\n    //  this will assign a new runner to the sandbox and restore the sandbox from the latest backup\n    if (sandbox.runnerId) {\n      const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n      const originalRunnerId = sandbox.runnerId // Store original value\n\n      const startScoreThreshold = this.configService.get('runnerScore.thresholds.start') || 0\n\n      const shouldMoveToNewRunner =\n        (runner.unschedulable || runner.state != RunnerState.READY || runner.availabilityScore < startScoreThreshold) &&\n        sandbox.backupState === BackupState.COMPLETED\n\n      // if the runner is unschedulable/not ready and sandbox has a valid backup, move sandbox to a new runner\n      if (shouldMoveToNewRunner) {\n        sandbox.prevRunnerId = originalRunnerId\n        sandbox.runnerId = null\n\n        await this.sandboxRepository.update(\n          sandbox.id,\n          {\n            updateData: {\n              prevRunnerId: originalRunnerId,\n              runnerId: null,\n            },\n          },\n          true,\n        )\n      }\n\n      // If the sandbox is on a runner and its backupState is COMPLETED\n      // but there are too many running sandboxes on that runner, move it to a less used runner\n      if (sandbox.backupState === BackupState.COMPLETED) {\n        if (runner.availabilityScore < this.configService.getOrThrow('runnerScore.thresholds.availability')) {\n          const availableRunners = await this.runnerService.findAvailableRunners({\n            regions: [sandbox.region],\n            sandboxClass: sandbox.class,\n          })\n          const lessUsedRunners = availableRunners.filter((runner) => runner.id !== originalRunnerId)\n\n          //  temp workaround to move sandboxes to less used runner\n          if (lessUsedRunners.length > 0) {\n            sandbox.prevRunnerId = originalRunnerId\n            sandbox.runnerId = null\n\n            await this.sandboxRepository.update(\n              sandbox.id,\n              {\n                updateData: {\n                  prevRunnerId: originalRunnerId,\n                  runnerId: null,\n                },\n              },\n              true,\n            )\n            try {\n              const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n              await runnerAdapter.destroySandbox(sandbox.id)\n            } catch (e) {\n              if (e.response?.status !== 404 && e.statusCode !== 404) {\n                this.logger.error(`Failed to cleanup sandbox ${sandbox.id} on previous runner ${runner.id}:`, e)\n              }\n            }\n          }\n        }\n      }\n    }\n\n    if (sandbox.runnerId === null) {\n      //  if sandbox has no runner, check if backup is completed\n      //  if not, set sandbox to error\n      //  if backup is completed, get random available runner and start sandbox\n      //  use the backup to start the sandbox\n\n      if (sandbox.backupState !== BackupState.COMPLETED) {\n        await this.updateSandboxState(\n          sandbox,\n          SandboxState.ERROR,\n          lockCode,\n          undefined,\n          'Sandbox has no runner and backup is not completed',\n        )\n        return DONT_SYNC_AGAIN\n      }\n\n      const syncCheck = await this.restoreSandboxOnNewRunner(sandbox, lockCode, organization, sandbox.prevRunnerId)\n      if (syncCheck !== null) {\n        return syncCheck\n      }\n    } else {\n      // if sandbox has runner, start sandbox\n      const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n\n      if (runner.state !== RunnerState.READY) {\n        return DONT_SYNC_AGAIN\n      }\n\n      const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n      const metadata: { [key: string]: string } = { ...organization?.sandboxMetadata }\n      if (sandbox.volumes?.length) {\n        metadata['volumes'] = JSON.stringify(\n          sandbox.volumes.map((v) => ({ volumeId: v.volumeId, mountPath: v.mountPath, subpath: v.subpath })),\n        )\n      }\n\n      try {\n        await runnerAdapter.startSandbox(sandbox.id, sandbox.authToken, metadata)\n      } catch (error) {\n        // Check against a list of substrings that should trigger an automatic recovery\n        if (error?.message) {\n          const matchesRecovery = RECOVERY_ERROR_SUBSTRINGS.some((substring) =>\n            error.message.toLowerCase().includes(substring.toLowerCase()),\n          )\n          if (matchesRecovery) {\n            try {\n              await this.restoreSandboxOnNewRunner(sandbox, lockCode, organization, sandbox.runnerId, true)\n              this.logger.warn(`Sandbox ${sandbox.id} transferred to a new runner`)\n              return SYNC_AGAIN\n            } catch (restoreError) {\n              this.logger.warn(`Sandbox ${sandbox.id} recovery attempt failed:`, restoreError.message)\n            }\n          }\n        }\n        throw error\n      }\n\n      await this.updateSandboxState(sandbox, SandboxState.STARTING, lockCode)\n      return SYNC_AGAIN\n    }\n\n    return SYNC_AGAIN\n  }\n\n  //  used to check if sandbox is started on runner and update sandbox state accordingly\n  //  also used to handle the case where a sandbox is started on a runner and then transferred to a new runner\n  private async handleRunnerSandboxStartedStateCheck(sandbox: Sandbox, lockCode: LockCode): Promise<SyncState> {\n    //  edge case when sandbox is being transferred to a new runner\n    if (!sandbox.runnerId) {\n      return SYNC_AGAIN\n    }\n\n    const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n    const sandboxInfo = await runnerAdapter.sandboxInfo(sandbox.id)\n\n    switch (sandboxInfo.state) {\n      case SandboxState.STARTED: {\n        //  if previous backup state is error or completed, set backup state to none\n        if ([BackupState.ERROR, BackupState.COMPLETED].includes(sandbox.backupState)) {\n          await this.updateSandboxState(\n            sandbox,\n            SandboxState.STARTED,\n            lockCode,\n            undefined,\n            undefined,\n            sandboxInfo.daemonVersion,\n            BackupState.NONE,\n          )\n          return DONT_SYNC_AGAIN\n        } else {\n          await this.updateSandboxState(\n            sandbox,\n            SandboxState.STARTED,\n            lockCode,\n            undefined,\n            undefined,\n            sandboxInfo.daemonVersion,\n          )\n\n          //  if sandbox was transferred to a new runner, remove it from the old runner\n          if (sandbox.prevRunnerId) {\n            await this.removeSandboxFromPreviousRunner(sandbox)\n          }\n\n          return DONT_SYNC_AGAIN\n        }\n      }\n      case SandboxState.STARTING:\n        if (await this.checkTimeoutError(sandbox, 5, 'Timeout while starting sandbox')) {\n          return DONT_SYNC_AGAIN\n        }\n        break\n      case SandboxState.RESTORING:\n        if (await this.checkTimeoutError(sandbox, 30, 'Timeout while starting sandbox')) {\n          return DONT_SYNC_AGAIN\n        }\n        break\n      case SandboxState.CREATING: {\n        if (await this.checkTimeoutError(sandbox, 15, 'Timeout while creating sandbox')) {\n          return DONT_SYNC_AGAIN\n        }\n        break\n      }\n      case SandboxState.UNKNOWN: {\n        await this.updateSandboxState(sandbox, SandboxState.UNKNOWN, lockCode)\n        break\n      }\n      case SandboxState.ERROR: {\n        await this.updateSandboxState(\n          sandbox,\n          SandboxState.ERROR,\n          lockCode,\n          undefined,\n          'Sandbox entered error state on runner during startup wait loop',\n        )\n        break\n      }\n      case SandboxState.PULLING_SNAPSHOT: {\n        if (await this.checkTimeoutError(sandbox, 30, 'Timeout while pulling snapshot')) {\n          return DONT_SYNC_AGAIN\n        }\n        await this.updateSandboxState(sandbox, SandboxState.PULLING_SNAPSHOT, lockCode)\n        break\n      }\n      case SandboxState.DESTROYED: {\n        this.logger.warn(\n          `Sandbox ${sandbox.id} is in destroyed state while starting on runner ${sandbox.runnerId}, prev runner ${sandbox.prevRunnerId}`,\n        )\n        await this.checkTimeoutError(\n          sandbox,\n          15,\n          'Timeout while starting sandbox: Sandbox is in unknown state on runner',\n        )\n        return DONT_SYNC_AGAIN\n      }\n      // also any other state that is not STARTED\n      default: {\n        this.logger.error(`Sandbox ${sandbox.id} is in unexpected state ${sandboxInfo.state}`)\n        await this.updateSandboxState(\n          sandbox,\n          SandboxState.ERROR,\n          lockCode,\n          undefined,\n          `Sandbox is in unexpected state: ${sandboxInfo.state}`,\n        )\n        break\n      }\n    }\n\n    return SYNC_AGAIN\n  }\n\n  private async checkTimeoutError(sandbox: Sandbox, timeoutMinutes: number, errorReason: string): Promise<boolean> {\n    if (\n      sandbox.lastActivityAt &&\n      new Date(sandbox.lastActivityAt).getTime() < Date.now() - 1000 * 60 * timeoutMinutes\n    ) {\n      const updateData: Partial<Sandbox> = {\n        state: SandboxState.ERROR,\n        errorReason,\n        recoverable: false,\n      }\n      await this.sandboxRepository.update(sandbox.id, { updateData, entity: sandbox })\n      return true\n    }\n    return false\n  }\n\n  private async restoreSandboxOnNewRunner(\n    sandbox: Sandbox,\n    lockCode: LockCode,\n    organization: Organization,\n    excludedRunnerId: string,\n    isRecovery?: boolean,\n  ): Promise<SyncState | null> {\n    let lockKey: string | null = null\n\n    // Recovery lock to prevent frequent automatic restore attempts\n    if (isRecovery) {\n      lockKey = `sandbox-${sandbox.id}-restored-cooldown`\n      const sixHoursInSeconds = 6 * 60 * 60\n      const acquired = await this.redisLockProvider.lock(lockKey, sixHoursInSeconds)\n      if (!acquired) {\n        return null\n      }\n    }\n\n    if (!sandbox.backupRegistryId) {\n      throw new Error('No registry found for backup')\n    }\n\n    const registry = await this.dockerRegistryService.findOne(sandbox.backupRegistryId)\n    if (!registry) {\n      throw new Error('No registry found for backup')\n    }\n\n    //  make sure we pick a runner that has the base snapshot\n    let baseSnapshot: Snapshot | null = null\n    if (sandbox.snapshot) {\n      try {\n        baseSnapshot = await this.snapshotService.getSnapshotByName(sandbox.snapshot, sandbox.organizationId)\n      } catch (e) {\n        if (e instanceof NotFoundException) {\n          //  if the base snapshot is not found, we'll use any available runner later\n        } else {\n          if (isRecovery) {\n            return SYNC_AGAIN\n          }\n          //  for all other errors, throw them\n          throw e\n        }\n      }\n    }\n\n    const snapshotRef = baseSnapshot ? baseSnapshot.ref : null\n\n    let availableRunners: Runner[] = []\n\n    const excludedRunnerIds: string[] = excludedRunnerId ? [excludedRunnerId] : []\n\n    const runnersWithBaseSnapshot: Runner[] = snapshotRef\n      ? await this.runnerService.findAvailableRunners({\n          regions: [sandbox.region],\n          sandboxClass: sandbox.class,\n          snapshotRef,\n          excludedRunnerIds,\n        })\n      : []\n    if (runnersWithBaseSnapshot.length > 0) {\n      availableRunners = runnersWithBaseSnapshot\n    } else {\n      //  if no runner has the base snapshot, get all available runners\n      availableRunners = await this.runnerService.findAvailableRunners({\n        regions: [sandbox.region],\n        excludedRunnerIds,\n      })\n    }\n\n    //  check if we have any available runners after filtering\n    if (availableRunners.length === 0) {\n      // Sync state again later. Runners are unavailable\n      if (isRecovery) {\n        await this.redisLockProvider.unlock(lockKey)\n      }\n      return DONT_SYNC_AGAIN\n    }\n\n    //  get random runner from available runners\n    const randomRunnerIndex = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1) + min)\n    const runner = availableRunners[randomRunnerIndex(0, availableRunners.length - 1)]\n\n    //  verify the runner is still available and ready\n    if (!runner || runner.state !== RunnerState.READY || runner.unschedulable) {\n      this.logger.warn(`Selected runner ${runner?.id || 'null'} is no longer available, retrying sandbox assignment`)\n      if (isRecovery) {\n        await this.redisLockProvider.unlock(lockKey)\n      }\n      return SYNC_AGAIN\n    }\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    const existingBackups = sandbox.existingBackupSnapshots\n      .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())\n      .map((existingSnapshot) => existingSnapshot.snapshotName)\n\n    let validBackup: string | null = null\n    let exists = false\n\n    for (const existingBackup of existingBackups) {\n      try {\n        if (!validBackup && sandbox.backupSnapshot) {\n          //  last snapshot is the current snapshot, so we don't need to check it\n          //  just in case, we'll use the value from the backupSnapshot property\n          validBackup = sandbox.backupSnapshot\n        } else {\n          validBackup = existingBackup\n        }\n\n        if (!validBackup) {\n          continue\n        }\n\n        await runnerAdapter.inspectSnapshotInRegistry(validBackup, registry)\n        exists = true\n        break\n      } catch (error) {\n        this.logger.error(`Failed to check if backup snapshot ${validBackup} exists in registry ${registry.id}:`, error)\n      }\n    }\n\n    const restoreBackupSnapshotRetryKey = `restore-backup-snapshot-retry-${sandbox.id}`\n    if (!exists) {\n      if (!isRecovery) {\n        // Check retry count - allow up to 3 attempts for transient issues\n        const retryCountRaw = await this.redis.get(restoreBackupSnapshotRetryKey)\n        const retryCount = retryCountRaw ? parseInt(retryCountRaw) : 0\n\n        if (retryCount < 3) {\n          // Increment retry count with 10 minute TTL, let syncStates cron pick up the retry later\n          await this.redis.setex(restoreBackupSnapshotRetryKey, 600, String(retryCount + 1))\n          this.logger.warn(\n            `No valid backup snapshot found for sandbox ${sandbox.id}, retry attempt ${retryCount + 1}/3`,\n          )\n          return DONT_SYNC_AGAIN\n        }\n\n        // After 3 retries, error out and clear the retry counter\n        await this.redis.del(restoreBackupSnapshotRetryKey)\n        await this.updateSandboxState(\n          sandbox,\n          SandboxState.ERROR,\n          lockCode,\n          undefined,\n          'No valid backup snapshot found',\n        )\n      } else {\n        throw new Error('No valid backup snapshot found')\n      }\n      return SYNC_AGAIN\n    }\n\n    // Clear the retry counter on success\n    await this.redis.del(restoreBackupSnapshotRetryKey)\n\n    await this.updateSandboxState(sandbox, SandboxState.RESTORING, lockCode, runner.id)\n\n    sandbox.snapshot = validBackup\n\n    const metadata = {\n      ...organization?.sandboxMetadata,\n      sandboxName: sandbox.name,\n    }\n\n    await runnerAdapter.createSandbox(\n      sandbox,\n      registry,\n      undefined,\n      metadata,\n      this.configService.get('sandboxOtel.endpointUrl'),\n    )\n    return null\n  }\n\n  private async removeSandboxFromPreviousRunner(sandbox: Sandbox): Promise<void> {\n    const runner = await this.runnerService.findOne(sandbox.prevRunnerId)\n    if (!runner) {\n      this.logger.warn(`Previously assigned runner ${sandbox.prevRunnerId} for sandbox ${sandbox.id} not found`)\n\n      await this.sandboxRepository.update(sandbox.id, { updateData: { prevRunnerId: null } }, true)\n      return\n    }\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    try {\n      // First try to destroy the sandbox\n      await runnerAdapter.destroySandbox(sandbox.id)\n    } catch (error) {\n      if (error.response?.status !== 404 && error.statusCode !== 404) {\n        this.logger.error(`Failed to cleanup sandbox ${sandbox.id} on previous runner ${runner.id}:`, error)\n        throw error\n      }\n    }\n\n    await this.sandboxRepository.update(sandbox.id, { updateData: { prevRunnerId: null } }, true)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/sandbox-actions/sandbox-stop.action.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable } from '@nestjs/common'\nimport { Sandbox } from '../../entities/sandbox.entity'\nimport { SandboxState } from '../../enums/sandbox-state.enum'\nimport { DONT_SYNC_AGAIN, SandboxAction, SyncState, SYNC_AGAIN } from './sandbox.action'\nimport { BackupState } from '../../enums/backup-state.enum'\nimport { RunnerState } from '../../enums/runner-state.enum'\nimport { RunnerService } from '../../services/runner.service'\nimport { RunnerAdapterFactory } from '../../runner-adapter/runnerAdapter'\nimport { SandboxRepository } from '../../repositories/sandbox.repository'\nimport { LockCode, RedisLockProvider } from '../../common/redis-lock.provider'\nimport { WithSpan } from '../../../common/decorators/otel.decorator'\n\n@Injectable()\nexport class SandboxStopAction extends SandboxAction {\n  constructor(\n    protected runnerService: RunnerService,\n    protected runnerAdapterFactory: RunnerAdapterFactory,\n    protected sandboxRepository: SandboxRepository,\n    protected redisLockProvider: RedisLockProvider,\n  ) {\n    super(runnerService, runnerAdapterFactory, sandboxRepository, redisLockProvider)\n  }\n\n  @WithSpan()\n  async run(sandbox: Sandbox, lockCode: LockCode): Promise<SyncState> {\n    const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n    if (runner.state !== RunnerState.READY) {\n      return DONT_SYNC_AGAIN\n    }\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    if (sandbox.state === SandboxState.STARTED) {\n      // stop sandbox\n      await runnerAdapter.stopSandbox(sandbox.id)\n      await this.updateSandboxState(sandbox, SandboxState.STOPPING, lockCode)\n\n      //  sync states again immediately for sandbox\n      return SYNC_AGAIN\n    }\n\n    if (sandbox.state !== SandboxState.STOPPING && sandbox.state !== SandboxState.ERROR) {\n      return DONT_SYNC_AGAIN\n    }\n\n    const sandboxInfo = await runnerAdapter.sandboxInfo(sandbox.id)\n\n    if (sandboxInfo.state === SandboxState.STOPPED) {\n      await this.updateSandboxState(\n        sandbox,\n        SandboxState.STOPPED,\n        lockCode,\n        undefined,\n        undefined,\n        undefined,\n        BackupState.NONE,\n      )\n      return DONT_SYNC_AGAIN\n    } else if (sandboxInfo.state === SandboxState.ERROR) {\n      await this.updateSandboxState(\n        sandbox,\n        SandboxState.ERROR,\n        lockCode,\n        undefined,\n        'Sandbox is in error state on runner',\n      )\n      return DONT_SYNC_AGAIN\n    }\n\n    return SYNC_AGAIN\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/sandbox-actions/sandbox.action.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { RunnerService } from '../../services/runner.service'\nimport { RunnerAdapterFactory } from '../../runner-adapter/runnerAdapter'\nimport { Sandbox } from '../../entities/sandbox.entity'\nimport { SandboxRepository } from '../../repositories/sandbox.repository'\nimport { SandboxState } from '../../enums/sandbox-state.enum'\nimport { BackupState } from '../../enums/backup-state.enum'\nimport { getStateChangeLockKey } from '../../utils/lock-key.util'\nimport { LockCode, RedisLockProvider } from '../../common/redis-lock.provider'\n\nexport const SYNC_AGAIN = 'sync-again'\nexport const DONT_SYNC_AGAIN = 'dont-sync-again'\nexport type SyncState = typeof SYNC_AGAIN | typeof DONT_SYNC_AGAIN\n\n@Injectable()\nexport abstract class SandboxAction {\n  protected readonly logger = new Logger(SandboxAction.name)\n\n  constructor(\n    protected readonly runnerService: RunnerService,\n    protected runnerAdapterFactory: RunnerAdapterFactory,\n    protected readonly sandboxRepository: SandboxRepository,\n    protected readonly redisLockProvider: RedisLockProvider,\n  ) {}\n\n  abstract run(sandbox: Sandbox, lockCode: LockCode): Promise<SyncState>\n\n  protected async updateSandboxState(\n    sandbox: Sandbox,\n    state: SandboxState,\n    expectedLockCode: LockCode,\n    runnerId?: string | null | undefined,\n    errorReason?: string,\n    daemonVersion?: string,\n    backupState?: BackupState,\n    recoverable?: boolean,\n  ) {\n    //  check if the lock code is still valid\n    const lockKey = getStateChangeLockKey(sandbox.id)\n    const currentLockCode = await this.redisLockProvider.getCode(lockKey)\n\n    if (currentLockCode === null) {\n      this.logger.warn(\n        `no lock code found - state update action expired - skipping - sandboxId: ${sandbox.id} - state: ${state}`,\n      )\n      return\n    }\n\n    if (expectedLockCode.getCode() !== currentLockCode.getCode()) {\n      this.logger.warn(\n        `lock code mismatch - state update action expired - skipping - sandboxId: ${sandbox.id} - state: ${state}`,\n      )\n      return\n    }\n\n    if (state !== SandboxState.ARCHIVED && !sandbox.pending) {\n      const err = new Error(`sandbox ${sandbox.id} is not in a pending state`)\n      this.logger.error(err)\n      return\n    }\n\n    const updateData: Partial<Sandbox> = {\n      state,\n    }\n\n    if (runnerId !== undefined) {\n      updateData.runnerId = runnerId\n    }\n\n    if (errorReason !== undefined) {\n      updateData.errorReason = errorReason\n      if (state === SandboxState.ERROR) {\n        updateData.recoverable = recoverable ?? false\n      }\n    }\n\n    if (sandbox.state === SandboxState.ERROR && !sandbox.errorReason) {\n      updateData.errorReason = 'Sandbox is in error state during update'\n      updateData.recoverable = false\n    }\n\n    if (daemonVersion !== undefined) {\n      updateData.daemonVersion = daemonVersion\n    }\n\n    if (state == SandboxState.DESTROYED) {\n      updateData.backupState = BackupState.NONE\n    }\n\n    if (backupState !== undefined) {\n      Object.assign(updateData, Sandbox.getBackupStateUpdate(sandbox, backupState))\n    }\n\n    if (recoverable !== undefined) {\n      updateData.recoverable = recoverable\n    }\n\n    await this.sandboxRepository.update(sandbox.id, { updateData, entity: sandbox })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/sandbox.manager.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, OnApplicationShutdown } from '@nestjs/common'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { In, IsNull, MoreThanOrEqual, Not, Raw } from 'typeorm'\nimport { randomUUID } from 'crypto'\n\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\nimport { RunnerService } from '../services/runner.service'\n\nimport { RedisLockProvider, LockCode } from '../common/redis-lock.provider'\n\nimport { SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION } from '../constants/sandbox.constants'\n\nimport { SandboxEvents } from '../constants/sandbox-events.constants'\nimport { SandboxStoppedEvent } from '../events/sandbox-stopped.event'\nimport { SandboxStartedEvent } from '../events/sandbox-started.event'\nimport { SandboxArchivedEvent } from '../events/sandbox-archived.event'\nimport { SandboxDestroyedEvent } from '../events/sandbox-destroyed.event'\nimport { SandboxCreatedEvent } from '../events/sandbox-create.event'\n\nimport { WithInstrumentation, WithSpan } from '../../common/decorators/otel.decorator'\n\nimport { SandboxStartAction } from './sandbox-actions/sandbox-start.action'\nimport { SandboxStopAction } from './sandbox-actions/sandbox-stop.action'\nimport { SandboxDestroyAction } from './sandbox-actions/sandbox-destroy.action'\nimport { SandboxArchiveAction } from './sandbox-actions/sandbox-archive.action'\nimport { SYNC_AGAIN, DONT_SYNC_AGAIN } from './sandbox-actions/sandbox.action'\n\nimport { TrackJobExecution } from '../../common/decorators/track-job-execution.decorator'\nimport { TrackableJobExecutions } from '../../common/interfaces/trackable-job-executions'\nimport { setTimeout } from 'timers/promises'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport { getStateChangeLockKey } from '../utils/lock-key.util'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { OnAsyncEvent } from '../../common/decorators/on-async-event.decorator'\nimport { sanitizeSandboxError } from '../utils/sanitize-error.util'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { RunnerAdapterFactory } from '../runner-adapter/runnerAdapter'\nimport { DockerRegistryService } from '../../docker-registry/services/docker-registry.service'\nimport { OrganizationService } from '../../organization/services/organization.service'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { BackupManager } from './backup.manager'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\n\n@Injectable()\nexport class SandboxManager implements TrackableJobExecutions, OnApplicationShutdown {\n  activeJobs = new Set<string>()\n\n  private readonly logger = new Logger(SandboxManager.name)\n\n  constructor(\n    private readonly sandboxRepository: SandboxRepository,\n    private readonly runnerService: RunnerService,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly sandboxStartAction: SandboxStartAction,\n    private readonly sandboxStopAction: SandboxStopAction,\n    private readonly sandboxDestroyAction: SandboxDestroyAction,\n    private readonly sandboxArchiveAction: SandboxArchiveAction,\n    private readonly configService: TypedConfigService,\n    private readonly dockerRegistryService: DockerRegistryService,\n    private readonly organizationService: OrganizationService,\n    private readonly runnerAdapterFactory: RunnerAdapterFactory,\n    private readonly backupManager: BackupManager,\n    @InjectRedis() private readonly redis: Redis,\n  ) {}\n\n  async onApplicationShutdown() {\n    //  wait for all active jobs to finish\n    while (this.activeJobs.size > 0) {\n      this.logger.log(`Waiting for ${this.activeJobs.size} active jobs to finish`)\n      await setTimeout(1000)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'auto-stop-check' })\n  @TrackJobExecution()\n  @WithInstrumentation()\n  @LogExecution('auto-stop-check')\n  @WithInstrumentation()\n  async autostopCheck(): Promise<void> {\n    const lockKey = 'auto-stop-check-worker-selected'\n    //  lock the sync to only run one instance at a time\n    if (!(await this.redisLockProvider.lock(lockKey, 60))) {\n      return\n    }\n\n    try {\n      const readyRunners = await this.runnerService.findAllReady()\n\n      // Process all runners in parallel\n      await Promise.all(\n        readyRunners.map(async (runner) => {\n          const sandboxes = await this.sandboxRepository.find({\n            where: {\n              runnerId: runner.id,\n              organizationId: Not(SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION),\n              state: SandboxState.STARTED,\n              desiredState: SandboxDesiredState.STARTED,\n              pending: Not(true),\n              autoStopInterval: Not(0),\n              lastActivityAt: Raw((alias) => `${alias} < NOW() - INTERVAL '1 minute' * \"autoStopInterval\"`),\n            },\n            order: {\n              lastBackupAt: 'ASC',\n            },\n            take: 100,\n          })\n\n          await Promise.all(\n            sandboxes.map(async (sandbox) => {\n              const lockKey = getStateChangeLockKey(sandbox.id)\n              const acquired = await this.redisLockProvider.lock(lockKey, 30)\n              if (!acquired) {\n                return\n              }\n\n              let updateData: Partial<Sandbox> = {}\n\n              //  if auto-delete interval is 0, delete the sandbox immediately\n              if (sandbox.autoDeleteInterval === 0) {\n                updateData = Sandbox.getSoftDeleteUpdate(sandbox)\n              } else {\n                updateData.pending = true\n                updateData.desiredState = SandboxDesiredState.STOPPED\n              }\n\n              try {\n                await this.sandboxRepository.updateWhere(sandbox.id, {\n                  updateData,\n                  whereCondition: { pending: false, state: sandbox.state },\n                })\n\n                this.syncInstanceState(sandbox.id).catch(this.logger.error)\n              } catch (error) {\n                this.logger.error(`Error processing auto-stop state for sandbox ${sandbox.id}:`, error)\n              } finally {\n                await this.redisLockProvider.unlock(lockKey)\n              }\n            }),\n          )\n        }),\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'auto-archive-check' })\n  @TrackJobExecution()\n  @LogExecution('auto-archive-check')\n  @WithInstrumentation()\n  async autoArchiveCheck(): Promise<void> {\n    const lockKey = 'auto-archive-check-worker-selected'\n    //  lock the sync to only run one instance at a time\n    if (!(await this.redisLockProvider.lock(lockKey, 60))) {\n      return\n    }\n\n    try {\n      const sandboxes = await this.sandboxRepository.find({\n        where: {\n          organizationId: Not(SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION),\n          state: SandboxState.STOPPED,\n          desiredState: SandboxDesiredState.STOPPED,\n          pending: Not(true),\n          lastActivityAt: Raw((alias) => `${alias} < NOW() - INTERVAL '1 minute' * \"autoArchiveInterval\"`),\n        },\n        order: {\n          lastBackupAt: 'ASC',\n        },\n        take: 100,\n      })\n\n      await Promise.all(\n        sandboxes.map(async (sandbox) => {\n          const lockKey = getStateChangeLockKey(sandbox.id)\n          const acquired = await this.redisLockProvider.lock(lockKey, 30)\n          if (!acquired) {\n            return\n          }\n\n          try {\n            const updateData: Partial<Sandbox> = {\n              desiredState: SandboxDesiredState.ARCHIVED,\n            }\n            await this.sandboxRepository.updateWhere(sandbox.id, {\n              updateData,\n              whereCondition: { pending: false, state: sandbox.state },\n            })\n\n            this.syncInstanceState(sandbox.id).catch(this.logger.error)\n          } catch (error) {\n            this.logger.error(`Error processing auto-archive state for sandbox ${sandbox.id}:`, error)\n          } finally {\n            await this.redisLockProvider.unlock(lockKey)\n          }\n        }),\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'auto-delete-check' })\n  @TrackJobExecution()\n  @LogExecution('auto-delete-check')\n  @WithInstrumentation()\n  async autoDeleteCheck(): Promise<void> {\n    const lockKey = 'auto-delete-check-worker-selected'\n    //  lock the sync to only run one instance at a time\n    if (!(await this.redisLockProvider.lock(lockKey, 60))) {\n      return\n    }\n\n    try {\n      const readyRunners = await this.runnerService.findAllReady()\n\n      // Process all runners in parallel\n      await Promise.all(\n        readyRunners.map(async (runner) => {\n          const sandboxes = await this.sandboxRepository.find({\n            where: {\n              runnerId: runner.id,\n              organizationId: Not(SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION),\n              state: SandboxState.STOPPED,\n              desiredState: SandboxDesiredState.STOPPED,\n              pending: Not(true),\n              autoDeleteInterval: MoreThanOrEqual(0),\n              lastActivityAt: Raw((alias) => `${alias} < NOW() - INTERVAL '1 minute' * \"autoDeleteInterval\"`),\n            },\n            order: {\n              lastActivityAt: 'ASC',\n            },\n            take: 100,\n          })\n\n          await Promise.all(\n            sandboxes.map(async (sandbox) => {\n              const lockKey = getStateChangeLockKey(sandbox.id)\n              const acquired = await this.redisLockProvider.lock(lockKey, 30)\n              if (!acquired) {\n                return\n              }\n\n              try {\n                const updateData = Sandbox.getSoftDeleteUpdate(sandbox)\n                await this.sandboxRepository.updateWhere(sandbox.id, {\n                  updateData,\n                  whereCondition: { pending: false, state: sandbox.state },\n                })\n\n                this.syncInstanceState(sandbox.id).catch(this.logger.error)\n              } catch (error) {\n                this.logger.error(`Error processing auto-delete state for sandbox ${sandbox.id}:`, error)\n              } finally {\n                await this.redisLockProvider.unlock(lockKey)\n              }\n            }),\n          )\n        }),\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'draining-runner-sandboxes-check' })\n  @TrackJobExecution()\n  @LogExecution('draining-runner-sandboxes-check')\n  @WithInstrumentation()\n  async drainingRunnerSandboxesCheck(): Promise<void> {\n    const lockKey = 'draining-runner-sandboxes-check'\n    const lockTtl = 10 * 60 // seconds (10 min)\n    if (!(await this.redisLockProvider.lock(lockKey, lockTtl))) {\n      return\n    }\n\n    try {\n      const skip = (await this.redis.get('draining-runner-sandboxes-skip')) || 0\n\n      const drainingRunners = await this.runnerService.findDrainingPaginated(Number(skip), 10)\n\n      this.logger.debug(`Checking ${drainingRunners.length} draining runners for sandbox migration (offset: ${skip})`)\n\n      if (drainingRunners.length === 0) {\n        await this.redis.set('draining-runner-sandboxes-skip', 0)\n        return\n      }\n\n      await this.redis.set('draining-runner-sandboxes-skip', Number(skip) + drainingRunners.length)\n\n      await Promise.allSettled(\n        drainingRunners.map(async (runner) => {\n          try {\n            const sandboxes = await this.sandboxRepository.find({\n              where: {\n                runnerId: runner.id,\n                state: SandboxState.STOPPED,\n                desiredState: SandboxDesiredState.STOPPED,\n                backupState: BackupState.COMPLETED,\n                backupSnapshot: Not(IsNull()),\n              },\n              take: 100,\n            })\n\n            this.logger.debug(\n              `Found ${sandboxes.length} eligible sandboxes on draining runner ${runner.id} for migration`,\n            )\n\n            await Promise.allSettled(\n              sandboxes.map(async (sandbox) => {\n                const sandboxLockKey = getStateChangeLockKey(sandbox.id)\n                const hasSandboxLock = await this.redisLockProvider.lock(sandboxLockKey, 60)\n                if (!hasSandboxLock) {\n                  return\n                }\n\n                try {\n                  const startScoreThreshold = this.configService.get('runnerScore.thresholds.start') || 0\n                  const targetRunner = await this.runnerService.getRandomAvailableRunner({\n                    snapshotRef: sandbox.backupSnapshot,\n                    excludedRunnerIds: [runner.id],\n                    availabilityScoreThreshold: startScoreThreshold,\n                  })\n\n                  await this.reassignSandbox(sandbox, runner.id, targetRunner.id)\n                } catch (e) {\n                  this.logger.error(`Error migrating sandbox ${sandbox.id} from draining runner ${runner.id}`, e)\n                } finally {\n                  await this.redisLockProvider.unlock(sandboxLockKey)\n                }\n              }),\n            )\n\n            // Archive ERROR sandboxes that have completed backups on this draining runner\n            await this.archiveErroredSandboxesOnDrainingRunner(runner.id)\n\n            // Recover recoverable ERROR sandboxes in-place (expand disk) so they become STOPPED\n            await this.recoverRecoverableSandboxesOnDrainingRunner(runner.id)\n\n            // Retry backups for non-started sandboxes with errored backup state\n            await this.retryErroredBackupsOnDrainingRunner(runner.id)\n          } catch (e) {\n            this.logger.error(`Error processing draining runner ${runner.id} for sandbox migration`, e)\n          }\n        }),\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  private async archiveErroredSandboxesOnDrainingRunner(runnerId: string): Promise<void> {\n    const erroredSandboxes = await this.sandboxRepository.find({\n      where: {\n        runnerId,\n        state: SandboxState.ERROR,\n        recoverable: false,\n        desiredState: Not(In([SandboxDesiredState.DESTROYED, SandboxDesiredState.ARCHIVED])),\n        backupState: BackupState.COMPLETED,\n        backupSnapshot: Not(IsNull()),\n      },\n      take: 100,\n    })\n\n    if (erroredSandboxes.length === 0) {\n      return\n    }\n\n    this.logger.debug(\n      `Found ${erroredSandboxes.length} errored sandboxes with completed backups on draining runner ${runnerId}`,\n    )\n\n    await Promise.allSettled(\n      erroredSandboxes.map(async (sandbox) => {\n        const sandboxLockKey = getStateChangeLockKey(sandbox.id)\n        const acquired = await this.redisLockProvider.lock(sandboxLockKey, 30)\n        if (!acquired) {\n          return\n        }\n\n        try {\n          this.logger.warn(\n            `Setting desired state to ARCHIVED for errored sandbox ${sandbox.id} on draining runner ${runnerId} (previous desired state: ${sandbox.desiredState})`,\n          )\n          const updateData: Partial<Sandbox> = {\n            desiredState: SandboxDesiredState.ARCHIVED,\n          }\n          await this.sandboxRepository.updateWhere(sandbox.id, {\n            updateData,\n            whereCondition: { state: SandboxState.ERROR },\n          })\n        } catch (e) {\n          this.logger.error(\n            `Failed to set desired state to ARCHIVED for errored sandbox ${sandbox.id} on draining runner ${runnerId}`,\n            e,\n          )\n        } finally {\n          await this.redisLockProvider.unlock(sandboxLockKey)\n        }\n      }),\n    )\n  }\n\n  private static readonly DRAINING_BACKUP_RETRY_TTL_SECONDS = 12 * 60 * 60 // 12 hours\n  private static readonly DRAINING_RECOVER_TTL_SECONDS = 12 * 60 * 60 // 12 hours\n\n  private async retryErroredBackupsOnDrainingRunner(runnerId: string): Promise<void> {\n    const erroredSandboxes = await this.sandboxRepository.find({\n      where: [\n        {\n          runnerId,\n          state: SandboxState.STOPPED,\n          recoverable: false,\n          desiredState: SandboxDesiredState.STOPPED,\n          backupState: BackupState.ERROR,\n        },\n        {\n          runnerId,\n          state: SandboxState.ERROR,\n          recoverable: false,\n          backupState: In([BackupState.ERROR, BackupState.NONE]),\n          desiredState: Not(SandboxDesiredState.DESTROYED),\n        },\n      ],\n      take: 100,\n    })\n\n    if (erroredSandboxes.length === 0) {\n      return\n    }\n\n    this.logger.debug(`Found ${erroredSandboxes.length} sandboxes with errored backups on draining runner ${runnerId}`)\n\n    await Promise.allSettled(\n      erroredSandboxes.map(async (sandbox) => {\n        const redisKey = `draining:backup-retry:${sandbox.id}`\n\n        // Check if we've already retried within the last 12 hours\n        const alreadyRetried = await this.redis.exists(redisKey)\n        if (alreadyRetried) {\n          this.logger.debug(\n            `Skipping backup retry for sandbox ${sandbox.id} on draining runner ${runnerId} — already retried within 12 hours`,\n          )\n          return\n        }\n\n        try {\n          await this.backupManager.setBackupPending(sandbox)\n          await this.redis.set(redisKey, '1', 'EX', SandboxManager.DRAINING_BACKUP_RETRY_TTL_SECONDS)\n          this.logger.log(`Retried backup for sandbox ${sandbox.id} on draining runner ${runnerId}`)\n        } catch (e) {\n          this.logger.error(`Failed to retry backup for sandbox ${sandbox.id} on draining runner ${runnerId}`, e)\n        }\n      }),\n    )\n  }\n\n  private async recoverRecoverableSandboxesOnDrainingRunner(runnerId: string): Promise<void> {\n    const recoverableSandboxes = await this.sandboxRepository.find({\n      where: {\n        runnerId,\n        recoverable: true,\n        desiredState: Not(In([SandboxDesiredState.DESTROYED])),\n        backupSnapshot: Not(IsNull()),\n      },\n      take: 100,\n    })\n\n    if (recoverableSandboxes.length === 0) {\n      return\n    }\n\n    this.logger.debug(`Found ${recoverableSandboxes.length} recoverable sandboxes on draining runner ${runnerId}`)\n\n    const runner = await this.runnerService.findOneOrFail(runnerId)\n\n    if (runner.apiVersion === '2') {\n      this.logger.debug(\n        `Skipping recovery for sandboxes on draining runner ${runnerId} — not supported for runner API v2`,\n      )\n      return\n    }\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    await Promise.allSettled(\n      recoverableSandboxes.map(async (sandbox) => {\n        const redisKey = `draining:recover:${sandbox.id}`\n\n        // Check if we've already attempted recovery within the last 12 hours\n        const alreadyAttempted = await this.redis.exists(redisKey)\n        if (alreadyAttempted) {\n          this.logger.debug(\n            `Skipping recovery for sandbox ${sandbox.id} on draining runner ${runnerId} — already attempted within 12 hours`,\n          )\n          return\n        }\n\n        const sandboxLockKey = getStateChangeLockKey(sandbox.id)\n        const acquired = await this.redisLockProvider.lock(sandboxLockKey, 60)\n        if (!acquired) {\n          return\n        }\n\n        try {\n          await runnerAdapter.recoverSandbox(sandbox)\n\n          const updateData: Partial<Sandbox> = {\n            state: SandboxState.STOPPED,\n            desiredState: SandboxDesiredState.STOPPED,\n            errorReason: null,\n            recoverable: false,\n            backupState: BackupState.NONE,\n          }\n\n          await this.sandboxRepository.updateWhere(sandbox.id, {\n            updateData,\n            whereCondition: { pending: false, state: sandbox.state },\n          })\n\n          this.logger.log(`Recovered sandbox ${sandbox.id} on draining runner ${runnerId}`)\n        } catch (e) {\n          await this.redis.set(redisKey, '1', 'EX', SandboxManager.DRAINING_RECOVER_TTL_SECONDS)\n          this.logger.error(`Failed to recover sandbox ${sandbox.id} on draining runner ${runnerId}`, e)\n        } finally {\n          await this.redisLockProvider.unlock(sandboxLockKey)\n        }\n      }),\n    )\n  }\n\n  private async reassignSandbox(sandbox: Sandbox, oldRunnerId: string, newRunnerId: string): Promise<void> {\n    this.logger.debug(\n      `Starting sandbox reassignment for ${sandbox.id} from runner ${oldRunnerId} to runner ${newRunnerId}`,\n    )\n\n    // Safety check: ensure sandbox is not pending\n    if (sandbox.pending) {\n      this.logger.warn(\n        `Sandbox ${sandbox.id} is pending, skipping reassignment from runner ${oldRunnerId} to runner ${newRunnerId}`,\n      )\n      return\n    }\n\n    if (!sandbox.backupRegistryId) {\n      throw new Error(`Sandbox ${sandbox.id} has no backup registry`)\n    }\n\n    const registry = await this.dockerRegistryService.findOne(sandbox.backupRegistryId)\n    if (!registry) {\n      throw new Error(`Registry ${sandbox.backupRegistryId} not found for sandbox ${sandbox.id}`)\n    }\n\n    const organization = await this.organizationService.findOne(sandbox.organizationId)\n\n    const metadata = {\n      ...organization?.sandboxMetadata,\n      sandboxName: sandbox.name,\n    }\n\n    const newRunner = await this.runnerService.findOneOrFail(newRunnerId)\n    const newRunnerAdapter = await this.runnerAdapterFactory.create(newRunner)\n\n    const originalSnapshot = sandbox.snapshot\n    sandbox.snapshot = sandbox.backupSnapshot\n\n    try {\n      // Pass undefined for entrypoint as the backup snapshot already has it baked in and use skipStart\n      await newRunnerAdapter.createSandbox(sandbox, registry, undefined, metadata, undefined, true)\n      this.logger.debug(`Created sandbox ${sandbox.id} on new runner ${newRunnerId} with skipStart`)\n    } catch (e) {\n      // Restore original snapshot on failure\n      sandbox.snapshot = originalSnapshot\n      this.logger.error(`Failed to create sandbox ${sandbox.id} on new runner ${newRunnerId}`, e)\n      throw e\n    }\n\n    // Re-fetch sandbox from DB to get fresh state (the in-memory entity may be stale)\n    const freshSandbox = await this.sandboxRepository.findOne({ where: { id: sandbox.id } })\n    if (!freshSandbox || freshSandbox.pending) {\n      this.logger.warn(\n        `Sandbox ${sandbox.id} is pending or missing, aborting reassignment from runner ${oldRunnerId} to runner ${newRunnerId}`,\n      )\n\n      // Roll back: remove the sandbox from the new runner since we won't complete the migration\n      try {\n        await newRunnerAdapter.destroySandbox(sandbox.id)\n        this.logger.debug(`Rolled back sandbox ${sandbox.id} creation on new runner ${newRunnerId}`)\n      } catch (rollbackErr) {\n        this.logger.error(\n          `Failed to roll back sandbox ${sandbox.id} on new runner ${newRunnerId} after pending check`,\n          rollbackErr,\n        )\n      }\n      return\n    }\n\n    // Update the sandbox to use the new runner; roll back on failure\n    try {\n      const updateData: Partial<Sandbox> = {\n        prevRunnerId: sandbox.runnerId,\n        runnerId: newRunnerId,\n      }\n      await this.sandboxRepository.update(\n        sandbox.id,\n        {\n          updateData,\n        },\n        true,\n      )\n    } catch (e) {\n      this.logger.error(`Failed to update sandbox ${sandbox.id} runnerId to ${newRunnerId}, rolling back`, e)\n\n      // Roll back: remove the sandbox from the new runner\n      try {\n        await newRunnerAdapter.destroySandbox(sandbox.id)\n        this.logger.debug(`Rolled back sandbox ${sandbox.id} creation on new runner ${newRunnerId}`)\n      } catch (rollbackErr) {\n        this.logger.error(\n          `Failed to roll back sandbox ${sandbox.id} on new runner ${newRunnerId} after DB update failure`,\n          rollbackErr,\n        )\n      }\n      throw e\n    }\n\n    this.logger.log(`Migrated sandbox ${sandbox.id} from draining runner ${oldRunnerId} to runner ${newRunnerId}`)\n\n    // Best effort deletion of the sandbox on the old runner\n    try {\n      const oldRunner = await this.runnerService.findOne(oldRunnerId)\n      if (oldRunner) {\n        const oldRunnerAdapter = await this.runnerAdapterFactory.create(oldRunner)\n        await oldRunnerAdapter.destroySandbox(sandbox.id)\n        this.logger.debug(`Deleted sandbox ${sandbox.id} from old runner ${oldRunnerId}`)\n      }\n    } catch (e) {\n      this.logger.warn(`Best effort deletion failed for sandbox ${sandbox.id} on old runner ${oldRunnerId}`, e)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'sync-states' })\n  @TrackJobExecution()\n  @WithInstrumentation()\n  @LogExecution('sync-states')\n  async syncStates(): Promise<void> {\n    const globalLockKey = 'sync-states'\n    const lockTtl = 10 * 60 // seconds (10 min)\n    if (!(await this.redisLockProvider.lock(globalLockKey, lockTtl))) {\n      return\n    }\n\n    try {\n      const queryBuilder = this.sandboxRepository\n        .createQueryBuilder('sandbox')\n        .select(['sandbox.id'])\n        .where('sandbox.state NOT IN (:...excludedStates)', {\n          excludedStates: [\n            SandboxState.DESTROYED,\n            SandboxState.ERROR,\n            SandboxState.BUILD_FAILED,\n            SandboxState.RESIZING,\n          ],\n        })\n        .andWhere('sandbox.\"desiredState\"::text != sandbox.state::text')\n        .andWhere('sandbox.\"desiredState\"::text != :archived', { archived: SandboxDesiredState.ARCHIVED })\n        .orderBy('sandbox.\"lastActivityAt\"', 'DESC')\n\n      const stream = await queryBuilder.stream()\n      let processedCount = 0\n      const maxProcessPerRun = 1000\n      const pendingProcesses: Promise<void>[] = []\n\n      try {\n        await new Promise<void>((resolve, reject) => {\n          stream.on('data', async (row: any) => {\n            if (processedCount >= maxProcessPerRun) {\n              resolve()\n              return\n            }\n\n            const lockKey = getStateChangeLockKey(row.sandbox_id)\n            if (await this.redisLockProvider.isLocked(lockKey)) {\n              // Sandbox is already being processed, skip it\n              return\n            }\n\n            // Process sandbox asynchronously but track the promise\n            const processPromise = this.syncInstanceState(row.sandbox_id)\n            pendingProcesses.push(processPromise)\n            processedCount++\n\n            // Limit concurrent processing to avoid overwhelming the system\n            if (pendingProcesses.length >= 10) {\n              stream.pause()\n              Promise.allSettled(pendingProcesses.splice(0, pendingProcesses.length))\n                .then(() => stream.resume())\n                .catch(reject)\n            }\n          })\n\n          stream.on('end', () => {\n            Promise.all(pendingProcesses)\n              .then(() => {\n                resolve()\n              })\n              .catch(reject)\n          })\n\n          stream.on('error', reject)\n        })\n      } finally {\n        if (!stream.destroyed) {\n          stream.destroy()\n        }\n      }\n    } finally {\n      await this.redisLockProvider.unlock(globalLockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'sync-archived-desired-states' })\n  @TrackJobExecution()\n  @LogExecution('sync-archived-desired-states')\n  @WithInstrumentation()\n  async syncArchivedDesiredStates(): Promise<void> {\n    const lockKey = 'sync-archived-desired-states'\n    if (!(await this.redisLockProvider.lock(lockKey, 30))) {\n      return\n    }\n\n    const sandboxes = await this.sandboxRepository.find({\n      where: {\n        state: In([SandboxState.ARCHIVING, SandboxState.STOPPED, SandboxState.ERROR]),\n        desiredState: SandboxDesiredState.ARCHIVED,\n      },\n      take: 100,\n      order: {\n        updatedAt: 'ASC',\n      },\n    })\n\n    await Promise.all(\n      sandboxes.map(async (sandbox) => {\n        this.syncInstanceState(sandbox.id)\n      }),\n    )\n    await this.redisLockProvider.unlock(lockKey)\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'sync-archived-completed-states' })\n  @TrackJobExecution()\n  @LogExecution('sync-archived-completed-states')\n  async syncArchivedCompletedStates(): Promise<void> {\n    const lockKey = 'sync-archived-completed-states'\n    if (!(await this.redisLockProvider.lock(lockKey, 30))) {\n      return\n    }\n\n    const sandboxes = await this.sandboxRepository.find({\n      where: {\n        state: In([SandboxState.ARCHIVING, SandboxState.STOPPED, SandboxState.ERROR]),\n        desiredState: SandboxDesiredState.ARCHIVED,\n        backupState: BackupState.COMPLETED,\n      },\n      take: 100,\n      order: {\n        updatedAt: 'ASC',\n      },\n    })\n\n    await Promise.allSettled(\n      sandboxes.map(async (sandbox) => {\n        await this.syncInstanceState(sandbox.id)\n      }),\n    )\n    await this.redisLockProvider.unlock(lockKey)\n  }\n\n  /**\n   * Sync the state of a sandbox.\n   *\n   * Loop to handle SYNC_AGAIN without releasing the lock or re-fetching.\n   * The sandbox entity is mutated in-place by repository.update() on each iteration,\n   * and the lock guarantees no concurrent modification.\n   */\n  async syncInstanceState(sandboxId: string): Promise<void> {\n    // Track the start time of the sync operation.\n    const startedAt = new Date()\n\n    // Generate a random lock code to prevent race condition if sandbox action continues after the lock expires.\n    const lockCode = new LockCode(randomUUID())\n\n    // Prevent syncState cron from running multiple instances of the same sandbox.\n    const lockKey = getStateChangeLockKey(sandboxId)\n    const acquired = await this.redisLockProvider.lock(lockKey, 30, lockCode)\n    if (!acquired) {\n      return\n    }\n\n    try {\n      const sandbox = await this.sandboxRepository.findOneOrFail({\n        where: { id: sandboxId },\n      })\n\n      while (new Date().getTime() - startedAt.getTime() <= 10000) {\n        if (\n          [SandboxState.DESTROYED, SandboxState.BUILD_FAILED, SandboxState.RESIZING].includes(sandbox.state) ||\n          (sandbox.state === SandboxState.ERROR && sandbox.desiredState !== SandboxDesiredState.ARCHIVED)\n        ) {\n          // Break sync loop if sandbox reaches a terminal state.\n          // However, should allow ERROR → ARCHIVED transition (e.g., during runner draining).\n          break\n        }\n\n        if (String(sandbox.state) === String(sandbox.desiredState)) {\n          this.logger.warn(\n            `Sandbox ${sandboxId} is already in the desired state ${sandbox.desiredState}, skipping sync`,\n          )\n          // Break sync loop if sandbox is already in the desired state.\n          break\n        }\n\n        // Rely on the sandbox action to return SYNC_AGAIN or DONT_SYNC_AGAIN to continue/break the sync loop.\n        let syncState = DONT_SYNC_AGAIN\n\n        try {\n          switch (sandbox.desiredState) {\n            case SandboxDesiredState.STARTED: {\n              syncState = await this.sandboxStartAction.run(sandbox, lockCode)\n              break\n            }\n            case SandboxDesiredState.STOPPED: {\n              syncState = await this.sandboxStopAction.run(sandbox, lockCode)\n              break\n            }\n            case SandboxDesiredState.DESTROYED: {\n              syncState = await this.sandboxDestroyAction.run(sandbox, lockCode)\n              break\n            }\n            case SandboxDesiredState.ARCHIVED: {\n              syncState = await this.sandboxArchiveAction.run(sandbox, lockCode)\n              break\n            }\n          }\n        } catch (error) {\n          this.logger.error(`Error processing desired state for sandbox ${sandboxId}:`, error)\n\n          const { recoverable, errorReason } = sanitizeSandboxError(error)\n\n          const updateData: Partial<Sandbox> = {\n            state: SandboxState.ERROR,\n            errorReason,\n            recoverable,\n          }\n\n          await this.sandboxRepository.update(sandboxId, { updateData, entity: sandbox })\n\n          // Break sync loop since sandbox is in error state.\n          break\n        }\n\n        // Do not sync again for v2 runners\n        // Job completion will update the sandbox state\n        if (sandbox.runnerId && (await this.runnerService.getRunnerApiVersion(sandbox.runnerId)) === '2') {\n          break\n        }\n\n        // Break sync loop if sandbox action returned DONT_SYNC_AGAIN.\n        if (syncState !== SYNC_AGAIN) {\n          break\n        }\n      }\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @OnAsyncEvent({\n    event: SandboxEvents.ARCHIVED,\n  })\n  @TrackJobExecution()\n  @WithSpan()\n  private async handleSandboxArchivedEvent(event: SandboxArchivedEvent) {\n    await this.syncInstanceState(event.sandbox.id)\n  }\n\n  @OnAsyncEvent({\n    event: SandboxEvents.DESTROYED,\n  })\n  @TrackJobExecution()\n  @WithSpan()\n  private async handleSandboxDestroyedEvent(event: SandboxDestroyedEvent) {\n    await this.syncInstanceState(event.sandbox.id)\n  }\n\n  @OnAsyncEvent({\n    event: SandboxEvents.STARTED,\n  })\n  @TrackJobExecution()\n  @WithSpan()\n  private async handleSandboxStartedEvent(event: SandboxStartedEvent) {\n    await this.syncInstanceState(event.sandbox.id)\n  }\n\n  @OnAsyncEvent({\n    event: SandboxEvents.STOPPED,\n  })\n  @TrackJobExecution()\n  @WithSpan()\n  private async handleSandboxStoppedEvent(event: SandboxStoppedEvent) {\n    await this.syncInstanceState(event.sandbox.id)\n  }\n\n  @OnAsyncEvent({\n    event: SandboxEvents.CREATED,\n  })\n  @TrackJobExecution()\n  @WithSpan()\n  private async handleSandboxCreatedEvent(event: SandboxCreatedEvent) {\n    await this.syncInstanceState(event.sandbox.id)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/snapshot.manager.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, NotFoundException, OnApplicationShutdown } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { In, IsNull, LessThan, Not, Repository } from 'typeorm'\nimport { DockerRegistryService } from '../../docker-registry/services/docker-registry.service'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\nimport { SnapshotRunner } from '../entities/snapshot-runner.entity'\nimport { Runner } from '../entities/runner.entity'\nimport { DockerRegistry } from '../../docker-registry/entities/docker-registry.entity'\nimport { RunnerState } from '../enums/runner-state.enum'\nimport { SnapshotRunnerState } from '../enums/snapshot-runner-state.enum'\nimport { v4 as uuidv4 } from 'uuid'\nimport { RunnerNotReadyError } from '../errors/runner-not-ready.error'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { OrganizationService } from '../../organization/services/organization.service'\nimport { BuildInfo } from '../entities/build-info.entity'\nimport { fromAxiosError } from '../../common/utils/from-axios-error'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { RunnerService } from '../services/runner.service'\nimport { TrackableJobExecutions } from '../../common/interfaces/trackable-job-executions'\nimport { TrackJobExecution } from '../../common/decorators/track-job-execution.decorator'\nimport { setTimeout as sleep } from 'timers/promises'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\nimport { RunnerAdapterFactory } from '../runner-adapter/runnerAdapter'\nimport { SnapshotStateError } from '../errors/snapshot-state-error'\nimport { SnapshotEvents } from '../constants/snapshot-events'\nimport { SnapshotCreatedEvent } from '../events/snapshot-created.event'\nimport { SnapshotService } from '../services/snapshot.service'\nimport { OnAsyncEvent } from '../../common/decorators/on-async-event.decorator'\nimport { parseDockerImage } from '../../common/utils/docker-image.util'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport { SnapshotInfoResponse } from '@daytonaio/runner-api-client'\nimport { SnapshotActivatedEvent } from '../events/snapshot-activated.event'\n\nconst SYNC_AGAIN = 'sync-again'\nconst DONT_SYNC_AGAIN = 'dont-sync-again'\nconst DEFAULT_SNAPSHOT_DEACTIVATION_TIMEOUT_MINUTES = 14 * 24 * 60 // 14 days\ntype SyncState = typeof SYNC_AGAIN | typeof DONT_SYNC_AGAIN\n\n@Injectable()\nexport class SnapshotManager implements TrackableJobExecutions, OnApplicationShutdown {\n  activeJobs = new Set<string>()\n\n  private readonly logger = new Logger(SnapshotManager.name)\n  //  generate a unique instance id used to ensure only one instance of the worker is handing the\n  //  snapshot activation\n  private readonly instanceId = uuidv4()\n\n  constructor(\n    @InjectRedis() private readonly redis: Redis,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    @InjectRepository(SnapshotRunner)\n    private readonly snapshotRunnerRepository: Repository<SnapshotRunner>,\n    @InjectRepository(Runner)\n    private readonly runnerRepository: Repository<Runner>,\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(BuildInfo)\n    private readonly buildInfoRepository: Repository<BuildInfo>,\n    private readonly runnerService: RunnerService,\n    private readonly dockerRegistryService: DockerRegistryService,\n    private readonly runnerAdapterFactory: RunnerAdapterFactory,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly organizationService: OrganizationService,\n    private readonly snapshotService: SnapshotService,\n  ) {}\n\n  async onApplicationShutdown() {\n    //  wait for all active jobs to finish\n    while (this.activeJobs.size > 0) {\n      this.logger.log(`Waiting for ${this.activeJobs.size} active jobs to finish`)\n      await sleep(1000)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_5_SECONDS, { name: 'sync-runner-snapshots', waitForCompletion: true })\n  @TrackJobExecution()\n  @LogExecution('sync-runner-snapshots')\n  @WithInstrumentation()\n  async syncRunnerSnapshots() {\n    const lockKey = 'sync-runner-snapshots-lock'\n    const lockTtl = 10 * 60 // seconds (10 min)\n    if (!(await this.redisLockProvider.lock(lockKey, lockTtl))) {\n      return\n    }\n\n    const skip = (await this.redis.get('sync-runner-snapshots-skip')) || 0\n\n    const snapshots = await this.snapshotRepository\n      .createQueryBuilder('snapshot')\n      .innerJoin('organization', 'org', 'org.id = snapshot.organizationId')\n      .where('snapshot.state = :snapshotState', { snapshotState: SnapshotState.ACTIVE })\n      .andWhere('org.suspended = false')\n      .orderBy('snapshot.createdAt', 'ASC')\n      .take(100)\n      .skip(Number(skip))\n      .getMany()\n\n    if (snapshots.length === 0) {\n      await this.redisLockProvider.unlock(lockKey)\n      await this.redis.set('sync-runner-snapshots-skip', 0)\n      return\n    }\n\n    await this.redis.set('sync-runner-snapshots-skip', Number(skip) + snapshots.length)\n\n    const results = await Promise.allSettled(\n      snapshots.map(async (snapshot) => {\n        const regions = await this.snapshotService.getSnapshotRegions(snapshot.id)\n\n        const sharedRegionIds = regions.filter((r) => r.organizationId === null).map((r) => r.id)\n        const organizationRegionIds = regions\n          .filter((r) => r.organizationId === snapshot.organizationId)\n          .map((r) => r.id)\n\n        return this.propagateSnapshotToRunners(snapshot, sharedRegionIds, organizationRegionIds)\n      }),\n    )\n\n    // Log all promise errors\n    results.forEach((result) => {\n      if (result.status === 'rejected') {\n        this.logger.error(`Error propagating snapshot to runners: ${fromAxiosError(result.reason)}`)\n      }\n    })\n\n    await this.redisLockProvider.unlock(lockKey)\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'sync-runner-snapshot-states', waitForCompletion: true })\n  @TrackJobExecution()\n  @LogExecution('sync-runner-snapshot-states')\n  @WithInstrumentation()\n  async syncRunnerSnapshotStates() {\n    //  this approach is not ideal, as if the number of runners is large, this will take a long time\n    //  also, if some snapshots stuck in a \"pulling\" state, they will infest the queue\n    //  todo: find a better approach\n\n    const lockKey = 'sync-runner-snapshot-states-lock'\n    if (!(await this.redisLockProvider.lock(lockKey, 30))) {\n      return\n    }\n\n    const runnerSnapshots = await this.snapshotRunnerRepository\n      .createQueryBuilder('snapshotRunner')\n      .where({\n        state: In([\n          SnapshotRunnerState.PULLING_SNAPSHOT,\n          SnapshotRunnerState.BUILDING_SNAPSHOT,\n          SnapshotRunnerState.REMOVING,\n        ]),\n      })\n      .orderBy('RANDOM()')\n      .take(100)\n      .getMany()\n\n    await Promise.allSettled(\n      runnerSnapshots.map((snapshotRunner) => {\n        return this.syncRunnerSnapshotState(snapshotRunner).catch((err) => {\n          if (err.code !== 'ECONNRESET') {\n            if (err instanceof RunnerNotReadyError) {\n              this.logger.debug(\n                `Runner ${snapshotRunner.runnerId} is not ready while trying to sync snapshot runner ${snapshotRunner.id}: ${err}`,\n              )\n              return\n            }\n            this.logger.error(`Error syncing runner snapshot state ${snapshotRunner.id}: ${fromAxiosError(err)}`)\n            this.snapshotRunnerRepository.update(snapshotRunner.id, {\n              state: SnapshotRunnerState.ERROR,\n              errorReason: fromAxiosError(err).message,\n            })\n          }\n        })\n      }),\n    )\n\n    await this.redisLockProvider.unlock(lockKey)\n  }\n\n  async syncRunnerSnapshotState(snapshotRunner: SnapshotRunner): Promise<void> {\n    const runner = await this.runnerService.findOne(snapshotRunner.runnerId)\n    if (!runner) {\n      //  cleanup the snapshot runner record if the runner is not found\n      //  this can happen if the runner is deleted from the database without cleaning up the snapshot runners\n      await this.snapshotRunnerRepository.delete(snapshotRunner.id)\n      this.logger.warn(\n        `Runner ${snapshotRunner.runnerId} not found while trying to process snapshot runner ${snapshotRunner.id}. Snapshot runner has been removed.`,\n      )\n      return\n    }\n\n    if (runner.state !== RunnerState.READY) {\n      //  todo: handle timeout policy\n      //  for now just remove the snapshot runner record if the runner is not ready\n      await this.snapshotRunnerRepository.delete(snapshotRunner.id)\n\n      throw new RunnerNotReadyError(`Runner ${runner.id} is not ready`)\n    }\n\n    switch (snapshotRunner.state) {\n      case SnapshotRunnerState.PULLING_SNAPSHOT:\n        await this.handleSnapshotRunnerStatePullingSnapshot(snapshotRunner, runner)\n        break\n      case SnapshotRunnerState.BUILDING_SNAPSHOT:\n        await this.handleSnapshotRunnerStateBuildingSnapshot(snapshotRunner, runner)\n        break\n      case SnapshotRunnerState.REMOVING:\n        await this.handleSnapshotRunnerStateRemoving(snapshotRunner, runner)\n        break\n    }\n  }\n\n  async propagateSnapshotToRunners(snapshot: Snapshot, sharedRegionIds: string[], organizationRegionIds: string[]) {\n    //  todo: remove try catch block and implement error handling\n    try {\n      //  get all runners in the regions to propagate to\n      const runners = await this.runnerRepository.find({\n        where: {\n          state: RunnerState.READY,\n          unschedulable: Not(true),\n          region: In([...sharedRegionIds, ...organizationRegionIds]),\n        },\n      })\n\n      const sharedRunners = runners.filter((runner) => sharedRegionIds.includes(runner.region))\n      const sharedRunnerIds = sharedRunners.map((runner) => runner.id)\n\n      const organizationRunners = runners.filter((runner) => organizationRegionIds.includes(runner.region))\n      const organizationRunnerIds = organizationRunners.map((runner) => runner.id)\n\n      //  get all runners where the snapshot is already propagated to (or in progress)\n      const sharedSnapshotRunners = await this.snapshotRunnerRepository.find({\n        where: {\n          snapshotRef: snapshot.ref,\n          state: In([SnapshotRunnerState.READY, SnapshotRunnerState.PULLING_SNAPSHOT]),\n          runnerId: In(sharedRunnerIds),\n        },\n      })\n      const sharedSnapshotRunnersDistinctRunnersIds = new Set(\n        sharedSnapshotRunners.map((snapshotRunner) => snapshotRunner.runnerId),\n      )\n\n      const organizationSnapshotRunners = await this.snapshotRunnerRepository.find({\n        where: {\n          snapshotRef: snapshot.ref,\n          state: In([SnapshotRunnerState.READY, SnapshotRunnerState.PULLING_SNAPSHOT]),\n          runnerId: In(organizationRunnerIds),\n        },\n      })\n      const organizationSnapshotRunnersDistinctRunnersIds = new Set(\n        organizationSnapshotRunners.map((snapshotRunner) => snapshotRunner.runnerId),\n      )\n\n      //  get all runners where the snapshot is not propagated to\n      const unallocatedSharedRunners = sharedRunners.filter(\n        (runner) => !sharedSnapshotRunnersDistinctRunnersIds.has(runner.id),\n      )\n      const unallocatedOrganizationRunners = organizationRunners.filter(\n        (runner) => !organizationSnapshotRunnersDistinctRunnersIds.has(runner.id),\n      )\n\n      const runnersToPropagateTo: Runner[] = []\n\n      // propagate the snapshot to all organization runners\n      runnersToPropagateTo.push(...unallocatedOrganizationRunners)\n\n      // respect the propagation limit for shared runners\n      const sharedRunnersPropagateLimit = Math.max(\n        0,\n        Math.ceil(sharedRunners.length / 3) - sharedSnapshotRunnersDistinctRunnersIds.size,\n      )\n      runnersToPropagateTo.push(\n        ...unallocatedSharedRunners.sort(() => Math.random() - 0.5).slice(0, sharedRunnersPropagateLimit),\n      )\n\n      if (runnersToPropagateTo.length === 0) {\n        return\n      }\n\n      // regionId -> registry\n      const internalRegistriesMap = new Map<string, DockerRegistry>()\n\n      for (const regionId of [...sharedRegionIds, ...organizationRegionIds]) {\n        const registry = await this.dockerRegistryService.findInternalRegistryBySnapshotRef(snapshot.ref, regionId)\n        if (registry) {\n          internalRegistriesMap.set(regionId, registry)\n        }\n      }\n\n      const results = await Promise.allSettled(\n        runnersToPropagateTo.map(async (runner) => {\n          const internalRegistry = internalRegistriesMap.get(runner.region)\n          if (!internalRegistry) {\n            throw new Error(`No internal registry found for snapshot ${snapshot.ref} in region ${runner.region}`)\n          }\n\n          const snapshotRunner = await this.runnerService.getSnapshotRunner(runner.id, snapshot.ref)\n\n          try {\n            if (!snapshotRunner) {\n              await this.runnerService.createSnapshotRunnerEntry(\n                runner.id,\n                snapshot.ref,\n                SnapshotRunnerState.PULLING_SNAPSHOT,\n              )\n              await this.pullSnapshotRunner(runner, snapshot.ref, internalRegistry)\n            } else if (snapshotRunner.state === SnapshotRunnerState.PULLING_SNAPSHOT) {\n              await this.handleSnapshotRunnerStatePullingSnapshot(snapshotRunner, runner)\n            }\n          } catch (err) {\n            this.logger.error(`Error propagating snapshot to runner ${runner.id}: ${fromAxiosError(err)}`)\n            snapshotRunner.state = SnapshotRunnerState.ERROR\n            snapshotRunner.errorReason = err.message\n            await this.snapshotRunnerRepository.update(snapshotRunner.id, snapshotRunner)\n          }\n        }),\n      )\n\n      results.forEach((result) => {\n        if (result.status === 'rejected') {\n          this.logger.error(result.reason)\n        }\n      })\n    } catch (err) {\n      this.logger.error(err)\n    }\n  }\n\n  async pullSnapshotRunner(\n    runner: Runner,\n    snapshotRef: string,\n    registry?: DockerRegistry,\n    destinationRegistry?: DockerRegistry,\n    destinationRef?: string,\n  ) {\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n    // Runner returns immediately; polling for completion is handled by syncRunnerSnapshotStates cron\n    await runnerAdapter.pullSnapshot(snapshotRef, registry, destinationRegistry, destinationRef)\n  }\n\n  async handleSnapshotRunnerStatePullingSnapshot(snapshotRunner: SnapshotRunner, runner: Runner) {\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n    try {\n      await runnerAdapter.getSnapshotInfo(snapshotRunner.snapshotRef)\n      snapshotRunner.state = SnapshotRunnerState.READY\n      await this.snapshotRunnerRepository.save(snapshotRunner)\n      return\n    } catch (err) {\n      if (err instanceof SnapshotStateError) {\n        snapshotRunner.state = SnapshotRunnerState.ERROR\n        snapshotRunner.errorReason = err.errorReason\n        await this.snapshotRunnerRepository.save(snapshotRunner)\n        return\n      }\n    }\n\n    const timeoutMinutes = 60\n    const timeoutMs = timeoutMinutes * 60 * 1000\n    if (Date.now() - snapshotRunner.updatedAt.getTime() > timeoutMs) {\n      snapshotRunner.state = SnapshotRunnerState.ERROR\n      snapshotRunner.errorReason = 'Timeout while pulling snapshot to runner'\n      await this.snapshotRunnerRepository.save(snapshotRunner)\n      return\n    }\n\n    const retryTimeoutMinutes = 10\n    const retryTimeoutMs = retryTimeoutMinutes * 60 * 1000\n    if (Date.now() - snapshotRunner.createdAt.getTime() > retryTimeoutMs) {\n      const internalRegistry = await this.dockerRegistryService.findInternalRegistryBySnapshotRef(\n        snapshotRunner.snapshotRef,\n        runner.region,\n      )\n      if (!internalRegistry) {\n        throw new Error(\n          `No internal registry found for snapshot ${snapshotRunner.snapshotRef} in region ${runner.region}`,\n        )\n      }\n      await this.pullSnapshotRunner(runner, snapshotRunner.snapshotRef, internalRegistry)\n      return\n    }\n  }\n\n  async handleSnapshotRunnerStateBuildingSnapshot(snapshotRunner: SnapshotRunner, runner: Runner) {\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n    try {\n      await runnerAdapter.getSnapshotInfo(snapshotRunner.snapshotRef)\n      snapshotRunner.state = SnapshotRunnerState.READY\n      await this.snapshotRunnerRepository.save(snapshotRunner)\n      return\n    } catch (err) {\n      if (err instanceof SnapshotStateError) {\n        snapshotRunner.state = SnapshotRunnerState.ERROR\n        snapshotRunner.errorReason = err.errorReason\n        await this.snapshotRunnerRepository.save(snapshotRunner)\n        return\n      }\n    }\n  }\n\n  // Pulls stopped sandboxes' backup snapshots to another runner to prepare for reassignment during draining\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'migrate-draining-runner-snapshots', waitForCompletion: true })\n  @TrackJobExecution()\n  @LogExecution('migrate-draining-runner-snapshots')\n  @WithInstrumentation()\n  private async handleMigrateDrainingRunnerSnapshots() {\n    const lockKey = 'migrate-draining-runner-snapshots'\n    const hasLock = await this.redisLockProvider.lock(lockKey, 60)\n    if (!hasLock) {\n      return\n    }\n\n    try {\n      const drainingRunners = await this.runnerRepository.find({\n        where: {\n          draining: true,\n          state: RunnerState.READY,\n        },\n      })\n\n      this.logger.debug(`Checking ${drainingRunners.length} draining runners for snapshot migration`)\n\n      await Promise.allSettled(\n        drainingRunners.map(async (runner) => {\n          try {\n            const sandboxes = await this.sandboxRepository.find({\n              where: {\n                runnerId: runner.id,\n                state: SandboxState.STOPPED,\n                desiredState: SandboxDesiredState.STOPPED,\n                backupState: BackupState.COMPLETED,\n                backupSnapshot: Not(IsNull()),\n              },\n              take: 100,\n            })\n\n            this.logger.debug(\n              `Found ${sandboxes.length} eligible sandboxes on draining runner ${runner.id} for snapshot migration`,\n            )\n\n            await Promise.allSettled(\n              sandboxes.map(async (sandbox) => {\n                const sandboxLockKey = `draining-runner-snapshot-migration:${sandbox.id}`\n                const hasSandboxLock = await this.redisLockProvider.lock(sandboxLockKey, 3600)\n                if (!hasSandboxLock) {\n                  return\n                }\n\n                try {\n                  // Get an available runner in the same region with the same class\n                  const targetRunner = await this.runnerService.getRandomAvailableRunner({\n                    regions: [sandbox.region],\n                    sandboxClass: sandbox.class,\n                    excludedRunnerIds: [runner.id],\n                  })\n\n                  // Check if snapshot runner entry already exists\n                  const existingEntry = await this.runnerService.getSnapshotRunner(\n                    targetRunner.id,\n                    sandbox.backupSnapshot,\n                  )\n                  if (existingEntry) {\n                    if (existingEntry.state === SnapshotRunnerState.ERROR) {\n                      // Clean up the failed entry so we can retry\n                      this.logger.warn(\n                        `Removing ERROR snapshot runner entry ${existingEntry.id} for runner ${targetRunner.id} and snapshot ${sandbox.backupSnapshot} to allow retry`,\n                      )\n                      await this.snapshotRunnerRepository.delete(existingEntry.id)\n                    } else {\n                      this.logger.debug(\n                        `Snapshot runner entry already exists for runner ${targetRunner.id} and snapshot ${sandbox.backupSnapshot} (state: ${existingEntry.state})`,\n                      )\n                      // Do not unlock to avoid duplicates\n                      return\n                    }\n                  }\n\n                  // Find the backup registry to use as source for the pull\n                  const registry = sandbox.backupRegistryId\n                    ? await this.dockerRegistryService.findOne(sandbox.backupRegistryId)\n                    : await this.dockerRegistryService.findInternalRegistryBySnapshotRef(\n                        sandbox.backupSnapshot,\n                        targetRunner.region,\n                      )\n\n                  if (!registry) {\n                    this.logger.warn(\n                      `No registry found for backup snapshot ${sandbox.backupSnapshot} of sandbox ${sandbox.id}`,\n                    )\n                    await this.redisLockProvider.unlock(sandboxLockKey)\n                    return\n                  }\n\n                  // Create snapshot runner entry on the target runner\n                  await this.runnerService.createSnapshotRunnerEntry(\n                    targetRunner.id,\n                    sandbox.backupSnapshot,\n                    SnapshotRunnerState.PULLING_SNAPSHOT,\n                  )\n                  await this.pullSnapshotRunner(targetRunner, sandbox.backupSnapshot, registry)\n\n                  this.logger.log(\n                    `Created snapshot runner entry for sandbox ${sandbox.id} backup ${sandbox.backupSnapshot} on runner ${targetRunner.id} (migrating from draining runner ${runner.id})`,\n                  )\n                  await this.redisLockProvider.unlock(sandboxLockKey)\n                } catch (e) {\n                  if (e instanceof BadRequestError && e.message === 'No available runners') {\n                    this.logger.warn(\n                      `No available runners found in region ${sandbox.region} for sandbox ${sandbox.id} snapshot migration`,\n                    )\n                  } else {\n                    this.logger.error(`Error migrating snapshot for sandbox ${sandbox.id}`, e)\n                  }\n                  await this.redisLockProvider.unlock(sandboxLockKey)\n                }\n              }),\n            )\n          } catch (e) {\n            this.logger.error(`Error processing draining runner ${runner.id} for snapshot migration`, e)\n          }\n        }),\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'check-snapshot-cleanup' })\n  @TrackJobExecution()\n  @LogExecution('check-snapshot-cleanup')\n  @WithInstrumentation()\n  async checkSnapshotCleanup() {\n    const lockKey = 'check-snapshot-cleanup-lock'\n    if (!(await this.redisLockProvider.lock(lockKey, 30))) {\n      return\n    }\n\n    const snapshots = await this.snapshotRepository.find({\n      where: {\n        state: SnapshotState.REMOVING,\n      },\n    })\n\n    await Promise.all(\n      snapshots.map(async (snapshot) => {\n        const countActiveSnapshots = await this.snapshotRepository.count({\n          where: {\n            state: SnapshotState.ACTIVE,\n            ref: snapshot.ref,\n          },\n        })\n\n        // Only remove snapshot runners if no other snapshots depend on them\n        if (countActiveSnapshots === 0) {\n          await this.snapshotRunnerRepository.update(\n            {\n              snapshotRef: snapshot.ref,\n            },\n            {\n              state: SnapshotRunnerState.REMOVING,\n            },\n          )\n        }\n\n        await this.snapshotRepository.remove(snapshot)\n      }),\n    )\n\n    await this.redisLockProvider.unlock(lockKey)\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'check-snapshot-state' })\n  @TrackJobExecution()\n  @LogExecution('check-snapshot-state')\n  @WithInstrumentation()\n  async checkSnapshotState() {\n    //  the first time the snapshot is created it needs to be pushed to the internal registry\n    //  before propagating to the runners\n    //  this cron job will process the snapshot states until the snapshot is active (or error)\n\n    //  get all snapshots\n    const snapshots = await this.snapshotRepository.find({\n      where: {\n        state: Not(In([SnapshotState.ACTIVE, SnapshotState.ERROR, SnapshotState.BUILD_FAILED, SnapshotState.INACTIVE])),\n      },\n    })\n\n    await Promise.all(\n      snapshots.map(async (snapshot) => {\n        this.syncSnapshotState(snapshot.id)\n      }),\n    )\n  }\n\n  async syncSnapshotState(snapshotId: string): Promise<void> {\n    const lockKey = `sync-snapshot-state-${snapshotId}`\n    if (!(await this.redisLockProvider.lock(lockKey, 720))) {\n      return\n    }\n\n    const snapshot = await this.snapshotRepository.findOne({\n      where: { id: snapshotId },\n    })\n\n    if (\n      !snapshot ||\n      [SnapshotState.ACTIVE, SnapshotState.ERROR, SnapshotState.BUILD_FAILED, SnapshotState.INACTIVE].includes(\n        snapshot.state,\n      )\n    ) {\n      await this.redisLockProvider.unlock(lockKey)\n      return\n    }\n\n    let syncState = DONT_SYNC_AGAIN\n\n    try {\n      switch (snapshot.state) {\n        case SnapshotState.PENDING:\n          syncState = await this.handleSnapshotStatePending(snapshot)\n          break\n        case SnapshotState.PULLING:\n        case SnapshotState.BUILDING:\n          syncState = await this.handleCheckInitialRunnerSnapshot(snapshot)\n          break\n        case SnapshotState.REMOVING:\n          syncState = await this.handleSnapshotStateRemoving(snapshot)\n          break\n      }\n    } catch (error) {\n      if (error.code === 'ECONNRESET') {\n        syncState = SYNC_AGAIN\n      } else {\n        const message = error.message || String(error)\n        await this.updateSnapshotState(snapshot.id, SnapshotState.ERROR, message)\n      }\n    }\n\n    await this.redisLockProvider.unlock(lockKey)\n    if (syncState === SYNC_AGAIN) {\n      this.syncSnapshotState(snapshotId)\n    }\n  }\n\n  async handleSnapshotRunnerStateRemoving(snapshotRunner: SnapshotRunner, runner: Runner) {\n    if (!runner) {\n      //  generally this should not happen\n      //  in case the runner has been deleted from the database, delete the snapshot runner record\n      const errorMessage = `Runner not found while trying to remove snapshot ${snapshotRunner.snapshotRef} from runner ${snapshotRunner.runnerId}`\n      this.logger.warn(errorMessage)\n\n      this.snapshotRunnerRepository.delete(snapshotRunner.id).catch((err) => {\n        this.logger.error(fromAxiosError(err))\n      })\n      return\n    }\n    if (!snapshotRunner.snapshotRef) {\n      //  this should never happen\n      //  remove the snapshot runner record (it will be recreated again by the snapshot propagation job)\n      this.logger.warn(`Internal snapshot name not found for snapshot runner ${snapshotRunner.id}`)\n      this.snapshotRunnerRepository.delete(snapshotRunner.id).catch((err) => {\n        this.logger.error(fromAxiosError(err))\n      })\n      return\n    }\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n    const exists = await runnerAdapter.snapshotExists(snapshotRunner.snapshotRef)\n    if (!exists) {\n      await this.snapshotRunnerRepository.delete(snapshotRunner.id)\n    } else {\n      //  just in case the snapshot is still there\n      runnerAdapter.removeSnapshot(snapshotRunner.snapshotRef).catch((err) => {\n        //  this should not happen, and is not critical\n        //  if the runner can not remove the snapshot, just delete the snapshot runner record\n        this.snapshotRunnerRepository.delete(snapshotRunner.id).catch((err) => {\n          this.logger.error(fromAxiosError(err))\n        })\n        //  and log the error for tracking\n        const errorMessage = `Failed to do just in case remove snapshot ${snapshotRunner.snapshotRef} from runner ${runner.id}: ${fromAxiosError(err)}`\n        this.logger.warn(errorMessage)\n      })\n    }\n  }\n\n  async handleSnapshotStateRemoving(snapshot: Snapshot): Promise<SyncState> {\n    const snapshotRunnerItems = await this.snapshotRunnerRepository.find({\n      where: {\n        snapshotRef: snapshot.ref,\n      },\n    })\n\n    if (snapshotRunnerItems.length === 0) {\n      await this.snapshotRepository.remove(snapshot)\n    }\n\n    return DONT_SYNC_AGAIN\n  }\n\n  async handleCheckInitialRunnerSnapshot(snapshot: Snapshot): Promise<SyncState> {\n    // Check for timeout - allow up to 30 minutes\n    const timeoutMinutes = 30\n    const timeoutMs = timeoutMinutes * 60 * 1000\n    if (Date.now() - snapshot.updatedAt.getTime() > timeoutMs) {\n      await this.updateSnapshotState(snapshot.id, SnapshotState.ERROR, 'Timeout processing snapshot on initial runner')\n      return DONT_SYNC_AGAIN\n    }\n\n    // Check if the snapshot ref is already set and it is already on the runner\n    const snapshotRunner = await this.snapshotRunnerRepository.findOne({\n      where: {\n        snapshotRef: snapshot.ref,\n        runnerId: snapshot.initialRunnerId,\n      },\n    })\n\n    if (snapshot.ref && snapshotRunner) {\n      if (snapshotRunner.state === SnapshotRunnerState.READY) {\n        await this.updateSnapshotState(snapshot.id, SnapshotState.ACTIVE)\n        return DONT_SYNC_AGAIN\n      } else if (snapshotRunner.state === SnapshotRunnerState.ERROR) {\n        await this.snapshotRunnerRepository.delete(snapshotRunner.id)\n      }\n    }\n\n    const runner = await this.runnerService.findOneOrFail(snapshot.initialRunnerId)\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    const initialImageRefOnRunner = snapshot.buildInfo ? snapshot.buildInfo.snapshotRef : snapshot.ref\n\n    let snapshotInfoResponse: SnapshotInfoResponse\n    try {\n      snapshotInfoResponse = await runnerAdapter.getSnapshotInfo(initialImageRefOnRunner)\n    } catch (error) {\n      if (error instanceof SnapshotStateError) {\n        throw error\n      } else {\n        return DONT_SYNC_AGAIN\n      }\n    }\n\n    const internalRegistry = await this.dockerRegistryService.getAvailableInternalRegistry(runner.region)\n    if (!internalRegistry) {\n      throw new Error('No internal registry found for snapshot')\n    }\n\n    await this.processSnapshotDigest(\n      snapshot,\n      internalRegistry,\n      snapshotInfoResponse.hash,\n      snapshotInfoResponse.sizeGB,\n      snapshotInfoResponse.entrypoint,\n    )\n\n    try {\n      await runnerAdapter.inspectSnapshotInRegistry(snapshot.ref, internalRegistry)\n    } catch (error) {\n      this.logger.error(`Failed to inspect snapshot ${snapshot.ref} in registry: ${error}`)\n      await this.snapshotRepository.save(snapshot)\n      return DONT_SYNC_AGAIN\n    }\n\n    try {\n      await runnerAdapter.removeSnapshot(initialImageRefOnRunner)\n    } catch (error) {\n      this.logger.error(`Failed to remove snapshot ${snapshot.imageName}: ${fromAxiosError(error)}`)\n    }\n\n    // For pull snapshots, best effort cleanup the original image now that we've computed the ref from it\n    // Only cleanup if there's no other snapshot in processing state using the same image\n    if (!snapshot.buildInfo) {\n      try {\n        const anotherSnapshot = await this.snapshotRepository.findOne({\n          where: {\n            imageName: snapshot.imageName,\n            id: Not(snapshot.id),\n            state: Not(In([SnapshotState.ACTIVE, SnapshotState.INACTIVE])),\n          },\n        })\n        if (!anotherSnapshot) {\n          await runnerAdapter.removeSnapshot(snapshot.imageName)\n        }\n      } catch (err) {\n        this.logger.error(`Failed to cleanup original image ${snapshot.imageName}: ${fromAxiosError(err)}`)\n      }\n    }\n\n    if (snapshotRunner) {\n      snapshotRunner.state = SnapshotRunnerState.READY\n      await this.snapshotRunnerRepository.save(snapshotRunner)\n    } else {\n      await this.runnerService.createSnapshotRunnerEntry(runner.id, snapshot.ref, SnapshotRunnerState.READY)\n    }\n    await this.updateSnapshotState(snapshot.id, SnapshotState.ACTIVE)\n\n    // Best effort removal of old snapshot from transient registry\n    const transientRegistry = await this.dockerRegistryService.findTransientRegistryBySnapshotImageName(\n      snapshot.imageName,\n      runner.region,\n    )\n    if (transientRegistry) {\n      try {\n        await this.dockerRegistryService.removeImage(snapshot.imageName, transientRegistry.id)\n      } catch (error) {\n        if (error.statusCode === 404) {\n          //  image not found, just return\n          return DONT_SYNC_AGAIN\n        }\n        this.logger.error('Failed to remove transient image:', fromAxiosError(error))\n      }\n    }\n\n    return DONT_SYNC_AGAIN\n  }\n\n  async processPullOnInitialRunner(snapshot: Snapshot, runner: Runner) {\n    // Check for timeout - allow up to 30 minutes\n    const timeoutMinutes = 30\n    const timeoutMs = timeoutMinutes * 60 * 1000\n    if (Date.now() - snapshot.updatedAt.getTime() > timeoutMs) {\n      await this.updateSnapshotState(\n        snapshot.id,\n        SnapshotState.ERROR,\n        'Timeout processing snapshot pull on initial runner',\n      )\n      return DONT_SYNC_AGAIN\n    }\n\n    let sourceRegistry = await this.dockerRegistryService.findSourceRegistryBySnapshotImageName(\n      snapshot.imageName,\n      runner.region,\n      snapshot.organizationId,\n    )\n    if (!sourceRegistry) {\n      sourceRegistry = await this.dockerRegistryService.getDefaultDockerHubRegistry()\n    }\n    const destinationRegistry = await this.dockerRegistryService.getAvailableInternalRegistry(runner.region)\n\n    // Fire pull request (runner returns 202 immediately)\n    // Post-processing (digest, cleanup) is handled by handleCheckInitialRunnerSnapshot on the next poll cycle\n    try {\n      await this.pullSnapshotRunner(\n        runner,\n        snapshot.imageName,\n        sourceRegistry,\n        destinationRegistry ?? undefined,\n        snapshot.ref ? snapshot.ref : undefined,\n      )\n    } catch (err) {\n      // Validation errors are still returned synchronously\n      await this.updateSnapshotState(snapshot.id, SnapshotState.ERROR, err.message)\n      throw err\n    }\n  }\n\n  async processBuildOnRunner(snapshot: Snapshot, runner: Runner) {\n    try {\n      const registry = await this.dockerRegistryService.getAvailableInternalRegistry(runner.region)\n\n      const sourceRegistries = await this.dockerRegistryService.getSourceRegistriesForDockerfile(\n        snapshot.buildInfo.dockerfileContent,\n        snapshot.organizationId,\n      )\n\n      const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n      registry.url = registry.url.replace(/^(https?:\\/\\/)/, '')\n      // Runner returns immediately; polling for completion is handled by handleCheckInitialRunnerSnapshot\n      await runnerAdapter.buildSnapshot(\n        snapshot.buildInfo,\n        snapshot.organizationId,\n        sourceRegistries.length > 0 ? sourceRegistries : undefined,\n        registry ?? undefined,\n        true,\n      )\n    } catch (err) {\n      this.logger.error(`Error building snapshot ${snapshot.name}: ${fromAxiosError(err)}`)\n      await this.updateSnapshotState(snapshot.id, SnapshotState.BUILD_FAILED, fromAxiosError(err).message)\n    }\n  }\n\n  async handleSnapshotStatePending(snapshot: Snapshot): Promise<SyncState> {\n    let initialRunner: Runner | undefined = undefined\n\n    if (!snapshot.initialRunnerId) {\n      // TODO: get only runners where the base snapshot is available (extract from buildInfo)\n      const excludedRunnerIds = snapshot.buildInfo\n        ? await this.runnerService.getRunnersWithMultipleSnapshotsBuilding()\n        : await this.runnerService.getRunnersWithMultipleSnapshotsPulling()\n\n      try {\n        const regions = await this.snapshotService.getSnapshotRegions(snapshot.id)\n        if (!regions.length) {\n          throw new Error('No regions found for snapshot')\n        }\n\n        initialRunner = await this.runnerService.getRandomAvailableRunner({\n          regions: regions.map((region) => region.id),\n          excludedRunnerIds: excludedRunnerIds,\n        })\n      } catch (error) {\n        this.logger.warn(`Failed to get initial runner: ${fromAxiosError(error)}`)\n      }\n\n      if (!initialRunner) {\n        // No runners available, retry later\n        return DONT_SYNC_AGAIN\n      }\n\n      snapshot.initialRunnerId = initialRunner.id\n      await this.snapshotRepository.save(snapshot)\n    } else {\n      initialRunner = await this.runnerService.findOneOrFail(snapshot.initialRunnerId)\n    }\n\n    if (snapshot.buildInfo) {\n      await this.updateSnapshotState(snapshot.id, SnapshotState.BUILDING)\n      await this.runnerService.createSnapshotRunnerEntry(\n        initialRunner.id,\n        snapshot.buildInfo.snapshotRef,\n        SnapshotRunnerState.BUILDING_SNAPSHOT,\n      )\n      await this.processBuildOnRunner(snapshot, initialRunner)\n    } else {\n      if (!snapshot.ref) {\n        const runnerAdapter = await this.runnerAdapterFactory.create(initialRunner)\n        const registry = await this.dockerRegistryService.findRegistryByImageName(\n          snapshot.imageName,\n          initialRunner.region,\n          snapshot.organizationId,\n        )\n\n        const image = parseDockerImage(snapshot.imageName)\n        if (registry && !image.registry) {\n          image.registry = registry.url.replace(/^(https?:\\/\\/)/, '')\n        }\n        const imageName = image.getFullName()\n\n        const internalRegistry = await this.dockerRegistryService.getAvailableInternalRegistry(initialRunner.region)\n        if (!internalRegistry) {\n          throw new Error('No internal registry found for snapshot')\n        }\n\n        const snapshotDigestResponse = await runnerAdapter.inspectSnapshotInRegistry(imageName, registry)\n        await this.processSnapshotDigest(\n          snapshot,\n          internalRegistry,\n          snapshotDigestResponse.hash,\n          snapshotDigestResponse.sizeGB,\n        )\n        await this.snapshotRepository.save(snapshot)\n      }\n\n      await this.updateSnapshotState(snapshot.id, SnapshotState.PULLING)\n      await this.runnerService.createSnapshotRunnerEntry(\n        initialRunner.id,\n        snapshot.ref,\n        SnapshotRunnerState.PULLING_SNAPSHOT,\n      )\n      await this.processPullOnInitialRunner(snapshot, initialRunner)\n    }\n\n    return SYNC_AGAIN\n  }\n\n  private async updateSnapshotState(snapshotId: string, state: SnapshotState, errorReason?: string) {\n    const partialUpdate: Partial<Snapshot> = {\n      state,\n    }\n\n    if (state === SnapshotState.ACTIVE) {\n      partialUpdate.lastUsedAt = new Date()\n    }\n\n    if (errorReason !== undefined) {\n      partialUpdate.errorReason = errorReason\n    }\n\n    const result = await this.snapshotRepository.update(\n      {\n        id: snapshotId,\n      },\n      partialUpdate,\n    )\n\n    if (!result.affected) {\n      throw new NotFoundException(`Snapshot with ID ${snapshotId} not found`)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_HOUR, { name: 'cleanup-old-buildinfo-snapshot-runners' })\n  @TrackJobExecution()\n  @LogExecution('cleanup-old-buildinfo-snapshot-runners')\n  @WithInstrumentation()\n  async cleanupOldBuildInfoSnapshotRunners() {\n    const lockKey = 'cleanup-old-buildinfo-snapshots-lock'\n    if (!(await this.redisLockProvider.lock(lockKey, 300))) {\n      return\n    }\n\n    try {\n      const oneDayAgo = new Date()\n      oneDayAgo.setDate(oneDayAgo.getDate() - 1)\n\n      // Find all BuildInfo entities that haven't been used in over a day\n      const oldBuildInfos = await this.buildInfoRepository.find({\n        where: {\n          lastUsedAt: LessThan(oneDayAgo),\n        },\n      })\n\n      if (oldBuildInfos.length === 0) {\n        return\n      }\n\n      const snapshotRefs = oldBuildInfos.map((buildInfo) => buildInfo.snapshotRef)\n\n      const result = await this.snapshotRunnerRepository.update(\n        { snapshotRef: In(snapshotRefs) },\n        { state: SnapshotRunnerState.REMOVING },\n      )\n\n      if (result.affected > 0) {\n        this.logger.debug(`Marked ${result.affected} SnapshotRunners for removal due to unused BuildInfo`)\n      }\n    } catch (error) {\n      this.logger.error(`Failed to mark old BuildInfo SnapshotRunners for removal: ${fromAxiosError(error)}`)\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_MINUTES, { name: 'deactivate-old-snapshots' })\n  @TrackJobExecution()\n  @LogExecution('deactivate-old-snapshots')\n  @WithInstrumentation()\n  async deactivateOldSnapshots() {\n    const lockKey = 'deactivate-old-snapshots-lock'\n    if (!(await this.redisLockProvider.lock(lockKey, 300))) {\n      return\n    }\n\n    try {\n      const cutoff = `NOW() - INTERVAL '1 minute' * COALESCE(org.\"snapshot_deactivation_timeout_minutes\", ${DEFAULT_SNAPSHOT_DEACTIVATION_TIMEOUT_MINUTES})`\n\n      const oldSnapshots = await this.snapshotRepository\n        .createQueryBuilder('snapshot')\n        .leftJoin('organization', 'org', `org.\"id\" = snapshot.\"organizationId\"`)\n        .where('snapshot.general = false')\n        .andWhere('snapshot.state = :snapshotState', { snapshotState: SnapshotState.ACTIVE })\n        .andWhere(`(snapshot.\"lastUsedAt\" IS NULL OR snapshot.\"lastUsedAt\" < ${cutoff})`)\n        .andWhere(`snapshot.\"createdAt\" < ${cutoff}`)\n        .andWhere(\n          `NOT EXISTS (\n            SELECT 1 FROM snapshot s\n            WHERE s.\"ref\" = snapshot.\"ref\"\n            AND s.state = :activeState\n            AND (s.\"lastUsedAt\" >= ${cutoff} OR s.\"createdAt\" >= ${cutoff})\n          )`,\n          {\n            activeState: SnapshotState.ACTIVE,\n          },\n        )\n        .take(100)\n        .getMany()\n\n      if (oldSnapshots.length === 0) {\n        return\n      }\n\n      // Deactivate the snapshots\n      const snapshotIds = oldSnapshots.map((snapshot) => snapshot.id)\n      await this.snapshotRepository.update({ id: In(snapshotIds) }, { state: SnapshotState.INACTIVE })\n\n      // Get internal names of deactivated snapshots\n      const refs = oldSnapshots.map((snapshot) => snapshot.ref).filter((name) => name) // Filter out null/undefined values\n\n      if (refs.length > 0) {\n        // Set associated SnapshotRunner records to REMOVING state\n        const result = await this.snapshotRunnerRepository.update(\n          { snapshotRef: In(refs) },\n          { state: SnapshotRunnerState.REMOVING },\n        )\n\n        this.logger.debug(\n          `Deactivated ${oldSnapshots.length} snapshots and marked ${result.affected} SnapshotRunners for removal`,\n        )\n      }\n    } catch (error) {\n      this.logger.error(`Failed to deactivate old snapshots: ${fromAxiosError(error)}`)\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_MINUTES, { name: 'cleanup-inactive-snapshots-from-runners' })\n  @TrackJobExecution()\n  @LogExecution('cleanup-inactive-snapshots-from-runners')\n  @WithInstrumentation()\n  async cleanupInactiveSnapshotsFromRunners() {\n    const lockKey = 'cleanup-inactive-snapshots-from-runners-lock'\n    if (!(await this.redisLockProvider.lock(lockKey, 300))) {\n      return\n    }\n\n    try {\n      // Only fetch inactive snapshots that have associated snapshot runner entries\n      const queryResult = await this.snapshotRepository\n        .createQueryBuilder('snapshot')\n        .select('snapshot.\"ref\"')\n        .where('snapshot.state = :snapshotState', { snapshotState: SnapshotState.INACTIVE })\n        .andWhere('snapshot.\"ref\" IS NOT NULL')\n        .andWhereExists(\n          this.snapshotRunnerRepository\n            .createQueryBuilder('snapshot_runner')\n            .select('1')\n            .where('snapshot_runner.\"snapshotRef\" = snapshot.\"ref\"')\n            .andWhere('snapshot_runner.state != :snapshotRunnerState', {\n              snapshotRunnerState: SnapshotRunnerState.REMOVING,\n            }),\n        )\n        .andWhere(\n          () => {\n            const query = this.snapshotRepository\n              .createQueryBuilder('s')\n              .select('1')\n              .where('s.\"ref\" = snapshot.\"ref\"')\n              .andWhere('s.state = :snapshotState')\n            return `NOT EXISTS (${query.getQuery()})`\n          },\n          {\n            snapshotState: SnapshotState.ACTIVE,\n          },\n        )\n        .take(100)\n        .getRawMany()\n\n      const inactiveSnapshotRefs = queryResult.map((result) => result.ref)\n\n      if (inactiveSnapshotRefs.length > 0) {\n        // Set associated SnapshotRunner records to REMOVING state\n        const result = await this.snapshotRunnerRepository.update(\n          { snapshotRef: In(inactiveSnapshotRefs) },\n          { state: SnapshotRunnerState.REMOVING },\n        )\n\n        this.logger.debug(`Marked ${result.affected} SnapshotRunners for removal`)\n      }\n    } catch (error) {\n      this.logger.error(`Failed to cleanup inactive snapshots from runners: ${fromAxiosError(error)}`)\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  private async processSnapshotDigest(\n    snapshot: Snapshot,\n    internalRegistry: DockerRegistry,\n    hash: string,\n    sizeGB: number,\n    entrypoint?: string[] | string,\n  ) {\n    let shouldSave = false\n    if (!snapshot.ref) {\n      shouldSave = true\n      const sanitizedUrl = internalRegistry.url.replace(/^https?:\\/\\//, '')\n      snapshot.ref = `${sanitizedUrl}/${internalRegistry.project || 'daytona'}/daytona-${hash}:daytona`\n    }\n\n    if (!snapshot.size) {\n      shouldSave = true\n\n      const organization = await this.organizationService.findOne(snapshot.organizationId)\n      if (!organization) {\n        throw new NotFoundException(`Organization with ID ${snapshot.organizationId} not found`)\n      }\n\n      const MAX_SIZE_GB = organization.maxSnapshotSize\n\n      if (sizeGB > MAX_SIZE_GB) {\n        await this.updateSnapshotState(\n          snapshot.id,\n          SnapshotState.ERROR,\n          `Snapshot size (${sizeGB.toFixed(2)}GB) exceeds maximum allowed size of ${MAX_SIZE_GB}GB`,\n        )\n        return DONT_SYNC_AGAIN\n      }\n\n      snapshot.size = sizeGB\n    }\n\n    // If entrypoint is not explicitly set, set it from snapshotInfoResponse\n    if (!snapshot.entrypoint) {\n      if (entrypoint && entrypoint.length > 0) {\n        shouldSave = true\n        if (Array.isArray(entrypoint)) {\n          snapshot.entrypoint = entrypoint\n        } else {\n          snapshot.entrypoint = [entrypoint]\n        }\n      }\n    }\n\n    if (shouldSave) {\n      await this.snapshotRepository.save(snapshot)\n    }\n  }\n\n  @OnAsyncEvent({\n    event: SnapshotEvents.CREATED,\n  })\n  private async handleSnapshotCreatedEvent(event: SnapshotCreatedEvent) {\n    await this.syncSnapshotState(event.snapshot.id)\n  }\n\n  @OnAsyncEvent({\n    event: SnapshotEvents.ACTIVATED,\n  })\n  private async handleSnapshotActivatedEvent(event: SnapshotActivatedEvent) {\n    await this.syncSnapshotState(event.snapshot.id)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/managers/volume.manager.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, OnApplicationBootstrap, OnApplicationShutdown, OnModuleInit } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Repository, In } from 'typeorm'\nimport { Volume } from '../entities/volume.entity'\nimport { VolumeState } from '../enums/volume-state.enum'\nimport { Cron, CronExpression, SchedulerRegistry } from '@nestjs/schedule'\nimport { S3Client, CreateBucketCommand, ListBucketsCommand, PutBucketTaggingCommand } from '@aws-sdk/client-s3'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { deleteS3Bucket } from '../../common/utils/delete-s3-bucket'\n\nimport { TrackableJobExecutions } from '../../common/interfaces/trackable-job-executions'\nimport { TrackJobExecution } from '../../common/decorators/track-job-execution.decorator'\nimport { setTimeout } from 'timers/promises'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\n\nconst VOLUME_STATE_LOCK_KEY = 'volume-state-'\n\n@Injectable()\nexport class VolumeManager\n  implements OnModuleInit, TrackableJobExecutions, OnApplicationShutdown, OnApplicationBootstrap\n{\n  activeJobs = new Set<string>()\n\n  private readonly logger = new Logger(VolumeManager.name)\n  private processingVolumes: Set<string> = new Set()\n  private skipTestConnection = false\n  private s3Client: S3Client | null = null\n\n  constructor(\n    @InjectRepository(Volume)\n    private readonly volumeRepository: Repository<Volume>,\n    private readonly configService: TypedConfigService,\n    @InjectRedis() private readonly redis: Redis,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly schedulerRegistry: SchedulerRegistry,\n  ) {\n    if (!this.configService.get('s3.endpoint')) {\n      return\n    }\n\n    const endpoint = this.configService.getOrThrow('s3.endpoint')\n    const region = this.configService.getOrThrow('s3.region')\n    const accessKeyId = this.configService.getOrThrow('s3.accessKey')\n    const secretAccessKey = this.configService.getOrThrow('s3.secretKey')\n    this.skipTestConnection = this.configService.get('skipConnections')\n\n    this.s3Client = new S3Client({\n      endpoint: endpoint.startsWith('http') ? endpoint : `http://${endpoint}`,\n      region,\n      credentials: {\n        accessKeyId,\n        secretAccessKey,\n      },\n      forcePathStyle: true,\n    })\n  }\n\n  async onModuleInit() {\n    if (!this.s3Client) {\n      return\n    }\n\n    if (this.skipTestConnection) {\n      this.logger.debug('Skipping S3 connection test')\n      return\n    }\n\n    await this.testConnection()\n  }\n\n  onApplicationBootstrap() {\n    if (!this.s3Client) {\n      return\n    }\n\n    this.schedulerRegistry.getCronJob('process-pending-volumes').start()\n  }\n\n  async onApplicationShutdown() {\n    //  wait for all active jobs to finish\n    while (this.activeJobs.size > 0) {\n      this.logger.log(`Waiting for ${this.activeJobs.size} active jobs to finish`)\n      await setTimeout(1000)\n    }\n  }\n\n  private async testConnection() {\n    try {\n      // Try a simple operation to test the connection\n      const command = new ListBucketsCommand({})\n      await this.s3Client.send(command)\n      this.logger.debug('Successfully connected to S3')\n    } catch (error) {\n      this.logger.error('Failed to connect to S3:', error)\n      throw error\n    }\n  }\n\n  @Cron(CronExpression.EVERY_5_SECONDS, { name: 'process-pending-volumes', waitForCompletion: true, disabled: true })\n  @TrackJobExecution()\n  @LogExecution('process-pending-volumes')\n  @WithInstrumentation()\n  async processPendingVolumes() {\n    if (!this.s3Client) {\n      return\n    }\n\n    try {\n      // Lock the entire process\n      const lockKey = 'process-pending-volumes'\n      if (!(await this.redisLockProvider.lock(lockKey, 30))) {\n        return\n      }\n\n      const pendingVolumes = await this.volumeRepository.find({\n        where: {\n          state: In([VolumeState.PENDING_CREATE, VolumeState.PENDING_DELETE]),\n        },\n      })\n\n      await Promise.all(\n        pendingVolumes.map(async (volume) => {\n          if (this.processingVolumes.has(volume.id)) {\n            return\n          }\n\n          // Get lock for this specific volume\n          const volumeLockKey = `${VOLUME_STATE_LOCK_KEY}${volume.id}`\n          const acquired = await this.redisLockProvider.lock(volumeLockKey, 30)\n          if (!acquired) {\n            return\n          }\n\n          try {\n            this.processingVolumes.add(volume.id)\n            await this.processVolumeState(volume)\n          } finally {\n            this.processingVolumes.delete(volume.id)\n            await this.redisLockProvider.unlock(volumeLockKey)\n          }\n        }),\n      )\n\n      await this.redisLockProvider.unlock(lockKey)\n    } catch (error) {\n      this.logger.error('Error processing pending volumes:', error)\n    }\n  }\n\n  private async processVolumeState(volume: Volume): Promise<void> {\n    const volumeLockKey = `${VOLUME_STATE_LOCK_KEY}${volume.id}`\n\n    try {\n      switch (volume.state) {\n        case VolumeState.PENDING_CREATE:\n          await this.handlePendingCreate(volume, volumeLockKey)\n          break\n        case VolumeState.PENDING_DELETE:\n          await this.handlePendingDelete(volume, volumeLockKey)\n          break\n      }\n    } catch (error) {\n      this.logger.error(`Error processing volume ${volume.id}:`, error)\n      await this.volumeRepository.update(volume.id, {\n        state: VolumeState.ERROR,\n        errorReason: error.message,\n      })\n    }\n  }\n\n  private async handlePendingCreate(volume: Volume, lockKey: string): Promise<void> {\n    try {\n      // Refresh lock before state change\n      await this.redis.setex(lockKey, 30, '1')\n\n      // Update state to CREATING\n      await this.volumeRepository.save({\n        ...volume,\n        state: VolumeState.CREATING,\n      })\n\n      // Refresh lock before S3 operation\n      await this.redis.setex(lockKey, 30, '1')\n\n      // Create bucket in Minio/S3\n      const createBucketCommand = new CreateBucketCommand({\n        Bucket: volume.getBucketName(),\n      })\n\n      await this.s3Client.send(createBucketCommand)\n\n      await this.s3Client.send(\n        new PutBucketTaggingCommand({\n          Bucket: volume.getBucketName(),\n          Tagging: {\n            TagSet: [\n              {\n                Key: 'VolumeId',\n                Value: volume.id,\n              },\n              {\n                Key: 'OrganizationId',\n                Value: volume.organizationId,\n              },\n              {\n                Key: 'Environment',\n                Value: this.configService.get('environment'),\n              },\n            ],\n          },\n        }),\n      )\n\n      // Refresh lock before final state update\n      await this.redis.setex(lockKey, 30, '1')\n\n      // Update volume state to READY\n      await this.volumeRepository.save({\n        ...volume,\n        state: VolumeState.READY,\n      })\n      this.logger.debug(`Volume ${volume.id} created successfully`)\n    } catch (error) {\n      this.logger.error(`Error creating volume ${volume.id}:`, error)\n      await this.volumeRepository.save({\n        ...volume,\n        state: VolumeState.ERROR,\n        errorReason: error.message,\n      })\n    }\n  }\n\n  private async handlePendingDelete(volume: Volume, lockKey: string): Promise<void> {\n    try {\n      // Refresh lock before state change\n      await this.redis.setex(lockKey, 30, '1')\n\n      // Update state to DELETING\n      await this.volumeRepository.save({\n        ...volume,\n        state: VolumeState.DELETING,\n      })\n\n      // Refresh lock before S3 operation\n      await this.redis.setex(lockKey, 30, '1')\n\n      // Delete bucket from Minio/S3\n      try {\n        await deleteS3Bucket(this.s3Client, volume.getBucketName())\n      } catch (error) {\n        if (error.name === 'NoSuchBucket') {\n          this.logger.warn(`Bucket for volume ${volume.id} does not exist, treating as already deleted`)\n        } else if (error.name === 'BucketNotEmpty') {\n          throw new Error('Volume deletion failed because the bucket is not empty. You may retry deletion.')\n        } else {\n          throw error\n        }\n      }\n\n      // Refresh lock before final state update\n      await this.redis.setex(lockKey, 30, '1')\n\n      // Delete any existing volume record with the deleted state and the same name in the same organization\n      await this.volumeRepository.delete({\n        organizationId: volume.organizationId,\n        name: `${volume.name}-deleted`,\n        state: VolumeState.DELETED,\n      })\n\n      // Update volume state to DELETED and rename\n      await this.volumeRepository.save({\n        ...volume,\n        state: VolumeState.DELETED,\n        name: `${volume.name}-deleted`,\n      })\n      this.logger.debug(`Volume ${volume.id} deleted successfully`)\n    } catch (error) {\n      this.logger.error(`Error deleting volume ${volume.id}:`, error)\n      await this.volumeRepository.save({\n        ...volume,\n        state: VolumeState.ERROR,\n        errorReason: error.message,\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/proxy/log-proxy.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Logger } from '@nestjs/common'\nimport { createProxyMiddleware, fixRequestBody, Options } from 'http-proxy-middleware'\nimport { IncomingMessage, ServerResponse } from 'http'\nimport { NextFunction } from 'express'\n\nexport class LogProxy {\n  private readonly logger = new Logger(LogProxy.name)\n\n  constructor(\n    private readonly targetUrl: string,\n    private readonly snapshotRef: string,\n    private readonly authToken: string,\n    private readonly follow: boolean,\n    private readonly req: IncomingMessage,\n    private readonly res: ServerResponse<IncomingMessage>,\n    private readonly next: NextFunction,\n  ) {}\n\n  create() {\n    const proxyOptions: Options = {\n      target: this.targetUrl,\n      secure: false,\n      changeOrigin: true,\n      autoRewrite: true,\n      pathRewrite: () => `/snapshots/logs?snapshotRef=${this.snapshotRef}&follow=${this.follow}`,\n      on: {\n        proxyReq: (proxyReq: any, req: any) => {\n          proxyReq.setHeader('Authorization', `Bearer ${this.authToken}`)\n          proxyReq.setHeader('Accept', 'application/octet-stream')\n          fixRequestBody(proxyReq, req)\n        },\n      },\n      proxyTimeout: 5 * 60 * 1000,\n    }\n\n    return createProxyMiddleware(proxyOptions)(this.req, this.res, this.next)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/repositories/sandbox.repository.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DataSource, FindOptionsWhere } from 'typeorm'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { ConflictException, Injectable, Logger, NotFoundException } from '@nestjs/common'\nimport { InjectDataSource } from '@nestjs/typeorm'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { BaseRepository } from '../../common/repositories/base.repository'\nimport { SandboxEvents } from '../constants/sandbox-events.constants'\nimport { SandboxStateUpdatedEvent } from '../events/sandbox-state-updated.event'\nimport { SandboxDesiredStateUpdatedEvent } from '../events/sandbox-desired-state-updated.event'\nimport { SandboxPublicStatusUpdatedEvent } from '../events/sandbox-public-status-updated.event'\nimport { SandboxOrganizationUpdatedEvent } from '../events/sandbox-organization-updated.event'\nimport { SandboxLookupCacheInvalidationService } from '../services/sandbox-lookup-cache-invalidation.service'\n\n@Injectable()\nexport class SandboxRepository extends BaseRepository<Sandbox> {\n  private readonly logger = new Logger(SandboxRepository.name)\n\n  constructor(\n    @InjectDataSource() dataSource: DataSource,\n    eventEmitter: EventEmitter2,\n    private readonly sandboxLookupCacheInvalidationService: SandboxLookupCacheInvalidationService,\n  ) {\n    super(dataSource, eventEmitter, Sandbox)\n  }\n\n  async insert(sandbox: Sandbox): Promise<Sandbox> {\n    const now = new Date()\n    if (!sandbox.createdAt) {\n      sandbox.createdAt = now\n    }\n    if (!sandbox.updatedAt) {\n      sandbox.updatedAt = now\n    }\n    if (!sandbox.lastActivityAt) {\n      sandbox.lastActivityAt = now\n    }\n\n    sandbox.assertValid()\n    sandbox.enforceInvariants()\n\n    await this.repository.insert(sandbox)\n\n    this.invalidateLookupCacheOnInsert(sandbox)\n\n    return sandbox\n  }\n\n  /**\n   * @param id - The ID of the sandbox to update.\n   * @param params.updateData - The partial data to update.\n   *\n   * @returns `void` because a raw update is performed.\n   */\n  async update(id: string, params: { updateData: Partial<Sandbox> }, raw: true): Promise<void>\n  /**\n   * @param id - The ID of the sandbox to update.\n   * @param params.updateData - The partial data to update.\n   * @param params.entity - Optional pre-fetched sandbox to use instead of fetching from the database.\n   *\n   * @returns The updated sandbox.\n   */\n  async update(id: string, params: { updateData: Partial<Sandbox>; entity?: Sandbox }, raw?: false): Promise<Sandbox>\n  async update(\n    id: string,\n    params: { updateData: Partial<Sandbox>; entity?: Sandbox },\n    raw = false,\n  ): Promise<Sandbox | void> {\n    const { updateData, entity } = params\n\n    if (updateData.state && !updateData.lastActivityAt) {\n      updateData.lastActivityAt = new Date()\n    }\n\n    if (raw) {\n      await this.repository.update(id, updateData)\n      return\n    }\n\n    const sandbox = entity ?? (await this.findOneBy({ id }))\n    if (!sandbox) {\n      throw new NotFoundException('Sandbox not found')\n    }\n\n    const previousSandbox = { ...sandbox }\n\n    Object.assign(sandbox, updateData)\n    sandbox.assertValid()\n    const invariantChanges = sandbox.enforceInvariants()\n\n    const result = await this.repository.update(id, { ...updateData, ...invariantChanges })\n    if (!result.affected) {\n      throw new NotFoundException('Sandbox not found after update')\n    }\n    sandbox.updatedAt = new Date()\n\n    this.emitUpdateEvents(sandbox, previousSandbox)\n    this.invalidateLookupCacheOnUpdate(sandbox, previousSandbox)\n\n    return sandbox\n  }\n\n  /**\n   * Partially updates a sandbox in the database and optionally emits a corresponding event based on the changes.\n   *\n   * Performs the update in a transaction with a pessimistic write lock to ensure consistency.\n   *\n   * @param id - The ID of the sandbox to update.\n   * @param params.updateData - The partial data to update.\n   * @param params.whereCondition - The where condition to use for the update.\n   *\n   * @throws {ConflictException} if the sandbox was modified by another operation\n   */\n  async updateWhere(\n    id: string,\n    params: {\n      updateData: Partial<Sandbox>\n      whereCondition: FindOptionsWhere<Sandbox>\n    },\n  ): Promise<Sandbox> {\n    const { updateData, whereCondition } = params\n\n    if (updateData.state && !updateData.lastActivityAt) {\n      updateData.lastActivityAt = new Date()\n    }\n\n    return this.manager.transaction(async (entityManager) => {\n      const whereClause = {\n        ...whereCondition,\n        id,\n      }\n\n      const sandbox = await entityManager.findOne(Sandbox, {\n        where: whereClause,\n        lock: { mode: 'pessimistic_write' },\n        relations: [],\n        loadEagerRelations: false,\n      })\n\n      if (!sandbox) {\n        throw new ConflictException('Sandbox was modified by another operation, please try again')\n      }\n\n      const previousSandbox = { ...sandbox }\n\n      Object.assign(sandbox, updateData)\n      sandbox.assertValid()\n      const invariantChanges = sandbox.enforceInvariants()\n\n      await entityManager.update(Sandbox, id, { ...updateData, ...invariantChanges })\n      sandbox.updatedAt = new Date()\n\n      this.emitUpdateEvents(sandbox, previousSandbox)\n      this.invalidateLookupCacheOnUpdate(sandbox, previousSandbox)\n\n      return sandbox\n    })\n  }\n\n  /**\n   * Invalidates the sandbox lookup cache for the inserted sandbox.\n   */\n  private invalidateLookupCacheOnInsert(sandbox: Sandbox): void {\n    try {\n      this.sandboxLookupCacheInvalidationService.invalidateOrgId({\n        sandboxId: sandbox.id,\n        organizationId: sandbox.organizationId,\n        name: sandbox.name,\n      })\n    } catch (error) {\n      this.logger.warn(\n        `Failed to enqueue sandbox lookup cache invalidation on insert (id, organizationId, name) for ${sandbox.id}: ${error instanceof Error ? error.message : String(error)}`,\n      )\n    }\n  }\n\n  /**\n   * Invalidates the sandbox lookup cache for the updated sandbox.\n   */\n  private invalidateLookupCacheOnUpdate(\n    updatedSandbox: Sandbox,\n    previousSandbox: Pick<Sandbox, 'organizationId' | 'name' | 'authToken'>,\n  ): void {\n    try {\n      this.sandboxLookupCacheInvalidationService.invalidate({\n        sandboxId: updatedSandbox.id,\n        organizationId: updatedSandbox.organizationId,\n        previousOrganizationId: previousSandbox.organizationId,\n        name: updatedSandbox.name,\n        previousName: previousSandbox.name,\n      })\n    } catch (error) {\n      this.logger.warn(\n        `Failed to enqueue sandbox lookup cache invalidation on update (id, organizationId, name) for ${updatedSandbox.id}: ${error instanceof Error ? error.message : String(error)}`,\n      )\n    }\n\n    try {\n      if (updatedSandbox.authToken !== previousSandbox.authToken) {\n        this.sandboxLookupCacheInvalidationService.invalidate({\n          authToken: updatedSandbox.authToken,\n        })\n      }\n    } catch (error) {\n      this.logger.warn(\n        `Failed to enqueue sandbox lookup cache invalidation on update (authToken) for ${updatedSandbox.id}: ${error instanceof Error ? error.message : String(error)}`,\n      )\n    }\n  }\n\n  /**\n   * Emits events based on the changes made to a sandbox.\n   */\n  private emitUpdateEvents(\n    updatedSandbox: Sandbox,\n    previousSandbox: Pick<Sandbox, 'state' | 'desiredState' | 'public' | 'organizationId'>,\n  ): void {\n    if (previousSandbox.state !== updatedSandbox.state) {\n      this.eventEmitter.emit(\n        SandboxEvents.STATE_UPDATED,\n        new SandboxStateUpdatedEvent(updatedSandbox, previousSandbox.state, updatedSandbox.state),\n      )\n    }\n\n    if (previousSandbox.desiredState !== updatedSandbox.desiredState) {\n      this.eventEmitter.emit(\n        SandboxEvents.DESIRED_STATE_UPDATED,\n        new SandboxDesiredStateUpdatedEvent(updatedSandbox, previousSandbox.desiredState, updatedSandbox.desiredState),\n      )\n    }\n\n    if (previousSandbox.public !== updatedSandbox.public) {\n      this.eventEmitter.emit(\n        SandboxEvents.PUBLIC_STATUS_UPDATED,\n        new SandboxPublicStatusUpdatedEvent(updatedSandbox, previousSandbox.public, updatedSandbox.public),\n      )\n    }\n\n    if (previousSandbox.organizationId !== updatedSandbox.organizationId) {\n      this.eventEmitter.emit(\n        SandboxEvents.ORGANIZATION_UPDATED,\n        new SandboxOrganizationUpdatedEvent(\n          updatedSandbox,\n          previousSandbox.organizationId,\n          updatedSandbox.organizationId,\n        ),\n      )\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/runner-adapter/runnerAdapter.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { Runner } from '../entities/runner.entity'\nimport { ModuleRef } from '@nestjs/core'\nimport { RunnerAdapterV0 } from './runnerAdapter.v0'\nimport { RunnerAdapterV2 } from './runnerAdapter.v2'\nimport { BuildInfo } from '../entities/build-info.entity'\nimport { DockerRegistry } from '../../docker-registry/entities/docker-registry.entity'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { RunnerServiceInfo } from '../common/runner-service-info'\n\nexport interface RunnerSandboxInfo {\n  state: SandboxState\n  daemonVersion?: string\n  backupState?: BackupState\n  backupErrorReason?: string\n}\n\nexport interface RunnerSnapshotInfo {\n  name: string\n  sizeGB: number\n  entrypoint: string[]\n  cmd: string[]\n  hash: string\n}\n\nexport interface SnapshotDigestResponse {\n  hash: string\n  sizeGB: number\n}\n\nexport interface RunnerMetrics {\n  currentAllocatedCpu?: number\n  currentAllocatedDiskGiB?: number\n  currentAllocatedMemoryGiB?: number\n  currentCpuUsagePercentage?: number\n  currentDiskUsagePercentage?: number\n  currentMemoryUsagePercentage?: number\n  currentSnapshotCount?: number\n  currentStartedSandboxes?: number\n}\n\nexport interface RunnerInfo {\n  serviceHealth?: RunnerServiceInfo[]\n  metrics?: RunnerMetrics\n  appVersion?: string\n}\n\nexport interface StartSandboxResponse {\n  daemonVersion: string\n}\n\nexport interface RunnerAdapter {\n  init(runner: Runner): Promise<void>\n\n  healthCheck(signal?: AbortSignal): Promise<void>\n\n  runnerInfo(signal?: AbortSignal): Promise<RunnerInfo>\n\n  sandboxInfo(sandboxId: string): Promise<RunnerSandboxInfo>\n  createSandbox(\n    sandbox: Sandbox,\n    registry?: DockerRegistry,\n    entrypoint?: string[],\n    metadata?: { [key: string]: string },\n    otelEndpoint?: string,\n    skipStart?: boolean,\n  ): Promise<StartSandboxResponse | undefined>\n  startSandbox(\n    sandboxId: string,\n    authToken: string,\n    metadata?: { [key: string]: string },\n    skipStart?: boolean,\n  ): Promise<StartSandboxResponse | undefined>\n  stopSandbox(sandboxId: string): Promise<void>\n  destroySandbox(sandboxId: string): Promise<void>\n  createBackup(sandbox: Sandbox, backupSnapshotName: string, registry?: DockerRegistry): Promise<void>\n\n  removeSnapshot(snapshotName: string): Promise<void>\n  buildSnapshot(\n    buildInfo: BuildInfo,\n    organizationId?: string,\n    sourceRegistries?: DockerRegistry[],\n    registry?: DockerRegistry,\n    pushToInternalRegistry?: boolean,\n  ): Promise<void>\n  pullSnapshot(\n    snapshotName: string,\n    registry?: DockerRegistry,\n    destinationRegistry?: DockerRegistry,\n    destinationRef?: string,\n    newTag?: string,\n  ): Promise<void>\n  snapshotExists(snapshotRef: string): Promise<boolean>\n  getSnapshotInfo(snapshotName: string): Promise<RunnerSnapshotInfo>\n  inspectSnapshotInRegistry(snapshotName: string, registry?: DockerRegistry): Promise<SnapshotDigestResponse>\n\n  updateNetworkSettings(\n    sandboxId: string,\n    networkBlockAll?: boolean,\n    networkAllowList?: string,\n    networkLimitEgress?: boolean,\n  ): Promise<void>\n\n  recoverSandbox(sandbox: Sandbox): Promise<void>\n\n  resizeSandbox(sandboxId: string, cpu?: number, memory?: number, disk?: number): Promise<void>\n}\n\n@Injectable()\nexport class RunnerAdapterFactory {\n  private readonly logger = new Logger(RunnerAdapterFactory.name)\n\n  constructor(private moduleRef: ModuleRef) {}\n\n  async create(runner: Runner): Promise<RunnerAdapter> {\n    switch (runner.apiVersion) {\n      case '0': {\n        const adapter = await this.moduleRef.create(RunnerAdapterV0)\n        await adapter.init(runner)\n        return adapter\n      }\n      case '2': {\n        const adapter = await this.moduleRef.create(RunnerAdapterV2)\n        await adapter.init(runner)\n        return adapter\n      }\n      default:\n        throw new Error(`Unsupported runner version: ${runner.apiVersion}`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/runner-adapter/runnerAdapter.v0.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport axios, { AxiosError } from 'axios'\nimport axiosDebug from 'axios-debug-log'\nimport axiosRetry from 'axios-retry'\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport {\n  RunnerAdapter,\n  RunnerInfo,\n  RunnerSandboxInfo,\n  RunnerSnapshotInfo,\n  StartSandboxResponse,\n  SnapshotDigestResponse,\n} from './runnerAdapter'\nimport { SnapshotStateError } from '../errors/snapshot-state-error'\nimport { Runner } from '../entities/runner.entity'\nimport {\n  Configuration,\n  SandboxApi,\n  EnumsSandboxState,\n  SnapshotsApi,\n  EnumsBackupState,\n  DefaultApi,\n  CreateSandboxDTO,\n  BuildSnapshotRequestDTO,\n  CreateBackupDTO,\n  PullSnapshotRequestDTO,\n  ToolboxApi,\n  UpdateNetworkSettingsDTO,\n  RecoverSandboxDTO,\n} from '@daytonaio/runner-api-client'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { BuildInfo } from '../entities/build-info.entity'\nimport { DockerRegistry } from '../../docker-registry/entities/docker-registry.entity'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { RunnerApiError } from '../errors/runner-api-error'\n\nconst isDebugEnabled = process.env.DEBUG === 'true'\n\n// Network error codes that should trigger a retry\nconst RETRYABLE_NETWORK_ERROR_CODES = ['ECONNRESET', 'ETIMEDOUT']\n\n@Injectable()\nexport class RunnerAdapterV0 implements RunnerAdapter {\n  private readonly logger = new Logger(RunnerAdapterV0.name)\n  private sandboxApiClient: SandboxApi\n  private snapshotApiClient: SnapshotsApi\n  private runnerApiClient: DefaultApi\n  private toolboxApiClient: ToolboxApi\n\n  private convertSandboxState(state: EnumsSandboxState): SandboxState {\n    switch (state) {\n      case EnumsSandboxState.SandboxStateCreating:\n        return SandboxState.CREATING\n      case EnumsSandboxState.SandboxStateRestoring:\n        return SandboxState.RESTORING\n      case EnumsSandboxState.SandboxStateDestroyed:\n        return SandboxState.DESTROYED\n      case EnumsSandboxState.SandboxStateDestroying:\n        return SandboxState.DESTROYING\n      case EnumsSandboxState.SandboxStateStarted:\n        return SandboxState.STARTED\n      case EnumsSandboxState.SandboxStateStopped:\n        return SandboxState.STOPPED\n      case EnumsSandboxState.SandboxStateStarting:\n        return SandboxState.STARTING\n      case EnumsSandboxState.SandboxStateStopping:\n        return SandboxState.STOPPING\n      case EnumsSandboxState.SandboxStateError:\n        return SandboxState.ERROR\n      case EnumsSandboxState.SandboxStatePullingSnapshot:\n        return SandboxState.PULLING_SNAPSHOT\n      default:\n        return SandboxState.UNKNOWN\n    }\n  }\n\n  private convertBackupState(state: EnumsBackupState): BackupState {\n    switch (state) {\n      case EnumsBackupState.BackupStatePending:\n        return BackupState.PENDING\n      case EnumsBackupState.BackupStateInProgress:\n        return BackupState.IN_PROGRESS\n      case EnumsBackupState.BackupStateCompleted:\n        return BackupState.COMPLETED\n      case EnumsBackupState.BackupStateFailed:\n        return BackupState.ERROR\n      default:\n        return BackupState.NONE\n    }\n  }\n\n  public async init(runner: Runner): Promise<void> {\n    if (!runner.apiUrl) {\n      throw new Error('Runner API URL is required')\n    }\n\n    const axiosInstance = axios.create({\n      baseURL: runner.apiUrl,\n      headers: {\n        Authorization: `Bearer ${runner.apiKey}`,\n      },\n      timeout: 1 * 60 * 60 * 1000, // 1 hour\n    })\n\n    const retryErrorMap = new WeakMap<AxiosError, string>()\n\n    // Configure axios-retry to handle network errors\n    axiosRetry(axiosInstance, {\n      retries: 3,\n      retryDelay: axiosRetry.exponentialDelay,\n      retryCondition: (error) => {\n        // Check if error code or message matches any retryable error\n        const matchedErrorCode = RETRYABLE_NETWORK_ERROR_CODES.find(\n          (code) =>\n            (error as any).code === code || error.message?.includes(code) || (error as any).cause?.code === code,\n        )\n\n        if (matchedErrorCode) {\n          retryErrorMap.set(error, matchedErrorCode)\n          return true\n        }\n\n        return false\n      },\n      onRetry: (retryCount, error, requestConfig) => {\n        this.logger.warn(\n          `Retrying request due to ${retryErrorMap.get(error)} (attempt ${retryCount}): ${requestConfig.method?.toUpperCase()} ${requestConfig.url}`,\n        )\n      },\n    })\n\n    axiosInstance.interceptors.response.use(\n      (response) => {\n        return response\n      },\n      (error) => {\n        const errorMessage = error.response?.data?.message || error.response?.data || error.message || String(error)\n        const statusCode = error.response?.data?.statusCode || error.response?.status || error.status\n        const code = error.response?.data?.code || (error as any).code || (error as any).cause?.code || ''\n\n        throw new RunnerApiError(String(errorMessage), statusCode, code)\n      },\n    )\n\n    if (isDebugEnabled) {\n      axiosDebug.addLogger(axiosInstance)\n    }\n\n    this.sandboxApiClient = new SandboxApi(new Configuration(), '', axiosInstance)\n    this.snapshotApiClient = new SnapshotsApi(new Configuration(), '', axiosInstance)\n    this.runnerApiClient = new DefaultApi(new Configuration(), '', axiosInstance)\n    this.toolboxApiClient = new ToolboxApi(new Configuration(), '', axiosInstance)\n  }\n\n  async healthCheck(signal?: AbortSignal): Promise<void> {\n    const response = await this.runnerApiClient.healthCheck({ signal })\n    if (response.data.status !== 'ok') {\n      throw new Error('Runner is not healthy')\n    }\n  }\n\n  async runnerInfo(signal?: AbortSignal): Promise<RunnerInfo> {\n    const response = await this.runnerApiClient.runnerInfo({ signal })\n    return {\n      serviceHealth: response.data.serviceHealth,\n      metrics: response.data.metrics,\n      appVersion: response.data.appVersion,\n    }\n  }\n\n  async sandboxInfo(sandboxId: string): Promise<RunnerSandboxInfo> {\n    const sandboxInfo = await this.sandboxApiClient.info(sandboxId)\n    return {\n      state: this.convertSandboxState(sandboxInfo.data.state),\n      backupState: this.convertBackupState(sandboxInfo.data.backupState),\n      backupErrorReason: sandboxInfo.data.backupError,\n      daemonVersion: sandboxInfo.data.daemonVersion,\n    }\n  }\n\n  async createSandbox(\n    sandbox: Sandbox,\n    registry?: DockerRegistry,\n    entrypoint?: string[],\n    metadata?: { [key: string]: string },\n    otelEndpoint?: string,\n    skipStart?: boolean,\n  ): Promise<StartSandboxResponse | undefined> {\n    const createSandboxDto: CreateSandboxDTO = {\n      id: sandbox.id,\n      userId: sandbox.organizationId,\n      snapshot: sandbox.snapshot,\n      osUser: sandbox.osUser,\n      cpuQuota: sandbox.cpu,\n      gpuQuota: sandbox.gpu,\n      memoryQuota: sandbox.mem,\n      storageQuota: sandbox.disk,\n      env: sandbox.env,\n      registry: registry\n        ? {\n            project: registry.project,\n            url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n            username: registry.username,\n            password: registry.password,\n          }\n        : undefined,\n      entrypoint: entrypoint,\n      volumes: sandbox.volumes?.map((volume) => ({\n        volumeId: volume.volumeId,\n        mountPath: volume.mountPath,\n        subpath: volume.subpath,\n      })),\n      networkBlockAll: sandbox.networkBlockAll,\n      networkAllowList: sandbox.networkAllowList,\n      metadata: metadata,\n      authToken: sandbox.authToken,\n      otelEndpoint,\n      skipStart: skipStart,\n      organizationId: sandbox.organizationId,\n      regionId: sandbox.region,\n    }\n\n    const response = await this.sandboxApiClient.create(createSandboxDto)\n\n    if (!response?.data?.daemonVersion) {\n      return undefined\n    }\n\n    return {\n      daemonVersion: response.data.daemonVersion,\n    }\n  }\n\n  async startSandbox(\n    sandboxId: string,\n    authToken: string,\n    metadata?: { [key: string]: string },\n  ): Promise<StartSandboxResponse | undefined> {\n    const response = await this.sandboxApiClient.start(sandboxId, authToken, metadata)\n\n    if (!response?.data?.daemonVersion) {\n      return undefined\n    }\n\n    return {\n      daemonVersion: response.data.daemonVersion,\n    }\n  }\n\n  async stopSandbox(sandboxId: string): Promise<void> {\n    await this.sandboxApiClient.stop(sandboxId)\n  }\n\n  async destroySandbox(sandboxId: string): Promise<void> {\n    await this.sandboxApiClient.destroy(sandboxId)\n  }\n\n  async createBackup(sandbox: Sandbox, backupSnapshotName: string, registry?: DockerRegistry): Promise<void> {\n    const request: CreateBackupDTO = {\n      snapshot: backupSnapshotName,\n      registry: undefined,\n    }\n\n    if (registry) {\n      request.registry = {\n        project: registry.project,\n        url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: registry.username,\n        password: registry.password,\n      }\n    }\n\n    await this.sandboxApiClient.createBackup(sandbox.id, request)\n  }\n\n  async buildSnapshot(\n    buildInfo: BuildInfo,\n    organizationId?: string,\n    sourceRegistries?: DockerRegistry[],\n    registry?: DockerRegistry,\n    pushToInternalRegistry?: boolean,\n  ): Promise<void> {\n    const request: BuildSnapshotRequestDTO = {\n      snapshot: buildInfo.snapshotRef,\n      dockerfile: buildInfo.dockerfileContent,\n      organizationId: organizationId,\n      context: buildInfo.contextHashes,\n      pushToInternalRegistry: pushToInternalRegistry,\n    }\n\n    if (sourceRegistries) {\n      request.sourceRegistries = sourceRegistries.map((sourceRegistry) => ({\n        project: sourceRegistry.project,\n        url: sourceRegistry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: sourceRegistry.username,\n        password: sourceRegistry.password,\n      }))\n    }\n\n    if (registry) {\n      request.registry = {\n        project: registry.project,\n        url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: registry.username,\n        password: registry.password,\n      }\n    }\n\n    await this.snapshotApiClient.buildSnapshot(request)\n  }\n\n  async removeSnapshot(snapshotName: string): Promise<void> {\n    await this.snapshotApiClient.removeSnapshot(snapshotName)\n  }\n\n  async pullSnapshot(\n    snapshotName: string,\n    registry?: DockerRegistry,\n    destinationRegistry?: DockerRegistry,\n    destinationRef?: string,\n    newTag?: string,\n  ): Promise<void> {\n    const request: PullSnapshotRequestDTO = {\n      snapshot: snapshotName,\n      newTag,\n    }\n\n    if (registry) {\n      request.registry = {\n        project: registry.project,\n        url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: registry.username,\n        password: registry.password,\n      }\n    }\n\n    if (destinationRegistry) {\n      request.destinationRegistry = {\n        project: destinationRegistry.project,\n        url: destinationRegistry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: destinationRegistry.username,\n        password: destinationRegistry.password,\n      }\n    }\n\n    if (destinationRef) {\n      request.destinationRef = destinationRef\n    }\n\n    await this.snapshotApiClient.pullSnapshot(request)\n  }\n\n  async snapshotExists(snapshotName: string): Promise<boolean> {\n    const response = await this.snapshotApiClient.snapshotExists(snapshotName)\n    return response.data.exists\n  }\n\n  async getSnapshotInfo(snapshotName: string): Promise<RunnerSnapshotInfo> {\n    try {\n      const response = await this.snapshotApiClient.getSnapshotInfo(snapshotName)\n\n      return {\n        name: response.data.name || '',\n        sizeGB: response.data.sizeGB,\n        entrypoint: response.data.entrypoint,\n        cmd: response.data.cmd,\n        hash: response.data.hash,\n      }\n    } catch (err) {\n      if (err instanceof RunnerApiError && err.statusCode === 422) {\n        throw new SnapshotStateError(err.message)\n      }\n      throw err\n    }\n  }\n\n  async inspectSnapshotInRegistry(snapshotName: string, registry?: DockerRegistry): Promise<SnapshotDigestResponse> {\n    const response = await this.snapshotApiClient.inspectSnapshotInRegistry({\n      snapshot: snapshotName,\n      registry: registry\n        ? {\n            project: registry.project,\n            url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n            username: registry.username,\n            password: registry.password,\n          }\n        : undefined,\n    })\n\n    return {\n      hash: response.data.hash,\n      sizeGB: response.data.sizeGB,\n    }\n  }\n\n  async updateNetworkSettings(\n    sandboxId: string,\n    networkBlockAll?: boolean,\n    networkAllowList?: string,\n    networkLimitEgress?: boolean,\n  ): Promise<void> {\n    const updateNetworkSettingsDto: UpdateNetworkSettingsDTO = {\n      networkBlockAll: networkBlockAll,\n      networkAllowList: networkAllowList,\n      networkLimitEgress: networkLimitEgress,\n    }\n\n    await this.sandboxApiClient.updateNetworkSettings(sandboxId, updateNetworkSettingsDto)\n  }\n\n  async recoverSandbox(sandbox: Sandbox): Promise<void> {\n    const recoverSandboxDTO: RecoverSandboxDTO = {\n      userId: sandbox.organizationId,\n      snapshot: sandbox.snapshot,\n      osUser: sandbox.osUser,\n      cpuQuota: sandbox.cpu,\n      gpuQuota: sandbox.gpu,\n      memoryQuota: sandbox.mem,\n      storageQuota: sandbox.disk,\n      env: sandbox.env,\n      volumes: sandbox.volumes?.map((volume) => ({\n        volumeId: volume.volumeId,\n        mountPath: volume.mountPath,\n        subpath: volume.subpath,\n      })),\n      networkBlockAll: sandbox.networkBlockAll,\n      networkAllowList: sandbox.networkAllowList,\n      errorReason: sandbox.errorReason,\n      backupErrorReason: sandbox.backupErrorReason,\n    }\n    await this.sandboxApiClient.recover(sandbox.id, recoverSandboxDTO)\n  }\n\n  async resizeSandbox(sandboxId: string, cpu?: number, memory?: number, disk?: number): Promise<void> {\n    await this.sandboxApiClient.resize(sandboxId, { cpu, memory, disk })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/runner-adapter/runnerAdapter.v2.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Repository, IsNull, Not } from 'typeorm'\nimport {\n  RunnerAdapter,\n  RunnerInfo,\n  RunnerSandboxInfo,\n  RunnerSnapshotInfo,\n  StartSandboxResponse,\n  SnapshotDigestResponse,\n} from './runnerAdapter'\nimport { Runner } from '../entities/runner.entity'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { Job } from '../entities/job.entity'\nimport { BuildInfo } from '../entities/build-info.entity'\nimport { DockerRegistry } from '../../docker-registry/entities/docker-registry.entity'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { JobType } from '../enums/job-type.enum'\nimport { JobStatus } from '../enums/job-status.enum'\nimport { ResourceType } from '../enums/resource-type.enum'\nimport { JobService } from '../services/job.service'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport {\n  CreateSandboxDTO,\n  CreateBackupDTO,\n  BuildSnapshotRequestDTO,\n  PullSnapshotRequestDTO,\n  UpdateNetworkSettingsDTO,\n  InspectSnapshotInRegistryRequest,\n  RecoverSandboxDTO,\n} from '@daytonaio/runner-api-client'\nimport { SnapshotStateError } from '../errors/snapshot-state-error'\n\n/**\n * RunnerAdapterV2 implements RunnerAdapter for v2 runners.\n * Instead of making direct API calls to the runner, it creates jobs in the database\n * that the v2 runner polls and processes asynchronously.\n */\n@Injectable()\nexport class RunnerAdapterV2 implements RunnerAdapter {\n  private readonly logger = new Logger(RunnerAdapterV2.name)\n  private runner: Runner\n\n  constructor(\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(Job)\n    private readonly jobRepository: Repository<Job>,\n    private readonly jobService: JobService,\n  ) {}\n\n  async init(runner: Runner): Promise<void> {\n    this.runner = runner\n  }\n\n  async healthCheck(_signal?: AbortSignal): Promise<void> {\n    throw new Error('healthCheck is not supported for V2 runners')\n  }\n\n  async runnerInfo(_signal?: AbortSignal): Promise<RunnerInfo> {\n    throw new Error('runnerInfo is not supported for V2 runners')\n  }\n\n  async sandboxInfo(sandboxId: string): Promise<RunnerSandboxInfo> {\n    // Query the sandbox entity\n    const sandbox = await this.sandboxRepository.findOne({\n      where: { id: sandboxId },\n    })\n\n    if (!sandbox) {\n      throw new Error(`Sandbox ${sandboxId} not found`)\n    }\n\n    // Query for any incomplete jobs for this sandbox to determine transitional state\n    const incompleteJob = await this.jobRepository.findOne({\n      where: {\n        resourceType: ResourceType.SANDBOX,\n        resourceId: sandboxId,\n        completedAt: IsNull(),\n      },\n      order: { createdAt: 'DESC' },\n    })\n\n    let state = sandbox.state\n\n    let daemonVersion: string | undefined = undefined\n\n    // If there's an incomplete job, infer the transitional state from job type\n    if (incompleteJob) {\n      state = this.inferStateFromJob(incompleteJob, sandbox)\n      daemonVersion = incompleteJob.getResultMetadata()?.daemonVersion\n    } else {\n      // Look for latest job for this sandbox\n      const latestJob = await this.jobRepository.findOne({\n        where: {\n          resourceType: ResourceType.SANDBOX,\n          resourceId: sandboxId,\n        },\n        order: { createdAt: 'DESC' },\n      })\n      if (latestJob) {\n        state = this.inferStateFromJob(latestJob, sandbox)\n        daemonVersion = latestJob.getResultMetadata()?.daemonVersion\n      }\n    }\n\n    return {\n      state,\n      backupState: sandbox.backupState,\n      backupErrorReason: sandbox.backupErrorReason,\n      daemonVersion,\n    }\n  }\n\n  private inferStateFromJob(job: Job, sandbox: Sandbox): SandboxState {\n    // Map job types to transitional states\n    switch (job.type) {\n      case JobType.CREATE_SANDBOX:\n        return job.status === JobStatus.COMPLETED ? SandboxState.STARTED : SandboxState.CREATING\n      case JobType.START_SANDBOX:\n        return job.status === JobStatus.COMPLETED ? SandboxState.STARTED : SandboxState.STARTING\n      case JobType.STOP_SANDBOX:\n        return job.status === JobStatus.COMPLETED ? SandboxState.STOPPED : SandboxState.STOPPING\n      case JobType.DESTROY_SANDBOX:\n        return job.status === JobStatus.COMPLETED ? SandboxState.DESTROYED : SandboxState.DESTROYING\n      default:\n        // For other job types (backup, etc.), return current sandbox state\n        return sandbox.state\n    }\n  }\n\n  async createSandbox(\n    sandbox: Sandbox,\n    registry?: DockerRegistry,\n    entrypoint?: string[],\n    metadata?: { [key: string]: string },\n    otelEndpoint?: string,\n    skipStart?: boolean,\n  ): Promise<StartSandboxResponse | undefined> {\n    const payload: CreateSandboxDTO = {\n      id: sandbox.id,\n      userId: sandbox.organizationId,\n      snapshot: sandbox.snapshot,\n      osUser: sandbox.osUser,\n      cpuQuota: sandbox.cpu,\n      gpuQuota: sandbox.gpu,\n      memoryQuota: sandbox.mem,\n      storageQuota: sandbox.disk,\n      env: sandbox.env,\n      registry: registry\n        ? {\n            project: registry.project,\n            url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n            username: registry.username,\n            password: registry.password,\n          }\n        : undefined,\n      entrypoint: entrypoint,\n      volumes: sandbox.volumes?.map((volume) => ({\n        volumeId: volume.volumeId,\n        mountPath: volume.mountPath,\n        subpath: volume.subpath,\n      })),\n      networkBlockAll: sandbox.networkBlockAll,\n      networkAllowList: sandbox.networkAllowList,\n      metadata: metadata,\n      authToken: sandbox.authToken,\n      otelEndpoint: otelEndpoint,\n      skipStart: skipStart,\n      organizationId: sandbox.organizationId,\n      regionId: sandbox.region,\n    }\n\n    await this.jobService.createJob(\n      null,\n      JobType.CREATE_SANDBOX,\n      this.runner.id,\n      ResourceType.SANDBOX,\n      sandbox.id,\n      payload,\n    )\n\n    this.logger.debug(`Created CREATE_SANDBOX job for sandbox ${sandbox.id} on runner ${this.runner.id}`)\n\n    // Daemon version will be set in the job result metadata\n    return undefined\n  }\n\n  async startSandbox(\n    sandboxId: string,\n    authToken: string,\n    metadata?: { [key: string]: string },\n  ): Promise<StartSandboxResponse | undefined> {\n    await this.jobService.createJob(null, JobType.START_SANDBOX, this.runner.id, ResourceType.SANDBOX, sandboxId, {\n      authToken,\n      metadata,\n    })\n\n    this.logger.debug(`Created START_SANDBOX job for sandbox ${sandboxId} on runner ${this.runner.id}`)\n\n    // Daemon version will be set in the job result metadata\n    return undefined\n  }\n\n  async stopSandbox(sandboxId: string): Promise<void> {\n    await this.jobService.createJob(null, JobType.STOP_SANDBOX, this.runner.id, ResourceType.SANDBOX, sandboxId)\n\n    this.logger.debug(`Created STOP_SANDBOX job for sandbox ${sandboxId} on runner ${this.runner.id}`)\n  }\n\n  async destroySandbox(sandboxId: string): Promise<void> {\n    await this.jobService.createJob(null, JobType.DESTROY_SANDBOX, this.runner.id, ResourceType.SANDBOX, sandboxId)\n\n    this.logger.debug(`Created DESTROY_SANDBOX job for sandbox ${sandboxId} on runner ${this.runner.id}`)\n  }\n\n  async recoverSandbox(sandbox: Sandbox): Promise<void> {\n    const recoverSandboxDTO: RecoverSandboxDTO = {\n      userId: sandbox.organizationId,\n      snapshot: sandbox.snapshot,\n      osUser: sandbox.osUser,\n      cpuQuota: sandbox.cpu,\n      gpuQuota: sandbox.gpu,\n      memoryQuota: sandbox.mem,\n      storageQuota: sandbox.disk,\n      env: sandbox.env,\n      volumes: sandbox.volumes?.map((volume) => ({\n        volumeId: volume.volumeId,\n        mountPath: volume.mountPath,\n        subpath: volume.subpath,\n      })),\n      networkBlockAll: sandbox.networkBlockAll,\n      networkAllowList: sandbox.networkAllowList,\n      errorReason: sandbox.errorReason,\n      backupErrorReason: sandbox.backupErrorReason,\n    }\n    await this.jobService.createJob(\n      null,\n      JobType.RECOVER_SANDBOX,\n      this.runner.id,\n      ResourceType.SANDBOX,\n      sandbox.id,\n      recoverSandboxDTO,\n    )\n\n    this.logger.debug(`Created RECOVER_SANDBOX job for sandbox ${sandbox.id} on runner ${this.runner.id}`)\n  }\n\n  async createBackup(sandbox: Sandbox, backupSnapshotName: string, registry?: DockerRegistry): Promise<void> {\n    const payload: CreateBackupDTO = {\n      snapshot: backupSnapshotName,\n      registry: undefined,\n    }\n\n    if (registry) {\n      payload.registry = {\n        project: registry.project,\n        url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: registry.username,\n        password: registry.password,\n      }\n    }\n\n    await this.jobService.createJob(\n      null,\n      JobType.CREATE_BACKUP,\n      this.runner.id,\n      ResourceType.SANDBOX,\n      sandbox.id,\n      payload,\n    )\n\n    this.logger.debug(`Created CREATE_BACKUP job for sandbox ${sandbox.id} on runner ${this.runner.id}`)\n  }\n\n  async buildSnapshot(\n    buildInfo: BuildInfo,\n    organizationId?: string,\n    sourceRegistries?: DockerRegistry[],\n    registry?: DockerRegistry,\n    pushToInternalRegistry?: boolean,\n  ): Promise<void> {\n    const payload: BuildSnapshotRequestDTO = {\n      snapshot: buildInfo.snapshotRef,\n      dockerfile: buildInfo.dockerfileContent,\n      organizationId: organizationId,\n      context: buildInfo.contextHashes,\n      pushToInternalRegistry: pushToInternalRegistry,\n    }\n\n    if (sourceRegistries) {\n      payload.sourceRegistries = sourceRegistries.map((sourceRegistry) => ({\n        project: sourceRegistry.project,\n        url: sourceRegistry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: sourceRegistry.username,\n        password: sourceRegistry.password,\n      }))\n    }\n\n    if (registry) {\n      payload.registry = {\n        project: registry.project,\n        url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: registry.username,\n        password: registry.password,\n      }\n    }\n\n    await this.jobService.createJob(\n      null,\n      JobType.BUILD_SNAPSHOT,\n      this.runner.id,\n      ResourceType.SNAPSHOT,\n      buildInfo.snapshotRef,\n      payload,\n    )\n\n    this.logger.debug(`Created BUILD_SNAPSHOT job for ${buildInfo.snapshotRef} on runner ${this.runner.id}`)\n  }\n\n  async pullSnapshot(\n    snapshotName: string,\n    registry?: DockerRegistry,\n    destinationRegistry?: DockerRegistry,\n    destinationRef?: string,\n    newTag?: string,\n  ): Promise<void> {\n    const payload: PullSnapshotRequestDTO = {\n      snapshot: snapshotName,\n      newTag,\n    }\n\n    if (registry) {\n      payload.registry = {\n        project: registry.project,\n        url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: registry.username,\n        password: registry.password,\n      }\n    }\n\n    if (destinationRegistry) {\n      payload.destinationRegistry = {\n        project: destinationRegistry.project,\n        url: destinationRegistry.url.replace(/^(https?:\\/\\/)/, ''),\n        username: destinationRegistry.username,\n        password: destinationRegistry.password,\n      }\n    }\n\n    if (destinationRef) {\n      payload.destinationRef = destinationRef\n    }\n\n    await this.jobService.createJob(\n      null,\n      JobType.PULL_SNAPSHOT,\n      this.runner.id,\n      ResourceType.SNAPSHOT,\n      destinationRef || snapshotName,\n      payload,\n    )\n\n    this.logger.debug(`Created PULL_SNAPSHOT job for ${snapshotName} on runner ${this.runner.id}`)\n  }\n\n  async removeSnapshot(snapshotName: string): Promise<void> {\n    await this.jobService.createJob(null, JobType.REMOVE_SNAPSHOT, this.runner.id, ResourceType.SNAPSHOT, snapshotName)\n\n    this.logger.debug(`Created REMOVE_SNAPSHOT job for ${snapshotName} on runner ${this.runner.id}`)\n  }\n\n  async snapshotExists(snapshotRef: string): Promise<boolean> {\n    // Find the latest job for this snapshot on this runner\n    // Do not include INSPECT_SNAPSHOT_IN_REGISTRY\n    const latestJob = await this.jobRepository.findOne({\n      where: [\n        {\n          runnerId: this.runner.id,\n          resourceType: ResourceType.SNAPSHOT,\n          resourceId: snapshotRef,\n          type: Not(JobType.INSPECT_SNAPSHOT_IN_REGISTRY),\n        },\n      ],\n      order: { createdAt: 'DESC' },\n    })\n\n    // If no job exists, snapshot doesn't exist\n    if (!latestJob) {\n      return false\n    }\n\n    // If the latest job is a REMOVE_SNAPSHOT, the snapshot no longer exists\n    if (latestJob.type === JobType.REMOVE_SNAPSHOT) {\n      return false\n    }\n\n    // If the latest job is PULL_SNAPSHOT or BUILD_SNAPSHOT, check if it completed successfully\n    if (latestJob.type === JobType.PULL_SNAPSHOT || latestJob.type === JobType.BUILD_SNAPSHOT) {\n      return latestJob.status === JobStatus.COMPLETED\n    }\n\n    // For any other job type, snapshot doesn't exist\n    return false\n  }\n\n  async getSnapshotInfo(snapshotRef: string): Promise<RunnerSnapshotInfo> {\n    const latestJob = await this.jobRepository.findOne({\n      where: [\n        {\n          runnerId: this.runner.id,\n          resourceType: ResourceType.SNAPSHOT,\n          resourceId: snapshotRef,\n          type: Not(JobType.INSPECT_SNAPSHOT_IN_REGISTRY),\n        },\n      ],\n      order: { createdAt: 'DESC' },\n    })\n\n    if (!latestJob) {\n      throw new Error(`Snapshot ${snapshotRef} not found on runner ${this.runner.id}`)\n    }\n\n    const metadata = latestJob.getResultMetadata()\n\n    switch (latestJob.status) {\n      case JobStatus.COMPLETED:\n        if (latestJob.type === JobType.PULL_SNAPSHOT || latestJob.type === JobType.BUILD_SNAPSHOT) {\n          return {\n            name: latestJob.resourceId,\n            sizeGB: metadata?.sizeGB,\n            entrypoint: metadata?.entrypoint,\n            cmd: metadata?.cmd,\n            hash: metadata?.hash,\n          }\n        }\n        throw new Error(\n          `Snapshot ${snapshotRef} is in an unknown state (${latestJob.status}) on runner ${this.runner.id}`,\n        )\n      case JobStatus.FAILED:\n        throw new SnapshotStateError(\n          latestJob.errorMessage || `Snapshot ${snapshotRef} failed on runner ${this.runner.id}`,\n        )\n      default:\n        throw new Error(\n          `Snapshot ${snapshotRef} is in an unknown state (${latestJob.status}) on runner ${this.runner.id}`,\n        )\n    }\n  }\n\n  async inspectSnapshotInRegistry(snapshotName: string, registry?: DockerRegistry): Promise<SnapshotDigestResponse> {\n    const payload: InspectSnapshotInRegistryRequest = {\n      snapshot: snapshotName,\n      registry: registry\n        ? {\n            project: registry.project,\n            url: registry.url.replace(/^(https?:\\/\\/)/, ''),\n            username: registry.username,\n            password: registry.password,\n          }\n        : undefined,\n    }\n\n    const job = await this.jobService.createJob(\n      null,\n      JobType.INSPECT_SNAPSHOT_IN_REGISTRY,\n      this.runner.id,\n      ResourceType.SNAPSHOT,\n      snapshotName,\n      payload,\n    )\n\n    this.logger.debug(`Created INSPECT_SNAPSHOT_IN_REGISTRY job for ${snapshotName} on runner ${this.runner.id}`)\n\n    const waitTimeout = 30 * 1000 // 30 seconds\n    const completedJob = await this.jobService.waitJobCompletion(job.id, waitTimeout)\n\n    if (!completedJob) {\n      throw new Error(`Snapshot ${snapshotName} not found in registry on runner ${this.runner.id}`)\n    }\n\n    if (completedJob.status !== JobStatus.COMPLETED) {\n      throw new Error(\n        `Snapshot ${snapshotName} failed to inspect in registry on runner ${this.runner.id}. Error: ${completedJob.errorMessage}`,\n      )\n    }\n\n    const resultMetadata = completedJob.getResultMetadata()\n\n    return {\n      hash: resultMetadata?.hash,\n      sizeGB: resultMetadata?.sizeGB,\n    }\n  }\n\n  async updateNetworkSettings(\n    sandboxId: string,\n    networkBlockAll?: boolean,\n    networkAllowList?: string,\n    networkLimitEgress?: boolean,\n  ): Promise<void> {\n    const payload: UpdateNetworkSettingsDTO = {\n      networkBlockAll: networkBlockAll,\n      networkAllowList: networkAllowList,\n      networkLimitEgress: networkLimitEgress,\n    }\n\n    await this.jobService.createJob(\n      null,\n      JobType.UPDATE_SANDBOX_NETWORK_SETTINGS,\n      this.runner.id,\n      ResourceType.SANDBOX,\n      sandboxId,\n      payload,\n    )\n\n    this.logger.debug(\n      `Created UPDATE_SANDBOX_NETWORK_SETTINGS job for sandbox ${sandboxId} on runner ${this.runner.id}`,\n    )\n  }\n\n  async resizeSandbox(sandboxId: string, cpu?: number, memory?: number, disk?: number): Promise<void> {\n    await this.jobService.createJob(null, JobType.RESIZE_SANDBOX, this.runner.id, ResourceType.SANDBOX, sandboxId, {\n      cpu,\n      memory,\n      disk,\n    })\n\n    this.logger.debug(`Created RESIZE_SANDBOX job for sandbox ${sandboxId} on runner ${this.runner.id}`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/sandbox.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { DataSource } from 'typeorm'\nimport { SandboxController } from './controllers/sandbox.controller'\nimport { SandboxService } from './services/sandbox.service'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { Sandbox } from './entities/sandbox.entity'\nimport { UserModule } from '../user/user.module'\nimport { RunnerService } from './services/runner.service'\nimport { Runner } from './entities/runner.entity'\nimport { RunnerController } from './controllers/runner.controller'\nimport { ToolboxService } from './services/toolbox.deprecated.service'\nimport { DockerRegistryModule } from '../docker-registry/docker-registry.module'\nimport { SandboxManager } from './managers/sandbox.manager'\nimport { ToolboxController } from './controllers/toolbox.deprecated.controller'\nimport { Snapshot } from './entities/snapshot.entity'\nimport { SnapshotController } from './controllers/snapshot.controller'\nimport { SnapshotService } from './services/snapshot.service'\nimport { SnapshotManager } from './managers/snapshot.manager'\nimport { SnapshotRunner } from './entities/snapshot-runner.entity'\nimport { DockerRegistry } from '../docker-registry/entities/docker-registry.entity'\nimport { RedisLockProvider } from './common/redis-lock.provider'\nimport { OrganizationModule } from '../organization/organization.module'\nimport { SandboxWarmPoolService } from './services/sandbox-warm-pool.service'\nimport { WarmPool } from './entities/warm-pool.entity'\nimport { PreviewController } from './controllers/preview.controller'\nimport { SnapshotSubscriber } from './subscribers/snapshot.subscriber'\nimport { VolumeController } from './controllers/volume.controller'\nimport { VolumeService } from './services/volume.service'\nimport { VolumeManager } from './managers/volume.manager'\nimport { Volume } from './entities/volume.entity'\nimport { BuildInfo } from './entities/build-info.entity'\nimport { BackupManager } from './managers/backup.manager'\nimport { VolumeSubscriber } from './subscribers/volume.subscriber'\nimport { RunnerSubscriber } from './subscribers/runner.subscriber'\nimport { WorkspaceController } from './controllers/workspace.deprecated.controller'\nimport { RunnerAdapterFactory } from './runner-adapter/runnerAdapter'\nimport { SandboxStartAction } from './managers/sandbox-actions/sandbox-start.action'\nimport { SandboxStopAction } from './managers/sandbox-actions/sandbox-stop.action'\nimport { SandboxDestroyAction } from './managers/sandbox-actions/sandbox-destroy.action'\nimport { SandboxArchiveAction } from './managers/sandbox-actions/sandbox-archive.action'\nimport { SshAccess } from './entities/ssh-access.entity'\nimport { SandboxRepository } from './repositories/sandbox.repository'\nimport { ProxyCacheInvalidationService } from './services/proxy-cache-invalidation.service'\nimport { RegionModule } from '../region/region.module'\nimport { Region } from '../region/entities/region.entity'\nimport { SnapshotRegion } from './entities/snapshot-region.entity'\nimport { JobController } from './controllers/job.controller'\nimport { JobService } from './services/job.service'\nimport { JobStateHandlerService } from './services/job-state-handler.service'\nimport { Job } from './entities/job.entity'\nimport { SandboxLookupCacheInvalidationService } from './services/sandbox-lookup-cache-invalidation.service'\nimport { SandboxAccessGuard } from './guards/sandbox-access.guard'\nimport { RunnerAccessGuard } from './guards/runner-access.guard'\nimport { RegionRunnerAccessGuard } from './guards/region-runner-access.guard'\nimport { RegionSandboxAccessGuard } from './guards/region-sandbox-access.guard'\nimport { ProxyGuard } from './guards/proxy.guard'\nimport { SshGatewayGuard } from './guards/ssh-gateway.guard'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\n\n@Module({\n  imports: [\n    UserModule,\n    DockerRegistryModule,\n    OrganizationModule,\n    RegionModule,\n    TypeOrmModule.forFeature([\n      Sandbox,\n      Runner,\n      Snapshot,\n      BuildInfo,\n      SnapshotRunner,\n      SnapshotRegion,\n      DockerRegistry,\n      WarmPool,\n      Volume,\n      SshAccess,\n      Region,\n      Job,\n    ]),\n  ],\n  controllers: [\n    SandboxController,\n    RunnerController,\n    ToolboxController,\n    SnapshotController,\n    WorkspaceController,\n    PreviewController,\n    VolumeController,\n    JobController,\n  ],\n  providers: [\n    SandboxService,\n    SandboxManager,\n    BackupManager,\n    SandboxWarmPoolService,\n    RunnerService,\n    ToolboxService,\n    SnapshotService,\n    ProxyCacheInvalidationService,\n    SandboxLookupCacheInvalidationService,\n    SnapshotManager,\n    RedisLockProvider,\n    SnapshotSubscriber,\n    VolumeService,\n    VolumeManager,\n    VolumeSubscriber,\n    RunnerSubscriber,\n    RunnerAdapterFactory,\n    SandboxStartAction,\n    SandboxStopAction,\n    SandboxDestroyAction,\n    SandboxArchiveAction,\n    JobService,\n    JobStateHandlerService,\n    SandboxAccessGuard,\n    RunnerAccessGuard,\n    RegionRunnerAccessGuard,\n    RegionSandboxAccessGuard,\n    ProxyGuard,\n    SshGatewayGuard,\n    {\n      provide: SandboxRepository,\n      inject: [DataSource, EventEmitter2, SandboxLookupCacheInvalidationService],\n      useFactory: (\n        dataSource: DataSource,\n        eventEmitter: EventEmitter2,\n        sandboxLookupCacheInvalidationService: SandboxLookupCacheInvalidationService,\n      ) => new SandboxRepository(dataSource, eventEmitter, sandboxLookupCacheInvalidationService),\n    },\n  ],\n  exports: [\n    SandboxService,\n    RunnerService,\n    RedisLockProvider,\n    SnapshotService,\n    VolumeService,\n    VolumeManager,\n    SandboxRepository,\n    RunnerAdapterFactory,\n  ],\n})\nexport class SandboxModule {}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/job-state-handler.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Repository } from 'typeorm'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { SnapshotRunner } from '../entities/snapshot-runner.entity'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\nimport { SnapshotRunnerState } from '../enums/snapshot-runner-state.enum'\nimport { JobStatus } from '../enums/job-status.enum'\nimport { JobType } from '../enums/job-type.enum'\nimport { Job } from '../entities/job.entity'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\nimport { sanitizeSandboxError } from '../utils/sanitize-error.util'\nimport { OrganizationUsageService } from '../../organization/services/organization-usage.service'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { ResourceType } from '../enums/resource-type.enum'\nimport { getStateChangeLockKey } from '../utils/lock-key.util'\n\n/**\n * Service for handling entity state updates based on job completion (v2 runners only).\n * This service listens to job status changes and updates entity states accordingly.\n */\n@Injectable()\nexport class JobStateHandlerService {\n  private readonly logger = new Logger(JobStateHandlerService.name)\n\n  constructor(\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    @InjectRepository(SnapshotRunner)\n    private readonly snapshotRunnerRepository: Repository<SnapshotRunner>,\n    private readonly organizationUsageService: OrganizationUsageService,\n    private readonly redisLockProvider: RedisLockProvider,\n  ) {}\n\n  /**\n   * Handle job completion and update entity state accordingly.\n   * Called when a job status is updated to COMPLETED or FAILED.\n   */\n  async handleJobCompletion(job: Job): Promise<void> {\n    if (job.status !== JobStatus.COMPLETED && job.status !== JobStatus.FAILED) {\n      return\n    }\n\n    if (!job.resourceId) {\n      return\n    }\n\n    switch (job.type) {\n      case JobType.CREATE_SANDBOX:\n        await this.handleCreateSandboxJobCompletion(job)\n        break\n      case JobType.START_SANDBOX:\n        await this.handleStartSandboxJobCompletion(job)\n        break\n      case JobType.STOP_SANDBOX:\n        await this.handleStopSandboxJobCompletion(job)\n        break\n      case JobType.DESTROY_SANDBOX:\n        await this.handleDestroySandboxJobCompletion(job)\n        break\n      case JobType.RESIZE_SANDBOX:\n        await this.handleResizeSandboxJobCompletion(job)\n        break\n      case JobType.PULL_SNAPSHOT:\n        await this.handlePullSnapshotJobCompletion(job)\n        break\n      case JobType.BUILD_SNAPSHOT:\n        await this.handleBuildSnapshotJobCompletion(job)\n        break\n      case JobType.REMOVE_SNAPSHOT:\n        await this.handleRemoveSnapshotJobCompletion(job)\n        break\n      case JobType.CREATE_BACKUP:\n        await this.handleCreateBackupJobCompletion(job)\n        break\n      case JobType.RECOVER_SANDBOX:\n        await this.handleRecoverSandboxJobCompletion(job)\n        break\n      default:\n        break\n    }\n\n    switch (job.resourceType) {\n      case ResourceType.SANDBOX: {\n        const lockKey = getStateChangeLockKey(job.resourceId)\n        this.redisLockProvider\n          .unlock(lockKey)\n          .catch((error) => this.logger.error(`Error unlocking Redis lock for sandbox ${job.resourceId}:`, error)) // Clean up lock after job completion\n        break\n      }\n      default:\n        break\n    }\n  }\n\n  private async handleCreateSandboxJobCompletion(job: Job): Promise<void> {\n    const sandboxId = job.resourceId\n    if (!sandboxId) return\n\n    try {\n      const sandbox = await this.sandboxRepository.findOne({ where: { id: sandboxId } })\n      if (!sandbox) {\n        this.logger.warn(`Sandbox ${sandboxId} not found for CREATE_SANDBOX job ${job.id}`)\n        return\n      }\n\n      if (sandbox.desiredState !== SandboxDesiredState.STARTED) {\n        this.logger.error(\n          `Sandbox ${sandboxId} is not in desired state STARTED for CREATE_SANDBOX job ${job.id}. Desired state: ${sandbox.desiredState}`,\n        )\n        return\n      }\n\n      const updateData: Partial<Sandbox> = {}\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(\n          `CREATE_SANDBOX job ${job.id} completed successfully, marking sandbox ${sandboxId} as STARTED`,\n        )\n        updateData.state = SandboxState.STARTED\n        updateData.errorReason = null\n        const metadata = job.getResultMetadata()\n        if (metadata?.daemonVersion && typeof metadata.daemonVersion === 'string') {\n          updateData.daemonVersion = metadata.daemonVersion\n        }\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`CREATE_SANDBOX job ${job.id} failed for sandbox ${sandboxId}: ${job.errorMessage}`)\n        updateData.state = SandboxState.ERROR\n        const { recoverable, errorReason } = sanitizeSandboxError(job.errorMessage)\n        updateData.errorReason = errorReason || 'Failed to create sandbox'\n        updateData.recoverable = recoverable\n      }\n\n      await this.sandboxRepository.update(sandboxId, { updateData, entity: sandbox })\n    } catch (error) {\n      this.logger.error(`Error handling CREATE_SANDBOX job completion for sandbox ${sandboxId}:`, error)\n    }\n  }\n\n  private async handleStartSandboxJobCompletion(job: Job): Promise<void> {\n    const sandboxId = job.resourceId\n    if (!sandboxId) return\n\n    try {\n      const sandbox = await this.sandboxRepository.findOne({ where: { id: sandboxId } })\n      if (!sandbox) {\n        this.logger.warn(`Sandbox ${sandboxId} not found for START_SANDBOX job ${job.id}`)\n        return\n      }\n\n      if (sandbox.desiredState !== SandboxDesiredState.STARTED) {\n        this.logger.error(\n          `Sandbox ${sandboxId} is not in desired state STARTED for START_SANDBOX job ${job.id}. Desired state: ${sandbox.desiredState}`,\n        )\n        return\n      }\n\n      const updateData: Partial<Sandbox> = {}\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(`START_SANDBOX job ${job.id} completed successfully, marking sandbox ${sandboxId} as STARTED`)\n        updateData.state = SandboxState.STARTED\n        updateData.errorReason = null\n        const metadata = job.getResultMetadata()\n        if (metadata?.daemonVersion && typeof metadata.daemonVersion === 'string') {\n          updateData.daemonVersion = metadata.daemonVersion\n        }\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`START_SANDBOX job ${job.id} failed for sandbox ${sandboxId}: ${job.errorMessage}`)\n        updateData.state = SandboxState.ERROR\n        const { recoverable, errorReason } = sanitizeSandboxError(job.errorMessage)\n        updateData.errorReason = errorReason || 'Failed to start sandbox'\n        updateData.recoverable = recoverable\n      }\n\n      await this.sandboxRepository.update(sandboxId, { updateData, entity: sandbox })\n    } catch (error) {\n      this.logger.error(`Error handling START_SANDBOX job completion for sandbox ${sandboxId}:`, error)\n    }\n  }\n\n  private async handleStopSandboxJobCompletion(job: Job): Promise<void> {\n    const sandboxId = job.resourceId\n    if (!sandboxId) return\n\n    try {\n      const sandbox = await this.sandboxRepository.findOne({ where: { id: sandboxId } })\n      if (!sandbox) {\n        this.logger.warn(`Sandbox ${sandboxId} not found for STOP_SANDBOX job ${job.id}`)\n        return\n      }\n\n      if (sandbox.desiredState !== SandboxDesiredState.STOPPED) {\n        this.logger.error(\n          `Sandbox ${sandboxId} is not in desired state STOPPED for STOP_SANDBOX job ${job.id}. Desired state: ${sandbox.desiredState}`,\n        )\n        return\n      }\n\n      const updateData: Partial<Sandbox> = {}\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(`STOP_SANDBOX job ${job.id} completed successfully, marking sandbox ${sandboxId} as STOPPED`)\n        updateData.state = SandboxState.STOPPED\n        updateData.errorReason = null\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`STOP_SANDBOX job ${job.id} failed for sandbox ${sandboxId}: ${job.errorMessage}`)\n        updateData.state = SandboxState.ERROR\n        const { recoverable, errorReason } = sanitizeSandboxError(job.errorMessage)\n        updateData.errorReason = errorReason || 'Failed to stop sandbox'\n        updateData.recoverable = recoverable\n      }\n\n      await this.sandboxRepository.update(sandboxId, { updateData, entity: sandbox })\n    } catch (error) {\n      this.logger.error(`Error handling STOP_SANDBOX job completion for sandbox ${sandboxId}:`, error)\n    }\n  }\n\n  private async handleDestroySandboxJobCompletion(job: Job): Promise<void> {\n    const sandboxId = job.resourceId\n    if (!sandboxId) return\n\n    try {\n      const sandbox = await this.sandboxRepository.findOne({ where: { id: sandboxId } })\n      if (!sandbox) {\n        this.logger.warn(`Sandbox ${sandboxId} not found for DESTROY_SANDBOX job ${job.id}`)\n        return\n      }\n      if (sandbox.desiredState !== SandboxDesiredState.DESTROYED) {\n        // Don't log anything because sandboxes can be destroyed on runners when archiving or moving to a new runner\n        return\n      }\n\n      const updateData: Partial<Sandbox> = {}\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(\n          `DESTROY_SANDBOX job ${job.id} completed successfully, marking sandbox ${sandboxId} as DESTROYED`,\n        )\n        updateData.state = SandboxState.DESTROYED\n        updateData.errorReason = null\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`DESTROY_SANDBOX job ${job.id} failed for sandbox ${sandboxId}: ${job.errorMessage}`)\n        updateData.state = SandboxState.ERROR\n        const { recoverable, errorReason } = sanitizeSandboxError(job.errorMessage)\n        updateData.errorReason = errorReason || 'Failed to destroy sandbox'\n        updateData.recoverable = recoverable\n      }\n\n      await this.sandboxRepository.update(sandboxId, { updateData, entity: sandbox })\n    } catch (error) {\n      this.logger.error(`Error handling DESTROY_SANDBOX job completion for sandbox ${sandboxId}:`, error)\n    }\n  }\n\n  private async handlePullSnapshotJobCompletion(job: Job): Promise<void> {\n    const snapshotRef = job.resourceId\n    const runnerId = job.runnerId\n    if (!snapshotRef || !runnerId) return\n\n    try {\n      const snapshotRunner = await this.snapshotRunnerRepository.findOne({\n        where: { snapshotRef, runnerId },\n      })\n\n      if (!snapshotRunner) {\n        this.logger.warn(`SnapshotRunner not found for snapshot ${snapshotRef} on runner ${runnerId}`)\n        return\n      }\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(\n          `PULL_SNAPSHOT job ${job.id} completed successfully, marking SnapshotRunner ${snapshotRunner.id} as READY`,\n        )\n        snapshotRunner.state = SnapshotRunnerState.READY\n        snapshotRunner.errorReason = null\n\n        // Check if this is the initial runner for a snapshot and update the snapshot state\n        const snapshot = await this.snapshotRepository.findOne({\n          where: { initialRunnerId: runnerId, ref: snapshotRef },\n        })\n        if (snapshot && (snapshot.state === SnapshotState.PULLING || snapshot.state === SnapshotState.BUILDING)) {\n          this.logger.debug(`Marking snapshot ${snapshot.id} as ACTIVE after initial pull completed`)\n          snapshot.state = SnapshotState.ACTIVE\n          snapshot.errorReason = null\n          snapshot.lastUsedAt = new Date()\n          await this.snapshotRepository.save(snapshot)\n        }\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`PULL_SNAPSHOT job ${job.id} failed for snapshot ${snapshotRef}: ${job.errorMessage}`)\n        snapshotRunner.state = SnapshotRunnerState.ERROR\n        snapshotRunner.errorReason = job.errorMessage || 'Failed to pull snapshot'\n\n        // Check if this is the initial runner for a snapshot and update the snapshot state\n        const snapshot = await this.snapshotRepository.findOne({\n          where: { initialRunnerId: runnerId, ref: snapshotRef },\n        })\n        if (snapshot && snapshot.state === SnapshotState.PULLING) {\n          this.logger.error(`Marking snapshot ${snapshot.id} as ERROR after initial pull failed`)\n          snapshot.state = SnapshotState.ERROR\n          snapshot.errorReason = job.errorMessage || 'Failed to pull snapshot on initial runner'\n          await this.snapshotRepository.save(snapshot)\n        }\n      }\n\n      await this.snapshotRunnerRepository.save(snapshotRunner)\n    } catch (error) {\n      this.logger.error(`Error handling PULL_SNAPSHOT job completion for snapshot ${snapshotRef}:`, error)\n    }\n  }\n\n  private async handleBuildSnapshotJobCompletion(job: Job): Promise<void> {\n    const snapshotRef = job.resourceId\n    const runnerId = job.runnerId\n    if (!snapshotRef || !runnerId) return\n\n    try {\n      // For BUILD_SNAPSHOT, find snapshot by buildInfo.snapshotRef\n      const snapshot = await this.snapshotRepository\n        .createQueryBuilder('snapshot')\n        .leftJoinAndSelect('snapshot.buildInfo', 'buildInfo')\n        .where('snapshot.initialRunnerId = :runnerId', { runnerId })\n        .andWhere('buildInfo.snapshotRef = :snapshotRef', { snapshotRef })\n        .getOne()\n\n      // Update SnapshotRunner state\n      const snapshotRunner = await this.snapshotRunnerRepository.findOne({\n        where: { snapshotRef, runnerId },\n      })\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(`BUILD_SNAPSHOT job ${job.id} completed successfully for snapshot ref ${snapshotRef}`)\n\n        if (snapshot?.state === SnapshotState.BUILDING) {\n          snapshot.state = SnapshotState.ACTIVE\n          snapshot.errorReason = null\n          snapshot.lastUsedAt = new Date()\n          await this.snapshotRepository.save(snapshot)\n          this.logger.debug(`Marked snapshot ${snapshot.id} as ACTIVE after build completed`)\n        }\n\n        if (snapshotRunner) {\n          snapshotRunner.state = SnapshotRunnerState.READY\n          snapshotRunner.errorReason = null\n          await this.snapshotRunnerRepository.save(snapshotRunner)\n        }\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`BUILD_SNAPSHOT job ${job.id} failed for snapshot ref ${snapshotRef}: ${job.errorMessage}`)\n\n        if (snapshot?.state === SnapshotState.BUILDING) {\n          snapshot.state = SnapshotState.ERROR\n          snapshot.errorReason = job.errorMessage || 'Failed to build snapshot'\n          await this.snapshotRepository.save(snapshot)\n        }\n\n        if (snapshotRunner) {\n          snapshotRunner.state = SnapshotRunnerState.ERROR\n          snapshotRunner.errorReason = job.errorMessage || 'Failed to build snapshot'\n          await this.snapshotRunnerRepository.save(snapshotRunner)\n        }\n      }\n    } catch (error) {\n      this.logger.error(`Error handling BUILD_SNAPSHOT job completion for snapshot ref ${snapshotRef}:`, error)\n    }\n  }\n\n  private async handleRemoveSnapshotJobCompletion(job: Job): Promise<void> {\n    const snapshotRef = job.resourceId\n    const runnerId = job.runnerId\n    if (!snapshotRef || !runnerId) return\n\n    try {\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(\n          `REMOVE_SNAPSHOT job ${job.id} completed successfully for snapshot ${snapshotRef} on runner ${runnerId}`,\n        )\n        const affected = await this.snapshotRunnerRepository.delete({ snapshotRef, runnerId })\n        if (affected.affected && affected.affected > 0) {\n          this.logger.debug(\n            `Removed ${affected.affected} snapshot runners for snapshot ${snapshotRef} on runner ${runnerId}`,\n          )\n        }\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(\n          `REMOVE_SNAPSHOT job ${job.id} failed for snapshot ${snapshotRef} on runner ${runnerId}: ${job.errorMessage}`,\n        )\n      }\n    } catch (error) {\n      this.logger.error(`Error handling REMOVE_SNAPSHOT job completion for snapshot ${snapshotRef}:`, error)\n    }\n  }\n\n  private async handleCreateBackupJobCompletion(job: Job): Promise<void> {\n    const sandboxId = job.resourceId\n    if (!sandboxId) return\n\n    try {\n      const sandbox = await this.sandboxRepository.findOne({ where: { id: sandboxId } })\n      if (!sandbox) {\n        this.logger.warn(`Sandbox ${sandboxId} not found for CREATE_BACKUP job ${job.id}`)\n        return\n      }\n\n      const updateData: Partial<Sandbox> = {}\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(\n          `CREATE_BACKUP job ${job.id} completed successfully, marking sandbox ${sandboxId} as BACKUP_COMPLETED`,\n        )\n        Object.assign(updateData, Sandbox.getBackupStateUpdate(sandbox, BackupState.COMPLETED))\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`CREATE_BACKUP job ${job.id} failed for sandbox ${sandboxId}: ${job.errorMessage}`)\n        Object.assign(\n          updateData,\n          Sandbox.getBackupStateUpdate(sandbox, BackupState.ERROR, undefined, undefined, job.errorMessage),\n        )\n      }\n\n      await this.sandboxRepository.update(sandboxId, { updateData, entity: sandbox })\n    } catch (error) {\n      this.logger.error(`Error handling CREATE_BACKUP job completion for sandbox ${sandboxId}:`, error)\n    }\n  }\n\n  private async handleRecoverSandboxJobCompletion(job: Job): Promise<void> {\n    const sandboxId = job.resourceId\n    if (!sandboxId) return\n\n    try {\n      const sandbox = await this.sandboxRepository.findOne({ where: { id: sandboxId } })\n      if (!sandbox) {\n        this.logger.warn(`Sandbox ${sandboxId} not found for RECOVER_SANDBOX job ${job.id}`)\n        return\n      }\n\n      if (sandbox.desiredState !== SandboxDesiredState.STARTED) {\n        this.logger.error(\n          `Sandbox ${sandboxId} is not in desired state STARTED for RECOVER_SANDBOX job ${job.id}. Desired state: ${sandbox.desiredState}`,\n        )\n        return\n      }\n\n      const updateData: Partial<Sandbox> = {}\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(\n          `RECOVER_SANDBOX job ${job.id} completed successfully, marking sandbox ${sandboxId} as STARTED`,\n        )\n        updateData.state = SandboxState.STARTED\n        updateData.errorReason = null\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`RECOVER_SANDBOX job ${job.id} failed for sandbox ${sandboxId}: ${job.errorMessage}`)\n        updateData.state = SandboxState.ERROR\n        updateData.errorReason = job.errorMessage || 'Failed to recover sandbox'\n      }\n\n      await this.sandboxRepository.update(sandboxId, { updateData, entity: sandbox })\n    } catch (error) {\n      this.logger.error(`Error handling RECOVER_SANDBOX job completion for sandbox ${sandboxId}:`, error)\n    }\n  }\n\n  private async handleResizeSandboxJobCompletion(job: Job): Promise<void> {\n    const sandboxId = job.resourceId\n    if (!sandboxId) return\n\n    try {\n      const sandbox = await this.sandboxRepository.findOne({ where: { id: sandboxId } })\n      if (!sandbox) {\n        this.logger.warn(`Sandbox ${sandboxId} not found for RESIZE_SANDBOX job ${job.id}`)\n        return\n      }\n\n      if (sandbox.state !== SandboxState.RESIZING) {\n        this.logger.warn(\n          `Sandbox ${sandboxId} is not in RESIZING state for RESIZE_SANDBOX job ${job.id}. State: ${sandbox.state}`,\n        )\n        return\n      }\n\n      // Determine the previous state (STARTED or STOPPED based on desiredState)\n      const previousState =\n        sandbox.desiredState === SandboxDesiredState.STARTED\n          ? SandboxState.STARTED\n          : sandbox.desiredState === SandboxDesiredState.STOPPED\n            ? SandboxState.STOPPED\n            : null\n\n      if (!previousState) {\n        this.logger.error(\n          `Sandbox ${sandboxId} has unexpected desiredState ${sandbox.desiredState} for RESIZE_SANDBOX job ${job.id}`,\n        )\n        return\n      }\n\n      // Calculate deltas before updating sandbox\n      const payload = job.payload as { cpu?: number; memory?: number; disk?: number }\n\n      // For cold resize (previousState === STOPPED), cpu/memory don't affect org quota.\n      const isHotResize = previousState === SandboxState.STARTED\n      const cpuDeltaForQuota = isHotResize ? (payload.cpu ?? sandbox.cpu) - sandbox.cpu : 0\n      const memDeltaForQuota = isHotResize ? (payload.memory ?? sandbox.mem) - sandbox.mem : 0\n      const diskDeltaForQuota = (payload.disk ?? sandbox.disk) - sandbox.disk // Disk only increases\n\n      const updateData: Partial<Sandbox> = {}\n\n      if (job.status === JobStatus.COMPLETED) {\n        this.logger.debug(`RESIZE_SANDBOX job ${job.id} completed successfully for sandbox ${sandboxId}`)\n\n        // Update sandbox resources\n        updateData.cpu = payload.cpu ?? sandbox.cpu\n        updateData.mem = payload.memory ?? sandbox.mem\n        updateData.disk = payload.disk ?? sandbox.disk\n        updateData.state = previousState\n\n        // Apply usage change (handles both positive and negative deltas)\n        await this.organizationUsageService.applyResizeUsageChange(\n          sandbox.organizationId,\n          sandbox.region,\n          cpuDeltaForQuota,\n          memDeltaForQuota,\n          diskDeltaForQuota,\n        )\n        return\n      } else if (job.status === JobStatus.FAILED) {\n        this.logger.error(`RESIZE_SANDBOX job ${job.id} failed for sandbox ${sandboxId}: ${job.errorMessage}`)\n\n        // Rollback pending usage (all deltas were tracked, including negative)\n        await this.organizationUsageService.decrementPendingSandboxUsage(\n          sandbox.organizationId,\n          sandbox.region,\n          cpuDeltaForQuota !== 0 ? cpuDeltaForQuota : undefined,\n          memDeltaForQuota !== 0 ? memDeltaForQuota : undefined,\n          diskDeltaForQuota !== 0 ? diskDeltaForQuota : undefined,\n        )\n\n        updateData.state = previousState\n      }\n\n      await this.sandboxRepository.update(sandboxId, { updateData, entity: sandbox })\n    } catch (error) {\n      this.logger.error(`Error handling RESIZE_SANDBOX job completion for sandbox ${sandboxId}:`, error)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/job.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ConflictException, Injectable, Logger, NotFoundException } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Repository, LessThan, EntityManager } from 'typeorm'\nimport { Job } from '../entities/job.entity'\nimport { JobDto, JobStatus, JobType, ResourceType } from '../dto/job.dto'\nimport { ResourceTypeForJobType } from '../dto/job-type-map.dto'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { JobStateHandlerService } from './job-state-handler.service'\nimport { propagation, context as otelContext } from '@opentelemetry/api'\nimport { PaginatedList } from '../../common/interfaces/paginated-list.interface'\n\nconst REDIS_BLOCKING_COMMAND_TIMEOUT_BUFFER_MS = 3_000\n\n@Injectable()\nexport class JobService {\n  private readonly logger = new Logger(JobService.name)\n  private readonly REDIS_JOB_QUEUE_PREFIX = 'runner:jobs:'\n\n  constructor(\n    @InjectRepository(Job)\n    private readonly jobRepository: Repository<Job>,\n    @InjectRedis() private readonly redis: Redis,\n    private readonly jobStateHandlerService: JobStateHandlerService,\n  ) {}\n\n  /**\n   * Create a job within the provided transaction manager\n   * If manager is null, uses the default repository (for non-transactional operations)\n   * @template T The JobType enum value - ensures compile-time type safety for resourceType and payload\n   */\n  async createJob<T extends JobType>(\n    manager: EntityManager | null,\n    type: T,\n    runnerId: string,\n    resourceType: ResourceTypeForJobType<T>,\n    resourceId: string,\n    payload?: string | Record<string, any>,\n  ): Promise<Job> {\n    // Use provided manager if available, otherwise use default repository\n    const repo = manager ? manager.getRepository(Job) : this.jobRepository\n\n    // Capture current OpenTelemetry trace context for distributed tracing\n    const traceContext = this.captureTraceContext()\n\n    const encodedPayload = typeof payload === 'string' ? payload : payload ? JSON.stringify(payload) : undefined\n\n    try {\n      const job = new Job({\n        type,\n        runnerId,\n        resourceType,\n        resourceId,\n        status: JobStatus.PENDING,\n        payload: encodedPayload,\n        traceContext,\n      })\n\n      await repo.insert(job)\n\n      // Log with context-specific info\n      const contextInfo = resourceId ? `${resourceType} ${resourceId}` : 'N/A'\n\n      this.logger.debug(`Created job ${job.id} of type ${type} for ${contextInfo} on runner ${runnerId}`)\n\n      // Notify runner via Redis - happens outside transaction\n      // If transaction rolls back, notification is harmless (runner will poll and find nothing)\n      await this.notifyRunner(runnerId, job.id)\n\n      return job\n    } catch (error) {\n      if (error.code === '23505') {\n        if (error.constraint === 'IDX_UNIQUE_INCOMPLETE_JOB') {\n          this.logger.error(`An incomplete job already exists for ${resourceType} ${resourceId} on runner ${runnerId}`)\n        }\n        throw new ConflictException('An operation is already in progress for this resource')\n      }\n      this.logger.error(`Error creating job: ${error}`)\n      throw error\n    }\n  }\n\n  private async notifyRunner(runnerId: string, jobId: string): Promise<void> {\n    try {\n      await this.redis.lpush(this.getRunnerQueueKey(runnerId), jobId)\n      this.logger.debug(`Notified runner ${runnerId} about job ${jobId} via Redis`)\n    } catch (error) {\n      this.logger.warn(`Failed to notify runner ${runnerId} via Redis: ${error.message}`)\n      // Job is still in DB, runner will pick it up via fallback polling\n    }\n  }\n\n  async findOne(jobId: string): Promise<Job | null> {\n    return this.jobRepository.findOneBy({ id: jobId })\n  }\n\n  async pollJobs(runnerId: string, limit = 10, timeoutSeconds = 30, abortSignal?: AbortSignal): Promise<JobDto[]> {\n    const queueKey = this.getRunnerQueueKey(runnerId)\n    const maxTimeout = Math.min(timeoutSeconds, 60) // Max 60 seconds\n\n    // Check if already aborted\n    if (abortSignal?.aborted) {\n      this.logger.debug(`Poll request for runner ${runnerId} was already aborted`)\n      return []\n    }\n\n    // STEP 1: Atomically claim pending jobs from database\n    // This prevents duplicates by updating status to IN_PROGRESS\n    let claimedJobs = await this.claimPendingJobs(runnerId, limit)\n\n    if (claimedJobs.length > 0) {\n      // Clear any stale job IDs from Redis queue\n      try {\n        await this.redis.del(queueKey)\n      } catch (error) {\n        this.logger.warn(`Failed to clear Redis queue: ${error.message}`)\n      }\n\n      return claimedJobs\n    }\n\n    // STEP 2: No existing jobs - wait for notification via Redis BRPOP\n    // Create a new dedicated Redis client for this BRPOP to support concurrent polling from multiple runners\n    // Each runner gets its own connection, preventing blocking issues\n    let blockingClient: Redis | null = null\n    try {\n      this.logger.debug(`No existing jobs, runner ${runnerId} starting BRPOP with timeout ${maxTimeout}s`)\n\n      blockingClient = this.redis.duplicate({\n        commandTimeout: maxTimeout * 1000 + REDIS_BLOCKING_COMMAND_TIMEOUT_BUFFER_MS,\n        retryStrategy: () => null,\n      })\n\n      // Wrap BRPOP in a promise that can be aborted\n      const brpopPromise = blockingClient.brpop(queueKey, maxTimeout)\n\n      let result: [string, string] | null = null\n      if (abortSignal) {\n        // Race between BRPOP and abort signal\n        result = await Promise.race([\n          brpopPromise,\n          new Promise<null>((resolve) => {\n            if (abortSignal.aborted) {\n              resolve(null)\n            } else {\n              abortSignal.addEventListener('abort', () => resolve(null), { once: true })\n            }\n          }),\n        ])\n\n        // If aborted, disconnect immediately to cancel BRPOP\n        if (abortSignal.aborted) {\n          this.logger.debug(`BRPOP aborted for runner ${runnerId}, closing Redis connection`)\n          blockingClient.disconnect()\n          return []\n        }\n      } else {\n        result = await brpopPromise\n      }\n\n      if (result) {\n        // Got notification - job(s) available\n        // Clear the entire queue (job IDs are just hints, not used directly)\n        this.logger.debug(`Got notification from Redis for runner ${runnerId}`)\n\n        try {\n          await this.redis.del(queueKey)\n        } catch (error) {\n          this.logger.warn(`Failed to clear Redis queue: ${error.message}`)\n        }\n\n        // Atomically claim jobs from database\n        claimedJobs = await this.claimPendingJobs(runnerId, limit)\n\n        if (claimedJobs.length > 0) {\n          this.logger.debug(`Claimed ${claimedJobs.length} jobs after Redis notification for runner ${runnerId}`)\n          return claimedJobs\n        }\n\n        // Notification received but no jobs found - possible race condition\n        this.logger.warn(`Received Redis notification but no pending jobs found for runner ${runnerId}`)\n      } else {\n        // BRPOP timeout - no jobs received\n        this.logger.debug(`BRPOP timeout for runner ${runnerId}, no new jobs`)\n      }\n    } catch (error) {\n      this.logger.error(`Redis BRPOP error for runner ${runnerId}: ${error.message}`)\n      // Fall through to database polling fallback\n    } finally {\n      // Always close the blocking client to prevent connection leaks\n      if (blockingClient) {\n        try {\n          blockingClient.disconnect()\n        } catch (error) {\n          this.logger.warn(`Failed to disconnect blocking Redis client for runner ${runnerId}: ${error.message}`)\n        }\n      }\n    }\n\n    // STEP 3: Final fallback - check database again\n    // This handles race conditions and Redis failures\n    claimedJobs = await this.claimPendingJobs(runnerId, limit)\n\n    if (claimedJobs.length > 0) {\n      this.logger.debug(`Claimed ${claimedJobs.length} pending jobs in fallback for runner ${runnerId}`)\n    }\n\n    return claimedJobs\n  }\n\n  async updateJobStatus(\n    jobId: string,\n    status: JobStatus,\n    errorMessage?: string,\n    resultMetadata?: string,\n  ): Promise<Job> {\n    const job = await this.findOne(jobId)\n    if (!job) {\n      throw new NotFoundException(`Job with ID ${jobId} not found`)\n    }\n\n    if (!this.isValidStatusTransition(job.status, status)) {\n      throw new ConflictException(`Invalid job status transition from ${job.status} to ${status} for job ${jobId}`)\n    }\n\n    job.status = status\n    if (errorMessage) {\n      job.errorMessage = errorMessage\n    }\n\n    if (status === JobStatus.IN_PROGRESS && !job.startedAt) {\n      job.startedAt = new Date()\n    }\n\n    if (status === JobStatus.COMPLETED || status === JobStatus.FAILED) {\n      job.completedAt = new Date()\n    }\n\n    if (resultMetadata) {\n      job.resultMetadata = resultMetadata\n    }\n\n    const updatedJob = await this.jobRepository.save(job)\n    this.logger.debug(`Updated job ${jobId} status to ${status}`)\n\n    // Handle job completion for v2 runners - update sandbox/snapshot/backup state\n    if (status === JobStatus.COMPLETED || status === JobStatus.FAILED) {\n      // Fire and forget - don't block the response\n      this.jobStateHandlerService.handleJobCompletion(updatedJob).catch((error) => {\n        this.logger.error(`Error handling job completion for job ${jobId}:`, error)\n      })\n    }\n\n    return updatedJob\n  }\n\n  async findPendingJobsForRunner(runnerId: string, limit = 10): Promise<Job[]> {\n    return this.jobRepository.find({\n      where: {\n        runnerId,\n        status: JobStatus.PENDING,\n      },\n      order: {\n        createdAt: 'ASC',\n      },\n      take: limit,\n    })\n  }\n\n  async findJobsForRunner(runnerId: string, status?: JobStatus, page = 1, limit = 100): Promise<PaginatedList<JobDto>> {\n    const whereCondition: { runnerId: string; status?: JobStatus } = { runnerId }\n\n    if (status) {\n      whereCondition.status = status\n    }\n\n    const [jobs, total] = await this.jobRepository.findAndCount({\n      where: whereCondition,\n      order: {\n        createdAt: 'DESC',\n      },\n      skip: (page - 1) * limit,\n      take: limit,\n    })\n\n    return {\n      items: jobs.map((job) => new JobDto(job)),\n      total,\n      page,\n      totalPages: Math.ceil(total / limit),\n    }\n  }\n\n  async findJobsBySandboxId(sandboxId: string): Promise<Job[]> {\n    return this.findJobsByResourceId(ResourceType.SANDBOX, sandboxId)\n  }\n\n  async findJobsByResourceId(resourceType: ResourceType, resourceId: string): Promise<Job[]> {\n    return this.jobRepository.find({\n      where: {\n        resourceType,\n        resourceId,\n      },\n      order: {\n        createdAt: 'DESC',\n      },\n    })\n  }\n\n  async waitJobCompletion(jobId: string, waitTimeout: number): Promise<Job | null> {\n    const startTime = Date.now()\n    const endTime = startTime + waitTimeout\n\n    while (Date.now() < endTime) {\n      const job = await this.findOne(jobId)\n      if (!job) {\n        return null\n      }\n\n      if (job.status === JobStatus.COMPLETED || job.status === JobStatus.FAILED) {\n        return job\n      }\n\n      await new Promise((resolve) => setTimeout(resolve, 100))\n    }\n\n    throw new Error(`Job ${jobId} timed out after ${waitTimeout}ms`)\n  }\n\n  /**\n   * Captures the current OpenTelemetry trace context in W3C Trace Context format\n   * This allows distributed tracing across the API and runner services\n   * @returns A map of trace context headers (traceparent, tracestate)\n   */\n  private captureTraceContext(): Record<string, string> | null {\n    try {\n      const carrier: Record<string, string> = {}\n\n      // Extract current trace context into carrier object using W3C Trace Context format\n      propagation.inject(otelContext.active(), carrier)\n\n      // Return the carrier if it contains trace information\n      if (Object.keys(carrier).length > 0) {\n        this.logger.debug(`Captured trace context: ${JSON.stringify(carrier)}`)\n        return carrier\n      }\n    } catch (error) {\n      this.logger.warn(`Failed to capture trace context: ${error.message}`)\n    }\n\n    return null\n  }\n\n  private isValidStatusTransition(currentStatus: JobStatus, newStatus: JobStatus): boolean {\n    if (currentStatus === newStatus) {\n      return true\n    }\n\n    const allowedTransitions: Record<JobStatus, JobStatus[]> = {\n      [JobStatus.PENDING]: [JobStatus.IN_PROGRESS, JobStatus.FAILED],\n      [JobStatus.IN_PROGRESS]: [JobStatus.COMPLETED, JobStatus.FAILED],\n      [JobStatus.COMPLETED]: [],\n      [JobStatus.FAILED]: [],\n    }\n\n    return allowedTransitions[currentStatus]?.includes(newStatus) ?? false\n  }\n\n  private getRunnerQueueKey(runnerId: string): string {\n    return `${this.REDIS_JOB_QUEUE_PREFIX}${runnerId}`\n  }\n\n  /**\n   * Cron job to check for stale jobs and mark them as failed\n   * Runs every minute to find jobs that have been IN_PROGRESS for too long\n   */\n  @Cron(CronExpression.EVERY_MINUTE)\n  async handleStaleJobs(): Promise<void> {\n    const staleThresholdMinutes = 10\n    const staleThreshold = new Date(Date.now() - staleThresholdMinutes * 60 * 1000)\n\n    try {\n      // Find jobs that are IN_PROGRESS but haven't been updated in the threshold time\n      const staleJobs = await this.jobRepository.find({\n        where: {\n          status: JobStatus.IN_PROGRESS,\n          updatedAt: LessThan(staleThreshold),\n        },\n      })\n\n      if (staleJobs.length === 0) {\n        return\n      }\n\n      this.logger.warn(`Found ${staleJobs.length} stale jobs, marking as failed`)\n\n      // Mark each stale job as failed with timeout error\n      for (const job of staleJobs) {\n        try {\n          await this.updateJobStatus(\n            job.id,\n            JobStatus.FAILED,\n            `Job timed out - no update received for ${staleThresholdMinutes} minutes`,\n          )\n\n          this.logger.warn(\n            `Marked job ${job.id} (type: ${job.type}, resource: ${job.resourceType} ${job.resourceId}) as failed due to timeout`,\n          )\n        } catch (error) {\n          this.logger.error(`Error marking job ${job.id} as failed: ${error.message}`, error.stack)\n        }\n      }\n    } catch (error) {\n      this.logger.error(`Error handling stale jobs: ${error.message}`, error.stack)\n    }\n  }\n\n  /**\n   * Atomically claim pending jobs by updating their status to IN_PROGRESS\n   * This prevents duplicate processing of the same job\n   */\n  private async claimPendingJobs(runnerId: string, limit: number): Promise<JobDto[]> {\n    // Find pending jobs\n    const jobs = await this.jobRepository.find({\n      where: {\n        runnerId,\n        status: JobStatus.PENDING,\n      },\n      order: {\n        createdAt: 'ASC',\n      },\n      take: limit,\n    })\n\n    if (jobs.length === 0) {\n      return []\n    }\n\n    // Update jobs to IN_PROGRESS\n    const now = new Date()\n    const claimedJobs: JobDto[] = []\n\n    for (const job of jobs) {\n      try {\n        job.status = JobStatus.IN_PROGRESS\n        job.startedAt = now\n        job.updatedAt = now\n\n        // save() with @VersionColumn will automatically check version and throw OptimisticLockVersionMismatchError if changed\n        const savedJob = await this.jobRepository.save(job)\n\n        claimedJobs.push(new JobDto(savedJob))\n      } catch (error) {\n        // If optimistic lock fails, job was already claimed by another runner - skip it\n        this.logger.debug(`Job ${job.id} already claimed by another runner (version mismatch)`)\n      }\n    }\n\n    if (claimedJobs.length > 0) {\n      this.logger.debug(`Claimed ${claimedJobs.length} existing pending jobs for runner ${runnerId}`)\n    }\n\n    return claimedJobs\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/proxy-cache-invalidation.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Injectable, Logger } from '@nestjs/common'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport Redis from 'ioredis'\n\nimport { SandboxEvents } from '../constants/sandbox-events.constants'\nimport { SandboxArchivedEvent } from '../events/sandbox-archived.event'\n\n@Injectable()\nexport class ProxyCacheInvalidationService {\n  private readonly logger = new Logger(ProxyCacheInvalidationService.name)\n  private static readonly RUNNER_INFO_CACHE_PREFIX = 'proxy:sandbox-runner-info:'\n\n  constructor(@InjectRedis() private readonly redis: Redis) {}\n\n  @OnEvent(SandboxEvents.ARCHIVED)\n  async handleSandboxArchived(event: SandboxArchivedEvent): Promise<void> {\n    await this.invalidateRunnerCache(event.sandbox.id)\n  }\n\n  private async invalidateRunnerCache(sandboxId: string): Promise<void> {\n    try {\n      await this.redis.del(`${ProxyCacheInvalidationService.RUNNER_INFO_CACHE_PREFIX}${sandboxId}`)\n      this.logger.debug(`Invalidated sandbox runner cache for ${sandboxId}`)\n    } catch (error) {\n      this.logger.warn(`Failed to invalidate runner cache for sandbox ${sandboxId}: ${error.message}`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/runner.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  BadRequestException,\n  ConflictException,\n  HttpException,\n  HttpStatus,\n  Inject,\n  Injectable,\n  Logger,\n  NotFoundException,\n} from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { DataSource, FindOptionsWhere, In, MoreThanOrEqual, Not, Repository, UpdateResult } from 'typeorm'\nimport { Runner } from '../entities/runner.entity'\nimport { CreateRunnerInternalDto } from '../dto/create-runner-internal.dto'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\nimport { RunnerState } from '../enums/runner-state.enum'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { SnapshotRunner } from '../entities/snapshot-runner.entity'\nimport { SnapshotRunnerState } from '../enums/snapshot-runner-state.enum'\nimport { RunnerSnapshotDto } from '../dto/runner-snapshot.dto'\nimport { RunnerAdapterFactory, RunnerInfo } from '../runner-adapter/runnerAdapter'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\nimport { RegionService } from '../../region/services/region.service'\nimport { RUNNER_NAME_REGEX } from '../constants/runner-name-regex.constant'\nimport { RegionType } from '../../region/enums/region-type.enum'\nimport { RunnerDto } from '../dto/runner.dto'\nimport { RunnerEvents } from '../constants/runner-events'\nimport { RunnerStateUpdatedEvent } from '../events/runner-state-updated.event'\nimport { RunnerDeletedEvent } from '../events/runner-deleted.event'\nimport { generateApiKeyValue } from '../../common/utils/api-key'\nimport { RunnerFullDto } from '../dto/runner-full.dto'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport Redis from 'ioredis'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\nimport { runnerLookupCacheKeyById, RUNNER_LOOKUP_CACHE_TTL_MS } from '../utils/runner-lookup-cache.util'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport { RunnerServiceInfo } from '../common/runner-service-info'\n\n@Injectable()\nexport class RunnerService {\n  private readonly logger = new Logger(RunnerService.name)\n  private readonly serviceStartTime = new Date()\n  private readonly scoreConfig: AvailabilityScoreConfig\n\n  constructor(\n    @InjectRepository(Runner)\n    private readonly runnerRepository: Repository<Runner>,\n    private readonly runnerAdapterFactory: RunnerAdapterFactory,\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(SnapshotRunner)\n    private readonly snapshotRunnerRepository: Repository<SnapshotRunner>,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly configService: TypedConfigService,\n    private readonly regionService: RegionService,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    @Inject(EventEmitter2)\n    private eventEmitter: EventEmitter2,\n    private readonly dataSource: DataSource,\n    @InjectRedis()\n    private readonly redis: Redis,\n  ) {\n    this.scoreConfig = this.getAvailabilityScoreConfig()\n  }\n\n  /**\n   * @throws {BadRequestException} If the runner name or class is invalid.\n   * @throws {NotFoundException} If the region is not found.\n   * @throws {ConflictException} If a runner with the same values already exists.\n   */\n  async create(createRunnerDto: CreateRunnerInternalDto): Promise<{\n    runner: Runner\n    apiKey: string\n  }> {\n    if (!RUNNER_NAME_REGEX.test(createRunnerDto.name)) {\n      throw new BadRequestException('Runner name must contain only letters, numbers, underscores, periods, and hyphens')\n    }\n    if (createRunnerDto.name.length < 2 || createRunnerDto.name.length > 255) {\n      throw new BadRequestException('Runner name must be between 3 and 255 characters')\n    }\n\n    const apiKey = createRunnerDto.apiKey ?? generateApiKeyValue()\n\n    let runner: Runner\n\n    switch (createRunnerDto.apiVersion) {\n      case '0':\n        runner = new Runner({\n          region: createRunnerDto.regionId,\n          name: createRunnerDto.name,\n          apiVersion: createRunnerDto.apiVersion,\n          apiKey: apiKey,\n          cpu: createRunnerDto.cpu,\n          memoryGiB: createRunnerDto.memoryGiB,\n          diskGiB: createRunnerDto.diskGiB,\n          domain: createRunnerDto.domain,\n          apiUrl: createRunnerDto.apiUrl,\n          proxyUrl: createRunnerDto.proxyUrl,\n          appVersion: createRunnerDto.appVersion,\n        })\n        break\n      case '2':\n        runner = new Runner({\n          region: createRunnerDto.regionId,\n          name: createRunnerDto.name,\n          apiVersion: createRunnerDto.apiVersion,\n          apiKey: apiKey,\n          appVersion: createRunnerDto.appVersion,\n        })\n        break\n      default:\n        throw new BadRequestException('Invalid runner version')\n    }\n\n    try {\n      const savedRunner = await this.runnerRepository.save(runner)\n      this.invalidateRunnerCache(savedRunner.id)\n      return { runner: savedRunner, apiKey }\n    } catch (error) {\n      if (error.code === '23505') {\n        if (error.detail.includes('domain')) {\n          throw new ConflictException('This domain is already in use')\n        }\n        if (error.detail.includes('name')) {\n          throw new ConflictException(`Runner with name ${createRunnerDto.name} already exists in this region`)\n        }\n        throw new ConflictException('A runner with these values already exists')\n      }\n      throw error\n    }\n  }\n\n  async findAllFull(): Promise<RunnerFullDto[]> {\n    const runners = await this.runnerRepository.find()\n\n    const regionIds = new Set(runners.map((runner) => runner.region))\n    const regions = await this.regionService.findByIds(Array.from(regionIds))\n\n    const regionTypeMap = new Map<string, RegionType>()\n    regions.forEach((region) => {\n      regionTypeMap.set(region.id, region.regionType)\n    })\n\n    return runners.map((runner) => RunnerFullDto.fromRunner(runner, regionTypeMap.get(runner.region)))\n  }\n\n  async findAllByRegion(regionId: string): Promise<RunnerDto[]> {\n    const runners = await this.runnerRepository.find({\n      where: {\n        region: regionId,\n      },\n    })\n\n    return runners.map(RunnerDto.fromRunner)\n  }\n\n  async findAllByRegionFull(regionId: string): Promise<RunnerFullDto[]> {\n    const runners = await this.runnerRepository.find({\n      where: {\n        region: regionId,\n      },\n    })\n\n    const region = await this.regionService.findOne(regionId)\n\n    return runners.map((runner) => RunnerFullDto.fromRunner(runner, region?.regionType))\n  }\n\n  async findAllByOrganization(organizationId: string, regionType?: RegionType): Promise<RunnerDto[]> {\n    const regions = await this.regionService.findAllByOrganization(organizationId, regionType)\n    const regionIds = regions.map((region) => region.id)\n\n    const runners = await this.runnerRepository.find({\n      where: {\n        region: In(regionIds),\n      },\n    })\n\n    return runners.map(RunnerDto.fromRunner)\n  }\n\n  async findDrainingPaginated(skip: number, take: number): Promise<Runner[]> {\n    return this.runnerRepository.find({\n      where: {\n        draining: true,\n        state: Not(RunnerState.DECOMMISSIONED),\n      },\n      order: {\n        id: 'ASC',\n      },\n      skip,\n      take,\n    })\n  }\n\n  async findAllReady(): Promise<Runner[]> {\n    return this.runnerRepository.find({\n      where: {\n        state: RunnerState.READY,\n      },\n    })\n  }\n\n  async findOne(id: string): Promise<Runner | null> {\n    return this.runnerRepository.findOne({\n      where: { id },\n      cache: {\n        id: runnerLookupCacheKeyById(id),\n        milliseconds: RUNNER_LOOKUP_CACHE_TTL_MS,\n      },\n    })\n  }\n\n  async findOneOrFail(id: string): Promise<Runner> {\n    const runner = await this.findOne(id)\n    if (!runner) {\n      throw new NotFoundException(`Runner with ID ${id} not found`)\n    }\n    return runner\n  }\n\n  async findOneFullOrFail(id: string): Promise<RunnerFullDto> {\n    const runner = await this.findOneOrFail(id)\n    const region = await this.regionService.findOne(runner.region)\n\n    return RunnerFullDto.fromRunner(runner, region?.regionType)\n  }\n\n  async findOneByDomain(domain: string): Promise<Runner | null> {\n    return this.runnerRepository.findOneBy({ domain })\n  }\n\n  async findByIds(runnerIds: string[]): Promise<Runner[]> {\n    if (runnerIds.length === 0) {\n      return []\n    }\n\n    return this.runnerRepository.find({\n      where: { id: In(runnerIds) },\n    })\n  }\n\n  async findByApiKey(apiKey: string): Promise<Runner | null> {\n    return this.runnerRepository.findOneBy({ apiKey })\n  }\n\n  async findBySandboxId(sandboxId: string): Promise<Runner | null> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: { id: sandboxId, state: Not(SandboxState.DESTROYED) },\n      select: ['runnerId'],\n    })\n    if (!sandbox) {\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n    if (!sandbox.runnerId) {\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} does not have a runner`)\n    }\n\n    return this.findOne(sandbox.runnerId)\n  }\n\n  async getRegionId(runnerId: string): Promise<string> {\n    const runner = await this.runnerRepository.findOne({\n      where: {\n        id: runnerId,\n      },\n      select: ['region'],\n      loadEagerRelations: false,\n    })\n\n    if (!runner || !runner.region) {\n      throw new NotFoundException('Runner not found')\n    }\n\n    return runner.region\n  }\n\n  async findAvailableRunners(params: GetRunnerParams): Promise<Runner[]> {\n    const runnerFilter: FindOptionsWhere<Runner> = {\n      state: RunnerState.READY,\n      unschedulable: Not(true),\n      draining: Not(true),\n      availabilityScore: params.availabilityScoreThreshold\n        ? MoreThanOrEqual(params.availabilityScoreThreshold)\n        : MoreThanOrEqual(this.configService.getOrThrow('runnerScore.thresholds.availability')),\n    }\n\n    const excludedRunnerIds = params.excludedRunnerIds?.length\n      ? params.excludedRunnerIds.filter((id) => !!id)\n      : undefined\n\n    if (params.snapshotRef !== undefined) {\n      const snapshotRunners = await this.snapshotRunnerRepository.find({\n        where: {\n          state: SnapshotRunnerState.READY,\n          snapshotRef: params.snapshotRef,\n        },\n      })\n\n      let runnerIds = snapshotRunners.map((snapshotRunner) => snapshotRunner.runnerId)\n\n      if (excludedRunnerIds?.length) {\n        runnerIds = runnerIds.filter((id) => !excludedRunnerIds.includes(id))\n      }\n\n      if (!runnerIds.length) {\n        return []\n      }\n\n      runnerFilter.id = In(runnerIds)\n    } else if (excludedRunnerIds?.length) {\n      runnerFilter.id = Not(In(excludedRunnerIds))\n    }\n\n    if (params.regions?.length) {\n      runnerFilter.region = In(params.regions)\n    }\n\n    if (params.sandboxClass !== undefined) {\n      runnerFilter.class = params.sandboxClass\n    }\n\n    const runners = await this.runnerRepository.find({\n      where: runnerFilter,\n    })\n\n    return runners.sort((a, b) => b.availabilityScore - a.availabilityScore).slice(0, 10)\n  }\n\n  /**\n   * @throws {NotFoundException} If the runner is not found.\n   * @throws {HttpException} If the runner is not unschedulable.\n   * @throws {HttpException} If the runner has sandboxes associated with it.\n   */\n  async remove(id: string): Promise<void> {\n    const runner = await this.findOne(id)\n    if (!runner) {\n      throw new NotFoundException('Runner not found')\n    }\n\n    if (!runner.unschedulable) {\n      throw new HttpException(\n        'Cannot delete runner which is available for scheduling sandboxes',\n        HttpStatus.PRECONDITION_REQUIRED,\n      )\n    }\n\n    const sandboxCount = await this.sandboxRepository.count({\n      where: { runnerId: id, state: Not(In([SandboxState.ARCHIVED, SandboxState.DESTROYED])) },\n    })\n    if (sandboxCount > 0) {\n      throw new HttpException(\n        'Cannot delete runner which has sandboxes associated with it',\n        HttpStatus.PRECONDITION_REQUIRED,\n      )\n    }\n\n    await this.dataSource.transaction(async (em) => {\n      await em.delete(Runner, id)\n      await this.eventEmitter.emitAsync(RunnerEvents.DELETED, new RunnerDeletedEvent(em, id))\n    })\n    this.invalidateRunnerCache(id)\n  }\n\n  async updateRunnerHealth(\n    runnerId: string,\n    domain?: string,\n    apiUrl?: string,\n    proxyUrl?: string,\n    serviceHealth?: RunnerServiceInfo[],\n    metrics?: {\n      currentCpuLoadAverage?: number\n      currentCpuUsagePercentage?: number\n      currentMemoryUsagePercentage?: number\n      currentDiskUsagePercentage?: number\n      currentAllocatedCpu?: number\n      currentAllocatedMemoryGiB?: number\n      currentAllocatedDiskGiB?: number\n      currentSnapshotCount?: number\n      currentStartedSandboxes?: number\n      cpu?: number\n      memoryGiB?: number\n      diskGiB?: number\n    },\n    appVersion?: string,\n  ): Promise<void> {\n    const runner = await this.findOne(runnerId)\n    if (!runner) {\n      this.logger.error(`Runner ${runnerId} not found when trying to update health`)\n      return\n    }\n\n    if (runner.state === RunnerState.DECOMMISSIONED) {\n      this.logger.debug(`Runner ${runnerId} is decommissioned, not updating health`)\n      return\n    }\n\n    const updateData: Partial<Runner> = {\n      state: RunnerState.READY,\n      lastChecked: new Date(),\n    }\n\n    if (domain) {\n      updateData.domain = domain\n    }\n\n    if (apiUrl) {\n      updateData.apiUrl = apiUrl\n    }\n\n    if (proxyUrl) {\n      updateData.proxyUrl = proxyUrl\n    }\n\n    if (appVersion) {\n      updateData.appVersion = appVersion\n    }\n\n    if (serviceHealth !== undefined) {\n      updateData.serviceHealth = serviceHealth\n    } else {\n      // Clear any previously stored service health when no new health data is provided\n      updateData.serviceHealth = null\n    }\n\n    const unhealthyServices = serviceHealth?.filter((s) => !s.healthy) ?? []\n    if (unhealthyServices.length > 0) {\n      const unhealthySummary = unhealthyServices\n        .map((s) => `\"${s.serviceName}\"${s.errorReason ? ` (${s.errorReason})` : ''}`)\n        .join(', ')\n      this.logger.warn(`Runner ${runnerId} services reported unhealthy: ${unhealthySummary}`)\n      updateData.state = RunnerState.UNRESPONSIVE\n    }\n\n    if (metrics) {\n      updateData.currentCpuLoadAverage = metrics.currentCpuLoadAverage || 0\n      updateData.currentCpuUsagePercentage = metrics.currentCpuUsagePercentage || 0\n      updateData.currentMemoryUsagePercentage = metrics.currentMemoryUsagePercentage || 0\n      updateData.currentDiskUsagePercentage = metrics.currentDiskUsagePercentage || 0\n      updateData.currentAllocatedCpu = metrics.currentAllocatedCpu || 0\n      updateData.currentAllocatedMemoryGiB = metrics.currentAllocatedMemoryGiB || 0\n      updateData.currentAllocatedDiskGiB = metrics.currentAllocatedDiskGiB || 0\n      updateData.currentSnapshotCount = metrics.currentSnapshotCount || 0\n      updateData.currentStartedSandboxes = metrics.currentStartedSandboxes || 0\n      updateData.cpu = metrics.cpu\n      updateData.memoryGiB = metrics.memoryGiB\n      updateData.diskGiB = metrics.diskGiB\n\n      updateData.availabilityScore = this.calculateAvailabilityScore(runnerId, {\n        cpuLoadAverage: updateData.currentCpuLoadAverage,\n        cpuUsage: updateData.currentCpuUsagePercentage,\n        memoryUsage: updateData.currentMemoryUsagePercentage,\n        diskUsage: updateData.currentDiskUsagePercentage,\n        allocatedCpu: updateData.currentAllocatedCpu,\n        allocatedMemoryGiB: updateData.currentAllocatedMemoryGiB,\n        allocatedDiskGiB: updateData.currentAllocatedDiskGiB,\n        runnerCpu: updateData.cpu || runner.cpu,\n        runnerMemoryGiB: updateData.memoryGiB || runner.memoryGiB,\n        runnerDiskGiB: updateData.diskGiB || runner.diskGiB,\n        startedSandboxes: updateData.currentStartedSandboxes || 0,\n      })\n    }\n\n    await this.updateRunner(runnerId, updateData)\n    this.logger.debug(`Updated health for runner ${runnerId}`)\n\n    this.eventEmitter.emit(\n      RunnerEvents.STATE_UPDATED,\n      new RunnerStateUpdatedEvent(runner, runner.state, updateData.state),\n    )\n  }\n\n  private async updateRunnerState(runnerId: string, newState: RunnerState): Promise<void> {\n    const runner = await this.findOne(runnerId)\n    if (!runner) {\n      this.logger.error(`Runner ${runnerId} not found when trying to update state`)\n      return\n    }\n\n    // Don't change state if runner is decommissioned\n    if (runner.state === RunnerState.DECOMMISSIONED) {\n      this.logger.debug(`Runner ${runnerId} is decommissioned, not updating state`)\n      return\n    }\n\n    await this.updateRunner(runnerId, {\n      state: newState,\n      lastChecked: new Date(),\n    })\n\n    this.eventEmitter.emit(RunnerEvents.STATE_UPDATED, new RunnerStateUpdatedEvent(runner, runner.state, newState))\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'check-runners', waitForCompletion: true })\n  @LogExecution('check-runners')\n  @WithInstrumentation()\n  private async handleCheckRunners() {\n    const lockKey = 'check-runners'\n    const hasLock = await this.redisLockProvider.lock(lockKey, 60)\n    if (!hasLock) {\n      return\n    }\n\n    try {\n      const runners = await this.runnerRepository.find({\n        where: [\n          {\n            apiVersion: '0',\n            state: Not(RunnerState.DECOMMISSIONED),\n          },\n          {\n            // v2 runners report health via healthcheck endpoint, so we only check if the health is stale (lastChecked timestamp)\n            apiVersion: '2',\n            state: RunnerState.READY,\n          },\n        ],\n        order: {\n          lastChecked: {\n            direction: 'ASC',\n            nulls: 'FIRST',\n          },\n        },\n        take: 100,\n      })\n\n      await Promise.allSettled(\n        runners.map(async (runner) => {\n          // v2 runners report health via healthcheck endpoint, check based on lastChecked timestamp\n          if (runner.apiVersion === '2') {\n            await this.checkRunnerV2Health(runner)\n            return\n          }\n\n          // v0 runners: imperative health check via adapter\n          const shouldRetry = runner.state === RunnerState.READY\n          const retryDelays = shouldRetry ? [500, 1000] : []\n\n          for (let attempt = 0; attempt <= retryDelays.length; attempt++) {\n            if (attempt > 0) {\n              await new Promise((resolve) => setTimeout(resolve, retryDelays[attempt - 1]))\n            }\n\n            const abortController = new AbortController()\n            let timeoutId: NodeJS.Timeout | null = null\n\n            const runnerHealthTimeoutSeconds = this.configService.get('runnerHealthTimeout')\n\n            try {\n              await Promise.race([\n                (async () => {\n                  this.logger.debug(`Checking runner ${runner.id}`)\n                  const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n                  await runnerAdapter.healthCheck(abortController.signal)\n\n                  let runnerInfo: RunnerInfo | undefined\n                  try {\n                    runnerInfo = await runnerAdapter.runnerInfo(abortController.signal)\n                  } catch (e) {\n                    this.logger.warn(`Failed to get runner info for runner ${runner.id}: ${e.message}`)\n                  }\n\n                  await this.updateRunnerHealth(\n                    runner.id,\n                    undefined,\n                    undefined,\n                    undefined,\n                    runnerInfo?.serviceHealth,\n                    runnerInfo?.metrics,\n                    runnerInfo?.appVersion,\n                  )\n                })(),\n                new Promise((_, reject) => {\n                  timeoutId = setTimeout(() => {\n                    abortController.abort()\n                    reject(new Error('Health check timeout'))\n                  }, runnerHealthTimeoutSeconds * 1000)\n                }),\n              ])\n\n              if (timeoutId) {\n                clearTimeout(timeoutId)\n              }\n              return // Success, exit retry loop\n            } catch (e) {\n              if (timeoutId) {\n                clearTimeout(timeoutId)\n              }\n\n              if (e.message === 'Health check timeout') {\n                this.logger.error(\n                  `Runner ${runner.id} health check timed out after ${runnerHealthTimeoutSeconds} seconds`,\n                )\n              } else if (e.code === 'ECONNREFUSED') {\n                this.logger.error(`Runner ${runner.id} not reachable`)\n              } else if (e.name === 'AbortError') {\n                this.logger.error(`Runner ${runner.id} health check was aborted due to timeout`)\n              } else {\n                this.logger.error(`Error checking runner ${runner.id}`, e)\n              }\n\n              // If last attempt, mark as unresponsive\n              if (attempt === retryDelays.length) {\n                await this.updateRunnerState(runner.id, RunnerState.UNRESPONSIVE)\n              }\n            }\n          }\n        }),\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  /**\n   * Check v2 runner health based on lastChecked timestamp.\n   * v2 runners report health via the healthcheck endpoint, so we check if lastChecked is within threshold.\n   */\n  private async checkRunnerV2Health(runner: Runner): Promise<void> {\n    const markAsUnresponsive = async () => {\n      this.logger.warn(\n        `v2 Runner ${runner.id} health check stale (last: ${Math.round((Date.now() - runner.lastChecked.getTime()) / 1000)}s ago), marking as UNRESPONSIVE`,\n      )\n      await this.updateRunnerState(runner.id, RunnerState.UNRESPONSIVE)\n    }\n\n    if (!runner.lastChecked) {\n      return\n    }\n\n    // v2 runners report health every ~10 seconds via the healthcheck endpoint\n    // Allow 60 seconds (6 missed healthchecks) before marking as UNRESPONSIVE\n    const healthCheckThresholdMs = 60 * 1000\n\n    if (runner.lastChecked < this.serviceStartTime) {\n      // Allow the runner a grace period to re-establish health checks\n      const timeSinceServiceStart = Date.now() - this.serviceStartTime.getTime()\n\n      if (timeSinceServiceStart > healthCheckThresholdMs) {\n        // Grace period expired and runner still hasn't checked in\n        await markAsUnresponsive()\n      }\n    } else {\n      // Runner has checked in since API started - use normal threshold\n      const timeSinceLastCheck = Date.now() - runner.lastChecked.getTime()\n\n      if (timeSinceLastCheck > healthCheckThresholdMs) {\n        // Runner hasn't reported health recently\n        await markAsUnresponsive()\n      }\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'check-decommission-runners', waitForCompletion: true })\n  @LogExecution('check-decommission-runners')\n  @WithInstrumentation()\n  private async handleCheckDecommissionRunners() {\n    const lockKey = 'check-decommission-runners'\n    const hasLock = await this.redisLockProvider.lock(lockKey, 60)\n    if (!hasLock) {\n      return\n    }\n\n    try {\n      const drainingRunners = await this.runnerRepository.find({\n        where: {\n          draining: true,\n          state: Not(RunnerState.DECOMMISSIONED),\n        },\n      })\n\n      this.logger.debug(`Checking ${drainingRunners.length} draining runners`)\n\n      await Promise.allSettled(\n        drainingRunners.map(async (runner) => {\n          try {\n            // Check if runner has any sandboxes with desiredState != DESTROYED\n            const nonDestroyedSandboxCount = await this.sandboxRepository.count({\n              where: {\n                runnerId: runner.id,\n                desiredState: Not(SandboxDesiredState.DESTROYED),\n              },\n            })\n\n            const redisKey = `runner:draining-check:${runner.id}`\n\n            if (nonDestroyedSandboxCount > 0) {\n              // Reset counter if there are non-destroyed sandboxes\n              await this.redis.set(redisKey, '0', 'EX', 600) // 10 minute TTL\n              this.logger.debug(\n                `Runner ${runner.id} has ${nonDestroyedSandboxCount} sandboxes with desiredState != DESTROYED, reset counter`,\n              )\n            } else {\n              // Increment counter\n              const currentCount = await this.redis.get(redisKey)\n              const count = currentCount ? parseInt(currentCount, 10) + 1 : 1\n\n              if (count >= 3) {\n                // Decommission the runner\n                await this.updateRunner(runner.id, {\n                  state: RunnerState.DECOMMISSIONED,\n                })\n                await this.redis.del(redisKey)\n                this.logger.log(`Runner ${runner.id} has been decommissioned after 3 successful draining checks`)\n              } else {\n                await this.redis.set(redisKey, count.toString(), 'EX', 600) // 10 minute TTL\n                this.logger.debug(\n                  `Runner ${runner.id} draining check passed (${count}/3), all sandboxes have desiredState = DESTROYED`,\n                )\n              }\n            }\n          } catch (e) {\n            this.logger.error(`Error checking draining runner ${runner.id}`, e)\n          }\n        }),\n      )\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  async updateSchedulingStatus(id: string, unschedulable: boolean): Promise<Runner> {\n    const runner = await this.findOneOrFail(id)\n    runner.unschedulable = unschedulable\n    await this.runnerRepository.save(runner)\n    return runner\n  }\n\n  async updateDrainingStatus(id: string, draining: boolean): Promise<Runner> {\n    const runner = await this.findOneOrFail(id)\n    runner.draining = draining\n    await this.runnerRepository.save(runner)\n    return runner\n  }\n\n  async getRandomAvailableRunner(params: GetRunnerParams): Promise<Runner> {\n    const availableRunners = await this.findAvailableRunners(params)\n\n    if (availableRunners.length === 0) {\n      throw new BadRequestError('No available runners')\n    }\n\n    // Get random runner from the best available runners\n    const randomIntFromInterval = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1) + min)\n\n    return availableRunners[randomIntFromInterval(0, availableRunners.length - 1)]\n  }\n\n  async getSnapshotRunner(runnerId: string, snapshotRef: string): Promise<SnapshotRunner> {\n    return this.snapshotRunnerRepository.findOne({\n      where: {\n        runnerId: runnerId,\n        snapshotRef: snapshotRef,\n      },\n    })\n  }\n\n  async getSnapshotRunners(snapshotRef: string): Promise<SnapshotRunner[]> {\n    return this.snapshotRunnerRepository.find({\n      where: {\n        snapshotRef,\n      },\n      order: {\n        state: 'ASC', // Sorts state BUILDING_SNAPSHOT before ERROR\n        createdAt: 'ASC', // Sorts first runner to start building snapshot on top\n      },\n    })\n  }\n\n  async createSnapshotRunnerEntry(\n    runnerId: string,\n    snapshotRef: string,\n    state?: SnapshotRunnerState,\n    errorReason?: string,\n  ): Promise<void> {\n    try {\n      const snapshotRunner = new SnapshotRunner()\n      snapshotRunner.runnerId = runnerId\n      snapshotRunner.snapshotRef = snapshotRef\n      if (state) {\n        snapshotRunner.state = state\n      }\n      if (errorReason) {\n        snapshotRunner.errorReason = errorReason\n      }\n      await this.snapshotRunnerRepository.save(snapshotRunner)\n    } catch (error) {\n      if (error.code === '23505') {\n        // PostgreSQL unique violation error code - entry already exists, allow it\n        this.logger.debug(\n          `SnapshotRunner entry already exists for runnerId: ${runnerId}, snapshotRef: ${snapshotRef}. Continuing...`,\n        )\n        return\n      }\n      throw error // Re-throw any other errors\n    }\n  }\n\n  // TODO: combine getRunnersWithMultipleSnapshotsBuilding and getRunnersWithMultipleSnapshotsPulling?\n\n  async getRunnersWithMultipleSnapshotsBuilding(maxSnapshotCount = 6): Promise<string[]> {\n    const runners = await this.sandboxRepository\n      .createQueryBuilder('sandbox')\n      .select('sandbox.runnerId', 'runnerId')\n      .where('sandbox.state = :state', { state: SandboxState.BUILDING_SNAPSHOT })\n      .andWhere('sandbox.buildInfoSnapshotRef IS NOT NULL')\n      .groupBy('sandbox.runnerId')\n      .having('COUNT(DISTINCT sandbox.buildInfoSnapshotRef) > :maxSnapshotCount', { maxSnapshotCount })\n      .getRawMany()\n\n    return runners.map((item) => item.runnerId)\n  }\n\n  async getRunnersWithMultipleSnapshotsPulling(maxSnapshotCount = 6): Promise<string[]> {\n    const runners = await this.snapshotRunnerRepository\n      .createQueryBuilder('snapshot_runner')\n      .select('snapshot_runner.runnerId')\n      .where('snapshot_runner.state = :state', { state: SnapshotRunnerState.PULLING_SNAPSHOT })\n      .groupBy('snapshot_runner.runnerId')\n      .having('COUNT(*) > :maxSnapshotCount', { maxSnapshotCount })\n      .getRawMany()\n\n    return runners.map((item) => item.runnerId)\n  }\n\n  async getRunnersBySnapshotRef(ref: string): Promise<RunnerSnapshotDto[]> {\n    const snapshotRunners = await this.snapshotRunnerRepository.find({\n      where: {\n        snapshotRef: ref,\n        state: Not(SnapshotRunnerState.ERROR),\n      },\n      select: ['runnerId', 'id'],\n    })\n\n    // Extract distinct runnerIds from snapshot runners\n    const runnerIds = [...new Set(snapshotRunners.map((sr) => sr.runnerId))]\n\n    // Find all runners with these IDs\n    const runners = await this.runnerRepository.find({\n      where: { id: In(runnerIds) },\n      select: ['id', 'domain'],\n    })\n\n    this.logger.debug(`Found ${runners.length} runners with IDs: ${runners.map((r) => r.id).join(', ')}`)\n\n    // Map to DTO format, including the snapshot runner ID\n    return runners.map((runner) => {\n      const snapshotRunner = snapshotRunners.find((sr) => sr.runnerId === runner.id)\n      return new RunnerSnapshotDto(snapshotRunner.id, runner.id, runner.domain)\n    })\n  }\n\n  async getInitialRunnerBySnapshotId(snapshotId: string): Promise<Runner> {\n    const snapshot = await this.snapshotRepository.findOne({ where: { id: snapshotId } })\n    if (!snapshot) {\n      throw new NotFoundException('Snapshot runner not found')\n    }\n    if (!snapshot.initialRunnerId) {\n      throw new BadRequestException('Initial runner not found')\n    }\n\n    return await this.findOneOrFail(snapshot.initialRunnerId)\n  }\n\n  async getRunnerApiVersion(runnerId: string): Promise<string> {\n    const result = await this.runnerRepository.findOneOrFail({\n      select: ['apiVersion'],\n      where: { id: runnerId },\n      cache: {\n        id: `runner:apiVersion:${runnerId}`,\n        milliseconds: 60 * 60 * 1000, // Cache for 1 hour\n      },\n    })\n\n    return result.apiVersion\n  }\n\n  private async updateRunner(\n    id: string,\n    data: Partial<Omit<Runner, 'id' | 'createdAt' | 'updatedAt'>>,\n  ): Promise<UpdateResult> {\n    const result = await this.runnerRepository.update(id, data)\n    this.invalidateRunnerCache(id)\n    return result\n  }\n\n  private invalidateRunnerCache(runnerId: string): void {\n    const cache = this.dataSource.queryResultCache\n    if (!cache) {\n      return\n    }\n\n    cache\n      .remove([runnerLookupCacheKeyById(runnerId)])\n      .then(() => this.logger.debug(`Invalidated runner lookup cache for ${runnerId}`))\n      .catch((error) =>\n        this.logger.warn(\n          `Failed to invalidate runner lookup cache for ${runnerId}: ${error instanceof Error ? error.message : String(error)}`,\n        ),\n      )\n  }\n\n  private calculateAvailabilityScore(runnerId: string, params: AvailabilityScoreParams): number {\n    if (\n      params.cpuLoadAverage < 0 ||\n      params.cpuUsage < 0 ||\n      params.memoryUsage < 0 ||\n      params.diskUsage < 0 ||\n      params.allocatedCpu < 0 ||\n      params.allocatedMemoryGiB < 0 ||\n      params.allocatedDiskGiB < 0 ||\n      params.startedSandboxes < 0\n    ) {\n      this.logger.warn(\n        `Runner ${runnerId} has negative values for load, CPU, memory, disk, allocated CPU, allocated memory, allocated disk, or started sandboxes`,\n      )\n      return 0\n    }\n\n    return this.calculateTOPSISScore(params)\n  }\n\n  private calculateTOPSISScore(params: AvailabilityScoreParams): number {\n    const current = [\n      params.cpuUsage,\n      params.memoryUsage,\n      params.diskUsage,\n      // Allocation ratios percentage\n      (params.allocatedCpu / params.runnerCpu) * 100,\n      (params.allocatedMemoryGiB / params.runnerMemoryGiB) * 100,\n      (params.allocatedDiskGiB / params.runnerDiskGiB) * 100,\n      params.startedSandboxes, // Raw count, will be normalized against its critical target value\n    ]\n\n    // Calculate weighted Euclidean distances\n    let distanceToOptimal = 0\n    let distanceToCritical = 0\n\n    for (let i = 0; i < current.length; i++) {\n      // Normalize to 0-1 scale\n      const normalizedCurrent = current[i] / 100\n      const normalizedOptimal = this.scoreConfig.targetValues.optimal[i] / 100\n      const normalizedCritical = this.scoreConfig.targetValues.critical[i] / 100\n\n      distanceToOptimal += this.scoreConfig.weights[i] * Math.pow(normalizedCurrent - normalizedOptimal, 2)\n      distanceToCritical += this.scoreConfig.weights[i] * Math.pow(normalizedCurrent - normalizedCritical, 2)\n    }\n\n    distanceToOptimal = Math.sqrt(distanceToOptimal)\n    distanceToCritical = Math.sqrt(distanceToCritical)\n\n    // TOPSIS relative closeness score (0 to 1)\n    let topsisScore = distanceToCritical / (distanceToOptimal + distanceToCritical)\n\n    // Apply exponential penalties for critical thresholds\n    let penaltyMultiplier = 1\n\n    if (params.cpuUsage >= this.scoreConfig.penalty.thresholds.cpu) {\n      penaltyMultiplier *= Math.exp(\n        -this.scoreConfig.penalty.exponents.cpu * (params.cpuUsage - this.scoreConfig.penalty.thresholds.cpu),\n      )\n    }\n\n    if (params.cpuLoadAverage >= this.scoreConfig.penalty.thresholds.cpuLoadAvg) {\n      penaltyMultiplier *= Math.exp(\n        -this.scoreConfig.penalty.exponents.cpuLoadAvg *\n          (params.cpuLoadAverage - this.scoreConfig.penalty.thresholds.cpuLoadAvg),\n      )\n    }\n\n    if (params.memoryUsage >= this.scoreConfig.penalty.thresholds.memory) {\n      penaltyMultiplier *= Math.exp(\n        -this.scoreConfig.penalty.exponents.memory * (params.memoryUsage - this.scoreConfig.penalty.thresholds.memory),\n      )\n    }\n\n    if (params.diskUsage >= this.scoreConfig.penalty.thresholds.disk) {\n      penaltyMultiplier *= Math.exp(\n        -this.scoreConfig.penalty.exponents.disk * (params.diskUsage - this.scoreConfig.penalty.thresholds.disk),\n      )\n    }\n\n    // Apply penalty\n    topsisScore *= penaltyMultiplier\n\n    return Math.round(topsisScore * 100)\n  }\n\n  private getAvailabilityScoreConfig(): AvailabilityScoreConfig {\n    return {\n      availabilityThreshold: this.configService.getOrThrow('runnerScore.thresholds.availability'),\n      weights: [\n        this.configService.getOrThrow('runnerScore.weights.cpuUsage'),\n        this.configService.getOrThrow('runnerScore.weights.memoryUsage'),\n        this.configService.getOrThrow('runnerScore.weights.diskUsage'),\n        this.configService.getOrThrow('runnerScore.weights.allocatedCpu'),\n        this.configService.getOrThrow('runnerScore.weights.allocatedMemory'),\n        this.configService.getOrThrow('runnerScore.weights.allocatedDisk'),\n        this.configService.getOrThrow('runnerScore.weights.startedSandboxes'),\n      ],\n      penalty: {\n        exponents: {\n          cpu: this.configService.getOrThrow('runnerScore.penalty.exponents.cpu'),\n          cpuLoadAvg: this.configService.getOrThrow('runnerScore.penalty.exponents.cpuLoadAvg'),\n          memory: this.configService.getOrThrow('runnerScore.penalty.exponents.memory'),\n          disk: this.configService.getOrThrow('runnerScore.penalty.exponents.disk'),\n        },\n        thresholds: {\n          cpu: this.configService.getOrThrow('runnerScore.penalty.thresholds.cpu'),\n          cpuLoadAvg: this.configService.getOrThrow('runnerScore.penalty.thresholds.cpuLoadAvg'),\n          memory: this.configService.getOrThrow('runnerScore.penalty.thresholds.memory'),\n          disk: this.configService.getOrThrow('runnerScore.penalty.thresholds.disk'),\n        },\n      },\n      targetValues: {\n        optimal: [\n          this.configService.getOrThrow('runnerScore.targetValues.optimal.cpu'),\n          this.configService.getOrThrow('runnerScore.targetValues.optimal.memory'),\n          this.configService.getOrThrow('runnerScore.targetValues.optimal.disk'),\n          this.configService.getOrThrow('runnerScore.targetValues.optimal.allocCpu'),\n          this.configService.getOrThrow('runnerScore.targetValues.optimal.allocMem'),\n          this.configService.getOrThrow('runnerScore.targetValues.optimal.allocDisk'),\n          this.configService.getOrThrow('runnerScore.targetValues.optimal.startedSandboxes'),\n        ],\n        critical: [\n          this.configService.getOrThrow('runnerScore.targetValues.critical.cpu'),\n          this.configService.getOrThrow('runnerScore.targetValues.critical.memory'),\n          this.configService.getOrThrow('runnerScore.targetValues.critical.disk'),\n          this.configService.getOrThrow('runnerScore.targetValues.critical.allocCpu'),\n          this.configService.getOrThrow('runnerScore.targetValues.critical.allocMem'),\n          this.configService.getOrThrow('runnerScore.targetValues.critical.allocDisk'),\n          this.configService.getOrThrow('runnerScore.targetValues.critical.startedSandboxes'),\n        ],\n      },\n    }\n  }\n}\n\nexport class GetRunnerParams {\n  regions?: string[]\n  sandboxClass?: SandboxClass\n  snapshotRef?: string\n  excludedRunnerIds?: string[]\n  availabilityScoreThreshold?: number\n}\n\ninterface AvailabilityScoreParams {\n  cpuLoadAverage: number\n  cpuUsage: number\n  memoryUsage: number\n  diskUsage: number\n  allocatedCpu: number\n  allocatedMemoryGiB: number\n  allocatedDiskGiB: number\n  startedSandboxes: number\n  runnerCpu: number\n  runnerMemoryGiB: number\n  runnerDiskGiB: number\n}\n\ninterface AvailabilityScoreConfig {\n  availabilityThreshold: number\n  weights: number[]\n  penalty: {\n    exponents: {\n      cpu: number\n      cpuLoadAvg: number\n      memory: number\n      disk: number\n    }\n    thresholds: {\n      cpu: number\n      cpuLoadAvg: number\n      memory: number\n      disk: number\n    }\n  }\n  targetValues: {\n    optimal: number[]\n    critical: number[]\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/sandbox-lookup-cache-invalidation.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { DataSource } from 'typeorm'\nimport {\n  sandboxLookupCacheKeyByAuthToken,\n  sandboxLookupCacheKeyById,\n  sandboxLookupCacheKeyByName,\n  sandboxOrgIdCacheKeyById,\n  sandboxOrgIdCacheKeyByName,\n} from '../utils/sandbox-lookup-cache.util'\n\ntype InvalidateSandboxLookupCacheArgs =\n  | {\n      sandboxId: string\n      organizationId: string\n      name: string\n      previousOrganizationId?: string | null\n      previousName?: string | null\n    }\n  | {\n      authToken: string\n    }\n\n@Injectable()\nexport class SandboxLookupCacheInvalidationService {\n  private readonly logger = new Logger(SandboxLookupCacheInvalidationService.name)\n\n  constructor(private readonly dataSource: DataSource) {}\n\n  invalidate(args: InvalidateSandboxLookupCacheArgs): void {\n    const cache = this.dataSource.queryResultCache\n    if (!cache) {\n      return\n    }\n\n    if ('authToken' in args) {\n      cache\n        .remove([sandboxLookupCacheKeyByAuthToken({ authToken: args.authToken })])\n        .then(() => this.logger.debug(`Invalidated sandbox lookup cache for authToken ${args.authToken}`))\n        .catch((error) =>\n          this.logger.warn(\n            `Failed to invalidate sandbox lookup cache for authToken ${args.authToken}: ${error instanceof Error ? error.message : String(error)}`,\n          ),\n        )\n      return\n    }\n\n    const organizationIds = Array.from(\n      new Set(\n        [args.organizationId, args.previousOrganizationId].filter((id): id is string =>\n          Boolean(id && id.trim().length > 0),\n        ),\n      ),\n    )\n    const names = Array.from(\n      new Set([args.name, args.previousName].filter((n): n is string => Boolean(n && n.trim().length > 0))),\n    )\n\n    const cacheIds: string[] = []\n    for (const organizationId of organizationIds) {\n      for (const returnDestroyed of [false, true]) {\n        cacheIds.push(\n          sandboxLookupCacheKeyById({\n            organizationId,\n            returnDestroyed,\n            sandboxId: args.sandboxId,\n          }),\n        )\n        for (const sandboxName of names) {\n          cacheIds.push(\n            sandboxLookupCacheKeyByName({\n              organizationId,\n              returnDestroyed,\n              sandboxName,\n            }),\n          )\n        }\n      }\n    }\n\n    if (cacheIds.length === 0) {\n      return\n    }\n\n    cache\n      .remove(cacheIds)\n      .then(() => this.logger.debug(`Invalidated sandbox lookup cache for ${args.sandboxId}`))\n      .catch((error) =>\n        this.logger.warn(\n          `Failed to invalidate sandbox lookup cache for ${args.sandboxId}: ${error instanceof Error ? error.message : String(error)}`,\n        ),\n      )\n  }\n\n  invalidateOrgId(args: {\n    sandboxId: string\n    organizationId: string\n    name: string\n    previousOrganizationId?: string | null\n    previousName?: string | null\n  }): void {\n    const cache = this.dataSource.queryResultCache\n    if (!cache) {\n      return\n    }\n\n    const organizationIds = Array.from(\n      new Set(\n        [args.organizationId, args.previousOrganizationId].filter((id): id is string =>\n          Boolean(id && id.trim().length > 0),\n        ),\n      ),\n    )\n    const names = Array.from(\n      new Set([args.name, args.previousName].filter((n): n is string => Boolean(n && n.trim().length > 0))),\n    )\n\n    const cacheIds: string[] = []\n    for (const organizationId of organizationIds) {\n      cacheIds.push(\n        sandboxOrgIdCacheKeyById({\n          organizationId,\n          sandboxId: args.sandboxId,\n        }),\n      )\n      for (const sandboxName of names) {\n        cacheIds.push(\n          sandboxOrgIdCacheKeyByName({\n            organizationId,\n            sandboxName,\n          }),\n        )\n      }\n    }\n\n    // Also invalidate the \"no org\" variants (when organizationId was not provided to getOrganizationId)\n    cacheIds.push(sandboxOrgIdCacheKeyById({ sandboxId: args.sandboxId }))\n    for (const sandboxName of names) {\n      cacheIds.push(sandboxOrgIdCacheKeyByName({ sandboxName }))\n    }\n\n    cache\n      .remove(cacheIds)\n      .then(() => this.logger.debug(`Invalidated sandbox orgId cache for ${args.sandboxId}`))\n      .catch((error) =>\n        this.logger.warn(\n          `Failed to invalidate sandbox orgId cache for ${args.sandboxId}: ${error instanceof Error ? error.message : String(error)}`,\n        ),\n      )\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/sandbox-warm-pool.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Inject, Injectable, Logger } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { FindOptionsWhere, In, MoreThan, Not, Repository } from 'typeorm'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION } from '../constants/sandbox.constants'\nimport { WarmPool } from '../entities/warm-pool.entity'\nimport { EventEmitter2, OnEvent } from '@nestjs/event-emitter'\nimport { SandboxEvents } from '../constants/sandbox-events.constants'\nimport { SandboxOrganizationUpdatedEvent } from '../events/sandbox-organization-updated.event'\nimport { ConfigService } from '@nestjs/config'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { Runner } from '../entities/runner.entity'\nimport { WarmPoolTopUpRequested } from '../events/warmpool-topup-requested.event'\nimport { WarmPoolEvents } from '../constants/warmpool-events.constants'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\nimport { isValidUuid } from '../../common/utils/uuid'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\n\nexport type FetchWarmPoolSandboxParams = {\n  snapshot: string | Snapshot\n  target: string\n  class: SandboxClass\n  cpu: number\n  mem: number\n  disk: number\n  gpu: number\n  osUser: string\n  env: { [key: string]: string }\n  organizationId: string\n  state: string\n}\n\n@Injectable()\nexport class SandboxWarmPoolService {\n  private readonly logger = new Logger(SandboxWarmPoolService.name)\n\n  constructor(\n    @InjectRepository(WarmPool)\n    private readonly warmPoolRepository: Repository<WarmPool>,\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    @InjectRepository(Runner)\n    private readonly runnerRepository: Repository<Runner>,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly configService: ConfigService,\n    @Inject(EventEmitter2)\n    private eventEmitter: EventEmitter2,\n    @InjectRedis() private readonly redis: Redis,\n  ) {}\n\n  //  on init\n  async onApplicationBootstrap() {\n    //  await this.adHocBackupCheck()\n  }\n\n  async fetchWarmPoolSandbox(params: FetchWarmPoolSandboxParams): Promise<Sandbox | null> {\n    //  validate snapshot\n    let snapshot: Snapshot | null = null\n    if (typeof params.snapshot === 'string') {\n      const sandboxSnapshot = params.snapshot || this.configService.get<string>('DEFAULT_SNAPSHOT')\n\n      const snapshotFilter: FindOptionsWhere<Snapshot>[] = [\n        { organizationId: params.organizationId, name: sandboxSnapshot, state: SnapshotState.ACTIVE },\n        { general: true, name: sandboxSnapshot, state: SnapshotState.ACTIVE },\n      ]\n\n      if (isValidUuid(sandboxSnapshot)) {\n        snapshotFilter.push(\n          { organizationId: params.organizationId, id: sandboxSnapshot, state: SnapshotState.ACTIVE },\n          { general: true, id: sandboxSnapshot, state: SnapshotState.ACTIVE },\n        )\n      }\n\n      snapshot = await this.snapshotRepository.findOne({\n        where: snapshotFilter,\n      })\n      if (!snapshot) {\n        throw new BadRequestError(\n          `Snapshot ${sandboxSnapshot} not found. Did you add it through the Daytona Dashboard?`,\n        )\n      }\n    } else {\n      snapshot = params.snapshot\n    }\n\n    //  check if sandbox is warm pool\n    const warmPoolItem = await this.warmPoolRepository.findOne({\n      where: {\n        snapshot: snapshot.name,\n        target: params.target,\n        class: params.class,\n        cpu: params.cpu,\n        mem: params.mem,\n        disk: params.disk,\n        gpu: params.gpu,\n        osUser: params.osUser,\n        env: params.env,\n        pool: MoreThan(0),\n      },\n    })\n    if (warmPoolItem) {\n      const availabilityScoreThreshold = this.configService.getOrThrow<number>('runnerScore.thresholds.availability')\n\n      // Build subquery to find excluded runners (unschedulable OR low score)\n      const excludedRunnersSubquery = this.runnerRepository\n        .createQueryBuilder('runner')\n        .select('runner.id')\n        .where('runner.region = :region')\n        .andWhere('(runner.unschedulable = true OR runner.availabilityScore < :scoreThreshold)')\n\n      const queryBuilder = this.sandboxRepository\n        .createQueryBuilder('sandbox')\n        .where('sandbox.class = :class', { class: warmPoolItem.class })\n        .andWhere('sandbox.cpu = :cpu', { cpu: warmPoolItem.cpu })\n        .andWhere('sandbox.mem = :mem', { mem: warmPoolItem.mem })\n        .andWhere('sandbox.disk = :disk', { disk: warmPoolItem.disk })\n        .andWhere('sandbox.snapshot = :snapshot', { snapshot: snapshot.name })\n        .andWhere('sandbox.osUser = :osUser', { osUser: warmPoolItem.osUser })\n        .andWhere('sandbox.env = :env', { env: warmPoolItem.env })\n        .andWhere('sandbox.organizationId = :organizationId', {\n          organizationId: SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION,\n        })\n        .andWhere('sandbox.region = :region', { region: warmPoolItem.target })\n        .andWhere('sandbox.state = :state', { state: SandboxState.STARTED })\n        .andWhere(`sandbox.runnerId NOT IN (${excludedRunnersSubquery.getQuery()})`)\n        .setParameters({\n          region: warmPoolItem.target,\n          scoreThreshold: availabilityScoreThreshold,\n        })\n\n      const candidateLimit = this.configService.getOrThrow<number>('warmPool.candidateLimit')\n      const warmPoolSandboxes = await queryBuilder.orderBy('RANDOM()').take(candidateLimit).getMany()\n\n      //  make sure we only release warm pool sandbox once\n      let warmPoolSandbox: Sandbox | null = null\n      for (const sandbox of warmPoolSandboxes) {\n        const lockKey = `sandbox-warm-pool-${sandbox.id}`\n        if (!(await this.redisLockProvider.lock(lockKey, 10))) {\n          continue\n        }\n\n        warmPoolSandbox = sandbox\n        break\n      }\n\n      return warmPoolSandbox\n    }\n\n    //  no warm pool config exists for this snapshot — cache it so callers can skip\n    await this.redis.set(`warm-pool:skip:${snapshot.id}`, '1', 'EX', 60)\n\n    return null\n  }\n\n  //  todo: make frequency configurable or more efficient\n  @Cron(CronExpression.EVERY_10_SECONDS, { name: 'warm-pool-check' })\n  @LogExecution('warm-pool-check')\n  @WithInstrumentation()\n  async warmPoolCheck(): Promise<void> {\n    const warmPoolItems = await this.warmPoolRepository.find()\n\n    await Promise.all(\n      warmPoolItems.map(async (warmPoolItem) => {\n        const lockKey = `warm-pool-lock-${warmPoolItem.id}`\n        if (!(await this.redisLockProvider.lock(lockKey, 720))) {\n          return\n        }\n\n        const sandboxCount = await this.sandboxRepository.count({\n          where: {\n            snapshot: warmPoolItem.snapshot,\n            organizationId: SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION,\n            class: warmPoolItem.class,\n            osUser: warmPoolItem.osUser,\n            env: warmPoolItem.env,\n            region: warmPoolItem.target,\n            cpu: warmPoolItem.cpu,\n            gpu: warmPoolItem.gpu,\n            mem: warmPoolItem.mem,\n            disk: warmPoolItem.disk,\n            desiredState: SandboxDesiredState.STARTED,\n            state: Not(In([SandboxState.ERROR, SandboxState.BUILD_FAILED])),\n          },\n        })\n\n        const missingCount = warmPoolItem.pool - sandboxCount\n        if (missingCount > 0) {\n          const promises = []\n          this.logger.debug(`Creating ${missingCount} sandboxes for warm pool id ${warmPoolItem.id}`)\n\n          for (let i = 0; i < missingCount; i++) {\n            promises.push(\n              this.eventEmitter.emitAsync(WarmPoolEvents.TOPUP_REQUESTED, new WarmPoolTopUpRequested(warmPoolItem)),\n            )\n          }\n\n          // Wait for all promises to settle before releasing the lock. Otherwise, another worker could start creating sandboxes\n          await Promise.allSettled(promises)\n        }\n\n        await this.redisLockProvider.unlock(lockKey)\n      }),\n    )\n  }\n\n  @OnEvent(SandboxEvents.ORGANIZATION_UPDATED)\n  async handleSandboxOrganizationUpdated(event: SandboxOrganizationUpdatedEvent) {\n    if (event.newOrganizationId === SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION) {\n      return\n    }\n    const warmPoolItem = await this.warmPoolRepository.findOne({\n      where: {\n        snapshot: event.sandbox.snapshot,\n        class: event.sandbox.class,\n        cpu: event.sandbox.cpu,\n        mem: event.sandbox.mem,\n        disk: event.sandbox.disk,\n        target: event.sandbox.region,\n        env: event.sandbox.env,\n        gpu: event.sandbox.gpu,\n        osUser: event.sandbox.osUser,\n      },\n    })\n\n    if (!warmPoolItem) {\n      return\n    }\n\n    const sandboxCount = await this.sandboxRepository.count({\n      where: {\n        snapshot: warmPoolItem.snapshot,\n        organizationId: SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION,\n        class: warmPoolItem.class,\n        osUser: warmPoolItem.osUser,\n        env: warmPoolItem.env,\n        region: warmPoolItem.target,\n        cpu: warmPoolItem.cpu,\n        gpu: warmPoolItem.gpu,\n        mem: warmPoolItem.mem,\n        disk: warmPoolItem.disk,\n        desiredState: SandboxDesiredState.STARTED,\n        state: Not(In([SandboxState.ERROR, SandboxState.BUILD_FAILED])),\n      },\n    })\n\n    if (warmPoolItem.pool <= sandboxCount) {\n      return\n    }\n\n    if (warmPoolItem) {\n      this.eventEmitter.emit(WarmPoolEvents.TOPUP_REQUESTED, new WarmPoolTopUpRequested(warmPoolItem))\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/sandbox.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ForbiddenException, Injectable, Logger, NotFoundException, ConflictException } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Not, Repository, LessThan, In, JsonContains, FindOptionsWhere, ILike } from 'typeorm'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { CreateSandboxDto } from '../dto/create-sandbox.dto'\nimport { ResizeSandboxDto } from '../dto/resize-sandbox.dto'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { SandboxClass } from '../enums/sandbox-class.enum'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\nimport { RunnerService } from './runner.service'\nimport { SandboxError } from '../../exceptions/sandbox-error.exception'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { BackupState } from '../enums/backup-state.enum'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\nimport { SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION } from '../constants/sandbox.constants'\nimport { SandboxWarmPoolService } from './sandbox-warm-pool.service'\nimport { EventEmitter2, OnEvent } from '@nestjs/event-emitter'\nimport { WarmPoolEvents } from '../constants/warmpool-events.constants'\nimport { WarmPoolTopUpRequested } from '../events/warmpool-topup-requested.event'\nimport { Runner } from '../entities/runner.entity'\nimport { Organization } from '../../organization/entities/organization.entity'\nimport { SandboxEvents } from '../constants/sandbox-events.constants'\nimport { SandboxStateUpdatedEvent } from '../events/sandbox-state-updated.event'\nimport { BuildInfo } from '../entities/build-info.entity'\nimport { generateBuildInfoHash as generateBuildSnapshotRef } from '../entities/build-info.entity'\nimport { SandboxBackupCreatedEvent } from '../events/sandbox-backup-created.event'\nimport { SandboxDestroyedEvent } from '../events/sandbox-destroyed.event'\nimport { SandboxStartedEvent } from '../events/sandbox-started.event'\nimport { SandboxStoppedEvent } from '../events/sandbox-stopped.event'\nimport { SandboxArchivedEvent } from '../events/sandbox-archived.event'\nimport { OrganizationService } from '../../organization/services/organization.service'\nimport { OrganizationEvents } from '../../organization/constants/organization-events.constant'\nimport { OrganizationSuspendedSandboxStoppedEvent } from '../../organization/events/organization-suspended-sandbox-stopped.event'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { WarmPool } from '../entities/warm-pool.entity'\nimport { SandboxDto, SandboxVolume } from '../dto/sandbox.dto'\nimport { isValidUuid } from '../../common/utils/uuid'\nimport { RunnerAdapterFactory } from '../runner-adapter/runnerAdapter'\nimport { validateNetworkAllowList } from '../utils/network-validation.util'\nimport { OrganizationUsageService } from '../../organization/services/organization-usage.service'\nimport { SshAccess } from '../entities/ssh-access.entity'\nimport { SshAccessDto, SshAccessValidationDto } from '../dto/ssh-access.dto'\nimport { VolumeService } from './volume.service'\nimport { PaginatedList } from '../../common/interfaces/paginated-list.interface'\nimport {\n  SandboxSortField,\n  SandboxSortDirection,\n  DEFAULT_SANDBOX_SORT_FIELD,\n  DEFAULT_SANDBOX_SORT_DIRECTION,\n} from '../dto/list-sandboxes-query.dto'\nimport { createRangeFilter } from '../../common/utils/range-filter'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport {\n  UPGRADE_TIER_MESSAGE,\n  ARCHIVE_SANDBOXES_MESSAGE,\n  PER_SANDBOX_LIMIT_MESSAGE,\n} from '../../common/constants/error-messages'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { customAlphabet as customNanoid, nanoid, urlAlphabet } from 'nanoid'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\nimport { validateMountPaths, validateSubpaths } from '../utils/volume-mount-path-validation.util'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport { PortPreviewUrlDto, SignedPortPreviewUrlDto } from '../dto/port-preview-url.dto'\nimport { RegionService } from '../../region/services/region.service'\nimport { DefaultRegionRequiredException } from '../../organization/exceptions/DefaultRegionRequiredException'\nimport { SnapshotService } from './snapshot.service'\nimport { RegionType } from '../../region/enums/region-type.enum'\nimport { SandboxCreatedEvent } from '../events/sandbox-create.event'\nimport { InjectRedis } from '@nestjs-modules/ioredis'\nimport { Redis } from 'ioredis'\nimport {\n  SANDBOX_LOOKUP_CACHE_TTL_MS,\n  SANDBOX_ORG_ID_CACHE_TTL_MS,\n  TOOLBOX_PROXY_URL_CACHE_TTL_S,\n  sandboxLookupCacheKeyById,\n  sandboxLookupCacheKeyByName,\n  sandboxOrgIdCacheKeyById,\n  sandboxOrgIdCacheKeyByName,\n  toolboxProxyUrlCacheKey,\n} from '../utils/sandbox-lookup-cache.util'\nimport { SandboxLookupCacheInvalidationService } from './sandbox-lookup-cache-invalidation.service'\nimport { Region } from '../../region/entities/region.entity'\n\nconst DEFAULT_CPU = 1\nconst DEFAULT_MEMORY = 1\nconst DEFAULT_DISK = 3\nconst DEFAULT_GPU = 0\n\n@Injectable()\nexport class SandboxService {\n  private readonly logger = new Logger(SandboxService.name)\n\n  constructor(\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    @InjectRepository(Runner)\n    private readonly runnerRepository: Repository<Runner>,\n    @InjectRepository(BuildInfo)\n    private readonly buildInfoRepository: Repository<BuildInfo>,\n    @InjectRepository(SshAccess)\n    private readonly sshAccessRepository: Repository<SshAccess>,\n    private readonly runnerService: RunnerService,\n    private readonly volumeService: VolumeService,\n    private readonly configService: TypedConfigService,\n    private readonly warmPoolService: SandboxWarmPoolService,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly organizationService: OrganizationService,\n    private readonly runnerAdapterFactory: RunnerAdapterFactory,\n    private readonly organizationUsageService: OrganizationUsageService,\n    private readonly redisLockProvider: RedisLockProvider,\n    @InjectRedis() private readonly redis: Redis,\n    private readonly regionService: RegionService,\n    private readonly snapshotService: SnapshotService,\n    private readonly sandboxLookupCacheInvalidationService: SandboxLookupCacheInvalidationService,\n  ) {}\n\n  protected getLockKey(id: string): string {\n    return `sandbox:${id}:state-change`\n  }\n\n  private assertSandboxNotErrored(sandbox: Sandbox): void {\n    if ([SandboxState.ERROR, SandboxState.BUILD_FAILED].includes(sandbox.state)) {\n      throw new SandboxError('Sandbox is in an errored state')\n    }\n  }\n\n  private async validateOrganizationQuotas(\n    organization: Organization,\n    region: Region,\n    cpu: number,\n    memory: number,\n    disk: number,\n    excludeSandboxId?: string,\n  ): Promise<{\n    pendingCpuIncremented: boolean\n    pendingMemoryIncremented: boolean\n    pendingDiskIncremented: boolean\n  }> {\n    // validate per-sandbox quotas\n    if (cpu > organization.maxCpuPerSandbox) {\n      throw new ForbiddenException(\n        `CPU request ${cpu} exceeds maximum allowed per sandbox (${organization.maxCpuPerSandbox}).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n      )\n    }\n    if (memory > organization.maxMemoryPerSandbox) {\n      throw new ForbiddenException(\n        `Memory request ${memory}GB exceeds maximum allowed per sandbox (${organization.maxMemoryPerSandbox}GB).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n      )\n    }\n    if (disk > organization.maxDiskPerSandbox) {\n      throw new ForbiddenException(\n        `Disk request ${disk}GB exceeds maximum allowed per sandbox (${organization.maxDiskPerSandbox}GB).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n      )\n    }\n\n    // e.g. region belonging to an organization\n    if (!region.enforceQuotas) {\n      return {\n        pendingCpuIncremented: false,\n        pendingMemoryIncremented: false,\n        pendingDiskIncremented: false,\n      }\n    }\n\n    const regionQuota = await this.organizationService.getRegionQuota(organization.id, region.id)\n\n    if (!regionQuota) {\n      if (region.regionType === RegionType.SHARED) {\n        // region is public, but the organization does not have a quota for it\n        throw new ForbiddenException(`Region ${region.id} is not available to the organization`)\n      } else {\n        // region is not public, respond as if the region was not found\n        throw new NotFoundException('Region not found')\n      }\n    }\n\n    // validate usage quotas\n    const {\n      cpuIncremented: pendingCpuIncremented,\n      memoryIncremented: pendingMemoryIncremented,\n      diskIncremented: pendingDiskIncremented,\n    } = await this.organizationUsageService.incrementPendingSandboxUsage(\n      organization.id,\n      region.id,\n      cpu,\n      memory,\n      disk,\n      excludeSandboxId,\n    )\n\n    const usageOverview = await this.organizationUsageService.getSandboxUsageOverview(\n      organization.id,\n      region.id,\n      excludeSandboxId,\n    )\n\n    try {\n      const upgradeTierMessage = UPGRADE_TIER_MESSAGE(this.configService.getOrThrow('dashboardUrl'))\n\n      if (usageOverview.currentCpuUsage + usageOverview.pendingCpuUsage > regionQuota.totalCpuQuota) {\n        throw new ForbiddenException(\n          `Total CPU limit exceeded. Maximum allowed: ${regionQuota.totalCpuQuota}.\\n${upgradeTierMessage}`,\n        )\n      }\n\n      if (usageOverview.currentMemoryUsage + usageOverview.pendingMemoryUsage > regionQuota.totalMemoryQuota) {\n        throw new ForbiddenException(\n          `Total memory limit exceeded. Maximum allowed: ${regionQuota.totalMemoryQuota}GiB.\\n${upgradeTierMessage}`,\n        )\n      }\n\n      if (usageOverview.currentDiskUsage + usageOverview.pendingDiskUsage > regionQuota.totalDiskQuota) {\n        throw new ForbiddenException(\n          `Total disk limit exceeded. Maximum allowed: ${regionQuota.totalDiskQuota}GiB.\\n${ARCHIVE_SANDBOXES_MESSAGE}\\n${upgradeTierMessage}`,\n        )\n      }\n    } catch (error) {\n      await this.rollbackPendingUsage(\n        organization.id,\n        region.id,\n        pendingCpuIncremented ? cpu : undefined,\n        pendingMemoryIncremented ? memory : undefined,\n        pendingDiskIncremented ? disk : undefined,\n      )\n      throw error\n    }\n\n    return {\n      pendingCpuIncremented,\n      pendingMemoryIncremented,\n      pendingDiskIncremented,\n    }\n  }\n\n  async rollbackPendingUsage(\n    organizationId: string,\n    regionId: string,\n    pendingCpuIncrement?: number,\n    pendingMemoryIncrement?: number,\n    pendingDiskIncrement?: number,\n  ): Promise<void> {\n    if (!pendingCpuIncrement && !pendingMemoryIncrement && !pendingDiskIncrement) {\n      return\n    }\n\n    try {\n      await this.organizationUsageService.decrementPendingSandboxUsage(\n        organizationId,\n        regionId,\n        pendingCpuIncrement,\n        pendingMemoryIncrement,\n        pendingDiskIncrement,\n      )\n    } catch (error) {\n      this.logger.error(`Error rolling back pending sandbox usage: ${error}`)\n    }\n  }\n\n  async archive(sandboxIdOrName: string, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    this.assertSandboxNotErrored(sandbox)\n\n    if (String(sandbox.state) !== String(sandbox.desiredState)) {\n      throw new SandboxError('State change in progress')\n    }\n\n    if (sandbox.state !== SandboxState.STOPPED) {\n      throw new SandboxError('Sandbox is not stopped')\n    }\n\n    if (sandbox.pending) {\n      throw new SandboxError('Sandbox state change in progress')\n    }\n\n    if (sandbox.autoDeleteInterval === 0) {\n      throw new SandboxError('Ephemeral sandboxes cannot be archived')\n    }\n\n    const updateData: Partial<Sandbox> = {\n      state: SandboxState.ARCHIVING,\n      desiredState: SandboxDesiredState.ARCHIVED,\n    }\n\n    const updatedSandbox = await this.sandboxRepository.updateWhere(sandbox.id, {\n      updateData,\n      whereCondition: { pending: false, state: SandboxState.STOPPED },\n    })\n\n    this.eventEmitter.emit(SandboxEvents.ARCHIVED, new SandboxArchivedEvent(updatedSandbox))\n    return updatedSandbox\n  }\n\n  async createForWarmPool(warmPoolItem: WarmPool): Promise<Sandbox> {\n    const sandbox = new Sandbox(warmPoolItem.target)\n\n    sandbox.organizationId = SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION\n\n    sandbox.class = warmPoolItem.class\n    sandbox.snapshot = warmPoolItem.snapshot\n    //  TODO: default user should be configurable\n    sandbox.osUser = 'daytona'\n    sandbox.env = warmPoolItem.env || {}\n\n    sandbox.cpu = warmPoolItem.cpu\n    sandbox.gpu = warmPoolItem.gpu\n    sandbox.mem = warmPoolItem.mem\n    sandbox.disk = warmPoolItem.disk\n\n    const snapshot = await this.snapshotRepository.findOne({\n      where: [\n        { organizationId: sandbox.organizationId, name: sandbox.snapshot, state: SnapshotState.ACTIVE },\n        { general: true, name: sandbox.snapshot, state: SnapshotState.ACTIVE },\n      ],\n    })\n    if (!snapshot) {\n      throw new BadRequestError(`Snapshot ${sandbox.snapshot} not found while creating warm pool sandbox`)\n    }\n\n    const runner = await this.runnerService.getRandomAvailableRunner({\n      regions: [sandbox.region],\n      sandboxClass: sandbox.class,\n      snapshotRef: snapshot.ref,\n    })\n\n    sandbox.runnerId = runner.id\n    sandbox.pending = true\n\n    await this.sandboxRepository.insert(sandbox)\n    return sandbox\n  }\n\n  async createFromSnapshot(\n    createSandboxDto: CreateSandboxDto,\n    organization: Organization,\n    useSandboxResourceParams_deprecated?: boolean,\n  ): Promise<SandboxDto> {\n    let pendingCpuIncrement: number | undefined\n    let pendingMemoryIncrement: number | undefined\n    let pendingDiskIncrement: number | undefined\n\n    const region = await this.getValidatedOrDefaultRegion(organization, createSandboxDto.target)\n\n    try {\n      const sandboxClass = this.getValidatedOrDefaultClass(createSandboxDto.class)\n\n      let snapshotIdOrName = createSandboxDto.snapshot\n\n      if (!createSandboxDto.snapshot?.trim()) {\n        snapshotIdOrName = this.configService.getOrThrow('defaultSnapshot')\n      }\n\n      const snapshotFilter: FindOptionsWhere<Snapshot>[] = [\n        { organizationId: organization.id, name: snapshotIdOrName },\n        { general: true, name: snapshotIdOrName },\n      ]\n\n      if (isValidUuid(snapshotIdOrName)) {\n        snapshotFilter.push(\n          { organizationId: organization.id, id: snapshotIdOrName },\n          { general: true, id: snapshotIdOrName },\n        )\n      }\n\n      const snapshots = await this.snapshotRepository.find({\n        where: snapshotFilter,\n      })\n\n      if (snapshots.length === 0) {\n        throw new BadRequestError(\n          `Snapshot ${snapshotIdOrName} not found. Did you add it through the Daytona Dashboard?`,\n        )\n      }\n\n      let snapshot = snapshots.find((s) => s.state === SnapshotState.ACTIVE)\n\n      if (!snapshot) {\n        snapshot = snapshots[0]\n      }\n\n      if (!(await this.snapshotService.isAvailableInRegion(snapshot.id, region.id))) {\n        throw new BadRequestError(`Snapshot ${snapshotIdOrName} is not available in region ${region.id}`)\n      }\n\n      if (snapshot.state !== SnapshotState.ACTIVE) {\n        throw new BadRequestError(`Snapshot ${snapshotIdOrName} is ${snapshot.state}`)\n      }\n\n      if (!snapshot.ref) {\n        throw new BadRequestError('Snapshot ref is not defined')\n      }\n\n      let cpu = snapshot.cpu\n      let mem = snapshot.mem\n      let disk = snapshot.disk\n      let gpu = snapshot.gpu\n\n      // Remove the deprecated behavior in a future release\n      if (useSandboxResourceParams_deprecated) {\n        if (createSandboxDto.cpu) {\n          cpu = createSandboxDto.cpu\n        }\n        if (createSandboxDto.memory) {\n          mem = createSandboxDto.memory\n        }\n        if (createSandboxDto.disk) {\n          disk = createSandboxDto.disk\n        }\n        if (createSandboxDto.gpu) {\n          gpu = createSandboxDto.gpu\n        }\n      }\n\n      this.organizationService.assertOrganizationIsNotSuspended(organization)\n\n      const { pendingCpuIncremented, pendingMemoryIncremented, pendingDiskIncremented } =\n        await this.validateOrganizationQuotas(organization, region, cpu, mem, disk)\n\n      if (pendingCpuIncremented) {\n        pendingCpuIncrement = cpu\n      }\n      if (pendingMemoryIncremented) {\n        pendingMemoryIncrement = mem\n      }\n      if (pendingDiskIncremented) {\n        pendingDiskIncrement = disk\n      }\n\n      if (!createSandboxDto.volumes || createSandboxDto.volumes.length === 0) {\n        const skipWarmPool = (await this.redis.exists(`warm-pool:skip:${snapshot.id}`)) === 1\n\n        if (!skipWarmPool) {\n          const warmPoolSandbox = await this.warmPoolService.fetchWarmPoolSandbox({\n            organizationId: organization.id,\n            snapshot,\n            target: region.id,\n            class: createSandboxDto.class,\n            cpu: cpu,\n            mem: mem,\n            disk: disk,\n            gpu: gpu,\n            osUser: createSandboxDto.user,\n            env: createSandboxDto.env,\n            state: SandboxState.STARTED,\n          })\n\n          if (warmPoolSandbox) {\n            return await this.assignWarmPoolSandbox(warmPoolSandbox, createSandboxDto, organization)\n          }\n        }\n      } else {\n        const volumeIdOrNames = createSandboxDto.volumes.map((v) => v.volumeId)\n        await this.volumeService.validateVolumes(organization.id, volumeIdOrNames)\n      }\n\n      const runner = await this.runnerService.getRandomAvailableRunner({\n        regions: [region.id],\n        sandboxClass,\n        snapshotRef: snapshot.ref,\n      })\n\n      const sandbox = new Sandbox(region.id, createSandboxDto.name)\n\n      sandbox.organizationId = organization.id\n\n      //  TODO: make configurable\n      sandbox.class = sandboxClass\n      sandbox.snapshot = snapshot.name\n      //  TODO: default user should be configurable\n      sandbox.osUser = createSandboxDto.user || 'daytona'\n      sandbox.env = createSandboxDto.env || {}\n      sandbox.labels = createSandboxDto.labels || {}\n\n      sandbox.cpu = cpu\n      sandbox.gpu = gpu\n      sandbox.mem = mem\n      sandbox.disk = disk\n\n      sandbox.public = createSandboxDto.public || false\n\n      if (createSandboxDto.networkBlockAll !== undefined) {\n        sandbox.networkBlockAll = createSandboxDto.networkBlockAll\n      }\n\n      if (createSandboxDto.networkAllowList !== undefined) {\n        sandbox.networkAllowList = this.resolveNetworkAllowList(createSandboxDto.networkAllowList)\n      }\n\n      if (createSandboxDto.autoStopInterval !== undefined) {\n        sandbox.autoStopInterval = this.resolveAutoStopInterval(createSandboxDto.autoStopInterval)\n      }\n\n      if (createSandboxDto.autoArchiveInterval !== undefined) {\n        sandbox.autoArchiveInterval = this.resolveAutoArchiveInterval(createSandboxDto.autoArchiveInterval)\n      }\n\n      if (createSandboxDto.autoDeleteInterval !== undefined) {\n        sandbox.autoDeleteInterval = createSandboxDto.autoDeleteInterval\n      }\n\n      if (createSandboxDto.volumes !== undefined) {\n        sandbox.volumes = this.resolveVolumes(createSandboxDto.volumes)\n      }\n\n      sandbox.runnerId = runner.id\n      sandbox.pending = true\n\n      const insertedSandbox = await this.sandboxRepository.insert(sandbox)\n\n      this.eventEmitter.emit(SandboxEvents.CREATED, new SandboxCreatedEvent(insertedSandbox))\n\n      return this.toSandboxDto(insertedSandbox)\n    } catch (error) {\n      await this.rollbackPendingUsage(\n        organization.id,\n        region.id,\n        pendingCpuIncrement,\n        pendingMemoryIncrement,\n        pendingDiskIncrement,\n      )\n\n      if (error.code === '23505') {\n        throw new ConflictException(`Sandbox with name ${createSandboxDto.name} already exists`)\n      }\n\n      throw error\n    }\n  }\n\n  private async assignWarmPoolSandbox(\n    warmPoolSandbox: Sandbox,\n    createSandboxDto: CreateSandboxDto,\n    organization: Organization,\n  ): Promise<SandboxDto> {\n    const now = new Date()\n    const updateData: Partial<Sandbox> = {\n      public: createSandboxDto.public || false,\n      labels: createSandboxDto.labels || {},\n      organizationId: organization.id,\n      createdAt: now,\n      lastActivityAt: now,\n    }\n\n    if (createSandboxDto.name) {\n      updateData.name = createSandboxDto.name\n    }\n\n    if (createSandboxDto.autoStopInterval !== undefined) {\n      updateData.autoStopInterval = this.resolveAutoStopInterval(createSandboxDto.autoStopInterval)\n    }\n\n    if (createSandboxDto.autoArchiveInterval !== undefined) {\n      updateData.autoArchiveInterval = this.resolveAutoArchiveInterval(createSandboxDto.autoArchiveInterval)\n    }\n\n    if (createSandboxDto.autoDeleteInterval !== undefined) {\n      updateData.autoDeleteInterval = createSandboxDto.autoDeleteInterval\n    }\n\n    if (createSandboxDto.networkBlockAll !== undefined) {\n      updateData.networkBlockAll = createSandboxDto.networkBlockAll\n    }\n\n    if (createSandboxDto.networkAllowList !== undefined) {\n      updateData.networkAllowList = this.resolveNetworkAllowList(createSandboxDto.networkAllowList)\n    }\n\n    if (!warmPoolSandbox.runnerId) {\n      throw new SandboxError('Runner not found for warm pool sandbox')\n    }\n\n    if (\n      createSandboxDto.networkBlockAll !== undefined ||\n      createSandboxDto.networkAllowList !== undefined ||\n      organization.sandboxLimitedNetworkEgress\n    ) {\n      const runner = await this.runnerService.findOneOrFail(warmPoolSandbox.runnerId)\n      const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n      await runnerAdapter.updateNetworkSettings(\n        warmPoolSandbox.id,\n        createSandboxDto.networkBlockAll,\n        createSandboxDto.networkAllowList,\n        organization.sandboxLimitedNetworkEgress,\n      )\n    }\n\n    const updatedSandbox = await this.sandboxRepository.update(warmPoolSandbox.id, {\n      updateData,\n      entity: warmPoolSandbox,\n    })\n\n    // Defensive invalidation of orgId cache since the sandbox moved from unassigned to a real organization\n    this.sandboxLookupCacheInvalidationService.invalidateOrgId({\n      sandboxId: warmPoolSandbox.id,\n      organizationId: organization.id,\n      name: warmPoolSandbox.name,\n      previousOrganizationId: SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION,\n    })\n\n    // Treat this as a newly started sandbox\n    this.eventEmitter.emit(\n      SandboxEvents.STATE_UPDATED,\n      new SandboxStateUpdatedEvent(updatedSandbox, SandboxState.STARTED, SandboxState.STARTED),\n    )\n    return this.toSandboxDto(updatedSandbox)\n  }\n\n  async createFromBuildInfo(createSandboxDto: CreateSandboxDto, organization: Organization): Promise<SandboxDto> {\n    let pendingCpuIncrement: number | undefined\n    let pendingMemoryIncrement: number | undefined\n    let pendingDiskIncrement: number | undefined\n\n    const region = await this.getValidatedOrDefaultRegion(organization, createSandboxDto.target)\n\n    try {\n      const sandboxClass = this.getValidatedOrDefaultClass(createSandboxDto.class)\n\n      const cpu = createSandboxDto.cpu || DEFAULT_CPU\n      const mem = createSandboxDto.memory || DEFAULT_MEMORY\n      const disk = createSandboxDto.disk || DEFAULT_DISK\n      const gpu = createSandboxDto.gpu || DEFAULT_GPU\n\n      this.organizationService.assertOrganizationIsNotSuspended(organization)\n\n      const { pendingCpuIncremented, pendingMemoryIncremented, pendingDiskIncremented } =\n        await this.validateOrganizationQuotas(organization, region, cpu, mem, disk)\n\n      if (pendingCpuIncremented) {\n        pendingCpuIncrement = cpu\n      }\n      if (pendingMemoryIncremented) {\n        pendingMemoryIncrement = mem\n      }\n      if (pendingDiskIncremented) {\n        pendingDiskIncrement = disk\n      }\n\n      if (createSandboxDto.volumes && createSandboxDto.volumes.length > 0) {\n        const volumeIdOrNames = createSandboxDto.volumes.map((v) => v.volumeId)\n        await this.volumeService.validateVolumes(organization.id, volumeIdOrNames)\n      }\n\n      const sandbox = new Sandbox(region.id, createSandboxDto.name)\n\n      sandbox.organizationId = organization.id\n\n      sandbox.class = sandboxClass\n      sandbox.osUser = createSandboxDto.user || 'daytona'\n      sandbox.env = createSandboxDto.env || {}\n      sandbox.labels = createSandboxDto.labels || {}\n\n      sandbox.cpu = cpu\n      sandbox.gpu = gpu\n      sandbox.mem = mem\n      sandbox.disk = disk\n      sandbox.public = createSandboxDto.public || false\n\n      if (createSandboxDto.networkBlockAll !== undefined) {\n        sandbox.networkBlockAll = createSandboxDto.networkBlockAll\n      }\n\n      if (createSandboxDto.networkAllowList !== undefined) {\n        sandbox.networkAllowList = this.resolveNetworkAllowList(createSandboxDto.networkAllowList)\n      }\n\n      if (createSandboxDto.autoStopInterval !== undefined) {\n        sandbox.autoStopInterval = this.resolveAutoStopInterval(createSandboxDto.autoStopInterval)\n      }\n\n      if (createSandboxDto.autoArchiveInterval !== undefined) {\n        sandbox.autoArchiveInterval = this.resolveAutoArchiveInterval(createSandboxDto.autoArchiveInterval)\n      }\n\n      if (createSandboxDto.autoDeleteInterval !== undefined) {\n        sandbox.autoDeleteInterval = createSandboxDto.autoDeleteInterval\n      }\n\n      if (createSandboxDto.volumes !== undefined) {\n        sandbox.volumes = this.resolveVolumes(createSandboxDto.volumes)\n      }\n\n      const buildInfoSnapshotRef = generateBuildSnapshotRef(\n        createSandboxDto.buildInfo.dockerfileContent,\n        createSandboxDto.buildInfo.contextHashes,\n      )\n\n      // Check if buildInfo with the same snapshotRef already exists\n      const existingBuildInfo = await this.buildInfoRepository.findOne({\n        where: { snapshotRef: buildInfoSnapshotRef },\n      })\n\n      if (existingBuildInfo) {\n        sandbox.buildInfo = existingBuildInfo\n        if (await this.redisLockProvider.lock(`build-info:${existingBuildInfo.snapshotRef}:update`, 60)) {\n          await this.buildInfoRepository.update(sandbox.buildInfo.snapshotRef, { lastUsedAt: new Date() })\n        }\n      } else {\n        const buildInfoEntity = this.buildInfoRepository.create({\n          ...createSandboxDto.buildInfo,\n        })\n        await this.buildInfoRepository.save(buildInfoEntity)\n        sandbox.buildInfo = buildInfoEntity\n      }\n\n      let runner: Runner\n\n      try {\n        const declarativeBuildScoreThreshold = this.configService.get('runnerScore.thresholds.declarativeBuild')\n        runner = await this.runnerService.getRandomAvailableRunner({\n          regions: [sandbox.region],\n          sandboxClass: sandbox.class,\n          snapshotRef: sandbox.buildInfo.snapshotRef,\n          ...(declarativeBuildScoreThreshold !== undefined && {\n            availabilityScoreThreshold: declarativeBuildScoreThreshold,\n          }),\n        })\n        sandbox.runnerId = runner.id\n      } catch (error) {\n        if (\n          error instanceof BadRequestError == false ||\n          error.message !== 'No available runners' ||\n          !sandbox.buildInfo\n        ) {\n          throw error\n        }\n        sandbox.state = SandboxState.PENDING_BUILD\n      }\n\n      sandbox.pending = true\n\n      const insertedSandbox = await this.sandboxRepository.insert(sandbox)\n\n      this.eventEmitter.emit(SandboxEvents.CREATED, new SandboxCreatedEvent(insertedSandbox))\n\n      return this.toSandboxDto(insertedSandbox)\n    } catch (error) {\n      await this.rollbackPendingUsage(\n        organization.id,\n        region.id,\n        pendingCpuIncrement,\n        pendingMemoryIncrement,\n        pendingDiskIncrement,\n      )\n\n      if (error.code === '23505') {\n        throw new ConflictException(`Sandbox with name ${createSandboxDto.name} already exists`)\n      }\n\n      throw error\n    }\n  }\n\n  async createBackup(sandboxIdOrName: string, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    if (sandbox.autoDeleteInterval === 0) {\n      throw new SandboxError('Ephemeral sandboxes cannot be backed up')\n    }\n\n    if (![BackupState.COMPLETED, BackupState.NONE].includes(sandbox.backupState)) {\n      throw new SandboxError('Sandbox backup is already in progress')\n    }\n\n    this.eventEmitter.emit(SandboxEvents.BACKUP_CREATED, new SandboxBackupCreatedEvent(sandbox))\n\n    return sandbox\n  }\n\n  async findAllDeprecated(\n    organizationId: string,\n    labels?: { [key: string]: string },\n    includeErroredDestroyed?: boolean,\n  ): Promise<Sandbox[]> {\n    const baseFindOptions: FindOptionsWhere<Sandbox> = {\n      organizationId,\n      ...(labels ? { labels: JsonContains(labels) } : {}),\n    }\n\n    const where: FindOptionsWhere<Sandbox>[] = [\n      {\n        ...baseFindOptions,\n        state: Not(In([SandboxState.DESTROYED, SandboxState.ERROR, SandboxState.BUILD_FAILED])),\n      },\n      {\n        ...baseFindOptions,\n        state: In([SandboxState.ERROR, SandboxState.BUILD_FAILED]),\n        ...(includeErroredDestroyed ? {} : { desiredState: Not(SandboxDesiredState.DESTROYED) }),\n      },\n    ]\n\n    return this.sandboxRepository.find({ where })\n  }\n\n  async findAll(\n    organizationId: string,\n    page = 1,\n    limit = 10,\n    filters?: {\n      id?: string\n      name?: string\n      labels?: { [key: string]: string }\n      includeErroredDestroyed?: boolean\n      states?: SandboxState[]\n      snapshots?: string[]\n      regionIds?: string[]\n      minCpu?: number\n      maxCpu?: number\n      minMemoryGiB?: number\n      maxMemoryGiB?: number\n      minDiskGiB?: number\n      maxDiskGiB?: number\n      lastEventAfter?: Date\n      lastEventBefore?: Date\n    },\n    sort?: {\n      field?: SandboxSortField\n      direction?: SandboxSortDirection\n    },\n  ): Promise<PaginatedList<Sandbox>> {\n    const pageNum = Number(page)\n    const limitNum = Number(limit)\n\n    const {\n      id,\n      name,\n      labels,\n      includeErroredDestroyed,\n      states,\n      snapshots,\n      regionIds,\n      minCpu,\n      maxCpu,\n      minMemoryGiB,\n      maxMemoryGiB,\n      minDiskGiB,\n      maxDiskGiB,\n      lastEventAfter,\n      lastEventBefore,\n    } = filters || {}\n\n    const { field: sortField = DEFAULT_SANDBOX_SORT_FIELD, direction: sortDirection = DEFAULT_SANDBOX_SORT_DIRECTION } =\n      sort || {}\n\n    const baseFindOptions: FindOptionsWhere<Sandbox> = {\n      organizationId,\n      ...(id ? { id: ILike(`${id}%`) } : {}),\n      ...(name ? { name: ILike(`${name}%`) } : {}),\n      ...(labels ? { labels: JsonContains(labels) } : {}),\n      ...(snapshots ? { snapshot: In(snapshots) } : {}),\n      ...(regionIds ? { region: In(regionIds) } : {}),\n    }\n\n    baseFindOptions.cpu = createRangeFilter(minCpu, maxCpu)\n    baseFindOptions.mem = createRangeFilter(minMemoryGiB, maxMemoryGiB)\n    baseFindOptions.disk = createRangeFilter(minDiskGiB, maxDiskGiB)\n    baseFindOptions.lastActivityAt = createRangeFilter(lastEventAfter, lastEventBefore)\n\n    const statesToInclude = (states || Object.values(SandboxState)).filter((state) => state !== SandboxState.DESTROYED)\n    const errorStates = [SandboxState.ERROR, SandboxState.BUILD_FAILED]\n\n    const nonErrorStatesToInclude = statesToInclude.filter((state) => !errorStates.includes(state))\n    const errorStatesToInclude = statesToInclude.filter((state) => errorStates.includes(state))\n\n    const where: FindOptionsWhere<Sandbox>[] = []\n\n    if (nonErrorStatesToInclude.length > 0) {\n      where.push({\n        ...baseFindOptions,\n        state: In(nonErrorStatesToInclude),\n      })\n    }\n\n    if (errorStatesToInclude.length > 0) {\n      where.push({\n        ...baseFindOptions,\n        state: In(errorStatesToInclude),\n        ...(includeErroredDestroyed ? {} : { desiredState: Not(SandboxDesiredState.DESTROYED) }),\n      })\n    }\n\n    const [items, total] = await this.sandboxRepository.findAndCount({\n      where,\n      order: {\n        [sortField]: {\n          direction: sortDirection,\n          nulls: 'LAST',\n        },\n        ...(sortField !== SandboxSortField.CREATED_AT && { createdAt: 'DESC' }),\n      },\n      skip: (pageNum - 1) * limitNum,\n      take: limitNum,\n    })\n\n    return {\n      items,\n      total,\n      page: pageNum,\n      totalPages: Math.ceil(total / limitNum),\n    }\n  }\n\n  private getExpectedDesiredStateForState(state: SandboxState): SandboxDesiredState | undefined {\n    switch (state) {\n      case SandboxState.STARTED:\n        return SandboxDesiredState.STARTED\n      case SandboxState.STOPPED:\n        return SandboxDesiredState.STOPPED\n      case SandboxState.ARCHIVED:\n        return SandboxDesiredState.ARCHIVED\n      case SandboxState.DESTROYED:\n        return SandboxDesiredState.DESTROYED\n      default:\n        return undefined\n    }\n  }\n\n  private hasValidDesiredState(state: SandboxState): boolean {\n    return this.getExpectedDesiredStateForState(state) !== undefined\n  }\n\n  async findByRunnerId(\n    runnerId: string,\n    states?: SandboxState[],\n    skipReconcilingSandboxes?: boolean,\n  ): Promise<Sandbox[]> {\n    const where: FindOptionsWhere<Sandbox> = { runnerId }\n    if (states && states.length > 0) {\n      // Validate that all states have corresponding desired states\n      states.forEach((state) => {\n        if (!this.hasValidDesiredState(state)) {\n          throw new BadRequestError(`State ${state} does not have a corresponding desired state`)\n        }\n      })\n      where.state = In(states)\n    }\n\n    let sandboxes = await this.sandboxRepository.find({ where })\n\n    if (skipReconcilingSandboxes) {\n      sandboxes = sandboxes.filter((sandbox) => {\n        const expectedDesiredState = this.getExpectedDesiredStateForState(sandbox.state)\n        return expectedDesiredState !== undefined && expectedDesiredState === sandbox.desiredState\n      })\n    }\n\n    return sandboxes\n  }\n\n  async findOneByIdOrName(\n    sandboxIdOrName: string,\n    organizationId: string,\n    returnDestroyed?: boolean,\n  ): Promise<Sandbox> {\n    const stateFilter = returnDestroyed ? {} : { state: Not(SandboxState.DESTROYED) }\n    const relations: ['buildInfo'] = ['buildInfo']\n\n    // Try lookup by ID first\n    let sandbox = await this.sandboxRepository.findOne({\n      where: {\n        id: sandboxIdOrName,\n        organizationId,\n        ...stateFilter,\n      },\n      relations,\n      cache: {\n        id: sandboxLookupCacheKeyById({ organizationId, returnDestroyed, sandboxId: sandboxIdOrName }),\n        milliseconds: SANDBOX_LOOKUP_CACHE_TTL_MS,\n      },\n    })\n\n    // Fallback to lookup by name\n    if (!sandbox) {\n      sandbox = await this.sandboxRepository.findOne({\n        where: {\n          name: sandboxIdOrName,\n          organizationId,\n          ...stateFilter,\n        },\n        relations,\n        cache: {\n          id: sandboxLookupCacheKeyByName({ organizationId, returnDestroyed, sandboxName: sandboxIdOrName }),\n          milliseconds: SANDBOX_LOOKUP_CACHE_TTL_MS,\n        },\n      })\n    }\n\n    if (\n      !sandbox ||\n      (!returnDestroyed &&\n        [SandboxState.ERROR, SandboxState.BUILD_FAILED].includes(sandbox.state) &&\n        sandbox.desiredState === SandboxDesiredState.DESTROYED)\n    ) {\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxIdOrName} not found`)\n    }\n\n    return sandbox\n  }\n\n  async findOne(sandboxId: string, returnDestroyed?: boolean): Promise<Sandbox> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: {\n        id: sandboxId,\n        ...(returnDestroyed ? {} : { state: Not(SandboxState.DESTROYED) }),\n      },\n    })\n\n    if (\n      !sandbox ||\n      (!returnDestroyed &&\n        [SandboxState.ERROR, SandboxState.BUILD_FAILED].includes(sandbox.state) &&\n        sandbox.desiredState === SandboxDesiredState.DESTROYED)\n    ) {\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n\n    return sandbox\n  }\n\n  async getOrganizationId(sandboxIdOrName: string, organizationId?: string): Promise<string> {\n    let sandbox = await this.sandboxRepository.findOne({\n      where: {\n        id: sandboxIdOrName,\n        ...(organizationId ? { organizationId: organizationId } : {}),\n      },\n      select: ['organizationId'],\n      cache: {\n        id: sandboxOrgIdCacheKeyById({ organizationId, sandboxId: sandboxIdOrName }),\n        milliseconds: SANDBOX_ORG_ID_CACHE_TTL_MS,\n      },\n    })\n\n    if (!sandbox && organizationId) {\n      sandbox = await this.sandboxRepository.findOne({\n        where: {\n          name: sandboxIdOrName,\n          organizationId: organizationId,\n        },\n        select: ['organizationId'],\n        cache: {\n          id: sandboxOrgIdCacheKeyByName({ organizationId, sandboxName: sandboxIdOrName }),\n          milliseconds: SANDBOX_ORG_ID_CACHE_TTL_MS,\n        },\n      })\n    }\n\n    if (!sandbox || !sandbox.organizationId) {\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxIdOrName} not found`)\n    }\n\n    return sandbox.organizationId\n  }\n\n  async getRunnerId(sandboxId: string): Promise<string | null> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: {\n        id: sandboxId,\n      },\n      select: ['runnerId'],\n      loadEagerRelations: false,\n    })\n\n    if (!sandbox) {\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n\n    return sandbox.runnerId || null\n  }\n\n  async getRegionId(sandboxId: string): Promise<string> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: {\n        id: sandboxId,\n      },\n      select: ['region'],\n      loadEagerRelations: false,\n    })\n\n    if (!sandbox) {\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n\n    return sandbox.region\n  }\n\n  async getPortPreviewUrl(sandboxIdOrName: string, organizationId: string, port: number): Promise<PortPreviewUrlDto> {\n    if (port < 1 || port > 65535) {\n      throw new BadRequestError('Invalid port')\n    }\n\n    const proxyDomain = this.configService.getOrThrow('proxy.domain')\n    const proxyProtocol = this.configService.getOrThrow('proxy.protocol')\n\n    const where: FindOptionsWhere<Sandbox> = {\n      organizationId: organizationId,\n      state: Not(SandboxState.DESTROYED),\n    }\n\n    const sandbox = await this.sandboxRepository.findOne({\n      where: [\n        {\n          id: sandboxIdOrName,\n          ...where,\n        },\n        {\n          name: sandboxIdOrName,\n          ...where,\n        },\n      ],\n      cache: {\n        id: `sandbox:${sandboxIdOrName}:organization:${organizationId}`,\n        milliseconds: 1000,\n      },\n    })\n\n    if (!sandbox) {\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxIdOrName} not found`)\n    }\n\n    let url = `${proxyProtocol}://${port}-${sandbox.id}.${proxyDomain}`\n\n    const region = await this.regionService.findOne(sandbox.region, true)\n    if (region && region.proxyUrl) {\n      // Insert port and sandbox.id into the custom proxy URL\n      url = region.proxyUrl.replace(/(https?:\\/)(\\/)/, `$1/${port}-${sandbox.id}.`)\n    }\n\n    return {\n      sandboxId: sandbox.id,\n      url,\n      token: sandbox.authToken,\n    }\n  }\n\n  async getSignedPortPreviewUrl(\n    sandboxIdOrName: string,\n    organizationId: string,\n    port: number,\n    expiresInSeconds = 60,\n  ): Promise<SignedPortPreviewUrlDto> {\n    if (port < 1 || port > 65535) {\n      throw new BadRequestError('Invalid port')\n    }\n\n    if (expiresInSeconds < 1 || expiresInSeconds > 60 * 60 * 24) {\n      throw new BadRequestError('expiresInSeconds must be between 1 second and 24 hours')\n    }\n\n    const proxyDomain = this.configService.getOrThrow('proxy.domain')\n    const proxyProtocol = this.configService.getOrThrow('proxy.protocol')\n\n    const where: FindOptionsWhere<Sandbox> = {\n      organizationId: organizationId,\n      state: Not(SandboxState.DESTROYED),\n    }\n\n    const sandbox = await this.sandboxRepository.findOne({\n      where: [\n        {\n          id: sandboxIdOrName,\n          ...where,\n        },\n        {\n          name: sandboxIdOrName,\n          ...where,\n        },\n      ],\n      cache: {\n        id: `sandbox:${sandboxIdOrName}:organization:${organizationId}`,\n        milliseconds: 1000,\n      },\n    })\n\n    if (!sandbox) {\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxIdOrName} not found`)\n    }\n\n    const token = customNanoid(urlAlphabet.replace('_', '').replace('-', ''))(16).toLocaleLowerCase()\n\n    const lockKey = `sandbox:signed-preview-url-token:${port}:${token}`\n    await this.redis.setex(lockKey, expiresInSeconds, sandbox.id)\n\n    let url = `${proxyProtocol}://${port}-${token}.${proxyDomain}`\n\n    const region = await this.regionService.findOne(sandbox.region, true)\n    if (region && region.proxyUrl) {\n      // Insert port and sandbox.id into the custom proxy URL\n      url = region.proxyUrl.replace(/(https?:\\/)(\\/)/, `$1/${port}-${token}.`)\n    }\n\n    return {\n      sandboxId: sandbox.id,\n      port,\n      token,\n      url,\n    }\n  }\n\n  async getSandboxIdFromSignedPreviewUrlToken(token: string, port: number): Promise<string> {\n    const lockKey = `sandbox:signed-preview-url-token:${port}:${token}`\n    const sandboxId = await this.redis.get(lockKey)\n    if (!sandboxId) {\n      throw new ForbiddenException('Invalid or expired token')\n    }\n    return sandboxId\n  }\n\n  async expireSignedPreviewUrlToken(\n    sandboxIdOrName: string,\n    organizationId: string,\n    token: string,\n    port: number,\n  ): Promise<void> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n    if (!sandbox) {\n      throw new NotFoundException(`Sandbox with ID or name ${sandboxIdOrName} not found`)\n    }\n\n    const lockKey = `sandbox:signed-preview-url-token:${port}:${token}`\n    await this.redis.del(lockKey)\n  }\n\n  async destroy(sandboxIdOrName: string, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    if (sandbox.pending && sandbox.state !== SandboxState.PENDING_BUILD) {\n      throw new SandboxError('Sandbox state change in progress')\n    }\n\n    const updateData = Sandbox.getSoftDeleteUpdate(sandbox)\n\n    const updatedSandbox = await this.sandboxRepository.updateWhere(sandbox.id, {\n      updateData,\n      whereCondition: { pending: sandbox.pending, state: sandbox.state },\n    })\n\n    this.eventEmitter.emit(SandboxEvents.DESTROYED, new SandboxDestroyedEvent(updatedSandbox))\n    return updatedSandbox\n  }\n\n  async start(sandboxIdOrName: string, organization: Organization): Promise<Sandbox> {\n    let pendingCpuIncrement: number | undefined\n    let pendingMemoryIncrement: number | undefined\n    let pendingDiskIncrement: number | undefined\n\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organization.id)\n\n    const region = await this.regionService.findOne(sandbox.region)\n    if (!region) {\n      throw new NotFoundException(`Region with ID ${sandbox.region} not found`)\n    }\n\n    try {\n      if (sandbox.state === SandboxState.STARTED && sandbox.desiredState === SandboxDesiredState.STARTED) {\n        return sandbox\n      }\n\n      this.assertSandboxNotErrored(sandbox)\n\n      if (String(sandbox.state) !== String(sandbox.desiredState)) {\n        // Allow start of stopped | archived and archiving | archived sandboxes\n        if (\n          sandbox.desiredState !== SandboxDesiredState.ARCHIVED ||\n          (sandbox.state !== SandboxState.STOPPED && sandbox.state !== SandboxState.ARCHIVING)\n        ) {\n          throw new SandboxError('State change in progress')\n        }\n      }\n\n      if (![SandboxState.STOPPED, SandboxState.ARCHIVED, SandboxState.ARCHIVING].includes(sandbox.state)) {\n        throw new SandboxError('Sandbox is not in valid state')\n      }\n\n      if (sandbox.pending) {\n        throw new SandboxError('Sandbox state change in progress')\n      }\n\n      this.organizationService.assertOrganizationIsNotSuspended(organization)\n\n      const { pendingCpuIncremented, pendingMemoryIncremented, pendingDiskIncremented } =\n        await this.validateOrganizationQuotas(organization, region, sandbox.cpu, sandbox.mem, sandbox.disk, sandbox.id)\n\n      if (pendingCpuIncremented) {\n        pendingCpuIncrement = sandbox.cpu\n      }\n      if (pendingMemoryIncremented) {\n        pendingMemoryIncrement = sandbox.mem\n      }\n      if (pendingDiskIncremented) {\n        pendingDiskIncrement = sandbox.disk\n      }\n\n      const updateData: Partial<Sandbox> = {\n        pending: true,\n        desiredState: SandboxDesiredState.STARTED,\n        authToken: nanoid(32).toLocaleLowerCase(),\n      }\n\n      const updatedSandbox = await this.sandboxRepository.updateWhere(sandbox.id, {\n        updateData,\n        whereCondition: { pending: false, state: sandbox.state },\n      })\n\n      this.eventEmitter.emit(SandboxEvents.STARTED, new SandboxStartedEvent(updatedSandbox))\n\n      return updatedSandbox\n    } catch (error) {\n      await this.rollbackPendingUsage(\n        organization.id,\n        sandbox.region,\n        pendingCpuIncrement,\n        pendingMemoryIncrement,\n        pendingDiskIncrement,\n      )\n      throw error\n    }\n  }\n\n  async stop(sandboxIdOrName: string, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    this.assertSandboxNotErrored(sandbox)\n\n    if (String(sandbox.state) !== String(sandbox.desiredState)) {\n      throw new SandboxError('State change in progress')\n    }\n\n    if (sandbox.state !== SandboxState.STARTED) {\n      throw new SandboxError('Sandbox is not started')\n    }\n\n    if (sandbox.pending) {\n      throw new SandboxError('Sandbox state change in progress')\n    }\n\n    const updateData: Partial<Sandbox> = {\n      pending: true,\n      desiredState: sandbox.autoDeleteInterval === 0 ? SandboxDesiredState.DESTROYED : SandboxDesiredState.STOPPED,\n    }\n\n    const updatedSandbox = await this.sandboxRepository.updateWhere(sandbox.id, {\n      updateData,\n      whereCondition: { pending: false, state: sandbox.state },\n    })\n\n    if (sandbox.autoDeleteInterval === 0) {\n      this.eventEmitter.emit(SandboxEvents.DESTROYED, new SandboxDestroyedEvent(updatedSandbox))\n    } else {\n      this.eventEmitter.emit(SandboxEvents.STOPPED, new SandboxStoppedEvent(updatedSandbox))\n    }\n\n    return updatedSandbox\n  }\n\n  async recover(sandboxIdOrName: string, organization: Organization): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organization.id)\n\n    if (sandbox.state !== SandboxState.ERROR) {\n      throw new BadRequestError('Sandbox must be in error state to recover')\n    }\n\n    if (sandbox.pending) {\n      throw new SandboxError('Sandbox state change in progress')\n    }\n\n    // Validate runner exists\n    if (!sandbox.runnerId) {\n      throw new NotFoundException(`Sandbox with ID ${sandbox.id} does not have a runner`)\n    }\n    const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n\n    if (runner.apiVersion === '2') {\n      // TODO: we need \"recovering\" state that can be set after calling recover\n      // Once in recovering, we abort further processing and let the manager/job handler take care of it\n      // (Also, since desiredState would be STARTED, we need to check the quota)\n      throw new ForbiddenException('Recovering sandboxes with runner API version 2 is not supported')\n    }\n\n    const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n    try {\n      await runnerAdapter.recoverSandbox(sandbox)\n    } catch (error) {\n      if (error instanceof Error && error.message.includes('storage cannot be further expanded')) {\n        const errorMsg = `Sandbox storage cannot be further expanded. Maximum expansion of ${(sandbox.disk * 0.1).toFixed(2)}GB (10% of original ${sandbox.disk.toFixed(2)}GB) has been reached. Please contact support for further assistance.`\n        throw new ForbiddenException(errorMsg)\n      }\n      throw error\n    }\n\n    const updateData: Partial<Sandbox> = {\n      state: SandboxState.STOPPED,\n      desiredState: SandboxDesiredState.STOPPED,\n      errorReason: null,\n      recoverable: false,\n    }\n\n    await this.sandboxRepository.updateWhere(sandbox.id, {\n      updateData,\n      whereCondition: { state: SandboxState.ERROR },\n    })\n\n    // Now that sandbox is in STOPPED state, use the normal start flow\n    // This handles quota validation, pending usage, event emission, etc.\n    return await this.start(sandbox.id, organization)\n  }\n\n  async resize(sandboxIdOrName: string, resizeDto: ResizeSandboxDto, organization: Organization): Promise<Sandbox> {\n    let pendingCpuIncrement: number | undefined\n    let pendingMemoryIncrement: number | undefined\n    let pendingDiskIncrement: number | undefined\n\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organization.id)\n\n    const region = await this.regionService.findOne(sandbox.region)\n    if (!region) {\n      throw new NotFoundException(`Region with ID ${sandbox.region} not found`)\n    }\n\n    try {\n      // Validate sandbox is in a valid state for resize\n      if (sandbox.state !== SandboxState.STARTED && sandbox.state !== SandboxState.STOPPED) {\n        throw new BadRequestError('Sandbox must be in started or stopped state to resize')\n      }\n\n      if (sandbox.pending) {\n        throw new SandboxError('Sandbox state change in progress')\n      }\n\n      // If no resize parameters provided, throw error\n      if (resizeDto.cpu === undefined && resizeDto.memory === undefined && resizeDto.disk === undefined) {\n        throw new BadRequestError('No resource changes specified - sandbox is already at the desired configuration')\n      }\n\n      // Disk resize requires stopped sandbox (cold resize only)\n      if (resizeDto.disk !== undefined && sandbox.state !== SandboxState.STOPPED) {\n        throw new BadRequestError('Disk resize can only be performed on a stopped sandbox')\n      }\n\n      // Hot resize (sandbox is running): only CPU and memory can be increased\n      const isHotResize = sandbox.state === SandboxState.STARTED\n\n      // Validate hot resize constraints\n      if (isHotResize) {\n        if (resizeDto.cpu !== undefined && resizeDto.cpu < sandbox.cpu) {\n          throw new BadRequestError('Sandbox must be in stopped state to decrease the number of CPU cores')\n        }\n\n        if (resizeDto.memory !== undefined && resizeDto.memory < sandbox.mem) {\n          throw new BadRequestError('Sandbox must be in stopped state to decrease memory')\n        }\n      }\n\n      // Disk can only be increased (never decreased)\n      if (resizeDto.disk !== undefined && resizeDto.disk < sandbox.disk) {\n        throw new BadRequestError('Sandbox disk size cannot be decreased')\n      }\n\n      // Calculate new resource values\n      const newCpu = resizeDto.cpu ?? sandbox.cpu\n      const newMem = resizeDto.memory ?? sandbox.mem\n      const newDisk = resizeDto.disk ?? sandbox.disk\n\n      // Throw if nothing actually changes\n      if (newCpu === sandbox.cpu && newMem === sandbox.mem && newDisk === sandbox.disk) {\n        throw new BadRequestError('No resource changes specified - sandbox is already at the desired configuration')\n      }\n\n      // Validate organization quotas for the new resource values\n      this.organizationService.assertOrganizationIsNotSuspended(organization)\n\n      // Validate per-sandbox quotas with total new values\n      if (newCpu > organization.maxCpuPerSandbox) {\n        throw new ForbiddenException(\n          `CPU request ${newCpu} exceeds maximum allowed per sandbox (${organization.maxCpuPerSandbox}).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n        )\n      }\n      if (newMem > organization.maxMemoryPerSandbox) {\n        throw new ForbiddenException(\n          `Memory request ${newMem}GB exceeds maximum allowed per sandbox (${organization.maxMemoryPerSandbox}GB).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n        )\n      }\n      if (newDisk > organization.maxDiskPerSandbox) {\n        throw new ForbiddenException(\n          `Disk request ${newDisk}GB exceeds maximum allowed per sandbox (${organization.maxDiskPerSandbox}GB).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n        )\n      }\n\n      // For cold resize, cpu/memory don't affect quota until sandbox is STARTED.\n      // For hot resize, track all deltas (positive reserves quota, negative frees quota for others).\n      const cpuDeltaForQuota = isHotResize ? newCpu - sandbox.cpu : 0\n      const memDeltaForQuota = isHotResize ? newMem - sandbox.mem : 0\n      const diskDeltaForQuota = newDisk - sandbox.disk // Disk only increases (validated at start of method)\n\n      // Validate and track pending for any non-zero quota changes\n      if (cpuDeltaForQuota !== 0 || memDeltaForQuota !== 0 || diskDeltaForQuota !== 0) {\n        const { pendingCpuIncremented, pendingMemoryIncremented, pendingDiskIncremented } =\n          await this.validateOrganizationQuotas(\n            organization,\n            region,\n            cpuDeltaForQuota,\n            memDeltaForQuota,\n            diskDeltaForQuota,\n          )\n\n        if (pendingCpuIncremented) {\n          pendingCpuIncrement = cpuDeltaForQuota\n        }\n        if (pendingMemoryIncremented) {\n          pendingMemoryIncrement = memDeltaForQuota\n        }\n        if (pendingDiskIncremented) {\n          pendingDiskIncrement = diskDeltaForQuota\n        }\n      }\n\n      // Get runner and validate before changing state\n      if (!sandbox.runnerId) {\n        throw new BadRequestError('Sandbox has no runner assigned')\n      }\n\n      const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n\n      // Capture the previous state before transitioning to RESIZING (STARTED or STOPPED)\n      const previousState =\n        sandbox.state === SandboxState.STARTED\n          ? SandboxState.STARTED\n          : sandbox.state === SandboxState.STOPPED\n            ? SandboxState.STOPPED\n            : null\n\n      if (!previousState) {\n        throw new BadRequestError('Sandbox must be in started or stopped state to resize')\n      }\n\n      // Now transition to RESIZING state\n      const updateData: Partial<Sandbox> = {\n        state: SandboxState.RESIZING,\n      }\n\n      await this.sandboxRepository.updateWhere(sandbox.id, {\n        updateData,\n        whereCondition: { pending: false, state: previousState },\n      })\n\n      try {\n        const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n\n        await runnerAdapter.resizeSandbox(sandbox.id, resizeDto.cpu, resizeDto.memory, resizeDto.disk)\n\n        // For V0 runners, update resources immediately (subscriber emits STATE_UPDATED)\n        // For V2 runners, job handler will update resources on completion\n        if (runner.apiVersion === '0') {\n          const updateData: Partial<Sandbox> = {\n            cpu: newCpu,\n            mem: newMem,\n            disk: newDisk,\n            state: previousState,\n          }\n\n          await this.sandboxRepository.updateWhere(sandbox.id, {\n            updateData,\n            whereCondition: { state: SandboxState.RESIZING },\n          })\n\n          // Apply the usage change (increments current, decrements pending)\n          // Only apply deltas for quotas that were validated/pending-incremented\n          await this.organizationUsageService.applyResizeUsageChange(\n            organization.id,\n            sandbox.region,\n            cpuDeltaForQuota,\n            memDeltaForQuota,\n            diskDeltaForQuota,\n          )\n        }\n\n        return await this.findOneByIdOrName(sandbox.id, organization.id)\n      } catch (error) {\n        // Return to previous state on error\n        const updateData: Partial<Sandbox> = {\n          state: previousState,\n        }\n\n        await this.sandboxRepository.updateWhere(sandbox.id, {\n          updateData,\n          whereCondition: { state: SandboxState.RESIZING },\n        })\n\n        throw error\n      }\n    } catch (error) {\n      await this.rollbackPendingUsage(\n        organization.id,\n        sandbox.region,\n        pendingCpuIncrement,\n        pendingMemoryIncrement,\n        pendingDiskIncrement,\n      )\n      throw error\n    }\n  }\n\n  async updatePublicStatus(sandboxIdOrName: string, isPublic: boolean, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    const updateData: Partial<Sandbox> = {\n      public: isPublic,\n    }\n\n    return await this.sandboxRepository.update(sandbox.id, {\n      updateData,\n      entity: sandbox,\n    })\n  }\n\n  async updateLastActivityAt(sandboxId: string, lastActivityAt: Date): Promise<void> {\n    // Prevent spamming updates\n    const lockKey = `sandbox:update-last-activity:${sandboxId}`\n    const acquired = await this.redisLockProvider.lock(lockKey, 45)\n    if (!acquired) {\n      return\n    }\n\n    await this.sandboxRepository.update(sandboxId, { updateData: { lastActivityAt } }, true)\n  }\n\n  async getToolboxProxyUrl(sandboxId: string): Promise<string> {\n    const sandbox = await this.findOne(sandboxId)\n    return this.resolveToolboxProxyUrl(sandbox.region)\n  }\n\n  async toSandboxDto(sandbox: Sandbox): Promise<SandboxDto> {\n    const toolboxProxyUrl = await this.resolveToolboxProxyUrl(sandbox.region)\n    return SandboxDto.fromSandbox(sandbox, toolboxProxyUrl)\n  }\n\n  async toSandboxDtos(sandboxes: Sandbox[]): Promise<SandboxDto[]> {\n    const urlMap = await this.resolveToolboxProxyUrls(sandboxes.map((s) => s.region))\n    return sandboxes.map((s) => {\n      const url = urlMap.get(s.region)\n      if (!url) {\n        throw new NotFoundException(`Toolbox proxy URL not resolved for region ${s.region}`)\n      }\n      return SandboxDto.fromSandbox(s, url)\n    })\n  }\n\n  async resolveToolboxProxyUrl(regionId: string): Promise<string> {\n    const cacheKey = toolboxProxyUrlCacheKey(regionId)\n    const cached = await this.redis.get(cacheKey)\n    if (cached) {\n      return cached\n    }\n\n    const region = await this.regionService.findOne(regionId)\n    const url = region?.toolboxProxyUrl\n      ? region.toolboxProxyUrl.replace(/\\/+$/, '') + '/toolbox'\n      : this.configService.getOrThrow('proxy.toolboxUrl')\n\n    this.redis.setex(cacheKey, TOOLBOX_PROXY_URL_CACHE_TTL_S, url).catch((err) => {\n      this.logger.warn(`Failed to cache toolbox proxy URL for region ${regionId}: ${err.message}`)\n    })\n    return url\n  }\n\n  async resolveToolboxProxyUrls(regionIds: string[]): Promise<Map<string, string>> {\n    const unique = [...new Set(regionIds)]\n    const result = new Map<string, string>()\n\n    const pipeline = this.redis.pipeline()\n    for (const id of unique) {\n      pipeline.get(toolboxProxyUrlCacheKey(id))\n    }\n    const cached = await pipeline.exec()\n\n    const uncached: string[] = []\n    for (let i = 0; i < unique.length; i++) {\n      const err = cached?.[i]?.[0]\n      if (err) {\n        this.logger.warn(`Failed to get cached toolbox proxy URL for region ${unique[i]}: ${err.message}`)\n      }\n      const val = cached?.[i]?.[1] as string | null\n      if (val) {\n        result.set(unique[i], val)\n      } else {\n        uncached.push(unique[i])\n      }\n    }\n\n    if (uncached.length > 0) {\n      const regions = await this.regionService.findByIds(uncached)\n      const regionMap = new Map(regions.map((r) => [r.id, r]))\n      const fallback = this.configService.getOrThrow('proxy.toolboxUrl')\n      const setPipeline = this.redis.pipeline()\n      for (const id of uncached) {\n        const region = regionMap.get(id)\n        const url = region?.toolboxProxyUrl ? region.toolboxProxyUrl.replace(/\\/+$/, '') + '/toolbox' : fallback\n        result.set(id, url)\n        setPipeline.setex(toolboxProxyUrlCacheKey(id), TOOLBOX_PROXY_URL_CACHE_TTL_S, url)\n      }\n      const setResults = await setPipeline.exec()\n      setResults?.forEach(([err], i) => {\n        if (err) {\n          this.logger.warn(`Failed to cache toolbox proxy URL for region ${uncached[i]}: ${err.message}`)\n        }\n      })\n    }\n\n    return result\n  }\n\n  async getBuildLogsUrl(sandboxIdOrName: string, organizationId: string): Promise<string> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    if (!sandbox.buildInfo?.snapshotRef) {\n      throw new NotFoundException(`Sandbox ${sandboxIdOrName} has no build info`)\n    }\n\n    const region = await this.regionService.findOne(sandbox.region, true)\n\n    if (!region) {\n      throw new NotFoundException(`Region for runner for sandbox ${sandboxIdOrName} not found`)\n    }\n\n    if (!region.proxyUrl) {\n      return `${this.configService.getOrThrow('proxy.protocol')}://${this.configService.getOrThrow('proxy.domain')}/sandboxes/${sandbox.id}/build-logs`\n    }\n\n    return region.proxyUrl + '/sandboxes/' + sandbox.id + '/build-logs'\n  }\n\n  private async getValidatedOrDefaultRegion(organization: Organization, regionIdOrName?: string): Promise<Region> {\n    if (!organization.defaultRegionId) {\n      throw new DefaultRegionRequiredException()\n    }\n\n    regionIdOrName = regionIdOrName?.trim()\n\n    if (!regionIdOrName) {\n      const region = await this.regionService.findOne(organization.defaultRegionId)\n      if (!region) {\n        throw new NotFoundException('Default region not found')\n      }\n      return region\n    }\n\n    const region =\n      (await this.regionService.findOneByName(regionIdOrName, organization.id)) ??\n      (await this.regionService.findOneByName(regionIdOrName, null)) ??\n      (await this.regionService.findOne(regionIdOrName))\n\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n\n    return region\n  }\n\n  private getValidatedOrDefaultClass(sandboxClass: SandboxClass): SandboxClass {\n    if (!sandboxClass) {\n      return SandboxClass.SMALL\n    }\n\n    if (Object.values(SandboxClass).includes(sandboxClass)) {\n      return sandboxClass\n    } else {\n      throw new BadRequestError('Invalid class')\n    }\n  }\n\n  async replaceLabels(\n    sandboxIdOrName: string,\n    labels: { [key: string]: string },\n    organizationId?: string,\n  ): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    // Replace all labels\n    const updateData: Partial<Sandbox> = {\n      labels,\n    }\n\n    return await this.sandboxRepository.update(sandbox.id, { updateData, entity: sandbox })\n  }\n\n  @Cron(CronExpression.EVERY_SECOND, { name: 'cleanup-destroyed-sandboxes' })\n  @LogExecution('cleanup-destroyed-sandboxes')\n  @WithInstrumentation()\n  async cleanupDestroyedSandboxes() {\n    const twentyFourHoursAgo = new Date()\n    twentyFourHoursAgo.setHours(twentyFourHoursAgo.getHours() - 24)\n\n    const destroyedSandboxs = await this.sandboxRepository.delete({\n      state: SandboxState.DESTROYED,\n      updatedAt: LessThan(twentyFourHoursAgo),\n    })\n\n    if (destroyedSandboxs.affected > 0) {\n      this.logger.debug(`Cleaned up ${destroyedSandboxs.affected} destroyed sandboxes`)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_10_MINUTES, { name: 'cleanup-build-failed-sandboxes' })\n  @LogExecution('cleanup-build-failed-sandboxes')\n  @WithInstrumentation()\n  async cleanupBuildFailedSandboxes() {\n    const twentyFourHoursAgo = new Date()\n    twentyFourHoursAgo.setHours(twentyFourHoursAgo.getHours() - 24)\n\n    const destroyedSandboxs = await this.sandboxRepository.delete({\n      state: SandboxState.BUILD_FAILED,\n      desiredState: SandboxDesiredState.DESTROYED,\n      updatedAt: LessThan(twentyFourHoursAgo),\n    })\n\n    if (destroyedSandboxs.affected > 0) {\n      this.logger.debug(`Cleaned up ${destroyedSandboxs.affected} build failed sandboxes`)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_SECOND, { name: 'cleanup-stale-build-failed-sandboxes' })\n  @LogExecution('cleanup-stale-build-failed-sandboxes')\n  @WithInstrumentation()\n  async cleanupStaleBuildFailedSandboxes() {\n    const sevenDaysAgo = new Date()\n    sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7)\n\n    const result = await this.sandboxRepository.delete({\n      state: SandboxState.BUILD_FAILED,\n      desiredState: SandboxDesiredState.STARTED,\n      updatedAt: LessThan(sevenDaysAgo),\n    })\n\n    if (result.affected > 0) {\n      this.logger.debug(`Cleaned up ${result.affected} stale build failed sandboxes`)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_SECOND, { name: 'cleanup-stale-error-sandboxes' })\n  @LogExecution('cleanup-stale-error-sandboxes')\n  @WithInstrumentation()\n  async cleanupStaleErrorSandboxes() {\n    const sevenDaysAgo = new Date()\n    sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7)\n\n    const result = await this.sandboxRepository.delete({\n      state: SandboxState.ERROR,\n      desiredState: SandboxDesiredState.DESTROYED,\n      updatedAt: LessThan(sevenDaysAgo),\n    })\n\n    if (result.affected > 0) {\n      this.logger.debug(`Cleaned up ${result.affected} stale error sandboxes`)\n    }\n  }\n\n  async setAutostopInterval(sandboxIdOrName: string, interval: number, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    const updateData: Partial<Sandbox> = {\n      autoStopInterval: this.resolveAutoStopInterval(interval),\n    }\n\n    return await this.sandboxRepository.update(sandbox.id, { updateData, entity: sandbox })\n  }\n\n  async setAutoArchiveInterval(sandboxIdOrName: string, interval: number, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    const updateData: Partial<Sandbox> = {\n      autoArchiveInterval: this.resolveAutoArchiveInterval(interval),\n    }\n\n    return await this.sandboxRepository.update(sandbox.id, { updateData, entity: sandbox })\n  }\n\n  async setAutoDeleteInterval(sandboxIdOrName: string, interval: number, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    const updateData: Partial<Sandbox> = {\n      autoDeleteInterval: interval,\n    }\n\n    return await this.sandboxRepository.update(sandbox.id, { updateData, entity: sandbox })\n  }\n\n  async updateNetworkSettings(\n    sandboxIdOrName: string,\n    networkBlockAll?: boolean,\n    networkAllowList?: string,\n    organizationId?: string,\n  ): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    const updateData: Partial<Sandbox> = {}\n\n    if (networkBlockAll !== undefined) {\n      updateData.networkBlockAll = networkBlockAll\n    }\n\n    if (networkAllowList !== undefined) {\n      updateData.networkAllowList = this.resolveNetworkAllowList(networkAllowList)\n    }\n\n    const updatedSandbox = await this.sandboxRepository.update(sandbox.id, { updateData, entity: sandbox })\n\n    // Update network settings on the runner\n    if (sandbox.runnerId) {\n      const runner = await this.runnerService.findOne(sandbox.runnerId)\n      if (runner) {\n        const runnerAdapter = await this.runnerAdapterFactory.create(runner)\n        await runnerAdapter.updateNetworkSettings(sandbox.id, networkBlockAll, networkAllowList)\n      }\n    }\n\n    return updatedSandbox\n  }\n\n  // used by internal services to update the state of a sandbox to resolve domain and runner state mismatch\n  // notably, when a sandbox instance stops or errors on the runner, the domain state needs to be updated to reflect the actual state\n  async updateState(\n    sandboxId: string,\n    newState: SandboxState,\n    recoverable = false,\n    errorReason?: string,\n  ): Promise<void> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: { id: sandboxId },\n    })\n\n    if (!sandbox) {\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n\n    if (sandbox.state === newState) {\n      this.logger.debug(`Sandbox ${sandboxId} is already in state ${newState}`)\n      return\n    }\n\n    //  only allow updating the state of started | stopped sandboxes\n    if (![SandboxState.STARTED, SandboxState.STOPPED].includes(sandbox.state)) {\n      throw new BadRequestError('Sandbox is not in a valid state to be updated')\n    }\n\n    if (sandbox.desiredState == SandboxDesiredState.DESTROYED) {\n      this.logger.debug(`Sandbox ${sandboxId} is already DESTROYED, skipping state update`)\n      return\n    }\n\n    const oldState = sandbox.state\n    const oldDesiredState = sandbox.desiredState\n\n    const updateData: Partial<Sandbox> = {\n      state: newState,\n      recoverable: false,\n    }\n\n    if (errorReason !== undefined) {\n      updateData.errorReason = errorReason\n      if (newState === SandboxState.ERROR) {\n        updateData.recoverable = recoverable\n      }\n    }\n\n    //  we need to update the desired state to match the new state\n    const desiredState = this.getExpectedDesiredStateForState(newState)\n    if (desiredState) {\n      updateData.desiredState = desiredState\n    }\n\n    await this.sandboxRepository.updateWhere(sandbox.id, {\n      updateData,\n      whereCondition: { pending: false, state: oldState, desiredState: oldDesiredState },\n    })\n  }\n\n  @OnEvent(WarmPoolEvents.TOPUP_REQUESTED)\n  private async createWarmPoolSandbox(event: WarmPoolTopUpRequested) {\n    await this.createForWarmPool(event.warmPool)\n  }\n\n  @Cron(CronExpression.EVERY_MINUTE, { name: 'handle-unschedulable-runners' })\n  @LogExecution('handle-unschedulable-runners')\n  @WithInstrumentation()\n  private async handleUnschedulableRunners() {\n    const runners = await this.runnerRepository.find({ where: { unschedulable: true } })\n\n    if (runners.length === 0) {\n      return\n    }\n\n    //  find all sandboxes that are using the unschedulable runners and have organizationId = '00000000-0000-0000-0000-000000000000'\n    const sandboxes = await this.sandboxRepository.find({\n      where: {\n        runnerId: In(runners.map((runner) => runner.id)),\n        organizationId: '00000000-0000-0000-0000-000000000000',\n        state: SandboxState.STARTED,\n        desiredState: Not(SandboxDesiredState.DESTROYED),\n      },\n    })\n\n    if (sandboxes.length === 0) {\n      return\n    }\n\n    const destroyPromises = sandboxes.map((sandbox) => this.destroy(sandbox.id))\n    const results = await Promise.allSettled(destroyPromises)\n\n    // Log any failed sandbox destructions\n    results.forEach((result, index) => {\n      if (result.status === 'rejected') {\n        this.logger.error(`Failed to destroy sandbox ${sandboxes[index].id}: ${result.reason}`)\n      }\n    })\n  }\n\n  async isSandboxPublic(sandboxId: string): Promise<boolean> {\n    const sandbox = await this.sandboxRepository.findOne({\n      where: { id: sandboxId },\n    })\n\n    if (!sandbox) {\n      throw new NotFoundException(`Sandbox with ID ${sandboxId} not found`)\n    }\n\n    return sandbox.public\n  }\n\n  @OnEvent(OrganizationEvents.SUSPENDED_SANDBOX_STOPPED)\n  async handleSuspendedSandboxStopped(event: OrganizationSuspendedSandboxStoppedEvent) {\n    await this.stop(event.sandboxId).catch((error) => {\n      //  log the error for now, but don't throw it as it will be retried\n      this.logger.error(`Error stopping sandbox from suspended organization. SandboxId: ${event.sandboxId}: `, error)\n    })\n  }\n\n  private resolveAutoStopInterval(autoStopInterval: number): number {\n    if (autoStopInterval < 0) {\n      throw new BadRequestError('Auto-stop interval must be non-negative')\n    }\n\n    return autoStopInterval\n  }\n\n  private resolveAutoArchiveInterval(autoArchiveInterval: number): number {\n    if (autoArchiveInterval < 0) {\n      throw new BadRequestError('Auto-archive interval must be non-negative')\n    }\n\n    const maxAutoArchiveInterval = this.configService.getOrThrow('maxAutoArchiveInterval')\n\n    if (autoArchiveInterval === 0) {\n      return maxAutoArchiveInterval\n    }\n\n    return Math.min(autoArchiveInterval, maxAutoArchiveInterval)\n  }\n\n  private resolveNetworkAllowList(networkAllowList: string): string {\n    try {\n      validateNetworkAllowList(networkAllowList)\n    } catch (error) {\n      throw new BadRequestError(error instanceof Error ? error.message : 'Invalid network allow list')\n    }\n\n    return networkAllowList\n  }\n\n  private resolveVolumes(volumes: SandboxVolume[]): SandboxVolume[] {\n    try {\n      validateMountPaths(volumes)\n    } catch (error) {\n      throw new BadRequestError(error instanceof Error ? error.message : 'Invalid volume mount configuration')\n    }\n\n    try {\n      validateSubpaths(volumes)\n    } catch (error) {\n      throw new BadRequestError(error instanceof Error ? error.message : 'Invalid volume subpath configuration')\n    }\n\n    return volumes\n  }\n\n  async createSshAccess(\n    sandboxIdOrName: string,\n    expiresInMinutes = 60,\n    organizationId?: string,\n  ): Promise<SshAccessDto> {\n    //  check if sandbox exists\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    // Revoke any existing SSH access for this sandbox\n    await this.revokeSshAccess(sandbox.id)\n\n    const sshAccess = new SshAccess()\n    sshAccess.sandboxId = sandbox.id\n    // Generate a safe token that can't doesn't have _ or - to avoid CLI issues\n    sshAccess.token = customNanoid(urlAlphabet.replace('_', '').replace('-', ''))(32)\n    sshAccess.expiresAt = new Date(Date.now() + expiresInMinutes * 60 * 1000)\n\n    await this.sshAccessRepository.save(sshAccess)\n\n    const region = await this.regionService.findOne(sandbox.region, true)\n    if (region && region.sshGatewayUrl) {\n      return SshAccessDto.fromSshAccess(sshAccess, region.sshGatewayUrl)\n    }\n\n    return SshAccessDto.fromSshAccess(sshAccess, this.configService.getOrThrow('sshGateway.url'))\n  }\n\n  async revokeSshAccess(sandboxIdOrName: string, token?: string, organizationId?: string): Promise<Sandbox> {\n    const sandbox = await this.findOneByIdOrName(sandboxIdOrName, organizationId)\n\n    if (token) {\n      // Revoke specific SSH access by token\n      await this.sshAccessRepository.delete({ sandboxId: sandbox.id, token })\n    } else {\n      // Revoke all SSH access for the sandbox\n      await this.sshAccessRepository.delete({ sandboxId: sandbox.id })\n    }\n\n    return sandbox\n  }\n\n  async validateSshAccess(token: string): Promise<SshAccessValidationDto> {\n    const sshAccess = await this.sshAccessRepository.findOne({\n      where: {\n        token,\n      },\n      relations: ['sandbox'],\n    })\n\n    if (!sshAccess) {\n      return { valid: false, sandboxId: null }\n    }\n\n    // Check if token is expired\n    const isExpired = sshAccess.expiresAt < new Date()\n    if (isExpired) {\n      return { valid: false, sandboxId: null }\n    }\n\n    // Get runner information if sandbox exists\n    if (sshAccess.sandbox && sshAccess.sandbox.runnerId) {\n      const runner = await this.runnerService.findOne(sshAccess.sandbox.runnerId)\n\n      if (runner) {\n        return {\n          valid: true,\n          sandboxId: sshAccess.sandbox.id,\n        }\n      }\n    }\n\n    return { valid: true, sandboxId: sshAccess.sandbox.id }\n  }\n\n  async updateSandboxBackupState(\n    sandboxId: string,\n    backupState: BackupState,\n    backupSnapshot?: string | null,\n    backupRegistryId?: string | null,\n    backupErrorReason?: string | null,\n  ): Promise<void> {\n    const sandboxToUpdate = await this.sandboxRepository.findOneByOrFail({\n      id: sandboxId,\n    })\n\n    const updateData = Sandbox.getBackupStateUpdate(\n      sandboxToUpdate,\n      backupState,\n      backupSnapshot,\n      backupRegistryId,\n      backupErrorReason,\n    )\n\n    await this.sandboxRepository.update(sandboxId, { updateData, entity: sandboxToUpdate })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/snapshot.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Injectable,\n  NotFoundException,\n  ConflictException,\n  ForbiddenException,\n  BadRequestException,\n  Logger,\n} from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Repository, Not, In, Raw, ILike, FindOptionsWhere } from 'typeorm'\nimport { v4 as uuidv4, validate as isUUID } from 'uuid'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { SnapshotState } from '../enums/snapshot-state.enum'\nimport { CreateSnapshotDto } from '../dto/create-snapshot.dto'\nimport { BuildInfo } from '../entities/build-info.entity'\nimport { generateBuildInfoHash as generateBuildSnapshotRef } from '../entities/build-info.entity'\nimport { EventEmitter2, OnEvent } from '@nestjs/event-emitter'\nimport { SandboxEvents } from '../constants/sandbox-events.constants'\nimport { SandboxCreatedEvent } from '../events/sandbox-create.event'\nimport { Organization } from '../../organization/entities/organization.entity'\nimport { OrganizationService } from '../../organization/services/organization.service'\nimport { SnapshotRunner } from '../entities/snapshot-runner.entity'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { OrganizationEvents } from '../../organization/constants/organization-events.constant'\nimport { OrganizationSuspendedSnapshotDeactivatedEvent } from '../../organization/events/organization-suspended-snapshot-deactivated.event'\nimport { SnapshotRunnerState } from '../enums/snapshot-runner-state.enum'\nimport { PaginatedList } from '../../common/interfaces/paginated-list.interface'\nimport { OrganizationUsageService } from '../../organization/services/organization-usage.service'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { SnapshotSortDirection, SnapshotSortField } from '../dto/list-snapshots-query.dto'\nimport { PER_SANDBOX_LIMIT_MESSAGE } from '../../common/constants/error-messages'\nimport { DockerRegistryService } from '../../docker-registry/services/docker-registry.service'\nimport { DefaultRegionRequiredException } from '../../organization/exceptions/DefaultRegionRequiredException'\nimport { Region } from '../../region/entities/region.entity'\nimport { RunnerState } from '../enums/runner-state.enum'\nimport { OnAsyncEvent } from '../../common/decorators/on-async-event.decorator'\nimport { RunnerEvents } from '../constants/runner-events'\nimport { RunnerDeletedEvent } from '../events/runner-deleted.event'\nimport { SnapshotRegion } from '../entities/snapshot-region.entity'\nimport { RegionType } from '../../region/enums/region-type.enum'\nimport { SnapshotEvents } from '../constants/snapshot-events'\nimport { SnapshotCreatedEvent } from '../events/snapshot-created.event'\nimport { RunnerService } from './runner.service'\nimport { RegionService } from '../../region/services/region.service'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport { SnapshotActivatedEvent } from '../events/snapshot-activated.event'\n\nconst IMAGE_NAME_REGEX = /^[a-zA-Z0-9_.\\-:]+(\\/[a-zA-Z0-9_.\\-:]+)*(@sha256:[a-f0-9]{64})?$/\n@Injectable()\nexport class SnapshotService {\n  private readonly logger = new Logger(SnapshotService.name)\n\n  constructor(\n    private readonly sandboxRepository: SandboxRepository,\n    @InjectRepository(Snapshot)\n    private readonly snapshotRepository: Repository<Snapshot>,\n    @InjectRepository(BuildInfo)\n    private readonly buildInfoRepository: Repository<BuildInfo>,\n    @InjectRepository(SnapshotRunner)\n    private readonly snapshotRunnerRepository: Repository<SnapshotRunner>,\n    @InjectRepository(Region)\n    private readonly regionRepository: Repository<Region>,\n    @InjectRepository(SnapshotRegion)\n    private readonly snapshotRegionRepository: Repository<SnapshotRegion>,\n    private readonly organizationService: OrganizationService,\n    private readonly organizationUsageService: OrganizationUsageService,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly runnerService: RunnerService,\n    private readonly regionService: RegionService,\n    private readonly dockerRegistryService: DockerRegistryService,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly configService: TypedConfigService,\n  ) {}\n\n  private validateImageName(name: string): string | null {\n    // Check for digest format (@sha256:hash)\n    if (name.includes('@sha256:')) {\n      const [imageName, digest] = name.split('@sha256:')\n      if (!imageName || !digest || !/^[a-f0-9]{64}$/.test(digest)) {\n        return 'Invalid digest format. Must be image@sha256:64_hex_characters'\n      }\n      return null\n    }\n\n    // Handle tag format (image:tag)\n    if (!name.includes(':') || name.endsWith(':') || /:\\s*$/.test(name)) {\n      return 'Image name must include a tag (e.g., ubuntu:22.04) or digest (@sha256:...)'\n    }\n\n    if (name.endsWith(':latest')) {\n      return 'Images with tag \":latest\" are not allowed'\n    }\n\n    if (!IMAGE_NAME_REGEX.test(name)) {\n      return 'Invalid image name format. Must be lowercase, may contain digits, dots, dashes, and single slashes between components'\n    }\n\n    return null\n  }\n\n  private validateSnapshotName(name: string): string | null {\n    if (!IMAGE_NAME_REGEX.test(name)) {\n      return 'Invalid snapshot name format. May contain letters, digits, dots, colons, and dashes'\n    }\n\n    return null\n  }\n\n  private processEntrypoint(entrypoint?: string[]): string[] | undefined {\n    if (!entrypoint || entrypoint.length === 0) {\n      return undefined\n    }\n\n    // Filter out empty strings from the array\n    const filteredEntrypoint = entrypoint.filter((cmd) => cmd && cmd.trim().length > 0)\n\n    return filteredEntrypoint.length > 0 ? filteredEntrypoint : undefined\n  }\n\n  private async readySnapshotRunnerExists(ref: string, regionId: string): Promise<boolean> {\n    return await this.snapshotRunnerRepository\n      .createQueryBuilder('sr')\n      .innerJoin('runner', 'r', 'r.id::text = sr.\"runnerId\"::text')\n      .where('sr.\"snapshotRef\" = :ref', { ref })\n      .andWhere('sr.state = :snapshotRunnerState', { snapshotRunnerState: SnapshotRunnerState.READY })\n      .andWhere('r.region = :regionId', { regionId })\n      .andWhere('r.state = :runnerState', { runnerState: RunnerState.READY })\n      .andWhere('r.unschedulable = false')\n      .getExists()\n  }\n\n  async createFromPull(organization: Organization, createSnapshotDto: CreateSnapshotDto, general = false) {\n    if (!organization.defaultRegionId) {\n      throw new DefaultRegionRequiredException()\n    }\n\n    const regionId = await this.getValidatedOrDefaultRegionId(organization, createSnapshotDto.regionId)\n\n    let pendingSnapshotCountIncrement: number | undefined\n\n    if (!createSnapshotDto.imageName) {\n      throw new BadRequestException('Must specify an image name')\n    }\n\n    try {\n      const entrypoint = createSnapshotDto.entrypoint\n      const ref: string | undefined = undefined\n      const state: SnapshotState = SnapshotState.PENDING\n\n      const nameValidationError = this.validateSnapshotName(createSnapshotDto.name)\n      if (nameValidationError) {\n        throw new BadRequestException(nameValidationError)\n      }\n\n      const imageValidationError = this.validateImageName(createSnapshotDto.imageName)\n      if (imageValidationError) {\n        throw new BadRequestException(imageValidationError)\n      }\n\n      this.organizationService.assertOrganizationIsNotSuspended(organization)\n\n      const newSnapshotCount = 1\n\n      const { pendingSnapshotCountIncremented } = await this.validateOrganizationQuotas(\n        organization,\n        newSnapshotCount,\n        createSnapshotDto.cpu,\n        createSnapshotDto.memory,\n        createSnapshotDto.disk,\n      )\n\n      if (pendingSnapshotCountIncremented) {\n        pendingSnapshotCountIncrement = newSnapshotCount\n      }\n\n      try {\n        const snapshotId = uuidv4()\n\n        const snapshot = this.snapshotRepository.create({\n          id: snapshotId,\n          organizationId: organization.id,\n          ...createSnapshotDto,\n          entrypoint: this.processEntrypoint(entrypoint),\n          mem: createSnapshotDto.memory, // Map memory to mem\n          state,\n          ref,\n          general,\n          snapshotRegions: [{ snapshotId, regionId }],\n        })\n\n        const savedSnapshot = await this.snapshotRepository.save(snapshot)\n\n        this.eventEmitter.emit(SnapshotEvents.CREATED, new SnapshotCreatedEvent(savedSnapshot))\n\n        return savedSnapshot\n      } catch (error) {\n        if (error.code === '23505') {\n          // PostgreSQL unique violation error code\n          throw new ConflictException(\n            `Snapshot with name \"${createSnapshotDto.name}\" already exists for this organization`,\n          )\n        }\n        throw error\n      }\n    } catch (error) {\n      await this.rollbackPendingUsage(organization.id, pendingSnapshotCountIncrement)\n      throw error\n    }\n  }\n\n  async createFromBuildInfo(organization: Organization, createSnapshotDto: CreateSnapshotDto, general = false) {\n    if (!organization.defaultRegionId) {\n      throw new DefaultRegionRequiredException()\n    }\n\n    const regionId = await this.getValidatedOrDefaultRegionId(organization, createSnapshotDto.regionId)\n\n    let pendingSnapshotCountIncrement: number | undefined\n    let entrypoint: string[] | undefined = undefined\n\n    try {\n      const nameValidationError = this.validateSnapshotName(createSnapshotDto.name)\n      if (nameValidationError) {\n        throw new BadRequestException(nameValidationError)\n      }\n\n      this.organizationService.assertOrganizationIsNotSuspended(organization)\n\n      const newSnapshotCount = 1\n\n      const { pendingSnapshotCountIncremented } = await this.validateOrganizationQuotas(\n        organization,\n        newSnapshotCount,\n        createSnapshotDto.cpu,\n        createSnapshotDto.memory,\n        createSnapshotDto.disk,\n      )\n\n      if (pendingSnapshotCountIncremented) {\n        pendingSnapshotCountIncrement = newSnapshotCount\n      }\n\n      entrypoint = this.getEntrypointFromDockerfile(createSnapshotDto.buildInfo.dockerfileContent)\n\n      const snapshotId = uuidv4()\n\n      const snapshot = this.snapshotRepository.create({\n        id: snapshotId,\n        organizationId: organization.id,\n        ...createSnapshotDto,\n        entrypoint: this.processEntrypoint(entrypoint),\n        mem: createSnapshotDto.memory, // Map memory to mem\n        state: SnapshotState.PENDING,\n        general,\n        snapshotRegions: [{ snapshotId, regionId }],\n      })\n\n      const buildSnapshotRef = generateBuildSnapshotRef(\n        createSnapshotDto.buildInfo.dockerfileContent,\n        createSnapshotDto.buildInfo.contextHashes,\n      )\n\n      // Check if buildInfo with the same snapshotRef already exists\n      const existingBuildInfo = await this.buildInfoRepository.findOne({\n        where: { snapshotRef: buildSnapshotRef },\n      })\n\n      if (existingBuildInfo) {\n        snapshot.buildInfo = existingBuildInfo\n        // Update lastUsed once per minute at most\n        if (await this.redisLockProvider.lock(`build-info:${existingBuildInfo.snapshotRef}:update`, 60)) {\n          existingBuildInfo.lastUsedAt = new Date()\n          await this.buildInfoRepository.save(existingBuildInfo)\n        }\n      } else {\n        const buildInfoEntity = this.buildInfoRepository.create({\n          ...createSnapshotDto.buildInfo,\n        })\n        await this.buildInfoRepository.save(buildInfoEntity)\n        snapshot.buildInfo = buildInfoEntity\n      }\n\n      const internalRegistry = await this.dockerRegistryService.getAvailableInternalRegistry(regionId)\n      if (!internalRegistry) {\n        throw new Error('No internal registry found for snapshot')\n      }\n      snapshot.ref = `${internalRegistry.url.replace(/^(https?:\\/\\/)/, '')}/${internalRegistry.project || 'daytona'}/${buildSnapshotRef}`\n\n      const exists = await this.readySnapshotRunnerExists(snapshot.ref, regionId)\n\n      if (exists) {\n        snapshot.state = SnapshotState.ACTIVE\n        snapshot.lastUsedAt = new Date()\n      }\n\n      try {\n        const savedSnapshot = await this.snapshotRepository.save(snapshot)\n\n        this.eventEmitter.emit(SnapshotEvents.CREATED, new SnapshotCreatedEvent(savedSnapshot))\n\n        return savedSnapshot\n      } catch (error) {\n        if (error.code === '23505') {\n          // PostgreSQL unique violation error code\n          throw new ConflictException(\n            `Snapshot with name \"${createSnapshotDto.name}\" already exists for this organization`,\n          )\n        }\n        throw error\n      }\n    } catch (error) {\n      await this.rollbackPendingUsage(organization.id, pendingSnapshotCountIncrement)\n      throw error\n    }\n  }\n\n  async removeSnapshot(snapshotId: string) {\n    const snapshot = await this.snapshotRepository.findOne({\n      where: { id: snapshotId },\n    })\n\n    if (!snapshot) {\n      throw new NotFoundException(`Snapshot ${snapshotId} not found`)\n    }\n    if (snapshot.general) {\n      throw new ForbiddenException('You cannot delete a general snapshot')\n    }\n    snapshot.state = SnapshotState.REMOVING\n    await this.snapshotRepository.save(snapshot)\n  }\n\n  async getAllSnapshots(\n    organizationId: string,\n    page = 1,\n    limit = 10,\n    filters?: { name?: string },\n    sort?: { field?: SnapshotSortField; direction?: SnapshotSortDirection },\n  ): Promise<PaginatedList<Snapshot>> {\n    const pageNum = Number(page)\n    const limitNum = Number(limit)\n\n    const { name } = filters || {}\n    const { field: sortField, direction: sortDirection } = sort || {}\n\n    const baseFindOptions: FindOptionsWhere<Snapshot> = {\n      ...(name ? { name: ILike(`%${name}%`) } : {}),\n    }\n\n    // Retrieve all snapshots belonging to the organization as well as all general snapshots\n    const where: FindOptionsWhere<Snapshot>[] = [\n      {\n        ...baseFindOptions,\n        organizationId,\n      },\n      {\n        ...baseFindOptions,\n        general: true,\n        hideFromUsers: false,\n      },\n    ]\n\n    const [items, total] = await this.snapshotRepository.findAndCount({\n      where,\n      relations: ['snapshotRegions'],\n      order: {\n        general: 'ASC', // Sort general snapshots last\n        [sortField]: {\n          direction: sortDirection,\n          nulls: 'LAST',\n        },\n        ...(sortField !== SnapshotSortField.CREATED_AT && { createdAt: 'DESC' }),\n      },\n      skip: (pageNum - 1) * limitNum,\n      take: limitNum,\n    })\n\n    // Filter out snapshot regions that are not available to the organization\n    const availableRegions = await this.organizationService.listAvailableRegions(organizationId)\n    const availableRegionIds = new Set(availableRegions.map((r) => r.id))\n\n    for (const snapshot of items) {\n      if (snapshot.snapshotRegions) {\n        snapshot.snapshotRegions = snapshot.snapshotRegions.filter((sr) => availableRegionIds.has(sr.regionId))\n      }\n    }\n\n    return {\n      items,\n      total,\n      page: pageNum,\n      totalPages: Math.ceil(total / limit),\n    }\n  }\n\n  async getSnapshot(snapshotId: string): Promise<Snapshot> {\n    const snapshot = await this.snapshotRepository.findOne({\n      where: { id: snapshotId },\n    })\n\n    if (!snapshot) {\n      throw new NotFoundException(`Snapshot ${snapshotId} not found`)\n    }\n\n    return snapshot\n  }\n\n  async getSnapshotWithRegions(snapshotIdOrName: string, organizationId: string): Promise<Snapshot> {\n    const where: FindOptionsWhere<Snapshot>[] = [\n      { name: snapshotIdOrName, organizationId },\n      { name: snapshotIdOrName, general: true },\n    ]\n    if (isUUID(snapshotIdOrName)) {\n      where.push({ id: snapshotIdOrName })\n    }\n\n    const snapshot = await this.snapshotRepository.findOne({\n      where,\n      relations: ['snapshotRegions'],\n      order: { general: 'ASC' },\n    })\n\n    if (!snapshot) {\n      throw new NotFoundException(`Snapshot ${snapshotIdOrName} not found`)\n    }\n\n    const availableRegions = await this.organizationService.listAvailableRegions(organizationId)\n    const availableRegionIds = new Set(availableRegions.map((r) => r.id))\n    if (snapshot.snapshotRegions) {\n      snapshot.snapshotRegions = snapshot.snapshotRegions.filter((sr) => availableRegionIds.has(sr.regionId))\n    }\n\n    return snapshot\n  }\n\n  async getSnapshotByName(snapshotName: string, organizationId: string): Promise<Snapshot> {\n    const snapshot = await this.snapshotRepository.findOne({\n      where: { name: snapshotName, organizationId },\n    })\n\n    if (!snapshot) {\n      //  check if the snapshot is general\n      const generalSnapshot = await this.snapshotRepository.findOne({\n        where: { name: snapshotName, general: true },\n      })\n      if (generalSnapshot) {\n        return generalSnapshot\n      }\n\n      throw new NotFoundException(`Snapshot with name ${snapshotName} not found`)\n    }\n\n    return snapshot\n  }\n\n  async setSnapshotGeneralStatus(snapshotId: string, general: boolean) {\n    const snapshot = await this.snapshotRepository.findOne({\n      where: { id: snapshotId },\n    })\n\n    if (!snapshot) {\n      throw new NotFoundException(`Snapshot ${snapshotId} not found`)\n    }\n\n    snapshot.general = general\n    return await this.snapshotRepository.save(snapshot)\n  }\n\n  async getBuildLogsUrl(snapshot: Snapshot): Promise<string> {\n    if (!snapshot.initialRunnerId) {\n      throw new NotFoundException(`Snapshot ${snapshot.id} has no initial runner`)\n    }\n\n    const runner = await this.runnerService.findOneOrFail(snapshot.initialRunnerId)\n    const region = await this.regionService.findOne(runner.region, true)\n\n    if (!region) {\n      throw new NotFoundException(`Region for initial runner for snapshot ${snapshot.id} not found`)\n    }\n\n    if (!region.proxyUrl) {\n      return `${this.configService.getOrThrow('proxy.protocol')}://${this.configService.getOrThrow('proxy.domain')}/snapshots/${snapshot.id}/build-logs`\n    }\n\n    return region.proxyUrl + '/snapshots/' + snapshot.id + '/build-logs'\n  }\n\n  private async validateOrganizationQuotas(\n    organization: Organization,\n    addedSnapshotCount: number,\n    cpu?: number,\n    memory?: number,\n    disk?: number,\n  ): Promise<{\n    pendingSnapshotCountIncremented: boolean\n  }> {\n    // validate per-sandbox quotas\n    if (cpu && cpu > organization.maxCpuPerSandbox) {\n      throw new ForbiddenException(\n        `CPU request ${cpu} exceeds maximum allowed per sandbox (${organization.maxCpuPerSandbox}).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n      )\n    }\n    if (memory && memory > organization.maxMemoryPerSandbox) {\n      throw new ForbiddenException(\n        `Memory request ${memory}GB exceeds maximum allowed per sandbox (${organization.maxMemoryPerSandbox}GB).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n      )\n    }\n    if (disk && disk > organization.maxDiskPerSandbox) {\n      throw new ForbiddenException(\n        `Disk request ${disk}GB exceeds maximum allowed per sandbox (${organization.maxDiskPerSandbox}GB).\\n${PER_SANDBOX_LIMIT_MESSAGE}`,\n      )\n    }\n\n    // validate usage quotas\n    await this.organizationUsageService.incrementPendingSnapshotUsage(organization.id, addedSnapshotCount)\n\n    const usageOverview = await this.organizationUsageService.getSnapshotUsageOverview(organization.id)\n\n    try {\n      if (usageOverview.currentSnapshotUsage + usageOverview.pendingSnapshotUsage > organization.snapshotQuota) {\n        throw new ForbiddenException(`Snapshot quota exceeded. Maximum allowed: ${organization.snapshotQuota}`)\n      }\n    } catch (error) {\n      await this.rollbackPendingUsage(organization.id, addedSnapshotCount)\n      throw error\n    }\n\n    return {\n      pendingSnapshotCountIncremented: true,\n    }\n  }\n\n  async rollbackPendingUsage(organizationId: string, pendingSnapshotCountIncrement?: number): Promise<void> {\n    if (!pendingSnapshotCountIncrement) {\n      return\n    }\n\n    try {\n      await this.organizationUsageService.decrementPendingSnapshotUsage(organizationId, pendingSnapshotCountIncrement)\n    } catch (error) {\n      this.logger.error(`Error rolling back pending snapshot usage: ${error}`)\n    }\n  }\n\n  @OnEvent(SandboxEvents.CREATED)\n  private async handleSandboxCreatedEvent(event: SandboxCreatedEvent) {\n    if (!event.sandbox.snapshot) {\n      return\n    }\n\n    // Update once per minute at most\n    if (!(await this.redisLockProvider.lock(`snapshot:${event.sandbox.snapshot}:update-last-used`, 60))) {\n      return\n    }\n\n    const snapshot = await this.getSnapshotByName(event.sandbox.snapshot, event.sandbox.organizationId)\n    snapshot.lastUsedAt = event.sandbox.createdAt\n    await this.snapshotRepository.save(snapshot)\n  }\n\n  async activateSnapshot(snapshotId: string, organization: Organization): Promise<Snapshot> {\n    const lockKey = `snapshot:${snapshotId}:activate`\n    await this.redisLockProvider.waitForLock(lockKey, 60)\n\n    let pendingSnapshotCountIncrement: number | undefined\n\n    try {\n      const snapshot = await this.snapshotRepository.findOne({\n        where: { id: snapshotId },\n      })\n\n      if (!snapshot) {\n        throw new NotFoundException(`Snapshot ${snapshotId} not found`)\n      }\n\n      if (snapshot.state === SnapshotState.ACTIVE) {\n        throw new BadRequestException(`Snapshot ${snapshotId} is already active`)\n      }\n\n      if (snapshot.state !== SnapshotState.INACTIVE) {\n        throw new BadRequestException(`Snapshot ${snapshotId} cannot be activated - it is in ${snapshot.state} state`)\n      }\n\n      this.organizationService.assertOrganizationIsNotSuspended(organization)\n\n      const activatedSnapshotCount = 1\n\n      const { pendingSnapshotCountIncremented } = await this.validateOrganizationQuotas(\n        organization,\n        activatedSnapshotCount,\n        snapshot.cpu,\n        snapshot.mem,\n        snapshot.disk,\n      )\n\n      if (pendingSnapshotCountIncremented) {\n        pendingSnapshotCountIncrement = activatedSnapshotCount\n      }\n\n      snapshot.state = SnapshotState.PENDING\n      const savedSnapshot = await this.snapshotRepository.save(snapshot)\n\n      this.eventEmitter.emit(SnapshotEvents.ACTIVATED, new SnapshotActivatedEvent(savedSnapshot))\n\n      return savedSnapshot\n    } catch (error) {\n      await this.rollbackPendingUsage(organization.id, pendingSnapshotCountIncrement)\n      throw error\n    } finally {\n      await this.redisLockProvider.unlock(lockKey)\n    }\n  }\n\n  async canCleanupImage(imageName: string): Promise<boolean> {\n    const snapshot = await this.snapshotRepository.findOne({\n      where: {\n        state: Not(In([SnapshotState.ERROR, SnapshotState.BUILD_FAILED])),\n        ref: imageName,\n      },\n    })\n\n    if (snapshot) {\n      return false\n    }\n\n    const sandbox = await this.sandboxRepository.findOne({\n      where: [\n        {\n          existingBackupSnapshots: Raw((alias) => `${alias} @> '[{\"snapshotName\":\"${imageName}\"}]'::jsonb`),\n        },\n        {\n          existingBackupSnapshots: Raw((alias) => `${alias} @> '[{\"imageName\":\"${imageName}\"}]'::jsonb`),\n        },\n        {\n          backupSnapshot: imageName,\n        },\n      ],\n    })\n\n    if (sandbox && sandbox.state !== SandboxState.DESTROYED) {\n      return false\n    }\n\n    return true\n  }\n\n  async deactivateSnapshot(snapshotId: string): Promise<void> {\n    const snapshot = await this.snapshotRepository.findOne({\n      where: { id: snapshotId },\n    })\n\n    if (!snapshot) {\n      throw new NotFoundException(`Snapshot ${snapshotId} not found`)\n    }\n\n    if (snapshot.state === SnapshotState.INACTIVE) {\n      return\n    }\n\n    snapshot.state = SnapshotState.INACTIVE\n    await this.snapshotRepository.save(snapshot)\n\n    try {\n      const countActiveSnapshots = await this.snapshotRepository.count({\n        where: {\n          state: SnapshotState.ACTIVE,\n          ref: snapshot.ref,\n        },\n      })\n\n      if (countActiveSnapshots === 0) {\n        // Set associated SnapshotRunner records to REMOVING state\n        const result = await this.snapshotRunnerRepository.update(\n          { snapshotRef: snapshot.ref },\n          { state: SnapshotRunnerState.REMOVING },\n        )\n        this.logger.debug(\n          `Deactivated snapshot ${snapshot.id} and marked ${result.affected} SnapshotRunners for removal`,\n        )\n      }\n    } catch (error) {\n      this.logger.error(`Deactivated snapshot ${snapshot.id}, but failed to mark snapshot runners for removal`, error)\n    }\n  }\n\n  // TODO: revise/cleanup\n  getEntrypointFromDockerfile(dockerfileContent: string): string[] {\n    // Match ENTRYPOINT with either a string or JSON array\n    const entrypointMatch = dockerfileContent.match(/ENTRYPOINT\\s+(.*)/)\n    if (entrypointMatch) {\n      const rawEntrypoint = entrypointMatch[1].trim()\n      try {\n        // Try parsing as JSON array\n        const parsed = JSON.parse(rawEntrypoint)\n        if (Array.isArray(parsed)) {\n          return parsed\n        }\n      } catch {\n        // Fallback: it's probably a plain string\n        return [rawEntrypoint.replace(/[\"']/g, '')]\n      }\n    }\n\n    return ['sleep', 'infinity']\n  }\n\n  /**\n   * Validates and returns a region ID for snapshot availability.\n   *\n   * @param organization - The organization which is creating the snapshot.\n   * @param regionId - The requested region ID. If omitted, the organization's default region is used.\n   * @returns The validated region ID\n   * @throws {NotFoundException} If the requested region is not available to the organization\n   */\n  private async getValidatedOrDefaultRegionId(organization: Organization, regionId?: string): Promise<string> {\n    if (!regionId) {\n      return organization.defaultRegionId\n    }\n\n    const region = await this.regionRepository.findOne({\n      where: { id: regionId },\n    })\n\n    if (!region) {\n      throw new NotFoundException('Region not found')\n    }\n\n    const availableRegions = await this.organizationService.listAvailableRegions(organization.id)\n\n    if (!availableRegions.some((r) => r.id === regionId)) {\n      if (region.regionType === RegionType.SHARED) {\n        // region is public, but the organization does not have a quota for it\n        throw new ForbiddenException(`Region ${regionId} is not available to the organization`)\n      } else {\n        // region is not public, respond as if the region was not found\n        throw new NotFoundException('Region not found')\n      }\n    }\n\n    return regionId\n  }\n\n  /**\n   * @param snapshotId\n   * @returns The regions where the snapshot is configured to be propagated to.\n   */\n  async getSnapshotRegions(snapshotId: string): Promise<Region[]> {\n    return await this.regionRepository\n      .createQueryBuilder('r')\n      .innerJoin('snapshot_region', 'sr', 'sr.\"regionId\" = r.id')\n      .where('sr.\"snapshotId\" = :snapshotId', { snapshotId })\n      .getMany()\n  }\n\n  /**\n   * @param snapshotId - The ID of the snapshot.\n   * @param regionId - The ID of the region.\n   * @returns true if the snapshot is available in the region, false otherwise.\n   */\n  async isAvailableInRegion(snapshotId: string, regionId: string): Promise<boolean> {\n    return await this.snapshotRegionRepository.exists({\n      where: {\n        snapshotId,\n        regionId,\n      },\n    })\n  }\n\n  @OnEvent(OrganizationEvents.SUSPENDED_SNAPSHOT_DEACTIVATED)\n  async handleSuspendedOrganizationSnapshotDeactivated(event: OrganizationSuspendedSnapshotDeactivatedEvent) {\n    await this.deactivateSnapshot(event.snapshotId).catch((error) => {\n      //  log the error for now, but don't throw it as it will be retried\n      this.logger.error(\n        `Error deactivating snapshot from suspended organization. SnapshotId: ${event.snapshotId}: `,\n        error,\n      )\n    })\n  }\n\n  @OnAsyncEvent({\n    event: RunnerEvents.DELETED,\n  })\n  async handleRunnerDeletedEvent(payload: RunnerDeletedEvent): Promise<void> {\n    await payload.entityManager.update(\n      SnapshotRunner,\n      { runnerId: payload.runnerId },\n      { state: SnapshotRunnerState.REMOVING },\n    )\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/toolbox.deprecated.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, NotFoundException, HttpException, BadRequestException, Logger } from '@nestjs/common'\nimport { Sandbox } from '../entities/sandbox.entity'\nimport { Runner } from '../entities/runner.entity'\nimport axios from 'axios'\nimport { SandboxState } from '../enums/sandbox-state.enum'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { SandboxService } from './sandbox.service'\nimport { RunnerService } from './runner.service'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\n\n@Injectable()\nexport class ToolboxService {\n  private readonly logger = new Logger(ToolboxService.name)\n\n  constructor(\n    private readonly sandboxRepository: SandboxRepository,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly sandboxService: SandboxService,\n    private readonly runnerService: RunnerService,\n  ) {}\n\n  async forwardRequestToRunner(sandboxId: string, method: string, path: string, data?: any): Promise<any> {\n    const runner = await this.getRunner(sandboxId)\n\n    if (!runner.proxyUrl) {\n      throw new NotFoundException(`Runner for sandbox ${sandboxId} has no proxy URL`)\n    }\n\n    const maxRetries = 5\n    let attempt = 1\n\n    while (attempt <= maxRetries) {\n      try {\n        const headers: any = {\n          Authorization: `Bearer ${runner.apiKey}`,\n        }\n\n        // Only set Content-Type for requests with body data\n        if (data && typeof data === 'object' && Object.keys(data).length > 0) {\n          headers['Content-Type'] = 'application/json'\n        }\n\n        const requestConfig: any = {\n          method,\n          url: `${runner.proxyUrl}/sandboxes/${sandboxId}${path}`,\n          headers,\n          maxBodyLength: 209715200, // 200MB in bytes\n          maxContentLength: 209715200, // 200MB in bytes\n          timeout: 360000, // 360 seconds\n        }\n\n        // Only add data if it's not an empty string or undefined\n        if (data !== undefined && data !== '') {\n          requestConfig.data = data\n        }\n\n        const response = await axios(requestConfig)\n        return response.data\n      } catch (error) {\n        if (error.message.includes('ECONNREFUSED')) {\n          if (attempt === maxRetries) {\n            throw new HttpException('Failed to connect to runner after multiple attempts', 500)\n          }\n          // Wait for attempt * 1000ms (1s, 2s, 3s)\n          await new Promise((resolve) => setTimeout(resolve, attempt * 1000))\n          attempt++\n          continue\n        }\n        // If it's an axios error with a response, throw a NestJS HttpException\n        if (error.response) {\n          throw new HttpException(error.response.data, error.response.status)\n        }\n\n        // For other types of errors, throw a generic 500 error\n        throw new HttpException(`Error forwarding request to runner: ${error.message}`, 500)\n      }\n    }\n  }\n\n  public async getRunner(sandboxId: string): Promise<Runner> {\n    let sandbox: Sandbox | null = null\n    try {\n      sandbox = await this.sandboxRepository.findOne({\n        where: { id: sandboxId },\n      })\n\n      if (!sandbox) {\n        throw new NotFoundException('Sandbox not found')\n      }\n\n      const runner = await this.runnerService.findOneOrFail(sandbox.runnerId)\n\n      if (sandbox.state !== SandboxState.STARTED) {\n        throw new BadRequestException('Sandbox is not running')\n      }\n\n      return runner\n    } finally {\n      const lockKey = `sandbox-last-activity-${sandboxId}`\n      const acquired = await this.redisLockProvider.lock(lockKey, 10)\n\n      // redis for cooldown period - 10 seconds\n      // prevents database flooding when multiple requests are made at the same time\n      if (acquired) {\n        await this.sandboxService.updateLastActivityAt(sandboxId, new Date())\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/services/volume.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  ConflictException,\n  ForbiddenException,\n  Injectable,\n  Logger,\n  NotFoundException,\n  ServiceUnavailableException,\n} from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { Repository, Not, In } from 'typeorm'\nimport { Volume } from '../entities/volume.entity'\nimport { VolumeState } from '../enums/volume-state.enum'\nimport { CreateVolumeDto } from '../dto/create-volume.dto'\nimport { v4 as uuidv4 } from 'uuid'\nimport { BadRequestError } from '../../exceptions/bad-request.exception'\nimport { Organization } from '../../organization/entities/organization.entity'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport { SandboxEvents } from '../constants/sandbox-events.constants'\nimport { SandboxCreatedEvent } from '../events/sandbox-create.event'\nimport { OrganizationService } from '../../organization/services/organization.service'\nimport { OrganizationUsageService } from '../../organization/services/organization-usage.service'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { RedisLockProvider } from '../common/redis-lock.provider'\nimport { SandboxRepository } from '../repositories/sandbox.repository'\nimport { SandboxDesiredState } from '../enums/sandbox-desired-state.enum'\n\n@Injectable()\nexport class VolumeService {\n  private readonly logger = new Logger(VolumeService.name)\n\n  constructor(\n    @InjectRepository(Volume)\n    private readonly volumeRepository: Repository<Volume>,\n    private readonly sandboxRepository: SandboxRepository,\n    private readonly organizationService: OrganizationService,\n    private readonly organizationUsageService: OrganizationUsageService,\n    private readonly configService: TypedConfigService,\n    private readonly redisLockProvider: RedisLockProvider,\n  ) {}\n\n  private async validateOrganizationQuotas(\n    organization: Organization,\n    addedVolumeCount: number,\n  ): Promise<{\n    pendingVolumeCountIncremented: boolean\n  }> {\n    // validate usage quotas\n    await this.organizationUsageService.incrementPendingVolumeUsage(organization.id, addedVolumeCount)\n\n    const usageOverview = await this.organizationUsageService.getVolumeUsageOverview(organization.id)\n\n    try {\n      if (usageOverview.currentVolumeUsage + usageOverview.pendingVolumeUsage > organization.volumeQuota) {\n        throw new ForbiddenException(`Volume quota exceeded. Maximum allowed: ${organization.volumeQuota}`)\n      }\n    } catch (error) {\n      await this.rollbackPendingUsage(organization.id, addedVolumeCount)\n      throw error\n    }\n\n    return {\n      pendingVolumeCountIncremented: true,\n    }\n  }\n\n  async rollbackPendingUsage(organizationId: string, pendingVolumeCountIncrement?: number): Promise<void> {\n    if (!pendingVolumeCountIncrement) {\n      return\n    }\n\n    try {\n      await this.organizationUsageService.decrementPendingVolumeUsage(organizationId, pendingVolumeCountIncrement)\n    } catch (error) {\n      this.logger.error(`Error rolling back pending volume usage: ${error}`)\n    }\n  }\n\n  async create(organization: Organization, createVolumeDto: CreateVolumeDto): Promise<Volume> {\n    if (!this.configService.get('s3.endpoint')) {\n      throw new ServiceUnavailableException('Object storage is not configured')\n    }\n\n    let pendingVolumeCountIncrement: number | undefined\n\n    try {\n      this.organizationService.assertOrganizationIsNotSuspended(organization)\n\n      const newVolumeCount = 1\n\n      const { pendingVolumeCountIncremented } = await this.validateOrganizationQuotas(organization, newVolumeCount)\n\n      if (pendingVolumeCountIncremented) {\n        pendingVolumeCountIncrement = newVolumeCount\n      }\n\n      const volume = new Volume()\n\n      // Generate ID\n      volume.id = uuidv4()\n\n      // Set name from DTO or use ID as default\n      volume.name = createVolumeDto.name || volume.id\n\n      // Check if volume with same name already exists for organization\n      const existingVolume = await this.volumeRepository.findOne({\n        where: {\n          organizationId: organization.id,\n          name: volume.name,\n          state: Not(VolumeState.DELETED),\n        },\n      })\n\n      if (existingVolume) {\n        throw new BadRequestError(`Volume with name ${volume.name} already exists`)\n      }\n\n      volume.organizationId = organization.id\n      volume.state = VolumeState.PENDING_CREATE\n\n      const savedVolume = await this.volumeRepository.save(volume)\n      this.logger.debug(`Created volume ${savedVolume.id} for organization ${organization.id}`)\n      return savedVolume\n    } catch (error) {\n      await this.rollbackPendingUsage(organization.id, pendingVolumeCountIncrement)\n      throw error\n    }\n  }\n\n  async delete(volumeId: string): Promise<void> {\n    const volume = await this.volumeRepository.findOne({\n      where: {\n        id: volumeId,\n      },\n    })\n\n    if (!volume) {\n      throw new NotFoundException(`Volume with ID ${volumeId} not found`)\n    }\n\n    if (volume.state !== VolumeState.READY && volume.state !== VolumeState.ERROR) {\n      throw new BadRequestError(\n        `Volume must be in '${VolumeState.READY}' or '${VolumeState.ERROR}' state in order to be deleted`,\n      )\n    }\n\n    // Check if any non-destroyed sandboxes are using this volume\n    const sandboxUsingVolume = await this.sandboxRepository\n      .createQueryBuilder('sandbox')\n      .where('sandbox.organizationId = :organizationId', {\n        organizationId: volume.organizationId,\n      })\n      .andWhere('sandbox.volumes @> :volFilter::jsonb', {\n        volFilter: JSON.stringify([{ volumeId }]),\n      })\n      .andWhere('sandbox.desiredState != :destroyed', {\n        destroyed: SandboxDesiredState.DESTROYED,\n      })\n      .select(['sandbox.id', 'sandbox.name'])\n      .getOne()\n\n    if (sandboxUsingVolume) {\n      throw new ConflictException(\n        `Volume cannot be deleted because it is in use by one or more sandboxes (e.g. ${sandboxUsingVolume.name})`,\n      )\n    }\n\n    // Update state to mark as deleting\n    volume.state = VolumeState.PENDING_DELETE\n    await this.volumeRepository.save(volume)\n    this.logger.debug(`Marked volume ${volumeId} for deletion`)\n  }\n\n  async findOne(volumeId: string): Promise<Volume> {\n    const volume = await this.volumeRepository.findOne({\n      where: { id: volumeId },\n    })\n\n    if (!volume) {\n      throw new NotFoundException(`Volume with ID ${volumeId} not found`)\n    }\n\n    return volume\n  }\n\n  async findAll(organizationId: string, includeDeleted = false): Promise<Volume[]> {\n    return this.volumeRepository.find({\n      where: {\n        organizationId,\n        ...(includeDeleted ? {} : { state: Not(VolumeState.DELETED) }),\n      },\n      order: {\n        lastUsedAt: {\n          direction: 'DESC',\n          nulls: 'LAST',\n        },\n        createdAt: 'DESC',\n      },\n    })\n  }\n\n  async findByName(organizationId: string, name: string): Promise<Volume> {\n    const volume = await this.volumeRepository.findOne({\n      where: {\n        organizationId,\n        name,\n        state: Not(VolumeState.DELETED),\n      },\n    })\n\n    if (!volume) {\n      throw new NotFoundException(`Volume with name ${name} not found`)\n    }\n\n    return volume\n  }\n\n  async validateVolumes(organizationId: string, volumeIdOrNames: string[]): Promise<void> {\n    if (!volumeIdOrNames.length) {\n      return\n    }\n\n    const volumes = await this.volumeRepository.find({\n      where: [\n        { id: In(volumeIdOrNames), organizationId, state: Not(VolumeState.DELETED) },\n        { name: In(volumeIdOrNames), organizationId, state: Not(VolumeState.DELETED) },\n      ],\n    })\n\n    // Check if all requested volumes were found and are in a READY state\n    const foundIds = new Set(volumes.map((v) => v.id))\n    const foundNames = new Set(volumes.map((v) => v.name))\n\n    for (const idOrName of volumeIdOrNames) {\n      if (!foundIds.has(idOrName) && !foundNames.has(idOrName)) {\n        throw new NotFoundException(`Volume '${idOrName}' not found`)\n      }\n    }\n\n    for (const volume of volumes) {\n      if (volume.state !== VolumeState.READY) {\n        throw new BadRequestError(`Volume '${volume.name}' is not in a ready state. Current state: ${volume.state}`)\n      }\n    }\n  }\n\n  async getOrganizationId(params: { id: string } | { name: string; organizationId: string }): Promise<string> {\n    if ('id' in params) {\n      const volume = await this.volumeRepository.findOneOrFail({\n        where: {\n          id: params.id,\n        },\n        select: ['organizationId'],\n        loadEagerRelations: false,\n      })\n      return volume.organizationId\n    }\n\n    const volume = await this.volumeRepository.findOneOrFail({\n      where: {\n        name: params.name,\n        organizationId: params.organizationId,\n      },\n      select: ['organizationId'],\n      loadEagerRelations: false,\n    })\n\n    return volume.organizationId\n  }\n\n  @OnEvent(SandboxEvents.CREATED)\n  private async handleSandboxCreatedEvent(event: SandboxCreatedEvent) {\n    if (!event.sandbox.volumes.length) {\n      return\n    }\n\n    try {\n      const volumeIds = event.sandbox.volumes.map((vol) => vol.volumeId)\n      const volumes = await this.volumeRepository.find({ where: { id: In(volumeIds) } })\n\n      const results = await Promise.allSettled(\n        volumes.map(async (volume) => {\n          // Update once per minute at most\n          if (!(await this.redisLockProvider.lock(`volume:${volume.id}:update-last-used`, 60))) {\n            return\n          }\n          volume.lastUsedAt = event.sandbox.createdAt\n          return this.volumeRepository.save(volume)\n        }),\n      )\n\n      results.forEach((result) => {\n        if (result.status === 'rejected') {\n          this.logger.error(\n            `Failed to update volume lastUsedAt timestamp for sandbox ${event.sandbox.id}: ${result.reason}`,\n          )\n        }\n      })\n    } catch (err) {\n      this.logger.error(err)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/subscribers/runner.subscriber.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Inject, Logger } from '@nestjs/common'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { DataSource, EntitySubscriberInterface, EventSubscriber, InsertEvent, UpdateEvent } from 'typeorm'\nimport { RunnerEvents } from '../constants/runner-events'\nimport { Runner } from '../entities/runner.entity'\nimport { RunnerCreatedEvent } from '../events/runner-created.event'\nimport { RunnerStateUpdatedEvent } from '../events/runner-state-updated.event'\nimport { RunnerUnschedulableUpdatedEvent } from '../events/runner-unschedulable-updated.event'\nimport { runnerLookupCacheKeyById } from '../utils/runner-lookup-cache.util'\n\n@EventSubscriber()\nexport class RunnerSubscriber implements EntitySubscriberInterface<Runner> {\n  private readonly logger = new Logger(RunnerSubscriber.name)\n\n  @Inject(EventEmitter2)\n  private eventEmitter: EventEmitter2\n\n  private dataSource: DataSource\n\n  constructor(dataSource: DataSource) {\n    this.dataSource = dataSource\n    dataSource.subscribers.push(this)\n  }\n\n  listenTo() {\n    return Runner\n  }\n\n  afterInsert(event: InsertEvent<Runner>) {\n    this.eventEmitter.emit(RunnerEvents.CREATED, new RunnerCreatedEvent(event.entity as Runner))\n  }\n\n  afterUpdate(event: UpdateEvent<Runner>) {\n    const updatedColumns = event.updatedColumns.map((col) => col.propertyName)\n\n    updatedColumns.forEach((column) => {\n      // For Repository.update(), TypeORM doesn't provide databaseEntity.\n      if (!event.entity || !event.databaseEntity) {\n        return\n      }\n\n      switch (column) {\n        case 'state':\n          this.eventEmitter.emit(\n            RunnerEvents.STATE_UPDATED,\n            new RunnerStateUpdatedEvent(event.entity as Runner, event.databaseEntity[column], event.entity[column]),\n          )\n          break\n        case 'unschedulable':\n          this.eventEmitter.emit(\n            RunnerEvents.UNSCHEDULABLE_UPDATED,\n            new RunnerUnschedulableUpdatedEvent(\n              event.entity as Runner,\n              event.databaseEntity[column],\n              event.entity[column],\n            ),\n          )\n          break\n        default:\n          break\n      }\n    })\n\n    // Invalidate cached runner lookup queries on any update triggered via save().\n    // Note: Repository.update() does not provide databaseEntity, so those paths\n    // invalidate explicitly via RunnerService.updateRunner().\n    const entity = event.entity as Runner | undefined\n    if (!entity?.id) {\n      return\n    }\n\n    const cache = this.dataSource.queryResultCache\n    if (!cache) {\n      return\n    }\n\n    cache\n      .remove([runnerLookupCacheKeyById(entity.id)])\n      .catch((error) =>\n        this.logger.warn(\n          `Failed to invalidate runner lookup cache for ${entity.id}: ${error instanceof Error ? error.message : String(error)}`,\n        ),\n      )\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/subscribers/snapshot.subscriber.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Inject } from '@nestjs/common'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { DataSource, EntitySubscriberInterface, EventSubscriber, RemoveEvent, UpdateEvent } from 'typeorm'\nimport { SnapshotEvents } from '../constants/snapshot-events'\nimport { Snapshot } from '../entities/snapshot.entity'\nimport { SnapshotStateUpdatedEvent } from '../events/snapshot-state-updated.event'\nimport { SnapshotRemovedEvent } from '../events/snapshot-removed.event'\n\n@EventSubscriber()\nexport class SnapshotSubscriber implements EntitySubscriberInterface<Snapshot> {\n  @Inject(EventEmitter2)\n  private eventEmitter: EventEmitter2\n\n  constructor(dataSource: DataSource) {\n    dataSource.subscribers.push(this)\n  }\n\n  listenTo() {\n    return Snapshot\n  }\n\n  afterUpdate(event: UpdateEvent<Snapshot>) {\n    const updatedColumns = event.updatedColumns.map((col) => col.propertyName)\n\n    updatedColumns.forEach((column) => {\n      switch (column) {\n        case 'state':\n          this.eventEmitter.emit(\n            SnapshotEvents.STATE_UPDATED,\n            new SnapshotStateUpdatedEvent(event.entity as Snapshot, event.databaseEntity[column], event.entity[column]),\n          )\n          break\n        default:\n          break\n      }\n    })\n  }\n\n  beforeRemove(event: RemoveEvent<Snapshot>) {\n    this.eventEmitter.emit(SnapshotEvents.REMOVED, new SnapshotRemovedEvent(event.databaseEntity as Snapshot))\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/subscribers/volume.subscriber.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Inject } from '@nestjs/common'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { DataSource, EntitySubscriberInterface, EventSubscriber, InsertEvent, UpdateEvent } from 'typeorm'\nimport { VolumeEvents } from '../constants/volume-events'\nimport { Volume } from '../entities/volume.entity'\nimport { VolumeCreatedEvent } from '../events/volume-created.event'\nimport { VolumeStateUpdatedEvent } from '../events/volume-state-updated.event'\nimport { VolumeLastUsedAtUpdatedEvent } from '../events/volume-last-used-at-updated.event'\n\n@EventSubscriber()\nexport class VolumeSubscriber implements EntitySubscriberInterface<Volume> {\n  @Inject(EventEmitter2)\n  private eventEmitter: EventEmitter2\n\n  constructor(dataSource: DataSource) {\n    dataSource.subscribers.push(this)\n  }\n\n  listenTo() {\n    return Volume\n  }\n\n  afterInsert(event: InsertEvent<Volume>) {\n    this.eventEmitter.emit(VolumeEvents.CREATED, new VolumeCreatedEvent(event.entity as Volume))\n  }\n\n  afterUpdate(event: UpdateEvent<Volume>) {\n    const updatedColumns = event.updatedColumns.map((col) => col.propertyName)\n\n    updatedColumns.forEach((column) => {\n      switch (column) {\n        case 'state':\n          this.eventEmitter.emit(\n            VolumeEvents.STATE_UPDATED,\n            new VolumeStateUpdatedEvent(event.entity as Volume, event.databaseEntity[column], event.entity[column]),\n          )\n          break\n        case 'lastUsedAt':\n          this.eventEmitter.emit(\n            VolumeEvents.LAST_USED_AT_UPDATED,\n            new VolumeLastUsedAtUpdatedEvent(event.entity as Volume),\n          )\n          break\n        default:\n          break\n      }\n    })\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/utils/lock-key.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport function getStateChangeLockKey(id: string): string {\n  return `sandbox:${id}:state-change`\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/utils/network-validation.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\nimport { isIPv4 } from 'net'\n\n/**\n * Validates network allow list to ensure valid CIDR network addresses are allowed\n * @param networkAllowList - Comma-separated string of network addresses\n * @returns null if valid, error message string if invalid\n */\nexport function validateNetworkAllowList(networkAllowList: string): void {\n  const networks = networkAllowList.split(',').map((net: string) => net.trim())\n\n  for (const network of networks) {\n    if (!network) continue // Skip empty entries\n\n    const [ipAddress, prefixLength] = network.split('/')\n\n    if (!isIPv4(ipAddress)) {\n      throw new Error(`Invalid IP address: \"${ipAddress}\" in network \"${network}\". Must be a valid IPv4 address`)\n    }\n\n    if (!prefixLength) {\n      throw new Error(`Invalid network format: \"${network}\". Missing CIDR prefix length (e.g., /24)`)\n    }\n\n    // Validate CIDR prefix length (0-32 for IPv4)\n    const prefix = parseInt(prefixLength, 10)\n    if (prefix < 0 || prefix > 32) {\n      throw new Error(`Invalid CIDR prefix length: ${network}. Prefix must be between 0 and 32`)\n    }\n  }\n\n  if (networks.length > 10) {\n    throw new Error(`Network allow list cannot contain more than 10 networks`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/utils/runner-lookup-cache.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const RUNNER_LOOKUP_CACHE_TTL_MS = 60_000\n\nexport function runnerLookupCacheKeyById(runnerId: string): string {\n  return `runner:lookup:by-id:${runnerId}`\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/utils/sandbox-lookup-cache.util.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const SANDBOX_LOOKUP_CACHE_TTL_MS = 10_000\nexport const SANDBOX_BUILD_INFO_CACHE_TTL_MS = 60_000\nexport const SANDBOX_ORG_ID_CACHE_TTL_MS = 60_000\nexport const TOOLBOX_PROXY_URL_CACHE_TTL_S = 30 * 60 // 30 minutes\n\ntype SandboxLookupCacheKeyArgs = {\n  organizationId?: string | null\n  returnDestroyed?: boolean\n}\n\nexport function sandboxLookupCacheKeyById(args: SandboxLookupCacheKeyArgs & { sandboxId: string }): string {\n  const organizationId = args.organizationId ?? 'none'\n  const returnDestroyed = args.returnDestroyed ? 1 : 0\n  return `sandbox:lookup:by-id:org:${organizationId}:returnDestroyed:${returnDestroyed}:value:${args.sandboxId}`\n}\n\nexport function sandboxLookupCacheKeyByName(args: SandboxLookupCacheKeyArgs & { sandboxName: string }): string {\n  const organizationId = args.organizationId ?? 'none'\n  const returnDestroyed = args.returnDestroyed ? 1 : 0\n  return `sandbox:lookup:by-name:org:${organizationId}:returnDestroyed:${returnDestroyed}:value:${args.sandboxName}`\n}\n\nexport function sandboxLookupCacheKeyByAuthToken(args: { authToken: string }): string {\n  return `sandbox:lookup:by-authToken:${args.authToken}`\n}\n\ntype SandboxOrgIdCacheKeyArgs = {\n  organizationId?: string\n}\n\nexport function sandboxOrgIdCacheKeyById(args: SandboxOrgIdCacheKeyArgs & { sandboxId: string }): string {\n  const organizationId = args.organizationId ?? 'none'\n  return `sandbox:orgId:by-id:org:${organizationId}:value:${args.sandboxId}`\n}\n\nexport function sandboxOrgIdCacheKeyByName(args: SandboxOrgIdCacheKeyArgs & { sandboxName: string }): string {\n  const organizationId = args.organizationId ?? 'none'\n  return `sandbox:orgId:by-name:org:${organizationId}:value:${args.sandboxName}`\n}\n\nexport function toolboxProxyUrlCacheKey(regionId: string): string {\n  return `toolbox-proxy-url:region:${regionId}`\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/utils/sanitize-error.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport function sanitizeSandboxError(error: any): { recoverable: boolean; errorReason: string } {\n  if (typeof error === 'string') {\n    try {\n      const errObj = JSON.parse(error) as { recoverable: boolean; errorReason: string }\n      return { recoverable: errObj.recoverable, errorReason: errObj.errorReason }\n    } catch {\n      return { recoverable: false, errorReason: error }\n    }\n  } else if (typeof error === 'object' && error !== null && 'recoverable' in error && 'errorReason' in error) {\n    return { recoverable: error.recoverable, errorReason: error.errorReason }\n  } else if (typeof error === 'object' && error.message) {\n    return sanitizeSandboxError(error.message)\n  }\n\n  return { recoverable: false, errorReason: String(error) }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox/utils/volume-mount-path-validation.util.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SandboxVolume } from '../dto/sandbox.dto'\n\n/**\n * Validates mount paths for sandbox volumes to ensure they are safe and valid\n * @param volumes - Array of SandboxVolume objects to validate\n * @throws Error with descriptive message if any mount path is invalid\n */\nexport function validateMountPaths(volumes: SandboxVolume[]): void {\n  const errors: string[] = []\n\n  for (const volume of volumes) {\n    const value = volume.mountPath\n\n    if (typeof value !== 'string') {\n      errors.push(`Invalid mount path ${value} (must be a string)`)\n      continue\n    }\n\n    if (!value.startsWith('/')) {\n      errors.push(`Invalid mount path ${value} (must be absolute)`)\n      continue\n    }\n\n    if (value === '/' || value === '//') {\n      errors.push(`Invalid mount path ${value} (cannot mount to the root directory)`)\n      continue\n    }\n\n    if (value.includes('/../') || value.includes('/./') || value.endsWith('/..') || value.endsWith('/.')) {\n      errors.push(`Invalid mount path ${value} (cannot contain relative path components)`)\n      continue\n    }\n\n    if (/\\/\\/+/.test(value.slice(1))) {\n      errors.push(`Invalid mount path ${value} (cannot contain consecutive slashes)`)\n      continue\n    }\n\n    const invalidPaths = ['/proc', '/sys', '/dev', '/boot', '/etc', '/bin', '/sbin', '/lib', '/lib64']\n    const matchedInvalid = invalidPaths.find((invalid) => value === invalid || value.startsWith(invalid + '/'))\n    if (matchedInvalid) {\n      errors.push(`Invalid mount path ${value} (cannot mount to system directory)`)\n    }\n  }\n\n  if (errors.length > 0) {\n    throw new Error(errors.join(', '))\n  }\n}\n\n/**\n * Validates subpaths for sandbox volumes to ensure they are safe S3 key prefixes\n * @param volumes - Array of SandboxVolume objects to validate\n * @throws Error with descriptive message if any subpath is invalid\n */\nexport function validateSubpaths(volumes: SandboxVolume[]): void {\n  const errors: string[] = []\n\n  for (const volume of volumes) {\n    const subpath = volume.subpath\n\n    // Empty/undefined subpath is valid (means mount entire volume)\n    if (!subpath) {\n      continue\n    }\n\n    if (typeof subpath !== 'string') {\n      errors.push(`Invalid subpath ${subpath} (must be a string)`)\n      continue\n    }\n\n    // S3 keys should not start with /\n    if (subpath.startsWith('/')) {\n      errors.push(`Invalid subpath \"${subpath}\" (S3 key prefixes cannot start with /)`)\n      continue\n    }\n\n    // Prevent path traversal\n    if (subpath.includes('..')) {\n      errors.push(`Invalid subpath \"${subpath}\" (cannot contain .. for security)`)\n      continue\n    }\n\n    // No consecutive slashes\n    if (subpath.includes('//')) {\n      errors.push(`Invalid subpath \"${subpath}\" (cannot contain consecutive slashes)`)\n      continue\n    }\n  }\n\n  if (errors.length > 0) {\n    throw new Error(errors.join(', '))\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/controllers/sandbox-telemetry.controller.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Get, Param, Query, UseGuards } from '@nestjs/common'\nimport { ApiOAuth2, ApiResponse, ApiOperation, ApiParam, ApiTags, ApiHeader, ApiBearerAuth } from '@nestjs/swagger'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { OrganizationResourceActionGuard } from '../../organization/guards/organization-resource-action.guard'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\nimport { SandboxAccessGuard } from '../../sandbox/guards/sandbox-access.guard'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { SandboxTelemetryService } from '../services/sandbox-telemetry.service'\nimport { LogsQueryParamsDto, TelemetryQueryParamsDto, MetricsQueryParamsDto } from '../dto/telemetry-query-params.dto'\nimport { PaginatedLogsDto } from '../dto/paginated-logs.dto'\nimport { PaginatedTracesDto } from '../dto/paginated-traces.dto'\nimport { TraceSpanDto } from '../dto/trace-span.dto'\nimport { MetricsResponseDto } from '../dto/metrics-response.dto'\nimport { RequireFlagsEnabled } from '@openfeature/nestjs-sdk'\nimport { AnalyticsApiDisabledGuard } from '../guards/analytics-api-disabled.guard'\n\n@ApiTags('sandbox')\n@Controller('sandbox')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, OrganizationResourceActionGuard, AuthenticatedRateLimitGuard, AnalyticsApiDisabledGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class SandboxTelemetryController {\n  constructor(private readonly sandboxTelemetryService: SandboxTelemetryService) {}\n\n  @Get(':sandboxId/telemetry/logs')\n  @ApiOperation({\n    summary: 'Get sandbox logs',\n    operationId: 'getSandboxLogs',\n    description: 'Retrieve OTEL logs for a sandbox within a time range',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Paginated list of log entries',\n    type: PaginatedLogsDto,\n  })\n  @UseGuards(SandboxAccessGuard)\n  @RequireFlagsEnabled({ flags: [{ flagKey: 'organization_experiments', defaultValue: true }] })\n  async getSandboxLogs(\n    @Param('sandboxId') sandboxId: string,\n    @Query() queryParams: LogsQueryParamsDto,\n  ): Promise<PaginatedLogsDto> {\n    return this.sandboxTelemetryService.getLogs(\n      sandboxId,\n      queryParams.from,\n      queryParams.to,\n      queryParams.page ?? 1,\n      queryParams.limit ?? 100,\n      queryParams.severities,\n      queryParams.search,\n    )\n  }\n\n  @Get(':sandboxId/telemetry/traces')\n  @ApiOperation({\n    summary: 'Get sandbox traces',\n    operationId: 'getSandboxTraces',\n    description: 'Retrieve OTEL traces for a sandbox within a time range',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Paginated list of trace summaries',\n    type: PaginatedTracesDto,\n  })\n  @UseGuards(SandboxAccessGuard)\n  @RequireFlagsEnabled({ flags: [{ flagKey: 'organization_experiments', defaultValue: true }] })\n  async getSandboxTraces(\n    @Param('sandboxId') sandboxId: string,\n    @Query() queryParams: TelemetryQueryParamsDto,\n  ): Promise<PaginatedTracesDto> {\n    return this.sandboxTelemetryService.getTraces(\n      sandboxId,\n      queryParams.from,\n      queryParams.to,\n      queryParams.page ?? 1,\n      queryParams.limit ?? 100,\n    )\n  }\n\n  @Get(':sandboxId/telemetry/traces/:traceId')\n  @ApiOperation({\n    summary: 'Get trace spans',\n    operationId: 'getSandboxTraceSpans',\n    description: 'Retrieve all spans for a specific trace',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiParam({\n    name: 'traceId',\n    description: 'ID of the trace',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'List of spans in the trace',\n    type: [TraceSpanDto],\n  })\n  @UseGuards(SandboxAccessGuard)\n  @RequireFlagsEnabled({ flags: [{ flagKey: 'organization_experiments', defaultValue: true }] })\n  async getSandboxTraceSpans(\n    @Param('sandboxId') sandboxId: string,\n    @Param('traceId') traceId: string,\n  ): Promise<TraceSpanDto[]> {\n    return this.sandboxTelemetryService.getTraceSpans(sandboxId, traceId)\n  }\n\n  @Get(':sandboxId/telemetry/metrics')\n  @ApiOperation({\n    summary: 'Get sandbox metrics',\n    operationId: 'getSandboxMetrics',\n    description: 'Retrieve OTEL metrics for a sandbox within a time range',\n  })\n  @ApiParam({\n    name: 'sandboxId',\n    description: 'ID of the sandbox',\n    type: 'string',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Metrics time series data',\n    type: MetricsResponseDto,\n  })\n  @UseGuards(SandboxAccessGuard)\n  @RequireFlagsEnabled({ flags: [{ flagKey: 'organization_experiments', defaultValue: true }] })\n  async getSandboxMetrics(\n    @Param('sandboxId') sandboxId: string,\n    @Query() queryParams: MetricsQueryParamsDto,\n  ): Promise<MetricsResponseDto> {\n    return this.sandboxTelemetryService.getMetrics(sandboxId, queryParams.from, queryParams.to, queryParams.metricNames)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/dto/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport * from './telemetry-query-params.dto'\nexport * from './log-entry.dto'\nexport * from './paginated-logs.dto'\nexport * from './trace-summary.dto'\nexport * from './trace-span.dto'\nexport * from './paginated-traces.dto'\nexport * from './metrics-response.dto'\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/dto/log-entry.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'LogEntry' })\nexport class LogEntryDto {\n  @ApiProperty({ description: 'Timestamp of the log entry' })\n  timestamp: string\n\n  @ApiProperty({ description: 'Log message body' })\n  body: string\n\n  @ApiProperty({ description: 'Severity level text (e.g., INFO, WARN, ERROR)' })\n  severityText: string\n\n  @ApiPropertyOptional({ description: 'Severity level number' })\n  severityNumber?: number\n\n  @ApiProperty({ description: 'Service name that generated the log' })\n  serviceName: string\n\n  @ApiProperty({\n    type: 'object',\n    description: 'Resource attributes from OTEL',\n    additionalProperties: { type: 'string' },\n  })\n  resourceAttributes: Record<string, string>\n\n  @ApiProperty({ type: 'object', description: 'Log-specific attributes', additionalProperties: { type: 'string' } })\n  logAttributes: Record<string, string>\n\n  @ApiPropertyOptional({ description: 'Associated trace ID if available' })\n  traceId?: string\n\n  @ApiPropertyOptional({ description: 'Associated span ID if available' })\n  spanId?: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/dto/metrics-response.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'MetricDataPoint' })\nexport class MetricDataPointDto {\n  @ApiProperty({ description: 'Timestamp of the data point' })\n  timestamp: string\n\n  @ApiProperty({ description: 'Value at this timestamp' })\n  value: number\n}\n\n@ApiSchema({ name: 'MetricSeries' })\nexport class MetricSeriesDto {\n  @ApiProperty({ description: 'Name of the metric' })\n  metricName: string\n\n  @ApiProperty({ type: [MetricDataPointDto], description: 'Data points for this metric' })\n  dataPoints: MetricDataPointDto[]\n}\n\n@ApiSchema({ name: 'MetricsResponse' })\nexport class MetricsResponseDto {\n  @ApiProperty({ type: [MetricSeriesDto], description: 'List of metric series' })\n  series: MetricSeriesDto[]\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/dto/paginated-logs.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { LogEntryDto } from './log-entry.dto'\n\n@ApiSchema({ name: 'PaginatedLogs' })\nexport class PaginatedLogsDto {\n  @ApiProperty({ type: [LogEntryDto], description: 'List of log entries' })\n  items: LogEntryDto[]\n\n  @ApiProperty({ description: 'Total number of log entries matching the query' })\n  total: number\n\n  @ApiProperty({ description: 'Current page number' })\n  page: number\n\n  @ApiProperty({ description: 'Total number of pages' })\n  totalPages: number\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/dto/paginated-traces.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { TraceSummaryDto } from './trace-summary.dto'\n\n@ApiSchema({ name: 'PaginatedTraces' })\nexport class PaginatedTracesDto {\n  @ApiProperty({ type: [TraceSummaryDto], description: 'List of trace summaries' })\n  items: TraceSummaryDto[]\n\n  @ApiProperty({ description: 'Total number of traces matching the query' })\n  total: number\n\n  @ApiProperty({ description: 'Current page number' })\n  page: number\n\n  @ApiProperty({ description: 'Total number of pages' })\n  totalPages: number\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/dto/telemetry-query-params.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'\nimport { IsDateString, IsOptional, IsArray, IsString, IsNumber, Min } from 'class-validator'\nimport { Type, Transform } from 'class-transformer'\n\nexport class TelemetryQueryParamsDto {\n  @ApiProperty({ type: String, format: 'date-time', description: 'Start of time range (ISO 8601)' })\n  @IsDateString()\n  from: string\n\n  @ApiProperty({ type: String, format: 'date-time', description: 'End of time range (ISO 8601)' })\n  @IsDateString()\n  to: string\n\n  @ApiPropertyOptional({ type: Number, default: 1, description: 'Page number (1-indexed)' })\n  @IsOptional()\n  @Type(() => Number)\n  @IsNumber()\n  @Min(1)\n  page?: number = 1\n\n  @ApiPropertyOptional({ type: Number, default: 100, description: 'Number of items per page' })\n  @IsOptional()\n  @Type(() => Number)\n  @IsNumber()\n  @Min(1)\n  limit?: number = 100\n}\n\nexport class LogsQueryParamsDto extends TelemetryQueryParamsDto {\n  @ApiPropertyOptional({\n    type: [String],\n    description: 'Filter by severity levels (DEBUG, INFO, WARN, ERROR)',\n  })\n  @IsOptional()\n  @IsArray()\n  @IsString({ each: true })\n  @Transform(({ value }) => (Array.isArray(value) ? value : [value]))\n  severities?: string[]\n\n  @ApiPropertyOptional({ type: String, description: 'Search in log body' })\n  @IsOptional()\n  @IsString()\n  search?: string\n}\n\nexport class MetricsQueryParamsDto {\n  @ApiProperty({ type: String, format: 'date-time', description: 'Start of time range (ISO 8601)' })\n  @IsDateString()\n  from: string\n\n  @ApiProperty({ type: String, format: 'date-time', description: 'End of time range (ISO 8601)' })\n  @IsDateString()\n  to: string\n\n  @ApiPropertyOptional({\n    type: [String],\n    description: 'Filter by metric names',\n  })\n  @IsOptional()\n  @IsArray()\n  @IsString({ each: true })\n  @Transform(({ value }) => (Array.isArray(value) ? value : [value]))\n  metricNames?: string[]\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/dto/trace-span.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'TraceSpan' })\nexport class TraceSpanDto {\n  @ApiProperty({ description: 'Trace identifier' })\n  traceId: string\n\n  @ApiProperty({ description: 'Span identifier' })\n  spanId: string\n\n  @ApiPropertyOptional({ description: 'Parent span identifier' })\n  parentSpanId?: string\n\n  @ApiProperty({ description: 'Span name' })\n  spanName: string\n\n  @ApiProperty({ description: 'Span start timestamp' })\n  timestamp: string\n\n  @ApiProperty({ description: 'Span duration in nanoseconds' })\n  durationNs: number\n\n  @ApiProperty({ type: 'object', description: 'Span attributes', additionalProperties: { type: 'string' } })\n  spanAttributes: Record<string, string>\n\n  @ApiPropertyOptional({ description: 'Status code of the span' })\n  statusCode?: string\n\n  @ApiPropertyOptional({ description: 'Status message' })\n  statusMessage?: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/dto/trace-summary.dto.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'TraceSummary' })\nexport class TraceSummaryDto {\n  @ApiProperty({ description: 'Unique trace identifier' })\n  traceId: string\n\n  @ApiProperty({ description: 'Name of the root span' })\n  rootSpanName: string\n\n  @ApiProperty({ description: 'Trace start time' })\n  startTime: string\n\n  @ApiProperty({ description: 'Trace end time' })\n  endTime: string\n\n  @ApiProperty({ description: 'Total duration in milliseconds' })\n  durationMs: number\n\n  @ApiProperty({ description: 'Number of spans in this trace' })\n  spanCount: number\n\n  @ApiPropertyOptional({ description: 'Status code of the trace' })\n  statusCode?: string\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/guards/analytics-api-disabled.guard.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CanActivate, Injectable, ForbiddenException } from '@nestjs/common'\nimport { TypedConfigService } from '../../config/typed-config.service'\n\n@Injectable()\nexport class AnalyticsApiDisabledGuard implements CanActivate {\n  constructor(private readonly configService: TypedConfigService) {}\n\n  canActivate(): boolean {\n    if (this.configService.get('analyticsApiUrl')) {\n      throw new ForbiddenException('Telemetry endpoints are disabled when Analytics API is configured')\n    }\n    return true\n  }\n}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport * from './sandbox-telemetry.module'\nexport * from './services/sandbox-telemetry.service'\nexport * from './dto'\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/sandbox-telemetry.module.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { SandboxTelemetryController } from './controllers/sandbox-telemetry.controller'\nimport { SandboxTelemetryService } from './services/sandbox-telemetry.service'\nimport { SandboxModule } from '../sandbox/sandbox.module'\nimport { OrganizationModule } from '../organization/organization.module'\n\n@Module({\n  imports: [SandboxModule, OrganizationModule],\n  controllers: [SandboxTelemetryController],\n  providers: [SandboxTelemetryService],\n  exports: [SandboxTelemetryService],\n})\nexport class SandboxTelemetryModule {}\n"
  },
  {
    "path": "apps/api/src/sandbox-telemetry/services/sandbox-telemetry.service.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { ClickHouseService } from '../../clickhouse/clickhouse.service'\nimport { LogEntryDto } from '../dto/log-entry.dto'\nimport { PaginatedLogsDto } from '../dto/paginated-logs.dto'\nimport { TraceSummaryDto } from '../dto/trace-summary.dto'\nimport { TraceSpanDto } from '../dto/trace-span.dto'\nimport { PaginatedTracesDto } from '../dto/paginated-traces.dto'\nimport { MetricsResponseDto, MetricSeriesDto, MetricDataPointDto } from '../dto/metrics-response.dto'\n\ninterface ClickHouseLogRow {\n  Timestamp: string\n  Body: string\n  SeverityText: string\n  SeverityNumber: number\n  ServiceName: string\n  ResourceAttributes: Record<string, string>\n  LogAttributes: Record<string, string>\n  TraceId: string\n  SpanId: string\n}\n\ninterface ClickHouseTraceAggregateRow {\n  TraceId: string\n  startTime: string\n  endTime: string\n  spanCount: number\n  rootSpanName: string\n  totalDuration: number\n  statusCode: string\n}\n\ninterface ClickHouseSpanRow {\n  TraceId: string\n  SpanId: string\n  ParentSpanId: string\n  SpanName: string\n  Timestamp: string\n  Duration: number\n  SpanAttributes: Record<string, string>\n  StatusCode: string\n  StatusMessage: string\n}\n\ninterface ClickHouseMetricRow {\n  timestamp: string\n  MetricName: string\n  value: number\n}\n\ninterface ClickHouseCountRow {\n  count: number\n}\n\n@Injectable()\nexport class SandboxTelemetryService {\n  private readonly logger = new Logger(SandboxTelemetryService.name)\n\n  constructor(private readonly clickhouseService: ClickHouseService) {}\n\n  private getServiceName(sandboxId: string): string {\n    return `sandbox-${sandboxId}`\n  }\n\n  isConfigured(): boolean {\n    return this.clickhouseService.isConfigured()\n  }\n\n  async getLogs(\n    sandboxId: string,\n    from: string,\n    to: string,\n    page: number,\n    limit: number,\n    severities?: string[],\n    search?: string,\n  ): Promise<PaginatedLogsDto> {\n    const serviceName = this.getServiceName(sandboxId)\n    const offset = (page - 1) * limit\n\n    // Build WHERE clause for optional filters\n    let whereClause = `ServiceName = {serviceName:String}\n      AND Timestamp >= {from:DateTime64}\n      AND Timestamp <= {to:DateTime64}`\n\n    if (severities && severities.length > 0) {\n      whereClause += ` AND SeverityText IN ({severities:Array(String)})`\n    }\n\n    if (search) {\n      whereClause += ` AND Body ILIKE {search:String}`\n    }\n\n    const params: Record<string, unknown> = {\n      serviceName,\n      from: new Date(from),\n      to: new Date(to),\n      limit,\n      offset,\n    }\n\n    if (severities && severities.length > 0) {\n      params.severities = severities\n    }\n\n    if (search) {\n      params.search = `%${search}%`\n    }\n\n    // Get total count\n    const countQuery = `\n      SELECT count() as count\n      FROM otel_logs\n      WHERE ${whereClause}\n    `\n    const countResult = await this.clickhouseService.query<ClickHouseCountRow>(countQuery, params)\n    const total = countResult[0]?.count || 0\n\n    // Get paginated logs\n    const logsQuery = `\n      SELECT Timestamp, Body, SeverityText, SeverityNumber, ServiceName,\n             ResourceAttributes, LogAttributes, TraceId, SpanId\n      FROM otel_logs\n      WHERE ${whereClause}\n      ORDER BY Timestamp DESC\n      LIMIT {limit:UInt32} OFFSET {offset:UInt32}\n    `\n    const rows = await this.clickhouseService.query<ClickHouseLogRow>(logsQuery, params)\n\n    const items: LogEntryDto[] = rows.map((row) => ({\n      timestamp: row.Timestamp,\n      body: row.Body,\n      severityText: row.SeverityText,\n      severityNumber: row.SeverityNumber,\n      serviceName: row.ServiceName,\n      resourceAttributes: row.ResourceAttributes || {},\n      logAttributes: row.LogAttributes || {},\n      traceId: row.TraceId || undefined,\n      spanId: row.SpanId || undefined,\n    }))\n\n    return {\n      items,\n      total,\n      page,\n      totalPages: Math.ceil(total / limit),\n    }\n  }\n\n  async getTraces(\n    sandboxId: string,\n    from: string,\n    to: string,\n    page: number,\n    limit: number,\n  ): Promise<PaginatedTracesDto> {\n    const serviceName = this.getServiceName(sandboxId)\n    const offset = (page - 1) * limit\n\n    const params = {\n      serviceName,\n      from: new Date(from),\n      to: new Date(to),\n      limit,\n      offset,\n    }\n\n    // Get total count of unique traces\n    const countQuery = `\n      SELECT count(DISTINCT TraceId) as count\n      FROM otel_traces\n      WHERE ServiceName = {serviceName:String}\n        AND Timestamp >= {from:DateTime64}\n        AND Timestamp <= {to:DateTime64}\n    `\n    const countResult = await this.clickhouseService.query<ClickHouseCountRow>(countQuery, params)\n    const total = countResult[0]?.count || 0\n\n    // Get aggregated trace data\n    const tracesQuery = `\n      SELECT\n        TraceId,\n        min(Timestamp) as startTime,\n        max(Timestamp) as endTime,\n        count() as spanCount,\n        argMinIf(SpanName, Timestamp, ParentSpanId = '') as rootSpanName,\n        max(Duration) as totalDuration,\n        any(StatusCode) as statusCode\n      FROM otel_traces\n      WHERE ServiceName = {serviceName:String}\n        AND Timestamp >= {from:DateTime64}\n        AND Timestamp <= {to:DateTime64}\n      GROUP BY TraceId\n      ORDER BY startTime DESC\n      LIMIT {limit:UInt32} OFFSET {offset:UInt32}\n    `\n    const rows = await this.clickhouseService.query<ClickHouseTraceAggregateRow>(tracesQuery, params)\n\n    const items: TraceSummaryDto[] = rows.map((row) => ({\n      traceId: row.TraceId,\n      rootSpanName: row.rootSpanName,\n      startTime: row.startTime,\n      endTime: row.endTime,\n      durationMs: row.totalDuration / 1_000_000, // Convert nanoseconds to milliseconds\n      spanCount: row.spanCount,\n      statusCode: row.statusCode || undefined,\n    }))\n\n    return {\n      items,\n      total,\n      page,\n      totalPages: Math.ceil(total / limit),\n    }\n  }\n\n  async getTraceSpans(sandboxId: string, traceId: string): Promise<TraceSpanDto[]> {\n    const serviceName = this.getServiceName(sandboxId)\n\n    const query = `\n      SELECT TraceId, SpanId, ParentSpanId, SpanName, Timestamp, Duration,\n             SpanAttributes, StatusCode, StatusMessage\n      FROM otel_traces\n      WHERE TraceId = {traceId:String}\n        AND ServiceName = {serviceName:String}\n      ORDER BY Timestamp ASC\n    `\n\n    const rows = await this.clickhouseService.query<ClickHouseSpanRow>(query, { traceId, serviceName })\n\n    return rows.map((row) => ({\n      traceId: row.TraceId,\n      spanId: row.SpanId,\n      parentSpanId: row.ParentSpanId || undefined,\n      spanName: row.SpanName,\n      timestamp: row.Timestamp,\n      durationNs: row.Duration,\n      spanAttributes: row.SpanAttributes || {},\n      statusCode: row.StatusCode || undefined,\n      statusMessage: row.StatusMessage || undefined,\n    }))\n  }\n\n  async getMetrics(sandboxId: string, from: string, to: string, metricNames?: string[]): Promise<MetricsResponseDto> {\n    const serviceName = this.getServiceName(sandboxId)\n\n    let whereClause = `ServiceName = {serviceName:String}\n      AND TimeUnix >= {from:DateTime64}\n      AND TimeUnix <= {to:DateTime64}`\n\n    const params: Record<string, unknown> = {\n      serviceName,\n      from: new Date(from),\n      to: new Date(to),\n    }\n\n    if (metricNames && metricNames.length > 0) {\n      whereClause += ` AND MetricName IN ({metricNames:Array(String)})`\n      params.metricNames = metricNames\n    }\n\n    // Query gauge metrics with 1-minute intervals\n    const gaugeQuery = `\n      SELECT\n        toStartOfInterval(TimeUnix, INTERVAL 1 MINUTE) as timestamp,\n        MetricName,\n        avg(Value) as value\n      FROM otel_metrics_gauge\n      WHERE ${whereClause}\n      GROUP BY timestamp, MetricName\n      ORDER BY timestamp ASC\n    `\n\n    const rows = await this.clickhouseService.query<ClickHouseMetricRow>(gaugeQuery, params)\n\n    // Group by metric name\n    const seriesMap = new Map<string, MetricDataPointDto[]>()\n    for (const row of rows) {\n      if (!seriesMap.has(row.MetricName)) {\n        seriesMap.set(row.MetricName, [])\n      }\n      seriesMap.get(row.MetricName)!.push({\n        timestamp: row.timestamp,\n        value: row.value,\n      })\n    }\n\n    const series: MetricSeriesDto[] = Array.from(seriesMap.entries()).map(([metricName, dataPoints]) => ({\n      metricName,\n      dataPoints,\n    }))\n\n    return { series }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/tracing.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { NodeSDK } from '@opentelemetry/sdk-node'\nimport { HttpInstrumentation } from '@opentelemetry/instrumentation-http'\nimport { ExpressInstrumentation } from '@opentelemetry/instrumentation-express'\nimport { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core'\nimport { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'\nimport { CompressionAlgorithm, OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base'\nimport { resourceFromAttributes } from '@opentelemetry/resources'\nimport { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'\nimport {\n  ATTR_DEPLOYMENT_ENVIRONMENT_NAME,\n  ATTR_SERVICE_INSTANCE_ID,\n} from '@opentelemetry/semantic-conventions/incubating'\nimport { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'\nimport { PgInstrumentation } from '@opentelemetry/instrumentation-pg'\nimport { KafkaJsInstrumentation } from '@opentelemetry/instrumentation-kafkajs'\nimport { getAppMode } from './common/utils/app-mode'\nimport { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'\nimport { hostname } from 'os'\nimport { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'\nimport { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\nimport { PinoInstrumentation } from '@opentelemetry/instrumentation-pino'\nimport { RuntimeNodeInstrumentation } from '@opentelemetry/instrumentation-runtime-node'\nimport { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs'\nimport { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'\n\n// Enable OpenTelemetry diagnostics\ndiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.WARN)\n\nconst appMode = getAppMode()\nconst serviceNameSuffix = appMode === 'api' ? 'api' : appMode === 'worker' ? 'worker' : 'api'\n\nconst otlpExporterConfig: OTLPExporterNodeConfigBase = {\n  compression: CompressionAlgorithm.GZIP,\n  keepAlive: true,\n}\n\nconst otelSdk = new NodeSDK({\n  resource: resourceFromAttributes({\n    [ATTR_SERVICE_NAME]: `daytona-${serviceNameSuffix}`,\n    [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: process.env.ENVIRONMENT,\n    [ATTR_SERVICE_INSTANCE_ID]: process.env.NODE_APP_INSTANCE\n      ? `${hostname()}-${process.env.NODE_APP_INSTANCE}`\n      : hostname(),\n  }),\n  instrumentations: [\n    new PinoInstrumentation(),\n    new HttpInstrumentation({ requireParentforOutgoingSpans: true }),\n    new ExpressInstrumentation(),\n    new NestInstrumentation(),\n    new IORedisInstrumentation({ requireParentSpan: true }),\n    new PgInstrumentation({ requireParentSpan: true }),\n    new KafkaJsInstrumentation(),\n    new RuntimeNodeInstrumentation(),\n  ],\n  logRecordProcessors: [new BatchLogRecordProcessor(new OTLPLogExporter(otlpExporterConfig))],\n  spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter(otlpExporterConfig))],\n  metricReaders: [\n    new PeriodicExportingMetricReader({\n      exporter: new OTLPMetricExporter(otlpExporterConfig),\n      exportIntervalMillis: 30 * 1000,\n    }),\n  ],\n})\n\nexport { otelSdk }\n\nprocess.on('SIGTERM', async () => {\n  console.log('SIGTERM received, shutting down OpenTelemetry SDK')\n  await otelSdk.shutdown()\n  console.log('OpenTelemetry SDK shut down')\n})\n"
  },
  {
    "path": "apps/api/src/usage/entities/sandbox-usage-period-archive.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'\nimport { SandboxUsagePeriod } from './sandbox-usage-period.entity'\n\n// Duplicate of SandboxUsagePeriod\n// Used to archive usage periods and keep the original table lightweight\n// Will only contain closed usage periods\n@Entity('sandbox_usage_periods_archive')\nexport class SandboxUsagePeriodArchive {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column()\n  sandboxId: string\n\n  @Column()\n  // Redundant property to optimize billing queries\n  organizationId: string\n\n  @Column({ type: 'timestamp with time zone' })\n  startAt: Date\n\n  @Column({ type: 'timestamp with time zone' })\n  endAt: Date\n\n  @Column({ type: 'float' })\n  cpu: number\n\n  @Column({ type: 'float' })\n  gpu: number\n\n  @Column({ type: 'float' })\n  mem: number\n\n  @Column({ type: 'float' })\n  disk: number\n\n  @Column()\n  region: string\n\n  public static fromUsagePeriod(usagePeriod: SandboxUsagePeriod) {\n    const usagePeriodEntity = new SandboxUsagePeriodArchive()\n    usagePeriodEntity.sandboxId = usagePeriod.sandboxId\n    usagePeriodEntity.organizationId = usagePeriod.organizationId\n    usagePeriodEntity.startAt = usagePeriod.startAt\n    usagePeriodEntity.endAt = usagePeriod.endAt\n    usagePeriodEntity.cpu = usagePeriod.cpu\n    usagePeriodEntity.gpu = usagePeriod.gpu\n    usagePeriodEntity.mem = usagePeriod.mem\n    usagePeriodEntity.disk = usagePeriod.disk\n    usagePeriodEntity.region = usagePeriod.region\n    return usagePeriodEntity\n  }\n}\n"
  },
  {
    "path": "apps/api/src/usage/entities/sandbox-usage-period.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'\n\n@Entity('sandbox_usage_periods')\n@Index('idx_sandbox_usage_periods_sandbox_end', ['sandboxId', 'endAt'])\nexport class SandboxUsagePeriod {\n  @PrimaryGeneratedColumn('uuid')\n  id: string\n\n  @Column()\n  sandboxId: string\n\n  @Column()\n  // Redundant property to optimize billing queries\n  organizationId: string\n\n  @Column({ type: 'timestamp with time zone' })\n  startAt: Date\n\n  @Column({ type: 'timestamp with time zone', nullable: true })\n  endAt: Date | null\n\n  @Column({ type: 'float' })\n  cpu: number\n\n  @Column({ type: 'float' })\n  gpu: number\n\n  @Column({ type: 'float' })\n  mem: number\n\n  @Column({ type: 'float' })\n  disk: number\n\n  @Column()\n  region: string\n\n  public static fromUsagePeriod(usagePeriod: SandboxUsagePeriod) {\n    const usagePeriodEntity = new SandboxUsagePeriod()\n    usagePeriodEntity.sandboxId = usagePeriod.sandboxId\n    usagePeriodEntity.organizationId = usagePeriod.organizationId\n    usagePeriodEntity.startAt = usagePeriod.startAt\n    usagePeriodEntity.endAt = usagePeriod.endAt\n    usagePeriodEntity.cpu = usagePeriod.cpu\n    usagePeriodEntity.gpu = usagePeriod.gpu\n    usagePeriodEntity.mem = usagePeriod.mem\n    usagePeriodEntity.disk = usagePeriod.disk\n    usagePeriodEntity.region = usagePeriod.region\n    return usagePeriodEntity\n  }\n}\n"
  },
  {
    "path": "apps/api/src/usage/services/usage.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, OnApplicationShutdown } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { IsNull, LessThan, Not, Repository } from 'typeorm'\nimport { SandboxUsagePeriod } from '../entities/sandbox-usage-period.entity'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport { SandboxStateUpdatedEvent } from '../../sandbox/events/sandbox-state-updated.event'\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\nimport { SandboxEvents } from './../../sandbox/constants/sandbox-events.constants'\nimport { Cron, CronExpression } from '@nestjs/schedule'\nimport { RedisLockProvider } from '../../sandbox/common/redis-lock.provider'\nimport { SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION } from '../../sandbox/constants/sandbox.constants'\nimport { SandboxUsagePeriodArchive } from '../entities/sandbox-usage-period-archive.entity'\nimport { TrackableJobExecutions } from '../../common/interfaces/trackable-job-executions'\nimport { TrackJobExecution } from '../../common/decorators/track-job-execution.decorator'\nimport { setTimeout as sleep } from 'timers/promises'\nimport { LogExecution } from '../../common/decorators/log-execution.decorator'\nimport { WithInstrumentation } from '../../common/decorators/otel.decorator'\nimport { SandboxRepository } from '../../sandbox/repositories/sandbox.repository'\n\n@Injectable()\nexport class UsageService implements TrackableJobExecutions, OnApplicationShutdown {\n  activeJobs = new Set<string>()\n  private readonly logger = new Logger(UsageService.name)\n\n  constructor(\n    @InjectRepository(SandboxUsagePeriod)\n    private sandboxUsagePeriodRepository: Repository<SandboxUsagePeriod>,\n    private readonly redisLockProvider: RedisLockProvider,\n    private readonly sandboxRepository: SandboxRepository,\n  ) {}\n\n  async onApplicationShutdown() {\n    //  wait for all active jobs to finish\n    while (this.activeJobs.size > 0) {\n      this.logger.log(`Waiting for ${this.activeJobs.size} active jobs to finish`)\n      await sleep(1000)\n    }\n  }\n\n  @OnEvent(SandboxEvents.STATE_UPDATED)\n  @TrackJobExecution()\n  async handleSandboxStateUpdate(event: SandboxStateUpdatedEvent) {\n    await this.waitForLock(event.sandbox.id)\n\n    try {\n      switch (event.newState) {\n        case SandboxState.STARTED: {\n          await this.closeUsagePeriod(event.sandbox.id)\n          await this.createUsagePeriod(event)\n          break\n        }\n        case SandboxState.STOPPING:\n          await this.closeUsagePeriod(event.sandbox.id)\n          await this.createUsagePeriod(event, true)\n          break\n        case SandboxState.ERROR:\n        case SandboxState.BUILD_FAILED:\n        case SandboxState.ARCHIVED:\n        case SandboxState.DESTROYED: {\n          await this.closeUsagePeriod(event.sandbox.id)\n          break\n        }\n      }\n    } finally {\n      this.releaseLock(event.sandbox.id).catch((error) => {\n        this.logger.error(`Error releasing lock for sandbox ${event.sandbox.id}`, error)\n      })\n    }\n  }\n\n  private async createUsagePeriod(event: SandboxStateUpdatedEvent, diskOnly = false) {\n    const usagePeriod = new SandboxUsagePeriod()\n    usagePeriod.sandboxId = event.sandbox.id\n    usagePeriod.startAt = new Date()\n    usagePeriod.endAt = null\n    if (!diskOnly) {\n      usagePeriod.cpu = event.sandbox.cpu\n      usagePeriod.gpu = event.sandbox.gpu\n      usagePeriod.mem = event.sandbox.mem\n    } else {\n      usagePeriod.cpu = 0\n      usagePeriod.gpu = 0\n      usagePeriod.mem = 0\n    }\n    usagePeriod.disk = event.sandbox.disk\n    usagePeriod.organizationId = event.sandbox.organizationId\n    usagePeriod.region = event.sandbox.region\n\n    await this.sandboxUsagePeriodRepository.save(usagePeriod)\n  }\n\n  private async closeUsagePeriod(sandboxId: string) {\n    const lastUsagePeriod = await this.sandboxUsagePeriodRepository.findOne({\n      where: {\n        sandboxId,\n        endAt: IsNull(),\n      },\n    })\n\n    if (lastUsagePeriod) {\n      lastUsagePeriod.endAt = new Date()\n      await this.sandboxUsagePeriodRepository.save(lastUsagePeriod)\n    }\n  }\n\n  @Cron(CronExpression.EVERY_MINUTE, { name: 'close-and-reopen-usage-periods' })\n  @TrackJobExecution()\n  @LogExecution('close-and-reopen-usage-periods')\n  @WithInstrumentation()\n  async closeAndReopenUsagePeriods() {\n    if (!(await this.redisLockProvider.lock('close-and-reopen-usage-periods', 60))) {\n      return\n    }\n\n    const usagePeriods = await this.sandboxUsagePeriodRepository.find({\n      where: {\n        endAt: IsNull(),\n        // 1 day ago\n        startAt: LessThan(new Date(Date.now() - 1000 * 60 * 60 * 24)),\n        organizationId: Not(SANDBOX_WARM_POOL_UNASSIGNED_ORGANIZATION),\n      },\n      order: {\n        startAt: 'ASC',\n      },\n      take: 100,\n    })\n\n    for (const usagePeriod of usagePeriods) {\n      if (!(await this.aquireLock(usagePeriod.sandboxId))) {\n        continue\n      }\n\n      // validate that the usage period should remain active just in case\n      try {\n        const sandbox = await this.sandboxRepository.findOne({\n          where: {\n            id: usagePeriod.sandboxId,\n          },\n        })\n\n        await this.sandboxUsagePeriodRepository.manager.transaction(async (transactionalEntityManager) => {\n          // Close usage period\n          const closeTime = new Date()\n          usagePeriod.endAt = closeTime\n          await transactionalEntityManager.save(usagePeriod)\n\n          if (\n            sandbox &&\n            (sandbox.state === SandboxState.STARTED ||\n              sandbox.state === SandboxState.STOPPED ||\n              sandbox.state === SandboxState.STOPPING)\n          ) {\n            // Create new usage period\n            const newUsagePeriod = SandboxUsagePeriod.fromUsagePeriod(usagePeriod)\n            newUsagePeriod.startAt = closeTime\n            newUsagePeriod.endAt = null\n            await transactionalEntityManager.save(newUsagePeriod)\n          }\n        })\n      } catch (error) {\n        this.logger.error(`Error closing and reopening usage period ${usagePeriod.sandboxId}`, error)\n      } finally {\n        await this.releaseLock(usagePeriod.sandboxId)\n      }\n    }\n\n    await this.redisLockProvider.unlock('close-and-reopen-usage-periods')\n  }\n\n  @Cron(CronExpression.EVERY_MINUTE, { name: 'archive-usage-periods' })\n  @TrackJobExecution()\n  @LogExecution('archive-usage-periods')\n  @WithInstrumentation()\n  async archiveUsagePeriods() {\n    const lockKey = 'archive-usage-periods'\n    if (!(await this.redisLockProvider.lock(lockKey, 60))) {\n      return\n    }\n\n    await this.sandboxUsagePeriodRepository.manager.transaction(async (transactionalEntityManager) => {\n      const usagePeriods = await transactionalEntityManager.find(SandboxUsagePeriod, {\n        where: {\n          endAt: Not(IsNull()),\n        },\n        order: {\n          startAt: 'ASC',\n        },\n        take: 1000,\n      })\n\n      if (usagePeriods.length === 0) {\n        return\n      }\n\n      this.logger.debug(`Found ${usagePeriods.length} usage periods to archive`)\n\n      await transactionalEntityManager.delete(\n        SandboxUsagePeriod,\n        usagePeriods.map((usagePeriod) => usagePeriod.id),\n      )\n      await transactionalEntityManager.save(usagePeriods.map(SandboxUsagePeriodArchive.fromUsagePeriod))\n    })\n\n    await this.redisLockProvider.unlock(lockKey)\n  }\n\n  private async waitForLock(sandboxId: string) {\n    while (!(await this.aquireLock(sandboxId))) {\n      await new Promise((resolve) => setTimeout(resolve, 500))\n    }\n  }\n\n  private async aquireLock(sandboxId: string): Promise<boolean> {\n    return await this.redisLockProvider.lock(`usage-period-${sandboxId}`, 60)\n  }\n\n  private async releaseLock(sandboxId: string) {\n    await this.redisLockProvider.unlock(`usage-period-${sandboxId}`)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/usage/usage.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { DataSource } from 'typeorm'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { SandboxUsagePeriod } from './entities/sandbox-usage-period.entity'\nimport { UsageService } from './services/usage.service'\nimport { RedisLockProvider } from '../sandbox/common/redis-lock.provider'\nimport { SandboxUsagePeriodArchive } from './entities/sandbox-usage-period-archive.entity'\nimport { SandboxRepository } from '../sandbox/repositories/sandbox.repository'\nimport { SandboxLookupCacheInvalidationService } from '../sandbox/services/sandbox-lookup-cache-invalidation.service'\nimport { Sandbox } from '../sandbox/entities/sandbox.entity'\n\n@Module({\n  imports: [TypeOrmModule.forFeature([SandboxUsagePeriod, Sandbox, SandboxUsagePeriodArchive])],\n  providers: [\n    UsageService,\n    RedisLockProvider,\n    SandboxLookupCacheInvalidationService,\n    {\n      provide: SandboxRepository,\n      inject: [DataSource, EventEmitter2, SandboxLookupCacheInvalidationService],\n      useFactory: (\n        dataSource: DataSource,\n        eventEmitter: EventEmitter2,\n        sandboxLookupCacheInvalidationService: SandboxLookupCacheInvalidationService,\n      ) => new SandboxRepository(dataSource, eventEmitter, sandboxLookupCacheInvalidationService),\n    },\n  ],\n  exports: [UsageService],\n})\nexport class UsageModule {}\n"
  },
  {
    "path": "apps/api/src/user/constants/acount-provider-display-name.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AccountProvider } from '../enums/account-provider.enum'\n\nexport const ACCOUNT_PROVIDER_DISPLAY_NAME: Record<AccountProvider, string> = {\n  [AccountProvider.GOOGLE]: 'Google',\n  [AccountProvider.GITHUB]: 'GitHub',\n}\n"
  },
  {
    "path": "apps/api/src/user/constants/user-events.constant.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const UserEvents = {\n  CREATED: 'user.created',\n  DELETED: 'user.deleted',\n  EMAIL_VERIFIED: 'user.email-verified',\n} as const\n"
  },
  {
    "path": "apps/api/src/user/dto/account-provider.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsString } from 'class-validator'\n\n@ApiSchema({ name: 'AccountProvider' })\nexport class AccountProviderDto {\n  @ApiProperty()\n  @IsString()\n  name: string\n\n  @ApiProperty()\n  @IsString()\n  displayName: string\n}\n"
  },
  {
    "path": "apps/api/src/user/dto/create-linked-account.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { IsString } from 'class-validator'\n\n@ApiSchema({ name: 'CreateLinkedAccount' })\nexport class CreateLinkedAccountDto {\n  @ApiProperty({\n    description: 'The authentication provider of the secondary account',\n  })\n  @IsString()\n  provider: string\n\n  @ApiProperty({\n    description: 'The user ID of the secondary account',\n  })\n  @IsString()\n  userId: string\n}\n"
  },
  {
    "path": "apps/api/src/user/dto/create-user.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsBoolean, IsEnum, IsOptional, IsString } from 'class-validator'\nimport { SystemRole } from '../enums/system-role.enum'\nimport { CreateOrganizationQuotaDto } from '../../organization/dto/create-organization-quota.dto'\n\n@ApiSchema({ name: 'CreateUser' })\nexport class CreateUserDto {\n  @ApiProperty()\n  @IsString()\n  id: string\n\n  @ApiProperty()\n  @IsString()\n  name: string\n\n  @ApiPropertyOptional()\n  @IsString()\n  @IsOptional()\n  email?: string\n\n  @ApiPropertyOptional()\n  @IsOptional()\n  personalOrganizationQuota?: CreateOrganizationQuotaDto\n\n  @ApiPropertyOptional()\n  @IsString()\n  @IsOptional()\n  personalOrganizationDefaultRegionId?: string\n\n  @ApiPropertyOptional({\n    enum: SystemRole,\n  })\n  @IsEnum(SystemRole)\n  @IsOptional()\n  role?: SystemRole\n\n  @ApiPropertyOptional()\n  @IsBoolean()\n  @IsOptional()\n  emailVerified?: boolean\n}\n"
  },
  {
    "path": "apps/api/src/user/dto/update-user.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiPropertyOptional, ApiSchema } from '@nestjs/swagger'\nimport { IsBoolean, IsEnum, IsOptional, IsString } from 'class-validator'\nimport { SystemRole } from '../enums/system-role.enum'\n\n@ApiSchema({ name: 'UpdateUser' })\nexport class UpdateUserDto {\n  @ApiPropertyOptional()\n  @IsString()\n  @IsOptional()\n  name?: string\n\n  @ApiPropertyOptional()\n  @IsString()\n  @IsOptional()\n  email?: string\n\n  @ApiPropertyOptional({\n    enum: SystemRole,\n  })\n  @IsEnum(SystemRole)\n  @IsOptional()\n  role?: SystemRole\n\n  @ApiPropertyOptional()\n  @IsBoolean()\n  @IsOptional()\n  emailVerified?: boolean\n}\n"
  },
  {
    "path": "apps/api/src/user/dto/user-public-key.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { UserPublicKey } from '../user.entity'\n\n@ApiSchema({ name: 'UserPublicKey' })\nexport class UserPublicKeyDto {\n  @ApiProperty({\n    description: 'Public key',\n  })\n  key: string\n\n  @ApiProperty({\n    description: 'Key name',\n  })\n  name: string\n\n  static fromUserPublicKey(publicKey: UserPublicKey): UserPublicKeyDto {\n    const dto: UserPublicKeyDto = {\n      key: publicKey.key,\n      name: publicKey.name,\n    }\n\n    return dto\n  }\n}\n"
  },
  {
    "path": "apps/api/src/user/dto/user.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { User } from '../user.entity'\nimport { UserPublicKeyDto } from './user-public-key.dto'\n\n@ApiSchema({ name: 'User' })\nexport class UserDto {\n  @ApiProperty({\n    description: 'User ID',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'User name',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'User email',\n  })\n  email: string\n\n  @ApiProperty({\n    description: 'User public keys',\n    type: [UserPublicKeyDto],\n  })\n  publicKeys: UserPublicKeyDto[]\n\n  @ApiProperty({\n    description: 'Creation timestamp',\n  })\n  createdAt: Date\n\n  static fromUser(user: User): UserDto {\n    const dto: UserDto = {\n      id: user.id,\n      name: user.name,\n      email: user.email,\n      publicKeys: user.publicKeys.map(UserPublicKeyDto.fromUserPublicKey),\n      createdAt: user.createdAt,\n    }\n\n    return dto\n  }\n}\n"
  },
  {
    "path": "apps/api/src/user/enums/account-provider.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum AccountProvider {\n  GOOGLE = 'google-oauth2',\n  GITHUB = 'github',\n}\n"
  },
  {
    "path": "apps/api/src/user/enums/system-role.enum.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum SystemRole {\n  ADMIN = 'admin',\n  USER = 'user',\n}\n"
  },
  {
    "path": "apps/api/src/user/events/user-created.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm'\nimport { User } from '../user.entity'\nimport { CreateOrganizationQuotaDto } from '../../organization/dto/create-organization-quota.dto'\n\nexport class UserCreatedEvent {\n  constructor(\n    public readonly entityManager: EntityManager,\n    public readonly user: User,\n    public readonly personalOrganizationQuota?: CreateOrganizationQuotaDto,\n    public readonly personalOrganizationDefaultRegionId?: string,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/user/events/user-deleted.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm'\n\nexport class UserDeletedEvent {\n  constructor(\n    public readonly entityManager: EntityManager,\n    public readonly userId: string,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/user/events/user-email-verified.event.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { EntityManager } from 'typeorm'\n\nexport class UserEmailVerifiedEvent {\n  constructor(\n    public readonly entityManager: EntityManager,\n    public readonly userId: string,\n  ) {}\n}\n"
  },
  {
    "path": "apps/api/src/user/user.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  BadRequestException,\n  Body,\n  Controller,\n  Delete,\n  ForbiddenException,\n  Get,\n  Logger,\n  NotFoundException,\n  Param,\n  Post,\n  UnauthorizedException,\n  UseGuards,\n} from '@nestjs/common'\nimport { User } from './user.entity'\nimport { UserService } from './user.service'\nimport { CreateUserDto } from './dto/create-user.dto'\nimport { ApiOAuth2, ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger'\nimport { CombinedAuthGuard } from '../auth/combined-auth.guard'\nimport { AuthContext } from '../common/decorators/auth-context.decorator'\nimport { AuthContext as IAuthContext } from '../common/interfaces/auth-context.interface'\nimport { UserDto } from './dto/user.dto'\nimport { SystemActionGuard } from '../auth/system-action.guard'\nimport { RequiredSystemRole } from '../common/decorators/required-role.decorator'\nimport { SystemRole } from './enums/system-role.enum'\nimport { TypedConfigService } from '../config/typed-config.service'\nimport axios from 'axios'\nimport { AccountProviderDto } from './dto/account-provider.dto'\nimport { ACCOUNT_PROVIDER_DISPLAY_NAME } from './constants/acount-provider-display-name.constant'\nimport { AccountProvider } from './enums/account-provider.enum'\nimport { CreateLinkedAccountDto } from './dto/create-linked-account.dto'\nimport { Audit, TypedRequest } from '../audit/decorators/audit.decorator'\nimport { AuditAction } from '../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../audit/enums/audit-target.enum'\nimport { AuthenticatedRateLimitGuard } from '../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('users')\n@Controller('users')\n@UseGuards(CombinedAuthGuard, AuthenticatedRateLimitGuard, SystemActionGuard)\n@ApiOAuth2(['openid', 'profile', 'email'])\n@ApiBearerAuth()\nexport class UserController {\n  private readonly logger = new Logger(UserController.name)\n\n  constructor(\n    private readonly userService: UserService,\n    private readonly configService: TypedConfigService,\n  ) {}\n\n  @Get('/me')\n  @ApiOperation({\n    summary: 'Get authenticated user',\n    operationId: 'getAuthenticatedUser',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'User details',\n    type: UserDto,\n  })\n  async getAuthenticatedUser(@AuthContext() authContext: IAuthContext): Promise<UserDto> {\n    const user = await this.userService.findOne(authContext.userId)\n    if (!user) {\n      throw new NotFoundException(`User with ID ${authContext.userId} not found`)\n    }\n\n    return UserDto.fromUser(user)\n  }\n\n  @Post()\n  @ApiOperation({\n    summary: 'Create user',\n    operationId: 'createUser',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @Audit({\n    action: AuditAction.CREATE,\n    targetType: AuditTarget.USER,\n    targetIdFromResult: (result: User) => result?.id,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateUserDto>) => ({\n        id: req.body?.id,\n        name: req.body?.name,\n        email: req.body?.email,\n        personalOrganizationQuota: req.body?.personalOrganizationQuota,\n        role: req.body?.role,\n        emailVerified: req.body?.emailVerified,\n      }),\n    },\n  })\n  async create(@Body() createUserDto: CreateUserDto): Promise<User> {\n    return this.userService.create(createUserDto)\n  }\n\n  @Get()\n  @ApiOperation({\n    summary: 'List all users',\n    operationId: 'listUsers',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  async findAll(): Promise<User[]> {\n    return this.userService.findAll()\n  }\n\n  @Post('/:id/regenerate-key-pair')\n  @ApiOperation({\n    summary: 'Regenerate user key pair',\n    operationId: 'regenerateKeyPair',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @Audit({\n    action: AuditAction.REGENERATE_KEY_PAIR,\n    targetType: AuditTarget.USER,\n    targetIdFromRequest: (req) => req.params.id,\n  })\n  async regenerateKeyPair(@Param('id') id: string): Promise<User> {\n    return this.userService.regenerateKeyPair(id)\n  }\n\n  @Get('/account-providers')\n  @ApiOperation({\n    summary: 'Get available account providers',\n    operationId: 'getAvailableAccountProviders',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'Available account providers',\n    type: [AccountProviderDto],\n  })\n  async getAvailableAccountProviders(): Promise<AccountProviderDto[]> {\n    if (!this.configService.get('oidc.managementApi.enabled')) {\n      this.logger.warn('OIDC Management API is not enabled')\n      throw new NotFoundException()\n    }\n\n    const token = await this.getManagementApiToken()\n\n    try {\n      const response = await axios.get<{ name: string }[]>(\n        `${this.configService.getOrThrow('oidc.issuer')}/api/v2/connections`,\n        {\n          headers: {\n            Authorization: `Bearer ${token}`,\n          },\n        },\n      )\n\n      const supportedProviders = new Set([AccountProvider.GOOGLE, AccountProvider.GITHUB])\n\n      const result: AccountProviderDto[] = response.data\n        .filter((connection) => supportedProviders.has(connection.name as AccountProvider))\n        .map((connection) => ({\n          name: connection.name,\n          displayName: ACCOUNT_PROVIDER_DISPLAY_NAME[connection.name as AccountProvider],\n        }))\n\n      return result\n    } catch (error) {\n      this.logger.error('Failed to get available account providers', error?.message || String(error))\n      throw new UnauthorizedException()\n    }\n  }\n\n  @Post('/linked-accounts')\n  @ApiOperation({\n    summary: 'Link account',\n    operationId: 'linkAccount',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Account linked successfully',\n  })\n  @Audit({\n    action: AuditAction.LINK_ACCOUNT,\n    requestMetadata: {\n      body: (req: TypedRequest<CreateLinkedAccountDto>) => ({\n        provider: req.body?.provider,\n        userId: req.body?.userId,\n      }),\n    },\n  })\n  async linkAccount(\n    @AuthContext() authContext: IAuthContext,\n    @Body() createLinkedAccountDto: CreateLinkedAccountDto,\n  ): Promise<void> {\n    if (!this.configService.get('oidc.managementApi.enabled')) {\n      this.logger.warn('OIDC Management API is not enabled')\n      throw new NotFoundException()\n    }\n\n    const authenticatedUser = await this.userService.findOne(authContext.userId)\n    if (!authenticatedUser.emailVerified) {\n      throw new ForbiddenException('Please verify your email address')\n    }\n\n    const userToLinkId = `${createLinkedAccountDto.provider}|${createLinkedAccountDto.userId}`\n\n    // Verify user doesn't already exist in our user table\n    const userToLink = await this.userService.findOne(userToLinkId)\n    if (userToLink) {\n      throw new BadRequestException('This account is already associated with another user')\n    }\n\n    const token = await this.getManagementApiToken()\n\n    // Verify account is eligible to be linked (must be reachable via OIDC Management API)\n    try {\n      await axios.get(\n        `${this.configService.getOrThrow('oidc.issuer')}/api/v2/users/${encodeURIComponent(userToLinkId)}`,\n        {\n          headers: {\n            Authorization: `Bearer ${token}`,\n          },\n        },\n      )\n    } catch (error) {\n      if (axios.isAxiosError(error) && error.response?.status === 404) {\n        throw new BadRequestException('Account not found or already linked to another user')\n      }\n      throw error\n    }\n\n    // Link account\n    try {\n      await axios.post(\n        `${this.configService.getOrThrow('oidc.issuer')}/api/v2/users/${authContext.userId}/identities`,\n        {\n          provider: createLinkedAccountDto.provider,\n          user_id: createLinkedAccountDto.userId,\n        },\n        {\n          headers: {\n            Authorization: `Bearer ${token}`,\n          },\n        },\n      )\n    } catch (error) {\n      this.logger.error('Failed to link account', error?.message || String(error))\n      throw new UnauthorizedException()\n    }\n  }\n\n  @Delete('/linked-accounts/:provider/:providerUserId')\n  @ApiOperation({\n    summary: 'Unlink account',\n    operationId: 'unlinkAccount',\n  })\n  @ApiResponse({\n    status: 204,\n    description: 'Account unlinked successfully',\n  })\n  @Audit({\n    action: AuditAction.UNLINK_ACCOUNT,\n    requestMetadata: {\n      params: (req) => ({\n        provider: req.params.provider,\n        providerUserId: req.params.providerUserId,\n      }),\n    },\n  })\n  async unlinkAccount(\n    @AuthContext() authContext: IAuthContext,\n    @Param('provider') provider: string,\n    @Param('providerUserId') providerUserId: string,\n  ): Promise<void> {\n    if (!this.configService.get('oidc.managementApi.enabled')) {\n      this.logger.warn('OIDC Management API is not enabled')\n      throw new NotFoundException()\n    }\n\n    const token = await this.getManagementApiToken()\n\n    try {\n      await axios.delete(\n        `${this.configService.getOrThrow('oidc.issuer')}/api/v2/users/${authContext.userId}/identities/${provider}/${providerUserId}`,\n        {\n          headers: {\n            Authorization: `Bearer ${token}`,\n          },\n        },\n      )\n    } catch (error) {\n      this.logger.error('Failed to unlink account', error?.message || String(error))\n      throw new UnauthorizedException()\n    }\n  }\n\n  @Post('/mfa/sms/enroll')\n  @ApiOperation({\n    summary: 'Enroll in SMS MFA',\n    operationId: 'enrollInSmsMfa',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'SMS MFA enrollment URL',\n    type: String,\n  })\n  async enrollInSmsMfa(@AuthContext() authContext: IAuthContext): Promise<string> {\n    if (!this.configService.get('oidc.managementApi.enabled')) {\n      this.logger.warn('OIDC Management API is not enabled')\n      throw new NotFoundException()\n    }\n\n    const token = await this.getManagementApiToken()\n\n    try {\n      const response = await axios.post(\n        `${this.configService.getOrThrow('oidc.issuer')}/api/v2/guardian/enrollments/ticket`,\n        {\n          user_id: authContext.userId,\n        },\n        {\n          headers: {\n            Authorization: `Bearer ${token}`,\n          },\n        },\n      )\n\n      return response.data.ticket_url\n    } catch (error) {\n      this.logger.error('Failed to enable SMS MFA', error?.message || String(error))\n      throw new UnauthorizedException()\n    }\n  }\n\n  @Get('/:id')\n  @ApiOperation({\n    summary: 'Get user by ID',\n    operationId: 'getUser',\n  })\n  @ApiResponse({\n    status: 200,\n    description: 'User details',\n    type: UserDto,\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  async getUserById(@Param('id') id: string): Promise<UserDto> {\n    const user = await this.userService.findOne(id)\n    if (!user) {\n      throw new NotFoundException(`User with ID ${id} not found`)\n    }\n\n    return UserDto.fromUser(user)\n  }\n\n  private async getManagementApiToken(): Promise<string> {\n    try {\n      const tokenResponse = await axios.post(`${this.configService.getOrThrow('oidc.issuer')}/oauth/token`, {\n        grant_type: 'client_credentials',\n        client_id: this.configService.getOrThrow('oidc.managementApi.clientId'),\n        client_secret: this.configService.getOrThrow('oidc.managementApi.clientSecret'),\n        audience: this.configService.getOrThrow('oidc.managementApi.audience'),\n      })\n      return tokenResponse.data.access_token\n    } catch (error) {\n      this.logger.error('Failed to get OIDC Management API token', error?.message || String(error))\n      throw new UnauthorizedException()\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/user/user.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column, CreateDateColumn, Entity, PrimaryColumn } from 'typeorm'\nimport { SystemRole } from './enums/system-role.enum'\n\nexport interface UserSSHKeyPair {\n  privateKey: string\n  publicKey: string\n}\n\nexport interface UserPublicKey {\n  key: string\n  name: string\n}\n\n@Entity()\nexport class User {\n  @PrimaryColumn()\n  id: string\n\n  @Column()\n  name: string\n\n  @Column({\n    default: '',\n  })\n  email: string\n\n  @Column({\n    default: false,\n  })\n  emailVerified: boolean\n\n  @Column({\n    type: 'simple-json',\n    nullable: true,\n  })\n  keyPair: UserSSHKeyPair\n\n  @Column('simple-json')\n  publicKeys: UserPublicKey[]\n\n  @Column({\n    type: 'enum',\n    enum: SystemRole,\n    default: SystemRole.USER,\n  })\n  role: SystemRole\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/user/user.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { UserController } from './user.controller'\nimport { UserService } from './user.service'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { User } from './user.entity'\n\n@Module({\n  imports: [TypeOrmModule.forFeature([User])],\n  controllers: [UserController],\n  providers: [UserService],\n  exports: [UserService],\n})\nexport class UserModule {}\n"
  },
  {
    "path": "apps/api/src/user/user.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, NotFoundException } from '@nestjs/common'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { User, UserSSHKeyPair } from './user.entity'\nimport { DataSource, ILike, In, Repository } from 'typeorm'\nimport { CreateUserDto } from './dto/create-user.dto'\nimport * as crypto from 'crypto'\nimport * as forge from 'node-forge'\nimport { EventEmitter2 } from '@nestjs/event-emitter'\nimport { UserEvents } from './constants/user-events.constant'\nimport { UpdateUserDto } from './dto/update-user.dto'\nimport { UserCreatedEvent } from './events/user-created.event'\nimport { UserDeletedEvent } from './events/user-deleted.event'\nimport { UserEmailVerifiedEvent } from './events/user-email-verified.event'\n\n@Injectable()\nexport class UserService {\n  constructor(\n    @InjectRepository(User)\n    private readonly userRepository: Repository<User>,\n    private readonly eventEmitter: EventEmitter2,\n    private readonly dataSource: DataSource,\n  ) {}\n\n  async create(createUserDto: CreateUserDto): Promise<User> {\n    let user = new User()\n    user.id = createUserDto.id\n    user.name = createUserDto.name\n    const keyPair = await this.generatePrivateKey()\n    user.keyPair = keyPair\n    user.publicKeys = []\n    user.emailVerified = createUserDto.emailVerified\n\n    if (createUserDto.email) {\n      user.email = createUserDto.email\n    }\n\n    if (createUserDto.role) {\n      user.role = createUserDto.role\n    }\n\n    await this.dataSource.transaction(async (em) => {\n      user = await em.save(user)\n      await this.eventEmitter.emitAsync(\n        UserEvents.CREATED,\n        new UserCreatedEvent(\n          em,\n          user,\n          createUserDto.personalOrganizationQuota,\n          createUserDto.personalOrganizationDefaultRegionId,\n        ),\n      )\n    })\n\n    return user\n  }\n\n  async findAll(): Promise<User[]> {\n    return this.userRepository.find()\n  }\n\n  async findByIds(ids: string[]): Promise<User[]> {\n    if (ids.length === 0) {\n      return []\n    }\n\n    return this.userRepository.find({\n      where: {\n        id: In(ids),\n      },\n    })\n  }\n\n  async findOne(id: string): Promise<User | null> {\n    return this.userRepository.findOne({ where: { id } })\n  }\n\n  async findOneOrFail(id: string): Promise<User> {\n    return this.userRepository.findOneOrFail({ where: { id } })\n  }\n\n  async findOneByEmail(email: string, ignoreCase = false): Promise<User | null> {\n    return this.userRepository.findOne({\n      where: {\n        email: ignoreCase ? ILike(email) : email,\n      },\n    })\n  }\n\n  async remove(id: string): Promise<void> {\n    await this.dataSource.transaction(async (em) => {\n      await em.delete(User, id)\n      await this.eventEmitter.emitAsync(UserEvents.DELETED, new UserDeletedEvent(em, id))\n    })\n  }\n\n  async regenerateKeyPair(id: string): Promise<User> {\n    const user = await this.userRepository.findOneBy({ id: id })\n    const keyPair = await this.generatePrivateKey()\n    user.keyPair = keyPair\n    return this.userRepository.save(user)\n  }\n\n  private generatePrivateKey(): Promise<UserSSHKeyPair> {\n    const comment = 'daytona'\n\n    return new Promise((resolve, reject) => {\n      crypto.generateKeyPair(\n        'rsa',\n        {\n          modulusLength: 4096,\n          publicKeyEncoding: {\n            type: 'pkcs1',\n            format: 'pem',\n          },\n          privateKeyEncoding: {\n            type: 'pkcs1',\n            format: 'pem',\n          },\n        },\n        (error, publicKey, privateKey) => {\n          if (error) {\n            reject(error)\n          } else {\n            const publicKeySShEncoded = forge.ssh.publicKeyToOpenSSH(forge.pki.publicKeyFromPem(publicKey), comment)\n\n            const privateKeySShEncoded = forge.ssh.privateKeyToOpenSSH(forge.pki.privateKeyFromPem(privateKey))\n\n            resolve({\n              publicKey: publicKeySShEncoded,\n              privateKey: privateKeySShEncoded,\n            })\n          }\n        },\n      )\n    })\n  }\n\n  // TODO: discuss if we need separate methods for updating specific fields\n  async update(userId: string, updateUserDto: UpdateUserDto): Promise<User> {\n    const user = await this.userRepository.findOne({\n      where: {\n        id: userId,\n      },\n    })\n\n    if (!user) {\n      throw new NotFoundException(`User with ID ${userId} not found.`)\n    }\n\n    if (updateUserDto.name) {\n      user.name = updateUserDto.name\n    }\n\n    if (updateUserDto.email) {\n      user.email = updateUserDto.email\n    }\n\n    if (updateUserDto.role) {\n      user.role = updateUserDto.role\n    }\n\n    if (updateUserDto.emailVerified) {\n      user.emailVerified = updateUserDto.emailVerified\n      await this.dataSource.transaction(async (em) => {\n        await em.save(user)\n        await this.eventEmitter.emitAsync(UserEvents.EMAIL_VERIFIED, new UserEmailVerifiedEvent(em, user.id))\n      })\n    }\n\n    return this.userRepository.save(user)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/webhook/README.md",
    "content": "# Webhook Service\n\nThis service provides webhook functionality using [Svix](https://svix.com) as the webhook delivery provider. It automatically creates Svix applications for new organizations and sends webhooks for various events.\n\n## Configuration\n\nSet the following environment variables:\n\n```bash\n# Required: Your Svix authentication token\nSVIX_AUTH_TOKEN=your_svix_auth_token_here\n\n# Optional: Custom Svix server URL (for self-hosted instances)\nSVIX_SERVER_URL=https://your-svix-instance.com\n```\n\n## API Endpoints\n\n### Get App Portal Access\n\n```http\nPOST /api/webhooks/organizations/{organizationId}/app-portal-access\n```\n\n**Response:**\n\n```json\n{\n  \"url\": \"https://app.svix.com/consumer/...\"\n}\n```\n\nReturns a URL that provides access to the Svix Consumer App Portal for managing webhook endpoints, viewing delivery attempts, and monitoring webhook performance.\n\n### Send Custom Webhook\n\n```http\nPOST /api/webhooks/organizations/{organizationId}/send\n```\n\n**Request Body:**\n\n```json\n{\n  \"eventType\": \"custom.event\",\n  \"payload\": {\n    \"message\": \"Hello from Daytona!\",\n    \"timestamp\": \"2025-01-01T00:00:00.000Z\"\n  },\n  \"eventId\": \"optional-unique-id\"\n}\n```\n\nSends a custom webhook message to all configured endpoints for the specified organization.\n\n### Get Message Delivery Attempts\n\n```http\nGET /api/webhooks/organizations/{organizationId}/messages/{messageId}/attempts\n```\n\n**Response:**\n\n```json\n[\n  {\n    \"id\": \"msg_attempt_123\",\n    \"status\": 200,\n    \"response\": \"OK\",\n    \"timestamp\": \"2025-01-01T00:00:00.000Z\"\n  }\n]\n```\n\nReturns the delivery attempts for a specific webhook message, including delivery status and response details.\n\n### Get Service Status\n\n```http\nGET /api/webhooks/status\n```\n\n**Response:**\n\n```json\n{\n  \"enabled\": true\n}\n```\n\nReturns the current status of the webhook service, indicating whether it's properly configured and enabled.\n\n## Automatic Events\n\nThe service automatically sends webhooks for the following events:\n\n### Sandbox Events\n\n- `sandbox.created` - When a sandbox is created\n- `sandbox.state.updated` - When sandbox state changes\n\n### Snapshot Events\n\n- `snapshot.created` - When a snapshot is created\n- `snapshot.state.updated` - When snapshot state changes\n- `snapshot.removed` - When a snapshot is removed\n\n### Volume Events\n\n- `volume.created` - When a volume is created\n- `volume.state.updated` - When volume state changes\n\n## Webhook Payload Format\n\nAll webhooks include event-specific data relevant to the resource being updated.\n\n### Example Sandbox Created Payload\n\n```json\n{\n  \"id\": \"sandbox-uuid\",\n  \"organizationId\": \"org-uuid\",\n  \"state\": \"STARTED\",\n  \"class\": \"SMALL\",\n  \"createdAt\": \"2025-01-01T00:00:00.000Z\"\n}\n```\n\n### Example Sandbox State Updated Payload\n\n```json\n{\n  \"id\": \"sandbox-uuid\",\n  \"organizationId\": \"org-uuid\",\n  \"oldState\": \"STOPPED\",\n  \"newState\": \"STARTED\",\n  \"updatedAt\": \"2025-01-01T00:00:00.000Z\"\n}\n```\n\n### Example Snapshot Created Payload\n\n```json\n{\n  \"id\": \"snapshot-uuid\",\n  \"name\": \"my-snapshot\",\n  \"organizationId\": \"org-uuid\",\n  \"state\": \"ACTIVE\",\n  \"createdAt\": \"2025-01-01T00:00:00.000Z\"\n}\n```\n\n### Example Volume State Updated Payload\n\n```json\n{\n  \"id\": \"volume-uuid\",\n  \"name\": \"my-volume\",\n  \"organizationId\": \"org-uuid\",\n  \"oldState\": \"CREATING\",\n  \"newState\": \"READY\",\n  \"updatedAt\": \"2025-01-01T00:00:00.000Z\"\n}\n```\n\n## Development\n\n### Adding New Event Types\n\n1. Add the event type to `webhook-events.constants.ts`\n2. Create an event handler in `webhook-event-handler.service.ts`\n3. Use the `@OnEvent()` decorator to listen for the event\n4. Define the payload structure for the new event type\n5. Add the events to the `openapi-webhooks.ts`\n6. Generate the openapi spec\n7. Upload the new schema to the Svix dashboard\n\n### Testing\n\nUse the Svix Play webhook debugger during development:\n\n1. Set up a webhook endpoint pointing to your Svix Play URL\n2. Send test webhooks using the `/send` endpoint\n3. Check the Svix dashboard for delivery status\n4. Monitor delivery attempts through the API\n\n### Local Development\n\nFor local development without Svix:\n\n1. Set `SVIX_AUTH_TOKEN` to an empty string or invalid value\n2. The service will log warnings but continue to function\n3. Event handlers will skip webhook delivery when disabled\n4. Use the status endpoint to verify configuration\n\n## Dependencies\n\n- `svix` - Official Svix JavaScript SDK\n- `@nestjs/event-emitter` - Event handling\n- `@nestjs/common` - Core NestJS functionality\n\n### Event Flow\n\n1. System event occurs (e.g., sandbox created)\n2. Event emitter publishes the event\n3. Webhook event handler catches the event\n4. Handler calls webhook service to send webhook\n5. Service delivers webhook through Svix\n6. Delivery status is tracked and available via API\n"
  },
  {
    "path": "apps/api/src/webhook/constants/webhook-events.constants.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum WebhookEvent {\n  SANDBOX_CREATED = 'sandbox.created',\n  SANDBOX_STATE_UPDATED = 'sandbox.state.updated',\n  SNAPSHOT_CREATED = 'snapshot.created',\n  SNAPSHOT_STATE_UPDATED = 'snapshot.state.updated',\n  SNAPSHOT_REMOVED = 'snapshot.removed',\n  VOLUME_CREATED = 'volume.created',\n  VOLUME_STATE_UPDATED = 'volume.state.updated',\n}\n"
  },
  {
    "path": "apps/api/src/webhook/controllers/webhook.controller.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Controller, Post, Get, Body, Param, UseGuards, HttpStatus, NotFoundException } from '@nestjs/common'\nimport { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiHeader } from '@nestjs/swagger'\nimport { WebhookService } from '../services/webhook.service'\nimport { SendWebhookDto } from '../dto/send-webhook.dto'\nimport { CombinedAuthGuard } from '../../auth/combined-auth.guard'\nimport { CustomHeaders } from '../../common/constants/header.constants'\nimport { SystemActionGuard } from '../../auth/system-action.guard'\nimport { OrganizationAccessGuard } from '../../organization/guards/organization-access.guard'\nimport { RequiredSystemRole } from '../../common/decorators/required-role.decorator'\nimport { SystemRole } from '../../user/enums/system-role.enum'\nimport { Audit, TypedRequest } from '../../audit/decorators/audit.decorator'\nimport { AuditAction } from '../../audit/enums/audit-action.enum'\nimport { AuditTarget } from '../../audit/enums/audit-target.enum'\nimport { OrganizationService } from '../../organization/services/organization.service'\nimport { WebhookAppPortalAccessDto } from '../dto/webhook-app-portal-access.dto'\nimport { WebhookInitializationStatusDto } from '../dto/webhook-initialization-status.dto'\nimport { AuthenticatedRateLimitGuard } from '../../common/guards/authenticated-rate-limit.guard'\n\n@ApiTags('webhooks')\n@Controller('webhooks')\n@ApiHeader(CustomHeaders.ORGANIZATION_ID)\n@UseGuards(CombinedAuthGuard, SystemActionGuard, OrganizationAccessGuard, AuthenticatedRateLimitGuard)\n@ApiBearerAuth()\nexport class WebhookController {\n  constructor(\n    private readonly organizationService: OrganizationService,\n    private readonly webhookService: WebhookService,\n  ) {}\n\n  @Post('organizations/:organizationId/app-portal-access')\n  @ApiOperation({ summary: 'Get Svix Consumer App Portal access for an organization' })\n  @ApiResponse({\n    status: HttpStatus.OK,\n    description: 'App Portal access generated successfully',\n    type: WebhookAppPortalAccessDto,\n  })\n  async getAppPortalAccess(@Param('organizationId') organizationId: string): Promise<WebhookAppPortalAccessDto> {\n    return this.webhookService.getAppPortalAccess(organizationId)\n  }\n\n  @Post('organizations/:organizationId/send')\n  @ApiOperation({ summary: 'Send a webhook message to an organization' })\n  @ApiResponse({\n    status: HttpStatus.OK,\n    description: 'Webhook message sent successfully',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @Audit({\n    action: AuditAction.SEND_WEBHOOK_MESSAGE,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n    requestMetadata: {\n      body: (req: TypedRequest<SendWebhookDto>) => ({\n        eventType: req.body?.eventType,\n        payload: req.body?.payload,\n        eventId: req.body?.eventId,\n      }),\n    },\n  })\n  async sendWebhook(\n    @Param('organizationId') organizationId: string,\n    @Body() sendWebhookDto: SendWebhookDto,\n  ): Promise<void> {\n    await this.webhookService.sendWebhook(\n      organizationId,\n      sendWebhookDto.eventType,\n      sendWebhookDto.payload,\n      sendWebhookDto.eventId,\n    )\n  }\n\n  @Get('organizations/:organizationId/messages/:messageId/attempts')\n  @ApiOperation({ summary: 'Get delivery attempts for a webhook message' })\n  @ApiResponse({\n    status: HttpStatus.OK,\n    description: 'List of delivery attempts',\n    type: [Object],\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  async getMessageAttempts(\n    @Param('organizationId') organizationId: string,\n    @Param('messageId') messageId: string,\n  ): Promise<any[]> {\n    return this.webhookService.getMessageAttempts(organizationId, messageId)\n  }\n\n  @Get('status')\n  @ApiOperation({ summary: 'Get webhook service status' })\n  @ApiResponse({\n    status: HttpStatus.OK,\n    description: 'Webhook service status',\n    schema: {\n      type: 'object',\n      properties: {\n        enabled: { type: 'boolean' },\n      },\n    },\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  async getStatus(): Promise<{ enabled: boolean }> {\n    return {\n      enabled: this.webhookService.isEnabled(),\n    }\n  }\n\n  @Get('organizations/:organizationId/initialization-status')\n  @ApiOperation({ summary: 'Get webhook initialization status for an organization' })\n  @ApiResponse({\n    status: HttpStatus.OK,\n    description: 'Webhook initialization status',\n    type: WebhookInitializationStatusDto,\n  })\n  @ApiResponse({\n    status: HttpStatus.NOT_FOUND,\n    description: 'Webhook initialization status not found',\n  })\n  async getInitializationStatus(\n    @Param('organizationId') organizationId: string,\n  ): Promise<WebhookInitializationStatusDto> {\n    const status = await this.webhookService.getInitializationStatus(organizationId)\n    if (!status) {\n      throw new NotFoundException('Webhook initialization status not found')\n    }\n    return WebhookInitializationStatusDto.fromWebhookInitialization(status)\n  }\n\n  @Post('organizations/:organizationId/initialize')\n  @ApiOperation({ summary: 'Initialize webhooks for an organization' })\n  @ApiResponse({\n    status: HttpStatus.CREATED,\n    description: 'Webhooks initialized successfully',\n  })\n  @ApiResponse({\n    status: HttpStatus.FORBIDDEN,\n    description: 'User does not have access to this organization',\n  })\n  @ApiResponse({\n    status: HttpStatus.NOT_FOUND,\n    description: 'Organization not found',\n  })\n  @RequiredSystemRole(SystemRole.ADMIN)\n  @Audit({\n    action: AuditAction.INITIALIZE_WEBHOOKS,\n    targetType: AuditTarget.ORGANIZATION,\n    targetIdFromRequest: (req) => req.params.organizationId,\n  })\n  async initializeWebhooks(@Param('organizationId') organizationId: string): Promise<void> {\n    const organization = await this.organizationService.findOne(organizationId)\n    if (!organization) {\n      throw new NotFoundException('Organization not found')\n    }\n\n    await this.webhookService.createSvixApplication(organization)\n  }\n}\n"
  },
  {
    "path": "apps/api/src/webhook/dto/send-webhook.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { IsString, IsObject, IsOptional, IsEnum } from 'class-validator'\nimport { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'\nimport { WebhookEvent } from '../constants/webhook-events.constants'\n\nexport class SendWebhookDto {\n  @ApiProperty({\n    description: 'The type of event being sent',\n    enum: WebhookEvent,\n    enumName: 'WebhookEvent',\n    example: 'sandbox.created',\n  })\n  @IsEnum(WebhookEvent)\n  eventType: WebhookEvent\n\n  @ApiProperty({\n    description: 'The payload data to send',\n    example: { id: 'sandbox-123', name: 'My Sandbox' },\n  })\n  @IsObject()\n  payload: Record<string, any>\n\n  @ApiPropertyOptional({\n    description: 'Optional event ID for idempotency',\n    example: 'evt_1234567890abcdef',\n  })\n  @IsOptional()\n  @IsString()\n  eventId?: string\n}\n"
  },
  {
    "path": "apps/api/src/webhook/dto/webhook-app-portal-access.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\n\n@ApiSchema({ name: 'WebhookAppPortalAccess' })\nexport class WebhookAppPortalAccessDto {\n  @ApiProperty({\n    description: 'The authentication token for the Svix consumer app portal',\n    example: 'appsk_...',\n  })\n  token: string\n\n  @ApiProperty({\n    description: 'The URL to the webhook app portal',\n    example: 'https://app.svix.com/app_1234567890',\n  })\n  url: string\n}\n"
  },
  {
    "path": "apps/api/src/webhook/dto/webhook-event-payloads.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { WebhookEvent } from '../constants/webhook-events.constants'\nimport { SandboxState } from '../../sandbox/enums/sandbox-state.enum'\nimport { SandboxClass } from '../../sandbox/enums/sandbox-class.enum'\nimport { SnapshotState } from '../../sandbox/enums/snapshot-state.enum'\nimport { VolumeState } from '../../sandbox/enums/volume-state.enum'\nimport { SandboxCreatedEvent } from '../../sandbox/events/sandbox-create.event'\nimport { SandboxStateUpdatedEvent } from '../../sandbox/events/sandbox-state-updated.event'\nimport { SnapshotCreatedEvent } from '../../sandbox/events/snapshot-created.event'\nimport { SnapshotStateUpdatedEvent } from '../../sandbox/events/snapshot-state-updated.event'\nimport { SnapshotRemovedEvent } from '../../sandbox/events/snapshot-removed.event'\nimport { VolumeCreatedEvent } from '../../sandbox/events/volume-created.event'\nimport { VolumeStateUpdatedEvent } from '../../sandbox/events/volume-state-updated.event'\n\nexport abstract class BaseWebhookEventDto {\n  @ApiProperty({\n    description: 'Event type identifier',\n    enum: WebhookEvent,\n    enumName: 'WebhookEvent',\n    example: 'sandbox.created',\n  })\n  event: string\n\n  @ApiProperty({\n    description: 'Timestamp when the event occurred',\n    example: '2025-12-19T10:30:00.000Z',\n    format: 'date-time',\n  })\n  timestamp: string\n}\n\n@ApiSchema({ name: 'SandboxCreatedWebhook' })\nexport class SandboxCreatedWebhookDto extends BaseWebhookEventDto {\n  @ApiProperty({\n    description: 'Sandbox ID',\n    example: 'sandbox123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: 'org123',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'Sandbox state',\n    enum: SandboxState,\n    enumName: 'SandboxState',\n  })\n  state: SandboxState\n\n  @ApiProperty({\n    description: 'Sandbox class',\n    enum: SandboxClass,\n    enumName: 'SandboxClass',\n  })\n  class: SandboxClass\n\n  @ApiProperty({\n    description: 'When the sandbox was created',\n    example: '2025-12-19T10:30:00.000Z',\n    format: 'date-time',\n  })\n  createdAt: string\n\n  static fromEvent(event: SandboxCreatedEvent, eventType: string): SandboxCreatedWebhookDto {\n    return {\n      event: eventType,\n      timestamp: new Date().toISOString(),\n      id: event.sandbox.id,\n      organizationId: event.sandbox.organizationId,\n      state: event.sandbox.state,\n      class: event.sandbox.class,\n      createdAt: event.sandbox.createdAt.toISOString(),\n    }\n  }\n}\n\n@ApiSchema({ name: 'SandboxStateUpdatedWebhook' })\nexport class SandboxStateUpdatedWebhookDto extends BaseWebhookEventDto {\n  @ApiProperty({\n    description: 'Sandbox ID',\n    example: 'sandbox123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: 'org123',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'Previous state',\n    enum: SandboxState,\n    enumName: 'SandboxState',\n  })\n  oldState: SandboxState\n\n  @ApiProperty({\n    description: 'New state',\n    enum: SandboxState,\n    enumName: 'SandboxState',\n  })\n  newState: SandboxState\n\n  @ApiProperty({\n    description: 'When the sandbox was last updated',\n    example: '2025-12-19T10:30:00.000Z',\n    format: 'date-time',\n  })\n  updatedAt: string\n\n  static fromEvent(event: SandboxStateUpdatedEvent, eventType: string): SandboxStateUpdatedWebhookDto {\n    return {\n      event: eventType,\n      timestamp: new Date().toISOString(),\n      id: event.sandbox.id,\n      organizationId: event.sandbox.organizationId,\n      oldState: event.oldState,\n      newState: event.newState,\n      updatedAt: event.sandbox.updatedAt.toISOString(),\n    }\n  }\n}\n\n@ApiSchema({ name: 'SnapshotCreatedWebhook' })\nexport class SnapshotCreatedWebhookDto extends BaseWebhookEventDto {\n  @ApiProperty({\n    description: 'Snapshot ID',\n    example: 'snapshot123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Snapshot name',\n    example: 'my-snapshot',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: 'org123',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'Snapshot state',\n    enum: SnapshotState,\n    enumName: 'SnapshotState',\n  })\n  state: SnapshotState\n\n  @ApiProperty({\n    description: 'When the snapshot was created',\n    example: '2025-12-19T10:30:00.000Z',\n    format: 'date-time',\n  })\n  createdAt: string\n\n  static fromEvent(event: SnapshotCreatedEvent, eventType: string): SnapshotCreatedWebhookDto {\n    return {\n      event: eventType,\n      timestamp: new Date().toISOString(),\n      id: event.snapshot.id,\n      name: event.snapshot.name,\n      organizationId: event.snapshot.organizationId,\n      state: event.snapshot.state,\n      createdAt: event.snapshot.createdAt.toISOString(),\n    }\n  }\n}\n\n@ApiSchema({ name: 'SnapshotStateUpdatedWebhook' })\nexport class SnapshotStateUpdatedWebhookDto extends BaseWebhookEventDto {\n  @ApiProperty({\n    description: 'Snapshot ID',\n    example: 'snapshot123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Snapshot name',\n    example: 'my-snapshot',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: 'org123',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'Previous state',\n    enum: SnapshotState,\n    enumName: 'SnapshotState',\n  })\n  oldState: SnapshotState\n\n  @ApiProperty({\n    description: 'New state',\n    enum: SnapshotState,\n    enumName: 'SnapshotState',\n  })\n  newState: SnapshotState\n\n  @ApiProperty({\n    description: 'When the snapshot was last updated',\n    example: '2025-12-19T10:30:00.000Z',\n    format: 'date-time',\n  })\n  updatedAt: string\n\n  static fromEvent(event: SnapshotStateUpdatedEvent, eventType: string): SnapshotStateUpdatedWebhookDto {\n    return {\n      event: eventType,\n      timestamp: new Date().toISOString(),\n      id: event.snapshot.id,\n      name: event.snapshot.name,\n      organizationId: event.snapshot.organizationId,\n      oldState: event.oldState,\n      newState: event.newState,\n      updatedAt: event.snapshot.updatedAt.toISOString(),\n    }\n  }\n}\n\n@ApiSchema({ name: 'SnapshotRemovedWebhook' })\nexport class SnapshotRemovedWebhookDto extends BaseWebhookEventDto {\n  @ApiProperty({\n    description: 'Snapshot ID',\n    example: 'snapshot123',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Snapshot name',\n    example: 'my-snapshot',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: 'org123',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'When the snapshot was removed',\n    example: '2025-12-19T10:30:00.000Z',\n    format: 'date-time',\n  })\n  removedAt: string\n\n  static fromEvent(event: SnapshotRemovedEvent, eventType: string): SnapshotRemovedWebhookDto {\n    return {\n      event: eventType,\n      timestamp: new Date().toISOString(),\n      id: event.snapshot.id,\n      name: event.snapshot.name,\n      organizationId: event.snapshot.organizationId,\n      removedAt: new Date().toISOString(),\n    }\n  }\n}\n\n@ApiSchema({ name: 'VolumeCreatedWebhook' })\nexport class VolumeCreatedWebhookDto extends BaseWebhookEventDto {\n  @ApiProperty({\n    description: 'Volume ID',\n    example: 'vol-12345678',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Volume name',\n    example: 'my-volume',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: 'org123',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'Volume state',\n    enum: VolumeState,\n    enumName: 'VolumeState',\n  })\n  state: VolumeState\n\n  @ApiProperty({\n    description: 'When the volume was created',\n    example: '2025-12-19T10:30:00.000Z',\n    format: 'date-time',\n  })\n  createdAt: string\n\n  static fromEvent(event: VolumeCreatedEvent, eventType: string): VolumeCreatedWebhookDto {\n    return {\n      event: eventType,\n      timestamp: new Date().toISOString(),\n      id: event.volume.id,\n      name: event.volume.name,\n      organizationId: event.volume.organizationId,\n      state: event.volume.state,\n      createdAt: event.volume.createdAt.toISOString(),\n    }\n  }\n}\n\n@ApiSchema({ name: 'VolumeStateUpdatedWebhook' })\nexport class VolumeStateUpdatedWebhookDto extends BaseWebhookEventDto {\n  @ApiProperty({\n    description: 'Volume ID',\n    example: 'vol-12345678',\n  })\n  id: string\n\n  @ApiProperty({\n    description: 'Volume name',\n    example: 'my-volume',\n  })\n  name: string\n\n  @ApiProperty({\n    description: 'Organization ID',\n    example: 'org123',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'Previous state',\n    enum: VolumeState,\n    enumName: 'VolumeState',\n  })\n  oldState: VolumeState\n\n  @ApiProperty({\n    description: 'New state',\n    enum: VolumeState,\n    enumName: 'VolumeState',\n  })\n  newState: VolumeState\n\n  @ApiProperty({\n    description: 'When the volume was last updated',\n    example: '2025-12-19T10:30:00.000Z',\n    format: 'date-time',\n  })\n  updatedAt: string\n\n  static fromEvent(event: VolumeStateUpdatedEvent, eventType: string): VolumeStateUpdatedWebhookDto {\n    return {\n      event: eventType,\n      timestamp: new Date().toISOString(),\n      id: event.volume.id,\n      name: event.volume.name,\n      organizationId: event.volume.organizationId,\n      oldState: event.oldState,\n      newState: event.newState,\n      updatedAt: event.volume.updatedAt.toISOString(),\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/webhook/dto/webhook-initialization-status.dto.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiProperty, ApiSchema } from '@nestjs/swagger'\nimport { WebhookInitialization } from '../entities/webhook-initialization.entity'\n\n@ApiSchema({ name: 'WebhookInitializationStatus' })\nexport class WebhookInitializationStatusDto {\n  @ApiProperty({\n    description: 'Organization ID',\n    example: '123e4567-e89b-12d3-a456-426614174000',\n  })\n  organizationId: string\n\n  @ApiProperty({\n    description: 'The ID of the Svix application',\n    example: 'app_1234567890',\n    nullable: true,\n  })\n  svixApplicationId?: string\n\n  @ApiProperty({\n    description: 'The error reason for the last initialization attempt',\n    example: 'Failed to create Svix application',\n    nullable: true,\n  })\n  lastError?: string\n\n  @ApiProperty({\n    description: 'The number of times the initialization has been attempted',\n    example: 3,\n  })\n  retryCount: number\n\n  @ApiProperty({\n    description: 'When the webhook initialization was created',\n    example: '2023-01-01T00:00:00.000Z',\n  })\n  createdAt: string\n\n  @ApiProperty({\n    description: 'When the webhook initialization was last updated',\n    example: '2023-01-01T00:00:00.000Z',\n  })\n  updatedAt: string\n\n  static fromWebhookInitialization(webhookInitialization: WebhookInitialization): WebhookInitializationStatusDto {\n    return {\n      organizationId: webhookInitialization.organizationId,\n      svixApplicationId: webhookInitialization.svixApplicationId,\n      lastError: webhookInitialization.lastError,\n      retryCount: webhookInitialization.retryCount,\n      createdAt: webhookInitialization.createdAt.toISOString(),\n      updatedAt: webhookInitialization.updatedAt.toISOString(),\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/webhook/entities/webhook-initialization.entity.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Entity, PrimaryColumn, CreateDateColumn, UpdateDateColumn, Column } from 'typeorm'\n\n@Entity()\nexport class WebhookInitialization {\n  @PrimaryColumn()\n  organizationId: string\n\n  @Column({\n    nullable: true,\n  })\n  svixApplicationId?: string\n\n  @Column({\n    type: 'text',\n    nullable: true,\n  })\n  lastError?: string\n\n  @Column({\n    type: 'int',\n    default: 0,\n  })\n  retryCount: number\n\n  @CreateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  createdAt: Date\n\n  @UpdateDateColumn({\n    type: 'timestamp with time zone',\n  })\n  updatedAt: Date\n}\n"
  },
  {
    "path": "apps/api/src/webhook/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport * from './webhook.module'\nexport * from './services/webhook.service'\nexport * from './services/webhook-event-handler.service'\nexport * from './entities/webhook-initialization.entity'\nexport * from './controllers/webhook.controller'\nexport * from './dto/send-webhook.dto'\n"
  },
  {
    "path": "apps/api/src/webhook/services/webhook-event-handler.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger } from '@nestjs/common'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport { WebhookService } from './webhook.service'\nimport { SandboxEvents } from '../../sandbox/constants/sandbox-events.constants'\nimport { SnapshotEvents } from '../../sandbox/constants/snapshot-events'\nimport { VolumeEvents } from '../../sandbox/constants/volume-events'\nimport { SandboxCreatedEvent } from '../../sandbox/events/sandbox-create.event'\nimport { SandboxStateUpdatedEvent } from '../../sandbox/events/sandbox-state-updated.event'\nimport { SnapshotCreatedEvent } from '../../sandbox/events/snapshot-created.event'\nimport { SnapshotStateUpdatedEvent } from '../../sandbox/events/snapshot-state-updated.event'\nimport { SnapshotRemovedEvent } from '../../sandbox/events/snapshot-removed.event'\nimport { VolumeCreatedEvent } from '../../sandbox/events/volume-created.event'\nimport { VolumeStateUpdatedEvent } from '../../sandbox/events/volume-state-updated.event'\nimport { WebhookEvent } from '../constants/webhook-events.constants'\nimport {\n  SandboxCreatedWebhookDto,\n  SandboxStateUpdatedWebhookDto,\n  SnapshotCreatedWebhookDto,\n  SnapshotStateUpdatedWebhookDto,\n  SnapshotRemovedWebhookDto,\n  VolumeCreatedWebhookDto,\n  VolumeStateUpdatedWebhookDto,\n} from '../dto/webhook-event-payloads.dto'\n\n@Injectable()\nexport class WebhookEventHandlerService {\n  private readonly logger = new Logger(WebhookEventHandlerService.name)\n\n  constructor(private readonly webhookService: WebhookService) {}\n\n  @OnEvent(SandboxEvents.CREATED)\n  async handleSandboxCreated(event: SandboxCreatedEvent) {\n    if (!this.webhookService.isEnabled()) {\n      return\n    }\n\n    try {\n      const payload = SandboxCreatedWebhookDto.fromEvent(event, WebhookEvent.SANDBOX_CREATED)\n      await this.webhookService.sendWebhook(event.sandbox.organizationId, WebhookEvent.SANDBOX_CREATED, payload)\n    } catch (error) {\n      this.logger.error(`Failed to send webhook for sandbox created: ${error.message}`)\n    }\n  }\n\n  @OnEvent(SandboxEvents.STATE_UPDATED)\n  async handleSandboxStateUpdated(event: SandboxStateUpdatedEvent) {\n    if (!this.webhookService.isEnabled()) {\n      return\n    }\n\n    try {\n      const payload = SandboxStateUpdatedWebhookDto.fromEvent(event, WebhookEvent.SANDBOX_STATE_UPDATED)\n      await this.webhookService.sendWebhook(event.sandbox.organizationId, WebhookEvent.SANDBOX_STATE_UPDATED, payload)\n    } catch (error) {\n      this.logger.error(`Failed to send webhook for sandbox state updated: ${error.message}`)\n    }\n  }\n\n  @OnEvent(SnapshotEvents.CREATED)\n  async handleSnapshotCreated(event: SnapshotCreatedEvent) {\n    if (!this.webhookService.isEnabled()) {\n      return\n    }\n\n    try {\n      const payload = SnapshotCreatedWebhookDto.fromEvent(event, WebhookEvent.SNAPSHOT_CREATED)\n      await this.webhookService.sendWebhook(event.snapshot.organizationId, WebhookEvent.SNAPSHOT_CREATED, payload)\n    } catch (error) {\n      this.logger.error(`Failed to send webhook for snapshot created: ${error.message}`)\n    }\n  }\n\n  @OnEvent(SnapshotEvents.STATE_UPDATED)\n  async handleSnapshotStateUpdated(event: SnapshotStateUpdatedEvent) {\n    if (!this.webhookService.isEnabled()) {\n      return\n    }\n\n    try {\n      const payload = SnapshotStateUpdatedWebhookDto.fromEvent(event, WebhookEvent.SNAPSHOT_STATE_UPDATED)\n      await this.webhookService.sendWebhook(event.snapshot.organizationId, WebhookEvent.SNAPSHOT_STATE_UPDATED, payload)\n    } catch (error) {\n      this.logger.error(`Failed to send webhook for snapshot state updated: ${error.message}`)\n    }\n  }\n\n  @OnEvent(SnapshotEvents.REMOVED)\n  async handleSnapshotRemoved(event: SnapshotRemovedEvent) {\n    if (!this.webhookService.isEnabled()) {\n      return\n    }\n\n    try {\n      const payload = SnapshotRemovedWebhookDto.fromEvent(event, WebhookEvent.SNAPSHOT_REMOVED)\n      await this.webhookService.sendWebhook(event.snapshot.organizationId, WebhookEvent.SNAPSHOT_REMOVED, payload)\n    } catch (error) {\n      this.logger.error(`Failed to send webhook for snapshot removed: ${error.message}`)\n    }\n  }\n\n  @OnEvent(VolumeEvents.CREATED)\n  async handleVolumeCreated(event: VolumeCreatedEvent) {\n    if (!this.webhookService.isEnabled()) {\n      return\n    }\n\n    try {\n      const payload = VolumeCreatedWebhookDto.fromEvent(event, WebhookEvent.VOLUME_CREATED)\n      await this.webhookService.sendWebhook(event.volume.organizationId, WebhookEvent.VOLUME_CREATED, payload)\n    } catch (error) {\n      this.logger.error(`Failed to send webhook for volume created: ${error.message}`)\n    }\n  }\n\n  @OnEvent(VolumeEvents.STATE_UPDATED)\n  async handleVolumeStateUpdated(event: VolumeStateUpdatedEvent) {\n    if (!this.webhookService.isEnabled()) {\n      return\n    }\n\n    try {\n      const payload = VolumeStateUpdatedWebhookDto.fromEvent(event, WebhookEvent.VOLUME_STATE_UPDATED)\n      await this.webhookService.sendWebhook(event.volume.organizationId, WebhookEvent.VOLUME_STATE_UPDATED, payload)\n    } catch (error) {\n      this.logger.error(`Failed to send webhook for volume state updated: ${error.message}`)\n    }\n  }\n\n  /**\n   * Send a custom webhook event\n   */\n  async sendCustomWebhook(organizationId: string, eventType: string, payload: any, eventId?: string): Promise<void> {\n    if (!this.webhookService.isEnabled()) {\n      return\n    }\n\n    try {\n      await this.webhookService.sendWebhook(organizationId, eventType, payload, eventId)\n    } catch (error) {\n      this.logger.error(`Failed to send custom webhook: ${error.message}`)\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/webhook/services/webhook.service.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Injectable, Logger, OnModuleInit } from '@nestjs/common'\nimport { OnEvent } from '@nestjs/event-emitter'\nimport { TypedConfigService } from '../../config/typed-config.service'\nimport { Svix } from 'svix'\nimport { OrganizationEvents } from '../../organization/constants/organization-events.constant'\nimport { Organization } from '../../organization/entities/organization.entity'\nimport { InjectRepository } from '@nestjs/typeorm'\nimport { WebhookInitialization } from '../entities/webhook-initialization.entity'\nimport { Repository } from 'typeorm'\n\n@Injectable()\nexport class WebhookService implements OnModuleInit {\n  private readonly logger = new Logger(WebhookService.name)\n  private svix: Svix | null = null\n\n  constructor(\n    private readonly configService: TypedConfigService,\n    @InjectRepository(WebhookInitialization)\n    private readonly webhookInitializationRepository: Repository<WebhookInitialization>,\n  ) {}\n\n  async onModuleInit() {\n    const svixAuthToken = this.configService.get('webhook.authToken')\n    if (svixAuthToken) {\n      const serverUrl = this.configService.get('webhook.serverUrl')\n      if (serverUrl) {\n        this.svix = new Svix(svixAuthToken, { serverUrl })\n      } else {\n        this.svix = new Svix(svixAuthToken)\n        //this.svix.eventType.importOpenapi\n      }\n      this.logger.log('Svix webhook service initialized')\n    } else {\n      this.logger.warn('SVIX_AUTH_TOKEN not configured, webhook service disabled')\n    }\n  }\n\n  /**\n   * Get webhook initialization status for an organization\n   */\n  async getInitializationStatus(organizationId: string): Promise<WebhookInitialization | null> {\n    return this.webhookInitializationRepository.findOne({\n      where: { organizationId },\n    })\n  }\n\n  // TODO: Remove this once we decide to open webhooks to all organizations\n  // @OnEvent(OrganizationEvents.CREATED)\n  async handleOrganizationCreated(organization: Organization) {\n    if (!this.svix) {\n      this.logger.debug('Svix not configured, skipping webhook creation')\n      return\n    }\n\n    try {\n      // Create a new Svix application for this organization\n      const svixAppId = await this.createSvixApplication(organization)\n      this.logger.log(`Created Svix application for organization ${organization.id}: ${svixAppId}`)\n    } catch (error) {\n      this.logger.error(`Failed to create Svix application for organization ${organization.id}:`, error)\n    }\n  }\n\n  /**\n   * Create a Svix application for an organization\n   */\n  async createSvixApplication(organization: Organization): Promise<string> {\n    if (!this.svix) {\n      throw new Error('Svix not configured')\n    }\n\n    let existingWebhookInitialization = await this.getInitializationStatus(organization.id)\n    if (existingWebhookInitialization && existingWebhookInitialization.svixApplicationId) {\n      this.logger.warn(\n        `Svix application already exists for organization ${organization.id}: ${existingWebhookInitialization.svixApplicationId}`,\n      )\n      return existingWebhookInitialization.svixApplicationId\n    } else {\n      existingWebhookInitialization = new WebhookInitialization()\n      existingWebhookInitialization.organizationId = organization.id\n      existingWebhookInitialization.svixApplicationId = null\n      existingWebhookInitialization.retryCount = -1\n      existingWebhookInitialization.lastError = null\n    }\n\n    try {\n      const svixApp = await this.svix.application.getOrCreate({\n        name: organization.name,\n        uid: organization.id,\n      })\n      existingWebhookInitialization.svixApplicationId = svixApp.id\n      existingWebhookInitialization.retryCount = existingWebhookInitialization.retryCount + 1\n      existingWebhookInitialization.lastError = null\n\n      await this.webhookInitializationRepository.save(existingWebhookInitialization)\n\n      this.logger.log(`Created Svix application for organization ${organization.id}: ${svixApp.id}`)\n      return svixApp.id\n    } catch (error) {\n      existingWebhookInitialization.retryCount = existingWebhookInitialization.retryCount + 1\n      existingWebhookInitialization.lastError = String(error)\n      await this.webhookInitializationRepository.save(existingWebhookInitialization)\n      this.logger.error(`Failed to create Svix application for organization ${organization.id}:`, error)\n      throw error\n    }\n  }\n\n  /**\n   * Send a webhook message to all endpoints of an organization\n   */\n  async sendWebhook(organizationId: string, eventType: string, payload: any, eventId?: string): Promise<void> {\n    if (!this.svix) {\n      this.logger.debug('Svix not configured, skipping webhook delivery')\n      return\n    }\n\n    try {\n      // Check if webhooks are initialized for this organization\n      const isInitialized = await this.getInitializationStatus(organizationId)\n\n      if (!isInitialized) {\n        this.logger.log(`Webhooks not initialized for organization ${organizationId}, creating Svix application now...`)\n        // For now, we'll just log that initialization is needed\n        // The actual initialization should be done through the API or event handler\n        this.logger.warn(\n          `Organization ${organizationId} needs webhook initialization. Please use the initialization API endpoint.`,\n        )\n        return\n      }\n\n      // Send the webhook message\n      await this.svix.message.create(organizationId, {\n        eventType,\n        payload,\n        eventId,\n      })\n\n      this.logger.debug(`Sent webhook ${eventType} to organization ${organizationId}`)\n    } catch (error) {\n      this.logger.error(`Failed to send webhook ${eventType} to organization ${organizationId}:`, error)\n      throw error\n    }\n  }\n\n  /**\n   * Get webhook delivery attempts for a message\n   */\n  async getMessageAttempts(organizationId: string, messageId: string): Promise<any[]> {\n    if (!this.svix) {\n      throw new Error('Svix not configured')\n    }\n\n    try {\n      const attempts = await this.svix.messageAttempt.listByMsg(organizationId, messageId)\n      return attempts.data\n    } catch (error) {\n      this.logger.error(`Failed to get message attempts for message ${messageId}:`, error)\n      throw error\n    }\n  }\n\n  /**\n   * Check if webhook service is enabled\n   */\n  isEnabled(): boolean {\n    return this.svix !== null\n  }\n\n  /**\n   * Get Svix Consumer App Portal access for an organization\n   */\n  async getAppPortalAccess(organizationId: string): Promise<{ token: string; url: string }> {\n    if (!this.svix) {\n      throw new Error('Svix not configured')\n    }\n    try {\n      const appPortalAccess = await this.svix.authentication.appPortalAccess(organizationId, {})\n      this.logger.debug(`Generated app portal access for organization ${organizationId}`)\n      return {\n        token: appPortalAccess.token,\n        url: appPortalAccess.url,\n      }\n    } catch (error) {\n      this.logger.debug(`Failed to generate app portal access for organization ${organizationId}:`, error)\n      throw error\n    }\n  }\n}\n"
  },
  {
    "path": "apps/api/src/webhook/webhook.module.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Module } from '@nestjs/common'\nimport { TypeOrmModule } from '@nestjs/typeorm'\nimport { WebhookService } from './services/webhook.service'\nimport { WebhookController } from './controllers/webhook.controller'\nimport { WebhookEventHandlerService } from './services/webhook-event-handler.service'\nimport { WebhookInitialization } from './entities/webhook-initialization.entity'\nimport { OrganizationModule } from '../organization/organization.module'\nimport { TypedConfigModule } from '../config/typed-config.module'\nimport { AuthModule } from '../auth/auth.module'\n\n@Module({\n  imports: [OrganizationModule, TypedConfigModule, TypeOrmModule.forFeature([WebhookInitialization]), AuthModule],\n  controllers: [WebhookController],\n  providers: [WebhookService, WebhookEventHandlerService],\n  exports: [WebhookService],\n})\nexport class WebhookModule {}\n"
  },
  {
    "path": "apps/api/tsconfig.app.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../../dist/out-tsc\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"nodenext\",\n    \"types\": [\"node\"],\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n    \"target\": \"es2022\"\n  },\n  \"include\": [\"src/**/*.ts\"],\n  \"exclude\": [\"jest.config.ts\", \"src/**/*.spec.ts\", \"src/**/*.test.ts\"]\n}\n"
  },
  {
    "path": "apps/api/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"files\": [],\n  \"include\": [],\n  \"references\": [\n    {\n      \"path\": \"./tsconfig.app.json\"\n    },\n    {\n      \"path\": \"./tsconfig.spec.json\"\n    }\n  ],\n  \"compilerOptions\": {\n    \"esModuleInterop\": true\n  }\n}\n"
  },
  {
    "path": "apps/api/tsconfig.spec.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../../dist/out-tsc\",\n    \"module\": \"commonjs\",\n    \"moduleResolution\": \"node10\",\n    \"types\": [\"jest\", \"node\"]\n  },\n  \"include\": [\"jest.config.ts\", \"src/**/*.test.ts\", \"src/**/*.spec.ts\", \"src/**/*.d.ts\"]\n}\n"
  },
  {
    "path": "apps/api/webpack.config.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nconst { composePlugins, withNx } = require('@nx/webpack')\nconst path = require('path')\nconst glob = require('glob')\n\nconst migrationFiles = glob.sync('apps/api/src/migrations/**/*-migration.{ts,js}')\nconst migrationEntries = migrationFiles.reduce((acc, migrationFile) => {\n  const entryName = migrationFile.substring(migrationFile.lastIndexOf('/') + 1, migrationFile.lastIndexOf('.'))\n  acc[entryName] = migrationFile\n  return acc\n}, {})\n\nmodule.exports = composePlugins(\n  // Default Nx composable plugin\n  withNx(),\n  // Custom composable plugin\n  (config, { options, context }) => {\n    // `config` is the Webpack configuration object\n    // `options` is the options passed to the `@nx/webpack:webpack` executor\n    // `context` is the context passed to the `@nx/webpack:webpack` executor\n    // customize configuration here\n    config.output.devtoolModuleFilenameTemplate = function (info) {\n      const rel = path.relative(process.cwd(), info.absoluteResourcePath)\n      return `webpack:///./${rel}`\n    }\n    // Preserve openapi files while cleaning other build artifacts\n    config.output.clean = {\n      keep: /openapi.*\\.json$/,\n    }\n    // add typeorm migrations as entry points\n    for (const key in migrationEntries) {\n      config.entry[`migrations/${key}`] = migrationEntries[key]\n    }\n    config.mode = process.env.NODE_ENV\n    return config\n  },\n)\n"
  },
  {
    "path": "apps/cli/apiclient/api_client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage apiclient\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/daytonaio/daytona/cli/auth\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype versionCheckTransport struct {\n\ttransport http.RoundTripper\n}\n\nvar versionMismatchWarningOnce sync.Once\n\nfunc (t *versionCheckTransport) RoundTrip(req *http.Request) (*http.Response, error) {\n\tresp, err := t.transport.RoundTrip(req)\n\tif resp != nil {\n\t\t// Check version mismatch on all responses, not just errors\n\t\tcheckVersionsMismatch(resp)\n\t}\n\treturn resp, err\n}\n\nvar apiClient *apiclient.APIClient\n\nconst DaytonaSourceHeader = \"X-Daytona-Source\"\nconst API_VERSION_HEADER = \"X-Daytona-Api-Version\"\n\nfunc checkVersionsMismatch(res *http.Response) {\n\t// If the CLI is running in a structured output mode (e.g. json/yaml),\n\t// avoid printing human-readable warnings that could break consumers.\n\tif internal.SuppressVersionMismatchWarning {\n\t\treturn\n\t}\n\n\tserverVersion := res.Header.Get(API_VERSION_HEADER)\n\tif serverVersion == \"\" {\n\t\treturn\n\t}\n\n\t// Trim \"v\" prefix from both versions for comparison\n\tcliVersion := strings.TrimPrefix(internal.Version, \"v\")\n\tapiVersion := strings.TrimPrefix(serverVersion, \"v\")\n\n\tif cliVersion == \"0.0.0-dev\" || cliVersion == apiVersion {\n\t\treturn\n\t}\n\n\tif compareVersions(cliVersion, apiVersion) >= 0 {\n\t\treturn\n\t}\n\n\tversionMismatchWarningOnce.Do(func() {\n\t\tlog.Warn(fmt.Sprintf(\"Version mismatch: Daytona CLI is on v%s and API is on v%s.\\nMake sure the versions are aligned using 'brew upgrade daytonaio/cli/daytona' or by downloading the latest version from https://github.com/daytonaio/daytona/releases.\", cliVersion, apiVersion))\n\t})\n}\n\n// compareVersions compares two semver strings\n// Returns: -1 if v1 < v2, 0 if v1 == v2, 1 if v1 > v2\nfunc compareVersions(v1, v2 string) int {\n\tparts1 := strings.Split(v1, \".\")\n\tparts2 := strings.Split(v2, \".\")\n\n\tmaxLen := len(parts1)\n\tif len(parts2) > maxLen {\n\t\tmaxLen = len(parts2)\n\t}\n\n\tfor i := 0; i < maxLen; i++ {\n\t\tvar n1, n2 int\n\t\tif i < len(parts1) {\n\t\t\t_, _ = fmt.Sscanf(parts1[i], \"%d\", &n1)\n\t\t}\n\t\tif i < len(parts2) {\n\t\t\t_, _ = fmt.Sscanf(parts2[i], \"%d\", &n2)\n\t\t}\n\n\t\tif n1 < n2 {\n\t\t\treturn -1\n\t\t}\n\t\tif n1 > n2 {\n\t\t\treturn 1\n\t\t}\n\t}\n\n\treturn 0\n}\n\nfunc GetApiClient(profile *config.Profile, defaultHeaders map[string]string) (*apiclient.APIClient, error) {\n\tc, err := config.GetConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar activeProfile config.Profile\n\tif profile == nil {\n\t\tvar err error\n\t\tactiveProfile, err = c.GetActiveProfile()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tactiveProfile = *profile\n\t}\n\n\tif apiClient != nil && activeProfile.Api.Key == nil {\n\t\terr := auth.RefreshTokenIfNeeded(context.Background())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn apiClient, nil\n\t}\n\n\tvar newApiClient *apiclient.APIClient\n\n\tserverUrl := activeProfile.Api.Url\n\n\tclientConfig := apiclient.NewConfiguration()\n\tclientConfig.Servers = apiclient.ServerConfigurations{\n\t\t{\n\t\t\tURL: serverUrl,\n\t\t},\n\t}\n\n\tif activeProfile.Api.Key != nil {\n\t\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+*activeProfile.Api.Key)\n\t} else if activeProfile.Api.Token != nil {\n\t\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+activeProfile.Api.Token.AccessToken)\n\n\t\tif activeProfile.ActiveOrganizationId != nil {\n\t\t\tclientConfig.AddDefaultHeader(\"X-Daytona-Organization-ID\", *activeProfile.ActiveOrganizationId)\n\t\t}\n\t}\n\n\tclientConfig.AddDefaultHeader(DaytonaSourceHeader, \"cli\")\n\n\tfor headerKey, headerValue := range defaultHeaders {\n\t\tclientConfig.AddDefaultHeader(headerKey, headerValue)\n\t}\n\n\tnewApiClient = apiclient.NewAPIClient(clientConfig)\n\n\tnewApiClient.GetConfig().HTTPClient = &http.Client{\n\t\tTransport: &versionCheckTransport{\n\t\t\ttransport: http.DefaultTransport,\n\t\t},\n\t}\n\n\tif apiClient != nil && activeProfile.Api.Key == nil {\n\t\terr = auth.RefreshTokenIfNeeded(context.Background())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tapiClient = newApiClient\n\treturn apiClient, nil\n}\n"
  },
  {
    "path": "apps/cli/apiclient/error_handler.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\ntype ApiErrorResponse struct {\n\tError   string `json:\"error\"`\n\tMessage any    `json:\"message,omitempty\"`\n}\n\nfunc HandleErrorResponse(res *http.Response, requestErr error) error {\n\tif res == nil {\n\t\treturn requestErr\n\t}\n\n\tdefer res.Body.Close()\n\n\tbody, err := io.ReadAll(res.Body)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar errResponse ApiErrorResponse\n\terr = json.Unmarshal(body, &errResponse)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terrMessage := string(errResponse.Error)\n\tif errMessage == \"\" {\n\t\t// Fall back to raw body if error field is empty\n\t\terrMessage = string(body)\n\t} else {\n\t\tif errResponse.Message != nil {\n\t\t\t// Message field could be a string or an array\n\t\t\tswitch msg := errResponse.Message.(type) {\n\t\t\tcase string:\n\t\t\t\terrMessage += \": \" + msg\n\t\t\tcase []any:\n\t\t\t\tif len(msg) > 0 {\n\t\t\t\t\tmsgStr := fmt.Sprintf(\"%v\", msg)\n\t\t\t\t\terrMessage += \": \" + msgStr\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif res.StatusCode == http.StatusUnauthorized {\n\t\terrMessage += \" - run 'daytona login' to reauthenticate\"\n\t}\n\n\treturn errors.New(errMessage)\n}\n"
  },
  {
    "path": "apps/cli/auth/auth.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage auth\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t_ \"embed\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/coreos/go-oidc/v3/oidc\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/oauth2\"\n)\n\n//go:embed auth_success.html\nvar successHTML []byte\n\nfunc StartCallbackServer(expectedState string) (string, error) {\n\tvar code string\n\tvar err error\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\n\tserver := &http.Server{Addr: fmt.Sprintf(\":%s\", config.GetAuth0CallbackPort())}\n\n\thttp.HandleFunc(\"/callback\", func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.URL.Query().Get(\"state\") != expectedState {\n\t\t\terr = fmt.Errorf(\"invalid state parameter\")\n\t\t\thttp.Error(w, \"State invalid\", http.StatusBadRequest)\n\t\t\twg.Done()\n\t\t\treturn\n\t\t}\n\n\t\tcode = r.URL.Query().Get(\"code\")\n\t\tif code == \"\" {\n\t\t\terr = fmt.Errorf(\"no code in callback\")\n\t\t\thttp.Error(w, \"No code\", http.StatusBadRequest)\n\t\t\twg.Done()\n\t\t\treturn\n\t\t}\n\n\t\tw.Header().Set(\"Content-Type\", \"text/html\")\n\t\t_, _ = w.Write(successHTML)\n\n\t\t// Delay server close to ensure browser receives the success page\n\t\tgo func() {\n\t\t\ttime.Sleep(500 * time.Millisecond)\n\t\t\twg.Done()\n\t\t\tserver.Close()\n\t\t}()\n\t})\n\n\tgo func() {\n\t\tif err := server.ListenAndServe(); err != http.ErrServerClosed {\n\t\t\tlog.Errorf(\"HTTP server error: %v\", err)\n\t\t}\n\t}()\n\twg.Wait()\n\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn code, nil\n}\n\nfunc GenerateRandomState() (string, error) {\n\tb := make([]byte, 32)\n\t_, err := rand.Read(b)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn base64.URLEncoding.EncodeToString(b), nil\n}\n\nfunc RefreshTokenIfNeeded(ctx context.Context) error {\n\tc, err := config.GetConfig()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tactiveProfile, err := c.GetActiveProfile()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif activeProfile.Api.Key != nil {\n\t\treturn nil\n\t}\n\n\tif activeProfile.Api.Token == nil {\n\t\treturn fmt.Errorf(\"no valid token found, use 'daytona login' to reauthenticate\")\n\t}\n\n\t// Check if token is about to expire (within 5 minutes)\n\tif time.Until(activeProfile.Api.Token.ExpiresAt) > 5*time.Minute {\n\t\treturn nil\n\t}\n\n\tprovider, err := oidc.NewProvider(ctx, config.GetAuth0Domain())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to initialize OIDC provider: %w\", err)\n\t}\n\n\toauth2Config := oauth2.Config{\n\t\tClientID:     config.GetAuth0ClientId(),\n\t\tClientSecret: config.GetAuth0ClientSecret(),\n\t\tRedirectURL:  fmt.Sprintf(\"http://localhost:%s/callback\", config.GetAuth0CallbackPort()),\n\t\tEndpoint:     provider.Endpoint(),\n\t\tScopes:       []string{oidc.ScopeOpenID, oidc.ScopeOfflineAccess, \"profile\"},\n\t}\n\n\ttoken := &oauth2.Token{\n\t\tRefreshToken: activeProfile.Api.Token.RefreshToken,\n\t}\n\n\tnewToken, err := oauth2Config.TokenSource(ctx, token).Token()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"use 'daytona login' to reauthenticate: %w\", err)\n\t}\n\n\tactiveProfile.Api.Token = &config.Token{\n\t\tAccessToken:  newToken.AccessToken,\n\t\tRefreshToken: newToken.RefreshToken,\n\t\tExpiresAt:    newToken.Expiry,\n\t}\n\n\treturn c.EditProfile(activeProfile)\n}\n"
  },
  {
    "path": "apps/cli/auth/auth_success.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <title>Daytona</title>\n    <link rel=\"icon\" href=\"https://www.daytona.io/favicon.ico\" />\n    <style>\n      body {\n        font-family:\n          Berkeley Mono,\n          monospace;\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        height: 100vh;\n        margin: 0;\n        background-color: #f5f5f5;\n      }\n\n      .container {\n        text-align: center;\n        padding: 2rem;\n        background: white;\n        border-radius: 8px;\n        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n      }\n\n      .logo {\n        max-width: 300px;\n        margin-top: 1rem;\n      }\n\n      h1 {\n        color: #333;\n        margin-bottom: 1rem;\n      }\n\n      p {\n        color: #666;\n        margin-bottom: 1.5rem;\n      }\n    </style>\n  </head>\n\n  <body>\n    <div class=\"container\">\n      <img\n        src=\"https://raw.githubusercontent.com/daytonaio/daytona/main/assets/images/Daytona-logotype-black.png\"\n        alt=\"Daytona\"\n        class=\"logo\"\n      />\n      <h1>Authentication Successful</h1>\n      <p>You can now close this window and return to the CLI.</p>\n    </div>\n\n    <script>\n      // Function to close the page after 10 seconds\n      setTimeout(function () {\n        window.close()\n      }, 10 * 1000)\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "apps/cli/cmd/auth/login.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage auth\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/coreos/go-oidc/v3/oidc\"\n\t\"github.com/daytonaio/daytona/cli/auth\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/pkg/browser\"\n\t\"github.com/spf13/cobra\"\n\t\"golang.org/x/oauth2\"\n)\n\nvar LoginCmd = &cobra.Command{\n\tUse:     \"login\",\n\tShort:   \"Log in to Daytona\",\n\tArgs:    cobra.NoArgs,\n\tGroupID: internal.USER_GROUP,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tif apiKeyFlag != \"\" {\n\t\t\treturn updateProfileWithLogin(nil, &apiKeyFlag)\n\t\t}\n\n\t\titems := []view_common.SelectItem{\n\t\t\t{Title: \"Login with Browser\", Desc: \"Authenticate using OAuth in your browser\"},\n\t\t\t{Title: \"Set Daytona API Key\", Desc: \"Authenticate using Daytona API key\"},\n\t\t}\n\n\t\tchoice, err := view_common.Select(\"Select Authentication Method\", items)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error running selection prompt: %w\", err)\n\t\t}\n\n\t\tif choice == \"\" {\n\t\t\treturn nil\n\t\t}\n\n\t\tvar tokenConfig *config.Token\n\t\tsetApiKey := choice == \"Set Daytona API Key\"\n\n\t\tif setApiKey {\n\t\t\t// Prompt for API key\n\t\t\tapiKey, err := view_common.PromptForInput(\"\", \"Enter your Daytona API key\", \"You can find it in the Daytona dashboard - https://app.daytona.io/dashboard\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn updateProfileWithLogin(nil, &apiKey)\n\t\t}\n\n\t\ttoken, err := login(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\ttokenConfig = &config.Token{\n\t\t\tAccessToken:  token.AccessToken,\n\t\t\tRefreshToken: token.RefreshToken,\n\t\t\tExpiresAt:    token.Expiry,\n\t\t}\n\n\t\treturn updateProfileWithLogin(tokenConfig, nil)\n\t},\n}\n\nvar (\n\tapiKeyFlag string\n)\n\nfunc init() {\n\tLoginCmd.Flags().StringVar(&apiKeyFlag, \"api-key\", \"\", \"API key to use for authentication\")\n}\n\nfunc updateProfileWithLogin(tokenConfig *config.Token, apiKey *string) error {\n\tc, err := config.GetConfig()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tactiveProfile, err := c.GetActiveProfile()\n\tif err != nil {\n\t\tif err == config.ErrNoProfilesFound {\n\t\t\tactiveProfile, err = createInitialProfile(c)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif apiKey != nil {\n\t\tactiveProfile.Api.Token = nil\n\t\tactiveProfile.Api.Key = apiKey\n\n\t\tview_common.RenderInfoMessageBold(\"Successfully set Daytona API key!\")\n\t}\n\n\tif tokenConfig != nil {\n\t\tactiveProfile.Api.Key = nil\n\t\tactiveProfile.Api.Token = tokenConfig\n\n\t\terr = c.EditProfile(activeProfile)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif activeProfile.Api.Key == nil {\n\t\t\tpersonalOrganizationId, err := common.GetPersonalOrganizationId(activeProfile)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tactiveProfile.ActiveOrganizationId = &personalOrganizationId\n\t\t}\n\t}\n\n\treturn c.EditProfile(activeProfile)\n}\n\nfunc createInitialProfile(c *config.Config) (config.Profile, error) {\n\tprofile := config.Profile{\n\t\tId:   \"initial\",\n\t\tName: \"initial\",\n\t\tApi: config.ServerApi{\n\t\t\tUrl: config.GetDaytonaApiUrl(),\n\t\t},\n\t}\n\n\tif internal.Version == \"v0.0.0-dev\" {\n\t\tprofile.Api.Url = \"http://localhost:3001/api\"\n\t}\n\n\treturn profile, c.AddProfile(profile)\n}\n\nfunc login(ctx context.Context) (*oauth2.Token, error) {\n\tprovider, err := oidc.NewProvider(ctx, config.GetAuth0Domain())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to initialize OIDC provider: %w\", err)\n\t}\n\n\tverifier := provider.Verifier(&oidc.Config{ClientID: config.GetAuth0ClientId()})\n\n\toauth2Config := oauth2.Config{\n\t\tClientID:     config.GetAuth0ClientId(),\n\t\tClientSecret: config.GetAuth0ClientSecret(),\n\t\tRedirectURL:  fmt.Sprintf(\"http://localhost:%s/callback\", config.GetAuth0CallbackPort()),\n\t\tEndpoint:     provider.Endpoint(),\n\t\tScopes:       []string{oidc.ScopeOpenID, oidc.ScopeOfflineAccess, \"profile\"},\n\t}\n\n\tstate, err := auth.GenerateRandomState()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to generate random state: %w\", err)\n\t}\n\n\tauthURL := oauth2Config.AuthCodeURL(\n\t\tstate,\n\t\toauth2.SetAuthURLParam(\"audience\", config.GetAuth0Audience()),\n\t)\n\n\tview_common.RenderInfoMessageBold(\"Opening the browser for authentication ...\")\n\n\tview_common.RenderInfoMessage(\"If opening fails, visit:\\n\")\n\n\tfmt.Println(authURL)\n\n\t_ = browser.OpenURL(authURL)\n\n\tcode, err := auth.StartCallbackServer(state)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"authentication failed: %w\", err)\n\t}\n\n\ttoken, err := oauth2Config.Exchange(ctx, code)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to exchange token: %w\", err)\n\t}\n\n\trawIDToken, ok := token.Extra(\"id_token\").(string)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"no id_token in token response\")\n\t}\n\n\t_, err = verifier.Verify(ctx, rawIDToken)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to verify ID token: %w\", err)\n\t}\n\n\tview_common.RenderInfoMessageBold(\"Successfully logged in!\")\n\n\treturn token, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/auth/logout.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage auth\n\nimport (\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar LogoutCmd = &cobra.Command{\n\tUse:     \"logout\",\n\tShort:   \"Logout from Daytona\",\n\tArgs:    cobra.NoArgs,\n\tGroupID: internal.USER_GROUP,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tc, err := config.GetConfig()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tactiveProfile, err := c.GetActiveProfile()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// For now, this just clears the local auth token/api key entries\n\t\tactiveProfile.Api.Token = nil\n\t\tactiveProfile.Api.Key = nil\n\n\t\terr = c.EditProfile(activeProfile)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcommon.RenderInfoMessageBold(\"Successfully logged out\")\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "apps/cli/cmd/autocomplete.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage cmd\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar supportedShells = []string{\"bash\", \"zsh\", \"fish\", \"powershell\"}\n\nvar AutoCompleteCmd = &cobra.Command{\n\tUse:   fmt.Sprintf(\"autocomplete [%s]\", strings.Join(supportedShells, \"|\")),\n\tShort: \"Adds a completion script for your shell environment\",\n\tArgs:  cobra.ExactArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tshell := args[0]\n\n\t\tprofilePath, err := SetupAutocompletionForShell(cmd.Root(), shell)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfmt.Println(\"Autocomplete script generated and injected successfully.\")\n\t\tfmt.Printf(\"Please source your %s profile to apply the changes or restart your terminal.\\n\", shell)\n\t\tfmt.Printf(\"For manual sourcing, use: source %s\\n\", profilePath)\n\t\tif shell == \"bash\" {\n\t\t\tfmt.Println(\"Please make sure that you have bash-completion installed in order to get full autocompletion functionality.\")\n\t\t\tfmt.Println(\"On how to install bash-completion, please refer to the following link: https://www.daytona.io/docs/tools/cli/#daytona-autocomplete\")\n\t\t}\n\n\t\treturn nil\n\t},\n}\n\nfunc DetectShellAndSetupAutocompletion(rootCmd *cobra.Command) error {\n\tshell := os.Getenv(\"SHELL\")\n\tif shell == \"\" {\n\t\treturn fmt.Errorf(\"unable to detect the shell, please use a supported one: %s\", strings.Join(supportedShells, \", \"))\n\t}\n\n\tfor _, supportedShell := range supportedShells {\n\t\tif strings.Contains(shell, supportedShell) {\n\t\t\tshell = supportedShell\n\t\t\tbreak\n\t\t}\n\t}\n\n\t_, err := SetupAutocompletionForShell(rootCmd, shell)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc SetupAutocompletionForShell(rootCmd *cobra.Command, shell string) (string, error) {\n\thomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error finding user home directory: %s\", err)\n\t}\n\n\tvar filePath, profilePath string\n\tswitch shell {\n\tcase \"bash\":\n\t\tfilePath = filepath.Join(homeDir, \".daytona.completion_script.bash\")\n\t\tprofilePath = filepath.Join(homeDir, \".bashrc\")\n\tcase \"zsh\":\n\t\tfilePath = filepath.Join(homeDir, \".daytona.completion_script.zsh\")\n\t\tprofilePath = filepath.Join(homeDir, \".zshrc\")\n\tcase \"fish\":\n\t\tfilePath = filepath.Join(homeDir, \".config\", \"fish\", \"daytona.completion_script.fish\")\n\t\tprofilePath = filepath.Join(homeDir, \".config\", \"fish\", \"config.fish\")\n\tcase \"powershell\":\n\t\tfilePath = filepath.Join(homeDir, \"daytona.completion_script.ps1\")\n\t\tprofilePath = filepath.Join(homeDir, \"Documents\", \"WindowsPowerShell\", \"Microsoft.PowerShell_profile.ps1\")\n\tdefault:\n\t\treturn \"\", errors.New(\"unsupported shell type. Please use bash, zsh, fish, or powershell\")\n\t}\n\n\tfile, err := os.Create(filePath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error creating completion script file: %s\", err)\n\t}\n\tdefer file.Close()\n\n\tswitch shell {\n\tcase \"bash\":\n\t\terr = rootCmd.GenBashCompletion(file)\n\tcase \"zsh\":\n\t\terr = rootCmd.GenZshCompletion(file)\n\tcase \"fish\":\n\t\terr = rootCmd.GenFishCompletion(file, true)\n\tcase \"powershell\":\n\t\terr = rootCmd.GenPowerShellCompletionWithDesc(file)\n\t}\n\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error generating completion script: %s\", err)\n\t}\n\n\tsourceCommand := fmt.Sprintf(\"\\nsource %s\\n\", filePath)\n\tif shell == \"powershell\" {\n\t\tsourceCommand = fmt.Sprintf(\". %s\\n\", filePath)\n\t}\n\n\talreadyPresent := false\n\t// Read existing content from the file\n\tprofile, err := os.ReadFile(profilePath)\n\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn \"\", fmt.Errorf(\"error while reading profile (%s): %s\", profilePath, err)\n\t}\n\n\tif strings.Contains(string(profile), strings.TrimSpace(sourceCommand)) {\n\t\talreadyPresent = true\n\t}\n\n\tif !alreadyPresent {\n\t\t// Append the source command to the shell's profile file if not present\n\t\tprofile, err := os.OpenFile(profilePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error opening profile file (%s): %s\", profilePath, err)\n\t\t}\n\t\tdefer profile.Close()\n\n\t\tif _, err := profile.WriteString(sourceCommand); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error writing to profile file (%s): %s\", profilePath, err)\n\t\t}\n\t}\n\n\treturn profilePath, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/aliases.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nvar commandAliases = map[string][]string{\n\t\"create\":    {\"add\", \"new\"},\n\t\"delete\":    {\"remove\", \"rm\"},\n\t\"update\":    {\"set\"},\n\t\"install\":   {\"i\"},\n\t\"uninstall\": {\"u\"},\n\t\"info\":      {\"view\", \"inspect\"},\n\t\"code\":      {\"open\"},\n\t\"logs\":      {\"log\"},\n\t\"forward\":   {\"fwd\"},\n\t\"list\":      {\"ls\"},\n}\n\nfunc GetAliases(cmd string) []string {\n\tif aliases, exists := commandAliases[cmd]; exists {\n\t\treturn aliases\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/build.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/pkg/minio\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\n// Create MinIO client from access parameters\nfunc CreateMinioClient(accessParams *apiclient.StorageAccessDto) (*minio.Client, error) {\n\tstorageURL, err := url.Parse(accessParams.StorageUrl)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid storage URL: %w\", err)\n\t}\n\n\tminioClient, err := minio.NewClient(\n\t\tstorageURL.Host,\n\t\taccessParams.AccessKey,\n\t\taccessParams.Secret,\n\t\taccessParams.Bucket,\n\t\tstorageURL.Scheme == \"https\",\n\t\taccessParams.SessionToken,\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create storage client: %w\", err)\n\t}\n\n\treturn minioClient, nil\n}\n\n// List existing objects in MinIO\nfunc ListExistingObjects(ctx context.Context, minioClient *minio.Client, orgID string) (map[string]bool, error) {\n\tobjects, err := minioClient.ListObjects(ctx, orgID)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list objects: %w\", err)\n\t}\n\n\texistingObjects := make(map[string]bool)\n\tfor _, obj := range objects {\n\t\texistingObjects[obj] = true\n\t}\n\treturn existingObjects, nil\n}\n\n// getContextHashes processes context paths and returns their hashes\nfunc getContextHashes(ctx context.Context, apiClient *apiclient.APIClient, contextPaths []string) ([]string, error) {\n\tcontextHashes := []string{}\n\tif len(contextPaths) == 0 {\n\t\treturn contextHashes, nil\n\t}\n\n\t// Get storage access parameters\n\taccessParams, res, err := apiClient.ObjectStorageAPI.GetPushAccess(ctx).Execute()\n\tif err != nil {\n\t\treturn nil, apiclient_cli.HandleErrorResponse(res, err)\n\t}\n\n\t// Create MinIO client\n\tminioClient, err := CreateMinioClient(accessParams)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create storage client: %w\", err)\n\t}\n\n\t// List existing objects to avoid re-uploading\n\texistingObjects, err := ListExistingObjects(ctx, minioClient, accessParams.OrganizationId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list existing objects: %w\", err)\n\t}\n\n\t// Process each context path\n\tfor _, contextPath := range contextPaths {\n\t\tabsPath, err := filepath.Abs(contextPath)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid context path %s: %w\", contextPath, err)\n\t\t}\n\n\t\tfileInfo, err := os.Stat(absPath)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to access context path %s: %w\", contextPath, err)\n\t\t}\n\n\t\tif fileInfo.IsDir() {\n\t\t\t// Process directory\n\t\t\tdirHashes, err := minioClient.ProcessDirectory(ctx, absPath, accessParams.OrganizationId, existingObjects)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to process directory %s: %w\", absPath, err)\n\t\t\t}\n\t\t\tcontextHashes = append(contextHashes, dirHashes...)\n\t\t} else {\n\t\t\t// Process single file\n\t\t\thash, err := minioClient.ProcessFile(ctx, absPath, accessParams.OrganizationId, existingObjects)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to process file %s: %w\", absPath, err)\n\t\t\t}\n\t\t\tcontextHashes = append(contextHashes, hash)\n\t\t}\n\t}\n\n\treturn contextHashes, nil\n}\n\nfunc parseDockerfileForSources(dockerfileContent string, dockerfileDir string) ([]string, error) {\n\tvar sources []string\n\tlines := strings.Split(dockerfileContent, \"\\n\")\n\n\tcopyRegex := regexp.MustCompile(`^\\s*COPY\\s+(.+)`)\n\taddRegex := regexp.MustCompile(`^\\s*ADD\\s+(.+)`)\n\n\tfor _, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\n\t\t// Skip empty lines and comments\n\t\tif line == \"\" || strings.HasPrefix(line, \"#\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar matches []string\n\t\tif copyRegex.MatchString(line) {\n\t\t\t// Skip COPY commands with --from= flag (multi-stage builds)\n\t\t\tif !strings.Contains(line, \"--from=\") {\n\t\t\t\tmatches = copyRegex.FindStringSubmatch(line)\n\t\t\t}\n\t\t} else if addRegex.MatchString(line) {\n\t\t\tmatches = addRegex.FindStringSubmatch(line)\n\t\t}\n\n\t\tif len(matches) > 1 {\n\t\t\tsourcePaths := parseCopyAddCommand(matches[1])\n\t\t\tfor _, srcPath := range sourcePaths {\n\t\t\t\t// Skip if it's a URL (ADD command can use URLs)\n\t\t\t\tif strings.HasPrefix(srcPath, \"http://\") || strings.HasPrefix(srcPath, \"https://\") {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Convert relative paths to absolute paths relative to Dockerfile directory\n\t\t\t\tif !filepath.IsAbs(srcPath) {\n\t\t\t\t\tsrcPath = filepath.Join(dockerfileDir, srcPath)\n\t\t\t\t}\n\n\t\t\t\tsrcPath = filepath.Clean(srcPath)\n\n\t\t\t\t// Check if path exists and add to sources\n\t\t\t\tif _, err := os.Stat(srcPath); err == nil {\n\t\t\t\t\tsources = append(sources, srcPath)\n\t\t\t\t} else {\n\t\t\t\t\t// If exact path doesn't exist, try to match glob patterns\n\t\t\t\t\tmatches, err := filepath.Glob(srcPath)\n\t\t\t\t\tif err == nil && len(matches) > 0 {\n\t\t\t\t\t\tsources = append(sources, matches...)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove duplicates and optimize paths\n\tsourceMap := make(map[string]bool)\n\tvar uniqueSources []string\n\n\t// Check if we have the current directory (.) in our sources\n\thasCurrentDir := false\n\tcurrentDirPath := dockerfileDir\n\n\tfor _, src := range sources {\n\t\tif src == currentDirPath {\n\t\t\thasCurrentDir = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// If we have the current directory, we only need that (it includes everything)\n\tif hasCurrentDir {\n\t\treturn []string{currentDirPath}, nil\n\t}\n\n\t// Otherwise, remove duplicates normally\n\tfor _, src := range sources {\n\t\tif !sourceMap[src] {\n\t\t\tsourceMap[src] = true\n\t\t\tuniqueSources = append(uniqueSources, src)\n\t\t}\n\t}\n\n\treturn uniqueSources, nil\n}\n\nfunc parseCopyAddCommand(args string) []string {\n\targs = strings.TrimSpace(args)\n\tvar sources []string\n\n\t// Handle JSON array format: [\"src1\", \"src2\", \"dest\"]\n\tif strings.HasPrefix(args, \"[\") && strings.HasSuffix(args, \"]\") {\n\t\t// Remove brackets and parse as space-separated values with quotes\n\t\tcontent := strings.Trim(args, \"[]\")\n\t\tparts := parseQuotedArguments(content)\n\t\tif len(parts) >= 2 {\n\t\t\t// All but the last argument are sources\n\t\t\tsources = parts[:len(parts)-1]\n\t\t}\n\t\treturn sources\n\t}\n\n\t// Handle regular format with possible flags\n\tparts := parseQuotedArguments(args)\n\n\t// Skip flags like --chown, --chmod, --from\n\tsourcesStartIdx := 0\n\tfor i := 0; i < len(parts); i++ {\n\t\tpart := parts[i]\n\t\tif strings.HasPrefix(part, \"--\") {\n\t\t\t// Skip the flag and its value if it has one\n\t\t\tif !strings.Contains(part, \"=\") && i+1 < len(parts) && !strings.HasPrefix(parts[i+1], \"--\") {\n\t\t\t\tsourcesStartIdx = i + 2\n\t\t\t} else {\n\t\t\t\tsourcesStartIdx = i + 1\n\t\t\t}\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// After skipping flags, we need at least one source and one destination\n\tif len(parts)-sourcesStartIdx >= 2 {\n\t\tsources = parts[sourcesStartIdx : len(parts)-1]\n\t}\n\n\treturn sources\n}\n\nfunc parseQuotedArguments(input string) []string {\n\tvar args []string\n\tvar current strings.Builder\n\tinQuotes := false\n\tquoteChar := byte(0)\n\n\tinput = strings.TrimSpace(input)\n\n\tfor i := 0; i < len(input); i++ {\n\t\tchar := input[i]\n\n\t\tif !inQuotes && (char == '\"' || char == '\\'') {\n\t\t\tinQuotes = true\n\t\t\tquoteChar = char\n\t\t} else if inQuotes && char == quoteChar {\n\t\t\tinQuotes = false\n\t\t\tquoteChar = 0\n\t\t} else if !inQuotes && (char == ' ' || char == '\\t') {\n\t\t\tif current.Len() > 0 {\n\t\t\t\targs = append(args, current.String())\n\t\t\t\tcurrent.Reset()\n\t\t\t}\n\t\t\t// Skip consecutive whitespace\n\t\t\tfor i+1 < len(input) && (input[i+1] == ' ' || input[i+1] == '\\t') {\n\t\t\t\ti++\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent.WriteByte(char)\n\t\t}\n\t}\n\n\tif current.Len() > 0 {\n\t\targs = append(args, current.String())\n\t}\n\n\treturn args\n}\n\nfunc GetCreateBuildInfoDto(ctx context.Context, dockerfilePath string, contextPaths []string) (*apiclient.CreateBuildInfo, error) {\n\tdockerfileAbsPath, err := filepath.Abs(dockerfilePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid dockerfile path: %w\", err)\n\t}\n\n\tif _, err := os.Stat(dockerfileAbsPath); os.IsNotExist(err) {\n\t\treturn nil, fmt.Errorf(\"dockerfile does not exist: %s\", dockerfileAbsPath)\n\t}\n\n\tdockerfileContent, err := os.ReadFile(dockerfileAbsPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read dockerfile: %w\", err)\n\t}\n\n\tdockerfileDir := filepath.Dir(dockerfileAbsPath)\n\n\t// If no context paths are provided, automatically parse the Dockerfile to find them\n\tif len(contextPaths) == 0 {\n\t\tautoContextPaths, err := parseDockerfileForSources(string(dockerfileContent), dockerfileDir)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse dockerfile for context: %w\", err)\n\t\t}\n\t\tcontextPaths = autoContextPaths\n\t} else {\n\t\tvar resolvedContextPaths []string\n\t\tfor _, contextPath := range contextPaths {\n\t\t\tvar absPath string\n\t\t\tif filepath.IsAbs(contextPath) {\n\t\t\t\tabsPath = contextPath\n\t\t\t} else {\n\t\t\t\t// When context paths are provided manually (via --context flag),\n\t\t\t\t// resolve them relative to the current working directory\n\t\t\t\tabsPath, err = filepath.Abs(contextPath)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"failed to resolve context path %s: %w\", contextPath, err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tresolvedContextPaths = append(resolvedContextPaths, absPath)\n\t\t}\n\t\tcontextPaths = resolvedContextPaths\n\t}\n\n\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcontextHashes, err := getContextHashes(ctx, apiClient, contextPaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &apiclient.CreateBuildInfo{\n\t\tDockerfileContent: string(dockerfileContent),\n\t\tContextHashes:     contextHashes,\n\t}, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/format.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\t\"github.com/spf13/cobra\"\n\t\"gopkg.in/yaml.v2\"\n)\n\nconst (\n\tformatFlagDescription = `Output format. Must be one of (yaml, json)`\n\tformatFlagName        = \"format\"\n\tformatFlagShortHand   = \"f\"\n)\n\nvar (\n\tFormatFlag  string\n\tstandardOut *os.File\n)\n\ntype outputFormatter struct {\n\tdata      interface{}\n\tformatter Formatter\n}\n\nfunc NewFormatter(data interface{}) *outputFormatter {\n\tvar formatter Formatter\n\tswitch FormatFlag {\n\tcase \"json\":\n\t\tformatter = JSONFormatter{}\n\tcase \"yaml\":\n\t\tformatter = YAMLFormatter{}\n\tcase \"\":\n\t\tformatter = nil\n\tdefault:\n\t\tformatter = JSONFormatter{} // Default to JSON\n\t}\n\n\treturn &outputFormatter{\n\t\tdata:      data,\n\t\tformatter: formatter,\n\t}\n\n}\n\ntype Formatter interface {\n\tFormat(data interface{}) (string, error)\n}\n\ntype JSONFormatter struct{}\n\nfunc (f JSONFormatter) Format(data interface{}) (string, error) {\n\tjsonData, err := json.MarshalIndent(data, \"\", \"  \") // Indent with two spaces\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(jsonData), nil\n}\n\ntype YAMLFormatter struct{}\n\nfunc (f YAMLFormatter) Format(data interface{}) (string, error) {\n\tyamlData, err := yaml.Marshal(data)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(yamlData), nil\n}\n\nfunc (f *outputFormatter) Print() {\n\n\tformattedOutput, err := f.formatter.Format(f.data)\n\tif err != nil {\n\t\tfmt.Printf(\"Error formatting output: %v\\n\", err)\n\t\tos.Exit(1)\n\t}\n\n\tUnblockStdOut()\n\tfmt.Println(formattedOutput)\n\tBlockStdOut()\n}\n\nfunc BlockStdOut() {\n\tif os.Stdout != nil {\n\t\tstandardOut = os.Stdout\n\t\tos.Stdout = nil\n\t}\n}\n\nfunc UnblockStdOut() {\n\tif os.Stdout == nil {\n\t\tos.Stdout = standardOut\n\t\tstandardOut = nil\n\t}\n}\n\nfunc RegisterFormatFlag(cmd *cobra.Command) {\n\tcmd.Flags().StringVarP(&FormatFlag, formatFlagName, formatFlagShortHand, FormatFlag, formatFlagDescription)\n\tcmd.PreRun = func(cmd *cobra.Command, args []string) {\n\t\tif FormatFlag != \"\" {\n\t\t\tBlockStdOut()\n\t\t\t// When a structured output format is requested, suppress\n\t\t\t// noisy warnings such as version mismatch so scripts\n\t\t\t// consuming json/yaml aren't broken.\n\t\t\tinternal.SuppressVersionMismatchWarning = true\n\t\t} else {\n\t\t\tinternal.SuppressVersionMismatchWarning = false\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/logs.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage common\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/cli/config\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype ReadLogParams struct {\n\tId                   string\n\tServerUrl            string\n\tServerApi            config.ServerApi\n\tActiveOrganizationId *string\n\tFollow               *bool\n\tResourceType         ResourceType\n}\n\ntype ResourceType string\n\nconst (\n\tResourceTypeSandbox  ResourceType = \"sandbox\"\n\tResourceTypeSnapshot ResourceType = \"snapshots\"\n)\n\nfunc ReadBuildLogs(ctx context.Context, params ReadLogParams) {\n\turl := fmt.Sprintf(\"%s/%s/%s/build-logs\", params.ServerUrl, params.ResourceType, params.Id)\n\tif params.Follow != nil && *params.Follow {\n\t\turl = fmt.Sprintf(\"%s?follow=true\", url)\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\n\tif err != nil {\n\t\tlog.Errorf(\"Failed to create request: %v\", err)\n\t\treturn\n\t}\n\n\tif params.ServerApi.Key != nil {\n\t\treq.Header.Add(\"Authorization\", fmt.Sprintf(\"Bearer %s\", *params.ServerApi.Key))\n\t} else if params.ServerApi.Token != nil {\n\t\treq.Header.Add(\"Authorization\", fmt.Sprintf(\"Bearer %s\", params.ServerApi.Token.AccessToken))\n\n\t\tif params.ActiveOrganizationId != nil {\n\t\t\treq.Header.Add(\"X-Daytona-Organization-ID\", *params.ActiveOrganizationId)\n\t\t}\n\t}\n\n\treq.Header.Add(\"Accept\", \"application/octet-stream\")\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tlog.Errorf(\"Failed to connect to server: %v\", err)\n\t\treturn\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tlog.Errorf(\"Server returned a non-OK status while retrieving logs: %d\", resp.StatusCode)\n\t\treturn\n\t}\n\n\treader := bufio.NewReader(resp.Body)\n\tbuffer := make([]byte, 4096)\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tdefault:\n\t\t\tn, err := reader.Read(buffer)\n\t\t\tif n > 0 {\n\t\t\t\tfmt.Print(string(buffer[:n]))\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\tif params.Follow != nil && *params.Follow {\n\t\t\t\t\t\ttime.Sleep(500 * time.Millisecond)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// Don't log context.Canceled as it's an expected case when streaming is stopped\n\t\t\t\tif err != context.Canceled {\n\t\t\t\t\tlog.Errorf(\"Error reading from stream: %v\", err)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/organization.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"context\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\nfunc GetPersonalOrganizationId(profile config.Profile) (string, error) {\n\tapiClient, err := apiclient_cli.GetApiClient(&profile, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\torganizationList, res, err := apiClient.OrganizationsAPI.ListOrganizations(context.Background()).Execute()\n\tif err != nil {\n\t\treturn \"\", apiclient_cli.HandleErrorResponse(res, err)\n\t}\n\n\tfor _, organization := range organizationList {\n\t\tif organization.Personal {\n\t\t\treturn organization.Id, nil\n\t\t}\n\t}\n\n\treturn \"\", nil\n}\n\nfunc GetActiveOrganizationName(apiClient *apiclient.APIClient, ctx context.Context) (string, error) {\n\tactiveOrganizationId, err := config.GetActiveOrganizationId()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif activeOrganizationId == \"\" {\n\t\treturn \"\", config.ErrNoActiveOrganization\n\t}\n\n\tactiveOrganization, res, err := apiClient.OrganizationsAPI.GetOrganization(ctx, activeOrganizationId).Execute()\n\tif err != nil {\n\t\treturn \"\", apiclient_cli.HandleErrorResponse(res, err)\n\t}\n\n\treturn activeOrganization.Name, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/sandbox.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\nfunc RequireStartedState(sandbox *apiclient.Sandbox) error {\n\tif sandbox.State == nil {\n\t\treturn fmt.Errorf(\"sandbox state is unknown\")\n\t}\n\n\tstate := *sandbox.State\n\tif state == apiclient.SANDBOXSTATE_STARTED {\n\t\treturn nil\n\t}\n\n\tsandboxRef := sandbox.Id\n\tif sandbox.Name != \"\" {\n\t\tsandboxRef = sandbox.Name\n\t}\n\n\tswitch state {\n\tcase apiclient.SANDBOXSTATE_STOPPED:\n\t\treturn fmt.Errorf(\"sandbox is stopped. Start it with: daytona sandbox start %s\", sandboxRef)\n\tcase apiclient.SANDBOXSTATE_ARCHIVED:\n\t\treturn fmt.Errorf(\"sandbox is archived. Start it with: daytona sandbox start %s\", sandboxRef)\n\tcase apiclient.SANDBOXSTATE_ARCHIVING:\n\t\treturn fmt.Errorf(\"sandbox is archiving. Start it with: daytona sandbox start %s\", sandboxRef)\n\tcase apiclient.SANDBOXSTATE_STARTING:\n\t\treturn fmt.Errorf(\"sandbox is starting. Please wait for it to be ready\")\n\tcase apiclient.SANDBOXSTATE_STOPPING:\n\t\treturn fmt.Errorf(\"sandbox is stopping. Please wait for it to complete\")\n\tcase apiclient.SANDBOXSTATE_CREATING:\n\t\treturn fmt.Errorf(\"sandbox is being created. Please wait for it to be ready\")\n\tcase apiclient.SANDBOXSTATE_DESTROYING:\n\t\treturn fmt.Errorf(\"sandbox is being destroyed\")\n\tcase apiclient.SANDBOXSTATE_DESTROYED:\n\t\treturn fmt.Errorf(\"sandbox has been destroyed\")\n\tcase apiclient.SANDBOXSTATE_ERROR:\n\t\treturn fmt.Errorf(\"sandbox is in an error state\")\n\tcase apiclient.SANDBOXSTATE_BUILD_FAILED:\n\t\treturn fmt.Errorf(\"sandbox build failed\")\n\tdefault:\n\t\treturn fmt.Errorf(\"sandbox is not running (state: %s)\", state)\n\t}\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/ssh.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// ParseSSHCommand parses the SSH command string returned by the API\n// Expected formats:\n// - \"ssh token@host\" (port 22)\n// - \"ssh -p port token@host\"\nfunc ParseSSHCommand(sshCommand string) ([]string, error) {\n\tparts := strings.Fields(sshCommand)\n\tif len(parts) < 2 {\n\t\treturn nil, fmt.Errorf(\"invalid SSH command format: %s\", sshCommand)\n\t}\n\n\t// Skip the \"ssh\" part\n\targs := parts[1:]\n\n\treturn args, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/ssh_unix.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\n//go:build unix\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"os/signal\"\n\t\"syscall\"\n)\n\n// ExecuteSSH runs the SSH command with proper terminal handling\nfunc ExecuteSSH(sshArgs []string) error {\n\tsshPath, err := exec.LookPath(\"ssh\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"ssh not found in PATH: %w\", err)\n\t}\n\n\t// Create the command\n\tsshCmd := exec.Command(sshPath, sshArgs...)\n\tsshCmd.Stdin = os.Stdin\n\tsshCmd.Stdout = os.Stdout\n\tsshCmd.Stderr = os.Stderr\n\n\t// Handle signals - forward them to the SSH process\n\tsigChan := make(chan os.Signal, 1)\n\tsignal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGWINCH)\n\n\t// Start the SSH process\n\tif err := sshCmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"failed to start SSH: %w\", err)\n\t}\n\n\t// Forward signals to the SSH process\n\tgo func() {\n\t\tfor sig := range sigChan {\n\t\t\tif sshCmd.Process != nil {\n\t\t\t\t_ = sshCmd.Process.Signal(sig)\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Wait for SSH to complete\n\terr = sshCmd.Wait()\n\n\t// Stop signal handling\n\tsignal.Stop(sigChan)\n\tclose(sigChan)\n\n\tif err != nil {\n\t\tif exitErr, ok := err.(*exec.ExitError); ok {\n\t\t\tos.Exit(exitErr.ExitCode())\n\t\t}\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/ssh_windows.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\n//go:build windows\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"os/signal\"\n\t\"syscall\"\n)\n\n// ExecuteSSH runs the SSH command with proper terminal handling\nfunc ExecuteSSH(sshArgs []string) error {\n\tsshPath, err := exec.LookPath(\"ssh\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"ssh not found in PATH: %w\", err)\n\t}\n\n\t// Create the command\n\tsshCmd := exec.Command(sshPath, sshArgs...)\n\tsshCmd.Stdin = os.Stdin\n\tsshCmd.Stdout = os.Stdout\n\tsshCmd.Stderr = os.Stderr\n\n\t// Handle signals - forward them to the SSH process\n\t// Note: SIGWINCH is not available on Windows\n\tsigChan := make(chan os.Signal, 1)\n\tsignal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)\n\n\t// Start the SSH process\n\tif err := sshCmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"failed to start SSH: %w\", err)\n\t}\n\n\t// Forward signals to the SSH process\n\tgo func() {\n\t\tfor sig := range sigChan {\n\t\t\tif sshCmd.Process != nil {\n\t\t\t\t_ = sshCmd.Process.Signal(sig)\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Wait for SSH to complete\n\terr = sshCmd.Wait()\n\n\t// Stop signal handling\n\tsignal.Stop(sigChan)\n\tclose(sigChan)\n\n\tif err != nil {\n\t\tif exitErr, ok := err.(*exec.ExitError); ok {\n\t\t\tos.Exit(exitErr.ExitCode())\n\t\t}\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/state.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\nfunc AwaitSnapshotState(ctx context.Context, apiClient *apiclient.APIClient, name string, state apiclient.SnapshotState) error {\n\tfor {\n\t\tsnapshot, res, err := apiClient.SnapshotsAPI.GetSnapshot(ctx, name).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tswitch snapshot.State {\n\t\tcase state:\n\t\t\treturn nil\n\t\tcase apiclient.SNAPSHOTSTATE_ERROR, apiclient.SNAPSHOTSTATE_BUILD_FAILED:\n\t\t\tif !snapshot.ErrorReason.IsSet() {\n\t\t\t\treturn fmt.Errorf(\"snapshot processing failed\")\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"snapshot processing failed: %s\", *snapshot.ErrorReason.Get())\n\t\t}\n\n\t\ttime.Sleep(time.Second)\n\t}\n}\n\nfunc AwaitSandboxState(ctx context.Context, apiClient *apiclient.APIClient, targetSandbox string, state apiclient.SandboxState) error {\n\tfor {\n\t\tsandbox, res, err := apiClient.SandboxAPI.GetSandbox(ctx, targetSandbox).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif sandbox.State != nil && *sandbox.State == state {\n\t\t\treturn nil\n\t\t} else if sandbox.State != nil && (*sandbox.State == apiclient.SANDBOXSTATE_ERROR || *sandbox.State == apiclient.SANDBOXSTATE_BUILD_FAILED) {\n\t\t\tif sandbox.ErrorReason == nil {\n\t\t\t\treturn fmt.Errorf(\"sandbox processing failed\")\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"sandbox processing failed: %s\", *sandbox.ErrorReason)\n\t\t}\n\n\t\ttime.Sleep(time.Second)\n\t}\n}\n"
  },
  {
    "path": "apps/cli/cmd/common/validate.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc ValidateImageName(imageName string) error {\n\tparts := strings.Split(imageName, \":\")\n\tif len(parts) != 2 {\n\t\treturn fmt.Errorf(\"invalid image format: must contain exactly one colon (e.g., 'ubuntu:22.04')\")\n\t}\n\tif parts[1] == \"latest\" {\n\t\treturn fmt.Errorf(\"tag 'latest' not allowed, please use a specific version tag\")\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/docs.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage cmd\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/pkg/browser\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar docsURL string = \"https://www.daytona.io/docs/\"\n\nvar DocsCmd = &cobra.Command{\n\tUse:     \"docs\",\n\tShort:   \"Opens the Daytona documentation in your default browser.\",\n\tArgs:    cobra.NoArgs,\n\tAliases: []string{\"documentation\", \"doc\"},\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tcommon.RenderInfoMessageBold(fmt.Sprintf(\"Opening the Daytona documentation in your default browser. If opening fails, you can go to %s manually.\", common.LinkStyle.Render(docsURL)))\n\t\treturn browser.OpenURL(docsURL)\n\t},\n}\n"
  },
  {
    "path": "apps/cli/cmd/generatedocs.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/cobra/doc\"\n)\n\nvar yamlDirectory = \"hack\"\nvar defaultDirectory = \"docs\"\n\nvar GenerateDocsCmd = &cobra.Command{\n\tUse:   \"generate-docs\",\n\tShort: \"Generate documentation for the Daytona CLI\",\n\tArgs:  cobra.NoArgs,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tdirectory, err := cmd.Flags().GetString(\"directory\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif directory == \"\" {\n\t\t\tdirectory = defaultDirectory\n\t\t}\n\n\t\terr = os.MkdirAll(directory, os.ModePerm)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = os.MkdirAll(filepath.Join(yamlDirectory, directory), os.ModePerm)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = doc.GenMarkdownTree(cmd.Root(), directory)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = doc.GenYamlTree(cmd.Root(), filepath.Join(yamlDirectory, directory))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfmt.Printf(\"Documentation generated at %s\\n\", directory)\n\t\treturn nil\n\t},\n\tHidden: true,\n}\n\nfunc init() {\n\tGenerateDocsCmd.Flags().String(\"directory\", \"\", \"Directory to generate documentation into\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/mcp/agents/claude.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage agents\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n)\n\nfunc InitClaude(homeDir string) (string, string, error) {\n\tvar agentConfigFilePath string\n\tvar mcpLogFilePath string\n\n\tswitch runtime.GOOS {\n\tcase \"darwin\":\n\t\tagentConfigFilePath = filepath.Join(homeDir, \"Library\", \"Application Support\", \"Claude\", \"claude_desktop_config.json\")\n\t\tmcpLogFilePath = filepath.Join(homeDir, \"Library\", \"Logs\", \"Claude\", mcpLogFileName)\n\n\tcase \"windows\":\n\t\t// Resolve %APPDATA% environment variable\n\t\tappData := os.Getenv(\"APPDATA\")\n\t\tif appData == \"\" {\n\t\t\treturn \"\", \"\", errors.New(\"could not resolve APPDATA environment variable\")\n\t\t}\n\n\t\tagentConfigFilePath = filepath.Join(appData, \"Claude\", \"claude_desktop_config.json\")\n\t\tmcpLogFilePath = filepath.Join(appData, \"Claude\", \"Logs\", mcpLogFileName)\n\n\tcase \"linux\":\n\t\tagentConfigFilePath = filepath.Join(homeDir, \".config\", \"Claude\", \"claude_desktop_config.json\")\n\t\tmcpLogFilePath = filepath.Join(\"var\", \"log\", \"Claude\", mcpLogFileName)\n\tdefault:\n\t\treturn \"\", \"\", errors.New(\"operating system is not supported\")\n\t}\n\n\treturn agentConfigFilePath, mcpLogFilePath, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/mcp/agents/common.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage agents\n\nvar mcpLogFileName string = \"daytona-mcp-server.log\"\n"
  },
  {
    "path": "apps/cli/cmd/mcp/agents/cursor.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage agents\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n)\n\nfunc InitCursor(homeDir string) (string, string, error) {\n\tvar agentConfigFilePath string\n\tvar mcpLogFilePath string\n\n\tswitch runtime.GOOS {\n\tcase \"darwin\":\n\t\tagentConfigFilePath = filepath.Join(homeDir, \".cursor\", \"mcp.json\")\n\t\tmcpLogFilePath = filepath.Join(homeDir, \"Library\", \"Logs\", \"Cursor\", mcpLogFileName)\n\n\tcase \"windows\":\n\t\t// Resolve %APPDATA% environment variable\n\t\tappData := os.Getenv(\"APPDATA\")\n\t\tif appData == \"\" {\n\t\t\treturn \"\", \"\", errors.New(\"could not resolve APPDATA environment variable\")\n\t\t}\n\n\t\tagentConfigFilePath = filepath.Join(appData, \".cursor\", \"mcp.json\")\n\t\tmcpLogFilePath = filepath.Join(appData, \"Cursor\", \"Logs\", mcpLogFileName)\n\n\tcase \"linux\":\n\t\tagentConfigFilePath = filepath.Join(homeDir, \".cursor\", \"mcp.json\")\n\t\tmcpLogFilePath = filepath.Join(\"var\", \"log\", \"Cursor\", mcpLogFileName)\n\tdefault:\n\t\treturn \"\", \"\", errors.New(\"operating system is not supported\")\n\t}\n\n\treturn agentConfigFilePath, mcpLogFilePath, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/mcp/agents/windsurf.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage agents\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n)\n\nfunc InitWindsurf(homeDir string) (string, string, error) {\n\tvar agentConfigFilePath string\n\tvar mcpLogFilePath string\n\n\tswitch runtime.GOOS {\n\tcase \"darwin\":\n\t\tagentConfigFilePath = filepath.Join(homeDir, \".codeium\", \"windsurf\", \"mcp_config.json\")\n\t\tmcpLogFilePath = filepath.Join(homeDir, \"Library\", \"Logs\", \"Windsurf\", mcpLogFileName)\n\n\tcase \"windows\":\n\t\t// Resolve %APPDATA% environment variable\n\t\tappData := os.Getenv(\"APPDATA\")\n\t\tif appData == \"\" {\n\t\t\treturn \"\", \"\", errors.New(\"could not resolve APPDATA environment variable\")\n\t\t}\n\n\t\tagentConfigFilePath = filepath.Join(appData, \".codeium\", \"windsurf\", \"mcp_config.json\")\n\t\tmcpLogFilePath = filepath.Join(appData, \"Windsurf\", \"Logs\", mcpLogFileName)\n\n\tcase \"linux\":\n\t\tagentConfigFilePath = filepath.Join(homeDir, \".codeium\", \"windsurf\", \"mcp_config.json\")\n\t\tmcpLogFilePath = filepath.Join(\"var\", \"log\", \"Windsurf\", mcpLogFileName)\n\tdefault:\n\t\treturn \"\", \"\", errors.New(\"operating system is not supported\")\n\t}\n\n\treturn agentConfigFilePath, mcpLogFilePath, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/mcp/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage mcp\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar ConfigCmd = &cobra.Command{\n\tUse:   \"config [AGENT_NAME]\",\n\tShort: \"Outputs JSON configuration for Daytona MCP Server\",\n\tArgs:  cobra.NoArgs,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\thomeDir, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvar mcpLogFilePath string\n\n\t\tswitch runtime.GOOS {\n\t\tcase \"darwin\":\n\t\t\tmcpLogFilePath = homeDir + \"/.daytona/daytona-mcp.log\"\n\t\tcase \"windows\":\n\t\t\tmcpLogFilePath = os.Getenv(\"APPDATA\") + \"\\\\.daytona\\\\daytona-mcp.log\"\n\t\tcase \"linux\":\n\t\t\tmcpLogFilePath = homeDir + \"/.daytona/daytona-mcp.log\"\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unsupported OS: %s\", runtime.GOOS)\n\t\t}\n\n\t\tdaytonaMcpConfig, err := getDayonaMcpConfig(mcpLogFilePath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tmcpConfig := map[string]interface{}{\n\t\t\t\"daytona-mcp\": daytonaMcpConfig,\n\t\t}\n\n\t\tjsonBytes, err := json.MarshalIndent(mcpConfig, \"\", \"  \")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfmt.Println(string(jsonBytes))\n\n\t\treturn nil\n\t},\n}\n\nfunc getDayonaMcpConfig(mcpLogFilePath string) (map[string]interface{}, error) {\n\thomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Create daytona-mcp config\n\tdaytonaMcpConfig := map[string]interface{}{\n\t\t\"command\": \"daytona\",\n\t\t\"args\":    []string{\"mcp\", \"start\"},\n\t\t\"env\": map[string]string{\n\t\t\t\"PATH\": homeDir + \":/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin\",\n\t\t\t\"HOME\": homeDir,\n\t\t},\n\t\t\"logFile\": mcpLogFilePath,\n\t}\n\n\tif runtime.GOOS == \"windows\" {\n\t\tdaytonaMcpConfig[\"env\"].(map[string]string)[\"APPDATA\"] = os.Getenv(\"APPDATA\")\n\t}\n\n\treturn daytonaMcpConfig, nil\n}\n"
  },
  {
    "path": "apps/cli/cmd/mcp/init.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage mcp\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/daytonaio/daytona/cli/cmd/mcp/agents\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar InitCmd = &cobra.Command{\n\tUse:   \"init [AGENT_NAME]\",\n\tShort: \"Initialize Daytona MCP Server with an agent (currently supported: claude, windsurf, cursor)\",\n\tArgs:  cobra.MaximumNArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tif len(args) == 0 {\n\t\t\treturn fmt.Errorf(\"agent name is required\")\n\t\t}\n\n\t\thomeDir, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvar agentConfigFilePath, mcpLogFilePath string\n\n\t\tswitch args[0] {\n\t\tcase \"claude\":\n\t\t\tagentConfigFilePath, mcpLogFilePath, err = agents.InitClaude(homeDir)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase \"cursor\":\n\t\t\tagentConfigFilePath, mcpLogFilePath, err = agents.InitCursor(homeDir)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase \"windsurf\":\n\t\t\tagentConfigFilePath, mcpLogFilePath, err = agents.InitWindsurf(homeDir)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"agent name %s is not supported\", args[0])\n\t\t}\n\n\t\treturn injectConfig(agentConfigFilePath, mcpLogFilePath)\n\t},\n}\n\nfunc injectConfig(agentConfigFilePath, mcpLogFilePath string) error {\n\tdaytonaMcpConfig, err := getDayonaMcpConfig(mcpLogFilePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Read existing model config or create new one\n\tvar agentConfig map[string]interface{}\n\tif agentConfigData, err := os.ReadFile(agentConfigFilePath); err == nil {\n\t\tif err := json.Unmarshal(agentConfigData, &agentConfig); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if !os.IsNotExist(err) {\n\t\treturn err\n\t} else {\n\t\tagentConfig = make(map[string]interface{})\n\t}\n\n\t// Initialize or update mcpServers field\n\tmcpServers, ok := agentConfig[\"mcpServers\"].(map[string]interface{})\n\tif !ok {\n\t\tmcpServers = make(map[string]interface{})\n\t}\n\n\t// Add or update daytona-mcp configuration\n\tmcpServers[\"daytona-mcp\"] = daytonaMcpConfig\n\tagentConfig[\"mcpServers\"] = mcpServers\n\n\t// Write back the updated config with indentation\n\tupdatedJSON, err := json.MarshalIndent(agentConfig, \"\", \"    \")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn os.WriteFile(agentConfigFilePath, updatedJSON, 0644)\n}\n"
  },
  {
    "path": "apps/cli/cmd/mcp/mcp.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage mcp\n\nimport (\n\t\"github.com/spf13/cobra\"\n)\n\nvar MCPCmd = &cobra.Command{\n\tUse:   \"mcp\",\n\tShort: \"Manage Daytona MCP Server\",\n\tLong:  \"Commands for managing Daytona MCP Server\",\n}\n\nfunc init() {\n\tMCPCmd.AddCommand(InitCmd)\n\tMCPCmd.AddCommand(StartCmd)\n\tMCPCmd.AddCommand(ConfigCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/mcp/start.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage mcp\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\n\t\"github.com/daytonaio/daytona/cli/mcp\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar StartCmd = &cobra.Command{\n\tUse:   \"start\",\n\tShort: \"Start Daytona MCP Server\",\n\tArgs:  cobra.NoArgs,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tserver := mcp.NewDaytonaMCPServer()\n\n\t\tinterruptChan := make(chan os.Signal, 1)\n\t\tsignal.Notify(interruptChan, os.Interrupt)\n\n\t\terrChan := make(chan error)\n\n\t\tgo func() {\n\t\t\terrChan <- server.Start()\n\t\t}()\n\n\t\tselect {\n\t\tcase err := <-errChan:\n\t\t\treturn err\n\t\tcase <-interruptChan:\n\t\t\treturn nil\n\t\t}\n\t},\n}\n"
  },
  {
    "path": "apps/cli/cmd/organization/create.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage organization\n\nimport (\n\t\"context\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/organization\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar CreateCmd = &cobra.Command{\n\tUse:   \"create [ORGANIZATION_NAME]\",\n\tShort: \"Create a new organization and set it as active\",\n\tArgs:  cobra.ExactArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcreateOrganizationDto := apiclient.CreateOrganization{\n\t\t\tName: args[0],\n\t\t}\n\n\t\torg, res, err := apiClient.OrganizationsAPI.CreateOrganization(ctx).CreateOrganization(createOrganizationDto).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tc, err := config.GetConfig()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tactiveProfile, err := c.GetActiveProfile()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tactiveProfile.ActiveOrganizationId = &org.Id\n\t\terr = c.EditProfile(activeProfile)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\torganization.RenderInfo(org, false)\n\n\t\tcommon.RenderInfoMessageBold(\"Your organization has been created and its approval is pending\\nOur team has been notified and will set up your resource quotas shortly\")\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "apps/cli/cmd/organization/delete.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage organization\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/organization\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar DeleteCmd = &cobra.Command{\n\tUse:     \"delete [ORGANIZATION]\",\n\tShort:   \"Delete an organization\",\n\tArgs:    cobra.MaximumNArgs(1),\n\tAliases: common.GetAliases(\"delete\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tvar chosenOrganization *apiclient.Organization\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\torgList, res, err := apiClient.OrganizationsAPI.ListOrganizations(ctx).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif len(orgList) == 0 {\n\t\t\tutil.NotifyEmptyOrganizationList(true)\n\t\t\treturn nil\n\t\t}\n\n\t\tif len(args) == 0 {\n\t\t\tchosenOrganization, err = organization.GetOrganizationIdFromPrompt(orgList)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tfor _, org := range orgList {\n\t\t\t\tif org.Id == args[0] || org.Name == args[0] {\n\t\t\t\t\tchosenOrganization = &org\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif chosenOrganization == nil {\n\t\t\t\treturn fmt.Errorf(\"organization %s not found\", args[0])\n\t\t\t}\n\t\t}\n\n\t\tif chosenOrganization.Name == \"Personal\" {\n\t\t\treturn fmt.Errorf(\"cannot delete personal organization\")\n\t\t}\n\n\t\tres, err = apiClient.OrganizationsAPI.DeleteOrganization(ctx, chosenOrganization.Id).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Organization %s has been deleted\", chosenOrganization.Name))\n\n\t\tc, err := config.GetConfig()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tactiveProfile, err := c.GetActiveProfile()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif activeProfile.ActiveOrganizationId == nil || *activeProfile.ActiveOrganizationId != chosenOrganization.Id {\n\t\t\treturn nil\n\t\t}\n\n\t\tpersonalOrganizationId, err := common.GetPersonalOrganizationId(activeProfile)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tactiveProfile.ActiveOrganizationId = &personalOrganizationId\n\t\treturn c.EditProfile(activeProfile)\n\t},\n}\n"
  },
  {
    "path": "apps/cli/cmd/organization/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage organization\n\nimport (\n\t\"context\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/views/organization\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar ListCmd = &cobra.Command{\n\tUse:     \"list\",\n\tShort:   \"List all organizations\",\n\tArgs:    cobra.NoArgs,\n\tAliases: common.GetAliases(\"list\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\torganizationList, res, err := apiClient.OrganizationsAPI.ListOrganizations(ctx).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif common.FormatFlag != \"\" {\n\t\t\tformattedData := common.NewFormatter(organizationList)\n\t\t\tformattedData.Print()\n\t\t\treturn nil\n\t\t}\n\n\t\tactiveOrganizationId, err := config.GetActiveOrganizationId()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\torganization.ListOrganizations(organizationList, &activeOrganizationId)\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\tcommon.RegisterFormatFlag(ListCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/organization/organization.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage organization\n\nimport (\n\t\"errors\"\n\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar OrganizationCmd = &cobra.Command{\n\tUse:     \"organization\",\n\tShort:   \"Manage Daytona organizations\",\n\tLong:    \"Commands for managing Daytona organizations\",\n\tAliases: []string{\"organizations\", \"org\", \"orgs\"},\n\tGroupID: internal.USER_GROUP,\n\tPersistentPreRunE: func(cmd *cobra.Command, args []string) error {\n\t\tif config.IsApiKeyAuth() {\n\t\t\treturn errors.New(\"organization commands are not available when using API key authentication - run `daytona login` to reauthenticate with browser\")\n\t\t}\n\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\tOrganizationCmd.AddCommand(ListCmd)\n\tOrganizationCmd.AddCommand(CreateCmd)\n\tOrganizationCmd.AddCommand(UseCmd)\n\tOrganizationCmd.AddCommand(DeleteCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/organization/use.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage organization\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/organization\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar UseCmd = &cobra.Command{\n\tUse:   \"use [ORGANIZATION]\",\n\tShort: \"Set active organization\",\n\tArgs:  cobra.MaximumNArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tvar chosenOrganization *apiclient.Organization\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\torgList, res, err := apiClient.OrganizationsAPI.ListOrganizations(ctx).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif len(orgList) == 0 {\n\t\t\tutil.NotifyEmptyOrganizationList(true)\n\t\t\treturn nil\n\t\t}\n\n\t\tif len(args) == 0 {\n\t\t\tchosenOrganization, err = organization.GetOrganizationIdFromPrompt(orgList)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tfor _, org := range orgList {\n\t\t\t\tif org.Id == args[0] || org.Name == args[0] {\n\t\t\t\t\tchosenOrganization = &org\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif chosenOrganization == nil {\n\t\t\t\treturn fmt.Errorf(\"organization %s not found\", args[0])\n\t\t\t}\n\t\t}\n\n\t\tc, err := config.GetConfig()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tactiveProfile, err := c.GetActiveProfile()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tactiveProfile.ActiveOrganizationId = &chosenOrganization.Id\n\t\terr = c.EditProfile(activeProfile)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcommon.RenderInfoMessageBold(fmt.Sprintf(\"Organization %s is now active\", chosenOrganization.Name))\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/archive.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar ArchiveCmd = &cobra.Command{\n\tUse:   \"archive [SANDBOX_ID] | [SANDBOX_NAME]\",\n\tShort: \"Archive a sandbox\",\n\tArgs:  cobra.MaximumNArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsandboxIdOrNameArg := args[0]\n\n\t\t_, res, err := apiClient.SandboxAPI.ArchiveSandbox(ctx, sandboxIdOrNameArg).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Sandbox %s marked for archival\", sandboxIdOrNameArg))\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/create.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/util\"\n\tviews_common \"github.com/daytonaio/daytona/cli/views/common\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/spf13/cobra\"\n)\n\nconst SANDBOX_TERMINAL_PORT = 22222\n\nvar CreateCmd = &cobra.Command{\n\tUse:     \"create [flags]\",\n\tShort:   \"Create a new sandbox\",\n\tArgs:    cobra.NoArgs,\n\tAliases: common.GetAliases(\"create\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcreateSandbox := apiclient.NewCreateSandbox()\n\n\t\t// Add non-zero values to the request\n\t\tif snapshotFlag != \"\" {\n\t\t\tcreateSandbox.SetSnapshot(snapshotFlag)\n\t\t}\n\t\tif nameFlag != \"\" {\n\t\t\tcreateSandbox.SetName(nameFlag)\n\t\t}\n\t\tif userFlag != \"\" {\n\t\t\tcreateSandbox.SetUser(userFlag)\n\t\t}\n\t\tif len(envFlag) > 0 {\n\t\t\tenv := make(map[string]string)\n\t\t\tfor _, e := range envFlag {\n\t\t\t\tparts := strings.SplitN(e, \"=\", 2)\n\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\tenv[parts[0]] = parts[1]\n\t\t\t\t}\n\t\t\t}\n\t\t\tcreateSandbox.SetEnv(env)\n\t\t}\n\t\tif len(labelsFlag) > 0 {\n\t\t\tlabels := make(map[string]string)\n\t\t\tfor _, l := range labelsFlag {\n\t\t\t\tparts := strings.SplitN(l, \"=\", 2)\n\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\tlabels[parts[0]] = parts[1]\n\t\t\t\t}\n\t\t\t}\n\t\t\tcreateSandbox.SetLabels(labels)\n\t\t}\n\t\tif publicFlag {\n\t\t\tcreateSandbox.SetPublic(true)\n\t\t}\n\t\tif classFlag != \"\" {\n\t\t\tcreateSandbox.SetClass(classFlag)\n\t\t}\n\t\tif targetFlag != \"\" {\n\t\t\tcreateSandbox.SetTarget(targetFlag)\n\t\t}\n\t\tif cpuFlag > 0 {\n\t\t\tcreateSandbox.SetCpu(cpuFlag)\n\t\t}\n\t\tif gpuFlag > 0 {\n\t\t\tcreateSandbox.SetGpu(gpuFlag)\n\t\t}\n\t\tif memoryFlag > 0 {\n\t\t\tcreateSandbox.SetMemory(memoryFlag)\n\t\t}\n\t\tif diskFlag > 0 {\n\t\t\tcreateSandbox.SetDisk(diskFlag)\n\t\t}\n\t\tif autoStopFlag >= 0 {\n\t\t\tcreateSandbox.SetAutoStopInterval(autoStopFlag)\n\t\t}\n\t\tif autoArchiveFlag >= 0 {\n\t\t\tcreateSandbox.SetAutoArchiveInterval(autoArchiveFlag)\n\t\t}\n\t\tcreateSandbox.SetAutoDeleteInterval(autoDeleteFlag)\n\n\t\tcreateSandbox.SetNetworkBlockAll(networkBlockAllFlag)\n\t\tif networkAllowListFlag != \"\" {\n\t\t\tcreateSandbox.SetNetworkAllowList(networkAllowListFlag)\n\t\t}\n\n\t\tif dockerfileFlag != \"\" {\n\t\t\tcreateBuildInfoDto, err := common.GetCreateBuildInfoDto(ctx, dockerfileFlag, contextFlag)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcreateSandbox.SetBuildInfo(*createBuildInfoDto)\n\t\t}\n\n\t\tif len(volumesFlag) > 0 {\n\t\t\tvolumes := make([]apiclient.SandboxVolume, 0, len(volumesFlag))\n\t\t\tfor _, v := range volumesFlag {\n\t\t\t\tparts := strings.SplitN(v, \":\", 2)\n\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\tvolumeId := parts[0]\n\t\t\t\t\tmountPath := parts[1]\n\t\t\t\t\tvolume := apiclient.SandboxVolume{\n\t\t\t\t\t\tVolumeId:  volumeId,\n\t\t\t\t\t\tMountPath: mountPath,\n\t\t\t\t\t}\n\t\t\t\t\tvolumes = append(volumes, volume)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(volumes) > 0 {\n\t\t\t\tcreateSandbox.SetVolumes(volumes)\n\t\t\t}\n\t\t}\n\n\t\tvar sandbox *apiclient.Sandbox\n\n\t\tsandbox, res, err := apiClient.SandboxAPI.CreateSandbox(ctx).CreateSandbox(*createSandbox).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif sandbox.State != nil && *sandbox.State == apiclient.SANDBOXSTATE_PENDING_BUILD {\n\t\t\tc, err := config.GetConfig()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tactiveProfile, err := c.GetActiveProfile()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\terr = common.AwaitSandboxState(ctx, apiClient, sandbox.Id, apiclient.SANDBOXSTATE_BUILDING_SNAPSHOT)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tlogsContext, stopLogs := context.WithCancel(context.Background())\n\t\t\tdefer stopLogs()\n\n\t\t\tgo common.ReadBuildLogs(logsContext, common.ReadLogParams{\n\t\t\t\tId:                   sandbox.Id,\n\t\t\t\tServerUrl:            activeProfile.Api.Url,\n\t\t\t\tServerApi:            activeProfile.Api,\n\t\t\t\tActiveOrganizationId: activeProfile.ActiveOrganizationId,\n\t\t\t\tFollow:               util.Pointer(true),\n\t\t\t\tResourceType:         common.ResourceTypeSandbox,\n\t\t\t})\n\n\t\t\terr = common.AwaitSandboxState(ctx, apiClient, sandbox.Id, apiclient.SANDBOXSTATE_STARTED)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Wait for the last logs to be read\n\t\t\ttime.Sleep(250 * time.Millisecond)\n\t\t\tstopLogs()\n\t\t}\n\n\t\tpreviewUrl, res, err := apiClient.SandboxAPI.GetPortPreviewUrl(ctx, sandbox.Id, SANDBOX_TERMINAL_PORT).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tboldStyle := lipgloss.NewStyle().Bold(true)\n\n\t\tviews_common.RenderInfoMessageBold(fmt.Sprintf(\"Sandbox '%s' created successfully\", sandbox.Name))\n\t\tviews_common.RenderInfoMessage(fmt.Sprintf(\"Connect via SSH:         %s\", boldStyle.Render(fmt.Sprintf(\"daytona ssh %s\", sandbox.Name))))\n\t\tviews_common.RenderInfoMessage(fmt.Sprintf(\"Open the Web Terminal:   %s\\n\", views_common.LinkStyle.Render(previewUrl.Url)))\n\t\treturn nil\n\t},\n}\n\nvar (\n\tsnapshotFlag         string\n\tnameFlag             string\n\tuserFlag             string\n\tenvFlag              []string\n\tlabelsFlag           []string\n\tpublicFlag           bool\n\tclassFlag            string\n\ttargetFlag           string\n\tcpuFlag              int32\n\tgpuFlag              int32\n\tmemoryFlag           int32\n\tdiskFlag             int32\n\tautoStopFlag         int32\n\tautoArchiveFlag      int32\n\tautoDeleteFlag       int32\n\tvolumesFlag          []string\n\tdockerfileFlag       string\n\tcontextFlag          []string\n\tnetworkBlockAllFlag  bool\n\tnetworkAllowListFlag string\n)\n\nfunc init() {\n\tCreateCmd.Flags().StringVar(&snapshotFlag, \"snapshot\", \"\", \"Snapshot to use for the sandbox\")\n\tCreateCmd.Flags().StringVar(&nameFlag, \"name\", \"\", \"Name of the sandbox\")\n\tCreateCmd.Flags().StringVar(&userFlag, \"user\", \"\", \"User associated with the sandbox\")\n\tCreateCmd.Flags().StringArrayVarP(&envFlag, \"env\", \"e\", []string{}, \"Environment variables (format: KEY=VALUE)\")\n\tCreateCmd.Flags().StringArrayVarP(&labelsFlag, \"label\", \"l\", []string{}, \"Labels (format: KEY=VALUE)\")\n\tCreateCmd.Flags().BoolVar(&publicFlag, \"public\", false, \"Make sandbox publicly accessible\")\n\tCreateCmd.Flags().StringVar(&classFlag, \"class\", \"\", \"Sandbox class type (small, medium, large)\")\n\tCreateCmd.Flags().StringVar(&targetFlag, \"target\", \"\", \"Target region (eu, us)\")\n\tCreateCmd.Flags().Int32Var(&cpuFlag, \"cpu\", 0, \"CPU cores allocated to the sandbox\")\n\tCreateCmd.Flags().Int32Var(&gpuFlag, \"gpu\", 0, \"GPU units allocated to the sandbox\")\n\tCreateCmd.Flags().Int32Var(&memoryFlag, \"memory\", 0, \"Memory allocated to the sandbox in MB\")\n\tCreateCmd.Flags().Int32Var(&diskFlag, \"disk\", 0, \"Disk space allocated to the sandbox in GB\")\n\tCreateCmd.Flags().Int32Var(&autoStopFlag, \"auto-stop\", 15, \"Auto-stop interval in minutes (0 means disabled)\")\n\tCreateCmd.Flags().Int32Var(&autoArchiveFlag, \"auto-archive\", 10080, \"Auto-archive interval in minutes (0 means the maximum interval will be used)\")\n\tCreateCmd.Flags().Int32Var(&autoDeleteFlag, \"auto-delete\", -1, \"Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\")\n\tCreateCmd.Flags().StringArrayVarP(&volumesFlag, \"volume\", \"v\", []string{}, \"Volumes to mount (format: VOLUME_NAME:MOUNT_PATH)\")\n\tCreateCmd.Flags().StringVarP(&dockerfileFlag, \"dockerfile\", \"f\", \"\", \"Path to Dockerfile for Sandbox snapshot\")\n\tCreateCmd.Flags().StringArrayVarP(&contextFlag, \"context\", \"c\", []string{}, \"Files or directories to include in the build context (can be specified multiple times)\")\n\tCreateCmd.Flags().BoolVar(&networkBlockAllFlag, \"network-block-all\", false, \"Whether to block all network access for the sandbox\")\n\tCreateCmd.Flags().StringVar(&networkAllowListFlag, \"network-allow-list\", \"\", \"Comma-separated list of allowed CIDR network addresses for the sandbox\")\n\n\tCreateCmd.MarkFlagsMutuallyExclusive(\"snapshot\", \"dockerfile\")\n\tCreateCmd.MarkFlagsMutuallyExclusive(\"snapshot\", \"context\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/delete.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\tviews_util \"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/spf13/cobra\"\n)\n\nconst spinnerThreshold = 10\n\nvar DeleteCmd = &cobra.Command{\n\tUse:     \"delete [SANDBOX_ID] | [SANDBOX_NAME]\",\n\tShort:   \"Delete a sandbox\",\n\tArgs:    cobra.MaximumNArgs(1),\n\tAliases: common.GetAliases(\"delete\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Handle case when no sandbox ID is provided and allFlag is true\n\t\tif len(args) == 0 {\n\t\t\tif allFlag {\n\t\t\t\tpage := float32(1.0)\n\t\t\t\tlimit := float32(200.0) // 200 is the maximum limit for the API\n\t\t\t\tvar allSandboxes []apiclient.Sandbox\n\n\t\t\t\tfor {\n\t\t\t\t\tsandboxBatch, res, err := apiClient.SandboxAPI.ListSandboxesPaginated(ctx).Page(page).Limit(limit).Execute()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t\t\t\t}\n\n\t\t\t\t\tallSandboxes = append(allSandboxes, sandboxBatch.Items...)\n\n\t\t\t\t\tif len(sandboxBatch.Items) < int(limit) || page >= float32(sandboxBatch.TotalPages) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tpage++\n\t\t\t\t}\n\n\t\t\t\tif len(allSandboxes) == 0 {\n\t\t\t\t\tview_common.RenderInfoMessageBold(\"No sandboxes to delete\")\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tvar deletedCount int64\n\n\t\t\t\tdeleteFn := func() error {\n\t\t\t\t\tvar wg sync.WaitGroup\n\t\t\t\t\tsem := make(chan struct{}, 10) // limit to 10 concurrent deletes\n\n\t\t\t\t\tfor _, sb := range allSandboxes {\n\t\t\t\t\t\twg.Add(1)\n\t\t\t\t\t\tgo func(sb apiclient.Sandbox) {\n\t\t\t\t\t\t\tdefer wg.Done()\n\t\t\t\t\t\t\tsem <- struct{}{}\n\t\t\t\t\t\t\tdefer func() { <-sem }()\n\n\t\t\t\t\t\t\t_, res, err := apiClient.SandboxAPI.DeleteSandbox(ctx, sb.Id).Execute()\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tfmt.Printf(\"Failed to delete sandbox %s: %s\\n\", sb.Id, apiclient_cli.HandleErrorResponse(res, err))\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tatomic.AddInt64(&deletedCount, 1)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}(sb)\n\t\t\t\t\t}\n\t\t\t\t\twg.Wait()\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tif len(allSandboxes) > spinnerThreshold {\n\t\t\t\t\terr = views_util.WithInlineSpinner(\"Deleting all sandboxes\", deleteFn)\n\t\t\t\t} else {\n\t\t\t\t\terr = deleteFn()\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Deleted %d sandboxes\", atomic.LoadInt64(&deletedCount)))\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn cmd.Help()\n\t\t}\n\n\t\t// Handle case when a sandbox ID is provided\n\t\tsandboxIdOrNameArg := args[0]\n\n\t\t_, res, err := apiClient.SandboxAPI.DeleteSandbox(ctx, sandboxIdOrNameArg).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Sandbox %s deleted\", sandboxIdOrNameArg))\n\n\t\treturn nil\n\t},\n}\n\nvar allFlag bool\n\nfunc init() {\n\tDeleteCmd.Flags().BoolVarP(&allFlag, \"all\", \"a\", false, \"Delete all sandboxes\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/exec.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/toolbox\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar ExecCmd = &cobra.Command{\n\tUse:   \"exec [SANDBOX_ID | SANDBOX_NAME] -- [COMMAND] [ARGS...]\",\n\tShort: \"Execute a command in a sandbox\",\n\tLong:  \"Execute a command in a running sandbox\",\n\tArgs:  cobra.MinimumNArgs(2),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsandboxIdOrName := args[0]\n\n\t\t// Find the command args after \"--\"\n\t\tcommandArgs := args[1:]\n\t\tif len(commandArgs) == 0 {\n\t\t\treturn fmt.Errorf(\"no command specified\")\n\t\t}\n\n\t\t// First, get the sandbox to get its ID and region (in case name was provided)\n\t\tsandbox, res, err := apiClient.SandboxAPI.GetSandbox(ctx, sandboxIdOrName).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif err := common.RequireStartedState(sandbox); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\ttoolboxClient := toolbox.NewClient(apiClient)\n\n\t\tcommand := strings.Join(commandArgs, \" \")\n\n\t\texecuteRequest := toolbox.ExecuteRequest{\n\t\t\tCommand: command,\n\t\t}\n\t\tif execCwd != \"\" {\n\t\t\texecuteRequest.Cwd = &execCwd\n\t\t}\n\t\tif execTimeout > 0 {\n\t\t\ttimeout := float32(execTimeout)\n\t\t\texecuteRequest.Timeout = &timeout\n\t\t}\n\n\t\t// Execute the command via toolbox\n\t\tresponse, err := toolboxClient.ExecuteCommand(ctx, sandbox, executeRequest)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Print the output (stdout + stderr combined)\n\t\tif response.Result != \"\" {\n\t\t\tfmt.Print(response.Result)\n\t\t}\n\n\t\t// Exit with the command's exit code\n\t\texitCode := int(response.ExitCode)\n\t\tif exitCode != 0 {\n\t\t\tif response.Result == \"\" {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"Command failed with exit code %d\\n\", exitCode)\n\t\t\t}\n\t\t\tos.Exit(exitCode)\n\t\t}\n\n\t\treturn nil\n\t},\n}\n\nvar (\n\texecCwd     string\n\texecTimeout int\n)\n\nfunc init() {\n\tExecCmd.Flags().StringVar(&execCwd, \"cwd\", \"\", \"Working directory for command execution\")\n\tExecCmd.Flags().IntVar(&execTimeout, \"timeout\", 0, \"Command timeout in seconds (0 for no timeout)\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/views/sandbox\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar InfoCmd = &cobra.Command{\n\tUse:     \"info [SANDBOX_ID] | [SANDBOX_NAME]\",\n\tShort:   \"Get sandbox info\",\n\tArgs:    cobra.ExactArgs(1),\n\tAliases: common.GetAliases(\"info\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsandboxIdOrNameArg := args[0]\n\n\t\tsb, res, err := apiClient.SandboxAPI.GetSandbox(ctx, sandboxIdOrNameArg).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif common.FormatFlag != \"\" {\n\t\t\tformattedData := common.NewFormatter(sb)\n\t\t\tformattedData.Print()\n\t\t\treturn nil\n\t\t}\n\n\t\tsandbox.RenderInfo(sb, false)\n\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\tcommon.RegisterFormatFlag(InfoCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/views/sandbox\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar (\n\tpageFlag  int\n\tlimitFlag int\n)\n\nvar ListCmd = &cobra.Command{\n\tUse:     \"list\",\n\tShort:   \"List sandboxes\",\n\tArgs:    cobra.NoArgs,\n\tAliases: common.GetAliases(\"list\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tpage := float32(1.0)\n\t\tlimit := float32(100.0)\n\n\t\tif cmd.Flags().Changed(\"page\") {\n\t\t\tpage = float32(pageFlag)\n\t\t}\n\n\t\tif cmd.Flags().Changed(\"limit\") {\n\t\t\tlimit = float32(limitFlag)\n\t\t}\n\n\t\tsandboxList, res, err := apiClient.SandboxAPI.ListSandboxesPaginated(ctx).Page(page).Limit(limit).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tsandbox.SortSandboxes(&sandboxList.Items)\n\n\t\tif common.FormatFlag != \"\" {\n\t\t\tformattedData := common.NewFormatter(sandboxList)\n\t\t\tformattedData.Print()\n\t\t\treturn nil\n\t\t}\n\n\t\tvar activeOrganizationName *string\n\n\t\tif !config.IsApiKeyAuth() {\n\t\t\tname, err := common.GetActiveOrganizationName(apiClient, ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tactiveOrganizationName = &name\n\t\t}\n\n\t\tsandbox.ListSandboxes(sandboxList.Items, activeOrganizationName)\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\tListCmd.Flags().IntVarP(&pageFlag, \"page\", \"p\", 1, \"Page number for pagination (starting from 1)\")\n\tListCmd.Flags().IntVarP(&limitFlag, \"limit\", \"l\", 100, \"Maximum number of items per page\")\n\tcommon.RegisterFormatFlag(ListCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/preview_url.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar PreviewUrlCmd = &cobra.Command{\n\tUse:     \"preview-url [SANDBOX_ID | SANDBOX_NAME]\",\n\tShort:   \"Get signed preview URL for a sandbox port\",\n\tArgs:    cobra.ExactArgs(1),\n\tAliases: common.GetAliases(\"preview-url\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsandboxIdOrName := args[0]\n\n\t\tif previewUrlPort == 0 {\n\t\t\treturn fmt.Errorf(\"port flag is required\")\n\t\t}\n\n\t\treq := apiClient.SandboxAPI.GetSignedPortPreviewUrl(ctx, sandboxIdOrName, previewUrlPort).\n\t\t\tExpiresInSeconds(previewUrlExpires)\n\n\t\tpreviewUrl, res, err := req.Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tfmt.Println(previewUrl.Url)\n\n\t\treturn nil\n\t},\n}\n\nvar (\n\tpreviewUrlPort    int32\n\tpreviewUrlExpires int32\n)\n\nfunc init() {\n\tPreviewUrlCmd.Flags().Int32VarP(&previewUrlPort, \"port\", \"p\", 0, \"Port number to get preview URL for (required)\")\n\tPreviewUrlCmd.Flags().Int32Var(&previewUrlExpires, \"expires\", 3600, \"URL expiration time in seconds\")\n\n\t_ = PreviewUrlCmd.MarkFlagRequired(\"port\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/sandbox.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar SandboxCmd = &cobra.Command{\n\tUse:     \"sandbox\",\n\tShort:   \"Manage Daytona sandboxes\",\n\tLong:    \"Commands for managing Daytona sandboxes\",\n\tAliases: []string{\"sandboxes\"},\n\tGroupID: internal.SANDBOX_GROUP,\n\tHidden:  true, // Deprecated: use top-level commands instead (e.g., \"daytona start\" instead of \"daytona sandbox start\")\n}\n\nfunc init() {\n\tSandboxCmd.AddCommand(ListCmd)\n\tSandboxCmd.AddCommand(CreateCmd)\n\tSandboxCmd.AddCommand(InfoCmd)\n\tSandboxCmd.AddCommand(DeleteCmd)\n\tSandboxCmd.AddCommand(StartCmd)\n\tSandboxCmd.AddCommand(StopCmd)\n\tSandboxCmd.AddCommand(ArchiveCmd)\n\tSandboxCmd.AddCommand(SSHCmd)\n\tSandboxCmd.AddCommand(ExecCmd)\n\tSandboxCmd.AddCommand(PreviewUrlCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/ssh.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar SSHCmd = &cobra.Command{\n\tUse:   \"ssh [SANDBOX_ID] | [SANDBOX_NAME]\",\n\tShort: \"SSH into a sandbox\",\n\tLong:  \"Establish an SSH connection to a running sandbox\",\n\tArgs:  cobra.ExactArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsandboxIdOrName := args[0]\n\n\t\t// Get sandbox to check state\n\t\tsandbox, res, err := apiClient.SandboxAPI.GetSandbox(ctx, sandboxIdOrName).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif err := common.RequireStartedState(sandbox); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Create SSH access token\n\t\tsshAccessRequest := apiClient.SandboxAPI.CreateSshAccess(ctx, sandbox.Id)\n\t\tif sshExpiresInMinutes > 0 {\n\t\t\tsshAccessRequest = sshAccessRequest.ExpiresInMinutes(float32(sshExpiresInMinutes))\n\t\t}\n\n\t\tsshAccess, res, err := sshAccessRequest.Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\t// Parse the SSH command from the response\n\t\tsshArgs, err := common.ParseSSHCommand(sshAccess.SshCommand)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to parse SSH command: %w\", err)\n\t\t}\n\n\t\t// Execute SSH\n\t\treturn common.ExecuteSSH(sshArgs)\n\t},\n}\n\nvar sshExpiresInMinutes int\n\nfunc init() {\n\tSSHCmd.Flags().IntVar(&sshExpiresInMinutes, \"expires\", 1440, \"SSH access token expiration time in minutes (defaults to 24 hours)\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/start.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar StartCmd = &cobra.Command{\n\tUse:   \"start [SANDBOX_ID] | [SANDBOX_NAME]\",\n\tShort: \"Start a sandbox\",\n\tArgs:  cobra.MaximumNArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsandboxIdOrNameArg := args[0]\n\n\t\t_, res, err := apiClient.SandboxAPI.StartSandbox(ctx, sandboxIdOrNameArg).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Sandbox %s started\", sandboxIdOrNameArg))\n\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n}\n"
  },
  {
    "path": "apps/cli/cmd/sandbox/stop.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar StopCmd = &cobra.Command{\n\tUse:   \"stop [SANDBOX_ID] | [SANDBOX_NAME]\",\n\tShort: \"Stop a sandbox\",\n\tArgs:  cobra.MaximumNArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tsandboxIdOrNameArg := args[0]\n\n\t\t_, res, err := apiClient.SandboxAPI.StopSandbox(ctx, sandboxIdOrNameArg).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Sandbox %s stopped\", sandboxIdOrNameArg))\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n}\n"
  },
  {
    "path": "apps/cli/cmd/snapshot/create.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage snapshot\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/util\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\tviews_util \"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar CreateCmd = &cobra.Command{\n\tUse:     \"create [SNAPSHOT]\",\n\tShort:   \"Create a snapshot\",\n\tArgs:    cobra.ExactArgs(1),\n\tAliases: common.GetAliases(\"create\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\t\tsnapshotName := args[0]\n\n\t\tusingDockerfile := dockerfilePathFlag != \"\"\n\t\tusingImage := imageNameFlag != \"\"\n\n\t\tif !usingDockerfile && !usingImage {\n\t\t\treturn fmt.Errorf(\"must specify either --dockerfile or --image\")\n\t\t}\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcreateSnapshot := apiclient.NewCreateSnapshot(snapshotName)\n\n\t\tif cpuFlag != 0 {\n\t\t\tcreateSnapshot.SetCpu(cpuFlag)\n\t\t}\n\t\tif memoryFlag != 0 {\n\t\t\tcreateSnapshot.SetMemory(memoryFlag)\n\t\t}\n\t\tif diskFlag != 0 {\n\t\t\tcreateSnapshot.SetDisk(diskFlag)\n\t\t}\n\t\tif regionIdFlag != \"\" {\n\t\t\tcreateSnapshot.SetRegionId(regionIdFlag)\n\t\t}\n\n\t\tif usingDockerfile {\n\t\t\tcreateBuildInfoDto, err := common.GetCreateBuildInfoDto(ctx, dockerfilePathFlag, contextFlag)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcreateSnapshot.SetBuildInfo(*createBuildInfoDto)\n\t\t} else if usingImage {\n\t\t\terr := common.ValidateImageName(imageNameFlag)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcreateSnapshot.SetImageName(imageNameFlag)\n\t\t\tif entrypointFlag != \"\" {\n\t\t\t\tcreateSnapshot.SetEntrypoint(strings.Split(entrypointFlag, \" \"))\n\t\t\t}\n\t\t} else if entrypointFlag != \"\" {\n\t\t\tcreateSnapshot.SetEntrypoint(strings.Split(entrypointFlag, \" \"))\n\t\t}\n\n\t\t// Send create request\n\t\tsnapshot, res, err := apiClient.SnapshotsAPI.CreateSnapshot(ctx).CreateSnapshot(*createSnapshot).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\t// If we're building from a Dockerfile, show build logs\n\t\tif usingDockerfile {\n\t\t\tc, err := config.GetConfig()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tactiveProfile, err := c.GetActiveProfile()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tlogsContext, stopLogs := context.WithCancel(context.Background())\n\t\t\tdefer stopLogs()\n\n\t\t\tgo common.ReadBuildLogs(logsContext, common.ReadLogParams{\n\t\t\t\tId:                   snapshot.Id,\n\t\t\t\tServerUrl:            activeProfile.Api.Url,\n\t\t\t\tServerApi:            activeProfile.Api,\n\t\t\t\tActiveOrganizationId: activeProfile.ActiveOrganizationId,\n\t\t\t\tFollow:               util.Pointer(true),\n\t\t\t\tResourceType:         common.ResourceTypeSnapshot,\n\t\t\t})\n\n\t\t\terr = common.AwaitSnapshotState(ctx, apiClient, snapshotName, apiclient.SNAPSHOTSTATE_PENDING)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Wait for the last logs to be read\n\t\t\ttime.Sleep(250 * time.Millisecond)\n\t\t\tstopLogs()\n\t\t}\n\n\t\terr = views_util.WithInlineSpinner(\"Waiting for the snapshot to be validated\", func() error {\n\t\t\treturn common.AwaitSnapshotState(ctx, apiClient, snapshotName, apiclient.SNAPSHOTSTATE_ACTIVE)\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Snapshot %s successfully created\", snapshotName))\n\t\tview_common.RenderInfoMessage(fmt.Sprintf(\"%s Run 'daytona sandbox create --snapshot %s' to create a new sandbox using this snapshot\", view_common.Checkmark, snapshotName))\n\t\treturn nil\n\t},\n}\n\nvar (\n\tentrypointFlag     string\n\timageNameFlag      string\n\tdockerfilePathFlag string\n\tcontextFlag        []string\n\tcpuFlag            int32\n\tmemoryFlag         int32\n\tdiskFlag           int32\n\tregionIdFlag       string\n)\n\nfunc init() {\n\tCreateCmd.Flags().StringVarP(&entrypointFlag, \"entrypoint\", \"e\", \"\", \"The entrypoint command for the snapshot\")\n\tCreateCmd.Flags().StringVarP(&imageNameFlag, \"image\", \"i\", \"\", \"The image name for the snapshot\")\n\tCreateCmd.Flags().StringVarP(&dockerfilePathFlag, \"dockerfile\", \"f\", \"\", \"Path to Dockerfile to build\")\n\tCreateCmd.Flags().StringArrayVarP(&contextFlag, \"context\", \"c\", []string{}, \"Files or directories to include in the build context (can be specified multiple times). If not provided, context will be automatically determined from COPY/ADD commands in the Dockerfile\")\n\tCreateCmd.Flags().Int32Var(&cpuFlag, \"cpu\", 0, \"CPU cores that will be allocated to the underlying sandboxes (default: 1)\")\n\tCreateCmd.Flags().Int32Var(&memoryFlag, \"memory\", 0, \"Memory that will be allocated to the underlying sandboxes in GB (default: 1)\")\n\tCreateCmd.Flags().Int32Var(&diskFlag, \"disk\", 0, \"Disk space that will be allocated to the underlying sandboxes in GB (default: 3)\")\n\tCreateCmd.Flags().StringVar(&regionIdFlag, \"region\", \"\", \"ID of the region where the snapshot will be available (defaults to organization default region)\")\n\n\tCreateCmd.MarkFlagsMutuallyExclusive(\"image\", \"dockerfile\")\n\tCreateCmd.MarkFlagsMutuallyExclusive(\"image\", \"context\")\n\tCreateCmd.MarkFlagsMutuallyExclusive(\"entrypoint\", \"dockerfile\")\n\tCreateCmd.MarkFlagsMutuallyExclusive(\"entrypoint\", \"context\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/snapshot/delete.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage snapshot\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar DeleteCmd = &cobra.Command{\n\tUse:     \"delete [SNAPSHOT_ID | SNAPSHOT_NAME]\",\n\tShort:   \"Delete a snapshot\",\n\tArgs:    cobra.MaximumNArgs(1),\n\tAliases: common.GetAliases(\"delete\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Handle case when no snapshot ID is provided and allFlag is true\n\t\tif len(args) == 0 {\n\t\t\tif allFlag {\n\t\t\t\tpage := float32(1.0)\n\t\t\t\tlimit := float32(200.0) // 200 is the maximum limit for the API\n\t\t\t\tvar allSnapshots []apiclient.SnapshotDto\n\n\t\t\t\tfor {\n\t\t\t\t\tsnapshotBatch, res, err := apiClient.SnapshotsAPI.GetAllSnapshots(ctx).Page(page).Limit(limit).Execute()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t\t\t\t}\n\n\t\t\t\t\tallSnapshots = append(allSnapshots, snapshotBatch.Items...)\n\n\t\t\t\t\tif len(snapshotBatch.Items) < int(limit) || page >= snapshotBatch.TotalPages {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tpage++\n\t\t\t\t}\n\n\t\t\t\tif len(allSnapshots) == 0 {\n\t\t\t\t\tview_common.RenderInfoMessageBold(\"No snapshots to delete\")\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tvar deletedCount int\n\n\t\t\t\tfor _, snapshot := range allSnapshots {\n\t\t\t\t\tres, err := apiClient.SnapshotsAPI.RemoveSnapshot(ctx, snapshot.Id).Execute()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tfmt.Printf(\"Failed to delete snapshot %s: %s\\n\", snapshot.Id, apiclient_cli.HandleErrorResponse(res, err))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdeletedCount++\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Deleted %d snapshots\", deletedCount))\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn cmd.Help()\n\t\t}\n\n\t\tsnapshotIdOrName := args[0]\n\n\t\tsnapshot, res, err := apiClient.SnapshotsAPI.GetSnapshot(ctx, snapshotIdOrName).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tres, err = apiClient.SnapshotsAPI.RemoveSnapshot(ctx, snapshot.Id).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Snapshot %s deleted\", snapshotIdOrName))\n\n\t\treturn nil\n\t},\n}\n\nvar allFlag bool\n\nfunc init() {\n\tDeleteCmd.Flags().BoolVarP(&allFlag, \"all\", \"a\", false, \"Delete all snapshots\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/snapshot/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage snapshot\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/views/snapshot\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar (\n\tpageFlag  int\n\tlimitFlag int\n)\n\nvar ListCmd = &cobra.Command{\n\tUse:     \"list\",\n\tShort:   \"List all snapshots\",\n\tLong:    \"List all available Daytona snapshots\",\n\tAliases: common.GetAliases(\"list\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tpage := float32(1.0)\n\t\tlimit := float32(100.0)\n\n\t\tif cmd.Flags().Changed(\"page\") {\n\t\t\tpage = float32(pageFlag)\n\t\t}\n\n\t\tif cmd.Flags().Changed(\"limit\") {\n\t\t\tlimit = float32(limitFlag)\n\t\t}\n\n\t\tsnapshots, res, err := apiClient.SnapshotsAPI.GetAllSnapshots(ctx).Page(page).Limit(limit).Execute()\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error: %v\\n\", err)\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif common.FormatFlag != \"\" {\n\t\t\tformattedData := common.NewFormatter(snapshots.Items)\n\t\t\tformattedData.Print()\n\t\t\treturn nil\n\t\t}\n\n\t\tvar activeOrganizationName *string\n\n\t\tif !config.IsApiKeyAuth() {\n\t\t\tname, err := common.GetActiveOrganizationName(apiClient, ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tactiveOrganizationName = &name\n\t\t}\n\n\t\tsnapshot.ListSnapshots(snapshots.Items, activeOrganizationName)\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\tcommon.RegisterFormatFlag(ListCmd)\n\tListCmd.Flags().IntVarP(&pageFlag, \"page\", \"p\", 1, \"Page number for pagination (starting from 1)\")\n\tListCmd.Flags().IntVarP(&limitFlag, \"limit\", \"l\", 100, \"Maximum number of items per page\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/snapshot/push.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage snapshot\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/docker\"\n\tviews_common \"github.com/daytonaio/daytona/cli/views/common\"\n\tviews_util \"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/client\"\n\t\"github.com/docker/docker/pkg/jsonmessage\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar PushCmd = &cobra.Command{\n\tUse:   \"push [SNAPSHOT]\",\n\tShort: \"Push local snapshot\",\n\tLong:  \"Push a local Docker image to Daytona. To securely build it on our infrastructure, use 'daytona snapshot build'\",\n\tArgs:  cobra.ExactArgs(1),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\t\tsourceImage := args[0]\n\n\t\terr := common.ValidateImageName(sourceImage)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tdockerClient, err := client.NewClientWithOpts(\n\t\t\tclient.FromEnv,\n\t\t\tclient.WithAPIVersionNegotiation(),\n\t\t)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create Docker client: %w\", err)\n\t\t}\n\t\tdefer dockerClient.Close()\n\n\t\t// Check if the image exists locally when not building\n\t\tif exists, err := docker.ImageExistsLocally(ctx, dockerClient, sourceImage); err != nil {\n\t\t\treturn err\n\t\t} else if !exists {\n\t\t\treturn fmt.Errorf(\"image '%s' not found locally. Please ensure the image exists and try again\", sourceImage)\n\t\t}\n\n\t\t// Validate image architecture\n\t\tisArchAmd, err := docker.CheckAmdArchitecture(ctx, dockerClient, sourceImage)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to check image architecture: %w\", err)\n\t\t}\n\t\tif !isArchAmd {\n\t\t\treturn fmt.Errorf(\"image '%s' is not compatible with AMD architecture\", sourceImage)\n\t\t}\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tpushAccessRequest := apiClient.DockerRegistryAPI.GetTransientPushAccess(ctx)\n\t\tif regionIdFlag != \"\" {\n\t\t\tpushAccessRequest = pushAccessRequest.RegionId(regionIdFlag)\n\t\t}\n\t\ttokenResponse, res, err := pushAccessRequest.Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tencodedAuthConfig, err := json.Marshal(registry.AuthConfig{\n\t\t\tUsername:      tokenResponse.Username,\n\t\t\tPassword:      tokenResponse.Secret,\n\t\t\tServerAddress: tokenResponse.RegistryUrl,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to marshal auth config: %w\", err)\n\t\t}\n\n\t\t// Extract image name without tag and create timestamp-based tag\n\t\timageName := sourceImage\n\t\tif colonIndex := strings.LastIndex(sourceImage, \":\"); colonIndex != -1 {\n\t\t\timageName = sourceImage[:colonIndex]\n\t\t}\n\n\t\t// Generate timestamp-based tag to avoid inconsistencies\n\t\t// 20060102150405 is the format of the timestamp (year, month, day, hour, minute, second)\n\t\ttimestamp := time.Now().Format(\"20060102150405\")\n\t\ttargetImage := fmt.Sprintf(\"%s/%s/%s:%s\", tokenResponse.RegistryUrl, tokenResponse.Project, imageName, timestamp)\n\t\terr = dockerClient.ImageTag(ctx, sourceImage, targetImage)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to tag image: %w\", err)\n\t\t}\n\n\t\t// Push image to transient registry\n\t\tpushReader, err := dockerClient.ImagePush(ctx, targetImage, image.PushOptions{\n\t\t\tRegistryAuth: base64.URLEncoding.EncodeToString(encodedAuthConfig),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to push image: %w\", err)\n\t\t}\n\t\tdefer pushReader.Close()\n\n\t\terr = jsonmessage.DisplayJSONMessagesStream(pushReader, os.Stdout, 0, true, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcreateSnapshot := apiclient.NewCreateSnapshot(nameFlag)\n\n\t\tcreateSnapshot.SetImageName(targetImage)\n\n\t\tif entrypointFlag != \"\" {\n\t\t\tcreateSnapshot.SetEntrypoint(strings.Split(entrypointFlag, \" \"))\n\t\t}\n\n\t\t// Poll until the image is really available on the registry\n\t\t// This is a workaround for harbor's delay in making newly created images available\n\t\tfor {\n\t\t\t_, err := dockerClient.DistributionInspect(ctx, targetImage,\n\t\t\t\tbase64.URLEncoding.EncodeToString(encodedAuthConfig))\n\t\t\tif err == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ttime.Sleep(time.Second)\n\t\t}\n\n\t\tif cpuFlag != 0 {\n\t\t\tcreateSnapshot.SetCpu(cpuFlag)\n\t\t}\n\t\tif memoryFlag != 0 {\n\t\t\tcreateSnapshot.SetMemory(memoryFlag)\n\t\t}\n\t\tif diskFlag != 0 {\n\t\t\tcreateSnapshot.SetDisk(diskFlag)\n\t\t}\n\t\tif regionIdFlag != \"\" {\n\t\t\tcreateSnapshot.SetRegionId(regionIdFlag)\n\t\t}\n\n\t\t_, res, err = apiClient.SnapshotsAPI.CreateSnapshot(ctx).CreateSnapshot(*createSnapshot).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tviews_common.RenderInfoMessageBold(fmt.Sprintf(\"Successfully pushed %s to Daytona\", sourceImage))\n\n\t\terr = views_util.WithInlineSpinner(\"Waiting for the snapshot to be validated\", func() error {\n\t\t\treturn common.AwaitSnapshotState(ctx, apiClient, nameFlag, apiclient.SNAPSHOTSTATE_ACTIVE)\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tviews_common.RenderInfoMessage(fmt.Sprintf(\"%s  Use '%s' to create a new sandbox using this snapshot\", views_common.Checkmark, nameFlag))\n\t\treturn nil\n\t},\n}\n\nvar (\n\tnameFlag string\n)\n\nfunc init() {\n\tPushCmd.Flags().StringVarP(&entrypointFlag, \"entrypoint\", \"e\", \"\", \"The entrypoint command for the image\")\n\tPushCmd.Flags().StringVarP(&nameFlag, \"name\", \"n\", \"\", \"Specify the Snapshot name\")\n\tPushCmd.Flags().Int32Var(&cpuFlag, \"cpu\", 0, \"CPU cores that will be allocated to the underlying sandboxes (default: 1)\")\n\tPushCmd.Flags().Int32Var(&memoryFlag, \"memory\", 0, \"Memory that will be allocated to the underlying sandboxes in GB (default: 1)\")\n\tPushCmd.Flags().Int32Var(&diskFlag, \"disk\", 0, \"Disk space that will be allocated to the underlying sandboxes in GB (default: 3)\")\n\tPushCmd.Flags().StringVar(&regionIdFlag, \"region\", \"\", \"ID of the region where the snapshot will be available (defaults to organization default region)\")\n\n\t_ = PushCmd.MarkFlagRequired(\"name\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/snapshot/snapshot.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage snapshot\n\nimport (\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar SnapshotsCmd = &cobra.Command{\n\tUse:     \"snapshot\",\n\tShort:   \"Manage Daytona snapshots\",\n\tLong:    \"Commands for managing Daytona snapshots\",\n\tAliases: []string{\"snapshots\"},\n\tGroupID: internal.SANDBOX_GROUP,\n}\n\nfunc init() {\n\tSnapshotsCmd.AddCommand(ListCmd)\n\tSnapshotsCmd.AddCommand(CreateCmd)\n\tSnapshotsCmd.AddCommand(PushCmd)\n\tSnapshotsCmd.AddCommand(DeleteCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/version.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage cmd\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar VersionCmd = &cobra.Command{\n\tUse:   \"version\",\n\tShort: \"Print the version number\",\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tfmt.Println(\"Daytona CLI version\", internal.Version)\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "apps/cli/cmd/volume/create.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage volume\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar CreateCmd = &cobra.Command{\n\tUse:     \"create [NAME]\",\n\tShort:   \"Create a volume\",\n\tArgs:    cobra.ExactArgs(1),\n\tAliases: common.GetAliases(\"create\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient_cli.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvolume, res, err := apiClient.VolumesAPI.CreateVolume(ctx).CreateVolume(apiclient.CreateVolume{\n\t\t\tName: args[0],\n\t\t}).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient_cli.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Volume %s successfully created\", volume.Name))\n\t\treturn nil\n\t},\n}\n\nvar sizeFlag int32\n\nfunc init() {\n\tCreateCmd.Flags().Int32VarP(&sizeFlag, \"size\", \"s\", 10, \"Size of the volume in GB\")\n}\n"
  },
  {
    "path": "apps/cli/cmd/volume/delete.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage volume\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\tview_common \"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar DeleteCmd = &cobra.Command{\n\tUse:     \"delete [VOLUME_ID]\",\n\tShort:   \"Delete a volume\",\n\tArgs:    cobra.ExactArgs(1),\n\tAliases: common.GetAliases(\"delete\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tres, err := apiClient.VolumesAPI.DeleteVolume(ctx, args[0]).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tview_common.RenderInfoMessageBold(fmt.Sprintf(\"Volume %s deleted\", args[0]))\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "apps/cli/cmd/volume/get.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage volume\n\nimport (\n\t\"context\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/views/volume\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar GetCmd = &cobra.Command{\n\tUse:     \"get [VOLUME_ID]\",\n\tShort:   \"Get volume details\",\n\tArgs:    cobra.ExactArgs(1),\n\tAliases: common.GetAliases(\"get\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvol, res, err := apiClient.VolumesAPI.GetVolume(ctx, args[0]).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif common.FormatFlag != \"\" {\n\t\t\tformattedData := common.NewFormatter(vol)\n\t\t\tformattedData.Print()\n\t\t\treturn nil\n\t\t}\n\n\t\tvolume.RenderInfo(vol, false)\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\tcommon.RegisterFormatFlag(GetCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/volume/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage volume\n\nimport (\n\t\"context\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/daytonaio/daytona/cli/cmd/common\"\n\t\"github.com/daytonaio/daytona/cli/config\"\n\t\"github.com/daytonaio/daytona/cli/views/volume\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar ListCmd = &cobra.Command{\n\tUse:     \"list\",\n\tShort:   \"List all volumes\",\n\tArgs:    cobra.NoArgs,\n\tAliases: common.GetAliases(\"list\"),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\tctx := context.Background()\n\n\t\tapiClient, err := apiclient.GetApiClient(nil, nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tvolumes, res, err := apiClient.VolumesAPI.ListVolumes(ctx).Execute()\n\t\tif err != nil {\n\t\t\treturn apiclient.HandleErrorResponse(res, err)\n\t\t}\n\n\t\tif common.FormatFlag != \"\" {\n\t\t\tformattedData := common.NewFormatter(volumes)\n\t\t\tformattedData.Print()\n\t\t\treturn nil\n\t\t}\n\n\t\tvar activeOrganizationName *string\n\n\t\tif !config.IsApiKeyAuth() {\n\t\t\tname, err := common.GetActiveOrganizationName(apiClient, ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tactiveOrganizationName = &name\n\t\t}\n\n\t\tvolume.ListVolumes(volumes, activeOrganizationName)\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\tcommon.RegisterFormatFlag(ListCmd)\n}\n"
  },
  {
    "path": "apps/cli/cmd/volume/volume.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage volume\n\nimport (\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar VolumeCmd = &cobra.Command{\n\tUse:     \"volume\",\n\tShort:   \"Manage Daytona volumes\",\n\tLong:    \"Commands for managing Daytona volumes\",\n\tAliases: []string{\"volumes\"},\n\tGroupID: internal.SANDBOX_GROUP,\n}\n\nfunc init() {\n\tVolumeCmd.AddCommand(ListCmd)\n\tVolumeCmd.AddCommand(CreateCmd)\n\tVolumeCmd.AddCommand(GetCmd)\n\tVolumeCmd.AddCommand(DeleteCmd)\n}\n"
  },
  {
    "path": "apps/cli/config/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage config\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/cli/cmd\"\n\t\"github.com/daytonaio/daytona/cli/internal\"\n)\n\nconst DAYTONA_API_URL_ENV_VAR = \"DAYTONA_API_URL\"\nconst DAYTONA_API_KEY_ENV_VAR = \"DAYTONA_API_KEY\"\n\ntype Config struct {\n\tActiveProfileId string    `json:\"activeProfile\"`\n\tProfiles        []Profile `json:\"profiles\"`\n}\n\ntype Profile struct {\n\tId                   string            `json:\"id\"`\n\tName                 string            `json:\"name\"`\n\tApi                  ServerApi         `json:\"api\"`\n\tActiveOrganizationId *string           `json:\"activeOrganizationId\"`\n\tToolboxProxyUrls     map[string]string `json:\"toolboxProxyUrls,omitempty\"` // Cache proxy URLs by region\n}\n\ntype ServerApi struct {\n\tUrl   string  `json:\"url\"`\n\tKey   *string `json:\"key\"`\n\tToken *Token  `json:\"token\"`\n}\n\ntype Token struct {\n\tAccessToken  string    `json:\"accessToken\"`\n\tRefreshToken string    `json:\"refreshToken\"`\n\tExpiresAt    time.Time `json:\"expiresAt\"`\n}\n\nfunc GetConfig() (*Config, error) {\n\tconfigFilePath, err := getConfigPath()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t_, err = os.Stat(configFilePath)\n\tif os.IsNotExist(err) {\n\t\t// Setup autocompletion when adding initial config\n\t\t_ = cmd.DetectShellAndSetupAutocompletion(cmd.AutoCompleteCmd.Root())\n\n\t\tconfig := &Config{}\n\t\treturn config, config.Save()\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar c Config\n\tconfigContent, err := os.ReadFile(configFilePath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\terr = json.Unmarshal(configContent, &c)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &c, nil\n}\n\nvar ErrNoProfilesFound = errors.New(\"no profiles found. Run `daytona login` to authenticate\")\n\nfunc (c *Config) GetActiveProfile() (Profile, error) {\n\tapiUrl := os.Getenv(DAYTONA_API_URL_ENV_VAR)\n\tapiKey := os.Getenv(DAYTONA_API_KEY_ENV_VAR)\n\n\tif apiUrl != \"\" && apiKey != \"\" {\n\t\treturn Profile{\n\t\t\tId: \"env\",\n\t\t\tApi: ServerApi{\n\t\t\t\tUrl: apiUrl,\n\t\t\t\tKey: &apiKey,\n\t\t\t},\n\t\t}, nil\n\t}\n\n\tif len(c.Profiles) == 0 {\n\t\treturn Profile{}, ErrNoProfilesFound\n\t}\n\n\tfor _, profile := range c.Profiles {\n\t\tif profile.Id == c.ActiveProfileId {\n\t\t\treturn profile, nil\n\t\t}\n\t}\n\n\treturn Profile{}, ErrNoActiveProfile\n}\n\nvar ErrNoActiveProfile = errors.New(\"no active profile found. Run `daytona login` to authenticate\")\nvar ErrNoActiveOrganization = errors.New(\"no active organization found. Run `daytona organization use` to select an organization\")\n\nfunc (c *Config) Save() error {\n\tconfigFilePath, err := getConfigPath()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = os.MkdirAll(filepath.Dir(configFilePath), 0755)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tconfigContent, err := json.MarshalIndent(c, \"\", \"  \")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn os.WriteFile(configFilePath, configContent, 0644)\n}\n\nfunc (c *Config) AddProfile(profile Profile) error {\n\tc.Profiles = append(c.Profiles, profile)\n\tc.ActiveProfileId = profile.Id\n\n\treturn c.Save()\n}\n\nfunc (c *Config) EditProfile(profile Profile) error {\n\tfor i, p := range c.Profiles {\n\t\tif p.Id == profile.Id {\n\t\t\tc.Profiles[i] = profile\n\n\t\t\treturn c.Save()\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"profile with id %s not found\", profile.Id)\n}\n\nfunc (c *Config) RemoveProfile(profileId string) error {\n\tif c.ActiveProfileId == profileId {\n\t\treturn errors.New(\"cannot remove active profile\")\n\t}\n\n\tvar profiles []Profile\n\tfor _, profile := range c.Profiles {\n\t\tif profile.Id != profileId {\n\t\t\tprofiles = append(profiles, profile)\n\t\t}\n\t}\n\n\tc.Profiles = profiles\n\n\treturn c.Save()\n}\n\nfunc (c *Config) GetProfile(profileId string) (Profile, error) {\n\tfor _, profile := range c.Profiles {\n\t\tif profile.Id == profileId {\n\t\t\treturn profile, nil\n\t\t}\n\t}\n\n\treturn Profile{}, errors.New(\"profile not found\")\n}\n\nfunc getConfigPath() (string, error) {\n\tconfigDir, err := GetConfigDir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn filepath.Join(configDir, \"config.json\"), nil\n}\n\nfunc GetConfigDir() (string, error) {\n\tdaytonaConfigDir := os.Getenv(\"DAYTONA_CONFIG_DIR\")\n\tif daytonaConfigDir != \"\" {\n\t\treturn daytonaConfigDir, nil\n\t}\n\n\tuserConfigDir, err := os.UserConfigDir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn filepath.Join(userConfigDir, \"daytona\"), nil\n}\n\nfunc DeleteConfigDir() error {\n\tconfigDir, err := GetConfigDir()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn os.RemoveAll(configDir)\n}\n\nfunc GetActiveOrganizationId() (string, error) {\n\tc, err := GetConfig()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tactiveProfile, err := c.GetActiveProfile()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif activeProfile.ActiveOrganizationId == nil {\n\t\treturn \"\", ErrNoActiveOrganization\n\t}\n\n\treturn *activeProfile.ActiveOrganizationId, nil\n}\n\nfunc IsApiKeyAuth() bool {\n\tc, err := GetConfig()\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tactiveProfile, err := c.GetActiveProfile()\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn activeProfile.Api.Key != nil && activeProfile.Api.Token == nil\n}\n\nfunc GetAuth0Domain() string {\n\tauth0Domain := os.Getenv(\"DAYTONA_AUTH0_DOMAIN\")\n\tif auth0Domain == \"\" {\n\t\tauth0Domain = internal.Auth0Domain\n\t}\n\n\treturn auth0Domain\n}\n\nfunc GetAuth0ClientId() string {\n\tauth0ClientId := os.Getenv(\"DAYTONA_AUTH0_CLIENT_ID\")\n\tif auth0ClientId == \"\" {\n\t\tauth0ClientId = internal.Auth0ClientId\n\t}\n\n\treturn auth0ClientId\n}\n\nfunc GetAuth0ClientSecret() string {\n\tauth0ClientSecret := os.Getenv(\"DAYTONA_AUTH0_CLIENT_SECRET\")\n\tif auth0ClientSecret == \"\" {\n\t\tauth0ClientSecret = internal.Auth0ClientSecret\n\t}\n\n\treturn auth0ClientSecret\n}\n\nfunc GetAuth0CallbackPort() string {\n\tauth0CallbackPort := os.Getenv(\"DAYTONA_AUTH0_CALLBACK_PORT\")\n\tif auth0CallbackPort == \"\" {\n\t\tauth0CallbackPort = internal.Auth0CallbackPort\n\t}\n\n\treturn auth0CallbackPort\n}\n\nfunc GetAuth0Audience() string {\n\tauth0Audience := os.Getenv(\"DAYTONA_AUTH0_AUDIENCE\")\n\tif auth0Audience == \"\" {\n\t\tauth0Audience = internal.Auth0Audience\n\t}\n\n\treturn auth0Audience\n}\n\nfunc GetDaytonaApiUrl() string {\n\tdaytonaApiUrl := os.Getenv(\"DAYTONA_API_URL\")\n\tif daytonaApiUrl == \"\" {\n\t\tdaytonaApiUrl = internal.DaytonaApiUrl\n\t}\n\n\treturn daytonaApiUrl\n}\n\nfunc GetToolboxProxyUrl(region string) (string, error) {\n\tc, err := GetConfig()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tactiveProfile, err := c.GetActiveProfile()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif activeProfile.ToolboxProxyUrls == nil {\n\t\treturn \"\", nil\n\t}\n\n\treturn activeProfile.ToolboxProxyUrls[region], nil\n}\n\nfunc SetToolboxProxyUrl(region, url string) error {\n\tc, err := GetConfig()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Find and update the active profile\n\tfor i, profile := range c.Profiles {\n\t\tif profile.Id == c.ActiveProfileId {\n\t\t\tif c.Profiles[i].ToolboxProxyUrls == nil {\n\t\t\t\tc.Profiles[i].ToolboxProxyUrls = make(map[string]string)\n\t\t\t}\n\t\t\tc.Profiles[i].ToolboxProxyUrls[region] = url\n\t\t\treturn c.Save()\n\t\t}\n\t}\n\n\treturn ErrNoActiveProfile\n}\n"
  },
  {
    "path": "apps/cli/docker/build.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"slices\"\n\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/client\"\n)\n\nfunc ImageExistsLocally(ctx context.Context, dockerClient *client.Client, imageName string) (bool, error) {\n\timages, err := dockerClient.ImageList(ctx, image.ListOptions{})\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"failed to list images: %w\", err)\n\t}\n\n\tfor _, image := range images {\n\t\tfor _, tag := range image.RepoTags {\n\t\t\tif tag == imageName {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn false, nil\n}\n\nfunc CheckAmdArchitecture(ctx context.Context, dockerClient *client.Client, imageName string) (bool, error) {\n\tinspect, err := dockerClient.ImageInspect(ctx, imageName)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"failed to inspect image: %w\", err)\n\t}\n\n\tx64Architectures := []string{\"amd64\", \"x86_64\"}\n\n\tif slices.Contains(x64Architectures, inspect.Architecture) {\n\t\treturn true, nil\n\t}\n\n\treturn false, nil\n}\n"
  },
  {
    "path": "apps/cli/docs/daytona.md",
    "content": "## daytona\n\nDaytona CLI\n\n### Synopsis\n\nCommand line interface for Daytona Sandboxes\n\n```\ndaytona [flags]\n```\n\n### Options\n\n```\n      --help      help for daytona\n  -v, --version   Display the version of Daytona\n```\n\n### SEE ALSO\n\n* [daytona archive](daytona_archive.md)  - Archive a sandbox\n* [daytona autocomplete](daytona_autocomplete.md)  - Adds a completion script for your shell environment\n* [daytona create](daytona_create.md)  - Create a new sandbox\n* [daytona delete](daytona_delete.md)  - Delete a sandbox\n* [daytona docs](daytona_docs.md)  - Opens the Daytona documentation in your default browser.\n* [daytona exec](daytona_exec.md)  - Execute a command in a sandbox\n* [daytona info](daytona_info.md)  - Get sandbox info\n* [daytona list](daytona_list.md)  - List sandboxes\n* [daytona login](daytona_login.md)  - Log in to Daytona\n* [daytona logout](daytona_logout.md)  - Logout from Daytona\n* [daytona mcp](daytona_mcp.md)  - Manage Daytona MCP Server\n* [daytona organization](daytona_organization.md)  - Manage Daytona organizations\n* [daytona preview-url](daytona_preview-url.md)  - Get signed preview URL for a sandbox port\n* [daytona snapshot](daytona_snapshot.md)  - Manage Daytona snapshots\n* [daytona ssh](daytona_ssh.md)  - SSH into a sandbox\n* [daytona start](daytona_start.md)  - Start a sandbox\n* [daytona stop](daytona_stop.md)  - Stop a sandbox\n* [daytona version](daytona_version.md)  - Print the version number\n* [daytona volume](daytona_volume.md)  - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/docs/daytona_archive.md",
    "content": "## daytona archive\n\nArchive a sandbox\n\n```\ndaytona archive [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_autocomplete.md",
    "content": "## daytona autocomplete\n\nAdds a completion script for your shell environment\n\n```\ndaytona autocomplete [bash|zsh|fish|powershell] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_create.md",
    "content": "## daytona create\n\nCreate a new sandbox\n\n```\ndaytona create [flags]\n```\n\n### Options\n\n```\n      --auto-archive int32          Auto-archive interval in minutes (0 means the maximum interval will be used) (default 10080)\n      --auto-delete int32           Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping) (default -1)\n      --auto-stop int32             Auto-stop interval in minutes (0 means disabled) (default 15)\n      --class string                Sandbox class type (small, medium, large)\n  -c, --context stringArray         Files or directories to include in the build context (can be specified multiple times)\n      --cpu int32                   CPU cores allocated to the sandbox\n      --disk int32                  Disk space allocated to the sandbox in GB\n  -f, --dockerfile string           Path to Dockerfile for Sandbox snapshot\n  -e, --env stringArray             Environment variables (format: KEY=VALUE)\n      --gpu int32                   GPU units allocated to the sandbox\n  -l, --label stringArray           Labels (format: KEY=VALUE)\n      --memory int32                Memory allocated to the sandbox in MB\n      --name string                 Name of the sandbox\n      --network-allow-list string   Comma-separated list of allowed CIDR network addresses for the sandbox\n      --network-block-all           Whether to block all network access for the sandbox\n      --public                      Make sandbox publicly accessible\n      --snapshot string             Snapshot to use for the sandbox\n      --target string               Target region (eu, us)\n      --user string                 User associated with the sandbox\n  -v, --volume stringArray          Volumes to mount (format: VOLUME_NAME:MOUNT_PATH)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_delete.md",
    "content": "## daytona delete\n\nDelete a sandbox\n\n```\ndaytona delete [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n### Options\n\n```\n  -a, --all   Delete all sandboxes\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_docs.md",
    "content": "## daytona docs\n\nOpens the Daytona documentation in your default browser.\n\n```\ndaytona docs [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_exec.md",
    "content": "## daytona exec\n\nExecute a command in a sandbox\n\n### Synopsis\n\nExecute a command in a running sandbox\n\n```\ndaytona exec [SANDBOX_ID | SANDBOX_NAME] -- [COMMAND] [ARGS...] [flags]\n```\n\n### Options\n\n```\n      --cwd string    Working directory for command execution\n      --timeout int   Command timeout in seconds (0 for no timeout)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_info.md",
    "content": "## daytona info\n\nGet sandbox info\n\n```\ndaytona info [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n### Options\n\n```\n  -f, --format string   Output format. Must be one of (yaml, json)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_list.md",
    "content": "## daytona list\n\nList sandboxes\n\n```\ndaytona list [flags]\n```\n\n### Options\n\n```\n  -f, --format string   Output format. Must be one of (yaml, json)\n  -l, --limit int       Maximum number of items per page (default 100)\n  -p, --page int        Page number for pagination (starting from 1) (default 1)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_login.md",
    "content": "## daytona login\n\nLog in to Daytona\n\n```\ndaytona login [flags]\n```\n\n### Options\n\n```\n      --api-key string   API key to use for authentication\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_logout.md",
    "content": "## daytona logout\n\nLogout from Daytona\n\n```\ndaytona logout [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_mcp.md",
    "content": "## daytona mcp\n\nManage Daytona MCP Server\n\n### Synopsis\n\nCommands for managing Daytona MCP Server\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n* [daytona mcp config](daytona_mcp_config.md)  - Outputs JSON configuration for Daytona MCP Server\n* [daytona mcp init](daytona_mcp_init.md)  - Initialize Daytona MCP Server with an agent (currently supported: claude, windsurf, cursor)\n* [daytona mcp start](daytona_mcp_start.md)  - Start Daytona MCP Server\n"
  },
  {
    "path": "apps/cli/docs/daytona_mcp_config.md",
    "content": "## daytona mcp config\n\nOutputs JSON configuration for Daytona MCP Server\n\n```\ndaytona mcp config [AGENT_NAME] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona mcp](daytona_mcp.md)  - Manage Daytona MCP Server\n"
  },
  {
    "path": "apps/cli/docs/daytona_mcp_init.md",
    "content": "## daytona mcp init\n\nInitialize Daytona MCP Server with an agent (currently supported: claude, windsurf, cursor)\n\n```\ndaytona mcp init [AGENT_NAME] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona mcp](daytona_mcp.md)  - Manage Daytona MCP Server\n"
  },
  {
    "path": "apps/cli/docs/daytona_mcp_start.md",
    "content": "## daytona mcp start\n\nStart Daytona MCP Server\n\n```\ndaytona mcp start [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona mcp](daytona_mcp.md)  - Manage Daytona MCP Server\n"
  },
  {
    "path": "apps/cli/docs/daytona_organization.md",
    "content": "## daytona organization\n\nManage Daytona organizations\n\n### Synopsis\n\nCommands for managing Daytona organizations\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n* [daytona organization create](daytona_organization_create.md)  - Create a new organization and set it as active\n* [daytona organization delete](daytona_organization_delete.md)  - Delete an organization\n* [daytona organization list](daytona_organization_list.md)  - List all organizations\n* [daytona organization use](daytona_organization_use.md)  - Set active organization\n"
  },
  {
    "path": "apps/cli/docs/daytona_organization_create.md",
    "content": "## daytona organization create\n\nCreate a new organization and set it as active\n\n```\ndaytona organization create [ORGANIZATION_NAME] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona organization](daytona_organization.md)  - Manage Daytona organizations\n"
  },
  {
    "path": "apps/cli/docs/daytona_organization_delete.md",
    "content": "## daytona organization delete\n\nDelete an organization\n\n```\ndaytona organization delete [ORGANIZATION] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona organization](daytona_organization.md)  - Manage Daytona organizations\n"
  },
  {
    "path": "apps/cli/docs/daytona_organization_list.md",
    "content": "## daytona organization list\n\nList all organizations\n\n```\ndaytona organization list [flags]\n```\n\n### Options\n\n```\n  -f, --format string   Output format. Must be one of (yaml, json)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona organization](daytona_organization.md)  - Manage Daytona organizations\n"
  },
  {
    "path": "apps/cli/docs/daytona_organization_use.md",
    "content": "## daytona organization use\n\nSet active organization\n\n```\ndaytona organization use [ORGANIZATION] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona organization](daytona_organization.md)  - Manage Daytona organizations\n"
  },
  {
    "path": "apps/cli/docs/daytona_preview-url.md",
    "content": "## daytona preview-url\n\nGet signed preview URL for a sandbox port\n\n```\ndaytona preview-url [SANDBOX_ID | SANDBOX_NAME] [flags]\n```\n\n### Options\n\n```\n      --expires int32   URL expiration time in seconds (default 3600)\n  -p, --port int32      Port number to get preview URL for (required)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_snapshot.md",
    "content": "## daytona snapshot\n\nManage Daytona snapshots\n\n### Synopsis\n\nCommands for managing Daytona snapshots\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n* [daytona snapshot create](daytona_snapshot_create.md)  - Create a snapshot\n* [daytona snapshot delete](daytona_snapshot_delete.md)  - Delete a snapshot\n* [daytona snapshot list](daytona_snapshot_list.md)  - List all snapshots\n* [daytona snapshot push](daytona_snapshot_push.md)  - Push local snapshot\n"
  },
  {
    "path": "apps/cli/docs/daytona_snapshot_create.md",
    "content": "## daytona snapshot create\n\nCreate a snapshot\n\n```\ndaytona snapshot create [SNAPSHOT] [flags]\n```\n\n### Options\n\n```\n  -c, --context stringArray   Files or directories to include in the build context (can be specified multiple times). If not provided, context will be automatically determined from COPY/ADD commands in the Dockerfile\n      --cpu int32             CPU cores that will be allocated to the underlying sandboxes (default: 1)\n      --disk int32            Disk space that will be allocated to the underlying sandboxes in GB (default: 3)\n  -f, --dockerfile string     Path to Dockerfile to build\n  -e, --entrypoint string     The entrypoint command for the snapshot\n  -i, --image string          The image name for the snapshot\n      --memory int32          Memory that will be allocated to the underlying sandboxes in GB (default: 1)\n      --region string         ID of the region where the snapshot will be available (defaults to organization default region)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona snapshot](daytona_snapshot.md)  - Manage Daytona snapshots\n"
  },
  {
    "path": "apps/cli/docs/daytona_snapshot_delete.md",
    "content": "## daytona snapshot delete\n\nDelete a snapshot\n\n```\ndaytona snapshot delete [SNAPSHOT_ID] [flags]\n```\n\n### Options\n\n```\n  -a, --all   Delete all snapshots\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona snapshot](daytona_snapshot.md)  - Manage Daytona snapshots\n"
  },
  {
    "path": "apps/cli/docs/daytona_snapshot_list.md",
    "content": "## daytona snapshot list\n\nList all snapshots\n\n### Synopsis\n\nList all available Daytona snapshots\n\n```\ndaytona snapshot list [flags]\n```\n\n### Options\n\n```\n  -f, --format string   Output format. Must be one of (yaml, json)\n  -l, --limit int       Maximum number of items per page (default 100)\n  -p, --page int        Page number for pagination (starting from 1) (default 1)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona snapshot](daytona_snapshot.md)  - Manage Daytona snapshots\n"
  },
  {
    "path": "apps/cli/docs/daytona_snapshot_push.md",
    "content": "## daytona snapshot push\n\nPush local snapshot\n\n### Synopsis\n\nPush a local Docker image to Daytona. To securely build it on our infrastructure, use 'daytona snapshot build'\n\n```\ndaytona snapshot push [SNAPSHOT] [flags]\n```\n\n### Options\n\n```\n      --cpu int32           CPU cores that will be allocated to the underlying sandboxes (default: 1)\n      --disk int32          Disk space that will be allocated to the underlying sandboxes in GB (default: 3)\n  -e, --entrypoint string   The entrypoint command for the image\n      --memory int32        Memory that will be allocated to the underlying sandboxes in GB (default: 1)\n  -n, --name string         Specify the Snapshot name\n      --region string       ID of the region where the snapshot will be available (defaults to organization default region)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona snapshot](daytona_snapshot.md)  - Manage Daytona snapshots\n"
  },
  {
    "path": "apps/cli/docs/daytona_ssh.md",
    "content": "## daytona ssh\n\nSSH into a sandbox\n\n### Synopsis\n\nEstablish an SSH connection to a running sandbox\n\n```\ndaytona ssh [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n### Options\n\n```\n      --expires int   SSH access token expiration time in minutes (defaults to 24 hours) (default 1440)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_start.md",
    "content": "## daytona start\n\nStart a sandbox\n\n```\ndaytona start [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_stop.md",
    "content": "## daytona stop\n\nStop a sandbox\n\n```\ndaytona stop [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_version.md",
    "content": "## daytona version\n\nPrint the version number\n\n```\ndaytona version [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n"
  },
  {
    "path": "apps/cli/docs/daytona_volume.md",
    "content": "## daytona volume\n\nManage Daytona volumes\n\n### Synopsis\n\nCommands for managing Daytona volumes\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona](daytona.md)  - Daytona CLI\n* [daytona volume create](daytona_volume_create.md)  - Create a volume\n* [daytona volume delete](daytona_volume_delete.md)  - Delete a volume\n* [daytona volume get](daytona_volume_get.md)  - Get volume details\n* [daytona volume list](daytona_volume_list.md)  - List all volumes\n"
  },
  {
    "path": "apps/cli/docs/daytona_volume_create.md",
    "content": "## daytona volume create\n\nCreate a volume\n\n```\ndaytona volume create [NAME] [flags]\n```\n\n### Options\n\n```\n  -s, --size int32   Size of the volume in GB (default 10)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona volume](daytona_volume.md)  - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/docs/daytona_volume_delete.md",
    "content": "## daytona volume delete\n\nDelete a volume\n\n```\ndaytona volume delete [VOLUME_ID] [flags]\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona volume](daytona_volume.md)  - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/docs/daytona_volume_get.md",
    "content": "## daytona volume get\n\nGet volume details\n\n```\ndaytona volume get [VOLUME_ID] [flags]\n```\n\n### Options\n\n```\n  -f, --format string   Output format. Must be one of (yaml, json)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona volume](daytona_volume.md)  - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/docs/daytona_volume_list.md",
    "content": "## daytona volume list\n\nList all volumes\n\n```\ndaytona volume list [flags]\n```\n\n### Options\n\n```\n  -f, --format string   Output format. Must be one of (yaml, json)\n```\n\n### Options inherited from parent commands\n\n```\n      --help   help for daytona\n```\n\n### SEE ALSO\n\n* [daytona volume](daytona_volume.md)  - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/go.mod",
    "content": "module github.com/daytonaio/daytona/cli\n\ngo 1.25.4\n\nrequire (\n\tgithub.com/charmbracelet/bubbletea v1.1.0\n\tgithub.com/daytonaio/daytona/libs/api-client-go v0.153.0\n\tgithub.com/docker/docker v28.5.2+incompatible\n\tgithub.com/mark3labs/mcp-go v0.32.0\n\tgithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c\n\tgithub.com/sirupsen/logrus v1.9.3\n\tgithub.com/spf13/cobra v1.10.1\n\tgolang.org/x/oauth2 v0.34.0\n)\n\nrequire (\n\tgithub.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect\n\tgithub.com/Microsoft/go-winio v0.6.2 // indirect\n\tgithub.com/atotto/clipboard v0.1.4 // indirect\n\tgithub.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect\n\tgithub.com/catppuccin/go v0.2.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/charmbracelet/x/ansi v0.4.2 // indirect\n\tgithub.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect\n\tgithub.com/charmbracelet/x/term v0.2.0 // indirect\n\tgithub.com/containerd/errdefs v1.0.0 // indirect\n\tgithub.com/containerd/errdefs/pkg v0.3.0 // indirect\n\tgithub.com/containerd/log v0.1.0 // indirect\n\tgithub.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect\n\tgithub.com/creack/pty v1.1.23 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/docker/go-connections v0.5.0 // indirect\n\tgithub.com/docker/go-units v0.5.0 // indirect\n\tgithub.com/dustin/go-humanize v1.0.1 // indirect\n\tgithub.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/go-ini/ini v1.67.0 // indirect\n\tgithub.com/go-jose/go-jose/v4 v4.1.3 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/goccy/go-json v0.10.5 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/klauspost/compress v1.18.1 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.3.0 // indirect\n\tgithub.com/lucasb-eyer/go-colorful v1.2.0 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/mattn/go-localereader v0.0.1 // indirect\n\tgithub.com/mattn/go-runewidth v0.0.16 // indirect\n\tgithub.com/minio/crc64nvme v1.0.1 // indirect\n\tgithub.com/minio/md5-simd v1.1.2 // indirect\n\tgithub.com/mitchellh/hashstructure/v2 v2.0.2 // indirect\n\tgithub.com/moby/docker-image-spec v1.3.1 // indirect\n\tgithub.com/moby/sys/atomicwriter v0.1.0 // indirect\n\tgithub.com/moby/term v0.5.2 // indirect\n\tgithub.com/morikuni/aec v1.0.0 // indirect\n\tgithub.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect\n\tgithub.com/muesli/cancelreader v0.2.2 // indirect\n\tgithub.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.1.1 // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/rivo/uniseg v0.4.7 // indirect\n\tgithub.com/rs/xid v1.6.0 // indirect\n\tgithub.com/russross/blackfriday/v2 v2.1.0 // indirect\n\tgithub.com/sahilm/fuzzy v0.1.1 // indirect\n\tgithub.com/spf13/cast v1.7.1 // indirect\n\tgithub.com/yosida95/uritemplate/v3 v3.0.2 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect\n\tgo.opentelemetry.io/otel v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.40.0 // indirect\n\tgolang.org/x/crypto v0.47.0 // indirect\n\tgolang.org/x/net v0.49.0 // indirect\n\tgolang.org/x/sync v0.19.0 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n\tgolang.org/x/text v0.33.0 // indirect\n\tgolang.org/x/time v0.10.0 // indirect\n\tgoogle.golang.org/grpc v1.79.3 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tgotest.tools/v3 v3.5.1 // indirect\n)\n\nrequire (\n\tgithub.com/charmbracelet/bubbles v0.20.0\n\tgithub.com/charmbracelet/huh v0.6.0\n\tgithub.com/charmbracelet/lipgloss v1.0.0\n\tgithub.com/coreos/go-oidc/v3 v3.12.0\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/joho/godotenv v1.5.1\n\tgithub.com/minio/minio-go/v7 v7.0.91\n\tgithub.com/spf13/pflag v1.0.9 // indirect\n\tgolang.org/x/term v0.39.0\n\tgopkg.in/yaml.v2 v2.4.0\n)\n"
  },
  {
    "path": "apps/cli/go.sum",
    "content": "github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=\ngithub.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=\ngithub.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=\ngithub.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=\ngithub.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=\ngithub.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=\ngithub.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=\ngithub.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=\ngithub.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA=\ngithub.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=\ngithub.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=\ngithub.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=\ngithub.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c=\ngithub.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=\ngithub.com/charmbracelet/huh v0.6.0 h1:mZM8VvZGuE0hoDXq6XLxRtgfWyTI3b2jZNKh0xWmax8=\ngithub.com/charmbracelet/huh v0.6.0/go.mod h1:GGNKeWCeNzKpEOh/OJD8WBwTQjV3prFAtQPpLv+AVwU=\ngithub.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=\ngithub.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=\ngithub.com/charmbracelet/x/ansi v0.4.2 h1:0JM6Aj/g/KC154/gOP4vfxun0ff6itogDYk41kof+qk=\ngithub.com/charmbracelet/x/ansi v0.4.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=\ngithub.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q=\ngithub.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=\ngithub.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4=\ngithub.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ=\ngithub.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=\ngithub.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=\ngithub.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=\ngithub.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=\ngithub.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=\ngithub.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=\ngithub.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=\ngithub.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=\ngithub.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=\ngithub.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/daytonaio/daytona/libs/api-client-go v0.153.0 h1:OGCzMcAR9RsrPToFuKJFUdKIcynnYtQCfvGn67Z0A2s=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=\ngithub.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=\ngithub.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=\ngithub.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=\ngithub.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=\ngithub.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=\ngithub.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=\ngithub.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=\ngithub.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=\ngithub.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=\ngithub.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=\ngithub.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=\ngithub.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=\ngithub.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=\ngithub.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=\ngithub.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=\ngithub.com/mark3labs/mcp-go v0.32.0 h1:fgwmbfL2gbd67obg57OfV2Dnrhs1HtSdlY/i5fn7MU8=\ngithub.com/mark3labs/mcp-go v0.32.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=\ngithub.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=\ngithub.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=\ngithub.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=\ngithub.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY=\ngithub.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=\ngithub.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=\ngithub.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=\ngithub.com/minio/minio-go/v7 v7.0.91 h1:tWLZnEfo3OZl5PoXQwcwTAPNNrjyWwOh6cbZitW5JQc=\ngithub.com/minio/minio-go/v7 v7.0.91/go.mod h1:uvMUcGrpgeSAAI6+sD3818508nUyMULw94j2Nxku/Go=\ngithub.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=\ngithub.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=\ngithub.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=\ngithub.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=\ngithub.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=\ngithub.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=\ngithub.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=\ngithub.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=\ngithub.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=\ngithub.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=\ngithub.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=\ngithub.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=\ngithub.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=\ngithub.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=\ngithub.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=\ngithub.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a h1:2MaM6YC3mGu54x+RKAA6JiFFHlHDY1UbkxqppT7wYOg=\ngithub.com/muesli/termenv v0.15.3-0.20240618155329-98d742f6907a/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=\ngithub.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=\ngithub.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=\ngithub.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=\ngithub.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=\ngithub.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=\ngithub.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=\ngithub.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=\ngithub.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=\ngolang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=\ngolang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=\ngolang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=\ngolang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=\ngolang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=\ngolang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=\ngoogle.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=\ngotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=\n"
  },
  {
    "path": "apps/cli/hack/build.sh",
    "content": "#!/bin/bash\n# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: AGPL-3.0\n\n\n# Exit on error\nset -e\n\n# Get absolute path of script directory\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_ROOT=\"$(cd \"${SCRIPT_DIR}/../..\" && pwd)\"\nDIST_DIR=\"$(cd \"${SCRIPT_DIR}/../../..\" && pwd)\"\n\n# Environment file precedence:\n# 1. DAYTONA_ENV_FILE environment variable if set\n# 2. .env file in CLI directory\n# 3. .env file in project root\n# 4. Default values\n\nload_env_file() {\n    local env_file=\"$1\"\n    if [ -f \"$env_file\" ]; then\n        source \"$env_file\"\n        return 0\n    fi\n    return 1\n}\n\n# If --skip-env-file is passed, skip loading env files\nfor arg in \"$@\"; do\n    if [ \"$arg\" == \"--skip-env-file\" ]; then\n        echo \"Skipping loading of environment files\"\n        SKIP_ENV_FILE=true\n        break\n    fi\ndone\n\nif [ \"$SKIP_ENV_FILE\" != \"true\" ]; then\n    echo \"Loading environment files\"\n    # Try loading environment files in order of precedence\n    if [ -n \"$DAYTONA_ENV_FILE\" ]; then\n        if ! load_env_file \"$DAYTONA_ENV_FILE\"; then\n            echo \"Warning: Environment file specified by DAYTONA_ENV_FILE ($DAYTONA_ENV_FILE) not found\"\n        fi\n    elif load_env_file \"${SCRIPT_DIR}/../.env.local\"; then\n        : # Successfully loaded CLI .env\n    elif load_env_file \"${SCRIPT_DIR}/../.env\"; then\n        : # Successfully loaded CLI .env\n    elif load_env_file \"${PROJECT_ROOT}/.env.local\"; then\n        : # Successfully loaded root .env\n    elif load_env_file \"${PROJECT_ROOT}/.env\"; then\n        : # Successfully loaded root .env\n    else\n        echo \"Note: No .env file found, using default values\"\n    fi\nfi\n\n# Set default values\nDAYTONA_VERSION=${VERSION:-v0.0.0-dev}\nGOOS=${GOOS:-linux}\nGOARCH=${GOARCH:-amd64}\nCGO_ENABLED=${CGO_ENABLED:-0}\n\n# Validate required variables\nREQUIRED_VARS=(\n    \"DAYTONA_API_URL\"\n    \"DAYTONA_AUTH0_DOMAIN\"\n    \"DAYTONA_AUTH0_CLIENT_ID\"\n    \"DAYTONA_AUTH0_CALLBACK_PORT\"\n    \"DAYTONA_AUTH0_AUDIENCE\"\n)\n\nMISSING_VARS=()\nfor var in \"${REQUIRED_VARS[@]}\"; do\n    if [ -z \"${!var}\" ]; then\n        MISSING_VARS+=(\"$var\")\n    fi\ndone\n\nif [ ${#MISSING_VARS[@]} -ne 0 ]; then\n    echo \"Error: Missing required environment variables:\"\n    printf '%s\\n' \"${MISSING_VARS[@]}\"\n    exit 1\nfi\n\n# Create build directory if it doesn't exist\nmkdir -p \"${DIST_DIR}/dist/apps/cli\"\n\n# Set output filename with .exe extension for Windows\nOUTPUT_FILE=\"daytona-${GOOS}-${GOARCH}\"\nif [ \"$GOOS\" == \"windows\" ]; then\n    OUTPUT_FILE=\"${OUTPUT_FILE}.exe\"\nfi\n\n# Build the binary\necho \"Building Daytona CLI with version: $DAYTONA_VERSION\"\ngo build \\\n    -ldflags \"-X 'github.com/daytonaio/daytona/cli/internal.Version=${DAYTONA_VERSION}' \\\n    -X 'github.com/daytonaio/daytona/cli/internal.DaytonaApiUrl=${DAYTONA_API_URL}' \\\n    -X 'github.com/daytonaio/daytona/cli/internal.Auth0Domain=${DAYTONA_AUTH0_DOMAIN}' \\\n    -X 'github.com/daytonaio/daytona/cli/internal.Auth0ClientId=${DAYTONA_AUTH0_CLIENT_ID}' \\\n    -X 'github.com/daytonaio/daytona/cli/internal.Auth0ClientSecret=${DAYTONA_AUTH0_CLIENT_SECRET}' \\\n    -X 'github.com/daytonaio/daytona/cli/internal.Auth0CallbackPort=${DAYTONA_AUTH0_CALLBACK_PORT}' \\\n    -X 'github.com/daytonaio/daytona/cli/internal.Auth0Audience=${DAYTONA_AUTH0_AUDIENCE}'\" \\\n    -o \"${DIST_DIR}/dist/apps/cli/${OUTPUT_FILE}\" main.go\n\necho \"Build complete: ${DIST_DIR}/dist/apps/cli/${OUTPUT_FILE}\"\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona.yaml",
    "content": "name: daytona\nsynopsis: Daytona CLI\ndescription: Command line interface for Daytona Sandboxes\nusage: daytona [flags]\noptions:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\n  - name: version\n    shorthand: v\n    default_value: 'false'\n    usage: Display the version of Daytona\nsee_also:\n  - daytona archive - Archive a sandbox\n  - daytona autocomplete - Adds a completion script for your shell environment\n  - daytona create - Create a new sandbox\n  - daytona delete - Delete a sandbox\n  - daytona docs - Opens the Daytona documentation in your default browser.\n  - daytona exec - Execute a command in a sandbox\n  - daytona info - Get sandbox info\n  - daytona list - List sandboxes\n  - daytona login - Log in to Daytona\n  - daytona logout - Logout from Daytona\n  - daytona mcp - Manage Daytona MCP Server\n  - daytona organization - Manage Daytona organizations\n  - daytona preview-url - Get signed preview URL for a sandbox port\n  - daytona snapshot - Manage Daytona snapshots\n  - daytona ssh - SSH into a sandbox\n  - daytona start - Start a sandbox\n  - daytona stop - Stop a sandbox\n  - daytona version - Print the version number\n  - daytona volume - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_archive.yaml",
    "content": "name: daytona archive\nsynopsis: Archive a sandbox\nusage: daytona archive [SANDBOX_ID] | [SANDBOX_NAME] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_autocomplete.yaml",
    "content": "name: daytona autocomplete\nsynopsis: Adds a completion script for your shell environment\nusage: daytona autocomplete [bash|zsh|fish|powershell] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_create.yaml",
    "content": "name: daytona create\nsynopsis: Create a new sandbox\nusage: daytona create [flags]\noptions:\n  - name: auto-archive\n    default_value: '10080'\n    usage: |\n      Auto-archive interval in minutes (0 means the maximum interval will be used)\n  - name: auto-delete\n    default_value: '-1'\n    usage: |\n      Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n  - name: auto-stop\n    default_value: '15'\n    usage: Auto-stop interval in minutes (0 means disabled)\n  - name: class\n    usage: Sandbox class type (small, medium, large)\n  - name: context\n    shorthand: c\n    default_value: '[]'\n    usage: |\n      Files or directories to include in the build context (can be specified multiple times)\n  - name: cpu\n    default_value: '0'\n    usage: CPU cores allocated to the sandbox\n  - name: disk\n    default_value: '0'\n    usage: Disk space allocated to the sandbox in GB\n  - name: dockerfile\n    shorthand: f\n    usage: Path to Dockerfile for Sandbox snapshot\n  - name: env\n    shorthand: e\n    default_value: '[]'\n    usage: 'Environment variables (format: KEY=VALUE)'\n  - name: gpu\n    default_value: '0'\n    usage: GPU units allocated to the sandbox\n  - name: label\n    shorthand: l\n    default_value: '[]'\n    usage: 'Labels (format: KEY=VALUE)'\n  - name: memory\n    default_value: '0'\n    usage: Memory allocated to the sandbox in MB\n  - name: name\n    usage: Name of the sandbox\n  - name: network-allow-list\n    usage: |\n      Comma-separated list of allowed CIDR network addresses for the sandbox\n  - name: network-block-all\n    default_value: 'false'\n    usage: Whether to block all network access for the sandbox\n  - name: public\n    default_value: 'false'\n    usage: Make sandbox publicly accessible\n  - name: snapshot\n    usage: Snapshot to use for the sandbox\n  - name: target\n    usage: Target region (eu, us)\n  - name: user\n    usage: User associated with the sandbox\n  - name: volume\n    shorthand: v\n    default_value: '[]'\n    usage: 'Volumes to mount (format: VOLUME_NAME:MOUNT_PATH)'\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_delete.yaml",
    "content": "name: daytona delete\nsynopsis: Delete a sandbox\nusage: daytona delete [SANDBOX_ID] | [SANDBOX_NAME] [flags]\noptions:\n  - name: all\n    shorthand: a\n    default_value: 'false'\n    usage: Delete all sandboxes\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_docs.yaml",
    "content": "name: daytona docs\nsynopsis: Opens the Daytona documentation in your default browser.\nusage: daytona docs [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_exec.yaml",
    "content": "name: daytona exec\nsynopsis: Execute a command in a sandbox\ndescription: Execute a command in a running sandbox\nusage: daytona exec [SANDBOX_ID | SANDBOX_NAME] -- [COMMAND] [ARGS...] [flags]\noptions:\n  - name: cwd\n    usage: Working directory for command execution\n  - name: timeout\n    default_value: '0'\n    usage: Command timeout in seconds (0 for no timeout)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_info.yaml",
    "content": "name: daytona info\nsynopsis: Get sandbox info\nusage: daytona info [SANDBOX_ID] | [SANDBOX_NAME] [flags]\noptions:\n  - name: format\n    shorthand: f\n    usage: Output format. Must be one of (yaml, json)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_list.yaml",
    "content": "name: daytona list\nsynopsis: List sandboxes\nusage: daytona list [flags]\noptions:\n  - name: format\n    shorthand: f\n    usage: Output format. Must be one of (yaml, json)\n  - name: limit\n    shorthand: l\n    default_value: '100'\n    usage: Maximum number of items per page\n  - name: page\n    shorthand: p\n    default_value: '1'\n    usage: Page number for pagination (starting from 1)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_login.yaml",
    "content": "name: daytona login\nsynopsis: Log in to Daytona\nusage: daytona login [flags]\noptions:\n  - name: api-key\n    usage: API key to use for authentication\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_logout.yaml",
    "content": "name: daytona logout\nsynopsis: Logout from Daytona\nusage: daytona logout [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_mcp.yaml",
    "content": "name: daytona mcp\nsynopsis: Manage Daytona MCP Server\ndescription: Commands for managing Daytona MCP Server\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n  - daytona mcp config - Outputs JSON configuration for Daytona MCP Server\n  - 'daytona mcp init - Initialize Daytona MCP Server with an agent (currently supported: claude, windsurf, cursor)'\n  - daytona mcp start - Start Daytona MCP Server\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_mcp_config.yaml",
    "content": "name: daytona mcp config\nsynopsis: Outputs JSON configuration for Daytona MCP Server\nusage: daytona mcp config [AGENT_NAME] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona mcp - Manage Daytona MCP Server\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_mcp_init.yaml",
    "content": "name: daytona mcp init\nsynopsis: |\n  Initialize Daytona MCP Server with an agent (currently supported: claude, windsurf, cursor)\nusage: daytona mcp init [AGENT_NAME] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona mcp - Manage Daytona MCP Server\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_mcp_start.yaml",
    "content": "name: daytona mcp start\nsynopsis: Start Daytona MCP Server\nusage: daytona mcp start [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona mcp - Manage Daytona MCP Server\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_organization.yaml",
    "content": "name: daytona organization\nsynopsis: Manage Daytona organizations\ndescription: Commands for managing Daytona organizations\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n  - daytona organization create - Create a new organization and set it as active\n  - daytona organization delete - Delete an organization\n  - daytona organization list - List all organizations\n  - daytona organization use - Set active organization\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_organization_create.yaml",
    "content": "name: daytona organization create\nsynopsis: Create a new organization and set it as active\nusage: daytona organization create [ORGANIZATION_NAME] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona organization - Manage Daytona organizations\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_organization_delete.yaml",
    "content": "name: daytona organization delete\nsynopsis: Delete an organization\nusage: daytona organization delete [ORGANIZATION] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona organization - Manage Daytona organizations\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_organization_list.yaml",
    "content": "name: daytona organization list\nsynopsis: List all organizations\nusage: daytona organization list [flags]\noptions:\n  - name: format\n    shorthand: f\n    usage: Output format. Must be one of (yaml, json)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona organization - Manage Daytona organizations\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_organization_use.yaml",
    "content": "name: daytona organization use\nsynopsis: Set active organization\nusage: daytona organization use [ORGANIZATION] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona organization - Manage Daytona organizations\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_preview-url.yaml",
    "content": "name: daytona preview-url\nsynopsis: Get signed preview URL for a sandbox port\nusage: daytona preview-url [SANDBOX_ID | SANDBOX_NAME] [flags]\noptions:\n  - name: expires\n    default_value: '3600'\n    usage: URL expiration time in seconds\n  - name: port\n    shorthand: p\n    default_value: '0'\n    usage: Port number to get preview URL for (required)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_snapshot.yaml",
    "content": "name: daytona snapshot\nsynopsis: Manage Daytona snapshots\ndescription: Commands for managing Daytona snapshots\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n  - daytona snapshot create - Create a snapshot\n  - daytona snapshot delete - Delete a snapshot\n  - daytona snapshot list - List all snapshots\n  - daytona snapshot push - Push local snapshot\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_snapshot_create.yaml",
    "content": "name: daytona snapshot create\nsynopsis: Create a snapshot\nusage: daytona snapshot create [SNAPSHOT] [flags]\noptions:\n  - name: context\n    shorthand: c\n    default_value: '[]'\n    usage: |\n      Files or directories to include in the build context (can be specified multiple times). If not provided, context will be automatically determined from COPY/ADD commands in the Dockerfile\n  - name: cpu\n    default_value: '0'\n    usage: |\n      CPU cores that will be allocated to the underlying sandboxes (default: 1)\n  - name: disk\n    default_value: '0'\n    usage: |\n      Disk space that will be allocated to the underlying sandboxes in GB (default: 3)\n  - name: dockerfile\n    shorthand: f\n    usage: Path to Dockerfile to build\n  - name: entrypoint\n    shorthand: e\n    usage: The entrypoint command for the snapshot\n  - name: image\n    shorthand: i\n    usage: The image name for the snapshot\n  - name: memory\n    default_value: '0'\n    usage: |\n      Memory that will be allocated to the underlying sandboxes in GB (default: 1)\n  - name: region\n    usage: |\n      ID of the region where the snapshot will be available (defaults to organization default region)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona snapshot - Manage Daytona snapshots\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_snapshot_delete.yaml",
    "content": "name: daytona snapshot delete\nsynopsis: Delete a snapshot\nusage: daytona snapshot delete [SNAPSHOT_ID] [flags]\noptions:\n  - name: all\n    shorthand: a\n    default_value: 'false'\n    usage: Delete all snapshots\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona snapshot - Manage Daytona snapshots\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_snapshot_list.yaml",
    "content": "name: daytona snapshot list\nsynopsis: List all snapshots\ndescription: List all available Daytona snapshots\nusage: daytona snapshot list [flags]\noptions:\n  - name: format\n    shorthand: f\n    usage: Output format. Must be one of (yaml, json)\n  - name: limit\n    shorthand: l\n    default_value: '100'\n    usage: Maximum number of items per page\n  - name: page\n    shorthand: p\n    default_value: '1'\n    usage: Page number for pagination (starting from 1)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona snapshot - Manage Daytona snapshots\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_snapshot_push.yaml",
    "content": "name: daytona snapshot push\nsynopsis: Push local snapshot\ndescription: |\n  Push a local Docker image to Daytona. To securely build it on our infrastructure, use 'daytona snapshot build'\nusage: daytona snapshot push [SNAPSHOT] [flags]\noptions:\n  - name: cpu\n    default_value: '0'\n    usage: |\n      CPU cores that will be allocated to the underlying sandboxes (default: 1)\n  - name: disk\n    default_value: '0'\n    usage: |\n      Disk space that will be allocated to the underlying sandboxes in GB (default: 3)\n  - name: entrypoint\n    shorthand: e\n    usage: The entrypoint command for the image\n  - name: memory\n    default_value: '0'\n    usage: |\n      Memory that will be allocated to the underlying sandboxes in GB (default: 1)\n  - name: name\n    shorthand: 'n'\n    usage: Specify the Snapshot name\n  - name: region\n    usage: |\n      ID of the region where the snapshot will be available (defaults to organization default region)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona snapshot - Manage Daytona snapshots\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_ssh.yaml",
    "content": "name: daytona ssh\nsynopsis: SSH into a sandbox\ndescription: Establish an SSH connection to a running sandbox\nusage: daytona ssh [SANDBOX_ID] | [SANDBOX_NAME] [flags]\noptions:\n  - name: expires\n    default_value: '1440'\n    usage: |\n      SSH access token expiration time in minutes (defaults to 24 hours)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_start.yaml",
    "content": "name: daytona start\nsynopsis: Start a sandbox\nusage: daytona start [SANDBOX_ID] | [SANDBOX_NAME] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_stop.yaml",
    "content": "name: daytona stop\nsynopsis: Stop a sandbox\nusage: daytona stop [SANDBOX_ID] | [SANDBOX_NAME] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_version.yaml",
    "content": "name: daytona version\nsynopsis: Print the version number\nusage: daytona version [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_volume.yaml",
    "content": "name: daytona volume\nsynopsis: Manage Daytona volumes\ndescription: Commands for managing Daytona volumes\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona - Daytona CLI\n  - daytona volume create - Create a volume\n  - daytona volume delete - Delete a volume\n  - daytona volume get - Get volume details\n  - daytona volume list - List all volumes\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_volume_create.yaml",
    "content": "name: daytona volume create\nsynopsis: Create a volume\nusage: daytona volume create [NAME] [flags]\noptions:\n  - name: size\n    shorthand: s\n    default_value: '10'\n    usage: Size of the volume in GB\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona volume - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_volume_delete.yaml",
    "content": "name: daytona volume delete\nsynopsis: Delete a volume\nusage: daytona volume delete [VOLUME_ID] [flags]\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona volume - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_volume_get.yaml",
    "content": "name: daytona volume get\nsynopsis: Get volume details\nusage: daytona volume get [VOLUME_ID] [flags]\noptions:\n  - name: format\n    shorthand: f\n    usage: Output format. Must be one of (yaml, json)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona volume - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/hack/docs/daytona_volume_list.yaml",
    "content": "name: daytona volume list\nsynopsis: List all volumes\nusage: daytona volume list [flags]\noptions:\n  - name: format\n    shorthand: f\n    usage: Output format. Must be one of (yaml, json)\ninherited_options:\n  - name: help\n    default_value: 'false'\n    usage: help for daytona\nsee_also:\n  - daytona volume - Manage Daytona volumes\n"
  },
  {
    "path": "apps/cli/hack/generate-cli-docs.sh",
    "content": "#!/bin/bash\n# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: AGPL-3.0\n\n\n# Clean up existing documentation files\nrm -rf docs hack/docs\n\n# Generate default CLI documentation files in folder \"docs\"\ngo run main.go generate-docs\n"
  },
  {
    "path": "apps/cli/internal/buildinfo.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage internal\n\nvar (\n\tVersion           = \"v0.0.0-dev\"\n\tDaytonaApiUrl     = \"\"\n\tAuth0Domain       = \"\"\n\tAuth0ClientId     = \"\"\n\tAuth0ClientSecret = \"\"\n\tAuth0CallbackPort = \"\"\n\tAuth0Audience     = \"\"\n)\n"
  },
  {
    "path": "apps/cli/internal/cmd.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage internal\n\nconst (\n\tUSER_GROUP    = \"user\"\n\tSANDBOX_GROUP = \"sandbox\"\n)\n\nvar (\n\tSuppressVersionMismatchWarning = false\n)\n"
  },
  {
    "path": "apps/cli/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage main\n\nimport (\n\t\"os\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/daytonaio/daytona/cli/cmd\"\n\t\"github.com/daytonaio/daytona/cli/cmd/auth\"\n\t\"github.com/daytonaio/daytona/cli/cmd/mcp\"\n\t\"github.com/daytonaio/daytona/cli/cmd/organization\"\n\t\"github.com/daytonaio/daytona/cli/cmd/sandbox\"\n\t\"github.com/daytonaio/daytona/cli/cmd/snapshot\"\n\t\"github.com/daytonaio/daytona/cli/cmd/volume\"\n\t\"github.com/daytonaio/daytona/cli/internal\"\n\t\"github.com/joho/godotenv\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar rootCmd = &cobra.Command{\n\tUse:               \"daytona\",\n\tShort:             \"Daytona CLI\",\n\tLong:              \"Command line interface for Daytona Sandboxes\",\n\tDisableAutoGenTag: true,\n\tSilenceUsage:      true,\n\tSilenceErrors:     true,\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\treturn cmd.Help()\n\t},\n}\n\nfunc init() {\n\trootCmd.AddGroup(&cobra.Group{ID: internal.USER_GROUP, Title: \"User\"})\n\trootCmd.AddGroup(&cobra.Group{ID: internal.SANDBOX_GROUP, Title: \"Sandbox\"})\n\n\trootCmd.AddCommand(auth.LoginCmd)\n\trootCmd.AddCommand(auth.LogoutCmd)\n\trootCmd.AddCommand(sandbox.SandboxCmd)\n\trootCmd.AddCommand(snapshot.SnapshotsCmd)\n\trootCmd.AddCommand(volume.VolumeCmd)\n\trootCmd.AddCommand(organization.OrganizationCmd)\n\trootCmd.AddCommand(mcp.MCPCmd)\n\trootCmd.AddCommand(cmd.DocsCmd)\n\trootCmd.AddCommand(cmd.AutoCompleteCmd)\n\trootCmd.AddCommand(cmd.GenerateDocsCmd)\n\trootCmd.AddCommand(cmd.VersionCmd)\n\n\t// Add sandbox subcommands as top-level shortcuts\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.CreateCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.DeleteCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.InfoCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.ListCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.StartCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.StopCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.ArchiveCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.SSHCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.ExecCmd))\n\trootCmd.AddCommand(createSandboxShortcut(sandbox.PreviewUrlCmd))\n\n\trootCmd.CompletionOptions.HiddenDefaultCmd = true\n\trootCmd.PersistentFlags().BoolP(\"help\", \"\", false, \"help for daytona\")\n\trootCmd.Flags().BoolP(\"version\", \"v\", false, \"Display the version of Daytona\")\n\n\trootCmd.PreRun = func(command *cobra.Command, args []string) {\n\t\tversionFlag, _ := command.Flags().GetBool(\"version\")\n\t\tif versionFlag {\n\t\t\terr := cmd.VersionCmd.RunE(command, []string{})\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatal(err)\n\t\t\t}\n\t\t\tos.Exit(0)\n\t\t}\n\t}\n}\n\n// createSandboxShortcut creates a top-level shortcut for a sandbox subcommand\nfunc createSandboxShortcut(original *cobra.Command) *cobra.Command {\n\tshortcut := &cobra.Command{\n\t\tUse:     original.Use,\n\t\tShort:   original.Short,\n\t\tLong:    original.Long,\n\t\tArgs:    original.Args,\n\t\tAliases: original.Aliases,\n\t\tGroupID: internal.SANDBOX_GROUP,\n\t\tRunE:    original.RunE,\n\t}\n\tshortcut.Flags().AddFlagSet(original.Flags())\n\treturn shortcut\n}\n\nfunc main() {\n\t_ = godotenv.Load()\n\n\terr := rootCmd.Execute()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "apps/cli/mcp/README.md",
    "content": "# Daytona MCP (Model Context Protocol) Server\n\nDaytona MCP Server allows AI agents to utilize:\n\n- Daytona Sandbox Management (Create, Destroy)\n- Execute commands in Daytona Sandboxes\n- File Operations in Daytona sandboxes\n- Generate preview links for web applications running in Daytona Sandboxes\n\n## Prerequisites\n\n- Daytona account\n- Daytona CLI installed\n- A compatible AI agent (Claude Desktop App, Claude Code, Cursor, Windsurf)\n\n## Steps to Integrate Daytona MCP Server with an AI Agent\n\n1. **Install the Daytona CLI:**\n\n**Mac/Linux**\n\n```bash\nbrew install daytonaio/cli/daytona\n```\n\n**Windows**\n\n```bash\npowershell -Command \"irm https://get.daytona.io/windows | iex\"\n```\n\n2. **Log in to your Daytona account:**\n\n```bash\ndaytona login\n```\n\n3. **Initialize the Daytona MCP server with Claude Desktop/Claude Code/Cursor/Windsurf:**\n\n```bash\ndaytona mcp init [claude/cursor/windsurf]\n```\n\n4. **Open Agent App**\n\n## Integrating with Other AI Agents Apps\n\n**Run the following command to get a JSON Daytona MCP configuration which you can c/p to your agent configuration:**\n\n```bash\ndaytona mcp config\n```\n\n**Command outputs the following:**\n\n```json\n{\n  \"mcpServers\": {\n    \"daytona-mcp\": {\n      \"command\": \"daytona\",\n      \"args\": [\"mcp\", \"start\"],\n      \"env\": {\n        \"HOME\": \"${HOME}\",\n        \"PATH\": \"${HOME}:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin\"\n      },\n      \"logFile\": \"${HOME}/Library/Logs/daytona/daytona-mcp-server.log\"\n    }\n  }\n}\n```\n\nNote: if you are running Daytona MCP Server on Windows OS, add the following to the env field of the configuration:\n\n```json\n\"APPDATA\": \"${APPDATA}\"\n```\n\n**Finally, open or restart your AI agent**\n\n## Available Tools\n\n### Sandbox Management\n\n- `create_sandbox`: Create a new sandbox with Daytona\n\n  - Parameters:\n    - `id` (optional): Sandbox ID - if provided, an existing sandbox will be used, new one will be created otherwise\n    - `target` (optional): Target region of the sandbox (if not provided, default region of the organization is used)\n    - `image`: Image of the sandbox (optional)\n    - `auto_stop_interval` (default: \"15\"): Auto-stop interval in minutes (0 means disabled)\n    - `auto_archive_interval` (default: \"10080\"): Auto-archive interval in minutes (0 means the maximum interval will be used)\n    - `auto_delete_interval` (default: \"-1\"): Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n\n- `destroy_sandbox`: Destroy a sandbox with Daytona\n\n### File Operations\n\n- `upload_file`: Upload a file to the Daytona sandbox\n\n  - Files can be text or base64-encoded binary content\n  - Creates necessary parent directories automatically\n  - Files persist during the session and have appropriate permissions\n  - Supports overwrite controls and maintains original files formats\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `file_path`: Path to the file to upload\n    - `content`: Content of the file to upload\n    - `encoding`: Encoding of the file to upload\n    - `overwrite`: Overwrite the file if it already exists\n\n- `download_file`: Download a file from the Daytona sandbox\n\n  - Returns file content as text or base64 encoded image\n  - Handles special cases like matplotlib plots stored as JSON\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `file_path`: Path to the file to download\n\n- `create_folder`: Create a new folder in the Daytona sandbox\n\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `folder_path`: Path to the folder to create\n    - `mode`: Mode of the folder to create (defaults to 0755)\n\n- `get_file_info`: Get information about a file in the Daytona sandbox\n\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `file_path`: Path to the file to get information about\n\n- `list_files`: List files in a directory in the Daytona sandbox\n\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `path`: Path to the directory to list files from (defaults to current directory)\n\n- `move_file`: Move or rename a file in the Daytona sandbox\n\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `source_path`: Source path of the file to move\n    - `dest_path`: Destination path where to move the file\n\n- `delete_file`: Delete a file or directory in the Daytona sandbox\n\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `file_path`: Path to the file or directory to delete\n\n### Git Operations\n\n- `git_clone`: Clone a Git repository into the Daytona sandbox\n\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `url`: URL of the Git repository to clone\n    - `path`: Directory to clone the repository into (defaults to current directory)\n    - `branch`: Branch to clone\n    - `commit_id`: Commit ID to clone\n    - `username`: Username to clone the repository with\n    - `password`: Password to clone the repository with\n\n### Command Execution\n\n- `execute_command`: Execute shell commands in the ephemeral Daytona Linux environment\n\n  - Returns full stdout and stderr output with exit codes\n  - Commands have sandbox user permissions\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `command`: Command to execute\n\n### Preview\n\n- `preview_link`: Generate accessible preview URLs for web applications running in the Daytona sandbox\n\n  - Creates a secure tunnel to expose local ports externally without configuration\n  - Validates if a server is actually running on the specified port\n  - Provides diagnostic information for troubleshooting\n  - Supports custom descriptions and metadata for better organization of multiple services\n  - Parameters:\n    - `id` (optional): Sandbox ID\n    - `port`: Port to expose\n    - `description`: Description of the service\n    - `check_server`: Check if a server is running\n\n## Troubleshooting\n\n- **Authentication issues:** Run `daytona login` to refresh your credentials\n- **Connection errors:** Ensure that the Daytona MCP Server is properly configured\n- **Sandbox errors:** Check sandbox status with `daytona sandbox list`\n\n## Support\n\nFor more information, visit [daytona.io](https://daytona.io) or contact support at support@daytona.io.\n"
  },
  {
    "path": "apps/cli/mcp/server.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage mcp\n\nimport (\n\t\"github.com/daytonaio/daytona/cli/mcp/tools\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\t\"github.com/mark3labs/mcp-go/server\"\n)\n\ntype DaytonaMCPServer struct {\n\tserver.MCPServer\n}\n\nfunc NewDaytonaMCPServer() *DaytonaMCPServer {\n\ts := &DaytonaMCPServer{}\n\n\ts.MCPServer = *server.NewMCPServer(\n\t\t\"Daytona MCP Server\",\n\t\t\"0.0.0-dev\",\n\t\tserver.WithRecovery(),\n\t\tserver.WithPromptCapabilities(false),\n\t\tserver.WithResourceCapabilities(false, false),\n\t\tserver.WithToolCapabilities(true),\n\t\tserver.WithLogging(),\n\t)\n\n\ts.addTools()\n\n\treturn s\n}\n\nfunc (s *DaytonaMCPServer) Start() error {\n\treturn server.ServeStdio(&s.MCPServer)\n}\n\nfunc (s *DaytonaMCPServer) addTools() {\n\ts.AddTool(tools.GetCreateSandboxTool(), mcp.NewTypedToolHandler(tools.CreateSandbox))\n\ts.AddTool(tools.GetDestroySandboxTool(), mcp.NewTypedToolHandler(tools.DestroySandbox))\n\n\ts.AddTool(tools.GetFileUploadTool(), mcp.NewTypedToolHandler(tools.FileUpload))\n\ts.AddTool(tools.GetFileDownloadTool(), mcp.NewTypedToolHandler(tools.FileDownload))\n\ts.AddTool(tools.GetFileInfoTool(), mcp.NewTypedToolHandler(tools.FileInfo))\n\ts.AddTool(tools.GetListFilesTool(), mcp.NewTypedToolHandler(tools.ListFiles))\n\ts.AddTool(tools.GetMoveFileTool(), mcp.NewTypedToolHandler(tools.MoveFile))\n\ts.AddTool(tools.GetDeleteFileTool(), mcp.NewTypedToolHandler(tools.DeleteFile))\n\ts.AddTool(tools.GetCreateFolderTool(), mcp.NewTypedToolHandler(tools.CreateFolder))\n\n\ts.AddTool(tools.GetExecuteCommandTool(), mcp.NewTypedToolHandler(tools.ExecuteCommand))\n\ts.AddTool(tools.GetPreviewLinkTool(), mcp.NewTypedToolHandler(tools.PreviewLink))\n\ts.AddTool(tools.GetGitCloneTool(), mcp.NewTypedToolHandler(tools.GitClone))\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/common.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport \"github.com/daytonaio/daytona/cli/apiclient\"\n\nvar daytonaMCPHeaders map[string]string = map[string]string{\n\tapiclient.DaytonaSourceHeader: \"daytona-mcp\",\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/create_folder.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype CreateFolderArgs struct {\n\tId         *string `json:\"id,omitempty\"`\n\tFolderPath *string `json:\"folderPath,omitempty\"`\n\tMode       *string `json:\"mode,omitempty\"`\n}\n\nfunc GetCreateFolderTool() mcp.Tool {\n\treturn mcp.NewTool(\"create_folder\",\n\t\tmcp.WithDescription(\"Create a new folder in the Daytona sandbox.\"),\n\t\tmcp.WithString(\"folderPath\", mcp.Required(), mcp.Description(\"Path to the folder to create.\")),\n\t\tmcp.WithString(\"mode\", mcp.Description(\"Mode of the folder to create (defaults to 0755).\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to create the folder in.\")),\n\t)\n}\n\nfunc CreateFolder(ctx context.Context, request mcp.CallToolRequest, args CreateFolderArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\tif args.FolderPath == nil || *args.FolderPath == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"folderPath parameter is required\")\n\t}\n\n\tmode := \"0755\" // default mode\n\tif args.Mode == nil || *args.Mode == \"\" {\n\t\targs.Mode = &mode\n\t}\n\n\t// Create the folder\n\t_, err = apiClient.ToolboxAPI.CreateFolderDeprecated(ctx, *args.Id).Path(*args.FolderPath).Mode(*args.Mode).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error creating folder: %v\", err)\n\t}\n\n\tlog.Infof(\"Created folder: %s\", *args.FolderPath)\n\n\treturn mcp.NewToolResultText(fmt.Sprintf(\"Created folder: %s\", *args.FolderPath)), nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/create_sandbox.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype CreateSandboxArgs struct {\n\tId                  *string                    `json:\"id,omitempty\"`\n\tName                *string                    `json:\"name,omitempty\"`\n\tTarget              *string                    `json:\"target,omitempty\"`\n\tSnapshot            *string                    `json:\"snapshot,omitempty\"`\n\tUser                *string                    `json:\"user,omitempty\"`\n\tEnv                 *map[string]string         `json:\"env,omitempty\"`\n\tLabels              *map[string]string         `json:\"labels,omitempty\"`\n\tPublic              *bool                      `json:\"public,omitempty\"`\n\tCpu                 *int32                     `json:\"cpu,omitempty\"`\n\tGpu                 *int32                     `json:\"gpu,omitempty\"`\n\tMemory              *int32                     `json:\"memory,omitempty\"`\n\tDisk                *int32                     `json:\"disk,omitempty\"`\n\tAutoStopInterval    *int32                     `json:\"autoStopInterval,omitempty\"`\n\tAutoArchiveInterval *int32                     `json:\"autoArchiveInterval,omitempty\"`\n\tAutoDeleteInterval  *int32                     `json:\"autoDeleteInterval,omitempty\"`\n\tVolumes             *[]apiclient.SandboxVolume `json:\"volumes,omitempty\"`\n\tBuildInfo           *apiclient.CreateBuildInfo `json:\"buildInfo,omitempty\"`\n\tNetworkBlockAll     *bool                      `json:\"networkBlockAll,omitempty\"`\n\tNetworkAllowList    *string                    `json:\"networkAllowList,omitempty\"`\n}\n\nfunc GetCreateSandboxTool() mcp.Tool {\n\treturn mcp.NewTool(\"create_sandbox\",\n\t\tmcp.WithDescription(\"Create a new sandbox with Daytona\"),\n\t\tmcp.WithString(\"id\", mcp.Description(\"If a sandbox ID is provided it is first checked if it exists and is running, if so, the existing sandbox will be used. However, a model is not able to provide custom sandbox ID but only the ones Daytona commands return and should always leave ID field empty if the intention is to create a new sandbox.\")),\n\t\tmcp.WithString(\"name\", mcp.Description(\"Name of the sandbox. If not provided, the sandbox ID will be used as the name.\")),\n\t\tmcp.WithString(\"target\", mcp.DefaultString(\"us\"), mcp.Description(\"Target region of the sandbox.\")),\n\t\tmcp.WithString(\"snapshot\", mcp.Description(\"Snapshot of the sandbox (don't specify any if not explicitly instructed from user). Cannot be specified when using a build info entry.\")),\n\t\tmcp.WithString(\"user\", mcp.Description(\"User associated with the sandbox.\")),\n\t\tmcp.WithObject(\"env\", mcp.Description(\"Environment variables for the sandbox. Format: {\\\"key\\\": \\\"value\\\", \\\"key2\\\": \\\"value2\\\"}\"), mcp.AdditionalProperties(map[string]any{\"type\": \"string\"})),\n\t\tmcp.WithObject(\"labels\", mcp.Description(\"Labels for the sandbox. Format: {\\\"key\\\": \\\"value\\\", \\\"key2\\\": \\\"value2\\\"}\"), mcp.AdditionalProperties(map[string]any{\"type\": \"string\"})),\n\t\tmcp.WithBoolean(\"public\", mcp.Description(\"Whether the sandbox http preview is publicly accessible.\")),\n\t\tmcp.WithNumber(\"cpu\", mcp.Description(\"CPU cores allocated to the sandbox. Cannot specify sandbox resources when using a snapshot.\"), mcp.Max(4)),\n\t\tmcp.WithNumber(\"gpu\", mcp.Description(\"GPU units allocated to the sandbox. Cannot specify sandbox resources when using a snapshot.\"), mcp.Max(1)),\n\t\tmcp.WithNumber(\"memory\", mcp.Description(\"Memory allocated to the sandbox in GB. Cannot specify sandbox resources when using a snapshot.\"), mcp.Max(8)),\n\t\tmcp.WithNumber(\"disk\", mcp.Description(\"Disk space allocated to the sandbox in GB. Cannot specify sandbox resources when using a snapshot.\"), mcp.Max(10)),\n\t\tmcp.WithNumber(\"autoStopInterval\", mcp.DefaultNumber(15), mcp.Min(0), mcp.Description(\"Auto-stop interval in minutes (0 means disabled) for the sandbox.\")),\n\t\tmcp.WithNumber(\"autoArchiveInterval\", mcp.DefaultNumber(10080), mcp.Min(0), mcp.Description(\"Auto-archive interval in minutes (0 means the maximum interval will be used) for the sandbox.\")),\n\t\tmcp.WithNumber(\"autoDeleteInterval\", mcp.DefaultNumber(-1), mcp.Description(\"Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping) for the sandbox.\")),\n\t\tmcp.WithArray(\"volumes\", mcp.Description(\"Volumes to attach to the sandbox.\"), mcp.Items(map[string]any{\"type\": \"object\", \"properties\": map[string]any{\"volumeId\": map[string]any{\"type\": \"string\"}, \"mountPath\": map[string]any{\"type\": \"string\"}}})),\n\t\tmcp.WithObject(\"buildInfo\", mcp.Description(\"Build information for the sandbox.\"), mcp.Properties(map[string]any{\"dockerfileContent\": map[string]any{\"type\": \"string\"}, \"contextHashes\": map[string]any{\"type\": \"array\", \"items\": map[string]any{\"type\": \"string\"}}})),\n\t\tmcp.WithBoolean(\"networkBlockAll\", mcp.Description(\"Whether to block all network access to the sandbox.\")),\n\t\tmcp.WithString(\"networkAllowList\", mcp.Description(\"Comma-separated list of domains to allow network access to the sandbox.\")),\n\t)\n}\n\nfunc CreateSandbox(ctx context.Context, request mcp.CallToolRequest, args CreateSandboxArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient_cli.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tsandboxId := \"\"\n\tif args.Id != nil && *args.Id != \"\" {\n\t\tsandboxId = *args.Id\n\t}\n\n\tif sandboxId != \"\" {\n\t\tsandbox, _, err := apiClient.SandboxAPI.GetSandbox(ctx, sandboxId).Execute()\n\t\tif err == nil && sandbox.State != nil && *sandbox.State == apiclient.SANDBOXSTATE_STARTED {\n\t\t\treturn mcp.NewToolResultText(fmt.Sprintf(\"Reusing existing sandbox %s\", sandboxId)), nil\n\t\t}\n\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox %s not found or not running\", sandboxId)\n\t}\n\n\tcreateSandboxReq, err := createSandboxRequest(args)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\t// Create new sandbox with retries\n\tmaxRetries := 3\n\tretryDelay := time.Second * 2\n\n\tfor retry := range maxRetries {\n\t\tsandbox, _, err := apiClient.SandboxAPI.CreateSandbox(ctx).CreateSandbox(*createSandboxReq).Execute()\n\t\tif err != nil {\n\t\t\tif strings.Contains(err.Error(), \"Total CPU quota exceeded\") {\n\t\t\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"CPU quota exceeded. Please delete unused sandboxes or upgrade your plan\")\n\t\t\t}\n\n\t\t\tif retry == maxRetries-1 {\n\t\t\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"failed to create sandbox after %d retries: %v\", maxRetries, err)\n\t\t\t}\n\n\t\t\tlog.Infof(\"Sandbox creation failed, retrying: %v\", err)\n\n\t\t\ttime.Sleep(retryDelay)\n\t\t\tretryDelay = retryDelay * 3 / 2 // Exponential backoff\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Infof(\"Created new sandbox: %s\", sandbox.Id)\n\n\t\treturn mcp.NewToolResultText(fmt.Sprintf(\"Created new sandbox %s\", sandbox.Id)), nil\n\t}\n\n\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"failed to create sandbox after %d retries\", maxRetries)\n}\n\nfunc createSandboxRequest(args CreateSandboxArgs) (*apiclient.CreateSandbox, error) {\n\tcreateSandbox := apiclient.NewCreateSandbox()\n\n\tif args.Name != nil && *args.Name != \"\" {\n\t\tcreateSandbox.SetName(*args.Name)\n\t}\n\n\tif args.BuildInfo != nil {\n\t\tif args.Snapshot != nil && *args.Snapshot != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"cannot specify a snapshot when using a build info entry\")\n\t\t}\n\t} else {\n\t\tif args.Cpu != nil || args.Gpu != nil || args.Memory != nil || args.Disk != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot specify sandbox resources when using a snapshot\")\n\t\t}\n\t}\n\n\tif args.Snapshot != nil && *args.Snapshot != \"\" {\n\t\tcreateSandbox.SetSnapshot(*args.Snapshot)\n\t}\n\n\tif args.Target != nil && *args.Target != \"\" {\n\t\tcreateSandbox.SetTarget(*args.Target)\n\t}\n\n\tif args.AutoStopInterval != nil {\n\t\tcreateSandbox.SetAutoStopInterval(*args.AutoStopInterval)\n\t}\n\n\tif args.AutoArchiveInterval != nil {\n\t\tcreateSandbox.SetAutoArchiveInterval(*args.AutoArchiveInterval)\n\t}\n\n\tif args.AutoDeleteInterval != nil {\n\t\tcreateSandbox.SetAutoDeleteInterval(*args.AutoDeleteInterval)\n\t}\n\n\tif args.User != nil && *args.User != \"\" {\n\t\tcreateSandbox.SetUser(*args.User)\n\t}\n\n\tif args.Env != nil {\n\t\tcreateSandbox.SetEnv(*args.Env)\n\t}\n\n\tif args.Labels != nil {\n\t\tcreateSandbox.SetLabels(*args.Labels)\n\t}\n\n\tif args.Public != nil {\n\t\tcreateSandbox.SetPublic(*args.Public)\n\t}\n\n\tif args.Cpu != nil {\n\t\tcreateSandbox.SetCpu(*args.Cpu)\n\t}\n\n\tif args.Memory != nil {\n\t\tcreateSandbox.SetMemory(*args.Memory)\n\t}\n\n\tif args.Disk != nil {\n\t\tcreateSandbox.SetDisk(*args.Disk)\n\t}\n\n\tif args.Volumes != nil {\n\t\tcreateSandbox.SetVolumes(*args.Volumes)\n\t}\n\n\tif args.BuildInfo != nil {\n\t\tcreateSandbox.SetBuildInfo(*args.BuildInfo)\n\t}\n\n\tif args.NetworkBlockAll != nil {\n\t\tcreateSandbox.SetNetworkBlockAll(*args.NetworkBlockAll)\n\t}\n\n\tif args.NetworkAllowList != nil {\n\t\tcreateSandbox.SetNetworkAllowList(*args.NetworkAllowList)\n\t}\n\n\treturn createSandbox, nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/delete_file.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype DeleteFileArgs struct {\n\tId       *string `json:\"id,omitempty\"`\n\tFilePath *string `json:\"filePath,omitempty\"`\n}\n\nfunc GetDeleteFileTool() mcp.Tool {\n\treturn mcp.NewTool(\"delete_file\",\n\t\tmcp.WithDescription(\"Delete a file or directory in the Daytona sandbox.\"),\n\t\tmcp.WithString(\"filePath\", mcp.Required(), mcp.Description(\"Path to the file or directory to delete.\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to delete the file in.\")),\n\t)\n}\n\nfunc DeleteFile(ctx context.Context, request mcp.CallToolRequest, args DeleteFileArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient_cli.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\tif args.FilePath == nil || *args.FilePath == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"filePath parameter is required\")\n\t}\n\n\t// Execute delete command\n\texecResponse, _, err := apiClient.ToolboxAPI.ExecuteCommandDeprecated(ctx, *args.Id).\n\t\tExecuteRequest(*apiclient.NewExecuteRequest(fmt.Sprintf(\"rm -rf %s\", *args.FilePath))).\n\t\tExecute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error deleting file: %v\", err)\n\t}\n\n\tlog.Infof(\"Deleted file: %s\", *args.FilePath)\n\n\treturn mcp.NewToolResultText(fmt.Sprintf(\"Deleted file: %s\\nOutput: %s\", *args.FilePath, execResponse.Result)), nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/destroy_sandbox.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype DestroySandboxArgs struct {\n\tId *string `json:\"id,omitempty\"`\n}\n\nfunc GetDestroySandboxTool() mcp.Tool {\n\treturn mcp.NewTool(\"destroy_sandbox\",\n\t\tmcp.WithDescription(\"Destroy a sandbox with Daytona\"),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to destroy.\")),\n\t)\n}\n\nfunc DestroySandbox(ctx context.Context, request mcp.CallToolRequest, args DestroySandboxArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\t// Destroy sandbox with retries\n\tmaxRetries := 3\n\tretryDelay := time.Second * 2\n\n\tfor retry := range maxRetries {\n\t\t_, _, err := apiClient.SandboxAPI.DeleteSandbox(ctx, *args.Id).Execute()\n\t\tif err != nil {\n\t\t\tif retry == maxRetries-1 {\n\t\t\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"failed to destroy sandbox after %d retries: %v\", maxRetries, err)\n\t\t\t}\n\n\t\t\tlog.Infof(\"Sandbox creation failed, retrying: %v\", err)\n\n\t\t\ttime.Sleep(retryDelay)\n\t\t\tretryDelay = retryDelay * 3 / 2 // Exponential backoff\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Infof(\"Destroyed sandbox with ID: %s\", *args.Id)\n\n\t\treturn mcp.NewToolResultText(fmt.Sprintf(\"Destroyed sandbox with ID %s\", *args.Id)), nil\n\t}\n\n\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"failed to destroy sandbox after %d retries\", maxRetries)\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/download_file.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"path/filepath\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n)\n\ntype FileDownloadArgs struct {\n\tId       *string `json:\"id,omitempty\"`\n\tFilePath *string `json:\"filePath,omitempty\"`\n}\n\ntype Content struct {\n\tType string `json:\"type\"`\n\tText string `json:\"text,omitempty\"`\n\tData string `json:\"data,omitempty\"`\n}\n\nfunc GetFileDownloadTool() mcp.Tool {\n\treturn mcp.NewTool(\"file_download\",\n\t\tmcp.WithDescription(\"Download a file from the Daytona sandbox. Returns the file content either as text or as a base64 encoded image. Handles special cases like matplotlib plots stored as JSON with embedded base64 images.\"),\n\t\tmcp.WithString(\"filePath\", mcp.Required(), mcp.Description(\"Path to the file to download.\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to download the file from.\")),\n\t)\n}\n\nfunc FileDownload(ctx context.Context, request mcp.CallToolRequest, args FileDownloadArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\tif args.FilePath == nil || *args.FilePath == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"filePath parameter is required\")\n\t}\n\n\t// Download the file\n\tfile, _, err := apiClient.ToolboxAPI.DownloadFileDeprecated(ctx, *args.Id).Path(*args.FilePath).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error downloading file: %v\", err)\n\t}\n\tdefer file.Close()\n\n\t// Read file content\n\tcontent, err := io.ReadAll(file)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error reading file content: %v\", err)\n\t}\n\n\t// Process file content based on file type\n\text := filepath.Ext(*args.FilePath)\n\tvar result []Content\n\n\tswitch ext {\n\tcase \".png\", \".jpg\", \".jpeg\", \".gif\":\n\t\t// For image files, return as base64 encoded data\n\t\tresult = []Content{{\n\t\t\tType: \"image\",\n\t\t\tData: string(content),\n\t\t}}\n\tcase \".json\":\n\t\t// For JSON files, try to parse and handle special cases like matplotlib plots\n\t\tvar jsonData map[string]interface{}\n\t\tif err := json.Unmarshal(content, &jsonData); err != nil {\n\t\t\t// If not valid JSON, return as text\n\t\t\tresult = []Content{{\n\t\t\t\tType: \"text\",\n\t\t\t\tText: string(content),\n\t\t\t}}\n\t\t} else {\n\t\t\t// Check if it's a matplotlib plot\n\t\t\tif _, ok := jsonData[\"data\"]; ok {\n\t\t\t\tresult = []Content{{\n\t\t\t\t\tType: \"image\",\n\t\t\t\t\tData: jsonData[\"data\"].(string),\n\t\t\t\t}}\n\t\t\t} else {\n\t\t\t\tresult = []Content{{\n\t\t\t\t\tType: \"text\",\n\t\t\t\t\tText: string(content),\n\t\t\t\t}}\n\t\t\t}\n\t\t}\n\tdefault:\n\t\t// For all other files, return as text\n\t\tresult = []Content{{\n\t\t\tType: \"text\",\n\t\t\tText: string(content),\n\t\t}}\n\t}\n\n\t// Convert result to JSON\n\tresultJSON, err := json.Marshal(result)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error marshaling result: %v\", err)\n\t}\n\n\treturn mcp.NewToolResultText(string(resultJSON)), nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/execute_command.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype ExecuteCommandArgs struct {\n\tId      *string `json:\"id,omitempty\"`\n\tCommand *string `json:\"command,omitempty\"`\n}\n\ntype CommandResult struct {\n\tStdout    string `json:\"stdout\"`\n\tStderr    string `json:\"stderr\"`\n\tExitCode  int    `json:\"exitCode\"`\n\tErrorType string `json:\"errorType,omitempty\"`\n}\n\nfunc GetExecuteCommandTool() mcp.Tool {\n\treturn mcp.NewTool(\"execute_command\",\n\t\tmcp.WithDescription(\"Execute shell commands in the ephemeral Daytona Linux environment. Returns full stdout and stderr output with exit codes. Commands have sandbox user permissions and can install packages, modify files, and interact with running services. Always use /tmp directory. Use verbose flags where available for better output.\"),\n\t\tmcp.WithString(\"command\", mcp.Required(), mcp.Description(\"Command to execute.\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to execute the command in.\")),\n\t)\n}\n\nfunc ExecuteCommand(ctx context.Context, request mcp.CallToolRequest, args ExecuteCommandArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient_cli.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn returnCommandError(\"Sandbox ID is required\", \"SandboxError\")\n\t}\n\n\tif args.Command == nil || *args.Command == \"\" {\n\t\treturn returnCommandError(\"Command must be a non-empty string\", \"ValueError\")\n\t}\n\n\t// Process the command\n\tcommand := strings.TrimSpace(*args.Command)\n\tif strings.Contains(command, \"&&\") || strings.HasPrefix(command, \"cd \") {\n\t\t// Wrap complex commands in /bin/sh -c\n\t\tcommand = fmt.Sprintf(\"/bin/sh -c %s\", shellQuote(command))\n\t}\n\n\tlog.Infof(\"Executing command: %s\", command)\n\n\t// Execute the command\n\tresult, _, err := apiClient.ToolboxAPI.ExecuteCommandDeprecated(ctx, *args.Id).\n\t\tExecuteRequest(*apiclient.NewExecuteRequest(command)).\n\t\tExecute()\n\n\tif err != nil {\n\t\t// Classify error types\n\t\terrStr := err.Error()\n\t\tswitch {\n\t\tcase strings.Contains(errStr, \"Connection\") || strings.Contains(errStr, \"Timeout\"):\n\t\t\treturn returnCommandError(fmt.Sprintf(\"Network error during command execution: %s\", errStr), \"NetworkError\")\n\t\tcase strings.Contains(errStr, \"Unauthorized\") || strings.Contains(errStr, \"401\"):\n\t\t\treturn returnCommandError(\"Authentication failed during command execution. Please check your API key\", \"NetworkError\")\n\t\tdefault:\n\t\t\treturn returnCommandError(fmt.Sprintf(\"Command execution failed: %s\", errStr), \"CommandExecutionError\")\n\t\t}\n\t}\n\n\t// Process command output\n\tcmdResult := CommandResult{\n\t\tStdout:   strings.TrimSpace(result.Result),\n\t\tExitCode: int(result.ExitCode),\n\t}\n\n\t// Log truncated output\n\toutputLen := len(cmdResult.Stdout)\n\tlogOutput := cmdResult.Stdout\n\tif outputLen > 500 {\n\t\tlogOutput = cmdResult.Stdout[:500] + \"...\"\n\t}\n\n\tlog.Infof(\"Command completed - exit code: %d, output length: %d\", cmdResult.ExitCode, outputLen)\n\n\tlog.Debugf(\"Command output (truncated): %s\", logOutput)\n\n\t// Check for non-zero exit code\n\tif cmdResult.ExitCode > 0 {\n\t\tlog.Infof(\"Command exited with non-zero status - exit code: %d\", cmdResult.ExitCode)\n\t}\n\n\t// Convert result to JSON\n\tresultJSON, err := json.MarshalIndent(cmdResult, \"\", \"  \")\n\tif err != nil {\n\t\treturn returnCommandError(fmt.Sprintf(\"Error marshaling result: %v\", err), \"CommandExecutionError\")\n\t}\n\n\treturn mcp.NewToolResultText(string(resultJSON)), nil\n}\n\n// Helper function to return command errors in a consistent format\nfunc returnCommandError(message, errorType string) (*mcp.CallToolResult, error) {\n\treturn &mcp.CallToolResult{\n\t\tIsError: true,\n\t\tResult: mcp.Result{\n\t\t\tMeta: map[string]interface{}{\n\t\t\t\t\"Stdout\":    \"\",\n\t\t\t\t\"Stderr\":    message,\n\t\t\t\t\"ExitCode\":  -1,\n\t\t\t\t\"ErrorType\": errorType,\n\t\t\t},\n\t\t},\n\t}, nil\n}\n\n// Helper function to quote shell commands\nfunc shellQuote(s string) string {\n\t// Simple shell quoting - wrap in single quotes and escape existing single quotes\n\treturn \"'\" + strings.ReplaceAll(s, \"'\", \"'\\\"'\\\"'\") + \"'\"\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/file_info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype FileInfoArgs struct {\n\tId       *string `json:\"id,omitempty\"`\n\tFilePath *string `json:\"filePath,omitempty\"`\n}\n\nfunc GetFileInfoTool() mcp.Tool {\n\treturn mcp.NewTool(\"get_file_info\",\n\t\tmcp.WithDescription(\"Get information about a file in the Daytona sandbox.\"),\n\t\tmcp.WithString(\"filePath\", mcp.Required(), mcp.Description(\"Path to the file to get information about.\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to get the file information from.\")),\n\t)\n}\n\nfunc FileInfo(ctx context.Context, request mcp.CallToolRequest, args FileInfoArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\tif args.FilePath == nil || *args.FilePath == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"filePath parameter is required\")\n\t}\n\n\t// Get file info\n\tfileInfo, _, err := apiClient.ToolboxAPI.GetFileInfoDeprecated(ctx, *args.Id).Path(*args.FilePath).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error getting file info: %v\", err)\n\t}\n\n\t// Convert file info to JSON\n\tfileInfoJSON, err := json.MarshalIndent(fileInfo, \"\", \"  \")\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error marshaling file info: %v\", err)\n\t}\n\n\tlog.Infof(\"Retrieved file info for: %s\", *args.FilePath)\n\n\treturn mcp.NewToolResultText(string(fileInfoJSON)), nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/git_clone.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype GitCloneArgs struct {\n\tId       *string `json:\"id,omitempty\"`\n\tUrl      *string `json:\"url,omitempty\"`\n\tPath     *string `json:\"path,omitempty\"`\n\tBranch   *string `json:\"branch,omitempty\"`\n\tCommitId *string `json:\"commitId,omitempty\"`\n\tUsername *string `json:\"username,omitempty\"`\n\tPassword *string `json:\"password,omitempty\"`\n}\n\nfunc GetGitCloneTool() mcp.Tool {\n\treturn mcp.NewTool(\"git_clone\",\n\t\tmcp.WithDescription(\"Clone a Git repository into the Daytona sandbox.\"),\n\t\tmcp.WithString(\"url\", mcp.Required(), mcp.Description(\"URL of the Git repository to clone.\")),\n\t\tmcp.WithString(\"path\", mcp.Description(\"Directory to clone the repository into (defaults to current directory).\")),\n\t\tmcp.WithString(\"branch\", mcp.Description(\"Branch to clone.\")),\n\t\tmcp.WithString(\"commitId\", mcp.Description(\"Commit ID to clone.\")),\n\t\tmcp.WithString(\"username\", mcp.Description(\"Username to clone the repository with.\")),\n\t\tmcp.WithString(\"password\", mcp.Description(\"Password to clone the repository with.\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to clone the repository in.\")),\n\t)\n}\n\nfunc GitClone(ctx context.Context, request mcp.CallToolRequest, args GitCloneArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient_cli.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\tgitCloneRequest, err := getGitCloneRequest(args)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\t_, err = apiClient.ToolboxAPI.GitCloneRepositoryDeprecated(ctx, *args.Id).GitCloneRequest(*gitCloneRequest).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error cloning repository: %v\", err)\n\t}\n\n\tlog.Infof(\"Cloned repository: %s to %s\", gitCloneRequest.Url, gitCloneRequest.Path)\n\n\treturn mcp.NewToolResultText(fmt.Sprintf(\"Cloned repository: %s to %s\", gitCloneRequest.Url, gitCloneRequest.Path)), nil\n}\n\nfunc getGitCloneRequest(args GitCloneArgs) (*apiclient.GitCloneRequest, error) {\n\tgitCloneRequest := apiclient.GitCloneRequest{}\n\n\tif args.Url == nil || *args.Url == \"\" {\n\t\treturn nil, fmt.Errorf(\"url parameter is required\")\n\t}\n\n\tgitCloneRequest.Url = *args.Url\n\n\tgitCloneRequest.Path = \".\"\n\tif args.Path != nil && *args.Path != \"\" {\n\t\tgitCloneRequest.Path = *args.Path\n\t}\n\n\tif args.Branch != nil && *args.Branch != \"\" {\n\t\tgitCloneRequest.Branch = args.Branch\n\t}\n\n\tif args.CommitId != nil && *args.CommitId != \"\" {\n\t\tgitCloneRequest.CommitId = args.CommitId\n\t}\n\n\tif args.Username != nil && *args.Username != \"\" {\n\t\tgitCloneRequest.Username = args.Username\n\t}\n\n\tif args.Password != nil && *args.Password != \"\" {\n\t\tgitCloneRequest.Password = args.Password\n\t}\n\n\treturn &gitCloneRequest, nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/list_files.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype ListFilesArgs struct {\n\tId   *string `json:\"id,omitempty\"`\n\tPath *string `json:\"path,omitempty\"`\n}\n\nfunc GetListFilesTool() mcp.Tool {\n\treturn mcp.NewTool(\"list_files\",\n\t\tmcp.WithDescription(\"List files in a directory in the Daytona sandbox.\"),\n\t\tmcp.WithString(\"path\", mcp.Description(\"Path to the directory to list files from (defaults to current directory).\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to list the files from.\")),\n\t)\n}\n\nfunc ListFiles(ctx context.Context, request mcp.CallToolRequest, args ListFilesArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\t// Get directory path from request arguments (optional)\n\tdirPath := \".\"\n\tif args.Path != nil && *args.Path != \"\" {\n\t\tdirPath = *args.Path\n\t}\n\n\t// List files\n\tfiles, _, err := apiClient.ToolboxAPI.ListFilesDeprecated(ctx, *args.Id).Path(dirPath).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error listing files: %v\", err)\n\t}\n\n\t// Convert files to JSON\n\tfilesJSON, err := json.MarshalIndent(files, \"\", \"  \")\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error marshaling files: %v\", err)\n\t}\n\n\tlog.Infof(\"Listed files in directory: %s\", dirPath)\n\n\treturn mcp.NewToolResultText(string(filesJSON)), nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/move_file.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype MoveFileArgs struct {\n\tId         *string `json:\"id,omitempty\"`\n\tSourcePath *string `json:\"sourcePath,omitempty\"`\n\tDestPath   *string `json:\"destPath,omitempty\"`\n}\n\nfunc GetMoveFileTool() mcp.Tool {\n\treturn mcp.NewTool(\"move_file\",\n\t\tmcp.WithDescription(\"Move or rename a file in the Daytona sandbox.\"),\n\t\tmcp.WithString(\"sourcePath\", mcp.Required(), mcp.Description(\"Source path of the file to move.\")),\n\t\tmcp.WithString(\"destPath\", mcp.Required(), mcp.Description(\"Destination path where to move the file.\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to move the file in.\")),\n\t)\n}\n\nfunc MoveFile(ctx context.Context, request mcp.CallToolRequest, args MoveFileArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\t// Get source and destination paths from request arguments\n\tif args.SourcePath == nil || *args.SourcePath == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sourcePath parameter is required\")\n\t}\n\n\tif args.DestPath == nil || *args.DestPath == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"destPath parameter is required\")\n\t}\n\n\t_, err = apiClient.ToolboxAPI.MoveFileDeprecated(ctx, *args.Id).Source(*args.SourcePath).Destination(*args.DestPath).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error moving file: %v\", err)\n\t}\n\n\tlog.Infof(\"Moved file from %s to %s\", *args.SourcePath, *args.DestPath)\n\n\treturn mcp.NewToolResultText(fmt.Sprintf(\"Moved file from %s to %s\", *args.SourcePath, *args.DestPath)), nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/preview_link.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\tapiclient_cli \"github.com/daytonaio/daytona/cli/apiclient\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype PreviewLinkArgs struct {\n\tId          *string `json:\"id,omitempty\"`\n\tPort        *int32  `json:\"port,omitempty\"`\n\tCheckServer *bool   `json:\"checkServer,omitempty\"`\n\tDescription *string `json:\"description,omitempty\"`\n}\n\nfunc GetPreviewLinkTool() mcp.Tool {\n\treturn mcp.NewTool(\"preview_link\",\n\t\tmcp.WithDescription(\"Generate accessible preview URLs for web applications running in the Daytona sandbox. Creates a secure tunnel to expose local ports externally without configuration. Validates if a server is actually running on the specified port and provides diagnostic information for troubleshooting. Supports custom descriptions and metadata for better organization of multiple services.\"),\n\t\tmcp.WithNumber(\"port\", mcp.Required(), mcp.Description(\"Port to expose.\")),\n\t\tmcp.WithString(\"description\", mcp.Required(), mcp.Description(\"Description of the service.\")),\n\t\tmcp.WithBoolean(\"checkServer\", mcp.Required(), mcp.Description(\"Check if a server is running on the specified port.\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to generate the preview link for.\")),\n\t)\n}\n\nfunc PreviewLink(ctx context.Context, request mcp.CallToolRequest, args PreviewLinkArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient_cli.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\tif args.Port == nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"port parameter is required\")\n\t}\n\n\tcheckServer := false\n\tif args.CheckServer != nil && *args.CheckServer {\n\t\tcheckServer = *args.CheckServer\n\t}\n\n\tlog.Infof(\"Generating preview link - port: %d\", *args.Port)\n\n\t// Get the sandbox using sandbox ID\n\tsandbox, _, err := apiClient.SandboxAPI.GetSandbox(ctx, *args.Id).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"failed to get sandbox: %v\", err)\n\t}\n\n\tif sandbox == nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"no sandbox available\")\n\t}\n\n\t// Check if server is running on specified port\n\tif checkServer {\n\t\tlog.Infof(\"Checking if server is running - port: %d\", *args.Port)\n\n\t\tcheckCmd := fmt.Sprintf(\"curl -s -o /dev/null -w '%%{http_code}' http://localhost:%d --max-time 2 || echo 'error'\", *args.Port)\n\t\tresult, _, err := apiClient.ToolboxAPI.ExecuteCommandDeprecated(ctx, *args.Id).ExecuteRequest(*apiclient.NewExecuteRequest(checkCmd)).Execute()\n\t\tif err != nil {\n\t\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error checking server: %v\", err)\n\t\t}\n\n\t\tresponse := strings.TrimSpace(result.Result)\n\t\tif response == \"error\" || strings.HasPrefix(response, \"0\") {\n\t\t\tlog.Infof(\"No server detected - port: %d\", *args.Port)\n\n\t\t\t// Check what might be using the port\n\t\t\tpsCmd := fmt.Sprintf(\"ps aux | grep ':%d' | grep -v grep || echo 'No process found'\", *args.Port)\n\t\t\tpsResult, _, err := apiClient.ToolboxAPI.ExecuteCommandDeprecated(ctx, *args.Id).ExecuteRequest(*apiclient.NewExecuteRequest(psCmd)).Execute()\n\t\t\tif err != nil {\n\t\t\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error checking processes: %v\", err)\n\t\t\t}\n\n\t\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"no server detected on port %d. Process info: %s\", *args.Port, strings.TrimSpace(psResult.Result))\n\t\t}\n\t}\n\n\t// Fetch preview URL\n\tpreviewURL, _, err := apiClient.SandboxAPI.GetPortPreviewUrl(ctx, *args.Id, float32(*args.Port)).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"failed to get preview URL: %v\", err)\n\t}\n\n\t// Test URL accessibility if requested\n\tvar accessible bool\n\tvar statusCode string\n\tif checkServer {\n\t\tcheckCmd := fmt.Sprintf(\"curl -s -o /dev/null -w '%%{http_code}' %s --max-time 3 || echo 'error'\", previewURL.Url)\n\t\tresult, _, err := apiClient.ToolboxAPI.ExecuteCommandDeprecated(ctx, *args.Id).ExecuteRequest(*apiclient.NewExecuteRequest(checkCmd)).Execute()\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"Error checking preview URL: %v\", err)\n\t\t} else {\n\t\t\tresponse := strings.TrimSpace(result.Result)\n\t\t\taccessible = response != \"error\" && !strings.HasPrefix(response, \"0\")\n\t\t\tif _, err := strconv.Atoi(response); err == nil {\n\t\t\t\tstatusCode = response\n\t\t\t}\n\t\t}\n\t}\n\n\tlog.Infof(\"Preview link generated: %s\", previewURL.Url)\n\tlog.Infof(\"Accessible: %t\", accessible)\n\tlog.Infof(\"Status code: %s\", statusCode)\n\n\treturn mcp.NewToolResultText(fmt.Sprintf(\"Preview link generated: %s\", previewURL.Url)), nil\n}\n"
  },
  {
    "path": "apps/cli/mcp/tools/upload_file.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage tools\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/daytonaio/daytona/cli/apiclient\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype FileUploadArgs struct {\n\tId        *string `json:\"id,omitempty\"`\n\tFilePath  *string `json:\"filePath,omitempty\"`\n\tContent   *string `json:\"content,omitempty\"`\n\tEncoding  *string `json:\"encoding,omitempty\"`\n\tOverwrite *bool   `json:\"overwrite,omitempty\"`\n}\n\nfunc GetFileUploadTool() mcp.Tool {\n\treturn mcp.NewTool(\"file_upload\",\n\t\tmcp.WithDescription(\"Upload files to the Daytona sandbox from text or base64-encoded binary content. Creates necessary parent directories automatically and verifies successful writes. Files persist during the session and have appropriate permissions for further tool operations. Supports overwrite controls and maintains original file formats.\"),\n\t\tmcp.WithString(\"filePath\", mcp.Required(), mcp.Description(\"Path to the file to upload. Files should always be uploaded to the /tmp directory if user doesn't specify otherwise.\")),\n\t\tmcp.WithString(\"content\", mcp.Required(), mcp.Description(\"Content of the file to upload.\")),\n\t\tmcp.WithString(\"encoding\", mcp.Required(), mcp.Description(\"Encoding of the file to upload.\")),\n\t\tmcp.WithBoolean(\"overwrite\", mcp.Required(), mcp.Description(\"Overwrite the file if it already exists.\")),\n\t\tmcp.WithString(\"id\", mcp.Required(), mcp.Description(\"ID of the sandbox to upload the file to.\")),\n\t)\n}\n\nfunc FileUpload(ctx context.Context, request mcp.CallToolRequest, args FileUploadArgs) (*mcp.CallToolResult, error) {\n\tapiClient, err := apiclient.GetApiClient(nil, daytonaMCPHeaders)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif args.Id == nil || *args.Id == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"sandbox ID is required\")\n\t}\n\n\tif args.FilePath == nil || *args.FilePath == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"filePath parameter is required\")\n\t}\n\n\tif args.Content == nil || *args.Content == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"content parameter is required\")\n\t}\n\n\tif args.Encoding == nil || *args.Encoding == \"\" {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"encoding parameter is required\")\n\t}\n\n\toverwrite := false\n\tif args.Overwrite != nil && *args.Overwrite {\n\t\toverwrite = *args.Overwrite\n\t}\n\n\t// Get the sandbox using sandbox ID\n\tsandbox, _, err := apiClient.SandboxAPI.GetSandbox(ctx, *args.Id).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"failed to get sandbox: %v\", err)\n\t}\n\n\tif sandbox == nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"no sandbox available\")\n\t}\n\n\t// Check if file exists and handle overwrite\n\tif !overwrite {\n\t\tfileInfo, _, err := apiClient.ToolboxAPI.GetFileInfoDeprecated(ctx, *args.Id).Path(*args.FilePath).Execute()\n\t\tif err == nil && fileInfo != nil {\n\t\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"file '%s' already exists and overwrite=false\", *args.FilePath)\n\t\t}\n\t}\n\n\t// Prepare content based on encoding\n\tvar binaryContent []byte\n\tif *args.Encoding == \"base64\" {\n\t\tvar err error\n\t\tbinaryContent, err = base64.StdEncoding.DecodeString(*args.Content)\n\t\tif err != nil {\n\t\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"invalid base64 encoding: %v\", err)\n\t\t}\n\t} else {\n\t\t// Default is text encoding\n\t\tbinaryContent = []byte(*args.Content)\n\t}\n\n\t// Create parent directories if they don't exist\n\tparentDir := filepath.Dir(*args.FilePath)\n\tif parentDir != \"\" {\n\t\t_, err := apiClient.ToolboxAPI.CreateFolderDeprecated(ctx, *args.Id).Path(parentDir).Mode(\"0755\").Execute()\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"Error creating parent directory: %v\", err)\n\t\t\t// Continue anyway as upload might handle this\n\t\t}\n\t}\n\n\t// Upload the file\n\ttempFile, err := os.CreateTemp(\"\", \"upload-*\")\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error creating temp file: %v\", err)\n\t}\n\tdefer os.Remove(tempFile.Name()) // Clean up temp file when done\n\tdefer tempFile.Close()\n\n\t// Write content to temp file\n\tif _, err := tempFile.Write(binaryContent); err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error writing to temp file: %v\", err)\n\t}\n\n\t// Reset file pointer to beginning\n\tif _, err := tempFile.Seek(0, 0); err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error seeking temp file: %v\", err)\n\t}\n\n\t// Upload the file\n\t_, err = apiClient.ToolboxAPI.UploadFileDeprecated(ctx, *args.Id).Path(*args.FilePath).File(tempFile).Execute()\n\tif err != nil {\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error uploading file: %v\", err)\n\t}\n\n\t// Get file info for size\n\tfileInfo, _, err := apiClient.ToolboxAPI.GetFileInfoDeprecated(ctx, *args.Id).Path(*args.FilePath).Execute()\n\tif err != nil {\n\t\tlog.Errorf(\"Error getting file info after upload: %v\", err)\n\n\t\treturn &mcp.CallToolResult{IsError: true}, fmt.Errorf(\"error getting file info after upload: %v\", err)\n\t}\n\n\tfileSizeKB := float64(fileInfo.Size) / 1024\n\tlog.Infof(\"File uploaded successfully: %s, size: %.2fKB\", *args.FilePath, fileSizeKB)\n\n\treturn mcp.NewToolResultText(fmt.Sprintf(\"File uploaded successfully: %s\", *args.FilePath)), nil\n}\n"
  },
  {
    "path": "apps/cli/pkg/minio/minio.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage minio\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/minio/minio-go/v7\"\n\t\"github.com/minio/minio-go/v7/pkg/credentials\"\n)\n\nconst CONTEXT_TAR_FILE_NAME = \"context.tar\"\n\ntype Client struct {\n\tminioClient *minio.Client\n\tbucket      string\n}\n\nfunc NewClient(endpoint, accessKey, secretKey, bucket string, useSSL bool, sessionToken string) (*Client, error) {\n\tminioClient, err := minio.New(endpoint, &minio.Options{\n\t\tCreds:  credentials.NewStaticV4(accessKey, secretKey, sessionToken),\n\t\tSecure: useSSL,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create MinIO client: %w\", err)\n\t}\n\n\treturn &Client{\n\t\tminioClient: minioClient,\n\t\tbucket:      bucket,\n\t}, nil\n}\n\nfunc (c *Client) UploadFile(ctx context.Context, objectName string, data []byte) error {\n\texists, err := c.minioClient.BucketExists(ctx, c.bucket)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error checking bucket existence: %w\", err)\n\t}\n\tif !exists {\n\t\terr = c.minioClient.MakeBucket(ctx, c.bucket, minio.MakeBucketOptions{})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error creating bucket: %w\", err)\n\t\t}\n\t}\n\n\treader := bytes.NewReader(data)\n\tobjectSize := int64(len(data))\n\n\t_, err = c.minioClient.PutObject(ctx, c.bucket, objectName, reader, objectSize, minio.PutObjectOptions{\n\t\tContentType: \"application/octet-stream\",\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error uploading file: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc readIgnoreFile(rootPath, filename string) []string {\n\tignoreFile := filepath.Join(rootPath, filename)\n\tcontent, err := os.ReadFile(ignoreFile)\n\tif err != nil {\n\t\treturn nil\n\t}\n\n\tvar patterns []string\n\tlines := strings.Split(string(content), \"\\n\")\n\tfor _, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\t\t// Skip empty lines and comments\n\t\tif line == \"\" || strings.HasPrefix(line, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tpatterns = append(patterns, line)\n\t}\n\treturn patterns\n}\n\nfunc matchPattern(filePath string, patterns []string) bool {\n\tfilePath = filepath.ToSlash(filePath)\n\n\tfor _, pattern := range patterns {\n\t\tpattern = filepath.ToSlash(pattern)\n\n\t\tif strings.HasSuffix(pattern, \"/\") {\n\t\t\tpattern = strings.TrimSuffix(pattern, \"/\")\n\t\t\tif strings.HasPrefix(filePath, pattern+\"/\") || filePath == pattern {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Handle double star patterns (**) - matches any number of directories\n\t\tif strings.Contains(pattern, \"**\") {\n\t\t\t// Convert ** to a simpler pattern for basic matching\n\t\t\tparts := strings.Split(pattern, \"**\")\n\t\t\tif len(parts) == 2 {\n\t\t\t\tprefix := parts[0]\n\t\t\t\tsuffix := parts[1]\n\n\t\t\t\t// Remove trailing/leading slashes from prefix/suffix\n\t\t\t\tprefix = strings.TrimSuffix(prefix, \"/\")\n\t\t\t\tsuffix = strings.TrimPrefix(suffix, \"/\")\n\n\t\t\t\tif prefix == \"\" && suffix != \"\" {\n\t\t\t\t\t// Pattern like **/node_modules\n\t\t\t\t\tif strings.Contains(filePath, \"/\"+suffix) || strings.HasSuffix(filePath, suffix) || filePath == suffix {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t} else if prefix != \"\" && suffix == \"\" {\n\t\t\t\t\t// Pattern like .git/**\n\t\t\t\t\tif strings.HasPrefix(filePath, prefix+\"/\") || filePath == prefix {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t} else if prefix != \"\" && suffix != \"\" {\n\t\t\t\t\t// Pattern like src/**/test\n\t\t\t\t\tif strings.HasPrefix(filePath, prefix+\"/\") && (strings.Contains(filePath, \"/\"+suffix) || strings.HasSuffix(filePath, suffix)) {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.Contains(pattern, \"*\") {\n\t\t\tmatched, err := filepath.Match(pattern, filepath.Base(filePath))\n\t\t\tif err == nil && matched {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Also check full path for patterns like */node_modules\n\t\t\tmatched, err = filepath.Match(pattern, filePath)\n\t\t\tif err == nil && matched {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Handle exact matches and prefix matches\n\t\tif filePath == pattern ||\n\t\t\tstrings.HasPrefix(filePath, pattern+\"/\") ||\n\t\t\tfilepath.Base(filePath) == pattern {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc shouldExcludeFile(filePath, rootPath string) bool {\n\trelPath, err := filepath.Rel(rootPath, filePath)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tdockerignorePatterns := readIgnoreFile(rootPath, \".dockerignore\")\n\n\tif len(dockerignorePatterns) == 0 {\n\t\treturn false\n\t}\n\n\treturn matchPattern(relPath, dockerignorePatterns)\n}\n\nfunc (c *Client) ListObjects(ctx context.Context, prefix string) ([]string, error) {\n\tvar objects []string\n\n\tobjectCh := c.minioClient.ListObjects(ctx, c.bucket, minio.ListObjectsOptions{\n\t\tPrefix: prefix,\n\t})\n\n\tfor object := range objectCh {\n\t\tif object.Err != nil {\n\t\t\treturn nil, object.Err\n\t\t}\n\t\tobjects = append(objects, object.Key)\n\t}\n\n\treturn objects, nil\n}\n\nfunc (c *Client) ProcessDirectory(ctx context.Context, dirPath, orgID string, existingObjects map[string]bool) ([]string, error) {\n\t// Check if .dockerignore exists and provide helpful message if context is large\n\tdockerignoreExists := false\n\tif _, err := os.Stat(filepath.Join(dirPath, \".dockerignore\")); err == nil {\n\t\tdockerignoreExists = true\n\t}\n\n\ttarFile, err := os.Create(CONTEXT_TAR_FILE_NAME)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create tar file: %w\", err)\n\t}\n\tdefer tarFile.Close()\n\n\ttw := tar.NewWriter(tarFile)\n\tdefer tw.Close()\n\n\tfileCount := 0\n\ttotalSize := int64(0)\n\n\twarned := false\n\terr = filepath.Walk(dirPath, func(file string, fi os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif fi.Name() == CONTEXT_TAR_FILE_NAME {\n\t\t\treturn nil\n\t\t}\n\n\t\tif shouldExcludeFile(file, dirPath) {\n\t\t\trelPath, _ := filepath.Rel(dirPath, file)\n\t\t\tif fi.IsDir() {\n\t\t\t\tfmt.Printf(\"Excluding directory: %s\\n\", relPath)\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\t\t\tfmt.Printf(\"Excluding file: %s\\n\", relPath)\n\t\t\treturn nil\n\t\t}\n\n\t\theader, err := tar.FileInfoHeader(fi, fi.Name())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\trelPath, err := filepath.Rel(dirPath, file)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\theader.Name = relPath\n\n\t\tif err := tw.WriteHeader(header); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Write file contents if regular file\n\t\tif fi.Mode().IsRegular() {\n\t\t\tfileCount++\n\t\t\ttotalSize += fi.Size()\n\n\t\t\tif fileCount%1000 == 0 {\n\t\t\t\tfmt.Printf(\"Processing... %d files, %.2f MB total\\n\", fileCount, float64(totalSize)/(1024*1024))\n\t\t\t}\n\n\t\t\t// Warn if context is getting very large (only warn once)\n\t\t\tif totalSize > 100*1024*1024 && !dockerignoreExists && !warned {\n\t\t\t\tfmt.Printf(\"Warning: Context size exceeds 100MB. Consider adding a .dockerignore file to exclude unnecessary files.\\n\")\n\t\t\t\twarned = true\n\t\t\t}\n\n\t\t\tf, err := os.Open(file)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer f.Close()\n\n\t\t\t_, err = io.Copy(tw, f)\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"write too long\") {\n\t\t\treturn nil, fmt.Errorf(\"context directory is too large for tar archive. Please create a .dockerignore file to exclude large directories like .git, node_modules, dist, etc. Original error: %w\", err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to process directory: %w\", err)\n\t}\n\n\tfmt.Printf(\"Context processing complete: %d files, %.2f MB total\\n\", fileCount, float64(totalSize)/(1024*1024))\n\n\t// Seek to start of tar file before calculating hash\n\tif _, err := tarFile.Seek(0, 0); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to seek tar file: %w\", err)\n\t}\n\n\t// Calculate hash of tar contents\n\thasher := sha256.New()\n\tif _, err := io.Copy(hasher, tarFile); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to hash tar: %w\", err)\n\t}\n\thash := hex.EncodeToString(hasher.Sum(nil))\n\n\tobjectName := fmt.Sprintf(\"%s/%s\", orgID, hash)\n\tif _, exists := existingObjects[objectName]; !exists {\n\t\terr = c.CreateDirectory(ctx, objectName)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif _, err := tarFile.Seek(0, 0); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to seek tar file: %w\", err)\n\t\t}\n\n\t\ttarContent, err := io.ReadAll(tarFile)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read tar file: %w\", err)\n\t\t}\n\n\t\terr = c.UploadFile(ctx, fmt.Sprintf(\"%s/%s\", objectName, CONTEXT_TAR_FILE_NAME), tarContent)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to upload tar: %w\", err)\n\t\t}\n\n\t\tif err := os.Remove(CONTEXT_TAR_FILE_NAME); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to remove tar file: %w\", err)\n\t\t}\n\t} else {\n\t\tfmt.Printf(\"Directory %s with hash %s already exists in storage\\n\", dirPath, hash)\n\t}\n\n\treturn []string{hash}, nil\n}\n\nfunc (c *Client) ProcessFile(ctx context.Context, filePath, orgID string, existingObjects map[string]bool) (string, error) {\n\tfileContent, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to read file: %w\", err)\n\t}\n\n\thasher := sha256.New()\n\thasher.Write(fileContent)\n\thash := hex.EncodeToString(hasher.Sum(nil))\n\n\tobjectName := fmt.Sprintf(\"%s/%s\", orgID, hash)\n\tif _, exists := existingObjects[objectName]; !exists {\n\t\tvar tarBuffer bytes.Buffer\n\t\ttarWriter := tar.NewWriter(&tarBuffer)\n\n\t\tfileName := filepath.Base(filePath)\n\n\t\tfileInfo, err := os.Stat(filePath)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to stat file: %w\", err)\n\t\t}\n\n\t\theader, err := tar.FileInfoHeader(fileInfo, \"\")\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to create tar header: %w\", err)\n\t\t}\n\t\theader.Name = fileName\n\n\t\tif err := tarWriter.WriteHeader(header); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to write tar header: %w\", err)\n\t\t}\n\n\t\tif _, err := tarWriter.Write(fileContent); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to write file to tar: %w\", err)\n\t\t}\n\n\t\tif err := tarWriter.Close(); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to close tar writer: %w\", err)\n\t\t}\n\n\t\terr = c.CreateDirectory(ctx, objectName)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\t// Upload tar file instead of raw content\n\t\terr = c.UploadFile(ctx, fmt.Sprintf(\"%s/%s\", objectName, CONTEXT_TAR_FILE_NAME), tarBuffer.Bytes())\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t} else {\n\t\tfmt.Printf(\"File %s with hash %s already exists in storage - skipping\\n\", filePath, hash)\n\t}\n\n\treturn hash, nil\n}\n\nfunc (c *Client) CreateDirectory(ctx context.Context, directoryPath string) error {\n\texists, err := c.minioClient.BucketExists(ctx, c.bucket)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error checking bucket existence: %w\", err)\n\t}\n\tif !exists {\n\t\treturn fmt.Errorf(\"bucket does not exist\")\n\t}\n\n\t// Ensure the directory path ends with a slash to represent a directory\n\tif !strings.HasSuffix(directoryPath, \"/\") {\n\t\tdirectoryPath = directoryPath + \"/\"\n\t}\n\n\t// Create an empty object to represent the directory\n\temptyContent := []byte{}\n\treader := bytes.NewReader(emptyContent)\n\t_, err = c.minioClient.PutObject(ctx, c.bucket, directoryPath, reader, 0, minio.PutObjectOptions{\n\t\tContentType: \"application/directory\",\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating directory marker: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/cli/project.json",
    "content": "{\n  \"name\": \"cli\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"application\",\n  \"sourceRoot\": \"apps/cli\",\n  \"tags\": [],\n  \"targets\": {\n    \"build\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"inputs\": [\"goProduction\"],\n      \"options\": {\n        \"main\": \"{projectRoot}/main.go\",\n        \"outputPath\": \"dist/apps/cli/cli\"\n      }\n    },\n    \"format\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cd {projectRoot} && go fmt ./... && prettier --write \\\"**/*.{yaml,html}\\\"\"\n      }\n    },\n    \"test\": {\n      \"executor\": \"@nx-go/nx-go:test\"\n    },\n    \"lint\": {\n      \"executor\": \"@nx-go/nx-go:lint\"\n    }\n  }\n}\n"
  },
  {
    "path": "apps/cli/toolbox/toolbox.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage toolbox\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/daytona/cli/config\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\ntype ExecuteRequest struct {\n\tCommand string   `json:\"command\"`\n\tCwd     *string  `json:\"cwd,omitempty\"`\n\tTimeout *float32 `json:\"timeout,omitempty\"`\n}\n\ntype ExecuteResponse struct {\n\tExitCode float32 `json:\"exitCode\"`\n\tResult   string  `json:\"result\"`\n}\n\ntype Client struct {\n\tapiClient *apiclient.APIClient\n}\n\nfunc NewClient(apiClient *apiclient.APIClient) *Client {\n\treturn &Client{\n\t\tapiClient: apiClient,\n\t}\n}\n\n// Gets the toolbox proxy URL for a sandbox, caching by region in config\nfunc (c *Client) getProxyURL(ctx context.Context, sandboxId, region string) (string, error) {\n\t// Check config cache first\n\tcachedURL, err := config.GetToolboxProxyUrl(region)\n\tif err == nil && cachedURL != \"\" {\n\t\treturn cachedURL, nil\n\t}\n\n\t// Fetch from API\n\ttoolboxProxyUrl, _, err := c.apiClient.SandboxAPI.GetToolboxProxyUrl(ctx, sandboxId).Execute()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get toolbox proxy URL: %w\", err)\n\t}\n\n\t// Best-effort caching\n\t_ = config.SetToolboxProxyUrl(region, toolboxProxyUrl.Url)\n\n\treturn toolboxProxyUrl.Url, nil\n}\n\nfunc (c *Client) ExecuteCommand(ctx context.Context, sandbox *apiclient.Sandbox, request ExecuteRequest) (*ExecuteResponse, error) {\n\tproxyURL, err := c.getProxyURL(ctx, sandbox.Id, sandbox.Target)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn c.executeCommandViaProxy(ctx, proxyURL, sandbox.Id, request)\n}\n\n// TODO: replace this with the toolbox api client at some point\nfunc (c *Client) executeCommandViaProxy(ctx context.Context, proxyURL, sandboxId string, request ExecuteRequest) (*ExecuteResponse, error) {\n\t// Build the URL: {proxyUrl}/{sandboxId}/process/execute\n\turl := fmt.Sprintf(\"%s/%s/process/execute\", strings.TrimSuffix(proxyURL, \"/\"), sandboxId)\n\n\tbody, err := json.Marshal(request)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to marshal request: %w\", err)\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, \"POST\", url, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tcfg, err := config.GetConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tactiveProfile, err := cfg.GetActiveProfile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif activeProfile.Api.Key != nil {\n\t\treq.Header.Set(\"Authorization\", \"Bearer \"+*activeProfile.Api.Key)\n\t} else if activeProfile.Api.Token != nil {\n\t\treq.Header.Set(\"Authorization\", \"Bearer \"+activeProfile.Api.Token.AccessToken)\n\t}\n\n\tif activeProfile.ActiveOrganizationId != nil {\n\t\treq.Header.Set(\"X-Daytona-Organization-ID\", *activeProfile.ActiveOrganizationId)\n\t}\n\n\tclient := &http.Client{}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to execute request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\trespBody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read response: %w\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"request failed with status %d: %s\", resp.StatusCode, string(respBody))\n\t}\n\n\tvar response ExecuteResponse\n\tif err := json.Unmarshal(respBody, &response); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse response: %w\", err)\n\t}\n\n\treturn &response, nil\n}\n"
  },
  {
    "path": "apps/cli/util/pointer.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\n// Use generics to create a pointer to a value\nfunc Pointer[T any](d T) *T {\n\treturn &d\n}\n"
  },
  {
    "path": "apps/cli/views/common/common.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/huh\"\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\nvar DefaultLayoutMarginTop = 1\n\nvar DefaultHorizontalMargin = 1\n\nvar TUITableMinimumWidth = 80\n\nvar SeparatorString = lipgloss.NewStyle().Foreground(LightGray).Render(\"===\")\n\nvar Checkmark = lipgloss.NewStyle().Foreground(lipgloss.Color(\"42\")).SetString(\"✓\").String()\n\nvar (\n\tminimumWidth     = 40\n\tmaximumWidth     = 160\n\twidthBreakpoints = []int{60, 80, 100, 120, 140, 160}\n)\n\nfunc RenderMainTitle(title string) {\n\tfmt.Println(lipgloss.NewStyle().Foreground(Green).Bold(true).Padding(1, 0, 1, 0).Render(title))\n}\n\nfunc RenderTip(message string) {\n\tfmt.Println(lipgloss.NewStyle().Padding(0, 0, 1, 1).Render(message))\n}\n\nfunc RenderInfoMessage(message string) {\n\tfmt.Println(lipgloss.NewStyle().PaddingLeft(1).Render(message))\n}\n\nfunc RenderInfoMessageBold(message string) {\n\tfmt.Println(lipgloss.NewStyle().Bold(true).Padding(1, 0, 1, 1).Render(message))\n}\n\nfunc GetStyledMainTitle(content string) string {\n\treturn lipgloss.NewStyle().Foreground(Dark).Background(Light).Padding(0, 1).MarginTop(1).Render(content)\n}\n\nfunc GetInfoMessage(message string) string {\n\treturn lipgloss.NewStyle().Padding(1, 0, 1, 1).Render(message)\n}\n\nfunc GetContainerBreakpointWidth(terminalWidth int) int {\n\tif terminalWidth < minimumWidth {\n\t\treturn 0\n\t}\n\tfor _, width := range widthBreakpoints {\n\t\tif terminalWidth < width {\n\t\t\treturn width - 20 - DefaultHorizontalMargin - DefaultHorizontalMargin\n\t\t}\n\t}\n\treturn maximumWidth\n}\n\nfunc GetEnvVarsInput(envVars *map[string]string) *huh.Text {\n\tif envVars == nil {\n\t\treturn nil\n\t}\n\n\tvar inputText string\n\tfor key, value := range *envVars {\n\t\tinputText += fmt.Sprintf(\"%s=%s\\n\", key, value)\n\t}\n\tinputText = strings.TrimSuffix(inputText, \"\\n\")\n\n\treturn huh.NewText().\n\t\tTitle(\"Environment Variables\").\n\t\tDescription(\"Enter environment variables in the format KEY=VALUE\\nTo pass machine env variables at runtime, use $VALUE\").\n\t\tCharLimit(-1).\n\t\tValue(&inputText).\n\t\tValidate(func(str string) error {\n\t\t\ttempEnvVars := map[string]string{}\n\t\t\tfor i, line := range strings.Split(str, \"\\n\") {\n\t\t\t\tif line == \"\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tparts := strings.SplitN(line, \"=\", 2)\n\t\t\t\tif len(parts) != 2 {\n\t\t\t\t\treturn fmt.Errorf(\"invalid format: %s on line %d\", line, i+1)\n\t\t\t\t}\n\n\t\t\t\ttempEnvVars[parts[0]] = parts[1]\n\t\t\t}\n\t\t\t*envVars = tempEnvVars\n\n\t\t\treturn nil\n\t\t})\n}\n\n// Bolds the message and prepends a checkmark\nfunc GetPrettyLogLine(message string) string {\n\treturn fmt.Sprintf(\"%s \\033[1m%s\\033[0m\\n\", lipgloss.NewStyle().Foreground(lipgloss.Color(\"42\")).SetString(\"✓\").String(), message)\n}\n"
  },
  {
    "path": "apps/cli/views/common/prompt.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/bubbles/textinput\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\ntype promptModel struct {\n\ttextInput textinput.Model\n\terr       error\n\tdone      bool\n\ttitle     string\n\tdesc      string\n}\n\nfunc (m promptModel) Init() tea.Cmd {\n\treturn textinput.Blink\n}\n\nfunc (m promptModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {\n\tvar cmd tea.Cmd\n\n\tswitch msg := msg.(type) {\n\tcase tea.KeyMsg:\n\t\tswitch msg.Type {\n\t\tcase tea.KeyEnter:\n\t\t\tm.done = true\n\t\t\treturn m, tea.Quit\n\t\tcase tea.KeyCtrlC:\n\t\t\tm.done = true\n\t\t\tm.err = fmt.Errorf(\"user cancelled\")\n\t\t\treturn m, tea.Quit\n\t\t}\n\t}\n\n\tm.textInput, cmd = m.textInput.Update(msg)\n\treturn m, cmd\n}\n\nfunc (m promptModel) View() string {\n\tif m.done {\n\t\treturn \"\"\n\t}\n\n\ttitleStyle := lipgloss.NewStyle().\n\t\tBold(true).\n\t\tMarginLeft(2).\n\t\tMarginTop(1)\n\n\tdescStyle := lipgloss.NewStyle().\n\t\tForeground(lipgloss.Color(\"241\")).\n\t\tMarginLeft(2)\n\n\treturn fmt.Sprintf(\"\\n%s\\n%s\\n\\n %s\\n\\n\",\n\t\ttitleStyle.Render(m.title),\n\t\tdescStyle.Render(m.desc),\n\t\tm.textInput.View())\n}\n\nfunc PromptForInput(prompt, title, desc string) (string, error) {\n\tti := textinput.New()\n\tti.Focus()\n\tti.CharLimit = 156\n\tti.Width = 80\n\tti.Prompt = \"› \"\n\n\tm := promptModel{\n\t\ttextInput: ti,\n\t\ttitle:     title,\n\t\tdesc:      desc,\n\t}\n\n\tp := tea.NewProgram(m, tea.WithAltScreen())\n\tmodel, err := p.Run()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error running prompt: %w\", err)\n\t}\n\n\tfinalModel, ok := model.(promptModel)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"could not read model state\")\n\t}\n\n\tif finalModel.err != nil {\n\t\treturn \"\", finalModel.err\n\t}\n\n\treturn strings.TrimSpace(finalModel.textInput.Value()), nil\n}\n"
  },
  {
    "path": "apps/cli/views/common/select.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\n// SelectItem represents an item in the selection list\ntype SelectItem struct {\n\tTitle string\n\tDesc  string\n}\n\n// SelectModel represents the selection UI model\ntype SelectModel struct {\n\tTitle    string\n\tItems    []SelectItem\n\tSelected int\n\tChoice   string\n\tQuitting bool\n}\n\n// NewSelectModel creates a new select model with the given title and items\nfunc NewSelectModel(title string, items []SelectItem) SelectModel {\n\treturn SelectModel{\n\t\tTitle:    title,\n\t\tItems:    items,\n\t\tSelected: 0,\n\t}\n}\n\nfunc (m SelectModel) Init() tea.Cmd {\n\treturn nil\n}\n\nfunc (m SelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {\n\tswitch msg := msg.(type) {\n\tcase tea.KeyMsg:\n\t\tswitch msg.String() {\n\t\tcase \"ctrl+c\":\n\t\t\tm.Quitting = true\n\t\t\treturn m, tea.Quit\n\t\tcase \"up\", \"k\":\n\t\t\tif m.Selected > 0 {\n\t\t\t\tm.Selected--\n\t\t\t}\n\t\tcase \"down\", \"j\":\n\t\t\tif m.Selected < len(m.Items)-1 {\n\t\t\t\tm.Selected++\n\t\t\t}\n\t\tcase \"enter\":\n\t\t\tm.Choice = m.Items[m.Selected].Title\n\t\t\treturn m, tea.Quit\n\t\t}\n\t}\n\treturn m, nil\n}\n\nfunc (m SelectModel) View() string {\n\tif m.Quitting {\n\t\treturn \"\"\n\t}\n\n\ts := lipgloss.NewStyle().\n\t\tBold(true).\n\t\tMarginLeft(2).\n\t\tMarginTop(1).\n\t\tRender(m.Title) + \"\\n\\n\"\n\n\tfor i, item := range m.Items {\n\t\tcursor := \"  \"\n\t\tstyle := lipgloss.NewStyle().\n\t\t\tForeground(lipgloss.Color(\"151\")).\n\t\t\tPaddingLeft(2)\n\n\t\tif i == m.Selected {\n\t\t\tcursor = \"› \"\n\t\t\tstyle = style.Foreground(lipgloss.Color(\"42\")).Bold(true)\n\t\t}\n\n\t\ts += style.Render(cursor+item.Title) + \"\\n\"\n\t\ts += lipgloss.NewStyle().\n\t\t\tPaddingLeft(4).\n\t\t\tForeground(lipgloss.Color(\"241\")).\n\t\t\tRender(item.Desc) + \"\\n\\n\"\n\t}\n\n\treturn s\n}\n\n// Select displays a selection prompt with the given title and items\n// Returns the selected item's title and any error that occurred\nfunc Select(title string, items []SelectItem) (string, error) {\n\tp := tea.NewProgram(NewSelectModel(title, items), tea.WithAltScreen())\n\tm, err := p.Run()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tfinalModel, ok := m.(SelectModel)\n\tif !ok {\n\t\treturn \"\", nil\n\t}\n\n\tif finalModel.Quitting {\n\t\treturn \"\", nil\n\t}\n\n\treturn finalModel.Choice, nil\n}\n"
  },
  {
    "path": "apps/cli/views/common/styles.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/charmbracelet/bubbles/list\"\n\t\"github.com/charmbracelet/huh\"\n\t\"github.com/charmbracelet/lipgloss\"\n)\n\nvar (\n\tListNavigationText       = \"load more\"\n\tListNavigationRenderText = \"+ Load more..\"\n)\n\nvar (\n\tGreen       = lipgloss.AdaptiveColor{Light: \"#23cc71\", Dark: \"#23cc71\"}\n\tBlue        = lipgloss.AdaptiveColor{Light: \"#017ffe\", Dark: \"#017ffe\"}\n\tYellow      = lipgloss.AdaptiveColor{Light: \"#d4ed2d\", Dark: \"#d4ed2d\"}\n\tCyan        = lipgloss.AdaptiveColor{Light: \"#3ef7e5\", Dark: \"#3ef7e5\"}\n\tDimmedGreen = lipgloss.AdaptiveColor{Light: \"#7be0a9\", Dark: \"#7be0a9\"}\n\tOrange      = lipgloss.AdaptiveColor{Light: \"#e3881b\", Dark: \"#e3881b\"}\n\tLight       = lipgloss.AdaptiveColor{Light: \"#000\", Dark: \"#fff\"}\n\tDark        = lipgloss.AdaptiveColor{Light: \"#fff\", Dark: \"#000\"}\n\tGray        = lipgloss.AdaptiveColor{Light: \"243\", Dark: \"243\"}\n\tLightGray   = lipgloss.AdaptiveColor{Light: \"#828282\", Dark: \"#828282\"}\n\tRed         = lipgloss.AdaptiveColor{Light: \"#FF4672\", Dark: \"#ED567A\"}\n)\n\nvar (\n\tColorPending      = lipgloss.AdaptiveColor{Light: \"#cce046\", Dark: \"#cce046\"}\n\tColorSuccess      = lipgloss.AdaptiveColor{Light: \"#2ecc71\", Dark: \"#2ecc71\"}\n\tColorStarting     = ColorSuccess\n\tColorStopped      = lipgloss.AdaptiveColor{Light: \"#a2a2a2\", Dark: \"#a2a2a2\"}\n\tColorStopping     = ColorStopped\n\tColorError        = lipgloss.AdaptiveColor{Light: \"#e74c3c\", Dark: \"#e74c3c\"}\n\tColorDeleting     = ColorStopped\n\tColorDeleted      = ColorStopped\n\tColorUnresponsive = ColorError\n)\n\nvar (\n\tBaseTableStyleHorizontalPadding = 4\n\tBaseTableStyle                  = lipgloss.NewStyle().\n\t\t\t\t\tPaddingLeft(BaseTableStyleHorizontalPadding).\n\t\t\t\t\tPaddingRight(BaseTableStyleHorizontalPadding).\n\t\t\t\t\tPaddingTop(1).\n\t\t\t\t\tMargin(1, 0)\n\n\tNameStyle           = lipgloss.NewStyle().Foreground(Light)\n\tLinkStyle           = lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color(\"12\"))\n\tActiveStyle         = lipgloss.NewStyle().Foreground(Green)\n\tInactiveStyle       = lipgloss.NewStyle().Foreground(Orange)\n\tDefaultRowDataStyle = lipgloss.NewStyle().Foreground(Gray)\n\tBaseCellStyle       = lipgloss.NewRenderer(os.Stdout).NewStyle().Padding(0, 4, 1, 0)\n\tTableHeaderStyle    = BaseCellStyle.Foreground(LightGray).Bold(false).Padding(0).MarginRight(4)\n)\n\nvar (\n\tUndefinedStyle     = lipgloss.NewStyle().Foreground(ColorPending)\n\tPendingStyle       = lipgloss.NewStyle().Foreground(ColorPending)\n\tRunningStyle       = lipgloss.NewStyle().Foreground(ColorPending)\n\tRunSuccessfulStyle = lipgloss.NewStyle().Foreground(ColorSuccess)\n\tCreatingStyle      = lipgloss.NewStyle().Foreground(ColorPending)\n\tStartedStyle       = lipgloss.NewStyle().Foreground(ColorSuccess)\n\tStartingStyle      = lipgloss.NewStyle().Foreground(ColorStarting)\n\tStoppedStyle       = lipgloss.NewStyle().Foreground(ColorStopped)\n\tStoppingStyle      = lipgloss.NewStyle().Foreground(ColorStopping)\n\tErrorStyle         = lipgloss.NewStyle().Foreground(ColorError)\n\tDeletingStyle      = lipgloss.NewStyle().Foreground(ColorDeleting)\n\tDeletedStyle       = lipgloss.NewStyle().Foreground(ColorDeleted)\n\tUnresponsiveStyle  = lipgloss.NewStyle().Foreground(ColorUnresponsive)\n)\n\nvar LogPrefixColors = []lipgloss.AdaptiveColor{\n\tBlue, Orange, Cyan, Yellow,\n}\n\ntype SelectionListOptions struct {\n\tParentIdentifier     string\n\tIsPaginationDisabled bool\n\tCursorIndex          int\n}\n\nfunc GetStyledSelectList(items []list.Item, listOptions ...SelectionListOptions) list.Model {\n\n\td := list.NewDefaultDelegate()\n\n\td.Styles.SelectedTitle = lipgloss.NewStyle().\n\t\tBorder(lipgloss.NormalBorder(), false, false, false, true).\n\t\tBorderForeground(Green).\n\t\tForeground(Green).\n\t\tBold(true).\n\t\tPadding(0, 0, 0, 1)\n\n\td.Styles.SelectedDesc = d.Styles.SelectedTitle.Foreground(DimmedGreen).Bold(false)\n\n\tl := list.New(items, d, 0, 0)\n\n\tif listOptions != nil {\n\t\t// Sets the mouse cursor to point to the first index of newly loaded items\n\t\tif listOptions[0].CursorIndex > 0 {\n\t\t\tl.Select(listOptions[0].CursorIndex)\n\t\t}\n\n\t\tif !listOptions[0].IsPaginationDisabled {\n\t\t\t// Add the 'Load More' option in search filter results\n\t\t\tl.Filter = func(term string, targets []string) []list.Rank {\n\t\t\t\tranks := list.DefaultFilter(term, targets)\n\n\t\t\t\tloadMoreIdx := -1\n\t\t\t\t// Ideally 'Load More' option if present should be found at the last index\n\t\t\t\tfor i := len(targets) - 1; i >= 0; i-- {\n\t\t\t\t\tif targets[i] == ListNavigationRenderText {\n\t\t\t\t\t\tloadMoreIdx = i\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif loadMoreIdx == -1 {\n\t\t\t\t\treturn ranks\n\t\t\t\t}\n\n\t\t\t\t// Return if already present\n\t\t\t\tfor i := range ranks {\n\t\t\t\t\tif ranks[i].Index == loadMoreIdx {\n\t\t\t\t\t\treturn ranks\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Append 'Load More' option in search filter results\n\t\t\t\tranks = append(ranks, list.Rank{\n\t\t\t\t\tIndex: loadMoreIdx,\n\t\t\t\t})\n\n\t\t\t\treturn ranks\n\t\t\t}\n\t\t}\n\t}\n\n\tl.Styles.FilterPrompt = lipgloss.NewStyle().Foreground(Green)\n\tl.Styles.FilterCursor = lipgloss.NewStyle().Foreground(Green).Background(Green)\n\tl.Styles.Title = lipgloss.NewStyle().Foreground(Dark).Bold(true).\n\t\tBackground(lipgloss.Color(\"#fff\")).Padding(0)\n\n\tl.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(Green)\n\tl.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(Green)\n\n\tsingularItemName := \"item \" + SeparatorString\n\tvar pluralItemName string\n\tif listOptions == nil {\n\t\tpluralItemName = fmt.Sprintf(\"items\\n\\n%s\", SeparatorString)\n\t} else if len(listOptions[0].ParentIdentifier) > 0 {\n\t\tpluralItemName = fmt.Sprintf(\"items (%s)\\n\\n%s\", listOptions[0].ParentIdentifier, SeparatorString)\n\t}\n\n\tl.SetStatusBarItemName(singularItemName, pluralItemName)\n\n\treturn l\n}\n\nfunc GetCustomTheme() *huh.Theme {\n\tt := huh.ThemeCharm()\n\n\tt.Blurred.FocusedButton = t.Blurred.FocusedButton.Background(Green)\n\tt.Blurred.FocusedButton = t.Blurred.FocusedButton.Bold(true)\n\tt.Blurred.TextInput.Prompt = t.Blurred.TextInput.Prompt.Foreground(Light)\n\tt.Blurred.TextInput.Cursor = t.Blurred.TextInput.Cursor.Foreground(Light)\n\tt.Blurred.SelectSelector = t.Blurred.SelectSelector.Foreground(Green)\n\tt.Blurred.Title = t.Blurred.Title.Foreground(Gray).Bold(true)\n\tt.Blurred.Description = t.Blurred.Description.Foreground(LightGray)\n\n\tt.Focused.Title = t.Focused.Title.Foreground(Green).Bold(true)\n\tt.Focused.Description = t.Focused.Description.Foreground(LightGray).Bold(true)\n\tt.Focused.FocusedButton = t.Focused.FocusedButton.Bold(true)\n\tt.Focused.FocusedButton = t.Focused.FocusedButton.Background(Green)\n\tt.Focused.TextInput.Prompt = t.Focused.TextInput.Prompt.Foreground(Green)\n\tt.Focused.TextInput.Cursor = t.Focused.TextInput.Cursor.Foreground(Light)\n\tt.Focused.SelectSelector = t.Focused.SelectSelector.Foreground(Green)\n\tt.Focused.SelectedOption = t.Focused.SelectedOption.Foreground(Green)\n\n\tt.Focused.ErrorIndicator = t.Focused.ErrorIndicator.Foreground(Red)\n\tt.Focused.ErrorMessage = t.Focused.ErrorMessage.Foreground(Red)\n\n\tt.Focused.Base = t.Focused.Base.BorderForeground(Green)\n\tt.Focused.Base = t.Focused.Base.BorderBottomForeground(Green)\n\n\tt.Focused.Base = t.Focused.Base.MarginTop(DefaultLayoutMarginTop)\n\tt.Blurred.Base = t.Blurred.Base.MarginTop(DefaultLayoutMarginTop)\n\n\treturn t\n}\n\nfunc GetInitialCommandTheme() *huh.Theme {\n\n\tnewTheme := huh.ThemeCharm()\n\n\tnewTheme.Blurred.Title = newTheme.Focused.Title\n\n\tb := &newTheme.Blurred\n\tb.FocusedButton = b.FocusedButton.Background(Green)\n\tb.FocusedButton = b.FocusedButton.Bold(true)\n\tb.TextInput.Prompt = b.TextInput.Prompt.Foreground(Green)\n\tb.TextInput.Cursor = b.TextInput.Cursor.Foreground(Green)\n\tb.SelectSelector = b.SelectSelector.Foreground(Green)\n\n\tf := &newTheme.Focused\n\tf.Base = f.Base.BorderForeground(lipgloss.Color(\"fff\"))\n\tf.Title = f.Title.Foreground(Green).Bold(true)\n\tf.FocusedButton = f.FocusedButton.Bold(true)\n\tf.FocusedButton = f.FocusedButton.Background(Green)\n\tf.TextInput.Prompt = f.TextInput.Prompt.Foreground(Green)\n\tf.TextInput.Cursor = f.TextInput.Cursor.Foreground(Light)\n\tf.SelectSelector = f.SelectSelector.Foreground(Green)\n\n\tf.Base = f.Base.UnsetMarginLeft()\n\tf.Base = f.Base.UnsetPaddingLeft()\n\tf.Base = f.Base.BorderLeft(false)\n\n\tf.SelectedOption = lipgloss.NewStyle().Foreground(Green)\n\n\treturn newTheme\n}\n"
  },
  {
    "path": "apps/cli/views/organization/info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage organization\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"golang.org/x/term\"\n)\n\nfunc RenderInfo(organization *apiclient.Organization, forceUnstyled bool) {\n\tvar output string\n\tnameLabel := \"Organization\"\n\n\toutput += \"\\n\"\n\toutput += getInfoLine(nameLabel, organization.Name) + \"\\n\"\n\toutput += getInfoLine(\"Created\", util.GetTimeSinceLabel(organization.CreatedAt)) + \"\\n\"\n\toutput += getInfoLine(\"ID\", organization.Id) + \"\\n\"\n\n\tterminalWidth, _, err := term.GetSize(int(os.Stdout.Fd()))\n\tif err != nil {\n\t\tfmt.Println(output)\n\t\treturn\n\t}\n\n\tif terminalWidth < common.TUITableMinimumWidth || forceUnstyled {\n\t\trenderUnstyledInfo(output)\n\t\treturn\n\t}\n\n\toutput = common.GetStyledMainTitle(\"Organization Info\") + \"\\n\" + output\n\n\trenderTUIView(output, common.GetContainerBreakpointWidth(terminalWidth))\n}\n\nfunc renderUnstyledInfo(output string) {\n\tfmt.Println(output)\n}\n\nfunc renderTUIView(output string, width int) {\n\toutput = lipgloss.NewStyle().PaddingLeft(3).Render(output)\n\n\tcontent := lipgloss.\n\t\tNewStyle().Width(width).\n\t\tRender(output)\n\n\tfmt.Println(content)\n}\n\nfunc getInfoLine(key, value string) string {\n\treturn util.PropertyNameStyle.Render(fmt.Sprintf(\"%-*s\", util.PropertyNameWidth, key)) + util.PropertyValueStyle.Render(value) + \"\\n\"\n}\n"
  },
  {
    "path": "apps/cli/views/organization/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage organization\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\ntype RowData struct {\n\tName    string\n\tId      string\n\tCreated string\n}\n\nfunc ListOrganizations(organizationList []apiclient.Organization, activeOrganizationId *string) {\n\tif len(organizationList) == 0 {\n\t\tutil.NotifyEmptyOrganizationList(true)\n\t\treturn\n\t}\n\n\tSortOrganizations(&organizationList)\n\n\theaders := []string{\"Name\", \"Id\", \"Created\"}\n\n\tdata := [][]string{}\n\n\tfor _, o := range organizationList {\n\t\tvar rowData *RowData\n\t\tvar row []string\n\n\t\trowData = getTableRowData(o, activeOrganizationId)\n\t\trow = getRowFromRowData(*rowData)\n\t\tdata = append(data, row)\n\t}\n\n\ttable := util.GetTableView(data, headers, nil, func() {\n\t\trenderUnstyledList(organizationList)\n\t})\n\n\tfmt.Println(table)\n}\n\nfunc SortOrganizations(organizationList *[]apiclient.Organization) {\n\tsort.Slice(*organizationList, func(i, j int) bool {\n\t\treturn (*organizationList)[i].CreatedAt.After((*organizationList)[j].CreatedAt)\n\t})\n}\n\nfunc getTableRowData(organization apiclient.Organization, activeOrganizationId *string) *RowData {\n\trowData := RowData{\"\", \"\", \"\"}\n\trowData.Name = organization.Name + util.AdditionalPropertyPadding\n\n\tif activeOrganizationId != nil && *activeOrganizationId == organization.Id {\n\t\trowData.Name = \"*\" + rowData.Name\n\t}\n\n\trowData.Id = organization.Id\n\trowData.Created = util.GetTimeSinceLabel(organization.CreatedAt)\n\n\treturn &rowData\n}\n\nfunc renderUnstyledList(organizationList []apiclient.Organization) {\n\tfor _, organization := range organizationList {\n\t\tRenderInfo(&organization, true)\n\n\t\tif organization.Id != organizationList[len(organizationList)-1].Id {\n\t\t\tfmt.Printf(\"\\n%s\\n\\n\", common.SeparatorString)\n\t\t}\n\n\t}\n}\n\nfunc getRowFromRowData(rowData RowData) []string {\n\trow := []string{\n\t\tcommon.NameStyle.Render(rowData.Name),\n\t\tcommon.DefaultRowDataStyle.Render(rowData.Id),\n\t\tcommon.DefaultRowDataStyle.Render(rowData.Created),\n\t}\n\n\treturn row\n}\n"
  },
  {
    "path": "apps/cli/views/organization/select.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage organization\n\nimport (\n\t\"github.com/charmbracelet/huh\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\nfunc GetOrganizationIdFromPrompt(organizationList []apiclient.Organization) (*apiclient.Organization, error) {\n\tvar chosenOrganizationId string\n\tvar organizationOptions []huh.Option[string]\n\n\tfor _, organization := range organizationList {\n\t\torganizationOptions = append(organizationOptions, huh.NewOption(organization.Name, organization.Id))\n\t}\n\n\tform := huh.NewForm(\n\t\thuh.NewGroup(\n\t\t\thuh.NewSelect[string]().\n\t\t\t\tTitle(\"Choose an Organization\").\n\t\t\t\tOptions(\n\t\t\t\t\torganizationOptions...,\n\t\t\t\t).\n\t\t\t\tValue(&chosenOrganizationId),\n\t\t).WithTheme(common.GetCustomTheme()),\n\t)\n\n\tif err := form.Run(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, organization := range organizationList {\n\t\tif organization.Id == chosenOrganizationId {\n\t\t\treturn &organization, nil\n\t\t}\n\t}\n\n\treturn nil, nil\n}\n"
  },
  {
    "path": "apps/cli/views/sandbox/info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"golang.org/x/term\"\n)\n\nfunc RenderInfo(sandbox *apiclient.Sandbox, forceUnstyled bool) {\n\tvar output string\n\n\toutput += \"\\n\"\n\n\toutput += getInfoLine(\"ID\", sandbox.Id) + \"\\n\"\n\n\tif sandbox.State != nil {\n\t\toutput += getInfoLine(\"State\", getStateLabel(*sandbox.State)) + \"\\n\"\n\t}\n\n\tif sandbox.Snapshot != nil {\n\t\toutput += getInfoLine(\"Snapshot\", *sandbox.Snapshot) + \"\\n\"\n\t}\n\n\toutput += getInfoLine(\"Region\", sandbox.Target) + \"\\n\"\n\n\tif sandbox.Class != nil {\n\t\toutput += getInfoLine(\"Class\", *sandbox.Class) + \"\\n\"\n\t}\n\n\tif sandbox.CreatedAt != nil {\n\t\toutput += getInfoLine(\"Created\", util.GetTimeSinceLabelFromString(*sandbox.CreatedAt)) + \"\\n\"\n\t}\n\n\tif sandbox.UpdatedAt != nil {\n\t\toutput += getInfoLine(\"Last Event\", util.GetTimeSinceLabelFromString(*sandbox.UpdatedAt)) + \"\\n\"\n\t}\n\n\tterminalWidth, _, err := term.GetSize(int(os.Stdout.Fd()))\n\tif err != nil {\n\t\tfmt.Println(output)\n\t\treturn\n\t}\n\tif terminalWidth < common.TUITableMinimumWidth || forceUnstyled {\n\t\trenderUnstyledInfo(output)\n\t\treturn\n\t}\n\n\toutput = common.GetStyledMainTitle(\"Sandbox Info\") + \"\\n\" + output\n\n\tif len(sandbox.Labels) > 0 {\n\t\tlabels := \"\"\n\t\ti := 0\n\t\tfor k, v := range sandbox.Labels {\n\t\t\tlabel := fmt.Sprintf(\"%s=%s\\n\", k, v)\n\t\t\tif i == 0 {\n\t\t\t\tlabels += label + \"\\n\"\n\t\t\t} else {\n\t\t\t\tlabels += getInfoLine(\"\", fmt.Sprintf(\"%s=%s\\n\", k, v))\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t\tlabels = strings.TrimSuffix(labels, \"\\n\")\n\t\toutput += \"\\n\" + strings.TrimSuffix(getInfoLine(\"Labels\", labels), \"\\n\")\n\t}\n\n\trenderTUIView(output, common.GetContainerBreakpointWidth(terminalWidth))\n}\n\nfunc renderUnstyledInfo(output string) {\n\tfmt.Println(output)\n}\n\nfunc renderTUIView(output string, width int) {\n\toutput = lipgloss.NewStyle().PaddingLeft(3).Render(output)\n\n\tcontent := lipgloss.\n\t\tNewStyle().Width(width).\n\t\tRender(output)\n\n\tfmt.Println(content)\n}\n\nfunc getInfoLine(key, value string) string {\n\treturn util.PropertyNameStyle.Render(fmt.Sprintf(\"%-*s\", util.PropertyNameWidth, key)) + util.PropertyValueStyle.Render(value) + \"\\n\"\n}\n\nfunc getStateLabel(state apiclient.SandboxState) string {\n\tswitch state {\n\tcase apiclient.SANDBOXSTATE_CREATING:\n\t\treturn common.CreatingStyle.Render(\"CREATING\")\n\tcase apiclient.SANDBOXSTATE_RESTORING:\n\t\treturn common.CreatingStyle.Render(\"RESTORING\")\n\tcase apiclient.SANDBOXSTATE_DESTROYED:\n\t\treturn common.DeletedStyle.Render(\"DESTROYED\")\n\tcase apiclient.SANDBOXSTATE_DESTROYING:\n\t\treturn common.DeletedStyle.Render(\"DESTROYING\")\n\tcase apiclient.SANDBOXSTATE_STARTED:\n\t\treturn common.StartedStyle.Render(\"STARTED\")\n\tcase apiclient.SANDBOXSTATE_STOPPED:\n\t\treturn common.StoppedStyle.Render(\"STOPPED\")\n\tcase apiclient.SANDBOXSTATE_STARTING:\n\t\treturn common.StartingStyle.Render(\"STARTING\")\n\tcase apiclient.SANDBOXSTATE_STOPPING:\n\t\treturn common.StoppingStyle.Render(\"STOPPING\")\n\tcase apiclient.SANDBOXSTATE_PULLING_SNAPSHOT:\n\t\treturn common.CreatingStyle.Render(\"PULLING SNAPSHOT\")\n\tcase apiclient.SANDBOXSTATE_ARCHIVING:\n\t\treturn common.CreatingStyle.Render(\"ARCHIVING\")\n\tcase apiclient.SANDBOXSTATE_ARCHIVED:\n\t\treturn common.StoppedStyle.Render(\"ARCHIVED\")\n\tcase apiclient.SANDBOXSTATE_ERROR:\n\t\treturn common.ErrorStyle.Render(\"ERROR\")\n\tcase apiclient.SANDBOXSTATE_BUILD_FAILED:\n\t\treturn common.ErrorStyle.Render(\"BUILD FAILED\")\n\tcase apiclient.SANDBOXSTATE_UNKNOWN:\n\t\treturn common.UndefinedStyle.Render(\"UNKNOWN\")\n\tdefault:\n\t\treturn common.UndefinedStyle.Render(\"/\")\n\t}\n}\n"
  },
  {
    "path": "apps/cli/views/sandbox/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sandbox\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\ntype RowData struct {\n\tName      string\n\tState     string\n\tRegion    string\n\tClass     string\n\tLastEvent string\n}\n\nfunc ListSandboxes(sandboxList []apiclient.Sandbox, activeOrganizationName *string) {\n\tif len(sandboxList) == 0 {\n\t\tutil.NotifyEmptySandboxList(true)\n\t\treturn\n\t}\n\n\theaders := []string{\"Sandbox\", \"State\", \"Region\", \"Class\", \"Last Event\"}\n\n\tdata := [][]string{}\n\n\tfor _, s := range sandboxList {\n\t\tvar rowData *RowData\n\t\tvar row []string\n\n\t\trowData = getTableRowData(s)\n\t\trow = getRowFromRowData(*rowData)\n\t\tdata = append(data, row)\n\t}\n\n\ttable := util.GetTableView(data, headers, activeOrganizationName, func() {\n\t\trenderUnstyledList(sandboxList)\n\t})\n\n\tfmt.Println(table)\n}\n\nfunc SortSandboxes(sandboxList *[]apiclient.Sandbox) {\n\tsort.Slice(*sandboxList, func(i, j int) bool {\n\t\tpi, pj := getStateSortPriorities(*(*sandboxList)[i].State, *(*sandboxList)[j].State)\n\t\tif pi != pj {\n\t\t\treturn pi < pj\n\t\t}\n\n\t\tif (*sandboxList)[i].CreatedAt == nil || (*sandboxList)[j].CreatedAt == nil {\n\t\t\treturn true\n\t\t}\n\n\t\t// If two sandboxes have the same state priority, compare the UpdatedAt property\n\t\treturn *(*sandboxList)[i].CreatedAt > *(*sandboxList)[j].CreatedAt\n\t})\n}\n\nfunc getTableRowData(sandbox apiclient.Sandbox) *RowData {\n\trowData := RowData{\"\", \"\", \"\", \"\", \"\"}\n\trowData.Name = sandbox.Id + util.AdditionalPropertyPadding\n\tif sandbox.State != nil {\n\t\trowData.State = getStateLabel(*sandbox.State)\n\t}\n\n\trowData.Region = sandbox.Target\n\tif sandbox.Class != nil {\n\t\trowData.Class = *sandbox.Class\n\t}\n\n\tif sandbox.UpdatedAt != nil {\n\t\trowData.LastEvent = util.GetTimeSinceLabelFromString(*sandbox.UpdatedAt)\n\t}\n\n\treturn &rowData\n}\n\nfunc renderUnstyledList(sandboxList []apiclient.Sandbox) {\n\tfor _, sandbox := range sandboxList {\n\t\tRenderInfo(&sandbox, true)\n\n\t\tif sandbox.Id != sandboxList[len(sandboxList)-1].Id {\n\t\t\tfmt.Printf(\"\\n%s\\n\\n\", common.SeparatorString)\n\t\t}\n\n\t}\n}\n\nfunc getRowFromRowData(rowData RowData) []string {\n\trow := []string{\n\t\tcommon.NameStyle.Render(rowData.Name),\n\t\trowData.State,\n\t\tcommon.DefaultRowDataStyle.Render(rowData.Region),\n\t\tcommon.DefaultRowDataStyle.Render(rowData.Class),\n\t\tcommon.DefaultRowDataStyle.Render(rowData.LastEvent),\n\t}\n\n\treturn row\n}\n\nfunc getStateSortPriorities(state1, state2 apiclient.SandboxState) (int, int) {\n\tpi, ok := sandboxListStatePriorities[state1]\n\tif !ok {\n\t\tpi = 99\n\t}\n\tpj, ok2 := sandboxListStatePriorities[state2]\n\tif !ok2 {\n\t\tpj = 99\n\t}\n\n\treturn pi, pj\n}\n\n// Sandboxes that have actions being performed on them have a higher priority when listing\nvar sandboxListStatePriorities = map[apiclient.SandboxState]int{\n\t\"pending\":       1,\n\t\"pending-start\": 1,\n\t\"deleting\":      1,\n\t\"creating\":      1,\n\t\"started\":       2,\n\t\"undefined\":     2,\n\t\"error\":         3,\n\t\"build-failed\":  3,\n\t\"stopped\":       4,\n}\n"
  },
  {
    "path": "apps/cli/views/snapshot/info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage snapshot\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"golang.org/x/term\"\n)\n\nfunc RenderInfo(snapshot *apiclient.SnapshotDto, forceUnstyled bool) {\n\tvar output string\n\tnameLabel := \"Snapshot\"\n\n\toutput += \"\\n\"\n\toutput += getInfoLine(nameLabel, snapshot.Name) + \"\\n\"\n\toutput += getInfoLine(\"State\", getStateLabel(snapshot.State)) + \"\\n\"\n\n\tif size := snapshot.Size.Get(); size != nil {\n\t\toutput += getInfoLine(\"Size\", fmt.Sprintf(\"%.2f GB\", *size)) + \"\\n\"\n\t} else {\n\t\toutput += getInfoLine(\"Size\", \"-\") + \"\\n\"\n\t}\n\toutput += getInfoLine(\"Created\", util.GetTimeSinceLabel(snapshot.CreatedAt)) + \"\\n\"\n\n\toutput += getInfoLine(\"ID\", snapshot.Id) + \"\\n\"\n\n\tterminalWidth, _, err := term.GetSize(int(os.Stdout.Fd()))\n\tif err != nil {\n\t\tfmt.Println(output)\n\t\treturn\n\t}\n\tif terminalWidth < common.TUITableMinimumWidth || forceUnstyled {\n\t\trenderUnstyledInfo(output)\n\t\treturn\n\t}\n\n\toutput = common.GetStyledMainTitle(\"Snapshot Info\") + \"\\n\" + output\n\n\trenderTUIView(output, common.GetContainerBreakpointWidth(terminalWidth))\n}\n\nfunc renderUnstyledInfo(output string) {\n\tfmt.Println(output)\n}\n\nfunc renderTUIView(output string, width int) {\n\toutput = lipgloss.NewStyle().PaddingLeft(3).Render(output)\n\n\tcontent := lipgloss.\n\t\tNewStyle().Width(width).\n\t\tRender(output)\n\n\tfmt.Println(content)\n}\n\nfunc getInfoLine(key, value string) string {\n\treturn util.PropertyNameStyle.Render(fmt.Sprintf(\"%-*s\", util.PropertyNameWidth, key)) + util.PropertyValueStyle.Render(value) + \"\\n\"\n}\n\nfunc getStateLabel(state apiclient.SnapshotState) string {\n\tswitch state {\n\tcase apiclient.SNAPSHOTSTATE_PENDING:\n\t\treturn common.CreatingStyle.Render(\"PENDING\")\n\tcase apiclient.SNAPSHOTSTATE_PULLING:\n\t\treturn common.CreatingStyle.Render(\"PULLING SNAPSHOT\")\n\tcase apiclient.SNAPSHOTSTATE_ACTIVE:\n\t\treturn common.StartedStyle.Render(\"ACTIVE\")\n\tcase apiclient.SNAPSHOTSTATE_ERROR:\n\t\treturn common.ErrorStyle.Render(\"ERROR\")\n\tcase apiclient.SNAPSHOTSTATE_BUILD_FAILED:\n\t\treturn common.ErrorStyle.Render(\"BUILD FAILED\")\n\tcase apiclient.SNAPSHOTSTATE_REMOVING:\n\t\treturn common.DeletedStyle.Render(\"REMOVING\")\n\tdefault:\n\t\treturn common.UndefinedStyle.Render(\"/\")\n\t}\n}\n"
  },
  {
    "path": "apps/cli/views/snapshot/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage snapshot\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\ntype RowData struct {\n\tName    string\n\tState   string\n\tSize    string\n\tCreated string\n}\n\nfunc ListSnapshots(snapshotList []apiclient.SnapshotDto, activeOrganizationName *string) {\n\tif len(snapshotList) == 0 {\n\t\tutil.NotifyEmptySnapshotList(true)\n\t\treturn\n\t}\n\n\tSortSnapshots(&snapshotList)\n\n\theaders := []string{\"Snapshot\", \"State\", \"Size\", \"Created\"}\n\n\tdata := [][]string{}\n\n\tfor _, img := range snapshotList {\n\t\tvar rowData *RowData\n\t\tvar row []string\n\n\t\trowData = getTableRowData(img)\n\t\trow = getRowFromRowData(*rowData)\n\t\tdata = append(data, row)\n\t}\n\n\ttable := util.GetTableView(data, headers, activeOrganizationName, func() {\n\t\trenderUnstyledList(snapshotList)\n\t})\n\n\tfmt.Println(table)\n}\n\nfunc SortSnapshots(snapshotList *[]apiclient.SnapshotDto) {\n\tsort.Slice(*snapshotList, func(i, j int) bool {\n\t\tpi, pj := getStateSortPriorities((*snapshotList)[i].State, (*snapshotList)[j].State)\n\t\tif pi != pj {\n\t\t\treturn pi < pj\n\t\t}\n\n\t\t// If two snapshots have the same state priority, compare the UpdatedAt property\n\t\treturn (*snapshotList)[i].CreatedAt.After((*snapshotList)[j].CreatedAt)\n\t})\n}\n\nfunc getTableRowData(snapshot apiclient.SnapshotDto) *RowData {\n\trowData := RowData{\"\", \"\", \"\", \"\"}\n\trowData.Name = snapshot.Name + util.AdditionalPropertyPadding\n\trowData.State = getStateLabel(snapshot.State)\n\n\tif snapshot.Size.IsSet() && snapshot.Size.Get() != nil {\n\t\trowData.Size = fmt.Sprintf(\"%.2f GB\", *snapshot.Size.Get())\n\t} else {\n\t\trowData.Size = \"-\"\n\t}\n\n\trowData.Created = util.GetTimeSinceLabel(snapshot.CreatedAt)\n\treturn &rowData\n}\n\nfunc renderUnstyledList(snapshotList []apiclient.SnapshotDto) {\n\tfor _, snapshot := range snapshotList {\n\t\tRenderInfo(&snapshot, true)\n\n\t\tif snapshot.Id != snapshotList[len(snapshotList)-1].Id {\n\t\t\tfmt.Printf(\"\\n%s\\n\\n\", common.SeparatorString)\n\t\t}\n\t}\n}\n\nfunc getRowFromRowData(rowData RowData) []string {\n\trow := []string{\n\t\tcommon.NameStyle.Render(rowData.Name),\n\t\trowData.State,\n\t\tcommon.DefaultRowDataStyle.Render(rowData.Size),\n\t\tcommon.DefaultRowDataStyle.Render(rowData.Created),\n\t}\n\n\treturn row\n}\n\nfunc getStateSortPriorities(state1, state2 apiclient.SnapshotState) (int, int) {\n\tpi, ok := snapshotListStatePriorities[state1]\n\tif !ok {\n\t\tpi = 99\n\t}\n\tpj, ok2 := snapshotListStatePriorities[state2]\n\tif !ok2 {\n\t\tpj = 99\n\t}\n\n\treturn pi, pj\n}\n\n// snapshots that have actions being performed on them have a higher priority when listing\nvar snapshotListStatePriorities = map[apiclient.SnapshotState]int{\n\tapiclient.SNAPSHOTSTATE_PENDING:  1,\n\tapiclient.SNAPSHOTSTATE_PULLING:  1,\n\tapiclient.SNAPSHOTSTATE_ERROR:    2,\n\tapiclient.SNAPSHOTSTATE_ACTIVE:   3,\n\tapiclient.SNAPSHOTSTATE_REMOVING: 4,\n}\n"
  },
  {
    "path": "apps/cli/views/util/empty_list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n)\n\nfunc NotifyEmptySandboxList(tip bool) {\n\tcommon.RenderInfoMessageBold(\"No sandboxes found\")\n\tif tip {\n\t\tcommon.RenderTip(\"Use the Daytona SDK to get started.\")\n\t}\n}\n\nfunc NotifyEmptySnapshotList(tip bool) {\n\tcommon.RenderInfoMessageBold(\"No snapshots found\")\n\tif tip {\n\t\tcommon.RenderTip(\"Use 'daytona snapshot push' to push a snapshot.\")\n\t}\n}\n\nfunc NotifyEmptyOrganizationList(tip bool) {\n\tcommon.RenderInfoMessageBold(\"No organizations found\")\n\tif tip {\n\t\tcommon.RenderTip(\"Use 'daytona organization create' to create an organization.\")\n\t}\n}\n\nfunc NotifyEmptyVolumeList(tip bool) {\n\tcommon.RenderInfoMessageBold(\"No volumes found\")\n\tif tip {\n\t\tcommon.RenderTip(\"Use 'daytona volume create' to create a volume.\")\n\t}\n}\n"
  },
  {
    "path": "apps/cli/views/util/info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n)\n\nconst PropertyNameWidth = 16\n\nvar PropertyNameStyle = lipgloss.NewStyle().\n\tForeground(common.LightGray)\n\nvar PropertyValueStyle = lipgloss.NewStyle().\n\tForeground(common.Light).\n\tBold(true)\n"
  },
  {
    "path": "apps/cli/views/util/spinner.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/charmbracelet/bubbles/spinner\"\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/term\"\n)\n\nvar isAborted bool\n\ntype model struct {\n\tspinner  spinner.Model\n\tquitting bool\n\tmessage  string\n\tinline   bool\n}\n\ntype Msg string\n\nfunc initialModel(message string, inline bool) model {\n\ts := spinner.New()\n\ts.Spinner = spinner.Dot\n\ts.Style = lipgloss.NewStyle().Foreground(common.Green)\n\treturn model{spinner: s, message: message, inline: inline}\n}\n\nfunc (m model) Init() tea.Cmd {\n\treturn m.spinner.Tick\n}\n\nfunc (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {\n\tswitch msg := msg.(type) {\n\tcase Msg:\n\t\tm.quitting = true\n\t\treturn m, tea.Quit\n\n\tcase tea.KeyMsg:\n\t\tswitch keypress := msg.String(); keypress {\n\t\tcase \"ctrl+c\":\n\t\t\tisAborted = true\n\t\t\tm.quitting = true\n\t\t\treturn m, tea.Quit\n\t\t}\n\t}\n\tvar cmd tea.Cmd\n\tm.spinner, cmd = m.spinner.Update(msg)\n\treturn m, cmd\n\n}\n\nfunc WithSpinner(message string, fn func() error) error {\n\tif isTTY() {\n\t\tp := start(message, false)\n\t\tdefer stop(p)\n\t}\n\treturn fn()\n}\n\nfunc WithInlineSpinner(message string, fn func() error) error {\n\tif isTTY() {\n\t\tp := start(message, true)\n\t\tdefer stop(p)\n\t}\n\treturn fn()\n}\n\nfunc start(message string, inline bool) *tea.Program {\n\tvar p *tea.Program\n\tif inline {\n\t\tp = tea.NewProgram(initialModel(message, true))\n\t} else {\n\t\tp = tea.NewProgram(initialModel(message, false), tea.WithAltScreen())\n\t}\n\tgo func() {\n\t\tif _, err := p.Run(); err != nil {\n\t\t\tfmt.Println(err)\n\t\t\tos.Exit(1)\n\t\t}\n\t\tif isAborted {\n\t\t\tfmt.Println(\"Operation cancelled\")\n\t\t\tos.Exit(1)\n\t\t}\n\t}()\n\treturn p\n\n}\n\nfunc stop(p *tea.Program) {\n\tp.Send(Msg(\"quit\"))\n\terr := p.ReleaseTerminal()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc (m model) View() string {\n\tif m.quitting {\n\t\treturn \"\"\n\t}\n\n\tstr := \"\"\n\tif m.inline {\n\t\tstr = common.GetInfoMessage(fmt.Sprintf(\"%s %s ...\", m.spinner.View(), m.message))\n\t} else {\n\t\tstr = common.NameStyle.Render(fmt.Sprintf(\"\\n\\n   %s %s ...\\n\\n\", m.spinner.View(), m.message))\n\t}\n\n\treturn str\n}\n\nfunc isTTY() bool {\n\treturn term.IsTerminal(int(os.Stdout.Fd()))\n}\n"
  },
  {
    "path": "apps/cli/views/util/table.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/charmbracelet/lipgloss/table\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"golang.org/x/term\"\n)\n\nvar AdditionalPropertyPadding = \"  \"\n\n// Left border, BaseTableStyle padding left, additional padding for target name and target config, BaseTableStyle padding right, BaseCellStyle padding right, right border\nvar RowWhiteSpace = 1 + 4 + len(AdditionalPropertyPadding)*2 + 4 + 4 + 1\nvar ArbitrarySpace = 10\n\n// Gets the table view string or falls back to an unstyled view for lower terminal widths\nfunc GetTableView(data [][]string, headers []string, activeOrganizationName *string, fallbackRender func()) string {\n\tre := lipgloss.NewRenderer(os.Stdout)\n\n\tterminalWidth, _, err := term.GetSize(int(os.Stdout.Fd()))\n\tif err != nil {\n\t\tfmt.Println(data)\n\t\treturn \"\"\n\t}\n\n\tbreakpointWidth := common.GetContainerBreakpointWidth(terminalWidth)\n\n\tminWidth := getMinimumWidth(data)\n\n\tif breakpointWidth == 0 || minWidth > breakpointWidth {\n\t\tfallbackRender()\n\t\treturn \"\"\n\t}\n\n\tt := table.New().\n\t\tHeaders(headers...).\n\t\tRows(data...).\n\t\tBorderStyle(re.NewStyle().Foreground(common.LightGray)).\n\t\tBorderRow(false).BorderColumn(false).BorderLeft(false).BorderRight(false).BorderTop(false).BorderBottom(false).\n\t\tStyleFunc(func(_, _ int) lipgloss.Style {\n\t\t\treturn common.BaseCellStyle\n\t\t}).Width(breakpointWidth - 2*common.BaseTableStyleHorizontalPadding - 1)\n\n\ttable := t.String()\n\n\tif activeOrganizationName != nil {\n\t\tactiveOrgMessage := common.GetInfoMessage(fmt.Sprintf(\"Active organization: %s\", *activeOrganizationName))\n\t\trightAlignedStyle := lipgloss.NewStyle().Width(breakpointWidth - 2*common.BaseTableStyleHorizontalPadding - 1).Align(lipgloss.Right)\n\t\ttable += \"\\n\" + rightAlignedStyle.Render(activeOrgMessage)\n\t}\n\n\treturn common.BaseTableStyle.Render(table)\n}\n\nfunc getMinimumWidth(data [][]string) int {\n\twidth := 0\n\twidestRow := 0\n\tfor _, row := range data {\n\t\tfor _, cell := range row {\n\t\t\t// Remove ANSI escape codes\n\t\t\tregex := regexp.MustCompile(\"\\x1b\\\\[[0-9;]*[a-zA-Z]\")\n\t\t\tstrippedCell := regex.ReplaceAllString(cell, \"\")\n\t\t\twidth += longestLineLength(strippedCell)\n\t\t\tif width > widestRow {\n\t\t\t\twidestRow = width\n\t\t\t}\n\t\t}\n\t\twidth = 0\n\t}\n\treturn widestRow\n}\n\n// Returns the length of the longest line in a string\nfunc longestLineLength(input string) int {\n\tlines := strings.Split(input, \"\\n\")\n\tmaxLength := 0\n\n\tfor _, line := range lines {\n\t\tif len(line) > maxLength {\n\t\t\tmaxLength = len(line)\n\t\t}\n\t}\n\n\treturn maxLength\n}\n"
  },
  {
    "path": "apps/cli/views/util/time.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nvar timeLayout = \"2006-01-02T15:04:05.999999999Z07:00\"\n\nfunc GetTimeSinceLabelFromString(input string) string {\n\tt, err := time.Parse(timeLayout, input)\n\tif err != nil {\n\t\treturn \"/\"\n\t}\n\n\treturn GetTimeSinceLabel(t)\n}\n\nfunc GetTimeSinceLabel(t time.Time) string {\n\tduration := time.Since(t)\n\n\tif duration < time.Minute {\n\t\treturn \"< 1 minute ago\"\n\t} else if duration < time.Hour {\n\t\tminutes := int(duration.Minutes())\n\t\tif minutes == 1 {\n\t\t\treturn \"1 minute ago\"\n\t\t}\n\t\treturn fmt.Sprintf(\"%d minutes ago\", minutes)\n\t} else if duration < 24*time.Hour {\n\t\thours := int(duration.Hours())\n\t\tif hours == 1 {\n\t\t\treturn \"1 hour ago\"\n\t\t}\n\t\treturn fmt.Sprintf(\"%d hours ago\", hours)\n\t} else {\n\t\tdays := int(duration.Hours() / 24)\n\t\tif days == 1 {\n\t\t\treturn \"1 day ago\"\n\t\t}\n\t\treturn fmt.Sprintf(\"%d days ago\", days)\n\t}\n}\n"
  },
  {
    "path": "apps/cli/views/volume/info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage volume\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"golang.org/x/term\"\n)\n\nfunc RenderInfo(volume *apiclient.VolumeDto, forceUnstyled bool) {\n\tvar output string\n\tnameLabel := \"Volume\"\n\n\toutput += \"\\n\"\n\toutput += getInfoLine(nameLabel, volume.Name) + \"\\n\"\n\toutput += getInfoLine(\"ID\", volume.Id) + \"\\n\"\n\toutput += getInfoLine(\"State\", getStateLabel(volume.State)) + \"\\n\"\n\n\toutput += getInfoLine(\"Created\", util.GetTimeSinceLabelFromString(volume.CreatedAt)) + \"\\n\"\n\n\tterminalWidth, _, err := term.GetSize(int(os.Stdout.Fd()))\n\tif err != nil {\n\t\tfmt.Println(output)\n\t\treturn\n\t}\n\tif terminalWidth < common.TUITableMinimumWidth || forceUnstyled {\n\t\trenderUnstyledInfo(output)\n\t\treturn\n\t}\n\n\toutput = common.GetStyledMainTitle(\"Volume Info\") + \"\\n\" + output\n\n\trenderTUIView(output, common.GetContainerBreakpointWidth(terminalWidth))\n}\n\nfunc renderUnstyledInfo(output string) {\n\tfmt.Println(output)\n}\n\nfunc renderTUIView(output string, width int) {\n\toutput = lipgloss.NewStyle().PaddingLeft(3).Render(output)\n\n\tcontent := lipgloss.\n\t\tNewStyle().Width(width).\n\t\tRender(output)\n\n\tfmt.Println(content)\n}\n\nfunc getInfoLine(key, value string) string {\n\treturn util.PropertyNameStyle.Render(fmt.Sprintf(\"%-*s\", util.PropertyNameWidth, key)) + util.PropertyValueStyle.Render(value) + \"\\n\"\n}\n\nfunc getStateLabel(state apiclient.VolumeState) string {\n\tswitch state {\n\tcase apiclient.VOLUMESTATE_PENDING_CREATE:\n\t\treturn common.CreatingStyle.Render(\"PENDING CREATE\")\n\tcase apiclient.VOLUMESTATE_CREATING:\n\t\treturn common.CreatingStyle.Render(\"CREATING\")\n\tcase apiclient.VOLUMESTATE_READY:\n\t\treturn common.StartedStyle.Render(\"READY\")\n\tcase apiclient.VOLUMESTATE_PENDING_DELETE:\n\t\treturn common.DeletedStyle.Render(\"PENDING DELETE\")\n\tcase apiclient.VOLUMESTATE_DELETING:\n\t\treturn common.DeletedStyle.Render(\"DELETING\")\n\tcase apiclient.VOLUMESTATE_DELETED:\n\t\treturn common.DeletedStyle.Render(\"DELETED\")\n\tcase apiclient.VOLUMESTATE_ERROR:\n\t\treturn common.ErrorStyle.Render(\"ERROR\")\n\tdefault:\n\t\treturn common.UndefinedStyle.Render(\"/\")\n\t}\n}\n"
  },
  {
    "path": "apps/cli/views/volume/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage volume\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/daytonaio/daytona/cli/views/common\"\n\t\"github.com/daytonaio/daytona/cli/views/util\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\ntype RowData struct {\n\tName    string\n\tState   string\n\tSize    string\n\tCreated string\n}\n\nfunc ListVolumes(volumeList []apiclient.VolumeDto, activeOrganizationName *string) {\n\tif len(volumeList) == 0 {\n\t\tutil.NotifyEmptyVolumeList(true)\n\t\treturn\n\t}\n\n\tSortVolumes(&volumeList)\n\n\theaders := []string{\"Volume\", \"State\", \"Size\", \"Created\"}\n\n\tdata := [][]string{}\n\n\tfor _, v := range volumeList {\n\t\tvar rowData *RowData\n\t\tvar row []string\n\n\t\trowData = getTableRowData(v)\n\t\trow = getRowFromRowData(*rowData)\n\t\tdata = append(data, row)\n\t}\n\n\ttable := util.GetTableView(data, headers, activeOrganizationName, func() {\n\t\trenderUnstyledList(volumeList)\n\t})\n\n\tfmt.Println(table)\n}\n\nfunc SortVolumes(volumeList *[]apiclient.VolumeDto) {\n\tsort.Slice(*volumeList, func(i, j int) bool {\n\t\tif (*volumeList)[i].State != (*volumeList)[j].State {\n\t\t\tpi, pj := getStateSortPriorities((*volumeList)[i].State, (*volumeList)[j].State)\n\t\t\treturn pi < pj\n\t\t}\n\n\t\t// If two volumes have the same state priority, compare the CreatedAt property\n\t\treturn (*volumeList)[i].CreatedAt > (*volumeList)[j].CreatedAt\n\t})\n}\n\nfunc getTableRowData(volume apiclient.VolumeDto) *RowData {\n\trowData := RowData{\"\", \"\", \"\", \"\"}\n\trowData.Name = volume.Name + util.AdditionalPropertyPadding\n\trowData.State = getStateLabel(volume.State)\n\trowData.Created = util.GetTimeSinceLabelFromString(volume.CreatedAt)\n\treturn &rowData\n}\n\nfunc renderUnstyledList(volumeList []apiclient.VolumeDto) {\n\tfor _, volume := range volumeList {\n\t\tRenderInfo(&volume, true)\n\n\t\tif volume.Id != volumeList[len(volumeList)-1].Id {\n\t\t\tfmt.Printf(\"\\n%s\\n\\n\", common.SeparatorString)\n\t\t}\n\t}\n}\n\nfunc getRowFromRowData(rowData RowData) []string {\n\trow := []string{\n\t\tcommon.NameStyle.Render(rowData.Name),\n\t\trowData.State,\n\t\tcommon.DefaultRowDataStyle.Render(rowData.Size),\n\t\tcommon.DefaultRowDataStyle.Render(rowData.Created),\n\t}\n\n\treturn row\n}\n\nfunc getStateSortPriorities(state1, state2 apiclient.VolumeState) (int, int) {\n\tpi, ok := volumeListStatePriorities[state1]\n\tif !ok {\n\t\tpi = 99\n\t}\n\tpj, ok2 := volumeListStatePriorities[state2]\n\tif !ok2 {\n\t\tpj = 99\n\t}\n\n\treturn pi, pj\n}\n\n// Volumes that have actions being performed on them have a higher priority when listing\nvar volumeListStatePriorities = map[apiclient.VolumeState]int{\n\tapiclient.VOLUMESTATE_PENDING_CREATE: 1,\n\tapiclient.VOLUMESTATE_CREATING:       1,\n\tapiclient.VOLUMESTATE_PENDING_DELETE: 1,\n\tapiclient.VOLUMESTATE_DELETING:       1,\n\tapiclient.VOLUMESTATE_READY:          2,\n\tapiclient.VOLUMESTATE_ERROR:          3,\n\tapiclient.VOLUMESTATE_DELETED:        4,\n}\n"
  },
  {
    "path": "apps/daemon/.gitignore",
    "content": "pkg/terminal/static\n!pkg/terminal/static/index.html\n"
  },
  {
    "path": "apps/daemon/cmd/daemon/config/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage config\n\nimport (\n\t\"time\"\n\n\t\"github.com/go-playground/validator/v10\"\n\t\"github.com/kelseyhightower/envconfig\"\n)\n\ntype Config struct {\n\tDaemonLogFilePath        string        `envconfig:\"DAYTONA_DAEMON_LOG_FILE_PATH\"`\n\tUserHomeAsWorkDir        bool          `envconfig:\"DAYTONA_USER_HOME_AS_WORKDIR\"`\n\tSandboxId                string        `envconfig:\"DAYTONA_SANDBOX_ID\" validate:\"required\"`\n\tOtelEndpoint             *string       `envconfig:\"DAYTONA_OTEL_ENDPOINT\"`\n\tTerminationCheckInterval time.Duration `envconfig:\"DAYTONA_TERMINATION_CHECK_INTERVAL\" default:\"100ms\" validate:\"min_duration=1ms\"`\n\tTerminationGracePeriod   time.Duration `envconfig:\"DAYTONA_TERMINATION_GRACE_PERIOD\" default:\"5s\" validate:\"min_duration=1s\"`\n\tRecordingsDir            string        `envconfig:\"DAYTONA_RECORDINGS_DIR\"`\n\tOrganizationId           *string       `envconfig:\"DAYTONA_ORGANIZATION_ID\"`\n\tRegionId                 *string       `envconfig:\"DAYTONA_REGION_ID\"`\n}\n\nvar defaultDaemonLogFilePath = \"/tmp/daytona-daemon.log\"\n\nvar config *Config\n\nfunc GetConfig() (*Config, error) {\n\tif config != nil {\n\t\treturn config, nil\n\t}\n\n\tconfig = &Config{}\n\n\terr := envconfig.Process(\"\", config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar validate = validator.New()\n\n\t// Register a custom tag \"min_duration\" that accepts a duration string like \"1ms\"\n\terr = validate.RegisterValidation(\"min_duration\", func(fl validator.FieldLevel) bool {\n\t\tmin, err := time.ParseDuration(fl.Param())\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\td, ok := fl.Field().Interface().(time.Duration)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\treturn d >= min\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\terr = validate.Struct(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif config.DaemonLogFilePath == \"\" {\n\t\tconfig.DaemonLogFilePath = defaultDaemonLogFilePath\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "apps/daemon/cmd/daemon/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"syscall\"\n\t\"time\"\n\n\tgolog \"log\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\t\"github.com/daytonaio/daemon/cmd/daemon/config\"\n\t\"github.com/daytonaio/daemon/internal/util\"\n\t\"github.com/daytonaio/daemon/pkg/recording\"\n\t\"github.com/daytonaio/daemon/pkg/recordingdashboard\"\n\t\"github.com/daytonaio/daemon/pkg/session\"\n\t\"github.com/daytonaio/daemon/pkg/ssh\"\n\t\"github.com/daytonaio/daemon/pkg/terminal\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox\"\n\t\"github.com/lmittmann/tint\"\n\t\"github.com/mattn/go-isatty\"\n)\n\nfunc main() {\n\tos.Exit(run())\n}\n\nfunc run() int {\n\tlogLevel := log.ParseLogLevel(os.Getenv(\"LOG_LEVEL\"))\n\n\t// Create the console handler with tint for colored output\n\tconsoleHandler := tint.NewHandler(os.Stdout, &tint.Options{\n\t\tNoColor:    !isatty.IsTerminal(os.Stdout.Fd()),\n\t\tTimeFormat: time.RFC3339,\n\t\tLevel:      logLevel,\n\t})\n\n\tlogger := slog.New(consoleHandler)\n\tslog.SetDefault(logger)\n\n\t// Redirect standard library log to slog\n\tgolog.SetOutput(&log.DebugLogWriter{})\n\n\thomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\tlogger.Error(\"Failed to get user home directory\", \"error\", err)\n\t\treturn 2\n\t}\n\n\tconfigDir := filepath.Join(homeDir, \".daytona\")\n\terr = os.MkdirAll(configDir, 0755)\n\tif err != nil {\n\t\tlogger.Error(\"Failed to create config directory\", \"path\", configDir, \"error\", err)\n\t\treturn 2\n\t}\n\n\tentrypointLogFilePath := filepath.Join(configDir, \"sessions\", util.EntrypointSessionID, util.EntrypointCommandID, \"output.log\")\n\n\t// Check if user wants to read entrypoint logs\n\targs := os.Args[1:]\n\tif len(args) == 2 && args[0] == \"entrypoint\" && args[1] == \"logs\" {\n\t\terr := util.ReadEntrypointLogs(entrypointLogFilePath)\n\t\tif err != nil {\n\t\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\t\tlogger.Warn(\"Logs not found, please check if correct entrypoint was provided for sandbox.\")\n\t\t\t} else {\n\t\t\t\tlogger.Error(\"Failed to read entrypoint log file\", \"error\", err)\n\t\t\t}\n\n\t\t\treturn 1\n\t\t}\n\n\t\treturn 0\n\t}\n\n\tc, err := config.GetConfig()\n\tif err != nil {\n\t\tlogger.Error(\"Failed to get config\", \"error\", err)\n\t\treturn 2\n\t}\n\n\t// If workdir in image is not set, use user home as workdir\n\tif c.UserHomeAsWorkDir {\n\t\terr = os.Chdir(homeDir)\n\t\tif err != nil {\n\t\t\tlogger.Warn(\"Failed to change working directory to home directory\", \"error\", err)\n\t\t}\n\t}\n\n\tvar logWriter io.Writer\n\tif c.DaemonLogFilePath != \"\" {\n\t\tlogFile, err := os.OpenFile(c.DaemonLogFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\n\t\tif err != nil {\n\t\t\tlogger.Error(\"Failed to open log file\", \"path\", c.DaemonLogFilePath, \"error\", err)\n\t\t} else {\n\t\t\tdefer logFile.Close()\n\t\t\tlogWriter = logFile\n\n\t\t\tfileHandler := slog.NewTextHandler(logWriter, &slog.HandlerOptions{\n\t\t\t\tLevel: logLevel,\n\t\t\t})\n\t\t\thandler := log.NewMultiHandler([]slog.Handler{consoleHandler, fileHandler}...)\n\n\t\t\tlogger = slog.New(handler)\n\t\t\tslog.SetDefault(logger)\n\t\t}\n\t}\n\n\tsessionService := session.NewSessionService(logger, configDir, c.TerminationGracePeriod, c.TerminationCheckInterval)\n\n\t// Execute passed arguments as command in entrypoint session\n\tif len(args) > 0 {\n\t\t// Create entrypoint session\n\t\terr = sessionService.Create(util.EntrypointSessionID, false)\n\t\tif err != nil {\n\t\t\tlogger.Error(\"Failed to create entrypoint session\", \"error\", err)\n\t\t\treturn 2\n\t\t}\n\n\t\t// Defer entrypoint session deletion concurrently with toolbox shutdown\n\t\tdefer func() {\n\t\t\tdelErr := sessionService.Delete(context.Background(), util.EntrypointSessionID)\n\t\t\tif delErr != nil {\n\t\t\t\tlogger.Error(\"Failed to delete entrypoint session\", \"error\", delErr)\n\t\t\t} else {\n\t\t\t\tlogger.Debug(\"Deleted entrypoint session\", \"session_id\", util.EntrypointSessionID)\n\t\t\t}\n\t\t}()\n\n\t\tlogger.Debug(\"Created entrypoint session\", \"session_id\", util.EntrypointSessionID)\n\n\t\t// Execute command asynchronously via session\n\t\tcommand := util.ShellQuoteJoin(args)\n\t\t_, err := sessionService.Execute(\n\t\t\tutil.EntrypointSessionID,\n\t\t\tutil.EntrypointCommandID,\n\t\t\tcommand,\n\t\t\ttrue,  // async=true for non-blocking\n\t\t\tfalse, // isCombinedOutput=false\n\t\t\ttrue,  // suppressInputEcho=true\n\t\t)\n\t\tif err != nil {\n\t\t\tlogger.Error(\"Failed to execute entrypoint command\", \"error\", err)\n\t\t\treturn 2\n\t\t}\n\t}\n\n\terrChan := make(chan error)\n\n\tworkDir, err := os.Getwd()\n\tif err != nil {\n\t\tlogger.Error(\"Failed to get current working directory\", \"error\", err)\n\t\treturn 2\n\t}\n\n\trecordingsDir := c.RecordingsDir\n\tif recordingsDir == \"\" {\n\t\trecordingsDir = filepath.Join(configDir, \"recordings\")\n\t}\n\trecordingService := recording.NewRecordingService(logger, recordingsDir)\n\n\ttoolBoxServer := toolbox.NewServer(toolbox.ServerConfig{\n\t\tLogger:                logger,\n\t\tWorkDir:               workDir,\n\t\tConfigDir:             configDir,\n\t\tOtelEndpoint:          c.OtelEndpoint,\n\t\tSandboxId:             c.SandboxId,\n\t\tSessionService:        sessionService,\n\t\tRecordingService:      recordingService,\n\t\tOrganizationId:        c.OrganizationId,\n\t\tRegionId:              c.RegionId,\n\t\tEntrypointLogFilePath: entrypointLogFilePath,\n\t})\n\n\t// Start the toolbox server in a go routine\n\tgo func() {\n\t\terr := toolBoxServer.Start()\n\t\tif err != nil {\n\t\t\terrChan <- err\n\t\t}\n\t}()\n\n\t// Start terminal server\n\tgo func() {\n\t\tif err := terminal.StartTerminalServer(22222); err != nil {\n\t\t\terrChan <- err\n\t\t}\n\t}()\n\n\t// Start recording dashboard server\n\tgo func() {\n\t\tif err := recordingdashboard.NewDashboardServer(logger, recordingService).Start(); err != nil {\n\t\t\terrChan <- err\n\t\t}\n\t}()\n\n\tsshServer := ssh.NewServer(logger, workDir, workDir)\n\n\tgo func() {\n\t\tif err := sshServer.Start(); err != nil {\n\t\t\terrChan <- err\n\t\t}\n\t}()\n\n\t// Set up signal handling for graceful shutdown\n\tsigChan := make(chan os.Signal, 1)\n\tsignal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)\n\n\t// Wait for either an error or shutdown signal\n\tselect {\n\tcase err := <-errChan:\n\t\tlogger.Error(\"Error occurred\", \"error\", err)\n\tcase sig := <-sigChan:\n\t\tlogger.Info(\"Received signal, shutting down gracefully...\", \"signal\", sig)\n\t}\n\n\t// Toolbox server graceful shutdown\n\ttoolBoxServer.Shutdown()\n\n\tslog.Info(\"Shutdown complete\")\n\treturn 0\n}\n"
  },
  {
    "path": "apps/daemon/go.mod",
    "content": "module github.com/daytonaio/daemon\n\ngo 1.25.4\n\n// v0.5.0 breaks tailscale-connected docker clients so we need to pin it to v0.4.0\nreplace github.com/docker/go-connections => github.com/docker/go-connections v0.4.0\n\n// samber/lo v1.47.0 - required by headscale breaks frp\nreplace github.com/samber/lo => github.com/samber/lo v1.39.0\n\nrequire (\n\tgithub.com/Masterminds/semver/v3 v3.4.0\n\tgithub.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5\n\tgithub.com/creack/pty v1.1.23\n\tgithub.com/gin-gonic/gin v1.10.1\n\tgithub.com/gliderlabs/ssh v0.3.8\n\tgithub.com/go-git/go-git/v5 v5.16.5\n\tgithub.com/go-playground/validator/v10 v10.27.0\n\tgithub.com/google/uuid v1.6.0\n\tgithub.com/gorilla/websocket v1.5.3\n\tgithub.com/hashicorp/go-hclog v1.6.3\n\tgithub.com/hashicorp/go-plugin v1.6.3\n\tgithub.com/kelseyhightower/envconfig v1.4.0\n\tgithub.com/lmittmann/tint v1.1.2\n\tgithub.com/mattn/go-isatty v0.0.20\n\tgithub.com/orcaman/concurrent-map/v2 v2.0.1\n\tgithub.com/pkg/sftp v1.13.6\n\tgithub.com/samber/slog-gin v1.20.1\n\tgithub.com/shirou/gopsutil/v4 v4.25.12\n\tgithub.com/sourcegraph/jsonrpc2 v0.2.0\n\tgithub.com/stretchr/testify v1.11.1\n\tgithub.com/swaggo/files v1.0.1\n\tgithub.com/swaggo/gin-swagger v1.6.0\n\tgithub.com/swaggo/swag v1.16.4\n\tgo.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.63.0\n\tgo.opentelemetry.io/otel/sdk v1.40.0\n\tgo.opentelemetry.io/otel/sdk/log v0.14.0\n\tgo.opentelemetry.io/otel/sdk/metric v1.40.0\n\tgolang.org/x/crypto v0.47.0\n\tgolang.org/x/sys v0.40.0\n\tgopkg.in/ini.v1 v1.67.0\n)\n\nrequire (\n\tdario.cat/mergo v1.0.1 // indirect\n\tgithub.com/KyleBanks/depth v1.2.1 // indirect\n\tgithub.com/Microsoft/go-winio v0.6.2 // indirect\n\tgithub.com/ProtonMail/go-crypto v1.1.6 // indirect\n\tgithub.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect\n\tgithub.com/bytedance/sonic v1.14.0 // indirect\n\tgithub.com/bytedance/sonic/loader v0.3.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/cloudflare/circl v1.6.3 // indirect\n\tgithub.com/cloudwego/base64x v0.1.6 // indirect\n\tgithub.com/cyphar/filepath-securejoin v0.4.1 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/ebitengine/purego v0.9.1 // indirect\n\tgithub.com/emirpasic/gods v1.18.1 // indirect\n\tgithub.com/fatih/color v1.15.0 // indirect\n\tgithub.com/gabriel-vasile/mimetype v1.4.10 // indirect\n\tgithub.com/gin-contrib/sse v1.1.0 // indirect\n\tgithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect\n\tgithub.com/go-git/go-billy/v5 v5.6.2 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-ole/go-ole v1.3.0 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.21.0 // indirect\n\tgithub.com/go-openapi/jsonreference v0.21.0 // indirect\n\tgithub.com/go-openapi/spec v0.21.0 // indirect\n\tgithub.com/go-openapi/swag v0.23.0 // indirect\n\tgithub.com/go-playground/locales v0.14.1 // indirect\n\tgithub.com/go-playground/universal-translator v0.18.1 // indirect\n\tgithub.com/goccy/go-json v0.10.5 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect\n\tgithub.com/golang/protobuf v1.5.4 // indirect\n\tgithub.com/hashicorp/yamux v0.1.1 // indirect\n\tgithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/kevinburke/ssh_config v1.2.0 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.3.0 // indirect\n\tgithub.com/kr/fs v0.1.0 // indirect\n\tgithub.com/leodido/go-urn v1.4.0 // indirect\n\tgithub.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect\n\tgithub.com/mailru/easyjson v0.7.7 // indirect\n\tgithub.com/mattn/go-colorable v0.1.13 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/oklog/run v1.0.0 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.4 // indirect\n\tgithub.com/pjbgf/sha1cd v0.3.2 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect\n\tgithub.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect\n\tgithub.com/skeema/knownhosts v1.3.1 // indirect\n\tgithub.com/tklauser/go-sysconf v0.3.16 // indirect\n\tgithub.com/tklauser/numcpus v0.11.0 // indirect\n\tgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirect\n\tgithub.com/ugorji/go/codec v1.3.0 // indirect\n\tgithub.com/xanzy/ssh-agent v0.3.3 // indirect\n\tgithub.com/yusufpapurcu/wmi v1.2.4 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/otel v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/log v0.14.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.40.0 // indirect\n\tgolang.org/x/arch v0.20.0 // indirect\n\tgolang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect\n\tgolang.org/x/net v0.49.0 // indirect\n\tgolang.org/x/text v0.33.0 // indirect\n\tgolang.org/x/tools v0.40.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect\n\tgoogle.golang.org/grpc v1.79.3 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/warnings.v0 v0.1.2 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "apps/daemon/go.sum",
    "content": "dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=\ndario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=\ngithub.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=\ngithub.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=\ngithub.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=\ngithub.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=\ngithub.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=\ngithub.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=\ngithub.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=\ngithub.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=\ngithub.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=\ngithub.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=\ngithub.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=\ngithub.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=\ngithub.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=\ngithub.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=\ngithub.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=\ngithub.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=\ngithub.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5 h1:BjkPE3785EwPhhyuFkbINB+2a1xATwk8SNDWnJiD41g=\ngithub.com/cakturk/go-netstat v0.0.0-20200220111822-e5b49efee7a5/go.mod h1:jtAfVaU/2cu1+wdSRPWE2c1N2qeAA3K4RH9pYgqwets=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=\ngithub.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=\ngithub.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=\ngithub.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=\ngithub.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=\ngithub.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=\ngithub.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=\ngithub.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=\ngithub.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=\ngithub.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=\ngithub.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=\ngithub.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=\ngithub.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=\ngithub.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=\ngithub.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=\ngithub.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=\ngithub.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=\ngithub.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=\ngithub.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=\ngithub.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=\ngithub.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=\ngithub.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=\ngithub.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=\ngithub.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=\ngithub.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=\ngithub.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=\ngithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=\ngithub.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=\ngithub.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=\ngithub.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=\ngithub.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=\ngithub.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=\ngithub.com/go-git/go-git/v5 v5.16.5 h1:mdkuqblwr57kVfXri5TTH+nMFLNUxIj9Z7F5ykFbw5s=\ngithub.com/go-git/go-git/v5 v5.16.5/go.mod h1:QOMLpNf1qxuSY4StA/ArOdfFR2TrKEjJiye2kel2m+M=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=\ngithub.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=\ngithub.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=\ngithub.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=\ngithub.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=\ngithub.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=\ngithub.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=\ngithub.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=\ngithub.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=\ngithub.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=\ngithub.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=\ngithub.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=\ngithub.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=\ngithub.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=\ngithub.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=\ngithub.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=\ngithub.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=\ngithub.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=\ngithub.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=\ngithub.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=\ngithub.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=\ngithub.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=\ngithub.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=\ngithub.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg=\ngithub.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0=\ngithub.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=\ngithub.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=\ngithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=\ngithub.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=\ngithub.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=\ngithub.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=\ngithub.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=\ngithub.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=\ngithub.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=\ngithub.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=\ngithub.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=\ngithub.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=\ngithub.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=\ngithub.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=\ngithub.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=\ngithub.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w=\ngithub.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=\ngithub.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k=\ngithub.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=\ngithub.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=\ngithub.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=\ngithub.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=\ngithub.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=\ngithub.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=\ngithub.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=\ngithub.com/orcaman/concurrent-map/v2 v2.0.1 h1:jOJ5Pg2w1oeB6PeDurIYf6k9PQ+aTITr/6lP/L/zp6c=\ngithub.com/orcaman/concurrent-map/v2 v2.0.1/go.mod h1:9Eq3TG2oBe5FirmYWQfYO5iH1q0Jv47PLaNK++uCdOM=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=\ngithub.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=\ngithub.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=\ngithub.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=\ngithub.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/samber/slog-gin v1.20.1 h1:75wbryS7XrmGcVu/lfOwSFWWjmGoqV4GlE41nQFP0a4=\ngithub.com/samber/slog-gin v1.20.1/go.mod h1:7R4VMQGENllRLLnwGyoB5nUSB+qzxThpGe5G02xla6o=\ngithub.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=\ngithub.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=\ngithub.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY=\ngithub.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU=\ngithub.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=\ngithub.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=\ngithub.com/sourcegraph/jsonrpc2 v0.2.0 h1:KjN/dC4fP6aN9030MZCJs9WQbTOjWHhrtKVpzzSrr/U=\ngithub.com/sourcegraph/jsonrpc2 v0.2.0/go.mod h1:ZafdZgk/axhT1cvZAPOhw+95nz2I/Ra5qMlU4gTRwIo=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=\ngithub.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=\ngithub.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=\ngithub.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=\ngithub.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=\ngithub.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg=\ngithub.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=\ngithub.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=\ngithub.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=\ngithub.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=\ngithub.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=\ngithub.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=\ngithub.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=\ngithub.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=\ngithub.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=\ngithub.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=\ngithub.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.63.0 h1:5kSIJ0y8ckZZKoDhZHdVtcyjVi6rXyAwyaR8mp4zLbg=\ngo.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.63.0/go.mod h1:i+fIMHvcSQtsIY82/xgiVWRklrNt/O6QriHLjzGeY+s=\ngo.opentelemetry.io/contrib/propagators/b3 v1.38.0 h1:uHsCCOSKl0kLrV2dLkFK+8Ywk9iKa/fptkytc6aFFEo=\ngo.opentelemetry.io/contrib/propagators/b3 v1.38.0/go.mod h1:wMRSZJZcY8ya9mApLLhwIMjqmApy2o/Ml+62lhvxyHU=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE=\ngo.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM=\ngo.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=\ngo.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=\ngo.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=\ngo.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg=\ngo.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngolang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=\ngolang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=\ngolang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=\ngolang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=\ngolang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=\ngolang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=\ngolang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=\ngolang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=\ngolang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=\ngolang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=\ngolang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=\ngolang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=\ngolang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=\ngonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=\ngoogle.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=\ngopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=\ngopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=\ngopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "apps/daemon/internal/buildinfo.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage internal\n\nvar (\n\tVersion = \"v0.0.0-dev\"\n)\n"
  },
  {
    "path": "apps/daemon/internal/util/entrypoint_logs.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n)\n\nfunc ReadEntrypointLogs(entrypointLogFilePath string) error {\n\tif entrypointLogFilePath == \"\" {\n\t\treturn errors.New(\"entrypoint log file path is not configured\")\n\t}\n\n\tlogFile, err := os.Open(entrypointLogFilePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open entrypoint log file at %s: %w\", entrypointLogFilePath, err)\n\t}\n\tdefer logFile.Close()\n\n\terrChan := make(chan error, 1)\n\tstdoutChan := make(chan []byte)\n\tstderrChan := make(chan []byte)\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\tgo log.ReadMultiplexedLog(ctx, logFile, true, stdoutChan, stderrChan, errChan)\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil\n\t\tcase line := <-stdoutChan:\n\t\t\t_, err := os.Stdout.Write(line)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to write entrypoint log line to stdout: %w\", err)\n\t\t\t}\n\t\tcase line := <-stderrChan:\n\t\t\t_, err := os.Stderr.Write(line)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to write entrypoint log line to stderr: %w\", err)\n\t\t\t}\n\t\tcase err := <-errChan:\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/internal/util/entrypoint_session.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nconst EntrypointSessionID string = \"entrypoint\"\nconst EntrypointCommandID string = \"entrypoint_command\"\nconst EmptyCommandID string = \"\"\n"
  },
  {
    "path": "apps/daemon/internal/util/log_reader.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc ReadLogWithExitCode(ctx context.Context, logReader io.Reader, follow bool, exitCodeFilePath string, c chan []byte, errChan chan error) {\n\treader := bufio.NewReader(logReader)\n\tconsecutiveEOFCount := 0\n\tmaxConsecutiveEOF := 50 // Check exit code after 50 consecutive EOF reads ( 50 * 20ms = 1 second)\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tdefault:\n\t\t\tbytes := make([]byte, 1024)\n\t\t\tn, err := reader.Read(bytes)\n\n\t\t\tif err != nil {\n\t\t\t\tif err != io.EOF {\n\t\t\t\t\terrChan <- err\n\t\t\t\t\treturn\n\t\t\t\t} else if !follow {\n\t\t\t\t\terrChan <- io.EOF\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// EOF while following - increment counter\n\t\t\t\tconsecutiveEOFCount++\n\n\t\t\t\t// Check exit code after maxConsecutiveEOF consecutive EOF reads\n\t\t\t\tif exitCodeFilePath != \"\" && consecutiveEOFCount >= maxConsecutiveEOF {\n\t\t\t\t\thasExit := hasExitCode(exitCodeFilePath)\n\t\t\t\t\tif hasExit {\n\t\t\t\t\t\terrChan <- io.EOF\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t// Reset counter and continue\n\t\t\t\t\tconsecutiveEOFCount = 0\n\t\t\t\t}\n\n\t\t\t\t// Sleep for a short time to avoid busy-waiting\n\t\t\t\ttime.Sleep(20 * time.Millisecond)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Reset EOF counter on successful read\n\t\t\tif consecutiveEOFCount > 0 {\n\t\t\t\tconsecutiveEOFCount = 0\n\t\t\t}\n\n\t\t\tif n > 0 {\n\t\t\t\t// Create a new slice with only the actual read data to avoid sending null bytes\n\t\t\t\tdata := make([]byte, n)\n\t\t\t\tcopy(data, bytes[:n])\n\t\t\t\tc <- data\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc hasExitCode(exitCodeFilePath string) bool {\n\tcontent, err := os.ReadFile(exitCodeFilePath)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn len(strings.TrimSpace(string(content))) > 0\n}\n"
  },
  {
    "path": "apps/daemon/internal/util/pointer.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\n// Use generics to create a pointer to a value\nfunc Pointer[T any](d T) *T {\n\treturn &d\n}\n"
  },
  {
    "path": "apps/daemon/internal/util/sandbox.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"errors\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nfunc GetValidatedName(input string) (string, error) {\n\tinput = strings.ReplaceAll(input, \" \", \"-\")\n\n\t// Regular expression that catches letters, numbers, and dashes\n\tpattern := \"^[a-zA-Z0-9-]+$\"\n\n\tmatched, err := regexp.MatchString(pattern, input)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif !matched {\n\t\treturn \"\", errors.New(\"only letters, numbers, and dashes are allowed\")\n\t}\n\n\treturn input, nil\n}\n\nfunc GetValidatedUrl(input string) (string, error) {\n\t// Check if the input starts with a scheme (e.g., http:// or https://)\n\tif !strings.HasPrefix(input, \"http://\") && !strings.HasPrefix(input, \"https://\") {\n\t\treturn \"\", errors.New(\"input is missing http:// or https://\")\n\t}\n\n\t// Try to parse the input as a URL\n\tparsedURL, err := url.Parse(input)\n\tif err != nil {\n\t\treturn \"\", errors.New(\"input is not a valid URL\")\n\t}\n\n\t// If parsing was successful, return the fixed URL\n\treturn parsedURL.String(), nil\n}\n\nfunc GetRepositorySlugFromUrl(url string, specifyGitProviders bool) string {\n\tif url == \"\" {\n\t\treturn \"/\"\n\t}\n\turl = strings.TrimSuffix(url, \"/\")\n\n\tparts := strings.Split(url, \"/\")\n\tif len(parts) < 2 {\n\t\treturn \"\"\n\t}\n\n\tif specifyGitProviders {\n\t\treturn parts[len(parts)-3] + \"/\" + parts[len(parts)-2] + \"/\" + parts[len(parts)-1]\n\t}\n\n\treturn parts[len(parts)-2] + \"/\" + parts[len(parts)-1]\n}\n\nfunc CleanUpRepositoryUrl(url string) string {\n\turl = strings.ToLower(url)\n\treturn strings.TrimSuffix(url, \"/\")\n}\n"
  },
  {
    "path": "apps/daemon/internal/util/shell_quote.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport \"strings\"\n\n// ShellQuoteJoin quotes each argument for safe use in a shell command string.\n// Each arg is wrapped in single quotes, with any internal single quotes escaped.\nfunc ShellQuoteJoin(args []string) string {\n\tquoted := make([]string, len(args))\n\tfor i, arg := range args {\n\t\tquoted[i] = \"'\" + strings.ReplaceAll(arg, \"'\", \"'\\\\''\") + \"'\"\n\t}\n\treturn strings.Join(quoted, \" \")\n}\n"
  },
  {
    "path": "apps/daemon/internal/util/version.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strings\"\n\n\tsemver \"github.com/Masterminds/semver/v3\"\n)\n\n// ExtractSdkVersionFromHeader extracts the SDK version from the headers.\n// If the X-Daytona-SDK-Version header is not present, it looks through\n// the Sec-WebSocket-Protocol header looking for the version protocol formatted like\n// X-Daytona-SDK-Version/<version>.\n// If no version is found, it returns an empty string.\nfunc ExtractSdkVersionFromHeader(header http.Header) string {\n\tif v := header.Get(\"X-Daytona-SDK-Version\"); v != \"\" {\n\t\treturn v\n\t}\n\n\t// no explicit header; look through Sec-WebSocket-Protocol entries\n\tprotocol := ExtractSdkVersionSubprotocol(header)\n\tif protocol != \"\" {\n\t\t// found version protocol; split off the version\n\t\tparts := strings.SplitN(protocol, \"~\", 2)\n\t\tif len(parts) == 2 {\n\t\t\treturn parts[1]\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// ExtractSdkVersionSubprotocol extracts the SDK version subprotocol from request headers\n// It looks for the X-Daytona-SDK-Version~<version> subprotocol in the Sec-WebSocket-Protocol header.\n// Returns an empty string if no SDK version subprotocol is found.\nfunc ExtractSdkVersionSubprotocol(header http.Header) string {\n\tsubprotocols := header.Get(\"Sec-WebSocket-Protocol\")\n\tif subprotocols == \"\" {\n\t\treturn \"\"\n\t}\n\n\tconst prefix = \"X-Daytona-SDK-Version~\"\n\t// split comma-separated protocols\n\tfor _, subprotocol := range strings.Split(subprotocols, \",\") {\n\t\tsubprotocol = strings.TrimSpace(subprotocol)\n\t\tif strings.HasPrefix(subprotocol, prefix) {\n\t\t\t// Return the full subprotocol string\n\t\t\treturn subprotocol\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// CompareVersions compares two versions and returns:\n// 1 if v1 is greater than v2\n// -1 if v1 is less than v2\n// 0 if they are equal\n//\n// It considers pre-releases to be invalid if the ranges does not include one.\n// If you want to have it include pre-releases a simple solution is to include -0 in your range.\nfunc CompareVersions(v1 string, v2 string) (*int, error) {\n\tsemverV1, err := semver.NewVersion(normalizeSemver(v1))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse semver v1: %s, normalized: %s, error: %w\", v1, normalizeSemver(v1), err)\n\t}\n\tsemverV2, err := semver.NewVersion(normalizeSemver(v2))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse semver v2: %s, normalized: %s, error: %w\", v2, normalizeSemver(v2), err)\n\t}\n\n\tcomparison := semverV1.Compare(semverV2)\n\treturn &comparison, nil\n}\n\nfunc normalizeSemver(input string) string {\n\t// If it's already in the form X.Y.Z-suffix, return as-is.\n\treAlreadyDashed := regexp.MustCompile(`^\\d+\\.\\d+\\.\\d+-\\S+$`)\n\tif reAlreadyDashed.MatchString(input) {\n\t\treturn input\n\t}\n\n\t// If there's a non-digit suffix immediately after X.Y.Z, dash it.\n\treNeedsDash := regexp.MustCompile(`^(\\d+)\\.(\\d+)\\.(\\d+)(\\D.+)$`)\n\tif reNeedsDash.MatchString(input) {\n\t\treturn reNeedsDash.ReplaceAllString(input, `$1.$2.$3-$4`)\n\t}\n\n\t// Otherwise (pure X.Y.Z or something else), leave unchanged.\n\treturn input\n}\n"
  },
  {
    "path": "apps/daemon/internal/util/websocket.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gorilla/websocket\"\n)\n\n// UpgradeToWebSocket is a toolbox utility function that upgrades an HTTP connection to a WebSocket connection.\n// It automatically extracts and accepts SDK version subprotocols (if present) from the request headers and accepts them during handshake.\n// It uses a permissive CORS (CheckOrigin always returns true) to allow connections from any origin.\nfunc UpgradeToWebSocket(w http.ResponseWriter, r *http.Request) (*websocket.Conn, error) {\n\t// Extract SDK version subprotocol from request headers\n\tsubprotocol := ExtractSdkVersionSubprotocol(r.Header)\n\tvar protocols []string\n\tif subprotocol != \"\" {\n\t\tprotocols = []string{subprotocol}\n\t}\n\n\t// Create a new upgrader for this request to prevent concurrency issues\n\tupgrader := websocket.Upgrader{\n\t\tCheckOrigin:  func(r *http.Request) bool { return true },\n\t\tSubprotocols: protocols,\n\t}\n\n\t// Upgrade the connection to a WebSocket protocol\n\tws, err := upgrader.Upgrade(w, r, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ws, nil\n}\n"
  },
  {
    "path": "apps/daemon/internal/util/ws_keepalive.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"log/slog\"\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n)\n\n// SetupWSKeepAlive configures WebSocket keepalive ping/pong handling on the\n// given connection. It installs a custom PingHandler that queues pong payloads\n// onto a buffered channel instead of writing to the connection directly. This\n// avoids write-mutex contention between the PingHandler and the caller's\n// single writer goroutine.\n//\n// The caller's writer goroutine must drain the returned channel via\n// WritePendingPongs before each data write so that keepalive pongs are never\n// delayed.\nfunc SetupWSKeepAlive(conn *websocket.Conn, logger *slog.Logger) <-chan []byte {\n\tpongCh := make(chan []byte, 10)\n\tconn.SetPingHandler(func(message string) error {\n\t\tselect {\n\t\tcase pongCh <- []byte(message):\n\t\tdefault:\n\t\t\tlogger.Warn(\"pong channel full, dropping pong response\")\n\t\t}\n\t\treturn nil\n\t})\n\treturn pongCh\n}\n\n// WritePendingPongs drains all queued pong responses and writes them to the\n// connection. This MUST be called from the single writer goroutine before each\n// data write so that keepalive pongs are never delayed by data writes. Because\n// only one goroutine writes to the conn, WriteControl acquires the\n// gorilla/websocket write mutex instantly — no contention, no silent drops.\nfunc WritePendingPongs(conn *websocket.Conn, pongCh <-chan []byte, deadline time.Duration, logger *slog.Logger) {\n\tfor {\n\t\tselect {\n\t\tcase pongData := <-pongCh:\n\t\t\tif err := conn.WriteControl(websocket.PongMessage, pongData, time.Now().Add(deadline)); err != nil {\n\t\t\t\tlogger.Debug(\"failed to write pong\", \"error\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/common/errors.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"time\"\n)\n\n// ErrorResponse represents the error response structure\n//\n//\t@Description\tError response\n//\t@Schema\t\t\tErrorResponse\ntype ErrorResponse struct {\n\tStatusCode int       `json:\"statusCode\" example:\"400\" binding:\"required\"`\n\tMessage    string    `json:\"message\" example:\"Bad request\" binding:\"required\"`\n\tCode       string    `json:\"code\" example:\"BAD_REQUEST\" binding:\"required\"`\n\tTimestamp  time.Time `json:\"timestamp\" example:\"2023-01-01T12:00:00Z\" binding:\"required\"`\n\tPath       string    `json:\"path\" example:\"/api/resource\" binding:\"required\"`\n\tMethod     string    `json:\"method\" example:\"GET\" binding:\"required\"`\n} //\t@name\tErrorResponse\n"
  },
  {
    "path": "apps/daemon/pkg/common/get_shell.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n)\n\nfunc GetShell() string {\n\tout, err := exec.Command(\"sh\", \"-c\", \"grep '^[^#]' /etc/shells\").Output()\n\tif err != nil {\n\t\treturn \"sh\"\n\t}\n\n\tif strings.Contains(string(out), \"/usr/bin/zsh\") {\n\t\treturn \"/usr/bin/zsh\"\n\t}\n\n\tif strings.Contains(string(out), \"/bin/zsh\") {\n\t\treturn \"/bin/zsh\"\n\t}\n\n\tif strings.Contains(string(out), \"/usr/bin/bash\") {\n\t\treturn \"/usr/bin/bash\"\n\t}\n\n\tif strings.Contains(string(out), \"/bin/bash\") {\n\t\treturn \"/bin/bash\"\n\t}\n\n\tshellEnv, shellSet := os.LookupEnv(\"SHELL\")\n\n\tif shellSet {\n\t\treturn shellEnv\n\t}\n\n\treturn \"sh\"\n}\n"
  },
  {
    "path": "apps/daemon/pkg/common/spawn_tty.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/creack/pty\"\n)\n\ntype TTYSize struct {\n\tHeight int\n\tWidth  int\n}\n\ntype SpawnTTYOptions struct {\n\tDir    string\n\tStdIn  io.Reader\n\tStdOut io.Writer\n\tTerm   string\n\tEnv    []string\n\tSizeCh <-chan TTYSize\n}\n\nfunc SpawnTTY(opts SpawnTTYOptions) error {\n\tshell := GetShell()\n\tcmd := exec.Command(shell)\n\n\tcmd.Dir = opts.Dir\n\n\tcmd.Env = append(cmd.Env, fmt.Sprintf(\"TERM=%s\", opts.Term))\n\tcmd.Env = append(cmd.Env, os.Environ()...)\n\tcmd.Env = append(cmd.Env, fmt.Sprintf(\"SHELL=%s\", shell))\n\tcmd.Env = append(cmd.Env, opts.Env...)\n\n\tf, err := pty.Start(cmd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer f.Close()\n\n\tgo func() {\n\t\tfor win := range opts.SizeCh {\n\t\t\tsyscall.Syscall(syscall.SYS_IOCTL, f.Fd(), uintptr(syscall.TIOCSWINSZ),\n\t\t\t\tuintptr(unsafe.Pointer(&struct{ h, w, x, y uint16 }{uint16(win.Height), uint16(win.Width), 0, 0})))\n\t\t}\n\t}()\n\n\tgo func() {\n\t\tio.Copy(f, opts.StdIn) // stdin\n\t}()\n\n\t_, err = io.Copy(opts.StdOut, f) // stdout\n\treturn err\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/add.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport \"github.com/go-git/go-git/v5\"\n\nfunc (s *Service) Add(files []string) error {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tw, err := repo.Worktree()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, file := range files {\n\t\t_, err = w.Add(file)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/branch.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plumbing\"\n)\n\nfunc (s *Service) CreateBranch(name string) error {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tw, err := repo.Worktree()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn w.Checkout(&git.CheckoutOptions{\n\t\tCreate: true,\n\t\tBranch: plumbing.NewBranchReferenceName(name),\n\t})\n}\n\nfunc (s *Service) ListBranches() ([]string, error) {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn []string{}, err\n\t}\n\n\tbranches, err := repo.Branches()\n\tif err != nil {\n\t\treturn []string{}, err\n\t}\n\n\tvar branchList []string\n\terr = branches.ForEach(func(ref *plumbing.Reference) error {\n\t\tbranchList = append(branchList, ref.Name().Short())\n\t\treturn nil\n\t})\n\n\treturn branchList, err\n}\n\nfunc (s *Service) DeleteBranch(name string) error {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn repo.Storer.RemoveReference(plumbing.NewBranchReferenceName(name))\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/checkout.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plumbing\"\n)\n\nfunc (s *Service) Checkout(branch string) error {\n\tr, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open repository: %w\", err)\n\t}\n\n\tw, err := r.Worktree()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get worktree: %w\", err)\n\t}\n\n\t// Try to checkout as a branch first\n\terr = w.Checkout(&git.CheckoutOptions{\n\t\tBranch: plumbing.NewBranchReferenceName(branch),\n\t})\n\n\tif err != nil {\n\t\t// If branch checkout fails, try as a commit hash\n\t\terr = w.Checkout(&git.CheckoutOptions{\n\t\t\tHash: plumbing.NewHash(branch),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to checkout branch or commit '%s': %w\", branch, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/clone.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/daemon/pkg/gitprovider\"\n\t\"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plumbing\"\n\t\"github.com/go-git/go-git/v5/plumbing/protocol/packp/capability\"\n\t\"github.com/go-git/go-git/v5/plumbing/transport\"\n\t\"github.com/go-git/go-git/v5/plumbing/transport/http\"\n)\n\nfunc (s *Service) CloneRepository(repo *gitprovider.GitRepository, auth *http.BasicAuth) error {\n\tcloneOptions := &git.CloneOptions{\n\t\tURL:             repo.Url,\n\t\tSingleBranch:    true,\n\t\tInsecureSkipTLS: true,\n\t\tAuth:            auth,\n\t}\n\n\tif s.LogWriter != nil {\n\t\tcloneOptions.Progress = s.LogWriter\n\t}\n\n\t// Azure DevOps requires capabilities multi_ack / multi_ack_detailed,\n\t// which are not fully implemented and by default are included in\n\t// transport.UnsupportedCapabilities.\n\t//\n\t// This can be removed once go-git implements the git v2 protocol.\n\ttransport.UnsupportedCapabilities = []capability.Capability{\n\t\tcapability.ThinPack,\n\t}\n\n\tif repo.Branch != \"\" {\n\t\tcloneOptions.ReferenceName = plumbing.NewBranchReferenceName(repo.Branch)\n\t}\n\n\t_, err := git.PlainClone(s.WorkDir, false, cloneOptions)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif repo.Target == gitprovider.CloneTargetCommit {\n\t\tr, err := git.PlainOpen(s.WorkDir)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tw, err := r.Worktree()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = w.Checkout(&git.CheckoutOptions{\n\t\t\tHash: plumbing.NewHash(repo.Sha),\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn err\n}\n\nfunc (s *Service) CloneRepositoryCmd(repo *gitprovider.GitRepository, auth *http.BasicAuth) []string {\n\tcloneCmd := []string{\"git\", \"clone\", \"--single-branch\"}\n\n\t// Only add branch flag if a specific branch is provided\n\tif repo.Branch != \"\" {\n\t\tcloneCmd = append(cloneCmd, \"--branch\", fmt.Sprintf(\"\\\"%s\\\"\", repo.Branch))\n\t}\n\n\tcloneUrl := repo.Url\n\n\t// Default to https protocol if not specified\n\tif !strings.Contains(cloneUrl, \"://\") {\n\t\tcloneUrl = fmt.Sprintf(\"https://%s\", cloneUrl)\n\t}\n\n\tif auth != nil {\n\t\tcloneUrl = fmt.Sprintf(\"%s://%s:%s@%s\", strings.Split(cloneUrl, \"://\")[0], auth.Username, auth.Password, strings.SplitN(cloneUrl, \"://\", 2)[1])\n\t}\n\n\tcloneCmd = append(cloneCmd, cloneUrl, s.WorkDir)\n\n\tif repo.Target == gitprovider.CloneTargetCommit {\n\t\tcloneCmd = append(cloneCmd, \"&&\", \"cd\", s.WorkDir)\n\t\tcloneCmd = append(cloneCmd, \"&&\", \"git\", \"checkout\", repo.Sha)\n\t}\n\n\treturn cloneCmd\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/commit.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport \"github.com/go-git/go-git/v5\"\n\nfunc (s *Service) Commit(message string, options *git.CommitOptions) (string, error) {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tw, err := repo.Worktree()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tcommit, err := w.Commit(message, options)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn commit.String(), nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/daytonaio/daemon/pkg/gitprovider\"\n\t\"gopkg.in/ini.v1\"\n)\n\nfunc (s *Service) SetGitConfig(userData *gitprovider.GitUser, providerConfig *gitprovider.GitProviderConfig) error {\n\tgitConfigFileName := s.GitConfigFileName\n\n\tvar gitConfigContent []byte\n\tgitConfigContent, err := os.ReadFile(gitConfigFileName)\n\tif err != nil {\n\t\tgitConfigContent = []byte{}\n\t}\n\n\tcfg, err := ini.Load(gitConfigContent)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !cfg.HasSection(\"credential\") {\n\t\t_, err := cfg.NewSection(\"credential\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t_, err = cfg.Section(\"credential\").NewKey(\"helper\", \"/usr/local/bin/daytona git-cred\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !cfg.HasSection(\"safe\") {\n\t\t_, err := cfg.NewSection(\"safe\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t_, err = cfg.Section(\"safe\").NewKey(\"directory\", s.WorkDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif userData != nil {\n\t\tif !cfg.HasSection(\"user\") {\n\t\t\t_, err := cfg.NewSection(\"user\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\t_, err := cfg.Section(\"user\").NewKey(\"name\", userData.Name)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t_, err = cfg.Section(\"user\").NewKey(\"email\", userData.Email)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err := s.setSigningConfig(cfg, providerConfig, userData); err != nil {\n\t\treturn err\n\t}\n\n\tvar buf bytes.Buffer\n\t_, err = cfg.WriteTo(&buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn os.WriteFile(gitConfigFileName, buf.Bytes(), 0644)\n}\n\nfunc (s *Service) setSigningConfig(cfg *ini.File, providerConfig *gitprovider.GitProviderConfig, userData *gitprovider.GitUser) error {\n\tif providerConfig == nil || providerConfig.SigningMethod == nil || providerConfig.SigningKey == nil {\n\t\treturn nil\n\t}\n\n\tif !cfg.HasSection(\"user\") {\n\t\t_, err := cfg.NewSection(\"user\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t_, err := cfg.Section(\"user\").NewKey(\"signingkey\", *providerConfig.SigningKey)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !cfg.HasSection(\"commit\") {\n\t\t_, err := cfg.NewSection(\"commit\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tswitch *providerConfig.SigningMethod {\n\tcase gitprovider.SigningMethodGPG:\n\t\t_, err := cfg.Section(\"commit\").NewKey(\"gpgSign\", \"true\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\tcase gitprovider.SigningMethodSSH:\n\t\terr := s.configureAllowedSigners(userData.Email, *providerConfig.SigningKey)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif !cfg.HasSection(\"gpg\") {\n\t\t\t_, err := cfg.NewSection(\"gpg\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\t_, err = cfg.Section(\"gpg\").NewKey(\"format\", \"ssh\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif !cfg.HasSection(\"gpg \\\"ssh\\\"\") {\n\t\t\t_, err := cfg.NewSection(\"gpg \\\"ssh\\\"\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tallowedSignersFile := filepath.Join(os.Getenv(\"HOME\"), \".ssh/allowed_signers\")\n\t\t_, err = cfg.Section(\"gpg \\\"ssh\\\"\").NewKey(\"allowedSignersFile\", allowedSignersFile)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (s *Service) configureAllowedSigners(email, sshKey string) error {\n\thomeDir := os.Getenv(\"HOME\")\n\tsshDir := filepath.Join(homeDir, \".ssh\")\n\tallowedSignersFile := filepath.Join(sshDir, \"allowed_signers\")\n\n\terr := os.MkdirAll(sshDir, 0700)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create SSH directory: %w\", err)\n\t}\n\n\tentry := fmt.Sprintf(\"%s namespaces=\\\"git\\\" %s\\n\", email, sshKey)\n\n\texistingContent, err := os.ReadFile(allowedSignersFile)\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"failed to read allowed_signers file: %w\", err)\n\t}\n\n\tnewContent := string(existingContent) + entry\n\n\terr = os.WriteFile(allowedSignersFile, []byte(newContent), 0600)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to write to allowed_signers file: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/log.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"github.com/go-git/go-git/v5/plumbing/object\"\n\n\t\"github.com/go-git/go-git/v5\"\n)\n\nfunc (s *Service) Log() ([]GitCommitInfo, error) {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn []GitCommitInfo{}, err\n\t}\n\n\tref, err := repo.Head()\n\tif err != nil {\n\t\treturn []GitCommitInfo{}, err\n\t}\n\n\tcommits, err := repo.Log(&git.LogOptions{From: ref.Hash()})\n\tif err != nil {\n\t\treturn []GitCommitInfo{}, err\n\t}\n\n\tvar history []GitCommitInfo\n\terr = commits.ForEach(func(commit *object.Commit) error {\n\t\thistory = append(history, GitCommitInfo{\n\t\t\tHash:      commit.Hash.String(),\n\t\t\tAuthor:    commit.Author.Name,\n\t\t\tEmail:     commit.Author.Email,\n\t\t\tMessage:   commit.Message,\n\t\t\tTimestamp: commit.Author.When,\n\t\t})\n\t\treturn nil\n\t})\n\n\treturn history, err\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/pull.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"github.com/go-git/go-git/v5/plumbing/transport/http\"\n\n\t\"github.com/go-git/go-git/v5\"\n)\n\nfunc (s *Service) Pull(auth *http.BasicAuth) error {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tw, err := repo.Worktree()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\toptions := &git.PullOptions{\n\t\tRemoteName: \"origin\",\n\t\tAuth:       auth,\n\t}\n\n\treturn w.Pull(options)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/push.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/go-git/go-git/v5/config\"\n\t\"github.com/go-git/go-git/v5/plumbing/transport/http\"\n\n\t\"github.com/go-git/go-git/v5\"\n)\n\nfunc (s *Service) Push(auth *http.BasicAuth) error {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tref, err := repo.Head()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\toptions := &git.PushOptions{\n\t\tAuth: auth,\n\t\tRefSpecs: []config.RefSpec{\n\t\t\tconfig.RefSpec(fmt.Sprintf(\"%s:%s\", ref.Name(), ref.Name())),\n\t\t},\n\t}\n\n\treturn repo.Push(options)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/service.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/daytonaio/daemon/pkg/gitprovider\"\n\t\"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plumbing/transport/http\"\n)\n\ntype GitStatus struct {\n\tCurrentBranch   string        `json:\"currentBranch\" validate:\"required\"`\n\tFiles           []*FileStatus `json:\"fileStatus\" validate:\"required\"`\n\tBranchPublished bool          `json:\"branchPublished\" validate:\"optional\"`\n\tAhead           int           `json:\"ahead\" validate:\"optional\"`\n\tBehind          int           `json:\"behind\" validate:\"optional\"`\n} // @name GitStatus\n\ntype FileStatus struct {\n\tName     string `json:\"name\" validate:\"required\"`\n\tExtra    string `json:\"extra\" validate:\"required\"`\n\tStaging  Status `json:\"staging\" validate:\"required\"`\n\tWorktree Status `json:\"worktree\" validate:\"required\"`\n} // @name FileStatus\n\n// Status status code of a file in the Worktree\ntype Status string // @name Status\n\nconst (\n\tUnmodified         Status = \"Unmodified\"\n\tUntracked          Status = \"Untracked\"\n\tModified           Status = \"Modified\"\n\tAdded              Status = \"Added\"\n\tDeleted            Status = \"Deleted\"\n\tRenamed            Status = \"Renamed\"\n\tCopied             Status = \"Copied\"\n\tUpdatedButUnmerged Status = \"Updated but unmerged\"\n)\n\nvar MapStatus map[git.StatusCode]Status = map[git.StatusCode]Status{\n\tgit.Unmodified:         Unmodified,\n\tgit.Untracked:          Untracked,\n\tgit.Modified:           Modified,\n\tgit.Added:              Added,\n\tgit.Deleted:            Deleted,\n\tgit.Renamed:            Renamed,\n\tgit.Copied:             Copied,\n\tgit.UpdatedButUnmerged: UpdatedButUnmerged,\n}\n\ntype IGitService interface {\n\tCloneRepository(repo *gitprovider.GitRepository, auth *http.BasicAuth) error\n\tCloneRepositoryCmd(repo *gitprovider.GitRepository, auth *http.BasicAuth) []string\n\tRepositoryExists() (bool, error)\n\tSetGitConfig(userData *gitprovider.GitUser, providerConfig *gitprovider.GitProviderConfig) error\n\tGetGitStatus() (*GitStatus, error)\n}\n\ntype Service struct {\n\tWorkDir           string\n\tGitConfigFileName string\n\tLogWriter         io.Writer\n\tOpenRepository    *git.Repository\n}\n\nfunc (s *Service) RepositoryExists() (bool, error) {\n\t_, err := os.Stat(filepath.Join(s.WorkDir, \".git\"))\n\tif os.IsNotExist(err) {\n\t\treturn false, nil\n\t}\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn true, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/service_test.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/daytonaio/daemon/pkg/gitprovider\"\n\t\"github.com/go-git/go-git/v5/plumbing/transport/http\"\n\t\"github.com/stretchr/testify/suite\"\n)\n\nvar repoHttp = &gitprovider.GitRepository{\n\tId:     \"123\",\n\tUrl:    \"http://localhost:3000/daytonaio/daytona\",\n\tName:   \"daytona\",\n\tBranch: \"main\",\n\tTarget: gitprovider.CloneTargetBranch,\n}\n\nvar repoHttps = &gitprovider.GitRepository{\n\tId:     \"123\",\n\tUrl:    \"https://github.com/daytonaio/daytona\",\n\tName:   \"daytona\",\n\tBranch: \"main\",\n\tTarget: gitprovider.CloneTargetBranch,\n}\n\nvar repoWithoutProtocol = &gitprovider.GitRepository{\n\tId:     \"123\",\n\tUrl:    \"github.com/daytonaio/daytona\",\n\tName:   \"daytona\",\n\tBranch: \"main\",\n\tTarget: gitprovider.CloneTargetBranch,\n}\n\nvar repoWithCloneTargetCommit = &gitprovider.GitRepository{\n\tId:     \"123\",\n\tUrl:    \"https://github.com/daytonaio/daytona\",\n\tName:   \"daytona\",\n\tBranch: \"main\",\n\tSha:    \"1234567890\",\n\tTarget: gitprovider.CloneTargetCommit,\n}\n\nvar creds = &http.BasicAuth{\n\tUsername: \"daytonaio\",\n\tPassword: \"Daytona123\",\n}\n\ntype GitServiceTestSuite struct {\n\tsuite.Suite\n\tgitService git.IGitService\n}\n\nfunc NewGitServiceTestSuite() *GitServiceTestSuite {\n\treturn &GitServiceTestSuite{}\n}\n\nfunc (s *GitServiceTestSuite) SetupTest() {\n\ts.gitService = &git.Service{\n\t\tWorkDir: \"/work-dir\",\n\t}\n}\n\nfunc TestGitService(t *testing.T) {\n\tsuite.Run(t, NewGitServiceTestSuite())\n}\n\nfunc (s *GitServiceTestSuite) TestCloneRepositoryCmd_WithCreds() {\n\tcloneCmd := s.gitService.CloneRepositoryCmd(repoHttps, creds)\n\ts.Require().Equal([]string{\"git\", \"clone\", \"--single-branch\", \"--branch\", \"\\\"main\\\"\", \"https://daytonaio:Daytona123@github.com/daytonaio/daytona\", \"/work-dir\"}, cloneCmd)\n\n\tcloneCmd = s.gitService.CloneRepositoryCmd(repoHttp, creds)\n\ts.Require().Equal([]string{\"git\", \"clone\", \"--single-branch\", \"--branch\", \"\\\"main\\\"\", \"http://daytonaio:Daytona123@localhost:3000/daytonaio/daytona\", \"/work-dir\"}, cloneCmd)\n\n\tcloneCmd = s.gitService.CloneRepositoryCmd(repoWithoutProtocol, creds)\n\ts.Require().Equal([]string{\"git\", \"clone\", \"--single-branch\", \"--branch\", \"\\\"main\\\"\", \"https://daytonaio:Daytona123@github.com/daytonaio/daytona\", \"/work-dir\"}, cloneCmd)\n\n\tcloneCmd = s.gitService.CloneRepositoryCmd(repoWithCloneTargetCommit, creds)\n\ts.Require().Equal([]string{\"git\", \"clone\", \"--single-branch\", \"--branch\", \"\\\"main\\\"\", \"https://daytonaio:Daytona123@github.com/daytonaio/daytona\", \"/work-dir\", \"&&\", \"cd\", \"/work-dir\", \"&&\", \"git\", \"checkout\", \"1234567890\"}, cloneCmd)\n}\n\nfunc (s *GitServiceTestSuite) TestCloneRepositoryCmd_WithoutCreds() {\n\tcloneCmd := s.gitService.CloneRepositoryCmd(repoHttps, nil)\n\ts.Require().Equal([]string{\"git\", \"clone\", \"--single-branch\", \"--branch\", \"\\\"main\\\"\", \"https://github.com/daytonaio/daytona\", \"/work-dir\"}, cloneCmd)\n\n\tcloneCmd = s.gitService.CloneRepositoryCmd(repoHttp, nil)\n\ts.Require().Equal([]string{\"git\", \"clone\", \"--single-branch\", \"--branch\", \"\\\"main\\\"\", \"http://localhost:3000/daytonaio/daytona\", \"/work-dir\"}, cloneCmd)\n\n\tcloneCmd = s.gitService.CloneRepositoryCmd(repoWithoutProtocol, nil)\n\ts.Require().Equal([]string{\"git\", \"clone\", \"--single-branch\", \"--branch\", \"\\\"main\\\"\", \"https://github.com/daytonaio/daytona\", \"/work-dir\"}, cloneCmd)\n\n\tcloneCmd = s.gitService.CloneRepositoryCmd(repoWithCloneTargetCommit, nil)\n\ts.Require().Equal([]string{\"git\", \"clone\", \"--single-branch\", \"--branch\", \"\\\"main\\\"\", \"https://github.com/daytonaio/daytona\", \"/work-dir\", \"&&\", \"cd\", \"/work-dir\", \"&&\", \"git\", \"checkout\", \"1234567890\"}, cloneCmd)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/status.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/go-git/go-git/v5\"\n)\n\nfunc (s *Service) GetGitStatus() (*GitStatus, error) {\n\trepo, err := git.PlainOpen(s.WorkDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tref, err := repo.Head()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tworktree, err := repo.Worktree()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tstatus, err := worktree.Status()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfiles := []*FileStatus{}\n\tfor path, file := range status {\n\t\tfiles = append(files, &FileStatus{\n\t\t\tName:     path,\n\t\t\tExtra:    file.Extra,\n\t\t\tStaging:  MapStatus[file.Staging],\n\t\t\tWorktree: MapStatus[file.Worktree],\n\t\t})\n\t}\n\n\tbranchPublished, err := s.isBranchPublished()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tahead, behind, err := s.getAheadBehindInfo()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &GitStatus{\n\t\tCurrentBranch:   ref.Name().Short(),\n\t\tFiles:           files,\n\t\tBranchPublished: branchPublished,\n\t\tAhead:           ahead,\n\t\tBehind:          behind,\n\t}, nil\n}\n\nfunc (s *Service) isBranchPublished() (bool, error) {\n\tupstream, err := s.getUpstreamBranch()\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn upstream != \"\", nil\n}\n\nfunc (s *Service) getUpstreamBranch() (string, error) {\n\tcmd := exec.Command(\"git\", \"-C\", s.WorkDir, \"rev-parse\", \"--abbrev-ref\", \"--symbolic-full-name\", \"@{upstream}\")\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\treturn \"\", nil\n\t}\n\n\treturn strings.TrimSpace(string(out)), nil\n}\n\nfunc (s *Service) getAheadBehindInfo() (int, int, error) {\n\tupstream, err := s.getUpstreamBranch()\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\tif upstream == \"\" {\n\t\treturn 0, 0, nil\n\t}\n\n\tcmd := exec.Command(\"git\", \"-C\", s.WorkDir, \"rev-list\", \"--left-right\", \"--count\", fmt.Sprintf(\"%s...HEAD\", upstream))\n\tout, err := cmd.CombinedOutput()\n\tif err != nil {\n\t\treturn 0, 0, nil\n\t}\n\n\treturn parseAheadBehind(out)\n}\n\nfunc parseAheadBehind(output []byte) (int, int, error) {\n\tcounts := strings.Split(strings.TrimSpace(string(output)), \"\\t\")\n\tif len(counts) != 2 {\n\t\treturn 0, 0, nil\n\t}\n\n\tahead, err := strconv.Atoi(counts[1])\n\tif err != nil {\n\t\treturn 0, 0, nil\n\t}\n\n\tbehind, err := strconv.Atoi(counts[0])\n\tif err != nil {\n\t\treturn 0, 0, nil\n\t}\n\n\treturn ahead, behind, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/git/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport \"time\"\n\ntype GitCommitInfo struct {\n\tHash      string    `json:\"hash\" validate:\"required\"`\n\tAuthor    string    `json:\"author\" validate:\"required\"`\n\tEmail     string    `json:\"email\" validate:\"required\"`\n\tMessage   string    `json:\"message\" validate:\"required\"`\n\tTimestamp time.Time `json:\"timestamp\" validate:\"required\"`\n} // @name GitCommitInfo\n"
  },
  {
    "path": "apps/daemon/pkg/gitprovider/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage gitprovider\n\ntype SigningMethod string // @name SigningMethod\n\nconst (\n\tSigningMethodSSH SigningMethod = \"ssh\"\n\tSigningMethodGPG SigningMethod = \"gpg\"\n)\n\ntype GitProviderConfig struct {\n\tId            string         `json:\"id\" validate:\"required\"`\n\tProviderId    string         `json:\"providerId\" validate:\"required\"`\n\tUsername      string         `json:\"username\" validate:\"required\"`\n\tBaseApiUrl    *string        `json:\"baseApiUrl,omitempty\" validate:\"optional\"`\n\tToken         string         `json:\"token\" validate:\"required\"`\n\tAlias         string         `json:\"alias\" validate:\"required\"`\n\tSigningKey    *string        `json:\"signingKey,omitempty\" validate:\"optional\"`\n\tSigningMethod *SigningMethod `json:\"signingMethod,omitempty\" validate:\"optional\"`\n} // @name GitProvider\n\ntype GitUser struct {\n\tId       string `json:\"id\" validate:\"required\"`\n\tUsername string `json:\"username\" validate:\"required\"`\n\tName     string `json:\"name\" validate:\"required\"`\n\tEmail    string `json:\"email\" validate:\"required\"`\n} // @name GitUser\n\ntype CloneTarget string // @name CloneTarget\n\nconst (\n\tCloneTargetBranch CloneTarget = \"branch\"\n\tCloneTargetCommit CloneTarget = \"commit\"\n)\n\ntype GitRepository struct {\n\tId       string      `json:\"id\" validate:\"required\"`\n\tUrl      string      `json:\"url\" validate:\"required\"`\n\tName     string      `json:\"name\" validate:\"required\"`\n\tBranch   string      `json:\"branch\" validate:\"required\"`\n\tSha      string      `json:\"sha\" validate:\"required\"`\n\tOwner    string      `json:\"owner\" validate:\"required\"`\n\tPrNumber *uint32     `json:\"prNumber,omitempty\" validate:\"optional\"`\n\tSource   string      `json:\"source\" validate:\"required\"`\n\tPath     *string     `json:\"path,omitempty\" validate:\"optional\"`\n\tTarget   CloneTarget `json:\"cloneTarget,omitempty\" validate:\"optional\"`\n} // @name GitRepository\n\ntype GitNamespace struct {\n\tId   string `json:\"id\" validate:\"required\"`\n\tName string `json:\"name\" validate:\"required\"`\n} // @name GitNamespace\n\ntype GitBranch struct {\n\tName string `json:\"name\" validate:\"required\"`\n\tSha  string `json:\"sha\" validate:\"required\"`\n} // @name GitBranch\n\ntype GitPullRequest struct {\n\tName            string `json:\"name\" validate:\"required\"`\n\tBranch          string `json:\"branch\" validate:\"required\"`\n\tSha             string `json:\"sha\" validate:\"required\"`\n\tSourceRepoId    string `json:\"sourceRepoId\" validate:\"required\"`\n\tSourceRepoUrl   string `json:\"sourceRepoUrl\" validate:\"required\"`\n\tSourceRepoOwner string `json:\"sourceRepoOwner\" validate:\"required\"`\n\tSourceRepoName  string `json:\"sourceRepoName\" validate:\"required\"`\n} // @name GitPullRequest\n\ntype GitEventData struct {\n\tUrl           string   `json:\"url\" validate:\"required\"`\n\tBranch        string   `json:\"branch\" validate:\"required\"`\n\tSha           string   `json:\"sha\" validate:\"required\"`\n\tOwner         string   `json:\"user\" validate:\"required\"`\n\tAffectedFiles []string `json:\"affectedFiles\" validate:\"required\"`\n} //\t@name\tGitEventData\n"
  },
  {
    "path": "apps/daemon/pkg/recording/delete.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"fmt\"\n\t\"os\"\n)\n\n// DeleteRecording deletes a recording by ID\nfunc (s *RecordingService) DeleteRecording(id string) error {\n\t// Check if it's an active recording\n\tif _, exists := s.activeRecordings.Get(id); exists {\n\t\treturn ErrRecordingStillActive\n\t}\n\n\t// Find the recording\n\trecording, err := s.GetRecording(id)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Delete the file\n\tif err := os.Remove(recording.FilePath); err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn ErrRecordingNotFound\n\t\t}\n\t\treturn fmt.Errorf(\"failed to delete recording file: %w\", err)\n\t}\n\n\ts.logger.Debug(\"Deleted recording\", \"id\", id, \"filePath\", recording.FilePath)\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/recording/get.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\n// GetRecording returns a recording by ID (active or from filesystem)\nfunc (s *RecordingService) GetRecording(id string) (*Recording, error) {\n\t// First check active recordings\n\tif active, exists := s.activeRecordings.Get(id); exists {\n\t\trecording := *active.recording\n\t\treturn &recording, nil\n\t}\n\n\t// Search in completed recordings on disk\n\trecordings, err := s.ListRecordings()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, rec := range recordings {\n\t\tif rec.ID == id {\n\t\t\treturn &rec, nil\n\t\t}\n\t}\n\n\treturn nil, ErrRecordingNotFound\n}\n"
  },
  {
    "path": "apps/daemon/pkg/recording/list.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/google/uuid\"\n)\n\n// ListRecordings returns all recordings (active and completed)\nfunc (s *RecordingService) ListRecordings() ([]Recording, error) {\n\trecordings := []Recording{}\n\n\t// Add active recordings\n\tfor item := range s.activeRecordings.IterBuffered() {\n\t\trecordings = append(recordings, *item.Val.recording)\n\t}\n\n\t// Scan recordings directory for completed recordings\n\tif _, err := os.Stat(s.recordingsDir); os.IsNotExist(err) {\n\t\treturn recordings, nil\n\t}\n\n\tentries, err := os.ReadDir(s.recordingsDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read recordings directory: %w\", err)\n\t}\n\n\tfor _, entry := range entries {\n\t\tif entry.IsDir() {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Only include MP4 files\n\t\tif filepath.Ext(entry.Name()) != \".mp4\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Skip files that are currently being recorded\n\t\tisActive := false\n\t\tfor item := range s.activeRecordings.IterBuffered() {\n\t\t\tif item.Val.recording.FileName == entry.Name() {\n\t\t\t\tisActive = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif isActive {\n\t\t\tcontinue\n\t\t}\n\n\t\tfilePath := filepath.Join(s.recordingsDir, entry.Name())\n\t\tfileInfo, err := entry.Info()\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Extract ID from filename (format: {id}_{label}_{timestamp}.mp4 or {id}_session_{timestamp}.mp4)\n\t\t// The ID is the first part before the underscore (UUID format)\n\t\tfileName := entry.Name()\n\t\tvar recordingID string\n\t\tif idx := strings.Index(fileName, \"_\"); idx > 0 {\n\t\t\tpotentialID := fileName[:idx]\n\t\t\t// Validate it's a UUID\n\t\t\tif _, err := uuid.Parse(potentialID); err == nil {\n\t\t\t\trecordingID = potentialID\n\t\t\t}\n\t\t}\n\t\t// Fallback to generating ID from file path for legacy recordings without ID in filename\n\t\tif recordingID == \"\" {\n\t\t\trecordingID = uuid.NewSHA1(uuid.NameSpaceURL, []byte(filePath)).String()\n\t\t}\n\n\t\t// Create recording entry from file info\n\t\t// Use file modification time as a proxy for end time\n\t\tmodTime := fileInfo.ModTime()\n\t\tsize := fileInfo.Size()\n\n\t\trecording := Recording{\n\t\t\tID:        recordingID,\n\t\t\tFileName:  fileName,\n\t\t\tFilePath:  filePath,\n\t\t\tStartTime: modTime, // Approximation - actual start time unknown for old recordings\n\t\t\tEndTime:   &modTime,\n\t\t\tStatus:    \"completed\",\n\t\t\tSizeBytes: &size,\n\t\t}\n\n\t\trecordings = append(recordings, recording)\n\t}\n\n\treturn recordings, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/recording/service.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"log/slog\"\n\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n)\n\n// RecordingService manages screen recording sessions\ntype RecordingService struct {\n\tlogger           *slog.Logger\n\tactiveRecordings cmap.ConcurrentMap[string, *activeRecording]\n\trecordingsDir    string\n}\n\nfunc NewRecordingService(logger *slog.Logger, recordingsDir string) *RecordingService {\n\treturn &RecordingService{\n\t\tlogger:           logger.With(slog.String(\"component\", \"recording_service\")),\n\t\tactiveRecordings: cmap.New[*activeRecording](),\n\t\trecordingsDir:    recordingsDir,\n\t}\n}\n\nfunc (s *RecordingService) GetRecordingsDir() string {\n\treturn s.recordingsDir\n}\n"
  },
  {
    "path": "apps/daemon/pkg/recording/start.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n)\n\n// validateLabel validates a user-provided label to prevent path injection\n// and ensure it's safe for use in a filename. Returns error if invalid.\nfunc validateLabel(label string) error {\n\tconst maxLabelLength = 100\n\n\t// Trim whitespace for validation\n\ttrimmed := strings.TrimSpace(label)\n\n\t// Check if label is empty after trimming\n\tif trimmed == \"\" {\n\t\treturn ErrInvalidLabel\n\t}\n\n\t// Check length\n\tif len(label) > maxLabelLength {\n\t\treturn ErrInvalidLabel\n\t}\n\n\t// Check for path separators (directory traversal)\n\tif strings.Contains(label, \"/\") || strings.Contains(label, \"\\\\\") {\n\t\treturn ErrInvalidLabel\n\t}\n\n\t// Check for leading dots (hidden files)\n\tif strings.HasPrefix(trimmed, \".\") {\n\t\treturn ErrInvalidLabel\n\t}\n\n\t// Only allow safe characters: alphanumeric, spaces, dots, underscores, and hyphens\n\tsafePattern := regexp.MustCompile(`^[A-Za-z0-9.\\s_-]+$`)\n\tif !safePattern.MatchString(label) {\n\t\treturn ErrInvalidLabel\n\t}\n\n\treturn nil\n}\n\n// StartRecording starts a new screen recording session\nfunc (s *RecordingService) StartRecording(label *string) (*Recording, error) {\n\t// Ensure recordings directory exists\n\tif err := os.MkdirAll(s.recordingsDir, 0755); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create recordings directory: %w\", err)\n\t}\n\n\t// Check if ffmpeg is available\n\tffmpegPath, err := exec.LookPath(\"ffmpeg\")\n\tif err != nil {\n\t\treturn nil, ErrFFmpegNotFound\n\t}\n\n\t// Check for DISPLAY environment variable (required for X11)\n\tdisplay := os.Getenv(\"DISPLAY\")\n\tif display == \"\" {\n\t\tdisplay = \":0\" // Default to :0 if not set\n\t}\n\n\t// Generate recording ID and filename\n\t// ID is included in filename so it can be recovered when scanning disk\n\tid := uuid.New().String()\n\tnow := time.Now()\n\ttimestamp := now.Format(\"20060102_150405\")\n\n\t// Validate label if provided (reject invalid labels without modification)\n\tif label != nil && *label != \"\" {\n\t\tif err := validateLabel(*label); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar fileName string\n\tif label != nil && *label != \"\" {\n\t\tfileName = fmt.Sprintf(\"%s_%s_%s.mp4\", id, *label, timestamp)\n\t} else {\n\t\tfileName = fmt.Sprintf(\"%s_session_%s.mp4\", id, timestamp)\n\t}\n\n\tfilePath := filepath.Join(s.recordingsDir, fileName)\n\n\t// Create recording entry\n\trecording := &Recording{\n\t\tID:        id,\n\t\tFileName:  fileName,\n\t\tFilePath:  filePath,\n\t\tStartTime: now,\n\t\tStatus:    \"recording\",\n\t}\n\n\t// Build ffmpeg command for Linux screen capture using x11grab\n\t// -f x11grab: X11 screen capture\n\t// -framerate 30: 30 FPS\n\t// -i :0.0: Capture from display :0, screen 0\n\t// -c:v libx264: H.264 codec\n\t// -preset ultrafast: Fast encoding for real-time capture\n\t// -pix_fmt yuv420p: Standard pixel format for compatibility\n\tcmd := exec.Command(ffmpegPath,\n\t\t\"-f\", \"x11grab\",\n\t\t\"-framerate\", \"30\",\n\t\t\"-i\", display,\n\t\t\"-c:v\", \"libx264\",\n\t\t\"-preset\", \"ultrafast\",\n\t\t\"-pix_fmt\", \"yuv420p\",\n\t\t\"-y\", // Overwrite output file if exists\n\t\tfilePath,\n\t)\n\n\t// Set environment to ensure DISPLAY is available\n\tcmd.Env = append(os.Environ(), fmt.Sprintf(\"DISPLAY=%s\", display))\n\n\t// Get stdin pipe for graceful shutdown\n\tstdinPipe, err := cmd.StdinPipe()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get stdin pipe: %w\", err)\n\t}\n\n\t// Start ffmpeg process\n\tif err := cmd.Start(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to start ffmpeg: %w\", err)\n\t}\n\n\ts.logger.Debug(\"Started recording\", \"id\", id, \"path\", filePath, \"display\", display)\n\n\t// Create a done channel to receive the Wait() result exactly once\n\tdone := make(chan error, 1)\n\n\t// Store active recording\n\ts.activeRecordings.Set(id, &activeRecording{\n\t\trecording: recording,\n\t\tcmd:       cmd,\n\t\tstdinPipe: stdinPipe,\n\t\tdone:      done,\n\t})\n\n\t// Start a goroutine to wait for the process and handle unexpected exits\n\tgo func() {\n\t\terr := cmd.Wait()\n\t\tdone <- err // Signal the done channel with the result\n\n\t\t// Atomically remove from active recordings if still there\n\t\tif active, exists := s.activeRecordings.Pop(id); exists {\n\t\t\tif err != nil {\n\t\t\t\ts.logger.Warn(\"Recording ffmpeg process exited unexpectedly\", \"id\", id, \"error\", err)\n\t\t\t\tactive.recording.Status = \"failed\"\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn recording, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/recording/stop.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"os\"\n\t\"time\"\n)\n\n// StopRecording stops an active recording session\nfunc (s *RecordingService) StopRecording(id string) (*Recording, error) {\n\tactive, exists := s.activeRecordings.Pop(id)\n\tif !exists {\n\t\treturn nil, ErrRecordingNotFound\n\t}\n\n\t// Send 'q' to ffmpeg stdin for graceful shutdown\n\t// This allows ffmpeg to properly finalize the video file\n\tif active.stdinPipe != nil {\n\t\t_, err := active.stdinPipe.Write([]byte(\"q\"))\n\t\tif err != nil {\n\t\t\ts.logger.Warn(\"Failed to send quit signal to ffmpeg\", \"error\", err)\n\t\t}\n\t\tactive.stdinPipe.Close()\n\t}\n\n\t// Wait for ffmpeg to finish by waiting on the done channel\n\tselect {\n\tcase <-active.done:\n\t\t// Process exited normally\n\tcase <-time.After(10 * time.Second):\n\t\t// Force kill if it doesn't exit gracefully\n\t\ts.logger.Warn(\"Recording did not stop gracefully, force killing\", \"id\", id)\n\t\tif active.cmd.Process != nil {\n\t\t\terr := active.cmd.Process.Kill()\n\t\t\tif err != nil {\n\t\t\t\ts.logger.Error(\"Failed to force kill recording\", \"id\", id, \"error\", err)\n\t\t\t}\n\t\t}\n\t\t// Still wait for the done channel to avoid goroutine leak\n\t\t<-active.done\n\t}\n\n\t// Update recording metadata\n\tnow := time.Now()\n\tactive.recording.EndTime = &now\n\tactive.recording.Status = \"completed\"\n\n\tduration := now.Sub(active.recording.StartTime).Seconds()\n\tactive.recording.DurationSeconds = &duration\n\n\t// Get file size\n\tif fileInfo, err := os.Stat(active.recording.FilePath); err == nil {\n\t\tsize := fileInfo.Size()\n\t\tactive.recording.SizeBytes = &size\n\t}\n\n\ts.logger.Debug(\"Stopped recording\", \"id\", id, \"durationSeconds\", duration)\n\n\treturn active.recording, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/recording/types.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"os/exec\"\n\t\"time\"\n)\n\nvar (\n\tErrRecordingNotFound    = errors.New(\"recording not found\")\n\tErrRecordingNotActive   = errors.New(\"recording is not active\")\n\tErrRecordingStillActive = errors.New(\"cannot delete an active recording\")\n\tErrFFmpegNotFound       = errors.New(\"ffmpeg not found in PATH\")\n\tErrInvalidLabel         = errors.New(\"invalid label: must be 1-100 characters, cannot start with dot, cannot contain path separators (/ or \\\\), and can only contain letters, numbers, spaces, dots, underscores, and hyphens\")\n)\n\ntype Recording struct {\n\tID              string\n\tFileName        string\n\tFilePath        string\n\tStartTime       time.Time\n\tEndTime         *time.Time\n\tStatus          string\n\tDurationSeconds *float64\n\tSizeBytes       *int64\n}\n\n// activeRecording holds the state of a currently running recording\ntype activeRecording struct {\n\trecording *Recording\n\tcmd       *exec.Cmd\n\tstdinPipe io.WriteCloser\n\tdone      chan error\n}\n"
  },
  {
    "path": "apps/daemon/pkg/recordingdashboard/assets.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recordingdashboard\n\nimport \"embed\"\n\n//go:embed static\nvar static embed.FS\n"
  },
  {
    "path": "apps/daemon/pkg/recordingdashboard/server.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recordingdashboard\n\nimport (\n\t\"fmt\"\n\t\"io/fs\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/daemon/pkg/recording\"\n\trecordingcontroller \"github.com/daytonaio/daemon/pkg/toolbox/computeruse/recording\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/config\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// DashboardServer serves the recording dashboard\ntype DashboardServer struct {\n\tlogger           *slog.Logger\n\trecordingService *recording.RecordingService\n}\n\n// NewDashboardServer creates a new dashboard server\nfunc NewDashboardServer(logger *slog.Logger, recordingService *recording.RecordingService) *DashboardServer {\n\treturn &DashboardServer{\n\t\tlogger:           logger.With(slog.String(\"component\", \"recordings_dashboard\")),\n\t\trecordingService: recordingService,\n\t}\n}\n\n// Start starts the dashboard server on the configured port\nfunc (s *DashboardServer) Start() error {\n\tgin.SetMode(gin.ReleaseMode)\n\tr := gin.New()\n\tr.Use(gin.Recovery())\n\n\t// Prepare the embedded frontend files\n\t// Serve the files from the embedded filesystem\n\tstaticFS, err := fs.Sub(static, \"static\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create sub filesystem: %w\", err)\n\t}\n\n\t// Serve dashboard HTML from embedded files\n\tr.GET(\"/\", gin.WrapH(http.FileServer(http.FS(staticFS))))\n\n\t// Serve video files\n\tr.GET(\"/videos/:filename\", s.serveVideo)\n\n\t// API endpoints\n\tr.GET(\"/api/recordings\", s.listRecordings)\n\tr.DELETE(\"/api/recordings\", s.deleteRecordings)\n\n\taddr := fmt.Sprintf(\":%d\", config.RECORDING_DASHBOARD_PORT)\n\ts.logger.Info(\"Starting recording dashboard\", \"port\", config.RECORDING_DASHBOARD_PORT)\n\n\terr = r.Run(addr)\n\treturn err\n}\n\nfunc (s *DashboardServer) serveVideo(ctx *gin.Context) {\n\tfilename := ctx.Param(\"filename\")\n\trecordingsDir := s.recordingService.GetRecordingsDir()\n\tfilePath := filepath.Join(recordingsDir, filename)\n\n\t// Security check - prevent path traversal\n\t// filepath.Rel returns a path with \"..\" if target is outside base directory\n\trel, err := filepath.Rel(recordingsDir, filePath)\n\tif err != nil || strings.Contains(rel, \"..\") {\n\t\tctx.JSON(http.StatusForbidden, gin.H{\"error\": \"access denied\"})\n\t\treturn\n\t}\n\n\tif _, err := os.Stat(filePath); os.IsNotExist(err) {\n\t\tctx.JSON(http.StatusNotFound, gin.H{\"error\": \"file not found\"})\n\t\treturn\n\t}\n\n\tctx.File(filePath)\n}\n\nfunc (s *DashboardServer) listRecordings(ctx *gin.Context) {\n\trecordings, err := s.recordingService.ListRecordings()\n\tif err != nil {\n\t\tctx.JSON(http.StatusInternalServerError, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\trecordingDTOs := make([]recordingcontroller.RecordingDTO, 0, len(recordings))\n\tfor _, rec := range recordings {\n\t\trecordingDTOs = append(recordingDTOs, *recordingcontroller.RecordingToDTO(&rec))\n\t}\n\n\tctx.JSON(http.StatusOK, gin.H{\"recordings\": recordingDTOs})\n}\n\ntype deleteRequest struct {\n\tIDs []string `json:\"ids\"`\n}\n\nfunc (s *DashboardServer) deleteRecordings(ctx *gin.Context) {\n\tvar req deleteRequest\n\tif err := ctx.ShouldBindJSON(&req); err != nil {\n\t\tctx.JSON(http.StatusBadRequest, gin.H{\"error\": \"invalid request\"})\n\t\treturn\n\t}\n\n\tdeleted := []string{}\n\tfailed := []string{}\n\n\t// Direct calls to data provider\n\tfor _, id := range req.IDs {\n\t\tif err := s.recordingService.DeleteRecording(id); err != nil {\n\t\t\tfailed = append(failed, id)\n\t\t\ts.logger.Warn(\"Failed to delete recording\", \"id\", id, \"error\", err)\n\t\t} else {\n\t\t\tdeleted = append(deleted, id)\n\t\t}\n\t}\n\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"deleted\": deleted,\n\t\t\"failed\":  failed,\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/recordingdashboard/static/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Screen Recordings</title>\n    <style>\n      * {\n        box-sizing: border-box;\n        margin: 0;\n        padding: 0;\n      }\n      body {\n        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n        background: #0a0a0a;\n        color: #fafafa;\n        padding: 24px;\n        min-height: 100vh;\n        -webkit-font-smoothing: antialiased;\n      }\n      .container {\n        max-width: 1200px;\n        margin: 0 auto;\n      }\n      .header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 24px;\n        padding-bottom: 16px;\n        border-bottom: 1px solid #262626;\n      }\n      h1 {\n        font-size: 20px;\n        font-weight: 600;\n        color: #fafafa;\n      }\n      .header-left {\n        display: flex;\n        align-items: center;\n        gap: 12px;\n      }\n      .refresh-info {\n        font-size: 12px;\n        color: #a3a3a3;\n      }\n      .btn {\n        padding: 8px 16px;\n        border: none;\n        border-radius: 6px;\n        cursor: pointer;\n        font-size: 13px;\n        font-weight: 500;\n        transition: all 0.15s ease;\n      }\n      .btn:hover {\n        opacity: 0.9;\n      }\n      .btn-primary {\n        background: #fafafa;\n        color: #0a0a0a;\n      }\n      .btn-secondary {\n        background: #262626;\n        color: #fafafa;\n        border: 1px solid #404040;\n      }\n      .btn-secondary:hover {\n        background: #333;\n      }\n      .btn-danger {\n        background: #dc2626;\n        color: #fafafa;\n      }\n      .btn-ghost {\n        background: transparent;\n        color: #a3a3a3;\n        padding: 6px 10px;\n      }\n      .btn-ghost:hover {\n        background: #262626;\n        color: #fafafa;\n      }\n      .btn:disabled {\n        opacity: 0.4;\n        cursor: not-allowed;\n      }\n      .btn-icon {\n        padding: 6px 8px;\n        font-size: 14px;\n      }\n      table {\n        width: 100%;\n        border-collapse: collapse;\n        background: #0a0a0a;\n        border: 1px solid #262626;\n        border-radius: 8px;\n        overflow: hidden;\n      }\n      th,\n      td {\n        padding: 12px 16px;\n        text-align: left;\n        border-bottom: 1px solid #262626;\n      }\n      th {\n        background: #141414;\n        color: #a3a3a3;\n        font-weight: 500;\n        font-size: 12px;\n        text-transform: uppercase;\n        letter-spacing: 0.05em;\n      }\n      tr:hover td {\n        background: #141414;\n      }\n      tr:last-child td {\n        border-bottom: none;\n      }\n      .actions {\n        display: flex;\n        gap: 4px;\n      }\n      .empty {\n        text-align: center;\n        padding: 48px 24px;\n        color: #a3a3a3;\n      }\n      .empty-icon {\n        font-size: 32px;\n        margin-bottom: 12px;\n        opacity: 0.5;\n      }\n      .modal {\n        display: none;\n        position: fixed;\n        top: 0;\n        left: 0;\n        width: 100%;\n        height: 100%;\n        background: rgba(0, 0, 0, 0.85);\n        justify-content: center;\n        align-items: center;\n        z-index: 1000;\n      }\n      .modal.active {\n        display: flex;\n      }\n      .modal-content {\n        background: #141414;\n        border: 1px solid #262626;\n        padding: 20px;\n        border-radius: 12px;\n        max-width: 90%;\n        max-height: 90%;\n      }\n      .modal-header {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        margin-bottom: 16px;\n        padding-bottom: 12px;\n        border-bottom: 1px solid #262626;\n      }\n      .modal-header h2 {\n        font-size: 16px;\n        font-weight: 500;\n      }\n      .close-btn {\n        background: #262626;\n        border: none;\n        color: #a3a3a3;\n        width: 28px;\n        height: 28px;\n        border-radius: 6px;\n        cursor: pointer;\n        font-size: 18px;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n      }\n      .close-btn:hover {\n        background: #333;\n        color: #fafafa;\n      }\n      video {\n        max-width: 100%;\n        max-height: 70vh;\n        border-radius: 8px;\n        background: #000;\n      }\n      .badge {\n        display: inline-block;\n        padding: 2px 8px;\n        border-radius: 4px;\n        font-size: 11px;\n        font-weight: 500;\n        text-transform: uppercase;\n      }\n      .badge-completed {\n        background: #166534;\n        color: #86efac;\n      }\n      .badge-recording {\n        background: #854d0e;\n        color: #fde047;\n      }\n      .badge-failed {\n        background: #991b1b;\n        color: #fca5a5;\n      }\n      .filename {\n        font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n        font-size: 13px;\n        color: #e5e5e5;\n      }\n      .meta {\n        color: #a3a3a3;\n        font-size: 13px;\n      }\n      input[type='checkbox'] {\n        width: 16px;\n        height: 16px;\n        accent-color: #fafafa;\n        cursor: pointer;\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"container\">\n      <div class=\"header\">\n        <div class=\"header-left\">\n          <h1>Screen Recordings</h1>\n          <span class=\"refresh-info\">Auto-refresh: 5s</span>\n        </div>\n        <button class=\"btn btn-danger\" id=\"deleteSelected\" disabled onclick=\"deleteSelected()\">Delete Selected</button>\n      </div>\n\n      <table>\n        <thead>\n          <tr>\n            <th style=\"width: 40px\"><input type=\"checkbox\" id=\"selectAll\" onchange=\"toggleSelectAll()\" /></th>\n            <th>Filename</th>\n            <th>Duration</th>\n            <th>Size</th>\n            <th>Status</th>\n            <th>Date</th>\n            <th style=\"width: 120px\">Actions</th>\n          </tr>\n        </thead>\n        <tbody id=\"recordingsBody\">\n          <tr>\n            <td colspan=\"7\" class=\"empty\">\n              <div class=\"empty-icon\">📹</div>\n              Loading...\n            </td>\n          </tr>\n        </tbody>\n      </table>\n    </div>\n\n    <div class=\"modal\" id=\"videoModal\">\n      <div class=\"modal-content\">\n        <div class=\"modal-header\">\n          <h2 id=\"videoTitle\">Video Playback</h2>\n          <button class=\"close-btn\" onclick=\"closeModal()\">&times;</button>\n        </div>\n        <video id=\"videoPlayer\" controls></video>\n      </div>\n    </div>\n\n    <script>\n      let recordings = []\n      let selectedIds = new Set()\n\n      async function loadRecordings() {\n        try {\n          const resp = await fetch('/api/recordings')\n          const data = await resp.json()\n          recordings = data.recordings || []\n          renderTable()\n        } catch (err) {\n          console.error('Failed to load recordings:', err)\n        }\n      }\n\n      function renderTable() {\n        const tbody = document.getElementById('recordingsBody')\n        if (recordings.length === 0) {\n          tbody.innerHTML =\n            '<tr><td colspan=\"7\" class=\"empty\"><div class=\"empty-icon\">📹</div>No recordings yet</td></tr>'\n          return\n        }\n\n        tbody.innerHTML = recordings\n          .map((rec) => {\n            const duration = rec.durationSeconds ? rec.durationSeconds.toFixed(1) + 's' : '-'\n            const size = rec.sizeBytes ? formatBytes(rec.sizeBytes) : '-'\n            const date = new Date(rec.startTime).toLocaleString()\n            const checked = selectedIds.has(rec.id) ? 'checked' : ''\n            const badgeClass = 'badge-' + rec.status\n\n            return `<tr>\n                    <td><input type=\"checkbox\" ${checked} onchange=\"toggleSelect('${rec.id}')\"></td>\n                    <td class=\"filename\">${rec.fileName}</td>\n                    <td class=\"meta\">${duration}</td>\n                    <td class=\"meta\">${size}</td>\n                    <td><span class=\"badge ${badgeClass}\">${rec.status}</span></td>\n                    <td class=\"meta\">${date}</td>\n                    <td class=\"actions\">\n                        <button class=\"btn btn-ghost btn-icon\" onclick=\"playVideo('${rec.fileName}')\" ${rec.status !== 'completed' ? 'disabled' : ''} title=\"Play\">▶</button>\n                        <button class=\"btn btn-ghost btn-icon\" onclick=\"downloadVideo('${rec.fileName}')\" ${rec.status !== 'completed' ? 'disabled' : ''} title=\"Download\">⬇</button>\n                        <button class=\"btn btn-ghost btn-icon\" onclick=\"deleteRecording('${rec.id}')\" title=\"Delete\">🗑</button>\n                    </td>\n                </tr>`\n          })\n          .join('')\n\n        updateDeleteButton()\n      }\n\n      function formatBytes(bytes) {\n        if (bytes < 1024) return bytes + ' B'\n        if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'\n        return (bytes / (1024 * 1024)).toFixed(1) + ' MB'\n      }\n\n      function toggleSelect(id) {\n        if (selectedIds.has(id)) {\n          selectedIds.delete(id)\n        } else {\n          selectedIds.add(id)\n        }\n        updateDeleteButton()\n      }\n\n      function toggleSelectAll() {\n        const selectAll = document.getElementById('selectAll').checked\n        selectedIds.clear()\n        if (selectAll) {\n          recordings.forEach((r) => selectedIds.add(r.id))\n        }\n        renderTable()\n      }\n\n      function updateDeleteButton() {\n        document.getElementById('deleteSelected').disabled = selectedIds.size === 0\n      }\n\n      function playVideo(filename) {\n        const video = document.getElementById('videoPlayer')\n        video.src = '/videos/' + filename\n        document.getElementById('videoTitle').textContent = filename\n        document.getElementById('videoModal').classList.add('active')\n        video.play()\n      }\n\n      function closeModal() {\n        const video = document.getElementById('videoPlayer')\n        video.pause()\n        video.src = ''\n        document.getElementById('videoModal').classList.remove('active')\n      }\n\n      function downloadVideo(filename) {\n        const a = document.createElement('a')\n        a.href = '/videos/' + filename\n        a.download = filename\n        a.click()\n      }\n\n      async function deleteRecording(id) {\n        if (!confirm('Delete this recording?')) return\n\n        try {\n          const resp = await fetch('/api/recordings', {\n            method: 'DELETE',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify({ ids: [id] }),\n          })\n          if (resp.ok) {\n            selectedIds.delete(id)\n            loadRecordings()\n          }\n        } catch (err) {\n          alert('Failed to delete recording')\n        }\n      }\n\n      async function deleteSelected() {\n        if (!confirm('Delete ' + selectedIds.size + ' selected recording(s)?')) return\n\n        try {\n          const resp = await fetch('/api/recordings', {\n            method: 'DELETE',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify({ ids: Array.from(selectedIds) }),\n          })\n          if (resp.ok) {\n            selectedIds.clear()\n            loadRecordings()\n          }\n        } catch (err) {\n          alert('Failed to delete recordings')\n        }\n      }\n\n      // Initial load and auto-refresh\n      loadRecordings()\n      setInterval(loadRecordings, 5000)\n\n      // Close modal on escape\n      document.addEventListener('keydown', (e) => {\n        if (e.key === 'Escape') closeModal()\n      })\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "apps/daemon/pkg/session/command.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\nfunc (s *SessionService) getSessionCommands(sessionId string) ([]*Command, error) {\n\tsession, ok := s.sessions.Get(sessionId)\n\tif !ok {\n\t\treturn nil, common_errors.NewNotFoundError(errors.New(\"session not found\"))\n\t}\n\n\tcommands := []*Command{}\n\tfor _, command := range session.commands.Items() {\n\t\tcmd, err := s.GetSessionCommand(sessionId, command.Id)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcommands = append(commands, cmd)\n\t}\n\n\treturn commands, nil\n}\n\nfunc (s *SessionService) GetSessionCommand(sessionId, cmdId string) (*Command, error) {\n\tsession, ok := s.sessions.Get(sessionId)\n\tif !ok {\n\t\treturn nil, common_errors.NewNotFoundError(errors.New(\"session not found\"))\n\t}\n\n\tcommand, ok := session.commands.Get(cmdId)\n\tif !ok {\n\t\treturn nil, common_errors.NewNotFoundError(errors.New(\"command not found\"))\n\t}\n\n\tif command.ExitCode != nil {\n\t\treturn command, nil\n\t}\n\n\t_, exitCodeFilePath := command.LogFilePath(session.Dir(s.configDir))\n\texitCode, err := os.ReadFile(exitCodeFilePath)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn command, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to read exit code file: %w\", err)\n\t}\n\n\texitCodeInt, err := strconv.Atoi(strings.TrimRight(string(exitCode), \"\\n\"))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to convert exit code to int: %w\", err)\n\t}\n\n\tcommand.ExitCode = &exitCodeInt\n\n\treturn command, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/common.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"net/http\"\n)\n\nfunc IsCombinedOutput(sdkVersion string, versionComparison *int, requestHeader http.Header) bool {\n\treturn (versionComparison != nil && *versionComparison < 0 && sdkVersion != \"0.0.0-dev\") || (sdkVersion == \"\" && requestHeader.Get(\"X-Daytona-Split-Output\") != \"true\")\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/create.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/daytonaio/daemon/pkg/common\"\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\nfunc (s *SessionService) Create(sessionId string, isLegacy bool) error {\n\tctx, cancel := context.WithCancel(context.Background())\n\n\tcmd := exec.CommandContext(ctx, common.GetShell())\n\tcmd.Env = os.Environ()\n\n\tif isLegacy {\n\t\thomeDir, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t\treturn fmt.Errorf(\"failed to obtain user home directory for legacy SDK compatibility: %w\", err)\n\t\t}\n\n\t\tcmd.Dir = homeDir\n\t}\n\n\tif _, ok := s.sessions.Get(sessionId); ok {\n\t\tcancel()\n\t\treturn common_errors.NewConflictError(errors.New(\"session already exists\"))\n\t}\n\n\tstdinWriter, err := cmd.StdinPipe()\n\tif err != nil {\n\t\tcancel()\n\t\treturn err\n\t}\n\n\terr = cmd.Start()\n\tif err != nil {\n\t\tcancel()\n\t\treturn err\n\t}\n\n\tsession := &session{\n\t\tid:          sessionId,\n\t\tcmd:         cmd,\n\t\tstdinWriter: stdinWriter,\n\t\tcommands:    cmap.New[*Command](),\n\t\tctx:         ctx,\n\t\tcancel:      cancel,\n\t}\n\ts.sessions.Set(sessionId, session)\n\n\terr = os.MkdirAll(session.Dir(s.configDir), 0755)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/delete.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/shirou/gopsutil/v4/process\"\n)\n\nfunc (s *SessionService) Delete(ctx context.Context, sessionId string) error {\n\tsession, ok := s.sessions.Get(sessionId)\n\tif !ok {\n\t\treturn common_errors.NewNotFoundError(errors.New(\"session not found\"))\n\t}\n\n\t// Terminate process group first with signals (SIGTERM -> SIGKILL)\n\terr := s.terminateSession(ctx, session)\n\tif err != nil {\n\t\ts.logger.ErrorContext(ctx, \"Failed to terminate session\", \"sessionId\", session.id, \"error\", err)\n\t\t// Continue with cleanup even if termination fails\n\t}\n\n\t// Cancel context after termination\n\tsession.cancel()\n\n\t// Clean up session directory\n\terr = os.RemoveAll(session.Dir(s.configDir))\n\tif err != nil {\n\t\treturn common_errors.NewBadRequestError(err)\n\t}\n\n\ts.sessions.Remove(session.id)\n\treturn nil\n}\n\nfunc (s *SessionService) terminateSession(ctx context.Context, session *session) error {\n\tif session.cmd == nil || session.cmd.Process == nil {\n\t\treturn nil\n\t}\n\n\tpid := session.cmd.Process.Pid\n\n\t_ = s.signalProcessTree(pid, syscall.SIGTERM)\n\n\terr := session.cmd.Process.Signal(syscall.SIGTERM)\n\tif err != nil {\n\t\t// If SIGTERM fails, try SIGKILL immediately\n\t\ts.logger.WarnContext(ctx, \"SIGTERM failed for session, trying SIGKILL\", \"sessionId\", session.id, \"error\", err)\n\t\t_ = s.signalProcessTree(pid, syscall.SIGKILL)\n\t\treturn session.cmd.Process.Kill()\n\t}\n\n\t// Wait for graceful termination\n\tif s.waitForTermination(ctx, pid, s.terminationGracePeriod, s.terminationCheckInterval) {\n\t\ts.logger.DebugContext(ctx, \"Session terminated gracefully\", \"sessionId\", session.id)\n\t\treturn nil\n\t}\n\n\ts.logger.DebugContext(ctx, \"Session timeout, sending SIGKILL to process tree\", \"sessionId\", session.id)\n\t_ = s.signalProcessTree(pid, syscall.SIGKILL)\n\treturn session.cmd.Process.Kill()\n}\n\nfunc (s *SessionService) signalProcessTree(pid int, sig syscall.Signal) error {\n\tparent, err := process.NewProcess(int32(pid))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdescendants, err := parent.Children()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, child := range descendants {\n\t\tchildPid := int(child.Pid)\n\t\t_ = s.signalProcessTree(childPid, sig)\n\t}\n\n\tfor _, child := range descendants {\n\t\t// Convert to OS process to send custom signal\n\t\tif childProc, err := os.FindProcess(int(child.Pid)); err == nil {\n\t\t\t_ = childProc.Signal(sig)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (s *SessionService) waitForTermination(ctx context.Context, pid int, timeout, interval time.Duration) bool {\n\ttimeoutCtx, cancel := context.WithTimeout(ctx, timeout)\n\tdefer cancel()\n\n\tticker := time.NewTicker(interval)\n\tdefer ticker.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-timeoutCtx.Done():\n\t\t\treturn false\n\t\tcase <-ticker.C:\n\t\t\tparent, err := process.NewProcess(int32(pid))\n\t\t\tif err != nil {\n\t\t\t\t// Process doesn't exist anymore\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tchildren, err := parent.Children()\n\t\t\tif err != nil {\n\t\t\t\t// Unable to enumerate children - likely process is dying/dead\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif len(children) == 0 {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/execute.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daemon/internal/util\"\n\t\"github.com/google/uuid\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/log\"\n)\n\nfunc (s *SessionService) Execute(sessionId, cmdId, cmd string, async, isCombinedOutput, suppressInputEcho bool) (*SessionExecute, error) {\n\tsession, ok := s.sessions.Get(sessionId)\n\tif !ok {\n\t\treturn nil, common_errors.NewNotFoundError(errors.New(\"session not found\"))\n\t}\n\n\tif cmdId == util.EmptyCommandID {\n\t\tcmdId = uuid.NewString()\n\t}\n\n\tif _, ok := session.commands.Get(cmdId); ok {\n\t\treturn nil, common_errors.NewConflictError(errors.New(\"command with the given ID already exists\"))\n\t}\n\n\tcommand := &Command{\n\t\tId:                cmdId,\n\t\tCommand:           cmd,\n\t\tSuppressInputEcho: suppressInputEcho,\n\t}\n\tsession.commands.Set(cmdId, command)\n\n\tlogFilePath, exitCodeFilePath := command.LogFilePath(session.Dir(s.configDir))\n\tlogDir := filepath.Dir(logFilePath)\n\n\tif err := os.MkdirAll(logDir, 0755); err != nil {\n\t\treturn nil, common_errors.NewBadRequestError(fmt.Errorf(\"failed to create log directory: %w\", err))\n\t}\n\n\tlogFile, err := os.Create(logFilePath)\n\tif err != nil {\n\t\treturn nil, common_errors.NewBadRequestError(fmt.Errorf(\"failed to create log file: %w\", err))\n\t}\n\n\tdefer logFile.Close()\n\n\tcmdToExec := fmt.Sprintf(cmdWrapperFormat+\"\\n\",\n\t\tlogFilePath, // %q  -> log\n\t\tlogDir,      // %q  -> dir\n\t\tcommand.InputFilePath(session.Dir(s.configDir)), // %q  -> input\n\t\ttoOctalEscapes(log.STDOUT_PREFIX),               // %s  -> stdout prefix\n\t\ttoOctalEscapes(log.STDERR_PREFIX),               // %s  -> stderr prefix\n\t\tcmd,                                             // %s  -> verbatim script body\n\t\texitCodeFilePath,                                // %q\n\t)\n\n\t_, err = session.stdinWriter.Write([]byte(cmdToExec))\n\tif err != nil {\n\t\treturn nil, common_errors.NewBadRequestError(fmt.Errorf(\"failed to write command: %w\", err))\n\t}\n\n\tif async {\n\t\treturn &SessionExecute{\n\t\t\tCommandId: cmdId,\n\t\t}, nil\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-session.ctx.Done():\n\t\t\tcommand, ok := session.commands.Get(cmdId)\n\t\t\tif !ok {\n\t\t\t\treturn nil, common_errors.NewBadRequestError(errors.New(\"command not found\"))\n\t\t\t}\n\n\t\t\tcommand.ExitCode = util.Pointer(1)\n\n\t\t\treturn nil, common_errors.NewBadRequestError(errors.New(\"session cancelled\"))\n\t\tdefault:\n\t\t\texitCode, err := os.ReadFile(exitCodeFilePath)\n\t\t\tif err != nil {\n\t\t\t\tif os.IsNotExist(err) {\n\t\t\t\t\ttime.Sleep(50 * time.Millisecond)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn nil, common_errors.NewBadRequestError(fmt.Errorf(\"failed to read exit code file: %w\", err))\n\t\t\t}\n\n\t\t\texitCodeInt, err := strconv.Atoi(strings.TrimRight(string(exitCode), \"\\n\"))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, common_errors.NewBadRequestError(fmt.Errorf(\"failed to convert exit code to int: %w\", err))\n\t\t\t}\n\n\t\t\tcommand, ok := session.commands.Get(cmdId)\n\t\t\tif !ok {\n\t\t\t\treturn nil, common_errors.NewBadRequestError(errors.New(\"command not found\"))\n\t\t\t}\n\t\t\tcommand.ExitCode = &exitCodeInt\n\n\t\t\tlogBytes, err := os.ReadFile(logFilePath)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, common_errors.NewBadRequestError(fmt.Errorf(\"failed to read log file: %w\", err))\n\t\t\t}\n\n\t\t\tlogContent := string(logBytes)\n\n\t\t\tif isCombinedOutput {\n\t\t\t\t// remove prefixes from log bytes\n\t\t\t\tlogBytes = bytes.ReplaceAll(bytes.ReplaceAll(logBytes, log.STDOUT_PREFIX, []byte{}), log.STDERR_PREFIX, []byte{})\n\t\t\t\tlogContent = string(logBytes)\n\t\t\t}\n\n\t\t\treturn &SessionExecute{\n\t\t\t\tCommandId: cmdId,\n\t\t\t\tOutput:    &logContent,\n\t\t\t\tExitCode:  &exitCodeInt,\n\t\t\t}, nil\n\t\t}\n\t}\n}\n\nfunc toOctalEscapes(b []byte) string {\n\tout := \"\"\n\tfor _, c := range b {\n\t\tout += fmt.Sprintf(\"\\\\%03o\", c) // e.g. 0x01 → \\001\n\t}\n\treturn out\n}\n\nvar cmdWrapperFormat string = `\n{\n\tlog=%q\n\tdir=%q\n\n\t# per-command FIFOs\n\tsp=\"$dir/stdout.pipe\"\n\tep=\"$dir/stderr.pipe\"\n\tip=%q\n\t\n\trm -f \"$sp\" \"$ep\" \"$ip\" && mkfifo \"$sp\" \"$ep\" \"$ip\" || exit 1\n\n\tcleanup() { rm -f \"$sp\" \"$ep\" \"$ip\"; }\n\ttrap 'cleanup' EXIT HUP INT TERM\n\n  # prefix each stream and append to shared log\n\t( while IFS= read -r line || [ -n \"$line\" ]; do printf '%s%%s\\n' \"$line\"; done < \"$sp\" ) >> \"$log\" & r1=$!\n\t( while IFS= read -r line || [ -n \"$line\" ]; do printf '%s%%s\\n' \"$line\"; done < \"$ep\" ) >> \"$log\" & r2=$!\n\n\t# Keep input FIFO open to prevent blocking when command opens stdin\n\tsleep infinity > \"$ip\" &\n\n\t# Run your command\n\t{ %s; } < \"$ip\" > \"$sp\" 2> \"$ep\"\n\techo \"$?\" >> %s\n\n\t# drain labelers (cleanup via trap)\n\twait \"$r1\" \"$r2\"\n\n\t# Ensure unlink even if the waits failed\n\tcleanup\n}\n`\n"
  },
  {
    "path": "apps/daemon/pkg/session/get.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"errors\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\nfunc (s *SessionService) Get(sessionId string) (*Session, error) {\n\t_, ok := s.sessions.Get(sessionId)\n\tif !ok {\n\t\treturn nil, common_errors.NewNotFoundError(errors.New(\"session not found\"))\n\t}\n\n\tcommands, err := s.getSessionCommands(sessionId)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &Session{\n\t\tSessionId: sessionId,\n\t\tCommands:  commands,\n\t}, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/input.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/log\"\n)\n\n// SendInput sends data to the session's stdin for a specific running command\n// This enables interactive command input for sessions\nfunc (s *SessionService) SendInput(sessionId, commandId string, data string) error {\n\tsession, ok := s.sessions.Get(sessionId)\n\tif !ok {\n\t\treturn common_errors.NewNotFoundError(errors.New(\"session not found\"))\n\t}\n\n\t// Check if the session process is still active\n\tif session.cmd.ProcessState != nil && session.cmd.ProcessState.Exited() {\n\t\treturn common_errors.NewGoneError(errors.New(\"session process has exited\"))\n\t}\n\n\t// Verify the command exists\n\tcommand, ok := session.commands.Get(commandId)\n\tif !ok {\n\t\treturn common_errors.NewNotFoundError(errors.New(\"command not found\"))\n\t}\n\n\t// Check if the command is still running (exit code not set means still running)\n\tif command.ExitCode != nil {\n\t\treturn common_errors.NewGoneError(fmt.Errorf(\"command has already completed with exit code %d\", *command.ExitCode))\n\t}\n\n\tinputFilePath := command.InputFilePath(session.Dir(s.configDir))\n\tf, err := os.OpenFile(inputFilePath, os.O_WRONLY, 0600)\n\tif err != nil {\n\t\treturn common_errors.NewInternalServerError(fmt.Errorf(\"failed to open input pipe: %w\", err))\n\t}\n\tdefer f.Close()\n\n\t// Ensure newline for commands like `read`\n\tif !strings.HasSuffix(data, \"\\n\") {\n\t\tdata += \"\\n\"\n\t}\n\n\t// Write to input pipe\n\tif _, err := f.Write([]byte(data)); err != nil {\n\t\treturn common_errors.NewInternalServerError(fmt.Errorf(\"failed to write to input pipe: %w\", err))\n\t}\n\n\tif !command.SuppressInputEcho {\n\t\t// Also echo input to log file for visibility (appears as stdout)\n\t\tlogFilePath, _ := command.LogFilePath(session.Dir(s.configDir))\n\t\tlogFile, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_WRONLY, 0600)\n\t\tif err != nil {\n\t\t\ts.logger.Debug(\"failed to open log file to echo input\", \"error\", err)\n\t\t} else {\n\t\t\tdefer logFile.Close()\n\t\t\t// Write with STDOUT prefix to maintain log format consistency\n\t\t\tdataWithPrefix := append(log.STDOUT_PREFIX, []byte(data)...)\n\t\t\t_, err = logFile.Write(dataWithPrefix)\n\t\t\tif err != nil {\n\t\t\t\ts.logger.Error(\"failed to echo input to log file\", \"error\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/list.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport \"github.com/daytonaio/daemon/internal/util\"\n\nfunc (s *SessionService) List() ([]Session, error) {\n\tsessions := []Session{}\n\n\tfor _, sessionId := range s.sessions.Keys() {\n\t\tif sessionId == util.EntrypointSessionID {\n\t\t\tcontinue\n\t\t}\n\n\t\tcommands, err := s.getSessionCommands(sessionId)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tsessions = append(sessions, Session{\n\t\t\tSessionId: sessionId,\n\t\t\tCommands:  commands,\n\t\t})\n\t}\n\n\treturn sessions, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/log.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daemon/internal/util\"\n\t\"github.com/gorilla/websocket\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/log\"\n)\n\ntype FetchLogsOptions struct {\n\tIsCombinedOutput   bool\n\tIsWebsocketUpgrade bool\n\tFollow             bool\n}\n\nfunc (s *SessionService) GetSessionCommandLogs(sessionId, commandId string, request *http.Request, responseWriter http.ResponseWriter, opts FetchLogsOptions) ([]byte, error) {\n\tsession, ok := s.sessions.Get(sessionId)\n\tif !ok {\n\t\treturn nil, common_errors.NewNotFoundError(errors.New(\"session not found\"))\n\t}\n\n\tcommand, ok := session.commands.Get(commandId)\n\tif !ok {\n\t\treturn nil, common_errors.NewNotFoundError(errors.New(\"command not found\"))\n\t}\n\n\tlogFilePath, exitCodeFilePath := command.LogFilePath(session.Dir(s.configDir))\n\n\tif opts.IsWebsocketUpgrade {\n\t\tlogFile, err := os.Open(logFilePath)\n\t\tif err != nil {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\treturn nil, common_errors.NewNotFoundError(err)\n\t\t\t}\n\t\t\tif os.IsPermission(err) {\n\t\t\t\treturn nil, common_errors.NewForbiddenError(err)\n\t\t\t}\n\t\t\treturn nil, common_errors.NewBadRequestError(err)\n\t\t}\n\t\tdefer logFile.Close()\n\t\tReadLog(s.logger, request, responseWriter, opts.Follow, logFile, util.ReadLogWithExitCode, exitCodeFilePath, func(logger *slog.Logger, conn *websocket.Conn, messages chan []byte, errors chan error, pongCh <-chan []byte) {\n\t\t\tvar buffer []byte\n\t\t\tfor {\n\t\t\t\t// Priority: always flush pending pong responses before writing data.\n\t\t\t\t// This ensures keepalive pongs are never delayed by data writes.\n\t\t\t\tutil.WritePendingPongs(conn, pongCh, time.Second, logger)\n\n\t\t\t\tselect {\n\t\t\t\tcase <-session.ctx.Done():\n\t\t\t\t\t// Flush any remaining bytes in buffer before closing\n\t\t\t\t\tif opts.IsCombinedOutput && len(buffer) > 0 {\n\t\t\t\t\t\tremainingData := flushRemainingBuffer(&buffer)\n\t\t\t\t\t\tif len(remainingData) > 0 {\n\t\t\t\t\t\t\terr := conn.WriteMessage(websocket.BinaryMessage, remainingData)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\ts.logger.Error(\"websocket write error\", \"error\", err)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\terr := conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, \"\"), time.Now().Add(time.Second))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\ts.logger.Error(\"websocket close control error\", \"error\", err)\n\t\t\t\t\t}\n\t\t\t\t\tconn.Close()\n\t\t\t\t\treturn\n\t\t\t\tcase pong := <-pongCh:\n\t\t\t\t\t// Pong arrived while waiting for data — write it immediately\n\t\t\t\t\tif err := conn.WriteControl(websocket.PongMessage, pong, time.Now().Add(time.Second)); err != nil {\n\t\t\t\t\t\ts.logger.Debug(\"failed to write pong\", \"error\", err)\n\t\t\t\t\t}\n\t\t\t\tcase msg := <-messages:\n\t\t\t\t\tif opts.IsCombinedOutput {\n\t\t\t\t\t\t// Process chunks with buffering to handle prefixes split across chunks\n\t\t\t\t\t\tprocessedData := processLogChunkWithPrefixFiltering(msg, &buffer)\n\t\t\t\t\t\tif len(processedData) > 0 {\n\t\t\t\t\t\t\terr := conn.WriteMessage(websocket.BinaryMessage, processedData)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\terrors <- err\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\terr := conn.WriteMessage(websocket.BinaryMessage, msg)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors <- err\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tcase <-errors:\n\t\t\t\t\t// Stream ended, flush any remaining bytes in buffer\n\t\t\t\t\tif opts.IsCombinedOutput && len(buffer) > 0 {\n\t\t\t\t\t\tremainingData := flushRemainingBuffer(&buffer)\n\t\t\t\t\t\tif len(remainingData) > 0 {\n\t\t\t\t\t\t\twriteErr := conn.WriteMessage(websocket.BinaryMessage, remainingData)\n\t\t\t\t\t\t\tif writeErr != nil {\n\t\t\t\t\t\t\t\ts.logger.Error(\"websocket write error\", \"error\", writeErr)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// The error will be handled by the main ReadLog function\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\treturn nil, nil\n\t}\n\n\tlogBytes, err := os.ReadFile(logFilePath)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil, common_errors.NewNotFoundError(err)\n\t\t}\n\t\tif os.IsPermission(err) {\n\t\t\treturn nil, common_errors.NewForbiddenError(err)\n\t\t}\n\t\treturn nil, common_errors.NewBadRequestError(err)\n\t}\n\n\tif opts.IsCombinedOutput {\n\t\t// remove prefixes from log bytes\n\t\tlogBytes = bytes.ReplaceAll(bytes.ReplaceAll(logBytes, log.STDOUT_PREFIX, []byte{}), log.STDERR_PREFIX, []byte{})\n\t}\n\n\treturn logBytes, nil\n}\n\n// ReadLog reads from the logReader and writes to the websocket.\n// TLogData is the type of the message to be read from the logReader.\n// The wsWriteFunc callback receives a pongCh that carries queued pong payloads;\n// the callback must drain it (via util.WritePendingPongs) before each data write\n// to give keepalive pongs priority over log data.\nfunc ReadLog[TLogData any](logger *slog.Logger, request *http.Request, responseWriter http.ResponseWriter, follow bool, logReader io.Reader, readFunc func(context.Context, io.Reader, bool, string, chan TLogData, chan error), exitCodeFilePath string, wsWriteFunc func(*slog.Logger, *websocket.Conn, chan TLogData, chan error, <-chan []byte)) {\n\tws, err := util.UpgradeToWebSocket(responseWriter, request)\n\tif err != nil {\n\t\tlogger.Error(\"websocket upgrade error\", \"error\", err)\n\t\treturn\n\t}\n\n\tpongCh := util.SetupWSKeepAlive(ws, logger)\n\n\tdefer func() {\n\t\tcloseErr := websocket.CloseNormalClosure\n\t\tif !errors.Is(err, io.EOF) {\n\t\t\tcloseErr = websocket.CloseInternalServerErr\n\t\t}\n\t\terr := ws.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(closeErr, \"\"), time.Now().Add(time.Second))\n\t\tif err != nil {\n\t\t\tlogger.Debug(\"websocket close control error\", \"error\", err)\n\t\t}\n\t\tws.Close()\n\t}()\n\n\tmsgChannel := make(chan TLogData)\n\terrChannel := make(chan error)\n\tctx, cancel := context.WithCancel(request.Context())\n\n\tdefer cancel()\n\tgo readFunc(ctx, logReader, follow, exitCodeFilePath, msgChannel, errChannel)\n\tgo wsWriteFunc(logger, ws, msgChannel, errChannel, pongCh)\n\n\treadErr := make(chan error)\n\tgo func() {\n\t\tfor {\n\t\t\t_, _, err := ws.ReadMessage()\n\t\t\treadErr <- err\n\t\t}\n\t}()\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tcase err = <-errChannel:\n\t\t\tif err != nil {\n\t\t\t\tif !errors.Is(err, io.EOF) {\n\t\t\t\t\tlogger.Error(\"log read error\", \"error\", err)\n\t\t\t\t}\n\t\t\t\tcancel()\n\t\t\t\treturn\n\t\t\t}\n\t\tcase err := <-readErr:\n\t\t\tif websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure, websocket.CloseAbnormalClosure) {\n\t\t\t\tlogger.Error(\"websocket unexpected close error\", \"error\", err)\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\n// processLogChunkWithPrefixFiltering processes log chunks with buffering to handle prefixes split across chunks\nfunc processLogChunkWithPrefixFiltering(chunk []byte, buffer *[]byte) []byte {\n\t// Append new chunk to buffer\n\t*buffer = append(*buffer, chunk...)\n\n\tvar result []byte\n\tprocessed := 0\n\n\tfor processed < len(*buffer) {\n\t\t// Check if we have enough bytes to check for prefixes\n\t\tif len(*buffer)-processed < 3 {\n\t\t\t// Not enough bytes for a complete prefix\n\t\t\t// Check if remaining bytes could be part of a prefix\n\t\t\tremainingBytes := (*buffer)[processed:]\n\n\t\t\t// If remaining bytes could be start of STDOUT_PREFIX (0x01, 0x01, 0x01)\n\t\t\tcouldBeStdoutPrefix := true\n\t\t\tfor i, b := range remainingBytes {\n\t\t\t\tif b != log.STDOUT_PREFIX[i] {\n\t\t\t\t\tcouldBeStdoutPrefix = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If remaining bytes could be start of STDERR_PREFIX (0x02, 0x02, 0x02)\n\t\t\tcouldBeStderrPrefix := true\n\t\t\tfor i, b := range remainingBytes {\n\t\t\t\tif b != log.STDERR_PREFIX[i] {\n\t\t\t\t\tcouldBeStderrPrefix = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If remaining bytes could be part of either prefix, keep them in buffer\n\t\t\tif couldBeStdoutPrefix || couldBeStderrPrefix {\n\t\t\t\t*buffer = remainingBytes\n\t\t\t} else {\n\t\t\t\t// Remaining bytes cannot be part of any prefix, output them\n\t\t\t\tresult = append(result, remainingBytes...)\n\t\t\t\t*buffer = (*buffer)[:0]\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\t// Check for STDOUT_PREFIX (0x01, 0x01, 0x01)\n\t\tif (*buffer)[processed] == log.STDOUT_PREFIX[0] &&\n\t\t\t(*buffer)[processed+1] == log.STDOUT_PREFIX[1] &&\n\t\t\t(*buffer)[processed+2] == log.STDOUT_PREFIX[2] {\n\t\t\t// Found STDOUT_PREFIX, skip it\n\t\t\tprocessed += 3\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check for STDERR_PREFIX (0x02, 0x02, 0x02)\n\t\tif (*buffer)[processed] == log.STDERR_PREFIX[0] &&\n\t\t\t(*buffer)[processed+1] == log.STDERR_PREFIX[1] &&\n\t\t\t(*buffer)[processed+2] == log.STDERR_PREFIX[2] {\n\t\t\t// Found STDERR_PREFIX, skip it\n\t\t\tprocessed += 3\n\t\t\tcontinue\n\t\t}\n\n\t\t// No prefix found, add this byte to result\n\t\tresult = append(result, (*buffer)[processed])\n\t\tprocessed++\n\t}\n\n\t// Remove processed bytes from buffer\n\tif processed > 0 && processed < len(*buffer) {\n\t\t*buffer = (*buffer)[processed:]\n\t}\n\n\treturn result\n}\n\n// flushRemainingBuffer processes any remaining bytes in the buffer at the end of the stream\nfunc flushRemainingBuffer(buffer *[]byte) []byte {\n\tif len(*buffer) == 0 {\n\t\treturn nil\n\t}\n\n\t// At the end of stream, any remaining bytes are not prefixes (since they're incomplete)\n\t// So we should output them as regular data\n\tresult := make([]byte, len(*buffer))\n\tcopy(result, *buffer)\n\t*buffer = (*buffer)[:0] // Clear the buffer\n\treturn result\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/service.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"log/slog\"\n\t\"time\"\n\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n)\n\ntype SessionService struct {\n\tlogger                   *slog.Logger\n\tconfigDir                string\n\tsessions                 cmap.ConcurrentMap[string, *session]\n\tterminationGracePeriod   time.Duration\n\tterminationCheckInterval time.Duration\n}\n\nfunc NewSessionService(logger *slog.Logger, configDir string, terminationGracePeriod, terminationCheckInterval time.Duration) *SessionService {\n\treturn &SessionService{\n\t\tlogger:                   logger.With(slog.String(\"component\", \"session_service\")),\n\t\tconfigDir:                configDir,\n\t\tsessions:                 cmap.New[*session](),\n\t\tterminationGracePeriod:   terminationGracePeriod,\n\t\tterminationCheckInterval: terminationCheckInterval,\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/session/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n)\n\ntype session struct {\n\tid          string\n\tcmd         *exec.Cmd\n\tstdinWriter io.Writer\n\tcommands    cmap.ConcurrentMap[string, *Command]\n\tctx         context.Context\n\tcancel      context.CancelFunc\n}\n\nfunc (s *session) Dir(configDir string) string {\n\treturn filepath.Join(configDir, \"sessions\", s.id)\n}\n\ntype Command struct {\n\tId                string `json:\"id\" validate:\"required\"`\n\tCommand           string `json:\"command\" validate:\"required\"`\n\tExitCode          *int   `json:\"exitCode,omitempty\" validate:\"optional\"`\n\tSuppressInputEcho bool   `json:\"suppressInputEcho\" validate:\"optional\"`\n}\n\nfunc (c *Command) LogFilePath(sessionDir string) (string, string) {\n\treturn filepath.Join(sessionDir, c.Id, \"output.log\"), filepath.Join(sessionDir, c.Id, \"exit_code\")\n}\n\nfunc (c *Command) InputFilePath(sessionDir string) string {\n\treturn filepath.Join(sessionDir, c.Id, \"input.pipe\")\n}\n\ntype Session struct {\n\tSessionId string     `json:\"sessionId\" validate:\"required\"`\n\tCommands  []*Command `json:\"commands\" validate:\"required\"`\n}\n\ntype SessionExecute struct {\n\tCommandId string  `json:\"cmdId\" validate:\"optional\"`\n\tOutput    *string `json:\"output\" validate:\"optional\"`\n\tStdout    *string `json:\"stdout\" validate:\"optional\"`\n\tStderr    *string `json:\"stderr\" validate:\"optional\"`\n\tExitCode  *int    `json:\"exitCode\" validate:\"optional\"`\n}\n"
  },
  {
    "path": "apps/daemon/pkg/ssh/config/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage config\n\nconst SSH_PORT = 22220\n"
  },
  {
    "path": "apps/daemon/pkg/ssh/server.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage ssh\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/daytonaio/daemon/pkg/common\"\n\t\"github.com/daytonaio/daemon/pkg/ssh/config\"\n\t\"github.com/gliderlabs/ssh\"\n\t\"github.com/pkg/sftp\"\n\t\"golang.org/x/sys/unix\"\n)\n\ntype Server struct {\n\tlogger         *slog.Logger\n\tworkDir        string\n\tdefaultWorkDir string\n}\n\nfunc NewServer(logger *slog.Logger, workDir, defaultWorkDir string) *Server {\n\treturn &Server{\n\t\tlogger:         logger.With(slog.String(\"component\", \"ssh_server\")),\n\t\tworkDir:        workDir,\n\t\tdefaultWorkDir: defaultWorkDir,\n\t}\n}\n\nfunc (s *Server) Start() error {\n\tforwardedTCPHandler := &ssh.ForwardedTCPHandler{}\n\tunixForwardHandler := newForwardedUnixHandler()\n\n\tsshServer := ssh.Server{\n\t\tAddr: fmt.Sprintf(\":%d\", config.SSH_PORT),\n\t\tPublicKeyHandler: func(ctx ssh.Context, key ssh.PublicKey) bool {\n\t\t\t// Allow all public key authentication attempts\n\t\t\ts.logger.Debug(\"Public key authentication accepted\", \"user\", ctx.User())\n\t\t\treturn true\n\t\t},\n\t\tPasswordHandler: func(ctx ssh.Context, password string) bool {\n\t\t\ts.logger.Debug(\"Password authentication attempt\", \"user\", ctx.User())\n\t\t\tif len(password) > 0 {\n\t\t\t\ts.logger.Debug(\"Received password\", \"length\", len(password))\n\t\t\t} else {\n\t\t\t\ts.logger.Debug(\"Received empty password\")\n\t\t\t}\n\t\t\t// Only allow authentication with the hardcoded password 'sandbox-ssh'\n\t\t\tauthenticated := password == \"sandbox-ssh\"\n\t\t\tif authenticated {\n\t\t\t\ts.logger.Debug(\"Password authentication succeeded\", \"user\", ctx.User())\n\t\t\t} else {\n\t\t\t\ts.logger.Debug(\"Password authentication failed (wrong password)\", \"user\", ctx.User())\n\t\t\t}\n\t\t\treturn authenticated\n\t\t},\n\t\tHandler: func(session ssh.Session) {\n\t\t\tswitch ss := session.Subsystem(); ss {\n\t\t\tcase \"\":\n\t\t\tcase \"sftp\":\n\t\t\t\ts.sftpHandler(session)\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\ts.logger.Error(\"Subsystem not supported\", \"subsystem\", ss)\n\t\t\t\tsession.Exit(1)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tptyReq, winCh, isPty := session.Pty()\n\t\t\tif session.RawCommand() == \"\" && isPty {\n\t\t\t\ts.handlePty(session, ptyReq, winCh)\n\t\t\t} else {\n\t\t\t\ts.handleNonPty(session)\n\t\t\t}\n\t\t},\n\t\tChannelHandlers: map[string]ssh.ChannelHandler{\n\t\t\t\"session\":                        ssh.DefaultSessionHandler,\n\t\t\t\"direct-tcpip\":                   ssh.DirectTCPIPHandler,\n\t\t\t\"direct-streamlocal@openssh.com\": directStreamLocalHandler,\n\t\t},\n\t\tRequestHandlers: map[string]ssh.RequestHandler{\n\t\t\t\"tcpip-forward\":                          forwardedTCPHandler.HandleSSHRequest,\n\t\t\t\"cancel-tcpip-forward\":                   forwardedTCPHandler.HandleSSHRequest,\n\t\t\t\"streamlocal-forward@openssh.com\":        unixForwardHandler.HandleSSHRequest,\n\t\t\t\"cancel-streamlocal-forward@openssh.com\": unixForwardHandler.HandleSSHRequest,\n\t\t},\n\t\tSubsystemHandlers: map[string]ssh.SubsystemHandler{\n\t\t\t\"sftp\": s.sftpHandler,\n\t\t},\n\t\tLocalPortForwardingCallback: ssh.LocalPortForwardingCallback(func(ctx ssh.Context, dhost string, dport uint32) bool {\n\t\t\treturn true\n\t\t}),\n\t\tReversePortForwardingCallback: ssh.ReversePortForwardingCallback(func(ctx ssh.Context, host string, port uint32) bool {\n\t\t\treturn true\n\t\t}),\n\t\tSessionRequestCallback: func(sess ssh.Session, requestType string) bool {\n\t\t\treturn true\n\t\t},\n\t}\n\n\ts.logger.Info(\"Starting ssh server\", \"port\", config.SSH_PORT)\n\treturn sshServer.ListenAndServe()\n}\n\nfunc (s *Server) handlePty(session ssh.Session, ptyReq ssh.Pty, winCh <-chan ssh.Window) {\n\tdir := s.workDir\n\n\tif _, err := os.Stat(s.workDir); os.IsNotExist(err) {\n\t\tdir = s.defaultWorkDir\n\t}\n\n\tenv := []string{}\n\n\tif ssh.AgentRequested(session) {\n\t\tl, err := ssh.NewAgentListener()\n\t\tif err != nil {\n\t\t\ts.logger.Error(\"Failed to start agent listener\", \"error\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer l.Close()\n\t\tgo ssh.ForwardAgentConnections(l, session)\n\t\tenv = append(env, fmt.Sprintf(\"%s=%s\", \"SSH_AUTH_SOCK\", l.Addr().String()))\n\t}\n\n\tsizeCh := make(chan common.TTYSize)\n\n\tgo func() {\n\t\tfor win := range winCh {\n\t\t\tsizeCh <- common.TTYSize{\n\t\t\t\tHeight: win.Height,\n\t\t\t\tWidth:  win.Width,\n\t\t\t}\n\t\t}\n\t}()\n\n\terr := common.SpawnTTY(common.SpawnTTYOptions{\n\t\tDir:    dir,\n\t\tStdIn:  session,\n\t\tStdOut: session,\n\t\tTerm:   ptyReq.Term,\n\t\tEnv:    env,\n\t\tSizeCh: sizeCh,\n\t})\n\n\tif err != nil {\n\t\t// Debug log here because this gets called on each ssh \"exit\"\n\t\t// TODO: Find a better way to handle this\n\t\ts.logger.Debug(\"Failed to spawn tty\", \"error\", err)\n\t\treturn\n\t}\n}\n\nfunc (s *Server) handleNonPty(session ssh.Session) {\n\targs := []string{}\n\tif len(session.Command()) > 0 {\n\t\targs = append([]string{\"-c\"}, session.RawCommand())\n\t}\n\n\tcmd := exec.Command(\"/bin/sh\", args...)\n\n\tcmd.Env = append(cmd.Env, os.Environ()...)\n\n\tif ssh.AgentRequested(session) {\n\t\tl, err := ssh.NewAgentListener()\n\t\tif err != nil {\n\t\t\ts.logger.Error(\"Failed to start agent listener\", \"error\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer l.Close()\n\t\tgo ssh.ForwardAgentConnections(l, session)\n\t\tcmd.Env = append(cmd.Env, fmt.Sprintf(\"%s=%s\", \"SSH_AUTH_SOCK\", l.Addr().String()))\n\t}\n\n\tcmd.Dir = s.workDir\n\tif _, err := os.Stat(s.workDir); os.IsNotExist(err) {\n\t\tcmd.Dir = s.defaultWorkDir\n\t}\n\n\tcmd.Stdout = session\n\tcmd.Stderr = session.Stderr()\n\tstdinPipe, err := cmd.StdinPipe()\n\tif err != nil {\n\t\ts.logger.Error(\"Unable to setup stdin for session\", \"error\", err)\n\t\treturn\n\t}\n\tgo func() {\n\t\t_, err := io.Copy(stdinPipe, session)\n\t\tif err != nil {\n\t\t\ts.logger.Error(\"Unable to read from session\", \"error\", err)\n\t\t\treturn\n\t\t}\n\t\t_ = stdinPipe.Close()\n\t}()\n\n\terr = cmd.Start()\n\tif err != nil {\n\t\ts.logger.Error(\"Unable to start command\", \"error\", err)\n\t\treturn\n\t}\n\tsigs := make(chan ssh.Signal, 1)\n\tsession.Signals(sigs)\n\tdefer func() {\n\t\tsession.Signals(nil)\n\t\tclose(sigs)\n\t}()\n\tgo func() {\n\t\tfor sig := range sigs {\n\t\t\tsignal := s.osSignalFrom(sig)\n\t\t\terr := cmd.Process.Signal(signal)\n\t\t\tif err != nil {\n\t\t\t\ts.logger.Warn(\"Unable to send signal to process\", \"error\", err)\n\t\t\t}\n\t\t}\n\t}()\n\terr = cmd.Wait()\n\n\tif err != nil {\n\t\ts.logger.Info(\"Command exited\", \"command\", session.RawCommand(), \"error\", err)\n\t\tsession.Exit(127)\n\t\treturn\n\t}\n\n\terr = session.Exit(0)\n\tif err != nil {\n\t\ts.logger.Warn(\"Unable to exit session\", \"error\", err)\n\t}\n}\n\nfunc (s *Server) osSignalFrom(sig ssh.Signal) os.Signal {\n\tswitch sig {\n\tcase ssh.SIGABRT:\n\t\treturn unix.SIGABRT\n\tcase ssh.SIGALRM:\n\t\treturn unix.SIGALRM\n\tcase ssh.SIGFPE:\n\t\treturn unix.SIGFPE\n\tcase ssh.SIGHUP:\n\t\treturn unix.SIGHUP\n\tcase ssh.SIGILL:\n\t\treturn unix.SIGILL\n\tcase ssh.SIGINT:\n\t\treturn unix.SIGINT\n\tcase ssh.SIGKILL:\n\t\treturn unix.SIGKILL\n\tcase ssh.SIGPIPE:\n\t\treturn unix.SIGPIPE\n\tcase ssh.SIGQUIT:\n\t\treturn unix.SIGQUIT\n\tcase ssh.SIGSEGV:\n\t\treturn unix.SIGSEGV\n\tcase ssh.SIGTERM:\n\t\treturn unix.SIGTERM\n\tcase ssh.SIGUSR1:\n\t\treturn unix.SIGUSR1\n\tcase ssh.SIGUSR2:\n\t\treturn unix.SIGUSR2\n\n\t// Unhandled, use sane fallback.\n\tdefault:\n\t\treturn unix.SIGKILL\n\t}\n}\n\nfunc (s *Server) sftpHandler(session ssh.Session) {\n\tdebugStream := io.Discard\n\tserverOptions := []sftp.ServerOption{\n\t\tsftp.WithDebug(debugStream),\n\t}\n\tserver, err := sftp.NewServer(\n\t\tsession,\n\t\tserverOptions...,\n\t)\n\tif err != nil {\n\t\ts.logger.Error(\"sftp server init error\", \"error\", err)\n\t\treturn\n\t}\n\tif err := server.Serve(); err == io.EOF {\n\t\tserver.Close()\n\t} else if err != nil {\n\t\ts.logger.Error(\"sftp server completed with error\", \"error\", err)\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/ssh/unix_forward.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage ssh\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"log/slog\"\n\t\"net\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"syscall\"\n\n\t\"github.com/gliderlabs/ssh\"\n\tgossh \"golang.org/x/crypto/ssh\"\n)\n\n// streamLocalForwardPayload describes the extra data sent in a\n// streamlocal-forward@openssh.com containing the socket path to bind to.\ntype streamLocalForwardPayload struct {\n\tSocketPath string\n}\n\n// forwardedStreamLocalPayload describes the data sent as the payload in the new\n// channel request when a Unix connection is accepted by the listener.\ntype forwardedStreamLocalPayload struct {\n\tSocketPath string\n\tReserved   uint32\n}\n\n// forwardedUnixHandler is a clone of ssh.ForwardedTCPHandler that does\n// streamlocal forwarding (aka. unix forwarding) instead of TCP forwarding.\ntype forwardedUnixHandler struct {\n\tsync.Mutex\n\tforwards map[forwardKey]net.Listener\n}\n\ntype forwardKey struct {\n\tsessionID string\n\taddr      string\n}\n\nfunc newForwardedUnixHandler() *forwardedUnixHandler {\n\treturn &forwardedUnixHandler{\n\t\tforwards: make(map[forwardKey]net.Listener),\n\t}\n}\n\nfunc (h *forwardedUnixHandler) HandleSSHRequest(ctx ssh.Context, _ *ssh.Server, req *gossh.Request) (bool, []byte) {\n\tslog.Debug(\"handling SSH unix forward\")\n\tconn, ok := ctx.Value(ssh.ContextKeyConn).(*gossh.ServerConn)\n\tif !ok {\n\t\tslog.Warn(\"SSH unix forward request from client with no gossh connection\")\n\t\treturn false, nil\n\t}\n\n\tswitch req.Type {\n\tcase \"streamlocal-forward@openssh.com\":\n\t\tvar reqPayload streamLocalForwardPayload\n\t\terr := gossh.Unmarshal(req.Payload, &reqPayload)\n\t\tif err != nil {\n\t\t\tslog.Warn(\"parse streamlocal-forward@openssh.com request (SSH unix forward) payload from client\", \"error\", err)\n\t\t\treturn false, nil\n\t\t}\n\n\t\taddr := reqPayload.SocketPath\n\t\tslog.Debug(\"request begin SSH unix forward\", \"socketPath\", addr)\n\n\t\tkey := forwardKey{\n\t\t\tsessionID: ctx.SessionID(),\n\t\t\taddr:      addr,\n\t\t}\n\n\t\th.Lock()\n\t\t_, ok := h.forwards[key]\n\t\th.Unlock()\n\t\tif ok {\n\t\t\t// In cases where `ExitOnForwardFailure=yes` is set, returning false\n\t\t\t// here will cause the connection to be closed. To avoid this, and\n\t\t\t// to match OpenSSH behavior, we silently ignore the second forward\n\t\t\t// request.\n\t\t\tslog.Warn(\"SSH unix forward request for socket path that is already being forwarded on this session, ignoring\", \"socketPath\", addr)\n\t\t\treturn true, nil\n\t\t}\n\n\t\t// Create socket parent dir if not exists.\n\t\tparentDir := filepath.Dir(addr)\n\t\terr = os.MkdirAll(parentDir, 0o700)\n\t\tif err != nil {\n\t\t\tslog.Error(\"failed to create parent directory for unix socket\", \"error\", err)\n\t\t\treturn false, nil\n\t\t}\n\n\t\t// Remove existing socket if it exists. We do not use os.Remove() here\n\t\t// so that directories are kept. Note that it's possible that we will\n\t\t// overwrite a regular file here. Both of these behaviors match OpenSSH,\n\t\t// however, which is why we unlink.\n\t\terr = unlink(addr)\n\t\tif err != nil && !errors.Is(err, fs.ErrNotExist) {\n\t\t\tslog.Warn(\"remove existing socket for SSH unix forward request\", \"socketPath\", addr, \"error\", err)\n\t\t\treturn false, nil\n\t\t}\n\n\t\tlc := &net.ListenConfig{}\n\t\tln, err := lc.Listen(ctx, \"unix\", addr)\n\t\tif err != nil {\n\t\t\tslog.Warn(\"listen on Unix socket for SSH unix forward request\", \"socketPath\", addr, \"error\", err)\n\t\t\treturn false, nil\n\t\t}\n\t\tslog.Debug(\"SSH unix forward listening on socket\", \"socketPath\", addr)\n\n\t\t// The listener needs to successfully start before it can be added to\n\t\t// the map, so we don't have to worry about checking for an existing\n\t\t// listener.\n\t\t//\n\t\t// This is also what the upstream TCP version of this code does.\n\t\th.Lock()\n\t\th.forwards[key] = ln\n\t\th.Unlock()\n\t\tslog.Debug(\"SSH unix forward added to cache\", \"socketPath\", addr)\n\n\t\tctx, cancel := context.WithCancel(ctx)\n\t\tgo func() {\n\t\t\t<-ctx.Done()\n\t\t\t_ = ln.Close()\n\t\t}()\n\t\tgo func() {\n\t\t\tdefer cancel()\n\n\t\t\tfor {\n\t\t\t\tc, err := ln.Accept()\n\t\t\t\tif err != nil {\n\t\t\t\t\tif !errors.Is(err, net.ErrClosed) {\n\t\t\t\t\t\tslog.Warn(\"accept on local Unix socket for SSH unix forward request\", \"socketPath\", addr, \"error\", err)\n\t\t\t\t\t}\n\t\t\t\t\t// closed below\n\t\t\t\t\tslog.Debug(\"SSH unix forward listener closed\", \"socketPath\", addr)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tslog.Debug(\"accepted SSH unix forward connection\", \"socketPath\", addr)\n\t\t\t\tpayload := gossh.Marshal(&forwardedStreamLocalPayload{\n\t\t\t\t\tSocketPath: addr,\n\t\t\t\t})\n\n\t\t\t\tgo func() {\n\t\t\t\t\tch, reqs, err := conn.OpenChannel(\"forwarded-streamlocal@openssh.com\", payload)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tslog.Warn(\"open SSH unix forward channel to client\", \"socketPath\", addr, \"error\", err)\n\t\t\t\t\t\t_ = c.Close()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tgo gossh.DiscardRequests(reqs)\n\t\t\t\t\tBicopy(ctx, ch, c)\n\t\t\t\t}()\n\t\t\t}\n\n\t\t\th.Lock()\n\t\t\tif ln2, ok := h.forwards[key]; ok && ln2 == ln {\n\t\t\t\tdelete(h.forwards, key)\n\t\t\t}\n\t\t\th.Unlock()\n\t\t\tslog.Debug(\"SSH unix forward listener removed from cache\", \"socketPath\", addr)\n\t\t\t_ = ln.Close()\n\t\t}()\n\n\t\treturn true, nil\n\n\tcase \"cancel-streamlocal-forward@openssh.com\":\n\t\tvar reqPayload streamLocalForwardPayload\n\t\terr := gossh.Unmarshal(req.Payload, &reqPayload)\n\t\tif err != nil {\n\t\t\tslog.Warn(\"parse cancel-streamlocal-forward@openssh.com (SSH unix forward) request payload from client\", \"error\", err)\n\t\t\treturn false, nil\n\t\t}\n\t\tslog.Debug(\"request to cancel SSH unix forward\", \"socketPath\", reqPayload.SocketPath)\n\n\t\tkey := forwardKey{\n\t\t\tsessionID: ctx.SessionID(),\n\t\t\taddr:      reqPayload.SocketPath,\n\t\t}\n\n\t\th.Lock()\n\t\tln, ok := h.forwards[key]\n\t\tdelete(h.forwards, key)\n\t\th.Unlock()\n\t\tif !ok {\n\t\t\tslog.Warn(\"SSH unix forward not found in cache\", \"socketPath\", reqPayload.SocketPath)\n\t\t\treturn true, nil\n\t\t}\n\t\t_ = ln.Close()\n\t\treturn true, nil\n\n\tdefault:\n\t\treturn false, nil\n\t}\n}\n\n// directStreamLocalPayload describes the extra data sent in a\n// direct-streamlocal@openssh.com channel request containing the socket path.\ntype directStreamLocalPayload struct {\n\tSocketPath string\n\n\tReserved1 string\n\tReserved2 uint32\n}\n\nfunc directStreamLocalHandler(_ *ssh.Server, _ *gossh.ServerConn, newChan gossh.NewChannel, ctx ssh.Context) {\n\tvar reqPayload directStreamLocalPayload\n\terr := gossh.Unmarshal(newChan.ExtraData(), &reqPayload)\n\tif err != nil {\n\t\t_ = newChan.Reject(gossh.ConnectionFailed, \"could not parse direct-streamlocal@openssh.com channel payload\")\n\t\treturn\n\t}\n\n\tvar dialer net.Dialer\n\tdconn, err := dialer.DialContext(ctx, \"unix\", reqPayload.SocketPath)\n\tif err != nil {\n\t\t_ = newChan.Reject(gossh.ConnectionFailed, fmt.Sprintf(\"dial unix socket %q: %+v\", reqPayload.SocketPath, err.Error()))\n\t\treturn\n\t}\n\n\tch, reqs, err := newChan.Accept()\n\tif err != nil {\n\t\t_ = dconn.Close()\n\t\treturn\n\t}\n\tgo gossh.DiscardRequests(reqs)\n\n\tBicopy(ctx, ch, dconn)\n}\n\n// unlink removes files and unlike os.Remove, directories are kept.\nfunc unlink(path string) error {\n\t// Ignore EINTR like os.Remove, see ignoringEINTR in os/file_posix.go\n\t// for more details.\n\tfor {\n\t\terr := syscall.Unlink(path)\n\t\tif !errors.Is(err, syscall.EINTR) {\n\t\t\treturn err\n\t\t}\n\t}\n}\n\n// Bicopy copies all of the data between the two connections and will close them\n// after one or both of them are done writing. If the context is canceled, both\n// of the connections will be closed.\nfunc Bicopy(ctx context.Context, c1, c2 io.ReadWriteCloser) {\n\tctx, cancel := context.WithCancel(ctx)\n\tdefer cancel()\n\n\tdefer func() {\n\t\t_ = c1.Close()\n\t\t_ = c2.Close()\n\t}()\n\n\tvar wg sync.WaitGroup\n\tcopyFunc := func(dst io.WriteCloser, src io.Reader) {\n\t\tdefer func() {\n\t\t\twg.Done()\n\t\t\t// If one side of the copy fails, ensure the other one exits as\n\t\t\t// well.\n\t\t\tcancel()\n\t\t}()\n\t\t_, _ = io.Copy(dst, src)\n\t}\n\n\twg.Add(2)\n\tgo copyFunc(c1, c2)\n\tgo copyFunc(c2, c1)\n\n\t// Convert waitgroup to a channel so we can also wait on the context.\n\tdone := make(chan struct{})\n\tgo func() {\n\t\tdefer close(done)\n\t\twg.Wait()\n\t}()\n\n\tselect {\n\tcase <-ctx.Done():\n\tcase <-done:\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/terminal/assets.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage terminal\n\nimport \"embed\"\n\n//go:embed static\nvar static embed.FS\n"
  },
  {
    "path": "apps/daemon/pkg/terminal/decoder.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage terminal\n\nimport (\n\t\"bytes\"\n\t\"unicode/utf8\"\n)\n\ntype UTF8Decoder struct {\n\tbuffer []byte\n}\n\nfunc NewUTF8Decoder() *UTF8Decoder {\n\treturn &UTF8Decoder{\n\t\tbuffer: make([]byte, 0, 1024),\n\t}\n}\n\n// Write appends new data to the internal buffer and decodes valid UTF-8 runes.\n// It returns the decoded string. Any incomplete bytes are kept for the next call.\nfunc (d *UTF8Decoder) Write(data []byte) string {\n\t// Combine buffer + new data\n\tdata = append(d.buffer, data...)\n\tvar output bytes.Buffer\n\n\ti := 0\n\tfor i < len(data) {\n\t\tr, size := utf8.DecodeRune(data[i:])\n\t\tif r == utf8.RuneError {\n\t\t\tif size == 1 {\n\t\t\t\t// Could be incomplete rune at the end\n\t\t\t\tremaining := len(data) - i\n\t\t\t\tif remaining < utf8.UTFMax {\n\t\t\t\t\t// Buffer the remaining bytes for next call\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// Otherwise, it's an invalid byte, emit replacement and advance by 1\n\t\t\t\toutput.WriteRune(r)\n\t\t\t\ti++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\toutput.WriteRune(r)\n\t\ti += size\n\t}\n\n\t// Save leftover bytes (possibly an incomplete rune)\n\td.buffer = d.buffer[:0]\n\tif i < len(data) {\n\t\td.buffer = append(d.buffer, data[i:]...)\n\t}\n\n\treturn output.String()\n}\n"
  },
  {
    "path": "apps/daemon/pkg/terminal/server.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage terminal\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/common\"\n\t\"github.com/gorilla/websocket\"\n)\n\nvar upgrader = websocket.Upgrader{\n\tCheckOrigin: func(r *http.Request) bool {\n\t\treturn true // Be careful with this in production\n\t},\n}\n\ntype windowSize struct {\n\tRows uint16 `json:\"rows\"`\n\tCols uint16 `json:\"cols\"`\n}\n\nfunc StartTerminalServer(port int) error {\n\t// Prepare the embedded frontend files\n\t// Serve the files from the embedded filesystem\n\tstaticFS, err := fs.Sub(static, \"static\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\thttp.Handle(\"/\", http.FileServer(http.FS(staticFS)))\n\thttp.HandleFunc(\"/ws\", handleWebSocket)\n\n\taddr := fmt.Sprintf(\":%d\", port)\n\tlog.Printf(\"Starting terminal server on http://localhost%s\", addr)\n\treturn http.ListenAndServe(addr, nil)\n}\n\nfunc handleWebSocket(w http.ResponseWriter, r *http.Request) {\n\tconn, err := upgrader.Upgrade(w, r, nil)\n\tif err != nil {\n\t\tlog.Printf(\"Failed to upgrade connection: %v\", err)\n\t\treturn\n\t}\n\tdefer conn.Close()\n\n\t// Create a new UTF8Decoder instance for this connection\n\tdecoder := NewUTF8Decoder()\n\n\tsizeCh := make(chan common.TTYSize)\n\tstdInReader, stdInWriter := io.Pipe()\n\tstdOutReader, stdOutWriter := io.Pipe()\n\n\t// Handle websocket -> pty\n\tgo func() {\n\t\tfor {\n\t\t\tmessageType, p, err := conn.ReadMessage()\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Check if it's a resize message\n\t\t\tif messageType == websocket.TextMessage {\n\t\t\t\tvar size windowSize\n\t\t\t\tif err := json.Unmarshal(p, &size); err == nil {\n\t\t\t\t\tsizeCh <- common.TTYSize{\n\t\t\t\t\t\tHeight: int(size.Rows),\n\t\t\t\t\t\tWidth:  int(size.Cols),\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Write to pty\n\t\t\t_, err = stdInWriter.Write(p)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\tgo func() {\n\t\t// Handle pty -> websocket\n\t\tbuf := make([]byte, 1024)\n\t\tfor {\n\t\t\tn, err := stdOutReader.Read(buf)\n\t\t\tif err != nil {\n\t\t\t\tif err != io.EOF {\n\t\t\t\t\tlog.Printf(\"Failed to read from pty: %v\", err)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// A multi-byte UTF-8 character can be split across stream reads.\n\t\t\t// UTF8Decoder buffers incomplete sequences to ensure proper decoding.\n\t\t\tdecoded := decoder.Write(buf[:n])\n\n\t\t\terr = conn.WriteMessage(websocket.TextMessage, []byte(decoded))\n\t\t\tif err != nil {\n\t\t\t\tlog.Printf(\"Failed to write to websocket: %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Create a pty\n\terr = common.SpawnTTY(common.SpawnTTYOptions{\n\t\tDir:    \"/\",\n\t\tStdIn:  stdInReader,\n\t\tStdOut: stdOutWriter,\n\t\tTerm:   \"xterm-256color\",\n\t\tSizeCh: sizeCh,\n\t})\n\tif err != nil {\n\t\tlog.Printf(\"Failed to start pty: %v\", err)\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/terminal/static/index.html",
    "content": "<!doctype html>\n<html>\n  <head>\n    <title>Web Terminal</title>\n    <link rel=\"stylesheet\" href=\"/xterm.css\" />\n    <script src=\"/xterm.js\"></script>\n    <script src=\"/xterm-addon-fit.js\"></script>\n    <style>\n      html,\n      body {\n        margin: 0;\n        padding: 0;\n        height: 100vh;\n        background: #000;\n      }\n      #terminal {\n        height: 100%;\n        width: 100%;\n      }\n    </style>\n  </head>\n  <body>\n    <div id=\"terminal\"></div>\n    <script>\n      const term = new Terminal({\n        cursorBlink: true,\n        fontSize: 14,\n        fontFamily: 'monospace',\n        theme: {\n          background: '#000000',\n          foreground: '#ffffff',\n        },\n      })\n\n      const fitAddon = new FitAddon.FitAddon()\n      term.loadAddon(fitAddon)\n      term.open(document.getElementById('terminal'))\n      fitAddon.fit()\n\n      // Connect to WebSocket\n      const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'\n      const socket = new WebSocket(`${protocol}//${window.location.host}/ws`)\n\n      socket.onopen = () => {\n        console.log('WebSocket connected')\n\n        // WebSocket -> Terminal\n        socket.onmessage = (event) => {\n          // Remove the Uint8Array conversion\n          term.write(event.data)\n        }\n\n        // Handle xterm data\n        term.onData((data) => {\n          socket.send(data)\n        })\n\n        // Handle resize\n        term.onResize((size) => {\n          socket.send(\n            JSON.stringify({\n              rows: size.rows,\n              cols: size.cols,\n            }),\n          )\n        })\n\n        // Initial size\n        socket.send(\n          JSON.stringify({\n            rows: term.rows,\n            cols: term.cols,\n          }),\n        )\n      }\n\n      // WebSocket -> Terminal\n      socket.onmessage = (event) => {\n        term.write(new Uint8Array(event.data))\n      }\n\n      socket.onclose = () => {\n        term.write('\\r\\nConnection closed\\r\\n')\n      }\n\n      // Handle window resize\n      window.addEventListener('resize', () => {\n        fitAddon.fit()\n      })\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/disabled_middleware.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage computeruse\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// computerUseDisabledMiddleware returns a middleware that handles requests when computer-use is disabled\nfunc ComputerUseDisabledMiddleware() gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tc.JSON(http.StatusServiceUnavailable, gin.H{\n\t\t\t\"message\":  \"Computer-use functionality is not available\",\n\t\t\t\"details\":  \"The computer-use plugin failed to initialize due to missing dependencies in the runtime environment.\",\n\t\t\t\"solution\": \"Install the required X11 dependencies (x11-apps, xvfb, etc.) to enable computer-use functionality. Check the daemon logs for specific error details.\",\n\t\t})\n\t\tc.Abort()\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/handler.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage computeruse\n\nimport (\n\t\"fmt\"\n\t\"github.com/gin-gonic/gin\"\n\t\"net/http\"\n)\n\ntype Handler struct {\n\tComputerUse IComputerUse\n}\n\n// StartComputerUse godoc\n//\n//\t@Summary\t\tStart computer use processes\n//\t@Description\tStart all computer use processes and return their status\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tComputerUseStartResponse\n//\t@Router\t\t\t/computeruse/start [post]\n//\n//\t@id\t\t\t\tStartComputerUse\nfunc (h *Handler) StartComputerUse(ctx *gin.Context) {\n\t_, err := h.ComputerUse.Start()\n\tif err != nil {\n\t\tctx.JSON(http.StatusServiceUnavailable, gin.H{\n\t\t\t\"error\":   \"Failed to start computer use\",\n\t\t\t\"details\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\tstatus, err := h.ComputerUse.GetProcessStatus()\n\tif err != nil {\n\t\tctx.JSON(http.StatusServiceUnavailable, gin.H{\n\t\t\t\"error\":   \"Failed to get computer use status\",\n\t\t\t\"details\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"message\": \"Computer use processes started successfully\",\n\t\t\"status\":  status,\n\t})\n}\n\n// StopComputerUse godoc\n//\n//\t@Summary\t\tStop computer use processes\n//\t@Description\tStop all computer use processes and return their status\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tComputerUseStopResponse\n//\t@Router\t\t\t/computeruse/stop [post]\n//\n//\t@id\t\t\t\tStopComputerUse\nfunc (h *Handler) StopComputerUse(ctx *gin.Context) {\n\t_, err := h.ComputerUse.Stop()\n\tif err != nil {\n\t\tctx.JSON(http.StatusServiceUnavailable, gin.H{\n\t\t\t\"error\":   \"Failed to stop computer use\",\n\t\t\t\"details\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\tstatus, err := h.ComputerUse.GetProcessStatus()\n\tif err != nil {\n\t\tctx.JSON(http.StatusServiceUnavailable, gin.H{\n\t\t\t\"error\":   \"Failed to get computer use status\",\n\t\t\t\"details\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"message\": \"Computer use processes stopped successfully\",\n\t\t\"status\":  status,\n\t})\n}\n\n// GetComputerUseStatus godoc\n//\n//\t@Summary\t\tGet computer use process status\n//\t@Description\tGet the status of all computer use processes\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tComputerUseStatusResponse\n//\t@Router\t\t\t/computeruse/process-status [get]\n//\n//\t@id\t\t\t\tGetComputerUseStatus\nfunc (h *Handler) GetComputerUseStatus(ctx *gin.Context) {\n\tstatus, err := h.ComputerUse.GetStatus()\n\tif err != nil {\n\t\tctx.JSON(http.StatusServiceUnavailable, gin.H{\n\t\t\t\"error\":   \"Failed to get computer use status\",\n\t\t\t\"details\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\tif status == nil {\n\t\tctx.JSON(http.StatusOK, gin.H{\n\t\t\t\"status\": \"unknown\",\n\t\t})\n\t\treturn\n\t}\n\tctx.JSON(http.StatusOK, *status)\n}\n\n// GetProcessStatus godoc\n//\n//\t@Summary\t\tGet specific process status\n//\t@Description\tCheck if a specific computer use process is running\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tprocessName\tpath\t\tstring\ttrue\t\"Process name to check\"\n//\t@Success\t\t200\t\t\t{object}\tProcessStatusResponse\n//\t@Router\t\t\t/computeruse/process/{processName}/status [get]\n//\n//\t@id\t\t\t\tGetProcessStatus\nfunc (h *Handler) GetProcessStatus(ctx *gin.Context) {\n\tprocessName := ctx.Param(\"processName\")\n\treq := &ProcessRequest{\n\t\tProcessName: processName,\n\t}\n\tisRunning, err := h.ComputerUse.IsProcessRunning(req)\n\tif err != nil {\n\t\tctx.JSON(http.StatusServiceUnavailable, gin.H{\n\t\t\t\"error\":   \"Failed to get process status\",\n\t\t\t\"details\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"processName\": processName,\n\t\t\"running\":     isRunning,\n\t})\n}\n\n// RestartProcess godoc\n//\n//\t@Summary\t\tRestart specific process\n//\t@Description\tRestart a specific computer use process\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tprocessName\tpath\t\tstring\ttrue\t\"Process name to restart\"\n//\t@Success\t\t200\t\t\t{object}\tProcessRestartResponse\n//\t@Router\t\t\t/computeruse/process/{processName}/restart [post]\n//\n//\t@id\t\t\t\tRestartProcess\nfunc (h *Handler) RestartProcess(ctx *gin.Context) {\n\tprocessName := ctx.Param(\"processName\")\n\treq := &ProcessRequest{\n\t\tProcessName: processName,\n\t}\n\t_, err := h.ComputerUse.RestartProcess(req)\n\n\tif err != nil {\n\t\tctx.JSON(http.StatusBadRequest, gin.H{\n\t\t\t\"error\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"message\":     fmt.Sprintf(\"Process %s restarted successfully\", processName),\n\t\t\"processName\": processName,\n\t})\n}\n\n// GetProcessLogs godoc\n//\n//\t@Summary\t\tGet process logs\n//\t@Description\tGet logs for a specific computer use process\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tprocessName\tpath\t\tstring\ttrue\t\"Process name to get logs for\"\n//\t@Success\t\t200\t\t\t{object}\tProcessLogsResponse\n//\t@Router\t\t\t/computeruse/process/{processName}/logs [get]\n//\n//\t@id\t\t\t\tGetProcessLogs\nfunc (h *Handler) GetProcessLogs(ctx *gin.Context) {\n\tprocessName := ctx.Param(\"processName\")\n\treq := &ProcessRequest{\n\t\tProcessName: processName,\n\t}\n\tlogs, err := h.ComputerUse.GetProcessLogs(req)\n\n\tif err != nil {\n\t\tctx.JSON(http.StatusBadRequest, gin.H{\n\t\t\t\"error\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"processName\": processName,\n\t\t\"logs\":        logs,\n\t})\n}\n\n// GetProcessErrors godoc\n//\n//\t@Summary\t\tGet process errors\n//\t@Description\tGet errors for a specific computer use process\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tprocessName\tpath\t\tstring\ttrue\t\"Process name to get errors for\"\n//\t@Success\t\t200\t\t\t{object}\tProcessErrorsResponse\n//\t@Router\t\t\t/computeruse/process/{processName}/errors [get]\n//\n//\t@id\t\t\t\tGetProcessErrors\nfunc (h *Handler) GetProcessErrors(ctx *gin.Context) {\n\tprocessName := ctx.Param(\"processName\")\n\treq := &ProcessRequest{\n\t\tProcessName: processName,\n\t}\n\terrors, err := h.ComputerUse.GetProcessErrors(req)\n\n\tif err != nil {\n\t\tctx.JSON(http.StatusBadRequest, gin.H{\n\t\t\t\"error\": err.Error(),\n\t\t})\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"processName\": processName,\n\t\t\"errors\":      errors,\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/interface.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage computeruse\n\nimport (\n\t\"net/http\"\n\t\"net/rpc\"\n\t\"strconv\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/hashicorp/go-plugin\"\n)\n\n// PluginInterface defines the interface that the computeruse plugin must implement\ntype IComputerUse interface {\n\t// Process management\n\tInitialize() (*Empty, error)\n\tStart() (*Empty, error)\n\tStop() (*Empty, error)\n\tGetProcessStatus() (map[string]ProcessStatus, error)\n\tIsProcessRunning(req *ProcessRequest) (bool, error)\n\tRestartProcess(req *ProcessRequest) (*Empty, error)\n\tGetProcessLogs(req *ProcessRequest) (string, error)\n\tGetProcessErrors(req *ProcessRequest) (string, error)\n\n\t// Screenshot methods\n\tTakeScreenshot(*ScreenshotRequest) (*ScreenshotResponse, error)\n\tTakeRegionScreenshot(*RegionScreenshotRequest) (*ScreenshotResponse, error)\n\tTakeCompressedScreenshot(*CompressedScreenshotRequest) (*ScreenshotResponse, error)\n\tTakeCompressedRegionScreenshot(*CompressedRegionScreenshotRequest) (*ScreenshotResponse, error)\n\n\t// Mouse control methods\n\tGetMousePosition() (*MousePositionResponse, error)\n\tMoveMouse(*MouseMoveRequest) (*MousePositionResponse, error)\n\tClick(*MouseClickRequest) (*MouseClickResponse, error)\n\tDrag(*MouseDragRequest) (*MouseDragResponse, error)\n\tScroll(*MouseScrollRequest) (*ScrollResponse, error)\n\n\t// Keyboard control methods\n\tTypeText(*KeyboardTypeRequest) (*Empty, error)\n\tPressKey(*KeyboardPressRequest) (*Empty, error)\n\tPressHotkey(*KeyboardHotkeyRequest) (*Empty, error)\n\n\t// Display info methods\n\tGetDisplayInfo() (*DisplayInfoResponse, error)\n\tGetWindows() (*WindowsResponse, error)\n\n\t// Status method\n\tGetStatus() (*ComputerUseStatusResponse, error)\n}\n\ntype ComputerUsePlugin struct {\n\tImpl IComputerUse\n}\n\n// Common structs for better composition\ntype Position struct {\n\tX int `json:\"x\"`\n\tY int `json:\"y\"`\n} //\t@name\tPosition\n\ntype Size struct {\n\tWidth  int `json:\"width\"`\n\tHeight int `json:\"height\"`\n} //\t@name\tSize\n\n// Screenshot parameter structs\ntype ScreenshotRequest struct {\n\tShowCursor bool `json:\"showCursor\"`\n} //\t@name\tScreenshotRequest\n\ntype RegionScreenshotRequest struct {\n\tPosition\n\tSize\n\tShowCursor bool `json:\"showCursor\"`\n} //\t@name\tRegionScreenshotRequest\n\ntype CompressedScreenshotRequest struct {\n\tShowCursor bool    `json:\"showCursor\"`\n\tFormat     string  `json:\"format\"`  // \"png\" or \"jpeg\"\n\tQuality    int     `json:\"quality\"` // 1-100 for JPEG quality\n\tScale      float64 `json:\"scale\"`   // 0.1-1.0 for scaling down\n} //\t@name\tCompressedScreenshotRequest\n\ntype CompressedRegionScreenshotRequest struct {\n\tPosition\n\tSize\n\tShowCursor bool    `json:\"showCursor\"`\n\tFormat     string  `json:\"format\"`  // \"png\" or \"jpeg\"\n\tQuality    int     `json:\"quality\"` // 1-100 for JPEG quality\n\tScale      float64 `json:\"scale\"`   // 0.1-1.0 for scaling down\n} //\t@name\tCompressedRegionScreenshotRequest\n\n// Mouse parameter structs\ntype MouseMoveRequest struct {\n\tPosition\n} //\t@name\tMouseMoveRequest\n\ntype MouseClickRequest struct {\n\tPosition\n\tButton string `json:\"button\"` // left, right, middle\n\tDouble bool   `json:\"double\"`\n} //\t@name\tMouseClickRequest\n\ntype MouseDragRequest struct {\n\tStartX int    `json:\"startX\"`\n\tStartY int    `json:\"startY\"`\n\tEndX   int    `json:\"endX\"`\n\tEndY   int    `json:\"endY\"`\n\tButton string `json:\"button\"`\n} //\t@name\tMouseDragRequest\n\ntype MouseScrollRequest struct {\n\tPosition\n\tDirection string `json:\"direction\"` // up, down\n\tAmount    int    `json:\"amount\"`\n} //\t@name\tMouseScrollRequest\n\n// Keyboard parameter structs\ntype KeyboardTypeRequest struct {\n\tText  string `json:\"text\"`\n\tDelay int    `json:\"delay\"` // milliseconds between keystrokes\n} //\t@name\tKeyboardTypeRequest\n\ntype KeyboardPressRequest struct {\n\tKey       string   `json:\"key\"`\n\tModifiers []string `json:\"modifiers\"` // ctrl, alt, shift, cmd\n} //\t@name\tKeyboardPressRequest\n\ntype KeyboardHotkeyRequest struct {\n\tKeys string `json:\"keys\"` // e.g., \"ctrl+c\", \"cmd+v\"\n} //\t@name\tKeyboardHotkeyRequest\n\n// Response structs for keyboard operations\ntype ScrollResponse struct {\n\tSuccess bool `json:\"success\"`\n} //\t@name\tScrollResponse\n\n// Response structs\ntype ScreenshotResponse struct {\n\tScreenshot     string    `json:\"screenshot\"`\n\tCursorPosition *Position `json:\"cursorPosition,omitempty\"`\n\tSizeBytes      int       `json:\"sizeBytes,omitempty\"`\n} //\t@name\tScreenshotResponse\n\n// Mouse response structs - separated by operation type\ntype MousePositionResponse struct {\n\tPosition\n} //\t@name\tMousePositionResponse\n\ntype MouseClickResponse struct {\n\tPosition\n} //\t@name\tMouseClickResponse\n\ntype MouseDragResponse struct {\n\tPosition // Final position\n} //\t@name\tMouseDragResponse\n\ntype DisplayInfoResponse struct {\n\tDisplays []DisplayInfo `json:\"displays\"`\n} //\t@name\tDisplayInfoResponse\n\ntype DisplayInfo struct {\n\tID int `json:\"id\"`\n\tPosition\n\tSize\n\tIsActive bool `json:\"isActive\"`\n} //\t@name\tDisplayInfo\n\ntype WindowsResponse struct {\n\tWindows []WindowInfo `json:\"windows\"`\n} //\t@name\tWindowsResponse\n\ntype WindowInfo struct {\n\tID    int    `json:\"id\"`\n\tTitle string `json:\"title\"`\n\tPosition\n\tSize\n\tIsActive bool `json:\"isActive\"`\n} //\t@name\tWindowInfo\n\ntype ComputerUseStatusResponse struct {\n\tStatus string `json:\"status\"`\n} //\t@name\tComputerUseStatusResponse\n\ntype ComputerUseStartResponse struct {\n\tMessage string                   `json:\"message\"`\n\tStatus  map[string]ProcessStatus `json:\"status\"`\n} //\t@name\tComputerUseStartResponse\n\ntype ComputerUseStopResponse struct {\n\tMessage string                   `json:\"message\"`\n\tStatus  map[string]ProcessStatus `json:\"status\"`\n} //\t@name\tComputerUseStopResponse\n\ntype ProcessStatus struct {\n\tRunning     bool\n\tPriority    int\n\tAutoRestart bool\n\tPid         *int\n} //\t@name\tProcessStatus\n\ntype ProcessStatusResponse struct {\n\tProcessName string `json:\"processName\"`\n\tRunning     bool   `json:\"running\"`\n} //\t@name\tProcessStatusResponse\n\ntype ProcessRestartResponse struct {\n\tMessage     string `json:\"message\"`\n\tProcessName string `json:\"processName\"`\n} //\t@name\tProcessRestartResponse\n\ntype ProcessLogsResponse struct {\n\tProcessName string `json:\"processName\"`\n\tLogs        string `json:\"logs\"`\n} //\t@name\tProcessLogsResponse\n\ntype ProcessErrorsResponse struct {\n\tProcessName string `json:\"processName\"`\n\tErrors      string `json:\"errors\"`\n} //\t@name\tProcessErrorsResponse\n\ntype ProcessRequest struct {\n\tProcessName string\n} //\t@name\tProcessRequest\n\ntype Empty struct{} //\t@name\tEmpty\n\nfunc (p *ComputerUsePlugin) Server(*plugin.MuxBroker) (any, error) {\n\treturn &ComputerUseRPCServer{Impl: p.Impl}, nil\n}\n\nfunc (p *ComputerUsePlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (any, error) {\n\treturn &ComputerUseRPCClient{client: c}, nil\n}\n\n// TakeScreenshot godoc\n//\n//\t@Summary\t\tTake a screenshot\n//\t@Description\tTake a screenshot of the entire screen\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tshowCursor\tquery\t\tbool\tfalse\t\"Whether to show cursor in screenshot\"\n//\t@Success\t\t200\t\t\t{object}\tScreenshotResponse\n//\t@Router\t\t\t/computeruse/screenshot [get]\n//\n//\t@id\t\t\t\tTakeScreenshot\nfunc WrapScreenshotHandler(fn func(*ScreenshotRequest) (*ScreenshotResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\treq := &ScreenshotRequest{\n\t\t\tShowCursor: c.Query(\"showCursor\") == \"true\",\n\t\t}\n\t\tresponse, err := fn(req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// TakeRegionScreenshot godoc\n//\n//\t@Summary\t\tTake a region screenshot\n//\t@Description\tTake a screenshot of a specific region of the screen\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tx\t\t\tquery\t\tint\t\ttrue\t\"X coordinate of the region\"\n//\t@Param\t\t\ty\t\t\tquery\t\tint\t\ttrue\t\"Y coordinate of the region\"\n//\t@Param\t\t\twidth\t\tquery\t\tint\t\ttrue\t\"Width of the region\"\n//\t@Param\t\t\theight\t\tquery\t\tint\t\ttrue\t\"Height of the region\"\n//\t@Param\t\t\tshowCursor\tquery\t\tbool\tfalse\t\"Whether to show cursor in screenshot\"\n//\t@Success\t\t200\t\t\t{object}\tScreenshotResponse\n//\t@Router\t\t\t/computeruse/screenshot/region [get]\n//\n//\t@id\t\t\t\tTakeRegionScreenshot\nfunc WrapRegionScreenshotHandler(fn func(*RegionScreenshotRequest) (*ScreenshotResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req RegionScreenshotRequest\n\t\tif err := c.ShouldBindQuery(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid parameters\"})\n\t\t\treturn\n\t\t}\n\t\treq.ShowCursor = c.Query(\"showCursor\") == \"true\"\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// TakeCompressedScreenshot godoc\n//\n//\t@Summary\t\tTake a compressed screenshot\n//\t@Description\tTake a compressed screenshot of the entire screen\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tshowCursor\tquery\t\tbool\tfalse\t\"Whether to show cursor in screenshot\"\n//\t@Param\t\t\tformat\t\tquery\t\tstring\tfalse\t\"Image format (png or jpeg)\"\n//\t@Param\t\t\tquality\t\tquery\t\tint\t\tfalse\t\"JPEG quality (1-100)\"\n//\t@Param\t\t\tscale\t\tquery\t\tfloat64\tfalse\t\"Scale factor (0.1-1.0)\"\n//\t@Success\t\t200\t\t\t{object}\tScreenshotResponse\n//\t@Router\t\t\t/computeruse/screenshot/compressed [get]\n//\n//\t@id\t\t\t\tTakeCompressedScreenshot\nfunc WrapCompressedScreenshotHandler(fn func(*CompressedScreenshotRequest) (*ScreenshotResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\treq := &CompressedScreenshotRequest{\n\t\t\tShowCursor: c.Query(\"showCursor\") == \"true\",\n\t\t\tFormat:     c.Query(\"format\"),\n\t\t\tQuality:    85,\n\t\t\tScale:      1.0,\n\t\t}\n\n\t\t// Parse quality\n\t\tif qualityStr := c.Query(\"quality\"); qualityStr != \"\" {\n\t\t\tif quality, err := strconv.Atoi(qualityStr); err == nil && quality >= 1 && quality <= 100 {\n\t\t\t\treq.Quality = quality\n\t\t\t}\n\t\t}\n\n\t\t// Parse scale\n\t\tif scaleStr := c.Query(\"scale\"); scaleStr != \"\" {\n\t\t\tif scale, err := strconv.ParseFloat(scaleStr, 64); err == nil && scale >= 0.1 && scale <= 1.0 {\n\t\t\t\treq.Scale = scale\n\t\t\t}\n\t\t}\n\n\t\tresponse, err := fn(req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// TakeCompressedRegionScreenshot godoc\n//\n//\t@Summary\t\tTake a compressed region screenshot\n//\t@Description\tTake a compressed screenshot of a specific region of the screen\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tx\t\t\tquery\t\tint\t\ttrue\t\"X coordinate of the region\"\n//\t@Param\t\t\ty\t\t\tquery\t\tint\t\ttrue\t\"Y coordinate of the region\"\n//\t@Param\t\t\twidth\t\tquery\t\tint\t\ttrue\t\"Width of the region\"\n//\t@Param\t\t\theight\t\tquery\t\tint\t\ttrue\t\"Height of the region\"\n//\t@Param\t\t\tshowCursor\tquery\t\tbool\tfalse\t\"Whether to show cursor in screenshot\"\n//\t@Param\t\t\tformat\t\tquery\t\tstring\tfalse\t\"Image format (png or jpeg)\"\n//\t@Param\t\t\tquality\t\tquery\t\tint\t\tfalse\t\"JPEG quality (1-100)\"\n//\t@Param\t\t\tscale\t\tquery\t\tfloat64\tfalse\t\"Scale factor (0.1-1.0)\"\n//\t@Success\t\t200\t\t\t{object}\tScreenshotResponse\n//\t@Router\t\t\t/computeruse/screenshot/region/compressed [get]\n//\n//\t@id\t\t\t\tTakeCompressedRegionScreenshot\nfunc WrapCompressedRegionScreenshotHandler(fn func(*CompressedRegionScreenshotRequest) (*ScreenshotResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req CompressedRegionScreenshotRequest\n\t\tif err := c.ShouldBindQuery(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid parameters\"})\n\t\t\treturn\n\t\t}\n\t\treq.ShowCursor = c.Query(\"showCursor\") == \"true\"\n\t\treq.Format = c.Query(\"format\")\n\t\treq.Quality = 85\n\t\treq.Scale = 1.0\n\n\t\t// Parse quality\n\t\tif qualityStr := c.Query(\"quality\"); qualityStr != \"\" {\n\t\t\tif quality, err := strconv.Atoi(qualityStr); err == nil && quality >= 1 && quality <= 100 {\n\t\t\t\treq.Quality = quality\n\t\t\t}\n\t\t}\n\n\t\t// Parse scale\n\t\tif scaleStr := c.Query(\"scale\"); scaleStr != \"\" {\n\t\t\tif scale, err := strconv.ParseFloat(scaleStr, 64); err == nil && scale >= 0.1 && scale <= 1.0 {\n\t\t\t\treq.Scale = scale\n\t\t\t}\n\t\t}\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// GetMousePosition godoc\n//\n//\t@Summary\t\tGet mouse position\n//\t@Description\tGet the current mouse cursor position\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tMousePositionResponse\n//\t@Router\t\t\t/computeruse/mouse/position [get]\n//\n//\t@id\t\t\t\tGetMousePosition\nfunc WrapMousePositionHandler(fn func() (*MousePositionResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tresponse, err := fn()\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// MoveMouse godoc\n//\n//\t@Summary\t\tMove mouse cursor\n//\t@Description\tMove the mouse cursor to the specified coordinates\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tMouseMoveRequest\ttrue\t\"Mouse move request\"\n//\t@Success\t\t200\t\t{object}\tMousePositionResponse\n//\t@Router\t\t\t/computeruse/mouse/move [post]\n//\n//\t@id\t\t\t\tMoveMouse\nfunc WrapMoveMouseHandler(fn func(*MouseMoveRequest) (*MousePositionResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req MouseMoveRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid coordinates\"})\n\t\t\treturn\n\t\t}\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// Click godoc\n//\n//\t@Summary\t\tClick mouse button\n//\t@Description\tClick the mouse button at the specified coordinates\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tMouseClickRequest\ttrue\t\"Mouse click request\"\n//\t@Success\t\t200\t\t{object}\tMouseClickResponse\n//\t@Router\t\t\t/computeruse/mouse/click [post]\n//\n//\t@id\t\t\t\tClick\nfunc WrapClickHandler(fn func(*MouseClickRequest) (*MouseClickResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req MouseClickRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid click parameters\"})\n\t\t\treturn\n\t\t}\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// Drag godoc\n//\n//\t@Summary\t\tDrag mouse\n//\t@Description\tDrag the mouse from start to end coordinates\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tMouseDragRequest\ttrue\t\"Mouse drag request\"\n//\t@Success\t\t200\t\t{object}\tMouseDragResponse\n//\t@Router\t\t\t/computeruse/mouse/drag [post]\n//\n//\t@id\t\t\t\tDrag\nfunc WrapDragHandler(fn func(*MouseDragRequest) (*MouseDragResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req MouseDragRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid drag parameters\"})\n\t\t\treturn\n\t\t}\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// Scroll godoc\n//\n//\t@Summary\t\tScroll mouse wheel\n//\t@Description\tScroll the mouse wheel at the specified coordinates\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tMouseScrollRequest\ttrue\t\"Mouse scroll request\"\n//\t@Success\t\t200\t\t{object}\tScrollResponse\n//\t@Router\t\t\t/computeruse/mouse/scroll [post]\n//\n//\t@id\t\t\t\tScroll\nfunc WrapScrollHandler(fn func(*MouseScrollRequest) (*ScrollResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req MouseScrollRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid scroll parameters\"})\n\t\t\treturn\n\t\t}\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// TypeText godoc\n//\n//\t@Summary\t\tType text\n//\t@Description\tType text with optional delay between keystrokes\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tKeyboardTypeRequest\ttrue\t\"Text typing request\"\n//\t@Success\t\t200\t\t{object}\tEmpty\n//\t@Router\t\t\t/computeruse/keyboard/type [post]\n//\n//\t@id\t\t\t\tTypeText\nfunc WrapTypeTextHandler(fn func(*KeyboardTypeRequest) (*Empty, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req KeyboardTypeRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid input\"})\n\t\t\treturn\n\t\t}\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// PressKey godoc\n//\n//\t@Summary\t\tPress key\n//\t@Description\tPress a key with optional modifiers\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tKeyboardPressRequest\ttrue\t\"Key press request\"\n//\t@Success\t\t200\t\t{object}\tEmpty\n//\t@Router\t\t\t/computeruse/keyboard/key [post]\n//\n//\t@id\t\t\t\tPressKey\nfunc WrapPressKeyHandler(fn func(*KeyboardPressRequest) (*Empty, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req KeyboardPressRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid key\"})\n\t\t\treturn\n\t\t}\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// PressHotkey godoc\n//\n//\t@Summary\t\tPress hotkey\n//\t@Description\tPress a hotkey combination (e.g., ctrl+c, cmd+v)\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tKeyboardHotkeyRequest\ttrue\t\"Hotkey press request\"\n//\t@Success\t\t200\t\t{object}\tEmpty\n//\t@Router\t\t\t/computeruse/keyboard/hotkey [post]\n//\n//\t@id\t\t\t\tPressHotkey\nfunc WrapPressHotkeyHandler(fn func(*KeyboardHotkeyRequest) (*Empty, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req KeyboardHotkeyRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"Invalid hotkey\"})\n\t\t\treturn\n\t\t}\n\n\t\tresponse, err := fn(&req)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// GetDisplayInfo godoc\n//\n//\t@Summary\t\tGet display information\n//\t@Description\tGet information about all available displays\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tDisplayInfoResponse\n//\t@Router\t\t\t/computeruse/display/info [get]\n//\n//\t@id\t\t\t\tGetDisplayInfo\nfunc WrapDisplayInfoHandler(fn func() (*DisplayInfoResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tresponse, err := fn()\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// GetWindows godoc\n//\n//\t@Summary\t\tGet windows information\n//\t@Description\tGet information about all open windows\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tWindowsResponse\n//\t@Router\t\t\t/computeruse/display/windows [get]\n//\n//\t@id\t\t\t\tGetWindows\nfunc WrapWindowsHandler(fn func() (*WindowsResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tresponse, err := fn()\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n\n// GetStatus godoc\n//\n//\t@Summary\t\tGet computer use status\n//\t@Description\tGet the current status of the computer use system\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tComputerUseStatusResponse\n//\t@Router\t\t\t/computeruse/status [get]\n//\n//\t@id\t\t\t\tGetComputerUseSystemStatus\nfunc WrapStatusHandler(fn func() (*ComputerUseStatusResponse, error)) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tresponse, err := fn()\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\t\treturn\n\t\t}\n\t\tc.JSON(http.StatusOK, response)\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/lazy.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage computeruse\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\t\"sync\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\nvar errNotLoaded = errors.New(\"computer-use plugin is not loaded yet\")\n\n// Compile-time check that LazyComputerUse implements IComputerUse.\nvar _ IComputerUse = &LazyComputerUse{}\n\n// LazyComputerUse is a proxy that implements IComputerUse and delegates to the\n// real implementation once it has been set. Before Set is called, every method\n// returns errNotLoaded.\ntype LazyComputerUse struct {\n\tmu   sync.RWMutex\n\timpl IComputerUse\n}\n\nfunc NewLazyComputerUse() *LazyComputerUse {\n\treturn &LazyComputerUse{}\n}\n\n// Set stores the real implementation. It is safe to call from any goroutine.\nfunc (l *LazyComputerUse) Set(impl IComputerUse) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tl.impl = impl\n}\n\n// IsReady reports whether the real implementation has been loaded.\nfunc (l *LazyComputerUse) IsReady() bool {\n\tl.mu.RLock()\n\tdefer l.mu.RUnlock()\n\treturn l.impl != nil\n}\n\nfunc (l *LazyComputerUse) get() (IComputerUse, error) {\n\tl.mu.RLock()\n\tdefer l.mu.RUnlock()\n\tif l.impl == nil {\n\t\treturn nil, errNotLoaded\n\t}\n\treturn l.impl, nil\n}\n\n// --- IComputerUse implementation ---\n\nfunc (l *LazyComputerUse) Initialize() (*Empty, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.Initialize()\n}\n\nfunc (l *LazyComputerUse) Start() (*Empty, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.Start()\n}\n\nfunc (l *LazyComputerUse) Stop() (*Empty, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.Stop()\n}\n\nfunc (l *LazyComputerUse) GetProcessStatus() (map[string]ProcessStatus, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.GetProcessStatus()\n}\n\nfunc (l *LazyComputerUse) IsProcessRunning(req *ProcessRequest) (bool, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn impl.IsProcessRunning(req)\n}\n\nfunc (l *LazyComputerUse) RestartProcess(req *ProcessRequest) (*Empty, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.RestartProcess(req)\n}\n\nfunc (l *LazyComputerUse) GetProcessLogs(req *ProcessRequest) (string, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn impl.GetProcessLogs(req)\n}\n\nfunc (l *LazyComputerUse) GetProcessErrors(req *ProcessRequest) (string, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn impl.GetProcessErrors(req)\n}\n\nfunc (l *LazyComputerUse) TakeScreenshot(req *ScreenshotRequest) (*ScreenshotResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.TakeScreenshot(req)\n}\n\nfunc (l *LazyComputerUse) TakeRegionScreenshot(req *RegionScreenshotRequest) (*ScreenshotResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.TakeRegionScreenshot(req)\n}\n\nfunc (l *LazyComputerUse) TakeCompressedScreenshot(req *CompressedScreenshotRequest) (*ScreenshotResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.TakeCompressedScreenshot(req)\n}\n\nfunc (l *LazyComputerUse) TakeCompressedRegionScreenshot(req *CompressedRegionScreenshotRequest) (*ScreenshotResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.TakeCompressedRegionScreenshot(req)\n}\n\nfunc (l *LazyComputerUse) GetMousePosition() (*MousePositionResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.GetMousePosition()\n}\n\nfunc (l *LazyComputerUse) MoveMouse(req *MouseMoveRequest) (*MousePositionResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.MoveMouse(req)\n}\n\nfunc (l *LazyComputerUse) Click(req *MouseClickRequest) (*MouseClickResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.Click(req)\n}\n\nfunc (l *LazyComputerUse) Drag(req *MouseDragRequest) (*MouseDragResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.Drag(req)\n}\n\nfunc (l *LazyComputerUse) Scroll(req *MouseScrollRequest) (*ScrollResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.Scroll(req)\n}\n\nfunc (l *LazyComputerUse) TypeText(req *KeyboardTypeRequest) (*Empty, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.TypeText(req)\n}\n\nfunc (l *LazyComputerUse) PressKey(req *KeyboardPressRequest) (*Empty, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.PressKey(req)\n}\n\nfunc (l *LazyComputerUse) PressHotkey(req *KeyboardHotkeyRequest) (*Empty, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.PressHotkey(req)\n}\n\nfunc (l *LazyComputerUse) GetDisplayInfo() (*DisplayInfoResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.GetDisplayInfo()\n}\n\nfunc (l *LazyComputerUse) GetWindows() (*WindowsResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.GetWindows()\n}\n\nfunc (l *LazyComputerUse) GetStatus() (*ComputerUseStatusResponse, error) {\n\timpl, err := l.get()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn impl.GetStatus()\n}\n\n// LazyCheckMiddleware returns 503 if the computer-use plugin has not loaded yet.\nfunc LazyCheckMiddleware(lazy *LazyComputerUse) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tif !lazy.IsReady() {\n\t\t\tc.JSON(http.StatusServiceUnavailable, gin.H{\n\t\t\t\t\"message\":  \"Computer-use functionality is not available\",\n\t\t\t\t\"details\":  \"The computer-use plugin is still loading or failed to initialize.\",\n\t\t\t\t\"solution\": \"Retry shortly. If the problem persists, check the daemon logs for specific error details.\",\n\t\t\t})\n\t\t\tc.Abort()\n\t\t\treturn\n\t\t}\n\t\tc.Next()\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/manager/manager.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage manager\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/daemon/pkg/toolbox/computeruse\"\n\t\"github.com/hashicorp/go-hclog\"\n\t\"github.com/hashicorp/go-plugin\"\n)\n\ntype pluginRef struct {\n\tclient *plugin.Client\n\timpl   computeruse.IComputerUse\n\tpath   string\n}\n\nvar ComputerUseHandshakeConfig = plugin.HandshakeConfig{\n\tProtocolVersion:  1,\n\tMagicCookieKey:   \"DAYTONA_COMPUTER_USE_PLUGIN\",\n\tMagicCookieValue: \"daytona_computer_use\",\n}\n\nvar computerUse = &pluginRef{}\n\n// ComputerUseError represents a computer-use plugin error with context\ntype ComputerUseError struct {\n\tType    string // \"dependency\", \"system\", \"plugin\"\n\tMessage string\n\tDetails string\n}\n\nfunc (e *ComputerUseError) Error() string {\n\treturn e.Message\n}\n\n// detectPluginError tries to execute the plugin binary directly to get detailed error information\nfunc detectPluginError(logger *slog.Logger, path string) *ComputerUseError {\n\t// Try to execute the plugin directly to get error output\n\tcmd := exec.Command(path)\n\n\t// Capture both stdout and stderr\n\tvar stdout, stderr bytes.Buffer\n\tcmd.Stdout = &stdout\n\tcmd.Stderr = &stderr\n\n\t// Execute the command\n\terr := cmd.Run()\n\n\t// Get the combined output\n\toutput := stdout.String() + stderr.String()\n\n\tif err == nil {\n\t\t// Plugin executed successfully, this shouldn't happen in normal flow\n\t\treturn &ComputerUseError{\n\t\t\tType:    \"plugin\",\n\t\t\tMessage: \"Plugin executed successfully but failed during handshake\",\n\t\t\tDetails: \"This may indicate a protocol version mismatch or plugin configuration issue.\",\n\t\t}\n\t}\n\n\t// Get exit code if available\n\texitCode := -1\n\tif exitErr, ok := err.(*exec.ExitError); ok {\n\t\texitCode = exitErr.ExitCode()\n\t}\n\n\t// Log the raw error for debugging\n\tlogger.Debug(\"Plugin execution failed\", \"exitCode\", exitCode, \"error\", err)\n\tlogger.Debug(\"Plugin stdout\", \"stdout\", stdout.String())\n\tlogger.Debug(\"Plugin stderr\", \"stderr\", stderr.String())\n\n\t// Check for missing X11 runtime dependencies\n\tif strings.Contains(output, \"libX11.so.6\") ||\n\t\tstrings.Contains(output, \"libXext.so.6\") ||\n\t\tstrings.Contains(output, \"libXtst.so.6\") ||\n\t\tstrings.Contains(output, \"libXrandr.so.2\") ||\n\t\tstrings.Contains(output, \"libXrender.so.1\") ||\n\t\tstrings.Contains(output, \"libXfixes.so.3\") ||\n\t\tstrings.Contains(output, \"libXss.so.1\") ||\n\t\tstrings.Contains(output, \"libXi.so.6\") ||\n\t\tstrings.Contains(output, \"libXinerama.so.1\") {\n\n\t\tmissingLibs := []string{}\n\t\tif strings.Contains(output, \"libX11.so.6\") {\n\t\t\tmissingLibs = append(missingLibs, \"libX11\")\n\t\t}\n\t\tif strings.Contains(output, \"libXext.so.6\") {\n\t\t\tmissingLibs = append(missingLibs, \"libXext\")\n\t\t}\n\t\tif strings.Contains(output, \"libXtst.so.6\") {\n\t\t\tmissingLibs = append(missingLibs, \"libXtst\")\n\t\t}\n\t\tif strings.Contains(output, \"libXrandr.so.2\") {\n\t\t\tmissingLibs = append(missingLibs, \"libXrandr\")\n\t\t}\n\t\tif strings.Contains(output, \"libXrender.so.1\") {\n\t\t\tmissingLibs = append(missingLibs, \"libXrender\")\n\t\t}\n\t\tif strings.Contains(output, \"libXfixes.so.3\") {\n\t\t\tmissingLibs = append(missingLibs, \"libXfixes\")\n\t\t}\n\t\tif strings.Contains(output, \"libXss.so.1\") {\n\t\t\tmissingLibs = append(missingLibs, \"libXScrnSaver\")\n\t\t}\n\t\tif strings.Contains(output, \"libXi.so.6\") {\n\t\t\tmissingLibs = append(missingLibs, \"libXi\")\n\t\t}\n\t\tif strings.Contains(output, \"libXinerama.so.1\") {\n\t\t\tmissingLibs = append(missingLibs, \"libXinerama\")\n\t\t}\n\n\t\treturn &ComputerUseError{\n\t\t\tType:    \"dependency\",\n\t\t\tMessage: fmt.Sprintf(\"Computer-use plugin requires X11 runtime libraries that are not available (missing: %s)\", strings.Join(missingLibs, \", \")),\n\t\t\tDetails: fmt.Sprintf(`To enable computer-use functionality, install the required dependencies:\n\nFor Ubuntu/Debian:\n  sudo apt-get update && sudo apt-get install -y \\\\\n    libx11-6 libxrandr2 libxext6 libxrender1 libxfixes3 libxss1 libxtst6 libxi6 libxinerama1 \\\\\n    xvfb x11vnc novnc xfce4 xfce4-terminal dbus-x11\n\nFor CentOS/RHEL/Fedora:\n  sudo yum install -y libX11 libXrandr libXext libXrender libXfixes libXScrnSaver libXtst libXi libXinerama \\\\\n    xorg-x11-server-Xvfb x11vnc novnc xfce4 xfce4-terminal dbus-x11\n\nFor Alpine:\n  apk add --no-cache \\\\\n    libx11 libxrandr libxext libxrender libxfixes libxss libxtst libxi libxinerama \\\\\n    xvfb x11vnc novnc xfce4 xfce4-terminal dbus-x11\n\nRaw error output: %s\n\nNote: Computer-use features will be disabled until dependencies are installed.`, output),\n\t\t}\n\t}\n\n\t// Check for missing development libraries (build-time dependencies)\n\tif strings.Contains(output, \"X11/extensions/XTest.h\") ||\n\t\tstrings.Contains(output, \"X11/Xlib.h\") ||\n\t\tstrings.Contains(output, \"X11/Xutil.h\") ||\n\t\tstrings.Contains(output, \"X11/X.h\") {\n\n\t\treturn &ComputerUseError{\n\t\t\tType:    \"dependency\",\n\t\t\tMessage: \"Computer-use plugin requires X11 development libraries\",\n\t\t\tDetails: fmt.Sprintf(`To build computer-use functionality, install the required development dependencies:\n\nFor Ubuntu/Debian:\n  sudo apt-get update && sudo apt-get install -y \\\\\n    libx11-dev libxtst-dev libxext-dev libxrandr-dev libxinerama-dev libxi-dev\n\nFor CentOS/RHEL/Fedora:\n  sudo yum install -y libX11-devel libXtst-devel libXext-devel libXrandr-devel libXinerama-devel libXi-devel\n\nFor Alpine:\n  apk add --no-cache \\\\\n    libx11-dev libxtst-dev libxext-dev libxrandr-dev libxinerama-dev libxi-dev\n\nRaw error output: %s\n\nNote: Computer-use features will be disabled until dependencies are installed.`, output),\n\t\t}\n\t}\n\n\t// Check for permission issues\n\tif strings.Contains(output, \"Permission denied\") ||\n\t\tstrings.Contains(output, \"not executable\") ||\n\t\tstrings.Contains(output, \"EACCES\") {\n\n\t\treturn &ComputerUseError{\n\t\t\tType:    \"system\",\n\t\t\tMessage: \"Computer-use plugin has permission issues\",\n\t\t\tDetails: fmt.Sprintf(\"The plugin at %s is not executable. Please check file permissions and ensure the binary is executable.\\n\\nRaw error output: %s\", path, output),\n\t\t}\n\t}\n\n\t// Check for architecture mismatch\n\tif strings.Contains(output, \"wrong ELF class\") ||\n\t\tstrings.Contains(output, \"architecture\") ||\n\t\tstrings.Contains(output, \"ELF\") ||\n\t\tstrings.Contains(output, \"exec format error\") {\n\n\t\treturn &ComputerUseError{\n\t\t\tType:    \"system\",\n\t\t\tMessage: \"Computer-use plugin architecture mismatch\",\n\t\t\tDetails: fmt.Sprintf(\"The plugin was compiled for a different architecture. Please rebuild the plugin for the current system architecture.\\n\\nRaw error output: %s\", output),\n\t\t}\n\t}\n\n\t// Check for missing system libraries\n\tif strings.Contains(output, \"libc.so\") ||\n\t\tstrings.Contains(output, \"libm.so\") ||\n\t\tstrings.Contains(output, \"libdl.so\") ||\n\t\tstrings.Contains(output, \"libpthread.so\") {\n\n\t\treturn &ComputerUseError{\n\t\t\tType:    \"system\",\n\t\t\tMessage: \"Computer-use plugin requires basic system libraries\",\n\t\t\tDetails: fmt.Sprintf(\"The plugin is missing basic system libraries. This may indicate a corrupted binary or system issue.\\n\\nRaw error output: %s\", output),\n\t\t}\n\t}\n\n\t// Check for file not found\n\tif strings.Contains(output, \"No such file or directory\") ||\n\t\tstrings.Contains(output, \"ENOENT\") {\n\n\t\treturn &ComputerUseError{\n\t\t\tType:    \"system\",\n\t\t\tMessage: \"Computer-use plugin file not found\",\n\t\t\tDetails: fmt.Sprintf(\"The plugin file at %s could not be found or accessed.\\n\\nRaw error output: %s\", path, output),\n\t\t}\n\t}\n\n\t// Check for Go runtime issues\n\tif strings.Contains(output, \"go:\") ||\n\t\tstrings.Contains(output, \"runtime:\") ||\n\t\tstrings.Contains(output, \"panic:\") {\n\n\t\treturn &ComputerUseError{\n\t\t\tType:    \"plugin\",\n\t\t\tMessage: \"Computer-use plugin has Go runtime issues\",\n\t\t\tDetails: fmt.Sprintf(\"The plugin encountered a Go runtime error.\\n\\nRaw error output: %s\", output),\n\t\t}\n\t}\n\n\t// Generic plugin error with full details\n\treturn &ComputerUseError{\n\t\tType:    \"plugin\",\n\t\tMessage: fmt.Sprintf(\"Computer-use plugin failed to start (exit code: %d)\", exitCode),\n\t\tDetails: fmt.Sprintf(\"Error: %v\\nExit Code: %d\\nOutput: %s\", err, exitCode, output),\n\t}\n}\n\nfunc GetComputerUse(logger *slog.Logger, path string) (computeruse.IComputerUse, error) {\n\tif computerUse.impl != nil {\n\t\treturn computerUse.impl, nil\n\t}\n\n\tif _, err := os.Stat(path); os.IsNotExist(err) {\n\t\treturn nil, fmt.Errorf(\"computer-use plugin not found at path: %s\", path)\n\t}\n\n\tpluginName := filepath.Base(path)\n\tpluginBasePath := filepath.Dir(path)\n\n\tif runtime.GOOS == \"windows\" && strings.HasSuffix(path, \".exe\") {\n\t\tpluginName = strings.TrimSuffix(pluginName, \".exe\")\n\t}\n\n\t// Pre-flight check: detect critical issues (missing shared libraries, wrong\n\t// architecture, permission errors) before starting the go-plugin client.\n\t// When the plugin binary exits immediately, go-plugin panics due to a\n\t// WaitGroup race condition in its goroutine, crashing the entire daemon.\n\tpluginErr := detectPluginError(logger, path)\n\tif pluginErr != nil && pluginErr.Type != \"plugin\" {\n\t\treturn nil, fmt.Errorf(\"failed to start computer-use plugin - detailed error\\n[type]: %s - [error]: %s - [details]: %s\", pluginErr.Type, pluginErr.Message, pluginErr.Details)\n\t}\n\n\thclogger := hclog.New(&hclog.LoggerOptions{\n\t\tName: pluginName,\n\t\t// Output: log.New().WriterLevel(log.DebugLevel),\n\t\tOutput: os.Stdout,\n\t\tLevel:  hclog.Debug,\n\t})\n\n\tpluginMap := map[string]plugin.Plugin{}\n\tpluginMap[pluginName] = &computeruse.ComputerUsePlugin{}\n\n\tclient := plugin.NewClient(&plugin.ClientConfig{\n\t\tHandshakeConfig: ComputerUseHandshakeConfig,\n\t\tPlugins:         pluginMap,\n\t\tCmd:             exec.Command(path),\n\t\tLogger:          hclogger,\n\t\tManaged:         true,\n\t})\n\n\tsuccess := false\n\tdefer func() {\n\t\tif !success {\n\t\t\tclient.Kill()\n\t\t}\n\t}()\n\n\tlogger.Info(\"Computer use registered\", \"pluginName\", pluginName)\n\trpcClient, err := client.Client()\n\tif err != nil {\n\t\tpluginErr := detectPluginError(logger, path)\n\t\tif pluginErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get RPC client for computer-use plugin - detailed error\\n[type]: %s - [error]: %s - [details]: %s\", pluginErr.Type, pluginErr.Message, pluginErr.Details)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"failed to get RPC client for computer-use plugin: %w\", err)\n\t}\n\n\traw, err := rpcClient.Dispense(pluginName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to dispense computer-use plugin: %w\", err)\n\t}\n\n\timpl, ok := raw.(computeruse.IComputerUse)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unexpected type from computer-use plugin\")\n\t}\n\n\t_, err = impl.Initialize()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to initialize computer-use plugin: %w\", err)\n\t}\n\n\tsuccess = true\n\tlogger.Info(\"Computer-use plugin initialized successfully\")\n\tcomputerUse.client = client\n\tcomputerUse.impl = impl\n\tcomputerUse.path = pluginBasePath\n\n\treturn impl, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/recording/controller.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"github.com/daytonaio/daemon/pkg/recording\"\n)\n\ntype RecordingController struct {\n\trecordingService *recording.RecordingService\n}\n\nfunc NewRecordingController(recordingService *recording.RecordingService) *RecordingController {\n\treturn &RecordingController{\n\t\trecordingService: recordingService,\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/recording/download.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/daytonaio/daemon/pkg/recording\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// DownloadRecording godoc\n//\n//\t@Summary\t\tDownload a recording\n//\t@Description\tDownload a recording by providing its ID\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\toctet-stream\n//\t@Param\t\t\tid\tpath\t\tstring\ttrue\t\"Recording ID\"\n//\t@Success\t\t200\t{file}\t\tbinary\n//\t@Failure\t\t404\t{object}\tmap[string]string\n//\t@Failure\t\t500\t{object}\tmap[string]string\n//\t@Router\t\t\t/computeruse/recordings/{id}/download [get]\n//\n//\t@id\t\t\t\tDownloadRecording\nfunc (r *RecordingController) DownloadRecording(ctx *gin.Context) {\n\tid := ctx.Param(\"id\")\n\n\trec, err := r.recordingService.GetRecording(id)\n\tif err != nil {\n\t\tif errors.Is(err, recording.ErrRecordingNotFound) {\n\t\t\tctx.JSON(http.StatusNotFound, gin.H{\"error\": \"recording not found\"})\n\t\t\treturn\n\t\t}\n\t\tctx.JSON(http.StatusInternalServerError, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\tif _, err := os.Stat(rec.FilePath); os.IsNotExist(err) {\n\t\tctx.JSON(http.StatusNotFound, gin.H{\"error\": \"file not found\"})\n\t\treturn\n\t}\n\n\tctx.File(rec.FilePath)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/recording/recording.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\trecordingservice \"github.com/daytonaio/daemon/pkg/recording\"\n)\n\n// ListRecordings godoc\n//\n//\t@Summary\t\tList all recordings\n//\t@Description\tGet a list of all recordings (active and completed)\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tListRecordingsResponse\n//\t@Failure\t\t500\t{object}\tmap[string]string\n//\t@Router\t\t\t/computeruse/recordings [get]\n//\n//\t@id\t\t\t\tListRecordings\nfunc (r *RecordingController) ListRecordings(ctx *gin.Context) {\n\trecordings, err := r.recordingService.ListRecordings()\n\tif err != nil {\n\t\tctx.JSON(http.StatusInternalServerError, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\trecordingDTOs := make([]RecordingDTO, 0, len(recordings))\n\tfor _, rec := range recordings {\n\t\trecordingDTOs = append(recordingDTOs, *RecordingToDTO(&rec))\n\t}\n\n\tresponse := ListRecordingsResponse{\n\t\tRecordings: recordingDTOs,\n\t}\n\n\tctx.JSON(http.StatusOK, response)\n}\n\n// GetRecording godoc\n//\n//\t@Summary\t\tGet recording details\n//\t@Description\tGet details of a specific recording by ID\n//\t@Tags\t\t\tcomputer-use\n//\t@Produce\t\tjson\n//\t@Param\t\t\tid\tpath\t\tstring\ttrue\t\"Recording ID\"\n//\t@Success\t\t200\t{object}\tRecordingDTO\n//\t@Failure\t\t404\t{object}\tmap[string]string\n//\t@Failure\t\t500\t{object}\tmap[string]string\n//\t@Router\t\t\t/computeruse/recordings/{id} [get]\n//\n//\t@id\t\t\t\tGetRecording\nfunc (r *RecordingController) GetRecording(ctx *gin.Context) {\n\tid := ctx.Param(\"id\")\n\tif id == \"\" {\n\t\tctx.JSON(http.StatusBadRequest, gin.H{\"error\": \"id is required\"})\n\t\treturn\n\t}\n\n\trecording, err := r.recordingService.GetRecording(id)\n\tif err != nil {\n\t\tif errors.Is(err, recordingservice.ErrRecordingNotFound) {\n\t\t\tctx.JSON(http.StatusNotFound, gin.H{\"error\": \"recording not found\"})\n\t\t\treturn\n\t\t}\n\t\tctx.JSON(http.StatusInternalServerError, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, *RecordingToDTO(recording))\n}\n\n// DeleteRecording godoc\n//\n//\t@Summary\t\tDelete a recording\n//\t@Description\tDelete a recording file by ID\n//\t@Tags\t\t\tcomputer-use\n//\t@Param\t\t\tid\tpath\tstring\ttrue\t\"Recording ID\"\n//\t@Success\t\t204\n//\t@Failure\t\t400\t{object}\tmap[string]string\n//\t@Failure\t\t404\t{object}\tmap[string]string\n//\t@Failure\t\t500\t{object}\tmap[string]string\n//\t@Router\t\t\t/computeruse/recordings/{id} [delete]\n//\n//\t@id\t\t\t\tDeleteRecording\nfunc (r *RecordingController) DeleteRecording(ctx *gin.Context) {\n\tid := ctx.Param(\"id\")\n\tif id == \"\" {\n\t\tctx.JSON(http.StatusBadRequest, gin.H{\"error\": \"id is required\"})\n\t\treturn\n\t}\n\n\terr := r.recordingService.DeleteRecording(id)\n\tif err != nil {\n\t\tif errors.Is(err, recordingservice.ErrRecordingNotFound) {\n\t\t\tctx.JSON(http.StatusNotFound, gin.H{\"error\": \"recording not found\"})\n\t\t\treturn\n\t\t}\n\t\tif errors.Is(err, recordingservice.ErrRecordingStillActive) {\n\t\t\tctx.JSON(http.StatusBadRequest, gin.H{\"error\": \"cannot delete an active recording, stop it first\"})\n\t\t\treturn\n\t\t}\n\t\tctx.JSON(http.StatusInternalServerError, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\tctx.Status(http.StatusNoContent)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/recording/start.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\trecordingservice \"github.com/daytonaio/daemon/pkg/recording\"\n)\n\n// StartRecording godoc\n//\n//\t@Summary\t\tStart a new recording\n//\t@Description\tStart a new screen recording session\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tStartRecordingRequest\tfalse\t\"Recording options\"\n//\t@Success\t\t201\t\t{object}\tRecordingDTO\n//\t@Failure\t\t400\t\t{object}\tmap[string]string\n//\t@Failure\t\t500\t\t{object}\tmap[string]string\n//\t@Router\t\t\t/computeruse/recordings/start [post]\n//\n//\t@id\t\t\t\tStartRecording\nfunc (h *RecordingController) StartRecording(ctx *gin.Context) {\n\tvar request StartRecordingRequest\n\tif err := ctx.ShouldBindJSON(&request); err != nil {\n\t\t// Allow empty body - label is optional\n\t\trequest = StartRecordingRequest{}\n\t}\n\n\trecording, err := h.recordingService.StartRecording(request.Label)\n\tif err != nil {\n\t\tif errors.Is(err, recordingservice.ErrFFmpegNotFound) {\n\t\t\tctx.JSON(http.StatusBadRequest, gin.H{\n\t\t\t\t\"error\":   \"ffmpeg_not_found\",\n\t\t\t\t\"message\": \"FFmpeg must be installed and available in PATH to use screen recording\",\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tif errors.Is(err, recordingservice.ErrInvalidLabel) {\n\t\t\tctx.JSON(http.StatusBadRequest, gin.H{\n\t\t\t\t\"error\":   \"invalid_label\",\n\t\t\t\t\"message\": err.Error(),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tctx.JSON(http.StatusInternalServerError, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusCreated, *RecordingToDTO(recording))\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/recording/stop.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\trecordingservice \"github.com/daytonaio/daemon/pkg/recording\"\n)\n\n// StopRecording godoc\n//\n//\t@Summary\t\tStop a recording\n//\t@Description\tStop an active screen recording session\n//\t@Tags\t\t\tcomputer-use\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tStopRecordingRequest\ttrue\t\"Recording ID to stop\"\n//\t@Success\t\t200\t\t{object}\tRecordingDTO\n//\t@Failure\t\t400\t\t{object}\tmap[string]string\n//\t@Failure\t\t404\t\t{object}\tmap[string]string\n//\t@Router\t\t\t/computeruse/recordings/stop [post]\n//\n//\t@id\t\t\t\tStopRecording\nfunc (r *RecordingController) StopRecording(ctx *gin.Context) {\n\tvar request StopRecordingRequest\n\tif err := ctx.ShouldBindJSON(&request); err != nil {\n\t\tctx.JSON(http.StatusBadRequest, gin.H{\"error\": \"invalid request: id is required\"})\n\t\treturn\n\t}\n\n\tif request.ID == \"\" {\n\t\tctx.JSON(http.StatusBadRequest, gin.H{\"error\": \"id is required\"})\n\t\treturn\n\t}\n\n\trecording, err := r.recordingService.StopRecording(request.ID)\n\tif err != nil {\n\t\tif errors.Is(err, recordingservice.ErrRecordingNotFound) {\n\t\t\tctx.JSON(http.StatusNotFound, gin.H{\"error\": \"recording not found\"})\n\t\t\treturn\n\t\t}\n\t\tctx.JSON(http.StatusInternalServerError, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, *RecordingToDTO(recording))\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/recording/types.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage recording\n\nimport (\n\t\"time\"\n\n\t\"github.com/daytonaio/daemon/pkg/recording\"\n)\n\n// Recording represents a recording session (active or completed)\ntype RecordingDTO struct {\n\tID              string     `json:\"id\" validate:\"required\"`\n\tFileName        string     `json:\"fileName\" validate:\"required\"`\n\tFilePath        string     `json:\"filePath\" validate:\"required\"`\n\tStartTime       time.Time  `json:\"startTime\" validate:\"required\"`\n\tEndTime         *time.Time `json:\"endTime,omitempty\"`\n\tStatus          string     `json:\"status\" validate:\"required\"`\n\tDurationSeconds *float64   `json:\"durationSeconds,omitempty\"`\n\tSizeBytes       *int64     `json:\"sizeBytes,omitempty\"`\n} // @name Recording\n\n// StartRecordingRequest represents the request to start a new recording\ntype StartRecordingRequest struct {\n\tLabel *string `json:\"label,omitempty\"`\n} // @name StartRecordingRequest\n\n// StopRecordingRequest represents the request to stop an active recording\ntype StopRecordingRequest struct {\n\tID string `json:\"id\" validate:\"required\"`\n} // @name StopRecordingRequest\n\n// ListRecordingsResponse represents the response containing all recordings\ntype ListRecordingsResponse struct {\n\tRecordings []RecordingDTO `json:\"recordings\" validate:\"required\"`\n} // @name ListRecordingsResponse\n\nfunc RecordingToDTO(r *recording.Recording) *RecordingDTO {\n\treturn &RecordingDTO{\n\t\tID:              r.ID,\n\t\tFileName:        r.FileName,\n\t\tFilePath:        r.FilePath,\n\t\tStartTime:       r.StartTime,\n\t\tEndTime:         r.EndTime,\n\t\tStatus:          r.Status,\n\t\tDurationSeconds: r.DurationSeconds,\n\t\tSizeBytes:       r.SizeBytes,\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/rpc_client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage computeruse\n\nimport (\n\t\"net/rpc\"\n)\n\ntype ComputerUseRPCClient struct {\n\tclient *rpc.Client\n}\n\n// Type check\nvar _ IComputerUse = &ComputerUseRPCClient{}\n\n// Process management methods\nfunc (m *ComputerUseRPCClient) Initialize() (*Empty, error) {\n\terr := m.client.Call(\"Plugin.Initialize\", new(any), new(Empty))\n\treturn new(Empty), err\n}\n\nfunc (m *ComputerUseRPCClient) Start() (*Empty, error) {\n\terr := m.client.Call(\"Plugin.Start\", new(any), new(Empty))\n\treturn new(Empty), err\n}\n\nfunc (m *ComputerUseRPCClient) Stop() (*Empty, error) {\n\terr := m.client.Call(\"Plugin.Stop\", new(any), new(Empty))\n\treturn new(Empty), err\n}\n\nfunc (m *ComputerUseRPCClient) GetProcessStatus() (map[string]ProcessStatus, error) {\n\tresp := map[string]ProcessStatus{}\n\terr := m.client.Call(\"Plugin.GetProcessStatus\", new(any), &resp)\n\treturn resp, err\n}\n\nfunc (m *ComputerUseRPCClient) IsProcessRunning(req *ProcessRequest) (bool, error) {\n\tvar resp bool\n\terr := m.client.Call(\"Plugin.IsProcessRunning\", req, &resp)\n\treturn resp, err\n}\n\nfunc (m *ComputerUseRPCClient) RestartProcess(req *ProcessRequest) (*Empty, error) {\n\terr := m.client.Call(\"Plugin.RestartProcess\", req, new(Empty))\n\treturn new(Empty), err\n}\n\nfunc (m *ComputerUseRPCClient) GetProcessLogs(req *ProcessRequest) (string, error) {\n\tvar resp string\n\terr := m.client.Call(\"Plugin.GetProcessLogs\", req, &resp)\n\treturn resp, err\n}\n\nfunc (m *ComputerUseRPCClient) GetProcessErrors(req *ProcessRequest) (string, error) {\n\tvar resp string\n\terr := m.client.Call(\"Plugin.GetProcessErrors\", req, &resp)\n\treturn resp, err\n}\n\n// Screenshot methods\nfunc (m *ComputerUseRPCClient) TakeScreenshot(request *ScreenshotRequest) (*ScreenshotResponse, error) {\n\tvar resp ScreenshotResponse\n\terr := m.client.Call(\"Plugin.TakeScreenshot\", request, &resp)\n\treturn &resp, err\n}\n\nfunc (m *ComputerUseRPCClient) TakeRegionScreenshot(request *RegionScreenshotRequest) (*ScreenshotResponse, error) {\n\tvar resp ScreenshotResponse\n\terr := m.client.Call(\"Plugin.TakeRegionScreenshot\", request, &resp)\n\treturn &resp, err\n}\n\nfunc (m *ComputerUseRPCClient) TakeCompressedScreenshot(request *CompressedScreenshotRequest) (*ScreenshotResponse, error) {\n\tvar resp ScreenshotResponse\n\terr := m.client.Call(\"Plugin.TakeCompressedScreenshot\", request, &resp)\n\treturn &resp, err\n}\n\nfunc (m *ComputerUseRPCClient) TakeCompressedRegionScreenshot(request *CompressedRegionScreenshotRequest) (*ScreenshotResponse, error) {\n\tvar resp ScreenshotResponse\n\terr := m.client.Call(\"Plugin.TakeCompressedRegionScreenshot\", request, &resp)\n\treturn &resp, err\n}\n\n// Mouse control methods\nfunc (m *ComputerUseRPCClient) GetMousePosition() (*MousePositionResponse, error) {\n\tvar resp MousePositionResponse\n\terr := m.client.Call(\"Plugin.GetMousePosition\", new(any), &resp)\n\treturn &resp, err\n}\n\nfunc (m *ComputerUseRPCClient) MoveMouse(request *MouseMoveRequest) (*MousePositionResponse, error) {\n\tvar resp MousePositionResponse\n\terr := m.client.Call(\"Plugin.MoveMouse\", request, &resp)\n\treturn &resp, err\n}\n\nfunc (m *ComputerUseRPCClient) Click(request *MouseClickRequest) (*MouseClickResponse, error) {\n\tvar resp MouseClickResponse\n\terr := m.client.Call(\"Plugin.Click\", request, &resp)\n\treturn &resp, err\n}\n\nfunc (m *ComputerUseRPCClient) Drag(request *MouseDragRequest) (*MouseDragResponse, error) {\n\tvar resp MouseDragResponse\n\terr := m.client.Call(\"Plugin.Drag\", request, &resp)\n\treturn &resp, err\n}\n\nfunc (m *ComputerUseRPCClient) Scroll(request *MouseScrollRequest) (*ScrollResponse, error) {\n\tvar resp ScrollResponse\n\terr := m.client.Call(\"Plugin.Scroll\", request, &resp)\n\treturn &resp, err\n}\n\n// Keyboard control methods\nfunc (m *ComputerUseRPCClient) TypeText(request *KeyboardTypeRequest) (*Empty, error) {\n\terr := m.client.Call(\"Plugin.TypeText\", request, new(Empty))\n\treturn new(Empty), err\n}\n\nfunc (m *ComputerUseRPCClient) PressKey(request *KeyboardPressRequest) (*Empty, error) {\n\terr := m.client.Call(\"Plugin.PressKey\", request, new(Empty))\n\treturn new(Empty), err\n}\n\nfunc (m *ComputerUseRPCClient) PressHotkey(request *KeyboardHotkeyRequest) (*Empty, error) {\n\terr := m.client.Call(\"Plugin.PressHotkey\", request, new(Empty))\n\treturn new(Empty), err\n}\n\n// Display info methods\nfunc (m *ComputerUseRPCClient) GetDisplayInfo() (*DisplayInfoResponse, error) {\n\tvar resp DisplayInfoResponse\n\terr := m.client.Call(\"Plugin.GetDisplayInfo\", new(any), &resp)\n\treturn &resp, err\n}\n\nfunc (m *ComputerUseRPCClient) GetWindows() (*WindowsResponse, error) {\n\tvar resp WindowsResponse\n\terr := m.client.Call(\"Plugin.GetWindows\", new(any), &resp)\n\treturn &resp, err\n}\n\n// Status method\nfunc (m *ComputerUseRPCClient) GetStatus() (*ComputerUseStatusResponse, error) {\n\tvar resp ComputerUseStatusResponse\n\terr := m.client.Call(\"Plugin.GetStatus\", new(any), &resp)\n\treturn &resp, err\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/computeruse/rpc_server.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage computeruse\n\ntype ComputerUseRPCServer struct {\n\tImpl IComputerUse\n}\n\n// Process management methods\nfunc (m *ComputerUseRPCServer) Initialize(arg any, resp *Empty) error {\n\t_, err := m.Impl.Initialize()\n\treturn err\n}\n\nfunc (m *ComputerUseRPCServer) Start(arg any, resp *Empty) error {\n\t_, err := m.Impl.Start()\n\treturn err\n}\n\nfunc (m *ComputerUseRPCServer) Stop(arg any, resp *Empty) error {\n\t_, err := m.Impl.Stop()\n\treturn err\n}\n\nfunc (m *ComputerUseRPCServer) GetProcessStatus(arg any, resp *map[string]ProcessStatus) error {\n\tstatus, err := m.Impl.GetProcessStatus()\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = status\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) IsProcessRunning(arg *ProcessRequest, resp *bool) error {\n\tisRunning, err := m.Impl.IsProcessRunning(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = isRunning\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) RestartProcess(arg *ProcessRequest, resp *Empty) error {\n\t_, err := m.Impl.RestartProcess(arg)\n\treturn err\n}\n\nfunc (m *ComputerUseRPCServer) GetProcessLogs(arg *ProcessRequest, resp *string) error {\n\tlogs, err := m.Impl.GetProcessLogs(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = logs\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) GetProcessErrors(arg *ProcessRequest, resp *string) error {\n\terrors, err := m.Impl.GetProcessErrors(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = errors\n\treturn nil\n}\n\n// Screenshot methods\nfunc (m *ComputerUseRPCServer) TakeScreenshot(arg *ScreenshotRequest, resp *ScreenshotResponse) error {\n\tresponse, err := m.Impl.TakeScreenshot(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) TakeRegionScreenshot(arg *RegionScreenshotRequest, resp *ScreenshotResponse) error {\n\tresponse, err := m.Impl.TakeRegionScreenshot(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) TakeCompressedScreenshot(arg *CompressedScreenshotRequest, resp *ScreenshotResponse) error {\n\tresponse, err := m.Impl.TakeCompressedScreenshot(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) TakeCompressedRegionScreenshot(arg *CompressedRegionScreenshotRequest, resp *ScreenshotResponse) error {\n\tresponse, err := m.Impl.TakeCompressedRegionScreenshot(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\n// Mouse control methods\nfunc (m *ComputerUseRPCServer) GetMousePosition(arg any, resp *MousePositionResponse) error {\n\tresponse, err := m.Impl.GetMousePosition()\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) MoveMouse(arg *MouseMoveRequest, resp *MousePositionResponse) error {\n\tresponse, err := m.Impl.MoveMouse(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) Click(arg *MouseClickRequest, resp *MouseClickResponse) error {\n\tresponse, err := m.Impl.Click(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) Drag(arg *MouseDragRequest, resp *MouseDragResponse) error {\n\tresponse, err := m.Impl.Drag(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) Scroll(arg *MouseScrollRequest, resp *ScrollResponse) error {\n\tresponse, err := m.Impl.Scroll(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\n// Keyboard control methods\nfunc (m *ComputerUseRPCServer) TypeText(arg *KeyboardTypeRequest, resp *Empty) error {\n\t_, err := m.Impl.TypeText(arg)\n\treturn err\n}\n\nfunc (m *ComputerUseRPCServer) PressKey(arg *KeyboardPressRequest, resp *Empty) error {\n\t_, err := m.Impl.PressKey(arg)\n\treturn err\n}\n\nfunc (m *ComputerUseRPCServer) PressHotkey(arg *KeyboardHotkeyRequest, resp *Empty) error {\n\t_, err := m.Impl.PressHotkey(arg)\n\treturn err\n}\n\n// Display info methods\nfunc (m *ComputerUseRPCServer) GetDisplayInfo(arg any, resp *DisplayInfoResponse) error {\n\tresponse, err := m.Impl.GetDisplayInfo()\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\nfunc (m *ComputerUseRPCServer) GetWindows(arg any, resp *WindowsResponse) error {\n\tresponse, err := m.Impl.GetWindows()\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n\n// Status method\nfunc (m *ComputerUseRPCServer) GetStatus(arg any, resp *ComputerUseStatusResponse) error {\n\tresponse, err := m.Impl.GetStatus()\n\tif err != nil {\n\t\treturn err\n\t}\n\t*resp = *response\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/config/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage config\n\nconst TOOLBOX_API_PORT = 2280\nconst RECORDING_DASHBOARD_PORT = 33333\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/controller.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage toolbox\n\nimport (\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/daytonaio/daemon/internal\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// Initialize godoc\n//\n//\t@Summary\t\tInitialize toolbox server\n//\t@Description\tSet the auth token and initialize telemetry for the toolbox server\n//\t@Tags\t\t\tserver\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tInitializeRequest\ttrue\t\"Initialization request\"\n//\t@Success\t\t200\t\t{object}\tmap[string]string\n//\t@Router\t\t\t/init [post]\n//\n//\t@id\t\t\t\tInitialize\nfunc (s *server) Initialize(otelServiceName string, entrypointLogFilePath string, organizationId, regionId *string) gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tvar req InitializeRequest\n\t\tif err := ctx.ShouldBindJSON(&req); err != nil {\n\t\t\tctx.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\n\t\ts.authToken = req.Token\n\n\t\terr := s.initTelemetry(ctx.Request.Context(), otelServiceName, entrypointLogFilePath, organizationId, regionId)\n\t\tif err != nil {\n\t\t\tctx.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\n\t\tctx.JSON(http.StatusOK, gin.H{\n\t\t\t\"message\": \"Auth token set and telemetry initialized successfully\",\n\t\t})\n\t}\n}\n\n// GetWorkDir godoc\n//\n//\t@Summary\t\tGet working directory\n//\t@Description\tGet the current working directory path. This is default directory used for running commands.\n//\t@Tags\t\t\tinfo\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tWorkDirResponse\n//\t@Router\t\t\t/work-dir [get]\n//\n//\t@id\t\t\t\tGetWorkDir\nfunc (s *server) GetWorkDir(ctx *gin.Context) {\n\tworkDir := WorkDirResponse{\n\t\tDir: s.WorkDir,\n\t}\n\n\tctx.JSON(http.StatusOK, workDir)\n}\n\n// GetUserHomeDir godoc\n//\n//\t@Summary\t\tGet user home directory\n//\t@Description\tGet the current user home directory path.\n//\t@Tags\t\t\tinfo\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tUserHomeDirResponse\n//\t@Router\t\t\t/user-home-dir [get]\n//\n//\t@id\t\t\t\tGetUserHomeDir\nfunc (s *server) GetUserHomeDir(ctx *gin.Context) {\n\tuserHomeDir, err := os.UserHomeDir()\n\tif err != nil {\n\t\tctx.AbortWithError(http.StatusInternalServerError, err)\n\t\treturn\n\t}\n\tuserHomeDirResponse := UserHomeDirResponse{\n\t\tDir: userHomeDir,\n\t}\n\n\tctx.JSON(http.StatusOK, userHomeDirResponse)\n}\n\n// GetVersion godoc\n//\n//\t@Summary\t\tGet version\n//\t@Description\tGet the current daemon version\n//\t@Tags\t\t\tinfo\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tmap[string]string\n//\t@Router\t\t\t/version [get]\n//\n//\t@id\t\t\t\tGetVersion\nfunc (s *server) GetVersion(ctx *gin.Context) {\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"version\": internal.Version,\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/docs/docs.go",
    "content": "// Package docs Code generated by swaggo/swag. DO NOT EDIT\npackage docs\n\nimport \"github.com/swaggo/swag\"\n\nconst docTemplate = `{\n    \"schemes\": {{ marshal .Schemes }},\n    \"swagger\": \"2.0\",\n    \"info\": {\n        \"description\": \"{{escape .Description}}\",\n        \"title\": \"{{.Title}}\",\n        \"contact\": {},\n        \"version\": \"{{.Version}}\"\n    },\n    \"host\": \"{{.Host}}\",\n    \"basePath\": \"{{.BasePath}}\",\n    \"paths\": {\n        \"/computeruse/display/info\": {\n            \"get\": {\n                \"description\": \"Get information about all available displays\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get display information\",\n                \"operationId\": \"GetDisplayInfo\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/DisplayInfoResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/display/windows\": {\n            \"get\": {\n                \"description\": \"Get information about all open windows\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get windows information\",\n                \"operationId\": \"GetWindows\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/WindowsResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/keyboard/hotkey\": {\n            \"post\": {\n                \"description\": \"Press a hotkey combination (e.g., ctrl+c, cmd+v)\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Press hotkey\",\n                \"operationId\": \"PressHotkey\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Hotkey press request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/KeyboardHotkeyRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Empty\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/keyboard/key\": {\n            \"post\": {\n                \"description\": \"Press a key with optional modifiers\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Press key\",\n                \"operationId\": \"PressKey\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Key press request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/KeyboardPressRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Empty\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/keyboard/type\": {\n            \"post\": {\n                \"description\": \"Type text with optional delay between keystrokes\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Type text\",\n                \"operationId\": \"TypeText\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Text typing request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/KeyboardTypeRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Empty\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/mouse/click\": {\n            \"post\": {\n                \"description\": \"Click the mouse button at the specified coordinates\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Click mouse button\",\n                \"operationId\": \"Click\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Mouse click request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/MouseClickRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/MouseClickResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/mouse/drag\": {\n            \"post\": {\n                \"description\": \"Drag the mouse from start to end coordinates\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Drag mouse\",\n                \"operationId\": \"Drag\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Mouse drag request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/MouseDragRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/MouseDragResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/mouse/move\": {\n            \"post\": {\n                \"description\": \"Move the mouse cursor to the specified coordinates\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Move mouse cursor\",\n                \"operationId\": \"MoveMouse\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Mouse move request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/MouseMoveRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/MousePositionResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/mouse/position\": {\n            \"get\": {\n                \"description\": \"Get the current mouse cursor position\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get mouse position\",\n                \"operationId\": \"GetMousePosition\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/MousePositionResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/mouse/scroll\": {\n            \"post\": {\n                \"description\": \"Scroll the mouse wheel at the specified coordinates\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Scroll mouse wheel\",\n                \"operationId\": \"Scroll\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Mouse scroll request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/MouseScrollRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ScrollResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/process-status\": {\n            \"get\": {\n                \"description\": \"Get the status of all computer use processes\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get computer use process status\",\n                \"operationId\": \"GetComputerUseStatus\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ComputerUseStatusResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/process/{processName}/errors\": {\n            \"get\": {\n                \"description\": \"Get errors for a specific computer use process\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get process errors\",\n                \"operationId\": \"GetProcessErrors\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Process name to get errors for\",\n                        \"name\": \"processName\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ProcessErrorsResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/process/{processName}/logs\": {\n            \"get\": {\n                \"description\": \"Get logs for a specific computer use process\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get process logs\",\n                \"operationId\": \"GetProcessLogs\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Process name to get logs for\",\n                        \"name\": \"processName\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ProcessLogsResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/process/{processName}/restart\": {\n            \"post\": {\n                \"description\": \"Restart a specific computer use process\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Restart specific process\",\n                \"operationId\": \"RestartProcess\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Process name to restart\",\n                        \"name\": \"processName\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ProcessRestartResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/process/{processName}/status\": {\n            \"get\": {\n                \"description\": \"Check if a specific computer use process is running\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get specific process status\",\n                \"operationId\": \"GetProcessStatus\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Process name to check\",\n                        \"name\": \"processName\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ProcessStatusResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/recordings\": {\n            \"get\": {\n                \"description\": \"Get a list of all recordings (active and completed)\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"List all recordings\",\n                \"operationId\": \"ListRecordings\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ListRecordingsResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/recordings/start\": {\n            \"post\": {\n                \"description\": \"Start a new screen recording session\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Start a new recording\",\n                \"operationId\": \"StartRecording\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Recording options\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/StartRecordingRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"201\": {\n                        \"description\": \"Created\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Recording\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/recordings/stop\": {\n            \"post\": {\n                \"description\": \"Stop an active screen recording session\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Stop a recording\",\n                \"operationId\": \"StopRecording\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Recording ID to stop\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/StopRecordingRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Recording\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/recordings/{id}\": {\n            \"get\": {\n                \"description\": \"Get details of a specific recording by ID\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get recording details\",\n                \"operationId\": \"GetRecording\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Recording ID\",\n                        \"name\": \"id\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Recording\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            },\n            \"delete\": {\n                \"description\": \"Delete a recording file by ID\",\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Delete a recording\",\n                \"operationId\": \"DeleteRecording\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Recording ID\",\n                        \"name\": \"id\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"204\": {\n                        \"description\": \"No Content\"\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/recordings/{id}/download\": {\n            \"get\": {\n                \"description\": \"Download a recording by providing its ID\",\n                \"produces\": [\n                    \"application/octet-stream\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Download a recording\",\n                \"operationId\": \"DownloadRecording\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Recording ID\",\n                        \"name\": \"id\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"file\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/screenshot\": {\n            \"get\": {\n                \"description\": \"Take a screenshot of the entire screen\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Take a screenshot\",\n                \"operationId\": \"TakeScreenshot\",\n                \"parameters\": [\n                    {\n                        \"type\": \"boolean\",\n                        \"description\": \"Whether to show cursor in screenshot\",\n                        \"name\": \"showCursor\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ScreenshotResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/screenshot/compressed\": {\n            \"get\": {\n                \"description\": \"Take a compressed screenshot of the entire screen\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Take a compressed screenshot\",\n                \"operationId\": \"TakeCompressedScreenshot\",\n                \"parameters\": [\n                    {\n                        \"type\": \"boolean\",\n                        \"description\": \"Whether to show cursor in screenshot\",\n                        \"name\": \"showCursor\",\n                        \"in\": \"query\"\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Image format (png or jpeg)\",\n                        \"name\": \"format\",\n                        \"in\": \"query\"\n                    },\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"JPEG quality (1-100)\",\n                        \"name\": \"quality\",\n                        \"in\": \"query\"\n                    },\n                    {\n                        \"type\": \"number\",\n                        \"description\": \"Scale factor (0.1-1.0)\",\n                        \"name\": \"scale\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ScreenshotResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/screenshot/region\": {\n            \"get\": {\n                \"description\": \"Take a screenshot of a specific region of the screen\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Take a region screenshot\",\n                \"operationId\": \"TakeRegionScreenshot\",\n                \"parameters\": [\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"X coordinate of the region\",\n                        \"name\": \"x\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"Y coordinate of the region\",\n                        \"name\": \"y\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"Width of the region\",\n                        \"name\": \"width\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"Height of the region\",\n                        \"name\": \"height\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"boolean\",\n                        \"description\": \"Whether to show cursor in screenshot\",\n                        \"name\": \"showCursor\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ScreenshotResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/screenshot/region/compressed\": {\n            \"get\": {\n                \"description\": \"Take a compressed screenshot of a specific region of the screen\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Take a compressed region screenshot\",\n                \"operationId\": \"TakeCompressedRegionScreenshot\",\n                \"parameters\": [\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"X coordinate of the region\",\n                        \"name\": \"x\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"Y coordinate of the region\",\n                        \"name\": \"y\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"Width of the region\",\n                        \"name\": \"width\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"Height of the region\",\n                        \"name\": \"height\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"boolean\",\n                        \"description\": \"Whether to show cursor in screenshot\",\n                        \"name\": \"showCursor\",\n                        \"in\": \"query\"\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Image format (png or jpeg)\",\n                        \"name\": \"format\",\n                        \"in\": \"query\"\n                    },\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"JPEG quality (1-100)\",\n                        \"name\": \"quality\",\n                        \"in\": \"query\"\n                    },\n                    {\n                        \"type\": \"number\",\n                        \"description\": \"Scale factor (0.1-1.0)\",\n                        \"name\": \"scale\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ScreenshotResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/start\": {\n            \"post\": {\n                \"description\": \"Start all computer use processes and return their status\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Start computer use processes\",\n                \"operationId\": \"StartComputerUse\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ComputerUseStartResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/status\": {\n            \"get\": {\n                \"description\": \"Get the current status of the computer use system\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Get computer use status\",\n                \"operationId\": \"GetComputerUseSystemStatus\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ComputerUseStatusResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/computeruse/stop\": {\n            \"post\": {\n                \"description\": \"Stop all computer use processes and return their status\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"computer-use\"\n                ],\n                \"summary\": \"Stop computer use processes\",\n                \"operationId\": \"StopComputerUse\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ComputerUseStopResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/files\": {\n            \"get\": {\n                \"description\": \"List files and directories in the specified path\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"List files and directories\",\n                \"operationId\": \"ListFiles\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Directory path to list (defaults to working directory)\",\n                        \"name\": \"path\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                                \"$ref\": \"#/definitions/FileInfo\"\n                            }\n                        }\n                    }\n                }\n            },\n            \"delete\": {\n                \"description\": \"Delete a file or directory at the specified path\",\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Delete a file or directory\",\n                \"operationId\": \"DeleteFile\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"File or directory path to delete\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"boolean\",\n                        \"description\": \"Enable recursive deletion for directories\",\n                        \"name\": \"recursive\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"204\": {\n                        \"description\": \"No Content\"\n                    }\n                }\n            }\n        },\n        \"/files/bulk-download\": {\n            \"post\": {\n                \"description\": \"Download multiple files by providing their paths\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"multipart/form-data\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Download multiple files\",\n                \"operationId\": \"DownloadFiles\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Paths of files to download\",\n                        \"name\": \"downloadFiles\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/FilesDownloadRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/gin.H\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/files/bulk-upload\": {\n            \"post\": {\n                \"description\": \"Upload multiple files with their destination paths\",\n                \"consumes\": [\n                    \"multipart/form-data\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Upload multiple files\",\n                \"operationId\": \"UploadFiles\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/files/download\": {\n            \"get\": {\n                \"description\": \"Download a file by providing its path\",\n                \"produces\": [\n                    \"application/octet-stream\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Download a file\",\n                \"operationId\": \"DownloadFile\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"File path to download\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"file\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/files/find\": {\n            \"get\": {\n                \"description\": \"Search for text pattern within files in a directory\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Find text in files\",\n                \"operationId\": \"FindInFiles\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Directory path to search in\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Text pattern to search for\",\n                        \"name\": \"pattern\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                                \"$ref\": \"#/definitions/Match\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/files/folder\": {\n            \"post\": {\n                \"description\": \"Create a folder with the specified path and optional permissions\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Create a folder\",\n                \"operationId\": \"CreateFolder\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Folder path to create\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Octal permission mode (default: 0755)\",\n                        \"name\": \"mode\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"201\": {\n                        \"description\": \"Created\"\n                    }\n                }\n            }\n        },\n        \"/files/info\": {\n            \"get\": {\n                \"description\": \"Get detailed information about a file or directory\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Get file information\",\n                \"operationId\": \"GetFileInfo\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"File or directory path\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/FileInfo\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/files/move\": {\n            \"post\": {\n                \"description\": \"Move or rename a file or directory from source to destination\",\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Move or rename file/directory\",\n                \"operationId\": \"MoveFile\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Source file or directory path\",\n                        \"name\": \"source\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Destination file or directory path\",\n                        \"name\": \"destination\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/files/permissions\": {\n            \"post\": {\n                \"description\": \"Set file permissions, ownership, and group for a file or directory\",\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Set file permissions\",\n                \"operationId\": \"SetFilePermissions\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"File or directory path\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Owner (username or UID)\",\n                        \"name\": \"owner\",\n                        \"in\": \"query\"\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Group (group name or GID)\",\n                        \"name\": \"group\",\n                        \"in\": \"query\"\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"File mode in octal format (e.g., 0755)\",\n                        \"name\": \"mode\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/files/replace\": {\n            \"post\": {\n                \"description\": \"Replace text pattern with new value in multiple files\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Replace text in files\",\n                \"operationId\": \"ReplaceInFiles\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Replace request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ReplaceRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                                \"$ref\": \"#/definitions/ReplaceResult\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/files/search\": {\n            \"get\": {\n                \"description\": \"Search for files matching a specific pattern in a directory\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Search files by pattern\",\n                \"operationId\": \"SearchFiles\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Directory path to search in\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"File pattern to match (e.g., *.txt, *.go)\",\n                        \"name\": \"pattern\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SearchFilesResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/files/upload\": {\n            \"post\": {\n                \"description\": \"Upload a file to the specified path\",\n                \"consumes\": [\n                    \"multipart/form-data\"\n                ],\n                \"tags\": [\n                    \"file-system\"\n                ],\n                \"summary\": \"Upload a file\",\n                \"operationId\": \"UploadFile\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Destination path for the uploaded file\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"file\",\n                        \"description\": \"File to upload\",\n                        \"name\": \"file\",\n                        \"in\": \"formData\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/gin.H\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/git/add\": {\n            \"post\": {\n                \"description\": \"Add files to the Git staging area\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Add files to Git staging\",\n                \"operationId\": \"AddFiles\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Add files request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitAddRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/git/branches\": {\n            \"get\": {\n                \"description\": \"Get a list of all branches in the Git repository\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"List branches\",\n                \"operationId\": \"ListBranches\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Repository path\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ListBranchResponse\"\n                        }\n                    }\n                }\n            },\n            \"post\": {\n                \"description\": \"Create a new branch in the Git repository\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Create a new branch\",\n                \"operationId\": \"CreateBranch\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Create branch request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitBranchRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"201\": {\n                        \"description\": \"Created\"\n                    }\n                }\n            },\n            \"delete\": {\n                \"description\": \"Delete a branch from the Git repository\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Delete a branch\",\n                \"operationId\": \"DeleteBranch\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Delete branch request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/git.GitDeleteBranchRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"204\": {\n                        \"description\": \"No Content\"\n                    }\n                }\n            }\n        },\n        \"/git/checkout\": {\n            \"post\": {\n                \"description\": \"Switch to a different branch or commit in the Git repository\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Checkout branch or commit\",\n                \"operationId\": \"CheckoutBranch\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Checkout request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitCheckoutRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/git/clone\": {\n            \"post\": {\n                \"description\": \"Clone a Git repository to the specified path\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Clone a Git repository\",\n                \"operationId\": \"CloneRepository\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Clone repository request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitCloneRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/git/commit\": {\n            \"post\": {\n                \"description\": \"Commit staged changes to the Git repository\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Commit changes\",\n                \"operationId\": \"CommitChanges\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Commit request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitCommitRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitCommitResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/git/history\": {\n            \"get\": {\n                \"description\": \"Get the commit history of the Git repository\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Get commit history\",\n                \"operationId\": \"GetCommitHistory\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Repository path\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                                \"$ref\": \"#/definitions/GitCommitInfo\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/git/pull\": {\n            \"post\": {\n                \"description\": \"Pull changes from the remote Git repository\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Pull changes from remote\",\n                \"operationId\": \"PullChanges\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Pull request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitRepoRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/git/push\": {\n            \"post\": {\n                \"description\": \"Push local changes to the remote Git repository\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Push changes to remote\",\n                \"operationId\": \"PushChanges\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Push request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitRepoRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/git/status\": {\n            \"get\": {\n                \"description\": \"Get the Git status of the repository at the specified path\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"git\"\n                ],\n                \"summary\": \"Get Git status\",\n                \"operationId\": \"GetStatus\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Repository path\",\n                        \"name\": \"path\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/GitStatus\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/init\": {\n            \"post\": {\n                \"description\": \"Set the auth token and initialize telemetry for the toolbox server\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"server\"\n                ],\n                \"summary\": \"Initialize toolbox server\",\n                \"operationId\": \"Initialize\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Initialization request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/InitializeRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/lsp/completions\": {\n            \"post\": {\n                \"description\": \"Get code completion suggestions from the LSP server\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"lsp\"\n                ],\n                \"summary\": \"Get code completions\",\n                \"operationId\": \"Completions\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Completion request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/LspCompletionParams\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/CompletionList\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/lsp/did-close\": {\n            \"post\": {\n                \"description\": \"Notify the LSP server that a document has been closed\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"lsp\"\n                ],\n                \"summary\": \"Notify document closed\",\n                \"operationId\": \"DidClose\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Document request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/LspDocumentRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/lsp/did-open\": {\n            \"post\": {\n                \"description\": \"Notify the LSP server that a document has been opened\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"lsp\"\n                ],\n                \"summary\": \"Notify document opened\",\n                \"operationId\": \"DidOpen\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Document request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/LspDocumentRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/lsp/document-symbols\": {\n            \"get\": {\n                \"description\": \"Get symbols (functions, classes, etc.) from a document\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"lsp\"\n                ],\n                \"summary\": \"Get document symbols\",\n                \"operationId\": \"DocumentSymbols\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Language ID (e.g., python, typescript)\",\n                        \"name\": \"languageId\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Path to project\",\n                        \"name\": \"pathToProject\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Document URI\",\n                        \"name\": \"uri\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                                \"$ref\": \"#/definitions/LspSymbol\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/lsp/start\": {\n            \"post\": {\n                \"description\": \"Start a Language Server Protocol server for the specified language\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"lsp\"\n                ],\n                \"summary\": \"Start LSP server\",\n                \"operationId\": \"Start\",\n                \"parameters\": [\n                    {\n                        \"description\": \"LSP server request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/LspServerRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/lsp/stop\": {\n            \"post\": {\n                \"description\": \"Stop a Language Server Protocol server\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"lsp\"\n                ],\n                \"summary\": \"Stop LSP server\",\n                \"operationId\": \"Stop\",\n                \"parameters\": [\n                    {\n                        \"description\": \"LSP server request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/LspServerRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\"\n                    }\n                }\n            }\n        },\n        \"/lsp/workspacesymbols\": {\n            \"get\": {\n                \"description\": \"Search for symbols across the entire workspace\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"lsp\"\n                ],\n                \"summary\": \"Get workspace symbols\",\n                \"operationId\": \"WorkspaceSymbols\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Search query\",\n                        \"name\": \"query\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Language ID (e.g., python, typescript)\",\n                        \"name\": \"languageId\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Path to project\",\n                        \"name\": \"pathToProject\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                                \"$ref\": \"#/definitions/LspSymbol\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/port\": {\n            \"get\": {\n                \"description\": \"Get a list of all currently active ports\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"port\"\n                ],\n                \"summary\": \"Get active ports\",\n                \"operationId\": \"GetPorts\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/PortList\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/port/{port}/in-use\": {\n            \"get\": {\n                \"description\": \"Check if a specific port is currently in use\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"port\"\n                ],\n                \"summary\": \"Check if port is in use\",\n                \"operationId\": \"IsPortInUse\",\n                \"parameters\": [\n                    {\n                        \"type\": \"integer\",\n                        \"description\": \"Port number (3000-9999)\",\n                        \"name\": \"port\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/IsPortInUseResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/execute\": {\n            \"post\": {\n                \"description\": \"Execute a shell command and return the output and exit code\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Execute a command\",\n                \"operationId\": \"ExecuteCommand\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Command execution request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ExecuteRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ExecuteResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/interpreter/context\": {\n            \"get\": {\n                \"description\": \"Returns information about all user-created interpreter contexts (excludes default context)\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"interpreter\"\n                ],\n                \"summary\": \"List all user-created interpreter contexts\",\n                \"operationId\": \"ListInterpreterContexts\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ListContextsResponse\"\n                        }\n                    }\n                }\n            },\n            \"post\": {\n                \"description\": \"Creates a new isolated interpreter context with optional working directory and language\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"interpreter\"\n                ],\n                \"summary\": \"Create a new interpreter context\",\n                \"operationId\": \"CreateInterpreterContext\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Context configuration\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/CreateContextRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/InterpreterContext\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/interpreter/context/{id}\": {\n            \"delete\": {\n                \"description\": \"Deletes an interpreter context and shuts down its worker process\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"interpreter\"\n                ],\n                \"summary\": \"Delete an interpreter context\",\n                \"operationId\": \"DeleteInterpreterContext\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Context ID\",\n                        \"name\": \"id\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/interpreter/execute\": {\n            \"get\": {\n                \"description\": \"Executes code in a specified context (or default context if not specified) via WebSocket streaming\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"interpreter\"\n                ],\n                \"summary\": \"Execute code in an interpreter context\",\n                \"operationId\": \"ExecuteInterpreterCode\",\n                \"responses\": {\n                    \"101\": {\n                        \"description\": \"Switching Protocols\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        },\n                        \"headers\": {\n                            \"Connection\": {\n                                \"type\": \"string\",\n                                \"description\": \"Upgrade\"\n                            },\n                            \"Upgrade\": {\n                                \"type\": \"string\",\n                                \"description\": \"websocket\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/pty\": {\n            \"get\": {\n                \"description\": \"Get a list of all active pseudo-terminal sessions\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"List all PTY sessions\",\n                \"operationId\": \"ListPtySessions\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/PtyListResponse\"\n                        }\n                    }\n                }\n            },\n            \"post\": {\n                \"description\": \"Create a new pseudo-terminal session with specified configuration\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Create a new PTY session\",\n                \"operationId\": \"CreatePtySession\",\n                \"parameters\": [\n                    {\n                        \"description\": \"PTY session creation request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/PtyCreateRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"201\": {\n                        \"description\": \"Created\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/PtyCreateResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/pty/{sessionId}\": {\n            \"get\": {\n                \"description\": \"Get detailed information about a specific pseudo-terminal session\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Get PTY session information\",\n                \"operationId\": \"GetPtySession\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"PTY session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/PtySessionInfo\"\n                        }\n                    }\n                }\n            },\n            \"delete\": {\n                \"description\": \"Delete a pseudo-terminal session and terminate its process\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Delete a PTY session\",\n                \"operationId\": \"DeletePtySession\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"PTY session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/gin.H\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/pty/{sessionId}/connect\": {\n            \"get\": {\n                \"description\": \"Establish a WebSocket connection to interact with a pseudo-terminal session\",\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Connect to PTY session via WebSocket\",\n                \"operationId\": \"ConnectPtySession\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"PTY session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"101\": {\n                        \"description\": \"Switching Protocols - WebSocket connection established\"\n                    }\n                }\n            }\n        },\n        \"/process/pty/{sessionId}/resize\": {\n            \"post\": {\n                \"description\": \"Resize the terminal dimensions of a pseudo-terminal session\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Resize a PTY session\",\n                \"operationId\": \"ResizePtySession\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"PTY session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Resize request with new dimensions\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/PtyResizeRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/PtySessionInfo\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/session\": {\n            \"get\": {\n                \"description\": \"Get a list of all active shell sessions\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"List all sessions\",\n                \"operationId\": \"ListSessions\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"array\",\n                            \"items\": {\n                                \"$ref\": \"#/definitions/Session\"\n                            }\n                        }\n                    }\n                }\n            },\n            \"post\": {\n                \"description\": \"Create a new shell session for command execution\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Create a new session\",\n                \"operationId\": \"CreateSession\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Session creation request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/CreateSessionRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"201\": {\n                        \"description\": \"Created\"\n                    }\n                }\n            }\n        },\n        \"/process/session/entrypoint\": {\n            \"get\": {\n                \"description\": \"Get details of an entrypoint session including its commands\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Get entrypoint session details\",\n                \"operationId\": \"GetEntrypointSession\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Session\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/session/entrypoint/logs\": {\n            \"get\": {\n                \"description\": \"Get logs for a sandbox entrypoint session. Supports both HTTP and WebSocket streaming.\",\n                \"produces\": [\n                    \"text/plain\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Get entrypoint logs\",\n                \"operationId\": \"GetEntrypointLogs\",\n                \"parameters\": [\n                    {\n                        \"type\": \"boolean\",\n                        \"description\": \"Follow logs in real-time (WebSocket only)\",\n                        \"name\": \"follow\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Entrypoint log content\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/session/{sessionId}\": {\n            \"get\": {\n                \"description\": \"Get details of a specific session including its commands\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Get session details\",\n                \"operationId\": \"GetSession\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Session\"\n                        }\n                    }\n                }\n            },\n            \"delete\": {\n                \"description\": \"Delete an existing shell session\",\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Delete a session\",\n                \"operationId\": \"DeleteSession\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"204\": {\n                        \"description\": \"No Content\"\n                    }\n                }\n            }\n        },\n        \"/process/session/{sessionId}/command/{commandId}\": {\n            \"get\": {\n                \"description\": \"Get details of a specific command within a session\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Get session command details\",\n                \"operationId\": \"GetSessionCommand\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Command ID\",\n                        \"name\": \"commandId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/Command\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/session/{sessionId}/command/{commandId}/input\": {\n            \"post\": {\n                \"description\": \"Send input data to a running command in a session for interactive execution\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Send input to command\",\n                \"operationId\": \"SendInput\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Command ID\",\n                        \"name\": \"commandId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Input send request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SessionSendInputRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"204\": {\n                        \"description\": \"No Content\"\n                    }\n                }\n            }\n        },\n        \"/process/session/{sessionId}/command/{commandId}/logs\": {\n            \"get\": {\n                \"description\": \"Get logs for a specific command within a session. Supports both HTTP and WebSocket streaming.\",\n                \"produces\": [\n                    \"text/plain\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Get session command logs\",\n                \"operationId\": \"GetSessionCommandLogs\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Command ID\",\n                        \"name\": \"commandId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"boolean\",\n                        \"description\": \"Follow logs in real-time (WebSocket only)\",\n                        \"name\": \"follow\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Log content\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/process/session/{sessionId}/exec\": {\n            \"post\": {\n                \"description\": \"Execute a command within an existing shell session\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"process\"\n                ],\n                \"summary\": \"Execute command in session\",\n                \"operationId\": \"SessionExecuteCommand\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Session ID\",\n                        \"name\": \"sessionId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Command execution request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SessionExecuteRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SessionExecuteResponse\"\n                        }\n                    },\n                    \"202\": {\n                        \"description\": \"Accepted\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SessionExecuteResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/user-home-dir\": {\n            \"get\": {\n                \"description\": \"Get the current user home directory path.\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"info\"\n                ],\n                \"summary\": \"Get user home directory\",\n                \"operationId\": \"GetUserHomeDir\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/UserHomeDirResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/version\": {\n            \"get\": {\n                \"description\": \"Get the current daemon version\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"info\"\n                ],\n                \"summary\": \"Get version\",\n                \"operationId\": \"GetVersion\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/work-dir\": {\n            \"get\": {\n                \"description\": \"Get the current working directory path. This is default directory used for running commands.\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"info\"\n                ],\n                \"summary\": \"Get working directory\",\n                \"operationId\": \"GetWorkDir\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/WorkDirResponse\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"definitions\": {\n        \"Command\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"command\",\n                \"id\"\n            ],\n            \"properties\": {\n                \"command\": {\n                    \"type\": \"string\"\n                },\n                \"exitCode\": {\n                    \"type\": \"integer\"\n                },\n                \"id\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"CompletionContext\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"triggerKind\"\n            ],\n            \"properties\": {\n                \"triggerCharacter\": {\n                    \"type\": \"string\"\n                },\n                \"triggerKind\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"CompletionItem\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"label\"\n            ],\n            \"properties\": {\n                \"detail\": {\n                    \"type\": \"string\"\n                },\n                \"documentation\": {},\n                \"filterText\": {\n                    \"type\": \"string\"\n                },\n                \"insertText\": {\n                    \"type\": \"string\"\n                },\n                \"kind\": {\n                    \"type\": \"integer\"\n                },\n                \"label\": {\n                    \"type\": \"string\"\n                },\n                \"sortText\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"CompletionList\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"isIncomplete\",\n                \"items\"\n            ],\n            \"properties\": {\n                \"isIncomplete\": {\n                    \"type\": \"boolean\"\n                },\n                \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/CompletionItem\"\n                    }\n                }\n            }\n        },\n        \"ComputerUseStartResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"message\": {\n                    \"type\": \"string\"\n                },\n                \"status\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"$ref\": \"#/definitions/ProcessStatus\"\n                    }\n                }\n            }\n        },\n        \"ComputerUseStatusResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"status\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"ComputerUseStopResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"message\": {\n                    \"type\": \"string\"\n                },\n                \"status\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"$ref\": \"#/definitions/ProcessStatus\"\n                    }\n                }\n            }\n        },\n        \"CreateContextRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"cwd\": {\n                    \"type\": \"string\"\n                },\n                \"language\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"CreateSessionRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"sessionId\"\n            ],\n            \"properties\": {\n                \"sessionId\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"DisplayInfo\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"height\": {\n                    \"type\": \"integer\"\n                },\n                \"id\": {\n                    \"type\": \"integer\"\n                },\n                \"isActive\": {\n                    \"type\": \"boolean\"\n                },\n                \"width\": {\n                    \"type\": \"integer\"\n                },\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"DisplayInfoResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"displays\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/DisplayInfo\"\n                    }\n                }\n            }\n        },\n        \"Empty\": {\n            \"type\": \"object\"\n        },\n        \"ExecuteRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"command\"\n            ],\n            \"properties\": {\n                \"command\": {\n                    \"type\": \"string\"\n                },\n                \"cwd\": {\n                    \"description\": \"Current working directory\",\n                    \"type\": \"string\"\n                },\n                \"timeout\": {\n                    \"description\": \"Timeout in seconds, defaults to 10 seconds\",\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"ExecuteResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"result\"\n            ],\n            \"properties\": {\n                \"exitCode\": {\n                    \"type\": \"integer\"\n                },\n                \"result\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"FileInfo\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"group\",\n                \"isDir\",\n                \"modTime\",\n                \"mode\",\n                \"name\",\n                \"owner\",\n                \"permissions\",\n                \"size\"\n            ],\n            \"properties\": {\n                \"group\": {\n                    \"type\": \"string\"\n                },\n                \"isDir\": {\n                    \"type\": \"boolean\"\n                },\n                \"modTime\": {\n                    \"type\": \"string\"\n                },\n                \"mode\": {\n                    \"type\": \"string\"\n                },\n                \"name\": {\n                    \"type\": \"string\"\n                },\n                \"owner\": {\n                    \"type\": \"string\"\n                },\n                \"permissions\": {\n                    \"type\": \"string\"\n                },\n                \"size\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"FileStatus\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"extra\",\n                \"name\",\n                \"staging\",\n                \"worktree\"\n            ],\n            \"properties\": {\n                \"extra\": {\n                    \"type\": \"string\"\n                },\n                \"name\": {\n                    \"type\": \"string\"\n                },\n                \"staging\": {\n                    \"$ref\": \"#/definitions/Status\"\n                },\n                \"worktree\": {\n                    \"$ref\": \"#/definitions/Status\"\n                }\n            }\n        },\n        \"FilesDownloadRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"paths\"\n            ],\n            \"properties\": {\n                \"paths\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    }\n                }\n            }\n        },\n        \"GitAddRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"files\",\n                \"path\"\n            ],\n            \"properties\": {\n                \"files\": {\n                    \"description\": \"files to add (use . for all files)\",\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"path\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"GitBranchRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"name\",\n                \"path\"\n            ],\n            \"properties\": {\n                \"name\": {\n                    \"type\": \"string\"\n                },\n                \"path\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"GitCheckoutRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"branch\",\n                \"path\"\n            ],\n            \"properties\": {\n                \"branch\": {\n                    \"type\": \"string\"\n                },\n                \"path\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"GitCloneRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"path\",\n                \"url\"\n            ],\n            \"properties\": {\n                \"branch\": {\n                    \"type\": \"string\"\n                },\n                \"commit_id\": {\n                    \"type\": \"string\"\n                },\n                \"password\": {\n                    \"type\": \"string\"\n                },\n                \"path\": {\n                    \"type\": \"string\"\n                },\n                \"url\": {\n                    \"type\": \"string\"\n                },\n                \"username\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"GitCommitInfo\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"author\",\n                \"email\",\n                \"hash\",\n                \"message\",\n                \"timestamp\"\n            ],\n            \"properties\": {\n                \"author\": {\n                    \"type\": \"string\"\n                },\n                \"email\": {\n                    \"type\": \"string\"\n                },\n                \"hash\": {\n                    \"type\": \"string\"\n                },\n                \"message\": {\n                    \"type\": \"string\"\n                },\n                \"timestamp\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"GitCommitRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"author\",\n                \"email\",\n                \"message\",\n                \"path\"\n            ],\n            \"properties\": {\n                \"allow_empty\": {\n                    \"type\": \"boolean\"\n                },\n                \"author\": {\n                    \"type\": \"string\"\n                },\n                \"email\": {\n                    \"type\": \"string\"\n                },\n                \"message\": {\n                    \"type\": \"string\"\n                },\n                \"path\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"GitCommitResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"hash\"\n            ],\n            \"properties\": {\n                \"hash\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"GitRepoRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"path\"\n            ],\n            \"properties\": {\n                \"password\": {\n                    \"type\": \"string\"\n                },\n                \"path\": {\n                    \"type\": \"string\"\n                },\n                \"username\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"GitStatus\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"currentBranch\",\n                \"fileStatus\"\n            ],\n            \"properties\": {\n                \"ahead\": {\n                    \"type\": \"integer\"\n                },\n                \"behind\": {\n                    \"type\": \"integer\"\n                },\n                \"branchPublished\": {\n                    \"type\": \"boolean\"\n                },\n                \"currentBranch\": {\n                    \"type\": \"string\"\n                },\n                \"fileStatus\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/FileStatus\"\n                    }\n                }\n            }\n        },\n        \"InitializeRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"token\"\n            ],\n            \"properties\": {\n                \"token\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"InterpreterContext\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"active\",\n                \"createdAt\",\n                \"cwd\",\n                \"id\",\n                \"language\"\n            ],\n            \"properties\": {\n                \"active\": {\n                    \"type\": \"boolean\"\n                },\n                \"createdAt\": {\n                    \"type\": \"string\"\n                },\n                \"cwd\": {\n                    \"type\": \"string\"\n                },\n                \"id\": {\n                    \"type\": \"string\"\n                },\n                \"language\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"IsPortInUseResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"isInUse\": {\n                    \"type\": \"boolean\"\n                }\n            }\n        },\n        \"KeyboardHotkeyRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"keys\": {\n                    \"description\": \"e.g., \\\"ctrl+c\\\", \\\"cmd+v\\\"\",\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"KeyboardPressRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"key\": {\n                    \"type\": \"string\"\n                },\n                \"modifiers\": {\n                    \"description\": \"ctrl, alt, shift, cmd\",\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    }\n                }\n            }\n        },\n        \"KeyboardTypeRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"delay\": {\n                    \"description\": \"milliseconds between keystrokes\",\n                    \"type\": \"integer\"\n                },\n                \"text\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"ListBranchResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"branches\"\n            ],\n            \"properties\": {\n                \"branches\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    }\n                }\n            }\n        },\n        \"ListContextsResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"contexts\"\n            ],\n            \"properties\": {\n                \"contexts\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/InterpreterContext\"\n                    }\n                }\n            }\n        },\n        \"ListRecordingsResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"recordings\"\n            ],\n            \"properties\": {\n                \"recordings\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/Recording\"\n                    }\n                }\n            }\n        },\n        \"LspCompletionParams\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"languageId\",\n                \"pathToProject\",\n                \"position\",\n                \"uri\"\n            ],\n            \"properties\": {\n                \"context\": {\n                    \"$ref\": \"#/definitions/CompletionContext\"\n                },\n                \"languageId\": {\n                    \"type\": \"string\"\n                },\n                \"pathToProject\": {\n                    \"type\": \"string\"\n                },\n                \"position\": {\n                    \"$ref\": \"#/definitions/LspPosition\"\n                },\n                \"uri\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"LspDocumentRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"languageId\",\n                \"pathToProject\",\n                \"uri\"\n            ],\n            \"properties\": {\n                \"languageId\": {\n                    \"type\": \"string\"\n                },\n                \"pathToProject\": {\n                    \"type\": \"string\"\n                },\n                \"uri\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"LspLocation\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"range\",\n                \"uri\"\n            ],\n            \"properties\": {\n                \"range\": {\n                    \"$ref\": \"#/definitions/LspRange\"\n                },\n                \"uri\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"LspPosition\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"character\",\n                \"line\"\n            ],\n            \"properties\": {\n                \"character\": {\n                    \"type\": \"integer\"\n                },\n                \"line\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"LspRange\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"end\",\n                \"start\"\n            ],\n            \"properties\": {\n                \"end\": {\n                    \"$ref\": \"#/definitions/LspPosition\"\n                },\n                \"start\": {\n                    \"$ref\": \"#/definitions/LspPosition\"\n                }\n            }\n        },\n        \"LspServerRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"languageId\",\n                \"pathToProject\"\n            ],\n            \"properties\": {\n                \"languageId\": {\n                    \"type\": \"string\"\n                },\n                \"pathToProject\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"LspSymbol\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"kind\",\n                \"location\",\n                \"name\"\n            ],\n            \"properties\": {\n                \"kind\": {\n                    \"type\": \"integer\"\n                },\n                \"location\": {\n                    \"$ref\": \"#/definitions/LspLocation\"\n                },\n                \"name\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"Match\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"content\",\n                \"file\",\n                \"line\"\n            ],\n            \"properties\": {\n                \"content\": {\n                    \"type\": \"string\"\n                },\n                \"file\": {\n                    \"type\": \"string\"\n                },\n                \"line\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"MouseClickRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"button\": {\n                    \"description\": \"left, right, middle\",\n                    \"type\": \"string\"\n                },\n                \"double\": {\n                    \"type\": \"boolean\"\n                },\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"MouseClickResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"MouseDragRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"button\": {\n                    \"type\": \"string\"\n                },\n                \"endX\": {\n                    \"type\": \"integer\"\n                },\n                \"endY\": {\n                    \"type\": \"integer\"\n                },\n                \"startX\": {\n                    \"type\": \"integer\"\n                },\n                \"startY\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"MouseDragResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"MouseMoveRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"MousePositionResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"MouseScrollRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"amount\": {\n                    \"type\": \"integer\"\n                },\n                \"direction\": {\n                    \"description\": \"up, down\",\n                    \"type\": \"string\"\n                },\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"PortList\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"ports\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"integer\"\n                    }\n                }\n            }\n        },\n        \"Position\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"ProcessErrorsResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"errors\": {\n                    \"type\": \"string\"\n                },\n                \"processName\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"ProcessLogsResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"logs\": {\n                    \"type\": \"string\"\n                },\n                \"processName\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"ProcessRestartResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"message\": {\n                    \"type\": \"string\"\n                },\n                \"processName\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"ProcessStatus\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"autoRestart\": {\n                    \"type\": \"boolean\"\n                },\n                \"pid\": {\n                    \"type\": \"integer\"\n                },\n                \"priority\": {\n                    \"type\": \"integer\"\n                },\n                \"running\": {\n                    \"type\": \"boolean\"\n                }\n            }\n        },\n        \"ProcessStatusResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"processName\": {\n                    \"type\": \"string\"\n                },\n                \"running\": {\n                    \"type\": \"boolean\"\n                }\n            }\n        },\n        \"PtyCreateRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"cols\": {\n                    \"type\": \"integer\"\n                },\n                \"cwd\": {\n                    \"type\": \"string\"\n                },\n                \"envs\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"id\": {\n                    \"type\": \"string\"\n                },\n                \"lazyStart\": {\n                    \"description\": \"Don't start PTY until first client connects\",\n                    \"type\": \"boolean\"\n                },\n                \"rows\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"PtyCreateResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"sessionId\"\n            ],\n            \"properties\": {\n                \"sessionId\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"PtyListResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"sessions\"\n            ],\n            \"properties\": {\n                \"sessions\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/PtySessionInfo\"\n                    }\n                }\n            }\n        },\n        \"PtyResizeRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"cols\",\n                \"rows\"\n            ],\n            \"properties\": {\n                \"cols\": {\n                    \"type\": \"integer\",\n                    \"maximum\": 1000,\n                    \"minimum\": 1\n                },\n                \"rows\": {\n                    \"type\": \"integer\",\n                    \"maximum\": 1000,\n                    \"minimum\": 1\n                }\n            }\n        },\n        \"PtySessionInfo\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"active\",\n                \"cols\",\n                \"createdAt\",\n                \"cwd\",\n                \"envs\",\n                \"id\",\n                \"lazyStart\",\n                \"rows\"\n            ],\n            \"properties\": {\n                \"active\": {\n                    \"type\": \"boolean\"\n                },\n                \"cols\": {\n                    \"type\": \"integer\"\n                },\n                \"createdAt\": {\n                    \"type\": \"string\"\n                },\n                \"cwd\": {\n                    \"type\": \"string\"\n                },\n                \"envs\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"id\": {\n                    \"type\": \"string\"\n                },\n                \"lazyStart\": {\n                    \"description\": \"Whether this session uses lazy start\",\n                    \"type\": \"boolean\"\n                },\n                \"rows\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"Recording\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"fileName\",\n                \"filePath\",\n                \"id\",\n                \"startTime\",\n                \"status\"\n            ],\n            \"properties\": {\n                \"durationSeconds\": {\n                    \"type\": \"number\"\n                },\n                \"endTime\": {\n                    \"type\": \"string\"\n                },\n                \"fileName\": {\n                    \"type\": \"string\"\n                },\n                \"filePath\": {\n                    \"type\": \"string\"\n                },\n                \"id\": {\n                    \"type\": \"string\"\n                },\n                \"sizeBytes\": {\n                    \"type\": \"integer\"\n                },\n                \"startTime\": {\n                    \"type\": \"string\"\n                },\n                \"status\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"ReplaceRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"files\",\n                \"newValue\",\n                \"pattern\"\n            ],\n            \"properties\": {\n                \"files\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"newValue\": {\n                    \"type\": \"string\"\n                },\n                \"pattern\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"ReplaceResult\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"error\": {\n                    \"type\": \"string\"\n                },\n                \"file\": {\n                    \"type\": \"string\"\n                },\n                \"success\": {\n                    \"type\": \"boolean\"\n                }\n            }\n        },\n        \"ScreenshotResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"cursorPosition\": {\n                    \"$ref\": \"#/definitions/Position\"\n                },\n                \"screenshot\": {\n                    \"type\": \"string\"\n                },\n                \"sizeBytes\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"ScrollResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"success\": {\n                    \"type\": \"boolean\"\n                }\n            }\n        },\n        \"SearchFilesResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"files\"\n            ],\n            \"properties\": {\n                \"files\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    }\n                }\n            }\n        },\n        \"Session\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"commands\",\n                \"sessionId\"\n            ],\n            \"properties\": {\n                \"commands\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/Command\"\n                    }\n                },\n                \"sessionId\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"SessionExecuteRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"command\"\n            ],\n            \"properties\": {\n                \"async\": {\n                    \"type\": \"boolean\"\n                },\n                \"command\": {\n                    \"type\": \"string\"\n                },\n                \"runAsync\": {\n                    \"type\": \"boolean\"\n                },\n                \"suppressInputEcho\": {\n                    \"type\": \"boolean\"\n                }\n            }\n        },\n        \"SessionExecuteResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"cmdId\"\n            ],\n            \"properties\": {\n                \"cmdId\": {\n                    \"type\": \"string\"\n                },\n                \"exitCode\": {\n                    \"type\": \"integer\"\n                },\n                \"output\": {\n                    \"type\": \"string\"\n                },\n                \"stderr\": {\n                    \"type\": \"string\"\n                },\n                \"stdout\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"SessionSendInputRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"data\"\n            ],\n            \"properties\": {\n                \"data\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"StartRecordingRequest\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"label\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"Status\": {\n            \"type\": \"string\",\n            \"enum\": [\n                \"Unmodified\",\n                \"Untracked\",\n                \"Modified\",\n                \"Added\",\n                \"Deleted\",\n                \"Renamed\",\n                \"Copied\",\n                \"Updated but unmerged\"\n            ],\n            \"x-enum-varnames\": [\n                \"Unmodified\",\n                \"Untracked\",\n                \"Modified\",\n                \"Added\",\n                \"Deleted\",\n                \"Renamed\",\n                \"Copied\",\n                \"UpdatedButUnmerged\"\n            ]\n        },\n        \"StopRecordingRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"id\"\n            ],\n            \"properties\": {\n                \"id\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"UserHomeDirResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"dir\"\n            ],\n            \"properties\": {\n                \"dir\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"WindowInfo\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"height\": {\n                    \"type\": \"integer\"\n                },\n                \"id\": {\n                    \"type\": \"integer\"\n                },\n                \"isActive\": {\n                    \"type\": \"boolean\"\n                },\n                \"title\": {\n                    \"type\": \"string\"\n                },\n                \"width\": {\n                    \"type\": \"integer\"\n                },\n                \"x\": {\n                    \"type\": \"integer\"\n                },\n                \"y\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"WindowsResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"windows\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/WindowInfo\"\n                    }\n                }\n            }\n        },\n        \"WorkDirResponse\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"dir\"\n            ],\n            \"properties\": {\n                \"dir\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"gin.H\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {}\n        },\n        \"git.GitDeleteBranchRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"name\",\n                \"path\"\n            ],\n            \"properties\": {\n                \"name\": {\n                    \"type\": \"string\"\n                },\n                \"path\": {\n                    \"type\": \"string\"\n                }\n            }\n        }\n    }\n}`\n\n// SwaggerInfo holds exported Swagger Info so clients can modify it\nvar SwaggerInfo = &swag.Spec{\n\tVersion:          \"v0.0.0-dev\",\n\tHost:             \"\",\n\tBasePath:         \"\",\n\tSchemes:          []string{},\n\tTitle:            \"Daytona Toolbox API\",\n\tDescription:      \"Daytona Toolbox API\",\n\tInfoInstanceName: \"swagger\",\n\tSwaggerTemplate:  docTemplate,\n\tLeftDelim:        \"{{\",\n\tRightDelim:       \"}}\",\n}\n\nfunc init() {\n\tswag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/docs/swagger.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"Daytona Toolbox API\",\n    \"title\": \"Daytona Toolbox API\",\n    \"contact\": {},\n    \"version\": \"v0.0.0-dev\"\n  },\n  \"paths\": {\n    \"/computeruse/display/info\": {\n      \"get\": {\n        \"description\": \"Get information about all available displays\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get display information\",\n        \"operationId\": \"GetDisplayInfo\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/DisplayInfoResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/display/windows\": {\n      \"get\": {\n        \"description\": \"Get information about all open windows\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get windows information\",\n        \"operationId\": \"GetWindows\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/WindowsResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/keyboard/hotkey\": {\n      \"post\": {\n        \"description\": \"Press a hotkey combination (e.g., ctrl+c, cmd+v)\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Press hotkey\",\n        \"operationId\": \"PressHotkey\",\n        \"parameters\": [\n          {\n            \"description\": \"Hotkey press request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/KeyboardHotkeyRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Empty\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/keyboard/key\": {\n      \"post\": {\n        \"description\": \"Press a key with optional modifiers\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Press key\",\n        \"operationId\": \"PressKey\",\n        \"parameters\": [\n          {\n            \"description\": \"Key press request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/KeyboardPressRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Empty\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/keyboard/type\": {\n      \"post\": {\n        \"description\": \"Type text with optional delay between keystrokes\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Type text\",\n        \"operationId\": \"TypeText\",\n        \"parameters\": [\n          {\n            \"description\": \"Text typing request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/KeyboardTypeRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Empty\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/mouse/click\": {\n      \"post\": {\n        \"description\": \"Click the mouse button at the specified coordinates\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Click mouse button\",\n        \"operationId\": \"Click\",\n        \"parameters\": [\n          {\n            \"description\": \"Mouse click request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/MouseClickRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/MouseClickResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/mouse/drag\": {\n      \"post\": {\n        \"description\": \"Drag the mouse from start to end coordinates\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Drag mouse\",\n        \"operationId\": \"Drag\",\n        \"parameters\": [\n          {\n            \"description\": \"Mouse drag request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/MouseDragRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/MouseDragResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/mouse/move\": {\n      \"post\": {\n        \"description\": \"Move the mouse cursor to the specified coordinates\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Move mouse cursor\",\n        \"operationId\": \"MoveMouse\",\n        \"parameters\": [\n          {\n            \"description\": \"Mouse move request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/MouseMoveRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/MousePositionResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/mouse/position\": {\n      \"get\": {\n        \"description\": \"Get the current mouse cursor position\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get mouse position\",\n        \"operationId\": \"GetMousePosition\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/MousePositionResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/mouse/scroll\": {\n      \"post\": {\n        \"description\": \"Scroll the mouse wheel at the specified coordinates\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Scroll mouse wheel\",\n        \"operationId\": \"Scroll\",\n        \"parameters\": [\n          {\n            \"description\": \"Mouse scroll request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/MouseScrollRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ScrollResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/process-status\": {\n      \"get\": {\n        \"description\": \"Get the status of all computer use processes\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get computer use process status\",\n        \"operationId\": \"GetComputerUseStatus\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ComputerUseStatusResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/process/{processName}/errors\": {\n      \"get\": {\n        \"description\": \"Get errors for a specific computer use process\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get process errors\",\n        \"operationId\": \"GetProcessErrors\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Process name to get errors for\",\n            \"name\": \"processName\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ProcessErrorsResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/process/{processName}/logs\": {\n      \"get\": {\n        \"description\": \"Get logs for a specific computer use process\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get process logs\",\n        \"operationId\": \"GetProcessLogs\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Process name to get logs for\",\n            \"name\": \"processName\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ProcessLogsResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/process/{processName}/restart\": {\n      \"post\": {\n        \"description\": \"Restart a specific computer use process\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Restart specific process\",\n        \"operationId\": \"RestartProcess\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Process name to restart\",\n            \"name\": \"processName\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ProcessRestartResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/process/{processName}/status\": {\n      \"get\": {\n        \"description\": \"Check if a specific computer use process is running\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get specific process status\",\n        \"operationId\": \"GetProcessStatus\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Process name to check\",\n            \"name\": \"processName\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ProcessStatusResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/recordings\": {\n      \"get\": {\n        \"description\": \"Get a list of all recordings (active and completed)\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"List all recordings\",\n        \"operationId\": \"ListRecordings\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ListRecordingsResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/recordings/start\": {\n      \"post\": {\n        \"description\": \"Start a new screen recording session\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Start a new recording\",\n        \"operationId\": \"StartRecording\",\n        \"parameters\": [\n          {\n            \"description\": \"Recording options\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/StartRecordingRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Recording\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/recordings/stop\": {\n      \"post\": {\n        \"description\": \"Stop an active screen recording session\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Stop a recording\",\n        \"operationId\": \"StopRecording\",\n        \"parameters\": [\n          {\n            \"description\": \"Recording ID to stop\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/StopRecordingRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Recording\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/recordings/{id}\": {\n      \"get\": {\n        \"description\": \"Get details of a specific recording by ID\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get recording details\",\n        \"operationId\": \"GetRecording\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Recording ID\",\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Recording\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"Delete a recording file by ID\",\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Delete a recording\",\n        \"operationId\": \"DeleteRecording\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Recording ID\",\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"No Content\"\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/recordings/{id}/download\": {\n      \"get\": {\n        \"description\": \"Download a recording by providing its ID\",\n        \"produces\": [\"application/octet-stream\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Download a recording\",\n        \"operationId\": \"DownloadRecording\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Recording ID\",\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"file\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/screenshot\": {\n      \"get\": {\n        \"description\": \"Take a screenshot of the entire screen\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Take a screenshot\",\n        \"operationId\": \"TakeScreenshot\",\n        \"parameters\": [\n          {\n            \"type\": \"boolean\",\n            \"description\": \"Whether to show cursor in screenshot\",\n            \"name\": \"showCursor\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ScreenshotResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/screenshot/compressed\": {\n      \"get\": {\n        \"description\": \"Take a compressed screenshot of the entire screen\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Take a compressed screenshot\",\n        \"operationId\": \"TakeCompressedScreenshot\",\n        \"parameters\": [\n          {\n            \"type\": \"boolean\",\n            \"description\": \"Whether to show cursor in screenshot\",\n            \"name\": \"showCursor\",\n            \"in\": \"query\"\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Image format (png or jpeg)\",\n            \"name\": \"format\",\n            \"in\": \"query\"\n          },\n          {\n            \"type\": \"integer\",\n            \"description\": \"JPEG quality (1-100)\",\n            \"name\": \"quality\",\n            \"in\": \"query\"\n          },\n          {\n            \"type\": \"number\",\n            \"description\": \"Scale factor (0.1-1.0)\",\n            \"name\": \"scale\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ScreenshotResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/screenshot/region\": {\n      \"get\": {\n        \"description\": \"Take a screenshot of a specific region of the screen\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Take a region screenshot\",\n        \"operationId\": \"TakeRegionScreenshot\",\n        \"parameters\": [\n          {\n            \"type\": \"integer\",\n            \"description\": \"X coordinate of the region\",\n            \"name\": \"x\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"integer\",\n            \"description\": \"Y coordinate of the region\",\n            \"name\": \"y\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"integer\",\n            \"description\": \"Width of the region\",\n            \"name\": \"width\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"integer\",\n            \"description\": \"Height of the region\",\n            \"name\": \"height\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"boolean\",\n            \"description\": \"Whether to show cursor in screenshot\",\n            \"name\": \"showCursor\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ScreenshotResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/screenshot/region/compressed\": {\n      \"get\": {\n        \"description\": \"Take a compressed screenshot of a specific region of the screen\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Take a compressed region screenshot\",\n        \"operationId\": \"TakeCompressedRegionScreenshot\",\n        \"parameters\": [\n          {\n            \"type\": \"integer\",\n            \"description\": \"X coordinate of the region\",\n            \"name\": \"x\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"integer\",\n            \"description\": \"Y coordinate of the region\",\n            \"name\": \"y\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"integer\",\n            \"description\": \"Width of the region\",\n            \"name\": \"width\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"integer\",\n            \"description\": \"Height of the region\",\n            \"name\": \"height\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"boolean\",\n            \"description\": \"Whether to show cursor in screenshot\",\n            \"name\": \"showCursor\",\n            \"in\": \"query\"\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Image format (png or jpeg)\",\n            \"name\": \"format\",\n            \"in\": \"query\"\n          },\n          {\n            \"type\": \"integer\",\n            \"description\": \"JPEG quality (1-100)\",\n            \"name\": \"quality\",\n            \"in\": \"query\"\n          },\n          {\n            \"type\": \"number\",\n            \"description\": \"Scale factor (0.1-1.0)\",\n            \"name\": \"scale\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ScreenshotResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/start\": {\n      \"post\": {\n        \"description\": \"Start all computer use processes and return their status\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Start computer use processes\",\n        \"operationId\": \"StartComputerUse\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ComputerUseStartResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/status\": {\n      \"get\": {\n        \"description\": \"Get the current status of the computer use system\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Get computer use status\",\n        \"operationId\": \"GetComputerUseSystemStatus\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ComputerUseStatusResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/computeruse/stop\": {\n      \"post\": {\n        \"description\": \"Stop all computer use processes and return their status\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"computer-use\"],\n        \"summary\": \"Stop computer use processes\",\n        \"operationId\": \"StopComputerUse\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ComputerUseStopResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/files\": {\n      \"get\": {\n        \"description\": \"List files and directories in the specified path\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"List files and directories\",\n        \"operationId\": \"ListFiles\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Directory path to list (defaults to working directory)\",\n            \"name\": \"path\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/FileInfo\"\n              }\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"Delete a file or directory at the specified path\",\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Delete a file or directory\",\n        \"operationId\": \"DeleteFile\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"File or directory path to delete\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"boolean\",\n            \"description\": \"Enable recursive deletion for directories\",\n            \"name\": \"recursive\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"No Content\"\n          }\n        }\n      }\n    },\n    \"/files/bulk-download\": {\n      \"post\": {\n        \"description\": \"Download multiple files by providing their paths\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"multipart/form-data\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Download multiple files\",\n        \"operationId\": \"DownloadFiles\",\n        \"parameters\": [\n          {\n            \"description\": \"Paths of files to download\",\n            \"name\": \"downloadFiles\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/FilesDownloadRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/gin.H\"\n            }\n          }\n        }\n      }\n    },\n    \"/files/bulk-upload\": {\n      \"post\": {\n        \"description\": \"Upload multiple files with their destination paths\",\n        \"consumes\": [\"multipart/form-data\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Upload multiple files\",\n        \"operationId\": \"UploadFiles\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/files/download\": {\n      \"get\": {\n        \"description\": \"Download a file by providing its path\",\n        \"produces\": [\"application/octet-stream\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Download a file\",\n        \"operationId\": \"DownloadFile\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"File path to download\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"file\"\n            }\n          }\n        }\n      }\n    },\n    \"/files/find\": {\n      \"get\": {\n        \"description\": \"Search for text pattern within files in a directory\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Find text in files\",\n        \"operationId\": \"FindInFiles\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Directory path to search in\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Text pattern to search for\",\n            \"name\": \"pattern\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Match\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/files/folder\": {\n      \"post\": {\n        \"description\": \"Create a folder with the specified path and optional permissions\",\n        \"consumes\": [\"application/json\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Create a folder\",\n        \"operationId\": \"CreateFolder\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Folder path to create\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Octal permission mode (default: 0755)\",\n            \"name\": \"mode\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created\"\n          }\n        }\n      }\n    },\n    \"/files/info\": {\n      \"get\": {\n        \"description\": \"Get detailed information about a file or directory\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Get file information\",\n        \"operationId\": \"GetFileInfo\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"File or directory path\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/FileInfo\"\n            }\n          }\n        }\n      }\n    },\n    \"/files/move\": {\n      \"post\": {\n        \"description\": \"Move or rename a file or directory from source to destination\",\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Move or rename file/directory\",\n        \"operationId\": \"MoveFile\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Source file or directory path\",\n            \"name\": \"source\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Destination file or directory path\",\n            \"name\": \"destination\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/files/permissions\": {\n      \"post\": {\n        \"description\": \"Set file permissions, ownership, and group for a file or directory\",\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Set file permissions\",\n        \"operationId\": \"SetFilePermissions\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"File or directory path\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Owner (username or UID)\",\n            \"name\": \"owner\",\n            \"in\": \"query\"\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Group (group name or GID)\",\n            \"name\": \"group\",\n            \"in\": \"query\"\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"File mode in octal format (e.g., 0755)\",\n            \"name\": \"mode\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/files/replace\": {\n      \"post\": {\n        \"description\": \"Replace text pattern with new value in multiple files\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Replace text in files\",\n        \"operationId\": \"ReplaceInFiles\",\n        \"parameters\": [\n          {\n            \"description\": \"Replace request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/ReplaceRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/ReplaceResult\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/files/search\": {\n      \"get\": {\n        \"description\": \"Search for files matching a specific pattern in a directory\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Search files by pattern\",\n        \"operationId\": \"SearchFiles\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Directory path to search in\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"File pattern to match (e.g., *.txt, *.go)\",\n            \"name\": \"pattern\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/SearchFilesResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/files/upload\": {\n      \"post\": {\n        \"description\": \"Upload a file to the specified path\",\n        \"consumes\": [\"multipart/form-data\"],\n        \"tags\": [\"file-system\"],\n        \"summary\": \"Upload a file\",\n        \"operationId\": \"UploadFile\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Destination path for the uploaded file\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"file\",\n            \"description\": \"File to upload\",\n            \"name\": \"file\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/gin.H\"\n            }\n          }\n        }\n      }\n    },\n    \"/git/add\": {\n      \"post\": {\n        \"description\": \"Add files to the Git staging area\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Add files to Git staging\",\n        \"operationId\": \"AddFiles\",\n        \"parameters\": [\n          {\n            \"description\": \"Add files request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitAddRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/git/branches\": {\n      \"get\": {\n        \"description\": \"Get a list of all branches in the Git repository\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"List branches\",\n        \"operationId\": \"ListBranches\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Repository path\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ListBranchResponse\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Create a new branch in the Git repository\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Create a new branch\",\n        \"operationId\": \"CreateBranch\",\n        \"parameters\": [\n          {\n            \"description\": \"Create branch request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitBranchRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created\"\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"Delete a branch from the Git repository\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Delete a branch\",\n        \"operationId\": \"DeleteBranch\",\n        \"parameters\": [\n          {\n            \"description\": \"Delete branch request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/git.GitDeleteBranchRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"No Content\"\n          }\n        }\n      }\n    },\n    \"/git/checkout\": {\n      \"post\": {\n        \"description\": \"Switch to a different branch or commit in the Git repository\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Checkout branch or commit\",\n        \"operationId\": \"CheckoutBranch\",\n        \"parameters\": [\n          {\n            \"description\": \"Checkout request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitCheckoutRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/git/clone\": {\n      \"post\": {\n        \"description\": \"Clone a Git repository to the specified path\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Clone a Git repository\",\n        \"operationId\": \"CloneRepository\",\n        \"parameters\": [\n          {\n            \"description\": \"Clone repository request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitCloneRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/git/commit\": {\n      \"post\": {\n        \"description\": \"Commit staged changes to the Git repository\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Commit changes\",\n        \"operationId\": \"CommitChanges\",\n        \"parameters\": [\n          {\n            \"description\": \"Commit request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitCommitRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitCommitResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/git/history\": {\n      \"get\": {\n        \"description\": \"Get the commit history of the Git repository\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Get commit history\",\n        \"operationId\": \"GetCommitHistory\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Repository path\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/GitCommitInfo\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/git/pull\": {\n      \"post\": {\n        \"description\": \"Pull changes from the remote Git repository\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Pull changes from remote\",\n        \"operationId\": \"PullChanges\",\n        \"parameters\": [\n          {\n            \"description\": \"Pull request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitRepoRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/git/push\": {\n      \"post\": {\n        \"description\": \"Push local changes to the remote Git repository\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Push changes to remote\",\n        \"operationId\": \"PushChanges\",\n        \"parameters\": [\n          {\n            \"description\": \"Push request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitRepoRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/git/status\": {\n      \"get\": {\n        \"description\": \"Get the Git status of the repository at the specified path\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"git\"],\n        \"summary\": \"Get Git status\",\n        \"operationId\": \"GetStatus\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Repository path\",\n            \"name\": \"path\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/GitStatus\"\n            }\n          }\n        }\n      }\n    },\n    \"/init\": {\n      \"post\": {\n        \"description\": \"Set the auth token and initialize telemetry for the toolbox server\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"server\"],\n        \"summary\": \"Initialize toolbox server\",\n        \"operationId\": \"Initialize\",\n        \"parameters\": [\n          {\n            \"description\": \"Initialization request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/InitializeRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/lsp/completions\": {\n      \"post\": {\n        \"description\": \"Get code completion suggestions from the LSP server\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"lsp\"],\n        \"summary\": \"Get code completions\",\n        \"operationId\": \"Completions\",\n        \"parameters\": [\n          {\n            \"description\": \"Completion request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/LspCompletionParams\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/CompletionList\"\n            }\n          }\n        }\n      }\n    },\n    \"/lsp/did-close\": {\n      \"post\": {\n        \"description\": \"Notify the LSP server that a document has been closed\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"lsp\"],\n        \"summary\": \"Notify document closed\",\n        \"operationId\": \"DidClose\",\n        \"parameters\": [\n          {\n            \"description\": \"Document request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/LspDocumentRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/lsp/did-open\": {\n      \"post\": {\n        \"description\": \"Notify the LSP server that a document has been opened\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"lsp\"],\n        \"summary\": \"Notify document opened\",\n        \"operationId\": \"DidOpen\",\n        \"parameters\": [\n          {\n            \"description\": \"Document request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/LspDocumentRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/lsp/document-symbols\": {\n      \"get\": {\n        \"description\": \"Get symbols (functions, classes, etc.) from a document\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"lsp\"],\n        \"summary\": \"Get document symbols\",\n        \"operationId\": \"DocumentSymbols\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Language ID (e.g., python, typescript)\",\n            \"name\": \"languageId\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Path to project\",\n            \"name\": \"pathToProject\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Document URI\",\n            \"name\": \"uri\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/LspSymbol\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/lsp/start\": {\n      \"post\": {\n        \"description\": \"Start a Language Server Protocol server for the specified language\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"lsp\"],\n        \"summary\": \"Start LSP server\",\n        \"operationId\": \"Start\",\n        \"parameters\": [\n          {\n            \"description\": \"LSP server request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/LspServerRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/lsp/stop\": {\n      \"post\": {\n        \"description\": \"Stop a Language Server Protocol server\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"lsp\"],\n        \"summary\": \"Stop LSP server\",\n        \"operationId\": \"Stop\",\n        \"parameters\": [\n          {\n            \"description\": \"LSP server request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/LspServerRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\"\n          }\n        }\n      }\n    },\n    \"/lsp/workspacesymbols\": {\n      \"get\": {\n        \"description\": \"Search for symbols across the entire workspace\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"lsp\"],\n        \"summary\": \"Get workspace symbols\",\n        \"operationId\": \"WorkspaceSymbols\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Search query\",\n            \"name\": \"query\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Language ID (e.g., python, typescript)\",\n            \"name\": \"languageId\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Path to project\",\n            \"name\": \"pathToProject\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/LspSymbol\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/port\": {\n      \"get\": {\n        \"description\": \"Get a list of all currently active ports\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"port\"],\n        \"summary\": \"Get active ports\",\n        \"operationId\": \"GetPorts\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/PortList\"\n            }\n          }\n        }\n      }\n    },\n    \"/port/{port}/in-use\": {\n      \"get\": {\n        \"description\": \"Check if a specific port is currently in use\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"port\"],\n        \"summary\": \"Check if port is in use\",\n        \"operationId\": \"IsPortInUse\",\n        \"parameters\": [\n          {\n            \"type\": \"integer\",\n            \"description\": \"Port number (3000-9999)\",\n            \"name\": \"port\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/IsPortInUseResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/execute\": {\n      \"post\": {\n        \"description\": \"Execute a shell command and return the output and exit code\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Execute a command\",\n        \"operationId\": \"ExecuteCommand\",\n        \"parameters\": [\n          {\n            \"description\": \"Command execution request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/ExecuteRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ExecuteResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/interpreter/context\": {\n      \"get\": {\n        \"description\": \"Returns information about all user-created interpreter contexts (excludes default context)\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"interpreter\"],\n        \"summary\": \"List all user-created interpreter contexts\",\n        \"operationId\": \"ListInterpreterContexts\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ListContextsResponse\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Creates a new isolated interpreter context with optional working directory and language\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"interpreter\"],\n        \"summary\": \"Create a new interpreter context\",\n        \"operationId\": \"CreateInterpreterContext\",\n        \"parameters\": [\n          {\n            \"description\": \"Context configuration\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/CreateContextRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/InterpreterContext\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/process/interpreter/context/{id}\": {\n      \"delete\": {\n        \"description\": \"Deletes an interpreter context and shuts down its worker process\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"interpreter\"],\n        \"summary\": \"Delete an interpreter context\",\n        \"operationId\": \"DeleteInterpreterContext\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Context ID\",\n            \"name\": \"id\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/process/interpreter/execute\": {\n      \"get\": {\n        \"description\": \"Executes code in a specified context (or default context if not specified) via WebSocket streaming\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"interpreter\"],\n        \"summary\": \"Execute code in an interpreter context\",\n        \"operationId\": \"ExecuteInterpreterCode\",\n        \"responses\": {\n          \"101\": {\n            \"description\": \"Switching Protocols\",\n            \"schema\": {\n              \"type\": \"string\"\n            },\n            \"headers\": {\n              \"Connection\": {\n                \"type\": \"string\",\n                \"description\": \"Upgrade\"\n              },\n              \"Upgrade\": {\n                \"type\": \"string\",\n                \"description\": \"websocket\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/process/pty\": {\n      \"get\": {\n        \"description\": \"Get a list of all active pseudo-terminal sessions\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"List all PTY sessions\",\n        \"operationId\": \"ListPtySessions\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/PtyListResponse\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Create a new pseudo-terminal session with specified configuration\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Create a new PTY session\",\n        \"operationId\": \"CreatePtySession\",\n        \"parameters\": [\n          {\n            \"description\": \"PTY session creation request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/PtyCreateRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/PtyCreateResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/pty/{sessionId}\": {\n      \"get\": {\n        \"description\": \"Get detailed information about a specific pseudo-terminal session\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Get PTY session information\",\n        \"operationId\": \"GetPtySession\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"PTY session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/PtySessionInfo\"\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"Delete a pseudo-terminal session and terminate its process\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Delete a PTY session\",\n        \"operationId\": \"DeletePtySession\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"PTY session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/gin.H\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/pty/{sessionId}/connect\": {\n      \"get\": {\n        \"description\": \"Establish a WebSocket connection to interact with a pseudo-terminal session\",\n        \"tags\": [\"process\"],\n        \"summary\": \"Connect to PTY session via WebSocket\",\n        \"operationId\": \"ConnectPtySession\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"PTY session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"101\": {\n            \"description\": \"Switching Protocols - WebSocket connection established\"\n          }\n        }\n      }\n    },\n    \"/process/pty/{sessionId}/resize\": {\n      \"post\": {\n        \"description\": \"Resize the terminal dimensions of a pseudo-terminal session\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Resize a PTY session\",\n        \"operationId\": \"ResizePtySession\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"PTY session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Resize request with new dimensions\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/PtyResizeRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/PtySessionInfo\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/session\": {\n      \"get\": {\n        \"description\": \"Get a list of all active shell sessions\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"List all sessions\",\n        \"operationId\": \"ListSessions\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/Session\"\n              }\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Create a new shell session for command execution\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Create a new session\",\n        \"operationId\": \"CreateSession\",\n        \"parameters\": [\n          {\n            \"description\": \"Session creation request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/CreateSessionRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created\"\n          }\n        }\n      }\n    },\n    \"/process/session/entrypoint\": {\n      \"get\": {\n        \"description\": \"Get details of an entrypoint session including its commands\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Get entrypoint session details\",\n        \"operationId\": \"GetEntrypointSession\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Session\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/session/entrypoint/logs\": {\n      \"get\": {\n        \"description\": \"Get logs for a sandbox entrypoint session. Supports both HTTP and WebSocket streaming.\",\n        \"produces\": [\"text/plain\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Get entrypoint logs\",\n        \"operationId\": \"GetEntrypointLogs\",\n        \"parameters\": [\n          {\n            \"type\": \"boolean\",\n            \"description\": \"Follow logs in real-time (WebSocket only)\",\n            \"name\": \"follow\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Entrypoint log content\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/session/{sessionId}\": {\n      \"get\": {\n        \"description\": \"Get details of a specific session including its commands\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Get session details\",\n        \"operationId\": \"GetSession\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Session\"\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"Delete an existing shell session\",\n        \"tags\": [\"process\"],\n        \"summary\": \"Delete a session\",\n        \"operationId\": \"DeleteSession\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"No Content\"\n          }\n        }\n      }\n    },\n    \"/process/session/{sessionId}/command/{commandId}\": {\n      \"get\": {\n        \"description\": \"Get details of a specific command within a session\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Get session command details\",\n        \"operationId\": \"GetSessionCommand\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Command ID\",\n            \"name\": \"commandId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/Command\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/session/{sessionId}/command/{commandId}/input\": {\n      \"post\": {\n        \"description\": \"Send input data to a running command in a session for interactive execution\",\n        \"consumes\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Send input to command\",\n        \"operationId\": \"SendInput\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Command ID\",\n            \"name\": \"commandId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Input send request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/SessionSendInputRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"204\": {\n            \"description\": \"No Content\"\n          }\n        }\n      }\n    },\n    \"/process/session/{sessionId}/command/{commandId}/logs\": {\n      \"get\": {\n        \"description\": \"Get logs for a specific command within a session. Supports both HTTP and WebSocket streaming.\",\n        \"produces\": [\"text/plain\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Get session command logs\",\n        \"operationId\": \"GetSessionCommandLogs\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Command ID\",\n            \"name\": \"commandId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"type\": \"boolean\",\n            \"description\": \"Follow logs in real-time (WebSocket only)\",\n            \"name\": \"follow\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Log content\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          }\n        }\n      }\n    },\n    \"/process/session/{sessionId}/exec\": {\n      \"post\": {\n        \"description\": \"Execute a command within an existing shell session\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"process\"],\n        \"summary\": \"Execute command in session\",\n        \"operationId\": \"SessionExecuteCommand\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Session ID\",\n            \"name\": \"sessionId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Command execution request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/SessionExecuteRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/SessionExecuteResponse\"\n            }\n          },\n          \"202\": {\n            \"description\": \"Accepted\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/SessionExecuteResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/user-home-dir\": {\n      \"get\": {\n        \"description\": \"Get the current user home directory path.\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"info\"],\n        \"summary\": \"Get user home directory\",\n        \"operationId\": \"GetUserHomeDir\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/UserHomeDirResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/version\": {\n      \"get\": {\n        \"description\": \"Get the current daemon version\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"info\"],\n        \"summary\": \"Get version\",\n        \"operationId\": \"GetVersion\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/work-dir\": {\n      \"get\": {\n        \"description\": \"Get the current working directory path. This is default directory used for running commands.\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"info\"],\n        \"summary\": \"Get working directory\",\n        \"operationId\": \"GetWorkDir\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/WorkDirResponse\"\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"Command\": {\n      \"type\": \"object\",\n      \"required\": [\"command\", \"id\"],\n      \"properties\": {\n        \"command\": {\n          \"type\": \"string\"\n        },\n        \"exitCode\": {\n          \"type\": \"integer\"\n        },\n        \"id\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"CompletionContext\": {\n      \"type\": \"object\",\n      \"required\": [\"triggerKind\"],\n      \"properties\": {\n        \"triggerCharacter\": {\n          \"type\": \"string\"\n        },\n        \"triggerKind\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"CompletionItem\": {\n      \"type\": \"object\",\n      \"required\": [\"label\"],\n      \"properties\": {\n        \"detail\": {\n          \"type\": \"string\"\n        },\n        \"documentation\": {},\n        \"filterText\": {\n          \"type\": \"string\"\n        },\n        \"insertText\": {\n          \"type\": \"string\"\n        },\n        \"kind\": {\n          \"type\": \"integer\"\n        },\n        \"label\": {\n          \"type\": \"string\"\n        },\n        \"sortText\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"CompletionList\": {\n      \"type\": \"object\",\n      \"required\": [\"isIncomplete\", \"items\"],\n      \"properties\": {\n        \"isIncomplete\": {\n          \"type\": \"boolean\"\n        },\n        \"items\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/CompletionItem\"\n          }\n        }\n      }\n    },\n    \"ComputerUseStartResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"message\": {\n          \"type\": \"string\"\n        },\n        \"status\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ProcessStatus\"\n          }\n        }\n      }\n    },\n    \"ComputerUseStatusResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"status\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ComputerUseStopResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"message\": {\n          \"type\": \"string\"\n        },\n        \"status\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/ProcessStatus\"\n          }\n        }\n      }\n    },\n    \"CreateContextRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cwd\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"CreateSessionRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"sessionId\"],\n      \"properties\": {\n        \"sessionId\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"DisplayInfo\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"height\": {\n          \"type\": \"integer\"\n        },\n        \"id\": {\n          \"type\": \"integer\"\n        },\n        \"isActive\": {\n          \"type\": \"boolean\"\n        },\n        \"width\": {\n          \"type\": \"integer\"\n        },\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"DisplayInfoResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"displays\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/DisplayInfo\"\n          }\n        }\n      }\n    },\n    \"Empty\": {\n      \"type\": \"object\"\n    },\n    \"ExecuteRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"command\"],\n      \"properties\": {\n        \"command\": {\n          \"type\": \"string\"\n        },\n        \"cwd\": {\n          \"description\": \"Current working directory\",\n          \"type\": \"string\"\n        },\n        \"timeout\": {\n          \"description\": \"Timeout in seconds, defaults to 10 seconds\",\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"ExecuteResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"result\"],\n      \"properties\": {\n        \"exitCode\": {\n          \"type\": \"integer\"\n        },\n        \"result\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"FileInfo\": {\n      \"type\": \"object\",\n      \"required\": [\"group\", \"isDir\", \"modTime\", \"mode\", \"name\", \"owner\", \"permissions\", \"size\"],\n      \"properties\": {\n        \"group\": {\n          \"type\": \"string\"\n        },\n        \"isDir\": {\n          \"type\": \"boolean\"\n        },\n        \"modTime\": {\n          \"type\": \"string\"\n        },\n        \"mode\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"owner\": {\n          \"type\": \"string\"\n        },\n        \"permissions\": {\n          \"type\": \"string\"\n        },\n        \"size\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"FileStatus\": {\n      \"type\": \"object\",\n      \"required\": [\"extra\", \"name\", \"staging\", \"worktree\"],\n      \"properties\": {\n        \"extra\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"staging\": {\n          \"$ref\": \"#/definitions/Status\"\n        },\n        \"worktree\": {\n          \"$ref\": \"#/definitions/Status\"\n        }\n      }\n    },\n    \"FilesDownloadRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"paths\"],\n      \"properties\": {\n        \"paths\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"GitAddRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"files\", \"path\"],\n      \"properties\": {\n        \"files\": {\n          \"description\": \"files to add (use . for all files)\",\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"path\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"GitBranchRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"name\", \"path\"],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"GitCheckoutRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"branch\", \"path\"],\n      \"properties\": {\n        \"branch\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"GitCloneRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"path\", \"url\"],\n      \"properties\": {\n        \"branch\": {\n          \"type\": \"string\"\n        },\n        \"commit_id\": {\n          \"type\": \"string\"\n        },\n        \"password\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"username\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"GitCommitInfo\": {\n      \"type\": \"object\",\n      \"required\": [\"author\", \"email\", \"hash\", \"message\", \"timestamp\"],\n      \"properties\": {\n        \"author\": {\n          \"type\": \"string\"\n        },\n        \"email\": {\n          \"type\": \"string\"\n        },\n        \"hash\": {\n          \"type\": \"string\"\n        },\n        \"message\": {\n          \"type\": \"string\"\n        },\n        \"timestamp\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"GitCommitRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"author\", \"email\", \"message\", \"path\"],\n      \"properties\": {\n        \"allow_empty\": {\n          \"type\": \"boolean\"\n        },\n        \"author\": {\n          \"type\": \"string\"\n        },\n        \"email\": {\n          \"type\": \"string\"\n        },\n        \"message\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"GitCommitResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"hash\"],\n      \"properties\": {\n        \"hash\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"GitRepoRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"path\"],\n      \"properties\": {\n        \"password\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        },\n        \"username\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"GitStatus\": {\n      \"type\": \"object\",\n      \"required\": [\"currentBranch\", \"fileStatus\"],\n      \"properties\": {\n        \"ahead\": {\n          \"type\": \"integer\"\n        },\n        \"behind\": {\n          \"type\": \"integer\"\n        },\n        \"branchPublished\": {\n          \"type\": \"boolean\"\n        },\n        \"currentBranch\": {\n          \"type\": \"string\"\n        },\n        \"fileStatus\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/FileStatus\"\n          }\n        }\n      }\n    },\n    \"InitializeRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"token\"],\n      \"properties\": {\n        \"token\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"InterpreterContext\": {\n      \"type\": \"object\",\n      \"required\": [\"active\", \"createdAt\", \"cwd\", \"id\", \"language\"],\n      \"properties\": {\n        \"active\": {\n          \"type\": \"boolean\"\n        },\n        \"createdAt\": {\n          \"type\": \"string\"\n        },\n        \"cwd\": {\n          \"type\": \"string\"\n        },\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"language\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"IsPortInUseResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"isInUse\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"KeyboardHotkeyRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"keys\": {\n          \"description\": \"e.g., \\\"ctrl+c\\\", \\\"cmd+v\\\"\",\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"KeyboardPressRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"key\": {\n          \"type\": \"string\"\n        },\n        \"modifiers\": {\n          \"description\": \"ctrl, alt, shift, cmd\",\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"KeyboardTypeRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"delay\": {\n          \"description\": \"milliseconds between keystrokes\",\n          \"type\": \"integer\"\n        },\n        \"text\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ListBranchResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"branches\"],\n      \"properties\": {\n        \"branches\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"ListContextsResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"contexts\"],\n      \"properties\": {\n        \"contexts\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/InterpreterContext\"\n          }\n        }\n      }\n    },\n    \"ListRecordingsResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"recordings\"],\n      \"properties\": {\n        \"recordings\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Recording\"\n          }\n        }\n      }\n    },\n    \"LspCompletionParams\": {\n      \"type\": \"object\",\n      \"required\": [\"languageId\", \"pathToProject\", \"position\", \"uri\"],\n      \"properties\": {\n        \"context\": {\n          \"$ref\": \"#/definitions/CompletionContext\"\n        },\n        \"languageId\": {\n          \"type\": \"string\"\n        },\n        \"pathToProject\": {\n          \"type\": \"string\"\n        },\n        \"position\": {\n          \"$ref\": \"#/definitions/LspPosition\"\n        },\n        \"uri\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"LspDocumentRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"languageId\", \"pathToProject\", \"uri\"],\n      \"properties\": {\n        \"languageId\": {\n          \"type\": \"string\"\n        },\n        \"pathToProject\": {\n          \"type\": \"string\"\n        },\n        \"uri\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"LspLocation\": {\n      \"type\": \"object\",\n      \"required\": [\"range\", \"uri\"],\n      \"properties\": {\n        \"range\": {\n          \"$ref\": \"#/definitions/LspRange\"\n        },\n        \"uri\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"LspPosition\": {\n      \"type\": \"object\",\n      \"required\": [\"character\", \"line\"],\n      \"properties\": {\n        \"character\": {\n          \"type\": \"integer\"\n        },\n        \"line\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"LspRange\": {\n      \"type\": \"object\",\n      \"required\": [\"end\", \"start\"],\n      \"properties\": {\n        \"end\": {\n          \"$ref\": \"#/definitions/LspPosition\"\n        },\n        \"start\": {\n          \"$ref\": \"#/definitions/LspPosition\"\n        }\n      }\n    },\n    \"LspServerRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"languageId\", \"pathToProject\"],\n      \"properties\": {\n        \"languageId\": {\n          \"type\": \"string\"\n        },\n        \"pathToProject\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"LspSymbol\": {\n      \"type\": \"object\",\n      \"required\": [\"kind\", \"location\", \"name\"],\n      \"properties\": {\n        \"kind\": {\n          \"type\": \"integer\"\n        },\n        \"location\": {\n          \"$ref\": \"#/definitions/LspLocation\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"Match\": {\n      \"type\": \"object\",\n      \"required\": [\"content\", \"file\", \"line\"],\n      \"properties\": {\n        \"content\": {\n          \"type\": \"string\"\n        },\n        \"file\": {\n          \"type\": \"string\"\n        },\n        \"line\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"MouseClickRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"button\": {\n          \"description\": \"left, right, middle\",\n          \"type\": \"string\"\n        },\n        \"double\": {\n          \"type\": \"boolean\"\n        },\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"MouseClickResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"MouseDragRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"button\": {\n          \"type\": \"string\"\n        },\n        \"endX\": {\n          \"type\": \"integer\"\n        },\n        \"endY\": {\n          \"type\": \"integer\"\n        },\n        \"startX\": {\n          \"type\": \"integer\"\n        },\n        \"startY\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"MouseDragResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"MouseMoveRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"MousePositionResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"MouseScrollRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"amount\": {\n          \"type\": \"integer\"\n        },\n        \"direction\": {\n          \"description\": \"up, down\",\n          \"type\": \"string\"\n        },\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"PortList\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"ports\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"integer\"\n          }\n        }\n      }\n    },\n    \"Position\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"ProcessErrorsResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"errors\": {\n          \"type\": \"string\"\n        },\n        \"processName\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ProcessLogsResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"logs\": {\n          \"type\": \"string\"\n        },\n        \"processName\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ProcessRestartResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"message\": {\n          \"type\": \"string\"\n        },\n        \"processName\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ProcessStatus\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"autoRestart\": {\n          \"type\": \"boolean\"\n        },\n        \"pid\": {\n          \"type\": \"integer\"\n        },\n        \"priority\": {\n          \"type\": \"integer\"\n        },\n        \"running\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"ProcessStatusResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"processName\": {\n          \"type\": \"string\"\n        },\n        \"running\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"PtyCreateRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cols\": {\n          \"type\": \"integer\"\n        },\n        \"cwd\": {\n          \"type\": \"string\"\n        },\n        \"envs\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"lazyStart\": {\n          \"description\": \"Don't start PTY until first client connects\",\n          \"type\": \"boolean\"\n        },\n        \"rows\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"PtyCreateResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"sessionId\"],\n      \"properties\": {\n        \"sessionId\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"PtyListResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"sessions\"],\n      \"properties\": {\n        \"sessions\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/PtySessionInfo\"\n          }\n        }\n      }\n    },\n    \"PtyResizeRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"cols\", \"rows\"],\n      \"properties\": {\n        \"cols\": {\n          \"type\": \"integer\",\n          \"maximum\": 1000,\n          \"minimum\": 1\n        },\n        \"rows\": {\n          \"type\": \"integer\",\n          \"maximum\": 1000,\n          \"minimum\": 1\n        }\n      }\n    },\n    \"PtySessionInfo\": {\n      \"type\": \"object\",\n      \"required\": [\"active\", \"cols\", \"createdAt\", \"cwd\", \"envs\", \"id\", \"lazyStart\", \"rows\"],\n      \"properties\": {\n        \"active\": {\n          \"type\": \"boolean\"\n        },\n        \"cols\": {\n          \"type\": \"integer\"\n        },\n        \"createdAt\": {\n          \"type\": \"string\"\n        },\n        \"cwd\": {\n          \"type\": \"string\"\n        },\n        \"envs\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"lazyStart\": {\n          \"description\": \"Whether this session uses lazy start\",\n          \"type\": \"boolean\"\n        },\n        \"rows\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"Recording\": {\n      \"type\": \"object\",\n      \"required\": [\"fileName\", \"filePath\", \"id\", \"startTime\", \"status\"],\n      \"properties\": {\n        \"durationSeconds\": {\n          \"type\": \"number\"\n        },\n        \"endTime\": {\n          \"type\": \"string\"\n        },\n        \"fileName\": {\n          \"type\": \"string\"\n        },\n        \"filePath\": {\n          \"type\": \"string\"\n        },\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"sizeBytes\": {\n          \"type\": \"integer\"\n        },\n        \"startTime\": {\n          \"type\": \"string\"\n        },\n        \"status\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ReplaceRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"files\", \"newValue\", \"pattern\"],\n      \"properties\": {\n        \"files\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"newValue\": {\n          \"type\": \"string\"\n        },\n        \"pattern\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ReplaceResult\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"error\": {\n          \"type\": \"string\"\n        },\n        \"file\": {\n          \"type\": \"string\"\n        },\n        \"success\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"ScreenshotResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cursorPosition\": {\n          \"$ref\": \"#/definitions/Position\"\n        },\n        \"screenshot\": {\n          \"type\": \"string\"\n        },\n        \"sizeBytes\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"ScrollResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"success\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"SearchFilesResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"files\"],\n      \"properties\": {\n        \"files\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        }\n      }\n    },\n    \"Session\": {\n      \"type\": \"object\",\n      \"required\": [\"commands\", \"sessionId\"],\n      \"properties\": {\n        \"commands\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/Command\"\n          }\n        },\n        \"sessionId\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"SessionExecuteRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"command\"],\n      \"properties\": {\n        \"async\": {\n          \"type\": \"boolean\"\n        },\n        \"command\": {\n          \"type\": \"string\"\n        },\n        \"runAsync\": {\n          \"type\": \"boolean\"\n        },\n        \"suppressInputEcho\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"SessionExecuteResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"cmdId\"],\n      \"properties\": {\n        \"cmdId\": {\n          \"type\": \"string\"\n        },\n        \"exitCode\": {\n          \"type\": \"integer\"\n        },\n        \"output\": {\n          \"type\": \"string\"\n        },\n        \"stderr\": {\n          \"type\": \"string\"\n        },\n        \"stdout\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"SessionSendInputRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"data\"],\n      \"properties\": {\n        \"data\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"StartRecordingRequest\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"label\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"Status\": {\n      \"type\": \"string\",\n      \"enum\": [\"Unmodified\", \"Untracked\", \"Modified\", \"Added\", \"Deleted\", \"Renamed\", \"Copied\", \"Updated but unmerged\"],\n      \"x-enum-varnames\": [\n        \"Unmodified\",\n        \"Untracked\",\n        \"Modified\",\n        \"Added\",\n        \"Deleted\",\n        \"Renamed\",\n        \"Copied\",\n        \"UpdatedButUnmerged\"\n      ]\n    },\n    \"StopRecordingRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"id\"],\n      \"properties\": {\n        \"id\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"UserHomeDirResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"dir\"],\n      \"properties\": {\n        \"dir\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"WindowInfo\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"height\": {\n          \"type\": \"integer\"\n        },\n        \"id\": {\n          \"type\": \"integer\"\n        },\n        \"isActive\": {\n          \"type\": \"boolean\"\n        },\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"width\": {\n          \"type\": \"integer\"\n        },\n        \"x\": {\n          \"type\": \"integer\"\n        },\n        \"y\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"WindowsResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"windows\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/WindowInfo\"\n          }\n        }\n      }\n    },\n    \"WorkDirResponse\": {\n      \"type\": \"object\",\n      \"required\": [\"dir\"],\n      \"properties\": {\n        \"dir\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"gin.H\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {}\n    },\n    \"git.GitDeleteBranchRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"name\", \"path\"],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"path\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/docs/swagger.yaml",
    "content": "definitions:\n  Command:\n    properties:\n      command:\n        type: string\n      exitCode:\n        type: integer\n      id:\n        type: string\n    required:\n      - command\n      - id\n    type: object\n  CompletionContext:\n    properties:\n      triggerCharacter:\n        type: string\n      triggerKind:\n        type: integer\n    required:\n      - triggerKind\n    type: object\n  CompletionItem:\n    properties:\n      detail:\n        type: string\n      documentation: {}\n      filterText:\n        type: string\n      insertText:\n        type: string\n      kind:\n        type: integer\n      label:\n        type: string\n      sortText:\n        type: string\n    required:\n      - label\n    type: object\n  CompletionList:\n    properties:\n      isIncomplete:\n        type: boolean\n      items:\n        items:\n          $ref: '#/definitions/CompletionItem'\n        type: array\n    required:\n      - isIncomplete\n      - items\n    type: object\n  ComputerUseStartResponse:\n    properties:\n      message:\n        type: string\n      status:\n        additionalProperties:\n          $ref: '#/definitions/ProcessStatus'\n        type: object\n    type: object\n  ComputerUseStatusResponse:\n    properties:\n      status:\n        type: string\n    type: object\n  ComputerUseStopResponse:\n    properties:\n      message:\n        type: string\n      status:\n        additionalProperties:\n          $ref: '#/definitions/ProcessStatus'\n        type: object\n    type: object\n  CreateContextRequest:\n    properties:\n      cwd:\n        type: string\n      language:\n        type: string\n    type: object\n  CreateSessionRequest:\n    properties:\n      sessionId:\n        type: string\n    required:\n      - sessionId\n    type: object\n  DisplayInfo:\n    properties:\n      height:\n        type: integer\n      id:\n        type: integer\n      isActive:\n        type: boolean\n      width:\n        type: integer\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  DisplayInfoResponse:\n    properties:\n      displays:\n        items:\n          $ref: '#/definitions/DisplayInfo'\n        type: array\n    type: object\n  Empty:\n    type: object\n  ExecuteRequest:\n    properties:\n      command:\n        type: string\n      cwd:\n        description: Current working directory\n        type: string\n      timeout:\n        description: Timeout in seconds, defaults to 10 seconds\n        type: integer\n    required:\n      - command\n    type: object\n  ExecuteResponse:\n    properties:\n      exitCode:\n        type: integer\n      result:\n        type: string\n    required:\n      - result\n    type: object\n  FileInfo:\n    properties:\n      group:\n        type: string\n      isDir:\n        type: boolean\n      modTime:\n        type: string\n      mode:\n        type: string\n      name:\n        type: string\n      owner:\n        type: string\n      permissions:\n        type: string\n      size:\n        type: integer\n    required:\n      - group\n      - isDir\n      - modTime\n      - mode\n      - name\n      - owner\n      - permissions\n      - size\n    type: object\n  FileStatus:\n    properties:\n      extra:\n        type: string\n      name:\n        type: string\n      staging:\n        $ref: '#/definitions/Status'\n      worktree:\n        $ref: '#/definitions/Status'\n    required:\n      - extra\n      - name\n      - staging\n      - worktree\n    type: object\n  FilesDownloadRequest:\n    properties:\n      paths:\n        items:\n          type: string\n        type: array\n    required:\n      - paths\n    type: object\n  GitAddRequest:\n    properties:\n      files:\n        description: files to add (use . for all files)\n        items:\n          type: string\n        type: array\n      path:\n        type: string\n    required:\n      - files\n      - path\n    type: object\n  GitBranchRequest:\n    properties:\n      name:\n        type: string\n      path:\n        type: string\n    required:\n      - name\n      - path\n    type: object\n  GitCheckoutRequest:\n    properties:\n      branch:\n        type: string\n      path:\n        type: string\n    required:\n      - branch\n      - path\n    type: object\n  GitCloneRequest:\n    properties:\n      branch:\n        type: string\n      commit_id:\n        type: string\n      password:\n        type: string\n      path:\n        type: string\n      url:\n        type: string\n      username:\n        type: string\n    required:\n      - path\n      - url\n    type: object\n  GitCommitInfo:\n    properties:\n      author:\n        type: string\n      email:\n        type: string\n      hash:\n        type: string\n      message:\n        type: string\n      timestamp:\n        type: string\n    required:\n      - author\n      - email\n      - hash\n      - message\n      - timestamp\n    type: object\n  GitCommitRequest:\n    properties:\n      allow_empty:\n        type: boolean\n      author:\n        type: string\n      email:\n        type: string\n      message:\n        type: string\n      path:\n        type: string\n    required:\n      - author\n      - email\n      - message\n      - path\n    type: object\n  GitCommitResponse:\n    properties:\n      hash:\n        type: string\n    required:\n      - hash\n    type: object\n  GitRepoRequest:\n    properties:\n      password:\n        type: string\n      path:\n        type: string\n      username:\n        type: string\n    required:\n      - path\n    type: object\n  GitStatus:\n    properties:\n      ahead:\n        type: integer\n      behind:\n        type: integer\n      branchPublished:\n        type: boolean\n      currentBranch:\n        type: string\n      fileStatus:\n        items:\n          $ref: '#/definitions/FileStatus'\n        type: array\n    required:\n      - currentBranch\n      - fileStatus\n    type: object\n  InitializeRequest:\n    properties:\n      token:\n        type: string\n    required:\n      - token\n    type: object\n  InterpreterContext:\n    properties:\n      active:\n        type: boolean\n      createdAt:\n        type: string\n      cwd:\n        type: string\n      id:\n        type: string\n      language:\n        type: string\n    required:\n      - active\n      - createdAt\n      - cwd\n      - id\n      - language\n    type: object\n  IsPortInUseResponse:\n    properties:\n      isInUse:\n        type: boolean\n    type: object\n  KeyboardHotkeyRequest:\n    properties:\n      keys:\n        description: e.g., \"ctrl+c\", \"cmd+v\"\n        type: string\n    type: object\n  KeyboardPressRequest:\n    properties:\n      key:\n        type: string\n      modifiers:\n        description: ctrl, alt, shift, cmd\n        items:\n          type: string\n        type: array\n    type: object\n  KeyboardTypeRequest:\n    properties:\n      delay:\n        description: milliseconds between keystrokes\n        type: integer\n      text:\n        type: string\n    type: object\n  ListBranchResponse:\n    properties:\n      branches:\n        items:\n          type: string\n        type: array\n    required:\n      - branches\n    type: object\n  ListContextsResponse:\n    properties:\n      contexts:\n        items:\n          $ref: '#/definitions/InterpreterContext'\n        type: array\n    required:\n      - contexts\n    type: object\n  ListRecordingsResponse:\n    properties:\n      recordings:\n        items:\n          $ref: '#/definitions/Recording'\n        type: array\n    required:\n      - recordings\n    type: object\n  LspCompletionParams:\n    properties:\n      context:\n        $ref: '#/definitions/CompletionContext'\n      languageId:\n        type: string\n      pathToProject:\n        type: string\n      position:\n        $ref: '#/definitions/LspPosition'\n      uri:\n        type: string\n    required:\n      - languageId\n      - pathToProject\n      - position\n      - uri\n    type: object\n  LspDocumentRequest:\n    properties:\n      languageId:\n        type: string\n      pathToProject:\n        type: string\n      uri:\n        type: string\n    required:\n      - languageId\n      - pathToProject\n      - uri\n    type: object\n  LspLocation:\n    properties:\n      range:\n        $ref: '#/definitions/LspRange'\n      uri:\n        type: string\n    required:\n      - range\n      - uri\n    type: object\n  LspPosition:\n    properties:\n      character:\n        type: integer\n      line:\n        type: integer\n    required:\n      - character\n      - line\n    type: object\n  LspRange:\n    properties:\n      end:\n        $ref: '#/definitions/LspPosition'\n      start:\n        $ref: '#/definitions/LspPosition'\n    required:\n      - end\n      - start\n    type: object\n  LspServerRequest:\n    properties:\n      languageId:\n        type: string\n      pathToProject:\n        type: string\n    required:\n      - languageId\n      - pathToProject\n    type: object\n  LspSymbol:\n    properties:\n      kind:\n        type: integer\n      location:\n        $ref: '#/definitions/LspLocation'\n      name:\n        type: string\n    required:\n      - kind\n      - location\n      - name\n    type: object\n  Match:\n    properties:\n      content:\n        type: string\n      file:\n        type: string\n      line:\n        type: integer\n    required:\n      - content\n      - file\n      - line\n    type: object\n  MouseClickRequest:\n    properties:\n      button:\n        description: left, right, middle\n        type: string\n      double:\n        type: boolean\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  MouseClickResponse:\n    properties:\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  MouseDragRequest:\n    properties:\n      button:\n        type: string\n      endX:\n        type: integer\n      endY:\n        type: integer\n      startX:\n        type: integer\n      startY:\n        type: integer\n    type: object\n  MouseDragResponse:\n    properties:\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  MouseMoveRequest:\n    properties:\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  MousePositionResponse:\n    properties:\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  MouseScrollRequest:\n    properties:\n      amount:\n        type: integer\n      direction:\n        description: up, down\n        type: string\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  PortList:\n    properties:\n      ports:\n        items:\n          type: integer\n        type: array\n    type: object\n  Position:\n    properties:\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  ProcessErrorsResponse:\n    properties:\n      errors:\n        type: string\n      processName:\n        type: string\n    type: object\n  ProcessLogsResponse:\n    properties:\n      logs:\n        type: string\n      processName:\n        type: string\n    type: object\n  ProcessRestartResponse:\n    properties:\n      message:\n        type: string\n      processName:\n        type: string\n    type: object\n  ProcessStatus:\n    properties:\n      autoRestart:\n        type: boolean\n      pid:\n        type: integer\n      priority:\n        type: integer\n      running:\n        type: boolean\n    type: object\n  ProcessStatusResponse:\n    properties:\n      processName:\n        type: string\n      running:\n        type: boolean\n    type: object\n  PtyCreateRequest:\n    properties:\n      cols:\n        type: integer\n      cwd:\n        type: string\n      envs:\n        additionalProperties:\n          type: string\n        type: object\n      id:\n        type: string\n      lazyStart:\n        description: Don't start PTY until first client connects\n        type: boolean\n      rows:\n        type: integer\n    type: object\n  PtyCreateResponse:\n    properties:\n      sessionId:\n        type: string\n    required:\n      - sessionId\n    type: object\n  PtyListResponse:\n    properties:\n      sessions:\n        items:\n          $ref: '#/definitions/PtySessionInfo'\n        type: array\n    required:\n      - sessions\n    type: object\n  PtyResizeRequest:\n    properties:\n      cols:\n        maximum: 1000\n        minimum: 1\n        type: integer\n      rows:\n        maximum: 1000\n        minimum: 1\n        type: integer\n    required:\n      - cols\n      - rows\n    type: object\n  PtySessionInfo:\n    properties:\n      active:\n        type: boolean\n      cols:\n        type: integer\n      createdAt:\n        type: string\n      cwd:\n        type: string\n      envs:\n        additionalProperties:\n          type: string\n        type: object\n      id:\n        type: string\n      lazyStart:\n        description: Whether this session uses lazy start\n        type: boolean\n      rows:\n        type: integer\n    required:\n      - active\n      - cols\n      - createdAt\n      - cwd\n      - envs\n      - id\n      - lazyStart\n      - rows\n    type: object\n  Recording:\n    properties:\n      durationSeconds:\n        type: number\n      endTime:\n        type: string\n      fileName:\n        type: string\n      filePath:\n        type: string\n      id:\n        type: string\n      sizeBytes:\n        type: integer\n      startTime:\n        type: string\n      status:\n        type: string\n    required:\n      - fileName\n      - filePath\n      - id\n      - startTime\n      - status\n    type: object\n  ReplaceRequest:\n    properties:\n      files:\n        items:\n          type: string\n        type: array\n      newValue:\n        type: string\n      pattern:\n        type: string\n    required:\n      - files\n      - newValue\n      - pattern\n    type: object\n  ReplaceResult:\n    properties:\n      error:\n        type: string\n      file:\n        type: string\n      success:\n        type: boolean\n    type: object\n  ScreenshotResponse:\n    properties:\n      cursorPosition:\n        $ref: '#/definitions/Position'\n      screenshot:\n        type: string\n      sizeBytes:\n        type: integer\n    type: object\n  ScrollResponse:\n    properties:\n      success:\n        type: boolean\n    type: object\n  SearchFilesResponse:\n    properties:\n      files:\n        items:\n          type: string\n        type: array\n    required:\n      - files\n    type: object\n  Session:\n    properties:\n      commands:\n        items:\n          $ref: '#/definitions/Command'\n        type: array\n      sessionId:\n        type: string\n    required:\n      - commands\n      - sessionId\n    type: object\n  SessionExecuteRequest:\n    properties:\n      async:\n        type: boolean\n      command:\n        type: string\n      runAsync:\n        type: boolean\n      suppressInputEcho:\n        type: boolean\n    required:\n      - command\n    type: object\n  SessionExecuteResponse:\n    properties:\n      cmdId:\n        type: string\n      exitCode:\n        type: integer\n      output:\n        type: string\n      stderr:\n        type: string\n      stdout:\n        type: string\n    required:\n      - cmdId\n    type: object\n  SessionSendInputRequest:\n    properties:\n      data:\n        type: string\n    required:\n      - data\n    type: object\n  StartRecordingRequest:\n    properties:\n      label:\n        type: string\n    type: object\n  Status:\n    enum:\n      - Unmodified\n      - Untracked\n      - Modified\n      - Added\n      - Deleted\n      - Renamed\n      - Copied\n      - Updated but unmerged\n    type: string\n    x-enum-varnames:\n      - Unmodified\n      - Untracked\n      - Modified\n      - Added\n      - Deleted\n      - Renamed\n      - Copied\n      - UpdatedButUnmerged\n  StopRecordingRequest:\n    properties:\n      id:\n        type: string\n    required:\n      - id\n    type: object\n  UserHomeDirResponse:\n    properties:\n      dir:\n        type: string\n    required:\n      - dir\n    type: object\n  WindowInfo:\n    properties:\n      height:\n        type: integer\n      id:\n        type: integer\n      isActive:\n        type: boolean\n      title:\n        type: string\n      width:\n        type: integer\n      x:\n        type: integer\n      'y':\n        type: integer\n    type: object\n  WindowsResponse:\n    properties:\n      windows:\n        items:\n          $ref: '#/definitions/WindowInfo'\n        type: array\n    type: object\n  WorkDirResponse:\n    properties:\n      dir:\n        type: string\n    required:\n      - dir\n    type: object\n  gin.H:\n    additionalProperties: {}\n    type: object\n  git.GitDeleteBranchRequest:\n    properties:\n      name:\n        type: string\n      path:\n        type: string\n    required:\n      - name\n      - path\n    type: object\ninfo:\n  contact: {}\n  description: Daytona Toolbox API\n  title: Daytona Toolbox API\n  version: v0.0.0-dev\npaths:\n  /computeruse/display/info:\n    get:\n      description: Get information about all available displays\n      operationId: GetDisplayInfo\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/DisplayInfoResponse'\n      summary: Get display information\n      tags:\n        - computer-use\n  /computeruse/display/windows:\n    get:\n      description: Get information about all open windows\n      operationId: GetWindows\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/WindowsResponse'\n      summary: Get windows information\n      tags:\n        - computer-use\n  /computeruse/keyboard/hotkey:\n    post:\n      consumes:\n        - application/json\n      description: Press a hotkey combination (e.g., ctrl+c, cmd+v)\n      operationId: PressHotkey\n      parameters:\n        - description: Hotkey press request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/KeyboardHotkeyRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/Empty'\n      summary: Press hotkey\n      tags:\n        - computer-use\n  /computeruse/keyboard/key:\n    post:\n      consumes:\n        - application/json\n      description: Press a key with optional modifiers\n      operationId: PressKey\n      parameters:\n        - description: Key press request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/KeyboardPressRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/Empty'\n      summary: Press key\n      tags:\n        - computer-use\n  /computeruse/keyboard/type:\n    post:\n      consumes:\n        - application/json\n      description: Type text with optional delay between keystrokes\n      operationId: TypeText\n      parameters:\n        - description: Text typing request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/KeyboardTypeRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/Empty'\n      summary: Type text\n      tags:\n        - computer-use\n  /computeruse/mouse/click:\n    post:\n      consumes:\n        - application/json\n      description: Click the mouse button at the specified coordinates\n      operationId: Click\n      parameters:\n        - description: Mouse click request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/MouseClickRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/MouseClickResponse'\n      summary: Click mouse button\n      tags:\n        - computer-use\n  /computeruse/mouse/drag:\n    post:\n      consumes:\n        - application/json\n      description: Drag the mouse from start to end coordinates\n      operationId: Drag\n      parameters:\n        - description: Mouse drag request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/MouseDragRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/MouseDragResponse'\n      summary: Drag mouse\n      tags:\n        - computer-use\n  /computeruse/mouse/move:\n    post:\n      consumes:\n        - application/json\n      description: Move the mouse cursor to the specified coordinates\n      operationId: MoveMouse\n      parameters:\n        - description: Mouse move request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/MouseMoveRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/MousePositionResponse'\n      summary: Move mouse cursor\n      tags:\n        - computer-use\n  /computeruse/mouse/position:\n    get:\n      description: Get the current mouse cursor position\n      operationId: GetMousePosition\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/MousePositionResponse'\n      summary: Get mouse position\n      tags:\n        - computer-use\n  /computeruse/mouse/scroll:\n    post:\n      consumes:\n        - application/json\n      description: Scroll the mouse wheel at the specified coordinates\n      operationId: Scroll\n      parameters:\n        - description: Mouse scroll request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/MouseScrollRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ScrollResponse'\n      summary: Scroll mouse wheel\n      tags:\n        - computer-use\n  /computeruse/process-status:\n    get:\n      description: Get the status of all computer use processes\n      operationId: GetComputerUseStatus\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ComputerUseStatusResponse'\n      summary: Get computer use process status\n      tags:\n        - computer-use\n  /computeruse/process/{processName}/errors:\n    get:\n      description: Get errors for a specific computer use process\n      operationId: GetProcessErrors\n      parameters:\n        - description: Process name to get errors for\n          in: path\n          name: processName\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ProcessErrorsResponse'\n      summary: Get process errors\n      tags:\n        - computer-use\n  /computeruse/process/{processName}/logs:\n    get:\n      description: Get logs for a specific computer use process\n      operationId: GetProcessLogs\n      parameters:\n        - description: Process name to get logs for\n          in: path\n          name: processName\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ProcessLogsResponse'\n      summary: Get process logs\n      tags:\n        - computer-use\n  /computeruse/process/{processName}/restart:\n    post:\n      description: Restart a specific computer use process\n      operationId: RestartProcess\n      parameters:\n        - description: Process name to restart\n          in: path\n          name: processName\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ProcessRestartResponse'\n      summary: Restart specific process\n      tags:\n        - computer-use\n  /computeruse/process/{processName}/status:\n    get:\n      description: Check if a specific computer use process is running\n      operationId: GetProcessStatus\n      parameters:\n        - description: Process name to check\n          in: path\n          name: processName\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ProcessStatusResponse'\n      summary: Get specific process status\n      tags:\n        - computer-use\n  /computeruse/recordings:\n    get:\n      description: Get a list of all recordings (active and completed)\n      operationId: ListRecordings\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ListRecordingsResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: List all recordings\n      tags:\n        - computer-use\n  /computeruse/recordings/{id}:\n    delete:\n      description: Delete a recording file by ID\n      operationId: DeleteRecording\n      parameters:\n        - description: Recording ID\n          in: path\n          name: id\n          required: true\n          type: string\n      responses:\n        '204':\n          description: No Content\n        '400':\n          description: Bad Request\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '404':\n          description: Not Found\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '500':\n          description: Internal Server Error\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Delete a recording\n      tags:\n        - computer-use\n    get:\n      description: Get details of a specific recording by ID\n      operationId: GetRecording\n      parameters:\n        - description: Recording ID\n          in: path\n          name: id\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/Recording'\n        '404':\n          description: Not Found\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '500':\n          description: Internal Server Error\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Get recording details\n      tags:\n        - computer-use\n  /computeruse/recordings/{id}/download:\n    get:\n      description: Download a recording by providing its ID\n      operationId: DownloadRecording\n      parameters:\n        - description: Recording ID\n          in: path\n          name: id\n          required: true\n          type: string\n      produces:\n        - application/octet-stream\n      responses:\n        '200':\n          description: OK\n          schema:\n            type: file\n        '404':\n          description: Not Found\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '500':\n          description: Internal Server Error\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Download a recording\n      tags:\n        - computer-use\n  /computeruse/recordings/start:\n    post:\n      consumes:\n        - application/json\n      description: Start a new screen recording session\n      operationId: StartRecording\n      parameters:\n        - description: Recording options\n          in: body\n          name: request\n          schema:\n            $ref: '#/definitions/StartRecordingRequest'\n      produces:\n        - application/json\n      responses:\n        '201':\n          description: Created\n          schema:\n            $ref: '#/definitions/Recording'\n        '400':\n          description: Bad Request\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '500':\n          description: Internal Server Error\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Start a new recording\n      tags:\n        - computer-use\n  /computeruse/recordings/stop:\n    post:\n      consumes:\n        - application/json\n      description: Stop an active screen recording session\n      operationId: StopRecording\n      parameters:\n        - description: Recording ID to stop\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/StopRecordingRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/Recording'\n        '400':\n          description: Bad Request\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '404':\n          description: Not Found\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Stop a recording\n      tags:\n        - computer-use\n  /computeruse/screenshot:\n    get:\n      description: Take a screenshot of the entire screen\n      operationId: TakeScreenshot\n      parameters:\n        - description: Whether to show cursor in screenshot\n          in: query\n          name: showCursor\n          type: boolean\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ScreenshotResponse'\n      summary: Take a screenshot\n      tags:\n        - computer-use\n  /computeruse/screenshot/compressed:\n    get:\n      description: Take a compressed screenshot of the entire screen\n      operationId: TakeCompressedScreenshot\n      parameters:\n        - description: Whether to show cursor in screenshot\n          in: query\n          name: showCursor\n          type: boolean\n        - description: Image format (png or jpeg)\n          in: query\n          name: format\n          type: string\n        - description: JPEG quality (1-100)\n          in: query\n          name: quality\n          type: integer\n        - description: Scale factor (0.1-1.0)\n          in: query\n          name: scale\n          type: number\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ScreenshotResponse'\n      summary: Take a compressed screenshot\n      tags:\n        - computer-use\n  /computeruse/screenshot/region:\n    get:\n      description: Take a screenshot of a specific region of the screen\n      operationId: TakeRegionScreenshot\n      parameters:\n        - description: X coordinate of the region\n          in: query\n          name: x\n          required: true\n          type: integer\n        - description: Y coordinate of the region\n          in: query\n          name: 'y'\n          required: true\n          type: integer\n        - description: Width of the region\n          in: query\n          name: width\n          required: true\n          type: integer\n        - description: Height of the region\n          in: query\n          name: height\n          required: true\n          type: integer\n        - description: Whether to show cursor in screenshot\n          in: query\n          name: showCursor\n          type: boolean\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ScreenshotResponse'\n      summary: Take a region screenshot\n      tags:\n        - computer-use\n  /computeruse/screenshot/region/compressed:\n    get:\n      description: Take a compressed screenshot of a specific region of the screen\n      operationId: TakeCompressedRegionScreenshot\n      parameters:\n        - description: X coordinate of the region\n          in: query\n          name: x\n          required: true\n          type: integer\n        - description: Y coordinate of the region\n          in: query\n          name: 'y'\n          required: true\n          type: integer\n        - description: Width of the region\n          in: query\n          name: width\n          required: true\n          type: integer\n        - description: Height of the region\n          in: query\n          name: height\n          required: true\n          type: integer\n        - description: Whether to show cursor in screenshot\n          in: query\n          name: showCursor\n          type: boolean\n        - description: Image format (png or jpeg)\n          in: query\n          name: format\n          type: string\n        - description: JPEG quality (1-100)\n          in: query\n          name: quality\n          type: integer\n        - description: Scale factor (0.1-1.0)\n          in: query\n          name: scale\n          type: number\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ScreenshotResponse'\n      summary: Take a compressed region screenshot\n      tags:\n        - computer-use\n  /computeruse/start:\n    post:\n      description: Start all computer use processes and return their status\n      operationId: StartComputerUse\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ComputerUseStartResponse'\n      summary: Start computer use processes\n      tags:\n        - computer-use\n  /computeruse/status:\n    get:\n      description: Get the current status of the computer use system\n      operationId: GetComputerUseSystemStatus\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ComputerUseStatusResponse'\n      summary: Get computer use status\n      tags:\n        - computer-use\n  /computeruse/stop:\n    post:\n      description: Stop all computer use processes and return their status\n      operationId: StopComputerUse\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ComputerUseStopResponse'\n      summary: Stop computer use processes\n      tags:\n        - computer-use\n  /files:\n    delete:\n      description: Delete a file or directory at the specified path\n      operationId: DeleteFile\n      parameters:\n        - description: File or directory path to delete\n          in: query\n          name: path\n          required: true\n          type: string\n        - description: Enable recursive deletion for directories\n          in: query\n          name: recursive\n          type: boolean\n      responses:\n        '204':\n          description: No Content\n      summary: Delete a file or directory\n      tags:\n        - file-system\n    get:\n      description: List files and directories in the specified path\n      operationId: ListFiles\n      parameters:\n        - description: Directory path to list (defaults to working directory)\n          in: query\n          name: path\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            items:\n              $ref: '#/definitions/FileInfo'\n            type: array\n      summary: List files and directories\n      tags:\n        - file-system\n  /files/bulk-download:\n    post:\n      consumes:\n        - application/json\n      description: Download multiple files by providing their paths\n      operationId: DownloadFiles\n      parameters:\n        - description: Paths of files to download\n          in: body\n          name: downloadFiles\n          required: true\n          schema:\n            $ref: '#/definitions/FilesDownloadRequest'\n      produces:\n        - multipart/form-data\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/gin.H'\n      summary: Download multiple files\n      tags:\n        - file-system\n  /files/bulk-upload:\n    post:\n      consumes:\n        - multipart/form-data\n      description: Upload multiple files with their destination paths\n      operationId: UploadFiles\n      responses:\n        '200':\n          description: OK\n      summary: Upload multiple files\n      tags:\n        - file-system\n  /files/download:\n    get:\n      description: Download a file by providing its path\n      operationId: DownloadFile\n      parameters:\n        - description: File path to download\n          in: query\n          name: path\n          required: true\n          type: string\n      produces:\n        - application/octet-stream\n      responses:\n        '200':\n          description: OK\n          schema:\n            type: file\n      summary: Download a file\n      tags:\n        - file-system\n  /files/find:\n    get:\n      description: Search for text pattern within files in a directory\n      operationId: FindInFiles\n      parameters:\n        - description: Directory path to search in\n          in: query\n          name: path\n          required: true\n          type: string\n        - description: Text pattern to search for\n          in: query\n          name: pattern\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            items:\n              $ref: '#/definitions/Match'\n            type: array\n      summary: Find text in files\n      tags:\n        - file-system\n  /files/folder:\n    post:\n      consumes:\n        - application/json\n      description: Create a folder with the specified path and optional permissions\n      operationId: CreateFolder\n      parameters:\n        - description: Folder path to create\n          in: query\n          name: path\n          required: true\n          type: string\n        - description: 'Octal permission mode (default: 0755)'\n          in: query\n          name: mode\n          required: true\n          type: string\n      responses:\n        '201':\n          description: Created\n      summary: Create a folder\n      tags:\n        - file-system\n  /files/info:\n    get:\n      description: Get detailed information about a file or directory\n      operationId: GetFileInfo\n      parameters:\n        - description: File or directory path\n          in: query\n          name: path\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/FileInfo'\n      summary: Get file information\n      tags:\n        - file-system\n  /files/move:\n    post:\n      description: Move or rename a file or directory from source to destination\n      operationId: MoveFile\n      parameters:\n        - description: Source file or directory path\n          in: query\n          name: source\n          required: true\n          type: string\n        - description: Destination file or directory path\n          in: query\n          name: destination\n          required: true\n          type: string\n      responses:\n        '200':\n          description: OK\n      summary: Move or rename file/directory\n      tags:\n        - file-system\n  /files/permissions:\n    post:\n      description: Set file permissions, ownership, and group for a file or directory\n      operationId: SetFilePermissions\n      parameters:\n        - description: File or directory path\n          in: query\n          name: path\n          required: true\n          type: string\n        - description: Owner (username or UID)\n          in: query\n          name: owner\n          type: string\n        - description: Group (group name or GID)\n          in: query\n          name: group\n          type: string\n        - description: File mode in octal format (e.g., 0755)\n          in: query\n          name: mode\n          type: string\n      responses:\n        '200':\n          description: OK\n      summary: Set file permissions\n      tags:\n        - file-system\n  /files/replace:\n    post:\n      consumes:\n        - application/json\n      description: Replace text pattern with new value in multiple files\n      operationId: ReplaceInFiles\n      parameters:\n        - description: Replace request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/ReplaceRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            items:\n              $ref: '#/definitions/ReplaceResult'\n            type: array\n      summary: Replace text in files\n      tags:\n        - file-system\n  /files/search:\n    get:\n      description: Search for files matching a specific pattern in a directory\n      operationId: SearchFiles\n      parameters:\n        - description: Directory path to search in\n          in: query\n          name: path\n          required: true\n          type: string\n        - description: File pattern to match (e.g., *.txt, *.go)\n          in: query\n          name: pattern\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/SearchFilesResponse'\n      summary: Search files by pattern\n      tags:\n        - file-system\n  /files/upload:\n    post:\n      consumes:\n        - multipart/form-data\n      description: Upload a file to the specified path\n      operationId: UploadFile\n      parameters:\n        - description: Destination path for the uploaded file\n          in: query\n          name: path\n          required: true\n          type: string\n        - description: File to upload\n          in: formData\n          name: file\n          required: true\n          type: file\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/gin.H'\n      summary: Upload a file\n      tags:\n        - file-system\n  /git/add:\n    post:\n      consumes:\n        - application/json\n      description: Add files to the Git staging area\n      operationId: AddFiles\n      parameters:\n        - description: Add files request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/GitAddRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Add files to Git staging\n      tags:\n        - git\n  /git/branches:\n    delete:\n      consumes:\n        - application/json\n      description: Delete a branch from the Git repository\n      operationId: DeleteBranch\n      parameters:\n        - description: Delete branch request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/git.GitDeleteBranchRequest'\n      produces:\n        - application/json\n      responses:\n        '204':\n          description: No Content\n      summary: Delete a branch\n      tags:\n        - git\n    get:\n      description: Get a list of all branches in the Git repository\n      operationId: ListBranches\n      parameters:\n        - description: Repository path\n          in: query\n          name: path\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ListBranchResponse'\n      summary: List branches\n      tags:\n        - git\n    post:\n      consumes:\n        - application/json\n      description: Create a new branch in the Git repository\n      operationId: CreateBranch\n      parameters:\n        - description: Create branch request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/GitBranchRequest'\n      produces:\n        - application/json\n      responses:\n        '201':\n          description: Created\n      summary: Create a new branch\n      tags:\n        - git\n  /git/checkout:\n    post:\n      consumes:\n        - application/json\n      description: Switch to a different branch or commit in the Git repository\n      operationId: CheckoutBranch\n      parameters:\n        - description: Checkout request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/GitCheckoutRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Checkout branch or commit\n      tags:\n        - git\n  /git/clone:\n    post:\n      consumes:\n        - application/json\n      description: Clone a Git repository to the specified path\n      operationId: CloneRepository\n      parameters:\n        - description: Clone repository request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/GitCloneRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Clone a Git repository\n      tags:\n        - git\n  /git/commit:\n    post:\n      consumes:\n        - application/json\n      description: Commit staged changes to the Git repository\n      operationId: CommitChanges\n      parameters:\n        - description: Commit request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/GitCommitRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/GitCommitResponse'\n      summary: Commit changes\n      tags:\n        - git\n  /git/history:\n    get:\n      description: Get the commit history of the Git repository\n      operationId: GetCommitHistory\n      parameters:\n        - description: Repository path\n          in: query\n          name: path\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            items:\n              $ref: '#/definitions/GitCommitInfo'\n            type: array\n      summary: Get commit history\n      tags:\n        - git\n  /git/pull:\n    post:\n      consumes:\n        - application/json\n      description: Pull changes from the remote Git repository\n      operationId: PullChanges\n      parameters:\n        - description: Pull request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/GitRepoRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Pull changes from remote\n      tags:\n        - git\n  /git/push:\n    post:\n      consumes:\n        - application/json\n      description: Push local changes to the remote Git repository\n      operationId: PushChanges\n      parameters:\n        - description: Push request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/GitRepoRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Push changes to remote\n      tags:\n        - git\n  /git/status:\n    get:\n      description: Get the Git status of the repository at the specified path\n      operationId: GetStatus\n      parameters:\n        - description: Repository path\n          in: query\n          name: path\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/GitStatus'\n      summary: Get Git status\n      tags:\n        - git\n  /init:\n    post:\n      description: Set the auth token and initialize telemetry for the toolbox server\n      operationId: Initialize\n      parameters:\n        - description: Initialization request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/InitializeRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Initialize toolbox server\n      tags:\n        - server\n  /lsp/completions:\n    post:\n      consumes:\n        - application/json\n      description: Get code completion suggestions from the LSP server\n      operationId: Completions\n      parameters:\n        - description: Completion request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/LspCompletionParams'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/CompletionList'\n      summary: Get code completions\n      tags:\n        - lsp\n  /lsp/did-close:\n    post:\n      consumes:\n        - application/json\n      description: Notify the LSP server that a document has been closed\n      operationId: DidClose\n      parameters:\n        - description: Document request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/LspDocumentRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Notify document closed\n      tags:\n        - lsp\n  /lsp/did-open:\n    post:\n      consumes:\n        - application/json\n      description: Notify the LSP server that a document has been opened\n      operationId: DidOpen\n      parameters:\n        - description: Document request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/LspDocumentRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Notify document opened\n      tags:\n        - lsp\n  /lsp/document-symbols:\n    get:\n      description: Get symbols (functions, classes, etc.) from a document\n      operationId: DocumentSymbols\n      parameters:\n        - description: Language ID (e.g., python, typescript)\n          in: query\n          name: languageId\n          required: true\n          type: string\n        - description: Path to project\n          in: query\n          name: pathToProject\n          required: true\n          type: string\n        - description: Document URI\n          in: query\n          name: uri\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            items:\n              $ref: '#/definitions/LspSymbol'\n            type: array\n      summary: Get document symbols\n      tags:\n        - lsp\n  /lsp/start:\n    post:\n      consumes:\n        - application/json\n      description: Start a Language Server Protocol server for the specified language\n      operationId: Start\n      parameters:\n        - description: LSP server request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/LspServerRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Start LSP server\n      tags:\n        - lsp\n  /lsp/stop:\n    post:\n      consumes:\n        - application/json\n      description: Stop a Language Server Protocol server\n      operationId: Stop\n      parameters:\n        - description: LSP server request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/LspServerRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n      summary: Stop LSP server\n      tags:\n        - lsp\n  /lsp/workspacesymbols:\n    get:\n      description: Search for symbols across the entire workspace\n      operationId: WorkspaceSymbols\n      parameters:\n        - description: Search query\n          in: query\n          name: query\n          required: true\n          type: string\n        - description: Language ID (e.g., python, typescript)\n          in: query\n          name: languageId\n          required: true\n          type: string\n        - description: Path to project\n          in: query\n          name: pathToProject\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            items:\n              $ref: '#/definitions/LspSymbol'\n            type: array\n      summary: Get workspace symbols\n      tags:\n        - lsp\n  /port:\n    get:\n      description: Get a list of all currently active ports\n      operationId: GetPorts\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/PortList'\n      summary: Get active ports\n      tags:\n        - port\n  /port/{port}/in-use:\n    get:\n      description: Check if a specific port is currently in use\n      operationId: IsPortInUse\n      parameters:\n        - description: Port number (3000-9999)\n          in: path\n          name: port\n          required: true\n          type: integer\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/IsPortInUseResponse'\n      summary: Check if port is in use\n      tags:\n        - port\n  /process/execute:\n    post:\n      consumes:\n        - application/json\n      description: Execute a shell command and return the output and exit code\n      operationId: ExecuteCommand\n      parameters:\n        - description: Command execution request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/ExecuteRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ExecuteResponse'\n      summary: Execute a command\n      tags:\n        - process\n  /process/interpreter/context:\n    get:\n      description: Returns information about all user-created interpreter contexts\n        (excludes default context)\n      operationId: ListInterpreterContexts\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/ListContextsResponse'\n      summary: List all user-created interpreter contexts\n      tags:\n        - interpreter\n    post:\n      consumes:\n        - application/json\n      description: Creates a new isolated interpreter context with optional working\n        directory and language\n      operationId: CreateInterpreterContext\n      parameters:\n        - description: Context configuration\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/CreateContextRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/InterpreterContext'\n        '400':\n          description: Bad Request\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '500':\n          description: Internal Server Error\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Create a new interpreter context\n      tags:\n        - interpreter\n  /process/interpreter/context/{id}:\n    delete:\n      description: Deletes an interpreter context and shuts down its worker process\n      operationId: DeleteInterpreterContext\n      parameters:\n        - description: Context ID\n          in: path\n          name: id\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '400':\n          description: Bad Request\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n        '404':\n          description: Not Found\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Delete an interpreter context\n      tags:\n        - interpreter\n  /process/interpreter/execute:\n    get:\n      consumes:\n        - application/json\n      description: Executes code in a specified context (or default context if not\n        specified) via WebSocket streaming\n      operationId: ExecuteInterpreterCode\n      produces:\n        - application/json\n      responses:\n        '101':\n          description: Switching Protocols\n          headers:\n            Connection:\n              description: Upgrade\n              type: string\n            Upgrade:\n              description: websocket\n              type: string\n          schema:\n            type: string\n      summary: Execute code in an interpreter context\n      tags:\n        - interpreter\n  /process/pty:\n    get:\n      description: Get a list of all active pseudo-terminal sessions\n      operationId: ListPtySessions\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/PtyListResponse'\n      summary: List all PTY sessions\n      tags:\n        - process\n    post:\n      consumes:\n        - application/json\n      description: Create a new pseudo-terminal session with specified configuration\n      operationId: CreatePtySession\n      parameters:\n        - description: PTY session creation request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/PtyCreateRequest'\n      produces:\n        - application/json\n      responses:\n        '201':\n          description: Created\n          schema:\n            $ref: '#/definitions/PtyCreateResponse'\n      summary: Create a new PTY session\n      tags:\n        - process\n  /process/pty/{sessionId}:\n    delete:\n      description: Delete a pseudo-terminal session and terminate its process\n      operationId: DeletePtySession\n      parameters:\n        - description: PTY session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/gin.H'\n      summary: Delete a PTY session\n      tags:\n        - process\n    get:\n      description: Get detailed information about a specific pseudo-terminal session\n      operationId: GetPtySession\n      parameters:\n        - description: PTY session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/PtySessionInfo'\n      summary: Get PTY session information\n      tags:\n        - process\n  /process/pty/{sessionId}/connect:\n    get:\n      description: Establish a WebSocket connection to interact with a pseudo-terminal\n        session\n      operationId: ConnectPtySession\n      parameters:\n        - description: PTY session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n      responses:\n        '101':\n          description: Switching Protocols - WebSocket connection established\n      summary: Connect to PTY session via WebSocket\n      tags:\n        - process\n  /process/pty/{sessionId}/resize:\n    post:\n      consumes:\n        - application/json\n      description: Resize the terminal dimensions of a pseudo-terminal session\n      operationId: ResizePtySession\n      parameters:\n        - description: PTY session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n        - description: Resize request with new dimensions\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/PtyResizeRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/PtySessionInfo'\n      summary: Resize a PTY session\n      tags:\n        - process\n  /process/session:\n    get:\n      description: Get a list of all active shell sessions\n      operationId: ListSessions\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            items:\n              $ref: '#/definitions/Session'\n            type: array\n      summary: List all sessions\n      tags:\n        - process\n    post:\n      consumes:\n        - application/json\n      description: Create a new shell session for command execution\n      operationId: CreateSession\n      parameters:\n        - description: Session creation request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/CreateSessionRequest'\n      produces:\n        - application/json\n      responses:\n        '201':\n          description: Created\n      summary: Create a new session\n      tags:\n        - process\n  /process/session/{sessionId}:\n    delete:\n      description: Delete an existing shell session\n      operationId: DeleteSession\n      parameters:\n        - description: Session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n      responses:\n        '204':\n          description: No Content\n      summary: Delete a session\n      tags:\n        - process\n    get:\n      description: Get details of a specific session including its commands\n      operationId: GetSession\n      parameters:\n        - description: Session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/Session'\n      summary: Get session details\n      tags:\n        - process\n  /process/session/{sessionId}/command/{commandId}:\n    get:\n      description: Get details of a specific command within a session\n      operationId: GetSessionCommand\n      parameters:\n        - description: Session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n        - description: Command ID\n          in: path\n          name: commandId\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/Command'\n      summary: Get session command details\n      tags:\n        - process\n  /process/session/{sessionId}/command/{commandId}/input:\n    post:\n      consumes:\n        - application/json\n      description: Send input data to a running command in a session for interactive\n        execution\n      operationId: SendInput\n      parameters:\n        - description: Session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n        - description: Command ID\n          in: path\n          name: commandId\n          required: true\n          type: string\n        - description: Input send request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/SessionSendInputRequest'\n      responses:\n        '204':\n          description: No Content\n      summary: Send input to command\n      tags:\n        - process\n  /process/session/{sessionId}/command/{commandId}/logs:\n    get:\n      description: Get logs for a specific command within a session. Supports both\n        HTTP and WebSocket streaming.\n      operationId: GetSessionCommandLogs\n      parameters:\n        - description: Session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n        - description: Command ID\n          in: path\n          name: commandId\n          required: true\n          type: string\n        - description: Follow logs in real-time (WebSocket only)\n          in: query\n          name: follow\n          type: boolean\n      produces:\n        - text/plain\n      responses:\n        '200':\n          description: Log content\n          schema:\n            type: string\n      summary: Get session command logs\n      tags:\n        - process\n  /process/session/{sessionId}/exec:\n    post:\n      consumes:\n        - application/json\n      description: Execute a command within an existing shell session\n      operationId: SessionExecuteCommand\n      parameters:\n        - description: Session ID\n          in: path\n          name: sessionId\n          required: true\n          type: string\n        - description: Command execution request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/SessionExecuteRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/SessionExecuteResponse'\n        '202':\n          description: Accepted\n          schema:\n            $ref: '#/definitions/SessionExecuteResponse'\n      summary: Execute command in session\n      tags:\n        - process\n  /process/session/entrypoint:\n    get:\n      description: Get details of an entrypoint session including its commands\n      operationId: GetEntrypointSession\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/Session'\n      summary: Get entrypoint session details\n      tags:\n        - process\n  /process/session/entrypoint/logs:\n    get:\n      description: Get logs for a sandbox entrypoint session. Supports both HTTP and\n        WebSocket streaming.\n      operationId: GetEntrypointLogs\n      parameters:\n        - description: Follow logs in real-time (WebSocket only)\n          in: query\n          name: follow\n          type: boolean\n      produces:\n        - text/plain\n      responses:\n        '200':\n          description: Entrypoint log content\n          schema:\n            type: string\n      summary: Get entrypoint logs\n      tags:\n        - process\n  /user-home-dir:\n    get:\n      description: Get the current user home directory path.\n      operationId: GetUserHomeDir\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/UserHomeDirResponse'\n      summary: Get user home directory\n      tags:\n        - info\n  /version:\n    get:\n      description: Get the current daemon version\n      operationId: GetVersion\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Get version\n      tags:\n        - info\n  /work-dir:\n    get:\n      description: Get the current working directory path. This is default directory\n        used for running commands.\n      operationId: GetWorkDir\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/WorkDirResponse'\n      summary: Get working directory\n      tags:\n        - info\nswagger: '2.0'\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/create_folder.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// CreateFolder godoc\n//\n//\t@Summary\t\tCreate a folder\n//\t@Description\tCreate a folder with the specified path and optional permissions\n//\t@Tags\t\t\tfile-system\n//\t@Accept\t\t\tjson\n//\t@Param\t\t\tpath\tquery\tstring\ttrue\t\"Folder path to create\"\n//\t@Param\t\t\tmode\tquery\tstring\ttrue\t\"Octal permission mode (default: 0755)\"\n//\t@Success\t\t201\n//\t@Router\t\t\t/files/folder [post]\n//\n//\t@id\t\t\t\tCreateFolder\nfunc CreateFolder(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tif path == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\t// Get the permission mode from query params, default to 0755\n\tmode := c.Query(\"mode\")\n\tvar perm os.FileMode = 0755\n\tif mode != \"\" {\n\t\tmodeNum, err := strconv.ParseUint(mode, 8, 32)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"invalid mode format\"))\n\t\t\treturn\n\t\t}\n\t\tperm = os.FileMode(modeNum)\n\t}\n\n\tif err := os.MkdirAll(path, perm); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusCreated)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/delete_file.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// DeleteFile godoc\n//\n//\t@Summary\t\tDelete a file or directory\n//\t@Description\tDelete a file or directory at the specified path\n//\t@Tags\t\t\tfile-system\n//\t@Param\t\t\tpath\t\tquery\tstring\ttrue\t\"File or directory path to delete\"\n//\t@Param\t\t\trecursive\tquery\tboolean\tfalse\t\"Enable recursive deletion for directories\"\n//\t@Success\t\t204\n//\t@Router\t\t\t/files [delete]\n//\n//\t@id\t\t\t\tDeleteFile\nfunc DeleteFile(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tif path == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\t// Check if recursive deletion is requested\n\trecursive := c.Query(\"recursive\") == \"true\"\n\n\t// Get file info to check if it's a directory\n\tinfo, err := os.Stat(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tc.AbortWithError(http.StatusNotFound, err)\n\t\t\treturn\n\t\t}\n\t\tif os.IsPermission(err) {\n\t\t\tc.AbortWithError(http.StatusForbidden, err)\n\t\t\treturn\n\t\t}\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\t// If it's a directory and recursive flag is not set, return error\n\tif info.IsDir() && !recursive {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"cannot delete directory without recursive flag\"))\n\t\treturn\n\t}\n\n\tvar deleteErr error\n\tif recursive {\n\t\tdeleteErr = os.RemoveAll(path)\n\t} else {\n\t\tdeleteErr = os.Remove(path)\n\t}\n\n\tif deleteErr != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, deleteErr)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusNoContent)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/download_file.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// DownloadFile godoc\n//\n//\t@Summary\t\tDownload a file\n//\t@Description\tDownload a file by providing its path\n//\t@Tags\t\t\tfile-system\n//\t@Produce\t\toctet-stream\n//\t@Param\t\t\tpath\tquery\tstring\ttrue\t\"File path to download\"\n//\t@Success\t\t200\t\t{file}\tbinary\n//\t@Router\t\t\t/files/download [get]\n//\n//\t@id\t\t\t\tDownloadFile\nfunc DownloadFile(c *gin.Context) {\n\trequestedPath := c.Query(\"path\")\n\tif requestedPath == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\tabsPath, err := filepath.Abs(requestedPath)\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid path: %w\", err))\n\t\treturn\n\t}\n\n\tfileInfo, err := os.Stat(absPath)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tc.AbortWithError(http.StatusNotFound, err)\n\t\t\treturn\n\t\t}\n\t\tif os.IsPermission(err) {\n\t\t\tc.AbortWithError(http.StatusForbidden, err)\n\t\t\treturn\n\t\t}\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tif fileInfo.IsDir() {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path must be a file\"))\n\t\treturn\n\t}\n\n\tc.Header(\"Content-Description\", \"File Transfer\")\n\tc.Header(\"Content-Type\", \"application/octet-stream\")\n\tc.Header(\"Content-Disposition\", \"attachment; filename=\"+filepath.Base(absPath))\n\tc.Header(\"Content-Transfer-Encoding\", \"binary\")\n\tc.Header(\"Expires\", \"0\")\n\tc.Header(\"Cache-Control\", \"must-revalidate\")\n\tc.Header(\"Pragma\", \"public\")\n\n\tc.File(absPath)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/download_files.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"mime\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"net/textproto\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// Wraps an io.Writer and aborts writes if the context is canceled.\ntype ctxWriter struct {\n\tctx context.Context\n\tw   io.Writer\n}\n\nfunc (cw *ctxWriter) Write(p []byte) (int, error) {\n\tselect {\n\tcase <-cw.ctx.Done():\n\t\treturn 0, cw.ctx.Err()\n\tdefault:\n\t}\n\treturn cw.w.Write(p)\n}\n\n// DownloadFiles godoc\n//\n//\t@Summary\t\tDownload multiple files\n//\t@Description\tDownload multiple files by providing their paths\n//\t@Tags\t\t\tfile-system\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tmultipart/form-data\n//\t@Param\t\t\tdownloadFiles\tbody\t\tFilesDownloadRequest\ttrue\t\"Paths of files to download\"\n//\t@Success\t\t200\t\t\t\t{object}\tgin.H\n//\t@Router\t\t\t/files/bulk-download [post]\n//\n//\t@id\t\t\t\tDownloadFiles\nfunc DownloadFiles(c *gin.Context) {\n\tvar req FilesDownloadRequest\n\tif err := c.BindJSON(&req); err != nil || len(req.Paths) == 0 {\n\t\tc.AbortWithStatusJSON(http.StatusBadRequest, gin.H{\n\t\t\t\"error\": \"request body must be {\\\"paths\\\": [ ... ]} and non-empty\",\n\t\t})\n\t\treturn\n\t}\n\n\tconst boundary = \"DAYTONA-FILE-BOUNDARY\"\n\tc.Status(http.StatusOK)\n\tc.Header(\"Content-Type\", fmt.Sprintf(\"multipart/form-data; boundary=%s\", boundary))\n\n\tmw := multipart.NewWriter(c.Writer)\n\tif err := mw.SetBoundary(boundary); err != nil {\n\t\tc.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{\n\t\t\t\"error\": \"failed to set multipart boundary\",\n\t\t})\n\t\treturn\n\t}\n\tdefer mw.Close() // ensure final boundary is written\n\n\tfor _, path := range req.Paths {\n\t\tif !fileExists(path) {\n\t\t\twriteErrorPart(c, mw, path, fmt.Sprintf(\"file not found or invalid: %s\", path))\n\t\t\tcontinue\n\t\t}\n\n\t\tf, err := os.Open(path)\n\t\tif err != nil {\n\t\t\twriteErrorPart(c, mw, path, fmt.Sprintf(\"error opening file: %v\", err))\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := writeFilePart(c.Request.Context(), mw, path, f); err != nil {\n\t\t\twriteErrorPart(c, mw, path,\n\t\t\t\tfmt.Sprintf(\"error streaming file: %v\", err))\n\t\t}\n\t\tf.Close()\n\t}\n}\n\n// Streams a file part using io.Copy and respects context cancellation.\nfunc writeFilePart(ctx context.Context, mw *multipart.Writer, path string, r io.Reader) error {\n\tctype := mime.TypeByExtension(filepath.Ext(path))\n\tif ctype == \"\" {\n\t\tctype = \"application/octet-stream\"\n\t}\n\n\thdr := textproto.MIMEHeader{}\n\thdr.Set(\"Content-Type\", ctype)\n\thdr.Set(\"Content-Disposition\",\n\t\tfmt.Sprintf(`form-data; name=\"%s\"; filename=\"%s\"`, \"file\", path),\n\t)\n\n\tpart, err := mw.CreatePart(hdr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Wrap part with context-aware writer\n\tcw := &ctxWriter{ctx: ctx, w: part}\n\t_, err = io.Copy(cw, r)\n\treturn err\n}\n\n// Writes an error message as a multipart part.\nfunc writeErrorPart(ctx *gin.Context, mw *multipart.Writer, path, text string) {\n\thdr := textproto.MIMEHeader{}\n\thdr.Set(\"Content-Type\", \"text/plain; charset=utf-8\")\n\thdr.Set(\"Content-Disposition\",\n\t\tfmt.Sprintf(`form-data; name=\"%s\"; filename=\"%s\"`, \"error\", path),\n\t)\n\tif part, err := mw.CreatePart(hdr); err == nil {\n\t\t_, err := io.WriteString(part, text)\n\t\tif err != nil {\n\t\t\tctx.AbortWithError(http.StatusInternalServerError, err)\n\t\t}\n\t}\n}\n\nfunc fileExists(path string) bool {\n\tinfo, err := os.Stat(path)\n\treturn err == nil && !info.IsDir()\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/find_in_files.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// FindInFiles godoc\n//\n//\t@Summary\t\tFind text in files\n//\t@Description\tSearch for text pattern within files in a directory\n//\t@Tags\t\t\tfile-system\n//\t@Produce\t\tjson\n//\t@Param\t\t\tpath\tquery\tstring\ttrue\t\"Directory path to search in\"\n//\t@Param\t\t\tpattern\tquery\tstring\ttrue\t\"Text pattern to search for\"\n//\t@Success\t\t200\t\t{array}\tMatch\n//\t@Router\t\t\t/files/find [get]\n//\n//\t@id\t\t\t\tFindInFiles\nfunc FindInFiles(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tpattern := c.Query(\"pattern\")\n\tif path == \"\" || pattern == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path and pattern are required\"))\n\t\treturn\n\t}\n\n\tvar matches = make([]Match, 0)\n\terr := filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn filepath.SkipDir\n\t\t}\n\n\t\tif !info.Mode().IsRegular() {\n\t\t\treturn nil\n\t\t}\n\n\t\tfile, err := os.Open(filePath)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tdefer file.Close()\n\n\t\tbuf := make([]byte, 512)\n\t\tn, err := file.Read(buf)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tfor i := 0; i < n; i++ {\n\t\t\t// skip binary files\n\t\t\tif buf[i] == 0 {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\n\t\t_, err = file.Seek(0, 0)\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tscanner := bufio.NewScanner(file)\n\t\tlineNum := 1\n\t\tfor scanner.Scan() {\n\t\t\tif strings.Contains(scanner.Text(), pattern) {\n\t\t\t\tmatches = append(matches, Match{\n\t\t\t\t\tFile:    filePath,\n\t\t\t\t\tLine:    lineNum,\n\t\t\t\t\tContent: scanner.Text(),\n\t\t\t\t})\n\t\t\t}\n\t\t\tlineNum++\n\t\t}\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, matches)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/get_file_info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"syscall\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// GetFileInfo godoc\n//\n//\t@Summary\t\tGet file information\n//\t@Description\tGet detailed information about a file or directory\n//\t@Tags\t\t\tfile-system\n//\t@Produce\t\tjson\n//\t@Param\t\t\tpath\tquery\t\tstring\ttrue\t\"File or directory path\"\n//\t@Success\t\t200\t\t{object}\tFileInfo\n//\t@Router\t\t\t/files/info [get]\n//\n//\t@id\t\t\t\tGetFileInfo\nfunc GetFileInfo(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tif path == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\tinfo, err := getFileInfo(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tc.AbortWithError(http.StatusNotFound, err)\n\t\t\treturn\n\t\t}\n\t\tif os.IsPermission(err) {\n\t\t\tc.AbortWithError(http.StatusForbidden, err)\n\t\t\treturn\n\t\t}\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, info)\n}\n\nfunc getFileInfo(path string) (FileInfo, error) {\n\tinfo, err := os.Stat(path)\n\tif err != nil {\n\t\treturn FileInfo{}, err\n\t}\n\n\tstat := info.Sys().(*syscall.Stat_t)\n\treturn FileInfo{\n\t\tName:        info.Name(),\n\t\tSize:        info.Size(),\n\t\tMode:        info.Mode().String(),\n\t\tModTime:     info.ModTime().String(),\n\t\tIsDir:       info.IsDir(),\n\t\tOwner:       strconv.FormatUint(uint64(stat.Uid), 10),\n\t\tGroup:       strconv.FormatUint(uint64(stat.Gid), 10),\n\t\tPermissions: fmt.Sprintf(\"%04o\", info.Mode().Perm()),\n\t}, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/list_files.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// ListFiles godoc\n//\n//\t@Summary\t\tList files and directories\n//\t@Description\tList files and directories in the specified path\n//\t@Tags\t\t\tfile-system\n//\t@Produce\t\tjson\n//\t@Param\t\t\tpath\tquery\tstring\tfalse\t\"Directory path to list (defaults to working directory)\"\n//\t@Success\t\t200\t\t{array}\tFileInfo\n//\t@Router\t\t\t/files [get]\n//\n//\t@id\t\t\t\tListFiles\nfunc ListFiles(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tif path == \"\" {\n\t\tpath = \".\"\n\t}\n\n\tfiles, err := os.ReadDir(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tc.AbortWithError(http.StatusNotFound, err)\n\t\t\treturn\n\t\t}\n\t\tif os.IsPermission(err) {\n\t\t\tc.AbortWithError(http.StatusForbidden, err)\n\t\t\treturn\n\t\t}\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tvar fileInfos = make([]FileInfo, 0)\n\tfor _, file := range files {\n\t\tinfo, err := getFileInfo(filepath.Join(path, file.Name()))\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tfileInfos = append(fileInfos, info)\n\t}\n\n\tc.JSON(http.StatusOK, fileInfos)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/move_file.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// MoveFile godoc\n//\n//\t@Summary\t\tMove or rename file/directory\n//\t@Description\tMove or rename a file or directory from source to destination\n//\t@Tags\t\t\tfile-system\n//\t@Param\t\t\tsource\t\tquery\tstring\ttrue\t\"Source file or directory path\"\n//\t@Param\t\t\tdestination\tquery\tstring\ttrue\t\"Destination file or directory path\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/files/move [post]\n//\n//\t@id\t\t\t\tMoveFile\nfunc MoveFile(c *gin.Context) {\n\tsourcePath := c.Query(\"source\")\n\tdestPath := c.Query(\"destination\")\n\n\tif sourcePath == \"\" || destPath == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"source and destination paths are required\"))\n\t\treturn\n\t}\n\n\t// Get absolute paths\n\tabsSourcePath, err := filepath.Abs(sourcePath)\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"invalid source path\"))\n\t\treturn\n\t}\n\n\tabsDestPath, err := filepath.Abs(destPath)\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"invalid destination path\"))\n\t\treturn\n\t}\n\n\t// Check if source exists\n\tsourceInfo, err := os.Stat(absSourcePath)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tc.AbortWithError(http.StatusNotFound, err)\n\t\t\treturn\n\t\t}\n\t\tif os.IsPermission(err) {\n\t\t\tc.AbortWithError(http.StatusForbidden, err)\n\t\t\treturn\n\t\t}\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\t// Check if destination parent directory exists\n\tdestDir := filepath.Dir(absDestPath)\n\t_, err = os.Stat(destDir)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tc.AbortWithError(http.StatusNotFound, err)\n\t\t\treturn\n\t\t}\n\t\tif os.IsPermission(err) {\n\t\t\tc.AbortWithError(http.StatusForbidden, err)\n\t\t\treturn\n\t\t}\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\t// Check if destination already exists\n\tif _, err := os.Stat(absDestPath); err == nil {\n\t\tc.AbortWithError(http.StatusConflict, errors.New(\"destination already exists\"))\n\t\treturn\n\t}\n\n\t// Perform the move operation\n\terr = os.Rename(absSourcePath, absDestPath)\n\tif err != nil {\n\t\t// If rename fails (e.g., across different devices), try copy and delete\n\t\tif err := copyFile(absSourcePath, absDestPath, sourceInfo); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"failed to move file: %w\", err))\n\t\t\treturn\n\t\t}\n\n\t\t// If copy successful, delete the source\n\t\tif err := os.RemoveAll(absSourcePath); err != nil {\n\t\t\t// If delete fails, inform that the file was copied but not deleted\n\t\t\tc.JSON(http.StatusOK, gin.H{\n\t\t\t\t\"message\": \"file copied successfully but source could not be deleted\",\n\t\t\t\t\"error\":   fmt.Sprintf(\"failed to delete source: %v\", err),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t}\n\n\tc.Status(http.StatusOK)\n}\n\nfunc copyFile(src, dst string, srcInfo os.FileInfo) error {\n\tif srcInfo.IsDir() {\n\t\treturn filepath.Walk(src, func(path string, info os.FileInfo, err error) error {\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Create relative path\n\t\t\trelPath, err := filepath.Rel(src, path)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\ttargetPath := filepath.Join(dst, relPath)\n\n\t\t\tif info.IsDir() {\n\t\t\t\treturn os.MkdirAll(targetPath, info.Mode())\n\t\t\t}\n\n\t\t\t// Copy the file\n\t\t\treturn copyFileContents(path, targetPath, info.Mode())\n\t\t})\n\t}\n\treturn copyFileContents(src, dst, srcInfo.Mode())\n}\n\nfunc copyFileContents(src, dst string, mode os.FileMode) error {\n\tin, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer in.Close()\n\n\tout, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer out.Close()\n\n\t_, err = bufio.NewReader(in).WriteTo(out)\n\treturn err\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/replace_in_files.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// ReplaceInFiles godoc\n//\n//\t@Summary\t\tReplace text in files\n//\t@Description\tReplace text pattern with new value in multiple files\n//\t@Tags\t\t\tfile-system\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tReplaceRequest\ttrue\t\"Replace request\"\n//\t@Success\t\t200\t\t{array}\tReplaceResult\n//\t@Router\t\t\t/files/replace [post]\n//\n//\t@id\t\t\t\tReplaceInFiles\nfunc ReplaceInFiles(c *gin.Context) {\n\tvar req ReplaceRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tresults := make([]ReplaceResult, 0, len(req.Files))\n\n\tfor _, filePath := range req.Files {\n\t\tcontent, err := os.ReadFile(filePath)\n\t\tif err != nil {\n\t\t\tresults = append(results, ReplaceResult{\n\t\t\t\tFile:    filePath,\n\t\t\t\tSuccess: false,\n\t\t\t\tError:   err.Error(),\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tnewValue := \"\"\n\t\tif req.NewValue != nil {\n\t\t\tnewValue = *req.NewValue\n\t\t}\n\n\t\tnewContent := strings.ReplaceAll(string(content), req.Pattern, newValue)\n\n\t\terr = os.WriteFile(filePath, []byte(newContent), 0644)\n\t\tif err != nil {\n\t\t\tresults = append(results, ReplaceResult{\n\t\t\t\tFile:    filePath,\n\t\t\t\tSuccess: false,\n\t\t\t\tError:   err.Error(),\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tresults = append(results, ReplaceResult{\n\t\t\tFile:    filePath,\n\t\t\tSuccess: true,\n\t\t})\n\t}\n\n\tc.JSON(http.StatusOK, results)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/search_files.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// SearchFiles godoc\n//\n//\t@Summary\t\tSearch files by pattern\n//\t@Description\tSearch for files matching a specific pattern in a directory\n//\t@Tags\t\t\tfile-system\n//\t@Produce\t\tjson\n//\t@Param\t\t\tpath\tquery\t\tstring\ttrue\t\"Directory path to search in\"\n//\t@Param\t\t\tpattern\tquery\t\tstring\ttrue\t\"File pattern to match (e.g., *.txt, *.go)\"\n//\t@Success\t\t200\t\t{object}\tSearchFilesResponse\n//\t@Router\t\t\t/files/search [get]\n//\n//\t@id\t\t\t\tSearchFiles\nfunc SearchFiles(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tpattern := c.Query(\"pattern\")\n\tif path == \"\" || pattern == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path and pattern are required\"))\n\t\treturn\n\t}\n\n\tvar matches []string\n\terr := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn filepath.SkipDir\n\t\t}\n\t\tif matched, _ := filepath.Match(pattern, info.Name()); matched {\n\t\t\tmatches = append(matches, path)\n\t\t}\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, SearchFilesResponse{\n\t\tFiles: matches,\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/set_file_permissions.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/user\"\n\t\"path/filepath\"\n\t\"strconv\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// SetFilePermissions godoc\n//\n//\t@Summary\t\tSet file permissions\n//\t@Description\tSet file permissions, ownership, and group for a file or directory\n//\t@Tags\t\t\tfile-system\n//\t@Param\t\t\tpath\tquery\tstring\ttrue\t\"File or directory path\"\n//\t@Param\t\t\towner\tquery\tstring\tfalse\t\"Owner (username or UID)\"\n//\t@Param\t\t\tgroup\tquery\tstring\tfalse\t\"Group (group name or GID)\"\n//\t@Param\t\t\tmode\tquery\tstring\tfalse\t\"File mode in octal format (e.g., 0755)\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/files/permissions [post]\n//\n//\t@id\t\t\t\tSetFilePermissions\nfunc SetFilePermissions(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\townerParam := c.Query(\"owner\")\n\tgroupParam := c.Query(\"group\")\n\tmode := c.Query(\"mode\")\n\n\tif path == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\t// convert to absolute path and check existence\n\tabsPath, err := filepath.Abs(path)\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"invalid path\"))\n\t\treturn\n\t}\n\n\t_, err = os.Stat(absPath)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tc.AbortWithError(http.StatusNotFound, err)\n\t\t\treturn\n\t\t}\n\t\tif os.IsPermission(err) {\n\t\t\tc.AbortWithError(http.StatusForbidden, err)\n\t\t\treturn\n\t\t}\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\t// handle mode change\n\tif mode != \"\" {\n\t\tmodeNum, err := strconv.ParseUint(mode, 8, 32)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"invalid mode format\"))\n\t\t\treturn\n\t\t}\n\n\t\tif err := os.Chmod(absPath, os.FileMode(modeNum)); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"failed to change mode: %w\", err))\n\t\t\treturn\n\t\t}\n\t}\n\n\t// handle ownership change\n\tif ownerParam != \"\" || groupParam != \"\" {\n\t\tuid := -1\n\t\tgid := -1\n\n\t\t// resolve owner\n\t\tif ownerParam != \"\" {\n\t\t\t// first try as numeric UID\n\t\t\tif uidNum, err := strconv.Atoi(ownerParam); err == nil {\n\t\t\t\tuid = uidNum\n\t\t\t} else {\n\t\t\t\t// try as username\n\t\t\t\tif u, err := user.Lookup(ownerParam); err == nil {\n\t\t\t\t\tif uid, err = strconv.Atoi(u.Uid); err != nil {\n\t\t\t\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"invalid user ID\"))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"user not found\"))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// resolve group\n\t\tif groupParam != \"\" {\n\t\t\t// first try as numeric GID\n\t\t\tif gidNum, err := strconv.Atoi(groupParam); err == nil {\n\t\t\t\tgid = gidNum\n\t\t\t} else {\n\t\t\t\t// try as group name\n\t\t\t\tif g, err := user.LookupGroup(groupParam); err == nil {\n\t\t\t\t\tif gid, err = strconv.Atoi(g.Gid); err != nil {\n\t\t\t\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"invalid group ID\"))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"group not found\"))\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif err := os.Chown(absPath, uid, gid); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"failed to change ownership: %w\", err))\n\t\t\treturn\n\t\t}\n\t}\n\n\tc.Status(http.StatusOK)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\ntype FileInfo struct {\n\tName        string `json:\"name\" validate:\"required\"`\n\tSize        int64  `json:\"size\" validate:\"required\"`\n\tMode        string `json:\"mode\" validate:\"required\"`\n\tModTime     string `json:\"modTime\" validate:\"required\"`\n\tIsDir       bool   `json:\"isDir\" validate:\"required\"`\n\tOwner       string `json:\"owner\" validate:\"required\"`\n\tGroup       string `json:\"group\" validate:\"required\"`\n\tPermissions string `json:\"permissions\" validate:\"required\"`\n} // @name FileInfo\n\ntype ReplaceRequest struct {\n\tFiles    []string `json:\"files\" validate:\"required\"`\n\tPattern  string   `json:\"pattern\" validate:\"required\"`\n\tNewValue *string  `json:\"newValue\" validate:\"required\"`\n} // @name ReplaceRequest\n\ntype ReplaceResult struct {\n\tFile    string `json:\"file\"`\n\tSuccess bool   `json:\"success\"`\n\tError   string `json:\"error,omitempty\"`\n} // @name ReplaceResult\n\ntype Match struct {\n\tFile    string `json:\"file\" validate:\"required\"`\n\tLine    int    `json:\"line\" validate:\"required\"`\n\tContent string `json:\"content\" validate:\"required\"`\n} // @name Match\n\ntype SearchFilesResponse struct {\n\tFiles []string `json:\"files\" validate:\"required\"`\n} // @name SearchFilesResponse\n\ntype FilesDownloadRequest struct {\n\tPaths []string `json:\"paths\" validate:\"required\"`\n} // @name FilesDownloadRequest\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/upload_file.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// UploadFile godoc\n//\n//\t@Summary\t\tUpload a file\n//\t@Description\tUpload a file to the specified path\n//\t@Tags\t\t\tfile-system\n//\t@Accept\t\t\tmultipart/form-data\n//\t@Param\t\t\tpath\tquery\t\tstring\ttrue\t\"Destination path for the uploaded file\"\n//\t@Param\t\t\tfile\tformData\tfile\ttrue\t\"File to upload\"\n//\t@Success\t\t200\t\t{object}\tgin.H\n//\t@Router\t\t\t/files/upload [post]\n//\n//\t@id\t\t\t\tUploadFile\nfunc UploadFile(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tif path == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\tfile, err := c.FormFile(\"file\")\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tif err := c.SaveUploadedFile(file, path); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusOK)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/fs/upload_files.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage fs\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// UploadFiles godoc\n//\n//\t@Summary\t\tUpload multiple files\n//\t@Description\tUpload multiple files with their destination paths\n//\t@Tags\t\t\tfile-system\n//\t@Accept\t\t\tmultipart/form-data\n//\t@Success\t\t200\n//\t@Router\t\t\t/files/bulk-upload [post]\n//\n//\t@id\t\t\t\tUploadFiles\nfunc UploadFiles(c *gin.Context) {\n\treader, err := c.Request.MultipartReader()\n\tif err != nil {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"errors\": []string{\"invalid multipart form\"}})\n\t\treturn\n\t}\n\n\tdests := make(map[string]string)\n\tvar errs []string\n\n\tfor {\n\t\tpart, err := reader.NextPart()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\terrs = append(errs, fmt.Sprintf(\"reading part: %v\", err))\n\t\t\tcontinue\n\t\t}\n\n\t\tname := part.FormName()\n\n\t\tif strings.HasSuffix(name, \".path\") {\n\t\t\tdata, err := io.ReadAll(part)\n\t\t\tif err != nil {\n\t\t\t\tidx := extractIndex(name)\n\t\t\t\terrs = append(errs, fmt.Sprintf(\"path[%s]: %v\", idx, err))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tidx := extractIndex(name)\n\t\t\tdests[idx] = string(data)\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.HasSuffix(name, \".file\") {\n\t\t\tidx := extractIndex(name)\n\t\t\tdest, ok := dests[idx]\n\t\t\tif !ok {\n\t\t\t\terrs = append(errs, fmt.Sprintf(\"file[%s]: missing .path metadata\", idx))\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif d := filepath.Dir(dest); d != \"\" {\n\t\t\t\tif err := os.MkdirAll(d, 0o755); err != nil {\n\t\t\t\t\terrs = append(errs, fmt.Sprintf(\"%s: mkdir %s: %v\", dest, d, err))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tf, err := os.Create(dest)\n\t\t\tif err != nil {\n\t\t\t\terrs = append(errs, fmt.Sprintf(\"%s: create: %v\", dest, err))\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif _, err := io.Copy(f, part); err != nil {\n\t\t\t\terrs = append(errs, fmt.Sprintf(\"%s: write: %v\", dest, err))\n\t\t\t}\n\t\t\tf.Close()\n\t\t\tcontinue\n\t\t}\n\t}\n\n\tif len(errs) > 0 {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"errors\": errs})\n\t\treturn\n\t}\n\n\tc.Status(http.StatusOK)\n}\n\nfunc extractIndex(fieldName string) string {\n\ts := strings.TrimPrefix(fieldName, \"files[\")\n\treturn strings.TrimSuffix(strings.TrimSuffix(s, \"].path\"), \"].file\")\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/add.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// AddFiles godoc\n//\n//\t@Summary\t\tAdd files to Git staging\n//\t@Description\tAdd files to the Git staging area\n//\t@Tags\t\t\tgit\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tGitAddRequest\ttrue\t\"Add files request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/git/add [post]\n//\n//\t@id\t\t\t\tAddFiles\nfunc AddFiles(c *gin.Context) {\n\tvar req GitAddRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: req.Path,\n\t}\n\n\tif err := gitService.Add(req.Files); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusOK)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/checkout.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// CheckoutBranch godoc\n//\n//\t@Summary\t\tCheckout branch or commit\n//\t@Description\tSwitch to a different branch or commit in the Git repository\n//\t@Tags\t\t\tgit\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tGitCheckoutRequest\ttrue\t\"Checkout request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/git/checkout [post]\n//\n//\t@id\t\t\t\tCheckoutBranch\nfunc CheckoutBranch(c *gin.Context) {\n\tvar req GitCheckoutRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: req.Path,\n\t}\n\n\tif err := gitService.Checkout(req.Branch); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusOK)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/clone_repository.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/daytonaio/daemon/pkg/gitprovider\"\n\t\"github.com/gin-gonic/gin\"\n\tgo_git_http \"github.com/go-git/go-git/v5/plumbing/transport/http\"\n)\n\n// CloneRepository godoc\n//\n//\t@Summary\t\tClone a Git repository\n//\t@Description\tClone a Git repository to the specified path\n//\t@Tags\t\t\tgit\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tGitCloneRequest\ttrue\t\"Clone repository request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/git/clone [post]\n//\n//\t@id\t\t\t\tCloneRepository\nfunc CloneRepository(c *gin.Context) {\n\tvar req GitCloneRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tbranch := \"\"\n\tif req.Branch != nil {\n\t\tbranch = *req.Branch\n\t}\n\n\trepo := gitprovider.GitRepository{\n\t\tUrl:    req.URL,\n\t\tBranch: branch,\n\t}\n\n\tif req.CommitID != nil {\n\t\trepo.Target = gitprovider.CloneTargetCommit\n\t\trepo.Sha = *req.CommitID\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: req.Path,\n\t}\n\n\tvar auth *go_git_http.BasicAuth\n\n\t// Set authentication if provided\n\tif req.Username != nil && req.Password != nil {\n\t\tauth = &go_git_http.BasicAuth{\n\t\t\tUsername: *req.Username,\n\t\t\tPassword: *req.Password,\n\t\t}\n\t}\n\n\terr := gitService.CloneRepository(&repo, auth)\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusOK)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/commit.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n\tgo_git \"github.com/go-git/go-git/v5\"\n\t\"github.com/go-git/go-git/v5/plumbing/object\"\n)\n\n// CommitChanges godoc\n//\n//\t@Summary\t\tCommit changes\n//\t@Description\tCommit staged changes to the Git repository\n//\t@Tags\t\t\tgit\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tGitCommitRequest\ttrue\t\"Commit request\"\n//\t@Success\t\t200\t\t{object}\tGitCommitResponse\n//\t@Router\t\t\t/git/commit [post]\n//\n//\t@id\t\t\t\tCommitChanges\nfunc CommitChanges(c *gin.Context) {\n\tvar req GitCommitRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: req.Path,\n\t}\n\n\tcommitSha, err := gitService.Commit(req.Message, &go_git.CommitOptions{\n\t\tAuthor: &object.Signature{\n\t\t\tName:  req.Author,\n\t\t\tEmail: req.Email,\n\t\t\tWhen:  time.Now(),\n\t\t},\n\t\tAllowEmptyCommits: req.AllowEmpty,\n\t})\n\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, GitCommitResponse{\n\t\tHash: commitSha,\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/create_branch.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// CreateBranch godoc\n//\n//\t@Summary\t\tCreate a new branch\n//\t@Description\tCreate a new branch in the Git repository\n//\t@Tags\t\t\tgit\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tGitBranchRequest\ttrue\t\"Create branch request\"\n//\t@Success\t\t201\n//\t@Router\t\t\t/git/branches [post]\n//\n//\t@id\t\t\t\tCreateBranch\nfunc CreateBranch(c *gin.Context) {\n\tvar req GitBranchRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: req.Path,\n\t}\n\n\tif err := gitService.CreateBranch(req.Name); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusCreated)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/delete_branch.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// DeleteBranch godoc\n//\n//\t@Summary\t\tDelete a branch\n//\t@Description\tDelete a branch from the Git repository\n//\t@Tags\t\t\tgit\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tGitDeleteBranchRequest\ttrue\t\"Delete branch request\"\n//\t@Success\t\t204\n//\t@Router\t\t\t/git/branches [delete]\n//\n//\t@id\t\t\t\tDeleteBranch\nfunc DeleteBranch(c *gin.Context) {\n\tvar req GitDeleteBranchRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: req.Path,\n\t}\n\n\tif err := gitService.DeleteBranch(req.Name); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusNoContent)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/history.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// GetCommitHistory godoc\n//\n//\t@Summary\t\tGet commit history\n//\t@Description\tGet the commit history of the Git repository\n//\t@Tags\t\t\tgit\n//\t@Produce\t\tjson\n//\t@Param\t\t\tpath\tquery\tstring\ttrue\t\"Repository path\"\n//\t@Success\t\t200\t\t{array}\tgit.GitCommitInfo\n//\t@Router\t\t\t/git/history [get]\n//\n//\t@id\t\t\t\tGetCommitHistory\nfunc GetCommitHistory(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tif path == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: path,\n\t}\n\n\tlog, err := gitService.Log()\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, log)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/list_branches.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// ListBranches godoc\n//\n//\t@Summary\t\tList branches\n//\t@Description\tGet a list of all branches in the Git repository\n//\t@Tags\t\t\tgit\n//\t@Produce\t\tjson\n//\t@Param\t\t\tpath\tquery\t\tstring\ttrue\t\"Repository path\"\n//\t@Success\t\t200\t\t{object}\tListBranchResponse\n//\t@Router\t\t\t/git/branches [get]\n//\n//\t@id\t\t\t\tListBranches\nfunc ListBranches(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tif path == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: path,\n\t}\n\n\tbranchList, err := gitService.ListBranches()\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, ListBranchResponse{\n\t\tBranches: branchList,\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/pull.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n\tgo_git \"github.com/go-git/go-git/v5\"\n\tgo_git_http \"github.com/go-git/go-git/v5/plumbing/transport/http\"\n)\n\n// PullChanges godoc\n//\n//\t@Summary\t\tPull changes from remote\n//\t@Description\tPull changes from the remote Git repository\n//\t@Tags\t\t\tgit\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tGitRepoRequest\ttrue\t\"Pull request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/git/pull [post]\n//\n//\t@id\t\t\t\tPullChanges\nfunc PullChanges(c *gin.Context) {\n\tvar req GitRepoRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tvar auth *go_git_http.BasicAuth\n\tif req.Username != nil && req.Password != nil {\n\t\tauth = &go_git_http.BasicAuth{\n\t\t\tUsername: *req.Username,\n\t\t\tPassword: *req.Password,\n\t\t}\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: req.Path,\n\t}\n\n\terr := gitService.Pull(auth)\n\tif err != nil && err != go_git.NoErrAlreadyUpToDate {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusOK)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/push.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n\tgo_git \"github.com/go-git/go-git/v5\"\n\tgo_git_http \"github.com/go-git/go-git/v5/plumbing/transport/http\"\n)\n\n// PushChanges godoc\n//\n//\t@Summary\t\tPush changes to remote\n//\t@Description\tPush local changes to the remote Git repository\n//\t@Tags\t\t\tgit\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tGitRepoRequest\ttrue\t\"Push request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/git/push [post]\n//\n//\t@id\t\t\t\tPushChanges\nfunc PushChanges(c *gin.Context) {\n\tvar req GitRepoRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\tvar auth *go_git_http.BasicAuth\n\tif req.Username != nil && req.Password != nil {\n\t\tauth = &go_git_http.BasicAuth{\n\t\t\tUsername: *req.Username,\n\t\t\tPassword: *req.Password,\n\t\t}\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: req.Path,\n\t}\n\n\terr := gitService.Push(auth)\n\tif err != nil && err != go_git.NoErrAlreadyUpToDate {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusOK)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/status.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/pkg/git\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// GetStatus godoc\n//\n//\t@Summary\t\tGet Git status\n//\t@Description\tGet the Git status of the repository at the specified path\n//\t@Tags\t\t\tgit\n//\t@Produce\t\tjson\n//\t@Param\t\t\tpath\tquery\t\tstring\ttrue\t\"Repository path\"\n//\t@Success\t\t200\t\t{object}\tgit.GitStatus\n//\t@Router\t\t\t/git/status [get]\n//\n//\t@id\t\t\t\tGetStatus\nfunc GetStatus(c *gin.Context) {\n\tpath := c.Query(\"path\")\n\tif path == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"path is required\"))\n\t\treturn\n\t}\n\n\tgitService := git.Service{\n\t\tWorkDir: path,\n\t}\n\n\tstatus, err := gitService.GetGitStatus()\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, status)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/git/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage git\n\ntype GitAddRequest struct {\n\tPath string `json:\"path\" validate:\"required\"`\n\t// files to add (use . for all files)\n\tFiles []string `json:\"files\" validate:\"required\"`\n} // @name GitAddRequest\n\ntype GitCloneRequest struct {\n\tURL      string  `json:\"url\" validate:\"required\"`\n\tPath     string  `json:\"path\" validate:\"required\"`\n\tUsername *string `json:\"username,omitempty\" validate:\"optional\"`\n\tPassword *string `json:\"password,omitempty\" validate:\"optional\"`\n\tBranch   *string `json:\"branch,omitempty\" validate:\"optional\"`\n\tCommitID *string `json:\"commit_id,omitempty\" validate:\"optional\"`\n} // @name GitCloneRequest\n\ntype GitCommitRequest struct {\n\tPath       string `json:\"path\" validate:\"required\"`\n\tMessage    string `json:\"message\" validate:\"required\"`\n\tAuthor     string `json:\"author\" validate:\"required\"`\n\tEmail      string `json:\"email\" validate:\"required\"`\n\tAllowEmpty bool   `json:\"allow_empty,omitempty\"`\n} // @name GitCommitRequest\n\ntype GitCommitResponse struct {\n\tHash string `json:\"hash\" validate:\"required\"`\n} // @name GitCommitResponse\n\ntype GitBranchRequest struct {\n\tPath string `json:\"path\" validate:\"required\"`\n\tName string `json:\"name\" validate:\"required\"`\n} // @name GitBranchRequest\n\ntype GitDeleteBranchRequest struct {\n\tPath string `json:\"path\" validate:\"required\"`\n\tName string `json:\"name\" validate:\"required\"`\n}\n\ntype ListBranchResponse struct {\n\tBranches []string `json:\"branches\" validate:\"required\"`\n} // @name ListBranchResponse\n\ntype GitRepoRequest struct {\n\tPath     string  `json:\"path\" validate:\"required\"`\n\tUsername *string `json:\"username,omitempty\" validate:\"optional\"`\n\tPassword *string `json:\"password,omitempty\" validate:\"optional\"`\n} // @name GitRepoRequest\n\ntype GitCheckoutRequest struct {\n\tPath   string `json:\"path\" validate:\"required\"`\n\tBranch string `json:\"branch\" validate:\"required\"`\n} // @name GitCheckoutRequest\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/lsp/client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage lsp\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.com/sourcegraph/jsonrpc2\"\n)\n\ntype Client struct {\n\tconn *jsonrpc2.Conn\n}\n\ntype InitializeParams struct {\n\tProcessID    int                `json:\"processId\"`\n\tClientInfo   ClientInfo         `json:\"clientInfo\"`\n\tRootURI      string             `json:\"rootUri\"`\n\tCapabilities ClientCapabilities `json:\"capabilities\"`\n}\n\ntype ClientInfo struct {\n\tName    string `json:\"name\"`\n\tVersion string `json:\"version\"`\n}\n\ntype ClientCapabilities struct {\n\tTextDocument TextDocumentClientCapabilities `json:\"textDocument\"`\n\tWorkspace    WorkspaceClientCapabilities    `json:\"workspace\"`\n}\n\ntype TextDocumentClientCapabilities struct {\n\tCompletion     CompletionClientCapabilities     `json:\"completion\"`\n\tDocumentSymbol DocumentSymbolClientCapabilities `json:\"documentSymbol\"`\n}\n\ntype CompletionClientCapabilities struct {\n\tDynamicRegistration bool                       `json:\"dynamicRegistration\"`\n\tCompletionItem      CompletionItemCapabilities `json:\"completionItem\"`\n\tContextSupport      bool                       `json:\"contextSupport\"`\n}\n\ntype CompletionItemCapabilities struct {\n\tSnippetSupport          bool     `json:\"snippetSupport\"`\n\tCommitCharactersSupport bool     `json:\"commitCharactersSupport\"`\n\tDocumentationFormat     []string `json:\"documentationFormat\"`\n\tDeprecatedSupport       bool     `json:\"deprecatedSupport\"`\n\tPreselectSupport        bool     `json:\"preselectSupport\"`\n}\n\ntype DocumentSymbolClientCapabilities struct {\n\tDynamicRegistration bool           `json:\"dynamicRegistration\"`\n\tSymbolKind          SymbolKindInfo `json:\"symbolKind\"`\n}\n\ntype SymbolKindInfo struct {\n\tValueSet []int `json:\"valueSet\"`\n}\n\ntype WorkspaceClientCapabilities struct {\n\tSymbol WorkspaceSymbolClientCapabilities `json:\"symbol\"`\n}\n\ntype WorkspaceSymbolClientCapabilities struct {\n\tDynamicRegistration bool `json:\"dynamicRegistration\"`\n}\n\ntype StdioStream struct {\n\tcmd *exec.Cmd\n\tin  io.WriteCloser\n\tout io.ReadCloser\n}\n\ntype Range struct {\n\tStart LspPosition `json:\"start\" validate:\"required\"`\n\tEnd   LspPosition `json:\"end\" validate:\"required\"`\n} // @name Range\n\ntype TextDocumentIdentifier struct {\n\tURI string `json:\"uri\" validate:\"required\"`\n}\n\ntype VersionedTextDocumentIdentifier struct {\n\tURI     string `json:\"uri\" validate:\"required\"`\n\tVersion int    `json:\"version\" validate:\"required\"`\n} // @name VersionedTextDocumentIdentifier\n\ntype CompletionParams struct {\n\tTextDocument TextDocumentIdentifier `json:\"textDocument\" validate:\"required\"`\n\tPosition     LspPosition            `json:\"position\" validate:\"required\"`\n\tContext      *CompletionContext     `json:\"context,omitempty\" validate:\"optional\"`\n} // @name CompletionParams\n\ntype CompletionContext struct {\n\tTriggerKind      int     `json:\"triggerKind\" validate:\"required\"`\n\tTriggerCharacter *string `json:\"triggerCharacter,omitempty\" validate:\"optional\"`\n} // @name CompletionContext\n\ntype CompletionItem struct {\n\tLabel         string      `json:\"label\" validate:\"required\"`\n\tKind          *int        `json:\"kind,omitempty\" validate:\"optional\"`\n\tDetail        *string     `json:\"detail,omitempty\" validate:\"optional\"`\n\tDocumentation interface{} `json:\"documentation,omitempty\" validate:\"optional\"`\n\tSortText      *string     `json:\"sortText,omitempty\" validate:\"optional\"`\n\tFilterText    *string     `json:\"filterText,omitempty\" validate:\"optional\"`\n\tInsertText    *string     `json:\"insertText,omitempty\" validate:\"optional\"`\n} // @name CompletionItem\n\ntype CompletionList struct {\n\tIsIncomplete bool             `json:\"isIncomplete\" validate:\"required\"`\n\tItems        []CompletionItem `json:\"items\" validate:\"required\"`\n} // @name CompletionList\n\ntype LspSymbol struct {\n\tKind     int         `json:\"kind\" validate:\"required\"`\n\tLocation LspLocation `json:\"location\" validate:\"required\"`\n\tName     string      `json:\"name\" validate:\"required\"`\n} // @name LspSymbol\n\ntype LspLocation struct {\n\tRange LspRange `json:\"range\" validate:\"required\"`\n\tURI   string   `json:\"uri\" validate:\"required\"`\n} // @name LspLocation\n\ntype LspRange struct {\n\tEnd   LspPosition `json:\"end\" validate:\"required\"`\n\tStart LspPosition `json:\"start\" validate:\"required\"`\n} // @name LspRange\n\ntype LspPosition struct {\n\tCharacter int `json:\"character\" validate:\"required\"`\n\tLine      int `json:\"line\" validate:\"required\"`\n} // @name LspPosition\n\ntype WorkspaceSymbolParams struct {\n\tQuery string `json:\"query\" validate:\"required\"`\n} // @name WorkspaceSymbolParams\n\nfunc (s *StdioStream) Read(p []byte) (n int, err error) {\n\treturn s.out.Read(p)\n}\n\nfunc (s *StdioStream) Write(p []byte) (n int, err error) {\n\treturn s.in.Write(p)\n}\n\nfunc (s *StdioStream) Close() error {\n\tif err := s.in.Close(); err != nil {\n\t\treturn err\n\t}\n\treturn s.out.Close()\n}\n\nfunc NewStdioStream(cmd *exec.Cmd) (*StdioStream, error) {\n\tstdin, err := cmd.StdinPipe()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &StdioStream{\n\t\tcmd: cmd,\n\t\tin:  stdin,\n\t\tout: stdout,\n\t}, nil\n}\n\nfunc (c *Client) NotifyDidClose(ctx context.Context, uri string) error {\n\tparams := map[string]interface{}{\n\t\t\"textDocument\": map[string]interface{}{\n\t\t\t\"uri\": uri,\n\t\t},\n\t}\n\n\treturn c.conn.Notify(ctx, \"textDocument/didClose\", params)\n}\n\nfunc (c *Client) GetWorkspaceSymbols(ctx context.Context, query string) ([]LspSymbol, error) {\n\tparams := map[string]interface{}{\n\t\t\"query\": query,\n\t}\n\n\tvar symbols []LspSymbol\n\terr := c.conn.Call(ctx, \"workspace/symbol\", params, &symbols)\n\treturn symbols, err\n}\n\nfunc (c *Client) GetCompletion(ctx context.Context, uri string, position LspPosition, context *CompletionContext) (*CompletionList, error) {\n\tparams := CompletionParams{\n\t\tTextDocument: TextDocumentIdentifier{\n\t\t\tURI: uri,\n\t\t},\n\t\tPosition: position,\n\t\tContext:  context,\n\t}\n\n\tvar result interface{}\n\tif err := c.conn.Call(ctx, \"textDocument/completion\", params, &result); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Handle both possible response types: CompletionList or []CompletionItem\n\tvar completionList CompletionList\n\tswitch v := result.(type) {\n\tcase map[string]interface{}:\n\t\t// It's a CompletionList\n\t\tif items, ok := v[\"items\"].([]interface{}); ok {\n\t\t\tcompletionItems := make([]CompletionItem, 0, len(items))\n\t\t\tfor _, item := range items {\n\t\t\t\tif itemMap, ok := item.(map[string]interface{}); ok {\n\t\t\t\t\tcompletionItems = append(completionItems, parseCompletionItem(itemMap))\n\t\t\t\t}\n\t\t\t}\n\t\t\tcompletionList.Items = completionItems\n\t\t\tcompletionList.IsIncomplete = v[\"isIncomplete\"].(bool)\n\t\t}\n\tcase []interface{}:\n\t\t// It's an array of CompletionItems\n\t\tcompletionItems := make([]CompletionItem, 0, len(v))\n\t\tfor _, item := range v {\n\t\t\tif itemMap, ok := item.(map[string]interface{}); ok {\n\t\t\t\tcompletionItems = append(completionItems, parseCompletionItem(itemMap))\n\t\t\t}\n\t\t}\n\t\tcompletionList.Items = completionItems\n\t}\n\n\treturn &completionList, nil\n}\n\nfunc (c *Client) DidOpen(ctx context.Context, uri string, languageId string) error {\n\tpath := strings.TrimPrefix(uri, \"file://\")\n\n\tcontent, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read file: %w\", err)\n\t}\n\n\tparams := map[string]interface{}{\n\t\t\"textDocument\": map[string]interface{}{\n\t\t\t\"uri\":        uri,\n\t\t\t\"languageId\": languageId,\n\t\t\t\"version\":    1,\n\t\t\t\"text\":       string(content),\n\t\t},\n\t}\n\n\treturn c.conn.Notify(ctx, \"textDocument/didOpen\", params)\n}\n\nfunc (c *Client) GetDocumentSymbols(ctx context.Context, uri string) ([]LspSymbol, error) {\n\tparams := map[string]interface{}{\n\t\t\"textDocument\": map[string]interface{}{\n\t\t\t\"uri\": uri,\n\t\t},\n\t}\n\n\tvar symbols []LspSymbol\n\terr := c.conn.Call(ctx, \"textDocument/documentSymbol\", params, &symbols)\n\treturn symbols, err\n}\n\nfunc parseCompletionItem(item map[string]interface{}) CompletionItem {\n\tci := CompletionItem{\n\t\tLabel: item[\"label\"].(string),\n\t}\n\n\tif kind, ok := item[\"kind\"].(float64); ok {\n\t\tk := int(kind)\n\t\tci.Kind = &k\n\t}\n\n\tif detail, ok := item[\"detail\"].(string); ok {\n\t\tci.Detail = &detail\n\t}\n\n\tif sortText, ok := item[\"sortText\"].(string); ok {\n\t\tci.SortText = &sortText\n\t}\n\n\tif filterText, ok := item[\"filterText\"].(string); ok {\n\t\tci.FilterText = &filterText\n\t}\n\n\tif insertText, ok := item[\"insertText\"].(string); ok {\n\t\tci.InsertText = &insertText\n\t}\n\n\tci.Documentation = item[\"documentation\"]\n\n\treturn ci\n}\n\nfunc (c *Client) Initialize(ctx context.Context, params InitializeParams) error {\n\tvar result interface{}\n\tif err := c.conn.Call(ctx, \"initialize\", params, &result); err != nil {\n\t\treturn err\n\t}\n\n\treturn c.conn.Notify(ctx, \"initialized\", nil)\n}\n\nfunc (c *Client) Shutdown(ctx context.Context) error {\n\treturn c.conn.Notify(ctx, \"shutdown\", nil)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/lsp/lsp.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage lsp\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// Start godoc\n//\n//\t@Summary\t\tStart LSP server\n//\t@Description\tStart a Language Server Protocol server for the specified language\n//\t@Tags\t\t\tlsp\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tLspServerRequest\ttrue\t\"LSP server request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/lsp/start [post]\n//\n//\t@id\t\t\t\tStart\nfunc Start(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req LspServerRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\t\treturn\n\t\t}\n\n\t\tservice := GetLSPService(logger)\n\t\terr := service.Start(req.LanguageId, req.PathToProject)\n\t\tif err != nil {\n\t\t\tlogger.Error(\"error starting LSP server\", \"error\", err)\n\t\t\tc.AbortWithError(http.StatusInternalServerError, errors.New(\"error starting LSP server\"))\n\t\t\treturn\n\t\t}\n\n\t\tc.Status(http.StatusOK)\n\t}\n}\n\n// Stop godoc\n//\n//\t@Summary\t\tStop LSP server\n//\t@Description\tStop a Language Server Protocol server\n//\t@Tags\t\t\tlsp\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tLspServerRequest\ttrue\t\"LSP server request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/lsp/stop [post]\n//\n//\t@id\t\t\t\tStop\nfunc Stop(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req LspServerRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\t\treturn\n\t\t}\n\n\t\tservice := GetLSPService(logger)\n\t\terr := service.Shutdown(req.LanguageId, req.PathToProject)\n\t\tif err != nil {\n\t\t\tlogger.Error(\"error stopping LSP server\", \"error\", err)\n\t\t\tc.AbortWithError(http.StatusInternalServerError, errors.New(\"error stopping LSP server\"))\n\t\t\treturn\n\t\t}\n\n\t\tc.Status(http.StatusOK)\n\t}\n}\n\n// DidOpen godoc\n//\n//\t@Summary\t\tNotify document opened\n//\t@Description\tNotify the LSP server that a document has been opened\n//\t@Tags\t\t\tlsp\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tLspDocumentRequest\ttrue\t\"Document request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/lsp/did-open [post]\n//\n//\t@id\t\t\t\tDidOpen\nfunc DidOpen(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req LspDocumentRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\t\treturn\n\t\t}\n\n\t\tservice := GetLSPService(logger)\n\t\tserver, err := service.Get(req.LanguageId, req.PathToProject)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\t\tif !server.IsInitialized() {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"server not initialized\"))\n\t\t\treturn\n\t\t}\n\t\terr = server.HandleDidOpen(c.Request.Context(), req.Uri)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\n\t\tc.Status(http.StatusOK)\n\t}\n}\n\n// DidClose godoc\n//\n//\t@Summary\t\tNotify document closed\n//\t@Description\tNotify the LSP server that a document has been closed\n//\t@Tags\t\t\tlsp\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tLspDocumentRequest\ttrue\t\"Document request\"\n//\t@Success\t\t200\n//\t@Router\t\t\t/lsp/did-close [post]\n//\n//\t@id\t\t\t\tDidClose\nfunc DidClose(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req LspDocumentRequest\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\t\treturn\n\t\t}\n\n\t\tservice := GetLSPService(logger)\n\t\tserver, err := service.Get(req.LanguageId, req.PathToProject)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\t\tif !server.IsInitialized() {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"server not initialized\"))\n\t\t\treturn\n\t\t}\n\t\terr = server.HandleDidClose(c.Request.Context(), req.Uri)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\n\t\tc.Status(http.StatusOK)\n\t}\n}\n\n// Completions godoc\n//\n//\t@Summary\t\tGet code completions\n//\t@Description\tGet code completion suggestions from the LSP server\n//\t@Tags\t\t\tlsp\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tLspCompletionParams\ttrue\t\"Completion request\"\n//\t@Success\t\t200\t\t{object}\tCompletionList\n//\t@Router\t\t\t/lsp/completions [post]\n//\n//\t@id\t\t\t\tCompletions\nfunc Completions(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar req LspCompletionParams\n\t\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\t\treturn\n\t\t}\n\n\t\tservice := GetLSPService(logger)\n\t\tserver, err := service.Get(req.LanguageId, req.PathToProject)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\t\tif !server.IsInitialized() {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"server not initialized\"))\n\t\t\treturn\n\t\t}\n\n\t\ttextDocument := TextDocumentIdentifier{\n\t\t\tURI: req.Uri,\n\t\t}\n\n\t\tcompletionParams := CompletionParams{\n\t\t\tTextDocument: textDocument,\n\t\t\tPosition:     req.Position,\n\t\t\tContext:      req.Context,\n\t\t}\n\n\t\tlist, err := server.HandleCompletions(c.Request.Context(), completionParams)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\n\t\tc.JSON(http.StatusOK, list)\n\t}\n}\n\n// DocumentSymbols godoc\n//\n//\t@Summary\t\tGet document symbols\n//\t@Description\tGet symbols (functions, classes, etc.) from a document\n//\t@Tags\t\t\tlsp\n//\t@Produce\t\tjson\n//\t@Param\t\t\tlanguageId\t\tquery\tstring\ttrue\t\"Language ID (e.g., python, typescript)\"\n//\t@Param\t\t\tpathToProject\tquery\tstring\ttrue\t\"Path to project\"\n//\t@Param\t\t\turi\t\t\t\tquery\tstring\ttrue\t\"Document URI\"\n//\t@Success\t\t200\t\t\t\t{array}\tLspSymbol\n//\t@Router\t\t\t/lsp/document-symbols [get]\n//\n//\t@id\t\t\t\tDocumentSymbols\nfunc DocumentSymbols(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tlanguageId := c.Query(\"languageId\")\n\t\tif languageId == \"\" {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"languageId is required\"))\n\t\t\treturn\n\t\t}\n\n\t\tpathToProject := c.Query(\"pathToProject\")\n\t\tif pathToProject == \"\" {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"pathToProject is required\"))\n\t\t\treturn\n\t\t}\n\n\t\turi := c.Query(\"uri\")\n\t\tif uri == \"\" {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"uri is required\"))\n\t\t\treturn\n\t\t}\n\n\t\tservice := GetLSPService(logger)\n\t\tserver, err := service.Get(languageId, pathToProject)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\t\tif !server.IsInitialized() {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"server not initialized\"))\n\t\t\treturn\n\t\t}\n\n\t\tsymbols, err := server.HandleDocumentSymbols(c.Request.Context(), uri)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\n\t\tc.JSON(http.StatusOK, symbols)\n\t}\n}\n\n// WorkspaceSymbols godoc\n//\n//\t@Summary\t\tGet workspace symbols\n//\t@Description\tSearch for symbols across the entire workspace\n//\t@Tags\t\t\tlsp\n//\t@Produce\t\tjson\n//\t@Param\t\t\tquery\t\t\tquery\tstring\ttrue\t\"Search query\"\n//\t@Param\t\t\tlanguageId\t\tquery\tstring\ttrue\t\"Language ID (e.g., python, typescript)\"\n//\t@Param\t\t\tpathToProject\tquery\tstring\ttrue\t\"Path to project\"\n//\t@Success\t\t200\t\t\t\t{array}\tLspSymbol\n//\t@Router\t\t\t/lsp/workspacesymbols [get]\n//\n//\t@id\t\t\t\tWorkspaceSymbols\nfunc WorkspaceSymbols(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tquery := c.Query(\"query\")\n\t\tif query == \"\" {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"query is required\"))\n\t\t\treturn\n\t\t}\n\n\t\tlanguageId := c.Query(\"languageId\")\n\t\tif languageId == \"\" {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"languageId is required\"))\n\t\t\treturn\n\t\t}\n\n\t\tpathToProject := c.Query(\"pathToProject\")\n\t\tif pathToProject == \"\" {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"pathToProject is required\"))\n\t\t\treturn\n\t\t}\n\n\t\tservice := GetLSPService(logger)\n\t\tserver, err := service.Get(languageId, pathToProject)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\t\tif !server.IsInitialized() {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"server not initialized\"))\n\t\t\treturn\n\t\t}\n\n\t\tsymbols, err := server.HandleWorkspaceSymbols(c.Request.Context(), query)\n\t\tif err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, err)\n\t\t\treturn\n\t\t}\n\n\t\tc.JSON(http.StatusOK, symbols)\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/lsp/python_lsp.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage lsp\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/sourcegraph/jsonrpc2\"\n)\n\ntype PythonLSPServer struct {\n\t*LSPServerAbstract\n}\n\nfunc (s *PythonLSPServer) Initialize(pathToProject string) error {\n\tctx := context.Background()\n\n\tcmd := exec.Command(\"pylsp\")\n\n\tstream, err := NewStdioStream(cmd)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create stdio stream: %w\", err)\n\t}\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"failed to start Python LSP server: %w\", err)\n\t}\n\n\thandler := jsonrpc2.HandlerWithError(func(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (interface{}, error) {\n\t\ts.logger.Debug(\"Received request\", \"method\", req.Method)\n\t\tif req.Params != nil {\n\t\t\ts.logger.Debug(\"Request params\", \"params\", req.Params)\n\t\t}\n\t\treturn nil, nil\n\t})\n\n\tconn := jsonrpc2.NewConn(ctx, jsonrpc2.NewBufferedStream(stream, jsonrpc2.VSCodeObjectCodec{}), handler)\n\n\tclient := &Client{conn: conn}\n\n\tparams := InitializeParams{\n\t\tProcessID: os.Getpid(),\n\t\tClientInfo: ClientInfo{\n\t\t\tName:    \"datyona-python-lsp-client\",\n\t\t\tVersion: \"0.0.1\",\n\t\t},\n\t\tRootURI: \"file://\" + pathToProject,\n\t\tCapabilities: ClientCapabilities{\n\t\t\tTextDocument: TextDocumentClientCapabilities{\n\t\t\t\tCompletion: CompletionClientCapabilities{\n\t\t\t\t\tDynamicRegistration: true,\n\t\t\t\t\tCompletionItem: CompletionItemCapabilities{\n\t\t\t\t\t\tSnippetSupport:          true,\n\t\t\t\t\t\tCommitCharactersSupport: true,\n\t\t\t\t\t\tDocumentationFormat:     []string{\"markdown\", \"plaintext\"},\n\t\t\t\t\t\tDeprecatedSupport:       true,\n\t\t\t\t\t\tPreselectSupport:        true,\n\t\t\t\t\t},\n\t\t\t\t\tContextSupport: true,\n\t\t\t\t},\n\t\t\t\tDocumentSymbol: DocumentSymbolClientCapabilities{\n\t\t\t\t\tDynamicRegistration: true,\n\t\t\t\t\tSymbolKind: SymbolKindInfo{\n\t\t\t\t\t\tValueSet: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tWorkspace: WorkspaceClientCapabilities{\n\t\t\t\tSymbol: WorkspaceSymbolClientCapabilities{\n\t\t\t\t\tDynamicRegistration: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tif err := client.Initialize(ctx, params); err != nil {\n\t\tconn.Close()\n\t\tkillerr := cmd.Process.Kill()\n\t\tif killerr != nil {\n\t\t\treturn fmt.Errorf(\"failed to initialize Python LSP connection: %w, failed to kill process: %w\", err, killerr)\n\t\t}\n\t\treturn fmt.Errorf(\"failed to initialize Python LSP connection: %w\", err)\n\t}\n\n\ts.client = client\n\ts.initialized = true\n\n\treturn nil\n}\n\nfunc (s *PythonLSPServer) Shutdown() error {\n\terr := s.client.Shutdown(context.Background())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to shutdown Python LSP server: %w\", err)\n\t}\n\ts.initialized = false\n\treturn nil\n}\n\nfunc NewPythonLSPServer(logger *slog.Logger) *PythonLSPServer {\n\treturn &PythonLSPServer{\n\t\tLSPServerAbstract: &LSPServerAbstract{\n\t\t\tlanguageId: \"python\",\n\t\t\tlogger:     logger.With(slog.String(\"component\", \"python_lsp_server\")),\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/lsp/server.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage lsp\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n)\n\ntype LSPServer interface {\n\tInitialize(pathToProject string) error\n\tIsInitialized() bool\n\tShutdown() error\n\n\tHandleDidOpen(ctx context.Context, uri string) error\n\tHandleDidClose(ctx context.Context, uri string) error\n\tHandleCompletions(ctx context.Context, params CompletionParams) (*CompletionList, error)\n\tHandleDocumentSymbols(ctx context.Context, uri string) ([]LspSymbol, error)\n\tHandleWorkspaceSymbols(ctx context.Context, query string) ([]LspSymbol, error)\n}\n\ntype LSPServerAbstract struct {\n\tclient *Client\n\n\tlogger *slog.Logger\n\n\tlanguageId  string\n\tinitialized bool\n}\n\n// Add new request types\ntype WorkspaceSymbolRequest struct {\n\tQuery string `json:\"query\"`\n}\n\nfunc (s *LSPServerAbstract) IsInitialized() bool {\n\treturn s.initialized\n}\n\nfunc (s *LSPServerAbstract) HandleDidOpen(ctx context.Context, uri string) error {\n\tif err := s.client.DidOpen(ctx, uri, s.languageId); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (s *LSPServerAbstract) HandleDidClose(ctx context.Context, uri string) error {\n\tif err := s.client.NotifyDidClose(ctx, uri); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (s *LSPServerAbstract) HandleCompletions(ctx context.Context, params CompletionParams) (*CompletionList, error) {\n\tcompletions, err := s.client.GetCompletion(\n\t\tctx,\n\t\tparams.TextDocument.URI,\n\t\tparams.Position,\n\t\tparams.Context,\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn completions, nil\n}\n\nfunc (s *LSPServerAbstract) HandleDocumentSymbols(ctx context.Context, uri string) ([]LspSymbol, error) {\n\tsymbols, err := s.client.GetDocumentSymbols(ctx, uri)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn symbols, nil\n}\n\nfunc (s *LSPServerAbstract) HandleWorkspaceSymbols(ctx context.Context, query string) ([]LspSymbol, error) {\n\tsymbols, err := s.client.GetWorkspaceSymbols(ctx, query)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn symbols, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/lsp/service.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage lsp\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"sync\"\n)\n\ntype LSPService struct {\n\tlogger  *slog.Logger\n\tservers map[string]LSPServer\n}\n\nvar (\n\tinstance *LSPService\n\tonce     sync.Once\n)\n\nfunc GetLSPService(logger *slog.Logger) *LSPService {\n\tonce.Do(func() {\n\t\tinstance = &LSPService{\n\t\t\tlogger:  logger,\n\t\t\tservers: make(map[string]LSPServer),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (s *LSPService) Get(languageId string, pathToProject string) (LSPServer, error) {\n\tkey := generateKey(languageId, pathToProject)\n\n\tif server, ok := s.servers[key]; ok {\n\t\treturn server, nil\n\t}\n\n\tswitch languageId {\n\tcase \"typescript\":\n\t\tserver := NewTypeScriptLSPServer(s.logger)\n\t\ts.servers[key] = server\n\t\treturn server, nil\n\tcase \"python\":\n\t\tserver := NewPythonLSPServer(s.logger)\n\t\ts.servers[key] = server\n\t\treturn server, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported language: %s\", languageId)\n\t}\n}\n\nfunc (s *LSPService) Start(languageId string, pathToProject string) error {\n\tkey := generateKey(languageId, pathToProject)\n\n\tserver, ok := s.servers[key]\n\tif ok {\n\t\tif server.IsInitialized() {\n\t\t\treturn nil\n\t\t}\n\t} else {\n\t\tnewServer := NewTypeScriptLSPServer(s.logger)\n\t\ts.servers[key] = newServer\n\t\tserver = newServer\n\t}\n\n\terr := server.Initialize(pathToProject)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create TypeScript LSP server: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *LSPService) Shutdown(languageId string, pathToProject string) error {\n\tkey := generateKey(languageId, pathToProject)\n\n\tserver, ok := s.servers[key]\n\tif !ok {\n\t\treturn fmt.Errorf(\"no server for language: %s\", languageId)\n\t}\n\terr := server.Shutdown()\n\tdelete(s.servers, key)\n\treturn err\n}\n\nfunc generateKey(languageId, pathToProject string) string {\n\tdata := fmt.Sprintf(\"%s:%s\", languageId, pathToProject)\n\treturn base64.StdEncoding.EncodeToString([]byte(data))\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/lsp/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage lsp\n\ntype LspServerRequest struct {\n\tLanguageId    string `json:\"languageId\" validate:\"required\"`\n\tPathToProject string `json:\"pathToProject\" validate:\"required\"`\n} // @name LspServerRequest\n\ntype LspDocumentRequest struct {\n\tLanguageId    string `json:\"languageId\" validate:\"required\"`\n\tPathToProject string `json:\"pathToProject\" validate:\"required\"`\n\tUri           string `json:\"uri\" validate:\"required\"`\n} // @name LspDocumentRequest\n\ntype LspCompletionParams struct {\n\tLanguageId    string             `json:\"languageId\" validate:\"required\"`\n\tPathToProject string             `json:\"pathToProject\" validate:\"required\"`\n\tUri           string             `json:\"uri\" validate:\"required\"`\n\tPosition      LspPosition        `json:\"position\" validate:\"required\"`\n\tContext       *CompletionContext `json:\"context,omitempty\" validate:\"optional\"`\n} // @name LspCompletionParams\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/lsp/typescript_lsp.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage lsp\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/sourcegraph/jsonrpc2\"\n)\n\ntype TypescriptLSPServer struct {\n\t*LSPServerAbstract\n}\n\nfunc (s *TypescriptLSPServer) Initialize(pathToProject string) error {\n\tctx := context.Background()\n\n\tcmd := exec.Command(\"typescript-language-server\", \"--stdio\")\n\n\tstream, err := NewStdioStream(cmd)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create stdio stream: %w\", err)\n\t}\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"failed to start LSP server: %w\", err)\n\t}\n\n\thandler := jsonrpc2.HandlerWithError(func(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) (interface{}, error) {\n\t\ts.logger.Debug(\"Received request\", \"method\", req.Method)\n\t\tif req.Params != nil {\n\t\t\ts.logger.Debug(\"Request params\", \"params\", req.Params)\n\t\t}\n\t\treturn nil, nil\n\t})\n\n\tconn := jsonrpc2.NewConn(ctx, jsonrpc2.NewBufferedStream(stream, jsonrpc2.VSCodeObjectCodec{}), handler)\n\n\tclient := &Client{conn: conn}\n\n\tparams := InitializeParams{\n\t\tProcessID: os.Getpid(),\n\t\tClientInfo: ClientInfo{\n\t\t\tName:    \"datyona-typescript-lsp-client\",\n\t\t\tVersion: \"0.0.1\",\n\t\t},\n\t\tRootURI: \"file://\" + pathToProject,\n\t\tCapabilities: ClientCapabilities{\n\t\t\tTextDocument: TextDocumentClientCapabilities{\n\t\t\t\tCompletion: CompletionClientCapabilities{\n\t\t\t\t\tDynamicRegistration: true,\n\t\t\t\t\tCompletionItem: CompletionItemCapabilities{\n\t\t\t\t\t\tSnippetSupport:          true,\n\t\t\t\t\t\tCommitCharactersSupport: true,\n\t\t\t\t\t\tDocumentationFormat:     []string{\"markdown\", \"plaintext\"},\n\t\t\t\t\t\tDeprecatedSupport:       true,\n\t\t\t\t\t\tPreselectSupport:        true,\n\t\t\t\t\t},\n\t\t\t\t\tContextSupport: true,\n\t\t\t\t},\n\t\t\t\tDocumentSymbol: DocumentSymbolClientCapabilities{\n\t\t\t\t\tDynamicRegistration: true,\n\t\t\t\t\tSymbolKind: SymbolKindInfo{\n\t\t\t\t\t\tValueSet: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tWorkspace: WorkspaceClientCapabilities{\n\t\t\t\tSymbol: WorkspaceSymbolClientCapabilities{\n\t\t\t\t\tDynamicRegistration: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tif err := client.Initialize(ctx, params); err != nil {\n\t\tconn.Close()\n\t\tkillerr := cmd.Process.Kill()\n\t\tif killerr != nil {\n\t\t\treturn fmt.Errorf(\"failed to initialize Typescript LSP connection: %w, failed to kill process: %w\", err, killerr)\n\t\t}\n\t\treturn fmt.Errorf(\"failed to initialize Typescript LSP connection: %w\", err)\n\t}\n\n\ts.client = client\n\ts.initialized = true\n\n\treturn nil\n}\n\nfunc (s *TypescriptLSPServer) Shutdown() error {\n\terr := s.client.Shutdown(context.Background())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to shutdown Typescript LSP server: %w\", err)\n\t}\n\ts.initialized = false\n\treturn nil\n}\n\nfunc NewTypeScriptLSPServer(logger *slog.Logger) *TypescriptLSPServer {\n\treturn &TypescriptLSPServer{\n\t\tLSPServerAbstract: &LSPServerAbstract{\n\t\t\tlanguageId: \"typescript\",\n\t\t\tlogger:     logger.With(slog.String(\"component\", \"typescript_lsp_server\")),\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/middlewares/error.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage middlewares\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daemon/pkg/common\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc ErrorMiddleware() gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tctx.Next()\n\n\t\tif len(ctx.Errors) > 0 {\n\t\t\terr := ctx.Errors.Last()\n\t\t\tstatusCode := ctx.Writer.Status()\n\n\t\t\terrorResponse := common.ErrorResponse{\n\t\t\t\tStatusCode: statusCode,\n\t\t\t\tMessage:    err.Error(),\n\t\t\t\tCode:       http.StatusText(statusCode),\n\t\t\t\tTimestamp:  time.Now(),\n\t\t\t\tPath:       ctx.Request.URL.Path,\n\t\t\t\tMethod:     ctx.Request.Method,\n\t\t\t}\n\n\t\t\tctx.Header(\"Content-Type\", \"application/json\")\n\t\t\tctx.AbortWithStatusJSON(statusCode, errorResponse)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/port/detector.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage port\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/cakturk/go-netstat/netstat\"\n\t\"github.com/gin-gonic/gin\"\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n)\n\ntype portsDetector struct {\n\tportMap cmap.ConcurrentMap[string, bool]\n}\n\nfunc NewPortsDetector() *portsDetector {\n\treturn &portsDetector{\n\t\tportMap: cmap.New[bool](),\n\t}\n}\n\nfunc (d *portsDetector) Start(ctx context.Context) {\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tdefault:\n\t\t\ttime.Sleep(1 * time.Second)\n\t\t\t// get only listening TCP sockets\n\t\t\ttabs, err := netstat.TCPSocks(func(s *netstat.SockTabEntry) bool {\n\t\t\t\treturn s.State == netstat.Listen\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfreshMap := map[string]bool{}\n\t\t\tfor _, e := range tabs {\n\t\t\t\ts := strconv.Itoa(int(e.LocalAddr.Port))\n\t\t\t\tfreshMap[s] = true\n\t\t\t\td.portMap.Set(s, true)\n\t\t\t}\n\n\t\t\tfor _, port := range d.portMap.Keys() {\n\t\t\t\tif !freshMap[port] {\n\t\t\t\t\td.portMap.Remove(port)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// GetPorts godoc\n//\n//\t@Summary\t\tGet active ports\n//\t@Description\tGet a list of all currently active ports\n//\t@Tags\t\t\tport\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tPortList\n//\t@Router\t\t\t/port [get]\n//\n//\t@id\t\t\t\tGetPorts\nfunc (d *portsDetector) GetPorts(c *gin.Context) {\n\tports := PortList{\n\t\tPorts: []uint{},\n\t}\n\n\tfor _, port := range d.portMap.Keys() {\n\t\tportInt, err := strconv.Atoi(port)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tports.Ports = append(ports.Ports, uint(portInt))\n\t}\n\n\tc.JSON(http.StatusOK, ports)\n}\n\n// IsPortInUse godoc\n//\n//\t@Summary\t\tCheck if port is in use\n//\t@Description\tCheck if a specific port is currently in use\n//\t@Tags\t\t\tport\n//\t@Produce\t\tjson\n//\t@Param\t\t\tport\tpath\t\tint\ttrue\t\"Port number (3000-9999)\"\n//\t@Success\t\t200\t\t{object}\tIsPortInUseResponse\n//\t@Router\t\t\t/port/{port}/in-use [get]\n//\n//\t@id\t\t\t\tIsPortInUse\nfunc (d *portsDetector) IsPortInUse(c *gin.Context) {\n\tportParam := c.Param(\"port\")\n\n\tport, err := strconv.Atoi(portParam)\n\tif err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"invalid port: must be a number between 3000 and 9999\"))\n\t\treturn\n\t}\n\n\tif port < 3000 || port > 9999 {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"port out of range: must be between 3000 and 9999\"))\n\t\treturn\n\t}\n\n\tportStr := strconv.Itoa(port)\n\n\tif d.portMap.Has(portStr) {\n\t\tc.JSON(http.StatusOK, IsPortInUseResponse{\n\t\t\tIsInUse: true,\n\t\t})\n\t} else {\n\t\t// If the port is not in the map, we check synchronously if it's in use and update the map\n\t\t_, err := net.DialTimeout(\"tcp\", fmt.Sprintf(\"localhost:%d\", port), 50*time.Millisecond)\n\t\tif err != nil {\n\t\t\tc.JSON(http.StatusOK, IsPortInUseResponse{\n\t\t\t\tIsInUse: false,\n\t\t\t})\n\t\t} else {\n\t\t\td.portMap.Set(portStr, true)\n\t\t\tc.JSON(http.StatusOK, IsPortInUseResponse{\n\t\t\t\tIsInUse: true,\n\t\t\t})\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/port/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage port\n\ntype PortList struct {\n\tPorts []uint `json:\"ports\"`\n} // @name PortList\n\ntype IsPortInUseResponse struct {\n\tIsInUse bool `json:\"isInUse\"`\n} // @name IsPortInUseResponse\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/execute.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage process\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"os/exec\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n// ExecuteCommand godoc\n//\n//\t@Summary\t\tExecute a command\n//\t@Description\tExecute a shell command and return the output and exit code\n//\t@Tags\t\t\tprocess\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tExecuteRequest\ttrue\t\"Command execution request\"\n//\t@Success\t\t200\t\t{object}\tExecuteResponse\n//\t@Router\t\t\t/process/execute [post]\n//\n//\t@id\t\t\t\tExecuteCommand\nfunc ExecuteCommand(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(c *gin.Context) {\n\t\tvar request ExecuteRequest\n\t\tif err := c.ShouldBindJSON(&request); err != nil {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"command is required\"))\n\t\t\treturn\n\t\t}\n\n\t\tcmdParts := parseCommand(request.Command)\n\t\tif len(cmdParts) == 0 {\n\t\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"empty command\"))\n\t\t\treturn\n\t\t}\n\n\t\tcmd := exec.Command(cmdParts[0], cmdParts[1:]...)\n\t\tif request.Cwd != nil {\n\t\t\tcmd.Dir = *request.Cwd\n\t\t}\n\n\t\t// set maximum execution time\n\t\ttimeout := 360 * time.Second\n\t\tif request.Timeout != nil && *request.Timeout > 0 {\n\t\t\ttimeout = time.Duration(*request.Timeout) * time.Second\n\t\t}\n\n\t\ttimeoutReached := false\n\t\ttimer := time.AfterFunc(timeout, func() {\n\t\t\ttimeoutReached = true\n\t\t\tif cmd.Process != nil {\n\t\t\t\t// kill the process group\n\t\t\t\terr := cmd.Process.Kill()\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Error(\"failed to kill process\", \"error\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t\tdefer timer.Stop()\n\n\t\toutput, err := cmd.CombinedOutput()\n\t\tif err != nil {\n\t\t\tif timeoutReached {\n\t\t\t\tc.AbortWithError(http.StatusRequestTimeout, errors.New(\"command execution timeout\"))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif exitError, ok := err.(*exec.ExitError); ok {\n\t\t\t\texitCode := exitError.ExitCode()\n\t\t\t\tc.JSON(http.StatusOK, ExecuteResponse{\n\t\t\t\t\tExitCode: exitCode,\n\t\t\t\t\tResult:   string(output),\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\t\t\tc.JSON(http.StatusOK, ExecuteResponse{\n\t\t\t\tExitCode: -1,\n\t\t\t\tResult:   string(output),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tif cmd.ProcessState == nil {\n\t\t\tc.JSON(http.StatusOK, ExecuteResponse{\n\t\t\t\tExitCode: -1,\n\t\t\t\tResult:   string(output),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\texitCode := cmd.ProcessState.ExitCode()\n\t\tc.JSON(http.StatusOK, ExecuteResponse{\n\t\t\tExitCode: exitCode,\n\t\t\tResult:   string(output),\n\t\t})\n\t}\n}\n\n// parseCommand splits a command string properly handling quotes\nfunc parseCommand(command string) []string {\n\tvar args []string\n\tvar current bytes.Buffer\n\tvar inQuotes bool\n\tvar quoteChar rune\n\n\tfor _, r := range command {\n\t\tswitch {\n\t\tcase r == '\"' || r == '\\'':\n\t\t\tif !inQuotes {\n\t\t\t\tinQuotes = true\n\t\t\t\tquoteChar = r\n\t\t\t} else if quoteChar == r {\n\t\t\t\tinQuotes = false\n\t\t\t\tquoteChar = 0\n\t\t\t} else {\n\t\t\t\tcurrent.WriteRune(r)\n\t\t\t}\n\t\tcase r == ' ' && !inQuotes:\n\t\t\tif current.Len() > 0 {\n\t\t\t\targs = append(args, current.String())\n\t\t\t\tcurrent.Reset()\n\t\t\t}\n\t\tdefault:\n\t\t\tcurrent.WriteRune(r)\n\t\t}\n\t}\n\n\tif current.Len() > 0 {\n\t\targs = append(args, current.String())\n\t}\n\n\treturn args\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/interpreter/controller.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage interpreter\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/daemon/internal/util\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/gorilla/websocket\"\n)\n\nfunc NewInterpreterController(logger *slog.Logger, workDir string) *Controller {\n\tInitManager(workDir)\n\t// Pre-warm the default interpreter context to reduce latency on first request\n\tgo func() {\n\t\t_, err := GetOrCreateDefaultContext(logger)\n\t\tif err != nil {\n\t\t\tlogger.Debug(\"Failed to pre-create default interpreter context\", \"error\", err)\n\t\t}\n\t}()\n\treturn &Controller{logger: logger.With(slog.String(\"component\", \"interpreter_controller\")), workDir: workDir}\n}\n\n// CreateContext creates a new interpreter context\n//\n//\t@Summary\t\tCreate a new interpreter context\n//\t@Description\tCreates a new isolated interpreter context with optional working directory and language\n//\t@Tags\t\t\tinterpreter\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tCreateContextRequest\ttrue\t\"Context configuration\"\n//\t@Success\t\t200\t\t{object}\tInterpreterContext\n//\t@Failure\t\t400\t\t{object}\tmap[string]string\n//\t@Failure\t\t500\t\t{object}\tmap[string]string\n//\t@Router\t\t\t/process/interpreter/context [post]\n//\n//\t@id\t\t\t\tCreateInterpreterContext\nfunc (c *Controller) CreateContext(ctx *gin.Context) {\n\tvar req CreateContextRequest\n\terr := ctx.ShouldBindJSON(&req)\n\tif err != nil {\n\t\tctx.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request payload: %w\", err))\n\t\treturn\n\t}\n\n\tlanguage := LanguagePython\n\tif req.Language != nil {\n\t\tlanguage = *req.Language\n\t}\n\tif language != LanguagePython {\n\t\tctx.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"unsupported language: %s (only '%s' is supported currently)\", language, LanguagePython))\n\t\treturn\n\t}\n\n\tcwd := c.workDir\n\tif req.Cwd != nil {\n\t\tcwd = *req.Cwd\n\t}\n\n\tiCtx, err := CreateContext(c.logger, cwd, language)\n\tif err != nil {\n\t\tctx.AbortWithError(http.StatusInternalServerError, err)\n\t\treturn\n\t}\n\n\tinfo := iCtx.Info()\n\tctx.JSON(http.StatusOK, ContextInfo{\n\t\tID:        info.ID,\n\t\tCwd:       info.Cwd,\n\t\tCreatedAt: info.CreatedAt,\n\t\tActive:    info.Active,\n\t\tLanguage:  info.Language,\n\t})\n}\n\n// Execute executes code in an interpreter context via WebSocket\n//\n//\t@Summary\t\tExecute code in an interpreter context\n//\t@Description\tExecutes code in a specified context (or default context if not specified) via WebSocket streaming\n//\t@Tags\t\t\tinterpreter\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Router\t\t\t/process/interpreter/execute [get]\n//\t@Success\t\t101\t{string}\tstring\t\t\"Switching Protocols\"\n//\t@Header\t\t\t101\t{string}\tUpgrade\t\t\"websocket\"\n//\t@Header\t\t\t101\t{string}\tConnection\t\"Upgrade\"\n//\n//\t@id\t\t\t\tExecuteInterpreterCode\nfunc (c *Controller) Execute(ctx *gin.Context) {\n\t// Upgrade to WebSocket\n\tws, err := util.UpgradeToWebSocket(ctx.Writer, ctx.Request)\n\tif err != nil {\n\t\tctx.AbortWithStatus(http.StatusBadRequest)\n\t\treturn\n\t}\n\n\t_, payload, err := ws.ReadMessage()\n\tif err != nil {\n\t\twriteWSError(ws, \"failed to read first message\", websocket.CloseProtocolError)\n\t\treturn\n\t}\n\n\tvar req ExecuteRequest\n\terr = json.Unmarshal(payload, &req)\n\tif err != nil {\n\t\twriteWSError(ws, \"invalid JSON payload\", websocket.CloseProtocolError)\n\t\treturn\n\t}\n\n\tif req.Code == \"\" {\n\t\twriteWSError(ws, \"code is required\", websocket.ClosePolicyViolation)\n\t\treturn\n\t}\n\n\ttimeout := 10 * time.Minute\n\tif req.Timeout != nil {\n\t\tif *req.Timeout < 0 {\n\t\t\twriteWSError(ws, \"timeout must be greater than or equal to 0\", websocket.ClosePolicyViolation)\n\t\t\treturn\n\t\t}\n\t\tif *req.Timeout == 0 {\n\t\t\ttimeout = 0\n\t\t} else {\n\t\t\ttimeout = time.Duration(*req.Timeout) * time.Second\n\t\t}\n\t}\n\n\tvar iCtx *Context\n\n\tif req.ContextID == nil {\n\t\tiCtx, err = GetOrCreateDefaultContext(c.logger)\n\t\tif err != nil {\n\t\t\twriteWSError(ws, \"failed to get default context: \"+err.Error(), websocket.CloseInternalServerErr)\n\t\t\treturn\n\t\t}\n\t} else {\n\t\tiCtx, err = GetContext(*req.ContextID)\n\t\tif err != nil {\n\t\t\twriteWSError(ws, \"context not found: \"+*req.ContextID, websocket.ClosePolicyViolation)\n\t\t\treturn\n\t\t}\n\t}\n\n\tcontextInfo := iCtx.Info()\n\tif !contextInfo.Active {\n\t\twriteWSError(ws, \"context is not active\", websocket.ClosePolicyViolation)\n\t\treturn\n\t}\n\n\tvar envs map[string]string\n\tif req.Envs != nil {\n\t\tenvs = *req.Envs\n\t}\n\n\tgo iCtx.enqueueAndExecute(req.Code, envs, timeout, ws)\n}\n\n// writeWSError sends an error message to the WebSocket and closes the connection\nfunc writeWSError(ws *websocket.Conn, value string, closeCode int) {\n\tcloseMessage := websocket.FormatCloseMessage(closeCode, value)\n\t_ = ws.WriteControl(websocket.CloseMessage, closeMessage, time.Now().Add(writeWait))\n\t_ = ws.Close()\n}\n\n// DeleteContext deletes an interpreter context\n//\n//\t@Summary\t\tDelete an interpreter context\n//\t@Description\tDeletes an interpreter context and shuts down its worker process\n//\t@Tags\t\t\tinterpreter\n//\t@Produce\t\tjson\n//\t@Param\t\t\tid\tpath\t\tstring\ttrue\t\"Context ID\"\n//\t@Success\t\t200\t{object}\tmap[string]string\n//\t@Failure\t\t400\t{object}\tmap[string]string\n//\t@Failure\t\t404\t{object}\tmap[string]string\n//\t@Router\t\t\t/process/interpreter/context/{id} [delete]\n//\n//\t@id\t\t\t\tDeleteInterpreterContext\nfunc (c *Controller) DeleteContext(ctx *gin.Context) {\n\tid := ctx.Param(\"id\")\n\tif id == \"\" {\n\t\tctx.AbortWithError(http.StatusBadRequest, errors.New(\"context ID is required\"))\n\t\treturn\n\t}\n\n\tif id == \"default\" {\n\t\tctx.AbortWithError(http.StatusBadRequest, errors.New(\"cannot delete default context\"))\n\t\treturn\n\t}\n\n\terr := DeleteContext(id)\n\tif err != nil {\n\t\tif common_errors.IsNotFoundError(err) {\n\t\t\tctx.AbortWithError(http.StatusNotFound, err)\n\t\t\treturn\n\t\t}\n\t\tctx.AbortWithError(http.StatusInternalServerError, err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, gin.H{\"message\": \"Context deleted successfully\"})\n}\n\n// ListContexts lists all user-created interpreter contexts (excludes default)\n//\n//\t@Summary\t\tList all user-created interpreter contexts\n//\t@Description\tReturns information about all user-created interpreter contexts (excludes default context)\n//\t@Tags\t\t\tinterpreter\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tListContextsResponse\n//\t@Router\t\t\t/process/interpreter/context [get]\n//\n//\t@id\t\t\t\tListInterpreterContexts\nfunc (c *Controller) ListContexts(ctx *gin.Context) {\n\tallContexts := ListContexts()\n\n\tuserContexts := make([]ContextInfo, 0, len(allContexts))\n\tfor _, context := range allContexts {\n\t\tif context.ID != \"default\" {\n\t\t\tuserContexts = append(userContexts, context)\n\t\t}\n\t}\n\n\tctx.JSON(http.StatusOK, ListContextsResponse{Contexts: userContexts})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/interpreter/manager.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage interpreter\n\nimport (\n\t\"fmt\"\n\t\"log/slog\"\n\t\"sync\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/google/uuid\"\n)\n\n// Manager manages multiple interpreter contexts\ntype Manager struct {\n\tcontexts   map[string]*Context\n\tmu         sync.RWMutex\n\tdefaultCwd string\n}\n\nvar globalManager *Manager\n\n// InitManager initializes the global context manager\nfunc InitManager(defaultCwd string) {\n\tglobalManager = &Manager{\n\t\tcontexts:   make(map[string]*Context),\n\t\tdefaultCwd: defaultCwd,\n\t}\n}\n\n// CreateContext creates a new interpreter context\nfunc (m *Manager) CreateContext(logger *slog.Logger, id, cwd, language string) (*Context, error) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tif _, exists := m.contexts[id]; exists {\n\t\treturn nil, fmt.Errorf(\"context with ID '%s' already exists\", id)\n\t}\n\n\tif language != \"\" && language != LanguagePython {\n\t\treturn nil, fmt.Errorf(\"unsupported language: %s (only '%s' is supported)\", language, LanguagePython)\n\t}\n\tif language == \"\" {\n\t\tlanguage = LanguagePython\n\t}\n\n\tif cwd == \"\" {\n\t\tcwd = m.defaultCwd\n\t}\n\n\tiCtx := &Context{\n\t\tinfo: ContextInfo{\n\t\t\tID:        id,\n\t\t\tCwd:       cwd,\n\t\t\tCreatedAt: time.Now(),\n\t\t\tActive:    false,\n\t\t\tLanguage:  language,\n\t\t},\n\t\tlogger: logger.With(slog.String(\"context_id\", id)),\n\t}\n\n\terr := iCtx.start()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to start context: %w\", err)\n\t}\n\n\tm.contexts[id] = iCtx\n\treturn iCtx, nil\n}\n\n// GetContext retrieves an existing context by ID\nfunc (m *Manager) GetContext(id string) (*Context, error) {\n\tm.mu.RLock()\n\tiCtx, exists := m.contexts[id]\n\tm.mu.RUnlock()\n\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"context with ID '%s' not found\", id)\n\t}\n\n\tinfo := iCtx.Info()\n\tif !info.Active {\n\t\terr := iCtx.start()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to restart context '%s': %w\", id, err)\n\t\t}\n\t}\n\n\treturn iCtx, nil\n}\n\n// GetOrCreateDefaultContext gets or creates the default context\nfunc (m *Manager) GetOrCreateDefaultContext(logger *slog.Logger) (*Context, error) {\n\tm.mu.RLock()\n\tiCtx, exists := m.contexts[\"default\"]\n\tm.mu.RUnlock()\n\n\tif exists {\n\t\tinfo := iCtx.Info()\n\t\tif !info.Active {\n\t\t\terr := iCtx.start()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to restart default context: %w\", err)\n\t\t\t}\n\t\t}\n\t\treturn iCtx, nil\n\t}\n\n\treturn m.CreateContext(logger, \"default\", m.defaultCwd, LanguagePython)\n}\n\n// DeleteContext removes a context and shuts it down\nfunc (m *Manager) DeleteContext(id string) error {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\n\tiCtx, exists := m.contexts[id]\n\tif !exists {\n\t\treturn common_errors.NewNotFoundError(fmt.Errorf(\"context with ID '%s' not found\", id))\n\t}\n\n\tiCtx.shutdown()\n\tdelete(m.contexts, id)\n\treturn nil\n}\n\n// ListContexts returns information about all contexts\nfunc (m *Manager) ListContexts() []ContextInfo {\n\tm.mu.RLock()\n\tdefer m.mu.RUnlock()\n\n\tcontexts := make([]ContextInfo, 0, len(m.contexts))\n\tfor _, iCtx := range m.contexts {\n\t\tcontexts = append(contexts, iCtx.Info())\n\t}\n\treturn contexts\n}\n\n// Global convenience functions\n\n// CreateContext creates a new context using the global manager\nfunc CreateContext(logger *slog.Logger, cwd, language string) (*Context, error) {\n\tif globalManager == nil {\n\t\treturn nil, fmt.Errorf(\"context manager not initialized\")\n\t}\n\tid := uuid.NewString()\n\treturn globalManager.CreateContext(logger, id, cwd, language)\n}\n\n// GetContext gets a context by ID using the global manager\nfunc GetContext(id string) (*Context, error) {\n\tif globalManager == nil {\n\t\treturn nil, fmt.Errorf(\"context manager not initialized\")\n\t}\n\treturn globalManager.GetContext(id)\n}\n\n// GetOrCreateDefaultContext gets or creates the default context\nfunc GetOrCreateDefaultContext(logger *slog.Logger) (*Context, error) {\n\tif globalManager == nil {\n\t\treturn nil, fmt.Errorf(\"context manager not initialized\")\n\t}\n\treturn globalManager.GetOrCreateDefaultContext(logger)\n}\n\n// DeleteContext deletes a context using the global manager\nfunc DeleteContext(id string) error {\n\tif globalManager == nil {\n\t\treturn fmt.Errorf(\"context manager not initialized\")\n\t}\n\treturn globalManager.DeleteContext(id)\n}\n\n// ListContexts lists all contexts using the global manager\nfunc ListContexts() []ContextInfo {\n\tif globalManager == nil {\n\t\treturn []ContextInfo{}\n\t}\n\treturn globalManager.ListContexts()\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/interpreter/repl_client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage interpreter\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t_ \"embed\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"syscall\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/google/uuid\"\n\t\"github.com/gorilla/websocket\"\n)\n\n//go:embed repl_worker.py\nvar pythonWorkerScript string\n\n// Info returns the current context information\nfunc (c *Context) Info() ContextInfo {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\treturn c.info\n}\n\n// enqueueAndExecute enqueues a job and processes jobs FIFO ensuring single execution at a time\nfunc (c *Context) enqueueAndExecute(code string, envs map[string]string, timeout time.Duration, ws *websocket.Conn) {\n\tc.mu.Lock()\n\tif c.queue == nil {\n\t\tc.queue = make(chan execJob, 128)\n\t\tgo c.processQueue()\n\t}\n\tc.mu.Unlock()\n\n\tjob := execJob{code: code, envs: envs, timeout: timeout, ws: ws}\n\tc.queue <- job\n}\n\nfunc (c *Context) processQueue() {\n\tfor job := range c.queue {\n\t\tif job.ws != nil {\n\t\t\tgo c.attachWebSocket(job.ws)\n\t\t}\n\n\t\tresult, err := c.executeCode(job.code, job.envs, job.timeout)\n\n\t\tif err != nil && common_errors.IsRequestTimeoutError(err) || result.Status == CommandStatusTimeout {\n\t\t\tc.closeClient(WebSocketCloseTimeout, \"\")\n\t\t} else {\n\t\t\tc.closeClient(websocket.CloseNormalClosure, \"\")\n\t\t}\n\t}\n}\n\n// closeClient closes the WebSocket client with specified close code\nfunc (c *Context) closeClient(code int, message string) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tif c.client == nil {\n\t\treturn\n\t}\n\n\tc.client.requestClose(code, message)\n\tc.client = nil\n}\n\n// executeCode executes code in the interpreter context\nfunc (c *Context) executeCode(code string, envs map[string]string, timeout time.Duration) (*CommandExecution, error) {\n\tcmdID := uuid.NewString()\n\texecution := &CommandExecution{\n\t\tID:        cmdID,\n\t\tCode:      code,\n\t\tStatus:    CommandStatusRunning,\n\t\tStartedAt: time.Now(),\n\t}\n\n\tc.commandMu.Lock()\n\tc.activeCommand = execution\n\tc.commandMu.Unlock()\n\n\tworkerCmd := WorkerCommand{ID: cmdID, Code: code, Envs: envs}\n\terr := c.sendCommand(workerCmd)\n\tif err != nil {\n\t\texecution.Status = CommandStatusError\n\t\tnow := time.Now()\n\t\texecution.EndedAt = &now\n\t\texecution.Error = &Error{Name: \"CommunicationError\", Value: err.Error()}\n\t\treturn execution, err\n\t}\n\n\tresultChan := make(chan bool, 1)\n\tgo func() {\n\t\tfor {\n\t\t\ttime.Sleep(50 * time.Millisecond)\n\t\t\tc.commandMu.Lock()\n\t\t\tif c.activeCommand == nil || c.activeCommand.Status != CommandStatusRunning {\n\t\t\t\tc.commandMu.Unlock()\n\t\t\t\tresultChan <- true\n\t\t\t\treturn\n\t\t\t}\n\t\t\tc.commandMu.Unlock()\n\t\t}\n\t}()\n\n\tvar timeoutC <-chan time.Time\n\tif timeout > 0 {\n\t\ttimer := time.NewTimer(timeout)\n\t\tdefer timer.Stop()\n\t\ttimeoutC = timer.C\n\t}\n\n\tselect {\n\tcase <-resultChan:\n\t\tc.commandMu.Lock()\n\t\tresult := c.activeCommand\n\t\tc.activeCommand = nil\n\t\tc.commandMu.Unlock()\n\t\treturn result, nil\n\n\tcase <-timeoutC:\n\t\tif c.cmd != nil && c.cmd.Process != nil {\n\t\t\t_ = c.cmd.Process.Signal(syscall.SIGINT)\n\t\t}\n\n\t\tgraceful := time.NewTimer(gracePeriod)\n\t\tdefer graceful.Stop()\n\n\t\tselect {\n\t\tcase <-resultChan:\n\t\t\tc.commandMu.Lock()\n\t\t\tresult := c.activeCommand\n\t\t\tc.activeCommand = nil\n\t\t\tc.commandMu.Unlock()\n\t\t\treturn result, nil\n\n\t\tcase <-graceful.C:\n\t\t\tif c.cmd != nil && c.cmd.Process != nil {\n\t\t\t\t_ = c.cmd.Process.Kill()\n\t\t\t}\n\n\t\t\tc.commandMu.Lock()\n\t\t\tif c.activeCommand != nil {\n\t\t\t\tc.activeCommand.Status = CommandStatusTimeout\n\t\t\t\tnow := time.Now()\n\t\t\t\tc.activeCommand.EndedAt = &now\n\t\t\t\tc.activeCommand.Error = &Error{\n\t\t\t\t\tName:  \"TimeoutError\",\n\t\t\t\t\tValue: \"Execution timeout - code took too long to execute\",\n\t\t\t\t}\n\t\t\t\tresult := c.activeCommand\n\t\t\t\tc.activeCommand = nil\n\t\t\t\tc.commandMu.Unlock()\n\t\t\t\treturn result, common_errors.NewRequestTimeoutError(fmt.Errorf(\"execution timeout\"))\n\t\t\t}\n\t\t\tc.commandMu.Unlock()\n\t\t\treturn execution, common_errors.NewRequestTimeoutError(fmt.Errorf(\"execution timeout\"))\n\t\t}\n\t}\n}\n\n// start initializes and starts the Python worker process\nfunc (c *Context) start() error {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\t// Already running?\n\tif c.info.Active && c.cmd != nil && c.stdin != nil {\n\t\treturn nil\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tc.ctx = ctx\n\tc.cancel = cancel\n\n\t// Create (or reuse) a single shared worker script file\n\ttempDir := os.TempDir()\n\tworkerPath := filepath.Join(tempDir, \"daytona_repl_worker.py\")\n\n\t// Check if worker file exists, if not create it\n\tif _, err := os.Stat(workerPath); os.IsNotExist(err) {\n\t\terr := os.WriteFile(workerPath, []byte(pythonWorkerScript), workerScriptPerms)\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t\treturn fmt.Errorf(\"failed to create worker script: %w\", err)\n\t\t}\n\t}\n\n\tc.workerPath = workerPath\n\n\t// Start Python worker process\n\tpyCmd := detectPythonCommand()\n\tcmd := exec.CommandContext(ctx, pyCmd, workerPath)\n\tcmd.Dir = c.info.Cwd\n\tcmd.Env = os.Environ()\n\n\t// Get stdin/stdout pipes\n\tstdin, err := cmd.StdinPipe()\n\tif err != nil {\n\t\tcancel()\n\t\treturn fmt.Errorf(\"failed to create stdin pipe: %w\", err)\n\t}\n\n\tstdout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\tcancel()\n\t\tstdin.Close()\n\t\treturn fmt.Errorf(\"failed to create stdout pipe: %w\", err)\n\t}\n\n\tcmd.Stderr = os.Stderr\n\n\t// Start the process\n\terr = cmd.Start()\n\tif err != nil {\n\t\tcancel()\n\t\tstdin.Close()\n\t\tstdout.Close()\n\t\treturn fmt.Errorf(\"failed to start Python worker: %w\", err)\n\t}\n\n\tc.cmd = cmd\n\tc.stdin = stdin\n\tc.stdout = stdout\n\tc.info.Active = true\n\tc.done = make(chan struct{})\n\n\tc.logger.Debug(\"Started interpreter context\", \"contextId\", c.info.ID, \"pid\", c.cmd.Process.Pid)\n\n\t// Start reading worker output\n\tgo c.workerReadLoop()\n\n\t// Monitor process exit\n\tgo c.monitorProcess()\n\n\treturn nil\n}\n\n// detectPythonCommand attempts to find a working python interpreter\nfunc detectPythonCommand() string {\n\tcandidates := []string{\"python3\", \"python\"}\n\tfor _, c := range candidates {\n\t\tif _, err := exec.LookPath(c); err == nil {\n\t\t\treturn c\n\t\t}\n\t}\n\treturn \"python3\"\n}\n\n// sendCommand sends a command to the Python worker\nfunc (c *Context) sendCommand(cmd WorkerCommand) error {\n\tc.mu.Lock()\n\tstdin := c.stdin\n\tc.mu.Unlock()\n\n\tif stdin == nil {\n\t\treturn errors.New(\"worker stdin not available\")\n\t}\n\n\tdata, err := json.Marshal(cmd)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshal command: %w\", err)\n\t}\n\n\tdata = append(data, '\\n')\n\t_, err = stdin.Write(data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to write command: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// workerReadLoop reads messages from the Python worker\nfunc (c *Context) workerReadLoop() {\n\tscanner := bufio.NewScanner(c.stdout)\n\tscanner.Buffer(make([]byte, 64*1024), 1024*1024)\n\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\n\t\tvar chunk map[string]any\n\t\terr := json.Unmarshal([]byte(line), &chunk)\n\t\tif err != nil {\n\t\t\tc.logger.Error(\"Failed to parse worker chunk\", \"error\", err)\n\t\t\tcontinue\n\t\t}\n\t\tc.handleChunk(chunk)\n\t}\n\n\terr := scanner.Err()\n\tif err != nil {\n\t\tc.logger.Error(\"Error reading from worker\", \"error\", err)\n\t}\n}\n\n// handleChunk processes streaming chunks from the Python worker\nfunc (c *Context) handleChunk(chunk map[string]any) {\n\t// Extract all fields at the beginning\n\tchunkType := getStringFromChunk(chunk, \"type\")\n\ttext := getStringFromChunk(chunk, \"text\")\n\tname := getStringFromChunk(chunk, \"name\")\n\tvalue := getStringFromChunk(chunk, \"value\")\n\ttraceback := getStringFromChunk(chunk, \"traceback\")\n\n\t// Update internal command state for certain chunk types\n\tswitch chunkType {\n\tcase ChunkTypeError:\n\t\tc.commandMu.Lock()\n\t\tif c.activeCommand != nil {\n\t\t\tc.activeCommand.Status = CommandStatusError\n\t\t\tnow := time.Now()\n\t\t\tc.activeCommand.EndedAt = &now\n\t\t\tc.activeCommand.Error = &Error{\n\t\t\t\tName:      name,\n\t\t\t\tValue:     value,\n\t\t\t\tTraceback: traceback,\n\t\t\t}\n\t\t}\n\t\tc.commandMu.Unlock()\n\tcase ChunkTypeControl:\n\t\tc.commandMu.Lock()\n\t\tif c.activeCommand != nil {\n\t\t\tswitch text {\n\t\t\tcase ControlChunkTypeCompleted:\n\t\t\t\t// Only set to OK if no error occurred (status would be Error already)\n\t\t\t\tif c.activeCommand.Status == CommandStatusRunning {\n\t\t\t\t\tc.activeCommand.Status = CommandStatusOK\n\t\t\t\t}\n\t\t\t\tnow := time.Now()\n\t\t\t\tc.activeCommand.EndedAt = &now\n\t\t\tcase ControlChunkTypeInterrupted:\n\t\t\t\tc.activeCommand.Status = CommandStatusTimeout\n\t\t\t\tnow := time.Now()\n\t\t\t\tc.activeCommand.EndedAt = &now\n\t\t\t}\n\t\t}\n\t\tc.commandMu.Unlock()\n\t\treturn\n\t}\n\n\t// Stream to WebSocket client\n\tc.emitOutput(&OutputMessage{\n\t\tType:      chunkType,\n\t\tText:      text,\n\t\tName:      name,\n\t\tValue:     value,\n\t\tTraceback: traceback,\n\t})\n}\n\n// Helper functions\nfunc getStringFromChunk(chunk map[string]any, key string) string {\n\tif val, ok := chunk[key].(string); ok {\n\t\treturn val\n\t}\n\treturn \"\"\n}\n\n// monitorProcess monitors the worker process and cleans up on exit\nfunc (c *Context) monitorProcess() {\n\terr := c.cmd.Wait()\n\n\tc.mu.Lock()\n\tc.info.Active = false\n\tcontextID := c.info.ID\n\tdone := c.done\n\tc.mu.Unlock()\n\n\t// Notify waiters that the process has exited\n\tif done != nil {\n\t\tclose(done)\n\t}\n\n\tif err != nil {\n\t\tc.commandMu.Lock()\n\t\tif c.activeCommand != nil && c.activeCommand.Status == CommandStatusRunning {\n\t\t\tc.activeCommand.Status = CommandStatusError\n\t\t\tnow := time.Now()\n\t\t\tc.activeCommand.EndedAt = &now\n\t\t\tc.activeCommand.Error = &Error{\n\t\t\t\tName:  \"WorkerProcessError\",\n\t\t\t\tValue: err.Error(),\n\t\t\t}\n\t\t}\n\t\tc.commandMu.Unlock()\n\t\tc.logger.Error(\"Interpreter context process exited with error\", \"contextId\", contextID, \"error\", err)\n\t} else {\n\t\tc.logger.Debug(\"Interpreter context process exited normally\", \"contextId\", contextID)\n\t}\n\n\t// Close WebSocket client if any\n\tc.closeClient(websocket.CloseGoingAway, \"worker process ended\")\n}\n\n// shutdown gracefully shuts down the worker\nfunc (c *Context) shutdown() {\n\tc.mu.Lock()\n\n\tif !c.info.Active {\n\t\tc.mu.Unlock()\n\t\treturn\n\t}\n\n\t// Get references while we have the lock\n\tcontextID := c.info.ID\n\tcancel := c.cancel\n\tcmd := c.cmd\n\tdone := c.done\n\tqueue := c.queue\n\tc.mu.Unlock()\n\n\t// Close the queue to exit processQueue goroutine and prevent new jobs\n\tif queue != nil {\n\t\tclose(queue)\n\t\tc.queue = nil\n\t}\n\n\t// Send SIGTERM to trigger immediate graceful shutdown (not queued)\n\tif cmd != nil && cmd.Process != nil {\n\t\t_ = cmd.Process.Signal(syscall.SIGTERM)\n\t}\n\n\t// Wait for process to exit (monitorProcess will close the done channel)\n\tif done != nil {\n\t\tselect {\n\t\tcase <-done:\n\t\t\t// Process exited gracefully\n\t\t\tc.logger.Debug(\"Interpreter context shut down gracefully\", \"contextId\", contextID)\n\t\tcase <-time.After(2 * time.Second):\n\t\t\t// Timeout - force kill\n\t\t\tc.logger.Debug(\"Interpreter context shutdown timeout, force killing\", \"contextId\", contextID)\n\t\t\tif cancel != nil {\n\t\t\t\tcancel()\n\t\t\t}\n\t\t\tif cmd != nil && cmd.Process != nil {\n\t\t\t\t_ = cmd.Process.Kill()\n\t\t\t}\n\t\t\t// Wait a bit more for kill to take effect\n\t\t\ttime.Sleep(100 * time.Millisecond)\n\t\t}\n\t}\n\n\t// Close WebSocket client\n\tc.closeClient(websocket.CloseGoingAway, \"context shutdown\")\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/interpreter/repl_worker.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: AGPL-3.0\n\n\"\"\"\nStateful Python REPL Worker for Daytona\n- JSON line protocol (stdout)\n- Persistent globals across exec calls\n- Clean user-only tracebacks\n- Graceful SIGINT\n\"\"\"\n\nimport io\nimport json\nimport os\nimport signal\nimport sys\nimport traceback\nfrom contextlib import redirect_stderr, redirect_stdout\n\n\nclass REPLWorker:\n    def __init__(self):\n        self.globals = {\n            \"__name__\": \"__main__\",\n            \"__doc__\": None,\n            \"__package__\": None,\n            \"__builtins__\": __builtins__,\n        }\n        self.should_shutdown = False\n        self._setup_signals()\n\n    # ---------- IO ----------\n    def _emit(self, chunk: dict):\n        try:\n            json.dump(chunk, sys.__stdout__)\n            sys.__stdout__.write(\"\\n\")\n            sys.__stdout__.flush()\n        except Exception as e:\n            sys.__stderr__.write(f\"Failed to send chunk: {e}\\n\")\n\n    class _StreamEmitter(io.TextIOBase):\n        def __init__(self, worker: \"REPLWorker\", stream_type: str):\n            self.worker = worker\n            self.stream_type = stream_type\n            self._buffer: list[str] = []\n\n        def writable(self):\n            return True\n\n        def write(self, data):  # type: ignore[override]\n            if not data:\n                return 0\n            if not isinstance(data, str):\n                data = str(data)\n            self._buffer.append(data)\n            if \"\\n\" in data or sum(len(chunk) for chunk in self._buffer) >= 1024:\n                self.flush()\n            return len(data)\n\n        def flush(self):  # type: ignore[override]\n            if not self._buffer:\n                return\n            payload = \"\".join(self._buffer)\n            self._buffer.clear()\n            # pylint: disable=protected-access\n            self.worker._emit({\"type\": self.stream_type, \"text\": payload})\n\n        def isatty(self):\n            return False\n\n        @property\n        def encoding(self):\n            return \"utf-8\"\n\n        def close(self):  # type: ignore[override]\n            self.flush()\n            return super().close()\n\n    # ---------- Signals ----------\n    def _setup_signals(self):\n        def sigint_handler(_signum, _frame):\n            raise KeyboardInterrupt(\"Execution interrupted\")\n\n        def sigterm_handler(_signum, _frame):\n            self.should_shutdown = True\n            raise KeyboardInterrupt(\"Shutting down\")\n\n        signal.signal(signal.SIGINT, sigint_handler)\n        signal.signal(signal.SIGTERM, sigterm_handler)\n\n    # ---------- Tracebacks ----------\n    def _clean_tb(self, etype, evalue, tb):\n        frames = [f for f in traceback.extract_tb(tb) if f.filename == \"<string>\"]\n        if not frames:\n            return f\"{etype.__name__}: {evalue}\\n\"\n        parts = [\"Traceback (most recent call last):\\n\"]\n        for f in frames:\n            parts.append(f'  File \"<stdin>\", line {f.lineno}\\n')\n            if f.line:\n                parts.append(f\"    {f.line}\\n\")\n        parts.append(f\"{etype.__name__}: {evalue}\\n\")\n        return \"\".join(parts)\n\n    # ---------- Exec ----------\n    def execute_code(self, code: str, envs=None) -> None:\n        stdout_emitter = self._StreamEmitter(self, \"stdout\")\n        stderr_emitter = self._StreamEmitter(self, \"stderr\")\n        control_text, error_chunk = \"completed\", None\n        env_snapshot = None\n\n        if envs:\n            env_snapshot = {}\n            for key, value in envs.items():\n                if not isinstance(key, str):\n                    key = str(key)\n                previous = os.environ.get(key)\n                env_snapshot[key] = previous\n\n                if value is None:\n                    os.environ.pop(key, None)\n                else:\n                    os.environ[key] = str(value)\n\n        try:\n            with redirect_stdout(stdout_emitter), redirect_stderr(stderr_emitter):\n                compiled = compile(code, \"<string>\", \"exec\")\n                exec(compiled, self.globals)  # pylint: disable=exec-used\n\n        except KeyboardInterrupt:\n            control_text = \"interrupted\"\n\n        except (SystemExit, Exception) as e:\n            # SystemExit completes normally\n            # Errors are indicated by the error chunk, not control type\n            if not isinstance(e, SystemExit):\n                error_chunk = {\n                    \"type\": \"error\",\n                    \"name\": type(e).__name__,\n                    \"value\": str(e),\n                    \"traceback\": self._clean_tb(type(e), e, e.__traceback__),\n                }\n        finally:\n            stdout_emitter.flush()\n            stderr_emitter.flush()\n            if env_snapshot is not None:\n                for key, previous in env_snapshot.items():\n                    if previous is None:\n                        os.environ.pop(key, None)\n                    else:\n                        os.environ[key] = previous\n            if error_chunk:\n                self._emit(error_chunk)\n            self._emit({\"type\": \"control\", \"text\": control_text})\n\n    # ---------- Protocol ----------\n    def handle_command(self, line: str) -> None:\n        try:\n            msg = json.loads(line)\n            envs = msg.get(\"envs\")\n            if envs is not None and not isinstance(envs, dict):\n                raise ValueError(\"envs must be an object\")\n            self.execute_code(msg.get(\"code\", \"\"), envs)\n        except json.JSONDecodeError as e:\n            self._emit({\"type\": \"error\", \"name\": \"JSONDecodeError\", \"value\": str(e), \"traceback\": \"\"})\n        except Exception as e:\n            self._emit({\"type\": \"error\", \"name\": type(e).__name__, \"value\": str(e), \"traceback\": \"\"})\n\n    # ---------- Main loop ----------\n    def run(self):\n        while True:\n            if self.should_shutdown:\n                break\n\n            try:\n                line = sys.stdin.readline()\n                if not line:\n                    break  # EOF\n                line = line.strip()\n                if not line:\n                    continue\n                self.handle_command(line)\n            except KeyboardInterrupt:\n                continue\n            except Exception as e:\n                sys.__stderr__.write(f\"Fatal error in main loop: {e}\\n\")\n                break\n\n\nif __name__ == \"__main__\":\n    REPLWorker().run()\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/interpreter/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage interpreter\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os/exec\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n)\n\n// Constants for WebSocket and execution management\nconst (\n\twriteWait         = 10 * time.Second\n\tgracePeriod       = 2 * time.Second\n\tworkerScriptPerms = 0700\n)\n\n// WebSocket close codes (4000-4999 are for private/application use)\nconst (\n\tWebSocketCloseTimeout = 4008 // Execution timeout\n)\n\n// Chunk type constants for websocket streaming\nconst (\n\tChunkTypeStdout  = \"stdout\"\n\tChunkTypeStderr  = \"stderr\"\n\tChunkTypeError   = \"error\"\n\tChunkTypeControl = \"control\"\n)\n\n// Control chunk subtypes\nconst (\n\tControlChunkTypeCompleted   = \"completed\"\n\tControlChunkTypeInterrupted = \"interrupted\"\n)\n\n// Command execution statuses\nconst (\n\tCommandStatusRunning = \"running\"\n\tCommandStatusOK      = \"ok\"\n\tCommandStatusError   = \"error\"\n\tCommandStatusTimeout = \"timeout\"\n)\n\n// Supported languages\nconst (\n\tLanguagePython = \"python\"\n)\n\n// Controller handles interpreter-related HTTP endpoints\ntype Controller struct {\n\tlogger  *slog.Logger\n\tworkDir string\n}\n\n// API Request/Response types\n\n// CreateContextRequest represents a request to create a new interpreter context\ntype CreateContextRequest struct {\n\tCwd      *string `json:\"cwd\" validate:\"optional\"`\n\tLanguage *string `json:\"language\" validate:\"optional\"`\n} // @name CreateContextRequest\n\n// ExecuteRequest represents a request to execute code\ntype ExecuteRequest struct {\n\tCode      string             `json:\"code\" binding:\"required\"`\n\tContextID *string            `json:\"contextId\" validate:\"optional\"`\n\tTimeout   *int64             `json:\"timeout\" validate:\"optional\"` // seconds, 0 disables timeout\n\tEnvs      *map[string]string `json:\"envs\" validate:\"optional\"`\n} // @name ExecuteRequest\n\n// ListContextsResponse represents the response when listing contexts\ntype ListContextsResponse struct {\n\tContexts []ContextInfo `json:\"contexts\" binding:\"required\"`\n} // @name ListContextsResponse\n\n// Context types\n\n// ContextInfo contains metadata about an interpreter context\ntype ContextInfo struct {\n\tID        string    `json:\"id\" binding:\"required\"`\n\tCwd       string    `json:\"cwd\" binding:\"required\"`\n\tCreatedAt time.Time `json:\"createdAt\" binding:\"required\"`\n\tActive    bool      `json:\"active\" binding:\"required\"`\n\tLanguage  string    `json:\"language\" binding:\"required\"`\n} // @name InterpreterContext\n\n// Context represents an active interpreter context with operational methods\ntype Context struct {\n\tinfo ContextInfo\n\n\tlogger *slog.Logger\n\n\tcmd        *exec.Cmd\n\tstdin      io.WriteCloser\n\tstdout     io.ReadCloser\n\tctx        context.Context\n\tcancel     context.CancelFunc\n\tworkerPath string\n\n\t// Single websocket client (protected by mu)\n\tclient *wsClient\n\n\t// Command tracking\n\tactiveCommand *CommandExecution\n\tcommandMu     sync.Mutex\n\n\t// Execution FIFO queue\n\tqueue chan execJob\n\n\t// Process exit notification\n\tdone chan struct{}\n\n\t// Guards session state and client\n\tmu sync.Mutex\n}\n\n// CommandExecution tracks a single code execution\ntype CommandExecution struct {\n\tID        string     `json:\"id\" binding:\"required\"`\n\tCode      string     `json:\"code\" binding:\"required\"`\n\tStatus    string     `json:\"status\" binding:\"required\"` // \"running\", \"ok\", \"error\", \"interrupted\", \"exit\", \"timeout\"\n\tError     *Error     `json:\"error,omitempty\"`\n\tStartedAt time.Time  `json:\"startedAt\" binding:\"required\"`\n\tEndedAt   *time.Time `json:\"endedAt,omitempty\"`\n}\n\n// Error represents a structured error from code execution\ntype Error struct {\n\tName      string `json:\"name\" binding:\"required\"`\n\tValue     string `json:\"value\" binding:\"required\"`\n\tTraceback string `json:\"traceback\" binding:\"required\"`\n}\n\n// Internal types\n\n// wsClient represents a WebSocket client connection for output streaming\ntype wsClient struct {\n\tid        string\n\tconn      *websocket.Conn\n\tsend      chan wsFrame\n\tpongCh    <-chan []byte // queued pong payloads from PingHandler, drained by clientWriter\n\tdone      chan struct{} // signals when clientWriter exits\n\tcloseOnce sync.Once\n\tlogger    *slog.Logger\n}\n\ntype wsFrame struct {\n\toutput *OutputMessage\n\tclose  *closeRequest\n}\n\ntype closeRequest struct {\n\tcode    int\n\tmessage string\n}\n\n// OutputMessage represents output sent to WebSocket clients\ntype OutputMessage struct {\n\tType      string `json:\"type\" binding:\"required\"`\n\tText      string `json:\"text\" binding:\"required\"`\n\tName      string `json:\"name\" binding:\"required\"`\n\tValue     string `json:\"value\" binding:\"required\"`\n\tTraceback string `json:\"traceback\" binding:\"required\"`\n}\n\n// WorkerCommand represents a command sent to the language worker\ntype WorkerCommand struct {\n\tID   string            `json:\"id\" binding:\"required\"`\n\tCode string            `json:\"code\" binding:\"required\"`\n\tEnvs map[string]string `json:\"envs\" binding:\"required\"`\n}\n\n// execJob represents one queued execution\ntype execJob struct {\n\tcode    string\n\tenvs    map[string]string\n\ttimeout time.Duration\n\tws      *websocket.Conn\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/interpreter/websocket.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage interpreter\n\nimport (\n\t\"encoding/json\"\n\t\"log/slog\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daemon/internal/util\"\n\t\"github.com/google/uuid\"\n\t\"github.com/gorilla/websocket\"\n)\n\n// attachWebSocket connects a WebSocket client to the interpreter context\nfunc (c *Context) attachWebSocket(ws *websocket.Conn) {\n\tpongCh := util.SetupWSKeepAlive(ws, c.logger)\n\n\tclientId := uuid.NewString()\n\tcl := &wsClient{\n\t\tid:     clientId,\n\t\tconn:   ws,\n\t\tsend:   make(chan wsFrame, 1024),\n\t\tpongCh: pongCh,\n\t\tdone:   make(chan struct{}),\n\t\tlogger: c.logger.With(slog.String(\"clientId\", clientId)),\n\t}\n\n\tc.mu.Lock()\n\tif c.client != nil {\n\t\tc.client.close()\n\t}\n\tc.client = cl\n\tc.mu.Unlock()\n\n\tc.logger.Debug(\"Client attached to interpreter context\", \"clientId\", cl.id, \"contextId\", c.info.ID)\n\n\tgo c.clientWriter(cl)\n\t// Continuously read from the WebSocket so that gorilla/websocket's\n\t// PingHandler is invoked for incoming ping frames. Without this,\n\t// client keepalive pings go unanswered and the connection is closed\n\t// with code 1011 after ~50s.\n\tgo func() {\n\t\tfor {\n\t\t\tif _, _, err := ws.ReadMessage(); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Wait for clientWriter to exit (signals disconnection)\n\t<-cl.done\n\n\tc.mu.Lock()\n\tif c.client != nil && c.client.id == cl.id {\n\t\tc.client = nil\n\t}\n\tc.mu.Unlock()\n\n\tcl.close()\n\tc.logger.Debug(\"Client detached from interpreter context\", \"clientId\", cl.id, \"contextId\", c.info.ID)\n}\n\n// clientWriter sends output messages to the WebSocket client\nfunc (c *Context) clientWriter(cl *wsClient) {\n\tdefer close(cl.done)\n\n\tfor {\n\t\t// Priority: always flush pending pong responses before writing data.\n\t\t// This ensures keepalive pongs are never delayed by data writes.\n\t\tutil.WritePendingPongs(cl.conn, cl.pongCh, writeWait, cl.logger)\n\n\t\tselect {\n\t\tcase <-c.ctx.Done():\n\t\t\treturn\n\t\tcase pong := <-cl.pongCh:\n\t\t\t// Pong arrived while waiting for data — write it immediately.\n\t\t\tif err := cl.conn.WriteControl(websocket.PongMessage, pong, time.Now().Add(writeWait)); err != nil {\n\t\t\t\tcl.logger.Debug(\"failed to write pong\", \"error\", err)\n\t\t\t}\n\t\tcase frame, ok := <-cl.send:\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\terr := cl.writeFrame(frame)\n\t\t\tif err != nil {\n\t\t\t\tc.logger.Debug(\"Failed to write frame\", \"error\", err)\n\t\t\t}\n\t\t\tif frame.close != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\n// emitOutput sends an output message to the connected WebSocket client\nfunc (c *Context) emitOutput(msg *OutputMessage) {\n\tc.mu.Lock()\n\tcl := c.client\n\tc.mu.Unlock()\n\n\tif cl == nil {\n\t\treturn\n\t}\n\n\tselect {\n\tcase cl.send <- wsFrame{output: msg}:\n\tdefault:\n\t\tc.logger.Debug(\"Client send channel full - closing slow consumer\")\n\t\tcl.requestClose(websocket.ClosePolicyViolation, \"slow consumer\")\n\n\t\tc.mu.Lock()\n\t\tif c.client != nil && c.client.id == cl.id {\n\t\t\tc.client = nil\n\t\t}\n\t\tc.mu.Unlock()\n\t}\n}\n\n// close closes a WebSocket client connection\nfunc (cl *wsClient) close() {\n\tcl.closeOnce.Do(func() {\n\t\tclose(cl.send)\n\n\t\t// Wait for clientWriter to drain remaining messages with a timeout\n\t\t// This ensures close frames and other pending messages have time to be sent\n\t\ttimer := time.NewTimer(5 * time.Second)\n\t\tselect {\n\t\tcase <-cl.done:\n\t\t\t// clientWriter has finished processing all messages\n\t\t\tif !timer.Stop() {\n\t\t\t\t<-timer.C\n\t\t\t}\n\t\tcase <-timer.C:\n\t\t\t// Timeout reached, proceed with closing\n\t\t\tcl.logger.Debug(\"Timeout waiting for client writer to finish\")\n\t\t}\n\n\t\t// Close the connection. The background read goroutine started in\n\t\t// attachWebSocket is the sole reader — gorilla's default CloseHandler\n\t\t// (invoked during ReadMessage) handles the RFC 6455 close handshake.\n\t\t// We must not call NextReader/ReadMessage here to avoid violating\n\t\t// gorilla's single-concurrent-reader rule.\n\t\t_ = cl.conn.Close()\n\t})\n}\n\nfunc (cl *wsClient) writeFrame(frame wsFrame) error {\n\tif frame.output == nil && frame.close == nil {\n\t\treturn nil\n\t}\n\n\terr := cl.conn.SetWriteDeadline(time.Now().Add(writeWait))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif frame.close != nil {\n\t\tpayload := websocket.FormatCloseMessage(frame.close.code, frame.close.message)\n\t\treturn cl.conn.WriteMessage(websocket.CloseMessage, payload)\n\t}\n\n\tdata, err := json.Marshal(frame.output)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn cl.conn.WriteMessage(websocket.TextMessage, data)\n}\n\nfunc (cl *wsClient) requestClose(code int, message string) {\n\tframe := wsFrame{\n\t\tclose: &closeRequest{\n\t\t\tcode:    code,\n\t\t\tmessage: message,\n\t\t},\n\t}\n\n\tselect {\n\tcase cl.send <- frame:\n\tdefault:\n\t\tcl.logger.Debug(\"Couldn't send close frame to client - closing connection\")\n\t}\n\n\tcl.close()\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/pty/controller.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage pty\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daemon/internal/util\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/gorilla/websocket\"\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n)\n\n// NewPTYController creates a new PTY controller\nfunc NewPTYController(logger *slog.Logger, workDir string) *PTYController {\n\treturn &PTYController{logger: logger.With(slog.String(\"component\", \"PTY_controller\")), workDir: workDir}\n}\n\n// CreatePTYSession godoc\n//\n//\t@Summary\t\tCreate a new PTY session\n//\t@Description\tCreate a new pseudo-terminal session with specified configuration\n//\t@Tags\t\t\tprocess\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tPTYCreateRequest\ttrue\t\"PTY session creation request\"\n//\t@Success\t\t201\t\t{object}\tPTYCreateResponse\n//\t@Router\t\t\t/process/pty [post]\n//\n//\t@id\t\t\t\tCreatePtySession\nfunc (p *PTYController) CreatePTYSession(c *gin.Context) {\n\tvar req PTYCreateRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\t// Validate session ID\n\tif req.ID == \"\" {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"session ID is required\"})\n\t\treturn\n\t}\n\n\t// Check if session with this ID already exists\n\tif _, exists := ptyManager.Get(req.ID); exists {\n\t\tc.JSON(http.StatusConflict, gin.H{\"error\": fmt.Sprintf(\"PTY session with ID '%s' already exists\", req.ID)})\n\t\treturn\n\t}\n\n\t// Defaults\n\tif req.Cwd == \"\" {\n\t\treq.Cwd = p.workDir\n\t}\n\tif req.Envs == nil {\n\t\treq.Envs = make(map[string]string, 1)\n\t}\n\tif req.Envs[\"TERM\"] == \"\" {\n\t\treq.Envs[\"TERM\"] = \"xterm-256color\"\n\t}\n\tif req.Cols == nil {\n\t\treq.Cols = util.Pointer(uint16(80))\n\t}\n\tif req.Rows == nil {\n\t\treq.Rows = util.Pointer(uint16(24))\n\t}\n\t// Set upper limits to avoid ioctl errors\n\tif *req.Cols > 1000 {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"invalid value for cols - must be less than 1000\"})\n\t\treturn\n\t}\n\tif *req.Rows > 1000 {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"invalid value for rows - must be less than 1000\"})\n\t\treturn\n\t}\n\n\tsession := &PTYSession{\n\t\tinfo: PTYSessionInfo{\n\t\t\tID:        req.ID,\n\t\t\tCwd:       req.Cwd,\n\t\t\tEnvs:      req.Envs,\n\t\t\tCols:      *req.Cols,\n\t\t\tRows:      *req.Rows,\n\t\t\tCreatedAt: time.Now(),\n\t\t\tActive:    false,\n\t\t\tLazyStart: req.LazyStart,\n\t\t},\n\t\tclients: cmap.New[*wsClient](),\n\t\tlogger:  p.logger.With(slog.String(\"sessionId\", req.ID)),\n\t}\n\n\t// Add to manager first to prevent race conditions\n\tptyManager.Add(session)\n\n\t// Start PTY immediately if not lazy start (default behavior)\n\tif !req.LazyStart {\n\t\tif err := session.start(); err != nil {\n\t\t\t// If start fails, remove from manager\n\t\t\tptyManager.Delete(req.ID)\n\t\t\tp.logger.Error(\"failed to start PTY at create\", \"error\", err)\n\t\t\tc.JSON(http.StatusInternalServerError, gin.H{\"error\": \"failed to start PTY session\"})\n\t\t\treturn\n\t\t}\n\t}\n\n\tc.JSON(http.StatusCreated, PTYCreateResponse{SessionID: req.ID})\n}\n\n// ListPTYSessions godoc\n//\n//\t@Summary\t\tList all PTY sessions\n//\t@Description\tGet a list of all active pseudo-terminal sessions\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tPTYListResponse\n//\t@Router\t\t\t/process/pty [get]\n//\n//\t@id\t\t\t\tListPtySessions\nfunc (p *PTYController) ListPTYSessions(c *gin.Context) {\n\tc.JSON(http.StatusOK, PTYListResponse{Sessions: ptyManager.List()})\n}\n\n// GetPTYSession godoc\n//\n//\t@Summary\t\tGet PTY session information\n//\t@Description\tGet detailed information about a specific pseudo-terminal session\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsessionId\tpath\t\tstring\ttrue\t\"PTY session ID\"\n//\t@Success\t\t200\t\t\t{object}\tPTYSessionInfo\n//\t@Router\t\t\t/process/pty/{sessionId} [get]\n//\n//\t@id\t\t\t\tGetPtySession\nfunc (p *PTYController) GetPTYSession(c *gin.Context) {\n\tid := c.Param(\"sessionId\")\n\tif id == \"\" {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"session ID is required\"})\n\t\treturn\n\t}\n\n\tif s, ok := ptyManager.Get(id); ok {\n\t\tc.JSON(http.StatusOK, s.Info())\n\t\treturn\n\t}\n\tc.JSON(http.StatusNotFound, gin.H{\"error\": \"PTY session not found\"})\n}\n\n// DeletePTYSession godoc\n//\n//\t@Summary\t\tDelete a PTY session\n//\t@Description\tDelete a pseudo-terminal session and terminate its process\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsessionId\tpath\t\tstring\ttrue\t\"PTY session ID\"\n//\t@Success\t\t200\t\t\t{object}\tgin.H\n//\t@Router\t\t\t/process/pty/{sessionId} [delete]\n//\n//\t@id\t\t\t\tDeletePtySession\nfunc (p *PTYController) DeletePTYSession(c *gin.Context) {\n\tid := c.Param(\"sessionId\")\n\tif id == \"\" {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"session ID is required\"})\n\t\treturn\n\t}\n\n\tif s, ok := ptyManager.Delete(id); ok {\n\t\ts.kill()\n\t\tp.logger.Debug(\"Deleted PTY session\", \"sessionId\", id)\n\t\tc.JSON(http.StatusOK, gin.H{\"message\": \"PTY session deleted\"})\n\t\treturn\n\t}\n\tc.JSON(http.StatusNotFound, gin.H{\"error\": \"PTY session not found\"})\n}\n\n// ConnectPTYSession godoc\n//\n//\t@Summary\t\tConnect to PTY session via WebSocket\n//\t@Description\tEstablish a WebSocket connection to interact with a pseudo-terminal session\n//\t@Tags\t\t\tprocess\n//\t@Param\t\t\tsessionId\tpath\tstring\ttrue\t\"PTY session ID\"\n//\t@Success\t\t101\t\t\t\"Switching Protocols - WebSocket connection established\"\n//\t@Router\t\t\t/process/pty/{sessionId}/connect [get]\n//\n//\t@id\t\t\t\tConnectPtySession\nfunc (p *PTYController) ConnectPTYSession(c *gin.Context) {\n\tid := c.Param(\"sessionId\")\n\tif id == \"\" {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"session ID is required\"})\n\t\treturn\n\t}\n\n\t// Upgrade to WebSocket\n\tws, err := util.UpgradeToWebSocket(c.Writer, c.Request)\n\tif err != nil {\n\t\tp.logger.Error(\"ws upgrade failed\", \"error\", err)\n\t\treturn\n\t}\n\n\tsession, err := ptyManager.VerifyPTYSessionReady(id)\n\tif err != nil {\n\t\tp.logger.Debug(\"failed to connect to PTY session\", \"sessionId\", id, \"error\", err)\n\t\t// Send error control message\n\t\terrorMsg := map[string]interface{}{\n\t\t\t\"type\":   \"control\",\n\t\t\t\"status\": \"error\",\n\t\t\t\"error\":  \"Failed to connect to PTY session: \" + err.Error(),\n\t\t}\n\t\tif errorJSON, err := json.Marshal(errorMsg); err == nil {\n\t\t\t_ = ws.WriteMessage(websocket.TextMessage, errorJSON)\n\t\t}\n\t\t_ = ws.Close()\n\t\treturn\n\t}\n\n\t// Attach to session - this will send the control message internally\n\tsession.attachWebSocket(ws)\n}\n\n// ResizePTYSession godoc\n//\n//\t@Summary\t\tResize a PTY session\n//\t@Description\tResize the terminal dimensions of a pseudo-terminal session\n//\t@Tags\t\t\tprocess\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsessionId\tpath\t\tstring\t\t\t\ttrue\t\"PTY session ID\"\n//\t@Param\t\t\trequest\t\tbody\t\tPTYResizeRequest\ttrue\t\"Resize request with new dimensions\"\n//\t@Success\t\t200\t\t\t{object}\tPTYSessionInfo\n//\t@Router\t\t\t/process/pty/{sessionId}/resize [post]\n//\n//\t@id\t\t\t\tResizePtySession\nfunc (p *PTYController) ResizePTYSession(c *gin.Context) {\n\tid := c.Param(\"sessionId\")\n\tif id == \"\" {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"session ID is required\"})\n\t\treturn\n\t}\n\n\tvar req PTYResizeRequest\n\tif err := c.ShouldBindJSON(&req); err != nil {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\tif req.Cols > 1000 {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"cols must be less than 1000\"})\n\t\treturn\n\t}\n\tif req.Rows > 1000 {\n\t\tc.JSON(http.StatusBadRequest, gin.H{\"error\": \"rows must be less than 1000\"})\n\t\treturn\n\t}\n\n\tsession, err := ptyManager.VerifyPTYSessionForResize(id)\n\tif err != nil {\n\t\tc.JSON(http.StatusGone, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\n\tif err := session.resize(req.Cols, req.Rows); err != nil {\n\t\tc.JSON(http.StatusInternalServerError, gin.H{\"error\": err.Error()})\n\t\treturn\n\t}\n\tp.logger.Debug(\"Resized PTY session\", \"sessionId\", id, \"cols\", req.Cols, \"rows\", req.Rows)\n\n\t// Return updated session info\n\tupdatedInfo := session.Info()\n\tc.JSON(http.StatusOK, updatedInfo)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/pty/manager.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage pty\n\nimport (\n\t\"fmt\"\n\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n)\n\n// Global PTY manager instance\nvar ptyManager = &PTYManager{\n\tsessions: cmap.New[*PTYSession](),\n}\n\n// NewPTYManager creates a new PTY manager instance\nfunc NewPTYManager() *PTYManager {\n\treturn &PTYManager{\n\t\tsessions: cmap.New[*PTYSession](),\n\t}\n}\n\n// Add adds a PTY session to the manager\nfunc (m *PTYManager) Add(s *PTYSession) {\n\tm.sessions.Set(s.info.ID, s)\n}\n\n// Get retrieves a PTY session by ID\nfunc (m *PTYManager) Get(id string) (*PTYSession, bool) {\n\ts, ok := m.sessions.Get(id)\n\treturn s, ok\n}\n\n// Delete removes a PTY session from the manager\nfunc (m *PTYManager) Delete(id string) (*PTYSession, bool) {\n\ts, ok := m.sessions.Get(id)\n\tif ok {\n\t\tm.sessions.Remove(id)\n\t}\n\treturn s, ok\n}\n\n// List returns information about all managed PTY sessions\nfunc (m *PTYManager) List() []PTYSessionInfo {\n\tout := make([]PTYSessionInfo, 0, m.sessions.Count())\n\tfor _, s := range m.sessions.Items() {\n\t\tout = append(out, s.Info())\n\t}\n\treturn out\n}\n\nfunc (m *PTYManager) VerifyPTYSessionReady(id string) (*PTYSession, error) {\n\t// Validate session existence and send control message\n\tsession, ok := ptyManager.Get(id)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"PTY session %s not found\", id)\n\t}\n\n\tsessionInfo := session.Info()\n\n\t// Handle inactive sessions based on lazy start flag\n\tif !sessionInfo.Active {\n\t\tif sessionInfo.LazyStart {\n\t\t\t// Lazy start session - start PTY on first client connection\n\t\t\tif err := session.start(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to start PTY session: %v\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Non-lazy session that's inactive means it has terminated\n\t\t\treturn nil, fmt.Errorf(\"PTY session '%s' has terminated and is no longer available\", id)\n\t\t}\n\t}\n\n\treturn session, nil\n}\n\nfunc (m *PTYManager) VerifyPTYSessionForResize(id string) (*PTYSession, error) {\n\tsession, ok := ptyManager.Get(id)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"PTY session %s not found\", id)\n\t}\n\n\tsessionInfo := session.Info()\n\n\t// Check if session can be resized\n\tif !sessionInfo.Active && !sessionInfo.LazyStart {\n\t\t// Non-lazy session that's inactive means it has terminated\n\t\treturn nil, fmt.Errorf(\"PTY session '%s' has terminated and cannot be resized\", id)\n\t}\n\n\treturn session, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/pty/session.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage pty\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\n\t\"github.com/creack/pty\"\n\t\"github.com/daytonaio/daemon/pkg/common\"\n)\n\n// Info returns the current session information\nfunc (s *PTYSession) Info() PTYSessionInfo {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.info\n}\n\n// start initializes and starts the PTY session\nfunc (s *PTYSession) start() error {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\t// already running?\n\tif s.info.Active && s.cmd != nil && s.ptmx != nil {\n\t\treturn nil\n\t}\n\n\t// Prevent restarting - once a session exits, it should be removed from manager\n\tif s.cmd != nil {\n\t\treturn errors.New(\"PTY session has already been used and cannot be restarted\")\n\t}\n\n\tif s.inCh == nil {\n\t\ts.inCh = make(chan []byte, 1024)\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\ts.ctx = ctx\n\ts.cancel = cancel\n\n\tshell := common.GetShell()\n\tif shell == \"\" {\n\t\treturn errors.New(\"no shell resolved\")\n\t}\n\n\tcmd := exec.CommandContext(ctx, shell, \"-i\", \"-l\")\n\tcmd.Dir = s.info.Cwd\n\n\t// Env\n\tcmd.Env = os.Environ()\n\tfor k, v := range s.info.Envs {\n\t\tcmd.Env = append(cmd.Env, fmt.Sprintf(\"%s=%s\", k, v))\n\t}\n\n\tptmx, err := pty.StartWithSize(cmd, &pty.Winsize{Rows: s.info.Rows, Cols: s.info.Cols})\n\tif err != nil {\n\t\tcancel()\n\t\treturn fmt.Errorf(\"pty.StartWithSize: %w\", err)\n\t}\n\n\ts.cmd = cmd\n\ts.ptmx = ptmx\n\ts.info.Active = true\n\n\ts.logger.Debug(\"Started PTY session\", \"sessionId\", s.info.ID, \"pid\", s.cmd.Process.Pid)\n\n\t// 1) PTY -> clients broadcaster\n\tgo s.ptyReadLoop()\n\n\t// 2) clients -> PTY writer\n\tgo s.inputWriteLoop()\n\n\t// Reap the process; mark inactive on exit and send exit event\n\tgo func() {\n\t\terr := s.cmd.Wait()\n\t\tvar exitCode int\n\t\tvar exitReason string\n\n\t\tif err != nil {\n\t\t\tif exitError, ok := err.(*exec.ExitError); ok {\n\t\t\t\texitCode = exitError.ExitCode()\n\t\t\t\t// Analyze the exit code to provide meaningful context\n\t\t\t\tif exitCode == 137 {\n\t\t\t\t\texitReason = \" (SIGKILL)\"\n\t\t\t\t} else if exitCode == 130 {\n\t\t\t\t\texitReason = \" (SIGINT - Ctrl+C)\"\n\t\t\t\t} else if exitCode == 143 {\n\t\t\t\t\texitReason = \" (SIGTERM)\"\n\t\t\t\t} else if exitCode > 128 {\n\t\t\t\t\tsigNum := exitCode - 128\n\t\t\t\t\texitReason = fmt.Sprintf(\" (signal %d)\", sigNum)\n\t\t\t\t} else {\n\t\t\t\t\texitReason = \" (non-zero exit)\"\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\texitCode = 1\n\t\t\t\texitReason = \" (process error)\"\n\t\t\t}\n\t\t} else {\n\t\t\texitCode = 0\n\t\t\texitReason = \" (clean exit)\"\n\t\t}\n\n\t\ts.mu.Lock()\n\t\ts.info.Active = false\n\t\tsessionID := s.info.ID\n\t\ts.mu.Unlock()\n\n\t\t// Close WebSocket connections with exit code and reason\n\t\ts.closeClientsWithExitCode(exitCode, exitReason)\n\n\t\t// Remove session from manager - process has exited and won't be reused\n\t\tptyManager.Delete(sessionID)\n\n\t\ts.logger.Debug(\"PTY session process exited and cleaned up\", \"sessionId\", sessionID, \"exitCode\", exitCode, \"exitReason\", exitReason)\n\t}()\n\n\treturn nil\n}\n\n// kill terminates the PTY session\nfunc (s *PTYSession) kill() {\n\t// kill process and PTY\n\ts.mu.Lock()\n\t// Check if already killed to prevent double-kill\n\tif !s.info.Active {\n\t\ts.mu.Unlock()\n\t\treturn\n\t}\n\n\tsessionID := s.info.ID\n\tif s.cancel != nil {\n\t\ts.cancel()\n\t}\n\tif s.ptmx != nil {\n\t\t_ = s.ptmx.Close()\n\t\ts.ptmx = nil\n\t}\n\tif s.cmd != nil && s.cmd.Process != nil {\n\t\t_ = s.cmd.Process.Kill()\n\t}\n\ts.info.Active = false\n\ts.mu.Unlock()\n\n\t// Close WebSocket connections with kill exit code - 137 = 128 + 9 (SIGKILL)\n\ts.closeClientsWithExitCode(137, \" (SIGKILL)\")\n\n\t// Remove session from manager - manually killed\n\tptyManager.Delete(sessionID)\n}\n\n// ptyReadLoop reads from PTY and broadcasts to all clients\nfunc (s *PTYSession) ptyReadLoop() {\n\tbuf := make([]byte, 32*1024)\n\tfor {\n\t\tn, err := s.ptmx.Read(buf)\n\t\tif n > 0 {\n\t\t\tb := make([]byte, n)\n\t\t\tcopy(b, buf[:n])\n\t\t\ts.broadcast(b)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// inputWriteLoop writes client input to PTY\nfunc (s *PTYSession) inputWriteLoop() {\n\tfor {\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\treturn\n\t\tcase data := <-s.inCh:\n\t\t\tif s.ptmx == nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif _, err := s.ptmx.Write(data); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\n// sendToPTY sends data from a client to the PTY\nfunc (s *PTYSession) sendToPTY(data []byte) error {\n\t// Check if inCh is available to prevent panic\n\tif s.inCh == nil {\n\t\treturn fmt.Errorf(\"PTY session input channel not available\")\n\t}\n\n\tselect {\n\tcase s.inCh <- data:\n\t\treturn nil\n\tcase <-s.ctx.Done():\n\t\treturn fmt.Errorf(\"PTY session input channel closed\")\n\t}\n}\n\n// resize changes the PTY window size\nfunc (s *PTYSession) resize(cols, rows uint16) error {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\t// Check if session is still active\n\tif !s.info.Active {\n\t\treturn errors.New(\"cannot resize inactive PTY session\")\n\t}\n\n\tif cols > 1000 {\n\t\treturn fmt.Errorf(\"cols must be less than 1000\")\n\t}\n\tif rows > 1000 {\n\t\treturn fmt.Errorf(\"rows must be less than 1000\")\n\t}\n\n\ts.info.Cols = cols\n\ts.info.Rows = rows\n\n\tif s.ptmx != nil {\n\t\tif err := pty.Setsize(s.ptmx, &pty.Winsize{Cols: cols, Rows: rows}); err != nil {\n\t\t\ts.logger.Debug(\"PTY resize error\", \"error\", err)\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\treturn errors.New(\"PTY file descriptor is not available\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/pty/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage pty\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/exec\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n)\n\n// Constants\nconst (\n\twriteWait = 10 * time.Second\n\treadLimit = 64 * 1024\n)\n\n// PTYController handles PTY-related HTTP endpoints\ntype PTYController struct {\n\tlogger  *slog.Logger\n\tworkDir string\n}\n\n// PTYManager manages multiple PTY sessions\ntype PTYManager struct {\n\tsessions cmap.ConcurrentMap[string, *PTYSession]\n}\n\n// wsClient represents a WebSocket client connection\ntype wsClient struct {\n\tid        string\n\tconn      *websocket.Conn\n\tsend      chan []byte   // outbound queue for this client (PTY -> WS)\n\tdone      chan struct{} // closed when the client is shutting down\n\tcloseOnce sync.Once\n}\n\n// PTYSession represents a single PTY session with multi-client support\ntype PTYSession struct {\n\tlogger *slog.Logger\n\n\tinfo PTYSessionInfo\n\n\tcmd    *exec.Cmd\n\tptmx   *os.File\n\tctx    context.Context\n\tcancel context.CancelFunc\n\n\t// multi-attach\n\tclients   cmap.ConcurrentMap[string, *wsClient]\n\tclientsMu sync.RWMutex\n\n\t// funnel of all client inputs -> single PTY writer (preserves ordering)\n\tinCh chan []byte\n\n\t// guards general session fields (info/cmd/ptmx)\n\tmu sync.Mutex\n}\n\n// PTYSessionInfo contains metadata about a PTY session\ntype PTYSessionInfo struct {\n\tID        string            `json:\"id\" validate:\"required\"`\n\tCwd       string            `json:\"cwd\" validate:\"required\"`\n\tEnvs      map[string]string `json:\"envs\" validate:\"required\"`\n\tCols      uint16            `json:\"cols\" validate:\"required\"`\n\tRows      uint16            `json:\"rows\" validate:\"required\"`\n\tCreatedAt time.Time         `json:\"createdAt\" validate:\"required\"`\n\tActive    bool              `json:\"active\" validate:\"required\"`\n\tLazyStart bool              `json:\"lazyStart\" validate:\"required\"` // Whether this session uses lazy start\n} // @name PtySessionInfo\n\n// API Request/Response types\n\n// PTYCreateRequest represents a request to create a new PTY session\ntype PTYCreateRequest struct {\n\tID        string            `json:\"id\"`\n\tCwd       string            `json:\"cwd,omitempty\"`\n\tEnvs      map[string]string `json:\"envs,omitempty\"`\n\tCols      *uint16           `json:\"cols\" validate:\"optional\"`\n\tRows      *uint16           `json:\"rows\" validate:\"optional\"`\n\tLazyStart bool              `json:\"lazyStart,omitempty\"` // Don't start PTY until first client connects\n} // @name PtyCreateRequest\n\n// PTYCreateResponse represents the response when creating a PTY session\ntype PTYCreateResponse struct {\n\tSessionID string `json:\"sessionId\" validate:\"required\"`\n} // @name PtyCreateResponse\n\n// PTYListResponse represents the response when listing PTY sessions\ntype PTYListResponse struct {\n\tSessions []PTYSessionInfo `json:\"sessions\" validate:\"required\"`\n} // @name PtyListResponse\n\n// PTYResizeRequest represents a request to resize a PTY session\ntype PTYResizeRequest struct {\n\tCols uint16 `json:\"cols\" binding:\"required,min=1,max=1000\"`\n\tRows uint16 `json:\"rows\" binding:\"required,min=1,max=1000\"`\n} // @name PtyResizeRequest\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/pty/websocket.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage pty\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/gorilla/websocket\"\n)\n\n// attachWebSocket connects a new WebSocket client to the PTY session\nfunc (s *PTYSession) attachWebSocket(ws *websocket.Conn) {\n\tcl := &wsClient{\n\t\tid:   uuid.NewString(),\n\t\tconn: ws,\n\t\tsend: make(chan []byte, 256), // if full, drop slow client\n\t\tdone: make(chan struct{}),\n\t}\n\n\t// Register client FIRST so it can receive PTY output via broadcast\n\ts.clients.Set(cl.id, cl)\n\tcount := s.clients.Count()\n\ts.logger.Debug(\"Client attached to PTY session\", \"clientId\", cl.id, \"sessionId\", s.info.ID, \"clientCount\", count)\n\n\t// Start PTY data flow - writer (PTY -> this client)\n\tgo s.clientWriter(cl)\n\n\t// Send success control message after client is registered and ready\n\tsuccessMsg := map[string]interface{}{\n\t\t\"type\":   \"control\",\n\t\t\"status\": \"connected\",\n\t}\n\tif successJSON, err := json.Marshal(successMsg); err == nil {\n\t\t_ = ws.WriteMessage(websocket.TextMessage, successJSON)\n\t}\n\n\t// reader (this client -> PTY); blocks until disconnect\n\ts.clientReader(cl)\n\n\t// on exit, unregister\n\ts.clients.Remove(cl.id)\n\n\tcl.close()\n\n\tremaining := s.clients.Count()\n\ts.logger.Debug(\"Client detached from PTY session\", \"clientId\", cl.id, \"sessionId\", s.info.ID, \"clientCount\", remaining)\n}\n\n// clientWriter sends PTY output to a specific WebSocket client\nfunc (s *PTYSession) clientWriter(cl *wsClient) {\n\tfor {\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\treturn\n\t\tcase <-cl.done:\n\t\t\treturn\n\t\tcase b := <-cl.send:\n\t\t\t_ = cl.conn.SetWriteDeadline(time.Now().Add(writeWait))\n\t\t\tif err := cl.conn.WriteMessage(websocket.BinaryMessage, b); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\n// clientReader reads input from a WebSocket client and sends to PTY\nfunc (s *PTYSession) clientReader(cl *wsClient) {\n\tconn := cl.conn\n\tconn.SetReadLimit(readLimit)\n\n\tfor {\n\t\t_, data, err := conn.ReadMessage()\n\t\tif err != nil {\n\t\t\tif !websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {\n\t\t\t\ts.logger.Debug(\"ws read error\", \"error\", err)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\t// Send all message data to PTY (text or binary)\n\t\tif err := s.sendToPTY(data); err != nil {\n\t\t\t// Send error to client and close connection\n\t\t\t_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(\n\t\t\t\twebsocket.CloseInternalServerErr, \"PTY session unavailable\",\n\t\t\t))\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// broadcast sends data to all connected WebSocket clients\nfunc (s *PTYSession) broadcast(b []byte) {\n\t// send to each client; drop slow clients to avoid stalling the PTY\n\ts.clientsMu.RLock()\n\tfor id, cl := range s.clients.Items() {\n\t\tselect {\n\t\tcase cl.send <- b:\n\t\tcase <-cl.done:\n\t\t\t// client is shutting down, skip\n\t\tdefault:\n\t\t\t// client's outbound queue is full -> drop the client\n\t\t\tgo func(id string, cl *wsClient) {\n\t\t\t\t_ = cl.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(\n\t\t\t\t\twebsocket.ClosePolicyViolation, \"slow consumer\",\n\t\t\t\t))\n\t\t\t\tcl.close()\n\t\t\t}(id, cl)\n\t\t}\n\t}\n\ts.clientsMu.RUnlock()\n}\n\n// closeClientsWithExitCode closes all WebSocket connections with structured exit data\nfunc (s *PTYSession) closeClientsWithExitCode(exitCode int, exitReason string) {\n\tvar wsCloseCode int\n\tvar exitReasonStr *string\n\n\t// Map PTY exit codes to WebSocket close codes\n\tif exitCode == 0 {\n\t\twsCloseCode = websocket.CloseNormalClosure\n\t\texitReasonStr = nil // undefined for clean exit\n\t} else {\n\t\twsCloseCode = websocket.CloseInternalServerErr\n\t\t// Set human-readable reason for non-zero exits\n\t\tswitch {\n\t\tcase exitCode == 130:\n\t\t\treason := \"Ctrl+C\"\n\t\t\texitReasonStr = &reason\n\t\tcase exitCode == 137:\n\t\t\treason := \"SIGKILL\"\n\t\t\texitReasonStr = &reason\n\t\tcase exitCode == 143:\n\t\t\treason := \"SIGTERM\"\n\t\t\texitReasonStr = &reason\n\t\tcase exitCode > 128:\n\t\t\tsigNum := exitCode - 128\n\t\t\treason := fmt.Sprintf(\"signal %d\", sigNum)\n\t\t\texitReasonStr = &reason\n\t\tdefault:\n\t\t\treason := \"non-zero exit\"\n\t\t\texitReasonStr = &reason\n\t\t}\n\t}\n\n\t// Create structured close data as JSON\n\ttype CloseData struct {\n\t\tExitCode   int     `json:\"exitCode\"`\n\t\tExitReason *string `json:\"exitReason,omitempty\"`\n\t}\n\n\tcloseData := CloseData{\n\t\tExitCode:   exitCode,\n\t\tExitReason: exitReasonStr,\n\t}\n\n\tcloseJSON, _ := json.Marshal(closeData)\n\n\ts.clientsMu.Lock()\n\tfor id, cl := range s.clients.Items() {\n\t\t_ = cl.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(\n\t\t\twsCloseCode, string(closeJSON),\n\t\t))\n\t\tcl.close()\n\t\ts.clients.Remove(id)\n\t}\n\ts.clientsMu.Unlock()\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/pty/ws_client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage pty\n\nfunc (cl *wsClient) close() {\n\tcl.closeOnce.Do(func() {\n\t\tclose(cl.done)\n\t\t_ = cl.conn.Close()\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/session/controller.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"log/slog\"\n\n\t\"github.com/daytonaio/daemon/pkg/session\"\n)\n\ntype SessionController struct {\n\tlogger         *slog.Logger\n\tconfigDir      string\n\tsessionService *session.SessionService\n}\n\nfunc NewSessionController(logger *slog.Logger, configDir string, sessionService *session.SessionService) *SessionController {\n\treturn &SessionController{\n\t\tlogger:         logger.With(slog.String(\"component\", \"session_controller\")),\n\t\tconfigDir:      configDir,\n\t\tsessionService: sessionService,\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/session/execute.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/daemon/internal/util\"\n\t\"github.com/daytonaio/daemon/pkg/session\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// SessionExecuteCommand godoc\n//\n//\t@Summary\t\tExecute command in session\n//\t@Description\tExecute a command within an existing shell session\n//\t@Tags\t\t\tprocess\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsessionId\tpath\t\tstring\t\t\t\t\ttrue\t\"Session ID\"\n//\t@Param\t\t\trequest\t\tbody\t\tSessionExecuteRequest\ttrue\t\"Command execution request\"\n//\t@Success\t\t200\t\t\t{object}\tSessionExecuteResponse\n//\t@Success\t\t202\t\t\t{object}\tSessionExecuteResponse\n//\t@Router\t\t\t/process/session/{sessionId}/exec [post]\n//\n//\t@id\t\t\t\tSessionExecuteCommand\nfunc (s *SessionController) SessionExecuteCommand(c *gin.Context) {\n\tsessionId := c.Param(\"sessionId\")\n\n\tif sessionId == util.EntrypointSessionID {\n\t\tc.Error(common_errors.NewBadRequestError(errors.New(\"can't execute command in entrypoint session\")))\n\t\treturn\n\t}\n\n\tvar request SessionExecuteRequest\n\tif err := c.ShouldBindJSON(&request); err != nil {\n\t\tc.AbortWithError(http.StatusBadRequest, fmt.Errorf(\"invalid request body: %w\", err))\n\t\treturn\n\t}\n\n\t// Validate command is not empty (if not already handled by binding)\n\tif strings.TrimSpace(request.Command) == \"\" {\n\t\tc.AbortWithError(http.StatusBadRequest, errors.New(\"command cannot be empty\"))\n\t\treturn\n\t}\n\n\t// Handle backward compatibility for \"async\" field\n\tif request.Async {\n\t\trequest.RunAsync = true\n\t}\n\n\tsdkVersion := util.ExtractSdkVersionFromHeader(c.Request.Header)\n\tversionComparison, err := util.CompareVersions(sdkVersion, \"0.27.0-0\")\n\tif err != nil {\n\t\ts.logger.ErrorContext(c.Request.Context(), \"failed to compare versions\", \"error\", err)\n\t\tversionComparison = util.Pointer(1)\n\t}\n\n\tisCombinedOutput := session.IsCombinedOutput(sdkVersion, versionComparison, c.Request.Header)\n\n\texecuteResult, err := s.sessionService.Execute(sessionId, util.EmptyCommandID, request.Command, request.RunAsync, isCombinedOutput, request.SuppressInputEcho)\n\tif err != nil {\n\t\tc.Error(fmt.Errorf(\"failed to execute command: %w\", err))\n\t\treturn\n\t}\n\n\tif request.RunAsync {\n\t\tc.JSON(http.StatusAccepted, &SessionExecuteResponse{\n\t\t\tCommandId: executeResult.CommandId,\n\t\t})\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, &SessionExecuteResponse{\n\t\tCommandId: executeResult.CommandId,\n\t\tOutput:    executeResult.Output,\n\t\tStdout:    executeResult.Stdout,\n\t\tStderr:    executeResult.Stderr,\n\t\tExitCode:  executeResult.ExitCode,\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/session/input.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/daemon/internal/util\"\n)\n\n// SendInput godoc\n//\n//\t@Summary\t\tSend input to command\n//\t@Description\tSend input data to a running command in a session for interactive execution\n//\t@Tags\t\t\tprocess\n//\t@Accept\t\t\tjson\n//\t@Param\t\t\tsessionId\tpath\tstring\t\t\t\t\ttrue\t\"Session ID\"\n//\t@Param\t\t\tcommandId\tpath\tstring\t\t\t\t\ttrue\t\"Command ID\"\n//\t@Param\t\t\trequest\t\tbody\tSessionSendInputRequest\ttrue\t\"Input send request\"\n//\t@Success\t\t204\n//\t@Router\t\t\t/process/session/{sessionId}/command/{commandId}/input [post]\n//\n//\t@id\t\t\t\tSendInput\nfunc (s *SessionController) SendInput(c *gin.Context) {\n\tsessionId := c.Param(\"sessionId\")\n\tcommandId := c.Param(\"commandId\")\n\n\tif sessionId == util.EntrypointSessionID {\n\t\tc.Error(common_errors.NewBadRequestError(errors.New(\"can't send input to entrypoint session\")))\n\t\treturn\n\t}\n\n\tvar request SessionSendInputRequest\n\tif err := c.ShouldBindJSON(&request); err != nil {\n\t\tc.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\terr := s.sessionService.SendInput(sessionId, commandId, request.Data)\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusNoContent)\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/session/log.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/daytonaio/daemon/internal/util\"\n\t\"github.com/daytonaio/daemon/pkg/session\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// GetSessionCommandLogs godoc\n//\n//\t@Summary\t\tGet session command logs\n//\t@Description\tGet logs for a specific command within a session. Supports both HTTP and WebSocket streaming.\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\ttext/plain\n//\t@Param\t\t\tsessionId\tpath\t\tstring\ttrue\t\"Session ID\"\n//\t@Param\t\t\tcommandId\tpath\t\tstring\ttrue\t\"Command ID\"\n//\t@Param\t\t\tfollow\t\tquery\t\tboolean\tfalse\t\"Follow logs in real-time (WebSocket only)\"\n//\t@Success\t\t200\t\t\t{string}\tstring\t\"Log content\"\n//\t@Router\t\t\t/process/session/{sessionId}/command/{commandId}/logs [get]\n//\n//\t@id\t\t\t\tGetSessionCommandLogs\nfunc (s *SessionController) GetSessionCommandLogs(c *gin.Context) {\n\tsessionId := c.Param(\"sessionId\")\n\tcmdId := c.Param(\"commandId\")\n\n\tsdkVersion := util.ExtractSdkVersionFromHeader(c.Request.Header)\n\tversionComparison, err := util.CompareVersions(sdkVersion, \"0.27.0-0\")\n\tif err != nil {\n\t\ts.logger.DebugContext(c.Request.Context(), \"failed to compare versions\", \"error\", err)\n\t\tversionComparison = util.Pointer(1)\n\t}\n\n\topts := session.FetchLogsOptions{\n\t\tIsCombinedOutput:   session.IsCombinedOutput(sdkVersion, versionComparison, c.Request.Header),\n\t\tIsWebsocketUpgrade: c.Request.Header.Get(\"Upgrade\") == \"websocket\",\n\t\tFollow:             c.Query(\"follow\") == \"true\",\n\t}\n\n\tlogBytes, err := s.sessionService.GetSessionCommandLogs(sessionId, cmdId, c.Request, c.Writer, opts)\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tif logBytes == nil {\n\t\treturn\n\t}\n\n\tc.String(http.StatusOK, string(logBytes))\n}\n\n// GetEntrypointLogs godoc\n//\n//\t@Summary\t\tGet entrypoint logs\n//\t@Description\tGet logs for a sandbox entrypoint session. Supports both HTTP and WebSocket streaming.\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\ttext/plain\n//\t@Param\t\t\tfollow\tquery\t\tboolean\tfalse\t\"Follow logs in real-time (WebSocket only)\"\n//\t@Success\t\t200\t\t{string}\tstring\t\"Entrypoint log content\"\n//\t@Router\t\t\t/process/session/entrypoint/logs [get]\n//\n//\t@id\t\t\t\tGetEntrypointLogs\nfunc (s *SessionController) GetEntrypointLogs(c *gin.Context) {\n\topts := session.FetchLogsOptions{\n\t\tIsCombinedOutput:   false,\n\t\tIsWebsocketUpgrade: c.Request.Header.Get(\"Upgrade\") == \"websocket\",\n\t\tFollow:             c.Query(\"follow\") == \"true\",\n\t}\n\n\tlogBytes, err := s.sessionService.GetSessionCommandLogs(util.EntrypointSessionID, util.EntrypointCommandID, c.Request, c.Writer, opts)\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tif logBytes == nil {\n\t\treturn\n\t}\n\n\tc.String(http.StatusOK, string(logBytes))\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/session/session.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/daemon/internal/util\"\n)\n\n// CreateSession godoc\n//\n//\t@Summary\t\tCreate a new session\n//\t@Description\tCreate a new shell session for command execution\n//\t@Tags\t\t\tprocess\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\tCreateSessionRequest\ttrue\t\"Session creation request\"\n//\t@Success\t\t201\n//\t@Router\t\t\t/process/session [post]\n//\n//\t@id\t\t\t\tCreateSession\nfunc (s *SessionController) CreateSession(c *gin.Context) {\n\tvar request CreateSessionRequest\n\tif err := c.ShouldBindJSON(&request); err != nil {\n\t\tc.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\tif request.SessionId == util.EntrypointSessionID {\n\t\tc.Error(common_errors.NewBadRequestError(errors.New(\"provided session ID is reserved and cannot be created/overridden\")))\n\t\treturn\n\t}\n\n\t// for backward compatibility (only sdk clients before 0.103.X), we use the home directory as the default directory\n\tsdkVersion := util.ExtractSdkVersionFromHeader(c.Request.Header)\n\tversionComparison, err := util.CompareVersions(sdkVersion, \"0.103.0-0\")\n\tif err != nil {\n\t\ts.logger.ErrorContext(c.Request.Context(), \"failed to compare versions\", \"error\", err)\n\t\tversionComparison = util.Pointer(1)\n\t}\n\n\tisLegacy := versionComparison != nil && *versionComparison < 0 && sdkVersion != \"0.0.0-dev\"\n\n\terr = s.sessionService.Create(request.SessionId, isLegacy)\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusCreated)\n}\n\n// DeleteSession godoc\n//\n//\t@Summary\t\tDelete a session\n//\t@Description\tDelete an existing shell session\n//\t@Tags\t\t\tprocess\n//\t@Param\t\t\tsessionId\tpath\tstring\ttrue\t\"Session ID\"\n//\t@Success\t\t204\n//\t@Router\t\t\t/process/session/{sessionId} [delete]\n//\n//\t@id\t\t\t\tDeleteSession\nfunc (s *SessionController) DeleteSession(c *gin.Context) {\n\tsessionId := c.Param(\"sessionId\")\n\n\tif sessionId == util.EntrypointSessionID {\n\t\tc.Error(common_errors.NewBadRequestError(errors.New(\"can't delete entrypoint session\")))\n\t\treturn\n\t}\n\n\terr := s.sessionService.Delete(c.Request.Context(), sessionId)\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tc.Status(http.StatusNoContent)\n}\n\n// ListSessions godoc\n//\n//\t@Summary\t\tList all sessions\n//\t@Description\tGet a list of all active shell sessions\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{array}\tSessionDTO\n//\t@Router\t\t\t/process/session [get]\n//\n//\t@id\t\t\t\tListSessions\nfunc (s *SessionController) ListSessions(c *gin.Context) {\n\tsessions, err := s.sessionService.List()\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tsessionDTOs := make([]SessionDTO, 0, len(sessions))\n\tfor _, session := range sessions {\n\t\tsessionDTOs = append(sessionDTOs, *SessionToDTO(&session))\n\t}\n\n\tc.JSON(http.StatusOK, sessionDTOs)\n}\n\n// GetSession godoc\n//\n//\t@Summary\t\tGet session details\n//\t@Description\tGet details of a specific session including its commands\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsessionId\tpath\t\tstring\ttrue\t\"Session ID\"\n//\t@Success\t\t200\t\t\t{object}\tSessionDTO\n//\t@Router\t\t\t/process/session/{sessionId} [get]\n//\n//\t@id\t\t\t\tGetSession\nfunc (s *SessionController) GetSession(c *gin.Context) {\n\tsessionId := c.Param(\"sessionId\")\n\n\tsession, err := s.sessionService.Get(sessionId)\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, SessionToDTO(session))\n}\n\n// GetSessionCommand godoc\n//\n//\t@Summary\t\tGet session command details\n//\t@Description\tGet details of a specific command within a session\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsessionId\tpath\t\tstring\ttrue\t\"Session ID\"\n//\t@Param\t\t\tcommandId\tpath\t\tstring\ttrue\t\"Command ID\"\n//\t@Success\t\t200\t\t\t{object}\tCommandDTO\n//\t@Router\t\t\t/process/session/{sessionId}/command/{commandId} [get]\n//\n//\t@id\t\t\t\tGetSessionCommand\nfunc (s *SessionController) GetSessionCommand(c *gin.Context) {\n\tsessionId := c.Param(\"sessionId\")\n\tcmdId := c.Param(\"commandId\")\n\n\tcommand, err := s.sessionService.GetSessionCommand(sessionId, cmdId)\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, CommandToDTO(command))\n}\n\n// GetEntrypointSession godoc\n//\n//\t@Summary\t\tGet entrypoint session details\n//\t@Description\tGet details of an entrypoint session including its commands\n//\t@Tags\t\t\tprocess\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tSessionDTO\n//\t@Router\t\t\t/process/session/entrypoint [get]\n//\n//\t@id\t\t\t\tGetEntrypointSession\nfunc (s *SessionController) GetEntrypointSession(c *gin.Context) {\n\tsession, err := s.sessionService.Get(util.EntrypointSessionID)\n\tif err != nil {\n\t\tc.Error(err)\n\t\treturn\n\t}\n\n\tc.JSON(http.StatusOK, SessionToDTO(session))\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/session/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage session\n\nimport \"github.com/daytonaio/daemon/pkg/session\"\n\ntype CreateSessionRequest struct {\n\tSessionId string `json:\"sessionId\" validate:\"required\"`\n} // @name CreateSessionRequest\n\ntype SessionExecuteRequest struct {\n\tCommand           string `json:\"command\" validate:\"required\"`\n\tRunAsync          bool   `json:\"runAsync\" validate:\"optional\"`\n\tAsync             bool   `json:\"async\" validate:\"optional\"`\n\tSuppressInputEcho bool   `json:\"suppressInputEcho\" validate:\"optional\"`\n} // @name SessionExecuteRequest\n\ntype SessionSendInputRequest struct {\n\tData string `json:\"data\" validate:\"required\"`\n} // @name SessionSendInputRequest\n\ntype SessionExecuteResponse struct {\n\tCommandId string  `json:\"cmdId\" validate:\"required\"`\n\tOutput    *string `json:\"output\" validate:\"optional\"`\n\tStdout    *string `json:\"stdout\" validate:\"optional\"`\n\tStderr    *string `json:\"stderr\" validate:\"optional\"`\n\tExitCode  *int    `json:\"exitCode\" validate:\"optional\"`\n} // @name SessionExecuteResponse\n\ntype SessionCommandLogsResponse struct {\n\tStdout string `json:\"stdout\" validate:\"required\"`\n\tStderr string `json:\"stderr\" validate:\"required\"`\n} // @name SessionCommandLogsResponse\n\ntype CommandDTO struct {\n\tId       string `json:\"id\" validate:\"required\"`\n\tCommand  string `json:\"command\" validate:\"required\"`\n\tExitCode *int   `json:\"exitCode,omitempty\" validate:\"optional\"`\n} // @name Command\n\ntype SessionDTO struct {\n\tSessionId string        `json:\"sessionId\" validate:\"required\"`\n\tCommands  []*CommandDTO `json:\"commands\" validate:\"required\"`\n} // @name Session\n\nfunc CommandToDTO(c *session.Command) *CommandDTO {\n\treturn &CommandDTO{\n\t\tId:       c.Id,\n\t\tCommand:  c.Command,\n\t\tExitCode: c.ExitCode,\n\t}\n}\n\nfunc SessionToDTO(s *session.Session) *SessionDTO {\n\tcommands := make([]*CommandDTO, 0, len(s.Commands))\n\tfor _, cmd := range s.Commands {\n\t\tcommands = append(commands, CommandToDTO(cmd))\n\t}\n\n\treturn &SessionDTO{\n\t\tSessionId: s.SessionId,\n\t\tCommands:  commands,\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/process/types.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage process\n\ntype ExecuteRequest struct {\n\tCommand string `json:\"command\" validate:\"required\"`\n\t// Timeout in seconds, defaults to 10 seconds\n\tTimeout *uint32 `json:\"timeout,omitempty\" validate:\"optional\"`\n\t// Current working directory\n\tCwd *string `json:\"cwd,omitempty\" validate:\"optional\"`\n} // @name ExecuteRequest\n\n// TODO: Set ExitCode as required once all sandboxes migrated to the new daemon\ntype ExecuteResponse struct {\n\tExitCode int    `json:\"exitCode\"`\n\tResult   string `json:\"result\" validate:\"required\"`\n} // @name ExecuteResponse\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/proxy/proxy.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"strings\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc GetProxyTarget(ctx *gin.Context) (*url.URL, map[string]string, error) {\n\ttargetPort := ctx.Param(\"port\")\n\tif targetPort == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"target port is required\")))\n\t\treturn nil, nil, errors.New(\"target port is required\")\n\t}\n\n\t// Build the target URL\n\ttargetURL := fmt.Sprintf(\"http://localhost:%s\", targetPort)\n\n\t// Get the wildcard path and normalize it\n\tpath := ctx.Param(\"path\")\n\n\t// Ensure path always has a leading slash but not duplicate slashes\n\tif path == \"\" {\n\t\tpath = \"/\"\n\t} else if !strings.HasPrefix(path, \"/\") {\n\t\tpath = \"/\" + path\n\t}\n\n\t// Create the complete target URL with path\n\ttarget, err := url.Parse(fmt.Sprintf(\"%s%s\", targetURL, path))\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to parse target URL: %w\", err)))\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse target URL: %w\", err)\n\t}\n\n\treturn target, nil, nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/server.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\n//\t@title\t\t\tDaytona Toolbox API\n//\t@version\t\tv0.0.0-dev\n//\t@description\tDaytona Toolbox API\n\npackage toolbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"path\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\tcommon_proxy \"github.com/daytonaio/common-go/pkg/proxy\"\n\t\"github.com/daytonaio/common-go/pkg/telemetry\"\n\t\"github.com/daytonaio/daemon/internal\"\n\t\"github.com/daytonaio/daemon/pkg/recording\"\n\tsession_svc \"github.com/daytonaio/daemon/pkg/session\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/computeruse\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/computeruse/manager\"\n\trecordingcontroller \"github.com/daytonaio/daemon/pkg/toolbox/computeruse/recording\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/config\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/fs\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/git\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/lsp\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/port\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/process\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/process/interpreter\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/process/pty\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/process/session\"\n\t\"github.com/daytonaio/daemon/pkg/toolbox/proxy\"\n\tsloggin \"github.com/samber/slog-gin\"\n\t\"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin\"\n\totellog \"go.opentelemetry.io/otel/sdk/log\"\n\t\"go.opentelemetry.io/otel/sdk/metric\"\n\tsdktrace \"go.opentelemetry.io/otel/sdk/trace\"\n\n\t\"github.com/daytonaio/daemon/pkg/toolbox/docs\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/gin-gonic/gin/binding\"\n\tswaggerfiles \"github.com/swaggo/files\"\n\tginSwagger \"github.com/swaggo/gin-swagger\"\n)\n\ntype ServerConfig struct {\n\tLogger                *slog.Logger\n\tWorkDir               string\n\tConfigDir             string\n\tComputerUse           computeruse.IComputerUse\n\tSandboxId             string\n\tOtelEndpoint          *string\n\tSessionService        *session_svc.SessionService\n\tRecordingService      *recording.RecordingService\n\tOrganizationId        *string\n\tRegionId              *string\n\tEntrypointLogFilePath string\n}\n\nfunc NewServer(config ServerConfig) *server {\n\treturn &server{\n\t\tlogger:                config.Logger.With(slog.String(\"component\", \"toolbox_server\")),\n\t\tWorkDir:               config.WorkDir,\n\t\tSandboxId:             config.SandboxId,\n\t\totelEndpoint:          config.OtelEndpoint,\n\t\ttelemetry:             Telemetry{},\n\t\tsessionService:        config.SessionService,\n\t\tconfigDir:             config.ConfigDir,\n\t\trecordingService:      config.RecordingService,\n\t\torganizationId:        config.OrganizationId,\n\t\tregionId:              config.RegionId,\n\t\tentrypointLogFilePath: config.EntrypointLogFilePath,\n\t}\n}\n\ntype server struct {\n\tWorkDir               string\n\tComputerUse           computeruse.IComputerUse\n\tSandboxId             string\n\tlogger                *slog.Logger\n\totelEndpoint          *string\n\tauthToken             string\n\ttelemetry             Telemetry\n\tsessionService        *session_svc.SessionService\n\tconfigDir             string\n\trecordingService      *recording.RecordingService\n\tentrypointLogFilePath string\n\tentrypointLogCancel   context.CancelFunc\n\thttpServer            *http.Server\n\torganizationId        *string\n\tregionId              *string\n\tctx                   context.Context\n\tcancel                context.CancelFunc\n}\n\ntype Telemetry struct {\n\tTracerProvider *sdktrace.TracerProvider\n\tMeterProvider  *metric.MeterProvider\n\tLoggerProvider *otellog.LoggerProvider\n}\n\nfunc (s *server) Start() error {\n\ts.ctx, s.cancel = context.WithCancel(context.Background())\n\tdefer s.cancel()\n\n\tdocs.SwaggerInfo.Description = \"Daytona Toolbox API\"\n\tdocs.SwaggerInfo.Title = \"Daytona Toolbox API\"\n\tdocs.SwaggerInfo.BasePath = \"/\"\n\tdocs.SwaggerInfo.Version = internal.Version\n\n\t// Set Gin to release mode in production\n\tif os.Getenv(\"ENVIRONMENT\") == \"production\" {\n\t\tgin.SetMode(gin.ReleaseMode)\n\t}\n\n\totelServiceName := fmt.Sprintf(\"sandbox-%s\", s.SandboxId)\n\n\tr := gin.New()\n\tr.Use(common_errors.Recovery())\n\tnoTelemetryRouter := r.Group(\"/\")\n\tr.Use(func(ctx *gin.Context) {\n\t\tif s.telemetry.TracerProvider == nil {\n\t\t\tctx.Next()\n\t\t\treturn\n\t\t}\n\n\t\totelgin.Middleware(otelServiceName, otelgin.WithTracerProvider(s.telemetry.TracerProvider))(ctx)\n\t\tctx.Next()\n\t})\n\tr.Use(sloggin.New(s.logger))\n\terrMiddleware := common_errors.NewErrorMiddleware(func(ctx *gin.Context, err error) common_errors.ErrorResponse {\n\t\treturn common_errors.ErrorResponse{\n\t\t\tStatusCode: http.StatusInternalServerError,\n\t\t\tMessage:    err.Error(),\n\t\t}\n\t})\n\n\tnoTelemetryRouter.Use(sloggin.New(s.logger))\n\tr.Use(errMiddleware)\n\tnoTelemetryRouter.Use(errMiddleware)\n\tbinding.Validator = new(DefaultValidator)\n\n\t// Add swagger UI in development mode\n\tif os.Getenv(\"ENVIRONMENT\") != \"production\" {\n\t\tr.GET(\"/swagger/*any\", ginSwagger.WrapHandler(swaggerfiles.Handler))\n\t}\n\n\tr.POST(\"/init\", s.Initialize(otelServiceName, s.entrypointLogFilePath, s.organizationId, s.regionId))\n\n\tr.GET(\"/version\", s.GetVersion)\n\n\t// keep /project-dir old behavior for backward compatibility\n\tr.GET(\"/project-dir\", s.GetUserHomeDir)\n\tr.GET(\"/user-home-dir\", s.GetUserHomeDir)\n\tr.GET(\"/work-dir\", s.GetWorkDir)\n\n\tfsController := r.Group(\"/files\")\n\t{\n\t\t// read operations\n\t\tfsController.GET(\"/\", fs.ListFiles)\n\t\tfsController.GET(\"/download\", fs.DownloadFile)\n\t\tfsController.POST(\"/bulk-download\", fs.DownloadFiles)\n\t\tfsController.GET(\"/find\", fs.FindInFiles)\n\t\tfsController.GET(\"/info\", fs.GetFileInfo)\n\t\tfsController.GET(\"/search\", fs.SearchFiles)\n\n\t\t// create/modify operations\n\t\tfsController.POST(\"/folder\", fs.CreateFolder)\n\t\tfsController.POST(\"/move\", fs.MoveFile)\n\t\tfsController.POST(\"/permissions\", fs.SetFilePermissions)\n\t\tfsController.POST(\"/replace\", fs.ReplaceInFiles)\n\t\tfsController.POST(\"/upload\", fs.UploadFile)\n\t\tfsController.POST(\"/bulk-upload\", fs.UploadFiles)\n\n\t\t// delete operations\n\t\tfsController.DELETE(\"/\", fs.DeleteFile)\n\t}\n\n\tprocessLogger := s.logger.With(slog.String(\"component\", \"process_controller\"))\n\tprocessController := r.Group(\"/process\")\n\t{\n\t\tprocessController.POST(\"/execute\", process.ExecuteCommand(processLogger))\n\n\t\tsessionController := session.NewSessionController(s.logger, s.configDir, s.sessionService)\n\t\tsessionGroup := processController.Group(\"/session\")\n\t\t{\n\t\t\tsessionGroup.GET(\"\", sessionController.ListSessions)\n\t\t\tsessionGroup.POST(\"\", sessionController.CreateSession)\n\t\t\tsessionGroup.GET(\"/entrypoint\", sessionController.GetEntrypointSession)\n\t\t\tsessionGroup.GET(\"/entrypoint/logs\", sessionController.GetEntrypointLogs)\n\t\t\tsessionGroup.POST(\"/:sessionId/exec\", sessionController.SessionExecuteCommand)\n\t\t\tsessionGroup.GET(\"/:sessionId\", sessionController.GetSession)\n\t\t\tsessionGroup.DELETE(\"/:sessionId\", sessionController.DeleteSession)\n\t\t\tsessionGroup.GET(\"/:sessionId/command/:commandId\", sessionController.GetSessionCommand)\n\t\t\tsessionGroup.POST(\"/:sessionId/command/:commandId/input\", sessionController.SendInput)\n\t\t\tsessionGroup.GET(\"/:sessionId/command/:commandId/logs\", sessionController.GetSessionCommandLogs)\n\t\t}\n\n\t\t// PTY endpoints\n\t\tptyController := pty.NewPTYController(s.logger, s.WorkDir)\n\t\tptyGroup := processController.Group(\"/pty\")\n\t\t{\n\t\t\tptyGroup.GET(\"\", ptyController.ListPTYSessions)\n\t\t\tptyGroup.POST(\"\", ptyController.CreatePTYSession)\n\t\t\tptyGroup.GET(\"/:sessionId\", ptyController.GetPTYSession)\n\t\t\tptyGroup.DELETE(\"/:sessionId\", ptyController.DeletePTYSession)\n\t\t\tptyGroup.GET(\"/:sessionId/connect\", ptyController.ConnectPTYSession)\n\t\t\tptyGroup.POST(\"/:sessionId/resize\", ptyController.ResizePTYSession)\n\t\t}\n\n\t\t// Interpreter endpoints\n\t\tinterpreterController := interpreter.NewInterpreterController(s.logger, s.WorkDir)\n\t\tinterpreterGroup := processController.Group(\"/interpreter\")\n\t\t{\n\t\t\tinterpreterGroup.POST(\"/context\", interpreterController.CreateContext)\n\t\t\tinterpreterGroup.GET(\"/context\", interpreterController.ListContexts)\n\t\t\tinterpreterGroup.DELETE(\"/context/:id\", interpreterController.DeleteContext)\n\t\t\tinterpreterGroup.GET(\"/execute\", interpreterController.Execute)\n\t\t}\n\t}\n\n\tgitController := r.Group(\"/git\")\n\t{\n\t\tgitController.GET(\"/branches\", git.ListBranches)\n\t\tgitController.GET(\"/history\", git.GetCommitHistory)\n\t\tgitController.GET(\"/status\", git.GetStatus)\n\n\t\tgitController.POST(\"/add\", git.AddFiles)\n\t\tgitController.POST(\"/branches\", git.CreateBranch)\n\t\tgitController.POST(\"/checkout\", git.CheckoutBranch)\n\t\tgitController.DELETE(\"/branches\", git.DeleteBranch)\n\t\tgitController.POST(\"/clone\", git.CloneRepository)\n\t\tgitController.POST(\"/commit\", git.CommitChanges)\n\t\tgitController.POST(\"/pull\", git.PullChanges)\n\t\tgitController.POST(\"/push\", git.PushChanges)\n\t}\n\n\tlspLogger := s.logger.With(slog.String(\"component\", \"lsp_service\"))\n\tlspController := r.Group(\"/lsp\")\n\t{\n\t\t//\tserver process\n\t\tlspController.POST(\"/start\", lsp.Start(lspLogger))\n\t\tlspController.POST(\"/stop\", lsp.Stop(lspLogger))\n\n\t\t//\tlsp operations\n\t\tlspController.POST(\"/completions\", lsp.Completions(lspLogger))\n\t\tlspController.POST(\"/did-open\", lsp.DidOpen(lspLogger))\n\t\tlspController.POST(\"/did-close\", lsp.DidClose(lspLogger))\n\n\t\tlspController.GET(\"/document-symbols\", lsp.DocumentSymbols(lspLogger))\n\t\tlspController.GET(\"/workspacesymbols\", lsp.WorkspaceSymbols(lspLogger))\n\t}\n\n\tlazyCU := computeruse.NewLazyComputerUse()\n\ts.ComputerUse = lazyCU\n\n\tgo func() {\n\t\t// Initialize plugin-based computer use lazily in a background goroutine\n\t\tpluginPath := \"/usr/local/lib/daytona-computer-use\"\n\t\t// Fallback to local config directory for development\n\t\tif _, err := os.Stat(pluginPath); os.IsNotExist(err) {\n\t\t\tpluginPath = path.Join(s.configDir, \"daytona-computer-use\")\n\t\t}\n\n\t\timpl, err := manager.GetComputerUse(s.logger, pluginPath)\n\t\tif err != nil {\n\t\t\ts.logger.Error(\"Computer-Use error\", \"error\", err)\n\t\t\ts.logger.Info(\"Continuing without computer-use functionality...\")\n\t\t\treturn\n\t\t}\n\t\tlazyCU.Set(impl)\n\t\ts.logger.Info(\"Computer-use plugin loaded successfully\")\n\t}()\n\n\t// Register computer-use endpoints with lazy check middleware\n\tcomputerUseController := r.Group(\"/computeruse\")\n\t{\n\t\tcomputerUseHandler := computeruse.Handler{\n\t\t\tComputerUse: lazyCU,\n\t\t}\n\n\t\tcuRoutes := computerUseController.Group(\"/\", computeruse.LazyCheckMiddleware(lazyCU))\n\n\t\t// Computer use status endpoint\n\t\tcuRoutes.GET(\"/status\", computeruse.WrapStatusHandler(lazyCU.GetStatus))\n\n\t\t// Computer use management endpoints\n\t\tcuRoutes.POST(\"/start\", computerUseHandler.StartComputerUse)\n\t\tcuRoutes.POST(\"/stop\", computerUseHandler.StopComputerUse)\n\t\tcuRoutes.GET(\"/process-status\", computerUseHandler.GetComputerUseStatus)\n\t\tcuRoutes.GET(\"/process/:processName/status\", computerUseHandler.GetProcessStatus)\n\t\tcuRoutes.POST(\"/process/:processName/restart\", computerUseHandler.RestartProcess)\n\t\tcuRoutes.GET(\"/process/:processName/logs\", computerUseHandler.GetProcessLogs)\n\t\tcuRoutes.GET(\"/process/:processName/errors\", computerUseHandler.GetProcessErrors)\n\n\t\t// Screenshot endpoints\n\t\tcuRoutes.GET(\"/screenshot\", computeruse.WrapScreenshotHandler(lazyCU.TakeScreenshot))\n\t\tcuRoutes.GET(\"/screenshot/region\", computeruse.WrapRegionScreenshotHandler(lazyCU.TakeRegionScreenshot))\n\t\tcuRoutes.GET(\"/screenshot/compressed\", computeruse.WrapCompressedScreenshotHandler(lazyCU.TakeCompressedScreenshot))\n\t\tcuRoutes.GET(\"/screenshot/region/compressed\", computeruse.WrapCompressedRegionScreenshotHandler(lazyCU.TakeCompressedRegionScreenshot))\n\n\t\t// Mouse control endpoints\n\t\tcuRoutes.GET(\"/mouse/position\", computeruse.WrapMousePositionHandler(lazyCU.GetMousePosition))\n\t\tcuRoutes.POST(\"/mouse/move\", computeruse.WrapMoveMouseHandler(lazyCU.MoveMouse))\n\t\tcuRoutes.POST(\"/mouse/click\", computeruse.WrapClickHandler(lazyCU.Click))\n\t\tcuRoutes.POST(\"/mouse/drag\", computeruse.WrapDragHandler(lazyCU.Drag))\n\t\tcuRoutes.POST(\"/mouse/scroll\", computeruse.WrapScrollHandler(lazyCU.Scroll))\n\n\t\t// Keyboard control endpoints\n\t\tcuRoutes.POST(\"/keyboard/type\", computeruse.WrapTypeTextHandler(lazyCU.TypeText))\n\t\tcuRoutes.POST(\"/keyboard/key\", computeruse.WrapPressKeyHandler(lazyCU.PressKey))\n\t\tcuRoutes.POST(\"/keyboard/hotkey\", computeruse.WrapPressHotkeyHandler(lazyCU.PressHotkey))\n\n\t\t// Display info endpoints\n\t\tcuRoutes.GET(\"/display/info\", computeruse.WrapDisplayInfoHandler(lazyCU.GetDisplayInfo))\n\t\tcuRoutes.GET(\"/display/windows\", computeruse.WrapWindowsHandler(lazyCU.GetWindows))\n\t}\n\n\t// Recording endpoints - always registered, independent of computer-use plugin\n\trecordingController := recordingcontroller.NewRecordingController(s.recordingService)\n\trecordingsGroup := computerUseController.Group(\"/recordings\")\n\t{\n\t\trecordingsGroup.POST(\"/start\", recordingController.StartRecording)\n\t\trecordingsGroup.POST(\"/stop\", recordingController.StopRecording)\n\t\trecordingsGroup.GET(\"\", recordingController.ListRecordings)\n\t\trecordingsGroup.GET(\"/:id\", recordingController.GetRecording)\n\t\trecordingsGroup.GET(\"/:id/download\", recordingController.DownloadRecording)\n\t\trecordingsGroup.DELETE(\"/:id\", recordingController.DeleteRecording)\n\t}\n\n\tportDetector := port.NewPortsDetector()\n\n\tportController := r.Group(\"/port\")\n\t{\n\t\tportController.GET(\"\", portDetector.GetPorts)\n\t\tportController.GET(\"/:port/in-use\", portDetector.IsPortInUse)\n\t}\n\n\tproxyController := noTelemetryRouter.Group(\"/proxy\")\n\t{\n\t\tproxyController.Any(\"/:port/*path\", common_proxy.NewProxyRequestHandler(proxy.GetProxyTarget, nil))\n\t}\n\n\tgo portDetector.Start(context.Background())\n\n\ts.httpServer = &http.Server{\n\t\tAddr:    fmt.Sprintf(\":%d\", config.TOOLBOX_API_PORT),\n\t\tHandler: r,\n\t}\n\n\t// Print to stdout so the runner can know that the daemon is ready\n\tfmt.Println(\"Starting toolbox server on port\", config.TOOLBOX_API_PORT)\n\n\tlistener, err := net.Listen(\"tcp\", s.httpServer.Addr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn s.httpServer.Serve(listener)\n}\n\nfunc (s *server) Shutdown() {\n\ts.logger.Info(\"Shutting down toolbox server\")\n\n\t// Stop accepting new requests and drain in-flight ones\n\tif s.httpServer != nil {\n\t\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\t\tdefer cancel()\n\t\tif err := s.httpServer.Shutdown(ctx); err != nil {\n\t\t\ts.logger.Error(\"toolbox HTTP server shutdown error\", \"error\", err)\n\t\t}\n\t}\n\n\t// Stop computer use if running\n\tif s.ComputerUse != nil {\n\t\ts.logger.Info(\"Stopping computer use...\")\n\t\t_, err := s.ComputerUse.Stop()\n\t\tif err != nil {\n\t\t\ts.logger.Error(\"Failed to stop computer use\", \"error\", err)\n\t\t}\n\t}\n\n\t// Flush telemetry\n\tif s.telemetry.TracerProvider != nil {\n\t\ts.logger.Info(\"Shutting down tracer provider\")\n\t\ttelemetry.ShutdownTracer(s.logger, s.telemetry.TracerProvider)\n\t}\n\n\tif s.telemetry.MeterProvider != nil {\n\t\ts.logger.Info(\"Shutting down meter provider\")\n\t\ttelemetry.ShutdownMeter(s.logger, s.telemetry.MeterProvider)\n\t}\n\n\tif s.telemetry.LoggerProvider != nil {\n\t\ts.logger.Info(\"Shutting down logger provider\")\n\t\ttelemetry.ShutdownLogger(s.logger, s.telemetry.LoggerProvider)\n\t}\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/telemetry.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage toolbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\t\"github.com/daytonaio/common-go/pkg/telemetry\"\n\t\"github.com/daytonaio/daemon/internal\"\n)\n\nfunc (s *server) initTelemetry(ctx context.Context, serviceName, entrypointLogFilePath string, organizationId, regionId *string) error {\n\tif s.otelEndpoint == nil {\n\t\ts.logger.InfoContext(ctx, \"Otel endpoint not provided, skipping telemetry initialization\")\n\t\treturn nil\n\t}\n\n\tif s.telemetry.LoggerProvider != nil {\n\t\tif err := s.telemetry.LoggerProvider.Shutdown(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to shutdown existing telemetry logger: %w\", err)\n\t\t}\n\t}\n\n\tif s.telemetry.MeterProvider != nil {\n\t\tif err := s.telemetry.MeterProvider.Shutdown(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to shutdown existing telemetry meter provider: %w\", err)\n\t\t}\n\t}\n\n\tif s.telemetry.TracerProvider != nil {\n\t\tif err := s.telemetry.TracerProvider.Shutdown(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to shutdown existing telemetry tracer provider: %w\", err)\n\t\t}\n\t}\n\n\tconfig := telemetry.Config{\n\t\tServiceName:    serviceName,\n\t\tServiceVersion: internal.Version,\n\t\tEndpoint:       *s.otelEndpoint,\n\t\tHeaders: map[string]string{\n\t\t\t\"sandbox-auth-token\": s.authToken,\n\t\t},\n\t}\n\n\textraLabels := make(map[string]string)\n\tif organizationId != nil && *organizationId != \"\" {\n\t\textraLabels[\"daytona_organization_id\"] = *organizationId\n\t}\n\n\tif regionId != nil && *regionId != \"\" {\n\t\textraLabels[\"daytona_region_id\"] = *regionId\n\t}\n\n\tif len(extraLabels) > 0 {\n\t\tconfig.ExtraLabels = extraLabels\n\t}\n\n\t// Use a background context\n\ttelemetryContext := context.Background()\n\n\t// Initialize OpenTelemetry logging\n\tnewLogger, lp, err := telemetry.InitLogger(telemetryContext, s.logger, config)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to initialize logger: %w\", err)\n\t}\n\ts.logger = newLogger\n\n\tif s.entrypointLogCancel != nil {\n\t\ts.entrypointLogCancel()\n\t}\n\n\tentrypointCtx, entrypointCancel := context.WithCancel(s.ctx)\n\ts.entrypointLogCancel = entrypointCancel\n\n\tgo func() {\n\t\tif entrypointLogFilePath == \"\" {\n\t\t\treturn\n\t\t}\n\n\t\tentrypointLogFile, err := os.Open(entrypointLogFilePath)\n\t\tif err != nil {\n\t\t\ts.logger.ErrorContext(ctx, \"Failed to open entrypoint log file\", \"error\", err, \"daytona-entrypoint\", true)\n\t\t\treturn\n\t\t}\n\t\tdefer entrypointLogFile.Close()\n\n\t\terrChan := make(chan error, 1)\n\t\tstdoutChan := make(chan []byte)\n\t\tstderrChan := make(chan []byte)\n\t\tgo log.ReadMultiplexedLog(entrypointCtx, entrypointLogFile, true, stdoutChan, stderrChan, errChan)\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-entrypointCtx.Done():\n\t\t\t\treturn\n\t\t\tcase line := <-stdoutChan:\n\t\t\t\ts.logger.InfoContext(telemetryContext, string(line), \"daytona-entrypoint\", true)\n\t\t\tcase line := <-stderrChan:\n\t\t\t\ts.logger.ErrorContext(telemetryContext, string(line), \"daytona-entrypoint\", true)\n\t\t\tcase err := <-errChan:\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.logger.ErrorContext(telemetryContext, \"Error reading entrypoint log file\", \"error\", err, \"daytona-entrypoint\", true)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Initialize OpenTelemetry metrics\n\tmp, err := telemetry.InitMetrics(ctx, config, \"daytona.sandbox\")\n\tif err != nil {\n\t\tif shutDownErr := lp.Shutdown(telemetryContext); shutDownErr != nil {\n\t\t\ts.logger.ErrorContext(ctx, \"Failed to shutdown logger after metrics initialization failure\", \"shutdownErr\", shutDownErr)\n\t\t}\n\t\treturn fmt.Errorf(\"failed to initialize metrics: %w\", err)\n\t}\n\n\t// Initialize OpenTelemetry tracing\n\ttp, err := telemetry.InitTracer(ctx, config)\n\tif err != nil {\n\t\tif shutDownErr := lp.Shutdown(telemetryContext); shutDownErr != nil {\n\t\t\ts.logger.ErrorContext(ctx, \"Failed to shutdown logger after tracer initialization failure\", \"shutdownErr\", shutDownErr)\n\t\t}\n\t\tif shutDownErr := mp.Shutdown(telemetryContext); shutDownErr != nil {\n\t\t\ts.logger.ErrorContext(ctx, \"Failed to shutdown meter provider after tracer initialization failure\", \"shutdownErr\", shutDownErr)\n\t\t}\n\t\treturn fmt.Errorf(\"failed to initialize tracer: %w\", err)\n\t}\n\n\ts.telemetry.TracerProvider = tp\n\ts.telemetry.MeterProvider = mp\n\ts.telemetry.LoggerProvider = lp\n\n\ts.logger.InfoContext(ctx, \"Telemetry initialized successfully\")\n\treturn nil\n}\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/types.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage toolbox\n\ntype InitializeRequest struct {\n\tToken string `json:\"token\" binding:\"required\"`\n} // @name InitializeRequest\n\ntype WorkDirResponse struct {\n\tDir string `json:\"dir\" binding:\"required\"`\n} // @name WorkDirResponse\n\ntype UserHomeDirResponse struct {\n\tDir string `json:\"dir\" binding:\"required\"`\n} // @name UserHomeDirResponse\n"
  },
  {
    "path": "apps/daemon/pkg/toolbox/validator.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage toolbox\n\nimport (\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/gin-gonic/gin/binding\"\n\t\"github.com/go-playground/validator/v10\"\n)\n\ntype DefaultValidator struct {\n\tonce     sync.Once\n\tvalidate *validator.Validate\n}\n\nvar _ binding.StructValidator = &DefaultValidator{}\n\ntype SliceValidationError []error\n\nfunc (err SliceValidationError) Error() string {\n\tif len(err) == 0 {\n\t\treturn \"\"\n\t}\n\n\tvar b strings.Builder\n\tfor i := 0; i < len(err); i++ {\n\t\tif err[i] != nil {\n\t\t\tif b.Len() > 0 {\n\t\t\t\tb.WriteString(\"\\n\")\n\t\t\t}\n\t\t\tb.WriteString(\"[\" + strconv.Itoa(i) + \"]: \" + err[i].Error())\n\t\t}\n\t}\n\treturn b.String()\n}\n\nfunc (v *DefaultValidator) ValidateStruct(obj any) error {\n\tif obj == nil {\n\t\treturn nil\n\t}\n\n\tvalue := reflect.ValueOf(obj)\n\tswitch value.Kind() {\n\tcase reflect.Ptr:\n\t\tif value.Elem().Kind() != reflect.Struct {\n\t\t\treturn v.ValidateStruct(value.Elem().Interface())\n\t\t}\n\t\treturn v.validateStruct(obj)\n\tcase reflect.Struct:\n\t\treturn v.validateStruct(obj)\n\tcase reflect.Slice, reflect.Array:\n\t\tcount := value.Len()\n\t\tvalidateRet := make(SliceValidationError, 0)\n\t\tfor i := 0; i < count; i++ {\n\t\t\tif err := v.ValidateStruct(value.Index(i).Interface()); err != nil {\n\t\t\t\tvalidateRet = append(validateRet, err)\n\t\t\t}\n\t\t}\n\t\tif len(validateRet) == 0 {\n\t\t\treturn nil\n\t\t}\n\t\treturn validateRet\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc (v *DefaultValidator) Engine() interface{} {\n\tv.lazyinit()\n\treturn v.validate\n}\n\nfunc (v *DefaultValidator) validateStruct(obj any) error {\n\tv.lazyinit()\n\treturn v.validate.Struct(obj)\n}\n\nfunc (v *DefaultValidator) lazyinit() {\n\tv.once.Do(func() {\n\t\tv.validate = validator.New(validator.WithRequiredStructEnabled())\n\t\tv.validate.SetTagName(\"validate\")\n\t\t_ = v.validate.RegisterValidation(\"optional\", func(fl validator.FieldLevel) bool {\n\t\t\treturn true\n\t\t}, true)\n\t})\n}\n"
  },
  {
    "path": "apps/daemon/project.json",
    "content": "{\n  \"name\": \"daemon\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"application\",\n  \"sourceRoot\": \"apps/daemon\",\n  \"tags\": [],\n  \"targets\": {\n    \"prepare\": {\n      \"executor\": \"@nx-go/nx-go:serve\",\n      \"options\": {\n        \"cwd\": \".\",\n        \"main\": \"{projectRoot}/tools/xterm.go\"\n      },\n      \"cache\": true,\n      \"inputs\": [\"{projectRoot}/tools/xterm.go\"],\n      \"outputs\": [\"{projectRoot}/pkg/terminal/static/*\"],\n      \"configurations\": {\n        \"production\": {}\n      }\n    },\n    \"build\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"inputs\": [\n        \"goProduction\",\n        \"^goProduction\",\n        { \"env\": \"VERSION\" },\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ],\n      \"options\": {\n        \"main\": \"{projectRoot}/cmd/daemon/main.go\",\n        \"outputPath\": \"dist/apps/daemon\"\n      },\n      \"configurations\": {\n        \"production\": {\n          \"flags\": [\"-ldflags \\\"-X 'github.com/daytonaio/daemon/internal.Version=$VERSION'\\\"\"]\n        }\n      },\n      \"dependsOn\": [\"build-amd64\"]\n    },\n    \"build-amd64\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"options\": {\n        \"main\": \"{projectRoot}/cmd/daemon/main.go\",\n        \"outputPath\": \"dist/apps/daemon-amd64\",\n        \"env\": {\n          \"GOARCH\": \"amd64\",\n          \"GOOS\": \"linux\",\n          \"CGO_ENABLED\": \"0\"\n        },\n        \"flags\": [\"-ldflags \\\"-X 'github.com/daytonaio/daemon/internal.Version=$VERSION'\\\"\"]\n      },\n      \"dependsOn\": [\"prepare\"],\n      \"inputs\": [\n        \"goProduction\",\n        \"^goProduction\",\n        { \"env\": \"VERSION\" },\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ]\n    },\n    \"serve\": {\n      \"executor\": \"@nx-go/nx-go:serve\",\n      \"options\": {\n        \"cmd\": \"gow\",\n        \"cwd\": \".\",\n        \"main\": \"{projectRoot}/cmd/daemon/main.go\"\n      },\n      \"configurations\": {\n        \"production\": {}\n      }\n    },\n    \"format\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cd {projectRoot} && go fmt ./... && prettier --write \\\"**/*.{yaml,html,json}\\\"\"\n      }\n    },\n    \"test\": {\n      \"executor\": \"@nx-go/nx-go:test\"\n    },\n    \"lint\": {\n      \"executor\": \"@nx-go/nx-go:lint\"\n    },\n    \"openapi\": {\n      \"executor\": \"nx:run-commands\",\n      \"cache\": true,\n      \"inputs\": [\"{projectRoot}/pkg/toolbox/**/*.go\", \"!{projectRoot}/pkg/toolbox/**/*_test.go\"],\n      \"outputs\": [\n        \"{projectRoot}/pkg/toolbox/docs/swagger.json\",\n        \"{projectRoot}/pkg/toolbox/docs/swagger.yaml\",\n        \"{projectRoot}/pkg/toolbox/docs/docs.go\"\n      ],\n      \"options\": {\n        \"cwd\": \"{projectRoot}/pkg/toolbox\",\n        \"command\": \"swag fmt && swag init --parseDependency --parseInternal --parseDepth 1 -o docs -g server.go && prettier --write \\\"**/*.{yaml,html,json}\\\"\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/daemon/tools/xterm.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\n// download_xterm.go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n)\n\nconst (\n\tXTERM_VERSION     = \"5.3.0\"\n\tXTERM_FIT_VERSION = \"0.8.0\"\n)\n\nfunc main() {\n\t// Get project root path\n\t_, filename, _, _ := runtime.Caller(0)\n\tprojectRoot := filepath.Join(filepath.Dir(filename), \"..\")\n\t// Create static directory structure\n\tstaticDir := filepath.Join(projectRoot, \"pkg\", \"terminal\", \"static\")\n\terr := os.MkdirAll(staticDir, 0755)\n\tif err != nil {\n\t\tfmt.Printf(\"Error creating directory %s: %v\\n\", staticDir, err)\n\t\tos.Exit(1)\n\t}\n\n\t// Files to download from cdnjs\n\tfiles := map[string]string{\n\t\tfilepath.Join(staticDir, \"xterm.js\"):           fmt.Sprintf(\"https://cdn.jsdelivr.net/npm/xterm@%s/lib/xterm.js\", XTERM_VERSION),\n\t\tfilepath.Join(staticDir, \"xterm.css\"):          fmt.Sprintf(\"https://cdn.jsdelivr.net/npm/xterm@%s/css/xterm.css\", XTERM_VERSION),\n\t\tfilepath.Join(staticDir, \"xterm-addon-fit.js\"): fmt.Sprintf(\"https://cdn.jsdelivr.net/npm/xterm-addon-fit@%s/lib/xterm-addon-fit.js\", XTERM_FIT_VERSION),\n\t}\n\n\t// Download each file\n\tfor filePath, url := range files {\n\t\tfmt.Printf(\"Downloading %s...\\n\", filePath)\n\n\t\tresp, err := http.Get(url)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error downloading %s: %v\\n\", url, err)\n\t\t\tos.Exit(1)\n\t\t}\n\t\tdefer resp.Body.Close()\n\n\t\tfile, err := os.Create(filePath)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error creating file %s: %v\\n\", filePath, err)\n\t\t\tos.Exit(1)\n\t\t}\n\n\t\t_, err = io.Copy(file, resp.Body)\n\t\tfile.Close()\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error writing to file %s: %v\\n\", filePath, err)\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n\n\tfmt.Println(\"xterm.js files downloaded successfully\")\n}\n"
  },
  {
    "path": "apps/dashboard/.prettierignore",
    "content": "/public\n"
  },
  {
    "path": "apps/dashboard/.storybook/main.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { StorybookConfig } from '@storybook/react-vite'\nimport { mergeConfig } from 'vite'\nimport path from 'path'\n\nconst config: StorybookConfig = {\n  stories: ['../src/**/*.stories.@(ts|tsx)'],\n  addons: ['@storybook/addon-essentials'],\n  framework: {\n    name: '@storybook/react-vite',\n    options: {},\n  },\n  typescript: {\n    reactDocgen: false,\n  },\n  viteFinal: async (config) => {\n    return mergeConfig(config, {\n      resolve: {\n        alias: [\n          {\n            find: '@daytonaio/sdk',\n            replacement: path.resolve(__dirname, '../../../libs/sdk-typescript/src'),\n          },\n          {\n            find: '@',\n            replacement: path.resolve(__dirname, '../src'),\n          },\n        ],\n      },\n    })\n  },\n}\n\nexport default config\n"
  },
  {
    "path": "apps/dashboard/.storybook/preview.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Preview } from '@storybook/react'\nimport '../src/index.css'\n\nconst preview: Preview = {\n  globalTypes: {\n    theme: {\n      description: 'Toggle light/dark theme',\n      toolbar: {\n        title: 'Theme',\n        icon: 'sun',\n        items: [\n          { value: 'light', icon: 'sun', title: 'Light' },\n          { value: 'dark', icon: 'moon', title: 'Dark' },\n        ],\n        dynamicTitle: true,\n      },\n    },\n  },\n  initialGlobals: {\n    theme: 'light',\n  },\n  decorators: [\n    (Story, context) => {\n      const theme = context.globals.theme || 'light'\n      document.documentElement.classList.toggle('dark', theme === 'dark')\n      return <Story />\n    },\n  ],\n  parameters: {\n    controls: {\n      matchers: {\n        color: /(background|color)$/i,\n        date: /Date$/i,\n      },\n    },\n  },\n}\n\nexport default preview\n"
  },
  {
    "path": "apps/dashboard/.storybook/tsconfig.json",
    "content": "{\n  \"extends\": \"../tsconfig.app.json\",\n  \"compilerOptions\": {\n    \"composite\": false,\n    \"declaration\": false,\n    \"declarationMap\": false\n  },\n  \"include\": [\"../src/**/*.ts\", \"../src/**/*.tsx\", \"./**/*.ts\"],\n  \"exclude\": [\"../src/**/*.spec.ts\", \"../src/**/*.test.ts\"]\n}\n"
  },
  {
    "path": "apps/dashboard/eslint.config.mjs",
    "content": "import nx from '@nx/eslint-plugin'\nimport baseConfig from '../../eslint.config.mjs'\n\nexport default [\n  ...baseConfig,\n  ...nx.configs['flat/react'],\n  {\n    files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],\n    // Override or add rules here\n    rules: {},\n  },\n]\n"
  },
  {
    "path": "apps/dashboard/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <link rel=\"icon\" href=\"/favicon.ico\" />\n    <link rel=\"shortcut icon\" href=\"/favicon.ico\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Daytona</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script>\n      // Check for dark mode preference\n      if (\n        localStorage.theme === 'dark' ||\n        (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)\n      ) {\n        document.documentElement.classList.add('dark')\n      }\n    </script>\n    <script type=\"module\" src=\"/src/main.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "apps/dashboard/postcss.config.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nconst { join } = require('path')\n\n// Note: If you use library-specific PostCSS/Tailwind configuration then you should remove the `postcssConfig` build\n// option from your application's configuration (i.e. project.json).\n//\n// See: https://nx.dev/guides/using-tailwind-css-in-react#step-4:-applying-configuration-to-libraries\n\nmodule.exports = {\n  plugins: {\n    tailwindcss: {\n      config: join(__dirname, 'tailwind.config.js'),\n    },\n    autoprefixer: {},\n  },\n}\n"
  },
  {
    "path": "apps/dashboard/project.json",
    "content": "{\n  \"name\": \"dashboard\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"sourceRoot\": \"apps/dashboard/src\",\n  \"projectType\": \"application\",\n  \"tags\": [],\n  \"targets\": {\n    \"build\": {\n      \"configurations\": {\n        \"production\": {\n          \"mode\": \"production\"\n        }\n      },\n      \"dependsOn\": [\n        {\n          \"target\": \"build\",\n          \"projects\": \"sdk-typescript\"\n        }\n      ]\n    },\n    \"storybook\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"storybook dev -p 6006 -c .storybook\",\n        \"cwd\": \"apps/dashboard\"\n      }\n    },\n    \"build-storybook\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"storybook build -c .storybook -o ../../dist/storybook\",\n        \"cwd\": \"apps/dashboard\"\n      }\n    },\n    \"format\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cd {projectRoot} && prettier --write \\\"**/*.{ts,tsx,js,jsx,json,css,mjs,html}\\\" --config ../../.prettierrc\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/public/mockServiceWorker.js",
    "content": "/* eslint-disable */\n/* tslint:disable */\n\n/**\n * Mock Service Worker.\n * @see https://github.com/mswjs/msw\n * - Please do NOT modify this file.\n */\n\nconst PACKAGE_VERSION = '2.12.2'\nconst INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'\nconst IS_MOCKED_RESPONSE = Symbol('isMockedResponse')\nconst activeClientIds = new Set()\n\naddEventListener('install', function () {\n  self.skipWaiting()\n})\n\naddEventListener('activate', function (event) {\n  event.waitUntil(self.clients.claim())\n})\n\naddEventListener('message', async function (event) {\n  const clientId = Reflect.get(event.source || {}, 'id')\n\n  if (!clientId || !self.clients) {\n    return\n  }\n\n  const client = await self.clients.get(clientId)\n\n  if (!client) {\n    return\n  }\n\n  const allClients = await self.clients.matchAll({\n    type: 'window',\n  })\n\n  switch (event.data) {\n    case 'KEEPALIVE_REQUEST': {\n      sendToClient(client, {\n        type: 'KEEPALIVE_RESPONSE',\n      })\n      break\n    }\n\n    case 'INTEGRITY_CHECK_REQUEST': {\n      sendToClient(client, {\n        type: 'INTEGRITY_CHECK_RESPONSE',\n        payload: {\n          packageVersion: PACKAGE_VERSION,\n          checksum: INTEGRITY_CHECKSUM,\n        },\n      })\n      break\n    }\n\n    case 'MOCK_ACTIVATE': {\n      activeClientIds.add(clientId)\n\n      sendToClient(client, {\n        type: 'MOCKING_ENABLED',\n        payload: {\n          client: {\n            id: client.id,\n            frameType: client.frameType,\n          },\n        },\n      })\n      break\n    }\n\n    case 'CLIENT_CLOSED': {\n      activeClientIds.delete(clientId)\n\n      const remainingClients = allClients.filter((client) => {\n        return client.id !== clientId\n      })\n\n      // Unregister itself when there are no more clients\n      if (remainingClients.length === 0) {\n        self.registration.unregister()\n      }\n\n      break\n    }\n  }\n})\n\naddEventListener('fetch', function (event) {\n  const requestInterceptedAt = Date.now()\n\n  // Bypass navigation requests.\n  if (event.request.mode === 'navigate') {\n    return\n  }\n\n  // Opening the DevTools triggers the \"only-if-cached\" request\n  // that cannot be handled by the worker. Bypass such requests.\n  if (\n    event.request.cache === 'only-if-cached' &&\n    event.request.mode !== 'same-origin'\n  ) {\n    return\n  }\n\n  // Bypass all requests when there are no active clients.\n  // Prevents the self-unregistered worked from handling requests\n  // after it's been terminated (still remains active until the next reload).\n  if (activeClientIds.size === 0) {\n    return\n  }\n\n  const requestId = crypto.randomUUID()\n  event.respondWith(handleRequest(event, requestId, requestInterceptedAt))\n})\n\n/**\n * @param {FetchEvent} event\n * @param {string} requestId\n * @param {number} requestInterceptedAt\n */\nasync function handleRequest(event, requestId, requestInterceptedAt) {\n  const client = await resolveMainClient(event)\n  const requestCloneForEvents = event.request.clone()\n  const response = await getResponse(\n    event,\n    client,\n    requestId,\n    requestInterceptedAt,\n  )\n\n  // Send back the response clone for the \"response:*\" life-cycle events.\n  // Ensure MSW is active and ready to handle the message, otherwise\n  // this message will pend indefinitely.\n  if (client && activeClientIds.has(client.id)) {\n    const serializedRequest = await serializeRequest(requestCloneForEvents)\n\n    // Clone the response so both the client and the library could consume it.\n    const responseClone = response.clone()\n\n    sendToClient(\n      client,\n      {\n        type: 'RESPONSE',\n        payload: {\n          isMockedResponse: IS_MOCKED_RESPONSE in response,\n          request: {\n            id: requestId,\n            ...serializedRequest,\n          },\n          response: {\n            type: responseClone.type,\n            status: responseClone.status,\n            statusText: responseClone.statusText,\n            headers: Object.fromEntries(responseClone.headers.entries()),\n            body: responseClone.body,\n          },\n        },\n      },\n      responseClone.body ? [serializedRequest.body, responseClone.body] : [],\n    )\n  }\n\n  return response\n}\n\n/**\n * Resolve the main client for the given event.\n * Client that issues a request doesn't necessarily equal the client\n * that registered the worker. It's with the latter the worker should\n * communicate with during the response resolving phase.\n * @param {FetchEvent} event\n * @returns {Promise<Client | undefined>}\n */\nasync function resolveMainClient(event) {\n  const client = await self.clients.get(event.clientId)\n\n  if (activeClientIds.has(event.clientId)) {\n    return client\n  }\n\n  if (client?.frameType === 'top-level') {\n    return client\n  }\n\n  const allClients = await self.clients.matchAll({\n    type: 'window',\n  })\n\n  return allClients\n    .filter((client) => {\n      // Get only those clients that are currently visible.\n      return client.visibilityState === 'visible'\n    })\n    .find((client) => {\n      // Find the client ID that's recorded in the\n      // set of clients that have registered the worker.\n      return activeClientIds.has(client.id)\n    })\n}\n\n/**\n * @param {FetchEvent} event\n * @param {Client | undefined} client\n * @param {string} requestId\n * @param {number} requestInterceptedAt\n * @returns {Promise<Response>}\n */\nasync function getResponse(event, client, requestId, requestInterceptedAt) {\n  // Clone the request because it might've been already used\n  // (i.e. its body has been read and sent to the client).\n  const requestClone = event.request.clone()\n\n  function passthrough() {\n    // Cast the request headers to a new Headers instance\n    // so the headers can be manipulated with.\n    const headers = new Headers(requestClone.headers)\n\n    // Remove the \"accept\" header value that marked this request as passthrough.\n    // This prevents request alteration and also keeps it compliant with the\n    // user-defined CORS policies.\n    const acceptHeader = headers.get('accept')\n    if (acceptHeader) {\n      const values = acceptHeader.split(',').map((value) => value.trim())\n      const filteredValues = values.filter(\n        (value) => value !== 'msw/passthrough',\n      )\n\n      if (filteredValues.length > 0) {\n        headers.set('accept', filteredValues.join(', '))\n      } else {\n        headers.delete('accept')\n      }\n    }\n\n    return fetch(requestClone, { headers })\n  }\n\n  // Bypass mocking when the client is not active.\n  if (!client) {\n    return passthrough()\n  }\n\n  // Bypass initial page load requests (i.e. static assets).\n  // The absence of the immediate/parent client in the map of the active clients\n  // means that MSW hasn't dispatched the \"MOCK_ACTIVATE\" event yet\n  // and is not ready to handle requests.\n  if (!activeClientIds.has(client.id)) {\n    return passthrough()\n  }\n\n  // Notify the client that a request has been intercepted.\n  const serializedRequest = await serializeRequest(event.request)\n  const clientMessage = await sendToClient(\n    client,\n    {\n      type: 'REQUEST',\n      payload: {\n        id: requestId,\n        interceptedAt: requestInterceptedAt,\n        ...serializedRequest,\n      },\n    },\n    [serializedRequest.body],\n  )\n\n  switch (clientMessage.type) {\n    case 'MOCK_RESPONSE': {\n      return respondWithMock(clientMessage.data)\n    }\n\n    case 'PASSTHROUGH': {\n      return passthrough()\n    }\n  }\n\n  return passthrough()\n}\n\n/**\n * @param {Client} client\n * @param {any} message\n * @param {Array<Transferable>} transferrables\n * @returns {Promise<any>}\n */\nfunction sendToClient(client, message, transferrables = []) {\n  return new Promise((resolve, reject) => {\n    const channel = new MessageChannel()\n\n    channel.port1.onmessage = (event) => {\n      if (event.data && event.data.error) {\n        return reject(event.data.error)\n      }\n\n      resolve(event.data)\n    }\n\n    client.postMessage(message, [\n      channel.port2,\n      ...transferrables.filter(Boolean),\n    ])\n  })\n}\n\n/**\n * @param {Response} response\n * @returns {Response}\n */\nfunction respondWithMock(response) {\n  // Setting response status code to 0 is a no-op.\n  // However, when responding with a \"Response.error()\", the produced Response\n  // instance will have status code set to 0. Since it's not possible to create\n  // a Response instance with status code 0, handle that use-case separately.\n  if (response.status === 0) {\n    return Response.error()\n  }\n\n  const mockedResponse = new Response(response.body, response)\n\n  Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {\n    value: true,\n    enumerable: true,\n  })\n\n  return mockedResponse\n}\n\n/**\n * @param {Request} request\n */\nasync function serializeRequest(request) {\n  return {\n    url: request.url,\n    mode: request.mode,\n    method: request.method,\n    headers: Object.fromEntries(request.headers.entries()),\n    cache: request.cache,\n    credentials: request.credentials,\n    destination: request.destination,\n    integrity: request.integrity,\n    redirect: request.redirect,\n    referrer: request.referrer,\n    referrerPolicy: request.referrerPolicy,\n    body: await request.arrayBuffer(),\n    keepalive: request.keepalive,\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/App.css",
    "content": "#root {\n  max-width: 1280px;\n  margin: 0 auto;\n  padding: 2rem;\n  text-align: center;\n}\n\n.logo {\n  height: 6em;\n  padding: 1.5em;\n  will-change: filter;\n  transition: filter 300ms;\n}\n.logo:hover {\n  filter: drop-shadow(0 0 2em #646cffaa);\n}\n.logo.react:hover {\n  filter: drop-shadow(0 0 2em #61dafbaa);\n}\n\n@keyframes logo-spin {\n  from {\n    transform: rotate(0deg);\n  }\n  to {\n    transform: rotate(360deg);\n  }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n  a:nth-of-type(2) .logo {\n    animation: logo-spin infinite 20s linear;\n  }\n}\n\n.card {\n  padding: 2em;\n}\n\n.read-the-docs {\n  color: #888;\n}\n"
  },
  {
    "path": "apps/dashboard/src/App.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport Onboarding from '@/pages/Onboarding'\nimport OrganizationMembers from '@/pages/OrganizationMembers'\nimport OrganizationSettings from '@/pages/OrganizationSettings'\nimport UserOrganizationInvitations from '@/pages/UserOrganizationInvitations'\nimport { NotificationSocketProvider } from '@/providers/NotificationSocketProvider'\nimport { OrganizationsProvider } from '@/providers/OrganizationsProvider'\nimport { SelectedOrganizationProvider } from '@/providers/SelectedOrganizationProvider'\nimport { UserOrganizationInvitationsProvider } from '@/providers/UserOrganizationInvitationsProvider'\nimport { initPylon } from '@/vendor/pylon'\nimport { OrganizationRolePermissionsEnum, OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport { useFeatureFlagEnabled, usePostHog } from 'posthog-js/react'\nimport React, { Suspense, useEffect } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { Navigate, Route, Routes, useLocation } from 'react-router-dom'\nimport { BannerProvider } from './components/Banner'\nimport { CommandPaletteProvider } from './components/CommandPalette'\nimport LoadingFallback from './components/LoadingFallback'\nimport { Button } from './components/ui/button'\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from './components/ui/dialog'\nimport { DAYTONA_DOCS_URL, DAYTONA_SLACK_URL } from './constants/ExternalLinks'\nimport { FeatureFlags } from './enums/FeatureFlags'\nimport { RoutePath, getRouteSubPath } from './enums/RoutePath'\nimport { useConfig } from './hooks/useConfig'\nimport AccountSettings from './pages/AccountSettings'\nimport AuditLogs from './pages/AuditLogs'\nimport Dashboard from './pages/Dashboard'\nimport EmailVerify from './pages/EmailVerify'\nimport Experimental from './pages/Experimental'\nimport Keys from './pages/Keys'\nimport LandingPage from './pages/LandingPage'\nimport Limits from './pages/Limits'\nimport Logout from './pages/Logout'\nimport NotFound from './pages/NotFound'\nimport Playground from './pages/Playground'\nimport Regions from './pages/Regions'\nimport Registries from './pages/Registries'\nimport Runners from './pages/Runners'\nimport Sandboxes from './pages/Sandboxes'\nimport Snapshots from './pages/Snapshots'\nimport Spending from './pages/Spending'\nimport Volumes from './pages/Volumes'\nimport Wallet from './pages/Wallet'\nimport WebhookEndpointDetails from './pages/WebhookEndpointDetails'\nimport Webhooks from './pages/Webhooks'\nimport { SandboxDetails } from './components/sandboxes'\nimport { ApiProvider } from './providers/ApiProvider'\nimport { RegionsProvider } from './providers/RegionsProvider'\nimport { SvixProvider } from './providers/SvixProvider'\n\n// Simple redirection components for external URLs\nconst DocsRedirect = () => {\n  React.useEffect(() => {\n    window.open(DAYTONA_DOCS_URL, '_blank')\n    window.location.href = RoutePath.DASHBOARD\n  }, [])\n  return null\n}\n\nconst SlackRedirect = () => {\n  React.useEffect(() => {\n    window.open(DAYTONA_SLACK_URL, '_blank')\n    window.location.href = RoutePath.DASHBOARD\n  }, [])\n  return null\n}\n\nfunction App() {\n  const config = useConfig()\n  const location = useLocation()\n  const posthog = usePostHog()\n\n  const { error: authError, isAuthenticated, user, signoutRedirect } = useAuth()\n\n  useEffect(() => {\n    if (isAuthenticated && user && posthog?.get_distinct_id() !== user.profile.sub) {\n      posthog?.identify(user.profile.sub, {\n        email: user.profile.email,\n        name: user.profile.name,\n      })\n    }\n    if (import.meta.env.PROD && config.pylonAppId && isAuthenticated && user) {\n      initPylon(config.pylonAppId, {\n        chat_settings: {\n          app_id: config.pylonAppId,\n          email: user.profile.email || '',\n          name: user.profile.name || '',\n          avatar_url: user.profile.picture,\n          email_hash: user.profile?.email_hash as string | undefined,\n        },\n      })\n    }\n  }, [isAuthenticated, user, posthog, config.pylonAppId])\n\n  // Hack for tracking PostHog pageviews in SPAs\n  useEffect(() => {\n    if (import.meta.env.PROD) {\n      posthog?.capture('$pageview', {\n        $current_url: window.location.href,\n      })\n    }\n  }, [location, posthog])\n\n  if (authError) {\n    return (\n      <Dialog open>\n        <DialogContent className=\"[&>button]:hidden\">\n          <DialogHeader>\n            <DialogTitle>Authentication Error</DialogTitle>\n            <DialogDescription>{authError.message}</DialogDescription>\n          </DialogHeader>\n          <DialogFooter>\n            <Button onClick={() => signoutRedirect()}>Go Back</Button>\n          </DialogFooter>\n        </DialogContent>\n      </Dialog>\n    )\n  }\n\n  return (\n    <Routes>\n      <Route path={RoutePath.LANDING} element={<LandingPage />} />\n      <Route path={RoutePath.LOGOUT} element={<Logout />} />\n      <Route path={RoutePath.DOCS} element={<DocsRedirect />} />\n      <Route path={RoutePath.SLACK} element={<SlackRedirect />} />\n      <Route\n        path={RoutePath.DASHBOARD}\n        element={\n          <Suspense fallback={<LoadingFallback />}>\n            <ApiProvider>\n              <OrganizationsProvider>\n                <SelectedOrganizationProvider>\n                  <RegionsProvider>\n                    <UserOrganizationInvitationsProvider>\n                      <NotificationSocketProvider>\n                        <CommandPaletteProvider>\n                          <BannerProvider>\n                            <Dashboard />\n                          </BannerProvider>\n                        </CommandPaletteProvider>\n                      </NotificationSocketProvider>\n                    </UserOrganizationInvitationsProvider>\n                  </RegionsProvider>\n                </SelectedOrganizationProvider>\n              </OrganizationsProvider>\n            </ApiProvider>\n          </Suspense>\n        }\n      >\n        <Route index element={<Navigate to={`${getRouteSubPath(RoutePath.SANDBOXES)}${location.search}`} replace />} />\n        <Route path={getRouteSubPath(RoutePath.KEYS)} element={<Keys />} />\n        <Route path={getRouteSubPath(RoutePath.SANDBOXES)} element={<Sandboxes />} />\n        <Route path={getRouteSubPath(RoutePath.SANDBOX_DETAILS)} element={<SandboxDetails />} />\n        <Route path={getRouteSubPath(RoutePath.SNAPSHOTS)} element={<Snapshots />} />\n        <Route path={getRouteSubPath(RoutePath.REGISTRIES)} element={<Registries />} />\n        <Route\n          path={getRouteSubPath(RoutePath.VOLUMES)}\n          element={\n            <RequiredPermissionsOrganizationPageWrapper\n              requiredPermissions={[OrganizationRolePermissionsEnum.READ_VOLUMES]}\n            >\n              <Volumes />\n            </RequiredPermissionsOrganizationPageWrapper>\n          }\n        />\n        <Route\n          path={getRouteSubPath(RoutePath.LIMITS)}\n          element={\n            <OwnerAccessOrganizationPageWrapper>\n              <Limits />\n            </OwnerAccessOrganizationPageWrapper>\n          }\n        />\n        {config.billingApiUrl && (\n          <>\n            <Route\n              path={getRouteSubPath(RoutePath.BILLING_SPENDING)}\n              element={\n                <OwnerAccessOrganizationPageWrapper>\n                  <Spending />\n                </OwnerAccessOrganizationPageWrapper>\n              }\n            />\n            <Route\n              path={getRouteSubPath(RoutePath.BILLING_WALLET)}\n              element={\n                <OwnerAccessOrganizationPageWrapper>\n                  <Wallet />\n                </OwnerAccessOrganizationPageWrapper>\n              }\n            />\n            <Route path={getRouteSubPath(RoutePath.EMAIL_VERIFY)} element={<EmailVerify />} />\n          </>\n        )}\n        <Route\n          path={getRouteSubPath(RoutePath.MEMBERS)}\n          element={\n            <NonPersonalOrganizationPageWrapper>\n              <OrganizationMembers />\n            </NonPersonalOrganizationPageWrapper>\n          }\n        />\n        {\n          // TODO: uncomment when we allow creating custom roles\n          /* <Route\n          path={getRouteSubPath(RoutePath.ROLES)}\n          element={\n            <NonPersonalOrganizationPageWrapper>\n              <OwnerAccessOrganizationPageWrapper>\n                <OrganizationRoles />\n              </OwnerAccessOrganizationPageWrapper>\n            </NonPersonalOrganizationPageWrapper>\n          }\n        /> */\n        }\n        <Route\n          path={getRouteSubPath(RoutePath.AUDIT_LOGS)}\n          element={\n            <RequiredPermissionsOrganizationPageWrapper\n              requiredPermissions={[OrganizationRolePermissionsEnum.READ_AUDIT_LOGS]}\n            >\n              <AuditLogs />\n            </RequiredPermissionsOrganizationPageWrapper>\n          }\n        />\n        <Route path={getRouteSubPath(RoutePath.SETTINGS)} element={<OrganizationSettings />} />\n        <Route\n          path={getRouteSubPath(RoutePath.REGIONS)}\n          element={\n            <RequiredFeatureFlagWrapper flagKey={FeatureFlags.ORGANIZATION_INFRASTRUCTURE}>\n              <Regions />\n            </RequiredFeatureFlagWrapper>\n          }\n        />\n        <Route\n          path={getRouteSubPath(RoutePath.RUNNERS)}\n          element={\n            <RequiredFeatureFlagWrapper flagKey={FeatureFlags.ORGANIZATION_INFRASTRUCTURE}>\n              <RequiredPermissionsOrganizationPageWrapper\n                requiredPermissions={[OrganizationRolePermissionsEnum.READ_RUNNERS]}\n              >\n                <Runners />\n              </RequiredPermissionsOrganizationPageWrapper>\n            </RequiredFeatureFlagWrapper>\n          }\n        />\n        <Route\n          path={getRouteSubPath(RoutePath.ACCOUNT_SETTINGS)}\n          element={<AccountSettings linkedAccountsEnabled={config.linkedAccountsEnabled} />}\n        />\n        <Route path={getRouteSubPath(RoutePath.USER_INVITATIONS)} element={<UserOrganizationInvitations />} />\n        <Route path={getRouteSubPath(RoutePath.ONBOARDING)} element={<Onboarding />} />\n        <Route\n          path={getRouteSubPath(RoutePath.EXPERIMENTAL)}\n          element={\n            <OwnerAccessOrganizationPageWrapper>\n              <Experimental />\n            </OwnerAccessOrganizationPageWrapper>\n          }\n        />\n        <Route path={getRouteSubPath(RoutePath.PLAYGROUND)} element={<Playground />} />\n        <Route\n          path={getRouteSubPath(RoutePath.WEBHOOKS)}\n          element={\n            <SvixProvider>\n              <Webhooks />\n            </SvixProvider>\n          }\n        />\n        <Route\n          path={getRouteSubPath(RoutePath.WEBHOOK_ENDPOINT_DETAILS)}\n          element={\n            <SvixProvider>\n              <WebhookEndpointDetails />\n            </SvixProvider>\n          }\n        />\n      </Route>\n      <Route path=\"*\" element={<NotFound />} />\n    </Routes>\n  )\n}\n\nfunction NonPersonalOrganizationPageWrapper({ children }: { children: React.ReactNode }) {\n  const { selectedOrganization } = useSelectedOrganization()\n\n  if (selectedOrganization?.personal) {\n    return <Navigate to={RoutePath.DASHBOARD} replace />\n  }\n\n  return children\n}\n\nfunction OwnerAccessOrganizationPageWrapper({ children }: { children: React.ReactNode }) {\n  const { authenticatedUserOrganizationMember } = useSelectedOrganization()\n\n  if (authenticatedUserOrganizationMember?.role !== OrganizationUserRoleEnum.OWNER) {\n    return <Navigate to={RoutePath.DASHBOARD} replace />\n  }\n\n  return children\n}\n\nfunction RequiredPermissionsOrganizationPageWrapper({\n  children,\n  requiredPermissions,\n}: {\n  children: React.ReactNode\n  requiredPermissions: OrganizationRolePermissionsEnum[]\n}) {\n  const { authenticatedUserHasPermission } = useSelectedOrganization()\n\n  if (!requiredPermissions.every((permission) => authenticatedUserHasPermission(permission))) {\n    return <Navigate to={RoutePath.DASHBOARD} replace />\n  }\n\n  return children\n}\n\nfunction RequiredFeatureFlagWrapper({ children, flagKey }: { children: React.ReactNode; flagKey: FeatureFlags }) {\n  const flagEnabled = useFeatureFlagEnabled(flagKey)\n\n  if (!flagEnabled) {\n    return <Navigate to={RoutePath.DASHBOARD} replace />\n  }\n\n  return children\n}\n\nexport default App\n"
  },
  {
    "path": "apps/dashboard/src/api/apiClient.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BillingApiClient } from '@/billing-api/billingApiClient'\nimport { DashboardConfig } from '@/types/DashboardConfig'\nimport {\n  Configuration as AnalyticsConfiguration,\n  TelemetryApi as AnalyticsTelemetryApi,\n  UsageApi as AnalyticsUsageApi,\n} from '@daytonaio/analytics-api-client'\nimport {\n  ApiKeysApi,\n  AuditApi,\n  Configuration,\n  DockerRegistryApi,\n  OrganizationsApi,\n  RegionsApi,\n  RunnersApi,\n  SandboxApi,\n  SnapshotsApi,\n  ToolboxApi,\n  UsersApi,\n  VolumesApi,\n  WebhooksApi,\n} from '@daytonaio/api-client'\nimport axios, { AxiosError } from 'axios'\nimport { DaytonaError } from './errors'\n\nexport class ApiClient {\n  private config: Configuration\n  private _snapshotApi: SnapshotsApi\n  private _sandboxApi: SandboxApi\n  private _userApi: UsersApi\n  private _apiKeyApi: ApiKeysApi\n  private _dockerRegistryApi: DockerRegistryApi\n  private _organizationsApi: OrganizationsApi\n  private _billingApi: BillingApiClient\n  private _volumeApi: VolumesApi\n  private _toolboxApi: ToolboxApi\n  private _auditApi: AuditApi\n  private _regionsApi: RegionsApi\n  private _runnersApi: RunnersApi\n  private _webhooksApi: WebhooksApi\n  private _analyticsUsageApi: AnalyticsUsageApi | null\n  private _analyticsTelemetryApi: AnalyticsTelemetryApi | null\n\n  constructor(config: DashboardConfig, accessToken: string) {\n    this.config = new Configuration({\n      basePath: config.apiUrl,\n      accessToken: accessToken,\n    })\n\n    const axiosInstance = axios.create()\n    axiosInstance.interceptors.response.use(\n      (response) => {\n        return response\n      },\n      (error) => {\n        let errorMessage: string\n\n        if (error instanceof AxiosError && error.message.includes('timeout of')) {\n          errorMessage = 'Operation timed out'\n        } else {\n          errorMessage = error.response?.data?.message || error.response?.data || error.message || String(error)\n        }\n\n        throw DaytonaError.fromString(String(errorMessage), { cause: error instanceof Error ? error : undefined })\n      },\n    )\n\n    // Initialize APIs\n    this._snapshotApi = new SnapshotsApi(this.config, undefined, axiosInstance)\n    this._sandboxApi = new SandboxApi(this.config, undefined, axiosInstance)\n    this._userApi = new UsersApi(this.config, undefined, axiosInstance)\n    this._apiKeyApi = new ApiKeysApi(this.config, undefined, axiosInstance)\n    this._dockerRegistryApi = new DockerRegistryApi(this.config, undefined, axiosInstance)\n    this._organizationsApi = new OrganizationsApi(this.config, undefined, axiosInstance)\n    this._billingApi = new BillingApiClient(config.billingApiUrl || window.location.origin, accessToken)\n    this._volumeApi = new VolumesApi(this.config, undefined, axiosInstance)\n    this._toolboxApi = new ToolboxApi(this.config, undefined, axiosInstance)\n    this._auditApi = new AuditApi(this.config, undefined, axiosInstance)\n    this._regionsApi = new RegionsApi(this.config, undefined, axiosInstance)\n    this._runnersApi = new RunnersApi(this.config, undefined, axiosInstance)\n    this._webhooksApi = new WebhooksApi(this.config, undefined, axiosInstance)\n\n    if (config.analyticsApiUrl) {\n      const analyticsConfig = new AnalyticsConfiguration({\n        basePath: config.analyticsApiUrl,\n        accessToken: accessToken,\n        baseOptions: {\n          headers: {\n            Authorization: `Bearer ${accessToken}`,\n          },\n        },\n      })\n      this._analyticsUsageApi = new AnalyticsUsageApi(analyticsConfig, undefined, axiosInstance)\n      this._analyticsTelemetryApi = new AnalyticsTelemetryApi(analyticsConfig, undefined, axiosInstance)\n    } else {\n      this._analyticsUsageApi = null\n      this._analyticsTelemetryApi = null\n    }\n  }\n\n  public setAccessToken(accessToken: string) {\n    this.config.accessToken = accessToken\n  }\n\n  public get snapshotApi() {\n    return this._snapshotApi\n  }\n\n  public get sandboxApi() {\n    return this._sandboxApi\n  }\n\n  public get userApi() {\n    return this._userApi\n  }\n\n  public get apiKeyApi() {\n    return this._apiKeyApi\n  }\n\n  public get dockerRegistryApi() {\n    return this._dockerRegistryApi\n  }\n\n  public get organizationsApi() {\n    return this._organizationsApi\n  }\n\n  public get billingApi() {\n    return this._billingApi\n  }\n\n  public get volumeApi() {\n    return this._volumeApi\n  }\n\n  public get toolboxApi() {\n    return this._toolboxApi\n  }\n\n  public get auditApi() {\n    return this._auditApi\n  }\n\n  public get regionsApi() {\n    return this._regionsApi\n  }\n\n  public get runnersApi() {\n    return this._runnersApi\n  }\n\n  public get webhooksApi() {\n    return this._webhooksApi\n  }\n\n  public get analyticsUsageApi() {\n    return this._analyticsUsageApi\n  }\n\n  public get analyticsTelemetryApi() {\n    return this._analyticsTelemetryApi\n  }\n\n  public async webhookRequest(method: string, url: string, data?: any) {\n    // Use the existing axios instance that's already configured with interceptors\n    const axiosInstance = axios.create({\n      baseURL: this.config.basePath,\n      headers: {\n        Authorization: `Bearer ${this.config.accessToken}`,\n      },\n    })\n\n    return axiosInstance.request({\n      method,\n      url,\n      data,\n    })\n  }\n\n  public get axiosInstance() {\n    return axios.create({\n      baseURL: this.config.basePath,\n      headers: {\n        Authorization: `Bearer ${this.config.accessToken}`,\n      },\n    })\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/api/errors.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport class DaytonaError extends Error {\n  public static fromError(error: Error): DaytonaError {\n    if (String(error).includes('Organization is suspended')) {\n      return new OrganizationSuspendedError(error.message, {\n        cause: error.cause,\n      })\n    }\n\n    return new DaytonaError(error.message, {\n      cause: error.cause,\n    })\n  }\n\n  public static fromString(error: string, options?: { cause?: Error }): DaytonaError {\n    return DaytonaError.fromError(new Error(error, options))\n  }\n}\n\nexport class OrganizationSuspendedError extends DaytonaError {}\n"
  },
  {
    "path": "apps/dashboard/src/assets/Logo.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport function Logo() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"27\" height=\"28\" fill=\"currentColor\" viewBox=\"0 0 27 28\">\n      <g clipPath=\"url(#a)\">\n        <path d=\"M11.213 18.712H1.575v3.282h9.638v-3.282ZM25.53 7.223H14.516v3.283H25.53V7.223ZM16.911.111 8.733 8.235l2.337 2.321 8.177-8.124-2.336-2.32Z\" />\n        <path d=\"m2.503 10.202 6.28 6.239-2.336 2.321-6.28-6.239 2.336-2.32Zm7.922 17.407 6.62-6.576-2.337-2.321-6.62 6.576 2.337 2.321Zm13.969-7.432-7.4-7.35 2.337-2.321 7.4 7.35-2.337 2.32ZM8.733 12.694V4.762H5.43v7.932h3.304Z\" />\n        <path d=\"M20.3 26.097V16.25h-3.305v9.847h3.304Z\" />\n      </g>\n      <defs>\n        <clipPath id=\"a\">\n          <path d=\"M0 0h27v28H0z\" />\n        </clipPath>\n      </defs>\n    </svg>\n  )\n}\n\nexport function LogoText() {\n  return (\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"82\" height=\"28\" fill=\"currentColor\" viewBox=\"0 0 82 28\">\n      <path\n        fillRule=\"evenodd\"\n        d=\"M-.073 22.568h3.97c2.246.034 3.934-.09 5.134-.603 1.218-.53 2.075-1.411 2.572-2.643.515-1.231.772-3.01.772-5.336 0-2.155-.214-3.943-.643-5.157-.429-1.214-1.157-2.112-2.186-2.694-1.012-.598-2.452-.992-4.321-1.18a25.132 25.132 0 0 0-2.495-.128c-.806-.017-1.763 0-2.803 0v17.741Zm7.844-3.066c-.617.393-1.474.624-2.572.693a7.063 7.063 0 0 1-1.054.025 95.24 95.24 0 0 1-1.363-.077V7.393c.72 0 1.508.043 2.366.128 1.149.137 2.031.41 2.649.821.617.41 1.054 1.044 1.312 1.899.257.838.385 2.018.385 3.54 0 1.608-.137 2.865-.411 3.771-.257.89-.695 1.54-1.312 1.95Zm7.067 2.848c.651.24 1.568.359 2.752.359 1.046 0 1.843-.128 2.392-.385.548-.274 1.054-.77 1.517-1.488h.206v1.745h2.52V13.5c0-1.249-.163-2.206-.488-2.873-.326-.685-.883-1.163-1.672-1.437-.772-.29-1.869-.436-3.292-.436-1.406 0-2.495.128-3.267.385-.754.239-1.286.658-1.594 1.257-.31.581-.516 1.421-.516 2.514h2.856c0-.719.172-1.206.515-1.463.36-.256 1.029-.384 2.006-.384.737 0 1.311.077 1.723.23.412.155.703.402.875.745.17.342.257.829.257 1.462v.359h-2.186c-1.664 0-2.95.145-3.858.436-.91.274-1.552.761-1.93 1.462-.377.685-.565 1.65-.565 2.9 0 1.06.128 1.88.386 2.462.274.582.728.992 1.363 1.232Zm5.375-2.386c-.48.256-1.175.385-2.083.385-.892 0-1.5-.137-1.826-.41-.326-.274-.489-.779-.489-1.515 0-.598.094-1.051.283-1.36.189-.324.497-.555.926-.692.446-.137 1.071-.214 1.877-.23l2.7-.026c-.033 1.111-.153 1.966-.359 2.565s-.549 1.026-1.029 1.283Zm27.122 2.129c.874.41 2.118.616 3.73.616 1.594 0 2.828-.205 3.703-.616.874-.427 1.492-1.129 1.852-2.104.377-.992.566-2.402.566-4.233 0-1.847-.189-3.266-.566-4.258-.36-.992-.977-1.693-1.852-2.104-.858-.427-2.092-.641-3.703-.641-1.612 0-2.856.214-3.73.641-.875.41-1.492 1.112-1.852 2.104-.36.992-.54 2.411-.54 4.258 0 1.83.18 3.241.54 4.233.36.992.977 1.694 1.852 2.104Zm5.761-2.155c-.463.274-1.14.41-2.031.41-.892 0-1.578-.136-2.058-.41-.48-.273-.823-.735-1.03-1.385-.205-.65-.308-1.582-.308-2.797 0-1.231.103-2.172.309-2.822.206-.667.549-1.137 1.029-1.41.48-.291 1.166-.437 2.058-.437.89 0 1.568.146 2.031.436.48.274.823.744 1.029 1.412.206.65.309 1.59.309 2.821 0 1.215-.103 2.147-.31 2.797-.205.65-.548 1.111-1.028 1.385Z\"\n        clipRule=\"evenodd\"\n      />\n      <path d=\"M58.13 8.88h2.752v2.105h.206c.428-.873.908-1.463 1.44-1.77.548-.308 1.337-.462 2.366-.462 1.234 0 2.186.162 2.855.487.669.308 1.149.83 1.44 1.565.292.736.437 1.787.437 3.156v8.62h-2.752V13.91c0-.7-.077-1.248-.231-1.642a1.398 1.398 0 0 0-.797-.82c-.378-.154-.918-.231-1.62-.231-.875 0-1.553.128-2.032.384-.464.257-.798.693-1.004 1.309-.206.615-.308 1.488-.308 2.617v7.055H58.13V8.88Z\" />\n      <path\n        fillRule=\"evenodd\"\n        d=\"M72.445 22.35c.652.24 1.57.359 2.753.359 1.046 0 1.843-.128 2.392-.385.548-.274 1.054-.77 1.517-1.488h.206v1.745h2.52V13.5c0-1.249-.163-2.206-.488-2.873-.326-.685-.883-1.163-1.672-1.437-.772-.29-1.87-.436-3.292-.436-1.406 0-2.495.128-3.267.385-.754.239-1.286.658-1.594 1.257-.309.581-.458 1.318-.458 2.514h2.798c0-.719.172-1.206.514-1.463.36-.256 1.03-.384 2.007-.384.737 0 1.311.077 1.723.23.411.155.703.402.874.745.172.342.258.829.258 1.462v.359h-2.187c-1.663 0-2.949.145-3.858.436-.909.274-1.551.761-1.929 1.462-.377.685-.566 1.65-.566 2.9 0 1.06.13 1.88.386 2.462.275.582.73.992 1.364 1.232Zm5.376-2.386c-.48.256-1.174.385-2.083.385-.892 0-1.5-.137-1.826-.41-.326-.274-.489-.779-.489-1.515 0-.598.094-1.051.283-1.36.188-.324.497-.555.926-.692.445-.137 1.072-.214 1.877-.23l2.701-.026c-.034 1.111-.155 1.966-.36 2.565-.206.599-.549 1.026-1.03 1.283Z\"\n        clipRule=\"evenodd\"\n      />\n      <path d=\"M36.202 8.851h-2.65l-2.601 11.27h-.947L27.506 8.85h-2.602l2.11 10.666a3.737 3.737 0 0 0 3.666 3.012l-.562 1.754c-.27.696-.376 1.42-1.74 1.42h-1.704v2.223l3.158.032c.953-.016 2.15-.704 3.04-3.675l3.33-15.432Zm3.89 13.3c.606.31 1.497.465 2.675.465h1.58v-2.348h-.723c-.693 0-1.212-.078-1.559-.232-.346-.155-.58-.379-.701-.671-.104-.31-.156-.748-.156-1.316v-6.914h3.14v-2.27h-3.14v-2.89H38.69v2.89h-1.243l-.469 2.27h1.608v7.017c0 1.101.104 1.97.312 2.606a2.38 2.38 0 0 0 1.195 1.393Z\" />\n    </svg>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/billingApiClient.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DaytonaError } from '@/api/errors'\nimport axios, { AxiosInstance } from 'axios'\nimport {\n  AutomaticTopUp,\n  OrganizationEmail,\n  OrganizationTier,\n  OrganizationUsage,\n  OrganizationWallet,\n  PaginatedInvoices,\n  PaymentUrl,\n  Tier,\n  WalletTopUpRequest,\n} from './types'\n\nexport class BillingApiClient {\n  private axiosInstance: AxiosInstance\n\n  constructor(apiUrl: string, accessToken: string) {\n    this.axiosInstance = axios.create({\n      baseURL: apiUrl,\n      headers: {\n        Authorization: `Bearer ${accessToken}`,\n      },\n    })\n\n    this.axiosInstance.interceptors.response.use(\n      (response) => {\n        return response\n      },\n      (error) => {\n        const errorMessage = error.response?.data?.message || error.response?.data || error.message || String(error)\n\n        throw DaytonaError.fromString(String(errorMessage))\n      },\n    )\n  }\n\n  public async getOrganizationUsage(organizationId: string): Promise<OrganizationUsage> {\n    const response = await this.axiosInstance.get(`/organization/${organizationId}/usage`)\n    return response.data\n  }\n\n  public async getPastOrganizationUsage(organizationId: string, periods?: number): Promise<OrganizationUsage[]> {\n    const response = await this.axiosInstance.get(`/organization/${organizationId}/usage/past?periods=${periods || 12}`)\n    return response.data\n  }\n\n  public async getOrganizationWallet(organizationId: string): Promise<OrganizationWallet> {\n    const response = await this.axiosInstance.get(`/organization/${organizationId}/wallet`)\n    return response.data\n  }\n\n  public async setAutomaticTopUp(organizationId: string, automaticTopUp?: AutomaticTopUp): Promise<void> {\n    await this.axiosInstance.put(`/organization/${organizationId}/wallet/automatic-top-up`, automaticTopUp)\n  }\n\n  public async getOrganizationBillingPortalUrl(organizationId: string): Promise<string> {\n    const response = await this.axiosInstance.get(`/organization/${organizationId}/portal-url`)\n    return response.data\n  }\n\n  public async getOrganizationCheckoutUrl(organizationId: string): Promise<string> {\n    const response = await this.axiosInstance.get(`/organization/${organizationId}/checkout-url`)\n    return response.data\n  }\n\n  public async redeemCoupon(organizationId: string, couponCode: string): Promise<string> {\n    const response = await this.axiosInstance.post(`/organization/${organizationId}/redeem-coupon/${couponCode}`)\n    return response.data?.message || 'Coupon redeemed successfully'\n  }\n\n  public async getOrganizationTier(organizationId: string): Promise<OrganizationTier> {\n    const response = await this.axiosInstance.get(`/organization/${organizationId}/tier`)\n    const orgTier: OrganizationTier = {\n      tier: response.data.tier,\n      largestSuccessfulPaymentDate: response.data.largestSuccessfulPaymentDate\n        ? new Date(response.data.largestSuccessfulPaymentDate)\n        : undefined,\n      largestSuccessfulPaymentCents: response.data.largestSuccessfulPaymentCents,\n      expiresAt: response.data.expiresAt ? new Date(response.data.expiresAt) : undefined,\n      hasVerifiedBusinessEmail: response.data.hasVerifiedBusinessEmail,\n    }\n\n    return orgTier\n  }\n\n  public async upgradeTier(organizationId: string, tier: number): Promise<void> {\n    await this.axiosInstance.post(`/organization/${organizationId}/tier/upgrade`, { tier })\n  }\n\n  public async downgradeTier(organizationId: string, tier: number): Promise<void> {\n    await this.axiosInstance.post(`/organization/${organizationId}/tier/downgrade`, { tier })\n  }\n\n  public async listTiers(): Promise<Tier[]> {\n    const response = await this.axiosInstance.get('/tier')\n    return response.data\n  }\n\n  public async listOrganizationEmails(organizationId: string): Promise<OrganizationEmail[]> {\n    const response = await this.axiosInstance.get(`/organization/${organizationId}/email`)\n    return response.data.map((email: any) => ({\n      ...email,\n      verifiedAt: email.verifiedAt ? new Date(email.verifiedAt) : undefined,\n    }))\n  }\n\n  public async addOrganizationEmail(organizationId: string, email: string): Promise<void> {\n    await this.axiosInstance.post(`/organization/${organizationId}/email`, { email })\n  }\n\n  public async deleteOrganizationEmail(organizationId: string, email: string): Promise<void> {\n    await this.axiosInstance.delete(`/organization/${organizationId}/email`, { data: { email } })\n  }\n\n  public async verifyOrganizationEmail(organizationId: string, email: string, token: string): Promise<void> {\n    await this.axiosInstance.post(`/organization/${organizationId}/email/verify`, { email, token })\n  }\n\n  public async resendOrganizationEmailVerification(organizationId: string, email: string): Promise<void> {\n    await this.axiosInstance.post(`/organization/${organizationId}/email/resend`, { email })\n  }\n\n  public async listInvoices(organizationId: string, page?: number, perPage?: number): Promise<PaginatedInvoices> {\n    const params = new URLSearchParams()\n    if (page !== undefined) {\n      params.append('page', page.toString())\n    }\n    if (perPage !== undefined) {\n      params.append('perPage', perPage.toString())\n    }\n    const queryString = params.toString()\n    const url = `/organization/${organizationId}/invoices${queryString ? `?${queryString}` : ''}`\n    const response = await this.axiosInstance.get(url)\n    return response.data\n  }\n\n  public async createInvoicePaymentUrl(organizationId: string, invoiceId: string): Promise<PaymentUrl> {\n    const response = await this.axiosInstance.post(`/organization/${organizationId}/invoices/${invoiceId}/payment-url`)\n    return response.data\n  }\n\n  public async voidInvoice(organizationId: string, invoiceId: string): Promise<void> {\n    await this.axiosInstance.post(`/organization/${organizationId}/invoices/${invoiceId}/void`)\n  }\n\n  public async topUpWallet(organizationId: string, amountCents: number): Promise<PaymentUrl> {\n    const response = await this.axiosInstance.post(`/organization/${organizationId}/wallet/top-up`, {\n      amountCents,\n    } as WalletTopUpRequest)\n    return response.data\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport * from './billingApiClient'\nexport * from './types'\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/types/Invoice.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface InvoiceErrorDetail {\n  details?: Record<string, string>\n  errorCode: string\n}\n\nexport type InvoicePaymentStatus = 'pending' | 'succeeded' | 'failed'\nexport type InvoiceStatus = 'draft' | 'finalized' | 'failed' | 'voided' | 'pending'\nexport type InvoiceType = 'subscription' | 'add_on' | 'one_off'\n\nexport interface Invoice {\n  currency: string\n  errorDetails?: InvoiceErrorDetail[]\n  fileUrl?: string\n  id: string\n  issuingDate: string\n  number: string\n  paymentDueDate: string\n  paymentOverdue: boolean\n  paymentStatus: InvoicePaymentStatus\n  sequentialId: number\n  status: InvoiceStatus\n  totalAmountCents: number\n  totalDueAmountCents: number\n  type: InvoiceType\n}\n\nexport interface PaginatedInvoices {\n  items: Invoice[]\n  totalItems: number\n  totalPages: number\n}\n\nexport interface PaymentUrl {\n  url: string\n}\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/types/OrganizationEmail.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type OrganizationEmail = {\n  email: string\n  verified: boolean\n  owner: boolean\n  business: boolean\n  verifiedAt?: Date\n}\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/types/OrganizationTier.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type OrganizationTier = {\n  tier: number\n  largestSuccessfulPaymentDate?: Date\n  largestSuccessfulPaymentCents: number\n  expiresAt?: Date\n  hasVerifiedBusinessEmail: boolean\n}\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/types/OrganizationUsage.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface OrganizationUsage {\n  from: Date\n  to: Date\n  issuingDate: string\n  amountCents: number\n  totalAmountCents: number\n  taxesAmountCents: number\n  usageCharges: UsageCharge[]\n}\n\nexport interface UsageCharge {\n  units: string\n  eventsCount: number\n  amountCents: number\n  billableMetric: BillableMetricCode\n}\n\nexport enum BillableMetricCode {\n  CPU_USAGE = 'cpu_usage',\n  GPU_USAGE = 'gpu_usage',\n  RAM_USAGE = 'ram_usage',\n  DISK_USAGE = 'disk_usage',\n  UNKNOWN = 'unknown',\n}\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/types/OrganizationWallet.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface OrganizationWallet {\n  balanceCents: number\n  ongoingBalanceCents: number\n  name: string\n  creditCardConnected: boolean\n\n  automaticTopUp?: AutomaticTopUp\n  hasFailedOrPendingInvoice?: boolean\n}\n\nexport type AutomaticTopUp = {\n  thresholdAmount: number\n  targetAmount: number\n}\n\nexport interface WalletTopUpRequest {\n  amountCents: number\n}\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/types/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport * from './OrganizationTier'\nexport * from './OrganizationUsage'\nexport * from './OrganizationWallet'\nexport * from './tier'\nexport * from './OrganizationEmail'\nexport * from './Invoice'\n"
  },
  {
    "path": "apps/dashboard/src/billing-api/types/tier.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport type Tier = {\n  tier: number\n  tierLimit: TierLimit\n  minTopUpAmountCents: number\n  topUpIntervalDays: number\n}\n\nexport type TierLimit = {\n  concurrentCPU: number\n  concurrentRAMGiB: number\n  concurrentDiskGiB: number\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/AccountProviderIcon.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ComponentType } from 'react'\nimport { Github, Link2, Mail, LucideProps } from 'lucide-react'\n\ntype Props = {\n  provider: string\n  className?: string\n}\n\nexport function AccountProviderIcon(props: Props) {\n  return getIcon(props.provider, props.className)\n}\n\nconst getIcon = (provider: string, className?: string) => {\n  const IconComponent = ICON[provider]\n\n  if (!IconComponent) {\n    return <Link2 className={className} />\n  }\n\n  return <IconComponent className={className} />\n}\n\nconst ICON: { [x: string]: ComponentType<LucideProps> } = {\n  github: Github,\n  'google-oauth2': Mail,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/AnnouncementBanner.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { X, Info } from 'lucide-react'\nimport { Button } from './ui/button'\n\ninterface AnnouncementBannerProps {\n  text: string\n  learnMoreUrl?: string\n  onDismiss: () => void\n}\n\nexport function AnnouncementBanner({ text, learnMoreUrl, onDismiss }: AnnouncementBannerProps) {\n  return (\n    <div className=\"fixed top-0 left-0 right-0 z-50 bg-primary text-primary-foreground px-4 md:px-6 h-16 md:h-12 flex items-center\">\n      <div className=\"flex items-center justify-between w-full\">\n        <div className=\"flex items-center justify-start flex-1 gap-4 md:gap-3\">\n          <Info className=\"h-4 w-4 flex-shrink-0\" />\n          <div className=\"flex items-center gap-4 md:gap-3\">\n            <p className=\"text-sm font-medium\">{text}</p>\n            {learnMoreUrl && (\n              <a\n                href={learnMoreUrl}\n                target=\"_blank\"\n                rel=\"noopener noreferrer\"\n                className=\"inline-flex items-center gap-1 text-sm font-medium underline whitespace-nowrap hover:text-primary-foreground/80\"\n              >\n                Learn More\n              </a>\n            )}\n          </div>\n        </div>\n        <Button\n          variant=\"ghost\"\n          size=\"sm\"\n          className=\"h-auto p-1 hover:bg-primary-foreground/10 text-primary-foreground hover:text-primary-foreground\"\n          onClick={onDismiss}\n          aria-label=\"Dismiss announcement\"\n        >\n          <X className=\"h-4 w-4\" />\n        </Button>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ApiKeyTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CREATE_API_KEY_PERMISSIONS_GROUPS } from '@/constants/CreateApiKeyPermissionsGroups'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { ApiKeyList, ApiKeyListPermissionsEnum, CreateApiKeyPermissionsEnum } from '@daytonaio/api-client'\n\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { KeyRound, Loader2 } from 'lucide-react'\nimport { useMemo, useState } from 'react'\nimport { Pagination } from './Pagination'\nimport { TableEmptyState } from './TableEmptyState'\nimport { Badge } from './ui/badge'\nimport { Button } from './ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from './ui/dialog'\nimport { Popover, PopoverContent, PopoverTrigger } from './ui/popover'\nimport { Skeleton } from './ui/skeleton'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './ui/table'\nimport { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'\n\ninterface DataTableProps {\n  data: ApiKeyList[]\n  loading: boolean\n  isLoadingKey: (key: ApiKeyList) => boolean\n  onRevoke: (key: ApiKeyList) => void\n}\n\nexport function ApiKeyTable({ data, loading, isLoadingKey, onRevoke }: DataTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const columns = getColumns({ onRevoke, isLoadingKey })\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    state: {\n      sorting,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <Table>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead className=\"px-2\" key={header.id}>\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <>\n                {Array.from(new Array(5)).map((_, i) => (\n                  <TableRow key={i}>\n                    {table.getVisibleLeafColumns().map((column, i, arr) =>\n                      i === arr.length - 1 ? null : (\n                        <TableCell key={column.id}>\n                          <Skeleton className=\"h-4 w-10/12\" />\n                        </TableCell>\n                      ),\n                    )}\n                  </TableRow>\n                ))}\n              </>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow\n                  key={row.id}\n                  data-state={row.getIsSelected() && 'selected'}\n                  className={`${isLoadingKey(row.original) ? 'opacity-50 pointer-events-none' : ''}`}\n                >\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell className=\"px-2\" key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No API Keys yet.\"\n                icon={<KeyRound className=\"w-8 h-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>API Keys authenticate requests made through the Daytona SDK or CLI.</p>\n                    <p>\n                      Generate one and{' '}\n                      <a\n                        href=\"https://www.daytona.io/docs/api-keys\"\n                        target=\"_blank\"\n                        rel=\"noopener noreferrer\"\n                        className=\"text-primary hover:underline font-medium\"\n                      >\n                        check out the API Key setup guide\n                      </a>\n                      .\n                    </p>\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination table={table} className=\"mt-4\" entityName=\"API Keys\" />\n    </div>\n  )\n}\n\nconst getExpiresAtColor = (expiresAt: Date | null) => {\n  if (!expiresAt) {\n    return 'text-foreground'\n  }\n\n  const MILLISECONDS_IN_MINUTE = 1000 * 60\n  const MINUTES_IN_DAY = 24 * 60\n\n  const diffInMinutes = Math.floor((new Date(expiresAt).getTime() - new Date().getTime()) / MILLISECONDS_IN_MINUTE)\n\n  // Already expired\n  if (diffInMinutes < 0) {\n    return 'text-red-500'\n  }\n\n  // Expires within a day\n  if (diffInMinutes < MINUTES_IN_DAY) {\n    return 'text-yellow-600 dark:text-yellow-400'\n  }\n\n  // Expires in more than a day\n  return 'text-foreground'\n}\n\nconst getColumns = ({\n  onRevoke,\n  isLoadingKey,\n}: {\n  onRevoke: (key: ApiKeyList) => void\n  isLoadingKey: (key: ApiKeyList) => boolean\n}): ColumnDef<ApiKeyList>[] => {\n  const columns: ColumnDef<ApiKeyList>[] = [\n    {\n      accessorKey: 'name',\n      header: 'Name',\n    },\n    {\n      accessorKey: 'value',\n      header: 'Key',\n    },\n    {\n      accessorKey: 'permissions',\n      header: () => {\n        return <div className=\"max-w-md px-3\">Permissions</div>\n      },\n      cell: ({ row }) => {\n        return <PermissionsTooltip permissions={row.original.permissions} availablePermissions={allPermissions} />\n      },\n    },\n    {\n      accessorKey: 'createdAt',\n      header: 'Created',\n      cell: ({ row }) => {\n        const createdAt = row.original.createdAt\n        const relativeTime = getRelativeTimeString(createdAt).relativeTimeString\n        const fullDate = new Date(createdAt).toLocaleString()\n\n        return (\n          <Tooltip>\n            <TooltipTrigger>\n              <span className=\"cursor-default\">{relativeTime}</span>\n            </TooltipTrigger>\n            <TooltipContent>\n              <p>{fullDate}</p>\n            </TooltipContent>\n          </Tooltip>\n        )\n      },\n    },\n    {\n      accessorKey: 'lastUsedAt',\n      header: 'Last Used',\n      cell: ({ row }) => {\n        const lastUsedAt = row.original.lastUsedAt\n        const relativeTime = getRelativeTimeString(lastUsedAt).relativeTimeString\n\n        if (!lastUsedAt) {\n          return <span className=\"text-muted-foreground\">{relativeTime}</span>\n        }\n\n        const fullDate = new Date(lastUsedAt).toLocaleString()\n\n        return (\n          <Tooltip>\n            <TooltipTrigger>\n              <span className=\"cursor-default\">{relativeTime}</span>\n            </TooltipTrigger>\n            <TooltipContent>\n              <p>{fullDate}</p>\n            </TooltipContent>\n          </Tooltip>\n        )\n      },\n    },\n    {\n      accessorKey: 'expiresAt',\n      header: 'Expires',\n      cell: ({ row }) => {\n        const expiresAt = row.original.expiresAt\n        const relativeTime = getRelativeTimeString(expiresAt).relativeTimeString\n\n        if (!expiresAt) {\n          return <span className=\"text-muted-foreground\">{relativeTime}</span>\n        }\n\n        const fullDate = new Date(expiresAt).toLocaleString()\n        const color = getExpiresAtColor(expiresAt)\n\n        return (\n          <Tooltip>\n            <TooltipTrigger>\n              <span className={`cursor-default ${color}`}>{relativeTime}</span>\n            </TooltipTrigger>\n            <TooltipContent>\n              <p>{fullDate}</p>\n            </TooltipContent>\n          </Tooltip>\n        )\n      },\n    },\n    {\n      id: 'actions',\n      size: 80,\n      cell: ({ row }) => {\n        const isLoading = isLoadingKey(row.original)\n\n        return (\n          <Dialog>\n            <DialogTrigger asChild>\n              <Button variant=\"ghost\" size={isLoading ? 'icon-sm' : 'sm'} disabled={isLoading} title=\"Revoke Key\">\n                {isLoading ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : 'Revoke'}\n              </Button>\n            </DialogTrigger>\n            <DialogContent>\n              <DialogHeader>\n                <DialogTitle>Confirm Key Revocation</DialogTitle>\n                <DialogDescription>\n                  Are you absolutely sure? This action cannot be undone. This will permanently delete this API key.\n                </DialogDescription>\n              </DialogHeader>\n              <DialogFooter>\n                <DialogClose asChild>\n                  <Button type=\"button\" variant=\"secondary\">\n                    Close\n                  </Button>\n                </DialogClose>\n                <DialogClose asChild>\n                  <Button variant=\"destructive\" onClick={() => onRevoke(row.original)}>\n                    Revoke\n                  </Button>\n                </DialogClose>\n              </DialogFooter>\n            </DialogContent>\n          </Dialog>\n        )\n      },\n    },\n  ]\n\n  return columns\n}\n\nconst allPermissions = Object.values(CreateApiKeyPermissionsEnum)\n\nconst IMPLICIT_READ_RESOURCES = ['Sandboxes', 'Snapshots', 'Registries', 'Regions']\n\nfunction PermissionsTooltip({\n  permissions,\n  availablePermissions,\n}: {\n  permissions: ApiKeyListPermissionsEnum[]\n  availablePermissions: CreateApiKeyPermissionsEnum[]\n}) {\n  const isFullAccess = allPermissions.length === permissions.length\n  const isSingleResourceAccess = CREATE_API_KEY_PERMISSIONS_GROUPS.find(\n    (group) =>\n      group.permissions.length === permissions.length && group.permissions.every((p) => permissions.includes(p)),\n  )\n\n  const availableGroups = useMemo(() => {\n    return CREATE_API_KEY_PERMISSIONS_GROUPS.map((group) => ({\n      ...group,\n      permissions: group.permissions.filter((p) => availablePermissions.includes(p)),\n    })).filter((group) => group.permissions.length > 0)\n  }, [availablePermissions])\n\n  const badgeVariant = isFullAccess ? 'warning' : 'outline'\n  const badgeText = isFullAccess ? 'Full' : isSingleResourceAccess ? isSingleResourceAccess.name : 'Restricted'\n\n  return (\n    <Popover>\n      <PopoverTrigger>\n        <Badge variant={badgeVariant} className=\"whitespace-nowrap\">\n          {badgeText} <span className=\"hidden xs:inline ml-1\">Access</span>\n        </Badge>\n      </PopoverTrigger>\n      <PopoverContent className=\"p-0\">\n        <p className=\"p-2 text-muted-foreground text-xs font-medium border-b\">Permissions</p>\n        <div className=\"flex flex-col\">\n          {availableGroups.map((group) => {\n            const selectedPermissions = group.permissions.filter((p) => permissions.includes(p))\n            const hasImplicitRead = IMPLICIT_READ_RESOURCES.includes(group.name)\n\n            if (selectedPermissions.length === 0 && !hasImplicitRead) {\n              return null\n            }\n\n            return (\n              <div key={group.name} className=\"flex justify-between gap-3 border-b last:border-b-0 p-2\">\n                <h3 className=\"text-sm\">{group.name}</h3>\n                <div className=\"flex gap-2 flex-wrap justify-end\">\n                  {hasImplicitRead && (\n                    <Badge variant=\"outline\" className=\"capitalize rounded-sm\">\n                      Read\n                    </Badge>\n                  )}\n                  {selectedPermissions.map((p) => (\n                    <Badge key={p} variant=\"outline\" className=\"capitalize rounded-sm\">\n                      {p.split(':')[0]}\n                    </Badge>\n                  ))}\n                </div>\n              </div>\n            )\n          })}\n        </div>\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/AuditLogTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Pagination } from '@/components/Pagination'\nimport { TableEmptyState } from '@/components/TableEmptyState'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { AuditLog } from '@daytonaio/api-client'\nimport { ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'\nimport { TextSearch } from 'lucide-react'\n\ninterface Props {\n  data: AuditLog[]\n  loading: boolean\n  pagination: {\n    pageIndex: number\n    pageSize: number\n  }\n  pageCount: number\n  totalItems: number\n  onPaginationChange: (pagination: { pageIndex: number; pageSize: number }) => void\n}\n\nexport function AuditLogTable({ data, loading, pagination, pageCount, onPaginationChange, totalItems }: Props) {\n  const columns = getColumns()\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    manualPagination: true,\n    pageCount: pageCount || 1,\n    onPaginationChange: pagination\n      ? (updater) => {\n          const newPagination = typeof updater === 'function' ? updater(table.getState().pagination) : updater\n          onPaginationChange(newPagination)\n        }\n      : undefined,\n    state: {\n      pagination: {\n        pageIndex: pagination?.pageIndex || 0,\n        pageSize: pagination?.pageSize || 10,\n      },\n    },\n    getRowId: (row) => row.id,\n  })\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <Table>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      style={{\n                        minWidth: header.column.columnDef.size,\n                        maxWidth: header.column.columnDef.size,\n                      }}\n                    >\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  Loading...\n                </TableCell>\n              </TableRow>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell\n                      key={cell.id}\n                      style={{\n                        minWidth: cell.column.columnDef.size,\n                        maxWidth: cell.column.columnDef.size,\n                      }}\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No logs yet.\"\n                icon={<TextSearch className=\"w-8 h-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>Audit logs are detailed records of all actions taken by users in the organization.</p>\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination table={table} className=\"mt-4\" entityName=\"Logs\" totalItems={totalItems} />\n    </div>\n  )\n}\n\nconst getColumns = (): ColumnDef<AuditLog>[] => {\n  const columns: ColumnDef<AuditLog>[] = [\n    {\n      header: 'Time',\n      size: 200,\n      cell: ({ row }) => {\n        const createdAt = new Date(row.original.createdAt)\n        const localeString = createdAt.toLocaleString()\n        const relativeTimeString = getRelativeTimeString(row.original.createdAt).relativeTimeString\n\n        return (\n          <div className=\"space-y-1\">\n            <div className=\"font-medium truncate\">{relativeTimeString}</div>\n            <div className=\"text-sm text-muted-foreground truncate\">{localeString}</div>\n          </div>\n        )\n      },\n    },\n    {\n      header: 'User',\n      size: 240,\n      cell: ({ row }) => {\n        const actorEmail = row.original.actorEmail\n        const actorId = row.original.actorId\n        const label = actorEmail || actorId\n\n        return (\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <div className=\"font-medium truncate w-fit max-w-full\">{label}</div>\n            </TooltipTrigger>\n            <TooltipContent>\n              <p>{label}</p>\n            </TooltipContent>\n          </Tooltip>\n        )\n      },\n    },\n    {\n      header: 'Action',\n      size: 240,\n      cell: ({ row }) => {\n        const action = row.original.action\n\n        return (\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <div className=\"font-medium truncate w-fit max-w-full\">{action}</div>\n            </TooltipTrigger>\n            <TooltipContent>\n              <p>{action}</p>\n            </TooltipContent>\n          </Tooltip>\n        )\n      },\n    },\n    {\n      header: 'Target',\n      size: 360,\n      cell: ({ row }) => {\n        const targetType = row.original.targetType\n        const targetId = row.original.targetId\n\n        if (!targetType && !targetId) {\n          return '-'\n        }\n\n        return (\n          <div className=\"space-y-1\">\n            {targetType && <div className=\"font-medium truncate\">{targetType}</div>}\n            {targetId && <div className=\"text-sm text-muted-foreground truncate\">{targetId}</div>}\n          </div>\n        )\n      },\n    },\n    {\n      header: 'Outcome',\n      size: 320,\n      cell: ({ row }) => {\n        const statusCode = row.original.statusCode\n        const errorMessage = row.original.errorMessage\n        const outcomeInfo = getOutcomeInfo(statusCode)\n\n        return (\n          <div className=\"space-y-1\">\n            <div className={`font-medium ${outcomeInfo.colorClass}`}>{outcomeInfo.label}</div>\n            {!errorMessage ? (\n              <div className=\"text-sm text-muted-foreground truncate\">{statusCode || '204'}</div>\n            ) : (\n              <Tooltip>\n                <TooltipTrigger asChild>\n                  <div className=\"text-sm text-muted-foreground truncate\">\n                    {statusCode || '500'}\n                    {` - ${errorMessage}`}\n                  </div>\n                </TooltipTrigger>\n                <TooltipContent>\n                  <p>{errorMessage}</p>\n                </TooltipContent>\n              </Tooltip>\n            )}\n          </div>\n        )\n      },\n    },\n  ]\n\n  return columns\n}\n\ntype OutcomeCategory = 'informational' | 'success' | 'redirect' | 'client-error' | 'server-error' | 'unknown'\n\ninterface OutcomeInfo {\n  label: string\n  colorClass: string\n}\n\nconst getOutcomeCategory = (statusCode: number | null | undefined): OutcomeCategory => {\n  if (!statusCode) return 'unknown'\n\n  if (statusCode >= 100 && statusCode < 200) return 'informational'\n  if (statusCode >= 200 && statusCode < 300) return 'success'\n  if (statusCode >= 300 && statusCode < 400) return 'redirect'\n  if (statusCode >= 400 && statusCode < 500) return 'client-error'\n  if (statusCode >= 500 && statusCode < 600) return 'server-error'\n\n  return 'unknown'\n}\n\nconst getOutcomeInfo = (statusCode: number | null | undefined): OutcomeInfo => {\n  const category = getOutcomeCategory(statusCode)\n\n  switch (category) {\n    case 'informational':\n      return {\n        label: 'Info',\n        colorClass: 'text-blue-500 dark:text-blue-300',\n      }\n    case 'success':\n      return {\n        label: 'Success',\n        colorClass: 'text-green-600 dark:text-green-400',\n      }\n    case 'redirect':\n      return {\n        label: 'Redirect',\n        colorClass: 'text-blue-600 dark:text-blue-400',\n      }\n    case 'client-error':\n    case 'server-error':\n      return {\n        label: 'Error',\n        colorClass: 'text-red-600 dark:text-red-400',\n      }\n    case 'unknown':\n    default:\n      return {\n        label: 'Unknown',\n        colorClass: 'text-gray-600 dark:text-gray-400',\n      }\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Banner.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport {\n  AlertCircleIcon,\n  AlertTriangleIcon,\n  CheckCircle2Icon,\n  ChevronRight,\n  InfoIcon,\n  MegaphoneIcon,\n  XIcon,\n} from 'lucide-react'\nimport { AnimatePresence, motion } from 'motion/react'\nimport { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'\nimport { v4 as uuidv4 } from 'uuid'\n\ntype BannerVariant = 'info' | 'success' | 'warning' | 'error' | 'neutral'\n\nconst variantIcons = {\n  info: InfoIcon,\n  success: CheckCircle2Icon,\n  warning: AlertTriangleIcon,\n  error: AlertCircleIcon,\n  neutral: MegaphoneIcon,\n}\n\nconst priorityMap: Record<BannerVariant, number> = {\n  error: 0,\n  warning: 1,\n  success: 2,\n  info: 3,\n  neutral: 4,\n}\n\nconst bannerVariants = cva('relative overflow-hidden backdrop-blur-xl border-y w-full', {\n  variants: {\n    variant: {\n      info: 'bg-info-background text-info-foreground border-info-separator',\n      success: 'bg-success-background text-success-foreground border-success-separator',\n      warning: 'bg-warning-background text-warning-foreground border-warning-separator',\n      error: 'bg-destructive-background text-destructive-foreground border-destructive-separator',\n      neutral: 'bg-muted/40 border-border',\n    },\n  },\n  defaultVariants: {\n    variant: 'info',\n  },\n})\n\ninterface BannerAction {\n  label: string\n  onClick: () => void\n}\n\ninterface BannerNotification {\n  id?: string\n  variant?: BannerVariant\n  title: string\n  description?: string\n  action?: BannerAction\n  icon?: React.ReactNode\n  onDismiss?: () => void\n  isDismissible?: boolean\n}\n\ninterface BannerContextValue {\n  notifications: BannerNotification[]\n  addBanner: (notification: BannerNotification) => string\n  removeBanner: (id: string) => void\n  clearBanners: () => void\n}\n\nconst BannerContext = createContext<BannerContextValue | null>(null)\n\nexport const useBanner = () => {\n  const context = useContext(BannerContext)\n  if (!context) {\n    throw new Error('useBanner must be used within a BannerProvider')\n  }\n  return context\n}\n\ninterface BannerProviderProps {\n  children: React.ReactNode\n  defaultNotifications?: BannerNotification[]\n}\n\nexport const BannerProvider = ({ children, defaultNotifications = [] }: BannerProviderProps) => {\n  const [notifications, setNotifications] = useState<BannerNotification[]>(defaultNotifications)\n\n  const addBanner = useCallback((notification: BannerNotification) => {\n    const id = notification.id || uuidv4()\n    setNotifications((prev) => {\n      const existingIndex = prev.findIndex((n) => n.id === id)\n      if (existingIndex >= 0) {\n        const updated = [...prev]\n        updated[existingIndex] = { ...notification, id }\n        return updated\n      }\n      return [{ ...notification, id }, ...prev]\n    })\n    return id\n  }, [])\n\n  const removeBanner = useCallback((id: string) => {\n    setNotifications((prev) => prev.filter((n) => n.id !== id))\n  }, [])\n\n  const clearBanners = useCallback(() => {\n    setNotifications([])\n  }, [])\n\n  const sortedNotifications = useMemo(() => {\n    return [...notifications].sort((a, b) => {\n      const variantA = (a.variant || 'info') as BannerVariant\n      const variantB = (b.variant || 'info') as BannerVariant\n      return priorityMap[variantA] - priorityMap[variantB]\n    })\n  }, [notifications])\n\n  const contextValue = useMemo(\n    () => ({\n      notifications: sortedNotifications,\n      addBanner,\n      removeBanner,\n      clearBanners,\n    }),\n    [sortedNotifications, addBanner, removeBanner, clearBanners],\n  )\n\n  return <BannerContext.Provider value={contextValue}>{children}</BannerContext.Provider>\n}\n\ninterface BannerProps extends VariantProps<typeof bannerVariants> {\n  title: string\n  description?: string\n  action?: BannerAction\n  onDismiss?: () => void\n  total?: number\n  currentIndex?: number\n  onNext?: () => void\n  className?: string\n  icon?: React.ReactNode\n  bannerClassName?: string\n}\n\nexport const Banner = ({\n  variant = 'info',\n  title,\n  description,\n  action,\n  onDismiss,\n  total = 0,\n  currentIndex = 0,\n  onNext,\n  className,\n  bannerClassName,\n  icon,\n  ...props\n}: BannerProps & React.ComponentProps<typeof motion.div>) => {\n  const IconComponent = variantIcons[variant ?? 'info']\n  const role = variant === 'error' || variant === 'warning' ? 'alert' : 'status'\n\n  return (\n    <motion.div layout className={cn('w-full relative z-30 origin-top', className)} {...props}>\n      <div className={cn(bannerVariants({ variant }))} role={role}>\n        <div\n          className={cn(\n            'grid grid-cols-[auto_1fr_auto_auto] grid-rows-[auto_auto] sm:grid-rows-1 items-center gap-x-2 px-4 sm:px-5 py-2 mx-auto justify-center',\n            bannerClassName,\n          )}\n        >\n          {icon || <IconComponent className=\"h-4 w-4 flex-shrink-0 text-current\" />}\n\n          <div className=\"flex items-center gap-3 overflow-hidden\">\n            <span className=\"text-sm font-semibold shrink-0\">{title}</span>\n            {description && (\n              <>\n                <span className=\"hidden md:flex opacity-20 border-l border-current h-6\" />\n                <span className=\"text-sm opacity-90 line-clamp-1 max-w-2xl\">{description}</span>\n              </>\n            )}\n          </div>\n\n          {action && (\n            <button\n              type=\"button\"\n              onClick={action.onClick}\n              className=\"text-sm font-medium underline-offset-4 underline row-[2] sm:row-[1] col-[2] sm:col-[3] justify-self-start\"\n            >\n              {action.label}\n            </button>\n          )}\n\n          {total > 1 && (\n            <div className=\"flex items-center gap-3\">\n              <span className=\"opacity-20 border-l border-current h-6 ml-1\" />\n              <div className=\"flex items-center gap-1\">\n                <span className=\"text-xs font-medium tabular-nums\">\n                  {currentIndex + 1}/{total}\n                </span>\n                <BannerButton onClick={() => onNext?.()} aria-label=\"Next Notification\">\n                  <ChevronRight className=\"w-4 h-4\" />\n                </BannerButton>\n              </div>\n            </div>\n          )}\n\n          <div className=\"flex items-center justify-center min-w-6 col-[-1] empty:hidden\">\n            {onDismiss && (\n              <BannerButton onClick={() => onDismiss()} aria-label=\"Dismiss\">\n                <XIcon className=\"w-4 h-4\" />\n              </BannerButton>\n            )}\n          </div>\n        </div>\n      </div>\n    </motion.div>\n  )\n}\n\nfunction BannerButton({ className, ...props }: React.ComponentProps<'button'>) {\n  return (\n    <button\n      type=\"button\"\n      className={cn(\n        'p-1 rounded transition-colors hover:bg-black/10 dark:hover:bg-white/10 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport const BannerStack = ({ className, bannerClassName }: { className?: string; bannerClassName?: string }) => {\n  const { notifications, removeBanner } = useBanner()\n  const [activeIndex, setActiveIndex] = useState(0)\n\n  useEffect(() => {\n    if (notifications.length > 0 && activeIndex >= notifications.length) {\n      setActiveIndex(Math.max(0, notifications.length - 1))\n    }\n  }, [notifications.length, activeIndex])\n\n  const activeItem = notifications.length > 0 ? notifications[activeIndex] : null\n\n  const handleNext = useCallback(\n    () => setActiveIndex((prev) => (prev + 1) % notifications.length),\n    [notifications.length],\n  )\n\n  const handleDismiss = useCallback(() => {\n    activeItem?.onDismiss?.()\n    if (activeItem?.id) {\n      removeBanner(activeItem.id)\n    }\n  }, [activeItem, removeBanner])\n\n  if (!activeItem) {\n    return null\n  }\n\n  return (\n    <motion.div\n      layout\n      className={cn('relative w-full overflow-hidden', className)}\n      initial={false}\n      animate={{ height: activeItem ? 'auto' : 0 }}\n      transition={{ duration: 0.2 }}\n    >\n      <AnimatePresence mode=\"popLayout\" initial={false}>\n        {activeItem && (\n          <Banner\n            bannerClassName={bannerClassName}\n            key={activeItem.id}\n            {...activeItem}\n            total={notifications.length}\n            currentIndex={activeIndex}\n            onNext={handleNext}\n            onDismiss={activeItem?.onDismiss ? handleDismiss : undefined}\n            initial={{ opacity: 0, y: -20, filter: 'blur(2px)' }}\n            animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}\n            exit={{ opacity: 0, y: 20, filter: 'blur(2px)' }}\n            transition={{\n              duration: 0.2,\n            }}\n          />\n        )}\n      </AnimatePresence>\n    </motion.div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/CodeBlock.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useTheme } from '@/contexts/ThemeContext'\nimport { cn } from '@/lib/utils'\nimport { Highlight, themes, type PrismTheme, type Token } from 'prism-react-renderer'\nimport { CopyButton } from './CopyButton'\n\ninterface CodeBlockProps {\n  code: string\n  language: string\n  showCopy?: boolean\n  codeAreaClassName?: string\n  className?: string\n}\n\ninterface HighlightProps {\n  style: React.CSSProperties\n  tokens: Token[][]\n  getLineProps: (props: { line: Token[]; key: number }) => React.HTMLAttributes<HTMLDivElement>\n  getTokenProps: (props: { token: Token; key: number }) => React.HTMLAttributes<HTMLSpanElement>\n}\n\nconst oneDark = {\n  ...themes.oneDark,\n  plain: {\n    ...themes.oneDark.plain,\n    background: 'hsl(var(--code-background))',\n  },\n}\n\nconst CodeBlock: React.FC<CodeBlockProps> = ({ code, language, showCopy = true, codeAreaClassName, className }) => {\n  const { theme } = useTheme()\n\n  return (\n    <div className={cn('relative rounded-lg', className)}>\n      <Highlight\n        theme={(theme === 'dark' ? oneDark : themes.oneLight) as PrismTheme}\n        code={code.trim()}\n        language={language}\n      >\n        {({ style, tokens, getLineProps, getTokenProps }: HighlightProps) => (\n          <pre className={cn('p-4 rounded-lg overflow-x-auto', codeAreaClassName)} style={style}>\n            {tokens.map((line, i) => {\n              const props = getLineProps({ line, key: i })\n              // @ts-expect-error Workaround for the render error. Key should not be spread into JSX\n              const { key, ...rest } = props\n              return (\n                <div key={i} {...rest}>\n                  {line.map((token, key) => {\n                    const tokenProps = getTokenProps({ token, key })\n                    // @ts-expect-error Workaround for the render error. Key should not be spread into JSX\n                    const { key: tokenKey, ...restTokenProps } = tokenProps\n                    return <span key={tokenKey} {...restTokenProps} />\n                  })}\n                </div>\n              )\n            })}\n          </pre>\n        )}\n      </Highlight>\n      {showCopy && (\n        <CopyButton\n          value={code.trim()}\n          variant=\"ghost\"\n          className=\"absolute text-muted-foreground right-2 top-2.5 p-2\"\n        />\n      )}\n    </div>\n  )\n}\n\nexport default CodeBlock\n"
  },
  {
    "path": "apps/dashboard/src/components/CommandPalette.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport { useDeepCompareMemo } from '@/hooks/useDeepCompareMemo'\nimport { cn, pluralize } from '@/lib/utils'\nimport { useCommandState } from 'cmdk'\nimport { AlertCircle, ChevronRight, Loader2 } from 'lucide-react'\nimport { AnimatePresence, motion, useAnimate } from 'motion/react'\nimport React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { createStore, useStore, type StoreApi } from 'zustand'\nimport {\n  Command,\n  CommandDialog,\n  CommandEmpty as CommandEmptyPrimitive,\n  CommandGroup as CommandGroupPrimitive,\n  CommandInput,\n  CommandItem as CommandItemPrimitive,\n  CommandList,\n} from './ui/command'\nimport { DialogDescription, DialogOverlay, DialogTitle } from './ui/dialog'\nimport { Kbd } from './ui/kbd'\nimport { Skeleton } from './ui/skeleton'\n\nexport type CommandConfig = {\n  id: string\n  label: ReactNode\n  icon?: ReactNode\n  loading?: boolean\n  page?: string\n  keywords?: string[]\n  onSelect?: () => void\n  disabled?: boolean\n  chainable?: boolean\n  value?: string\n  className?: string\n}\n\nexport type RegisterCommandsOptions = {\n  pageId?: string\n  groupId?: string\n  groupLabel?: string\n  groupOrder?: number\n}\n\nexport type PageConfig = {\n  id: string\n  label?: string\n  placeholder?: string\n}\n\ntype CommandGroup = {\n  id: string\n  label?: string\n  order: number\n  commands: Map<string, CommandConfig>\n}\n\ntype PageData = {\n  meta: PageConfig\n  groups: Map<string, CommandGroup>\n}\n\ntype CommandPaletteState = {\n  isOpen: boolean\n  activePageId: string\n  pageStack: string[]\n  searchByPage: Map<string, string>\n  shouldFilter: boolean\n  isLoading: boolean\n  pages: Map<string, PageData>\n}\n\ntype CommandPaletteActions = {\n  setIsOpen: (open: boolean) => void\n  setSearch: (value: string) => void\n  setShouldFilter: (value: boolean) => void\n  setIsLoading: (value: boolean) => void\n  pushPage: (pageId: string) => void\n  popPage: () => void\n  goToPage: (pageId: string) => void\n  popToRoot: () => void\n  registerPage: (config: PageConfig) => void\n  registerCommands: (commands: CommandConfig[], options?: RegisterCommandsOptions) => () => void\n  unregisterCommands: (commandIds: string[], options?: { pageId?: string; groupId?: string }) => void\n}\n\ntype CommandPaletteStore = CommandPaletteState & { actions: CommandPaletteActions }\n\nconst createCommandPaletteStore = (defaultPage = 'root') => {\n  return createStore<CommandPaletteStore>((set, get) => ({\n    isOpen: false,\n    activePageId: defaultPage,\n    pageStack: [defaultPage],\n    searchByPage: new Map(),\n    shouldFilter: true,\n    isLoading: false,\n    pages: new Map([\n      [\n        defaultPage,\n        {\n          meta: { id: defaultPage, label: 'Home', placeholder: 'Type a command or search...' },\n          groups: new Map(),\n        },\n      ],\n    ]),\n\n    actions: {\n      setIsOpen: (isOpen) => set({ isOpen }),\n      setSearch: (value) =>\n        set((state) => {\n          const newSearchByPage = new Map(state.searchByPage)\n          newSearchByPage.set(state.activePageId, value)\n\n          return { searchByPage: newSearchByPage }\n        }),\n      setShouldFilter: (value) => set({ shouldFilter: value }),\n      setIsLoading: (value) => set({ isLoading: value }),\n\n      pushPage: (pageId) =>\n        set((state) => {\n          if (!state.pages.has(pageId)) {\n            return state\n          }\n\n          return {\n            pageStack: [...state.pageStack, pageId],\n            activePageId: pageId,\n          }\n        }),\n\n      popPage: () =>\n        set((state) => {\n          if (state.pageStack.length <= 1) return state\n          const newStack = state.pageStack.slice(0, -1)\n\n          return {\n            pageStack: newStack,\n            activePageId: newStack[newStack.length - 1],\n          }\n        }),\n\n      goToPage: (pageId) =>\n        set((state) => {\n          const pageIndex = state.pageStack.indexOf(pageId)\n          if (pageIndex !== -1) {\n            return {\n              pageStack: state.pageStack.slice(0, pageIndex + 1),\n              activePageId: pageId,\n            }\n          }\n\n          return state\n        }),\n\n      popToRoot: () =>\n        set({\n          pageStack: [defaultPage],\n          activePageId: defaultPage,\n          searchByPage: new Map(),\n        }),\n\n      registerPage: (config) =>\n        set((state) => {\n          const newPages = new Map(state.pages)\n          const existing = newPages.get(config.id)\n\n          newPages.set(config.id, {\n            meta: { ...existing?.meta, ...config },\n            groups: existing?.groups ?? new Map(),\n          })\n\n          return { pages: newPages }\n        }),\n\n      registerCommands: (commands, options = {}) => {\n        const { pageId = defaultPage, groupId = 'default', groupLabel, groupOrder = 100 } = options\n\n        set((state) => {\n          const page = state.pages.get(pageId)\n          if (!page) {\n            return state\n          }\n\n          const newGroups = new Map(page.groups)\n          const existingGroup = newGroups.get(groupId)\n\n          const newCommands = new Map(existingGroup?.commands ?? new Map())\n\n          for (const cmd of commands) {\n            newCommands.set(cmd.id, cmd)\n          }\n\n          newGroups.set(groupId, {\n            id: groupId,\n            label: groupLabel ?? existingGroup?.label,\n            order: groupOrder ?? existingGroup?.order ?? 0,\n            commands: newCommands,\n          })\n\n          const newPages = new Map(state.pages)\n\n          newPages.set(pageId, { ...page, groups: newGroups })\n\n          return { pages: newPages }\n        })\n\n        const commandIds = commands.map((c) => c.id)\n        return () => get().actions.unregisterCommands(commandIds, { pageId, groupId })\n      },\n\n      unregisterCommands: (commandIds, options = {}) => {\n        const { pageId = defaultPage, groupId = 'default' } = options\n\n        set((state) => {\n          const page = state.pages.get(pageId)\n          if (!page) {\n            return state\n          }\n\n          const group = page.groups.get(groupId)\n          if (!group) {\n            return state\n          }\n\n          const newCommands = new Map(group.commands)\n          for (const id of commandIds) {\n            newCommands.delete(id)\n          }\n\n          const newPages = new Map(state.pages)\n          const newGroups = new Map(page.groups)\n\n          if (newCommands.size === 0) {\n            newGroups.delete(groupId)\n          } else {\n            newGroups.set(groupId, { ...group, commands: newCommands })\n          }\n\n          newPages.set(pageId, { ...page, groups: newGroups })\n\n          return { pages: newPages }\n        })\n      },\n    },\n  }))\n}\n\nconst CommandPaletteContext = createContext<StoreApi<CommandPaletteStore> | null>(null)\n\nexport function useCommandPalette<T = CommandPaletteStore>(\n  selector: (state: CommandPaletteStore) => T = (state) => state as T,\n): T {\n  const store = useContext(CommandPaletteContext)\n  if (!store) {\n    throw new Error('useCommandPalette must be used within <CommandPaletteProvider />')\n  }\n  return useStore(store, selector)\n}\n\nexport function useCommandPaletteActions() {\n  const store = useContext(CommandPaletteContext)\n  if (!store) {\n    throw new Error('useCommandPaletteActions must be used within <CommandPaletteProvider />')\n  }\n\n  return useStore(store, (state) => state.actions)\n}\n\nexport type CommandPaletteProviderProps = {\n  children: ReactNode\n  defaultPage?: string\n  enableGlobalShortcut?: boolean\n}\n\nexport function CommandPaletteProvider({\n  children,\n  defaultPage = 'root',\n  enableGlobalShortcut = true,\n}: CommandPaletteProviderProps) {\n  const storeRef = useRef<StoreApi<CommandPaletteStore> | null>(null)\n\n  if (!storeRef.current) {\n    storeRef.current = createCommandPaletteStore(defaultPage)\n  }\n\n  useEffect(() => {\n    if (!enableGlobalShortcut) return\n\n    const handleKeyDown = (e: KeyboardEvent) => {\n      if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {\n        e.preventDefault()\n        const state = storeRef.current?.getState()\n        state?.actions.setIsOpen(!state.isOpen)\n      }\n    }\n\n    document.addEventListener('keydown', handleKeyDown)\n    return () => document.removeEventListener('keydown', handleKeyDown)\n  }, [enableGlobalShortcut])\n\n  return <CommandPaletteContext.Provider value={storeRef.current}>{children}</CommandPaletteContext.Provider>\n}\n\nexport function useRegisterCommands(commands: CommandConfig[], options?: RegisterCommandsOptions) {\n  const { registerCommands } = useCommandPaletteActions()\n\n  const optionsMemo = useDeepCompareMemo(options)\n\n  useEffect(() => {\n    const unregister = registerCommands(commands, optionsMemo)\n    return () => unregister()\n  }, [commands, optionsMemo, registerCommands])\n}\n\nexport function useRegisterPage(config: PageConfig) {\n  const { registerPage } = useCommandPaletteActions()\n\n  const configMemo = useDeepCompareMemo(config)\n\n  useEffect(() => {\n    registerPage(configMemo)\n  }, [configMemo, registerPage])\n}\n\nexport type CommandPaletteProps = {\n  className?: string\n  overlay?: ReactNode\n}\n\nexport function CommandPalette({ className, overlay }: CommandPaletteProps) {\n  const pages = useCommandPalette((state) => state.pages)\n  const activePageId = useCommandPalette((state) => state.activePageId)\n  const isOpen = useCommandPalette((state) => state.isOpen)\n  const search = useCommandPalette((state) => state.searchByPage.get(state.activePageId) ?? '')\n  const shouldFilter = useCommandPalette((state) => state.shouldFilter)\n  const isLoading = useCommandPalette((state) => state.isLoading)\n  const pageStack = useCommandPalette((state) => state.pageStack)\n\n  const { setIsOpen, setSearch, popPage, popToRoot } = useCommandPaletteActions()\n\n  const activePage = pages.get(activePageId)\n  const inputRef = useRef<HTMLInputElement>(null)\n\n  const [scope, animate] = useAnimate()\n\n  useEffect(() => {\n    if (isOpen) {\n      popToRoot()\n      requestAnimationFrame(() => inputRef.current?.focus())\n    }\n  }, [isOpen, popToRoot])\n\n  useEffect(() => {\n    if (isOpen && scope.current) {\n      animate(scope.current, { scale: [0.975, 1] }, { duration: 0.3 })\n    }\n  }, [activePageId, isOpen, animate, scope])\n\n  const sortedGroups = useMemo(() => {\n    if (!activePage) {\n      return []\n    }\n    return Array.from(activePage.groups.values()).sort((a, b) => a.order - b.order)\n  }, [activePage])\n\n  return (\n    <CommandDialog\n      open={isOpen}\n      onOpenChange={setIsOpen}\n      className={cn(\n        'sm:max-w-xl w-full top-[calc(50%-250px)] translate-y-0 data-[state=closed]:!slide-out-to-top-4 data-[state=open]:!slide-in-from-top-4',\n        'bg-transparent border-none shadow-none p-0 overflow-visible',\n        className,\n      )}\n      overlay={overlay ?? <DialogOverlay className=\"bg-black/80\" />}\n    >\n      <motion.div\n        ref={scope}\n        className=\"flex flex-col w-full h-full border border-border/50 dark:bg-popover/70 bg-popover backdrop-blur rounded-xl overflow-hidden shadow-2xl transform-gpu\"\n      >\n        <Command\n          shouldFilter={shouldFilter}\n          loop\n          className=\"bg-transparent [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\"\n        >\n          <DialogTitle className=\"sr-only\">Command Palette</DialogTitle>\n          <DialogDescription className=\"sr-only\">\n            Use the command palette to navigate the application.\n          </DialogDescription>\n\n          <Breadcrumbs />\n\n          <CommandInput\n            value={search}\n            onValueChange={setSearch}\n            placeholder={activePage?.meta.placeholder ?? 'Type a command or search...'}\n            ref={inputRef}\n            onKeyDown={(e) => {\n              if (e.key === 'Backspace' && !search && pageStack.length > 1) {\n                e.preventDefault()\n                popPage()\n              }\n            }}\n          />\n\n          <PulseBar mode={isLoading ? 'pulse' : 'flash'} isVisible={isOpen} />\n\n          <CommandList\n            className={cn(\n              'max-h-[400px] scroll-mask transition-[height,opacity] duration-150 ease-in-out h-[var(--cmdk-list-height)]',\n              {\n                'opacity-50': isLoading,\n              },\n            )}\n          >\n            {sortedGroups.map((group) => (\n              <CommandGroupRenderer key={group.id} group={group} />\n            ))}\n            <CommandEmpty search={search} />\n          </CommandList>\n\n          <CommandFooter hideResultsCount={!shouldFilter} className=\"mt-1\">\n            {pageStack.length > 1 ? (\n              <button\n                onClick={popPage}\n                className=\"hover:text-foreground mr-2 flex items-center gap-1 transition-colors\"\n              >\n                <Kbd>Backspace</Kbd> to go back\n              </button>\n            ) : (\n              <span>\n                Use <Kbd>↑</Kbd> <Kbd>↓</Kbd> to navigate\n              </span>\n            )}\n          </CommandFooter>\n        </Command>\n      </motion.div>\n    </CommandDialog>\n  )\n}\n\nfunction Breadcrumbs() {\n  const { pageStack, pages } = useCommandPalette()\n  const { goToPage } = useCommandPaletteActions()\n\n  return (\n    <div className=\"flex items-center gap-1 border-b-[0.5px] px-3 py-2 text-xs text-muted-foreground dark:bg-muted/20 bg-muted\">\n      {pageStack.map((id, i) => {\n        const isLast = i === pageStack.length - 1\n        const page = pages.get(id)\n\n        return (\n          <React.Fragment key={id}>\n            {i > 0 && (\n              <span className=\"opacity-50\" aria-hidden=\"true\">\n                /\n              </span>\n            )}\n            <button\n              className={cn(isLast && 'font-medium', 'hover:text-foreground transition-colors')}\n              onClick={() => goToPage(id)}\n            >\n              {page?.meta.label ?? id}\n            </button>\n          </React.Fragment>\n        )\n      })}\n    </div>\n  )\n}\n\nfunction CommandGroupRenderer({ group }: { group: CommandGroup }) {\n  const sortedCommands = useMemo(() => Array.from(group.commands.values()), [group.commands])\n\n  if (sortedCommands.length === 0) return null\n\n  return (\n    <CommandGroupPrimitive heading={group.label} className=\"px-2\">\n      {sortedCommands.map((cmd) => (\n        <CommandItem key={cmd.id} config={cmd} />\n      ))}\n    </CommandGroupPrimitive>\n  )\n}\n\nfunction CommandItem({ config }: { config: CommandConfig }) {\n  const { pushPage, setIsOpen } = useCommandPaletteActions()\n\n  const handleSelect = useCallback(() => {\n    if (config.page) {\n      pushPage(config.page)\n    } else {\n      config.onSelect?.()\n      if (!config.chainable) {\n        setIsOpen(false)\n      }\n    }\n  }, [config, pushPage, setIsOpen])\n\n  const value = config.value ?? (typeof config.label === 'string' ? config.label : config.id)\n\n  return (\n    <CommandItemPrimitive\n      value={value}\n      onSelect={handleSelect}\n      disabled={config.disabled || config.loading}\n      keywords={config.keywords}\n      className={cn(\n        'dark:data-[selected=true]:bg-accent/80 data-[selected=true]:bg-accent py-3 px-2 text-foreground ',\n        config.className,\n      )}\n    >\n      <div className=\"flex items-center gap-2 flex-1 line-clamp-1\">\n        {config.loading ? (\n          <Loader2 className=\"h-4 w-4 animate-spin text-muted-foreground\" />\n        ) : (\n          config.icon && <span className=\"text-muted-foreground\">{config.icon}</span>\n        )}\n        <span className=\"overflow-hidden\">{config.label}</span>\n      </div>\n\n      {config.page && <ChevronRight className=\"ml-2 h-4 w-4 text-muted-foreground/50\" />}\n    </CommandItemPrimitive>\n  )\n}\n\nfunction CommandFooter({\n  children,\n  hideResultsCount = false,\n  className,\n}: {\n  children: ReactNode\n  hideResultsCount?: boolean\n  className?: string\n}) {\n  const resultsCount = useCommandState((state) => state.filtered.count)\n\n  return (\n    <div\n      className={cn(\n        'border-t-[0.5px] p-2 text-xs text-muted-foreground dark:bg-muted/20 bg-muted flex justify-between',\n        className,\n      )}\n    >\n      {children}\n      {!hideResultsCount && <span className=\"ml-auto\">{pluralize(resultsCount, 'result', 'results')}</span>}\n    </div>\n  )\n}\n\nfunction CommandEmpty({ search }: { search: string }) {\n  return (\n    <CommandEmptyPrimitive className=\"text-muted-foreground py-6 text-center text-sm\">\n      No results found for <span className=\"text-foreground\">\"{search}\"</span>.\n    </CommandEmptyPrimitive>\n  )\n}\n\nfunction PulseBar({ mode, isVisible, className }: { mode: 'flash' | 'pulse'; isVisible: boolean; className?: string }) {\n  const gradientBackground = `linear-gradient(90deg, transparent, #66F0C2, #00C241, #66F0C2, transparent)`\n\n  if (!isVisible) return null\n\n  return (\n    <div\n      className={cn(\n        'relative flex items-center justify-center overflow-hidden w-full h-[0.5px] transform-gpu',\n        className,\n      )}\n    >\n      <AnimatePresence>\n        {mode === 'flash' && (\n          <motion.div\n            key=\"flash-mode\"\n            className=\"absolute left-1/2 top-0 bottom-0 w-1/2\"\n            style={{ background: gradientBackground }}\n            initial={{ x: '-50%', width: 100, opacity: 0 }}\n            animate={{ width: '200%', opacity: [1, 1, 1, 0] }}\n            transition={{ duration: 0.3, delay: 0.1 }}\n          />\n        )}\n\n        {mode === 'pulse' && (\n          <motion.div\n            key=\"pulse-mode\"\n            className=\"absolute left-0 top-0 bottom-0 w-full\"\n            style={{ background: gradientBackground }}\n            initial={{ opacity: 0 }}\n            animate={{ opacity: [0, 1, 0] }}\n            transition={{ duration: 0.75, repeat: Infinity }}\n          />\n        )}\n      </AnimatePresence>\n    </div>\n  )\n}\n\nexport function CommandHighlight({\n  children,\n  className,\n  ...props\n}: { children: ReactNode } & React.HTMLAttributes<HTMLSpanElement>) {\n  return (\n    <Kbd className={cn('text-sm', className)} {...props}>\n      {children}\n    </Kbd>\n  )\n}\n\nexport function CommandError({\n  message = 'Something went wrong',\n  onRetry,\n  className,\n}: {\n  message?: string\n  onRetry?: () => void\n  className?: string\n}) {\n  return (\n    <div className={cn('flex flex-col items-center justify-center py-6 px-4 text-center', className)}>\n      <AlertCircle className=\"h-6 w-6 text-destructive mb-2\" />\n      <p className=\"text-sm text-muted-foreground\">{message}</p>\n      {onRetry && (\n        <button\n          onClick={onRetry}\n          className=\"mt-2 text-sm text-primary hover:underline focus:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded\"\n        >\n          Try again\n        </button>\n      )}\n    </div>\n  )\n}\n\nexport function CommandLoading({ count = 3, className }: { count?: number; className?: string }) {\n  return (\n    <div className={cn('p-1', className)}>\n      {Array.from({ length: count }).map((_, i) => (\n        <div key={i} className=\"flex items-center gap-2 px-2 py-3\">\n          <Skeleton className=\"h-4 w-4 rounded\" />\n          <Skeleton className=\"h-4 flex-1 max-w-[180px] rounded\" />\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport { Kbd, KbdGroup } from './ui/kbd'\n"
  },
  {
    "path": "apps/dashboard/src/components/ComparisonTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { ChevronDown, ChevronRight } from 'lucide-react'\nimport { FC, Fragment, ReactNode, useState } from 'react'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './ui/table'\n\ninterface ComparisonRow {\n  label: ReactNode\n  values: ReactNode[]\n}\n\nexport interface ComparisonSection {\n  id?: string\n  title: ReactNode\n  collapsed?: boolean\n  collapsible?: boolean\n  rows: ComparisonRow[]\n}\n\ninterface Props {\n  columns: string[]\n  headerLabel?: string\n  currentColumn?: number\n  currentRow?: number\n  data: ComparisonSection[]\n  className?: string\n}\n\nexport function ComparisonTable({ columns = [], headerLabel, currentColumn, currentRow, data = [], className }: Props) {\n  return (\n    <div\n      className={cn(\n        'w-full rounded-lg border border-border bg-card overflow-x-auto scrollbar-thin scrollbar-thumb-border scrollbar-track-background',\n        className,\n      )}\n    >\n      <Table>\n        <TableHeader>\n          <TableRow className=\"border-b border-border\">\n            <TableHead className=\"py-2 px-4 text-muted-foreground border-r border-border sticky left-0 bg-background z-10\">\n              {headerLabel}\n            </TableHead>\n            {columns.map((column, index) => (\n              <TableHead\n                key={index}\n                className={cn(\n                  'py-2 px-4 text-xs text-nowrap',\n                  index === currentColumn ? 'text-foreground bg-muted/50' : 'text-muted-foreground',\n                )}\n              >\n                {column}\n              </TableHead>\n            ))}\n          </TableRow>\n        </TableHeader>\n        <TableBody className=\"[&_tr]:h-auto\">\n          {data.map((section, idx) => (\n            <CollapsibleSection\n              key={section.id || idx}\n              section={section}\n              currentColumn={currentColumn}\n              currentRow={currentRow}\n            />\n          ))}\n        </TableBody>\n      </Table>\n    </div>\n  )\n}\n\ninterface CollapsibleSectionProps {\n  section: ComparisonSection\n  currentColumn?: number\n  currentRow?: number\n}\n\nconst CollapsibleSection: FC<CollapsibleSectionProps> = ({ section, currentColumn, currentRow }) => {\n  const [isOpen, setIsOpen] = useState(section.collapsible ? !section.collapsed : true)\n\n  return (\n    <Fragment>\n      {section.collapsible && (\n        <TableRow\n          onClick={() => setIsOpen(!isOpen)}\n          className={cn('cursor-pointer border-b border-border group select-none hover:bg-muted')}\n          aria-expanded={isOpen}\n        >\n          <TableCell colSpan={10} className=\"py-2 px-4 bg-muted\">\n            <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n              {isOpen ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n              {section.title}\n            </div>\n          </TableCell>\n        </TableRow>\n      )}\n\n      {isOpen &&\n        section.rows.map((row, rowIdx) => (\n          <TableRow\n            key={rowIdx}\n            className={cn('border-b border-border group hover:bg-muted transition-none', {\n              'bg-muted': currentRow === rowIdx,\n            })}\n          >\n            <TableCell\n              className={cn(\n                'py-2 px-4 text-muted-foreground text-xs border-r border-border align-top w-40 sticky left-0 bg-background z-10 group-hover:bg-muted',\n                {\n                  'bg-muted': currentRow === rowIdx,\n                },\n              )}\n            >\n              {row.label}\n            </TableCell>\n\n            {row.values.map((val, colIdx) => {\n              const isActive = colIdx === currentColumn\n\n              return (\n                <TableCell\n                  key={colIdx}\n                  className={cn(\n                    'py-2 px-4 text-xs align-top text-right tabular-nums',\n                    isActive ? 'bg-muted text-foreground' : 'text-muted-foreground',\n                  )}\n                >\n                  {val}\n                </TableCell>\n              )\n            })}\n          </TableRow>\n        ))}\n    </Fragment>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/CopyButton.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useCopyToClipboard } from '@/hooks/useCopyToClipboard'\nimport { cn } from '@/lib/utils'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { CheckIcon, CopyIcon } from 'lucide-react'\nimport { ComponentProps } from 'react'\nimport TooltipButton from './TooltipButton'\n\nconst MotionCopyIcon = motion(CopyIcon)\nconst MotionCheckIcon = motion(CheckIcon)\n\nconst iconProps = {\n  initial: { opacity: 0, y: 5 },\n  animate: { opacity: 1, y: 0 },\n  exit: { opacity: 0, y: -5 },\n  transition: { duration: 0.1 },\n}\n\nfunction CopyButton({\n  value,\n  className,\n  tooltipText,\n  variant = 'ghost',\n  autoHide,\n  onClick,\n  ...props\n}: { value: string; tooltipText?: string; autoHide?: boolean } & Omit<\n  ComponentProps<typeof TooltipButton>,\n  'tooltipText'\n>) {\n  const [copied, copy] = useCopyToClipboard()\n\n  return (\n    <TooltipButton\n      tooltipText={tooltipText || (copied ? 'Copied' : 'Copy')}\n      onClick={(e) => {\n        copy(value)\n        onClick?.(e)\n        e.stopPropagation()\n      }}\n      className={cn(\n        'font-sans text-muted-foreground hover:text-foreground',\n        {\n          'opacity-0 -translate-x-1': autoHide && !copied,\n          'group-hover/copy-button:opacity-100 group-hover/copy-button:translate-x-0 group-focus-within/copy-button:opacity-100 group-focus-within/copy-button:translate-x-0':\n            autoHide,\n          'opacity-100 translate-x-0': autoHide && copied,\n        },\n        className,\n      )}\n      variant={variant}\n      {...props}\n    >\n      <AnimatePresence initial={false} mode=\"wait\">\n        {copied ? (\n          <MotionCheckIcon\n            className={cn('size-4 text-success', { 'size-3.5': props.size === 'icon-xs' })}\n            key=\"copied\"\n            {...iconProps}\n          />\n        ) : (\n          <MotionCopyIcon className={cn('size-4', { 'size-3': props.size === 'icon-xs' })} key=\"copy\" {...iconProps} />\n        )}\n      </AnimatePresence>\n    </TooltipButton>\n  )\n}\n\nexport { CopyButton }\n"
  },
  {
    "path": "apps/dashboard/src/components/CreateApiKeyDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { DatePicker } from '@/components/ui/date-picker'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { Spinner } from '@/components/ui/spinner'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { CheckIcon, CopyIcon, EyeIcon, EyeOffIcon, InfoIcon } from 'lucide-react'\n\nimport { Field, FieldDescription, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field'\nimport { Input } from '@/components/ui/input'\nimport { InputGroup, InputGroupButton, InputGroupInput } from '@/components/ui/input-group'\nimport { Label } from '@/components/ui/label'\nimport { CREATE_API_KEY_PERMISSIONS_GROUPS } from '@/constants/CreateApiKeyPermissionsGroups'\nimport { useCreateApiKeyMutation } from '@/hooks/mutations/useCreateApiKeyMutation'\nimport { useCopyToClipboard } from '@/hooks/useCopyToClipboard'\nimport { handleApiError } from '@/lib/error-handling'\nimport { getMaskedToken } from '@/lib/utils'\nimport { ApiKeyResponse, CreateApiKeyPermissionsEnum } from '@daytonaio/api-client'\nimport { useForm } from '@tanstack/react-form'\nimport { Plus } from 'lucide-react'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { toast } from 'sonner'\nimport { z } from 'zod'\nimport { Alert, AlertDescription, AlertTitle } from './ui/alert'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs'\nimport { ToggleGroup, ToggleGroupItem } from './ui/toggle-group'\n\ninterface CreateApiKeyDialogProps {\n  availablePermissions: CreateApiKeyPermissionsEnum[]\n  apiUrl: string\n  className?: string\n  organizationId?: string\n}\n\nconst isReadPermission = (permission: CreateApiKeyPermissionsEnum) => permission.startsWith('read:')\nconst isWritePermission = (permission: CreateApiKeyPermissionsEnum) => permission.startsWith('write:')\nconst isDeletePermission = (permission: CreateApiKeyPermissionsEnum) => permission.startsWith('delete:')\n\nconst IMPLICIT_READ_RESOURCES = ['Sandboxes', 'Snapshots', 'Registries', 'Regions']\n\nconst formSchema = z.object({\n  name: z.string().min(1, 'Name is required'),\n  expiresAt: z.date().optional(),\n  permissions: z.array(z.enum(CreateApiKeyPermissionsEnum)),\n})\n\ntype FormValues = z.infer<typeof formSchema>\n\nexport const CreateApiKeyDialog: React.FC<CreateApiKeyDialogProps> = ({\n  availablePermissions,\n  apiUrl,\n  className,\n  organizationId,\n}) => {\n  const [open, setOpen] = useState(false)\n\n  const { reset: resetCreateApiKeyMutation, ...createApiKeyMutation } = useCreateApiKeyMutation()\n\n  const availableGroups = useMemo(() => {\n    return CREATE_API_KEY_PERMISSIONS_GROUPS.map((group) => ({\n      ...group,\n      permissions: group.permissions.filter((p) => availablePermissions.includes(p)),\n    })).filter((group) => group.permissions.length > 0)\n  }, [availablePermissions])\n\n  const form = useForm({\n    defaultValues: {\n      name: '',\n      expiresAt: undefined,\n      permissions: availablePermissions,\n    } as FormValues,\n    validators: {\n      onSubmit: formSchema,\n    },\n    onSubmit: async ({ value }) => {\n      if (!organizationId) {\n        toast.error('Select an organization to create an API key.')\n        return\n      }\n\n      try {\n        await createApiKeyMutation.mutateAsync({\n          organizationId,\n          name: value.name.trim(),\n          permissions: value.permissions,\n          expiresAt: value.expiresAt ?? null,\n        })\n\n        toast.success('API key created successfully')\n      } catch (error) {\n        handleApiError(error, 'Failed to create API key')\n      }\n    },\n  })\n\n  const resetState = useCallback(() => {\n    form.reset({\n      name: '',\n      expiresAt: undefined,\n      permissions: availablePermissions,\n    })\n    resetCreateApiKeyMutation()\n  }, [resetCreateApiKeyMutation, form, availablePermissions])\n\n  useEffect(() => {\n    if (open) {\n      resetState()\n    }\n  }, [open, resetState])\n\n  const createdKey = createApiKeyMutation.data\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        setOpen(isOpen)\n      }}\n    >\n      <DialogTrigger asChild>\n        <Button variant=\"default\" size=\"sm\" title=\"Create Key\" className={className}>\n          <Plus className=\"w-4 h-4\" />\n          Create Key\n        </Button>\n      </DialogTrigger>\n\n      <DialogContent className=\"max-w-lg\">\n        <DialogHeader>\n          <DialogTitle>{createdKey ? 'API Key Created' : 'Create New API Key'}</DialogTitle>\n          <DialogDescription>\n            {createdKey\n              ? 'Your API key has been created successfully.'\n              : 'Choose which actions this API key will be authorized to perform.'}\n          </DialogDescription>\n        </DialogHeader>\n        {createdKey ? (\n          <CreatedKeyDisplay createdKey={createdKey} apiUrl={apiUrl} key={createdKey.value} />\n        ) : (\n          <div className=\"overflow-y-auto px-1\">\n            <form\n              id=\"create-api-key-form\"\n              className=\"space-y-6\"\n              onSubmit={(e) => {\n                e.preventDefault()\n                e.stopPropagation()\n                form.handleSubmit()\n              }}\n            >\n              <form.Field name=\"name\">\n                {(field) => {\n                  const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                  return (\n                    <Field data-invalid={isInvalid}>\n                      <FieldLabel htmlFor={field.name}>Key Name</FieldLabel>\n                      <Input\n                        aria-invalid={isInvalid}\n                        id={field.name}\n                        name={field.name}\n                        value={field.state.value}\n                        onBlur={field.handleBlur}\n                        onChange={(e) => field.handleChange(e.target.value)}\n                        placeholder=\"Name\"\n                      />\n                      {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                        <FieldError errors={field.state.meta.errors} />\n                      )}\n                    </Field>\n                  )\n                }}\n              </form.Field>\n\n              <form.Field name=\"expiresAt\">\n                {(field) => (\n                  <Field>\n                    <FieldLabel htmlFor={field.name}>Expires</FieldLabel>\n                    <DatePicker\n                      id={field.name}\n                      value={field.state.value}\n                      onChange={field.handleChange}\n                      disabledBefore={new Date()}\n                    />\n                    <FieldDescription>Optional expiration date for the API key.</FieldDescription>\n                  </Field>\n                )}\n              </form.Field>\n\n              <Tabs\n                defaultValue=\"full-access\"\n                className=\"items-start pb-4\"\n                onValueChange={(value) => {\n                  if (value === 'full-access') {\n                    form.setFieldValue('permissions', availablePermissions)\n                  } else if (value === 'sandbox-access') {\n                    form.setFieldValue('permissions', [\n                      CreateApiKeyPermissionsEnum.WRITE_SANDBOXES,\n                      CreateApiKeyPermissionsEnum.DELETE_SANDBOXES,\n                    ])\n                  } else {\n                    form.setFieldValue('permissions', [])\n                  }\n                }}\n              >\n                <Label className=\"mb-1\">Permissions</Label>\n\n                <TabsList className=\"bg-muted w-full [&>*]:flex-1\">\n                  <TabsTrigger value=\"full-access\">Full Access</TabsTrigger>\n                  <TabsTrigger value=\"sandbox-access\">Sandboxes</TabsTrigger>\n                  <TabsTrigger value=\"restricted-access\">Restricted </TabsTrigger>\n                </TabsList>\n                <TabsContent value=\"sandbox-access\" className=\"w-full\">\n                  <Alert variant=\"info\">\n                    <InfoIcon />\n                    <AlertTitle>Sandboxes Access</AlertTitle>\n                    <AlertDescription>\n                      This key grants read and write access to the Sandboxes resource.\n                    </AlertDescription>\n                  </Alert>\n                </TabsContent>\n                <TabsContent value=\"full-access\" className=\"w-full\">\n                  <Alert variant=\"info\">\n                    <InfoIcon />\n                    <AlertTitle>Full Access</AlertTitle>\n                    <AlertDescription>\n                      This key grants full access to all resources. For better security, we recommend creating a\n                      restricted key.\n                    </AlertDescription>\n                  </Alert>\n                </TabsContent>\n                <TabsContent value=\"restricted-access\" className=\"w-full\">\n                  {availableGroups.length > 0 && (\n                    <form.Field name=\"permissions\">\n                      {(field) => (\n                        <Field data-invalid={field.state.meta.isTouched && !field.state.meta.isValid}>\n                          <FieldGroup className=\"gap-4 xs:gap-2\">\n                            {availableGroups.map((group) => {\n                              const readPermission = group.permissions.find(isReadPermission)\n                              const writePermission = group.permissions.find(isWritePermission)\n                              const deletePermission = group.permissions.find(isDeletePermission)\n                              const hasImplicitRead = IMPLICIT_READ_RESOURCES.includes(group.name)\n\n                              return (\n                                <div\n                                  key={group.name}\n                                  className=\"flex gap-2 justify-between xs:items-center flex-col xs:flex-row\"\n                                >\n                                  <Label htmlFor={`group-${group.name}`} className=\"font-normal\">\n                                    {group.name}\n                                  </Label>\n\n                                  <ToggleGroup\n                                    type=\"multiple\"\n                                    variant=\"outline\"\n                                    size=\"sm\"\n                                    spacing={0}\n                                    value={group.permissions.filter((p) => field.state.value.includes(p))}\n                                    onValueChange={(newGroupSelection) => {\n                                      const permissionsWithoutThisGroup = field.state.value.filter(\n                                        (p) => !group.permissions.includes(p),\n                                      )\n\n                                      field.handleChange([\n                                        ...permissionsWithoutThisGroup,\n                                        ...newGroupSelection,\n                                      ] as CreateApiKeyPermissionsEnum[])\n                                    }}\n                                  >\n                                    {hasImplicitRead ? (\n                                      <ToggleGroupItem\n                                        value=\"\"\n                                        aria-label=\"Implicit read access\"\n                                        className=\"min-w-[64px]\"\n                                        disabled\n                                        data-state=\"on\"\n                                      >\n                                        Read*\n                                      </ToggleGroupItem>\n                                    ) : (\n                                      <ToggleGroupItem\n                                        value={readPermission ?? ''}\n                                        aria-label=\"Toggle read\"\n                                        className=\"min-w-[64px]\"\n                                        disabled={!readPermission}\n                                      >\n                                        {readPermission ? 'Read' : '-'}\n                                      </ToggleGroupItem>\n                                    )}\n                                    <ToggleGroupItem\n                                      value={writePermission ?? ''}\n                                      aria-label=\"Toggle write\"\n                                      className=\"min-w-[64px]\"\n                                      disabled={!writePermission}\n                                    >\n                                      {writePermission ? 'Write' : '-'}\n                                    </ToggleGroupItem>\n                                    <ToggleGroupItem\n                                      value={deletePermission ?? ''}\n                                      aria-label=\"Toggle delete\"\n                                      className=\"min-w-[64px]\"\n                                      disabled={!deletePermission}\n                                    >\n                                      {deletePermission ? 'Delete' : '-'}\n                                    </ToggleGroupItem>\n                                  </ToggleGroup>\n                                </div>\n                              )\n                            })}\n                          </FieldGroup>\n                          {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                            <FieldError errors={field.state.meta.errors} />\n                          )}\n                          <p className=\"text-sm text-muted-foreground mt-3\">\n                            *Read access is always granted for these resources.\n                          </p>\n                        </Field>\n                      )}\n                    </form.Field>\n                  )}\n                </TabsContent>\n              </Tabs>\n            </form>\n          </div>\n        )}\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\">\n              Close\n            </Button>\n          </DialogClose>\n          {!createdKey && (\n            <form.Subscribe\n              selector={(state) => [state.canSubmit, state.isSubmitting]}\n              children={([canSubmit, isSubmitting]) => (\n                <Button\n                  type=\"submit\"\n                  form=\"create-api-key-form\"\n                  variant=\"default\"\n                  disabled={!canSubmit || isSubmitting || !organizationId}\n                >\n                  {isSubmitting && <Spinner />}\n                  Create\n                </Button>\n              )}\n            />\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nconst MotionCopyIcon = motion(CopyIcon)\nconst MotionCheckIcon = motion(CheckIcon)\n\nconst iconProps = {\n  initial: { opacity: 0, y: 5 },\n  animate: { opacity: 1, y: 0 },\n  exit: { opacity: 0, y: -5 },\n  transition: { duration: 0.1 },\n}\n\nfunction CreatedKeyDisplay({ createdKey, apiUrl }: { createdKey: ApiKeyResponse; apiUrl: string }) {\n  const [copiedApiKey, copyApiKey] = useCopyToClipboard()\n  const [copiedApiUrl, copyApiUrl] = useCopyToClipboard()\n\n  const [apiKeyRevealed, setApiKeyRevealed] = useState(false)\n\n  return (\n    <div className=\"space-y-6\">\n      <Alert variant=\"warning\">\n        <InfoIcon />\n        <AlertDescription>You can only view this key once. Store it safely.</AlertDescription>\n      </Alert>\n      <FieldGroup className=\"gap-4\">\n        <Field>\n          <FieldLabel htmlFor=\"api-key\">API Key</FieldLabel>\n\n          <InputGroup className=\"pr-1 flex-1\">\n            <InputGroupInput\n              id=\"api-key\"\n              value={apiKeyRevealed ? createdKey.value : getMaskedToken(createdKey.value)}\n              readOnly\n            />\n            <InputGroupButton variant=\"ghost\" size=\"icon-xs\" onClick={() => setApiKeyRevealed(!apiKeyRevealed)}>\n              {apiKeyRevealed ? <EyeOffIcon className=\"h-4 w-4\" /> : <EyeIcon className=\"h-4 w-4\" />}\n            </InputGroupButton>\n            <InputGroupButton variant=\"ghost\" size=\"icon-xs\" onClick={() => copyApiKey(createdKey.value)}>\n              <AnimatePresence initial={false} mode=\"wait\">\n                {copiedApiKey ? (\n                  <MotionCheckIcon className=\"h-4 w-4\" key=\"copied\" {...iconProps} />\n                ) : (\n                  <MotionCopyIcon className=\"h-4 w-4\" key=\"copy\" {...iconProps} />\n                )}\n              </AnimatePresence>\n            </InputGroupButton>\n          </InputGroup>\n        </Field>\n\n        <Field>\n          <FieldLabel htmlFor=\"api-url\">API URL</FieldLabel>\n\n          <InputGroup className=\"pr-1 flex-1\">\n            <InputGroupInput id=\"api-url\" value={apiUrl} readOnly />\n            <InputGroupButton variant=\"ghost\" size=\"icon-xs\" onClick={() => copyApiUrl(apiUrl)}>\n              <AnimatePresence initial={false} mode=\"wait\">\n                {copiedApiUrl ? (\n                  <MotionCheckIcon className=\"h-4 w-4\" key=\"copied\" {...iconProps} />\n                ) : (\n                  <MotionCopyIcon className=\"h-4 w-4\" key=\"copy\" {...iconProps} />\n                )}\n              </AnimatePresence>\n            </InputGroupButton>\n          </InputGroup>\n        </Field>\n      </FieldGroup>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/CreateRegionDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState } from 'react'\nimport { CreateRegion, CreateRegionResponse } from '@daytonaio/api-client'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { toast } from 'sonner'\nimport { Plus, Copy } from 'lucide-react'\nimport { getMaskedToken } from '@/lib/utils'\n\nconst DEFAULT_FORM_DATA = {\n  name: '',\n  proxyUrl: '',\n  sshGatewayUrl: '',\n  snapshotManagerUrl: '',\n}\n\ninterface CreateRegionDialogProps {\n  onCreateRegion: (data: CreateRegion) => Promise<CreateRegionResponse | null>\n  writePermitted: boolean\n  loadingData: boolean\n}\n\nexport const CreateRegionDialog: React.FC<CreateRegionDialogProps> = ({\n  onCreateRegion,\n  writePermitted,\n  loadingData,\n}) => {\n  const [open, setOpen] = useState(false)\n  const [loading, setLoading] = useState(false)\n\n  const [createdRegion, setCreatedRegion] = useState<CreateRegionResponse | null>(null)\n  const [isProxyApiKeyRevealed, setIsProxyApiKeyRevealed] = useState(false)\n  const [isSshGatewayApiKeyRevealed, setIsSshGatewayApiKeyRevealed] = useState(false)\n  const [isSnapshotManagerPasswordRevealed, setIsSnapshotManagerPasswordRevealed] = useState(false)\n\n  const [formData, setFormData] = useState(DEFAULT_FORM_DATA)\n\n  const handleCreate = async () => {\n    setLoading(true)\n    try {\n      const createRegionData: CreateRegion = {\n        name: formData.name,\n        proxyUrl: formData.proxyUrl.trim() || null,\n        sshGatewayUrl: formData.sshGatewayUrl.trim() || null,\n        snapshotManagerUrl: formData.snapshotManagerUrl.trim() || null,\n      }\n\n      const region = await onCreateRegion(createRegionData)\n      if (region) {\n        if (\n          !region.proxyApiKey &&\n          !region.sshGatewayApiKey &&\n          !region.snapshotManagerUsername &&\n          !region.snapshotManagerPassword\n        ) {\n          setOpen(false)\n          setCreatedRegion(null)\n        } else {\n          setCreatedRegion(region)\n        }\n        setFormData(DEFAULT_FORM_DATA)\n      }\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const copyToClipboard = async (text: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      toast.success('Copied to clipboard')\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n      toast.error('Failed to copy to clipboard')\n    }\n  }\n\n  if (!writePermitted) {\n    return null\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        setOpen(isOpen)\n        if (!isOpen) {\n          setCreatedRegion(null)\n          setFormData(DEFAULT_FORM_DATA)\n          setIsProxyApiKeyRevealed(false)\n          setIsSshGatewayApiKeyRevealed(false)\n          setIsSnapshotManagerPasswordRevealed(false)\n        }\n      }}\n    >\n      <DialogTrigger asChild>\n        <Button variant=\"default\" size=\"sm\" disabled={loadingData} className=\"w-auto px-4\" title=\"Create Region\">\n          <Plus className=\"w-4 h-4\" />\n          Create Region\n        </Button>\n      </DialogTrigger>\n\n      <DialogContent className=\"max-w-2xl\">\n        <DialogHeader>\n          <DialogTitle>{createdRegion ? 'New Region Created' : 'Create New Region'}</DialogTitle>\n          <DialogDescription>\n            {!createdRegion\n              ? 'Add a new region for grouping runners and sandboxes.'\n              : createdRegion.proxyApiKey ||\n                  createdRegion.sshGatewayApiKey ||\n                  createdRegion.snapshotManagerUsername ||\n                  createdRegion.snapshotManagerPassword\n                ? \"Save these credentials securely. You won't be able to see them again.\"\n                : ''}\n          </DialogDescription>\n        </DialogHeader>\n\n        {createdRegion &&\n        (createdRegion.proxyApiKey ||\n          createdRegion.sshGatewayApiKey ||\n          createdRegion.snapshotManagerUsername ||\n          createdRegion.snapshotManagerPassword) ? (\n          <div className=\"space-y-6\">\n            {createdRegion.proxyApiKey && (\n              <div className=\"space-y-3\">\n                <Label htmlFor=\"proxy-api-key\">Proxy API Key</Label>\n                <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                  <span\n                    className=\"overflow-x-auto pr-2 cursor-text select-all\"\n                    onMouseEnter={() => setIsProxyApiKeyRevealed(true)}\n                    onMouseLeave={() => setIsProxyApiKeyRevealed(false)}\n                  >\n                    {isProxyApiKeyRevealed ? createdRegion.proxyApiKey : getMaskedToken(createdRegion.proxyApiKey)}\n                  </span>\n                  <Copy\n                    className=\"w-4 h-4 cursor-pointer text-muted-foreground hover:text-foreground transition-colors\"\n                    onClick={() => copyToClipboard(createdRegion.proxyApiKey!)}\n                  />\n                </div>\n              </div>\n            )}\n\n            {createdRegion.sshGatewayApiKey && (\n              <div className=\"space-y-3\">\n                <Label htmlFor=\"ssh-gateway-api-key\">SSH Gateway API Key</Label>\n                <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                  <span\n                    className=\"overflow-x-auto pr-2 cursor-text select-all\"\n                    onMouseEnter={() => setIsSshGatewayApiKeyRevealed(true)}\n                    onMouseLeave={() => setIsSshGatewayApiKeyRevealed(false)}\n                  >\n                    {isSshGatewayApiKeyRevealed\n                      ? createdRegion.sshGatewayApiKey\n                      : getMaskedToken(createdRegion.sshGatewayApiKey)}\n                  </span>\n                  <Copy\n                    className=\"w-4 h-4 cursor-pointer text-muted-foreground hover:text-foreground transition-colors\"\n                    onClick={() => copyToClipboard(createdRegion.sshGatewayApiKey!)}\n                  />\n                </div>\n              </div>\n            )}\n\n            {createdRegion.snapshotManagerUsername && (\n              <div className=\"space-y-3\">\n                <Label htmlFor=\"snapshot-manager-username\">Snapshot manager username</Label>\n                <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                  <span className=\"overflow-x-auto pr-2 cursor-text select-all\">\n                    {createdRegion.snapshotManagerUsername}\n                  </span>\n                  <Copy\n                    className=\"w-4 h-4 cursor-pointer text-muted-foreground hover:text-foreground transition-colors\"\n                    onClick={() => copyToClipboard(createdRegion.snapshotManagerUsername!)}\n                  />\n                </div>\n              </div>\n            )}\n\n            {createdRegion.snapshotManagerPassword && (\n              <div className=\"space-y-3\">\n                <Label htmlFor=\"snapshot-manager-password\">Snapshot manager password</Label>\n                <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                  <span\n                    className=\"overflow-x-auto pr-2 cursor-text select-all\"\n                    onMouseEnter={() => setIsSnapshotManagerPasswordRevealed(true)}\n                    onMouseLeave={() => setIsSnapshotManagerPasswordRevealed(false)}\n                  >\n                    {isSnapshotManagerPasswordRevealed\n                      ? createdRegion.snapshotManagerPassword\n                      : getMaskedToken(createdRegion.snapshotManagerPassword)}\n                  </span>\n                  <Copy\n                    className=\"w-4 h-4 cursor-pointer text-muted-foreground hover:text-foreground transition-colors\"\n                    onClick={() => copyToClipboard(createdRegion.snapshotManagerPassword!)}\n                  />\n                </div>\n              </div>\n            )}\n          </div>\n        ) : (\n          <form\n            id=\"create-region-form\"\n            className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n            onSubmit={async (e) => {\n              e.preventDefault()\n              await handleCreate()\n            }}\n          >\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"name\">Region Name</Label>\n              <Input\n                id=\"name\"\n                value={formData.name}\n                onChange={(e) => {\n                  setFormData((prev) => ({ ...prev, name: e.target.value }))\n                }}\n                placeholder=\"us-east-1\"\n              />\n              <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n                Region name must contain only letters, numbers, underscores, periods, and hyphens.\n              </p>\n            </div>\n\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"proxy-url\">Proxy URL</Label>\n              <Input\n                id=\"proxy-url\"\n                value={formData.proxyUrl}\n                onChange={(e) => {\n                  setFormData((prev) => ({ ...prev, proxyUrl: e.target.value }))\n                }}\n                placeholder=\"https://proxy.example.com\"\n              />\n              <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n                (Optional) URL of the custom proxy for this region\n              </p>\n            </div>\n\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"ssh-gateway-url\">SSH gateway URL</Label>\n              <Input\n                id=\"ssh-gateway-url\"\n                value={formData.sshGatewayUrl}\n                onChange={(e) => {\n                  setFormData((prev) => ({ ...prev, sshGatewayUrl: e.target.value }))\n                }}\n                placeholder=\"https://ssh-gateway.example.com\"\n              />\n              <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n                (Optional) URL of the custom SSH gateway for this region\n              </p>\n            </div>\n\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"snapshot-manager-url\">Snapshot manager URL</Label>\n              <Input\n                id=\"snapshot-manager-url\"\n                value={formData.snapshotManagerUrl}\n                onChange={(e) => {\n                  setFormData((prev) => ({ ...prev, snapshotManagerUrl: e.target.value }))\n                }}\n                placeholder=\"https://snapshot-manager.example.com\"\n              />\n              <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n                (Optional) URL of the custom snapshot manager for this region\n              </p>\n            </div>\n          </form>\n        )}\n\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\">\n              {createdRegion ? 'Close' : 'Cancel'}\n            </Button>\n          </DialogClose>\n          {!createdRegion &&\n            (loading ? (\n              <Button type=\"button\" variant=\"default\" disabled>\n                Creating...\n              </Button>\n            ) : (\n              <Button type=\"submit\" form=\"create-region-form\" variant=\"default\" disabled={loading}>\n                Create\n              </Button>\n            ))}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/CreateRunnerDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useEffect } from 'react'\nimport { Region, CreateRunner, CreateRunnerResponse } from '@daytonaio/api-client'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { toast } from 'sonner'\nimport { Plus, Copy } from 'lucide-react'\nimport { getMaskedToken } from '@/lib/utils'\n\nconst DEFAULT_FORM_DATA = {\n  name: '',\n  regionId: '',\n}\n\ninterface CreateRunnerDialogProps {\n  regions: Region[]\n  onCreateRunner: (data: CreateRunner) => Promise<CreateRunnerResponse | null>\n}\n\nexport const CreateRunnerDialog: React.FC<CreateRunnerDialogProps> = ({ regions, onCreateRunner }) => {\n  const [open, setOpen] = useState(false)\n  const [loading, setLoading] = useState(false)\n\n  const [createdRunner, setCreatedRunner] = useState<CreateRunnerResponse | null>(null)\n  const [isTokenRevealed, setIsTokenRevealed] = useState(false)\n\n  const [formData, setFormData] = useState(DEFAULT_FORM_DATA)\n  const [formErrors, setFormErrors] = useState<Record<string, string>>({})\n\n  useEffect(() => {\n    if (regions.length > 0 && !formData.regionId) {\n      setFormData((prev) => ({ ...prev, regionId: regions[0].id }))\n    }\n  }, [regions, formData.regionId])\n\n  const validateForm = () => {\n    const errors: Record<string, string> = {}\n\n    if (!formData.name.trim()) {\n      errors.name = 'Name is required'\n    }\n\n    if (!formData.regionId) {\n      errors.regionId = 'Region is required'\n    }\n\n    setFormErrors(errors)\n    return Object.keys(errors).length === 0\n  }\n\n  const handleCreate = async () => {\n    if (!validateForm()) {\n      return\n    }\n\n    setLoading(true)\n    try {\n      const runner = await onCreateRunner({\n        name: formData.name.trim(),\n        regionId: formData.regionId,\n      })\n      if (runner) {\n        setCreatedRunner(runner)\n        setFormData({\n          ...DEFAULT_FORM_DATA,\n          regionId: regions.length > 0 ? regions[0].id : '',\n        })\n        setFormErrors({})\n      }\n    } finally {\n      setLoading(false)\n    }\n  }\n\n  const copyToClipboard = async (text: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      toast.success('Copied to clipboard')\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n      toast.error('Failed to copy to clipboard')\n    }\n  }\n\n  if (regions.length === 0) {\n    return null\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        setOpen(isOpen)\n        if (!isOpen) {\n          setCreatedRunner(null)\n          setFormData({\n            ...DEFAULT_FORM_DATA,\n            regionId: regions.length > 0 ? regions[0].id : '',\n          })\n          setFormErrors({})\n        }\n      }}\n    >\n      <DialogTrigger asChild>\n        <Button variant=\"default\" size=\"sm\" className=\"w-auto px-4\" title=\"Create Runner\">\n          <Plus className=\"w-4 h-4\" />\n          Create Runner\n        </Button>\n      </DialogTrigger>\n\n      <DialogContent className=\"max-w-2xl\">\n        <DialogHeader>\n          <DialogTitle>Create New Runner</DialogTitle>\n          <DialogDescription>Add configuration for a new runner in your selected region.</DialogDescription>\n        </DialogHeader>\n\n        {createdRunner ? (\n          <div className=\"space-y-6\">\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"token\">Token</Label>\n              <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                <span\n                  className=\"overflow-x-auto pr-2 cursor-text select-all\"\n                  onMouseEnter={() => setIsTokenRevealed(true)}\n                  onMouseLeave={() => setIsTokenRevealed(false)}\n                >\n                  {isTokenRevealed ? createdRunner.apiKey : getMaskedToken(createdRunner.apiKey)}\n                </span>\n                <Copy\n                  className=\"w-4 h-4 cursor-pointer text-muted-foreground hover:text-foreground transition-colors\"\n                  onClick={() => copyToClipboard(createdRunner.apiKey)}\n                />\n              </div>\n              <p className=\"text-sm text-muted-foreground\">\n                Save this token securely. You won't be able to see it again.\n              </p>\n            </div>\n          </div>\n        ) : (\n          <form\n            id=\"create-runner-form\"\n            className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n            onSubmit={async (e) => {\n              e.preventDefault()\n              await handleCreate()\n            }}\n          >\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"regionId\">Region</Label>\n              <Select\n                value={formData.regionId}\n                onValueChange={(value) => {\n                  setFormData((prev) => ({ ...prev, regionId: value }))\n                  if (formErrors.regionId) {\n                    setFormErrors((prev) => ({ ...prev, regionId: '' }))\n                  }\n                }}\n              >\n                <SelectTrigger className={`h-8 ${formErrors.regionId ? 'border-destructive' : ''}`}>\n                  <SelectValue placeholder=\"Select a region\" />\n                </SelectTrigger>\n                <SelectContent>\n                  {regions.map((region) => (\n                    <SelectItem key={region.id} value={region.id}>\n                      {region.name}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n              {formErrors.regionId && <p className=\"text-sm text-destructive\">{formErrors.regionId}</p>}\n            </div>\n\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"name\">Name</Label>\n              <Input\n                id=\"name\"\n                value={formData.name}\n                onChange={(e) => {\n                  setFormData((prev) => ({ ...prev, name: e.target.value }))\n                }}\n                placeholder=\"runner-1\"\n              />\n              {formErrors.name && <p className=\"text-sm text-destructive\">{formErrors.name}</p>}\n            </div>\n          </form>\n        )}\n\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\">\n              {createdRunner ? 'Close' : 'Cancel'}\n            </Button>\n          </DialogClose>\n          {!createdRunner &&\n            (loading ? (\n              <Button type=\"button\" variant=\"default\" disabled>\n                Creating...\n              </Button>\n            ) : (\n              <Button type=\"submit\" form=\"create-runner-form\" variant=\"default\" disabled={loading}>\n                Create\n              </Button>\n            ))}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/DebouncedInput.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useEffect, useState } from 'react'\nimport { Input } from './ui/input'\n\nexport const DebouncedInput = ({\n  value: initialValue,\n  onChange,\n  debounce = 500,\n  ...props\n}: {\n  value: string | number\n  onChange: (value: string | number) => void\n  debounce?: number\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'>) => {\n  const [value, setValue] = useState(initialValue)\n\n  useEffect(() => {\n    setValue(initialValue)\n  }, [initialValue])\n\n  useEffect(() => {\n    const timeout = setTimeout(() => {\n      onChange(value)\n    }, debounce)\n\n    return () => clearTimeout(timeout)\n  }, [value])\n\n  return <Input {...props} value={value} onChange={(e) => setValue(e.target.value)} />\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/EllipsisWithTooltip.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { Slot } from '@radix-ui/react-slot'\nimport { useRef, useState } from 'react'\nimport { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'\n\nexport function EllipsisWithTooltip({\n  children,\n  asChild,\n  className,\n  ...props\n}: {\n  children: React.ReactNode\n  className?: string\n  asChild?: boolean\n}) {\n  const [isOpen, setIsOpen] = useState(false)\n  const triggerRef = useRef<HTMLDivElement>(null)\n\n  const Comp = asChild ? Slot : 'div'\n\n  return (\n    <Tooltip\n      open={isOpen}\n      onOpenChange={(shouldOpen) => {\n        if (shouldOpen) {\n          const isTruncated = triggerRef.current && triggerRef.current.scrollWidth > triggerRef.current.clientWidth\n          if (isTruncated) {\n            setIsOpen(true)\n          }\n        } else {\n          setIsOpen(false)\n        }\n      }}\n      delayDuration={300}\n    >\n      <TooltipTrigger asChild>\n        <Comp ref={triggerRef} className={cn('truncate', className)} {...props}>\n          {children}\n        </Comp>\n      </TooltipTrigger>\n      <TooltipContent>{children}</TooltipContent>\n    </Tooltip>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ErrorBoundaryFallback.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Dialog, DialogHeader, DialogDescription, DialogTitle, DialogContent } from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\nimport { FallbackProps } from 'react-error-boundary'\n\nexport function ErrorBoundaryFallback({ error, resetErrorBoundary }: FallbackProps) {\n  return (\n    <Dialog open>\n      <DialogContent className=\"[&>button]:hidden\">\n        <DialogHeader>\n          <DialogTitle>Something went wrong</DialogTitle>\n          <DialogDescription>\n            We're having trouble loading the dashboard. This could be due to a temporary service issue or network\n            problem. Please try again or contact support if the issue persists.\n          </DialogDescription>\n        </DialogHeader>\n\n        <div className=\"space-y-4\">\n          <div className=\"bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4\">\n            <h4 className=\"font-semibold text-red-800 dark:text-red-200 mb-2\">Error Details:</h4>\n            <p className=\"text-red-700 dark:text-red-300 font-mono text-sm break-all\">\n              {error?.message || 'Unknown error'}\n            </p>\n          </div>\n\n          {error?.stack && (\n            <details className=\"bg-gray-50 dark:bg-gray-900/20 border border-gray-200 dark:border-gray-800 rounded-lg p-4\">\n              <summary className=\"cursor-pointer font-semibold text-gray-800 dark:text-gray-200\">\n                Stack Trace (click to expand)\n              </summary>\n              <pre className=\"text-xs text-gray-700 dark:text-gray-300 overflow-auto max-h-48 font-mono whitespace-pre-wrap mt-2\">\n                {error.stack}\n              </pre>\n            </details>\n          )}\n\n          <div className=\"flex gap-2 justify-end\">\n            <Button variant=\"outline\" onClick={() => window.location.reload()}>\n              Reload Page\n            </Button>\n            <Button variant=\"outline\" onClick={resetErrorBoundary}>\n              Try Again\n            </Button>\n          </div>\n        </div>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Invoices/InvoicesTableActions.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { MoreHorizontalIcon } from 'lucide-react'\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n} from '../ui/alert-dialog'\nimport { Button } from '../ui/button'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '../ui/dropdown-menu'\nimport { InvoicesTableActionsProps } from './types'\n\nexport function InvoicesTableActions({ invoice, onView, onVoid, onPay }: InvoicesTableActionsProps) {\n  if (!onView && !onVoid && !onPay) {\n    return null\n  }\n\n  return (\n    <div className=\"flex items-center gap-1\">\n      <DropdownMenu>\n        <DropdownMenuTrigger asChild>\n          <Button variant=\"ghost\" size=\"sm\" className=\"h-8 w-8 p-0\">\n            <MoreHorizontalIcon className=\"h-4 w-4\" aria-label=\"Open menu\" />\n          </Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent align=\"end\">\n          {onView && (\n            <DropdownMenuItem className=\"cursor-pointer\" onSelect={() => onView?.(invoice)}>\n              View\n            </DropdownMenuItem>\n          )}\n          {onPay && (\n            <DropdownMenuItem className=\"cursor-pointer\" onSelect={() => onPay?.(invoice)}>\n              Pay\n            </DropdownMenuItem>\n          )}\n          {onVoid && (\n            <>\n              <DropdownMenuSeparator />\n              <AlertDialog>\n                <AlertDialogTrigger asChild>\n                  <DropdownMenuItem\n                    className=\"cursor-pointer\"\n                    onSelect={(e) => e.preventDefault()}\n                    variant=\"destructive\"\n                  >\n                    Void\n                  </DropdownMenuItem>\n                </AlertDialogTrigger>\n                <AlertDialogContent className=\"sm:max-w-md\">\n                  <AlertDialogHeader>\n                    <AlertDialogTitle>Void Invoice</AlertDialogTitle>\n                    <AlertDialogDescription>\n                      Are you sure you want to void the invoice <span className=\"font-bold\">{invoice.number}</span>?\n                      <br />\n                      This action cannot be undone.\n                    </AlertDialogDescription>\n                  </AlertDialogHeader>\n                  <AlertDialogFooter>\n                    <AlertDialogCancel>Cancel</AlertDialogCancel>\n                    <AlertDialogAction onClick={() => onVoid?.(invoice)} variant=\"destructive\">\n                      Void\n                    </AlertDialogAction>\n                  </AlertDialogFooter>\n                </AlertDialogContent>\n              </AlertDialog>\n            </>\n          )}\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Invoices/InvoicesTableHeader.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Search } from 'lucide-react'\nimport React from 'react'\nimport { DebouncedInput } from '../DebouncedInput'\nimport { InvoicesTableHeaderProps } from './types'\n\nexport function InvoicesTableHeader({ table }: InvoicesTableHeaderProps) {\n  const [globalFilter, setGlobalFilter] = React.useState('')\n\n  React.useEffect(() => {\n    const down = (e: KeyboardEvent) => {\n      if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {\n        e.preventDefault()\n        // Focus search input\n        const searchInput = document.querySelector('[data-search-input]') as HTMLInputElement\n        if (searchInput) {\n          searchInput.focus()\n        }\n      }\n    }\n\n    document.addEventListener('keydown', down)\n    return () => document.removeEventListener('keydown', down)\n  }, [])\n\n  return (\n    <div className=\"flex items-center justify-between pb-4\">\n      <div className=\"flex flex-1 items-center space-x-2\">\n        <div className=\"relative w-full max-w-sm\">\n          <Search className=\"absolute left-2 top-2 h-4 w-4 text-muted-foreground\" />\n          <DebouncedInput\n            placeholder=\"Search invoices...\"\n            value={globalFilter ?? ''}\n            onChange={(value) => {\n              setGlobalFilter(String(value))\n              table.setGlobalFilter(String(value))\n            }}\n            className=\"pl-8\"\n            data-search-input\n          />\n        </div>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Invoices/columns.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Invoice } from '@/billing-api/types/Invoice'\nimport { formatAmount } from '@/lib/utils'\nimport { ColumnDef } from '@tanstack/react-table'\nimport { ArrowDown, ArrowUp } from 'lucide-react'\nimport React from 'react'\nimport { Badge } from '../ui/badge'\nimport { InvoicesTableActions } from './InvoicesTableActions'\n\ninterface SortableHeaderProps {\n  column: any\n  label: string\n  dataState?: string\n}\n\nconst SortableHeader: React.FC<SortableHeaderProps> = ({ column, label, dataState }) => {\n  return (\n    <div\n      role=\"button\"\n      onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n      className=\"flex items-center\"\n      {...(dataState && { 'data-state': dataState })}\n    >\n      {label}\n      {column.getIsSorted() === 'asc' ? (\n        <ArrowUp className=\"ml-2 h-4 w-4\" />\n      ) : column.getIsSorted() === 'desc' ? (\n        <ArrowDown className=\"ml-2 h-4 w-4\" />\n      ) : (\n        <div className=\"ml-2 w-4 h-4\" />\n      )}\n    </div>\n  )\n}\n\ninterface GetColumnsProps {\n  onViewInvoice?: (invoice: Invoice) => void\n  onVoidInvoice?: (invoice: Invoice) => void\n  onPayInvoice?: (invoice: Invoice) => void\n}\n\nexport function getColumns({ onViewInvoice, onVoidInvoice, onPayInvoice }: GetColumnsProps): ColumnDef<Invoice>[] {\n  const columns: ColumnDef<Invoice>[] = [\n    {\n      id: 'number',\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Invoice\" />\n      },\n      accessorKey: 'number',\n      cell: ({ row }) => {\n        return (\n          <div className=\"w-full truncate\">\n            <span className=\"font-medium\">{row.original.number}</span>\n          </div>\n        )\n      },\n      sortingFn: (rowA, rowB) => {\n        return rowA.original.number.localeCompare(rowB.original.number)\n      },\n    },\n    {\n      id: 'issuingDate',\n      size: 140,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Date\" />\n      },\n      cell: ({ row }) => {\n        const date = new Date(row.original.issuingDate)\n        return (\n          <div className=\"w-full truncate\">\n            <span>{date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })}</span>\n          </div>\n        )\n      },\n      accessorFn: (row) => new Date(row.issuingDate).getTime(),\n      sortingFn: (rowA, rowB) => {\n        return new Date(rowA.original.issuingDate).getTime() - new Date(rowB.original.issuingDate).getTime()\n      },\n    },\n    {\n      id: 'paymentDueDate',\n      size: 140,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Due Date\" />\n      },\n      cell: ({ row }) => {\n        const date = new Date(row.original.paymentDueDate)\n        return (\n          <div className=\"w-full truncate\">\n            <span>{date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' })}</span>\n          </div>\n        )\n      },\n      accessorFn: (row) => new Date(row.paymentDueDate).getTime(),\n      sortingFn: (rowA, rowB) => {\n        return new Date(rowA.original.paymentDueDate).getTime() - new Date(rowB.original.paymentDueDate).getTime()\n      },\n    },\n    {\n      id: 'totalAmountCents',\n      size: 120,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Amount\" />\n      },\n      cell: ({ row }) => {\n        return (\n          <div className=\"w-full truncate\">\n            <span>{formatAmount(row.original.totalAmountCents)}</span>\n          </div>\n        )\n      },\n      accessorKey: 'totalAmountCents',\n      sortingFn: (rowA, rowB) => {\n        return rowA.original.totalAmountCents - rowB.original.totalAmountCents\n      },\n    },\n    {\n      id: 'paymentStatus',\n      size: 120,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Status\" />\n      },\n      cell: ({ row }) => {\n        const invoice = row.original\n        const isSucceeded = invoice.paymentStatus === 'succeeded'\n        const isFailed = invoice.paymentStatus === 'failed'\n        const isOverdue = invoice.paymentOverdue\n\n        let variant: 'success' | 'destructive' | 'secondary' = 'secondary'\n        let label = 'Pending'\n\n        if (isSucceeded) {\n          variant = 'success'\n          label = 'Paid'\n        } else if (isOverdue || isFailed) {\n          variant = 'destructive'\n          label = isOverdue ? 'Overdue' : 'Failed'\n        }\n\n        if (invoice.status === 'voided') {\n          label = 'Voided'\n        }\n\n        return (\n          <div className=\"max-w-[120px] flex\">\n            <Badge variant={variant}>{label}</Badge>\n          </div>\n        )\n      },\n      accessorKey: 'paymentStatus',\n      sortingFn: (rowA, rowB) => {\n        const statusOrder = { succeeded: 0, pending: 1, failed: 2 }\n        return (statusOrder[rowA.original.paymentStatus] ?? 3) - (statusOrder[rowB.original.paymentStatus] ?? 3)\n      },\n    },\n    {\n      id: 'type',\n      size: 120,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Type\" />\n      },\n      cell: ({ row }) => {\n        const type = row.original.type\n        const displayType = type === 'subscription' ? 'Subscription' : 'One Time'\n        return (\n          <div className=\"w-full truncate\">\n            <span>{displayType}</span>\n          </div>\n        )\n      },\n      accessorKey: 'type',\n      sortingFn: (rowA, rowB) => {\n        return rowA.original.type.localeCompare(rowB.original.type)\n      },\n    },\n    {\n      id: 'actions',\n      size: 100,\n      enableHiding: false,\n      cell: ({ row }) => {\n        const isPayable = row.original.paymentStatus === 'pending' && row.original.status === 'finalized'\n        const isViewable = Boolean(row.original.fileUrl)\n        const isVoidable =\n          row.original.status === 'finalized' && ['pending', 'failed'].includes(row.original.paymentStatus)\n\n        return (\n          <div>\n            <InvoicesTableActions\n              invoice={row.original}\n              onView={isViewable ? onViewInvoice : undefined}\n              onVoid={isVoidable ? onVoidInvoice : undefined}\n              onPay={isPayable ? onPayInvoice : undefined}\n            />\n          </div>\n        )\n      },\n    },\n  ]\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Invoices/index.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { flexRender } from '@tanstack/react-table'\nimport { FileText } from 'lucide-react'\nimport { Pagination } from '../Pagination'\nimport { TableEmptyState } from '../TableEmptyState'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table'\nimport { InvoicesTableHeader } from './InvoicesTableHeader'\nimport { InvoicesTableProps } from './types'\nimport { useInvoicesTable } from './useInvoicesTable'\n\nexport function InvoicesTable({\n  data,\n  pagination,\n  totalItems,\n  pageCount,\n  onPaginationChange,\n  loading,\n  onViewInvoice,\n  onVoidInvoice,\n  onRowClick,\n  onPayInvoice,\n}: InvoicesTableProps) {\n  const { table } = useInvoicesTable({\n    data,\n    pagination,\n    pageCount,\n    onPaginationChange,\n    onViewInvoice,\n    onVoidInvoice,\n    onPayInvoice,\n  })\n\n  return (\n    <>\n      <InvoicesTableHeader table={table} />\n\n      <Table className=\"border-separate border-spacing-0\">\n        <TableHeader>\n          {table.getHeaderGroups().map((headerGroup) => (\n            <TableRow key={headerGroup.id}>\n              {headerGroup.headers.map((header) => {\n                return (\n                  <TableHead\n                    key={header.id}\n                    data-state={header.column.getCanSort() && 'sortable'}\n                    onClick={() =>\n                      header.column.getCanSort() && header.column.toggleSorting(header.column.getIsSorted() === 'asc')\n                    }\n                    className={cn(\n                      'sticky top-0 z-[3] border-b border-border',\n                      header.column.getCanSort() ? 'hover:bg-muted cursor-pointer' : '',\n                    )}\n                  >\n                    {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                )\n              })}\n            </TableRow>\n          ))}\n        </TableHeader>\n        <TableBody>\n          {loading ? (\n            <TableRow>\n              <TableCell colSpan={table.getAllColumns().length} className=\"h-10 text-center\">\n                Loading...\n              </TableCell>\n            </TableRow>\n          ) : table.getRowModel().rows?.length ? (\n            table.getRowModel().rows.map((row) => (\n              <TableRow\n                key={row.id}\n                className={`transition-colors duration-300 ${onRowClick ? 'cursor-pointer' : ''}`}\n                onClick={() => onRowClick?.(row.original)}\n              >\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell\n                    key={cell.id}\n                    onClick={(e) => {\n                      if (cell.column.id === 'actions') {\n                        e.stopPropagation()\n                      }\n                    }}\n                    className=\"border-b border-border\"\n                    style={{\n                      width: cell.column.id === 'number' ? '20%' : 'auto',\n                      maxWidth: cell.column.getSize() + 80,\n                      minWidth: cell.column.getSize(),\n                    }}\n                    sticky={cell.column.id === 'actions' ? 'right' : undefined}\n                  >\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))\n          ) : (\n            <TableEmptyState\n              colSpan={table.getAllColumns().length}\n              message=\"No invoices yet.\"\n              icon={<FileText className=\"w-8 h-8\" />}\n              description={\n                <div className=\"space-y-2\">\n                  <p>Invoices will appear here once they are generated.</p>\n                </div>\n              }\n            />\n          )}\n        </TableBody>\n      </Table>\n\n      <div className=\"flex items-center justify-end\">\n        <Pagination className=\"pb-2 pt-6\" table={table} entityName=\"Invoices\" totalItems={totalItems} />\n      </div>\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Invoices/types.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Invoice } from '@/billing-api'\nimport { Table } from '@tanstack/react-table'\n\nexport interface InvoicesTableProps {\n  data: Invoice[]\n  totalItems: number\n  pagination: {\n    pageIndex: number\n    pageSize: number\n  }\n  pageCount: number\n  onPaginationChange: (pagination: { pageIndex: number; pageSize: number }) => void\n  loading: boolean\n  onViewInvoice?: (invoice: Invoice) => void\n  onVoidInvoice?: (invoice: Invoice) => void\n  onRowClick?: (invoice: Invoice) => void\n  onPayInvoice?: (invoice: Invoice) => void\n}\n\nexport interface InvoicesTableActionsProps {\n  invoice: Invoice\n  onView?: (invoice: Invoice) => void\n  onVoid?: (invoice: Invoice) => void\n  onPay?: (invoice: Invoice) => void\n}\n\nexport interface InvoicesTableHeaderProps {\n  table: Table<Invoice>\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Invoices/useInvoicesTable.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Invoice } from '@/billing-api/types/Invoice'\nimport {\n  ColumnFiltersState,\n  getCoreRowModel,\n  getFacetedRowModel,\n  getFacetedUniqueValues,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { useMemo, useState } from 'react'\nimport { getColumns } from './columns'\n\ninterface UseInvoicesTableProps {\n  pagination: {\n    pageIndex: number\n    pageSize: number\n  }\n  pageCount: number\n  onPaginationChange: (pagination: { pageIndex: number; pageSize: number }) => void\n  data: Invoice[]\n  onViewInvoice?: (invoice: Invoice) => void\n  onVoidInvoice?: (invoice: Invoice) => void\n  onPayInvoice?: (invoice: Invoice) => void\n}\n\nexport function useInvoicesTable({\n  data,\n  pagination,\n  pageCount,\n  onPaginationChange,\n  onViewInvoice,\n  onVoidInvoice,\n  onPayInvoice,\n}: UseInvoicesTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([\n    {\n      id: 'issuingDate',\n      desc: true,\n    },\n  ])\n  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n\n  const columns = useMemo(\n    () =>\n      getColumns({\n        onViewInvoice,\n        onVoidInvoice,\n        onPayInvoice,\n      }),\n    [onViewInvoice, onVoidInvoice, onPayInvoice],\n  )\n\n  const table = useReactTable({\n    data,\n    columns,\n    onColumnFiltersChange: setColumnFilters,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    getFacetedRowModel: getFacetedRowModel(),\n    getFacetedUniqueValues: getFacetedUniqueValues(),\n    getFilteredRowModel: getFilteredRowModel(),\n    manualPagination: true,\n    pageCount: pageCount,\n    onPaginationChange: (updater) => {\n      const newPagination = typeof updater === 'function' ? updater(table.getState().pagination) : updater\n      onPaginationChange(newPagination)\n    },\n    state: {\n      sorting,\n      columnFilters,\n      pagination: {\n        pageIndex: pagination.pageIndex,\n        pageSize: pagination.pageSize,\n      },\n    },\n    defaultColumn: {\n      size: 100,\n    },\n    getRowId: (row) => row.id,\n  })\n\n  return {\n    table,\n    sorting,\n    columnFilters,\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/LimitUsageChart.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  ChartConfig,\n  ChartContainer,\n  ChartLegend,\n  ChartLegendContent,\n  ChartTooltip,\n  ChartTooltipContent,\n} from '@/components/ui/chart'\nimport { FacetFilter } from '@/components/ui/facet-filter'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport type { RegionUsageOverview } from '@daytonaio/api-client'\nimport { useMemo, useState } from 'react'\nimport { Bar, BarChart, CartesianGrid, ReferenceLine, XAxis, YAxis } from 'recharts'\n\ntype ResourceKey = 'cpu' | 'ram' | 'storage'\n\nconst clamp = (v: number) => Math.max(0, Math.min(100, Math.round(v * 10) / 10))\n\nconst formatDate = (value: string) => new Date(value).toLocaleDateString(undefined, { month: 'short', day: '2-digit' })\n\ninterface PastUsage {\n  date: string\n  peakCpuUsage: number\n  peakMemoryUsage: number\n  peakDiskUsage: number\n}\n\nexport function LimitUsageChart({\n  defaultPeriod = 30,\n  defaultResources = ['ram', 'cpu', 'storage'],\n  pastUsage = [],\n  currentUsage,\n  title,\n}: {\n  defaultPeriod?: number\n  defaultResources?: ResourceKey[]\n  pastUsage: PastUsage[]\n  currentUsage?: RegionUsageOverview | null\n  title?: React.ReactNode\n}) {\n  const [period, setPeriod] = useState(defaultPeriod.toString())\n\n  const [selected, setSelected] = useState<Set<ResourceKey>>(new Set(defaultResources))\n\n  const data = useMemo(() => {\n    if (!currentUsage) {\n      return []\n    }\n\n    const { totalCpuQuota, totalMemoryQuota, totalDiskQuota } = currentUsage\n    return pastUsage.slice(-Number(period)).map((r) => ({\n      date: r.date,\n      cpu: clamp((r.peakCpuUsage / totalCpuQuota) * 100),\n      ram: clamp((r.peakMemoryUsage / totalMemoryQuota) * 100),\n      storage: clamp((r.peakDiskUsage / totalDiskQuota) * 100),\n    }))\n  }, [pastUsage, currentUsage, period])\n\n  const config: ChartConfig = useMemo(() => {\n    const full: Record<string, { label: string; color: string }> = {\n      cpu: { label: 'CPU', color: 'hsl(var(--chart-3))' },\n      ram: { label: 'RAM', color: 'hsl(var(--chart-2))' },\n      storage: { label: 'Storage', color: 'hsl(var(--chart-1))' },\n    }\n    return Object.fromEntries(Object.entries(full).filter(([k]) => selected.has(k as ResourceKey))) as ChartConfig\n  }, [selected])\n\n  return (\n    <div className=\"w-full\">\n      <div className=\"mb-3 flex items-center justify-between\">\n        {title}\n        <div className=\"flex gap-2 items-center\">\n          <FacetFilter\n            title=\"Resources\"\n            options={[\n              { label: 'CPU', value: 'cpu' },\n              { label: 'RAM', value: 'ram' },\n              { label: 'Storage', value: 'storage' },\n            ]}\n            selectedValues={selected}\n            setSelectedValues={(key) => setSelected(new Set(key as Set<ResourceKey>))}\n          />\n          <Select value={period} onValueChange={setPeriod}>\n            <SelectTrigger className=\"w-[160px] rounded-lg\" aria-label=\"Select the period\">\n              <SelectValue placeholder=\"Last 30 days\" />\n            </SelectTrigger>\n            <SelectContent className=\"rounded-xl\">\n              <SelectItem value=\"7\">Last 7 days</SelectItem>\n              <SelectItem value=\"14\">Last 14 days</SelectItem>\n              <SelectItem value=\"30\">Last 30 days</SelectItem>\n            </SelectContent>\n          </Select>\n        </div>\n      </div>\n\n      <ChartContainer config={config} className=\"aspect-auto h-[300px] w-full\">\n        <BarChart data={data}>\n          <CartesianGrid vertical={false} />\n          <XAxis\n            dataKey=\"date\"\n            tickLine={false}\n            axisLine={false}\n            tickMargin={8}\n            minTickGap={32}\n            tickFormatter={formatDate}\n          />\n          <YAxis\n            domain={[0, 100]}\n            tickLine={false}\n            axisLine={false}\n            tickMargin={8}\n            tickCount={5}\n            tickFormatter={(v) => `${v}%`}\n          />\n          <ReferenceLine y={80} strokeDasharray=\"6 6\" stroke=\"#e88c3094\" label=\"80%\" />\n          <ReferenceLine y={100} strokeDasharray=\"6 6\" stroke=\"hsl(var(--destructive))\" label=\"MAX\" />\n          <ChartTooltip\n            cursor={false}\n            content={\n              <ChartTooltipContent\n                indicator=\"dot\"\n                labelFormatter={(label) => formatDate(label)}\n                valueFormatter={(value) => `${value}%`}\n              />\n            }\n          />\n          <ChartLegend content={<ChartLegendContent />} />\n          {selected.has('storage') && <Bar dataKey=\"storage\" fill=\"var(--color-storage)\" radius={[4, 4, 0, 0]} />}\n          {selected.has('ram') && <Bar dataKey=\"ram\" fill=\"var(--color-ram)\" radius={[4, 4, 0, 0]} />}\n          {selected.has('cpu') && <Bar dataKey=\"cpu\" fill=\"var(--color-cpu)\" radius={[4, 4, 0, 0]} />}\n        </BarChart>\n      </ChartContainer>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/LiveIndicator.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useQueryCountdown } from '@/hooks/useQueryCountdown'\nimport { cn } from '@/lib/utils'\nimport { Tooltip } from './Tooltip'\n\nexport function LiveIndicator({\n  isUpdating,\n  intervalMs,\n  lastUpdatedAt,\n}: {\n  isUpdating: boolean\n  intervalMs: number\n  lastUpdatedAt: number\n}) {\n  const refreshingIn = useQueryCountdown(lastUpdatedAt, intervalMs)\n\n  return (\n    <Tooltip\n      content={\n        <div className=\"relative flex flex-col items-center\">\n          <div className=\"text-xs text-muted-foreground\">Data is refreshed every {intervalMs / 1000} seconds.</div>\n          <span className={cn('text-xs text-muted-foreground/70')}>\n            Refreshing{' '}\n            {isUpdating ? (\n              ''\n            ) : (\n              <>\n                in <span className=\"min-w-[2ch] inline-block tabular-nums text-center\">{refreshingIn}</span>s\n              </>\n            )}\n            ...\n          </span>\n        </div>\n      }\n      label={\n        <div className=\"flex items-center gap-2\">\n          <div\n            className={cn('w-2 h-2 bg-green-500 rounded-full transition-all', {\n              'opacity-70': isUpdating,\n            })}\n          >\n            <div\n              className={cn('w-full h-full bg-green-500 rounded-full', {\n                'animate-ping': !isUpdating,\n              })}\n            />\n          </div>\n          <span\n            className={cn('text-xs text-muted-foreground transition-all', {\n              'opacity-70': isUpdating,\n            })}\n          >\n            Live\n          </span>\n        </div>\n      }\n    />\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/LoadingFallback.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Logo, LogoText } from '@/assets/Logo'\nimport {\n  Sidebar as SidebarComponent,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarInset,\n  SidebarProvider,\n} from '@/components/ui/sidebar'\nimport { motion } from 'framer-motion'\nimport { Loader2 } from 'lucide-react'\nimport { useEffect, useState } from 'react'\nimport { Skeleton } from './ui/skeleton'\n\nconst LoadingFallback = () => {\n  const [showLongLoadingMessage, setShowLongLoadingMessage] = useState(false)\n\n  useEffect(() => {\n    const timer = setTimeout(() => {\n      setShowLongLoadingMessage(true)\n    }, 5_000)\n\n    return () => clearTimeout(timer)\n  }, [])\n\n  return (\n    <SidebarProvider isBannerVisible={false}>\n      <SidebarComponent isBannerVisible={false} collapsible=\"icon\">\n        <SidebarContent>\n          <SidebarGroup>\n            <div className=\"flex justify-between items-center gap-2 px-2 mb-2 h-12\">\n              <div className=\"flex items-center gap-2 group-data-[state=collapsed]:hidden text-primary\">\n                <Logo />\n                <LogoText />\n              </div>\n            </div>\n\n            <Skeleton className=\"w-full h-8 mb-2\" />\n\n            <div className=\"flex flex-col gap-2\">\n              <Skeleton className=\"w-full h-8\" />\n              <Skeleton className=\"w-full h-8\" />\n              <Skeleton className=\"w-full h-8\" />\n              <Skeleton className=\"w-full h-8\" />\n              <Skeleton className=\"w-full h-8\" />\n            </div>\n          </SidebarGroup>\n        </SidebarContent>\n        <SidebarFooter>\n          <div className=\"flex flex-col gap-2\">\n            <Skeleton className=\"w-full h-8\" />\n            <Skeleton className=\"w-full h-8\" />\n            <Skeleton className=\"w-full h-8\" />\n          </div>\n        </SidebarFooter>\n      </SidebarComponent>\n      <SidebarInset className=\"overflow-hidden\">\n        <div className=\"absolute inset-0 p-6 bg-background z-[3]\">\n          <div className=\"flex items-center justify-center h-full flex-col gap-2\">\n            <Loader2 className=\"w-8 h-8 animate-spin\" />\n            <motion.div\n              initial={{ opacity: 0, y: 10 }}\n              animate={showLongLoadingMessage ? { opacity: 1, y: 0 } : { opacity: 0, y: 10 }}\n              transition={{ duration: 0.35 }}\n            >\n              <p className=\"text-sm text-muted-foreground text-center\">This is taking longer than expected...</p>\n              <p className=\"text-sm text-muted-foreground text-center\">\n                If this issue persists, contact us at{' '}\n                <a href=\"mailto:support@daytona.io\" className=\"text-primary underline\">\n                  support@daytona.io\n                </a>\n                .\n              </p>\n            </motion.div>\n          </div>\n        </div>\n      </SidebarInset>\n    </SidebarProvider>\n  )\n}\n\nexport default LoadingFallback\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationMembers/CancelOrganizationInvitationDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\n\ninterface CancelOrganizationInvitationDialogProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onCancelInvitation: () => Promise<boolean>\n  loading: boolean\n}\n\nexport const CancelOrganizationInvitationDialog: React.FC<CancelOrganizationInvitationDialogProps> = ({\n  open,\n  onOpenChange,\n  onCancelInvitation,\n  loading,\n}) => {\n  const handleCancelInvitation = async () => {\n    const success = await onCancelInvitation()\n    if (success) {\n      onOpenChange(false)\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Cancel Invitation</DialogTitle>\n          <DialogDescription>\n            Are you sure you want to cancel this invitation to join the organization?\n          </DialogDescription>\n        </DialogHeader>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Confirming...\n            </Button>\n          ) : (\n            <Button variant=\"destructive\" onClick={handleCancelInvitation}>\n              Confirm\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationMembers/CreateOrganizationInvitationDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ViewerOrganizationRoleCheckbox } from '@/components/OrganizationMembers/ViewerOrganizationRoleCheckbox'\nimport { Button } from '@/components/ui/button'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'\nimport { CreateOrganizationInvitationRoleEnum, OrganizationRole } from '@daytonaio/api-client'\nimport { Plus } from 'lucide-react'\nimport React, { useEffect, useState } from 'react'\n\ninterface CreateOrganizationInvitationDialogProps {\n  availableRoles: OrganizationRole[]\n  loadingAvailableRoles: boolean\n  onCreateInvitation: (\n    email: string,\n    role: CreateOrganizationInvitationRoleEnum,\n    assignedRoleIds: string[],\n  ) => Promise<boolean>\n  className?: string\n}\n\nexport const CreateOrganizationInvitationDialog: React.FC<CreateOrganizationInvitationDialogProps> = ({\n  availableRoles,\n  loadingAvailableRoles,\n  onCreateInvitation,\n  className,\n}) => {\n  const [open, setOpen] = useState(false)\n  const [email, setEmail] = useState('')\n  const [role, setRole] = useState<CreateOrganizationInvitationRoleEnum>(CreateOrganizationInvitationRoleEnum.MEMBER)\n  const [assignedRoleIds, setAssignedRoleIds] = useState<string[]>([])\n  const [loading, setLoading] = useState(false)\n\n  const [developerRole, setDeveloperRole] = useState<OrganizationRole | null>(null)\n\n  useEffect(() => {\n    if (!loadingAvailableRoles) {\n      const developerRole = availableRoles.find((r) => r.name === 'Developer')\n      if (developerRole) {\n        setDeveloperRole(developerRole)\n        setAssignedRoleIds([developerRole.id])\n      }\n    }\n  }, [loadingAvailableRoles, availableRoles])\n\n  const handleRoleAssignmentToggle = (roleId: string) => {\n    setAssignedRoleIds((current) => {\n      if (current.includes(roleId)) {\n        return current.filter((p) => p !== roleId)\n      } else {\n        return [...current, roleId]\n      }\n    })\n  }\n\n  const handleCreateInvitation = async () => {\n    setLoading(true)\n    const success = await onCreateInvitation(\n      email,\n      role,\n      role === CreateOrganizationInvitationRoleEnum.OWNER ? [] : assignedRoleIds,\n    )\n    if (success) {\n      setOpen(false)\n      setEmail('')\n      setRole(CreateOrganizationInvitationRoleEnum.MEMBER)\n      if (developerRole) {\n        setAssignedRoleIds([developerRole.id])\n      } else {\n        setAssignedRoleIds([])\n      }\n    }\n    setLoading(false)\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        setOpen(isOpen)\n        if (!isOpen) {\n          setEmail('')\n          setRole(CreateOrganizationInvitationRoleEnum.MEMBER)\n          if (developerRole) {\n            setAssignedRoleIds([developerRole.id])\n          } else {\n            setAssignedRoleIds([])\n          }\n        }\n      }}\n    >\n      <DialogTrigger asChild>\n        <Button variant=\"default\" size=\"sm\" className={className} title=\"Add Registry\">\n          <Plus className=\"w-4 h-4\" />\n          Invite Member\n        </Button>\n      </DialogTrigger>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Invite Member</DialogTitle>\n          <DialogDescription>\n            Give them access to the organization with an appropriate role and assignments.\n          </DialogDescription>\n        </DialogHeader>\n        <form\n          id=\"invitation-form\"\n          className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n          onSubmit={async (e) => {\n            e.preventDefault()\n            await handleCreateInvitation()\n          }}\n        >\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"email\">Email</Label>\n            <Input\n              id=\"email\"\n              value={email}\n              type=\"email\"\n              onChange={(e) => setEmail(e.target.value)}\n              placeholder=\"mail@example.com\"\n            />\n          </div>\n\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"role\">Role</Label>\n            <RadioGroup\n              className=\"gap-6\"\n              value={role}\n              onValueChange={(value: CreateOrganizationInvitationRoleEnum) => setRole(value)}\n            >\n              <div className=\"flex items-center space-x-4\">\n                <RadioGroupItem value={CreateOrganizationInvitationRoleEnum.OWNER} id=\"role-owner\" />\n                <div className=\"space-y-1\">\n                  <Label htmlFor=\"role-owner\" className=\"font-normal\">\n                    Owner\n                  </Label>\n                  <p className=\"text-sm text-gray-500\">\n                    Full administrative access to the organization and its resources\n                  </p>\n                </div>\n              </div>\n              <div className=\"flex items-center space-x-4\">\n                <RadioGroupItem value={CreateOrganizationInvitationRoleEnum.MEMBER} id=\"role-member\" />\n                <div className=\"space-y-1\">\n                  <Label htmlFor=\"role-member\" className=\"font-normal\">\n                    Member\n                  </Label>\n                  <p className=\"text-sm text-gray-500\">Access to organization resources is based on assignments</p>\n                </div>\n              </div>\n            </RadioGroup>\n          </div>\n\n          {role === CreateOrganizationInvitationRoleEnum.MEMBER && !loadingAvailableRoles && (\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"assignments\">Assignments</Label>\n              <div className=\"space-y-6\">\n                <ViewerOrganizationRoleCheckbox />\n                {availableRoles.map((availableRole) => (\n                  <div key={availableRole.id} className=\"flex items-center space-x-4\">\n                    <Checkbox\n                      id={`role-${availableRole.id}`}\n                      checked={assignedRoleIds.includes(availableRole.id)}\n                      onCheckedChange={() => handleRoleAssignmentToggle(availableRole.id)}\n                    />\n                    <div className=\"space-y-1\">\n                      <Label htmlFor={`role-${availableRole.id}`} className=\"font-normal\">\n                        {availableRole.name}\n                      </Label>\n                      {availableRole.description && (\n                        <p className=\"text-sm text-gray-500\">{availableRole.description}</p>\n                      )}\n                    </div>\n                  </div>\n                ))}\n              </div>\n            </div>\n          )}\n        </form>\n\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Inviting...\n            </Button>\n          ) : (\n            <Button type=\"submit\" form=\"invitation-form\" variant=\"default\" disabled={!email.trim()}>\n              Invite\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationMembers/OrganizationInvitationTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useState } from 'react'\nimport { MoreHorizontal } from 'lucide-react'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { OrganizationInvitation, OrganizationRole, UpdateOrganizationInvitationRoleEnum } from '@daytonaio/api-client'\nimport { Pagination } from '@/components/Pagination'\nimport { Button } from '@/components/ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'\nimport { TableHeader, TableRow, TableHead, TableBody, TableCell, Table } from '@/components/ui/table'\nimport { CancelOrganizationInvitationDialog } from '@/components/OrganizationMembers/CancelOrganizationInvitationDialog'\nimport { UpdateOrganizationInvitationDialog } from './UpdateOrganizationInvitationDialog'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { TableEmptyState } from '../TableEmptyState'\n\ninterface DataTableProps {\n  data: OrganizationInvitation[]\n  loadingData: boolean\n  availableRoles: OrganizationRole[]\n  loadingAvailableRoles: boolean\n  onCancelInvitation: (invitationId: string) => Promise<boolean>\n  onUpdateInvitation: (\n    invitationId: string,\n    role: UpdateOrganizationInvitationRoleEnum,\n    assignedRoleIds: string[],\n  ) => Promise<boolean>\n  loadingInvitationAction: Record<string, boolean>\n}\n\nexport function OrganizationInvitationTable({\n  data,\n  loadingData,\n  availableRoles,\n  loadingAvailableRoles,\n  onCancelInvitation,\n  onUpdateInvitation,\n  loadingInvitationAction,\n}: DataTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [invitationToCancel, setInvitationToCancel] = useState<string | null>(null)\n  const [isCancelDialogOpen, setIsCancelDialogOpen] = useState(false)\n  const [invitationToUpdate, setInvitationToUpdate] = useState<OrganizationInvitation | null>(null)\n  const [isUpdateDialogOpen, setIsUpdateDialogOpen] = useState(false)\n\n  const handleCancel = (invitationId: string) => {\n    setInvitationToCancel(invitationId)\n    setIsCancelDialogOpen(true)\n  }\n\n  const handleUpdate = (invitation: OrganizationInvitation) => {\n    setInvitationToUpdate(invitation)\n    setIsUpdateDialogOpen(true)\n  }\n\n  const handleConfirmCancel = async () => {\n    if (invitationToCancel) {\n      const success = await onCancelInvitation(invitationToCancel)\n      if (success) {\n        setInvitationToCancel(null)\n        setIsCancelDialogOpen(false)\n      }\n      return success\n    }\n    return false\n  }\n\n  const handleConfirmUpdate = async (role: UpdateOrganizationInvitationRoleEnum, assignedRoleIds: string[]) => {\n    if (invitationToUpdate) {\n      const success = await onUpdateInvitation(invitationToUpdate.id, role, assignedRoleIds)\n      if (success) {\n        setInvitationToUpdate(null)\n        setIsUpdateDialogOpen(false)\n      }\n      return success\n    }\n    return false\n  }\n\n  const columns = getColumns({ onCancel: handleCancel, onUpdate: handleUpdate })\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    state: {\n      sorting,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  return (\n    <>\n      <div>\n        <div className=\"rounded-md border\">\n          <Table>\n            <TableHeader>\n              {table.getHeaderGroups().map((headerGroup) => (\n                <TableRow key={headerGroup.id}>\n                  {headerGroup.headers.map((header) => {\n                    return (\n                      <TableHead key={header.id}>\n                        {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                      </TableHead>\n                    )\n                  })}\n                </TableRow>\n              ))}\n            </TableHeader>\n            <TableBody>\n              {loadingData ? (\n                <TableRow>\n                  <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                    Loading...\n                  </TableCell>\n                </TableRow>\n              ) : table.getRowModel().rows?.length ? (\n                table.getRowModel().rows.map((row) => (\n                  <TableRow\n                    key={row.id}\n                    data-state={row.getIsSelected() && 'selected'}\n                    className={`h-14 ${loadingInvitationAction[row.original.id] ? 'opacity-50 pointer-events-none' : ''}`}\n                  >\n                    {row.getVisibleCells().map((cell) => (\n                      <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>\n                    ))}\n                  </TableRow>\n                ))\n              ) : (\n                <TableEmptyState colSpan={columns.length} message=\"No Invitations found.\" />\n              )}\n            </TableBody>\n          </Table>\n        </div>\n        <Pagination table={table} className=\"mt-4\" entityName=\"Invitations\" />\n      </div>\n\n      {invitationToUpdate && (\n        <UpdateOrganizationInvitationDialog\n          open={isUpdateDialogOpen}\n          onOpenChange={(open) => {\n            setIsUpdateDialogOpen(open)\n            if (!open) {\n              setInvitationToUpdate(null)\n            }\n          }}\n          invitation={invitationToUpdate}\n          availableRoles={availableRoles}\n          loadingAvailableRoles={loadingAvailableRoles}\n          onUpdateInvitation={handleConfirmUpdate}\n        />\n      )}\n\n      {invitationToCancel && (\n        <CancelOrganizationInvitationDialog\n          open={isCancelDialogOpen}\n          onOpenChange={(open) => {\n            setIsCancelDialogOpen(open)\n            if (!open) {\n              setInvitationToCancel(null)\n            }\n          }}\n          onCancelInvitation={handleConfirmCancel}\n          loading={loadingInvitationAction[invitationToCancel]}\n        />\n      )}\n    </>\n  )\n}\n\nconst getColumns = ({\n  onCancel,\n  onUpdate,\n}: {\n  onCancel: (invitationId: string) => void\n  onUpdate: (invitation: OrganizationInvitation) => void\n}): ColumnDef<OrganizationInvitation>[] => {\n  const columns: ColumnDef<OrganizationInvitation>[] = [\n    {\n      accessorKey: 'email',\n      header: 'Email',\n    },\n    {\n      accessorKey: 'invitedBy',\n      header: 'Invited by',\n    },\n    {\n      accessorKey: 'expiresAt',\n      header: 'Expires',\n      cell: ({ row }) => {\n        return new Date(row.original.expiresAt).toLocaleDateString()\n      },\n    },\n    {\n      accessorKey: 'status',\n      header: 'Status',\n      cell: ({ row }) => {\n        const isExpired = new Date(row.original.expiresAt) < new Date()\n        return isExpired ? <span className=\"text-red-600 dark:text-red-400\">Expired</span> : 'Pending'\n      },\n    },\n    {\n      id: 'actions',\n      cell: ({ row }) => {\n        const isExpired = new Date(row.original.expiresAt) < new Date()\n        if (isExpired) {\n          return null\n        }\n        return (\n          <div className=\"text-right\">\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button variant=\"ghost\" className=\"h-8 w-8 p-0\">\n                  <span className=\"sr-only\">Open menu</span>\n                  <MoreHorizontal className=\"h-4 w-4\" />\n                </Button>\n              </DropdownMenuTrigger>\n\n              <DropdownMenuContent align=\"end\">\n                <DropdownMenuItem className=\"cursor-pointer\" onClick={() => onUpdate(row.original)}>\n                  Edit\n                </DropdownMenuItem>\n                <DropdownMenuItem\n                  className=\"cursor-pointer text-red-600 dark:text-red-400\"\n                  onClick={() => onCancel(row.original.id)}\n                >\n                  Cancel\n                </DropdownMenuItem>\n              </DropdownMenuContent>\n            </DropdownMenu>\n          </div>\n        )\n      },\n    },\n  ]\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationMembers/OrganizationMemberTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useState } from 'react'\nimport { MoreHorizontal } from 'lucide-react'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { OrganizationRole, OrganizationUser, OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport { Pagination } from '@/components/Pagination'\nimport { Button } from '@/components/ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'\nimport { TableHeader, TableRow, TableHead, TableBody, TableCell, Table } from '@/components/ui/table'\nimport { RemoveOrganizationMemberDialog } from '@/components/OrganizationMembers/RemoveOrganizationMemberDialog'\nimport { UpdateOrganizationMemberAccess } from '@/components/OrganizationMembers/UpdateOrganizationMemberAccessDialog'\nimport { capitalize } from '@/lib/utils'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { TableEmptyState } from '../TableEmptyState'\n\ninterface DataTableProps {\n  data: OrganizationUser[]\n  loadingData: boolean\n  availableAssignments: OrganizationRole[]\n  loadingAvailableAssignments: boolean\n  onUpdateMemberAccess: (userId: string, role: OrganizationUserRoleEnum, assignedRoleIds: string[]) => Promise<boolean>\n  onRemoveMember: (userId: string) => Promise<boolean>\n  loadingMemberAction: Record<string, boolean>\n  ownerMode: boolean\n}\n\nexport function OrganizationMemberTable({\n  data,\n  loadingData,\n  availableAssignments,\n  loadingAvailableAssignments,\n  onUpdateMemberAccess,\n  onRemoveMember,\n  loadingMemberAction,\n  ownerMode,\n}: DataTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [memberToUpdate, setMemberToUpdate] = useState<OrganizationUser | null>(null)\n  const [isUpdateMemberAccessDialogOpen, setIsUpdateMemberAccessDialogOpen] = useState(false)\n  const [memberToRemove, setMemberToRemove] = useState<string | null>(null)\n  const [isRemoveDialogOpen, setIsRemoveDialogOpen] = useState(false)\n\n  const columns = getColumns({\n    onUpdateMemberRole: (member) => {\n      setMemberToUpdate(member)\n      setIsUpdateMemberAccessDialogOpen(true)\n    },\n    onUpdateAssignedRoles: (member) => {\n      setMemberToUpdate(member)\n      setIsUpdateMemberAccessDialogOpen(true)\n    },\n    onRemove: (userId: string) => {\n      setMemberToRemove(userId)\n      setIsRemoveDialogOpen(true)\n    },\n    ownerMode,\n  })\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    state: {\n      sorting,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  const handleUpdateMemberAccess = async (role: OrganizationUserRoleEnum, assignedRoleIds: string[]) => {\n    if (memberToUpdate) {\n      const success = await onUpdateMemberAccess(memberToUpdate.userId, role, assignedRoleIds)\n      if (success) {\n        setMemberToUpdate(null)\n        setIsUpdateMemberAccessDialogOpen(false)\n      }\n      return success\n    }\n    return false\n  }\n\n  const handleConfirmRemove = async () => {\n    if (memberToRemove) {\n      const success = await onRemoveMember(memberToRemove)\n      if (success) {\n        setMemberToRemove(null)\n        setIsRemoveDialogOpen(false)\n      }\n      return success\n    }\n    return false\n  }\n\n  return (\n    <>\n      <div>\n        <div className=\"rounded-md border\">\n          <Table>\n            <TableHeader>\n              {table.getHeaderGroups().map((headerGroup) => (\n                <TableRow key={headerGroup.id}>\n                  {headerGroup.headers.map((header) => {\n                    return (\n                      <TableHead key={header.id}>\n                        {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                      </TableHead>\n                    )\n                  })}\n                </TableRow>\n              ))}\n            </TableHeader>\n            <TableBody>\n              {loadingData ? (\n                <TableRow>\n                  <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                    Loading...\n                  </TableCell>\n                </TableRow>\n              ) : table.getRowModel().rows?.length ? (\n                table.getRowModel().rows.map((row) => (\n                  <TableRow\n                    key={row.id}\n                    data-state={row.getIsSelected() && 'selected'}\n                    className={`h-14 ${loadingMemberAction[row.original.userId] ? 'opacity-50 pointer-events-none' : ''}`}\n                  >\n                    {row.getVisibleCells().map((cell) => (\n                      <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>\n                    ))}\n                  </TableRow>\n                ))\n              ) : (\n                <TableEmptyState colSpan={columns.length} message=\"No Members found.\" />\n              )}\n            </TableBody>\n          </Table>\n        </div>\n        <Pagination table={table} className=\"mt-4\" entityName=\"Members\" />\n      </div>\n\n      {memberToUpdate && (\n        <UpdateOrganizationMemberAccess\n          open={isUpdateMemberAccessDialogOpen}\n          onOpenChange={(open) => {\n            setIsUpdateMemberAccessDialogOpen(open)\n            if (!open) {\n              setMemberToUpdate(null)\n            }\n          }}\n          initialRole={memberToUpdate.role}\n          initialAssignments={memberToUpdate.assignedRoles}\n          availableAssignments={availableAssignments}\n          loadingAvailableAssignments={loadingAvailableAssignments}\n          onUpdateAccess={handleUpdateMemberAccess}\n          processingUpdateAccess={loadingMemberAction[memberToUpdate.userId]}\n        />\n      )}\n\n      {memberToRemove && (\n        <RemoveOrganizationMemberDialog\n          open={isRemoveDialogOpen}\n          onOpenChange={(open) => {\n            setIsRemoveDialogOpen(open)\n            if (!open) {\n              setMemberToRemove(null)\n            }\n          }}\n          onRemoveMember={handleConfirmRemove}\n          loading={loadingMemberAction[memberToRemove]}\n        />\n      )}\n    </>\n  )\n}\n\nconst getColumns = ({\n  onUpdateMemberRole,\n  onUpdateAssignedRoles,\n  onRemove,\n  ownerMode,\n}: {\n  onUpdateMemberRole: (member: OrganizationUser) => void\n  onUpdateAssignedRoles: (member: OrganizationUser) => void\n  onRemove: (userId: string) => void\n  ownerMode: boolean\n}): ColumnDef<OrganizationUser>[] => {\n  const columns: ColumnDef<OrganizationUser>[] = [\n    {\n      accessorKey: 'email',\n      header: 'Email',\n    },\n    {\n      accessorKey: 'role',\n      header: () => {\n        return <div className=\"px-3 w-24\">Role</div>\n      },\n      cell: ({ row }) => {\n        const role = capitalize(row.original.role)\n\n        if (!ownerMode) {\n          return <div className=\"px-3 text-sm\">{role}</div>\n        }\n\n        return (\n          <Button variant=\"ghost\" className=\"w-auto px-3\" onClick={() => onUpdateMemberRole(row.original)}>\n            {role}\n          </Button>\n        )\n      },\n    },\n  ]\n\n  if (ownerMode) {\n    const extraColumns: ColumnDef<OrganizationUser>[] = [\n      {\n        accessorKey: 'assignedRoles',\n        header: () => {\n          return <div className=\"px-3 w-32\">Assignments</div>\n        },\n        cell: ({ row }) => {\n          if (row.original.role === OrganizationUserRoleEnum.OWNER) {\n            return <div className=\"px-3 text-sm text-muted-foreground\">Full Access</div>\n          }\n\n          const roleCount = row.original.assignedRoles?.length || 0\n          const roleText = roleCount === 1 ? '1 role' : `${roleCount} roles`\n\n          return (\n            <Button variant=\"ghost\" className=\"w-auto px-3\" onClick={() => onUpdateAssignedRoles(row.original)}>\n              {roleText}\n            </Button>\n          )\n        },\n      },\n      {\n        id: 'actions',\n        cell: ({ row }) => {\n          return (\n            <div className=\"text-right\">\n              <DropdownMenu>\n                <DropdownMenuTrigger asChild>\n                  <Button variant=\"ghost\" className=\"h-8 w-8 p-0\">\n                    <span className=\"sr-only\">Open menu</span>\n                    <MoreHorizontal className=\"h-4 w-4\" />\n                  </Button>\n                </DropdownMenuTrigger>\n\n                <DropdownMenuContent align=\"end\">\n                  <DropdownMenuItem className=\"cursor-pointer\" onClick={() => onUpdateMemberRole(row.original)}>\n                    Change Role\n                  </DropdownMenuItem>\n                  {row.original.role !== OrganizationUserRoleEnum.OWNER && (\n                    <DropdownMenuItem className=\"cursor-pointer\" onClick={() => onUpdateAssignedRoles(row.original)}>\n                      Manage Assignments\n                    </DropdownMenuItem>\n                  )}\n                  <DropdownMenuItem\n                    className=\"cursor-pointer text-red-600 dark:text-red-400\"\n                    onClick={() => onRemove(row.original.userId)}\n                  >\n                    Remove\n                  </DropdownMenuItem>\n                </DropdownMenuContent>\n              </DropdownMenu>\n            </div>\n          )\n        },\n      },\n    ]\n    columns.push(...extraColumns)\n  }\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationMembers/RemoveOrganizationMemberDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\n\ninterface RemoveOrganizationMemberDialogProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onRemoveMember: () => Promise<boolean>\n  loading: boolean\n}\n\nexport const RemoveOrganizationMemberDialog: React.FC<RemoveOrganizationMemberDialogProps> = ({\n  open,\n  onOpenChange,\n  onRemoveMember,\n  loading,\n}) => {\n  const handleRemoveMember = async () => {\n    const success = await onRemoveMember()\n    if (success) {\n      onOpenChange(false)\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Remove Member</DialogTitle>\n          <DialogDescription>\n            Are you sure you want to remove this member from the organization? Any API keys they have created will\n            become ineffective.\n          </DialogDescription>\n        </DialogHeader>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Removing...\n            </Button>\n          ) : (\n            <Button variant=\"destructive\" onClick={handleRemoveMember}>\n              Remove\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationMembers/UpdateOrganizationInvitationDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState } from 'react'\nimport {\n  UpdateOrganizationInvitationRoleEnum,\n  OrganizationRole,\n  OrganizationInvitation,\n  OrganizationInvitationRoleEnum,\n} from '@daytonaio/api-client'\nimport { Button } from '@/components/ui/button'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'\nimport { ViewerOrganizationRoleCheckbox } from '@/components/OrganizationMembers/ViewerOrganizationRoleCheckbox'\n\ninterface UpdateOrganizationInvitationDialogProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  invitation: OrganizationInvitation\n  availableRoles: OrganizationRole[]\n  loadingAvailableRoles: boolean\n  onUpdateInvitation: (role: UpdateOrganizationInvitationRoleEnum, assignedRoleIds: string[]) => Promise<boolean>\n}\n\nexport const UpdateOrganizationInvitationDialog: React.FC<UpdateOrganizationInvitationDialogProps> = ({\n  open,\n  onOpenChange,\n  invitation,\n  availableRoles,\n  loadingAvailableRoles,\n  onUpdateInvitation,\n}) => {\n  const [role, setRole] = useState<OrganizationInvitationRoleEnum>(invitation.role)\n  const [assignedRoleIds, setAssignedRoleIds] = useState<string[]>(invitation.assignedRoles.map((role) => role.id))\n  const [loading, setLoading] = useState(false)\n\n  const handleRoleAssignmentToggle = (roleId: string) => {\n    setAssignedRoleIds((current) => {\n      if (current.includes(roleId)) {\n        return current.filter((p) => p !== roleId)\n      } else {\n        return [...current, roleId]\n      }\n    })\n  }\n\n  const handleUpdateInvitation = async () => {\n    setLoading(true)\n    const success = await onUpdateInvitation(role, role === OrganizationInvitationRoleEnum.OWNER ? [] : assignedRoleIds)\n    if (success) {\n      onOpenChange(false)\n      setRole(invitation.role)\n      setAssignedRoleIds(invitation.assignedRoles.map((role) => role.id))\n    }\n    setLoading(false)\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        onOpenChange(isOpen)\n        if (!isOpen) {\n          setRole(invitation.role)\n          setRole(invitation.role)\n          setAssignedRoleIds(invitation.assignedRoles.map((role) => role.id))\n        }\n      }}\n    >\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Update Invitation</DialogTitle>\n          <DialogDescription>Modify organization access for the invited member.</DialogDescription>\n        </DialogHeader>\n        <div className=\"space-y-6 overflow-y-auto px-1 pb-1\">\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"email\">Email</Label>\n            <Input value={invitation.email} type=\"email\" disabled readOnly />\n          </div>\n\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"role\">Role</Label>\n            <RadioGroup\n              className=\"gap-6\"\n              value={role}\n              onValueChange={(value: OrganizationInvitationRoleEnum) => setRole(value)}\n            >\n              <div className=\"flex items-center space-x-4\">\n                <RadioGroupItem value={OrganizationInvitationRoleEnum.OWNER} id=\"role-owner\" />\n                <div className=\"space-y-1\">\n                  <Label htmlFor=\"role-owner\" className=\"font-normal\">\n                    Owner\n                  </Label>\n                  <p className=\"text-sm text-gray-500\">\n                    Full administrative access to the organization and its resources\n                  </p>\n                </div>\n              </div>\n              <div className=\"flex items-center space-x-4\">\n                <RadioGroupItem value={OrganizationInvitationRoleEnum.MEMBER} id=\"role-member\" />\n                <div className=\"space-y-1\">\n                  <Label htmlFor=\"role-member\" className=\"font-normal\">\n                    Member\n                  </Label>\n                  <p className=\"text-sm text-gray-500\">Access to organization resources is based on assignments</p>\n                </div>\n              </div>\n            </RadioGroup>\n          </div>\n\n          {role === OrganizationInvitationRoleEnum.MEMBER && !loadingAvailableRoles && (\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"assignments\">Assignments</Label>\n              <div className=\"space-y-6\">\n                <ViewerOrganizationRoleCheckbox />\n                {availableRoles.map((availableRole) => (\n                  <div key={availableRole.id} className=\"flex items-center space-x-4\">\n                    <Checkbox\n                      id={`role-${availableRole.id}`}\n                      checked={assignedRoleIds.includes(availableRole.id)}\n                      onCheckedChange={() => handleRoleAssignmentToggle(availableRole.id)}\n                    />\n                    <div className=\"space-y-1\">\n                      <Label htmlFor={`role-${availableRole.id}`} className=\"font-normal\">\n                        {availableRole.name}\n                      </Label>\n                      {availableRole.description && (\n                        <p className=\"text-sm text-gray-500\">{availableRole.description}</p>\n                      )}\n                    </div>\n                  </div>\n                ))}\n              </div>\n            </div>\n          )}\n        </div>\n\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Updating...\n            </Button>\n          ) : (\n            <Button type=\"button\" variant=\"default\" onClick={handleUpdateInvitation}>\n              Update\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationMembers/UpdateOrganizationMemberAccessDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState } from 'react'\nimport { CreateOrganizationInvitationRoleEnum, OrganizationRole, OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport { Button } from '@/components/ui/button'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Label } from '@/components/ui/label'\nimport { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'\nimport { ViewerOrganizationRoleCheckbox } from '@/components/OrganizationMembers/ViewerOrganizationRoleCheckbox'\n\ninterface UpdateOrganizationMemberAccessProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  initialRole: OrganizationUserRoleEnum\n  initialAssignments: OrganizationRole[]\n  availableAssignments: OrganizationRole[]\n  loadingAvailableAssignments: boolean\n  onUpdateAccess: (role: OrganizationUserRoleEnum, assignedRoleIds: string[]) => Promise<boolean>\n  processingUpdateAccess: boolean\n}\n\nexport const UpdateOrganizationMemberAccess: React.FC<UpdateOrganizationMemberAccessProps> = ({\n  open,\n  onOpenChange,\n  initialRole,\n  initialAssignments,\n  availableAssignments,\n  loadingAvailableAssignments,\n  onUpdateAccess,\n  processingUpdateAccess,\n}) => {\n  const [role, setRole] = useState<OrganizationUserRoleEnum>(initialRole)\n  const [assignedRoleIds, setAssignedRoleIds] = useState<string[]>(initialAssignments.map((a) => a.id))\n\n  const handleRoleAssignmentToggle = (roleId: string) => {\n    setAssignedRoleIds((current) => {\n      if (current.includes(roleId)) {\n        return current.filter((p) => p !== roleId)\n      } else {\n        return [...current, roleId]\n      }\n    })\n  }\n\n  const handleUpdateAccess = async () => {\n    const success = await onUpdateAccess(role, role === OrganizationUserRoleEnum.OWNER ? [] : assignedRoleIds)\n    if (success) {\n      onOpenChange(false)\n      setRole(initialRole)\n      setAssignedRoleIds(initialAssignments.map((a) => a.id))\n    }\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        onOpenChange(isOpen)\n        if (!isOpen) {\n          setRole(initialRole)\n          setAssignedRoleIds(initialAssignments.map((a) => a.id))\n        }\n      }}\n    >\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Update Access</DialogTitle>\n          <DialogDescription>\n            Manage access to the organization with an appropriate role and assignments.\n          </DialogDescription>\n          {role !== OrganizationUserRoleEnum.OWNER && (\n            <DialogDescription className=\"text-yellow-600 dark:text-yellow-400\">\n              Removing assignments will automatically revoke any API keys this member created using permissions granted\n              from those assignments.\n            </DialogDescription>\n          )}\n        </DialogHeader>\n        <form\n          id=\"update-access-form\"\n          className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n          onSubmit={async (e) => {\n            e.preventDefault()\n            await handleUpdateAccess()\n          }}\n        >\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"role\">Role</Label>\n            <RadioGroup\n              className=\"gap-6\"\n              value={role}\n              onValueChange={(value: CreateOrganizationInvitationRoleEnum) => setRole(value)}\n            >\n              <div className=\"flex items-center space-x-4\">\n                <RadioGroupItem value={CreateOrganizationInvitationRoleEnum.OWNER} id=\"role-owner\" />\n                <div className=\"space-y-1\">\n                  <Label htmlFor=\"role-owner\" className=\"font-normal\">\n                    Owner\n                  </Label>\n                  <p className=\"text-sm text-gray-500\">\n                    Full administrative access to the organization and its resources\n                  </p>\n                </div>\n              </div>\n              <div className=\"flex items-center space-x-4\">\n                <RadioGroupItem value={CreateOrganizationInvitationRoleEnum.MEMBER} id=\"role-member\" />\n                <div className=\"space-y-1\">\n                  <Label htmlFor=\"role-member\" className=\"font-normal\">\n                    Member\n                  </Label>\n                  <p className=\"text-sm text-gray-500\">Access to organization resources is based on assignments</p>\n                </div>\n              </div>\n            </RadioGroup>\n          </div>\n\n          {role === CreateOrganizationInvitationRoleEnum.MEMBER &&\n            !loadingAvailableAssignments &&\n            availableAssignments.length > 0 && (\n              <div className=\"space-y-3\">\n                <Label htmlFor=\"assignments\">Assignments</Label>\n                <div className=\"space-y-6\">\n                  <ViewerOrganizationRoleCheckbox />\n                  {availableAssignments.map((assignment) => (\n                    <div key={assignment.id} className=\"flex items-center space-x-4\">\n                      <Checkbox\n                        id={`role-${assignment.id}`}\n                        checked={assignedRoleIds.includes(assignment.id)}\n                        onCheckedChange={() => handleRoleAssignmentToggle(assignment.id)}\n                      />\n                      <div className=\"space-y-1\">\n                        <Label htmlFor={`role-${assignment.id}`} className=\"font-normal\">\n                          {assignment.name}\n                        </Label>\n                        {assignment.description && <p className=\"text-sm text-gray-500\">{assignment.description}</p>}\n                      </div>\n                    </div>\n                  ))}\n                </div>\n              </div>\n            )}\n        </form>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={processingUpdateAccess}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {processingUpdateAccess ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Saving...\n            </Button>\n          ) : (\n            <Button type=\"submit\" form=\"update-access-form\" variant=\"default\" disabled={loadingAvailableAssignments}>\n              Save\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationMembers/ViewerOrganizationRoleCheckbox.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport { Label } from '@/components/ui/label'\n\nexport const ViewerOrganizationRoleCheckbox: React.FC = () => {\n  return (\n    <div className=\"flex items-center space-x-4\">\n      <Checkbox id=\"role-viewer\" checked={true} disabled={true} />\n      <div className=\"space-y-1\">\n        <Label htmlFor=\"role-viewer\" className=\"font-normal\">\n          Viewer\n        </Label>\n        <p className=\"text-sm text-gray-500\">\n          Grants read access to sandboxes, snapshots, and registries in the organization\n        </p>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationRoles/CreateOrganizationRoleDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { ORGANIZATION_ROLE_PERMISSIONS_GROUPS } from '@/constants/OrganizationPermissionsGroups'\nimport { OrganizationRolePermissionGroup } from '@/types/OrganizationRolePermissionGroup'\nimport { OrganizationRolePermissionsEnum } from '@daytonaio/api-client'\nimport { Plus } from 'lucide-react'\nimport React, { useState } from 'react'\n\ninterface CreateOrganizationRoleDialogProps {\n  onCreateRole: (name: string, description: string, permissions: OrganizationRolePermissionsEnum[]) => Promise<boolean>\n  className?: string\n}\n\nexport const CreateOrganizationRoleDialog: React.FC<CreateOrganizationRoleDialogProps> = ({\n  onCreateRole,\n  className,\n}) => {\n  const [open, setOpen] = useState(false)\n  const [name, setName] = useState('')\n  const [description, setDescription] = useState('')\n  const [permissions, setPermissions] = useState<OrganizationRolePermissionsEnum[]>([])\n  const [loading, setLoading] = useState(false)\n\n  const handleCreateRole = async () => {\n    setLoading(true)\n    const success = await onCreateRole(name, description, permissions)\n    if (success) {\n      setOpen(false)\n      setName('')\n      setDescription('')\n      setPermissions([])\n    }\n    setLoading(false)\n  }\n\n  const isGroupChecked = (group: OrganizationRolePermissionGroup) => {\n    return group.permissions.every((permission) => permissions.includes(permission))\n  }\n\n  // Toggle all permissions in a group\n  const handleGroupToggle = (group: OrganizationRolePermissionGroup) => {\n    if (isGroupChecked(group)) {\n      // If all checked, uncheck all\n      setPermissions((current) => current.filter((p) => !group.permissions.includes(p)))\n    } else {\n      // If not all checked, check all\n      setPermissions((current) => {\n        const newPermissions = [...current]\n        group.permissions.forEach((key) => {\n          if (!newPermissions.includes(key)) {\n            newPermissions.push(key)\n          }\n        })\n        return newPermissions\n      })\n    }\n  }\n\n  // Toggle a single permission\n  const handlePermissionToggle = (permission: OrganizationRolePermissionsEnum) => {\n    setPermissions((current) => {\n      if (current.includes(permission)) {\n        return current.filter((p) => p !== permission)\n      } else {\n        return [...current, permission]\n      }\n    })\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        setOpen(isOpen)\n        if (!isOpen) {\n          setName('')\n          setDescription('')\n          setPermissions([])\n        }\n      }}\n    >\n      <DialogTrigger asChild>\n        <Button variant=\"default\" size=\"sm\" className={className} title=\"Add Registry\">\n          <Plus className=\"w-4 h-4\" />\n          Create Role\n        </Button>\n      </DialogTrigger>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Create Role</DialogTitle>\n          <DialogDescription>Define a custom role for managing access to the organization.</DialogDescription>\n        </DialogHeader>\n        <form\n          id=\"create-role-form\"\n          className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n          onSubmit={async (e) => {\n            e.preventDefault()\n            await handleCreateRole()\n          }}\n        >\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"name\">Name</Label>\n            <Input id=\"name\" value={name} onChange={(e) => setName(e.target.value)} placeholder=\"Name\" />\n          </div>\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"description\">Description</Label>\n            <Input\n              id=\"description\"\n              value={description}\n              onChange={(e) => setDescription(e.target.value)}\n              placeholder=\"Description\"\n            />\n          </div>\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"permissions\">Permissions</Label>\n            <div className=\"space-y-6\">\n              {ORGANIZATION_ROLE_PERMISSIONS_GROUPS.map((group) => {\n                const groupIsChecked = isGroupChecked(group)\n\n                return (\n                  <div key={group.name} className=\"space-y-3\">\n                    <div className=\"flex items-center space-x-2\">\n                      <Checkbox\n                        id={`group-${group.name}`}\n                        checked={groupIsChecked}\n                        onCheckedChange={() => handleGroupToggle(group)}\n                      />\n                      <Label htmlFor={`group-${group.name}`} className=\"font-normal\">\n                        {group.name}\n                      </Label>\n                    </div>\n                    <div className=\"ml-6 space-y-2\">\n                      {group.permissions.map((permission) => (\n                        <div key={permission} className=\"flex items-center space-x-2\">\n                          <Checkbox\n                            id={permission}\n                            checked={permissions.includes(permission)}\n                            onCheckedChange={() => handlePermissionToggle(permission)}\n                            disabled={groupIsChecked}\n                            className={`${groupIsChecked ? 'pointer-events-none' : ''}`}\n                          />\n                          <Label\n                            htmlFor={permission}\n                            className={`font-normal${groupIsChecked ? ' opacity-70 pointer-events-none' : ''}`}\n                          >\n                            {permission}\n                          </Label>\n                        </div>\n                      ))}\n                    </div>\n                  </div>\n                )\n              })}\n            </div>\n          </div>\n        </form>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Creating...\n            </Button>\n          ) : (\n            <Button\n              type=\"submit\"\n              form=\"create-role-form\"\n              variant=\"default\"\n              disabled={!name.trim() || !description.trim() || permissions.length === 0}\n            >\n              Create\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationRoles/DeleteOrganizationRoleDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\n\ninterface DeleteOrganizationRoleDialogProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onDeleteRole: () => Promise<boolean>\n  loading: boolean\n}\n\nexport const DeleteOrganizationRoleDialog: React.FC<DeleteOrganizationRoleDialogProps> = ({\n  open,\n  onOpenChange,\n  onDeleteRole,\n  loading,\n}) => {\n  const handleDeleteRole = async () => {\n    const success = await onDeleteRole()\n    if (success) {\n      onOpenChange(false)\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Delete Role</DialogTitle>\n          <DialogDescription>Are you sure you want to delete this role?</DialogDescription>\n        </DialogHeader>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Deleting...\n            </Button>\n          ) : (\n            <Button variant=\"destructive\" onClick={handleDeleteRole}>\n              Delete\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationRoles/OrganizationRoleTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DeleteOrganizationRoleDialog } from '@/components/OrganizationRoles/DeleteOrganizationRoleDialog'\nimport { UpdateOrganizationRoleDialog } from '@/components/OrganizationRoles/UpdateOrganizationRoleDialog'\nimport { Pagination } from '@/components/Pagination'\nimport { Button } from '@/components/ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { OrganizationRole, OrganizationRolePermissionsEnum } from '@daytonaio/api-client'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { MoreHorizontal } from 'lucide-react'\nimport { useState } from 'react'\nimport { TableEmptyState } from '../TableEmptyState'\n\ninterface DataTableProps {\n  data: OrganizationRole[]\n  loadingData: boolean\n  onUpdateRole: (\n    roleId: string,\n    name: string,\n    description: string,\n    permissions: OrganizationRolePermissionsEnum[],\n  ) => Promise<boolean>\n  onDeleteRole: (roleId: string) => Promise<boolean>\n  loadingRoleAction: Record<string, boolean>\n}\n\nexport function OrganizationRoleTable({\n  data,\n  loadingData,\n  onUpdateRole,\n  onDeleteRole,\n  loadingRoleAction,\n}: DataTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [roleToDelete, setRoleToDelete] = useState<string | null>(null)\n  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false)\n  const [roleToUpdate, setRoleToUpdate] = useState<OrganizationRole | null>(null)\n  const [isUpdateDialogOpen, setIsUpdateDialogOpen] = useState(false)\n\n  const columns = getColumns({\n    onUpdate: (role) => {\n      setRoleToUpdate(role)\n      setIsUpdateDialogOpen(true)\n    },\n    onDelete: (userId: string) => {\n      setRoleToDelete(userId)\n      setIsDeleteDialogOpen(true)\n    },\n  })\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    state: {\n      sorting,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  const handleUpdateRole = async (\n    name: string,\n    description: string,\n    permissions: OrganizationRolePermissionsEnum[],\n  ) => {\n    if (roleToUpdate) {\n      const success = await onUpdateRole(roleToUpdate.id, name, description, permissions)\n      if (success) {\n        setRoleToUpdate(null)\n        setIsUpdateDialogOpen(false)\n      }\n      return success\n    }\n    return false\n  }\n\n  const handleConfirmDeleteRole = async () => {\n    if (roleToDelete) {\n      const success = await onDeleteRole(roleToDelete)\n      if (success) {\n        setRoleToDelete(null)\n        setIsDeleteDialogOpen(false)\n      }\n      return success\n    }\n    return false\n  }\n\n  return (\n    <>\n      <div>\n        <div className=\"rounded-md border\">\n          <Table>\n            <TableHeader>\n              {table.getHeaderGroups().map((headerGroup) => (\n                <TableRow key={headerGroup.id}>\n                  {headerGroup.headers.map((header) => {\n                    return (\n                      <TableHead key={header.id}>\n                        {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                      </TableHead>\n                    )\n                  })}\n                </TableRow>\n              ))}\n            </TableHeader>\n            <TableBody>\n              {loadingData ? (\n                <TableRow>\n                  <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                    Loading...\n                  </TableCell>\n                </TableRow>\n              ) : table.getRowModel().rows?.length ? (\n                table.getRowModel().rows.map((row) => (\n                  <TableRow\n                    key={row.id}\n                    data-state={row.getIsSelected() && 'selected'}\n                    className={loadingRoleAction[row.original.id] ? 'opacity-50 pointer-events-none' : ''}\n                  >\n                    {row.getVisibleCells().map((cell) => (\n                      <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>\n                    ))}\n                  </TableRow>\n                ))\n              ) : (\n                <TableEmptyState colSpan={columns.length} message=\"No Roles found.\" />\n              )}\n            </TableBody>\n          </Table>\n        </div>\n        <Pagination table={table} className=\"mt-4\" entityName=\"Roles\" />\n      </div>\n\n      {roleToUpdate && (\n        <UpdateOrganizationRoleDialog\n          open={isUpdateDialogOpen}\n          onOpenChange={(open) => {\n            setIsUpdateDialogOpen(open)\n            if (!open) {\n              setRoleToUpdate(null)\n            }\n          }}\n          initialData={roleToUpdate}\n          onUpdateRole={handleUpdateRole}\n        />\n      )}\n\n      {roleToDelete && (\n        <DeleteOrganizationRoleDialog\n          open={isDeleteDialogOpen}\n          onOpenChange={(open) => {\n            setIsDeleteDialogOpen(open)\n            if (!open) {\n              setRoleToDelete(null)\n            }\n          }}\n          onDeleteRole={handleConfirmDeleteRole}\n          loading={loadingRoleAction[roleToDelete]}\n        />\n      )}\n    </>\n  )\n}\n\nconst getColumns = ({\n  onUpdate,\n  onDelete,\n}: {\n  onUpdate: (role: OrganizationRole) => void\n  onDelete: (roleId: string) => void\n}): ColumnDef<OrganizationRole>[] => {\n  const columns: ColumnDef<OrganizationRole>[] = [\n    {\n      accessorKey: 'name',\n      header: 'Name',\n      cell: ({ row }) => {\n        return <div className=\"min-w-48\">{row.original.name}</div>\n      },\n    },\n    {\n      accessorKey: 'description',\n      header: 'Description',\n      cell: ({ row }) => {\n        return (\n          <Tooltip>\n            <TooltipTrigger>\n              <div className=\"truncate max-w-md cursor-text\">{row.original.description}</div>\n            </TooltipTrigger>\n            <TooltipContent>\n              <p className=\"max-w-[300px]\">{row.original.description}</p>\n            </TooltipContent>\n          </Tooltip>\n        )\n      },\n    },\n    {\n      accessorKey: 'permissions',\n      header: () => {\n        return <div className=\"max-w-md px-3\">Permissions</div>\n      },\n      cell: ({ row }) => {\n        const permissions = row.original.permissions.join(', ')\n        return (\n          <Tooltip>\n            <TooltipTrigger>\n              <div className=\"truncate max-w-md px-3 cursor-text\">{permissions || '-'}</div>\n            </TooltipTrigger>\n            {permissions && (\n              <TooltipContent>\n                <p className=\"max-w-[300px]\">{permissions}</p>\n              </TooltipContent>\n            )}\n          </Tooltip>\n        )\n      },\n    },\n    {\n      id: 'actions',\n      cell: ({ row }) => {\n        if (row.original.isGlobal) {\n          return null\n        }\n        return (\n          <div className=\"text-right\">\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <Button variant=\"ghost\" className=\"h-8 w-8 p-0\">\n                  <span className=\"sr-only\">Open menu</span>\n                  <MoreHorizontal className=\"h-4 w-4\" />\n                </Button>\n              </DropdownMenuTrigger>\n\n              <DropdownMenuContent align=\"end\">\n                <DropdownMenuItem className=\"cursor-pointer\" onClick={() => onUpdate(row.original)}>\n                  Edit\n                </DropdownMenuItem>\n                <DropdownMenuItem\n                  className=\"cursor-pointer text-red-600 dark:text-red-400\"\n                  onClick={() => onDelete(row.original.id)}\n                >\n                  Delete\n                </DropdownMenuItem>\n              </DropdownMenuContent>\n            </DropdownMenu>\n          </div>\n        )\n      },\n    },\n  ]\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/OrganizationRoles/UpdateOrganizationRoleDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState } from 'react'\nimport { OrganizationRole, OrganizationRolePermissionsEnum } from '@daytonaio/api-client'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { ORGANIZATION_ROLE_PERMISSIONS_GROUPS } from '@/constants/OrganizationPermissionsGroups'\nimport { OrganizationRolePermissionGroup } from '@/types/OrganizationRolePermissionGroup'\n\ninterface UpdateOrganizationRoleDialogProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  initialData: OrganizationRole\n  onUpdateRole: (name: string, description: string, permissions: OrganizationRolePermissionsEnum[]) => Promise<boolean>\n}\n\nexport const UpdateOrganizationRoleDialog: React.FC<UpdateOrganizationRoleDialogProps> = ({\n  open,\n  onOpenChange,\n  initialData,\n  onUpdateRole,\n}) => {\n  const [name, setName] = useState(initialData.name)\n  const [description, setDescription] = useState(initialData.description)\n  const [permissions, setPermissions] = useState(initialData.permissions)\n  const [loading, setLoading] = useState(false)\n\n  const handleUpdateRole = async () => {\n    setLoading(true)\n    const success = await onUpdateRole(name, description, permissions)\n    if (success) {\n      onOpenChange(false)\n      setName('')\n      setDescription('')\n      setPermissions([])\n    }\n    setLoading(false)\n  }\n\n  const isGroupChecked = (group: OrganizationRolePermissionGroup) => {\n    return group.permissions.every((permission) => permissions.includes(permission))\n  }\n\n  // Toggle all permissions in a group\n  const handleGroupToggle = (group: OrganizationRolePermissionGroup) => {\n    if (isGroupChecked(group)) {\n      // If all checked, uncheck all\n      setPermissions((current) => current.filter((p) => !group.permissions.includes(p)))\n    } else {\n      // If not all checked, check all\n      setPermissions((current) => {\n        const newPermissions = [...current]\n        group.permissions.forEach((key) => {\n          if (!newPermissions.includes(key)) {\n            newPermissions.push(key)\n          }\n        })\n        return newPermissions\n      })\n    }\n  }\n\n  // Toggle a single permission\n  const handlePermissionToggle = (permission: OrganizationRolePermissionsEnum) => {\n    setPermissions((current) => {\n      if (current.includes(permission)) {\n        return current.filter((p) => p !== permission)\n      } else {\n        return [...current, permission]\n      }\n    })\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        onOpenChange(isOpen)\n        if (!isOpen) {\n          setName('')\n          setDescription('')\n          setPermissions([])\n        }\n      }}\n    >\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Edit Role</DialogTitle>\n          <DialogDescription>Modify permissions for the custom organization role.</DialogDescription>\n        </DialogHeader>\n        <form\n          id=\"edit-role-form\"\n          className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n          onSubmit={async (e) => {\n            e.preventDefault()\n            await handleUpdateRole()\n          }}\n        >\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"name\">Name</Label>\n            <Input id=\"name\" value={name} onChange={(e) => setName(e.target.value)} placeholder=\"Name\" />\n          </div>\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"description\">Description</Label>\n            <Input\n              id=\"description\"\n              value={description}\n              onChange={(e) => setDescription(e.target.value)}\n              placeholder=\"Description\"\n            />\n          </div>\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"permissions\">Permissions</Label>\n            <div className=\"space-y-6\">\n              {ORGANIZATION_ROLE_PERMISSIONS_GROUPS.map((group) => {\n                const groupIsChecked = isGroupChecked(group)\n\n                return (\n                  <div key={group.name} className=\"space-y-3\">\n                    <div className=\"flex items-center space-x-2\">\n                      <Checkbox\n                        id={`group-${group.name}`}\n                        checked={groupIsChecked}\n                        onCheckedChange={() => handleGroupToggle(group)}\n                      />\n                      <Label htmlFor={`group-${group.name}`} className=\"font-normal\">\n                        {group.name}\n                      </Label>\n                    </div>\n                    <div className=\"ml-6 space-y-2\">\n                      {group.permissions.map((permission) => (\n                        <div key={permission} className=\"flex items-center space-x-2\">\n                          <Checkbox\n                            id={permission}\n                            checked={permissions.includes(permission)}\n                            onCheckedChange={() => handlePermissionToggle(permission)}\n                            disabled={groupIsChecked}\n                            className={`${groupIsChecked ? 'pointer-events-none' : ''}`}\n                          />\n                          <Label\n                            htmlFor={permission}\n                            className={`font-normal${groupIsChecked ? ' opacity-70 pointer-events-none' : ''}`}\n                          >\n                            {permission}\n                          </Label>\n                        </div>\n                      ))}\n                    </div>\n                  </div>\n                )\n              })}\n            </div>\n          </div>\n        </form>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Saving...\n            </Button>\n          ) : (\n            <Button\n              type=\"submit\"\n              form=\"edit-role-form\"\n              variant=\"default\"\n              disabled={!name.trim() || !description.trim()}\n            >\n              Save\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Organizations/CreateOrganizationDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useState } from 'react'\nimport { Check, Copy } from 'lucide-react'\nimport { Organization, Region } from '@daytonaio/api-client'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { Link } from 'react-router-dom'\nimport { Label } from '@/components/ui/label'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { RoutePath } from '@/enums/RoutePath'\n\ninterface CreateOrganizationDialogProps {\n  open: boolean\n  billingApiUrl?: string\n  regions: Region[]\n  loadingRegions: boolean\n  getRegionName: (regionId: string) => string | undefined\n  onOpenChange: (open: boolean) => void\n  onCreateOrganization: (name: string, defaultRegionId: string) => Promise<Organization | null>\n}\n\nexport const CreateOrganizationDialog: React.FC<CreateOrganizationDialogProps> = ({\n  open,\n  billingApiUrl,\n  regions,\n  loadingRegions,\n  getRegionName,\n  onOpenChange,\n  onCreateOrganization,\n}) => {\n  const [name, setName] = useState('')\n  const [defaultRegionId, setDefaultRegionId] = useState<string | undefined>(undefined)\n  const [loading, setLoading] = useState(false)\n  const [createdOrg, setCreatedOrg] = useState<Organization | null>(null)\n  const [copied, setCopied] = useState<string | null>(null)\n\n  const handleCreateOrganization = async () => {\n    if (!name.trim() || !defaultRegionId) {\n      return\n    }\n\n    setLoading(true)\n    const org = await onCreateOrganization(name.trim(), defaultRegionId)\n    if (org) {\n      // TODO: Return when we fix the selected org states\n      // setCreatedOrg(org)\n      // setName('')\n      // setDefaultRegionId(undefined)\n      // setLoading(false)\n    } else {\n      setLoading(false)\n    }\n  }\n\n  const copyToClipboard = async (text: string, label: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      setCopied(label)\n      setTimeout(() => setCopied(null), 2000)\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n    }\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        onOpenChange(isOpen)\n        if (!isOpen) {\n          setName('')\n          setDefaultRegionId(undefined)\n          setCreatedOrg(null)\n          setCopied(null)\n        }\n      }}\n    >\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>{createdOrg ? 'New Organization' : 'Create New Organization'}</DialogTitle>\n          <DialogDescription>\n            {createdOrg\n              ? 'You can switch between organizations in the top left corner of the sidebar.'\n              : 'Create a new organization to share resources and collaborate with others.'}\n          </DialogDescription>\n        </DialogHeader>\n        {createdOrg ? (\n          <div className=\"space-y-6\">\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"organization-id\">Organization ID</Label>\n              <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                <span className=\"overflow-x-auto pr-2 cursor-text select-all\">{createdOrg.id}</span>\n                {(copied === 'Organization ID' && <Check className=\"w-4 h-4\" />) || (\n                  <Copy\n                    className=\"w-4 h-4 cursor-pointer\"\n                    onClick={() => copyToClipboard(createdOrg.id, 'Organization ID')}\n                  />\n                )}\n              </div>\n            </div>\n\n            {createdOrg.defaultRegionId && (\n              <div className=\"space-y-3\">\n                <Label htmlFor=\"organization-default-region\">Default Region</Label>\n                <Input\n                  id=\"organization-default-region\"\n                  value={getRegionName(createdOrg.defaultRegionId) ?? createdOrg.defaultRegionId}\n                  readOnly\n                />\n              </div>\n            )}\n\n            <div className=\"p-3 rounded-md bg-blue-100 text-blue-600 dark:bg-blue-900/30 dark:text-blue-400\">\n              <p className=\"font-medium\">Your organization is created.</p>\n              <p className=\"text-sm mt-1\">\n                {billingApiUrl ? (\n                  <>\n                    To get started, add a payment method on the{' '}\n                    <Link\n                      to={RoutePath.BILLING_WALLET}\n                      className=\"text-blue-500 hover:underline\"\n                      onClick={(e) => {\n                        onOpenChange(false)\n                      }}\n                    >\n                      wallet page\n                    </Link>\n                    .\n                  </>\n                ) : null}\n              </p>\n            </div>\n          </div>\n        ) : !loadingRegions && regions.length === 0 ? (\n          <div className=\"p-3 rounded-md bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400\">\n            <p className=\"font-medium\">No regions available</p>\n            <p className=\"text-sm mt-1\">Organization cannot be created because no regions are available.</p>\n          </div>\n        ) : (\n          <form\n            id=\"create-organization-form\"\n            className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n            onSubmit={async (e) => {\n              e.preventDefault()\n              await handleCreateOrganization()\n            }}\n          >\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"organization-name\">Organization Name</Label>\n              <Input id=\"organization-name\" value={name} onChange={(e) => setName(e.target.value)} placeholder=\"Name\" />\n            </div>\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"region-select\">Region</Label>\n              <Select value={defaultRegionId} onValueChange={setDefaultRegionId}>\n                <SelectTrigger className=\"h-8\" id=\"region-select\" disabled={loadingRegions} loading={loadingRegions}>\n                  <SelectValue placeholder={loadingRegions ? 'Loading regions...' : 'Select a region'} />\n                </SelectTrigger>\n                <SelectContent>\n                  {regions.map((region) => (\n                    <SelectItem key={region.id} value={region.id}>\n                      {region.name}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n              <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n                The region that will be used as the default target for creating sandboxes in this organization.\n              </p>\n            </div>\n          </form>\n        )}\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              {createdOrg ? 'Close' : 'Cancel'}\n            </Button>\n          </DialogClose>\n          {!createdOrg &&\n            (loading ? (\n              <Button type=\"button\" variant=\"default\" disabled>\n                Creating...\n              </Button>\n            ) : (\n              <Button\n                type=\"submit\"\n                form=\"create-organization-form\"\n                variant=\"default\"\n                disabled={!name.trim() || !defaultRegionId}\n              >\n                Create\n              </Button>\n            ))}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Organizations/DeleteOrganizationDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState } from 'react'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\n\ninterface DeleteOrganizationDialogProps {\n  organizationName: string\n  onDeleteOrganization: () => Promise<boolean>\n  loading: boolean\n}\n\nexport const DeleteOrganizationDialog: React.FC<DeleteOrganizationDialogProps> = ({\n  organizationName,\n  onDeleteOrganization,\n  loading,\n}) => {\n  const [open, setOpen] = useState(false)\n  const [confirmName, setConfirmName] = useState('')\n\n  const handleDeleteOrganization = async () => {\n    const success = await onDeleteOrganization()\n    if (success) {\n      setOpen(false)\n      setConfirmName('')\n    }\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        setOpen(isOpen)\n        if (!isOpen) {\n          setConfirmName('')\n        }\n      }}\n    >\n      <DialogTrigger asChild>\n        <Button variant=\"destructive\" className=\"w-auto px-4\">\n          Delete Organization\n        </Button>\n      </DialogTrigger>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Delete Organization</DialogTitle>\n          <DialogDescription>\n            This will permanently delete all associated data. This action cannot be undone.\n          </DialogDescription>\n        </DialogHeader>\n        <form\n          id=\"delete-organization-form\"\n          className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n          onSubmit={async (e) => {\n            e.preventDefault()\n            await handleDeleteOrganization()\n          }}\n        >\n          <div className=\"space-y-6\">\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"confirm-action\">\n                Please type <span className=\"font-bold cursor-text select-all\">{organizationName}</span> to confirm\n              </Label>\n              <Input\n                id=\"confirm-action\"\n                value={confirmName}\n                onChange={(e) => setConfirmName(e.target.value)}\n                placeholder={organizationName}\n              />\n            </div>\n          </div>\n        </form>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"destructive\" disabled>\n              Deleting...\n            </Button>\n          ) : (\n            <Button\n              type=\"submit\"\n              form=\"delete-organization-form\"\n              variant=\"destructive\"\n              disabled={confirmName !== organizationName}\n            >\n              Delete\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Organizations/LeaveOrganizationDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState } from 'react'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\n\ninterface LeaveOrganizationDialogProps {\n  onLeaveOrganization: () => Promise<boolean>\n  loading: boolean\n}\n\nexport const LeaveOrganizationDialog: React.FC<LeaveOrganizationDialogProps> = ({ onLeaveOrganization, loading }) => {\n  const [open, setOpen] = useState(false)\n\n  const handleLeaveOrganization = async () => {\n    const success = await onLeaveOrganization()\n    if (success) {\n      setOpen(false)\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button variant=\"destructive\" className=\"w-auto px-4\">\n          Leave Organization\n        </Button>\n      </DialogTrigger>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Leave Organization</DialogTitle>\n          <DialogDescription>Are you sure you want to leave this organization?</DialogDescription>\n        </DialogHeader>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Leaving...\n            </Button>\n          ) : (\n            <Button type=\"button\" variant=\"destructive\" onClick={handleLeaveOrganization}>\n              Leave\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Organizations/OrganizationPicker.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar'\nimport { useApi } from '@/hooks/useApi'\nimport { useOrganizations } from '@/hooks/useOrganizations'\nimport { useRegions } from '@/hooks/useRegions'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { Organization } from '@daytonaio/api-client'\nimport { Building2, ChevronsUpDown, Copy, PlusCircle, SquareUserRound } from 'lucide-react'\nimport { useEffect, useMemo, useState } from 'react'\nimport { toast } from 'sonner'\nimport { useCopyToClipboard } from 'usehooks-ts'\nimport { CommandHighlight, useRegisterCommands, type CommandConfig } from '../CommandPalette'\nimport { CreateOrganizationDialog } from './CreateOrganizationDialog'\n\nfunction useOrganizationCommands() {\n  const { organizations } = useOrganizations()\n  const { selectedOrganization, onSelectOrganization } = useSelectedOrganization()\n  const [, copyToClipboard] = useCopyToClipboard()\n\n  const commands: CommandConfig[] = useMemo(() => {\n    const cmds: CommandConfig[] = []\n\n    if (selectedOrganization) {\n      cmds.push({\n        id: 'copy-org-id',\n        label: 'Copy Organization ID',\n        icon: <Copy className=\"w-4 h-4\" />,\n        onSelect: () => {\n          copyToClipboard(selectedOrganization.id)\n          toast.success('Organization ID copied to clipboard')\n        },\n      })\n    }\n\n    for (const org of organizations) {\n      if (org.id === selectedOrganization?.id) continue\n\n      cmds.push({\n        id: `switch-org-${org.id}`,\n        label: (\n          <>\n            Switch to <CommandHighlight>{org.name}</CommandHighlight>\n          </>\n        ),\n        value: `switch to organization ${org.name}`,\n        icon: <Building2 className=\"w-4 h-4\" />,\n        onSelect: () => onSelectOrganization(org.id),\n      })\n    }\n\n    return cmds\n  }, [organizations, selectedOrganization, copyToClipboard, onSelectOrganization])\n\n  useRegisterCommands(commands, { groupId: 'organization', groupLabel: 'Organization', groupOrder: 5 })\n}\n\nexport const OrganizationPicker: React.FC = () => {\n  const { organizationsApi } = useApi()\n\n  const { organizations, refreshOrganizations } = useOrganizations()\n  const { selectedOrganization, onSelectOrganization } = useSelectedOrganization()\n  const { sharedRegions: regions, loadingSharedRegions: loadingRegions, getRegionName } = useRegions()\n\n  const [optimisticSelectedOrganization, setOptimisticSelectedOrganization] = useState(selectedOrganization)\n  const [loadingSelectOrganization, setLoadingSelectOrganization] = useState(false)\n\n  useOrganizationCommands()\n\n  useEffect(() => {\n    setOptimisticSelectedOrganization(selectedOrganization)\n  }, [selectedOrganization])\n\n  const handleSelectOrganization = async (organizationId: string) => {\n    const organization = organizations.find((org) => org.id === organizationId)\n    if (!organization) {\n      return\n    }\n\n    setOptimisticSelectedOrganization(organization)\n    setLoadingSelectOrganization(true)\n    const success = await onSelectOrganization(organizationId)\n    if (!success) {\n      setOptimisticSelectedOrganization(selectedOrganization)\n    }\n    setLoadingSelectOrganization(false)\n  }\n\n  const [showCreateOrganizationDialog, setShowCreateOrganizationDialog] = useState(false)\n\n  const handleCreateOrganization = async (name: string, defaultRegionId: string) => {\n    try {\n      const organization = (\n        await organizationsApi.createOrganization({\n          name: name.trim(),\n          defaultRegionId,\n        })\n      ).data\n      toast.success('Organization created successfully')\n      await refreshOrganizations(organization.id)\n      return organization\n    } catch (error) {\n      handleApiError(error, 'Failed to create organization')\n      return null\n    }\n  }\n\n  const getOrganizationIcon = (organization: Organization) => {\n    if (organization.personal) {\n      return <SquareUserRound className=\"w-5 h-5\" />\n    }\n    return <Building2 className=\"w-5 h-5\" />\n  }\n\n  // personal first, then alphabetical\n  const sortedOrganizations = useMemo(() => {\n    return organizations.sort((a, b) => {\n      if (a.personal && !b.personal) {\n        return -1\n      } else if (!a.personal && b.personal) {\n        return 1\n      } else {\n        return a.name.localeCompare(b.name)\n      }\n    })\n  }, [organizations])\n\n  if (!optimisticSelectedOrganization) {\n    return null\n  }\n\n  return (\n    <SidebarMenuItem>\n      <DropdownMenu>\n        <DropdownMenuTrigger asChild>\n          <SidebarMenuButton\n            disabled={loadingSelectOrganization}\n            className=\"outline outline-1 outline-border outline-offset-0 mb-2 bg-muted\"\n            tooltip={optimisticSelectedOrganization.name}\n          >\n            <div className=\"w-4 h-4 flex-shrink-0 bg-black rounded-full text-white flex items-center justify-center text-[10px] font-bold\">\n              {optimisticSelectedOrganization.name[0].toUpperCase()}\n            </div>\n            <span className=\"truncate text-foreground\">{optimisticSelectedOrganization.name}</span>\n            <ChevronsUpDown className=\"ml-auto w-4 h-4 opacity-50\" />\n          </SidebarMenuButton>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent className=\"w-[--radix-popper-anchor-width]\">\n          <div className=\"max-h-44 overflow-y-auto\">\n            {sortedOrganizations.map((org) => (\n              <DropdownMenuItem\n                key={org.id}\n                onClick={() => handleSelectOrganization(org.id)}\n                className=\"cursor-pointer flex items-center gap-2\"\n              >\n                {getOrganizationIcon(org)}\n                <span className=\"truncate\">{org.name}</span>\n              </DropdownMenuItem>\n            ))}\n          </div>\n          <DropdownMenuSeparator />\n          <div>\n            <DropdownMenuItem\n              className=\"cursor-pointer text-primary flex items-center gap-2\"\n              onClick={() => setShowCreateOrganizationDialog(true)}\n            >\n              <PlusCircle className=\"w-4 h-4 flex-shrink-0\" />\n              <span>Create Organization</span>\n            </DropdownMenuItem>\n          </div>\n        </DropdownMenuContent>\n      </DropdownMenu>\n\n      <CreateOrganizationDialog\n        open={showCreateOrganizationDialog}\n        onOpenChange={setShowCreateOrganizationDialog}\n        regions={regions}\n        loadingRegions={loadingRegions}\n        getRegionName={getRegionName}\n        onCreateOrganization={handleCreateOrganization}\n      />\n    </SidebarMenuItem>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Organizations/SetDefaultRegionDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useState } from 'react'\nimport { Region } from '@daytonaio/api-client'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Label } from '@/components/ui/label'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\n\ninterface SetDefaultRegionDialogProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  regions: Region[]\n  loadingRegions: boolean\n  onSetDefaultRegion: (defaultRegionId: string) => Promise<boolean>\n}\n\nexport const SetDefaultRegionDialog: React.FC<SetDefaultRegionDialogProps> = ({\n  open,\n  onOpenChange,\n  regions,\n  loadingRegions,\n  onSetDefaultRegion,\n}) => {\n  const [defaultRegionId, setDefaultRegionId] = useState<string | undefined>(undefined)\n  const [loading, setLoading] = useState(false)\n\n  const handleSetDefaultRegion = async () => {\n    if (!defaultRegionId) {\n      return\n    }\n\n    setLoading(true)\n    const success = await onSetDefaultRegion(defaultRegionId)\n    // TODO: Return when we fix the selected org states\n    // if (success) {\n    //   onOpenChange(false)\n    // }\n    // setLoading(false)\n  }\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        onOpenChange(isOpen)\n        if (!isOpen) {\n          setDefaultRegionId(undefined)\n        }\n      }}\n    >\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Set Default Region</DialogTitle>\n          <DialogDescription>\n            Your organization needs a default region to create sandboxes and manage resources.\n          </DialogDescription>\n        </DialogHeader>\n        {!loadingRegions && regions.length === 0 ? (\n          <div className=\"p-3 rounded-md bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400\">\n            <p className=\"font-medium\">No regions available</p>\n            <p className=\"text-sm mt-1\">Default region cannot be set because no regions are available.</p>\n          </div>\n        ) : (\n          <form\n            id=\"set-default-region-form\"\n            className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n            onSubmit={async (e) => {\n              e.preventDefault()\n              await handleSetDefaultRegion()\n            }}\n          >\n            <div className=\"space-y-3\">\n              <Label htmlFor=\"region-select\">Region</Label>\n              <Select value={defaultRegionId} onValueChange={setDefaultRegionId}>\n                <SelectTrigger className=\"h-8\" id=\"region-select\" disabled={loadingRegions} loading={loadingRegions}>\n                  <SelectValue placeholder={loadingRegions ? 'Loading regions...' : 'Select a region'} />\n                </SelectTrigger>\n                <SelectContent>\n                  {regions.map((region) => (\n                    <SelectItem key={region.id} value={region.id}>\n                      {region.name}\n                    </SelectItem>\n                  ))}\n                </SelectContent>\n              </Select>\n            </div>\n          </form>\n        )}\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Saving...\n            </Button>\n          ) : (\n            <Button type=\"submit\" form=\"set-default-region-form\" variant=\"default\" disabled={!defaultRegionId}>\n              Save\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/PageLayout.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { type ComponentProps } from 'react'\nimport { BannerStack } from './Banner'\nimport { SidebarTrigger } from './ui/sidebar'\n\nfunction PageLayout({ className, ...props }: ComponentProps<'div'>) {\n  return <div className={cn('flex h-full flex-col group/page', className)} {...props} />\n}\n\nfunction PageHeader({ className, children, ...props }: ComponentProps<'header'>) {\n  return (\n    <header\n      className={cn(\n        'flex gap-2 sm:gap-4 items-center border-b border-border p-4 sm:px-5 bg-background z-10 group-[:has([data-slot=page-banner]:not(:empty))]/page:border-b-transparent',\n        className,\n      )}\n      {...props}\n    >\n      <SidebarTrigger className=\"[&_svg]:size-5 md:hidden\" />\n      {children}\n    </header>\n  )\n}\n\nfunction PageTitle({ className, children, ...props }: ComponentProps<'h1'>) {\n  return (\n    <h1 className={cn('text-2xl font-medium tracking-tight', className)} {...props}>\n      {children}\n    </h1>\n  )\n}\n\nfunction PageDescription({ className, ...props }: ComponentProps<'p'>) {\n  return <p className={cn('text-sm text-muted-foreground', className)} {...props} />\n}\n\nfunction PageBanner({ className, children, ...props }: ComponentProps<'div'>) {\n  return (\n    <div data-slot=\"page-banner\" className={cn('w-full relative z-30 empty:hidden', className)} {...props}>\n      {children}\n    </div>\n  )\n}\n\nfunction PageContent({\n  className,\n  size = 'default',\n  ...props\n}: ComponentProps<'main'> & { size?: 'default' | 'full' }) {\n  return (\n    <>\n      <PageBanner>\n        <BannerStack bannerClassName={cn({ 'max-w-5xl mx-auto': size === 'default' })} />\n      </PageBanner>\n      <main\n        className={cn(\n          'flex flex-col gap-4 p-4 sm:px-5 w-full pt-6',\n          {\n            'max-w-5xl mx-auto': size === 'default',\n          },\n          className,\n        )}\n        {...props}\n      />\n    </>\n  )\n}\n\nexport { PageContent, PageDescription, PageHeader, PageLayout, PageTitle }\n"
  },
  {
    "path": "apps/dashboard/src/components/Pagination.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Table } from '@tanstack/react-table'\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select'\nimport { Button } from './ui/button'\nimport { PAGE_SIZE_OPTIONS } from '../constants/Pagination'\n\ninterface PaginationProps<TData> {\n  table: Table<TData>\n  selectionEnabled?: boolean\n  className?: string\n  entityName?: string\n  totalItems?: number\n}\n\nexport function Pagination<TData>({\n  table,\n  selectionEnabled,\n  className,\n  entityName,\n  totalItems,\n}: PaginationProps<TData>) {\n  return (\n    <div className={`flex flex-col sm:flex-row gap-2 sm:items-center justify-between w-full ${className}`}>\n      <div className=\"flex items-center gap-4\">\n        <Select\n          value={`${table.getState().pagination.pageSize}`}\n          onValueChange={(value) => {\n            table.setPageSize(Number(value))\n          }}\n        >\n          <SelectTrigger className=\"h-8 w-[164px]\">\n            <SelectValue placeholder={table.getState().pagination.pageSize + 'per page'} />\n          </SelectTrigger>\n          <SelectContent side=\"top\">\n            {PAGE_SIZE_OPTIONS.map((pageSize) => (\n              <SelectItem key={pageSize} value={`${pageSize}`}>\n                {pageSize} per page\n              </SelectItem>\n            ))}\n          </SelectContent>\n        </Select>\n\n        {selectionEnabled ? (\n          <div className=\"flex-1 text-sm text-muted-foreground\">\n            {table.getFilteredSelectedRowModel().rows.length} of {totalItems ?? table.getFilteredRowModel().rows.length}{' '}\n            item(s) selected.\n          </div>\n        ) : (\n          <div className=\"flex-1 text-sm text-muted-foreground\">\n            {totalItems ?? table.getFilteredRowModel().rows.length} total item(s)\n          </div>\n        )}\n      </div>\n      <div className=\"flex items-center gap-4\">\n        <div className=\"flex items-center justify-end text-sm font-medium text-muted-foreground\">\n          Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount() || 1}\n        </div>\n        <div className=\"flex items-center space-x-2\">\n          <Button\n            variant=\"outline\"\n            className=\"hidden h-8 w-8 p-0 lg:flex\"\n            onClick={() => table.setPageIndex(0)}\n            disabled={!table.getCanPreviousPage()}\n          >\n            <span className=\"sr-only\">Go to first page</span>\n            <ChevronsLeft />\n          </Button>\n          <Button\n            variant=\"outline\"\n            className=\"h-8 w-8 p-0\"\n            onClick={() => table.previousPage()}\n            disabled={!table.getCanPreviousPage()}\n          >\n            <span className=\"sr-only\">Go to previous page</span>\n            <ChevronLeft />\n          </Button>\n          <Button\n            variant=\"outline\"\n            className=\"h-8 w-8 p-0\"\n            onClick={() => table.nextPage()}\n            disabled={!table.getCanNextPage()}\n          >\n            <span className=\"sr-only\">Go to next page</span>\n            <ChevronRight />\n          </Button>\n          <Button\n            variant=\"outline\"\n            className=\"hidden h-8 w-8 p-0 lg:flex\"\n            onClick={() => table.setPageIndex(table.getPageCount() - 1)}\n            disabled={!table.getCanNextPage()}\n          >\n            <span className=\"sr-only\">Go to last page</span>\n            <ChevronsRight />\n          </Button>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/ActionForm.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Label } from '@/components/ui/label'\nimport { PlaygroundActionFormDataBasic } from '@/contexts/PlaygroundContext'\nimport { PlaygroundActions } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport PlaygroundActionRunButton from './ActionRunButton'\n\ntype PlaygroundActionFormProps<A> = {\n  actionFormItem: PlaygroundActionFormDataBasic<A>\n  onRunActionClick?: () => Promise<void>\n  disable?: boolean\n  hideRunActionButton?: boolean\n}\n\nfunction PlaygroundActionForm<A extends PlaygroundActions>({\n  actionFormItem,\n  onRunActionClick,\n  disable,\n  hideRunActionButton,\n}: PlaygroundActionFormProps<A>) {\n  const { runningActionMethod, actionRuntimeError } = usePlayground()\n\n  return (\n    <>\n      <div className=\"flex items-center justify-between\">\n        <div>\n          <Label htmlFor={actionFormItem.methodName as string}>{actionFormItem.label}</Label>\n          <p id={actionFormItem.methodName as string} className=\"text-sm text-muted-foreground mt-1\">\n            {actionFormItem.description}\n          </p>\n        </div>\n        {!hideRunActionButton && (\n          <PlaygroundActionRunButton\n            isDisabled={disable || !!runningActionMethod}\n            isRunning={runningActionMethod === actionFormItem.methodName}\n            onRunActionClick={onRunActionClick}\n          />\n        )}\n      </div>\n      <div className=\"empty:hidden\">\n        {actionRuntimeError[actionFormItem.methodName] && (\n          <p className=\"text-sm text-red-500 mt-2\">{actionRuntimeError[actionFormItem.methodName]}</p>\n        )}\n      </div>\n    </>\n  )\n}\n\nexport default PlaygroundActionForm\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/ActionRunButton.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { Loader2, Play } from 'lucide-react'\nimport TooltipButton from '../TooltipButton'\n\ntype PlaygroundActionRunButtonProps = {\n  isDisabled: boolean\n  isRunning: boolean\n  onRunActionClick?: () => Promise<void>\n  className?: string\n}\n\nconst PlaygroundActionRunButton: React.FC<PlaygroundActionRunButtonProps> = ({\n  isDisabled,\n  isRunning,\n  onRunActionClick,\n  className,\n}) => {\n  return (\n    <TooltipButton\n      disabled={isDisabled}\n      variant=\"outline\"\n      tooltipText=\"Run\"\n      onClick={onRunActionClick}\n      className={cn('w-8 h-8', className)}\n    >\n      {isRunning ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"w-4 h-4\" />}\n    </TooltipButton>\n  )\n}\n\nexport default PlaygroundActionRunButton\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Inputs/CheckboxInput.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Checkbox } from '@/components/ui/checkbox'\nimport { ParameterFormItem } from '@/contexts/PlaygroundContext'\n\ntype FormCheckboxInputProps = {\n  checkedValue: boolean | undefined\n  formItem: ParameterFormItem\n  onChangeHandler: (checked: boolean) => void\n}\n\nconst FormCheckboxInput: React.FC<FormCheckboxInputProps> = ({ checkedValue, formItem, onChangeHandler }) => {\n  return (\n    <div className=\"flex-1\">\n      <Checkbox id={formItem.key} checked={checkedValue} onCheckedChange={(value) => onChangeHandler(!!value)} />\n    </div>\n  )\n}\n\nexport default FormCheckboxInput\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Inputs/InlineInputFormControl.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { ReactNode } from 'react'\nimport { ParameterFormItem } from '@/contexts/PlaygroundContext'\nimport InputLabel from './Label'\n\ntype InlineInputFormControlProps = {\n  formItem: ParameterFormItem\n  children: ReactNode\n}\n\nconst InlineInputFormControl: React.FC<InlineInputFormControlProps> = ({ formItem, children }) => {\n  return (\n    <div className=\"flex items-center gap-4\">\n      <InputLabel formItem={formItem} />\n      {children}\n    </div>\n  )\n}\n\nexport default InlineInputFormControl\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Inputs/Label.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Label } from '@/components/ui/label'\nimport { ParameterFormItem } from '@/contexts/PlaygroundContext'\n\ntype InputLabelProps = {\n  formItem: ParameterFormItem\n}\n\nconst InputLabel: React.FC<InputLabelProps> = ({ formItem }) => {\n  return (\n    <Label htmlFor={formItem.key} className=\"w-32 flex-shrink-0\">\n      <span className=\"relative\">\n        {formItem.label}\n        {formItem.required ? <span className=\"text-muted-foreground\">* </span> : null}\n      </span>\n    </Label>\n  )\n}\n\nexport default InputLabel\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Inputs/NumberInput.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Input } from '@/components/ui/input'\nimport { NumberParameterFormItem } from '@/contexts/PlaygroundContext'\nimport React from 'react'\n\ntype FormNumberInputProps = {\n  numberValue: number | undefined\n  numberFormItem: NumberParameterFormItem\n  onChangeHandler: (value: number | undefined) => void\n  disabled?: boolean\n}\n\nconst FormNumberInput: React.FC<FormNumberInputProps> = ({\n  numberValue,\n  numberFormItem,\n  onChangeHandler,\n  disabled,\n}) => {\n  return (\n    <Input\n      id={numberFormItem.key}\n      type=\"number\"\n      className=\"w-full\"\n      min={numberFormItem.min}\n      max={numberFormItem.max}\n      placeholder={numberFormItem.placeholder}\n      step={numberFormItem.step}\n      value={numberValue ?? ''}\n      onChange={(e) => {\n        const newValue = e.target.value ? Number(e.target.value) : undefined\n        onChangeHandler(newValue)\n      }}\n      disabled={disabled}\n    />\n  )\n}\n\nexport default FormNumberInput\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Inputs/SelectInput.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { ParameterFormItem } from '@/contexts/PlaygroundContext'\nimport { Loader2 } from 'lucide-react'\n\ntype SelectOption = {\n  value: string\n  label: string\n}\n\ntype FormSelectInputProps = {\n  selectOptions: SelectOption[]\n  selectValue: string | undefined\n  formItem: ParameterFormItem\n  onChangeHandler: (value: string) => void\n  loading?: boolean\n}\n\nconst FormSelectInput: React.FC<FormSelectInputProps> = ({\n  selectOptions,\n  selectValue,\n  formItem,\n  onChangeHandler,\n  loading,\n}) => {\n  return (\n    <Select value={selectValue} onValueChange={onChangeHandler}>\n      <SelectTrigger className=\"w-full box-border\" size=\"sm\" aria-label={formItem.label}>\n        {loading ? (\n          <div className=\"w-full flex items-center justify-center gap-2\">\n            <Loader2 className=\"h-4 w-4 animate-spin text-muted-foreground\" />\n            <span className=\"text-muted-foreground\">Loading...</span>\n          </div>\n        ) : (\n          <SelectValue id={formItem.key} placeholder={formItem.placeholder} />\n        )}\n      </SelectTrigger>\n      <SelectContent>\n        {selectOptions.map((option) => (\n          <SelectItem key={option.value} value={option.value}>\n            {option.label}\n          </SelectItem>\n        ))}\n      </SelectContent>\n    </Select>\n  )\n}\n\nexport default FormSelectInput\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Inputs/StackedInputFormControl.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { ReactNode } from 'react'\nimport { ParameterFormItem } from '@/contexts/PlaygroundContext'\nimport InputLabel from './Label'\n\ntype StackedInputFormControlProps = {\n  formItem: ParameterFormItem\n  children: ReactNode\n}\n\nconst StackedInputFormControl: React.FC<StackedInputFormControlProps> = ({ formItem, children }) => {\n  return (\n    <div className=\"space-y-2\">\n      <InputLabel formItem={formItem} />\n      {children}\n    </div>\n  )\n}\n\nexport default StackedInputFormControl\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Inputs/TextInput.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Input } from '@/components/ui/input'\nimport { ParameterFormItem } from '@/contexts/PlaygroundContext'\n\ntype FormTextInputProps = {\n  textValue: string | undefined\n  formItem: ParameterFormItem\n  onChangeHandler: (value: string) => void\n}\n\nconst FormTextInput: React.FC<FormTextInputProps> = ({ textValue, formItem, onChangeHandler }) => {\n  return (\n    <Input\n      id={formItem.key}\n      className=\"w-full\"\n      placeholder={formItem.placeholder}\n      value={textValue ?? ''}\n      onChange={(e) => onChangeHandler(e.target.value)}\n    />\n  )\n}\n\nexport default FormTextInput\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/PlaygroundLayout.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { cn } from '@/lib/utils'\n\nfunction PlaygroundLayout({ children, className }: { children: React.ReactNode; className?: string }) {\n  return (\n    <div className={cn('grid grid-cols-1 lg:grid-cols-[minmax(320px,400px)_1fr] h-full', className)}>{children}</div>\n  )\n}\n\nfunction PlaygroundLayoutSidebar({ children }: { children: React.ReactNode }) {\n  return (\n    <ScrollArea fade=\"mask\" className=\"bg-sidebar/20 border-r border-border hidden lg:flex h-full overflow-hidden\">\n      <div className=\"p-4\">{children}</div>\n    </ScrollArea>\n  )\n}\n\nfunction PlaygroundLayoutContent({ children, className }: { children: React.ReactNode; className?: string }) {\n  return (\n    <div\n      className={cn(\n        'overflow-auto bg-[radial-gradient(hsl(var(--border))_1px,transparent_1px)] [background-size:12px_12px] flex items-center justify-center p-5',\n        className,\n      )}\n    >\n      {children}\n    </div>\n  )\n}\n\nexport { PlaygroundLayout, PlaygroundLayoutContent, PlaygroundLayoutSidebar }\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/ResponseCard.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ReactNode } from 'react'\n\ntype ResponseCardProps = {\n  responseContent: string | ReactNode\n}\n\nconst ResponseCard: React.FC<ResponseCardProps> = ({ responseContent }) => {\n  return (\n    <div className=\"rounded-lg h-full\">\n      <pre className=\"max-w-full h-full p-4 rounded-lg overflow-y-auto text-sm font-mono\">\n        {typeof responseContent === 'string' ? <code>{responseContent}</code> : responseContent}\n      </pre>\n    </div>\n  )\n}\n\nexport default ResponseCard\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/CodeSnippets/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CodeLanguage } from '@daytonaio/sdk'\nimport { PythonSnippetGenerator } from './python'\nimport { CodeSnippetGenerator } from './types'\nimport { TypeScriptSnippetGenerator } from './typescript'\n\nexport const codeSnippetGenerators: Record<Exclude<CodeLanguage, CodeLanguage.JAVASCRIPT>, CodeSnippetGenerator> = {\n  [CodeLanguage.PYTHON]: PythonSnippetGenerator,\n  [CodeLanguage.TYPESCRIPT]: TypeScriptSnippetGenerator,\n}\n\nexport type { CodeSnippetActionFlags, CodeSnippetGenerator, CodeSnippetParams } from './types'\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/CodeSnippets/python.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CodeSnippetGenerator } from './types'\nimport { joinGroupedSections } from './utils'\n\nexport const PythonSnippetGenerator: CodeSnippetGenerator = {\n  getImports(p) {\n    return (\n      [\n        'from daytona import Daytona',\n        p.actions.useConfigObject ? 'DaytonaConfig' : '',\n        p.config.useSandboxCreateParams\n          ? p.config.createSandboxFromSnapshot\n            ? 'CreateSandboxFromSnapshotParams'\n            : 'CreateSandboxFromImageParams'\n          : '',\n        p.config.useResources ? 'Resources' : '',\n        p.config.createSandboxFromImage ? 'Image' : '',\n      ]\n        .filter(Boolean)\n        .join(', ') + '\\n'\n    )\n  },\n\n  getConfig(p) {\n    if (!p.actions.useConfigObject) return ''\n    return ['\\n# Define the configuration', 'config = DaytonaConfig()'].filter(Boolean).join('\\n') + '\\n'\n  },\n\n  getClientInit(p) {\n    return ['# Initialize the Daytona client', `daytona = Daytona(${p.actions.useConfigObject ? 'config' : ''})`]\n      .filter(Boolean)\n      .join('\\n')\n  },\n\n  getResources(p) {\n    if (!p.config.useResources) return ''\n    const ind = '\\t'\n    return [\n      '\\n\\n# Create a Sandbox with custom resources\\nresources = Resources(',\n      p.config.useResourcesCPU\n        ? `${ind}cpu=${p.state['resources']['cpu']}, # ${p.state['resources']['cpu']} CPU cores`\n        : '',\n      p.config.useResourcesMemory\n        ? `${ind}memory=${p.state['resources']['memory']}, # ${p.state['resources']['memory']}GB RAM`\n        : '',\n      p.config.useResourcesDisk\n        ? `${ind}disk=${p.state['resources']['disk']}, # ${p.state['resources']['disk']}GB disk space`\n        : '',\n      ')',\n    ]\n      .filter(Boolean)\n      .join('\\n')\n  },\n\n  getSandboxParams(p) {\n    if (!p.config.useSandboxCreateParams) return ''\n    const ind = '\\t'\n    return [\n      `\\n\\nparams = ${p.config.createSandboxFromSnapshot ? 'CreateSandboxFromSnapshotParams' : 'CreateSandboxFromImageParams'}(`,\n      p.config.useCustomSandboxSnapshotName ? `${ind}snapshot=\"${p.state['snapshotName']}\",` : '',\n      p.config.createSandboxFromImage ? `${ind}image=Image.debian_slim(\"3.13\"),` : '',\n      p.config.useResources ? `${ind}resources=resources,` : '',\n      p.config.useLanguageParam ? `${ind}language=\"${p.state['language']}\",` : '',\n      ...(p.config.createSandboxParamsExist\n        ? [\n            p.config.useAutoStopInterval\n              ? `${ind}auto_stop_interval=${p.state['createSandboxBaseParams']['autoStopInterval']}, # ${p.state['createSandboxBaseParams']['autoStopInterval'] == 0 ? 'Disables the auto-stop feature' : `Sandbox will be stopped after ${p.state['createSandboxBaseParams']['autoStopInterval']} minute${(p.state['createSandboxBaseParams']['autoStopInterval'] as number) > 1 ? 's' : ''}`}`\n              : '',\n            p.config.useAutoArchiveInterval\n              ? `${ind}auto_archive_interval=${p.state['createSandboxBaseParams']['autoArchiveInterval']}, # Auto-archive after a Sandbox has been stopped for ${p.state['createSandboxBaseParams']['autoArchiveInterval'] == 0 ? '30 days' : `${p.state['createSandboxBaseParams']['autoArchiveInterval']} minutes`}`\n              : '',\n            p.config.useAutoDeleteInterval\n              ? `${ind}auto_delete_interval=${p.state['createSandboxBaseParams']['autoDeleteInterval']}, # ${p.state['createSandboxBaseParams']['autoDeleteInterval'] == 0 ? 'Sandbox will be deleted immediately after stopping' : p.state['createSandboxBaseParams']['autoDeleteInterval'] == -1 ? 'Auto-delete functionality disabled' : `Auto-delete after a Sandbox has been stopped for ${p.state['createSandboxBaseParams']['autoDeleteInterval']} minutes`}`\n              : '',\n          ]\n        : []),\n      ')',\n    ]\n      .filter(Boolean)\n      .join('\\n')\n  },\n\n  getSandboxCreate(p) {\n    return [\n      '\\n# Create the Sandbox instance',\n      `sandbox = daytona.create(${p.config.useSandboxCreateParams ? 'params' : ''})`,\n      'print(f\"Sandbox created:{sandbox.id}\")',\n    ].join('\\n')\n  },\n\n  getCodeRun(p) {\n    if (!p.actions.codeToRunExists) return ''\n    const ind = '\\t'\n    return [\n      '\\n\\n# Run code securely inside the Sandbox',\n      'codeRunResponse = sandbox.process.code_run(',\n      `'''${p.state['codeRunParams'].languageCode}'''`,\n      ')',\n      'if codeRunResponse.exit_code != 0:',\n      `${ind}print(f\"Error: {codeRunResponse.exit_code} {codeRunResponse.result}\")`,\n      'else:',\n      `${ind}print(codeRunResponse.result)`,\n    ].join('\\n')\n  },\n\n  getShellRun(p) {\n    if (!p.actions.shellCommandExists) return ''\n    return [\n      '\\n\\n# Execute shell commands',\n      `shellRunResponse = sandbox.process.exec(\"${p.state['shellCommandRunParams'].shellCommand}\")`,\n      'print(shellRunResponse.result)',\n    ].join('\\n')\n  },\n\n  getFileSystemOps(p) {\n    const sections: string[] = []\n    const ind = '\\t'\n\n    if (p.actions.fileSystemCreateFolderParamsSet) {\n      sections.push(\n        [\n          '# Create folder with specific permissions',\n          `sandbox.fs.create_folder(\"${p.state['createFolderParams'].folderDestinationPath}\", \"${p.state['createFolderParams'].permissions}\")`,\n        ].join('\\n'),\n      )\n    }\n\n    if (p.actions.fileSystemListFilesLocationSet) {\n      sections.push(\n        [\n          '# List files in a directory',\n          `files = sandbox.fs.list_files(\"${p.state['listFilesParams'].directoryPath}\")`,\n          'for file in files:',\n          `${ind}print(f\"Name: {file.name}\")`,\n          `${ind}print(f\"Is directory: {file.is_dir}\")`,\n          `${ind}print(f\"Size: {file.size}\")`,\n          `${ind}print(f\"Modified: {file.mod_time}\")`,\n        ].join('\\n'),\n      )\n    }\n\n    if (p.actions.fileSystemDeleteFileRequiredParamsSet) {\n      sections.push(\n        [\n          `# Delete ${p.actions.useFileSystemDeleteFileRecursive ? 'directory' : 'file'}`,\n          `sandbox.fs.delete_file(\"${p.state['deleteFileParams'].filePath}\"${p.actions.useFileSystemDeleteFileRecursive ? ', True' : ''})`,\n        ].join('\\n'),\n      )\n    }\n\n    return joinGroupedSections(sections)\n  },\n\n  getGitOps(p) {\n    const sections: string[] = []\n    const ind = '\\t'\n\n    if (p.actions.gitCloneOperationRequiredParamsSet) {\n      sections.push(\n        [\n          '# Clone git repository',\n          'sandbox.git.clone(',\n          `${ind}url=\"${p.state['gitCloneParams'].repositoryURL}\",`,\n          `${ind}path=\"${p.state['gitCloneParams'].cloneDestinationPath}\",`,\n          p.actions.useGitCloneBranch ? `${ind}branch=\"${p.state['gitCloneParams'].branchToClone}\",` : '',\n          p.actions.useGitCloneCommitId ? `${ind}commit_id=\"${p.state['gitCloneParams'].commitToClone}\",` : '',\n          p.actions.useGitCloneUsername ? `${ind}username=\"${p.state['gitCloneParams'].authUsername}\",` : '',\n          p.actions.useGitClonePassword ? `${ind}password=\"${p.state['gitCloneParams'].authPassword}\"` : '',\n          ')',\n        ]\n          .filter(Boolean)\n          .join('\\n'),\n      )\n    }\n\n    if (p.actions.gitStatusOperationLocationSet) {\n      sections.push(\n        [\n          '# Get repository status',\n          `status = sandbox.git.status(\"${p.state['gitStatusParams'].repositoryPath}\")`,\n          'print(f\"Current branch: {status.current_branch}\")',\n          'print(f\"Commits ahead: {status.ahead}\")',\n          'print(f\"Commits behind: {status.behind}\")',\n          'for file_status in status.file_status:',\n          '\\tprint(f\"File: {file_status.name}\")',\n        ].join('\\n'),\n      )\n    }\n\n    if (p.actions.gitBranchesOperationLocationSet) {\n      sections.push(\n        [\n          '# List branches',\n          `branchesResponse = sandbox.git.branches(\"${p.state['gitBranchesParams'].repositoryPath}\")`,\n          'for branch in branchesResponse.branches:',\n          '\\tprint(f\"Branch: {branch}\")',\n        ].join('\\n'),\n      )\n    }\n\n    return joinGroupedSections(sections)\n  },\n\n  buildFullSnippet(p) {\n    const imports = this.getImports(p)\n    const config = this.getConfig(p)\n    const client = this.getClientInit(p)\n    const resources = this.getResources(p)\n    const params = this.getSandboxParams(p)\n    const create = this.getSandboxCreate(p)\n    const codeRun = this.getCodeRun(p)\n    const shell = this.getShellRun(p)\n    const fsOps = this.getFileSystemOps(p)\n    const gitOps = this.getGitOps(p)\n\n    return `${imports}${config}\\n${client}${resources}${params}\\n${create}${fsOps}${gitOps}${codeRun}${shell}`\n  },\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/CodeSnippets/types.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SandboxParams, SandboxParametersInfo } from '@/contexts/PlaygroundContext'\n\nexport interface CodeSnippetActionFlags {\n  useConfigObject: boolean\n  fileSystemListFilesLocationSet: boolean\n  fileSystemCreateFolderParamsSet: boolean\n  fileSystemDeleteFileRequiredParamsSet: boolean\n  useFileSystemDeleteFileRecursive: boolean\n  shellCommandExists: boolean\n  codeToRunExists: boolean\n  gitCloneOperationRequiredParamsSet: boolean\n  useGitCloneBranch: boolean\n  useGitCloneCommitId: boolean\n  useGitCloneUsername: boolean\n  useGitClonePassword: boolean\n  gitStatusOperationLocationSet: boolean\n  gitBranchesOperationLocationSet: boolean\n}\n\nexport interface CodeSnippetParams {\n  state: SandboxParams\n  config: SandboxParametersInfo\n  actions: CodeSnippetActionFlags\n}\n\nexport interface CodeSnippetGenerator {\n  getImports(p: CodeSnippetParams): string\n  getConfig(p: CodeSnippetParams): string\n  getClientInit(p: CodeSnippetParams): string\n  getResources(p: CodeSnippetParams): string\n  getSandboxParams(p: CodeSnippetParams): string\n  getSandboxCreate(p: CodeSnippetParams): string\n  getCodeRun(p: CodeSnippetParams): string\n  getShellRun(p: CodeSnippetParams): string\n  getFileSystemOps(p: CodeSnippetParams): string\n  getGitOps(p: CodeSnippetParams): string\n  buildFullSnippet(p: CodeSnippetParams): string\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/CodeSnippets/typescript.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CodeSnippetGenerator } from './types'\nimport { joinGroupedSections } from './utils'\n\nexport const TypeScriptSnippetGenerator: CodeSnippetGenerator = {\n  getImports(p) {\n    return (\n      [\n        'import { Daytona',\n        p.actions.useConfigObject ? 'DaytonaConfig' : '',\n        p.config.createSandboxFromImage ? 'Image' : '',\n      ]\n        .filter(Boolean)\n        .join(', ') + \" } from '@daytonaio/sdk'\\n\"\n    )\n  },\n\n  getConfig(p) {\n    if (!p.actions.useConfigObject) return ''\n    return ['\\n// Define the configuration', 'const config: DaytonaConfig = { }'].filter(Boolean).join('\\n') + '\\n'\n  },\n\n  getClientInit(p) {\n    return [\n      '\\t// Initialize the Daytona client',\n      `\\tconst daytona = new Daytona(${p.actions.useConfigObject ? 'config' : ''})`,\n    ]\n      .filter(Boolean)\n      .join('\\n')\n  },\n\n  getResources(p) {\n    if (!p.config.useResources) return ''\n    const ind = '\\t\\t\\t\\t'\n    return [\n      `${ind.slice(0, -1)}resources: {`,\n      p.config.useResourcesCPU\n        ? `${ind}cpu: ${p.state['resources']['cpu']}, // ${p.state['resources']['cpu']} CPU cores`\n        : '',\n      p.config.useResourcesMemory\n        ? `${ind}memory: ${p.state['resources']['memory']}, // ${p.state['resources']['memory']}GB RAM`\n        : '',\n      p.config.useResourcesDisk\n        ? `${ind}disk: ${p.state['resources']['disk']}, // ${p.state['resources']['disk']}GB disk space`\n        : '',\n      `${ind.slice(0, -1)}}`,\n    ]\n      .filter(Boolean)\n      .join('\\n')\n  },\n\n  getSandboxParams(p) {\n    if (!p.config.useSandboxCreateParams) return ''\n    const ind = '\\t\\t\\t'\n    return [\n      `{`,\n      p.config.useCustomSandboxSnapshotName ? `${ind}snapshot: '${p.state['snapshotName']}',` : '',\n      p.config.createSandboxFromImage ? `${ind}image: Image.debianSlim(\"3.13\"),` : '',\n      this.getResources(p),\n      p.config.useLanguageParam ? `${ind}language: '${p.state['language']}',` : '',\n      ...(p.config.createSandboxParamsExist\n        ? [\n            p.config.useAutoStopInterval\n              ? `${ind}autoStopInterval: ${p.state['createSandboxBaseParams']['autoStopInterval']}, // ${p.state['createSandboxBaseParams']['autoStopInterval'] == 0 ? 'Disables the auto-stop feature' : `Sandbox will be stopped after ${p.state['createSandboxBaseParams']['autoStopInterval']} minute${(p.state['createSandboxBaseParams']['autoStopInterval'] as number) > 1 ? 's' : ''}`}`\n              : '',\n            p.config.useAutoArchiveInterval\n              ? `${ind}autoArchiveInterval: ${p.state['createSandboxBaseParams']['autoArchiveInterval']}, // Auto-archive after a Sandbox has been stopped for ${p.state['createSandboxBaseParams']['autoArchiveInterval'] == 0 ? '30 days' : `${p.state['createSandboxBaseParams']['autoArchiveInterval']} minutes`}`\n              : '',\n            p.config.useAutoDeleteInterval\n              ? `${ind}autoDeleteInterval: ${p.state['createSandboxBaseParams']['autoDeleteInterval']}, // ${p.state['createSandboxBaseParams']['autoDeleteInterval'] == 0 ? 'Sandbox will be deleted immediately after stopping' : p.state['createSandboxBaseParams']['autoDeleteInterval'] == -1 ? 'Auto-delete functionality disabled' : `Auto-delete after a Sandbox has been stopped for ${p.state['createSandboxBaseParams']['autoDeleteInterval']} minutes`}`\n              : '',\n          ]\n        : []),\n      `${ind.slice(0, -1)}}`,\n    ]\n      .filter(Boolean)\n      .join('\\n')\n  },\n\n  getSandboxCreate(p) {\n    return [\n      '\\t\\t// Create the Sandbox instance',\n      `\\t\\tconst sandbox = await daytona.create(${p.config.useSandboxCreateParams ? this.getSandboxParams(p) : ''})`,\n    ].join('\\n')\n  },\n\n  getCodeRun(p) {\n    if (!p.actions.codeToRunExists) return ''\n    const ind = '\\t\\t'\n    return [\n      `\\n\\n${ind}// Run code securely inside the Sandbox`,\n      `${ind}const codeRunResponse = await sandbox.process.codeRun(\\``,\n      `${(p.state['codeRunParams'].languageCode ?? '').replace(/`/g, '\\\\`').replace(/\\$\\{/g, '\\\\${')}`, // Escape backticks and ${ to prevent breaking the template literal\n      `${ind}\\`)`,\n      `${ind}if (codeRunResponse.exitCode !== 0) {`,\n      `${ind + '\\t'}console.error(\"Error running code:\", codeRunResponse.exitCode, codeRunResponse.result)`,\n      `${ind}} else {`,\n      `${ind + '\\t'}console.log(codeRunResponse.result)`,\n      `${ind}}`,\n    ].join('\\n')\n  },\n\n  getShellRun(p) {\n    if (!p.actions.shellCommandExists) return ''\n    const ind = '\\t\\t'\n    return [\n      `\\n\\n${ind}// Execute shell commands`,\n      `${ind}const shellRunResponse = await sandbox.process.executeCommand('${p.state['shellCommandRunParams'].shellCommand}')`,\n      `${ind}console.log(shellRunResponse.result)`,\n    ].join('\\n')\n  },\n\n  getFileSystemOps(p) {\n    const sections: string[] = []\n    const ind = '\\t\\t\\t'\n    const base = ind.slice(0, -1)\n\n    if (p.actions.fileSystemCreateFolderParamsSet) {\n      sections.push(\n        [\n          `${base}// Create folder with specific permissions`,\n          `${base}await sandbox.fs.createFolder(\"${p.state['createFolderParams'].folderDestinationPath}\", \"${p.state['createFolderParams'].permissions}\")`,\n        ].join('\\n'),\n      )\n    }\n\n    if (p.actions.fileSystemListFilesLocationSet) {\n      sections.push(\n        [\n          `${base}// List files in a directory`,\n          `${base}const files = await sandbox.fs.listFiles(\"${p.state['listFilesParams'].directoryPath}\")`,\n          `${base}files.forEach(file => {`,\n          `${ind}console.log(\\`Name: \\${file.name}\\`)`,\n          `${ind}console.log(\\`Is directory: \\${file.isDir}\\`)`,\n          `${ind}console.log(\\`Size: \\${file.size}\\`)`,\n          `${ind}console.log(\\`Modified: \\${file.modTime}\\`)`,\n          `${base}})`,\n        ].join('\\n'),\n      )\n    }\n\n    if (p.actions.fileSystemDeleteFileRequiredParamsSet) {\n      sections.push(\n        [\n          `${base}// Delete ${p.actions.useFileSystemDeleteFileRecursive ? 'directory' : 'file'}`,\n          `${base}await sandbox.fs.deleteFile(\"${p.state['deleteFileParams'].filePath}\"${p.actions.useFileSystemDeleteFileRecursive ? ', true' : ''})`,\n        ].join('\\n'),\n      )\n    }\n\n    return joinGroupedSections(sections)\n  },\n\n  getGitOps(p) {\n    const sections: string[] = []\n    const ind = '\\t\\t\\t'\n    const base = ind.slice(0, -1)\n\n    if (p.actions.gitCloneOperationRequiredParamsSet) {\n      sections.push(\n        [\n          `${base}// Clone git repository`,\n          `${base}await sandbox.git.clone(`,\n          `${ind}\"${p.state['gitCloneParams'].repositoryURL}\",`,\n          `${ind}\"${p.state['gitCloneParams'].cloneDestinationPath}\",`,\n          p.actions.useGitCloneBranch ? `${ind}\"${p.state['gitCloneParams'].branchToClone}\",` : '',\n          p.actions.useGitCloneCommitId ? `${ind}\"${p.state['gitCloneParams'].commitToClone}\",` : '',\n          p.actions.useGitCloneUsername ? `${ind}\"${p.state['gitCloneParams'].authUsername}\",` : '',\n          p.actions.useGitClonePassword ? `${ind}\"${p.state['gitCloneParams'].authPassword}\"` : '',\n          `${base})`,\n        ]\n          .filter(Boolean)\n          .join('\\n'),\n      )\n    }\n\n    if (p.actions.gitStatusOperationLocationSet) {\n      sections.push(\n        [\n          `${base}// Get repository status`,\n          `${base}const status = await sandbox.git.status(\"${p.state['gitStatusParams'].repositoryPath}\")`,\n          `${base}console.log(\\`Current branch: \\${status.currentBranch}\\`)`,\n          `${base}console.log(\\`Commits ahead: \\${status.ahead}\\`)`,\n          `${base}console.log(\\`Commits behind: \\${status.behind}\\`)`,\n          `${base}status.fileStatus.forEach(file => {`,\n          `${ind}console.log(\\`File: \\${file.name}\\`)`,\n          `${base}})`,\n        ].join('\\n'),\n      )\n    }\n\n    if (p.actions.gitBranchesOperationLocationSet) {\n      sections.push(\n        [\n          `${base}// List branches`,\n          `${base}const branchesResponse = await sandbox.git.branches(\"${p.state['gitBranchesParams'].repositoryPath}\")`,\n          `${base}branchesResponse.branches.forEach(branch => {`,\n          `${ind}console.log(\\`Branch: \\${branch}\\`)`,\n          `${base}})`,\n        ].join('\\n'),\n      )\n    }\n\n    return joinGroupedSections(sections)\n  },\n\n  buildFullSnippet(p) {\n    const imports = this.getImports(p)\n    const config = this.getConfig(p)\n    const client = this.getClientInit(p)\n    const create = this.getSandboxCreate(p)\n    const codeRun = this.getCodeRun(p)\n    const shell = this.getShellRun(p)\n    const fsOps = this.getFileSystemOps(p)\n    const gitOps = this.getGitOps(p)\n\n    return `${imports}${config}\nasync function main() {\n${client}\n\\ttry {\n${create}${fsOps}${gitOps}${codeRun}${shell}\n\\t} catch (error) {\n\\t\\tconsole.error(\"Sandbox flow error:\", error)\n\\t}\n}\nmain().catch(console.error)`\n  },\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/CodeSnippets/utils.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Joins grouped code snippet sections with consistent spacing.\n * Each non-empty section gets a `\\n\\n` prefix, producing a blank line between sections.\n */\nexport function joinGroupedSections(sections: string[]): string {\n  const nonEmpty = sections.filter(Boolean)\n  if (nonEmpty.length === 0) return ''\n  return nonEmpty.map((section) => '\\n\\n' + section).join('')\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/CodeSnippetsResponse.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport PythonIcon from '@/assets/python.svg'\nimport TypescriptIcon from '@/assets/typescript.svg'\nimport CodeBlock from '@/components/CodeBlock'\nimport { CopyButton } from '@/components/CopyButton'\nimport TooltipButton from '@/components/TooltipButton'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport {\n  FileSystemActions,\n  GitOperationsActions,\n  ProcessCodeExecutionActions,\n  SandboxParametersSections,\n} from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { usePlaygroundSandbox } from '@/hooks/usePlaygroundSandbox'\nimport { createErrorMessageOutput } from '@/lib/playground'\nimport { cn } from '@/lib/utils'\nimport { CodeLanguage, Sandbox } from '@daytonaio/sdk'\nimport { ChevronUpIcon, Loader2, PanelBottom, Play, XIcon } from 'lucide-react'\nimport { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Group, Panel, usePanelRef } from 'react-resizable-panels'\nimport ResponseCard from '../ResponseCard'\nimport { Window, WindowContent, WindowTitleBar } from '../Window'\nimport { codeSnippetGenerators, CodeSnippetParams } from './CodeSnippets'\n\nconst codeSnippetSupportedLanguages = [\n  { value: CodeLanguage.PYTHON, label: 'Python', icon: PythonIcon },\n  { value: CodeLanguage.TYPESCRIPT, label: 'TypeScript', icon: TypescriptIcon },\n] as const\n\nconst SECTION_SCROLL_MARKERS: Partial<Record<SandboxParametersSections, string[]>> = {\n  [SandboxParametersSections.FILE_SYSTEM]: [\n    '# Create folder',\n    '# List files',\n    '# Delete',\n    '// Create folder',\n    '// List files',\n    '// Delete',\n  ],\n  [SandboxParametersSections.GIT_OPERATIONS]: [\n    '# Clone git',\n    '# Get repository',\n    '# List branches',\n    '// Clone git',\n    '// Get repository',\n    '// List branches',\n  ],\n  [SandboxParametersSections.PROCESS_CODE_EXECUTION]: [\n    '# Run code securely',\n    '# Execute shell',\n    '// Run code securely',\n    '// Execute shell',\n  ],\n}\n\nconst SandboxCodeSnippetsResponse = ({ className }: { className?: string }) => {\n  const [codeSnippetLanguage, setCodeSnippetLanguage] = useState<CodeLanguage>(CodeLanguage.PYTHON)\n  const [codeSnippetOutput, setCodeSnippetOutput] = useState<string | ReactNode>('')\n  const [isCodeSnippetRunning, setIsCodeSnippetRunning] = useState<boolean>(false)\n\n  const {\n    sandboxParametersState,\n    actionRuntimeError,\n    getSandboxParametersInfo,\n    enabledSections,\n    pendingScrollSection,\n    clearPendingScrollSection,\n  } = usePlayground()\n  const {\n    sandbox: { create: createSandbox },\n  } = usePlaygroundSandbox()\n\n  const useConfigObject = false // Currently not needed, we use jwtToken for client config\n\n  const fsOn = enabledSections.includes(SandboxParametersSections.FILE_SYSTEM)\n  const gitOn = enabledSections.includes(SandboxParametersSections.GIT_OPERATIONS)\n  const procOn = enabledSections.includes(SandboxParametersSections.PROCESS_CODE_EXECUTION)\n\n  const fileSystemListFilesLocationSet = fsOn && !actionRuntimeError[FileSystemActions.LIST_FILES]\n  const fileSystemCreateFolderParamsSet = fsOn && !actionRuntimeError[FileSystemActions.CREATE_FOLDER]\n  const fileSystemDeleteFileRequiredParamsSet = fsOn && !actionRuntimeError[FileSystemActions.DELETE_FILE]\n  const useFileSystemDeleteFileRecursive =\n    fileSystemDeleteFileRequiredParamsSet && sandboxParametersState['deleteFileParams'].recursive === true\n  const shellCommandExists = procOn && !actionRuntimeError[ProcessCodeExecutionActions.SHELL_COMMANDS_RUN]\n  const codeToRunExists = procOn && !actionRuntimeError[ProcessCodeExecutionActions.CODE_RUN]\n  const gitCloneOperationRequiredParamsSet = gitOn && !actionRuntimeError[GitOperationsActions.GIT_CLONE]\n  const useGitCloneBranch = !!sandboxParametersState['gitCloneParams'].branchToClone\n  const useGitCloneCommitId = !!sandboxParametersState['gitCloneParams'].commitToClone\n  const useGitCloneUsername = !!sandboxParametersState['gitCloneParams'].authUsername\n  const useGitClonePassword = !!sandboxParametersState['gitCloneParams'].authPassword\n  const gitStatusOperationLocationSet = gitOn && !actionRuntimeError[GitOperationsActions.GIT_STATUS]\n  const gitBranchesOperationLocationSet = gitOn && !actionRuntimeError[GitOperationsActions.GIT_BRANCHES_LIST]\n\n  const codeScrollRef = useRef<HTMLDivElement>(null)\n  const highlightTimersRef = useRef<ReturnType<typeof setTimeout>[]>([])\n\n  const scrollToSection = useCallback((section: SandboxParametersSections) => {\n    const viewport = codeScrollRef.current?.querySelector<HTMLElement>('[data-slot=scroll-area-viewport]')\n    if (!viewport) return\n\n    const markers = SECTION_SCROLL_MARKERS[section]\n    if (!markers?.length) return\n\n    const walker = document.createTreeWalker(viewport, NodeFilter.SHOW_TEXT)\n    let node: Text | null\n    while ((node = walker.nextNode() as Text | null)) {\n      const text = node.textContent?.trim() ?? ''\n      if (!markers.some((m) => text.startsWith(m))) continue\n\n      const span = node.parentElement\n      if (!span) continue\n\n      const el = (span.closest('[class*=\"line\"]') as HTMLElement | null) ?? span\n      const viewportRect = viewport.getBoundingClientRect()\n      viewport.scrollTo({\n        top: viewport.scrollTop + el.getBoundingClientRect().top - viewportRect.top - 32,\n        behavior: 'smooth',\n      })\n\n      highlightTimersRef.current.forEach(clearTimeout)\n      el.style.backgroundColor = 'rgba(34, 197, 94, 0.2)'\n      el.style.borderRadius = '3px'\n      highlightTimersRef.current = [\n        setTimeout(() => {\n          el.style.transition = 'background-color 1.5s ease-out'\n          el.style.backgroundColor = 'rgba(34, 197, 94, 0)'\n        }, 500),\n        setTimeout(() => {\n          el.style.backgroundColor = ''\n          el.style.transition = ''\n          el.style.borderRadius = ''\n        }, 2100),\n      ]\n      return\n    }\n  }, [])\n\n  useEffect(() => {\n    if (!pendingScrollSection) return\n    requestAnimationFrame(() => {\n      scrollToSection(pendingScrollSection)\n      clearPendingScrollSection()\n    })\n  }, [pendingScrollSection, scrollToSection, clearPendingScrollSection])\n\n  const codeSnippetParams = useMemo<CodeSnippetParams>(\n    () => ({\n      state: sandboxParametersState,\n      config: getSandboxParametersInfo(),\n      actions: {\n        useConfigObject,\n        fileSystemListFilesLocationSet,\n        fileSystemCreateFolderParamsSet,\n        fileSystemDeleteFileRequiredParamsSet,\n        useFileSystemDeleteFileRecursive,\n        shellCommandExists,\n        codeToRunExists,\n        gitCloneOperationRequiredParamsSet,\n        useGitCloneBranch,\n        useGitCloneCommitId,\n        useGitCloneUsername,\n        useGitClonePassword,\n        gitStatusOperationLocationSet,\n        gitBranchesOperationLocationSet,\n      },\n    }),\n    [\n      sandboxParametersState,\n      getSandboxParametersInfo,\n      useConfigObject,\n      fileSystemListFilesLocationSet,\n      fileSystemCreateFolderParamsSet,\n      fileSystemDeleteFileRequiredParamsSet,\n      useFileSystemDeleteFileRecursive,\n      shellCommandExists,\n      codeToRunExists,\n      gitCloneOperationRequiredParamsSet,\n      useGitCloneBranch,\n      useGitCloneCommitId,\n      useGitCloneUsername,\n      useGitClonePassword,\n      gitStatusOperationLocationSet,\n      gitBranchesOperationLocationSet,\n    ],\n  )\n\n  const sandboxCodeSnippetsData = useMemo(\n    () => ({\n      [CodeLanguage.PYTHON]: { code: codeSnippetGenerators[CodeLanguage.PYTHON].buildFullSnippet(codeSnippetParams) },\n      [CodeLanguage.TYPESCRIPT]: {\n        code: codeSnippetGenerators[CodeLanguage.TYPESCRIPT].buildFullSnippet(codeSnippetParams),\n      },\n    }),\n    [codeSnippetParams],\n  )\n\n  const runCodeSnippet = async () => {\n    setIsCodeSnippetRunning(true)\n    let codeSnippetOutput = 'Creating sandbox...\\n'\n    setCodeSnippetOutput(codeSnippetOutput)\n    let sandbox: Sandbox | undefined\n\n    try {\n      sandbox = await createSandbox()\n      codeSnippetOutput = `Sandbox successfully created: ${sandbox.id}\\n`\n      setCodeSnippetOutput(codeSnippetOutput)\n      if (codeToRunExists) {\n        setCodeSnippetOutput(codeSnippetOutput + '\\nRunning code...')\n        const codeRunResponse = await sandbox.process.codeRun(\n          sandboxParametersState['codeRunParams'].languageCode as string,\n        ) // codeToRunExists guarantees that value isn't undefined so we put as string to silence TS compiler\n        codeSnippetOutput += `\\nCode run result: ${codeRunResponse.result}`\n        setCodeSnippetOutput(codeSnippetOutput)\n      }\n      if (shellCommandExists) {\n        setCodeSnippetOutput(codeSnippetOutput + '\\nRunning shell command...')\n        const shellCommandResponse = await sandbox.process.executeCommand(\n          sandboxParametersState['shellCommandRunParams'].shellCommand as string, // shellCommandExists guarantees that value isn't undefined so we put as string to silence TS compiler\n        )\n        codeSnippetOutput += `\\nShell command result: ${shellCommandResponse.result}`\n        setCodeSnippetOutput(codeSnippetOutput)\n      }\n      let codeRunShellCommandFinishedMessage = '\\n'\n      if (codeToRunExists && shellCommandExists) {\n        codeRunShellCommandFinishedMessage += '🎉 Code and shell command executed successfully.'\n      } else if (codeToRunExists) {\n        codeRunShellCommandFinishedMessage += '🎉 Code executed successfully.'\n      } else if (shellCommandExists) {\n        codeRunShellCommandFinishedMessage += '🎉 Shell command executed successfully.'\n      }\n      codeSnippetOutput += codeRunShellCommandFinishedMessage + '\\n'\n      setCodeSnippetOutput(codeSnippetOutput)\n      if (fileSystemCreateFolderParamsSet) {\n        setCodeSnippetOutput(codeSnippetOutput + '\\nCreating directory...')\n        await sandbox.fs.createFolder(\n          sandboxParametersState['createFolderParams'].folderDestinationPath,\n          sandboxParametersState['createFolderParams'].permissions,\n        )\n        codeSnippetOutput += '\\n🎉 Directory created successfully.\\n'\n        setCodeSnippetOutput(codeSnippetOutput)\n      }\n      if (fileSystemListFilesLocationSet) {\n        setCodeSnippetOutput(codeSnippetOutput + '\\nListing directory files...')\n        const files = await sandbox.fs.listFiles(sandboxParametersState['listFilesParams'].directoryPath)\n        codeSnippetOutput += '\\nDirectory content:'\n        codeSnippetOutput += '\\n'\n        files.forEach((file) => {\n          codeSnippetOutput += `Name: ${file.name}\\n`\n          codeSnippetOutput += `Is directory: ${file.isDir}\\n`\n          codeSnippetOutput += `Size: ${file.size}\\n`\n          codeSnippetOutput += `Modified: ${file.modTime}\\n`\n        })\n        setCodeSnippetOutput(codeSnippetOutput)\n      }\n      if (fileSystemDeleteFileRequiredParamsSet) {\n        setCodeSnippetOutput(\n          codeSnippetOutput + `\\nDeleting ${useFileSystemDeleteFileRecursive ? 'directory' : 'file'}...`,\n        )\n        await sandbox.fs.deleteFile(\n          sandboxParametersState['deleteFileParams'].filePath,\n          useFileSystemDeleteFileRecursive || false,\n        )\n        codeSnippetOutput += `\\n🎉 ${useFileSystemDeleteFileRecursive ? 'Directory' : 'File'} deleted successfully.\\n`\n        setCodeSnippetOutput(codeSnippetOutput)\n      }\n      if (gitCloneOperationRequiredParamsSet) {\n        setCodeSnippetOutput(codeSnippetOutput + '\\nCloning repo...')\n        await sandbox.git.clone(\n          sandboxParametersState['gitCloneParams'].repositoryURL,\n          sandboxParametersState['gitCloneParams'].cloneDestinationPath,\n          useGitCloneBranch ? sandboxParametersState['gitCloneParams'].branchToClone : undefined,\n          useGitCloneCommitId ? sandboxParametersState['gitCloneParams'].commitToClone : undefined,\n          useGitCloneUsername ? sandboxParametersState['gitCloneParams'].authUsername : undefined,\n          useGitClonePassword ? sandboxParametersState['gitCloneParams'].authPassword : undefined,\n        )\n        codeSnippetOutput += '\\n🎉 Repository cloned successfully.\\n'\n        setCodeSnippetOutput(codeSnippetOutput)\n      }\n      if (gitStatusOperationLocationSet) {\n        setCodeSnippetOutput(codeSnippetOutput + '\\nFetching repository status...')\n        const status = await sandbox.git.status(sandboxParametersState['gitStatusParams'].repositoryPath)\n        codeSnippetOutput += `\\nCurrent branch: ${status.currentBranch}\\n`\n        codeSnippetOutput += `Commits ahead: ${status.ahead}\\n`\n        codeSnippetOutput += `Commits behind: ${status.behind}\\n`\n        status.fileStatus.forEach((file) => (codeSnippetOutput += `File: ${file.name}\\n`))\n        setCodeSnippetOutput(codeSnippetOutput)\n      }\n      if (gitBranchesOperationLocationSet) {\n        setCodeSnippetOutput(codeSnippetOutput + '\\nFetching repository branches...')\n        const response = await sandbox.git.branches(sandboxParametersState['gitBranchesParams'].repositoryPath)\n        codeSnippetOutput += '\\n'\n        response.branches.forEach((branch) => (codeSnippetOutput += `Branch: ${branch}\\n`))\n        setCodeSnippetOutput(codeSnippetOutput)\n      }\n      setCodeSnippetOutput(codeSnippetOutput + '\\nSandbox session finished.')\n    } catch (error) {\n      console.error(error)\n      setCodeSnippetOutput(\n        <>\n          <span>{codeSnippetOutput}</span>\n          <br />\n          {createErrorMessageOutput(error)}\n        </>,\n      )\n    } finally {\n      setIsCodeSnippetRunning(false)\n    }\n  }\n\n  const resultPanelRef = usePanelRef()\n\n  return (\n    <Window className={className}>\n      <WindowTitleBar>Sandbox Code</WindowTitleBar>\n      <WindowContent className=\"relative\">\n        <Tabs\n          value={codeSnippetLanguage}\n          className=\"flex flex-col gap-4\"\n          onValueChange={(languageValue) => setCodeSnippetLanguage(languageValue as CodeLanguage)}\n        >\n          <div className=\"flex justify-between items-center\">\n            <TabsList>\n              {codeSnippetSupportedLanguages.map((language) => (\n                <TabsTrigger\n                  key={language.value}\n                  value={language.value}\n                  className={cn('py-1 rounded-t-md', {\n                    'bg-foreground/10': codeSnippetLanguage === language.value,\n                  })}\n                >\n                  <div className=\"flex items-center text-sm\">\n                    <img src={language.icon} alt={`${language.label} icon`} className=\"w-4 h-4\" />\n                    <span className=\"ml-2\">{language.label}</span>\n                  </div>\n                </TabsTrigger>\n              ))}\n            </TabsList>\n            <div className=\"flex items-center gap-2\">\n              <Button\n                disabled={isCodeSnippetRunning}\n                variant=\"outline\"\n                className=\"ml-auto\"\n                onClick={() => {\n                  runCodeSnippet()\n                  if (resultPanelRef.current?.isCollapsed()) {\n                    resultPanelRef.current.resize(100)\n                  }\n                }}\n              >\n                {isCodeSnippetRunning ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <Play className=\"w-4 h-4\" />} Run\n              </Button>\n              <TooltipButton\n                tooltipText=\"Show result\"\n                className=\"!px-2\"\n                size=\"icon-sm\"\n                variant=\"outline\"\n                onClick={() => {\n                  if (resultPanelRef.current?.isCollapsed()) {\n                    resultPanelRef.current.resize('20%')\n                  } else {\n                    resultPanelRef.current?.collapse()\n                  }\n                }}\n              >\n                <PanelBottom />\n              </TooltipButton>\n            </div>\n          </div>\n          <Group orientation=\"vertical\" className=\"min-h-[500px] border-border rounded-b-md\">\n            <Panel minSize={'20%'}>\n              <div ref={codeScrollRef} className=\"h-full\">\n                {codeSnippetSupportedLanguages.map((language) => (\n                  <TabsContent\n                    key={language.value}\n                    value={language.value}\n                    className=\"rounded-md h-full overflow-auto mt-0\"\n                  >\n                    <CopyButton\n                      className=\"absolute right-4 z-10 backdrop-blur-sm\"\n                      variant=\"ghost\"\n                      size=\"icon-sm\"\n                      value={sandboxCodeSnippetsData[language.value].code}\n                    />\n                    <ScrollArea\n                      fade=\"mask\"\n                      horizontal\n                      className=\"h-full overflow-auto bg-[hsl(var(--code-background))]\"\n                      fadeOffset={35}\n                    >\n                      <CodeBlock\n                        showCopy={false}\n                        language={language.value}\n                        code={sandboxCodeSnippetsData[language.value].code}\n                        codeAreaClassName=\"text-sm [overflow:initial] min-w-fit h-full\"\n                      />\n                    </ScrollArea>\n                  </TabsContent>\n                ))}\n              </div>\n            </Panel>\n\n            <Panel maxSize=\"80%\" minSize=\"20%\" panelRef={resultPanelRef} collapsedSize={0} collapsible defaultSize={33}>\n              <div className=\"bg-background w-full border rounded-md overflow-auto h-full flex flex-col\">\n                <div className=\"flex justify-between border-b px-4 pr-2 py-1 text-xs items-center bg-muted/50\">\n                  <div className=\"text-muted-foreground font-mono\">Result</div>\n                  <div className=\"flex items-center gap-2\">\n                    <TooltipButton\n                      onClick={() => resultPanelRef.current?.resize('80%')}\n                      tooltipText=\"Maximize\"\n                      className=\"h-6 w-6\"\n                      size=\"sm\"\n                      variant=\"ghost\"\n                    >\n                      <ChevronUpIcon className=\"w-4 h-4\" />\n                    </TooltipButton>\n                    <TooltipButton\n                      tooltipText=\"Close\"\n                      className=\"h-6 w-6\"\n                      size=\"sm\"\n                      variant=\"ghost\"\n                      onClick={() => resultPanelRef.current?.collapse()}\n                    >\n                      <XIcon />\n                    </TooltipButton>\n                  </div>\n                </div>\n                <div className=\"flex-1 overflow-y-auto\">\n                  <ResponseCard\n                    responseContent={\n                      codeSnippetOutput || (\n                        <div className=\"text-muted-foreground font-mono\">Code output will be shown here...</div>\n                      )\n                    }\n                  />\n                </div>\n              </div>\n            </Panel>\n          </Group>\n        </Tabs>\n      </WindowContent>\n    </Window>\n  )\n}\n\nexport default SandboxCodeSnippetsResponse\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/Parameters/FileSystem.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  CreateFolderParams,\n  DeleteFileParams,\n  FileSystemActionFormData,\n  ListFilesParams,\n  ParameterFormData,\n  ParameterFormItem,\n} from '@/contexts/PlaygroundContext'\nimport { FileSystemActions } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport PlaygroundActionForm from '../../ActionForm'\nimport FormCheckboxInput from '../../Inputs/CheckboxInput'\nimport InlineInputFormControl from '../../Inputs/InlineInputFormControl'\nimport FormTextInput from '../../Inputs/TextInput'\n\nconst SandboxFileSystem: React.FC = () => {\n  const { sandboxParametersState, playgroundActionParamValueSetter } = usePlayground()\n  const createFolderParams = sandboxParametersState['createFolderParams']\n  const listFilesParams = sandboxParametersState['listFilesParams']\n  const deleteFileParams = sandboxParametersState['deleteFileParams']\n\n  const listFilesDirectoryFormData: ParameterFormItem & { key: 'directoryPath' } = {\n    label: 'Directory location',\n    key: 'directoryPath',\n    placeholder: 'Directory path to list',\n    required: true,\n  }\n\n  const createFolderParamsFormData: ParameterFormData<CreateFolderParams> = [\n    {\n      label: 'Folder location',\n      key: 'folderDestinationPath',\n      placeholder: 'Path where the directory should be created',\n      required: true,\n    },\n    {\n      label: 'Permissions',\n      key: 'permissions',\n      placeholder: 'Directory permissions in octal format (e.g. \"755\")',\n      required: true,\n    },\n  ]\n\n  const deleteFileLocationFormData: ParameterFormItem & { key: 'filePath' } = {\n    label: 'File location',\n    key: 'filePath',\n    placeholder: 'Path to the file or directory to delete',\n    required: true,\n  }\n  const deleteFileRecursiveFormData: ParameterFormItem & { key: 'recursive' } = {\n    label: 'Delete directory',\n    key: 'recursive',\n    placeholder: 'If the file is a directory, this must be true to delete it.',\n  }\n\n  const fileSystemActionsFormData: FileSystemActionFormData<ListFilesParams | CreateFolderParams | DeleteFileParams>[] =\n    [\n      {\n        methodName: FileSystemActions.CREATE_FOLDER,\n        label: 'createFolder()',\n        description: 'Creates a new directory in the Sandbox at the specified path with the given permissions',\n        parametersFormItems: createFolderParamsFormData,\n        parametersState: createFolderParams,\n      },\n      {\n        methodName: FileSystemActions.LIST_FILES,\n        label: 'listFiles()',\n        description: 'Lists files and directories in a given path and returns their information',\n        parametersFormItems: [listFilesDirectoryFormData],\n        parametersState: listFilesParams,\n      },\n      {\n        methodName: FileSystemActions.DELETE_FILE,\n        label: 'deleteFile()',\n        description: 'Deletes a file from the Sandbox',\n        parametersFormItems: [deleteFileLocationFormData, deleteFileRecursiveFormData],\n        parametersState: deleteFileParams,\n      },\n    ]\n\n  return (\n    <div className=\"space-y-6\">\n      {fileSystemActionsFormData.map((fileSystemAction) => (\n        <div key={fileSystemAction.methodName} className=\"space-y-4\">\n          <PlaygroundActionForm<FileSystemActions> actionFormItem={fileSystemAction} hideRunActionButton />\n          <div className=\"space-y-2\">\n            {fileSystemAction.methodName === FileSystemActions.LIST_FILES && (\n              <InlineInputFormControl formItem={listFilesDirectoryFormData}>\n                <FormTextInput\n                  formItem={listFilesDirectoryFormData}\n                  textValue={listFilesParams[listFilesDirectoryFormData.key]}\n                  onChangeHandler={(value) =>\n                    playgroundActionParamValueSetter(\n                      fileSystemAction,\n                      listFilesDirectoryFormData,\n                      'listFilesParams',\n                      value,\n                    )\n                  }\n                />\n              </InlineInputFormControl>\n            )}\n            {fileSystemAction.methodName === FileSystemActions.CREATE_FOLDER && (\n              <>\n                {createFolderParamsFormData.map((createFolderParamFormItem) => (\n                  <InlineInputFormControl key={createFolderParamFormItem.key} formItem={createFolderParamFormItem}>\n                    <FormTextInput\n                      formItem={createFolderParamFormItem}\n                      textValue={createFolderParams[createFolderParamFormItem.key]}\n                      onChangeHandler={(value) =>\n                        playgroundActionParamValueSetter(\n                          fileSystemAction,\n                          createFolderParamFormItem,\n                          'createFolderParams',\n                          value,\n                        )\n                      }\n                    />\n                  </InlineInputFormControl>\n                ))}\n              </>\n            )}\n            {fileSystemAction.methodName === FileSystemActions.DELETE_FILE && (\n              <>\n                <InlineInputFormControl formItem={deleteFileLocationFormData}>\n                  <FormTextInput\n                    formItem={deleteFileLocationFormData}\n                    textValue={deleteFileParams[deleteFileLocationFormData.key]}\n                    onChangeHandler={(value) =>\n                      playgroundActionParamValueSetter(\n                        fileSystemAction,\n                        deleteFileLocationFormData,\n                        'deleteFileParams',\n                        value,\n                      )\n                    }\n                  />\n                </InlineInputFormControl>\n                <InlineInputFormControl formItem={deleteFileRecursiveFormData}>\n                  <FormCheckboxInput\n                    formItem={deleteFileRecursiveFormData}\n                    checkedValue={deleteFileParams[deleteFileRecursiveFormData.key]}\n                    onChangeHandler={(checked) =>\n                      playgroundActionParamValueSetter(\n                        fileSystemAction,\n                        deleteFileRecursiveFormData,\n                        'deleteFileParams',\n                        checked,\n                      )\n                    }\n                  />\n                </InlineInputFormControl>\n              </>\n            )}\n          </div>\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default SandboxFileSystem\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/Parameters/GitOperations.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  GitBranchesParams,\n  GitCloneParams,\n  GitOperationsActionFormData,\n  GitStatusParams,\n  ParameterFormData,\n  ParameterFormItem,\n} from '@/contexts/PlaygroundContext'\nimport { GitOperationsActions } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport PlaygroundActionForm from '../../ActionForm'\nimport InlineInputFormControl from '../../Inputs/InlineInputFormControl'\nimport FormTextInput from '../../Inputs/TextInput'\n\nconst SandboxGitOperations: React.FC = () => {\n  const { sandboxParametersState, playgroundActionParamValueSetter } = usePlayground()\n  const gitCloneParams = sandboxParametersState['gitCloneParams']\n  const gitStatusParams = sandboxParametersState['gitStatusParams']\n  const gitBranchesParams = sandboxParametersState['gitBranchesParams']\n\n  const gitCloneParamsFormData: ParameterFormData<GitCloneParams> = [\n    { label: 'URL', key: 'repositoryURL', placeholder: 'Repository URL to clone from', required: true },\n    {\n      label: 'Destination',\n      key: 'cloneDestinationPath',\n      placeholder: 'Path where the repository should be cloned',\n      required: true,\n    },\n    { label: 'Branch', key: 'branchToClone', placeholder: 'Specific branch to clone' },\n    { label: 'Commit', key: 'commitToClone', placeholder: 'Specific commit to clone' },\n    { label: 'Username', key: 'authUsername', placeholder: 'Git username for authentication' },\n    { label: 'Password', key: 'authPassword', placeholder: 'Git password or token for authentication' },\n  ]\n\n  const gitRepoLocationFormData: ParameterFormItem & { key: 'repositoryPath' } = {\n    label: 'Repo location',\n    key: 'repositoryPath',\n    placeholder: 'Path to the Git repository root',\n    required: true,\n  }\n\n  const gitOperationsActionsFormData: GitOperationsActionFormData<\n    GitCloneParams | GitStatusParams | GitBranchesParams\n  >[] = [\n    {\n      methodName: GitOperationsActions.GIT_CLONE,\n      label: 'clone()',\n      description: 'Clones a Git repository into the specified path',\n      parametersFormItems: gitCloneParamsFormData,\n      parametersState: gitCloneParams,\n    },\n    {\n      methodName: GitOperationsActions.GIT_STATUS,\n      label: 'status()',\n      description: 'Gets the current Git repository status',\n      parametersFormItems: [gitRepoLocationFormData],\n      parametersState: gitStatusParams,\n    },\n    {\n      methodName: GitOperationsActions.GIT_BRANCHES_LIST,\n      label: 'branches()',\n      description: 'Lists branches in the repository',\n      parametersFormItems: [gitRepoLocationFormData],\n      parametersState: gitBranchesParams,\n    },\n  ]\n\n  return (\n    <div className=\"space-y-6\">\n      {gitOperationsActionsFormData.map((gitOperationsAction) => (\n        <div key={gitOperationsAction.methodName} className=\"space-y-4\">\n          <PlaygroundActionForm<GitOperationsActions> actionFormItem={gitOperationsAction} hideRunActionButton />\n          <div className=\"space-y-2\">\n            {gitOperationsAction.methodName === GitOperationsActions.GIT_CLONE && (\n              <>\n                {gitCloneParamsFormData.map((gitCloneParamFormItem) => (\n                  <InlineInputFormControl key={gitCloneParamFormItem.key} formItem={gitCloneParamFormItem}>\n                    <FormTextInput\n                      formItem={gitCloneParamFormItem}\n                      textValue={gitCloneParams[gitCloneParamFormItem.key]}\n                      onChangeHandler={(value) =>\n                        playgroundActionParamValueSetter(\n                          gitOperationsAction,\n                          gitCloneParamFormItem,\n                          'gitCloneParams',\n                          value,\n                        )\n                      }\n                    />\n                  </InlineInputFormControl>\n                ))}\n              </>\n            )}\n            {gitOperationsAction.methodName === GitOperationsActions.GIT_STATUS && (\n              <InlineInputFormControl formItem={gitRepoLocationFormData}>\n                <FormTextInput\n                  formItem={gitRepoLocationFormData}\n                  textValue={gitStatusParams[gitRepoLocationFormData.key]}\n                  onChangeHandler={(value) =>\n                    playgroundActionParamValueSetter(\n                      gitOperationsAction,\n                      gitRepoLocationFormData,\n                      'gitStatusParams',\n                      value,\n                    )\n                  }\n                />\n              </InlineInputFormControl>\n            )}\n            {gitOperationsAction.methodName === GitOperationsActions.GIT_BRANCHES_LIST && (\n              <InlineInputFormControl formItem={gitRepoLocationFormData}>\n                <FormTextInput\n                  formItem={gitRepoLocationFormData}\n                  textValue={gitBranchesParams[gitRepoLocationFormData.key]}\n                  onChangeHandler={(value) =>\n                    playgroundActionParamValueSetter(\n                      gitOperationsAction,\n                      gitRepoLocationFormData,\n                      'gitBranchesParams',\n                      value,\n                    )\n                  }\n                />\n              </InlineInputFormControl>\n            )}\n          </div>\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default SandboxGitOperations\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/Parameters/Management.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Tooltip } from '@/components/Tooltip'\nimport { Label } from '@/components/ui/label'\nimport { SANDBOX_SNAPSHOT_DEFAULT_VALUE } from '@/constants/Playground'\nimport { NumberParameterFormItem, ParameterFormItem } from '@/contexts/PlaygroundContext'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { getLanguageCodeToRun } from '@/lib/playground'\nimport { SnapshotDto } from '@daytonaio/api-client'\nimport { CodeLanguage, Resources } from '@daytonaio/sdk'\nimport { HelpCircleIcon } from 'lucide-react'\nimport InlineInputFormControl from '../../Inputs/InlineInputFormControl'\nimport FormNumberInput from '../../Inputs/NumberInput'\nimport FormSelectInput from '../../Inputs/SelectInput'\nimport StackedInputFormControl from '../../Inputs/StackedInputFormControl'\nimport { useEffect } from 'react'\n\n// TODO - Currently, snapshot selection is not supported in the Playground, so props are hardcoded to an empty array and false for loading. We keep snapshot parts commented to enable it in future if requested by users. Also, sandbox creation and code snippet generation suppoort snapshot selection, so they will work when snapshot selection is enabled in the UI without requiring any additional changes. Currently, the snapshot value is fixed to 'Default'\ntype SandboxManagementParametersProps = {\n  snapshotsData: Array<SnapshotDto>\n  snapshotsLoading: boolean\n}\n\nconst SandboxManagementParameters: React.FC<SandboxManagementParametersProps> = ({\n  snapshotsData,\n  snapshotsLoading,\n}) => {\n  const { sandboxParametersState, setSandboxParameterValue } = usePlayground()\n  const sandboxLanguage = sandboxParametersState['language']\n  const sandboxSnapshotName = sandboxParametersState['snapshotName']\n  const resources = sandboxParametersState['resources']\n  const sandboxFromImageParams = sandboxParametersState['createSandboxBaseParams']\n\n  const languageFormData: ParameterFormItem = {\n    label: 'Language',\n    key: 'language',\n    placeholder: 'Select sandbox language',\n  }\n\n  // const sandboxSnapshotFormData: ParameterFormItem = {\n  //   label: 'Snapshot',\n  //   key: 'snapshotName',\n  //   placeholder: 'Select sandbox snapshot',\n  // }\n\n  // Available languages\n  const languageOptions = [\n    {\n      value: CodeLanguage.PYTHON,\n      label: 'Python (default)',\n    },\n    {\n      value: CodeLanguage.TYPESCRIPT,\n      label: 'TypeScript',\n    },\n    {\n      value: CodeLanguage.JAVASCRIPT,\n      label: 'JavaScript',\n    },\n  ]\n  const resourcesFormData: (NumberParameterFormItem & { key: keyof Resources })[] = [\n    { label: 'Compute (vCPU)', key: 'cpu', min: 1, max: Infinity, placeholder: '1' },\n    { label: 'Memory (GiB)', key: 'memory', min: 1, max: Infinity, placeholder: '1' },\n    { label: 'Storage (GiB)', key: 'disk', min: 1, max: Infinity, placeholder: '3' },\n  ]\n\n  const lifecycleParamsFormData: (NumberParameterFormItem & {\n    key: 'autoStopInterval' | 'autoArchiveInterval' | 'autoDeleteInterval'\n  })[] = [\n    { label: 'Stop (min)', key: 'autoStopInterval', min: 0, max: Infinity, placeholder: '15' },\n    { label: 'Archive (min)', key: 'autoArchiveInterval', min: 0, max: Infinity, placeholder: '7' },\n    { label: 'Delete (min)', key: 'autoDeleteInterval', min: -1, max: Infinity, placeholder: '' },\n  ]\n\n  // Change code to run based on selected sandbox language\n  useEffect(() => {\n    setSandboxParameterValue('codeRunParams', {\n      languageCode: getLanguageCodeToRun(sandboxParametersState.language),\n    })\n  }, [sandboxParametersState.language, setSandboxParameterValue])\n\n  const nonDefaultSnapshotSelected = sandboxSnapshotName && sandboxSnapshotName !== SANDBOX_SNAPSHOT_DEFAULT_VALUE\n\n  return (\n    <>\n      <StackedInputFormControl formItem={languageFormData}>\n        <FormSelectInput\n          selectOptions={languageOptions}\n          selectValue={sandboxLanguage}\n          formItem={languageFormData}\n          onChangeHandler={(value) => {\n            setSandboxParameterValue(languageFormData.key as 'language', value as CodeLanguage)\n          }}\n        />\n      </StackedInputFormControl>\n      {/* <StackedInputFormControl formItem={sandboxSnapshotFormData}>\n        <FormSelectInput\n          selectOptions={[\n            { value: SANDBOX_SNAPSHOT_DEFAULT_VALUE, label: 'Default' },\n            ...snapshotsData.map((snapshot) => ({\n              value: snapshot.name,\n              label: snapshot.name,\n            })),\n          ]}\n          loading={snapshotsLoading}\n          selectValue={sandboxSnapshotName}\n          formItem={sandboxSnapshotFormData}\n          onChangeHandler={(snapshotName) => {\n            setSandboxParameterValue(sandboxSnapshotFormData.key as 'snapshotName', snapshotName)\n          }}\n        />\n      </StackedInputFormControl> */}\n      <div className=\"space-y-2\">\n        <div className=\"flex items-center gap-2\">\n          <Label htmlFor=\"resources\" className=\"text-sm text-muted-foreground\">\n            Resources\n          </Label>\n          {nonDefaultSnapshotSelected && (\n            <Tooltip\n              content={\n                <div className=\"text-balance text-center max-w-[300px]\">\n                  Resources cannot be modified when a non-default snapshot is selected.\n                </div>\n              }\n              label={\n                <button className=\"rounded-full\">\n                  <HelpCircleIcon className=\"h-4 w-4 text-muted-foreground\" />\n                </button>\n              }\n            />\n          )}\n        </div>\n        <div id=\"resources\" className=\"space-y-2\">\n          {resourcesFormData.map((resourceParamFormItem) => (\n            <InlineInputFormControl key={resourceParamFormItem.key} formItem={resourceParamFormItem}>\n              <FormNumberInput\n                disabled={Boolean(nonDefaultSnapshotSelected)}\n                numberValue={resources[resourceParamFormItem.key]}\n                numberFormItem={resourceParamFormItem}\n                onChangeHandler={(value) => {\n                  setSandboxParameterValue('resources', { ...resources, [resourceParamFormItem.key]: value })\n                }}\n              />\n            </InlineInputFormControl>\n          ))}\n        </div>\n      </div>\n      <div className=\"space-y-2\">\n        <Label htmlFor=\"lifecycle\" className=\"text-sm text-muted-foreground\">\n          Lifecycle\n        </Label>\n        <div id=\"lifecycle\" className=\"space-y-2\">\n          {lifecycleParamsFormData.map((lifecycleParamFormItem) => (\n            <InlineInputFormControl key={lifecycleParamFormItem.key} formItem={lifecycleParamFormItem}>\n              <FormNumberInput\n                numberValue={sandboxFromImageParams[lifecycleParamFormItem.key]}\n                numberFormItem={lifecycleParamFormItem}\n                onChangeHandler={(value) => {\n                  setSandboxParameterValue('createSandboxBaseParams', {\n                    ...sandboxFromImageParams,\n                    [lifecycleParamFormItem.key]: value,\n                  })\n                }}\n              />\n            </InlineInputFormControl>\n          ))}\n        </div>\n      </div>\n    </>\n  )\n}\n\nexport default SandboxManagementParameters\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/Parameters/ProcessCodeExecution.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport CodeBlock from '@/components/CodeBlock'\nimport {\n  CodeRunParams,\n  ParameterFormItem,\n  ProcessCodeExecutionOperationsActionFormData,\n  ShellCommandRunParams,\n} from '@/contexts/PlaygroundContext'\nimport { ProcessCodeExecutionActions } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { CodeLanguage } from '@daytonaio/sdk'\nimport PlaygroundActionForm from '../../ActionForm'\nimport StackedInputFormControl from '../../Inputs/StackedInputFormControl'\n\nconst SandboxProcessCodeExecution: React.FC = () => {\n  const { sandboxParametersState, setSandboxParameterValue } = usePlayground()\n  const codeRunParams = sandboxParametersState['codeRunParams']\n  const shellCommandRunParams = sandboxParametersState['shellCommandRunParams']\n\n  const codeRunLanguageCodeFormData: ParameterFormItem & { key: 'languageCode' } = {\n    label: 'Code to execute',\n    key: 'languageCode',\n    placeholder: 'Write the code you want to execute inside the sandbox',\n    required: true,\n  }\n\n  const shellCommandFormData: ParameterFormItem & { key: 'shellCommand' } = {\n    label: 'Shell command',\n    key: 'shellCommand',\n    placeholder: 'Enter a shell command to run inside the sandbox',\n    required: true,\n  }\n\n  const processCodeExecutionActionsFormData: ProcessCodeExecutionOperationsActionFormData<\n    CodeRunParams | ShellCommandRunParams\n  >[] = [\n    {\n      methodName: ProcessCodeExecutionActions.CODE_RUN,\n      label: 'codeRun()',\n      description: 'Executes code in the Sandbox using the appropriate language runtime',\n      parametersFormItems: [codeRunLanguageCodeFormData],\n      parametersState: codeRunParams,\n    },\n    {\n      methodName: ProcessCodeExecutionActions.SHELL_COMMANDS_RUN,\n      label: 'executeCommand()',\n      description: 'Executes a shell command in the Sandbox',\n      parametersFormItems: [shellCommandFormData],\n      parametersState: shellCommandRunParams,\n    },\n  ]\n\n  //TODO -> Currently codeRun and executeCommand values are fixed -> when we enable user to define them implement onChange handlers with validatePlaygroundActionWithParams logic\n  return (\n    <div className=\"space-y-6\">\n      {processCodeExecutionActionsFormData.map((processCodeExecutionAction) => (\n        <div key={processCodeExecutionAction.methodName} className=\"space-y-4\">\n          <PlaygroundActionForm<ProcessCodeExecutionActions>\n            actionFormItem={processCodeExecutionAction}\n            hideRunActionButton\n          />\n          <div className=\"space-y-2\">\n            {processCodeExecutionAction.methodName === ProcessCodeExecutionActions.CODE_RUN && (\n              <StackedInputFormControl formItem={codeRunLanguageCodeFormData}>\n                <CodeBlock\n                  language={sandboxParametersState.language || CodeLanguage.PYTHON} // Python is default language if none specified\n                  code={codeRunParams[codeRunLanguageCodeFormData.key] || ''}\n                />\n              </StackedInputFormControl>\n            )}\n            {processCodeExecutionAction.methodName === ProcessCodeExecutionActions.SHELL_COMMANDS_RUN && (\n              <StackedInputFormControl formItem={shellCommandFormData}>\n                <CodeBlock language=\"bash\" code={shellCommandRunParams[shellCommandFormData.key] || ''} />\n              </StackedInputFormControl>\n            )}\n          </div>\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default SandboxProcessCodeExecution\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Sandbox/Parameters/index.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'\nimport { Switch } from '@/components/ui/switch'\nimport { SandboxParametersSections } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { cn } from '@/lib/utils'\nimport { BoltIcon, FolderIcon, GitBranchIcon, SquareTerminalIcon } from 'lucide-react'\nimport SandboxFileSystem from './FileSystem'\nimport SandboxGitOperations from './GitOperations'\nimport SandboxManagementParameters from './Management'\nimport SandboxProcessCodeExecution from './ProcessCodeExecution'\n\nconst sandboxParametersSectionsData = [\n  { value: SandboxParametersSections.SANDBOX_MANAGEMENT, label: 'Management' },\n  { value: SandboxParametersSections.FILE_SYSTEM, label: 'File System' },\n  { value: SandboxParametersSections.GIT_OPERATIONS, label: 'Git Operations' },\n  { value: SandboxParametersSections.PROCESS_CODE_EXECUTION, label: 'Process & Code Execution' },\n]\n\nconst sectionIcons = {\n  [SandboxParametersSections.SANDBOX_MANAGEMENT]: <BoltIcon strokeWidth={1.5} />,\n  [SandboxParametersSections.GIT_OPERATIONS]: <GitBranchIcon strokeWidth={1.5} />,\n  [SandboxParametersSections.FILE_SYSTEM]: <FolderIcon strokeWidth={1.5} />,\n  [SandboxParametersSections.PROCESS_CODE_EXECUTION]: <SquareTerminalIcon strokeWidth={1.5} />,\n}\n\nconst SandboxParameters = ({ className }: { className?: string }) => {\n  const { openedParametersSections, setOpenedParametersSections, enabledSections, enableSection, disableSection } =\n    usePlayground()\n\n  // TODO - Currently, snapshot selection is not supported in the Playground, so we are using empty array and false for loading. We keep to code commented to enable it in future if requested by users.\n  // const { snapshotApi } = useApi()\n  // const { selectedOrganization } = useSelectedOrganization()\n\n  // const { data: snapshotsData = [], isLoading: snapshotsLoading } = useQuery({\n  //   queryKey: ['snapshots', selectedOrganization?.id, 'all'],\n  //   queryFn: async () => {\n  //     if (!selectedOrganization) return []\n  //     const response = await snapshotApi.getAllSnapshots(selectedOrganization.id)\n  //     return response.data.items\n  //   },\n  //   enabled: !!selectedOrganization,\n  // })\n\n  return (\n    <div className={cn('flex flex-col gap-6', className)}>\n      <div>\n        <h2>Sandbox Configuration</h2>\n        <p className=\"text-sm text-muted-foreground mt-1\">Manage resources, lifecycle policies, and file systems.</p>\n      </div>\n      <Accordion\n        type=\"multiple\"\n        value={openedParametersSections}\n        onValueChange={(sections) => setOpenedParametersSections(sections as SandboxParametersSections[])}\n      >\n        {sandboxParametersSectionsData.map((section) => {\n          const isManagement = section.value === SandboxParametersSections.SANDBOX_MANAGEMENT\n          const isEnabled = enabledSections.includes(section.value as SandboxParametersSections)\n          const isExpanded = openedParametersSections.includes(section.value as SandboxParametersSections)\n          return (\n            <AccordionItem\n              key={section.value}\n              value={section.value}\n              className=\"border px-2 last:border-b first:rounded-t-lg last:rounded-b-lg border-t-0 first:border-t\"\n            >\n              <AccordionTrigger\n                headerClassName={cn(\n                  'font-semibold text-muted-foreground dark:bg-muted/50 bg-muted/80 border-b -mx-2 px-3',\n                  {\n                    'border-b-border': isExpanded,\n                    'border-b-transparent': !isExpanded,\n                    'opacity-80': !isEnabled && !isManagement,\n                  },\n                )}\n                className=\"hover:no-underline hover:text-primary py-3\"\n                right={\n                  !isManagement ? (\n                    <Switch\n                      checked={isEnabled}\n                      onCheckedChange={(checked) =>\n                        checked\n                          ? enableSection(section.value as SandboxParametersSections)\n                          : disableSection(section.value as SandboxParametersSections)\n                      }\n                      size=\"sm\"\n                      className=\"ml-3\"\n                    />\n                  ) : undefined\n                }\n              >\n                <div className=\"flex items-center gap-2 [&_svg]:size-4 text-sm font-medium\">\n                  {sectionIcons[section.value]} {section.label}\n                </div>\n              </AccordionTrigger>\n              <AccordionContent className=\"py-3 px-1\">\n                {isExpanded && (\n                  <div className=\"space-y-4\">\n                    {section.value === SandboxParametersSections.FILE_SYSTEM && <SandboxFileSystem />}\n                    {section.value === SandboxParametersSections.GIT_OPERATIONS && <SandboxGitOperations />}\n                    {section.value === SandboxParametersSections.SANDBOX_MANAGEMENT && (\n                      <SandboxManagementParameters snapshotsData={[]} snapshotsLoading={false} />\n                    )}\n                    {section.value === SandboxParametersSections.PROCESS_CODE_EXECUTION && (\n                      <SandboxProcessCodeExecution />\n                    )}\n                  </div>\n                )}\n              </AccordionContent>\n            </AccordionItem>\n          )\n        })}\n      </Accordion>\n    </div>\n  )\n}\n\nexport default SandboxParameters\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Terminal/Description.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { TerminalIcon } from 'lucide-react'\n\nconst sampleCommands = ['ls -la', 'top', 'ps aux', 'df -h']\n\nconst TerminalCommand = ({ value }: { value: string }) => {\n  return (\n    <div className=\"bg-muted/50 px-2 py-1 text-muted-foreground rounded-md font-mono flex justify-between group items-center\">\n      <span>\n        <span className=\"mr-2 opacity-50\">$</span>\n        {value}\n      </span>\n      <CopyButton value={value} variant=\"ghost\" className=\"size-6 [&>svg]:size-3\" />\n    </div>\n  )\n}\n\nconst TerminalDescription: React.FC = () => {\n  return (\n    <div className=\"flex flex-col gap-6\">\n      <div>\n        <h2>Web Terminal</h2>\n        <p className=\"text-muted-foreground text-sm mt-1\">\n          Run commands, view files, and debug directly in the browser.\n        </p>\n      </div>\n      <div className=\"text-sm\">\n        <h3 className=\"text-muted-foreground flex items-center gap-2 font-semibold py-3\">\n          <TerminalIcon className=\"size-4\" />\n          Common Commands\n        </h3>\n        <ul className=\"flex flex-col gap-1.5\">\n          {sampleCommands.map((cmd) => (\n            <li key={cmd}>\n              <TerminalCommand value={cmd} />\n            </li>\n          ))}\n        </ul>\n      </div>\n    </div>\n  )\n}\n\nexport default TerminalDescription\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Terminal/WebTerminal.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Spinner } from '@/components/ui/spinner'\nimport { usePlaygroundSandbox } from '@/hooks/usePlaygroundSandbox'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { RefreshCcw } from 'lucide-react'\nimport { Window, WindowContent, WindowTitleBar } from '../Window'\n\nconst motionLoadingProps = {\n  initial: { opacity: 0, y: 10 },\n  animate: { opacity: 1, y: 0 },\n  exit: { opacity: 0, y: -10 },\n  transition: { duration: 0.175 },\n}\n\nconst WebTerminal: React.FC<{ className?: string }> = ({ className }) => {\n  const { sandbox, terminal } = usePlaygroundSandbox()\n  const loadingTerminalUrl = terminal.loading || (!sandbox.instance && !sandbox.error)\n\n  return (\n    <Window className={className}>\n      <WindowTitleBar>Sandbox Terminal</WindowTitleBar>\n      <WindowContent>\n        <div className=\"w-full bg-muted/40 dark:bg-muted/10 min-h-[500px] flex flex-col [&>*]:flex-1\">\n          {loadingTerminalUrl || !terminal.url ? (\n            <div className=\"h-full flex items-center justify-center rounded-lg\">\n              <AnimatePresence mode=\"wait\">\n                {loadingTerminalUrl ? (\n                  <motion.p className=\"flex items-center gap-2\" key=\"loading\" {...motionLoadingProps}>\n                    <Spinner className=\"size-4 mr-2\" /> Loading terminal...\n                  </motion.p>\n                ) : (\n                  <motion.p\n                    key=\"error\"\n                    className=\"flex flex-col items-center justify-center gap-2\"\n                    {...motionLoadingProps}\n                  >\n                    There was an error loading the terminal.\n                    {sandbox.instance ? (\n                      <Button variant=\"outline\" className=\"ml-2\" onClick={() => terminal.refetch()}>\n                        <RefreshCcw className=\"size-4\" />\n                        Retry\n                      </Button>\n                    ) : (\n                      sandbox.error && <span className=\"text-sm text-muted-foreground\">{sandbox.error}</span>\n                    )}\n                  </motion.p>\n                )}\n              </AnimatePresence>\n            </div>\n          ) : (\n            <iframe title=\"Interactive web terminal for sandbox\" src={terminal.url} width={'100%'} height={'100%'} />\n          )}\n        </div>\n      </WindowContent>\n    </Window>\n  )\n}\n\nexport default WebTerminal\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/VNC/DesktopWindowResponse.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport TooltipButton from '@/components/TooltipButton'\nimport { Button } from '@/components/ui/button'\nimport { Spinner } from '@/components/ui/spinner'\nimport { DAYTONA_DOCS_URL } from '@/constants/ExternalLinks'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { usePlaygroundSandbox } from '@/hooks/usePlaygroundSandbox'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { ChevronUpIcon, RefreshCcw, XIcon } from 'lucide-react'\nimport { useEffect } from 'react'\nimport { Group, Panel, usePanelRef } from 'react-resizable-panels'\nimport ResponseCard from '../ResponseCard'\nimport { Window, WindowContent, WindowTitleBar } from '../Window'\n\nconst motionLoadingProps = {\n  initial: { opacity: 0, y: 10 },\n  animate: { opacity: 1, y: 0 },\n  exit: { opacity: 0, y: -10 },\n  transition: { duration: 0.175 },\n}\n\nconst isMissingDependenciesError = (message: string) => {\n  return message === 'Computer-use functionality is not available'\n}\n\nconst VNCErrorContent: React.FC<{ message: string }> = ({ message }) => {\n  if (isMissingDependenciesError(message)) {\n    return (\n      <div className=\"text-muted-foreground/80 text-center text-sm\">\n        <div className=\"font-medium text-muted-foreground\">Computer-use functionality is not available.</div>\n        <div className=\"mt-3\">Computer-use dependencies are missing in the runtime environment.</div>\n        <div className=\"mt-2\">\n          <a\n            href={`${DAYTONA_DOCS_URL}/en/vnc-access/`}\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n            className=\"text-primary hover:underline\"\n          >\n            Read the computer-use guide\n          </a>{' '}\n          to learn more.\n        </div>\n      </div>\n    )\n  }\n\n  return <div>{message}</div>\n}\n\nconst VNCDesktopWindowResponse: React.FC<{ className?: string }> = ({ className }) => {\n  const { VNCInteractionOptionsParamsState } = usePlayground()\n  const { sandbox, vnc } = usePlaygroundSandbox()\n\n  const loadingVNCUrl = vnc.loading || (!sandbox.instance && !sandbox.error)\n\n  const resultPanelRef = usePanelRef()\n\n  useEffect(() => {\n    if (resultPanelRef.current?.isCollapsed()) {\n      resultPanelRef.current?.resize('20%')\n    }\n  }, [VNCInteractionOptionsParamsState.responseContent, resultPanelRef])\n\n  return (\n    <Window className={className}>\n      <WindowTitleBar>Desktop Window </WindowTitleBar>\n      <WindowContent className=\"w-full flex flex-col items-center justify-center\">\n        <Group orientation=\"vertical\" className=\"aspect-[4/3] border-border rounded-b-md\">\n          <Panel minSize={'20%'} className=\"overflow-auto\">\n            <div className=\"aspect-[4/3] bg-muted/40 dark:bg-muted/10 rounded-lg\">\n              {loadingVNCUrl || vnc.error || !vnc.url ? (\n                <div className=\"h-full flex items-center justify-center rounded-lg\">\n                  <AnimatePresence mode=\"wait\">\n                    {loadingVNCUrl ? (\n                      <motion.div className=\"flex items-center gap-2\" key=\"loading\" {...motionLoadingProps}>\n                        <Spinner className=\"size-4 mr-2\" /> Loading VNC...\n                      </motion.div>\n                    ) : (\n                      <motion.div\n                        key=\"error\"\n                        className=\"flex flex-col items-center justify-center gap-2 text-center max-w-sm text-pretty\"\n                        {...motionLoadingProps}\n                      >\n                        {vnc.error && <VNCErrorContent message={vnc.error || 'There was an error loading VNC.'} />}\n\n                        {sandbox.instance ? (\n                          <Button variant=\"outline\" className=\"mt-2\" onClick={() => vnc.refetch()}>\n                            <RefreshCcw className=\"size-4\" />\n                            Retry\n                          </Button>\n                        ) : (\n                          sandbox.error && <span className=\"text-sm text-muted-foreground\">{sandbox.error}</span>\n                        )}\n                      </motion.div>\n                    )}\n                  </AnimatePresence>\n                </div>\n              ) : (\n                <iframe\n                  title=\"VNC desktop window\"\n                  src={`${vnc.url}/vnc.html?autoconnect=true&resize=scale`}\n                  className=\"w-full h-full\"\n                />\n              )}\n            </div>\n          </Panel>\n\n          <Panel maxSize=\"80%\" minSize=\"20%\" panelRef={resultPanelRef} collapsedSize={0} collapsible defaultSize={0}>\n            <div className=\"bg-background w-full border rounded-md overflow-auto flex flex-col h-full\">\n              <div className=\"flex justify-between border-b px-4 pr-2 py-1 text-xs items-center dark:bg-muted/50\">\n                <div className=\"text-muted-foreground font-mono\">Result</div>\n                <div className=\"flex items-center gap-2\">\n                  <TooltipButton\n                    onClick={() => resultPanelRef.current?.resize('80%')}\n                    tooltipText=\"Maximize\"\n                    className=\"h-6 w-6\"\n                    size=\"sm\"\n                    variant=\"ghost\"\n                  >\n                    <ChevronUpIcon className=\"w-4 h-4\" />\n                  </TooltipButton>\n                  <TooltipButton\n                    tooltipText=\"Close\"\n                    className=\"h-6 w-6\"\n                    size=\"sm\"\n                    variant=\"ghost\"\n                    onClick={() => resultPanelRef.current?.collapse()}\n                  >\n                    <XIcon />\n                  </TooltipButton>\n                </div>\n              </div>\n              <div className=\"flex-1 overflow-y-auto\">\n                <ResponseCard\n                  responseContent={\n                    VNCInteractionOptionsParamsState.responseContent || (\n                      <div className=\"text-muted-foreground font-mono\">Interaction results will be shown here...</div>\n                    )\n                  }\n                />\n              </div>\n            </div>\n          </Panel>\n        </Group>\n      </WindowContent>\n    </Window>\n  )\n}\n\nexport default VNCDesktopWindowResponse\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/VNC/Interaction/Display.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  PlaygroundActionFormDataBasic,\n  PlaygroundActionInvokeApi,\n  VNCInteractionOptionsSectionComponentProps,\n} from '@/contexts/PlaygroundContext'\nimport { DisplayActions } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { DisplayInfoResponse, WindowsResponse } from '@daytonaio/api-client'\nimport { ComputerUse } from '@daytonaio/sdk'\nimport PlaygroundActionForm from '../../ActionForm'\n\nconst VNCDisplayOperations: React.FC<VNCInteractionOptionsSectionComponentProps> = ({\n  disableActions,\n  ComputerUseClient,\n  wrapVNCInvokeApi,\n}) => {\n  const { runPlaygroundActionWithoutParams, setVNCInteractionOptionsParamValue } = usePlayground()\n\n  const displayActionsFormData: PlaygroundActionFormDataBasic<DisplayActions>[] = [\n    {\n      methodName: DisplayActions.GET_INFO,\n      label: 'getInfo()',\n      description: 'Gets information about the displays',\n    },\n    {\n      methodName: DisplayActions.GET_WINDOWS,\n      label: 'getWindows()',\n      description: 'Gets the list of open windows',\n    },\n  ]\n\n  // Disable logic ensures that this method is called when ComputerUseClient exists -> we use as ComputerUse to silence TS compiler\n  const displayActionAPICall: PlaygroundActionInvokeApi = async (displayActionFormData) => {\n    const displayActionResponse = await (ComputerUseClient as ComputerUse).display[\n      displayActionFormData.methodName as DisplayActions\n    ]()\n    let displayActionResponseText = ''\n    switch (displayActionFormData.methodName) {\n      case DisplayActions.GET_INFO: {\n        const displayInfoResponse = displayActionResponse as DisplayInfoResponse\n        type Display = {\n          width: number\n          height: number\n          x: number\n          y: number\n        }\n        ;(displayInfoResponse.displays as Display[]).forEach((display, index) => {\n          displayActionResponseText += `Display ${index}: ${display.width}x${display.height} at ${display.x},${display.y}\\n`\n        })\n        break\n      }\n      case DisplayActions.GET_WINDOWS: {\n        const displayWindowsResponse = displayActionResponse as WindowsResponse\n        displayActionResponseText += `Found ${displayWindowsResponse.windows.length} open windows:\\n`\n        type Window = {\n          title: string\n          id: string\n        }\n        ;(displayWindowsResponse.windows as Window[]).forEach((window) => {\n          displayActionResponseText += `- ${window.title} (ID: ${window.id})\\n`\n        })\n        break\n      }\n    }\n    setVNCInteractionOptionsParamValue('responseContent', displayActionResponseText)\n  }\n\n  return (\n    <div className=\"flex flex-col gap-6\">\n      {displayActionsFormData.map((displayActionFormData) => (\n        <div key={displayActionFormData.methodName} className=\"space-y-4\">\n          <PlaygroundActionForm<DisplayActions>\n            actionFormItem={displayActionFormData}\n            onRunActionClick={() =>\n              runPlaygroundActionWithoutParams(displayActionFormData, wrapVNCInvokeApi(displayActionAPICall))\n            }\n            disable={disableActions}\n          />\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default VNCDisplayOperations\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/VNC/Interaction/Keyboard.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  KeyboardActionFormData,\n  KeyboardHotKey,\n  KeyboardPress,\n  KeyboardType,\n  NumberParameterFormItem,\n  ParameterFormData,\n  PlaygroundActionInvokeApi,\n  VNCInteractionOptionsSectionComponentProps,\n} from '@/contexts/PlaygroundContext'\nimport { KeyboardActions } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { ComputerUse } from '@daytonaio/sdk'\nimport PlaygroundActionForm from '../../ActionForm'\nimport InlineInputFormControl from '../../Inputs/InlineInputFormControl'\nimport FormNumberInput from '../../Inputs/NumberInput'\nimport FormTextInput from '../../Inputs/TextInput'\n\nconst VNCKeyboardOperations: React.FC<VNCInteractionOptionsSectionComponentProps> = ({\n  disableActions,\n  ComputerUseClient,\n  wrapVNCInvokeApi,\n}) => {\n  const {\n    VNCInteractionOptionsParamsState,\n    setVNCInteractionOptionsParamValue,\n    playgroundActionParamValueSetter,\n    runPlaygroundActionWithParams,\n  } = usePlayground()\n  const hotKeyParams = VNCInteractionOptionsParamsState['keyboardHotKeyParams']\n  const pressParams = VNCInteractionOptionsParamsState['keyboardPressParams']\n  const typeParams = VNCInteractionOptionsParamsState['keyboardTypeParams']\n\n  const hotKeyParamsFormData: ParameterFormData<KeyboardHotKey> = [\n    { label: 'Keys', key: 'keys', placeholder: 'ctrl+c, alt+tab', required: true },\n  ]\n\n  const pressParamsFormData: ParameterFormData<KeyboardPress> = [\n    { label: 'Key', key: 'key', placeholder: 'Enter', required: true },\n    { label: 'Modifiers', key: 'modifiers', placeholder: 'ctrl, alt, shift' },\n  ]\n\n  const typeParamsFormData: ParameterFormData<KeyboardType> = [\n    { label: 'Text', key: 'text', placeholder: 'Daytona', required: true },\n    { label: 'Delay(ms)', key: 'delay', placeholder: '50ms', min: 0, max: Infinity, step: 10 },\n  ]\n\n  const keyboardActionsFormData: KeyboardActionFormData<KeyboardHotKey | KeyboardPress | KeyboardType>[] = [\n    {\n      methodName: KeyboardActions.HOTKEY,\n      label: 'hotkey()',\n      description: 'Presses a hotkey combination',\n      parametersFormItems: hotKeyParamsFormData,\n      parametersState: hotKeyParams,\n      onChangeParamsValidationDisabled: true,\n    },\n    {\n      methodName: KeyboardActions.PRESS,\n      label: 'press()',\n      description: 'Presses a key with optional modifiers',\n      parametersFormItems: pressParamsFormData,\n      parametersState: pressParams,\n      onChangeParamsValidationDisabled: true,\n    },\n    {\n      methodName: KeyboardActions.TYPE,\n      label: 'type()',\n      description: 'Types the specified text',\n      parametersFormItems: typeParamsFormData,\n      parametersState: typeParams,\n      onChangeParamsValidationDisabled: true,\n    },\n  ]\n\n  // Disable logic ensures that this method is called when ComputerUseClient exists -> we use as ComputerUse to silence TS compiler\n  const keyboardActionAPICall: PlaygroundActionInvokeApi = async (keyboardActionFormData) => {\n    const KeyboardActionsClient = (ComputerUseClient as ComputerUse).keyboard\n    // All keyboard actions have Promise<void> return type -> we don't need the reponse\n    switch (keyboardActionFormData.methodName) {\n      case KeyboardActions.HOTKEY:\n        await KeyboardActionsClient[KeyboardActions.HOTKEY](hotKeyParams.keys)\n        break\n      case KeyboardActions.PRESS:\n        await KeyboardActionsClient[KeyboardActions.PRESS](\n          pressParams.key,\n          pressParams.modifiers\n            ? pressParams.modifiers\n                .split(',')\n                .map((item) => item.trim())\n                .filter((item) => item !== '')\n            : undefined,\n        )\n        break\n      case KeyboardActions.TYPE:\n        await KeyboardActionsClient[KeyboardActions.TYPE](typeParams.text, typeParams.delay ?? undefined)\n        break\n    }\n    setVNCInteractionOptionsParamValue('responseContent', '')\n  }\n\n  return (\n    <div className=\"space-y-6\">\n      {keyboardActionsFormData.map((keyboardAction) => (\n        <div key={keyboardAction.methodName} className=\"space-y-4\">\n          <PlaygroundActionForm<KeyboardActions>\n            actionFormItem={keyboardAction}\n            onRunActionClick={() =>\n              runPlaygroundActionWithParams(keyboardAction, wrapVNCInvokeApi(keyboardActionAPICall))\n            }\n            disable={disableActions}\n          />\n          <div className=\"space-y-2\">\n            {keyboardAction.methodName === KeyboardActions.HOTKEY && (\n              <InlineInputFormControl formItem={hotKeyParamsFormData[0]}>\n                <FormTextInput\n                  formItem={hotKeyParamsFormData[0]}\n                  textValue={hotKeyParams[hotKeyParamsFormData[0].key]}\n                  onChangeHandler={(value) =>\n                    playgroundActionParamValueSetter(\n                      keyboardAction,\n                      hotKeyParamsFormData[0],\n                      'keyboardHotKeyParams',\n                      value,\n                    )\n                  }\n                />\n              </InlineInputFormControl>\n            )}\n            {keyboardAction.methodName === KeyboardActions.PRESS && (\n              <>\n                {pressParamsFormData.map((pressParamFormItem) => (\n                  <InlineInputFormControl key={pressParamFormItem.key} formItem={pressParamFormItem}>\n                    <FormTextInput\n                      formItem={pressParamFormItem}\n                      textValue={pressParams[pressParamFormItem.key]}\n                      onChangeHandler={(value) =>\n                        playgroundActionParamValueSetter(\n                          keyboardAction,\n                          pressParamFormItem,\n                          'keyboardPressParams',\n                          value,\n                        )\n                      }\n                    />\n                  </InlineInputFormControl>\n                ))}\n              </>\n            )}\n            {keyboardAction.methodName === KeyboardActions.TYPE && (\n              <>\n                <InlineInputFormControl formItem={typeParamsFormData[0]}>\n                  <FormTextInput\n                    formItem={typeParamsFormData[0]}\n                    textValue={typeParams[typeParamsFormData[0].key as 'text']}\n                    onChangeHandler={(value) =>\n                      playgroundActionParamValueSetter(\n                        keyboardAction,\n                        typeParamsFormData[0],\n                        'keyboardTypeParams',\n                        value,\n                      )\n                    }\n                  />\n                </InlineInputFormControl>\n                <InlineInputFormControl formItem={typeParamsFormData[1]}>\n                  <FormNumberInput\n                    numberFormItem={typeParamsFormData[1] as NumberParameterFormItem}\n                    numberValue={typeParams[typeParamsFormData[1].key as 'delay']}\n                    onChangeHandler={(value) =>\n                      playgroundActionParamValueSetter(\n                        keyboardAction,\n                        typeParamsFormData[1],\n                        'keyboardTypeParams',\n                        value,\n                      )\n                    }\n                  />\n                </InlineInputFormControl>\n              </>\n            )}\n          </div>\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default VNCKeyboardOperations\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/VNC/Interaction/Mouse.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  MouseActionFormData,\n  MouseClick,\n  MouseDrag,\n  MouseMove,\n  MouseScroll,\n  NumberParameterFormItem,\n  ParameterFormData,\n  ParameterFormItem,\n  PlaygroundActionFormDataBasic,\n  PlaygroundActionInvokeApi,\n  VNCInteractionOptionsSectionComponentProps,\n} from '@/contexts/PlaygroundContext'\nimport { MouseActions, MouseButton, MouseScrollDirection } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { ComputerUse } from '@daytonaio/sdk'\nimport React from 'react'\nimport PlaygroundActionForm from '../../ActionForm'\nimport FormCheckboxInput from '../../Inputs/CheckboxInput'\nimport InlineInputFormControl from '../../Inputs/InlineInputFormControl'\nimport FormNumberInput from '../../Inputs/NumberInput'\nimport FormSelectInput from '../../Inputs/SelectInput'\n\nconst mouseButtonFormData: ParameterFormItem & { key: 'button' } = {\n  label: 'Button',\n  key: 'button',\n  placeholder: 'Select mouse button',\n}\n\ntype MouseActionWithParamsFormData = MouseActionFormData<MouseClick | MouseDrag | MouseMove | MouseScroll>\n\nconst VNCMouseOperations: React.FC<VNCInteractionOptionsSectionComponentProps> = ({\n  disableActions,\n  ComputerUseClient,\n  wrapVNCInvokeApi,\n}) => {\n  const {\n    VNCInteractionOptionsParamsState,\n    setVNCInteractionOptionsParamValue,\n    playgroundActionParamValueSetter,\n    runPlaygroundActionWithParams,\n    runPlaygroundActionWithoutParams,\n  } = usePlayground()\n  const mouseClickParams = VNCInteractionOptionsParamsState['mouseClickParams']\n  const mouseDragParams = VNCInteractionOptionsParamsState['mouseDragParams']\n  const mouseMoveParams = VNCInteractionOptionsParamsState['mouseMoveParams']\n  const mouseScrollParams = VNCInteractionOptionsParamsState['mouseScrollParams']\n\n  const mouseClickNumberParamsFormData: (NumberParameterFormItem & { key: 'x' | 'y' })[] = [\n    { label: 'Coord X', key: 'x', min: 0, max: Infinity, placeholder: '100', required: true },\n    { label: 'Coord Y', key: 'y', min: 0, max: Infinity, placeholder: '100', required: true },\n  ]\n\n  const mouseDoubleClickFormData: ParameterFormItem & { key: 'double' } = {\n    label: 'Double click',\n    key: 'double',\n    placeholder: 'Is mouse double click',\n  }\n\n  const mouseClickParamsFormData: ParameterFormData<MouseClick> = [\n    ...mouseClickNumberParamsFormData,\n    mouseButtonFormData,\n    mouseDoubleClickFormData,\n  ]\n\n  const mouseDragNumberParamsFormData: (NumberParameterFormItem & { key: 'startX' | 'startY' | 'endX' | 'endY' })[] = [\n    { label: 'Start X', key: 'startX', min: 0, max: Infinity, placeholder: '100', required: true },\n    { label: 'Start Y', key: 'startY', min: 0, max: Infinity, placeholder: '100', required: true },\n    { label: 'End X', key: 'endX', min: 0, max: Infinity, placeholder: '100', required: true },\n    { label: 'End Y', key: 'endY', min: 0, max: Infinity, placeholder: '100', required: true },\n  ]\n  const mouseDragParamsFormData: ParameterFormData<MouseDrag> = [...mouseDragNumberParamsFormData, mouseButtonFormData]\n\n  const mouseMoveNumberParamsFormData: (NumberParameterFormItem & { key: 'x' | 'y' })[] = [\n    { label: 'Coord X', key: 'x', min: 0, max: Infinity, placeholder: '100', required: true },\n    { label: 'Coord Y', key: 'y', min: 0, max: Infinity, placeholder: '100', required: true },\n  ]\n  const mouseMoveParamsFormData: ParameterFormData<MouseMove> = mouseMoveNumberParamsFormData\n\n  const mouseScrollNumberParamsFormData: (NumberParameterFormItem & { key: 'x' | 'y' })[] = [\n    { label: 'Coord X', key: 'x', min: 0, max: Infinity, placeholder: '100', required: true },\n    { label: 'Coord Y', key: 'y', min: 0, max: Infinity, placeholder: '100', required: true },\n  ]\n\n  const mouseScrollDirectionFormData: ParameterFormItem & { key: 'direction' } = {\n    label: 'Scroll direction',\n    key: 'direction',\n    placeholder: 'Mouse scroll direction',\n  }\n\n  const mouseScrollDirectionOptions = [\n    {\n      value: MouseScrollDirection.DOWN,\n      label: 'Down',\n    },\n    {\n      value: MouseScrollDirection.UP,\n      label: 'Up',\n    },\n  ]\n\n  const mouseScrollAmountFormData: NumberParameterFormItem & { key: 'amount' } = {\n    label: 'Scroll amount',\n    key: 'amount',\n    placeholder: 'Mouse scroll amount',\n    min: 1,\n    max: Infinity,\n  }\n\n  const mouseScrollParamsFormData: ParameterFormData<MouseScroll> = [\n    ...mouseScrollNumberParamsFormData,\n    mouseScrollDirectionFormData,\n    mouseScrollAmountFormData,\n  ]\n\n  const mouseActionsWithParamsFormData: MouseActionWithParamsFormData[] = [\n    {\n      methodName: MouseActions.CLICK,\n      label: 'click()',\n      description: 'Clicks the mouse at the specified coordinates',\n      parametersFormItems: mouseClickParamsFormData,\n      parametersState: mouseClickParams,\n      onChangeParamsValidationDisabled: true,\n    },\n    {\n      methodName: MouseActions.DRAG,\n      label: 'drag()',\n      description: 'Drags the mouse from start coordinates to end coordinates',\n      parametersFormItems: mouseDragParamsFormData,\n      parametersState: mouseDragParams,\n      onChangeParamsValidationDisabled: true,\n    },\n    {\n      methodName: MouseActions.MOVE,\n      label: 'move()',\n      description: 'Moves the mouse cursor to the specified coordinates',\n      parametersFormItems: mouseMoveParamsFormData,\n      parametersState: mouseMoveParams,\n      onChangeParamsValidationDisabled: true,\n    },\n    // {\n    //   methodName: MouseActions.SCROLL,\n    //   label: 'scroll()',\n    //   description: 'Scrolls the mouse wheel at the specified coordinates',\n    //   parametersFormItems: mouseScrollParamsFormData,\n    //   parametersState: mouseScrollParams,\n    //   onChangeParamsValidationDisabled: true,\n    // },\n  ]\n\n  const mouseActionsWithoutParamsFormData: PlaygroundActionFormDataBasic<MouseActions>[] = [\n    {\n      methodName: MouseActions.GET_POSITION,\n      label: 'getPosition()',\n      description: 'Gets the current mouse cursor position',\n    },\n  ]\n\n  // Disable logic ensures that this method is called when ComputerUseClient exists -> we use as ComputerUse to silence TS compiler\n  const mouseActionAPICall: PlaygroundActionInvokeApi = async (mouseActionFormData) => {\n    const MouseActionsClient = (ComputerUseClient as ComputerUse).mouse\n    let mouseActionResponseText = ''\n    switch (mouseActionFormData.methodName) {\n      case MouseActions.CLICK: {\n        const mouseClickResponse = await MouseActionsClient[MouseActions.CLICK](\n          mouseClickParams.x,\n          mouseClickParams.y,\n          mouseClickParams.button ?? undefined,\n          mouseClickParams.double,\n        )\n        mouseActionResponseText = `Mouse clicked at (${mouseClickResponse.x}, ${mouseClickResponse.y})`\n        break\n      }\n      case MouseActions.DRAG: {\n        const mouseDragResponse = await MouseActionsClient[MouseActions.DRAG](\n          mouseDragParams.startX,\n          mouseDragParams.startY,\n          mouseDragParams.endX,\n          mouseDragParams.endY,\n          mouseDragParams.button ?? undefined,\n        )\n        mouseActionResponseText = `Mouse drag ended at (${mouseDragResponse.x}, ${mouseDragResponse.y})`\n        break\n      }\n      case MouseActions.MOVE: {\n        const mouseMoveResponse = await MouseActionsClient[MouseActions.MOVE](mouseMoveParams.x, mouseMoveParams.y)\n        mouseActionResponseText = `Mouse moved to (${mouseMoveResponse.x}, ${mouseMoveResponse.y})`\n        break\n      }\n      case MouseActions.SCROLL: {\n        // The scroll promise never resolves, so we don't await it\n        const mouseScrollResponse = MouseActionsClient[MouseActions.SCROLL](\n          mouseScrollParams.x,\n          mouseScrollParams.y,\n          mouseScrollParams.direction,\n          mouseScrollParams.amount ?? undefined,\n        )\n        mouseActionResponseText = (await mouseScrollResponse)\n          ? `Mouse scrolled ${mouseScrollParams.direction} at (${mouseScrollParams.x}, ${mouseScrollParams.y}) by ${mouseScrollParams.amount ?? 1}`\n          : `Failed to scroll ${mouseScrollParams.direction} at (${mouseScrollParams.x}, ${mouseScrollParams.y})`\n        break\n      }\n      case MouseActions.GET_POSITION: {\n        const mousePositionResponse = await MouseActionsClient[MouseActions.GET_POSITION]()\n        mouseActionResponseText = `Mouse is at (${mousePositionResponse.x}, ${mousePositionResponse.y})`\n        break\n      }\n    }\n    setVNCInteractionOptionsParamValue('responseContent', mouseActionResponseText)\n  }\n\n  return (\n    <div className=\"flex flex-col gap-6\">\n      {mouseActionsWithParamsFormData.map((mouseActionFormData) => (\n        <div key={mouseActionFormData.methodName} className=\"space-y-4\">\n          <PlaygroundActionForm<MouseActions>\n            actionFormItem={mouseActionFormData}\n            onRunActionClick={() =>\n              runPlaygroundActionWithParams(mouseActionFormData, wrapVNCInvokeApi(mouseActionAPICall))\n            }\n            disable={disableActions}\n          />\n          <div className=\"space-y-2\">\n            {mouseActionFormData.methodName === MouseActions.CLICK && (\n              <>\n                {mouseClickNumberParamsFormData.map((mouseClickNumberParamFormItem) => (\n                  <InlineInputFormControl\n                    key={mouseClickNumberParamFormItem.key}\n                    formItem={mouseClickNumberParamFormItem}\n                  >\n                    <FormNumberInput\n                      numberValue={mouseClickParams[mouseClickNumberParamFormItem.key]}\n                      numberFormItem={mouseClickNumberParamFormItem}\n                      onChangeHandler={(value) =>\n                        playgroundActionParamValueSetter(\n                          mouseActionFormData,\n                          mouseClickNumberParamFormItem,\n                          'mouseClickParams',\n                          value,\n                        )\n                      }\n                    />\n                  </InlineInputFormControl>\n                ))}\n                <MouseButtonSelect<MouseClick>\n                  mouseActionFormData={mouseActionFormData}\n                  paramsStateObject={mouseClickParams}\n                  contextParamsPropertyName=\"mouseClickParams\"\n                />\n                <InlineInputFormControl formItem={mouseDoubleClickFormData}>\n                  <FormCheckboxInput\n                    checkedValue={mouseClickParams[mouseDoubleClickFormData.key as 'double']}\n                    formItem={mouseDoubleClickFormData}\n                    onChangeHandler={(checked) =>\n                      playgroundActionParamValueSetter(\n                        mouseActionFormData,\n                        mouseDoubleClickFormData,\n                        'mouseClickParams',\n                        checked,\n                      )\n                    }\n                  />\n                </InlineInputFormControl>\n              </>\n            )}\n            {mouseActionFormData.methodName === MouseActions.DRAG && (\n              <>\n                {mouseDragNumberParamsFormData.map((mouseDragNumberParamFormItem) => (\n                  <InlineInputFormControl\n                    key={mouseDragNumberParamFormItem.key}\n                    formItem={mouseDragNumberParamFormItem}\n                  >\n                    <FormNumberInput\n                      numberValue={mouseDragParams[mouseDragNumberParamFormItem.key]}\n                      numberFormItem={mouseDragNumberParamFormItem}\n                      onChangeHandler={(value) =>\n                        playgroundActionParamValueSetter(\n                          mouseActionFormData,\n                          mouseDragNumberParamFormItem,\n                          'mouseDragParams',\n                          value,\n                        )\n                      }\n                    />\n                  </InlineInputFormControl>\n                ))}\n                <MouseButtonSelect<MouseDrag>\n                  mouseActionFormData={mouseActionFormData}\n                  paramsStateObject={mouseDragParams}\n                  contextParamsPropertyName=\"mouseDragParams\"\n                />\n              </>\n            )}\n            {mouseActionFormData.methodName === MouseActions.MOVE && (\n              <>\n                {mouseMoveNumberParamsFormData.map((mouseMoveNumberParamFormItem) => (\n                  <InlineInputFormControl\n                    key={mouseMoveNumberParamFormItem.key}\n                    formItem={mouseMoveNumberParamFormItem}\n                  >\n                    <FormNumberInput\n                      numberValue={mouseMoveParams[mouseMoveNumberParamFormItem.key]}\n                      numberFormItem={mouseMoveNumberParamFormItem}\n                      onChangeHandler={(value) =>\n                        playgroundActionParamValueSetter(\n                          mouseActionFormData,\n                          mouseMoveNumberParamFormItem,\n                          'mouseMoveParams',\n                          value,\n                        )\n                      }\n                    />\n                  </InlineInputFormControl>\n                ))}\n              </>\n            )}\n            {mouseActionFormData.methodName === MouseActions.SCROLL && (\n              <>\n                {mouseScrollNumberParamsFormData.map((mouseScrollNumberParamFormItem) => (\n                  <InlineInputFormControl\n                    key={mouseScrollNumberParamFormItem.key}\n                    formItem={mouseScrollNumberParamFormItem}\n                  >\n                    <FormNumberInput\n                      numberValue={mouseScrollParams[mouseScrollNumberParamFormItem.key]}\n                      numberFormItem={mouseScrollNumberParamFormItem}\n                      onChangeHandler={(value) =>\n                        playgroundActionParamValueSetter(\n                          mouseActionFormData,\n                          mouseScrollNumberParamFormItem,\n                          'mouseScrollParams',\n                          value,\n                        )\n                      }\n                    />\n                  </InlineInputFormControl>\n                ))}\n                <InlineInputFormControl formItem={mouseScrollDirectionFormData}>\n                  <FormSelectInput\n                    selectOptions={mouseScrollDirectionOptions}\n                    selectValue={mouseScrollParams[mouseScrollDirectionFormData.key]}\n                    formItem={mouseScrollDirectionFormData}\n                    onChangeHandler={(value) =>\n                      playgroundActionParamValueSetter(\n                        mouseActionFormData,\n                        mouseScrollDirectionFormData,\n                        'mouseScrollParams',\n                        value,\n                      )\n                    }\n                  />\n                </InlineInputFormControl>\n                <InlineInputFormControl formItem={mouseScrollAmountFormData}>\n                  <FormNumberInput\n                    numberValue={mouseScrollParams[mouseScrollAmountFormData.key]}\n                    numberFormItem={mouseScrollAmountFormData}\n                    onChangeHandler={(value) =>\n                      playgroundActionParamValueSetter(\n                        mouseActionFormData,\n                        mouseScrollAmountFormData,\n                        'mouseScrollParams',\n                        value,\n                      )\n                    }\n                  />\n                </InlineInputFormControl>\n              </>\n            )}\n          </div>\n        </div>\n      ))}\n      {mouseActionsWithoutParamsFormData.map((mouseActionFormData) => (\n        <div key={mouseActionFormData.methodName} className=\"space-y-4\">\n          <PlaygroundActionForm<MouseActions>\n            actionFormItem={mouseActionFormData}\n            onRunActionClick={() =>\n              runPlaygroundActionWithoutParams(mouseActionFormData, wrapVNCInvokeApi(mouseActionAPICall))\n            }\n            disable={disableActions}\n          />\n        </div>\n      ))}\n    </div>\n  )\n}\n\ntype MouseButtonSelectProps<T> = {\n  mouseActionFormData: MouseActionWithParamsFormData\n  paramsStateObject: T\n  contextParamsPropertyName: 'mouseClickParams' | 'mouseDragParams'\n}\n\nconst MouseButtonSelect = <T extends MouseClick | MouseDrag>({\n  mouseActionFormData,\n  paramsStateObject,\n  contextParamsPropertyName,\n}: MouseButtonSelectProps<T>) => {\n  const { playgroundActionParamValueSetter } = usePlayground()\n\n  const mouseButtonOptions = [\n    {\n      value: MouseButton.LEFT,\n      label: 'Left',\n    },\n    {\n      value: MouseButton.MIDDLE,\n      label: 'Middle',\n    },\n    {\n      value: MouseButton.RIGHT,\n      label: 'Right',\n    },\n  ]\n\n  return (\n    <InlineInputFormControl formItem={mouseButtonFormData}>\n      <FormSelectInput\n        selectOptions={mouseButtonOptions}\n        selectValue={paramsStateObject[mouseButtonFormData.key as 'button']}\n        formItem={mouseButtonFormData}\n        onChangeHandler={(value) =>\n          playgroundActionParamValueSetter(mouseActionFormData, mouseButtonFormData, contextParamsPropertyName, value)\n        }\n      />\n    </InlineInputFormControl>\n  )\n}\n\nexport default VNCMouseOperations\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/VNC/Interaction/Screenshot.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Label } from '@/components/ui/label'\nimport {\n  CustomizedScreenshotOptions,\n  NumberParameterFormItem,\n  ParameterFormData,\n  ParameterFormItem,\n  PlaygroundActionInvokeApi,\n  ScreenshotActionFormData,\n  VNCInteractionOptionsSectionComponentProps,\n} from '@/contexts/PlaygroundContext'\nimport { ScreenshotActions, ScreenshotFormatOption } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { CompressedScreenshotResponse, RegionScreenshotResponse } from '@daytonaio/api-client'\nimport { ComputerUse, ScreenshotRegion } from '@daytonaio/sdk'\nimport { ScreenshotResponse } from '@daytonaio/toolbox-api-client'\nimport PlaygroundActionForm from '../../ActionForm'\nimport FormCheckboxInput from '../../Inputs/CheckboxInput'\nimport InlineInputFormControl from '../../Inputs/InlineInputFormControl'\nimport FormNumberInput from '../../Inputs/NumberInput'\nimport FormSelectInput from '../../Inputs/SelectInput'\n\nconst VNCScreenshotOperations: React.FC<VNCInteractionOptionsSectionComponentProps> = ({\n  disableActions,\n  ComputerUseClient,\n  wrapVNCInvokeApi,\n}) => {\n  const {\n    VNCInteractionOptionsParamsState,\n    setVNCInteractionOptionsParamValue,\n    playgroundActionParamValueSetter,\n    runPlaygroundActionWithParams,\n  } = usePlayground()\n  const screenshotOptions = VNCInteractionOptionsParamsState['screenshotOptionsConfig']\n  const screenshotRegion = VNCInteractionOptionsParamsState['screenshotRegionConfig']\n\n  const screenshotOptionsNumberParametersFormData: (NumberParameterFormItem & { key: 'quality' | 'scale' })[] = [\n    { label: 'Scale', key: 'scale', min: 0.1, max: 1, placeholder: '0.5', step: 0.1 },\n    { label: 'Quality', key: 'quality', min: 1, max: 100, placeholder: '95' },\n  ]\n\n  const screenshotFormatFormData: ParameterFormItem & { key: 'format' } = {\n    label: 'Format',\n    key: 'format',\n    placeholder: 'Select screenshot image format',\n  }\n\n  const screenshotFormatOptions = [\n    {\n      value: ScreenshotFormatOption.PNG,\n      label: 'PNG',\n    },\n    {\n      value: ScreenshotFormatOption.JPEG,\n      label: 'JPEG',\n    },\n    {\n      value: ScreenshotFormatOption.WEBP,\n      label: 'WebP',\n    },\n  ]\n\n  const screenshotShowCursorFormData: ParameterFormItem & { key: 'showCursor' } = {\n    label: 'Show cursor',\n    key: 'showCursor',\n    placeholder: 'Show cursor in screenshot',\n  }\n\n  const screenshotOptionsFormData: ParameterFormData<CustomizedScreenshotOptions> = [\n    ...screenshotOptionsNumberParametersFormData,\n    screenshotFormatFormData,\n    screenshotShowCursorFormData,\n  ]\n\n  const screenshotRegionNumberParametersFormData: (NumberParameterFormItem & { key: keyof ScreenshotRegion })[] = [\n    { label: 'Top left X', key: 'x', min: 0, max: Infinity, placeholder: '100', required: true },\n    { label: 'Top left Y', key: 'y', min: 0, max: Infinity, placeholder: '100', required: true },\n    { label: 'Width', key: 'width', min: 0, max: Infinity, placeholder: '300', required: true },\n    { label: 'Height', key: 'height', min: 0, max: Infinity, placeholder: '200', required: true },\n  ]\n\n  const screenshotActionsFormData: ScreenshotActionFormData<ScreenshotRegion | CustomizedScreenshotOptions>[] = [\n    {\n      methodName: ScreenshotActions.TAKE_COMPRESSED,\n      label: 'takeCompressed()',\n      description: 'Takes a compressed screenshot of the entire screen',\n      parametersFormItems: screenshotOptionsFormData,\n      parametersState: screenshotOptions,\n      onChangeParamsValidationDisabled: true,\n    },\n    // {\n    //   methodName: ScreenshotActions.TAKE_COMPRESSED_REGION,\n    //   label: 'takeCompressedRegion()',\n    //   description: 'Takes a compressed screenshot of a specific region',\n    //   parametersFormItems: [...screenshotOptionsFormData, ...screenshotRegionNumberParametersFormData],\n    //   parametersState: {\n    //     ...screenshotOptions,\n    //     ...screenshotRegion,\n    //   },\n    //   onChangeParamsValidationDisabled: true,\n    // },\n    {\n      methodName: ScreenshotActions.TAKE_FULL_SCREEN,\n      label: 'takeFullScreen()',\n      description: 'Takes a screenshot of the entire screen',\n      parametersFormItems: [screenshotShowCursorFormData],\n      parametersState: screenshotOptions,\n      onChangeParamsValidationDisabled: true,\n    },\n    // {\n    //   methodName: ScreenshotActions.TAKE_REGION,\n    //   label: 'takeRegion()',\n    //   description: 'Takes a screenshot of a specific region',\n    //   parametersFormItems: [...screenshotRegionNumberParametersFormData, screenshotShowCursorFormData],\n    //   parametersState: {\n    //     ...screenshotRegion,\n    //     ...screenshotOptions,\n    //   },\n    //   onChangeParamsValidationDisabled: true,\n    // },\n  ]\n\n  // Disable logic ensures that this method is called when ComputerUseClient exists -> we use as ComputerUse to silence TS compiler\n  const screenshotActionAPICall: PlaygroundActionInvokeApi = async (screenshotActionFormData) => {\n    const ScreenshotActionsClient = (ComputerUseClient as ComputerUse).screenshot\n    let screenshotActionResponse: ScreenshotResponse | RegionScreenshotResponse | CompressedScreenshotResponse = {\n      screenshot: '',\n    }\n    switch (screenshotActionFormData.methodName) {\n      case ScreenshotActions.TAKE_COMPRESSED: {\n        screenshotActionResponse = await ScreenshotActionsClient[ScreenshotActions.TAKE_COMPRESSED](\n          screenshotOptions ?? undefined,\n        )\n        break\n      }\n      case ScreenshotActions.TAKE_COMPRESSED_REGION: {\n        screenshotActionResponse = await ScreenshotActionsClient[ScreenshotActions.TAKE_COMPRESSED_REGION](\n          screenshotRegion,\n          screenshotOptions ?? undefined,\n        )\n        break\n      }\n      case ScreenshotActions.TAKE_FULL_SCREEN: {\n        screenshotActionResponse = await ScreenshotActionsClient[ScreenshotActions.TAKE_FULL_SCREEN](\n          screenshotOptions.showCursor,\n        )\n        break\n      }\n      case ScreenshotActions.TAKE_REGION: {\n        screenshotActionResponse = await ScreenshotActionsClient[ScreenshotActions.TAKE_REGION](\n          screenshotRegion,\n          screenshotOptions.showCursor,\n        )\n        break\n      }\n    }\n    // All screenshot actions responses have these fields in common\n    type CursorPositionType = { x: number; y: number }\n    const screenshotActionsResponseText = [\n      `Screenshot (base64): ${screenshotActionResponse.screenshot}`,\n      `Size: ${screenshotActionResponse.sizeBytes ?? 'unknown'}`,\n      screenshotActionResponse.cursorPosition\n        ? `Cursor position: (${(screenshotActionResponse.cursorPosition as CursorPositionType).x}, ${(screenshotActionResponse.cursorPosition as CursorPositionType).y})`\n        : '',\n    ].join('\\n')\n    setVNCInteractionOptionsParamValue('responseContent', screenshotActionsResponseText)\n\n    // Auto-download the screenshot image\n    if (screenshotActionResponse.screenshot) {\n      const format = screenshotOptions.format ?? ScreenshotFormatOption.PNG\n      const mimeType =\n        format === ScreenshotFormatOption.JPEG\n          ? 'image/jpeg'\n          : format === ScreenshotFormatOption.WEBP\n            ? 'image/webp'\n            : 'image/png'\n      const link = document.createElement('a')\n      link.href = `data:${mimeType};base64,${screenshotActionResponse.screenshot}`\n      link.download = `screenshot-${Date.now()}.${format}`\n      link.click()\n    }\n  }\n\n  return (\n    <div className=\"flex flex-col gap-6\">\n      <div className=\"space-y-2\">\n        <div className=\"w-full\">\n          <Label htmlFor=\"screenshot-options\" className=\"text-sm text-muted-foreground\">\n            Screenshot Options\n          </Label>\n        </div>\n        <div id=\"screenshot-options\" className=\"space-y-2\">\n          <InlineInputFormControl formItem={screenshotFormatFormData}>\n            <FormSelectInput\n              selectOptions={screenshotFormatOptions}\n              selectValue={screenshotOptions[screenshotFormatFormData.key as 'format']}\n              formItem={screenshotFormatFormData}\n              onChangeHandler={(value) => {\n                // Since all screenshot actions have onChangeParamsValidationDisabled set, the actionFormData parameter is irrelevant. We pass the first action simply to satisfy the method's parameter requirements.\n                playgroundActionParamValueSetter(\n                  screenshotActionsFormData[0],\n                  screenshotFormatFormData,\n                  'screenshotOptionsConfig',\n                  value,\n                )\n              }}\n            />\n          </InlineInputFormControl>\n          {screenshotOptionsNumberParametersFormData.map((screenshotOptionParamFormItem) => (\n            <InlineInputFormControl key={screenshotOptionParamFormItem.key} formItem={screenshotOptionParamFormItem}>\n              <FormNumberInput\n                numberValue={screenshotOptions[screenshotOptionParamFormItem.key]}\n                numberFormItem={screenshotOptionParamFormItem}\n                onChangeHandler={(value) => {\n                  // Since all screenshot actions have onChangeParamsValidationDisabled set, the actionFormData parameter is irrelevant. We pass the first action simply to satisfy the method's parameter requirements.\n                  playgroundActionParamValueSetter(\n                    screenshotActionsFormData[0],\n                    screenshotOptionParamFormItem,\n                    'screenshotOptionsConfig',\n                    value,\n                  )\n                }}\n              />\n            </InlineInputFormControl>\n          ))}\n          <InlineInputFormControl formItem={screenshotShowCursorFormData}>\n            <FormCheckboxInput\n              checkedValue={screenshotOptions[screenshotShowCursorFormData.key as 'showCursor']}\n              formItem={screenshotShowCursorFormData}\n              onChangeHandler={(checked) => {\n                // Since all screenshot actions have onChangeParamsValidationDisabled set, the actionFormData parameter is irrelevant. We pass the first action simply to satisfy the method's parameter requirements.\n                playgroundActionParamValueSetter(\n                  screenshotActionsFormData[0],\n                  screenshotShowCursorFormData,\n                  'screenshotOptionsConfig',\n                  checked,\n                )\n              }}\n            />\n          </InlineInputFormControl>\n        </div>\n      </div>\n      <div className=\"space-y-2\">\n        <div className=\"w-full\">\n          <Label htmlFor=\"screenshot-options\" className=\"text-sm text-muted-foreground\">\n            Screenshot Region\n          </Label>\n        </div>\n        <div id=\"screenshot-region\" className=\"space-y-2\">\n          {screenshotRegionNumberParametersFormData.map((screenshotRegionParamFormItem) => (\n            <InlineInputFormControl key={screenshotRegionParamFormItem.key} formItem={screenshotRegionParamFormItem}>\n              <FormNumberInput\n                numberValue={screenshotRegion[screenshotRegionParamFormItem.key]}\n                numberFormItem={screenshotRegionParamFormItem}\n                onChangeHandler={(value) => {\n                  // Since all screenshot actions have onChangeParamsValidationDisabled set, the actionFormData parameter is irrelevant. We pass the first action simply to satisfy the method's parameter requirements.\n                  playgroundActionParamValueSetter(\n                    screenshotActionsFormData[0],\n                    screenshotRegionParamFormItem,\n                    'screenshotRegionConfig',\n                    value,\n                  )\n                }}\n              />\n            </InlineInputFormControl>\n          ))}\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-4\">\n        {screenshotActionsFormData.map((screenshotAction) => (\n          <div key={screenshotAction.methodName}>\n            <PlaygroundActionForm<ScreenshotActions>\n              actionFormItem={screenshotAction}\n              onRunActionClick={() =>\n                runPlaygroundActionWithParams(screenshotAction, wrapVNCInvokeApi(screenshotActionAPICall))\n              }\n              disable={disableActions}\n            />\n          </div>\n        ))}\n      </div>\n    </div>\n  )\n}\n\nexport default VNCScreenshotOperations\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/VNC/Interaction/index.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'\nimport { VNCInteractionOptionsSectionComponentProps, WrapVNCInvokeApiType } from '@/contexts/PlaygroundContext'\nimport { VNCInteractionOptionsSections } from '@/enums/Playground'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { usePlaygroundSandbox } from '@/hooks/usePlaygroundSandbox'\nimport { createErrorMessageOutput } from '@/lib/playground'\n\nimport { CameraIcon, KeyboardIcon, MonitorIcon, MousePointer2Icon } from 'lucide-react'\nimport { useCallback, useState } from 'react'\nimport VNCDisplayOperations from './Display'\nimport VNCKeyboardOperations from './Keyboard'\nimport VNCMouseOperations from './Mouse'\nimport VNCScreenshotOperations from './Screenshot'\n\nconst VNCInteractionOptionsSectionsData = [\n  { value: VNCInteractionOptionsSections.DISPLAY, label: 'Display' },\n  { value: VNCInteractionOptionsSections.KEYBOARD, label: 'Keyboard' },\n  { value: VNCInteractionOptionsSections.MOUSE, label: 'Mouse' },\n  { value: VNCInteractionOptionsSections.SCREENSHOT, label: 'Screenshot' },\n]\n\nconst sectionIcons = {\n  [VNCInteractionOptionsSections.DISPLAY]: <MonitorIcon strokeWidth={1.5} />,\n  [VNCInteractionOptionsSections.KEYBOARD]: <KeyboardIcon strokeWidth={1.5} />,\n  [VNCInteractionOptionsSections.MOUSE]: <MousePointer2Icon strokeWidth={1.5} />,\n  [VNCInteractionOptionsSections.SCREENSHOT]: <CameraIcon strokeWidth={1.5} />,\n}\n\nconst VNCInteractionOptions: React.FC = () => {\n  const [openedInteractionOptionsSections, setOpenedInteractionOptionsSections] = useState<\n    VNCInteractionOptionsSections[]\n  >([VNCInteractionOptionsSections.DISPLAY])\n  const { setVNCInteractionOptionsParamValue } = usePlayground()\n\n  const { sandbox, vnc } = usePlaygroundSandbox()\n\n  const ComputerUseClient = vnc.url && sandbox.instance ? sandbox.instance.computerUse : null\n\n  // Standardize VNC invokeAPI call flow with this method\n  const wrapVNCInvokeApi = useCallback<WrapVNCInvokeApiType>(\n    (invokeApi) => {\n      return async (actionFormData) => {\n        // Set running message\n        setVNCInteractionOptionsParamValue('responseContent', `Running ${actionFormData.methodName}...`)\n\n        try {\n          // Call the action API method\n          await invokeApi(actionFormData)\n        } catch (error) {\n          setVNCInteractionOptionsParamValue('responseContent', createErrorMessageOutput(error))\n        }\n      }\n    },\n    [setVNCInteractionOptionsParamValue],\n  )\n\n  // Disable actions run if there was an error during sandbox creation or during VNC ComputerUse initialization\n  const VNCActionsDisabled = !!sandbox.error || !!vnc.error || !ComputerUseClient\n\n  const interactionOptionsSectionComponentProps: VNCInteractionOptionsSectionComponentProps = {\n    disableActions: VNCActionsDisabled,\n    ComputerUseClient,\n    wrapVNCInvokeApi,\n  }\n\n  return (\n    <div className=\"flex flex-col gap-6\">\n      <div>\n        <h2>Computer Use</h2>\n        <p className=\"text-sm text-muted-foreground mt-1\">\n          Automate GUI interactions or manually control the desktop environment.\n        </p>\n      </div>\n      <Accordion\n        type=\"multiple\"\n        value={openedInteractionOptionsSections}\n        onValueChange={(interactionOptionsSections) =>\n          setOpenedInteractionOptionsSections(interactionOptionsSections as VNCInteractionOptionsSections[])\n        }\n      >\n        {VNCInteractionOptionsSectionsData.map((section) => {\n          const isCollapsed = !openedInteractionOptionsSections.includes(section.value as VNCInteractionOptionsSections)\n          return (\n            <AccordionItem\n              key={section.value}\n              value={section.value}\n              className=\"border px-2 last:border-b first:rounded-t-lg last:rounded-b-lg border-t-0 first:border-t\"\n            >\n              <AccordionTrigger className=\"font-semibold text-muted-foreground hover:no-underline dark:bg-muted/50 bg-muted/80 hover:text-primary py-3 border-b border-b-transparent data-[state=open]:border-b-border -mx-2 px-3\">\n                <div className=\"flex items-center gap-2 [&_svg]:size-4 text-sm font-medium\">\n                  {sectionIcons[section.value]} {section.label}\n                </div>\n              </AccordionTrigger>\n              <AccordionContent className=\"py-3 px-1\">\n                {!isCollapsed && (\n                  <div className=\"space-y-4\">\n                    {section.value === VNCInteractionOptionsSections.DISPLAY && (\n                      <VNCDisplayOperations {...interactionOptionsSectionComponentProps} />\n                    )}\n                    {section.value === VNCInteractionOptionsSections.KEYBOARD && (\n                      <VNCKeyboardOperations {...interactionOptionsSectionComponentProps} />\n                    )}\n                    {section.value === VNCInteractionOptionsSections.MOUSE && (\n                      <VNCMouseOperations {...interactionOptionsSectionComponentProps} />\n                    )}\n                    {section.value === VNCInteractionOptionsSections.SCREENSHOT && (\n                      <VNCScreenshotOperations {...interactionOptionsSectionComponentProps} />\n                    )}\n                  </div>\n                )}\n              </AccordionContent>\n            </AccordionItem>\n          )\n        })}\n      </Accordion>\n    </div>\n  )\n}\n\nexport default VNCInteractionOptions\n"
  },
  {
    "path": "apps/dashboard/src/components/Playground/Window.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { motion } from 'framer-motion'\nimport { ComponentProps, ReactNode } from 'react'\n\nconst Window = ({ children, className = '' }: ComponentProps<'div'>) => {\n  return (\n    <motion.div\n      layoutId=\"window\"\n      className={cn(\n        'flex flex-col bg-card/80 backdrop-blur-xl dark:border dark:border-border rounded-xl overflow-hidden ring-1 ring-ring/5 shadow-lg shadow-black/5 dark:shadow-black/20',\n        className,\n      )}\n    >\n      {children}\n    </motion.div>\n  )\n}\n\nconst WindowTitleBar = ({\n  children,\n  right,\n  hideControls = false,\n}: {\n  children?: ReactNode\n  right?: ReactNode\n  hideControls?: boolean\n} & ComponentProps<'div'>) => {\n  return (\n    <motion.div\n      layout\n      layoutId=\"window-title-bar\"\n      className=\"relative items-center h-8 px-4 border-b border-border select-none shrink-0 grid grid-cols-[auto_1fr_auto] bg-muted/50\"\n    >\n      <motion.div className=\"flex gap-2 z-10\" layout>\n        {!hideControls && (\n          <>\n            <div className=\"w-3 h-3 rounded-full bg-muted-foreground/30\" />\n            <div className=\"w-3 h-3 rounded-full bg-muted-foreground/30\" />\n            <div className=\"w-3 h-3 rounded-full bg-muted-foreground/30\" />\n          </>\n        )}\n      </motion.div>\n\n      <motion.div\n        layoutId=\"window-title-bar-content\"\n        className=\"absolute inset-0 flex items-center justify-center pointer-events-none\"\n      >\n        <span className=\"text-sm text-muted-foreground\">{children}</span>\n      </motion.div>\n\n      <div className=\"ml-auto z-10\">{right}</div>\n    </motion.div>\n  )\n}\n\nconst WindowContent = ({ children, className = '' }: ComponentProps<'div'>) => {\n  return (\n    <motion.div\n      layoutId=\"window-content\"\n      layout=\"position\"\n      className={cn(\n        'flex-1 overflow-y-auto scrollbar-thin scrollbar-thumb-border scrollbar-track-background p-4 pb-3.5 text-foreground',\n        className,\n      )}\n    >\n      {children}\n    </motion.div>\n  )\n}\n\nexport { Window, WindowContent, WindowTitleBar }\n"
  },
  {
    "path": "apps/dashboard/src/components/PostHogProviderWrapper.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useConfig } from '@/hooks/useConfig'\nimport { PostHogProvider } from 'posthog-js/react'\nimport { FC, ReactNode } from 'react'\n\ninterface PostHogProviderWrapperProps {\n  children: ReactNode\n}\n\nexport const PostHogProviderWrapper: FC<PostHogProviderWrapperProps> = ({ children }) => {\n  const config = useConfig()\n\n  if (!config.posthog) {\n    return children\n  }\n\n  if (!config.posthog?.apiKey || !config.posthog?.host) {\n    console.error('Invalid PostHog configuration')\n    return children\n  }\n\n  return (\n    <PostHogProvider\n      apiKey={config.posthog.apiKey}\n      options={{\n        api_host: config.posthog.host,\n        opt_out_capturing_by_default: true,\n        cookieless_mode: 'on_reject',\n        persistence: 'localStorage',\n        person_profiles: 'always',\n        autocapture: false,\n        capture_pageview: false,\n        capture_pageleave: true,\n      }}\n    >\n      {children}\n    </PostHogProvider>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/PrivacyBanner.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Cookie, Settings } from 'lucide-react'\nimport { useState } from 'react'\nimport { PrivacyPreferencesDialog, usePrivacyConsent } from './PrivacyPreferencesDialog'\nimport { Button } from './ui/button'\n\nexport function PrivacyBanner() {\n  const { hasConsented, preferences, saveConsent } = usePrivacyConsent()\n  const [showCustomize, setShowCustomize] = useState(false)\n\n  const handleAcceptAll = () => {\n    saveConsent({\n      necessary: true,\n      analytics: true,\n      preferences: true,\n      marketing: true,\n    })\n  }\n\n  const handleRejectAll = () => {\n    saveConsent({\n      necessary: true,\n      analytics: false,\n      preferences: false,\n      marketing: false,\n    })\n  }\n\n  if (hasConsented) return null\n\n  return (\n    <>\n      <div className=\"fixed bottom-0 left-0 right-0 z-50 p-4 md:p-6 pointer-events-none\">\n        <div className=\"mx-auto max-w-4xl rounded-lg border border-border bg-background p-5 shadow-xl pointer-events-auto\">\n          <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n            <div className=\"flex items-start gap-3\">\n              <Cookie className=\"mt-1 h-6 w-6 flex-shrink-0 text-primary\" />\n              <div className=\"space-y-1\">\n                <h4 className=\"font-semibold text-sm\">We value your privacy</h4>\n                <p className=\"text-sm text-muted-foreground max-w-xl\">\n                  We use tracking technologies for essential functionality like authentication, and optionally for\n                  analytics to improve our product.\n                </p>\n              </div>\n            </div>\n            <div className=\"flex flex-col sm:flex-row gap-2 flex-shrink-0 pt-2 lg:pt-0\">\n              <Button variant=\"outline\" size=\"sm\" onClick={() => setShowCustomize(true)}>\n                <Settings className=\"mr-2 h-4 w-4\" />\n                Customize\n              </Button>\n              <Button variant=\"secondary\" size=\"sm\" onClick={handleRejectAll}>\n                Essential Only\n              </Button>\n              <Button size=\"sm\" onClick={handleAcceptAll}>\n                Accept All\n              </Button>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <PrivacyPreferencesDialog\n        open={showCustomize}\n        onOpenChange={setShowCustomize}\n        preferences={preferences}\n        onSave={saveConsent}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/PrivacyPreferencesDialog.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { usePostHog } from 'posthog-js/react'\nimport { useCallback, useEffect, useState } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { Button } from './ui/button'\nimport { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from './ui/dialog'\nimport { Separator } from './ui/separator'\nimport { Switch } from './ui/switch'\n\ntype ConsentPreferences = {\n  necessary: boolean\n  analytics: boolean\n  preferences: boolean\n  marketing: boolean\n}\n\nconst CONSENT_KEY_PREFIX = 'privacy_consent_'\n\nconst DEFAULT_PREFERENCES: ConsentPreferences = {\n  necessary: true,\n  analytics: false,\n  preferences: false,\n  marketing: false,\n}\n\nexport function usePrivacyConsent() {\n  const posthog = usePostHog()\n  const { user } = useAuth()\n\n  const [hasConsented, setHasConsented] = useState(false)\n  const [preferences, setPreferences] = useState<ConsentPreferences>(DEFAULT_PREFERENCES)\n\n  const consentKey = user?.profile?.sub ? `${CONSENT_KEY_PREFIX}${user.profile.sub}` : null\n\n  useEffect(() => {\n    if (!consentKey || !posthog) return\n\n    try {\n      const saved = localStorage.getItem(consentKey)\n      if (saved) {\n        const parsedConsent: ConsentPreferences = JSON.parse(saved)\n        setPreferences(parsedConsent)\n        if (parsedConsent.analytics) {\n          posthog.opt_in_capturing()\n        } else {\n          posthog.opt_out_capturing()\n        }\n        setHasConsented(true)\n      } else {\n        setHasConsented(false)\n      }\n    } catch {\n      console.error('Error parsing privacy consent')\n      setHasConsented(false)\n    }\n  }, [posthog, consentKey])\n\n  const saveConsent = useCallback(\n    (newPreferences: ConsentPreferences) => {\n      if (!consentKey) return\n\n      localStorage.setItem(consentKey, JSON.stringify(newPreferences))\n      setPreferences(newPreferences)\n\n      if (newPreferences.analytics) {\n        posthog?.opt_in_capturing()\n      } else {\n        posthog?.opt_out_capturing()\n      }\n\n      setHasConsented(true)\n    },\n    [consentKey, posthog],\n  )\n\n  return { hasConsented, preferences, saveConsent }\n}\n\ntype PrivacyPreferencesDialogProps = {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  preferences: ConsentPreferences\n  onSave: (preferences: ConsentPreferences) => void\n}\n\nexport function PrivacyPreferencesDialog({ open, onOpenChange, preferences, onSave }: PrivacyPreferencesDialogProps) {\n  const [tempPreferences, setTempPreferences] = useState<ConsentPreferences>(preferences)\n\n  useEffect(() => {\n    if (open) {\n      setTempPreferences(preferences)\n    }\n  }, [open, preferences])\n\n  const handleSave = () => {\n    onSave(tempPreferences)\n    onOpenChange(false)\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent className=\"sm:max-w-md\">\n        <DialogHeader>\n          <DialogTitle>Privacy Preferences</DialogTitle>\n        </DialogHeader>\n\n        <DialogDescription>\n          Choose which tracking technologies you allow. Essential tracking is always required.\n        </DialogDescription>\n\n        <div className=\"rounded-md border\">\n          <div className=\"flex items-start justify-between space-x-2 p-3 bg-muted/50\">\n            <div className=\"space-y-1\">\n              <p className=\"font-medium text-sm\">Essential</p>\n              <p className=\"text-xs text-muted-foreground\">\n                Required for login sessions and core functionality. Cannot be disabled.\n              </p>\n            </div>\n            <Switch checked disabled />\n          </div>\n\n          <Separator />\n\n          <div className=\"flex items-start justify-between space-x-2 p-3\">\n            <div className=\"space-y-1\">\n              <p className=\"font-medium text-sm\">Analytics</p>\n              <p className=\"text-xs text-muted-foreground\">\n                Collects anonymous usage data to help us understand how the product is used and improve it.\n              </p>\n            </div>\n            <Switch\n              checked={tempPreferences.analytics}\n              onCheckedChange={(checked) => setTempPreferences((prev) => ({ ...prev, analytics: checked }))}\n            />\n          </div>\n\n          <Separator />\n\n          <div className=\"flex items-start justify-between space-x-2 p-3\">\n            <div className=\"space-y-1\">\n              <p className=\"font-medium text-sm\">Preferences</p>\n              <p className=\"text-xs text-muted-foreground\">\n                Remembers your settings like theme and layout across sessions.\n              </p>\n            </div>\n            <Switch\n              checked={tempPreferences.preferences}\n              onCheckedChange={(checked) => setTempPreferences((prev) => ({ ...prev, preferences: checked }))}\n            />\n          </div>\n\n          <Separator />\n\n          <div className=\"flex items-start justify-between space-x-2 p-3\">\n            <div className=\"space-y-1\">\n              <p className=\"font-medium text-sm\">Marketing</p>\n              <p className=\"text-xs text-muted-foreground\">\n                Used for communications about Daytona features and updates.\n              </p>\n            </div>\n            <Switch\n              checked={tempPreferences.marketing}\n              onCheckedChange={(checked) => setTempPreferences((prev) => ({ ...prev, marketing: checked }))}\n            />\n          </div>\n        </div>\n\n        <DialogFooter>\n          <Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n            Cancel\n          </Button>\n          <Button onClick={handleSave}>Save Preferences</Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/QuotaLine.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { motion } from 'framer-motion'\nimport React from 'react'\n\ninterface QuotaLineProps {\n  current: number\n  total: number\n  className?: string\n}\n\nconst transition = {\n  type: 'spring',\n  stiffness: 60,\n  damping: 15,\n  mass: 1,\n} as const\n\nconst QuotaLine: React.FC<QuotaLineProps> = ({ current, total, className }) => {\n  const percentage = Math.min(Math.max((current / total) * 100, 0), 100)\n\n  const greenWidth = Math.min(percentage, 60)\n  const yellowWidth = Math.min(Math.max(percentage - 60, 0), 30)\n  const redWidth = Math.min(Math.max(percentage - 90, 0), 10)\n\n  return (\n    <div className={cn('w-full h-2 bg-muted rounded-full overflow-clip flex relative', className)}>\n      <motion.div\n        className=\"h-full bg-green-500\"\n        initial={{ width: 0 }}\n        animate={{ width: `${greenWidth}%` }}\n        transition={transition}\n      />\n      <motion.div\n        className=\"h-full bg-yellow-400\"\n        initial={{ width: 0 }}\n        animate={{ width: `${yellowWidth}%` }}\n        transition={transition}\n      />\n      <motion.div\n        className=\"h-full bg-red-500\"\n        initial={{ width: 0 }}\n        animate={{ width: `${redWidth}%` }}\n        transition={transition}\n      />\n    </div>\n  )\n}\n\nexport default QuotaLine\n"
  },
  {
    "path": "apps/dashboard/src/components/RegionDetailsSheet.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'\nimport { formatTimestamp } from '@/lib/utils'\nimport { Region, RegionType } from '@daytonaio/api-client'\nimport { Copy, Info, Pencil, Trash, X } from 'lucide-react'\nimport React from 'react'\nimport { toast } from 'sonner'\n\ninterface RegionDetailsSheetProps {\n  region: Region | null\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  regionIsLoading: Record<string, boolean>\n  writePermitted: boolean\n  deletePermitted: boolean\n  onDelete: (region: Region) => void\n  onUpdate: (region: Region) => void\n  onRegenerateProxyApiKey: (region: Region) => void\n  onRegenerateSshGatewayApiKey: (region: Region) => void\n  onRegenerateSnapshotManagerCredentials: (region: Region) => void\n}\n\nconst RegionDetailsSheet: React.FC<RegionDetailsSheetProps> = ({\n  region,\n  open,\n  onOpenChange,\n  regionIsLoading,\n  writePermitted,\n  deletePermitted,\n  onDelete,\n  onUpdate,\n  onRegenerateProxyApiKey,\n  onRegenerateSshGatewayApiKey,\n  onRegenerateSnapshotManagerCredentials,\n}) => {\n  if (!region) return null\n\n  const copyToClipboard = async (text: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      toast.success('Copied to clipboard')\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n      toast.error('Failed to copy to clipboard')\n    }\n  }\n\n  const isLoading = regionIsLoading[region.id] || false\n  const isCustomRegion = region.regionType === RegionType.CUSTOM\n\n  return (\n    <Sheet open={open} onOpenChange={onOpenChange}>\n      <SheetContent className=\"w-dvw sm:w-[800px] p-0 flex flex-col gap-0 [&>button]:hidden\">\n        <SheetHeader className=\"space-y-0 flex flex-row justify-between items-center p-6\">\n          <SheetTitle className=\"text-2xl font-medium\">Region Details</SheetTitle>\n          <div className=\"flex gap-2 items-center\">\n            {writePermitted && isCustomRegion && (\n              <Button variant=\"outline\" className=\"w-8 h-8\" onClick={() => onUpdate(region)} disabled={isLoading}>\n                <Pencil className=\"w-4 h-4\" />\n              </Button>\n            )}\n            {deletePermitted && isCustomRegion && (\n              <Button variant=\"outline\" className=\"w-8 h-8\" onClick={() => onDelete(region)} disabled={isLoading}>\n                <Trash className=\"w-4 h-4\" />\n              </Button>\n            )}\n            <Button variant=\"outline\" className=\"w-8 h-8\" onClick={() => onOpenChange(false)} disabled={isLoading}>\n              <X className=\"w-4 h-4\" />\n            </Button>\n          </div>\n        </SheetHeader>\n\n        <div className=\"flex-1 p-6 space-y-10 overflow-y-auto min-h-0\">\n          <div className=\"grid grid-cols-2 gap-6\">\n            <div>\n              <h3 className=\"text-sm text-muted-foreground\">Name</h3>\n              <div className=\"mt-1 flex items-center gap-2\">\n                <p className=\"text-sm font-medium truncate\">{region.name}</p>\n                <button\n                  onClick={() => copyToClipboard(region.name)}\n                  className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                  aria-label=\"Copy name\"\n                >\n                  <Copy className=\"w-3 h-3\" />\n                </button>\n              </div>\n            </div>\n            <div>\n              <h3 className=\"text-sm text-muted-foreground\">ID</h3>\n              <div className=\"mt-1 flex items-center gap-2\">\n                <p className=\"text-sm font-medium truncate\">{region.id}</p>\n                <button\n                  onClick={() => copyToClipboard(region.id)}\n                  className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                  aria-label=\"Copy ID\"\n                >\n                  <Copy className=\"w-3 h-3\" />\n                </button>\n              </div>\n            </div>\n          </div>\n\n          <div className=\"grid grid-cols-2 gap-6\">\n            <div>\n              <h3 className=\"text-sm text-muted-foreground\">Created</h3>\n              <p className=\"mt-1 text-sm font-medium\">{formatTimestamp(region.createdAt)}</p>\n            </div>\n          </div>\n\n          <div>\n            <h3 className=\"text-lg font-medium\">URLs</h3>\n            <div className=\"mt-3 space-y-4\">\n              <div>\n                <h4 className=\"text-sm text-muted-foreground\">Proxy URL</h4>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{region.proxyUrl || '-'}</p>\n                  {region.proxyUrl && (\n                    <button\n                      onClick={() => copyToClipboard(region.proxyUrl || '')}\n                      className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                      aria-label=\"Copy Proxy URL\"\n                    >\n                      <Copy className=\"w-3 h-3\" />\n                    </button>\n                  )}\n                </div>\n              </div>\n              <div>\n                <h4 className=\"text-sm text-muted-foreground\">SSH Gateway URL</h4>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{region.sshGatewayUrl || '-'}</p>\n                  {region.sshGatewayUrl && (\n                    <button\n                      onClick={() => copyToClipboard(region.sshGatewayUrl || '')}\n                      className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                      aria-label=\"Copy SSH Gateway URL\"\n                    >\n                      <Copy className=\"w-3 h-3\" />\n                    </button>\n                  )}\n                </div>\n              </div>\n              <div>\n                <h4 className=\"text-sm text-muted-foreground\">Snapshot Manager URL</h4>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{region.snapshotManagerUrl || '-'}</p>\n                  {region.snapshotManagerUrl && (\n                    <button\n                      onClick={() => copyToClipboard(region.snapshotManagerUrl || '')}\n                      className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                      aria-label=\"Copy Snapshot Manager URL\"\n                    >\n                      <Copy className=\"w-3 h-3\" />\n                    </button>\n                  )}\n                </div>\n              </div>\n            </div>\n          </div>\n\n          {isCustomRegion &&\n            writePermitted &&\n            (region.proxyUrl || region.sshGatewayUrl || region.snapshotManagerUrl) && (\n              <div>\n                <h3 className=\"text-lg font-medium\">Credentials</h3>\n                <div className=\"mt-3 space-y-3\">\n                  {region.proxyUrl && (\n                    <Button\n                      variant=\"outline\"\n                      onClick={() => onRegenerateProxyApiKey(region)}\n                      disabled={isLoading}\n                      className=\"w-full justify-start\"\n                    >\n                      <Info className=\"w-4 h-4 mr-2\" />\n                      Regenerate Proxy API Key\n                    </Button>\n                  )}\n                  {region.sshGatewayUrl && (\n                    <Button\n                      variant=\"outline\"\n                      onClick={() => onRegenerateSshGatewayApiKey(region)}\n                      disabled={isLoading}\n                      className=\"w-full justify-start\"\n                    >\n                      <Info className=\"w-4 h-4 mr-2\" />\n                      Regenerate SSH Gateway API Key\n                    </Button>\n                  )}\n                  {region.snapshotManagerUrl && (\n                    <Button\n                      variant=\"outline\"\n                      onClick={() => onRegenerateSnapshotManagerCredentials(region)}\n                      disabled={isLoading}\n                      className=\"w-full justify-start\"\n                    >\n                      <Info className=\"w-4 h-4 mr-2\" />\n                      Regenerate Snapshot Manager Credentials\n                    </Button>\n                  )}\n                </div>\n              </div>\n            )}\n        </div>\n      </SheetContent>\n    </Sheet>\n  )\n}\n\nexport default RegionDetailsSheet\n"
  },
  {
    "path": "apps/dashboard/src/components/RegionTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { Region, RegionType } from '@daytonaio/api-client'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { Copy, MapPinned, MoreHorizontal } from 'lucide-react'\nimport { useState } from 'react'\nimport { toast } from 'sonner'\nimport { DebouncedInput } from './DebouncedInput'\nimport { Pagination } from './Pagination'\nimport { TableEmptyState } from './TableEmptyState'\nimport { Button } from './ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './ui/dropdown-menu'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './ui/table'\nimport { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'\n\ninterface DataTableProps {\n  data: Region[]\n  loading: boolean\n  isLoadingRegion: (region: Region) => boolean\n  deletePermitted: boolean\n  writePermitted: boolean\n  onDelete: (region: Region) => void\n  onOpenDetails: (region: Region) => void\n}\n\nexport function RegionTable({\n  data,\n  loading,\n  isLoadingRegion,\n  deletePermitted,\n  writePermitted,\n  onDelete,\n  onOpenDetails,\n}: DataTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [globalFilter, setGlobalFilter] = useState('')\n\n  const copyToClipboard = async (text: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      toast.success('Copied to clipboard')\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n      toast.error('Failed to copy to clipboard')\n    }\n  }\n\n  const columns = getColumns({\n    onDelete,\n    isLoadingRegion,\n    deletePermitted,\n    writePermitted,\n    copyToClipboard,\n    onOpenDetails,\n  })\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getFilteredRowModel: getFilteredRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    onGlobalFilterChange: setGlobalFilter,\n    globalFilterFn: (row, columnId, filterValue) => {\n      const region = row.original as Region\n      const searchValue = filterValue.toLowerCase()\n      return region.name.toLowerCase().includes(searchValue) || region.id.toLowerCase().includes(searchValue)\n    },\n    state: {\n      sorting,\n      globalFilter,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  return (\n    <div>\n      <div className=\"flex items-center mb-4\">\n        <DebouncedInput\n          value={globalFilter ?? ''}\n          onChange={(value) => setGlobalFilter(String(value))}\n          placeholder=\"Search by Name or ID\"\n          className=\"max-w-sm\"\n        />\n      </div>\n      <div className=\"rounded-md border\">\n        <Table style={{ tableLayout: 'fixed', width: '100%' }}>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      className=\"px-2\"\n                      key={header.id}\n                      style={{\n                        width: `${header.column.getSize()}px`,\n                      }}\n                    >\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  Loading...\n                </TableCell>\n              </TableRow>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => {\n                const isCustom = row.original.regionType === RegionType.CUSTOM\n                const isLoading = isLoadingRegion(row.original)\n                return (\n                  <TableRow\n                    key={row.id}\n                    data-state={row.getIsSelected() && 'selected'}\n                    className={`${isLoading ? 'opacity-50 pointer-events-none' : ''} ${isCustom && !isLoading ? 'cursor-pointer hover:bg-muted/50' : ''}`}\n                    onClick={() => {\n                      if (isCustom && !isLoading) {\n                        onOpenDetails(row.original)\n                      }\n                    }}\n                  >\n                    {row.getVisibleCells().map((cell) => (\n                      <TableCell\n                        className=\"px-2\"\n                        key={cell.id}\n                        style={{\n                          width: `${cell.column.getSize()}px`,\n                        }}\n                      >\n                        {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                      </TableCell>\n                    ))}\n                  </TableRow>\n                )\n              })\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No custom regions found.\"\n                icon={<MapPinned className=\"w-8 h-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>Create regions for grouping runners and sandboxes.</p>\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination table={table} className=\"mt-4\" entityName=\"Regions\" />\n    </div>\n  )\n}\n\nconst getColumns = ({\n  onDelete,\n  isLoadingRegion,\n  deletePermitted,\n  writePermitted,\n  copyToClipboard,\n  onOpenDetails,\n}: {\n  onDelete: (region: Region) => void\n  isLoadingRegion: (region: Region) => boolean\n  deletePermitted: boolean\n  writePermitted: boolean\n  copyToClipboard: (text: string) => Promise<void>\n  onOpenDetails: (region: Region) => void\n}): ColumnDef<Region>[] => {\n  const columns: ColumnDef<Region>[] = [\n    {\n      accessorKey: 'name',\n      header: 'Name',\n      size: 300,\n      cell: ({ row }) => (\n        <div className=\"w-full truncate flex items-center gap-2\">\n          <span className=\"truncate block\">{row.original.name}</span>\n          <button\n            onClick={(e) => {\n              e.stopPropagation()\n              copyToClipboard(row.original.name)\n            }}\n            className=\"text-muted-foreground hover:text-foreground transition-colors\"\n            aria-label=\"Copy Name\"\n          >\n            <Copy className=\"w-3 h-3\" />\n          </button>\n        </div>\n      ),\n    },\n    {\n      accessorKey: 'id',\n      header: 'ID',\n      size: 300,\n      cell: ({ row }) => (\n        <div className=\"w-full truncate flex items-center gap-2\">\n          <span className=\"truncate block\">{row.original.id}</span>\n          <button\n            onClick={(e) => {\n              e.stopPropagation()\n              copyToClipboard(row.original.id)\n            }}\n            className=\"text-muted-foreground hover:text-foreground transition-colors\"\n            aria-label=\"Copy ID\"\n          >\n            <Copy className=\"w-3 h-3\" />\n          </button>\n        </div>\n      ),\n    },\n    {\n      accessorKey: 'createdAt',\n      header: 'Created',\n      cell: ({ row }) => {\n        if (row.original.regionType !== RegionType.CUSTOM) {\n          return null\n        }\n\n        const createdAt = row.original.createdAt\n        const relativeTime = getRelativeTimeString(createdAt).relativeTimeString\n        const fullDate = new Date(createdAt).toLocaleString()\n\n        return (\n          <Tooltip>\n            <TooltipTrigger>\n              <span className=\"cursor-default\">{relativeTime}</span>\n            </TooltipTrigger>\n            <TooltipContent>\n              <p>{fullDate}</p>\n            </TooltipContent>\n          </Tooltip>\n        )\n      },\n    },\n  ]\n\n  columns.push({\n    id: 'options',\n    header: () => {\n      return null\n    },\n    cell: ({ row }) => {\n      if (row.original.regionType !== RegionType.CUSTOM || (!deletePermitted && !writePermitted)) {\n        return <div className=\"flex justify-end h-8 w-8\" />\n      }\n\n      const isLoading = isLoadingRegion(row.original)\n\n      return (\n        <div className=\"flex justify-end\" onClick={(e) => e.stopPropagation()}>\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button variant=\"ghost\" size=\"sm\" className=\"h-8 w-8 p-0\" disabled={isLoading}>\n                <MoreHorizontal className=\"h-4 w-4\" />\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\">\n              <DropdownMenuItem\n                onClick={() => onOpenDetails(row.original)}\n                className=\"cursor-pointer\"\n                disabled={isLoading}\n              >\n                Details\n              </DropdownMenuItem>\n              {deletePermitted && (\n                <DropdownMenuItem\n                  onClick={() => onDelete(row.original)}\n                  className=\"cursor-pointer text-red-600 dark:text-red-400\"\n                  disabled={isLoading}\n                >\n                  Delete\n                </DropdownMenuItem>\n              )}\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </div>\n      )\n    },\n  })\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/RegistryTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DockerRegistry, OrganizationRolePermissionsEnum } from '@daytonaio/api-client'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { TableHeader, TableRow, TableHead, TableBody, TableCell, Table } from './ui/table'\nimport { Button } from './ui/button'\nimport { useMemo, useState } from 'react'\nimport { MoreHorizontal, Package } from 'lucide-react'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from './ui/dropdown-menu'\nimport { DialogTrigger } from './ui/dialog'\nimport { Pagination } from './Pagination'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { TableEmptyState } from './TableEmptyState'\n\ninterface DataTableProps {\n  data: DockerRegistry[]\n  loading: boolean\n  onDelete: (id: string) => void\n  onEdit: (registry: DockerRegistry) => void\n}\n\nexport function RegistryTable({ data, loading, onDelete, onEdit }: DataTableProps) {\n  const { authenticatedUserHasPermission } = useSelectedOrganization()\n\n  const writePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_REGISTRIES),\n    [authenticatedUserHasPermission],\n  )\n\n  const deletePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.DELETE_REGISTRIES),\n    [authenticatedUserHasPermission],\n  )\n\n  const [sorting, setSorting] = useState<SortingState>([])\n  const columns = getColumns({ onDelete, onEdit, loading, writePermitted, deletePermitted })\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    state: {\n      sorting,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <Table>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead key={header.id} className=\"px-2\">\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  Loading...\n                </TableCell>\n              </TableRow>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell className=\"px-2\" key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No Container registries found.\"\n                icon={<Package className=\"w-8 h-8\" />}\n                description=\"Connect to external container registries (e.g., Docker Hub, GCR, ECR) to pull images for your Sandboxes.\"\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination table={table} className=\"mt-4\" entityName=\"Registries\" />\n    </div>\n  )\n}\n\nconst getColumns = ({\n  onDelete,\n  onEdit,\n  loading,\n  writePermitted,\n  deletePermitted,\n}: {\n  onDelete: (id: string) => void\n  onEdit: (registry: DockerRegistry) => void\n  loading: boolean\n  writePermitted: boolean\n  deletePermitted: boolean\n}): ColumnDef<DockerRegistry>[] => {\n  const columns: ColumnDef<DockerRegistry>[] = [\n    {\n      accessorKey: 'name',\n      header: 'Name',\n    },\n    {\n      accessorKey: 'url',\n      header: 'URL',\n    },\n    {\n      id: 'project',\n      header: 'Project',\n      cell: ({ row }) => {\n        return row.original.project || '-'\n      },\n    },\n    {\n      accessorKey: 'username',\n      header: 'Username',\n    },\n    {\n      id: 'actions',\n      cell: ({ row }) => {\n        if (!writePermitted && !deletePermitted) {\n          return null\n        }\n\n        return (\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button variant=\"ghost\" className=\"h-8 w-8 p-0\">\n                <span className=\"sr-only\">Open menu</span>\n                <MoreHorizontal className=\"h-4 w-4\" />\n              </Button>\n            </DropdownMenuTrigger>\n\n            <DropdownMenuContent align=\"end\">\n              {writePermitted && (\n                <DialogTrigger asChild>\n                  <DropdownMenuItem onClick={() => onEdit(row.original)} className=\"cursor-pointer\" disabled={loading}>\n                    Edit\n                  </DropdownMenuItem>\n                </DialogTrigger>\n              )}\n              {deletePermitted && (\n                <>\n                  <DropdownMenuSeparator />\n                  <DropdownMenuItem\n                    className=\"cursor-pointer text-red-600 dark:text-red-400\"\n                    disabled={loading}\n                    onClick={() => onDelete(row.original.id)}\n                  >\n                    Delete\n                  </DropdownMenuItem>\n                </>\n              )}\n            </DropdownMenuContent>\n          </DropdownMenu>\n        )\n      },\n    },\n  ]\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ResourceChip.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CpuIcon, HardDriveIcon, MemoryStickIcon } from 'lucide-react'\n\ninterface Props {\n  resource: 'cpu' | 'memory' | 'disk'\n  value: number\n  unit?: string\n  icon?: React.ReactNode\n}\n\nconst resourceUnits = {\n  cpu: 'vCPU',\n  memory: 'GiB',\n  disk: 'GiB',\n}\n\nconst resourceIcons = {\n  cpu: CpuIcon,\n  memory: MemoryStickIcon,\n  disk: HardDriveIcon,\n}\n\nexport function ResourceChip({ resource, value, unit, icon }: Props) {\n  const resourceUnit = unit ?? resourceUnits[resource]\n  const ResourceIcon = resourceIcons[resource]\n\n  return (\n    <div className=\"flex items-center gap-1 bg-muted/80 border border-border rounded-full px-2 py-[2px] text-sm whitespace-nowrap\">\n      {icon === null ? null : (icon ?? <ResourceIcon className=\"w-4 h-4 flex-shrink-0\" strokeWidth={1.5} />)} {value}{' '}\n      {resourceUnit}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/RunnerDetailsSheet.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'\nimport { Tabs, TabsContent } from '@/components/ui/tabs'\nimport { formatTimestamp, getRelativeTimeString } from '@/lib/utils'\nimport { Runner, RunnerState } from '@daytonaio/api-client'\nimport { Copy, Trash, X, CheckCircle, AlertTriangle, Timer, Pause } from 'lucide-react'\nimport React from 'react'\nimport { toast } from 'sonner'\nimport { ResourceChip } from './ResourceChip'\nimport QuotaLine from './QuotaLine'\n\ninterface RunnerDetailsSheetProps {\n  runner: Runner | null\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  runnerIsLoading: Record<string, boolean>\n  writePermitted: boolean\n  deletePermitted: boolean\n  onDelete: (runner: Runner) => void\n  getRegionName: (regionId: string) => string | undefined\n}\n\nconst RunnerDetailsSheet: React.FC<RunnerDetailsSheetProps> = ({\n  runner,\n  open,\n  onOpenChange,\n  runnerIsLoading,\n  deletePermitted,\n  onDelete,\n  getRegionName,\n}) => {\n  if (!runner) return null\n\n  const copyToClipboard = async (text: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      toast.success('Copied to clipboard')\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n      toast.error('Failed to copy to clipboard')\n    }\n  }\n\n  const getStateIcon = (state: RunnerState) => {\n    switch (state) {\n      case RunnerState.READY:\n        return <CheckCircle className=\"w-4 h-4 flex-shrink-0\" />\n      case RunnerState.DISABLED:\n      case RunnerState.DECOMMISSIONED:\n        return <Pause className=\"w-4 h-4 flex-shrink-0\" />\n      case RunnerState.UNRESPONSIVE:\n        return <AlertTriangle className=\"w-4 h-4 flex-shrink-0\" />\n      default:\n        return <Timer className=\"w-4 h-4 flex-shrink-0\" />\n    }\n  }\n\n  const getStateColor = (state: RunnerState) => {\n    switch (state) {\n      case RunnerState.READY:\n        return 'text-green-500'\n      case RunnerState.DISABLED:\n      case RunnerState.DECOMMISSIONED:\n        return 'text-gray-500 dark:text-gray-400'\n      case RunnerState.UNRESPONSIVE:\n        return 'text-red-500'\n      default:\n        return 'text-gray-600 dark:text-gray-400'\n    }\n  }\n\n  const getStateLabel = (state: RunnerState) => {\n    return state\n      .split('_')\n      .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n      .join(' ')\n  }\n\n  const getLastEvent = (runner: Runner): { date: Date; relativeTimeString: string } => {\n    return getRelativeTimeString(runner.updatedAt)\n  }\n\n  return (\n    <Sheet open={open} onOpenChange={onOpenChange}>\n      <SheetContent className=\"w-dvw sm:w-[800px] p-0 flex flex-col gap-0 [&>button]:hidden\">\n        <SheetHeader className=\"space-y-0 flex flex-row justify-between items-center p-6\">\n          <SheetTitle className=\"text-2xl font-medium\">Runner Details</SheetTitle>\n          <div className=\"flex gap-2 items-center\">\n            {deletePermitted && (\n              <Button\n                variant=\"outline\"\n                className=\"w-8 h-8\"\n                onClick={() => onDelete(runner)}\n                disabled={runnerIsLoading[runner.id]}\n              >\n                <Trash className=\"w-4 h-4\" />\n              </Button>\n            )}\n            <Button\n              variant=\"outline\"\n              className=\"w-8 h-8\"\n              onClick={() => onOpenChange(false)}\n              disabled={runnerIsLoading[runner.id]}\n            >\n              <X className=\"w-4 h-4\" />\n            </Button>\n          </div>\n        </SheetHeader>\n\n        <Tabs defaultValue=\"overview\" className=\"flex-1 flex flex-col min-h-0\">\n          <TabsContent value=\"overview\" className=\"flex-1 p-6 space-y-10 overflow-y-auto min-h-0\">\n            {/* Basic Info */}\n            <div className=\"grid grid-cols-2 gap-6\">\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Name</h3>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{runner.name}</p>\n                  <button\n                    onClick={() => copyToClipboard(runner.name)}\n                    className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                    aria-label=\"Copy name\"\n                  >\n                    <Copy className=\"w-3 h-3\" />\n                  </button>\n                </div>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">UUID</h3>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{runner.id}</p>\n                  <button\n                    onClick={() => copyToClipboard(runner.id)}\n                    className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                    aria-label=\"Copy UUID\"\n                  >\n                    <Copy className=\"w-3 h-3\" />\n                  </button>\n                </div>\n              </div>\n            </div>\n\n            {/* Status */}\n            <div className=\"grid grid-cols-1 md:grid-cols-4 gap-6\">\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">State</h3>\n                <div className={`mt-1 flex items-center gap-2 ${getStateColor(runner.state)}`}>\n                  {getStateIcon(runner.state)}\n                  <span className=\"text-sm font-medium\">{getStateLabel(runner.state)}</span>\n                </div>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Schedulable</h3>\n                <p className=\"mt-1 text-sm font-medium\">{runner.unschedulable ? 'No' : 'Yes'}</p>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Region</h3>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{getRegionName(runner.region) ?? runner.region}</p>\n                  <button\n                    onClick={() => copyToClipboard(runner.region)}\n                    className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                    aria-label=\"Copy region\"\n                  >\n                    <Copy className=\"w-3 h-3\" />\n                  </button>\n                </div>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Version</h3>\n                <p className=\"mt-1 text-sm font-medium\">{runner.appVersion ?? 'N/A'}</p>\n              </div>\n            </div>\n\n            {/* Health Metrics */}\n            <div>\n              <h3 className=\"text-lg font-medium mb-4\">Health Metrics</h3>\n              <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n                <div className=\"flex flex-col gap-1\">\n                  <div className=\"flex justify-between\">\n                    <span className=\"text-muted-foreground text-xs\">Availability Score</span>\n                    <span className=\"text-xs\">\n                      {runner.availabilityScore != null ? runner.availabilityScore.toFixed(2) : 'N/A'}%\n                    </span>\n                  </div>\n                  <QuotaLine current={runner.availabilityScore ?? 0} total={100} />\n                </div>\n                <div className=\"flex flex-col gap-1\">\n                  <div className=\"flex justify-between\">\n                    <span className=\"text-muted-foreground text-xs\">CPU Usage</span>\n                    <span className=\"text-xs\">\n                      {runner.currentCpuUsagePercentage != null ? runner.currentCpuUsagePercentage.toFixed(2) : 'N/A'}%\n                    </span>\n                  </div>\n                  <QuotaLine current={runner.currentCpuUsagePercentage ?? 0} total={100} />\n                </div>\n                <div className=\"flex flex-col gap-1\">\n                  <div className=\"flex justify-between\">\n                    <span className=\"text-muted-foreground text-xs\">Memory Usage</span>\n                    <span className=\"text-xs\">\n                      {runner.currentMemoryUsagePercentage != null\n                        ? runner.currentMemoryUsagePercentage.toFixed(2)\n                        : 'N/A'}\n                      %\n                    </span>\n                  </div>\n                  <QuotaLine current={runner.currentMemoryUsagePercentage ?? 0} total={100} />\n                </div>\n                <div className=\"flex flex-col gap-1\">\n                  <div className=\"flex justify-between\">\n                    <span className=\"text-muted-foreground text-xs\">Disk Usage</span>\n                    <span className=\"text-xs\">\n                      {runner.currentDiskUsagePercentage != null ? runner.currentDiskUsagePercentage.toFixed(2) : 'N/A'}\n                      %\n                    </span>\n                  </div>\n                  <QuotaLine current={runner.currentDiskUsagePercentage ?? 0} total={100} />\n                </div>\n                <div>\n                  <h4 className=\"text-muted-foreground text-xs\">Active Sandboxes</h4>\n                  <p className=\"mt-1 text-2xl font-semibold\">{runner.currentStartedSandboxes ?? 0}</p>\n                </div>\n                <div>\n                  <h4 className=\"text-muted-foreground text-xs\">Snapshots</h4>\n                  <p className=\"mt-1 text-2xl font-semibold\">{runner.currentSnapshotCount ?? 0}</p>\n                </div>\n              </div>\n            </div>\n\n            {/* Total Resources */}\n            <div className=\"grid grid-cols-1\">\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Total Resources</h3>\n                <div className=\"mt-1 text-sm font-medium flex items-center gap-1 flex-wrap\">\n                  <ResourceChip resource=\"cpu\" value={Number(runner.cpu.toFixed(2))} />\n                  <ResourceChip resource=\"memory\" value={Number(runner.memory.toFixed(2))} />\n                  <ResourceChip resource=\"disk\" value={Number(runner.disk.toFixed(2))} />\n                  {runner.gpu !== undefined && runner.gpu > 0 && (\n                    <div className=\"flex items-center gap-1 bg-purple-100 text-purple-600 dark:bg-purple-950 dark:text-purple-200 rounded-full px-2 py-[2px] text-sm whitespace-nowrap\">\n                      {runner.gpu} GPU{runner.gpuType ? ` (${runner.gpuType})` : ''}\n                    </div>\n                  )}\n                </div>\n              </div>\n            </div>\n\n            {/* Timestamps */}\n            <div className=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n              {runner.lastChecked && (\n                <div>\n                  <h3 className=\"text-sm text-muted-foreground\">Last Checked</h3>\n                  <p className=\"mt-1 text-sm font-medium\">{formatTimestamp(runner.lastChecked)}</p>\n                </div>\n              )}\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Created At</h3>\n                <p className=\"mt-1 text-sm font-medium\">{formatTimestamp(runner.createdAt)}</p>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Last Updated</h3>\n                <p className=\"mt-1 text-sm font-medium\">{getLastEvent(runner).relativeTimeString}</p>\n              </div>\n            </div>\n          </TabsContent>\n        </Tabs>\n      </SheetContent>\n    </Sheet>\n  )\n}\n\nexport default RunnerDetailsSheet\n"
  },
  {
    "path": "apps/dashboard/src/components/RunnerTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Runner, RunnerState, Region } from '@daytonaio/api-client'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { TableHeader, TableRow, TableHead, TableBody, TableCell, Table } from './ui/table'\nimport { Button } from './ui/button'\nimport { Switch } from './ui/switch'\nimport { useState } from 'react'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './ui/dropdown-menu'\nimport { Pagination } from './Pagination'\nimport { Server, MoreHorizontal, Copy, AlertTriangle, CheckCircle, Timer, Pause } from 'lucide-react'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { TableEmptyState } from './TableEmptyState'\nimport { toast } from 'sonner'\nimport { DebouncedInput } from './DebouncedInput'\nimport { cn } from '@/lib/utils'\n\ninterface RunnerTableProps {\n  data: Runner[]\n  regions: Region[]\n  loading: boolean\n  isLoadingRunner: (runner: Runner) => boolean\n  writePermitted: boolean\n  deletePermitted: boolean\n  onToggleEnabled: (runner: Runner) => void\n  onDelete: (runner: Runner) => void\n  getRegionName: (regionId: string) => string | undefined\n  onRowClick?: (runner: Runner) => void\n  autoRefresh?: boolean\n  onAutoRefreshChange?: (enabled: boolean) => void\n}\n\nexport function RunnerTable({\n  data,\n  regions,\n  loading,\n  isLoadingRunner,\n  writePermitted,\n  deletePermitted,\n  onToggleEnabled,\n  onDelete,\n  getRegionName,\n  onRowClick,\n  autoRefresh,\n  onAutoRefreshChange,\n}: RunnerTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [globalFilter, setGlobalFilter] = useState('')\n\n  const copyToClipboard = async (text: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      toast.success('Copied to clipboard')\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n      toast.error('Failed to copy to clipboard')\n    }\n  }\n\n  const columns = getColumns({\n    onToggleEnabled,\n    onDelete,\n    isLoadingRunner,\n    writePermitted,\n    deletePermitted,\n    copyToClipboard,\n    getRegionName,\n  })\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getFilteredRowModel: getFilteredRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    onGlobalFilterChange: setGlobalFilter,\n    globalFilterFn: (row, columnId, filterValue) => {\n      const runner = row.original as Runner\n      const searchValue = filterValue.toLowerCase()\n      const regionName = getRegionName(runner.region) ?? runner.region\n      return (\n        runner.id.toLowerCase().includes(searchValue) ||\n        runner.name.toLowerCase().includes(searchValue) ||\n        regionName.toLowerCase().includes(searchValue)\n      )\n    },\n    state: {\n      sorting,\n      globalFilter,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  return (\n    <div>\n      <div className=\"flex items-center flex-wrap gap-4 mb-4\">\n        <DebouncedInput\n          value={globalFilter ?? ''}\n          onChange={(value) => setGlobalFilter(String(value))}\n          placeholder=\"Search by ID, Name, or Region\"\n          className=\"max-w-sm\"\n        />\n        {onAutoRefreshChange && (\n          <div className=\"flex items-center gap-2\">\n            <span className=\"text-sm text-muted-foreground\">Auto-refresh</span>\n            <Switch checked={autoRefresh} onCheckedChange={onAutoRefreshChange} />\n          </div>\n        )}\n      </div>\n      <div className=\"rounded-md border\">\n        <Table style={{ tableLayout: 'fixed', width: '100%' }}>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      className=\"px-2\"\n                      key={header.id}\n                      style={{\n                        width: `${header.column.getSize()}px`,\n                      }}\n                    >\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  Loading...\n                </TableCell>\n              </TableRow>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow\n                  key={row.id}\n                  data-state={row.getIsSelected() && 'selected'}\n                  className={cn(\n                    isLoadingRunner(row.original) ? 'opacity-50 pointer-events-none' : '',\n                    onRowClick && 'cursor-pointer hover:bg-muted/50',\n                  )}\n                  onClick={() => onRowClick?.(row.original)}\n                >\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell\n                      className=\"px-2\"\n                      key={cell.id}\n                      style={{\n                        width: `${cell.column.getSize()}px`,\n                      }}\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No runners found.\"\n                icon={<Server className=\"w-8 h-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>Runners are the machines that run your sandboxes.</p>\n                    {regions.length === 0 && (\n                      <p>There must be at least one region in your organization before runners can be created.</p>\n                    )}\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination table={table} className=\"mt-4\" entityName=\"Runners\" />\n    </div>\n  )\n}\n\nconst getColumns = ({\n  onToggleEnabled,\n  onDelete,\n  isLoadingRunner,\n  writePermitted,\n  deletePermitted,\n  copyToClipboard,\n  getRegionName,\n}: {\n  onToggleEnabled: (runner: Runner) => void\n  onDelete: (runner: Runner) => void\n  isLoadingRunner: (runner: Runner) => boolean\n  writePermitted: boolean\n  deletePermitted: boolean\n  copyToClipboard: (text: string) => Promise<void>\n  getRegionName: (regionId: string) => string | undefined\n}): ColumnDef<Runner>[] => {\n  const getStateIcon = (state: RunnerState) => {\n    switch (state) {\n      case RunnerState.READY:\n        return <CheckCircle className=\"w-4 h-4 flex-shrink-0\" />\n      case RunnerState.DISABLED:\n      case RunnerState.DECOMMISSIONED:\n        return <Pause className=\"w-4 h-4 flex-shrink-0\" />\n      case RunnerState.UNRESPONSIVE:\n        return <AlertTriangle className=\"w-4 h-4 flex-shrink-0\" />\n      default:\n        return <Timer className=\"w-4 h-4 flex-shrink-0\" />\n    }\n  }\n\n  const getStateColor = (state: RunnerState) => {\n    switch (state) {\n      case RunnerState.READY:\n        return 'text-green-500'\n      case RunnerState.DISABLED:\n      case RunnerState.DECOMMISSIONED:\n        return 'text-gray-500 dark:text-gray-400'\n      case RunnerState.UNRESPONSIVE:\n        return 'text-red-500'\n      default:\n        return 'text-gray-600 dark:text-gray-400'\n    }\n  }\n\n  const getStateLabel = (state: RunnerState) => {\n    return state\n      .split('_')\n      .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n      .join(' ')\n  }\n\n  const isRunnerSchedulable = (runner: Runner) => {\n    return !runner.unschedulable\n  }\n\n  const columns: ColumnDef<Runner>[] = [\n    {\n      accessorKey: 'id',\n      header: 'ID',\n      size: 240,\n      cell: ({ row }) => (\n        <div className=\"w-full truncate flex items-center gap-2\">\n          <span className=\"truncate block text-sm\">{row.original.id}</span>\n          <button\n            onClick={(e) => {\n              e.stopPropagation()\n              copyToClipboard(row.original.id)\n            }}\n            className=\"text-muted-foreground hover:text-foreground transition-colors\"\n            aria-label=\"Copy ID\"\n          >\n            <Copy className=\"w-3 h-3\" />\n          </button>\n        </div>\n      ),\n    },\n    {\n      accessorKey: 'name',\n      header: 'Name',\n      size: 240,\n      cell: ({ row }) => (\n        <div className=\"w-full truncate flex items-center gap-2\">\n          <span className=\"truncate block text-sm\">{row.original.name}</span>\n          <button\n            onClick={(e) => {\n              e.stopPropagation()\n              copyToClipboard(row.original.name)\n            }}\n            className=\"text-muted-foreground hover:text-foreground transition-colors\"\n            aria-label=\"Copy Name\"\n          >\n            <Copy className=\"w-3 h-3\" />\n          </button>\n        </div>\n      ),\n    },\n    {\n      accessorKey: 'regionId',\n      header: 'Region',\n      size: 180,\n      cell: ({ row }) => (\n        <div className=\"w-full truncate flex items-center gap-2\">\n          <span className=\"truncate block text-sm\">{getRegionName(row.original.region) ?? row.original.region}</span>\n          <button\n            onClick={(e) => {\n              e.stopPropagation()\n              copyToClipboard(getRegionName(row.original.region) ?? row.original.region)\n            }}\n            className=\"text-muted-foreground hover:text-foreground transition-colors\"\n            aria-label=\"Copy Region\"\n          >\n            <Copy className=\"w-3 h-3\" />\n          </button>\n        </div>\n      ),\n    },\n    // {\n    //   accessorKey: 'domain',\n    //   header: 'Domain',\n    //   size: 180,\n    //   cell: ({ row }) => (\n    //     <div className=\"w-full truncate flex items-center gap-2\">\n    //       <span className=\"truncate block text-sm\">{row.original.domain || '/'}</span>\n    //       {row.original.domain && (\n    //         <button\n    //           onClick={(e) => {\n    //             e.stopPropagation()\n    //             copyToClipboard(row.original.domain!)\n    //           }}\n    //           className=\"text-muted-foreground hover:text-foreground transition-colors\"\n    //           aria-label=\"Copy Domain\"\n    //         >\n    //           <Copy className=\"w-3 h-3\" />\n    //         </button>\n    //       )}\n    //     </div>\n    //   ),\n    // },\n    {\n      accessorKey: 'state',\n      header: 'State',\n      size: 200,\n      cell: ({ row }) => (\n        <div className={`flex items-center gap-2 ${getStateColor(row.original.state)}`}>\n          {getStateIcon(row.original.state)}\n          {getStateLabel(row.original.state)}\n        </div>\n      ),\n    },\n    {\n      accessorKey: 'unschedulable',\n      header: 'Schedulable',\n      size: 60,\n      cell: ({ row }) => {\n        const isLoading = isLoadingRunner(row.original)\n        return (\n          <Switch\n            checked={isRunnerSchedulable(row.original)}\n            onCheckedChange={() => writePermitted && !isLoading && onToggleEnabled(row.original)}\n            disabled={!writePermitted || isLoading}\n            onClick={(e) => e.stopPropagation()}\n          />\n        )\n      },\n    },\n  ]\n\n  columns.push({\n    id: 'options',\n    header: () => {\n      return null\n    },\n    cell: ({ row }) => {\n      if (!deletePermitted) {\n        return null\n      }\n\n      const isLoading = isLoadingRunner(row.original)\n\n      return (\n        <div className=\"flex justify-end\">\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>\n              <Button variant=\"ghost\" size=\"sm\" className=\"h-8 w-8 p-0\" disabled={isLoading}>\n                <MoreHorizontal className=\"h-4 w-4\" />\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\">\n              <DropdownMenuItem\n                onClick={(e) => {\n                  e.stopPropagation()\n                  onDelete(row.original)\n                }}\n                className=\"cursor-pointer text-red-600 dark:text-red-400\"\n                disabled={isLoading}\n              >\n                Delete\n              </DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </div>\n      )\n    },\n  })\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Sandbox/CreateSandboxSheet.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport { Field, FieldDescription, FieldError, FieldLabel } from '@/components/ui/field'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport {\n  Sheet,\n  SheetContent,\n  SheetDescription,\n  SheetFooter,\n  SheetHeader,\n  SheetTitle,\n  SheetTrigger,\n} from '@/components/ui/sheet'\nimport { Spinner } from '@/components/ui/spinner'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport { FeatureFlags } from '@/enums/FeatureFlags'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useCreateSandboxMutation } from '@/hooks/mutations/useCreateSandboxMutation'\nimport { useSnapshotsQuery } from '@/hooks/queries/useSnapshotsQuery'\nimport { useConfig } from '@/hooks/useConfig'\nimport { useRegions } from '@/hooks/useRegions'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { parseEnvFile } from '@/lib/env'\nimport { handleApiError } from '@/lib/error-handling'\nimport { imageNameSchema } from '@/lib/schema'\nimport { cn, getRegionFullDisplayName } from '@/lib/utils'\nimport { Sandbox } from '@daytonaio/sdk'\nimport { useForm } from '@tanstack/react-form'\nimport { Info, Minus, Plus, Upload } from 'lucide-react'\nimport { useFeatureFlagEnabled } from 'posthog-js/react'\nimport { ComponentProps, useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { NumericFormat } from 'react-number-format'\nimport { createSearchParams, generatePath, useNavigate } from 'react-router-dom'\nimport { toast } from 'sonner'\nimport { z } from 'zod'\nimport { Tooltip } from '../Tooltip'\nimport { ScrollArea } from '../ui/scroll-area'\n\nconst NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/\n\nconst NONE_VALUE = '__none__'\n\nenum Source {\n  SNAPSHOT = 'snapshot',\n  IMAGE = 'image',\n}\n\nconst keyValuePairSchema = z.object({\n  key: z.string(),\n  value: z.string(),\n})\n\nconst noDuplicateKeys = (pairs: { key: string; value: string }[] | undefined) => {\n  if (!pairs) return true\n  const keys = pairs.filter((p) => p.key).map((p) => p.key)\n  return new Set(keys).size === keys.length\n}\n\nconst resourceSchema = (name: string, max: number | undefined) =>\n  z\n    .number()\n    .optional()\n    .refine(\n      (val) => val === undefined || (val >= 1 && (!max || val <= max)),\n      max ? `${name} must be between 1 and ${max}` : `${name} must be at least 1`,\n    )\n\nconst buildBaseFormSchema = (maxCpu?: number, maxMemory?: number, maxDisk?: number) =>\n  z.object({\n    name: z\n      .string()\n      .optional()\n      .refine((val) => !val || NAME_REGEX.test(val), 'Only letters, digits, dots, underscores and dashes are allowed'),\n    regionId: z.string().optional(),\n    cpu: resourceSchema('CPU', maxCpu),\n    memory: resourceSchema('Memory', maxMemory),\n    disk: resourceSchema('Storage', maxDisk),\n    autoStopInterval: z.number().min(0).optional(),\n    autoArchiveInterval: z.number().min(0).optional(),\n    autoDeleteInterval: z\n      .number()\n      .refine((val) => val === -1 || val >= 0, 'Must be -1 (disabled) or a non-negative number')\n      .optional(),\n    envVars: z.array(keyValuePairSchema).optional().refine(noDuplicateKeys, 'Duplicate keys are not allowed'),\n    labels: z.array(keyValuePairSchema).optional().refine(noDuplicateKeys, 'Duplicate keys are not allowed'),\n    public: z.boolean().optional(),\n    networkBlockAll: z.boolean().optional(),\n    ephemeral: z.boolean().optional(),\n  })\n\nconst buildFormSchema = (maxCpu?: number, maxMemory?: number, maxDisk?: number) => {\n  const base = buildBaseFormSchema(maxCpu, maxMemory, maxDisk)\n  return z.discriminatedUnion('source', [\n    base.extend({\n      source: z.literal(Source.SNAPSHOT),\n      snapshot: z.string().optional(),\n      image: z.string().optional(),\n    }),\n    base.extend({\n      source: z.literal(Source.IMAGE),\n      snapshot: z.string().optional(),\n      image: imageNameSchema,\n    }),\n  ])\n}\n\ntype FormValues = z.input<ReturnType<typeof buildBaseFormSchema>> & {\n  source: Source\n  snapshot?: string\n  image?: string\n}\n\nconst defaultValues: FormValues = {\n  name: '',\n  source: Source.SNAPSHOT,\n  snapshot: undefined,\n  image: '',\n  regionId: undefined,\n  cpu: undefined,\n  memory: undefined,\n  disk: undefined,\n  autoStopInterval: undefined,\n  autoArchiveInterval: undefined,\n  autoDeleteInterval: undefined,\n  envVars: [],\n  labels: [],\n  public: false,\n  networkBlockAll: false,\n  ephemeral: false,\n}\n\nconst InfoTooltipButton = ({ className, ...props }: ComponentProps<'button'>) => {\n  return (\n    <button className={cn('rounded-full', className)} {...props}>\n      <Info className=\"size-3 text-muted-foreground\" />\n    </button>\n  )\n}\n\nexport const CreateSandboxSheet = ({ className }: { className?: string }) => {\n  const navigate = useNavigate()\n  const createSandboxEnabled = useFeatureFlagEnabled(FeatureFlags.DASHBOARD_CREATE_SANDBOX)\n  const [open, setOpen] = useState(false)\n\n  const config = useConfig()\n  const { availableRegions: regions, loadingAvailableRegions: loadingRegions } = useRegions()\n  const { selectedOrganization } = useSelectedOrganization()\n  const { reset: resetCreateSandboxMutation, ...createSandboxMutation } = useCreateSandboxMutation()\n  const formRef = useRef<HTMLFormElement>(null)\n\n  const maxCpu = selectedOrganization?.maxCpuPerSandbox\n  const maxMemory = selectedOrganization?.maxMemoryPerSandbox\n  const maxDisk = selectedOrganization?.maxDiskPerSandbox\n\n  const formSchema = useMemo(() => buildFormSchema(maxCpu, maxMemory, maxDisk), [maxCpu, maxMemory, maxDisk])\n\n  const { data: snapshotsData, isLoading: snapshotsLoading } = useSnapshotsQuery({\n    page: 1,\n    pageSize: 100,\n  })\n\n  const form = useForm({\n    defaultValues,\n    validators: {\n      onSubmit: formSchema,\n    },\n    onSubmitInvalid: () => {\n      const formEl = formRef.current\n      if (!formEl) return\n      const invalidInput = formEl.querySelector('[aria-invalid=\"true\"]') as HTMLInputElement | null\n      if (invalidInput) {\n        invalidInput.scrollIntoView({ behavior: 'smooth', block: 'center' })\n        invalidInput.focus()\n      }\n    },\n    onSubmit: async ({ value }) => {\n      if (!selectedOrganization?.id) {\n        toast.error('Select an organization to create a sandbox.')\n        return\n      }\n\n      const envVars: Record<string, string> = {}\n      value.envVars?.forEach(({ key, value: val }) => {\n        if (key) envVars[key] = val\n      })\n\n      const labels: Record<string, string> = {}\n      value.labels?.forEach(({ key, value: val }) => {\n        if (key) labels[key] = val\n      })\n\n      const isImage = value.source === Source.IMAGE\n\n      const baseParams = {\n        name: value.name?.trim() || undefined,\n        target: value.regionId || undefined,\n        autoStopInterval: value.autoStopInterval,\n        autoArchiveInterval: value.autoArchiveInterval,\n        autoDeleteInterval: value.autoDeleteInterval,\n        ephemeral: value.ephemeral || undefined,\n        envVars: Object.keys(envVars).length > 0 ? envVars : undefined,\n        labels: Object.keys(labels).length > 0 ? labels : undefined,\n        public: value.public || undefined,\n        networkBlockAll: value.networkBlockAll || undefined,\n      }\n\n      let sandbox: Sandbox | undefined = undefined\n      try {\n        if (isImage && value.image) {\n          sandbox = await createSandboxMutation.mutateAsync({\n            ...baseParams,\n            image: value.image,\n            resources:\n              value.cpu || value.memory || value.disk\n                ? { cpu: value.cpu, memory: value.memory, disk: value.disk }\n                : undefined,\n          })\n        } else {\n          sandbox = await createSandboxMutation.mutateAsync({\n            ...baseParams,\n            snapshot: value.snapshot || undefined,\n          })\n        }\n\n        toast.success(`Sandbox created`)\n\n        setOpen(false)\n\n        if (sandbox?.id) {\n          navigate({\n            pathname: generatePath(RoutePath.SANDBOX_DETAILS, { sandboxId: sandbox.id }),\n            search: `${createSearchParams({\n              tab: 'terminal',\n            })}`,\n          })\n        }\n      } catch (error) {\n        handleApiError(error, 'Failed to create sandbox')\n      }\n    },\n  })\n\n  const handleSourceChange = useCallback(\n    (val: string) => {\n      form.setFieldValue('source', val as Source)\n      if (val === Source.SNAPSHOT) {\n        form.setFieldValue('image', '')\n        form.setFieldValue('cpu', undefined)\n        form.setFieldValue('memory', undefined)\n        form.setFieldValue('disk', undefined)\n      } else {\n        form.setFieldValue('snapshot', undefined)\n      }\n    },\n    [form],\n  )\n\n  const resetState = useCallback(() => {\n    form.reset(defaultValues)\n    resetCreateSandboxMutation()\n  }, [resetCreateSandboxMutation, form])\n\n  const handleEnvFileImport = useCallback(\n    (e: React.ChangeEvent<HTMLInputElement>) => {\n      const file = e.target.files?.[0]\n      if (!file) return\n\n      const reader = new FileReader()\n      reader.onload = () => {\n        const parsed = parseEnvFile(reader.result as string)\n        if (parsed.length === 0) return\n\n        const existing = form.getFieldValue('envVars') ?? []\n        const nonEmpty = existing.filter((p) => p.key || p.value)\n        form.setFieldValue('envVars', [...nonEmpty, ...parsed])\n      }\n      reader.readAsText(file)\n      e.target.value = ''\n    },\n    [form],\n  )\n\n  const handleEnvPaste = useCallback(\n    (e: React.ClipboardEvent<HTMLInputElement>, index: number) => {\n      const text = e.clipboardData.getData('text')\n      if (!text.includes('=') || !text.includes('\\n')) return\n      e.preventDefault()\n      const parsed = parseEnvFile(text)\n      if (parsed.length === 0) return\n\n      const existing = form.getFieldValue('envVars') ?? []\n      const current = existing[index]\n      const isEmptyRow = !current?.key && !current?.value\n      const before = existing.slice(0, index)\n      const after = existing.slice(index + (isEmptyRow ? 1 : 0))\n\n      form.setFieldValue('envVars', [...before, ...parsed, ...after])\n    },\n    [form],\n  )\n\n  useEffect(() => {\n    if (open) {\n      resetState()\n    }\n  }, [open, resetState])\n\n  if (!createSandboxEnabled) {\n    return null\n  }\n\n  return (\n    <Sheet\n      open={open}\n      onOpenChange={(isOpen) => {\n        setOpen(isOpen)\n      }}\n    >\n      <SheetTrigger asChild>\n        <Button variant=\"default\" size=\"sm\" title=\"Create Sandbox\">\n          <Plus className=\"size-4\" />\n          Create Sandbox\n        </Button>\n      </SheetTrigger>\n      <SheetContent className={`w-dvw sm:w-[500px] p-0 flex flex-col gap-0 ${className ?? ''}`}>\n        <SheetHeader className=\"border-b border-border p-4 px-5 items-center flex text-left flex-row\">\n          <SheetTitle className=\"text-2xl\">Create Sandbox</SheetTitle>\n          <SheetDescription className=\"sr-only\">Create a new sandbox in your organization.</SheetDescription>\n        </SheetHeader>\n        <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0\">\n          <form\n            ref={formRef}\n            id=\"create-sandbox-form\"\n            className=\"gap-6 flex flex-col p-5\"\n            onSubmit={(e) => {\n              e.preventDefault()\n              e.stopPropagation()\n              form.handleSubmit()\n            }}\n          >\n            <form.Field name=\"name\">\n              {(field) => {\n                const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                return (\n                  <Field data-invalid={isInvalid}>\n                    <FieldLabel htmlFor={field.name}>Name</FieldLabel>\n                    <Input\n                      aria-invalid={isInvalid}\n                      id={field.name}\n                      name={field.name}\n                      value={field.state.value}\n                      onBlur={field.handleBlur}\n                      onChange={(e) => field.handleChange(e.target.value)}\n                      placeholder=\"my-sandbox\"\n                    />\n                    <FieldDescription>\n                      Optional. If not provided, the sandbox ID will be used as the name. Names are reusable once a\n                      sandbox is destroyed.\n                    </FieldDescription>\n                    {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                      <FieldError errors={field.state.meta.errors} />\n                    )}\n                  </Field>\n                )\n              }}\n            </form.Field>\n\n            <form.Subscribe selector={(state) => state.values.source}>\n              {(source) => (\n                <Tabs value={source} onValueChange={handleSourceChange} className=\"gap-3\">\n                  <div className=\"flex flex-col gap-2\">\n                    <FieldLabel>Source</FieldLabel>\n                    <TabsList className=\"w-full\">\n                      <TabsTrigger value={Source.SNAPSHOT} className=\"flex-1\">\n                        Snapshot\n                      </TabsTrigger>\n                      <TabsTrigger value={Source.IMAGE} className=\"flex-1\">\n                        Image\n                      </TabsTrigger>\n                    </TabsList>\n                  </div>\n\n                  <TabsContent value={Source.SNAPSHOT}>\n                    <form.Field name=\"snapshot\">\n                      {(field) => (\n                        <Field>\n                          <FieldLabel htmlFor={field.name}>Snapshot</FieldLabel>\n                          <Select\n                            value={field.state.value || NONE_VALUE}\n                            onValueChange={(val) => field.handleChange(val === NONE_VALUE ? '' : val)}\n                          >\n                            <SelectTrigger\n                              className=\"h-8\"\n                              id={field.name}\n                              disabled={snapshotsLoading}\n                              loading={snapshotsLoading}\n                            >\n                              <SelectValue\n                                placeholder={snapshotsLoading ? 'Loading snapshots...' : 'Select a snapshot'}\n                              />\n                            </SelectTrigger>\n                            <SelectContent>\n                              <SelectItem value={NONE_VALUE}>\n                                {config.defaultSnapshot} <Badge variant=\"secondary\">default</Badge>\n                              </SelectItem>\n                              {snapshotsData?.items?.map((snapshot) => (\n                                <SelectItem key={snapshot.id} value={snapshot.name}>\n                                  {snapshot.name}\n                                </SelectItem>\n                              ))}\n                            </SelectContent>\n                          </Select>\n                        </Field>\n                      )}\n                    </form.Field>\n                  </TabsContent>\n\n                  <TabsContent value={Source.IMAGE} className=\"flex flex-col gap-4\">\n                    <form.Field name=\"image\">\n                      {(field) => {\n                        const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                        return (\n                          <Field data-invalid={isInvalid}>\n                            <FieldLabel htmlFor={field.name}>Image</FieldLabel>\n                            <Input\n                              aria-invalid={isInvalid}\n                              id={field.name}\n                              value={field.state.value}\n                              onBlur={field.handleBlur}\n                              onChange={(e) => field.handleChange(e.target.value)}\n                              placeholder=\"ubuntu:22.04\"\n                            />\n                            <FieldDescription>\n                              Must include either a tag (e.g., ubuntu:22.04) or a digest. The tag &quot;latest&quot; is\n                              not allowed.\n                            </FieldDescription>\n                            {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                              <FieldError errors={field.state.meta.errors} />\n                            )}\n                          </Field>\n                        )\n                      }}\n                    </form.Field>\n                    <div className=\"flex flex-col gap-2\">\n                      <Label className=\"text-sm font-medium\">Resources</Label>\n                      <div className=\"flex flex-col gap-2\">\n                        <form.Field name=\"cpu\">\n                          {(field) => {\n                            const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                            return (\n                              <div className=\"flex flex-col gap-1\">\n                                <div className=\"flex items-center gap-4\">\n                                  <Label htmlFor={field.name} className=\"w-32 flex-shrink-0\">\n                                    Compute (vCPU):\n                                  </Label>\n                                  <NumericFormat\n                                    customInput={Input}\n                                    aria-invalid={isInvalid}\n                                    id={field.name}\n                                    className=\"w-full\"\n                                    placeholder=\"1\"\n                                    decimalScale={0}\n                                    allowNegative={false}\n                                    isAllowed={(values) => {\n                                      if (values.floatValue === undefined) return true\n                                      return !maxCpu || values.floatValue <= maxCpu\n                                    }}\n                                    value={field.state.value ?? ''}\n                                    onBlur={field.handleBlur}\n                                    onValueChange={(values) => field.handleChange(values.floatValue ?? undefined)}\n                                  />\n                                </div>\n                                {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                                  <FieldError errors={field.state.meta.errors} />\n                                )}\n                              </div>\n                            )\n                          }}\n                        </form.Field>\n                        <form.Field name=\"memory\">\n                          {(field) => {\n                            const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                            return (\n                              <div className=\"flex flex-col gap-1\">\n                                <div className=\"flex items-center gap-4\">\n                                  <Label htmlFor={field.name} className=\"w-32 flex-shrink-0\">\n                                    Memory (GiB):\n                                  </Label>\n                                  <NumericFormat\n                                    customInput={Input}\n                                    aria-invalid={isInvalid}\n                                    id={field.name}\n                                    className=\"w-full\"\n                                    placeholder=\"1\"\n                                    decimalScale={0}\n                                    allowNegative={false}\n                                    isAllowed={(values) => {\n                                      if (values.floatValue === undefined) return true\n                                      return !maxMemory || values.floatValue <= maxMemory\n                                    }}\n                                    value={field.state.value ?? ''}\n                                    onBlur={field.handleBlur}\n                                    onValueChange={(values) => field.handleChange(values.floatValue ?? undefined)}\n                                  />\n                                </div>\n                                {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                                  <FieldError errors={field.state.meta.errors} />\n                                )}\n                              </div>\n                            )\n                          }}\n                        </form.Field>\n                        <form.Field name=\"disk\">\n                          {(field) => {\n                            const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                            return (\n                              <div className=\"flex flex-col gap-1\">\n                                <div className=\"flex items-center gap-4\">\n                                  <Label htmlFor={field.name} className=\"w-32 flex-shrink-0\">\n                                    Storage (GiB):\n                                  </Label>\n                                  <NumericFormat\n                                    customInput={Input}\n                                    aria-invalid={isInvalid}\n                                    id={field.name}\n                                    className=\"w-full\"\n                                    placeholder=\"3\"\n                                    decimalScale={0}\n                                    allowNegative={false}\n                                    isAllowed={(values) => {\n                                      if (values.floatValue === undefined) return true\n                                      return !maxDisk || values.floatValue <= maxDisk\n                                    }}\n                                    value={field.state.value ?? ''}\n                                    onBlur={field.handleBlur}\n                                    onValueChange={(values) => field.handleChange(values.floatValue ?? undefined)}\n                                  />\n                                </div>\n                                {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                                  <FieldError errors={field.state.meta.errors} />\n                                )}\n                              </div>\n                            )\n                          }}\n                        </form.Field>\n                      </div>\n                      <FieldDescription>\n                        {`Defaults: 1 vCPU, 1 GiB memory, 3 GiB storage.`}\n                        <br />\n                        {maxCpu ? ` Limits: ${maxCpu} vCPU, ${maxMemory} GiB memory, ${maxDisk} GiB storage.` : ''}\n                      </FieldDescription>\n                    </div>\n                  </TabsContent>\n                </Tabs>\n              )}\n            </form.Subscribe>\n\n            <form.Field name=\"regionId\">\n              {(field) => (\n                <Field>\n                  <FieldLabel htmlFor={field.name}>Region</FieldLabel>\n                  <Select value={field.state.value} onValueChange={field.handleChange}>\n                    <SelectTrigger className=\"h-8\" id={field.name} disabled={loadingRegions} loading={loadingRegions}>\n                      <SelectValue placeholder={loadingRegions ? 'Loading regions...' : 'Select a region'} />\n                    </SelectTrigger>\n                    <SelectContent>\n                      {regions.map((region) => (\n                        <SelectItem key={region.id} value={region.id}>\n                          {getRegionFullDisplayName(region)}\n                        </SelectItem>\n                      ))}\n                    </SelectContent>\n                  </Select>\n                  <FieldDescription>\n                    The region where the sandbox will be created. If not specified, your organization's default region\n                    will be used.\n                  </FieldDescription>\n                </Field>\n              )}\n            </form.Field>\n            <div className=\"flex flex-col gap-2\">\n              <Label className=\"text-sm font-medium\">Lifecycle</Label>\n              <div className=\"flex flex-col gap-2\">\n                <form.Field name=\"autoStopInterval\">\n                  {(field) => (\n                    <div className=\"flex items-center gap-4\">\n                      <Label htmlFor={field.name} className=\"w-40 flex-shrink-0 flex items-center gap-1\">\n                        Auto-stop (min):\n                        <Tooltip\n                          label={<InfoTooltipButton aria-label=\"Auto-stop information\" />}\n                          content={\n                            <p>\n                              Minutes of inactivity before stopping. Resets on preview access, SSH, or Toolbox API\n                              calls.\n                              <br />\n                              <span className=\"text-muted-foreground\">0 = disabled</span>\n                            </p>\n                          }\n                          side=\"right\"\n                          contentClassName=\"max-w-xs\"\n                        />\n                      </Label>\n                      <NumericFormat\n                        customInput={Input}\n                        id={field.name}\n                        className=\"w-full\"\n                        placeholder=\"15\"\n                        decimalScale={0}\n                        allowNegative={false}\n                        value={field.state.value ?? ''}\n                        onValueChange={(values) => field.handleChange(values.floatValue ?? undefined)}\n                      />\n                    </div>\n                  )}\n                </form.Field>\n                <form.Field name=\"autoArchiveInterval\">\n                  {(field) => (\n                    <div className=\"flex items-center gap-4\">\n                      <Label htmlFor={field.name} className=\"w-40 flex-shrink-0 flex items-center gap-1\">\n                        Auto-archive (min):\n                        <Tooltip\n                          label={<InfoTooltipButton aria-label=\"Auto-archive information\" />}\n                          content={\n                            <p>\n                              Minutes a sandbox must remain continuously stopped before archiving.\n                              <br />\n                              <span className=\"text-muted-foreground\">0 = max (30 days)</span>\n                            </p>\n                          }\n                          side=\"right\"\n                          contentClassName=\"max-w-xs\"\n                        />\n                      </Label>\n                      <NumericFormat\n                        customInput={Input}\n                        id={field.name}\n                        className=\"w-full\"\n                        placeholder=\"10080 (7 days)\"\n                        decimalScale={0}\n                        allowNegative={false}\n                        value={field.state.value ?? ''}\n                        onValueChange={(values) => field.handleChange(values.floatValue ?? undefined)}\n                      />\n                    </div>\n                  )}\n                </form.Field>\n                <form.Field name=\"autoDeleteInterval\">\n                  {(field) => (\n                    <form.Subscribe selector={(state) => state.values.ephemeral}>\n                      {(ephemeral) => (\n                        <div className=\"flex items-center gap-4\">\n                          <Label htmlFor={field.name} className=\"w-40 flex-shrink-0 flex items-center gap-1\">\n                            Auto-delete (min):\n                            <Tooltip\n                              label={<InfoTooltipButton aria-label=\"Auto-delete information\" />}\n                              content={\n                                <p>\n                                  Minutes a sandbox must remain continuously stopped before permanent deletion.\n                                  <br />\n                                  <span className=\"text-muted-foreground\">0 = deleted on stop</span>\n                                  <br />\n                                  <span className=\"text-muted-foreground\">-1 = disabled</span>\n                                </p>\n                              }\n                              side=\"right\"\n                              contentClassName=\"max-w-xs\"\n                            />\n                          </Label>\n                          <NumericFormat\n                            customInput={Input}\n                            id={field.name}\n                            className=\"w-full\"\n                            placeholder=\"Disabled\"\n                            disabled={ephemeral}\n                            decimalScale={0}\n                            allowNegative\n                            isAllowed={(values) => {\n                              if (values.floatValue === undefined) return true\n                              return values.floatValue === -1 || values.floatValue >= 0\n                            }}\n                            value={ephemeral ? 0 : (field.state.value ?? '')}\n                            onValueChange={(values) => field.handleChange(values.floatValue ?? undefined)}\n                          />\n                        </div>\n                      )}\n                    </form.Subscribe>\n                  )}\n                </form.Field>\n                <form.Field name=\"ephemeral\">\n                  {(field) => (\n                    <div className=\"flex items-start gap-2\">\n                      <Checkbox\n                        className=\"mt-0.5\"\n                        id={field.name}\n                        checked={field.state.value ?? false}\n                        onCheckedChange={(checked) => {\n                          const isEphemeral = checked === true\n                          field.handleChange(isEphemeral)\n                          if (isEphemeral) {\n                            form.setFieldValue('autoDeleteInterval', 0)\n                          }\n                        }}\n                      />\n                      <div className=\"flex flex-col gap-1\">\n                        <Label htmlFor={field.name} className=\"text-sm font-normal\">\n                          Ephemeral\n                        </Label>\n                        <FieldDescription>Automatically delete the sandbox when it stops.</FieldDescription>\n                      </div>\n                    </div>\n                  )}\n                </form.Field>\n              </div>\n            </div>\n\n            <form.Field name=\"envVars\">\n              {(field) => {\n                const hasErrors = field.state.meta.errors.length > 0\n                return (\n                  <Field data-invalid={hasErrors}>\n                    <FieldLabel>Environment Variables</FieldLabel>\n                    <div className=\"flex flex-col gap-2\">\n                      {(field.state.value ?? []).map((_, index) => (\n                        <div key={index} className=\"flex items-center gap-2\">\n                          <Input\n                            placeholder=\"Key\"\n                            value={field.state.value?.[index]?.key ?? ''}\n                            onChange={(e) => {\n                              const updated = [...(field.state.value ?? [])]\n                              updated[index] = { ...updated[index], key: e.target.value }\n                              field.handleChange(updated)\n                            }}\n                            onPaste={(e) => handleEnvPaste(e, index)}\n                          />\n                          <Input\n                            placeholder=\"Value\"\n                            value={field.state.value?.[index]?.value ?? ''}\n                            onChange={(e) => {\n                              const updated = [...(field.state.value ?? [])]\n                              updated[index] = { ...updated[index], value: e.target.value }\n                              field.handleChange(updated)\n                            }}\n                          />\n                          <Button\n                            type=\"button\"\n                            variant=\"ghost\"\n                            size=\"icon\"\n                            aria-label=\"Remove variable\"\n                            className=\"flex-shrink-0 h-8 w-8\"\n                            onClick={() => {\n                              const updated = (field.state.value ?? []).filter((_, i) => i !== index)\n                              field.handleChange(updated)\n                            }}\n                          >\n                            <Minus className=\"size-4\" />\n                          </Button>\n                        </div>\n                      ))}\n                      <Button\n                        type=\"button\"\n                        variant=\"outline\"\n                        size=\"sm\"\n                        className=\"w-fit\"\n                        onClick={() => field.handleChange([...(field.state.value ?? []), { key: '', value: '' }])}\n                      >\n                        <Plus className=\"size-4\" />\n                        Add Variable\n                      </Button>\n                    </div>\n                    <FieldDescription asChild>\n                      <div>\n                        <input\n                          type=\"file\"\n                          accept=\"env\"\n                          className=\"sr-only peer\"\n                          onChange={handleEnvFileImport}\n                          id=\"env-file-input\"\n                        />\n                        <label\n                          className=\"inline-flex items-center gap-1 underline hover:text-foreground cursor-pointer peer-focus-visible:text-primary\"\n                          htmlFor=\"env-file-input\"\n                        >\n                          <Upload className=\"size-3\" />\n                          Import .env file\n                        </label>{' '}\n                        or paste .env contents into any key field.\n                      </div>\n                    </FieldDescription>\n                    {hasErrors && <FieldError errors={field.state.meta.errors} />}\n                  </Field>\n                )\n              }}\n            </form.Field>\n\n            <form.Field name=\"labels\">\n              {(field) => {\n                const hasErrors = field.state.meta.errors.length > 0\n                return (\n                  <Field data-invalid={hasErrors}>\n                    <FieldLabel>Labels</FieldLabel>\n                    <div className=\"flex flex-col gap-2\">\n                      {(field.state.value ?? []).map((_, index) => (\n                        <div key={index} className=\"flex items-center gap-2\">\n                          <Input\n                            placeholder=\"Key\"\n                            value={field.state.value?.[index]?.key ?? ''}\n                            onChange={(e) => {\n                              const updated = [...(field.state.value ?? [])]\n                              updated[index] = { ...updated[index], key: e.target.value }\n                              field.handleChange(updated)\n                            }}\n                          />\n                          <Input\n                            placeholder=\"Value\"\n                            value={field.state.value?.[index]?.value ?? ''}\n                            onChange={(e) => {\n                              const updated = [...(field.state.value ?? [])]\n                              updated[index] = { ...updated[index], value: e.target.value }\n                              field.handleChange(updated)\n                            }}\n                          />\n                          <Button\n                            type=\"button\"\n                            variant=\"ghost\"\n                            size=\"icon\"\n                            aria-label=\"Remove label\"\n                            className=\"flex-shrink-0 h-8 w-8\"\n                            onClick={() => {\n                              const updated = (field.state.value ?? []).filter((_, i) => i !== index)\n                              field.handleChange(updated)\n                            }}\n                          >\n                            <Minus className=\"size-4\" />\n                          </Button>\n                        </div>\n                      ))}\n                      <Button\n                        type=\"button\"\n                        variant=\"outline\"\n                        size=\"sm\"\n                        className=\"w-fit\"\n                        onClick={() => field.handleChange([...(field.state.value ?? []), { key: '', value: '' }])}\n                      >\n                        <Plus className=\"size-4\" />\n                        Add Label\n                      </Button>\n                    </div>\n                    {hasErrors && <FieldError errors={field.state.meta.errors} />}\n                  </Field>\n                )\n              }}\n            </form.Field>\n\n            <div className=\"flex flex-col gap-4\">\n              <Label className=\"text-sm font-medium\">Network</Label>\n              <form.Field name=\"public\">\n                {(field) => (\n                  <div className=\"flex items-start gap-2\">\n                    <Checkbox\n                      id={field.name}\n                      className=\"mt-0.5\"\n                      checked={field.state.value ?? false}\n                      onCheckedChange={(checked) => field.handleChange(checked === true)}\n                    />\n                    <div className=\"flex flex-col gap-1\">\n                      <Label htmlFor={field.name} className=\"text-sm font-normal\">\n                        Public HTTP Preview\n                      </Label>\n                      <FieldDescription>Allow public access to HTTP preview URLs.</FieldDescription>\n                    </div>\n                  </div>\n                )}\n              </form.Field>\n              <form.Field name=\"networkBlockAll\">\n                {(field) => (\n                  <div className=\"flex items-start gap-2\">\n                    <Checkbox\n                      id={field.name}\n                      className=\"mt-0.5\"\n                      checked={field.state.value ?? false}\n                      onCheckedChange={(checked) => field.handleChange(checked === true)}\n                    />\n                    <div className=\"flex flex-col gap-1\">\n                      <Label htmlFor={field.name} className=\"text-sm font-normal\">\n                        Block All Network Access\n                      </Label>\n                      <FieldDescription>Block all outbound network access from the sandbox.</FieldDescription>\n                    </div>\n                  </div>\n                )}\n              </form.Field>\n            </div>\n          </form>\n        </ScrollArea>\n        <SheetFooter className=\"p-5 pt-3 border-t border-border sm:justify-start\">\n          <form.Subscribe\n            selector={(state) => [state.canSubmit, state.isSubmitting]}\n            children={([canSubmit, isSubmitting]) => (\n              <Button\n                type=\"submit\"\n                form=\"create-sandbox-form\"\n                variant=\"default\"\n                disabled={!canSubmit || isSubmitting || !selectedOrganization?.id}\n              >\n                {isSubmitting && <Spinner />}\n                Create\n              </Button>\n            )}\n          />\n        </SheetFooter>\n      </SheetContent>\n    </Sheet>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxDetailsSheet.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport { formatDuration, formatTimestamp, getRelativeTimeString } from '@/lib/utils'\nimport { Sandbox, SandboxState } from '@daytonaio/api-client'\nimport { Archive, Play, Tag, Trash, Wrench, X } from 'lucide-react'\nimport React, { useState } from 'react'\nimport { Link, generatePath } from 'react-router-dom'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { CopyButton } from './CopyButton'\nimport { ResourceChip } from './ResourceChip'\nimport { SandboxState as SandboxStateComponent } from './SandboxTable/SandboxState'\nimport { TimestampTooltip } from './TimestampTooltip'\nimport { LogsTab, TracesTab, MetricsTab } from './telemetry'\nimport { SandboxSpendingTab } from './spending'\nimport { useFeatureFlagEnabled } from 'posthog-js/react'\nimport { FeatureFlags } from '@/enums/FeatureFlags'\nimport { useConfig } from '@/hooks/useConfig'\n\ninterface SandboxDetailsSheetProps {\n  sandbox: Sandbox | null\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  sandboxIsLoading: Record<string, boolean>\n  handleStart: (id: string) => void\n  handleStop: (id: string) => void\n  handleDelete: (id: string) => void\n  handleArchive: (id: string) => void\n  getWebTerminalUrl: (id: string) => Promise<string | null>\n  getRegionName: (regionId: string) => string | undefined\n  writePermitted: boolean\n  deletePermitted: boolean\n  handleRecover: (id: string) => void\n}\n\nconst SandboxDetailsSheet: React.FC<SandboxDetailsSheetProps> = ({\n  sandbox,\n  open,\n  onOpenChange,\n  sandboxIsLoading,\n  handleStart,\n  handleStop,\n  handleDelete,\n  handleArchive,\n  getWebTerminalUrl,\n  getRegionName,\n  writePermitted,\n  deletePermitted,\n  handleRecover,\n}) => {\n  const [terminalUrl, setTerminalUrl] = useState<string | null>(null)\n  const experimentsEnabled = useFeatureFlagEnabled(FeatureFlags.ORGANIZATION_EXPERIMENTS)\n  const spendingEnabled = useFeatureFlagEnabled(FeatureFlags.SANDBOX_SPENDING)\n  const config = useConfig()\n  const spendingTabAvailable = spendingEnabled && !!config.analyticsApiUrl\n\n  // TODO: uncomment when we enable the terminal tab\n  // useEffect(() => {\n  //   const getTerminalUrl = async () => {\n  //     if (!sandbox?.id) {\n  //       setTerminalUrl(null)\n  //       return\n  //     }\n\n  //     const url = await getWebTerminalUrl(sandbox.id)\n  //     setTerminalUrl(url)\n  //   }\n\n  //   getTerminalUrl()\n  // }, [sandbox?.id, getWebTerminalUrl])\n\n  if (!sandbox) return null\n\n  const getLastEvent = (sandbox: Sandbox): { date: Date; relativeTimeString: string } => {\n    return getRelativeTimeString(sandbox.updatedAt)\n  }\n\n  return (\n    <Sheet open={open} onOpenChange={onOpenChange}>\n      <SheetContent className=\"w-dvw sm:w-[800px] p-0 flex flex-col gap-0 [&>button]:hidden\">\n        <SheetHeader className=\"space-y-0 flex flex-row justify-between items-center  p-4 px-5 border-b border-border\">\n          <SheetTitle className=\"text-2xl font-medium\">Sandbox Details</SheetTitle>\n          <div className=\"flex gap-2 items-center\">\n            <Button variant=\"link\" asChild>\n              <Link to={generatePath(RoutePath.SANDBOX_DETAILS, { sandboxId: sandbox.id })}>View</Link>\n            </Button>\n            {writePermitted && (\n              <>\n                {sandbox.state === SandboxState.STARTED && (\n                  <Button\n                    variant=\"outline\"\n                    onClick={() => handleStop(sandbox.id)}\n                    disabled={sandboxIsLoading[sandbox.id]}\n                  >\n                    Stop\n                  </Button>\n                )}\n                {(sandbox.state === SandboxState.STOPPED || sandbox.state === SandboxState.ARCHIVED) &&\n                  !sandbox.recoverable && (\n                    <Button\n                      variant=\"outline\"\n                      onClick={() => handleStart(sandbox.id)}\n                      disabled={sandboxIsLoading[sandbox.id]}\n                    >\n                      <Play className=\"w-4 h-4\" />\n                      Start\n                    </Button>\n                  )}\n                {sandbox.state === SandboxState.ERROR && sandbox.recoverable && (\n                  <Button\n                    variant=\"outline\"\n                    onClick={() => handleRecover(sandbox.id)}\n                    disabled={sandboxIsLoading[sandbox.id]}\n                  >\n                    <Wrench className=\"w-4 h-4\" />\n                    Recover\n                  </Button>\n                )}\n                {/* {(sandbox.state === SandboxState.STOPPED || sandbox.state === SandboxState.ARCHIVED) && (\n                  <Button\n                    variant=\"outline\"\n                    onClick={() => handleFork(sandbox.id)}\n                    disabled={sandboxIsLoading[sandbox.id]}\n                  >\n                    <GitFork className=\"w-4 h-4\" />\n                    Fork\n                  </Button>\n                )}\n                {(sandbox.state === SandboxState.STOPPED || sandbox.state === SandboxState.ARCHIVED) && (\n                  <Button\n                    variant=\"outline\"\n                    onClick={() => handleSnapshot(sandbox.id)}\n                    disabled={sandboxIsLoading[sandbox.id]}\n                  >\n                    <Camera className=\"w-4 h-4\" />\n                    Snapshot\n                  </Button>\n                )} */}\n                {sandbox.state === SandboxState.STOPPED && (\n                  <Button\n                    variant=\"outline\"\n                    className=\"w-8 h-8\"\n                    onClick={() => handleArchive(sandbox.id)}\n                    disabled={sandboxIsLoading[sandbox.id]}\n                  >\n                    <Archive className=\"w-4 h-4\" />\n                  </Button>\n                )}\n              </>\n            )}\n            {deletePermitted && (\n              <Button\n                variant=\"outline\"\n                className=\"w-8 h-8\"\n                onClick={() => handleDelete(sandbox.id)}\n                disabled={sandboxIsLoading[sandbox.id]}\n              >\n                <Trash className=\"w-4 h-4\" />\n              </Button>\n            )}\n            <Button\n              variant=\"outline\"\n              className=\"w-8 h-8\"\n              onClick={() => onOpenChange(false)}\n              disabled={sandboxIsLoading[sandbox.id]}\n            >\n              <X className=\"w-4 h-4\" />\n            </Button>\n          </div>\n        </SheetHeader>\n\n        <Tabs defaultValue=\"overview\" className=\"flex-1 flex flex-col min-h-0\">\n          {experimentsEnabled && (\n            <TabsList className=\"mx-4 w-fit flex-shrink-0 bg-transparent border-b border-border rounded-none h-auto p-0 gap-0 mt-2\">\n              <TabsTrigger\n                value=\"overview\"\n                className=\"rounded-none border-b-2 border-transparent data-[state=active]:border-foreground data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2\"\n              >\n                Overview\n              </TabsTrigger>\n              <TabsTrigger\n                value=\"logs\"\n                className=\"rounded-none border-b-2 border-transparent data-[state=active]:border-foreground data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2\"\n              >\n                Logs\n              </TabsTrigger>\n              <TabsTrigger\n                value=\"traces\"\n                className=\"rounded-none border-b-2 border-transparent data-[state=active]:border-foreground data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2\"\n              >\n                Traces\n              </TabsTrigger>\n              <TabsTrigger\n                value=\"metrics\"\n                className=\"rounded-none border-b-2 border-transparent data-[state=active]:border-foreground data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2\"\n              >\n                Metrics\n              </TabsTrigger>\n              {spendingTabAvailable && (\n                <TabsTrigger\n                  value=\"spending\"\n                  className=\"rounded-none border-b-2 border-transparent data-[state=active]:border-foreground data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 py-2\"\n                >\n                  Spending\n                </TabsTrigger>\n              )}\n            </TabsList>\n          )}\n\n          <TabsContent value=\"overview\" className=\"flex-1 p-6 space-y-10 overflow-y-auto min-h-0\">\n            <div className=\"grid grid-cols-2 gap-6\">\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Name</h3>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{sandbox.name}</p>\n                  <CopyButton value={sandbox.name} tooltipText=\"Copy name\" size=\"icon-xs\" />\n                </div>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">UUID</h3>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{sandbox.id}</p>\n                  <CopyButton value={sandbox.id} tooltipText=\"Copy UUID\" size=\"icon-xs\" />\n                </div>\n              </div>\n            </div>\n\n            <div className=\"grid grid-cols-1 md:grid-cols-4 gap-6\">\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">State</h3>\n                <div className=\"mt-1 text-sm\">\n                  <SandboxStateComponent\n                    state={sandbox.state}\n                    errorReason={sandbox.errorReason}\n                    recoverable={sandbox.recoverable}\n                  />\n                </div>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Snapshot</h3>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{sandbox.snapshot || '-'}</p>\n                  {sandbox.snapshot && (\n                    <CopyButton value={sandbox.snapshot} tooltipText=\"Copy snapshot\" size=\"icon-xs\" />\n                  )}\n                </div>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Region</h3>\n                <div className=\"mt-1 flex items-center gap-2\">\n                  <p className=\"text-sm font-medium truncate\">{getRegionName(sandbox.target) ?? sandbox.target}</p>\n                  <CopyButton value={sandbox.target} tooltipText=\"Copy region\" size=\"icon-xs\" />\n                </div>\n              </div>\n            </div>\n            <div className=\"grid grid-cols-1 md:grid-cols-4 gap-6\">\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Last event</h3>\n                <p className=\"mt-1 text-sm font-medium\">\n                  <TimestampTooltip timestamp={sandbox.updatedAt}>\n                    {getLastEvent(sandbox).relativeTimeString}\n                  </TimestampTooltip>\n                </p>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Created at</h3>\n                <p className=\"mt-1 text-sm font-medium\">\n                  <TimestampTooltip timestamp={sandbox.createdAt}>\n                    {formatTimestamp(sandbox.createdAt)}\n                  </TimestampTooltip>\n                </p>\n              </div>\n            </div>\n\n            <div className=\"grid grid-cols-1 md:grid-cols-4 gap-6\">\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Auto-stop</h3>\n                <p className=\"mt-1 text-sm font-medium\">\n                  {sandbox.autoStopInterval ? formatDuration(sandbox.autoStopInterval) : 'Disabled'}\n                </p>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Auto-archive</h3>\n                <p className=\"mt-1 text-sm font-medium\">\n                  {sandbox.autoArchiveInterval ? formatDuration(sandbox.autoArchiveInterval) : 'Disabled'}\n                </p>\n              </div>\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Auto-delete</h3>\n                <p className=\"mt-1 text-sm font-medium\">\n                  {sandbox.autoDeleteInterval !== undefined && sandbox.autoDeleteInterval >= 0\n                    ? sandbox.autoDeleteInterval === 0\n                      ? 'On stop'\n                      : formatDuration(sandbox.autoDeleteInterval)\n                    : 'Disabled'}\n                </p>\n              </div>\n            </div>\n\n            <div className=\"grid grid-cols-1\">\n              <div>\n                <h3 className=\"text-sm text-muted-foreground\">Resources</h3>\n                <div className=\"mt-1 text-sm font-medium flex items-center gap-1 flex-wrap\">\n                  <ResourceChip resource=\"cpu\" value={sandbox.cpu} />\n                  <ResourceChip resource=\"memory\" value={sandbox.memory} />\n                  <ResourceChip resource=\"disk\" value={sandbox.disk} />\n                </div>\n              </div>\n            </div>\n            <div>\n              <h3 className=\"text-lg font-medium\">Labels</h3>\n              <div className=\"mt-3 space-y-4\">\n                {Object.entries(sandbox.labels ?? {}).length > 0 ? (\n                  Object.entries(sandbox.labels ?? {}).map(([key, value]) => (\n                    <div key={key} className=\"text-sm\">\n                      <div>{key}</div>\n                      <div className=\"font-medium p-2 bg-muted rounded-md mt-1 border border-border\">{value}</div>\n                    </div>\n                  ))\n                ) : (\n                  <div className=\"flex flex-col border border-border rounded-md items-center justify-center gap-2 text-muted-foreground w-full min-h-40\">\n                    <Tag className=\"w-4 h-4\" />\n                    <span className=\"text-sm\">No labels found</span>\n                  </div>\n                )}\n              </div>\n            </div>\n          </TabsContent>\n\n          <TabsContent value=\"terminal\" className=\"p-4\">\n            <iframe title=\"Terminal\" src={terminalUrl || undefined} className=\"w-full h-full\"></iframe>\n          </TabsContent>\n\n          <TabsContent value=\"logs\" className=\"flex-1 min-h-0 overflow-hidden\">\n            <LogsTab sandboxId={sandbox.id} />\n          </TabsContent>\n\n          <TabsContent value=\"traces\" className=\"flex-1 min-h-0 overflow-hidden\">\n            <TracesTab sandboxId={sandbox.id} />\n          </TabsContent>\n\n          <TabsContent value=\"metrics\" className=\"flex-1 min-h-0 overflow-hidden\">\n            <MetricsTab sandboxId={sandbox.id} />\n          </TabsContent>\n\n          {spendingTabAvailable && (\n            <TabsContent value=\"spending\" className=\"flex-1 min-h-0 overflow-hidden\">\n              <SandboxSpendingTab sandboxId={sandbox.id} />\n            </TabsContent>\n          )}\n        </Tabs>\n      </SheetContent>\n    </Sheet>\n  )\n}\n\nexport default SandboxDetailsSheet\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/BulkActionAlertDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from '../ui/alert-dialog'\n\nexport enum BulkAction {\n  Delete = 'delete',\n  Start = 'start',\n  Stop = 'stop',\n  Archive = 'archive',\n}\n\ninterface BulkActionData {\n  title: string\n  description: string\n  buttonLabel: string\n  buttonVariant?: 'destructive'\n}\n\nfunction getBulkActionData(action: BulkAction, count: number): BulkActionData {\n  const countText = count === 1 ? 'this sandbox' : `these ${count} selected sandboxes`\n\n  switch (action) {\n    case BulkAction.Delete:\n      return {\n        title: 'Delete Sandboxes',\n        description: `Are you sure you want to delete ${countText}? This action cannot be undone.`,\n        buttonLabel: 'Delete',\n        buttonVariant: 'destructive',\n      }\n    case BulkAction.Start:\n      return {\n        title: 'Start Sandboxes',\n        description: `Are you sure you want to start ${countText}?`,\n        buttonLabel: 'Start',\n      }\n    case BulkAction.Stop:\n      return {\n        title: 'Stop Sandboxes',\n        description: `Are you sure you want to stop ${countText}?`,\n        buttonLabel: 'Stop',\n      }\n    case BulkAction.Archive:\n      return {\n        title: 'Archive Sandboxes',\n        description: `Are you sure you want to archive ${countText}? Archived sandboxes can be restored later.`,\n        buttonLabel: 'Archive',\n      }\n  }\n}\n\ninterface BulkActionAlertDialogProps {\n  action: BulkAction | null\n  count: number\n  onConfirm: () => void\n  onCancel: () => void\n}\n\nexport function BulkActionAlertDialog({ action, count, onConfirm, onCancel }: BulkActionAlertDialogProps) {\n  const data = action ? getBulkActionData(action, count) : null\n\n  if (!data) return null\n\n  return (\n    <AlertDialog open={action !== null} onOpenChange={(open) => !open && onCancel()}>\n      <AlertDialogContent>\n        <>\n          <AlertDialogHeader>\n            <AlertDialogTitle>{data.title}</AlertDialogTitle>\n            <AlertDialogDescription>{data.description}</AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <AlertDialogAction onClick={onConfirm} variant={data.buttonVariant}>\n              {data.buttonLabel}\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </>\n      </AlertDialogContent>\n    </AlertDialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/SandboxState.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SandboxState as SandboxStateType } from '@daytonaio/api-client'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip'\nimport { getStateLabel } from './constants'\nimport { STATE_ICONS } from './state-icons'\n\ninterface SandboxStateProps {\n  state?: SandboxStateType\n  errorReason?: string\n  recoverable?: boolean\n}\n\nexport function SandboxState({ state, errorReason, recoverable }: SandboxStateProps) {\n  if (!state) return null\n  const stateIcon = recoverable ? STATE_ICONS['RECOVERY'] : STATE_ICONS[state] || STATE_ICONS[SandboxStateType.UNKNOWN]\n  const label = getStateLabel(state)\n\n  if (state === SandboxStateType.ERROR || state === SandboxStateType.BUILD_FAILED) {\n    const errorColor = recoverable ? 'text-yellow-600 dark:text-yellow-400' : 'text-red-600 dark:text-red-400'\n\n    const errorContent = (\n      <div className={`flex items-center gap-1 ${errorColor}`}>\n        <div className=\"w-4 h-4 flex items-center justify-center flex-shrink-0\">{stateIcon}</div>\n        <span className=\"truncate\">{label}</span>\n      </div>\n    )\n\n    if (!errorReason) {\n      return errorContent\n    }\n\n    return (\n      <Tooltip delayDuration={100}>\n        <TooltipTrigger asChild>{errorContent}</TooltipTrigger>\n        <TooltipContent>\n          <p className=\"max-w-[300px]\">{errorReason}</p>\n        </TooltipContent>\n      </Tooltip>\n    )\n  }\n\n  return (\n    <div className={`flex items-center gap-1 ${state === SandboxStateType.ARCHIVED ? 'text-muted-foreground' : ''}`}>\n      <div className=\"w-4 h-4 flex items-center justify-center flex-shrink-0\">{stateIcon}</div>\n      <span className=\"truncate\">{label}</span>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/SandboxTableActions.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { RoutePath } from '@/enums/RoutePath'\nimport { SandboxState } from '@daytonaio/api-client'\nimport { Terminal, MoreVertical, Play, Square, Loader2, Wrench } from 'lucide-react'\nimport { generatePath, useNavigate } from 'react-router-dom'\nimport { Button } from '../ui/button'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '../ui/dropdown-menu'\nimport { SandboxTableActionsProps } from './types'\nimport { useMemo } from 'react'\n\nexport function SandboxTableActions({\n  sandbox,\n  writePermitted,\n  deletePermitted,\n  isLoading,\n  onStart,\n  onStop,\n  onDelete,\n  onArchive,\n  onVnc,\n  onOpenWebTerminal,\n  onCreateSshAccess,\n  onRevokeSshAccess,\n  onRecover,\n  onScreenRecordings,\n}: SandboxTableActionsProps) {\n  const navigate = useNavigate()\n\n  const menuItems = useMemo(() => {\n    const items = []\n\n    items.push({\n      key: 'open',\n      label: 'Open',\n      onClick: () => navigate(generatePath(RoutePath.SANDBOX_DETAILS, { sandboxId: sandbox.id })),\n      disabled: isLoading,\n    })\n\n    if (writePermitted) {\n      if (sandbox.state === SandboxState.STARTED) {\n        items.push({\n          key: 'vnc',\n          label: 'VNC',\n          onClick: () => onVnc(sandbox.id),\n          disabled: isLoading,\n        })\n        items.push({\n          key: 'screen-recordings',\n          label: 'Screen Recordings',\n          onClick: () => onScreenRecordings(sandbox.id),\n          disabled: isLoading,\n        })\n        items.push({\n          key: 'stop',\n          label: 'Stop',\n          onClick: () => onStop(sandbox.id),\n          disabled: isLoading,\n        })\n      } else if (sandbox.state === SandboxState.STOPPED || sandbox.state === SandboxState.ARCHIVED) {\n        items.push({\n          key: 'start',\n          label: 'Start',\n          onClick: () => onStart(sandbox.id),\n          disabled: isLoading,\n        })\n      } else if (sandbox.state === SandboxState.ERROR && sandbox.recoverable) {\n        items.push({\n          key: 'recover',\n          label: 'Recover',\n          onClick: () => onRecover(sandbox.id),\n          disabled: isLoading,\n        })\n      }\n\n      if (sandbox.state === SandboxState.STOPPED) {\n        items.push({\n          key: 'archive',\n          label: 'Archive',\n          onClick: () => onArchive(sandbox.id),\n          disabled: isLoading,\n        })\n      }\n\n      // Add SSH access options\n      items.push({\n        key: 'create-ssh',\n        label: 'Create SSH Access',\n        onClick: () => onCreateSshAccess(sandbox.id),\n        disabled: isLoading,\n      })\n      items.push({\n        key: 'revoke-ssh',\n        label: 'Revoke SSH Access',\n        onClick: () => onRevokeSshAccess(sandbox.id),\n        disabled: isLoading,\n      })\n    }\n\n    if (deletePermitted) {\n      if (items.length > 0 && (sandbox.state === SandboxState.STOPPED || sandbox.state === SandboxState.STARTED)) {\n        items.push({ key: 'separator', type: 'separator' })\n      }\n\n      items.push({\n        key: 'delete',\n        label: 'Delete',\n        onClick: () => onDelete(sandbox.id),\n        disabled: isLoading,\n        className: 'text-red-600 dark:text-red-400',\n      })\n    }\n\n    return items\n  }, [\n    writePermitted,\n    deletePermitted,\n    sandbox.state,\n    sandbox.id,\n    isLoading,\n    sandbox.recoverable,\n    onStart,\n    onStop,\n    onDelete,\n    onArchive,\n    onVnc,\n    onCreateSshAccess,\n    onRevokeSshAccess,\n    onRecover,\n    onScreenRecordings,\n    navigate,\n  ])\n\n  if (!writePermitted && !deletePermitted) {\n    return null\n  }\n\n  return (\n    <div className=\"flex items-center justify-end gap-2\">\n      <Button\n        variant=\"outline\"\n        className=\"h-7 w-7 p-0 text-muted-foreground\"\n        onClick={(e) => {\n          e.stopPropagation()\n          if (sandbox.state === SandboxState.STARTED) {\n            onStop(sandbox.id)\n          } else if (sandbox.state === SandboxState.ERROR && sandbox.recoverable) {\n            onRecover(sandbox.id)\n          } else {\n            onStart(sandbox.id)\n          }\n        }}\n      >\n        {sandbox.state === SandboxState.STARTED ? (\n          <Square className=\"w-4 h-4\" />\n        ) : sandbox.state === SandboxState.STOPPING || sandbox.state === SandboxState.STARTING ? (\n          <Loader2 className=\"w-4 h-4 animate-spin\" />\n        ) : sandbox.state === SandboxState.ERROR && sandbox.recoverable ? (\n          <Wrench className=\"w-4 h-4\" />\n        ) : (\n          <Play className=\"w-4 h-4\" />\n        )}\n      </Button>\n\n      {sandbox.state === SandboxState.STARTED ? (\n        <Button\n          variant=\"outline\"\n          className=\"h-7 w-7 p-0 text-muted-foreground\"\n          onClick={() => onOpenWebTerminal(sandbox.id)}\n        >\n          <Terminal className=\"w-4 h-4\" />\n        </Button>\n      ) : (\n        <Button variant=\"outline\" className=\"h-7 w-7 p-0 text-muted-foreground\" disabled>\n          <Terminal className=\"w-4 h-4\" />\n        </Button>\n      )}\n\n      <DropdownMenu>\n        <DropdownMenuTrigger asChild>\n          <Button variant=\"outline\" className=\"h-7 w-7 p-0 text-muted-foreground\">\n            <span className=\"sr-only\">Open menu</span>\n            <MoreVertical />\n          </Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent align=\"end\">\n          {menuItems.map((item) => {\n            if (item.type === 'separator') {\n              return <DropdownMenuSeparator key={item.key} />\n            }\n\n            return (\n              <DropdownMenuItem\n                key={item.key}\n                onClick={(e) => {\n                  e.stopPropagation()\n                  item.onClick?.()\n                }}\n                className={`cursor-pointer ${item.className || ''}`}\n                disabled={item.disabled}\n              >\n                {item.label}\n              </DropdownMenuItem>\n            )\n          })}\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/SandboxTableHeader.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport {\n  ArrowUpDown,\n  Calendar,\n  Camera,\n  Check,\n  Columns,\n  Cpu,\n  Globe,\n  HardDrive,\n  ListFilter,\n  MemoryStick,\n  RefreshCw,\n  Square,\n  Tag,\n} from 'lucide-react'\nimport * as React from 'react'\nimport { DebouncedInput } from '../DebouncedInput'\nimport { TableColumnVisibilityToggle } from '../TableColumnVisibilityToggle'\nimport { Button } from '../ui/button'\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandInputButton,\n  CommandItem,\n  CommandList,\n} from '../ui/command'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuPortal,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n} from '../ui/dropdown-menu'\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'\nimport { LabelFilter, LabelFilterIndicator } from './filters/LabelFilter'\nimport { LastEventFilter, LastEventFilterIndicator } from './filters/LastEventFilter'\nimport { RegionFilter, RegionFilterIndicator } from './filters/RegionFilter'\nimport { ResourceFilter, ResourceFilterIndicator, ResourceFilterValue } from './filters/ResourceFilter'\nimport { SnapshotFilter, SnapshotFilterIndicator } from './filters/SnapshotFilter'\nimport { StateFilter, StateFilterIndicator } from './filters/StateFilter'\nimport { SandboxTableHeaderProps } from './types'\n\nconst RESOURCE_FILTERS = [\n  { type: 'cpu' as const, label: 'CPU', icon: Cpu },\n  { type: 'memory' as const, label: 'Memory', icon: MemoryStick },\n  { type: 'disk' as const, label: 'Disk', icon: HardDrive },\n]\n\nexport function SandboxTableHeader({\n  table,\n  regionOptions,\n  regionsDataIsLoading,\n  snapshots,\n  snapshotsDataIsLoading,\n  snapshotsDataHasMore,\n  onChangeSnapshotSearchValue,\n  onRefresh,\n  isRefreshing = false,\n}: SandboxTableHeaderProps) {\n  const [open, setOpen] = React.useState(false)\n  const currentSort = table.getState().sorting[0]?.id || ''\n\n  const sortableColumns = [\n    { id: 'name', label: 'Name' },\n    { id: 'state', label: 'State' },\n    { id: 'snapshot', label: 'Snapshot' },\n    { id: 'region', label: 'Region' },\n    { id: 'lastEvent', label: 'Last Event' },\n  ]\n\n  return (\n    <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n      <div className=\"flex flex-wrap gap-2 items-center\">\n        <DebouncedInput\n          value={(table.getColumn('name')?.getFilterValue() as string) ?? ''}\n          onChange={(value) => table.getColumn('name')?.setFilterValue(value)}\n          placeholder=\"Search by Name or UUID\"\n          className=\"w-[240px]\"\n        />\n\n        <Button variant=\"outline\" onClick={onRefresh} disabled={isRefreshing} className=\"flex items-center gap-2\">\n          <RefreshCw className={`w-4 h-4 ${isRefreshing ? 'animate-spin' : ''}`} />\n          Refresh\n        </Button>\n\n        <DropdownMenu modal={false}>\n          <DropdownMenuTrigger asChild>\n            <Button variant=\"outline\">\n              <Columns className=\"w-4 h-4\" />\n              View\n            </Button>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent align=\"end\" className=\"w-[200px] p-0\">\n            <TableColumnVisibilityToggle\n              columns={table.getAllColumns().filter((column) => ['name', 'id', 'labels'].includes(column.id))}\n              getColumnLabel={(id: string) => {\n                switch (id) {\n                  case 'name':\n                    return 'Name'\n                  case 'id':\n                    return 'UUID'\n                  case 'labels':\n                    return 'Labels'\n                  default:\n                    return id\n                }\n              }}\n            />\n          </DropdownMenuContent>\n        </DropdownMenu>\n\n        <Popover open={open} onOpenChange={setOpen}>\n          <PopoverTrigger asChild>\n            <Button variant=\"outline\" role=\"combobox\" aria-expanded={open} className=\"justify-between\">\n              {currentSort ? (\n                <div className=\"flex items-center gap-2\">\n                  <div className=\"text-muted-foreground font-normal\">\n                    Sorted by:{' '}\n                    <span className=\"font-medium text-primary\">\n                      {sortableColumns.find((column) => column.id === currentSort)?.label}\n                    </span>\n                  </div>\n                </div>\n              ) : (\n                <div className=\"flex items-center gap-2\">\n                  <ArrowUpDown className=\"w-4 h-4\" />\n                  <span>Sort</span>\n                </div>\n              )}\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent className=\"w-[240px] p-0\" align=\"start\">\n            <Command>\n              <CommandInput placeholder=\"Search...\">\n                <CommandInputButton\n                  aria-expanded={open}\n                  className=\"justify-between\"\n                  onClick={() => {\n                    table.resetSorting()\n                    setOpen(false)\n                  }}\n                >\n                  Reset\n                </CommandInputButton>\n              </CommandInput>\n              <CommandList>\n                <CommandEmpty>No column found.</CommandEmpty>\n                <CommandGroup>\n                  {sortableColumns.map((column) => (\n                    <CommandItem\n                      key={column.id}\n                      value={column.id}\n                      onSelect={(currentValue) => {\n                        const col = table.getColumn(currentValue)\n                        if (col) {\n                          col.toggleSorting(false)\n                        }\n                        setOpen(false)\n                      }}\n                    >\n                      <Check className={cn('mr-2 h-4 w-4', currentSort === column.id ? 'opacity-100' : 'opacity-0')} />\n                      {column.label}\n                    </CommandItem>\n                  ))}\n                </CommandGroup>\n              </CommandList>\n            </Command>\n          </PopoverContent>\n        </Popover>\n\n        <DropdownMenu modal={false}>\n          <DropdownMenuTrigger asChild>\n            <Button variant=\"outline\">\n              <ListFilter className=\"w-4 h-4\" />\n              Filter\n            </Button>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent className=\" w-40\" align=\"start\">\n            <DropdownMenuSub>\n              <DropdownMenuSubTrigger>\n                <Square className=\"w-4 h-4\" />\n                State\n              </DropdownMenuSubTrigger>\n              <DropdownMenuPortal>\n                <DropdownMenuSubContent className=\"p-0 w-64\">\n                  <StateFilter\n                    value={(table.getColumn('state')?.getFilterValue() as string[]) || []}\n                    onFilterChange={(value) => table.getColumn('state')?.setFilterValue(value)}\n                  />\n                </DropdownMenuSubContent>\n              </DropdownMenuPortal>\n            </DropdownMenuSub>\n            <DropdownMenuSub>\n              <DropdownMenuSubTrigger>\n                <Camera className=\"w-4 h-4\" />\n                Snapshot\n              </DropdownMenuSubTrigger>\n              <DropdownMenuPortal>\n                <DropdownMenuSubContent className=\"p-0 w-64\">\n                  <SnapshotFilter\n                    value={(table.getColumn('snapshot')?.getFilterValue() as string[]) || []}\n                    onFilterChange={(value) => table.getColumn('snapshot')?.setFilterValue(value)}\n                    snapshots={snapshots}\n                    isLoading={snapshotsDataIsLoading}\n                    hasMore={snapshotsDataHasMore}\n                    onChangeSnapshotSearchValue={onChangeSnapshotSearchValue}\n                  />\n                </DropdownMenuSubContent>\n              </DropdownMenuPortal>\n            </DropdownMenuSub>\n            <DropdownMenuSub>\n              <DropdownMenuSubTrigger>\n                <Globe className=\"w-4 h-4\" />\n                Region\n              </DropdownMenuSubTrigger>\n              <DropdownMenuPortal>\n                <DropdownMenuSubContent className=\"p-0 w-64\">\n                  <RegionFilter\n                    value={(table.getColumn('region')?.getFilterValue() as string[]) || []}\n                    onFilterChange={(value) => table.getColumn('region')?.setFilterValue(value)}\n                    options={regionOptions}\n                    isLoading={regionsDataIsLoading}\n                  />\n                </DropdownMenuSubContent>\n              </DropdownMenuPortal>\n            </DropdownMenuSub>\n            {RESOURCE_FILTERS.map(({ type, label, icon: Icon }) => (\n              <DropdownMenuSub key={type}>\n                <DropdownMenuSubTrigger>\n                  <Icon className=\"w-4 h-4\" />\n                  {label}\n                </DropdownMenuSubTrigger>\n                <DropdownMenuPortal>\n                  <DropdownMenuSubContent className=\"p-3 w-64\">\n                    <ResourceFilter\n                      value={(table.getColumn('resources')?.getFilterValue() as ResourceFilterValue) || {}}\n                      onFilterChange={(value) => table.getColumn('resources')?.setFilterValue(value)}\n                      resourceType={type}\n                    />\n                  </DropdownMenuSubContent>\n                </DropdownMenuPortal>\n              </DropdownMenuSub>\n            ))}\n            <DropdownMenuSub>\n              <DropdownMenuSubTrigger>\n                <Tag className=\"w-4 h-4\" />\n                Labels\n              </DropdownMenuSubTrigger>\n              <DropdownMenuPortal>\n                <DropdownMenuSubContent className=\"p-0 w-64\">\n                  <LabelFilter\n                    value={(table.getColumn('labels')?.getFilterValue() as string[]) || []}\n                    onFilterChange={(value) => table.getColumn('labels')?.setFilterValue(value)}\n                  />\n                </DropdownMenuSubContent>\n              </DropdownMenuPortal>\n            </DropdownMenuSub>\n            <DropdownMenuSub>\n              <DropdownMenuSubTrigger>\n                <Calendar className=\"w-4 h-4\" />\n                Last Event\n              </DropdownMenuSubTrigger>\n              <DropdownMenuPortal>\n                <DropdownMenuSubContent className=\"p-3 w-92\">\n                  <LastEventFilter\n                    onFilterChange={(value) => table.getColumn('lastEvent')?.setFilterValue(value)}\n                    value={(table.getColumn('lastEvent')?.getFilterValue() as Date[]) || []}\n                  />\n                </DropdownMenuSubContent>\n              </DropdownMenuPortal>\n            </DropdownMenuSub>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      </div>\n\n      <div className=\"flex flex-1 gap-1 overflow-x-auto scrollbar-hide h-8 items-center\">\n        {(table.getColumn('state')?.getFilterValue() as string[])?.length > 0 && (\n          <StateFilterIndicator\n            value={(table.getColumn('state')?.getFilterValue() as string[]) || []}\n            onFilterChange={(value) => table.getColumn('state')?.setFilterValue(value)}\n          />\n        )}\n\n        {(table.getColumn('snapshot')?.getFilterValue() as string[])?.length > 0 && (\n          <SnapshotFilterIndicator\n            value={(table.getColumn('snapshot')?.getFilterValue() as string[]) || []}\n            onFilterChange={(value) => table.getColumn('snapshot')?.setFilterValue(value)}\n            snapshots={snapshots}\n            isLoading={snapshotsDataIsLoading}\n            hasMore={snapshotsDataHasMore}\n            onChangeSnapshotSearchValue={onChangeSnapshotSearchValue}\n          />\n        )}\n\n        {(table.getColumn('region')?.getFilterValue() as string[])?.length > 0 && (\n          <RegionFilterIndicator\n            value={(table.getColumn('region')?.getFilterValue() as string[]) || []}\n            onFilterChange={(value) => table.getColumn('region')?.setFilterValue(value)}\n            options={regionOptions}\n            isLoading={regionsDataIsLoading}\n          />\n        )}\n\n        {RESOURCE_FILTERS.map(({ type }) => {\n          const resourceValue = (table.getColumn('resources')?.getFilterValue() as ResourceFilterValue)?.[type]\n          return resourceValue ? (\n            <ResourceFilterIndicator\n              key={type}\n              value={table.getColumn('resources')?.getFilterValue() as ResourceFilterValue}\n              onFilterChange={(value) => table.getColumn('resources')?.setFilterValue(value)}\n              resourceType={type}\n            />\n          ) : null\n        })}\n\n        {(table.getColumn('labels')?.getFilterValue() as string[])?.length > 0 && (\n          <LabelFilterIndicator\n            value={(table.getColumn('labels')?.getFilterValue() as string[]) || []}\n            onFilterChange={(value) => table.getColumn('labels')?.setFilterValue(value)}\n          />\n        )}\n\n        {(table.getColumn('lastEvent')?.getFilterValue() as Date[])?.length > 0 && (\n          <LastEventFilterIndicator\n            value={(table.getColumn('lastEvent')?.getFilterValue() as Date[]) || []}\n            onFilterChange={(value) => table.getColumn('lastEvent')?.setFilterValue(value)}\n          />\n        )}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/columns.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { formatTimestamp, getRelativeTimeString } from '@/lib/utils'\nimport { Sandbox, SandboxDesiredState, SandboxState } from '@daytonaio/api-client'\nimport { ColumnDef } from '@tanstack/react-table'\nimport { ArrowDown, ArrowUp } from 'lucide-react'\nimport React from 'react'\nimport { EllipsisWithTooltip } from '../EllipsisWithTooltip'\nimport { Checkbox } from '../ui/checkbox'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip'\nimport { SandboxState as SandboxStateComponent } from './SandboxState'\nimport { SandboxTableActions } from './SandboxTableActions'\n\ninterface SortableHeaderProps {\n  column: any\n  label: string\n  dataState?: string\n}\n\nconst SortableHeader: React.FC<SortableHeaderProps> = ({ column, label, dataState }) => {\n  return (\n    <div\n      role=\"button\"\n      onClick={() => column.toggleSorting(column.getIsSorted() === 'asc')}\n      className=\"flex items-center\"\n      {...(dataState && { 'data-state': dataState })}\n    >\n      {label}\n      {column.getIsSorted() === 'asc' ? (\n        <ArrowUp className=\"ml-2 h-4 w-4\" />\n      ) : column.getIsSorted() === 'desc' ? (\n        <ArrowDown className=\"ml-2 h-4 w-4\" />\n      ) : (\n        <div className=\"ml-2 w-4 h-4\" />\n      )}\n    </div>\n  )\n}\n\ninterface GetColumnsProps {\n  handleStart: (id: string) => void\n  handleStop: (id: string) => void\n  handleDelete: (id: string) => void\n  handleArchive: (id: string) => void\n  handleVnc: (id: string) => void\n  getWebTerminalUrl: (id: string) => Promise<string | null>\n  sandboxIsLoading: Record<string, boolean>\n  writePermitted: boolean\n  deletePermitted: boolean\n  handleCreateSshAccess: (id: string) => void\n  handleRevokeSshAccess: (id: string) => void\n  handleRecover: (id: string) => void\n  getRegionName: (regionId: string) => string | undefined\n  handleScreenRecordings: (id: string) => void\n}\n\nexport function getColumns({\n  handleStart,\n  handleStop,\n  handleDelete,\n  handleArchive,\n  handleVnc,\n  getWebTerminalUrl,\n  sandboxIsLoading,\n  writePermitted,\n  deletePermitted,\n  handleCreateSshAccess,\n  handleRevokeSshAccess,\n  handleRecover,\n  getRegionName,\n  handleScreenRecordings,\n}: GetColumnsProps): ColumnDef<Sandbox>[] {\n  const handleOpenWebTerminal = async (sandboxId: string) => {\n    const url = await getWebTerminalUrl(sandboxId)\n    if (url) {\n      window.open(url, '_blank')\n    }\n  }\n\n  const columns: ColumnDef<Sandbox>[] = [\n    {\n      id: 'select',\n      size: 30,\n      header: ({ table }) => (\n        <Checkbox\n          checked={\n            table.getIsAllPageRowsSelected() ? true : table.getIsSomePageRowsSelected() ? 'indeterminate' : false\n          }\n          onCheckedChange={(value) => {\n            for (const row of table.getRowModel().rows) {\n              if (sandboxIsLoading[row.original.id] || row.original.state === SandboxState.DESTROYED) {\n                row.toggleSelected(false)\n              } else {\n                row.toggleSelected(!!value)\n              }\n            }\n          }}\n          aria-label=\"Select all\"\n          className=\"translate-y-[2px]\"\n        />\n      ),\n      cell: ({ row }) => {\n        return (\n          <div>\n            <Checkbox\n              checked={row.getIsSelected()}\n              onCheckedChange={(value) => row.toggleSelected(!!value)}\n              aria-label=\"Select row\"\n              onClick={(e) => e.stopPropagation()}\n              className=\"translate-y-[1px]\"\n            />\n          </div>\n        )\n      },\n\n      enableSorting: false,\n      enableHiding: false,\n    },\n    {\n      id: 'name',\n      size: 320,\n      enableSorting: true,\n      enableHiding: true,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Name\" />\n      },\n      accessorKey: 'name',\n      cell: ({ row }) => {\n        const displayName = getDisplayName(row.original)\n        return (\n          <div className=\"w-full truncate\">\n            <span className=\"truncate block\">{displayName}</span>\n          </div>\n        )\n      },\n    },\n    {\n      id: 'id',\n      size: 320,\n      enableSorting: false,\n      enableHiding: true,\n      header: () => {\n        return <span>UUID</span>\n      },\n      accessorKey: 'id',\n      cell: ({ row }) => {\n        return (\n          <div className=\"w-full truncate\">\n            <span className=\"truncate block\">{row.original.id}</span>\n          </div>\n        )\n      },\n    },\n    {\n      id: 'state',\n      size: 140,\n      enableSorting: true,\n      enableHiding: false,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"State\" />\n      },\n      cell: ({ row }) => (\n        <div className=\"w-full truncate\">\n          <SandboxStateComponent\n            state={row.original.state}\n            errorReason={row.original.errorReason}\n            recoverable={row.original.recoverable}\n          />\n        </div>\n      ),\n      accessorKey: 'state',\n    },\n    {\n      id: 'snapshot',\n      size: 150,\n      enableSorting: true,\n      enableHiding: false,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Snapshot\" />\n      },\n      cell: ({ row }) => {\n        return (\n          <div className=\"w-full truncate\">\n            {row.original.snapshot ? (\n              <EllipsisWithTooltip>{row.original.snapshot}</EllipsisWithTooltip>\n            ) : (\n              <div className=\"truncate text-muted-foreground/50\">-</div>\n            )}\n          </div>\n        )\n      },\n      accessorKey: 'snapshot',\n    },\n    {\n      id: 'region',\n      size: 100,\n      enableSorting: true,\n      enableHiding: false,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Region\" dataState=\"sortable\" />\n      },\n      cell: ({ row }) => {\n        return (\n          <div className=\"w-full truncate\">\n            <span className=\"truncate block\">{getRegionName(row.original.target) ?? row.original.target}</span>\n          </div>\n        )\n      },\n      accessorKey: 'target',\n    },\n    {\n      id: 'resources',\n      size: 190,\n      enableSorting: false,\n      enableHiding: false,\n      header: () => {\n        return <span>Resources</span>\n      },\n      cell: ({ row }) => {\n        return (\n          <div className=\"flex items-center gap-2 w-full truncate\">\n            <div className=\"whitespace-nowrap\">\n              {row.original.cpu} <span className=\"text-muted-foreground\">vCPU</span>\n            </div>\n            <div className=\"w-[1px] h-6 bg-muted-foreground/20 rounded-full inline-block\"></div>\n            <div className=\"whitespace-nowrap\">\n              {row.original.memory} <span className=\"text-muted-foreground\">GiB</span>\n            </div>\n            <div className=\"w-[1px] h-6 bg-muted-foreground/20 rounded-full inline-block\"></div>\n            <div className=\"whitespace-nowrap\">\n              {row.original.disk} <span className=\"text-muted-foreground\">GiB</span>\n            </div>\n          </div>\n        )\n      },\n    },\n    {\n      id: 'labels',\n      size: 110,\n      enableSorting: false,\n      enableHiding: true,\n      header: () => {\n        return <span>Labels</span>\n      },\n      cell: ({ row }) => {\n        const labels = Object.entries(row.original.labels ?? {})\n          .map(([key, value]) => `${key}: ${value}`)\n          .join(', ')\n\n        const labelCount = Object.keys(row.original.labels ?? {}).length\n        return (\n          <Tooltip>\n            <TooltipTrigger asChild>\n              {labelCount > 0 ? (\n                <div className=\"truncate w-fit bg-blue-100 rounded-sm text-blue-800 dark:bg-blue-950 dark:text-blue-200 px-1\">\n                  {labelCount > 0 ? (labelCount === 1 ? '1 label' : `${labelCount} labels`) : '/'}\n                </div>\n              ) : (\n                <div className=\"truncate max-w-md text-muted-foreground/50\">-</div>\n              )}\n            </TooltipTrigger>\n            {labels && (\n              <TooltipContent>\n                <p className=\"max-w-[300px]\">{labels}</p>\n              </TooltipContent>\n            )}\n          </Tooltip>\n        )\n      },\n      accessorFn: (row) => Object.entries(row.labels ?? {}).map(([key, value]) => `${key}: ${value}`),\n    },\n    {\n      id: 'lastEvent',\n      size: 120,\n      enableSorting: true,\n      enableHiding: false,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Last Event\" />\n      },\n      accessorFn: (row) => getLastEvent(row).date,\n      cell: ({ row }) => {\n        const lastEvent = getLastEvent(row.original)\n        return (\n          <div className=\"w-full truncate\">\n            <span className=\"truncate block\">{lastEvent.relativeTimeString}</span>\n          </div>\n        )\n      },\n    },\n    {\n      id: 'createdAt',\n      size: 200,\n      enableSorting: true,\n      enableHiding: false,\n      header: ({ column }) => {\n        return <SortableHeader column={column} label=\"Created At\" />\n      },\n      cell: ({ row }) => {\n        const timestamp = formatTimestamp(row.original.createdAt)\n        return (\n          <div className=\"w-full truncate\">\n            <span className=\"truncate block\">{timestamp}</span>\n          </div>\n        )\n      },\n    },\n    {\n      id: 'actions',\n      size: 100,\n      enableHiding: false,\n      cell: ({ row }) => (\n        <div className=\"w-full flex justify-end\">\n          <SandboxTableActions\n            sandbox={row.original}\n            writePermitted={writePermitted}\n            deletePermitted={deletePermitted}\n            isLoading={sandboxIsLoading[row.original.id]}\n            onStart={handleStart}\n            onStop={handleStop}\n            onDelete={handleDelete}\n            onArchive={handleArchive}\n            onVnc={handleVnc}\n            onOpenWebTerminal={handleOpenWebTerminal}\n            onCreateSshAccess={handleCreateSshAccess}\n            onRevokeSshAccess={handleRevokeSshAccess}\n            onRecover={handleRecover}\n            onScreenRecordings={handleScreenRecordings}\n          />\n        </div>\n      ),\n    },\n  ]\n\n  return columns\n}\n\nfunction getDisplayName(sandbox: Sandbox): string {\n  // If the sandbox is destroying and the name starts with \"DESTROYED_\", trim the prefix and timestamp\n  if (sandbox.desiredState === SandboxDesiredState.DESTROYED && sandbox.name.startsWith('DESTROYED_')) {\n    // Remove \"DESTROYED_\" prefix and everything after the last underscore (timestamp)\n    const withoutPrefix = sandbox.name.substring(10) // Remove \"DESTROYED_\"\n    const lastUnderscoreIndex = withoutPrefix.lastIndexOf('_')\n    if (lastUnderscoreIndex !== -1) {\n      return withoutPrefix.substring(0, lastUnderscoreIndex)\n    }\n    return withoutPrefix\n  }\n  return sandbox.name\n}\n\nfunction getLastEvent(sandbox: Sandbox): { date: Date; relativeTimeString: string } {\n  return getRelativeTimeString(sandbox.updatedAt)\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/constants.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SandboxState } from '@daytonaio/api-client'\nimport { CheckCircle, Circle, AlertTriangle, Timer, Archive } from 'lucide-react'\nimport { FacetedFilterOption } from './types'\n\nconst STATE_LABEL_MAPPING: Record<SandboxState, string> = {\n  [SandboxState.STARTED]: 'Started',\n  [SandboxState.STOPPED]: 'Stopped',\n  [SandboxState.ERROR]: 'Error',\n  [SandboxState.BUILD_FAILED]: 'Build Failed',\n  [SandboxState.BUILDING_SNAPSHOT]: 'Building Snapshot',\n  [SandboxState.PENDING_BUILD]: 'Pending Build',\n  [SandboxState.RESTORING]: 'Restoring',\n  [SandboxState.ARCHIVED]: 'Archived',\n  [SandboxState.CREATING]: 'Creating',\n  [SandboxState.STARTING]: 'Starting',\n  [SandboxState.STOPPING]: 'Stopping',\n  [SandboxState.DESTROYING]: 'Deleting',\n  [SandboxState.DESTROYED]: 'Deleted',\n  [SandboxState.PULLING_SNAPSHOT]: 'Pulling Snapshot',\n  [SandboxState.UNKNOWN]: 'Unknown',\n  [SandboxState.ARCHIVING]: 'Archiving',\n  [SandboxState.RESIZING]: 'Resizing',\n}\n\nexport const STATUSES: FacetedFilterOption[] = [\n  {\n    label: getStateLabel(SandboxState.STARTED),\n    value: SandboxState.STARTED,\n    icon: CheckCircle,\n  },\n  { label: getStateLabel(SandboxState.STOPPED), value: SandboxState.STOPPED, icon: Circle },\n  { label: getStateLabel(SandboxState.ERROR), value: SandboxState.ERROR, icon: AlertTriangle },\n  { label: getStateLabel(SandboxState.BUILD_FAILED), value: SandboxState.BUILD_FAILED, icon: AlertTriangle },\n  { label: getStateLabel(SandboxState.STARTING), value: SandboxState.STARTING, icon: Timer },\n  { label: getStateLabel(SandboxState.STOPPING), value: SandboxState.STOPPING, icon: Timer },\n  { label: getStateLabel(SandboxState.DESTROYING), value: SandboxState.DESTROYING, icon: Timer },\n  { label: getStateLabel(SandboxState.ARCHIVED), value: SandboxState.ARCHIVED, icon: Archive },\n  { label: getStateLabel(SandboxState.ARCHIVING), value: SandboxState.ARCHIVING, icon: Timer },\n]\n\nexport function getStateLabel(state?: SandboxState): string {\n  if (!state) {\n    return 'Unknown'\n  }\n  return STATE_LABEL_MAPPING[state]\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/filters/LabelFilter.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'\nimport { Plus, Trash2, X } from 'lucide-react'\nimport { useState } from 'react'\n\ninterface LabelFilterProps {\n  value: string[]\n  onFilterChange: (value: string[] | undefined) => void\n}\n\nexport function LabelFilterIndicator({ value, onFilterChange }: Pick<LabelFilterProps, 'value' | 'onFilterChange'>) {\n  return (\n    <div className=\"flex items-center h-6 gap-0.5 rounded-sm border border-border bg-muted/80 hover:bg-muted/50 text-sm\">\n      <Popover>\n        <PopoverTrigger className=\"max-w-[160px] overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground px-2\">\n          Labels: <span className=\"text-primary font-medium\">{value.length} selected</span>\n        </PopoverTrigger>\n\n        <PopoverContent className=\"p-0 w-[320px]\" align=\"start\">\n          <LabelFilter value={value} onFilterChange={onFilterChange} />\n        </PopoverContent>\n      </Popover>\n\n      <button className=\"h-6 w-5 p-0 border-0 hover:text-muted-foreground\" onClick={() => onFilterChange(undefined)}>\n        <X className=\"h-3 w-3\" />\n      </button>\n    </div>\n  )\n}\n\nexport function LabelFilter({ value, onFilterChange }: LabelFilterProps) {\n  const [newKey, setNewKey] = useState('')\n  const [newValue, setNewValue] = useState('')\n\n  // Convert string array back to key-value pairs for display\n  const labelPairs = value.map((labelString) => {\n    const [key, ...valueParts] = labelString.split(': ')\n    return { key: key || '', value: valueParts.join(': ') || '' }\n  })\n\n  const addKeyValuePair = () => {\n    if (newKey.trim() && newValue.trim()) {\n      const newLabelString = `${newKey.trim()}: ${newValue.trim()}`\n      const updatedValue = [...value, newLabelString]\n      onFilterChange(updatedValue)\n      setNewKey('')\n      setNewValue('')\n    }\n  }\n\n  const removeKeyValuePair = (index: number) => {\n    const updatedValue = value.filter((_, i) => i !== index)\n    onFilterChange(updatedValue.length > 0 ? updatedValue : undefined)\n  }\n\n  const clearAll = () => {\n    onFilterChange(undefined)\n  }\n\n  return (\n    <div className=\"p-3 space-y-3\">\n      {/* Header */}\n      <div className=\"flex items-center justify-between\">\n        <h4 className=\"text-sm font-medium\">Labels</h4>\n        <button className=\"text-sm text-muted-foreground hover:text-primary pl-2\" onClick={clearAll}>\n          Clear\n        </button>\n      </div>\n\n      {/* Current key-value pairs */}\n      {labelPairs.length > 0 && (\n        <div className=\"space-y-2\">\n          <div className=\"space-y-1 max-h-32 overflow-y-auto\">\n            {labelPairs.map((pair, index) => (\n              <div key={index} className=\"flex items-center gap-2 p-2 bg-muted/50 rounded-sm\">\n                <div className=\"flex-1 flex items-center gap-1 text-sm min-w-0\">\n                  <Tooltip>\n                    <TooltipTrigger asChild>\n                      <div className=\"truncate flex-shrink-0 max-w-[50%] rounded-sm bg-blue-100 dark:bg-blue-950 text-blue-800 dark:text-blue-200 px-1 cursor-default\">\n                        {pair.key}\n                      </div>\n                    </TooltipTrigger>\n                    <TooltipContent>\n                      <p className=\"max-w-[300px] break-words\">{pair.key}</p>\n                    </TooltipContent>\n                  </Tooltip>\n\n                  <Tooltip>\n                    <TooltipTrigger asChild>\n                      <span className=\"truncate flex-1 text-muted-foreground cursor-default\">{pair.value}</span>\n                    </TooltipTrigger>\n                    <TooltipContent>\n                      <p className=\"max-w-[300px] break-words\">{pair.value}</p>\n                    </TooltipContent>\n                  </Tooltip>\n                </div>\n                <Button variant=\"ghost\" size=\"sm\" className=\"h-6 w-6 p-0\" onClick={() => removeKeyValuePair(index)}>\n                  <Trash2 className=\"h-3 w-3\" />\n                </Button>\n              </div>\n            ))}\n          </div>\n        </div>\n      )}\n\n      {/* Add new key-value pair */}\n      <div className=\"space-y-2\">\n        <div className=\"space-y-2\">\n          <Input\n            placeholder=\"Key\"\n            value={newKey}\n            onChange={(e) => setNewKey(e.target.value)}\n            className=\"h-8\"\n            onKeyDown={(e) => {\n              if (e.key === 'Enter' && newKey.trim() && newValue.trim()) {\n                addKeyValuePair()\n              }\n            }}\n          />\n          <Input\n            placeholder=\"Value\"\n            value={newValue}\n            onChange={(e) => setNewValue(e.target.value)}\n            className=\"h-8\"\n            onKeyDown={(e) => {\n              if (e.key === 'Enter' && newKey.trim() && newValue.trim()) {\n                addKeyValuePair()\n              }\n            }}\n          />\n          <Button\n            variant=\"outline\"\n            size=\"sm\"\n            className=\"w-full h-8\"\n            onClick={addKeyValuePair}\n            disabled={!newKey.trim() || !newValue.trim()}\n          >\n            <Plus className=\"h-3 w-3 mr-1\" />\n            Add Label\n          </Button>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/filters/LastEventFilter.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover'\nimport { cn } from '@/lib/utils'\nimport { Calendar } from '@/components/ui/calendar'\nimport { Label } from '@/components/ui/label'\nimport { useState } from 'react'\nimport { format } from 'date-fns'\nimport { CalendarIcon, X } from 'lucide-react'\n\ninterface LastEventFilterProps {\n  value: (Date | undefined)[]\n  onFilterChange: (value: (Date | undefined)[] | undefined) => void\n}\n\nexport function LastEventFilterIndicator({ value, onFilterChange }: LastEventFilterProps) {\n  return (\n    <div className=\"flex items-center h-6 gap-0.5 rounded-sm border border-border bg-muted/80 hover:bg-muted/50 text-sm\">\n      <Popover>\n        <PopoverTrigger className=\"max-w-[220px] overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground px-2\">\n          Last Event:{' '}\n          <span className=\"text-primary font-medium\">\n            {value.some((d) => d !== undefined)\n              ? `${value\n                  .filter((d): d is Date => d !== undefined)\n                  .map((d) => format(d, 'PPP'))\n                  .join(' - ')}`\n              : ''}\n          </span>\n        </PopoverTrigger>\n        <PopoverContent className=\"p-3 w-auto\" align=\"start\">\n          <LastEventFilter onFilterChange={onFilterChange} value={value} />\n        </PopoverContent>\n      </Popover>\n\n      <button className=\"h-6 w-5 p-0 border-0 hover:text-muted-foreground\" onClick={() => onFilterChange(undefined)}>\n        <X className=\"h-3 w-3\" />\n      </button>\n    </div>\n  )\n}\n\ninterface LastEventFilterContentProps {\n  onFilterChange: (value: (Date | undefined)[] | undefined) => void\n  value: (Date | undefined)[]\n}\n\nexport function LastEventFilter({ onFilterChange, value }: LastEventFilterContentProps) {\n  const [fromDate, setFromDate] = useState<Date | undefined>(value[0])\n  const [toDate, setToDate] = useState<Date | undefined>(value[1])\n\n  const handleFromDateSelect = (selectedDate: Date | undefined) => {\n    setFromDate(selectedDate)\n    const dates = [selectedDate, toDate]\n    const hasAnyDate = dates.some((date) => date !== undefined)\n    onFilterChange(hasAnyDate ? dates : undefined)\n  }\n\n  const handleToDateSelect = (selectedDate: Date | undefined) => {\n    setToDate(selectedDate)\n    const dates = [fromDate, selectedDate]\n    const hasAnyDate = dates.some((date) => date !== undefined)\n    onFilterChange(hasAnyDate ? dates : undefined)\n  }\n\n  const handleClear = () => {\n    setFromDate(undefined)\n    setToDate(undefined)\n    onFilterChange(undefined)\n  }\n\n  return (\n    <div className=\"flex flex-col gap-2\">\n      <div className=\"flex items-center justify-between\">\n        <Label>Last event</Label>\n        <button className=\"text-sm text-muted-foreground hover:text-primary px-2\" onClick={() => handleClear()}>\n          Clear\n        </button>\n      </div>\n      <div className=\"flex gap-2 items-center\">\n        <Popover>\n          <PopoverTrigger asChild>\n            <Button variant=\"outline\" className={cn('min-w-40', !fromDate && 'text-muted-foreground')}>\n              <CalendarIcon className=\" h-4 w-4\" />\n              {fromDate ? format(fromDate, 'PPP') : <span>Pick a date</span>}\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent className=\"w-auto p-0\" align=\"start\">\n            <Calendar mode=\"single\" selected={fromDate} onSelect={handleFromDateSelect} initialFocus />\n          </PopoverContent>\n        </Popover>\n\n        <div className=\"w-4 flex-shrink-0 h-[1px] bg-border\"></div>\n\n        <Popover>\n          <PopoverTrigger asChild>\n            <Button variant=\"outline\" className={cn('min-w-40', !toDate && 'text-muted-foreground')}>\n              <CalendarIcon className=\" h-4 w-4\" />\n              {toDate ? format(toDate, 'PPP') : <span>Pick a date</span>}\n            </Button>\n          </PopoverTrigger>\n          <PopoverContent className=\"w-auto p-0\" align=\"start\">\n            <Calendar mode=\"single\" selected={toDate} onSelect={handleToDateSelect} initialFocus />\n          </PopoverContent>\n        </Popover>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/filters/RegionFilter.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Command,\n  CommandCheckboxItem,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandInputButton,\n  CommandList,\n} from '@/components/ui/command'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { Loader2, X } from 'lucide-react'\nimport { FacetedFilterOption } from '../types'\n\ninterface RegionFilterProps {\n  value: string[]\n  onFilterChange: (value: string[] | undefined) => void\n  options?: FacetedFilterOption[]\n  isLoading?: boolean\n}\n\nexport function RegionFilterIndicator({ value, onFilterChange, options, isLoading }: RegionFilterProps) {\n  const selectedRegionLabels = value\n    .map((v) => options?.find((r) => r.value === v)?.label)\n    .filter(Boolean)\n    .join(', ')\n\n  return (\n    <div className=\"flex items-center h-6 gap-0.5 rounded-sm border border-border bg-muted/80 hover:bg-muted/50 text-sm\">\n      <Popover>\n        <PopoverTrigger className=\"max-w-[160px] overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground px-2\">\n          Region:{' '}\n          <span className=\"text-primary font-medium\">\n            {selectedRegionLabels.length > 0 ? selectedRegionLabels : 'All'}\n          </span>\n        </PopoverTrigger>\n\n        <PopoverContent className=\"p-0 w-72\" align=\"start\">\n          <RegionFilter value={value} onFilterChange={onFilterChange} options={options} isLoading={isLoading} />\n        </PopoverContent>\n      </Popover>\n\n      <button className=\"h-6 w-5 p-0 border-0 hover:text-muted-foreground\" onClick={() => onFilterChange(undefined)}>\n        <X className=\"h-3 w-3\" />\n      </button>\n    </div>\n  )\n}\n\nexport function RegionFilter({ value, onFilterChange, options, isLoading }: RegionFilterProps) {\n  return (\n    <Command>\n      <CommandInput placeholder=\"Search...\" className=\"\">\n        <CommandInputButton onClick={() => onFilterChange(undefined)}>Clear</CommandInputButton>\n      </CommandInput>\n      <CommandList>\n        {isLoading ? (\n          <div className=\"flex items-center justify-center py-6\">\n            <Loader2 className=\"h-4 w-4 animate-spin mr-2\" />\n            <span className=\"text-sm text-muted-foreground\">Loading regions...</span>\n          </div>\n        ) : (\n          <>\n            <CommandEmpty>No regions found.</CommandEmpty>\n            <CommandGroup>\n              {options?.map((region) => (\n                <CommandCheckboxItem\n                  checked={value.includes(region.value)}\n                  key={region.value}\n                  onSelect={() => {\n                    const newValue = value.includes(region.value)\n                      ? value.filter((v) => v !== region.value)\n                      : [...value, region.value]\n                    onFilterChange(newValue.length > 0 ? newValue : undefined)\n                  }}\n                >\n                  {region.label}\n                </CommandCheckboxItem>\n              ))}\n            </CommandGroup>\n          </>\n        )}\n      </CommandList>\n    </Command>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/filters/ResourceFilter.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { useMemo } from 'react'\n\nimport { X } from 'lucide-react'\n\nexport interface ResourceFilterValue {\n  cpu?: { min?: number; max?: number }\n  memory?: { min?: number; max?: number }\n  disk?: { min?: number; max?: number }\n}\n\ninterface ResourceFilterProps {\n  value: ResourceFilterValue\n  onFilterChange: (value: ResourceFilterValue | undefined) => void\n  resourceType?: 'cpu' | 'memory' | 'disk'\n}\n\nconst RESOURCE_CONFIG = {\n  cpu: { label: 'vCPU', displayLabel: 'CPU' },\n  memory: { label: 'Memory (GiB)', displayLabel: 'Memory' },\n  disk: { label: 'Disk (GiB)', displayLabel: 'Disk' },\n} as const\n\nexport function ResourceFilterIndicator({ value, onFilterChange, resourceType }: ResourceFilterProps) {\n  const { title, label } = useMemo(() => {\n    let title = 'All'\n    let label = 'Resources'\n\n    if (resourceType) {\n      const resourceValue = value[resourceType]\n      if (resourceValue?.min || resourceValue?.max) {\n        const config = RESOURCE_CONFIG[resourceType]\n        const unit = resourceType === 'cpu' ? 'vCPU' : 'GiB'\n        title = `${resourceValue.min ?? 'Any'} - ${resourceValue.max ?? 'Any'} ${unit}`\n        label = config.displayLabel\n      }\n    } else {\n      const filters: string[] = []\n      Object.entries(RESOURCE_CONFIG).forEach(([type, config]) => {\n        const resourceValue = value[type as keyof ResourceFilterValue]\n        if (resourceValue?.min || resourceValue?.max) {\n          const unit = type === 'cpu' ? 'vCPU' : 'GiB'\n          filters.push(`${config.displayLabel}: ${resourceValue.min ?? 'any'}-${resourceValue.max ?? 'any'} ${unit}`)\n        }\n      })\n      title = filters.length > 0 ? filters.join('; ') : 'All'\n    }\n\n    return { title, label }\n  }, [value, resourceType])\n\n  return (\n    <div className=\"flex items-center h-6 gap-0.5 rounded-sm border border-border bg-muted/80 hover:bg-muted/50 text-sm\">\n      <Popover>\n        <PopoverTrigger className=\"max-w-[240px] overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground px-2\">\n          {label}: <span className=\"text-primary font-medium\">{title}</span>\n        </PopoverTrigger>\n\n        <PopoverContent className=\"w-72 p-4\" align=\"start\">\n          <ResourceFilter value={value} onFilterChange={onFilterChange} resourceType={resourceType} />\n        </PopoverContent>\n      </Popover>\n\n      <button\n        className=\"h-6 w-5 p-0 border-0 hover:text-muted-foreground\"\n        onClick={() => {\n          if (resourceType) {\n            const newFilterValue = { ...value }\n            delete newFilterValue[resourceType]\n            onFilterChange(Object.keys(newFilterValue).length > 0 ? newFilterValue : undefined)\n          } else {\n            onFilterChange(undefined)\n          }\n        }}\n      >\n        <X className=\"h-3 w-3\" />\n      </button>\n    </div>\n  )\n}\n\nexport function ResourceFilter({ value, onFilterChange, resourceType }: ResourceFilterProps) {\n  const handleValueChange = (\n    resource: keyof ResourceFilterValue,\n    field: 'min' | 'max',\n    newValue: number | undefined,\n  ) => {\n    const currentResourceValue = value[resource] || {}\n    const updatedResourceValue = { ...currentResourceValue, [field]: newValue }\n\n    if (newValue === undefined && !currentResourceValue.min && !currentResourceValue.max) {\n      const newFilterValue = { ...value }\n      delete newFilterValue[resource]\n      onFilterChange(Object.keys(newFilterValue).length > 0 ? newFilterValue : undefined)\n      return\n    }\n\n    const newFilterValue = { ...value, [resource]: updatedResourceValue }\n    onFilterChange(newFilterValue)\n  }\n\n  const handleClear = (resource: keyof ResourceFilterValue) => {\n    const newFilterValue = { ...value }\n    delete newFilterValue[resource]\n    onFilterChange(Object.keys(newFilterValue).length > 0 ? newFilterValue : undefined)\n  }\n\n  if (resourceType) {\n    const config = RESOURCE_CONFIG[resourceType]\n    const currentValues = value[resourceType] || {}\n\n    return (\n      <div className=\"flex flex-col gap-2\">\n        <div className=\"flex items-center justify-between gap-2\">\n          <Label>{config.label}</Label>\n          <button\n            className=\"text-sm text-muted-foreground hover:text-primary\"\n            onClick={() => handleClear(resourceType)}\n          >\n            Clear\n          </button>\n        </div>\n        <div className=\"flex items-center gap-2\">\n          <Input\n            type=\"number\"\n            placeholder=\"Min\"\n            min={0}\n            value={currentValues.min ?? ''}\n            onChange={(e) => {\n              const newValue = e.target.value ? Number(e.target.value) : undefined\n              handleValueChange(resourceType, 'min', newValue)\n            }}\n            className=\"w-full\"\n          />\n          <div className=\"w-8 h-[1px] bg-border\"></div>\n          <Input\n            type=\"number\"\n            placeholder=\"Max\"\n            min={0}\n            value={currentValues.max ?? ''}\n            onChange={(e) => {\n              const newValue = e.target.value ? Number(e.target.value) : undefined\n              handleValueChange(resourceType, 'max', newValue)\n            }}\n            className=\"w-full\"\n          />\n        </div>\n      </div>\n    )\n  }\n\n  return null\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/filters/SnapshotFilter.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Command,\n  CommandCheckboxItem,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandInputButton,\n  CommandList,\n} from '@/components/ui/command'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { SnapshotDto } from '@daytonaio/api-client'\nimport { Loader2, X } from 'lucide-react'\nimport { useState } from 'react'\n\ninterface SnapshotFilterProps {\n  value: string[]\n  onFilterChange: (value: string[] | undefined) => void\n  snapshots: SnapshotDto[]\n  isLoading: boolean\n  hasMore?: boolean\n  onChangeSnapshotSearchValue: (name?: string) => void\n}\n\nexport function SnapshotFilterIndicator({\n  value,\n  onFilterChange,\n  snapshots,\n  isLoading,\n  hasMore,\n  onChangeSnapshotSearchValue,\n}: SnapshotFilterProps) {\n  return (\n    <div className=\"flex items-center h-6 gap-0.5 rounded-sm border border-border bg-muted/80 hover:bg-muted/50 text-sm\">\n      <Popover>\n        <PopoverTrigger className=\"max-w-[160px] overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground px-2\">\n          Snapshot: <span className=\"text-primary font-medium\">{value.length} selected</span>\n        </PopoverTrigger>\n\n        <PopoverContent className=\"p-0 w-[240px]\" align=\"start\">\n          <SnapshotFilter\n            value={value}\n            onFilterChange={onFilterChange}\n            snapshots={snapshots}\n            isLoading={isLoading}\n            hasMore={hasMore}\n            onChangeSnapshotSearchValue={onChangeSnapshotSearchValue}\n          />\n        </PopoverContent>\n      </Popover>\n\n      <button className=\"h-6 w-5 p-0 border-0 hover:text-muted-foreground\" onClick={() => onFilterChange(undefined)}>\n        <X className=\"h-3 w-3\" />\n      </button>\n    </div>\n  )\n}\n\nexport function SnapshotFilter({\n  value,\n  onFilterChange,\n  snapshots,\n  isLoading,\n  hasMore,\n  onChangeSnapshotSearchValue,\n}: SnapshotFilterProps) {\n  const [searchValue, setSearchValue] = useState('')\n\n  const handleSelect = (snapshotName: string) => {\n    const newValue = value.includes(snapshotName)\n      ? value.filter((name) => name !== snapshotName)\n      : [...value, snapshotName]\n    onFilterChange(newValue.length > 0 ? newValue : undefined)\n  }\n\n  const handleSearchChange = (search: string | number) => {\n    const searchStr = String(search)\n    setSearchValue(searchStr)\n    if (onChangeSnapshotSearchValue) {\n      onChangeSnapshotSearchValue(searchStr || undefined)\n    }\n  }\n\n  return (\n    <Command>\n      <CommandInput placeholder=\"Search...\" className=\"\" value={searchValue} onValueChange={setSearchValue}>\n        <CommandInputButton\n          onClick={() => {\n            onFilterChange(undefined)\n            setSearchValue('')\n            if (onChangeSnapshotSearchValue) {\n              onChangeSnapshotSearchValue(undefined)\n            }\n          }}\n        >\n          Clear\n        </CommandInputButton>\n      </CommandInput>\n      {hasMore && (\n        <div className=\"px-2 pb-2 mt-2\">\n          <div className=\"text-xs text-muted-foreground bg-muted/50 rounded px-2 py-1\">\n            Please refine your search to see more Snapshots.\n          </div>\n        </div>\n      )}\n      <CommandList>\n        {isLoading ? (\n          <div className=\"flex items-center justify-center py-6\">\n            <Loader2 className=\"h-4 w-4 animate-spin mr-2\" />\n            <span className=\"text-sm text-muted-foreground\">Loading Snapshots...</span>\n          </div>\n        ) : (\n          <>\n            <CommandEmpty>No Snapshots found.</CommandEmpty>\n            <CommandGroup>\n              {snapshots.map((snapshot) => (\n                <CommandCheckboxItem\n                  key={snapshot.id}\n                  onSelect={() => handleSelect(snapshot.name ?? '')}\n                  value={snapshot.name}\n                  className=\"cursor-pointer\"\n                  checked={value.includes(snapshot.name ?? '')}\n                >\n                  {snapshot.name}\n                </CommandCheckboxItem>\n              ))}\n            </CommandGroup>\n          </>\n        )}\n      </CommandList>\n    </Command>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/filters/StateFilter.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  Command,\n  CommandCheckboxItem,\n  CommandGroup,\n  CommandInput,\n  CommandInputButton,\n  CommandList,\n} from '@/components/ui/command'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { SandboxState } from '@daytonaio/api-client'\nimport { X } from 'lucide-react'\nimport { STATUSES, getStateLabel } from '../constants'\n\ninterface StateFilterProps {\n  value: string[]\n  onFilterChange: (value: string[] | undefined) => void\n}\n\nexport function StateFilterIndicator({ value, onFilterChange }: StateFilterProps) {\n  const selectedStates = value.map((v) => getStateLabel(v as SandboxState))\n  return (\n    <div className=\"flex items-center h-6 gap-0.5 rounded-sm border border-border bg-muted/80 hover:bg-muted/50 text-sm\">\n      <Popover>\n        <PopoverTrigger className=\"max-w-[240px] overflow-hidden text-ellipsis whitespace-nowrap text-muted-foreground px-2\">\n          States:{' '}\n          <span className=\"text-primary font-medium\">\n            {selectedStates.length > 0\n              ? selectedStates.length > 2\n                ? `${selectedStates[0]}, ${selectedStates[1]}, +${selectedStates.length - 2}`\n                : `${selectedStates.join(', ')}`\n              : ''}\n          </span>\n        </PopoverTrigger>\n\n        <PopoverContent className=\"p-0 w-72\" align=\"start\">\n          <StateFilter value={value} onFilterChange={onFilterChange} />\n        </PopoverContent>\n      </Popover>\n\n      <button className=\"h-6 w-5 p-0 border-0 hover:text-muted-foreground\" onClick={() => onFilterChange(undefined)}>\n        <X className=\"h-3 w-3\" />\n      </button>\n    </div>\n  )\n}\n\nexport function StateFilter({ value, onFilterChange }: StateFilterProps) {\n  return (\n    <Command>\n      <CommandInput placeholder=\"Search...\">\n        <CommandInputButton\n          className=\"text-sm text-muted-foreground hover:text-primary px-2\"\n          onClick={() => onFilterChange(undefined)}\n        >\n          Clear\n        </CommandInputButton>\n      </CommandInput>\n\n      <CommandList>\n        <CommandGroup>\n          {STATUSES.map((status) => (\n            <CommandCheckboxItem\n              key={status.value}\n              checked={value.includes(status.value)}\n              onSelect={() => {\n                const newValue = value.includes(status.value)\n                  ? value.filter((v) => v !== status.value)\n                  : [...value, status.value]\n                onFilterChange(newValue.length > 0 ? newValue : undefined)\n              }}\n            >\n              {status.label}\n            </CommandCheckboxItem>\n          ))}\n        </CommandGroup>\n      </CommandList>\n    </Command>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/index.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { cn } from '@/lib/utils'\nimport {\n  filterArchivable,\n  filterDeletable,\n  filterStartable,\n  filterStoppable,\n  getBulkActionCounts,\n} from '@/lib/utils/sandbox'\nimport { OrganizationRolePermissionsEnum, Sandbox, SandboxState } from '@daytonaio/api-client'\nimport { flexRender } from '@tanstack/react-table'\nimport { Container } from 'lucide-react'\nimport { AnimatePresence } from 'motion/react'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useNavigate } from 'react-router-dom'\nimport { useCommandPaletteActions } from '../CommandPalette'\nimport { Pagination } from '../Pagination'\nimport { SelectionToast } from '../SelectionToast'\nimport { TableEmptyState } from '../TableEmptyState'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table'\nimport { BulkAction, BulkActionAlertDialog } from './BulkActionAlertDialog'\nimport { SandboxTableHeader } from './SandboxTableHeader'\nimport { SandboxTableProps } from './types'\nimport { useSandboxCommands } from './useSandboxCommands'\nimport { useSandboxTable } from './useSandboxTable'\n\nexport function SandboxTable({\n  data,\n  sandboxIsLoading,\n  sandboxStateIsTransitioning,\n  loading,\n  snapshots,\n  snapshotsDataIsLoading,\n  snapshotsDataHasMore,\n  onChangeSnapshotSearchValue,\n  regionsData,\n  regionsDataIsLoading,\n  getRegionName,\n  handleStart,\n  handleStop,\n  handleDelete,\n  handleBulkDelete,\n  handleBulkStart,\n  handleBulkStop,\n  handleBulkArchive,\n  handleArchive,\n  handleVnc,\n  getWebTerminalUrl,\n  handleCreateSshAccess,\n  handleRevokeSshAccess,\n  handleScreenRecordings,\n  handleRefresh,\n  isRefreshing,\n  onRowClick,\n  pagination,\n  pageCount,\n  totalItems,\n  onPaginationChange,\n  sorting,\n  onSortingChange,\n  filters,\n  onFiltersChange,\n  handleRecover,\n}: SandboxTableProps) {\n  const navigate = useNavigate()\n  const { authenticatedUserHasPermission } = useSelectedOrganization()\n  const writePermitted = authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_SANDBOXES)\n  const deletePermitted = authenticatedUserHasPermission(OrganizationRolePermissionsEnum.DELETE_SANDBOXES)\n\n  const { table, regionOptions } = useSandboxTable({\n    data,\n    sandboxIsLoading,\n    writePermitted,\n    deletePermitted,\n    handleStart,\n    handleStop,\n    handleDelete,\n    handleArchive,\n    handleVnc,\n    getWebTerminalUrl,\n    handleCreateSshAccess,\n    handleRevokeSshAccess,\n    handleScreenRecordings,\n    pagination,\n    pageCount,\n    onPaginationChange,\n    sorting,\n    onSortingChange,\n    filters,\n    onFiltersChange,\n    regionsData,\n    handleRecover,\n    getRegionName,\n  })\n\n  const [pendingBulkAction, setPendingBulkAction] = useState<BulkAction | null>(null)\n\n  const selectedRows = table.getRowModel().rows.filter((row) => row.getIsSelected())\n  const hasSelection = selectedRows.length > 0\n  const selectedCount = selectedRows.length\n  const totalCount = table.getRowModel().rows.length\n  const selectedSandboxes: Sandbox[] = selectedRows.map((row) => row.original)\n\n  const bulkActionCounts = useMemo(() => getBulkActionCounts(selectedSandboxes), [selectedSandboxes])\n\n  const handleBulkActionConfirm = () => {\n    if (!pendingBulkAction) return\n\n    const handlers: Record<BulkAction, () => void> = {\n      [BulkAction.Delete]: () => handleBulkDelete(filterDeletable(selectedSandboxes).map((s) => s.id)),\n      [BulkAction.Start]: () => handleBulkStart(filterStartable(selectedSandboxes).map((s) => s.id)),\n      [BulkAction.Stop]: () => handleBulkStop(filterStoppable(selectedSandboxes).map((s) => s.id)),\n      [BulkAction.Archive]: () => handleBulkArchive(filterArchivable(selectedSandboxes).map((s) => s.id)),\n    }\n\n    handlers[pendingBulkAction]()\n    setPendingBulkAction(null)\n    table.toggleAllRowsSelected(false)\n  }\n\n  const toggleAllRowsSelected = useCallback(\n    (selected: boolean) => {\n      if (selected) {\n        for (const row of table.getRowModel().rows) {\n          const selectDisabled = sandboxIsLoading[row.original.id] || row.original.state === SandboxState.DESTROYED\n          if (!selectDisabled) {\n            row.toggleSelected(true)\n          }\n        }\n      } else {\n        table.toggleAllRowsSelected(selected)\n      }\n    },\n    [sandboxIsLoading, table],\n  )\n\n  const selectableCount = useMemo(() => {\n    return data.filter((sandbox) => !sandboxIsLoading[sandbox.id] && sandbox.state !== SandboxState.DESTROYED).length\n  }, [sandboxIsLoading, data])\n\n  useSandboxCommands({\n    writePermitted,\n    deletePermitted,\n    selectedCount,\n    totalCount,\n    selectableCount,\n    toggleAllRowsSelected,\n    bulkActionCounts,\n    onDelete: () => setPendingBulkAction(BulkAction.Delete),\n    onStart: () => setPendingBulkAction(BulkAction.Start),\n    onStop: () => setPendingBulkAction(BulkAction.Stop),\n    onArchive: () => setPendingBulkAction(BulkAction.Archive),\n  })\n\n  const { setIsOpen } = useCommandPaletteActions()\n  const handleOpenCommandPalette = () => {\n    setIsOpen(true)\n  }\n\n  return (\n    <>\n      <SandboxTableHeader\n        table={table}\n        regionOptions={regionOptions}\n        regionsDataIsLoading={regionsDataIsLoading}\n        snapshots={snapshots}\n        snapshotsDataIsLoading={snapshotsDataIsLoading}\n        snapshotsDataHasMore={snapshotsDataHasMore}\n        onChangeSnapshotSearchValue={onChangeSnapshotSearchValue}\n        onRefresh={handleRefresh}\n        isRefreshing={isRefreshing}\n      />\n\n      <Table className=\"border-separate border-spacing-0\" style={{ tableLayout: 'fixed', width: '100%' }}>\n        <TableHeader>\n          {table.getHeaderGroups().map((headerGroup) => (\n            <TableRow key={headerGroup.id}>\n              {headerGroup.headers.map((header) => {\n                return (\n                  <TableHead\n                    key={header.id}\n                    data-state={header.column.getCanSort() && 'sortable'}\n                    onClick={() =>\n                      header.column.getCanSort() && header.column.toggleSorting(header.column.getIsSorted() === 'asc')\n                    }\n                    className={cn(\n                      'sticky top-0 z-[3] border-b border-border',\n                      header.column.getCanSort() ? 'hover:bg-muted cursor-pointer' : '',\n                    )}\n                    style={{\n                      width: `${header.column.getSize()}px`,\n                    }}\n                  >\n                    {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                )\n              })}\n            </TableRow>\n          ))}\n        </TableHeader>\n        <TableBody>\n          {loading ? (\n            <TableRow>\n              <TableCell colSpan={table.getAllColumns().length} className=\"h-10 text-center\">\n                Loading...\n              </TableCell>\n            </TableRow>\n          ) : table.getRowModel().rows?.length ? (\n            table.getRowModel().rows.map((row) => (\n              <TableRow\n                key={row.id}\n                data-state={row.getIsSelected() && 'selected'}\n                className={cn('group/table-row transition-all', {\n                  'opacity-80 pointer-events-none':\n                    sandboxIsLoading[row.original.id] || row.original.state === SandboxState.DESTROYED,\n                  'bg-muted animate-pulse': sandboxStateIsTransitioning[row.original.id],\n                  'cursor-pointer': onRowClick,\n                })}\n                onClick={() => onRowClick?.(row.original)}\n              >\n                {row.getVisibleCells().map((cell) => (\n                  <TableCell\n                    key={cell.id}\n                    onClick={(e) => {\n                      if (cell.column.id === 'select' || cell.column.id === 'actions') {\n                        e.stopPropagation()\n                      }\n                    }}\n                    className={cn('border-b border-border', {\n                      'group-hover/table-row:underline': cell.column.id === 'name',\n                    })}\n                    style={{\n                      width: `${cell.column.getSize()}px`,\n                    }}\n                    sticky={cell.column.id === 'actions' ? 'right' : undefined}\n                  >\n                    {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                  </TableCell>\n                ))}\n              </TableRow>\n            ))\n          ) : (\n            <TableEmptyState\n              colSpan={table.getAllColumns().length}\n              message=\"No Sandboxes yet.\"\n              icon={<Container className=\"w-8 h-8\" />}\n              description={\n                <div className=\"space-y-2\">\n                  <p>Spin up a Sandbox to run code in an isolated environment.</p>\n                  <p>Use the Daytona SDK or CLI to create one.</p>\n                  <p>\n                    <button\n                      onClick={() => navigate(RoutePath.ONBOARDING)}\n                      className=\"text-primary hover:underline font-medium\"\n                    >\n                      Check out the Onboarding guide\n                    </button>{' '}\n                    to learn more.\n                  </p>\n                </div>\n              }\n            />\n          )}\n        </TableBody>\n      </Table>\n\n      <div className=\"flex items-center justify-end relative\">\n        <Pagination className=\"pb-2 pt-6\" table={table} entityName=\"Sandboxes\" totalItems={totalItems} />\n\n        <AnimatePresence>\n          {hasSelection && (\n            <SelectionToast\n              className=\"absolute bottom-5 left-1/2 -translate-x-1/2 z-50\"\n              selectedCount={selectedRows.length}\n              onClearSelection={() => table.resetRowSelection()}\n              onActionClick={handleOpenCommandPalette}\n            />\n          )}\n        </AnimatePresence>\n      </div>\n\n      <BulkActionAlertDialog\n        action={pendingBulkAction}\n        count={\n          pendingBulkAction\n            ? {\n                [BulkAction.Delete]: bulkActionCounts.deletable,\n                [BulkAction.Start]: bulkActionCounts.startable,\n                [BulkAction.Stop]: bulkActionCounts.stoppable,\n                [BulkAction.Archive]: bulkActionCounts.archivable,\n              }[pendingBulkAction]\n            : 0\n        }\n        onConfirm={handleBulkActionConfirm}\n        onCancel={() => setPendingBulkAction(null)}\n      />\n    </>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/state-icons.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SandboxState } from '@daytonaio/api-client'\nimport { Loader2 } from 'lucide-react'\n\ninterface SquareProps {\n  color: string\n}\n\nfunction Square({ color }: SquareProps) {\n  return (\n    <div className=\"w-4 h-4 p-1\">\n      <div className={`w-2 h-2 ${color} rounded-[2px]`} />\n    </div>\n  )\n}\n\nexport const STATE_ICONS: Record<SandboxState | 'RECOVERY', React.ReactNode> = {\n  [SandboxState.UNKNOWN]: <Square color=\"bg-muted-foreground/20\" />,\n  [SandboxState.CREATING]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  [SandboxState.STARTING]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  [SandboxState.STARTED]: <Square color=\"bg-green-600\" />,\n  [SandboxState.STOPPING]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  [SandboxState.STOPPED]: <Square color=\"bg-muted-foreground/50\" />,\n  [SandboxState.DESTROYING]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  [SandboxState.DESTROYED]: <Square color=\"bg-muted-foreground/20\" />,\n  [SandboxState.ERROR]: <Square color=\"bg-destructive\" />,\n  [SandboxState.BUILD_FAILED]: <Square color=\"bg-destructive\" />,\n  [SandboxState.BUILDING_SNAPSHOT]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  [SandboxState.PULLING_SNAPSHOT]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  [SandboxState.PENDING_BUILD]: <Square color=\"bg-muted-foreground/20\" />,\n  [SandboxState.ARCHIVED]: <Square color=\"bg-muted-foreground/20\" />,\n  [SandboxState.ARCHIVING]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  [SandboxState.RESTORING]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  [SandboxState.RESIZING]: <Loader2 className=\"w-3 h-3 animate-spin\" />,\n  RECOVERY: <Square color=\"bg-yellow-600\" />,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/types.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DEFAULT_SANDBOX_SORTING, SandboxFilters, SandboxSorting } from '@/hooks/useSandboxes'\nimport {\n  ListSandboxesPaginatedOrderEnum,\n  ListSandboxesPaginatedSortEnum,\n  ListSandboxesPaginatedStatesEnum,\n  Region,\n  Sandbox,\n  SandboxState,\n  SnapshotDto,\n} from '@daytonaio/api-client'\nimport { ColumnFiltersState, SortingState, Table } from '@tanstack/react-table'\n\nexport interface SandboxTableProps {\n  data: Sandbox[]\n  sandboxIsLoading: Record<string, boolean>\n  sandboxStateIsTransitioning: Record<string, boolean>\n  loading: boolean\n  snapshots: SnapshotDto[]\n  snapshotsDataIsLoading: boolean\n  snapshotsDataHasMore?: boolean\n  onChangeSnapshotSearchValue: (name?: string) => void\n  regionsData: Region[]\n  regionsDataIsLoading: boolean\n  getRegionName: (regionId: string) => string | undefined\n  handleStart: (id: string) => void\n  handleStop: (id: string) => void\n  handleDelete: (id: string) => void\n  handleBulkDelete: (ids: string[]) => void\n  handleBulkStart: (ids: string[]) => void\n  handleBulkStop: (ids: string[]) => void\n  handleBulkArchive: (ids: string[]) => void\n  handleArchive: (id: string) => void\n  handleVnc: (id: string) => void\n  getWebTerminalUrl: (id: string) => Promise<string | null>\n  handleCreateSshAccess: (id: string) => void\n  handleRevokeSshAccess: (id: string) => void\n  handleRefresh: () => void\n  isRefreshing?: boolean\n  onRowClick?: (sandbox: Sandbox) => void\n  pagination: {\n    pageIndex: number\n    pageSize: number\n  }\n  pageCount: number\n  totalItems: number\n  onPaginationChange: (pagination: { pageIndex: number; pageSize: number }) => void\n  sorting: SandboxSorting\n  onSortingChange: (sorting: SandboxSorting) => void\n  filters: SandboxFilters\n  onFiltersChange: (filters: SandboxFilters) => void\n  handleRecover: (id: string) => void\n  handleScreenRecordings: (id: string) => void\n}\n\nexport interface SandboxTableActionsProps {\n  sandbox: Sandbox\n  writePermitted: boolean\n  deletePermitted: boolean\n  isLoading: boolean\n  onStart: (id: string) => void\n  onStop: (id: string) => void\n  onDelete: (id: string) => void\n  onArchive: (id: string) => void\n  onVnc: (id: string) => void\n  onOpenWebTerminal: (id: string) => void\n  onCreateSshAccess: (id: string) => void\n  onRevokeSshAccess: (id: string) => void\n  onRecover: (id: string) => void\n  onScreenRecordings: (id: string) => void\n}\n\nexport interface SandboxTableHeaderProps {\n  table: Table<Sandbox>\n  regionOptions: FacetedFilterOption[]\n  regionsDataIsLoading: boolean\n  snapshots: SnapshotDto[]\n  snapshotsDataIsLoading: boolean\n  snapshotsDataHasMore?: boolean\n  onChangeSnapshotSearchValue: (name?: string) => void\n  onRefresh: () => void\n  isRefreshing?: boolean\n}\n\nexport interface FacetedFilterOption {\n  label: string\n  value: string | SandboxState\n  icon?: any\n}\n\nexport const convertTableSortingToApiSorting = (sorting: SortingState): SandboxSorting => {\n  if (!sorting.length) {\n    return DEFAULT_SANDBOX_SORTING\n  }\n\n  const sort = sorting[0]\n  let field: ListSandboxesPaginatedSortEnum\n\n  switch (sort.id) {\n    case 'name':\n      field = ListSandboxesPaginatedSortEnum.NAME\n      break\n    case 'state':\n      field = ListSandboxesPaginatedSortEnum.STATE\n      break\n    case 'snapshot':\n      field = ListSandboxesPaginatedSortEnum.SNAPSHOT\n      break\n    case 'region':\n    case 'target':\n      field = ListSandboxesPaginatedSortEnum.REGION\n      break\n    case 'lastEvent':\n    case 'updatedAt':\n      field = ListSandboxesPaginatedSortEnum.UPDATED_AT\n      break\n    case 'createdAt':\n    default:\n      field = ListSandboxesPaginatedSortEnum.CREATED_AT\n      break\n  }\n\n  return {\n    field,\n    direction: sort.desc ? ListSandboxesPaginatedOrderEnum.DESC : ListSandboxesPaginatedOrderEnum.ASC,\n  }\n}\n\nexport const convertTableFiltersToApiFilters = (columnFilters: ColumnFiltersState): SandboxFilters => {\n  const filters: SandboxFilters = {}\n\n  columnFilters.forEach((filter) => {\n    switch (filter.id) {\n      case 'name':\n        if (filter.value && typeof filter.value === 'string') {\n          filters.idOrName = filter.value\n        }\n        break\n      case 'state':\n        if (Array.isArray(filter.value) && filter.value.length > 0) {\n          filters.states = filter.value as ListSandboxesPaginatedStatesEnum[]\n        }\n        break\n      case 'snapshot':\n        if (Array.isArray(filter.value) && filter.value.length > 0) {\n          filters.snapshots = filter.value as string[]\n        }\n        break\n      case 'region':\n      case 'target':\n        if (Array.isArray(filter.value) && filter.value.length > 0) {\n          filters.regions = filter.value as string[]\n        }\n        break\n      case 'labels':\n        if (Array.isArray(filter.value) && filter.value.length > 0) {\n          const labelObj: Record<string, string> = {}\n          filter.value.forEach((label: string) => {\n            const [key, value] = label.split(': ')\n            if (key && value) {\n              labelObj[key] = value\n            }\n          })\n          if (Object.keys(labelObj).length > 0) {\n            filters.labels = labelObj\n          }\n        }\n        break\n      case 'resources':\n        if (filter.value && typeof filter.value === 'object') {\n          const resourceValue = filter.value as {\n            cpu?: { min?: number; max?: number }\n            memory?: { min?: number; max?: number }\n            disk?: { min?: number; max?: number }\n          }\n\n          if (resourceValue.cpu?.min !== undefined) {\n            filters.minCpu = resourceValue.cpu.min\n          }\n          if (resourceValue.cpu?.max !== undefined) {\n            filters.maxCpu = resourceValue.cpu.max\n          }\n          if (resourceValue.memory?.min !== undefined) {\n            filters.minMemoryGiB = resourceValue.memory.min\n          }\n          if (resourceValue.memory?.max !== undefined) {\n            filters.maxMemoryGiB = resourceValue.memory.max\n          }\n          if (resourceValue.disk?.min !== undefined) {\n            filters.minDiskGiB = resourceValue.disk.min\n          }\n          if (resourceValue.disk?.max !== undefined) {\n            filters.maxDiskGiB = resourceValue.disk.max\n          }\n        }\n        break\n      case 'lastEvent':\n        if (Array.isArray(filter.value) && filter.value.length > 0) {\n          const dateRange = filter.value as (Date | undefined)[]\n          if (dateRange[0]) {\n            filters.lastEventAfter = dateRange[0]\n          }\n          if (dateRange[1]) {\n            filters.lastEventBefore = dateRange[1]\n          }\n        }\n        break\n    }\n  })\n\n  return filters\n}\n\nexport const convertApiSortingToTableSorting = (sorting: SandboxSorting): SortingState => {\n  if (!sorting.field || !sorting.direction) {\n    return [{ id: 'lastEvent', desc: true }]\n  }\n\n  let id: string\n  switch (sorting.field) {\n    case ListSandboxesPaginatedSortEnum.NAME:\n      id = 'name'\n      break\n    case ListSandboxesPaginatedSortEnum.STATE:\n      id = 'state'\n      break\n    case ListSandboxesPaginatedSortEnum.SNAPSHOT:\n      id = 'snapshot'\n      break\n    case ListSandboxesPaginatedSortEnum.REGION:\n      id = 'region'\n      break\n    case ListSandboxesPaginatedSortEnum.UPDATED_AT:\n      id = 'lastEvent'\n      break\n    case ListSandboxesPaginatedSortEnum.CREATED_AT:\n    default:\n      id = 'createdAt'\n      break\n  }\n\n  return [{ id, desc: sorting.direction === ListSandboxesPaginatedOrderEnum.DESC }]\n}\n\nexport const convertApiFiltersToTableFilters = (filters: SandboxFilters): ColumnFiltersState => {\n  const columnFilters: ColumnFiltersState = []\n\n  if (filters.idOrName) {\n    columnFilters.push({ id: 'name', value: filters.idOrName })\n  }\n\n  if (filters.states && filters.states.length > 0) {\n    columnFilters.push({ id: 'state', value: filters.states })\n  }\n\n  if (filters.snapshots && filters.snapshots.length > 0) {\n    columnFilters.push({ id: 'snapshot', value: filters.snapshots })\n  }\n\n  if (filters.regions && filters.regions.length > 0) {\n    columnFilters.push({ id: 'region', value: filters.regions })\n  }\n\n  if (filters.labels && Object.keys(filters.labels).length > 0) {\n    const labelArray = Object.entries(filters.labels).map(([key, value]) => `${key}: ${value}`)\n    columnFilters.push({ id: 'labels', value: labelArray })\n  }\n\n  // Convert resource filters back to table format\n  const resourceValue: {\n    cpu?: { min?: number; max?: number }\n    memory?: { min?: number; max?: number }\n    disk?: { min?: number; max?: number }\n  } = {}\n\n  if (filters.minCpu !== undefined || filters.maxCpu !== undefined) {\n    resourceValue.cpu = {}\n    if (filters.minCpu !== undefined) resourceValue.cpu.min = filters.minCpu\n    if (filters.maxCpu !== undefined) resourceValue.cpu.max = filters.maxCpu\n  }\n\n  if (filters.minMemoryGiB !== undefined || filters.maxMemoryGiB !== undefined) {\n    resourceValue.memory = {}\n    if (filters.minMemoryGiB !== undefined) resourceValue.memory.min = filters.minMemoryGiB\n    if (filters.maxMemoryGiB !== undefined) resourceValue.memory.max = filters.maxMemoryGiB\n  }\n\n  if (filters.minDiskGiB !== undefined || filters.maxDiskGiB !== undefined) {\n    resourceValue.disk = {}\n    if (filters.minDiskGiB !== undefined) resourceValue.disk.min = filters.minDiskGiB\n    if (filters.maxDiskGiB !== undefined) resourceValue.disk.max = filters.maxDiskGiB\n  }\n\n  if (Object.keys(resourceValue).length > 0) {\n    columnFilters.push({ id: 'resources', value: resourceValue })\n  }\n\n  // Convert date range filters back to table format\n  if (filters.lastEventAfter || filters.lastEventBefore) {\n    const dateRange: (Date | undefined)[] = [undefined, undefined]\n    if (filters.lastEventAfter) dateRange[0] = filters.lastEventAfter\n    if (filters.lastEventBefore) dateRange[1] = filters.lastEventBefore\n    columnFilters.push({ id: 'lastEvent', value: dateRange })\n  }\n\n  return columnFilters\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/useSandboxCommands.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { pluralize } from '@/lib/utils'\nimport { BulkActionCounts } from '@/lib/utils/sandbox'\nimport { ArchiveIcon, CheckSquare2Icon, MinusSquareIcon, PlayIcon, SquareIcon, TrashIcon } from 'lucide-react'\nimport { useMemo } from 'react'\nimport { CommandConfig, useRegisterCommands } from '../CommandPalette'\n\ninterface UseSandboxCommandsProps {\n  writePermitted: boolean\n  deletePermitted: boolean\n  selectedCount: number\n  totalCount: number\n  selectableCount: number\n  toggleAllRowsSelected: (selected: boolean) => void\n  bulkActionCounts: BulkActionCounts\n  onDelete: () => void\n  onStart: () => void\n  onStop: () => void\n  onArchive: () => void\n}\n\nexport function useSandboxCommands({\n  writePermitted,\n  deletePermitted,\n  selectedCount,\n  selectableCount,\n  totalCount,\n  toggleAllRowsSelected,\n  bulkActionCounts,\n  onDelete,\n  onStart,\n  onStop,\n  onArchive,\n}: UseSandboxCommandsProps) {\n  const rootCommands: CommandConfig[] = useMemo(() => {\n    const commands: CommandConfig[] = []\n\n    if (selectableCount !== selectedCount) {\n      commands.push({\n        id: 'select-all-sandboxes',\n        label: 'Select All Sandboxes',\n        icon: <CheckSquare2Icon className=\"w-4 h-4\" />,\n        onSelect: () => toggleAllRowsSelected(true),\n        chainable: true,\n      })\n    }\n\n    if (selectedCount > 0) {\n      commands.push({\n        id: 'deselect-all-sandboxes',\n        label: 'Deselect All Sandboxes',\n        icon: <MinusSquareIcon className=\"w-4 h-4\" />,\n        onSelect: () => toggleAllRowsSelected(false),\n        chainable: true,\n      })\n    }\n\n    if (writePermitted && bulkActionCounts.startable > 0) {\n      commands.push({\n        id: 'start-sandboxes',\n        label: `Start ${pluralize(bulkActionCounts.startable, 'Sandbox', 'Sandboxes')}`,\n        icon: <PlayIcon className=\"w-4 h-4\" />,\n        onSelect: onStart,\n      })\n    }\n\n    if (writePermitted && bulkActionCounts.stoppable > 0) {\n      commands.push({\n        id: 'stop-sandboxes',\n        label: `Stop ${pluralize(bulkActionCounts.stoppable, 'Sandbox', 'Sandboxes')}`,\n        icon: <SquareIcon className=\"w-4 h-4\" />,\n        onSelect: onStop,\n      })\n    }\n\n    if (writePermitted && bulkActionCounts.archivable > 0) {\n      commands.push({\n        id: 'archive-sandboxes',\n        label: `Archive ${pluralize(bulkActionCounts.archivable, 'Sandbox', 'Sandboxes')}`,\n        icon: <ArchiveIcon className=\"w-4 h-4\" />,\n        onSelect: onArchive,\n      })\n    }\n\n    if (deletePermitted && bulkActionCounts.deletable > 0) {\n      commands.push({\n        id: 'delete-sandboxes',\n        label: `Delete ${pluralize(bulkActionCounts.deletable, 'Sandbox', 'Sandboxes')}`,\n        icon: <TrashIcon className=\"w-4 h-4\" />,\n        onSelect: onDelete,\n      })\n    }\n\n    return commands\n  }, [\n    selectedCount,\n    selectableCount,\n    toggleAllRowsSelected,\n    writePermitted,\n    deletePermitted,\n    bulkActionCounts,\n    onDelete,\n    onStart,\n    onStop,\n    onArchive,\n  ])\n\n  useRegisterCommands(rootCommands, { groupId: 'sandbox-actions', groupLabel: 'Sandbox actions', groupOrder: 0 })\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SandboxTable/useSandboxTable.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox, Region } from '@daytonaio/api-client'\nimport {\n  useReactTable,\n  getCoreRowModel,\n  getFacetedRowModel,\n  getFacetedUniqueValues,\n  getPaginationRowModel,\n  VisibilityState,\n} from '@tanstack/react-table'\nimport { useMemo, useState, useEffect } from 'react'\nimport { FacetedFilterOption } from './types'\nimport { getColumns } from './columns'\nimport {\n  convertApiSortingToTableSorting,\n  convertApiFiltersToTableFilters,\n  convertTableSortingToApiSorting,\n  convertTableFiltersToApiFilters,\n} from './types'\nimport { SandboxFilters, SandboxSorting } from '@/hooks/useSandboxes'\nimport { LocalStorageKey } from '@/enums/LocalStorageKey'\nimport { getLocalStorageItem, setLocalStorageItem } from '@/lib/local-storage'\nimport { getRegionFullDisplayName } from '@/lib/utils'\n\ninterface UseSandboxTableProps {\n  data: Sandbox[]\n  sandboxIsLoading: Record<string, boolean>\n  writePermitted: boolean\n  deletePermitted: boolean\n  handleStart: (id: string) => void\n  handleStop: (id: string) => void\n  handleDelete: (id: string) => void\n  handleArchive: (id: string) => void\n  handleVnc: (id: string) => void\n  getWebTerminalUrl: (id: string) => Promise<string | null>\n  handleCreateSshAccess: (id: string) => void\n  handleRevokeSshAccess: (id: string) => void\n  handleScreenRecordings: (id: string) => void\n  pagination: {\n    pageIndex: number\n    pageSize: number\n  }\n  pageCount: number\n  onPaginationChange: (pagination: { pageIndex: number; pageSize: number }) => void\n  sorting: SandboxSorting\n  onSortingChange: (sorting: SandboxSorting) => void\n  filters: SandboxFilters\n  onFiltersChange: (filters: SandboxFilters) => void\n  regionsData: Region[]\n  handleRecover: (id: string) => void\n  getRegionName: (regionId: string) => string | undefined\n}\n\nexport function useSandboxTable({\n  data,\n  sandboxIsLoading,\n  writePermitted,\n  deletePermitted,\n  handleStart,\n  handleStop,\n  handleDelete,\n  handleArchive,\n  handleVnc,\n  getWebTerminalUrl,\n  handleCreateSshAccess,\n  handleRevokeSshAccess,\n  handleScreenRecordings,\n  pagination,\n  pageCount,\n  onPaginationChange,\n  sorting,\n  onSortingChange,\n  filters,\n  onFiltersChange,\n  regionsData,\n  handleRecover,\n  getRegionName,\n}: UseSandboxTableProps) {\n  // Column visibility state management with persistence\n  const [columnVisibility, setColumnVisibility] = useState<VisibilityState>(() => {\n    const saved = getLocalStorageItem(LocalStorageKey.SandboxTableColumnVisibility)\n    if (saved) {\n      try {\n        return JSON.parse(saved)\n      } catch {\n        return { id: false, labels: false }\n      }\n    }\n    return { id: false, labels: false }\n  })\n\n  useEffect(() => {\n    setLocalStorageItem(LocalStorageKey.SandboxTableColumnVisibility, JSON.stringify(columnVisibility))\n  }, [columnVisibility])\n\n  // Convert API sorting and filters to table format for internal use\n  const tableSorting = useMemo(() => convertApiSortingToTableSorting(sorting), [sorting])\n  const tableFilters = useMemo(() => convertApiFiltersToTableFilters(filters), [filters])\n\n  const regionOptions: FacetedFilterOption[] = useMemo(() => {\n    return regionsData.map((region) => ({\n      label: getRegionFullDisplayName(region),\n      value: region.id,\n    }))\n  }, [regionsData])\n\n  const columns = useMemo(\n    () =>\n      getColumns({\n        handleStart,\n        handleStop,\n        handleDelete,\n        handleArchive,\n        handleVnc,\n        getWebTerminalUrl,\n        sandboxIsLoading,\n        writePermitted,\n        deletePermitted,\n        handleCreateSshAccess,\n        handleRevokeSshAccess,\n        handleRecover,\n        getRegionName,\n        handleScreenRecordings,\n      }),\n    [\n      handleStart,\n      handleStop,\n      handleDelete,\n      handleArchive,\n      handleVnc,\n      getWebTerminalUrl,\n      sandboxIsLoading,\n      writePermitted,\n      deletePermitted,\n      handleCreateSshAccess,\n      handleRevokeSshAccess,\n      handleRecover,\n      getRegionName,\n      handleScreenRecordings,\n    ],\n  )\n\n  const table = useReactTable({\n    data,\n    columns,\n    manualFiltering: true,\n    onColumnFiltersChange: (updater) => {\n      const newTableFilters = typeof updater === 'function' ? updater(table.getState().columnFilters) : updater\n      const newApiFilters = convertTableFiltersToApiFilters(newTableFilters)\n      onFiltersChange(newApiFilters)\n    },\n    getCoreRowModel: getCoreRowModel(),\n    manualSorting: true,\n    onSortingChange: (updater) => {\n      const newTableSorting = typeof updater === 'function' ? updater(table.getState().sorting) : updater\n      const newApiSorting = convertTableSortingToApiSorting(newTableSorting)\n      onSortingChange(newApiSorting)\n    },\n    getFacetedRowModel: getFacetedRowModel(),\n    getFacetedUniqueValues: getFacetedUniqueValues(),\n    manualPagination: true,\n    pageCount: pageCount,\n    onPaginationChange: (updater) => {\n      const newPagination = typeof updater === 'function' ? updater(table.getState().pagination) : updater\n      onPaginationChange(newPagination)\n    },\n    getPaginationRowModel: getPaginationRowModel(),\n    state: {\n      sorting: tableSorting,\n      columnFilters: tableFilters,\n      columnVisibility,\n      pagination: {\n        pageIndex: pagination.pageIndex,\n        pageSize: pagination.pageSize,\n      },\n    },\n    onColumnVisibilityChange: setColumnVisibility,\n    defaultColumn: {\n      size: 100,\n    },\n    enableRowSelection: deletePermitted,\n    getRowId: (row) => row.id,\n  })\n\n  return {\n    table,\n    regionOptions,\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SelectionToast.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Separator } from '@/components/ui/separator'\nimport { cn, pluralize } from '@/lib/utils'\nimport { CommandIcon, XIcon } from 'lucide-react'\nimport { motion } from 'motion/react'\n\nexport function SelectionToast({\n  className,\n  selectedCount,\n  onClearSelection,\n  onActionClick,\n}: {\n  className?: string\n  selectedCount: number\n  onActionClick: () => void\n  onClearSelection: () => void\n}) {\n  return (\n    <motion.div\n      initial={{ scale: 0.9, opacity: 0, y: 20, x: '-50%' }}\n      animate={{ scale: 1, opacity: 1, y: 0, x: '-50%' }}\n      exit={{ scale: 0.9, opacity: 0, y: 20, x: '-50%' }}\n      className={cn('bg-popover  gap-3 max-w-[90vw]', className)}\n    >\n      <div className=\"bg-background text-foreground border border-border rounded-lg shadow-lg pl-3 pr-1 py-1 flex items-center justify-between gap-4\">\n        <div className=\"flex items-center gap-1\">\n          <div className=\"text-sm tabular-nums whitespace-nowrap\">\n            {pluralize(selectedCount, 'item', 'items')} selected\n          </div>\n          <Button variant=\"ghost\" size=\"icon-sm\" onClick={onClearSelection}>\n            <XIcon className=\"size-3.5\" />\n          </Button>\n        </div>\n        <Separator orientation=\"vertical\" className=\"h-5\" />\n\n        <Button variant=\"ghost\" size=\"sm\" className=\"h-8\" onClick={onActionClick}>\n          <CommandIcon className=\"size-3.5\" />\n          <span className=\"text-sm\">Actions</span>\n        </Button>\n      </div>\n    </motion.div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Sidebar.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Logo, LogoText } from '@/assets/Logo'\nimport { OrganizationPicker } from '@/components/Organizations/OrganizationPicker'\nimport {\n  Sidebar as SidebarComponent,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarHeader,\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarSeparator,\n  SidebarTrigger,\n  useSidebar,\n} from '@/components/ui/sidebar'\nimport { DAYTONA_DOCS_URL, DAYTONA_SLACK_URL } from '@/constants/ExternalLinks'\nimport { useTheme } from '@/contexts/ThemeContext'\nimport { FeatureFlags } from '@/enums/FeatureFlags'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useWebhookAppPortalAccessQuery } from '@/hooks/queries/useWebhookAppPortalAccessQuery'\nimport { useConfig } from '@/hooks/useConfig'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useUserOrganizationInvitations } from '@/hooks/useUserOrganizationInvitations'\nimport { useWebhooks } from '@/hooks/useWebhooks'\nimport { cn, getMetaKey } from '@/lib/utils'\nimport { usePylon, usePylonCommands } from '@/vendor/pylon'\nimport { OrganizationRolePermissionsEnum, OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport {\n  ArrowRightIcon,\n  BookOpen,\n  Box,\n  ChartColumn,\n  ChevronsUpDown,\n  Container,\n  CreditCard,\n  FlaskConical,\n  HardDrive,\n  Joystick,\n  KeyRound,\n  LifeBuoyIcon,\n  ListChecks,\n  LockKeyhole,\n  LogOut,\n  Mail,\n  MapPinned,\n  MoonIcon,\n  PackageOpen,\n  SearchIcon,\n  Server,\n  Settings,\n  Slack,\n  SquareUserRound,\n  SunIcon,\n  TextSearch,\n  Users,\n} from 'lucide-react'\nimport { useFeatureFlagEnabled, usePostHog } from 'posthog-js/react'\nimport React, { useMemo } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { Link, useLocation, useNavigate } from 'react-router-dom'\nimport { CommandConfig, useCommandPaletteActions, useRegisterCommands } from './CommandPalette'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from './ui/dropdown-menu'\nimport { Kbd } from './ui/kbd'\nimport { ScrollArea } from './ui/scroll-area'\n\ninterface SidebarProps {\n  isBannerVisible: boolean\n  billingEnabled: boolean\n  version: string\n}\n\ninterface SidebarItem {\n  icon: React.ReactElement\n  label: string\n  path: RoutePath | string\n  onClick?: () => void\n}\n\nconst useNavCommands = (items: { label: string; path: RoutePath | string; onClick?: () => void }[]) => {\n  const { pathname } = useLocation()\n  const navigate = useNavigate()\n\n  const navCommands: CommandConfig[] = useMemo(\n    () =>\n      items\n        .filter((item) => item.path !== pathname)\n        .map((item) => ({\n          id: `nav-${item.path}`,\n          label: `Go to ${item.label}`,\n          icon: <ArrowRightIcon className=\"w-4 h-4\" />,\n          onSelect: () => navigate(item.path),\n        })),\n    [pathname, navigate, items],\n  )\n\n  useRegisterCommands(navCommands, { groupId: 'navigation', groupLabel: 'Navigation', groupOrder: 1 })\n}\n\nexport function Sidebar({ isBannerVisible, billingEnabled, version }: SidebarProps) {\n  const posthog = usePostHog()\n  const config = useConfig()\n  const { theme, setTheme } = useTheme()\n  const { user, signoutRedirect } = useAuth()\n  const { pathname } = useLocation()\n  const sidebar = useSidebar()\n  const { selectedOrganization, authenticatedUserOrganizationMember, authenticatedUserHasPermission } =\n    useSelectedOrganization()\n  const { count: organizationInvitationsCount } = useUserOrganizationInvitations()\n  const { isInitialized: webhooksInitialized } = useWebhooks()\n  const webhooksAccess = useWebhookAppPortalAccessQuery(selectedOrganization?.id)\n  const orgInfraEnabled = useFeatureFlagEnabled(FeatureFlags.ORGANIZATION_INFRASTRUCTURE)\n  const organizationExperimentsEnabled = useFeatureFlagEnabled(FeatureFlags.ORGANIZATION_EXPERIMENTS)\n  const playgroundEnabled = useFeatureFlagEnabled(FeatureFlags.DASHBOARD_PLAYGROUND)\n  const webhooksEnabled = useFeatureFlagEnabled(FeatureFlags.DASHBOARD_WEBHOOKS)\n\n  const sidebarItems = useMemo(() => {\n    const arr: SidebarItem[] = [\n      {\n        icon: <Container size={16} strokeWidth={1.5} />,\n        label: 'Sandboxes',\n        path: RoutePath.SANDBOXES,\n      },\n      {\n        icon: <Box size={16} strokeWidth={1.5} />,\n        label: 'Snapshots',\n        path: RoutePath.SNAPSHOTS,\n      },\n      {\n        icon: <PackageOpen size={16} strokeWidth={1.5} />,\n        label: 'Registries',\n        path: RoutePath.REGISTRIES,\n      },\n    ]\n    if (authenticatedUserHasPermission(OrganizationRolePermissionsEnum.READ_VOLUMES)) {\n      arr.push({\n        icon: <HardDrive size={16} strokeWidth={1.5} />,\n        label: 'Volumes',\n        path: RoutePath.VOLUMES,\n      })\n    }\n\n    if (authenticatedUserHasPermission(OrganizationRolePermissionsEnum.READ_AUDIT_LOGS)) {\n      arr.push({\n        icon: <TextSearch size={16} strokeWidth={1.5} />,\n        label: 'Audit Logs',\n        path: RoutePath.AUDIT_LOGS,\n      })\n    }\n\n    return arr\n  }, [authenticatedUserHasPermission])\n\n  const settingsItems = useMemo(() => {\n    const arr: SidebarItem[] = [\n      {\n        icon: <Settings size={16} strokeWidth={1.5} />,\n        label: 'Settings',\n        path: RoutePath.SETTINGS,\n      },\n      { icon: <KeyRound size={16} strokeWidth={1.5} />, label: 'API Keys', path: RoutePath.KEYS },\n    ]\n\n    // Add Webhooks link if webhooks are initialized\n    if (webhooksInitialized) {\n      if (webhooksEnabled) {\n        arr.push({\n          icon: <Mail size={16} strokeWidth={1.5} />,\n          label: 'Webhooks',\n          path: RoutePath.WEBHOOKS,\n        })\n      } else {\n        arr.push({\n          icon: <Mail size={16} strokeWidth={1.5} />,\n          label: 'Webhooks',\n          path: '#webhooks' as any, // This will be handled by onClick\n          onClick: () => {\n            window.open(webhooksAccess.data?.url, '_blank', 'noopener,noreferrer')\n          },\n        })\n      }\n    }\n\n    if (authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER) {\n      arr.push({\n        icon: <LockKeyhole size={16} strokeWidth={1.5} />,\n        label: 'Limits',\n        path: RoutePath.LIMITS,\n      })\n    }\n    if (!selectedOrganization?.personal) {\n      arr.push({\n        icon: <Users size={16} strokeWidth={1.5} />,\n        label: 'Members',\n        path: RoutePath.MEMBERS,\n      })\n      // TODO: uncomment when we allow creating custom roles\n      // if (authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER) {\n      //   arr.push({ icon: <UserCog className=\"w-5 h-5\" />, label: 'Roles', path: RoutePath.ROLES })\n      // }\n    }\n\n    return arr\n  }, [\n    authenticatedUserOrganizationMember?.role,\n    selectedOrganization?.personal,\n    webhooksInitialized,\n    webhooksAccess.data?.url,\n    webhooksEnabled,\n  ])\n\n  const experimentalItems = useMemo(() => {\n    const arr: SidebarItem[] = []\n\n    if (\n      organizationExperimentsEnabled &&\n      authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER\n    ) {\n      arr.push({\n        icon: <FlaskConical size={16} strokeWidth={1.5} />,\n        label: 'Experimental',\n        path: RoutePath.EXPERIMENTAL,\n      })\n    }\n    return arr\n  }, [organizationExperimentsEnabled, authenticatedUserOrganizationMember?.role])\n\n  const billingItems = useMemo(() => {\n    if (!billingEnabled || authenticatedUserOrganizationMember?.role !== OrganizationUserRoleEnum.OWNER) {\n      return []\n    }\n\n    return [\n      {\n        icon: <ChartColumn size={16} strokeWidth={1.5} />,\n        label: 'Spending',\n        path: RoutePath.BILLING_SPENDING,\n      },\n      {\n        icon: <CreditCard size={16} strokeWidth={1.5} />,\n        label: 'Wallet',\n        path: RoutePath.BILLING_WALLET,\n      },\n    ]\n  }, [billingEnabled, authenticatedUserOrganizationMember?.role])\n\n  const infrastructureItems = useMemo(() => {\n    if (!orgInfraEnabled) {\n      return []\n    }\n\n    const arr = [\n      {\n        icon: <MapPinned size={16} strokeWidth={1.5} />,\n        label: 'Regions',\n        path: RoutePath.REGIONS,\n      },\n    ]\n\n    if (authenticatedUserHasPermission(OrganizationRolePermissionsEnum.READ_RUNNERS)) {\n      arr.push({\n        icon: <Server size={16} strokeWidth={1.5} />,\n        label: 'Runners',\n        path: RoutePath.RUNNERS,\n      })\n    }\n\n    return arr\n  }, [authenticatedUserHasPermission, orgInfraEnabled])\n\n  const handleSignOut = () => {\n    posthog?.reset()\n    signoutRedirect()\n  }\n\n  const miscItems = useMemo(() => {\n    if (!playgroundEnabled) {\n      return []\n    }\n\n    return [\n      playgroundEnabled && {\n        icon: <Joystick size={16} strokeWidth={1.5} />,\n        label: 'Playground',\n        path: RoutePath.PLAYGROUND,\n      },\n    ]\n  }, [playgroundEnabled])\n\n  const sidebarGroups: { label: string; items: SidebarItem[] }[] = useMemo(() => {\n    return [\n      { label: 'Sandboxes', items: sidebarItems },\n      {\n        label: 'Misc',\n        items: miscItems,\n      },\n      { label: 'Settings', items: settingsItems },\n      { label: 'Billing', items: billingItems },\n      { label: 'Infrastructure', items: infrastructureItems },\n      { label: 'Experimental', items: experimentalItems },\n    ].filter((group) => group.items.length > 0)\n  }, [sidebarItems, settingsItems, billingItems, infrastructureItems, experimentalItems, miscItems])\n\n  const commandItems = useMemo(() => {\n    return sidebarGroups\n      .flatMap((group) => group.items)\n      .concat(\n        {\n          path: RoutePath.ACCOUNT_SETTINGS,\n          label: 'Account Settings',\n          icon: <Settings size={16} strokeWidth={1.5} />,\n        },\n        {\n          path: RoutePath.USER_INVITATIONS,\n          label: 'Invitations',\n          icon: <Mail size={16} strokeWidth={1.5} />,\n        },\n        {\n          path: RoutePath.ONBOARDING,\n          label: 'Onboarding',\n          icon: <ListChecks size={16} strokeWidth={1.5} />,\n        },\n      )\n  }, [sidebarGroups])\n\n  const { unreadCount: pylonUnreadCount, toggle: togglePylon, isEnabled: pylonEnabled } = usePylon()\n  usePylonCommands()\n\n  const commandPaletteActions = useCommandPaletteActions()\n\n  useNavCommands(commandItems)\n\n  const metaKey = getMetaKey()\n\n  return (\n    <SidebarComponent isBannerVisible={isBannerVisible} collapsible=\"icon\">\n      <SidebarHeader>\n        <div\n          className={cn('flex justify-between items-center gap-2 px-2 mb-2 h-12', {\n            'justify-center px-0': !sidebar.open,\n          })}\n        >\n          <div className=\"flex items-center gap-2 group-data-[state=collapsed]:hidden text-primary\">\n            <Logo />\n            <LogoText />\n          </div>\n          <SidebarTrigger className=\"p-2 [&_svg]:size-5\" />\n        </div>\n        <SidebarMenu>\n          <OrganizationPicker />\n          <SidebarMenuItem className=\"mb-1\">\n            <SidebarMenuButton\n              tooltip={`Search ${metaKey}+K`}\n              variant=\"outline\"\n              className=\"flex items-center gap-2 justify-between dark:bg-input/30 dark:hover:bg-sidebar-accent hover:shadow-[0_0_0_1px_hsl(var(--sidebar-border))]\"\n              onClick={() => commandPaletteActions.setIsOpen(true)}\n            >\n              <span className=\"flex items-center gap-2\">\n                <SearchIcon className=\"w-4 h-4\" /> Search\n              </span>\n              <Kbd className=\"whitespace-nowrap\">{metaKey} K</Kbd>\n            </SidebarMenuButton>\n          </SidebarMenuItem>\n        </SidebarMenu>\n      </SidebarHeader>\n      <SidebarContent>\n        <ScrollArea fade=\"shadow\" className=\"overflow-auto flex-1\">\n          {sidebarGroups.map((group, i) => (\n            <React.Fragment key={group.label}>\n              {i > 0 && <SidebarSeparator />}\n              <SidebarGroup>\n                <SidebarGroupContent>\n                  <SidebarMenu>\n                    {group.items.map((item) => (\n                      <SidebarMenuItem key={item.label}>\n                        <SidebarMenuButton\n                          asChild\n                          isActive={pathname.startsWith(item.path)}\n                          className=\"text-sm\"\n                          tooltip={item.label}\n                        >\n                          {item.onClick ? (\n                            <button onClick={() => item.onClick?.()}>\n                              {item.icon}\n                              <span>{item.label}</span>\n                            </button>\n                          ) : (\n                            <Link to={item.path}>\n                              {item.icon}\n                              <span>{item.label}</span>\n                            </Link>\n                          )}\n                        </SidebarMenuButton>\n                      </SidebarMenuItem>\n                    ))}\n                  </SidebarMenu>\n                </SidebarGroupContent>\n              </SidebarGroup>\n            </React.Fragment>\n          ))}\n        </ScrollArea>\n      </SidebarContent>\n      <SidebarFooter className=\"pb-4\">\n        <SidebarMenu>\n          {pylonEnabled && (\n            <SidebarMenuItem>\n              <SidebarMenuButton\n                tooltip=\"Support\"\n                onClick={() => {\n                  togglePylon()\n                }}\n              >\n                <LifeBuoyIcon className=\"size-4\" strokeWidth={1.5} />\n                Support\n                {pylonUnreadCount > 0 && (\n                  <div className={cn('w-2 h-2 bg-green-500 rounded-full transition-all')}>\n                    <div className={cn('w-full h-full bg-green-500 rounded-full animate-ping')} />\n                  </div>\n                )}\n              </SidebarMenuButton>\n            </SidebarMenuItem>\n          )}\n          <SidebarMenuItem>\n            <SidebarMenuButton asChild tooltip=\"Slack\">\n              <a href={DAYTONA_SLACK_URL} className=\" h-8 py-0\" target=\"_blank\" rel=\"noopener noreferrer\">\n                <Slack size={16} strokeWidth={1.5} />\n                <span>Slack</span>\n              </a>\n            </SidebarMenuButton>\n          </SidebarMenuItem>\n          <SidebarMenuItem>\n            <SidebarMenuButton asChild tooltip=\"Docs\">\n              <a href={DAYTONA_DOCS_URL} className=\" h-8 py-0\" target=\"_blank\" rel=\"noopener noreferrer\">\n                <BookOpen size={16} strokeWidth={1.5} />\n                <span>Docs</span>\n              </a>\n            </SidebarMenuButton>\n          </SidebarMenuItem>\n          <SidebarMenuItem>\n            <DropdownMenu>\n              <DropdownMenuTrigger asChild>\n                <SidebarMenuButton\n                  className={cn(\n                    'flex flex-shrink-0 items-center outline outline-1 outline-border outline-offset-0 bg-muted font-medium mt-2',\n                    {\n                      'h-12': sidebar.open,\n                    },\n                  )}\n                  tooltip=\"Profile\"\n                >\n                  {user?.profile.picture ? (\n                    <img\n                      src={user.profile.picture}\n                      alt={user.profile.name || 'Profile picture'}\n                      className=\"h-4 w-4 rounded-sm flex-shrink-0\"\n                    />\n                  ) : (\n                    <SquareUserRound className=\"!w-4 !h-4  flex-shrink-0\" />\n                  )}\n                  <div className=\"flex-1 min-w-0\">\n                    <span className=\"truncate block\">{user?.profile.name || ''}</span>\n                    <span className=\"truncate block text-muted-foreground text-xs\">{user?.profile.email || ''}</span>\n                  </div>\n                  <ChevronsUpDown className=\"w-4 h-4 opacity-50 flex-shrink-0\" />\n                </SidebarMenuButton>\n              </DropdownMenuTrigger>\n              <DropdownMenuContent side=\"top\" align=\"start\" className=\"w-[--radix-popper-anchor-width] min-w-[12rem]\">\n                <DropdownMenuItem asChild className=\"cursor-pointer\">\n                  <Link to={RoutePath.ACCOUNT_SETTINGS}>\n                    <Settings className=\"size-4\" />\n                    Account Settings\n                  </Link>\n                </DropdownMenuItem>\n                <DropdownMenuItem\n                  className=\"cursor-pointer\"\n                  onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}\n                >\n                  {theme === 'dark' ? <SunIcon className=\"size-4\" /> : <MoonIcon className=\"size-4\" />}\n                  {theme === 'dark' ? 'Light mode' : 'Dark mode'}\n                </DropdownMenuItem>\n                <DropdownMenuSeparator />\n                <DropdownMenuItem asChild className=\"cursor-pointer\">\n                  <Link to={RoutePath.USER_INVITATIONS}>\n                    <Mail className=\"size-4\" />\n                    Invitations\n                    {organizationInvitationsCount > 0 && (\n                      <span className=\"ml-auto px-2 py-0.5 text-xs font-medium bg-secondary rounded-full\">\n                        {organizationInvitationsCount}\n                      </span>\n                    )}\n                  </Link>\n                </DropdownMenuItem>\n                <DropdownMenuItem asChild className=\"cursor-pointer\">\n                  <Link to={RoutePath.ONBOARDING}>\n                    <ListChecks className=\"size-4\" />\n                    Onboarding\n                  </Link>\n                </DropdownMenuItem>\n                <DropdownMenuSeparator />\n                <DropdownMenuItem className=\"cursor-pointer\" onClick={handleSignOut}>\n                  <LogOut className=\"size-4\" />\n                  Sign out\n                </DropdownMenuItem>\n              </DropdownMenuContent>\n            </DropdownMenu>\n          </SidebarMenuItem>\n          <SidebarMenuItem key=\"version\">\n            <div\n              className={cn(\n                'flex items-center w-full justify-center gap-2 mt-2 overflow-auto min-h-4 whitespace-nowrap',\n              )}\n            >\n              {sidebar.open && <span className=\"text-xs text-muted-foreground\">Version {version}</span>}\n            </div>\n          </SidebarMenuItem>\n        </SidebarMenu>\n      </SidebarFooter>\n    </SidebarComponent>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/SortIcon.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { ArrowDownIcon, ArrowUpDownIcon, ArrowUpIcon } from 'lucide-react'\n\ninterface Props {\n  sort: 'asc' | 'desc' | null\n  hideDefaultState?: boolean\n  className?: string\n}\n\nconst motionProps = {\n  initial: { opacity: 0, y: 6 },\n  animate: { opacity: 1, y: 0 },\n  exit: { opacity: 0, y: -6 },\n  transition: { duration: 0.15 },\n}\n\nconst PlaceholderIcon = () => <span className=\"size-4 inline-block\" />\n\nexport const SortOrderIcon = ({ hideDefaultState = false, sort, className }: Props) => {\n  const Icon =\n    sort === 'asc'\n      ? ArrowUpIcon\n      : sort === 'desc'\n        ? ArrowDownIcon\n        : hideDefaultState\n          ? PlaceholderIcon\n          : ArrowUpDownIcon\n\n  return (\n    <AnimatePresence mode=\"wait\" initial={false}>\n      <motion.span\n        key={sort || 'none'}\n        {...motionProps}\n        className={cn(\n          'flex items-center justify-center text-muted-foreground/60 transition-colors duration-150',\n          'group-hover/sort-header:text-current group-focus-visible/sort-header:text-current',\n          { 'text-foreground': sort },\n          className,\n        )}\n        aria-hidden=\"true\"\n      >\n        <Icon className=\"size-4\" />\n      </motion.span>\n    </AnimatePresence>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/TableColumnVisibilityToggle.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Column } from '@tanstack/react-table'\nimport { Command, CommandCheckboxItem, CommandGroup, CommandList } from './ui/command'\n\ninterface TableColumnVisibilityToggleProps {\n  columns: Column<any, unknown>[]\n  getColumnLabel: (id: string) => string\n}\n\nexport function TableColumnVisibilityToggle({ columns, getColumnLabel }: TableColumnVisibilityToggleProps) {\n  return (\n    <Command>\n      <CommandList>\n        <CommandGroup>\n          {columns\n            .filter((column) => column.getCanHide())\n            .map((column) => {\n              return (\n                <CommandCheckboxItem\n                  key={column.id}\n                  checked={column.getIsVisible()}\n                  onSelect={() => column.toggleVisibility()}\n                >\n                  {getColumnLabel(column.id)}\n                </CommandCheckboxItem>\n              )\n            })}\n        </CommandGroup>\n      </CommandList>\n    </Command>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/TableEmptyState.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { TableRow, TableCell } from './ui/table'\n\ninterface TableEmptyStateProps {\n  /**\n   * The number of columns in the table (used for colSpan)\n   */\n  colSpan: number\n  /**\n   * The message to display when no data is found\n   */\n  message: string\n  /**\n   * Optional icon to display above the message\n   */\n  icon?: React.ReactNode\n  /**\n   * Optional description text to display below the main message\n   */\n  description?: React.ReactNode\n  /**\n   * Additional CSS classes for the container\n   */\n  className?: string\n}\n\nexport function TableEmptyState({ colSpan, message, icon, description, className = '' }: TableEmptyStateProps) {\n  return (\n    <TableRow>\n      <TableCell colSpan={colSpan} className={`h-24 text-center ${className}`}>\n        <div className=\"flex flex-col items-center justify-center space-y-3 py-8\">\n          {icon && <div className=\"text-muted-foreground\">{icon}</div>}\n          <p className=\"text-muted-foreground font-medium\">{message}</p>\n          {description && <div className=\"text-sm text-muted-foreground/80 max-w-md\">{description}</div>}\n        </div>\n      </TableCell>\n    </TableRow>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/TierComparisonTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ComparisonSection, ComparisonTable } from './ComparisonTable'\n\nimport { OrganizationTier, Tier } from '@/billing-api'\nimport { TIER_RATE_LIMITS } from '@/constants/limits'\nimport { Skeleton } from './ui/skeleton'\n\nexport function TierComparisonTableSkeleton() {\n  return (\n    <div className=\"flex flex-col gap-4 p-4\">\n      {Array.from({ length: 5 }).map((_, index) => (\n        <Skeleton key={index} className=\"h-7 w-full\" />\n      ))}\n    </div>\n  )\n}\n\nexport function TierComparisonTable({\n  tiers,\n  currentTier,\n  className,\n}: {\n  tiers: Tier[]\n  currentTier?: OrganizationTier | null\n  className?: string\n}) {\n  return (\n    <ComparisonTable\n      className={className}\n      headerLabel=\"Tier\"\n      columns={[\n        'Compute (vCPU)',\n        'Memory (GiB)',\n        'Storage (GiB)',\n        'API Requests/min',\n        'Sandbox Creation/min',\n        'Sandbox Lifecycle/min',\n      ]}\n      currentRow={(currentTier?.tier || 1) - 1}\n      data={buildTierComparisonTableData(tiers || [])}\n    />\n  )\n}\n\nfunction buildTierComparisonTableData(tiers: Tier[]): ComparisonSection[] {\n  return [\n    {\n      id: 'tiers',\n      title: 'Tiers',\n      rows: tiers\n        .map((tier) => {\n          return {\n            label: <span className=\"whitespace-nowrap\">{tier.tier}</span>,\n            values: [\n              `${tier.tierLimit.concurrentCPU}`,\n              `${tier.tierLimit.concurrentRAMGiB}`,\n              `${tier.tierLimit.concurrentDiskGiB}`,\n              `${TIER_RATE_LIMITS[tier.tier]?.authenticatedRateLimit.toLocaleString() || '-'}`,\n              `${TIER_RATE_LIMITS[tier.tier]?.sandboxCreateRateLimit.toLocaleString() || '-'}`,\n              `${TIER_RATE_LIMITS[tier.tier]?.sandboxLifecycleRateLimit.toLocaleString() || '-'}`,\n            ],\n          }\n        })\n        .concat({\n          label: <span className=\"whitespace-nowrap\">Enterprise</span>,\n          values: Array(6).fill('Custom'),\n        }),\n    },\n  ]\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/TierUpgradeCard.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OrganizationTier, Tier } from '@/billing-api'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useDowngradeTierMutation } from '@/hooks/mutations/useDowngradeTierMutation'\nimport { useUpgradeTierMutation } from '@/hooks/mutations/useUpgradeTierMutation'\nimport { handleApiError } from '@/lib/error-handling'\nimport { cn } from '@/lib/utils'\nimport { Organization } from '@daytonaio/api-client/src'\nimport { CheckIcon, ExternalLinkIcon, Loader2 } from 'lucide-react'\nimport { useMemo } from 'react'\nimport { Link } from 'react-router-dom'\nimport { toast } from 'sonner'\n\ninterface Props {\n  tiers: Tier[]\n  organizationTier?: OrganizationTier | null\n  organization: Organization\n  requirementsState: {\n    emailVerified: boolean\n    creditCardLinked: boolean\n  }\n}\n\nexport function TierUpgradeCard({ tiers, organizationTier, requirementsState, organization }: Props) {\n  const { currentTier, previousTier, nextTier } = useMemo(() => {\n    const targetTiers: { currentTier?: Tier; previousTier?: Tier; nextTier?: Tier } = {}\n    for (const tier of tiers) {\n      if (tier.tier === organizationTier?.tier) {\n        targetTiers.currentTier = tier\n      }\n      if (tier.tier < (organizationTier?.tier || 0)) {\n        targetTiers.previousTier = tier\n      }\n      if (tier.tier > (organizationTier?.tier || 0) && !targetTiers.nextTier) {\n        targetTiers.nextTier = tier\n      }\n    }\n    return targetTiers\n  }, [tiers, organizationTier])\n\n  const requirements = getTierRequirementItems(requirementsState, organizationTier, nextTier)\n\n  const canUpgrade = requirements.length > 0 && requirements.every((requirement) => requirement.isChecked)\n\n  const downgradeTier = useDowngradeTierMutation()\n  const upgradeTier = useUpgradeTierMutation()\n\n  const handleUpgradeTier = async (tier: number) => {\n    if (!organization) {\n      return\n    }\n\n    try {\n      await upgradeTier.mutateAsync({ organizationId: organization.id, tier })\n      toast.success('Tier upgraded successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to upgrade organization tier')\n    }\n  }\n\n  const handleDowngradeTier = async (tier: number) => {\n    if (!organization) {\n      return\n    }\n\n    try {\n      await downgradeTier.mutateAsync({ organizationId: organization.id, tier })\n      toast.success('Tier downgraded successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to downgrade organization tier')\n    }\n  }\n\n  return (\n    <Card>\n      <CardContent className=\"p-0\">\n        {nextTier && (\n          <div className=\"grid sm:grid-cols-2 grid-cols-1\">\n            <div className=\"p-4 flex flex-col gap-1\">\n              <div className=\"text-lg font-medium\">Upgrade to Tier {nextTier?.tier}</div>\n              <div className=\"text-muted-foreground text-sm\">\n                Unlock more resources and higher rate limits by completing the verification steps.\n              </div>\n            </div>\n            <div className=\"sm:border-l border-border p-4 flex flex-col gap-2\">\n              <div className=\"text-xs text-muted-foreground\">Requirements</div>\n              <ul>\n                {requirements.map((requirement) => (\n                  <li key={requirement.label}>\n                    <TierRequirementItem\n                      checked={requirement.isChecked}\n                      label={requirement.label}\n                      link={requirement.link}\n                    />\n                  </li>\n                ))}\n              </ul>\n              {requirements.length && !canUpgrade && (\n                <div className=\"text-xs text-muted-foreground\">Please complete all requirements to upgrade.</div>\n              )}\n              <Button\n                className=\"w-full mt-4\"\n                onClick={() => handleUpgradeTier(nextTier.tier)}\n                disabled={!canUpgrade || upgradeTier.isPending}\n              >\n                {upgradeTier.isPending && <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />}\n                Upgrade\n              </Button>\n            </div>\n          </div>\n        )}\n        <div className=\"p-4 border-t border-border flex items-center justify-between gap-2\">\n          <div className=\"flex flex-col gap-1 text-sm\">\n            <div className=\"font-medium\">Enterprise</div>\n            <div className=\"text-muted-foreground\">\n              Contact sales at{' '}\n              <a href=\"mailto:sales@daytona.io\" className=\"hover:text-foreground underline\">\n                sales@daytona.io\n              </a>\n              .\n            </div>\n          </div>\n\n          <Button variant={organizationTier?.tier && organizationTier.tier > 2 ? 'default' : 'secondary'} asChild>\n            <a href=\"mailto:sales@daytona.io?subject=Custom%20Tier%20Inquiry&body=Hi%20Daytona%20Team%2C%0A%0AI%27m%20interested%20in%20a%20custom%20plan%20and%20would%20like%20to%20learn%20more%20about%20your%20options.%0A%0AHere%27s%20some%20context%3A%0A%0A-%20Your%20use%20case%3A%20%0A-%20Current%20technology%3A%20%0A-%20Requirements%3A%20%0A-%20Typical%20sandbox%20size%3A%20%0A-%20Peak%20concurrent%20sandboxes%3A%20%0A%0AThanks.\">\n              Contact Sales\n            </a>\n          </Button>\n        </div>\n        {organizationTier && (\n          <div className=\"border-t border-border p-4 flex items-center justify-between gap-2\">\n            <div className=\"flex flex-col gap-1 text-sm\">\n              <div className=\"font-medium\">Current Tier: {organizationTier?.tier}</div>\n              <div className=\"text-muted-foreground empty:hidden flex flex-col\">\n                {organizationTier.expiresAt && (\n                  <div>\n                    Tier expires on{' '}\n                    {organizationTier.expiresAt.toLocaleDateString('en-US', {\n                      month: 'short',\n                      day: 'numeric',\n                    })}\n                    .\n                  </div>\n                )}\n                {currentTier && currentTier?.topUpIntervalDays > 0 && (\n                  <div>\n                    Automatically charged {getDollarAmount(currentTier.minTopUpAmountCents)} every{' '}\n                    {currentTier.topUpIntervalDays} days.\n                  </div>\n                )}\n              </div>\n            </div>\n            {previousTier && (\n              <Button\n                variant=\"outline\"\n                onClick={() => handleDowngradeTier(previousTier.tier)}\n                disabled={downgradeTier.isPending}\n              >\n                {downgradeTier.isPending && <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />}\n                Downgrade\n              </Button>\n            )}\n          </div>\n        )}\n      </CardContent>\n    </Card>\n  )\n}\n\nfunction getDollarAmount(cents: number) {\n  return new Intl.NumberFormat('en-US', {\n    style: 'currency',\n    currency: 'USD',\n    minimumFractionDigits: 0,\n    maximumFractionDigits: 0,\n  }).format(cents / 100)\n}\n\nfunction checkTopUpRequirementStatus(currentTier: OrganizationTier, nextTier: Tier) {\n  if (!currentTier) {\n    return false\n  }\n\n  if (currentTier.largestSuccessfulPaymentCents < nextTier.minTopUpAmountCents) {\n    return false\n  }\n\n  if (nextTier.topUpIntervalDays && currentTier.largestSuccessfulPaymentDate) {\n    const diffTime = Math.abs(Date.now() - (currentTier.largestSuccessfulPaymentDate?.getTime() || 0))\n    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24))\n\n    return diffDays < nextTier.topUpIntervalDays\n  }\n\n  return true\n}\n\nfunction getTierRequirementItems(\n  requirementsState: {\n    emailVerified: boolean\n    creditCardLinked: boolean\n  },\n  currentTier?: OrganizationTier | null,\n  tier?: Tier | null,\n) {\n  if (!tier || !currentTier) {\n    return []\n  }\n  if (tier.tier < 1 || tier.tier > 4) {\n    return []\n  }\n\n  const items = []\n\n  if (tier.tier === 1) {\n    items.push({\n      label: 'Email verification',\n      isChecked: requirementsState.emailVerified,\n      link: RoutePath.ACCOUNT_SETTINGS,\n    })\n  }\n  if (tier.tier === 2) {\n    items.push({\n      label: 'Credit card linked',\n      isChecked: requirementsState.creditCardLinked,\n      link: RoutePath.BILLING_WALLET,\n    })\n  }\n\n  if (tier.minTopUpAmountCents) {\n    items.push({\n      label: `Top up ${getDollarAmount(tier.minTopUpAmountCents)} (${tier.topUpIntervalDays ? `every ${tier.topUpIntervalDays} days` : 'one time'})`,\n      isChecked: checkTopUpRequirementStatus(currentTier, tier),\n      link: RoutePath.BILLING_WALLET,\n    })\n  }\n\n  return items\n}\n\ninterface TierRequirementItemProps {\n  checked: boolean\n  label: string\n  link?: string\n  externalLink?: boolean\n}\n\nfunction RequirementIcon({ checked, label }: { checked: boolean; label: string }) {\n  return (\n    <div\n      className={cn(\n        'flex-shrink-0 w-3.5 h-3.5 rounded-full flex items-center justify-center border border-muted-foreground/50',\n        {\n          'bg-muted/50 text-foreground': checked,\n          'text-transparent': !checked,\n        },\n      )}\n    >\n      <CheckIcon size={10} aria-label={label} />\n    </div>\n  )\n}\n\nfunction TierRequirementItem({ checked, label, link, externalLink }: TierRequirementItemProps) {\n  const content = (\n    <span className=\"flex items-center gap-2 text-sm\">\n      <RequirementIcon checked={checked} label={label} />\n      <span\n        className={cn({\n          'text-muted-foreground line-through': checked,\n          'text-foreground': !checked,\n          'hover:underline': !checked && link,\n        })}\n      >\n        {label}\n      </span>\n      {!checked && externalLink && (\n        <ExternalLinkIcon size={16} className=\"inline align-text-bottom\" aria-label={label} />\n      )}\n    </span>\n  )\n\n  if (!checked && link) {\n    return (\n      <div\n        className={cn({\n          'text-foreground': checked,\n          'text-muted-foreground': !checked,\n          'hover:underline': !checked && link,\n        })}\n      >\n        <Link to={link}>{content}</Link>\n      </div>\n    )\n  }\n\n  return <div className={cn(checked ? 'text-foreground' : 'text-muted-foreground')}>{content}</div>\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/TimestampTooltip.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { format, formatDistanceToNow } from 'date-fns'\nimport { ReactNode } from 'react'\nimport { Separator } from './ui/separator'\nimport { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'\n\ninterface TimestampTooltipProps {\n  timestamp?: string\n  children: ReactNode\n  time?: boolean\n}\n\nexport const TimestampTooltip = ({ children, timestamp, time = true }: TimestampTooltipProps) => {\n  if (!timestamp) {\n    return children\n  }\n\n  const date = new Date(timestamp)\n  const relativeTimeString = formatDistanceToNow(date, { addSuffix: true })\n\n  const dateFormat = 'MMM d, yyyy'\n  const timeFormat = 'HH:mm:ss'\n\n  const utcDate = new Date(\n    date.getUTCFullYear(),\n    date.getUTCMonth(),\n    date.getUTCDate(),\n    date.getUTCHours(),\n    date.getUTCMinutes(),\n    date.getUTCSeconds(),\n  )\n  const utcDateFormatted = format(utcDate, dateFormat)\n  const utcTimeFormatted = format(utcDate, timeFormat)\n\n  const localDateFormatted = format(date, dateFormat)\n  const localTimeFormatted = format(date, timeFormat)\n\n  const timezoneFormatter = new Intl.DateTimeFormat('en-US', {\n    timeZoneName: 'short',\n  })\n  const timezoneParts = timezoneFormatter.formatToParts(date)\n  const localTimezone = timezoneParts.find((part) => part.type === 'timeZoneName')?.value || 'Local'\n\n  return (\n    <Tooltip>\n      <TooltipTrigger>{children}</TooltipTrigger>\n      <TooltipContent className=\"flex flex-col gap-1.5 text-xs\">\n        <div className=\"font-medium first-letter:capitalize\">{relativeTimeString}</div>\n        <Separator className=\"-mx-3 w-[calc(100%+1.5rem)]\" />\n        <table className=\"border-collapse border-0\">\n          <tbody>\n            <tr>\n              <td className=\"text-muted-foreground pr-2 border-0\">[UTC]</td>\n              <td className=\"border-0 pr-2\">{utcDateFormatted}</td>\n              {time && <td className=\"border-0 text-muted-foreground\">{utcTimeFormatted}</td>}\n            </tr>\n            <tr>\n              <td className=\"text-muted-foreground pr-2 border-0\">[{localTimezone}]</td>\n              <td className=\"border-0 pr-2\">{localDateFormatted}</td>\n              {time && <td className=\"border-0 text-muted-foreground\">{localTimeFormatted}</td>}\n            </tr>\n          </tbody>\n        </table>\n      </TooltipContent>\n    </Tooltip>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Tooltip.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { TooltipContent, TooltipTrigger, Tooltip as UiTooltip } from '@/components/ui/tooltip'\nimport React from 'react'\n\nexport function Tooltip({\n  label,\n  content,\n  side = 'top',\n  contentClassName,\n}: {\n  label: React.ReactNode\n  content: React.ReactNode\n  side?: 'right' | 'left' | 'top' | 'bottom'\n  contentClassName?: string\n}) {\n  return (\n    <UiTooltip>\n      <TooltipTrigger asChild>{label}</TooltipTrigger>\n      <TooltipContent side={side} className={contentClassName}>\n        {content}\n      </TooltipContent>\n    </UiTooltip>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/TooltipButton.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ComponentProps, ReactNode } from 'react'\nimport { Button } from './ui/button'\nimport { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'\n\ntype Props = ComponentProps<typeof Button> & {\n  tooltipText: string\n  tooltipContent?: ReactNode\n  tooltipContainer?: HTMLElement\n  side?: ComponentProps<typeof TooltipContent>['side']\n}\n\nfunction TooltipButton({\n  tooltipText,\n  tooltipContent,\n  side = 'top',\n  tooltipContainer,\n  ref,\n  size = 'icon-sm',\n  ...props\n}: Props) {\n  return (\n    <Tooltip delayDuration={0}>\n      <TooltipTrigger asChild>\n        <Button ref={ref} {...props} size={size} aria-label={tooltipText} />\n      </TooltipTrigger>\n      <TooltipContent side={side}>{tooltipContent || <div>{tooltipText}</div>}</TooltipContent>\n    </Tooltip>\n  )\n}\n\nexport default TooltipButton\n"
  },
  {
    "path": "apps/dashboard/src/components/UpdateRegionDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useEffect, useMemo } from 'react'\nimport { Region, UpdateRegion } from '@daytonaio/api-client'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\n\ninterface UpdateRegionDialogProps {\n  region: Region\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onUpdateRegion: (regionId: string, data: UpdateRegion) => Promise<boolean>\n  loading: boolean\n}\n\nexport const UpdateRegionDialog: React.FC<UpdateRegionDialogProps> = ({\n  region,\n  open,\n  onOpenChange,\n  onUpdateRegion,\n  loading,\n}) => {\n  const [formData, setFormData] = useState({\n    proxyUrl: region.proxyUrl || '',\n    sshGatewayUrl: region.sshGatewayUrl || '',\n    snapshotManagerUrl: region.snapshotManagerUrl || '',\n  })\n\n  // Reset form when dialog opens with new region\n  useEffect(() => {\n    if (open) {\n      setFormData({\n        proxyUrl: region.proxyUrl || '',\n        sshGatewayUrl: region.sshGatewayUrl || '',\n        snapshotManagerUrl: region.snapshotManagerUrl || '',\n      })\n    }\n  }, [open, region])\n\n  const hasChanges = useMemo(() => {\n    const proxyChanged = (formData.proxyUrl.trim() || null) !== (region.proxyUrl || null)\n    const sshGatewayChanged = (formData.sshGatewayUrl.trim() || null) !== (region.sshGatewayUrl || null)\n    const snapshotManagerChanged = (formData.snapshotManagerUrl.trim() || null) !== (region.snapshotManagerUrl || null)\n    return proxyChanged || sshGatewayChanged || snapshotManagerChanged\n  }, [formData, region])\n\n  const handleUpdate = async () => {\n    // Only include changed fields\n    const updateData: UpdateRegion = {}\n\n    const proxyUrlValue = formData.proxyUrl.trim() || null\n    const sshGatewayUrlValue = formData.sshGatewayUrl.trim() || null\n    const snapshotManagerUrlValue = formData.snapshotManagerUrl.trim() || null\n\n    if (proxyUrlValue !== (region.proxyUrl || null)) {\n      updateData.proxyUrl = proxyUrlValue\n    }\n    if (sshGatewayUrlValue !== (region.sshGatewayUrl || null)) {\n      updateData.sshGatewayUrl = sshGatewayUrlValue\n    }\n    if (snapshotManagerUrlValue !== (region.snapshotManagerUrl || null)) {\n      updateData.snapshotManagerUrl = snapshotManagerUrlValue\n    }\n\n    const success = await onUpdateRegion(region.id, updateData)\n    if (success) {\n      onOpenChange(false)\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent className=\"max-w-2xl\">\n        <DialogHeader>\n          <DialogTitle>Update Region: {region.name}</DialogTitle>\n          <DialogDescription>Modify the URLs for this region.</DialogDescription>\n        </DialogHeader>\n\n        <form\n          id=\"update-region-form\"\n          className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n          onSubmit={async (e) => {\n            e.preventDefault()\n            await handleUpdate()\n          }}\n        >\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"proxy-url\">Proxy URL</Label>\n            <Input\n              id=\"proxy-url\"\n              value={formData.proxyUrl}\n              onChange={(e) => {\n                setFormData((prev) => ({ ...prev, proxyUrl: e.target.value }))\n              }}\n              placeholder=\"https://proxy.example.com\"\n            />\n            <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n              (Optional) URL of the custom proxy for this region\n            </p>\n          </div>\n\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"ssh-gateway-url\">SSH gateway URL</Label>\n            <Input\n              id=\"ssh-gateway-url\"\n              value={formData.sshGatewayUrl}\n              onChange={(e) => {\n                setFormData((prev) => ({ ...prev, sshGatewayUrl: e.target.value }))\n              }}\n              placeholder=\"https://ssh-gateway.example.com\"\n            />\n            <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n              (Optional) URL of the custom SSH gateway for this region\n            </p>\n          </div>\n\n          <div className=\"space-y-3\">\n            <Label htmlFor=\"snapshot-manager-url\">Snapshot manager URL</Label>\n            <Input\n              id=\"snapshot-manager-url\"\n              value={formData.snapshotManagerUrl}\n              onChange={(e) => {\n                setFormData((prev) => ({ ...prev, snapshotManagerUrl: e.target.value }))\n              }}\n              placeholder=\"https://snapshot-manager.example.com\"\n            />\n            <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n              (Optional) URL of the custom snapshot manager for this region. Cannot be changed if snapshots exist in\n              this region.\n            </p>\n          </div>\n        </form>\n\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\">\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Updating...\n            </Button>\n          ) : (\n            <Button type=\"submit\" form=\"update-region-form\" variant=\"default\" disabled={loading || !hasChanges}>\n              Update\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/UsageOverview.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { RegionUsageOverview } from '@daytonaio/api-client'\nimport QuotaLine from './QuotaLine'\nimport { Skeleton } from './ui/skeleton'\n\nexport function UsageOverview({\n  usageOverview,\n  className,\n}: {\n  usageOverview: RegionUsageOverview\n  className?: string\n}) {\n  return (\n    <div className={cn('flex gap-4 [&>*]:flex-1 flex-col lg:flex-row', className)}>\n      <div className=\"flex flex-col gap-1\">\n        <div className=\"w-full flex justify-between gap-2\">\n          <div className=\"text-muted-foreground text-xs\">Compute</div>\n          <UsageLabel current={usageOverview.currentCpuUsage} total={usageOverview.totalCpuQuota} unit=\"vCPU\" />\n        </div>\n        <QuotaLine current={usageOverview.currentCpuUsage} total={usageOverview.totalCpuQuota} />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <div className=\"w-full flex justify-between gap-2\">\n          <div className=\"text-muted-foreground text-xs\">Memory</div>\n          <UsageLabel current={usageOverview.currentMemoryUsage} total={usageOverview.totalMemoryQuota} unit=\"GiB\" />\n        </div>\n        <QuotaLine current={usageOverview.currentMemoryUsage} total={usageOverview.totalMemoryQuota} />\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <div className=\"w-full flex justify-between gap-2\">\n          <div className=\"text-muted-foreground text-xs\">Storage</div>\n          <UsageLabel current={usageOverview.currentDiskUsage} total={usageOverview.totalDiskQuota} unit=\"GiB\" />\n        </div>\n        <QuotaLine current={usageOverview.currentDiskUsage} total={usageOverview.totalDiskQuota} />\n      </div>\n    </div>\n  )\n}\n\nexport function UsageOverviewSkeleton() {\n  return (\n    <div className=\"flex flex-col gap-3 p-4 lg:flex-row\">\n      <Skeleton className=\"h-8 w-full\" />\n      <Skeleton className=\"h-8 w-full\" />\n      <Skeleton className=\"h-8 w-full\" />\n    </div>\n  )\n}\n\nconst UsageLabel = ({ current, total, unit }: { current: number; total: number; unit: string }) => {\n  const percentage = (current / total) * 100\n  const isHighUsage = percentage > 90\n\n  return (\n    <span\n      className={cn('text-xs text-nowrap', {\n        'text-destructive': isHighUsage,\n      })}\n    >\n      {current} <span className=\"opacity-50\">/</span> {total} {unit}\n    </span>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/UsageOverviewIndicator.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport { RegionUsageOverview } from '@daytonaio/api-client/src'\n\nexport function UsageOverviewIndicator({\n  usage,\n  className,\n  isLive,\n}: {\n  usage: RegionUsageOverview\n  className?: string\n  isLive?: boolean\n}) {\n  return (\n    <div className={cn('flex gap-4 items-center', className)}>\n      {isLive && <LiveIndicatorDot />}\n      <ResourceLabel value={usage.currentCpuUsage} total={usage.totalCpuQuota} unit=\"vCPU\" />\n      <ResourceLabel value={usage.currentMemoryUsage} total={usage.totalMemoryQuota} unit=\"GiB\" name=\"RAM\" />\n      <ResourceLabel value={usage.currentDiskUsage} total={usage.totalDiskQuota} unit=\"GiB\" name=\"Storage\" />\n    </div>\n  )\n}\n\nfunction ResourceLabel({ value, total, unit, name }: { value: number; total: number; unit?: string; name?: string }) {\n  return (\n    <span className=\"text-sm flex gap-1 items-center text-muted-foreground/70 font-mono uppercase\">\n      {name}\n      <span className=\"text-foreground\">{value}</span>/<span className=\"text-foreground\">{total}</span>\n      {unit}\n    </span>\n  )\n}\n\nfunction LiveIndicatorDot({ className }: { className?: string }) {\n  return (\n    <div className={cn('relative grid place-items-center h-2 w-2', className)}>\n      <div className=\"animate-ping h-2 w-2 bg-green-500 rounded-full absolute \" />\n      <div className=\"h-2 w-2 bg-green-500 rounded-full \" />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/UserOrganizationInvitations/DeclineOrganizationInvitationDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\n\ninterface DeclineOrganizationInvitationDialogProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onDeclineInvitation: () => Promise<boolean>\n  loading: boolean\n}\n\nexport const DeclineOrganizationInvitationDialog: React.FC<DeclineOrganizationInvitationDialogProps> = ({\n  open,\n  onOpenChange,\n  onDeclineInvitation,\n  loading,\n}) => {\n  const handleDeclineInvitation = async () => {\n    const success = await onDeclineInvitation()\n    if (success) {\n      onOpenChange(false)\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Decline Invitation</DialogTitle>\n          <DialogDescription>\n            Are you sure you want to decline this invitation to join the organization?\n          </DialogDescription>\n        </DialogHeader>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\" disabled={loading}>\n              Cancel\n            </Button>\n          </DialogClose>\n          {loading ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Declining...\n            </Button>\n          ) : (\n            <Button variant=\"destructive\" onClick={handleDeclineInvitation}>\n              Decline\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/UserOrganizationInvitations/OrganizationInvitationActionDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState } from 'react'\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\nimport { OrganizationInvitation } from '@daytonaio/api-client'\n\ninterface OrganizationInvitationActionDialogProps {\n  invitation: OrganizationInvitation\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onAccept: (invitation: OrganizationInvitation) => Promise<boolean>\n  onDecline: (invitation: OrganizationInvitation) => Promise<boolean>\n}\n\nexport const OrganizationInvitationActionDialog: React.FC<OrganizationInvitationActionDialogProps> = ({\n  invitation,\n  open,\n  onOpenChange,\n  onAccept,\n  onDecline,\n}) => {\n  const [loadingAccept, setLoadingAccept] = useState(false)\n  const [loadingDecline, setLoadingDecline] = useState(false)\n\n  const handleAccept = async () => {\n    setLoadingAccept(true)\n    const success = await onAccept(invitation)\n    if (success) {\n      onOpenChange(false)\n    }\n    setLoadingAccept(false)\n  }\n\n  const handleDecline = async () => {\n    setLoadingDecline(true)\n    const success = await onDecline(invitation)\n    if (success) {\n      onOpenChange(false)\n    }\n    setLoadingDecline(false)\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Organization Invitation</DialogTitle>\n          <DialogDescription>Would you like to accept or decline this invitation?</DialogDescription>\n        </DialogHeader>\n        <div>\n          <div className=\"grid grid-cols-[120px_1fr] gap-2\">\n            <span className=\"text-muted-foreground\">Organization:</span>\n            <span className=\"font-medium\">{invitation.organizationName}</span>\n\n            <span className=\"text-muted-foreground\">Invited by:</span>\n            <span className=\"font-medium\">{invitation.invitedBy || 'Not specified'}</span>\n\n            <span className=\"text-muted-foreground\">Expires:</span>\n            <span className=\"font-medium\">\n              {new Date(invitation.expiresAt).toLocaleString('default', {\n                year: 'numeric',\n                month: 'numeric',\n                day: 'numeric',\n                hour: 'numeric',\n                minute: '2-digit',\n              })}\n            </span>\n          </div>\n        </div>\n        <DialogFooter>\n          {loadingDecline ? (\n            <Button type=\"button\" variant=\"secondary\" disabled>\n              Declining...\n            </Button>\n          ) : (\n            <Button type=\"button\" variant=\"secondary\" onClick={handleDecline} disabled={loadingAccept}>\n              Decline\n            </Button>\n          )}\n          {loadingAccept ? (\n            <Button type=\"button\" variant=\"default\" disabled>\n              Accepting...\n            </Button>\n          ) : (\n            <Button type=\"button\" variant=\"default\" onClick={handleAccept} disabled={loadingDecline}>\n              Accept\n            </Button>\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/UserOrganizationInvitations/UserOrganizationInvitationTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useState } from 'react'\nimport { Check, X } from 'lucide-react'\nimport {\n  ColumnDef,\n  flexRender,\n  getCoreRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { OrganizationInvitation } from '@daytonaio/api-client'\nimport { Pagination } from '@/components/Pagination'\nimport { Button } from '@/components/ui/button'\nimport { TableHeader, TableRow, TableHead, TableBody, TableCell, Table } from '@/components/ui/table'\nimport { DeclineOrganizationInvitationDialog } from '@/components/UserOrganizationInvitations/DeclineOrganizationInvitationDialog'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { TableEmptyState } from '../TableEmptyState'\n\ninterface DataTableProps {\n  data: OrganizationInvitation[]\n  loadingData: boolean\n  onAcceptInvitation: (invitation: OrganizationInvitation) => Promise<boolean>\n  onDeclineInvitation: (invitation: OrganizationInvitation) => Promise<boolean>\n  loadingInvitationAction: Record<string, boolean>\n}\n\nexport function UserOrganizationInvitationTable({\n  data,\n  loadingData,\n  onAcceptInvitation,\n  onDeclineInvitation,\n  loadingInvitationAction,\n}: DataTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [invitationToDecline, setInvitationToDecline] = useState<OrganizationInvitation | null>(null)\n  const [isDeclineDialogOpen, setIsDeclineDialogOpen] = useState(false)\n\n  const handleDecline = (invitation: OrganizationInvitation) => {\n    setInvitationToDecline(invitation)\n    setIsDeclineDialogOpen(true)\n  }\n\n  const handleConfirmDecline = async () => {\n    if (invitationToDecline) {\n      const success = await onDeclineInvitation(invitationToDecline)\n      if (success) {\n        setInvitationToDecline(null)\n        setIsDeclineDialogOpen(false)\n        return success\n      }\n    }\n    return false\n  }\n\n  const columns = getColumns({ onAccept: onAcceptInvitation, onDecline: handleDecline })\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    state: {\n      sorting,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  return (\n    <>\n      <div>\n        <div className=\"rounded-md border\">\n          <Table>\n            <TableHeader>\n              {table.getHeaderGroups().map((headerGroup) => (\n                <TableRow key={headerGroup.id}>\n                  {headerGroup.headers.map((header) => {\n                    return (\n                      <TableHead key={header.id}>\n                        {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                      </TableHead>\n                    )\n                  })}\n                </TableRow>\n              ))}\n            </TableHeader>\n            <TableBody>\n              {loadingData ? (\n                <TableRow>\n                  <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                    Loading...\n                  </TableCell>\n                </TableRow>\n              ) : table.getRowModel().rows?.length ? (\n                table.getRowModel().rows.map((row) => (\n                  <TableRow\n                    key={row.id}\n                    data-state={row.getIsSelected() && 'selected'}\n                    className={`h-14 ${loadingInvitationAction[row.original.id] ? 'opacity-50 pointer-events-none' : ''}`}\n                  >\n                    {row.getVisibleCells().map((cell) => (\n                      <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>\n                    ))}\n                  </TableRow>\n                ))\n              ) : (\n                <TableEmptyState colSpan={columns.length} message=\"No Invitations found.\" />\n              )}\n            </TableBody>\n          </Table>\n        </div>\n        <Pagination table={table} className=\"mt-4\" entityName=\"Invitations\" />\n      </div>\n\n      {invitationToDecline && (\n        <DeclineOrganizationInvitationDialog\n          open={isDeclineDialogOpen}\n          onOpenChange={(open) => {\n            setIsDeclineDialogOpen(open)\n            if (!open) {\n              setInvitationToDecline(null)\n            }\n          }}\n          onDeclineInvitation={handleConfirmDecline}\n          loading={loadingInvitationAction[invitationToDecline.id]}\n        />\n      )}\n    </>\n  )\n}\n\nconst getColumns = ({\n  onAccept,\n  onDecline,\n}: {\n  onAccept: (invitation: OrganizationInvitation) => void\n  onDecline: (invitation: OrganizationInvitation) => void\n}): ColumnDef<OrganizationInvitation>[] => {\n  const columns: ColumnDef<OrganizationInvitation>[] = [\n    {\n      accessorKey: 'organizationName',\n      header: 'Organization',\n    },\n    {\n      accessorKey: 'invitedBy',\n      header: 'Invited by',\n    },\n    {\n      accessorKey: 'expiresAt',\n      header: 'Expires',\n      cell: ({ row }) => {\n        return new Date(row.original.expiresAt).toLocaleDateString()\n      },\n    },\n    {\n      id: 'actions',\n      cell: ({ row }) => {\n        return (\n          <div className=\"flex justify-end gap-2\">\n            <Button variant=\"ghost\" className=\"h-8 w-8 p-0\" onClick={() => onAccept(row.original)}>\n              <span className=\"sr-only\">Accept invitation</span>\n              <Check className=\"h-4 w-4\" />\n            </Button>\n            <Button variant=\"ghost\" className=\"h-8 w-8 p-0\" onClick={() => onDecline(row.original)}>\n              <span className=\"sr-only\">Decline invitation</span>\n              <X className=\"h-4 w-4\" />\n            </Button>\n          </div>\n        )\n      },\n    },\n  ]\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/VerifyEmailDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\n\ninterface VerifyEmailDialogProps {\n  open: boolean\n  onOpenChange: (open: boolean) => void\n}\n\nexport const VerifyEmailDialog: React.FC<VerifyEmailDialogProps> = ({ open, onOpenChange }) => {\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Verify Your Account</DialogTitle>\n          <DialogDescription>\n            A verification email was sent to your registered email address. Please note that you must verify your email\n            before you can create sandboxes or new organizations.\n          </DialogDescription>\n        </DialogHeader>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\">\n              Close\n            </Button>\n          </DialogClose>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/VolumeTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DebouncedInput } from '@/components/DebouncedInput'\nimport { Pagination } from '@/components/Pagination'\nimport { Button } from '@/components/ui/button'\nimport { Checkbox } from '@/components/ui/checkbox'\nimport { DataTableFacetedFilter, FacetedFilterOption } from '@/components/ui/data-table-faceted-filter'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { OrganizationRolePermissionsEnum, VolumeDto, VolumeState } from '@daytonaio/api-client'\nimport {\n  ColumnDef,\n  ColumnFiltersState,\n  flexRender,\n  getCoreRowModel,\n  getFacetedRowModel,\n  getFacetedUniqueValues,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { AlertTriangle, CheckCircle, HardDrive, Loader2, MoreHorizontal, Timer } from 'lucide-react'\nimport { useMemo, useState } from 'react'\nimport { TableEmptyState } from './TableEmptyState'\n\ninterface VolumeTableProps {\n  data: VolumeDto[]\n  loading: boolean\n  processingVolumeAction: Record<string, boolean>\n  onDelete: (volume: VolumeDto) => void\n  onBulkDelete: (volumes: VolumeDto[]) => void\n}\n\nexport function VolumeTable({ data, loading, processingVolumeAction, onDelete, onBulkDelete }: VolumeTableProps) {\n  const { authenticatedUserHasPermission } = useSelectedOrganization()\n\n  const deletePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.DELETE_VOLUMES),\n    [authenticatedUserHasPermission],\n  )\n\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n\n  const columns = getColumns({\n    onDelete,\n    processingVolumeAction,\n    deletePermitted,\n  })\n  const table = useReactTable({\n    data,\n    columns,\n    onColumnFiltersChange: setColumnFilters,\n    getCoreRowModel: getCoreRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    getFacetedRowModel: getFacetedRowModel(),\n    getFacetedUniqueValues: getFacetedUniqueValues(),\n    getFilteredRowModel: getFilteredRowModel(),\n    state: {\n      sorting,\n      columnFilters,\n    },\n    enableRowSelection: true,\n    getRowId: (row) => row.id,\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n  const [bulkDeleteConfirmationOpen, setBulkDeleteConfirmationOpen] = useState(false)\n\n  return (\n    <div>\n      <div className=\"flex items-center mb-4\">\n        <DebouncedInput\n          value={(table.getColumn('name')?.getFilterValue() as string) ?? ''}\n          onChange={(value) => table.getColumn('name')?.setFilterValue(value)}\n          placeholder=\"Search...\"\n          className=\"max-w-sm mr-4\"\n        />\n        {table.getColumn('state') && (\n          <DataTableFacetedFilter column={table.getColumn('state')} title=\"State\" options={statuses} />\n        )}\n      </div>\n      <div className=\"rounded-md border\">\n        <Table>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead className=\"px-2\" key={header.id}>\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <TableRow>\n                <TableCell colSpan={columns.length} className=\"h-24 text-center\">\n                  Loading...\n                </TableCell>\n              </TableRow>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow\n                  key={row.id}\n                  data-state={row.getIsSelected() && 'selected'}\n                  className={`${processingVolumeAction[row.original.id] || row.original.state === VolumeState.PENDING_DELETE || row.original.state === VolumeState.DELETING ? 'opacity-50 pointer-events-none' : ''}`}\n                >\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell className=\"px-2\" key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No Volumes yet.\"\n                icon={<HardDrive className=\"w-8 h-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>\n                      Volumes are shared, persistent directories backed by S3-compatible storage, perfect for reusing\n                      datasets, caching dependencies, or passing files across sandboxes.\n                    </p>\n                    <p>\n                      Create one via the SDK or CLI. <br />\n                      <a\n                        href=\"https://www.daytona.io/docs/volumes\"\n                        target=\"_blank\"\n                        rel=\"noopener noreferrer\"\n                        className=\"text-primary hover:underline font-medium\"\n                      >\n                        Read the Volumes guide\n                      </a>{' '}\n                      to learn more.\n                    </p>\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <div className=\"flex items-center justify-between space-x-2 py-4\">\n        {table.getRowModel().rows.some((row) => row.getIsSelected()) && (\n          <Popover open={bulkDeleteConfirmationOpen} onOpenChange={setBulkDeleteConfirmationOpen}>\n            <PopoverTrigger>\n              <Button variant=\"destructive\" size=\"sm\" className=\"h-8\">\n                Bulk Delete\n              </Button>\n            </PopoverTrigger>\n            <PopoverContent side=\"top\">\n              <div className=\"flex flex-col gap-4\">\n                <p>Are you sure you want to delete these Volumes?</p>\n                <div className=\"flex items-center space-x-2\">\n                  <Button\n                    variant=\"destructive\"\n                    onClick={() => {\n                      onBulkDelete(\n                        table\n                          .getRowModel()\n                          .rows.filter((row) => row.getIsSelected())\n                          .map((row) => row.original),\n                      )\n                      setBulkDeleteConfirmationOpen(false)\n                    }}\n                  >\n                    Delete\n                  </Button>\n                  <Button variant=\"outline\" onClick={() => setBulkDeleteConfirmationOpen(false)}>\n                    Cancel\n                  </Button>\n                </div>\n              </div>\n            </PopoverContent>\n          </Popover>\n        )}\n        <Pagination table={table} selectionEnabled entityName=\"Volumes\" />\n      </div>\n    </div>\n  )\n}\n\nconst getStateIcon = (state: VolumeState) => {\n  switch (state) {\n    case VolumeState.READY:\n      return <CheckCircle className=\"w-4 h-4 flex-shrink-0\" />\n    case VolumeState.ERROR:\n      return <AlertTriangle className=\"w-4 h-4 flex-shrink-0\" />\n    default:\n      return <Timer className=\"w-4 h-4 flex-shrink-0\" />\n  }\n}\n\nconst getStateColor = (state: VolumeState) => {\n  switch (state) {\n    case VolumeState.READY:\n      return 'text-green-500'\n    case VolumeState.ERROR:\n      return 'text-red-500'\n    default:\n      return 'text-gray-600 dark:text-gray-400'\n  }\n}\n\nconst getStateLabel = (state: VolumeState) => {\n  return state\n    .split('_')\n    .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n    .join(' ')\n}\n\nconst statuses: FacetedFilterOption[] = [\n  { label: getStateLabel(VolumeState.CREATING), value: VolumeState.CREATING, icon: Timer },\n  { label: getStateLabel(VolumeState.READY), value: VolumeState.READY, icon: CheckCircle },\n  { label: getStateLabel(VolumeState.PENDING_CREATE), value: VolumeState.PENDING_CREATE, icon: Timer },\n  { label: getStateLabel(VolumeState.PENDING_DELETE), value: VolumeState.PENDING_DELETE, icon: Timer },\n  { label: getStateLabel(VolumeState.DELETING), value: VolumeState.DELETING, icon: Timer },\n  { label: getStateLabel(VolumeState.DELETED), value: VolumeState.DELETED, icon: Timer },\n  { label: getStateLabel(VolumeState.ERROR), value: VolumeState.ERROR, icon: AlertTriangle },\n]\n\nconst getColumns = ({\n  onDelete,\n  processingVolumeAction,\n  deletePermitted,\n}: {\n  onDelete: (volume: VolumeDto) => void\n  processingVolumeAction: Record<string, boolean>\n  deletePermitted: boolean\n}): ColumnDef<VolumeDto>[] => {\n  const columns: ColumnDef<VolumeDto>[] = [\n    {\n      id: 'select',\n      header: ({ table }) => (\n        <Checkbox\n          checked={\n            table.getIsAllPageRowsSelected() ? true : table.getIsSomePageRowsSelected() ? 'indeterminate' : false\n          }\n          onCheckedChange={(value) => {\n            for (const row of table.getRowModel().rows) {\n              if (processingVolumeAction[row.original.id]) {\n                row.toggleSelected(false)\n              } else {\n                row.toggleSelected(!!value)\n              }\n            }\n          }}\n          aria-label=\"Select all\"\n          className=\"translate-y-[2px]\"\n        />\n      ),\n      cell: ({ row }) => {\n        if (processingVolumeAction[row.original.id]) {\n          return <Loader2 className=\"w-4 h-4 animate-spin\" />\n        }\n        return (\n          <Checkbox\n            checked={row.getIsSelected()}\n            onCheckedChange={(value) => row.toggleSelected(!!value)}\n            aria-label=\"Select row\"\n            className=\"translate-y-[2px]\"\n          />\n        )\n      },\n      enableSorting: false,\n      enableHiding: false,\n    },\n    {\n      accessorKey: 'name',\n      header: 'Name',\n      cell: ({ row }) => {\n        return <div className=\"w-40\">{row.original.name}</div>\n      },\n    },\n    {\n      id: 'state',\n      header: 'State',\n      cell: ({ row }) => {\n        const volume = row.original\n        const state = row.original.state\n        const color = getStateColor(state)\n\n        if (state === VolumeState.ERROR && !!volume.errorReason) {\n          return (\n            <Tooltip>\n              <TooltipTrigger>\n                <div className={`flex items-center gap-2 ${color}`}>\n                  {getStateIcon(state)}\n                  {getStateLabel(state)}\n                </div>\n              </TooltipTrigger>\n              <TooltipContent>\n                <p className=\"max-w-[300px]\">{volume.errorReason}</p>\n              </TooltipContent>\n            </Tooltip>\n          )\n        }\n\n        return (\n          <div className={`flex items-center gap-2 w-40 ${color}`}>\n            {getStateIcon(state)}\n            <span>{getStateLabel(state)}</span>\n          </div>\n        )\n      },\n      accessorKey: 'state',\n      filterFn: (row, id, value) => {\n        return value.includes(row.getValue(id))\n      },\n    },\n    {\n      accessorKey: 'createdAt',\n      header: 'Created',\n      cell: ({ row }) => {\n        return getRelativeTimeString(row.original.createdAt).relativeTimeString\n      },\n    },\n    {\n      accessorKey: 'lastUsedAt',\n      header: 'Last Used',\n      cell: ({ row }) => {\n        return getRelativeTimeString(row.original.lastUsedAt).relativeTimeString\n      },\n    },\n    {\n      id: 'actions',\n      enableHiding: false,\n      cell: ({ row }) => {\n        if (!deletePermitted) {\n          return null\n        }\n\n        return (\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button variant=\"ghost\" className=\"h-8 w-8 p-0\">\n                <span className=\"sr-only\">Open menu</span>\n                <MoreHorizontal />\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\">\n              <DropdownMenuItem\n                className={`cursor-pointer text-red-600 dark:text-red-400 ${\n                  processingVolumeAction[row.original.id] ? 'opacity-50 pointer-events-none' : ''\n                }`}\n                disabled={processingVolumeAction[row.original.id]}\n                onClick={() => onDelete(row.original)}\n              >\n                Delete\n              </DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        )\n      },\n    },\n  ]\n\n  return columns\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/CreateEndpointDialog.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n  Command,\n  CommandCheckboxItem,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandList,\n} from '@/components/ui/command'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { Field, FieldError, FieldLabel } from '@/components/ui/field'\nimport { Input } from '@/components/ui/input'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { Spinner } from '@/components/ui/spinner'\nimport { WEBHOOK_EVENT_CATEGORIES, WEBHOOK_EVENTS } from '@/constants/webhook-events'\nimport { handleApiError } from '@/lib/error-handling'\nimport { cn } from '@/lib/utils'\nimport { useForm } from '@tanstack/react-form'\nimport { ChevronsUpDown, Plus } from 'lucide-react'\nimport React, { useCallback, useEffect, useState } from 'react'\nimport { toast } from 'sonner'\nimport { useSvix } from 'svix-react'\nimport { z } from 'zod'\n\nconst formSchema = z.object({\n  url: z.string().min(1, 'URL is required').url('Must be a valid URL'),\n  description: z.string(),\n  filterTypes: z.array(z.string()).min(1, 'At least one event is required'),\n})\n\ntype FormValues = z.infer<typeof formSchema>\n\ninterface CreateEndpointDialogProps {\n  onSuccess: () => void\n  className?: string\n}\n\nexport const CreateEndpointDialog: React.FC<CreateEndpointDialogProps> = ({ onSuccess, className }) => {\n  const [open, setOpen] = useState(false)\n  const [eventsPopoverOpen, setEventsPopoverOpen] = useState(false)\n\n  const { svix, appId } = useSvix()\n\n  const form = useForm({\n    defaultValues: {\n      url: '',\n      description: '',\n      filterTypes: [],\n    } as FormValues,\n    validators: {\n      onSubmit: formSchema,\n    },\n    onSubmit: async ({ value }) => {\n      try {\n        await svix.endpoint.create(appId, {\n          url: value.url.trim(),\n          description: value.description?.trim() || undefined,\n          filterTypes: value.filterTypes.length > 0 ? value.filterTypes : undefined,\n        })\n        toast.success('Endpoint created')\n        onSuccess()\n        setOpen(false)\n      } catch (error) {\n        handleApiError(error, 'Failed to create endpoint')\n      }\n    },\n  })\n\n  const resetState = useCallback(() => {\n    form.reset()\n  }, [form])\n\n  useEffect(() => {\n    if (open) {\n      resetState()\n    }\n  }, [open, resetState])\n\n  const toggleEvent = (eventValue: string) => {\n    const currentEvents = form.getFieldValue('filterTypes')\n    if (currentEvents.includes(eventValue)) {\n      form.setFieldValue(\n        'filterTypes',\n        currentEvents.filter((e) => e !== eventValue),\n      )\n    } else {\n      form.setFieldValue('filterTypes', [...currentEvents, eventValue])\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={setOpen}>\n      <DialogTrigger asChild>\n        <Button variant=\"default\" size=\"sm\" title=\"Add Endpoint\" className={className}>\n          <Plus className=\"w-4 h-4\" />\n          Add Endpoint\n        </Button>\n      </DialogTrigger>\n      <DialogContent className=\"max-w-lg\">\n        <DialogHeader>\n          <DialogTitle>Add Webhook Endpoint</DialogTitle>\n          <DialogDescription>Configure a new endpoint to receive webhook events.</DialogDescription>\n        </DialogHeader>\n        <form\n          id=\"create-endpoint-form\"\n          className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n          onSubmit={(e) => {\n            e.preventDefault()\n            e.stopPropagation()\n            form.handleSubmit()\n          }}\n        >\n          <form.Field name=\"description\">\n            {(field) => {\n              const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n              return (\n                <Field data-invalid={isInvalid}>\n                  <FieldLabel htmlFor={field.name}>Endpoint Name</FieldLabel>\n                  <Input\n                    aria-invalid={isInvalid}\n                    autoComplete=\"off\"\n                    id={field.name}\n                    name={field.name}\n                    value={field.state.value}\n                    onBlur={field.handleBlur}\n                    onChange={(e) => field.handleChange(e.target.value)}\n                    placeholder=\"My Webhook Endpoint\"\n                  />\n                  {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                    <FieldError errors={field.state.meta.errors} />\n                  )}\n                </Field>\n              )\n            }}\n          </form.Field>\n\n          <form.Field name=\"url\">\n            {(field) => {\n              const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n              return (\n                <Field data-invalid={isInvalid}>\n                  <FieldLabel htmlFor={field.name}>Endpoint URL</FieldLabel>\n                  <Input\n                    autoComplete=\"off\"\n                    aria-invalid={isInvalid}\n                    id={field.name}\n                    name={field.name}\n                    type=\"url\"\n                    value={field.state.value}\n                    onBlur={field.handleBlur}\n                    onChange={(e) => field.handleChange(e.target.value)}\n                    placeholder=\"https://example.com/webhook\"\n                  />\n                  {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                    <FieldError errors={field.state.meta.errors} />\n                  )}\n                </Field>\n              )\n            }}\n          </form.Field>\n\n          <form.Field name=\"filterTypes\">\n            {(field) => {\n              const selectedEvents = field.state.value\n              const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n              return (\n                <Field data-invalid={isInvalid}>\n                  <FieldLabel>Events</FieldLabel>\n                  <Popover open={eventsPopoverOpen} onOpenChange={setEventsPopoverOpen} modal>\n                    <PopoverTrigger asChild>\n                      <Button\n                        variant=\"outline\"\n                        role=\"combobox\"\n                        aria-expanded={eventsPopoverOpen}\n                        className={cn('w-full justify-between h-auto min-h-10', {\n                          '!pl-2': selectedEvents.length > 0,\n                        })}\n                      >\n                        <div className=\"flex flex-wrap gap-1\">\n                          {selectedEvents.length === 0 ? (\n                            <span className=\"text-muted-foreground\">Select events...</span>\n                          ) : selectedEvents.length > 2 ? (\n                            <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-normal\">\n                              {selectedEvents.length} events selected\n                            </Badge>\n                          ) : (\n                            selectedEvents.map((event) => (\n                              <Badge key={event} variant=\"secondary\" className=\"rounded-sm px-1 font-normal\">\n                                {WEBHOOK_EVENTS.find((e) => e.value === event)?.label || event}\n                              </Badge>\n                            ))\n                          )}\n                        </div>\n                        <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n                      </Button>\n                    </PopoverTrigger>\n                    <PopoverContent className=\"w-[var(--radix-popover-trigger-width)] p-0\" align=\"start\">\n                      <Command>\n                        <CommandInput placeholder=\"Search events...\" />\n                        <CommandList>\n                          <CommandEmpty>No events found.</CommandEmpty>\n                          {WEBHOOK_EVENT_CATEGORIES.map((category) => (\n                            <CommandGroup key={category} heading={category}>\n                              {WEBHOOK_EVENTS.filter((event) => event.category === category).map((event) => (\n                                <CommandCheckboxItem\n                                  key={event.value}\n                                  checked={selectedEvents.includes(event.value)}\n                                  onSelect={() => toggleEvent(event.value)}\n                                >\n                                  {event.label}\n                                </CommandCheckboxItem>\n                              ))}\n                            </CommandGroup>\n                          ))}\n                        </CommandList>\n                      </Command>\n                    </PopoverContent>\n                  </Popover>\n                  {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                    <FieldError errors={field.state.meta.errors} />\n                  )}\n                </Field>\n              )\n            }}\n          </form.Field>\n        </form>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\">\n              Cancel\n            </Button>\n          </DialogClose>\n          <form.Subscribe\n            selector={(state) => [state.canSubmit, state.isSubmitting]}\n            children={([canSubmit, isSubmitting]) => (\n              <Button type=\"submit\" form=\"create-endpoint-form\" variant=\"default\" disabled={!canSubmit || isSubmitting}>\n                {isSubmitting && <Spinner />}\n                Create\n              </Button>\n            )}\n          />\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/DeliveryStatsLine.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\nimport type { EndpointStats } from 'svix'\nimport { motion } from 'framer-motion'\nimport React from 'react'\n\nconst transition = {\n  type: 'spring',\n  stiffness: 60,\n  damping: 15,\n  mass: 1,\n} as const\n\nconst SEGMENTS = [\n  { key: 'success', label: 'Success', color: 'bg-green-500', dotColor: 'bg-green-500' },\n  { key: 'fail', label: 'Failed', color: 'bg-red-500', dotColor: 'bg-red-500' },\n  { key: 'pending', label: 'Pending', color: 'bg-muted-foreground/50', dotColor: 'bg-muted-foreground/50' },\n  { key: 'sending', label: 'Sending', color: 'bg-white', dotColor: 'bg-white border border-border' },\n] as const\n\ninterface DeliveryStatsLineProps {\n  stats: EndpointStats\n  className?: string\n}\n\nconst DeliveryStatsLine: React.FC<DeliveryStatsLineProps> = ({ stats, className }) => {\n  const total = stats.success + stats.fail + stats.pending + stats.sending\n\n  if (total === 0) {\n    return (\n      <div className={cn('flex flex-col gap-2', className)}>\n        <div className=\"w-full h-2 bg-muted rounded-full\" />\n        <Legend stats={stats} total={total} />\n      </div>\n    )\n  }\n\n  return (\n    <div className={cn('flex flex-col gap-2', className)}>\n      <div className=\"w-full h-2 bg-muted rounded-full overflow-clip flex\">\n        {SEGMENTS.map(({ key, color }) => {\n          const value = stats[key]\n          if (value === 0) return null\n          const pct = (value / total) * 100\n          return (\n            <motion.div\n              key={key}\n              className={cn('h-full', color)}\n              initial={{ width: 0 }}\n              animate={{ width: `${pct}%` }}\n              transition={transition}\n            />\n          )\n        })}\n      </div>\n      <Legend stats={stats} total={total} />\n    </div>\n  )\n}\n\nfunction Legend({ stats, total }: { stats: EndpointStats; total: number }) {\n  return (\n    <div className=\"flex items-center gap-4 flex-wrap\">\n      {SEGMENTS.map(({ key, label, dotColor }) => (\n        <div key={key} className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n          <div className={cn('w-2 h-2 rounded-full', dotColor)} />\n          <span>\n            {label} {stats[key]}\n            {total > 0 && <span className=\"ml-0.5\">({Math.round((stats[key] / total) * 100)}%)</span>}\n          </span>\n        </div>\n      ))}\n    </div>\n  )\n}\n\nexport default DeliveryStatsLine\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/EditEndpointDialog.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n  Command,\n  CommandCheckboxItem,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandList,\n} from '@/components/ui/command'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Field, FieldError, FieldLabel } from '@/components/ui/field'\nimport { Input } from '@/components/ui/input'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { Spinner } from '@/components/ui/spinner'\nimport { WEBHOOK_EVENT_CATEGORIES, WEBHOOK_EVENTS } from '@/constants/webhook-events'\nimport { useUpdateWebhookEndpointMutation } from '@/hooks/mutations/useUpdateWebhookEndpointMutation'\nimport { handleApiError } from '@/lib/error-handling'\nimport { useForm } from '@tanstack/react-form'\nimport { ChevronsUpDown } from 'lucide-react'\nimport React, { useEffect, useState } from 'react'\nimport { toast } from 'sonner'\nimport { EndpointOut } from 'svix'\nimport { z } from 'zod'\n\nconst formSchema = z.object({\n  url: z.string().min(1, 'URL is required').url('Must be a valid URL'),\n  description: z.string().min(1, 'Name is required'),\n  filterTypes: z.array(z.string()).min(1, 'At least one event is required'),\n})\n\ntype FormValues = z.infer<typeof formSchema>\n\ninterface EditEndpointDialogProps {\n  endpoint: EndpointOut | null\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onSuccess: () => void\n}\n\nexport const EditEndpointDialog: React.FC<EditEndpointDialogProps> = ({ endpoint, open, onOpenChange, onSuccess }) => {\n  const [eventsPopoverOpen, setEventsPopoverOpen] = useState(false)\n\n  const updateMutation = useUpdateWebhookEndpointMutation()\n\n  const form = useForm({\n    defaultValues: {\n      url: '',\n      description: '',\n      filterTypes: [],\n    } as FormValues,\n    validators: {\n      onSubmit: formSchema,\n    },\n    onSubmit: async ({ value }) => {\n      if (!endpoint) return\n\n      try {\n        await updateMutation.mutateAsync({\n          endpointId: endpoint.id,\n          update: {\n            url: value.url.trim(),\n            description: value.description?.trim() || undefined,\n            filterTypes: value.filterTypes.length > 0 ? value.filterTypes : undefined,\n          },\n        })\n        toast.success('Endpoint updated')\n        onSuccess()\n        onOpenChange(false)\n      } catch (error) {\n        handleApiError(error, 'Failed to update endpoint')\n      }\n    },\n  })\n\n  useEffect(() => {\n    if (endpoint && open) {\n      form.reset({\n        url: endpoint.url,\n        description: endpoint.description || '',\n        filterTypes: endpoint.filterTypes || [],\n      })\n    }\n  }, [endpoint, open, form])\n\n  const handleOpenChange = (isOpen: boolean) => {\n    onOpenChange(isOpen)\n    if (!isOpen) {\n      form.reset()\n    }\n  }\n\n  const toggleEvent = (eventValue: string) => {\n    const currentEvents = form.getFieldValue('filterTypes')\n    if (currentEvents.includes(eventValue)) {\n      form.setFieldValue(\n        'filterTypes',\n        currentEvents.filter((e) => e !== eventValue),\n      )\n    } else {\n      form.setFieldValue('filterTypes', [...currentEvents, eventValue])\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={handleOpenChange}>\n      <DialogContent className=\"max-w-lg\">\n        <DialogHeader>\n          <DialogTitle>Edit Webhook Endpoint</DialogTitle>\n          <DialogDescription>Update the endpoint configuration.</DialogDescription>\n        </DialogHeader>\n        <form\n          id=\"edit-endpoint-form\"\n          className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n          onSubmit={(e) => {\n            e.preventDefault()\n            e.stopPropagation()\n            form.handleSubmit()\n          }}\n        >\n          <form.Field name=\"description\">\n            {(field) => {\n              const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n              return (\n                <Field data-invalid={isInvalid}>\n                  <FieldLabel htmlFor={field.name}>Endpoint Name</FieldLabel>\n                  <Input\n                    aria-invalid={isInvalid}\n                    id={field.name}\n                    name={field.name}\n                    value={field.state.value}\n                    onBlur={field.handleBlur}\n                    onChange={(e) => field.handleChange(e.target.value)}\n                    placeholder=\"My Webhook Endpoint\"\n                  />\n                  {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                    <FieldError errors={field.state.meta.errors} />\n                  )}\n                </Field>\n              )\n            }}\n          </form.Field>\n\n          <form.Field name=\"url\">\n            {(field) => {\n              const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n              return (\n                <Field data-invalid={isInvalid}>\n                  <FieldLabel htmlFor={field.name}>Endpoint URL</FieldLabel>\n                  <Input\n                    aria-invalid={isInvalid}\n                    id={field.name}\n                    name={field.name}\n                    type=\"url\"\n                    value={field.state.value}\n                    onBlur={field.handleBlur}\n                    onChange={(e) => field.handleChange(e.target.value)}\n                    placeholder=\"https://example.com/webhook\"\n                  />\n                  {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                    <FieldError errors={field.state.meta.errors} />\n                  )}\n                </Field>\n              )\n            }}\n          </form.Field>\n\n          <form.Field name=\"filterTypes\">\n            {(field) => {\n              const selectedEvents = field.state.value\n              const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n              return (\n                <Field data-invalid={isInvalid}>\n                  <FieldLabel>Events</FieldLabel>\n                  <Popover open={eventsPopoverOpen} onOpenChange={setEventsPopoverOpen} modal>\n                    <PopoverTrigger asChild>\n                      <Button\n                        variant=\"outline\"\n                        role=\"combobox\"\n                        aria-expanded={eventsPopoverOpen}\n                        className=\"w-full justify-between h-auto min-h-10\"\n                      >\n                        <div className=\"flex flex-wrap gap-1\">\n                          {selectedEvents.length === 0 ? (\n                            <span className=\"text-muted-foreground\">Select events...</span>\n                          ) : selectedEvents.length > 2 ? (\n                            <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-normal\">\n                              {selectedEvents.length} events selected\n                            </Badge>\n                          ) : (\n                            selectedEvents.map((event) => (\n                              <Badge key={event} variant=\"secondary\" className=\"rounded-sm px-1 font-normal\">\n                                {WEBHOOK_EVENTS.find((e) => e.value === event)?.label || event}\n                              </Badge>\n                            ))\n                          )}\n                        </div>\n                        <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n                      </Button>\n                    </PopoverTrigger>\n                    <PopoverContent className=\"w-[var(--radix-popover-trigger-width)] p-0\" align=\"start\">\n                      <Command>\n                        <CommandInput placeholder=\"Search events...\" />\n                        <CommandList>\n                          <CommandEmpty>No events found.</CommandEmpty>\n                          {WEBHOOK_EVENT_CATEGORIES.map((category) => (\n                            <CommandGroup key={category} heading={category}>\n                              {WEBHOOK_EVENTS.filter((event) => event.category === category).map((event) => (\n                                <CommandCheckboxItem\n                                  key={event.value}\n                                  checked={selectedEvents.includes(event.value)}\n                                  onSelect={() => toggleEvent(event.value)}\n                                >\n                                  {event.label}\n                                </CommandCheckboxItem>\n                              ))}\n                            </CommandGroup>\n                          ))}\n                        </CommandList>\n                      </Command>\n                    </PopoverContent>\n                  </Popover>\n                  {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                    <FieldError errors={field.state.meta.errors} />\n                  )}\n                </Field>\n              )\n            }}\n          </form.Field>\n        </form>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\">\n              Cancel\n            </Button>\n          </DialogClose>\n          <form.Subscribe\n            selector={(state) => [state.canSubmit, state.isSubmitting]}\n            children={([canSubmit, isSubmitting]) => (\n              <Button type=\"submit\" form=\"edit-endpoint-form\" variant=\"default\" disabled={!canSubmit || isSubmitting}>\n                {isSubmitting && <Spinner />}\n                Save\n              </Button>\n            )}\n          />\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/EndpointEventsTable/EndpointEventsTable.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DebouncedInput } from '@/components/DebouncedInput'\nimport { Pagination } from '@/components/Pagination'\nimport { TableEmptyState } from '@/components/TableEmptyState'\nimport { DataTableFacetedFilter } from '@/components/ui/data-table-faceted-filter'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport {\n  ColumnFiltersState,\n  flexRender,\n  getCoreRowModel,\n  getFacetedRowModel,\n  getFacetedUniqueValues,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { Mail } from 'lucide-react'\nimport { useCallback, useState } from 'react'\nimport { EndpointMessageOut } from 'svix'\nimport { columns, eventTypeOptions, statusOptions } from './columns'\nimport { EventDetailsSheet } from './EventDetailsSheet'\n\ninterface EndpointEventsTableProps {\n  data: EndpointMessageOut[]\n  loading: boolean\n  onReplay: (msgId: string) => void\n}\n\nexport function EndpointEventsTable({ data, loading, onReplay }: EndpointEventsTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n  const [globalFilter, setGlobalFilter] = useState('')\n  const [selectedEventIndex, setSelectedEventIndex] = useState<number | null>(null)\n  const [sheetOpen, setSheetOpen] = useState(false)\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getFilteredRowModel: getFilteredRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    onColumnFiltersChange: setColumnFilters,\n    getFacetedRowModel: getFacetedRowModel(),\n    getFacetedUniqueValues: getFacetedUniqueValues(),\n    onGlobalFilterChange: setGlobalFilter,\n    globalFilterFn: (row, _columnId, filterValue) => {\n      const event = row.original\n      const searchValue = filterValue.toLowerCase()\n      return (\n        (event.id?.toLowerCase().includes(searchValue) ?? false) ||\n        (event.eventType?.toLowerCase().includes(searchValue) ?? false) ||\n        (event.statusText?.toLowerCase().includes(searchValue) ?? false)\n      )\n    },\n    state: {\n      sorting,\n      columnFilters,\n      globalFilter,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n    meta: {\n      endpointEvents: {\n        onReplay,\n      },\n    },\n  })\n\n  const handleRowClick = useCallback((index: number) => {\n    setSelectedEventIndex(index)\n    setSheetOpen(true)\n  }, [])\n\n  const rowCount = table.getRowModel().rows.length\n\n  const handleNavigate = useCallback(\n    (direction: 'prev' | 'next') => {\n      setSelectedEventIndex((prev) => {\n        if (prev === null) return null\n        if (direction === 'prev' && prev > 0) return prev - 1\n        if (direction === 'next' && prev < rowCount - 1) return prev + 1\n        return prev\n      })\n    },\n    [rowCount],\n  )\n\n  return (\n    <div>\n      <div className=\"flex items-center mb-4\">\n        <DebouncedInput\n          value={globalFilter ?? ''}\n          onChange={(value) => setGlobalFilter(String(value))}\n          placeholder=\"Search by Event Type, Message ID, or Status\"\n          className=\"max-w-sm mr-4\"\n        />\n        {table.getColumn('eventType') && (\n          <DataTableFacetedFilter\n            column={table.getColumn('eventType')}\n            title=\"Event Type\"\n            options={eventTypeOptions}\n            className=\"mr-2\"\n          />\n        )}\n        {table.getColumn('status') && (\n          <DataTableFacetedFilter column={table.getColumn('status')} title=\"Status\" options={statusOptions} />\n        )}\n      </div>\n      <div className=\"rounded-md\">\n        <Table style={{ tableLayout: 'fixed', width: '100%' }}>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      className=\"px-2\"\n                      key={header.id}\n                      style={{\n                        width: `${header.column.getSize()}px`,\n                      }}\n                    >\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <>\n                {Array.from(new Array(5)).map((_, i) => (\n                  <TableRow key={i}>\n                    {table.getVisibleLeafColumns().map((column) => (\n                      <TableCell key={column.id} className=\"px-2\">\n                        <Skeleton className=\"h-4 w-10/12\" />\n                      </TableCell>\n                    ))}\n                  </TableRow>\n                ))}\n              </>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row, rowIndex) => (\n                <TableRow\n                  key={row.id}\n                  data-state={row.getIsSelected() && 'selected'}\n                  className={`cursor-pointer hover:bg-muted/50 focus-visible:bg-muted/50 focus-visible:outline-none ${sheetOpen && selectedEventIndex === rowIndex ? 'bg-muted/50' : ''}`}\n                  tabIndex={0}\n                  role=\"button\"\n                  onClick={() => handleRowClick(rowIndex)}\n                  onKeyDown={(e) => {\n                    if (e.key === 'Enter' || e.key === ' ') {\n                      e.preventDefault()\n                      handleRowClick(rowIndex)\n                    }\n                  }}\n                >\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell\n                      className=\"px-2\"\n                      key={cell.id}\n                      style={{\n                        width: `${cell.column.getSize()}px`,\n                      }}\n                    >\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No events found.\"\n                icon={<Mail className=\"size-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>Events will appear here when webhooks are triggered.</p>\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination table={table} className=\"mt-4\" entityName=\"Events\" />\n      <EventDetailsSheet\n        event={selectedEventIndex !== null ? (table.getRowModel().rows[selectedEventIndex]?.original ?? null) : null}\n        open={sheetOpen}\n        onOpenChange={setSheetOpen}\n        onNavigate={handleNavigate}\n        hasPrev={selectedEventIndex !== null && selectedEventIndex > 0}\n        hasNext={selectedEventIndex !== null && selectedEventIndex < table.getRowModel().rows.length - 1}\n        onReplay={onReplay}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/EndpointEventsTable/EventDetailsSheet.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { Separator } from '@/components/ui/separator'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { ChevronDown, ChevronUp, RefreshCw, X } from 'lucide-react'\nimport { useCallback, useState } from 'react'\nimport { EndpointMessageOut } from 'svix'\nimport { MessageAttemptsTable } from '../MessageAttemptsTable'\n\ninterface EventDetailsSheetProps {\n  event: EndpointMessageOut | null\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onNavigate: (direction: 'prev' | 'next') => void\n  hasPrev: boolean\n  hasNext: boolean\n  onReplay: (msgId: string) => void\n}\n\nexport function EventDetailsSheet({\n  event,\n  open,\n  onOpenChange,\n  onNavigate,\n  hasPrev,\n  hasNext,\n  onReplay,\n}: EventDetailsSheetProps) {\n  const [attemptsReloadKey, setAttemptsReloadKey] = useState(0)\n\n  const handleReplay = useCallback(\n    (msgId: string) => {\n      onReplay(msgId)\n      setAttemptsReloadKey((prev) => prev + 1)\n    },\n    [onReplay],\n  )\n\n  if (!event) return null\n\n  const hasPayload = event.payload && Object.keys(event.payload).length > 0\n  const payload = hasPayload\n    ? typeof event.payload === 'string'\n      ? event.payload\n      : JSON.stringify(event.payload, null, 2)\n    : ''\n  const { relativeTimeString } = getRelativeTimeString(event.timestamp)\n\n  return (\n    <Sheet open={open} onOpenChange={onOpenChange}>\n      <SheetContent className=\"w-dvw sm:w-[520px] p-0 flex flex-col gap-0 [&>button]:hidden\" side=\"right\">\n        <SheetHeader className=\"flex flex-row items-center justify-between p-4 px-5 space-y-0\">\n          <SheetTitle className=\"text-lg font-medium\">Event Details</SheetTitle>\n          <div className=\"flex items-center gap-1\">\n            <Button variant=\"ghost\" size=\"icon-sm\" disabled={!hasPrev} onClick={() => onNavigate('prev')}>\n              <ChevronUp className=\"size-4\" />\n              <span className=\"sr-only\">Previous event</span>\n            </Button>\n            <Button variant=\"ghost\" size=\"icon-sm\" disabled={!hasNext} onClick={() => onNavigate('next')}>\n              <ChevronDown className=\"size-4\" />\n              <span className=\"sr-only\">Next event</span>\n            </Button>\n            <Button variant=\"ghost\" size=\"icon-sm\" onClick={() => onOpenChange(false)}>\n              <X className=\"size-4\" />\n              <span className=\"sr-only\">Close</span>\n            </Button>\n          </div>\n        </SheetHeader>\n\n        <Separator />\n        <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0\">\n          <div className=\"flex flex-col px-5 py-4 gap-3\">\n            <span className=\"text-base font-medium\">Overview</span>\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-sm text-muted-foreground\">Message ID</span>\n              <div className=\"flex items-center gap-1 group/copy-button\">\n                <span className=\"text-sm font-mono\">{event.id}</span>\n                <CopyButton value={event.id} size=\"icon-xs\" tooltipText=\"Copy Message ID\" />\n              </div>\n            </div>\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-sm text-muted-foreground\">Status</span>\n              <Badge variant={event.status === 0 ? 'success' : event.status === 1 ? 'secondary' : 'destructive'}>\n                {event.status === 0 ? 'Success' : event.status === 1 ? 'Pending' : 'Failed'}\n              </Badge>\n            </div>\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-sm text-muted-foreground\">Event Type</span>\n              <Badge variant=\"secondary\">{event.eventType}</Badge>\n            </div>\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-sm text-muted-foreground\">Sent</span>\n              <TimestampTooltip\n                timestamp={event.timestamp instanceof Date ? event.timestamp.toISOString() : String(event.timestamp)}\n              >\n                <span className=\"text-sm cursor-default\">{relativeTimeString}</span>\n              </TimestampTooltip>\n            </div>\n            {event.nextAttempt && (\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-sm text-muted-foreground\">Next Attempt</span>\n                <TimestampTooltip\n                  timestamp={\n                    event.nextAttempt instanceof Date ? event.nextAttempt.toISOString() : String(event.nextAttempt)\n                  }\n                >\n                  <span className=\"text-sm cursor-default\">\n                    {getRelativeTimeString(event.nextAttempt).relativeTimeString}\n                  </span>\n                </TimestampTooltip>\n              </div>\n            )}\n            {event.channels && event.channels.length > 0 && (\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-sm text-muted-foreground\">Channels</span>\n                <div className=\"flex items-center gap-1 flex-wrap justify-end\">\n                  {event.channels.map((channel) => (\n                    <Badge key={channel} variant=\"outline\" className=\"font-normal text-xs\">\n                      {channel}\n                    </Badge>\n                  ))}\n                </div>\n              </div>\n            )}\n            {event.tags && event.tags.length > 0 && (\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-sm text-muted-foreground\">Tags</span>\n                <div className=\"flex items-center gap-1 flex-wrap justify-end\">\n                  {event.tags.map((tag) => (\n                    <Badge key={tag} variant=\"outline\" className=\"font-normal text-xs\">\n                      {tag}\n                    </Badge>\n                  ))}\n                </div>\n              </div>\n            )}\n            {event.eventId && (\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-sm text-muted-foreground\">Event ID</span>\n                <div className=\"flex items-center gap-1 group/copy-button\">\n                  <span className=\"text-sm font-mono\">{event.eventId}</span>\n                  <CopyButton value={event.eventId} size=\"icon-xs\" tooltipText=\"Copy Event ID\" />\n                </div>\n              </div>\n            )}\n            <Button variant=\"outline\" size=\"sm\" className=\"w-full mt-1\" onClick={() => handleReplay(event.id)}>\n              <RefreshCw className=\"size-3.5 mr-1.5\" />\n              Replay\n            </Button>\n          </div>\n\n          <Separator />\n\n          <div className=\"flex flex-col px-5 py-4\">\n            <div className=\"flex items-center justify-between mb-3\">\n              <span className=\"text-base font-medium\">Payload</span>\n              {hasPayload && <CopyButton value={payload} size=\"icon-xs\" tooltipText=\"Copy Payload\" />}\n            </div>\n            {hasPayload ? (\n              <pre className=\"text-sm font-mono bg-muted/80 p-3 rounded-md overflow-auto whitespace-pre-wrap break-all\">\n                {payload}\n              </pre>\n            ) : (\n              <div className=\"text-sm bg-muted/80 p-3 rounded-md\">\n                <span className=\"italic text-muted-foreground\">This event has no payload</span>\n              </div>\n            )}\n          </div>\n\n          <Separator />\n\n          <div className=\"flex flex-col px-5 py-4\">\n            <MessageAttemptsTable messageId={event.id} reloadKey={attemptsReloadKey} />\n          </div>\n        </ScrollArea>\n      </SheetContent>\n    </Sheet>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/EndpointEventsTable/columns.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { FacetedFilterOption } from '@/components/ui/data-table-faceted-filter'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'\nimport { WEBHOOK_EVENTS } from '@/constants/webhook-events'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { ColumnDef, RowData, Table } from '@tanstack/react-table'\nimport { CheckCircle, Clock, MoreHorizontal, XCircle } from 'lucide-react'\nimport { EndpointMessageOut } from 'svix'\nimport { CopyButton } from '../../CopyButton'\n\ntype EndpointEventsTableMeta = {\n  onReplay: (msgId: string) => void\n}\n\ndeclare module '@tanstack/react-table' {\n  interface TableMeta<TData extends RowData> {\n    endpointEvents?: TData extends EndpointMessageOut ? EndpointEventsTableMeta : never\n  }\n}\n\nconst getMeta = (table: Table<EndpointMessageOut>) => {\n  return table.options.meta?.endpointEvents as EndpointEventsTableMeta\n}\n\nconst columns: ColumnDef<EndpointMessageOut>[] = [\n  {\n    accessorKey: 'id',\n    header: 'Message ID',\n    size: 300,\n    cell: ({ row }) => {\n      const msgId = row.original.id\n      return (\n        <div className=\"w-full truncate flex items-center gap-2 group/copy-button\">\n          <span className=\"truncate block font-mono text-sm hover:underline focus:underline cursor-pointer\">\n            {msgId ?? '-'}\n          </span>\n          {msgId && (\n            <span onClick={(e) => e.stopPropagation()}>\n              <CopyButton value={msgId} size=\"icon-xs\" autoHide tooltipText=\"Copy Message ID\" />\n            </span>\n          )}\n        </div>\n      )\n    },\n  },\n  {\n    id: 'status',\n    accessorFn: (row) => row.statusText || 'unknown',\n    header: 'Status',\n    size: 100,\n    filterFn: (row, id, value) => {\n      return value.includes(row.getValue(id))\n    },\n    cell: ({ row }) => {\n      const status = row.original.status\n      const variant = status === 0 ? 'success' : status === 1 ? 'secondary' : 'destructive'\n      return <Badge variant={variant}>{status === 0 ? 'Success' : status === 1 ? 'Pending' : 'Failed'}</Badge>\n    },\n  },\n  {\n    accessorKey: 'eventType',\n    header: 'Event Type',\n    size: 200,\n    filterFn: (row, id, value) => {\n      return value.includes(row.getValue(id))\n    },\n    cell: ({ row }) => {\n      const eventType = row.original.eventType\n      return (\n        <Badge variant=\"secondary\" className=\"font-normal text-xs\">\n          {eventType}\n        </Badge>\n      )\n    },\n  },\n  {\n    accessorKey: 'nextAttempt',\n    header: 'Next Attempt',\n    size: 100,\n    cell: ({ row }) => {\n      const nextAttempt = row.original.nextAttempt\n      if (!nextAttempt) {\n        return <span className=\"text-muted-foreground\">-</span>\n      }\n      const relativeTime = getRelativeTimeString(nextAttempt)\n      return (\n        <TimestampTooltip timestamp={nextAttempt.toString()}>\n          <span className=\"cursor-default text-sm\">{relativeTime.relativeTimeString}</span>\n        </TimestampTooltip>\n      )\n    },\n  },\n  {\n    accessorKey: 'timestamp',\n    header: 'Sent',\n    size: 100,\n    cell: ({ row }) => {\n      const timestamp = row.original.timestamp\n      if (!timestamp) {\n        return <span className=\"text-muted-foreground\">-</span>\n      }\n      const relativeTime = getRelativeTimeString(timestamp)\n\n      return (\n        <TimestampTooltip timestamp={timestamp.toString()}>\n          <span className=\"cursor-default\">{relativeTime.relativeTimeString}</span>\n        </TimestampTooltip>\n      )\n    },\n  },\n  {\n    id: 'actions',\n    maxSize: 44,\n    enableHiding: false,\n    cell: ({ row, table }) => {\n      const { onReplay } = getMeta(table)\n      const msgId = row.original.id\n      return (\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>\n            <Button variant=\"ghost\" size=\"icon-xs\">\n              <span className=\"sr-only\">Open menu</span>\n              <MoreHorizontal className=\"h-4 w-4\" />\n            </Button>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent align=\"end\" onClick={(e) => e.stopPropagation()}>\n            <DropdownMenuItem className=\"cursor-pointer\" onClick={() => onReplay(msgId)}>\n              Replay\n            </DropdownMenuItem>\n          </DropdownMenuContent>\n        </DropdownMenu>\n      )\n    },\n  },\n]\n\nconst eventTypeOptions: FacetedFilterOption[] = WEBHOOK_EVENTS.map((event) => ({\n  label: event.label,\n  value: event.value,\n}))\n\nconst statusOptions: FacetedFilterOption[] = [\n  { label: 'Success', value: 'success', icon: CheckCircle },\n  { label: 'Pending', value: 'pending', icon: Clock },\n  { label: 'Failed', value: 'fail', icon: XCircle },\n]\n\nexport { columns, eventTypeOptions, statusOptions }\nexport type { EndpointEventsTableMeta }\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/EndpointEventsTable/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport { EndpointEventsTable } from './EndpointEventsTable'\nexport type { EndpointEventsTableMeta } from './columns'\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/MessageAttemptsTable.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport { Badge } from '@/components/ui/badge'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { ChevronDown, ChevronRight, LoaderCircle } from 'lucide-react'\nimport { Fragment, useCallback, useEffect, useRef, useState } from 'react'\nimport { MessageAttemptOut } from 'svix'\nimport { useMessageAttempts } from 'svix-react'\n\nconst RELOAD_DELAY = 5\n\nfunction AttemptStatusBadge({ status }: { status: number }) {\n  const variant = status === 0 ? 'success' : status === 1 ? 'secondary' : 'destructive'\n  const label = status === 0 ? 'Success' : status === 1 ? 'Pending' : status === 3 ? 'Sending' : 'Failed'\n  return <Badge variant={variant}>{label}</Badge>\n}\n\nfunction TriggerTypeBadge({ triggerType }: { triggerType: number }) {\n  return (\n    <Badge variant=\"outline\" className=\"font-normal text-xs\">\n      {triggerType === 1 ? 'Manual' : 'Scheduled'}\n    </Badge>\n  )\n}\n\nfunction AttemptExpandedRow({ attempt }: { attempt: MessageAttemptOut }) {\n  let responseBody: string\n  try {\n    const parsed = JSON.parse(attempt.response)\n    responseBody = JSON.stringify(parsed, null, 2)\n  } catch {\n    responseBody = attempt.response || '(empty)'\n  }\n\n  return (\n    <div className=\"flex flex-col gap-3 px-3 py-3\">\n      <div className=\"flex flex-col gap-2 text-sm\">\n        <div className=\"flex items-center justify-between\">\n          <span className=\"text-muted-foreground\">Status Code</span>\n          {!attempt.responseStatusCode ? (\n            <span className=\"text-muted-foreground italic\">No Response</span>\n          ) : (\n            <Badge\n              variant={\n                attempt.responseStatusCode >= 200 && attempt.responseStatusCode < 300 ? 'success' : 'destructive'\n              }\n            >\n              {attempt.responseStatusCode}\n            </Badge>\n          )}\n        </div>\n        <div className=\"flex items-center justify-between\">\n          <span className=\"text-muted-foreground\">Duration</span>\n          <span className=\"font-mono\">{attempt.responseDurationMs}ms</span>\n        </div>\n        <div className=\"flex items-center justify-between\">\n          <span className=\"text-muted-foreground\">Trigger</span>\n          <TriggerTypeBadge triggerType={attempt.triggerType} />\n        </div>\n        <div className=\"flex items-center justify-between\">\n          <span className=\"text-muted-foreground\">Endpoint ID</span>\n          <div className=\"flex items-center gap-1 group/copy-button\">\n            <span className=\"font-mono truncate max-w-[120px]\">{attempt.endpointId}</span>\n            <CopyButton value={attempt.endpointId} size=\"icon-xs\" tooltipText=\"Copy Endpoint ID\" />\n          </div>\n        </div>\n      </div>\n\n      <div>\n        <div className=\"flex items-center justify-between mb-1.5\">\n          <span className=\"text-sm text-muted-foreground\">Response Body</span>\n          <CopyButton value={attempt.response || ''} size=\"icon-xs\" tooltipText=\"Copy Response\" />\n        </div>\n        <pre className=\"text-xs font-mono bg-muted/80 p-2.5 rounded-md overflow-auto whitespace-pre-wrap break-all max-h-[200px]\">\n          {responseBody}\n        </pre>\n      </div>\n    </div>\n  )\n}\n\nexport function MessageAttemptsTable({ messageId, reloadKey }: { messageId: string; reloadKey?: number }) {\n  const attempts = useMessageAttempts(messageId)\n  const [expandedRows, setExpandedRows] = useState<Set<string>>(new Set())\n  const [countdown, setCountdown] = useState<number | null>(null)\n  const prevReloadKey = useRef(reloadKey)\n  const timerRef = useRef<ReturnType<typeof setInterval>>(null)\n\n  const clearTimer = useCallback(() => {\n    if (timerRef.current) {\n      clearInterval(timerRef.current)\n      timerRef.current = null\n    }\n  }, [])\n\n  useEffect(() => {\n    if (reloadKey !== undefined && reloadKey !== prevReloadKey.current) {\n      prevReloadKey.current = reloadKey\n      clearTimer()\n      setCountdown(RELOAD_DELAY)\n\n      timerRef.current = setInterval(() => {\n        setCountdown((prev) => {\n          if (prev === null || prev <= 1) {\n            clearTimer()\n            attempts.reload()\n            return null\n          }\n          return prev - 1\n        })\n      }, 1000)\n    }\n  }, [reloadKey, attempts, clearTimer])\n\n  useEffect(() => {\n    return clearTimer\n  }, [clearTimer])\n\n  const toggleRow = (attemptId: string) => {\n    setExpandedRows((prev) => {\n      const next = new Set(prev)\n      if (next.has(attemptId)) {\n        next.delete(attemptId)\n      } else {\n        next.add(attemptId)\n      }\n      return next\n    })\n  }\n\n  const header = (\n    <div className=\"flex items-center gap-2 mb-3\">\n      <span className=\"text-base font-medium\">Delivery Attempts</span>\n      <AnimatePresence>\n        {countdown !== null && (\n          <motion.span\n            key=\"countdown\"\n            initial={{ y: 10, opacity: 0 }}\n            animate={{ y: 0, opacity: 1 }}\n            exit={{ y: -10, opacity: 0 }}\n            transition={{ duration: 0.15, ease: 'easeOut' }}\n            className=\"flex items-center gap-1.5 text-xs text-muted-foreground\"\n          >\n            <LoaderCircle className=\"size-3 animate-spin\" />\n            Reloading in {countdown}...\n          </motion.span>\n        )}\n      </AnimatePresence>\n    </div>\n  )\n\n  if (attempts.loading) {\n    return (\n      <div>\n        {header}\n        <div className=\"space-y-2\">\n          <Skeleton className=\"h-8 w-full\" />\n          <Skeleton className=\"h-8 w-full\" />\n          <Skeleton className=\"h-8 w-full\" />\n        </div>\n      </div>\n    )\n  }\n\n  if (attempts.error) {\n    return (\n      <div>\n        {header}\n        <div className=\"text-sm text-muted-foreground\">Failed to load message attempts.</div>\n      </div>\n    )\n  }\n\n  const data = attempts.data ?? []\n\n  if (data.length === 0) {\n    return (\n      <div>\n        {header}\n        <div className=\"text-sm text-muted-foreground\">No delivery attempts yet.</div>\n      </div>\n    )\n  }\n\n  return (\n    <div>\n      {header}\n      <div className=\"rounded-md border\">\n        <Table>\n          <TableHeader>\n            <TableRow>\n              <TableHead className=\"px-3 w-[28px]\" />\n              <TableHead className=\"px-3\">Status</TableHead>\n              <TableHead className=\"px-3\">URL</TableHead>\n              <TableHead className=\"px-3\">Timestamp</TableHead>\n            </TableRow>\n          </TableHeader>\n          <TableBody>\n            {data.map((attempt: MessageAttemptOut) => {\n              const { relativeTimeString } = getRelativeTimeString(attempt.timestamp)\n              const isExpanded = expandedRows.has(attempt.id)\n              return (\n                <Fragment key={attempt.id}>\n                  <TableRow className=\"cursor-pointer hover:bg-muted/50\" onClick={() => toggleRow(attempt.id)}>\n                    <TableCell className=\"px-3 w-[28px]\">\n                      {isExpanded ? (\n                        <ChevronDown className=\"size-3.5 text-muted-foreground\" />\n                      ) : (\n                        <ChevronRight className=\"size-3.5 text-muted-foreground\" />\n                      )}\n                    </TableCell>\n                    <TableCell className=\"px-3\">\n                      <AttemptStatusBadge status={attempt.status} />\n                    </TableCell>\n                    <TableCell className=\"px-3\">\n                      <span className=\"text-sm font-mono truncate block max-w-[200px]\">{attempt.url}</span>\n                    </TableCell>\n                    <TableCell className=\"px-3\">\n                      <TimestampTooltip\n                        timestamp={\n                          attempt.timestamp instanceof Date\n                            ? attempt.timestamp.toISOString()\n                            : String(attempt.timestamp)\n                        }\n                      >\n                        <span className=\"text-sm cursor-default\">{relativeTimeString}</span>\n                      </TimestampTooltip>\n                    </TableCell>\n                  </TableRow>\n                  {isExpanded && (\n                    <TableRow className=\"hover:bg-transparent\">\n                      <TableCell colSpan={4} className=\"p-0 border-b\">\n                        <AttemptExpandedRow attempt={attempt} />\n                      </TableCell>\n                    </TableRow>\n                  )}\n                </Fragment>\n              )\n            })}\n          </TableBody>\n        </Table>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/WebhooksEndpointTable/WebhooksEndpointTable.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DebouncedInput } from '@/components/DebouncedInput'\nimport { Pagination } from '@/components/Pagination'\nimport { TableEmptyState } from '@/components/TableEmptyState'\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from '@/components/ui/alert-dialog'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { RoutePath } from '@/enums/RoutePath'\nimport {\n  flexRender,\n  getCoreRowModel,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { Mail } from 'lucide-react'\nimport { useState } from 'react'\nimport { useNavigate } from 'react-router-dom'\nimport { EndpointOut } from 'svix'\nimport { columns } from './columns'\n\ninterface WebhooksEndpointTableProps {\n  data: EndpointOut[]\n  loading: boolean\n  onDisable: (endpoint: EndpointOut) => void\n  onDelete: (endpoint: EndpointOut) => void\n  isLoadingEndpoint: (endpoint: EndpointOut) => boolean\n}\n\nexport function WebhooksEndpointTable({\n  data,\n  loading,\n  onDisable,\n  onDelete,\n  isLoadingEndpoint,\n}: WebhooksEndpointTableProps) {\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [globalFilter, setGlobalFilter] = useState('')\n  const [deleteEndpoint, setDeleteEndpoint] = useState<EndpointOut | null>(null)\n  const [disableEndpoint, setDisableEndpoint] = useState<EndpointOut | null>(null)\n  const navigate = useNavigate()\n\n  const handleConfirmDelete = () => {\n    if (deleteEndpoint) {\n      onDelete(deleteEndpoint)\n      setDeleteEndpoint(null)\n    }\n  }\n\n  const handleConfirmDisable = () => {\n    if (disableEndpoint) {\n      onDisable(disableEndpoint)\n      setDisableEndpoint(null)\n    }\n  }\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getFilteredRowModel: getFilteredRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    onGlobalFilterChange: setGlobalFilter,\n    globalFilterFn: (row, _columnId, filterValue) => {\n      const endpoint = row.original\n      const searchValue = filterValue.toLowerCase()\n      return (\n        endpoint.url.toLowerCase().includes(searchValue) ||\n        (endpoint.description?.toLowerCase().includes(searchValue) ?? false) ||\n        endpoint.id.toLowerCase().includes(searchValue)\n      )\n    },\n    state: {\n      sorting,\n      globalFilter,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n    meta: {\n      webhookEndpoints: {\n        onDisable: setDisableEndpoint,\n        onDelete: setDeleteEndpoint,\n        isLoadingEndpoint,\n      },\n    },\n  })\n\n  const handleRowClick = (endpoint: EndpointOut) => {\n    navigate(RoutePath.WEBHOOK_ENDPOINT_DETAILS.replace(':endpointId', endpoint.id))\n  }\n\n  return (\n    <div>\n      <div className=\"flex items-center mb-4\">\n        <DebouncedInput\n          value={globalFilter ?? ''}\n          onChange={(value) => setGlobalFilter(String(value))}\n          placeholder=\"Search by URL or Description\"\n          className=\"max-w-sm\"\n        />\n      </div>\n      <div className=\"rounded-md border\">\n        <Table style={{ tableLayout: 'fixed', width: '100%' }}>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      className=\"px-2\"\n                      key={header.id}\n                      style={{\n                        width: `${header.column.getSize()}px`,\n                      }}\n                    >\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <>\n                {Array.from(new Array(5)).map((_, i) => (\n                  <TableRow key={i}>\n                    {table.getVisibleLeafColumns().map((column, colIndex, arr) =>\n                      colIndex === arr.length - 1 ? null : (\n                        <TableCell key={column.id} className=\"px-2\">\n                          <Skeleton className=\"h-4 w-10/12\" />\n                        </TableCell>\n                      ),\n                    )}\n                  </TableRow>\n                ))}\n              </>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => {\n                const isLoading = isLoadingEndpoint(row.original)\n                return (\n                  <TableRow\n                    key={row.id}\n                    data-state={row.getIsSelected() && 'selected'}\n                    className={`${isLoading ? 'opacity-50 pointer-events-none' : 'cursor-pointer hover:bg-muted/50 focus-visible:bg-muted/50 focus-visible:outline-none'}`}\n                    tabIndex={isLoading ? undefined : 0}\n                    role={isLoading ? undefined : 'link'}\n                    onClick={() => {\n                      if (!isLoading) {\n                        handleRowClick(row.original)\n                      }\n                    }}\n                    onKeyDown={(e) => {\n                      if (!isLoading && (e.key === 'Enter' || e.key === ' ')) {\n                        e.preventDefault()\n                        handleRowClick(row.original)\n                      }\n                    }}\n                  >\n                    {row.getVisibleCells().map((cell) => (\n                      <TableCell\n                        className=\"px-2\"\n                        key={cell.id}\n                        style={{\n                          width: `${cell.column.getSize()}px`,\n                        }}\n                      >\n                        {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                      </TableCell>\n                    ))}\n                  </TableRow>\n                )\n              })\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No webhook endpoints found.\"\n                icon={<Mail className=\"size-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>Create an endpoint to start receiving webhook events.</p>\n                    <p>\n                      <a\n                        href=\"https://www.daytona.io/docs/en/tools/api/#daytona/webhook/undefined/\"\n                        target=\"_blank\"\n                        rel=\"noopener noreferrer\"\n                        className=\"text-primary hover:underline font-medium\"\n                      >\n                        Check out the Docs\n                      </a>{' '}\n                      to learn more.\n                    </p>\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination table={table} className=\"mt-4\" entityName=\"Endpoints\" />\n\n      <AlertDialog open={!!deleteEndpoint} onOpenChange={(open) => !open && setDeleteEndpoint(null)}>\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>Delete Webhook Endpoint</AlertDialogTitle>\n            <AlertDialogDescription>\n              Are you sure you want to delete this webhook endpoint? This action cannot be undone.\n              {deleteEndpoint && (\n                <div className=\"mt-2 text-sm\">\n                  <strong>URL:</strong> {deleteEndpoint.url}\n                </div>\n              )}\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <AlertDialogAction variant=\"destructive\" onClick={handleConfirmDelete}>\n              Delete\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n\n      <AlertDialog open={!!disableEndpoint} onOpenChange={(open) => !open && setDisableEndpoint(null)}>\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>{disableEndpoint?.disabled ? 'Enable' : 'Disable'} Webhook Endpoint</AlertDialogTitle>\n            <AlertDialogDescription>\n              Are you sure you want to {disableEndpoint?.disabled ? 'enable' : 'disable'} this webhook endpoint?\n              {disableEndpoint && (\n                <div className=\"mt-2 text-sm\">\n                  <strong>URL:</strong> {disableEndpoint.url}\n                </div>\n              )}\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <AlertDialogAction onClick={handleConfirmDisable}>\n              {disableEndpoint?.disabled ? 'Enable' : 'Disable'}\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/WebhooksEndpointTable/columns.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { ColumnDef, RowData, Table } from '@tanstack/react-table'\nimport { MoreHorizontal } from 'lucide-react'\nimport { EndpointOut } from 'svix'\nimport { CopyButton } from '../../CopyButton'\n\ntype WebhooksEndpointTableMeta = {\n  onDisable: (endpoint: EndpointOut) => void\n  onDelete: (endpoint: EndpointOut) => void\n  isLoadingEndpoint: (endpoint: EndpointOut) => boolean\n}\n\ndeclare module '@tanstack/react-table' {\n  interface TableMeta<TData extends RowData> {\n    webhookEndpoints?: TData extends EndpointOut ? WebhooksEndpointTableMeta : never\n  }\n}\n\nconst getMeta = (table: Table<EndpointOut>) => {\n  return table.options.meta?.webhookEndpoints as WebhooksEndpointTableMeta\n}\n\nconst columns: ColumnDef<EndpointOut>[] = [\n  {\n    accessorKey: 'description',\n    header: 'Name',\n    size: 200,\n    cell: ({ row }) => (\n      <div className=\"w-full truncate flex items-center gap-2\">\n        <span className=\"truncate block hover:underline focus:underline cursor-pointer\">\n          {row.original.description || 'Unnamed Endpoint'}\n        </span>\n      </div>\n    ),\n  },\n  {\n    accessorKey: 'url',\n    header: 'URL',\n    size: 300,\n    cell: ({ row }) => (\n      <div className=\"w-full truncate flex items-center gap-2 group/copy-button\">\n        <span className=\"truncate block\">{row.original.url}</span>\n        <CopyButton value={row.original.url} size=\"icon-xs\" autoHide tooltipText=\"Copy URL\" />\n      </div>\n    ),\n  },\n  {\n    accessorKey: 'disabled',\n    header: 'Status',\n    size: 100,\n    cell: ({ row }) => (\n      <Badge variant={row.original.disabled ? 'secondary' : 'success'}>\n        {row.original.disabled ? 'Disabled' : 'Active'}\n      </Badge>\n    ),\n  },\n  {\n    accessorKey: 'createdAt',\n    header: 'Created',\n    size: 150,\n    cell: ({ row }) => {\n      const createdAt = row.original.createdAt\n      const relativeTime = getRelativeTimeString(createdAt).relativeTimeString\n\n      return (\n        <TimestampTooltip timestamp={typeof createdAt === 'string' ? createdAt : createdAt.toISOString()}>\n          <span className=\"cursor-default\">{relativeTime}</span>\n        </TimestampTooltip>\n      )\n    },\n  },\n  {\n    id: 'actions',\n    header: () => null,\n    maxSize: 44,\n    cell: ({ row, table }) => {\n      const { onDisable, onDelete, isLoadingEndpoint } = getMeta(table)\n      const isLoading = isLoadingEndpoint(row.original)\n\n      return (\n        <div className=\"flex justify-end\" onClick={(e) => e.stopPropagation()}>\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <Button variant=\"ghost\" size=\"icon-xs\" disabled={isLoading}>\n                <MoreHorizontal className=\"size-4\" />\n              </Button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\">\n              <DropdownMenuItem onClick={() => onDisable(row.original)} className=\"cursor-pointer\" disabled={isLoading}>\n                {row.original.disabled ? 'Enable' : 'Disable'}\n              </DropdownMenuItem>\n              <DropdownMenuItem\n                variant=\"destructive\"\n                onClick={() => onDelete(row.original)}\n                className=\"cursor-pointer\"\n                disabled={isLoading}\n              >\n                Delete\n              </DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </div>\n      )\n    },\n  },\n]\n\nexport { columns }\nexport type { WebhooksEndpointTableMeta }\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/WebhooksEndpointTable/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport { WebhooksEndpointTable } from './WebhooksEndpointTable'\nexport type { WebhooksEndpointTableMeta } from './columns'\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/WebhooksMessagesTable/MessageDetailsSheet.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Separator } from '@/components/ui/separator'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { ChevronDown, ChevronUp, X } from 'lucide-react'\nimport { MessageOut } from 'svix'\nimport { MessageAttemptsTable } from '../MessageAttemptsTable'\n\ninterface MessageDetailsSheetProps {\n  message: MessageOut | null\n  open: boolean\n  onOpenChange: (open: boolean) => void\n  onNavigate: (direction: 'prev' | 'next') => void\n  hasPrev: boolean\n  hasNext: boolean\n}\n\nexport function MessageDetailsSheet({\n  message,\n  open,\n  onOpenChange,\n  onNavigate,\n  hasPrev,\n  hasNext,\n}: MessageDetailsSheetProps) {\n  if (!message) return null\n\n  const hasPayload = message.payload && Object.keys(message.payload).length > 0\n  const payload = hasPayload\n    ? typeof message.payload === 'string'\n      ? message.payload\n      : JSON.stringify(message.payload, null, 2)\n    : ''\n  const { relativeTimeString } = getRelativeTimeString(message.timestamp)\n\n  return (\n    <Sheet open={open} onOpenChange={onOpenChange}>\n      <SheetContent className=\"w-dvw sm:w-[520px] p-0 flex flex-col gap-0 [&>button]:hidden\" side=\"right\">\n        <SheetHeader className=\"flex flex-row items-center justify-between p-4 px-5 space-y-0\">\n          <SheetTitle className=\"text-lg font-medium\">Message Details</SheetTitle>\n          <div className=\"flex items-center gap-1\">\n            <Button variant=\"ghost\" size=\"icon-sm\" disabled={!hasPrev} onClick={() => onNavigate('prev')}>\n              <ChevronUp className=\"size-4\" />\n              <span className=\"sr-only\">Previous message</span>\n            </Button>\n            <Button variant=\"ghost\" size=\"icon-sm\" disabled={!hasNext} onClick={() => onNavigate('next')}>\n              <ChevronDown className=\"size-4\" />\n              <span className=\"sr-only\">Next message</span>\n            </Button>\n            <Button variant=\"ghost\" size=\"icon-sm\" onClick={() => onOpenChange(false)}>\n              <X className=\"size-4\" />\n              <span className=\"sr-only\">Close</span>\n            </Button>\n          </div>\n        </SheetHeader>\n\n        <Separator />\n\n        <div className=\"flex-1 min-h-0 overflow-auto\">\n          <div className=\"flex flex-col px-5 py-4 gap-3\">\n            <span className=\"text-base font-medium\">Overview</span>\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-sm text-muted-foreground\">Message ID</span>\n              <div className=\"flex items-center gap-1 group/copy-button\">\n                <span className=\"text-sm font-mono\">{message.id}</span>\n                <CopyButton value={message.id} size=\"icon-xs\" tooltipText=\"Copy Message ID\" />\n              </div>\n            </div>\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-sm text-muted-foreground\">Event Type</span>\n              <Badge variant=\"secondary\">{message.eventType}</Badge>\n            </div>\n            {message.eventId && (\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-sm text-muted-foreground\">Event ID</span>\n                <div className=\"flex items-center gap-1 group/copy-button\">\n                  <span className=\"text-sm font-mono\">{message.eventId}</span>\n                  <CopyButton value={message.eventId} size=\"icon-xs\" tooltipText=\"Copy Event ID\" />\n                </div>\n              </div>\n            )}\n            <div className=\"flex items-center justify-between\">\n              <span className=\"text-sm text-muted-foreground\">Timestamp</span>\n              <TimestampTooltip\n                timestamp={\n                  message.timestamp instanceof Date ? message.timestamp.toISOString() : String(message.timestamp)\n                }\n              >\n                <span className=\"text-sm cursor-default\">{relativeTimeString}</span>\n              </TimestampTooltip>\n            </div>\n            {message.channels && message.channels.length > 0 && (\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-sm text-muted-foreground\">Channels</span>\n                <div className=\"flex items-center gap-1 flex-wrap justify-end\">\n                  {message.channels.map((channel) => (\n                    <Badge key={channel} variant=\"outline\" className=\"font-normal text-xs\">\n                      {channel}\n                    </Badge>\n                  ))}\n                </div>\n              </div>\n            )}\n            {message.tags && message.tags.length > 0 && (\n              <div className=\"flex items-center justify-between\">\n                <span className=\"text-sm text-muted-foreground\">Tags</span>\n                <div className=\"flex items-center gap-1 flex-wrap justify-end\">\n                  {message.tags.map((tag) => (\n                    <Badge key={tag} variant=\"outline\" className=\"font-normal text-xs\">\n                      {tag}\n                    </Badge>\n                  ))}\n                </div>\n              </div>\n            )}\n          </div>\n\n          <Separator />\n\n          <div className=\"flex flex-col px-5 py-4\">\n            <div className=\"flex items-center justify-between mb-3\">\n              <span className=\"text-base font-medium\">Payload</span>\n              {hasPayload && <CopyButton value={payload} size=\"icon-xs\" tooltipText=\"Copy Payload\" />}\n            </div>\n            {hasPayload ? (\n              <pre className=\"text-sm font-mono bg-muted/80 p-3 rounded-md overflow-auto whitespace-pre-wrap break-all\">\n                {payload}\n              </pre>\n            ) : (\n              <div className=\"text-sm bg-muted/80 p-3 rounded-md\">\n                <span className=\"italic text-muted-foreground\">This message has no payload</span>\n              </div>\n            )}\n          </div>\n\n          <Separator />\n\n          <div className=\"flex flex-col px-5 py-4\">\n            <MessageAttemptsTable messageId={message.id} />\n          </div>\n        </div>\n      </SheetContent>\n    </Sheet>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/WebhooksMessagesTable/WebhooksMessagesTable.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DebouncedInput } from '@/components/DebouncedInput'\nimport { Pagination } from '@/components/Pagination'\nimport { TableEmptyState } from '@/components/TableEmptyState'\nimport { DataTableFacetedFilter } from '@/components/ui/data-table-faceted-filter'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport {\n  ColumnFiltersState,\n  flexRender,\n  getCoreRowModel,\n  getFacetedRowModel,\n  getFacetedUniqueValues,\n  getFilteredRowModel,\n  getPaginationRowModel,\n  getSortedRowModel,\n  SortingState,\n  useReactTable,\n} from '@tanstack/react-table'\nimport { Mail, RefreshCcw } from 'lucide-react'\nimport { useCallback, useState } from 'react'\nimport { Button } from '@/components/ui/button'\nimport { useMessages } from 'svix-react'\nimport { columns, eventTypeOptions } from './columns'\nimport { MessageDetailsSheet } from './MessageDetailsSheet'\n\nexport function WebhooksMessagesTable() {\n  const messages = useMessages()\n  const [sorting, setSorting] = useState<SortingState>([])\n  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])\n  const [globalFilter, setGlobalFilter] = useState('')\n  const [selectedMessageIndex, setSelectedMessageIndex] = useState<number | null>(null)\n  const [sheetOpen, setSheetOpen] = useState(false)\n\n  const data = messages.data ?? []\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    getFilteredRowModel: getFilteredRowModel(),\n    getPaginationRowModel: getPaginationRowModel(),\n    onSortingChange: setSorting,\n    getSortedRowModel: getSortedRowModel(),\n    onColumnFiltersChange: setColumnFilters,\n    getFacetedRowModel: getFacetedRowModel(),\n    getFacetedUniqueValues: getFacetedUniqueValues(),\n    onGlobalFilterChange: setGlobalFilter,\n    globalFilterFn: (row, _columnId, filterValue) => {\n      const message = row.original\n      const searchValue = filterValue.toLowerCase()\n      return (\n        (message.id?.toLowerCase().includes(searchValue) ?? false) ||\n        (message.eventType?.toLowerCase().includes(searchValue) ?? false) ||\n        (message.eventId?.toLowerCase().includes(searchValue) ?? false)\n      )\n    },\n    state: {\n      sorting,\n      columnFilters,\n      globalFilter,\n    },\n    initialState: {\n      pagination: {\n        pageSize: DEFAULT_PAGE_SIZE,\n      },\n    },\n  })\n\n  const handleRowClick = useCallback((index: number) => {\n    setSelectedMessageIndex(index)\n    setSheetOpen(true)\n  }, [])\n\n  const rowCount = table.getRowModel().rows.length\n\n  const handleNavigate = useCallback(\n    (direction: 'prev' | 'next') => {\n      setSelectedMessageIndex((prev) => {\n        if (prev === null) return null\n        if (direction === 'prev' && prev > 0) return prev - 1\n        if (direction === 'next' && prev < rowCount - 1) return prev + 1\n        return prev\n      })\n    },\n    [rowCount],\n  )\n\n  return (\n    <div>\n      <div className=\"flex items-center mb-4\">\n        <DebouncedInput\n          value={globalFilter ?? ''}\n          onChange={(value) => setGlobalFilter(String(value))}\n          placeholder=\"Search by Message ID, Event Type, or Event ID\"\n          className=\"max-w-sm mr-4\"\n        />\n        {table.getColumn('eventType') && (\n          <DataTableFacetedFilter column={table.getColumn('eventType')} title=\"Event Type\" options={eventTypeOptions} />\n        )}\n        <Button\n          variant=\"ghost\"\n          size=\"icon-sm\"\n          onClick={() => messages.reload()}\n          disabled={messages.loading}\n          className=\"ml-auto\"\n        >\n          <RefreshCcw className=\"h-4 w-4\" />\n        </Button>\n      </div>\n      <div className=\"rounded-md border\">\n        <Table style={{ tableLayout: 'fixed', width: '100%' }}>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => (\n                  <TableHead className=\"px-2\" key={header.id} style={{ width: `${header.column.getSize()}px` }}>\n                    {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                  </TableHead>\n                ))}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {messages.loading ? (\n              <>\n                {Array.from(new Array(5)).map((_, i) => (\n                  <TableRow key={i}>\n                    {table.getVisibleLeafColumns().map((column) => (\n                      <TableCell key={column.id} className=\"px-2\">\n                        <Skeleton className=\"h-4 w-10/12\" />\n                      </TableCell>\n                    ))}\n                  </TableRow>\n                ))}\n              </>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row, rowIndex) => (\n                <TableRow\n                  key={row.id}\n                  data-state={row.getIsSelected() && 'selected'}\n                  className={`cursor-pointer hover:bg-muted/50 focus-visible:bg-muted/50 focus-visible:outline-none ${sheetOpen && selectedMessageIndex === rowIndex ? 'bg-muted/50' : ''}`}\n                  tabIndex={0}\n                  role=\"button\"\n                  onClick={() => handleRowClick(rowIndex)}\n                  onKeyDown={(e) => {\n                    if (e.key === 'Enter' || e.key === ' ') {\n                      e.preventDefault()\n                      handleRowClick(rowIndex)\n                    }\n                  }}\n                >\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell className=\"px-2\" key={cell.id} style={{ width: `${cell.column.getSize()}px` }}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No messages found.\"\n                icon={<Mail className=\"size-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>Messages will appear here when webhook events are triggered.</p>\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination table={table} className=\"mt-4\" entityName=\"Messages\" />\n      <MessageDetailsSheet\n        message={\n          selectedMessageIndex !== null ? (table.getRowModel().rows[selectedMessageIndex]?.original ?? null) : null\n        }\n        open={sheetOpen}\n        onOpenChange={setSheetOpen}\n        onNavigate={handleNavigate}\n        hasPrev={selectedMessageIndex !== null && selectedMessageIndex > 0}\n        hasNext={selectedMessageIndex !== null && selectedMessageIndex < table.getRowModel().rows.length - 1}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/Webhooks/WebhooksMessagesTable/columns.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport { Badge } from '@/components/ui/badge'\nimport { FacetedFilterOption } from '@/components/ui/data-table-faceted-filter'\nimport { WEBHOOK_EVENTS } from '@/constants/webhook-events'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { ColumnDef } from '@tanstack/react-table'\nimport { MessageOut } from 'svix'\nimport { CopyButton } from '../../CopyButton'\n\nconst columns: ColumnDef<MessageOut>[] = [\n  {\n    accessorKey: 'id',\n    header: 'Message ID',\n    size: 300,\n    cell: ({ row }) => {\n      const msgId = row.original.id\n      return (\n        <div className=\"w-full truncate flex items-center gap-2 group/copy-button\">\n          <span className=\"truncate block font-mono text-sm hover:underline focus:underline cursor-pointer\">\n            {msgId ?? '-'}\n          </span>\n          {msgId && (\n            <span onClick={(e) => e.stopPropagation()}>\n              <CopyButton value={msgId} size=\"icon-xs\" autoHide tooltipText=\"Copy Message ID\" />\n            </span>\n          )}\n        </div>\n      )\n    },\n  },\n  {\n    accessorKey: 'eventType',\n    header: 'Event Type',\n    size: 200,\n    filterFn: (row, id, value) => {\n      return value.includes(row.getValue(id))\n    },\n    cell: ({ row }) => {\n      const eventType = row.original.eventType\n      return (\n        <Badge variant=\"secondary\" className=\"font-normal text-xs\">\n          {eventType}\n        </Badge>\n      )\n    },\n  },\n  {\n    accessorKey: 'timestamp',\n    header: 'Timestamp',\n    size: 200,\n    cell: ({ row }) => {\n      const timestamp = row.original.timestamp\n      if (!timestamp) {\n        return <span className=\"text-muted-foreground\">-</span>\n      }\n      const relativeTime = getRelativeTimeString(timestamp)\n\n      return (\n        <TimestampTooltip timestamp={timestamp.toString()}>\n          <span className=\"cursor-default\">{relativeTime.relativeTimeString}</span>\n        </TimestampTooltip>\n      )\n    },\n  },\n]\n\nconst eventTypeOptions: FacetedFilterOption[] = WEBHOOK_EVENTS.map((event) => ({\n  label: event.label,\n  value: event.value,\n}))\n\nexport { columns, eventTypeOptions }\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/CreateSshAccessDialog.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useCallback, useEffect, useState } from 'react'\nimport { SshAccessDto } from '@daytonaio/api-client'\nimport { useForm } from '@tanstack/react-form'\nimport { CheckIcon, CopyIcon, InfoIcon } from 'lucide-react'\nimport { AnimatePresence, motion } from 'motion/react'\nimport { NumericFormat } from 'react-number-format'\nimport { z } from 'zod'\nimport { Field, FieldError, FieldLabel } from '@/components/ui/field'\nimport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupInput,\n  InputGroupText,\n} from '@/components/ui/input-group'\nimport { Spinner } from '@/components/ui/spinner'\nimport { Alert, AlertDescription } from '@/components/ui/alert'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\nimport { useCreateSshAccessMutation } from '@/hooks/mutations/useCreateSshAccessMutation'\nimport { useCopyToClipboard } from '@/hooks/useCopyToClipboard'\nimport { handleApiError } from '@/lib/error-handling'\n\ninterface CreateSshAccessDialogProps {\n  sandboxId: string\n  open: boolean\n  onOpenChange: (open: boolean) => void\n}\n\nconst MotionCopyIcon = motion(CopyIcon)\nconst MotionCheckIcon = motion(CheckIcon)\n\nconst iconProps = {\n  initial: { opacity: 0, y: 5 },\n  animate: { opacity: 1, y: 0 },\n  exit: { opacity: 0, y: -5 },\n  transition: { duration: 0.1 },\n}\n\nconst formSchema = z.object({\n  expiryMinutes: z.number().int('Must be a whole number').min(1, 'Minimum 1 minute').max(1440, 'Maximum 1440 minutes'),\n})\n\ntype FormValues = z.infer<typeof formSchema>\n\nconst defaultValues: FormValues = {\n  expiryMinutes: 60,\n}\n\nexport function CreateSshAccessDialog({ sandboxId, open, onOpenChange }: CreateSshAccessDialogProps) {\n  const [sshAccess, setSshAccess] = useState<SshAccessDto | null>(null)\n  const { reset: resetMutation, ...createMutation } = useCreateSshAccessMutation()\n\n  const form = useForm({\n    defaultValues,\n    validators: {\n      onSubmit: formSchema,\n    },\n    onSubmit: async ({ value }) => {\n      try {\n        const result = await createMutation.mutateAsync({\n          sandboxId,\n          expiresInMinutes: value.expiryMinutes,\n        })\n        setSshAccess(result)\n      } catch (error) {\n        handleApiError(error, 'Failed to create SSH access')\n      }\n    },\n  })\n\n  const resetState = useCallback(() => {\n    form.reset(defaultValues)\n    resetMutation()\n    setSshAccess(null)\n  }, [form, resetMutation])\n\n  useEffect(() => {\n    if (open) {\n      resetState()\n    }\n  }, [open, resetState])\n\n  return (\n    <Dialog open={open} onOpenChange={onOpenChange}>\n      <DialogContent className=\"max-w-sm\">\n        <DialogHeader>\n          <DialogTitle>{sshAccess ? 'SSH Access Created' : 'Create SSH Access'}</DialogTitle>\n          <DialogDescription>\n            {sshAccess ? 'Your SSH access has been created successfully.' : 'Set the expiration time for SSH access.'}\n          </DialogDescription>\n        </DialogHeader>\n        {sshAccess ? (\n          <SshAccessCreated sshAccess={sshAccess} />\n        ) : (\n          <form\n            id=\"create-ssh-form\"\n            onSubmit={(e) => {\n              e.preventDefault()\n              e.stopPropagation()\n              form.handleSubmit()\n            }}\n          >\n            <form.Field name=\"expiryMinutes\">\n              {(field) => {\n                const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                return (\n                  <Field data-invalid={isInvalid}>\n                    <FieldLabel htmlFor={field.name}>Expiry</FieldLabel>\n                    <InputGroup>\n                      <NumericFormat\n                        customInput={InputGroupInput}\n                        aria-invalid={isInvalid}\n                        id={field.name}\n                        name={field.name}\n                        inputMode=\"numeric\"\n                        allowNegative={false}\n                        decimalScale={0}\n                        value={field.state.value}\n                        onBlur={field.handleBlur}\n                        onValueChange={({ floatValue }) => field.handleChange(floatValue ?? 0)}\n                      />\n                      <InputGroupAddon align=\"inline-end\">\n                        <InputGroupText>min</InputGroupText>\n                      </InputGroupAddon>\n                    </InputGroup>\n                    {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                      <FieldError errors={field.state.meta.errors} />\n                    )}\n                  </Field>\n                )\n              }}\n            </form.Field>\n          </form>\n        )}\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button variant=\"secondary\">Close</Button>\n          </DialogClose>\n          {!sshAccess && (\n            <form.Subscribe\n              selector={(state) => [state.canSubmit, state.isSubmitting]}\n              children={([canSubmit, isSubmitting]) => (\n                <Button type=\"submit\" form=\"create-ssh-form\" disabled={!canSubmit || isSubmitting}>\n                  {isSubmitting && <Spinner />}\n                  Create\n                </Button>\n              )}\n            />\n          )}\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction SshAccessCreated({ sshAccess }: { sshAccess: SshAccessDto }) {\n  const [copiedCommand, copyCommand] = useCopyToClipboard()\n\n  return (\n    <div className=\"space-y-4\">\n      <Alert variant=\"warning\">\n        <InfoIcon />\n        <AlertDescription>Store the token safely — you won't be able to view it again.</AlertDescription>\n      </Alert>\n      <Field>\n        <FieldLabel htmlFor=\"ssh-command\">SSH Command</FieldLabel>\n        <InputGroup className=\"pr-1\">\n          <InputGroupInput id=\"ssh-command\" value={sshAccess.sshCommand} readOnly />\n          <InputGroupButton variant=\"ghost\" size=\"icon-xs\" onClick={() => copyCommand(sshAccess.sshCommand)}>\n            <AnimatePresence initial={false} mode=\"wait\">\n              {copiedCommand ? (\n                <MotionCheckIcon className=\"size-4\" key=\"copied\" {...iconProps} />\n              ) : (\n                <MotionCopyIcon className=\"size-4\" key=\"copy\" {...iconProps} />\n              )}\n            </AnimatePresence>\n          </InputGroupButton>\n        </InputGroup>\n      </Field>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/RevokeSshAccessDialog.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useState } from 'react'\nimport { toast } from 'sonner'\nimport { Field, FieldLabel } from '@/components/ui/field'\nimport { Input } from '@/components/ui/input'\nimport { Spinner } from '@/components/ui/spinner'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Button } from '@/components/ui/button'\nimport { useRevokeSshAccessMutation } from '@/hooks/mutations/useRevokeSshAccessMutation'\nimport { handleApiError } from '@/lib/error-handling'\n\ninterface RevokeSshAccessDialogProps {\n  sandboxId: string\n  open: boolean\n  onOpenChange: (open: boolean) => void\n}\n\nexport function RevokeSshAccessDialog({ sandboxId, open, onOpenChange }: RevokeSshAccessDialogProps) {\n  const [token, setToken] = useState('')\n  const revokeMutation = useRevokeSshAccessMutation()\n\n  const handleOpenChange = (isOpen: boolean) => {\n    onOpenChange(isOpen)\n    if (!isOpen) {\n      setToken('')\n      revokeMutation.reset()\n    }\n  }\n\n  const handleRevoke = async () => {\n    if (!token.trim()) {\n      toast.error('Please enter a token to revoke')\n      return\n    }\n    try {\n      await revokeMutation.mutateAsync({ sandboxId, token })\n      toast.success('SSH access revoked successfully')\n      handleOpenChange(false)\n    } catch (error) {\n      handleApiError(error, 'Failed to revoke SSH access')\n    }\n  }\n\n  return (\n    <Dialog open={open} onOpenChange={handleOpenChange}>\n      <DialogContent className=\"max-w-sm\">\n        <DialogHeader>\n          <DialogTitle>Revoke SSH Access</DialogTitle>\n          <DialogDescription>Enter the SSH access token you want to revoke.</DialogDescription>\n        </DialogHeader>\n        <Field>\n          <FieldLabel htmlFor=\"ssh-revoke-token\">SSH Token</FieldLabel>\n          <Input\n            id=\"ssh-revoke-token\"\n            value={token}\n            onChange={(e) => setToken(e.target.value)}\n            placeholder=\"Paste token here\"\n          />\n        </Field>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button variant=\"secondary\">Cancel</Button>\n          </DialogClose>\n          <Button variant=\"destructive\" onClick={handleRevoke} disabled={!token.trim() || revokeMutation.isPending}>\n            {revokeMutation.isPending && <Spinner />}\n            Revoke\n          </Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxContentTabs.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Spinner } from '@/components/ui/spinner'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport { useRegions } from '@/hooks/useRegions'\nimport { Sandbox } from '@daytonaio/api-client'\nimport { SandboxInfoPanel } from './SandboxInfoPanel'\nimport { SandboxLogsTab } from './SandboxLogsTab'\nimport { SandboxMetricsTab } from './SandboxMetricsTab'\nimport { SandboxSpendingTab } from './SandboxSpendingTab'\nimport { SandboxTerminalTab } from './SandboxTerminalTab'\nimport { SandboxTracesTab } from './SandboxTracesTab'\nimport { SandboxVncTab } from './SandboxVncTab'\nimport { TabValue } from './SearchParams'\n\ninterface SandboxContentTabsProps {\n  sandbox: Sandbox | undefined\n  isLoading: boolean\n  experimentsEnabled: boolean | undefined\n  tab: TabValue\n  onTabChange: (tab: TabValue) => void\n}\n\nexport function SandboxContentTabs({\n  sandbox,\n  isLoading,\n  experimentsEnabled,\n  tab,\n  onTabChange,\n}: SandboxContentTabsProps) {\n  const { getRegionName } = useRegions()\n\n  if (isLoading) {\n    return (\n      <div className=\"flex flex-col h-full\">\n        <div className=\"flex items-center gap-0 border-b border-border h-[41px] px-4 shrink-0\">\n          <Skeleton className=\"h-4 w-16 lg:hidden\" />\n          <Skeleton className=\"h-4 w-10 ml-4 lg:ml-0\" />\n          <Skeleton className=\"h-4 w-12 ml-4\" />\n          <Skeleton className=\"h-4 w-14 ml-4\" />\n          <Skeleton className=\"h-4 w-16 ml-4\" />\n          <Skeleton className=\"h-4 w-10 ml-4\" />\n        </div>\n        <div className=\"flex-1 flex items-center justify-center text-muted-foreground\">\n          <Spinner className=\"size-5\" />\n        </div>\n      </div>\n    )\n  }\n\n  if (!sandbox) return null\n\n  return (\n    <Tabs value={tab} onValueChange={(v) => onTabChange(v as TabValue)} className=\"flex flex-col h-full gap-0\">\n      <TabsList variant=\"underline\" className=\"h-[41px] overflow-x-auto overflow-y-hidden scrollbar-sm\">\n        <TabsTrigger value=\"overview\" className=\"lg:hidden\">\n          Overview\n        </TabsTrigger>\n        {experimentsEnabled && (\n          <>\n            <TabsTrigger value=\"logs\">Logs</TabsTrigger>\n            <TabsTrigger value=\"traces\">Traces</TabsTrigger>\n            <TabsTrigger value=\"metrics\">Metrics</TabsTrigger>\n            <TabsTrigger value=\"spending\">Spending</TabsTrigger>\n          </>\n        )}\n        <TabsTrigger value=\"terminal\">Terminal</TabsTrigger>\n        <TabsTrigger value=\"vnc\">VNC</TabsTrigger>\n      </TabsList>\n\n      <TabsContent value=\"overview\" className=\"flex-1 min-h-0 m-0 overflow-y-auto scrollbar-sm lg:hidden\">\n        <SandboxInfoPanel sandbox={sandbox} getRegionName={getRegionName} />\n      </TabsContent>\n      {experimentsEnabled && (\n        <>\n          <TabsContent value=\"logs\" className=\"flex-1 min-h-0 m-0 data-[state=active]:flex flex-col overflow-hidden\">\n            <SandboxLogsTab sandboxId={sandbox.id} />\n          </TabsContent>\n          <TabsContent value=\"traces\" className=\"flex-1 min-h-0 m-0 data-[state=active]:flex flex-col overflow-hidden\">\n            <SandboxTracesTab sandboxId={sandbox.id} />\n          </TabsContent>\n          <TabsContent value=\"metrics\" className=\"flex-1 min-h-0 m-0 data-[state=active]:flex flex-col overflow-hidden\">\n            <SandboxMetricsTab sandboxId={sandbox.id} />\n          </TabsContent>\n          <TabsContent\n            value=\"spending\"\n            className=\"flex-1 min-h-0 m-0 data-[state=active]:flex flex-col overflow-hidden\"\n          >\n            <SandboxSpendingTab sandboxId={sandbox.id} />\n          </TabsContent>\n        </>\n      )}\n      <TabsContent value=\"terminal\" className=\"flex-1 min-h-0 m-0 data-[state=active]:flex flex-col overflow-hidden\">\n        <SandboxTerminalTab sandbox={sandbox} />\n      </TabsContent>\n      <TabsContent value=\"vnc\" className=\"flex-1 min-h-0 m-0 data-[state=active]:flex flex-col overflow-hidden\">\n        <SandboxVncTab sandbox={sandbox} />\n      </TabsContent>\n    </Tabs>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxDetails.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OrganizationSuspendedError } from '@/api/errors'\nimport { PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from '@/components/ui/alert-dialog'\nimport { Button } from '@/components/ui/button'\nimport { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { FeatureFlags } from '@/enums/FeatureFlags'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useArchiveSandboxMutation } from '@/hooks/mutations/useArchiveSandboxMutation'\nimport { useDeleteSandboxMutation } from '@/hooks/mutations/useDeleteSandboxMutation'\nimport { useRecoverSandboxMutation } from '@/hooks/mutations/useRecoverSandboxMutation'\nimport { useStartSandboxMutation } from '@/hooks/mutations/useStartSandboxMutation'\nimport { useStopSandboxMutation } from '@/hooks/mutations/useStopSandboxMutation'\nimport { useSandboxQuery } from '@/hooks/queries/useSandboxQuery'\nimport { useApi } from '@/hooks/useApi'\nimport { useConfig } from '@/hooks/useConfig'\nimport { useMatchMedia } from '@/hooks/useMatchMedia'\nimport { useRegions } from '@/hooks/useRegions'\nimport { useSandboxWsSync } from '@/hooks/useSandboxWsSync'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { isStoppable, isTransitioning } from '@/lib/utils/sandbox'\nimport { SandboxSessionProvider } from '@/providers/SandboxSessionProvider'\nimport { OrganizationRolePermissionsEnum, OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport { isAxiosError } from 'axios'\nimport { Container, GripVertical, RefreshCw } from 'lucide-react'\nimport { useQueryState } from 'nuqs'\nimport { useFeatureFlagEnabled } from 'posthog-js/react'\nimport { useEffect, useState } from 'react'\nimport { Group, Panel, Separator } from 'react-resizable-panels'\nimport { useNavigate, useParams } from 'react-router-dom'\nimport { toast } from 'sonner'\nimport { CreateSshAccessDialog } from './CreateSshAccessDialog'\nimport { RevokeSshAccessDialog } from './RevokeSshAccessDialog'\nimport { SandboxContentTabs } from './SandboxContentTabs'\nimport { SandboxHeader } from './SandboxHeader'\nimport { InfoPanelSkeleton, SandboxInfoPanel } from './SandboxInfoPanel'\nimport { tabParser } from './SearchParams'\n\nexport default function SandboxDetails() {\n  const { sandboxId } = useParams<{ sandboxId: string }>()\n  const navigate = useNavigate()\n  const config = useConfig()\n  const { sandboxApi } = useApi()\n  const { authenticatedUserOrganizationMember, selectedOrganization, authenticatedUserHasPermission } =\n    useSelectedOrganization()\n  const { getRegionName } = useRegions()\n\n  const experimentsEnabled = useFeatureFlagEnabled(FeatureFlags.ORGANIZATION_EXPERIMENTS)\n\n  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)\n  const [createSshDialogOpen, setCreateSshDialogOpen] = useState(false)\n  const [revokeSshDialogOpen, setRevokeSshDialogOpen] = useState(false)\n  const [tab, setTab] = useQueryState('tab', tabParser)\n  const isDesktop = useMatchMedia('(min-width: 1024px)')\n\n  // On desktop (lg+), the overview tab is hidden in the sidebar, so switch to a content tab\n  useEffect(() => {\n    if (isDesktop && tab === 'overview') {\n      setTab(experimentsEnabled ? 'logs' : 'terminal')\n    }\n  }, [isDesktop, tab, setTab, experimentsEnabled])\n\n  // When experiments are disabled, coerce experimental tabs back to a supported default\n  useEffect(() => {\n    if (!experimentsEnabled && (tab === 'logs' || tab === 'traces' || tab === 'metrics' || tab === 'spending')) {\n      setTab('terminal')\n    }\n  }, [experimentsEnabled, tab, setTab])\n\n  const { data: sandbox, isLoading, isError, error, refetch, isFetching } = useSandboxQuery(sandboxId ?? '')\n  const isNotFound = isError && isAxiosError(error.cause) && error.cause?.status === 404\n\n  useSandboxWsSync({ sandboxId })\n\n  const startMutation = useStartSandboxMutation()\n  const stopMutation = useStopSandboxMutation()\n  const archiveMutation = useArchiveSandboxMutation()\n  const recoverMutation = useRecoverSandboxMutation()\n  const deleteMutation = useDeleteSandboxMutation()\n\n  const writePermitted = authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_SANDBOXES)\n  const deletePermitted = authenticatedUserHasPermission(OrganizationRolePermissionsEnum.DELETE_SANDBOXES)\n  const transitioning = sandbox ? isTransitioning(sandbox) : false\n  const anyMutating =\n    startMutation.isPending ||\n    stopMutation.isPending ||\n    archiveMutation.isPending ||\n    recoverMutation.isPending ||\n    deleteMutation.isPending\n  const actionsDisabled = anyMutating || transitioning\n\n  const handleStart = async () => {\n    if (!sandbox) return\n    try {\n      await startMutation.mutateAsync({ sandboxId: sandbox.id })\n      toast.success('Sandbox started')\n    } catch (error) {\n      handleApiError(\n        error,\n        'Failed to start sandbox',\n        error instanceof OrganizationSuspendedError &&\n          config.billingApiUrl &&\n          authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER ? (\n          <Button variant=\"secondary\" onClick={() => navigate(RoutePath.BILLING_WALLET)}>\n            Go to billing\n          </Button>\n        ) : undefined,\n      )\n    }\n  }\n\n  const handleStop = async () => {\n    if (!sandbox) return\n    try {\n      await stopMutation.mutateAsync({ sandboxId: sandbox.id })\n      toast.success('Sandbox stopped')\n    } catch (error) {\n      handleApiError(error, 'Failed to stop sandbox')\n    }\n  }\n\n  const handleArchive = async () => {\n    if (!sandbox) return\n    try {\n      await archiveMutation.mutateAsync({ sandboxId: sandbox.id })\n      toast.success('Sandbox archived')\n    } catch (error) {\n      handleApiError(error, 'Failed to archive sandbox')\n    }\n  }\n\n  const handleRecover = async () => {\n    if (!sandbox) return\n    try {\n      await recoverMutation.mutateAsync({ sandboxId: sandbox.id })\n      toast.success('Sandbox recovery started')\n    } catch (error) {\n      handleApiError(error, 'Failed to recover sandbox')\n    }\n  }\n\n  const handleDelete = async () => {\n    if (!sandbox) return\n    try {\n      await deleteMutation.mutateAsync({ sandboxId: sandbox.id })\n      toast.success('Sandbox deleted')\n      setDeleteDialogOpen(false)\n      navigate(RoutePath.SANDBOXES)\n    } catch (error) {\n      handleApiError(error, 'Failed to delete sandbox')\n    }\n  }\n\n  const handleScreenRecordings = async () => {\n    if (!sandbox || !isStoppable(sandbox)) {\n      toast.error('Sandbox must be started to access Screen Recordings')\n      return\n    }\n    try {\n      const response = await sandboxApi.getSignedPortPreviewUrl(sandbox.id, 33333, selectedOrganization?.id)\n      window.open(response.data.url, '_blank', 'noopener,noreferrer')\n      toast.success('Opening Screen Recordings dashboard...')\n    } catch (error) {\n      handleApiError(error, 'Failed to open Screen Recordings')\n    }\n  }\n\n  return (\n    <SandboxSessionProvider>\n      <PageLayout className=\"max-h-screen overflow-hidden\">\n        <PageHeader>\n          <PageTitle>Sandboxes</PageTitle>\n        </PageHeader>\n\n        <SandboxHeader\n          sandbox={sandbox}\n          isLoading={isLoading}\n          writePermitted={writePermitted}\n          deletePermitted={deletePermitted}\n          actionsDisabled={actionsDisabled}\n          isFetching={isFetching}\n          onStart={handleStart}\n          onStop={handleStop}\n          onArchive={handleArchive}\n          onRecover={handleRecover}\n          onDelete={() => setDeleteDialogOpen(true)}\n          onRefresh={() => refetch()}\n          onBack={() => navigate(RoutePath.SANDBOXES)}\n          onCreateSshAccess={() => setCreateSshDialogOpen(true)}\n          onRevokeSshAccess={() => setRevokeSshDialogOpen(true)}\n          onScreenRecordings={handleScreenRecordings}\n          mutations={{\n            start: startMutation.isPending,\n            stop: stopMutation.isPending,\n            archive: archiveMutation.isPending,\n            recover: recoverMutation.isPending,\n          }}\n        />\n\n        {isNotFound ? (\n          <div className=\"flex flex-1 min-h-0 items-center justify-center\">\n            <Empty>\n              <EmptyHeader>\n                <EmptyMedia variant=\"icon\">\n                  <Container className=\"size-4\" />\n                </EmptyMedia>\n                <EmptyTitle>Sandbox not found</EmptyTitle>\n                <EmptyDescription>Are you sure you're in the right organization?</EmptyDescription>\n              </EmptyHeader>\n              <Button variant=\"outline\" size=\"sm\" onClick={() => navigate(RoutePath.SANDBOXES)}>\n                Back to Sandboxes\n              </Button>\n            </Empty>\n          </div>\n        ) : (\n          <Group orientation=\"horizontal\" className=\"flex flex-1 min-h-0 overflow-hidden\">\n            {isDesktop && (\n              <>\n                <Panel\n                  id=\"overview\"\n                  minSize={250}\n                  maxSize={550}\n                  defaultSize={320}\n                  className=\"flex flex-col overflow-hidden\"\n                >\n                  <div className=\"flex items-center px-5 border-b border-border shrink-0 h-[41px]\">\n                    <span className=\"text-sm font-medium\">Overview</span>\n                  </div>\n                  <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0\">\n                    {isLoading ? (\n                      <InfoPanelSkeleton />\n                    ) : isError || !sandbox ? (\n                      <div className=\"flex flex-col items-center justify-center gap-3 p-8 text-center text-muted-foreground\">\n                        <p className=\"text-sm\">Failed to load sandbox details.</p>\n                        <Button variant=\"outline\" size=\"sm\" onClick={() => refetch()}>\n                          <RefreshCw className=\"size-4\" />\n                          Retry\n                        </Button>\n                      </div>\n                    ) : (\n                      <SandboxInfoPanel sandbox={sandbox} getRegionName={getRegionName} />\n                    )}\n                  </ScrollArea>\n                </Panel>\n                <ResizableSeparator />\n              </>\n            )}\n            <Panel id=\"content\" className=\"flex-1 min-w-0 flex flex-col overflow-hidden\">\n              <SandboxContentTabs\n                sandbox={sandbox}\n                isLoading={isLoading}\n                experimentsEnabled={experimentsEnabled}\n                tab={tab}\n                onTabChange={setTab}\n              />\n            </Panel>\n          </Group>\n        )}\n\n        <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\n          <AlertDialogContent>\n            <AlertDialogHeader>\n              <AlertDialogTitle>Delete Sandbox</AlertDialogTitle>\n              <AlertDialogDescription>\n                Are you sure you want to delete this sandbox? This action cannot be undone.\n              </AlertDialogDescription>\n            </AlertDialogHeader>\n            <AlertDialogFooter>\n              <AlertDialogCancel disabled={deleteMutation.isPending}>Cancel</AlertDialogCancel>\n              <AlertDialogAction variant=\"destructive\" onClick={handleDelete} disabled={deleteMutation.isPending}>\n                {deleteMutation.isPending ? 'Deleting...' : 'Delete'}\n              </AlertDialogAction>\n            </AlertDialogFooter>\n          </AlertDialogContent>\n        </AlertDialog>\n\n        {sandboxId && (\n          <>\n            <CreateSshAccessDialog\n              sandboxId={sandboxId}\n              open={createSshDialogOpen}\n              onOpenChange={setCreateSshDialogOpen}\n            />\n            <RevokeSshAccessDialog\n              sandboxId={sandboxId}\n              open={revokeSshDialogOpen}\n              onOpenChange={setRevokeSshDialogOpen}\n            />\n          </>\n        )}\n      </PageLayout>\n    </SandboxSessionProvider>\n  )\n}\n\nfunction ResizableSeparator() {\n  return (\n    <Separator className=\"group relative flex w-px items-center justify-center bg-transparent text-muted-foreground focus-visible:outline-none after:absolute after:inset-y-0 after:left-1/2 after:w-px after:-translate-x-1/2 after:bg-border after:transition-colors data-[separator=hover]:text-primary data-[separator=hover]:after:bg-primary data-[separator=active]:text-primary data-[separator=active]:after:bg-primary focus-visible:text-primary\">\n      <div className=\"z-10 flex h-6 w-3.5 items-center justify-center rounded-sm border border-border bg-background transition-colors group-data-[separator=hover]:border-current group-data-[separator=active]:border-current group-focus-visible:border-current\">\n        <GripVertical className=\"size-3 text-current\" />\n      </div>\n    </Separator>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxHeader.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { SandboxState } from '@/components/SandboxTable/SandboxState'\nimport { Button } from '@/components/ui/button'\nimport { ButtonGroup } from '@/components/ui/button-group'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Spinner } from '@/components/ui/spinner'\nimport { isArchivable, isRecoverable, isStartable, isStoppable } from '@/lib/utils/sandbox'\nimport { Sandbox } from '@daytonaio/api-client'\nimport { ArrowLeft, MoreHorizontal, Play, RefreshCw, Square, Wrench } from 'lucide-react'\n\ninterface SandboxHeaderProps {\n  sandbox: Sandbox | undefined\n  isLoading: boolean\n  writePermitted: boolean\n  deletePermitted: boolean\n  actionsDisabled: boolean\n  isFetching: boolean\n  onStart: () => void\n  onStop: () => void\n  onArchive: () => void\n  onRecover: () => void\n  onDelete: () => void\n  onRefresh: () => void\n  onBack: () => void\n  onCreateSshAccess: () => void\n  onRevokeSshAccess: () => void\n  onScreenRecordings: () => void\n  mutations: { start: boolean; stop: boolean; archive: boolean; recover: boolean }\n}\n\nexport function SandboxHeader({\n  sandbox,\n  isLoading,\n  writePermitted,\n  deletePermitted,\n  actionsDisabled,\n  isFetching,\n  onStart,\n  onStop,\n  onArchive,\n  onRecover,\n  onDelete,\n  onRefresh,\n  onBack,\n  onCreateSshAccess,\n  onRevokeSshAccess,\n  onScreenRecordings,\n  mutations,\n}: SandboxHeaderProps) {\n  return (\n    <div className=\"flex flex-wrap items-center justify-between gap-x-4 gap-y-2 min-w-0 px-4 sm:px-5 py-2 border-b border-border shrink-0\">\n      <div className=\"flex items-center gap-2 min-w-0\">\n        <Button variant=\"ghost\" size=\"icon-sm\" className=\"shrink-0\" onClick={onBack}>\n          <ArrowLeft className=\"size-4\" />\n        </Button>\n        {isLoading ? (\n          <SandboxHeaderSkeleton />\n        ) : sandbox ? (\n          <div className=\"min-w-0\">\n            <div className=\"flex items-center gap-1 min-w-0\">\n              <h2 className=\"text-base font-medium truncate\">{sandbox.name || sandbox.id}</h2>\n              <CopyButton value={sandbox.name || sandbox.id} tooltipText=\"Copy name\" size=\"icon-xs\" />\n            </div>\n            <div className=\"flex items-center gap-1 min-w-0\">\n              <span className=\"text-xs text-muted-foreground shrink-0\">UUID</span>\n              <span className=\"text-sm text-muted-foreground font-mono truncate\">{sandbox.id}</span>\n              <CopyButton value={sandbox.id} tooltipText=\"Copy ID\" size=\"icon-xs\" />\n            </div>\n          </div>\n        ) : null}\n      </div>\n\n      <div className=\"flex items-center gap-3 shrink-0 ml-8 sm:ml-0\">\n        {isLoading ? (\n          <div className=\"flex items-center gap-2\">\n            <Skeleton className=\"h-6 w-16\" />\n            <Skeleton className=\"h-8 w-20\" />\n            <Skeleton className=\"h-8 w-8\" />\n            <Skeleton className=\"h-8 w-8\" />\n          </div>\n        ) : sandbox ? (\n          <>\n            <SandboxState state={sandbox.state} errorReason={sandbox.errorReason} recoverable={sandbox.recoverable} />\n            <div className=\"flex items-center gap-2\">\n              {writePermitted && (\n                <ButtonGroup>\n                  {isStartable(sandbox) && !sandbox.recoverable && (\n                    <Button variant=\"outline\" size=\"sm\" onClick={onStart} disabled={actionsDisabled}>\n                      {mutations.start ? <Spinner className=\"size-4\" /> : <Play className=\"size-4\" />}\n                      Start\n                    </Button>\n                  )}\n                  {isStoppable(sandbox) && (\n                    <Button variant=\"outline\" size=\"sm\" onClick={onStop} disabled={actionsDisabled}>\n                      {mutations.stop ? <Spinner className=\"size-4\" /> : <Square className=\"size-4\" />}\n                      Stop\n                    </Button>\n                  )}\n                  {isRecoverable(sandbox) && (\n                    <Button variant=\"outline\" size=\"sm\" onClick={onRecover} disabled={actionsDisabled}>\n                      {mutations.recover ? <Spinner className=\"size-4\" /> : <Wrench className=\"size-4\" />}\n                      Recover\n                    </Button>\n                  )}\n                  <DropdownMenu>\n                    <DropdownMenuTrigger asChild>\n                      <Button variant=\"outline\" size=\"icon-sm\" aria-label=\"More actions\">\n                        <MoreHorizontal className=\"size-4\" />\n                      </Button>\n                    </DropdownMenuTrigger>\n                    <DropdownMenuContent align=\"end\" className=\"w-48\">\n                      <DropdownMenuGroup>\n                        <DropdownMenuItem onClick={onCreateSshAccess} disabled={actionsDisabled}>\n                          Create SSH Access\n                        </DropdownMenuItem>\n                        <DropdownMenuItem onClick={onRevokeSshAccess} disabled={actionsDisabled}>\n                          Revoke SSH Access\n                        </DropdownMenuItem>\n                        <DropdownMenuSeparator />\n                        <DropdownMenuItem onClick={onScreenRecordings} disabled={actionsDisabled}>\n                          Screen Recordings\n                        </DropdownMenuItem>\n                      </DropdownMenuGroup>\n                      {isArchivable(sandbox) && (\n                        <>\n                          <DropdownMenuSeparator />\n                          <DropdownMenuGroup>\n                            <DropdownMenuItem onClick={onArchive} disabled={actionsDisabled}>\n                              Archive\n                            </DropdownMenuItem>\n                          </DropdownMenuGroup>\n                        </>\n                      )}\n                      {deletePermitted && (\n                        <>\n                          <DropdownMenuSeparator />\n                          <DropdownMenuGroup>\n                            <DropdownMenuItem variant=\"destructive\" onClick={onDelete} disabled={actionsDisabled}>\n                              Delete\n                            </DropdownMenuItem>\n                          </DropdownMenuGroup>\n                        </>\n                      )}\n                    </DropdownMenuContent>\n                  </DropdownMenu>\n                </ButtonGroup>\n              )}\n              <Button variant=\"ghost\" size=\"icon-sm\" onClick={onRefresh} disabled={isFetching} title=\"Refresh\">\n                {isFetching ? <Spinner className=\"size-4\" /> : <RefreshCw className=\"size-4\" />}\n              </Button>\n            </div>\n          </>\n        ) : null}\n      </div>\n    </div>\n  )\n}\n\nfunction SandboxHeaderSkeleton() {\n  return (\n    <div className=\"flex flex-col gap-1\">\n      <div className=\"h-6 flex items-center\">\n        <Skeleton className=\"h-4 w-40\" />\n      </div>\n      <div className=\"h-6 flex items-center\">\n        <Skeleton className=\"h-3.5 w-52\" />\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxInfoPanel.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { ResourceChip } from '@/components/ResourceChip'\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport { Alert, AlertDescription } from '@/components/ui/alert'\nimport { Empty, EmptyDescription, EmptyHeader, EmptyMedia } from '@/components/ui/empty'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { cn, formatDuration, getRelativeTimeString } from '@/lib/utils'\nimport { Sandbox } from '@daytonaio/api-client'\nimport { AlertCircle, Tag } from 'lucide-react'\nimport React, { useMemo } from 'react'\n\nexport function InfoSection({\n  title,\n  children,\n  className,\n}: {\n  title: string\n  children: React.ReactNode\n  className?: string\n}) {\n  return (\n    <div className={cn('px-5 py-4 border-b border-border last:border-b-0', className)}>\n      <p className=\"text-xs uppercase tracking-widest text-muted-foreground mb-2\">{title}</p>\n      {children}\n    </div>\n  )\n}\n\nexport function InfoRow({\n  label,\n  children,\n  className,\n}: {\n  label: string\n  children: React.ReactNode\n  className?: string\n}) {\n  return (\n    <div className={cn('flex items-center justify-between gap-3 py-1', className)}>\n      <span className=\"text-sm text-muted-foreground shrink-0\">{label}</span>\n      <div className=\"min-w-0 text-sm text-right\">{children}</div>\n    </div>\n  )\n}\n\ninterface SandboxInfoPanelProps {\n  sandbox: Sandbox\n  getRegionName: (id: string) => string | undefined\n}\n\nexport function SandboxInfoPanel({ sandbox, getRegionName }: SandboxInfoPanelProps) {\n  const labelEntries = useMemo(() => {\n    return sandbox.labels ? Object.entries(sandbox.labels) : []\n  }, [sandbox.labels])\n\n  return (\n    <div className=\"flex flex-col\">\n      {sandbox.errorReason && (\n        <div className=\"px-5 pt-4\">\n          <Alert variant={sandbox.recoverable ? 'warning' : 'destructive'}>\n            <AlertCircle />\n            <AlertDescription>{sandbox.errorReason}</AlertDescription>\n          </Alert>\n        </div>\n      )}\n\n      <InfoSection title=\"General\">\n        <InfoRow label=\"Region\" className=\"-mr-2\">\n          <div className=\"flex items-center gap-1\">\n            <span className=\"truncate\">{getRegionName(sandbox.target) ?? sandbox.target}</span>\n            <CopyButton value={sandbox.target} tooltipText=\"Copy\" size=\"icon-xs\" />\n          </div>\n        </InfoRow>\n        <InfoRow label=\"Snapshot\" className=\"-mr-2\">\n          {sandbox.snapshot ? (\n            <div className=\"flex items-center gap-1 min-w-0\">\n              <span className=\"truncate font-mono text-sm\">{sandbox.snapshot}</span>\n              <CopyButton value={sandbox.snapshot} tooltipText=\"Copy\" size=\"icon-xs\" />\n            </div>\n          ) : (\n            <span className=\"text-muted-foreground font-normal\">—</span>\n          )}\n        </InfoRow>\n      </InfoSection>\n\n      <InfoSection title=\"Resources\">\n        <div className=\"flex flex-wrap gap-2 py-1\">\n          <ResourceChip resource=\"cpu\" value={sandbox.cpu} />\n          <ResourceChip resource=\"memory\" value={sandbox.memory} />\n          <ResourceChip resource=\"disk\" value={sandbox.disk} />\n        </div>\n      </InfoSection>\n\n      <InfoSection title=\"Lifecycle\">\n        <InfoRow label=\"Auto-stop\">\n          {sandbox.autoStopInterval ? (\n            formatDuration(sandbox.autoStopInterval)\n          ) : (\n            <span className=\"text-muted-foreground font-normal\">Disabled</span>\n          )}\n        </InfoRow>\n        <InfoRow label=\"Auto-archive\">\n          {sandbox.autoArchiveInterval ? (\n            formatDuration(sandbox.autoArchiveInterval)\n          ) : (\n            <span className=\"text-muted-foreground font-normal\">Disabled</span>\n          )}\n        </InfoRow>\n        <InfoRow label=\"Auto-delete\">\n          {sandbox.autoDeleteInterval !== undefined && sandbox.autoDeleteInterval >= 0 ? (\n            sandbox.autoDeleteInterval === 0 ? (\n              'On stop'\n            ) : (\n              formatDuration(sandbox.autoDeleteInterval)\n            )\n          ) : (\n            <span className=\"text-muted-foreground font-normal\">Disabled</span>\n          )}\n        </InfoRow>\n      </InfoSection>\n\n      <InfoSection title=\"Labels\">\n        {labelEntries.length > 0 ? (\n          <div className=\"max-h-[250px] overflow-y-auto scrollbar-sm\">\n            <div className=\"flex flex-wrap gap-2 py-1\">\n              {labelEntries.map(([key, value]) => (\n                <code\n                  key={key}\n                  className=\"flex items-center gap-1 bg-muted border border-border rounded px-2 py-1 text-xs font-mono\"\n                >\n                  <span className=\"text-muted-foreground\">{key}:</span>\n                  <span>{value}</span>\n                </code>\n              ))}\n            </div>\n          </div>\n        ) : (\n          <Empty>\n            <EmptyHeader>\n              <EmptyMedia variant=\"icon\">\n                <Tag className=\"size-4\" />\n              </EmptyMedia>\n              <EmptyDescription>No labels</EmptyDescription>\n            </EmptyHeader>\n          </Empty>\n        )}\n      </InfoSection>\n\n      <InfoSection title=\"Timestamps\">\n        <InfoRow label=\"Created\">\n          <TimestampTooltip timestamp={sandbox.createdAt}>\n            <span>{getRelativeTimeString(sandbox.createdAt).relativeTimeString}</span>\n          </TimestampTooltip>\n        </InfoRow>\n        <InfoRow label=\"Last event\">\n          <TimestampTooltip timestamp={sandbox.updatedAt}>\n            <span>{getRelativeTimeString(sandbox.updatedAt).relativeTimeString}</span>\n          </TimestampTooltip>\n        </InfoRow>\n      </InfoSection>\n    </div>\n  )\n}\n\nexport function InfoPanelSkeleton() {\n  return (\n    <div className=\"flex flex-col\">\n      <div className=\"px-5 py-4 border-b border-border\">\n        <Skeleton className=\"h-2.5 w-16 mb-3\" />\n        <div className=\"space-y-3\">\n          <div className=\"flex justify-between\">\n            <Skeleton className=\"h-4 w-12\" />\n            <Skeleton className=\"h-4 w-20\" />\n          </div>\n          <div className=\"flex justify-between\">\n            <Skeleton className=\"h-4 w-16\" />\n            <Skeleton className=\"h-4 w-32\" />\n          </div>\n        </div>\n      </div>\n      <div className=\"px-5 py-4 border-b border-border\">\n        <Skeleton className=\"h-2.5 w-20 mb-3\" />\n        <div className=\"flex gap-2\">\n          <Skeleton className=\"h-6 w-16 rounded-full\" />\n          <Skeleton className=\"h-6 w-16 rounded-full\" />\n          <Skeleton className=\"h-6 w-16 rounded-full\" />\n        </div>\n      </div>\n      <div className=\"px-5 py-4 border-b border-border\">\n        <Skeleton className=\"h-2.5 w-18 mb-3\" />\n        <div className=\"space-y-3\">\n          <div className=\"flex justify-between\">\n            <Skeleton className=\"h-4 w-20\" />\n            <Skeleton className=\"h-4 w-16\" />\n          </div>\n          <div className=\"flex justify-between\">\n            <Skeleton className=\"h-4 w-24\" />\n            <Skeleton className=\"h-4 w-16\" />\n          </div>\n          <div className=\"flex justify-between\">\n            <Skeleton className=\"h-4 w-22\" />\n            <Skeleton className=\"h-4 w-16\" />\n          </div>\n        </div>\n      </div>\n      <div className=\"px-5 py-4 border-b border-border\">\n        <Skeleton className=\"h-2.5 w-14 mb-3\" />\n        <Skeleton className=\"h-4 w-full\" />\n      </div>\n      <div className=\"px-5 py-4\">\n        <Skeleton className=\"h-2.5 w-24 mb-3\" />\n        <div className=\"space-y-3\">\n          <div className=\"flex justify-between\">\n            <Skeleton className=\"h-4 w-16\" />\n            <Skeleton className=\"h-4 w-24\" />\n          </div>\n          <div className=\"flex justify-between\">\n            <Skeleton className=\"h-4 w-20\" />\n            <Skeleton className=\"h-4 w-24\" />\n          </div>\n        </div>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxLogsTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { SeverityBadge } from '@/components/telemetry/SeverityBadge'\nimport { TimeRangeSelector } from '@/components/telemetry/TimeRangeSelector'\nimport { Button } from '@/components/ui/button'\nimport { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { Input } from '@/components/ui/input'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { DAYTONA_DOCS_URL } from '@/constants/ExternalLinks'\nimport { LogsQueryParams, useSandboxLogs } from '@/hooks/useSandboxLogs'\nimport { cn } from '@/lib/utils'\nimport { LogEntry } from '@daytonaio/api-client'\nimport { format, subHours } from 'date-fns'\nimport { ChevronDown, ChevronLeft, ChevronRight, FileText, RefreshCw, Search } from 'lucide-react'\nimport { useQueryStates } from 'nuqs'\nimport React, { useCallback, useMemo, useState } from 'react'\nimport { logsSearchParams, SEVERITY_OPTIONS, timeRangeSearchParams } from './SearchParams'\n\nfunction formatTimestamp(timestamp: string) {\n  try {\n    return format(new Date(timestamp), 'yyyy-MM-dd HH:mm:ss.SSS')\n  } catch {\n    return timestamp\n  }\n}\n\nconst getLogKey = (log: LogEntry, index: number) => `${log.timestamp}-${index}`\n\nfunction LogsTableSkeleton() {\n  return (\n    <Table>\n      <TableHeader>\n        <TableRow>\n          <TableHead className=\"w-10\" />\n          <TableHead className=\"w-48\">Timestamp</TableHead>\n          <TableHead className=\"w-24\">Severity</TableHead>\n          <TableHead>Message</TableHead>\n        </TableRow>\n      </TableHeader>\n      <TableBody>\n        {Array.from({ length: 10 }).map((_, i) => (\n          <TableRow key={i}>\n            <TableCell>\n              <Skeleton className=\"size-4\" />\n            </TableCell>\n            <TableCell>\n              <Skeleton className=\"h-4 w-36\" />\n            </TableCell>\n            <TableCell>\n              <Skeleton className=\"h-5 w-14 rounded-full\" />\n            </TableCell>\n            <TableCell>\n              <Skeleton className=\"h-4\" style={{ width: `${45 + (i % 4) * 12}%` }} />\n            </TableCell>\n          </TableRow>\n        ))}\n      </TableBody>\n    </Table>\n  )\n}\n\nfunction LogsErrorState({ onRetry }: { onRetry: () => void }) {\n  return (\n    <Empty className=\"flex-1 border-0\">\n      <EmptyHeader>\n        <EmptyTitle>Failed to load logs</EmptyTitle>\n        <EmptyDescription>Something went wrong while fetching logs.</EmptyDescription>\n      </EmptyHeader>\n      <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n        <RefreshCw className=\"size-4\" />\n        Retry\n      </Button>\n    </Empty>\n  )\n}\n\nfunction LogsEmptyState() {\n  return (\n    <Empty className=\"flex-1 border-0\">\n      <EmptyHeader>\n        <EmptyMedia variant=\"icon\">\n          <FileText className=\"size-4\" />\n        </EmptyMedia>\n        <EmptyTitle>No logs found</EmptyTitle>\n        <EmptyDescription>\n          Try adjusting your time range or filters.{' '}\n          <a href={`${DAYTONA_DOCS_URL}/en/experimental/otel-collection`} target=\"_blank\" rel=\"noopener noreferrer\">\n            Learn more about observability\n          </a>\n          .\n        </EmptyDescription>\n      </EmptyHeader>\n    </Empty>\n  )\n}\n\nexport function SandboxLogsTab({ sandboxId }: { sandboxId: string }) {\n  const [params, setParams] = useQueryStates(logsSearchParams)\n  const [timeRange, setTimeRange] = useQueryStates(timeRangeSearchParams)\n  const [searchInput, setSearchInput] = useState(params.search)\n  const [expandedRow, setExpandedRow] = useState<number | null>(null)\n  const limit = 50\n\n  const resolvedFrom = useMemo(() => timeRange.from ?? subHours(new Date(), 1), [timeRange.from])\n  const resolvedTo = useMemo(() => timeRange.to ?? new Date(), [timeRange.to])\n\n  const queryParams: LogsQueryParams = useMemo(\n    () => ({\n      from: resolvedFrom,\n      to: resolvedTo,\n      page: params.logsPage,\n      limit,\n      severities: params.severity.length > 0 ? [...params.severity] : undefined,\n      search: params.search || undefined,\n    }),\n    [resolvedFrom, resolvedTo, params.logsPage, params.severity, params.search],\n  )\n\n  const { data, isLoading, isError, refetch } = useSandboxLogs(sandboxId, queryParams)\n\n  const handleTimeRangeChange = useCallback(\n    (from: Date, to: Date) => {\n      setTimeRange({ from, to })\n      setParams({ logsPage: 1 })\n    },\n    [setTimeRange, setParams],\n  )\n\n  const handleSearch = useCallback(() => {\n    setParams({ search: searchInput, logsPage: 1 })\n  }, [searchInput, setParams])\n\n  const handleSeverityChange = useCallback(\n    (value: string) => {\n      if (value === 'all' || !value) {\n        setParams({ severity: [], logsPage: 1 })\n      } else {\n        setParams({ severity: [value as (typeof SEVERITY_OPTIONS)[number]], logsPage: 1 })\n      }\n    },\n    [setParams],\n  )\n\n  return (\n    <div className=\"flex flex-col h-full gap-4 p-4\">\n      <div className=\"flex flex-wrap items-center gap-3 shrink-0\">\n        <TimeRangeSelector\n          onChange={handleTimeRangeChange}\n          defaultRange={timeRange.from && timeRange.to ? { from: timeRange.from, to: timeRange.to } : undefined}\n          className=\"w-auto\"\n        />\n\n        <div className=\"flex items-center gap-2\">\n          <Input\n            placeholder=\"Search logs...\"\n            value={searchInput}\n            onChange={(e) => setSearchInput(e.target.value)}\n            onKeyDown={(e) => e.key === 'Enter' && handleSearch()}\n            className=\"w-48\"\n          />\n          <Button variant=\"outline\" size=\"icon-sm\" onClick={handleSearch}>\n            <Search className=\"size-4\" />\n          </Button>\n        </div>\n\n        <Select value={params.severity.length === 1 ? params.severity[0] : ''} onValueChange={handleSeverityChange}>\n          <SelectTrigger className=\"w-32\" size=\"sm\">\n            <SelectValue placeholder=\"Severity\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"all\">All</SelectItem>\n            {SEVERITY_OPTIONS.map((sev) => (\n              <SelectItem key={sev} value={sev}>\n                {sev}\n              </SelectItem>\n            ))}\n          </SelectContent>\n        </Select>\n\n        <Button variant=\"ghost\" size=\"icon-sm\" onClick={() => refetch()} className=\"ml-auto\">\n          <RefreshCw className=\"size-4\" />\n        </Button>\n      </div>\n\n      {isLoading ? (\n        <div className=\"flex-1 min-h-0 border rounded-md\">\n          <LogsTableSkeleton />\n        </div>\n      ) : isError ? (\n        <div className=\"flex-1 min-h-0 border rounded-md flex\">\n          <LogsErrorState onRetry={() => refetch()} />\n        </div>\n      ) : !data?.items?.length ? (\n        <div className=\"flex-1 min-h-0 border rounded-md flex\">\n          <LogsEmptyState />\n        </div>\n      ) : (\n        <ScrollArea\n          fade=\"mask\"\n          horizontal\n          className=\"flex-1 min-h-0 border rounded-md [&_[data-slot=scroll-area-viewport]>div]:!overflow-visible [&_[data-slot=scroll-area-viewport]>div>div]:!overflow-visible\"\n        >\n          <Table>\n            <TableHeader className=\"sticky top-0 z-10 bg-background after:absolute after:bottom-0 after:left-0 after:right-0 after:h-px after:bg-border\">\n              <TableRow>\n                <TableHead className=\"w-10\" />\n                <TableHead className=\"w-48\">Timestamp</TableHead>\n                <TableHead className=\"w-24\">Severity</TableHead>\n                <TableHead>Message</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {data.items.map((log: LogEntry, index: number) => (\n                <React.Fragment key={getLogKey(log, index)}>\n                  <TableRow\n                    className=\"cursor-pointer hover:bg-muted/50\"\n                    onClick={() => setExpandedRow(expandedRow === index ? null : index)}\n                  >\n                    <TableCell>\n                      <ChevronDown\n                        className={cn(\n                          'size-4 transition-transform duration-200',\n                          expandedRow === index && 'rotate-180',\n                        )}\n                      />\n                    </TableCell>\n                    <TableCell className=\"font-mono text-xs\">{formatTimestamp(log.timestamp)}</TableCell>\n                    <TableCell>\n                      <SeverityBadge severity={log.severityText} />\n                    </TableCell>\n                    <TableCell className=\"max-w-md truncate font-mono text-xs\">{log.body}</TableCell>\n                  </TableRow>\n                  {expandedRow === index && (\n                    <TableRow>\n                      <TableCell colSpan={4} className=\"bg-muted/30 p-4\">\n                        <div className=\"space-y-3\">\n                          <div>\n                            <h4 className=\"text-sm font-medium mb-1\">Full Message</h4>\n                            <pre className=\"text-xs bg-background p-2 rounded overflow-x-auto whitespace-pre-wrap\">\n                              {log.body}\n                            </pre>\n                          </div>\n                          {log.traceId && (\n                            <div>\n                              <h4 className=\"text-sm font-medium mb-1\">Trace ID</h4>\n                              <code className=\"text-xs bg-background p-1 rounded\">{log.traceId}</code>\n                            </div>\n                          )}\n                          {log.spanId && (\n                            <div>\n                              <h4 className=\"text-sm font-medium mb-1\">Span ID</h4>\n                              <code className=\"text-xs bg-background p-1 rounded\">{log.spanId}</code>\n                            </div>\n                          )}\n                          {Object.keys(log.logAttributes || {}).length > 0 && (\n                            <div>\n                              <h4 className=\"text-sm font-medium mb-1\">Attributes</h4>\n                              <div className=\"relative\">\n                                <CopyButton\n                                  value={JSON.stringify(log.logAttributes, null, 2)}\n                                  tooltipText=\"Copy\"\n                                  size=\"icon-xs\"\n                                  className=\"absolute top-1.5 right-1.5\"\n                                />\n                                <pre className=\"text-xs bg-background p-2 rounded overflow-x-auto\">\n                                  {JSON.stringify(log.logAttributes, null, 2)}\n                                </pre>\n                              </div>\n                            </div>\n                          )}\n                        </div>\n                      </TableCell>\n                    </TableRow>\n                  )}\n                </React.Fragment>\n              ))}\n            </TableBody>\n          </Table>\n        </ScrollArea>\n      )}\n\n      {data && data.totalPages > 1 && (\n        <div className=\"flex items-center justify-between shrink-0\">\n          <span className=\"text-sm text-muted-foreground\">\n            Page {params.logsPage} of {data.totalPages} ({data.total} total)\n          </span>\n          <div className=\"flex items-center gap-2\">\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              disabled={params.logsPage <= 1}\n              onClick={() => setParams({ logsPage: params.logsPage - 1 })}\n            >\n              <ChevronLeft className=\"size-4\" />\n              Previous\n            </Button>\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              disabled={params.logsPage >= data.totalPages}\n              onClick={() => setParams({ logsPage: params.logsPage + 1 })}\n            >\n              Next\n              <ChevronRight className=\"size-4\" />\n            </Button>\n          </div>\n        </div>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxMetricsTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useCallback, useMemo } from 'react'\nimport { useQueryStates } from 'nuqs'\nimport { useSandboxMetrics, MetricsQueryParams } from '@/hooks/useSandboxMetrics'\nimport { TimeRangeSelector } from '@/components/telemetry/TimeRangeSelector'\nimport { Button } from '@/components/ui/button'\nimport { ChartContainer, ChartTooltip, ChartTooltipContent, ChartConfig } from '@/components/ui/chart'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { LineChart, Line, XAxis, YAxis, CartesianGrid, Legend } from 'recharts'\nimport { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { DAYTONA_DOCS_URL } from '@/constants/ExternalLinks'\nimport { RefreshCw, BarChart3 } from 'lucide-react'\nimport { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'\nimport { format, subHours } from 'date-fns'\nimport { MetricSeries } from '@daytonaio/api-client'\nimport { getMetricDisplayName } from '@/constants/metrics'\nimport { timeRangeSearchParams } from './SearchParams'\n\nconst CHART_COLORS = [\n  'hsl(var(--chart-1))',\n  'hsl(var(--chart-2))',\n  'hsl(var(--chart-3))',\n  'hsl(var(--chart-4))',\n  'hsl(var(--chart-5))',\n]\n\nconst BYTES_TO_GIB = 1024 * 1024 * 1024\ntype ViewMode = '%' | 'GiB'\n\nconst METRIC_GROUPS = [\n  { key: 'cpu', title: 'CPU', prefix: '.cpu.', hasToggle: false },\n  { key: 'memory', title: 'Memory', prefix: '.memory.', hasToggle: true },\n  { key: 'filesystem', title: 'Filesystem', prefix: '.filesystem.', hasToggle: true },\n]\n\nfunction isByteMetric(metricName: string): boolean {\n  return !metricName.endsWith('.utilization')\n}\n\nfunction buildChartData(series: MetricSeries[], convertToGiB: boolean): Record<string, unknown>[] {\n  const timestampSet = new Set<string>()\n  const indexed = series.map((s) => {\n    const byTimestamp = new Map<string, number | null>()\n    for (const p of s.dataPoints) {\n      timestampSet.add(p.timestamp)\n      byTimestamp.set(p.timestamp, p.value ?? null)\n    }\n    return { metricName: s.metricName, byTimestamp, convertMetric: convertToGiB && isByteMetric(s.metricName) }\n  })\n  const timestamps = Array.from(timestampSet).sort()\n\n  return timestamps.map((timestamp) => {\n    const point: Record<string, unknown> = { timestamp }\n    for (const { metricName, byTimestamp, convertMetric } of indexed) {\n      const value = byTimestamp.get(timestamp)\n      if (value == null) {\n        point[metricName] = null\n      } else if (convertMetric) {\n        point[metricName] = Math.round((value / BYTES_TO_GIB) * 100) / 100\n      } else {\n        point[metricName] = value\n      }\n    }\n    return point\n  })\n}\n\nfunction buildChartConfig(series: MetricSeries[]): ChartConfig {\n  const config: ChartConfig = {}\n  series.forEach((s, index) => {\n    config[s.metricName] = {\n      label: getMetricDisplayName(s.metricName),\n      color: CHART_COLORS[index % CHART_COLORS.length],\n    }\n  })\n  return config\n}\n\nconst formatXAxis = (timestamp: string) => {\n  try {\n    return format(new Date(timestamp), 'HH:mm')\n  } catch {\n    return timestamp\n  }\n}\n\nfunction MetricGroupChart({\n  title,\n  series,\n  convertToGiB,\n  viewMode,\n  onViewModeChange,\n}: {\n  title: string\n  series: MetricSeries[]\n  convertToGiB: boolean\n  viewMode?: ViewMode\n  onViewModeChange?: (mode: ViewMode) => void\n}) {\n  const chartData = React.useMemo(() => buildChartData(series, convertToGiB), [series, convertToGiB])\n  const chartConfig = React.useMemo(() => buildChartConfig(series), [series])\n  const displayTitle = viewMode ? `${title} (${viewMode})` : title\n\n  return (\n    <div className=\"rounded-md border border-border\">\n      <div className=\"flex items-center gap-2 px-4 py-3\">\n        <h3 className=\"text-sm font-medium\">{displayTitle}</h3>\n        {viewMode && onViewModeChange && (\n          <ToggleGroup\n            type=\"single\"\n            value={viewMode}\n            onValueChange={(value) => {\n              if (value) onViewModeChange(value as ViewMode)\n            }}\n            variant=\"outline\"\n            size=\"sm\"\n          >\n            <ToggleGroupItem value=\"%\" className=\"text-xs px-2 h-6\">\n              %\n            </ToggleGroupItem>\n            <ToggleGroupItem value=\"GiB\" className=\"text-xs px-2 h-6\">\n              GiB\n            </ToggleGroupItem>\n          </ToggleGroup>\n        )}\n      </div>\n      <div className=\"border-t border-border px-4 py-3\">\n        <ChartContainer config={chartConfig} className=\"h-[220px] w-full\">\n          <LineChart data={chartData} margin={{ top: 10, right: 10, left: 0, bottom: 5 }}>\n            <CartesianGrid strokeDasharray=\"3 3\" className=\"stroke-muted\" />\n            <XAxis\n              dataKey=\"timestamp\"\n              tickFormatter={formatXAxis}\n              className=\"text-xs\"\n              tick={{ fill: 'hsl(var(--muted-foreground))' }}\n            />\n            <YAxis\n              width={35}\n              className=\"text-xs\"\n              tick={{ fill: 'hsl(var(--muted-foreground))' }}\n              tickFormatter={convertToGiB ? (value: number) => value.toFixed(2) : undefined}\n              domain={viewMode === '%' ? [0, 100] : undefined}\n            />\n            <ChartTooltip\n              content={\n                <ChartTooltipContent\n                  labelFormatter={(label) => {\n                    try {\n                      return format(new Date(label as string), 'yyyy-MM-dd HH:mm:ss')\n                    } catch {\n                      return String(label)\n                    }\n                  }}\n                />\n              }\n            />\n            <Legend />\n            {series.map((s, index) => {\n              const isLimit = s.metricName.endsWith('.limit') || s.metricName.endsWith('.total')\n              return (\n                <Line\n                  key={s.metricName}\n                  type=\"monotone\"\n                  dataKey={s.metricName}\n                  name={getMetricDisplayName(s.metricName)}\n                  stroke={CHART_COLORS[index % CHART_COLORS.length]}\n                  strokeWidth={isLimit ? 1.5 : 2}\n                  strokeDasharray={isLimit ? '6 3' : undefined}\n                  dot={false}\n                  connectNulls\n                />\n              )\n            })}\n          </LineChart>\n        </ChartContainer>\n      </div>\n    </div>\n  )\n}\n\nfunction MetricsChartsSkeleton() {\n  return (\n    <div className=\"flex flex-col gap-6\">\n      {['CPU', 'Memory', 'Filesystem'].map((title) => (\n        <div key={title} className=\"min-h-[250px]\">\n          <div className=\"flex items-center gap-2 mb-2\">\n            <Skeleton className=\"h-4 w-20\" />\n          </div>\n          <Skeleton className=\"h-[220px] w-full rounded-md\" />\n        </div>\n      ))}\n    </div>\n  )\n}\n\nfunction MetricsErrorState({ onRetry }: { onRetry: () => void }) {\n  return (\n    <Empty className=\"flex-1 border-0\">\n      <EmptyHeader>\n        <EmptyTitle>Failed to load metrics</EmptyTitle>\n        <EmptyDescription>Something went wrong while fetching metrics.</EmptyDescription>\n      </EmptyHeader>\n      <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n        <RefreshCw className=\"size-4\" />\n        Retry\n      </Button>\n    </Empty>\n  )\n}\n\nfunction MetricsEmptyState() {\n  return (\n    <Empty className=\"flex-1 border-0\">\n      <EmptyHeader>\n        <EmptyMedia variant=\"icon\">\n          <BarChart3 className=\"size-4\" />\n        </EmptyMedia>\n        <EmptyTitle>No metrics available</EmptyTitle>\n        <EmptyDescription>\n          Metrics may take a moment to appear after the sandbox starts.{' '}\n          <a href={`${DAYTONA_DOCS_URL}/en/experimental/otel-collection`} target=\"_blank\" rel=\"noopener noreferrer\">\n            Learn more about observability\n          </a>\n          .\n        </EmptyDescription>\n      </EmptyHeader>\n    </Empty>\n  )\n}\n\nexport function SandboxMetricsTab({ sandboxId }: { sandboxId: string }) {\n  const [timeRange, setTimeRange] = useQueryStates(timeRangeSearchParams)\n  const [viewModes, setViewModes] = useState<Record<string, ViewMode>>({ memory: '%', filesystem: '%' })\n\n  const resolvedFrom = useMemo(() => timeRange.from ?? subHours(new Date(), 1), [timeRange.from])\n  const resolvedTo = useMemo(() => timeRange.to ?? new Date(), [timeRange.to])\n\n  const queryParams: MetricsQueryParams = { from: resolvedFrom, to: resolvedTo }\n  const { data, isLoading, isError, refetch } = useSandboxMetrics(sandboxId, queryParams)\n\n  const handleTimeRangeChange = useCallback(\n    (from: Date, to: Date) => {\n      setTimeRange({ from, to })\n    },\n    [setTimeRange],\n  )\n\n  const handleViewModeChange = useCallback((groupKey: string, mode: ViewMode) => {\n    setViewModes((prev) => ({ ...prev, [groupKey]: mode }))\n  }, [])\n\n  const groupedSeries = React.useMemo(() => {\n    if (!data?.series?.length) return []\n\n    return METRIC_GROUPS.map((group) => {\n      const allSeries = data.series.filter((s) => s.metricName.includes(group.prefix))\n      const mode = group.hasToggle ? viewModes[group.key] : undefined\n\n      let filteredSeries = allSeries.filter((s) => s.metricName !== 'system.memory.utilization')\n      if (mode === '%') {\n        filteredSeries = filteredSeries.filter((s) => s.metricName.endsWith('.utilization'))\n      } else if (mode === 'GiB') {\n        filteredSeries = filteredSeries.filter((s) => !s.metricName.endsWith('.utilization'))\n      }\n\n      return {\n        key: group.key,\n        title: group.title,\n        series: filteredSeries,\n        convertToGiB: mode === 'GiB',\n        hasToggle: group.hasToggle,\n        viewMode: mode,\n      }\n    }).filter((group) => group.series.length > 0)\n  }, [data, viewModes])\n\n  return (\n    <div className=\"flex flex-col h-full gap-4 p-4\">\n      <div className=\"flex flex-wrap items-center gap-3 shrink-0\">\n        <TimeRangeSelector\n          onChange={handleTimeRangeChange}\n          defaultRange={timeRange.from && timeRange.to ? { from: timeRange.from, to: timeRange.to } : undefined}\n          className=\"w-auto\"\n        />\n        <Button variant=\"ghost\" size=\"icon-sm\" onClick={() => refetch()} className=\"ml-auto\">\n          <RefreshCw className=\"size-4\" />\n        </Button>\n      </div>\n\n      {isLoading ? (\n        <div className=\"flex-1 min-h-0 rounded-md border border-border p-4\">\n          <MetricsChartsSkeleton />\n        </div>\n      ) : isError ? (\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <MetricsErrorState onRetry={() => refetch()} />\n        </div>\n      ) : !data?.series?.length ? (\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <MetricsEmptyState />\n        </div>\n      ) : (\n        <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0\">\n          <div className=\"flex flex-col gap-4\">\n            {groupedSeries.map((group) => (\n              <MetricGroupChart\n                key={group.key}\n                title={group.title}\n                series={group.series}\n                convertToGiB={group.convertToGiB}\n                viewMode={group.hasToggle ? group.viewMode : undefined}\n                onViewModeChange={group.hasToggle ? (mode) => handleViewModeChange(group.key, mode) : undefined}\n              />\n            ))}\n          </div>\n        </ScrollArea>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxSpendingTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { TimeRangeSelector } from '@/components/telemetry/TimeRangeSelector'\nimport { Button } from '@/components/ui/button'\nimport { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { AnalyticsUsageParams, useSandboxUsagePeriods } from '@/hooks/queries/useAnalyticsUsage'\nimport { formatMoney } from '@/lib/utils'\nimport { format, subHours } from 'date-fns'\nimport { DollarSign, RefreshCw } from 'lucide-react'\nimport { useQueryStates } from 'nuqs'\nimport { useCallback, useMemo } from 'react'\nimport { timeRangeSearchParams } from './SearchParams'\n\nfunction formatTimestamp(timestamp: string) {\n  try {\n    return format(new Date(timestamp), 'yyyy-MM-dd HH:mm:ss')\n  } catch {\n    return timestamp\n  }\n}\n\nfunction SpendingTableSkeleton() {\n  return (\n    <Table>\n      <TableHeader>\n        <TableRow>\n          <TableHead>Start</TableHead>\n          <TableHead>End</TableHead>\n          <TableHead className=\"text-right\">CPU</TableHead>\n          <TableHead className=\"text-right\">RAM (GB)</TableHead>\n          <TableHead className=\"text-right\">Disk (GB)</TableHead>\n          <TableHead className=\"text-right\">Price</TableHead>\n        </TableRow>\n      </TableHeader>\n      <TableBody>\n        {Array.from({ length: 8 }).map((_, i) => (\n          <TableRow key={i}>\n            <TableCell>\n              <Skeleton className=\"h-4 w-36\" />\n            </TableCell>\n            <TableCell>\n              <Skeleton className=\"h-4 w-36\" />\n            </TableCell>\n            <TableCell className=\"text-right\">\n              <Skeleton className=\"h-4 w-8 ml-auto\" />\n            </TableCell>\n            <TableCell className=\"text-right\">\n              <Skeleton className=\"h-4 w-8 ml-auto\" />\n            </TableCell>\n            <TableCell className=\"text-right\">\n              <Skeleton className=\"h-4 w-8 ml-auto\" />\n            </TableCell>\n            <TableCell className=\"text-right\">\n              <Skeleton className=\"h-4 w-14 ml-auto\" />\n            </TableCell>\n          </TableRow>\n        ))}\n      </TableBody>\n    </Table>\n  )\n}\n\nfunction SpendingErrorState({ onRetry }: { onRetry: () => void }) {\n  return (\n    <Empty className=\"flex-1 border-0\">\n      <EmptyHeader>\n        <EmptyTitle>Failed to load spending</EmptyTitle>\n        <EmptyDescription>Something went wrong while fetching usage periods.</EmptyDescription>\n      </EmptyHeader>\n      <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n        <RefreshCw className=\"size-4\" />\n        Retry\n      </Button>\n    </Empty>\n  )\n}\n\nfunction SpendingEmptyState() {\n  return (\n    <Empty className=\"flex-1 border-0\">\n      <EmptyHeader>\n        <EmptyMedia variant=\"icon\">\n          <DollarSign className=\"size-4\" />\n        </EmptyMedia>\n        <EmptyTitle>No usage periods found</EmptyTitle>\n        <EmptyDescription>Try adjusting your time range.</EmptyDescription>\n      </EmptyHeader>\n    </Empty>\n  )\n}\n\nexport function SandboxSpendingTab({ sandboxId }: { sandboxId: string }) {\n  const [timeRange, setTimeRange] = useQueryStates(timeRangeSearchParams)\n\n  const resolvedFrom = useMemo(() => timeRange.from ?? subHours(new Date(), 24), [timeRange.from])\n  const resolvedTo = useMemo(() => timeRange.to ?? new Date(), [timeRange.to])\n\n  const queryParams: AnalyticsUsageParams = { from: resolvedFrom, to: resolvedTo }\n  const { data, isLoading, isError, refetch } = useSandboxUsagePeriods(sandboxId, queryParams)\n\n  const handleTimeRangeChange = useCallback(\n    (from: Date, to: Date) => {\n      setTimeRange({ from, to })\n    },\n    [setTimeRange],\n  )\n\n  return (\n    <div className=\"flex flex-col h-full gap-4 p-4\">\n      <div className=\"flex flex-wrap items-center gap-3 shrink-0\">\n        <TimeRangeSelector\n          onChange={handleTimeRangeChange}\n          defaultRange={timeRange.from && timeRange.to ? { from: timeRange.from, to: timeRange.to } : undefined}\n          defaultSelectedQuickRange=\"Last 24 hours\"\n          className=\"w-auto\"\n        />\n        <Button variant=\"ghost\" size=\"icon-sm\" onClick={() => refetch()} className=\"ml-auto\">\n          <RefreshCw className=\"size-4\" />\n        </Button>\n      </div>\n\n      {isLoading ? (\n        <div className=\"flex-1 min-h-0 border rounded-md\">\n          <SpendingTableSkeleton />\n        </div>\n      ) : isError ? (\n        <div className=\"flex-1 min-h-0 border rounded-md flex\">\n          <SpendingErrorState onRetry={() => refetch()} />\n        </div>\n      ) : !data?.length ? (\n        <div className=\"flex-1 min-h-0 border rounded-md flex\">\n          <SpendingEmptyState />\n        </div>\n      ) : (\n        <ScrollArea\n          fade=\"mask\"\n          horizontal\n          className=\"flex-1 min-h-0 border rounded-md [&_[data-slot=scroll-area-viewport]>div]:!overflow-visible [&_[data-slot=scroll-area-viewport]>div>div]:!overflow-visible\"\n        >\n          <Table>\n            <TableHeader className=\"sticky top-0 z-10 bg-background after:absolute after:bottom-0 after:left-0 after:right-0 after:h-px after:bg-border\">\n              <TableRow>\n                <TableHead>Start</TableHead>\n                <TableHead>End</TableHead>\n                <TableHead className=\"text-right\">CPU</TableHead>\n                <TableHead className=\"text-right\">RAM (GB)</TableHead>\n                <TableHead className=\"text-right\">Disk (GB)</TableHead>\n                <TableHead className=\"text-right\">Price</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {data.map((period) => {\n                const rowKey = `${period.startAt ?? 'unknown-start'}-${period.endAt ?? 'unknown-end'}`\n                return (\n                  <TableRow key={rowKey}>\n                    <TableCell className=\"font-mono text-xs\">\n                      {period.startAt ? formatTimestamp(period.startAt) : '-'}\n                    </TableCell>\n                    <TableCell className=\"font-mono text-xs\">\n                      {period.endAt ? formatTimestamp(period.endAt) : '-'}\n                    </TableCell>\n                    <TableCell className=\"text-right\">{period.cpu ?? 0}</TableCell>\n                    <TableCell className=\"text-right\">{period.ramGB ?? 0}</TableCell>\n                    <TableCell className=\"text-right\">{period.diskGB ?? 0}</TableCell>\n                    <TableCell className=\"text-right font-mono text-xs\">\n                      {formatMoney(period.price ?? 0, {\n                        maximumFractionDigits: 8,\n                      })}\n                    </TableCell>\n                  </TableRow>\n                )\n              })}\n            </TableBody>\n          </Table>\n        </ScrollArea>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxTerminalTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useEffect, useState } from 'react'\nimport { Button } from '@/components/ui/button'\nimport { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { DAYTONA_DOCS_URL } from '@/constants/ExternalLinks'\nimport { useTerminalSessionQuery } from '@/hooks/queries/useTerminalSessionQuery'\nimport { useSandboxSessionContext } from '@/hooks/useSandboxSessionContext'\nimport { isStoppable } from '@/lib/utils/sandbox'\nimport { Sandbox } from '@daytonaio/api-client'\nimport { Spinner } from '@/components/ui/spinner'\nimport { Play, RefreshCw, TerminalSquare } from 'lucide-react'\n\nexport function SandboxTerminalTab({ sandbox }: { sandbox: Sandbox }) {\n  const running = isStoppable(sandbox)\n  const { isTerminalActivated, activateTerminal } = useSandboxSessionContext()\n\n  const [activated, setActivated] = useState(() => isTerminalActivated(sandbox.id))\n\n  const {\n    data: session,\n    isLoading,\n    isError,\n    isFetching,\n    existingSession,\n    reset,\n  } = useTerminalSessionQuery(sandbox.id, running && activated)\n\n  // Auto-reconnect: if activated and session is expired, refetch\n  useEffect(() => {\n    if (!activated || !existingSession) return\n    if (existingSession.expiresAt <= Date.now()) {\n      reset()\n    }\n  }, [activated, existingSession, reset])\n\n  const handleConnect = () => {\n    activateTerminal(sandbox.id)\n    setActivated(true)\n  }\n\n  if (!running) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <Empty className=\"border-0\">\n            <EmptyHeader>\n              <EmptyMedia variant=\"icon\">\n                <TerminalSquare className=\"size-4\" />\n              </EmptyMedia>\n              <EmptyTitle>Sandbox is not running</EmptyTitle>\n              <EmptyDescription>\n                Start the sandbox to access the terminal.{' '}\n                <a href={`${DAYTONA_DOCS_URL}/en/web-terminal`} target=\"_blank\" rel=\"noopener noreferrer\">\n                  Learn more\n                </a>\n                .\n              </EmptyDescription>\n            </EmptyHeader>\n          </Empty>\n        </div>\n      </div>\n    )\n  }\n\n  // Not yet activated — show connect button\n  if (!activated) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <Empty className=\"border-0\">\n            <EmptyHeader>\n              <EmptyMedia variant=\"icon\">\n                <TerminalSquare className=\"size-4\" />\n              </EmptyMedia>\n              <EmptyTitle>Terminal</EmptyTitle>\n              <EmptyDescription>\n                Connect to an interactive terminal session in your sandbox.{' '}\n                <a href={`${DAYTONA_DOCS_URL}/en/web-terminal`} target=\"_blank\" rel=\"noopener noreferrer\">\n                  Learn more\n                </a>\n                .\n              </EmptyDescription>\n            </EmptyHeader>\n            <Button onClick={handleConnect}>\n              <Play className=\"size-4\" />\n              Connect\n            </Button>\n          </Empty>\n        </div>\n      </div>\n    )\n  }\n\n  // Loading / fetching\n  if (isLoading || isFetching) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex items-center justify-center gap-2 text-muted-foreground\">\n          <Spinner className=\"size-4\" />\n          <span className=\"text-sm\">Connecting...</span>\n        </div>\n      </div>\n    )\n  }\n\n  // Error\n  if (isError || !session) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <Empty className=\"border-0\">\n            <EmptyHeader>\n              <EmptyTitle>Failed to connect</EmptyTitle>\n              <EmptyDescription>Something went wrong while connecting to the terminal.</EmptyDescription>\n            </EmptyHeader>\n            <Button variant=\"outline\" size=\"sm\" onClick={() => reset()}>\n              <RefreshCw className=\"size-4\" />\n              Retry\n            </Button>\n          </Empty>\n        </div>\n      </div>\n    )\n  }\n\n  // Active session\n  return (\n    <div className=\"flex-1 flex flex-col p-4\">\n      <div className=\"flex-1 min-h-0 rounded-md border border-border bg-black overflow-hidden p-1\">\n        <iframe title=\"Sandbox terminal\" src={session.url} className=\"w-full h-full border-0\" />\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxTracesTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useCallback, useMemo } from 'react'\nimport { useQueryStates } from 'nuqs'\nimport { useSandboxTraces, TracesQueryParams } from '@/hooks/useSandboxTraces'\nimport { useSandboxTraceSpans } from '@/hooks/useSandboxTraceSpans'\nimport { TimeRangeSelector } from '@/components/telemetry/TimeRangeSelector'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { CopyButton } from '@/components/CopyButton'\nimport { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { DAYTONA_DOCS_URL } from '@/constants/ExternalLinks'\nimport { ChevronLeft, ChevronRight, RefreshCw, Activity, ChevronDown } from 'lucide-react'\nimport { format, subHours } from 'date-fns'\nimport { TraceSummary, TraceSpan } from '@daytonaio/api-client'\nimport { cn } from '@/lib/utils'\nimport { tracesSearchParams, timeRangeSearchParams } from './SearchParams'\n\ninterface SpanNode extends TraceSpan {\n  depth: number\n  children: SpanNode[]\n}\n\nfunction buildSpanTree(spans: TraceSpan[]): SpanNode[] {\n  const map = new Map<string, SpanNode>()\n  const roots: SpanNode[] = []\n\n  for (const span of spans) {\n    map.set(span.spanId, { ...span, depth: 0, children: [] })\n  }\n  for (const span of spans) {\n    const node = map.get(span.spanId)!\n    if (span.parentSpanId && map.has(span.parentSpanId)) {\n      map.get(span.parentSpanId)!.children.push(node)\n    } else {\n      roots.push(node)\n    }\n  }\n\n  const assignDepths = (nodes: SpanNode[], depth: number) => {\n    for (const n of nodes) {\n      n.depth = depth\n      assignDepths(n.children, depth + 1)\n    }\n  }\n  assignDepths(roots, 0)\n\n  const flat: SpanNode[] = []\n  const walk = (nodes: SpanNode[]) => {\n    nodes.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime())\n    for (const n of nodes) {\n      flat.push(n)\n      walk(n.children)\n    }\n  }\n  walk(roots)\n  return flat\n}\n\nfunction formatNsDuration(ns: number) {\n  const ms = ns / 1_000_000\n  if (ms < 1) return `${(ms * 1000).toFixed(0)}µs`\n  if (ms < 1000) return `${ms.toFixed(2)}ms`\n  return `${(ms / 1000).toFixed(2)}s`\n}\n\nfunction formatMsDuration(ms: number) {\n  if (ms < 1) return `${(ms * 1000).toFixed(2)}µs`\n  if (ms < 1000) return `${ms.toFixed(2)}ms`\n  return `${(ms / 1000).toFixed(2)}s`\n}\n\nfunction formatTimestamp(timestamp: string) {\n  try {\n    return format(new Date(timestamp), 'yyyy-MM-dd HH:mm:ss.SSS')\n  } catch {\n    return timestamp\n  }\n}\n\nfunction truncateId(id: string) {\n  return id.length > 16 ? `${id.slice(0, 8)}…${id.slice(-8)}` : id\n}\n\nfunction statusColor(code?: string): string {\n  if (!code) return 'bg-blue-500/70'\n  const c = code.toUpperCase()\n  if (c === 'ERROR' || c === 'STATUS_CODE_ERROR') return 'bg-destructive/70'\n  if (c === 'OK' || c === 'STATUS_CODE_OK') return 'bg-emerald-500/70'\n  return 'bg-blue-500/70'\n}\n\nfunction TracesTableSkeleton() {\n  return (\n    <Table>\n      <TableHeader>\n        <TableRow>\n          <TableHead className=\"w-10\" />\n          <TableHead>Trace ID</TableHead>\n          <TableHead>Root Span</TableHead>\n          <TableHead>Start Time</TableHead>\n          <TableHead>Duration</TableHead>\n          <TableHead className=\"text-center\">Spans</TableHead>\n        </TableRow>\n      </TableHeader>\n      <TableBody>\n        {Array.from({ length: 8 }).map((_, i) => (\n          <TableRow key={i}>\n            <TableCell>\n              <Skeleton className=\"size-4\" />\n            </TableCell>\n            <TableCell>\n              <Skeleton className=\"h-4 w-28\" />\n            </TableCell>\n            <TableCell>\n              <Skeleton className=\"h-4\" style={{ width: `${40 + (i % 3) * 15}%` }} />\n            </TableCell>\n            <TableCell>\n              <Skeleton className=\"h-4 w-36\" />\n            </TableCell>\n            <TableCell>\n              <Skeleton className=\"h-4 w-16\" />\n            </TableCell>\n            <TableCell className=\"text-center\">\n              <Skeleton className=\"h-4 w-8 mx-auto\" />\n            </TableCell>\n          </TableRow>\n        ))}\n      </TableBody>\n    </Table>\n  )\n}\n\nfunction TracesErrorState({ onRetry }: { onRetry: () => void }) {\n  return (\n    <Empty className=\"flex-1 border-0\">\n      <EmptyHeader>\n        <EmptyTitle>Failed to load traces</EmptyTitle>\n        <EmptyDescription>Something went wrong while fetching traces.</EmptyDescription>\n      </EmptyHeader>\n      <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n        <RefreshCw className=\"size-4\" />\n        Retry\n      </Button>\n    </Empty>\n  )\n}\n\nfunction TracesEmptyState() {\n  return (\n    <Empty className=\"flex-1 border-0\">\n      <EmptyHeader>\n        <EmptyMedia variant=\"icon\">\n          <Activity className=\"size-4\" />\n        </EmptyMedia>\n        <EmptyTitle>No traces found</EmptyTitle>\n        <EmptyDescription>\n          Try adjusting your time range.{' '}\n          <a href={`${DAYTONA_DOCS_URL}/en/experimental/otel-collection`} target=\"_blank\" rel=\"noopener noreferrer\">\n            Learn more about observability\n          </a>\n          .\n        </EmptyDescription>\n      </EmptyHeader>\n    </Empty>\n  )\n}\n\nfunction DetailRow({ label, children, mono = true }: { label: string; children: React.ReactNode; mono?: boolean }) {\n  return (\n    <div>\n      <span className=\"text-muted-foreground text-[10px] uppercase tracking-wider font-semibold\">{label}</span>\n      <div className={cn('flex items-center gap-1 mt-0.5', mono && 'font-mono')}>{children}</div>\n    </div>\n  )\n}\n\nfunction TraceExpandedRow({ sandboxId, trace }: { sandboxId: string; trace: TraceSummary }) {\n  const { data: spans, isLoading, isError, refetch } = useSandboxTraceSpans(sandboxId, trace.traceId)\n  const [selectedSpanId, setSelectedSpanId] = useState<string | null>(null)\n\n  const spanTree = useMemo(() => (spans ? buildSpanTree(spans) : []), [spans])\n\n  const { traceStart, traceDuration } = useMemo(() => {\n    if (!spans?.length) return { traceStart: 0, traceDuration: 0 }\n    const starts = spans.map((s) => new Date(s.timestamp).getTime())\n    const ends = spans.map((s, i) => starts[i] + s.durationNs / 1_000_000)\n    const start = Math.min(...starts)\n    return { traceStart: start, traceDuration: Math.max(...ends) - start }\n  }, [spans])\n\n  const selectedSpan = useMemo(\n    () => spanTree.find((s) => s.spanId === selectedSpanId) ?? null,\n    [spanTree, selectedSpanId],\n  )\n\n  if (isLoading) {\n    return (\n      <div className=\"flex h-[340px] border-t border-border\">\n        <div className=\"w-1/2 border-r border-border flex flex-col overflow-hidden\">\n          <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border bg-muted/30 shrink-0\">\n            <Skeleton className=\"h-3 w-10\" />\n          </div>\n          <div className=\"py-1 flex flex-col gap-0.5\">\n            {Array.from({ length: 8 }).map((_, i) => (\n              <div\n                key={i}\n                className=\"flex items-center gap-2 px-3 py-1\"\n                style={{ paddingLeft: `${12 + (i % 3) * 14}px` }}\n              >\n                <Skeleton className=\"shrink-0 h-3 w-[120px]\" />\n                <Skeleton className=\"flex-1 h-4 rounded min-w-[60px]\" />\n                <Skeleton className=\"shrink-0 h-3 w-[56px]\" />\n              </div>\n            ))}\n          </div>\n        </div>\n        <div className=\"w-1/2 flex flex-col overflow-hidden\">\n          <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border bg-muted/30 shrink-0\">\n            <span className=\"text-xs font-medium text-muted-foreground\">Select a span</span>\n          </div>\n          <div className=\"flex-1 flex items-center justify-center text-muted-foreground text-sm\">\n            Click a span to see details\n          </div>\n        </div>\n      </div>\n    )\n  }\n\n  if (isError) {\n    return (\n      <div className=\"flex flex-col items-center justify-center gap-3 h-[340px] text-muted-foreground\">\n        <p className=\"text-sm\">Failed to load spans.</p>\n        <Button variant=\"outline\" size=\"sm\" onClick={() => refetch()}>\n          <RefreshCw className=\"size-4\" />\n          Retry\n        </Button>\n      </div>\n    )\n  }\n\n  if (!spanTree.length) {\n    return (\n      <div className=\"flex items-center justify-center h-48 text-muted-foreground text-sm\">\n        No spans found for this trace.\n      </div>\n    )\n  }\n\n  return (\n    <div className=\"flex h-[340px] border-t border-border\">\n      <div className=\"w-1/2 border-r border-border flex flex-col overflow-hidden\">\n        <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border bg-muted/30 shrink-0\">\n          <span className=\"text-xs font-medium text-muted-foreground\">Spans</span>\n          <span className=\"text-xs text-muted-foreground\">({spanTree.length})</span>\n        </div>\n        <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0\">\n          <div className=\"py-1\">\n            {spanTree.map((span) => {\n              const spanStartMs = new Date(span.timestamp).getTime()\n              const spanDurMs = span.durationNs / 1_000_000\n              const offsetPct = traceDuration > 0 ? ((spanStartMs - traceStart) / traceDuration) * 100 : 0\n              const widthPct = traceDuration > 0 ? (spanDurMs / traceDuration) * 100 : 100\n              const isSelected = selectedSpanId === span.spanId\n\n              return (\n                <button\n                  key={span.spanId}\n                  type=\"button\"\n                  onClick={() => setSelectedSpanId(span.spanId)}\n                  className={cn(\n                    'w-full text-left flex items-center gap-2 px-3 py-1 hover:bg-muted/50 transition-colors',\n                    isSelected && 'bg-muted',\n                  )}\n                  style={{ paddingLeft: `${12 + span.depth * 14}px` }}\n                >\n                  <span className=\"shrink-0 w-[120px] truncate text-xs\">{span.spanName}</span>\n                  <div className=\"flex-1 h-4 bg-muted/60 rounded relative overflow-hidden min-w-[60px]\">\n                    <div\n                      className={cn('absolute h-full rounded', statusColor(span.statusCode))}\n                      style={{\n                        left: `${Math.min(offsetPct, 99)}%`,\n                        width: `${Math.max(widthPct, 1)}%`,\n                      }}\n                    />\n                  </div>\n                  <span className=\"shrink-0 text-[10px] font-mono text-muted-foreground w-[56px] text-right\">\n                    {formatNsDuration(span.durationNs)}\n                  </span>\n                </button>\n              )\n            })}\n          </div>\n        </ScrollArea>\n      </div>\n\n      <div className=\"w-1/2 flex flex-col overflow-hidden\">\n        <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border bg-muted/30 shrink-0\">\n          <span className=\"text-xs font-medium text-muted-foreground\">\n            {selectedSpan ? 'Span Detail' : 'Select a span'}\n          </span>\n        </div>\n        {selectedSpan ? (\n          <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0\">\n            <div className=\"p-3 space-y-3 text-xs\">\n              <DetailRow label=\"Name\" mono={false}>\n                {selectedSpan.spanName}\n              </DetailRow>\n              <DetailRow label=\"Span ID\">\n                <span className=\"font-mono\">{selectedSpan.spanId}</span>\n                <CopyButton value={selectedSpan.spanId} tooltipText=\"Copy\" size=\"icon-xs\" />\n              </DetailRow>\n              {selectedSpan.parentSpanId && (\n                <DetailRow label=\"Parent Span ID\">\n                  <span className=\"font-mono\">{selectedSpan.parentSpanId}</span>\n                  <CopyButton value={selectedSpan.parentSpanId} tooltipText=\"Copy\" size=\"icon-xs\" />\n                </DetailRow>\n              )}\n              <DetailRow label=\"Start\">\n                <span className=\"font-mono\">{formatTimestamp(selectedSpan.timestamp)}</span>\n              </DetailRow>\n              <DetailRow label=\"Duration\">\n                <span className=\"font-mono\">{formatNsDuration(selectedSpan.durationNs)}</span>\n              </DetailRow>\n              {selectedSpan.statusCode && (\n                <DetailRow label=\"Status\">\n                  <span\n                    className={cn(\n                      'inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium',\n                      selectedSpan.statusCode.toUpperCase().includes('ERROR')\n                        ? 'bg-destructive/10 text-destructive'\n                        : selectedSpan.statusCode.toUpperCase().includes('OK')\n                          ? 'bg-emerald-500/10 text-emerald-600 dark:text-emerald-400'\n                          : 'bg-muted text-muted-foreground',\n                    )}\n                  >\n                    {selectedSpan.statusCode}\n                  </span>\n                  {selectedSpan.statusMessage && (\n                    <span className=\"text-muted-foreground ml-2\">{selectedSpan.statusMessage}</span>\n                  )}\n                </DetailRow>\n              )}\n              {Object.keys(selectedSpan.spanAttributes ?? {}).length > 0 && (\n                <div>\n                  <span className=\"text-muted-foreground text-[10px] uppercase tracking-wider font-semibold\">\n                    Attributes\n                  </span>\n                  <div className=\"mt-1.5 rounded border border-border overflow-hidden\">\n                    <table className=\"w-full text-xs\">\n                      <tbody>\n                        {Object.entries(selectedSpan.spanAttributes).map(([key, val]) => (\n                          <tr key={key} className=\"border-b border-border last:border-b-0\">\n                            <td className=\"px-2 py-1 text-muted-foreground font-mono bg-muted/30 w-[40%] align-middle break-all\">\n                              {key}\n                            </td>\n                            <td className=\"px-2 py-1 font-mono align-middle break-all\">{val}</td>\n                          </tr>\n                        ))}\n                      </tbody>\n                    </table>\n                  </div>\n                </div>\n              )}\n            </div>\n          </ScrollArea>\n        ) : (\n          <div className=\"flex-1 flex items-center justify-center text-muted-foreground text-sm\">\n            Click a span to see details\n          </div>\n        )}\n      </div>\n    </div>\n  )\n}\n\nexport function SandboxTracesTab({ sandboxId }: { sandboxId: string }) {\n  const [params, setParams] = useQueryStates(tracesSearchParams)\n  const [timeRange, setTimeRange] = useQueryStates(timeRangeSearchParams)\n  const [expandedTraceId, setExpandedTraceId] = useState<string | null>(null)\n  const limit = 50\n\n  const resolvedFrom = useMemo(() => timeRange.from ?? subHours(new Date(), 1), [timeRange.from])\n  const resolvedTo = useMemo(() => timeRange.to ?? new Date(), [timeRange.to])\n\n  const queryParams: TracesQueryParams = useMemo(\n    () => ({\n      from: resolvedFrom,\n      to: resolvedTo,\n      page: params.tracesPage,\n      limit,\n    }),\n    [resolvedFrom, resolvedTo, params.tracesPage],\n  )\n\n  const { data, isLoading, isError, refetch } = useSandboxTraces(sandboxId, queryParams)\n\n  const handleTimeRangeChange = useCallback(\n    (from: Date, to: Date) => {\n      setTimeRange({ from, to })\n      setParams({ tracesPage: 1 })\n    },\n    [setTimeRange, setParams],\n  )\n\n  return (\n    <div className=\"flex flex-col h-full gap-4 p-4\">\n      <div className=\"flex flex-wrap items-center gap-3 shrink-0\">\n        <TimeRangeSelector\n          onChange={handleTimeRangeChange}\n          defaultRange={timeRange.from && timeRange.to ? { from: timeRange.from, to: timeRange.to } : undefined}\n          className=\"w-auto\"\n        />\n        <Button variant=\"ghost\" size=\"icon-sm\" onClick={() => refetch()} className=\"ml-auto\">\n          <RefreshCw className=\"size-4\" />\n        </Button>\n      </div>\n\n      {isLoading ? (\n        <div className=\"flex-1 min-h-0 border rounded-md\">\n          <TracesTableSkeleton />\n        </div>\n      ) : isError ? (\n        <div className=\"flex-1 min-h-0 border rounded-md flex\">\n          <TracesErrorState onRetry={() => refetch()} />\n        </div>\n      ) : !data?.items?.length ? (\n        <div className=\"flex-1 min-h-0 border rounded-md flex\">\n          <TracesEmptyState />\n        </div>\n      ) : (\n        <ScrollArea\n          fade=\"mask\"\n          horizontal\n          className=\"flex-1 min-h-0 border rounded-md [&_[data-slot=scroll-area-viewport]>div]:!overflow-visible [&_[data-slot=scroll-area-viewport]>div>div]:!overflow-visible\"\n        >\n          <Table>\n            <TableHeader className=\"sticky top-0 z-10 bg-background after:absolute after:bottom-0 after:left-0 after:right-0 after:h-px after:bg-border\">\n              <TableRow>\n                <TableHead className=\"w-10\" />\n                <TableHead>Trace ID</TableHead>\n                <TableHead>Root Span</TableHead>\n                <TableHead>Start Time</TableHead>\n                <TableHead>Duration</TableHead>\n                <TableHead className=\"text-center\">Spans</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {data.items.map((trace: TraceSummary) => {\n                const isExpanded = expandedTraceId === trace.traceId\n                return (\n                  <React.Fragment key={trace.traceId}>\n                    <TableRow\n                      className=\"cursor-pointer hover:bg-muted/50 group/trace-row\"\n                      onClick={() => setExpandedTraceId(isExpanded ? null : trace.traceId)}\n                    >\n                      <TableCell className=\"w-10 px-2\">\n                        <ChevronDown\n                          className={cn(\n                            'size-4 text-muted-foreground transition-transform duration-200',\n                            isExpanded && 'rotate-180',\n                          )}\n                        />\n                      </TableCell>\n                      <TableCell className=\"font-mono text-xs whitespace-nowrap\">\n                        <div className=\"flex items-center gap-1\">\n                          <span>{truncateId(trace.traceId)}</span>\n                          <CopyButton\n                            value={trace.traceId}\n                            tooltipText=\"Copy Trace ID\"\n                            size=\"icon-xs\"\n                            className=\"[@media(hover:hover)]:opacity-0 [@media(hover:hover)]:group-hover/trace-row:opacity-100 transition-opacity\"\n                            onClick={(e) => e.stopPropagation()}\n                          />\n                        </div>\n                      </TableCell>\n                      <TableCell className=\"max-w-xs truncate\">{trace.rootSpanName}</TableCell>\n                      <TableCell className=\"font-mono text-xs\">{formatTimestamp(trace.startTime)}</TableCell>\n                      <TableCell className=\"font-mono text-xs\">{formatMsDuration(trace.durationMs)}</TableCell>\n                      <TableCell className=\"text-center\">{trace.spanCount}</TableCell>\n                    </TableRow>\n                    {isExpanded && (\n                      <TableRow>\n                        <TableCell colSpan={6} className=\"p-0\">\n                          <TraceExpandedRow sandboxId={sandboxId} trace={trace} />\n                        </TableCell>\n                      </TableRow>\n                    )}\n                  </React.Fragment>\n                )\n              })}\n            </TableBody>\n          </Table>\n        </ScrollArea>\n      )}\n\n      {data && data.totalPages > 1 && (\n        <div className=\"flex items-center justify-between shrink-0\">\n          <span className=\"text-sm text-muted-foreground\">\n            Page {params.tracesPage} of {data.totalPages} ({data.total} total)\n          </span>\n          <div className=\"flex items-center gap-2\">\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              disabled={params.tracesPage <= 1}\n              onClick={() => setParams({ tracesPage: params.tracesPage - 1 })}\n            >\n              <ChevronLeft className=\"size-4\" />\n              Previous\n            </Button>\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              disabled={params.tracesPage >= data.totalPages}\n              onClick={() => setParams({ tracesPage: params.tracesPage + 1 })}\n            >\n              Next\n              <ChevronRight className=\"size-4\" />\n            </Button>\n          </div>\n        </div>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SandboxVncTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useEffect } from 'react'\nimport { Button } from '@/components/ui/button'\nimport { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { DAYTONA_DOCS_URL } from '@/constants/ExternalLinks'\nimport { useStartVncMutation } from '@/hooks/mutations/useStartVncMutation'\nimport { useVncInitialStatusQuery, useVncPollStatusQuery } from '@/hooks/queries/useVncStatusQuery'\nimport { useVncSessionQuery } from '@/hooks/queries/useVncSessionQuery'\nimport { isStoppable } from '@/lib/utils/sandbox'\nimport { Sandbox } from '@daytonaio/api-client'\nimport { Spinner } from '@/components/ui/spinner'\nimport { Monitor, Play, RefreshCw } from 'lucide-react'\n\nconst VNC_MISSING_DEPS_MSG = 'Computer-use functionality is not available'\n\nexport function SandboxVncTab({ sandbox }: { sandbox: Sandbox }) {\n  const running = isStoppable(sandbox)\n\n  // 1. Check initial VNC availability & status\n  const initialStatusQuery = useVncInitialStatusQuery(sandbox.id, running)\n\n  const isMissingDeps = (initialStatusQuery.error as Error | null)?.message === VNC_MISSING_DEPS_MSG\n  const alreadyActive = initialStatusQuery.data === 'active'\n\n  // 2. Start VNC\n  const startMutation = useStartVncMutation(sandbox.id)\n\n  const startError = startMutation.error?.message\n  const startMissingDeps = startError === VNC_MISSING_DEPS_MSG\n\n  // 3. Poll until active after starting\n  const pollStatusQuery = useVncPollStatusQuery(sandbox.id, startMutation.isSuccess)\n\n  const vncReady = alreadyActive || pollStatusQuery.data === 'active'\n\n  // 4. Get signed URL once ready\n  const {\n    data: session,\n    isLoading: sessionLoading,\n    isError: sessionError,\n    existingSession,\n    reset,\n  } = useVncSessionQuery(sandbox.id, vncReady)\n\n  // Auto-reconnect: if session is expired, refetch\n  useEffect(() => {\n    if (!existingSession) return\n    if (existingSession.expiresAt <= Date.now()) {\n      reset()\n    }\n  }, [existingSession, reset])\n\n  const isStarting =\n    startMutation.isPending ||\n    (startMutation.isSuccess && !pollStatusQuery.data && !pollStatusQuery.error) ||\n    (vncReady && sessionLoading)\n\n  const unavailable = isMissingDeps || startMissingDeps\n  const pollError = pollStatusQuery.error?.message\n  const anyError = startError && !startMissingDeps ? startError : pollError\n\n  if (!running) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <Empty className=\"border-0\">\n            <EmptyHeader>\n              <EmptyMedia variant=\"icon\">\n                <Monitor className=\"size-4\" />\n              </EmptyMedia>\n              <EmptyTitle>Sandbox is not running</EmptyTitle>\n              <EmptyDescription>\n                Start the sandbox to access the VNC desktop.{' '}\n                <a href={`${DAYTONA_DOCS_URL}/en/vnc-access`} target=\"_blank\" rel=\"noopener noreferrer\">\n                  Learn more\n                </a>\n                .\n              </EmptyDescription>\n            </EmptyHeader>\n          </Empty>\n        </div>\n      </div>\n    )\n  }\n\n  if (initialStatusQuery.isLoading) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex items-center justify-center gap-2 text-muted-foreground\">\n          <Spinner className=\"size-4\" />\n          <span className=\"text-sm\">Checking VNC status...</span>\n        </div>\n      </div>\n    )\n  }\n\n  if (unavailable) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <Empty className=\"border-0\">\n            <EmptyHeader>\n              <EmptyMedia variant=\"icon\">\n                <Monitor className=\"size-4\" />\n              </EmptyMedia>\n              <EmptyTitle>VNC not available</EmptyTitle>\n              <EmptyDescription>\n                Computer-use dependencies are not installed in this sandbox.{' '}\n                <a href={`${DAYTONA_DOCS_URL}/en/vnc-access`} target=\"_blank\" rel=\"noopener noreferrer\">\n                  Read the setup guide\n                </a>\n                .\n              </EmptyDescription>\n            </EmptyHeader>\n          </Empty>\n        </div>\n      </div>\n    )\n  }\n\n  // Not yet started — show start button\n  if (!vncReady && !isStarting) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <Empty className=\"border-0\">\n            <EmptyHeader>\n              <EmptyMedia variant=\"icon\">\n                <Monitor className=\"size-4\" />\n              </EmptyMedia>\n              <EmptyTitle>VNC Desktop</EmptyTitle>\n              <EmptyDescription>\n                Start the VNC server to access a graphical desktop.{' '}\n                <a href={`${DAYTONA_DOCS_URL}/en/vnc-access`} target=\"_blank\" rel=\"noopener noreferrer\">\n                  Learn more\n                </a>\n                .\n              </EmptyDescription>\n            </EmptyHeader>\n            <Button onClick={() => startMutation.mutate()}>\n              <Play className=\"size-4\" />\n              Start VNC\n            </Button>\n          </Empty>\n        </div>\n      </div>\n    )\n  }\n\n  // Starting / polling / getting URL\n  if (isStarting) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border bg-neutral-950 flex items-center justify-center gap-2 text-muted-foreground\">\n          <Spinner className=\"size-4\" />\n          <span className=\"text-sm\">\n            {startMutation.isPending\n              ? 'Starting VNC desktop...'\n              : vncReady && sessionLoading\n                ? 'Getting preview URL...'\n                : 'Waiting for VNC to become ready...'}\n          </span>\n        </div>\n      </div>\n    )\n  }\n\n  // Error\n  if (anyError || sessionError) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border flex\">\n          <Empty className=\"border-0\">\n            <EmptyHeader>\n              <EmptyTitle>Failed to connect</EmptyTitle>\n              <EmptyDescription>{anyError || 'Something went wrong while connecting to VNC.'}</EmptyDescription>\n            </EmptyHeader>\n            <Button variant=\"outline\" size=\"sm\" onClick={reset}>\n              <RefreshCw className=\"size-4\" />\n              Retry\n            </Button>\n          </Empty>\n        </div>\n      </div>\n    )\n  }\n\n  // Active session\n  if (session) {\n    return (\n      <div className=\"flex-1 flex flex-col p-4\">\n        <div className=\"flex-1 min-h-0 rounded-md border border-border bg-neutral-950 overflow-hidden\">\n          <iframe\n            title=\"VNC desktop\"\n            src={`${session.url}/vnc.html?autoconnect=true&resize=scale`}\n            className=\"w-full h-full border-0\"\n          />\n        </div>\n      </div>\n    )\n  }\n\n  return null\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/SearchParams.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { parseAsArrayOf, parseAsInteger, parseAsIsoDateTime, parseAsString, parseAsStringLiteral } from 'nuqs'\n\nexport const TAB_VALUES = ['overview', 'logs', 'traces', 'metrics', 'spending', 'terminal', 'vnc'] as const\nexport type TabValue = (typeof TAB_VALUES)[number]\n\nexport const SEVERITY_OPTIONS = ['DEBUG', 'INFO', 'WARN', 'ERROR'] as const\n\nexport const tabParser = parseAsStringLiteral(TAB_VALUES).withDefault('overview')\n\nexport const logsSearchParams = {\n  logsPage: parseAsInteger.withDefault(1),\n  search: parseAsString.withDefault(''),\n  severity: parseAsArrayOf(parseAsStringLiteral(SEVERITY_OPTIONS)).withDefault([]),\n}\n\nexport const tracesSearchParams = {\n  tracesPage: parseAsInteger.withDefault(1),\n}\n\nexport const timeRangeSearchParams = {\n  from: parseAsIsoDateTime,\n  to: parseAsIsoDateTime,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/sandboxes/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport { default as SandboxDetails } from './SandboxDetails'\nexport { SandboxLogsTab } from './SandboxLogsTab'\nexport { SandboxTracesTab } from './SandboxTracesTab'\nexport { SandboxMetricsTab } from './SandboxMetricsTab'\nexport { SandboxTerminalTab } from './SandboxTerminalTab'\nexport { SandboxVncTab } from './SandboxVncTab'\nexport { SandboxHeader } from './SandboxHeader'\nexport { SandboxInfoPanel, InfoPanelSkeleton, InfoSection, InfoRow } from './SandboxInfoPanel'\n"
  },
  {
    "path": "apps/dashboard/src/components/snapshots/CreateSnapshotDialog.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { Field, FieldDescription, FieldError, FieldLabel } from '@/components/ui/field'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Spinner } from '@/components/ui/spinner'\nimport { useCreateSnapshotMutation } from '@/hooks/mutations/useCreateSnapshotMutation'\nimport { useRegions } from '@/hooks/useRegions'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { getRegionFullDisplayName } from '@/lib/utils'\nimport { useForm } from '@tanstack/react-form'\nimport { Plus } from 'lucide-react'\nimport { Ref, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'\nimport { toast } from 'sonner'\nimport { imageNameSchema } from '@/lib/schema'\nimport { z } from 'zod'\nimport { ScrollArea } from '../ui/scroll-area'\n\nconst IMAGE_NAME_REGEX = /^[a-zA-Z0-9_.\\-:]+(\\/[a-zA-Z0-9_.\\-:]+)*(@sha256:[a-f0-9]{64})?$/\n\nconst snapshotNameSchema = z\n  .string()\n  .min(1, 'Snapshot name is required')\n  .refine((name) => IMAGE_NAME_REGEX.test(name), 'Only letters, digits, dots, colons, slashes and dashes are allowed')\n\nconst formSchema = z.object({\n  name: snapshotNameSchema,\n  imageName: imageNameSchema,\n  entrypoint: z.string().optional(),\n  cpu: z.number().min(1).optional(),\n  memory: z.number().min(1).optional(),\n  disk: z.number().min(1).optional(),\n  regionId: z.string().optional(),\n})\n\ntype FormValues = z.infer<typeof formSchema>\n\nconst defaultValues: FormValues = {\n  name: '',\n  imageName: '',\n  entrypoint: '',\n  cpu: undefined,\n  memory: undefined,\n  disk: undefined,\n  regionId: undefined,\n}\n\nexport const CreateSnapshotDialog = ({ className, ref }: { className?: string; ref?: Ref<{ open: () => void }> }) => {\n  const [open, setOpen] = useState(false)\n\n  const { availableRegions: regions, loadingAvailableRegions: loadingRegions } = useRegions()\n  const { selectedOrganization } = useSelectedOrganization()\n  const { reset: resetCreateSnapshotMutation, ...createSnapshotMutation } = useCreateSnapshotMutation()\n  const formRef = useRef<HTMLFormElement>(null)\n\n  useImperativeHandle(ref, () => ({\n    open: () => setOpen(true),\n  }))\n\n  const form = useForm({\n    defaultValues,\n    validators: {\n      onSubmit: formSchema,\n    },\n    onSubmitInvalid: () => {\n      const form = formRef.current\n      if (!form) return\n      const invalidInput = form.querySelector('[aria-invalid=\"true\"]') as HTMLInputElement | null\n      if (invalidInput) {\n        invalidInput.scrollIntoView({ behavior: 'smooth', block: 'center' })\n        invalidInput.focus()\n      }\n    },\n    onSubmit: async ({ value }) => {\n      if (!selectedOrganization?.id) {\n        toast.error('Select an organization to create a snapshot.')\n        return\n      }\n\n      const trimmedEntrypoint = value.entrypoint?.trim()\n\n      try {\n        await createSnapshotMutation.mutateAsync({\n          snapshot: {\n            name: value.name.trim(),\n            imageName: value.imageName.trim(),\n            entrypoint: trimmedEntrypoint ? trimmedEntrypoint.split(' ') : undefined,\n            cpu: value.cpu,\n            memory: value.memory,\n            disk: value.disk,\n            regionId: value.regionId,\n          },\n          organizationId: selectedOrganization.id,\n        })\n\n        toast.success(`Creating snapshot ${value.name.trim()}`)\n        setOpen(false)\n      } catch (error) {\n        handleApiError(error, 'Failed to create snapshot')\n      }\n    },\n  })\n\n  const resetState = useCallback(() => {\n    form.reset(defaultValues)\n    resetCreateSnapshotMutation()\n  }, [resetCreateSnapshotMutation, form])\n\n  useEffect(() => {\n    if (open) {\n      resetState()\n    }\n  }, [open, resetState])\n\n  return (\n    <Dialog\n      open={open}\n      onOpenChange={(isOpen) => {\n        setOpen(isOpen)\n      }}\n    >\n      <DialogTrigger asChild>\n        <Button variant=\"default\" size=\"sm\" className=\"ml-auto\" title=\"Create Snapshot\">\n          <Plus className=\"w-4 h-4\" />\n          Create Snapshot\n        </Button>\n      </DialogTrigger>\n      <DialogContent className={className}>\n        <DialogHeader>\n          <DialogTitle>Create New Snapshot</DialogTitle>\n          <DialogDescription>\n            Register a new snapshot to be used for spinning up sandboxes in your organization.\n          </DialogDescription>\n        </DialogHeader>\n        <ScrollArea fade=\"mask\" className=\"h-[500px] overflow-auto -mx-5\">\n          <form\n            ref={formRef}\n            id=\"create-snapshot-form\"\n            className=\"gap-6 flex flex-col px-5\"\n            onSubmit={(e) => {\n              e.preventDefault()\n              e.stopPropagation()\n              form.handleSubmit()\n            }}\n          >\n            <form.Field name=\"name\">\n              {(field) => {\n                const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                return (\n                  <Field data-invalid={isInvalid}>\n                    <FieldLabel htmlFor={field.name}>Snapshot Name</FieldLabel>\n                    <Input\n                      aria-invalid={isInvalid}\n                      id={field.name}\n                      name={field.name}\n                      value={field.state.value}\n                      onBlur={field.handleBlur}\n                      onChange={(e) => field.handleChange(e.target.value)}\n                      placeholder=\"ubuntu-4vcpu-8ram-100gb\"\n                    />\n                    <FieldDescription>\n                      The name you will use in your client app (SDK, CLI) to reference the snapshot.\n                    </FieldDescription>\n                    {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                      <FieldError errors={field.state.meta.errors} />\n                    )}\n                  </Field>\n                )\n              }}\n            </form.Field>\n\n            <form.Field name=\"imageName\">\n              {(field) => {\n                const isInvalid = field.state.meta.isTouched && !field.state.meta.isValid\n                return (\n                  <Field data-invalid={isInvalid}>\n                    <FieldLabel htmlFor={field.name}>Image</FieldLabel>\n                    <Input\n                      aria-invalid={isInvalid}\n                      id={field.name}\n                      name={field.name}\n                      value={field.state.value}\n                      onBlur={field.handleBlur}\n                      onChange={(e) => field.handleChange(e.target.value)}\n                      placeholder=\"ubuntu:22.04\"\n                    />\n                    <FieldDescription>\n                      Must include either a tag (e.g., ubuntu:22.04) or a digest. The tag \"latest\" is not allowed.\n                    </FieldDescription>\n                    {field.state.meta.errors.length > 0 && field.state.meta.isTouched && (\n                      <FieldError errors={field.state.meta.errors} />\n                    )}\n                  </Field>\n                )\n              }}\n            </form.Field>\n\n            <form.Field name=\"regionId\">\n              {(field) => (\n                <Field>\n                  <FieldLabel htmlFor={field.name}>Region</FieldLabel>\n                  <Select value={field.state.value} onValueChange={field.handleChange}>\n                    <SelectTrigger className=\"h-8\" id={field.name} disabled={loadingRegions} loading={loadingRegions}>\n                      <SelectValue placeholder={loadingRegions ? 'Loading regions...' : 'Select a region'} />\n                    </SelectTrigger>\n                    <SelectContent>\n                      {regions.map((region) => (\n                        <SelectItem key={region.id} value={region.id}>\n                          {getRegionFullDisplayName(region)}\n                        </SelectItem>\n                      ))}\n                    </SelectContent>\n                  </Select>\n                  <FieldDescription>\n                    The region where the snapshot will be available. If not specified, your organization's default\n                    region will be used.\n                  </FieldDescription>\n                </Field>\n              )}\n            </form.Field>\n\n            <div className=\"flex flex-col gap-2\">\n              <Label className=\"text-sm font-medium\">Resources</Label>\n              <div className=\"flex flex-col gap-2\">\n                <form.Field name=\"cpu\">\n                  {(field) => (\n                    <div className=\"flex items-center gap-4\">\n                      <Label htmlFor={field.name} className=\"w-32 flex-shrink-0\">\n                        Compute (vCPU):\n                      </Label>\n                      <Input\n                        id={field.name}\n                        type=\"number\"\n                        className=\"w-full\"\n                        min=\"1\"\n                        placeholder=\"1\"\n                        value={field.state.value ?? ''}\n                        onChange={(e) => field.handleChange(parseInt(e.target.value) || undefined)}\n                      />\n                    </div>\n                  )}\n                </form.Field>\n                <form.Field name=\"memory\">\n                  {(field) => (\n                    <div className=\"flex items-center gap-4\">\n                      <Label htmlFor={field.name} className=\"w-32 flex-shrink-0\">\n                        Memory (GiB):\n                      </Label>\n                      <Input\n                        id={field.name}\n                        type=\"number\"\n                        className=\"w-full\"\n                        min=\"1\"\n                        placeholder=\"1\"\n                        value={field.state.value ?? ''}\n                        onChange={(e) => field.handleChange(parseInt(e.target.value) || undefined)}\n                      />\n                    </div>\n                  )}\n                </form.Field>\n                <form.Field name=\"disk\">\n                  {(field) => (\n                    <div className=\"flex items-center gap-4\">\n                      <Label htmlFor={field.name} className=\"w-32 flex-shrink-0\">\n                        Storage (GiB):\n                      </Label>\n                      <Input\n                        id={field.name}\n                        type=\"number\"\n                        className=\"w-full\"\n                        min=\"1\"\n                        placeholder=\"3\"\n                        value={field.state.value ?? ''}\n                        onChange={(e) => field.handleChange(parseInt(e.target.value) || undefined)}\n                      />\n                    </div>\n                  )}\n                </form.Field>\n              </div>\n              <FieldDescription>\n                If not specified, default values will be used (1 vCPU, 1 GiB memory, 3 GiB storage).\n              </FieldDescription>\n            </div>\n\n            <form.Field name=\"entrypoint\">\n              {(field) => (\n                <Field>\n                  <FieldLabel htmlFor={field.name}>Entrypoint (optional)</FieldLabel>\n                  <Input\n                    id={field.name}\n                    name={field.name}\n                    value={field.state.value ?? ''}\n                    onBlur={field.handleBlur}\n                    onChange={(e) => field.handleChange(e.target.value)}\n                    placeholder=\"sleep infinity\"\n                  />\n                  <FieldDescription>\n                    Ensure that the entrypoint is a long running command. If not provided, or if the snapshot does not\n                    have an entrypoint, 'sleep infinity' will be used as the default.\n                  </FieldDescription>\n                </Field>\n              )}\n            </form.Field>\n          </form>\n        </ScrollArea>\n        <DialogFooter>\n          <DialogClose asChild>\n            <Button type=\"button\" variant=\"secondary\">\n              Cancel\n            </Button>\n          </DialogClose>\n          <form.Subscribe\n            selector={(state) => [state.canSubmit, state.isSubmitting]}\n            children={([canSubmit, isSubmitting]) => (\n              <Button\n                type=\"submit\"\n                form=\"create-snapshot-form\"\n                variant=\"default\"\n                disabled={!canSubmit || isSubmitting || !selectedOrganization?.id}\n              >\n                {isSubmitting && <Spinner />}\n                Create\n              </Button>\n            )}\n          />\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/snapshots/SnapshotTable/BulkActionAlertDialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from '../../ui/alert-dialog'\n\nexport enum SnapshotBulkAction {\n  Delete = 'delete',\n  Deactivate = 'deactivate',\n}\n\ninterface BulkActionData {\n  title: string\n  description: string\n  buttonLabel: string\n  buttonVariant?: 'destructive'\n}\n\nfunction getBulkActionData(action: SnapshotBulkAction, count: number): BulkActionData {\n  const countText = count === 1 ? 'this snapshot' : `these ${count} selected snapshots`\n\n  switch (action) {\n    case SnapshotBulkAction.Delete:\n      return {\n        title: 'Delete Snapshots',\n        description: `Are you sure you want to delete ${countText}? This action cannot be undone.`,\n        buttonLabel: 'Delete',\n        buttonVariant: 'destructive',\n      }\n    case SnapshotBulkAction.Deactivate:\n      return {\n        title: 'Deactivate Snapshots',\n        description: `Are you sure you want to deactivate ${countText}? Deactivated snapshots can be reactivated later.`,\n        buttonLabel: 'Deactivate',\n      }\n  }\n}\n\ninterface SnapshotBulkActionAlertDialogProps {\n  action: SnapshotBulkAction | null\n  count: number\n  onConfirm: () => void\n  onCancel: () => void\n}\n\nexport function SnapshotBulkActionAlertDialog({\n  action,\n  count,\n  onConfirm,\n  onCancel,\n}: SnapshotBulkActionAlertDialogProps) {\n  const data = action ? getBulkActionData(action, count) : null\n\n  if (!data) return null\n\n  return (\n    <AlertDialog open={action !== null} onOpenChange={(open) => !open && onCancel()}>\n      <AlertDialogContent>\n        <>\n          <AlertDialogHeader>\n            <AlertDialogTitle>{data.title}</AlertDialogTitle>\n            <AlertDialogDescription>{data.description}</AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <AlertDialogAction onClick={onConfirm} variant={data.buttonVariant}>\n              {data.buttonLabel}\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </>\n      </AlertDialogContent>\n    </AlertDialog>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/snapshots/SnapshotTable/SnapshotTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useCommandPaletteActions } from '@/components/CommandPalette'\nimport { SelectionToast } from '@/components/SelectionToast'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { SnapshotSorting } from '@/hooks/queries/useSnapshotsQuery'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { cn } from '@/lib/utils'\nimport { OrganizationRolePermissionsEnum, SnapshotDto, SnapshotState } from '@daytonaio/api-client'\nimport { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'\nimport { Box } from 'lucide-react'\nimport { AnimatePresence } from 'motion/react'\nimport { useCallback, useMemo, useState } from 'react'\nimport { Pagination } from '../../Pagination'\nimport { TableEmptyState } from '../../TableEmptyState'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../ui/table'\nimport { SnapshotBulkAction, SnapshotBulkActionAlertDialog } from './BulkActionAlertDialog'\nimport { columns } from './columns'\nimport {\n  getSnapshotBulkActionCounts,\n  isSnapshotActivatable,\n  isSnapshotDeactivatable,\n  isSnapshotDeletable,\n  useSnapshotsCommands,\n} from './useSnapshotsCommands'\nimport { convertApiSortingToTableSorting, convertTableSortingToApiSorting } from './utils'\n\ninterface DataTableProps {\n  data: SnapshotDto[]\n  loading: boolean\n  loadingSnapshots: Record<string, boolean>\n  getRegionName: (regionId: string) => string | undefined\n  onDelete: (snapshot: SnapshotDto) => void\n  onBulkDelete?: (snapshots: SnapshotDto[]) => void\n  onBulkDeactivate?: (snapshots: SnapshotDto[]) => void\n  onBulkActivate?: (snapshots: SnapshotDto[]) => void\n  onActivate?: (snapshot: SnapshotDto) => void\n  onDeactivate?: (snapshot: SnapshotDto) => void\n  onCreateSnapshot?: () => void\n  pagination: {\n    pageIndex: number\n    pageSize: number\n  }\n  pageCount: number\n  totalItems: number\n  onPaginationChange: (pagination: { pageIndex: number; pageSize: number }) => void\n  sorting: SnapshotSorting\n  onSortingChange: (sorting: SnapshotSorting) => void\n}\n\nexport function SnapshotTable({\n  data,\n  loading,\n  loadingSnapshots,\n  getRegionName,\n  onDelete,\n  onActivate,\n  onDeactivate,\n  onCreateSnapshot,\n  pagination,\n  pageCount,\n  totalItems,\n  onBulkDelete,\n  onBulkActivate,\n  onBulkDeactivate,\n  onPaginationChange,\n  sorting,\n  onSortingChange,\n}: DataTableProps) {\n  const { authenticatedUserHasPermission } = useSelectedOrganization()\n\n  const writePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_SNAPSHOTS),\n    [authenticatedUserHasPermission],\n  )\n\n  const deletePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.DELETE_SNAPSHOTS),\n    [authenticatedUserHasPermission],\n  )\n\n  const tableSorting = useMemo(() => convertApiSortingToTableSorting(sorting), [sorting])\n\n  const selectableCount = useMemo(() => {\n    return data.filter(\n      (snapshot) => !snapshot.general && !loadingSnapshots[snapshot.id] && snapshot.state !== SnapshotState.REMOVING,\n    ).length\n  }, [data, loadingSnapshots])\n\n  const table = useReactTable({\n    data,\n    columns,\n    getCoreRowModel: getCoreRowModel(),\n    manualSorting: true,\n    onSortingChange: (updater) => {\n      const newTableSorting = typeof updater === 'function' ? updater(table.getState().sorting) : updater\n      const newApiSorting = convertTableSortingToApiSorting(newTableSorting)\n      onSortingChange(newApiSorting)\n    },\n    manualPagination: true,\n    pageCount: pageCount || 1,\n    onPaginationChange: pagination\n      ? (updater) => {\n          const newPagination = typeof updater === 'function' ? updater(table.getState().pagination) : updater\n          onPaginationChange(newPagination)\n        }\n      : undefined,\n    state: {\n      sorting: tableSorting,\n      pagination: {\n        pageIndex: pagination?.pageIndex || 0,\n        pageSize: pagination?.pageSize || 10,\n      },\n    },\n    meta: {\n      snapshot: {\n        writePermitted,\n        deletePermitted,\n        loadingSnapshots,\n        getRegionName,\n        selectableCount,\n        onDelete,\n        loading,\n        onActivate,\n        onDeactivate,\n      },\n    },\n    getRowId: (row) => row.id,\n    enableRowSelection: deletePermitted,\n  })\n\n  const selectedRows = table.getSelectedRowModel().rows\n  const hasSelection = selectedRows.length > 0\n\n  const [pendingBulkAction, setPendingBulkAction] = useState<SnapshotBulkAction | null>(null)\n  const selectedSnapshots = selectedRows.map((row) => row.original)\n\n  const bulkActionCounts = useMemo(() => getSnapshotBulkActionCounts(selectedSnapshots), [selectedSnapshots])\n\n  const handleBulkActionConfirm = () => {\n    if (!pendingBulkAction) return\n\n    const handlers: Record<SnapshotBulkAction, () => void> = {\n      [SnapshotBulkAction.Delete]: () => {\n        if (onBulkDelete) {\n          onBulkDelete(selectedSnapshots.filter(isSnapshotDeletable))\n        }\n      },\n      [SnapshotBulkAction.Deactivate]: () => {\n        if (onBulkDeactivate) {\n          onBulkDeactivate(selectedSnapshots.filter(isSnapshotDeactivatable))\n        }\n      },\n    }\n\n    handlers[pendingBulkAction]()\n    setPendingBulkAction(null)\n    table.toggleAllRowsSelected(false)\n  }\n\n  const toggleAllRowsSelected = useCallback(\n    (selected: boolean) => {\n      if (selected) {\n        for (const row of table.getRowModel().rows) {\n          const isGeneral = row.original.general\n          const isLoading = loadingSnapshots[row.original.id]\n          const isRemoving = row.original.state === SnapshotState.REMOVING\n          if (!isGeneral && !isLoading && !isRemoving) {\n            row.toggleSelected(true)\n          }\n        }\n      } else {\n        table.toggleAllRowsSelected(false)\n      }\n    },\n    [table, loadingSnapshots],\n  )\n\n  useSnapshotsCommands({\n    writePermitted,\n    deletePermitted,\n    selectedCount: selectedRows.length,\n    totalCount: data.length,\n    selectableCount,\n    toggleAllRowsSelected,\n    bulkActionCounts,\n    onDelete: () => setPendingBulkAction(SnapshotBulkAction.Delete),\n    onDeactivate: () => setPendingBulkAction(SnapshotBulkAction.Deactivate),\n    onActivate: () => onBulkActivate?.(selectedSnapshots.filter(isSnapshotActivatable)),\n    onCreateSnapshot: onCreateSnapshot,\n  })\n\n  const { setIsOpen } = useCommandPaletteActions()\n  const handleOpenCommandPalette = () => {\n    setIsOpen(true)\n  }\n\n  return (\n    <div>\n      <div className=\"rounded-md border\">\n        <Table>\n          <TableHeader>\n            {table.getHeaderGroups().map((headerGroup) => (\n              <TableRow key={headerGroup.id}>\n                {headerGroup.headers.map((header) => {\n                  return (\n                    <TableHead\n                      key={header.id}\n                      className={cn('px-2', header.column.getCanSort() && 'hover:bg-muted cursor-pointer')}\n                    >\n                      {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}\n                    </TableHead>\n                  )\n                })}\n              </TableRow>\n            ))}\n          </TableHeader>\n          <TableBody>\n            {loading ? (\n              <>\n                {Array.from(new Array(10)).map((_, i) => (\n                  <TableRow key={i}>\n                    {table.getVisibleLeafColumns().map((column, i, arr) =>\n                      i === arr.length - 1 ? null : (\n                        <TableCell key={column.id}>\n                          <Skeleton className=\"h-4 w-10/12\" />\n                        </TableCell>\n                      ),\n                    )}\n                  </TableRow>\n                ))}\n              </>\n            ) : table.getRowModel().rows?.length ? (\n              table.getRowModel().rows.map((row) => (\n                <TableRow\n                  key={row.id}\n                  data-state={row.getIsSelected() ? 'selected' : undefined}\n                  className={`${\n                    loadingSnapshots[row.original.id] || row.original.state === SnapshotState.REMOVING\n                      ? 'opacity-50 pointer-events-none'\n                      : ''\n                  } ${row.original.general ? 'pointer-events-none' : ''}`}\n                >\n                  {row.getVisibleCells().map((cell) => (\n                    <TableCell className=\"px-2\" key={cell.id}>\n                      {flexRender(cell.column.columnDef.cell, cell.getContext())}\n                    </TableCell>\n                  ))}\n                </TableRow>\n              ))\n            ) : (\n              <TableEmptyState\n                colSpan={columns.length}\n                message=\"No Snapshots yet.\"\n                icon={<Box className=\"w-8 h-8\" />}\n                description={\n                  <div className=\"space-y-2\">\n                    <p>\n                      Snapshots are reproducible, pre-configured environments based on any Docker-compatible image. Use\n                      them to define language runtimes, dependencies, and tools for your sandboxes.\n                    </p>\n                    <p>\n                      Create one from the Dashboard, CLI, or SDK to get started. <br />\n                      <a\n                        href=\"https://www.daytona.io/docs/snapshots\"\n                        target=\"_blank\"\n                        rel=\"noopener noreferrer\"\n                        className=\"text-primary hover:underline font-medium\"\n                      >\n                        Read the Snapshots guide\n                      </a>{' '}\n                      to learn more.\n                    </p>\n                  </div>\n                }\n              />\n            )}\n          </TableBody>\n        </Table>\n      </div>\n      <Pagination\n        table={table}\n        selectionEnabled={deletePermitted}\n        entityName=\"Snapshots\"\n        totalItems={totalItems}\n        className=\"mt-4\"\n      />\n      <AnimatePresence>\n        {hasSelection && (\n          <SelectionToast\n            className=\"absolute bottom-5 left-1/2 -translate-x-1/2 z-50\"\n            selectedCount={selectedRows.length}\n            onClearSelection={() => table.resetRowSelection()}\n            onActionClick={handleOpenCommandPalette}\n          />\n        )}\n      </AnimatePresence>\n\n      <SnapshotBulkActionAlertDialog\n        action={pendingBulkAction}\n        count={\n          pendingBulkAction\n            ? {\n                [SnapshotBulkAction.Delete]: bulkActionCounts.deletable,\n                [SnapshotBulkAction.Deactivate]: bulkActionCounts.deactivatable,\n              }[pendingBulkAction]\n            : 0\n        }\n        onConfirm={handleBulkActionConfirm}\n        onCancel={() => setPendingBulkAction(null)}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/snapshots/SnapshotTable/columns.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport { getRelativeTimeString } from '@/lib/utils'\nimport { SnapshotDto, SnapshotState } from '@daytonaio/api-client'\nimport { ColumnDef, RowData, Table } from '@tanstack/react-table'\nimport { Loader2, MoreHorizontal } from 'lucide-react'\nimport React from 'react'\nimport { SortOrderIcon } from '../../SortIcon'\nimport { Badge, BadgeProps } from '../../ui/badge'\nimport { Button } from '../../ui/button'\nimport { Checkbox } from '../../ui/checkbox'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '../../ui/dropdown-menu'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'\n\ntype SnapshotTableMeta = {\n  writePermitted: boolean\n  deletePermitted: boolean\n  loadingSnapshots: Record<string, boolean>\n  getRegionName: (regionId: string) => string | undefined\n  onActivate?: (snapshot: SnapshotDto) => void\n  onDeactivate?: (snapshot: SnapshotDto) => void\n  onDelete: (snapshot: SnapshotDto) => void\n  loading: boolean\n  selectableCount: number\n}\n\ndeclare module '@tanstack/react-table' {\n  interface TableMeta<TData extends RowData> {\n    snapshot?: TData extends SnapshotDto ? SnapshotTableMeta : never\n  }\n}\n\ninterface SortableHeaderProps {\n  column: any\n  label: string\n}\n\nconst getMeta = (table: Table<SnapshotDto>) => {\n  return table.options.meta?.snapshot as SnapshotTableMeta\n}\n\nconst SortableHeader: React.FC<SortableHeaderProps> = ({ column, label }) => {\n  const sortDirection = column.getIsSorted()\n\n  return (\n    <button\n      type=\"button\"\n      onClick={() => column.toggleSorting(sortDirection === 'asc')}\n      className=\"group/sort-button flex items-center gap-2 w-full h-full\"\n    >\n      {label}\n      <SortOrderIcon sort={sortDirection || null} />\n    </button>\n  )\n}\n\nconst columns: ColumnDef<SnapshotDto>[] = [\n  {\n    id: 'select',\n    header: ({ table }) => {\n      const { deletePermitted, loading, selectableCount } = getMeta(table)\n\n      const selectedCount = table.getSelectedRowModel().rows.length\n      const anySelectable = selectableCount > 0\n      const allSelected = selectedCount > 0 && selectedCount === selectableCount\n      const partiallySelected = selectedCount > 0 && selectedCount < selectableCount\n\n      if (!deletePermitted || !anySelectable) {\n        return null\n      }\n\n      return (\n        <Checkbox\n          checked={allSelected || (partiallySelected && 'indeterminate')}\n          onCheckedChange={() => {\n            if (table)\n              table.getRowModel().rows.forEach((row) => {\n                if (row.original.general) {\n                  return\n                }\n                if (allSelected) {\n                  row.toggleSelected(false)\n                } else {\n                  row.toggleSelected(true)\n                }\n              })\n          }}\n          aria-label=\"Select all\"\n          disabled={!deletePermitted || loading}\n          className=\"translate-y-[2px]\"\n        />\n      )\n    },\n    cell: ({ row, table }) => {\n      const { deletePermitted, loadingSnapshots, loading } = getMeta(table)\n\n      if (!deletePermitted || row.original.general) {\n        return null\n      }\n\n      if (loadingSnapshots[row.original.id]) {\n        return <Loader2 className=\"w-4 h-4 animate-spin\" />\n      }\n\n      return (\n        <Checkbox\n          checked={row.getIsSelected()}\n          onCheckedChange={(value) => row.toggleSelected(!!value)}\n          aria-label=\"Select row\"\n          disabled={!deletePermitted || loadingSnapshots[row.original.id] || loading}\n          className=\"translate-y-[2px]\"\n        />\n      )\n    },\n    enableSorting: false,\n    enableHiding: false,\n  },\n  {\n    accessorKey: 'name',\n    enableSorting: true,\n    header: ({ column }) => <SortableHeader column={column} label=\"Name\" />,\n    cell: ({ row }) => {\n      const snapshot = row.original\n      return (\n        <div className=\"flex items-center gap-2\">\n          {snapshot.name}\n          {snapshot.general && <Badge variant=\"secondary\">System</Badge>}\n        </div>\n      )\n    },\n  },\n  {\n    accessorKey: 'imageName',\n    enableSorting: false,\n    header: 'Image',\n    cell: ({ row }) => {\n      const snapshot = row.original\n      if (!snapshot.imageName && snapshot.buildInfo) {\n        return (\n          <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-medium\">\n            DECLARATIVE BUILD\n          </Badge>\n        )\n      }\n      return snapshot.imageName\n    },\n  },\n  {\n    accessorKey: 'regionIds',\n    enableSorting: false,\n    header: 'Region',\n    cell: ({ row, table }) => {\n      const { getRegionName } = getMeta(table)\n      const snapshot = row.original\n      if (!snapshot.regionIds?.length) {\n        return '-'\n      }\n\n      const regionNames = snapshot.regionIds.map((id) => getRegionName(id) ?? id)\n      const firstRegion = regionNames[0]\n      const remainingCount = regionNames.length - 1\n\n      if (remainingCount === 0) {\n        return (\n          <span className=\"truncate max-w-[150px] block\" title={firstRegion}>\n            {firstRegion}\n          </span>\n        )\n      }\n\n      return (\n        <Tooltip>\n          <TooltipTrigger asChild>\n            <div className=\"flex items-center gap-1.5\">\n              <span className=\"truncate max-w-[150px]\">{firstRegion}</span>\n              <Badge variant=\"secondary\" className=\"text-xs px-1.5 py-0 h-5\">\n                +{remainingCount}\n              </Badge>\n            </div>\n          </TooltipTrigger>\n          <TooltipContent>\n            <div className=\"flex flex-col gap-1\">\n              {regionNames.map((name, idx) => (\n                <span key={idx}>{name}</span>\n              ))}\n            </div>\n          </TooltipContent>\n        </Tooltip>\n      )\n    },\n  },\n  {\n    id: 'resources',\n    enableSorting: false,\n    header: 'Resources',\n    cell: ({ row }) => {\n      const snapshot = row.original\n\n      return (\n        <div className=\"flex items-center gap-2 w-full truncate\">\n          <div className=\"whitespace-nowrap\">\n            {snapshot.cpu} <span className=\"text-muted-foreground\">vCPU</span>\n          </div>\n          <div className=\"w-[1px] h-6 bg-muted-foreground/20 rounded-full inline-block\"></div>\n          <div className=\"whitespace-nowrap\">\n            {snapshot.mem} <span className=\"text-muted-foreground\">GiB</span>\n          </div>\n          <div className=\"w-[1px] h-6 bg-muted-foreground/20 rounded-full inline-block\"></div>\n          <div className=\"whitespace-nowrap\">\n            {snapshot.disk} <span className=\"text-muted-foreground\">GiB</span>\n          </div>\n        </div>\n      )\n    },\n  },\n  {\n    accessorKey: 'state',\n    enableSorting: true,\n    header: ({ column }) => <SortableHeader column={column} label=\"State\" />,\n    cell: ({ row }) => {\n      const snapshot = row.original\n      const variant = getStateBadgeVariant(snapshot.state)\n\n      if (\n        (snapshot.state === SnapshotState.ERROR || snapshot.state === SnapshotState.BUILD_FAILED) &&\n        !!snapshot.errorReason\n      ) {\n        return (\n          <Tooltip>\n            <TooltipTrigger>\n              <Badge variant={variant}>{getStateLabel(snapshot.state)}</Badge>\n            </TooltipTrigger>\n            <TooltipContent>\n              <p className=\"max-w-[300px]\">{snapshot.errorReason}</p>\n            </TooltipContent>\n          </Tooltip>\n        )\n      }\n\n      return <Badge variant={variant}>{getStateLabel(snapshot.state)}</Badge>\n    },\n  },\n  {\n    accessorKey: 'createdAt',\n    enableSorting: true,\n    header: ({ column }) => <SortableHeader column={column} label=\"Created\" />,\n    cell: ({ row }) => {\n      const snapshot = row.original\n      if (snapshot.general) {\n        return <span className=\"text-muted-foreground\">-</span>\n      }\n\n      const timestamp = getRelativeTimeString(snapshot.createdAt)\n\n      return (\n        <TimestampTooltip timestamp={snapshot.createdAt.toString()}>{timestamp.relativeTimeString}</TimestampTooltip>\n      )\n    },\n  },\n  {\n    accessorKey: 'lastUsedAt',\n    enableSorting: true,\n    header: ({ column }) => <SortableHeader column={column} label=\"Last Used\" />,\n    cell: ({ row }) => {\n      const snapshot = row.original\n      if (snapshot.general || !snapshot.lastUsedAt) {\n        return <span className=\"text-muted-foreground\">-</span>\n      }\n\n      const timestamp = getRelativeTimeString(snapshot.lastUsedAt)\n\n      return (\n        <TimestampTooltip timestamp={snapshot.lastUsedAt.toString()}>{timestamp.relativeTimeString}</TimestampTooltip>\n      )\n    },\n  },\n  {\n    id: 'actions',\n    cell: ({ row, table }) => {\n      const { writePermitted, deletePermitted, loadingSnapshots, onActivate, onDeactivate, onDelete } = getMeta(table)\n\n      if ((!writePermitted && !deletePermitted) || row.original.general) {\n        return null\n      }\n\n      const showActivate = writePermitted && onActivate && row.original.state === SnapshotState.INACTIVE\n      const showDeactivate = writePermitted && onDeactivate && row.original.state === SnapshotState.ACTIVE\n      const showDelete = deletePermitted\n\n      const showSeparator = (showActivate || showDeactivate) && showDelete\n\n      return (\n        <DropdownMenu>\n          <DropdownMenuTrigger asChild>\n            <Button variant=\"ghost\" className=\"h-8 w-8 p-0\">\n              <span className=\"sr-only\">Open menu</span>\n              <MoreHorizontal className=\"h-4 w-4\" />\n            </Button>\n          </DropdownMenuTrigger>\n          <DropdownMenuContent align=\"end\">\n            {showActivate && (\n              <DropdownMenuItem onClick={() => onActivate(row.original)} disabled={loadingSnapshots[row.original.id]}>\n                Activate\n              </DropdownMenuItem>\n            )}\n            {showDeactivate && (\n              <DropdownMenuItem onClick={() => onDeactivate(row.original)} disabled={loadingSnapshots[row.original.id]}>\n                Deactivate\n              </DropdownMenuItem>\n            )}\n            {showSeparator && <DropdownMenuSeparator />}\n            {showDelete && (\n              <DropdownMenuItem\n                onClick={() => onDelete(row.original)}\n                variant=\"destructive\"\n                disabled={loadingSnapshots[row.original.id]}\n              >\n                Delete\n              </DropdownMenuItem>\n            )}\n          </DropdownMenuContent>\n        </DropdownMenu>\n      )\n    },\n  },\n]\n\nconst getStateBadgeVariant = (state: SnapshotState): BadgeProps['variant'] => {\n  switch (state) {\n    case SnapshotState.ACTIVE:\n      return 'success'\n    case SnapshotState.INACTIVE:\n      return 'secondary'\n    case SnapshotState.ERROR:\n    case SnapshotState.BUILD_FAILED:\n      return 'destructive'\n    default:\n      return 'secondary'\n  }\n}\n\nconst getStateLabel = (state: SnapshotState) => {\n  if (state === SnapshotState.REMOVING) {\n    return 'Deleting'\n  }\n  return state\n    .split('_')\n    .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n    .join(' ')\n}\n\nexport { columns }\nexport type { SnapshotTableMeta }\n"
  },
  {
    "path": "apps/dashboard/src/components/snapshots/SnapshotTable/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport { SnapshotTable } from './SnapshotTable'\nexport { useSnapshotsCommands, getSnapshotBulkActionCounts } from './useSnapshotsCommands'\nexport type { SnapshotBulkActionCounts } from './useSnapshotsCommands'\nexport { SnapshotBulkAction, SnapshotBulkActionAlertDialog } from './BulkActionAlertDialog'\n"
  },
  {
    "path": "apps/dashboard/src/components/snapshots/SnapshotTable/useSnapshotsCommands.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { pluralize } from '@/lib/utils'\nimport { SnapshotDto, SnapshotState } from '@daytonaio/api-client'\nimport { CheckSquare2Icon, MinusSquareIcon, PauseIcon, PlayIcon, PlusIcon, TrashIcon } from 'lucide-react'\nimport { useMemo } from 'react'\nimport { CommandConfig, useRegisterCommands } from '../../CommandPalette'\n\nexport interface SnapshotBulkActionCounts {\n  deletable: number\n  deactivatable: number\n  activatable: number\n}\n\nexport function isSnapshotDeletable(snapshot: SnapshotDto): boolean {\n  return snapshot.state !== SnapshotState.REMOVING\n}\n\nexport function isSnapshotDeactivatable(snapshot: SnapshotDto): boolean {\n  return snapshot.state === SnapshotState.ACTIVE\n}\n\nexport function isSnapshotActivatable(snapshot: SnapshotDto): boolean {\n  return snapshot.state === SnapshotState.INACTIVE\n}\n\nexport function getSnapshotBulkActionCounts(snapshots: SnapshotDto[]): SnapshotBulkActionCounts {\n  return {\n    deletable: snapshots.filter(isSnapshotDeletable).length,\n    deactivatable: snapshots.filter(isSnapshotDeactivatable).length,\n    activatable: snapshots.filter(isSnapshotActivatable).length,\n  }\n}\n\ninterface UseSnapshotsCommandsProps {\n  writePermitted: boolean\n  deletePermitted: boolean\n  selectedCount: number\n  totalCount: number\n  selectableCount: number\n  toggleAllRowsSelected: (selected: boolean) => void\n  bulkActionCounts: SnapshotBulkActionCounts\n  onDelete: () => void\n  onDeactivate: () => void\n  onActivate: () => void\n  onCreateSnapshot?: () => void\n}\n\nexport function useSnapshotsCommands({\n  writePermitted,\n  deletePermitted,\n  selectedCount,\n  selectableCount,\n  toggleAllRowsSelected,\n  bulkActionCounts,\n  onDelete,\n  onActivate,\n  onDeactivate,\n  onCreateSnapshot,\n}: UseSnapshotsCommandsProps) {\n  const rootCommands: CommandConfig[] = useMemo(() => {\n    const commands: CommandConfig[] = []\n\n    if (writePermitted && onCreateSnapshot) {\n      commands.push({\n        id: 'create-snapshot',\n        label: 'Create Snapshot',\n        icon: <PlusIcon className=\"w-4 h-4\" />,\n        onSelect: onCreateSnapshot,\n      })\n    }\n\n    if (selectableCount !== selectedCount) {\n      commands.push({\n        id: 'select-all-snapshots',\n        label: 'Select All Snapshots',\n        icon: <CheckSquare2Icon className=\"w-4 h-4\" />,\n        onSelect: () => toggleAllRowsSelected(true),\n        chainable: true,\n      })\n    }\n\n    if (selectedCount > 0) {\n      commands.push({\n        id: 'deselect-all-snapshots',\n        label: 'Deselect All Snapshots',\n        icon: <MinusSquareIcon className=\"w-4 h-4\" />,\n        onSelect: () => toggleAllRowsSelected(false),\n        chainable: true,\n      })\n    }\n\n    if (writePermitted && bulkActionCounts.deactivatable > 0) {\n      commands.push({\n        id: 'deactivate-snapshots',\n        label: `Deactivate ${pluralize(bulkActionCounts.deactivatable, 'Snapshot', 'Snapshots')}`,\n        icon: <PauseIcon className=\"w-4 h-4\" />,\n        onSelect: onDeactivate,\n      })\n    }\n\n    if (writePermitted && bulkActionCounts.activatable > 0) {\n      commands.push({\n        id: 'activate-snapshots',\n        label: `Activate ${pluralize(bulkActionCounts.activatable, 'Snapshot', 'Snapshots')}`,\n        icon: <PlayIcon className=\"w-4 h-4\" />,\n        onSelect: onActivate,\n      })\n    }\n\n    if (deletePermitted && bulkActionCounts.deletable > 0) {\n      commands.push({\n        id: 'delete-snapshots',\n        label: `Delete ${pluralize(bulkActionCounts.deletable, 'Snapshot', 'Snapshots')}`,\n        icon: <TrashIcon className=\"w-4 h-4\" />,\n        onSelect: onDelete,\n      })\n    }\n\n    return commands\n  }, [\n    writePermitted,\n    deletePermitted,\n    selectedCount,\n    selectableCount,\n    toggleAllRowsSelected,\n    bulkActionCounts,\n    onDelete,\n    onDeactivate,\n    onActivate,\n    onCreateSnapshot,\n  ])\n\n  useRegisterCommands(rootCommands, { groupId: 'snapshot-actions', groupLabel: 'Snapshot actions', groupOrder: 0 })\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/snapshots/SnapshotTable/utils.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DEFAULT_SNAPSHOT_SORTING, SnapshotSorting } from '@/hooks/queries/useSnapshotsQuery'\nimport { GetAllSnapshotsOrderEnum, GetAllSnapshotsSortEnum } from '@daytonaio/api-client'\nimport { SortingState } from '@tanstack/react-table'\n\nexport const convertApiSortingToTableSorting = (sorting: SnapshotSorting): SortingState => {\n  let id: string\n  switch (sorting.field) {\n    case GetAllSnapshotsSortEnum.NAME:\n      id = 'name'\n      break\n    case GetAllSnapshotsSortEnum.STATE:\n      id = 'state'\n      break\n    case GetAllSnapshotsSortEnum.CREATED_AT:\n      id = 'createdAt'\n      break\n    case GetAllSnapshotsSortEnum.LAST_USED_AT:\n    default:\n      id = 'lastUsedAt'\n      break\n  }\n\n  return [{ id, desc: sorting.direction === GetAllSnapshotsOrderEnum.DESC }]\n}\n\nexport const convertTableSortingToApiSorting = (sorting: SortingState): SnapshotSorting => {\n  if (!sorting.length) {\n    return DEFAULT_SNAPSHOT_SORTING\n  }\n\n  const sort = sorting[0]\n  let field: GetAllSnapshotsSortEnum\n\n  switch (sort.id) {\n    case 'name':\n      field = GetAllSnapshotsSortEnum.NAME\n      break\n    case 'state':\n      field = GetAllSnapshotsSortEnum.STATE\n      break\n    case 'createdAt':\n      field = GetAllSnapshotsSortEnum.CREATED_AT\n      break\n    case 'lastUsedAt':\n    default:\n      field = GetAllSnapshotsSortEnum.LAST_USED_AT\n      break\n  }\n\n  return {\n    field,\n    direction: sort.desc ? GetAllSnapshotsOrderEnum.DESC : GetAllSnapshotsOrderEnum.ASC,\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/spending/AggregatedUsageChart.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { cn } from '@/lib/utils'\nimport { ModelsAggregatedUsage } from '@daytonaio/analytics-api-client'\nimport NumberFlow from '@number-flow/react'\nimport { motion } from 'framer-motion'\nimport React from 'react'\n\ninterface AggregatedUsageChartProps {\n  data: ModelsAggregatedUsage | undefined\n  isLoading: boolean\n}\n\nfunction formatSeconds(seconds: number): { value: number; suffix: string } {\n  if (seconds < 60) return { value: Math.round(seconds * 10) / 10, suffix: ' s' }\n  if (seconds < 3600) return { value: Math.round((seconds / 60) * 10) / 10, suffix: ' m' }\n  return { value: Math.round((seconds / 3600) * 10) / 10, suffix: ' h' }\n}\n\nfunction formatGBSeconds(gbSeconds: number): { value: number; suffix: string } {\n  if (gbSeconds < 3600) return { value: Math.round(gbSeconds * 10) / 10, suffix: ' GB-s' }\n  return { value: Math.round((gbSeconds / 3600) * 10) / 10, suffix: ' GB-h' }\n}\n\nconst transition = {\n  type: 'spring',\n  stiffness: 60,\n  damping: 15,\n  mass: 1,\n} as const\n\nconst SEGMENTS = [\n  { key: 'cpu' as const, label: 'CPU', color: 'bg-[hsl(var(--chart-1))]' },\n  { key: 'ram' as const, label: 'RAM', color: 'bg-[hsl(var(--chart-2))]' },\n  { key: 'disk' as const, label: 'Disk', color: 'bg-[hsl(var(--chart-3))]' },\n]\n\nexport const UsageSummary: React.FC<AggregatedUsageChartProps> = ({ data, isLoading }) => {\n  const totalPrice = data?.totalPrice ?? 0\n  const sandboxCount = data?.sandboxCount ?? 0\n\n  return (\n    <div className=\"flex gap-4 sm:gap-12 sm:flex-row flex-col p-4\">\n      <div className=\"flex flex-col gap-1\">\n        <div>Total Cost</div>\n        <div className=\"relative\">\n          <div className={cn('text-2xl font-semibold', isLoading && 'invisible')}>\n            $\n            <NumberFlow\n              value={Math.round(totalPrice * 100) / 100}\n              format={{ minimumFractionDigits: 2, maximumFractionDigits: 2 }}\n            />\n          </div>\n          {isLoading && <Skeleton className=\"absolute inset-y-1 left-0 w-24\" />}\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-1\">\n        <div>Sandboxes</div>\n        <div className=\"relative\">\n          <div className={cn('text-2xl font-semibold', isLoading && 'invisible')}>\n            <NumberFlow value={sandboxCount} />\n          </div>\n          {isLoading && <Skeleton className=\"absolute inset-y-1 left-0 w-14\" />}\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport const AggregatedUsageChart: React.FC<AggregatedUsageChartProps> = ({ data, isLoading }) => {\n  const cpuSeconds = data?.totalCPUSeconds ?? 0\n  const ramGBSeconds = data?.totalRAMGBSeconds ?? 0\n  const diskGBSeconds = data?.totalDiskGBSeconds ?? 0\n\n  const cpu = formatSeconds(cpuSeconds)\n  const ram = formatGBSeconds(ramGBSeconds)\n  const disk = formatGBSeconds(diskGBSeconds)\n\n  return (\n    <div className=\"overflow-hidden\">\n      <div className=\"grid grid-cols-1 sm:grid-cols-3 -mr-px -mb-px\">\n        <StatItem label=\"CPU\" suffix={cpu.suffix} isLoading={isLoading}>\n          <NumberFlow value={cpu.value} format={{ minimumFractionDigits: 1, maximumFractionDigits: 1 }} />\n        </StatItem>\n        <StatItem label=\"RAM\" suffix={ram.suffix} isLoading={isLoading}>\n          <NumberFlow value={ram.value} format={{ minimumFractionDigits: 1, maximumFractionDigits: 1 }} />\n        </StatItem>\n        <StatItem label=\"Disk\" suffix={disk.suffix} isLoading={isLoading}>\n          <NumberFlow value={disk.value} format={{ minimumFractionDigits: 1, maximumFractionDigits: 1 }} />\n        </StatItem>\n      </div>\n    </div>\n  )\n}\n\nfunction StatItem({\n  label,\n  suffix,\n  children,\n  isLoading,\n}: {\n  label: string\n  suffix?: string\n  children: React.ReactNode\n  isLoading?: boolean\n}) {\n  return (\n    <div className=\"px-4 py-2 sm:p-4 border-b border-r border-border flex items-center gap-2 sm:block\">\n      <p className=\"text-sm text-muted-foreground\">{label}</p>\n      <div className=\"relative\">\n        <p className={cn('text-xl font-semibold', isLoading && 'invisible')}>\n          {children}\n          {suffix && <span className=\"text-base font-medium text-muted-foreground\">{suffix}</span>}\n        </p>\n        {isLoading && <Skeleton className=\"absolute top-1 h-5 w-16\" />}\n      </div>\n    </div>\n  )\n}\n\nexport const ResourceUsageBreakdown: React.FC<{ data: ModelsAggregatedUsage | undefined }> = ({ data }) => {\n  const cpuSeconds = data?.totalCPUSeconds ?? 0\n  const ramGBSeconds = data?.totalRAMGBSeconds ?? 0\n  const diskGBSeconds = data?.totalDiskGBSeconds ?? 0\n\n  const segmentValues = {\n    cpu: cpuSeconds,\n    ram: ramGBSeconds,\n    disk: diskGBSeconds,\n  }\n  const total = cpuSeconds + ramGBSeconds + diskGBSeconds\n\n  return (\n    <div className=\"flex flex-col gap-4 p-4\">\n      <p className=\"text-xl font-semibold leading-none tracking-tight\">Resource Breakdown</p>\n      <div className=\"flex flex-col gap-2\">\n        <div className=\"w-full h-2 bg-muted rounded-full overflow-clip flex\">\n          {total === 0\n            ? null\n            : SEGMENTS.map(({ key, color }) => {\n                const value = segmentValues[key]\n                if (value === 0) return null\n                const pct = (value / total) * 100\n                return (\n                  <motion.div\n                    key={key}\n                    className={cn('h-full', color)}\n                    initial={{ width: 0 }}\n                    animate={{ width: `${pct}%` }}\n                    transition={transition}\n                  />\n                )\n              })}\n        </div>\n        <div className=\"flex items-center gap-4 flex-wrap\">\n          {SEGMENTS.map(({ key, label, color }) => (\n            <div key={key} className=\"flex items-center gap-1.5 text-xs\">\n              <div className={cn('w-2 h-2 rounded-full', color)} />\n              <span>\n                {label} {total > 0 ? `${Math.round((segmentValues[key] / total) * 100)}%` : '0%'}\n              </span>\n            </div>\n          ))}\n        </div>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/spending/CostBreakdown.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Spinner } from '@/components/ui/spinner'\nimport { subMonths } from 'date-fns'\nimport { AlertCircle, BarChart3, RefreshCw } from 'lucide-react'\nimport * as React from 'react'\nimport { useCallback, useMemo } from 'react'\nimport { FacetFilter } from '../ui/facet-filter'\nimport { ResourceUsageChart, UsageChartData } from './ResourceUsageChart'\n\ntype CostBreakdownProps = {\n  usageData: UsageChartData[]\n  showTotal?: boolean\n  isLoading?: boolean\n  isError?: boolean\n  onRetry?: () => void\n}\n\nexport function CostBreakdown({ usageData, showTotal, isLoading, isError, onRetry }: CostBreakdownProps) {\n  const [timeRange, setTimeRange] = React.useState(12)\n  const [chartType, setChartType] = React.useState<'bar' | 'area'>('bar')\n  const [filters, setFilters] = React.useState<Set<string>>(new Set(['ramGB', 'cpu', 'diskGB']))\n\n  const filterFromObject = useCallback(\n    (obj: any) => {\n      return Object.fromEntries(Object.entries(obj).filter(([key]) => key === 'date' || filters.has(key)))\n    },\n    [filters],\n  )\n\n  const data = useMemo(() => {\n    const referenceDate = new Date()\n\n    let monthsToSubtract = 12\n    if (timeRange === 6) {\n      monthsToSubtract = 6\n    } else if (timeRange === 3) {\n      monthsToSubtract = 3\n    }\n    const startDate = subMonths(new Date(referenceDate), monthsToSubtract)\n\n    const filteredData = usageData.filter((usage) => {\n      const date = new Date(usage.date)\n      return date >= startDate\n    })\n\n    if (filteredData.length < timeRange) {\n      const missingData: UsageChartData[] = []\n      for (let i = 0; i < timeRange - filteredData.length; i++) {\n        const refDate = filteredData.length > 0 ? filteredData[0].date : new Date()\n        missingData.push({\n          date: subMonths(new Date(refDate), i + 1).toISOString(),\n          diskGB: 0,\n          ramGB: 0,\n          cpu: 0,\n        })\n      }\n      return [...missingData.reverse(), ...filteredData].map(filterFromObject)\n    }\n\n    return filteredData.map(filterFromObject)\n  }, [usageData, timeRange, filterFromObject])\n\n  const chartConfig = useMemo(() => {\n    const mapped: Record<string, { label: string; color: string }> = {\n      cpu: {\n        label: 'CPU',\n        color: 'hsl(var(--chart-1))',\n      },\n      ramGB: {\n        label: 'RAM',\n        color: 'hsl(var(--chart-2))',\n      },\n      diskGB: {\n        label: 'Disk',\n        color: 'hsl(var(--chart-3))',\n      },\n    }\n\n    return filterFromObject(mapped) as Record<string, { label: string; color: string }>\n  }, [filterFromObject])\n\n  const noData = !isLoading && usageData.length === 0\n\n  return (\n    <Card>\n      <CardHeader className=\"flex flex-col sm:flex-row sm:items-center gap-2 space-y-0 border-b p-4\">\n        <div className=\"flex-1\">\n          <CardTitle>Monthly Cost Breakdown</CardTitle>\n        </div>\n        <div className=\"flex items-center gap-2 flex-wrap\">\n          <FacetFilter\n            title=\"Filters\"\n            className=\"h-8 pr-1\"\n            options={[\n              { label: 'CPU', value: 'cpu' },\n              { label: 'RAM', value: 'ramGB' },\n              { label: 'Disk', value: 'diskGB' },\n            ]}\n            selectedValues={filters}\n            setSelectedValues={setFilters}\n          />\n          <Select value={chartType} onValueChange={(value) => setChartType(value as 'bar' | 'area')}>\n            <SelectTrigger size=\"sm\" className=\"w-[80px] rounded-lg\" aria-label=\"Select a chart type\">\n              <SelectValue placeholder=\"Bar\" />\n            </SelectTrigger>\n            <SelectContent className=\"rounded-xl\">\n              <SelectItem value=\"bar\">Bar</SelectItem>\n              <SelectItem value=\"area\">Area</SelectItem>\n            </SelectContent>\n          </Select>\n          <Select value={timeRange.toString()} onValueChange={(value) => setTimeRange(Number(value))}>\n            <SelectTrigger size=\"sm\" className=\"w-[150px] rounded-lg\" aria-label=\"Select the range of months\">\n              <SelectValue placeholder=\"Last 12 months\" />\n            </SelectTrigger>\n            <SelectContent className=\"rounded-xl\">\n              <SelectItem value=\"12\">Last 12 months</SelectItem>\n              <SelectItem value=\"6\">Last 6 months</SelectItem>\n              <SelectItem value=\"3\">Last 3 months</SelectItem>\n            </SelectContent>\n          </Select>\n        </div>\n      </CardHeader>\n      {isError ? (\n        <Empty className=\"py-12\">\n          <EmptyHeader>\n            <EmptyMedia variant=\"icon\" className=\"bg-destructive-background text-destructive\">\n              <AlertCircle />\n            </EmptyMedia>\n            <EmptyTitle className=\"text-destructive\">Failed to load billing data</EmptyTitle>\n            <EmptyDescription>Something went wrong while fetching billing data. Please try again.</EmptyDescription>\n          </EmptyHeader>\n          {onRetry && (\n            <EmptyContent>\n              <Button variant=\"secondary\" size=\"sm\" onClick={onRetry}>\n                <RefreshCw />\n                Retry\n              </Button>\n            </EmptyContent>\n          )}\n        </Empty>\n      ) : noData ? (\n        <Empty className=\"py-12\">\n          <EmptyHeader>\n            <EmptyMedia variant=\"icon\">\n              <BarChart3 />\n            </EmptyMedia>\n            <EmptyTitle>No billing data yet</EmptyTitle>\n            <EmptyDescription>\n              Monthly cost data will show up here once your organization has usage to report.\n            </EmptyDescription>\n          </EmptyHeader>\n        </Empty>\n      ) : (\n        <CardContent className=\"relative px-2 pt-4 sm:px-6 sm:pt-6\">\n          {isLoading && (\n            <div className=\"absolute inset-0 z-10 flex items-center justify-center backdrop-grayscale backdrop-blur-[2px]\">\n              <Spinner className=\"size-6\" />\n            </div>\n          )}\n          <ResourceUsageChart data={data} chartConfig={chartConfig} chartType={chartType} showTotal={showTotal} />\n        </CardContent>\n      )}\n    </Card>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/spending/ResourceUsageChart.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  ChartConfig,\n  ChartContainer,\n  ChartLegend,\n  ChartLegendContent,\n  ChartTooltip,\n  ChartTooltipContent,\n} from '@/components/ui/chart'\nimport { formatMoney } from '@/lib/utils'\nimport { Area, AreaChart, Bar, BarChart, CartesianGrid, XAxis, YAxis } from 'recharts'\n\nexport type UsageChartData = {\n  date: string\n  ramGB: number\n  cpu: number\n  diskGB: number\n  // gpu: number\n}\n\ntype UsageChartProps = {\n  data: Record<string, unknown>[]\n  chartConfig: Record<string, { label: string; color: string }>\n  chartType: 'bar' | 'area'\n  showTotal?: boolean\n}\n\nconst getShortDate = (value: string) => {\n  const date = new Date(value)\n  return date.toLocaleDateString('en-US', {\n    month: 'short',\n    year: 'numeric',\n  })\n}\n\nexport function ResourceUsageChart({ data, chartConfig, chartType, showTotal }: UsageChartProps) {\n  if (chartType === 'bar') {\n    return (\n      <ChartContainer config={chartConfig as ChartConfig} className=\"aspect-auto h-[300px] w-full\">\n        <BarChart accessibilityLayer data={data}>\n          <CartesianGrid vertical={false} />\n          <XAxis dataKey=\"date\" tickLine={false} tickMargin={10} axisLine={false} tickFormatter={getShortDate} />\n          <YAxis\n            tickLine={false}\n            axisLine={false}\n            tickMargin={4}\n            tickCount={4}\n            width={45}\n            tickFormatter={(value) => formatMoney(value)}\n          />\n          <ChartTooltip\n            cursor={false}\n            content={\n              <ChartTooltipContent\n                indicator=\"dot\"\n                hideLabel={!showTotal}\n                labelFormatter={(label, payload) => {\n                  return `${getShortDate(label)}: ${formatMoney(payload.reduce((acc, curr) => acc + (curr.value as number), 0))}`\n                }}\n              />\n            }\n          />\n          <ChartLegend content={<ChartLegendContent />} />\n          <Bar dataKey=\"cpu\" stackId=\"a\" fill=\"var(--color-cpu)\" radius={[0, 0, 0, 0]} />\n          <Bar dataKey=\"ramGB\" stackId=\"a\" fill=\"var(--color-ramGB)\" radius={[0, 0, 0, 0]} />\n          <Bar dataKey=\"diskGB\" stackId=\"a\" fill=\"var(--color-diskGB)\" radius={[4, 4, 0, 0]} />\n        </BarChart>\n      </ChartContainer>\n    )\n  }\n\n  return (\n    <ChartContainer config={chartConfig as ChartConfig} className=\"aspect-auto h-[300px] w-full\">\n      <AreaChart data={data}>\n        <defs>\n          <linearGradient id=\"fillDiskGB\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n            <stop offset=\"5%\" stopColor=\"var(--color-diskGB)\" stopOpacity={0.8} />\n            <stop offset=\"95%\" stopColor=\"var(--color-diskGB)\" stopOpacity={0.1} />\n          </linearGradient>\n          <linearGradient id=\"fillRamGB\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n            <stop offset=\"5%\" stopColor=\"var(--color-ramGB)\" stopOpacity={0.8} />\n            <stop offset=\"95%\" stopColor=\"var(--color-ramGB)\" stopOpacity={0.1} />\n          </linearGradient>\n          <linearGradient id=\"fillCpu\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n            <stop offset=\"5%\" stopColor=\"var(--color-cpu)\" stopOpacity={0.8} />\n            <stop offset=\"95%\" stopColor=\"var(--color-cpu)\" stopOpacity={0.1} />\n          </linearGradient>\n        </defs>\n        <CartesianGrid vertical={false} />\n        <XAxis\n          dataKey=\"date\"\n          tickLine={false}\n          axisLine={false}\n          tickMargin={8}\n          minTickGap={32}\n          tickFormatter={getShortDate}\n        />\n        <YAxis\n          tickLine={false}\n          axisLine={false}\n          tickMargin={4}\n          tickCount={4}\n          width={45}\n          tickFormatter={(value) => formatMoney(value)}\n        />\n        <ChartTooltip\n          cursor={false}\n          content={\n            <ChartTooltipContent\n              indicator=\"dot\"\n              hideLabel={!showTotal}\n              labelFormatter={(label, payload) => {\n                return `${getShortDate(label)}: ${formatMoney(payload.reduce((acc, curr) => acc + (curr.value as number), 0))}`\n              }}\n            />\n          }\n        />\n        <Area dataKey=\"diskGB\" type=\"monotoneX\" fill=\"url(#fillDiskGB)\" stroke=\"var(--color-diskGB)\" stackId=\"a\" />\n        <Area dataKey=\"ramGB\" type=\"monotoneX\" fill=\"url(#fillRamGB)\" stroke=\"var(--color-ramGB)\" stackId=\"a\" />\n        <Area dataKey=\"cpu\" type=\"monotoneX\" fill=\"url(#fillCpu)\" stroke=\"var(--color-cpu)\" stackId=\"a\" />\n        <ChartLegend content={<ChartLegendContent />} />\n      </AreaChart>\n    </ChartContainer>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/spending/SandboxSpendingTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useCallback } from 'react'\nimport { useSandboxUsagePeriods, AnalyticsUsageParams } from '@/hooks/queries/useAnalyticsUsage'\nimport { TimeRangeSelector } from '@/components/telemetry/TimeRangeSelector'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { Spinner } from '@/components/ui/spinner'\nimport { RefreshCw, DollarSign } from 'lucide-react'\nimport { format, subHours } from 'date-fns'\n\nfunction formatPrice(price: number): string {\n  if (price >= 0.01) return `$${price.toFixed(2)}`\n  if (price === 0) return '$0.00'\n  return `$${parseFloat(price.toPrecision(2))}`\n}\n\ninterface SandboxSpendingTabProps {\n  sandboxId: string\n}\n\nexport const SandboxSpendingTab: React.FC<SandboxSpendingTabProps> = ({ sandboxId }) => {\n  const [timeRange, setTimeRange] = useState(() => {\n    const now = new Date()\n    return { from: subHours(now, 24), to: now }\n  })\n\n  const queryParams: AnalyticsUsageParams = {\n    from: timeRange.from,\n    to: timeRange.to,\n  }\n\n  const { data, isLoading, refetch } = useSandboxUsagePeriods(sandboxId, queryParams)\n\n  const handleTimeRangeChange = useCallback((from: Date, to: Date) => {\n    setTimeRange({ from, to })\n  }, [])\n\n  const defaultRange = { from: timeRange.from, to: timeRange.to }\n\n  return (\n    <div className=\"flex flex-col h-full gap-4 p-4\">\n      <div className=\"flex flex-wrap items-center gap-3\">\n        <TimeRangeSelector\n          onChange={handleTimeRangeChange}\n          defaultRange={defaultRange}\n          defaultSelectedQuickRange=\"Last 24 hours\"\n          className=\"w-auto\"\n        />\n\n        <Button variant=\"outline\" size=\"icon\" onClick={() => refetch()}>\n          <RefreshCw className=\"h-4 w-4\" />\n        </Button>\n      </div>\n\n      <div className=\"flex-1 overflow-y-auto\">\n        {isLoading ? (\n          <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n            <Spinner className=\"w-6 h-6\" />\n          </div>\n        ) : !data?.length ? (\n          <div className=\"flex flex-col items-center justify-center h-full min-h-[400px] text-muted-foreground gap-2\">\n            <DollarSign className=\"w-8 h-8\" />\n            <span className=\"text-sm\">No usage periods found</span>\n          </div>\n        ) : (\n          <Table>\n            <TableHeader>\n              <TableRow>\n                <TableHead>Start</TableHead>\n                <TableHead>End</TableHead>\n                <TableHead className=\"text-right\">CPU</TableHead>\n                <TableHead className=\"text-right\">RAM (GB)</TableHead>\n                <TableHead className=\"text-right\">Disk (GB)</TableHead>\n                <TableHead className=\"text-right\">Price</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {data.map((period) => {\n                const rowKey = `${period.startAt ?? 'unknown-start'}-${period.endAt ?? 'unknown-end'}`\n                return (\n                  <TableRow key={rowKey}>\n                    <TableCell className=\"text-sm\">\n                      {period.startAt ? format(new Date(period.startAt), 'yyyy-MM-dd HH:mm:ss') : '-'}\n                    </TableCell>\n                    <TableCell className=\"text-sm\">\n                      {period.endAt ? format(new Date(period.endAt), 'yyyy-MM-dd HH:mm:ss') : '-'}\n                    </TableCell>\n                    <TableCell className=\"text-right\">{period.cpu ?? 0}</TableCell>\n                    <TableCell className=\"text-right\">{period.ramGB ?? 0}</TableCell>\n                    <TableCell className=\"text-right\">{period.diskGB ?? 0}</TableCell>\n                    <TableCell className=\"text-right\">{formatPrice(period.price ?? 0)}</TableCell>\n                  </TableRow>\n                )\n              })}\n            </TableBody>\n          </Table>\n        )}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/spending/SandboxUsageTable.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { SortOrderIcon } from '@/components/SortIcon'\nimport { Button } from '@/components/ui/button'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { PAGE_SIZE_OPTIONS } from '@/constants/Pagination'\nimport { ModelsSandboxUsage } from '@daytonaio/analytics-api-client'\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react'\nimport React, { useMemo, useState } from 'react'\n\nconst SKELETON_ROWS = 10\n\ninterface SandboxUsageTableProps {\n  data: ModelsSandboxUsage[] | undefined\n  isLoading: boolean\n}\n\ntype SortField = 'totalPrice' | 'totalCPUSeconds' | 'totalRAMGBSeconds' | 'totalDiskGBSeconds'\ntype SortDirection = 'asc' | 'desc'\n\nexport const SandboxUsageTable: React.FC<SandboxUsageTableProps> = ({ data, isLoading }) => {\n  const [sortField, setSortField] = useState<SortField>('totalPrice')\n  const [sortDirection, setSortDirection] = useState<SortDirection>('desc')\n  const [pageIndex, setPageIndex] = useState(0)\n  const [pageSize, setPageSize] = useState(25)\n\n  const sortedData = useMemo(() => {\n    if (!data) return []\n    return [...data].sort((a, b) => {\n      const aVal = (a[sortField] ?? 0) as number\n      const bVal = (b[sortField] ?? 0) as number\n      return sortDirection === 'desc' ? bVal - aVal : aVal - bVal\n    })\n  }, [data, sortField, sortDirection])\n\n  const pageCount = Math.max(1, Math.ceil(sortedData.length / pageSize))\n  const paginatedData = useMemo(() => {\n    const start = pageIndex * pageSize\n    return sortedData.slice(start, start + pageSize)\n  }, [sortedData, pageIndex, pageSize])\n\n  const handleSort = (field: SortField) => {\n    if (sortField === field) {\n      setSortDirection((prev) => (prev === 'desc' ? 'asc' : 'desc'))\n    } else {\n      setSortField(field)\n      setSortDirection('desc')\n    }\n    setPageIndex(0)\n  }\n\n  const getSortDirection = (field: SortField): 'asc' | 'desc' | null => {\n    if (sortField !== field) return null\n    return sortDirection\n  }\n\n  const handlePageSizeChange = (value: string) => {\n    setPageSize(Number(value))\n    setPageIndex(0)\n  }\n\n  if (!isLoading && (!data || sortedData.length === 0)) {\n    return null\n  }\n\n  return (\n    <div className=\"px-4\">\n      <Table>\n        <TableHeader>\n          <TableRow>\n            <TableHead>Sandbox ID</TableHead>\n            <SortableTableHead\n              field=\"totalPrice\"\n              label=\"Total Price\"\n              onSort={handleSort}\n              getSortDirection={getSortDirection}\n            />\n            <SortableTableHead\n              field=\"totalCPUSeconds\"\n              label=\"CPU (seconds)\"\n              onSort={handleSort}\n              getSortDirection={getSortDirection}\n            />\n            <SortableTableHead\n              field=\"totalRAMGBSeconds\"\n              label=\"RAM (GB-seconds)\"\n              onSort={handleSort}\n              getSortDirection={getSortDirection}\n            />\n            <SortableTableHead\n              field=\"totalDiskGBSeconds\"\n              label=\"Disk (GB-seconds)\"\n              onSort={handleSort}\n              getSortDirection={getSortDirection}\n            />\n          </TableRow>\n        </TableHeader>\n        <TableBody>\n          {isLoading\n            ? Array.from({ length: SKELETON_ROWS }).map((_, i) => (\n                <TableRow key={i}>\n                  <TableCell>\n                    <Skeleton className=\"h-4 w-[200px]\" />\n                  </TableCell>\n                  <TableCell className=\"text-right\">\n                    <Skeleton className=\"h-4 w-12 ml-auto\" />\n                  </TableCell>\n                  <TableCell className=\"text-right\">\n                    <Skeleton className=\"h-4 w-16 ml-auto\" />\n                  </TableCell>\n                  <TableCell className=\"text-right\">\n                    <Skeleton className=\"h-4 w-16 ml-auto\" />\n                  </TableCell>\n                  <TableCell className=\"text-right\">\n                    <Skeleton className=\"h-4 w-16 ml-auto\" />\n                  </TableCell>\n                </TableRow>\n              ))\n            : paginatedData.map((sandbox, index) => (\n                <TableRow key={sandbox.sandboxId ?? `row-${index}`}>\n                  <TableCell className=\"font-mono text-sm\">\n                    <div className=\"flex items-center gap-2 group/copy-button\">\n                      <span className=\"truncate max-w-[200px]\">{sandbox.sandboxId}</span>\n                      {sandbox.sandboxId && (\n                        <CopyButton value={sandbox.sandboxId} tooltipText=\"Copy sandbox ID\" size=\"icon-xs\" autoHide />\n                      )}\n                    </div>\n                  </TableCell>\n                  <TableCell className=\"text-right tabular-nums\">${(sandbox.totalPrice ?? 0).toFixed(2)}</TableCell>\n                  <TableCell className=\"text-right tabular-nums\">{(sandbox.totalCPUSeconds ?? 0).toFixed(1)}</TableCell>\n                  <TableCell className=\"text-right tabular-nums\">\n                    {(sandbox.totalRAMGBSeconds ?? 0).toFixed(1)}\n                  </TableCell>\n                  <TableCell className=\"text-right tabular-nums\">\n                    {(sandbox.totalDiskGBSeconds ?? 0).toFixed(1)}\n                  </TableCell>\n                </TableRow>\n              ))}\n        </TableBody>\n      </Table>\n\n      <div className=\"flex flex-col sm:flex-row gap-2 sm:items-center justify-between w-full pb-2 pt-4\">\n        <div className=\"flex items-center gap-4\">\n          <Select value={`${pageSize}`} onValueChange={handlePageSizeChange}>\n            <SelectTrigger className=\"h-8 w-[164px]\">\n              <SelectValue />\n            </SelectTrigger>\n            <SelectContent side=\"top\">\n              {PAGE_SIZE_OPTIONS.map((size) => (\n                <SelectItem key={size} value={`${size}`}>\n                  {size} per page\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n          <div className=\"text-sm text-muted-foreground\">{sortedData.length} total item(s)</div>\n        </div>\n        <div className=\"flex items-center gap-4\">\n          <div className=\"text-sm font-medium text-muted-foreground\">\n            Page {pageIndex + 1} of {pageCount}\n          </div>\n          <div className=\"flex items-center space-x-2\">\n            <Button\n              variant=\"outline\"\n              className=\"hidden h-8 w-8 p-0 lg:flex\"\n              onClick={() => setPageIndex(0)}\n              disabled={pageIndex === 0}\n            >\n              <span className=\"sr-only\">Go to first page</span>\n              <ChevronsLeft />\n            </Button>\n            <Button\n              variant=\"outline\"\n              className=\"h-8 w-8 p-0\"\n              onClick={() => setPageIndex((p) => p - 1)}\n              disabled={pageIndex === 0}\n            >\n              <span className=\"sr-only\">Go to previous page</span>\n              <ChevronLeft />\n            </Button>\n            <Button\n              variant=\"outline\"\n              className=\"h-8 w-8 p-0\"\n              onClick={() => setPageIndex((p) => p + 1)}\n              disabled={pageIndex >= pageCount - 1}\n            >\n              <span className=\"sr-only\">Go to next page</span>\n              <ChevronRight />\n            </Button>\n            <Button\n              variant=\"outline\"\n              className=\"hidden h-8 w-8 p-0 lg:flex\"\n              onClick={() => setPageIndex(pageCount - 1)}\n              disabled={pageIndex >= pageCount - 1}\n            >\n              <span className=\"sr-only\">Go to last page</span>\n              <ChevronsRight />\n            </Button>\n          </div>\n        </div>\n      </div>\n    </div>\n  )\n}\n\nfunction SortableTableHead({\n  field,\n  label,\n  onSort,\n  getSortDirection,\n}: {\n  field: SortField\n  label: string\n  onSort: (field: SortField) => void\n  getSortDirection: (field: SortField) => 'asc' | 'desc' | null\n}) {\n  const sortDirection = getSortDirection(field)\n  const ariaSort = sortDirection === 'asc' ? 'ascending' : sortDirection === 'desc' ? 'descending' : 'none'\n\n  return (\n    <TableHead className=\"hover:bg-muted cursor-pointer\" aria-sort={ariaSort}>\n      <button\n        type=\"button\"\n        className=\"group/sort-header flex items-center gap-2 w-full h-full justify-end\"\n        onClick={() => onSort(field)}\n      >\n        {label}\n        <SortOrderIcon sort={sortDirection} />\n      </button>\n    </TableHead>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/spending/UsageTimelineChart.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  ChartConfig,\n  ChartContainer,\n  ChartLegend,\n  ChartLegendContent,\n  ChartTooltip,\n  ChartTooltipContent,\n} from '@/components/ui/chart'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Spinner } from '@/components/ui/spinner'\nimport { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'\nimport { useRegions } from '@/hooks/useRegions'\nimport { formatMoney } from '@/lib/utils'\nimport { ModelsUsageChartPoint } from '@daytonaio/analytics-api-client'\nimport type { RegionUsageOverview } from '@daytonaio/api-client'\nimport { differenceInCalendarDays } from 'date-fns'\nimport { useMemo, useState } from 'react'\nimport { Area, AreaChart, CartesianGrid, ReferenceLine, XAxis, YAxis } from 'recharts'\n\ntype UsageTimelineChartProps = {\n  data: ModelsUsageChartPoint[] | undefined\n  isLoading: boolean\n  regionUsage: RegionUsageOverview[] | undefined\n  selectedRegion: string | undefined\n  onRegionChange: (region: string) => void\n  dateRange: { from: Date; to: Date }\n}\n\ntype ChartMode = 'resources' | 'cost'\ntype ResourceFilter = 'all' | 'cpu' | 'ram' | 'disk'\n\nconst RESOURCE_COLORS = {\n  cpu: 'hsl(var(--chart-1))',\n  ram: 'hsl(var(--chart-2))',\n  disk: 'hsl(var(--chart-3))',\n}\n\nconst LIMIT_COLOR = '#ef4444'\n\nconst allResourceChartConfig: ChartConfig = {\n  cpuPercent: { label: 'Compute', color: RESOURCE_COLORS.cpu },\n  ramPercent: { label: 'Memory', color: RESOURCE_COLORS.ram },\n  diskPercent: { label: 'Storage', color: RESOURCE_COLORS.disk },\n}\n\nconst cpuChartConfig: ChartConfig = {\n  cpu: { label: 'CPU (vCPU)', color: RESOURCE_COLORS.cpu },\n}\n\nconst ramChartConfig: ChartConfig = {\n  ramGB: { label: 'RAM (GiB)', color: RESOURCE_COLORS.ram },\n}\n\nconst diskChartConfig: ChartConfig = {\n  diskGB: { label: 'Disk (GiB)', color: RESOURCE_COLORS.disk },\n}\n\nconst costChartConfig: ChartConfig = {\n  cpuPrice: { label: 'CPU', color: RESOURCE_COLORS.cpu },\n  ramPrice: { label: 'RAM', color: RESOURCE_COLORS.ram },\n  diskPrice: { label: 'Disk', color: RESOURCE_COLORS.disk },\n}\n\nfunction formatTime(value: string) {\n  const date = new Date(value)\n  if (isNaN(date.getTime())) {\n    return ''\n  }\n  return date.toLocaleTimeString('en-US', {\n    hour: '2-digit',\n    minute: '2-digit',\n    hour12: false,\n  })\n}\n\nfunction formatDateAndTime(value: string) {\n  const date = new Date(value)\n  if (isNaN(date.getTime())) {\n    return ''\n  }\n  return date.toLocaleString('en-US', {\n    month: 'short',\n    day: 'numeric',\n    hour: '2-digit',\n    minute: '2-digit',\n    hour12: false,\n  })\n}\n\nfunction formatTooltipLabel(value: string) {\n  const date = new Date(value)\n  if (isNaN(date.getTime())) {\n    return ''\n  }\n  return date.toLocaleString('en-US', {\n    month: 'short',\n    day: 'numeric',\n    hour: '2-digit',\n    minute: '2-digit',\n    hour12: false,\n  })\n}\n\nexport function UsageTimelineChart({\n  data,\n  isLoading,\n  regionUsage,\n  selectedRegion,\n  onRegionChange,\n  dateRange,\n}: UsageTimelineChartProps) {\n  const { getRegionName } = useRegions()\n\n  const [mode, setMode] = useState<ChartMode>('resources')\n  const [resourceFilter, setResourceFilter] = useState<ResourceFilter>('all')\n\n  const isMultiDay = useMemo(\n    () => differenceInCalendarDays(dateRange.to, dateRange.from) >= 1,\n    [dateRange.from, dateRange.to],\n  )\n\n  const limits = useMemo(() => {\n    if (!selectedRegion || !regionUsage) return null\n    const region = regionUsage.find((r) => r.regionId === selectedRegion)\n    if (!region) return null\n    return {\n      cpu: region.totalCpuQuota,\n      ram: region.totalMemoryQuota,\n      disk: region.totalDiskQuota,\n    }\n  }, [selectedRegion, regionUsage])\n\n  const chartData = useMemo(() => {\n    if (!data?.length) return []\n    return data.map((point) => {\n      const cpu = point.cpu ?? 0\n      const ramGB = point.ramGB ?? 0\n      const diskGB = point.diskGB ?? 0\n\n      const cpuPercent = limits?.cpu ? (cpu / limits.cpu) * 100 : 0\n      const ramPercent = limits?.ram ? (ramGB / limits.ram) * 100 : 0\n      const diskPercent = limits?.disk ? (diskGB / limits.disk) * 100 : 0\n\n      return {\n        time: point.time ?? '',\n        cpu,\n        ramGB,\n        diskGB,\n        cpuPrice: point.cpuPrice ?? 0,\n        ramPrice: point.ramPrice ?? 0,\n        diskPrice: point.diskPrice ?? 0,\n        cpuPercent,\n        ramPercent,\n        diskPercent,\n      }\n    })\n  }, [data, limits])\n\n  const isResourceMode = mode === 'resources'\n\n  const { chartConfig, dataKeys } = useMemo(() => {\n    if (!isResourceMode) {\n      return {\n        chartConfig: costChartConfig,\n        dataKeys: ['cpuPrice', 'ramPrice', 'diskPrice'] as string[],\n      }\n    }\n    switch (resourceFilter) {\n      case 'all':\n        return {\n          chartConfig: allResourceChartConfig,\n          dataKeys: ['cpuPercent', 'ramPercent', 'diskPercent'] as string[],\n        }\n      case 'cpu':\n        return { chartConfig: cpuChartConfig, dataKeys: ['cpu'] as string[] }\n      case 'ram':\n        return { chartConfig: ramChartConfig, dataKeys: ['ramGB'] as string[] }\n      case 'disk':\n        return { chartConfig: diskChartConfig, dataKeys: ['diskGB'] as string[] }\n    }\n  }, [isResourceMode, resourceFilter])\n\n  const yAxisDomain = useMemo<[number, number] | undefined>(() => {\n    if (!isResourceMode) return undefined\n    if (resourceFilter === 'all') {\n      return [0, 120]\n    }\n    if (!limits) return undefined\n    const limitValue = resourceFilter === 'cpu' ? limits.cpu : resourceFilter === 'ram' ? limits.ram : limits.disk\n    if (limitValue <= 0) return undefined\n    // Round up to a nice number so ticks are evenly spaced\n    const raw = limitValue * 1.2\n    const tickCount = 4\n    const interval = Math.ceil(raw / tickCount)\n    const niceMax = interval * tickCount\n    return [0, niceMax]\n  }, [isResourceMode, resourceFilter, limits])\n\n  const yAxisFormatter = useMemo(() => {\n    if (!isResourceMode) return (value: number) => formatMoney(value)\n    if (resourceFilter === 'all') return (value: number) => `${value}%`\n    return (value: number) => value.toLocaleString()\n  }, [isResourceMode, resourceFilter])\n\n  const tooltipValueFormatter = useMemo(() => {\n    if (!isResourceMode) return (value: number) => formatMoney(value)\n    if (resourceFilter === 'all') return (value: number) => `${value.toFixed(1)}%`\n    return (value: number) => value.toLocaleString()\n  }, [isResourceMode, resourceFilter])\n\n  return (\n    <div className=\"flex flex-col gap-4 p-4\">\n      <div className=\"flex items-center justify-between flex-wrap gap-2\">\n        <p className=\"text-xl font-semibold leading-none tracking-tight\">Usage Timeline</p>\n        <div className=\"flex items-center gap-3 flex-wrap\">\n          <Select\n            value={selectedRegion ?? ''}\n            onValueChange={(value) => onRegionChange(value)}\n            disabled={!regionUsage?.length}\n          >\n            <SelectTrigger size=\"sm\" className=\"w-[160px] rounded-lg\" aria-label=\"Select region\">\n              <SelectValue placeholder=\"Select region\" />\n            </SelectTrigger>\n            <SelectContent className=\"rounded-xl\">\n              {regionUsage?.map((usage) => (\n                <SelectItem key={usage.regionId} value={usage.regionId}>\n                  {getRegionName(usage.regionId) ?? usage.regionId}\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n          {isResourceMode && (\n            <Select value={resourceFilter} onValueChange={(value) => setResourceFilter(value as ResourceFilter)}>\n              <SelectTrigger size=\"sm\" className=\"w-[150px] rounded-lg\" aria-label=\"Select resource\">\n                <SelectValue />\n              </SelectTrigger>\n              <SelectContent className=\"rounded-xl\">\n                <SelectItem value=\"all\">All Resources</SelectItem>\n                <SelectItem value=\"cpu\">Compute</SelectItem>\n                <SelectItem value=\"ram\">Memory</SelectItem>\n                <SelectItem value=\"disk\">Storage</SelectItem>\n              </SelectContent>\n            </Select>\n          )}\n          <ToggleGroup\n            type=\"single\"\n            value={mode}\n            onValueChange={(value) => {\n              if (value) setMode(value as ChartMode)\n            }}\n            variant=\"outline\"\n            size=\"sm\"\n          >\n            <ToggleGroupItem value=\"resources\">Resources</ToggleGroupItem>\n            <ToggleGroupItem value=\"cost\">Cost</ToggleGroupItem>\n          </ToggleGroup>\n        </div>\n      </div>\n      <div className=\"relative\">\n        {isLoading && (\n          <div className=\"absolute inset-0 z-10 flex items-center justify-center backdrop-grayscale backdrop-blur-[2px]\">\n            <Spinner className=\"size-6\" />\n          </div>\n        )}\n        <ChartContainer config={chartConfig} className=\"aspect-auto h-[300px] w-full\">\n          <AreaChart data={chartData}>\n            <defs>\n              {dataKeys.map((key) => (\n                <linearGradient key={key} id={`fill-${key}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n                  <stop offset=\"5%\" stopColor={`var(--color-${key})`} stopOpacity={0.8} />\n                  <stop offset=\"95%\" stopColor={`var(--color-${key})`} stopOpacity={0.1} />\n                </linearGradient>\n              ))}\n            </defs>\n            <CartesianGrid vertical={false} />\n            <XAxis\n              dataKey=\"time\"\n              tickLine={false}\n              axisLine={false}\n              tickMargin={8}\n              minTickGap={48}\n              tickFormatter={isMultiDay ? formatDateAndTime : formatTime}\n            />\n            <YAxis\n              tickLine={false}\n              axisLine={false}\n              tickMargin={4}\n              tickCount={5}\n              width={50}\n              domain={yAxisDomain}\n              tickFormatter={yAxisFormatter}\n            />\n            <ChartTooltip\n              cursor={false}\n              content={\n                <ChartTooltipContent\n                  indicator=\"dot\"\n                  labelFormatter={(label) => formatTooltipLabel(label)}\n                  valueFormatter={(value) => tooltipValueFormatter(Number(value))}\n                />\n              }\n            />\n            {dataKeys.map((key) => (\n              <Area\n                key={key}\n                dataKey={key}\n                type=\"monotoneX\"\n                fill={`url(#fill-${key})`}\n                stroke={`var(--color-${key})`}\n                stackId={resourceFilter === 'all' && isResourceMode ? 'a' : undefined}\n              />\n            ))}\n            {isResourceMode && resourceFilter === 'all' && (\n              <ReferenceLine\n                y={100}\n                stroke={LIMIT_COLOR}\n                strokeDasharray=\"6 3\"\n                strokeWidth={1.5}\n                label={{\n                  value: 'Limit (100%)',\n                  position: 'insideTopRight',\n                  fontSize: 11,\n                  fill: LIMIT_COLOR,\n                }}\n              />\n            )}\n            {isResourceMode && resourceFilter === 'cpu' && limits && limits.cpu > 0 && (\n              <ReferenceLine\n                y={limits.cpu}\n                stroke={LIMIT_COLOR}\n                strokeDasharray=\"6 3\"\n                strokeWidth={1.5}\n                label={{\n                  value: `CPU limit (${limits.cpu} vCPU)`,\n                  position: 'insideTopRight',\n                  fontSize: 11,\n                  fill: LIMIT_COLOR,\n                }}\n              />\n            )}\n            {isResourceMode && resourceFilter === 'ram' && limits && limits.ram > 0 && (\n              <ReferenceLine\n                y={limits.ram}\n                stroke={LIMIT_COLOR}\n                strokeDasharray=\"6 3\"\n                strokeWidth={1.5}\n                label={{\n                  value: `RAM limit (${limits.ram} GiB)`,\n                  position: 'insideTopRight',\n                  fontSize: 11,\n                  fill: LIMIT_COLOR,\n                }}\n              />\n            )}\n            {isResourceMode && resourceFilter === 'disk' && limits && limits.disk > 0 && (\n              <ReferenceLine\n                y={limits.disk}\n                stroke={LIMIT_COLOR}\n                strokeDasharray=\"6 3\"\n                strokeWidth={1.5}\n                label={{\n                  value: `Disk limit (${limits.disk} GiB)`,\n                  position: 'insideTopRight',\n                  fontSize: 11,\n                  fill: LIMIT_COLOR,\n                }}\n              />\n            )}\n            <ChartLegend content={<ChartLegendContent />} />\n          </AreaChart>\n        </ChartContainer>\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/spending/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport * from './AggregatedUsageChart'\nexport * from './SandboxUsageTable'\nexport * from './SandboxSpendingTab'\nexport * from './CostBreakdown'\nexport * from './ResourceUsageChart'\n"
  },
  {
    "path": "apps/dashboard/src/components/telemetry/LogsTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useCallback } from 'react'\nimport { useSandboxLogs, LogsQueryParams } from '@/hooks/useSandboxLogs'\nimport { TimeRangeSelector } from './TimeRangeSelector'\nimport { SeverityBadge } from './SeverityBadge'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Input } from '@/components/ui/input'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { ChevronLeft, ChevronRight, Search, FileText, RefreshCw, ChevronDown, ChevronUp } from 'lucide-react'\nimport { Spinner } from '@/components/ui/spinner'\nimport { format } from 'date-fns'\nimport { subHours } from 'date-fns'\nimport { LogEntry } from '@daytonaio/api-client'\n\ninterface LogsTabProps {\n  sandboxId: string\n}\n\nconst SEVERITY_OPTIONS = ['DEBUG', 'INFO', 'WARN', 'ERROR']\n\nexport const LogsTab: React.FC<LogsTabProps> = ({ sandboxId }) => {\n  const [timeRange, setTimeRange] = useState(() => {\n    const now = new Date()\n    return { from: subHours(now, 1), to: now }\n  })\n  const [page, setPage] = useState(1)\n  const [search, setSearch] = useState('')\n  const [searchInput, setSearchInput] = useState('')\n  const [selectedSeverities, setSelectedSeverities] = useState<string[]>([])\n  const [expandedRow, setExpandedRow] = useState<number | null>(null)\n  const limit = 50\n\n  const queryParams: LogsQueryParams = {\n    from: timeRange.from,\n    to: timeRange.to,\n    page,\n    limit,\n    severities: selectedSeverities.length > 0 ? selectedSeverities : undefined,\n    search: search || undefined,\n  }\n\n  const { data, isLoading, refetch } = useSandboxLogs(sandboxId, queryParams)\n\n  const handleTimeRangeChange = useCallback((from: Date, to: Date) => {\n    setTimeRange({ from, to })\n    setPage(1)\n  }, [])\n\n  const handleSearch = () => {\n    setSearch(searchInput)\n    setPage(1)\n  }\n\n  const handleSeverityChange = (severity: string) => {\n    setSelectedSeverities((prev) =>\n      prev.includes(severity) ? prev.filter((s) => s !== severity) : [...prev, severity],\n    )\n    setPage(1)\n  }\n\n  const toggleRowExpansion = (index: number) => {\n    setExpandedRow(expandedRow === index ? null : index)\n  }\n\n  const formatTimestamp = (timestamp: string) => {\n    try {\n      return format(new Date(timestamp), 'yyyy-MM-dd HH:mm:ss.SSS')\n    } catch {\n      return timestamp\n    }\n  }\n\n  return (\n    <div className=\"flex flex-col h-full gap-4 p-4\">\n      <div className=\"flex flex-wrap items-center gap-3\">\n        <TimeRangeSelector onChange={handleTimeRangeChange} className=\"w-auto\" />\n\n        <div className=\"flex items-center gap-2\">\n          <Input\n            placeholder=\"Search logs...\"\n            value={searchInput}\n            onChange={(e) => setSearchInput(e.target.value)}\n            onKeyDown={(e) => e.key === 'Enter' && handleSearch()}\n            className=\"w-48\"\n          />\n          <Button variant=\"outline\" size=\"icon\" onClick={handleSearch}>\n            <Search className=\"h-4 w-4\" />\n          </Button>\n        </div>\n\n        <Select\n          value={selectedSeverities.length === 1 ? selectedSeverities[0] : ''}\n          onValueChange={(value) => {\n            if (value) {\n              setSelectedSeverities([value])\n            } else {\n              setSelectedSeverities([])\n            }\n            setPage(1)\n          }}\n        >\n          <SelectTrigger className=\"w-32\">\n            <SelectValue placeholder=\"Severity\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"all\">All</SelectItem>\n            {SEVERITY_OPTIONS.map((sev) => (\n              <SelectItem key={sev} value={sev}>\n                {sev}\n              </SelectItem>\n            ))}\n          </SelectContent>\n        </Select>\n\n        <Button variant=\"outline\" size=\"icon\" onClick={() => refetch()}>\n          <RefreshCw className=\"h-4 w-4\" />\n        </Button>\n      </div>\n\n      <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0 border rounded-md\">\n        {isLoading ? (\n          <div className=\"flex items-center justify-center h-40\">\n            <Spinner className=\"w-6 h-6\" />\n          </div>\n        ) : !data?.items?.length ? (\n          <div className=\"flex flex-col items-center justify-center h-40 text-muted-foreground gap-2\">\n            <FileText className=\"w-8 h-8\" />\n            <span className=\"text-sm\">No logs found</span>\n          </div>\n        ) : (\n          <Table>\n            <TableHeader>\n              <TableRow>\n                <TableHead className=\"w-12\"></TableHead>\n                <TableHead className=\"w-48\">Timestamp</TableHead>\n                <TableHead className=\"w-24\">Severity</TableHead>\n                <TableHead>Message</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {data.items.map((log: LogEntry, index: number) => (\n                <React.Fragment key={index}>\n                  <TableRow className=\"cursor-pointer hover:bg-muted/50\" onClick={() => toggleRowExpansion(index)}>\n                    <TableCell>\n                      {expandedRow === index ? <ChevronUp className=\"h-4 w-4\" /> : <ChevronDown className=\"h-4 w-4\" />}\n                    </TableCell>\n                    <TableCell className=\"font-mono text-xs\">{formatTimestamp(log.timestamp)}</TableCell>\n                    <TableCell>\n                      <SeverityBadge severity={log.severityText} />\n                    </TableCell>\n                    <TableCell className=\"max-w-md truncate font-mono text-xs\">{log.body}</TableCell>\n                  </TableRow>\n                  {expandedRow === index && (\n                    <TableRow>\n                      <TableCell colSpan={4} className=\"bg-muted/30 p-4\">\n                        <div className=\"space-y-3\">\n                          <div>\n                            <h4 className=\"text-sm font-medium mb-1\">Full Message</h4>\n                            <pre className=\"text-xs bg-background p-2 rounded overflow-x-auto whitespace-pre-wrap\">\n                              {log.body}\n                            </pre>\n                          </div>\n                          {log.traceId && (\n                            <div>\n                              <h4 className=\"text-sm font-medium mb-1\">Trace ID</h4>\n                              <code className=\"text-xs bg-background p-1 rounded\">{log.traceId}</code>\n                            </div>\n                          )}\n                          {log.spanId && (\n                            <div>\n                              <h4 className=\"text-sm font-medium mb-1\">Span ID</h4>\n                              <code className=\"text-xs bg-background p-1 rounded\">{log.spanId}</code>\n                            </div>\n                          )}\n                          {Object.keys(log.logAttributes || {}).length > 0 && (\n                            <div>\n                              <h4 className=\"text-sm font-medium mb-1\">Attributes</h4>\n                              <pre className=\"text-xs bg-background p-2 rounded overflow-x-auto\">\n                                {JSON.stringify(log.logAttributes, null, 2)}\n                              </pre>\n                            </div>\n                          )}\n                        </div>\n                      </TableCell>\n                    </TableRow>\n                  )}\n                </React.Fragment>\n              ))}\n            </TableBody>\n          </Table>\n        )}\n      </ScrollArea>\n\n      {data && data.totalPages > 1 && (\n        <div className=\"flex items-center justify-between\">\n          <span className=\"text-sm text-muted-foreground\">\n            Page {page} of {data.totalPages} ({data.total} total logs)\n          </span>\n          <div className=\"flex items-center gap-2\">\n            <Button variant=\"outline\" size=\"sm\" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>\n              <ChevronLeft className=\"h-4 w-4\" />\n              Previous\n            </Button>\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              disabled={page >= data.totalPages}\n              onClick={() => setPage((p) => p + 1)}\n            >\n              Next\n              <ChevronRight className=\"h-4 w-4\" />\n            </Button>\n          </div>\n        </div>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/telemetry/MetricsTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useCallback } from 'react'\nimport { useSandboxMetrics, MetricsQueryParams } from '@/hooks/useSandboxMetrics'\nimport { TimeRangeSelector } from './TimeRangeSelector'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { ChartContainer, ChartTooltip, ChartTooltipContent, ChartConfig } from '@/components/ui/chart'\nimport { LineChart, Line, XAxis, YAxis, CartesianGrid, ResponsiveContainer, Legend } from 'recharts'\nimport { RefreshCw, BarChart3 } from 'lucide-react'\nimport { Spinner } from '@/components/ui/spinner'\nimport { format } from 'date-fns'\nimport { subHours } from 'date-fns'\nimport { MetricSeries } from '@daytonaio/api-client'\nimport { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'\n\ninterface MetricsTabProps {\n  sandboxId: string\n}\n\nconst CHART_COLORS = [\n  'hsl(var(--chart-1))',\n  'hsl(var(--chart-2))',\n  'hsl(var(--chart-3))',\n  'hsl(var(--chart-4))',\n  'hsl(var(--chart-5))',\n]\n\nconst BYTES_TO_GIB = 1024 * 1024 * 1024\n\ntype ViewMode = '%' | 'GiB'\n\nconst METRIC_GROUPS = [\n  { key: 'cpu', title: 'CPU', prefix: '.cpu.', hasToggle: false },\n  { key: 'memory', title: 'Memory', prefix: '.memory.', hasToggle: true },\n  { key: 'filesystem', title: 'Filesystem', prefix: '.filesystem.', hasToggle: true },\n]\n\nfunction isByteMetric(metricName: string): boolean {\n  return !metricName.endsWith('.utilization')\n}\n\nfunction buildChartData(series: MetricSeries[], convertToGiB: boolean): Record<string, unknown>[] {\n  const timestampSet = new Set<string>()\n  series.forEach((s) => {\n    s.dataPoints.forEach((point) => {\n      timestampSet.add(point.timestamp)\n    })\n  })\n\n  const timestamps = Array.from(timestampSet).sort()\n\n  return timestamps.map((timestamp) => {\n    const point: Record<string, unknown> = { timestamp }\n    series.forEach((s) => {\n      const dp = s.dataPoints.find((p) => p.timestamp === timestamp)\n      if (dp?.value == null) {\n        point[s.metricName] = null\n      } else if (convertToGiB && isByteMetric(s.metricName)) {\n        point[s.metricName] = Math.round((dp.value / BYTES_TO_GIB) * 100) / 100\n      } else {\n        point[s.metricName] = dp.value\n      }\n    })\n    return point\n  })\n}\n\nfunction buildChartConfig(series: MetricSeries[]): ChartConfig {\n  const config: ChartConfig = {}\n  series.forEach((s, index) => {\n    config[s.metricName] = {\n      label: s.metricName.replace(/^daytona\\.sandbox\\./, ''),\n      color: CHART_COLORS[index % CHART_COLORS.length],\n    }\n  })\n  return config\n}\n\nconst formatXAxis = (timestamp: string) => {\n  try {\n    return format(new Date(timestamp), 'HH:mm')\n  } catch {\n    return timestamp\n  }\n}\n\ninterface MetricGroupChartProps {\n  title: string\n  series: MetricSeries[]\n  convertToGiB: boolean\n  viewMode?: ViewMode\n  onViewModeChange?: (mode: ViewMode) => void\n}\n\nconst MetricGroupChart: React.FC<MetricGroupChartProps> = ({\n  title,\n  series,\n  convertToGiB,\n  viewMode,\n  onViewModeChange,\n}) => {\n  const chartData = React.useMemo(() => buildChartData(series, convertToGiB), [series, convertToGiB])\n  const chartConfig = React.useMemo(() => buildChartConfig(series), [series])\n\n  const displayTitle = viewMode ? `${title} (${viewMode})` : title\n\n  return (\n    <div className=\"min-h-[250px]\">\n      <div className=\"flex items-center gap-2 mb-2\">\n        <h3 className=\"text-sm font-medium\">{displayTitle}</h3>\n        {viewMode && onViewModeChange && (\n          <ToggleGroup\n            type=\"single\"\n            value={viewMode}\n            onValueChange={(value) => {\n              if (value) onViewModeChange(value as ViewMode)\n            }}\n            variant=\"outline\"\n            size=\"sm\"\n          >\n            <ToggleGroupItem value=\"%\" className=\"text-xs px-2 h-6\">\n              %\n            </ToggleGroupItem>\n            <ToggleGroupItem value=\"GiB\" className=\"text-xs px-2 h-6\">\n              GiB\n            </ToggleGroupItem>\n          </ToggleGroup>\n        )}\n      </div>\n      <ChartContainer config={chartConfig} className=\"h-[220px] w-full\">\n        <ResponsiveContainer width=\"100%\" height=\"100%\">\n          <LineChart data={chartData} margin={{ top: 10, right: 30, left: 20, bottom: 5 }}>\n            <CartesianGrid strokeDasharray=\"3 3\" className=\"stroke-muted\" />\n            <XAxis\n              dataKey=\"timestamp\"\n              tickFormatter={formatXAxis}\n              className=\"text-xs\"\n              tick={{ fill: 'hsl(var(--muted-foreground))' }}\n            />\n            <YAxis\n              className=\"text-xs\"\n              tick={{ fill: 'hsl(var(--muted-foreground))' }}\n              tickFormatter={convertToGiB ? (value: number) => value.toFixed(2) : undefined}\n              domain={viewMode === '%' ? [0, 100] : undefined}\n            />\n            <ChartTooltip\n              content={\n                <ChartTooltipContent\n                  labelFormatter={(label) => {\n                    try {\n                      return format(new Date(label as string), 'yyyy-MM-dd HH:mm:ss')\n                    } catch {\n                      return String(label)\n                    }\n                  }}\n                />\n              }\n            />\n            <Legend />\n            {series.map((s, index) => (\n              <Line\n                key={s.metricName}\n                type=\"monotone\"\n                dataKey={s.metricName}\n                stroke={CHART_COLORS[index % CHART_COLORS.length]}\n                strokeWidth={2}\n                dot={false}\n                connectNulls\n              />\n            ))}\n          </LineChart>\n        </ResponsiveContainer>\n      </ChartContainer>\n    </div>\n  )\n}\n\nexport const MetricsTab: React.FC<MetricsTabProps> = ({ sandboxId }) => {\n  const [timeRange, setTimeRange] = useState(() => {\n    const now = new Date()\n    return { from: subHours(now, 1), to: now }\n  })\n\n  const queryParams: MetricsQueryParams = {\n    from: timeRange.from,\n    to: timeRange.to,\n  }\n\n  const { data, isLoading, refetch } = useSandboxMetrics(sandboxId, queryParams)\n\n  const [viewModes, setViewModes] = useState<Record<string, ViewMode>>({\n    memory: '%',\n    filesystem: '%',\n  })\n\n  const handleTimeRangeChange = useCallback((from: Date, to: Date) => {\n    setTimeRange({ from, to })\n  }, [])\n\n  const handleViewModeChange = useCallback((groupKey: string, mode: ViewMode) => {\n    setViewModes((prev) => ({ ...prev, [groupKey]: mode }))\n  }, [])\n\n  const groupedSeries = React.useMemo(() => {\n    if (!data?.series?.length) return []\n\n    return METRIC_GROUPS.map((group) => {\n      const allSeries = data.series.filter((s) => s.metricName.includes(group.prefix))\n      const mode = group.hasToggle ? viewModes[group.key] : undefined\n\n      let filteredSeries = allSeries.filter((s) => s.metricName !== 'system.memory.utilization')\n      if (mode === '%') {\n        filteredSeries = filteredSeries.filter((s) => s.metricName.endsWith('.utilization'))\n      } else if (mode === 'GiB') {\n        filteredSeries = filteredSeries.filter((s) => !s.metricName.endsWith('.utilization'))\n      }\n\n      return {\n        key: group.key,\n        title: group.title,\n        series: filteredSeries,\n        convertToGiB: mode === 'GiB',\n        hasToggle: group.hasToggle,\n        viewMode: mode,\n      }\n    }).filter((group) => group.series.length > 0)\n  }, [data, viewModes])\n\n  return (\n    <div className=\"flex flex-col h-full gap-4 p-4\">\n      <div className=\"flex flex-wrap items-center gap-3\">\n        <TimeRangeSelector onChange={handleTimeRangeChange} className=\"w-auto\" />\n\n        <Button variant=\"outline\" size=\"icon\" onClick={() => refetch()}>\n          <RefreshCw className=\"h-4 w-4\" />\n        </Button>\n      </div>\n\n      <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0\">\n        {isLoading ? (\n          <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n            <Spinner className=\"w-6 h-6\" />\n          </div>\n        ) : !data?.series?.length ? (\n          <div className=\"flex flex-col items-center justify-center h-full min-h-[400px] text-muted-foreground gap-2\">\n            <BarChart3 className=\"w-8 h-8\" />\n            <span className=\"text-sm\">No metrics found</span>\n          </div>\n        ) : (\n          <div className=\"flex flex-col gap-6\">\n            {groupedSeries.map((group) => (\n              <MetricGroupChart\n                key={group.key}\n                title={group.title}\n                series={group.series}\n                convertToGiB={group.convertToGiB}\n                viewMode={group.hasToggle ? group.viewMode : undefined}\n                onViewModeChange={group.hasToggle ? (mode) => handleViewModeChange(group.key, mode) : undefined}\n              />\n            ))}\n          </div>\n        )}\n      </ScrollArea>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/telemetry/SeverityBadge.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport { Badge } from '@/components/ui/badge'\n\ninterface SeverityBadgeProps {\n  severity: string\n}\n\nexport const SeverityBadge: React.FC<SeverityBadgeProps> = ({ severity }) => {\n  const getSeverityVariant = (sev: string) => {\n    const upperSev = sev.toUpperCase()\n    switch (upperSev) {\n      case 'ERROR':\n      case 'FATAL':\n        return 'destructive'\n      case 'WARN':\n      case 'WARNING':\n        return 'warning'\n      case 'INFO':\n        return 'info'\n      case 'DEBUG':\n      case 'TRACE':\n        return 'secondary'\n      default:\n        return 'outline'\n    }\n  }\n\n  return <Badge variant={getSeverityVariant(severity)}>{severity}</Badge>\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/telemetry/TimeRangeSelector.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useEffect } from 'react'\nimport { DateRangePicker, DateRangePickerRef, QuickRangesConfig } from '@/components/ui/date-range-picker'\nimport { DateRange } from 'react-day-picker'\nimport { subHours } from 'date-fns'\n\ninterface TimeRangeSelectorProps {\n  onChange: (from: Date, to: Date) => void\n  defaultRange?: { from: Date; to: Date }\n  defaultSelectedQuickRange?: string\n  className?: string\n}\n\nconst quickRanges: QuickRangesConfig = {\n  minutes: [15, 30],\n  hours: [1, 3, 6, 12, 24],\n  days: [3, 7],\n}\n\nexport const TimeRangeSelector: React.FC<TimeRangeSelectorProps> = ({\n  onChange,\n  defaultRange,\n  defaultSelectedQuickRange = 'Last 1 hour',\n  className,\n}) => {\n  const pickerRef = React.useRef<DateRangePickerRef>(null)\n  const [dateRange, setDateRange] = useState<DateRange>(() => {\n    if (defaultRange) {\n      return { from: defaultRange.from, to: defaultRange.to }\n    }\n    // Default to last 1 hour\n    const now = new Date()\n    return { from: subHours(now, 1), to: now }\n  })\n\n  useEffect(() => {\n    if (dateRange.from && dateRange.to) {\n      onChange(dateRange.from, dateRange.to)\n    }\n  }, [dateRange, onChange])\n\n  const handleChange = (range: DateRange) => {\n    setDateRange(range)\n  }\n\n  return (\n    <DateRangePicker\n      ref={pickerRef}\n      value={dateRange}\n      onChange={handleChange}\n      quickRangesEnabled\n      quickRanges={quickRanges}\n      timeSelection\n      className={className}\n      defaultSelectedQuickRange={defaultSelectedQuickRange}\n    />\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/telemetry/TraceDetailsSheet.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useMemo } from 'react'\nimport { useSandboxTraceSpans } from '@/hooks/useSandboxTraceSpans'\nimport { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { Spinner } from '@/components/ui/spinner'\nimport { CopyButton } from '@/components/CopyButton'\nimport { TraceSpan } from '@daytonaio/api-client'\n\ninterface TraceDetailsSheetProps {\n  sandboxId: string\n  traceId: string | null\n  open: boolean\n  onOpenChange: (open: boolean) => void\n}\n\ninterface SpanWithDepth extends TraceSpan {\n  depth: number\n  children: SpanWithDepth[]\n}\n\nexport const TraceDetailsSheet: React.FC<TraceDetailsSheetProps> = ({ sandboxId, traceId, open, onOpenChange }) => {\n  const { data: spans, isLoading } = useSandboxTraceSpans(sandboxId, traceId ?? undefined, {\n    enabled: !!traceId && open,\n  })\n\n  // Build tree structure from flat span list\n  const spanTree = useMemo(() => {\n    if (!spans || spans.length === 0) return []\n\n    const spanMap = new Map<string, SpanWithDepth>()\n    const roots: SpanWithDepth[] = []\n\n    // First pass: create all spans with depth 0\n    spans.forEach((span) => {\n      spanMap.set(span.spanId, { ...span, depth: 0, children: [] })\n    })\n\n    // Second pass: build tree and calculate depths\n    spans.forEach((span) => {\n      const spanWithDepth = spanMap.get(span.spanId)!\n      if (span.parentSpanId && spanMap.has(span.parentSpanId)) {\n        const parent = spanMap.get(span.parentSpanId)!\n        parent.children.push(spanWithDepth)\n      } else {\n        roots.push(spanWithDepth)\n      }\n    })\n\n    // Third pass: calculate depths\n    const setDepths = (spans: SpanWithDepth[], depth: number) => {\n      spans.forEach((span) => {\n        span.depth = depth\n        setDepths(span.children, depth + 1)\n      })\n    }\n    setDepths(roots, 0)\n\n    // Flatten tree in order\n    const result: SpanWithDepth[] = []\n    const flatten = (spans: SpanWithDepth[]) => {\n      // Sort by timestamp\n      spans.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime())\n      spans.forEach((span) => {\n        result.push(span)\n        flatten(span.children)\n      })\n    }\n    flatten(roots)\n\n    return result\n  }, [spans])\n\n  // Calculate trace start time and total duration for waterfall\n  const { traceStart, traceDuration } = useMemo(() => {\n    if (!spans || spans.length === 0) return { traceStart: 0, traceDuration: 0 }\n\n    const times = spans.map((s) => new Date(s.timestamp).getTime())\n    const durations = spans.map((s, i) => times[i] + s.durationNs / 1_000_000)\n\n    const start = Math.min(...times)\n    const end = Math.max(...durations)\n\n    return { traceStart: start, traceDuration: end - start }\n  }, [spans])\n\n  const formatDuration = (durationNs: number) => {\n    const ms = durationNs / 1_000_000\n    if (ms < 1) {\n      return `${(ms * 1000).toFixed(0)}us`\n    }\n    if (ms < 1000) {\n      return `${ms.toFixed(2)}ms`\n    }\n    return `${(ms / 1000).toFixed(2)}s`\n  }\n\n  return (\n    <Sheet open={open} onOpenChange={onOpenChange}>\n      <SheetContent className=\"w-dvw sm:w-[700px] p-0 flex flex-col gap-0\">\n        <SheetHeader className=\"p-4 border-b\">\n          <SheetTitle className=\"flex items-center gap-2\">\n            Trace Details\n            {traceId && (\n              <>\n                <code className=\"text-sm font-mono text-muted-foreground font-normal\">{traceId}</code>\n                <CopyButton value={traceId} tooltipText=\"Copy Trace ID\" size=\"icon-xs\" />\n              </>\n            )}\n          </SheetTitle>\n        </SheetHeader>\n\n        <ScrollArea className=\"flex-1\">\n          {isLoading ? (\n            <div className=\"flex items-center justify-center h-40\">\n              <Spinner className=\"w-6 h-6\" />\n            </div>\n          ) : !spanTree.length ? (\n            <div className=\"flex items-center justify-center h-40 text-muted-foreground\">\n              <span className=\"text-sm\">No spans found</span>\n            </div>\n          ) : (\n            <div className=\"p-4 space-y-2\">\n              {spanTree.map((span) => {\n                const spanStart = new Date(span.timestamp).getTime()\n                const spanDuration = span.durationNs / 1_000_000\n                const offsetPercent = traceDuration > 0 ? ((spanStart - traceStart) / traceDuration) * 100 : 0\n                const widthPercent = traceDuration > 0 ? (spanDuration / traceDuration) * 100 : 100\n\n                return (\n                  <div key={span.spanId} className=\"group\">\n                    <div className=\"flex items-center gap-2\" style={{ paddingLeft: `${span.depth * 16}px` }}>\n                      <div className=\"flex-shrink-0 w-48 truncate text-sm\">{span.spanName}</div>\n                      <div className=\"flex-1 h-6 bg-muted rounded relative overflow-hidden\">\n                        <div\n                          className=\"absolute h-full bg-primary/70 rounded transition-all group-hover:bg-primary\"\n                          style={{\n                            left: `${Math.min(offsetPercent, 99)}%`,\n                            width: `${Math.max(widthPercent, 1)}%`,\n                          }}\n                        />\n                      </div>\n                      <div className=\"flex-shrink-0 w-20 text-right text-xs font-mono text-muted-foreground\">\n                        {formatDuration(span.durationNs)}\n                      </div>\n                    </div>\n\n                    <div\n                      className=\"hidden group-hover:block mt-2 p-3 bg-muted/50 rounded text-xs\"\n                      style={{ marginLeft: `${span.depth * 16}px` }}\n                    >\n                      <div className=\"grid grid-cols-2 gap-2\">\n                        <div>\n                          <span className=\"text-muted-foreground\">Span ID:</span>\n                          <code className=\"ml-1 font-mono\">{span.spanId.slice(0, 16)}</code>\n                        </div>\n                        {span.parentSpanId && (\n                          <div>\n                            <span className=\"text-muted-foreground\">Parent:</span>\n                            <code className=\"ml-1 font-mono\">{span.parentSpanId.slice(0, 16)}</code>\n                          </div>\n                        )}\n                        {span.statusCode && (\n                          <div>\n                            <span className=\"text-muted-foreground\">Status:</span>\n                            <span className=\"ml-1\">{span.statusCode}</span>\n                          </div>\n                        )}\n                      </div>\n                      {Object.keys(span.spanAttributes || {}).length > 0 && (\n                        <div className=\"mt-2\">\n                          <span className=\"text-muted-foreground\">Attributes:</span>\n                          <pre className=\"mt-1 p-2 bg-background rounded overflow-x-auto\">\n                            {JSON.stringify(span.spanAttributes, null, 2)}\n                          </pre>\n                        </div>\n                      )}\n                    </div>\n                  </div>\n                )\n              })}\n            </div>\n          )}\n        </ScrollArea>\n      </SheetContent>\n    </Sheet>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/telemetry/TracesTab.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState, useCallback } from 'react'\nimport { useSandboxTraces, TracesQueryParams } from '@/hooks/useSandboxTraces'\nimport { TimeRangeSelector } from './TimeRangeSelector'\nimport { TraceDetailsSheet } from './TraceDetailsSheet'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { ChevronLeft, ChevronRight, RefreshCw, Activity } from 'lucide-react'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'\nimport { CopyButton } from '@/components/CopyButton'\nimport { Spinner } from '@/components/ui/spinner'\nimport { format } from 'date-fns'\nimport { subHours } from 'date-fns'\nimport { TraceSummary } from '@daytonaio/api-client'\n\ninterface TracesTabProps {\n  sandboxId: string\n}\n\nexport const TracesTab: React.FC<TracesTabProps> = ({ sandboxId }) => {\n  const [timeRange, setTimeRange] = useState(() => {\n    const now = new Date()\n    return { from: subHours(now, 1), to: now }\n  })\n  const [page, setPage] = useState(1)\n  const [selectedTraceId, setSelectedTraceId] = useState<string | null>(null)\n  const limit = 50\n\n  const queryParams: TracesQueryParams = {\n    from: timeRange.from,\n    to: timeRange.to,\n    page,\n    limit,\n  }\n\n  const { data, isLoading, refetch } = useSandboxTraces(sandboxId, queryParams)\n\n  const handleTimeRangeChange = useCallback((from: Date, to: Date) => {\n    setTimeRange({ from, to })\n    setPage(1)\n  }, [])\n\n  const formatTimestamp = (timestamp: string) => {\n    try {\n      return format(new Date(timestamp), 'yyyy-MM-dd HH:mm:ss.SSS')\n    } catch {\n      return timestamp\n    }\n  }\n\n  const formatDuration = (durationMs: number) => {\n    if (durationMs < 1) {\n      return `${(durationMs * 1000).toFixed(2)}us`\n    }\n    if (durationMs < 1000) {\n      return `${durationMs.toFixed(2)}ms`\n    }\n    return `${(durationMs / 1000).toFixed(2)}s`\n  }\n\n  const truncateTraceId = (traceId: string) => {\n    if (traceId.length > 16) {\n      return `${traceId.slice(0, 8)}...${traceId.slice(-8)}`\n    }\n    return traceId\n  }\n\n  return (\n    <div className=\"flex flex-col h-full gap-4 p-4\">\n      <div className=\"flex flex-wrap items-center gap-3\">\n        <TimeRangeSelector onChange={handleTimeRangeChange} className=\"w-auto\" />\n\n        <Button variant=\"outline\" size=\"icon\" onClick={() => refetch()}>\n          <RefreshCw className=\"h-4 w-4\" />\n        </Button>\n      </div>\n\n      <ScrollArea fade=\"mask\" className=\"flex-1 min-h-0 border rounded-md\">\n        {isLoading ? (\n          <div className=\"flex items-center justify-center h-40\">\n            <Spinner className=\"w-6 h-6\" />\n          </div>\n        ) : !data?.items?.length ? (\n          <div className=\"flex flex-col items-center justify-center h-40 text-muted-foreground gap-2\">\n            <Activity className=\"w-8 h-8\" />\n            <span className=\"text-sm\">No traces found</span>\n          </div>\n        ) : (\n          <Table>\n            <TableHeader>\n              <TableRow>\n                <TableHead>Trace ID</TableHead>\n                <TableHead>Root Span</TableHead>\n                <TableHead>Start Time</TableHead>\n                <TableHead>Duration</TableHead>\n                <TableHead className=\"text-center\">Spans</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {data.items.map((trace: TraceSummary) => (\n                <TableRow\n                  key={trace.traceId}\n                  className=\"cursor-pointer hover:bg-muted/50\"\n                  onClick={() => setSelectedTraceId(trace.traceId)}\n                >\n                  <TableCell className=\"font-mono text-xs\">\n                    <div className=\"flex items-center gap-1\">\n                      <Tooltip>\n                        <TooltipTrigger asChild>\n                          <span>{truncateTraceId(trace.traceId)}</span>\n                        </TooltipTrigger>\n                        <TooltipContent>\n                          <code className=\"font-mono text-xs\">{trace.traceId}</code>\n                        </TooltipContent>\n                      </Tooltip>\n                      <CopyButton\n                        value={trace.traceId}\n                        tooltipText=\"Copy Trace ID\"\n                        size=\"icon-xs\"\n                        onClick={(e) => e.stopPropagation()}\n                      />\n                    </div>\n                  </TableCell>\n                  <TableCell className=\"max-w-xs truncate\">{trace.rootSpanName}</TableCell>\n                  <TableCell className=\"font-mono text-xs\">{formatTimestamp(trace.startTime)}</TableCell>\n                  <TableCell className=\"font-mono text-xs\">{formatDuration(trace.durationMs)}</TableCell>\n                  <TableCell className=\"text-center\">{trace.spanCount}</TableCell>\n                </TableRow>\n              ))}\n            </TableBody>\n          </Table>\n        )}\n      </ScrollArea>\n\n      {data && data.totalPages > 1 && (\n        <div className=\"flex items-center justify-between\">\n          <span className=\"text-sm text-muted-foreground\">\n            Page {page} of {data.totalPages} ({data.total} total traces)\n          </span>\n          <div className=\"flex items-center gap-2\">\n            <Button variant=\"outline\" size=\"sm\" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>\n              <ChevronLeft className=\"h-4 w-4\" />\n              Previous\n            </Button>\n            <Button\n              variant=\"outline\"\n              size=\"sm\"\n              disabled={page >= data.totalPages}\n              onClick={() => setPage((p) => p + 1)}\n            >\n              Next\n              <ChevronRight className=\"h-4 w-4\" />\n            </Button>\n          </div>\n        </div>\n      )}\n\n      <TraceDetailsSheet\n        sandboxId={sandboxId}\n        traceId={selectedTraceId}\n        open={!!selectedTraceId}\n        onOpenChange={(open) => !open && setSelectedTraceId(null)}\n      />\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/telemetry/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport * from './LogsTab'\nexport * from './TracesTab'\nexport * from './TraceDetailsSheet'\nexport * from './MetricsTab'\nexport * from './TimeRangeSelector'\nexport * from './SeverityBadge'\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/accordion.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion'\nimport { ChevronDown } from 'lucide-react'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst Accordion = AccordionPrimitive.Root\n\nconst AccordionItem = ({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Item>) => (\n  <AccordionPrimitive.Item className={cn('border-b last:border-b-0', className)} {...props} />\n)\n\nconst AccordionTrigger = ({\n  className,\n  headerClassName,\n  children,\n  icon,\n  right,\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger> & {\n  icon?: React.ReactNode\n  headerClassName?: string\n  right?: React.ReactNode\n}) => (\n  <AccordionPrimitive.Header className={cn('flex items-center', headerClassName)}>\n    <AccordionPrimitive.Trigger\n      className={cn(\n        'flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      {icon === null ? null : icon || <ChevronDown className=\"h-4 w-4 shrink-0 transition-transform duration-200\" />}\n    </AccordionPrimitive.Trigger>\n    {right}\n  </AccordionPrimitive.Header>\n)\n\nconst AccordionContent = ({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) => (\n  <AccordionPrimitive.Content\n    className=\"overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n    {...props}\n  >\n    <div className={cn('pb-4 pt-0', className)}>{children}</div>\n  </AccordionPrimitive.Content>\n)\n\nexport { Accordion, AccordionContent, AccordionItem, AccordionTrigger }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/alert-dialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'\nimport * as React from 'react'\n\nimport { buttonVariants } from '@/components/ui/button'\nimport { cn } from '@/lib/utils'\nimport { VariantProps } from 'class-variance-authority'\n\nfunction AlertDialog({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {\n  return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />\n}\n\nfunction AlertDialogTrigger({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {\n  return <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n}\n\nfunction AlertDialogPortal({ ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {\n  return <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n}\n\nfunction AlertDialogOverlay({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {\n  return (\n    <AlertDialogPrimitive.Overlay\n      data-slot=\"alert-dialog-overlay\"\n      className={cn(\n        'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogContent({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {\n  return (\n    <AlertDialogPortal>\n      <AlertDialogOverlay />\n      <AlertDialogPrimitive.Content\n        data-slot=\"alert-dialog-content\"\n        className={cn(\n          'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-2xl',\n          className,\n        )}\n        {...props}\n      />\n    </AlertDialogPortal>\n  )\n}\n\nfunction AlertDialogHeader({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"alert-dialog-header\"\n      className={cn('flex flex-col gap-2 text-center sm:text-left', className)}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogFooter({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"alert-dialog-footer\"\n      className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogTitle({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n  return (\n    <AlertDialogPrimitive.Title\n      data-slot=\"alert-dialog-title\"\n      className={cn('text-lg font-semibold', className)}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n  return (\n    <AlertDialogPrimitive.Description\n      data-slot=\"alert-dialog-description\"\n      className={cn('text-muted-foreground text-sm', className)}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogAction({\n  className,\n  variant,\n  ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Action> & VariantProps<typeof buttonVariants>) {\n  return <AlertDialogPrimitive.Action className={cn(buttonVariants({ variant }), className)} {...props} />\n}\n\nfunction AlertDialogCancel({ className, ...props }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {\n  return <AlertDialogPrimitive.Cancel className={cn(buttonVariants({ variant: 'outline' }), className)} {...props} />\n}\n\nexport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogOverlay,\n  AlertDialogPortal,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/alert.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\nimport { Button } from './button'\n\nconst alertVariants = cva(\n  'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',\n  {\n    variants: {\n      variant: {\n        default: 'bg-card text-card-foreground',\n        destructive:\n          'text-destructive bg-destructive-background text-destructive-foreground border-destructive-separator',\n        info: 'bg-info-background text-info-foreground border-info-separator',\n        warning: 'bg-warning-background text-warning-foreground border-warning-separator',\n        success: 'bg-success-background text-success-foreground border-success-separator',\n        neutral: 'bg-muted/40 border-border',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n    },\n  },\n)\n\nfunction Alert({ className, variant, ...props }: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {\n  return <div data-slot=\"alert\" role=\"alert\" className={cn(alertVariants({ variant }), className)} {...props} />\n}\n\nfunction AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"alert-title\"\n      className={cn('col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight', className)}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDescription({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"alert-description\"\n      className={cn(\n        'text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed text-pretty',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertButton({ className, ...props }: React.ComponentProps<'button'>) {\n  return <Button data-slot=\"alert-button\" className={cn('', className)} {...props} />\n}\n\nexport { Alert, AlertButton, AlertDescription, AlertTitle }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/badge.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst badgeVariants = cva(\n  'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',\n  {\n    variants: {\n      variant: {\n        info: 'bg-info-background text-info-foreground border-info-separator',\n        warning: 'bg-warning-background text-warning-foreground border-warning-separator',\n        default: 'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',\n        secondary: 'border bg-secondary text-secondary-foreground hover:bg-secondary/80',\n        destructive:\n          'border-destructive-separator bg-destructive-background text-destructive-foreground hover:bg-destructive-background/80',\n        success:\n          'border-success-separator bg-success-background text-success-foreground hover:bg-success-background/80',\n        outline: 'text-foreground',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n    },\n  },\n)\n\nexport interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n  return <div className={cn(badgeVariants({ variant }), className)} {...props} />\n}\n\nexport { Badge, badgeVariants }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/button-group.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { Separator } from '@/components/ui/separator'\nimport { cn } from '@/lib/utils'\n\nconst buttonGroupVariants = cva(\n  \"has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-lg flex w-fit items-stretch *:focus-visible:z-10 *:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1\",\n  {\n    variants: {\n      orientation: {\n        horizontal:\n          '[&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-lg! [&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',\n        vertical:\n          '[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-lg! flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',\n      },\n    },\n    defaultVariants: {\n      orientation: 'horizontal',\n    },\n  },\n)\n\nfunction ButtonGroup({\n  className,\n  orientation,\n  ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof buttonGroupVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"button-group\"\n      data-orientation={orientation}\n      className={cn(buttonGroupVariants({ orientation }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction ButtonGroupText({\n  className,\n  asChild = false,\n  ...props\n}: React.ComponentProps<'div'> & {\n  asChild?: boolean\n}) {\n  const Comp = asChild ? Slot : 'div'\n\n  return (\n    <Comp\n      className={cn(\n        \"bg-muted gap-2 rounded-lg border px-2.5 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ButtonGroupSeparator({\n  className,\n  orientation = 'vertical',\n  ...props\n}: React.ComponentProps<typeof Separator>) {\n  return (\n    <Separator\n      data-slot=\"button-group-separator\"\n      orientation={orientation}\n      className={cn(\n        'bg-input relative self-stretch data-horizontal:mx-px data-horizontal:w-auto data-vertical:my-px data-vertical:h-auto',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/button.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-color disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n        destructive: 'bg-destructive text-white hover:bg-destructive/90',\n        outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n        secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n        ghost: 'hover:bg-accent hover:text-accent-foreground',\n        link: 'text-primary underline-offset-4 hover:underline',\n      },\n      size: {\n        default: 'h-8 px-4 py-2',\n        sm: 'h-8 rounded-md gap-1.5 px-3',\n        lg: 'h-10 rounded-md px-6',\n        icon: 'size-9',\n        'icon-xs': 'size-6',\n        'icon-sm': 'size-8 has-[>svg]:px-2',\n        'icon-lg': 'size-10',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n    },\n  },\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<'button'> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : 'button'\n\n  return <Comp data-slot=\"button\" className={cn(buttonVariants({ variant, size, className }))} {...props} />\n}\n\nexport { Button, buttonVariants }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/calendar.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\nimport { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from 'lucide-react'\nimport { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker'\n\nimport { cn } from '@/lib/utils'\nimport { Button, buttonVariants } from '@/components/ui/button'\n\nfunction Calendar({\n  className,\n  classNames,\n  showOutsideDays = true,\n  captionLayout = 'label',\n  buttonVariant = 'ghost',\n  formatters,\n  components,\n  ...props\n}: React.ComponentProps<typeof DayPicker> & {\n  buttonVariant?: React.ComponentProps<typeof Button>['variant']\n}) {\n  const defaultClassNames = getDefaultClassNames()\n\n  return (\n    <DayPicker\n      showOutsideDays={showOutsideDays}\n      className={cn(\n        'bg-background group/calendar p-3 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent',\n        String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n        String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n        className,\n      )}\n      captionLayout={captionLayout}\n      formatters={{\n        formatMonthDropdown: (date) => date.toLocaleString('default', { month: 'short' }),\n        ...formatters,\n      }}\n      classNames={{\n        root: cn('w-fit', defaultClassNames.root),\n        months: cn('relative flex flex-col gap-4 md:flex-row', defaultClassNames.months),\n        month: cn('flex w-full flex-col gap-4', defaultClassNames.month),\n        nav: cn('absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1', defaultClassNames.nav),\n        button_previous: cn(\n          buttonVariants({ variant: buttonVariant }),\n          'h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50',\n          defaultClassNames.button_previous,\n        ),\n        button_next: cn(\n          buttonVariants({ variant: buttonVariant }),\n          'h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50',\n          defaultClassNames.button_next,\n        ),\n        month_caption: cn(\n          'flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]',\n          defaultClassNames.month_caption,\n        ),\n        dropdowns: cn(\n          'flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium',\n          defaultClassNames.dropdowns,\n        ),\n        dropdown_root: cn(\n          'has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border',\n          defaultClassNames.dropdown_root,\n        ),\n        dropdown: cn('absolute inset-0 opacity-0', defaultClassNames.dropdown),\n        caption_label: cn(\n          'select-none font-medium',\n          captionLayout === 'label'\n            ? 'text-sm'\n            : '[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5',\n          defaultClassNames.caption_label,\n        ),\n        table: 'w-full border-collapse',\n        weekdays: cn('flex', defaultClassNames.weekdays),\n        weekday: cn(\n          'text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal',\n          defaultClassNames.weekday,\n        ),\n        week: cn('mt-2 flex w-full', defaultClassNames.week),\n        week_number_header: cn('w-[--cell-size] select-none', defaultClassNames.week_number_header),\n        week_number: cn('text-muted-foreground select-none text-[0.8rem]', defaultClassNames.week_number),\n        day: cn(\n          'group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md',\n          defaultClassNames.day,\n        ),\n        range_start: cn('bg-accent rounded-l-md', defaultClassNames.range_start),\n        range_middle: cn('rounded-none', defaultClassNames.range_middle),\n        range_end: cn('bg-accent rounded-r-md', defaultClassNames.range_end),\n        today: cn(\n          'bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none',\n          defaultClassNames.today,\n        ),\n        outside: cn('text-muted-foreground aria-selected:text-muted-foreground', defaultClassNames.outside),\n        disabled: cn('text-muted-foreground opacity-50', defaultClassNames.disabled),\n        hidden: cn('invisible', defaultClassNames.hidden),\n        ...classNames,\n      }}\n      components={{\n        Root: ({ className, rootRef, ...props }) => {\n          return <div data-slot=\"calendar\" ref={rootRef} className={cn('rounded-md', className)} {...props} />\n        },\n        Chevron: ({ className, orientation, ...props }) => {\n          if (orientation === 'left') {\n            return <ChevronLeftIcon className={cn('size-4', className)} {...props} />\n          }\n\n          if (orientation === 'right') {\n            return <ChevronRightIcon className={cn('size-4', className)} {...props} />\n          }\n\n          return <ChevronDownIcon className={cn('size-4', className)} {...props} />\n        },\n        DayButton: CalendarDayButton,\n        WeekNumber: ({ children, ...props }) => {\n          return (\n            <td {...props}>\n              <div className=\"flex size-[--cell-size] items-center justify-center text-center\">{children}</div>\n            </td>\n          )\n        },\n        ...components,\n      }}\n      {...props}\n    />\n  )\n}\n\nfunction CalendarDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>) {\n  const defaultClassNames = getDefaultClassNames()\n\n  const ref = React.useRef<HTMLButtonElement>(null)\n  React.useEffect(() => {\n    if (modifiers.focused) ref.current?.focus()\n  }, [modifiers.focused])\n\n  return (\n    <Button\n      ref={ref}\n      variant=\"ghost\"\n      size=\"icon\"\n      data-day={day.date.toLocaleDateString()}\n      data-selected-single={\n        modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle\n      }\n      data-range-start={modifiers.range_start}\n      data-range-end={modifiers.range_end}\n      data-range-middle={modifiers.range_middle}\n      className={cn(\n        'data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70',\n        defaultClassNames.day,\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Calendar, CalendarDayButton }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/card.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => (\n  <div ref={ref} className={cn('rounded-lg border bg-card text-card-foreground shadow-sm', className)} {...props} />\n))\nCard.displayName = 'Card'\n\nconst CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn('flex flex-col space-y-1.5 p-4 pb-2', className)} {...props} />\n  ),\n)\nCardHeader.displayName = 'CardHeader'\n\nconst CardTitle = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn('text-xl font-semibold leading-none tracking-tight', className)} {...props} />\n  ),\n)\nCardTitle.displayName = 'CardTitle'\n\nconst CardDescription = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props} />\n  ),\n)\nCardDescription.displayName = 'CardDescription'\n\nconst CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => <div ref={ref} className={cn('p-4 w-full', className)} {...props} />,\n)\nCardContent.displayName = 'CardContent'\n\nconst CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} className={cn('flex items-center p-4 border-t border-border', className)} {...props} />\n  ),\n)\nCardFooter.displayName = 'CardFooter'\n\nexport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/chart.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\nimport * as RechartsPrimitive from 'recharts'\n\nimport { cn } from '@/lib/utils'\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: '', dark: '.dark' } as const\n\nexport type ChartConfig = {\n  [k in string]: {\n    label?: React.ReactNode\n    icon?: React.ComponentType\n  } & ({ color?: string; theme?: never } | { color?: never; theme: Record<keyof typeof THEMES, string> })\n}\n\ntype ChartContextProps = {\n  config: ChartConfig\n}\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null)\n\nfunction useChart() {\n  const context = React.useContext(ChartContext)\n\n  if (!context) {\n    throw new Error('useChart must be used within a <ChartContainer />')\n  }\n\n  return context\n}\n\nconst ChartContainer = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentProps<'div'> & {\n    config: ChartConfig\n    children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>['children']\n  }\n>(({ id, className, children, config, ...props }, ref) => {\n  const uniqueId = React.useId()\n  const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`\n\n  return (\n    <ChartContext.Provider value={{ config }}>\n      <div\n        data-chart={chartId}\n        ref={ref}\n        className={cn(\n          \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none\",\n          className,\n        )}\n        {...props}\n      >\n        <ChartStyle id={chartId} config={config} />\n        <RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>\n      </div>\n    </ChartContext.Provider>\n  )\n})\nChartContainer.displayName = 'Chart'\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n  const colorConfig = Object.entries(config).filter(([, config]) => config.theme || config.color)\n\n  if (!colorConfig.length) {\n    return null\n  }\n\n  return (\n    <style\n      dangerouslySetInnerHTML={{\n        __html: Object.entries(THEMES)\n          .map(\n            ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n  .map(([key, itemConfig]) => {\n    const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] || itemConfig.color\n    return color ? `  --color-${key}: ${color};` : null\n  })\n  .join('\\n')}\n}\n`,\n          )\n          .join('\\n'),\n      }}\n    />\n  )\n}\n\nconst ChartTooltip = RechartsPrimitive.Tooltip\n\nconst ChartTooltipContent = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\n    React.ComponentProps<'div'> & {\n      hideLabel?: boolean\n      hideIndicator?: boolean\n      indicator?: 'line' | 'dot' | 'dashed'\n      nameKey?: string\n      labelKey?: string\n      valueFormatter?: (value: number | string | Array<number | string>) => React.ReactNode\n    }\n>(\n  (\n    {\n      active,\n      payload,\n      className,\n      indicator = 'dot',\n      hideLabel = false,\n      hideIndicator = false,\n      label,\n      labelFormatter,\n      labelClassName,\n      formatter,\n      color,\n      nameKey,\n      labelKey,\n      valueFormatter,\n    },\n    ref,\n  ) => {\n    const { config } = useChart()\n\n    const tooltipLabel = React.useMemo(() => {\n      if (hideLabel || !payload?.length) {\n        return null\n      }\n\n      const [item] = payload\n      const key = `${labelKey || item?.dataKey || item?.name || 'value'}`\n      const itemConfig = getPayloadConfigFromPayload(config, item, key)\n      const value =\n        !labelKey && typeof label === 'string'\n          ? config[label as keyof typeof config]?.label || label\n          : itemConfig?.label\n\n      if (labelFormatter) {\n        return <div className={cn('font-medium', labelClassName)}>{labelFormatter(value, payload)}</div>\n      }\n\n      if (!value) {\n        return null\n      }\n\n      return <div className={cn('font-medium', labelClassName)}>{value}</div>\n    }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey])\n\n    if (!active || !payload?.length) {\n      return null\n    }\n\n    const nestLabel = payload.length === 1 && indicator !== 'dot'\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\n          'grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl',\n          className,\n        )}\n      >\n        {!nestLabel ? tooltipLabel : null}\n        <div className=\"grid gap-1.5\">\n          {payload.map((item, index) => {\n            const key = `${nameKey || item.name || item.dataKey || 'value'}`\n            const itemConfig = getPayloadConfigFromPayload(config, item, key)\n            const indicatorColor = color || item.payload.fill || item.color\n\n            return (\n              <div\n                key={item.dataKey}\n                className={cn(\n                  'flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground',\n                  indicator === 'dot' && 'items-center',\n                )}\n              >\n                {formatter && item?.value !== undefined && item.name ? (\n                  formatter(item.value, item.name, item, index, item.payload)\n                ) : (\n                  <>\n                    {itemConfig?.icon ? (\n                      <itemConfig.icon />\n                    ) : (\n                      !hideIndicator && (\n                        <div\n                          className={cn('shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]', {\n                            'h-2.5 w-2.5': indicator === 'dot',\n                            'w-1': indicator === 'line',\n                            'w-0 border-[1.5px] border-dashed bg-transparent': indicator === 'dashed',\n                            'my-0.5': nestLabel && indicator === 'dashed',\n                          })}\n                          style={\n                            {\n                              '--color-bg': indicatorColor,\n                              '--color-border': indicatorColor,\n                            } as React.CSSProperties\n                          }\n                        />\n                      )\n                    )}\n                    <div\n                      className={cn(\n                        'flex flex-1 justify-between gap-4 leading-none',\n                        nestLabel ? 'items-end' : 'items-center',\n                      )}\n                    >\n                      <div className=\"grid gap-1.5\">\n                        {nestLabel ? tooltipLabel : null}\n                        <span className=\"text-muted-foreground\">{itemConfig?.label || item.name}</span>\n                      </div>\n                      {item.value && (\n                        <span className=\"font-mono font-medium tabular-nums text-foreground\">\n                          {valueFormatter ? valueFormatter(item.value) : item.value.toLocaleString()}\n                        </span>\n                      )}\n                    </div>\n                  </>\n                )}\n              </div>\n            )\n          })}\n        </div>\n      </div>\n    )\n  },\n)\nChartTooltipContent.displayName = 'ChartTooltip'\n\nconst ChartLegend = RechartsPrimitive.Legend\n\nconst ChartLegendContent = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentProps<'div'> &\n    Pick<RechartsPrimitive.LegendProps, 'payload' | 'verticalAlign'> & {\n      hideIcon?: boolean\n      nameKey?: string\n    }\n>(({ className, hideIcon = false, payload, verticalAlign = 'bottom', nameKey }, ref) => {\n  const { config } = useChart()\n\n  if (!payload?.length) {\n    return null\n  }\n\n  return (\n    <div\n      ref={ref}\n      className={cn('flex items-center justify-center gap-4', verticalAlign === 'top' ? 'pb-3' : 'pt-3', className)}\n    >\n      {payload.map((item) => {\n        const key = `${nameKey || item.dataKey || 'value'}`\n        const itemConfig = getPayloadConfigFromPayload(config, item, key)\n\n        return (\n          <div\n            key={item.value}\n            className={cn('flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground')}\n          >\n            {itemConfig?.icon && !hideIcon ? (\n              <itemConfig.icon />\n            ) : (\n              <div\n                className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n                style={{\n                  backgroundColor: item.color,\n                }}\n              />\n            )}\n            {itemConfig?.label}\n          </div>\n        )\n      })}\n    </div>\n  )\n})\nChartLegendContent.displayName = 'ChartLegend'\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {\n  if (typeof payload !== 'object' || payload === null) {\n    return undefined\n  }\n\n  const payloadPayload =\n    'payload' in payload && typeof payload.payload === 'object' && payload.payload !== null\n      ? payload.payload\n      : undefined\n\n  let configLabelKey: string = key\n\n  if (key in payload && typeof payload[key as keyof typeof payload] === 'string') {\n    configLabelKey = payload[key as keyof typeof payload] as string\n  } else if (\n    payloadPayload &&\n    key in payloadPayload &&\n    typeof payloadPayload[key as keyof typeof payloadPayload] === 'string'\n  ) {\n    configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string\n  }\n\n  return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config]\n}\n\nexport { ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/checkbox.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as CheckboxPrimitive from '@radix-ui/react-checkbox'\nimport { CheckIcon, MinusIcon } from 'lucide-react'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n  return (\n    <CheckboxPrimitive.Root\n      data-slot=\"checkbox\"\n      className={cn(\n        'peer group border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',\n        className,\n      )}\n      {...props}\n    >\n      <CheckboxPrimitive.Indicator\n        data-slot=\"checkbox-indicator\"\n        className=\"grid place-content-center text-current transition-none\"\n      >\n        <MinusIcon className=\"hidden size-2.5 group-data-[state=indeterminate]:block\" />\n        <CheckIcon className=\"hidden size-3.5 group-data-[state=checked]:block\" />\n      </CheckboxPrimitive.Indicator>\n    </CheckboxPrimitive.Root>\n  )\n}\n\nexport { Checkbox }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/command.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n'use client'\n\nimport { Command as CommandPrimitive } from 'cmdk'\nimport { Check, SearchIcon } from 'lucide-react'\nimport * as React from 'react'\n\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'\nimport { cn } from '@/lib/utils'\n\nfunction Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\n        'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandDialog({\n  title = 'Command Palette',\n  description = 'Search for a command to run...',\n  children,\n  className,\n  showCloseButton = false,\n  overlay,\n  ref,\n  ...props\n}: React.ComponentProps<typeof Dialog> & {\n  title?: string\n  overlay?: React.ReactNode\n  description?: string\n  className?: string\n  showCloseButton?: boolean\n  ref?: React.RefObject<HTMLDivElement>\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent\n        className={cn('overflow-hidden p-0 [&_[data-slot=dialog-close]]:hidden', className)}\n        overlay={overlay}\n        ref={ref}\n      >\n        {children}\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction CommandInputButton({ className, ...props }: React.ComponentProps<'button'>) {\n  return <button className={cn('text-sm text-muted-foreground hover:text-foreground px-2', className)} {...props} />\n}\n\nconst CommandInput = React.forwardRef<\n  React.ComponentRef<typeof CommandPrimitive.Input>,\n  React.ComponentProps<typeof CommandPrimitive.Input> & { icon?: React.ReactNode }\n>(({ className, children, icon, ...props }, ref) => {\n  return (\n    <div data-slot=\"command-input-wrapper\" className=\"flex items-center gap-2 border-b px-3\">\n      {icon !== null ? icon || <SearchIcon className=\"size-4 shrink-0 opacity-50\" /> : null}\n      <CommandPrimitive.Input\n        ref={ref}\n        data-slot=\"command-input\"\n        className={cn(\n          'placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none disabled:cursor-not-allowed disabled:opacity-50',\n          className,\n        )}\n        {...props}\n      />\n      {children}\n    </div>\n  )\n})\nCommandInput.displayName = 'CommandInput'\n\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(\n        'max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto scrollbar-thin scrollbar-thumb-border scrollbar-track-background',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandEmpty({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return (\n    <CommandPrimitive.Empty\n      data-slot=\"command-empty\"\n      className={cn('py-6 text-center text-sm', className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        'text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn('bg-border -mx-1 h-px', className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandShortcut({ className, ...props }: React.ComponentProps<'span'>) {\n  return (\n    <span\n      data-slot=\"command-shortcut\"\n      className={cn('text-muted-foreground ml-auto text-xs tracking-widest', className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandCheckboxItem({\n  className,\n  children,\n  checked,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item> & { checked: boolean }) {\n  return (\n    <CommandItem {...props}>\n      <div className=\"flex items-center\">\n        <div\n          className={cn('mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary', {\n            'bg-primary text-primary-foreground': checked,\n            'opacity-50 [&_svg]:invisible': !checked,\n          })}\n        >\n          <Check className={cn('size-3.5 text-current')} />\n        </div>\n        {children}\n      </div>\n    </CommandItem>\n  )\n}\n\nexport {\n  Command,\n  CommandCheckboxItem,\n  CommandDialog,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandInputButton,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n  CommandShortcut,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/data-table-faceted-filter.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Column } from '@tanstack/react-table'\nimport { PlusCircle } from 'lucide-react'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\nimport { Badge } from './badge'\nimport { Button } from './button'\nimport {\n  Command,\n  CommandCheckboxItem,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n} from './command'\nimport { Popover, PopoverContent, PopoverTrigger } from './popover'\nimport { Separator } from './separator'\n\ninterface DataTableFacetedFilterProps<TData, TValue> {\n  column?: Column<TData, TValue>\n  title?: string\n  options: FacetedFilterOption[]\n  className?: string\n}\n\nexport type FacetedFilterOption = {\n  label: string\n  value: string\n  icon?: React.ComponentType<{ className?: string }>\n}\n\nexport function DataTableFacetedFilter<TData, TValue>({\n  column,\n  title,\n  options,\n  className,\n}: DataTableFacetedFilterProps<TData, TValue>) {\n  const facets = column?.getFacetedUniqueValues()\n  const selectedValues = new Set(column?.getFilterValue() as string[])\n\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button\n          variant=\"outline\"\n          size=\"sm\"\n          className={cn(\n            'border-dashed',\n            {\n              '!pr-1': selectedValues?.size,\n            },\n            className,\n          )}\n        >\n          <PlusCircle />\n          {title}\n          {selectedValues?.size > 0 && (\n            <>\n              <Separator orientation=\"vertical\" className=\"mx-2 h-4\" />\n              <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-normal lg:hidden\">\n                {selectedValues.size}\n              </Badge>\n              <div className=\"hidden space-x-1 lg:flex\">\n                {selectedValues.size > 2 ? (\n                  <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-normal\">\n                    {selectedValues.size} selected\n                  </Badge>\n                ) : (\n                  options\n                    .filter((option) => selectedValues.has(option.value))\n                    .map((option) => (\n                      <Badge variant=\"secondary\" key={option.value} className=\"rounded-sm px-1 font-normal\">\n                        {option.label}\n                      </Badge>\n                    ))\n                )}\n              </div>\n            </>\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-[200px] p-0\" align=\"start\">\n        <Command>\n          <CommandInput placeholder={title} />\n          <CommandList>\n            <CommandEmpty>No results found.</CommandEmpty>\n            <CommandGroup>\n              {options.map((option) => {\n                const isSelected = selectedValues.has(option.value)\n                return (\n                  <CommandCheckboxItem\n                    checked={isSelected}\n                    key={option.value}\n                    onSelect={() => {\n                      if (isSelected) {\n                        selectedValues.delete(option.value)\n                      } else {\n                        selectedValues.add(option.value)\n                      }\n                      const filterValues = Array.from(selectedValues)\n                      column?.setFilterValue(filterValues.length ? filterValues : undefined)\n                    }}\n                  >\n                    {option.icon && <option.icon className=\"mr-2 h-4 w-4 text-muted-foreground\" />}\n                    <span>{option.label}</span>\n                    {facets?.get(option.value) && (\n                      <span className=\"ml-auto flex h-4 w-4 items-center justify-center font-mono text-xs\">\n                        {facets.get(option.value)}\n                      </span>\n                    )}\n                  </CommandCheckboxItem>\n                )\n              })}\n            </CommandGroup>\n            {selectedValues.size > 0 && (\n              <>\n                <CommandSeparator />\n                <CommandGroup>\n                  <CommandItem\n                    onSelect={() => column?.setFilterValue(undefined)}\n                    className=\"justify-center text-center\"\n                  >\n                    Clear filters\n                  </CommandItem>\n                </CommandGroup>\n              </>\n            )}\n          </CommandList>\n        </Command>\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/date-picker.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { format } from 'date-fns'\nimport { Calendar as CalendarIcon, X } from 'lucide-react'\n\nimport { Calendar } from '@/components/ui/calendar'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { InputGroup, InputGroupAddon, InputGroupButton } from './input-group'\n\ninterface DatePickerProps {\n  value?: Date\n  onChange: (date?: Date) => void\n  required?: boolean\n  disabledBefore?: Date\n  id?: string\n}\n\nexport function DatePicker({ value, onChange, required, disabledBefore, id }: DatePickerProps) {\n  const handleClear = (e: React.MouseEvent) => {\n    e.stopPropagation()\n    onChange(undefined)\n  }\n\n  return (\n    <Popover>\n      <InputGroup className=\"overflow-clip\">\n        <PopoverTrigger\n          data-slot=\"input-group-control\"\n          id={id}\n          data-empty={!value}\n          className=\"flex flex-1 data-[empty=true]:text-muted-foreground justify-between text-left font-normal focus-visible:outline-none pl-2 h-full\"\n        >\n          <div className=\"flex items-center gap-2 text-sm\">\n            <CalendarIcon className=\"h-4 w-4\" />\n            {value ? format(value, 'PPP') : <span>Select date</span>}\n          </div>\n        </PopoverTrigger>\n        {value && (\n          <InputGroupAddon align=\"inline-end\">\n            <InputGroupButton type=\"button\" size=\"icon-xs\" onClick={handleClear}>\n              <X className=\"h-3 w-3\" />\n            </InputGroupButton>\n          </InputGroupAddon>\n        )}\n      </InputGroup>\n\n      <PopoverContent className=\"w-auto p-0\" align=\"start\">\n        <Calendar\n          mode=\"single\"\n          selected={value}\n          onSelect={onChange}\n          required={required}\n          disabled={(() => {\n            const conditions = []\n            if (disabledBefore) {\n              conditions.push({ before: disabledBefore })\n            }\n            return conditions\n          })()}\n        />\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/date-range-picker.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Button } from '@/components/ui/button'\nimport { Calendar } from '@/components/ui/calendar'\nimport { Input } from '@/components/ui/input'\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'\nimport { cn } from '@/lib/utils'\nimport { format, subDays, subHours, subMinutes } from 'date-fns'\nimport { CalendarIcon } from 'lucide-react'\nimport { forwardRef, useEffect, useImperativeHandle, useState } from 'react'\nimport { DateRange } from 'react-day-picker'\n\n// Simple configuration object\nexport interface QuickRangesConfig {\n  minutes?: number[]\n  hours?: number[]\n  days?: number[]\n  months?: number[]\n  years?: number[]\n}\n\nconst createTimeRangesFromConfig = (config: QuickRangesConfig) => {\n  const ranges: Array<{ label: string; getRange: () => DateRange }> = []\n\n  // Generate ranges from config\n  for (const unit in config) {\n    const values = config[unit as keyof QuickRangesConfig]\n    if (!values || !Array.isArray(values)) continue\n\n    values.forEach((value) => {\n      const unitLabel = value === 1 ? unit.slice(0, -1) : unit // Remove 's' for singular\n      ranges.push({\n        label: `Last ${value} ${unitLabel}`,\n        getRange: () => {\n          const now = new Date()\n          switch (unit) {\n            case 'minutes':\n              return { from: subMinutes(now, value), to: now }\n            case 'hours':\n              return { from: subHours(now, value), to: now }\n            case 'days':\n              return { from: subDays(now, value), to: now }\n            case 'months':\n              return { from: subDays(now, value * 30), to: now }\n            case 'years':\n              return { from: subDays(now, value * 365), to: now }\n            default:\n              return { from: now, to: now }\n          }\n        },\n      })\n    })\n  }\n\n  return ranges\n}\n\nexport interface DateRangePickerProps {\n  value?: DateRange\n  onChange?: (range: DateRange) => void\n  quickRangesEnabled?: boolean\n  quickRanges?: QuickRangesConfig\n  className?: string\n  timeSelection?: boolean\n  disabled?: boolean\n  defaultSelectedQuickRange?: string\n  contentAlign?: 'start' | 'end'\n}\n\nexport interface DateRangePickerRef {\n  getCurrentRange: () => DateRange\n}\n\nexport const DateRangePicker = forwardRef<DateRangePickerRef, DateRangePickerProps>(\n  (\n    {\n      value,\n      onChange,\n      quickRangesEnabled = false,\n      quickRanges = {},\n      className,\n      timeSelection = true,\n      disabled = false,\n      defaultSelectedQuickRange,\n      contentAlign = 'start',\n    },\n    ref,\n  ) => {\n    const [isOpen, setIsOpen] = useState(false)\n    const [selectedQuickRange, setSelectedQuickRange] = useState<string | null>(defaultSelectedQuickRange ?? null)\n    const [fromTime, setFromTime] = useState<string>('00:00:00')\n    const [toTime, setToTime] = useState<string>('23:59:59')\n\n    // Internal state to track the current selection for preview\n    const [internalRange, setInternalRange] = useState<DateRange>(value || { from: undefined, to: undefined })\n\n    // Expose methods to parent component\n    useImperativeHandle(\n      ref,\n      () => ({\n        getCurrentRange: (): DateRange => {\n          // Always return fresh range for relative selections\n          if (selectedQuickRange && selectedQuickRange !== 'All time') {\n            const matchingRange = createTimeRangesFromConfig(quickRanges).find(\n              (timeRange) => timeRange.label === selectedQuickRange,\n            )\n            if (matchingRange) {\n              return matchingRange.getRange() // Fresh timestamps every time!\n            }\n          }\n          // For custom ranges or \"All time\", return the current value\n          return value || { from: undefined, to: undefined }\n        },\n      }),\n      [selectedQuickRange, quickRanges, value],\n    )\n\n    // Sync internal state when parent value changes\n    useEffect(() => {\n      setInternalRange(value || { from: undefined, to: undefined })\n    }, [value])\n\n    const handleQuickRangeSelect = (range: DateRange, label: string) => {\n      setSelectedQuickRange(label)\n      setInternalRange(range) // Update internal state for preview\n      onChange?.(range) // Notify parent immediately\n      setIsOpen(false)\n    }\n\n    const handleCustomRangeChange = (range: DateRange | undefined) => {\n      if (range) {\n        setSelectedQuickRange(null) // Clear quick range when using custom\n        setInternalRange(range) // Update internal state for preview\n        // Removed onChange call - only apply when button is clicked\n      }\n    }\n\n    const handleTimeChange = (time: string, isFrom: boolean) => {\n      if (isFrom) {\n        setFromTime(time)\n      } else {\n        setToTime(time)\n      }\n\n      // Removed immediate application - only apply when button is clicked\n      // Time changes are now stored in state but not sent to parent until Apply is clicked\n    }\n\n    const formatRange = (range: DateRange) => {\n      // If a quick range is selected, show its label\n      if (selectedQuickRange) return selectedQuickRange\n\n      // Check if this is \"All time\" (no date restriction)\n      if (!range.from && !range.to) return 'Select date range'\n\n      // Helper function to format a date with or without time\n      const formatDate = (date: Date) => {\n        if (timeSelection) {\n          return `${format(date, 'MMM dd, yyyy')}, ${fromTime}`\n        }\n        return format(date, 'MMM dd, yyyy')\n      }\n\n      // Show custom date range with or without time\n      if (range.from && range.to) {\n        if (timeSelection) {\n          // For custom ranges with time, show the actual time that will be applied\n          return `${format(range.from, 'MMM dd, yyyy')}, ${fromTime} - ${format(range.to, 'MMM dd, yyyy')}, ${toTime}`\n        }\n        return `${format(range.from, 'MMM dd, yyyy')} - ${format(range.to, 'MMM dd, yyyy')}`\n      } else if (range.from) {\n        return `${formatDate(range.from)} - ...`\n      }\n\n      return 'Select date range'\n    }\n\n    return (\n      <Popover open={isOpen} onOpenChange={setIsOpen}>\n        <PopoverTrigger asChild>\n          <Button\n            variant=\"outline\"\n            className={cn(\n              'flex w-full justify-between text-left font-normal hover:bg-background',\n              !internalRange?.from && 'text-muted-foreground',\n              className,\n              disabled && 'opacity-50 cursor-not-allowed',\n            )}\n            disabled={disabled}\n          >\n            <div className=\"flex items-center gap-2\">\n              <CalendarIcon className=\"h-4 w-4\" />\n              {internalRange?.from ? formatRange(internalRange) : <span>Select date range</span>}\n            </div>\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"w-auto p-0\" align={contentAlign}>\n          <div className=\"flex\">\n            {/* Quick ranges panel */}\n            {quickRangesEnabled && (\n              <div className=\"w-64 p-4 border-r\">\n                <div className=\"text-sm font-medium mb-3 text-center\">Quick ranges</div>\n                <div className=\"space-y-1 max-h-[400px] overflow-y-auto overflow-x-hidden [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-muted-foreground/20 [&::-webkit-scrollbar-thumb]:rounded-full\">\n                  <button\n                    className={cn(\n                      'w-full text-left px-3 py-2 text-sm rounded-md transition-colors',\n                      selectedQuickRange === 'All time' ? 'bg-primary text-primary-foreground' : 'hover:bg-muted',\n                    )}\n                    onClick={() => handleQuickRangeSelect({ from: undefined, to: undefined }, 'All time')}\n                  >\n                    All time\n                  </button>\n                  {createTimeRangesFromConfig(quickRanges || {}).map((timeRange) => (\n                    <button\n                      key={timeRange.label}\n                      className={cn(\n                        'w-full text-left px-3 py-2 text-sm rounded-md transition-colors',\n                        selectedQuickRange === timeRange.label\n                          ? 'bg-primary text-primary-foreground'\n                          : 'hover:bg-muted',\n                      )}\n                      onClick={() => handleQuickRangeSelect(timeRange.getRange(), timeRange.label)}\n                    >\n                      {timeRange.label}\n                    </button>\n                  ))}\n                </div>\n              </div>\n            )}\n\n            {/* Custom range panel */}\n            <div className=\"w-auto p-4\">\n              <h3 className=\"font-semibold text-sm mb-3 text-center\">Custom range</h3>\n              {/* <p className=\"text-xs text-muted-foreground mb-4\">\n              Click and drag to select a date range, or click two dates\n            </p> */}\n\n              <div className=\"w-fit mx-auto\">\n                <Calendar\n                  mode=\"range\"\n                  selected={internalRange}\n                  onSelect={handleCustomRangeChange}\n                  numberOfMonths={1}\n                  disabled={{ after: new Date() }}\n                />\n              </div>\n\n              {/* Time selection */}\n              {timeSelection && (\n                <div className=\"mt-3\">\n                  <div className=\"space-y-3\">\n                    <div className=\"flex items-center gap-3\">\n                      <label className=\"w-8 text-sm font-medium text-foreground text-left\">From</label>\n                      <Input\n                        type=\"time\"\n                        value={fromTime}\n                        onChange={(e) => handleTimeChange(e.target.value, true)}\n                        step=\"1\"\n                        className=\"w-2/3\"\n                      />\n                    </div>\n                    <div className=\"flex items-center gap-3\">\n                      <label className=\"w-8 text-sm font-medium text-foreground text-left\">To</label>\n                      <Input\n                        type=\"time\"\n                        value={toTime}\n                        onChange={(e) => handleTimeChange(e.target.value, false)}\n                        step=\"1\"\n                        className=\"w-2/3\"\n                      />\n                    </div>\n                  </div>\n                </div>\n              )}\n\n              {/* Action buttons */}\n              <div className=\"flex justify-center mt-4\">\n                <Button\n                  variant=\"default\"\n                  size=\"sm\"\n                  className=\"w-auto px-4\"\n                  onClick={() => {\n                    const applyTimeToDate = (date: Date, timeStr: string) => {\n                      const [hours, minutes, seconds] = timeStr.split(':').map((str) => parseInt(str, 10))\n                      return new Date(date.getFullYear(), date.getMonth(), date.getDate(), hours, minutes, seconds || 0)\n                    }\n                    const finalRange: DateRange = {\n                      from: applyTimeToDate(internalRange.from || new Date(), fromTime),\n                      to: applyTimeToDate(internalRange.to || new Date(), toTime),\n                    }\n                    onChange?.(finalRange)\n                    setIsOpen(false)\n                  }}\n                >\n                  Apply time range\n                </Button>\n              </div>\n            </div>\n          </div>\n        </PopoverContent>\n      </Popover>\n    )\n  },\n)\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/dialog.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { XIcon } from 'lucide-react'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n  return (\n    <DialogPrimitive.Overlay\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  overlay,\n  ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content> & {\n  showCloseButton?: boolean\n  overlay?: React.ReactNode\n}) {\n  return (\n    <DialogPortal data-slot=\"dialog-portal\">\n      {overlay !== null ? overlay || <DialogOverlay /> : null}\n      <DialogPrimitive.Content\n        data-slot=\"dialog-content\"\n        className={cn(\n          'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] fixed top-[50%] left-[50%] z-50 flex max-h-[80vh] w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] flex-col gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',\n          className,\n        )}\n        {...props}\n      >\n        {children}\n        <DialogPrimitive.Close\n          data-slot=\"dialog-close\"\n          className=\"ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\"\n        >\n          <XIcon />\n          <span className=\"sr-only\">Close</span>\n        </DialogPrimitive.Close>\n      </DialogPrimitive.Content>\n    </DialogPortal>\n  )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn('flex flex-col gap-2 text-center sm:text-left', className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn('text-lg leading-none font-semibold', className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogDescription({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Description>) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn('text-muted-foreground text-sm', className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/drawer.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as React from 'react'\nimport { Drawer as DrawerPrimitive } from 'vaul'\n\nimport { cn } from '@/lib/utils'\n\nfunction Drawer({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n  return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\n}\n\nfunction DrawerTrigger({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n  return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\n}\n\nfunction DrawerPortal({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n  return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\n}\n\nfunction DrawerClose({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n  return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\n}\n\nfunction DrawerOverlay({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n  return (\n    <DrawerPrimitive.Overlay\n      data-slot=\"drawer-overlay\"\n      className={cn(\n        'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DrawerContent({ className, children, ...props }: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n  return (\n    <DrawerPortal data-slot=\"drawer-portal\">\n      <DrawerOverlay />\n      <DrawerPrimitive.Content\n        data-slot=\"drawer-content\"\n        className={cn(\n          'group/drawer-content bg-background fixed z-50 flex h-auto flex-col',\n          'data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b',\n          'data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t',\n          'data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm',\n          'data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm',\n          className,\n        )}\n        {...props}\n      >\n        <div className=\"bg-muted mx-auto my-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\n        {children}\n      </DrawerPrimitive.Content>\n    </DrawerPortal>\n  )\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"drawer-header\"\n      className={cn(\n        'flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {\n  return <div data-slot=\"drawer-footer\" className={cn('mt-auto flex flex-col gap-2 p-4', className)} {...props} />\n}\n\nfunction DrawerTitle({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n  return (\n    <DrawerPrimitive.Title\n      data-slot=\"drawer-title\"\n      className={cn('text-foreground font-semibold', className)}\n      {...props}\n    />\n  )\n}\n\nfunction DrawerDescription({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n  return (\n    <DrawerPrimitive.Description\n      data-slot=\"drawer-description\"\n      className={cn('text-muted-foreground text-sm', className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Drawer,\n  DrawerClose,\n  DrawerContent,\n  DrawerDescription,\n  DrawerFooter,\n  DrawerHeader,\n  DrawerOverlay,\n  DrawerPortal,\n  DrawerTitle,\n  DrawerTrigger,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/dropdown-menu.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport { Check, ChevronRight, Circle } from 'lucide-react'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst DropdownMenu = DropdownMenuPrimitive.Root\n\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\nconst DropdownMenuPortal = DropdownMenuPrimitive.Portal\n\nconst DropdownMenuSub = DropdownMenuPrimitive.Sub\n\nconst DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownMenuSubTrigger = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n    inset?: boolean\n  }\n>(({ className, inset, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.SubTrigger\n    ref={ref}\n    className={cn(\n      'flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n      inset && 'pl-8',\n      className,\n    )}\n    {...props}\n  >\n    {children}\n    <ChevronRight className=\"ml-auto\" />\n  </DropdownMenuPrimitive.SubTrigger>\n))\nDropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName\n\nconst DropdownMenuSubContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.SubContent\n    ref={ref}\n    className={cn(\n      'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n      className,\n    )}\n    {...props}\n  />\n))\nDropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownMenuContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n  <DropdownMenuPrimitive.Portal>\n    <DropdownMenuPrimitive.Content\n      ref={ref}\n      sideOffset={sideOffset}\n      className={cn(\n        'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n        className,\n      )}\n      {...props}\n    />\n  </DropdownMenuPrimitive.Portal>\n))\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nconst DropdownMenuItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n    inset?: boolean\n    variant?: 'default' | 'destructive'\n  }\n>(({ className, inset, variant = 'default', ...props }, ref) => (\n  <DropdownMenuPrimitive.Item\n    ref={ref}\n    data-variant={variant}\n    className={cn(\n      'relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n      'data-[variant=destructive]:text-destructive-foreground data-[variant=destructive]:focus:bg-destructive-background dark:data-[variant=destructive]:focus:bg-destructive-background data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:*:[svg]:text-destructive-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground',\n      inset && 'pl-8',\n      className,\n    )}\n    {...props}\n  />\n))\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName\n\nconst DropdownMenuCheckboxItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n  <DropdownMenuPrimitive.CheckboxItem\n    ref={ref}\n    className={cn(\n      'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n      className,\n    )}\n    checked={checked}\n    {...props}\n  >\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <DropdownMenuPrimitive.ItemIndicator>\n        <Check className=\"h-4 w-4\" />\n      </DropdownMenuPrimitive.ItemIndicator>\n    </span>\n    {children}\n  </DropdownMenuPrimitive.CheckboxItem>\n))\nDropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName\n\nconst DropdownMenuRadioItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.RadioItem\n    ref={ref}\n    className={cn(\n      'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n      className,\n    )}\n    {...props}\n  >\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <DropdownMenuPrimitive.ItemIndicator>\n        <Circle className=\"h-2 w-2 fill-current\" />\n      </DropdownMenuPrimitive.ItemIndicator>\n    </span>\n    {children}\n  </DropdownMenuPrimitive.RadioItem>\n))\nDropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\nconst DropdownMenuLabel = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n    inset?: boolean\n  }\n>(({ className, inset, ...props }, ref) => (\n  <DropdownMenuPrimitive.Label\n    ref={ref}\n    className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}\n    {...props}\n  />\n))\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\nconst DropdownMenuSeparator = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />\n))\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\nconst DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {\n  return <span className={cn('ml-auto text-xs tracking-widest opacity-60', className)} {...props} />\n}\nDropdownMenuShortcut.displayName = 'DropdownMenuShortcut'\n\nexport {\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuPortal,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/empty.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst emptyVariants = cva(\n  'gap-4 rounded-xl border-dashed p-6 flex w-full min-w-0 flex-1 flex-col items-center justify-center text-center text-balance',\n  {\n    variants: {\n      variant: {\n        default: 'bg-card text-card-foreground',\n        destructive: 'bg-destructive-background text-destructive-foreground border-destructive-separator',\n        info: 'bg-info-background text-info-foreground border-info-separator',\n        warning: 'bg-warning-background text-warning-foreground border-warning-separator',\n        success: 'bg-success-background text-success-foreground border-success-separator',\n        neutral: 'bg-muted/40 border-border',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n    },\n  },\n)\n\nfunction Empty({ className, variant, ...props }: React.ComponentProps<'div'> & VariantProps<typeof emptyVariants>) {\n  return <div data-slot=\"empty\" className={cn(emptyVariants({ variant }), className)} {...props} />\n}\n\nfunction EmptyHeader({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div data-slot=\"empty-header\" className={cn('gap-2 flex max-w-sm flex-col items-center', className)} {...props} />\n  )\n}\n\nconst emptyMediaVariants = cva(\n  'mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0',\n  {\n    variants: {\n      variant: {\n        default: 'bg-transparent',\n        icon: \"bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-4\",\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n    },\n  },\n)\n\nfunction EmptyMedia({\n  className,\n  variant = 'default',\n  ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof emptyMediaVariants>) {\n  return (\n    <div\n      data-slot=\"empty-icon\"\n      data-variant={variant}\n      className={cn(emptyMediaVariants({ variant, className }))}\n      {...props}\n    />\n  )\n}\n\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<'div'>) {\n  return <div data-slot=\"empty-title\" className={cn('text-sm font-medium tracking-tight', className)} {...props} />\n}\n\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<'p'>) {\n  return (\n    <p\n      data-slot=\"empty-description\"\n      className={cn(\n        'text-sm/relaxed text-muted-foreground [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction EmptyContent({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"empty-content\"\n      className={cn('gap-2.5 text-sm flex w-full max-w-sm min-w-0 flex-col items-center text-balance', className)}\n      {...props}\n    />\n  )\n}\n\nexport { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, emptyVariants }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/facet-filter.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PlusCircle } from 'lucide-react'\n\nimport { cn } from '@/lib/utils'\nimport { Badge } from './badge'\nimport { Button } from './button'\nimport {\n  Command,\n  CommandCheckboxItem,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n} from './command'\nimport { FacetedFilterOption } from './data-table-faceted-filter'\nimport { Popover, PopoverContent, PopoverTrigger } from './popover'\nimport { Separator } from './separator'\n\ninterface FacetFilterProps {\n  title: string\n  options: FacetedFilterOption[]\n  selectedValues: Set<string>\n  className?: string\n  setSelectedValues: (values: Set<string>) => void\n}\n\nexport function FacetFilter({ title, options, selectedValues, setSelectedValues, className }: FacetFilterProps) {\n  return (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\" size=\"sm\" className={cn('h-10 border-dashed', className)}>\n          <PlusCircle />\n          {title}\n          {selectedValues?.size > 0 && (\n            <>\n              <Separator orientation=\"vertical\" className=\"mx-2 h-4\" />\n              <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-normal lg:hidden\">\n                {selectedValues.size}\n              </Badge>\n              <div className=\"hidden space-x-1 lg:flex\">\n                {selectedValues.size > 2 ? (\n                  <Badge variant=\"secondary\" className=\"rounded-sm px-1 font-normal\">\n                    {selectedValues.size} selected\n                  </Badge>\n                ) : (\n                  options\n                    .filter((option) => selectedValues.has(option.value))\n                    .map((option) => (\n                      <Badge variant=\"secondary\" key={option.value} className=\"rounded-sm px-1 font-normal\">\n                        {option.label}\n                      </Badge>\n                    ))\n                )}\n              </div>\n            </>\n          )}\n        </Button>\n      </PopoverTrigger>\n      <PopoverContent className=\"w-[200px] p-0\" align=\"start\">\n        <Command>\n          <CommandInput placeholder={title} />\n          <CommandList>\n            <CommandEmpty>No results found.</CommandEmpty>\n            <CommandGroup>\n              {options.map((option) => {\n                const isSelected = selectedValues.has(option.value)\n                return (\n                  <CommandCheckboxItem\n                    checked={isSelected}\n                    key={option.value}\n                    onSelect={() => {\n                      if (isSelected) {\n                        selectedValues.delete(option.value)\n                      } else {\n                        selectedValues.add(option.value)\n                      }\n                      setSelectedValues(new Set(selectedValues))\n                    }}\n                  >\n                    {option.icon && <option.icon className=\"mr-2 h-4 w-4 text-muted-foreground\" />}\n                    <span>{option.label}</span>\n                  </CommandCheckboxItem>\n                )\n              })}\n            </CommandGroup>\n            {selectedValues.size > 0 && (\n              <>\n                <CommandSeparator />\n                <CommandGroup>\n                  <CommandItem onSelect={() => setSelectedValues(new Set())} className=\"justify-center text-center\">\n                    Clear filters\n                  </CommandItem>\n                </CommandGroup>\n              </>\n            )}\n          </CommandList>\n        </Command>\n      </PopoverContent>\n    </Popover>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/field.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { useMemo } from 'react'\n\nimport { Slot } from '@radix-ui/react-slot'\n\nimport { Label } from '@/components/ui/label'\nimport { Separator } from '@/components/ui/separator'\nimport { cn } from '@/lib/utils'\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\n  return (\n    <fieldset\n      data-slot=\"field-set\"\n      className={cn(\n        'flex flex-col gap-6',\n        'has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldLegend({\n  className,\n  variant = 'legend',\n  ...props\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\n  return (\n    <legend\n      data-slot=\"field-legend\"\n      data-variant={variant}\n      className={cn('mb-3 font-medium', 'data-[variant=legend]:text-base', 'data-[variant=label]:text-sm', className)}\n      {...props}\n    />\n  )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"field-group\"\n      className={cn(\n        'group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nconst fieldVariants = cva('group/field flex w-full gap-2 data-[invalid=true]:text-destructive', {\n  variants: {\n    orientation: {\n      vertical: ['flex-col [&>*]:w-full [&>.sr-only]:w-auto'],\n      horizontal: [\n        'flex-row items-center',\n        '[&>[data-slot=field-label]]:flex-auto',\n        'has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n      ],\n      responsive: [\n        'flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto',\n        '@md/field-group:[&>[data-slot=field-label]]:flex-auto',\n        '@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\n      ],\n    },\n  },\n  defaultVariants: {\n    orientation: 'vertical',\n  },\n})\n\nfunction Field({\n  className,\n  orientation = 'vertical',\n  ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"field\"\n      data-orientation={orientation}\n      className={cn(fieldVariants({ orientation }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"field-content\"\n      className={cn('group/field-content flex flex-1 flex-col gap-1.5 leading-snug', className)}\n      {...props}\n    />\n  )\n}\n\nfunction FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>) {\n  return (\n    <Label\n      data-slot=\"field-label\"\n      className={cn(\n        'group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 text-foreground',\n        'has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4',\n        'has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"field-label\"\n      className={cn(\n        'flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldDescription({ className, asChild = false, ...props }: React.ComponentProps<'p'> & { asChild?: boolean }) {\n  const Comp = asChild ? Slot : 'p'\n  return (\n    <Comp\n      data-slot=\"field-description\"\n      className={cn(\n        'text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance',\n        'last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5',\n        '[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldSeparator({\n  children,\n  className,\n  ...props\n}: React.ComponentProps<'div'> & {\n  children?: React.ReactNode\n}) {\n  return (\n    <div\n      data-slot=\"field-separator\"\n      data-content={!!children}\n      className={cn('relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2', className)}\n      {...props}\n    >\n      <Separator className=\"absolute inset-0 top-1/2\" />\n      {children && (\n        <span\n          className=\"bg-background text-muted-foreground relative mx-auto block w-fit px-2\"\n          data-slot=\"field-separator-content\"\n        >\n          {children}\n        </span>\n      )}\n    </div>\n  )\n}\n\nfunction FieldError({\n  className,\n  children,\n  errors,\n  ...props\n}: React.ComponentProps<'div'> & {\n  errors?: Array<{ message?: string } | undefined>\n}) {\n  const content = useMemo(() => {\n    if (children) {\n      return children\n    }\n\n    if (!errors?.length) {\n      return null\n    }\n\n    const uniqueErrors = [...new Map(errors.map((error) => [error?.message, error])).values()]\n\n    if (uniqueErrors?.length == 1) {\n      return uniqueErrors[0]?.message\n    }\n\n    return (\n      <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n        {uniqueErrors.map((error, index) => error?.message && <li key={index}>{error.message}</li>)}\n      </ul>\n    )\n  }, [children, errors])\n\n  if (!content) {\n    return null\n  }\n\n  return (\n    <div\n      role=\"alert\"\n      data-slot=\"field-error\"\n      className={cn('text-destructive text-sm font-normal', className)}\n      {...props}\n    >\n      {content}\n    </div>\n  )\n}\n\nexport {\n  Field,\n  FieldContent,\n  FieldDescription,\n  FieldError,\n  FieldGroup,\n  FieldLabel,\n  FieldLegend,\n  FieldSeparator,\n  FieldSet,\n  FieldTitle,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/input-group.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Textarea } from '@/components/ui/textarea'\nimport { cn } from '@/lib/utils'\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot=\"input-group\"\n      role=\"group\"\n      className={cn(\n        'group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none',\n        'h-9 min-w-0 has-[>textarea]:h-auto',\n\n        // Variants based on alignment.\n        'has-[>[data-align=inline-start]]:[&>input]:pl-2',\n        'has-[>[data-align=inline-end]]:[&>input]:pr-2',\n        'has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3',\n        'has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3',\n\n        // Focus state.\n        'has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]',\n\n        // Error state.\n        'has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40',\n\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupAddonVariants = cva(\n  \"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50\",\n  {\n    variants: {\n      align: {\n        'inline-start': 'order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]',\n        'inline-end': 'order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]',\n        'block-start':\n          'order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5',\n        'block-end': 'order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5',\n      },\n    },\n    defaultVariants: {\n      align: 'inline-start',\n    },\n  },\n)\n\nfunction InputGroupAddon({\n  className,\n  align = 'inline-start',\n  ...props\n}: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"input-group-addon\"\n      data-align={align}\n      className={cn(inputGroupAddonVariants({ align }), className)}\n      onClick={(e) => {\n        if ((e.target as HTMLElement).closest('button')) {\n          return\n        }\n        e.currentTarget.parentElement?.querySelector('input')?.focus()\n      }}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupButtonVariants = cva(\n  'text-sm shadow-none flex gap-2 items-center data-[slot=input-group-button]:[&:not(:last-child)]:mr-1',\n  {\n    variants: {\n      size: {\n        xs: \"h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2\",\n        sm: 'h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5',\n        'icon-xs': 'size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0',\n        'icon-sm': 'size-8 p-0 has-[>svg]:p-0',\n      },\n    },\n    defaultVariants: {\n      size: 'xs',\n    },\n  },\n)\n\nfunction InputGroupButton({\n  className,\n  type = 'button',\n  variant = 'ghost',\n  size = 'xs',\n  ...props\n}: Omit<React.ComponentProps<typeof Button>, 'size'> & VariantProps<typeof inputGroupButtonVariants>) {\n  return (\n    <Button\n      type={type}\n      data-slot=\"input-group-button\"\n      data-size={size}\n      variant={variant}\n      className={cn(inputGroupButtonVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {\n  return (\n    <span\n      className={cn(\n        \"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupInput({ className, ...props }: React.ComponentProps<'input'>) {\n  return (\n    <Input\n      data-slot=\"input-group-control\"\n      className={cn(\n        'flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupTextarea({ className, ...props }: React.ComponentProps<'textarea'>) {\n  return (\n    <Textarea\n      data-slot=\"input-group-control\"\n      className={cn(\n        'flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/input.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Input({ className, type, ...props }: React.ComponentProps<'input'>) {\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      className={cn(\n        'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-8 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',\n        'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',\n        'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Input }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/kbd.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\n\nfunction Kbd({ className, ...props }: React.ComponentProps<'kbd'>) {\n  return (\n    <kbd\n      data-slot=\"kbd\"\n      className={cn(\n        'bg-muted text-muted-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none',\n        \"[&_svg:not([class*='size-'])]:size-3\",\n        '[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction KbdGroup({ className, ...props }: React.ComponentProps<'div'>) {\n  return <kbd data-slot=\"kbd-group\" className={cn('inline-flex items-center gap-1', className)} {...props} />\n}\n\nexport { Kbd, KbdGroup }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/label.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\nimport * as LabelPrimitive from '@radix-ui/react-label'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from '@/lib/utils'\n\nconst labelVariants = cva('text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70')\n\nconst Label = React.forwardRef<\n  React.ElementRef<typeof LabelPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n  <LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />\n))\nLabel.displayName = LabelPrimitive.Root.displayName\n\nexport { Label }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/popover.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as PopoverPrimitive from '@radix-ui/react-popover'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n  return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n  return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n  className,\n  align = 'center',\n  sideOffset = 4,\n  ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n  return (\n    <PopoverPrimitive.Portal>\n      <PopoverPrimitive.Content\n        data-slot=\"popover-content\"\n        align={align}\n        sideOffset={sideOffset}\n        className={cn(\n          'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n          className,\n        )}\n        {...props}\n      />\n    </PopoverPrimitive.Portal>\n  )\n}\n\nfunction PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n  return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />\n}\n\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<'div'>) {\n  return <div data-slot=\"popover-header\" className={cn('flex flex-col gap-0.5 text-sm', className)} {...props} />\n}\n\nfunction PopoverTitle({ className, ...props }: React.ComponentProps<'h2'>) {\n  return <div data-slot=\"popover-title\" className={cn('font-medium', className)} {...props} />\n}\n\nfunction PopoverDescription({ className, ...props }: React.ComponentProps<'p'>) {\n  return <p data-slot=\"popover-description\" className={cn('text-muted-foreground', className)} {...props} />\n}\n\nexport { Popover, PopoverAnchor, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/radio-group.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { Circle } from 'lucide-react'\n\nimport { cn } from '@/lib/utils'\n\nconst RadioGroup = React.forwardRef<\n  React.ElementRef<typeof RadioGroupPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>\n>(({ className, ...props }, ref) => {\n  return <RadioGroupPrimitive.Root className={cn('grid gap-2', className)} {...props} ref={ref} />\n})\nRadioGroup.displayName = RadioGroupPrimitive.Root.displayName\n\nconst RadioGroupItem = React.forwardRef<\n  React.ElementRef<typeof RadioGroupPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>\n>(({ className, ...props }, ref) => {\n  return (\n    <RadioGroupPrimitive.Item\n      ref={ref}\n      className={cn(\n        'aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n        className,\n      )}\n      {...props}\n    >\n      <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n        <Circle className=\"h-2.5 w-2.5 fill-current text-current\" />\n      </RadioGroupPrimitive.Indicator>\n    </RadioGroupPrimitive.Item>\n  )\n})\nRadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName\n\nexport { RadioGroup, RadioGroupItem }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/scroll-area.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area'\nimport { RefObject, useEffect, useRef } from 'react'\nimport { useResizeObserver } from 'usehooks-ts'\n\nimport { cn } from '@/lib/utils'\n\nconst updateScrollOffsets = (viewport: HTMLElement | null, root: HTMLElement | null) => {\n  if (!viewport || !root) {\n    return\n  }\n\n  const { scrollTop, scrollHeight, clientHeight } = viewport\n  const top = scrollTop\n  const bottom = scrollHeight - clientHeight - scrollTop\n\n  root.style.setProperty('--offset-y-top', `${top}`)\n  root.style.setProperty('--offset-y-bottom', `${bottom}`)\n}\n\nfunction ScrollArea({\n  className,\n  children,\n  fade,\n  horizontal,\n  fadeOffset = 25,\n  ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.Root> & {\n  fade?: 'mask' | 'shadow'\n  fadeOffset?: number\n  horizontal?: boolean\n}) {\n  const rootRef = useRef<HTMLDivElement>(null)\n  const viewportRef = useRef<HTMLDivElement>(null)\n\n  useResizeObserver({\n    ref: viewportRef as RefObject<HTMLElement>,\n    onResize: () => updateScrollOffsets(viewportRef.current, rootRef.current),\n  })\n\n  useEffect(() => {\n    updateScrollOffsets(viewportRef.current, rootRef.current)\n  }, [])\n\n  return (\n    <ScrollAreaPrimitive.Root\n      ref={rootRef}\n      data-slot=\"scroll-area\"\n      style={\n        {\n          '--fade-offset': fadeOffset !== undefined ? `${fadeOffset}px` : '30px',\n          ...props.style,\n        } as React.CSSProperties\n      }\n      className={cn(\n        'relative group/scroll-area',\n        {\n          'before:pointer-events-none before:absolute before:top-0 before:left-0 before:right-0 before:z-10 before:[height:var(--fade-offset)] before:bg-gradient-to-b dark:before:from-black/20 before:from-black/10 before:to-transparent before:transition-opacity before:duration-150 before:opacity-[min(1,calc(var(--offset-y-top)/20))]':\n            fade === 'shadow',\n          'after:pointer-events-none after:absolute after:bottom-0 after:left-0 after:right-0 after:z-10 after:[height:var(--fade-offset)] after:bg-gradient-to-t dark:after:from-black/20 after:from-black/10 after:to-transparent after:transition-opacity after:duration-150 after:opacity-[min(1,calc(var(--offset-y-bottom)/20))]':\n            fade === 'shadow',\n        },\n        className,\n      )}\n      {...props}\n    >\n      <ScrollAreaPrimitive.Viewport\n        ref={viewportRef}\n        onScroll={(e) => {\n          updateScrollOffsets(e.currentTarget, rootRef.current)\n        }}\n        data-slot=\"scroll-area-viewport\"\n        className={cn(\n          'focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&>div]:!block',\n          {\n            '[mask-image:linear-gradient(to_bottom,transparent,black_min(var(--offset-y-top)*1px,var(--fade-offset)),black_calc(100%-min(var(--offset-y-bottom)*1px,var(--fade-offset))),transparent)]':\n              fade === 'mask',\n          },\n        )}\n      >\n        {children}\n      </ScrollAreaPrimitive.Viewport>\n      <ScrollBar />\n      {horizontal && <ScrollBar orientation=\"horizontal\" />}\n      <ScrollAreaPrimitive.Corner />\n    </ScrollAreaPrimitive.Root>\n  )\n}\n\nfunction ScrollBar({\n  className,\n  orientation = 'vertical',\n  ...props\n}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {\n  return (\n    <ScrollAreaPrimitive.ScrollAreaScrollbar\n      data-slot=\"scroll-area-scrollbar\"\n      orientation={orientation}\n      className={cn(\n        'flex touch-none p-px transition-colors select-none',\n        {\n          'h-full w-2.5 border-l border-l-transparent': orientation === 'vertical',\n          'h-2.5 flex-col border-t border-t-transparent': orientation === 'horizontal',\n        },\n        className,\n      )}\n      {...props}\n    >\n      <ScrollAreaPrimitive.ScrollAreaThumb\n        data-slot=\"scroll-area-thumb\"\n        className=\"bg-border relative flex-1 rounded-full\"\n      />\n    </ScrollAreaPrimitive.ScrollAreaScrollbar>\n  )\n}\n\nexport { ScrollArea, ScrollBar }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/select.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as SelectPrimitive from '@radix-ui/react-select'\nimport { Check, ChevronDown, ChevronUp } from 'lucide-react'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst Select = SelectPrimitive.Root\n\nconst SelectGroup = SelectPrimitive.Group\n\nconst SelectValue = SelectPrimitive.Value\n\nconst SelectTrigger = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Trigger>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & {\n    loading?: boolean\n    size?: 'xs' | 'sm' | 'default'\n  }\n>(({ className, children, loading, size = 'default', ...props }, ref) => (\n  <SelectPrimitive.Trigger\n    ref={ref}\n    data-size={size}\n    className={cn(\n      'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground disabled:opacity-50 [&>span]:line-clamp-1 data-[size=sm]:h-8 data-[size=xs]:h-7 outline-none',\n      'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',\n      loading ? 'disabled:cursor-progress' : 'disabled:cursor-not-allowed',\n      className,\n    )}\n    {...props}\n  >\n    {children}\n    <SelectPrimitive.Icon asChild>\n      <ChevronDown className=\"h-4 w-4 opacity-50\" />\n    </SelectPrimitive.Icon>\n  </SelectPrimitive.Trigger>\n))\nSelectTrigger.displayName = SelectPrimitive.Trigger.displayName\n\nconst SelectScrollUpButton = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.ScrollUpButton\n    ref={ref}\n    className={cn('flex cursor-default items-center justify-center py-1', className)}\n    {...props}\n  >\n    <ChevronUp className=\"h-4 w-4\" />\n  </SelectPrimitive.ScrollUpButton>\n))\nSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName\n\nconst SelectScrollDownButton = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.ScrollDownButton\n    ref={ref}\n    className={cn('flex cursor-default items-center justify-center py-1', className)}\n    {...props}\n  >\n    <ChevronDown className=\"h-4 w-4\" />\n  </SelectPrimitive.ScrollDownButton>\n))\nSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName\n\nconst SelectContent = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>\n>(({ className, children, position = 'popper', ...props }, ref) => (\n  <SelectPrimitive.Portal>\n    <SelectPrimitive.Content\n      ref={ref}\n      className={cn(\n        'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n        position === 'popper' &&\n          'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n        className,\n      )}\n      position={position}\n      {...props}\n    >\n      <SelectScrollUpButton />\n      <SelectPrimitive.Viewport\n        className={cn(\n          'p-1',\n          position === 'popper' &&\n            'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]',\n        )}\n      >\n        {children}\n      </SelectPrimitive.Viewport>\n      <SelectScrollDownButton />\n    </SelectPrimitive.Content>\n  </SelectPrimitive.Portal>\n))\nSelectContent.displayName = SelectPrimitive.Content.displayName\n\nconst SelectLabel = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Label>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.Label ref={ref} className={cn('py-1.5 pl-8 pr-2 text-sm font-semibold', className)} {...props} />\n))\nSelectLabel.displayName = SelectPrimitive.Label.displayName\n\nconst SelectItem = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n  <SelectPrimitive.Item\n    ref={ref}\n    className={cn(\n      'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n      className,\n    )}\n    {...props}\n  >\n    <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n      <SelectPrimitive.ItemIndicator>\n        <Check className=\"h-4 w-4\" />\n      </SelectPrimitive.ItemIndicator>\n    </span>\n\n    <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n  </SelectPrimitive.Item>\n))\nSelectItem.displayName = SelectPrimitive.Item.displayName\n\nconst SelectSeparator = React.forwardRef<\n  React.ElementRef<typeof SelectPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <SelectPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />\n))\nSelectSeparator.displayName = SelectPrimitive.Separator.displayName\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/separator.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as SeparatorPrimitive from '@radix-ui/react-separator'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst Separator = React.forwardRef<\n  React.ElementRef<typeof SeparatorPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>\n>(({ className, orientation = 'horizontal', decorative = true, ...props }, ref) => (\n  <SeparatorPrimitive.Root\n    ref={ref}\n    data-slot=\"separator\"\n    decorative={decorative}\n    orientation={orientation}\n    className={cn('shrink-0 bg-border', orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]', className)}\n    {...props}\n  />\n))\nSeparator.displayName = SeparatorPrimitive.Root.displayName\n\nexport { Separator }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/sheet.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as SheetPrimitive from '@radix-ui/react-dialog'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { X } from 'lucide-react'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst Sheet = SheetPrimitive.Root\n\nconst SheetTrigger = SheetPrimitive.Trigger\n\nconst SheetClose = SheetPrimitive.Close\n\nconst SheetPortal = SheetPrimitive.Portal\n\nconst SheetOverlay = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Overlay>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Overlay\n    className={cn(\n      'fixed inset-0 z-50 bg-black/20  data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n      className,\n    )}\n    {...props}\n    ref={ref}\n  />\n))\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName\n\nconst sheetVariants = cva(\n  'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-200 data-[state=open]:duration-300',\n  {\n    variants: {\n      side: {\n        top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',\n        bottom:\n          'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',\n        left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',\n        right:\n          'inset-y-0 right-0 h-full w-3/4  border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right',\n      },\n    },\n    defaultVariants: {\n      side: 'right',\n    },\n  },\n)\n\ninterface SheetContentProps\n  extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,\n    VariantProps<typeof sheetVariants> {}\n\nconst SheetContent = React.forwardRef<React.ElementRef<typeof SheetPrimitive.Content>, SheetContentProps>(\n  ({ side = 'right', className, children, ...props }, ref) => (\n    <SheetPortal>\n      <SheetOverlay />\n      <SheetPrimitive.Content ref={ref} className={cn(sheetVariants({ side }), className)} {...props}>\n        {children}\n        <SheetPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary\">\n          <X className=\"h-4 w-4\" />\n          <span className=\"sr-only\">Close</span>\n        </SheetPrimitive.Close>\n      </SheetPrimitive.Content>\n    </SheetPortal>\n  ),\n)\nSheetContent.displayName = SheetPrimitive.Content.displayName\n\nconst SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn('flex flex-col space-y-2 text-center sm:text-left', className)} {...props} />\n)\nSheetHeader.displayName = 'SheetHeader'\n\nconst SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (\n  <div className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)} {...props} />\n)\nSheetFooter.displayName = 'SheetFooter'\n\nconst SheetTitle = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Title>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Title ref={ref} className={cn('text-lg font-semibold text-foreground', className)} {...props} />\n))\nSheetTitle.displayName = SheetPrimitive.Title.displayName\n\nconst SheetDescription = React.forwardRef<\n  React.ElementRef<typeof SheetPrimitive.Description>,\n  React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n  <SheetPrimitive.Description ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props} />\n))\nSheetDescription.displayName = SheetPrimitive.Description.displayName\n\nexport {\n  Sheet,\n  SheetClose,\n  SheetContent,\n  SheetDescription,\n  SheetFooter,\n  SheetHeader,\n  SheetOverlay,\n  SheetPortal,\n  SheetTitle,\n  SheetTrigger,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/sidebar.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Slot } from '@radix-ui/react-slot'\nimport { VisuallyHidden } from '@radix-ui/react-visually-hidden'\nimport { VariantProps, cva } from 'class-variance-authority'\nimport { PanelLeft } from 'lucide-react'\nimport * as React from 'react'\n\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Separator } from '@/components/ui/separator'\nimport { Sheet, SheetContent, SheetDescription, SheetTitle } from '@/components/ui/sheet'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'\nimport { useIsMobile } from '@/hooks/use-mobile'\nimport { cn } from '@/lib/utils'\n\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state'\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = '16rem'\nconst SIDEBAR_WIDTH_MOBILE = '18rem'\nconst SIDEBAR_WIDTH_ICON = '3rem'\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b'\n\ntype SidebarContext = {\n  state: 'expanded' | 'collapsed'\n  open: boolean\n  setOpen: (open: boolean) => void\n  openMobile: boolean\n  setOpenMobile: (open: boolean) => void\n  isMobile: boolean\n  toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContext | null>(null)\n\nfunction useSidebar() {\n  const context = React.useContext(SidebarContext)\n  if (!context) {\n    throw new Error('useSidebar must be used within a SidebarProvider.')\n  }\n\n  return context\n}\n\nconst SidebarProvider = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentProps<'div'> & {\n    defaultOpen?: boolean\n    open?: boolean\n    onOpenChange?: (open: boolean) => void\n    isBannerVisible: boolean\n  }\n>(\n  (\n    {\n      defaultOpen = true,\n      open: openProp,\n      onOpenChange: setOpenProp,\n      className,\n      style,\n      children,\n      isBannerVisible,\n      ...props\n    },\n    ref,\n  ) => {\n    const isMobile = useIsMobile()\n    const [openMobile, setOpenMobile] = React.useState(false)\n\n    // This is the internal state of the sidebar.\n    // We use openProp and setOpenProp for control from outside the component.\n    const [_open, _setOpen] = React.useState(defaultOpen)\n    const open = openProp ?? _open\n    const setOpen = React.useCallback(\n      (value: boolean | ((value: boolean) => boolean)) => {\n        const openState = typeof value === 'function' ? value(open) : value\n        if (setOpenProp) {\n          setOpenProp(openState)\n        } else {\n          _setOpen(openState)\n        }\n\n        // This sets the cookie to keep the sidebar state.\n        document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n      },\n      [setOpenProp, open],\n    )\n\n    // Helper to toggle the sidebar.\n    const toggleSidebar = React.useCallback(() => {\n      return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n    }, [isMobile, setOpen, setOpenMobile])\n\n    // Adds a keyboard shortcut to toggle the sidebar.\n    React.useEffect(() => {\n      const handleKeyDown = (event: KeyboardEvent) => {\n        if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {\n          event.preventDefault()\n          toggleSidebar()\n        }\n      }\n\n      window.addEventListener('keydown', handleKeyDown)\n      return () => window.removeEventListener('keydown', handleKeyDown)\n    }, [toggleSidebar])\n\n    // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n    // This makes it easier to style the sidebar with Tailwind classes.\n    const state = open ? 'expanded' : 'collapsed'\n\n    const contextValue = React.useMemo<SidebarContext>(\n      () => ({\n        state,\n        open,\n        setOpen,\n        isMobile,\n        openMobile,\n        setOpenMobile,\n        toggleSidebar,\n      }),\n      [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],\n    )\n\n    return (\n      <SidebarContext.Provider value={contextValue}>\n        <div\n          style={\n            {\n              '--sidebar-width': SIDEBAR_WIDTH,\n              '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\n              ...style,\n            } as React.CSSProperties\n          }\n          className={cn(\n            'group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar',\n            isBannerVisible ? 'pt-16 md:pt-0' : '',\n            className,\n          )}\n          ref={ref}\n          {...props}\n        >\n          {children}\n        </div>\n      </SidebarContext.Provider>\n    )\n  },\n)\nSidebarProvider.displayName = 'SidebarProvider'\n\nconst Sidebar = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentProps<'div'> & {\n    side?: 'left' | 'right'\n    variant?: 'sidebar' | 'floating' | 'inset'\n    collapsible?: 'offcanvas' | 'icon' | 'none'\n    isBannerVisible: boolean\n  }\n>(\n  (\n    { side = 'left', variant = 'sidebar', collapsible = 'offcanvas', className, children, isBannerVisible, ...props },\n    ref,\n  ) => {\n    const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n\n    if (collapsible === 'none') {\n      return (\n        <div\n          className={cn('flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground', className)}\n          ref={ref}\n          {...props}\n        >\n          {children}\n        </div>\n      )\n    }\n\n    if (isMobile) {\n      return (\n        <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n          <SheetContent\n            data-sidebar=\"sidebar\"\n            data-mobile=\"true\"\n            className=\"w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n            style={\n              {\n                '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\n              } as React.CSSProperties\n            }\n            side={side}\n          >\n            <VisuallyHidden>\n              <SheetTitle>Sidebar</SheetTitle>\n              <SheetDescription>Includes navigation to different pages in the application.</SheetDescription>\n            </VisuallyHidden>\n            <div className=\"flex h-full w-full flex-col\">{children}</div>\n          </SheetContent>\n        </Sheet>\n      )\n    }\n\n    return (\n      <div\n        ref={ref}\n        className=\"group peer hidden md:block text-sidebar-foreground\"\n        data-state={state}\n        data-collapsible={state === 'collapsed' ? collapsible : ''}\n        data-variant={variant}\n        data-side={side}\n      >\n        {/* This is what handles the sidebar gap on desktop */}\n        <div\n          className={cn(\n            'duration-200 relative h-svh w-[--sidebar-width] bg-transparent transition-[width] ease-linear',\n            'group-data-[collapsible=offcanvas]:w-0',\n            'group-data-[side=right]:rotate-180',\n            variant === 'floating' || variant === 'inset'\n              ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'\n              : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',\n          )}\n        />\n        <div\n          className={cn(\n            'duration-200 fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] ease-linear md:flex',\n            isBannerVisible ? 'md:top-12 md:bottom-0 md:h-[calc(100svh-3rem)]' : '',\n            side === 'left'\n              ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'\n              : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',\n            // Adjust the padding for floating and inset variants.\n            variant === 'floating' || variant === 'inset'\n              ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'\n              : 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',\n            className,\n          )}\n          {...props}\n        >\n          <div\n            data-sidebar=\"sidebar\"\n            className=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow\"\n          >\n            {children}\n          </div>\n        </div>\n      </div>\n    )\n  },\n)\nSidebar.displayName = 'Sidebar'\n\nconst SidebarTrigger = React.forwardRef<React.ElementRef<typeof Button>, React.ComponentProps<typeof Button>>(\n  ({ className, onClick, ...props }, ref) => {\n    const { toggleSidebar } = useSidebar()\n\n    return (\n      <Button\n        ref={ref}\n        data-sidebar=\"trigger\"\n        variant=\"ghost\"\n        size=\"icon\"\n        className={cn('h-5 w-5', className)}\n        onClick={(event) => {\n          onClick?.(event)\n          toggleSidebar()\n        }}\n        {...props}\n      >\n        <PanelLeft size={20} strokeWidth={1.5} className=\"w-5 h-5\" />\n        <span className=\"sr-only\">Toggle Sidebar</span>\n      </Button>\n    )\n  },\n)\nSidebarTrigger.displayName = 'SidebarTrigger'\n\nconst SidebarRail = React.forwardRef<HTMLButtonElement, React.ComponentProps<'button'>>(\n  ({ className, ...props }, ref) => {\n    const { toggleSidebar } = useSidebar()\n\n    return (\n      <button\n        ref={ref}\n        data-sidebar=\"rail\"\n        aria-label=\"Toggle Sidebar\"\n        tabIndex={-1}\n        onClick={toggleSidebar}\n        title=\"Toggle Sidebar\"\n        className={cn(\n          'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',\n          '[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize',\n          '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\n          'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar',\n          '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\n          '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\n          className,\n        )}\n        {...props}\n      />\n    )\n  },\n)\nSidebarRail.displayName = 'SidebarRail'\n\nconst SidebarInset = React.forwardRef<HTMLDivElement, React.ComponentProps<'main'>>(({ className, ...props }, ref) => {\n  return (\n    <main\n      ref={ref}\n      className={cn(\n        'relative flex min-h-svh flex-1 flex-col bg-background',\n        'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',\n        className,\n      )}\n      {...props}\n    />\n  )\n})\nSidebarInset.displayName = 'SidebarInset'\n\nconst SidebarInput = React.forwardRef<React.ElementRef<typeof Input>, React.ComponentProps<typeof Input>>(\n  ({ className, ...props }, ref) => {\n    return (\n      <Input\n        ref={ref}\n        data-sidebar=\"input\"\n        className={cn(\n          'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',\n          className,\n        )}\n        {...props}\n      />\n    )\n  },\n)\nSidebarInput.displayName = 'SidebarInput'\n\nconst SidebarHeader = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(({ className, ...props }, ref) => {\n  return <div ref={ref} data-sidebar=\"header\" className={cn('flex flex-col gap-2 p-2', className)} {...props} />\n})\nSidebarHeader.displayName = 'SidebarHeader'\n\nconst SidebarFooter = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(({ className, ...props }, ref) => {\n  return <div ref={ref} data-sidebar=\"footer\" className={cn('flex flex-col gap-2 p-2', className)} {...props} />\n})\nSidebarFooter.displayName = 'SidebarFooter'\n\nconst SidebarSeparator = React.forwardRef<React.ElementRef<typeof Separator>, React.ComponentProps<typeof Separator>>(\n  ({ className, ...props }, ref) => {\n    return (\n      <Separator\n        ref={ref}\n        data-sidebar=\"separator\"\n        className={cn('mx-3 w-auto bg-sidebar-border', className)}\n        {...props}\n      />\n    )\n  },\n)\nSidebarSeparator.displayName = 'SidebarSeparator'\n\nconst SidebarContent = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(({ className, ...props }, ref) => {\n  return (\n    <div ref={ref} data-sidebar=\"content\" className={cn('flex min-h-0 flex-1 flex-col gap-1', className)} {...props} />\n  )\n})\nSidebarContent.displayName = 'SidebarContent'\n\nconst SidebarGroup = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(({ className, ...props }, ref) => {\n  return (\n    <div\n      ref={ref}\n      data-sidebar=\"group\"\n      className={cn('relative flex w-full min-w-0 flex-col p-2', className)}\n      {...props}\n    />\n  )\n})\nSidebarGroup.displayName = 'SidebarGroup'\n\nconst SidebarGroupLabel = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'> & { asChild?: boolean }>(\n  ({ className, asChild = false, ...props }, ref) => {\n    const Comp = asChild ? Slot : 'div'\n\n    return (\n      <Comp\n        ref={ref}\n        data-sidebar=\"group-label\"\n        className={cn(\n          'duration-200 flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n          'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',\n          className,\n        )}\n        {...props}\n      />\n    )\n  },\n)\nSidebarGroupLabel.displayName = 'SidebarGroupLabel'\n\nconst SidebarGroupAction = React.forwardRef<HTMLButtonElement, React.ComponentProps<'button'> & { asChild?: boolean }>(\n  ({ className, asChild = false, ...props }, ref) => {\n    const Comp = asChild ? Slot : 'button'\n\n    return (\n      <Comp\n        ref={ref}\n        data-sidebar=\"group-action\"\n        className={cn(\n          'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n          // Increases the hit area of the button on mobile.\n          'after:absolute after:-inset-2 after:md:hidden',\n          'group-data-[collapsible=icon]:hidden',\n          className,\n        )}\n        {...props}\n      />\n    )\n  },\n)\nSidebarGroupAction.displayName = 'SidebarGroupAction'\n\nconst SidebarGroupContent = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(\n  ({ className, ...props }, ref) => (\n    <div ref={ref} data-sidebar=\"group-content\" className={cn('w-full text-sm', className)} {...props} />\n  ),\n)\nSidebarGroupContent.displayName = 'SidebarGroupContent'\n\nconst SidebarMenu = React.forwardRef<HTMLUListElement, React.ComponentProps<'ul'>>(({ className, ...props }, ref) => (\n  <ul ref={ref} data-sidebar=\"menu\" className={cn('flex w-full min-w-0 flex-col gap-1', className)} {...props} />\n))\nSidebarMenu.displayName = 'SidebarMenu'\n\nconst SidebarMenuItem = React.forwardRef<HTMLLIElement, React.ComponentProps<'li'>>(({ className, ...props }, ref) => (\n  <li ref={ref} data-sidebar=\"menu-item\" className={cn('group/menu-item relative', className)} {...props} />\n))\nSidebarMenuItem.displayName = 'SidebarMenuItem'\n\nconst sidebarMenuButtonVariants = cva(\n  'peer/menu-button flex w-full items-center px-2 gap-2 overflow-hidden rounded-md text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[active=true]:bg-muted data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!py-2 group-data-[collapsible=icon]:!px-2 [&>span:last-child]:truncate [&>svg]:shrink-0',\n  {\n    variants: {\n      variant: {\n        default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',\n        outline:\n          'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',\n      },\n      size: {\n        default: 'h-8 text-sm',\n        sm: 'h-7 text-xs',\n        lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n    },\n  },\n)\n\nconst SidebarMenuButton = React.forwardRef<\n  HTMLButtonElement,\n  React.ComponentProps<'button'> & {\n    asChild?: boolean\n    isActive?: boolean\n    tooltip?: string | React.ComponentProps<typeof TooltipContent>\n  } & VariantProps<typeof sidebarMenuButtonVariants>\n>(({ asChild = false, isActive = false, variant = 'default', size = 'default', tooltip, className, ...props }, ref) => {\n  const Comp = asChild ? Slot : 'button'\n  const { isMobile, state } = useSidebar()\n\n  const button = (\n    <Comp\n      ref={ref}\n      data-sidebar=\"menu-button\"\n      data-size={size}\n      data-active={isActive}\n      className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n      {...props}\n    />\n  )\n\n  if (!tooltip) {\n    return button\n  }\n\n  if (typeof tooltip === 'string') {\n    tooltip = {\n      children: tooltip,\n    }\n  }\n\n  return (\n    <Tooltip>\n      <TooltipTrigger asChild>{button}</TooltipTrigger>\n      <TooltipContent side=\"right\" align=\"center\" hidden={state !== 'collapsed' || isMobile} {...tooltip} />\n    </Tooltip>\n  )\n})\nSidebarMenuButton.displayName = 'SidebarMenuButton'\n\nconst SidebarMenuAction = React.forwardRef<\n  HTMLButtonElement,\n  React.ComponentProps<'button'> & {\n    asChild?: boolean\n    showOnHover?: boolean\n  }\n>(({ className, asChild = false, showOnHover = false, ...props }, ref) => {\n  const Comp = asChild ? Slot : 'button'\n\n  return (\n    <Comp\n      ref={ref}\n      data-sidebar=\"menu-action\"\n      className={cn(\n        'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',\n        // Increases the hit area of the button on mobile.\n        'after:absolute after:-inset-2 after:md:hidden',\n        'peer-data-[size=sm]/menu-button:top-1',\n        'peer-data-[size=default]/menu-button:top-1.5',\n        'peer-data-[size=lg]/menu-button:top-2.5',\n        'group-data-[collapsible=icon]:hidden',\n        showOnHover &&\n          'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',\n        className,\n      )}\n      {...props}\n    />\n  )\n})\nSidebarMenuAction.displayName = 'SidebarMenuAction'\n\nconst SidebarMenuBadge = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(\n  ({ className, ...props }, ref) => (\n    <div\n      ref={ref}\n      data-sidebar=\"menu-badge\"\n      className={cn(\n        'absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground select-none pointer-events-none',\n        'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',\n        'peer-data-[size=sm]/menu-button:top-1',\n        'peer-data-[size=default]/menu-button:top-1.5',\n        'peer-data-[size=lg]/menu-button:top-2.5',\n        'group-data-[collapsible=icon]:hidden',\n        className,\n      )}\n      {...props}\n    />\n  ),\n)\nSidebarMenuBadge.displayName = 'SidebarMenuBadge'\n\nconst SidebarMenuSkeleton = React.forwardRef<\n  HTMLDivElement,\n  React.ComponentProps<'div'> & {\n    showIcon?: boolean\n  }\n>(({ className, showIcon = false, ...props }, ref) => {\n  // Random width between 50 to 90%.\n  const width = React.useMemo(() => {\n    return `${Math.floor(Math.random() * 40) + 50}%`\n  }, [])\n\n  return (\n    <div\n      ref={ref}\n      data-sidebar=\"menu-skeleton\"\n      className={cn('rounded-md h-8 flex gap-2 px-2 items-center', className)}\n      {...props}\n    >\n      {showIcon && <Skeleton className=\"size-4 rounded-md\" data-sidebar=\"menu-skeleton-icon\" />}\n      <Skeleton\n        className=\"h-4 flex-1 max-w-[--skeleton-width]\"\n        data-sidebar=\"menu-skeleton-text\"\n        style={\n          {\n            '--skeleton-width': width,\n          } as React.CSSProperties\n        }\n      />\n    </div>\n  )\n})\nSidebarMenuSkeleton.displayName = 'SidebarMenuSkeleton'\n\nconst SidebarMenuSub = React.forwardRef<HTMLUListElement, React.ComponentProps<'ul'>>(\n  ({ className, ...props }, ref) => (\n    <ul\n      ref={ref}\n      data-sidebar=\"menu-sub\"\n      className={cn(\n        'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',\n        'group-data-[collapsible=icon]:hidden',\n        className,\n      )}\n      {...props}\n    />\n  ),\n)\nSidebarMenuSub.displayName = 'SidebarMenuSub'\n\nconst SidebarMenuSubItem = React.forwardRef<HTMLLIElement, React.ComponentProps<'li'>>(({ ...props }, ref) => (\n  <li ref={ref} {...props} />\n))\nSidebarMenuSubItem.displayName = 'SidebarMenuSubItem'\n\nconst SidebarMenuSubButton = React.forwardRef<\n  HTMLAnchorElement,\n  React.ComponentProps<'a'> & {\n    asChild?: boolean\n    size?: 'sm' | 'md'\n    isActive?: boolean\n  }\n>(({ asChild = false, size = 'md', isActive, className, ...props }, ref) => {\n  const Comp = asChild ? Slot : 'a'\n\n  return (\n    <Comp\n      ref={ref}\n      data-sidebar=\"menu-sub-button\"\n      data-size={size}\n      data-active={isActive}\n      className={cn(\n        'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',\n        'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',\n        size === 'sm' && 'text-xs',\n        size === 'md' && 'text-sm',\n        'group-data-[collapsible=icon]:hidden',\n        className,\n      )}\n      {...props}\n    />\n  )\n})\nSidebarMenuSubButton.displayName = 'SidebarMenuSubButton'\n\nexport {\n  Sidebar,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarGroupAction,\n  SidebarGroupContent,\n  SidebarGroupLabel,\n  SidebarHeader,\n  SidebarInput,\n  SidebarInset,\n  SidebarMenu,\n  SidebarMenuAction,\n  SidebarMenuBadge,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarMenuSkeleton,\n  SidebarMenuSub,\n  SidebarMenuSubButton,\n  SidebarMenuSubItem,\n  SidebarProvider,\n  SidebarRail,\n  SidebarSeparator,\n  SidebarTrigger,\n  useSidebar,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/skeleton.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { cn } from '@/lib/utils'\n\nfunction Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div\n      className={cn(\n        'rounded-md dark:bg-muted/70 bg-muted relative overflow-hidden isolate',\n        'after:absolute after:inset-0 after:-translate-x-full after:[animation:skeleton-shimmer_2s_infinite] after:bg-muted-foreground/10 dark:after:bg-muted-foreground/10 after:[mask-image:linear-gradient(90deg,transparent,black,transparent)]',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Skeleton }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/slider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\nimport * as SliderPrimitive from '@radix-ui/react-slider'\n\nimport { cn } from '@/lib/utils'\n\nconst Slider = React.forwardRef<\n  React.ElementRef<typeof SliderPrimitive.Root>,\n  React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>\n>(({ className, ...props }, ref) => (\n  <SliderPrimitive.Root\n    ref={ref}\n    className={cn('relative flex w-full touch-none select-none items-center', className)}\n    {...props}\n  >\n    <SliderPrimitive.Track className=\"relative h-2 w-full grow overflow-hidden rounded-full bg-secondary\">\n      <SliderPrimitive.Range className=\"absolute h-full bg-primary\" />\n    </SliderPrimitive.Track>\n    <SliderPrimitive.Thumb className=\"block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50\" />\n  </SliderPrimitive.Root>\n))\nSlider.displayName = SliderPrimitive.Root.displayName\n\nexport { Slider }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/sonner.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useTheme } from '@/contexts/ThemeContext'\nimport { CheckCircleIcon, InfoIcon, WarningIcon, XCircleIcon } from '@phosphor-icons/react'\nimport { Toaster as Sonner } from 'sonner'\n\ntype ToasterProps = React.ComponentProps<typeof Sonner>\n\nconst Toaster = ({ ...props }: ToasterProps) => {\n  const { theme } = useTheme()\n\n  return (\n    <Sonner\n      theme={theme as ToasterProps['theme']}\n      className=\"toaster group\"\n      icons={{\n        success: <CheckCircleIcon weight=\"fill\" className=\"size-4 text-success\" />,\n        error: <XCircleIcon weight=\"fill\" className=\"size-4 text-destructive\" />,\n        warning: <WarningIcon weight=\"fill\" className=\"size-4 text-warning\" />,\n        info: <InfoIcon weight=\"fill\" className=\"size-4 text-foreground\" />,\n      }}\n      toastOptions={{\n        classNames: {\n          toast:\n            'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg group-[.toaster]:border',\n          description: '!text-muted-foreground',\n          actionButton: 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n          cancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n          closeButton: 'group-[.toast]:border',\n        },\n      }}\n      closeButton\n      {...props}\n    />\n  )\n}\n\nexport { Toaster }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/spinner.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Loader2Icon } from 'lucide-react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Spinner({ className, ...props }: React.ComponentProps<'svg'>) {\n  return <Loader2Icon role=\"status\" aria-label=\"Loading\" className={cn('size-4 animate-spin', className)} {...props} />\n}\n\nexport { Spinner }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/accordion.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '../accordion'\n\nconst meta: Meta<typeof Accordion> = {\n  title: 'UI/Accordion',\n  component: Accordion,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Accordion>\n\nexport const Default: Story = {\n  render: () => (\n    <Accordion type=\"single\" collapsible className=\"w-96\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>Is it accessible?</AccordionTrigger>\n        <AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Is it styled?</AccordionTrigger>\n        <AccordionContent>Yes. It comes with default styles that match your theme.</AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-3\">\n        <AccordionTrigger>Is it animated?</AccordionTrigger>\n        <AccordionContent>Yes. It animates with CSS transitions.</AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  ),\n}\n\nexport const Multiple: Story = {\n  render: () => (\n    <Accordion type=\"multiple\" className=\"w-96\">\n      <AccordionItem value=\"item-1\">\n        <AccordionTrigger>Section 1</AccordionTrigger>\n        <AccordionContent>Content for section 1.</AccordionContent>\n      </AccordionItem>\n      <AccordionItem value=\"item-2\">\n        <AccordionTrigger>Section 2</AccordionTrigger>\n        <AccordionContent>Content for section 2.</AccordionContent>\n      </AccordionItem>\n    </Accordion>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/alert-dialog.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n} from '../alert-dialog'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof AlertDialog> = {\n  title: 'UI/AlertDialog',\n  component: AlertDialog,\n}\n\nexport default meta\ntype Story = StoryObj<typeof AlertDialog>\n\nexport const Default: Story = {\n  render: () => (\n    <AlertDialog>\n      <AlertDialogTrigger asChild>\n        <Button variant=\"destructive\">Delete Account</Button>\n      </AlertDialogTrigger>\n      <AlertDialogContent>\n        <AlertDialogHeader>\n          <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>\n          <AlertDialogDescription>\n            This action cannot be undone. This will permanently delete your account.\n          </AlertDialogDescription>\n        </AlertDialogHeader>\n        <AlertDialogFooter>\n          <AlertDialogCancel>Cancel</AlertDialogCancel>\n          <AlertDialogAction variant=\"destructive\">Delete</AlertDialogAction>\n        </AlertDialogFooter>\n      </AlertDialogContent>\n    </AlertDialog>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/alert.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Alert, AlertDescription, AlertTitle } from '../alert'\nimport { InfoIcon, AlertTriangleIcon, CheckCircleIcon, XCircleIcon } from 'lucide-react'\n\nconst meta: Meta<typeof Alert> = {\n  title: 'UI/Alert',\n  component: Alert,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Alert>\n\nexport const Default: Story = {\n  render: () => (\n    <Alert>\n      <InfoIcon className=\"size-4\" />\n      <AlertTitle>Default Alert</AlertTitle>\n      <AlertDescription>This is a default alert message.</AlertDescription>\n    </Alert>\n  ),\n}\n\nexport const Destructive: Story = {\n  render: () => (\n    <Alert variant=\"destructive\">\n      <XCircleIcon className=\"size-4\" />\n      <AlertTitle>Error</AlertTitle>\n      <AlertDescription>Something went wrong.</AlertDescription>\n    </Alert>\n  ),\n}\n\nexport const Info: Story = {\n  render: () => (\n    <Alert variant=\"info\">\n      <InfoIcon className=\"size-4\" />\n      <AlertTitle>Info</AlertTitle>\n      <AlertDescription>Here is some useful information.</AlertDescription>\n    </Alert>\n  ),\n}\n\nexport const Warning: Story = {\n  render: () => (\n    <Alert variant=\"warning\">\n      <AlertTriangleIcon className=\"size-4\" />\n      <AlertTitle>Warning</AlertTitle>\n      <AlertDescription>Please review before continuing.</AlertDescription>\n    </Alert>\n  ),\n}\n\nexport const Success: Story = {\n  render: () => (\n    <Alert variant=\"success\">\n      <CheckCircleIcon className=\"size-4\" />\n      <AlertTitle>Success</AlertTitle>\n      <AlertDescription>Operation completed successfully.</AlertDescription>\n    </Alert>\n  ),\n}\n\nexport const AllVariants: Story = {\n  render: () => (\n    <div className=\"flex flex-col gap-2 w-[500px]\">\n      <p className=\"text-sm font-medium text-muted-foreground\">variant</p>\n      <div className=\"flex flex-col gap-4\">\n        <Alert>\n          <InfoIcon className=\"size-4\" />\n          <AlertTitle>Default</AlertTitle>\n          <AlertDescription>Default alert variant.</AlertDescription>\n        </Alert>\n        <Alert variant=\"info\">\n          <InfoIcon className=\"size-4\" />\n          <AlertTitle>Info</AlertTitle>\n          <AlertDescription>Informational alert variant.</AlertDescription>\n        </Alert>\n        <Alert variant=\"warning\">\n          <AlertTriangleIcon className=\"size-4\" />\n          <AlertTitle>Warning</AlertTitle>\n          <AlertDescription>Warning alert variant.</AlertDescription>\n        </Alert>\n        <Alert variant=\"destructive\">\n          <XCircleIcon className=\"size-4\" />\n          <AlertTitle>Destructive</AlertTitle>\n          <AlertDescription>Destructive alert variant.</AlertDescription>\n        </Alert>\n        <Alert variant=\"success\">\n          <CheckCircleIcon className=\"size-4\" />\n          <AlertTitle>Success</AlertTitle>\n          <AlertDescription>Success alert variant.</AlertDescription>\n        </Alert>\n        <Alert variant=\"neutral\">\n          <InfoIcon className=\"size-4\" />\n          <AlertTitle>Neutral</AlertTitle>\n          <AlertDescription>Neutral alert variant.</AlertDescription>\n        </Alert>\n      </div>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/badge.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Badge } from '../badge'\n\nconst meta: Meta<typeof Badge> = {\n  title: 'UI/Badge',\n  component: Badge,\n  args: {\n    children: 'Badge',\n  },\n}\n\nexport default meta\ntype Story = StoryObj<typeof Badge>\n\nexport const Default: Story = {}\nexport const Secondary: Story = { args: { variant: 'secondary' } }\nexport const Destructive: Story = { args: { variant: 'destructive' } }\nexport const Outline: Story = { args: { variant: 'outline' } }\nexport const Info: Story = { args: { variant: 'info' } }\nexport const Warning: Story = { args: { variant: 'warning' } }\nexport const Success: Story = { args: { variant: 'success' } }\n\nexport const AllVariants: Story = {\n  render: () => (\n    <div className=\"flex flex-col gap-2\">\n      <p className=\"text-sm font-medium text-muted-foreground\">variant</p>\n      <div className=\"flex flex-wrap items-center gap-2\">\n        <Badge variant=\"default\">Default</Badge>\n        <Badge variant=\"secondary\">Secondary</Badge>\n        <Badge variant=\"destructive\">Destructive</Badge>\n        <Badge variant=\"outline\">Outline</Badge>\n        <Badge variant=\"info\">Info</Badge>\n        <Badge variant=\"warning\">Warning</Badge>\n        <Badge variant=\"success\">Success</Badge>\n      </div>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/button.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof Button> = {\n  title: 'UI/Button',\n  component: Button,\n  args: {\n    children: 'Button',\n  },\n}\n\nexport default meta\ntype Story = StoryObj<typeof Button>\n\nexport const Default: Story = {}\nexport const Destructive: Story = { args: { variant: 'destructive' } }\nexport const Outline: Story = { args: { variant: 'outline' } }\nexport const Secondary: Story = { args: { variant: 'secondary' } }\nexport const Ghost: Story = { args: { variant: 'ghost' } }\nexport const Link: Story = { args: { variant: 'link' } }\nexport const Small: Story = { args: { size: 'sm' } }\nexport const Large: Story = { args: { size: 'lg' } }\nexport const Disabled: Story = { args: { disabled: true } }\n\nexport const AllVariants: Story = {\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">variant</p>\n        <div className=\"flex flex-wrap items-center gap-2\">\n          <Button variant=\"default\">Default</Button>\n          <Button variant=\"destructive\">Destructive</Button>\n          <Button variant=\"outline\">Outline</Button>\n          <Button variant=\"secondary\">Secondary</Button>\n          <Button variant=\"ghost\">Ghost</Button>\n          <Button variant=\"link\">Link</Button>\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">size</p>\n        <div className=\"flex flex-wrap items-center gap-2\">\n          <Button size=\"sm\">Small</Button>\n          <Button size=\"default\">Default</Button>\n          <Button size=\"lg\">Large</Button>\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">disabled</p>\n        <div className=\"flex flex-wrap items-center gap-2\">\n          <Button disabled>Disabled</Button>\n          <Button variant=\"outline\" disabled>\n            Disabled Outline\n          </Button>\n        </div>\n      </div>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/calendar.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Calendar } from '../calendar'\n\nconst meta: Meta<typeof Calendar> = {\n  title: 'UI/Calendar',\n  component: Calendar,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Calendar>\n\nexport const Default: Story = {\n  args: {\n    mode: 'single',\n  },\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/card.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '../card'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof Card> = {\n  title: 'UI/Card',\n  component: Card,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Card>\n\nexport const Default: Story = {\n  render: () => (\n    <Card className=\"w-80\">\n      <CardHeader>\n        <CardTitle>Card Title</CardTitle>\n        <CardDescription>Card description goes here.</CardDescription>\n      </CardHeader>\n      <CardContent>\n        <p className=\"text-sm\">Card content goes here.</p>\n      </CardContent>\n      <CardFooter>\n        <Button>Action</Button>\n      </CardFooter>\n    </Card>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/chart.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Bar, BarChart, XAxis, YAxis } from 'recharts'\nimport { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from '../chart'\n\nconst meta: Meta<typeof ChartContainer> = {\n  title: 'UI/Chart',\n  component: ChartContainer,\n}\n\nexport default meta\ntype Story = StoryObj<typeof ChartContainer>\n\nconst chartData = [\n  { month: 'Jan', desktop: 186, mobile: 80 },\n  { month: 'Feb', desktop: 305, mobile: 200 },\n  { month: 'Mar', desktop: 237, mobile: 120 },\n  { month: 'Apr', desktop: 73, mobile: 190 },\n  { month: 'May', desktop: 209, mobile: 130 },\n  { month: 'Jun', desktop: 214, mobile: 140 },\n]\n\nconst chartConfig: ChartConfig = {\n  desktop: { label: 'Desktop', color: 'hsl(var(--chart-1))' },\n  mobile: { label: 'Mobile', color: 'hsl(var(--chart-2))' },\n}\n\nexport const BarChartExample: Story = {\n  render: () => (\n    <ChartContainer config={chartConfig} className=\"min-h-[200px] w-full\">\n      <BarChart data={chartData}>\n        <XAxis dataKey=\"month\" />\n        <YAxis />\n        <ChartTooltip content={<ChartTooltipContent />} />\n        <Bar dataKey=\"desktop\" fill=\"var(--color-desktop)\" radius={4} />\n        <Bar dataKey=\"mobile\" fill=\"var(--color-mobile)\" radius={4} />\n      </BarChart>\n    </ChartContainer>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/checkbox.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Checkbox } from '../checkbox'\nimport { Label } from '../label'\n\nconst meta: Meta<typeof Checkbox> = {\n  title: 'UI/Checkbox',\n  component: Checkbox,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Checkbox>\n\nexport const Default: Story = {}\nexport const Checked: Story = { args: { defaultChecked: true } }\nexport const Disabled: Story = { args: { disabled: true } }\n\nexport const WithLabel: Story = {\n  render: () => (\n    <div className=\"flex items-center gap-2\">\n      <Checkbox id=\"terms\" />\n      <Label htmlFor=\"terms\">Accept terms and conditions</Label>\n    </div>\n  ),\n}\n\nexport const AllStates: Story = {\n  render: () => (\n    <div className=\"flex flex-col gap-2\">\n      <p className=\"text-sm font-medium text-muted-foreground\">state</p>\n      <div className=\"flex flex-col gap-4\">\n        <div className=\"flex items-center gap-2\">\n          <Checkbox id=\"unchecked\" />\n          <Label htmlFor=\"unchecked\">Unchecked</Label>\n        </div>\n        <div className=\"flex items-center gap-2\">\n          <Checkbox id=\"checked\" defaultChecked />\n          <Label htmlFor=\"checked\">Checked</Label>\n        </div>\n        <div className=\"flex items-center gap-2\">\n          <Checkbox id=\"indeterminate\" checked=\"indeterminate\" />\n          <Label htmlFor=\"indeterminate\">Indeterminate</Label>\n        </div>\n        <div className=\"flex items-center gap-2\">\n          <Checkbox id=\"disabled\" disabled />\n          <Label htmlFor=\"disabled\">Disabled</Label>\n        </div>\n        <div className=\"flex items-center gap-2\">\n          <Checkbox id=\"disabled-checked\" disabled defaultChecked />\n          <Label htmlFor=\"disabled-checked\">Disabled Checked</Label>\n        </div>\n      </div>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/colors.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { useState, useCallback } from 'react'\nimport { MoreVertical, Check } from 'lucide-react'\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '../dropdown-menu'\nimport { Separator } from '../separator'\n\nfunction hslToHex(hsl: string): string {\n  const parts = hsl.trim().split(/\\s+/)\n  if (parts.length < 3) return '#000000'\n  const h = parseFloat(parts[0])\n  const s = parseFloat(parts[1]) / 100\n  const l = parseFloat(parts[2]) / 100\n\n  const a = s * Math.min(l, 1 - l)\n  const f = (n: number) => {\n    const k = (n + h / 30) % 12\n    const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\n    return Math.round(255 * color)\n      .toString(16)\n      .padStart(2, '0')\n  }\n  return `#${f(0)}${f(8)}${f(4)}`\n}\n\nfunction ColorSwatch({ variable, label }: { variable: string; label: string }) {\n  const [copied, setCopied] = useState<string | null>(null)\n\n  const copyToClipboard = useCallback((text: string, type: string) => {\n    navigator.clipboard.writeText(text)\n    setCopied(type)\n    setTimeout(() => setCopied(null), 1500)\n  }, [])\n\n  const hslValue =\n    typeof window !== 'undefined' ? getComputedStyle(document.documentElement).getPropertyValue(variable).trim() : ''\n  const hex = hslToHex(hslValue)\n\n  return (\n    <div>\n      <div\n        className=\"relative w-[100px] aspect-square rounded-md border border-border\"\n        style={{ backgroundColor: `hsl(var(${variable}))` }}\n      >\n        <div style={{ position: 'absolute', top: 4, right: 4, zIndex: 10 }}>\n          <DropdownMenu>\n            <DropdownMenuTrigger asChild>\n              <button\n                style={{\n                  padding: 2,\n                  borderRadius: 4,\n                  backgroundColor: 'rgba(255,255,255,0.8)',\n                  border: '1px solid #e5e5e5',\n                  boxShadow: '0 1px 2px rgba(0,0,0,0.1)',\n                  cursor: 'pointer',\n                  display: 'flex',\n                  alignItems: 'center',\n                  justifyContent: 'center',\n                }}\n              >\n                <MoreVertical className=\"size-3.5\" />\n              </button>\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\" className=\"min-w-[140px]\">\n              <DropdownMenuItem onClick={() => copyToClipboard(hex, 'hex')}>\n                {copied === 'hex' ? <Check className=\"size-3.5\" /> : null}\n                Copy hex\n                <span className=\"ml-auto text-xs text-muted-foreground\">{hex}</span>\n              </DropdownMenuItem>\n              <DropdownMenuItem onClick={() => copyToClipboard(`var(${variable})`, 'var')}>\n                {copied === 'var' ? <Check className=\"size-3.5\" /> : null}\n                Copy variable\n              </DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </div>\n      </div>\n      <div className=\"mt-1.5 text-xs leading-tight\">\n        <div className=\"font-medium truncate w-[100px]\">{label}</div>\n        <div className=\"text-muted-foreground truncate w-[100px]\">{variable}</div>\n      </div>\n    </div>\n  )\n}\n\nconst colorGroups = [\n  {\n    name: 'Base',\n    colors: [\n      { variable: '--background', label: 'Background' },\n      { variable: '--foreground', label: 'Foreground' },\n      { variable: '--card', label: 'Card' },\n      { variable: '--card-foreground', label: 'Card FG' },\n      { variable: '--popover', label: 'Popover' },\n      { variable: '--popover-foreground', label: 'Popover FG' },\n    ],\n  },\n  {\n    name: 'Brand',\n    colors: [\n      { variable: '--primary', label: 'Primary' },\n      { variable: '--primary-foreground', label: 'Primary FG' },\n      { variable: '--secondary', label: 'Secondary' },\n      { variable: '--secondary-foreground', label: 'Secondary FG' },\n      { variable: '--muted', label: 'Muted' },\n      { variable: '--muted-foreground', label: 'Muted FG' },\n      { variable: '--accent', label: 'Accent' },\n      { variable: '--accent-foreground', label: 'Accent FG' },\n    ],\n  },\n  {\n    name: 'Borders & Inputs',\n    colors: [\n      { variable: '--border', label: 'Border' },\n      { variable: '--input', label: 'Input' },\n      { variable: '--ring', label: 'Ring' },\n    ],\n  },\n  {\n    name: 'Destructive',\n    colors: [\n      { variable: '--destructive', label: 'Destructive' },\n      { variable: '--destructive-background', label: 'Destructive BG' },\n      { variable: '--destructive-foreground', label: 'Destructive FG' },\n      { variable: '--destructive-separator', label: 'Destructive Sep' },\n    ],\n  },\n  {\n    name: 'Warning',\n    colors: [\n      { variable: '--warning', label: 'Warning' },\n      { variable: '--warning-background', label: 'Warning BG' },\n      { variable: '--warning-foreground', label: 'Warning FG' },\n      { variable: '--warning-separator', label: 'Warning Sep' },\n    ],\n  },\n  {\n    name: 'Success',\n    colors: [\n      { variable: '--success', label: 'Success' },\n      { variable: '--success-background', label: 'Success BG' },\n      { variable: '--success-foreground', label: 'Success FG' },\n      { variable: '--success-separator', label: 'Success Sep' },\n    ],\n  },\n  {\n    name: 'Info',\n    colors: [\n      { variable: '--info-background', label: 'Info BG' },\n      { variable: '--info-foreground', label: 'Info FG' },\n      { variable: '--info-separator', label: 'Info Sep' },\n    ],\n  },\n  {\n    name: 'Chart',\n    colors: [\n      { variable: '--chart-1', label: 'Chart 1' },\n      { variable: '--chart-2', label: 'Chart 2' },\n      { variable: '--chart-3', label: 'Chart 3' },\n      { variable: '--chart-4', label: 'Chart 4' },\n      { variable: '--chart-5', label: 'Chart 5' },\n    ],\n  },\n  {\n    name: 'Sidebar',\n    colors: [\n      { variable: '--sidebar-background', label: 'Sidebar BG' },\n      { variable: '--sidebar-foreground', label: 'Sidebar FG' },\n      { variable: '--sidebar-primary', label: 'Sidebar Primary' },\n      { variable: '--sidebar-primary-foreground', label: 'Sidebar Primary FG' },\n      { variable: '--sidebar-accent', label: 'Sidebar Accent' },\n      { variable: '--sidebar-accent-foreground', label: 'Sidebar Accent FG' },\n      { variable: '--sidebar-border', label: 'Sidebar Border' },\n      { variable: '--sidebar-ring', label: 'Sidebar Ring' },\n    ],\n  },\n]\n\nfunction ColorPalette() {\n  return (\n    <div className=\"flex flex-col gap-6\">\n      {colorGroups.map((group, index) => (\n        <div key={group.name} className=\"flex flex-col gap-6\">\n          {index > 0 && <Separator />}\n          <h3 className=\"text-sm font-semibold\">{group.name}</h3>\n          <div className=\"flex flex-wrap gap-4\">\n            {group.colors.map((color) => (\n              <ColorSwatch key={color.variable} {...color} />\n            ))}\n          </div>\n        </div>\n      ))}\n    </div>\n  )\n}\n\nconst meta: Meta = {\n  title: 'Foundation/Colors',\n}\n\nexport default meta\ntype Story = StoryObj\n\nexport const Palette: Story = {\n  render: () => <ColorPalette />,\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/command.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport {\n  Command,\n  CommandEmpty,\n  CommandGroup,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandSeparator,\n} from '../command'\n\nconst meta: Meta<typeof Command> = {\n  title: 'UI/Command',\n  component: Command,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Command>\n\nexport const Default: Story = {\n  render: () => (\n    <Command className=\"rounded-lg border shadow-md w-96\">\n      <CommandInput placeholder=\"Type a command or search...\" />\n      <CommandList>\n        <CommandEmpty>No results found.</CommandEmpty>\n        <CommandGroup heading=\"Suggestions\">\n          <CommandItem>Calendar</CommandItem>\n          <CommandItem>Search</CommandItem>\n          <CommandItem>Settings</CommandItem>\n        </CommandGroup>\n        <CommandSeparator />\n        <CommandGroup heading=\"Actions\">\n          <CommandItem>New File</CommandItem>\n          <CommandItem>New Folder</CommandItem>\n        </CommandGroup>\n      </CommandList>\n    </Command>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/date-picker.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { useState } from 'react'\nimport { DatePicker } from '../date-picker'\n\nconst meta: Meta<typeof DatePicker> = {\n  title: 'UI/DatePicker',\n  component: DatePicker,\n}\n\nexport default meta\ntype Story = StoryObj<typeof DatePicker>\n\nexport const Default: Story = {\n  render: () => {\n    const [date, setDate] = useState<Date | undefined>()\n    return <DatePicker value={date} onChange={setDate} />\n  },\n}\n\nexport const WithValue: Story = {\n  render: () => {\n    const [date, setDate] = useState<Date | undefined>(new Date())\n    return <DatePicker value={date} onChange={setDate} />\n  },\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/dialog.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '../dialog'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof Dialog> = {\n  title: 'UI/Dialog',\n  component: Dialog,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Dialog>\n\nexport const Default: Story = {\n  render: () => (\n    <Dialog>\n      <DialogTrigger asChild>\n        <Button variant=\"outline\">Open Dialog</Button>\n      </DialogTrigger>\n      <DialogContent>\n        <DialogHeader>\n          <DialogTitle>Dialog Title</DialogTitle>\n          <DialogDescription>This is a dialog description.</DialogDescription>\n        </DialogHeader>\n        <div className=\"py-4\">\n          <p className=\"text-sm text-muted-foreground\">Dialog content goes here.</p>\n        </div>\n        <DialogFooter>\n          <Button variant=\"outline\">Cancel</Button>\n          <Button>Save</Button>\n        </DialogFooter>\n      </DialogContent>\n    </Dialog>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/drawer.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport {\n  Drawer,\n  DrawerContent,\n  DrawerDescription,\n  DrawerFooter,\n  DrawerHeader,\n  DrawerTitle,\n  DrawerTrigger,\n} from '../drawer'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof Drawer> = {\n  title: 'UI/Drawer',\n  component: Drawer,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Drawer>\n\nexport const Default: Story = {\n  render: () => (\n    <Drawer>\n      <DrawerTrigger asChild>\n        <Button variant=\"outline\">Open Drawer</Button>\n      </DrawerTrigger>\n      <DrawerContent>\n        <DrawerHeader>\n          <DrawerTitle>Drawer Title</DrawerTitle>\n          <DrawerDescription>Drawer description goes here.</DrawerDescription>\n        </DrawerHeader>\n        <div className=\"p-4\">\n          <p className=\"text-sm text-muted-foreground\">Drawer content.</p>\n        </div>\n        <DrawerFooter>\n          <Button>Submit</Button>\n        </DrawerFooter>\n      </DrawerContent>\n    </Drawer>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/dropdown-menu.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuTrigger,\n} from '../dropdown-menu'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof DropdownMenu> = {\n  title: 'UI/DropdownMenu',\n  component: DropdownMenu,\n}\n\nexport default meta\ntype Story = StoryObj<typeof DropdownMenu>\n\nexport const Default: Story = {\n  render: () => (\n    <DropdownMenu>\n      <DropdownMenuTrigger asChild>\n        <Button variant=\"outline\">Open Menu</Button>\n      </DropdownMenuTrigger>\n      <DropdownMenuContent className=\"w-56\">\n        <DropdownMenuLabel>My Account</DropdownMenuLabel>\n        <DropdownMenuSeparator />\n        <DropdownMenuGroup>\n          <DropdownMenuItem>\n            Profile\n            <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            Settings\n            <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>\n          </DropdownMenuItem>\n        </DropdownMenuGroup>\n        <DropdownMenuSeparator />\n        <DropdownMenuItem variant=\"destructive\">\n          Log out\n          <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>\n        </DropdownMenuItem>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/facet-filter.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { useState } from 'react'\nimport { FacetFilter } from '../facet-filter'\n\nconst meta: Meta<typeof FacetFilter> = {\n  title: 'UI/FacetFilter',\n  component: FacetFilter,\n}\n\nexport default meta\ntype Story = StoryObj<typeof FacetFilter>\n\nconst options = [\n  { label: 'Active', value: 'active' },\n  { label: 'Inactive', value: 'inactive' },\n  { label: 'Pending', value: 'pending' },\n]\n\nexport const Default: Story = {\n  render: () => {\n    const [selected, setSelected] = useState<Set<string>>(new Set())\n    return <FacetFilter title=\"Status\" options={options} selectedValues={selected} setSelectedValues={setSelected} />\n  },\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/field.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel } from '../field'\nimport { Input } from '../input'\n\nconst meta: Meta<typeof Field> = {\n  title: 'UI/Field',\n  component: Field,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Field>\n\nexport const Vertical: Story = {\n  render: () => (\n    <FieldGroup className=\"max-w-sm\">\n      <Field orientation=\"vertical\">\n        <FieldLabel htmlFor=\"email\">Email</FieldLabel>\n        <FieldContent>\n          <Input id=\"email\" placeholder=\"you@example.com\" />\n          <FieldDescription>We'll never share your email.</FieldDescription>\n        </FieldContent>\n      </Field>\n    </FieldGroup>\n  ),\n}\n\nexport const Horizontal: Story = {\n  render: () => (\n    <FieldGroup className=\"max-w-md\">\n      <Field orientation=\"horizontal\">\n        <FieldLabel htmlFor=\"name\">Name</FieldLabel>\n        <FieldContent>\n          <Input id=\"name\" placeholder=\"John Doe\" />\n        </FieldContent>\n      </Field>\n    </FieldGroup>\n  ),\n}\n\nexport const WithError: Story = {\n  render: () => (\n    <FieldGroup className=\"max-w-sm\">\n      <Field orientation=\"vertical\">\n        <FieldLabel htmlFor=\"password\">Password</FieldLabel>\n        <FieldContent>\n          <Input id=\"password\" type=\"password\" aria-invalid=\"true\" />\n          <FieldError>Password must be at least 8 characters.</FieldError>\n        </FieldContent>\n      </Field>\n    </FieldGroup>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/input-group.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText } from '../input-group'\nimport { SearchIcon, CopyIcon } from 'lucide-react'\n\nconst meta: Meta<typeof InputGroup> = {\n  title: 'UI/InputGroup',\n  component: InputGroup,\n  decorators: [\n    (Story) => (\n      <div className=\"max-w-sm\">\n        <Story />\n      </div>\n    ),\n  ],\n}\n\nexport default meta\ntype Story = StoryObj<typeof InputGroup>\n\nexport const WithIcon: Story = {\n  render: () => (\n    <InputGroup>\n      <InputGroupAddon align=\"inline-start\">\n        <SearchIcon />\n      </InputGroupAddon>\n      <InputGroupInput placeholder=\"Search...\" />\n    </InputGroup>\n  ),\n}\n\nexport const WithButton: Story = {\n  render: () => (\n    <InputGroup>\n      <InputGroupInput placeholder=\"Copy this text\" />\n      <InputGroupAddon align=\"inline-end\">\n        <InputGroupButton>\n          <CopyIcon />\n        </InputGroupButton>\n      </InputGroupAddon>\n    </InputGroup>\n  ),\n}\n\nexport const WithText: Story = {\n  render: () => (\n    <InputGroup>\n      <InputGroupAddon align=\"inline-start\">\n        <InputGroupText>https://</InputGroupText>\n      </InputGroupAddon>\n      <InputGroupInput placeholder=\"example.com\" />\n    </InputGroup>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/input.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Input } from '../input'\n\nconst meta: Meta<typeof Input> = {\n  title: 'UI/Input',\n  component: Input,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Input>\n\nexport const Default: Story = { args: { placeholder: 'Enter text...' } }\nexport const WithValue: Story = { args: { defaultValue: 'Hello World' } }\nexport const Disabled: Story = { args: { placeholder: 'Disabled', disabled: true } }\nexport const File: Story = { args: { type: 'file' } }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/kbd.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Kbd, KbdGroup } from '../kbd'\n\nconst meta: Meta<typeof Kbd> = {\n  title: 'UI/Kbd',\n  component: Kbd,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Kbd>\n\nexport const Default: Story = { args: { children: 'K' } }\n\nexport const Group: Story = {\n  render: () => (\n    <KbdGroup>\n      <Kbd>⌘</Kbd>\n      <Kbd>K</Kbd>\n    </KbdGroup>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/label.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Label } from '../label'\n\nconst meta: Meta<typeof Label> = {\n  title: 'UI/Label',\n  component: Label,\n  args: {\n    children: 'Email address',\n  },\n}\n\nexport default meta\ntype Story = StoryObj<typeof Label>\n\nexport const Default: Story = {}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/popover.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Popover, PopoverContent, PopoverTrigger } from '../popover'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof Popover> = {\n  title: 'UI/Popover',\n  component: Popover,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Popover>\n\nexport const Default: Story = {\n  render: () => (\n    <Popover>\n      <PopoverTrigger asChild>\n        <Button variant=\"outline\">Open Popover</Button>\n      </PopoverTrigger>\n      <PopoverContent>\n        <div className=\"space-y-2\">\n          <h4 className=\"font-medium text-sm\">Popover Title</h4>\n          <p className=\"text-sm text-muted-foreground\">This is the popover content.</p>\n        </div>\n      </PopoverContent>\n    </Popover>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/radio-group.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { RadioGroup, RadioGroupItem } from '../radio-group'\nimport { Label } from '../label'\n\nconst meta: Meta<typeof RadioGroup> = {\n  title: 'UI/RadioGroup',\n  component: RadioGroup,\n}\n\nexport default meta\ntype Story = StoryObj<typeof RadioGroup>\n\nexport const Default: Story = {\n  render: () => (\n    <RadioGroup defaultValue=\"option-1\">\n      <div className=\"flex items-center space-x-2\">\n        <RadioGroupItem value=\"option-1\" id=\"r1\" />\n        <Label htmlFor=\"r1\">Option 1</Label>\n      </div>\n      <div className=\"flex items-center space-x-2\">\n        <RadioGroupItem value=\"option-2\" id=\"r2\" />\n        <Label htmlFor=\"r2\">Option 2</Label>\n      </div>\n      <div className=\"flex items-center space-x-2\">\n        <RadioGroupItem value=\"option-3\" id=\"r3\" />\n        <Label htmlFor=\"r3\">Option 3</Label>\n      </div>\n    </RadioGroup>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/scroll-area.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { ScrollArea } from '../scroll-area'\n\nconst meta: Meta<typeof ScrollArea> = {\n  title: 'UI/ScrollArea',\n  component: ScrollArea,\n}\n\nexport default meta\ntype Story = StoryObj<typeof ScrollArea>\n\nexport const Default: Story = {\n  render: () => (\n    <ScrollArea className=\"h-48 w-64 rounded-md border p-4\">\n      {Array.from({ length: 50 }, (_, i) => (\n        <div key={i} className=\"py-1 text-sm\">\n          Item {i + 1}\n        </div>\n      ))}\n    </ScrollArea>\n  ),\n}\n\nexport const WithShadowFade: Story = {\n  render: () => (\n    <ScrollArea className=\"h-48 w-64 rounded-md border p-4\" fade=\"shadow\">\n      {Array.from({ length: 50 }, (_, i) => (\n        <div key={i} className=\"py-1 text-sm\">\n          Item {i + 1}\n        </div>\n      ))}\n    </ScrollArea>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/select.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../select'\n\nconst meta: Meta<typeof Select> = {\n  title: 'UI/Select',\n  component: Select,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Select>\n\nexport const Default: Story = {\n  render: () => (\n    <Select>\n      <SelectTrigger className=\"w-48\">\n        <SelectValue placeholder=\"Select a fruit\" />\n      </SelectTrigger>\n      <SelectContent>\n        <SelectItem value=\"apple\">Apple</SelectItem>\n        <SelectItem value=\"banana\">Banana</SelectItem>\n        <SelectItem value=\"cherry\">Cherry</SelectItem>\n        <SelectItem value=\"grape\">Grape</SelectItem>\n      </SelectContent>\n    </Select>\n  ),\n}\n\nexport const Small: Story = {\n  render: () => (\n    <Select>\n      <SelectTrigger className=\"w-48\" size=\"sm\">\n        <SelectValue placeholder=\"Select size\" />\n      </SelectTrigger>\n      <SelectContent>\n        <SelectItem value=\"s\">Small</SelectItem>\n        <SelectItem value=\"m\">Medium</SelectItem>\n        <SelectItem value=\"l\">Large</SelectItem>\n      </SelectContent>\n    </Select>\n  ),\n}\n\nexport const AllSizes: Story = {\n  render: () => (\n    <div className=\"flex flex-col gap-2\">\n      <p className=\"text-sm font-medium text-muted-foreground\">size</p>\n      <div className=\"flex flex-col gap-4\">\n        <Select>\n          <SelectTrigger className=\"w-48\" size=\"xs\">\n            <SelectValue placeholder=\"Extra Small\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"a\">Option A</SelectItem>\n          </SelectContent>\n        </Select>\n        <Select>\n          <SelectTrigger className=\"w-48\" size=\"sm\">\n            <SelectValue placeholder=\"Small\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"a\">Option A</SelectItem>\n          </SelectContent>\n        </Select>\n        <Select>\n          <SelectTrigger className=\"w-48\" size=\"default\">\n            <SelectValue placeholder=\"Default\" />\n          </SelectTrigger>\n          <SelectContent>\n            <SelectItem value=\"a\">Option A</SelectItem>\n          </SelectContent>\n        </Select>\n      </div>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/separator.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Separator } from '../separator'\n\nconst meta: Meta<typeof Separator> = {\n  title: 'UI/Separator',\n  component: Separator,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Separator>\n\nexport const Horizontal: Story = {\n  decorators: [\n    (Story) => (\n      <div className=\"w-64\">\n        <div className=\"text-sm\">Above</div>\n        <Story />\n        <div className=\"text-sm\">Below</div>\n      </div>\n    ),\n  ],\n}\n\nexport const Vertical: Story = {\n  args: { orientation: 'vertical' },\n  decorators: [\n    (Story) => (\n      <div className=\"flex h-8 items-center gap-4\">\n        <span className=\"text-sm\">Left</span>\n        <Story />\n        <span className=\"text-sm\">Right</span>\n      </div>\n    ),\n  ],\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/sheet.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from '../sheet'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof Sheet> = {\n  title: 'UI/Sheet',\n  component: Sheet,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Sheet>\n\nexport const Right: Story = {\n  render: () => (\n    <Sheet>\n      <SheetTrigger asChild>\n        <Button variant=\"outline\">Open Sheet</Button>\n      </SheetTrigger>\n      <SheetContent side=\"right\">\n        <SheetHeader>\n          <SheetTitle>Sheet Title</SheetTitle>\n          <SheetDescription>Sheet description goes here.</SheetDescription>\n        </SheetHeader>\n        <div className=\"py-4\">\n          <p className=\"text-sm text-muted-foreground\">Sheet content.</p>\n        </div>\n      </SheetContent>\n    </Sheet>\n  ),\n}\n\nexport const Left: Story = {\n  render: () => (\n    <Sheet>\n      <SheetTrigger asChild>\n        <Button variant=\"outline\">Open Left Sheet</Button>\n      </SheetTrigger>\n      <SheetContent side=\"left\">\n        <SheetHeader>\n          <SheetTitle>Left Sheet</SheetTitle>\n          <SheetDescription>This sheet opens from the left.</SheetDescription>\n        </SheetHeader>\n      </SheetContent>\n    </Sheet>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/sidebar.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport {\n  Sidebar,\n  SidebarContent,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarGroupLabel,\n  SidebarMenu,\n  SidebarMenuButton,\n  SidebarMenuItem,\n  SidebarProvider,\n} from '../sidebar'\nimport { HomeIcon, SettingsIcon, UsersIcon } from 'lucide-react'\n\nconst meta: Meta<typeof Sidebar> = {\n  title: 'UI/Sidebar',\n  component: Sidebar,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Sidebar>\n\nconst items = [\n  { title: 'Home', icon: HomeIcon },\n  { title: 'Users', icon: UsersIcon },\n  { title: 'Settings', icon: SettingsIcon },\n]\n\nexport const Default: Story = {\n  render: () => (\n    <SidebarProvider isBannerVisible={false}>\n      <Sidebar isBannerVisible={false}>\n        <SidebarContent>\n          <SidebarGroup>\n            <SidebarGroupLabel>Application</SidebarGroupLabel>\n            <SidebarGroupContent>\n              <SidebarMenu>\n                {items.map((item) => (\n                  <SidebarMenuItem key={item.title}>\n                    <SidebarMenuButton>\n                      <item.icon />\n                      <span>{item.title}</span>\n                    </SidebarMenuButton>\n                  </SidebarMenuItem>\n                ))}\n              </SidebarMenu>\n            </SidebarGroupContent>\n          </SidebarGroup>\n        </SidebarContent>\n      </Sidebar>\n    </SidebarProvider>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/skeleton.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Skeleton } from '../skeleton'\n\nconst meta: Meta<typeof Skeleton> = {\n  title: 'UI/Skeleton',\n  component: Skeleton,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Skeleton>\n\nexport const Default: Story = {\n  args: { className: 'h-4 w-48' },\n}\n\nexport const Card: Story = {\n  render: () => (\n    <div className=\"flex flex-col space-y-3\">\n      <Skeleton className=\"h-32 w-64 rounded-xl\" />\n      <div className=\"space-y-2\">\n        <Skeleton className=\"h-4 w-64\" />\n        <Skeleton className=\"h-4 w-48\" />\n      </div>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/slider.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Slider } from '../slider'\n\nconst meta: Meta<typeof Slider> = {\n  title: 'UI/Slider',\n  component: Slider,\n  decorators: [\n    (Story) => (\n      <div className=\"w-64\">\n        <Story />\n      </div>\n    ),\n  ],\n}\n\nexport default meta\ntype Story = StoryObj<typeof Slider>\n\nexport const Default: Story = { args: { defaultValue: [50] } }\nexport const WithRange: Story = { args: { defaultValue: [25], max: 100, step: 1 } }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/sonner.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { toast, Toaster } from 'sonner'\nimport { Button } from '../button'\n\nconst meta: Meta = {\n  title: 'UI/Sonner',\n  decorators: [\n    (Story) => (\n      <div>\n        <Toaster />\n        <Story />\n      </div>\n    ),\n  ],\n}\n\nexport default meta\ntype Story = StoryObj\n\nexport const Default: Story = {\n  render: () => (\n    <div className=\"flex gap-2\">\n      <Button variant=\"outline\" onClick={() => toast('Default toast')}>\n        Default\n      </Button>\n      <Button variant=\"outline\" onClick={() => toast.success('Success toast')}>\n        Success\n      </Button>\n      <Button variant=\"outline\" onClick={() => toast.error('Error toast')}>\n        Error\n      </Button>\n      <Button variant=\"outline\" onClick={() => toast.warning('Warning toast')}>\n        Warning\n      </Button>\n      <Button variant=\"outline\" onClick={() => toast.info('Info toast')}>\n        Info\n      </Button>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/spinner.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Spinner } from '../spinner'\n\nconst meta: Meta<typeof Spinner> = {\n  title: 'UI/Spinner',\n  component: Spinner,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Spinner>\n\nexport const Default: Story = {}\nexport const Large: Story = { args: { className: 'size-8' } }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/switch.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Switch } from '../switch'\nimport { Label } from '../label'\n\nconst meta: Meta<typeof Switch> = {\n  title: 'UI/Switch',\n  component: Switch,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Switch>\n\nexport const Default: Story = {}\nexport const Checked: Story = { args: { defaultChecked: true } }\nexport const Small: Story = { args: { size: 'sm' } }\nexport const Disabled: Story = { args: { disabled: true } }\n\nexport const WithLabel: Story = {\n  render: () => (\n    <div className=\"flex items-center gap-2\">\n      <Switch id=\"airplane\" />\n      <Label htmlFor=\"airplane\">Airplane Mode</Label>\n    </div>\n  ),\n}\n\nexport const AllVariants: Story = {\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">size · default</p>\n        <div className=\"flex items-center gap-4\">\n          <div className=\"flex items-center gap-2\">\n            <Switch />\n            <Label>Default</Label>\n          </div>\n          <div className=\"flex items-center gap-2\">\n            <Switch defaultChecked />\n            <Label>Checked</Label>\n          </div>\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">size · sm</p>\n        <div className=\"flex items-center gap-4\">\n          <div className=\"flex items-center gap-2\">\n            <Switch size=\"sm\" />\n            <Label>Small</Label>\n          </div>\n          <div className=\"flex items-center gap-2\">\n            <Switch size=\"sm\" defaultChecked />\n            <Label>Small Checked</Label>\n          </div>\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">disabled</p>\n        <div className=\"flex items-center gap-2\">\n          <Switch disabled />\n          <Label>Disabled</Label>\n        </div>\n      </div>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/table.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from '../table'\n\nconst meta: Meta<typeof Table> = {\n  title: 'UI/Table',\n  component: Table,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Table>\n\nexport const Default: Story = {\n  render: () => (\n    <Table>\n      <TableCaption>A list of recent invoices.</TableCaption>\n      <TableHeader>\n        <TableRow>\n          <TableHead>Invoice</TableHead>\n          <TableHead>Status</TableHead>\n          <TableHead>Method</TableHead>\n          <TableHead className=\"text-right\">Amount</TableHead>\n        </TableRow>\n      </TableHeader>\n      <TableBody>\n        <TableRow>\n          <TableCell>INV001</TableCell>\n          <TableCell>Paid</TableCell>\n          <TableCell>Credit Card</TableCell>\n          <TableCell className=\"text-right\">$250.00</TableCell>\n        </TableRow>\n        <TableRow>\n          <TableCell>INV002</TableCell>\n          <TableCell>Pending</TableCell>\n          <TableCell>PayPal</TableCell>\n          <TableCell className=\"text-right\">$150.00</TableCell>\n        </TableRow>\n        <TableRow>\n          <TableCell>INV003</TableCell>\n          <TableCell>Unpaid</TableCell>\n          <TableCell>Bank Transfer</TableCell>\n          <TableCell className=\"text-right\">$350.00</TableCell>\n        </TableRow>\n      </TableBody>\n    </Table>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/tabs.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '../tabs'\n\nconst meta: Meta<typeof Tabs> = {\n  title: 'UI/Tabs',\n  component: Tabs,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Tabs>\n\nexport const Default: Story = {\n  render: () => (\n    <Tabs defaultValue=\"tab1\" className=\"w-96\">\n      <TabsList>\n        <TabsTrigger value=\"tab1\">Account</TabsTrigger>\n        <TabsTrigger value=\"tab2\">Password</TabsTrigger>\n        <TabsTrigger value=\"tab3\">Settings</TabsTrigger>\n      </TabsList>\n      <TabsContent value=\"tab1\">\n        <p className=\"text-sm text-muted-foreground p-4\">Account settings content.</p>\n      </TabsContent>\n      <TabsContent value=\"tab2\">\n        <p className=\"text-sm text-muted-foreground p-4\">Password settings content.</p>\n      </TabsContent>\n      <TabsContent value=\"tab3\">\n        <p className=\"text-sm text-muted-foreground p-4\">General settings content.</p>\n      </TabsContent>\n    </Tabs>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/textarea.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Textarea } from '../textarea'\n\nconst meta: Meta<typeof Textarea> = {\n  title: 'UI/Textarea',\n  component: Textarea,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Textarea>\n\nexport const Default: Story = { args: { placeholder: 'Type your message...' } }\nexport const Disabled: Story = { args: { placeholder: 'Disabled', disabled: true } }\nexport const WithValue: Story = { args: { defaultValue: 'Some content here...' } }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/toggle-group.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { ToggleGroup, ToggleGroupItem } from '../toggle-group'\nimport { AlignLeftIcon, AlignCenterIcon, AlignRightIcon } from 'lucide-react'\n\nconst meta: Meta<typeof ToggleGroup> = {\n  title: 'UI/ToggleGroup',\n  component: ToggleGroup,\n}\n\nexport default meta\ntype Story = StoryObj<typeof ToggleGroup>\n\nexport const Default: Story = {\n  render: () => (\n    <ToggleGroup type=\"single\" defaultValue=\"center\">\n      <ToggleGroupItem value=\"left\" aria-label=\"Align left\">\n        <AlignLeftIcon className=\"size-4\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"center\" aria-label=\"Align center\">\n        <AlignCenterIcon className=\"size-4\" />\n      </ToggleGroupItem>\n      <ToggleGroupItem value=\"right\" aria-label=\"Align right\">\n        <AlignRightIcon className=\"size-4\" />\n      </ToggleGroupItem>\n    </ToggleGroup>\n  ),\n}\n\nexport const Outline: Story = {\n  render: () => (\n    <ToggleGroup type=\"multiple\" variant=\"outline\">\n      <ToggleGroupItem value=\"bold\">Bold</ToggleGroupItem>\n      <ToggleGroupItem value=\"italic\">Italic</ToggleGroupItem>\n      <ToggleGroupItem value=\"underline\">Underline</ToggleGroupItem>\n    </ToggleGroup>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/toggle.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Toggle } from '../toggle'\nimport { BoldIcon } from 'lucide-react'\n\nconst meta: Meta<typeof Toggle> = {\n  title: 'UI/Toggle',\n  component: Toggle,\n  args: {\n    children: <BoldIcon className=\"size-4\" />,\n    'aria-label': 'Toggle bold',\n  },\n}\n\nexport default meta\ntype Story = StoryObj<typeof Toggle>\n\nexport const Default: Story = {}\nexport const Outline: Story = { args: { variant: 'outline' } }\nexport const Small: Story = { args: { size: 'sm' } }\nexport const Large: Story = { args: { size: 'lg' } }\nexport const WithText: Story = { args: { children: 'Toggle me' } }\n\nexport const AllVariants: Story = {\n  render: () => (\n    <div className=\"flex flex-col gap-6\">\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">variant</p>\n        <div className=\"flex items-center gap-2\">\n          <Toggle variant=\"default\" aria-label=\"Default\">\n            <BoldIcon className=\"size-4\" />\n          </Toggle>\n          <Toggle variant=\"outline\" aria-label=\"Outline\">\n            <BoldIcon className=\"size-4\" />\n          </Toggle>\n        </div>\n      </div>\n      <div className=\"flex flex-col gap-2\">\n        <p className=\"text-sm font-medium text-muted-foreground\">size</p>\n        <div className=\"flex items-center gap-2\">\n          <Toggle size=\"sm\" aria-label=\"Small\">\n            <BoldIcon className=\"size-4\" />\n          </Toggle>\n          <Toggle size=\"default\" aria-label=\"Default\">\n            <BoldIcon className=\"size-4\" />\n          </Toggle>\n          <Toggle size=\"lg\" aria-label=\"Large\">\n            <BoldIcon className=\"size-4\" />\n          </Toggle>\n        </div>\n      </div>\n    </div>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/stories/tooltip.stories.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Meta, StoryObj } from '@storybook/react'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip'\nimport { Button } from '../button'\n\nconst meta: Meta<typeof Tooltip> = {\n  title: 'UI/Tooltip',\n  component: Tooltip,\n}\n\nexport default meta\ntype Story = StoryObj<typeof Tooltip>\n\nexport const Default: Story = {\n  render: () => (\n    <Tooltip>\n      <TooltipTrigger asChild>\n        <Button variant=\"outline\">Hover me</Button>\n      </TooltipTrigger>\n      <TooltipContent>\n        <p>Tooltip content</p>\n      </TooltipContent>\n    </Tooltip>\n  ),\n}\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/switch.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport { cn } from '@/lib/utils'\nimport * as SwitchPrimitive from '@radix-ui/react-switch'\nimport * as React from 'react'\n\nfunction Switch({\n  className,\n  size = 'default',\n  ...props\n}: React.ComponentProps<typeof SwitchPrimitive.Root> & {\n  size?: 'sm' | 'default'\n}) {\n  return (\n    <SwitchPrimitive.Root\n      data-slot=\"switch\"\n      data-size={size}\n      className={cn(\n        'data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 dark:data-[state=unchecked]:bg-input/80 shrink-0 rounded-full border border-transparent focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] peer group/switch relative inline-flex items-center transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n        className,\n      )}\n      {...props}\n    >\n      <SwitchPrimitive.Thumb\n        data-slot=\"switch-thumb\"\n        className=\"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground rounded-full group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-[state=checked]:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-[state=checked]:translate-x-[calc(100%-2px)] group-data-[size=default]/switch:data-[state=unchecked]:translate-x-0 group-data-[size=sm]/switch:data-[state=unchecked]:translate-x-0 pointer-events-none block ring-0 transition-transform\"\n      />\n    </SwitchPrimitive.Root>\n  )\n}\nexport { Switch }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/table.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(\n  ({ className, ...props }, ref) => (\n    <div className=\"flex-1 w-full overflow-auto rounded-md scrollbar-thin scrollbar-thumb-border scrollbar-track-background\">\n      <table ref={ref} className={cn('w-full caption-bottom text-sm', className)} {...props} />\n    </div>\n  ),\n)\nTable.displayName = 'Table'\n\nconst TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => <thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />,\n)\nTableHeader.displayName = 'TableHeader'\n\nconst TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => (\n    <tbody ref={ref} className={cn('[&_tr:last-child]:border-0', '[&_tr]:h-10', className)} {...props} />\n  ),\n)\nTableBody.displayName = 'TableBody'\n\nconst TableFooter = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(\n  ({ className, ...props }, ref) => (\n    <tfoot ref={ref} className={cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', className)} {...props} />\n  ),\n)\nTableFooter.displayName = 'TableFooter'\n\nconst TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(\n  ({ className, ...props }, ref) => (\n    <tr\n      ref={ref}\n      className={cn(\n        'bg-background border-b transition-colors data-[state=selected]:bg-muted/25 dark:data-[state=selected]:bg-muted/25',\n        className,\n      )}\n      {...props}\n    />\n  ),\n)\nTableRow.displayName = 'TableRow'\n\nconst TableHead = React.forwardRef<\n  HTMLTableCellElement,\n  React.ThHTMLAttributes<HTMLTableCellElement> & { sticky?: 'left' | 'right' }\n>(({ className, sticky, ...props }, ref) => (\n  <th\n    ref={ref}\n    className={cn(\n      'bg-inherit h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',\n      sticky && cn('sticky', 'z-10', sticky === 'left' ? 'left-0' : 'right-0'),\n      className,\n    )}\n    {...props}\n  />\n))\nTableHead.displayName = 'TableHead'\n\nconst TableCell = React.forwardRef<\n  HTMLTableCellElement,\n  React.TdHTMLAttributes<HTMLTableCellElement> & { sticky?: 'left' | 'right' }\n>(({ className, sticky, ...props }, ref) => (\n  <td\n    ref={ref}\n    className={cn(\n      'bg-inherit p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',\n      sticky && cn('sticky', 'z-[1]', sticky === 'left' ? 'left-0' : 'right-0'),\n      className,\n    )}\n    {...props}\n  />\n))\nTableCell.displayName = 'TableCell'\n\nconst TableCaption = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(\n  ({ className, ...props }, ref) => (\n    <caption ref={ref} className={cn('mt-4 text-sm text-muted-foreground', className)} {...props} />\n  ),\n)\nTableCaption.displayName = 'TableCaption'\n\nexport { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/tabs.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\ntype TabsVariant = 'default' | 'underline'\n\nconst TabsVariantContext = React.createContext<TabsVariant>('default')\n\nfunction Tabs({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Root>) {\n  return <TabsPrimitive.Root data-slot=\"tabs\" className={cn('flex flex-col gap-2', className)} {...props} />\n}\n\nfunction TabsList({\n  className,\n  variant = 'default',\n  ...props\n}: React.ComponentProps<typeof TabsPrimitive.List> & { variant?: TabsVariant }) {\n  return (\n    <TabsVariantContext.Provider value={variant}>\n      <TabsPrimitive.List\n        data-slot=\"tabs-list\"\n        className={cn(\n          variant === 'underline'\n            ? 'inline-flex items-center w-full bg-transparent border-b border-border rounded-none h-auto p-0 gap-0 justify-start shrink-0 text-muted-foreground'\n            : 'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',\n          className,\n        )}\n        {...props}\n      />\n    </TabsVariantContext.Provider>\n  )\n}\n\nfunction TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {\n  const variant = React.useContext(TabsVariantContext)\n  return (\n    <TabsPrimitive.Trigger\n      data-slot=\"tabs-trigger\"\n      className={cn(\n        variant === 'underline'\n          ? 'inline-flex items-center justify-center whitespace-nowrap rounded-none border-b-2 border-transparent px-4 py-2.5 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:border-foreground data-[state=active]:bg-transparent data-[state=active]:text-foreground data-[state=active]:shadow-none'\n          : 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-card data-[state=active]:text-foreground data-[state=active]:shadow',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {\n  return <TabsPrimitive.Content data-slot=\"tabs-content\" className={cn('flex-1 outline-none', className)} {...props} />\n}\n\nexport { Tabs, TabsContent, TabsList, TabsTrigger }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/textarea.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/toggle-group.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'\nimport { type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\nimport { toggleVariants } from './toggle'\n\nconst ToggleGroupContext = React.createContext<\n  VariantProps<typeof toggleVariants> & {\n    spacing?: number\n  }\n>({\n  size: 'default',\n  variant: 'default',\n  spacing: 0,\n})\n\nfunction ToggleGroup({\n  className,\n  variant,\n  size,\n  spacing = 0,\n  children,\n  ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &\n  VariantProps<typeof toggleVariants> & {\n    spacing?: number\n  }) {\n  return (\n    <ToggleGroupPrimitive.Root\n      data-slot=\"toggle-group\"\n      data-variant={variant}\n      data-size={size}\n      data-spacing={spacing}\n      style={{ '--gap': spacing } as React.CSSProperties}\n      className={cn(\n        'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs',\n        className,\n      )}\n      {...props}\n    >\n      <ToggleGroupContext.Provider value={{ variant, size, spacing }}>{children}</ToggleGroupContext.Provider>\n    </ToggleGroupPrimitive.Root>\n  )\n}\n\nfunction ToggleGroupItem({\n  className,\n  children,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>) {\n  const context = React.useContext(ToggleGroupContext)\n\n  return (\n    <ToggleGroupPrimitive.Item\n      data-slot=\"toggle-group-item\"\n      data-variant={context.variant || variant}\n      data-size={context.size || size}\n      data-spacing={context.spacing}\n      className={cn(\n        toggleVariants({\n          variant: context.variant || variant,\n          size: context.size || size,\n        }),\n        'w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10',\n        'data-[spacing=\"0\"]:rounded-none data-[spacing=\"0\"]:shadow-none data-[spacing=\"0\"]:first:rounded-l-md data-[spacing=\"0\"]:last:rounded-r-md data-[spacing=\"0\"]:data-[variant=outline]:border-l-0 data-[spacing=\"0\"]:data-[variant=outline]:first:border-l',\n        className,\n      )}\n      {...props}\n    >\n      {children}\n    </ToggleGroupPrimitive.Item>\n  )\n}\n\nexport { ToggleGroup, ToggleGroupItem }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/toggle.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as TogglePrimitive from '@radix-ui/react-toggle'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst toggleVariants = cva(\n  \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap data-[state=on]:bg-accent data-[state=on]:text-accent-foreground\",\n  {\n    variants: {\n      variant: {\n        default: 'bg-transparent',\n        outline:\n          'border border-border bg-transparent shadow-xs hover:bg-accent/50 hover:text-accent-foreground text-muted-foreground',\n      },\n      size: {\n        default: 'h-9 px-2 min-w-9',\n        sm: 'h-8 px-1.5 min-w-8 text-xs',\n        lg: 'h-10 px-2.5 min-w-10',\n      },\n    },\n    defaultVariants: {\n      variant: 'default',\n      size: 'default',\n    },\n  },\n)\n\nfunction Toggle({\n  className,\n  variant,\n  size,\n  ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>) {\n  return (\n    <TogglePrimitive.Root data-slot=\"toggle\" className={cn(toggleVariants({ variant, size, className }))} {...props} />\n  )\n}\n\nexport { Toggle, toggleVariants }\n"
  },
  {
    "path": "apps/dashboard/src/components/ui/tooltip.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nfunction TooltipProvider({ delayDuration = 0, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n  return <TooltipPrimitive.Provider data-slot=\"tooltip-provider\" delayDuration={delayDuration} {...props} />\n}\n\nfunction Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n  return (\n    <TooltipProvider>\n      <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n    </TooltipProvider>\n  )\n}\n\nfunction TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n  className,\n  sideOffset = 4,\n  children,\n  ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n  return (\n    <TooltipPrimitive.Portal>\n      <TooltipPrimitive.Content\n        data-slot=\"tooltip-content\"\n        sideOffset={sideOffset}\n        className={cn(\n          'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n          className,\n        )}\n        {...props}\n      >\n        {children}\n      </TooltipPrimitive.Content>\n    </TooltipPrimitive.Portal>\n  )\n}\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n"
  },
  {
    "path": "apps/dashboard/src/constants/CreateApiKeyPermissionsGroups.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CreateApiKeyPermissionsEnum } from '@daytonaio/api-client'\n\nexport const CREATE_API_KEY_PERMISSIONS_GROUPS: { name: string; permissions: CreateApiKeyPermissionsEnum[] }[] = [\n  {\n    name: 'Sandboxes',\n    permissions: [CreateApiKeyPermissionsEnum.WRITE_SANDBOXES, CreateApiKeyPermissionsEnum.DELETE_SANDBOXES],\n  },\n  {\n    name: 'Snapshots',\n    permissions: [CreateApiKeyPermissionsEnum.WRITE_SNAPSHOTS, CreateApiKeyPermissionsEnum.DELETE_SNAPSHOTS],\n  },\n  {\n    name: 'Registries',\n    permissions: [CreateApiKeyPermissionsEnum.WRITE_REGISTRIES, CreateApiKeyPermissionsEnum.DELETE_REGISTRIES],\n  },\n  {\n    name: 'Volumes',\n    permissions: [\n      CreateApiKeyPermissionsEnum.READ_VOLUMES,\n      CreateApiKeyPermissionsEnum.WRITE_VOLUMES,\n      CreateApiKeyPermissionsEnum.DELETE_VOLUMES,\n    ],\n  },\n  {\n    name: 'Regions',\n    permissions: [CreateApiKeyPermissionsEnum.WRITE_REGIONS, CreateApiKeyPermissionsEnum.DELETE_REGIONS],\n  },\n  {\n    name: 'Runners',\n    permissions: [\n      CreateApiKeyPermissionsEnum.READ_RUNNERS,\n      CreateApiKeyPermissionsEnum.WRITE_RUNNERS,\n      CreateApiKeyPermissionsEnum.DELETE_RUNNERS,\n    ],\n  },\n  {\n    name: 'Audit',\n    permissions: [CreateApiKeyPermissionsEnum.READ_AUDIT_LOGS],\n  },\n]\n"
  },
  {
    "path": "apps/dashboard/src/constants/ExternalLinks.ts",
    "content": "/**\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * External URLs for Daytona resources\n */\nexport const DAYTONA_DOCS_URL = 'https://www.daytona.io/docs'\nexport const DAYTONA_SLACK_URL = 'https://go.daytona.io/slack'\n"
  },
  {
    "path": "apps/dashboard/src/constants/OrganizationPermissionsGroups.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OrganizationRolePermissionsEnum } from '@daytonaio/api-client'\n\nexport const ORGANIZATION_ROLE_PERMISSIONS_GROUPS: { name: string; permissions: OrganizationRolePermissionsEnum[] }[] =\n  [\n    {\n      name: 'Sandboxes',\n      permissions: [OrganizationRolePermissionsEnum.WRITE_SANDBOXES, OrganizationRolePermissionsEnum.DELETE_SANDBOXES],\n    },\n    {\n      name: 'Snapshots',\n      permissions: [OrganizationRolePermissionsEnum.WRITE_SNAPSHOTS, OrganizationRolePermissionsEnum.DELETE_SNAPSHOTS],\n    },\n    {\n      name: 'Registries',\n      permissions: [\n        OrganizationRolePermissionsEnum.WRITE_REGISTRIES,\n        OrganizationRolePermissionsEnum.DELETE_REGISTRIES,\n      ],\n    },\n    {\n      name: 'Volumes',\n      permissions: [\n        OrganizationRolePermissionsEnum.READ_VOLUMES,\n        OrganizationRolePermissionsEnum.WRITE_VOLUMES,\n        OrganizationRolePermissionsEnum.DELETE_VOLUMES,\n      ],\n    },\n  ]\n"
  },
  {
    "path": "apps/dashboard/src/constants/Pagination.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const PAGE_SIZE_OPTIONS = [10, 25, 50, 100, 200] as const\nexport const DEFAULT_PAGE_SIZE = 25\n"
  },
  {
    "path": "apps/dashboard/src/constants/Playground.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const DEFAULT_CPU_RESOURCES = 1\n\nexport const DEFAULT_MEMORY_RESOURCES = 1\n\nexport const DEFAULT_DISK_RESOURCES = 3\n\nexport const SANDBOX_SNAPSHOT_DEFAULT_VALUE = 'Default'\n"
  },
  {
    "path": "apps/dashboard/src/constants/limits.ts",
    "content": "/**\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const TIER_REQUIREMENTS: Record<number, string[]> = {\n  1: ['Email verification'],\n  2: ['Credit card linked', 'GitHub connected', 'Top up $25 (one time)'],\n  3: ['Business email verified', 'Top up $500 (one time)'],\n  4: ['Top up $2,000 (every 30 days)'],\n}\n\nexport const TIER_RATE_LIMITS: Record<\n  number,\n  { authenticatedRateLimit: number; sandboxCreateRateLimit: number; sandboxLifecycleRateLimit: number }\n> = {\n  1: {\n    authenticatedRateLimit: 10_000,\n    sandboxCreateRateLimit: 300,\n    sandboxLifecycleRateLimit: 10_000,\n  },\n  2: {\n    authenticatedRateLimit: 20_000,\n    sandboxCreateRateLimit: 400,\n    sandboxLifecycleRateLimit: 20_000,\n  },\n  3: {\n    authenticatedRateLimit: 40_000,\n    sandboxCreateRateLimit: 500,\n    sandboxLifecycleRateLimit: 40_000,\n  },\n  4: {\n    authenticatedRateLimit: 50_000,\n    sandboxCreateRateLimit: 600,\n    sandboxLifecycleRateLimit: 50_000,\n  },\n}\n"
  },
  {
    "path": "apps/dashboard/src/constants/metrics.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const METRIC_DISPLAY_NAMES: Record<string, string> = {\n  'daytona.sandbox.cpu.utilization': 'CPU Utilization',\n  'daytona.sandbox.cpu.limit': 'CPU Limit',\n  'daytona.sandbox.memory.utilization': 'Memory Utilization',\n  'daytona.sandbox.memory.usage': 'Memory Usage',\n  'daytona.sandbox.memory.limit': 'Memory Limit',\n  'daytona.sandbox.filesystem.utilization': 'Disk Utilization',\n  'daytona.sandbox.filesystem.usage': 'Disk Usage',\n  'daytona.sandbox.filesystem.total': 'Disk Total',\n  'daytona.sandbox.filesystem.available': 'Disk Available',\n  'system.memory.utilization': 'System Memory Utilization',\n}\n\nexport function getMetricDisplayName(metricName: string): string {\n  return METRIC_DISPLAY_NAMES[metricName] ?? metricName.replace(/^daytona\\.sandbox\\./, '')\n}\n"
  },
  {
    "path": "apps/dashboard/src/constants/webhook-events.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { WebhookEvent } from '@daytonaio/api-client'\n\nexport const WEBHOOK_EVENTS: Array<{ value: WebhookEvent; label: string; category: string }> = [\n  { value: WebhookEvent.SANDBOX_CREATED, label: 'Sandbox Created', category: 'Sandbox' },\n  { value: WebhookEvent.SANDBOX_STATE_UPDATED, label: 'Sandbox State Updated', category: 'Sandbox' },\n  { value: WebhookEvent.SNAPSHOT_CREATED, label: 'Snapshot Created', category: 'Snapshot' },\n  { value: WebhookEvent.SNAPSHOT_REMOVED, label: 'Snapshot Removed', category: 'Snapshot' },\n  { value: WebhookEvent.SNAPSHOT_STATE_UPDATED, label: 'Snapshot State Updated', category: 'Snapshot' },\n  { value: WebhookEvent.VOLUME_CREATED, label: 'Volume Created', category: 'Volume' },\n  { value: WebhookEvent.VOLUME_STATE_UPDATED, label: 'Volume State Updated', category: 'Volume' },\n] as const\n\nexport const WEBHOOK_EVENT_CATEGORIES = ['Sandbox', 'Snapshot', 'Volume'] as const\n\nexport type WebhookEventValue = (typeof WEBHOOK_EVENTS)[number]['value']\nexport type WebhookEventCategory = (typeof WEBHOOK_EVENT_CATEGORIES)[number]\n"
  },
  {
    "path": "apps/dashboard/src/contexts/ApiContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiClient } from '@/api/apiClient'\nimport { createContext } from 'react'\n\nexport const ApiContext = createContext<ApiClient | null>(null)\n"
  },
  {
    "path": "apps/dashboard/src/contexts/ConfigContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DashboardConfig } from '@/types/DashboardConfig'\nimport { createContext } from 'react'\n\nexport const ConfigContext = createContext<DashboardConfig | null>(null)\n"
  },
  {
    "path": "apps/dashboard/src/contexts/NotificationSocketContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { createContext } from 'react'\nimport { Socket } from 'socket.io-client'\n\nexport interface INotificationSocketContext {\n  notificationSocket: Socket | null\n}\n\nexport const NotificationSocketContext = createContext<INotificationSocketContext | undefined>(undefined)\n"
  },
  {
    "path": "apps/dashboard/src/contexts/OrganizationsContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Organization } from '@daytonaio/api-client'\nimport { createContext } from 'react'\n\nexport interface IOrganizationsContext {\n  organizations: Organization[]\n  refreshOrganizations: (selectedOrganizationId?: string) => Promise<void>\n}\n\nexport const OrganizationsContext = createContext<IOrganizationsContext | undefined>(undefined)\n"
  },
  {
    "path": "apps/dashboard/src/contexts/PlaygroundContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  FileSystemActions,\n  GitOperationsActions,\n  KeyboardActions,\n  MouseActions,\n  MouseButton,\n  MouseScrollDirection,\n  PlaygroundActions,\n  ProcessCodeExecutionActions,\n  SandboxParametersSections,\n  ScreenshotActions,\n  ScreenshotFormatOption,\n} from '@/enums/Playground'\nimport {\n  CodeLanguage,\n  ComputerUse,\n  CreateSandboxBaseParams,\n  CreateSandboxFromImageParams,\n  CreateSandboxFromSnapshotParams,\n  Resources,\n  ScreenshotOptions,\n  ScreenshotRegion,\n} from '@daytonaio/sdk'\nimport { createContext, ReactNode } from 'react'\n\nexport interface ParameterFormItem {\n  label: string\n  placeholder: string\n  key: string\n  required?: boolean\n}\n\nexport interface NumberParameterFormItem extends ParameterFormItem {\n  min: number\n  max: number\n  step?: number\n}\n\n// keyof (A | B | C) gives intersections of types i.e. type = common properties to A,B,C\n// KeysOf gives us keyof A | keyof B | keyof C behaviour\nexport type KeysOf<T> = T extends any ? keyof T : never\n\nexport type ParameterFormData<T> = ((ParameterFormItem | NumberParameterFormItem) & { key: KeysOf<T> })[]\n\n// Form data structure for actions which don't require any parameters for their execution\nexport interface PlaygroundActionFormDataBasic<A> {\n  label: string\n  description: string\n  methodName: A\n  onChangeParamsValidationDisabled?: boolean\n}\n\n// Form data structure for actions which use certain parameters for their execution\nexport type PlaygroundActionWithParamsFormData<A, T> = PlaygroundActionFormDataBasic<A> & {\n  parametersFormItems: ParameterFormData<T>\n  parametersState: T\n}\n\n// --- VNC param types ---\n\nexport type KeyboardHotKey = {\n  keys: string\n}\n\nexport type KeyboardPress = {\n  key: string\n  modifiers?: string\n}\n\nexport type KeyboardType = {\n  text: string\n  delay?: number\n}\n\nexport type MouseClick = {\n  x: number\n  y: number\n  button?: MouseButton\n  double?: boolean\n}\n\nexport type MouseDrag = {\n  startX: number\n  startY: number\n  endX: number\n  endY: number\n  button?: MouseButton\n}\n\nexport type MouseMove = {\n  x: number\n  y: number\n}\n\nexport type MouseScroll = {\n  x: number\n  y: number\n  direction: MouseScrollDirection\n  amount?: number\n}\n\nexport interface CustomizedScreenshotOptions extends Omit<ScreenshotOptions, 'format'> {\n  format?: ScreenshotFormatOption\n}\n\n// --- VNC component types ---\n\nexport type WrapVNCInvokeApiType = (\n  invokeApi: PlaygroundActionInvokeApi,\n) => <A, T>(\n  actionFormData: PlaygroundActionFormDataBasic<A> | PlaygroundActionWithParamsFormData<A, T>,\n) => Promise<void>\n\nexport type VNCInteractionOptionsSectionComponentProps = {\n  disableActions: boolean\n  ComputerUseClient: ComputerUse | null\n  wrapVNCInvokeApi: WrapVNCInvokeApiType\n}\n\n// --- Action-specific form data types ---\n\nexport type KeyboardActionFormData<T extends KeyboardHotKey | KeyboardPress | KeyboardType> =\n  PlaygroundActionWithParamsFormData<KeyboardActions, T>\n\nexport type MouseActionFormData<T extends MouseClick | MouseDrag | MouseMove | MouseScroll> =\n  PlaygroundActionWithParamsFormData<MouseActions, T>\n\nexport type ScreenshotActionFormData<T extends ScreenshotRegion | CustomizedScreenshotOptions> =\n  PlaygroundActionWithParamsFormData<ScreenshotActions, T>\n\n// --- Sandbox param types ---\n\nexport type ListFilesParams = {\n  directoryPath: string\n}\n\nexport type CreateFolderParams = {\n  folderDestinationPath: string\n  permissions: string\n}\n\nexport type DeleteFileParams = {\n  filePath: string\n  recursive?: boolean\n}\n\nexport type GitCloneParams = {\n  repositoryURL: string\n  cloneDestinationPath: string\n  branchToClone?: string\n  commitToClone?: string\n  authUsername?: string\n  authPassword?: string\n}\n\nexport type GitStatusParams = {\n  repositoryPath: string\n}\n\nexport type GitBranchesParams = {\n  repositoryPath: string\n}\n\nexport type CodeRunParams = {\n  languageCode?: string\n}\n\nexport type ShellCommandRunParams = {\n  shellCommand?: string\n}\n\nexport type FileSystemActionFormData<T extends ListFilesParams | CreateFolderParams | DeleteFileParams> =\n  PlaygroundActionWithParamsFormData<FileSystemActions, T>\n\nexport type GitOperationsActionFormData<T extends GitCloneParams | GitStatusParams | GitBranchesParams> =\n  PlaygroundActionWithParamsFormData<GitOperationsActions, T>\n\nexport type ProcessCodeExecutionOperationsActionFormData<T extends CodeRunParams | ShellCommandRunParams> =\n  PlaygroundActionWithParamsFormData<ProcessCodeExecutionActions, T>\n\nexport interface SandboxParams {\n  language?: CodeLanguage\n  snapshotName?: string\n  resources: Resources\n  createSandboxBaseParams: CreateSandboxBaseParams\n  // File system operations params\n  listFilesParams: ListFilesParams\n  createFolderParams: CreateFolderParams\n  deleteFileParams: DeleteFileParams\n  // Git operations params\n  gitCloneParams: GitCloneParams\n  gitStatusParams: GitStatusParams\n  gitBranchesParams: GitBranchesParams\n  // Process and Code Execution params\n  codeRunParams: CodeRunParams\n  shellCommandRunParams: ShellCommandRunParams\n}\n\nexport type SetSandboxParamsValue = <K extends keyof SandboxParams>(key: K, value: SandboxParams[K]) => void\n\nexport interface VNCInteractionOptionsParams {\n  keyboardHotKeyParams: KeyboardHotKey\n  keyboardPressParams: KeyboardPress\n  keyboardTypeParams: KeyboardType\n  mouseClickParams: MouseClick\n  mouseDragParams: MouseDrag\n  mouseMoveParams: MouseMove\n  mouseScrollParams: MouseScroll\n  screenshotOptionsConfig: CustomizedScreenshotOptions\n  screenshotRegionConfig: ScreenshotRegion\n  responseContent?: string | ReactNode\n}\n\nexport type SetVNCInteractionOptionsParamValue = <K extends keyof VNCInteractionOptionsParams>(\n  key: K,\n  value: VNCInteractionOptionsParams[K],\n) => void\n\nexport type PlaygroundActionParams = SandboxParams & VNCInteractionOptionsParams\n\nexport type SetPlaygroundActionParamValue = <K extends keyof PlaygroundActionParams>(\n  key: K,\n  value: PlaygroundActionParams[K],\n) => void\n\n// Currently running action, or none\nexport type RunningActionMethodName = PlaygroundActions | null\n\n// Mapping between action and runtime error message (if any)\nexport type ActionRuntimeError = Partial<Record<PlaygroundActions, string>>\n\n// Method for validation of required params for a given action\nexport type ValidatePlaygroundActionRequiredParams = <T>(\n  actionParamsFormData: ParameterFormData<T>,\n  actionParamsState: T,\n) => string | undefined\n\n// Basic method which runs an action that has no params\nexport type RunPlaygroundActionBasic = <A extends PlaygroundActions>(\n  actionFormData: PlaygroundActionFormDataBasic<A>,\n  invokeApi: PlaygroundActionInvokeApi,\n) => Promise<void>\n\n// Runs an action that requires params\nexport type RunPlaygroundActionWithParams = <A extends PlaygroundActions, T>(\n  actionFormData: PlaygroundActionWithParamsFormData<A, T>,\n  invokeApi: PlaygroundActionInvokeApi,\n) => Promise<void>\n\nexport type PlaygroundActionInvokeApi = <A, T>(\n  actionFormData: PlaygroundActionFormDataBasic<A> | PlaygroundActionWithParamsFormData<A, T>,\n) => Promise<void>\n\nexport type ValidatePlaygroundActionWithParams = <A extends PlaygroundActions, T>(\n  actionFormData: PlaygroundActionWithParamsFormData<A, T>,\n  parametersState: T,\n) => void\n\nexport type PlaygroundActionParamValueSetter = <A extends PlaygroundActions, T>(\n  actionFormData: PlaygroundActionWithParamsFormData<A, T>,\n  paramFormData: ParameterFormItem,\n  actionParamsKey: keyof PlaygroundActionParams,\n  value: any,\n) => void\n\nexport type SandboxParametersInfo = {\n  useLanguageParam: boolean\n  useResources: boolean\n  useResourcesCPU: boolean\n  useResourcesMemory: boolean\n  useResourcesDisk: boolean\n  createSandboxParamsExist: boolean\n  useAutoStopInterval: boolean\n  useAutoArchiveInterval: boolean\n  useAutoDeleteInterval: boolean\n  useSandboxCreateParams: boolean\n  useCustomSandboxSnapshotName: boolean\n  createSandboxFromImage: boolean\n  createSandboxFromSnapshot: boolean\n  createSandboxParams: CreateSandboxBaseParams | CreateSandboxFromImageParams | CreateSandboxFromSnapshotParams\n}\n\nexport interface IPlaygroundContext {\n  sandboxParametersState: SandboxParams\n  setSandboxParameterValue: SetSandboxParamsValue\n  VNCInteractionOptionsParamsState: VNCInteractionOptionsParams\n  setVNCInteractionOptionsParamValue: SetVNCInteractionOptionsParamValue\n  runPlaygroundActionWithParams: RunPlaygroundActionWithParams\n  runPlaygroundActionWithoutParams: RunPlaygroundActionBasic\n  validatePlaygroundActionWithParams: ValidatePlaygroundActionWithParams\n  playgroundActionParamValueSetter: PlaygroundActionParamValueSetter\n  runningActionMethod: RunningActionMethodName\n  actionRuntimeError: ActionRuntimeError\n  getSandboxParametersInfo: () => SandboxParametersInfo\n  openedParametersSections: SandboxParametersSections[]\n  setOpenedParametersSections: React.Dispatch<React.SetStateAction<SandboxParametersSections[]>>\n  enabledSections: SandboxParametersSections[]\n  enableSection: (section: SandboxParametersSections) => void\n  disableSection: (section: SandboxParametersSections) => void\n  pendingScrollSection: SandboxParametersSections | null\n  clearPendingScrollSection: () => void\n}\n\nexport const PlaygroundContext = createContext<IPlaygroundContext | null>(null)\n"
  },
  {
    "path": "apps/dashboard/src/contexts/RegionsContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Region } from '@daytonaio/api-client'\nimport { createContext } from 'react'\n\nexport interface IRegionsContext {\n  sharedRegions: Region[]\n  loadingSharedRegions: boolean\n  availableRegions: Region[]\n  loadingAvailableRegions: boolean\n  customRegions: Region[]\n  refreshAvailableRegions: () => Promise<Region[]>\n  getRegionName: (regionId: string) => string | undefined\n}\n\nexport const RegionsContext = createContext<IRegionsContext | undefined>(undefined)\n"
  },
  {
    "path": "apps/dashboard/src/contexts/SandboxSessionContext.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { createContext } from 'react'\n\nexport interface ISandboxSessionContext {\n  isTerminalActivated: (sandboxId: string) => boolean\n  activateTerminal: (sandboxId: string) => void\n  isVncActivated: (sandboxId: string) => boolean\n  activateVnc: (sandboxId: string) => void\n}\n\nexport const SandboxSessionContext = createContext<ISandboxSessionContext | null>(null)\n"
  },
  {
    "path": "apps/dashboard/src/contexts/SelectedOrganizationContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Organization, OrganizationRolePermissionsEnum, OrganizationUser } from '@daytonaio/api-client'\n\nimport { createContext } from 'react'\n\nexport interface ISelectedOrganizationContext {\n  selectedOrganization: Organization | null\n  organizationMembers: OrganizationUser[]\n  refreshOrganizationMembers: () => Promise<OrganizationUser[]>\n  authenticatedUserOrganizationMember: OrganizationUser | null\n  authenticatedUserHasPermission: (permission: OrganizationRolePermissionsEnum) => boolean\n  onSelectOrganization: (organizationId: string) => Promise<boolean>\n}\n\nexport const SelectedOrganizationContext = createContext<ISelectedOrganizationContext | undefined>(undefined)\n"
  },
  {
    "path": "apps/dashboard/src/contexts/ThemeContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { createContext, useContext, useEffect, useState } from 'react'\n\ntype Theme = 'dark' | 'light'\n\ntype ThemeProviderProps = {\n  children: React.ReactNode\n  defaultTheme?: Theme\n  storageKey?: string\n}\n\ntype ThemeProviderState = {\n  theme: Theme\n  setTheme: (theme: Theme) => void\n}\n\nconst initialState: ThemeProviderState = {\n  theme: 'dark',\n  setTheme: () => null,\n}\n\nconst ThemeProviderContext = createContext<ThemeProviderState>(initialState)\n\nasync function runWithoutAnimation<T>(callback: () => T | Promise<T>): Promise<T> {\n  const style = document.createElement('style')\n  style.appendChild(\n    document.createTextNode(`*, *::before, *::after { transition: none !important; animation: none !important; }`),\n  )\n  document.head.appendChild(style)\n\n  try {\n    return await callback()\n  } finally {\n    window.getComputedStyle(document.body)\n\n    setTimeout(() => {\n      if (document.head.contains(style)) {\n        document.head.removeChild(style)\n      }\n    }, 1)\n  }\n}\n\nexport function ThemeProvider({\n  children,\n  defaultTheme = 'dark',\n  storageKey = 'vite-ui-theme',\n  ...props\n}: ThemeProviderProps) {\n  const [theme, setTheme] = useState<Theme>(() => (localStorage.getItem(storageKey) as Theme) || defaultTheme)\n\n  useEffect(() => {\n    runWithoutAnimation(() => {\n      const root = window.document.documentElement\n\n      root.classList.remove('light', 'dark')\n\n      root.classList.add(theme)\n    })\n  }, [theme])\n\n  const value = {\n    theme,\n    setTheme: (theme: Theme) => {\n      localStorage.setItem(storageKey, theme)\n      setTheme(theme)\n    },\n  }\n\n  return (\n    <ThemeProviderContext.Provider {...props} value={value}>\n      {children}\n    </ThemeProviderContext.Provider>\n  )\n}\n\nexport const useTheme = () => {\n  const context = useContext(ThemeProviderContext)\n\n  if (context === undefined) throw new Error('useTheme must be used within a ThemeProvider')\n\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/contexts/UserOrganizationInvitationsContext.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { createContext } from 'react'\n\nexport interface IUserOrganizationInvitationsContext {\n  count: number\n  setCount(count: number): void\n}\n\nexport const UserOrganizationInvitationsContext = createContext<IUserOrganizationInvitationsContext | undefined>(\n  undefined,\n)\n"
  },
  {
    "path": "apps/dashboard/src/enums/FeatureFlags.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum FeatureFlags {\n  ORGANIZATION_INFRASTRUCTURE = 'organization_infrastructure',\n  ORGANIZATION_EXPERIMENTS = 'organization_experiments',\n  DASHBOARD_PLAYGROUND = 'dashboard_playground',\n  DASHBOARD_WEBHOOKS = 'dashboard_webhooks',\n  SANDBOX_SPENDING = 'sandbox_spending',\n  DASHBOARD_CREATE_SANDBOX = 'dashboard_create-sandbox',\n}\n"
  },
  {
    "path": "apps/dashboard/src/enums/LocalStorageKey.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum LocalStorageKey {\n  SelectedOrganizationId = 'SelectedOrganizationId',\n  SkipOnboardingPrefix = 'SkipOnboarding_',\n  AnnouncementBannerDismissed = 'AnnouncementBannerDismissed',\n  SandboxTableColumnVisibility = 'SandboxTableColumnVisibility',\n}\n"
  },
  {
    "path": "apps/dashboard/src/enums/Playground.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport enum PlaygroundCategories {\n  SANDBOX = 'sandbox',\n  TERMINAL = 'terminal',\n  VNC = 'vnc',\n}\n\nexport enum SandboxParametersSections {\n  SANDBOX_MANAGEMENT = 'sandbox_management',\n  FILE_SYSTEM = 'file_system',\n  GIT_OPERATIONS = 'git_operations',\n  PROCESS_CODE_EXECUTION = 'process_code_execution',\n}\n\nexport enum VNCInteractionOptionsSections {\n  DISPLAY = 'display',\n  KEYBOARD = 'keyboard',\n  MOUSE = 'mouse',\n  SCREENSHOT = 'screenshot',\n}\n\nexport enum DisplayActions {\n  GET_INFO = 'getInfo',\n  GET_WINDOWS = 'getWindows',\n}\n\nexport enum KeyboardActions {\n  HOTKEY = 'hotkey',\n  PRESS = 'press',\n  TYPE = 'type',\n}\n\nexport enum MouseButton {\n  LEFT = 'left',\n  RIGHT = 'right',\n  MIDDLE = 'middle',\n}\n\nexport enum MouseScrollDirection {\n  UP = 'up',\n  DOWN = 'down',\n}\n\nexport enum MouseActions {\n  CLICK = 'click',\n  DRAG = 'drag',\n  MOVE = 'move',\n  SCROLL = 'scroll',\n  GET_POSITION = 'getPosition',\n}\n\nexport enum ScreenshotFormatOption {\n  JPEG = 'jpeg',\n  PNG = 'png',\n  WEBP = 'webp',\n}\n\nexport enum ScreenshotActions {\n  TAKE_COMPRESSED = 'takeCompressed',\n  TAKE_COMPRESSED_REGION = 'takeCompressedRegion',\n  TAKE_FULL_SCREEN = 'takeFullScreen',\n  TAKE_REGION = 'takeRegion',\n}\n\nexport enum FileSystemActions {\n  LIST_FILES = 'listFiles',\n  CREATE_FOLDER = 'createFolder',\n  DELETE_FILE = 'deleteFile',\n}\n\nexport enum GitOperationsActions {\n  GIT_CLONE = 'clone',\n  GIT_STATUS = 'status',\n  GIT_BRANCHES_LIST = 'branches',\n}\n\nexport enum ProcessCodeExecutionActions {\n  CODE_RUN = 'codeRun',\n  SHELL_COMMANDS_RUN = 'executeCommand',\n}\n\nexport type SandboxCodeSnippetsActions = FileSystemActions | GitOperationsActions | ProcessCodeExecutionActions\n\nexport type VNCInteractionActions = DisplayActions | KeyboardActions | MouseActions | ScreenshotActions\n\n// Actions enums values represent method names for TypeScript SDK\nexport type PlaygroundActions = VNCInteractionActions | SandboxCodeSnippetsActions\n"
  },
  {
    "path": "apps/dashboard/src/enums/RoutePath.ts",
    "content": "/**\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Enum for all route paths in the application\n * Use this for consistent route references across the app\n */\nexport enum RoutePath {\n  // Main routes\n  LANDING = '/',\n  LOGOUT = '/logout',\n  DASHBOARD = '/dashboard',\n  DOCS = '/docs',\n  SLACK = '/slack',\n\n  // Dashboard sub-routes\n  KEYS = '/dashboard/keys',\n  SANDBOXES = '/dashboard/sandboxes',\n  SNAPSHOTS = '/dashboard/snapshots',\n  REGISTRIES = '/dashboard/registries',\n  VOLUMES = '/dashboard/volumes',\n  LIMITS = '/dashboard/limits',\n  BILLING_SPENDING = '/dashboard/billing/spending',\n  BILLING_WALLET = '/dashboard/billing/wallet',\n  MEMBERS = '/dashboard/members',\n  ROLES = '/dashboard/roles',\n  SETTINGS = '/dashboard/settings',\n  ONBOARDING = '/dashboard/onboarding',\n  AUDIT_LOGS = '/dashboard/audit-logs',\n  REGIONS = '/dashboard/regions',\n  RUNNERS = '/dashboard/runners',\n  EXPERIMENTAL = '/dashboard/experimental',\n  PLAYGROUND = '/dashboard/playground',\n\n  // User routes\n  USER_INVITATIONS = '/dashboard/user/invitations',\n  ACCOUNT_SETTINGS = '/dashboard/user/account-settings',\n\n  // Webhooks\n  WEBHOOKS = '/dashboard/webhooks',\n  WEBHOOK_ENDPOINT_DETAILS = '/dashboard/webhooks/:endpointId',\n  // Sandboxes\n  SANDBOX_DETAILS = '/dashboard/sandboxes/:sandboxId',\n\n  // Email verification\n  EMAIL_VERIFY = '/dashboard/organization/:organizationId/verify-email/:email/:token',\n}\n\n/**\n * Returns only the path segment for dashboard sub-routes\n * Useful for nested routes under the dashboard\n */\nexport const getRouteSubPath = (path: RoutePath): string => {\n  return path.replace('/dashboard/', '')\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useArchiveSandboxMutation.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\ninterface ArchiveSandboxVariables {\n  sandboxId: string\n}\n\nexport const useArchiveSandboxMutation = () => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: async ({ sandboxId }: ArchiveSandboxVariables) => {\n      await sandboxApi.archiveSandbox(sandboxId, selectedOrganization?.id)\n    },\n    onSuccess: (_, { sandboxId }) => {\n      queryClient.invalidateQueries({\n        queryKey: queryKeys.sandboxes.detail(selectedOrganization?.id ?? '', sandboxId),\n      })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useCreateApiKeyMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiKeyResponse, CreateApiKeyPermissionsEnum } from '@daytonaio/api-client'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\nexport interface CreateApiKeyMutationVariables {\n  name: string\n  permissions: CreateApiKeyPermissionsEnum[]\n  expiresAt: Date | null\n  organizationId?: string\n}\n\nexport const useCreateApiKeyMutation = () => {\n  const { apiKeyApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation<ApiKeyResponse, unknown, CreateApiKeyMutationVariables>({\n    mutationFn: async ({ organizationId, name, permissions, expiresAt }) => {\n      const response = await apiKeyApi.createApiKey(\n        {\n          name,\n          permissions,\n          expiresAt: expiresAt ?? undefined,\n        },\n        organizationId,\n      )\n\n      return response.data\n    },\n    onSuccess: async (_data, { organizationId }) => {\n      if (organizationId) {\n        await queryClient.invalidateQueries({ queryKey: queryKeys.apiKeys.list(organizationId) })\n      }\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useCreateInvoicePaymentUrlMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PaymentUrl } from '@/billing-api/types/Invoice'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface CreateInvoicePaymentUrlVariables {\n  organizationId: string\n  invoiceId: string\n}\n\nexport const useCreateInvoicePaymentUrlMutation = () => {\n  const { billingApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation<PaymentUrl, unknown, CreateInvoicePaymentUrlVariables>({\n    mutationFn: ({ organizationId, invoiceId }) => billingApi.createInvoicePaymentUrl(organizationId, invoiceId),\n    onSuccess: (_data, { organizationId }) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.wallet(organizationId) })\n      queryClient.invalidateQueries({ queryKey: queryKeys.billing.invoices(organizationId) })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useCreateSandboxMutation.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CreateSandboxFromImageParams, CreateSandboxFromSnapshotParams, Daytona, Sandbox } from '@daytonaio/sdk'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useAuth } from 'react-oidc-context'\nimport { useSelectedOrganization } from '../useSelectedOrganization'\nimport { getSandboxesQueryKey } from '../useSandboxes'\n\nexport type CreateSandboxParams = (CreateSandboxFromSnapshotParams | CreateSandboxFromImageParams) & {\n  target?: string\n}\n\nexport const useCreateSandboxMutation = () => {\n  const { user } = useAuth()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n\n  return useMutation<Sandbox, unknown, CreateSandboxParams>({\n    mutationFn: async (params) => {\n      if (!user?.access_token || !selectedOrganization?.id) {\n        throw new Error('Missing authentication or organization')\n      }\n\n      const { target, ...createParams } = params\n      const client = new Daytona({\n        jwtToken: user.access_token,\n        apiUrl: import.meta.env.VITE_API_URL,\n        organizationId: selectedOrganization.id,\n        target,\n      })\n\n      if ('image' in createParams) {\n        return await client.create(createParams as CreateSandboxFromImageParams)\n      }\n      return await client.create(createParams as CreateSandboxFromSnapshotParams)\n    },\n    onSuccess: async () => {\n      if (selectedOrganization?.id) {\n        await queryClient.invalidateQueries({ queryKey: getSandboxesQueryKey(selectedOrganization.id) })\n      }\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useCreateSnapshotMutation.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CreateSnapshot, SnapshotDto } from '@daytonaio/api-client'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\nexport interface CreateSnapshotMutationVariables {\n  snapshot: CreateSnapshot\n  organizationId?: string\n}\n\nexport const useCreateSnapshotMutation = () => {\n  const { snapshotApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation<SnapshotDto, unknown, CreateSnapshotMutationVariables>({\n    mutationFn: async ({ snapshot, organizationId }) => {\n      const response = await snapshotApi.createSnapshot(snapshot, organizationId)\n      return response.data\n    },\n    onSuccess: async (_data, { organizationId }) => {\n      if (organizationId) {\n        await queryClient.invalidateQueries({ queryKey: queryKeys.snapshots.all })\n      }\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useCreateSshAccessMutation.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useMutation } from '@tanstack/react-query'\n\ninterface CreateSshAccessVariables {\n  sandboxId: string\n  expiresInMinutes: number\n}\n\nexport const useCreateSshAccessMutation = () => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useMutation({\n    mutationFn: async ({ sandboxId, expiresInMinutes }: CreateSshAccessVariables) => {\n      const response = await sandboxApi.createSshAccess(sandboxId, selectedOrganization?.id, expiresInMinutes)\n      return response.data\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useDeleteOrganizationMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface DeleteOrganizationVariables {\n  organizationId: string\n}\n\nexport const useDeleteOrganizationMutation = () => {\n  const { organizationsApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: ({ organizationId }: DeleteOrganizationVariables) =>\n      organizationsApi.deleteOrganization(organizationId),\n    onSuccess: (_data, { organizationId }) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.list() })\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.detail(organizationId) })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useDeleteSandboxMutation.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\ninterface DeleteSandboxVariables {\n  sandboxId: string\n}\n\nexport const useDeleteSandboxMutation = () => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: async ({ sandboxId }: DeleteSandboxVariables) => {\n      await sandboxApi.deleteSandbox(sandboxId, selectedOrganization?.id)\n    },\n    onSuccess: (_, { sandboxId }) => {\n      queryClient.invalidateQueries({\n        queryKey: queryKeys.sandboxes.detail(selectedOrganization?.id ?? '', sandboxId),\n      })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useDeleteWebhookEndpointMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation } from '@tanstack/react-query'\nimport { useSvix } from 'svix-react'\n\ninterface DeleteWebhookEndpointVariables {\n  endpointId: string\n}\n\nexport const useDeleteWebhookEndpointMutation = () => {\n  const { svix, appId } = useSvix()\n\n  return useMutation({\n    mutationFn: async ({ endpointId }: DeleteWebhookEndpointVariables) => {\n      await svix.endpoint.delete(appId, endpointId)\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useDowngradeTierMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface DowngradeTierParams {\n  organizationId: string\n  tier: number\n}\n\nexport const useDowngradeTierMutation = () => {\n  const { billingApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: ({ organizationId, tier }: DowngradeTierParams) => billingApi.downgradeTier(organizationId, tier),\n    onSuccess: async (_data, { organizationId }) => {\n      await Promise.all([\n        queryClient.invalidateQueries({ queryKey: queryKeys.organization.tier(organizationId) }),\n        queryClient.invalidateQueries({ queryKey: queryKeys.organization.usage.overview(organizationId) }),\n      ])\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useEnrollInSmsMfaMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\n\nexport const useEnrollInSmsMfaMutation = () => {\n  const { userApi } = useApi()\n\n  return useMutation({\n    mutationFn: async () => {\n      const response = await userApi.enrollInSmsMfa()\n      return response.data\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useLeaveOrganizationMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface LeaveOrganizationVariables {\n  organizationId: string\n}\n\nexport const useLeaveOrganizationMutation = () => {\n  const { organizationsApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: ({ organizationId }: LeaveOrganizationVariables) => organizationsApi.leaveOrganization(organizationId),\n    onSuccess: (_data, { organizationId }) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.list() })\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.detail(organizationId) })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useRecoverSandboxMutation.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\ninterface RecoverSandboxVariables {\n  sandboxId: string\n}\n\nexport const useRecoverSandboxMutation = () => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: async ({ sandboxId }: RecoverSandboxVariables) => {\n      await sandboxApi.recoverSandbox(sandboxId, selectedOrganization?.id)\n    },\n    onSuccess: (_, { sandboxId }) => {\n      queryClient.invalidateQueries({\n        queryKey: queryKeys.sandboxes.detail(selectedOrganization?.id ?? '', sandboxId),\n      })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useRedeemCouponMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface RedeemCouponVariables {\n  organizationId: string\n  couponCode: string\n}\n\nexport const useRedeemCouponMutation = () => {\n  const { billingApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation<string, unknown, RedeemCouponVariables>({\n    mutationFn: ({ organizationId, couponCode }) => billingApi.redeemCoupon(organizationId, couponCode),\n    onSuccess: (_data, { organizationId }) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.wallet(organizationId) })\n\n      // a coupon can upgrade the tier\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.tier(organizationId) })\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.usage.overview(organizationId) })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useReplayWebhookEventMutation.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation } from '@tanstack/react-query'\nimport { useSvix } from 'svix-react'\n\ninterface ReplayWebhookEventVariables {\n  endpointId: string\n  msgId: string\n}\n\nexport const useReplayWebhookEventMutation = () => {\n  const { svix, appId } = useSvix()\n\n  return useMutation({\n    mutationFn: async ({ endpointId, msgId }: ReplayWebhookEventVariables) => {\n      return svix.messageAttempt.resend(appId, msgId, endpointId)\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useRevokeApiKeyMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface RevokeApiKeyVariables {\n  userId: string\n  name: string\n  organizationId?: string\n}\n\nexport const useRevokeApiKeyMutation = () => {\n  const { apiKeyApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: ({ userId, name, organizationId }: RevokeApiKeyVariables) =>\n      apiKeyApi.deleteApiKeyForUser(userId, name, organizationId),\n    onSuccess: async (_data, { organizationId }) => {\n      if (organizationId) {\n        await queryClient.invalidateQueries({ queryKey: queryKeys.apiKeys.list(organizationId) })\n      }\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useRevokeSshAccessMutation.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useMutation } from '@tanstack/react-query'\n\ninterface RevokeSshAccessVariables {\n  sandboxId: string\n  token: string\n}\n\nexport const useRevokeSshAccessMutation = () => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useMutation({\n    mutationFn: async ({ sandboxId, token }: RevokeSshAccessVariables) => {\n      await sandboxApi.revokeSshAccess(sandboxId, selectedOrganization?.id, token)\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useRotateWebhookSecretMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation } from '@tanstack/react-query'\nimport { useSvix } from 'svix-react'\n\ninterface RotateWebhookSecretVariables {\n  endpointId: string\n}\n\nexport const useRotateWebhookSecretMutation = () => {\n  const { svix, appId } = useSvix()\n\n  return useMutation({\n    mutationFn: async ({ endpointId }: RotateWebhookSecretVariables) => {\n      return svix.endpoint.rotateSecret(appId, endpointId, {})\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useSetAutomaticTopUpMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AutomaticTopUp } from '@/billing-api/types/OrganizationWallet'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface SetAutomaticTopUpVariables {\n  organizationId: string\n  automaticTopUp?: AutomaticTopUp\n}\n\nexport const useSetAutomaticTopUpMutation = () => {\n  const { billingApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: ({ organizationId, automaticTopUp }: SetAutomaticTopUpVariables) =>\n      billingApi.setAutomaticTopUp(organizationId, automaticTopUp),\n    onSuccess: (_data, { organizationId }) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.wallet(organizationId) })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useSetOrganizationDefaultRegionMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface SetOrganizationDefaultRegionVariables {\n  organizationId: string\n  defaultRegionId: string\n}\n\nexport const useSetOrganizationDefaultRegionMutation = () => {\n  const { organizationsApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: ({ organizationId, defaultRegionId }: SetOrganizationDefaultRegionVariables) =>\n      organizationsApi.setOrganizationDefaultRegion(organizationId, { defaultRegionId }),\n    onSuccess: (_data, { organizationId }) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.list() })\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.detail(organizationId) })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useStartSandboxMutation.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\ninterface StartSandboxVariables {\n  sandboxId: string\n}\n\nexport const useStartSandboxMutation = () => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: async ({ sandboxId }: StartSandboxVariables) => {\n      await sandboxApi.startSandbox(sandboxId, selectedOrganization?.id)\n    },\n    onSuccess: (_, { sandboxId }) => {\n      queryClient.invalidateQueries({\n        queryKey: queryKeys.sandboxes.detail(selectedOrganization?.id ?? '', sandboxId),\n      })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useStartVncMutation.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useMutation } from '@tanstack/react-query'\n\nexport const useStartVncMutation = (sandboxId: string) => {\n  const { toolboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useMutation({\n    mutationFn: async () => {\n      await toolboxApi.startComputerUseDeprecated(sandboxId, selectedOrganization?.id)\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useStopSandboxMutation.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\ninterface StopSandboxVariables {\n  sandboxId: string\n}\n\nexport const useStopSandboxMutation = () => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: async ({ sandboxId }: StopSandboxVariables) => {\n      await sandboxApi.stopSandbox(sandboxId, selectedOrganization?.id)\n    },\n    onSuccess: (_, { sandboxId }) => {\n      queryClient.invalidateQueries({\n        queryKey: queryKeys.sandboxes.detail(selectedOrganization?.id ?? '', sandboxId),\n      })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useTopUpWalletMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PaymentUrl } from '@/billing-api/types/Invoice'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface TopUpWalletVariables {\n  organizationId: string\n  amountCents: number\n}\n\nexport const useTopUpWalletMutation = () => {\n  const { billingApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation<PaymentUrl, unknown, TopUpWalletVariables>({\n    mutationFn: ({ organizationId, amountCents }) => billingApi.topUpWallet(organizationId, amountCents),\n    onSuccess: (_data, { organizationId }) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.wallet(organizationId) })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useUnlinkAccountMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface UnlinkAccountParams {\n  provider: string\n  userId: string\n}\n\nexport const useUnlinkAccountMutation = () => {\n  const { userApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: ({ provider, userId }: UnlinkAccountParams) => userApi.unlinkAccount(provider, userId),\n    onSuccess: () => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.user.accountProviders() })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useUpdateWebhookEndpointMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation } from '@tanstack/react-query'\nimport { EndpointPatch } from 'svix'\nimport { useSvix } from 'svix-react'\n\ninterface UpdateWebhookEndpointVariables {\n  endpointId: string\n  update: EndpointPatch\n}\n\nexport const useUpdateWebhookEndpointMutation = () => {\n  const { svix, appId } = useSvix()\n\n  return useMutation({\n    mutationFn: async ({ endpointId, update }: UpdateWebhookEndpointVariables) => {\n      return svix.endpoint.patch(appId, endpointId, update)\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useUpgradeTierMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface UpgradeTierParams {\n  organizationId: string\n  tier: number\n}\n\nexport const useUpgradeTierMutation = () => {\n  const { billingApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation({\n    mutationFn: ({ organizationId, tier }: UpgradeTierParams) => billingApi.upgradeTier(organizationId, tier),\n    onSuccess: async (_data, { organizationId }) => {\n      await Promise.all([\n        queryClient.invalidateQueries({ queryKey: queryKeys.organization.tier(organizationId) }),\n        queryClient.invalidateQueries({ queryKey: queryKeys.organization.usage.overview(organizationId) }),\n      ])\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/mutations/useVoidInvoiceMutation.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from '../queries/queryKeys'\nimport { useApi } from '../useApi'\n\ninterface VoidInvoiceVariables {\n  organizationId: string\n  invoiceId: string\n}\n\nexport const useVoidInvoiceMutation = () => {\n  const { billingApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return useMutation<void, unknown, VoidInvoiceVariables>({\n    mutationFn: ({ organizationId, invoiceId }) => billingApi.voidInvoice(organizationId, invoiceId),\n    onSuccess: (_data, { organizationId }) => {\n      queryClient.invalidateQueries({ queryKey: queryKeys.organization.wallet(organizationId) })\n      queryClient.invalidateQueries({ queryKey: queryKeys.billing.invoices(organizationId) })\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/billingQueries.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { OrganizationWallet } from '@/billing-api/types/OrganizationWallet'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport { UseQueryOptions } from '@tanstack/react-query'\nimport { useOrganizationBillingPortalUrlQuery } from './useOrganizationBillingPortalUrlQuery'\nimport {\n  useFetchOrganizationCheckoutUrlQuery,\n  useIsOrganizationCheckoutUrlFetching,\n} from './useOrganizationCheckoutUrlQuery'\nimport { useOrganizationInvoicesQuery } from './useOrganizationInvoicesQuery'\nimport { useOrganizationTierQuery } from './useOrganizationTierQuery'\nimport { useOrganizationWalletQuery } from './useOrganizationWalletQuery'\n\nfunction useSelectedOrgBillingScope() {\n  const { selectedOrganization, authenticatedUserOrganizationMember } = useSelectedOrganization()\n  const isOwner = authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER\n\n  return {\n    organizationId: selectedOrganization?.id ?? '',\n    enabled: Boolean(selectedOrganization && isOwner),\n  }\n}\n\nexport function useOwnerWalletQuery(\n  queryOptions?: Omit<UseQueryOptions<OrganizationWallet>, 'queryKey' | 'queryFn' | 'enabled'>,\n) {\n  const scope = useSelectedOrgBillingScope()\n  return useOrganizationWalletQuery({\n    ...scope,\n    ...queryOptions,\n  })\n}\n\nexport function useOwnerTierQuery() {\n  const scope = useSelectedOrgBillingScope()\n  return useOrganizationTierQuery(scope)\n}\n\nexport function useOwnerBillingPortalUrlQuery() {\n  const scope = useSelectedOrgBillingScope()\n  return useOrganizationBillingPortalUrlQuery(scope)\n}\n\nexport function useFetchOwnerCheckoutUrlQuery() {\n  const { organizationId } = useSelectedOrgBillingScope()\n  const fetchCheckoutUrl = useFetchOrganizationCheckoutUrlQuery()\n  return () => fetchCheckoutUrl(organizationId)\n}\n\nexport function useIsOwnerCheckoutUrlFetching() {\n  const { organizationId } = useSelectedOrgBillingScope()\n  return useIsOrganizationCheckoutUrlFetching(organizationId)\n}\n\nexport function useOwnerInvoicesQuery(page?: number, perPage?: number) {\n  const scope = useSelectedOrgBillingScope()\n  return useOrganizationInvoicesQuery({\n    ...scope,\n    page,\n    perPage,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/queryKeys.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { SnapshotQueryParams } from './useSnapshotsQuery'\n\nexport const queryKeys = {\n  config: {\n    all: ['config'] as const,\n  },\n  apiKeys: {\n    all: ['api-keys'] as const,\n    list: (organizationId: string) => [...queryKeys.apiKeys.all, organizationId, 'list'] as const,\n  },\n  webhooks: {\n    all: ['webhooks'] as const,\n    appPortalAccess: (organizationId: string) =>\n      [...queryKeys.webhooks.all, organizationId, 'app-portal-access'] as const,\n    initializationStatus: (organizationId: string) =>\n      [...queryKeys.webhooks.all, organizationId, 'initialization-status'] as const,\n  },\n  organization: {\n    all: ['organization'] as const,\n\n    list: () => [...queryKeys.organization.all, 'list'] as const,\n    detail: (organizationId: string) => [...queryKeys.organization.all, organizationId, 'detail'] as const,\n\n    usage: {\n      overview: (organizationId: string) =>\n        [...queryKeys.organization.all, organizationId, 'usage', 'overview'] as const,\n      current: (organizationId: string) => [...queryKeys.organization.all, organizationId, 'usage', 'current'] as const,\n      past: (organizationId: string) => [...queryKeys.organization.all, organizationId, 'usage', 'past'] as const,\n    },\n\n    tier: (organizationId: string) => [...queryKeys.organization.all, organizationId, 'tier'] as const,\n    wallet: (organizationId: string) => [...queryKeys.organization.all, organizationId, 'wallet'] as const,\n  },\n  user: {\n    all: ['users'] as const,\n    accountProviders: () => [...queryKeys.user.all, 'account-providers'] as const,\n  },\n  billing: {\n    all: ['billing'] as const,\n    tiers: () => [...queryKeys.billing.all, 'tiers'] as const,\n    emails: (organizationId: string) => [...queryKeys.billing.all, organizationId, 'emails'] as const,\n    portalUrl: (organizationId: string) => [...queryKeys.billing.all, organizationId, 'portal-url'] as const,\n    checkoutUrl: (organizationId: string) => [...queryKeys.billing.all, organizationId, 'checkout-url'] as const,\n    invoices: (organizationId: string, page?: number, perPage?: number) =>\n      [\n        ...queryKeys.billing.all,\n        organizationId,\n        'invoices',\n        ...(page !== undefined && perPage !== undefined ? [{ page, perPage }] : []),\n      ] as const,\n  },\n  snapshots: {\n    all: ['snapshots'] as const,\n    list: (organizationId: string, params?: SnapshotQueryParams) => {\n      const base = [...queryKeys.snapshots.all, organizationId, 'list'] as const\n      if (!params) return base\n      return [\n        ...base,\n        {\n          page: params.page,\n          pageSize: params.pageSize,\n          ...(params.filters && { filters: params.filters }),\n          ...(params.sorting && { sorting: params.sorting }),\n        },\n      ] as const\n    },\n  },\n  sandboxes: {\n    all: ['sandboxes'] as const,\n    detail: (organizationId: string, sandboxId: string) =>\n      [...queryKeys.sandboxes.all, organizationId, sandboxId, 'detail'] as const,\n    terminalSession: (sandboxId: string) => [...queryKeys.sandboxes.all, sandboxId, 'terminal-session'] as const,\n    vncInitialStatus: (sandboxId: string) => [...queryKeys.sandboxes.all, sandboxId, 'vnc-initial-status'] as const,\n    vncPollStatus: (sandboxId: string) => [...queryKeys.sandboxes.all, sandboxId, 'vnc-poll-status'] as const,\n    vncSession: (sandboxId: string) => [...queryKeys.sandboxes.all, sandboxId, 'vnc-session'] as const,\n  },\n  telemetry: {\n    all: ['telemetry'] as const,\n    logs: (sandboxId: string, params: object) => [...queryKeys.telemetry.all, sandboxId, 'logs', params] as const,\n    traces: (sandboxId: string, params: object) => [...queryKeys.telemetry.all, sandboxId, 'traces', params] as const,\n    metrics: (sandboxId: string, params: object) => [...queryKeys.telemetry.all, sandboxId, 'metrics', params] as const,\n    traceSpans: (sandboxId: string, traceId: string) =>\n      [...queryKeys.telemetry.all, sandboxId, 'traces', traceId] as const,\n  },\n  sandbox: {\n    all: ['sandbox'] as const,\n    session: (scope: string) => [...queryKeys.sandbox.all, scope] as const,\n    currentId: (scope: string) => [...queryKeys.sandbox.all, scope, 'current-id'] as const,\n    instance: (scope: string, id: string) => [...queryKeys.sandbox.all, scope, id] as const,\n    terminalUrl: (scope: string, id: string) => [...queryKeys.sandbox.all, scope, id, 'terminal-url'] as const,\n    vncStatus: (scope: string, id: string) => [...queryKeys.sandbox.all, scope, id, 'vnc-status'] as const,\n    vncUrl: (scope: string, id: string) => [...queryKeys.sandbox.all, scope, id, 'vnc-url'] as const,\n  },\n  analytics: {\n    all: ['analytics'] as const,\n    aggregatedUsage: (organizationId: string, params: object) =>\n      [...queryKeys.analytics.all, organizationId, 'aggregated-usage', params] as const,\n    usageChart: (organizationId: string, params: object) =>\n      [...queryKeys.analytics.all, organizationId, 'usage-chart', params] as const,\n    sandboxesUsage: (organizationId: string, params: object) =>\n      [...queryKeys.analytics.all, organizationId, 'sandboxes-usage', params] as const,\n    sandboxUsagePeriods: (organizationId: string, sandboxId: string, params: object) =>\n      [...queryKeys.analytics.all, organizationId, sandboxId, 'usage-periods', params] as const,\n  },\n} as const\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useAccountProvidersQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { AccountProvider } from '@daytonaio/api-client'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { queryKeys } from './queryKeys'\n\nexport const useAccountProvidersQuery = () => {\n  const { userApi } = useApi()\n\n  return useQuery<AccountProvider[]>({\n    queryKey: queryKeys.user.accountProviders(),\n    queryFn: async () => userApi.getAvailableAccountProviders().then((response) => response.data),\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useAnalyticsUsage.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport {\n  ModelsAggregatedUsage,\n  ModelsSandboxUsage,\n  ModelsUsageChartPoint,\n  ModelsUsagePeriod,\n} from '@daytonaio/analytics-api-client'\n\nexport interface AnalyticsUsageParams {\n  from: Date\n  to: Date\n  enabled?: boolean\n}\n\nexport function useAggregatedUsage(params: AnalyticsUsageParams) {\n  const api = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<ModelsAggregatedUsage>({\n    queryKey: queryKeys.analytics.aggregatedUsage(selectedOrganization?.id ?? '', params),\n    queryFn: async () => {\n      if (!selectedOrganization || !api.analyticsUsageApi) {\n        throw new Error('Missing required parameters')\n      }\n      const response = await api.analyticsUsageApi.organizationOrganizationIdUsageAggregatedGet(\n        selectedOrganization.id,\n        params.from.toISOString(),\n        params.to.toISOString(),\n      )\n      return response.data\n    },\n    enabled: !!selectedOrganization && !!api.analyticsUsageApi && params.enabled !== false,\n    staleTime: 10_000,\n  })\n}\n\nexport function useSandboxesUsage(params: AnalyticsUsageParams) {\n  const api = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<ModelsSandboxUsage[]>({\n    queryKey: queryKeys.analytics.sandboxesUsage(selectedOrganization?.id ?? '', params),\n    queryFn: async () => {\n      if (!selectedOrganization || !api.analyticsUsageApi) {\n        throw new Error('Missing required parameters')\n      }\n      const response = await api.analyticsUsageApi.organizationOrganizationIdUsageSandboxGet(\n        selectedOrganization.id,\n        params.from.toISOString(),\n        params.to.toISOString(),\n      )\n      return response.data\n    },\n    enabled: !!selectedOrganization && !!api.analyticsUsageApi && params.enabled !== false,\n    staleTime: 10_000,\n  })\n}\n\nexport interface UsageChartParams extends AnalyticsUsageParams {\n  region?: string\n}\n\nexport function useUsageChart(params: UsageChartParams) {\n  const api = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<ModelsUsageChartPoint[]>({\n    queryKey: queryKeys.analytics.usageChart(selectedOrganization?.id ?? '', params),\n    queryFn: async () => {\n      if (!selectedOrganization || !api.analyticsUsageApi) {\n        throw new Error('Missing required parameters')\n      }\n      const response = await api.analyticsUsageApi.organizationOrganizationIdUsageChartGet(\n        selectedOrganization.id,\n        params.from.toISOString(),\n        params.to.toISOString(),\n        params.region,\n      )\n      return response.data\n    },\n    enabled: !!selectedOrganization && !!api.analyticsUsageApi && params.enabled !== false,\n    staleTime: 10_000,\n  })\n}\n\nexport function useSandboxUsagePeriods(sandboxId: string | undefined, params: AnalyticsUsageParams) {\n  const api = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<ModelsUsagePeriod[]>({\n    queryKey: queryKeys.analytics.sandboxUsagePeriods(selectedOrganization?.id ?? '', sandboxId ?? '', params),\n    queryFn: async () => {\n      if (!selectedOrganization || !sandboxId || !api.analyticsUsageApi) {\n        throw new Error('Missing required parameters')\n      }\n      const response = await api.analyticsUsageApi.organizationOrganizationIdSandboxSandboxIdUsageGet(\n        selectedOrganization.id,\n        sandboxId,\n        params.from.toISOString(),\n        params.to.toISOString(),\n      )\n      return response.data\n    },\n    enabled: !!sandboxId && !!selectedOrganization && !!api.analyticsUsageApi && params.enabled !== false,\n    staleTime: 10_000,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useApiKeysQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiKeyList } from '@daytonaio/api-client'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { queryKeys } from './queryKeys'\n\nexport const useApiKeysQuery = (organizationId?: string) => {\n  const { apiKeyApi } = useApi()\n\n  return useQuery<ApiKeyList[]>({\n    queryKey: organizationId ? queryKeys.apiKeys.list(organizationId) : queryKeys.apiKeys.all,\n    enabled: Boolean(organizationId),\n    queryFn: async () => {\n      if (!organizationId) {\n        return []\n      }\n      const response = await apiKeyApi.listApiKeys(organizationId)\n      return response.data\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useOrganizationBillingPortalUrlQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { useConfig } from '../useConfig'\nimport { queryKeys } from './queryKeys'\n\nexport const useOrganizationBillingPortalUrlQuery = ({\n  organizationId,\n  enabled = true,\n}: {\n  organizationId: string\n  enabled?: boolean\n}) => {\n  const { billingApi } = useApi()\n  const config = useConfig()\n\n  return useQuery<string | null>({\n    queryKey: queryKeys.billing.portalUrl(organizationId),\n    queryFn: () => billingApi.getOrganizationBillingPortalUrl(organizationId),\n    enabled: Boolean(enabled && organizationId && config.billingApiUrl),\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useOrganizationCheckoutUrlQuery.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useIsFetching, useQueryClient } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { queryKeys } from './queryKeys'\n\nexport const useIsOrganizationCheckoutUrlFetching = (organizationId: string) =>\n  useIsFetching({ queryKey: queryKeys.billing.checkoutUrl(organizationId) }) > 0\n\nexport const useFetchOrganizationCheckoutUrlQuery = () => {\n  const { billingApi } = useApi()\n  const queryClient = useQueryClient()\n\n  return (organizationId: string) =>\n    queryClient.fetchQuery({\n      queryKey: queryKeys.billing.checkoutUrl(organizationId),\n      queryFn: () => billingApi.getOrganizationCheckoutUrl(organizationId),\n    })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useOrganizationInvoicesQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { PaginatedInvoices } from '@/billing-api/types/Invoice'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { useConfig } from '../useConfig'\nimport { queryKeys } from './queryKeys'\n\nexport const useOrganizationInvoicesQuery = ({\n  organizationId,\n  page,\n  perPage,\n  enabled = true,\n}: {\n  organizationId: string\n  page?: number\n  perPage?: number\n  enabled?: boolean\n}) => {\n  const { billingApi } = useApi()\n  const config = useConfig()\n\n  return useQuery<PaginatedInvoices>({\n    queryKey: queryKeys.billing.invoices(organizationId, page, perPage),\n    queryFn: () => billingApi.listInvoices(organizationId, page, perPage),\n    enabled: Boolean(enabled && config.billingApiUrl && organizationId),\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useOrganizationTierQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { OrganizationTier } from '@/billing-api'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { useConfig } from '../useConfig'\nimport { queryKeys } from './queryKeys'\n\nexport const useOrganizationTierQuery = ({\n  organizationId,\n  enabled = true,\n}: {\n  organizationId: string\n  enabled?: boolean\n}) => {\n  const { billingApi } = useApi()\n  const config = useConfig()\n\n  return useQuery<OrganizationTier | null>({\n    queryKey: queryKeys.organization.tier(organizationId),\n    queryFn: () => billingApi.getOrganizationTier(organizationId),\n    enabled: Boolean(enabled && organizationId && config.billingApiUrl),\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useOrganizationUsageOverviewQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { OrganizationUsageOverview } from '@daytonaio/api-client'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { queryKeys } from './queryKeys'\n\nexport const useOrganizationUsageOverviewQuery = (\n  { organizationId }: { organizationId: string },\n  options?: Omit<Parameters<typeof useQuery<OrganizationUsageOverview>>[0], 'queryKey' | 'queryFn'>,\n) => {\n  const { organizationsApi } = useApi()\n\n  return useQuery<OrganizationUsageOverview>({\n    queryKey: queryKeys.organization.usage.overview(organizationId),\n    queryFn: async () => (await organizationsApi.getOrganizationUsageOverview(organizationId)).data,\n    enabled: !!organizationId,\n    ...options,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useOrganizationUsageQuery.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { OrganizationUsage } from '@/billing-api'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { useConfig } from '../useConfig'\nimport { queryKeys } from './queryKeys'\n\nexport const useOrganizationUsageQuery = ({\n  organizationId,\n  enabled = true,\n}: {\n  organizationId: string\n  enabled?: boolean\n}) => {\n  const { billingApi } = useApi()\n  const config = useConfig()\n\n  return useQuery<OrganizationUsage>({\n    queryKey: queryKeys.organization.usage.current(organizationId),\n    queryFn: () => billingApi.getOrganizationUsage(organizationId),\n    enabled: Boolean(enabled && config.billingApiUrl && organizationId),\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useOrganizationWalletQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { OrganizationWallet } from '@/billing-api/types/OrganizationWallet'\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { useConfig } from '../useConfig'\nimport { queryKeys } from './queryKeys'\n\nexport const useOrganizationWalletQuery = ({\n  organizationId,\n  enabled = true,\n  ...queryOptions\n}: {\n  organizationId: string\n  enabled?: boolean\n} & Omit<UseQueryOptions<OrganizationWallet>, 'queryKey' | 'queryFn'>) => {\n  const { billingApi } = useApi()\n  const config = useConfig()\n\n  return useQuery<OrganizationWallet>({\n    queryKey: queryKeys.organization.wallet(organizationId),\n    queryFn: () => billingApi.getOrganizationWallet(organizationId),\n    enabled: Boolean(enabled && config.billingApiUrl && organizationId),\n    refetchOnWindowFocus: true,\n    ...queryOptions,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/usePastOrganizationUsageQuery.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { OrganizationUsage } from '@/billing-api'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { useConfig } from '../useConfig'\nimport { queryKeys } from './queryKeys'\n\nexport const usePastOrganizationUsageQuery = ({\n  organizationId,\n  enabled = true,\n}: {\n  organizationId: string\n  enabled?: boolean\n}) => {\n  const { billingApi } = useApi()\n  const config = useConfig()\n\n  return useQuery<OrganizationUsage[]>({\n    queryKey: queryKeys.organization.usage.past(organizationId),\n    queryFn: () => billingApi.getPastOrganizationUsage(organizationId),\n    enabled: Boolean(enabled && config.billingApiUrl && organizationId),\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useSandboxQuery.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useQuery } from '@tanstack/react-query'\nimport { isAxiosError } from 'axios'\nimport { queryKeys } from './queryKeys'\n\nexport const useSandboxQuery = (sandboxId: string) => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery({\n    queryKey: queryKeys.sandboxes.detail(selectedOrganization?.id ?? '', sandboxId),\n    queryFn: async () => {\n      const response = await sandboxApi.getSandbox(sandboxId, selectedOrganization?.id)\n      return response.data\n    },\n    enabled: !!sandboxId && !!selectedOrganization?.id,\n    staleTime: 1000 * 10,\n    retry: (failureCount, error) => {\n      if (isAxiosError(error.cause) && error.cause?.status === 404) return false\n      return failureCount < 3\n    },\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useSnapshotsQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { GetAllSnapshotsOrderEnum, GetAllSnapshotsSortEnum, PaginatedSnapshots } from '@daytonaio/api-client'\nimport { keepPreviousData, useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { useSelectedOrganization } from '../useSelectedOrganization'\nimport { queryKeys } from './queryKeys'\n\nexport interface SnapshotFilters {\n  name?: string\n}\n\nexport interface SnapshotSorting {\n  field: GetAllSnapshotsSortEnum\n  direction: GetAllSnapshotsOrderEnum\n}\n\nexport const DEFAULT_SNAPSHOT_SORTING: SnapshotSorting = {\n  field: GetAllSnapshotsSortEnum.LAST_USED_AT,\n  direction: GetAllSnapshotsOrderEnum.DESC,\n}\n\nexport interface SnapshotQueryParams {\n  page: number\n  pageSize: number\n  filters?: SnapshotFilters\n  sorting?: SnapshotSorting\n}\n\nexport function useSnapshotsQuery(params: SnapshotQueryParams) {\n  const { snapshotApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<PaginatedSnapshots>({\n    queryKey: queryKeys.snapshots.list(selectedOrganization?.id ?? '', params),\n    queryFn: async () => {\n      if (!selectedOrganization) {\n        throw new Error('No organization selected')\n      }\n\n      const { page, pageSize, filters = {}, sorting = DEFAULT_SNAPSHOT_SORTING } = params\n\n      const response = await snapshotApi.getAllSnapshots(\n        selectedOrganization.id,\n        page,\n        pageSize,\n        filters.name,\n        sorting.field,\n        sorting.direction,\n      )\n\n      return response.data\n    },\n    enabled: !!selectedOrganization,\n    placeholderData: keepPreviousData,\n    staleTime: 1000 * 10,\n    gcTime: 1000 * 60 * 5,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useTerminalSessionQuery.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from './queryKeys'\n\nconst TERMINAL_PORT = 22222\nconst SESSION_DURATION_SECONDS = 300\n\nexport type TerminalSession = {\n  url: string\n  expiresAt: number\n}\n\nexport const useTerminalSessionQuery = (sandboxId: string, enabled: boolean) => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n  const queryKey = queryKeys.sandboxes.terminalSession(sandboxId)\n\n  const query = useQuery({\n    queryKey,\n    queryFn: async (): Promise<TerminalSession> => {\n      const url = (\n        await sandboxApi.getSignedPortPreviewUrl(\n          sandboxId,\n          TERMINAL_PORT,\n          selectedOrganization?.id,\n          SESSION_DURATION_SECONDS,\n        )\n      ).data.url\n      return { url, expiresAt: Date.now() + SESSION_DURATION_SECONDS * 1000 }\n    },\n    enabled: enabled && !!sandboxId && !!selectedOrganization?.id,\n    staleTime: Infinity,\n  })\n\n  const existingSession = queryClient.getQueryData<TerminalSession>(queryKey)\n\n  const reset = () => {\n    queryClient.removeQueries({ queryKey })\n  }\n\n  return { ...query, existingSession, reset }\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useTiersQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport type { Tier } from '@/billing-api'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { useConfig } from '../useConfig'\nimport { queryKeys } from './queryKeys'\n\nexport const useTiersQuery = ({ enabled = true }: { enabled?: boolean } = {}) => {\n  const { billingApi } = useApi()\n  const config = useConfig()\n\n  return useQuery<Tier[]>({\n    queryKey: queryKeys.billing.tiers(),\n    queryFn: () => billingApi.listTiers(),\n    enabled: Boolean(enabled && config.billingApiUrl),\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useVncSessionQuery.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { queryKeys } from './queryKeys'\n\nconst VNC_PORT = 6080\nconst SESSION_DURATION_SECONDS = 300\n\nexport type VncSession = {\n  url: string\n  expiresAt: number\n}\n\nexport const useVncSessionQuery = (sandboxId: string, enabled: boolean) => {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n  const queryKey = queryKeys.sandboxes.vncSession(sandboxId)\n\n  const query = useQuery({\n    queryKey,\n    queryFn: async (): Promise<VncSession> => {\n      const url = (\n        await sandboxApi.getSignedPortPreviewUrl(\n          sandboxId,\n          VNC_PORT,\n          selectedOrganization?.id,\n          SESSION_DURATION_SECONDS,\n        )\n      ).data.url\n      return { url, expiresAt: Date.now() + SESSION_DURATION_SECONDS * 1000 }\n    },\n    enabled: enabled && !!sandboxId && !!selectedOrganization?.id,\n    staleTime: Infinity,\n  })\n\n  const existingSession = queryClient.getQueryData<VncSession>(queryKey)\n\n  const reset = () => {\n    queryClient.removeQueries({ queryKey })\n  }\n\n  return { ...query, existingSession, reset }\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useVncStatusQuery.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useQuery } from '@tanstack/react-query'\nimport { queryKeys } from './queryKeys'\n\nexport const useVncInitialStatusQuery = (sandboxId: string, enabled: boolean) => {\n  const { toolboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery({\n    queryKey: queryKeys.sandboxes.vncInitialStatus(sandboxId),\n    queryFn: async () => {\n      const { data } = await toolboxApi.getComputerUseStatusDeprecated(sandboxId, selectedOrganization?.id)\n      return data.status as string\n    },\n    enabled: enabled && !!sandboxId && !!selectedOrganization?.id,\n    retry: false,\n    staleTime: 0,\n  })\n}\n\nexport const useVncPollStatusQuery = (sandboxId: string, enabled: boolean) => {\n  const { toolboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery({\n    queryKey: queryKeys.sandboxes.vncPollStatus(sandboxId),\n    queryFn: async () => {\n      const { data } = await toolboxApi.getComputerUseStatusDeprecated(sandboxId, selectedOrganization?.id)\n      if (data.status !== 'active') throw new Error(`VNC not ready: ${data.status}`)\n      return data.status as string\n    },\n    enabled: enabled && !!sandboxId && !!selectedOrganization?.id,\n    retry: 10,\n    retryDelay: 2000,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useWebhookAppPortalAccessQuery.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { queryKeys } from './queryKeys'\n\ninterface WebhookAppPortalAccess {\n  token: string\n  url: string\n}\n\nexport const useWebhookAppPortalAccessQuery = (organizationId?: string) => {\n  const { axiosInstance } = useApi()\n\n  return useQuery<WebhookAppPortalAccess>({\n    queryKey: organizationId ? queryKeys.webhooks.appPortalAccess(organizationId) : queryKeys.webhooks.all,\n    enabled: Boolean(organizationId),\n    queryFn: async () => {\n      if (!organizationId) {\n        throw new Error('Organization ID is required')\n      }\n      const response = await axiosInstance.post<WebhookAppPortalAccess>(\n        `/webhooks/organizations/${organizationId}/app-portal-access`,\n      )\n      return response.data\n    },\n    staleTime: 1000 * 60 * 5, // Token is valid for some time, cache for 5 minutes\n    retry: 1,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/queries/useWebhookInitializationStatusQuery.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { WebhookInitializationStatus } from '@daytonaio/api-client'\nimport { useQuery } from '@tanstack/react-query'\nimport { useApi } from '../useApi'\nimport { queryKeys } from './queryKeys'\n\nexport const useWebhookInitializationStatusQuery = (organizationId?: string) => {\n  const { webhooksApi } = useApi()\n\n  return useQuery<WebhookInitializationStatus | null>({\n    queryKey: organizationId ? queryKeys.webhooks.initializationStatus(organizationId) : queryKeys.webhooks.all,\n    enabled: Boolean(organizationId),\n    queryFn: async () => {\n      if (!organizationId) {\n        return null\n      }\n      try {\n        const response = await webhooksApi.webhookControllerGetInitializationStatus(organizationId)\n        return response.data\n      } catch {\n        // If the endpoint returns 404, webhooks are not initialized\n        return null\n      }\n    },\n    staleTime: 1000 * 60 * 5, // Cache for 5 minutes\n    retry: false, // Don't retry on 404\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/use-mobile.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useMatchMedia } from './useMatchMedia'\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n  return useMatchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useApi.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useContext } from 'react'\nimport { ApiContext } from '@/contexts/ApiContext'\n\nexport function useApi() {\n  const context = useContext(ApiContext)\n  if (!context) {\n    throw new Error('useApi must be used within an ApiProvider')\n  }\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useConfig.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useContext } from 'react'\nimport { ConfigContext } from '@/contexts/ConfigContext'\n\nexport function useConfig() {\n  const context = useContext(ConfigContext)\n  if (!context) {\n    throw new Error('useConfig must be used within a ConfigProvider')\n  }\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useCopyToClipboard.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n'use client'\n\nimport { useCallback, useState } from 'react'\nimport { toast } from 'sonner'\n\ntype CopyFn = (text: string) => Promise<boolean>\n\nexport function useCopyToClipboard({ timeout = 2000 }: { timeout?: number } = {}): [string | null, CopyFn] {\n  const [copiedText, setCopiedText] = useState<string | null>(null)\n\n  const copy: CopyFn = useCallback(\n    async (text) => {\n      if (!navigator?.clipboard) {\n        toast.error('Clipboard not supported')\n        return false\n      }\n\n      try {\n        await navigator.clipboard.writeText(text)\n\n        setCopiedText(text)\n\n        if (timeout !== 0) {\n          setTimeout(() => {\n            setCopiedText(null)\n          }, timeout)\n        }\n\n        return true\n      } catch (error) {\n        console.error('Failed to copy to clipboard', error)\n        setCopiedText(null)\n\n        toast.error('Failed to copy to clipboard')\n\n        return false\n      }\n    },\n    [timeout],\n  )\n\n  return [copiedText, copy]\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useDeepCompareMemo.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport isEqual from 'fast-deep-equal'\nimport { useRef } from 'react'\n\nexport function useDeepCompareMemo<T>(value: T) {\n  const ref = useRef<T>(value)\n\n  if (!isEqual(value, ref.current)) {\n    ref.current = value\n  }\n\n  return ref.current\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useDocsSearchCommands.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  CommandHighlight,\n  useCommandPalette,\n  useCommandPaletteActions,\n  useRegisterCommands,\n  useRegisterPage,\n  type CommandConfig,\n} from '@/components/CommandPalette'\nimport { cn } from '@/lib/utils'\nimport { keepPreviousData, useQuery } from '@tanstack/react-query'\nimport { liteClient as algoliasearch } from 'algoliasearch/lite'\nimport { BookOpen, Code2, Container, Layers, Terminal } from 'lucide-react'\nimport { ReactNode, useEffect, useMemo, useState } from 'react'\n\nconst ALGOLIA_APP_ID = import.meta.env.VITE_ALGOLIA_APP_ID\nconst ALGOLIA_API_KEY = import.meta.env.VITE_ALGOLIA_API_KEY\nconst DOCS_INDEX = import.meta.env.VITE_ALGOLIA_DOCS_INDEX_NAME || 'docs_test'\nconst CLI_INDEX = import.meta.env.VITE_ALGOLIA_CLI_INDEX_NAME || 'cli_test'\nconst SDK_INDEX = import.meta.env.VITE_ALGOLIA_SDK_INDEX_NAME || 'sdk_test'\n\nconst docSearchEnabled = Boolean(ALGOLIA_APP_ID && ALGOLIA_API_KEY)\nconst client = docSearchEnabled ? algoliasearch(ALGOLIA_APP_ID, ALGOLIA_API_KEY) : null\n\nexport type AlgoliaHit = {\n  objectID: string\n  url: string\n  slug: string\n  title: string\n  description?: string\n  content?: string\n  _highlightResult?: {\n    title?: { value: string; matchLevel: string }\n    description?: { value: string; matchLevel: string }\n  }\n}\n\nexport type SearchResults = {\n  docs: AlgoliaHit[]\n  cli: AlgoliaHit[]\n  sdk: AlgoliaHit[]\n}\n\nexport const searchDocumentation = async (query: string): Promise<SearchResults> => {\n  if (!client || !query.trim()) {\n    return { docs: [], cli: [], sdk: [] }\n  }\n\n  const commonParams = {\n    hitsPerPage: 3,\n    attributesToHighlight: ['title', 'description'],\n    highlightPreTag: '<em>',\n    highlightPostTag: '</em>',\n  }\n\n  const { results } = await client.search({\n    requests: [\n      { indexName: DOCS_INDEX, query, ...commonParams },\n      { indexName: CLI_INDEX, query, ...commonParams },\n      { indexName: SDK_INDEX, query, ...commonParams },\n    ],\n  })\n\n  const getHits = (index: number) =>\n    results[index] && 'hits' in results[index] ? (results[index].hits as AlgoliaHit[]) : []\n\n  return {\n    docs: getHits(0),\n    cli: getHits(1),\n    sdk: getHits(2),\n  }\n}\n\nfunction useDebounce<T>(value: T, delay: number): T {\n  const [debouncedValue, setDebouncedValue] = useState(value)\n  useEffect(() => {\n    const handler = setTimeout(() => setDebouncedValue(value), delay)\n    return () => clearTimeout(handler)\n  }, [value, delay])\n  return debouncedValue\n}\n\nexport const useDocsSearchQuery = ({ search, enabled }: { search: string; enabled: boolean }) => {\n  return useQuery({\n    queryKey: ['algolia-search', search],\n    queryFn: () => searchDocumentation(search),\n    enabled: enabled && search.length > 1,\n    staleTime: 1000 * 60 * 5,\n    placeholderData: keepPreviousData,\n  })\n}\n\nconst openDocs = (path = '') => {\n  window.open(`https://www.daytona.io/docs${path}`, '_blank')\n}\n\nconst SearchSnippet = ({\n  hit,\n  attribute,\n  className,\n}: {\n  hit: AlgoliaHit\n  attribute: 'title' | 'description'\n  className?: string\n}) => {\n  const content = hit._highlightResult?.[attribute]?.value || hit[attribute] || ''\n\n  return (\n    <span\n      className={cn(\n        '[&_em]:not-italic [&_em]:rounded [&_em]:bg-[#2fcc712b] [&_em]:text-[#058157] dark:[&_em]:text-[#2fcc71] [&_em]:px-[2px]',\n        className,\n      )}\n      dangerouslySetInnerHTML={{ __html: content }}\n    />\n  )\n}\n\nconst ResultRow = ({ hit, tag }: { hit: AlgoliaHit; tag?: ReactNode }) => (\n  <div className=\"flex flex-col overflow-hidden\">\n    <div className=\"flex items-center gap-2\">\n      <SearchSnippet hit={hit} attribute=\"title\" className=\"font-mediumline-clamp-1\" />\n      {tag}\n    </div>\n    {hit.description && (\n      <SearchSnippet hit={hit} attribute=\"description\" className=\"text-xs text-muted-foreground line-clamp-1\" />\n    )}\n  </div>\n)\n\n// todo: something more robust here\nconst parseSDKLanguage = (hit: AlgoliaHit) => {\n  const [, lang] = hit.slug.split('/')\n  if (lang.includes('python')) {\n    return 'Python'\n  }\n  if (lang.includes('typescript')) {\n    return 'TypeScript'\n  }\n\n  return lang\n}\n\nconst handleSelect = (hit: AlgoliaHit) => {\n  const url = `https://www.daytona.io${hit.url}`\n  window.open(url, '_blank')\n}\n\nexport function useDocsSearchCommands() {\n  const activePageId = useCommandPalette((state) => state.activePageId)\n  const search = useCommandPalette((state) => state.searchByPage.get('search-docs') ?? '')\n\n  const { setShouldFilter, setIsLoading } = useCommandPaletteActions()\n  const enabled = activePageId === 'search-docs' && docSearchEnabled\n  const debouncedQuery = useDebounce(search, 300)\n\n  const { data, isError, isFetching } = useDocsSearchQuery({\n    search: debouncedQuery,\n    enabled,\n  })\n\n  useRegisterPage({ id: 'search-docs', label: 'Search Docs', placeholder: 'Search documentation...' })\n\n  useEffect(() => {\n    if (!enabled) {\n      return\n    }\n    setShouldFilter(false)\n    return () => setShouldFilter(true)\n  }, [enabled, setShouldFilter])\n\n  useEffect(() => {\n    if (!enabled) {\n      return\n    }\n    setIsLoading(isFetching)\n  }, [enabled, isFetching, setIsLoading])\n\n  const docsCommands: CommandConfig[] = useMemo(() => {\n    if (!search || !data) {\n      return [\n        {\n          id: 'suggestion-quickstart',\n          label: 'Quick Start',\n          icon: <BookOpen className=\"w-4 h-4\" />,\n          onSelect: () => openDocs(),\n          chainable: true,\n        },\n        {\n          id: 'suggestion-sandboxes',\n          label: 'Sandboxes',\n          icon: <Container className=\"w-4 h-4\" />,\n          onSelect: () => openDocs('/en/sandboxes'),\n        },\n        {\n          id: 'suggestion-snapshots',\n          label: 'Snapshots',\n          icon: <Layers className=\"w-4 h-4\" />,\n          onSelect: () => openDocs('/en/snapshots'),\n          chainable: true,\n        },\n        {\n          id: 'suggestion-limits',\n          label: 'Limits',\n          icon: <Terminal className=\"w-4 h-4\" />,\n          onSelect: () => openDocs('/en/limits'),\n          chainable: true,\n        },\n      ]\n    }\n\n    if (isError) {\n      return [\n        {\n          id: 'error',\n          label: 'Failed to load documentation. Try again.',\n          disabled: true,\n        },\n      ]\n    }\n\n    return data.docs.map((hit) => ({\n      id: `docs-${hit.objectID}`,\n      label: <ResultRow hit={hit} />,\n      value: `docs ${hit.title} ${hit.description || ''}`,\n      icon: <BookOpen className=\"w-4 h-4\" />,\n      onSelect: () => handleSelect(hit),\n      chainable: true,\n      className: 'py-2',\n    }))\n  }, [search, data, isError])\n\n  const cliCommands: CommandConfig[] = useMemo(() => {\n    if (!search || !data) {\n      return []\n    }\n\n    return data.cli.map((hit) => ({\n      id: `cli-${hit.objectID}`,\n      label: <ResultRow hit={hit} />,\n      value: `cli ${hit.title} ${hit.description || ''}`,\n      icon: <Terminal className=\"w-4 h-4\" />,\n      onSelect: () => handleSelect(hit),\n      chainable: true,\n      className: 'py-2',\n    }))\n  }, [search, data])\n\n  const sdkCommands: CommandConfig[] = useMemo(() => {\n    if (!search || !data) {\n      return []\n    }\n\n    return data.sdk.map((hit) => {\n      const sdkLanguage = parseSDKLanguage(hit)\n      return {\n        id: `sdk-${hit.objectID}`,\n        label: (\n          <ResultRow hit={hit} tag={<CommandHighlight className=\"text-xs h-auto\">{sdkLanguage}</CommandHighlight>} />\n        ),\n        value: `sdk ${hit.title} ${hit.description || ''} ${sdkLanguage}`,\n        icon: <Code2 className=\"w-4 h-4\" />,\n        onSelect: () => handleSelect(hit),\n        chainable: true,\n        className: 'py-2',\n      }\n    })\n  }, [search, data])\n\n  useRegisterCommands(docsCommands, {\n    pageId: 'search-docs',\n    groupId: 'docs-results',\n    groupLabel: !search ? 'Suggestions' : data?.docs.length ? 'Results' : undefined,\n    groupOrder: 0,\n  })\n\n  useRegisterCommands(cliCommands, {\n    pageId: 'search-docs',\n    groupId: 'cli-results',\n    groupLabel: data?.cli.length ? 'CLI' : undefined,\n    groupOrder: 1,\n  })\n\n  useRegisterCommands(sdkCommands, {\n    pageId: 'search-docs',\n    groupId: 'sdk-results',\n    groupLabel: data?.sdk.length ? 'SDK' : undefined,\n    groupOrder: 2,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useMatchMedia.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useSyncExternalStore, useMemo, useCallback } from 'react'\n\nfunction getServerSnapshot(): boolean {\n  return false\n}\n\nexport function useMatchMedia(query: string): boolean {\n  const mql = useMemo(() => {\n    if (typeof window === 'undefined') return null\n    return window.matchMedia(query)\n  }, [query])\n\n  const subscribe = useCallback(\n    (callback: () => void) => {\n      if (!mql) return () => undefined\n\n      mql.addEventListener('change', callback)\n      return () => mql.removeEventListener('change', callback)\n    },\n    [mql],\n  )\n\n  const getSnapshot = useCallback(() => {\n    return mql ? mql.matches : false\n  }, [mql])\n\n  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useNotificationSocket.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { NotificationSocketContext } from '@/contexts/NotificationSocketContext'\nimport { useContext } from 'react'\n\nexport function useNotificationSocket() {\n  const context = useContext(NotificationSocketContext)\n\n  if (!context) {\n    throw new Error('useNotificationSocket must be used within a NotificationSocketProvider')\n  }\n\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useOrganizationRoles.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useState, useEffect, useCallback } from 'react'\nimport { OrganizationRole } from '@daytonaio/api-client'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\n\nexport const useOrganizationRoles = () => {\n  const { organizationsApi } = useApi()\n\n  const { selectedOrganization } = useSelectedOrganization()\n\n  const [roles, setRoles] = useState<OrganizationRole[]>([])\n  const [loadingRoles, setLoadingRoles] = useState(true)\n\n  const fetchRoles = useCallback(\n    async (showTableLoadingState = true) => {\n      if (!selectedOrganization) {\n        return\n      }\n      if (showTableLoadingState) {\n        setLoadingRoles(true)\n      }\n      try {\n        const response = await organizationsApi.listOrganizationRoles(selectedOrganization.id)\n        setRoles(response.data)\n      } catch (error) {\n        handleApiError(error, 'Failed to fetch organization roles')\n      } finally {\n        setLoadingRoles(false)\n      }\n    },\n    [organizationsApi, selectedOrganization],\n  )\n\n  useEffect(() => {\n    fetchRoles()\n  }, [fetchRoles])\n\n  return {\n    roles,\n    loadingRoles,\n    refreshRoles: fetchRoles,\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useOrganizations.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OrganizationsContext } from '@/contexts/OrganizationsContext'\nimport { useContext } from 'react'\n\nexport function useOrganizations() {\n  const context = useContext(OrganizationsContext)\n\n  if (!context) {\n    throw new Error('useOrganizations must be used within a OrganizationsProvider')\n  }\n\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/usePlayground.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useContext } from 'react'\nimport { PlaygroundContext } from '@/contexts/PlaygroundContext'\n\nexport function usePlayground() {\n  const context = useContext(PlaygroundContext)\n\n  if (!context) {\n    throw new Error('usePlayground must be used within a <PlaygroundProvider />')\n  }\n\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/usePlaygroundSandbox.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PlaygroundSandboxContext } from '@/providers/PlaygroundSandboxProvider'\nimport { UseSandboxSessionResult } from '@/hooks/useSandboxSession'\nimport { useContext } from 'react'\n\nexport type UsePlaygroundSandboxResult = UseSandboxSessionResult\n\nexport function usePlaygroundSandbox(): UsePlaygroundSandboxResult {\n  const context = useContext(PlaygroundSandboxContext)\n\n  if (!context) {\n    throw new Error('usePlaygroundSandbox must be used within a <PlaygroundSandboxProvider />')\n  }\n\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useQueryCountdown.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useEffect, useState } from 'react'\n\nexport function useQueryCountdown(\n  dataUpdatedAt: number,\n  intervalMs: number,\n  {\n    updateInterval,\n  }: {\n    updateInterval?: number\n  } = {},\n) {\n  const [seconds, setSeconds] = useState(intervalMs / 1000)\n\n  useEffect(() => {\n    if (!dataUpdatedAt) return\n\n    const timer = setInterval(() => {\n      const timePassed = Date.now() - dataUpdatedAt\n      const remaining = Math.max(0, intervalMs - timePassed)\n      setSeconds(Math.ceil(remaining / 1000))\n    }, updateInterval || 1000)\n\n    return () => clearInterval(timer)\n  }, [dataUpdatedAt, intervalMs, updateInterval])\n\n  return seconds\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useRegions.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { RegionsContext } from '@/contexts/RegionsContext'\nimport { useContext } from 'react'\n\nexport function useRegions() {\n  const context = useContext(RegionsContext)\n\n  if (!context) {\n    throw new Error('useRegions must be used within a RegionsProvider')\n  }\n\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSandboxLogs.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { PaginatedLogs } from '@daytonaio/api-client'\n\nexport interface LogsQueryParams {\n  from: Date\n  to: Date\n  page?: number\n  limit?: number\n  severities?: string[]\n  search?: string\n}\n\nexport function useSandboxLogs(\n  sandboxId: string | undefined,\n  params: LogsQueryParams,\n  options?: Omit<UseQueryOptions<PaginatedLogs>, 'queryKey' | 'queryFn'>,\n) {\n  const api = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<PaginatedLogs>({\n    queryKey: queryKeys.telemetry.logs(sandboxId ?? '', params),\n    queryFn: async () => {\n      if (!selectedOrganization || !sandboxId || !api.analyticsTelemetryApi) {\n        throw new Error('Missing required parameters')\n      }\n      const limit = params.limit ?? 50\n      const page = params.page ?? 1\n      const offset = (page - 1) * limit\n      const severity = params.severities?.length ? params.severities.join(',') : undefined\n\n      const response = await api.analyticsTelemetryApi.organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet(\n        selectedOrganization.id,\n        sandboxId,\n        params.from.toISOString(),\n        params.to.toISOString(),\n        severity,\n        params.search,\n        limit,\n        offset,\n      )\n\n      const items = (response.data ?? []).map((entry) => ({\n        timestamp: entry.timestamp ?? '',\n        body: entry.body ?? '',\n        severityText: entry.severityText ?? '',\n        severityNumber: entry.severityNumber,\n        serviceName: entry.serviceName ?? '',\n        resourceAttributes: entry.resourceAttributes ?? {},\n        logAttributes: entry.logAttributes ?? {},\n        traceId: entry.traceId,\n        spanId: entry.spanId,\n      }))\n\n      return {\n        items,\n        total: items.length < limit ? offset + items.length : offset + items.length + 1,\n        page,\n        totalPages: items.length < limit ? page : page + 1,\n      }\n    },\n    enabled: !!sandboxId && !!selectedOrganization && !!api.analyticsTelemetryApi && !!params.from && !!params.to,\n    staleTime: 10_000,\n    ...options,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSandboxMetrics.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { MetricsResponse } from '@daytonaio/api-client'\n\nexport interface MetricsQueryParams {\n  from: Date\n  to: Date\n  metricNames?: string[]\n}\n\nexport function useSandboxMetrics(\n  sandboxId: string | undefined,\n  params: MetricsQueryParams,\n  options?: Omit<UseQueryOptions<MetricsResponse>, 'queryKey' | 'queryFn'>,\n) {\n  const api = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<MetricsResponse>({\n    queryKey: queryKeys.telemetry.metrics(sandboxId ?? '', params),\n    queryFn: async () => {\n      if (!selectedOrganization || !sandboxId || !api.analyticsTelemetryApi) {\n        throw new Error('Missing required parameters')\n      }\n      const metricNames = params.metricNames?.length ? params.metricNames.join(',') : undefined\n\n      const response = await api.analyticsTelemetryApi.organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet(\n        selectedOrganization.id,\n        sandboxId,\n        params.from.toISOString(),\n        params.to.toISOString(),\n        metricNames,\n      )\n\n      // Group flat ModelsMetricPoint[] into MetricSeries[]\n      const seriesMap = new Map<string, { timestamp: string; value: number }[]>()\n      for (const point of response.data ?? []) {\n        const name = point.metricName ?? ''\n        if (!seriesMap.has(name)) {\n          seriesMap.set(name, [])\n        }\n        seriesMap.get(name)!.push({\n          timestamp: point.timestamp ?? '',\n          value: point.value ?? 0,\n        })\n      }\n\n      const series = Array.from(seriesMap.entries()).map(([metricName, dataPoints]) => ({\n        metricName,\n        dataPoints,\n      }))\n\n      return { series }\n    },\n    enabled: !!sandboxId && !!selectedOrganization && !!api.analyticsTelemetryApi && !!params.from && !!params.to,\n    staleTime: 10_000,\n    ...options,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSandboxSession.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport {\n  CreateSandboxBaseParams,\n  CreateSandboxFromImageParams,\n  CreateSandboxFromSnapshotParams,\n  Daytona,\n  Sandbox,\n} from '@daytonaio/sdk'\nimport { QueryClient, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useCallback, useEffect, useMemo, useRef } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { toast } from 'sonner'\n\ntype CreateSandboxParams = CreateSandboxBaseParams | CreateSandboxFromImageParams | CreateSandboxFromSnapshotParams\n\nconst TERMINAL_PORT = 22222\nconst VNC_PORT = 6080\nconst DEFAULT_URL_EXPIRY_SECONDS = 600\n\nexport type UseSandboxSessionOptions = {\n  scope?: string\n  createParams?: CreateSandboxParams\n  terminal?: boolean\n  vnc?: boolean\n  notify?: { sandbox?: boolean; terminal?: boolean; vnc?: boolean }\n  urlExpirySeconds?: number\n}\n\nexport type SandboxState = {\n  instance: Sandbox | null\n  loading: boolean\n  error: string | null\n  create: (params?: CreateSandboxParams) => Promise<Sandbox>\n}\n\nexport type PortQueryState = {\n  url: string | null\n  loading: boolean\n  error: string | null\n  refetch: () => void\n}\n\nexport type VncState = PortQueryState & {\n  start: () => void\n}\n\nexport type UseSandboxSessionResult = {\n  sandbox: SandboxState\n  terminal: PortQueryState\n  vnc: VncState\n}\n\nexport function removeSandboxSessionQueries(queryClient: QueryClient, scope: string): void {\n  queryClient\n    .getMutationCache()\n    .findAll({ mutationKey: ['create-sandbox', scope] })\n    .forEach((m) => queryClient.getMutationCache().remove(m))\n  queryClient.removeQueries({ queryKey: queryKeys.sandbox.session(scope) })\n}\n\nexport function removeSandboxSessionQueriesByInstanceId(queryClient: QueryClient, sandboxId: string): void {\n  const scopes = new Set<string>()\n  for (const query of queryClient.getQueryCache().findAll({ queryKey: queryKeys.sandbox.all })) {\n    if (query.queryKey.includes(sandboxId)) {\n      scopes.add(query.queryKey[1] as string)\n    }\n  }\n  scopes.forEach((s) => removeSandboxSessionQueries(queryClient, s))\n}\n\nexport function useSandboxSession(options?: UseSandboxSessionOptions): UseSandboxSessionResult {\n  const {\n    scope,\n    createParams,\n    terminal = false,\n    vnc = false,\n    notify,\n    urlExpirySeconds = DEFAULT_URL_EXPIRY_SECONDS,\n  } = options ?? {}\n  const notifyRef = useRef({ sandbox: true, terminal: true, vnc: true, ...notify })\n  notifyRef.current = { sandbox: true, terminal: true, vnc: true, ...notify }\n  const { user } = useAuth()\n  const { selectedOrganization } = useSelectedOrganization()\n  const { sandboxApi, toolboxApi } = useApi()\n  const queryClient = useQueryClient()\n\n  const client = useMemo(() => {\n    if (!user?.access_token || !selectedOrganization?.id) return null\n    return new Daytona({\n      jwtToken: user.access_token,\n      apiUrl: import.meta.env.VITE_API_URL,\n      organizationId: selectedOrganization.id,\n    })\n  }, [user?.access_token, selectedOrganization?.id])\n\n  const createMutation = useMutation<Sandbox, Error, CreateSandboxParams | undefined>({\n    mutationKey: ['create-sandbox', scope ?? 'default'],\n    mutationFn: async (params) => {\n      if (!client) throw new Error('Unable to create Daytona client: missing access token or organization ID.')\n      return await client.create(params ?? createParams)\n    },\n    onSuccess: (newSandbox) => {\n      if (scope) queryClient.setQueryData(queryKeys.sandbox.currentId(scope), newSandbox.id)\n    },\n    onError: (error) => {\n      if (notifyRef.current.sandbox) {\n        toast.error('Failed to create sandbox', {\n          description: error.message,\n          action: { label: 'Try again', onClick: () => createMutation.mutate(createParams) },\n        })\n      }\n    },\n  })\n\n  const persistedSandboxId = scope ? queryClient.getQueryData<string>(queryKeys.sandbox.currentId(scope)) : undefined\n  const sandboxId = createMutation.data?.id ?? persistedSandboxId ?? ''\n  const resolvedScope = scope ?? sandboxId\n\n  const sandboxQuery = useQuery<Sandbox>({\n    queryKey: queryKeys.sandbox.instance(resolvedScope, sandboxId),\n    queryFn: () => client?.get(sandboxId) ?? Promise.reject(new Error('Client not initialized')),\n    enabled: !!resolvedScope && !!sandboxId && !!client,\n  })\n\n  const sandbox = sandboxQuery.data ?? createMutation.data ?? null\n\n  const getPortPreviewUrl = useCallback(\n    async (id: string, port: number) =>\n      (await sandboxApi.getSignedPortPreviewUrl(id, port, selectedOrganization?.id, urlExpirySeconds)).data.url,\n    [sandboxApi, selectedOrganization?.id, urlExpirySeconds],\n  )\n\n  const terminalQuery = useQuery<string, Error>({\n    queryKey: queryKeys.sandbox.terminalUrl(resolvedScope, sandboxId),\n    queryFn: () => getPortPreviewUrl(sandboxId, TERMINAL_PORT),\n    enabled: terminal && !!sandboxId,\n    staleTime: Infinity,\n  })\n\n  const vncToastId = `vnc-${resolvedScope}-${sandboxId}`\n  const vncToastShownRef = useRef(false)\n\n  const startVncMutation = useMutation<void, Error>({\n    mutationFn: async () => {\n      await toolboxApi.startComputerUseDeprecated(sandboxId, selectedOrganization?.id)\n    },\n    onMutate: () => {\n      if (notifyRef.current.vnc) {\n        vncToastShownRef.current = true\n        toast.loading('Starting VNC desktop...', { id: vncToastId })\n      }\n    },\n    onSuccess: () => {\n      if (vncToastShownRef.current) {\n        toast.loading('VNC desktop started, checking status...', { id: vncToastId })\n      }\n    },\n  })\n\n  const prevSandboxIdRef = useRef<string>('')\n  useEffect(() => {\n    if (prevSandboxIdRef.current && !sandboxQuery.data && !sandboxQuery.isFetching) {\n      createMutation.reset()\n      startVncMutation.reset()\n      vncToastShownRef.current = false\n      if (scope) removeSandboxSessionQueries(queryClient, scope)\n    }\n    prevSandboxIdRef.current = sandboxId\n  }, [sandboxId, sandboxQuery.data, sandboxQuery.isFetching, createMutation, startVncMutation, queryClient, scope])\n\n  const vncStatusQuery = useQuery<string, Error>({\n    queryKey: queryKeys.sandbox.vncStatus(resolvedScope, sandboxId),\n    queryFn: async () => {\n      const {\n        data: { status },\n      } = await toolboxApi.getComputerUseStatusDeprecated(sandboxId, selectedOrganization?.id)\n      if (status !== 'active') throw new Error(`VNC desktop not ready: ${status}`)\n      return status\n    },\n    enabled: vnc && !!sandboxId && startVncMutation.isSuccess,\n  })\n\n  const vncReady = vncStatusQuery.data === 'active'\n\n  const vncUrlQuery = useQuery<string, Error>({\n    queryKey: queryKeys.sandbox.vncUrl(resolvedScope, sandboxId),\n    queryFn: async () => await getPortPreviewUrl(sandboxId, VNC_PORT),\n    enabled: vnc && !!sandboxId && vncReady,\n    staleTime: Infinity,\n  })\n\n  useEffect(() => {\n    if (!vncToastShownRef.current) return\n\n    if (vncUrlQuery.data) {\n      toast.success('VNC desktop is ready', { id: vncToastId })\n      vncToastShownRef.current = false\n    } else if (startVncMutation.error) {\n      toast.error('Failed to start VNC desktop', { id: vncToastId, description: startVncMutation.error.message })\n      vncToastShownRef.current = false\n    } else if (vncStatusQuery.error) {\n      toast.error('VNC desktop failed to become ready', { id: vncToastId, description: vncStatusQuery.error.message })\n      vncToastShownRef.current = false\n    }\n  }, [vncToastId, vncUrlQuery.data, startVncMutation.error, vncStatusQuery.error])\n\n  const createSandbox = useCallback(\n    (params?: CreateSandboxParams) => createMutation.mutateAsync(params ?? createParams),\n    [createMutation, createParams],\n  )\n\n  return {\n    sandbox: {\n      instance: sandbox,\n      loading: createMutation.isPending || (!!sandboxId && sandboxQuery.isLoading),\n      error: createMutation.error?.message ?? sandboxQuery.error?.message ?? null,\n      create: createSandbox,\n    },\n    terminal: {\n      url: terminalQuery.data ?? null,\n      loading: terminalQuery.isLoading,\n      error: terminalQuery.error?.message ?? null,\n      refetch: terminalQuery.refetch,\n    },\n    vnc: {\n      url: vncUrlQuery.data ?? null,\n      loading: startVncMutation.isPending || vncStatusQuery.isLoading || (vncReady && vncUrlQuery.isLoading),\n      error: startVncMutation.error?.message ?? vncStatusQuery.error?.message ?? vncUrlQuery.error?.message ?? null,\n      start: () => startVncMutation.mutate(),\n      refetch: () => {\n        startVncMutation.reset()\n        queryClient.removeQueries({ queryKey: queryKeys.sandbox.vncStatus(resolvedScope, sandboxId) })\n        queryClient.removeQueries({ queryKey: queryKeys.sandbox.vncUrl(resolvedScope, sandboxId) })\n        if (notifyRef.current.vnc) {\n          vncToastShownRef.current = true\n          toast.loading('Retrying VNC desktop...', { id: vncToastId })\n        }\n        startVncMutation.mutate()\n      },\n    },\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSandboxSessionContext.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ISandboxSessionContext, SandboxSessionContext } from '@/contexts/SandboxSessionContext'\nimport { useContext } from 'react'\n\nexport function useSandboxSessionContext(): ISandboxSessionContext {\n  const context = useContext(SandboxSessionContext)\n  if (!context) {\n    throw new Error('useSandboxSessionContext must be used within a SandboxSessionProvider')\n  }\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSandboxTraceSpans.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { TraceSpan } from '@daytonaio/api-client'\n\nexport function useSandboxTraceSpans(\n  sandboxId: string | undefined,\n  traceId: string | undefined,\n  options?: Omit<UseQueryOptions<TraceSpan[]>, 'queryKey' | 'queryFn'>,\n) {\n  const api = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<TraceSpan[]>({\n    queryKey: queryKeys.telemetry.traceSpans(sandboxId ?? '', traceId ?? ''),\n    queryFn: async () => {\n      if (!selectedOrganization || !sandboxId || !traceId || !api.analyticsTelemetryApi) {\n        throw new Error('Missing required parameters')\n      }\n      const response =\n        await api.analyticsTelemetryApi.organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet(\n          selectedOrganization.id,\n          sandboxId,\n          traceId,\n        )\n\n      return (response.data ?? []).map((span) => ({\n        traceId: span.traceId ?? '',\n        spanId: span.spanId ?? '',\n        parentSpanId: span.parentSpanId,\n        spanName: span.spanName ?? '',\n        timestamp: span.timestamp ?? '',\n        durationNs: (span.durationMs ?? 0) * 1_000_000,\n        spanAttributes: span.spanAttributes ?? {},\n        statusCode: span.statusCode,\n        statusMessage: span.statusMessage,\n      }))\n    },\n    enabled: !!sandboxId && !!traceId && !!selectedOrganization && !!api.analyticsTelemetryApi,\n    staleTime: 30_000,\n    ...options,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSandboxTraces.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useQuery, UseQueryOptions } from '@tanstack/react-query'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { PaginatedTraces } from '@daytonaio/api-client'\n\nexport interface TracesQueryParams {\n  from: Date\n  to: Date\n  page?: number\n  limit?: number\n}\n\nexport function useSandboxTraces(\n  sandboxId: string | undefined,\n  params: TracesQueryParams,\n  options?: Omit<UseQueryOptions<PaginatedTraces>, 'queryKey' | 'queryFn'>,\n) {\n  const api = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<PaginatedTraces>({\n    queryKey: queryKeys.telemetry.traces(sandboxId ?? '', params),\n    queryFn: async () => {\n      if (!selectedOrganization || !sandboxId || !api.analyticsTelemetryApi) {\n        throw new Error('Missing required parameters')\n      }\n      const limit = params.limit ?? 50\n      const page = params.page ?? 1\n      const offset = (page - 1) * limit\n\n      const response = await api.analyticsTelemetryApi.organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet(\n        selectedOrganization.id,\n        sandboxId,\n        params.from.toISOString(),\n        params.to.toISOString(),\n        limit,\n        offset,\n      )\n\n      const items = (response.data ?? []).map((trace) => ({\n        traceId: trace.traceId ?? '',\n        rootSpanName: trace.rootSpanName ?? '',\n        startTime: trace.startTime ?? '',\n        endTime: trace.endTime ?? '',\n        durationMs: trace.totalDurationMs ?? 0,\n        spanCount: trace.spanCount ?? 0,\n        statusCode: trace.statusCode,\n      }))\n\n      return {\n        items,\n        total: items.length < limit ? offset + items.length : offset + items.length + 1,\n        page,\n        totalPages: items.length < limit ? page : page + 1,\n      }\n    },\n    enabled: !!sandboxId && !!selectedOrganization && !!api.analyticsTelemetryApi && !!params.from && !!params.to,\n    staleTime: 10_000,\n    ...options,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSandboxWsSync.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useNotificationSocket } from '@/hooks/useNotificationSocket'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { getSandboxesQueryKey } from '@/hooks/useSandboxes'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { PaginatedSandboxes, Sandbox, SandboxDesiredState, SandboxState } from '@daytonaio/api-client'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { useEffect } from 'react'\n\ninterface UseSandboxWsSyncOptions {\n  sandboxId?: string\n  refetchOnCreate?: boolean\n}\n\nexport function useSandboxWsSync({ sandboxId, refetchOnCreate = false }: UseSandboxWsSyncOptions = {}) {\n  const { notificationSocket } = useNotificationSocket()\n  const { selectedOrganization } = useSelectedOrganization()\n  const queryClient = useQueryClient()\n\n  useEffect(() => {\n    if (!notificationSocket || !selectedOrganization?.id) return\n\n    const orgId = selectedOrganization.id\n\n    const updateStateInListCache = (targetId: string, state: SandboxState) => {\n      queryClient.setQueriesData<PaginatedSandboxes>({ queryKey: getSandboxesQueryKey(orgId) }, (oldData) => {\n        if (!oldData) return oldData\n        return {\n          ...oldData,\n          items: oldData.items.map((s) => (s.id === targetId ? { ...s, state } : s)),\n        }\n      })\n    }\n\n    const updateStateInDetailCache = (targetId: string, state: SandboxState) => {\n      queryClient.setQueryData<Sandbox>(queryKeys.sandboxes.detail(orgId, targetId), (oldData) => {\n        if (!oldData) return oldData\n        return { ...oldData, state }\n      })\n    }\n\n    const optimisticUpdate = (targetId: string, state: SandboxState) => {\n      updateStateInListCache(targetId, state)\n      if (sandboxId) {\n        updateStateInDetailCache(targetId, state)\n      }\n    }\n\n    const invalidate = () => {\n      queryClient.invalidateQueries({\n        queryKey: getSandboxesQueryKey(orgId),\n        refetchType: 'none',\n      })\n\n      if (sandboxId) {\n        queryClient.invalidateQueries({\n          queryKey: queryKeys.sandboxes.detail(orgId, sandboxId),\n        })\n      }\n    }\n\n    const handleCreated = (_sandbox: Sandbox) => {\n      if (sandboxId) return\n\n      queryClient.invalidateQueries({\n        queryKey: getSandboxesQueryKey(orgId),\n        refetchType: refetchOnCreate ? 'active' : 'none',\n      })\n    }\n\n    const handleStateUpdated = (data: { sandbox: Sandbox; oldState: SandboxState; newState: SandboxState }) => {\n      if (sandboxId && data.sandbox.id !== sandboxId) return\n\n      // warm pool sandboxes — treat as created\n      if (data.oldState === data.newState && data.newState === SandboxState.STARTED) {\n        handleCreated(data.sandbox)\n        return\n      }\n\n      let updatedState = data.newState\n\n      // error/build_failed with desiredState=DESTROYED should display as destroyed\n      if (\n        data.sandbox.desiredState === SandboxDesiredState.DESTROYED &&\n        (data.newState === SandboxState.ERROR || data.newState === SandboxState.BUILD_FAILED)\n      ) {\n        updatedState = SandboxState.DESTROYED\n      }\n\n      optimisticUpdate(data.sandbox.id, updatedState)\n      invalidate()\n    }\n\n    const handleDesiredStateUpdated = (data: {\n      sandbox: Sandbox\n      oldDesiredState: SandboxDesiredState\n      newDesiredState: SandboxDesiredState\n    }) => {\n      if (sandboxId && data.sandbox.id !== sandboxId) return\n\n      if (data.newDesiredState !== SandboxDesiredState.DESTROYED) return\n      if (data.sandbox.state !== SandboxState.ERROR && data.sandbox.state !== SandboxState.BUILD_FAILED) return\n\n      optimisticUpdate(data.sandbox.id, SandboxState.DESTROYED)\n      invalidate()\n    }\n\n    notificationSocket.on('sandbox.created', handleCreated)\n    notificationSocket.on('sandbox.state.updated', handleStateUpdated)\n    notificationSocket.on('sandbox.desired-state.updated', handleDesiredStateUpdated)\n\n    return () => {\n      notificationSocket.off('sandbox.created', handleCreated)\n      notificationSocket.off('sandbox.state.updated', handleStateUpdated)\n      notificationSocket.off('sandbox.desired-state.updated', handleDesiredStateUpdated)\n    }\n  }, [notificationSocket, selectedOrganization?.id, sandboxId, refetchOnCreate, queryClient])\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSandboxes.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { QueryKey, useQuery } from '@tanstack/react-query'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport {\n  ListSandboxesPaginatedOrderEnum,\n  ListSandboxesPaginatedSortEnum,\n  ListSandboxesPaginatedStatesEnum,\n  PaginatedSandboxes,\n} from '@daytonaio/api-client'\nimport { isValidUUID } from '@/lib/utils'\n\nexport interface SandboxFilters {\n  idOrName?: string\n  labels?: Record<string, string>\n  includeErroredDeleted?: boolean\n  states?: ListSandboxesPaginatedStatesEnum[]\n  snapshots?: string[]\n  regions?: string[]\n  minCpu?: number\n  maxCpu?: number\n  minMemoryGiB?: number\n  maxMemoryGiB?: number\n  minDiskGiB?: number\n  maxDiskGiB?: number\n  lastEventAfter?: Date\n  lastEventBefore?: Date\n}\n\nexport interface SandboxSorting {\n  field?: ListSandboxesPaginatedSortEnum\n  direction?: ListSandboxesPaginatedOrderEnum\n}\n\nexport const DEFAULT_SANDBOX_SORTING: SandboxSorting = {\n  field: ListSandboxesPaginatedSortEnum.UPDATED_AT,\n  direction: ListSandboxesPaginatedOrderEnum.DESC,\n}\n\nexport interface SandboxQueryParams {\n  page: number\n  pageSize: number\n  filters?: SandboxFilters\n  sorting?: SandboxSorting\n}\n\nexport const getSandboxesQueryKey = (organizationId: string | undefined, params?: SandboxQueryParams): QueryKey => {\n  const baseKey = ['sandboxes' as const, organizationId]\n\n  if (!params) {\n    return baseKey\n  }\n\n  const normalizedParams = {\n    page: params.page,\n    pageSize: params.pageSize,\n    ...(params.filters && { filters: params.filters }),\n    ...(params.sorting && { sorting: params.sorting }),\n  }\n\n  return [...baseKey, normalizedParams]\n}\n\nexport function useSandboxes(queryKey: QueryKey, params: SandboxQueryParams) {\n  const { sandboxApi } = useApi()\n  const { selectedOrganization } = useSelectedOrganization()\n\n  return useQuery<PaginatedSandboxes>({\n    queryKey,\n    queryFn: async () => {\n      if (!selectedOrganization) {\n        throw new Error('No organization selected')\n      }\n\n      const { page, pageSize, filters = {}, sorting = {} } = params\n\n      const listResponse = await sandboxApi.listSandboxesPaginated(\n        selectedOrganization.id,\n        page,\n        pageSize,\n        undefined,\n        filters.idOrName,\n        filters.labels ? JSON.stringify(filters.labels) : undefined,\n        filters.includeErroredDeleted,\n        filters.states,\n        filters.snapshots,\n        filters.regions,\n        filters.minCpu,\n        filters.maxCpu,\n        filters.minMemoryGiB,\n        filters.maxMemoryGiB,\n        filters.minDiskGiB,\n        filters.maxDiskGiB,\n        filters.lastEventAfter,\n        filters.lastEventBefore,\n        sorting.field,\n        sorting.direction,\n      )\n\n      let paginatedData = listResponse.data\n\n      // TODO: this will be obsolete once we introduce the search API\n      if (filters.idOrName && isValidUUID(filters.idOrName) && page === 1) {\n        // Attempt to fetch sandbox by ID if the search value is a valid UUID\n        try {\n          const sandbox = (await sandboxApi.getSandbox(filters.idOrName, selectedOrganization.id)).data\n          const existsInPaginatedData = paginatedData.items.some((item) => item.id === sandbox.id)\n\n          if (!existsInPaginatedData) {\n            paginatedData = {\n              ...paginatedData,\n              // This is an exact UUID match, ignore sorting\n              items: [sandbox, ...paginatedData.items],\n              total: paginatedData.total + 1,\n            }\n          }\n        } catch (error) {\n          // TODO: rethrow if not 4xx\n        }\n      }\n\n      return paginatedData\n    },\n    enabled: !!selectedOrganization,\n    staleTime: 1000 * 10, // 10 seconds\n    gcTime: 1000 * 60 * 5, // 5 minutes,\n  })\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSelectedOrganization.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useContext } from 'react'\nimport { SelectedOrganizationContext } from '@/contexts/SelectedOrganizationContext'\n\nexport function useSelectedOrganization() {\n  const context = useContext(SelectedOrganizationContext)\n\n  if (!context) {\n    throw new Error('useSelectedOrganization must be used within a SelectedOrganizationProvider')\n  }\n\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useSuspensionBanner.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useBanner } from '@/components/Banner'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { Organization } from '@daytonaio/api-client'\nimport { addHours, formatDistanceToNow } from 'date-fns'\nimport { CreditCardIcon, MailIcon } from 'lucide-react'\nimport { useEffect, useRef } from 'react'\nimport { useLocation, useNavigate } from 'react-router-dom'\n\nconst SUSPENSION_BANNER_ID = 'suspension-banner'\n\n// todo: enumerate reasons\nconst PAYMENT_METHOD_REQUIRED_REASON = 'Payment method required'\nconst VERIFY_EMAIL_REASON = 'Please verify your email address'\nconst CREDITS_DEPLETED_REASON = 'Credits depleted'\n\nfunction isSetupRequiredSuspension(reason: string) {\n  return reason === PAYMENT_METHOD_REQUIRED_REASON || reason === VERIFY_EMAIL_REASON\n}\n\nfunction isCreditsDepletionSuspension(reason: string) {\n  return reason === CREDITS_DEPLETED_REASON\n}\n\ntype Suspension = Pick<\n  Organization,\n  'suspended' | 'suspensionReason' | 'suspendedAt' | 'suspensionCleanupGracePeriodHours'\n>\n\nexport function useSuspensionBanner(suspension?: Suspension | null) {\n  const { addBanner, removeBanner } = useBanner()\n  const navigate = useNavigate()\n  const location = useLocation()\n  const path = location?.pathname\n  const previousSuspendedRef = useRef<boolean | undefined>(undefined)\n\n  useEffect(() => {\n    const wasSuspended = previousSuspendedRef.current\n    const isSuspended = suspension?.suspended ?? false\n\n    if (wasSuspended && !isSuspended) {\n      removeBanner(SUSPENSION_BANNER_ID)\n      previousSuspendedRef.current = isSuspended\n      return\n    }\n\n    previousSuspendedRef.current = isSuspended\n\n    if (!isSuspended || !suspension?.suspensionReason) {\n      return\n    }\n\n    const reason = suspension.suspensionReason\n\n    if (isSetupRequiredSuspension(reason)) {\n      if (reason === PAYMENT_METHOD_REQUIRED_REASON) {\n        addBanner({\n          id: SUSPENSION_BANNER_ID,\n          variant: 'info',\n          title: 'Setup Required',\n          description: 'Add a payment method to start creating sandboxes.',\n          icon: <CreditCardIcon className=\"h-4 w-4 flex-shrink-0 text-current\" />,\n          action:\n            path !== RoutePath.BILLING_WALLET\n              ? {\n                  label: 'Go to Billing',\n                  onClick: () => navigate(RoutePath.BILLING_WALLET),\n                }\n              : undefined,\n          isDismissible: false,\n        })\n      } else if (reason === VERIFY_EMAIL_REASON) {\n        addBanner({\n          id: SUSPENSION_BANNER_ID,\n          variant: 'info',\n          title: 'Verification Required',\n          description: 'Please verify your email address to access all features.',\n          icon: <MailIcon className=\"h-4 w-4 flex-shrink-0 text-current\" />,\n          isDismissible: false,\n        })\n      }\n      return\n    }\n\n    if (isCreditsDepletionSuspension(reason)) {\n      const suspendedAtDate = suspension.suspendedAt ? new Date(suspension.suspendedAt) : null\n      const cleanupDate = suspendedAtDate\n        ? addHours(suspendedAtDate, suspension.suspensionCleanupGracePeriodHours ?? 0)\n        : null\n\n      const cleanupDatePassed = cleanupDate !== null && cleanupDate <= new Date()\n\n      const cleanupText = cleanupDate\n        ? cleanupDatePassed\n          ? 'Sandboxes will be stopped'\n          : `Sandboxes will be stopped ${formatDistanceToNow(cleanupDate, { addSuffix: true })}`\n        : 'Sandboxes will be stopped soon'\n\n      addBanner({\n        id: SUSPENSION_BANNER_ID,\n        variant: 'error',\n        title: 'Credits depleted',\n        description: cleanupText,\n        action:\n          path !== RoutePath.BILLING_WALLET\n            ? {\n                label: 'Go to Billing',\n                onClick: () => navigate(RoutePath.BILLING_WALLET),\n              }\n            : undefined,\n        isDismissible: false,\n      })\n      return\n    }\n\n    const suspendedAtDate = suspension.suspendedAt ? new Date(suspension.suspendedAt) : null\n    const cleanupDate = suspendedAtDate\n      ? addHours(suspendedAtDate, suspension.suspensionCleanupGracePeriodHours ?? 0)\n      : null\n\n    const cleanupDatePassed = cleanupDate !== null && cleanupDate <= new Date()\n    const cleanupText = cleanupDate\n      ? cleanupDatePassed\n        ? 'Sandboxes will be stopped'\n        : `Sandboxes will be stopped ${formatDistanceToNow(cleanupDate, { addSuffix: true })}`\n      : 'Sandboxes will be stopped soon'\n\n    addBanner({\n      id: SUSPENSION_BANNER_ID,\n      variant: 'error',\n      title: 'Organization suspended',\n      description: reason ? `${reason}. ${cleanupText}` : cleanupText,\n      isDismissible: false,\n    })\n  }, [suspension, addBanner, removeBanner, navigate, path])\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useUserOrganizationInvitations.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { UserOrganizationInvitationsContext } from '@/contexts/UserOrganizationInvitationsContext'\nimport { useContext } from 'react'\n\nexport function useUserOrganizationInvitations() {\n  const context = useContext(UserOrganizationInvitationsContext)\n\n  if (!context) {\n    throw new Error('useUserOrganizationInvitations must be used within a UserOrganizationInvitationsProvider')\n  }\n\n  return context\n}\n"
  },
  {
    "path": "apps/dashboard/src/hooks/useWebhooks.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useWebhookInitializationStatusQuery } from './queries/useWebhookInitializationStatusQuery'\nimport { useSelectedOrganization } from './useSelectedOrganization'\n\nexport function useWebhooks() {\n  const { selectedOrganization } = useSelectedOrganization()\n  const { data, isLoading, refetch } = useWebhookInitializationStatusQuery(selectedOrganization?.id)\n\n  const isInitialized = data?.svixApplicationId != null\n\n  return {\n    isInitialized,\n    isLoading,\n    refresh: refetch,\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/index.css",
    "content": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\nbody {\n  margin: 0;\n  min-height: 100vh;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n@layer base {\n  :root {\n    --background: 0 0% 100%;\n    --foreground: 0 0% 3.9%;\n    --card: 0 0% 100%;\n    --card-foreground: 0 0% 3.9%;\n    --popover: 0 0% 100%;\n    --popover-foreground: 0 0% 3.9%;\n    --primary: 0 0% 9%;\n    --primary-foreground: 0 0% 98%;\n    --secondary: 0 0% 96.1%;\n    --secondary-foreground: 0 0% 9%;\n    --muted: 0 0% 96.1%;\n    --muted-foreground: 0 0% 45.1%;\n    --accent: 0 0% 94%;\n    --accent-foreground: 0 0% 9%;\n\n    --border: 0 0% 89.8%;\n    --input: 0 0% 89.8%;\n    --ring: 0 0% 3.9%;\n\n    --chart-1: 217.22deg 91.22% 59.8%;\n    --chart-2: 158.11deg 64.37% 51.57%;\n    --chart-3: 258.31deg 89.53% 66.27%;\n    --chart-4: 37.69deg 92.13% 50.2%;\n    --chart-5: 220deg 8.94% 46.08%;\n    --chart-6: 188.74deg 94.5% 42.75%;\n    --chart-7: 330.37deg 81.19% 60.39%;\n\n    --radius: 0.5rem;\n    --spacing: 0.25rem;\n\n    --info-background: 217 90% 97%;\n    --info-foreground: 221 83% 53%;\n    --info-separator: 217 90% 92%;\n\n    --success: 141 60% 30%;\n    --success-background: 160 43% 96%;\n    --success-foreground: 161 95% 24%;\n    --success-separator: 151 47% 85%;\n\n    --warning: 32 100% 35%;\n    --warning-background: 43 75% 96%;\n    --warning-foreground: 32 98% 34%;\n    --warning-separator: 43 79% 85%;\n\n    --destructive: 0 84.2% 60.2%;\n    --destructive-background: 3 90% 97%;\n    --destructive-foreground: 0 71% 49%;\n    --destructive-separator: 2 95% 90%;\n\n    --sidebar-background: 0 0% 99.5%;\n    --sidebar-foreground: 0 0% 26.1%;\n    --sidebar-primary: 0 0% 10%;\n    --sidebar-primary-foreground: 0 0% 98%;\n    --sidebar-accent: 0 0% 95.9%;\n    --sidebar-accent-foreground: 0 0% 10%;\n    --sidebar-border: 0 0% 91%;\n    --sidebar-ring: 0 0% 59.8%;\n\n    --code-background: 0 0% 97%;\n  }\n\n  .dark {\n    --background: 0 0% 3.9%;\n    --foreground: 0 0% 98%;\n    --card: 0 0% 3.9%;\n    --card-foreground: 0 0% 98%;\n    --popover: 0 0% 3.9%;\n    --popover-foreground: 0 0% 98%;\n    --primary: 0 0% 98%;\n    --primary-foreground: 0 0% 9%;\n    --secondary: 0 0% 14.9%;\n    --secondary-foreground: 0 0% 98%;\n    --muted: 0 0% 14.9%;\n    --muted-foreground: 0 0% 63.9%;\n    --accent: 0 0% 16%;\n    --accent-foreground: 0 0% 98%;\n\n    --border: 0 0% 14.9%;\n    --input: 0 0% 14.9%;\n    --ring: 0 0% 83.1%;\n\n    --info-background: 218 39% 10%;\n    --info-foreground: 220 96% 70%;\n    --info-separator: 217 46% 15%;\n\n    --success: 141 71% 48%;\n    --success-background: 152 30% 8%;\n    --success-foreground: 158 63% 52%;\n    --success-separator: 153 43% 12%;\n\n    --warning: 45 100% 50%;\n    --warning-background: 44 42% 9%;\n    --warning-foreground: 43 96% 56%;\n    --warning-separator: 43 57% 14%;\n\n    --destructive: 0 62.8% 50.6%;\n    --destructive-background: 4 35% 10%;\n    --destructive-foreground: 0 92% 71%;\n    --destructive-separator: 2 44% 15%;\n\n    --sidebar-background: 0 0% 10%;\n    --sidebar-foreground: 0 0% 95.9%;\n    --sidebar-primary: 0 0% 48%;\n    --sidebar-primary-foreground: 0 0% 100%;\n    --sidebar-accent: 0 0% 15.9%;\n    --sidebar-accent-foreground: 0 0% 95.9%;\n    --sidebar-border: 0 0% 15.9%;\n    --sidebar-ring: 0 0% 59.8%;\n\n    --code-background: 0 0% 6%;\n  }\n\n  .slide-in-from-right {\n    animation: slide-in-from-right 0.2s ease-out;\n  }\n\n  .slide-out-to-right {\n    animation: slide-out-to-right 0.2s ease-out;\n  }\n\n  @keyframes slide-in-from-right {\n    from {\n      transform: translateX(100%);\n    }\n    to {\n      transform: translateX(0);\n    }\n  }\n\n  @keyframes slide-out-to-right {\n    from {\n      transform: translateX(0);\n    }\n    to {\n      transform: translateX(100%);\n    }\n  }\n}\n\n@layer base {\n  * {\n    @apply border-border;\n  }\n  body {\n    @apply bg-background text-foreground;\n  }\n}\n\n@layer base {\n  * {\n    @apply border-border outline-ring/50;\n  }\n  body {\n    @apply bg-background text-foreground;\n  }\n}\n\n@layer base {\n  /* Hide native time dropdown UI */\n  input[type='time']::-webkit-calendar-picker-indicator {\n    display: none;\n    -webkit-appearance: none;\n  }\n\n  input[type='time']::-webkit-clear-button,\n  input[type='time']::-webkit-inner-spin-button {\n    display: none;\n    -webkit-appearance: none;\n  }\n\n  /* Firefox support */\n  input[type='time'] {\n    -moz-appearance: textfield;\n  }\n}\n\n.scrollbar-sm {\n  @apply scrollbar-thin scrollbar-thumb-neutral-300 dark:scrollbar-thumb-neutral-700 scrollbar-track-background;\n}\n\n@keyframes skeleton-shimmer {\n  100% {\n    transform: translateX(100%);\n  }\n}\n\n::selection {\n  @apply bg-primary text-primary-foreground;\n}\n"
  },
  {
    "path": "apps/dashboard/src/lib/bulk-action-toast.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ExternalToast, toast } from 'sonner'\n\ntype ToastId = string | number\n\ntype BulkActionToastOptions = Omit<ExternalToast, 'id'>\n\ninterface BulkActionResultOptions {\n  successTitle: string\n  errorTitle: string\n  warningTitle: string\n  canceledTitle: string\n}\n\ninterface BulkActionToast {\n  id: ToastId\n  loading: (message: string, options?: BulkActionToastOptions) => void\n  success: (message: string, options?: BulkActionToastOptions) => void\n  error: (message: string, options?: BulkActionToastOptions) => void\n  warning: (message: string, options?: BulkActionToastOptions) => void\n  info: (message: string, options?: BulkActionToastOptions) => void\n  result: (result: { successCount: number; failureCount: number }, options: BulkActionResultOptions) => void\n  dismiss: () => void\n}\n\nexport function createBulkActionToast(initialMessage: string, options?: BulkActionToastOptions): BulkActionToast {\n  const id = toast.loading(initialMessage, {\n    ...options,\n  })\n\n  return {\n    id,\n\n    loading(message: string, opts?: BulkActionToastOptions) {\n      toast.loading(message, { ...opts, id })\n    },\n\n    success(message: string, opts?: BulkActionToastOptions) {\n      toast.success(message, {\n        action: null,\n        ...opts,\n        id,\n      })\n    },\n\n    error(message: string, opts?: BulkActionToastOptions) {\n      toast.error(message, {\n        action: null,\n        ...opts,\n        id,\n      })\n    },\n\n    warning(message: string, opts?: BulkActionToastOptions) {\n      toast.warning(message, {\n        action: null,\n        ...opts,\n        id,\n      })\n    },\n\n    info(message: string, opts?: BulkActionToastOptions) {\n      toast.message(message, {\n        action: null,\n        ...opts,\n        id,\n      })\n    },\n\n    result(\n      { successCount, failureCount }: { successCount: number; failureCount: number },\n      opts: BulkActionResultOptions,\n    ) {\n      const processedCount = successCount + failureCount\n      const allSucceeded = processedCount > 0 && failureCount === 0\n      const allFailed = processedCount > 0 && successCount === 0\n\n      if (allSucceeded) {\n        this.success(opts.successTitle)\n      } else if (allFailed) {\n        this.error(opts.errorTitle)\n      } else if (processedCount > 0) {\n        this.warning(opts.warningTitle, {\n          description: `${successCount} succeeded. ${failureCount} failed.`,\n        })\n      } else {\n        this.info(opts.canceledTitle)\n      }\n    },\n\n    dismiss() {\n      toast.dismiss(id)\n    },\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/lib/env.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { parse } from 'dotenv'\n\nexport interface EnvVar {\n  key: string\n  value: string\n}\n\nexport function parseEnvFile(src: string): EnvVar[] {\n  const parsed = parse(src)\n  return Object.entries(parsed).map(([key, value]) => ({ key, value }))\n}\n"
  },
  {
    "path": "apps/dashboard/src/lib/error-handling.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Action, toast } from 'sonner'\nimport { DaytonaError } from '@/api/errors'\n\nexport function handleApiError(error: unknown, message: string, toastAction?: React.ReactNode | Action) {\n  const isDaytonaError = error instanceof DaytonaError\n\n  toast.error(message, {\n    description: isDaytonaError ? error.message : 'Please try again or check the console for more details',\n    action: toastAction,\n  })\n\n  if (!isDaytonaError) {\n    console.error(message, error)\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/lib/local-storage.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const getLocalStorageItem = (key: string): string | null => {\n  try {\n    return localStorage.getItem(key)\n  } catch (error) {\n    console.error('Failed to read from localStorage:', error)\n    return null\n  }\n}\n\nexport const setLocalStorageItem = (key: string, value: string): void => {\n  try {\n    localStorage.setItem(key, value)\n  } catch (error) {\n    console.error('Failed to write to localStorage:', error)\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/lib/playground.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ReactNode } from 'react'\nimport { CodeLanguage } from '@daytonaio/sdk'\n\nexport const createErrorMessageOutput = (error: unknown): ReactNode => {\n  return (\n    <span>\n      <span className=\"text-red-500\">Error: </span>\n      <span>{error instanceof Error ? error.message : String(error)}</span>\n    </span>\n  )\n}\n\nexport const getLanguageCodeToRun = (language?: CodeLanguage): string => {\n  switch (language) {\n    case CodeLanguage.TYPESCRIPT:\n      return `function greet(name: string): string {\n\\treturn \\`Hello, \\${name}!\\`;\n}\nconsole.log(greet(\"Daytona\"));`\n    case CodeLanguage.JAVASCRIPT:\n      return `function greet(name) {\n\\treturn \\`Hello, \\${name}!\\`;\n}\nconsole.log(greet(\"Daytona\"));`\n    default:\n      // Python is default language if none specified\n      return `def greet(name):\n\\treturn f\"Hello, {name}!\"\nprint(greet(\"Daytona\"))`\n  }\n}\n\nexport const objectHasAnyValue = (obj: object) => Object.values(obj).some((v) => v !== '' && v !== undefined)\n"
  },
  {
    "path": "apps/dashboard/src/lib/schema.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { z } from 'zod'\n\nconst IMAGE_NAME_REGEX = /^[a-zA-Z0-9_.\\-:]+(\\/[a-zA-Z0-9_.\\-:]+)*(@sha256:[a-f0-9]{64})?$/\nconst IMAGE_TAG_OR_DIGEST_REGEX = /^[^@]+@sha256:[a-f0-9]{64}$|^(?!.*@sha256:).*:.+$/\n\nexport const imageNameSchema = z\n  .string()\n  .min(1, 'Image name is required')\n  .refine((name) => IMAGE_NAME_REGEX.test(name), 'Only letters, digits, dots, colons, slashes and dashes are allowed')\n  .refine(\n    (name) => IMAGE_TAG_OR_DIGEST_REGEX.test(name),\n    'Image must include a tag (e.g., ubuntu:22.04) or digest (@sha256:...)',\n  )\n  .refine((name) => !name.endsWith(':latest'), 'Images with tag \":latest\" are not allowed')\n"
  },
  {
    "path": "apps/dashboard/src/lib/suspended-fetch.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nenum PromiseStatus {\n  Pending = 'pending',\n  Success = 'success',\n  Error = 'error',\n}\n\nexport function suspendedFetch<T>(url: string): () => T {\n  let status: PromiseStatus = PromiseStatus.Pending\n  let result: T\n\n  const suspend = fetch(url).then(\n    (res) =>\n      res.json().then(\n        (data) => {\n          status = PromiseStatus.Success\n          result = data\n        },\n        (err) => {\n          status = PromiseStatus.Error\n          result = err\n        },\n      ),\n    (err) => {\n      status = PromiseStatus.Error\n      result = err\n    },\n  )\n\n  return () => {\n    switch (status) {\n      case PromiseStatus.Pending:\n        throw suspend\n      case PromiseStatus.Error:\n        throw result\n      case PromiseStatus.Success:\n        return result\n    }\n  }\n}\n\nexport async function minDuration<T>(callback: Promise<T>, delay = 500): Promise<T> {\n  const a = await Promise.all([callback, new Promise((r) => setTimeout(r, delay))])\n  return a[0]\n}\n"
  },
  {
    "path": "apps/dashboard/src/lib/utils/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n\nexport function getRelativeTimeString(\n  timestamp: string | Date | undefined | null,\n  fallback = '-',\n): { date: Date; relativeTimeString: string } {\n  if (!timestamp) {\n    return { date: new Date(), relativeTimeString: fallback }\n  }\n\n  try {\n    const date = new Date(timestamp)\n    const now = new Date()\n    const diffInMinutes = Math.floor((now.getTime() - date.getTime()) / (1000 * 60))\n    const isFuture = diffInMinutes < 0\n    const absDiffInMinutes = Math.abs(diffInMinutes)\n\n    if (absDiffInMinutes < 1)\n      return {\n        date,\n        relativeTimeString: isFuture ? 'shortly' : 'just now',\n      }\n\n    if (absDiffInMinutes < 60) {\n      return {\n        date,\n        relativeTimeString: isFuture ? `in ${absDiffInMinutes}m` : `${absDiffInMinutes}m ago`,\n      }\n    }\n\n    const hours = Math.floor(absDiffInMinutes / 60)\n    if (hours < 24) {\n      return {\n        date,\n        relativeTimeString: isFuture ? `in ${hours}h` : `${hours}h ago`,\n      }\n    }\n\n    const days = Math.floor(hours / 24)\n    if (days < 365) {\n      return {\n        date,\n        relativeTimeString: isFuture ? `in ${days}d` : `${days}d ago`,\n      }\n    }\n\n    const years = Math.floor(days / 365)\n    return {\n      date,\n      relativeTimeString: isFuture ? `in ${years}y` : `${years}y ago`,\n    }\n  } catch (e) {\n    return { date: new Date(), relativeTimeString: fallback }\n  }\n}\n\nexport function capitalize(value: string) {\n  return value.charAt(0).toUpperCase() + value.slice(1)\n}\n\nexport function getMaskedToken(token: string) {\n  return `${token.substring(0, 3)}********************${token.slice(-3)}`\n}\n\nexport function formatDuration(minutes: number): string {\n  minutes = Math.abs(minutes)\n\n  if (minutes < 60) {\n    return `${Math.floor(minutes)}m`\n  }\n\n  const hours = minutes / 60\n  if (hours < 24) {\n    return `${Math.floor(hours)}h`\n  }\n\n  const days = hours / 24\n  if (days < 365) {\n    return `${Math.floor(days)}d`\n  }\n\n  const years = days / 365\n  return `${Math.floor(years)}y`\n}\n\nexport function pluralize(count: number, singular: string, plural: string): string {\n  return count === 1 ? `${count} ${singular}` : `${count} ${plural}`\n}\n\nexport function isValidUUID(str: string): boolean {\n  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n  return uuidRegex.test(str)\n}\n\nexport function formatTimestamp(timestamp: string | Date | undefined | null): string {\n  if (!timestamp) {\n    return '-'\n  }\n\n  return new Date(timestamp).toLocaleString()\n}\n\nexport function formatAmount(amount: number): string {\n  return Intl.NumberFormat('en-US', {\n    style: 'currency',\n    currency: 'USD',\n    minimumFractionDigits: 2,\n    maximumFractionDigits: 2,\n  }).format((amount ?? 0) / 100)\n}\n\nexport function formatMoney(\n  value: number,\n  options?: { minimumFractionDigits?: number; maximumFractionDigits?: number },\n): string {\n  return Intl.NumberFormat('en-US', {\n    style: 'currency',\n    currency: 'USD',\n    minimumFractionDigits: 2,\n    maximumFractionDigits: 2,\n    ...options,\n  }).format(value)\n}\n\nexport function findLast<T>(arr: T[], predicate: (item: T, index: number, array: T[]) => boolean): T | undefined {\n  for (let i = arr.length - 1; i >= 0; i--) {\n    if (predicate(arr[i], i, arr)) {\n      return arr[i]\n    }\n  }\n\n  return undefined\n}\n\nexport function getRegionFullDisplayName(region: { id: string; name: string; organizationId?: string | null }): string {\n  return `${region.name}${region.organizationId && region.name !== region.id ? ` (${region.id})` : ''}`\n}\n\nexport function getMetaKey(): string {\n  return window.navigator.userAgent.includes('Mac') ? '⌘' : 'Ctrl'\n}\n"
  },
  {
    "path": "apps/dashboard/src/lib/utils/sandbox.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Sandbox, SandboxState } from '@daytonaio/api-client'\n\nexport function isStartable(sandbox: Sandbox): boolean {\n  return sandbox.state === SandboxState.STOPPED || sandbox.state === SandboxState.ARCHIVED\n}\n\nexport function isStoppable(sandbox: Sandbox): boolean {\n  return sandbox.state === SandboxState.STARTED\n}\n\nexport function isArchivable(sandbox: Sandbox): boolean {\n  return sandbox.state === SandboxState.STOPPED\n}\n\nexport function isRecoverable(sandbox: Sandbox): boolean {\n  return sandbox.state === SandboxState.ERROR && sandbox.recoverable === true\n}\n\nexport function isDeletable(_sandbox: Sandbox): boolean {\n  return true\n}\n\nexport function isTransitioning(sandbox: Sandbox): boolean {\n  return (\n    sandbox.state === SandboxState.CREATING ||\n    sandbox.state === SandboxState.STARTING ||\n    sandbox.state === SandboxState.STOPPING ||\n    sandbox.state === SandboxState.DESTROYING ||\n    sandbox.state === SandboxState.ARCHIVING ||\n    sandbox.state === SandboxState.RESTORING ||\n    sandbox.state === SandboxState.BUILDING_SNAPSHOT ||\n    sandbox.state === SandboxState.PULLING_SNAPSHOT\n  )\n}\n\nexport function getSandboxDisplayLabel(sandbox: Sandbox): string {\n  return sandbox.name ? `${sandbox.name} (${sandbox.id})` : sandbox.id\n}\n\nexport function filterStartable<T extends Sandbox>(sandboxes: T[]): T[] {\n  return sandboxes.filter(isStartable)\n}\n\nexport function filterStoppable<T extends Sandbox>(sandboxes: T[]): T[] {\n  return sandboxes.filter(isStoppable)\n}\n\nexport function filterArchivable<T extends Sandbox>(sandboxes: T[]): T[] {\n  return sandboxes.filter(isArchivable)\n}\n\nexport function filterDeletable<T extends Sandbox>(sandboxes: T[]): T[] {\n  return sandboxes.filter(isDeletable)\n}\n\nexport interface BulkActionCounts {\n  startable: number\n  stoppable: number\n  archivable: number\n  deletable: number\n}\n\nexport function getBulkActionCounts(sandboxes: Sandbox[]): BulkActionCounts {\n  return {\n    startable: filterStartable(sandboxes).length,\n    stoppable: filterStoppable(sandboxes).length,\n    archivable: filterArchivable(sandboxes).length,\n    deletable: filterDeletable(sandboxes).length,\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/main.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { NuqsAdapter } from 'nuqs/adapters/react-router/v6'\nimport React, { Suspense } from 'react'\nimport ReactDOM from 'react-dom/client'\nimport { ErrorBoundary } from 'react-error-boundary'\nimport { BrowserRouter } from 'react-router-dom'\nimport App from './App'\nimport { ErrorBoundaryFallback } from './components/ErrorBoundaryFallback'\nimport LoadingFallback from './components/LoadingFallback'\nimport { PostHogProviderWrapper } from './components/PostHogProviderWrapper'\nimport { ThemeProvider } from './contexts/ThemeContext'\nimport './index.css'\nimport { ConfigProvider } from './providers/ConfigProvider'\nimport { QueryProvider } from './providers/QueryProvider'\n\nconst root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)\n\nasync function enableMocking() {\n  if (import.meta.env.VITE_ENABLE_MOCKING !== 'true') {\n    return\n  }\n\n  const { worker } = await import('./mocks/browser')\n  return worker.start()\n}\n\nenableMocking().then(() =>\n  root.render(\n    <React.StrictMode>\n      <ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>\n        <QueryProvider>\n          <ThemeProvider>\n            <Suspense fallback={<LoadingFallback />}>\n              <ConfigProvider>\n                <BrowserRouter>\n                  <PostHogProviderWrapper>\n                    <NuqsAdapter>\n                      <App />\n                    </NuqsAdapter>\n                  </PostHogProviderWrapper>\n                </BrowserRouter>\n              </ConfigProvider>\n            </Suspense>\n          </ThemeProvider>\n        </QueryProvider>\n      </ErrorBoundary>\n    </React.StrictMode>,\n  ),\n)\n"
  },
  {
    "path": "apps/dashboard/src/mocks/browser.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { setupWorker } from 'msw/browser'\nimport { handlers } from './handlers'\n\nexport const worker = setupWorker(...handlers)\n"
  },
  {
    "path": "apps/dashboard/src/mocks/handlers.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OrganizationEmail, OrganizationTier, OrganizationWallet } from '@/billing-api'\nimport { Invoice, PaginatedInvoices, PaymentUrl } from '@/billing-api/types/Invoice'\nimport { Tier } from '@/billing-api/types/tier'\nimport { DaytonaConfiguration } from '@daytonaio/api-client/src'\nimport { bypass, http, HttpResponse } from 'msw'\n\nconst BILLING_API_URL = 'http://localhost:3000/api/billing'\nconst API_URL = import.meta.env.VITE_API_URL\n\nexport const handlers = [\n  http.get(`${API_URL}/config`, async () => {\n    const originalConfig = await fetch(bypass(`${API_URL}/config`)).then((res) => res.json())\n\n    return HttpResponse.json<Partial<DaytonaConfiguration>>({\n      ...originalConfig,\n      billingApiUrl: BILLING_API_URL,\n    })\n  }),\n  http.get(`${BILLING_API_URL}/organization/:organizationId/portal-url`, async () => {\n    return HttpResponse.json<string>(`${BILLING_API_URL}/portal`)\n  }),\n  http.get(`${BILLING_API_URL}/tier`, async () => {\n    return HttpResponse.json<Tier[]>([\n      {\n        tier: 1,\n        tierLimit: {\n          concurrentCPU: 10,\n          concurrentRAMGiB: 20,\n          concurrentDiskGiB: 30,\n        },\n        minTopUpAmountCents: 0,\n        topUpIntervalDays: 0,\n      },\n      {\n        tier: 2,\n        tierLimit: {\n          concurrentCPU: 100,\n          concurrentRAMGiB: 200,\n          concurrentDiskGiB: 300,\n        },\n        minTopUpAmountCents: 2500,\n        topUpIntervalDays: 0,\n      },\n      {\n        tier: 3,\n        tierLimit: {\n          concurrentCPU: 250,\n          concurrentRAMGiB: 500,\n          concurrentDiskGiB: 2000,\n        },\n        minTopUpAmountCents: 50000,\n        topUpIntervalDays: 0,\n      },\n      {\n        tier: 4,\n        tierLimit: {\n          concurrentCPU: 500,\n          concurrentRAMGiB: 1000,\n          concurrentDiskGiB: 5000,\n        },\n        minTopUpAmountCents: 200000,\n        topUpIntervalDays: 30,\n      },\n    ])\n  }),\n  http.get(`${BILLING_API_URL}/organization/:organizationId/wallet`, async () => {\n    return HttpResponse.json<OrganizationWallet>({\n      balanceCents: 1000,\n      ongoingBalanceCents: 1000,\n      name: 'Wallet',\n      creditCardConnected: false,\n      automaticTopUp: undefined,\n      hasFailedOrPendingInvoice: true,\n    })\n  }),\n  http.get(`${BILLING_API_URL}/organization/:organizationId/tier`, async () => {\n    return HttpResponse.json<OrganizationTier>({\n      tier: 2,\n      largestSuccessfulPaymentDate: new Date(),\n      largestSuccessfulPaymentCents: 1000,\n      expiresAt: new Date(),\n      hasVerifiedBusinessEmail: true,\n    })\n  }),\n  http.get(`${BILLING_API_URL}/organization/:organizationId/email`, async () => {\n    return HttpResponse.json<OrganizationEmail[]>([\n      {\n        email: 'user@example.com',\n        verified: true,\n        owner: true,\n        business: false,\n        verifiedAt: new Date(),\n      },\n    ])\n  }),\n  http.get(`${BILLING_API_URL}/organization/:organizationId/invoices`, async ({ request, params }) => {\n    const url = new URL(request.url)\n    const page = parseInt(url.searchParams.get('page') || '1', 10)\n    const perPage = parseInt(url.searchParams.get('perPage') || '50', 10)\n\n    const mockInvoices: Invoice[] = [\n      {\n        id: 'inv-001',\n        number: 'INV-2026-001',\n        currency: 'USD',\n        issuingDate: new Date('2026-01-01').toISOString(),\n        paymentDueDate: new Date('2026-01-15').toISOString(),\n        paymentOverdue: false,\n        paymentStatus: 'succeeded',\n        sequentialId: 1,\n        status: 'finalized',\n        totalAmountCents: 9847,\n        totalDueAmountCents: 0,\n        type: 'subscription',\n        fileUrl: 'https://example.com/invoices/inv-001.pdf',\n      },\n      {\n        id: 'inv-004',\n        number: 'INV-2025-010',\n        currency: 'USD',\n        issuingDate: new Date('2025-10-01').toISOString(),\n        paymentDueDate: new Date('2025-10-15').toISOString(),\n        paymentOverdue: true,\n        paymentStatus: 'pending',\n        sequentialId: 10,\n        status: 'finalized',\n        totalAmountCents: 12150,\n        totalDueAmountCents: 12150,\n        type: 'subscription',\n        fileUrl: 'https://example.com/invoices/inv-004.pdf',\n      },\n      {\n        id: 'inv-009',\n        number: 'INV-2030-010',\n        currency: 'USD',\n        issuingDate: new Date('2025-10-01').toISOString(),\n        paymentDueDate: new Date('2030-10-15').toISOString(),\n        paymentOverdue: false,\n        paymentStatus: 'pending',\n        sequentialId: 10,\n        status: 'pending',\n        totalAmountCents: 12150,\n        totalDueAmountCents: 12150,\n        type: 'subscription',\n        fileUrl: 'https://example.com/invoices/inv-004.pdf',\n      },\n      {\n        id: 'inv-005',\n        number: 'INV-2025-009',\n        currency: 'USD',\n        issuingDate: new Date('2025-09-01').toISOString(),\n        paymentDueDate: new Date('2025-09-15').toISOString(),\n        paymentOverdue: false,\n        paymentStatus: 'failed',\n        sequentialId: 9,\n        status: 'failed',\n        totalAmountCents: 8900,\n        totalDueAmountCents: 0,\n        type: 'add_on',\n        fileUrl: 'https://example.com/invoices/inv-005.pdf',\n      },\n    ]\n\n    const startIndex = (page - 1) * perPage\n    const endIndex = startIndex + perPage\n    const paginatedItems = mockInvoices.slice(startIndex, endIndex)\n    const totalItems = mockInvoices.length\n    const totalPages = Math.ceil(totalItems / perPage)\n\n    return HttpResponse.json<PaginatedInvoices>({\n      items: paginatedItems,\n      totalItems,\n      totalPages,\n    })\n  }),\n  http.post(`${BILLING_API_URL}/organization/:organizationId/invoices/:invoiceId/payment-url`, async () => {\n    return HttpResponse.json<PaymentUrl>({\n      url: 'https://checkout.stripe.com/pay/cs_test_1234567890',\n    })\n  }),\n  http.post(`${BILLING_API_URL}/organization/:organizationId/invoices/:invoiceId/void`, async () => {\n    return HttpResponse.json({})\n  }),\n  http.post(`${BILLING_API_URL}/organization/:organizationId/wallet/top-up`, async () => {\n    return HttpResponse.json<PaymentUrl>({\n      url: `https://checkout.stripe.com/pay/cs_test_${Date.now()}`,\n    })\n  }),\n]\n"
  },
  {
    "path": "apps/dashboard/src/pages/AccountSettings.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { PrivacyPreferencesDialog, usePrivacyConsent } from '@/components/PrivacyPreferencesDialog'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport React, { useState } from 'react'\nimport LinkedAccounts from './LinkedAccounts'\n\nconst AccountSettings: React.FC<{ linkedAccountsEnabled: boolean }> = ({ linkedAccountsEnabled }) => {\n  const { preferences, saveConsent } = usePrivacyConsent()\n  const [showPrivacyDialog, setShowPrivacyDialog] = useState(false)\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Account Settings</PageTitle>\n      </PageHeader>\n\n      <PageContent>\n        <div className=\"flex flex-col gap-6\">\n          {linkedAccountsEnabled && <LinkedAccounts />}\n\n          <Card>\n            <CardContent>\n              <div className=\"flex sm:flex-row flex-col justify-between sm:items-center gap-2\">\n                <div className=\"text-sm\">\n                  <div className=\"text-muted-foreground\">\n                    <p className=\"font-semibold text-foreground\">Privacy Preferences</p>\n                    Manage which tracking technologies are used for analytics and marketing.\n                  </div>\n                </div>\n                <Button variant=\"outline\" onClick={() => setShowPrivacyDialog(true)}>\n                  Manage Preferences\n                </Button>\n              </div>\n            </CardContent>\n          </Card>\n        </div>\n\n        <PrivacyPreferencesDialog\n          open={showPrivacyDialog}\n          onOpenChange={setShowPrivacyDialog}\n          preferences={preferences}\n          onSave={saveConsent}\n        />\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default AccountSettings\n"
  },
  {
    "path": "apps/dashboard/src/pages/AuditLogs.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AuditLogTable } from '@/components/AuditLogTable'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { DateRangePicker, DateRangePickerRef, QuickRangesConfig } from '@/components/ui/date-range-picker'\nimport { Label } from '@/components/ui/label'\nimport { Switch } from '@/components/ui/switch'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { PaginatedAuditLogs } from '@daytonaio/api-client'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { DateRange } from 'react-day-picker'\nimport { useInterval } from 'usehooks-ts'\n\nconst AuditLogs: React.FC = () => {\n  const { auditApi } = useApi()\n\n  const [data, setData] = useState<PaginatedAuditLogs>({\n    items: [],\n    total: 0,\n    page: 1,\n    totalPages: 0,\n    nextToken: undefined,\n  })\n  const [loadingData, setLoadingData] = useState(true)\n  const [autoRefresh, setAutoRefresh] = useState(false)\n  const [dateRange, setDateRange] = useState<DateRange>({ from: undefined, to: undefined })\n  const dateRangePickerRef = useRef<DateRangePickerRef>(null)\n\n  const { selectedOrganization } = useSelectedOrganization()\n\n  const [paginationParams, setPaginationParams] = useState({\n    pageIndex: 0,\n    pageSize: DEFAULT_PAGE_SIZE,\n  })\n  const [currentCursor, setCurrentCursor] = useState<string | undefined>(undefined)\n  const [cursorHistory, setCursorHistory] = useState<string[]>([])\n\n  // Quick ranges configuration\n  const auditLogQuickRanges: QuickRangesConfig = useMemo(\n    () => ({\n      minutes: [5, 15, 30],\n      hours: [1, 3, 6, 12],\n      days: [1, 2, 7, 30, 90],\n      months: [6],\n      years: [1],\n    }),\n    [],\n  )\n\n  const fetchData = useCallback(\n    async (showTableLoadingState = true) => {\n      if (!selectedOrganization) {\n        return\n      }\n\n      if (showTableLoadingState) {\n        setLoadingData(true)\n      }\n\n      try {\n        const response = (\n          await auditApi.getOrganizationAuditLogs(\n            selectedOrganization.id,\n            paginationParams.pageIndex + 1,\n            paginationParams.pageSize,\n            dateRange.from,\n            dateRange.to,\n            currentCursor,\n          )\n        ).data\n\n        setData(response)\n      } catch (error) {\n        handleApiError(error, 'Failed to fetch audit logs')\n      } finally {\n        setLoadingData(false)\n      }\n    },\n    [auditApi, selectedOrganization, paginationParams.pageIndex, paginationParams.pageSize, dateRange, currentCursor],\n  )\n\n  const handlePaginationChange = useCallback(\n    ({ pageIndex, pageSize }: { pageIndex: number; pageSize: number }) => {\n      if (pageSize !== paginationParams.pageSize) {\n        // Reset to first page when changing page size\n        setPaginationParams({ pageIndex: 0, pageSize })\n        setCurrentCursor(undefined)\n        setCursorHistory([])\n      } else if (pageIndex > paginationParams.pageIndex) {\n        // Next page - use cursor if available\n        if (data.nextToken) {\n          // Store current cursor in history before moving to next\n          if (currentCursor) {\n            setCursorHistory((prev) => [...prev, currentCursor])\n          }\n          setCurrentCursor(data.nextToken)\n          setPaginationParams((prev) => ({ ...prev, pageIndex: prev.pageIndex + 1 }))\n        } else {\n          // Regular offset pagination\n          setCurrentCursor(undefined)\n          setCursorHistory([])\n          setPaginationParams({ pageIndex, pageSize })\n        }\n      } else if (pageIndex < paginationParams.pageIndex) {\n        // Previous page - check if we can go back in cursor history\n        if (currentCursor && cursorHistory.length > 0) {\n          // Go back in cursor pagination\n          const previousCursor = cursorHistory[cursorHistory.length - 1]\n          setCursorHistory((prev) => prev.slice(0, -1))\n          setCurrentCursor(previousCursor)\n          setPaginationParams((prev) => ({ ...prev, pageIndex: prev.pageIndex - 1 }))\n        } else {\n          // Go back to offset pagination\n          setCurrentCursor(undefined)\n          setCursorHistory([])\n          setPaginationParams({ pageIndex, pageSize })\n        }\n      } else {\n        // Same page, just update params\n        setPaginationParams({ pageIndex, pageSize })\n      }\n      setLoadingData(true)\n    },\n    [paginationParams.pageIndex, paginationParams.pageSize, data.nextToken, currentCursor, cursorHistory],\n  )\n\n  useEffect(() => {\n    fetchData()\n  }, [fetchData])\n\n  // Auto-refresh\n  useInterval(\n    () => {\n      fetchData(false)\n    },\n    autoRefresh ? 5000 : null,\n  )\n\n  // handle case where there are no items on the current page, and we are not on the first page\n  useEffect(() => {\n    if (data.items.length === 0 && paginationParams.pageIndex > 0) {\n      setPaginationParams((prev) => ({\n        ...prev,\n        pageIndex: prev.pageIndex - 1,\n      }))\n    }\n  }, [data.items.length, paginationParams.pageIndex])\n\n  const handleAutoRefreshChange = useCallback(\n    (enabled: boolean) => {\n      setAutoRefresh(enabled)\n      if (enabled) {\n        // Fetch immediately when enabling auto refresh\n        fetchData(false)\n      }\n    },\n    [fetchData],\n  )\n\n  const handleDateRangeChange = useCallback((range: DateRange) => {\n    setDateRange(range)\n    setPaginationParams({ pageIndex: 0, pageSize: DEFAULT_PAGE_SIZE })\n    setCurrentCursor(undefined)\n    setCursorHistory([])\n    setData((prev) => ({ ...prev, page: 1, nextToken: undefined }))\n  }, [])\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Audit Logs</PageTitle>\n        <div className=\"flex items-center gap-2 ml-auto\">\n          <Label htmlFor=\"auto-refresh\">Auto Refresh</Label>\n          <Switch id=\"auto-refresh\" checked={autoRefresh} onCheckedChange={handleAutoRefreshChange} />\n        </div>\n      </PageHeader>\n\n      <PageContent size=\"full\">\n        <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n          <div className=\"flex gap-2 items-center\">\n            <DateRangePicker\n              value={dateRange}\n              onChange={handleDateRangeChange}\n              quickRangesEnabled={true}\n              quickRanges={auditLogQuickRanges}\n              timeSelection={true}\n              ref={dateRangePickerRef}\n              disabled={loadingData}\n            />\n          </div>\n        </div>\n\n        <AuditLogTable\n          data={data.items}\n          loading={loadingData}\n          pageCount={data.totalPages}\n          totalItems={data.total}\n          onPaginationChange={handlePaginationChange}\n          pagination={{\n            pageIndex: paginationParams.pageIndex,\n            pageSize: paginationParams.pageSize,\n          }}\n        />\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default AuditLogs\n"
  },
  {
    "path": "apps/dashboard/src/pages/Callback.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useEffect } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { useNavigate } from 'react-router-dom'\n\nconst Callback = () => {\n  const { isAuthenticated, isLoading } = useAuth()\n  const navigate = useNavigate()\n\n  useEffect(() => {\n    if (!isLoading && isAuthenticated) {\n      navigate('/')\n    }\n  }, [isLoading, isAuthenticated, navigate])\n\n  return (\n    <div className=\"min-h-screen flex items-center justify-center\">\n      <div className=\"text-center\">\n        <div className=\"w-16 h-16 border-4 border-blue-600 border-t-transparent rounded-full animate-spin mx-auto mb-4\"></div>\n        <p className=\"text-gray-600\">Completing authentication...</p>\n      </div>\n    </div>\n  )\n}\n\nexport default Callback\n"
  },
  {
    "path": "apps/dashboard/src/pages/Dashboard.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useEffect, useMemo, useState } from 'react'\nimport { Outlet } from 'react-router-dom'\n\nimport { AnnouncementBanner } from '@/components/AnnouncementBanner'\nimport { CommandPalette, useRegisterCommands, type CommandConfig } from '@/components/CommandPalette'\nimport { Sidebar } from '@/components/Sidebar'\nimport { SidebarInset, SidebarProvider } from '@/components/ui/sidebar'\nimport { Toaster } from '@/components/ui/sonner'\nimport { VerifyEmailDialog } from '@/components/VerifyEmailDialog'\nimport { DAYTONA_DOCS_URL, DAYTONA_SLACK_URL } from '@/constants/ExternalLinks'\nimport { useTheme } from '@/contexts/ThemeContext'\nimport { LocalStorageKey } from '@/enums/LocalStorageKey'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useOwnerWalletQuery } from '@/hooks/queries/billingQueries'\nimport { useConfig } from '@/hooks/useConfig'\nimport { useDocsSearchCommands } from '@/hooks/useDocsSearchCommands'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useSuspensionBanner } from '@/hooks/useSuspensionBanner'\nimport { cn } from '@/lib/utils'\nimport { BookOpen, BookSearchIcon, SlackIcon, SunMoon } from 'lucide-react'\nimport { useNavigate } from 'react-router-dom'\nimport { PrivacyBanner } from '@/components/PrivacyBanner'\n\nfunction useDashboardCommands() {\n  const { theme, setTheme } = useTheme()\n\n  const helpCommands: CommandConfig[] = useMemo(\n    () => [\n      {\n        id: 'open-slack',\n        label: 'Open Slack',\n        icon: <SlackIcon className=\"w-4 h-4\" />,\n        onSelect: () => window.open(DAYTONA_SLACK_URL, '_blank'),\n      },\n      {\n        id: 'open-docs',\n        label: 'Open Docs',\n        icon: <BookOpen className=\"w-4 h-4\" />,\n        onSelect: () => window.open(DAYTONA_DOCS_URL, '_blank'),\n      },\n      {\n        id: 'search-docs',\n        label: 'Search Docs',\n        icon: <BookSearchIcon className=\"w-4 h-4\" />,\n        page: 'search-docs',\n      },\n    ],\n    [],\n  )\n  useRegisterCommands(helpCommands, { groupId: 'help', groupLabel: 'Help', groupOrder: 2 })\n\n  const globalCommands: CommandConfig[] = useMemo(\n    () => [\n      {\n        id: 'toggle-theme',\n        label: 'Toggle Theme',\n        icon: <SunMoon className=\"w-4 h-4\" />,\n        onSelect: () => setTheme(theme === 'dark' ? 'light' : 'dark'),\n      },\n    ],\n    [theme, setTheme],\n  )\n  useRegisterCommands(globalCommands, { groupId: 'global', groupLabel: 'Global', groupOrder: 5 })\n}\n\nconst Dashboard: React.FC = () => {\n  const { selectedOrganization } = useSelectedOrganization()\n  const [showVerifyEmailDialog, setShowVerifyEmailDialog] = useState(false)\n  const config = useConfig()\n  useOwnerWalletQuery() // prefetch wallet\n\n  useDashboardCommands()\n  useDocsSearchCommands()\n\n  const navigate = useNavigate()\n\n  useSuspensionBanner(selectedOrganization)\n\n  useEffect(() => {\n    if (\n      selectedOrganization?.suspended &&\n      selectedOrganization.suspensionReason === 'Please verify your email address'\n    ) {\n      setShowVerifyEmailDialog(true)\n    }\n  }, [selectedOrganization])\n\n  useEffect(() => {\n    if (!config.billingApiUrl) {\n      return\n    }\n\n    if (!selectedOrganization) {\n      return\n    }\n\n    if (!selectedOrganization.defaultRegionId) {\n      navigate(RoutePath.SETTINGS)\n      return\n    }\n  }, [config.billingApiUrl, selectedOrganization]) // Do not depend on navigate to avoid infinite loops\n\n  const [bannerText, bannerLearnMoreUrl] = useMemo(() => {\n    if (!config.announcements || Object.entries(config.announcements).length === 0) {\n      return [null, null]\n    }\n\n    return [Object.values(config.announcements)[0].text, Object.values(config.announcements)[0].learnMoreUrl]\n  }, [config.announcements])\n  const [isBannerVisible, setIsBannerVisible] = useState(false)\n\n  useEffect(() => {\n    if (!bannerText) {\n      setIsBannerVisible(false)\n      return\n    }\n\n    // Check if this announcement has been dismissed\n    const dismissedBanners = JSON.parse(localStorage.getItem(LocalStorageKey.AnnouncementBannerDismissed) || '[]')\n    const isDismissed = dismissedBanners.includes(bannerText)\n\n    setIsBannerVisible(!isDismissed)\n  }, [bannerText])\n\n  const handleDismissBanner = () => {\n    // Add this announcement to the dismissed list\n    const dismissedBanners = JSON.parse(localStorage.getItem(LocalStorageKey.AnnouncementBannerDismissed) || '[]')\n    localStorage.setItem(LocalStorageKey.AnnouncementBannerDismissed, JSON.stringify([...dismissedBanners, bannerText]))\n\n    setIsBannerVisible(false)\n  }\n\n  return (\n    <div className=\"relative w-full\">\n      {isBannerVisible && bannerText && (\n        <AnnouncementBanner text={bannerText} onDismiss={handleDismissBanner} learnMoreUrl={bannerLearnMoreUrl} />\n      )}\n      <SidebarProvider isBannerVisible={isBannerVisible} defaultOpen={true}>\n        <Sidebar isBannerVisible={isBannerVisible} billingEnabled={!!config.billingApiUrl} version={config.version} />\n        <SidebarInset className=\"overflow-y-auto\">\n          <div className={cn('w-full min-h-screen overscroll-none', isBannerVisible ? 'md:pt-12' : '')}>\n            <Outlet />\n            <CommandPalette />\n          </div>\n        </SidebarInset>\n        <Toaster />\n        <VerifyEmailDialog open={showVerifyEmailDialog} onOpenChange={setShowVerifyEmailDialog} />\n        <PrivacyBanner />\n      </SidebarProvider>\n    </div>\n  )\n}\n\nexport default Dashboard\n"
  },
  {
    "path": "apps/dashboard/src/pages/EmailVerify.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Logo } from '@/assets/Logo'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardHeader, CardTitle } from '@/components/ui/card'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useState, useEffect } from 'react'\nimport { useNavigate, useParams } from 'react-router-dom'\n\nexport default function EmailVerify() {\n  const { organizationId, email, token } = useParams<{\n    organizationId: string\n    email: string\n    token: string\n  }>()\n  const navigate = useNavigate()\n  const [verificationStatus, setVerificationStatus] = useState<'loading' | 'success' | 'error'>('loading')\n  const [errorMessage, setErrorMessage] = useState<string>('')\n  const { onSelectOrganization } = useSelectedOrganization()\n  const { billingApi } = useApi()\n\n  useEffect(() => {\n    const verifyEmail = async () => {\n      if (!organizationId || !email || !token) {\n        setVerificationStatus('error')\n        setErrorMessage('Invalid verification link')\n        return\n      }\n\n      try {\n        await billingApi.verifyOrganizationEmail(organizationId, email, token)\n        setVerificationStatus('success')\n        onSelectOrganization(organizationId)\n        setTimeout(() => {\n          navigate(RoutePath.BILLING_WALLET)\n        }, 1000)\n      } catch (error) {\n        setVerificationStatus('error')\n        setErrorMessage('An error occurred while verifying your email')\n      }\n    }\n\n    verifyEmail()\n  }, [organizationId, email, token, billingApi, navigate, onSelectOrganization])\n\n  return (\n    <div className=\"flex items-center justify-center min-h-screen bg-background\">\n      <Card className=\"w-full max-w-md\">\n        <CardHeader className=\"text-center\">\n          <div className=\"flex justify-center mb-4\">\n            <Logo />\n          </div>\n          {verificationStatus === 'loading' && (\n            <>\n              <CardTitle>Verifying Your Email</CardTitle>\n              <p className=\"text-muted-foreground\">Please wait while we verify your email address...</p>\n            </>\n          )}\n          {verificationStatus === 'success' && (\n            <>\n              <CardTitle className=\"text-green-600\">Email Verified Successfully!</CardTitle>\n              <p className=\"text-muted-foreground\">\n                Your email has been verified. You will be redirected to the wallet page shortly.\n              </p>\n            </>\n          )}\n          {verificationStatus === 'error' && (\n            <>\n              <CardTitle className=\"text-red-600\">Verification Failed</CardTitle>\n              <p className=\"text-muted-foreground\">{errorMessage}</p>\n              <Button onClick={() => navigate(RoutePath.BILLING_WALLET)} className=\"mt-4\">\n                Go to Wallet\n              </Button>\n            </>\n          )}\n        </CardHeader>\n      </Card>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/pages/Experimental.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useState } from 'react'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { Label } from '@/components/ui/label'\nimport { Input } from '@/components/ui/input'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardHeader } from '@/components/ui/card'\nimport { handleApiError } from '@/lib/error-handling'\nimport { toast } from 'sonner'\n\nconst Experimental: React.FC = () => {\n  const { organizationsApi } = useApi()\n  const [loadingCreate, setLoadingCreate] = useState(false)\n  const { selectedOrganization } = useSelectedOrganization()\n  const [headers, setHeaders] = useState<{ key: string; value: string }[]>(() => {\n    const config = selectedOrganization?.experimentalConfig as Record<string, any> | undefined\n    if (!config || typeof config !== 'object' || Array.isArray(config)) {\n      return []\n    }\n\n    return config['otel']?.headers\n      ? Object.entries(config['otel']?.headers).map(([key, value]) => ({ key, value: value as string }))\n      : []\n  })\n  const [newHeader, setNewHeader] = useState<{ key: string; value: string }>({ key: '', value: '' })\n  const [endpoint, setEndpoint] = useState(() => {\n    const config = selectedOrganization?.experimentalConfig as Record<string, any> | undefined\n    if (!config || typeof config !== 'object' || Array.isArray(config)) {\n      return ''\n    }\n\n    return config['otel']?.endpoint || ''\n  })\n  const hasOtelEnabled =\n    selectedOrganization?.experimentalConfig && !!(selectedOrganization.experimentalConfig as Record<string, any>).otel\n\n  const handleSaveConfig = async () => {\n    if (!selectedOrganization) {\n      return\n    }\n\n    setLoadingCreate(true)\n    try {\n      const experimentalConfig = {\n        ...selectedOrganization.experimentalConfig,\n        otel: {\n          endpoint,\n          headers: [...headers, newHeader]\n            .filter(({ key, value }) => key.trim() && value.trim())\n            .reduce(\n              (acc, { key, value }) => {\n                acc[key] = value\n                return acc\n              },\n              {} as { [key: string]: string },\n            ),\n        },\n      }\n\n      await organizationsApi.updateExperimentalConfig(selectedOrganization.id, experimentalConfig)\n      toast.success('Experimental configuration saved successfully')\n      setTimeout(() => window.location.reload(), 500)\n    } catch (error) {\n      handleApiError(error, 'Failed to save experimental configuration')\n    } finally {\n      setLoadingCreate(false)\n    }\n  }\n\n  const handleDisableOtel = async () => {\n    if (!selectedOrganization) {\n      return\n    }\n\n    setLoadingCreate(true)\n    try {\n      const experimentalConfig: any = {\n        ...selectedOrganization.experimentalConfig,\n      }\n      delete experimentalConfig['otel']\n\n      await organizationsApi.updateExperimentalConfig(selectedOrganization.id, experimentalConfig)\n      setEndpoint('')\n      setHeaders([])\n    } catch (error) {\n      handleApiError(error, 'Failed to disable OpenTelemetry configuration')\n    } finally {\n      setLoadingCreate(false)\n    }\n  }\n\n  if (!selectedOrganization) {\n    return <div className=\"p-6\">No organization selected.</div>\n  }\n\n  return (\n    <div className=\"px-6 py-2\">\n      <div className=\"mb-2 h-12\">\n        <h1 className=\"text-2xl font-medium\">Experimental Features</h1>\n\n        <Card className=\"mt-4\">\n          <CardHeader>OpenTelemetry (OTEL) Configuration</CardHeader>\n          <CardContent>\n            <form\n              id=\"experimental-features-form\"\n              className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n              onSubmit={async (e) => {\n                e.preventDefault()\n                await handleSaveConfig()\n              }}\n            >\n              <div className=\"space-y-3\">\n                <Label htmlFor=\"otel-endpoint\">Endpoint</Label>\n                <Input\n                  id=\"otel-endpoint\"\n                  placeholder=\"https://otel-collector.example.com:4318\"\n                  value={endpoint}\n                  onChange={(e) => setEndpoint(e.target.value)}\n                />\n                <p className=\"text-sm text-muted-foreground mt-1 pl-1\">The OpenTelemetry collector endpoint URL.</p>\n              </div>\n\n              <div className=\"space-y-3 max-w-2xl\">\n                <div className=\"flex items-center justify-between\">\n                  <Label>Headers</Label>\n                </div>\n\n                <div className=\"space-y-2\">\n                  {headers.map(({ key, value }, index) => (\n                    <div key={index} className=\"flex items-center gap-2\">\n                      <HeaderInput\n                        headerKey={key}\n                        headerValue={value}\n                        onChangeKey={(e) => {\n                          const newHeaders = [...headers]\n                          newHeaders[index].key = e.target.value\n                          setHeaders(newHeaders)\n                        }}\n                        onChangeValue={(e) => {\n                          const newHeaders = [...headers]\n                          newHeaders[index].value = e.target.value\n                          setHeaders(newHeaders)\n                        }}\n                      />\n                      <Button\n                        type=\"button\"\n                        variant=\"ghost\"\n                        size=\"sm\"\n                        onClick={() => {\n                          const newHeaders = headers.filter((_, i) => i !== index)\n                          setHeaders(newHeaders)\n                        }}\n                      >\n                        Remove\n                      </Button>\n                    </div>\n                  ))}\n\n                  <div className=\"flex items-center gap-2\">\n                    <HeaderInput\n                      headerKey={newHeader.key}\n                      headerValue={newHeader.value}\n                      onChangeKey={(e) => {\n                        setNewHeader({ ...newHeader, key: e.target.value })\n                      }}\n                      onChangeValue={(e) => {\n                        setNewHeader({ ...newHeader, value: e.target.value })\n                      }}\n                      onAdd={() => {\n                        if (newHeader.key.trim() && newHeader.value.trim()) {\n                          setHeaders([...headers, newHeader])\n                          setNewHeader({ key: '', value: '' })\n                        }\n                      }}\n                    />\n                    <Button\n                      type=\"button\"\n                      variant=\"outline\"\n                      size=\"sm\"\n                      onClick={() => {\n                        if (newHeader.key.trim() && newHeader.value.trim()) {\n                          setHeaders([...headers, newHeader])\n                          setNewHeader({ key: '', value: '' })\n                        }\n                      }}\n                      disabled={!newHeader.key.trim() || !newHeader.value.trim()}\n                    >\n                      +\n                    </Button>\n                  </div>\n                </div>\n\n                <p className=\"text-sm text-muted-foreground mt-1 pl-1\">\n                  Optional headers to send with OTEL requests (e.g., authentication tokens).\n                </p>\n              </div>\n\n              <div className=\"flex items-center gap-2\">\n                <Button type=\"submit\" form=\"experimental-features-form\" disabled={loadingCreate || !endpoint.trim()}>\n                  {loadingCreate ? 'Saving...' : 'Save'}\n                </Button>\n                {hasOtelEnabled && (\n                  <Button type=\"button\" variant=\"outline\" onClick={handleDisableOtel}>\n                    Disable\n                  </Button>\n                )}\n              </div>\n            </form>\n          </CardContent>\n        </Card>\n      </div>\n    </div>\n  )\n}\n\nconst HeaderInput = ({\n  headerKey,\n  headerValue,\n  onChangeKey,\n  onChangeValue,\n  onAdd,\n}: {\n  headerKey: string\n  headerValue: string\n  onChangeKey: (e: React.ChangeEvent<HTMLInputElement>) => void\n  onChangeValue: (e: React.ChangeEvent<HTMLInputElement>) => void\n  onAdd?: () => void\n}) => (\n  <>\n    <Input placeholder=\"Header key\" className=\"flex-1\" value={headerKey} onChange={onChangeKey} />\n    <Input\n      placeholder=\"Header value\"\n      className=\"flex-1\"\n      value={headerValue}\n      onChange={onChangeValue}\n      onKeyDown={(e) => {\n        if (e.key === 'Enter' && headerKey.trim() && headerValue.trim()) {\n          onAdd?.()\n        }\n      }}\n    />\n  </>\n)\n\nexport default Experimental\n"
  },
  {
    "path": "apps/dashboard/src/pages/Keys.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CreateApiKeyDialog } from '@/components/CreateApiKeyDialog'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { useRevokeApiKeyMutation } from '@/hooks/mutations/useRevokeApiKeyMutation'\nimport { useApiKeysQuery } from '@/hooks/queries/useApiKeysQuery'\nimport { useConfig } from '@/hooks/useConfig'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { ApiKeyList, CreateApiKeyPermissionsEnum, OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport { useCallback, useMemo, useState } from 'react'\nimport { toast } from 'sonner'\nimport { ApiKeyTable } from '../components/ApiKeyTable'\n\nconst Keys: React.FC = () => {\n  const { apiUrl } = useConfig()\n  const [loadingKeys, setLoadingKeys] = useState<Record<string, boolean>>({})\n\n  const { selectedOrganization, authenticatedUserOrganizationMember } = useSelectedOrganization()\n  const revokeApiKeyMutation = useRevokeApiKeyMutation()\n  const apiKeysQuery = useApiKeysQuery(selectedOrganization?.id)\n\n  const availablePermissions = useMemo<CreateApiKeyPermissionsEnum[]>(() => {\n    if (!authenticatedUserOrganizationMember) {\n      return []\n    }\n    if (authenticatedUserOrganizationMember.role === OrganizationUserRoleEnum.OWNER) {\n      return Object.values(CreateApiKeyPermissionsEnum)\n    }\n    return Array.from(new Set(authenticatedUserOrganizationMember.assignedRoles.flatMap((role) => role.permissions)))\n  }, [authenticatedUserOrganizationMember])\n\n  const handleRevoke = async (key: ApiKeyList) => {\n    if (!selectedOrganization) {\n      return\n    }\n    const loadingId = getLoadingKeyId(key)\n    setLoadingKeys((prev) => ({ ...prev, [loadingId]: true }))\n    try {\n      await revokeApiKeyMutation.mutateAsync({\n        userId: key.userId,\n        name: key.name,\n        organizationId: selectedOrganization.id,\n      })\n      toast.success('API key revoked successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to revoke API key')\n    } finally {\n      setLoadingKeys((prev) => ({ ...prev, [loadingId]: false }))\n    }\n  }\n\n  const getLoadingKeyId = useCallback((key: ApiKeyList) => {\n    return `${key.userId}-${key.name}`\n  }, [])\n\n  const isLoadingKey = useCallback(\n    (key: ApiKeyList) => {\n      const loadingId = getLoadingKeyId(key)\n      return loadingKeys[loadingId]\n    },\n    [getLoadingKeyId, loadingKeys],\n  )\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>API Keys</PageTitle>\n        <CreateApiKeyDialog\n          className=\"ml-auto\"\n          availablePermissions={availablePermissions}\n          apiUrl={apiUrl}\n          organizationId={selectedOrganization?.id}\n        />\n      </PageHeader>\n\n      <PageContent>\n        <ApiKeyTable\n          data={apiKeysQuery.data ?? []}\n          loading={apiKeysQuery.isLoading || apiKeysQuery.isRefetching}\n          isLoadingKey={isLoadingKey}\n          onRevoke={handleRevoke}\n        />\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default Keys\n"
  },
  {
    "path": "apps/dashboard/src/pages/LandingPage.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport { Navigate, useLocation } from 'react-router-dom'\nimport { useAuth } from 'react-oidc-context'\nimport LoadingFallback from '@/components/LoadingFallback'\nimport { RoutePath } from '@/enums/RoutePath'\n\nconst LandingPage: React.FC = () => {\n  const { signinRedirect, isAuthenticated, isLoading } = useAuth()\n  const location = useLocation()\n\n  if (isLoading) {\n    return <LoadingFallback />\n  }\n\n  if (isAuthenticated) {\n    return <Navigate to={`${RoutePath.DASHBOARD}${location.search}`} replace />\n  } else {\n    void signinRedirect({\n      state: {\n        returnTo: location.pathname + location.search,\n      },\n    })\n  }\n}\n\nexport default LandingPage\n"
  },
  {
    "path": "apps/dashboard/src/pages/Limits.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { LiveIndicator } from '@/components/LiveIndicator'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { TierComparisonTable, TierComparisonTableSkeleton } from '@/components/TierComparisonTable'\nimport { TierUpgradeCard } from '@/components/TierUpgradeCard'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { UsageOverview, UsageOverviewSkeleton } from '@/components/UsageOverview'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useOwnerTierQuery, useOwnerWalletQuery } from '@/hooks/queries/billingQueries'\nimport { useOrganizationUsageOverviewQuery } from '@/hooks/queries/useOrganizationUsageOverviewQuery'\nimport { useTiersQuery } from '@/hooks/queries/useTiersQuery'\nimport { useConfig } from '@/hooks/useConfig'\nimport { useRegions } from '@/hooks/useRegions'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { cn } from '@/lib/utils'\nimport type { RegionUsageOverview } from '@daytonaio/api-client'\nimport { keepPreviousData } from '@tanstack/react-query'\nimport { RefreshCcw } from 'lucide-react'\nimport { ReactNode, useEffect, useMemo, useState } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { useNavigate } from 'react-router-dom'\n\nexport default function Limits() {\n  const { user } = useAuth()\n  const { selectedOrganization } = useSelectedOrganization()\n  const organizationTierQuery = useOwnerTierQuery()\n  const walletQuery = useOwnerWalletQuery()\n  const tiersQuery = useTiersQuery()\n\n  const organizationTier = organizationTierQuery.data\n  const tiers = tiersQuery.data?.sort((a, b) => a.tier - b.tier)\n  const wallet = walletQuery.data\n\n  const { getRegionName } = useRegions()\n  const [selectedRegionId, setSelectedRegionId] = useState<string | undefined>(undefined)\n  const config = useConfig()\n  const navigate = useNavigate()\n\n  useEffect(() => {\n    if (selectedOrganization && !selectedOrganization.defaultRegionId) {\n      navigate(RoutePath.SETTINGS)\n    }\n  }, [navigate, selectedOrganization])\n\n  const { data: usageOverview, ...usageOverviewQuery } = useOrganizationUsageOverviewQuery(\n    {\n      organizationId: selectedOrganization?.id || '',\n    },\n    {\n      placeholderData: keepPreviousData,\n      refetchInterval: 10_000,\n      refetchIntervalInBackground: true,\n      staleTime: 0,\n    },\n  )\n\n  useEffect(() => {\n    if (usageOverview && usageOverview.regionUsage.length > 0 && !selectedRegionId) {\n      const regionIds = usageOverview.regionUsage.map((usage) => usage.regionId)\n      const regionId = regionIds.find((regionId) => regionId === selectedOrganization?.defaultRegionId) || regionIds[0]\n      setSelectedRegionId(regionId)\n    }\n  }, [usageOverview, selectedOrganization?.defaultRegionId, selectedRegionId])\n\n  const currentRegionUsageOverview = useMemo<RegionUsageOverview | null>(() => {\n    if (!usageOverview || !selectedRegionId) {\n      return null\n    }\n    return usageOverview.regionUsage.find((usage) => usage.regionId === selectedRegionId) || null\n  }, [usageOverview, selectedRegionId])\n\n  const isLoading = organizationTierQuery.isLoading || tiersQuery.isLoading || walletQuery.isLoading\n  const isError =\n    organizationTierQuery.isError || tiersQuery.isError || usageOverviewQuery.isError || walletQuery.isError\n\n  const handleRetry = () => {\n    organizationTierQuery.refetch()\n    tiersQuery.refetch()\n    usageOverviewQuery.refetch()\n    walletQuery.refetch()\n  }\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Limits</PageTitle>\n      </PageHeader>\n\n      <PageContent>\n        {isError ? (\n          <Card>\n            <CardHeader>\n              <CardTitle className=\"text-center\">Oops, something went wrong</CardTitle>\n            </CardHeader>\n            <CardContent className=\"flex justify-between items-center flex-col gap-3\">\n              <div>There was an error loading your limits.</div>\n              <Button variant=\"outline\" onClick={handleRetry}>\n                <RefreshCcw className=\"mr-2 h-4 w-4\" />\n                Retry\n              </Button>\n            </CardContent>\n          </Card>\n        ) : (\n          <>\n            <Card>\n              <CardHeader className=\"p-4\">\n                <div className=\"flex items-center justify-between gap-2 mb-2 flex-wrap\">\n                  <CardTitle className=\"flex justify-between gap-x-4 gap-y-2 flex-row flex-wrap items-center\">\n                    <div className=\"flex items-center gap-2\">\n                      Current Usage{' '}\n                      {organizationTier && (\n                        <Badge variant=\"outline\" className=\"font-mono uppercase\">\n                          Tier {organizationTier.tier}\n                        </Badge>\n                      )}\n                    </div>\n                  </CardTitle>\n                  {usageOverview && usageOverview.regionUsage.length > 0 && (\n                    <div className=\"flex items-center gap-2\">\n                      <span className=\"text-sm text-muted-foreground\">Region:</span>\n                      <Select value={selectedRegionId} onValueChange={setSelectedRegionId}>\n                        <SelectTrigger\n                          size=\"xs\"\n                          disabled={usageOverview.regionUsage.length === 1}\n                          className={`uppercase w-auto min-w-12 max-w-48 gap-x-2 ${usageOverview.regionUsage.length === 1 ? 'pointer-events-none select-none [&>svg]:hidden min-w-10 disabled:opacity-100' : ''}`}\n                        >\n                          <SelectValue placeholder=\"Select region\" />\n                        </SelectTrigger>\n                        <SelectContent className=\"min-w-24 max-w-48\" align=\"end\">\n                          {usageOverview.regionUsage.map((usage) => (\n                            <SelectItem key={usage.regionId} value={usage.regionId} className=\"uppercase\">\n                              {getRegionName(usage.regionId) ?? usage.regionId}\n                            </SelectItem>\n                          ))}\n                        </SelectContent>\n                      </Select>\n                    </div>\n                  )}\n                </div>\n                <CardDescription>\n                  Limits help us mitigate misuse and manage infrastructure resources. <br /> Ensuring fair and stable\n                  access to sandboxes and compute capacity across all users.\n                </CardDescription>\n              </CardHeader>\n              <CardContent className=\"p-0 flex flex-col\">\n                {usageOverviewQuery.isLoading ? (\n                  <UsageOverviewSkeleton />\n                ) : (\n                  usageOverview &&\n                  currentRegionUsageOverview && (\n                    <div className=\"p-4 border-t border-border flex flex-col gap-2\">\n                      <div className=\"flex items-center gap-4\">\n                        <div className=\"text-sm font-medium\">Resources</div>\n                        <LiveIndicator\n                          isUpdating={usageOverviewQuery.isFetching}\n                          intervalMs={10_000}\n                          lastUpdatedAt={usageOverviewQuery.dataUpdatedAt || 0}\n                        />\n                      </div>\n                      <UsageOverview usageOverview={currentRegionUsageOverview} />\n                    </div>\n                  )\n                )}\n                <RateLimits\n                  title=\"Sandbox Limits\"\n                  description=\"Resources limit per sandbox.\"\n                  className=\"border-t border-border\"\n                  rateLimits={[\n                    { label: 'Compute', value: selectedOrganization?.maxCpuPerSandbox, unit: 'vCPU' },\n                    { label: 'Memory', value: selectedOrganization?.maxMemoryPerSandbox, unit: 'GiB' },\n                    { label: 'Storage', value: selectedOrganization?.maxDiskPerSandbox, unit: 'GiB' },\n                  ]}\n                />\n\n                <RateLimits\n                  title=\"Rate Limits\"\n                  description=\"How many requests you can make.\"\n                  className=\"border-t border-border\"\n                  rateLimits={[\n                    {\n                      value: selectedOrganization?.authenticatedRateLimit || config?.rateLimit?.authenticated?.limit,\n                      label: 'General Requests',\n                      ttlSeconds:\n                        selectedOrganization?.authenticatedRateLimitTtlSeconds ?? config?.rateLimit?.authenticated?.ttl,\n                    },\n                    {\n                      value: selectedOrganization?.sandboxCreateRateLimit || config?.rateLimit?.sandboxCreate?.limit,\n                      label: 'Sandbox Creation',\n                      ttlSeconds:\n                        selectedOrganization?.sandboxCreateRateLimitTtlSeconds ?? config?.rateLimit?.sandboxCreate?.ttl,\n                    },\n                    {\n                      value:\n                        selectedOrganization?.sandboxLifecycleRateLimit || config?.rateLimit?.sandboxLifecycle?.limit,\n                      label: 'Sandbox Lifecycle',\n                      ttlSeconds:\n                        selectedOrganization?.sandboxLifecycleRateLimitTtlSeconds ??\n                        config?.rateLimit?.sandboxLifecycle?.ttl,\n                    },\n                  ]}\n                />\n              </CardContent>\n            </Card>\n\n            {config.billingApiUrl && selectedOrganization && (\n              <>\n                <TierUpgradeCard\n                  organizationTier={organizationTier}\n                  tiers={tiers || []}\n                  organization={selectedOrganization}\n                  requirementsState={{\n                    emailVerified: !!user?.profile?.email_verified,\n                    creditCardLinked: !!wallet?.creditCardConnected,\n                  }}\n                />\n\n                <Card className=\"mb-10\">\n                  <CardHeader>\n                    <CardTitle className=\"flex items-center mb-2\">Limits</CardTitle>\n                  </CardHeader>\n                  <CardContent className=\"p-0\">\n                    {isLoading ? (\n                      <TierComparisonTableSkeleton />\n                    ) : (\n                      <TierComparisonTable\n                        className=\"border-l-0 border-r-0 rounded-none only:mb-4\"\n                        tiers={tiers || []}\n                        currentTier={organizationTier}\n                      />\n                    )}\n                  </CardContent>\n                </Card>\n              </>\n            )}\n          </>\n        )}\n      </PageContent>\n    </PageLayout>\n  )\n}\n\ninterface LimitItem {\n  value?: number | null\n  unit?: string\n  label: string\n  ttlSeconds?: number | null\n}\n\nfunction RateLimits({\n  rateLimits,\n  className,\n  title,\n  description,\n}: {\n  rateLimits: LimitItem[]\n  className?: string\n  title: ReactNode\n  description: ReactNode\n}) {\n  const isEmpty = rateLimits.every(({ value }) => !value)\n  if (isEmpty) {\n    return null\n  }\n\n  return (\n    <div className={cn('p-4 border-t border-border flex flex-col gap-4', className)}>\n      <div className=\"flex flex-col gap-1\">\n        <div className=\"text-foreground text-sm font-medium\">{title}</div>\n        <div className=\"text-muted-foreground text-sm\">{description}</div>\n      </div>\n      <div className=\"grid grid-cols-1 gap-2 sm:gap-4 sm:grid-cols-3\">\n        {rateLimits.map(\n          ({ label, value, unit, ttlSeconds }) =>\n            value && <RateLimitItem key={label} label={label} value={value} unit={unit} ttlSeconds={ttlSeconds} />,\n        )}\n      </div>\n    </div>\n  )\n}\n\nfunction formatTtl(ttlSeconds?: number | null): string {\n  if (!ttlSeconds) return ' / min'\n  if (ttlSeconds % 60 === 0) return ` / ${ttlSeconds / 60}min`\n  return ` / ${ttlSeconds}s`\n}\n\nfunction RateLimitItem({ label, value, unit, ttlSeconds }: LimitItem) {\n  if (!value) {\n    return null\n  }\n\n  return (\n    <div className=\"flex flex-col\">\n      <div className=\"text-muted-foreground text-xs\">{label}</div>\n      <div className=\"text-foreground text-sm font-medium\">\n        {value?.toLocaleString()}\n        {unit ? ` ${unit}` : formatTtl(ttlSeconds)}\n      </div>\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/pages/LinkedAccounts.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { AccountProviderIcon } from '@/components/AccountProviderIcon'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Spinner } from '@/components/ui/spinner'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'\nimport { useUnlinkAccountMutation } from '@/hooks/mutations/useUnlinkAccountMutation'\nimport { useAccountProvidersQuery } from '@/hooks/queries/useAccountProvidersQuery'\nimport { handleApiError } from '@/lib/error-handling'\nimport { ShieldCheck } from 'lucide-react'\nimport React, { useMemo } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { toast } from 'sonner'\n\nexport interface UserProfileIdentity {\n  provider: string\n  userId: string\n}\n\ninterface AccountProvider {\n  name: string\n  displayName: string\n  userId: string | null\n  isLinked: boolean\n  isPrimary: boolean\n}\n\nconst LinkedAccounts: React.FC = () => {\n  const { user } = useAuth()\n  const accountProvidersQuery = useAccountProvidersQuery()\n\n  const accountProviders = useMemo<AccountProvider[]>(() => {\n    const identities = (user?.profile.identities as UserProfileIdentity[]) || []\n\n    return (accountProvidersQuery.data || [])\n      .map((provider) => {\n        const identity = identities.find((i) => i.provider === provider.name)\n        return {\n          name: provider.name,\n          displayName: provider.displayName,\n          userId: identity?.userId || null,\n          isLinked: Boolean(identity),\n          isPrimary: Boolean(identity && user?.profile.sub === `${identity.provider}|${identity.userId}`),\n        }\n      })\n      .filter((provider) => provider.isLinked)\n      .sort((a, b) => Number(b.isPrimary) - Number(a.isPrimary))\n  }, [accountProvidersQuery.data, user])\n\n  return (\n    <Card>\n      <CardHeader className=\"p-4\">\n        <CardTitle>Linked Accounts</CardTitle>\n        <CardDescription>View and manage accounts linked to your Daytona account.</CardDescription>\n      </CardHeader>\n      {accountProvidersQuery.isLoading ? (\n        <CardContent className=\"flex flex-col gap-5\">\n          {[...Array(2)].map((_, index) => (\n            <ProviderSkeleton key={index} />\n          ))}\n        </CardContent>\n      ) : (\n        <CardContent className=\"p-0\">\n          {accountProviders.map((provider) => (\n            <LinkedAccount key={provider.name} provider={provider} />\n          ))}\n        </CardContent>\n      )}\n    </Card>\n  )\n}\n\nconst ProviderSkeleton = () => {\n  return (\n    <div className=\"flex flex-col gap-2\">\n      <div className=\"flex items-center gap-2\">\n        <Skeleton className=\"w-5 h-5\" />\n        <Skeleton className=\"w-24 h-5\" />\n      </div>\n      <Skeleton className=\"w-full h-5\" />\n    </div>\n  )\n}\n\nexport default LinkedAccounts\n\nconst LinkedAccount = ({ provider }: { provider: AccountProvider }) => {\n  const unlinkAccountMutation = useUnlinkAccountMutation()\n  const { signinSilent } = useAuth()\n\n  const handleUnlinkAccount = async () => {\n    if (provider.isPrimary) {\n      toast.error('Primary account cannot be unlinked')\n      return\n    }\n\n    if (!provider.userId) {\n      return\n    }\n\n    try {\n      await unlinkAccountMutation.mutateAsync({ provider: provider.name, userId: provider.userId })\n      toast.success('Successfully unlinked account')\n      await new Promise((resolve) => setTimeout(resolve, 1500))\n      const success = await signinSilent()\n      if (!success) {\n        window.location.reload()\n      }\n    } catch (error) {\n      handleApiError(error, 'Failed to unlink account')\n    }\n  }\n\n  return (\n    <div className=\"flex items-center gap-3 p-4 border-t border-border justify-between\">\n      <div className=\"flex flex-col\">\n        <div className=\"flex items-center gap-2\">\n          <AccountProviderIcon provider={provider.name} className=\"h-4 w-4\" />\n          <div>{provider.displayName}</div>\n          {provider.isPrimary && (\n            <Tooltip>\n              <TooltipTrigger asChild>\n                <Badge variant=\"outline\" className=\"gap-1 text-xs\">\n                  <ShieldCheck className=\"h-3 w-3\" />\n                  Primary\n                </Badge>\n              </TooltipTrigger>\n              <TooltipContent>\n                <p>Primary accounts cannot be unlinked</p>\n              </TooltipContent>\n            </Tooltip>\n          )}\n        </div>\n        <p className=\"text-sm text-muted-foreground\">\n          {provider.isPrimary\n            ? `This is your primary account used for authentication.`\n            : `Your ${provider.displayName} account is linked as a secondary login method.`}\n        </p>\n      </div>\n      {!provider.isPrimary && (\n        <Button variant=\"outline\" onClick={handleUnlinkAccount} disabled={unlinkAccountMutation.isPending}>\n          {unlinkAccountMutation.isPending && <Spinner />}\n          Unlink\n        </Button>\n      )}\n    </div>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/pages/Logout.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport LoadingFallback from '@/components/LoadingFallback'\nimport { usePostHog } from 'posthog-js/react'\nimport { useEffect } from 'react'\nimport { useAuth } from 'react-oidc-context'\n\nconst Logout = () => {\n  const { signoutRedirect } = useAuth()\n  const posthog = usePostHog()\n\n  useEffect(() => {\n    posthog?.reset()\n    void signoutRedirect()\n  }, [signoutRedirect, posthog])\n\n  return <LoadingFallback />\n}\n\nexport default Logout\n"
  },
  {
    "path": "apps/dashboard/src/pages/NotFound.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React from 'react'\nimport { useNavigate } from 'react-router-dom'\nimport { Button } from '@/components/ui/button'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { Home } from 'lucide-react'\n\nconst NotFound: React.FC = () => {\n  const navigate = useNavigate()\n\n  return (\n    <div className=\"min-h-screen bg-background flex items-center justify-center p-4\">\n      <div className=\"text-center space-y-6 max-w-lg\">\n        <h1 className=\"text-4xl font-bold text-foreground animate-bounce\">404</h1>\n        <p className=\"text-base text-muted-foreground\">The page you're looking for doesn't exist or has been moved.</p>\n        <Button onClick={() => navigate(RoutePath.DASHBOARD)} className=\"flex items-center gap-2 mx-auto\">\n          <Home className=\"w-4 h-4\" />\n          Go to Dashboard\n        </Button>\n      </div>\n    </div>\n  )\n}\n\nexport default NotFound\n"
  },
  {
    "path": "apps/dashboard/src/pages/Onboarding.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport pythonIcon from '@/assets/python.svg'\nimport typescriptIcon from '@/assets/typescript.svg'\nimport CodeBlock from '@/components/CodeBlock'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport { DAYTONA_DOCS_URL } from '@/constants/ExternalLinks'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useApi } from '@/hooks/useApi'\nimport { useOrganizations } from '@/hooks/useOrganizations'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { getMaskedToken } from '@/lib/utils'\nimport { ApiKeyResponse, CreateApiKeyPermissionsEnum, OrganizationRolePermissionsEnum } from '@daytonaio/api-client'\nimport { Check, ClipboardIcon, Eye, EyeOff, Loader2, Plus } from 'lucide-react'\nimport { useEffect, useState } from 'react'\nimport { useNavigate } from 'react-router-dom'\nimport { toast } from 'sonner'\n\nconst Onboarding: React.FC = () => {\n  const { apiKeyApi } = useApi()\n  const { organizations } = useOrganizations()\n  const { selectedOrganization, onSelectOrganization, authenticatedUserHasPermission } = useSelectedOrganization()\n  const navigate = useNavigate()\n\n  const [language, setLanguage] = useState<'typescript' | 'python'>('python')\n  const [apiKeyName, setApiKeyName] = useState('')\n  const [apiKeyPermissions, setApiKeyPermissions] = useState<CreateApiKeyPermissionsEnum[]>([])\n  const [createdApiKey, setCreatedApiKey] = useState<ApiKeyResponse | null>(null)\n  const [isApiKeyRevealed, setIsApiKeyRevealed] = useState(false)\n  const [isApiKeyCopied, setIsApiKeyCopied] = useState(false)\n  const [isLoadingCreateKey, setIsLoadingCreateKey] = useState(false)\n  const [hasSufficientPermissions, setHasSufficientPermissions] = useState(false)\n\n  // Reset onboarding when switching organizations\n  useEffect(() => {\n    if (selectedOrganization) {\n      setCreatedApiKey(null)\n      setHasSufficientPermissions(false)\n      setApiKeyPermissions([])\n    }\n  }, [selectedOrganization])\n\n  // User must have permission to create sandboxes to use the onboarding snippet\n  useEffect(() => {\n    const ensureOnboardingPermissions = async () => {\n      if (authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_SANDBOXES)) {\n        setHasSufficientPermissions(true)\n        const permissions: CreateApiKeyPermissionsEnum[] = [CreateApiKeyPermissionsEnum.WRITE_SANDBOXES]\n        if (authenticatedUserHasPermission(OrganizationRolePermissionsEnum.DELETE_SANDBOXES)) {\n          permissions.push(CreateApiKeyPermissionsEnum.DELETE_SANDBOXES)\n        }\n        setApiKeyPermissions(permissions)\n      } else {\n        const personalOrg = organizations.find((org) => org.personal)\n\n        if (personalOrg) {\n          const success = await onSelectOrganization(personalOrg.id)\n          if (success) {\n            toast.success('Switched to personal organization', {\n              description:\n                'You did not have the necessary permissions for creating sandboxes in the previous organization.',\n            })\n            return\n          }\n        }\n\n        toast.error('An unexpected issue occurred while preparing your onboarding snippet')\n      }\n    }\n\n    ensureOnboardingPermissions()\n  }, [authenticatedUserHasPermission, onSelectOrganization, organizations])\n\n  const handleCreateApiKey = async () => {\n    if (!selectedOrganization) {\n      return\n    }\n\n    setIsLoadingCreateKey(true)\n    try {\n      const key = (\n        await apiKeyApi.createApiKey(\n          {\n            name: apiKeyName,\n            permissions: apiKeyPermissions,\n          },\n          selectedOrganization.id,\n        )\n      ).data\n      setCreatedApiKey(key)\n      setApiKeyName('')\n      toast.success('API key created successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to create API key')\n    } finally {\n      setIsLoadingCreateKey(false)\n    }\n  }\n\n  const copyToClipboard = async (value: string) => {\n    try {\n      await navigator.clipboard.writeText(value)\n      setIsApiKeyCopied(true)\n      setTimeout(() => setIsApiKeyCopied(false), 2000)\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n    }\n  }\n\n  return (\n    <div className=\"p-6\">\n      <div className=\"min-h-screen p-14\">\n        <div className=\"max-w-3xl mx-auto\">\n          <div className=\"flex justify-between items-center mb-8\">\n            <div>\n              <h1 className=\"text-2xl font-bold mb-2\">Get Started</h1>\n              <p className=\"text-muted-foreground\">Install and get your Sandboxes running.</p>\n            </div>\n            <div className=\"flex items-center space-x-2\">\n              <Tabs value={language} onValueChange={(value) => setLanguage(value as 'typescript' | 'python')}>\n                <TabsList className=\"bg-foreground/10 p-0 rounded-none\">\n                  <TabsTrigger\n                    value=\"python\"\n                    className=\"data-[state=active]:bg-transparent data-[state=active]:text-foreground border-b-2 data-[state=active]:border-primary rounded-none h-full\"\n                  >\n                    <img src={pythonIcon} alt=\"Python\" className=\"w-4 h-4\" />\n                  </TabsTrigger>\n                  <TabsTrigger\n                    value=\"typescript\"\n                    className=\"data-[state=active]:bg-transparent data-[state=active]:text-foreground border-b-2 data-[state=active]:border-primary rounded-none h-full\"\n                  >\n                    <img src={typescriptIcon} alt=\"TypeScript\" className=\"w-4 h-4\" />\n                  </TabsTrigger>\n                </TabsList>\n              </Tabs>\n            </div>\n          </div>\n\n          <div className=\"relative\">\n            {/* Timeline line */}\n            <div className=\"absolute left-[15px] top-[40px] bottom-0 w-[2px] bg-muted-foreground/50\" />\n\n            {/* Steps */}\n            <div className=\"space-y-12\">\n              {/* Step 1 */}\n              <div className=\"relative pl-12\">\n                <div className=\"absolute left-0 w-8 h-8 text-background rounded-full bg-muted-foreground flex items-center justify-center text-sm\">\n                  1\n                </div>\n                <div>\n                  <h2 className=\"text-xl font-semibold mb-4\">Install the SDK</h2>\n                  <p className=\"mb-4\">Run the following command in your terminal to install the Daytona SDK:</p>\n                  <div className=\"transition-all duration-500\">\n                    <CodeBlock code={codeExamples[language].install} language=\"bash\" showCopy />\n                  </div>\n                </div>\n              </div>\n\n              {/* Step 2 */}\n              <div className=\"relative pl-12\">\n                <div className=\"absolute left-0 w-8 h-8 text-background rounded-full bg-muted-foreground flex items-center justify-center text-sm\">\n                  2\n                </div>\n                <div>\n                  <h2 className=\"text-xl font-semibold mb-4\">Create an API Key</h2>\n                  <p className=\"mb-4\">\n                    This API key will have permissions to only{' '}\n                    {apiKeyPermissions.includes(CreateApiKeyPermissionsEnum.DELETE_SANDBOXES) ? 'manage' : 'create'}{' '}\n                    Sandboxes. For full API permissions, head to the{' '}\n                    <button\n                      onClick={() => navigate(RoutePath.KEYS)}\n                      className=\"underline cursor-pointer hover:text-muted-foreground\"\n                    >\n                      Keys\n                    </button>{' '}\n                    page.\n                  </p>\n                  {createdApiKey ? (\n                    <div className=\"p-4 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                      <span className=\"overflow-x-auto pr-2 cursor-text select-all\">\n                        {isApiKeyRevealed ? createdApiKey.value : getMaskedToken(createdApiKey.value)}\n                      </span>\n                      <div className=\"flex items-center space-x-3 pl-3\">\n                        {isApiKeyRevealed ? (\n                          <EyeOff\n                            className=\"w-4 h-4 cursor-pointer hover:text-green-400 dark:hover:text-green-200 transition-colors\"\n                            onClick={() => setIsApiKeyRevealed(false)}\n                          />\n                        ) : (\n                          <Eye\n                            className=\"w-4 h-4 cursor-pointer hover:text-green-400 dark:hover:text-green-200 transition-colors\"\n                            onClick={() => setIsApiKeyRevealed(true)}\n                          />\n                        )}\n                        {isApiKeyCopied ? (\n                          <Check className=\"w-4 h-4\" />\n                        ) : (\n                          <ClipboardIcon\n                            className=\"w-4 h-4 cursor-pointer hover:text-green-400 dark:hover:text-green-200 transition-colors\"\n                            onClick={() => copyToClipboard(createdApiKey.value)}\n                          />\n                        )}\n                      </div>\n                    </div>\n                  ) : (\n                    <form\n                      onSubmit={async (e) => {\n                        e.preventDefault()\n                        await handleCreateApiKey()\n                      }}\n                    >\n                      <div className=\"mb-6\">\n                        <label htmlFor=\"key-name\" className=\"block mb-1 text-sm font-medium text-muted-foreground\">\n                          API Key Name\n                        </label>\n\n                        <Input\n                          id=\"key-name\"\n                          type=\"text\"\n                          value={apiKeyName}\n                          onChange={(e) => setApiKeyName(e.target.value)}\n                          required\n                          placeholder=\"e.g. Onboarding\"\n                          className=\"md:text-base px-4 h-10.5\"\n                          disabled={!hasSufficientPermissions}\n                        />\n                      </div>\n                      <Button\n                        type=\"submit\"\n                        disabled={isLoadingCreateKey || !hasSufficientPermissions}\n                        className=\"text-base\"\n                      >\n                        {isLoadingCreateKey ? (\n                          <Loader2 className=\"h-6 w-6 animate-spin\" />\n                        ) : (\n                          <Plus className=\"w-6 h-6\" />\n                        )}\n                        Create API Key\n                      </Button>\n                    </form>\n                  )}\n                </div>\n              </div>\n\n              {/* Step 3 */}\n              <div className=\"relative pl-12\">\n                <div\n                  className={`absolute left-0 w-8 h-8 text-background rounded-full flex items-center justify-center text-sm ${\n                    !createdApiKey ? 'bg-secondary' : 'bg-muted-foreground'\n                  }`}\n                >\n                  3\n                </div>\n                <div className={!createdApiKey ? 'opacity-40 pointer-events-none' : ''}>\n                  <h2 className=\"text-xl font-semibold mb-4\">Create a Sandbox</h2>\n                  <p className=\"mb-4\">The example below will create a Sandbox and run a simple code snippet:</p>\n                  <div className=\"transition-all duration-500\">\n                    <CodeBlock\n                      code={\n                        createdApiKey && isApiKeyRevealed\n                          ? codeExamples[language].example.replace('your-api-key', createdApiKey.value)\n                          : codeExamples[language].example\n                      }\n                      language={language}\n                      showCopy\n                    />\n                  </div>\n                </div>\n              </div>\n\n              {/* Step 4 */}\n              <div className=\"relative pl-12\">\n                <div\n                  className={`absolute left-0 w-8 h-8 text-background rounded-full flex items-center justify-center text-sm ${\n                    !createdApiKey ? 'bg-secondary' : 'bg-muted-foreground'\n                  }`}\n                >\n                  4\n                </div>\n                <div className={!createdApiKey ? 'opacity-40 pointer-events-none' : ''}>\n                  <h2 className=\"text-xl font-semibold mb-4\">Run the Example</h2>\n                  <p className=\"mb-4\">Run the following command in your terminal to run the example:</p>\n                  <div className=\"transition-all duration-500\">\n                    <CodeBlock code={codeExamples[language].run} language=\"bash\" showCopy />\n                  </div>\n                </div>\n              </div>\n\n              {/* Step 5 */}\n              <div className=\"relative pl-12\">\n                <div\n                  className={`absolute left-0 w-8 h-8 text-background rounded-full flex items-center justify-center text-sm ${\n                    !createdApiKey ? 'bg-secondary' : 'bg-muted-foreground'\n                  }`}\n                >\n                  5\n                </div>\n                <div className={!createdApiKey ? 'opacity-40 pointer-events-none' : ''}>\n                  <h2 className=\"text-xl font-semibold mb-4\">That's It</h2>\n                  <p className=\"text-muted-foreground\">\n                    It's as easy as that. For more examples check out the{' '}\n                    <a href={DAYTONA_DOCS_URL} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-primary\">\n                      Docs\n                    </a>\n                    .\n                  </p>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  )\n}\n\nconst codeExamples = {\n  typescript: {\n    install: `npm install @daytonaio/sdk`,\n    run: `npx tsx index.mts`,\n    example: `import { Daytona } from '@daytonaio/sdk'\n  \n// Initialize the Daytona client\nconst daytona = new Daytona({ apiKey: 'your-api-key' });\n\n// Create the Sandbox instance\nconst sandbox = await daytona.create({\n  language: 'typescript',\n});\n\n// Run the code securely inside the Sandbox\nconst response = await sandbox.process.codeRun('console.log(\"Hello World from code!\")')\nconsole.log(response.result);\n  `,\n  },\n  python: {\n    install: `pip install daytona`,\n    run: `python main.py`,\n    example: `from daytona import Daytona, DaytonaConfig\n  \n# Define the configuration\nconfig = DaytonaConfig(api_key=\"your-api-key\")\n\n# Initialize the Daytona client\ndaytona = Daytona(config)\n\n# Create the Sandbox instance\nsandbox = daytona.create()\n\n# Run the code securely inside the Sandbox\nresponse = sandbox.process.code_run('print(\"Hello World from code!\")')\nif response.exit_code != 0:\n  print(f\"Error: {response.exit_code} {response.result}\")\nelse:\n    print(response.result)\n  `,\n  },\n}\n\nexport default Onboarding\n"
  },
  {
    "path": "apps/dashboard/src/pages/OrganizationMembers.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CreateOrganizationInvitationDialog } from '@/components/OrganizationMembers/CreateOrganizationInvitationDialog'\nimport { OrganizationInvitationTable } from '@/components/OrganizationMembers/OrganizationInvitationTable'\nimport { OrganizationMemberTable } from '@/components/OrganizationMembers/OrganizationMemberTable'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { useApi } from '@/hooks/useApi'\nimport { useOrganizationRoles } from '@/hooks/useOrganizationRoles'\nimport { useOrganizations } from '@/hooks/useOrganizations'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport {\n  CreateOrganizationInvitationRoleEnum,\n  OrganizationInvitation,\n  OrganizationUserRoleEnum,\n  UpdateOrganizationInvitationRoleEnum,\n} from '@daytonaio/api-client'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { toast } from 'sonner'\n\nconst OrganizationMembers: React.FC = () => {\n  const { user } = useAuth()\n  const { organizationsApi } = useApi()\n\n  const { refreshOrganizations } = useOrganizations()\n  const { selectedOrganization, organizationMembers, refreshOrganizationMembers, authenticatedUserOrganizationMember } =\n    useSelectedOrganization()\n  const { roles, loadingRoles } = useOrganizationRoles()\n\n  const [invitations, setInvitations] = useState<OrganizationInvitation[]>([])\n  const [loadingInvitations, setLoadingInvitations] = useState(true)\n\n  const [loadingMemberAction, setLoadingMemberAction] = useState<Record<string, boolean>>({})\n  const [loadingInvitationAction, setLoadingInvitationAction] = useState<Record<string, boolean>>({})\n\n  const fetchInvitations = useCallback(\n    async (showTableLoadingState = true) => {\n      if (!selectedOrganization) {\n        return\n      }\n      if (showTableLoadingState) {\n        setLoadingInvitations(true)\n      }\n      try {\n        const response = await organizationsApi.listOrganizationInvitations(selectedOrganization.id)\n        setInvitations(response.data)\n      } catch (error) {\n        handleApiError(error, 'Failed to fetch invitations')\n      } finally {\n        setLoadingInvitations(false)\n      }\n    },\n    [organizationsApi, selectedOrganization],\n  )\n\n  useEffect(() => {\n    refreshOrganizationMembers()\n    fetchInvitations()\n  }, [fetchInvitations, refreshOrganizationMembers])\n\n  const handleUpdateMemberAccess = async (\n    userId: string,\n    role: OrganizationUserRoleEnum,\n    assignedRoleIds: string[],\n  ): Promise<boolean> => {\n    if (!selectedOrganization) {\n      return false\n    }\n    setLoadingMemberAction((prev) => ({ ...prev, [userId]: true }))\n    try {\n      await organizationsApi.updateAccessForOrganizationMember(selectedOrganization.id, userId, {\n        role,\n        assignedRoleIds,\n      })\n      toast.success('Access updated successfully')\n      await refreshOrganizationMembers()\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to update access')\n      return false\n    } finally {\n      setLoadingMemberAction((prev) => ({ ...prev, [userId]: false }))\n    }\n  }\n\n  const handleRemoveMember = async (userId: string): Promise<boolean> => {\n    if (!selectedOrganization) {\n      return false\n    }\n    setLoadingMemberAction((prev) => ({ ...prev, [userId]: true }))\n    try {\n      await organizationsApi.deleteOrganizationMember(selectedOrganization.id, userId)\n      toast.success('Member removed successfully')\n      if (userId === user?.profile.sub) {\n        await refreshOrganizations()\n      } else {\n        await refreshOrganizationMembers()\n      }\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to remove member')\n      return false\n    } finally {\n      setLoadingMemberAction((prev) => ({ ...prev, [userId]: false }))\n    }\n  }\n\n  const handleCreateInvitation = async (\n    email: string,\n    role: CreateOrganizationInvitationRoleEnum,\n    assignedRoleIds: string[],\n  ): Promise<boolean> => {\n    if (!selectedOrganization) {\n      return false\n    }\n    try {\n      await organizationsApi.createOrganizationInvitation(selectedOrganization.id, { email, role, assignedRoleIds })\n      toast.success('Invitation created successfully')\n      await fetchInvitations(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to create invitation')\n      return false\n    }\n  }\n\n  const handleUpdateInvitation = async (\n    invitationId: string,\n    role: UpdateOrganizationInvitationRoleEnum,\n    assignedRoleIds: string[],\n  ): Promise<boolean> => {\n    if (!selectedOrganization) {\n      return false\n    }\n    setLoadingInvitationAction((prev) => ({ ...prev, [invitationId]: true }))\n    try {\n      await organizationsApi.updateOrganizationInvitation(selectedOrganization.id, invitationId, {\n        role,\n        assignedRoleIds,\n      })\n      toast.success('Invitation updated successfully')\n      await fetchInvitations(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to update invitation')\n      return false\n    } finally {\n      setLoadingInvitationAction((prev) => ({ ...prev, [invitationId]: false }))\n    }\n  }\n\n  const handleCancelInvitation = async (invitationId: string): Promise<boolean> => {\n    if (!selectedOrganization) {\n      return false\n    }\n    setLoadingInvitationAction((prev) => ({ ...prev, [invitationId]: true }))\n    try {\n      await organizationsApi.cancelOrganizationInvitation(selectedOrganization.id, invitationId)\n      toast.success('Invitation cancelled successfully')\n      await fetchInvitations(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to cancel invitation')\n      return false\n    } finally {\n      setLoadingInvitationAction((prev) => ({ ...prev, [invitationId]: false }))\n    }\n  }\n\n  const authenticatedUserIsOwner = useMemo(() => {\n    return authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER\n  }, [authenticatedUserOrganizationMember])\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Members</PageTitle>\n        {authenticatedUserIsOwner && (\n          <CreateOrganizationInvitationDialog\n            className=\"ml-auto\"\n            availableRoles={roles}\n            loadingAvailableRoles={loadingRoles}\n            onCreateInvitation={handleCreateInvitation}\n          />\n        )}\n      </PageHeader>\n\n      <PageContent>\n        <OrganizationMemberTable\n          data={organizationMembers}\n          loadingData={loadingRoles}\n          availableAssignments={roles}\n          loadingAvailableAssignments={loadingRoles}\n          onUpdateMemberAccess={handleUpdateMemberAccess}\n          onRemoveMember={handleRemoveMember}\n          loadingMemberAction={loadingMemberAction}\n          ownerMode={authenticatedUserIsOwner}\n        />\n\n        {authenticatedUserIsOwner && (\n          <>\n            <div className=\"mb-2 mt-12 h-12 flex items-center justify-between\">\n              <h1 className=\"text-2xl font-medium\">Invitations</h1>\n            </div>\n\n            <OrganizationInvitationTable\n              data={invitations}\n              loadingData={loadingInvitations}\n              availableRoles={roles}\n              loadingAvailableRoles={loadingRoles}\n              onCancelInvitation={handleCancelInvitation}\n              onUpdateInvitation={handleUpdateInvitation}\n              loadingInvitationAction={loadingInvitationAction}\n            />\n          </>\n        )}\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default OrganizationMembers\n"
  },
  {
    "path": "apps/dashboard/src/pages/OrganizationRoles.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CreateOrganizationRoleDialog } from '@/components/OrganizationRoles/CreateOrganizationRoleDialog'\nimport { OrganizationRoleTable } from '@/components/OrganizationRoles/OrganizationRoleTable'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { useApi } from '@/hooks/useApi'\nimport { useOrganizationRoles } from '@/hooks/useOrganizationRoles'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { OrganizationRolePermissionsEnum } from '@daytonaio/api-client'\nimport React, { useState } from 'react'\nimport { toast } from 'sonner'\n\nconst OrganizationRoles: React.FC = () => {\n  const { organizationsApi } = useApi()\n\n  const { selectedOrganization } = useSelectedOrganization()\n  const { roles, loadingRoles, refreshRoles } = useOrganizationRoles()\n\n  const [loadingRoleAction, setLoadingRoleAction] = useState<Record<string, boolean>>({})\n\n  const handleCreateRole = async (\n    name: string,\n    description: string,\n    permissions: OrganizationRolePermissionsEnum[],\n  ): Promise<boolean> => {\n    if (!selectedOrganization) {\n      return false\n    }\n    try {\n      await organizationsApi.createOrganizationRole(selectedOrganization.id, {\n        name: name.trim(),\n        description: description?.trim(),\n        permissions,\n      })\n      toast.success('Role created successfully')\n      await refreshRoles(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to create role')\n      return false\n    }\n  }\n\n  const handleUpdateRole = async (\n    roleId: string,\n    name: string,\n    description: string,\n    permissions: OrganizationRolePermissionsEnum[],\n  ): Promise<boolean> => {\n    if (!selectedOrganization) {\n      return false\n    }\n    setLoadingRoleAction((prev) => ({ ...prev, [roleId]: true }))\n    try {\n      await organizationsApi.updateOrganizationRole(selectedOrganization.id, roleId, {\n        name: name.trim(),\n        description: description?.trim(),\n        permissions,\n      })\n      toast.success('Role updated successfully')\n      await refreshRoles(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to update role')\n      return false\n    } finally {\n      setLoadingRoleAction((prev) => ({ ...prev, [roleId]: false }))\n    }\n  }\n\n  const handleDeleteRole = async (roleId: string): Promise<boolean> => {\n    if (!selectedOrganization) {\n      return false\n    }\n    setLoadingRoleAction((prev) => ({ ...prev, [roleId]: true }))\n    try {\n      await organizationsApi.deleteOrganizationRole(selectedOrganization.id, roleId)\n      toast.success('Role deleted successfully')\n      await refreshRoles(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to delete role')\n      return false\n    } finally {\n      setLoadingRoleAction((prev) => ({ ...prev, [roleId]: false }))\n    }\n  }\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Roles</PageTitle>\n        <CreateOrganizationRoleDialog className=\"ml-auto\" onCreateRole={handleCreateRole} />\n      </PageHeader>\n\n      <PageContent>\n        <OrganizationRoleTable\n          data={roles}\n          loadingData={loadingRoles}\n          onUpdateRole={handleUpdateRole}\n          onDeleteRole={handleDeleteRole}\n          loadingRoleAction={loadingRoleAction}\n        />\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default OrganizationRoles\n"
  },
  {
    "path": "apps/dashboard/src/pages/OrganizationSettings.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DeleteOrganizationDialog } from '@/components/Organizations/DeleteOrganizationDialog'\nimport { LeaveOrganizationDialog } from '@/components/Organizations/LeaveOrganizationDialog'\nimport { SetDefaultRegionDialog } from '@/components/Organizations/SetDefaultRegionDialog'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Field, FieldContent, FieldDescription, FieldLabel } from '@/components/ui/field'\nimport { Input } from '@/components/ui/input'\nimport { InputGroup, InputGroupButton, InputGroupInput } from '@/components/ui/input-group'\nimport { useDeleteOrganizationMutation } from '@/hooks/mutations/useDeleteOrganizationMutation'\nimport { useLeaveOrganizationMutation } from '@/hooks/mutations/useLeaveOrganizationMutation'\nimport { useSetOrganizationDefaultRegionMutation } from '@/hooks/mutations/useSetOrganizationDefaultRegionMutation'\nimport { useOrganizations } from '@/hooks/useOrganizations'\nimport { useRegions } from '@/hooks/useRegions'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport { CheckIcon, CopyIcon } from 'lucide-react'\nimport React, { useEffect, useState } from 'react'\nimport { toast } from 'sonner'\nimport { useCopyToClipboard } from 'usehooks-ts'\n\nconst OrganizationSettings: React.FC = () => {\n  const { refreshOrganizations } = useOrganizations()\n  const { selectedOrganization, authenticatedUserOrganizationMember } = useSelectedOrganization()\n  const { getRegionName, sharedRegions: regions, loadingSharedRegions: loadingRegions } = useRegions()\n\n  const deleteOrganizationMutation = useDeleteOrganizationMutation()\n  const leaveOrganizationMutation = useLeaveOrganizationMutation()\n  const setDefaultRegionMutation = useSetOrganizationDefaultRegionMutation()\n  const [showSetDefaultRegionDialog, setSetDefaultRegionDialog] = useState(false)\n  const [copied, copyToClipboard] = useCopyToClipboard()\n\n  useEffect(() => {\n    if (selectedOrganization && !selectedOrganization.defaultRegionId) {\n      setSetDefaultRegionDialog(true)\n    }\n  }, [selectedOrganization])\n\n  if (!selectedOrganization) {\n    return null\n  }\n\n  const handleSetDefaultRegion = async (defaultRegionId: string): Promise<boolean> => {\n    try {\n      await setDefaultRegionMutation.mutateAsync({\n        organizationId: selectedOrganization.id,\n        defaultRegionId,\n      })\n      toast.success('Default region set successfully')\n      await refreshOrganizations(selectedOrganization.id)\n      setSetDefaultRegionDialog(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to set default region')\n      return false\n    }\n  }\n\n  const handleDeleteOrganization = async () => {\n    try {\n      await deleteOrganizationMutation.mutateAsync({ organizationId: selectedOrganization.id })\n      toast.success('Organization deleted successfully')\n      await refreshOrganizations()\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to delete organization')\n      return false\n    }\n  }\n\n  const handleLeaveOrganization = async () => {\n    try {\n      await leaveOrganizationMutation.mutateAsync({ organizationId: selectedOrganization.id })\n      toast.success('Organization left successfully')\n      await refreshOrganizations()\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to leave organization')\n      return false\n    }\n  }\n\n  const isOwner = authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Settings</PageTitle>\n      </PageHeader>\n\n      <PageContent>\n        <Card>\n          <CardHeader className=\"p-4\">\n            <CardTitle>Organization Details</CardTitle>\n          </CardHeader>\n          <CardContent className=\"border-t border-border\">\n            <Field className=\"grid sm:grid-cols-2 items-center\">\n              <FieldContent className=\"flex-1\">\n                <FieldLabel htmlFor=\"organization-name\">Organization Name</FieldLabel>\n                <FieldDescription>The public name of your organization.</FieldDescription>\n              </FieldContent>\n\n              <Input id=\"organization-name\" value={selectedOrganization.name} readOnly className=\"flex-1\" />\n            </Field>\n          </CardContent>\n\n          <CardContent className=\"border-t border-border\">\n            <Field className=\"grid sm:grid-cols-2 items-center\">\n              <FieldContent className=\"flex-1\">\n                <FieldLabel htmlFor=\"organization-id\">Organization ID</FieldLabel>\n                <FieldDescription>\n                  The unique identifier of your organization.\n                  <br />\n                  Used in CLI and API calls.\n                </FieldDescription>\n              </FieldContent>\n              <InputGroup className=\"pr-1 flex-1\">\n                <InputGroupInput id=\"organization-id\" value={selectedOrganization.id} readOnly />\n                <InputGroupButton\n                  variant=\"ghost\"\n                  size=\"icon-xs\"\n                  onClick={() =>\n                    copyToClipboard(selectedOrganization.id).then(() => toast.success('Copied to clipboard'))\n                  }\n                >\n                  {copied ? <CheckIcon className=\"h-4 w-4\" /> : <CopyIcon className=\"h-4 w-4\" />}\n                </InputGroupButton>\n              </InputGroup>\n            </Field>\n          </CardContent>\n          <CardContent className=\"border-t border-border\">\n            <Field className=\"grid sm:grid-cols-2 items-center\">\n              <FieldContent className=\"flex-1\">\n                <FieldLabel htmlFor=\"organization-default-region\">Default Region</FieldLabel>\n                <FieldDescription>The default target for creating sandboxes in this organization.</FieldDescription>\n              </FieldContent>\n              {selectedOrganization.defaultRegionId ? (\n                <Input\n                  id=\"organization-default-region\"\n                  value={getRegionName(selectedOrganization.defaultRegionId) ?? selectedOrganization.defaultRegionId}\n                  readOnly\n                  className=\"flex-1 uppercase\"\n                />\n              ) : isOwner ? (\n                <div className=\"flex sm:justify-end\">\n                  <Button onClick={() => setSetDefaultRegionDialog(true)} variant=\"secondary\">\n                    Set Region\n                  </Button>\n                </div>\n              ) : null}\n            </Field>\n          </CardContent>\n        </Card>\n\n        {!selectedOrganization.personal && authenticatedUserOrganizationMember !== null && (\n          <Card className=\"bg-destructive-background border-destructive-separator\">\n            <CardContent>\n              <div className=\"flex sm:flex-row flex-col justify-between sm:items-center gap-2\">\n                <div className=\"text-sm\">\n                  <div className=\"text-muted-foreground\">\n                    <p className=\"font-semibold text-destructive-foreground\">Danger Zone</p>\n                    {isOwner ? (\n                      <>Delete the organization and all associated data.</>\n                    ) : (\n                      <>Remove yourself from the organization.</>\n                    )}\n                  </div>\n                </div>\n                {isOwner ? (\n                  <DeleteOrganizationDialog\n                    organizationName={selectedOrganization.name}\n                    onDeleteOrganization={handleDeleteOrganization}\n                    loading={deleteOrganizationMutation.isPending}\n                  />\n                ) : (\n                  <LeaveOrganizationDialog\n                    onLeaveOrganization={handleLeaveOrganization}\n                    loading={leaveOrganizationMutation.isPending}\n                  />\n                )}\n              </div>\n            </CardContent>\n          </Card>\n        )}\n        <SetDefaultRegionDialog\n          open={showSetDefaultRegionDialog}\n          onOpenChange={setSetDefaultRegionDialog}\n          regions={regions}\n          loadingRegions={loadingRegions}\n          onSetDefaultRegion={handleSetDefaultRegion}\n        />\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default OrganizationSettings\n"
  },
  {
    "path": "apps/dashboard/src/pages/Playground.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport {\n  PlaygroundLayout,\n  PlaygroundLayoutContent,\n  PlaygroundLayoutSidebar,\n} from '@/components/Playground/PlaygroundLayout'\nimport SandboxCodeSnippetsResponse from '@/components/Playground/Sandbox/CodeSnippetsResponse'\nimport SandboxParameters from '@/components/Playground/Sandbox/Parameters'\nimport TerminalDescription from '@/components/Playground/Terminal/Description'\nimport WebTerminal from '@/components/Playground/Terminal/WebTerminal'\nimport VNCDesktopWindowResponse from '@/components/Playground/VNC/DesktopWindowResponse'\nimport VNCInteractionOptions from '@/components/Playground/VNC/Interaction'\nimport { Button } from '@/components/ui/button'\nimport { Drawer, DrawerContent } from '@/components/ui/drawer'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport { PlaygroundCategories } from '@/enums/Playground'\nimport { PlaygroundProvider } from '@/providers/PlaygroundProvider'\nimport { PlaygroundSandboxProvider } from '@/providers/PlaygroundSandboxProvider'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { SettingsIcon } from 'lucide-react'\nimport { useEffect, useMemo, useRef, useState } from 'react'\nimport { useResizeObserver } from 'usehooks-ts'\n\nconst playgroundCategoriesData = [\n  { value: PlaygroundCategories.SANDBOX, label: 'Sandbox' },\n  { value: PlaygroundCategories.TERMINAL, label: 'Terminal' },\n  { value: PlaygroundCategories.VNC, label: 'VNC' },\n]\n\nconst SlideLeftRight = ({ children, direction }: { children: React.ReactNode; direction: 'left' | 'right' }) => {\n  return (\n    <motion.div\n      initial={{ opacity: 0, filter: 'blur(2px)', x: direction === 'left' ? -20 : 20 }}\n      animate={{ opacity: 1, filter: 'blur(0px)', x: 0 }}\n      exit={{ opacity: 0, filter: 'blur(2px)', x: direction === 'left' ? 20 : -20 }}\n      transition={{ duration: 0.2 }}\n    >\n      {children}\n    </motion.div>\n  )\n}\n\nconst Playground: React.FC = () => {\n  const [playgroundCategory, setPlaygroundCategory] = useState<PlaygroundCategories>(PlaygroundCategories.SANDBOX)\n\n  const [drawerOpen, setDrawerOpen] = useState<PlaygroundCategories | null>(null)\n  const handleDrawerOpenChange = (open: boolean) => {\n    if (!open) {\n      setDrawerOpen(null)\n    }\n  }\n\n  const pageContentRef = useRef<HTMLDivElement>(null)\n\n  useResizeObserver({\n    ref: pageContentRef as React.RefObject<HTMLElement>,\n    onResize: () => {\n      if (pageContentRef.current) {\n        const { width } = pageContentRef.current.getBoundingClientRect()\n        if (width < 1024) {\n          setDrawerOpen(null)\n        }\n      }\n    },\n  })\n\n  const prevCategory = useRef<PlaygroundCategories>(playgroundCategory)\n  useEffect(() => {\n    prevCategory.current = playgroundCategory\n  }, [playgroundCategory])\n\n  const direction = useMemo(() => {\n    const currentIndex = playgroundCategoriesData.findIndex((category) => category.value === playgroundCategory)\n    const prevIndex = playgroundCategoriesData.findIndex((category) => category.value === prevCategory.current)\n    return currentIndex > prevIndex ? 'right' : 'left'\n  }, [playgroundCategory])\n\n  const sidePanel = useMemo(() => {\n    if (playgroundCategory === PlaygroundCategories.SANDBOX) return <SandboxParameters />\n    if (playgroundCategory === PlaygroundCategories.TERMINAL) return <TerminalDescription />\n    if (playgroundCategory === PlaygroundCategories.VNC) return <VNCInteractionOptions />\n    return null\n  }, [playgroundCategory])\n\n  return (\n    <PageLayout className=\"max-h-[100vh] overflow-auto\">\n      <PageHeader>\n        <PageTitle>Playground</PageTitle>\n      </PageHeader>\n\n      <PageContent size=\"full\" className=\"!p-0 h-full flex flex-col flex-1 overflow-auto\" ref={pageContentRef}>\n        <PlaygroundProvider>\n          <PlaygroundSandboxProvider activeTab={playgroundCategory}>\n            <Tabs\n              value={playgroundCategory}\n              onValueChange={(value) => setPlaygroundCategory(value as PlaygroundCategories)}\n              className=\"h-full gap-0\"\n            >\n              <div className=\"flex items-center justify-between shadow-[inset_0_-1px] shadow-border pr-4\">\n                <TabsList className=\"px-2 shadow-none bg-transparent w-auto pb-0\">\n                  {playgroundCategoriesData.map((category) => (\n                    <TabsTrigger\n                      value={category.value}\n                      key={category.value}\n                      className=\"data-[state=inactive]:border-b-transparent data-[state=active]:border-b-foreground border-b rounded-none !shadow-none -mb-0.5 pb-1.5\"\n                    >\n                      {category.label}\n                    </TabsTrigger>\n                  ))}\n                </TabsList>\n                <Button\n                  onClick={() => setDrawerOpen(playgroundCategory)}\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"lg:hidden\"\n                >\n                  <SettingsIcon className=\"size-4 mr-2\" /> Configure\n                </Button>\n              </div>\n              <TabsContent\n                value={playgroundCategory}\n                key={playgroundCategory}\n                className=\"mt-0 data-[state=inactive]:hidden\"\n                asChild\n              >\n                <PlaygroundLayout className=\"overflow-auto\">\n                  <PlaygroundLayoutSidebar>\n                    <AnimatePresence mode=\"popLayout\">\n                      <SlideLeftRight direction={direction} key={playgroundCategory}>\n                        {sidePanel}\n                      </SlideLeftRight>\n                    </AnimatePresence>\n                  </PlaygroundLayoutSidebar>\n\n                  <Drawer open={drawerOpen === playgroundCategory} onOpenChange={handleDrawerOpenChange}>\n                    <DrawerContent>\n                      <div className=\"p-4 overflow-auto\">{sidePanel}</div>\n                    </DrawerContent>\n                  </Drawer>\n                  <PlaygroundLayoutContent className=\"[&>*]:w-full [&>*]:max-w-[min(90%,1024px)]\">\n                    {playgroundCategory === PlaygroundCategories.SANDBOX && <SandboxCodeSnippetsResponse />}\n                    {playgroundCategory === PlaygroundCategories.TERMINAL && <WebTerminal />}\n                    {playgroundCategory === PlaygroundCategories.VNC && <VNCDesktopWindowResponse />}\n                  </PlaygroundLayoutContent>\n                </PlaygroundLayout>\n              </TabsContent>\n            </Tabs>\n          </PlaygroundSandboxProvider>\n        </PlaygroundProvider>\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default Playground\n"
  },
  {
    "path": "apps/dashboard/src/pages/Regions.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useMemo, useState } from 'react'\nimport { useApi } from '@/hooks/useApi'\nimport {\n  Region,\n  OrganizationRolePermissionsEnum,\n  CreateRegion,\n  CreateRegionResponse,\n  SnapshotManagerCredentials,\n  UpdateRegion,\n} from '@daytonaio/api-client'\nimport { RegionTable } from '@/components/RegionTable'\nimport { CreateRegionDialog } from '@/components/CreateRegionDialog'\nimport { UpdateRegionDialog } from '@/components/UpdateRegionDialog'\nimport RegionDetailsSheet from '@/components/RegionDetailsSheet'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from '@/components/ui/alert-dialog'\nimport { Button } from '@/components/ui/button'\nimport { toast } from 'sonner'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { useRegions } from '@/hooks/useRegions'\nimport { getMaskedToken } from '@/lib/utils'\nimport { Copy } from 'lucide-react'\n\nconst Regions: React.FC = () => {\n  const { organizationsApi } = useApi()\n  const { selectedOrganization, authenticatedUserHasPermission } = useSelectedOrganization()\n  const {\n    availableRegions: regions,\n    loadingAvailableRegions: loadingRegions,\n    refreshAvailableRegions: refreshRegions,\n  } = useRegions()\n\n  const [regionIsLoading, setRegionIsLoading] = useState<Record<string, boolean>>({})\n\n  const [regionToDelete, setRegionToDelete] = useState<Region | null>(null)\n  const [deleteRegionDialogIsOpen, setDeleteRegionDialogIsOpen] = useState(false)\n\n  // Regenerate API Key state\n  const [showRegenerateProxyApiKeyDialog, setShowRegenerateProxyApiKeyDialog] = useState(false)\n  const [showRegenerateSshGatewayApiKeyDialog, setShowRegenerateSshGatewayApiKeyDialog] = useState(false)\n  const [showRegenerateSnapshotManagerCredsDialog, setShowRegenerateSnapshotManagerCredsDialog] = useState(false)\n  const [regeneratedApiKey, setRegeneratedApiKey] = useState<string | null>(null)\n  const [regeneratedSnapshotManagerCreds, setRegeneratedSnapshotManagerCreds] =\n    useState<SnapshotManagerCredentials | null>(null)\n  const [regionForRegenerate, setRegionForRegenerate] = useState<Region | null>(null)\n  const [copied, setCopied] = useState(false)\n  const [isApiKeyRevealed, setIsApiKeyRevealed] = useState(false)\n  const [isSnapshotManagerPasswordRevealed, setIsSnapshotManagerPasswordRevealed] = useState(false)\n\n  // Region Details Sheet state\n  const [selectedRegion, setSelectedRegion] = useState<Region | null>(null)\n  const [showRegionDetails, setShowRegionDetails] = useState(false)\n\n  // Update Region Dialog state\n  const [showUpdateRegionDialog, setShowUpdateRegionDialog] = useState(false)\n  const [regionToUpdate, setRegionToUpdate] = useState<Region | null>(null)\n\n  const handleCreateRegion = async (createRegionData: CreateRegion): Promise<CreateRegionResponse | null> => {\n    if (!selectedOrganization) {\n      return null\n    }\n\n    try {\n      const response = (await organizationsApi.createRegion(createRegionData, selectedOrganization.id)).data\n      toast.success(`Creating region ${createRegionData.name}`)\n      await refreshRegions()\n      return response\n    } catch (error) {\n      handleApiError(error, 'Failed to create region')\n      return null\n    }\n  }\n\n  const handleDelete = async (region: Region) => {\n    if (!selectedOrganization) {\n      return\n    }\n\n    setRegionIsLoading((prev) => ({ ...prev, [region.id]: true }))\n\n    try {\n      await organizationsApi.deleteRegion(region.id, selectedOrganization.id)\n      setRegionToDelete(null)\n      setDeleteRegionDialogIsOpen(false)\n      toast.success(`Deleting region ${region.name}`)\n      await refreshRegions()\n    } catch (error) {\n      handleApiError(error, 'Failed to delete region')\n    } finally {\n      setRegionIsLoading((prev) => ({ ...prev, [region.id]: false }))\n    }\n  }\n\n  const writePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_REGIONS),\n    [authenticatedUserHasPermission],\n  )\n\n  const deletePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.DELETE_REGIONS),\n    [authenticatedUserHasPermission],\n  )\n\n  const handleRegenerateProxyApiKey = async (region: Region) => {\n    setRegionForRegenerate(region)\n    setRegeneratedApiKey(null)\n    setShowRegenerateProxyApiKeyDialog(true)\n  }\n\n  const handleRegenerateSshGatewayApiKey = async (region: Region) => {\n    setRegionForRegenerate(region)\n    setRegeneratedApiKey(null)\n    setShowRegenerateSshGatewayApiKeyDialog(true)\n  }\n\n  const handleRegenerateSnapshotManagerCredentials = async (region: Region) => {\n    setRegionForRegenerate(region)\n    setRegeneratedSnapshotManagerCreds(null)\n    setShowRegenerateSnapshotManagerCredsDialog(true)\n  }\n\n  const handleOpenRegionDetails = (region: Region) => {\n    setSelectedRegion(region)\n    setShowRegionDetails(true)\n  }\n\n  const handleUpdateRegion = async (regionId: string, updateData: UpdateRegion): Promise<boolean> => {\n    if (!selectedOrganization) return false\n\n    setRegionIsLoading((prev) => ({ ...prev, [regionId]: true }))\n    try {\n      await organizationsApi.updateRegion(regionId, updateData, selectedOrganization.id)\n      toast.success('Region updated successfully')\n      await refreshRegions()\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to update region')\n      return false\n    } finally {\n      setRegionIsLoading((prev) => ({ ...prev, [regionId]: false }))\n    }\n  }\n\n  const handleOpenUpdateDialog = (region: Region) => {\n    setRegionToUpdate(region)\n    setShowUpdateRegionDialog(true)\n    setShowRegionDetails(false)\n  }\n\n  const confirmRegenerateProxyApiKey = async () => {\n    if (!regionForRegenerate || !selectedOrganization) {\n      return\n    }\n\n    setRegionIsLoading((prev) => ({ ...prev, [regionForRegenerate.id]: true }))\n\n    try {\n      const response = await organizationsApi.regenerateProxyApiKey(regionForRegenerate.id, selectedOrganization.id)\n      setRegeneratedApiKey(response.data.apiKey)\n      setShowRegenerateProxyApiKeyDialog(true)\n      toast.success('Proxy API key regenerated successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to regenerate proxy API key')\n      setShowRegenerateProxyApiKeyDialog(false)\n      setRegionForRegenerate(null)\n    } finally {\n      setRegionIsLoading((prev) => ({ ...prev, [regionForRegenerate.id]: false }))\n    }\n  }\n\n  const confirmRegenerateSshGatewayApiKey = async () => {\n    if (!regionForRegenerate || !selectedOrganization) {\n      return\n    }\n\n    setRegionIsLoading((prev) => ({ ...prev, [regionForRegenerate.id]: true }))\n\n    try {\n      const response = await organizationsApi.regenerateSshGatewayApiKey(\n        regionForRegenerate.id,\n        selectedOrganization.id,\n      )\n      setRegeneratedApiKey(response.data.apiKey)\n      setShowRegenerateSshGatewayApiKeyDialog(true)\n      toast.success('SSH Gateway API key regenerated successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to regenerate SSH Gateway API key')\n      setShowRegenerateSshGatewayApiKeyDialog(false)\n      setRegionForRegenerate(null)\n    } finally {\n      setRegionIsLoading((prev) => ({ ...prev, [regionForRegenerate.id]: false }))\n    }\n  }\n\n  const confirmRegenerateSnapshotManagerCredentials = async () => {\n    if (!regionForRegenerate || !selectedOrganization) {\n      return\n    }\n\n    setRegionIsLoading((prev) => ({ ...prev, [regionForRegenerate.id]: true }))\n\n    try {\n      const response = await organizationsApi.regenerateSnapshotManagerCredentials(\n        regionForRegenerate.id,\n        selectedOrganization.id,\n      )\n      setRegeneratedSnapshotManagerCreds(response.data)\n      setShowRegenerateSnapshotManagerCredsDialog(true)\n      toast.success('Snapshot Manager credentials regenerated successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to regenerate Snapshot Manager credentials')\n      setShowRegenerateSnapshotManagerCredsDialog(false)\n      setRegionForRegenerate(null)\n    } finally {\n      setRegionIsLoading((prev) => ({ ...prev, [regionForRegenerate.id]: false }))\n    }\n  }\n\n  const copyToClipboard = async (text: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      setCopied(true)\n      setTimeout(() => setCopied(false), 2000)\n      toast.success('Copied to clipboard')\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n      toast.error('Failed to copy to clipboard')\n    }\n  }\n\n  return (\n    <div className=\"px-6 py-2\">\n      <div className=\"mb-2 h-12 flex items-center justify-between\">\n        <h1 className=\"text-2xl font-medium\">Regions</h1>\n        <CreateRegionDialog\n          onCreateRegion={handleCreateRegion}\n          writePermitted={writePermitted}\n          loadingData={loadingRegions}\n        />\n      </div>\n\n      <RegionTable\n        data={regions}\n        loading={loadingRegions}\n        isLoadingRegion={(region) => regionIsLoading[region.id] || false}\n        deletePermitted={deletePermitted}\n        writePermitted={writePermitted}\n        onDelete={(region) => {\n          setRegionToDelete(region)\n          setDeleteRegionDialogIsOpen(true)\n        }}\n        onOpenDetails={handleOpenRegionDetails}\n      />\n\n      <RegionDetailsSheet\n        region={selectedRegion}\n        open={showRegionDetails}\n        onOpenChange={(open) => {\n          setShowRegionDetails(open)\n          if (!open) {\n            setSelectedRegion(null)\n          }\n        }}\n        regionIsLoading={regionIsLoading}\n        writePermitted={writePermitted}\n        deletePermitted={deletePermitted}\n        onDelete={(region) => {\n          setRegionToDelete(region)\n          setDeleteRegionDialogIsOpen(true)\n          setShowRegionDetails(false)\n        }}\n        onUpdate={handleOpenUpdateDialog}\n        onRegenerateProxyApiKey={handleRegenerateProxyApiKey}\n        onRegenerateSshGatewayApiKey={handleRegenerateSshGatewayApiKey}\n        onRegenerateSnapshotManagerCredentials={handleRegenerateSnapshotManagerCredentials}\n      />\n\n      {regionToUpdate && (\n        <UpdateRegionDialog\n          region={regionToUpdate}\n          open={showUpdateRegionDialog}\n          onOpenChange={(isOpen) => {\n            setShowUpdateRegionDialog(isOpen)\n            if (!isOpen) setRegionToUpdate(null)\n          }}\n          onUpdateRegion={handleUpdateRegion}\n          loading={regionToUpdate ? regionIsLoading[regionToUpdate.id] || false : false}\n        />\n      )}\n\n      {regionToDelete && (\n        <Dialog\n          open={deleteRegionDialogIsOpen}\n          onOpenChange={(isOpen) => {\n            setDeleteRegionDialogIsOpen(isOpen)\n            if (!isOpen) {\n              setRegionToDelete(null)\n            }\n          }}\n        >\n          <DialogContent>\n            <DialogHeader>\n              <DialogTitle>Confirm Region Deletion</DialogTitle>\n              <DialogDescription>\n                Are you sure you want to delete this region? This action cannot be undone.\n              </DialogDescription>\n            </DialogHeader>\n            <DialogFooter>\n              <DialogClose asChild>\n                <Button type=\"button\" variant=\"secondary\">\n                  Cancel\n                </Button>\n              </DialogClose>\n              <Button\n                variant=\"destructive\"\n                onClick={() => handleDelete(regionToDelete)}\n                disabled={regionIsLoading[regionToDelete.id]}\n              >\n                {regionIsLoading[regionToDelete.id] ? 'Deleting...' : 'Delete'}\n              </Button>\n            </DialogFooter>\n          </DialogContent>\n        </Dialog>\n      )}\n\n      {/* Regenerate Proxy API Key Dialog */}\n      <AlertDialog\n        open={showRegenerateProxyApiKeyDialog}\n        onOpenChange={(isOpen) => {\n          setShowRegenerateProxyApiKeyDialog(isOpen)\n          if (!isOpen) {\n            setRegionForRegenerate(null)\n            setRegeneratedApiKey(null)\n            setCopied(false)\n            setIsApiKeyRevealed(false)\n          }\n        }}\n      >\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>\n              {regeneratedApiKey ? 'Proxy API Key Regenerated' : 'Regenerate Proxy API Key'}\n            </AlertDialogTitle>\n            <AlertDialogDescription>\n              {regeneratedApiKey ? (\n                'The new API key has been generated. Copy it now as it will not be shown again.'\n              ) : (\n                <>\n                  <strong>Warning:</strong> This will immediately invalidate the current proxy API key. The proxy will\n                  need to be redeployed with the new API key.\n                </>\n              )}\n              {regeneratedApiKey && (\n                <div className=\"space-y-4 mt-4\">\n                  <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                    <span\n                      className=\"overflow-x-auto pr-2 cursor-text select-all\"\n                      onMouseEnter={() => setIsApiKeyRevealed(true)}\n                      onMouseLeave={() => setIsApiKeyRevealed(false)}\n                    >\n                      {isApiKeyRevealed ? regeneratedApiKey : getMaskedToken(regeneratedApiKey)}\n                    </span>\n                    <Copy\n                      className=\"w-4 h-4 cursor-pointer flex-shrink-0 text-muted-foreground hover:text-foreground transition-colors\"\n                      onClick={() => copyToClipboard(regeneratedApiKey)}\n                    />\n                  </div>\n                </div>\n              )}\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n\n          <AlertDialogFooter>\n            {!regeneratedApiKey ? (\n              <>\n                <AlertDialogCancel>Cancel</AlertDialogCancel>\n                <AlertDialogAction\n                  onClick={confirmRegenerateProxyApiKey}\n                  disabled={!regionForRegenerate || regionIsLoading[regionForRegenerate?.id || '']}\n                  className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n                >\n                  {regionForRegenerate && regionIsLoading[regionForRegenerate.id] ? 'Regenerating...' : 'Regenerate'}\n                </AlertDialogAction>\n              </>\n            ) : (\n              <AlertDialogAction\n                onClick={() => {\n                  setShowRegenerateProxyApiKeyDialog(false)\n                  setRegionForRegenerate(null)\n                  setRegeneratedApiKey(null)\n                  setCopied(false)\n                  setIsApiKeyRevealed(false)\n                }}\n                className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n              >\n                Close\n              </AlertDialogAction>\n            )}\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n\n      {/* Regenerate SSH Gateway API Key Dialog */}\n      <AlertDialog\n        open={showRegenerateSshGatewayApiKeyDialog}\n        onOpenChange={(isOpen) => {\n          setShowRegenerateSshGatewayApiKeyDialog(isOpen)\n          if (!isOpen) {\n            setRegionForRegenerate(null)\n            setRegeneratedApiKey(null)\n            setCopied(false)\n            setIsApiKeyRevealed(false)\n          }\n        }}\n      >\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>\n              {regeneratedApiKey ? 'SSH Gateway API Key Regenerated' : 'Regenerate SSH Gateway API Key'}\n            </AlertDialogTitle>\n            <AlertDialogDescription>\n              {regeneratedApiKey ? (\n                'The new API key has been generated. Copy it now as it will not be shown again.'\n              ) : (\n                <>\n                  <strong>Warning:</strong> This will immediately invalidate the current SSH gateway API key. The SSH\n                  gateway will need to be redeployed with the new API key.\n                </>\n              )}\n              {regeneratedApiKey && (\n                <div className=\"space-y-4 mt-4\">\n                  <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                    <span\n                      className=\"overflow-x-auto pr-2 cursor-text select-all\"\n                      onMouseEnter={() => setIsApiKeyRevealed(true)}\n                      onMouseLeave={() => setIsApiKeyRevealed(false)}\n                    >\n                      {isApiKeyRevealed ? regeneratedApiKey : getMaskedToken(regeneratedApiKey)}\n                    </span>\n                    <Copy\n                      className=\"w-4 h-4 cursor-pointer flex-shrink-0 text-muted-foreground hover:text-foreground transition-colors\"\n                      onClick={() => copyToClipboard(regeneratedApiKey)}\n                    />\n                  </div>\n                </div>\n              )}\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n\n          <AlertDialogFooter>\n            {!regeneratedApiKey ? (\n              <>\n                <AlertDialogCancel>Cancel</AlertDialogCancel>\n                <AlertDialogAction\n                  onClick={confirmRegenerateSshGatewayApiKey}\n                  disabled={!regionForRegenerate || regionIsLoading[regionForRegenerate?.id || '']}\n                  className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n                >\n                  {regionForRegenerate && regionIsLoading[regionForRegenerate.id] ? 'Regenerating...' : 'Regenerate'}\n                </AlertDialogAction>\n              </>\n            ) : (\n              <AlertDialogAction\n                onClick={() => {\n                  setShowRegenerateSshGatewayApiKeyDialog(false)\n                  setRegionForRegenerate(null)\n                  setRegeneratedApiKey(null)\n                  setCopied(false)\n                  setIsApiKeyRevealed(false)\n                }}\n                className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n              >\n                Close\n              </AlertDialogAction>\n            )}\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n\n      {/* Regenerate Snapshot Manager Credentials Dialog */}\n      <AlertDialog\n        open={showRegenerateSnapshotManagerCredsDialog}\n        onOpenChange={(isOpen) => {\n          setShowRegenerateSnapshotManagerCredsDialog(isOpen)\n          if (!isOpen) {\n            setRegionForRegenerate(null)\n            setRegeneratedSnapshotManagerCreds(null)\n            setCopied(false)\n            setIsSnapshotManagerPasswordRevealed(false)\n          }\n        }}\n      >\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>\n              {regeneratedSnapshotManagerCreds\n                ? 'Snapshot Manager Credentials Regenerated'\n                : 'Regenerate Snapshot Manager Credentials'}\n            </AlertDialogTitle>\n            <AlertDialogDescription>\n              {regeneratedSnapshotManagerCreds ? (\n                'The new credentials have been generated. Copy them now as they will not be shown again.'\n              ) : (\n                <>\n                  <strong>Warning:</strong> This will immediately invalidate the current Snapshot Manager credentials.\n                  The Snapshot Manager will need to be reconfigured with the new credentials.\n                </>\n              )}\n              {regeneratedSnapshotManagerCreds && (\n                <div className=\"space-y-4 mt-4\">\n                  <div>\n                    <span className=\"text-xs text-muted-foreground\">Username</span>\n                    <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                      <span className=\"overflow-x-auto pr-2 cursor-text select-all\">\n                        {regeneratedSnapshotManagerCreds.username}\n                      </span>\n                      <Copy\n                        className=\"w-4 h-4 cursor-pointer flex-shrink-0 text-muted-foreground hover:text-foreground transition-colors\"\n                        onClick={() => copyToClipboard(regeneratedSnapshotManagerCreds.username)}\n                      />\n                    </div>\n                  </div>\n                  <div>\n                    <span className=\"text-xs text-muted-foreground\">Password</span>\n                    <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                      <span\n                        className=\"overflow-x-auto pr-2 cursor-text select-all\"\n                        onMouseEnter={() => setIsSnapshotManagerPasswordRevealed(true)}\n                        onMouseLeave={() => setIsSnapshotManagerPasswordRevealed(false)}\n                      >\n                        {isSnapshotManagerPasswordRevealed\n                          ? regeneratedSnapshotManagerCreds.password\n                          : getMaskedToken(regeneratedSnapshotManagerCreds.password)}\n                      </span>\n                      <Copy\n                        className=\"w-4 h-4 cursor-pointer flex-shrink-0 text-muted-foreground hover:text-foreground transition-colors\"\n                        onClick={() => copyToClipboard(regeneratedSnapshotManagerCreds.password)}\n                      />\n                    </div>\n                  </div>\n                </div>\n              )}\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n\n          <AlertDialogFooter>\n            {!regeneratedSnapshotManagerCreds ? (\n              <>\n                <AlertDialogCancel>Cancel</AlertDialogCancel>\n                <AlertDialogAction\n                  onClick={confirmRegenerateSnapshotManagerCredentials}\n                  disabled={!regionForRegenerate || regionIsLoading[regionForRegenerate?.id || '']}\n                  className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n                >\n                  {regionForRegenerate && regionIsLoading[regionForRegenerate.id] ? 'Regenerating...' : 'Regenerate'}\n                </AlertDialogAction>\n              </>\n            ) : (\n              <AlertDialogAction\n                onClick={() => {\n                  setShowRegenerateSnapshotManagerCredsDialog(false)\n                  setRegionForRegenerate(null)\n                  setRegeneratedSnapshotManagerCreds(null)\n                  setCopied(false)\n                  setIsSnapshotManagerPasswordRevealed(false)\n                }}\n                className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n              >\n                Close\n              </AlertDialogAction>\n            )}\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n    </div>\n  )\n}\n\nexport default Regions\n"
  },
  {
    "path": "apps/dashboard/src/pages/Registries.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { RegistryTable } from '@/components/RegistryTable'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'\nimport { useApi } from '@/hooks/useApi'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport {\n  DockerRegistryRegistryTypeEnum,\n  OrganizationRolePermissionsEnum,\n  type DockerRegistry,\n} from '@daytonaio/api-client'\nimport { Info, Plus } from 'lucide-react'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { toast } from 'sonner'\n\nconst Registries: React.FC = () => {\n  const { dockerRegistryApi } = useApi()\n  const [registries, setRegistries] = useState<DockerRegistry[]>([])\n  const [loading, setLoading] = useState(true)\n  const [registryToDelete, setRegistryToDelete] = useState<string | null>(null)\n  const [formData, setFormData] = useState({\n    name: '',\n    url: '',\n    username: '',\n    password: '',\n    project: '',\n  })\n  const [registryToEdit, setRegistryToEdit] = useState<DockerRegistry | null>(null)\n  const [showCreateOrEditDialog, setShowCreateOrEditDialog] = useState(false)\n  const [actionInProgress, setActionInProgress] = useState(false)\n\n  const { selectedOrganization, authenticatedUserHasPermission } = useSelectedOrganization()\n\n  const fetchRegistries = useCallback(\n    async (showTableLoadingState = true) => {\n      if (!selectedOrganization) {\n        return\n      }\n      if (showTableLoadingState) {\n        setLoading(true)\n      }\n      try {\n        const response = await dockerRegistryApi.listRegistries(selectedOrganization.id)\n        setRegistries(response.data)\n      } catch (error) {\n        handleApiError(error, 'Failed to fetch registries')\n      } finally {\n        setLoading(false)\n      }\n    },\n    [dockerRegistryApi, selectedOrganization],\n  )\n\n  useEffect(() => {\n    fetchRegistries()\n  }, [fetchRegistries])\n\n  const handleCreate = async () => {\n    setActionInProgress(true)\n    try {\n      await dockerRegistryApi.createRegistry(\n        {\n          name: formData.name.trim(),\n          url: formData.url.trim() || 'docker.io',\n          username: formData.username.trim(),\n          password: formData.password.trim(),\n          project: formData.project.trim(),\n          registryType: DockerRegistryRegistryTypeEnum.ORGANIZATION,\n        },\n        selectedOrganization?.id,\n      )\n      toast.success('Registry created successfully')\n      await fetchRegistries(false)\n      setShowCreateOrEditDialog(false)\n      setFormData({\n        name: '',\n        url: '',\n        username: '',\n        password: '',\n        project: '',\n      })\n    } catch (error) {\n      handleApiError(error, 'Failed to create registry')\n    } finally {\n      setActionInProgress(false)\n    }\n  }\n\n  const handleEdit = async () => {\n    if (!registryToEdit) return\n\n    setActionInProgress(true)\n    try {\n      await dockerRegistryApi.updateRegistry(\n        registryToEdit.id,\n        {\n          name: formData.name.trim(),\n          url: formData.url.trim() || 'docker.io',\n          username: formData.username.trim(),\n          password: formData.password.trim(),\n          project: formData.project.trim(),\n        },\n        selectedOrganization?.id,\n      )\n      toast.success('Registry edited successfully')\n      await fetchRegistries(false)\n      setShowCreateOrEditDialog(false)\n      setRegistryToEdit(null)\n      setFormData({\n        name: '',\n        url: '',\n        username: '',\n        password: '',\n        project: '',\n      })\n    } catch (error) {\n      handleApiError(error, 'Failed to edit registry')\n    } finally {\n      setActionInProgress(false)\n    }\n  }\n\n  const handleDelete = async (id: string) => {\n    setActionInProgress(true)\n    try {\n      await dockerRegistryApi.deleteRegistry(id, selectedOrganization?.id)\n      toast.success('Registry deleted successfully')\n      await fetchRegistries(false)\n      setRegistryToDelete(null)\n    } catch (error) {\n      handleApiError(error, 'Failed to delete registry')\n    } finally {\n      setActionInProgress(false)\n    }\n  }\n\n  const writePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_REGISTRIES),\n    [authenticatedUserHasPermission],\n  )\n\n  const dialogContent = (\n    <DialogContent>\n      <DialogHeader>\n        <DialogTitle>{registryToEdit ? 'Edit Registry' : 'Add Registry'}</DialogTitle>\n        <DialogDescription>\n          Registry details must be provided for images that are not publicly available.\n        </DialogDescription>\n      </DialogHeader>\n      <form\n        id=\"registry-form\"\n        className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n        onSubmit={async (e) => {\n          e.preventDefault()\n          if (registryToEdit) {\n            await handleEdit()\n          } else {\n            await handleCreate()\n          }\n        }}\n      >\n        <div className=\"space-y-3\">\n          <Label htmlFor=\"name\">Registry Name</Label>\n          <Input\n            id=\"name\"\n            value={formData.name}\n            onChange={(e) => setFormData((prev) => ({ ...prev, name: e.target.value }))}\n            placeholder=\"My Registry\"\n            required\n          />\n        </div>\n        <div className=\"space-y-3\">\n          <div className=\"flex items-center gap-1.5\">\n            <Label htmlFor=\"url\">Registry URL</Label>\n            <Tooltip>\n              <TooltipTrigger asChild>\n                <Info className=\"h-3.5 w-3.5 text-muted-foreground cursor-help\" />\n              </TooltipTrigger>\n              <TooltipContent>\n                <p>Defaults to docker.io when left blank</p>\n              </TooltipContent>\n            </Tooltip>\n          </div>\n          <Input\n            id=\"url\"\n            value={formData.url}\n            onChange={(e) => setFormData((prev) => ({ ...prev, url: e.target.value }))}\n            placeholder=\"https://registry.example.com\"\n          />\n        </div>\n        <div className=\"space-y-3\">\n          <Label htmlFor=\"username\">Username</Label>\n          <Input\n            id=\"username\"\n            value={formData.username}\n            onChange={(e) => setFormData((prev) => ({ ...prev, username: e.target.value }))}\n            required\n          />\n        </div>\n        <div className=\"space-y-3\">\n          <Label htmlFor=\"password\">Password</Label>\n          <Input\n            id=\"password\"\n            type=\"password\"\n            value={formData.password}\n            onChange={(e) => setFormData((prev) => ({ ...prev, password: e.target.value }))}\n            required={!registryToEdit}\n          />\n          {registryToEdit && <p className=\"text-sm text-gray-500\">Leave empty to keep the current password.</p>}\n        </div>\n        <div className=\"space-y-3\">\n          <div className=\"flex items-center gap-1.5\">\n            <Label htmlFor=\"project\">Project</Label>\n\n            <Tooltip>\n              <TooltipTrigger asChild>\n                <Info className=\"h-3.5 w-3.5 text-muted-foreground cursor-help\" />\n              </TooltipTrigger>\n              <TooltipContent>\n                <p>Leave this empty for private Docker Hub entries</p>\n              </TooltipContent>\n            </Tooltip>\n          </div>\n          <Input\n            id=\"project\"\n            value={formData.project}\n            onChange={(e) => setFormData((prev) => ({ ...prev, project: e.target.value }))}\n            placeholder=\"my-project\"\n          />\n        </div>\n      </form>\n      <DialogFooter>\n        <DialogClose asChild>\n          <Button type=\"button\" variant=\"secondary\">\n            Cancel\n          </Button>\n        </DialogClose>\n        {actionInProgress ? (\n          <Button type=\"button\" variant=\"default\" disabled>\n            {registryToEdit ? 'Editing...' : 'Adding...'}\n          </Button>\n        ) : (\n          <Button\n            type=\"submit\"\n            form=\"registry-form\"\n            variant=\"default\"\n            disabled={\n              !formData.name.trim() || !formData.username.trim() || (!registryToEdit && !formData.password.trim())\n            }\n          >\n            {registryToEdit ? 'Edit' : 'Add'}\n          </Button>\n        )}\n      </DialogFooter>\n    </DialogContent>\n  )\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Registries</PageTitle>\n        {writePermitted && (\n          <Button\n            variant=\"default\"\n            size=\"sm\"\n            disabled={loading}\n            className=\"ml-auto\"\n            title=\"Add Registry\"\n            onClick={() => {\n              setShowCreateOrEditDialog(true)\n              setFormData({\n                name: '',\n                url: '',\n                username: '',\n                password: '',\n                project: '',\n              })\n            }}\n          >\n            <Plus className=\"w-4 h-4\" />\n            Add Registry\n          </Button>\n        )}\n      </PageHeader>\n\n      <PageContent size=\"full\">\n        <Dialog\n          open={showCreateOrEditDialog}\n          onOpenChange={(isOpen) => {\n            setShowCreateOrEditDialog(isOpen)\n            if (isOpen) {\n              return\n            }\n\n            setRegistryToDelete(null)\n            setRegistryToEdit(null)\n            setFormData({\n              name: '',\n              url: '',\n              username: '',\n              password: '',\n              project: '',\n            })\n          }}\n        >\n          {writePermitted && dialogContent}\n\n          <RegistryTable\n            data={registries}\n            loading={loading}\n            onDelete={(id) => setRegistryToDelete(id)}\n            onEdit={(registry) => {\n              setFormData({\n                name: registry.name,\n                url: registry.url,\n                username: registry.username,\n                password: '',\n                project: registry.project,\n              })\n              setRegistryToEdit(registry)\n            }}\n          />\n        </Dialog>\n\n        <Dialog\n          open={!!registryToDelete}\n          onOpenChange={(isOpen) => {\n            if (isOpen) {\n              return\n            }\n\n            setRegistryToDelete(null)\n          }}\n        >\n          <DialogContent>\n            <DialogHeader>\n              <DialogTitle>Confirm Registry Deletion</DialogTitle>\n              <DialogDescription>\n                Are you sure you want to delete this registry? This action cannot be undone.\n              </DialogDescription>\n            </DialogHeader>\n            <DialogFooter>\n              <DialogClose asChild>\n                <Button type=\"button\" variant=\"secondary\">\n                  Cancel\n                </Button>\n              </DialogClose>\n              <Button\n                variant=\"destructive\"\n                onClick={() => {\n                  if (registryToDelete) {\n                    handleDelete(registryToDelete)\n                  }\n                }}\n                disabled={actionInProgress}\n              >\n                {actionInProgress ? 'Deleting...' : 'Delete'}\n              </Button>\n            </DialogFooter>\n          </DialogContent>\n        </Dialog>\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default Registries\n"
  },
  {
    "path": "apps/dashboard/src/pages/Runners.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useApi } from '@/hooks/useApi'\nimport {\n  Runner,\n  RunnerState,\n  OrganizationRolePermissionsEnum,\n  CreateRunner,\n  CreateRunnerResponse,\n} from '@daytonaio/api-client'\nimport { RunnerTable } from '@/components/RunnerTable'\nimport { CreateRunnerDialog } from '@/components/CreateRunnerDialog'\nimport RunnerDetailsSheet from '@/components/RunnerDetailsSheet'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { toast } from 'sonner'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { useNotificationSocket } from '@/hooks/useNotificationSocket'\nimport { handleApiError } from '@/lib/error-handling'\nimport { useRegions } from '@/hooks/useRegions'\n\nconst Runners: React.FC = () => {\n  const { runnersApi } = useApi()\n  const { notificationSocket } = useNotificationSocket()\n  const { customRegions: regions, loadingAvailableRegions: loadingRegions, getRegionName } = useRegions()\n\n  const [runners, setRunners] = useState<Runner[]>([])\n  const [loadingRunnersData, setLoadingRunnersData] = useState(false)\n  const [runnerIsLoading, setRunnerIsLoading] = useState<Record<string, boolean>>({})\n\n  const [runnerToDelete, setRunnerToDelete] = useState<Runner | null>(null)\n  const [deleteRunnerDialogIsOpen, setDeleteRunnerDialogIsOpen] = useState(false)\n\n  const [runnerToToggleScheduling, setRunnerToToggleScheduling] = useState<Runner | null>(null)\n  const [toggleRunnerSchedulingDialogIsOpen, setToggleRunnerSchedulingDialogIsOpen] = useState(false)\n\n  const [selectedRunner, setSelectedRunner] = useState<Runner | null>(null)\n  const [showRunnerDetails, setShowRunnerDetails] = useState(false)\n\n  const [autoRefresh, setAutoRefresh] = useState(false)\n\n  const { selectedOrganization, authenticatedUserHasPermission } = useSelectedOrganization()\n\n  const fetchRunners = useCallback(\n    async (showTableLoadingState = true) => {\n      if (!selectedOrganization) {\n        return\n      }\n      if (showTableLoadingState) {\n        setLoadingRunnersData(true)\n      }\n      try {\n        const response = (await runnersApi.listRunners(selectedOrganization.id)).data\n        setRunners(response || [])\n      } catch (error) {\n        handleApiError(error, 'Failed to fetch runners')\n        setRunners([])\n      } finally {\n        setLoadingRunnersData(false)\n      }\n    },\n    [runnersApi, selectedOrganization],\n  )\n\n  useEffect(() => {\n    fetchRunners()\n  }, [fetchRunners])\n\n  useEffect(() => {\n    if (!autoRefresh) return\n    const interval = setInterval(() => {\n      fetchRunners(false)\n    }, 5000)\n    return () => clearInterval(interval)\n  }, [autoRefresh, fetchRunners])\n\n  useEffect(() => {\n    const handleRunnerCreatedEvent = (runner: Runner) => {\n      if (!runners.some((r) => r.id === runner.id)) {\n        setRunners((prev) => [runner, ...prev])\n      }\n    }\n\n    const handleRunnerStateUpdatedEvent = (data: { runner: Runner; oldState: RunnerState; newState: RunnerState }) => {\n      if (!runners.some((r) => r.id === data.runner.id)) {\n        setRunners((prev) => [data.runner, ...prev])\n      } else {\n        setRunners((prev) =>\n          prev.map((r) =>\n            r.id === data.runner.id\n              ? {\n                  ...r,\n                  state: data.newState,\n                }\n              : r,\n          ),\n        )\n      }\n    }\n\n    const handleRunnerUnschedulableUpdatedEvent = (runner: Runner) => {\n      if (!runners.some((r) => r.id === runner.id)) {\n        setRunners((prev) => [runner, ...prev])\n      } else {\n        setRunners((prev) => prev.map((r) => (r.id === runner.id ? runner : r)))\n      }\n    }\n\n    if (!notificationSocket) {\n      return\n    }\n\n    notificationSocket.on('runner.created', handleRunnerCreatedEvent)\n    notificationSocket.on('runner.state.updated', handleRunnerStateUpdatedEvent)\n    notificationSocket.on('runner.unschedulable.updated', handleRunnerUnschedulableUpdatedEvent)\n\n    return () => {\n      notificationSocket.off('runner.created', handleRunnerCreatedEvent)\n      notificationSocket.off('runner.state.updated', handleRunnerStateUpdatedEvent)\n      notificationSocket.off('runner.unschedulable.updated', handleRunnerUnschedulableUpdatedEvent)\n    }\n  }, [notificationSocket, runners])\n\n  useEffect(() => {\n    if (!selectedRunner || !runners) return\n    const found = runners.find((r) => r.id === selectedRunner.id)\n    if (!found) {\n      setSelectedRunner(null)\n      setShowRunnerDetails(false)\n      return\n    }\n    setSelectedRunner(found)\n  }, [runners, selectedRunner])\n\n  const handleCreateRunner = async (createRunnerData: CreateRunner): Promise<CreateRunnerResponse | null> => {\n    try {\n      const response = (await runnersApi.createRunner(createRunnerData, selectedOrganization?.id)).data\n      toast.success('Runner created successfully')\n      return response\n    } catch (error) {\n      handleApiError(error, 'Failed to create runner')\n      return null\n    }\n  }\n\n  const handleToggleEnabled = async (runner: Runner) => {\n    setRunnerToToggleScheduling(runner)\n    setToggleRunnerSchedulingDialogIsOpen(true)\n  }\n\n  const confirmToggleScheduling = async () => {\n    if (!runnerToToggleScheduling) return\n\n    setRunnerIsLoading((prev) => ({ ...prev, [runnerToToggleScheduling.id]: true }))\n    try {\n      await runnersApi.updateRunnerScheduling(runnerToToggleScheduling.id, selectedOrganization?.id, {\n        data: { unschedulable: !runnerToToggleScheduling.unschedulable },\n      })\n      toast.success(\n        `Runner is now ${runnerToToggleScheduling.unschedulable ? 'available' : 'unavailable'} for scheduling new sandboxes`,\n      )\n    } catch (error) {\n      handleApiError(error, 'Failed to update runner scheduling status')\n    } finally {\n      setRunnerIsLoading((prev) => ({ ...prev, [runnerToToggleScheduling.id]: false }))\n      setToggleRunnerSchedulingDialogIsOpen(false)\n      setRunnerToToggleScheduling(null)\n    }\n  }\n\n  const handleDelete = async (runner: Runner) => {\n    setRunnerToDelete(runner)\n    setDeleteRunnerDialogIsOpen(true)\n  }\n\n  const confirmDelete = async () => {\n    if (!runnerToDelete) return\n\n    setRunnerIsLoading((prev) => ({ ...prev, [runnerToDelete.id]: true }))\n    try {\n      await runnersApi.deleteRunner(runnerToDelete.id, selectedOrganization?.id)\n      toast.success('Runner deleted successfully')\n      await fetchRunners(false)\n    } catch (error) {\n      handleApiError(error, 'Failed to delete runner')\n    } finally {\n      setRunnerIsLoading((prev) => ({ ...prev, [runnerToDelete.id]: false }))\n      setDeleteRunnerDialogIsOpen(false)\n      setRunnerToDelete(null)\n    }\n  }\n\n  const writePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_RUNNERS),\n    [authenticatedUserHasPermission],\n  )\n\n  const deletePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.DELETE_RUNNERS),\n    [authenticatedUserHasPermission],\n  )\n\n  return (\n    <div className=\"px-6 py-2\">\n      <div className=\"mb-2 h-12 flex items-center justify-between\">\n        <h1 className=\"text-2xl font-medium\">Runners</h1>\n        {writePermitted && regions.length > 0 && (\n          <CreateRunnerDialog regions={regions} onCreateRunner={handleCreateRunner} />\n        )}\n      </div>\n\n      <RunnerTable\n        data={runners}\n        regions={regions}\n        loading={loadingRunnersData || loadingRegions}\n        isLoadingRunner={(runner) => runnerIsLoading[runner.id] || false}\n        writePermitted={writePermitted}\n        deletePermitted={deletePermitted}\n        onToggleEnabled={handleToggleEnabled}\n        onDelete={handleDelete}\n        getRegionName={getRegionName}\n        onRowClick={(runner: Runner) => {\n          setSelectedRunner(runner)\n          setShowRunnerDetails(true)\n        }}\n        autoRefresh={autoRefresh}\n        onAutoRefreshChange={setAutoRefresh}\n      />\n\n      {runnerToToggleScheduling && (\n        <Dialog open={toggleRunnerSchedulingDialogIsOpen} onOpenChange={setToggleRunnerSchedulingDialogIsOpen}>\n          <DialogContent>\n            <DialogHeader>\n              <DialogTitle>Update Runner</DialogTitle>\n              <DialogDescription>\n                Are you sure you want to update the scheduling status of this runner? This will make the runner{' '}\n                {runnerToToggleScheduling.unschedulable ? 'available' : 'unavailable'} for scheduling new sandboxes.\n              </DialogDescription>\n            </DialogHeader>\n            <DialogFooter>\n              <DialogClose asChild>\n                <Button type=\"button\" variant=\"secondary\">\n                  Cancel\n                </Button>\n              </DialogClose>\n              <Button\n                variant={runnerToToggleScheduling.unschedulable ? 'default' : 'destructive'}\n                onClick={confirmToggleScheduling}\n                disabled={runnerIsLoading[runnerToToggleScheduling.id]}\n              >\n                {runnerIsLoading[runnerToToggleScheduling.id]\n                  ? 'Updating...'\n                  : runnerToToggleScheduling.unschedulable\n                    ? 'Mark as schedulable'\n                    : 'Mark as unschedulable'}\n              </Button>\n            </DialogFooter>\n          </DialogContent>\n        </Dialog>\n      )}\n\n      {runnerToDelete && (\n        <Dialog open={deleteRunnerDialogIsOpen} onOpenChange={setDeleteRunnerDialogIsOpen}>\n          <DialogContent>\n            <DialogHeader>\n              <DialogTitle>Confirm Runner Deletion</DialogTitle>\n              <DialogDescription>\n                Are you sure you want to delete this runner? This action cannot be undone.\n              </DialogDescription>\n            </DialogHeader>\n            <DialogFooter>\n              <DialogClose asChild>\n                <Button type=\"button\" variant=\"secondary\">\n                  Cancel\n                </Button>\n              </DialogClose>\n              <Button variant=\"destructive\" onClick={confirmDelete} disabled={runnerIsLoading[runnerToDelete.id]}>\n                {runnerIsLoading[runnerToDelete.id] ? 'Deleting...' : 'Delete'}\n              </Button>\n            </DialogFooter>\n          </DialogContent>\n        </Dialog>\n      )}\n\n      <RunnerDetailsSheet\n        runner={selectedRunner}\n        open={showRunnerDetails}\n        onOpenChange={setShowRunnerDetails}\n        runnerIsLoading={runnerIsLoading}\n        writePermitted={writePermitted}\n        deletePermitted={deletePermitted}\n        onDelete={(runner) => {\n          setRunnerToDelete(runner)\n          setDeleteRunnerDialogIsOpen(true)\n          setShowRunnerDetails(false)\n        }}\n        getRegionName={getRegionName}\n      />\n    </div>\n  )\n}\n\nexport default Runners\n"
  },
  {
    "path": "apps/dashboard/src/pages/Sandboxes.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OrganizationSuspendedError } from '@/api/errors'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { CreateSandboxSheet } from '@/components/Sandbox/CreateSandboxSheet'\nimport SandboxDetailsSheet from '@/components/SandboxDetailsSheet'\nimport { SandboxTable } from '@/components/SandboxTable'\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from '@/components/ui/alert-dialog'\nimport { Button } from '@/components/ui/button'\nimport { Label } from '@/components/ui/label'\nimport { DAYTONA_DOCS_URL } from '@/constants/ExternalLinks'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { LocalStorageKey } from '@/enums/LocalStorageKey'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { SnapshotFilters, SnapshotQueryParams, useSnapshotsQuery } from '@/hooks/queries/useSnapshotsQuery'\nimport { useApi } from '@/hooks/useApi'\nimport { useConfig } from '@/hooks/useConfig'\nimport { useNotificationSocket } from '@/hooks/useNotificationSocket'\nimport { useRegions } from '@/hooks/useRegions'\nimport {\n  DEFAULT_SANDBOX_SORTING,\n  getSandboxesQueryKey,\n  SandboxFilters,\n  SandboxQueryParams,\n  SandboxSorting,\n  useSandboxes,\n} from '@/hooks/useSandboxes'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { createBulkActionToast } from '@/lib/bulk-action-toast'\nimport { handleApiError } from '@/lib/error-handling'\nimport { getLocalStorageItem, setLocalStorageItem } from '@/lib/local-storage'\nimport { formatDuration, pluralize } from '@/lib/utils'\nimport {\n  OrganizationUserRoleEnum,\n  Sandbox,\n  SandboxDesiredState,\n  SandboxState,\n  SshAccessDto,\n} from '@daytonaio/api-client'\nimport { QueryKey, useQueryClient } from '@tanstack/react-query'\nimport { Check, Copy } from 'lucide-react'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { useNavigate } from 'react-router-dom'\nimport { toast } from 'sonner'\n\nconst Sandboxes: React.FC = () => {\n  const { sandboxApi, apiKeyApi, toolboxApi } = useApi()\n  const { user } = useAuth()\n  const navigate = useNavigate()\n  const { notificationSocket } = useNotificationSocket()\n  const config = useConfig()\n  const queryClient = useQueryClient()\n  const { selectedOrganization, authenticatedUserOrganizationMember } = useSelectedOrganization()\n\n  // Pagination\n\n  const [paginationParams, setPaginationParams] = useState({\n    pageIndex: 0,\n    pageSize: DEFAULT_PAGE_SIZE,\n  })\n\n  const handlePaginationChange = useCallback(({ pageIndex, pageSize }: { pageIndex: number; pageSize: number }) => {\n    setPaginationParams({ pageIndex, pageSize })\n  }, [])\n\n  // Filters\n\n  const [filters, setFilters] = useState<SandboxFilters>({})\n\n  const handleFiltersChange = useCallback((filters: SandboxFilters) => {\n    setFilters(filters)\n    setPaginationParams((prev) => ({ ...prev, pageIndex: 0 }))\n  }, [])\n\n  // Sorting\n\n  const [sorting, setSorting] = useState<SandboxSorting>(DEFAULT_SANDBOX_SORTING)\n\n  const handleSortingChange = useCallback((sorting: SandboxSorting) => {\n    setSorting(sorting)\n    setPaginationParams((prev) => ({ ...prev, pageIndex: 0 }))\n  }, [])\n\n  // Sandboxes Data\n\n  const queryParams = useMemo<SandboxQueryParams>(\n    () => ({\n      page: paginationParams.pageIndex + 1, // 1-indexed\n      pageSize: paginationParams.pageSize,\n      filters: filters,\n      sorting: sorting,\n    }),\n    [paginationParams, filters, sorting],\n  )\n\n  const baseQueryKey = useMemo<QueryKey>(\n    () => getSandboxesQueryKey(selectedOrganization?.id),\n    [selectedOrganization?.id],\n  )\n\n  const queryKey = useMemo<QueryKey>(\n    () => getSandboxesQueryKey(selectedOrganization?.id, queryParams),\n    [selectedOrganization?.id, queryParams],\n  )\n\n  const {\n    data: sandboxesData,\n    isLoading: sandboxesDataIsLoading,\n    error: sandboxesDataError,\n    refetch: refetchSandboxesData,\n  } = useSandboxes(queryKey, queryParams)\n\n  useEffect(() => {\n    if (sandboxesDataError) {\n      handleApiError(sandboxesDataError, 'Failed to fetch sandboxes')\n    }\n  }, [sandboxesDataError])\n\n  const updateSandboxInCache = useCallback(\n    (sandboxId: string, updates: Partial<Sandbox>) => {\n      queryClient.setQueryData(queryKey, (oldData: any) => {\n        if (!oldData) return oldData\n        return {\n          ...oldData,\n          items: oldData.items.map((sandbox: Sandbox) =>\n            sandbox.id === sandboxId ? { ...sandbox, ...updates } : sandbox,\n          ),\n        }\n      })\n    },\n    [queryClient, queryKey],\n  )\n\n  /**\n   * Marks all sandbox queries for this organization as stale.\n   *\n   * Useful when sandbox event occurs and we don't have a good way of knowing for which combination of query parameters the sandbox would be shown.\n   *\n   * @param shouldRefetchActiveQueries If true, only active queries will be refetched. Otherwise, no queries will be refetched.\n   */\n  const markAllSandboxQueriesAsStale = useCallback(\n    async (shouldRefetchActiveQueries = false) => {\n      queryClient.invalidateQueries({\n        queryKey: baseQueryKey,\n        refetchType: shouldRefetchActiveQueries ? 'active' : 'none',\n      })\n    },\n    [queryClient, baseQueryKey],\n  )\n\n  /**\n   * Aborts all outgoing refetches for the provided key.\n   *\n   * Useful for preventing refetches from overwriting optimistic updates.\n   *\n   * @param queryKey\n   */\n  const cancelQueryRefetches = useCallback(\n    async (queryKey: QueryKey) => {\n      queryClient.cancelQueries({ queryKey })\n    },\n    [queryClient],\n  )\n\n  // Go to previous page if there are no items on the current page\n\n  useEffect(() => {\n    if (sandboxesData?.items.length === 0 && paginationParams.pageIndex > 0) {\n      setPaginationParams((prev) => ({\n        ...prev,\n        pageIndex: prev.pageIndex - 1,\n      }))\n    }\n  }, [sandboxesData?.items.length, paginationParams.pageIndex])\n\n  // Ephemeral Sandbox States\n\n  const [sandboxIsLoading, setSandboxIsLoading] = useState<Record<string, boolean>>({})\n  const [sandboxStateIsTransitioning, setSandboxStateIsTransitioning] = useState<Record<string, boolean>>({}) // display transition animation\n\n  // Manual Refreshing\n\n  const [sandboxDataIsRefreshing, setSandboxDataIsRefreshing] = useState(false)\n\n  const handleRefresh = useCallback(async () => {\n    setSandboxDataIsRefreshing(true)\n    try {\n      await refetchSandboxesData()\n    } catch (error) {\n      handleApiError(error, 'Failed to refresh sandboxes')\n    } finally {\n      setSandboxDataIsRefreshing(false)\n    }\n  }, [refetchSandboxesData])\n\n  // Delete Sandbox Dialog\n\n  const [sandboxToDelete, setSandboxToDelete] = useState<string | null>(null)\n  const [showDeleteDialog, setShowDeleteDialog] = useState(false)\n\n  // Sandbox Details Drawer\n\n  const [selectedSandbox, setSelectedSandbox] = useState<Sandbox | null>(null)\n  const [showSandboxDetails, setShowSandboxDetails] = useState(false)\n\n  useEffect(() => {\n    if (!selectedSandbox || !sandboxesData?.items) {\n      return\n    }\n\n    const selectedSandboxInData = sandboxesData.items.find((s) => s.id === selectedSandbox.id)\n\n    if (!selectedSandboxInData) {\n      setSelectedSandbox(null)\n      setShowSandboxDetails(false)\n      return\n    }\n\n    if (selectedSandboxInData !== selectedSandbox) {\n      setSelectedSandbox(selectedSandboxInData)\n    }\n  }, [sandboxesData?.items, selectedSandbox])\n\n  const performSandboxStateOptimisticUpdate = useCallback(\n    (sandboxId: string, newState: SandboxState) => {\n      updateSandboxInCache(sandboxId, { state: newState })\n\n      if (selectedSandbox?.id === sandboxId) {\n        setSelectedSandbox((prev) => (prev ? { ...prev, state: newState } : null))\n      }\n    },\n    [updateSandboxInCache, selectedSandbox?.id],\n  )\n\n  const revertSandboxStateOptimisticUpdate = useCallback(\n    (sandboxId: string, previousState?: SandboxState) => {\n      if (!previousState) {\n        return\n      }\n\n      updateSandboxInCache(sandboxId, { state: previousState })\n\n      if (selectedSandbox?.id === sandboxId) {\n        setSelectedSandbox((prev) => (prev ? { ...prev, state: previousState } : null))\n      }\n    },\n    [updateSandboxInCache, selectedSandbox?.id],\n  )\n\n  // SSH Access Dialogs\n\n  const [showCreateSshDialog, setShowCreateSshDialog] = useState(false)\n  const [showRevokeSshDialog, setShowRevokeSshDialog] = useState(false)\n  const [sshAccess, setSshAccess] = useState<SshAccessDto | null>(null)\n  const [sshExpiryMinutes, setSshExpiryMinutes] = useState<number>(60)\n  const [revokeSshToken, setRevokeSshToken] = useState<string>('')\n  const [sshSandboxId, setSshSandboxId] = useState<string>('')\n  const [copied, setCopied] = useState<string | null>(null)\n\n  // Snapshot Filter\n\n  const [snapshotFilters, setSnapshotFilters] = useState<SnapshotFilters>({})\n\n  const handleSnapshotFiltersChange = useCallback((filters: Partial<SnapshotFilters>) => {\n    setSnapshotFilters((prev) => ({ ...prev, ...filters }))\n  }, [])\n\n  const snapshotsQueryParams = useMemo<SnapshotQueryParams>(\n    () => ({\n      page: 1,\n      pageSize: 100,\n      filters: snapshotFilters,\n    }),\n    [snapshotFilters],\n  )\n\n  const {\n    data: snapshotsData,\n    isLoading: snapshotsDataIsLoading,\n    error: snapshotsDataError,\n  } = useSnapshotsQuery(snapshotsQueryParams)\n\n  const snapshotsDataHasMore = useMemo(() => {\n    return snapshotsData && snapshotsData.totalPages > 1\n  }, [snapshotsData])\n\n  useEffect(() => {\n    if (snapshotsDataError) {\n      handleApiError(snapshotsDataError, 'Failed to fetch snapshots')\n    }\n  }, [snapshotsDataError])\n\n  // Region Filter\n\n  const { availableRegions: regionsData, loadingAvailableRegions: regionsDataIsLoading, getRegionName } = useRegions()\n\n  // Subscribe to Sandbox Events\n\n  useEffect(() => {\n    const handleSandboxCreatedEvent = (sandbox: Sandbox) => {\n      const isFirstPage = paginationParams.pageIndex === 0\n      const isDefaultFilters = Object.keys(filters).length === 0\n      const isDefaultSorting =\n        sorting.field === DEFAULT_SANDBOX_SORTING.field && sorting.direction === DEFAULT_SANDBOX_SORTING.direction\n\n      const shouldRefetchActiveQueries = isFirstPage && isDefaultFilters && isDefaultSorting\n\n      markAllSandboxQueriesAsStale(shouldRefetchActiveQueries)\n    }\n\n    const handleSandboxStateUpdatedEvent = (data: {\n      sandbox: Sandbox\n      oldState: SandboxState\n      newState: SandboxState\n    }) => {\n      // warm pool sandboxes\n      if (data.oldState === data.newState && data.newState === SandboxState.STARTED) {\n        handleSandboxCreatedEvent(data.sandbox)\n        return\n      }\n\n      let updatedState = data.newState\n\n      // error,build_failed | destroyed should be displayed as destroyed in the UI\n      if (\n        data.sandbox.desiredState === SandboxDesiredState.DESTROYED &&\n        (data.newState === SandboxState.ERROR || data.newState === SandboxState.BUILD_FAILED)\n      ) {\n        updatedState = SandboxState.DESTROYED\n      }\n\n      performSandboxStateOptimisticUpdate(data.sandbox.id, updatedState)\n\n      markAllSandboxQueriesAsStale()\n    }\n\n    const handleSandboxDesiredStateUpdatedEvent = (data: {\n      sandbox: Sandbox\n      oldDesiredState: SandboxDesiredState\n      newDesiredState: SandboxDesiredState\n    }) => {\n      // error,build_failed | destroyed should be displayed as destroyed in the UI\n\n      if (data.newDesiredState !== SandboxDesiredState.DESTROYED) {\n        return\n      }\n\n      if (data.sandbox.state !== SandboxState.ERROR && data.sandbox.state !== SandboxState.BUILD_FAILED) {\n        return\n      }\n\n      performSandboxStateOptimisticUpdate(data.sandbox.id, SandboxState.DESTROYED)\n\n      markAllSandboxQueriesAsStale()\n    }\n\n    if (!notificationSocket) {\n      return\n    }\n\n    notificationSocket.on('sandbox.created', handleSandboxCreatedEvent)\n    notificationSocket.on('sandbox.state.updated', handleSandboxStateUpdatedEvent)\n    notificationSocket.on('sandbox.desired-state.updated', handleSandboxDesiredStateUpdatedEvent)\n\n    return () => {\n      notificationSocket.off('sandbox.created', handleSandboxCreatedEvent)\n      notificationSocket.off('sandbox.state.updated', handleSandboxStateUpdatedEvent)\n      notificationSocket.off('sandbox.desired-state.updated', handleSandboxDesiredStateUpdatedEvent)\n    }\n  }, [\n    filters,\n    markAllSandboxQueriesAsStale,\n    notificationSocket,\n    paginationParams.pageIndex,\n    performSandboxStateOptimisticUpdate,\n    sorting.direction,\n    sorting.field,\n  ])\n\n  // Sandbox Action Handlers\n\n  const handleStart = async (id: string) => {\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n    setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: true }))\n\n    const sandboxToStart = sandboxesData?.items.find((s) => s.id === id)\n    const previousState = sandboxToStart?.state\n\n    await cancelQueryRefetches(queryKey)\n    performSandboxStateOptimisticUpdate(id, SandboxState.STARTING)\n\n    try {\n      await sandboxApi.startSandbox(id, selectedOrganization?.id)\n      toast.success(`Starting sandbox with ID: ${id}`)\n      await markAllSandboxQueriesAsStale()\n    } catch (error) {\n      handleApiError(\n        error,\n        'Failed to start sandbox',\n        error instanceof OrganizationSuspendedError &&\n          config.billingApiUrl &&\n          authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER ? (\n          <Button variant=\"secondary\" onClick={() => navigate(RoutePath.BILLING_WALLET)}>\n            Go to billing\n          </Button>\n        ) : undefined,\n      )\n      revertSandboxStateOptimisticUpdate(id, previousState)\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n      setTimeout(() => {\n        setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: false }))\n      }, 2000)\n    }\n  }\n\n  const handleRecover = async (id: string) => {\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n    setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: true }))\n\n    const sandboxToRecover = sandboxesData?.items.find((s) => s.id === id)\n    const previousState = sandboxToRecover?.state\n\n    await cancelQueryRefetches(queryKey)\n    performSandboxStateOptimisticUpdate(id, SandboxState.STARTING)\n\n    try {\n      await sandboxApi.recoverSandbox(id, selectedOrganization?.id)\n      toast.success('Sandbox recovered. Restarting...')\n      await markAllSandboxQueriesAsStale()\n    } catch (error) {\n      handleApiError(error, 'Failed to recover sandbox')\n      revertSandboxStateOptimisticUpdate(id, previousState)\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n      setTimeout(() => {\n        setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: false }))\n      }, 2000)\n    }\n  }\n\n  const handleStop = async (id: string) => {\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n    setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: true }))\n\n    const sandboxToStop = sandboxesData?.items.find((s) => s.id === id)\n    const previousState = sandboxToStop?.state\n\n    await cancelQueryRefetches(queryKey)\n    performSandboxStateOptimisticUpdate(id, SandboxState.STOPPING)\n\n    try {\n      await sandboxApi.stopSandbox(id, selectedOrganization?.id)\n      toast.success(\n        `Stopping sandbox with ID: ${id}`,\n        sandboxToStop?.autoDeleteInterval !== undefined && sandboxToStop.autoDeleteInterval >= 0\n          ? {\n              description: `This sandbox will be deleted automatically ${sandboxToStop.autoDeleteInterval === 0 ? 'upon stopping' : `in ${formatDuration(sandboxToStop.autoDeleteInterval)} unless it is started again`}.`,\n            }\n          : undefined,\n      )\n      await markAllSandboxQueriesAsStale()\n    } catch (error) {\n      handleApiError(error, 'Failed to stop sandbox')\n      revertSandboxStateOptimisticUpdate(id, previousState)\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n      setTimeout(() => {\n        setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: false }))\n      }, 2000)\n    }\n  }\n\n  const handleDelete = async (id: string) => {\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n    setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: true }))\n\n    const sandboxToDelete = sandboxesData?.items.find((s) => s.id === id)\n    const previousState = sandboxToDelete?.state\n\n    await cancelQueryRefetches(queryKey)\n    performSandboxStateOptimisticUpdate(id, SandboxState.DESTROYING)\n\n    try {\n      await sandboxApi.deleteSandbox(id, selectedOrganization?.id)\n      setSandboxToDelete(null)\n      setShowDeleteDialog(false)\n\n      if (selectedSandbox?.id === id) {\n        setShowSandboxDetails(false)\n        setSelectedSandbox(null)\n      }\n\n      toast.success(`Deleting sandbox with ID:  ${id}`)\n\n      await markAllSandboxQueriesAsStale()\n    } catch (error) {\n      handleApiError(error, 'Failed to delete sandbox')\n      revertSandboxStateOptimisticUpdate(id, previousState)\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n      setTimeout(() => {\n        setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: false }))\n      }, 2000)\n    }\n  }\n\n  const handleArchive = async (id: string) => {\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n    setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: true }))\n\n    const sandboxToArchive = sandboxesData?.items.find((s) => s.id === id)\n    const previousState = sandboxToArchive?.state\n\n    await cancelQueryRefetches(queryKey)\n    performSandboxStateOptimisticUpdate(id, SandboxState.ARCHIVING)\n\n    try {\n      await sandboxApi.archiveSandbox(id, selectedOrganization?.id)\n      toast.success(`Archiving sandbox with ID: ${id}`)\n      await markAllSandboxQueriesAsStale()\n    } catch (error) {\n      handleApiError(error, 'Failed to archive sandbox')\n      revertSandboxStateOptimisticUpdate(id, previousState)\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n      setTimeout(() => {\n        setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: false }))\n      }, 2000)\n    }\n  }\n\n  // todo(rpavlini): we should refactor this and move to react-query mutations\n  const executeBulkAction = useCallback(\n    async ({\n      ids,\n      actionName,\n      optimisticState,\n      apiCall,\n      toastMessages,\n    }: {\n      ids: string[]\n      actionName: string\n      optimisticState: SandboxState\n      apiCall: (id: string) => Promise<unknown>\n      toastMessages: {\n        successTitle: string\n        errorTitle: string\n        warningTitle: string\n        canceledTitle: string\n      }\n    }) => {\n      await cancelQueryRefetches(queryKey)\n\n      const previousStatesById = new Map((sandboxesData?.items ?? []).map((sandbox) => [sandbox.id, sandbox.state]))\n\n      let isCancelled = false\n      let processedCount = 0\n      let successCount = 0\n      let failureCount = 0\n\n      const totalLabel = pluralize(ids.length, 'sandbox', 'sandboxes')\n      const onCancel = () => {\n        isCancelled = true\n      }\n\n      const bulkToast = createBulkActionToast(`${actionName} 0 of ${totalLabel}.`, {\n        action: { label: 'Cancel', onClick: onCancel },\n      })\n\n      try {\n        for (const id of ids) {\n          if (isCancelled) break\n\n          processedCount += 1\n          bulkToast.loading(`${actionName} ${processedCount} of ${totalLabel}.`, {\n            action: { label: 'Cancel', onClick: onCancel },\n          })\n\n          setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n          setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: true }))\n          performSandboxStateOptimisticUpdate(id, optimisticState)\n\n          try {\n            await apiCall(id)\n            successCount += 1\n          } catch (error) {\n            failureCount += 1\n            revertSandboxStateOptimisticUpdate(id, previousStatesById.get(id))\n            console.error(`${actionName} sandbox failed`, id, error)\n          } finally {\n            setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n            setTimeout(() => {\n              setSandboxStateIsTransitioning((prev) => ({ ...prev, [id]: false }))\n            }, 2000)\n          }\n        }\n\n        await markAllSandboxQueriesAsStale()\n        bulkToast.result({ successCount, failureCount }, toastMessages)\n      } catch (error) {\n        console.error(`${actionName} sandboxes failed`, error)\n        bulkToast.error(`${actionName} sandboxes failed.`)\n      }\n\n      return { successCount, failureCount }\n    },\n    [\n      cancelQueryRefetches,\n      queryKey,\n      sandboxesData?.items,\n      performSandboxStateOptimisticUpdate,\n      revertSandboxStateOptimisticUpdate,\n      markAllSandboxQueriesAsStale,\n    ],\n  )\n\n  const handleBulkStart = (ids: string[]) =>\n    executeBulkAction({\n      ids,\n      actionName: 'Starting',\n      optimisticState: SandboxState.STARTING,\n      apiCall: (id) => sandboxApi.startSandbox(id, selectedOrganization?.id),\n      toastMessages: {\n        successTitle: `${pluralize(ids.length, 'sandbox', 'sandboxes')} started.`,\n        errorTitle: `Failed to start ${pluralize(ids.length, 'sandbox', 'sandboxes')}.`,\n        warningTitle: 'Failed to start some sandboxes.',\n        canceledTitle: 'Start canceled.',\n      },\n    })\n\n  const handleBulkStop = (ids: string[]) =>\n    executeBulkAction({\n      ids,\n      actionName: 'Stopping',\n      optimisticState: SandboxState.STOPPING,\n      apiCall: (id) => sandboxApi.stopSandbox(id, selectedOrganization?.id),\n      toastMessages: {\n        successTitle: `${pluralize(ids.length, 'sandbox', 'sandboxes')} stopped.`,\n        errorTitle: `Failed to stop ${pluralize(ids.length, 'sandbox', 'sandboxes')}.`,\n        warningTitle: 'Failed to stop some sandboxes.',\n        canceledTitle: 'Stop canceled.',\n      },\n    })\n\n  const handleBulkArchive = (ids: string[]) =>\n    executeBulkAction({\n      ids,\n      actionName: 'Archiving',\n      optimisticState: SandboxState.ARCHIVING,\n      apiCall: (id) => sandboxApi.archiveSandbox(id, selectedOrganization?.id),\n      toastMessages: {\n        successTitle: `${pluralize(ids.length, 'sandbox', 'sandboxes')} archived.`,\n        errorTitle: `Failed to archive ${pluralize(ids.length, 'sandbox', 'sandboxes')}.`,\n        warningTitle: 'Failed to archive some sandboxes.',\n        canceledTitle: 'Archive canceled.',\n      },\n    })\n\n  const handleBulkDelete = async (ids: string[]) => {\n    const selectedSandboxInBulk = selectedSandbox && ids.includes(selectedSandbox.id)\n\n    await executeBulkAction({\n      ids,\n      actionName: 'Deleting',\n      optimisticState: SandboxState.DESTROYING,\n      apiCall: (id) => sandboxApi.deleteSandbox(id, selectedOrganization?.id),\n      toastMessages: {\n        successTitle: `${pluralize(ids.length, 'sandbox', 'sandboxes')} deleted.`,\n        errorTitle: `Failed to delete ${pluralize(ids.length, 'sandbox', 'sandboxes')}.`,\n        warningTitle: 'Failed to delete some sandboxes.',\n        canceledTitle: 'Delete canceled.',\n      },\n    })\n\n    if (selectedSandboxInBulk) {\n      setShowSandboxDetails(false)\n      setSelectedSandbox(null)\n    }\n  }\n\n  const getPortPreviewUrl = useCallback(\n    async (sandboxId: string, port: number): Promise<string> => {\n      setSandboxIsLoading((prev) => ({ ...prev, [sandboxId]: true }))\n      try {\n        return (await sandboxApi.getSignedPortPreviewUrl(sandboxId, port, selectedOrganization?.id)).data.url\n      } finally {\n        setSandboxIsLoading((prev) => ({ ...prev, [sandboxId]: false }))\n      }\n    },\n    [sandboxApi, selectedOrganization],\n  )\n\n  const getVncUrl = async (sandboxId: string): Promise<string | null> => {\n    try {\n      const portPreviewUrl = await getPortPreviewUrl(sandboxId, 6080)\n      return portPreviewUrl + '/vnc.html'\n    } catch (error) {\n      handleApiError(error, 'Failed to construct VNC URL')\n      return null\n    }\n  }\n\n  const handleVnc = async (id: string) => {\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n\n    // Notify user immediately that we're checking VNC status\n    toast.info('Checking VNC desktop status...')\n\n    try {\n      // First, check if computer use is already started\n      const statusResponse = await toolboxApi.getComputerUseStatusDeprecated(id, selectedOrganization?.id)\n      const status = statusResponse.data.status\n\n      // Check if computer use is active (all processes running)\n      if (status === 'active') {\n        const vncUrl = await getVncUrl(id)\n        if (vncUrl) {\n          window.open(vncUrl, '_blank')\n          toast.success('Opening VNC desktop...')\n        }\n      } else {\n        // Computer use is not active, try to start it\n        try {\n          await toolboxApi.startComputerUseDeprecated(id, selectedOrganization?.id)\n          toast.success('Starting VNC desktop...')\n\n          // Wait a moment for processes to start, then open VNC\n          await new Promise((resolve) => setTimeout(resolve, 5000))\n\n          try {\n            const newStatusResponse = await toolboxApi.getComputerUseStatusDeprecated(id, selectedOrganization?.id)\n            const newStatus = newStatusResponse.data.status\n\n            if (newStatus === 'active') {\n              const vncUrl = await getVncUrl(id)\n\n              if (vncUrl) {\n                window.open(vncUrl, '_blank')\n                toast.success('VNC desktop is ready!', {\n                  action: (\n                    <Button variant=\"secondary\" onClick={() => window.open(vncUrl, '_blank')}>\n                      Open in new tab\n                    </Button>\n                  ),\n                })\n              }\n            } else {\n              toast.error(`VNC desktop failed to start. Status: ${newStatus}`)\n            }\n          } catch (error) {\n            handleApiError(error, 'Failed to check VNC status after start')\n          }\n        } catch (startError: any) {\n          // Check if this is a computer-use availability error\n          const errorMessage = startError?.response?.data?.message || startError?.message || String(startError)\n\n          if (errorMessage === 'Computer-use functionality is not available') {\n            toast.error('Computer-use functionality is not available', {\n              description: (\n                <div>\n                  <div>Computer-use dependencies are missing in the runtime environment.</div>\n                  <div className=\"mt-2\">\n                    <a\n                      href={`${DAYTONA_DOCS_URL}/getting-started/computer-use`}\n                      target=\"_blank\"\n                      rel=\"noopener noreferrer\"\n                      className=\"text-primary hover:underline\"\n                    >\n                      See documentation on how to configure the runtime for computer-use\n                    </a>\n                  </div>\n                </div>\n              ),\n            })\n          } else {\n            handleApiError(startError, 'Failed to start VNC desktop')\n          }\n        }\n      }\n    } catch (error) {\n      handleApiError(error, 'Failed to check VNC status')\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n    }\n  }\n\n  const getWebTerminalUrl = useCallback(\n    async (sandboxId: string): Promise<string | null> => {\n      try {\n        return await getPortPreviewUrl(sandboxId, 22222)\n      } catch (error) {\n        handleApiError(error, 'Failed to construct web terminal URL')\n        return null\n      }\n    },\n    [getPortPreviewUrl],\n  )\n\n  const handleScreenRecordings = async (id: string) => {\n    // Check if sandbox is started\n    const sandbox = sandboxesData?.items?.find((s) => s.id === id)\n    if (!sandbox || sandbox.state !== SandboxState.STARTED) {\n      toast.error('Sandbox must be started to access Screen Recordings')\n      return\n    }\n\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n    try {\n      const portPreviewUrl = await getPortPreviewUrl(id, 33333)\n      window.open(portPreviewUrl, '_blank')\n      toast.success('Opening Screen Recordings dashboard...')\n    } catch (error) {\n      handleApiError(error, 'Failed to open Screen Recordings')\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n    }\n  }\n\n  const handleCreateSshAccess = async (id: string) => {\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n    try {\n      const response = await sandboxApi.createSshAccess(id, selectedOrganization?.id, sshExpiryMinutes)\n      setSshAccess(response.data)\n      setSshSandboxId(id)\n      setShowCreateSshDialog(true)\n      toast.success('SSH access created successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to create SSH access')\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n    }\n  }\n\n  const openCreateSshDialog = (id: string) => {\n    setSshSandboxId(id)\n    setShowCreateSshDialog(true)\n  }\n\n  const handleRevokeSshAccess = async (id: string) => {\n    if (!revokeSshToken.trim()) {\n      toast.error('Please enter a token to revoke')\n      return\n    }\n\n    setSandboxIsLoading((prev) => ({ ...prev, [id]: true }))\n    try {\n      await sandboxApi.revokeSshAccess(id, selectedOrganization?.id, revokeSshToken)\n      setRevokeSshToken('')\n      setSshSandboxId('')\n      setShowRevokeSshDialog(false)\n      toast.success('SSH access revoked successfully')\n    } catch (error) {\n      handleApiError(error, 'Failed to revoke SSH access')\n    } finally {\n      setSandboxIsLoading((prev) => ({ ...prev, [id]: false }))\n    }\n  }\n\n  const openRevokeSshDialog = (id: string) => {\n    setSshSandboxId(id)\n    setShowRevokeSshDialog(true)\n  }\n\n  const copyToClipboard = async (text: string, label: string) => {\n    try {\n      await navigator.clipboard.writeText(text)\n      setCopied(label)\n      setTimeout(() => setCopied(null), 2000)\n    } catch (err) {\n      console.error('Failed to copy text:', err)\n    }\n  }\n\n  // Redirect user to the onboarding page if they haven't created an api key yet\n  // Perform only once per user\n\n  useEffect(() => {\n    const onboardIfNeeded = async () => {\n      if (!selectedOrganization) {\n        return\n      }\n\n      const skipOnboardingKey = `${LocalStorageKey.SkipOnboardingPrefix}${user?.profile.sub}`\n      const shouldSkipOnboarding = getLocalStorageItem(skipOnboardingKey) === 'true'\n\n      if (shouldSkipOnboarding) {\n        return\n      }\n\n      try {\n        const keys = (await apiKeyApi.listApiKeys(selectedOrganization.id)).data\n        if (keys.length === 0) {\n          setLocalStorageItem(skipOnboardingKey, 'true')\n          navigate(RoutePath.ONBOARDING)\n        } else {\n          setLocalStorageItem(skipOnboardingKey, 'true')\n        }\n      } catch (error) {\n        console.error('Failed to check if user needs onboarding', error)\n      }\n    }\n\n    onboardIfNeeded()\n  }, [navigate, user, selectedOrganization, apiKeyApi])\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Sandboxes</PageTitle>\n        <div className=\"flex items-center gap-2 ml-auto\">\n          {!sandboxesDataIsLoading && (!sandboxesData?.items || sandboxesData.items.length === 0) && (\n            <>\n              <Button variant=\"link\" className=\"text-primary\" onClick={() => navigate(RoutePath.ONBOARDING)} size=\"sm\">\n                Onboarding guide\n              </Button>\n              <Button variant=\"link\" className=\"text-primary\" asChild size=\"sm\">\n                <a href={DAYTONA_DOCS_URL} target=\"_blank\" rel=\"noopener noreferrer\" className=\"text-primary\">\n                  Docs\n                </a>\n              </Button>\n            </>\n          )}\n          <CreateSandboxSheet />\n        </div>\n      </PageHeader>\n      <PageContent size=\"full\" className=\"flex-1 max-h-[calc(100vh-65px)]\">\n        <SandboxTable\n          sandboxIsLoading={sandboxIsLoading}\n          sandboxStateIsTransitioning={sandboxStateIsTransitioning}\n          handleStart={handleStart}\n          handleStop={handleStop}\n          handleDelete={(id: string) => {\n            setSandboxToDelete(id)\n            setShowDeleteDialog(true)\n          }}\n          handleBulkDelete={handleBulkDelete}\n          handleBulkStart={handleBulkStart}\n          handleBulkStop={handleBulkStop}\n          handleBulkArchive={handleBulkArchive}\n          handleArchive={handleArchive}\n          handleVnc={handleVnc}\n          getWebTerminalUrl={getWebTerminalUrl}\n          handleCreateSshAccess={openCreateSshDialog}\n          handleRevokeSshAccess={openRevokeSshDialog}\n          handleRefresh={handleRefresh}\n          isRefreshing={sandboxDataIsRefreshing}\n          data={sandboxesData?.items || []}\n          loading={sandboxesDataIsLoading}\n          snapshots={snapshotsData?.items || []}\n          snapshotsDataIsLoading={snapshotsDataIsLoading}\n          snapshotsDataHasMore={snapshotsDataHasMore}\n          onChangeSnapshotSearchValue={(name?: string) => handleSnapshotFiltersChange({ name })}\n          regionsData={regionsData || []}\n          regionsDataIsLoading={regionsDataIsLoading}\n          onRowClick={(sandbox: Sandbox) => {\n            setSelectedSandbox(sandbox)\n            setShowSandboxDetails(true)\n          }}\n          pageCount={sandboxesData?.totalPages || 0}\n          totalItems={sandboxesData?.total || 0}\n          onPaginationChange={handlePaginationChange}\n          pagination={{\n            pageIndex: paginationParams.pageIndex,\n            pageSize: paginationParams.pageSize,\n          }}\n          sorting={sorting}\n          onSortingChange={handleSortingChange}\n          filters={filters}\n          onFiltersChange={handleFiltersChange}\n          handleRecover={handleRecover}\n          getRegionName={getRegionName}\n          handleScreenRecordings={handleScreenRecordings}\n        />\n\n        {sandboxToDelete && (\n          <AlertDialog\n            open={showDeleteDialog}\n            onOpenChange={(isOpen) => {\n              setShowDeleteDialog(isOpen)\n              if (!isOpen) {\n                setSandboxToDelete(null)\n              }\n            }}\n          >\n            <AlertDialogContent>\n              <AlertDialogHeader>\n                <AlertDialogTitle>Confirm Sandbox Deletion</AlertDialogTitle>\n                <AlertDialogDescription>\n                  Are you sure you want to delete this sandbox? This action cannot be undone.\n                </AlertDialogDescription>\n              </AlertDialogHeader>\n              <AlertDialogFooter>\n                <AlertDialogCancel>Cancel</AlertDialogCancel>\n                <AlertDialogAction\n                  variant=\"destructive\"\n                  onClick={() => handleDelete(sandboxToDelete)}\n                  disabled={sandboxIsLoading[sandboxToDelete]}\n                >\n                  {sandboxIsLoading[sandboxToDelete] ? 'Deleting...' : 'Delete'}\n                </AlertDialogAction>\n              </AlertDialogFooter>\n            </AlertDialogContent>\n          </AlertDialog>\n        )}\n\n        {/* Create SSH Access Dialog */}\n        <AlertDialog\n          open={showCreateSshDialog}\n          onOpenChange={(isOpen) => {\n            setShowCreateSshDialog(isOpen)\n            if (!isOpen) {\n              setSshAccess(null)\n              setSshExpiryMinutes(60)\n              setSshSandboxId('')\n            }\n          }}\n        >\n          <AlertDialogContent>\n            <AlertDialogHeader>\n              <AlertDialogTitle>Create SSH Access</AlertDialogTitle>\n              <AlertDialogDescription>\n                {sshAccess\n                  ? 'SSH access has been created successfully. Use the token below to connect:'\n                  : 'Set the expiration time for SSH access:'}\n              </AlertDialogDescription>\n            </AlertDialogHeader>\n            <div className=\"space-y-4\">\n              {!sshAccess ? (\n                <div className=\"space-y-3\">\n                  <Label className=\"text-sm font-medium\">Expiry (minutes):</Label>\n                  <input\n                    type=\"number\"\n                    min=\"1\"\n                    max=\"1440\"\n                    value={sshExpiryMinutes}\n                    onChange={(e) => setSshExpiryMinutes(Number(e.target.value))}\n                    className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none\"\n                  />\n                </div>\n              ) : (\n                <div className=\"p-3 flex justify-between items-center rounded-md bg-green-100 text-green-600 dark:bg-green-900/50 dark:text-green-400\">\n                  <span className=\"overflow-x-auto pr-2 cursor-text select-all\">{sshAccess.sshCommand}</span>\n                  {(copied === 'SSH Command' && <Check className=\"w-4 h-4\" />) || (\n                    <Copy\n                      className=\"w-4 h-4 cursor-pointer\"\n                      onClick={() => copyToClipboard(sshAccess.sshCommand, 'SSH Command')}\n                    />\n                  )}\n                </div>\n              )}\n            </div>\n            <AlertDialogFooter>\n              {!sshAccess ? (\n                <>\n                  <AlertDialogCancel>Cancel</AlertDialogCancel>\n                  <AlertDialogAction\n                    onClick={() => handleCreateSshAccess(sshSandboxId)}\n                    disabled={!sshSandboxId}\n                    className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n                  >\n                    Create\n                  </AlertDialogAction>\n                </>\n              ) : (\n                <AlertDialogAction\n                  onClick={() => setShowCreateSshDialog(false)}\n                  className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n                >\n                  Close\n                </AlertDialogAction>\n              )}\n            </AlertDialogFooter>\n          </AlertDialogContent>\n        </AlertDialog>\n\n        {/* Revoke SSH Access Dialog */}\n        <AlertDialog\n          open={showRevokeSshDialog}\n          onOpenChange={(isOpen) => {\n            setShowRevokeSshDialog(isOpen)\n            if (!isOpen) {\n              setRevokeSshToken('')\n              setSshSandboxId('')\n            }\n          }}\n        >\n          <AlertDialogContent>\n            <AlertDialogHeader>\n              <AlertDialogTitle>Revoke SSH Access</AlertDialogTitle>\n              <AlertDialogDescription>Enter the SSH access token you want to revoke:</AlertDialogDescription>\n            </AlertDialogHeader>\n            <div className=\"space-y-4\">\n              <div className=\"space-y-3\">\n                <label className=\"text-sm font-medium\">SSH Token:</label>\n                <input\n                  type=\"text\"\n                  value={revokeSshToken}\n                  onChange={(e) => setRevokeSshToken(e.target.value)}\n                  placeholder=\"Enter SSH token to revoke\"\n                  className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\"\n                />\n              </div>\n            </div>\n            <AlertDialogFooter>\n              <AlertDialogCancel>Cancel</AlertDialogCancel>\n              <AlertDialogAction\n                onClick={() => handleRevokeSshAccess(sshSandboxId)}\n                disabled={!revokeSshToken.trim() || !sshSandboxId}\n                className=\"bg-secondary text-secondary-foreground hover:bg-secondary/80\"\n              >\n                Revoke Access\n              </AlertDialogAction>\n            </AlertDialogFooter>\n          </AlertDialogContent>\n        </AlertDialog>\n\n        <SandboxDetailsSheet\n          sandbox={selectedSandbox}\n          open={showSandboxDetails}\n          onOpenChange={setShowSandboxDetails}\n          sandboxIsLoading={sandboxIsLoading}\n          handleStart={handleStart}\n          handleStop={handleStop}\n          handleDelete={(id) => {\n            setSandboxToDelete(id)\n            setShowDeleteDialog(true)\n            setShowSandboxDetails(false)\n          }}\n          handleArchive={handleArchive}\n          getWebTerminalUrl={getWebTerminalUrl}\n          writePermitted={authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER}\n          deletePermitted={authenticatedUserOrganizationMember?.role === OrganizationUserRoleEnum.OWNER}\n          handleRecover={handleRecover}\n          getRegionName={getRegionName}\n        />\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default Sandboxes\n"
  },
  {
    "path": "apps/dashboard/src/pages/Snapshots.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { CreateSnapshotDialog } from '@/components/snapshots/CreateSnapshotDialog'\nimport { SnapshotTable } from '@/components/snapshots/SnapshotTable'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog'\nimport { DEFAULT_PAGE_SIZE } from '@/constants/Pagination'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport {\n  DEFAULT_SNAPSHOT_SORTING,\n  SnapshotQueryParams,\n  SnapshotSorting,\n  useSnapshotsQuery,\n} from '@/hooks/queries/useSnapshotsQuery'\nimport { useApi } from '@/hooks/useApi'\nimport { useNotificationSocket } from '@/hooks/useNotificationSocket'\nimport { useRegions } from '@/hooks/useRegions'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { createBulkActionToast } from '@/lib/bulk-action-toast'\nimport { handleApiError } from '@/lib/error-handling'\nimport { pluralize } from '@/lib/utils'\nimport { OrganizationRolePermissionsEnum, PaginatedSnapshots, SnapshotDto, SnapshotState } from '@daytonaio/api-client'\nimport { useQueryClient } from '@tanstack/react-query'\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { toast } from 'sonner'\n\nconst Snapshots: React.FC = () => {\n  const { notificationSocket } = useNotificationSocket()\n  const queryClient = useQueryClient()\n\n  const { snapshotApi } = useApi()\n  const { getRegionName } = useRegions()\n  const [loadingSnapshots, setLoadingSnapshots] = useState<Record<string, boolean>>({})\n  const [snapshotToDelete, setSnapshotToDelete] = useState<SnapshotDto | null>(null)\n  const [showDeleteDialog, setShowDeleteDialog] = useState(false)\n\n  const { selectedOrganization, authenticatedUserHasPermission } = useSelectedOrganization()\n\n  const [paginationParams, setPaginationParams] = useState({\n    pageIndex: 0,\n    pageSize: DEFAULT_PAGE_SIZE,\n  })\n\n  const [sorting, setSorting] = useState<SnapshotSorting>(DEFAULT_SNAPSHOT_SORTING)\n\n  const queryParams = useMemo<SnapshotQueryParams>(\n    () => ({\n      page: paginationParams.pageIndex + 1,\n      pageSize: paginationParams.pageSize,\n      sorting,\n    }),\n    [paginationParams, sorting],\n  )\n\n  const baseQueryKey = useMemo(() => queryKeys.snapshots.all, [])\n\n  const queryKey = useMemo(\n    () => queryKeys.snapshots.list(selectedOrganization?.id ?? '', queryParams),\n    [selectedOrganization?.id, queryParams],\n  )\n\n  const {\n    data: snapshotsData,\n    isLoading: snapshotsDataIsLoading,\n    error: snapshotsDataError,\n  } = useSnapshotsQuery(queryParams)\n\n  useEffect(() => {\n    if (snapshotsDataError) {\n      handleApiError(snapshotsDataError, 'Failed to fetch snapshots')\n    }\n  }, [snapshotsDataError])\n\n  const updateSnapshotInCache = useCallback(\n    (snapshotId: string, updates: Partial<SnapshotDto>) => {\n      queryClient.setQueryData(queryKey, (oldData: PaginatedSnapshots | undefined) => {\n        if (!oldData) return oldData\n        return {\n          ...oldData,\n          items: oldData.items.map((snapshot) => (snapshot.id === snapshotId ? { ...snapshot, ...updates } : snapshot)),\n        }\n      })\n    },\n    [queryClient, queryKey],\n  )\n\n  const markAllSnapshotQueriesAsStale = useCallback(\n    async (shouldRefetchActiveQueries = false) => {\n      queryClient.invalidateQueries({\n        queryKey: baseQueryKey,\n        refetchType: shouldRefetchActiveQueries ? 'active' : 'none',\n      })\n    },\n    [queryClient, baseQueryKey],\n  )\n\n  const handlePaginationChange = useCallback(({ pageIndex, pageSize }: { pageIndex: number; pageSize: number }) => {\n    setPaginationParams({ pageIndex, pageSize })\n  }, [])\n\n  const handleSortingChange = useCallback((newSorting: SnapshotSorting) => {\n    setSorting(newSorting)\n    setPaginationParams((prev) => ({ ...prev, pageIndex: 0 }))\n  }, [])\n\n  useEffect(() => {\n    const handleSnapshotCreatedEvent = () => {\n      markAllSnapshotQueriesAsStale(true)\n    }\n\n    const handleSnapshotStateUpdatedEvent = (data: {\n      snapshot: SnapshotDto\n      oldState: SnapshotState\n      newState: SnapshotState\n    }) => {\n      updateSnapshotInCache(data.snapshot.id, data.snapshot)\n    }\n\n    const handleSnapshotRemovedEvent = () => {\n      markAllSnapshotQueriesAsStale(true)\n    }\n\n    if (!notificationSocket) {\n      return\n    }\n\n    notificationSocket.on('snapshot.created', handleSnapshotCreatedEvent)\n    notificationSocket.on('snapshot.state.updated', handleSnapshotStateUpdatedEvent)\n    notificationSocket.on('snapshot.removed', handleSnapshotRemovedEvent)\n\n    return () => {\n      notificationSocket.off('snapshot.created', handleSnapshotCreatedEvent)\n      notificationSocket.off('snapshot.state.updated', handleSnapshotStateUpdatedEvent)\n      notificationSocket.off('snapshot.removed', handleSnapshotRemovedEvent)\n    }\n  }, [notificationSocket, markAllSnapshotQueriesAsStale, updateSnapshotInCache])\n\n  useEffect(() => {\n    if (snapshotsData?.items.length === 0 && paginationParams.pageIndex > 0) {\n      setPaginationParams((prev) => ({\n        ...prev,\n        pageIndex: prev.pageIndex - 1,\n      }))\n    }\n  }, [snapshotsData?.items.length, paginationParams.pageIndex])\n\n  const handleDelete = async (snapshot: SnapshotDto) => {\n    setLoadingSnapshots((prev) => ({ ...prev, [snapshot.id]: true }))\n    updateSnapshotInCache(snapshot.id, { state: SnapshotState.REMOVING })\n\n    try {\n      await snapshotApi.removeSnapshot(snapshot.id, selectedOrganization?.id)\n      setSnapshotToDelete(null)\n      setShowDeleteDialog(false)\n      toast.success(`Deleting snapshot ${snapshot.name}`)\n    } catch (error) {\n      handleApiError(error, 'Failed to delete snapshot')\n      updateSnapshotInCache(snapshot.id, { state: snapshot.state })\n    } finally {\n      setLoadingSnapshots((prev) => ({ ...prev, [snapshot.id]: false }))\n    }\n  }\n\n  const handleActivate = async (snapshot: SnapshotDto) => {\n    setLoadingSnapshots((prev) => ({ ...prev, [snapshot.id]: true }))\n    updateSnapshotInCache(snapshot.id, { state: SnapshotState.PENDING })\n\n    try {\n      await snapshotApi.activateSnapshot(snapshot.id, selectedOrganization?.id)\n      toast.success(`Activating snapshot ${snapshot.name}`)\n    } catch (error) {\n      handleApiError(error, 'Failed to activate snapshot')\n      updateSnapshotInCache(snapshot.id, { state: snapshot.state })\n    } finally {\n      setLoadingSnapshots((prev) => ({ ...prev, [snapshot.id]: false }))\n    }\n  }\n\n  const handleDeactivate = async (snapshot: SnapshotDto) => {\n    setLoadingSnapshots((prev) => ({ ...prev, [snapshot.id]: true }))\n    updateSnapshotInCache(snapshot.id, { state: SnapshotState.INACTIVE })\n\n    try {\n      await snapshotApi.deactivateSnapshot(snapshot.id, selectedOrganization?.id)\n      toast.success(`Deactivating snapshot ${snapshot.name}`)\n    } catch (error) {\n      handleApiError(error, 'Failed to deactivate snapshot')\n      updateSnapshotInCache(snapshot.id, { state: snapshot.state })\n    } finally {\n      setLoadingSnapshots((prev) => ({ ...prev, [snapshot.id]: false }))\n    }\n  }\n\n  const writePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_SNAPSHOTS),\n    [authenticatedUserHasPermission],\n  )\n\n  const executeBulkAction = useCallback(\n    async ({\n      ids,\n      actionName,\n      optimisticState,\n      apiCall,\n      toastMessages,\n    }: {\n      ids: string[]\n      actionName: string\n      optimisticState: SnapshotState\n      apiCall: (id: string) => Promise<unknown>\n      toastMessages: {\n        successTitle: string\n        errorTitle: string\n        warningTitle: string\n        canceledTitle: string\n      }\n    }) => {\n      const previousStatesById = new Map((snapshotsData?.items ?? []).map((snapshot) => [snapshot.id, snapshot.state]))\n\n      let isCancelled = false\n      let processedCount = 0\n      let successCount = 0\n      let failureCount = 0\n\n      const totalLabel = pluralize(ids.length, 'snapshot', 'snapshots')\n      const onCancel = () => {\n        isCancelled = true\n      }\n\n      const bulkToast = createBulkActionToast(`${actionName} 0 of ${totalLabel}.`, {\n        action: { label: 'Cancel', onClick: onCancel },\n      })\n\n      try {\n        for (const id of ids) {\n          if (isCancelled) break\n\n          processedCount += 1\n          bulkToast.loading(`${actionName} ${processedCount} of ${totalLabel}.`, {\n            action: { label: 'Cancel', onClick: onCancel },\n          })\n\n          setLoadingSnapshots((prev) => ({ ...prev, [id]: true }))\n          updateSnapshotInCache(id, { state: optimisticState })\n\n          try {\n            await apiCall(id)\n            successCount += 1\n          } catch (error) {\n            failureCount += 1\n            updateSnapshotInCache(id, { state: previousStatesById.get(id) })\n            console.error(`${actionName} snapshot failed`, id, error)\n          } finally {\n            setLoadingSnapshots((prev) => ({ ...prev, [id]: false }))\n          }\n        }\n\n        await markAllSnapshotQueriesAsStale(true)\n        bulkToast.result({ successCount, failureCount }, toastMessages)\n      } catch (error) {\n        console.error(`${actionName} snapshots failed`, error)\n        bulkToast.error(`${actionName} snapshots failed.`)\n      }\n\n      return { successCount, failureCount }\n    },\n    [snapshotsData?.items, updateSnapshotInCache, markAllSnapshotQueriesAsStale],\n  )\n\n  const handleBulkDelete = (snapshots: SnapshotDto[]) =>\n    executeBulkAction({\n      ids: snapshots.map((s) => s.id),\n      actionName: 'Deleting',\n      optimisticState: SnapshotState.REMOVING,\n      apiCall: (id) => snapshotApi.removeSnapshot(id, selectedOrganization?.id),\n      toastMessages: {\n        successTitle: `${pluralize(snapshots.length, 'Snapshot', 'Snapshots')} deleted.`,\n        errorTitle: `Failed to delete ${pluralize(snapshots.length, 'snapshot', 'snapshots')}.`,\n        warningTitle: 'Failed to delete some snapshots.',\n        canceledTitle: 'Delete canceled.',\n      },\n    })\n\n  const handleBulkDeactivate = (snapshots: SnapshotDto[]) =>\n    executeBulkAction({\n      ids: snapshots.map((s) => s.id),\n      actionName: 'Deactivating',\n      optimisticState: SnapshotState.INACTIVE,\n      apiCall: (id) => snapshotApi.deactivateSnapshot(id, selectedOrganization?.id),\n      toastMessages: {\n        successTitle: `${pluralize(snapshots.length, 'Snapshot', 'Snapshots')} deactivated.`,\n        errorTitle: `Failed to deactivate ${pluralize(snapshots.length, 'snapshot', 'snapshots')}.`,\n        warningTitle: 'Failed to deactivate some snapshots.',\n        canceledTitle: 'Deactivate canceled.',\n      },\n    })\n\n  const handleBulkActivate = (snapshots: SnapshotDto[]) =>\n    executeBulkAction({\n      ids: snapshots.map((s) => s.id),\n      actionName: 'Activating',\n      optimisticState: SnapshotState.ACTIVE,\n      apiCall: (id) => snapshotApi.activateSnapshot(id, selectedOrganization?.id),\n      toastMessages: {\n        successTitle: `${pluralize(snapshots.length, 'Snapshot', 'Snapshots')} activated.`,\n        errorTitle: `Failed to activate ${pluralize(snapshots.length, 'snapshot', 'snapshots')}.`,\n        warningTitle: 'Failed to activate some snapshots.',\n        canceledTitle: 'Activate canceled.',\n      },\n    })\n\n  const dialogRef = useRef<{ open: () => void }>(null)\n\n  const handleCreateSnapshot = () => {\n    dialogRef.current?.open()\n  }\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Snapshots</PageTitle>\n        {writePermitted && <CreateSnapshotDialog className=\"ml-auto\" ref={dialogRef} />}\n      </PageHeader>\n\n      <PageContent size=\"full\">\n        <SnapshotTable\n          data={snapshotsData?.items ?? []}\n          loading={snapshotsDataIsLoading}\n          loadingSnapshots={loadingSnapshots}\n          getRegionName={getRegionName}\n          onDelete={(snapshot) => {\n            setSnapshotToDelete(snapshot)\n            setShowDeleteDialog(true)\n          }}\n          onBulkDelete={handleBulkDelete}\n          onBulkDeactivate={handleBulkDeactivate}\n          onBulkActivate={handleBulkActivate}\n          onActivate={handleActivate}\n          onDeactivate={handleDeactivate}\n          onCreateSnapshot={handleCreateSnapshot}\n          pageCount={snapshotsData?.totalPages ?? 0}\n          totalItems={snapshotsData?.total ?? 0}\n          onPaginationChange={handlePaginationChange}\n          pagination={{\n            pageIndex: paginationParams.pageIndex,\n            pageSize: paginationParams.pageSize,\n          }}\n          sorting={sorting}\n          onSortingChange={handleSortingChange}\n        />\n\n        {snapshotToDelete && (\n          <Dialog\n            open={showDeleteDialog}\n            onOpenChange={(isOpen) => {\n              setShowDeleteDialog(isOpen)\n              if (!isOpen) {\n                setSnapshotToDelete(null)\n              }\n            }}\n          >\n            <DialogContent>\n              <DialogHeader>\n                <DialogTitle>Confirm Snapshot Deletion</DialogTitle>\n                <DialogDescription>\n                  Are you sure you want to delete this snapshot? This action cannot be undone.\n                </DialogDescription>\n              </DialogHeader>\n              <DialogFooter>\n                <DialogClose asChild>\n                  <Button type=\"button\" variant=\"secondary\">\n                    Cancel\n                  </Button>\n                </DialogClose>\n                <Button\n                  variant=\"destructive\"\n                  onClick={() => handleDelete(snapshotToDelete)}\n                  disabled={loadingSnapshots[snapshotToDelete.id]}\n                >\n                  {loadingSnapshots[snapshotToDelete.id] ? 'Deleting...' : 'Delete'}\n                </Button>\n              </DialogFooter>\n            </DialogContent>\n          </Dialog>\n        )}\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default Snapshots\n"
  },
  {
    "path": "apps/dashboard/src/pages/Spending.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { BillableMetricCode, OrganizationUsage } from '@/billing-api/types/OrganizationUsage'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { AggregatedUsageChart, ResourceUsageBreakdown, UsageSummary } from '@/components/spending/AggregatedUsageChart'\nimport { CostBreakdown } from '@/components/spending/CostBreakdown'\nimport { UsageChartData } from '@/components/spending/ResourceUsageChart'\nimport { SandboxUsageTable } from '@/components/spending/SandboxUsageTable'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardHeader, CardTitle } from '@/components/ui/card'\nimport { DateRangePicker, QuickRangesConfig } from '@/components/ui/date-range-picker'\nimport { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty'\nimport { Separator } from '@/components/ui/separator'\nimport { FeatureFlags } from '@/enums/FeatureFlags'\nimport { UsageTimelineChart } from '@/components/spending/UsageTimelineChart'\nimport { useAggregatedUsage, useSandboxesUsage, useUsageChart } from '@/hooks/queries/useAnalyticsUsage'\nimport { useOrganizationUsageOverviewQuery } from '@/hooks/queries/useOrganizationUsageOverviewQuery'\nimport { useOrganizationUsageQuery } from '@/hooks/queries/useOrganizationUsageQuery'\nimport { usePastOrganizationUsageQuery } from '@/hooks/queries/usePastOrganizationUsageQuery'\nimport { useConfig } from '@/hooks/useConfig'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { addDays, differenceInCalendarDays, subDays } from 'date-fns'\nimport { AlertCircle, BarChart3, RefreshCw } from 'lucide-react'\nimport { useFeatureFlagEnabled } from 'posthog-js/react'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { DateRange } from 'react-day-picker'\n\nconst analyticsQuickRanges: QuickRangesConfig = {\n  hours: [1, 6, 12, 24],\n  days: [7, 14, 30],\n}\n\nconst Spending = () => {\n  const { selectedOrganization } = useSelectedOrganization()\n  const config = useConfig()\n  const spendingEnabled = useFeatureFlagEnabled(FeatureFlags.SANDBOX_SPENDING)\n  const analyticsAvailable = spendingEnabled && !!config.analyticsApiUrl\n\n  const [analyticsDateRange, setAnalyticsDateRange] = useState<DateRange>(() => {\n    const now = new Date()\n    return { from: subDays(now, 30), to: now }\n  })\n\n  const handleAnalyticsDateRangeChange = useCallback((range: DateRange) => {\n    if (range.from && range.to) {\n      const days = differenceInCalendarDays(range.to, range.from)\n      if (days > 30) {\n        setAnalyticsDateRange({ from: range.from, to: addDays(range.from, 30) })\n        return\n      }\n    }\n    setAnalyticsDateRange(range)\n  }, [])\n\n  const [selectedChartRegion, setSelectedChartRegion] = useState<string | undefined>(undefined)\n  const hasDefaultedRegion = useRef(false)\n\n  const analyticsParams = {\n    from: analyticsDateRange.from ?? subDays(new Date(), 30),\n    to: analyticsDateRange.to ?? new Date(),\n    enabled: analyticsAvailable && !!selectedOrganization,\n  }\n\n  const {\n    data: aggregatedUsage,\n    isLoading: aggregatedLoading,\n    isError: aggregatedError,\n    refetch: refetchAggregated,\n  } = useAggregatedUsage(analyticsParams)\n  const {\n    data: sandboxesUsage,\n    isLoading: sandboxesLoading,\n    isError: sandboxesError,\n    refetch: refetchSandboxes,\n  } = useSandboxesUsage(analyticsParams)\n  const { data: usageChartPoints, isLoading: chartLoading } = useUsageChart({\n    ...analyticsParams,\n    region: selectedChartRegion,\n  })\n\n  const { data: usageOverview } = useOrganizationUsageOverviewQuery({\n    organizationId: selectedOrganization?.id ?? '',\n  })\n\n  // Default chart region to the organization's default region (only once)\n  useEffect(() => {\n    if (hasDefaultedRegion.current) return\n    const regionUsage = usageOverview?.regionUsage\n    if (!regionUsage?.length) return\n    hasDefaultedRegion.current = true\n    const defaultRegionId = selectedOrganization?.defaultRegionId\n    if (defaultRegionId && regionUsage.some((r) => r.regionId === defaultRegionId)) {\n      setSelectedChartRegion(defaultRegionId)\n    } else {\n      setSelectedChartRegion(regionUsage[0].regionId)\n    }\n  }, [usageOverview?.regionUsage, selectedOrganization?.defaultRegionId])\n\n  const {\n    data: currentOrganizationUsage,\n    isLoading: currentUsageLoading,\n    isError: currentUsageError,\n    refetch: refetchCurrentUsage,\n  } = useOrganizationUsageQuery({\n    organizationId: selectedOrganization?.id ?? '',\n    enabled: !!selectedOrganization,\n  })\n\n  const {\n    data: pastOrganizationUsage,\n    isLoading: pastUsageLoading,\n    isError: pastUsageError,\n    refetch: refetchPastUsage,\n  } = usePastOrganizationUsageQuery({\n    organizationId: selectedOrganization?.id ?? '',\n    enabled: !!selectedOrganization,\n  })\n\n  const sortedPastUsage = useMemo(\n    () => [...(pastOrganizationUsage ?? [])].sort((a, b) => new Date(a.from).getTime() - new Date(b.from).getTime()),\n    [pastOrganizationUsage],\n  )\n\n  const usageChartData = useMemo(\n    () =>\n      [...sortedPastUsage, ...(currentOrganizationUsage ? [currentOrganizationUsage] : [])].map(\n        convertUsageToChartData,\n      ),\n    [sortedPastUsage, currentOrganizationUsage],\n  )\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Spending</PageTitle>\n      </PageHeader>\n\n      <PageContent>\n        {analyticsAvailable && (\n          <Card>\n            <CardHeader className=\"flex flex-row items-center gap-2 space-y-0 border-b p-4\">\n              <div className=\"flex-1\">\n                <CardTitle>Resource Usage</CardTitle>\n              </div>\n              <DateRangePicker\n                value={analyticsDateRange}\n                onChange={handleAnalyticsDateRangeChange}\n                quickRangesEnabled\n                quickRanges={analyticsQuickRanges}\n                timeSelection\n                defaultSelectedQuickRange=\"Last 30 days\"\n                className=\"w-auto\"\n                contentAlign=\"end\"\n              />\n            </CardHeader>\n            {aggregatedError ? (\n              <Empty className=\"py-12\">\n                <EmptyHeader>\n                  <EmptyMedia variant=\"icon\" className=\"bg-destructive-background text-destructive\">\n                    <AlertCircle />\n                  </EmptyMedia>\n                  <EmptyTitle className=\"text-destructive\">Failed to load resource usage</EmptyTitle>\n                  <EmptyDescription>Something went wrong while fetching usage data. Please try again.</EmptyDescription>\n                </EmptyHeader>\n                <EmptyContent>\n                  <Button variant=\"secondary\" size=\"sm\" onClick={() => refetchAggregated()}>\n                    <RefreshCw />\n                    Retry\n                  </Button>\n                </EmptyContent>\n              </Empty>\n            ) : !aggregatedLoading && !aggregatedUsage?.sandboxCount ? (\n              <Empty className=\"py-12\">\n                <EmptyHeader>\n                  <EmptyMedia variant=\"icon\">\n                    <BarChart3 />\n                  </EmptyMedia>\n                  <EmptyTitle>No resource usage data</EmptyTitle>\n                  <EmptyDescription>\n                    Usage data will appear here once your sandboxes start consuming resources in the selected time\n                    range.\n                  </EmptyDescription>\n                </EmptyHeader>\n              </Empty>\n            ) : (\n              <>\n                <UsageSummary data={aggregatedUsage} isLoading={aggregatedLoading} />\n                <Separator />\n                <AggregatedUsageChart data={aggregatedUsage} isLoading={aggregatedLoading} />\n                <Separator />\n                <ResourceUsageBreakdown data={aggregatedUsage} />\n                <Separator />\n                <UsageTimelineChart\n                  data={usageChartPoints}\n                  isLoading={chartLoading}\n                  regionUsage={usageOverview?.regionUsage}\n                  selectedRegion={selectedChartRegion}\n                  onRegionChange={setSelectedChartRegion}\n                  dateRange={{ from: analyticsParams.from, to: analyticsParams.to }}\n                />\n              </>\n            )}\n            <Separator />\n            <div className=\"p-4\">\n              <p className=\"text-xl font-semibold leading-none tracking-tight\">Per-Sandbox Usage</p>\n              <p className=\"text-sm text-muted-foreground mt-2\">\n                Resource consumption broken down by individual sandbox.\n              </p>\n            </div>\n            {sandboxesError ? (\n              <Empty className=\"py-12\">\n                <EmptyHeader>\n                  <EmptyMedia variant=\"icon\" className=\"bg-destructive-background text-destructive\">\n                    <AlertCircle />\n                  </EmptyMedia>\n                  <EmptyTitle className=\"text-destructive\">Failed to load sandbox usage</EmptyTitle>\n                  <EmptyDescription>\n                    Something went wrong while fetching per-sandbox data. Please try again.\n                  </EmptyDescription>\n                </EmptyHeader>\n                <EmptyContent>\n                  <Button variant=\"secondary\" size=\"sm\" onClick={() => refetchSandboxes()}>\n                    <RefreshCw />\n                    Retry\n                  </Button>\n                </EmptyContent>\n              </Empty>\n            ) : !sandboxesLoading && !sandboxesUsage?.length ? (\n              <Empty className=\"py-12\">\n                <EmptyHeader>\n                  <EmptyMedia variant=\"icon\">\n                    <BarChart3 />\n                  </EmptyMedia>\n                  <EmptyTitle>No sandbox usage yet</EmptyTitle>\n                  <EmptyDescription>\n                    Once you create and run a sandbox, its resource consumption will appear here.\n                  </EmptyDescription>\n                </EmptyHeader>\n              </Empty>\n            ) : (\n              <SandboxUsageTable data={sandboxesUsage} isLoading={sandboxesLoading} />\n            )}\n          </Card>\n        )}\n\n        <CostBreakdown\n          usageData={usageChartData}\n          showTotal\n          isLoading={currentUsageLoading || pastUsageLoading}\n          isError={currentUsageError || pastUsageError}\n          onRetry={() => {\n            if (currentUsageError) refetchCurrentUsage()\n            if (pastUsageError) refetchPastUsage()\n          }}\n        />\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nfunction convertUsageToChartData(usage: OrganizationUsage): UsageChartData {\n  let ramGB = 0\n  let cpu = 0\n  let diskGB = 0\n  // let gpu = 0\n\n  for (const charge of usage.usageCharges) {\n    switch (charge.billableMetric) {\n      case BillableMetricCode.RAM_USAGE:\n        ramGB += Number(charge.amountCents) / 100\n        break\n      case BillableMetricCode.CPU_USAGE:\n        cpu += Number(charge.amountCents) / 100\n        break\n      case BillableMetricCode.DISK_USAGE:\n        diskGB += Number(charge.amountCents) / 100\n        break\n      // case BillableMetricCode.GPU_USAGE:\n      //   gpu += Number(charge.amountCents) / 100\n      //   break\n    }\n  }\n\n  return {\n    date: new Date(usage.from).toISOString(),\n    diskGB,\n    ramGB,\n    cpu,\n    // gpu,\n  }\n}\n\nexport default Spending\n"
  },
  {
    "path": "apps/dashboard/src/pages/UserOrganizationInvitations.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { OrganizationInvitationActionDialog } from '@/components/UserOrganizationInvitations/OrganizationInvitationActionDialog'\nimport { UserOrganizationInvitationTable } from '@/components/UserOrganizationInvitations/UserOrganizationInvitationTable'\nimport { useApi } from '@/hooks/useApi'\nimport { useOrganizations } from '@/hooks/useOrganizations'\nimport { useUserOrganizationInvitations } from '@/hooks/useUserOrganizationInvitations'\nimport { handleApiError } from '@/lib/error-handling'\nimport { OrganizationInvitation } from '@daytonaio/api-client'\nimport React, { useCallback, useEffect, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { toast } from 'sonner'\n\nconst UserOrganizationInvitations: React.FC = () => {\n  const { organizationsApi } = useApi()\n\n  const { refreshOrganizations } = useOrganizations()\n  const { setCount } = useUserOrganizationInvitations()\n\n  const [invitations, setInvitations] = useState<OrganizationInvitation[]>([])\n  const [loadingInvitations, setLoadingInvitations] = useState(true)\n\n  const [loadingInvitationAction, setLoadingInvitationAction] = useState<Record<string, boolean>>({})\n\n  const fetchInvitations = useCallback(\n    async (showTableLoadingState = true) => {\n      if (showTableLoadingState) {\n        setLoadingInvitations(true)\n      }\n      try {\n        const response = await organizationsApi.listOrganizationInvitationsForAuthenticatedUser()\n        setInvitations(response.data)\n        setCount(response.data.length)\n      } catch (error) {\n        handleApiError(error, 'Failed to fetch invitations')\n      } finally {\n        setLoadingInvitations(false)\n      }\n    },\n    [organizationsApi, setCount],\n  )\n\n  useEffect(() => {\n    fetchInvitations()\n  }, [fetchInvitations])\n\n  const [searchParams, setSearchParams] = useSearchParams()\n  const [invitationActionDialogOpen, setInvitationActionDialogOpen] = useState(false)\n  const [selectedInvitation, setSelectedInvitation] = useState<OrganizationInvitation | null>(null)\n\n  useEffect(() => {\n    const invitationId = searchParams.get('id')\n    if (invitationId && invitations.length > 0) {\n      const invitation = invitations.find((i) => i.id === invitationId)\n      if (invitation) {\n        setSelectedInvitation(invitation)\n        setInvitationActionDialogOpen(true)\n      }\n    }\n    // clear the query parameter after processing\n    if (invitationId && !loadingInvitations) {\n      const newSearchParams = new URLSearchParams(searchParams)\n      newSearchParams.delete('id')\n      setSearchParams(newSearchParams, { replace: true })\n    }\n  }, [searchParams, invitations, setSearchParams, loadingInvitations])\n\n  const handleAcceptInvitation = async (invitation: OrganizationInvitation): Promise<boolean> => {\n    setLoadingInvitationAction((prev) => ({ ...prev, [invitation.id]: true }))\n    try {\n      await organizationsApi.acceptOrganizationInvitation(invitation.id)\n      toast.success('Invitation accepted successfully')\n      await refreshOrganizations(invitation.organizationId)\n      await fetchInvitations(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to accept invitation')\n      return false\n    } finally {\n      setLoadingInvitationAction((prev) => ({ ...prev, [invitation.id]: false }))\n    }\n  }\n\n  const handleDeclineInvitation = async (invitation: OrganizationInvitation): Promise<boolean> => {\n    setLoadingInvitationAction((prev) => ({ ...prev, [invitation.id]: true }))\n    try {\n      await organizationsApi.declineOrganizationInvitation(invitation.id)\n      toast.success('Invitation declined successfully')\n      await fetchInvitations(false)\n      return true\n    } catch (error) {\n      handleApiError(error, 'Failed to decline invitation')\n      return false\n    } finally {\n      setLoadingInvitationAction((prev) => ({ ...prev, [invitation.id]: false }))\n    }\n  }\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Invitations</PageTitle>\n      </PageHeader>\n\n      <PageContent size=\"full\">\n        <UserOrganizationInvitationTable\n          data={invitations}\n          loadingData={loadingInvitations}\n          onAcceptInvitation={handleAcceptInvitation}\n          onDeclineInvitation={handleDeclineInvitation}\n          loadingInvitationAction={loadingInvitationAction}\n        />\n\n        {selectedInvitation && (\n          <OrganizationInvitationActionDialog\n            invitation={selectedInvitation}\n            open={invitationActionDialogOpen}\n            onOpenChange={setInvitationActionDialogOpen}\n            onAccept={handleAcceptInvitation}\n            onDecline={handleDeclineInvitation}\n          />\n        )}\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default UserOrganizationInvitations\n"
  },
  {
    "path": "apps/dashboard/src/pages/Volumes.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { Button } from '@/components/ui/button'\nimport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport { VolumeTable } from '@/components/VolumeTable'\nimport { useApi } from '@/hooks/useApi'\nimport { useNotificationSocket } from '@/hooks/useNotificationSocket'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { handleApiError } from '@/lib/error-handling'\nimport { OrganizationRolePermissionsEnum, VolumeDto, VolumeState } from '@daytonaio/api-client'\nimport { Plus } from 'lucide-react'\nimport React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { toast } from 'sonner'\n\nconst Volumes: React.FC = () => {\n  const { volumeApi } = useApi()\n  const { notificationSocket } = useNotificationSocket()\n\n  const [volumes, setVolumes] = useState<VolumeDto[]>([])\n  const [loadingVolumes, setLoadingVolumes] = useState(true)\n\n  const [showCreateDialog, setShowCreateDialog] = useState(false)\n  const [newVolumeName, setNewVolumeName] = useState('')\n  const [loadingCreate, setLoadingCreate] = useState(false)\n\n  const [volumeToDelete, setVolumeToDelete] = useState<VolumeDto | null>(null)\n  const [showDeleteDialog, setShowDeleteDialog] = useState(false)\n  const [processingVolumeAction, setProcessingVolumeAction] = useState<Record<string, boolean>>({})\n\n  const { selectedOrganization, authenticatedUserHasPermission } = useSelectedOrganization()\n\n  const fetchVolumes = useCallback(\n    async (showTableLoadingState = true) => {\n      if (!selectedOrganization) {\n        return\n      }\n      if (showTableLoadingState) {\n        setLoadingVolumes(true)\n      }\n      try {\n        const volumes = (await volumeApi.listVolumes(selectedOrganization.id)).data\n        setVolumes(volumes)\n      } catch (error) {\n        handleApiError(error, 'Failed to fetch volumes')\n      } finally {\n        setLoadingVolumes(false)\n      }\n    },\n    [volumeApi, selectedOrganization],\n  )\n\n  useEffect(() => {\n    fetchVolumes()\n  }, [fetchVolumes])\n\n  useEffect(() => {\n    const handleVolumeCreatedEvent = (volume: VolumeDto) => {\n      if (!volumes.some((v) => v.id === volume.id)) {\n        setVolumes((prev) => [volume, ...prev])\n      }\n    }\n\n    const handleVolumeStateUpdatedEvent = (data: {\n      volume: VolumeDto\n      oldState: VolumeState\n      newState: VolumeState\n    }) => {\n      if (data.newState === VolumeState.DELETED) {\n        setVolumes((prev) => prev.filter((v) => v.id !== data.volume.id))\n      } else if (!volumes.some((v) => v.id === data.volume.id)) {\n        setVolumes((prev) => [data.volume, ...prev])\n      } else {\n        setVolumes((prev) => prev.map((v) => (v.id === data.volume.id ? data.volume : v)))\n      }\n    }\n\n    const handleVolumeLastUsedAtUpdatedEvent = (volume: VolumeDto) => {\n      if (!volumes.some((v) => v.id === volume.id)) {\n        setVolumes((prev) => [volume, ...prev])\n      } else {\n        setVolumes((prev) => prev.map((v) => (v.id === volume.id ? volume : v)))\n      }\n    }\n\n    if (!notificationSocket) {\n      return\n    }\n\n    notificationSocket.on('volume.created', handleVolumeCreatedEvent)\n    notificationSocket.on('volume.state.updated', handleVolumeStateUpdatedEvent)\n    notificationSocket.on('volume.lastUsedAt.updated', handleVolumeLastUsedAtUpdatedEvent)\n\n    return () => {\n      notificationSocket.off('volume.created', handleVolumeCreatedEvent)\n      notificationSocket.off('volume.state.updated', handleVolumeStateUpdatedEvent)\n      notificationSocket.off('volume.lastUsedAt.updated', handleVolumeLastUsedAtUpdatedEvent)\n    }\n  }, [notificationSocket, volumes])\n\n  const handleCreate = async () => {\n    setLoadingCreate(true)\n    try {\n      await volumeApi.createVolume(\n        {\n          name: newVolumeName,\n        },\n        selectedOrganization?.id,\n      )\n      setShowCreateDialog(false)\n      setNewVolumeName('')\n      toast.success(`Creating volume ${newVolumeName}`)\n    } catch (error) {\n      handleApiError(error, 'Failed to create volume')\n    } finally {\n      setLoadingCreate(false)\n    }\n  }\n\n  const handleDelete = async (volume: VolumeDto) => {\n    setProcessingVolumeAction((prev) => ({ ...prev, [volume.id]: true }))\n\n    // Optimistically update the volume state\n    setVolumes((prev) => prev.map((v) => (v.id === volume.id ? { ...v, state: VolumeState.PENDING_DELETE } : v)))\n\n    try {\n      await volumeApi.deleteVolume(volume.id, selectedOrganization?.id)\n      setVolumeToDelete(null)\n      setShowDeleteDialog(false)\n      toast.success(`Deleting volume ${volume.name}`)\n    } catch (error) {\n      handleApiError(error, 'Failed to delete volume')\n      // Revert the optimistic update\n      setVolumes((prev) => prev.map((v) => (v.id === volume.id ? { ...v, state: volume.state } : v)))\n    } finally {\n      setProcessingVolumeAction((prev) => ({ ...prev, [volume.id]: false }))\n    }\n  }\n\n  const handleBulkDelete = async (volumes: VolumeDto[]) => {\n    setProcessingVolumeAction((prev) => ({ ...prev, ...volumes.reduce((acc, v) => ({ ...acc, [v.id]: true }), {}) }))\n\n    for (const volume of volumes) {\n      // Optimistically update the volume state\n      setVolumes((prev) => prev.map((v) => (v.id === volume.id ? { ...v, state: VolumeState.PENDING_DELETE } : v)))\n\n      try {\n        await volumeApi.deleteVolume(volume.id, selectedOrganization?.id)\n        toast.success(`Deleting volume ${volume.name}`)\n      } catch (error) {\n        handleApiError(error, 'Failed to delete volume')\n\n        // Revert the optimistic update\n        setVolumes((prev) => prev.map((v) => (v.id === volume.id ? { ...v, state: volume.state } : v)))\n\n        // Wait for user decision\n        const shouldContinue = window.confirm(\n          `Failed to delete volume ${volume.name}. Do you want to continue with the remaining volumes?`,\n        )\n\n        if (!shouldContinue) {\n          break\n        }\n      } finally {\n        setProcessingVolumeAction((prev) => ({ ...prev, [volume.id]: false }))\n      }\n    }\n  }\n\n  const writePermitted = useMemo(\n    () => authenticatedUserHasPermission(OrganizationRolePermissionsEnum.WRITE_VOLUMES),\n    [authenticatedUserHasPermission],\n  )\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Volumes</PageTitle>\n        <Dialog\n          open={showCreateDialog}\n          onOpenChange={(isOpen) => {\n            setShowCreateDialog(isOpen)\n            if (isOpen) {\n              return\n            }\n            setNewVolumeName('')\n          }}\n        >\n          {writePermitted && (\n            <DialogTrigger asChild>\n              <Button variant=\"default\" size=\"sm\" disabled={loadingVolumes} className=\"ml-auto\" title=\"Create Volume\">\n                <Plus className=\"w-4 h-4\" />\n                Create Volume\n              </Button>\n            </DialogTrigger>\n          )}\n          <DialogContent>\n            <DialogHeader>\n              <DialogTitle>Create New Volume</DialogTitle>\n              <DialogDescription>Instantly Access Shared Files with Volume Mounts</DialogDescription>\n            </DialogHeader>\n            <form\n              id=\"create-volume-form\"\n              className=\"space-y-6 overflow-y-auto px-1 pb-1\"\n              onSubmit={async (e) => {\n                e.preventDefault()\n                await handleCreate()\n              }}\n            >\n              <div className=\"space-y-3\">\n                <Label htmlFor=\"name\">Volume Name</Label>\n                <Input\n                  id=\"name\"\n                  value={newVolumeName}\n                  onChange={(e) => setNewVolumeName(e.target.value)}\n                  placeholder=\"my-volume\"\n                />\n              </div>\n            </form>\n            <DialogFooter>\n              <DialogClose asChild>\n                <Button type=\"button\" size=\"sm\" variant=\"secondary\">\n                  Cancel\n                </Button>\n              </DialogClose>\n              {loadingCreate ? (\n                <Button type=\"button\" size=\"sm\" variant=\"default\" disabled>\n                  Creating...\n                </Button>\n              ) : (\n                <Button\n                  type=\"submit\"\n                  size=\"sm\"\n                  form=\"create-volume-form\"\n                  variant=\"default\"\n                  disabled={!newVolumeName.trim()}\n                >\n                  Create\n                </Button>\n              )}\n            </DialogFooter>\n          </DialogContent>\n        </Dialog>\n      </PageHeader>\n\n      <PageContent size=\"full\">\n        <VolumeTable\n          data={volumes}\n          loading={loadingVolumes}\n          processingVolumeAction={processingVolumeAction}\n          onDelete={(volume) => {\n            setVolumeToDelete(volume)\n            setShowDeleteDialog(true)\n          }}\n          onBulkDelete={handleBulkDelete}\n        />\n\n        {volumeToDelete && (\n          <Dialog\n            open={showDeleteDialog}\n            onOpenChange={(isOpen) => {\n              setShowDeleteDialog(isOpen)\n              if (!isOpen) {\n                setVolumeToDelete(null)\n              }\n            }}\n          >\n            <DialogContent>\n              <DialogHeader>\n                <DialogTitle>Confirm Volume Deletion</DialogTitle>\n                <DialogDescription>\n                  Are you sure you want to delete this Volume? This action cannot be undone.\n                </DialogDescription>\n              </DialogHeader>\n              <DialogFooter>\n                <DialogClose asChild>\n                  <Button type=\"button\" variant=\"secondary\">\n                    Cancel\n                  </Button>\n                </DialogClose>\n                <Button\n                  variant=\"destructive\"\n                  onClick={() => handleDelete(volumeToDelete)}\n                  disabled={processingVolumeAction[volumeToDelete.id]}\n                >\n                  {processingVolumeAction[volumeToDelete.id] ? 'Deleting...' : 'Delete'}\n                </Button>\n              </DialogFooter>\n            </DialogContent>\n          </Dialog>\n        )}\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default Volumes\n"
  },
  {
    "path": "apps/dashboard/src/pages/Wallet.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { Invoice } from '@/billing-api/types/Invoice'\nimport { AutomaticTopUp } from '@/billing-api/types/OrganizationWallet'\nimport { InvoicesTable } from '@/components/Invoices'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText } from '@/components/ui/input-group'\nimport { Label } from '@/components/ui/label'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { Spinner } from '@/components/ui/spinner'\nimport { useCreateInvoicePaymentUrlMutation } from '@/hooks/mutations/useCreateInvoicePaymentUrlMutation'\nimport { useRedeemCouponMutation } from '@/hooks/mutations/useRedeemCouponMutation'\nimport { useSetAutomaticTopUpMutation } from '@/hooks/mutations/useSetAutomaticTopUpMutation'\nimport { useTopUpWalletMutation } from '@/hooks/mutations/useTopUpWalletMutation'\nimport { useVoidInvoiceMutation } from '@/hooks/mutations/useVoidInvoiceMutation'\nimport {\n  useFetchOwnerCheckoutUrlQuery,\n  useIsOwnerCheckoutUrlFetching,\n  useOwnerBillingPortalUrlQuery,\n  useOwnerInvoicesQuery,\n  useOwnerWalletQuery,\n} from '@/hooks/queries/billingQueries'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { formatAmount } from '@/lib/utils'\nimport { ArrowUpRight, CheckCircleIcon, InfoIcon, SparklesIcon, TriangleAlertIcon } from 'lucide-react'\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { NumericFormat } from 'react-number-format'\nimport { useAuth } from 'react-oidc-context'\nimport { toast } from 'sonner'\n\nconst DEFAULT_PAGE_SIZE = 10\n\nconst Wallet = () => {\n  const { selectedOrganization } = useSelectedOrganization()\n  const { user } = useAuth()\n  const [automaticTopUp, setAutomaticTopUp] = useState<AutomaticTopUp | undefined>(undefined)\n  const [couponCode, setCouponCode] = useState<string>('')\n  const [redeemCouponError, setRedeemCouponError] = useState<string | null>(null)\n  const [redeemCouponSuccess, setRedeemCouponSuccess] = useState<string | null>(null)\n  const [oneTimeTopUpAmount, setOneTimeTopUpAmount] = useState<number | undefined>(undefined)\n  const [selectedPreset, setSelectedPreset] = useState<number | null>(null)\n  const [invoicesPagination, setInvoicesPagination] = useState({\n    pageIndex: 0,\n    pageSize: DEFAULT_PAGE_SIZE,\n  })\n  const walletQuery = useOwnerWalletQuery({ refetchOnMount: 'always' })\n  const billingPortalUrlQuery = useOwnerBillingPortalUrlQuery()\n  const invoicesQuery = useOwnerInvoicesQuery(invoicesPagination.pageIndex + 1, invoicesPagination.pageSize)\n\n  const isCheckoutUrlLoading = useIsOwnerCheckoutUrlFetching()\n  const fetchCheckoutUrl = useFetchOwnerCheckoutUrlQuery()\n  const wallet = walletQuery.data\n  const billingPortalUrl = billingPortalUrlQuery.data\n  const setAutomaticTopUpMutation = useSetAutomaticTopUpMutation()\n  const redeemCouponMutation = useRedeemCouponMutation()\n  const topUpWalletMutation = useTopUpWalletMutation()\n  const createInvoicePaymentUrlMutation = useCreateInvoicePaymentUrlMutation()\n  const voidInvoiceMutation = useVoidInvoiceMutation()\n\n  useEffect(() => {\n    if (wallet?.automaticTopUp) {\n      setAutomaticTopUp(wallet.automaticTopUp)\n    }\n  }, [wallet])\n\n  const handleUpdatePaymentMethod = useCallback(async () => {\n    const newWindow = window.open('', '_blank')\n    try {\n      const data = await fetchCheckoutUrl()\n      if (newWindow) {\n        newWindow.location.href = data\n      }\n    } catch (error) {\n      newWindow?.close()\n      toast.error('Failed to fetch checkout url', {\n        description: String(error),\n      })\n    }\n  }, [fetchCheckoutUrl])\n\n  const handleSetAutomaticTopUp = useCallback(async () => {\n    if (!selectedOrganization) {\n      return\n    }\n\n    try {\n      await setAutomaticTopUpMutation.mutateAsync({\n        organizationId: selectedOrganization.id,\n        automaticTopUp,\n      })\n      toast.success('Automatic top up set successfully')\n    } catch (error) {\n      toast.error('Failed to set automatic top up', {\n        description: String(error),\n      })\n    }\n  }, [selectedOrganization, automaticTopUp, setAutomaticTopUpMutation])\n\n  const handleRedeemCoupon = useCallback(async () => {\n    if (!selectedOrganization || !couponCode) {\n      return\n    }\n\n    setRedeemCouponError(null)\n    setRedeemCouponSuccess(null)\n\n    try {\n      const message = await redeemCouponMutation.mutateAsync({\n        organizationId: selectedOrganization.id,\n        couponCode,\n      })\n      setRedeemCouponSuccess(message)\n      setTimeout(() => {\n        setRedeemCouponSuccess(null)\n      }, 3000)\n      setCouponCode('')\n    } catch (error) {\n      setRedeemCouponError(String(error))\n      console.error('Failed to redeem coupon:', error)\n    }\n  }, [selectedOrganization, couponCode, redeemCouponMutation])\n\n  const saveAutomaticTopUpDisabled = useMemo(() => {\n    if (setAutomaticTopUpMutation.isPending) {\n      return true\n    }\n\n    if (automaticTopUp?.thresholdAmount !== wallet?.automaticTopUp?.thresholdAmount) {\n      if (!wallet?.automaticTopUp) {\n        if ((automaticTopUp?.thresholdAmount || 0) !== 0) {\n          return false\n        }\n      } else {\n        return false\n      }\n    }\n\n    if (automaticTopUp?.targetAmount !== wallet?.automaticTopUp?.targetAmount) {\n      if (!wallet?.automaticTopUp) {\n        if ((automaticTopUp?.targetAmount || 0) !== 0) {\n          return false\n        }\n      } else {\n        return false\n      }\n    }\n\n    return true\n  }, [setAutomaticTopUpMutation.isPending, wallet, automaticTopUp])\n\n  const handleTopUpWallet = useCallback(async () => {\n    if (!selectedOrganization) {\n      return\n    }\n    const amount = selectedPreset ?? oneTimeTopUpAmount\n    if (!amount) {\n      return\n    }\n\n    const newWindow = window.open('', '_blank')\n    try {\n      const result = await topUpWalletMutation.mutateAsync({\n        organizationId: selectedOrganization.id,\n        amountCents: amount * 100,\n      })\n      if (newWindow) {\n        newWindow.location.href = result.url\n      }\n    } catch (error) {\n      newWindow?.close()\n      toast.error('Failed to initiate top-up', {\n        description: String(error),\n      })\n    }\n  }, [selectedOrganization, selectedPreset, oneTimeTopUpAmount, topUpWalletMutation])\n\n  const handlePayInvoice = useCallback(\n    async (invoice: Invoice) => {\n      if (!selectedOrganization) {\n        return\n      }\n\n      if (invoice.paymentStatus === 'pending' && invoice.totalDueAmountCents > 0) {\n        const newWindow = window.open('', '_blank')\n        try {\n          const result = await createInvoicePaymentUrlMutation.mutateAsync({\n            organizationId: selectedOrganization.id,\n            invoiceId: invoice.id,\n          })\n          if (newWindow) {\n            newWindow.location.href = result.url\n          }\n        } catch (error) {\n          newWindow?.close()\n          toast.error('Failed to open invoice', {\n            description: String(error),\n          })\n        }\n      }\n    },\n    [selectedOrganization, createInvoicePaymentUrlMutation],\n  )\n\n  const handleViewInvoice = useCallback(\n    async (invoice: Invoice) => {\n      if (!selectedOrganization) {\n        return\n      }\n\n      window.open(invoice.fileUrl, '_blank')\n    },\n    [selectedOrganization],\n  )\n\n  const handleVoidInvoice = useCallback(\n    async (invoice: Invoice) => {\n      if (!selectedOrganization) {\n        return\n      }\n      try {\n        await voidInvoiceMutation.mutateAsync({\n          organizationId: selectedOrganization.id,\n          invoiceId: invoice.id,\n        })\n        toast.success('Invoice voided successfully')\n      } catch (error) {\n        toast.error('Failed to void invoice', {\n          description: String(error),\n        })\n      }\n    },\n    [selectedOrganization, voidInvoiceMutation],\n  )\n\n  const isBillingLoading = walletQuery.isLoading && billingPortalUrlQuery.isLoading\n  const topUpEnabled =\n    wallet?.creditCardConnected && !topUpWalletMutation.isPending && (selectedPreset || oneTimeTopUpAmount)\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Wallet</PageTitle>\n      </PageHeader>\n\n      <PageContent>\n        {isBillingLoading && (\n          <div className=\"flex flex-col gap-6\">\n            <Card className=\"flex flex-col gap-4\">\n              <CardContent className=\"flex flex-col gap-4\">\n                <Skeleton className=\"h-5 w-full max-w-sm\" />\n                <div className=\"flex items-center gap-2\">\n                  <Skeleton className=\"h-10 flex-1\" />\n                  <Skeleton className=\"h-10 flex-1\" />\n                </div>\n                <Skeleton className=\" h-10\" />\n                <Skeleton className=\" h-10\" />\n              </CardContent>\n            </Card>\n            <Card className=\"flex flex-col gap-4\">\n              <CardContent className=\"flex flex-col gap-4\">\n                <Skeleton className=\"h-5 w-full max-w-sm\" />\n                <div className=\"flex items-center gap-2\">\n                  <Skeleton className=\"h-10 flex-1\" />\n                  <Skeleton className=\"h-10 flex-1\" />\n                </div>\n                <Skeleton className=\" h-10\" />\n              </CardContent>\n            </Card>\n          </div>\n        )}\n        {wallet && (\n          <>\n            {user && (\n              <>\n                {!user.profile.email_verified && (\n                  <Alert variant=\"info\">\n                    <TriangleAlertIcon />\n                    <AlertTitle>Verify your email</AlertTitle>\n                    <AlertDescription>\n                      {wallet.balanceCents && wallet.balanceCents > 0 ? (\n                        <>\n                          Please verify your email address to complete your account setup.\n                          <br />A verification email was sent to you.\n                        </>\n                      ) : (\n                        <>\n                          Verify your email address to recieve $100 of credits.\n                          <br />A verification email was sent to you.\n                        </>\n                      )}\n                    </AlertDescription>\n                  </Alert>\n                )}\n                {!wallet.creditCardConnected && user.profile.email_verified && selectedOrganization?.personal && (\n                  <Alert variant=\"neutral\">\n                    <SparklesIcon />\n                    <AlertDescription>Connect a credit card to receive an additional $100 of credits.</AlertDescription>\n                  </Alert>\n                )}\n              </>\n            )}\n            {wallet.hasFailedOrPendingInvoice && (\n              <Alert variant=\"destructive\">\n                <TriangleAlertIcon />\n                <AlertTitle>Outstanding invoices</AlertTitle>\n                <AlertDescription>\n                  You have failed or pending invoices that need to be resolved before adding new funds. Please review\n                  your invoices below and complete or void any outstanding payments.\n                </AlertDescription>\n              </Alert>\n            )}\n\n            <Card className=\"h-full\">\n              <CardHeader>\n                <CardTitle>Overview</CardTitle>\n              </CardHeader>\n              <CardContent className=\"\">\n                <div className=\"flex items-start sm:flex-row flex-col gap-4 sm:items-end justify-between\">\n                  <div className=\"flex gap-4 sm:gap-12 sm:flex-row flex-col\">\n                    <div className=\"flex flex-col gap-1\">\n                      <div className=\"\">Current balance</div>\n                      <div className=\"text-xl text-foreground font-semibold\">\n                        {formatAmount(wallet.ongoingBalanceCents)}\n                      </div>\n                    </div>\n                    <div className=\"flex flex-col gap-1\">\n                      <div className=\"\">Spent this month</div>\n                      <div className=\"text-xl font-semibold\">\n                        {formatAmount(wallet.balanceCents - wallet.ongoingBalanceCents)}\n                      </div>\n                    </div>\n                  </div>\n                  {billingPortalUrlQuery.isLoading ? (\n                    <Skeleton className=\"h-8 w-[160px]\" />\n                  ) : billingPortalUrl ? (\n                    <Button variant=\"link\" asChild className=\"flex items-center gap-2 !px-0\">\n                      <a\n                        href={`${billingPortalUrl}/customer-edit-information`}\n                        target=\"_blank\"\n                        rel=\"noopener noreferrer\"\n                      >\n                        Update Billing Info\n                        <ArrowUpRight />\n                      </a>\n                    </Button>\n                  ) : null}\n                </div>\n              </CardContent>\n              <CardContent className=\"border-t border-border\">\n                <div className=\"flex gap-4 items-center justify-between\">\n                  <div className=\"flex flex-col gap-1 items-start\">\n                    <div className=\"text-sm font-medium\">Payment method</div>\n                    {!wallet.creditCardConnected ? (\n                      <div className=\"text-sm text-muted-foreground\">Payment method not connected</div>\n                    ) : (\n                      <div className=\"text-sm text-muted-foreground flex items-center gap-2\">\n                        <CheckCircleIcon className=\"w-4 h-4 shrink-0\" /> Credit card connected\n                      </div>\n                    )}\n                  </div>\n                  {!wallet.creditCardConnected ? (\n                    <Button variant=\"default\" onClick={handleUpdatePaymentMethod} disabled={isCheckoutUrlLoading}>\n                      {isCheckoutUrlLoading && <Spinner />} Connect\n                    </Button>\n                  ) : (\n                    <Button variant=\"secondary\" onClick={handleUpdatePaymentMethod} disabled={isCheckoutUrlLoading}>\n                      {isCheckoutUrlLoading && <Spinner />} Update\n                    </Button>\n                  )}\n                </div>\n              </CardContent>\n\n              {user?.profile.email_verified && (\n                <CardContent className=\"border-t border-border\">\n                  <div className=\"flex gap-4 md:items-center justify-between md:flex-row flex-col\">\n                    <div className=\"flex flex-col gap-1 items-start flex-1\">\n                      <div className=\"text-sm font-medium\">Redeem coupon</div>\n                      {redeemCouponError ? (\n                        <div className=\"text-sm text-destructive\">{redeemCouponError}</div>\n                      ) : redeemCouponSuccess ? (\n                        <div className=\"text-sm text-success\">{redeemCouponSuccess}</div>\n                      ) : (\n                        <div className=\"text-sm text-muted-foreground\">Enter a coupon code to redeem your credits.</div>\n                      )}\n                    </div>\n\n                    <div className=\"flex gap-2 items-center\">\n                      <Input\n                        placeholder=\"Enter coupon code\"\n                        value={couponCode}\n                        onChange={(e) => setCouponCode(e.target.value)}\n                      />\n                      <Button\n                        variant=\"secondary\"\n                        onClick={handleRedeemCoupon}\n                        disabled={redeemCouponMutation.isPending}\n                      >\n                        {redeemCouponMutation.isPending && <Spinner />} Redeem\n                      </Button>\n                    </div>\n                  </div>\n                </CardContent>\n              )}\n            </Card>\n\n            {wallet.creditCardConnected && (\n              <Card className=\"w-full\">\n                <CardHeader>\n                  <CardTitle>Automatic top-up</CardTitle>\n                  <CardDescription>\n                    Set automatic top-up rules for your wallet.\n                    <br />\n                    The target amount must be at least $10 higher than the threshold amount.\n                  </CardDescription>\n                </CardHeader>\n                <CardContent>\n                  <div className=\"flex sm:flex-row flex-col gap-6\">\n                    <div className=\"flex flex-col gap-2 flex-1\">\n                      <Label htmlFor=\"thresholdAmount\">When balance is below</Label>\n                      <InputGroup>\n                        <InputGroupAddon>\n                          <InputGroupText>$</InputGroupText>\n                        </InputGroupAddon>\n                        <NumericFormat\n                          customInput={InputGroupInput}\n                          placeholder=\"0.00\"\n                          id=\"thresholdAmount\"\n                          inputMode=\"decimal\"\n                          thousandSeparator\n                          decimalScale={2}\n                          value={automaticTopUp?.thresholdAmount ?? ''}\n                          onValueChange={({ floatValue }) => {\n                            const value = floatValue ?? 0\n\n                            let targetAmount = automaticTopUp?.targetAmount ?? 0\n                            if (value > targetAmount - 10) {\n                              targetAmount = value + 10\n                            }\n\n                            setAutomaticTopUp({\n                              thresholdAmount: value,\n                              targetAmount,\n                            })\n                          }}\n                        />\n                        <InputGroupAddon align=\"inline-end\">\n                          <InputGroupText>USD</InputGroupText>\n                        </InputGroupAddon>\n                      </InputGroup>\n                    </div>\n\n                    <div className=\"flex flex-col gap-2 flex-1\">\n                      <Label htmlFor=\"targetAmount\">Bring balance to</Label>\n                      <InputGroup>\n                        <InputGroupAddon>\n                          <InputGroupText>$</InputGroupText>\n                        </InputGroupAddon>\n                        <NumericFormat\n                          placeholder=\"0.00\"\n                          customInput={InputGroupInput}\n                          id=\"targetAmount\"\n                          inputMode=\"decimal\"\n                          thousandSeparator\n                          decimalScale={2}\n                          value={automaticTopUp?.targetAmount ?? ''}\n                          onValueChange={({ floatValue }) => {\n                            const thresholdAmount = automaticTopUp?.thresholdAmount ?? 0\n                            setAutomaticTopUp({\n                              thresholdAmount,\n                              targetAmount: floatValue ?? 0,\n                            })\n                          }}\n                          onBlur={() => {\n                            const thresholdAmount = automaticTopUp?.thresholdAmount ?? 0\n                            const currentTarget = automaticTopUp?.targetAmount ?? 0\n\n                            if (currentTarget < thresholdAmount) {\n                              setAutomaticTopUp({\n                                thresholdAmount,\n                                targetAmount: thresholdAmount,\n                              })\n                            }\n                          }}\n                        />\n                        <InputGroupAddon align=\"inline-end\">\n                          <InputGroupText>USD</InputGroupText>\n                        </InputGroupAddon>\n                      </InputGroup>\n                    </div>\n                  </div>\n                </CardContent>\n                <CardFooter className=\"flex justify-between gap-2\">\n                  <div className=\"flex items-center gap-2 text-muted-foreground\">\n                    <InfoIcon className=\"w-4 h-4 shrink-0\" />{' '}\n                    <span className=\"text-sm \">Setting both values to 0 will disable automatic top-ups.</span>\n                  </div>\n                  <div className=\"flex gap-2 items-center ml-auto\">\n                    <Button\n                      onClick={handleSetAutomaticTopUp}\n                      disabled={saveAutomaticTopUpDisabled || walletQuery.isLoading || !wallet}\n                    >\n                      {setAutomaticTopUpMutation.isPending && <Spinner />} Save\n                    </Button>\n                  </div>\n                </CardFooter>\n              </Card>\n            )}\n\n            <Card className=\"w-full\">\n              <CardHeader>\n                <CardTitle>One time top-up</CardTitle>\n                <CardDescription>\n                  Add funds to your wallet instantly. Select a preset amount or enter a custom value.\n                </CardDescription>\n              </CardHeader>\n              <CardContent>\n                <div className=\"grid grid-cols-1 gap-10 items-center lg:grid-cols-2\">\n                  <div className=\"flex flex-col gap-2\">\n                    <Label className=\"text-sm font-medium\">Select amount</Label>\n                    <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-3\">\n                      {[25, 500, 1000, 2000].map((amount) => (\n                        <Button\n                          key={amount}\n                          type=\"button\"\n                          variant={selectedPreset === amount ? 'default' : 'outline'}\n                          size=\"default\"\n                          className=\"flex h-9\"\n                          onClick={() => {\n                            setSelectedPreset(amount)\n                            setOneTimeTopUpAmount(undefined)\n                          }}\n                        >\n                          <span className=\"font-semibold\">${amount.toLocaleString()}</span>\n                        </Button>\n                      ))}\n                    </div>\n                  </div>\n                  <div className=\"flex items-center gap-3 lg:hidden\">\n                    <div className=\"flex-1 h-px bg-border\" />\n                    <span className=\"text-sm text-muted-foreground\">or</span>\n                    <div className=\"flex-1 h-px bg-border\" />\n                  </div>\n                  <div className=\"flex flex-col gap-2\">\n                    <Label htmlFor=\"customTopUpAmount\" className=\"text-sm font-medium\">\n                      Enter custom amount\n                    </Label>\n                    <InputGroup>\n                      <InputGroupAddon>\n                        <InputGroupText>$</InputGroupText>\n                      </InputGroupAddon>\n                      <NumericFormat\n                        placeholder=\"0.00\"\n                        customInput={InputGroupInput}\n                        id=\"customTopUpAmount\"\n                        inputMode=\"decimal\"\n                        thousandSeparator\n                        decimalScale={2}\n                        value={oneTimeTopUpAmount ?? ''}\n                        onValueChange={({ floatValue }) => {\n                          const value = floatValue ?? undefined\n                          setOneTimeTopUpAmount(value)\n                          setSelectedPreset(null)\n                        }}\n                        onFocus={() => {\n                          setSelectedPreset(null)\n                        }}\n                      />\n                      <InputGroupAddon align=\"inline-end\">\n                        <InputGroupText>USD</InputGroupText>\n                      </InputGroupAddon>\n                    </InputGroup>\n                  </div>\n                </div>\n              </CardContent>\n              <CardFooter className=\"flex justify-between gap-2\">\n                <div className=\"text-sm text-muted-foreground\">\n                  You will be redirected to Stripe to complete the payment.\n                </div>\n                <Button onClick={handleTopUpWallet} disabled={!topUpEnabled} size=\"sm\">\n                  {topUpWalletMutation.isPending && <Spinner />}\n                  Top up\n                </Button>\n              </CardFooter>\n            </Card>\n\n            <Card className=\"w-full\">\n              <CardHeader>\n                <CardTitle>Invoices</CardTitle>\n                <CardDescription>\n                  View and download your billing invoices. All invoices are automatically generated and sent to your\n                  billing emails.\n                </CardDescription>\n              </CardHeader>\n              <CardContent>\n                <InvoicesTable\n                  data={invoicesQuery.data?.items ?? []}\n                  pagination={invoicesPagination}\n                  pageCount={invoicesQuery.data?.totalPages ?? 0}\n                  totalItems={invoicesQuery.data?.totalItems ?? 0}\n                  onPaginationChange={setInvoicesPagination}\n                  loading={invoicesQuery.isLoading}\n                  onViewInvoice={handleViewInvoice}\n                  onVoidInvoice={handleVoidInvoice}\n                  onPayInvoice={handlePayInvoice}\n                />\n              </CardContent>\n            </Card>\n          </>\n        )}\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default Wallet\n"
  },
  {
    "path": "apps/dashboard/src/pages/WebhookEndpointDetails.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CopyButton } from '@/components/CopyButton'\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { TimestampTooltip } from '@/components/TimestampTooltip'\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n} from '@/components/ui/alert-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { InputGroup, InputGroupButton, InputGroupInput } from '@/components/ui/input-group'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport DeliveryStatsLine from '@/components/Webhooks/DeliveryStatsLine'\nimport { EditEndpointDialog } from '@/components/Webhooks/EditEndpointDialog'\nimport { EndpointEventsTable } from '@/components/Webhooks/EndpointEventsTable'\nimport { RoutePath } from '@/enums/RoutePath'\nimport { useDeleteWebhookEndpointMutation } from '@/hooks/mutations/useDeleteWebhookEndpointMutation'\nimport { useReplayWebhookEventMutation } from '@/hooks/mutations/useReplayWebhookEventMutation'\nimport { useRotateWebhookSecretMutation } from '@/hooks/mutations/useRotateWebhookSecretMutation'\nimport { useUpdateWebhookEndpointMutation } from '@/hooks/mutations/useUpdateWebhookEndpointMutation'\nimport { handleApiError } from '@/lib/error-handling'\nimport { getMaskedToken, getRelativeTimeString } from '@/lib/utils'\nimport { ArrowLeft, Eye, EyeOff, Loader2, MoreHorizontal, RefreshCcw } from 'lucide-react'\nimport React, { useState } from 'react'\nimport { useNavigate, useParams } from 'react-router-dom'\nimport { toast } from 'sonner'\nimport { useAttemptedMessages, useEndpoint, useEndpointSecret, useEndpointStats } from 'svix-react'\n\nconst WebhookEndpointDetails: React.FC = () => {\n  const { endpointId } = useParams<{ endpointId: string }>()\n  const navigate = useNavigate()\n  const [isSecretRevealed, setIsSecretRevealed] = useState(false)\n  const [editDialogOpen, setEditDialogOpen] = useState(false)\n  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)\n  const [disableDialogOpen, setDisableDialogOpen] = useState(false)\n  const [rotateSecretDialogOpen, setRotateSecretDialogOpen] = useState(false)\n\n  const endpoint = useEndpoint(endpointId || '')\n  const secret = useEndpointSecret(endpointId || '')\n  const messages = useAttemptedMessages(endpointId || '', {})\n  const stats = useEndpointStats(endpointId || '')\n\n  const updateMutation = useUpdateWebhookEndpointMutation()\n  const deleteMutation = useDeleteWebhookEndpointMutation()\n  const rotateSecretMutation = useRotateWebhookSecretMutation()\n  const replayMutation = useReplayWebhookEventMutation()\n\n  const isMutating = updateMutation.isPending || deleteMutation.isPending || rotateSecretMutation.isPending\n\n  const isRefreshing = endpoint.loading || secret.loading || messages.loading || stats.loading\n\n  const statsIsLoading = !stats.data && stats.loading\n  const statsIsFetching = !!stats.data && stats.loading\n\n  const handleRetry = () => {\n    endpoint.reload()\n    secret.reload()\n    messages.reload()\n    stats.reload()\n  }\n\n  const handleDisable = async () => {\n    if (!endpoint.data) return\n    setDisableDialogOpen(false)\n    try {\n      await updateMutation.mutateAsync({\n        endpointId: endpoint.data.id,\n        update: { disabled: !endpoint.data.disabled },\n      })\n      toast.success('Endpoint updated')\n      endpoint.reload()\n    } catch (error) {\n      handleApiError(error, 'Failed to update endpoint')\n    }\n  }\n\n  const handleDelete = async () => {\n    if (!endpoint.data) return\n    try {\n      await deleteMutation.mutateAsync({ endpointId: endpoint.data.id })\n      toast.success('Endpoint deleted')\n      setDeleteDialogOpen(false)\n      navigate(RoutePath.WEBHOOKS)\n    } catch (error) {\n      handleApiError(error, 'Failed to delete endpoint')\n    }\n  }\n\n  const handleRotateSecret = async () => {\n    if (!endpoint.data) return\n    try {\n      await rotateSecretMutation.mutateAsync({ endpointId: endpoint.data.id })\n      toast.success('Secret rotated')\n      secret.reload()\n      setRotateSecretDialogOpen(false)\n    } catch (error) {\n      handleApiError(error, 'Failed to rotate secret')\n    }\n  }\n\n  const handleReplay = async (msgId: string) => {\n    if (!endpointId) return\n    try {\n      await replayMutation.mutateAsync({ endpointId, msgId })\n      toast.success('Event replayed')\n      messages.reload()\n      stats.reload()\n    } catch (error) {\n      handleApiError(error, 'Failed to replay event')\n    }\n  }\n\n  const handleEditSuccess = () => {\n    endpoint.reload()\n  }\n\n  const endpointData = endpoint.data\n  const relativeTime = endpointData ? getRelativeTimeString(endpointData.createdAt).relativeTimeString : null\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Webhooks</PageTitle>\n      </PageHeader>\n\n      <PageContent className=\"gap-6\">\n        <div className=\"flex items-center gap-3 min-w-0\">\n          <Button variant=\"ghost\" size=\"icon-sm\" className=\"shrink-0\" onClick={() => navigate(RoutePath.WEBHOOKS)}>\n            <ArrowLeft className=\"w-4 h-4\" />\n          </Button>\n          {endpoint.loading ? (\n            <>\n              <Skeleton className=\"h-6 w-48\" />\n              <Skeleton className=\"h-5 w-16\" />\n              <Skeleton className=\"h-4 w-24\" />\n            </>\n          ) : endpointData ? (\n            <>\n              <h2 className=\"text-lg font-medium truncate min-w-0\">{endpointData.description || 'Unnamed Endpoint'}</h2>\n              <Badge variant={endpointData.disabled ? 'secondary' : 'success'} className=\"shrink-0\">\n                {endpointData.disabled ? 'Disabled' : 'Enabled'}\n              </Badge>\n              <span className=\"text-sm text-muted-foreground shrink-0 hidden sm:inline\">•</span>\n              <TimestampTooltip\n                timestamp={\n                  typeof endpointData.createdAt === 'string'\n                    ? endpointData.createdAt\n                    : endpointData.createdAt.toISOString()\n                }\n              >\n                <span className=\"text-sm text-muted-foreground cursor-default shrink-0 hidden sm:inline\">\n                  {relativeTime}\n                </span>\n              </TimestampTooltip>\n              <div className=\"ml-auto flex items-center gap-2 shrink-0\">\n                <DropdownMenu>\n                  <DropdownMenuTrigger asChild>\n                    <Button variant=\"outline\" size=\"icon-sm\" disabled={isMutating}>\n                      <MoreHorizontal className=\"h-4 w-4\" />\n                    </Button>\n                  </DropdownMenuTrigger>\n                  <DropdownMenuContent align=\"end\">\n                    <DropdownMenuItem onClick={() => setEditDialogOpen(true)} className=\"cursor-pointer\">\n                      Edit\n                    </DropdownMenuItem>\n                    <DropdownMenuItem onClick={() => setDisableDialogOpen(true)} className=\"cursor-pointer\">\n                      {endpointData.disabled ? 'Enable' : 'Disable'}\n                    </DropdownMenuItem>\n                    <DropdownMenuSeparator />\n                    <DropdownMenuItem onClick={() => setRotateSecretDialogOpen(true)} className=\"cursor-pointer\">\n                      Rotate Secret\n                    </DropdownMenuItem>\n                    <DropdownMenuSeparator />\n                    <DropdownMenuItem\n                      variant=\"destructive\"\n                      onClick={() => setDeleteDialogOpen(true)}\n                      className=\"cursor-pointer\"\n                    >\n                      Delete\n                    </DropdownMenuItem>\n                  </DropdownMenuContent>\n                </DropdownMenu>\n                <Button variant=\"ghost\" size=\"icon-sm\" onClick={handleRetry} disabled={isRefreshing}>\n                  {isRefreshing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n                </Button>\n              </div>\n            </>\n          ) : null}\n        </div>\n\n        {endpoint.loading ? (\n          <div className=\"flex flex-col gap-4\">\n            <Card>\n              <CardHeader>\n                <CardTitle>Endpoint Configuration</CardTitle>\n              </CardHeader>\n              <CardContent className=\"p-4 flex flex-col gap-4\">\n                <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\n                  <div className=\"flex flex-col\">\n                    <div className=\"text-muted-foreground text-xs mb-1\">URL</div>\n                    <Skeleton className=\"h-9 w-full\" />\n                  </div>\n                  <div className=\"flex flex-col\">\n                    <div className=\"text-muted-foreground text-xs mb-1\">Signing Secret</div>\n                    <Skeleton className=\"h-9 w-full\" />\n                  </div>\n                </div>\n                <div>\n                  <div className=\"text-muted-foreground text-xs mb-1\">Listening For</div>\n                  <div className=\"flex flex-wrap gap-1.5\">\n                    <Skeleton className=\"h-5 w-24 rounded-full\" />\n                    <Skeleton className=\"h-5 w-32 rounded-full\" />\n                    <Skeleton className=\"h-5 w-20 rounded-full\" />\n                  </div>\n                </div>\n              </CardContent>\n            </Card>\n            <Card>\n              <CardHeader>\n                <CardTitle>Delivery Stats</CardTitle>\n              </CardHeader>\n              <CardContent>\n                <div className=\"flex flex-col gap-2\">\n                  <Skeleton className=\"h-2 w-full rounded-full\" />\n                  <div className=\"flex items-center gap-4\">\n                    <Skeleton className=\"h-3 w-20\" />\n                    <Skeleton className=\"h-3 w-16\" />\n                    <Skeleton className=\"h-3 w-18\" />\n                    <Skeleton className=\"h-3 w-18\" />\n                  </div>\n                </div>\n              </CardContent>\n            </Card>\n            <Card>\n              <CardHeader>\n                <CardTitle>Event History</CardTitle>\n              </CardHeader>\n              <CardContent>\n                <EndpointEventsTable data={[]} loading={true} onReplay={handleReplay} />\n              </CardContent>\n            </Card>\n          </div>\n        ) : endpoint.error || !endpointData ? (\n          <Card>\n            <CardHeader>\n              <CardTitle className=\"text-center\">Oops, something went wrong</CardTitle>\n            </CardHeader>\n            <CardContent className=\"flex justify-between items-center flex-col gap-3\">\n              <div>There was an error loading the endpoint details.</div>\n              <Button variant=\"outline\" onClick={handleRetry}>\n                <RefreshCcw className=\"mr-2 h-4 w-4\" />\n                Retry\n              </Button>\n            </CardContent>\n          </Card>\n        ) : (\n          <div className=\"flex flex-col gap-4\">\n            <Card>\n              <CardHeader>\n                <CardTitle>Endpoint Configuration</CardTitle>\n              </CardHeader>\n              <CardContent className=\"p-4 flex flex-col gap-4\">\n                <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-4\">\n                  <div className=\"flex flex-col\">\n                    <div className=\"text-muted-foreground text-xs mb-1\">URL</div>\n                    <InputGroup className=\"pr-1\">\n                      <InputGroupInput value={endpointData.url} readOnly className=\"font-mono text-sm\" />\n                      <CopyButton value={endpointData.url} size=\"icon-xs\" tooltipText=\"Copy URL\" />\n                    </InputGroup>\n                  </div>\n                  <div className=\"flex flex-col\">\n                    <div className=\"text-muted-foreground text-xs mb-1\">Signing Secret</div>\n                    {secret.loading ? (\n                      <Skeleton className=\"h-9 w-full\" />\n                    ) : secret.error ? (\n                      <span className=\"text-sm text-muted-foreground\">Failed to load</span>\n                    ) : secret.data ? (\n                      <InputGroup className=\"pr-1\">\n                        <InputGroupInput\n                          value={isSecretRevealed ? secret.data.key : getMaskedToken(secret.data.key)}\n                          readOnly\n                          className=\"font-mono text-sm\"\n                        />\n                        <InputGroupButton\n                          variant=\"ghost\"\n                          size=\"icon-xs\"\n                          onClick={() => setIsSecretRevealed(!isSecretRevealed)}\n                          title={isSecretRevealed ? 'Hide secret' : 'Reveal secret'}\n                        >\n                          {isSecretRevealed ? <EyeOff className=\"h-4 w-4\" /> : <Eye className=\"h-4 w-4\" />}\n                        </InputGroupButton>\n                        <CopyButton value={secret.data.key} size=\"icon-xs\" tooltipText=\"Copy Signing Secret\" />\n                      </InputGroup>\n                    ) : null}\n                  </div>\n                </div>\n                {endpointData.filterTypes && endpointData.filterTypes.length > 0 && (\n                  <div>\n                    <div className=\"text-muted-foreground text-xs mb-1\">Listening For</div>\n                    <div className=\"flex flex-wrap gap-1.5\">\n                      {endpointData.filterTypes.map((eventType) => (\n                        <Badge key={eventType} variant=\"secondary\" className=\"font-normal text-xs\">\n                          {eventType}\n                        </Badge>\n                      ))}\n                    </div>\n                  </div>\n                )}\n              </CardContent>\n            </Card>\n            <Card>\n              <CardHeader>\n                <CardTitle>Delivery Stats</CardTitle>\n              </CardHeader>\n              <CardContent>\n                {statsIsLoading ? (\n                  <div className=\"flex flex-col gap-2\">\n                    <Skeleton className=\"h-2 w-full rounded-full\" />\n                    <div className=\"flex items-center gap-4\">\n                      <Skeleton className=\"h-3 w-20\" />\n                      <Skeleton className=\"h-3 w-16\" />\n                      <Skeleton className=\"h-3 w-18\" />\n                      <Skeleton className=\"h-3 w-18\" />\n                    </div>\n                  </div>\n                ) : stats.data ? (\n                  <div className={statsIsFetching ? 'opacity-50 transition-opacity' : ''}>\n                    <DeliveryStatsLine stats={stats.data} />\n                  </div>\n                ) : null}\n              </CardContent>\n            </Card>\n            <Card>\n              <CardHeader>\n                <CardTitle>Event History</CardTitle>\n              </CardHeader>\n              <CardContent>\n                <EndpointEventsTable data={messages.data || []} loading={messages.loading} onReplay={handleReplay} />\n              </CardContent>\n            </Card>\n          </div>\n        )}\n      </PageContent>\n\n      <EditEndpointDialog\n        endpoint={endpoint.data || null}\n        open={editDialogOpen}\n        onOpenChange={setEditDialogOpen}\n        onSuccess={handleEditSuccess}\n      />\n\n      <AlertDialog open={disableDialogOpen} onOpenChange={setDisableDialogOpen}>\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>{endpoint.data?.disabled ? 'Enable' : 'Disable'} Webhook Endpoint</AlertDialogTitle>\n            <AlertDialogDescription>\n              Are you sure you want to {endpoint.data?.disabled ? 'enable' : 'disable'} this webhook endpoint?\n              {endpoint.data?.disabled\n                ? ' The endpoint will start receiving webhook events again.'\n                : ' The endpoint will stop receiving webhook events.'}\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <AlertDialogAction onClick={handleDisable}>\n              {endpoint.data?.disabled ? 'Enable' : 'Disable'}\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n\n      <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>Delete Webhook Endpoint</AlertDialogTitle>\n            <AlertDialogDescription>\n              Are you sure you want to delete this endpoint? This action cannot be undone. All webhook history for this\n              endpoint will be permanently deleted.\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <AlertDialogAction variant=\"destructive\" onClick={handleDelete} disabled={deleteMutation.isPending}>\n              {deleteMutation.isPending ? 'Deleting...' : 'Delete'}\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n\n      <AlertDialog open={rotateSecretDialogOpen} onOpenChange={setRotateSecretDialogOpen}>\n        <AlertDialogContent>\n          <AlertDialogHeader>\n            <AlertDialogTitle>Rotate Signing Secret</AlertDialogTitle>\n            <AlertDialogDescription>\n              Are you sure you want to rotate the signing secret? The current secret will be invalidated and you will\n              need to update your webhook handler with the new secret.\n            </AlertDialogDescription>\n          </AlertDialogHeader>\n          <AlertDialogFooter>\n            <AlertDialogCancel>Cancel</AlertDialogCancel>\n            <AlertDialogAction onClick={handleRotateSecret} disabled={rotateSecretMutation.isPending}>\n              {rotateSecretMutation.isPending ? 'Rotating...' : 'Rotate Secret'}\n            </AlertDialogAction>\n          </AlertDialogFooter>\n        </AlertDialogContent>\n      </AlertDialog>\n    </PageLayout>\n  )\n}\n\nexport default WebhookEndpointDetails\n"
  },
  {
    "path": "apps/dashboard/src/pages/Webhooks.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { CreateEndpointDialog } from '@/components/Webhooks/CreateEndpointDialog'\nimport { WebhooksEndpointTable } from '@/components/Webhooks/WebhooksEndpointTable'\nimport { WebhooksMessagesTable } from '@/components/Webhooks/WebhooksMessagesTable/WebhooksMessagesTable'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'\nimport { useDeleteWebhookEndpointMutation } from '@/hooks/mutations/useDeleteWebhookEndpointMutation'\nimport { useUpdateWebhookEndpointMutation } from '@/hooks/mutations/useUpdateWebhookEndpointMutation'\nimport { handleApiError } from '@/lib/error-handling'\nimport { RefreshCcw } from 'lucide-react'\nimport React, { useCallback, useState } from 'react'\nimport { toast } from 'sonner'\nimport { EndpointOut } from 'svix'\nimport { useEndpoints } from 'svix-react'\n\nconst Webhooks: React.FC = () => {\n  const endpoints = useEndpoints()\n  const [mutatingEndpointId, setMutatingEndpointId] = useState<string | null>(null)\n  const [activeTab, setActiveTab] = useState('endpoints')\n\n  const updateMutation = useUpdateWebhookEndpointMutation()\n  const deleteMutation = useDeleteWebhookEndpointMutation()\n\n  const handleDisable = useCallback(\n    async (endpoint: EndpointOut) => {\n      setMutatingEndpointId(endpoint.id)\n      try {\n        await updateMutation.mutateAsync({\n          endpointId: endpoint.id,\n          update: { disabled: !endpoint.disabled },\n        })\n        toast.success('Endpoint updated')\n        endpoints.reload()\n      } catch (error) {\n        handleApiError(error, 'Failed to update endpoint')\n      } finally {\n        setMutatingEndpointId(null)\n      }\n    },\n    [updateMutation, endpoints],\n  )\n\n  const handleDelete = useCallback(\n    async (endpoint: EndpointOut) => {\n      setMutatingEndpointId(endpoint.id)\n      try {\n        await deleteMutation.mutateAsync({ endpointId: endpoint.id })\n        toast.success('Endpoint deleted')\n        endpoints.reload()\n      } catch (error) {\n        handleApiError(error, 'Failed to delete endpoint')\n      } finally {\n        setMutatingEndpointId(null)\n      }\n    },\n    [deleteMutation, endpoints],\n  )\n\n  const handleSuccess = useCallback(() => {\n    endpoints.reload()\n  }, [endpoints])\n\n  const isLoadingEndpoint = useCallback(\n    (endpoint: EndpointOut) => {\n      return mutatingEndpointId === endpoint.id && (updateMutation.isPending || deleteMutation.isPending)\n    },\n    [mutatingEndpointId, updateMutation.isPending, deleteMutation.isPending],\n  )\n\n  if (endpoints.error) {\n    return (\n      <PageLayout>\n        <PageHeader>\n          <PageTitle>Webhooks</PageTitle>\n        </PageHeader>\n        <PageContent>\n          <Card>\n            <CardHeader>\n              <CardTitle className=\"text-center\">Oops, something went wrong</CardTitle>\n            </CardHeader>\n            <CardContent className=\"flex justify-between items-center flex-col gap-3\">\n              <div>There was an error loading your webhook endpoints.</div>\n              <Button variant=\"outline\" onClick={() => endpoints.reload()}>\n                <RefreshCcw className=\"mr-2 h-4 w-4\" />\n                Retry\n              </Button>\n            </CardContent>\n          </Card>\n        </PageContent>\n      </PageLayout>\n    )\n  }\n\n  return (\n    <PageLayout>\n      <PageHeader>\n        <PageTitle>Webhooks</PageTitle>\n        <a\n          href=\"https://www.daytona.io/docs/en/tools/api/#daytona/webhook/undefined/\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n          className=\"ml-auto\"\n        >\n          <Button variant=\"link\" size=\"sm\">\n            Docs\n          </Button>\n        </a>\n        {activeTab === 'endpoints' && <CreateEndpointDialog onSuccess={handleSuccess} />}\n      </PageHeader>\n\n      <PageContent>\n        <Tabs value={activeTab} onValueChange={setActiveTab} className=\"gap-6\">\n          <TabsList className=\"shadow-none bg-transparent w-auto p-0 pb-0 justify-start border-b rounded-none\">\n            <TabsTrigger\n              value=\"endpoints\"\n              className=\"data-[state=inactive]:border-b-transparent data-[state=active]:border-b-foreground border-b rounded-none !shadow-none -mb-0.5 pb-1.5\"\n            >\n              Endpoints\n            </TabsTrigger>\n            <TabsTrigger\n              value=\"messages\"\n              className=\"data-[state=inactive]:border-b-transparent data-[state=active]:border-b-foreground border-b rounded-none !shadow-none -mb-0.5 pb-1.5\"\n            >\n              Messages\n            </TabsTrigger>\n          </TabsList>\n          <TabsContent value=\"endpoints\">\n            <WebhooksEndpointTable\n              data={endpoints.data || []}\n              loading={endpoints.loading}\n              isLoadingEndpoint={isLoadingEndpoint}\n              onDisable={handleDisable}\n              onDelete={handleDelete}\n            />\n          </TabsContent>\n          <TabsContent value=\"messages\">\n            <WebhooksMessagesTable />\n          </TabsContent>\n        </Tabs>\n      </PageContent>\n    </PageLayout>\n  )\n}\n\nexport default Webhooks\n"
  },
  {
    "path": "apps/dashboard/src/providers/ApiProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ApiContext } from '@/contexts/ApiContext'\nimport { useEffect, useRef, useState } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport LoadingFallback from '@/components/LoadingFallback'\nimport { ApiClient } from '@/api/apiClient'\nimport { useLocation } from 'react-router-dom'\nimport { useConfig } from '@/hooks/useConfig'\n\nexport const ApiProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n  const { user, isAuthenticated, isLoading, signinRedirect } = useAuth()\n  const config = useConfig()\n  const location = useLocation()\n\n  const apiRef = useRef<ApiClient | null>(null)\n  const [isApiReady, setIsApiReady] = useState(false)\n\n  // Initialize API client as soon as user is available\n  useEffect(() => {\n    if (user) {\n      if (!apiRef.current) {\n        apiRef.current = new ApiClient(config, user.access_token)\n      } else {\n        apiRef.current.setAccessToken(user.access_token)\n      }\n      setIsApiReady(true)\n    } else {\n      setIsApiReady(false)\n    }\n  }, [user, config])\n\n  useEffect(() => {\n    if (!isLoading && !isAuthenticated) {\n      void signinRedirect({\n        state: {\n          returnTo: location.pathname + location.search,\n        },\n      })\n    }\n  }, [isLoading, isAuthenticated, signinRedirect, location])\n\n  if (isLoading || !isApiReady) {\n    return <LoadingFallback />\n  }\n\n  return <ApiContext.Provider value={apiRef.current}>{children}</ApiContext.Provider>\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/ConfigProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { RoutePath } from '@/enums/RoutePath'\nimport { queryKeys } from '@/hooks/queries/queryKeys'\nimport { DaytonaConfiguration } from '@daytonaio/api-client'\nimport { useSuspenseQuery } from '@tanstack/react-query'\nimport { InMemoryWebStorage, WebStorageStateStore } from 'oidc-client-ts'\nimport { ReactNode, useMemo } from 'react'\nimport { AuthProvider, AuthProviderProps } from 'react-oidc-context'\nimport { ConfigContext } from '../contexts/ConfigContext'\n\nconst apiUrl = (import.meta.env.VITE_BASE_API_URL ?? window.location.origin) + '/api'\n\ntype Props = {\n  children: ReactNode\n}\n\nexport function ConfigProvider(props: Props) {\n  const { data: config } = useSuspenseQuery({\n    queryKey: queryKeys.config.all,\n    queryFn: async () => {\n      const res = await fetch(`${apiUrl}/config`)\n      if (!res.ok) {\n        throw res\n      }\n      return res.json() as Promise<DaytonaConfiguration>\n    },\n  })\n\n  const oidcConfig: AuthProviderProps = useMemo(() => {\n    const isLocalhost = window.location.hostname === 'localhost'\n    const stateStore = isLocalhost ? window.sessionStorage : new InMemoryWebStorage()\n\n    return {\n      authority: config.oidc.issuer,\n      client_id: config.oidc.clientId,\n      extraQueryParams: {\n        audience: config.oidc.audience,\n      },\n      scope: 'openid profile email',\n      redirect_uri: window.location.origin,\n      staleStateAgeInSeconds: 60,\n      accessTokenExpiringNotificationTimeInSeconds: 290,\n      userStore: new WebStorageStateStore({ store: stateStore }),\n      onSigninCallback: (user) => {\n        const state = user?.state as { returnTo?: string } | undefined\n        const targetUrl = state?.returnTo || RoutePath.DASHBOARD\n        window.history.replaceState({}, '', targetUrl)\n        window.dispatchEvent(new PopStateEvent('popstate'))\n      },\n      post_logout_redirect_uri: window.location.origin,\n    }\n  }, [config])\n\n  return (\n    <ConfigContext.Provider value={{ ...config, apiUrl }}>\n      <AuthProvider {...oidcConfig}>{props.children}</AuthProvider>\n    </ConfigContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/NotificationSocketProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useAuth } from 'react-oidc-context'\nimport { ReactNode, useEffect, useState } from 'react'\nimport { io, Socket } from 'socket.io-client'\nimport { NotificationSocketContext } from '@/contexts/NotificationSocketContext'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\n\ntype Props = {\n  children: ReactNode\n}\n\nexport function NotificationSocketProvider(props: Props) {\n  const { user } = useAuth()\n  const { selectedOrganization } = useSelectedOrganization()\n  const [notificationSocket, setNotificationSocket] = useState<Socket | null>(null)\n\n  useEffect(() => {\n    const socket = io(window.location.origin, {\n      path: '/api/socket.io/',\n      autoConnect: false,\n      transports: ['websocket', 'webtransport'],\n      query: {\n        organizationId: selectedOrganization?.id,\n      },\n    })\n\n    setNotificationSocket(socket)\n\n    if (user) {\n      const token = user.access_token\n      socket.auth = { token }\n      socket.connect()\n    }\n\n    return () => {\n      socket.disconnect()\n    }\n  }, [user, selectedOrganization?.id])\n\n  return (\n    <NotificationSocketContext.Provider value={{ notificationSocket }}>\n      {props.children}\n    </NotificationSocketContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/OrganizationsProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ReactNode, useCallback, useMemo, useState } from 'react'\nimport { suspend } from 'suspend-react'\nimport { useApi } from '@/hooks/useApi'\nimport { OrganizationsContext, IOrganizationsContext } from '@/contexts/OrganizationsContext'\nimport { Organization } from '@daytonaio/api-client'\nimport { handleApiError } from '@/lib/error-handling'\nimport { LocalStorageKey } from '@/enums/LocalStorageKey'\n\ntype Props = {\n  children: ReactNode\n}\n\nexport function OrganizationsProvider(props: Props) {\n  const { organizationsApi } = useApi()\n\n  const getOrganizations = useCallback(async () => {\n    try {\n      return (await organizationsApi.listOrganizations()).data\n    } catch (error) {\n      handleApiError(error, 'Failed to fetch your organizations')\n      throw error\n    }\n  }, [organizationsApi])\n\n  const [organizations, setOrganizations] = useState<Organization[]>(\n    suspend(getOrganizations, [organizationsApi, 'organizations']),\n  )\n\n  // TODO: come back to this asap\n  const refreshOrganizations_todo = useCallback(\n    async (selectedOrganizationId?: string) => {\n      const orgs = await getOrganizations()\n      setOrganizations(orgs)\n      if (selectedOrganizationId) {\n        localStorage.setItem(LocalStorageKey.SelectedOrganizationId, selectedOrganizationId)\n      }\n    },\n    [getOrganizations],\n  )\n\n  // After creating a new org, the selected org was updated unnecessarily so we reload the page just in case\n  const refreshOrganizations = useCallback(async (selectedOrganizationId?: string) => {\n    if (selectedOrganizationId) {\n      localStorage.setItem(LocalStorageKey.SelectedOrganizationId, selectedOrganizationId)\n    }\n    setTimeout(() => {\n      window.location.reload()\n    }, 500)\n  }, [])\n\n  const contextValue: IOrganizationsContext = useMemo(() => {\n    return {\n      organizations,\n      setOrganizations,\n      refreshOrganizations,\n    }\n  }, [organizations, refreshOrganizations])\n\n  return <OrganizationsContext.Provider value={contextValue}>{props.children}</OrganizationsContext.Provider>\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/PlaygroundProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport {\n  DEFAULT_CPU_RESOURCES,\n  DEFAULT_DISK_RESOURCES,\n  DEFAULT_MEMORY_RESOURCES,\n  SANDBOX_SNAPSHOT_DEFAULT_VALUE,\n} from '@/constants/Playground'\nimport {\n  ActionRuntimeError,\n  PlaygroundActionParams,\n  PlaygroundActionParamValueSetter,\n  PlaygroundContext,\n  RunningActionMethodName,\n  RunPlaygroundActionBasic,\n  RunPlaygroundActionWithParams,\n  SandboxParams,\n  SetPlaygroundActionParamValue,\n  SetSandboxParamsValue,\n  SetVNCInteractionOptionsParamValue,\n  ValidatePlaygroundActionRequiredParams,\n  ValidatePlaygroundActionWithParams,\n  VNCInteractionOptionsParams,\n} from '@/contexts/PlaygroundContext'\nimport {\n  MouseButton,\n  MouseScrollDirection,\n  SandboxParametersSections,\n  ScreenshotFormatOption,\n} from '@/enums/Playground'\nimport { getLanguageCodeToRun, objectHasAnyValue } from '@/lib/playground'\nimport {\n  CreateSandboxBaseParams,\n  CreateSandboxFromImageParams,\n  CreateSandboxFromSnapshotParams,\n  Image,\n} from '@daytonaio/sdk'\nimport { useCallback, useState } from 'react'\n\nconst PARAM_SECTION_MAP: Partial<Record<keyof SandboxParams, SandboxParametersSections>> = {\n  listFilesParams: SandboxParametersSections.FILE_SYSTEM,\n  createFolderParams: SandboxParametersSections.FILE_SYSTEM,\n  deleteFileParams: SandboxParametersSections.FILE_SYSTEM,\n  gitCloneParams: SandboxParametersSections.GIT_OPERATIONS,\n  gitStatusParams: SandboxParametersSections.GIT_OPERATIONS,\n  gitBranchesParams: SandboxParametersSections.GIT_OPERATIONS,\n  codeRunParams: SandboxParametersSections.PROCESS_CODE_EXECUTION,\n  shellCommandRunParams: SandboxParametersSections.PROCESS_CODE_EXECUTION,\n}\n\nexport const PlaygroundProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n  const [openedParametersSections, setOpenedParametersSections] = useState<SandboxParametersSections[]>([\n    SandboxParametersSections.SANDBOX_MANAGEMENT,\n  ])\n  const [enabledSections, setEnabledSections] = useState<SandboxParametersSections[]>([\n    SandboxParametersSections.SANDBOX_MANAGEMENT,\n  ])\n  const [pendingScrollSection, setPendingScrollSection] = useState<SandboxParametersSections | null>(null)\n\n  const enableSection = useCallback((section: SandboxParametersSections) => {\n    setEnabledSections((prev) => (prev.includes(section) ? prev : [...prev, section]))\n    setOpenedParametersSections((prev) => (prev.includes(section) ? prev : [...prev, section]))\n    setPendingScrollSection(section)\n  }, [])\n\n  const disableSection = useCallback((section: SandboxParametersSections) => {\n    setEnabledSections((prev) => prev.filter((s) => s !== section))\n    setOpenedParametersSections((prev) => prev.filter((s) => s !== section))\n  }, [])\n\n  const clearPendingScrollSection = useCallback(() => setPendingScrollSection(null), [])\n\n  const [sandboxParametersState, setSandboxParametersState] = useState<SandboxParams>({\n    snapshotName: SANDBOX_SNAPSHOT_DEFAULT_VALUE,\n    resources: {\n      cpu: DEFAULT_CPU_RESOURCES,\n      memory: DEFAULT_MEMORY_RESOURCES,\n      disk: DEFAULT_DISK_RESOURCES,\n    },\n    createSandboxBaseParams: {\n      autoStopInterval: 5,\n      autoArchiveInterval: 5,\n      autoDeleteInterval: 0,\n    },\n    listFilesParams: {\n      directoryPath: 'workspace/new-dir',\n    },\n    createFolderParams: {\n      folderDestinationPath: 'workspace/new-dir',\n      permissions: '755',\n    },\n    deleteFileParams: {\n      filePath: 'workspace/new-dir',\n      recursive: true,\n    },\n    gitCloneParams: {\n      repositoryURL: 'https://github.com/octocat/Hello-World.git',\n      cloneDestinationPath: 'workspace/repo',\n    },\n    gitStatusParams: {\n      repositoryPath: 'workspace/repo',\n    },\n    gitBranchesParams: {\n      repositoryPath: 'workspace/repo',\n    },\n    codeRunParams: {\n      languageCode: getLanguageCodeToRun(),\n    },\n    shellCommandRunParams: {\n      shellCommand: 'ls -la', // Current default and fixed value\n    },\n  })\n  const [VNCInteractionOptionsParamsState, setVNCInteractionOptionsParamsState] = useState<VNCInteractionOptionsParams>(\n    {\n      keyboardHotKeyParams: { keys: '' },\n      keyboardPressParams: { key: '' },\n      keyboardTypeParams: { text: '' },\n      mouseClickParams: {\n        x: 100,\n        y: 100,\n        button: MouseButton.LEFT,\n        double: false,\n      },\n      mouseDragParams: {\n        startX: 100,\n        startY: 100,\n        endX: 200,\n        endY: 200,\n        button: MouseButton.LEFT,\n      },\n      mouseMoveParams: {\n        x: 100,\n        y: 100,\n      },\n      mouseScrollParams: {\n        x: 100,\n        y: 100,\n        direction: MouseScrollDirection.DOWN,\n        amount: 1,\n      },\n      screenshotOptionsConfig: {\n        showCursor: false,\n        format: ScreenshotFormatOption.PNG,\n        quality: 100,\n        scale: 1,\n      },\n      screenshotRegionConfig: {\n        x: 100,\n        y: 100,\n        width: 300,\n        height: 200,\n      },\n    },\n  )\n\n  const setSandboxParameterValue: SetSandboxParamsValue = useCallback((key, value) => {\n    setSandboxParametersState((prev) => ({ ...prev, [key]: value }))\n  }, [])\n\n  const setVNCInteractionOptionsParamValue: SetVNCInteractionOptionsParamValue = useCallback((key, value) => {\n    setVNCInteractionOptionsParamsState((prev) => ({ ...prev, [key]: value }))\n  }, [])\n\n  const setPlaygroundActionParamValue: SetPlaygroundActionParamValue = useCallback(\n    (key, value) => {\n      if (key in sandboxParametersState) {\n        setSandboxParameterValue(key as keyof SandboxParams, value as SandboxParams[keyof SandboxParams])\n      } else if (key in VNCInteractionOptionsParamsState) {\n        setVNCInteractionOptionsParamValue(\n          key as keyof VNCInteractionOptionsParams,\n          value as VNCInteractionOptionsParams[keyof VNCInteractionOptionsParams],\n        )\n      } else {\n        console.error(`Unknown parameter key: ${String(key)}`)\n      }\n    },\n    [\n      setSandboxParameterValue,\n      setVNCInteractionOptionsParamValue,\n      sandboxParametersState,\n      VNCInteractionOptionsParamsState,\n    ],\n  )\n\n  const [runningActionMethod, setRunningActionMethod] = useState<RunningActionMethodName>(null)\n  const [actionRuntimeError, setActionRuntimeError] = useState<ActionRuntimeError>({})\n\n  const validatePlaygroundActionRequiredParams: ValidatePlaygroundActionRequiredParams = useCallback(\n    (actionParamsFormData, actionParamsState) => {\n      if (actionParamsFormData.some((formItem) => formItem.required)) {\n        const emptyFormItem = actionParamsFormData\n          .filter((formItem) => formItem.required)\n          .find((formItem) => {\n            const value = actionParamsState[formItem.key]\n            return value === '' || value === undefined\n          })\n\n        if (emptyFormItem) {\n          return `${emptyFormItem.label} parameter is required for this action`\n        }\n      }\n\n      return undefined\n    },\n    [],\n  )\n\n  const runPlaygroundAction: RunPlaygroundActionBasic = useCallback(async (actionFormData, invokeApi) => {\n    setRunningActionMethod(actionFormData.methodName)\n    // Reset error if exists\n    setActionRuntimeError((prev) => ({\n      ...prev,\n      [actionFormData.methodName]: undefined,\n    }))\n    try {\n      await invokeApi(actionFormData)\n    } catch (error: unknown) {\n      console.error('API call error', error)\n      setActionRuntimeError((prev) => ({\n        ...prev,\n        [actionFormData.methodName]: error instanceof Error ? error.message : String(error),\n      }))\n    } finally {\n      setRunningActionMethod(null)\n    }\n  }, [])\n\n  const runPlaygroundActionWithParams: RunPlaygroundActionWithParams = useCallback(\n    async (actionFormData, invokeApi) => {\n      const validationError = validatePlaygroundActionRequiredParams(\n        actionFormData.parametersFormItems,\n        actionFormData.parametersState,\n      )\n      if (validationError) {\n        setActionRuntimeError((prev) => ({\n          ...prev,\n          [actionFormData.methodName]: validationError,\n        }))\n        setRunningActionMethod(null)\n        return\n      }\n      return await runPlaygroundAction(actionFormData, invokeApi)\n    },\n    [runPlaygroundAction, validatePlaygroundActionRequiredParams],\n  )\n\n  const validatePlaygroundActionWithParams: ValidatePlaygroundActionWithParams = useCallback(\n    (actionFormData, parametersState) => {\n      const validationError = validatePlaygroundActionRequiredParams(\n        actionFormData.parametersFormItems,\n        parametersState,\n      )\n      if (validationError) {\n        setActionRuntimeError((prev) => ({\n          ...prev,\n          [actionFormData.methodName]: validationError,\n        }))\n      } // Reset error\n      else\n        setActionRuntimeError((prev) => ({\n          ...prev,\n          [actionFormData.methodName]: undefined,\n        }))\n    },\n    [validatePlaygroundActionRequiredParams],\n  )\n\n  const playgroundActionParamValueSetter: PlaygroundActionParamValueSetter = useCallback(\n    (actionFormData, paramFormData, actionParamsKey, value) => {\n      const prev =\n        actionParamsKey in sandboxParametersState\n          ? sandboxParametersState[actionParamsKey as keyof SandboxParams]\n          : VNCInteractionOptionsParamsState[actionParamsKey as keyof VNCInteractionOptionsParams]\n      const newState = Object.assign({}, prev, { [paramFormData.key]: value })\n\n      setPlaygroundActionParamValue(actionParamsKey, newState as PlaygroundActionParams[typeof actionParamsKey])\n      if (!actionFormData.onChangeParamsValidationDisabled)\n        validatePlaygroundActionWithParams(actionFormData, newState as typeof actionFormData.parametersState)\n\n      // Auto-enable the section that owns this param if it's currently disabled\n      const section = PARAM_SECTION_MAP[actionParamsKey as keyof SandboxParams]\n      if (section && !enabledSections.includes(section)) enableSection(section)\n    },\n    [\n      setPlaygroundActionParamValue,\n      validatePlaygroundActionWithParams,\n      sandboxParametersState,\n      VNCInteractionOptionsParamsState,\n      enabledSections,\n      enableSection,\n    ],\n  )\n\n  const getSandboxParametersInfo = useCallback(() => {\n    const useLanguageParam = !!sandboxParametersState['language']\n    const resourceValuesExist = objectHasAnyValue(sandboxParametersState['resources'])\n    const useResourcesCPU = resourceValuesExist && sandboxParametersState['resources']['cpu'] !== undefined\n    const useResourcesMemory = resourceValuesExist && sandboxParametersState['resources']['memory'] !== undefined\n    const useResourcesDisk = resourceValuesExist && sandboxParametersState['resources']['disk'] !== undefined\n    const useDefaultResourceValues = !(\n      (useResourcesCPU && sandboxParametersState['resources']['cpu'] !== DEFAULT_CPU_RESOURCES) ||\n      (useResourcesMemory && sandboxParametersState['resources']['memory'] !== DEFAULT_MEMORY_RESOURCES) ||\n      (useResourcesDisk && sandboxParametersState['resources']['disk'] !== DEFAULT_DISK_RESOURCES)\n    )\n\n    const createSandboxParamsExist = objectHasAnyValue(sandboxParametersState['createSandboxBaseParams'])\n    const useAutoStopInterval =\n      createSandboxParamsExist && sandboxParametersState['createSandboxBaseParams']['autoStopInterval'] !== undefined\n    const useAutoArchiveInterval =\n      createSandboxParamsExist && sandboxParametersState['createSandboxBaseParams']['autoArchiveInterval'] !== undefined\n    const useAutoDeleteInterval =\n      createSandboxParamsExist && sandboxParametersState['createSandboxBaseParams']['autoDeleteInterval'] !== undefined\n\n    const createSandboxFromImageParams: CreateSandboxFromImageParams = { image: Image.debianSlim('3.13') } // Default and fixed image if CreateSandboxFromImageParams are used\n    const snapshotName = sandboxParametersState['snapshotName']\n    const useCustomSandboxSnapshotName = snapshotName !== undefined && snapshotName !== SANDBOX_SNAPSHOT_DEFAULT_VALUE\n    const createSandboxFromSnapshotParams: CreateSandboxFromSnapshotParams = {\n      snapshot: useCustomSandboxSnapshotName ? snapshotName : undefined,\n    }\n    const createSandboxFromSnapshot = useCustomSandboxSnapshotName || useDefaultResourceValues\n\n    // Create from base image if default resource values are not used\n    // Snapshot parameter has precedence over resources and createSandboxFromImage\n    const createSandboxFromImage = !useDefaultResourceValues && !useCustomSandboxSnapshotName\n\n    // We specify resources for sandbox creation if there is any specified resource value which has value different from the default one and useCustomSandboxSnapshotName is false\n    const useResources = !useCustomSandboxSnapshotName && resourceValuesExist && !useDefaultResourceValues\n    const useSandboxCreateParams =\n      useLanguageParam ||\n      useResources ||\n      createSandboxParamsExist ||\n      useCustomSandboxSnapshotName ||\n      createSandboxFromImage\n\n    if (createSandboxFromImage) {\n      // Set CreateSandboxFromImageParams specific params\n      if (useResources) {\n        createSandboxFromImageParams.resources = {}\n        if (useResourcesCPU) createSandboxFromImageParams.resources.cpu = sandboxParametersState['resources']['cpu']\n        if (useResourcesMemory)\n          createSandboxFromImageParams.resources.memory = sandboxParametersState['resources']['memory']\n        if (useResourcesDisk) createSandboxFromImageParams.resources.disk = sandboxParametersState['resources']['disk']\n      }\n    }\n    let createSandboxParams: CreateSandboxBaseParams | CreateSandboxFromImageParams | CreateSandboxFromSnapshotParams =\n      {}\n    if (createSandboxFromSnapshot) createSandboxParams = createSandboxFromSnapshotParams\n    else if (createSandboxFromImage) createSandboxParams = createSandboxFromImageParams\n    // Set CreateSandboxBaseParams params which are common for both params types\n    if (useLanguageParam) createSandboxParams.language = sandboxParametersState['language']\n    if (useAutoStopInterval)\n      createSandboxParams.autoStopInterval = sandboxParametersState['createSandboxBaseParams']['autoStopInterval']\n    if (useAutoArchiveInterval)\n      createSandboxParams.autoArchiveInterval = sandboxParametersState['createSandboxBaseParams']['autoArchiveInterval']\n    if (useAutoDeleteInterval)\n      createSandboxParams.autoDeleteInterval = sandboxParametersState['createSandboxBaseParams']['autoDeleteInterval']\n    createSandboxParams.labels = { 'daytona-playground': 'true' }\n    if (useLanguageParam)\n      createSandboxParams.labels['daytona-playground-language'] = sandboxParametersState['language'] as string // useLanguageParam guarantees that value isn't undefined so we put as string to silence TS compiler\n    return {\n      useLanguageParam,\n      useResources,\n      useResourcesCPU,\n      useResourcesMemory,\n      useResourcesDisk,\n      createSandboxParamsExist,\n      useAutoStopInterval,\n      useAutoArchiveInterval,\n      useAutoDeleteInterval,\n      useSandboxCreateParams,\n      useCustomSandboxSnapshotName,\n      createSandboxFromImage,\n      createSandboxFromSnapshot,\n      createSandboxParams,\n    }\n  }, [sandboxParametersState])\n\n  return (\n    <PlaygroundContext.Provider\n      value={{\n        sandboxParametersState,\n        setSandboxParameterValue,\n        VNCInteractionOptionsParamsState,\n        setVNCInteractionOptionsParamValue,\n        runPlaygroundActionWithParams,\n        runPlaygroundActionWithoutParams: runPlaygroundAction,\n        validatePlaygroundActionWithParams,\n        playgroundActionParamValueSetter,\n        runningActionMethod,\n        actionRuntimeError,\n        getSandboxParametersInfo,\n        openedParametersSections,\n        setOpenedParametersSections,\n        enabledSections,\n        enableSection,\n        disableSection,\n        pendingScrollSection,\n        clearPendingScrollSection,\n      }}\n    >\n      {children}\n    </PlaygroundContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/PlaygroundSandboxProvider.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PlaygroundCategories } from '@/enums/Playground'\nimport { useDeepCompareMemo } from '@/hooks/useDeepCompareMemo'\nimport { usePlayground } from '@/hooks/usePlayground'\nimport { useSandboxSession, UseSandboxSessionResult } from '@/hooks/useSandboxSession'\nimport { createContext, useEffect, useRef } from 'react'\n\nexport const PlaygroundSandboxContext = createContext<UseSandboxSessionResult | null>(null)\n\nexport const PlaygroundSandboxProvider: React.FC<{\n  activeTab: PlaygroundCategories\n  children: React.ReactNode\n}> = ({ activeTab, children }) => {\n  const { getSandboxParametersInfo } = usePlayground()\n  const { createSandboxParams } = getSandboxParametersInfo()\n  const stableCreateParams = useDeepCompareMemo(createSandboxParams)\n\n  const session = useSandboxSession({\n    scope: 'playground',\n    createParams: stableCreateParams,\n    terminal: true,\n    vnc: true,\n    notify: { vnc: activeTab === PlaygroundCategories.VNC },\n  })\n\n  const createRef = useRef(session.sandbox.create)\n  createRef.current = session.sandbox.create\n\n  useEffect(() => {\n    const needsSandbox = activeTab === PlaygroundCategories.TERMINAL || activeTab === PlaygroundCategories.VNC\n    if (needsSandbox && !session.sandbox.instance && !session.sandbox.loading && !session.sandbox.error) {\n      createRef.current()\n    }\n  }, [activeTab, session.sandbox.instance, session.sandbox.loading, session.sandbox.error])\n\n  const vncSandboxId = useRef<string | null>(null)\n  useEffect(() => {\n    const id = session.sandbox.instance?.id\n    if (id && vncSandboxId.current !== id) {\n      vncSandboxId.current = id\n      session.vnc.start()\n    }\n  }, [session.sandbox.instance?.id, session.vnc])\n\n  return <PlaygroundSandboxContext.Provider value={session}>{children}</PlaygroundSandboxContext.Provider>\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/QueryProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { keepPreviousData, QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport { ReactQueryDevtools } from '@tanstack/react-query-devtools'\nimport React from 'react'\n\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      staleTime: 1000 * 60 * 5, // 5 minutes\n      gcTime: 1000 * 60 * 10, // 10 minutes (previously cacheTime)\n      retry: (failureCount, error: any) => {\n        if (error?.response?.status >= 400 && error?.response?.status < 500) {\n          return false\n        }\n        return failureCount < 3\n      },\n      placeholderData: keepPreviousData,\n    },\n  },\n})\n\nexport const QueryProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n  return (\n    <QueryClientProvider client={queryClient}>\n      {children}\n      {import.meta.env.DEV && <ReactQueryDevtools initialIsOpen={false} />}\n    </QueryClientProvider>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/RegionsProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'\nimport { Region, RegionType } from '@daytonaio/api-client'\nimport { IRegionsContext, RegionsContext } from '@/contexts/RegionsContext'\nimport { useApi } from '@/hooks/useApi'\nimport { handleApiError } from '@/lib/error-handling'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\n\ntype Props = {\n  children: ReactNode\n}\n\nexport function RegionsProvider(props: Props) {\n  const { regionsApi, organizationsApi } = useApi()\n\n  const { selectedOrganization } = useSelectedOrganization()\n\n  const [sharedRegions, setSharedRegions] = useState<Region[]>([])\n  const [loadingSharedRegions, setLoadingSharedRegions] = useState(true)\n\n  const [availableRegions, setAvailableRegions] = useState<Region[]>([])\n  const [loadingAvailableRegions, setLoadingAvailableRegions] = useState(true)\n\n  const getSharedRegions = useCallback(async () => {\n    try {\n      const regions = (await regionsApi.listSharedRegions()).data\n      setSharedRegions(regions)\n    } catch (error) {\n      handleApiError(error, 'Failed to fetch shared regions')\n      setSharedRegions([])\n    } finally {\n      setLoadingSharedRegions(false)\n    }\n  }, [regionsApi])\n\n  const getAvailableRegions = useCallback(async () => {\n    if (!selectedOrganization) {\n      setAvailableRegions([])\n      setLoadingAvailableRegions(false)\n      return []\n    }\n    try {\n      const regions = (await organizationsApi.listAvailableRegions(selectedOrganization.id)).data\n      setAvailableRegions(regions)\n      return regions\n    } catch (error) {\n      handleApiError(error, 'Failed to fetch available regions')\n      setAvailableRegions([])\n      return []\n    } finally {\n      setLoadingAvailableRegions(false)\n    }\n  }, [organizationsApi, selectedOrganization])\n\n  useEffect(() => {\n    getSharedRegions()\n    getAvailableRegions()\n  }, [getSharedRegions, getAvailableRegions])\n\n  const getRegionName = useCallback(\n    (regionId: string): string | undefined => {\n      const region = [...availableRegions, ...sharedRegions].find((region) => region.id === regionId)\n      return region?.name\n    },\n    [availableRegions, sharedRegions],\n  )\n\n  const customRegions = useMemo(() => {\n    return availableRegions.filter((region) => region.regionType === RegionType.CUSTOM)\n  }, [availableRegions])\n\n  const contextValue: IRegionsContext = useMemo(() => {\n    return {\n      sharedRegions,\n      loadingSharedRegions,\n      availableRegions,\n      loadingAvailableRegions,\n      customRegions,\n      refreshAvailableRegions: getAvailableRegions,\n      getRegionName,\n    }\n  }, [\n    loadingSharedRegions,\n    loadingAvailableRegions,\n    sharedRegions,\n    availableRegions,\n    customRegions,\n    getAvailableRegions,\n    getRegionName,\n  ])\n\n  return <RegionsContext.Provider value={contextValue}>{props.children}</RegionsContext.Provider>\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/SandboxSessionProvider.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ISandboxSessionContext, SandboxSessionContext } from '@/contexts/SandboxSessionContext'\nimport { ReactNode, useCallback, useRef } from 'react'\n\ntype SessionFlags = { terminal: boolean; vnc: boolean }\n\nexport function SandboxSessionProvider({ children }: { children: ReactNode }) {\n  const flagsRef = useRef<Map<string, SessionFlags>>(new Map())\n\n  const getFlags = useCallback((sandboxId: string): SessionFlags => {\n    let flags = flagsRef.current.get(sandboxId)\n    if (!flags) {\n      flags = { terminal: false, vnc: false }\n      flagsRef.current.set(sandboxId, flags)\n    }\n    return flags\n  }, [])\n\n  const value: ISandboxSessionContext = {\n    isTerminalActivated: (sandboxId) => getFlags(sandboxId).terminal,\n    activateTerminal: (sandboxId) => {\n      getFlags(sandboxId).terminal = true\n    },\n    isVncActivated: (sandboxId) => getFlags(sandboxId).vnc,\n    activateVnc: (sandboxId) => {\n      getFlags(sandboxId).vnc = true\n    },\n  }\n\n  return <SandboxSessionContext.Provider value={value}>{children}</SandboxSessionContext.Provider>\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/SelectedOrganizationProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ISelectedOrganizationContext, SelectedOrganizationContext } from '@/contexts/SelectedOrganizationContext'\nimport { LocalStorageKey } from '@/enums/LocalStorageKey'\nimport { useApi } from '@/hooks/useApi'\nimport { useOrganizations } from '@/hooks/useOrganizations'\nimport { handleApiError } from '@/lib/error-handling'\nimport { Organization, OrganizationRolePermissionsEnum, OrganizationUserRoleEnum } from '@daytonaio/api-client'\nimport { usePostHog } from 'posthog-js/react'\nimport { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'\nimport { useAuth } from 'react-oidc-context'\nimport { toast } from 'sonner'\nimport { suspend } from 'suspend-react'\n\ntype Props = {\n  children: ReactNode\n}\n\nexport function SelectedOrganizationProvider(props: Props) {\n  const { user } = useAuth()\n  const { organizationsApi } = useApi()\n  const posthog = usePostHog()\n\n  const { organizations } = useOrganizations()\n\n  const [selectedOrganizationId, setSelectedOrganizationId] = useState<string | null>(() => {\n    const storedId = localStorage.getItem(LocalStorageKey.SelectedOrganizationId)\n    if (storedId && organizations.find((org) => org.id === storedId)) {\n      return storedId\n    } else if (organizations.length > 0) {\n      const defaultOrg = organizations.find((org) => org.personal) || organizations[0]\n      localStorage.setItem(LocalStorageKey.SelectedOrganizationId, defaultOrg.id)\n      return defaultOrg.id\n    } else {\n      localStorage.removeItem(LocalStorageKey.SelectedOrganizationId)\n      return null\n    }\n  })\n\n  useEffect(() => {\n    if (!organizations.length) {\n      setSelectedOrganizationId(null)\n    }\n    if (!selectedOrganizationId || !organizations.some((org) => org.id === selectedOrganizationId)) {\n      const defaultOrg = organizations.find((org) => org.personal) || organizations[0]\n      localStorage.setItem(LocalStorageKey.SelectedOrganizationId, defaultOrg.id)\n      setSelectedOrganizationId(defaultOrg.id)\n    }\n  }, [organizations, selectedOrganizationId])\n\n  const selectedOrganization = useMemo<Organization | null>(() => {\n    if (!selectedOrganizationId) {\n      return null\n    }\n    return organizations.find((org) => org.id === selectedOrganizationId) || null\n  }, [organizations, selectedOrganizationId])\n\n  useEffect(() => {\n    if (!posthog || !selectedOrganizationId) {\n      return\n    }\n\n    posthog.group('organization', selectedOrganizationId)\n  }, [posthog, selectedOrganizationId])\n\n  const getOrganizationMembers = useCallback(\n    async (selectedOrganizationId: string | null) => {\n      if (!selectedOrganizationId) {\n        return []\n      }\n      try {\n        return (await organizationsApi.listOrganizationMembers(selectedOrganizationId)).data\n      } catch (error) {\n        handleApiError(error, 'Failed to fetch organization members')\n        throw error\n      }\n    },\n    [organizationsApi],\n  )\n\n  const [organizationMembers, setOrganizationMembers] = useState(\n    suspend(() => getOrganizationMembers(selectedOrganizationId), [organizationsApi, 'organizationMembers']),\n  )\n\n  const refreshOrganizationMembers = useCallback(\n    async (organizationId?: string) => {\n      const organizationMembers = await getOrganizationMembers(organizationId || selectedOrganizationId)\n      setOrganizationMembers(organizationMembers)\n      return organizationMembers\n    },\n    [getOrganizationMembers, selectedOrganizationId],\n  )\n\n  const authenticatedUserOrganizationMember = useMemo(() => {\n    return organizationMembers.find((member) => member.userId === user?.profile.sub) || null\n  }, [organizationMembers, user])\n\n  const authenticatedUserAssignedPermissions = useMemo(() => {\n    if (!authenticatedUserOrganizationMember) {\n      return null\n    }\n    return new Set(authenticatedUserOrganizationMember.assignedRoles.flatMap((role) => role.permissions))\n  }, [authenticatedUserOrganizationMember])\n\n  const authenticatedUserHasPermission = useCallback(\n    (permission: OrganizationRolePermissionsEnum) => {\n      if (!authenticatedUserOrganizationMember || !authenticatedUserAssignedPermissions) {\n        return false\n      }\n      if (authenticatedUserOrganizationMember.role === OrganizationUserRoleEnum.OWNER) {\n        return true\n      }\n      return authenticatedUserAssignedPermissions.has(permission)\n    },\n    [authenticatedUserOrganizationMember, authenticatedUserAssignedPermissions],\n  )\n\n  const handleSelectOrganization = useCallback(\n    async (organizationId: string): Promise<boolean> => {\n      const organizationMembers = await refreshOrganizationMembers(organizationId)\n\n      // confirm switch if user is a member of the new organization\n      if (organizationMembers.some((member) => member.userId === user?.profile.sub)) {\n        localStorage.setItem(LocalStorageKey.SelectedOrganizationId, organizationId)\n        setSelectedOrganizationId(organizationId)\n        return true\n      } else {\n        toast.error('Failed to switch organization', {\n          closeButton: true,\n        })\n        return false\n      }\n    },\n    [refreshOrganizationMembers, user],\n  )\n\n  const contextValue: ISelectedOrganizationContext = useMemo(() => {\n    return {\n      selectedOrganization,\n      organizationMembers,\n      refreshOrganizationMembers,\n      authenticatedUserOrganizationMember,\n      authenticatedUserHasPermission,\n      onSelectOrganization: handleSelectOrganization,\n    }\n  }, [\n    selectedOrganization,\n    organizationMembers,\n    authenticatedUserOrganizationMember,\n    authenticatedUserHasPermission,\n    handleSelectOrganization,\n    refreshOrganizationMembers,\n  ])\n\n  return (\n    <SelectedOrganizationContext.Provider value={contextValue}>{props.children}</SelectedOrganizationContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/SvixProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { PageContent, PageHeader, PageLayout, PageTitle } from '@/components/PageLayout'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Skeleton } from '@/components/ui/skeleton'\nimport { useWebhookAppPortalAccessQuery } from '@/hooks/queries/useWebhookAppPortalAccessQuery'\nimport { useWebhookInitializationStatusQuery } from '@/hooks/queries/useWebhookInitializationStatusQuery'\nimport { useSelectedOrganization } from '@/hooks/useSelectedOrganization'\nimport { RefreshCcw } from 'lucide-react'\nimport React from 'react'\nimport { SvixProvider as SvixReactProvider } from 'svix-react'\n\ninterface SvixProviderProps {\n  children: React.ReactNode\n}\n\nexport function SvixProvider({ children }: SvixProviderProps) {\n  const { selectedOrganization } = useSelectedOrganization()\n  const {\n    data: appPortalAccess,\n    isLoading: isLoadingAppPortalAccess,\n    error: appPortalAccessError,\n    refetch: refetchAppPortalAccess,\n  } = useWebhookAppPortalAccessQuery(selectedOrganization?.id)\n  const {\n    data: initStatus,\n    isLoading: isLoadingInitStatus,\n    error: initStatusError,\n    refetch: refetchInitStatus,\n  } = useWebhookInitializationStatusQuery(selectedOrganization?.id)\n\n  const isLoading = isLoadingAppPortalAccess || isLoadingInitStatus\n  const error = appPortalAccessError || initStatusError\n  const refetch = () => {\n    refetchAppPortalAccess()\n    refetchInitStatus()\n  }\n\n  if (isLoading) {\n    return (\n      <PageLayout>\n        <PageHeader>\n          <PageTitle>Webhooks</PageTitle>\n        </PageHeader>\n        <PageContent>\n          <Card>\n            <CardHeader>\n              <Skeleton className=\"h-6 w-48\" />\n            </CardHeader>\n            <CardContent className=\"space-y-4\">\n              <Skeleton className=\"h-10 w-full\" />\n              <Skeleton className=\"h-10 w-full\" />\n              <Skeleton className=\"h-10 w-full\" />\n            </CardContent>\n          </Card>\n        </PageContent>\n      </PageLayout>\n    )\n  }\n\n  if (error || !appPortalAccess?.token || !initStatus?.svixApplicationId) {\n    return (\n      <PageLayout>\n        <PageHeader>\n          <PageTitle>Webhooks</PageTitle>\n        </PageHeader>\n        <PageContent>\n          <Card>\n            <CardHeader>\n              <CardTitle className=\"text-center\">Oops, something went wrong</CardTitle>\n            </CardHeader>\n            <CardContent className=\"flex justify-between items-center flex-col gap-3\">\n              <div>Failed to load webhooks. Please try again later.</div>\n              <Button variant=\"outline\" onClick={() => refetch()}>\n                <RefreshCcw className=\"mr-2 h-4 w-4\" />\n                Retry\n              </Button>\n            </CardContent>\n          </Card>\n        </PageContent>\n      </PageLayout>\n    )\n  }\n\n  return (\n    <SvixReactProvider token={appPortalAccess.token} appId={initStatus.svixApplicationId}>\n      {children}\n    </SvixReactProvider>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/providers/UserOrganizationInvitationsProvider.tsx",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'\nimport { useApi } from '@/hooks/useApi'\nimport {\n  UserOrganizationInvitationsContext,\n  IUserOrganizationInvitationsContext,\n} from '@/contexts/UserOrganizationInvitationsContext'\n\ntype Props = {\n  children: ReactNode\n}\n\nexport function UserOrganizationInvitationsProvider(props: Props) {\n  const { organizationsApi } = useApi()\n\n  const [count, setCount] = useState<number>(0)\n\n  const getInvitationsCount = useCallback(async () => {\n    try {\n      const count = (await organizationsApi.getOrganizationInvitationsCountForAuthenticatedUser()).data\n      setCount(count)\n    } catch (e) {\n      // silently fail\n    }\n  }, [organizationsApi])\n\n  useEffect(() => {\n    void getInvitationsCount()\n  }, [getInvitationsCount])\n\n  const contextValue: IUserOrganizationInvitationsContext = useMemo(() => {\n    return {\n      count,\n      setCount,\n    }\n  }, [count])\n\n  return (\n    <UserOrganizationInvitationsContext.Provider value={contextValue}>\n      {props.children}\n    </UserOrganizationInvitationsContext.Provider>\n  )\n}\n"
  },
  {
    "path": "apps/dashboard/src/services/webhookService.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useAuth } from 'react-oidc-context'\nimport { useCallback } from 'react'\nimport { WebhookInitializationStatus } from '@daytonaio/api-client'\n\nexport function useWebhookService() {\n  const { user } = useAuth()\n\n  const getInitializationStatus = useCallback(\n    async (organizationId: string): Promise<WebhookInitializationStatus | null> => {\n      try {\n        // Create a simple fetch request with the access token\n        // Note: We don't need to include /api in the URL since the Vite dev server proxy handles it\n        const response = await fetch(`/api/webhooks/organizations/${organizationId}/initialization-status`, {\n          method: 'GET',\n          headers: {\n            Authorization: `Bearer ${user?.access_token || ''}`,\n            'Content-Type': 'application/json',\n          },\n        })\n\n        if (!response.ok) {\n          return null\n        }\n\n        return await response.json()\n      } catch (error) {\n        console.error('Failed to get webhook initialization status:', error)\n        return null\n      }\n    },\n    [user?.access_token],\n  )\n\n  const getAppPortalAccess = useCallback(\n    async (organizationId: string): Promise<string | null> => {\n      try {\n        // Note: We don't need to include /api in the URL since the Vite dev server proxy handles it\n        const response = await fetch(`/api/webhooks/organizations/${organizationId}/app-portal-access`, {\n          method: 'POST',\n          headers: {\n            Authorization: `Bearer ${user?.access_token || ''}`,\n            'Content-Type': 'application/json',\n          },\n        })\n\n        if (!response.ok) {\n          return null\n        }\n\n        const data = await response.json()\n        return data.url\n      } catch (error) {\n        console.error('Failed to get app portal access:', error)\n        return null\n      }\n    },\n    [user?.access_token],\n  )\n\n  const isWebhookInitialized = useCallback(\n    async (organizationId: string): Promise<boolean> => {\n      const status = await getInitializationStatus(organizationId)\n      return status !== null && status.svixApplicationId !== null\n    },\n    [getInitializationStatus],\n  )\n\n  return {\n    getInitializationStatus,\n    getAppPortalAccess,\n    isWebhookInitialized,\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/types/CreateApiKeyPermissionGroup.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { CreateApiKeyPermissionsEnum } from '@daytonaio/api-client'\n\nexport interface CreateApiKeyPermissionGroup {\n  name: string\n  permissions: CreateApiKeyPermissionsEnum[]\n}\n"
  },
  {
    "path": "apps/dashboard/src/types/DashboardConfig.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { DaytonaConfiguration } from '@daytonaio/api-client'\n\nexport type DashboardConfig = DaytonaConfiguration & {\n  apiUrl: string\n}\n"
  },
  {
    "path": "apps/dashboard/src/types/OrganizationRolePermissionGroup.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { OrganizationRolePermissionsEnum } from '@daytonaio/api-client'\n\nexport interface OrganizationRolePermissionGroup {\n  name: string\n  permissions: OrganizationRolePermissionsEnum[]\n}\n"
  },
  {
    "path": "apps/dashboard/src/types/sandbox.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport interface Sandbox {\n  id: string\n  name: string\n  state: string\n  region: string\n  runnerDomain: string\n}\n"
  },
  {
    "path": "apps/dashboard/src/types/window.d.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\ninterface Window {\n  pylon?: {\n    chat_settings: {\n      app_id: string\n      email: string\n      name: string\n      avatar_url?: string\n      email_hash?: string\n    }\n  }\n  Pylon?: {\n    (command: 'show' | 'hide'): void\n    (command: 'onShow' | 'onHide', callback: (() => void) | null): void\n    (command: 'onChangeUnreadMessagesCount', callback: ((count: number) => void) | null): void\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/vendor/pylon/addPylonWidget.ts",
    "content": "/* eslint-disable prefer-rest-params */\n/* eslint-disable no-var */\n/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport const addPylonWidget = (appId: string) => {\n  var e = window\n  var t = document\n  var n = function () {\n    // @ts-expect-error ignore\n    n.e(arguments)\n  }\n  // @ts-expect-error ignore\n  n.q = []\n  // @ts-expect-error ignore\n  n.e = function (e) {\n    // @ts-expect-error ignore\n    n.q.push(e)\n  }\n\n  e.Pylon = n\n  var r = function () {\n    var e = t.createElement('script')\n    e.setAttribute('type', 'text/javascript')\n    e.setAttribute('async', 'true')\n    e.setAttribute('src', `https://widget.usepylon.com/widget/${appId}`)\n    var n = t.getElementsByTagName('script')[0]\n    if (n.parentNode) n.parentNode.insertBefore(e, n)\n  }\n  if (t.readyState === 'complete') {\n    r()\n  } else if (e.addEventListener) {\n    e.addEventListener('load', r, false)\n  }\n}\n\nexport const initPylon = (appId: string, options: typeof window.pylon) => {\n  addPylonWidget(appId)\n\n  window.pylon = options\n}\n"
  },
  {
    "path": "apps/dashboard/src/vendor/pylon/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nexport { initPylon } from './addPylonWidget'\nexport { usePylon } from './usePylon'\nexport { usePylonCommands } from './usePylonCommands'\n"
  },
  {
    "path": "apps/dashboard/src/vendor/pylon/usePylon.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { useConfig } from '@/hooks/useConfig'\nimport { useEffect } from 'react'\nimport { create } from 'zustand'\n\ninterface PylonState {\n  isOpen: boolean\n  unreadCount: number\n  isInitialized: boolean\n  initListeners: () => void\n  toggle: () => void\n}\n\nconst usePylonStore = create<PylonState>()((set, get) => ({\n  isOpen: false,\n  unreadCount: 0,\n  isInitialized: false,\n\n  initListeners: () => {\n    if (get().isInitialized || !window.Pylon) {\n      return\n    }\n\n    window.Pylon('onShow', () => set({ isOpen: true }))\n    window.Pylon('onHide', () => set({ isOpen: false }))\n    window.Pylon('onChangeUnreadMessagesCount', (count: number) => set({ unreadCount: count }))\n\n    set({ isInitialized: true })\n  },\n\n  toggle: () => {\n    if (!window.Pylon) return\n\n    if (get().isOpen) {\n      window.Pylon('hide')\n    } else {\n      window.Pylon('show')\n    }\n  },\n}))\n\nexport function usePylon() {\n  const config = useConfig()\n  const pylon = usePylonStore()\n\n  const initListeners = usePylonStore((state) => state.initListeners)\n\n  useEffect(() => {\n    initListeners()\n  }, [initListeners])\n\n  return {\n    isOpen: pylon.isOpen,\n    unreadCount: pylon.unreadCount,\n    toggle: pylon.toggle,\n    isEnabled: Boolean(config.pylonAppId),\n  }\n}\n"
  },
  {
    "path": "apps/dashboard/src/vendor/pylon/usePylonCommands.tsx",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { LifeBuoyIcon } from 'lucide-react'\nimport { useMemo } from 'react'\nimport { useRegisterCommands } from '../../components/CommandPalette'\nimport { usePylon } from './usePylon'\n\nexport function usePylonCommands() {\n  const { toggle, isEnabled } = usePylon()\n\n  const commands = useMemo(\n    () => [\n      {\n        id: 'pylon-support',\n        label: 'Help & Support',\n        icon: <LifeBuoyIcon className=\"w-4 h-4\" />,\n        keywords: ['help', 'support', 'chat', 'pylon', 'assist'],\n        onSelect: toggle,\n      },\n    ],\n    [toggle],\n  )\n\n  useRegisterCommands(isEnabled ? commands : [], { groupId: 'support', groupLabel: 'Support', groupOrder: 10 })\n}\n"
  },
  {
    "path": "apps/dashboard/src/vite-env.d.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/// <reference types=\"vite/client\" />\n\ndeclare module '*.png' {\n  const content: string\n  export default content\n}\n\ninterface ImportMetaEnv {\n  readonly VITE_API_URL: string\n}\n\ninterface ImportMeta {\n  readonly env: ImportMetaEnv\n}\n"
  },
  {
    "path": "apps/dashboard/tailwind.config.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nconst { createGlobPatternsForDependencies } = require('@nx/react/tailwind')\nconst { join } = require('path')\nconst plugin = require('tailwindcss/plugin')\n\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  darkMode: ['class'],\n  content: [\n    join(__dirname, '{src,pages,components,app}/**/*!(*.spec).{ts,tsx,html}'),\n    ...createGlobPatternsForDependencies(__dirname),\n  ],\n  theme: {\n    extend: {\n      screens: {\n        xs: '480px',\n      },\n      borderRadius: {\n        lg: 'var(--radius)',\n        md: 'calc(var(--radius) - 2px)',\n        sm: 'calc(var(--radius) - 4px)',\n      },\n      colors: {\n        background: 'hsl(var(--background))',\n        foreground: 'hsl(var(--foreground))',\n        card: {\n          DEFAULT: 'hsl(var(--card))',\n          foreground: 'hsl(var(--card-foreground))',\n        },\n        popover: {\n          DEFAULT: 'hsl(var(--popover))',\n          foreground: 'hsl(var(--popover-foreground))',\n        },\n        primary: {\n          DEFAULT: 'hsl(var(--primary))',\n          foreground: 'hsl(var(--primary-foreground))',\n        },\n        secondary: {\n          DEFAULT: 'hsl(var(--secondary))',\n          foreground: 'hsl(var(--secondary-foreground))',\n        },\n        muted: {\n          DEFAULT: 'hsl(var(--muted))',\n          foreground: 'hsl(var(--muted-foreground))',\n        },\n        accent: {\n          DEFAULT: 'hsl(var(--accent))',\n          foreground: 'hsl(var(--accent-foreground))',\n        },\n        destructive: {\n          DEFAULT: 'hsl(var(--destructive))',\n          foreground: 'hsl(var(--destructive-foreground))',\n          background: 'hsl(var(--destructive-background))',\n          separator: 'hsl(var(--destructive-separator))',\n        },\n        warning: {\n          DEFAULT: 'hsl(var(--warning))',\n          foreground: 'hsl(var(--warning-foreground))',\n          background: 'hsl(var(--warning-background))',\n          separator: 'hsl(var(--warning-separator))',\n        },\n        success: {\n          DEFAULT: 'hsl(var(--success))',\n          foreground: 'hsl(var(--success-foreground))',\n          background: 'hsl(var(--success-background))',\n          separator: 'hsl(var(--success-separator))',\n        },\n        info: {\n          DEFAULT: 'hsl(var(--info))',\n          foreground: 'hsl(var(--info-foreground))',\n          background: 'hsl(var(--info-background))',\n          separator: 'hsl(var(--info-separator))',\n        },\n        border: 'hsl(var(--border))',\n        input: 'hsl(var(--input))',\n        ring: 'hsl(var(--ring))',\n        chart: {\n          1: 'hsl(var(--chart-1))',\n          2: 'hsl(var(--chart-2))',\n          3: 'hsl(var(--chart-3))',\n          4: 'hsl(var(--chart-4))',\n          5: 'hsl(var(--chart-5))',\n        },\n        sidebar: {\n          DEFAULT: 'hsl(var(--sidebar-background))',\n          foreground: 'hsl(var(--sidebar-foreground))',\n          primary: 'hsl(var(--sidebar-primary))',\n          'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',\n          accent: 'hsl(var(--sidebar-accent))',\n          'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',\n          border: 'hsl(var(--sidebar-border))',\n          ring: 'hsl(var(--sidebar-ring))',\n        },\n      },\n      keyframes: {\n        'accordion-down': {\n          from: {\n            height: '0',\n          },\n          to: {\n            height: 'var(--radix-accordion-content-height)',\n          },\n        },\n        'accordion-up': {\n          from: {\n            height: 'var(--radix-accordion-content-height)',\n          },\n          to: {\n            height: '0',\n          },\n        },\n      },\n      animation: {\n        'accordion-down': 'accordion-down 0.2s ease-out',\n        'accordion-up': 'accordion-up 0.2s ease-out',\n      },\n    },\n  },\n  plugins: [\n    require('tailwind-scrollbar'),\n    require('tailwindcss-animate'),\n    plugin(function ({ addVariant }) {\n      addVariant('aria-invalid', '&[aria-invalid=\"true\"]')\n    }),\n  ],\n}\n"
  },
  {
    "path": "apps/dashboard/tsconfig.app.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../../dist/out-tsc\",\n    \"module\": \"ES2022\",\n    \"allowImportingTsExtensions\": true,\n    \"noEmit\": true,\n    \"types\": [\"node\", \"@nx/react/typings/cssmodule.d.ts\", \"@nx/react/typings/image.d.ts\", \"vite/client\"],\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"@/*\": [\"src/*\"],\n      \"@daytonaio/*\": [\"../../libs/*\"],\n      \"@daytonaio/sdk\": [\"../../dist/libs/sdk-typescript/src/index.d.ts\"]\n    }\n  },\n  \"exclude\": [\n    \"src/**/*.spec.ts\",\n    \"src/**/*.test.ts\",\n    \"src/**/*.spec.tsx\",\n    \"src/**/*.test.tsx\",\n    \"src/**/*.spec.js\",\n    \"src/**/*.test.js\",\n    \"src/**/*.spec.jsx\",\n    \"src/**/*.test.jsx\"\n  ],\n  \"include\": [\"src/**/*.js\", \"src/**/*.jsx\", \"src/**/*.ts\", \"src/**/*.tsx\"]\n}\n"
  },
  {
    "path": "apps/dashboard/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"allowJs\": false,\n    \"esModuleInterop\": false,\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"types\": [\"vite/client\"],\n    \"resolveJsonModule\": true\n  },\n  \"files\": [],\n  \"include\": [],\n  \"references\": [\n    {\n      \"path\": \"./tsconfig.app.json\"\n    }\n  ],\n  \"extends\": \"../../tsconfig.base.json\"\n}\n"
  },
  {
    "path": "apps/dashboard/vite.config.mts",
    "content": "/// <reference types='vitest' />\nimport { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'\nimport { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'\nimport react from '@vitejs/plugin-react'\nimport fs from 'fs'\nimport path from 'path'\nimport { defineConfig } from 'vite'\nimport { analyzer } from 'vite-bundle-analyzer'\nimport checker from 'vite-plugin-checker'\nimport { nodePolyfills } from 'vite-plugin-node-polyfills'\n\nconst outDir = '../../dist/apps/dashboard'\n\nexport default defineConfig((mode) => ({\n  root: __dirname,\n  cacheDir: '../../node_modules/.vite/apps/dashboard',\n  server: {\n    port: 3000,\n    host: '0.0.0.0',\n    proxy: {\n      '/api': {\n        target: 'http://localhost:3001',\n        ws: true,\n        changeOrigin: true,\n        rewriteWsOrigin: true,\n      },\n    },\n  },\n  plugins: [\n    react(),\n    // Required for @daytonaio/sdk\n    nodePolyfills({\n      globals: { global: true, process: true, Buffer: true },\n      overrides: {\n        path: 'path-browserify-win32',\n      },\n      protocolImports: true,\n    }),\n    nxViteTsPaths(),\n    nxCopyAssetsPlugin(['*.md']),\n    // enforce typechecking for build mode\n    mode.command === 'build' &&\n      checker({\n        typescript: {\n          tsconfigPath: './tsconfig.app.json',\n        },\n      }),\n\n    {\n      name: 'exclude-msw',\n      apply: 'build',\n      writeBundle() {\n        if (mode.mode === 'production') {\n          const mswPath = path.resolve(__dirname, outDir, 'mockServiceWorker.js')\n\n          if (fs.existsSync(mswPath)) {\n            fs.rmSync(mswPath)\n            console.log('Removed mockServiceWorker.js from production build.')\n          }\n        }\n      },\n    },\n    analyzer({\n      openAnalyzer: false,\n      analyzerPort: 4000,\n      enabled: mode.mode === 'analyze',\n    }),\n  ],\n  resolve: {\n    alias: [\n      // Resolve @daytonaio/sdk to the local source\n      {\n        find: '@daytonaio/sdk',\n        replacement: path.resolve(__dirname, '../../libs/sdk-typescript/src'),\n      },\n      // Target @ but not @daytonaio,\n      {\n        // find: /^@(?!daytonaio)/,\n        find: '@',\n        replacement: path.resolve(__dirname, './src'), // Make sure this points to dashboard's src\n      },\n    ],\n  },\n  // Uncomment this if you are using workers.\n  // worker: {\n  //  plugins: [ nxViteTsPaths() ],\n  // },\n  optimizeDeps: {\n    exclude: ['tar'],\n  },\n  build: {\n    outDir,\n    emptyOutDir: true,\n    reportCompressedSize: true,\n    commonjsOptions: {\n      transformMixedEsModules: true,\n    },\n    // we'd ideally polyfill it but until https://github.com/davidmyersdev/vite-plugin-node-polyfills/issues/118 gets resolved we can just exclude it\n    rollupOptions: {\n      external: ['tar'],\n    },\n  },\n}))\n"
  },
  {
    "path": "apps/docs/.dockerignore",
    "content": "node_modules\nDockerfile"
  },
  {
    "path": "apps/docs/.gitignore",
    "content": "# build output\ndist/\n# generated types\n.astro/\n\n# dependencies\nnode_modules/\n\n.pnpm-store\n\n# logs\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\n\n# environment variables\n.env.production\n\n# macOS-specific files\n.DS_Store\n\n# Idea/Jetbrains\n.idea/\n\n# git config\n.gitconfig\n\n# vscode settings\n.vscode\n.vscode/\n\n# unnecessary lockfiles (only using yarn)\npackage-lock.json\npnpm-lock.yaml\n"
  },
  {
    "path": "apps/docs/.markdownlint-cli2.jsonc",
    "content": "{\n  \"$schema\": \"https://raw.githubusercontent.com/DavidAnson/markdownlint-cli2/24eb4dce508ab81398d14d75179123fca425f12d/schema/markdownlint-cli2-config-schema.json\",\n  \"config\": {\n    \"no-emphasis-as-heading\": false,\n    \"line-length\": false,\n    \"no-inline-html\": false,\n    \"first-line-h1\": false,\n    \"no-bare-urls\": false,\n    \"no-duplicate-heading\": false,\n    \"emphasis-style\": {\n      \"style\": \"underscore\",\n    },\n    \"ol-prefix\": false,\n    \"fenced-code-language\": false,\n    \"single-title\": false,\n    \"heading-increment\": false,\n  },\n}\n"
  },
  {
    "path": "apps/docs/.nvmrc",
    "content": "v20.10.0\n"
  },
  {
    "path": "apps/docs/.prettierrc",
    "content": "{\n  \"trailingComma\": \"es5\",\n  \"tabWidth\": 2,\n  \"semi\": false,\n  \"singleQuote\": true,\n  \"arrowParens\": \"avoid\",\n  \"importOrder\": [\"^[./]\"],\n  \"importOrderSeparation\": true,\n  \"importOrderSortSpecifiers\": true,\n  \"plugins\": [\"prettier-plugin-astro\", \"@trivago/prettier-plugin-sort-imports\"],\n  \"overrides\": [\n    {\n      \"files\": \"*.astro\",\n      \"options\": {\n        \"parser\": \"astro\"\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "apps/docs/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, caste, color, religion, or sexual\nidentity and orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n- Demonstrating empathy and kindness toward other people\n- Being respectful of differing opinions, viewpoints, and experiences\n- Giving and gracefully accepting constructive feedback\n- Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n- Focusing on what is best not just for us as individuals, but for the overall\n  community\n\nExamples of unacceptable behavior include:\n\n- The use of sexualized language or imagery, and sexual attention or advances of\n  any kind\n- Trolling, insulting or derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or email address,\n  without their explicit permission\n- Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official email address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\n<codeofconduct@daytona.io>.\n\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series of\nactions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or permanent\nban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within the\ncommunity.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.1, available at\n[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].\n\nCommunity Impact Guidelines were inspired by\n[Mozilla's code of conduct enforcement ladder][Mozilla CoC].\n\nFor answers to common questions about this code of conduct, see the FAQ at\n[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at\n[https://www.contributor-covenant.org/translations][translations].\n\n[homepage]: https://www.contributor-covenant.org\n[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html\n[Mozilla CoC]: https://github.com/mozilla/diversity\n[FAQ]: https://www.contributor-covenant.org/faq\n[translations]: https://www.contributor-covenant.org/translations\n"
  },
  {
    "path": "apps/docs/CONTRIBUTING.md",
    "content": "# Contributing to Daytona Documentation\n\nThank you for your interest in contributing to Daytona Documentation! Whether you're fixing a typo, improving existing docs, or adding new content, your help is greatly appreciated.\n\nWe are happy to provide guidance on PRs, technical writing, and turning any feature idea into a reality.\n\nThis document provides a detailed guide for contributors, especially writers, to ensure that contributions are consistent and of high quality. If you need further assistance, don't hesitate to reach out in the [Daytona Slack Community][slack].\n\n## Writing Overview\n\n### Main Guidelines\n\n- **Clarity and Conciseness**: Write clearly and concisely. Avoid complex jargon and aim for simplicity.\n- **Second Person Narrative**: Address the reader as \"you\" to create an engaging and direct narrative.\n- **Active Voice**: Use active voice whenever possible to make your writing more dynamic and clear.\n- **Screenshots and Examples**: Include annotated screenshots and examples to illustrate complex points.\n- **Formatting**: Use Markdown for formatting. Refer to the [Markdown Guide](https://www.markdownguide.org) if you're unfamiliar with it.\n- **Code Snippets**: When including code, ensure it's properly formatted and tested.\n- **Links**: Add hyperlinks to relevant sections within the docs or to external resources for additional information.\n\n### Writing Process\n\n1. **Familiarize Yourself**: Begin by understanding Daytona and its features. Explore the existing documentation to get a sense of the writing style and structure.\n2. **Find a Topic**: Look for topics that need improvement, missing documentation, or new features that haven't been documented yet. You can check existing [issues][issues] for documentation requests or open a new issue if you identify a gap in the content.\n3. **Discuss Your Ideas**: If you're addressing an unreported problem or proposing new content, open an issue to discuss your ideas. Provide a clear and concise description of what you want to add or change.\n4. **Write**: Make your changes or add new content. Follow the existing documentation format and style guide. Save your files in the correct directories as per the project structure.\n5. **Share**: Share your drafts with the community for feedback. Incorporate any suggestions that improve the quality and clarity of the documentation.\n6. **Commit and Open a Pull Request**: Commit your changes with clear messages, push them to your fork, and submit a pull request to the main repository for review.\n7. **Review**: Wait for a review and merge.\n\nRemember to stay responsive to feedback during the review process and make any necessary revisions based on suggestions from maintainers or other contributors.\n\n## Contributing to Docs 101\n\n### Contributing using Daytona\n\nTo contribute using Daytona, follow these steps:\n\n1. **Fork the Docs repo**: Fork the [Daytona Docs repository][sl] to your GitHub account to create an isolated copy where you can work without affecting the original project.\n2. **Access Daytona**: Start a new workspace using the GitHub repositor link and Daytona URL of your Daytona instance, for example '<https://YOUR-DAYTONA.INSTANCE/#https://github.com/YOUR-USERNAME/docs>'. If you don't have access to Daytona you can easily [install](https://github.com/daytonaio/installer) it on your own server. Now, start a workspace through a Daytona dashboard. Optionally, you can install a preferred [Daytona extension](https://download.daytona.io/) in your IDE.\n3. **Sync Your Fork**: Before making changes, sync your fork with the main repository to ensure you're working with the latest version.\n4. **Branch Out**: Create a new branch for your work. Use a descriptive name that reflects the changes you're planning to make.\n5. **Make Changes and Test**: Use the preferred IDE to edit, preview, and validate your changes to the documentation.\n6. **Commit and Push**: Commit your changes with clear messages and push them to your fork.\n7. **Open a Pull Request**: From your fork, submit a pull request to the main repository for review.\n\n### Contributing using Codespaces\n\nTo contribute using GitHub Codespaces, follow these steps:\n\n1. **Fork the Docs repo**: Fork the [Daytona Docs repository][sl] to your GitHub account to create an isolated copy where you can work without affecting the original project.\n2. **Create a Codespace**: Go to your fork in GitHub to create a new Codespace.\n3. **Sync Your Fork**: Before making changes, sync your fork with the main repository to ensure you're working with the latest version.\n4. **Branch Out**: Create a new branch for your work. Use a descriptive name that reflects the changes you're planning to make.\n5. **Make Changes and Test**: Use the Codespaces to edit, preview, and validate your changes to the documentation.\n6. **Commit and Push**: After making changes, commit to your fork and push the updates.\n7. **Open a Pull Request**: Create a pull request from your fork to the main Daytona Docs repository for review.\n\n### Contributing using the Local Environment\n\nTo set up and contribute using your local environment, follow these steps:\n\n1. **Fork and Clone**: Fork the [Daytona Docs repository][sl] to your GitHub account and clone it to your local machine.\n2. **Sync Your Fork**: Before making changes, sync your fork with the main repository to ensure you're working with the latest version.\n3. **Branch Out**: Create a new branch for your work. Use a descriptive name that reflects the changes you're planning to make.\n4. **Set Up Your Environment**: Ensure you have Node.js (v16 or higher) and pnpm (v8.2 or higher) installed, then install dependencies with `pnpm i`.\n5. **Make Changes Locally**: Edit the documentation as needed, following the writing guidelines and style.\n6. **Test Your Changes**: Run a local development server to preview your changes.\n7. **Commit and Push**: Commit your changes with descriptive messages and push them to your fork.\n8. **Create a Pull Request**: Submit a pull request to the main repository for your changes to be reviewed and merged.\n\n## Testing\n\n### Testing visual changes while you work\n\nRun the Astro dev server on the docs site to see how changes you make impact a project using Starlight.\n\nTo do this, move into the `docs/` directory and then run `pnpm dev run`:\n\n```sh\ncd docs\npnpm dev run\n```\n\nYou should then be able to open a preview <http://localhost:4321> and see your changes.\n\n> **Note**\n> Changes to the Starlight integration will require you to quit and restart the dev server to take effect.\n\n## Git Workflow and Commands Cheat Sheet\n\nThis cheat sheet provides the essential Git commands necessary for contributing to the Daytona Documentation as specified in the previous sections.\n\n### Fork and Clone Repository\n\n```sh\n# Fork the repository on GitHub to your account using GitHub website\n\n# Clone your forked repository to your local machine, when using Daytona this is done automatically when creating workspace\ngit clone https://github.com/YOUR-USERNAME/docs.git\ncd docs\n```\n\n### Sync Your Fork with the Original Repository\n\n```sh\n# Add the original repository as an upstream remote\ngit remote add upstream https://github.com/daytonaio/docs.git\n\n# Fetch the latest changes from upstream\ngit fetch upstream\n\n# Check out your fork's local default branch (usually 'main')\ngit checkout main\n\n# Merge changes from upstream/default branch into your local default branch\ngit merge upstream/main\n```\n\n### Create a New Branch for Your Changes\n\n```sh\n# Create a new branch and switch to it, e.g. we are updating Gettings Started page\ngit checkout -b update-getting-started\n```\n\n### Make Changes and Commit Them\n\n```sh\n# Add all new and modified files to the staging area\ngit add .\n\n# Commit your changes with a descriptive message\ngit commit -m \"Add a guide on integrating Daytona with VS Code\"\n```\n\n### Push Changes to Your Fork on GitHub\n\n```sh\n# Push your branch to your GitHub fork\ngit push -u origin update-getting-started\n```\n\n### Create a Pull Request\n\n```sh\n# Go to the original repository on GitHub\n# Click on 'New Pull Request' and select your branch\n# Fill out the PR form and submit\n```\n\n### Update Your Branch with the Latest Changes from the Main Repository (if needed)\n\n```sh\n# Fetch the latest changes from the original repository\ngit fetch upstream\n\n# Rebase your branch on top of the latest changes from the default branch\ngit rebase upstream/main\n\n# Force push to update your GitHub fork (use with caution)\ngit push -f origin update-getting-started\n```\n\n### Merge Changes from Main into Your Branch (if there are conflicts after a rebase)\n\n```sh\n# Merge changes from the main branch into your feature branch\ngit merge main\n\n# Resolve any conflicts, then continue with the rebase\ngit rebase --continue\n\n# Push the changes after resolving conflicts\ngit push origin update-getting-started\n```\n\nRemember to replace `YOUR-USERNAME` with your actual GitHub username and `update-getting-started` with the name of the branch you are working on. Use these commands as a guide to maintain a clean and up-to-date Git workflow.\n\n## Other\n\n### Adding a new language to Starlight’s docs\n\nTo add a language, you will need its BCP-47 tag and a label. See [“Adding a new language”](https://github.com/withastro/docs/blob/main/contributor-guides/translating-astro-docs.md#adding-a-new-language) in the Astro docs repo for some helpful tips around choosing these.\n\n- Add your language to the `locales` config in `docs/astro.config.mjs`\n- Add your language’s subtag to the i18n label config in `.github/labeler.yml`\n- Add your language to the `pa11y` script’s `--sitemap-exclude` flag in `package.json`\n- Create the first translated page for your language.  \n   This must be the Daytona Docs landing page: `docs/src/content/docs/{language}/index.mdx`.\n- Open a pull request on GitHub to add your changes to Daytona Docs!\n\n### Understanding Starlight\n\n- Starlight is built as an Astro integration.\n  Read the [Astro Integration API docs][api-docs] to learn more about how integrations work.\n\n  The Starlight integration is exported from [`packages/starlight/index.ts`](./packages/starlight/index.ts).\n  It sets up Starlight’s routing logic, parses user config, and adds configuration to a Starlight user’s Astro project.\n\n- For tips and abilities on authoring content in Starlight follow the guide: [https://starlight.astro.build/guides/authoring-content/](https://starlight.astro.build/guides/authoring-content/)\n\n- Most pages in a Starlight project are built using a single [`packages/starlight/index.astro`](./packages/starlight/index.astro) route.\n  If you’ve worked on an Astro site before, much of this should look familiar: it’s an Astro component and uses a number of other components to build a page based on user content.\n\n- Starlight consumes a user’s content from the `'docs'` [content collection](https://docs.astro.build/en/guides/content-collections/).\n  This allows us to specify the permissible frontmatter via [a Starlight-specific schema](./packages/starlight/schema.ts) and get predictable data while providing clear error messages if a user sets invalid frontmatter in a page.\n\n- Components that require JavaScript for their functionality are all written without a UI framework, most often as custom elements.\n  This helps keep Starlight lightweight and makes it easier for a user to choose to add components from a framework of their choice to their project.\n\n- Components that require client-side JavaScript or CSS should use JavaScript/CSS features that are well-supported by browsers.\n\n  You can find a list of supported browsers and their versions using this [browserslist query](https://browsersl.ist/#q=%3E+0.5%25%2C+not+dead%2C+Chrome+%3E%3D+88%2C+Edge+%3E%3D+88%2C+Firefox+%3E%3D+98%2C+Safari+%3E%3D+15.4%2C+iOS+%3E%3D+15.4%2C+not+op_mini+all). To check whether or not a feature is supported, you can visit the [Can I use](https://caniuse.com) website and search for the feature.\n\n[slack]: https://go.daytona.io/slack\n[issues]: https://github.com/daytonaio/docs/issues\n[sl]: https://github.com/daytonaio/docs/pulls\n[api-docs]: https://docs.astro.build/en/reference/integrations-reference/\n"
  },
  {
    "path": "apps/docs/Dockerfile",
    "content": "FROM node:22-alpine AS build\n\nENV CI=true\n\nRUN npm install -g corepack && corepack enable\n\nWORKDIR /daytona\n\n# Yarn caching layer\nCOPY package.json yarn.lock .yarnrc.yml ./\nRUN yarn install --immutable\n\n# Nx + TS config\nCOPY nx.json tsconfig.base.json ./\n\n# App source (docs + api for openapi generation)\nCOPY apps/docs/ apps/docs/\nCOPY apps/api/ apps/api/\nCOPY apps/daemon/pkg/toolbox/docs/swagger.json apps/daemon/pkg/toolbox/docs/swagger.json\n\n# Lib dependencies (api imports runner-api-client)\nCOPY libs/runner-api-client/ libs/runner-api-client/\n\n# Docs build arguments\nENV PUBLIC_WEB_URL=https://daytona.io\nARG PUBLIC_ALGOLIA_APP_ID\nENV PUBLIC_ALGOLIA_APP_ID=${PUBLIC_ALGOLIA_APP_ID}\nARG PUBLIC_ALGOLIA_API_KEY\nENV PUBLIC_ALGOLIA_API_KEY=${PUBLIC_ALGOLIA_API_KEY}\nARG PUBLIC_WEB_URL\nENV PUBLIC_WEB_URL=${PUBLIC_WEB_URL}\nARG PUBLIC_ALGOLIA_DOCS_INDEX_NAME=docs\nENV PUBLIC_ALGOLIA_DOCS_INDEX_NAME=${PUBLIC_ALGOLIA_DOCS_INDEX_NAME}\nARG PUBLIC_ALGOLIA_CLI_INDEX_NAME=cli\nENV PUBLIC_ALGOLIA_CLI_INDEX_NAME=${PUBLIC_ALGOLIA_CLI_INDEX_NAME}\nARG PUBLIC_ALGOLIA_SDK_INDEX_NAME=sdk\nENV PUBLIC_ALGOLIA_SDK_INDEX_NAME=${PUBLIC_ALGOLIA_SDK_INDEX_NAME}\n\nENV VERSION=12345.67890.0\nENV NX_DAEMON=false\n\nRUN yarn nx build docs --configuration=production --nxBail=true\n\nFROM node:22-alpine AS docs\n\nARG VERSION=0.0.1\n\nWORKDIR /daytona\n\nCOPY --from=build /daytona/node_modules node_modules\nCOPY --from=build /daytona/dist/apps/docs dist/apps/docs\nCOPY --from=build /daytona/apps/docs/server dist/apps/docs/server\n\nWORKDIR /daytona/dist/apps/docs\n\nRUN VER=$(echo ${VERSION} | sed 's/^v//') && \\\n  MAJOR=$(echo ${VER} | cut -d. -f1) && \\\n  MINOR=$(echo ${VER} | cut -d. -f2) && \\\n  find . -type f \\( -name \"*.mjs\" -o -name \"*.js\" -o -name \"*.html\" \\) \\\n    -exec sed -i \"s/12345\\.67890/${MAJOR}.${MINOR}/g\" {} +\n\nENTRYPOINT [\"sh\", \"-c\", \"node server/index.mjs\"]\n"
  },
  {
    "path": "apps/docs/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "apps/docs/README.md",
    "content": "<div align=\"center\">\n\n[![Documentation](https://img.shields.io/github/v/release/daytonaio/docs?label=Docs&color=23cc71)](https://www.daytona.io/docs)\n![License](https://img.shields.io/badge/License-AGPL--3-blue)\n[![Go Report Card](https://goreportcard.com/badge/github.com/daytonaio/daytona)](https://goreportcard.com/report/github.com/daytonaio/daytona)\n[![Issues - daytona](https://img.shields.io/github/issues/daytonaio/daytona)](https://github.com/daytonaio/daytona/issues)\n![GitHub Release](https://img.shields.io/github/v/release/daytonaio/daytona)\n\n</div>\n\n&nbsp;\n\n<div align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/daytonaio/daytona/raw/main/assets/images/Daytona-logotype-white.png\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://github.com/daytonaio/daytona/raw/main/assets/images/Daytona-logotype-black.png\">\n    <img alt=\"Daytona logo\" src=\"https://github.com/daytonaio/daytona/raw/main/assets/images/Daytona-logotype-black.png\" width=\"50%\">\n  </picture>\n</div>\n\n<h3 align=\"center\">\n  Run AI Code.\n  <br/>\n  Secure and Elastic Infrastructure for\n  Running Your AI-Generated Code.\n</h3>\n\n<p align=\"center\">\n    <a href=\"https://www.daytona.io/docs\"> Documentation </a>·\n    <a href=\"https://github.com/daytonaio/daytona/issues/new?assignees=&labels=bug&projects=&template=bug_report.md&title=%F0%9F%90%9B+Bug+Report%3A+\"> Report Bug </a>·\n    <a href=\"https://github.com/daytonaio/daytona/issues/new?assignees=&labels=enhancement&projects=&template=feature_request.md&title=%F0%9F%9A%80+Feature%3A+\"> Request Feature </a>·\n    <a href=\"https://go.daytona.io/slack\"> Join our Slack </a>·\n    <a href=\"https://x.com/daytonaio\"> Connect on X </a>\n</p>\n\n<p align=\"center\">\n    <a href=\"https://www.producthunt.com/posts/daytona-2?embed=true&utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-daytona&#0045;2\" target=\"_blank\"><img src=\"https://api.producthunt.com/widgets/embed-image/v1/top-post-badge.svg?post_id=957617&theme=neutral&period=daily&t=1746176740150\" alt=\"Daytona&#0032; - Secure&#0032;and&#0032;elastic&#0032;infra&#0032;for&#0032;running&#0032;your&#0032;AI&#0045;generated&#0032;code&#0046; | Product Hunt\" style=\"width: 250px; height: 54px;\" width=\"250\" height=\"54\" /></a>\n    <a href=\"https://www.producthunt.com/posts/daytona-2?embed=true&utm_source=badge-top-post-topic-badge&utm_medium=badge&utm_souce=badge-daytona&#0045;2\" target=\"_blank\"><img src=\"https://api.producthunt.com/widgets/embed-image/v1/top-post-topic-badge.svg?post_id=957617&theme=neutral&period=monthly&topic_id=237&t=1746176740150\" alt=\"Daytona&#0032; - Secure&#0032;and&#0032;elastic&#0032;infra&#0032;for&#0032;running&#0032;your&#0032;AI&#0045;generated&#0032;code&#0046; | Product Hunt\" style=\"width: 250px; height: 54px;\" width=\"250\" height=\"54\" /></a>\n</p>\n\n---\n\n## Installation\n\n### Python SDK\n\n```bash\npip install daytona\n```\n\n### TypeScript SDK\n\n```bash\nnpm install @daytonaio/sdk\n```\n\n---\n\n## Features\n\n- **Lightning-Fast Infrastructure**: Sub-90ms Sandbox creation from code to execution.\n- **Separated & Isolated Runtime**: Execute AI-generated code with zero risk to your infrastructure.\n- **Massive Parallelization for Concurrent AI Workflows**: Fork Sandbox filesystem and memory state (Coming soon!)\n- **Programmatic Control**: File, Git, LSP, and Execute API\n- **Unlimited Persistence**: Your Sandboxes can live forever\n- **OCI/Docker Compatibility**: Use any OCI/Docker image to create a Sandbox\n\n---\n\n## Quick Start\n\n1. Create an account at https://app.daytona.io\n1. Generate a [new API key](https://app.daytona.io/dashboard/keys)\n1. Follow the [Getting Started docs](https://www.daytona.io/docs/getting-started/) to start using the Daytona SDK\n\n## Creating your first Sandbox\n\n### Python SDK\n\n```py\nfrom daytona import Daytona, DaytonaConfig, CreateSandboxBaseParams\n\n# Initialize the Daytona client\ndaytona = Daytona(DaytonaConfig(api_key=\"YOUR_API_KEY\"))\n\n# Create the Sandbox instance\nsandbox = daytona.create(CreateSandboxBaseParams(language=\"python\"))\n\n# Run code securely inside the Sandbox\nresponse = sandbox.process.code_run('print(\"Sum of 3 and 4 is \" + str(3 + 4))')\nif response.exit_code != 0:\n    print(f\"Error running code: {response.exit_code} {response.result}\")\nelse:\n    print(response.result)\n\n# Clean up the Sandbox\ndaytona.delete(sandbox)\n```\n\n### Typescript SDK\n\n```jsx\nimport { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  // Initialize the Daytona client\n  const daytona = new Daytona({\n    apiKey: 'YOUR_API_KEY',\n  })\n\n  let sandbox\n  try {\n    // Create the Sandbox instance\n    sandbox = await daytona.create({\n      language: 'typescript',\n    })\n    // Run code securely inside the Sandbox\n    const response = await sandbox.process.codeRun('console.log(\"Sum of 3 and 4 is \" + (3 + 4))')\n    if (response.exitCode !== 0) {\n      console.error('Error running code:', response.exitCode, response.result)\n    } else {\n      console.log(response.result)\n    }\n  } catch (error) {\n    console.error('Sandbox flow error:', error)\n  } finally {\n    if (sandbox) await daytona.delete(sandbox)\n  }\n}\n\nmain().catch(console.error)\n```\n\n---\n\n## Contributing\n\nDaytona is Open Source under the [GNU AFFERO GENERAL PUBLIC LICENSE](LICENSE), and is the [copyright of its contributors](NOTICE). If you would like to contribute to the software, read the Developer Certificate of Origin Version 1.1 (https://developercertificate.org/). Afterwards, navigate to the [contributing guide](CONTRIBUTING.md) to get started.\n"
  },
  {
    "path": "apps/docs/SECURITY.md",
    "content": "# Security Policy\n\n## Reporting a Vulnerability\n\nTo report a vulnerability, please contact us at [servicedesk@daytona.io](mailto:servicedesk@daytona.io).\n"
  },
  {
    "path": "apps/docs/astro.config.mjs",
    "content": "import node from '@astrojs/node'\nimport react from '@astrojs/react'\nimport starlight from '@astrojs/starlight'\nimport { ExpressiveCodeTheme } from '@astrojs/starlight/expressive-code'\nimport { defineConfig } from 'astro/config'\nimport fs from 'node:fs'\n\nimport config from './gt.config.json'\nimport { generateI18nConfig } from './src/i18n/generateI18nConfig'\n\nconst jsonDarkString = fs.readFileSync(\n  new URL(`src/assets/themes/daytona-code-dark.json`, import.meta.url),\n  'utf-8'\n)\nconst jsonLightString = fs.readFileSync(\n  new URL(`src/assets/themes/daytona-code-light.json`, import.meta.url),\n  'utf-8'\n)\nconst myThemeDark = ExpressiveCodeTheme.fromJSONString(jsonDarkString)\nconst myThemeLight = ExpressiveCodeTheme.fromJSONString(jsonLightString)\n\n// https://astro.build/config\nexport default defineConfig({\n  site: process.env.PUBLIC_WEB_URL,\n  base: '/docs',\n  integrations: [\n    react(),\n    starlight({\n      favicon: '/favicon.ico',\n      title: 'Daytona',\n      social: {\n        github: 'https://github.com/daytonaio',\n      },\n      editLink: {\n        baseUrl: 'https://github.com/daytonaio/daytona/blob/main/apps/docs/',\n      },\n      tableOfContents: { minHeadingLevel: 2, maxHeadingLevel: 4 },\n      customCss: ['./src/fonts/font-face.css', './src/styles/style.scss'],\n      components: {\n        Footer: './src/components/Footer.astro',\n        MarkdownContent: './src/components/MarkdownContent.astro',\n        Pagination: './src/components/Pagination.astro',\n        Header: './src/components/Header.astro',\n        PageSidebar: './src/components/PageSidebar.astro',\n        PageFrame: './src/components/PageFrame.astro',\n        Sidebar: './src/components/Sidebar.astro',\n        TwoColumnContent: './src/components/TwoColumnContent.astro',\n        TableOfContents: './src/components/TableOfContents.astro',\n        MobileMenuToggle: './src/components/MobileMenuToggle.astro',\n        ContentPanel: './src/components/ContentPanel.astro',\n        PageTitle: './src/components/PageTitle.astro',\n        Hero: './src/components/Hero.astro',\n        ThemeProvider: './src/components/ThemeProvider.astro',\n        ThemeSelect: './src/components/ThemeSelect.astro',\n        Head: './src/components/Head.astro',\n        EditLink: './src/components/EditLink.astro',\n        ExploreMore: './src/components/ExploreMore.astro',\n      },\n      expressiveCode: {\n        minSyntaxHighlightingColorContrast: 3.0,\n        themes: [myThemeDark, myThemeLight],\n      },\n      ...generateI18nConfig(config),\n    }),\n  ],\n  security: {\n    allowedDomains: [\n      { hostname: 'daytona.io' },\n      { hostname: 'www.daytona.io' },\n      { hostname: 'localhost' },\n    ],\n  },\n  output: 'server',\n  adapter: node({\n    mode: 'middleware',\n  }),\n  outDir: '../../dist/apps/docs',\n  vite: {\n    ssr: {\n      noExternal: ['path-to-regexp', '@astrojs/react', 'zod'],\n    },\n  },\n})\n"
  },
  {
    "path": "apps/docs/gt.config.json",
    "content": "{\n  \"framework\": \"react\",\n  \"defaultLocale\": \"en\",\n  \"src\": [\n    \"apps/docs/src/components/**/*.{ts,tsx,jsx,js}\"\n  ],\n  \"files\": {\n    \"mdx\": {\n      \"include\": [\n        \"apps/docs/src/content/docs/[locale]/**/*.mdx\"\n      ]\n    },\n    \"md\": {\n      \"include\": [\n        \"apps/docs/src/content/docs/[locale]/**/*.md\"\n      ]\n    },\n    \"json\": {\n      \"include\": [\n        \"apps/docs/src/content/i18n/[locale].json\"\n      ]\n    },\n    \"gt\": {\n      \"output\": \"apps/docs/src/data/i18n/[locale].json\"\n    }\n  },\n  \"locales\": [\n    \"en\",\n    \"ja\"\n  ],\n  \"ssr\": true,\n  \"options\": {\n    \"experimentalFlattenJsonFiles\": true,\n    \"experimentalLocalizeStaticUrls\": true,\n    \"docsUrlPattern\": \"/docs/[locale]/\"\n  },\n  \"_versionId\": \"e9edf82e30c7226839d457b619cc781a7f9ff298eb8485697a17047ec81d8e9b\"\n}"
  },
  {
    "path": "apps/docs/project.json",
    "content": "{\n  \"name\": \"docs\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"application\",\n  \"sourceRoot\": \"apps/docs\",\n  \"targets\": {\n    \"serve\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"cwd\": \"{projectRoot}\",\n        \"command\": \"astro dev --host\"\n      }\n    },\n    \"build\": {\n      \"executor\": \"nx:run-commands\",\n      \"inputs\": [\n        \"{projectRoot}/src/**/*\",\n        \"{projectRoot}/public/**/*\",\n        \"{projectRoot}/astro.config.*\",\n        \"{projectRoot}/package.json\",\n        \"{projectRoot}/tailwind.config.*\",\n        \"{projectRoot}/tools/**/*\",\n        \"{workspaceRoot}/dist/apps/api/openapi.json\",\n        \"{workspaceRoot}/dist/apps/api/openapi.3.1.0.json\",\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ],\n      \"outputs\": [\"{workspaceRoot}/dist/apps/docs\"],\n      \"options\": {\n        \"cwd\": \"{projectRoot}\",\n        \"commands\": [\n          \"astro build\",\n          \"node ./tools/update-search.js\",\n          \"node ./tools/update-llms.js\"\n        ],\n        \"parallel\": false\n      },\n      \"dependsOn\": [\"api:openapi\"],\n      \"configurations\": {\n        \"production\": {\n          \"commands\": [\n            \"astro build --prod\",\n            \"node ./tools/update-search.js\",\n            \"node ./tools/update-llms.js\"\n          ]\n        }\n      }\n    },\n    \"update-cli-reference\": {\n      \"executor\": \"nx:run-commands\",\n      \"cache\": true,\n      \"inputs\": [\n        \"{projectRoot}/tools/**/*\",\n        \"{workspaceRoot}/dist/apps/cli/**/*\"\n      ],\n      \"outputs\": [\"{projectRoot}/src/content/docs/en/cli/**/*\"],\n      \"options\": {\n        \"cwd\": \"{projectRoot}/tools\",\n        \"command\": \"node ./update-cli-reference.js\"\n      }\n    },\n    \"update-api-reference\": {\n      \"executor\": \"nx:run-commands\",\n      \"cache\": true,\n      \"inputs\": [\n        \"{projectRoot}/tools/**/*\",\n        \"{workspaceRoot}/dist/apps/api/openapi.json\",\n        \"{workspaceRoot}/dist/apps/api/openapi.3.1.0.json\",\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ],\n      \"outputs\": [\"{projectRoot}/src/content/docs/en/api/**/*\"],\n      \"options\": {\n        \"cwd\": \"{projectRoot}/tools\",\n        \"command\": \"node ./update-api-reference.js\"\n      },\n      \"dependsOn\": [\"api:openapi\"]\n    },\n    \"check-version-env\": {},\n    \"docker\": {\n      \"options\": {\n        \"target\": \"docs\",\n        \"build-args\": [\n          \"VERSION=$VERSION\",\n          \"PUBLIC_ALGOLIA_APP_ID=$PUBLIC_ALGOLIA_APP_ID\",\n          \"PUBLIC_ALGOLIA_API_KEY=$PUBLIC_ALGOLIA_API_KEY\",\n          \"PUBLIC_WEB_URL=$PUBLIC_WEB_URL\",\n          \"PUBLIC_ALGOLIA_DOCS_INDEX_NAME=$PUBLIC_ALGOLIA_DOCS_INDEX_NAME\",\n          \"PUBLIC_ALGOLIA_CLI_INDEX_NAME=$PUBLIC_ALGOLIA_CLI_INDEX_NAME\",\n          \"PUBLIC_ALGOLIA_SDK_INDEX_NAME=$PUBLIC_ALGOLIA_SDK_INDEX_NAME\"\n        ]\n      }\n    },\n    \"push-manifest\": {}\n  },\n  \"implicitDependencies\": [\"api\"]\n}\n"
  },
  {
    "path": "apps/docs/server/index.mjs",
    "content": "import express from 'express'\n\nimport { handler as ssrHandler } from '../server/entry.mjs'\nimport { env } from './util/environment.mjs'\nimport { redirects as slugRedirects } from './util/redirects.mjs'\n\n// Full-path redirect map from the shared URL map (slug redirects)\nconst redirects = Object.fromEntries(\n  Object.entries(slugRedirects).map(([from, to]) => [`/docs/${from}`, `/docs/${to}`])\n)\n\nconst app = express()\napp.use(express.json())\napp.use((req, res, next) => {\n  res.setHeader('X-Frame-Options', 'SAMEORIGIN')\n  next()\n})\napp.use((req, res, next) => {\n  const path = req.path.replace(/\\/$/, '') || req.path\n  const target = redirects[path]\n  if (target) {\n    return res.redirect(301, target)\n  }\n  // Handle locale-prefixed paths (/docs/en/slug -> /docs/en/new-slug)\n  const localeMatch = path.match(/^\\/docs\\/([a-z]{2})\\/(.+)$/)\n  if (localeMatch) {\n    const bareTarget = redirects[`/docs/${localeMatch[2]}`]\n    if (bareTarget) {\n      return res.redirect(301, bareTarget.replace('/docs/', `/docs/${localeMatch[1]}/`))\n    }\n  }\n  next()\n})\napp.use('/docs', express.static('client/'))\napp.use(ssrHandler)\napp.use((req, res) => {\n  res.sendFile('404.html', { root: 'client/' })\n})\n\napp.listen(env.FUNCTIONS_PORT, () => {\n  console.log(`Functions available on port ${env.FUNCTIONS_PORT}`)\n})\n"
  },
  {
    "path": "apps/docs/server/util/environment.mjs",
    "content": "import { config } from 'dotenv'\nimport { cleanEnv, num } from 'envalid'\n\nconfig()\n\nexport const env = cleanEnv(process.env, {\n  FUNCTIONS_PORT: num(),\n})\n"
  },
  {
    "path": "apps/docs/server/util/redirects.mjs",
    "content": "/**\n * Redirect map for pages that changed URLs during the content architecture refactor.\n *\n * The single source of truth used by the Express production server (server/index.mjs)\n * and the Astro middleware (src/middleware.ts).\n */\nexport const redirects = {\n  'inngest-agentkit-coding-agent': 'guides/agentkit/inngest-agentkit-coding-agent',\n  'claude-agent-sdk-connect-service-sandbox': 'guides/claude/claude-agent-sdk-connect-service-sandbox',\n  'claude-agent-sdk-interactive-terminal-sandbox': 'guides/claude/claude-agent-sdk-interactive-terminal-sandbox',\n  'claude-code-run-tasks-stream-logs-sandbox': 'guides/claude/claude-code-run-tasks-stream-logs-sandbox',\n  'codex-sdk-interactive-terminal-sandbox': 'guides/codex/codex-sdk-interactive-terminal-sandbox',\n  'data-analysis-with-ai': 'guides/data-analysis-with-ai',\n  'google-adk-code-generator': 'guides/google-adk-code-generator',\n  'langchain-data-analysis': 'guides/langchain/langchain-data-analysis',\n  'letta-code-agent': 'guides/letta-code/letta-code-agent',\n  'mastra-coding-agent': 'guides/mastra/mastra-coding-agent',\n  'opencode-web-agent': 'guides/opencode/opencode-web-agent',\n  'recursive-language-models': 'guides/rlm/recursive-language-models',\n  'guides/recursive-language-models': 'guides/rlm/recursive-language-models',\n  'trl-grpo-training': 'guides/reinforcement-learning/trl-grpo-training',\n  'preview-and-authentication': 'preview',\n  'regions-and-runners': 'regions',\n  'claude': 'guides/claude',\n  'computer-use-macos': 'computer-use',\n  'computer-use-windows': 'computer-use',\n  'computer-use-linux': 'computer-use',\n}\n"
  },
  {
    "path": "apps/docs/src/assets/docs/README.md",
    "content": "### How to update SVG diagrams\n\n1. Open XML file (e.g. `src/assets/docs/sandbox-states.drawio.xml`) in [draw.io](https://app.diagrams.net/)\n2. Make necessary changes\n3. Export as SVG with \"Transparent Backround\" toggled `on` and \"Embed Fonts\" toggled `off`\n4. Replace the existing SVG with the newly exported one\n5. In the new SVG, remove the `color-scheme: light dark;` CSS property declaration\n6. Export as XML and replace the existing XML with the newly exported one\n"
  },
  {
    "path": "apps/docs/src/assets/docs/sandbox-states.drawio.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<mxfile host=\"app.diagrams.net\" agent=\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36\" version=\"29.3.2\">\n  <diagram name=\"Page-1\" id=\"5JbCIHgbIGlznXKxIacy\">\n    <mxGraphModel dx=\"1072\" dy=\"729\" grid=\"1\" gridSize=\"10\" guides=\"1\" tooltips=\"1\" connect=\"1\" arrows=\"1\" fold=\"1\" page=\"1\" pageScale=\"1\" pageWidth=\"850\" pageHeight=\"1100\" math=\"0\" shadow=\"0\">\n      <root>\n        <mxCell id=\"0\" />\n        <mxCell id=\"1\" parent=\"0\" />\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-1\" edge=\"1\" parent=\"1\" source=\"v7m3hZkdDCJrDmzJJEV5-3\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#595959;\" target=\"v7m3hZkdDCJrDmzJJEV5-7\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"177\" y=\"42\" />\n              <mxPoint x=\"827\" y=\"42\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-2\" connectable=\"0\" parent=\"v7m3hZkdDCJrDmzJJEV5-1\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontColor=#595959;\" value=\"sandbox.delete()\" vertex=\"1\">\n          <mxGeometry relative=\"1\" x=\"0.0598\" y=\"1\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-3\" parent=\"1\" style=\"whiteSpace=wrap;strokeWidth=2;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;rounded=1;html=1;fillColor=#d5e8d4;fontSize=14;strokeColor=#82b366;fontColor=#000000;\" value=\"STARTED\" vertex=\"1\">\n          <mxGeometry height=\"54\" width=\"116\" x=\"148\" y=\"134\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-4\" edge=\"1\" parent=\"1\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#595959;\" target=\"v7m3hZkdDCJrDmzJJEV5-7\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"425\" y=\"72\" />\n              <mxPoint x=\"827\" y=\"72\" />\n            </Array>\n            <mxPoint x=\"425\" y=\"142.0000000000001\" as=\"sourcePoint\" />\n            <mxPoint x=\"766\" y=\"138.40999999999997\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-5\" connectable=\"0\" parent=\"v7m3hZkdDCJrDmzJJEV5-4\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontColor=#595959;\" value=\"sandbox.delete()\" vertex=\"1\">\n          <mxGeometry relative=\"1\" x=\"0.0334\" y=\"2\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-6\" parent=\"1\" style=\"whiteSpace=wrap;strokeWidth=2;rounded=1;html=1;fillColor=#d5e8d4;fontSize=14;fontStyle=0;strokeColor=#82b366;fontColor=#000000;\" value=\"STOPPED\" vertex=\"1\">\n          <mxGeometry height=\"54\" width=\"118\" x=\"366\" y=\"132\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-7\" parent=\"1\" style=\"rounded=1;whiteSpace=wrap;arcSize=50;strokeWidth=2;shape=ellipse;html=1;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;fontSize=14;perimeter=ellipsePerimeter;fillColor=#f5f5f5;fontColor=#000000;strokeColor=#666666;\" value=\"DELETED\" vertex=\"1\">\n          <mxGeometry height=\"61.18\" width=\"94\" x=\"780\" y=\"130.41\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-8\" edge=\"1\" parent=\"1\" style=\"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontSize=14;fontColor=#595959;\" value=\"d\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"680\" y=\"134\" />\n              <mxPoint x=\"680\" y=\"102\" />\n              <mxPoint x=\"827\" y=\"102\" />\n            </Array>\n            <mxPoint x=\"681\" y=\"134\" as=\"sourcePoint\" />\n            <mxPoint x=\"826.9999999999998\" y=\"130.40999999999997\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-9\" connectable=\"0\" parent=\"v7m3hZkdDCJrDmzJJEV5-8\" style=\"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=14;fontColor=#595959;\" value=\"sandbox.delete()\" vertex=\"1\">\n          <mxGeometry relative=\"1\" x=\"-0.0267\" y=\"1\" as=\"geometry\">\n            <mxPoint x=\"-6\" as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-10\" parent=\"1\" style=\"whiteSpace=wrap;strokeWidth=2;rounded=1;html=1;fillColor=#d5e8d4;fontSize=14;strokeColor=#82b366;fontColor=#000000;\" value=\"ARCHIVED\" vertex=\"1\">\n          <mxGeometry height=\"54\" width=\"122\" x=\"620\" y=\"134\" as=\"geometry\" />\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-11\" edge=\"1\" parent=\"1\" source=\"v7m3hZkdDCJrDmzJJEV5-3\" style=\"startArrow=none;endArrow=block;exitX=0.5;exitY=0;entryX=0.25;entryY=0;rounded=0;exitDx=0;exitDy=0;entryDx=0;entryDy=0;edgeStyle=orthogonalEdgeStyle;fontSize=14;fontColor=#595959;\" target=\"v7m3hZkdDCJrDmzJJEV5-6\" value=\"sandbox.stop()\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"206\" y=\"102\" />\n              <mxPoint x=\"396\" y=\"102\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-12\" edge=\"1\" parent=\"1\" source=\"v7m3hZkdDCJrDmzJJEV5-3\" style=\"startArrow=none;endArrow=block;exitX=1;exitY=0.5;entryX=0;entryY=0.5;rounded=0;edgeStyle=orthogonalEdgeStyle;entryDx=0;entryDy=0;exitDx=0;exitDy=0;fontSize=14;fontColor=#595959;fontStyle=2\" target=\"v7m3hZkdDCJrDmzJJEV5-6\" value=\"auto-stop\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <mxPoint x=\"126.04265306122446\" y=\"208\" as=\"sourcePoint\" />\n            <mxPoint x=\"332.09627450980395\" y=\"152.00000000000003\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-13\" edge=\"1\" parent=\"1\" source=\"v7m3hZkdDCJrDmzJJEV5-6\" style=\"startArrow=none;endArrow=block;exitX=0.5;exitY=1;entryX=0.5;entryY=1;rounded=0;edgeStyle=orthogonalEdgeStyle;entryDx=0;entryDy=0;exitDx=0;exitDy=0;fontSize=14;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#595959;\" target=\"v7m3hZkdDCJrDmzJJEV5-3\" value=\"sandbox.start()\">\n          <mxGeometry relative=\"1\" x=\"0.0021\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n            <Array as=\"points\">\n              <mxPoint x=\"425\" y=\"212\" />\n              <mxPoint x=\"206\" y=\"212\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-14\" edge=\"1\" parent=\"1\" source=\"v7m3hZkdDCJrDmzJJEV5-6\" style=\"startArrow=none;endArrow=block;exitX=0.75;exitY=0;entryX=0.28;entryY=-0.01;rounded=0;edgeStyle=orthogonalEdgeStyle;exitDx=0;exitDy=0;fontSize=14;fontColor=#595959;\" target=\"v7m3hZkdDCJrDmzJJEV5-10\" value=\"sandbox.archive()\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"455\" y=\"102\" />\n              <mxPoint x=\"655\" y=\"102\" />\n              <mxPoint x=\"655\" y=\"120\" />\n            </Array>\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-15\" edge=\"1\" parent=\"1\" source=\"v7m3hZkdDCJrDmzJJEV5-6\" style=\"startArrow=none;endArrow=block;exitX=1;exitY=0.5;entryX=0;entryY=0.5;rounded=0;edgeStyle=orthogonalEdgeStyle;entryDx=0;entryDy=0;exitDx=0;exitDy=0;fontStyle=2;fontSize=14;fontColor=#595959;\" target=\"v7m3hZkdDCJrDmzJJEV5-10\" value=\"auto-archive\">\n          <mxGeometry relative=\"1\" x=\"0.1304\" y=\"1\" as=\"geometry\">\n            <mxPoint as=\"offset\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-16\" edge=\"1\" parent=\"1\" style=\"startArrow=none;endArrow=block;entryX=0.25;entryY=1;rounded=0;edgeStyle=orthogonalEdgeStyle;entryDx=0;entryDy=0;fontSize=14;fontColor=#595959;\" value=\"sandbox.start()\">\n          <mxGeometry relative=\"1\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"673\" y=\"188\" />\n              <mxPoint x=\"673\" y=\"244\" />\n              <mxPoint x=\"190\" y=\"244\" />\n            </Array>\n            <mxPoint x=\"673\" y=\"188\" as=\"sourcePoint\" />\n            <mxPoint x=\"190.00000000000006\" y=\"190\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-17\" edge=\"1\" parent=\"1\" style=\"endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;\" target=\"v7m3hZkdDCJrDmzJJEV5-7\" value=\"\">\n          <mxGeometry height=\"50\" relative=\"1\" width=\"50\" as=\"geometry\">\n            <Array as=\"points\">\n              <mxPoint x=\"500\" y=\"190\" />\n              <mxPoint x=\"500\" y=\"210\" />\n              <mxPoint x=\"827\" y=\"210\" />\n            </Array>\n            <mxPoint x=\"500\" y=\"160\" as=\"sourcePoint\" />\n            <mxPoint x=\"830\" y=\"230\" as=\"targetPoint\" />\n          </mxGeometry>\n        </mxCell>\n        <mxCell id=\"v7m3hZkdDCJrDmzJJEV5-18\" parent=\"1\" style=\"text;whiteSpace=wrap;html=1;\" value=\"&lt;span style=&quot;color: rgb(89, 89, 89); font-family: Helvetica; font-size: 14px; font-style: italic; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: center; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: nowrap; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; float: none; display: inline !important;&quot;&gt;auto-delete&lt;/span&gt;\" vertex=\"1\">\n          <mxGeometry height=\"40\" width=\"100\" x=\"550\" y=\"191.59\" as=\"geometry\" />\n        </mxCell>\n      </root>\n    </mxGraphModel>\n  </diagram>\n</mxfile>\n"
  },
  {
    "path": "apps/docs/src/assets/themes/daytona-code-dark.json",
    "content": "{\n  \"name\": \"daytona-code-dark\",\n  \"colors\": {\n    \"editor.background\": \"#0A0A0A\",\n    \"editor.foreground\": \"#fff\",\n    \"activityBarBadge.background\": \"#007acc\",\n    \"sideBarTitle.foreground\": \"#bbbbbb\"\n  },\n  \"tokenColors\": [\n    {\n      \"name\": \"Comment\",\n      \"scope\": [\"comment\", \"punctuation.definition.comment\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#a2a2a2\"\n      }\n    },\n    {\n      \"name\": \"Variables\",\n      \"scope\": [\"variable\", \"string constant.other.placeholder\"],\n      \"settings\": {\n        \"foreground\": \"#8558DE\"\n      }\n    },\n    {\n      \"name\": \"Colors\",\n      \"scope\": [\"constant.other.color\"],\n      \"settings\": {\n        \"foreground\": \"#ffffff\"\n      }\n    },\n    {\n      \"name\": \"Invalid\",\n      \"scope\": [\"invalid\", \"invalid.illegal\"],\n      \"settings\": {\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"Keyword\",\n      \"scope\": [\"keyword\", \"storage.type\", \"storage.modifier\"],\n      \"settings\": {\n        \"foreground\": \"#E67E22\"\n      }\n    },\n    {\n      \"name\": \"Storage\",\n      \"scope\": [\"storage.type\", \"storage.modifier\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Operator, Misc\",\n      \"scope\": [\n        \"keyword.control\",\n        \"constant.other.color\",\n        \"punctuation\",\n        \"meta.tag\",\n        \"punctuation.definition.tag\",\n        \"punctuation.separator.inheritance.php\",\n        \"punctuation.definition.tag.html\",\n        \"punctuation.definition.tag.begin.html\",\n        \"punctuation.definition.tag.end.html\",\n        \"punctuation.section.embedded\",\n        \"keyword.other.template\",\n        \"keyword.other.substitution\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FFF\"\n      }\n    },\n    {\n      \"name\": \"Tag\",\n      \"scope\": [\n        \"entity.name.tag\",\n        \"meta.tag.sgml\",\n        \"markup.deleted.git_gutter\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FFF\"\n      }\n    },\n    {\n      \"name\": \"Function, Special Method\",\n      \"scope\": [\n        \"entity.name.function\",\n        \"meta.function-call\",\n        \"variable.function\",\n        \"support.function\",\n        \"keyword.other.special-method\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"Block Level Variables\",\n      \"scope\": [\"meta.block variable.other\"],\n      \"settings\": {\n        \"foreground\": \"#FFF\"\n      }\n    },\n    {\n      \"name\": \"Other Variable, String Link\",\n      \"scope\": [\"support.other.variable\", \"string.other.link\"],\n      \"settings\": {\n        \"foreground\": \"#FFF\"\n      }\n    },\n    {\n      \"name\": \"Number, Constant, Function Argument, Tag Attribute, Embedded\",\n      \"scope\": [\n        \"constant.numeric\",\n        \"constant.language\",\n        \"support.constant\",\n        \"constant.character\",\n        \"constant.escape\",\n        \"keyword.other.unit\",\n        \"keyword.other\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FFF\"\n      }\n    },\n    {\n      \"name\": \"Variable parametar\",\n      \"scope\": [\"variable.parameter\"],\n      \"settings\": {\n        \"foreground\": \"#8558DE\"\n      }\n    },\n    {\n      \"name\": \"String, Symbols, Inherited Class, Markup Heading\",\n      \"scope\": [\n        \"string\",\n        \"constant.other.symbol\",\n        \"constant.other.key\",\n        \"entity.other.inherited-class\",\n        \"markup.heading\",\n        \"markup.inserted.git_gutter\",\n        \"meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#F1C40F\"\n      }\n    },\n    {\n      \"name\": \"Class, Support\",\n      \"scope\": [\n        \"entity.name\",\n        \"support.type\",\n        \"support.class\",\n        \"support.other.namespace.use.php\",\n        \"meta.use.php\",\n        \"support.other.namespace.php\",\n        \"markup.changed.git_gutter\",\n        \"support.type.sys-types\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Entity Types\",\n      \"scope\": [\"support.type\"],\n      \"settings\": {\n        \"foreground\": \"#B2CCD6\"\n      }\n    },\n    {\n      \"name\": \"CSS Class and Support\",\n      \"scope\": [\n        \"source.css support.type.property-name\",\n        \"source.sass support.type.property-name\",\n        \"source.scss support.type.property-name\",\n        \"source.less support.type.property-name\",\n        \"source.stylus support.type.property-name\",\n        \"source.postcss support.type.property-name\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#B2CCD6\"\n      }\n    },\n    {\n      \"name\": \"Sub-methods\",\n      \"scope\": [\n        \"entity.name.module.js\",\n        \"variable.import.parameter.js\",\n        \"variable.other.class.js\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"Language methods\",\n      \"scope\": [\"variable.language\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"entity.name.method.js\",\n      \"scope\": [\"entity.name.method.js\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"meta.method.js\",\n      \"scope\": [\n        \"meta.class-method.js entity.name.function.js\",\n        \"variable.function.constructor\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"Attributes\",\n      \"scope\": [\"entity.other.attribute-name\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"HTML Attributes\",\n      \"scope\": [\n        \"text.html.basic entity.other.attribute-name.html\",\n        \"text.html.basic entity.other.attribute-name\"\n      ],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#FFCB6B\"\n      }\n    },\n    {\n      \"name\": \"CSS Classes\",\n      \"scope\": [\"entity.other.attribute-name.class\"],\n      \"settings\": {\n        \"foreground\": \"#FFCB6B\"\n      }\n    },\n    {\n      \"name\": \"CSS ID's\",\n      \"scope\": [\"source.sass keyword.control\"],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"Inserted\",\n      \"scope\": [\"markup.inserted\"],\n      \"settings\": {\n        \"foreground\": \"#C3E88D\"\n      }\n    },\n    {\n      \"name\": \"Deleted\",\n      \"scope\": [\"markup.deleted\"],\n      \"settings\": {\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"Changed\",\n      \"scope\": [\"markup.changed\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Regular Expressions\",\n      \"scope\": [\"string.regexp\"],\n      \"settings\": {\n        \"foreground\": \"#E67E22\"\n      }\n    },\n    {\n      \"name\": \"Escape Characters\",\n      \"scope\": [\"constant.character.escape\"],\n      \"settings\": {\n        \"foreground\": \"#E67E22\"\n      }\n    },\n    {\n      \"name\": \"URL\",\n      \"scope\": [\"*url*\", \"*link*\", \"*uri*\"],\n      \"settings\": {\n        \"fontStyle\": \"underline\"\n      }\n    },\n    {\n      \"name\": \"Decorators\",\n      \"scope\": [\n        \"tag.decorator.js entity.name.tag.js\",\n        \"tag.decorator.js punctuation.definition.tag.js\"\n      ],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"ES7 Bind Operator\",\n      \"scope\": [\n        \"source.js constant.other.object.key.js string.unquoted.label.js\"\n      ],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 0\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 1\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FFCB6B\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 2\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#F78C6C\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 3\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 4\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#C17E70\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 5\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 6\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FFF\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 7\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 8\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#C3E88D\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Plain\",\n      \"scope\": [\n        \"text.html.markdown\",\n        \"punctuation.definition.list_item.markdown\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#EEFFFF\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Markup Raw Inline\",\n      \"scope\": [\"text.html.markdown markup.inline.raw.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Markup Raw Inline Punctuation\",\n      \"scope\": [\n        \"text.html.markdown markup.inline.raw.markdown punctuation.definition.raw.markdown\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#65737E\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Heading\",\n      \"scope\": [\n        \"markdown.heading\",\n        \"markup.heading | markup.heading entity.name\",\n        \"markup.heading.markdown punctuation.definition.heading.markdown\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#C3E88D\"\n      }\n    },\n    {\n      \"name\": \"Markup - Italic\",\n      \"scope\": [\"markup.italic\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#FFF\"\n      }\n    },\n    {\n      \"name\": \"Markup - Bold\",\n      \"scope\": [\"markup.bold\", \"markup.bold string\"],\n      \"settings\": {\n        \"fontStyle\": \"bold\",\n        \"foreground\": \"#FFF\"\n      }\n    },\n    {\n      \"name\": \"Markup - Bold-Italic\",\n      \"scope\": [\n        \"markup.bold markup.italic\",\n        \"markup.italic markup.bold\",\n        \"markup.quote markup.bold\",\n        \"markup.bold markup.italic string\",\n        \"markup.italic markup.bold string\",\n        \"markup.quote markup.bold string\"\n      ],\n      \"settings\": {\n        \"fontStyle\": \"bold\",\n        \"foreground\": \"#f07178\"\n      }\n    },\n    {\n      \"name\": \"Markup - Underline\",\n      \"scope\": [\"markup.underline\"],\n      \"settings\": {\n        \"fontStyle\": \"underline\",\n        \"foreground\": \"#F78C6C\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Blockquote\",\n      \"scope\": [\"markup.quote punctuation.definition.blockquote.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#65737E\"\n      }\n    },\n    {\n      \"name\": \"Markup - Quote\",\n      \"scope\": [\"markup.quote\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Link\",\n      \"scope\": [\"string.other.link.title.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Link Description\",\n      \"scope\": [\"string.other.link.description.title.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Link Anchor\",\n      \"scope\": [\"constant.other.reference.link.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#FFCB6B\"\n      }\n    },\n    {\n      \"name\": \"Markup - Raw Block\",\n      \"scope\": [\"markup.raw.block\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Raw Block Fenced\",\n      \"scope\": [\"markup.raw.block.fenced.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#00000050\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Fenced Bode Block\",\n      \"scope\": [\"punctuation.definition.fenced.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#00000050\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Fenced Bode Block Variable\",\n      \"scope\": [\n        \"markup.raw.block.fenced.markdown\",\n        \"variable.language.fenced.markdown\",\n        \"punctuation.section.class.end\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#EEFFFF\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Fenced Language\",\n      \"scope\": [\"variable.language.fenced.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#65737E\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Separator\",\n      \"scope\": [\"meta.separator\"],\n      \"settings\": {\n        \"fontStyle\": \"bold\",\n        \"foreground\": \"#65737E\"\n      }\n    },\n    {\n      \"name\": \"Markup - Table\",\n      \"scope\": [\"markup.table\"],\n      \"settings\": {\n        \"foreground\": \"#EEFFFF\"\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "apps/docs/src/assets/themes/daytona-code-light.json",
    "content": "{\n  \"name\": \"daytona-code-light\",\n  \"colors\": {\n    \"editor.background\": \"#ffffff\",\n    \"editor.foreground\": \"#000\",\n    \"activityBarBadge.background\": \"#007acc\",\n    \"sideBarTitle.foreground\": \"#bbbbbb\"\n  },\n  \"tokenColors\": [\n    {\n      \"name\": \"Comment\",\n      \"scope\": [\"comment\", \"punctuation.definition.comment\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#a2a2a2\"\n      }\n    },\n    {\n      \"name\": \"Variables\",\n      \"scope\": [\"variable\", \"string constant.other.placeholder\"],\n      \"settings\": {\n        \"foreground\": \"#8558DE\"\n      }\n    },\n    {\n      \"name\": \"Colors\",\n      \"scope\": [\"constant.other.color\"],\n      \"settings\": {\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"Invalid\",\n      \"scope\": [\"invalid\", \"invalid.illegal\"],\n      \"settings\": {\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"Keyword\",\n      \"scope\": [\"keyword\", \"storage.type\", \"storage.modifier\"],\n      \"settings\": {\n        \"foreground\": \"#E67E22\"\n      }\n    },\n    {\n      \"name\": \"Storage\",\n      \"scope\": [\"storage.type\", \"storage.modifier\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Operator, Misc\",\n      \"scope\": [\n        \"keyword.control\",\n        \"constant.other.color\",\n        \"punctuation\",\n        \"meta.tag\",\n        \"punctuation.definition.tag\",\n        \"punctuation.separator.inheritance.php\",\n        \"punctuation.definition.tag.html\",\n        \"punctuation.definition.tag.begin.html\",\n        \"punctuation.definition.tag.end.html\",\n        \"punctuation.section.embedded\",\n        \"keyword.other.template\",\n        \"keyword.other.substitution\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"Tag\",\n      \"scope\": [\n        \"entity.name.tag\",\n        \"meta.tag.sgml\",\n        \"markup.deleted.git_gutter\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"Function, Special Method\",\n      \"scope\": [\n        \"entity.name.function\",\n        \"meta.function-call\",\n        \"variable.function\",\n        \"support.function\",\n        \"keyword.other.special-method\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"Block Level Variables\",\n      \"scope\": [\"meta.block variable.other\"],\n      \"settings\": {\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"Other Variable, String Link\",\n      \"scope\": [\"support.other.variable\", \"string.other.link\"],\n      \"settings\": {\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"Number, Constant, Function Argument, Tag Attribute, Embedded\",\n      \"scope\": [\n        \"constant.numeric\",\n        \"constant.language\",\n        \"support.constant\",\n        \"constant.character\",\n        \"constant.escape\",\n        \"keyword.other.unit\",\n        \"keyword.other\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"Variable parametar\",\n      \"scope\": [\"variable.parameter\"],\n      \"settings\": {\n        \"foreground\": \"#8558DE\"\n      }\n    },\n    {\n      \"name\": \"String, Symbols, Inherited Class, Markup Heading\",\n      \"scope\": [\n        \"string\",\n        \"constant.other.symbol\",\n        \"constant.other.key\",\n        \"entity.other.inherited-class\",\n        \"markup.heading\",\n        \"markup.inserted.git_gutter\",\n        \"meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#F1C40F\"\n      }\n    },\n    {\n      \"name\": \"Class, Support\",\n      \"scope\": [\n        \"entity.name\",\n        \"support.type\",\n        \"support.class\",\n        \"support.other.namespace.use.php\",\n        \"meta.use.php\",\n        \"support.other.namespace.php\",\n        \"markup.changed.git_gutter\",\n        \"support.type.sys-types\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Entity Types\",\n      \"scope\": [\"support.type\"],\n      \"settings\": {\n        \"foreground\": \"#B2CCD6\"\n      }\n    },\n    {\n      \"name\": \"CSS Class and Support\",\n      \"scope\": [\n        \"source.css support.type.property-name\",\n        \"source.sass support.type.property-name\",\n        \"source.scss support.type.property-name\",\n        \"source.less support.type.property-name\",\n        \"source.stylus support.type.property-name\",\n        \"source.postcss support.type.property-name\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#B2CCD6\"\n      }\n    },\n    {\n      \"name\": \"Sub-methods\",\n      \"scope\": [\n        \"entity.name.module.js\",\n        \"variable.import.parameter.js\",\n        \"variable.other.class.js\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"Language methods\",\n      \"scope\": [\"variable.language\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"entity.name.method.js\",\n      \"scope\": [\"entity.name.method.js\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"meta.method.js\",\n      \"scope\": [\n        \"meta.class-method.js entity.name.function.js\",\n        \"variable.function.constructor\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"Attributes\",\n      \"scope\": [\"entity.other.attribute-name\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"HTML Attributes\",\n      \"scope\": [\n        \"text.html.basic entity.other.attribute-name.html\",\n        \"text.html.basic entity.other.attribute-name\"\n      ],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#FFCB6B\"\n      }\n    },\n    {\n      \"name\": \"CSS Classes\",\n      \"scope\": [\"entity.other.attribute-name.class\"],\n      \"settings\": {\n        \"foreground\": \"#FFCB6B\"\n      }\n    },\n    {\n      \"name\": \"CSS ID's\",\n      \"scope\": [\"source.sass keyword.control\"],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"Inserted\",\n      \"scope\": [\"markup.inserted\"],\n      \"settings\": {\n        \"foreground\": \"#C3E88D\"\n      }\n    },\n    {\n      \"name\": \"Deleted\",\n      \"scope\": [\"markup.deleted\"],\n      \"settings\": {\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"Changed\",\n      \"scope\": [\"markup.changed\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Regular Expressions\",\n      \"scope\": [\"string.regexp\"],\n      \"settings\": {\n        \"foreground\": \"#E67E22\"\n      }\n    },\n    {\n      \"name\": \"Escape Characters\",\n      \"scope\": [\"constant.character.escape\"],\n      \"settings\": {\n        \"foreground\": \"#E67E22\"\n      }\n    },\n    {\n      \"name\": \"URL\",\n      \"scope\": [\"*url*\", \"*link*\", \"*uri*\"],\n      \"settings\": {\n        \"fontStyle\": \"underline\"\n      }\n    },\n    {\n      \"name\": \"Decorators\",\n      \"scope\": [\n        \"tag.decorator.js entity.name.tag.js\",\n        \"tag.decorator.js punctuation.definition.tag.js\"\n      ],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"ES7 Bind Operator\",\n      \"scope\": [\n        \"source.js constant.other.object.key.js string.unquoted.label.js\"\n      ],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 0\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 1\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FFCB6B\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 2\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#F78C6C\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 3\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#FF5370\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 4\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#C17E70\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 5\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 6\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 7\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"JSON Key - Level 8\",\n      \"scope\": [\n        \"source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#C3E88D\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Plain\",\n      \"scope\": [\n        \"text.html.markdown\",\n        \"punctuation.definition.list_item.markdown\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#EEFFFF\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Markup Raw Inline\",\n      \"scope\": [\"text.html.markdown markup.inline.raw.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Markup Raw Inline Punctuation\",\n      \"scope\": [\n        \"text.html.markdown markup.inline.raw.markdown punctuation.definition.raw.markdown\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#65737E\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Heading\",\n      \"scope\": [\n        \"markdown.heading\",\n        \"markup.heading | markup.heading entity.name\",\n        \"markup.heading.markdown punctuation.definition.heading.markdown\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#C3E88D\"\n      }\n    },\n    {\n      \"name\": \"Markup - Italic\",\n      \"scope\": [\"markup.italic\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\",\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"Markup - Bold\",\n      \"scope\": [\"markup.bold\", \"markup.bold string\"],\n      \"settings\": {\n        \"fontStyle\": \"bold\",\n        \"foreground\": \"#000\"\n      }\n    },\n    {\n      \"name\": \"Markup - Bold-Italic\",\n      \"scope\": [\n        \"markup.bold markup.italic\",\n        \"markup.italic markup.bold\",\n        \"markup.quote markup.bold\",\n        \"markup.bold markup.italic string\",\n        \"markup.italic markup.bold string\",\n        \"markup.quote markup.bold string\"\n      ],\n      \"settings\": {\n        \"fontStyle\": \"bold\",\n        \"foreground\": \"#f07178\"\n      }\n    },\n    {\n      \"name\": \"Markup - Underline\",\n      \"scope\": [\"markup.underline\"],\n      \"settings\": {\n        \"fontStyle\": \"underline\",\n        \"foreground\": \"#F78C6C\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Blockquote\",\n      \"scope\": [\"markup.quote punctuation.definition.blockquote.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#65737E\"\n      }\n    },\n    {\n      \"name\": \"Markup - Quote\",\n      \"scope\": [\"markup.quote\"],\n      \"settings\": {\n        \"fontStyle\": \"italic\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Link\",\n      \"scope\": [\"string.other.link.title.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#2ECC71\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Link Description\",\n      \"scope\": [\"string.other.link.description.title.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Link Anchor\",\n      \"scope\": [\"constant.other.reference.link.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#FFCB6B\"\n      }\n    },\n    {\n      \"name\": \"Markup - Raw Block\",\n      \"scope\": [\"markup.raw.block\"],\n      \"settings\": {\n        \"foreground\": \"#3498DB\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Raw Block Fenced\",\n      \"scope\": [\"markup.raw.block.fenced.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#00000050\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Fenced Bode Block\",\n      \"scope\": [\"punctuation.definition.fenced.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#00000050\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Fenced Bode Block Variable\",\n      \"scope\": [\n        \"markup.raw.block.fenced.markdown\",\n        \"variable.language.fenced.markdown\",\n        \"punctuation.section.class.end\"\n      ],\n      \"settings\": {\n        \"foreground\": \"#EEFFFF\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Fenced Language\",\n      \"scope\": [\"variable.language.fenced.markdown\"],\n      \"settings\": {\n        \"foreground\": \"#65737E\"\n      }\n    },\n    {\n      \"name\": \"Markdown - Separator\",\n      \"scope\": [\"meta.separator\"],\n      \"settings\": {\n        \"fontStyle\": \"bold\",\n        \"foreground\": \"#65737E\"\n      }\n    },\n    {\n      \"name\": \"Markup - Table\",\n      \"scope\": [\"markup.table\"],\n      \"settings\": {\n        \"foreground\": \"#EEFFFF\"\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "apps/docs/src/components/ApiBackButton.astro",
    "content": "---\nimport arrowLeft from '@assets/icons/arrow-left.svg?raw'\nimport { localizePath } from '../i18n/utils'\n\nconst pathSegments = Astro.url.pathname.split('/').filter(Boolean)\nconst localeIndex = pathSegments.indexOf('docs') + 1\nconst currentLocale =\n  localeIndex > 0 && pathSegments[localeIndex]\n    ? pathSegments[localeIndex]\n    : 'en'\nconst backHref = localizePath('/docs', currentLocale)\n---\n\n<div class=\"api-page-header\">\n  <a href={backHref} class=\"back-button\">\n    <Fragment set:html={arrowLeft} />\n    Back to Documentation\n  </a>\n</div>\n\n<style>\n  .api-page-header {\n    margin-bottom: 1rem !important;\n  }\n\n  .back-button {\n    display: inline-flex;\n    align-items: center;\n    gap: 0.5rem;\n    padding: 0.5rem 1rem;\n    border: 1px solid var(--border-extra);\n    border-radius: 0.1875rem;\n    text-decoration: none;\n    color: var(--primary-text-color);\n    font-family: 'Inter', sans-serif;\n    font-size: 0.875rem;\n    transition: all 0.2s;\n  }\n\n  .back-button:hover {\n    opacity: 0.8;\n    border-color: var(--hover-color);\n  }\n\n  .back-button svg {\n    flex-shrink: 0;\n    width: 16px;\n    height: 16px;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/ApiReference.astro",
    "content": "---\nimport { ScalarComponent } from '@scalar/astro'\nimport fs from 'node:fs'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nfunction findWorkspaceRoot(startPath: string): string {\n  let current = resolve(startPath)\n  const root = resolve(current, '/')\n\n  while (current !== root) {\n    const nxJson = join(current, 'nx.json')\n\n    if (fs.existsSync(nxJson)) {\n      return current\n    }\n\n    const parent = resolve(current, '..')\n    if (parent === current) break\n    current = parent\n  }\n\n  return process.cwd()\n}\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\nconst workspaceRoot = findWorkspaceRoot(__dirname)\nconst mainApiPath = join(workspaceRoot, 'dist/apps/api/openapi.3.1.0.json')\nconst mainApiSpecRaw = JSON.parse(fs.readFileSync(mainApiPath, 'utf-8'))\nconst mainApiSpec = {\n  ...mainApiSpecRaw,\n  servers: [{ url: 'https://app.daytona.io/api' }],\n}\n\nconst toolboxApiPath = join(\n  workspaceRoot,\n  'apps/daemon/pkg/toolbox/docs/swagger.json'\n)\nconst toolboxApiSpecRaw = JSON.parse(fs.readFileSync(toolboxApiPath, 'utf-8'))\nconst toolboxApiSpec = {\n  ...toolboxApiSpecRaw,\n  servers: [{ url: 'https://proxy.app.daytona.io/toolbox/{sandboxId}' }],\n  info: {\n    ...toolboxApiSpecRaw.info,\n    description: `${toolboxApiSpecRaw.info.description || 'Daytona Daemon API'}\n\nTo get the toolbox proxy URL for your sandbox, call the \\`/api/config\\` endpoint from the main Daytona API. The response includes a \\`proxyToolboxUrl\\` field which provides the base URL template. Replace \\`{sandboxId}\\` in the URL with your actual sandbox ID to get the full toolbox API endpoint for that sandbox.\n\nExample:\n\\`\\`\\`\nGET /api/config\nResponse: { \"proxyToolboxUrl\": \"https://proxy.app.daytona.io/toolbox/{sandboxId}\" }\n\\`\\`\\`\n\nThen use it as: \\`https://proxy.app.daytona.io/toolbox/YOUR_SANDBOX_ID\\``,\n  },\n}\n---\n\n<div id=\"scalar-container\">\n  <ScalarComponent\n    configuration={{\n      sources: [\n        {\n          title: 'Daytona API',\n          slug: 'daytona',\n          content: mainApiSpec,\n          default: true,\n          url: 'https://app.daytona.io/api',\n        },\n        {\n          title: 'Daytona Toolbox API',\n          slug: 'daytona-toolbox',\n          content: toolboxApiSpec,\n          url: 'https://proxy.daytona.io/api',\n        },\n      ],\n      hideClientButton: true,\n      hideTestRequestButton: true,\n      theme: 'default',\n      searchHotKey: 'l',\n      hideDarkModeToggle: true,\n      telemetry: false,\n    }}\n  />\n</div>\n\n<script>\n  function getCurrentTheme(): 'light' | 'dark' {\n    const theme = document.documentElement.dataset.theme\n    if (theme === 'light' || theme === 'dark') {\n      return theme\n    }\n    return window.matchMedia('(prefers-color-scheme: light)').matches\n      ? 'light'\n      : 'dark'\n  }\n\n  function getScalarTheme(docsTheme: 'light' | 'dark'): string {\n    return docsTheme === 'dark' ? 'moon' : 'default'\n  }\n\n  function updateScalarTheme(): void {\n    const docsTheme = getCurrentTheme()\n    const scalarTheme = getScalarTheme(docsTheme)\n\n    const container = document.getElementById('scalar-container')\n    if (!container) return\n\n    const themeSelectors = [\n      'scalar-api',\n      'scalar-component',\n      '[data-scalar]',\n      '#scalar-container > *',\n      '#scalar-container scalar-api',\n      '#scalar-container iframe',\n    ]\n\n    let scalarElements: NodeListOf<Element> | null = null\n    for (const selector of themeSelectors) {\n      const elements = document.querySelectorAll(selector)\n      if (elements.length > 0) {\n        scalarElements = elements\n        break\n      }\n    }\n\n    function traverseShadowDOM(root: Element, callback: (el: Element) => void) {\n      callback(root)\n      if ((root as any).shadowRoot) {\n        const shadowRoot = (root as any).shadowRoot\n        const children = shadowRoot.querySelectorAll('*')\n        children.forEach((child: Element) => {\n          callback(child)\n          traverseShadowDOM(child, callback)\n        })\n      }\n    }\n\n    const allScalarElements: Element[] = []\n    if (scalarElements) {\n      scalarElements.forEach(el => {\n        allScalarElements.push(el)\n        traverseShadowDOM(el, shadowEl => {\n          if (shadowEl.tagName?.toLowerCase().includes('scalar')) {\n            allScalarElements.push(shadowEl)\n          }\n        })\n      })\n    }\n\n    function findAllChildren(parent: Element): Element[] {\n      const children: Element[] = []\n      Array.from(parent.children).forEach(child => {\n        children.push(child)\n        children.push(...findAllChildren(child))\n      })\n      return children\n    }\n\n    const allChildren = findAllChildren(container)\n    allChildren.forEach(el => {\n      if (!allScalarElements.includes(el)) {\n        allScalarElements.push(el)\n      }\n      traverseShadowDOM(el, shadowEl => {\n        if (!allScalarElements.includes(shadowEl)) {\n          allScalarElements.push(shadowEl)\n        }\n      })\n    })\n\n    if (allScalarElements.length === 0) {\n      return\n    }\n\n    allScalarElements.forEach((element: Element) => {\n      const el = element as any\n\n      try {\n        if ('setAttribute' in element) {\n          element.setAttribute('theme', scalarTheme)\n          element.setAttribute('data-theme', scalarTheme)\n          element.setAttribute('data-scalar-theme', scalarTheme)\n        }\n      } catch (e) {}\n\n      try {\n        if (docsTheme === 'dark') {\n          element.classList.add(\n            'dark',\n            'scalar-dark',\n            'theme-dark',\n            'dark-mode'\n          )\n          element.classList.remove(\n            'light',\n            'scalar-light',\n            'theme-light',\n            'light-mode'\n          )\n        } else {\n          element.classList.add(\n            'light',\n            'scalar-light',\n            'theme-light',\n            'light-mode'\n          )\n          element.classList.remove(\n            'dark',\n            'scalar-dark',\n            'theme-dark',\n            'dark-mode'\n          )\n        }\n      } catch (e) {}\n    })\n  }\n\n  function watchForScalar(): void {\n    const container = document.getElementById('scalar-container')\n    if (!container) return\n\n    const scalarObserver = new MutationObserver(() => {\n      updateScalarTheme()\n      showMoreButtonStyles()\n    })\n\n    scalarObserver.observe(container, {\n      childList: true,\n      subtree: true,\n      attributes: false,\n    })\n\n    requestAnimationFrame(() => {\n      requestAnimationFrame(() => {\n        updateScalarTheme()\n        showMoreButtonStyles()\n      })\n    })\n  }\n\n  function watchThemeChanges(): void {\n    const observer = new MutationObserver(mutations => {\n      mutations.forEach(mutation => {\n        if (\n          mutation.type === 'attributes' &&\n          mutation.attributeName === 'data-theme'\n        ) {\n          updateScalarTheme()\n        }\n      })\n    })\n\n    observer.observe(document.documentElement, {\n      attributes: true,\n      attributeFilter: ['data-theme'],\n    })\n  }\n\n  function showMoreButtonStyles(): void {\n    const styleId = 'scalar-show-more-custom-styles'\n    const styleContent = `\n      button.show-more {\n        margin-left: 0px !important;\n        transform: translateX(0px) !important;\n        margin-top: 32px !important;\n      }\n\n      @media (max-width: 768px) {\n        button.show-more {\n          margin-left: auto !important;\n          margin-right: auto !important;\n          display: flex !important;\n          align-items: center !important;\n          justify-content: center !important;\n          white-space: nowrap !important;\n          flex-wrap: nowrap !important;\n        }\n\n        button.show-more > * {\n          flex-shrink: 0 !important;\n          white-space: nowrap !important;\n        }\n      }\n\n      section.section {\n        margin-top: 24px !important;\n        margin-bottom: 24px !important;\n        padding-top: 24px !important;\n        padding-bottom: 24px !important;\n      }\n\n      section.section:first-child {\n        margin-top: 32px !important;\n        padding-top: 0 !important;\n      }\n\n      .scalar-reference-intro-auth h2,\n      .scalar-reference-intro-auth h2 span,\n      .scalar-reference-intro-auth .section-header-label {\n        font-weight: 500 !important;\n        font-size: 0.90rem !important;\n        line-height: 1.5 !important;\n        font-family: 'Inter', sans-serif !important;\n      }\n\n      button.client-libraries {\n        margin-left: 4px !important;\n        margin-right: 4px !important;\n      }\n    `\n\n    if (!document.getElementById(styleId)) {\n      const style = document.createElement('style')\n      style.id = styleId\n      style.textContent = styleContent\n      document.head.appendChild(style)\n    }\n\n    const container = document.getElementById('scalar-container')\n    if (container) {\n      function injectIntoShadowRoots(root: Element) {\n        if ((root as any).shadowRoot) {\n          const shadowRoot = (root as any).shadowRoot\n          const existingStyle = shadowRoot.querySelector(`#${styleId}`)\n          if (!existingStyle) {\n            const shadowStyle = document.createElement('style')\n            shadowStyle.id = styleId\n            shadowStyle.textContent = styleContent\n            shadowRoot.appendChild(shadowStyle)\n          }\n        }\n        Array.from(root.children).forEach(child => {\n          injectIntoShadowRoots(child)\n        })\n      }\n      injectIntoShadowRoots(container)\n    }\n  }\n\n  function initialize(): void {\n    watchForScalar()\n    watchThemeChanges()\n    updateScalarTheme()\n    showMoreButtonStyles()\n\n    setTimeout(() => {\n      showMoreButtonStyles()\n    }, 500)\n  }\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', initialize)\n  } else {\n    initialize()\n  }\n\n  if (window.matchMedia) {\n    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n    mediaQuery.addEventListener('change', () => {\n      const currentTheme = document.documentElement.dataset.theme\n      const systemTheme = window.matchMedia('(prefers-color-scheme: light)')\n        .matches\n        ? 'light'\n        : 'dark'\n\n      if (!currentTheme || currentTheme === systemTheme) {\n        updateScalarTheme()\n      }\n    })\n  }\n</script>\n"
  },
  {
    "path": "apps/docs/src/components/ArchitectureDiagram.astro",
    "content": "---\nimport architectureLight from '@assets/docs/architecture-light.svg'\nimport architectureDark from '@assets/docs/architecture-dark.svg'\n---\n\n<theme-aware-image>\n  <picture>\n    <source\n      srcset={architectureDark.src}\n      data-dark-src={architectureDark.src}\n      data-light-src={architectureLight.src}\n    />\n    <img\n      src={architectureLight.src}\n      alt=\"Daytona architecture diagram\"\n      class=\"architecture-diagram theme-image\"\n    />\n  </picture>\n</theme-aware-image>\n\n<style>\n  .architecture-diagram {\n    width: 100%;\n    height: auto;\n    margin: 2rem 0;\n    display: block;\n  }\n</style>\n\n<script>\n  class ThemeAwareImage extends HTMLElement {\n    constructor() {\n      super()\n      this.updateImage(\n        document.documentElement.dataset.theme as 'light' | 'dark'\n      )\n\n      const observer = new MutationObserver(mutations => {\n        mutations.forEach(mutation => {\n          if (mutation.attributeName === 'data-theme') {\n            const theme = document.documentElement.dataset.theme as\n              | 'light'\n              | 'dark'\n            this.updateImage(theme)\n          }\n        })\n      })\n\n      observer.observe(document.documentElement, {\n        attributes: true,\n        attributeFilter: ['data-theme'],\n      })\n    }\n\n    updateImage(theme: 'light' | 'dark') {\n      const sources = this.querySelectorAll('source')\n      const images = this.querySelectorAll('img')\n\n      sources.forEach(source => {\n        const newSrc =\n          theme === 'dark' ? source.dataset.darkSrc : source.dataset.lightSrc\n        if (newSrc) {\n          source.srcset = newSrc\n        }\n      })\n\n      images.forEach(img => {\n        const source = img.previousElementSibling as HTMLSourceElement\n        if (source) {\n          img.src = source.srcset\n        }\n      })\n    }\n  }\n\n  customElements.define('theme-aware-image', ThemeAwareImage)\n</script>\n"
  },
  {
    "path": "apps/docs/src/components/Aside.astro",
    "content": "---\nimport { AstroError } from 'astro/errors'\nimport bookmarkIcon from '@assets/icons/bookmark.svg?raw'\nimport warningIcon from '@assets/icons/warning.svg?raw'\nimport circleInfoIcon from '@assets/icons/circle-information.svg?raw'\nimport circleErrorIcon from '@assets/icons/circle-error.svg?raw'\n\nconst asideVariants = ['note', 'tip', 'caution', 'danger'] as const\nconst icons = {\n  note: circleInfoIcon,\n  tip: bookmarkIcon,\n  caution: warningIcon,\n  danger: circleErrorIcon,\n} as const\n\ninterface Props {\n  type?: (typeof asideVariants)[number]\n  title?: string\n}\n\nlet { type = 'note', title } = Astro.props\n\nif (!asideVariants.includes(type)) {\n  throw new AstroError(\n    'Invalid `type` prop passed to the `<Aside>` component.\\n',\n    `Received: ${JSON.stringify(type)}\\n` +\n      `Expected one of ${asideVariants.map(i => JSON.stringify(i)).join(', ')}`\n  )\n}\n\nif (!title) {\n  title = type\n}\n---\n\n<aside aria-label={title} class={`starlight-aside starlight-aside--${type}`}>\n  <p class=\"starlight-aside__title\" aria-hidden=\"true\">\n    <Fragment set:html={icons[type]} />\n    {title}\n  </p>\n  <section class=\"starlight-aside__content\">\n    <slot />\n  </section>\n</aside>\n"
  },
  {
    "path": "apps/docs/src/components/ContentPanel.astro",
    "content": "---\n\n---\n\n<div class=\"content-panel\">\n  <div class=\"sl-container\"><slot /></div>\n</div>\n\n<style>\n  .sl-container {\n    > h1 {\n      margin-top: 28px;\n    }\n\n    @media (max-width: 1024px) {\n      > h1 {\n        margin-top: 8px;\n      }\n    }\n  }\n\n  .sl-container {\n    display: flex;\n    flex-direction: column;\n    gap: 24px;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/EditLink.astro",
    "content": "---\nimport editIcon from '@assets/icons/edit.svg?raw'\n\nconst { editUrl } = Astro.props\n---\n\n{\n  editUrl && (\n    <a href={editUrl} class=\"edit-link\">\n      <Fragment set:html={editIcon} />\n      {Astro.locals.t('page.editLink' as any)}\n    </a>\n  )\n}\n\n<style>\n  .edit-link {\n    display: flex;\n    gap: 8px;\n    font-family: 'Inter', sans-serif;\n    font-weight: 500;\n    font-size: 0.75rem;\n    line-height: 1.4;\n    letter-spacing: -0.02em;\n    color: var(--primary-text-color);\n    > svg {\n      width: 1rem;\n      height: 1rem;\n\n      > path {\n        fill: var(--primary-text-color);\n      }\n    }\n    &:hover {\n      transition: 0.6s opacity;\n      opacity: 0.6;\n    }\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/ExploreMore.astro",
    "content": "---\nimport { getExploreMoreData } from '../utils/navigation'\nimport { getSidebarConfig } from '../content/config'\n\nconst { expanded } = Astro.props\nconst exploreMoreData = getExploreMoreData(\n  getSidebarConfig(Astro.props.lang, (key: string) => {\n    try {\n      return Astro.locals?.t?.(key as any) || key\n    } catch {\n      return key\n    }\n  }),\n  Astro.url.pathname\n)\nconst gridColumn = expanded ? 'span 2' : 'inherit'\nconst style = `grid-column: ${gridColumn};`\n---\n\n{\n  exploreMoreData.map(group => (\n    <section>\n      <h1>{group.title || Astro.locals.t('exploreMore.exploreMore' as any)}</h1>\n      <ul>\n        {group.items.map(item => (\n          <a href={item.href} style={style}>\n            <li>\n              <span class=\"document-title\">{item.title}</span>\n              <br />\n              <span class=\"subtitle\">{item.subtitle}</span>\n            </li>\n          </a>\n        ))}\n      </ul>\n    </section>\n  ))\n}\n\n<style>\n  section {\n    all: unset;\n  }\n\n  h1 {\n    all: unset;\n    font-family: 'Berkeley Mono', monospace;\n    font-weight: 700;\n    font-size: 2em;\n  }\n\n  ul {\n    all: unset;\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    gap: 1em;\n  }\n\n  a {\n    display: block;\n    width: 100%;\n    height: 100%;\n    background: var(--block-bg-color);\n    border: var(--border);\n    border-color: var(--block-bg-color);\n  }\n\n  a:hover {\n    background: var(--secondary-text-color);\n    border-color: var(--secondary-text-color);\n  }\n\n  li {\n    display: inline-block;\n    padding: 1em;\n    width: 100%;\n    height: 100%;\n  }\n\n  .document-title {\n    font-weight: bold;\n  }\n\n  .subtitle {\n    font-weight: normal;\n    font-size: 0.8em;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/Footer.astro",
    "content": "---\nimport textArrowIcon from '@assets/icons/text-arrow.svg?raw'\nimport Default from '@astrojs/starlight/components/Footer.astro'\nimport { major, minor } from 'semver'\nimport ThemeSelect from './ThemeSelect.astro'\nimport { LocaleSelect } from './menu/LocaleSelector'\n\nconst version = import.meta.env.VERSION || '0.0.1'\nconst [maj, min] = [major(version), minor(version)]\nconst release = `${maj}.${min}`\n// TODO: switch to SDK\n\nconst releaseLink = `https://github.com/daytonaio/daytona/releases/tag/v${release}.0`\n---\n\n<Default {...Astro.props as any}>\n  <slot />\n</Default>\n<footer class=\"docs-footer__container\">\n  <div class=\"docs-footer__container__support-links\">\n    <p>\n      <Fragment set:html={textArrowIcon} />{\n        Astro.locals.t('footer.needHelp' as any)\n      } -\n      <a href=\"https://go.daytona.io/slack\"\n        >{Astro.locals.t('footer.reachSupport' as any)}</a\n      >\n    </p>\n    <p>\n      <Fragment set:html={textArrowIcon} />{\n        Astro.locals.t('footer.latestUpdates' as any)\n      } - <a href=\"https://github.com/daytonaio/daytona/commits/main/\"\n        >{Astro.locals.t('footer.viewChangelog' as any)}</a\n      >\n    </p>\n    <p>\n      <Fragment set:html={textArrowIcon} />{\n        Astro.locals.t('footer.dotfilesInsider' as any)\n      } - <a href=\"https://www.daytona.io/dotfiles/\"\n        >{Astro.locals.t('footer.readBlog' as any)}</a\n      >\n    </p>\n    <p>\n      <Fragment set:html={textArrowIcon} />{\n        Astro.locals.t('footer.LLMs' as any)\n      } -\n      <a href=\"https://www.daytona.io/docs/llms.txt\">llms.txt</a> &\n      <a href=\"https://www.daytona.io/docs/llms-full.txt\">llms-full.txt</a>\n    </p>\n  </div>\n\n  <div class=\"docs-footer__container__bottom\">\n    <div class=\"docs-footer__container__bottom-block\">\n      <div><p>© {new Date().getFullYear()} Daytona Platforms, Inc.</p></div>\n      <div class=\"divider\"></div>\n    </div>\n\n    <div class=\"footer-selects\">\n      <LocaleSelect client:load locale={Astro.props.lang} />\n      <ThemeSelect />\n    </div>\n    <div class=\"menu-list\">\n      <a href=\"https://www.daytona.io/company/privacy-policy\"\n        >{Astro.locals.t('footer.privacyPolicy' as any)}</a\n      >\n      <a href=\"https://www.daytona.io/company/terms-of-service\"\n        >{Astro.locals.t('footer.termsOfService' as any)}</a\n      >\n    </div>\n  </div>\n</footer>\n\n<style>\n  .footer-selects {\n    display: flex;\n    gap: 8px;\n    justify-content: flex-end;\n    align-items: center;\n\n    order: 2;\n    margin-left: auto;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/GuidesList.astro",
    "content": "---\nimport { getCollection } from 'astro:content'\nimport { getSidebarConfig, NavigationCategory } from '../content/config'\nimport type { NavigationGroup, NavigationLink } from '../utils/navigation'\n\ninterface Props {\n  lang?: string\n  category?: string\n}\n\ninterface GuideItem {\n  href: string\n  title: string\n  description?: string\n}\n\nconst { category, lang = 'en' } = Astro.props\n\nconst sidebarConfig = getSidebarConfig(lang, (key: string) => {\n  try {\n    return Astro.locals?.t?.(key as any) || key\n  } catch {\n    return key\n  }\n})\n\nconst guidesGroups = sidebarConfig.filter(\n  (group: NavigationGroup) => group.category === NavigationCategory.GUIDES\n)\n\nlet navLinks: NavigationLink[]\n\nif (category) {\n  // When filtering by category, include all guides in that category (even hidden ones)\n  navLinks = guidesGroups.flatMap((group: NavigationGroup) =>\n    (group.entries || []).filter(\n      (entry: NavigationLink) =>\n        entry.type === 'link' && entry.href.includes(`/guides/${category}/`)\n    )\n  ) as NavigationLink[]\n} else {\n  // For main guides page, only show non-hidden entries\n  navLinks = guidesGroups.flatMap((group: NavigationGroup) =>\n    (group.entries || []).filter(\n      (entry: NavigationLink) => !entry.hideInSidebar && entry.type === 'link'\n    )\n  ) as NavigationLink[]\n}\n\n// Get all docs to fetch actual titles\nconst allDocs = await getCollection('docs')\n\n// Map navigation links to guide items with actual titles from frontmatter\nconst guides: GuideItem[] = navLinks.map(link => {\n  // Convert href to slug format (remove /docs/en/ prefix)\n  const slug = link.href.replace(/^\\/docs\\//, '').replace(/^en\\//, 'en/')\n\n  // Find matching doc\n  const doc = allDocs.find(\n    d => d.slug === slug || d.slug === slug.replace(/\\/$/, '')\n  )\n\n  return {\n    href: link.href,\n    title: doc?.data?.title || link.label,\n    description: doc?.data?.description || link.description,\n  }\n})\n---\n\n<div class=\"guides-list\">\n  <ul>\n    {\n      guides.map(guide => (\n        <a href={guide.href}>\n          <li>\n            <span class=\"guide-title\">{guide.title}</span>\n            {guide.description && (\n              <span class=\"guide-description\">{guide.description}</span>\n            )}\n          </li>\n        </a>\n      ))\n    }\n  </ul>\n</div>\n\n<style>\n  .guides-list {\n    margin-top: 2em;\n  }\n\n  ul {\n    all: unset;\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    gap: 1em;\n  }\n\n  @media (max-width: 768px) {\n    ul {\n      grid-template-columns: 1fr;\n    }\n  }\n\n  a,\n  a:hover,\n  a:visited,\n  a:active {\n    display: block;\n    width: 100%;\n    height: 100%;\n    background: var(--block-bg-color);\n    border: var(--border);\n    border-color: var(--block-bg-color);\n    border-radius: 4px;\n    transition: all 0.15s;\n    text-decoration: none !important;\n  }\n\n  a:hover {\n    background: var(--secondary-text-color);\n    border-color: var(--secondary-text-color);\n  }\n\n  a * {\n    text-decoration: none !important;\n  }\n\n  li {\n    display: flex;\n    flex-direction: column;\n    padding: 1em;\n    width: 100%;\n    min-height: 160px;\n    box-sizing: border-box;\n  }\n\n  .guide-title {\n    font-weight: bold;\n    line-height: 1.4;\n    display: -webkit-box;\n    -webkit-line-clamp: 2;\n    -webkit-box-orient: vertical;\n    overflow: hidden;\n  }\n\n  .guide-description {\n    font-weight: normal;\n    font-size: 0.9em;\n    color: var(--secondary-text-color);\n    margin-top: 0.9em;\n    display: -webkit-box;\n    -webkit-line-clamp: 4;\n    -webkit-box-orient: vertical;\n    overflow: hidden;\n  }\n\n  a:hover .guide-description {\n    color: var(--primary-text-color);\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/Head.astro",
    "content": "---\nimport type { Props } from '@astrojs/starlight/props'\nimport Default from '@astrojs/starlight/components/Head.astro'\nimport PostHog from '@components/PostHog.astro'\nconst image = '/docs/daytona.png'\n---\n\n<Default {...Astro.props}><slot /></Default>\n<meta name=\"image\" property=\"og:image\" content={image} />\n<meta property=\"og:image:secure_url\" content={image} />\n<meta property=\"og:image:type\" content=\"image/png\" />\n<meta property=\"og:image:width\" content=\"1248\" />\n<meta property=\"og:image:height\" content=\"628\" />\n<meta property=\"og:image:alt\" content=\"Daytona\" />\n<meta name=\"algolia-site-verification\" content=\"2988B4D95ECF88B6\" />\n{import.meta.env.PROD && <PostHog />}\n"
  },
  {
    "path": "apps/docs/src/components/Header.astro",
    "content": "---\nimport daytonaLogo from '@assets/icons/daytona-logo.svg?raw'\nimport searchIcon from '@assets/icons/search.svg?raw'\nimport packageIcon from '@assets/sidebar/package.svg?raw'\nimport serverIcon from '@assets/sidebar/server.svg?raw'\nimport terminalIcon from '@assets/sidebar/terminal.svg?raw'\nimport Search from '@components/Search'\nimport Version from '@components/Version.astro'\nimport gtconfig from '../../gt.config.json'\nimport '../styles/components/search.scss'\nimport { SideNavLinks } from './menu/SideNavLinks'\nimport { getHeaderActiveState } from '@utils/navigation'\n\nconst PUBLIC_WEB_URL = (\n  import.meta.env.PUBLIC_WEB_URL || 'https://daytona.io'\n).replace(/\\/$/, '')\n\n// Disable search for translations (for now)\nconst algoliaEnabled =\n  import.meta.env.PUBLIC_ALGOLIA_APP_ID &&\n  import.meta.env.PUBLIC_ALGOLIA_API_KEY &&\n  Astro.props.lang === gtconfig.defaultLocale\n\n// Show search in production when enabled, or always in dev mode\nconst showSearch = algoliaEnabled || import.meta.env.DEV\n\nconst {\n  isTypescriptSdkActive,\n  isPythonSdkActive,\n  isRubySdkActive,\n  isGoSdkActive,\n  isApiActive,\n  isCliActive,\n  isReferencesActive,\n  isGuidesActive,\n} = getHeaderActiveState(import.meta.env.BASE_URL, Astro.url.pathname)\n---\n\n<header class=\"navbar\">\n  <nav class=\"desktop-only\">\n    <div class=\"logo-divider\">\n      <a\n        href={import.meta.env.BASE_URL}\n        aria-label=\"Daytona\"\n        class=\"daytona-logo\"\n      >\n        <Fragment set:html={daytonaLogo} />\n      </a>\n    </div>\n    <div class=\"navbar-links\">\n      <div class=\"dropdown\">\n        <span class:list={['dropdown-trigger', { active: isReferencesActive }]}>\n          {Astro.locals.t('header.references' as any)}\n          <svg\n            class=\"chevron\"\n            width=\"10\"\n            height=\"6\"\n            viewBox=\"0 0 10 6\"\n            fill=\"none\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n          >\n            <path\n              d=\"M1 1L5 5L9 1\"\n              stroke=\"currentColor\"\n              stroke-width=\"1.5\"\n              stroke-linecap=\"round\"\n              stroke-linejoin=\"round\"></path>\n          </svg>\n        </span>\n        <div class=\"dropdown-menu\">\n          <a\n            href={`${import.meta.env.BASE_URL}/en/typescript-sdk`}\n            class:list={[{ active: isTypescriptSdkActive }]}\n          >\n            <Fragment set:html={packageIcon} />\n            {Astro.locals.t('sidebarconfig.tsSdkReference' as any)}\n          </a>\n          <a\n            href={`${import.meta.env.BASE_URL}/en/python-sdk`}\n            class:list={[{ active: isPythonSdkActive }]}\n          >\n            <Fragment set:html={packageIcon} />\n            {Astro.locals.t('sidebarconfig.pythonSdkReference' as any)}\n          </a>\n          <a\n            href={`${import.meta.env.BASE_URL}/en/ruby-sdk`}\n            class:list={[{ active: isRubySdkActive }]}\n          >\n            <Fragment set:html={packageIcon} />\n            {Astro.locals.t('sidebarconfig.rubySdkReference' as any)}\n          </a>\n          <a\n            href={`${import.meta.env.BASE_URL}/en/go-sdk`}\n            class:list={[{ active: isGoSdkActive }]}\n          >\n            <Fragment set:html={packageIcon} />\n            {Astro.locals.t('sidebarconfig.goSdkReference' as any)}\n          </a>\n          <a\n            href={`${import.meta.env.BASE_URL}/en/tools/api`}\n            class:list={[{ active: isApiActive }]}\n          >\n            <Fragment set:html={serverIcon} />\n            {Astro.locals.t('sidebarconfig.apiReference' as any)}\n          </a>\n          <a\n            href={`${import.meta.env.BASE_URL}/en/tools/cli`}\n            class:list={[{ active: isCliActive }]}\n          >\n            <Fragment set:html={terminalIcon} />\n            {Astro.locals.t('sidebarconfig.cliReference' as any)}\n          </a>\n        </div>\n      </div>\n      <a href={`/docs/en/guides`} class:list={[{ active: isGuidesActive }]}\n        >{Astro.locals.t('header.guides' as any)}\n      </a>\n      <a href=\"https://www.daytona.io/changelog\"\n        >{Astro.locals.t('header.changelog' as any)}\n      </a>\n    </div>\n    <div class=\"nav__items_side_menu\">\n      <a href={import.meta.env.BASE_URL} class=\"dotfiles-logo\">v<Version /> </a>\n      {\n        showSearch && (\n          <button id=\"search-icon\" class=\"search-click search-click-desktop\">\n            <div class=\"search-label\">\n              <Fragment set:html={searchIcon} />\n              Search\n            </div>\n            <kbd>⌘ K</kbd>\n          </button>\n        )\n      }\n      <SideNavLinks client:load locale={Astro.props.lang} />\n    </div>\n  </nav>\n  <nav class=\"mobile-navigation\">\n    <div class=\"blur-section\">\n      <a\n        href={import.meta.env.BASE_URL}\n        aria-label=\"Daytona\"\n        class=\"daytona-logo blur-section\"\n      >\n        <Fragment set:html={daytonaLogo} />\n      </a>\n    </div>\n    {\n      showSearch && (\n        <p id=\"search-icon-mobile\" class=\"search-click\">\n          <Fragment set:html={searchIcon} />\n        </p>\n      )\n    }\n  </nav>\n</header>\n\n{\n  // Skip search for translations (for now)\n  showSearch && <Search client:load locale={Astro.props.lang} />\n}\n\n<style>\n  .navbar-links {\n    display: flex;\n    align-items: center;\n    gap: 16px;\n  }\n\n  .navbar-links > a,\n  .navbar-links .dropdown-trigger {\n    text-transform: uppercase;\n    font-size: 14px;\n    font-family: 'Berkeley Mono', monospace;\n    color: var(--primary-text-color);\n    transition: all 0.2s;\n    font-weight: 400;\n    letter-spacing: -0.01rem;\n    cursor: pointer;\n    &:hover {\n      color: var(--hover-color);\n    }\n  }\n\n  .navbar-links .dropdown-trigger.active,\n  .navbar-links > a.active {\n    color: var(--hover-color);\n  }\n\n  .dropdown {\n    position: relative;\n  }\n\n  .dropdown-trigger {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n  }\n\n  .dropdown-trigger .chevron {\n    width: 8px;\n    height: 8px;\n    transition: transform 0.3s;\n  }\n\n  .dropdown:hover .dropdown-trigger .chevron {\n    transform: rotate(180deg);\n  }\n\n  .dropdown-menu {\n    position: absolute;\n    top: 100%;\n    left: 0px;\n    min-width: 200px;\n    background-color: var(--block-bg-color);\n    border: 1px solid var(--border-color);\n    border-radius: 4px;\n    padding: 8px 0;\n    opacity: 0;\n    visibility: hidden;\n    transform: translateY(8px);\n    transition: all 0.2s;\n    z-index: 100;\n    margin-top: 8px;\n  }\n\n  .dropdown:hover .dropdown-menu {\n    opacity: 1;\n    visibility: visible;\n    transform: translateY(0);\n  }\n\n  .dropdown-menu a {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    padding: 8px 16px;\n    font-size: 14px;\n    font-family: 'Berkeley Mono', monospace;\n    color: var(--primary-text-color);\n    text-transform: none;\n    transition: all 0.15s;\n    &:hover {\n      background-color: var(--hover-bg-color, rgba(255, 255, 255, 0.05));\n      color: var(--hover-color);\n    }\n    &.active {\n      background-color: var(--hover-bg-color, rgba(255, 255, 255, 0.05));\n      color: var(--hover-color);\n    }\n  }\n\n  .dropdown-menu a :global(svg) {\n    width: 16px;\n    height: 16px;\n    flex-shrink: 0;\n  }\n\n  .dropdown-menu a :global(svg path) {\n    fill: currentColor;\n  }\n\n  .search-click-desktop {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 14px;\n    font-weight: 500;\n    color: var(--secondary-text-color);\n    cursor: pointer;\n    gap: 42px;\n    border: 1px solid var(--border-color);\n    border-radius: 3px;\n    padding: 3px 4px 3px 8px;\n    transition: all 0.15s;\n    background-color: transparent;\n    max-width: 250px;\n    margin: 0 auto;\n    width: 100%;\n    display: flex;\n    justify-content: space-between;\n  }\n\n  .search-click:hover {\n    color: var(--primary-text-color);\n    background-color: var(--block-bg-color);\n  }\n\n  .search-label {\n    display: flex;\n    align-items: center;\n    gap: 4px;\n\n    svg {\n      height: 16px;\n      width: 16px;\n    }\n  }\n\n  .search-click kbd {\n    background-color: var(--block-bg-color);\n    border-radius: 3px;\n    padding: 1px 4px;\n    font-size: 12px;\n    font-weight: 500;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/Hero.astro",
    "content": "---\nimport { PAGE_TITLE_ID } from './TableOfContent/constants'\nconst { data } = Astro.props.entry\nconst { title = data.title, tagline, image, actions = [] } = data.hero || {}\n---\n\n<div class=\"hero\">\n  <h1 id={PAGE_TITLE_ID} data-page-title set:html={title} />\n  {tagline && <div class=\"tagline\" set:html={tagline} />}\n</div>\n\n<style>\n  .hero {\n    display: grid;\n    grid-template-columns: 100%;\n    margin-top: 40px;\n    margin-bottom: 60px;\n    @include for-mobile-screen-sizes {\n      margin-bottom: 40px;\n    }\n\n    .hero-highlight {\n      color: var(--hover-color);\n    }\n    .hero-lowlight {\n      color: var(--secondary-text-color);\n    }\n  }\n  .tagline {\n    font-family: 'Inter', sans-serif;\n    font-weight: 500;\n    font-size: 1.25rem;\n    letter-spacing: -0.01em;\n    line-height: 1.5;\n    color: var(--primary-text-color);\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/Image.astro",
    "content": "---\nimport { Image as AstroImage } from 'astro:assets'\n\nconst { imageAlt, iconLight, iconDark, height, width } = Astro.props\n---\n\n<theme-aware-image>\n  <picture class=\"cursor-pointer\">\n    <source\n      srcset={iconDark.src}\n      data-dark-src={iconDark.src}\n      data-light-src={iconLight.src}\n    />\n    <AstroImage\n      src={iconLight}\n      alt={imageAlt}\n      style={`height: ${height || 'auto'}; width: ${width || 'auto'};`}\n      class=\"theme-image\"\n    />\n  </picture>\n\n  <dialog class=\"modal\">\n    <picture class=\"modal-picture\">\n      <source\n        srcset={iconDark.src}\n        data-dark-src={iconDark.src}\n        data-light-src={iconLight.src}\n      />\n      <AstroImage\n        src={iconLight}\n        alt={imageAlt}\n        class=\"modal-image theme-image\"\n      />\n    </picture>\n    <button class=\"close-button\" aria-label=\"Close modal\">X</button>\n  </dialog>\n</theme-aware-image>\n\n<style>\n  .modal {\n    padding: 0;\n    border: none;\n    background: rgba(0, 0, 0, 0.8);\n    width: 100vw;\n    height: 100vh;\n    max-width: 100vw;\n    max-height: 100vh;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n  }\n\n  .modal:not([open]) {\n    display: none;\n  }\n\n  .modal::backdrop {\n    background: rgba(0, 0, 0, 0.8);\n  }\n\n  .modal-image {\n    max-width: 90vw;\n    max-height: 90vh;\n    object-fit: contain;\n  }\n\n  .close-button {\n    position: absolute;\n    top: 2rem;\n    right: 2rem;\n    background: white;\n    border: none;\n    border-radius: 50%;\n    width: 2rem;\n    height: 2rem;\n    font-size: 1.5rem;\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    padding: 0;\n    color: black;\n  }\n\n  .close-button:hover {\n    background: #eee;\n  }\n\n  .cursor-pointer {\n    cursor: pointer;\n  }\n</style>\n\n<script>\n  class ThemeAwareImage extends HTMLElement {\n    constructor() {\n      super()\n      this.setupModal()\n      this.updateImage(\n        document.documentElement.dataset.theme as 'light' | 'dark'\n      )\n\n      const observer = new MutationObserver(mutations => {\n        mutations.forEach(mutation => {\n          if (mutation.attributeName === 'data-theme') {\n            const theme = document.documentElement.dataset.theme as\n              | 'light'\n              | 'dark'\n            this.updateImage(theme)\n          }\n        })\n      })\n\n      observer.observe(document.documentElement, {\n        attributes: true,\n        attributeFilter: ['data-theme'],\n      })\n    }\n\n    setupModal() {\n      const mainPicture = this.querySelector('picture:not(.modal-picture)')\n      const modal = this.querySelector('dialog')\n      const closeButton = modal?.querySelector('.close-button')\n\n      if (mainPicture && modal) {\n        mainPicture.addEventListener('click', () => {\n          modal.showModal()\n        })\n\n        closeButton?.addEventListener('click', () => {\n          modal.close()\n        })\n\n        modal.addEventListener('click', e => {\n          if (e.target === modal) {\n            modal.close()\n          }\n        })\n\n        document.addEventListener('keydown', e => {\n          if (e.key === 'Escape' && modal.open) {\n            modal.close()\n          }\n        })\n      }\n    }\n\n    updateImage(theme: 'light' | 'dark') {\n      const sources = this.querySelectorAll('source')\n      const images = this.querySelectorAll('img')\n\n      sources.forEach(source => {\n        const newSrc =\n          theme === 'dark' ? source.dataset.darkSrc : source.dataset.lightSrc\n        if (newSrc) {\n          source.srcset = newSrc\n        }\n      })\n\n      images.forEach(img => {\n        const source = img.previousElementSibling as HTMLSourceElement\n        if (source) {\n          img.src = source.srcset\n        }\n      })\n    }\n  }\n\n  customElements.define('theme-aware-image', ThemeAwareImage)\n</script>\n"
  },
  {
    "path": "apps/docs/src/components/Keyboard.astro",
    "content": "---\ninterface Props {\n  shortcuts: string | string[]\n}\nconst { shortcuts } = Astro.props\n---\n\n{\n  !Array.isArray(shortcuts) ? (\n    <span class=\"keyboard-shortcut\">{shortcuts}</span>\n  ) : (\n    shortcuts.map((shortcut, index) => {\n      return (\n        <>\n          {' '}\n          <span class=\"keyboard-shortcut\">{shortcut}</span>\n          {index === shortcuts.length - 1 ? ' ' : ' + '}\n        </>\n      )\n    })\n  )\n}\n"
  },
  {
    "path": "apps/docs/src/components/Label.astro",
    "content": "<aside class=\"label\">\n  <section class=\"starlight-aside__content\">\n    <slot />\n  </section>\n</aside>\n"
  },
  {
    "path": "apps/docs/src/components/MarkdownContent.astro",
    "content": "<div class=\"markdown-content\"><slot /></div>\n\n<script>\n  document.addEventListener('DOMContentLoaded', function () {\n    let tables = document.querySelectorAll('table')\n\n    if (tables.length > 0) {\n      tables.forEach(table => {\n        let wrapperDiv = document.createElement('div')\n        wrapperDiv.classList.add('table-wrapper')\n        if (table.parentNode) {\n          table.parentNode.insertBefore(wrapperDiv, table)\n          wrapperDiv.appendChild(table)\n        }\n      })\n    }\n\n    const headings = document.querySelectorAll(\n      '.markdown-content h2[id], .markdown-content h3[id], .markdown-content h4[id], .markdown-content h5[id]'\n    )\n    const filteredHeadings = Array.from(headings).filter(\n      heading => !heading.closest('#scalar-container')\n    )\n\n    filteredHeadings.forEach(heading => {\n      const anchor = document.createElement('a')\n      anchor.href = `#${heading.id}`\n      anchor.className = 'heading-anchor'\n      anchor.setAttribute('aria-hidden', 'true')\n      anchor.textContent = '#'\n      heading.prepend(anchor)\n\n      heading.addEventListener('click', function (e) {\n        if (e.target === anchor) return\n        document.querySelectorAll('.heading-anchor.visible').forEach(a => {\n          if (a !== anchor) a.classList.remove('visible')\n        })\n        anchor.classList.toggle('visible')\n      })\n\n      anchor.addEventListener('click', function () {\n        anchor.classList.remove('visible')\n      })\n    })\n\n    document.addEventListener('click', function (e) {\n      const target = e.target as HTMLElement\n      if (!target.closest('h2, h3, h4, h5')) {\n        document.querySelectorAll('.heading-anchor.visible').forEach(a => {\n          a.classList.remove('visible')\n        })\n      }\n    })\n  })\n</script>\n"
  },
  {
    "path": "apps/docs/src/components/MobileMenuToggle.astro",
    "content": "---\nimport menuIcon from '@assets/icons/menu.svg?raw'\nimport closeXIcon from '@assets/icons/closeX.svg?raw'\n---\n\n<starlight-menu-button>\n  <div id=\"blur-overlay\"></div>\n  <button\n    aria-expanded=\"false\"\n    aria-label={Astro.locals.t('menuButton.accessibleLabel' as any)}\n    aria-controls=\"starlight__sidebar\"\n  >\n    <Fragment set:html={menuIcon} />\n    <Fragment set:html={closeXIcon} />\n  </button>\n</starlight-menu-button>\n\n<script>\n  class StarlightMenuButton extends HTMLElement {\n    btn = this.querySelector('button')!\n\n    constructor() {\n      super()\n      // Toggle `aria-expanded` state when a user clicks the button.\n      this.btn.addEventListener('click', () => this.toggleExpanded())\n\n      // Close the menu when a user presses the escape key.\n      const parentNav = this.closest('nav')\n      if (parentNav) {\n        parentNav.addEventListener('keyup', e => this.closeOnEscape(e))\n      }\n    }\n\n    setExpanded(expanded: boolean) {\n      this.setAttribute('aria-expanded', String(expanded))\n      document.body.toggleAttribute('data-mobile-menu-expanded', expanded)\n    }\n\n    toggleExpanded() {\n      this.setExpanded(this.getAttribute('aria-expanded') !== 'true')\n    }\n\n    closeOnEscape(e: KeyboardEvent) {\n      if (e.code === 'Escape') {\n        this.setExpanded(false)\n        this.btn.focus()\n      }\n    }\n  }\n\n  customElements.define('starlight-menu-button', StarlightMenuButton)\n</script>\n\n<style>\n  button {\n    display: none;\n    position: fixed;\n    top: calc((74px - var(--sl-menu-button-size)) / 2);\n    inset-inline-end: var(--sl-nav-pad-x);\n    z-index: var(--sl-z-index-navbar);\n    padding: 0.5rem;\n    background-color: unset;\n    border: var(--border);\n    cursor: pointer;\n    right: 40px;\n\n    > svg:last-child {\n      display: none;\n    }\n\n    > svg path {\n      fill: var(--primary-text-color);\n    }\n\n    @media (max-width: 1024px) {\n      display: flex;\n    }\n    @media (max-width: 650px) {\n      right: 20px;\n    }\n  }\n  [aria-expanded='true'] button {\n    box-shadow: none;\n    > svg:first-child {\n      display: none;\n    }\n    > svg:last-child {\n      display: block;\n    }\n  }\n\n  [aria-expanded='true'] #blur-overlay {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 4;\n    background-color: rgba(22, 22, 22, 0.8);\n    backdrop-filter: blur(2px);\n  }\n</style>\n\n<style is:global>\n  [data-mobile-menu-expanded] {\n    overflow: auto;\n  }\n\n  @media (max-width: 1024px) {\n    [data-mobile-menu-expanded] {\n      overflow: hidden;\n    }\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/OpenPageDropdown/OpenPageDropdown.module.scss",
    "content": ".dropdownMenuTrigger {\n  display: flex;\n  align-items: center;\n  padding: 0.25rem 0.5rem;\n  gap: 0.5rem;\n  border: 1px solid var(--border-color);\n  border-radius: 0.25rem;\n\n  background-color: var(--block-bg-color);\n  color: var(--foreground-color);\n\n  font-size: 0.875rem;\n  line-height: 1rem;\n  font-weight: 500;\n  user-select: none;\n\n  &:focus,\n  &:hover,\n  &[data-state='open'] {\n    background-color: var(--cta-surface-neutral-primary);\n  }\n  cursor: pointer;\n}\n\n.dropdownMenuContent {\n  position: relative;\n  z-index: 50;\n  min-width: 8rem;\n  max-height: var(--radix-dropdownMenucontent-available-height);\n  padding: 0.25rem;\n  overflow: hidden auto;\n  transform-origin: var(--radix-dropdownMenucontent-transform-origin);\n  animation-duration: 0.2s;\n  animation-timing-function: ease-out;\n  border: 1px solid var(--border-color);\n  border-radius: 0.375rem;\n  background-color: var(--block-bg-color);\n  box-shadow:\n    0 4px 6px -1px rgba(0, 0, 0, 0.1),\n    0 2px 4px -1px rgba(0, 0, 0, 0.06);\n  color: var(--text-color);\n\n  &[data-side='bottom'] {\n    animation-name: slideUpAndFade;\n  }\n\n  .dropdownMenuItem {\n    display: flex;\n    align-items: center;\n    padding: 0.5rem 0.5rem;\n    border-radius: 0.25rem;\n    outline: none;\n    font-size: 0.875rem;\n    line-height: 1rem;\n    cursor: pointer;\n    user-select: none;\n    gap: 0.5rem;\n    color: var(--foreground-color);\n\n    & > svg {\n      flex-shrink: 0;\n      width: 14px;\n      height: 14px;\n      pointer-events: none;\n    }\n\n    &:focus {\n      background-color: var(--cta-surface-neutral-primary);\n    }\n\n    & > svg:last-child {\n      margin-left: auto;\n      opacity: 0.5;\n    }\n  }\n\n  .mcpLinkContent {\n    display: flex;\n    flex-direction: column;\n    gap: 0.125rem;\n    flex: 1;\n    align-items: flex-start;\n  }\n\n  .mcpLinkSubtext {\n    font-size: 0.75rem;\n    line-height: 1rem;\n    color: var(--secondary-text-color);\n    opacity: 0.7;\n  }\n}\n\n@keyframes slideUpAndFade {\n  from {\n    opacity: 0;\n    transform: translateY(2px);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/components/OpenPageDropdown/OpenPageDropdown.tsx",
    "content": "'use client'\n\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n} from '@radix-ui/react-dropdown-menu'\nimport { clsx as cn } from 'clsx'\nimport { GTProvider, T } from 'gt-react'\nimport { ArrowUpRightIcon, ChevronDownIcon } from 'lucide-react'\nimport loadTranslations from 'src/i18n/loadTranslations'\n\nimport gtConfig from '../../../gt.config.json'\nimport styles from './OpenPageDropdown.module.scss'\n\nfunction getPromptUrl(baseURL: string, url: string) {\n  return `${baseURL}?q=${encodeURIComponent(`Read ${url} so I can ask questions about it.`)}`\n}\n\nconst menuItems = {\n  claude: (url: string) => (\n    <a\n      href={getPromptUrl('https://claude.ai/new', url)}\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 24 24\"\n        className={styles.icon}\n      >\n        <path\n          d=\"m4.714 15.956 4.718-2.648.079-.23-.08-.128h-.23l-.79-.048-2.695-.073-2.337-.097-2.265-.122-.57-.121-.535-.704.055-.353.48-.321.685.06 1.518.104 2.277.157 1.651.098 2.447.255h.389l.054-.158-.133-.097-.103-.098-2.356-1.596-2.55-1.688-1.336-.972-.722-.491L2 6.223l-.158-1.008.655-.722.88.06.225.061.893.686 1.906 1.476 2.49 1.833.364.304.146-.104.018-.072-.164-.274-1.354-2.446-1.445-2.49-.644-1.032-.17-.619a2.972 2.972 0 0 1-.103-.729L6.287.133 6.7 0l.995.134.42.364.619 1.415L9.735 4.14l1.555 3.03.455.898.243.832.09.255h.159V9.01l.127-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.583.28.48.685-.067.444-.286 1.851-.558 2.903-.365 1.942h.213l.243-.242.983-1.306 1.652-2.064.728-.82.85-.904.547-.431h1.032l.759 1.129-.34 1.166-1.063 1.347-.88 1.142-1.263 1.7-.79 1.36.074.11.188-.02 2.853-.606 1.542-.28 1.84-.315.832.388.09.395-.327.807-1.967.486-2.307.462-3.436.813-.043.03.049.061 1.548.146.662.036h1.62l3.018.225.79.522.473.638-.08.485-1.213.62-1.64-.389-3.825-.91-1.31-.329h-.183v.11l1.093 1.068 2.003 1.81 2.508 2.33.127.578-.321.455-.34-.049-2.204-1.657-.85-.747-1.925-1.62h-.127v.17l.443.649 2.343 3.521.122 1.08-.17.353-.607.213-.668-.122-1.372-1.924-1.415-2.168-1.141-1.943-.14.08-.674 7.254-.316.37-.728.28-.607-.461-.322-.747.322-1.476.388-1.924.316-1.53.285-1.9.17-.632-.012-.042-.14.018-1.432 1.967-2.18 2.945-1.724 1.845-.413.164-.716-.37.066-.662.401-.589 2.386-3.036 1.439-1.882.929-1.086-.006-.158h-.055L4.138 18.56l-1.13.146-.485-.456.06-.746.231-.243 1.907-1.312Z\"\n          fill=\"currentColor\"\n        />\n      </svg>\n      <T>Open in Claude</T>\n      <ArrowUpRightIcon size={13} />\n    </a>\n  ),\n  chatgpt: (url: string) => (\n    <a\n      href={getPromptUrl('https://chatgpt.com', url)}\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 24 24\"\n        className={styles.icon}\n      >\n        <path\n          d=\"M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08-4.778 2.758a.795.795 0 0 0-.393.681zm1.097-2.365 2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5Z\"\n          fill=\"currentColor\"\n        />\n      </svg>\n      <T>Open in ChatGPT</T>\n      <ArrowUpRightIcon size={13} />\n    </a>\n  ),\n  perplexity: (url: string) => (\n    <a\n      href={getPromptUrl('https://www.perplexity.ai/', url)}\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      <svg\n        fill=\"currentColor\"\n        fill-rule=\"evenodd\"\n        height=\"1em\"\n        className={styles.icon}\n        viewBox=\"1.5 0 21 24\"\n        width=\"1em\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <path d=\"M19.785 0v7.272H22.5V17.62h-2.935V24l-7.037-6.194v6.145h-1.091v-6.152L4.392 24v-6.465H1.5V7.188h2.884V0l7.053 6.494V.19h1.09v6.49L19.786 0zm-7.257 9.044v7.319l5.946 5.234V14.44l-5.946-5.397zm-1.099-.08l-5.946 5.398v7.235l5.946-5.234V8.965zm8.136 7.58h1.844V8.349H13.46l6.105 5.54v2.655zm-8.982-8.28H2.59v8.195h1.8v-2.576l6.192-5.62zM5.475 2.476v4.71h5.115l-5.115-4.71zm13.219 0l-5.115 4.71h5.115v-4.71z\" />\n      </svg>\n      <T>Open in Perplexity</T>\n      <ArrowUpRightIcon size={13} />\n    </a>\n  ),\n  grok: (url: string) => (\n    <a\n      href={getPromptUrl('https://grok.com/', url)}\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      <svg\n        fill=\"currentColor\"\n        fill-rule=\"evenodd\"\n        height=\"1em\"\n        className={styles.icon}\n        viewBox=\"0 0 24 24\"\n        width=\"1em\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <title>Grok</title>\n        <path d=\"M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815\"></path>\n      </svg>\n      <T>Open in Grok</T>\n      <ArrowUpRightIcon size={13} />\n    </a>\n  ),\n  cursor: (url: string) => (\n    <a href=\"/docs/mcp/\" className={cn(styles.mcpLink)}>\n      <svg\n        fill=\"currentColor\"\n        fill-rule=\"evenodd\"\n        height=\"1em\"\n        className={styles.icon}\n        viewBox=\"0 0 24 24\"\n        width=\"1em\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <title>Cursor</title>\n        <path d=\"M22.106 5.68L12.5.135a.998.998 0 00-.998 0L1.893 5.68a.84.84 0 00-.419.726v11.186c0 .3.16.577.42.727l9.607 5.547a.999.999 0 00.998 0l9.608-5.547a.84.84 0 00.42-.727V6.407a.84.84 0 00-.42-.726zm-.603 1.176L12.228 22.92c-.063.108-.228.064-.228-.061V12.34a.59.59 0 00-.295-.51l-9.11-5.26c-.107-.062-.063-.228.062-.228h18.55c.264 0 .428.286.296.514z\"></path>\n      </svg>\n      <div className={styles.mcpLinkContent}>\n        <T>Open in Cursor</T>\n        <span className={styles.mcpLinkSubtext}>\n          Install MCP server in Cursor\n        </span>\n      </div>\n      <ArrowUpRightIcon size={13} />\n    </a>\n  ),\n  windsurf: (url: string) => (\n    <a href=\"/docs/mcp/\" className={cn(styles.mcpLink)}>\n      <svg\n        fill=\"currentColor\"\n        fill-rule=\"evenodd\"\n        height=\"1em\"\n        className={styles.icon}\n        viewBox=\"0 0 24 24\"\n        width=\"1em\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <title>Windsurf</title>\n        <path\n          clip-rule=\"evenodd\"\n          d=\"M23.78 5.004h-.228a2.187 2.187 0 00-2.18 2.196v4.912c0 .98-.804 1.775-1.76 1.775a1.818 1.818 0 01-1.472-.773L13.168 5.95a2.197 2.197 0 00-1.81-.95c-1.134 0-2.154.972-2.154 2.173v4.94c0 .98-.797 1.775-1.76 1.775-.57 0-1.136-.289-1.472-.773L.408 5.098C.282 4.918 0 5.007 0 5.228v4.284c0 .216.066.426.188.604l5.475 7.889c.324.466.8.812 1.351.938 1.377.316 2.645-.754 2.645-2.117V11.89c0-.98.787-1.775 1.76-1.775h.002c.586 0 1.135.288 1.472.773l4.972 7.163a2.15 2.15 0 001.81.95c1.158 0 2.151-.973 2.151-2.173v-4.939c0-.98.787-1.775 1.76-1.775h.194c.122 0 .22-.1.22-.222V5.225a.221.221 0 00-.22-.222z\"\n        ></path>\n      </svg>\n      <div className={styles.mcpLinkContent}>\n        <T>Open in Windsurf</T>\n        <span className={styles.mcpLinkSubtext}>\n          Install MCP server in Windsurf\n        </span>\n      </div>\n      <ArrowUpRightIcon size={13} />\n    </a>\n  ),\n  claude_mcp: (url: string) => (\n    <a href=\"/docs/mcp/\" target=\"_blank\" rel=\"noopener noreferrer\">\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 24 24\"\n        className={styles.icon}\n      >\n        <path\n          d=\"m4.714 15.956 4.718-2.648.079-.23-.08-.128h-.23l-.79-.048-2.695-.073-2.337-.097-2.265-.122-.57-.121-.535-.704.055-.353.48-.321.685.06 1.518.104 2.277.157 1.651.098 2.447.255h.389l.054-.158-.133-.097-.103-.098-2.356-1.596-2.55-1.688-1.336-.972-.722-.491L2 6.223l-.158-1.008.655-.722.88.06.225.061.893.686 1.906 1.476 2.49 1.833.364.304.146-.104.018-.072-.164-.274-1.354-2.446-1.445-2.49-.644-1.032-.17-.619a2.972 2.972 0 0 1-.103-.729L6.287.133 6.7 0l.995.134.42.364.619 1.415L9.735 4.14l1.555 3.03.455.898.243.832.09.255h.159V9.01l.127-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.583.28.48.685-.067.444-.286 1.851-.558 2.903-.365 1.942h.213l.243-.242.983-1.306 1.652-2.064.728-.82.85-.904.547-.431h1.032l.759 1.129-.34 1.166-1.063 1.347-.88 1.142-1.263 1.7-.79 1.36.074.11.188-.02 2.853-.606 1.542-.28 1.84-.315.832.388.09.395-.327.807-1.967.486-2.307.462-3.436.813-.043.03.049.061 1.548.146.662.036h1.62l3.018.225.79.522.473.638-.08.485-1.213.62-1.64-.389-3.825-.91-1.31-.329h-.183v.11l1.093 1.068 2.003 1.81 2.508 2.33.127.578-.321.455-.34-.049-2.204-1.657-.85-.747-1.925-1.62h-.127v.17l.443.649 2.343 3.521.122 1.08-.17.353-.607.213-.668-.122-1.372-1.924-1.415-2.168-1.141-1.943-.14.08-.674 7.254-.316.37-.728.28-.607-.461-.322-.747.322-1.476.388-1.924.316-1.53.285-1.9.17-.632-.012-.042-.14.018-1.432 1.967-2.18 2.945-1.724 1.845-.413.164-.716-.37.066-.662.401-.589 2.386-3.036 1.439-1.882.929-1.086-.006-.158h-.055L4.138 18.56l-1.13.146-.485-.456.06-.746.231-.243 1.907-1.312Z\"\n          fill=\"currentColor\"\n        />\n      </svg>\n      <div className={styles.mcpLinkContent}>\n        <T>Open in Claude</T>\n        <span className={styles.mcpLinkSubtext}>\n          Install MCP server in Claude\n        </span>\n      </div>\n      <ArrowUpRightIcon size={13} />\n    </a>\n  ),\n}\n\ninterface Props {\n  url: string\n  className?: string\n}\n\nfunction OpenPageDropdownContent({ url, className }: Props) {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger\n        className={cn(styles.dropdownMenuTrigger, className)}\n        aria-label=\"Open Page LLM Actions Menu\"\n      >\n        <T>Open</T>\n        <ChevronDownIcon size={14} />\n      </DropdownMenuTrigger>\n      <DropdownMenuPortal>\n        <DropdownMenuContent\n          align=\"end\"\n          className={styles.dropdownMenuContent}\n          sideOffset={4}\n        >\n          {Object.entries(menuItems).map(([key, value]) => (\n            <DropdownMenuItem\n              key={key}\n              asChild\n              className={styles.dropdownMenuItem}\n            >\n              {value(url)}\n            </DropdownMenuItem>\n          ))}\n        </DropdownMenuContent>\n      </DropdownMenuPortal>\n    </DropdownMenu>\n  )\n}\n\nexport const OpenPageDropdown = ({\n  locale,\n  ...props\n}: { locale: string } & Props) => {\n  return (\n    <GTProvider\n      config={gtConfig}\n      loadTranslations={loadTranslations}\n      locale={locale}\n      projectId={import.meta.env.PUBLIC_VITE_GT_PROJECT_ID}\n      devApiKey={import.meta.env.PUBLIC_VITE_GT_API_KEY}\n    >\n      <OpenPageDropdownContent {...props} />\n    </GTProvider>\n  )\n}\n"
  },
  {
    "path": "apps/docs/src/components/PageFrame.astro",
    "content": "---\nimport MobileMenuToggle from './MobileMenuToggle.astro'\n\nconst { hasSidebar: originalHasSidebar } = Astro.props\nconst isApiPage = Astro.url.pathname.includes('/tools/api')\nconst hasSidebar = originalHasSidebar && !isApiPage\n---\n\n<div class={`page sl-flex ${!hasSidebar ? 'no-sidebar' : ''}`}>\n  <div class=\"header-wrapper\"><slot name=\"header\" /></div>\n  <div class=\"grid-template\">\n    {\n      hasSidebar && (\n        <nav\n          class=\"sidebar\"\n          aria-label={Astro.locals.t('sidebarNav.accessibleLabel' as any)}\n        >\n          <MobileMenuToggle {...Astro.props} />\n          <div id=\"starlight__sidebar\" class=\"sidebar-pane\">\n            <div class=\"sidebar-content sl-flex\">\n              <slot name=\"sidebar\" />\n            </div>\n          </div>\n        </nav>\n      )\n    }\n    <div class=\"main-frame\"><slot /></div>\n  </div>\n</div>\n\n<script is:inline>\n  ;(() => {\n    try {\n      if (!matchMedia('(min-width: 50em)').matches) return\n      const scroller = document.getElementById('starlight__sidebar')\n\n      const state = JSON.parse(\n        sessionStorage.getItem('sl-sidebar-state') || '0'\n      )\n      if (!scroller || !state) return\n\n      scroller.scrollTop = state.scroll\n    } catch {}\n  })()\n</script>\n\n<style>\n  .grid-template {\n    position: relative;\n    display: grid;\n    grid-template-columns: 1fr 4fr;\n    column-gap: 48px;\n    @media (max-width: 1024px) {\n      grid-template-columns: 100%;\n    }\n  }\n\n  :global(.no-sidebar) .grid-template {\n    grid-template-columns: 100%;\n  }\n\n  .header-wrapper {\n    position: sticky;\n    z-index: 4;\n    inset-inline-start: 0;\n    inset-block-start: 0;\n    width: 100%;\n    background-color: var(--bg-color);\n  }\n\n  :global([data-has-sidebar]) .header {\n    padding-inline-end: var(--sl-nav-pad-x);\n    @media (max-width: 1024px) {\n      padding-inline-end: calc(\n        var(--sl-nav-gap) + var(--sl-nav-pad-x) + var(--sl-menu-button-size)\n      );\n    }\n  }\n\n  .sidebar-pane {\n    --sl-sidebar-visibility: visible;\n    visibility: var(--sl-sidebar-visibility, hidden);\n    position: sticky;\n    max-height: 100vh;\n    z-index: 3;\n    inset-block: 0;\n    width: 100%;\n    background-color: var(--bg-color);\n    overflow-y: auto;\n    overscroll-behavior: contain;\n    max-height: calc(100vh - 75px);\n    position: sticky;\n    top: 75px;\n    mask-image: linear-gradient(\n      to bottom,\n      transparent,\n      black 30px,\n      black calc(100% - 30px),\n      transparent 100%\n    );\n\n    @media (max-width: 1024px) {\n      display: none;\n      --sl-sidebar-visibility: hidden;\n      z-index: 5;\n      padding-top: 55px;\n      position: fixed;\n      right: 0;\n      width: 75vw;\n      border-left: 1px solid var(--border-extra);\n      padding-left: 20px;\n      padding-right: 20px;\n      top: 0;\n      max-height: unset;\n    }\n  }\n\n  :global([aria-expanded='true']) ~ .sidebar-pane {\n    --sl-sidebar-visibility: visible;\n    display: block;\n  }\n\n  .sidebar-content {\n    min-height: max-content;\n    flex-direction: column;\n    gap: 1rem;\n    &:after {\n      content: '';\n      padding-bottom: 1px;\n    }\n    @media (max-width: 1024px) {\n      &:after {\n        content: unset;\n      }\n    }\n  }\n\n  .main-frame {\n    @media (max-width: 1024px) {\n      padding-top: calc(48px + var(--sl-mobile-toc-height));\n    }\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/PageSidebar.astro",
    "content": "---\nimport TableOfContents from 'virtual:starlight/components/TableOfContents'\n---\n\n{\n  Astro.props.toc && (\n    <>\n      <div class=\"right-sidebar-panel\">\n        <div class=\"sl-container\">\n          <TableOfContents {...Astro.props} />\n        </div>\n      </div>\n    </>\n  )\n}\n\n<style>\n  .right-sidebar-panel :global(h2) {\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 0.75rem;\n    font-weight: normal;\n    line-height: 1;\n    text-transform: uppercase;\n    color: var(--primary-text-color);\n    letter-spacing: -0.00875rem;\n    padding-bottom: 10px;\n    border-bottom: var(--border);\n    width: 100%;\n    margin-bottom: 0.5rem;\n  }\n  .right-sidebar-panel :global(a) {\n    display: block;\n    font-size: var(--sl-text-xs);\n    text-decoration: none;\n    color: var(--sl-color-gray-3);\n    overflow-wrap: anywhere;\n    transition: color 0.1s ease-in-out;\n  }\n  .right-sidebar-panel :global(a:hover) {\n    color: var(--sl-color-white);\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/PageTitle.astro",
    "content": "---\nimport { CopyButton } from './buttons/CopyButton'\nimport { LinkButton } from './buttons/LinkButton'\nimport { OpenPageDropdown } from './OpenPageDropdown/OpenPageDropdown'\nimport { PAGE_TITLE_ID } from './TableOfContent/constants'\n\nconst { origin, pathname } = Astro.url\nconst normalizedPath = pathname.replace(/\\/$/, '')\nconst markdownUrl = `${origin}${normalizedPath || '/docs/en'}.md`\n\nconst markdownRaw = Astro.props.entry.body\n---\n\n{\n  !Astro.props.entry.data.hideTitleOnPage && (\n    <h1 id={PAGE_TITLE_ID}>{Astro.props.entry.data.title}</h1>\n  )\n}\n<div class=\"title-actions\">\n  <CopyButton client:load value={markdownRaw} variant=\"ghost\"\n    >{Astro.locals.t('header.copyForLlms' as any)}</CopyButton\n  >\n  <LinkButton\n    client:load\n    href={markdownUrl}\n    target=\"_blank\"\n    variant=\"ghost\"\n    className=\"desktop-only\"\n  >\n    <svg stroke-linejoin=\"round\" viewBox=\"0 0 22 16\" height=\"16\" width=\"16\">\n      <path\n        fill-rule=\"evenodd\"\n        clip-rule=\"evenodd\"\n        d=\"M19.5 2.25H2.5C1.80964 2.25 1.25 2.80964 1.25 3.5V12.5C1.25 13.1904 1.80964 13.75 2.5 13.75H19.5C20.1904 13.75 20.75 13.1904 20.75 12.5V3.5C20.75 2.80964 20.1904 2.25 19.5 2.25ZM2.5 1C1.11929 1 0 2.11929 0 3.5V12.5C0 13.8807 1.11929 15 2.5 15H19.5C20.8807 15 22 13.8807 22 12.5V3.5C22 2.11929 20.8807 1 19.5 1H2.5ZM3 4.5H4H4.25H4.6899L4.98715 4.82428L7 7.02011L9.01285 4.82428L9.3101 4.5H9.75H10H11V5.5V11.5H9V7.79807L7.73715 9.17572L7 9.97989L6.26285 9.17572L5 7.79807V11.5H3V5.5V4.5ZM15 8V4.5H17V8H19.5L17 10.5L16 11.5L15 10.5L12.5 8H15Z\"\n        fill=\"currentColor\"\n      >\n      </path>\n    </svg>\n    {Astro.locals.t('header.viewAsMarkdown' as any)}\n  </LinkButton>\n  <OpenPageDropdown\n    client:load\n    locale={Astro.props.locale}\n    url={markdownUrl}\n    className=\"right\"\n  />\n\n  {\n    (Astro.props.entry.data.licence || Astro.props.entry.data.distribution) && (\n      <dl class=\"tiers-distribution-list\">\n        <div>\n          <>\n            <dt>Licence:</dt>\n            <dd>{Astro.props.entry.data.licence}</dd>\n          </>\n        </div>\n        <div>\n          <>\n            <dt>Distribution:</dt>\n            <dd>{Astro.props.entry.data.distribution}</dd>\n          </>\n        </div>\n      </dl>\n    )\n  }\n\n  <style>\n    .tiers-distribution-list {\n      margin: 0;\n      border-left: 1px solid var(--hover-color);\n      padding-left: 8px;\n      display: flex;\n      flex-direction: column;\n      gap: 4px;\n      > div {\n        display: inline-flex;\n        font-family: 'Inter', sans-serif;\n        font-weight: 500;\n        font-size: 0.75rem;\n        line-height: 1.4;\n        letter-spacing: -0.02em;\n        > dt {\n          color: var(--secondary-text-color);\n        }\n        > dd {\n          color: var(--primary-text-color);\n          margin-left: 1ch;\n        }\n      }\n    }\n    h1 {\n      margin-bottom: unset !important;\n    }\n\n    .title-actions {\n      padding-bottom: 12px;\n      border-bottom: 1px solid var(--border-color);\n      font-size: 0.8125rem;\n      display: flex;\n      gap: 8px;\n      align-items: center;\n    }\n\n    .title-actions:first-child {\n      margin-top: 40px;\n    }\n\n    .right {\n      margin-left: auto;\n    }\n\n    @media (max-width: 650px) {\n      .desktop-only {\n        display: none;\n      }\n    }\n  </style>\n</div>\n"
  },
  {
    "path": "apps/docs/src/components/Pagination.astro",
    "content": "---\nimport arrowRight from '@assets/icons/arrow-right.svg?raw'\nimport arrowLeft from '@assets/icons/arrow-left.svg?raw'\nimport { getPagination } from '../utils/navigation.js'\nimport { getSidebarConfig } from '../content/config.js'\n\nconst { dir } = Astro.props\nconst isRtl = dir === 'rtl'\nconst { prev, next } = getPagination(\n  getSidebarConfig(Astro.props.lang, (key: string) => {\n    try {\n      return Astro.locals?.t?.(key as any) || key\n    } catch {\n      return key\n    }\n  }),\n  Astro.url.pathname\n)\nconst { locale } = Astro.props\n---\n\n<div class=\"pagination-links\" dir={dir}>\n  {\n    prev && (\n      <a href={prev.href} rel=\"prev\">\n        <Fragment set:html={isRtl ? arrowRight : arrowLeft} />\n        <div class=\"pagination-links__container\">\n          <span class=\"link-description\">\n            {Astro.locals.t('page.previousLink' as any)}\n          </span>\n          <span class=\"link-title\">{prev.label}</span>\n        </div>\n      </a>\n    )\n  }\n  {\n    next && (\n      <a href={next.href} rel=\"next\">\n        <Fragment set:html={isRtl ? arrowLeft : arrowRight} />\n        <div class=\"pagination-links__container\">\n          <span class=\"link-description\">\n            {Astro.locals.t('page.nextLink' as any)}\n          </span>\n          <span class=\"link-title\">{next.label}</span>\n        </div>\n      </a>\n    )\n  }\n</div>\n\n<style>\n  .pagination-links {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));\n    gap: 1rem;\n  }\n\n  a {\n    display: flex;\n    align-items: center;\n    justify-content: flex-start;\n    gap: 1rem;\n    width: 100%;\n    flex-basis: calc(50% - 0.5rem);\n    flex-grow: 1;\n    border: 1px solid var(--border-extra);\n    border-radius: 0.1875rem;\n    padding: 1rem;\n    text-decoration: none;\n    overflow-wrap: anywhere;\n  }\n  [rel='next'] {\n    justify-content: end;\n    text-align: end;\n    flex-direction: row-reverse;\n  }\n  a:hover {\n    opacity: 0.6;\n  }\n\n  .link-title {\n    font-family: 'Inter', sans-serif;\n    font-size: 1rem;\n    font-weight: 400;\n    line-height: 1.6;\n    letter-spacing: -0.01rem;\n    color: var(--primary-text-color);\n    text-transform: initial;\n  }\n\n  svg {\n    flex-shrink: 0;\n  }\n  .pagination-links__container {\n    display: flex;\n    flex-direction: column;\n  }\n  .link-description {\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 0.75rem;\n    color: var(--secondary-text-color);\n    text-transform: uppercase;\n    line-height: 1;\n    letter-spacing: -0.0075rem;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/PostHog.astro",
    "content": "<script is:inline>\n  !(function (t, e) {\n    var o, n, p, r\n    e.__SV ||\n      ((window.posthog = e),\n      (e._i = []),\n      (e.init = function (i, s, a) {\n        function g(t, e) {\n          var o = e.split('.')\n          2 == o.length && ((t = t[o[0]]), (e = o[1])),\n            (t[e] = function () {\n              t.push([e].concat(Array.prototype.slice.call(arguments, 0)))\n            })\n        }\n        ;((p = t.createElement('script')).type = 'text/javascript'),\n          (p.crossOrigin = 'anonymous'),\n          (p.async = !0),\n          (p.src =\n            s.api_host.replace('.i.posthog.com', '-assets.i.posthog.com') +\n            '/static/array.js'),\n          (r = t.getElementsByTagName('script')[0]).parentNode.insertBefore(\n            p,\n            r\n          )\n        var u = e\n        for (\n          void 0 !== a ? (u = e[a] = []) : (a = 'posthog'),\n            u.people = u.people || [],\n            u.toString = function (t) {\n              var e = 'posthog'\n              return 'posthog' !== a && (e += '.' + a), t || (e += ' (stub)'), e\n            },\n            u.people.toString = function () {\n              return u.toString(1) + '.people (stub)'\n            },\n            o =\n              'init capture register register_once register_for_session unregister unregister_for_session getFeatureFlag getFeatureFlagPayload isFeatureEnabled reloadFeatureFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSessionId getSurveys getActiveMatchingSurveys renderSurvey canRenderSurvey getNextSurveyStep identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException loadToolbar get_property getSessionProperty createPersonProfile opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing clear_opt_in_out_capturing debug getPageViewId'.split(\n                ' '\n              ),\n            n = 0;\n          n < o.length;\n          n++\n        )\n          g(u, o[n])\n        e._i.push([i, s, a])\n      }),\n      (e.__SV = 1))\n  })(document, window.posthog || [])\n  posthog.init('phc_bYtEsdMDrNLydXPD4tufkBrHKgfO2zbycM30LOowYNv', {\n    api_host: 'https://d18ag4dodbta3l.cloudfront.net',\n    person_profiles: 'always',\n    autocapture: false,\n    capture_pageview: true,\n    capture_pageleave: true,\n    cookieless_mode: 'always',\n  })\n</script>\n"
  },
  {
    "path": "apps/docs/src/components/SandboxDiagram.astro",
    "content": "---\nimport sandboxDiagramUrl from '@assets/docs/sandbox-states.svg?url'\n---\n\n<img\n  src={sandboxDiagramUrl}\n  alt=\"Sandbox lifecycle diagram\"\n  class=\"sandbox-diagram\"\n/>\n\n<style>\n  .sandbox-diagram {\n    width: 100%;\n    height: auto;\n    margin: 2rem 0;\n    display: block;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/Search.jsx",
    "content": "import { liteClient as algoliasearch } from 'algoliasearch/lite'\nimport { GTProvider, useGT } from 'gt-react'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n  Configure,\n  Highlight,\n  Hits,\n  Index,\n  InstantSearch,\n  Pagination,\n  SearchBox,\n  connectStats,\n} from 'react-instantsearch-dom'\nimport loadTranslations from 'src/i18n/loadTranslations'\n\nimport gtConfig from '../../gt.config.json'\nimport '../styles/components/search.scss'\n\nconst ALGOLIA_APP_ID = import.meta.env.PUBLIC_ALGOLIA_APP_ID || null\nconst ALGOLIA_API_KEY = import.meta.env.PUBLIC_ALGOLIA_API_KEY || null\nconst DOCS_INDEX_NAME =\n  import.meta.env.PUBLIC_ALGOLIA_DOCS_INDEX_NAME || 'docs'\nconst CLI_INDEX_NAME = import.meta.env.PUBLIC_ALGOLIA_CLI_INDEX_NAME || 'cli'\nconst SDK_INDEX_NAME = import.meta.env.PUBLIC_ALGOLIA_SDK_INDEX_NAME || 'sdk'\nconst API_INDEX_NAME = import.meta.env.PUBLIC_ALGOLIA_API_INDEX_NAME || 'api'\n\nconst searchClient =\n  ALGOLIA_APP_ID && ALGOLIA_API_KEY\n    ? algoliasearch(ALGOLIA_APP_ID, ALGOLIA_API_KEY)\n    : null\n\nfunction getSortedIndexes() {\n  const path = typeof window !== 'undefined' ? window.location.pathname : ''\n  const isApiPage = path.includes('/tools/api')\n  const isSdkPage = path.includes('/typescript-sdk') || path.includes('/python-sdk')\n  const isCliPage = path.includes('/tools/cli')\n\n  if (isApiPage) {\n    return [API_INDEX_NAME, DOCS_INDEX_NAME, CLI_INDEX_NAME, SDK_INDEX_NAME]\n  }\n  if (isSdkPage) {\n    return [SDK_INDEX_NAME, DOCS_INDEX_NAME, CLI_INDEX_NAME, API_INDEX_NAME]\n  }\n  if (isCliPage) {\n    return [CLI_INDEX_NAME, DOCS_INDEX_NAME, SDK_INDEX_NAME, API_INDEX_NAME]\n  }\n  return [DOCS_INDEX_NAME, CLI_INDEX_NAME, SDK_INDEX_NAME, API_INDEX_NAME]\n}\n\nconst INDEX_LABELS = {\n  [DOCS_INDEX_NAME]: 'Documentation',\n  [CLI_INDEX_NAME]: 'CLI',\n  [SDK_INDEX_NAME]: 'SDK',\n  [API_INDEX_NAME]: 'API',\n}\n\nfunction SearchContent() {\n  const [isSearchVisible, setIsSearchVisible] = useState(false)\n  const [searchQuery, setSearchQuery] = useState('')\n  const [debounceQuery, setDebounceQuery] = useState('')\n  const [displayHits, setDisplayHits] = useState(false)\n  const [totalHits, setTotalHits] = useState(0)\n  const [sortedIndexes, setSortedIndexes] = useState(getSortedIndexes())\n  const [selectedIndexFilter, setSelectedIndexFilter] = useState(null)\n  const [indexesWithHits, setIndexesWithHits] = useState([])\n  const debounceTimeoutRef = useRef(null)\n  const searchWrapperRef = useRef(null)\n  const t = useGT()\n\n  const currentPath =\n    typeof window !== 'undefined' ? window.location.pathname : ''\n\n  useEffect(() => {\n    if (isSearchVisible) {\n      setSortedIndexes(getSortedIndexes())\n    }\n  }, [isSearchVisible, currentPath])\n\n  useEffect(() => {\n    const toggleSearch = () => {\n      setIsSearchVisible(prev => {\n        if (prev) {\n          setSearchQuery('')\n          setDebounceQuery('')\n          setDisplayHits(false)\n          setTotalHits(0)\n          setSelectedIndexFilter(null)\n          setIndexesWithHits([])\n        }\n        return !prev\n      })\n    }\n\n    const handleKeyDown = event => {\n      if ((event.metaKey || event.ctrlKey) && event.key === 'k') {\n        event.preventDefault()\n        toggleSearch()\n      } else if (event.key === 'Escape') {\n        setIsSearchVisible(false)\n        setSearchQuery('')\n        setDebounceQuery('')\n        setDisplayHits(false)\n        setTotalHits(0)\n        setSelectedIndexFilter(null)\n        setIndexesWithHits([])\n      }\n    }\n\n    const handleSearchClick = event => {\n      if (event.target.closest('.search-click')) {\n        event.preventDefault()\n        event.stopPropagation()\n        toggleSearch()\n      }\n    }\n\n    const handleClickOutside = event => {\n      if (\n        searchWrapperRef.current &&\n        !searchWrapperRef.current.contains(event.target) &&\n        !event.target.closest('.search-click')\n      ) {\n        setIsSearchVisible(false)\n        setSearchQuery('')\n        setDebounceQuery('')\n        setDisplayHits(false)\n        setTotalHits(0)\n        setSelectedIndexFilter(null)\n        setIndexesWithHits([])\n      }\n    }\n\n    document.addEventListener('keydown', handleKeyDown)\n    document.addEventListener('click', handleSearchClick)\n    document.addEventListener('mousedown', handleClickOutside)\n\n    return () => {\n      document.removeEventListener('keydown', handleKeyDown)\n      document.removeEventListener('click', handleSearchClick)\n      document.removeEventListener('mousedown', handleClickOutside)\n    }\n  }, [])\n\n  useEffect(() => {\n    if (isSearchVisible && debounceQuery && displayHits) {\n      document.body.classList.add('no-scroll')\n    } else {\n      document.body.classList.remove('no-scroll')\n    }\n  }, [isSearchVisible, debounceQuery, displayHits])\n\n  useEffect(() => {\n    if (debounceTimeoutRef.current) {\n      clearTimeout(debounceTimeoutRef.current)\n    }\n\n    debounceTimeoutRef.current = setTimeout(() => {\n      setTotalHits(0)\n      setDebounceQuery(searchQuery)\n      setSelectedIndexFilter(null)\n    }, 400)\n\n    return () => {\n      if (debounceTimeoutRef.current) {\n        clearTimeout(debounceTimeoutRef.current)\n      }\n    }\n  }, [searchQuery])\n\n  const handleIndexHitsChange = useCallback((indexName, nbHits) => {\n    setIndexesWithHits(prev =>\n      nbHits > 0\n        ? prev.includes(indexName)\n          ? prev\n          : [...prev, indexName]\n        : prev.filter(i => i !== indexName)\n    )\n  }, [])\n\n  return (\n    isSearchVisible && (\n      <div\n        id=\"searchbox-wrapper\"\n        className=\"searchbox-wrapper\"\n        ref={searchWrapperRef}\n      >\n        <InstantSearch indexName={DOCS_INDEX_NAME} searchClient={searchClient}>\n          <div className=\"search-bar-container\">\n            <SearchBox\n              translations={{\n                placeholder: t('Search documentation', {\n                  $context: 'As in a search bar on a website',\n                }),\n              }}\n              autoFocus\n              onChange={event => setSearchQuery(event.currentTarget.value)}\n              value={searchQuery}\n            />\n          </div>\n          <div className=\"search-content\">\n            {debounceQuery && (\n              <>\n                <div className=\"search-index-filters\">\n                  <button\n                    type=\"button\"\n                    className={`search-index-filter-chip ${selectedIndexFilter === null ? 'active' : ''}`}\n                    onClick={() => setSelectedIndexFilter(null)}\n                  >\n                    All\n                  </button>\n                  {sortedIndexes\n                    .filter(indexName => indexesWithHits.includes(indexName))\n                    .map(indexName => (\n                      <button\n                        key={indexName}\n                        type=\"button\"\n                        className={`search-index-filter-chip ${selectedIndexFilter === indexName ? 'active' : ''}`}\n                        onClick={() => setSelectedIndexFilter(indexName)}\n                      >\n                        {INDEX_LABELS[indexName] ?? indexName}\n                      </button>\n                    ))}\n                </div>\n                {sortedIndexes.map(indexName => (\n                  <div\n                    key={`${indexName}-${debounceQuery}`}\n                    className=\"search-index-panel\"\n                    hidden={selectedIndexFilter !== null && selectedIndexFilter !== indexName}\n                  >\n                    <SearchIndex\n                      indexName={indexName}\n                      setDisplayHits={setDisplayHits}\n                      setIsSearchVisible={setIsSearchVisible}\n                      setTotalHits={setTotalHits}\n                      onIndexHitsChange={handleIndexHitsChange}\n                      debounceQuery={debounceQuery}\n                    />\n                  </div>\n                ))}\n                {(totalHits === 0 ||\n                  (selectedIndexFilter !== null && !indexesWithHits.includes(selectedIndexFilter))) && (\n                  <div style={{\n                    textAlign: 'center',\n                    padding: '20px',\n                    color: 'var(--primary-text-color)',\n                    fontSize: '16px'\n                  }}>\n                    No results found for \"<strong>{debounceQuery}</strong>\"\n                  </div>\n                )}\n              </>\n            )}\n            <Configure hitsPerPage={10} clickAnalytics getRankingInfo={false} />\n          </div>\n        </InstantSearch>\n      </div>\n    )\n  )\n}\n\nfunction SearchIndex({ indexName, setDisplayHits, setIsSearchVisible, setTotalHits, onIndexHitsChange, debounceQuery }) {\n  return (\n    <Index indexName={indexName}>\n      <ConditionalSearchIndex\n        indexName={indexName}\n        setDisplayHits={setDisplayHits}\n        setIsSearchVisible={setIsSearchVisible}\n        setTotalHits={setTotalHits}\n        onIndexHitsChange={onIndexHitsChange}\n        debounceQuery={debounceQuery}\n      />\n    </Index>\n  )\n}\n\nconst ConditionalSearchIndexComponent = ({ indexName, setDisplayHits, setIsSearchVisible, nbHits, setTotalHits, onIndexHitsChange, debounceQuery }) => {\n  useEffect(() => {\n    setDisplayHits(nbHits > 0)\n    setTotalHits(prev => prev + nbHits)\n  }, [nbHits, setDisplayHits, setTotalHits, debounceQuery])\n\n  useEffect(() => {\n    if (onIndexHitsChange && typeof nbHits === 'number') {\n      onIndexHitsChange(indexName, nbHits)\n    }\n  }, [indexName, nbHits, onIndexHitsChange])\n\n  if (nbHits === 0) {\n    return null\n  }\n\n  return (\n    <>\n      <div data-index={indexName}>\n        <div\n          className=\"stats-pagination-wrapper\"\n          style={indexName === 'blogs_test' ? { marginTop: '24px' } : {}}\n        >\n          <Stats setDisplayHits={setDisplayHits} indexName={indexName} />\n          <Pagination\n            showFirst={false}\n            showPrevious\n            showNext\n            showLast={false}\n            padding={1}\n          />\n        </div>\n        <Hits\n          hitComponent={props => (\n            <Hit\n              {...props}\n              setIsSearchVisible={setIsSearchVisible}\n              indexName={indexName}\n            />\n          )}\n        />\n      </div>\n      <hr style={{ marginBottom: '40px' }} />\n    </>\n  )\n}\n\nconst ConditionalSearchIndex = connectStats(ConditionalSearchIndexComponent)\n\nfunction Hit({ hit, setIsSearchVisible, indexName }) {\n  const handleClick = e => {\n    e.preventDefault()\n    let hitUrl = hit.url\n\n    if (indexName === 'blogs_test') {\n      hitUrl = `https://www.daytona.io/dotfiles/${hit.slug}`\n    } else if (indexName === 'website') {\n      hitUrl = `https://www.daytona.io/${hit.slug}`\n    }\n\n    const currentUrl = window.location.href\n\n    if (currentUrl.includes(hitUrl)) {\n      const element = document.querySelector(`[data-slug='${hit.slug}']`)\n      if (element) {\n        element.scrollIntoView({ behavior: 'smooth' })\n      }\n    } else {\n      window.location.href = hitUrl\n    }\n    setIsSearchVisible(false)\n  }\n\n  return (\n    <div\n      tabIndex=\"0\"\n      onKeyDown={e => {\n        if (e.key === 'Enter') {\n          handleClick(e)\n        }\n      }}\n    >\n      <a href={hit.url} tabIndex=\"-1\" onClick={handleClick}>\n        {([DOCS_INDEX_NAME, CLI_INDEX_NAME, SDK_INDEX_NAME, API_INDEX_NAME].includes(indexName) || indexName === 'website') && (\n          <>\n            <h5\n              style={{\n                fontSize: '20px',\n                display: 'flex',\n                alignItems: 'center',\n              }}\n            >\n              <span style={{ fontSize: '10px', marginRight: '8px' }}>🟦</span>\n              <span style={{ marginLeft: '4px' }}>\n                <Highlight attribute=\"title\" hit={hit} />\n              </span>\n            </h5>\n            <h6\n              style={{\n                fontSize: '12px',\n                color: '#686868',\n                fontWeight: 500,\n                paddingLeft: '24px',\n              }}\n            >\n              {hit.slug}\n            </h6>\n          </>\n        )}\n        {indexName === 'blogs_test' && hit.featuredImage?.url && (\n          <img\n            src={hit.featuredImage.url}\n            alt={hit.featuredImage.alt || 'Blog image'}\n            style={{\n              width: '100%',\n              maxWidth: '500px',\n              marginBottom: '12px',\n              border: '1px solid var(--border-color)',\n            }}\n          />\n        )}\n        {indexName === 'blogs_test' && (\n          <h5\n            style={{ fontSize: '20px', display: 'flex', alignItems: 'center' }}\n          >\n            <span style={{ fontSize: '10px', marginRight: '8px' }}>🟦</span>\n            <span style={{ marginLeft: '4px' }}>\n              <Highlight attribute=\"title\" hit={hit} />\n            </span>\n          </h5>\n        )}\n        {indexName === 'blogs_test' &&\n          hit.author?.name &&\n          hit.publishedDate && (\n            <p\n              style={{\n                fontSize: '14px',\n                paddingLeft: '24px',\n                paddingBottom: '8px',\n              }}\n            >\n              {hit.publishedDate} :: {hit.author.name}\n            </p>\n          )}\n        <p\n          style={{\n            fontSize: '14px',\n            paddingBottom: '16px',\n            paddingLeft: '24px',\n          }}\n        >\n          <Highlight attribute=\"description\" hit={hit} />\n        </p>\n      </a>\n    </div>\n  )\n}\n\nconst CustomStats = ({ nbHits, indexName, setDisplayHits }) => {\n  useEffect(() => {\n    setDisplayHits(nbHits > 0)\n  }, [nbHits, setDisplayHits])\n\n  const getIndexLabel = () => {\n    switch (indexName) {\n      case DOCS_INDEX_NAME:\n        return 'Documentation'\n      case 'blogs_test':\n        return 'Blog'\n      case 'website':\n        return 'Website'\n      case CLI_INDEX_NAME:\n        return 'CLI'\n      case SDK_INDEX_NAME:\n        return 'SDK'\n      case API_INDEX_NAME:\n        return 'API'\n      default:\n        return 'Results'\n    }\n  }\n\n  return (\n    <div className=\"custom-stats\">\n      <span style={{ color: 'var(--primary-text-color)' }}>\n        {getIndexLabel()}{' '}\n      </span>\n      ({nbHits} results)\n    </div>\n  )\n}\n\nconst Stats = connectStats(CustomStats)\n\nconst Search = ({ locale }) => {\n  return (\n    <GTProvider\n      config={gtConfig}\n      loadTranslations={loadTranslations}\n      locale={locale}\n      projectId={import.meta.env.PUBLIC_VITE_GT_PROJECT_ID}\n      devApiKey={import.meta.env.PUBLIC_VITE_GT_API_KEY}\n    >\n      <SearchContent />\n    </GTProvider>\n  )\n}\n\nexport default Search\n"
  },
  {
    "path": "apps/docs/src/components/Sidebar.astro",
    "content": "---\nimport { getSidebarConfig } from '../content/config'\nimport { getSidebar, getHeaderActiveState } from '../utils/navigation'\nimport SidebarSublist from './SidebarSublist.astro'\nimport { SideNavLinks } from './menu/SideNavLinks'\nimport packageIcon from '@assets/sidebar/package.svg?raw'\nimport serverIcon from '@assets/sidebar/server.svg?raw'\nimport terminalIcon from '@assets/sidebar/terminal.svg?raw'\n\nconst PUBLIC_WEB_URL = (\n  import.meta.env.PUBLIC_WEB_URL || 'https://daytona.io'\n).replace(/\\/$/, '')\n\nconst {\n  isTypescriptSdkActive,\n  isPythonSdkActive,\n  isRubySdkActive,\n  isApiActive,\n  isCliActive,\n  isReferencesActive,\n  isGuidesActive,\n} = getHeaderActiveState(import.meta.env.BASE_URL, Astro.url.pathname)\n---\n\n<SidebarSublist\n  sublist={getSidebar(\n    getSidebarConfig(Astro.props.lang, (key: string) => {\n      try {\n        return Astro.locals?.t?.(key as any) || key\n      } catch {\n        return key\n      }\n    }),\n    Astro.url.pathname\n  )}\n/>\n<div class=\"navbar-links\">\n  <details class=\"mobile-dropdown\" open={isReferencesActive}>\n    <summary class:list={[{ active: isReferencesActive }]}>\n      {Astro.locals.t('header.references' as any)}\n      <svg\n        class=\"chevron\"\n        width=\"10\"\n        height=\"6\"\n        viewBox=\"0 0 10 6\"\n        fill=\"none\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n      >\n        <path\n          d=\"M1 1L5 5L9 1\"\n          stroke=\"currentColor\"\n          stroke-width=\"1.5\"\n          stroke-linecap=\"round\"\n          stroke-linejoin=\"round\"></path>\n      </svg>\n    </summary>\n    <div class=\"mobile-dropdown-menu\">\n      <a\n        href={`${import.meta.env.BASE_URL}/en/typescript-sdk`}\n        class:list={[{ active: isTypescriptSdkActive }]}\n      >\n        <Fragment set:html={packageIcon} />\n        {Astro.locals.t('sidebarconfig.tsSdkReference' as any)}\n      </a>\n      <a\n        href={`${import.meta.env.BASE_URL}/en/python-sdk`}\n        class:list={[{ active: isPythonSdkActive }]}\n      >\n        <Fragment set:html={packageIcon} />\n        {Astro.locals.t('sidebarconfig.pythonSdkReference' as any)}\n      </a>\n      <a\n        href={`${import.meta.env.BASE_URL}/en/ruby-sdk`}\n        class:list={[{ active: isRubySdkActive }]}\n      >\n        <Fragment set:html={packageIcon} />\n        {Astro.locals.t('sidebarconfig.rubySdkReference' as any)}\n      </a>\n      <a\n        href={`${import.meta.env.BASE_URL}/en/tools/api`}\n        class:list={[{ active: isApiActive }]}\n      >\n        <Fragment set:html={serverIcon} />\n        {Astro.locals.t('sidebarconfig.apiReference' as any)}\n      </a>\n      <a\n        href={`${import.meta.env.BASE_URL}/en/tools/cli`}\n        class:list={[{ active: isCliActive }]}\n      >\n        <Fragment set:html={terminalIcon} />\n        {Astro.locals.t('sidebarconfig.cliReference' as any)}\n      </a>\n    </div>\n  </details>\n  <a href={`/docs/en/guides`} class:list={[{ active: isGuidesActive }]}\n    >{Astro.locals.t('header.guides' as any)}</a\n  >\n</div>\n<div class=\"mobile-nav-btn nav__items_side_menu\">\n  <SideNavLinks client:load locale={Astro.props.lang} />\n</div>\n\n<style>\n  .navbar-links {\n    display: none;\n    align-items: flex-start;\n    flex-direction: column;\n    gap: 16px;\n    border-top: 1px solid var(--border-color);\n    padding-top: 20px;\n\n    @media (max-width: 1024px) {\n      display: flex;\n    }\n  }\n\n  .navbar-links > a,\n  .mobile-dropdown summary {\n    text-transform: uppercase;\n    font-size: 14px;\n    font-family: 'Berkeley Mono', monospace;\n    color: var(--primary-text-color);\n    transition: all 0.2s;\n    font-weight: 400;\n    letter-spacing: -0.01rem;\n    cursor: pointer;\n    &:hover {\n      color: var(--hover-color);\n    }\n    &.active {\n      color: var(--hover-color);\n    }\n  }\n\n  .mobile-dropdown {\n    width: 100%;\n  }\n\n  .mobile-dropdown summary {\n    display: flex;\n    align-items: center;\n    gap: 6px;\n    list-style: none;\n  }\n\n  .mobile-dropdown summary::-webkit-details-marker {\n    display: none;\n  }\n\n  .mobile-dropdown .chevron {\n    width: 10px;\n    height: 6px;\n    transition: transform 0.2s;\n  }\n\n  .mobile-dropdown[open] .chevron {\n    transform: rotate(180deg);\n  }\n\n  .mobile-dropdown-menu {\n    display: flex;\n    flex-direction: column;\n    gap: 8px;\n    padding: 12px 0 4px 0;\n  }\n\n  .mobile-dropdown-menu a {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    font-size: 14px;\n    font-family: 'Berkeley Mono', monospace;\n    color: var(--secondary-text-color);\n    text-transform: none;\n    transition: all 0.15s;\n    &:hover {\n      color: var(--hover-color);\n    }\n    &.active {\n      color: var(--hover-color);\n    }\n  }\n\n  .mobile-dropdown-menu a :global(svg) {\n    width: 16px;\n    height: 16px;\n    flex-shrink: 0;\n  }\n\n  .mobile-dropdown-menu a :global(svg path) {\n    fill: currentColor;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/SidebarSublist.astro",
    "content": "---\nimport { isActiveOrParentPath } from '../utils/navigation'\nimport { NavigationCategory } from '../content/config'\nimport arrowUpRightIcon from '@assets/sidebar/arrow-up-right.svg?raw'\n\n// Add TypeScript interface declaration for Window\ndeclare global {\n  interface Window {\n    sidebarStates: { [key: string]: boolean }\n  }\n}\n\nfunction getSVG(name: string) {\n  const filepath = `/src/assets/sidebar/${name}`\n  const files = import.meta.glob<string>('/src/assets/sidebar/*.svg', {\n    query: '?raw',\n    import: 'default',\n  })\n\n  if (!(filepath in files)) {\n    throw new Error(`${filepath} not found`)\n  }\n\n  return files[filepath]()\n}\n\ninterface Props {\n  sublist: any[]\n  nested?: boolean\n  collapse?: boolean\n}\n\nconst { sublist = [], nested, collapse = false } = Astro.props\n---\n\n<!-- Pre-render script to set initial states -->\n<script is:inline define:vars={{ sublist }}>\n  // Create a global object to store initial states\n  window.sidebarStates = window.sidebarStates || {}\n  try {\n    // Get all sidebar states from localStorage\n    Object.keys(localStorage).forEach(key => {\n      if (key.startsWith('sidebar-')) {\n        const groupId = key.replace('sidebar-', '')\n        window.sidebarStates[groupId] = localStorage.getItem(key) === 'true'\n      }\n    })\n  } catch (e) {\n    console.error('Failed to access localStorage:', e)\n  }\n</script>\n\n<ul class:list={{ 'top-level': !nested }}>\n  {\n    sublist.map(entry => (\n      <li>\n        {entry.type === 'link' ? (\n          <a\n            href={entry.href}\n            aria-current={entry.isCurrent ? 'page' : undefined}\n            target={entry.external ? '_blank' : undefined}\n            class:list={[\n              entry.attrs?.class,\n              { context: entry.context },\n              { active: isActiveOrParentPath(entry.href, Astro.url.pathname) },\n            ]}\n          >\n            {entry.attrs?.icon && (\n              <Fragment set:html={getSVG(entry.attrs.icon)} />\n            )}\n            <span>{entry.label}</span>\n            {entry.external && (\n              <span class=\"external-icon\">\n                <Fragment set:html={arrowUpRightIcon} />\n              </span>\n            )}\n          </a>\n        ) : entry.type === 'group' ? (\n          entry.collapse || (collapse && entry.label?.includes('SDK')) ? (\n            <details\n              class=\"sidebar-group is-collapsible\"\n              data-group-id={entry.label}\n              set:html={`<script>\n                if (window.sidebarStates && window.sidebarStates['${entry.label}']) {\n                  document.currentScript.parentElement.setAttribute('open', '');\n                }\n              </script>`}\n            >\n              <summary class=\"group-label\">\n                <span class=\"large\">{entry.label}</span>\n                <svg\n                  class=\"caret\"\n                  width=\"16\"\n                  height=\"16\"\n                  viewBox=\"0 0 24 24\"\n                  fill=\"none\"\n                  xmlns=\"http://www.w3.org/2000/svg\"\n                >\n                  <path\n                    d=\"M9 18L15 12L9 6\"\n                    stroke=\"currentColor\"\n                    stroke-width=\"2\"\n                    stroke-linecap=\"round\"\n                    stroke-linejoin=\"round\"\n                  />\n                </svg>\n              </summary>\n              <div class=\"group-content\">\n                <Astro.self\n                  sublist={entry.entries}\n                  nested\n                  collapse={collapse}\n                />\n              </div>\n            </details>\n          ) : (\n            <div\n              class:list={[\n                { main: entry.category === NavigationCategory.MAIN },\n              ]}\n            >\n              <div class=\"group-label\">\n                <span class=\"large\">{entry.label}</span>\n              </div>\n              <Astro.self sublist={entry.entries} nested collapse={collapse} />\n            </div>\n          )\n        ) : null}\n      </li>\n    ))\n  }\n</ul>\n\n<script>\n  // Handle state persistence for collapsible sections\n  const initializeDetails = () => {\n    document\n      .querySelectorAll<HTMLDetailsElement>('details.is-collapsible')\n      .forEach(details => {\n        const groupId = details.getAttribute('data-group-id')\n        if (!groupId) return\n\n        // Store state changes\n        details.addEventListener('toggle', () => {\n          localStorage.setItem(`sidebar-${groupId}`, details.open.toString())\n          window.sidebarStates[groupId] = details.open\n        })\n      })\n  }\n\n  // Run on page transitions\n  document.addEventListener('astro:page-load', initializeDetails)\n  // Run on initial load\n  initializeDetails()\n</script>\n\n<style>\n  ul {\n    --sl-sidebar-item-padding-inline: 0.5rem;\n    list-style: none;\n    padding: 0;\n  }\n\n  li {\n    overflow-wrap: anywhere;\n  }\n\n  .large {\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 0.8125rem;\n    font-weight: 500;\n    line-height: 1;\n    letter-spacing: -0.12px;\n    text-transform: uppercase;\n    color: var(--primary-text-color);\n  }\n\n  .sidebar-group {\n    margin: 8px 0;\n  }\n\n  .sidebar-group.is-collapsible {\n    border-radius: 4px;\n    transition: background-color 0.2s ease;\n  }\n\n  .group-label {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 24px 0 8px 0;\n  }\n\n  /* Collapsible specific styles */\n  .is-collapsible .group-label {\n    cursor: pointer;\n  }\n\n  .is-collapsible .group-content {\n    padding: 0 8px 8px 8px;\n  }\n\n  .caret {\n    transition: transform 0.2s ease;\n  }\n\n  details[open] .caret {\n    transform: rotate(90deg);\n  }\n\n  summary {\n    list-style: none;\n  }\n  summary::-webkit-details-marker {\n    display: none;\n  }\n\n  li > a {\n    display: flex;\n    align-items: center;\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 0.875rem;\n    font-style: normal;\n    font-weight: 400;\n    letter-spacing: -0.04rem;\n    text-decoration: none;\n    color: var(--secondary-text-color);\n    padding: 4px 0 4px 0px;\n    transition: 0.2s;\n\n    > svg {\n      margin-right: 8px;\n      width: 16px;\n      height: 16px;\n      opacity: 0.5;\n\n      path {\n        transition: 0.2s;\n        fill: currentColor;\n      }\n    }\n  }\n\n  .main {\n    padding-bottom: 20px;\n    border-bottom: var(--border);\n  }\n\n  .main a {\n    color: var(--primary-text-color);\n  }\n\n  .main a.context {\n    color: var(--hover-color);\n\n    > svg {\n      opacity: 1;\n    }\n  }\n\n  a:focus,\n  a:hover:not(.active) {\n    color: var(--primary-text-color);\n  }\n\n  a.active {\n    color: var(--hover-color);\n    > svg {\n      opacity: 1;\n    }\n  }\n\n  [aria-current='page'],\n  [aria-current='page']:hover,\n  [aria-current='page']:focus {\n    color: var(--hover-color);\n  }\n\n  a > *:not(:last-child),\n  .group-label > *:not(:last-child) {\n    margin-inline-end: 0.25em;\n  }\n\n  .external-icon {\n    display: flex;\n    height: 8px;\n    width: 8px;\n    margin: 0 8px;\n    opacity: 0.5;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/TableOfContent/constants.ts",
    "content": "export const PAGE_TITLE_ID = '_top'\n"
  },
  {
    "path": "apps/docs/src/components/TableOfContent/starlight-toc.ts",
    "content": "import { PAGE_TITLE_ID } from './constants.ts'\n\nexport class StarlightTOC extends HTMLElement {\n  private _current = this.querySelector(\n    'a[aria-current=\"true\"]'\n  ) as HTMLAnchorElement | null\n  private minH = parseInt(this.dataset.minH || '2', 10)\n  private maxH = parseInt(this.dataset.maxH || '3', 10)\n\n  protected set current(link: HTMLAnchorElement) {\n    if (link === this._current) return\n    if (this._current) this._current.removeAttribute('aria-current')\n    link.setAttribute('aria-current', 'true')\n    this._current = link\n  }\n\n  constructor() {\n    super()\n\n    /** All the links in the table of contents. */\n    const links = [...this.querySelectorAll('a')]\n\n    /** Test if an element is a table-of-contents heading. */\n    const isHeading = (el: Element): el is HTMLHeadingElement => {\n      if (el instanceof HTMLHeadingElement) {\n        // Special case for page title h1\n        if (el.id === PAGE_TITLE_ID) return true\n        // Check the heading level is within the user-configured limits for the ToC\n        const level = el.tagName[1]\n        if (level) {\n          const int = parseInt(level, 10)\n          if (int >= this.minH && int <= this.maxH) return true\n        }\n      }\n      return false\n    }\n\n    /** Walk up the DOM to find the nearest heading. */\n    const getElementHeading = (\n      el: Element | null\n    ): HTMLHeadingElement | null => {\n      if (!el) return null\n      const origin = el\n      while (el) {\n        if (isHeading(el)) return el\n        // Assign the previous sibling’s last, most deeply nested child to el.\n        el = el.previousElementSibling\n        while (el?.lastElementChild) {\n          el = el.lastElementChild\n        }\n        // Look for headings amongst siblings.\n        const h = getElementHeading(el)\n        if (h) return h\n      }\n      // Walk back up the parent.\n      return getElementHeading(origin.parentElement)\n    }\n\n    /** Handle intersections and set the current link to the heading for the current intersection. */\n    const setCurrent: IntersectionObserverCallback = entries => {\n      for (const { isIntersecting, target } of entries) {\n        if (!isIntersecting) continue\n        const heading = getElementHeading(target)\n        if (!heading) continue\n        const link = links.find(\n          link => link.hash === '#' + encodeURIComponent(heading.id)\n        )\n        if (link) {\n          this.current = link\n          break\n        }\n      }\n    }\n\n    // Observe elements with an `id` (most likely headings) and their siblings.\n    // Also observe direct children of `.content` to include elements before\n    // the first heading.\n    const toObserve = document.querySelectorAll(\n      'main [id], main [id] ~ *, main .content > *'\n    )\n\n    let observer: IntersectionObserver | undefined\n    const observe = () => {\n      if (observer) observer.disconnect()\n      observer = new IntersectionObserver(setCurrent, {\n        rootMargin: this.getRootMargin(),\n      })\n      toObserve.forEach(h => observer!.observe(h))\n    }\n    observe()\n\n    const onIdle = window.requestIdleCallback || (cb => setTimeout(cb, 1))\n    let timeout: NodeJS.Timeout\n    window.addEventListener('resize', () => {\n      // Disable intersection observer while window is resizing.\n      if (observer) observer.disconnect()\n      clearTimeout(timeout)\n      timeout = setTimeout(() => onIdle(observe), 200)\n    })\n  }\n\n  private getRootMargin(): `-${number}px 0% ${number}px` {\n    const navBarHeight =\n      document.querySelector('header')?.getBoundingClientRect().height || 0\n    // `<summary>` only exists in mobile ToC, so will fall back to 0 in large viewport component.\n    const mobileTocHeight =\n      this.querySelector('summary')?.getBoundingClientRect().height || 0\n    /** Start intersections at nav height + 2rem padding. */\n    const top = navBarHeight + mobileTocHeight + 32\n    /** End intersections 1.5rem later. */\n    const bottom = top + 24\n    const height = document.documentElement.clientHeight\n    return `-${top}px 0% ${bottom - height}px`\n  }\n}\n\ncustomElements.define('starlight-toc', StarlightTOC)\n"
  },
  {
    "path": "apps/docs/src/components/TableOfContents.astro",
    "content": "---\nimport TableOfContentsList from './TableOfContentsList.astro'\n\nconst { toc } = Astro.props\n---\n\n{\n  toc && (\n    <starlight-toc\n      data-min-h={toc.minHeadingLevel}\n      data-max-h={toc.maxHeadingLevel}\n    >\n      <nav aria-labelledby=\"starlight__on-this-page\">\n        <h2 id=\"starlight__on-this-page\" class=\"table-of-contents-title\">\n          # {Astro.locals.t('tableOfContents.title' as any)}\n        </h2>\n        <TableOfContentsList toc={toc.items} />\n      </nav>\n    </starlight-toc>\n  )\n}\n\n<script src=\"./TableOfContent/starlight-toc\"></script>\n"
  },
  {
    "path": "apps/docs/src/components/TableOfContentsList.astro",
    "content": "---\nimport type { TocItem } from '@astrojs/starlight/utils/generateToC'\n\ninterface Props {\n  toc: TocItem[]\n  depth?: number\n  isMobile?: boolean\n}\n\nconst { toc, isMobile = false, depth = 0 } = Astro.props\n---\n\n<ul class:list={{ isMobile }}>\n  {\n    toc.map(heading => (\n      <li>\n        <a href={'#' + heading.slug} style={`padding-left: ${depth * 8}px;`}>\n          <span>{heading.text}</span>\n        </a>\n        {heading.children.length > 0 && (\n          <Astro.self\n            toc={heading.children}\n            depth={depth + 1}\n            isMobile={isMobile}\n          />\n        )}\n      </li>\n    ))\n  }\n</ul>\n\n<style define:vars={{ depth }}>\n  ul {\n    padding: 0;\n    list-style: none;\n    row-gap: 4px;\n  }\n  a {\n    color: var(--secondary-text-color);\n    font-family: 'Inter', sans-serif;\n    font-size: 0.8125rem;\n    font-weight: 500;\n    letter-spacing: -0.015rem;\n    margin-bottom: 8px;\n    transition: color 0.1s ease-in-out;\n    &:hover {\n      text-decoration: underline;\n      color: var(--primary-text-color) !important;\n      text-decoration-color: var(--hover-color) !important;\n      text-underline-offset: 3.2px;\n    }\n  }\n  a[aria-current='true'] {\n    color: var(--primary-text-color) !important;\n    :before {\n      content: '_';\n    }\n  }\n  .isMobile a {\n    --pad-inline: 1rem;\n    display: flex;\n    justify-content: space-between;\n    gap: var(--pad-inline);\n    border-top: var(--border);\n    border-radius: 0;\n    padding-block: 0.5rem;\n    text-decoration: none;\n    outline-offset: var(--sl-outline-offset-inside);\n  }\n  .isMobile:first-child > li:first-child > a {\n    border-top: 0;\n  }\n  .isMobile a[aria-current='true'],\n  .isMobile a[aria-current='true']:hover,\n  .isMobile a[aria-current='true']:focus {\n    color: var(--primary-text-color);\n    background-color: unset;\n  }\n  .isMobile a[aria-current='true']::after {\n    content: '';\n    width: 1rem;\n    /* Check mark SVG icon */\n    -webkit-mask-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxNCAxNCc+PHBhdGggZD0nTTEwLjkxNCA0LjIwNmEuNTgzLjU4MyAwIDAgMC0uODI4IDBMNS43NCA4LjU1NyAzLjkxNCA2LjcyNmEuNTk2LjU5NiAwIDAgMC0uODI4Ljg1N2wyLjI0IDIuMjRhLjU4My41ODMgMCAwIDAgLjgyOCAwbDQuNzYtNC43NmEuNTgzLjU4MyAwIDAgMCAwLS44NTdaJy8+PC9zdmc+Cg==');\n    mask-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxNCAxNCc+PHBhdGggZD0nTTEwLjkxNCA0LjIwNmEuNTgzLjU4MyAwIDAgMC0uODI4IDBMNS43NCA4LjU1NyAzLjkxNCA2LjcyNmEuNTk2LjU5NiAwIDAgMC0uODI4Ljg1N2wyLjI0IDIuMjRhLjU4My41ODMgMCAwIDAgLjgyOCAwbDQuNzYtNC43NmEuNTgzLjU4MyAwIDAgMCAwLS44NTdaJy8+PC9zdmc+Cg==');\n    -webkit-mask-repeat: no-repeat;\n    mask-repeat: no-repeat;\n    flex-shrink: 0;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/ThemeProvider.astro",
    "content": "<script is:inline>\n  window.ThemeProvider = (() => {\n    const storedTheme =\n      typeof localStorage !== 'undefined' && localStorage.getItem('theme')\n    const theme =\n      storedTheme ||\n      (window.matchMedia('(prefers-color-scheme: light)').matches\n        ? 'light'\n        : 'dark')\n    document.documentElement.dataset.theme =\n      theme === 'light' ? 'light' : 'dark'\n    return {\n      updatePickers(theme = storedTheme || 'auto') {\n        document.querySelectorAll('theme-select').forEach(picker => {\n          const buttons = picker.querySelectorAll('button')\n          buttons.forEach(button => {\n            if (button.id === theme) {\n              button.classList.add('theme-select-button-active')\n            } else {\n              button.classList.remove('theme-select-button-active')\n            }\n          })\n        })\n      },\n    }\n  })()\n</script>\n"
  },
  {
    "path": "apps/docs/src/components/ThemeSelect.astro",
    "content": "---\nimport { Image } from 'astro:assets'\nimport darkThemeIcon from '@assets/icons/dark-moon.svg?raw'\nimport defaultThemeIcon from '@assets/icons/default-mood.svg?raw'\nimport lightThemeIcon from '@assets/icons/light-sun.svg?raw'\n---\n\n<theme-select class=\"theme-select-container\">\n  <button type=\"button\" id=\"dark\" aria-label=\"dark theme\">\n    <Fragment set:html={darkThemeIcon} />\n  </button>\n  <button type=\"button\" id=\"light\" aria-label=\"light theme\">\n    <Fragment set:html={lightThemeIcon} />\n  </button>\n  <button type=\"button\" id=\"auto\" aria-label=\"default theme\">\n    <Fragment set:html={defaultThemeIcon} />\n  </button>\n</theme-select>\n\n<script is:inline>\n  ThemeProvider.updatePickers()\n</script>\n\n<script>\n  type Theme = 'auto' | 'dark' | 'light'\n\n  class ThemeSelect extends HTMLElement {\n    #key = 'theme'\n\n    constructor() {\n      super()\n      this.#onThemeChange(this.#loadTheme())\n      const buttons = this.querySelectorAll('button')\n      buttons.forEach(button => {\n        button.addEventListener('click', () => {\n          const theme = button.id as Theme\n          this.#onThemeChange(theme)\n        })\n      })\n    }\n\n    /** Get a typesafe theme string from any JS value (unknown values are coerced to `'auto'`). */\n    #parseTheme(theme: unknown): Theme {\n      if (theme === 'auto' || theme === 'dark' || theme === 'light') {\n        return theme\n      } else {\n        return 'auto'\n      }\n    }\n\n    /** Get the preferred system color scheme. */\n    #getPreferredColorScheme(): Theme {\n      return matchMedia('(prefers-color-scheme: light)').matches\n        ? 'light'\n        : 'dark'\n    }\n\n    /** Update select menu UI, document theme, and local storage state. */\n    #onThemeChange(theme: Theme): void {\n      ThemeProvider.updatePickers(theme)\n      document.documentElement.dataset.theme =\n        theme === 'auto' ? this.#getPreferredColorScheme() : theme\n      this.#storeTheme(theme)\n    }\n\n    /** Store the user’s preference in `localStorage`. */\n    #storeTheme(theme: Theme): void {\n      if (typeof localStorage !== 'undefined') {\n        if (theme === 'light' || theme === 'dark') {\n          localStorage.setItem(this.#key, theme)\n        } else {\n          localStorage.removeItem(this.#key)\n        }\n      }\n    }\n\n    /** Load the user’s preference from `localStorage`. */\n    #loadTheme(): Theme {\n      const theme =\n        typeof localStorage !== 'undefined' && localStorage.getItem(this.#key)\n      return this.#parseTheme(theme)\n    }\n  }\n\n  customElements.define('theme-select', ThemeSelect)\n</script>\n\n<style>\n  .theme-select-container {\n    display: flex;\n    text-align: center;\n    gap: 4px;\n\n    .theme-select-button-active {\n      background-color: var(--block-bg-color);\n      border-radius: 3px;\n      border: var(--active-border);\n      > svg path {\n        fill: var(--primary-text-color);\n      }\n    }\n    > button {\n      background: none;\n      border: none;\n      padding: 4px;\n      display: flex;\n      align-items: center;\n      cursor: pointer;\n      &:hover {\n        background: var(--block-bg-color);\n        border-radius: 3px;\n      }\n    }\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/TwoColumnContent.astro",
    "content": "---\nconst isApiPage = Astro.url.pathname.includes('/tools/api')\nconst hasToc = Astro.props.toc && !isApiPage\n---\n\n<div class={`main-pane-wrapper ${isApiPage ? 'no-toc' : ''}`}>\n  {\n    hasToc && (\n      <aside class=\"right-sidebar-container\">\n        <div class=\"right-sidebar\">\n          <slot name=\"right-sidebar\" />\n        </div>\n      </aside>\n    )\n  }\n  <div class=\"main-pane\"><slot /></div>\n</div>\n\n<style>\n  .main-pane {\n    isolation: isolate;\n  }\n  .main-pane-wrapper {\n    display: grid;\n    grid-template-columns: 7fr 2fr;\n    column-gap: 48px;\n    @media (max-width: 1024px) {\n      grid-template-columns: 100%;\n    }\n  }\n\n  .main-pane-wrapper.no-toc {\n    grid-template-columns: 100%;\n  }\n  .right-sidebar-container {\n    order: 2;\n    position: relative;\n    @media (max-width: 1024px) {\n      order: unset;\n      position: unset;\n    }\n  }\n\n  .right-sidebar {\n    position: sticky;\n    top: 74px;\n    padding-top: 40px;\n    width: 100%;\n    height: calc(100vh - 74px);\n    overflow-y: auto;\n    scrollbar-width: none;\n    @media (max-width: 1024px) {\n      padding-top: unset;\n      position: unset;\n      height: unset;\n    }\n  }\n\n  .main-pane {\n    width: 100%;\n  }\n\n  :global([data-has-sidebar][data-has-toc]) .main-pane {\n    --sl-content-margin-inline: auto 0;\n    order: 1;\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/Version.astro",
    "content": "---\nimport { major, minor } from 'semver'\n\nconst version = import.meta.env.VERSION || '0.0.1'\nconst [maj, min] = [major(version), minor(version)]\n---\n\n{maj}.{min}\n"
  },
  {
    "path": "apps/docs/src/components/buttons/Button.module.scss",
    "content": ".button {\n  border-radius: 4px;\n  padding: 0.25rem 0.5rem;\n  gap: 0.5rem;\n  justify-content: center;\n  align-items: center;\n  display: flex;\n  border-radius: 0.25rem;\n\n  cursor: pointer;\n\n  font-size: 0.875rem;\n  line-height: 1rem;\n  font-weight: 500;\n  transition-property: all 0.2s ease-in-out;\n  color: var(--foreground-color);\n  background-color: var(--block-bg-color);\n  border: 1px solid var(--border-color);\n\n  &.ghost {\n    background-color: transparent;\n    border: 1px solid transparent;\n  }\n\n  &:hover {\n    background-color: var(--cta-surface-neutral-primary);\n  }\n\n  & > svg {\n    width: 14px;\n    height: 14px;\n    flex-shrink: 0;\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/components/buttons/CopyButton.tsx",
    "content": "'use client'\n\nimport { clsx as cn } from 'clsx'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { CheckIcon, CopyIcon } from 'lucide-react'\nimport type { ComponentProps } from 'react'\nimport * as React from 'react'\n\nimport styles from './Button.module.scss'\n\nfunction useCopyToClipboard({\n  timeout = 2000,\n  onCopy,\n}: {\n  timeout?: number\n  onCopy?: () => void\n} = {}) {\n  const [isCopied, setIsCopied] = React.useState(false)\n\n  const copyToClipboard = (value: string) => {\n    if (typeof window === 'undefined' || !navigator.clipboard.writeText) {\n      return\n    }\n\n    if (!value) {\n      return\n    }\n\n    navigator.clipboard.writeText(value).then(() => {\n      setIsCopied(true)\n\n      onCopy?.()\n\n      if (timeout !== 0) {\n        setTimeout(() => {\n          setIsCopied(false)\n        }, timeout)\n      }\n    }, console.error)\n  }\n\n  return { isCopied, copyToClipboard }\n}\n\nconst iconProps = {\n  initial: { opacity: 0, y: 5 },\n  animate: { opacity: 1, y: 0 },\n  exit: { opacity: 0, y: -5 },\n  transition: { duration: 0.125 },\n}\n\nconst MotionCopyIcon = motion(CopyIcon)\nconst MotionCheckIcon = motion(CheckIcon)\n\ninterface Props {\n  value: string\n  variant?: 'default' | 'ghost'\n}\nexport function CopyButton({\n  value,\n  children,\n  className,\n  variant = 'default',\n  ...props\n}: Props & ComponentProps<'button'>) {\n  const { isCopied, copyToClipboard } = useCopyToClipboard()\n\n  return (\n    <button\n      className={cn(\n        styles.button,\n        {\n          [styles.ghost]: variant === 'ghost',\n          [styles.default]: variant === 'default',\n        },\n        className\n      )}\n      type=\"button\"\n      onClick={() => copyToClipboard(value)}\n      {...props}\n    >\n      <AnimatePresence initial={false} mode=\"wait\">\n        {isCopied ? (\n          <MotionCheckIcon size={14} key=\"copied\" {...iconProps} />\n        ) : (\n          <MotionCopyIcon size={14} key=\"copy\" {...iconProps} />\n        )}\n      </AnimatePresence>\n      {children}\n    </button>\n  )\n}\n"
  },
  {
    "path": "apps/docs/src/components/buttons/LinkButton.tsx",
    "content": "import { clsx as cn } from 'clsx'\nimport type { ComponentProps } from 'react'\n\nimport styles from './Button.module.scss'\n\ninterface Props {\n  variant?: 'default' | 'ghost'\n}\nexport function LinkButton({\n  children,\n  className,\n  variant = 'default',\n  ...props\n}: Props & ComponentProps<'a'>) {\n  return (\n    <a\n      className={cn(\n        styles.button,\n        {\n          [styles.ghost]: variant === 'ghost',\n          [styles.default]: variant === 'default',\n        },\n        className\n      )}\n      {...props}\n    >\n      {children}\n    </a>\n  )\n}\n"
  },
  {
    "path": "apps/docs/src/components/cards/Card.astro",
    "content": "---\nconst { icon, title, link } = Astro.props\n---\n\n<a class=\"description-card\" href={link}>\n  <figure>\n    <Fragment set:html={icon} />\n  </figure>\n  <h6>{title}</h6>\n  <slot />\n</a>\n"
  },
  {
    "path": "apps/docs/src/components/cards/CardGrid.astro",
    "content": "---\nconst {\n  gridNumber,\n  mobileGridNumber,\n  colsMinWidth,\n  colsMinWidthMobile,\n  gridGap = '16px',\n} = Astro.props\n---\n\n<div class:list={'card-grid'}><slot /></div>\n\n<style\n  define:vars={{\n    gridNumber,\n    mobileGridNumber,\n    colsMinWidth,\n    gridGap,\n    colsMinWidthMobile,\n  }}\n>\n  .card-grid {\n    display: grid;\n    grid-template-columns: repeat(\n      auto-fit,\n      minmax(\n        min(\n          (\n            100% / var(--mobileGridNumber) - var(--gridGap) *\n              (var(--mobileGridNumber) - 1) / var(--mobileGridNumber)\n          ),\n          max(\n            var(--colsMinWidth),\n            (\n              100% / var(--gridNumber) - var(--gridGap) *\n                (var(--gridNumber) - 1) / var(--gridNumber)\n            )\n          )\n        ),\n        1fr\n      )\n    );\n    gap: 16px;\n    justify-items: center;\n    @media (max-width: 650px) {\n      grid-template-columns: repeat(\n        auto-fit,\n        minmax(\n          min(\n            (\n              100% / var(--mobileGridNumber) - var(--gridGap) *\n                (var(--mobileGridNumber) - 1) / var(--mobileGridNumber)\n            ),\n            max(\n              var(--colsMinWidthMobile),\n              (\n                100% / var(--gridNumber) - var(--gridGap) *\n                  (var(--gridNumber) - 1) / var(--gridNumber)\n              )\n            )\n          ),\n          1fr\n        )\n      );\n    }\n  }\n</style>\n"
  },
  {
    "path": "apps/docs/src/components/cards/ImageCard.astro",
    "content": "---\nimport { Image } from 'astro:assets'\nconst { imageDark, imageAlt, link, icon } = Astro.props\n---\n\n<a href={link} class=\"image-card\">\n  <figure>\n    {!icon && <Image src={imageDark} alt={imageAlt} />}\n    {icon && <Image src={icon} alt={imageAlt} width={46} height={46} />}\n  </figure>\n</a>\n"
  },
  {
    "path": "apps/docs/src/components/cards/LinkCard.astro",
    "content": "---\nconst { title, link } = Astro.props\n---\n\n<a class=\"link-card\" href={link}>\n  <span class=\"title\">{title}</span>\n  <span class=\"description\">\n    <slot />\n  </span>\n</a>\n"
  },
  {
    "path": "apps/docs/src/components/cards/TitleCard.astro",
    "content": "---\nconst { icon, title, link } = Astro.props\n---\n\n<a href={link} class=\"title-card\">\n  <figure>\n    <Fragment set:html={icon} />\n  </figure>\n  <h6>{title}</h6>\n</a>\n"
  },
  {
    "path": "apps/docs/src/components/menu/LocaleSelector.module.scss",
    "content": ".localeSelector {\n  display: flex;\n  align-items: center;\n  height: 30px;\n  border: none;\n  border-right: 6px solid var(--block-bg-color);\n  border-left: 4px solid var(--block-bg-color);\n  border-radius: 0.25rem;\n  background-color: var(--block-bg-color);\n  color: var(--foreground-color);\n  font-size: 0.875rem;\n  line-height: 1rem;\n  font-weight: 500;\n  user-select: none;\n  box-shadow: 0 0 0 1px var(--border-color);\n  padding-right: 4px;\n\n  &:focus-visible {\n    outline: 1px solid initial;\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/components/menu/LocaleSelector.tsx",
    "content": "import { GTProvider, useLocaleSelector } from 'gt-react'\nimport type { ChangeEvent, ComponentProps } from 'react'\nimport loadTranslations from 'src/i18n/loadTranslations'\nimport { localizePath } from 'src/i18n/utils'\n\nimport gtConfig from '../../../gt.config.json'\nimport styles from './LocaleSelector.module.scss'\n\nfunction capitalizeLanguageName(language: string): string {\n  if (!language) return ''\n  return (\n    language.charAt(0).toUpperCase() +\n    (language.length > 1 ? language.slice(1) : '')\n  )\n}\n\ntype Props = ComponentProps<'select'>\n\nfunction LocaleSelector({\n  locales: _locales,\n  ...props\n}: Props & { locales?: string[] }): React.JSX.Element | null {\n  const {\n    locale: currentLocale,\n    locales,\n    getLocaleProperties,\n  } = useLocaleSelector(_locales ? _locales : undefined)\n\n  if (!locales || locales.length === 0 || !currentLocale) {\n    return null\n  }\n\n  const getDisplayName = (locale: string) =>\n    capitalizeLanguageName(getLocaleProperties(locale).nativeNameWithRegionCode)\n\n  const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {\n    const nextLocale = event.target.value\n    if (!nextLocale || nextLocale === currentLocale) return\n\n    window.location.href = localizePath(\n      window.location.pathname,\n      nextLocale,\n      currentLocale\n    )\n  }\n\n  const { className, ...restProps } = props\n\n  return (\n    <select\n      className={styles.localeSelector}\n      value={currentLocale}\n      onChange={handleChange}\n    >\n      {locales.map(locale => (\n        <option key={locale} value={locale}>\n          {getDisplayName(locale)}\n        </option>\n      ))}\n    </select>\n  )\n}\n\nexport const LocaleSelect = ({\n  locale,\n  ...props\n}: { locale: string } & Props) => {\n  return (\n    <GTProvider\n      config={gtConfig}\n      loadTranslations={loadTranslations}\n      locale={locale}\n      projectId={import.meta.env.PUBLIC_VITE_GT_PROJECT_ID}\n      devApiKey={import.meta.env.PUBLIC_VITE_GT_API_KEY}\n    >\n      <LocaleSelector {...props} />\n    </GTProvider>\n  )\n}\n"
  },
  {
    "path": "apps/docs/src/components/menu/SideNavLinks.tsx",
    "content": "import { GTProvider, T, useGT } from 'gt-react'\nimport { useEffect, useState } from 'react'\nimport loadTranslations from 'src/i18n/loadTranslations'\n\nimport gtConfig from '../../../gt.config.json'\n\nconst GITHUB_STARS_FORMATTER = new Intl.NumberFormat('en-US', {\n  notation: 'compact',\n  maximumFractionDigits: 1,\n})\n\nconst SideNavLinksContent = () => {\n  const [stars, setStars] = useState<number | null | undefined>(undefined)\n  const t = useGT()\n  useEffect(() => {\n    const storedStars = sessionStorage.getItem('stargazers')\n    if (!storedStars || isNaN(Number(storedStars))) {\n      fetch('https://api.github.com/repos/daytonaio/daytona')\n        .then(response => response.json())\n        .then(data => {\n          setStars(data.stargazers_count)\n          sessionStorage.setItem('stargazers', String(data.stargazers_count))\n        })\n        .catch(error => {\n          console.error(error)\n          setStars(null)\n        })\n    } else {\n      setStars(Number(storedStars))\n    }\n  }, [])\n\n  return (\n    <>\n      <T>\n        <div className=\"nav-item call\">\n          <a\n            href=\"https://app.daytona.io\"\n            target=\"_blank\"\n            className=\"nav__link\"\n            rel=\"noreferrer\"\n          >\n            Sign in\n          </a>\n        </div>\n      </T>\n\n      <div className=\"nav-item github\">\n        <a\n          href=\"https://github.com/daytonaio\"\n          target=\"_blank\"\n          className=\"nav__link\"\n          rel=\"noreferrer\"\n        >\n          <svg\n            width=\"17\"\n            height=\"16\"\n            viewBox=\"0 0 17 16\"\n            fill=\"none\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n          >\n            <path\n              fillRule=\"evenodd\"\n              clipRule=\"evenodd\"\n              d=\"M8.86217 0C4.36603 0 0.724365 3.67055 0.724365 8.20235C0.724365 11.8319 3.05381 14.8975 6.28859 15.9843C6.69548 16.0561 6.84807 15.81 6.84807 15.5947C6.84807 15.3999 6.83789 14.754 6.83789 14.067C4.79327 14.4464 4.26431 13.5646 4.10156 13.1033C4.01001 12.8674 3.61329 12.1395 3.26743 11.9447C2.98261 11.7909 2.57572 11.4115 3.25726 11.4013C3.89811 11.391 4.35586 11.9959 4.50845 12.242C5.24085 13.4826 6.41066 13.134 6.87858 12.9187C6.94979 12.3856 7.16341 12.0267 7.39737 11.8216C5.58671 11.6166 3.69467 10.9091 3.69467 7.77173C3.69467 6.87972 4.01001 6.14151 4.52879 5.56735C4.44741 5.36229 4.16259 4.52155 4.61017 3.39372C4.61017 3.39372 5.29171 3.17841 6.84807 4.23446C7.49909 4.04991 8.19081 3.95763 8.88252 3.95763C9.57423 3.95763 10.2659 4.04991 10.917 4.23446C12.4733 3.16816 13.1549 3.39372 13.1549 3.39372C13.6024 4.52155 13.3176 5.36229 13.2362 5.56735C13.755 6.14151 14.0704 6.86947 14.0704 7.77173C14.0704 10.9194 12.1682 11.6166 10.3575 11.8216C10.6525 12.078 10.9068 12.5701 10.9068 13.3391C10.9068 14.4361 10.8966 15.3179 10.8966 15.5947C10.8966 15.81 11.0492 16.0664 11.4561 15.9843C14.6705 14.8975 17 11.8216 17 8.20235C17 3.67055 13.3583 0 8.86217 0Z\"\n            ></path>\n          </svg>\n          {stars === undefined\n            ? ''\n            : stars === null\n              ? t('Star', { $context: 'As in a star on GitHub' })\n              : GITHUB_STARS_FORMATTER.format(stars)}\n        </a>\n      </div>\n    </>\n  )\n}\n\nexport const SideNavLinks = ({ locale }: { locale: string }) => {\n  return (\n    <GTProvider\n      config={gtConfig}\n      loadTranslations={loadTranslations}\n      locale={locale}\n      projectId={import.meta.env.PUBLIC_VITE_GT_PROJECT_ID}\n      devApiKey={import.meta.env.PUBLIC_VITE_GT_API_KEY}\n    >\n      <SideNavLinksContent />\n    </GTProvider>\n  )\n}\n"
  },
  {
    "path": "apps/docs/src/components/table/Table.astro",
    "content": "---\n\n---\n\n<div class=\"not-content\">\n  <table class=\"container\">\n    <slot />\n  </table>\n</div>\n"
  },
  {
    "path": "apps/docs/src/components/table/TableRow.astro",
    "content": "---\ninterface Props {\n  contents: string | string[] | HTMLElement | HTMLSpanElement\n}\nconst { contents } = Astro.props\n// This thing needs to be fixed, problem: 1. HTMLElement can't be rendered as props, ideally they should be 2. Array are not getting rendered correctly, current implementation is a temporary fix\n---\n\n{\n  !Array.isArray(contents) ? (\n    <tr class=\"table-row\">\n      <td class=\"table-data\">{contents ? contents : <slot />}</td>\n      {<slot name=\"html\" /> && (\n        <td>\n          <slot name=\"html\" />\n        </td>\n      )}\n    </tr>\n  ) : (\n    <tr class=\"table-row\">\n      {contents ? (\n        contents.map(content => {\n          ;<td class=\"table-data\">{content}</td>\n        })\n      ) : (\n        <slot />\n      )}\n    </tr>\n  )\n}\n"
  },
  {
    "path": "apps/docs/src/content/config.ts",
    "content": "import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'\nimport { defineCollection, z } from 'astro:content'\nimport { generateI18nSchema } from 'src/i18n/generateI18nSchema'\nimport { localizePath } from 'src/i18n/utils'\n\nimport type { NavigationGroup } from '../utils/navigation'\n\nexport const collections = {\n  docs: defineCollection({\n    schema: docsSchema({\n      extend: z.object({\n        licence: z.string().optional(),\n        distribution: z.string().optional(),\n        hideTitleOnPage: z.boolean().optional(),\n      }),\n    }),\n  }),\n  i18n: defineCollection({\n    type: 'data',\n    schema: i18nSchema({\n      extend: generateI18nSchema(),\n    }),\n  }),\n}\n\nexport enum NavigationCategory {\n  MAIN,\n  GENERAL,\n  TYPESCRIPT_SDK,\n  PYTHON_SDK,\n  GUIDES,\n  RUBY_SDK,\n  GO_SDK,\n}\n\n/**\n * relatedGroupCategory - Applicable only to main navigation links. All links with that category will be shown in the sidebar when the link is active.\n * category - Applicable to groups. All links with that category will be shown in the sidebar when the link with that category or the main link that is related to the category is active.\n * homePageHref - Applicable to groups. The href of the link that will be used as previous link for the pagination component (if the current link is the first in the list).\n * disablePagination - Applicable to all links. If true, the pagination component will not be shown for the link.\n * autopopulateFromDir - Applicable to groups. If set, the group will be populated with all the files (except index file) in the directory.\n */\nexport const getSidebarConfig = (\n  locale: string,\n  labels?: ((key: string) => string) | Record<string, string>\n): NavigationGroup[] => {\n  const t =\n    typeof labels === 'function'\n      ? labels\n      : (key: string) => labels?.[key] ?? key\n\n  if (!t || typeof t !== 'function') return []\n  return [\n    {\n      type: 'group',\n      category: NavigationCategory.MAIN,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs', locale),\n          label: t('sidebarconfig.documentation'),\n          attrs: {\n            icon: 'home.svg',\n          },\n          relatedGroupCategory: NavigationCategory.GENERAL,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/typescript-sdk', locale),\n          label: t('sidebarconfig.tsSdkReference'),\n          attrs: {\n            icon: 'package.svg',\n          },\n          relatedGroupCategory: NavigationCategory.TYPESCRIPT_SDK,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/python-sdk', locale),\n          label: t('sidebarconfig.pythonSdkReference'),\n          attrs: {\n            icon: 'package.svg',\n          },\n          relatedGroupCategory: NavigationCategory.PYTHON_SDK,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/ruby-sdk', locale),\n          label: t('sidebarconfig.rubySdkReference'),\n          attrs: {\n            icon: 'package.svg',\n          },\n          relatedGroupCategory: NavigationCategory.RUBY_SDK,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/go-sdk', locale),\n          label: t('sidebarconfig.goSdkReference'),\n          attrs: {\n            icon: 'package.svg',\n          },\n          relatedGroupCategory: NavigationCategory.GO_SDK,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/tools/api', locale),\n          label: t('sidebarconfig.apiReference'),\n          disablePagination: true,\n          attrs: {\n            icon: 'server.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/tools/cli', locale),\n          label: t('sidebarconfig.cliReference'),\n          disablePagination: true,\n          attrs: {\n            icon: 'terminal.svg',\n          },\n        },\n        // {\n        //   type: 'link',\n        //   href: 'https://www.daytona.io/dotfiles/guides',\n        //   label: t('sidebarconfig.guides'),\n        //   disablePagination: true,\n        //   external: true,\n        //   attrs: {\n        //     icon: 'book.svg',\n        //   },\n        // },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.introduction'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs', locale),\n          label: t('sidebarconfig.quickStart'),\n          attrs: {\n            icon: 'rocket.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/architecture', locale),\n          label: t('sidebarconfig.architecture'),\n          description: t('sidebarconfig.architectureDescription'),\n          attrs: {\n            icon: 'architecture.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/getting-started', locale),\n          label: t('sidebarconfig.gettingStarted'),\n          description: t('sidebarconfig.gettingStartedDescription'),\n          attrs: {\n            icon: 'bookmark.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/sandboxes', locale),\n          label: t('sidebarconfig.sandboxes'),\n          description: t('sidebarconfig.sandboxesDescription'),\n          attrs: {\n            icon: 'rectangle.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.sandbox'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/configuration', locale),\n          label: t('sidebarconfig.environment'),\n          description: t('sidebarconfig.configurationDescription'),\n          attrs: {\n            icon: 'git-commit.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/snapshots', locale),\n          label: t('sidebarconfig.snapshots'),\n          description: t('sidebarconfig.snapshotsDescription'),\n          attrs: {\n            icon: 'layers.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/declarative-builder', locale),\n          label: t('sidebarconfig.declarativeBuilder'),\n          description: t('sidebarconfig.declarativeBuilderDescription'),\n          attrs: {\n            icon: 'prebuilds.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/volumes', locale),\n          label: t('sidebarconfig.volumes'),\n          description: t('sidebarconfig.volumesDescription'),\n          attrs: {\n            icon: 'container-registries.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/regions', locale),\n          label: t('sidebarconfig.regions'),\n          description: t('sidebarconfig.regionsDescription'),\n          attrs: {\n            icon: 'globe.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.agentTools'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/file-system-operations', locale),\n          label: t('sidebarconfig.fileSystem'),\n          description: t('sidebarconfig.fileSystemDescription'),\n          attrs: {\n            icon: 'folder.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/git-operations', locale),\n          label: t('sidebarconfig.gitOperations'),\n          description: t('sidebarconfig.gitOperationsDescription'),\n          attrs: {\n            icon: 'git-branch.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/language-server-protocol', locale),\n          label: t('sidebarconfig.languageServerProtocol'),\n          description: t('sidebarconfig.languageServerProtocolDescription'),\n          attrs: {\n            icon: 'pulse.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/process-code-execution', locale),\n          label: t('sidebarconfig.processCodeExecution'),\n          description: t('sidebarconfig.processCodeExecutionDescription'),\n          attrs: {\n            icon: 'computer.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/pty', locale),\n          label: t('sidebarconfig.pty'),\n          description: t('sidebarconfig.ptyDescription'),\n          attrs: {\n            icon: 'terminal.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/log-streaming', locale),\n          label: t('sidebarconfig.logStreaming'),\n          description: t('sidebarconfig.logStreamingDescription'),\n          attrs: {\n            icon: 'log2.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/mcp', locale),\n          label: t('sidebarconfig.mcpServer'),\n          disablePagination: true,\n          attrs: {\n            icon: 'server.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/computer-use', locale),\n          label: t('sidebarconfig.computerUse'),\n          disablePagination: true,\n          attrs: {\n            icon: 'computer.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.humanTools'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/web-terminal', locale),\n          label: t('sidebarconfig.webTerminal'),\n          description: t('sidebarconfig.webTerminalDescription'),\n          attrs: {\n            icon: 'terminal.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/ssh-access', locale),\n          label: t('sidebarconfig.sshAccess'),\n          description: t('sidebarconfig.sshAccessDescription'),\n          attrs: {\n            icon: 'terminal.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/vnc-access', locale),\n          label: t('sidebarconfig.vncAccess'),\n          description: t('sidebarconfig.vncAccessDescription'),\n          attrs: {\n            icon: 'vnc.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/vpn-connections', locale),\n          label: t('sidebarconfig.vpnConnection'),\n          description: t('sidebarconfig.vpnConnectionDescription'),\n          attrs: {\n            icon: 'shield.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/preview', locale),\n          label: t('sidebarconfig.preview'),\n          description: t('sidebarconfig.previewDescription'),\n          attrs: {\n            icon: 'globe.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/custom-preview-proxy', locale),\n          label: t('sidebarconfig.customPreviewProxy'),\n          description: t('sidebarconfig.customPreviewProxyDescription'),\n          attrs: {\n            icon: 'proxy-link.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/playground', locale),\n          label: t('sidebarconfig.playground'),\n          description: t('sidebarconfig.playgroundDescription'),\n          attrs: {\n            icon: 'playground.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.systemTools'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/webhooks', locale),\n          label: t('sidebarconfig.webhooks'),\n          description: t('sidebarconfig.webhooksDescription'),\n          attrs: {\n            icon: 'webhook.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/network-limits', locale),\n          label: t('sidebarconfig.networkLimits'),\n          description: t('sidebarconfig.networkLimitsDescription'),\n          attrs: {\n            icon: 'network-limits.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.integrations'),\n      homePageHref: localizePath('/docs/guides', locale),\n      category: NavigationCategory.GUIDES,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/guides', locale),\n          label: t('sidebarconfig.guides'),\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/guides/data-analysis-with-ai', locale),\n          label: t('sidebarconfig.dataAnalysis'),\n          disablePagination: true,\n          attrs: {\n            icon: 'chart.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/agentkit/inngest-agentkit-coding-agent',\n            locale\n          ),\n          label: t('sidebarconfig.inngestAgentKit'),\n          disablePagination: true,\n          attrs: {\n            icon: 'inngest-agentkit.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/guides/opencode', locale),\n          label: t('sidebarconfig.opencode'),\n          disablePagination: true,\n          attrs: {\n            icon: 'opencode.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/opencode/opencode-plugin',\n            locale\n          ),\n          label: t('sidebarconfig.opencode'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/opencode/opencode-sdk-agent',\n            locale\n          ),\n          label: t('sidebarconfig.opencode'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/opencode/opencode-web-agent',\n            locale\n          ),\n          label: t('sidebarconfig.opencode'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/langchain/langchain-data-analysis',\n            locale\n          ),\n          label: t('sidebarconfig.langchain'),\n          disablePagination: true,\n          attrs: {\n            icon: 'langchain.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/guides/mastra/mastra-coding-agent', locale),\n          label: t('sidebarconfig.mastra'),\n          disablePagination: true,\n          attrs: {\n            icon: 'mastra.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/guides/claude', locale),\n          label: t('sidebarconfig.claude'),\n          disablePagination: true,\n          attrs: {\n            icon: 'claude.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/claude/claude-code-run-cli-sandbox',\n            locale\n          ),\n          label: t('sidebarconfig.claude'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/claude/claude-agent-sdk-interactive-terminal-sandbox',\n            locale\n          ),\n          label: t('sidebarconfig.claude'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/claude/claude-agent-sdk-connect-service-sandbox',\n            locale\n          ),\n          label: t('sidebarconfig.claude'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/claude/claude-code-run-tasks-stream-logs-sandbox',\n            locale\n          ),\n          label: t('sidebarconfig.claude'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/guides/openclaw', locale),\n          label: t('sidebarconfig.openclaw'),\n          disablePagination: true,\n          attrs: {\n            icon: 'openclaw.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/openclaw/openclaw-run-secure-sandbox',\n            locale\n          ),\n          label: t('sidebarconfig.openclaw'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/openclaw/openclaw-sdk-sandbox',\n            locale\n          ),\n          label: t('sidebarconfig.openclaw'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/codex/codex-sdk-interactive-terminal-sandbox',\n            locale\n          ),\n          label: t('sidebarconfig.codex'),\n          disablePagination: true,\n          attrs: {\n            icon: 'openai.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/guides/google-adk-code-generator', locale),\n          label: t('sidebarconfig.googleAdk'),\n          disablePagination: true,\n          attrs: {\n            icon: 'google-adk.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/letta-code/letta-code-agent',\n            locale\n          ),\n          label: t('sidebarconfig.lettacode'),\n          disablePagination: true,\n          attrs: {\n            icon: 'letta-code.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/reinforcement-learning/trl-grpo-training',\n            locale\n          ),\n          label: t('sidebarconfig.trlGrpo'),\n          disablePagination: true,\n          attrs: {\n            icon: 'trl-logo.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/guides/rlm', locale),\n          label: t('sidebarconfig.rlm'),\n          disablePagination: true,\n          attrs: {\n            icon: 'recursive-lm.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath(\n            '/docs/guides/rlm/recursive-language-models',\n            locale\n          ),\n          label: t('sidebarconfig.rlm'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/guides/rlm/dspy-rlms', locale),\n          label: t('sidebarconfig.rlm'),\n          disablePagination: true,\n          hideInSidebar: true,\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.security'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/audit-logs', locale),\n          label: t('sidebarconfig.auditLogs'),\n          description: t('sidebarconfig.auditLogsDescription'),\n          attrs: {\n            icon: 'log.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/security-exhibit', locale),\n          label: t('sidebarconfig.securityExhibit'),\n          description: t('sidebarconfig.securityExhibitDescription'),\n          attrs: {\n            icon: 'security.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.deployments'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/oss-deployment', locale),\n          label: t('sidebarconfig.ossDeployment'),\n          disablePagination: true,\n          attrs: {\n            icon: 'computer.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/runners', locale),\n          label: t('sidebarconfig.customerManagedCompute'),\n          description: t('sidebarconfig.customerManagedComputeDescription'),\n          disablePagination: true,\n          attrs: {\n            icon: 'computer.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.experimental'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/experimental/otel-collection', locale),\n          label: t('sidebarconfig.otelCollection'),\n          disablePagination: true,\n          attrs: {\n            icon: 'telemetry.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.accountManagement'),\n      homePageHref: localizePath('/docs', locale),\n      category: NavigationCategory.GENERAL,\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/api-keys', locale),\n          label: t('sidebarconfig.apiKeys'),\n          description: t('sidebarconfig.apiKeysDescription'),\n          attrs: {\n            icon: 'tag.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/organizations', locale),\n          label: t('sidebarconfig.organizations'),\n          description: t('sidebarconfig.organizationsDescription'),\n          attrs: {\n            icon: 'building.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/limits', locale),\n          label: t('sidebarconfig.limits'),\n          description: t('sidebarconfig.limitsDescription'),\n          attrs: {\n            icon: 'log.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/billing', locale),\n          label: t('sidebarconfig.billing'),\n          description: t('sidebarconfig.billingDescription'),\n          attrs: {\n            icon: 'credit-card.svg',\n          },\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/linked-accounts', locale),\n          label: t('sidebarconfig.linkedAccounts'),\n          description: t('sidebarconfig.linkedAccountsDescription'),\n          attrs: {\n            icon: 'link.svg',\n          },\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.tsSdkReference'),\n      homePageHref: localizePath('/docs/typescript-sdk', locale),\n      category: NavigationCategory.TYPESCRIPT_SDK,\n      autopopulateFromDir: localizePath('/docs/typescript-sdk', locale),\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/typescript-sdk', locale),\n          label: t('sidebarconfig.tsSdkReference'),\n          hideInSidebar: true,\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/typescript-sdk/daytona', locale),\n          label: t('sidebarconfig.daytona'),\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/typescript-sdk/sandbox', locale),\n          label: t('sidebarconfig.sandbox'),\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.common'),\n      homePageHref: localizePath('/docs/python-sdk', locale),\n      category: NavigationCategory.PYTHON_SDK,\n      autopopulateFromDir: localizePath('/docs/python-sdk/common', locale),\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/python-sdk', locale),\n          label: t('sidebarconfig.pythonSdkReference'),\n          hideInSidebar: true,\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.syncPython'),\n      homePageHref: localizePath('/docs/python-sdk', locale),\n      category: NavigationCategory.PYTHON_SDK,\n      autopopulateFromDir: localizePath('/docs/python-sdk/sync', locale),\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/python-sdk/sync/daytona', locale),\n          label: t('sidebarconfig.daytona'),\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/python-sdk/sync/sandbox', locale),\n          label: t('sidebarconfig.sandbox'),\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.asyncPython'),\n      homePageHref: localizePath('/docs/python-sdk', locale),\n      category: NavigationCategory.PYTHON_SDK,\n      autopopulateFromDir: localizePath('/docs/python-sdk/async', locale),\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/python-sdk/async/async-daytona', locale),\n          label: t('sidebarconfig.asyncDaytona'),\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/python-sdk/async/async-sandbox', locale),\n          label: t('sidebarconfig.asyncSandbox'),\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.rubySdkReference'),\n      homePageHref: localizePath('/docs/ruby-sdk', locale),\n      category: NavigationCategory.RUBY_SDK,\n      autopopulateFromDir: localizePath('/docs/ruby-sdk', locale),\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/ruby-sdk/daytona', locale),\n          label: t('sidebarconfig.daytona'),\n        },\n        {\n          type: 'link',\n          href: localizePath('/docs/ruby-sdk/sandbox', locale),\n          label: t('sidebarconfig.sandbox'),\n        },\n      ],\n    },\n    {\n      type: 'group',\n      label: t('sidebarconfig.goSdkReference'),\n      homePageHref: localizePath('/docs/go-sdk', locale),\n      category: NavigationCategory.GO_SDK,\n      autopopulateFromDir: localizePath('/docs/go-sdk', locale),\n      entries: [\n        {\n          type: 'link',\n          href: localizePath('/docs/go-sdk/daytona', locale),\n          label: t('sidebarconfig.daytona'),\n        },\n      ],\n    },\n  ]\n}\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/404.md",
    "content": "---\ntitle: 'Something went wrong · Daytona'\ntemplate: doc\neditUrl: false\ntableOfContents: false\npagefind: false\nhead:\n  - tag: title\n    content: Something went wrong · Daytona\nhero:\n  title: 'Something went wrong'\n  tagline: Oops! Page not found.\n---\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/api-keys.mdx",
    "content": "---\ntitle: API Keys\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona API keys authenticate requests to the [Daytona API](/docs/en/tools/api). They are used by the Daytona [SDKs](/docs/en/getting-started#sdks) and [CLI](/docs/en/getting-started#cli) to access and manage resources in your organization.\n\n## Create an API key\n\nDaytona provides options to create API keys in [Daytona Dashboard ↗](https://app.daytona.io/dashboard/keys) or programmatically using the [API](/docs/en/tools/api/#daytona/tag/api-keys).\n\n1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/keys)\n2. Click the **Create Key** button\n3. Enter the name of the API key, set the expiration date, and [select permissions](#permissions--scopes)\n4. Click **Create** to create the API key\n5. Copy the API key to your clipboard\n\nTo use the API key in your application, set the `DAYTONA_API_KEY` environment variable. Daytona supports multiple options to configure your environment: [in code](/docs/en/configuration#configuration-in-code), [environment variables](/docs/en/configuration#environment-variables), [.env file](/docs/en/configuration#env-file), and [default values](/docs/en/configuration#default-values).\n\nAPI keys support optional expiration and can be revoked at any time. After creation, you can only retrieve a masked key value when listing keys.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/api-keys' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --data '{\n  \"name\": \"My API Key\",\n  \"permissions\": [\"write:sandboxes\", \"delete:sandboxes\"],\n  \"expiresAt\": \"2030-01-01T00:00:00.000Z\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/api-keys) reference:\n\n> [**Create API key (API)**](/docs/en/tools/api/#daytona/tag/api-keys/POST/api-keys)\n\n## Permissions & Scopes\n\n| **Resource** | **Scope**               | **Description**          |\n| ------------ | ----------------------- | ------------------------ |\n| Sandboxes    | **`write:sandboxes`**   | Create/modify sandboxes  |\n|              | **`delete:sandboxes`**  | Delete sandboxes         |\n| Snapshots    | **`write:snapshots`**   | Create/modify snapshots  |\n|              | **`delete:snapshots`**  | Delete snapshots         |\n| Registries   | **`write:registries`**  | Create/modify registries |\n|              | **`delete:registries`** | Delete registries        |\n| Volumes      | **`read:volumes`**      | View volumes             |\n|              | **`write:volumes`**     | Create/modify volumes    |\n|              | **`delete:volumes`**    | Delete volumes           |\n| Audit        | **`read:audit_logs`**   | View audit logs          |\n| Regions      | **`write:regions`**     | Create/modify regions    |\n|              | **`delete:regions`**    | Delete regions           |\n| Runners      | **`read:runners`**      | View runners             |\n|              | **`write:runners`**     | Create/modify runners    |\n|              | **`delete:runners`**    | Delete runners           |\n\n## List API keys\n\nDaytona provides methods to list all API keys for the current user or organization.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/api-keys' \\\n  --header 'Authorization: Bearer YOUR_API_KEY'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/api-keys) reference:\n\n> [**list (API)**](/docs/en/tools/api/#daytona/tag/api-keys/GET/api-keys)\n\n## Get current API key\n\nDaytona provides methods to get details of the API key used to authenticate the current request.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/api-keys/current' \\\n  --header 'Authorization: Bearer YOUR_API_KEY'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/api-keys) reference:\n\n> [**get current (API)**](/docs/en/tools/api/#daytona/tag/api-keys/GET/api-keys/current)\n\n## Get API key\n\nDaytona provides methods to get a single API key by name.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/api-keys/my-api-key' \\\n  --header 'Authorization: Bearer YOUR_API_KEY'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/api-keys) reference:\n\n> [**get (API)**](/docs/en/tools/api/#daytona/tag/api-keys/GET/api-keys/{name})\n\n## Delete API key\n\nDaytona provides options to delete an API key in [Daytona Dashboard ↗](https://app.daytona.io/dashboard/keys) or programmatically using the API. The key is revoked immediately and cannot be recovered.\n\n1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/keys)\n2. Click **Revoke** next to the API key you want to delete\n3. Confirm the revocation\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/api-keys/my-api-key' \\\n  --request DELETE \\\n  --header 'Authorization: Bearer YOUR_API_KEY'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/api-keys) reference:\n\n> [**delete (API)**](/docs/en/tools/api/#daytona/tag/api-keys/DELETE/api-keys/{name})\n\n## Delete API key for user\n\nDaytona provides options for organization admins to delete an API key for a specific user.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/api-keys/{userId}/my-api-key' \\\n  --request DELETE \\\n  --header 'Authorization: Bearer YOUR_API_KEY'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/api-keys) reference:\n\n> [**delete for user (API)**](/docs/en/tools/api/#daytona/tag/api-keys/DELETE/api-keys/{userId}/{name})\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/architecture.mdx",
    "content": "---\ntitle: Architecture\n---\n\nimport ArchitectureDiagram from '@components/ArchitectureDiagram.astro'\n\nDaytona provides **full composable computers** — [sandboxes](/docs/en/sandboxes) — for AI agents. Daytona platform is organized into multiple plane components, each serving a specific purpose:\n\n- [Interface plane](#interface-plane) provides client interfaces for interacting with Daytona\n- [Control plane](#control-plane) orchestrates all sandbox operations\n- [Compute plane](#compute-plane) runs and manages sandbox instances\n\n<ArchitectureDiagram />\n\n### Interface plane\n\nThe interface plane provides client interfaces for users and agents to interact with Daytona. The following components are part of the interface plane and available to all users and agents:\n\n- **SDK**: [Python](/docs/en/python-sdk), [TypeScript](/docs/en/typescript-sdk), [Ruby](/docs/en/ruby-sdk), and [Go](/docs/en/go-sdk) for programmatic sandbox management\n- [CLI](/docs/en/tools/cli): command-line interface for direct sandbox operations\n- [Dashboard](https://app.daytona.io/dashboard/): web interface for visual sandbox management and monitoring\n- [MCP](/docs/en/mcp): Model Context Protocol server for AI tool integration\n- [SSH](/docs/en/ssh-access): secure shell access to running sandboxes\n\n### Control plane\n\nThe control plane is the central coordination layer of the Daytona platform. It receives all client requests, manages the full sandbox lifecycle, schedules sandboxes onto runners, and continuously reconciles states across the infrastructure. The control plane includes the following components:\n\n- [API](#api) handles authentication, sandbox lifecycle management, and resource allocation\n- [Proxy](#proxy) routes external traffic to sandboxes, enabling direct access to services\n- [Snapshot builder](#snapshot-builder) builds and manages sandbox [snapshots](/docs/en/snapshots)\n- [Sandbox manager](#sandbox-manager) handles sandbox lifecycle management and state reconciliation\n\n#### API\n\nThe API is a NestJS-based RESTful service that serves as the primary entry point for all platform operations, managing authentication, sandbox lifecycle, snapshots, volumes, and resource allocation. The [snapshot builder](#snapshot-builder) and [sandbox manager](#sandbox-manager) run as internal processes within the API. The API integrates the following internal services and components:\n\n- **Redis** provides caching, session management, and distributed locking\n- **PostgreSQL** serves as the primary persistent store for metadata and configuration\n- **Auth0/OIDC provider** authenticates users and services via OpenID Connect. The API enforces organization-level multi-tenancy, where each sandbox, snapshot, and volume belongs to an organization, and access control is applied at the organization boundary\n- **SMTP server** handles email delivery for organization invitations, account notifications, and alert messages\n- [Sandbox manager](#sandbox-manager) schedules sandboxes onto runners, reconciles states, and enforces sandbox lifecycle management policies\n- **PostHog** collects platform analytics and usage metrics for monitoring and improvement\n\nTo interact with sandboxes from the API, see the [API](/docs/en/tools/api) and [Toolbox API](/docs/en/tools/api#daytona-toolbox) references.\n\n#### Proxy\n\nThe proxy is a dedicated HTTP proxy that routes external traffic to the correct sandbox using host-based routing. Each sandbox is reachable at `{port}-{sandboxId}.{proxy-domain}`, where the port maps to a service running inside the sandbox. The proxy resolves the target runner for a given sandbox, injects authentication headers, and forwards the request. It supports both HTTP and WebSocket protocols.\n\n#### Snapshot builder\n\nThe snapshot builder is part of the API process and orchestrates the creation of sandbox [snapshots](/docs/en/snapshots) from a Dockerfile or a pre-built image from a [container registry](#container-registry). It coordinates with runners to build or pull images, which are then pushed to an internal snapshot registry that implements the OCI distribution specification.\n\n#### Sandbox manager\n\nThe sandbox manager is part of the API process and schedules sandboxes onto runners, reconciles states, and enforces [sandbox lifecycle management](/docs/en/sandboxes#sandbox-lifecycle) policies.\n\n### Compute plane\n\nThe compute plane is the infrastructure layer where sandboxes run. Sandboxes run on [runners](#sandbox-runners), compute nodes that host multiple sandboxes with dedicated resources and scale horizontally across shared or dedicated [regions](/docs/en/regions). The compute plane consists of the following components:\n\n- [Sandbox runners](#sandbox-runners) host sandboxes with dedicated resources\n- [Sandbox daemon](#sandbox-daemon) provides code execution and environment access inside each sandbox\n- [Snapshot store](#snapshot-store) stores sandbox snapshot images\n- [Volumes](#volumes) provides persistent storage shared across sandboxes\n\n#### Sandbox runners\n\nRunners are compute nodes that power Daytona's compute plane, providing the underlying infrastructure for running sandbox workloads. Each runner polls the control plane API for jobs and executes sandbox operations: creating, starting, stopping, destroying, resizing, and backing up sandboxes. Runners interact with S3-compatible object storage for snapshot and volume data, and with the internal snapshot registry.\n\nEach sandbox runs as an isolated instance with its own Linux namespaces for processes, network, filesystem mounts, and inter-process communication. Each runner allocates dedicated vCPU, RAM, and disk resources per sandbox.\n\n#### Sandbox daemon\n\nThe sandbox daemon is a code execution agent that runs inside each sandbox. It exposes the [Toolbox API](/docs/en/tools/api#daytona-toolbox), providing direct access to the sandbox environment: file system and Git operations, process and code execution, computer use, log streaming, and terminal sessions.\n\n#### Snapshot store\n\nThe snapshot store is an internal OCI-compliant registry that stores sandbox snapshot images using the OCI distribution specification. Runners pull snapshot images from this store when creating new sandboxes. The store uses S3-compatible object storage as its backend.\n\n#### Volumes\n\n[Volumes](/docs/en/volumes) provide persistent storage that can be shared across sandboxes. Each volume is backed by S3-compatible object storage and mounted into sandboxes as a read-write directory. Multiple sandboxes can mount the same volume simultaneously, allowing data to be shared across sandboxes and persist independently of the sandbox lifecycle.\n\n### Container registry\n\nContainer registries serve as the source for sandbox base images. When creating a [snapshot](/docs/en/snapshots), the snapshot builder pulls the specified image from an external registry, and pushes it to the internal snapshot registry for use by runners. For Dockerfile-based snapshots, parent images referenced in `FROM` directives are also pulled from the configured source registries during the build. Daytona supports any OCI-compatible registry:\n\n- [Docker Hub](/docs/en/snapshots#docker-hub)\n- [Google Artifact Registry](/docs/en/snapshots#google-artifact-registry)\n- [GitHub Container Registry (GHCR)](/docs/en/snapshots#github-container-registry-ghcr)\n- [Private registries](/docs/en/snapshots#using-images-from-private-registries): any registry that implements the OCI distribution specification\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/audit-logs.mdx",
    "content": "---\ntitle: Audit Logs\ndescription: View and monitor all user actions across your Daytona organization.\n---\n\nDaytona audit logs provide a detailed record of user and system activity across your organization. Use this feature to track sandbox lifecycle events, user access, system changes, and more.\n\n- **Security audits**: monitor for unauthorized access or sandbox misuse\n- **Debugging**: understand sandbox lifecycle issues (e.g. failed starts)\n- **Compliance Export**: export logs for internal or external audits (coming soon)\n\nAudit logs are available to [admins](/docs/en/organizations#organization-roles) with full access and [members](/docs/en/organizations#organization-roles) with audit log permissions. Contact your organization administrator if you cannot access audit logs.\n\n## Access from Dashboard\n\nAccess the audit logs page directly from [Daytona Dashboard ↗](https://app.daytona.io/dashboard/audit-logs). The audit logs page displays a list of all audit logs for your organization, including the following columns:\n\n- **Time**: the timestamp of the action\n- **User**: the user who performed the action\n- [Actions](#actions): the action performed\n- [Targets](#targets): the resource affected by the action\n- [Outcomes](#outcomes): the result of the action\n\nTo filter audit logs by time, use the date range picker in the top-left corner of the page.\n\n## Real-time updates\n\nDaytona provides real-time updates of audit logs. Enable the **Auto Refresh** toggle in the top-right corner of the [Daytona Audit Logs ↗](https://app.daytona.io/dashboard/audit-logs) page to automatically refresh logs as new events occur.\n\n## Programmatic management\n\nDaytona provides API endpoints for programmatic access to audit logs.\n\n### Get all audit logs\n\nTo get all audit logs, use the following API endpoint:\n\n```bash\ncurl https://app.daytona.io/api/audit \\\n  --header 'Authorization: Bearer YOUR_API_KEY'\n```\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/audit) reference:\n\n> [**Get all audit logs (API)**](/docs/en/tools/api/#daytona/tag/audit/GET/audit-logs)\n\n### Get audit logs for organization\n\nTo get audit logs for a specific organization, use the following API endpoint:\n\n```bash\ncurl https://app.daytona.io/api/audit/organizations/{organizationId} \\\n  --header 'Authorization: Bearer YOUR_API_KEY'\n```\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/audit) reference:\n\n> [**Get audit logs for organization (API)**](/docs/en/tools/api/#daytona/tag/audit/GET/audit/organizations/{organizationId})\n\n## Log Structure\n\nEach audit log entry contains the following fields:\n\n| Field                | Type   | Description                                          |\n| -------------------- | ------ | ---------------------------------------------------- |\n| **`id`**             | string | Unique log entry identifier                          |\n| **`actorId`**        | string | ID of the user who performed the action              |\n| **`actorEmail`**     | string | Email of the user who performed the action           |\n| **`organizationId`** | string | Organization ID                                      |\n| **`action`**         | string | Operation executed (e.g., `create`, `start`, `stop`) |\n| **`targetType`**     | string | Resource type affected (e.g., `sandbox`, `snapshot`) |\n| **`targetId`**       | string | ID of the affected resource                          |\n| **`statusCode`**     | number | HTTP status code of the result                       |\n| **`errorMessage`**   | string | Error message if the action failed                   |\n| **`ipAddress`**      | string | IP address of the request origin                     |\n| **`userAgent`**      | string | User agent of the request origin                     |\n| **`source`**         | string | Source of the action                                 |\n| **`metadata`**       | object | Additional context about the action                  |\n| **`createdAt`**      | string | ISO 8601 timestamp of when the action occurred       |\n\n## Actions\n\nBelow is the complete list of actions logged by Daytona:\n\n```text\ncreate, read, update, delete, login,\nset_default, update_access, update_quota, update_region_quota,\nsuspend, unsuspend, accept, decline,\nlink_account, unlink_account, leave_organization,\nregenerate_key_pair, update_scheduling,\nstart, stop, replace_labels, create_backup,\nupdate_public_status, set_auto_stop_interval,\nset_auto_archive_interval, set_auto_delete_interval, archive,\nget_port_preview_url, set_general_status, activate, deactivate,\nupdate_network_settings,\nsend_webhook_message, initialize_webhooks,\nupdate_sandbox_default_limited_network_egress,\ncreate_ssh_access, revoke_ssh_access,\nregenerate_proxy_api_key,regenerate_ssh_gateway_api_key,regenerate_snapshot_manager_credentials,\ntoolbox_delete_file, toolbox_download_file, toolbox_create_folder,\ntoolbox_move_file, toolbox_set_file_permissions, toolbox_replace_in_files,\ntoolbox_upload_file, toolbox_bulk_upload_files,\ntoolbox_git_add_files, toolbox_git_create_branch, toolbox_git_delete_branch,\ntoolbox_git_clone_repository, toolbox_git_commit_changes,\ntoolbox_git_pull_changes, toolbox_git_push_changes,\ntoolbox_git_checkout_branch, toolbox_execute_command,\ntoolbox_create_session, toolbox_session_execute_command,\ntoolbox_delete_session, toolbox_computer_use_start,\ntoolbox_computer_use_stop, toolbox_computer_use_restart_process\n```\n\n## Targets\n\nEach action targets a specific resource type. Possible targets include:\n\n```text\napi_key, organization, organization_invitation,\norganization_role, organization_user, docker_registry,\nrunner, sandbox, snapshot, user, volume\n```\n\n## Outcomes\n\nThe outcome field indicates the result of the action. Statuses follow standard HTTP semantics:\n\n| **Outcome** | **Description**               |\n| ----------- | ----------------------------- |\n| Info        | Informational (1xx codes)     |\n| Success     | Action succeeded (2xx codes)  |\n| Redirect    | Redirects (3xx codes)         |\n| Error       | Client/server error (4xx/5xx) |\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/billing.mdx",
    "content": "---\ntitle: Billing\n---\n\n[Daytona Billing ↗](https://app.daytona.io/dashboard/billing/spending) provides an overview of your organization's billing, wallet, and usage details.\n\nDaytona displays a cost breakdown chart that shows a breakdown of costs per resource. You can choose between area and bar charts and filter by RAM, CPU, and storage. You can also filter by date range (last 12, 6, or 3 months).\n\n## Wallet\n\n[Daytona Wallet ↗](https://app.daytona.io/dashboard/billing/wallet) shows the current balance of the organization's wallet and the amount of credits spent this month.\n\n### Add payment method\n\nDaytona provides a payment method to add to your wallet. You can connect your credit card to your wallet to top up your balance.\n\n1. Navigate to [Daytona Wallet ↗](https://app.daytona.io/dashboard/billing/wallet)\n2. Click the **Connect** button next to the **Payment method** section\n3. Follow the prompts to connect your credit card to your wallet.\n\nOrganizations can set automatic top-up rules for their wallets.\n\n- **Threshold** — When the wallet balance drops to this amount, a top-up is triggered.  \n- **Target** — The wallet balance is topped up to this amount.\n\nSet both **Threshold** and **Target** to `0` to disable automatic top-up.\n\n### Redeem coupon\n\nDaytona provides coupon codes to redeem credits on your wallet.\n\n1. Navigate to [Daytona Wallet ↗](https://app.daytona.io/dashboard/billing/wallet)\n2. Enter the coupon code in the **Redeem coupon** input field\n3. Click the **Redeem** button to redeem the coupon code.\n\n### Billing emails\n\nDaytona provides billing emails to receive important billing notifications such as invoices and credit depletion notices.\n\n1. Navigate to [Daytona Wallet ↗](https://app.daytona.io/dashboard/billing/wallet)\n2. Click the **Add Email** button to add a new email address.\n3. Enter the email address and click the **Add Email** button.\n\nA verification email will be sent to the email address to verify it. Once verified, the email address will be added to the list of billing emails.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/computer-use.mdx",
    "content": "---\ntitle: Computer Use\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nComputer Use enables programmatic control of desktop environments within sandboxes. It provides mouse, keyboard, screenshot, screen recording, and display operations for automating GUI interactions and testing desktop applications.\n\nComputer Use and [VNC](/docs/en/vnc-access) work together to enable both manual and automated desktop interactions. VNC provides the visual interface for users to manually interact with the desktop, while Computer Use provides the programmatic API for AI agents to automate operations.\n\nComputer Use is available for **Linux**. **Windows** and **macOS** support is currently in private alpha.\n\n:::caution[Private Alpha]\nComputer Use for macOS and Windows is currently in private alpha and requires access. To request access, fill out the [Windows](https://docs.google.com/forms/d/e/1FAIpQLSfoK-77-VpfsMubw8F4f1opCxIL1AyJUgnM0ONYup5hZ0RTvQ/viewform?usp=dialog) or [macOS](https://docs.google.com/forms/d/e/1FAIpQLSc9xlGZ49OjWNkyzDPC9Ip3InMRR0ZXY3tcoD-PFQj3ck6gzQ/viewform?usp=sharing&ouid=103304973264148733944) access request form. Our team will review your request and reach out with setup instructions.\n:::\n\n- **GUI application testing**: automate interactions with native applications, click buttons, fill forms, and validate UI behavior\n- **Visual testing & screenshots**: capture screenshots of applications, compare UI states, and perform visual regression testing\n- **Desktop automation**: automate repetitive desktop tasks, file management through GUI, and complex workflows\n\n## Start Computer Use\n\nStart all computer use processes (Xvfb, xfce4, x11vnc, novnc) in the Sandbox.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresult = sandbox.computer_use.start()\nprint(\"Computer use processes started:\", result.message)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst result = await sandbox.computerUse.start();\nconsole.log('Computer use processes started:', result.message);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresult = sandbox.computer_use.start\nputs \"Computer use processes started: #{result.message}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nerr := sandbox.ComputerUse.Start(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer sandbox.ComputerUse.Stop(ctx)\n\nfmt.Println(\"Computer use processes started\")\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/start' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**start (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computerusestart)\n>\n> [**start (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#start)\n>\n> [**start (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#start)\n>\n> [**Start Computer Use Processes (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/start)\n\n## Stop Computer Use\n\nStop all computer use processes in the Sandbox.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresult = sandbox.computer_use.stop()\nprint(\"Computer use processes stopped:\", result.message)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst result = await sandbox.computerUse.stop();\nconsole.log('Computer use processes stopped:', result.message);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresult = sandbox.computer_use.stop\nputs \"Computer use processes stopped: #{result.message}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nerr := sandbox.ComputerUse.Stop(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Println(\"Computer use processes stopped\")\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/stop' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**stop (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computerusestop)\n>\n> [**stop (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#stop)\n>\n> [**stop (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#stop)\n>\n> [**Stop Computer Use Processes (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/stop)\n\n## Get status\n\nGet the status of all computer use processes.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresponse = sandbox.computer_use.get_status()\nprint(\"Computer use status:\", response.status)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst status = await sandbox.computerUse.getStatus();\nconsole.log('Computer use status:', status.status);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresponse = sandbox.computer_use.status\nputs \"Computer use status: #{response.status}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nstatus, err := sandbox.ComputerUse.GetStatus(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Computer use status: %v\\n\", status[\"status\"])\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/status'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**get_status (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computeruseget_status)\n>\n> [**getStatus (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#getstatus)\n>\n> [**status (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#status)\n>\n> [**Get Computer Use status (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/status)\n\n## Get process status\n\nGet the status of a specific VNC process.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nxvfb_status = sandbox.computer_use.get_process_status(\"xvfb\")\nnovnc_status = sandbox.computer_use.get_process_status(\"novnc\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst xvfbStatus = await sandbox.computerUse.getProcessStatus('xvfb');\nconst noVncStatus = await sandbox.computerUse.getProcessStatus('novnc');\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nxvfb_status = sandbox.computer_use.get_process_status(\"xvfb\")\nno_vnc_status = sandbox.computer_use.get_process_status(\"novnc\")\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/status'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**get_process_status (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computeruseget_process_status)\n>\n> [**getProcessStatus (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#getprocessstatus)\n>\n> [**get_process_status (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#get_process_status)\n>\n> [**Get Process Status (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/process/{processName}/status)\n\n## Restart process\n\nRestart a specific VNC process.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresult = sandbox.computer_use.restart_process(\"xfce4\")\nprint(\"XFCE4 process restarted:\", result.message)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst result = await sandbox.computerUse.restartProcess('xfce4');\nconsole.log('XFCE4 process restarted:', result.message);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresult = sandbox.computer_use.restart_process(\"xfce4\")\nputs \"XFCE4 process restarted: #{result.message}\"\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/restart' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**restart_process (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computeruserestart_process)\n>\n> [**restartProcess (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#restartprocess)\n>\n> [**restart_process (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#restart_process)\n>\n> [**Restart process (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/process/{processName}/restart)\n\n## Get process logs\n\nGet logs for a specific VNC process.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nlogs = sandbox.computer_use.get_process_logs(\"novnc\")\nprint(\"NoVNC logs:\", logs)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst logsResp = await sandbox.computerUse.getProcessLogs('novnc');\nconsole.log('NoVNC logs:', logsResp.logs);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nlogs = sandbox.computer_use.get_process_logs(\"novnc\")\nputs \"NoVNC logs: #{logs}\"\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/logs'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**get_process_logs (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computeruseget_process_logs)\n>\n> [**getProcessLogs (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#getprocesslogs)\n>\n> [**get_process_logs (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#get_process_logs)\n>\n> [**Get process logs (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/process/{processName}/logs)\n\n## Get process errors\n\nGet error logs for a specific VNC process.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nerrors = sandbox.computer_use.get_process_errors(\"x11vnc\")\nprint(\"X11VNC errors:\", errors)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst errorsResp = await sandbox.computerUse.getProcessErrors('x11vnc');\nconsole.log('X11VNC errors:', errorsResp.errors);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nerrors = sandbox.computer_use.get_process_errors(\"x11vnc\")\nputs \"X11VNC errors: #{errors}\"\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/process/{processName}/errors'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**get_process_errors (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computeruseget_process_errors)\n>\n> [**getProcessErrors (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#getprocesserrors)\n>\n> [**get_process_errors (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#get_process_errors)\n>\n> [**Get process errors (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/process/{processName}/errors)\n\n## Mouse operations\n\n### Click\n\nClick the mouse at the specified coordinates.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Single left click\nresult = sandbox.computer_use.mouse.click(100, 200)\n\n# Double click\ndouble_click = sandbox.computer_use.mouse.click(100, 200, \"left\", True)\n\n# Right click\nright_click = sandbox.computer_use.mouse.click(100, 200, \"right\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Single left click\nconst result = await sandbox.computerUse.mouse.click(100, 200);\n\n// Double click\nconst doubleClick = await sandbox.computerUse.mouse.click(100, 200, 'left', true);\n\n// Right click\nconst rightClick = await sandbox.computerUse.mouse.click(100, 200, 'right');\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Single left click\nresult = sandbox.computer_use.mouse.click(x: 100, y: 200)\n\n# Double click\ndouble_click = sandbox.computer_use.mouse.click(x: 100, y: 200, button: 'left', double: true)\n\n# Right click\nright_click = sandbox.computer_use.mouse.click(x: 100, y: 200, button: 'right')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Single left click\nresult, err := sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, nil, nil)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Double click\ndoubleClick := true\nresult, err = sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, nil, &doubleClick)\n\n// Right click\nrightButton := \"right\"\nresult, err = sandbox.ComputerUse.Mouse().Click(ctx, 100, 200, &rightButton, nil)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/click' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"button\": \"\",\n  \"double\": true,\n  \"x\": 1,\n  \"y\": 1\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**click (Python SDK)**](/docs/en/python-sdk/sync/computer-use#mouseclick)\n>\n> [**click (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#click)\n>\n> [**Click (Go SDK)**](/docs/en/go-sdk/daytona/#MouseService.Click)\n>\n> [**Mouse click (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/mouse/click)\n\n### Move\n\nMove the mouse cursor to the specified coordinates.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresult = sandbox.computer_use.mouse.move(100, 200)\nprint(f\"Mouse moved to: {result.x}, {result.y}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst result = await sandbox.computerUse.mouse.move(100, 200);\nconsole.log(`Mouse moved to: ${result.x}, ${result.y}`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresult = sandbox.computer_use.mouse.move(x: 100, y: 200)\nputs \"Mouse moved to: #{result.x}, #{result.y}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nresult, err := sandbox.ComputerUse.Mouse().Move(ctx, 100, 200)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Mouse moved to: %v, %v\\n\", result[\"x\"], result[\"y\"])\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/move' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"x\": 1,\n  \"y\": 1\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**move (Python SDK)**](/docs/en/python-sdk/sync/computer-use#mousemove)\n>\n> [**move (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#move)\n>\n> [**Move (Go SDK)**](/docs/en/go-sdk/daytona/#MouseService.Move)\n>\n> [**Mouse move (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/mouse/move)\n\n### Drag\n\nDrag the mouse from start coordinates to end coordinates.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresult = sandbox.computer_use.mouse.drag(50, 50, 150, 150)\nprint(f\"Dragged from {result.from_x},{result.from_y} to {result.to_x},{result.to_y}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst result = await sandbox.computerUse.mouse.drag(50, 50, 150, 150);\nconsole.log(`Dragged from ${result.from.x},${result.from.y} to ${result.to.x},${result.to.y}`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresult = sandbox.computer_use.mouse.drag(start_x: 50, start_y: 50, end_x: 150, end_y: 150)\nputs \"Dragged from #{result.from_x},#{result.from_y} to #{result.to_x},#{result.to_y}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nresult, err := sandbox.ComputerUse.Mouse().Drag(ctx, 50, 50, 150, 150, nil)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Dragged to %v, %v\\n\", result[\"x\"], result[\"y\"])\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/drag' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"button\": \"\",\n  \"endX\": 1,\n  \"endY\": 1,\n  \"startX\": 1,\n  \"startY\": 1\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**drag (Python SDK)**](/docs/en/python-sdk/sync/computer-use#mousedrag)\n>\n> [**drag (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#drag)\n>\n> [**Drag (Go SDK)**](/docs/en/go-sdk/daytona/#MouseService.Drag)\n>\n> [**Mouse drag (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/mouse/drag)\n\n### Scroll\n\nScroll the mouse wheel at the specified coordinates.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Scroll up\nscroll_up = sandbox.computer_use.mouse.scroll(100, 200, \"up\", 3)\n\n# Scroll down\nscroll_down = sandbox.computer_use.mouse.scroll(100, 200, \"down\", 5)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Scroll up\nconst scrollUp = await sandbox.computerUse.mouse.scroll(100, 200, 'up', 3);\n\n// Scroll down\nconst scrollDown = await sandbox.computerUse.mouse.scroll(100, 200, 'down', 5);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Scroll up\nscroll_up = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'up', amount: 3)\n\n# Scroll down\nscroll_down = sandbox.computer_use.mouse.scroll(x: 100, y: 200, direction: 'down', amount: 5)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Scroll up\namount := 3\nsuccess, err := sandbox.ComputerUse.Mouse().Scroll(ctx, 100, 200, \"up\", &amount)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Scroll down\namount = 5\nsuccess, err = sandbox.ComputerUse.Mouse().Scroll(ctx, 100, 200, \"down\", &amount)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/scroll' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"amount\": 1,\n  \"direction\": \"\",\n  \"x\": 1,\n  \"y\": 1\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**scroll (Python SDK)**](/docs/en/python-sdk/sync/computer-use#mousescroll)\n>\n> [**scroll (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#scroll)\n>\n> [**Scroll (Go SDK)**](/docs/en/go-sdk/daytona/#MouseService.Scroll)\n>\n> [**Mouse scroll (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/mouse/scroll)\n\n### Get position\n\nGet the current mouse cursor position.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nposition = sandbox.computer_use.mouse.get_position()\nprint(f\"Mouse is at: {position.x}, {position.y}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst position = await sandbox.computerUse.mouse.getPosition();\nconsole.log(`Mouse is at: ${position.x}, ${position.y}`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nposition = sandbox.computer_use.mouse.position\nputs \"Mouse is at: #{position.x}, #{position.y}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nposition, err := sandbox.ComputerUse.Mouse().GetPosition(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Mouse is at: %v, %v\\n\", position[\"x\"], position[\"y\"])\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/mouse/position'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**get_position (Python SDK)**](/docs/en/python-sdk/sync/computer-use#mouseget_position)\n>\n> [**getPosition (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#getposition)\n>\n> [**GetPosition (Go SDK)**](/docs/en/go-sdk/daytona/#MouseService.GetPosition)\n>\n> [**Get mouse position (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/mouse/position)\n\n## Keyboard operations\n\n### Type\n\nType the specified text.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox.computer_use.keyboard.type(\"Hello, World!\")\n\n# With delay between characters\nsandbox.computer_use.keyboard.type(\"Slow typing\", 100)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nawait sandbox.computerUse.keyboard.type('Hello, World!');\n\n// With delay between characters\nawait sandbox.computerUse.keyboard.type('Slow typing', 100);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsandbox.computer_use.keyboard.type(text: \"Hello, World!\")\n\n# With delay between characters\nsandbox.computer_use.keyboard.type(text: \"Slow typing\", delay: 100)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nerr := sandbox.ComputerUse.Keyboard().Type(ctx, \"Hello, World!\", nil)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// With delay between characters\ndelay := 100\nerr = sandbox.ComputerUse.Keyboard().Type(ctx, \"Slow typing\", &delay)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/keyboard/type' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"delay\": 1,\n  \"text\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**type (Python SDK)**](/docs/en/python-sdk/sync/computer-use#keyboardtype)\n>\n> [**type (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#type)\n>\n> [**Type (Go SDK)**](/docs/en/go-sdk/daytona/#KeyboardService.Type)\n>\n> [**Keyboard type (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/keyboard/type)\n\n### Press\n\nPress a key with optional modifiers.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Press Enter\nsandbox.computer_use.keyboard.press(\"Return\")\n\n# Press Ctrl+C\nsandbox.computer_use.keyboard.press(\"c\", [\"ctrl\"])\n\n# Press Ctrl+Shift+T\nsandbox.computer_use.keyboard.press(\"t\", [\"ctrl\", \"shift\"])\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Press Enter\nawait sandbox.computerUse.keyboard.press('Return');\n\n// Press Ctrl+C\nawait sandbox.computerUse.keyboard.press('c', ['ctrl']);\n\n// Press Ctrl+Shift+T\nawait sandbox.computerUse.keyboard.press('t', ['ctrl', 'shift']);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Press Enter\nsandbox.computer_use.keyboard.press(key: \"Return\")\n\n# Press Ctrl+C\nsandbox.computer_use.keyboard.press(key: \"c\", modifiers: [\"ctrl\"])\n\n# Press Ctrl+Shift+T\nsandbox.computer_use.keyboard.press(key: \"t\", modifiers: [\"ctrl\", \"shift\"])\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Press Enter\nerr := sandbox.ComputerUse.Keyboard().Press(ctx, \"Return\", nil)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Press Ctrl+C\nerr = sandbox.ComputerUse.Keyboard().Press(ctx, \"c\", []string{\"ctrl\"})\n\n// Press Ctrl+Shift+T\nerr = sandbox.ComputerUse.Keyboard().Press(ctx, \"t\", []string{\"ctrl\", \"shift\"})\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/keyboard/key' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"key\": \"\",\n  \"modifiers\": [\n    \"\"\n  ]\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**press (Python SDK)**](/docs/en/python-sdk/sync/computer-use#keyboardpress)\n>\n> [**press (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#press)\n>\n> [**Press (Go SDK)**](/docs/en/go-sdk/daytona/#KeyboardService.Press)\n>\n> [**Keyboard press (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/keyboard/press)\n\n### Hotkey\n\nPress a hotkey combination.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Copy\nsandbox.computer_use.keyboard.hotkey(\"ctrl+c\")\n\n# Paste\nsandbox.computer_use.keyboard.hotkey(\"ctrl+v\")\n\n# Alt+Tab\nsandbox.computer_use.keyboard.hotkey(\"alt+tab\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Copy\nawait sandbox.computerUse.keyboard.hotkey('ctrl+c');\n\n// Paste\nawait sandbox.computerUse.keyboard.hotkey('ctrl+v');\n\n// Alt+Tab\nawait sandbox.computerUse.keyboard.hotkey('alt+tab');\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Copy\nsandbox.computer_use.keyboard.hotkey(keys: \"ctrl+c\")\n\n# Paste\nsandbox.computer_use.keyboard.hotkey(keys: \"ctrl+v\")\n\n# Alt+Tab\nsandbox.computer_use.keyboard.hotkey(keys: \"alt+tab\")\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Copy\nerr := sandbox.ComputerUse.Keyboard().Hotkey(ctx, \"ctrl+c\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Paste\nerr = sandbox.ComputerUse.Keyboard().Hotkey(ctx, \"ctrl+v\")\n\n// Alt+Tab\nerr = sandbox.ComputerUse.Keyboard().Hotkey(ctx, \"alt+tab\")\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/keyboard/hotkey' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"keys\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**hotkey (Python SDK)**](/docs/en/python-sdk/sync/computer-use#keyboardhotkey)\n>\n> [**hotkey (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#hotkey)\n>\n> [**Hotkey (Go SDK)**](/docs/en/go-sdk/daytona/#KeyboardService.Hotkey)\n>\n> [**Keyboard hotkey (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/keyboard/hotkey)\n\n## Screenshot operations\n\n### Take full screen\n\nTake a screenshot of the entire screen.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nscreenshot = sandbox.computer_use.screenshot.take_full_screen()\nprint(f\"Screenshot size: {screenshot.width}x{screenshot.height}\")\n\n# With cursor visible\nwith_cursor = sandbox.computer_use.screenshot.take_full_screen(True)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst screenshot = await sandbox.computerUse.screenshot.takeFullScreen();\nconsole.log(`Screenshot size: ${screenshot.width}x${screenshot.height}`);\n\n// With cursor visible\nconst withCursor = await sandbox.computerUse.screenshot.takeFullScreen(true);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nscreenshot = sandbox.computer_use.screenshot.take_full_screen\nputs \"Screenshot size: #{screenshot.width}x#{screenshot.height}\"\n\n# With cursor visible\nwith_cursor = sandbox.computer_use.screenshot.take_full_screen(show_cursor: true)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nscreenshot, err := sandbox.ComputerUse.Screenshot().TakeFullScreen(ctx, nil)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Screenshot captured, size: %d bytes\\n\", *screenshot.SizeBytes)\n\n// With cursor visible\nshowCursor := true\nwithCursor, err := sandbox.ComputerUse.Screenshot().TakeFullScreen(ctx, &showCursor)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/screenshot'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**take_full_screen (Python SDK)**](/docs/en/python-sdk/sync/computer-use#screenshottake_full_screen)\n>\n> [**takeFullScreen (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#takefullscreen)\n>\n> [**TakeFullScreen (Go SDK)**](/docs/en/go-sdk/daytona/#ScreenshotService.TakeFullScreen)\n>\n> [**Take screenshot (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/screenshot)\n\n### Take region\n\nTake a screenshot of a specific region.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import ScreenshotRegion\n\nregion = ScreenshotRegion(x=100, y=100, width=300, height=200)\nscreenshot = sandbox.computer_use.screenshot.take_region(region)\nprint(f\"Captured region: {screenshot.region.width}x{screenshot.region.height}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst region = { x: 100, y: 100, width: 300, height: 200 };\nconst screenshot = await sandbox.computerUse.screenshot.takeRegion(region);\nconsole.log(`Captured region: ${screenshot.region.width}x${screenshot.region.height}`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nregion = Daytona::ComputerUse::ScreenshotRegion.new(x: 100, y: 100, width: 300, height: 200)\nscreenshot = sandbox.computer_use.screenshot.take_region(region: region)\nputs \"Captured region: #{screenshot.region.width}x#{screenshot.region.height}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nregion := types.ScreenshotRegion{X: 100, Y: 100, Width: 300, Height: 200}\nscreenshot, err := sandbox.ComputerUse.Screenshot().TakeRegion(ctx, region, nil)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Captured region: %dx%d\\n\", screenshot.Width, screenshot.Height)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/screenshot/region?x=1&y=1&width=1&height=1'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**take_region (Python SDK)**](/docs/en/python-sdk/sync/computer-use#screenshottake_region)\n>\n> [**takeRegion (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#takeregion)\n>\n> [**TakeRegion (Go SDK)**](/docs/en/go-sdk/daytona/#ScreenshotService.TakeRegion)\n>\n> [**Take Screenshot Region (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/screenshot/region)\n\n### Take compressed\n\nTake a compressed screenshot of the entire screen.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import ScreenshotOptions\n\n# Default compression\nscreenshot = sandbox.computer_use.screenshot.take_compressed()\n\n# High quality JPEG\njpeg = sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"jpeg\", quality=95, show_cursor=True)\n)\n\n# Scaled down PNG\nscaled = sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"png\", scale=0.5)\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Default compression\nconst screenshot = await sandbox.computerUse.screenshot.takeCompressed();\n\n// High quality JPEG\nconst jpeg = await sandbox.computerUse.screenshot.takeCompressed({\n  format: 'jpeg',\n  quality: 95,\n  showCursor: true\n});\n\n// Scaled down PNG\nconst scaled = await sandbox.computerUse.screenshot.takeCompressed({\n  format: 'png',\n  scale: 0.5\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Default compression\nscreenshot = sandbox.computer_use.screenshot.take_compressed\n\n# High quality JPEG\njpeg = sandbox.computer_use.screenshot.take_compressed(\n  options: Daytona::ComputerUse::ScreenshotOptions.new(format: \"jpeg\", quality: 95, show_cursor: true)\n)\n\n# Scaled down PNG\nscaled = sandbox.computer_use.screenshot.take_compressed(\n  options: Daytona::ComputerUse::ScreenshotOptions.new(format: \"png\", scale: 0.5)\n)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/screenshot/compressed'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**take_compressed (Python SDK)**](/docs/en/python-sdk/sync/computer-use#screenshottake_compressed)\n>\n> [**takeCompressed (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#takecompressed)\n>\n> [**Take compressed screenshot (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/screenshot/compressed)\n\n### Take compressed region\n\nTake a compressed screenshot of a specific region.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import ScreenshotRegion, ScreenshotOptions\n\nregion = ScreenshotRegion(x=0, y=0, width=800, height=600)\nscreenshot = sandbox.computer_use.screenshot.take_compressed_region(\n    region,\n    ScreenshotOptions(format=\"webp\", quality=80, show_cursor=True)\n)\nprint(f\"Compressed size: {screenshot.size_bytes} bytes\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst region = { x: 0, y: 0, width: 800, height: 600 };\nconst screenshot = await sandbox.computerUse.screenshot.takeCompressedRegion(region, {\n  format: 'webp',\n  quality: 80,\n  showCursor: true\n});\nconsole.log(`Compressed size: ${screenshot.size_bytes} bytes`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nregion = Daytona::ComputerUse::ScreenshotRegion.new(x: 0, y: 0, width: 800, height: 600)\nscreenshot = sandbox.computer_use.screenshot.take_compressed_region(\n  region: region,\n  options: Daytona::ComputerUse::ScreenshotOptions.new(format: \"webp\", quality: 80, show_cursor: true)\n)\nputs \"Compressed size: #{screenshot.size_bytes} bytes\"\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/screenshot/region/compressed?x=1&y=1&width=1&height=1'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**take_compressed_region (Python SDK)**](/docs/en/python-sdk/sync/computer-use#screenshottake_compressed_region)\n>\n> [**takeCompressedRegion (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#takecompressedregion)\n>\n> [**Take compressed screenshot region (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/screenshot/region/compressed)\n\n## Screen Recording\n\nComputer Use supports screen recording capabilities, allowing you to capture desktop sessions for debugging, documentation, or automation workflows.\n\n### Configure Recording Directory\n\nBy default, recordings are saved to `~/.daytona/recordings`. You can specify a custom directory by passing the `DAYTONA_RECORDINGS_DIR` environment variable when creating a sandbox:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, CreateSandboxFromSnapshotParams\n\ndaytona = Daytona()\nsandbox = daytona.create(\n    CreateSandboxFromSnapshotParams(\n        snapshot=\"daytonaio/sandbox:0.6.0\",\n        name=\"my-sandbox\",\n        env_vars={\"DAYTONA_RECORDINGS_DIR\": \"/home/daytona/my-recordings\"}\n    )\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst sandbox = await daytona.create({\n  snapshot: 'daytonaio/sandbox:0.6.0',\n  name: 'my-sandbox',\n  envVars: { DAYTONA_RECORDINGS_DIR: '/home/daytona/my-recordings' }\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Client.new\nsandbox = daytona.create(\n  snapshot: 'daytonaio/sandbox:0.6.0',\n  name: 'my-sandbox',\n  env_vars: { DAYTONA_RECORDINGS_DIR: '/home/daytona/my-recordings' }\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nimport (\n\t\"github.com/daytonaio/daytona/pkg/client\"\n\t\"github.com/daytonaio/daytona/pkg/types\"\n)\n\ndaytona := client.New()\nenvVars := map[string]string{\n\t\"DAYTONA_RECORDINGS_DIR\": \"/home/daytona/my-recordings\",\n}\n\nsandbox, err := daytona.Create(ctx, &types.CreateSandboxParams{\n\tSnapshot: \"daytonaio/sandbox:0.6.0\",\n\tName:     \"my-sandbox\",\n\tEnvVars:  envVars,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n</Tabs>\n\n### Start Recording\n\nStart a new screen recording session with an optional name identifier:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Start recording with a custom name\nrecording = sandbox.computer_use.recording.start(\"test-1\")\nprint(f\"Recording started: {recording.id}\")\nprint(f\"File path: {recording.file_path}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Start recording with a custom name\nconst recording = await sandbox.computerUse.recording.start('test-1');\nconsole.log(`Recording started: ${recording.id}`);\nconsole.log(`File path: ${recording.file_path}`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Start recording with a custom label\nrecording = sandbox.computer_use.recording.start(label: 'test-1')\nputs \"Recording started: #{recording.id}\"\nputs \"File path: #{recording.file_path}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Start recording with a custom name\nname := \"test-1\"\nrecording, err := sandbox.ComputerUse.Recording().Start(ctx, &name)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Recording started: %s\\n\", *recording.Id)\nfmt.Printf(\"File path: %s\\n\", *recording.FilePath)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/start' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"name\": \"test-1\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**start (Python SDK)**](/docs/en/python-sdk/sync/computer-use#recordingstart)\n>\n> [**start (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#start-1)\n>\n> [**start (Ruby SDK)**](/docs/en/ruby-sdk/computer-use)\n>\n> [**Start (Go SDK)**](/docs/en/go-sdk/daytona/#RecordingService.Start)\n>\n> [**Start Recording (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/recordings/start)\n\n### Stop Recording\n\nStop an active recording session by providing the recording ID:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Stop the recording\nstopped_recording = sandbox.computer_use.recording.stop(recording.id)\nprint(f\"Recording stopped: {stopped_recording.duration_seconds} seconds\")\nprint(f\"Saved to: {stopped_recording.file_path}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Stop the recording\nconst stoppedRecording = await sandbox.computerUse.recording.stop(recording.id);\nconsole.log(`Recording stopped: ${stoppedRecording.duration_seconds} seconds`);\nconsole.log(`Saved to: ${stoppedRecording.file_path}`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Stop the recording\nstopped_recording = sandbox.computer_use.recording.stop(id: recording.id)\nputs \"Recording stopped: #{stopped_recording.duration_seconds} seconds\"\nputs \"Saved to: #{stopped_recording.file_path}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Stop the recording\nstoppedRecording, err := sandbox.ComputerUse.Recording().Stop(ctx, *recording.Id)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Recording stopped: %f seconds\\n\", *stoppedRecording.DurationSeconds)\nfmt.Printf(\"Saved to: %s\\n\", *stoppedRecording.FilePath)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/stop' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"id\": \"recording-id\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**stop (Python SDK)**](/docs/en/python-sdk/sync/computer-use#recordingstop)\n>\n> [**stop (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#stop-1)\n>\n> [**stop (Ruby SDK)**](/docs/en/ruby-sdk/computer-use)\n>\n> [**Stop (Go SDK)**](/docs/en/go-sdk/daytona/#RecordingService.Stop)\n>\n> [**Stop Recording (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/recordings/stop)\n\n### List Recordings\n\nGet a list of all recordings in the sandbox:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nrecordings_list = sandbox.computer_use.recording.list()\nprint(f\"Total recordings: {len(recordings_list.recordings)}\")\nfor rec in recordings_list.recordings:\n    print(f\"- {rec.name}: {rec.duration_seconds}s ({rec.file_size_bytes} bytes)\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst recordingsList = await sandbox.computerUse.recording.list();\nconsole.log(`Total recordings: ${recordingsList.recordings.length}`);\nrecordingsList.recordings.forEach(rec => {\n  console.log(`- ${rec.name}: ${rec.duration_seconds}s (${rec.file_size_bytes} bytes)`);\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrecordings_list = sandbox.computer_use.recording.list\nputs \"Total recordings: #{recordings_list.recordings.length}\"\nrecordings_list.recordings.each do |rec|\n  puts \"- #{rec.name}: #{rec.duration_seconds}s (#{rec.file_size_bytes} bytes)\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nrecordingsList, err := sandbox.ComputerUse.Recording().List(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Total recordings: %d\\n\", len(recordingsList.Recordings))\nfor _, rec := range recordingsList.Recordings {\n\tfmt.Printf(\"- %s: %.2fs (%d bytes)\\n\", *rec.Name, *rec.DurationSeconds, *rec.FileSizeBytes)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**list (Python SDK)**](/docs/en/python-sdk/sync/computer-use#recordinglist)\n>\n> [**list (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#list)\n>\n> [**list (Ruby SDK)**](/docs/en/ruby-sdk/computer-use)\n>\n> [**List (Go SDK)**](/docs/en/go-sdk/daytona/#RecordingService.List)\n>\n> [**List Recordings (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/recordings)\n\n### Get Recording\n\nGet details about a specific recording:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nrecording_detail = sandbox.computer_use.recording.get(\"recording-id\")\nprint(f\"Recording: {recording_detail.name}\")\nprint(f\"Status: {recording_detail.status}\")\nprint(f\"Duration: {recording_detail.duration_seconds}s\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst recordingDetail = await sandbox.computerUse.recording.get('recording-id');\nconsole.log(`Recording: ${recordingDetail.name}`);\nconsole.log(`Status: ${recordingDetail.status}`);\nconsole.log(`Duration: ${recordingDetail.duration_seconds}s`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrecording_detail = sandbox.computer_use.recording.get(id: 'recording-id')\nputs \"Recording: #{recording_detail.name}\"\nputs \"Status: #{recording_detail.status}\"\nputs \"Duration: #{recording_detail.duration_seconds}s\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nrecordingDetail, err := sandbox.ComputerUse.Recording().Get(ctx, \"recording-id\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Recording: %s\\n\", *recordingDetail.Name)\nfmt.Printf(\"Status: %s\\n\", *recordingDetail.Status)\nfmt.Printf(\"Duration: %.2fs\\n\", *recordingDetail.DurationSeconds)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/{id}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**get (Python SDK)**](/docs/en/python-sdk/sync/computer-use#recordingget)\n>\n> [**get (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#get)\n>\n> [**get (Ruby SDK)**](/docs/en/ruby-sdk/computer-use)\n>\n> [**Get (Go SDK)**](/docs/en/go-sdk/daytona/#RecordingService.Get)\n>\n> [**Get Recording (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/recordings/{id})\n\n### Delete Recording\n\nDelete a recording by ID:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox.computer_use.recording.delete(\"recording-id\")\nprint(\"Recording deleted successfully\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nawait sandbox.computerUse.recording.delete('recording-id');\nconsole.log('Recording deleted successfully');\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsandbox.computer_use.recording.delete(id: 'recording-id')\nputs 'Recording deleted successfully'\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nerr := sandbox.ComputerUse.Recording().Delete(ctx, \"recording-id\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Println(\"Recording deleted successfully\")\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/{id}' \\\n  --request DELETE\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**delete (Python SDK)**](/docs/en/python-sdk/sync/computer-use#recordingdelete)\n>\n> [**delete (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#delete)\n>\n> [**delete (Ruby SDK)**](/docs/en/ruby-sdk/computer-use)\n>\n> [**Delete (Go SDK)**](/docs/en/go-sdk/daytona/#RecordingService.Delete)\n>\n> [**Delete Recording (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/DELETE/computeruse/recordings/{id})\n\n### Download Recording\n\nDownload a recording file from the sandbox to your local machine. The file is streamed efficiently without loading the entire content into memory, making it suitable for large recordings.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Download recording to local file\nsandbox.computer_use.recording.download(recording.id, \"local_recording.mp4\")\nprint(\"Recording downloaded successfully\")\n\n# Or with custom path\nimport os\ndownload_path = os.path.join(\"recordings\", f\"recording_{recording.id}.mp4\")\nsandbox.computer_use.recording.download(recording.id, download_path)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Download recording to local file\nawait sandbox.computerUse.recording.download(recording.id, 'local_recording.mp4');\nconsole.log('Recording downloaded successfully');\n\n// Or with custom path\nconst downloadPath = `recordings/recording_${recording.id}.mp4`;\nawait sandbox.computerUse.recording.download(recording.id, downloadPath);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Download recording to local file\nsandbox.computer_use.recording.download(id: recording.id, local_path: 'local_recording.mp4')\nputs 'Recording downloaded successfully'\n\n# Or with custom path\ndownload_path = \"recordings/recording_#{recording.id}.mp4\"\nsandbox.computer_use.recording.download(id: recording.id, local_path: download_path)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Download recording to local file\nerr := sandbox.ComputerUse.Recording().Download(ctx, recording.GetId(), \"local_recording.mp4\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Println(\"Recording downloaded successfully\")\n\n// Or with custom path\ndownloadPath := fmt.Sprintf(\"recordings/recording_%s.mp4\", recording.GetId())\nerr = sandbox.ComputerUse.Recording().Download(ctx, recording.GetId(), downloadPath)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/recordings/{id}/download' \\\n  --output local_recording.mp4\n```\n\n</TabItem>\n</Tabs>\n\n:::tip[Streaming Downloads]\nAll SDK implementations stream the recording file directly to disk without loading the entire content into memory. This allows you to download large recordings (hundreds of MB or even GB) efficiently without running out of memory.\n\n- **Python**: Streams in 64KB chunks using `httpx`\n- **TypeScript**: Uses Node.js `pipeline()` with backpressure handling\n- **Ruby**: Uses Typhoeus streaming with `on_body` callbacks\n- **Go**: Uses `io.Copy()` with 32KB internal buffer\n:::\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Ruby SDK](/docs/en/ruby-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**download (Python SDK)**](/docs/en/python-sdk/sync/computer-use#recordingdownload)\n>\n> [**download (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#download)\n>\n> [**download (Ruby SDK)**](/docs/en/ruby-sdk/computer-use)\n>\n> [**Download (Go SDK)**](/docs/en/go-sdk/daytona/#RecordingService.Download)\n>\n> [**Download Recording (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/recordings/{id}/download)\n\n### Recording Dashboard\n\nEvery sandbox includes a built-in recording dashboard for managing screen recordings through a web interface. The dashboard allows you to view, download, and delete recordings without writing code.\n\nTo access the recording dashboard:\n\n1. Navigate to your sandboxes in the Daytona Dashboard\n2. Click the action menu (three dots) for your sandbox\n3. Select **Screen Recordings** from the dropdown menu\n\nThe recording dashboard provides:\n- List of all recordings with metadata (name, duration, file size, creation time)\n- Playback controls for reviewing recordings\n- Download functionality to save recordings locally\n- Delete options for managing storage\n\n:::tip\nThe recording dashboard runs on a private port and is automatically secured. No additional authentication is required once you access it through the Daytona Dashboard.\n:::\n\n## Display operations\n\n### Get info\n\nGet information about the displays.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ninfo = sandbox.computer_use.display.get_info()\nprint(f\"Primary display: {info.primary_display.width}x{info.primary_display.height}\")\nprint(f\"Total displays: {info.total_displays}\")\nfor i, display in enumerate(info.displays):\n    print(f\"Display {i}: {display.width}x{display.height} at {display.x},{display.y}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst info = await sandbox.computerUse.display.getInfo();\nconsole.log(`Primary display: ${info.primary_display.width}x${info.primary_display.height}`);\nconsole.log(`Total displays: ${info.total_displays}`);\ninfo.displays.forEach((display, index) => {\n  console.log(`Display ${index}: ${display.width}x${display.height} at ${display.x},${display.y}`);\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\ninfo = sandbox.computer_use.display.info\nputs \"Primary display: #{info.primary_display.width}x#{info.primary_display.height}\"\nputs \"Total displays: #{info.total_displays}\"\ninfo.displays.each_with_index do |display, i|\n  puts \"Display #{i}: #{display.width}x#{display.height} at #{display.x},#{display.y}\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\ninfo, err := sandbox.ComputerUse.Display().GetInfo(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Displays: %v\\n\", info[\"displays\"])\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/display/info'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**get_info (Python SDK)**](/docs/en/python-sdk/sync/computer-use#displayget_info)\n>\n> [**getInfo (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#getinfo)\n>\n> [**GetInfo (Go SDK)**](/docs/en/go-sdk/daytona/#DisplayService.GetInfo)\n>\n> [**Get display info (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/display/info)\n\n### Get windows\n\nGet the list of open windows.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nwindows = sandbox.computer_use.display.get_windows()\nprint(f\"Found {windows.count} open windows:\")\nfor window in windows.windows:\n    print(f\"- {window.title} (ID: {window.id})\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst windows = await sandbox.computerUse.display.getWindows();\nconsole.log(`Found ${windows.count} open windows:`);\nwindows.windows.forEach(window => {\n  console.log(`- ${window.title} (ID: ${window.id})`);\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nwindows = sandbox.computer_use.display.windows\nputs \"Found #{windows.count} open windows:\"\nwindows.windows.each do |window|\n  puts \"- #{window.title} (ID: #{window.id})\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nresult, err := sandbox.ComputerUse.Display().GetWindows(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Open windows: %v\\n\", result[\"windows\"])\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/display/windows'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/computer-use), [TypeScript SDK](/docs/en/typescript-sdk/computer-use), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api#daytona-toolbox/tag/computer-use) references:\n\n> [**get_windows (Python SDK)**](/docs/en/python-sdk/sync/computer-use#displayget_windows)\n>\n> [**getWindows (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#getwindows)\n>\n> [**GetWindows (Go SDK)**](/docs/en/go-sdk/daytona/#DisplayService.GetWindows)\n>\n> [**Get Windows (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/display/windows)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/configuration.mdx",
    "content": "---\ntitle: Environment Configuration\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona supports multiple methods to configure your environment, in order of precedence:\n\n1. [Configuration in code](#configuration-in-code)\n2. [Environment variables](#environment-variables)\n3. [.env file](#env-file)\n4. [Default values](#default-values)\n\n## Configuration in code\n\nTo configure your environment in code, use the `DaytonaConfig` class. The `DaytonaConfig` class accepts the following parameters:\n\n- `api_key`: Your Daytona [API Key](/docs/api-keys)\n- `api_url`: URL of your [Daytona API](/docs/en/tools/api)\n- `target`: Target region to create the Sandboxes on (`us` / `eu`)\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import DaytonaConfig\n\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"your-api-url\",\n    target=\"us\"\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { DaytonaConfig } from '@daytonaio/sdk'\n\nconst config: DaytonaConfig = {\n  apiKey: 'your-api-key',\n  apiUrl: 'your-api-url',\n  target: 'us',\n}\n```\n\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\nconfig = Daytona::Config.new(\n  api_key: 'your-api-key',\n  api_url: 'your-api-url',\n  target: 'us'\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n    config := daytona.Config{\n        APIKey: \"your-api-key\",\n        APIURL: \"your-api-url\",\n        Target: \"us\",\n    }\n\n    client := daytona.NewClient(&config)\n\n    _ = client\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/api-keys \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \\\n  --data '{\n  \"name\": \"\",\n  \"permissions\": [\n    \"write:registries\"\n  ],\n  \"expiresAt\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/daytona), [TypeScript SDK](/docs/en/typescript-sdk/daytona), [Ruby SDK](/docs/en/ruby-sdk/daytona), [Go SDK](/docs/en/go-sdk/daytona), and [API](/docs/en/tools/api/#daytona/tag/api-keys) references:\n\n> [**DaytonaConfig (Python SDK)**](/docs/en/python-sdk/sync/daytona#daytonaconfig)\n>\n> [**DaytonaConfig (TypeScript SDK)**](/docs/en/typescript-sdk/daytona#daytonaconfig)\n>\n> [**Config (Ruby SDK)**](/docs/en/ruby-sdk/config#config)\n>\n> [**DaytonaConfig (Go SDK)**](/docs/en/go-sdk/types#DaytonaConfig)\n>\n> [**Config (API)**](/docs/en/tools/api/#daytona/tag/api-keys/POST/api-keys)\n\n## Environment variables\n\nDaytona supports environment variables for configuration. The SDK automatically looks for these environment variables:\n\n| Variable              | Description                                | Required |\n| --------------------- | ------------------------------------------ | -------- |\n| **`DAYTONA_API_KEY`** | Your Daytona API key.                      | Yes      |\n| **`DAYTONA_API_URL`** | URL of your Daytona API.                   | No       |\n| **`DAYTONA_TARGET`**  | Daytona Target to create the sandboxes on. | No       |\n\n### Shell\n\nSet environment variables in your shell using the following methods:\n\n<Tabs syncKey=\"shell\">\n  <TabItem label=\"Bash/Zsh\" icon=\"seti:shell\">\n\n    ```bash\n    export DAYTONA_API_KEY=your-api-key\n    export DAYTONA_API_URL=https://your-api-url\n    export DAYTONA_TARGET=us\n    ```\n\n  </TabItem>\n  <TabItem label=\"Windows PowerShell\" icon=\"seti:powershell\">\n\n    ```bash\n    $env:DAYTONA_API_KEY=\"your-api-key\"\n    $env:DAYTONA_API_URL=\"https://your-api-url\"\n    $env:DAYTONA_TARGET=\"us\"\n    ```\n\n  </TabItem>\n</Tabs>\n\n### .env file\n\nSet the environment variables in a `.env` file using the following format:\n\n```bash\nDAYTONA_API_KEY=YOUR_API_KEY\nDAYTONA_API_URL=https://your_api_url\nDAYTONA_TARGET=us\n```\n\n## Default values\n\nIf no configuration is provided, Daytona will use its built-in default values:\n\n| **Option** | **Value**                           |\n| ---------- | ----------------------------------- |\n| API URL    | https://app.daytona.io/api          |\n| Target     | Default region for the organization |\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/custom-preview-proxy.mdx",
    "content": "---\ntitle: Custom Preview Proxy\ndescription: Deploy your own preview proxy with custom domains, authentication, and styling.\n---\n\nDaytona provides a preview proxy service that can be used to handle [preview URLs](/docs/en/preview) for sandboxes. This gives you full control over the preview experience, including custom domains, authentication, error handling, and styling.\n\n- **Custom domain**: host your proxy under your own domain (e.g., `preview.yourcompany.com`)\n- **User authentication**: implement custom authentication logic for private previews\n- **Sandbox management**: automatically start stopped sandboxes before forwarding users\n- **Custom error pages**: style error pages to match your brand\n- **Preview warning control**: disable Daytona's preview warning\n- **CORS management**: override Daytona's default CORS settings\n\n## How it works\n\nWhen a user visits a preview URL, your custom proxy receives the request and can:\n\n1. Authenticate the user using custom logic\n2. Check sandbox status and start it if needed\n3. Forward the request to the actual sandbox\n4. Handle responses with custom styling and error pages\n5. Send custom headers to control Daytona's behavior\n\nYour proxy should forward the `X-Forwarded-Host` header with the original request host when proxying requests to Daytona.\n\n## WebSocket support\n\nThe preview proxy fully supports WebSocket connections. WebSocket upgrade requests (`Upgrade: websocket`) are automatically detected and proxied. WebSocket connections skip the preview warning page.\n\n## Reserved ports\n\nThe following ports are reserved for internal services and always require authentication, even on public sandboxes:\n\n| Port        | Service                                   |\n| ----------- | ----------------------------------------- |\n| **`22222`** | [**Web** terminal](/docs/en/web-terminal) |\n| **`2280`**  | Toolbox (IDE/development interface)       |\n| **`33333`** | Recording dashboard                       |\n\nYour custom proxy should avoid exposing these ports unless you explicitly need access to these services.\n\n## Proxy headers\n\nYour proxy can send special headers to control Daytona's behavior.\n\n### Disable preview warning\n\nTo disable Daytona's preview warning page, send:\n\n```\nX-Daytona-Skip-Preview-Warning: true\n```\n\nThe warning page is only shown to browser requests. It sets a `daytona-preview-page-accepted` cookie that persists for 24 hours after acceptance.\n\n### Disable CORS\n\nDaytona's default CORS policy allows all origins with credentials. To override this and use your own CORS settings, send:\n\n```\nX-Daytona-Disable-CORS: true\n```\n\n### Disable last activity update\n\nTo prevent sandbox last activity updates when previewing, set the `X-Daytona-Skip-Last-Activity-Update` header to `true`. This prevents Daytona from keeping sandboxes that have [auto-stop enabled](/docs/en/sandboxes#auto-stop-interval) in a started state:\n\n```bash\ncurl -H \"X-Daytona-Skip-Last-Activity-Update: true\" \\\n  https://3000-sandbox-123456.proxy.daytona.work\n```\n\n### Authentication\n\nFor private preview links, send:\n\n```\nX-Daytona-Preview-Token: {sandboxToken}\n```\n\nThe `sandboxToken` can be fetched through the Daytona SDK or API using the [standard preview URL](/docs/en/preview#standard-preview-url) methods.\n\n## Examples\n\nExamples of custom preview proxies are available on [GitHub](https://github.com/daytonaio/daytona-proxy-samples).\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/declarative-builder.mdx",
    "content": "---\ntitle: Declarative Builder\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDeclarative Builder provides a powerful, code-first approach to defining dependencies for Daytona Sandboxes. Instead of importing images from a container registry, you can programmatically define them using the Daytona SDK.\n\nThe declarative builder system supports two primary workflows:\n\n1. [**Declarative images**](#declarative-image-building): build images with varying dependencies _on demand_ when creating sandboxes\n2. [**Pre-built Snapshots**](#creating-pre-built-snapshots): create and register _ready-to-use_ [Snapshots](/docs/snapshots) that can be shared across multiple sandboxes\n\n## Build declarative images\n\nDaytona provides an option to create declarative images on-the-fly when creating sandboxes. This is ideal for iterating quickly without creating separate snapshots.\n\nDeclarative images are cached for 24 hours, and are automatically reused when running the same script. Thus, subsequent runs on the same runner will be almost instantaneous.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Define a declarative image with python packages\ndeclarative_image = (\n  Image.debian_slim(\"3.12\")\n  .pip_install([\"requests\", \"pytest\"])\n  .workdir(\"/home/daytona\")\n)\n\n# Create a new sandbox with the declarative image and stream the build logs\nsandbox = daytona.create(\n  CreateSandboxFromImageParams(image=declarative_image),\n  timeout=0,\n  on_snapshot_create_logs=print,\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Define a declarative image with python packages\nconst declarativeImage = Image.debianSlim('3.12')\n  .pipInstall(['requests', 'pytest'])\n  .workdir('/home/daytona')\n\n// Create a new sandbox with the declarative image and stream the build logs\nconst sandbox = await daytona.create(\n  {\n    image: declarativeImage,\n  },\n  {\n    timeout: 0,\n    onSnapshotCreateLogs: console.log,\n  }\n)\n```\n\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Define a simple declarative image with Python packages\ndeclarative_image = Daytona::Image\n  .debian_slim('3.12')\n  .pip_install(['requests', 'pytest'])\n  .workdir('/home/daytona')\n\n# Create a new Sandbox with the declarative image and stream the build logs\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromImageParams.new(image: declarative_image),\n  on_snapshot_create_logs: proc { |chunk| puts chunk }\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Define a declarative image with python packages\nversion := \"3.12\"\ndeclarativeImage := daytona.DebianSlim(&version).\n  PipInstall([]string{\"requests\", \"pytest\"}).\n  Workdir(\"/home/daytona\")\n\n// Create a new sandbox with the declarative image and stream the build logs\nlogChan := make(chan string)\ngo func() {\n  for log := range logChan {\n    fmt.Print(log)\n  }\n}()\n\nsandbox, err := client.Create(ctx, types.ImageParams{\n  Image: declarativeImage,\n}, options.WithTimeout(0), options.WithLogChannel(logChan))\nif err != nil {\n  // handle error\n}\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**CreateSandboxFromImageParams (Python SDK)**](/docs/python-sdk/sync/daytona#createsandboxfromimageparams)\n>\n> [**CreateSandboxFromImageParams (TypeScript SDK)**](/docs/typescript-sdk/daytona#createsandboxfromimageparams)\n>\n> [**CreateSandboxFromImageParams (Ruby SDK)**](/docs/ruby-sdk/daytona#createsandboxfromimageparams)\n>\n> [**Create (Go SDK)**](/docs/go-sdk/daytona#Client.Create)\n\n:::note\nUse the following best practices when working with the declarative builder:\n\n- **Layer Optimization**: Group related operations to minimize Docker layers\n\n- **Cache Utilization**: Identical build commands and context will be cached and subsequent builds will be almost instant\n\n- **Security**: Create non-root users for application workloads\n\n- **Resource Efficiency**: Use slim base images when appropriate\n\n- **Context Minimization**: Only include necessary files in the build context\n  :::\n\n## Create pre-built Snapshots\n\nDaytona provides an option to [create pre-built snapshots](/docs/snapshots#create-snapshots) that can be reused across multiple sandboxes.\n\nThe snapshot remains visible in the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/snapshots) and is permanently cached, ensuring instant availability without rebuilding.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Create a python data science image\nsnapshot_name = \"data-science-snapshot\"\n\nimage = (\n  Image.debian_slim(\"3.12\")\n  .pip_install([\"pandas\", \"numpy\"])\n  .workdir(\"/home/daytona\")\n)\n\n# Create the snapshot and stream the build logs\ndaytona.snapshot.create(\n  CreateSnapshotParams(\n    name=snapshot_name,\n    image=image,\n  ),\non_logs=print,\n)\n\n# Create a new sandbox using the pre-built snapshot\nsandbox = daytona.create(\nCreateSandboxFromSnapshotParams(snapshot=snapshot_name)\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Create a python data science image\nconst snapshotName = 'data-science-snapshot'\n\nconst image = Image.debianSlim('3.12')\n  .pipInstall(['pandas', 'numpy'])\n  .workdir('/home/daytona')\n\n// Create the snapshot and stream the build logs\nawait daytona.snapshot.create(\n  {\n    name: snapshotName,\n    image,\n  },\n  {\n    onLogs: console.log,\n  }\n)\n\n// Create a new sandbox using the pre-built snapshot\nconst sandbox = await daytona.create({\n  snapshot: snapshotName,\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Create a simple Python data science image\nsnapshot_name = 'data-science-snapshot'\n\nimage = Daytona::Image\n  .debian_slim('3.12')\n  .pip_install(['pandas', 'numpy'])\n  .workdir('/home/daytona')\n\n# Create the Snapshot and stream the build logs\ndaytona.snapshot.create(\n  Daytona::CreateSnapshotParams.new(\n    name: snapshot_name,\n    image: image\n  ),\n  on_logs: proc { |chunk| puts chunk }\n)\n\n# Create a new Sandbox using the pre-built Snapshot\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(snapshot: snapshot_name)\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a python data science image\nsnapshotName := \"data-science-snapshot\"\n\nversion := \"3.12\"\nimage := daytona.DebianSlim(&version).\n  PipInstall([]string{\"pandas\", \"numpy\"}).\n  Workdir(\"/home/daytona\")\n\n// Create the snapshot and stream the build logs\n_, logChan, err := client.Snapshot.Create(ctx, &types.CreateSnapshotParams{\n  Name:  snapshotName,\n  Image: image,\n})\nif err != nil {\n  // handle error\n}\nfor log := range logChan {\n  fmt.Print(log)\n}\n\n// Create a new sandbox using the pre-built snapshot\nsandbox, err := client.Create(ctx, types.SnapshotParams{\n  Snapshot: snapshotName,\n})\nif err != nil {\n  // handle error\n}\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**CreateSnapshotParams (Python SDK)**](/docs/python-sdk/sync/snapshot#createsnapshotparams)\n>\n> [**CreateSnapshotParams (TypeScript SDK)**](/docs/typescript-sdk/snapshot#createsnapshotparams)\n>\n> [**CreateSnapshotParams (Ruby SDK)**](/docs/ruby-sdk/snapshot#createsnapshotparams)\n>\n> [**Create (Go SDK)**](/docs/go-sdk/daytona#SnapshotService.Create)\n\n## Image configuration\n\nDaytona provides an option to define images programmatically using the Daytona SDK. You can specify base images, install packages, add files, set environment variables, and more.\n\nFor a complete API reference and method signatures, see the [Python](/docs/python-sdk/common/image), [TypeScript](/docs/typescript-sdk/image), [Ruby](/docs/ruby-sdk/image), and [Go](/docs/go-sdk/daytona#type-DockerImage) SDK references.\n\n### Base image selection\n\nDaytona provides an option to select base images. The following snippets demonstrate how to select and configure base images:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Create an image from a base\nimage = Image.base(\"python:3.12-slim-bookworm\")\n\n# Use a Debian slim image with Python 3.12\nimage = Image.debian_slim(\"3.12\")\n```\n\n</TabItem>\n\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Create an image from a base\nconst image = Image.base('python:3.12-slim-bookworm')\n\n// Use a Debian slim image with Python 3.12\nconst image = Image.debianSlim('3.12')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Create an image from a base\nimage = Daytona::Image.base('python:3.12-slim-bookworm')\n\n# Use a Debian slim image with Python 3.12\nimage = Daytona::Image.debian_slim('3.12')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create an image from a base\nimage := daytona.Base(\"python:3.12-slim-bookworm\")\n\n// Use a Debian slim image with Python 3.12\nversion := \"3.12\"\nimage := daytona.DebianSlim(&version)\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**base (Python SDK)**](/docs/python-sdk/common/image#imagebase)\n>\n> [**base (TypeScript SDK)**](/docs/typescript-sdk/image#base)\n>\n> [**Base (Go SDK)**](/docs/go-sdk/daytona#Base)\n>\n> [**debian_slim (Python SDK)**](/docs/python-sdk/common/image#imagedebian_slim)\n>\n> [**debianSlim (TypeScript SDK)**](/docs/typescript-sdk/image#debianslim)\n>\n> [**DebianSlim (Go SDK)**](/docs/go-sdk/daytona#DebianSlim)\n\n### Package management\n\nDaytona provides an option to install packages and dependencies to your image.\nThe following snippets demonstrate how to install packages and dependencies to your image:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Add pip packages\nimage = Image.debian_slim(\"3.12\").pip_install([\"requests\", \"pandas\"])\n\n# Install from requirements.txt\nimage = Image.debian_slim(\"3.12\").pip_install_from_requirements(\"requirements.txt\")\n\n# Install from pyproject.toml (with optional dependencies)\nimage = Image.debian_slim(\"3.12\").pip_install_from_pyproject(\"pyproject.toml\", optional_dependencies=[\"dev\"])\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Add pip packages\nconst image = Image.debianSlim('3.12').pipInstall(['requests', 'pandas'])\n\n// Install from requirements.txt\nconst image = Image.debianSlim('3.12').pipInstallFromRequirements('requirements.txt')\n\n// Install from pyproject.toml (with optional dependencies)\nconst image = Image.debianSlim('3.12').pipInstallFromPyproject('pyproject.toml', {\n  optionalDependencies: ['dev']\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\n# Add pip packages\nimage = Daytona::Image.debian_slim('3.12').pip_install(['requests', 'pandas'])\n\n# Install from requirements.txt\nimage = Daytona::Image.debian_slim('3.12').pip_install_from_requirements('requirements.txt')\n\n# Install from pyproject.toml (with optional dependencies)\nimage = Daytona::Image.debian_slim('3.12').pip_install_from_pyproject('pyproject.toml',\n  optional_dependencies: ['dev']\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Add pip packages\nversion := \"3.12\"\nimage := daytona.DebianSlim(&version).PipInstall([]string{\"requests\", \"pandas\"})\n\n// Install from requirements.txt\nimage := daytona.DebianSlim(&version).\n  AddLocalFile(\"requirements.txt\", \"/tmp/requirements.txt\").\n  Run(\"pip install -r /tmp/requirements.txt\")\n\n// Install from pyproject.toml (with optional dependencies)\nimage := daytona.DebianSlim(&version).\n  AddLocalFile(\"pyproject.toml\", \"/tmp/pyproject.toml\").\n  Run(\"pip install /tmp[dev]\")\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**pip_install (Python SDK)**](/docs/python-sdk/common/image#imagepip_install)\n>\n> [**pipInstall (TypeScript SDK)**](/docs/typescript-sdk/image#pipinstall)\n>\n> [**pip_install (Ruby SDK)**](/docs/ruby-sdk/image#pip_install)\n>\n> [**PipInstall (Go SDK)**](/docs/go-sdk/daytona#DockerImage.PipInstall)\n>\n> [**pip_install_from_requirements (Python SDK)**](/docs/python-sdk/common/image#imagepip_install_from_requirements)\n>\n> [**pipInstallFromRequirements (TypeScript SDK)**](/docs/typescript-sdk/image#pipinstallfromrequirements)\n>\n> [**pip_install_from_requirements (Ruby SDK)**](/docs/ruby-sdk/image#pip_install_from_requirements)\n>\n> [**pip_install_from_pyproject (Python SDK)**](/docs/python-sdk/common/image#imagepip_install_from_pyproject)\n>\n> [**pipInstallFromPyproject (TypeScript SDK)**](/docs/typescript-sdk/image#pipinstallfrompyproject)\n>\n> [**pip_install_from_pyproject (Ruby SDK)**](/docs/ruby-sdk/image#pip_install_from_pyproject)\n\n### File system operations\n\nDaytona provides an option to add files and directories to your image.\nThe following snippets demonstrate how to add files and directories to your image:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Add a local file\nimage = Image.debian_slim(\"3.12\").add_local_file(\"package.json\", \"/home/daytona/package.json\")\n\n# Add a local directory\nimage = Image.debian_slim(\"3.12\").add_local_dir(\"src\", \"/home/daytona/src\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Add a local file\nconst image = Image.debianSlim('3.12').addLocalFile('package.json', '/home/daytona/package.json')\n\n// Add a local directory\nconst image = Image.debianSlim('3.12').addLocalDir('src', '/home/daytona/src')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Add a local file\nimage = Daytona::Image.debian_slim('3.12').add_local_file('package.json', '/home/daytona/package.json')\n\n# Add a local directory\nimage = Daytona::Image.debian_slim('3.12').add_local_dir('src', '/home/daytona/src')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Add a local file\nversion := \"3.12\"\nimage := daytona.DebianSlim(&version).AddLocalFile(\"package.json\", \"/home/daytona/package.json\")\n\n// Add a local directory\nimage := daytona.DebianSlim(&version).AddLocalDir(\"src\", \"/home/daytona/src\")\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**add_local_file (Python SDK)**](/docs/python-sdk/common/image#imageadd_local_file)\n>\n> [**add_local_dir (Python SDK)**](/docs/python-sdk/common/image#imageadd_local_dir)\n>\n> [**addLocalFile (TypeScript SDK)**](/docs/typescript-sdk/image#addlocalfile)\n>\n> [**addLocalDir (TypeScript SDK)**](/docs/typescript-sdk/image#addlocaldir)\n>\n> [**add_local_file (Ruby SDK)**](/docs/ruby-sdk/image#add_local_file)\n>\n> [**add_local_dir (Ruby SDK)**](/docs/ruby-sdk/image#add_local_dir)\n>\n> [**AddLocalFile (Go SDK)**](/docs/go-sdk/daytona#DockerImage.AddLocalFile)\n>\n> [**AddLocalDir (Go SDK)**](/docs/go-sdk/daytona#DockerImage.AddLocalDir)\n\n### Environment configuration\n\nDaytona provides an option to configure environment variables and working directories.\nThe following snippets demonstrate how to configure environment variables and working directories:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Set environment variables\nimage = Image.debian_slim(\"3.12\").env({\"PROJECT_ROOT\": \"/home/daytona\"})\n\n# Set working directory\nimage = Image.debian_slim(\"3.12\").workdir(\"/home/daytona\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Set environment variables\nconst image = Image.debianSlim('3.12').env({ PROJECT_ROOT: '/home/daytona' })\n\n// Set working directory\nconst image = Image.debianSlim('3.12').workdir('/home/daytona')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Set environment variables\nimage = Daytona::Image.debian_slim('3.12').env({ 'PROJECT_ROOT' => '/home/daytona' })\n\n# Set working directory\nimage = Daytona::Image.debian_slim('3.12').workdir('/home/daytona')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Set environment variables\nversion := \"3.12\"\nimage := daytona.DebianSlim(&version).Env(\"PROJECT_ROOT\", \"/home/daytona\")\n\n// Set working directory\nimage := daytona.DebianSlim(&version).Workdir(\"/home/daytona\")\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**env (Python SDK)**](/docs/python-sdk/common/image#imageenv)\n>\n> [**workdir (Python SDK)**](/docs/python-sdk/common/image#imageworkdir)\n>\n> [**env (TypeScript SDK)**](/docs/typescript-sdk/image#env)\n>\n> [**workdir (TypeScript SDK)**](/docs/typescript-sdk/image#workdir)\n>\n> [**env (Ruby SDK)**](/docs/ruby-sdk/image#env)\n>\n> [**workdir (Ruby SDK)**](/docs/ruby-sdk/image#workdir)\n>\n> [**Env (Go SDK)**](/docs/go-sdk/daytona#DockerImage.Env)\n>\n> [**Workdir (Go SDK)**](/docs/go-sdk/daytona#DockerImage.Workdir)\n\n### Commands and entrypoints\n\nDaytona provides an option to execute commands during build and configure container startup behavior.\nThe following snippets demonstrate how to execute commands during build and configure container startup behavior:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Run shell commands during build\nimage = Image.debian_slim(\"3.12\").run_commands(\n    'apt-get update && apt-get install -y git',\n    'groupadd -r daytona && useradd -r -g daytona -m daytona',\n    'mkdir -p /home/daytona/workspace'\n)\n\n# Set entrypoint\nimage = Image.debian_slim(\"3.12\").entrypoint([\"/bin/bash\"])\n\n# Set default command\nimage = Image.debian_slim(\"3.12\").cmd([\"/bin/bash\"])\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Run shell commands during build\nconst image = Image.debianSlim('3.12').runCommands(\n    'apt-get update && apt-get install -y git',\n    'groupadd -r daytona && useradd -r -g daytona -m daytona',\n    'mkdir -p /home/daytona/workspace'\n)\n\n// Set entrypoint\nconst image = Image.debianSlim('3.12').entrypoint(['/bin/bash'])\n\n// Set default command\nconst image = Image.debianSlim('3.12').cmd(['/bin/bash'])\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Run shell commands during build\nimage = Daytona::Image.debian_slim('3.12').run_commands(\n  'apt-get update && apt-get install -y git',\n  'groupadd -r daytona && useradd -r -g daytona -m daytona',\n  'mkdir -p /home/daytona/workspace'\n)\n\n# Set entrypoint\nimage = Daytona::Image.debian_slim('3.12').entrypoint(['/bin/bash'])\n\n# Set default command\nimage = Daytona::Image.debian_slim('3.12').cmd(['/bin/bash'])\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Run shell commands during build\nversion := \"3.12\"\nimage := daytona.DebianSlim(&version).\n  Run(\"apt-get update && apt-get install -y git\").\n  Run(\"groupadd -r daytona && useradd -r -g daytona -m daytona\").\n  Run(\"mkdir -p /home/daytona/workspace\")\n\n// Set entrypoint\nimage := daytona.DebianSlim(&version).Entrypoint([]string{\"/bin/bash\"})\n\n// Set default command\nimage := daytona.DebianSlim(&version).Cmd([]string{\"/bin/bash\"})\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**run_commands (Python SDK)**](/docs/python-sdk/common/image#imagerun_commands)\n>\n> [**entrypoint (Python SDK)**](/docs/python-sdk/common/image#imageentrypoint)\n>\n> [**cmd (Python SDK)**](/docs/python-sdk/common/image#imagecmd)\n>\n> [**runCommands (TypeScript SDK)**](/docs/typescript-sdk/image#runcommands)\n>\n> [**entrypoint (TypeScript SDK)**](/docs/typescript-sdk/image#entrypoint)\n>\n> [**cmd (TypeScript SDK)**](/docs/typescript-sdk/image#cmd)\n>\n> [**run_commands (Ruby SDK)**](/docs/ruby-sdk/image#run_commands)\n>\n> [**entrypoint (Ruby SDK)**](/docs/ruby-sdk/image#entrypoint)\n>\n> [**cmd (Ruby SDK)**](/docs/ruby-sdk/image#cmd)\n>\n> [**Run (Go SDK)**](/docs/go-sdk/daytona#DockerImage.Run)\n>\n> [**Entrypoint (Go SDK)**](/docs/go-sdk/daytona#DockerImage.Entrypoint)\n>\n> [**Cmd (Go SDK)**](/docs/go-sdk/daytona#DockerImage.Cmd)\n\n### Dockerfile integration\n\nDaytona provides an option to integrate existing Dockerfiles or add custom Dockerfile commands.\nThe following snippets demonstrate how to integrate existing Dockerfiles or add custom Dockerfile commands:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Add custom Dockerfile commands\nimage = Image.debian_slim(\"3.12\").dockerfile_commands([\"RUN echo 'Hello, world!'\"])\n\n# Use an existing Dockerfile\nimage = Image.from_dockerfile(\"Dockerfile\")\n\n# Extend an existing Dockerfile\nimage = Image.from_dockerfile(\"app/Dockerfile\").pip_install([\"numpy\"])\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Add custom Dockerfile commands\nconst image = Image.debianSlim('3.12').dockerfileCommands(['RUN echo \"Hello, world!\"'])\n\n// Use an existing Dockerfile\nconst image = Image.fromDockerfile('Dockerfile')\n\n// Extend an existing Dockerfile\nconst image = Image.fromDockerfile(\"app/Dockerfile\").pipInstall(['numpy'])\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Add custom Dockerfile commands\nimage = Daytona::Image.debian_slim('3.12').dockerfile_commands(['RUN echo \"Hello, world!\"'])\n\n# Use an existing Dockerfile\nimage = Daytona::Image.from_dockerfile('Dockerfile')\n\n# Extend an existing Dockerfile\nimage = Daytona::Image.from_dockerfile('app/Dockerfile').pip_install(['numpy'])\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Note: In Go, FromDockerfile takes the Dockerfile content as a string\ncontent, err := os.ReadFile(\"Dockerfile\")\nif err != nil {\n  // handle error\n}\nimage := daytona.FromDockerfile(string(content))\n\n// Extend an existing Dockerfile with additional commands\ncontent, err = os.ReadFile(\"app/Dockerfile\")\nif err != nil {\n  // handle error\n}\nimage := daytona.FromDockerfile(string(content)).\n  PipInstall([]string{\"numpy\"})\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**dockerfile_commands (Python SDK)**](/docs/python-sdk/common/image#imagedockerfile_commands)\n>\n> [**from_dockerfile (Python SDK)**](/docs/python-sdk/common/image#imagefrom_dockerfile)\n>\n> [**dockerfileCommands (TypeScript SDK)**](/docs/typescript-sdk/image#dockerfilecommands)\n>\n> [**fromDockerfile (TypeScript SDK)**](/docs/typescript-sdk/image#fromdockerfile)\n>\n> [**dockerfile_commands (Ruby SDK)**](/docs/ruby-sdk/image#dockerfile_commands)\n>\n> [**FromDockerfile (Go SDK)**](/docs/go-sdk/daytona#FromDockerfile)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/experimental/otel-collection.mdx",
    "content": "---\ntitle: OpenTelemetry Collection\ndescription: Enable distributed tracing for Daytona SDK operations using OpenTelemetry.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nOpenTelemetry (OTEL) tracing allows you to monitor and debug your Daytona SDK operations by collecting distributed traces. This is particularly useful for understanding performance bottlenecks, debugging issues, and gaining visibility into your sandbox operations.\n\n:::caution\nOpenTelemetry collection is currently an experimental feature and may change in future releases. To request access to this feature, please contact [support@daytona.io](mailto:support@daytona.io).\n:::\n\n---\n\n## Sandbox Telemetry Collection\n\nDaytona can collect traces, logs, and metrics directly from your sandboxes. This provides complete observability across your entire Daytona environment, from [SDK calls](#sdk-tracing-configuration) to sandbox runtime behavior.\n\n### What Gets Collected from Sandboxes\n\nWhen sandbox telemetry is enabled, the following data is collected:\n\n**Metrics:**\n\n- `daytona.sandbox.cpu.utilization` - CPU usage percentage (0-100%)\n- `daytona.sandbox.cpu.limit` - CPU cores limit\n- `daytona.sandbox.memory.utilization` - Memory usage percentage (0-100%)\n- `daytona.sandbox.memory.usage` - Memory used in bytes\n- `daytona.sandbox.memory.limit` - Memory limit in bytes\n- `daytona.sandbox.filesystem.utilization` - Disk usage percentage (0-100%)\n- `daytona.sandbox.filesystem.usage` - Disk space used in bytes\n- `daytona.sandbox.filesystem.available` - Disk space available in bytes\n- `daytona.sandbox.filesystem.total` - Total disk space in bytes\n\n**Traces:**\n\n- HTTP requests and responses\n- Custom spans from your application code\n\n**Logs:**\n\n- Application logs (stdout/stderr)\n- System logs\n- Runtime errors and warnings\n\n### Viewing Telemetry in the Dashboard\n\nLogs, traces, and metrics collected from sandboxes can be viewed directly in the Daytona Dashboard. Open the **Sandbox Details** sheet for any sandbox and use the **Logs**, **Traces**, and **Metrics** tabs to inspect the collected telemetry data.\n\n:::note\nDaytona retains sandbox telemetry data for **3 days**. If you need to keep the data for longer, it is recommended that you connect your own OTLP-compatible collector using the [sandbox collection configuration](#configure-sandbox-collection).\n:::\n\n:::tip\nSandbox telemetry collection works independently from SDK tracing. You can enable one or both depending on your observability needs:\n\n- **SDK tracing only**: Monitor Daytona API operations and SDK calls\n- **Sandbox telemetry only**: Monitor application behavior inside sandboxes\n- **Both**: Get complete end-to-end observability across your entire stack\n:::\n\n### Configure Sandbox Collection\n\nTo enable telemetry collection from sandboxes:\n\n1. Navigate to the [Daytona Dashboard](https://app.daytona.io)\n2. Go to **Settings** → **Experimental**\n3. Configure the following fields:\n   \n- **OTLP Endpoint**: Your OpenTelemetry collector endpoint (e.g., `https://otlp.nr-data.net`)\n- **OTLP Headers**: Authentication headers in `key=value` format (e.g., `api-key=YOUR_API_KEY`)\n\nOnce configured, all sandboxes will automatically export their telemetry data to your specified OTLP endpoint.\n\n---\n\n## SDK Tracing Configuration\n\nWhen enabled, the Daytona SDK automatically instruments all SDK operations including:\n\n- Sandbox creation, starting, stopping, and deletion\n- File system operations\n- Code execution\n- Process management\n- HTTP requests to the Daytona API\n\nTraces are exported using the OTLP (OpenTelemetry Protocol) format and can be sent to any OTLP-compatible backend such as New Relic, Jaeger, or Zipkin.\n\n### 1. Enable OTEL in SDK\n\nTo enable OpenTelemetry tracing, pass the `otelEnabled` experimental flag when initializing the Daytona client:\n\nAlternatively, you can set the `DAYTONA_EXPERIMENTAL_OTEL_ENABLED` environment variable to `true` instead of passing the configuration option:\n\n```bash\nexport DAYTONA_EXPERIMENTAL_OTEL_ENABLED=true\n```\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, DaytonaConfig\n\n    # Using async context manager (recommended)\n    async with Daytona(DaytonaConfig(\n        _experimental={\"otelEnabled\": True}\n    )) as daytona:\n        sandbox = await daytona.create()\n        # All operations will be traced\n    # OpenTelemetry traces are flushed on close\n    ```\n\n    Or without context manager:\n    ```python\n    daytona = Daytona(DaytonaConfig(\n        _experimental={\"otelEnabled\": True}\n    ))\n    try:\n        sandbox = await daytona.create()\n        # All operations will be traced\n    finally:\n        await daytona.close()  # Flushes traces\n    ```\n\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona } from '@daytonaio/sdk'\n\n    // Using async dispose (recommended)\n    await using daytona = new Daytona({\n      _experimental: { otelEnabled: true }\n    })\n\n    const sandbox = await daytona.create()\n    // All operations will be traced\n    // Traces are automatically flushed on dispose\n    ```\n\n    Or with explicit disposal:\n    ```typescript\n    const daytona = new Daytona({\n      _experimental: { otelEnabled: true }\n    })\n\n    try {\n      const sandbox = await daytona.create()\n      // All operations will be traced\n    } finally {\n      await daytona[Symbol.asyncDispose]()  // Flushes traces\n    }\n    ```\n\n  </TabItem>\n\n  <TabItem label=\"Go\" icon=\"seti:go\">\n    ```go\n    import (\n        \"context\"\n        \"log\"\n\n        \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n        \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n    )\n\n    client, err := daytona.NewClientWithConfig(&types.DaytonaConfig{\n        Experimental: &types.ExperimentalConfig{\n            OtelEnabled: true,\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer client.Close(context.Background()) // Flushes traces\n\n    sandbox, err := client.Create(context.Background(), nil)\n    // All operations will be traced\n    ```\n\n  </TabItem>\n\n  <TabItem label=\"Ruby\" icon=\"seti:ruby\">\n    ```ruby\n    require 'daytona'\n\n    config = Daytona::Config.new(\n      _experimental: { 'otel_enabled' => true }\n    )\n    daytona = Daytona::Daytona.new(config)\n\n    sandbox = daytona.create\n    # All operations will be traced\n\n    daytona.close # Flushes traces\n    ```\n\n    Or with `ensure` block:\n    ```ruby\n    daytona = Daytona::Daytona.new(\n      Daytona::Config.new(_experimental: { 'otel_enabled' => true })\n    )\n    begin\n      sandbox = daytona.create\n      # All operations will be traced\n    ensure\n      daytona.close # Flushes traces\n    end\n    ```\n\n  </TabItem>\n</Tabs>\n\n### 2. Configure OTLP Exporter\n\nThe SDK uses standard OpenTelemetry environment variables for configuration. Set these before running your application:\n\n#### Required Environment Variables\n\n```bash\n# OTLP endpoint (without the /v1/traces path)\nOTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.nr-data.net:4317\n\n# Authentication headers (format: key1=value1,key2=value2)\nOTEL_EXPORTER_OTLP_HEADERS=\"api-key=your-api-key-here\"\n```\n\n---\n\n## Provider-Specific Examples\n\n### New Relic\n\n```bash\nOTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.nr-data.net:4317\nOTEL_EXPORTER_OTLP_HEADERS=\"api-key=YOUR_NEW_RELIC_LICENSE_KEY\"\n```\n\n### Jaeger (Local)\n\n```bash\nOTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318\n```\n\n### Grafana Cloud\n\n```bash\nOTEL_EXPORTER_OTLP_ENDPOINT=https://otlp-gateway-prod-<region>.grafana.net/otlp\nOTEL_EXPORTER_OTLP_HEADERS=\"Authorization=Basic <BASE64_ENCODED_CREDENTIALS>\"\n```\n\nSetup: Go to [Grafana Cloud Portal](https://grafana.com) → **Connections** → **Add new connection** → Search for **OpenTelemetry (OTLP)** → Follow the wizard to create an access token. The endpoint and headers will be provided in the instrumentation instructions. See the [Grafana dashboard example](https://github.com/daytonaio/daytona/tree/main/examples/otel-dashboards/grafana) for detailed setup steps.\n\n---\n\n## Complete Example\n\nHere's a complete example showing how to use OpenTelemetry tracing with the Daytona SDK:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import asyncio\n    import os\n    from daytona import Daytona, DaytonaConfig\n\n    # Set OTEL configuration\n    os.environ[\"OTEL_EXPORTER_OTLP_ENDPOINT\"] = \"https://otlp.nr-data.net:4317\"\n    os.environ[\"OTEL_EXPORTER_OTLP_HEADERS\"] = \"api-key=YOUR_API_KEY\"\n\n    async def main():\n        # Initialize Daytona with OTEL enabled\n        async with Daytona(DaytonaConfig(\n            _experimental={\"otelEnabled\": True}\n        )) as daytona:\n\n            # Create a sandbox - this operation will be traced\n            sandbox = await daytona.create()\n            print(f\"Created sandbox: {sandbox.id}\")\n\n            # Execute code - this operation will be traced\n            result = await sandbox.process.code_run(\"\"\n\nimport numpy as np\nprint(f\"NumPy version: {np.__version__}\")\n            \"\")\n            print(f\"Execution result: {result.result}\")\n\n            # Upload a file - this operation will be traced\n            await sandbox.fs.upload_file(\"local.txt\", \"/home/daytona/remote.txt\")\n\n            # Delete sandbox - this operation will be traced\n            await daytona.delete(sandbox)\n\n        # Traces are automatically flushed when exiting the context manager\n\n    if __name__ == \"__main__\":\n        asyncio.run(main())\n    ```\n\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    // Set OTEL configuration\n    process.env.OTEL_EXPORTER_OTLP_ENDPOINT = \"https://otlp.nr-data.net:4317\"\n    process.env.OTEL_EXPORTER_OTLP_HEADERS = \"api-key=YOUR_API_KEY\"\n\n    import { Daytona } from '@daytonaio/sdk'\n\n    async function main() {\n      // Initialize Daytona with OTEL enabled\n      await using daytona = new Daytona({\n        _experimental: { otelEnabled: true }\n      })\n\n      // Create a sandbox - this operation will be traced\n      const sandbox = await daytona.create()\n      console.log(`Created sandbox: ${sandbox.id}`)\n\n      // Execute code - this operation will be traced\n      const result = await sandbox.process.codeRun(`\n\nimport numpy as np\nprint(f\"NumPy version: {np.__version__}\")\n      `)\n      console.log(`Execution result: ${result.result}`)\n\n      // Upload a file - this operation will be traced\n      await sandbox.fs.uploadFile('local.txt', '/home/daytona/remote.txt')\n\n      // Delete sandbox - this operation will be traced\n      await daytona.delete(sandbox)\n\n      // Traces are automatically flushed when the daytona instance is disposed\n    }\n\n    main().catch(console.error)\n    ```\n\n  </TabItem>\n\n  <TabItem label=\"Go\" icon=\"seti:go\">\n    ```go\n    package main\n\n    import (\n        \"context\"\n        \"fmt\"\n        \"log\"\n        \"os\"\n\n        \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n        \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n    )\n\n    func main() {\n        // Set OTEL configuration\n        os.Setenv(\"OTEL_EXPORTER_OTLP_ENDPOINT\", \"https://otlp.nr-data.net:4317\")\n        os.Setenv(\"OTEL_EXPORTER_OTLP_HEADERS\", \"api-key=YOUR_API_KEY\")\n\n        ctx := context.Background()\n\n        // Initialize Daytona with OTEL enabled\n        client, err := daytona.NewClientWithConfig(&types.DaytonaConfig{\n          Experimental: &types.ExperimentalConfig{\n            OtelEnabled: true,\n          },\n        })\n        if err != nil {\n          log.Fatal(err)\n        }\n        defer client.Close(ctx) // Flushes traces on exit\n\n        // Create a sandbox - this operation will be traced\n        sandbox, err := client.Create(ctx, nil)\n        if err != nil {\n          log.Fatal(err)\n        }\n        fmt.Printf(\"Created sandbox: %s\\n\", sandbox.ID)\n\n        // Execute code - this operation will be traced\n        result, err := sandbox.Process.CodeRun(ctx, &types.CodeRunParams{\n            Code: `\n\nimport numpy as np\nprint(f\"NumPy version: {np.__version__}\")\n            `,\n        })\n        if err != nil {\n          log.Fatal(err)\n        }\n        fmt.Printf(\"Execution result: %s\\n\", result.Result)\n\n        // Upload a file - this operation will be traced\n        err = sandbox.Fs.UploadFile(ctx, \"local.txt\", \"/home/daytona/remote.txt\")\n        if err != nil {\n          log.Fatal(err)\n        }\n\n        // Delete sandbox - this operation will be traced\n        err = client.Delete(ctx, sandbox, nil)\n        if err != nil {\n          log.Fatal(err)\n        }\n\n        // Traces are flushed when client.Close is called via defer\n    }\n    ```\n\n  </TabItem>\n\n  <TabItem label=\"Ruby\" icon=\"seti:ruby\">\n    ```ruby\n    require 'daytona'\n\n    # Set OTEL configuration\n    ENV[\"OTEL_EXPORTER_OTLP_ENDPOINT\"] = \"https://otlp.nr-data.net:4317\"\n    ENV[\"OTEL_EXPORTER_OTLP_HEADERS\"] = \"api-key=YOUR_API_KEY\"\n\n    # Initialize Daytona with OTEL enabled\n    config = Daytona::Config.new(\n      _experimental: { 'otel_enabled' => true }\n    )\n    daytona = Daytona::Daytona.new(config)\n\n    begin\n      # Create a sandbox - this operation will be traced\n      sandbox = daytona.create\n      puts \"Created sandbox: #{sandbox.id}\"\n\n      # Execute code - this operation will be traced\n      result = sandbox.process.code_run(\"\n\nimport numpy as np\nprint(f'NumPy version: {np.__version__}')\n      \")\n      puts \"Execution result: #{result.result}\"\n\n      # Upload a file - this operation will be traced\n      sandbox.fs.upload_file(\"local.txt\", \"/home/daytona/remote.txt\")\n\n      # Delete sandbox - this operation will be traced\n      daytona.delete(sandbox)\n    ensure\n      daytona.close # Flushes traces\n    end\n    ```\n\n  </TabItem>\n</Tabs>\n\n---\n\n## What Gets Traced\n\nThe Daytona SDK automatically instruments the following operations:\n\n### SDK-Level Operations\n\n- `create()` - Sandbox creation and initialization\n- `get()` - Retrieving sandbox instances\n- `list()` - Listing sandboxes\n- `start()` - Starting sandboxes\n- `stop()` - Stopping sandboxes\n- `delete()` - Deleting sandboxes\n- All sandbox, snapshot and volume operations (file system, code execution, process management, etc.)\n\n### HTTP Requests\n\n- All API calls to the Daytona backend\n- Request duration and response status codes\n- Error information for failed requests\n\n### Trace Attributes\n\nEach trace includes valuable metadata such as:\n\n- Service name and version\n- HTTP method, URL, and status code\n- Request and response duration\n- Error details (if applicable)\n- Custom SDK operation metadata\n\n---\n\n## Dashboard Examples\n\n- [New Relic](https://github.com/daytonaio/daytona/tree/main/examples/otel-dashboards/new-relic)\n- [Grafana](https://github.com/daytonaio/daytona/tree/main/examples/otel-dashboards/grafana)\n\n## Troubleshooting\n\n### Verify Traces Are Being Sent\n\n1. Check that environment variables are set correctly\n2. Verify your OTLP endpoint is reachable\n3. Confirm API keys/headers are valid\n4. Check your observability platform for incoming traces\n5. Look for connection errors in application logs\n\n### Common Issues\n\n**Traces not appearing:**\n\n- Ensure `otelEnabled: true` is set in the configuration\n- Verify OTLP endpoint and headers are correct\n- Check that you're properly closing/disposing the Daytona instance to flush traces\n\n**Connection refused:**\n\n- Verify the OTLP endpoint URL is correct\n- Ensure the endpoint is accessible from your application\n- Check firewall rules if running in a restricted environment\n\n**Authentication errors:**\n\n- Verify API key format matches your provider's requirements\n- Check that the `OTEL_EXPORTER_OTLP_HEADERS` format is correct (key=value pairs)\n\n---\n\n## Best Practices\n\n1. **Always close the client**: Use `async with` (Python), `await using` (TypeScript), `defer client.Close()` (Go), or `ensure daytona.close` (Ruby) to ensure traces are properly flushed\n1. **Monitor trace volume**: Be aware that enabling tracing will increase network traffic and storage in your observability platform\n1. **Use in development first**: Test OTEL configuration in development before enabling in production\n1. **Configure sampling**: For high-volume applications, consider configuring trace sampling to reduce costs\n\n---\n\n## Additional Resources\n\n- [OpenTelemetry Documentation](https://opentelemetry.io/docs/)\n- [OTLP Specification](https://opentelemetry.io/docs/specs/otlp/)\n- [Daytona SDK Documentation](/docs/en/introduction/)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/file-system-operations.mdx",
    "content": "---\ntitle: File System Operations\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona provides comprehensive file system operations through the `fs` module in sandboxes.\n\n## Basic operations\n\nDaytona provides methods to interact with the file system in sandboxes. You can perform various operations like listing files, creating directories, reading and writing files, and more.\n\nFile operations assume you are operating in the sandbox user's home directory (e.g. `workspace` implies `/home/[username]/workspace`). Use a leading `/` when providing absolute paths.\n\n### List files and directories\n\nDaytona provides methods to list files and directories in a sandbox by providing the path to the directory. If the path is not provided, the method will list the files and directories in the sandbox working directory.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# List files in a directory\nfiles = sandbox.fs.list_files(\"workspace\")\n\nfor file in files:\n    print(f\"Name: {file.name}\")\n    print(f\"Is directory: {file.is_dir}\")\n    print(f\"Size: {file.size}\")\n    print(f\"Modified: {file.mod_time}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// List files in a directory\nconst files = await sandbox.fs.listFiles('workspace')\n\nfiles.forEach(file => {\n  console.log(`Name: ${file.name}`)\n  console.log(`Is directory: ${file.isDir}`)\n  console.log(`Size: ${file.size}`)\n  console.log(`Modified: ${file.modTime}`)\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# List directory contents\nfiles = sandbox.fs.list_files(\"workspace/data\")\n\n# Print files and their sizes\nfiles.each do |file|\n  puts \"#{file.name}: #{file.size} bytes\" unless file.is_dir\nend\n\n# List only directories\ndirs = files.select(&:is_dir)\nputs \"Subdirectories: #{dirs.map(&:name).join(', ')}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// List files in a directory\nfiles, err := sandbox.FileSystem.ListFiles(ctx, \"workspace\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfor _, file := range files {\n\tfmt.Printf(\"Name: %s\\n\", file.Name)\n\tfmt.Printf(\"Is directory: %t\\n\", file.IsDirectory)\n\tfmt.Printf(\"Size: %d\\n\", file.Size)\n\tfmt.Printf(\"Modified: %s\\n\", file.ModifiedTime)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**list_files (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemlist_files)\n>\n> [**listFiles (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#listfiles)\n>\n> [**list_files (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#list_files)\n>\n> [**ListFiles (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.ListFiles)\n>\n> [**list files and directories (API)**](/docs/en/tools/api/#daytona-toolbox/tag/file-system/GET/files)\n\n### Get directory or file information\n\nDaytona provides methods to get directory or file information such as group, directory, modified time, mode, name, owner, permissions, and size by providing the path to the directory or file.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Get file metadata\ninfo = sandbox.fs.get_file_info(\"workspace/data/file.txt\")\nprint(f\"Size: {info.size} bytes\")\nprint(f\"Modified: {info.mod_time}\")\nprint(f\"Mode: {info.mode}\")\n\n# Check if path is a directory\ninfo = sandbox.fs.get_file_info(\"workspace/data\")\nif info.is_dir:\n    print(\"Path is a directory\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Get file details\nconst info = await fs.getFileDetails('app/config.json')\nconsole.log(`Size: ${info.size}, Modified: ${info.modTime}`)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Get file metadata\ninfo = sandbox.fs.get_file_info(\"workspace/data/file.txt\")\nputs \"Size: #{info.size} bytes\"\nputs \"Modified: #{info.mod_time}\"\nputs \"Mode: #{info.mode}\"\n\n# Check if path is a directory\ninfo = sandbox.fs.get_file_info(\"workspace/data\")\nputs \"Path is a directory\" if info.is_dir\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Get file metadata\ninfo, err := sandbox.FileSystem.GetFileInfo(ctx, \"workspace/data/file.txt\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Size: %d bytes\\n\", info.Size)\nfmt.Printf(\"Modified: %s\\n\", info.ModifiedTime)\nfmt.Printf(\"Mode: %s\\n\", info.Mode)\n\n// Check if path is a directory\ninfo, err = sandbox.FileSystem.GetFileInfo(ctx, \"workspace/data\")\nif err != nil {\n\tlog.Fatal(err)\n}\nif info.IsDirectory {\n\tfmt.Println(\"Path is a directory\")\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/info?path='\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**get_file_info (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemget_file_info)\n>\n> [**getFileDetails (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#getfiledetails)\n>\n> [**get_file_info (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#get_file_info)\n>\n> [**GetFileInfo (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.GetFileInfo)\n>\n> [**get file information (API)**](/docs/en/tools/api/#daytona-toolbox/tag/file-system/GET/files/info)\n\n### Create directories\n\nDaytona provides methods to create directories by providing the path to the directory and the permissions to set on the directory.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Create with specific permissions\nsandbox.fs.create_folder(\"workspace/new-dir\", \"755\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Create with specific permissions\nawait sandbox.fs.createFolder('workspace/new-dir', '755')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Create a directory with standard permissions\nsandbox.fs.create_folder(\"workspace/data\", \"755\")\n\n# Create a private directory\nsandbox.fs.create_folder(\"workspace/secrets\", \"700\")\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create with specific permissions\nerr := sandbox.FileSystem.CreateFolder(ctx, \"workspace/new-dir\",\n\toptions.WithMode(\"755\"),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/folder?path=&mode=' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**create_folder (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemcreate_folder)\n>\n> [**createFolder (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#createfolder)\n>\n> [**create_folder (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#create_folder)\n>\n> [**CreateFolder (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.CreateFolder)\n>\n> [**create folder (API)**](/docs/en/tools/api/#daytona-toolbox/tag/file-system/POST/files/folder)\n\n### Upload files\n\nDaytona provides methods to upload a single or multiple files in sandboxes.\n\n#### Upload a single file\n\nDaytona provides methods to upload a single file in sandboxes by providing the content to upload and the path to the file to upload it to.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Upload a single file\nwith open(\"local_file.txt\", \"rb\") as f:\n    content = f.read()\nsandbox.fs.upload_file(content, \"remote_file.txt\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Upload a single file\nconst fileContent = Buffer.from('Hello, World!')\nawait sandbox.fs.uploadFile(fileContent, 'data.txt')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Upload a text file from string content\ncontent = \"Hello, World!\"\nsandbox.fs.upload_file(content, \"tmp/hello.txt\")\n\n# Upload a local file\nsandbox.fs.upload_file(\"local_file.txt\", \"tmp/file.txt\")\n\n# Upload binary data\ndata = { key: \"value\" }.to_json\nsandbox.fs.upload_file(data, \"tmp/config.json\")\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Upload from a local file path\nerr := sandbox.FileSystem.UploadFile(ctx, \"local_file.txt\", \"remote_file.txt\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Or upload from byte content\ncontent := []byte(\"Hello, World!\")\nerr = sandbox.FileSystem.UploadFile(ctx, content, \"hello.txt\")\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/upload?path=' \\\n  --request POST \\\n  --header 'Content-Type: multipart/form-data' \\\n  --form 'file='\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**upload_file (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemupload_file)\n>\n> [**uploadFile (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#uploadfile)\n>\n> [**upload_file (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#upload_file)\n>\n> [**UploadFile (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.UploadFile)\n>\n> [**upload file (API)**](/docs/en/tools/api/#daytona-toolbox/tag/file-system/POST/files/upload)\n\n#### Upload multiple files\n\nDaytona provides methods to upload multiple files in sandboxes by providing the content to upload and their destination paths.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Upload multiple files at once\nfiles_to_upload = []\n\nwith open(\"file1.txt\", \"rb\") as f1:\n    files_to_upload.append(FileUpload(\n        source=f1.read(),\n        destination=\"data/file1.txt\",\n    ))\n\nwith open(\"file2.txt\", \"rb\") as f2:\n    files_to_upload.append(FileUpload(\n        source=f2.read(),\n        destination=\"data/file2.txt\",\n    ))\n\nwith open(\"settings.json\", \"rb\") as f3:\n    files_to_upload.append(FileUpload(\n        source=f3.read(),\n        destination=\"config/settings.json\",\n    ))\n\nsandbox.fs.upload_files(files_to_upload)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Upload multiple files at once\nconst files = [\n  {\n    source: Buffer.from('Content of file 1'),\n    destination: 'data/file1.txt',\n  },\n  {\n    source: Buffer.from('Content of file 2'),\n    destination: 'data/file2.txt',\n  },\n  {\n    source: Buffer.from('{\"key\": \"value\"}'),\n    destination: 'config/settings.json',\n  },\n]\n\nawait sandbox.fs.uploadFiles(files)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Upload multiple files\nfiles = [\n  FileUpload.new(\"Content of file 1\", \"/tmp/file1.txt\"),\n  FileUpload.new(\"workspace/data/file2.txt\", \"/tmp/file2.txt\"),\n  FileUpload.new('{\"key\": \"value\"}', \"/tmp/config.json\")\n]\n\nsandbox.fs.upload_files(files)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Upload multiple files by calling UploadFile for each\nfilesToUpload := []struct {\n\tsource      string\n\tdestination string\n}{\n\t{\"file1.txt\", \"data/file1.txt\"},\n\t{\"file2.txt\", \"data/file2.txt\"},\n\t{\"settings.json\", \"config/settings.json\"},\n}\n\nfor _, f := range filesToUpload {\n\terr := sandbox.FileSystem.UploadFile(ctx, f.source, f.destination)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/bulk-upload' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**upload_files (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemupload_files)\n>\n> [**uploadFiles (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#uploadfiles)\n>\n> [**upload_files (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#upload_files)\n>\n> [**upload multiple files (API)**](/docs/en/tools/api/#daytona-toolbox/tag/file-system/POST/files/bulk-upload)\n\n### Download files\n\nDaytona provides methods to download files from sandboxes.\n\n#### Download a single file\n\nDaytona provides methods to download a single file from sandboxes by providing the path to the file to download.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ncontent = sandbox.fs.download_file(\"file1.txt\")\n\nwith open(\"local_file.txt\", \"wb\") as f:\n    f.write(content)\n\nprint(content.decode('utf-8'))\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst downloadedFile = await sandbox.fs.downloadFile('file1.txt')\nconsole.log('File content:', downloadedFile.toString())\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Download and get file content\ncontent = sandbox.fs.download_file(\"workspace/data/file.txt\")\nputs content\n\n# Download and save a file locally\nsandbox.fs.download_file(\"workspace/data/file.txt\", \"local_copy.txt\")\nsize_mb = File.size(\"local_copy.txt\") / 1024.0 / 1024.0\nputs \"Size of the downloaded file: #{size_mb} MB\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Download and get contents in memory\ncontent, err := sandbox.FileSystem.DownloadFile(ctx, \"file1.txt\", nil)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Println(string(content))\n\n// Download and save to a local file\nlocalPath := \"local_file.txt\"\ncontent, err = sandbox.FileSystem.DownloadFile(ctx, \"file1.txt\", &localPath)\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/download?path='\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**download_file (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemdownload_file)\n>\n> [**downloadFile (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#downloadfile)\n>\n> [**download_file (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#download_file)\n>\n> [**DownloadFile (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.DownloadFile)\n>\n> [**download file (API)**](/docs/en/tools/api#daytona-toolbox/tag/file-system/GET/files/download)\n\n#### Download multiple files\n\nDaytona provides methods to download multiple files from sandboxes by providing the paths to the files to download.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Download multiple files at once\nfiles_to_download = [\n    FileDownloadRequest(source=\"data/file1.txt\"), # No destination - download to memory\n    FileDownloadRequest(source=\"data/file2.txt\", destination=\"local_file2.txt\"), # Download to local file\n]\n\nresults = sandbox.fs.download_files(files_to_download)\n\nfor result in results:\n    if result.error:\n        print(f\"Error downloading {result.source}: {result.error}\")\n    elif result.result:\n        print(f\"Downloaded {result.source} to {result.result}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Download multiple files at once\nconst files = [\n  { source: 'data/file1.txt' }, // No destination - download to memory\n  { source: 'data/file2.txt', destination: 'local_file2.txt' }, // Download to local file\n]\n\nconst results = await sandbox.fs.downloadFiles(files)\n\nresults.forEach(result => {\n  if (result.error) {\n    console.error(`Error downloading ${result.source}: ${result.error}`)\n  } else if (result.result) {\n    console.log(`Downloaded ${result.source} to ${result.result}`)\n  }\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Download multiple files by calling download_file for each\nfiles_to_download = [\n  { remote: \"data/file1.txt\", local: nil },              # Download to memory\n  { remote: \"data/file2.txt\", local: \"local_file2.txt\" } # Download to local file\n]\n\nfiles_to_download.each do |f|\n  if f[:local]\n    sandbox.fs.download_file(f[:remote], f[:local])\n    puts \"Downloaded #{f[:remote]} to #{f[:local]}\"\n  else\n    content = sandbox.fs.download_file(f[:remote])\n    puts \"Downloaded #{f[:remote]} to memory (#{content.size} bytes)\"\n  end\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Download multiple files by calling DownloadFile for each\nfilesToDownload := []struct {\n\tremotePath string\n\tlocalPath  *string\n}{\n\t{\"data/file1.txt\", nil},                           // Download to memory\n\t{\"data/file2.txt\", ptrString(\"local_file2.txt\")},  // Download to local file\n}\n\nfor _, f := range filesToDownload {\n\tcontent, err := sandbox.FileSystem.DownloadFile(ctx, f.remotePath, f.localPath)\n\tif err != nil {\n\t\tfmt.Printf(\"Error downloading %s: %v\\n\", f.remotePath, err)\n\t\tcontinue\n\t}\n\tif f.localPath == nil {\n\t\tfmt.Printf(\"Downloaded %s to memory (%d bytes)\\n\", f.remotePath, len(content))\n\t} else {\n\t\tfmt.Printf(\"Downloaded %s to %s\\n\", f.remotePath, *f.localPath)\n\t}\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/bulk-download' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"paths\": [\n    \"\"\n  ]\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**download_files (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemdownload_files)\n>\n> [**downloadFiles (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#downloadfiles)\n>\n> [**download_file (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#download_file)\n>\n> [**download multiple files (API)**](/docs/en/tools/api#daytona-toolbox/tag/file-system/POST/files/bulk-download)\n\n### Delete files\n\nDaytona provides methods to delete files or directories from sandboxes by providing the path to the file or directory to delete.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox.fs.delete_file(\"workspace/file.txt\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nawait sandbox.fs.deleteFile('workspace/file.txt')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Delete a file\nsandbox.fs.delete_file(\"workspace/data/old_file.txt\")\n\n# Delete a directory recursively\nsandbox.fs.delete_file(\"workspace/old_dir\", recursive: true)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Delete a file\nerr := sandbox.FileSystem.DeleteFile(ctx, \"workspace/file.txt\", false)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Delete a directory recursively\nerr = sandbox.FileSystem.DeleteFile(ctx, \"workspace/old_dir\", true)\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files?path=' \\\n  --request DELETE\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**delete_file (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemdelete_file)\n>\n> [**deleteFile (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#deletefile)\n>\n> [**delete_file (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#delete_file)\n>\n> [**DeleteFile (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.DeleteFile)\n>\n> [**delete file or directory (API)**](/docs/en/tools/api#daytona-toolbox/tag/file-system/DELETE/files)\n\n## Advanced operations\n\nDaytona provides advanced file system operations such as file permissions, search and replace, and move files.\n\n### File permissions\n\nDaytona provides methods to set file permissions, ownership, and group for a file or directory by providing the path to the file or directory and the permissions to set.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Set file permissions\nsandbox.fs.set_file_permissions(\"workspace/file.txt\", \"644\")\n\n# Get file permissions\nfile_info = sandbox.fs.get_file_info(\"workspace/file.txt\")\nprint(f\"Permissions: {file_info.permissions}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Set file permissions\nawait sandbox.fs.setFilePermissions('workspace/file.txt', { mode: '644' })\n\n// Get file permissions\nconst fileInfo = await sandbox.fs.getFileDetails('workspace/file.txt')\nconsole.log(`Permissions: ${fileInfo.permissions}`)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Make a file executable\nsandbox.fs.set_file_permissions(\n  path: \"workspace/scripts/run.sh\",\n  mode: \"755\"  # rwxr-xr-x\n)\n\n# Change file owner\nsandbox.fs.set_file_permissions(\n  path: \"workspace/data/file.txt\",\n  owner: \"daytona\",\n  group: \"daytona\"\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Set file permissions\nerr := sandbox.FileSystem.SetFilePermissions(ctx, \"workspace/file.txt\",\n\toptions.WithPermissionMode(\"644\"),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Set owner and group\nerr = sandbox.FileSystem.SetFilePermissions(ctx, \"workspace/file.txt\",\n\toptions.WithOwner(\"daytona\"),\n\toptions.WithGroup(\"daytona\"),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Get file info to check permissions\nfileInfo, err := sandbox.FileSystem.GetFileInfo(ctx, \"workspace/file.txt\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Mode: %s\\n\", fileInfo.Mode)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/permissions?path=' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**set_file_permissions (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemset_file_permissions)\n>\n> [**setFilePermissions (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#setfilepermissions)\n>\n> [**set_file_permissions (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#set_file_permissions)\n>\n> [**SetFilePermissions (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.SetFilePermissions)\n>\n> [**set file permissions (API)**](/docs/en/tools/api#daytona-toolbox/tag/file-system/POST/files/permissions)\n\n### Find and replace text in files\n\nDaytona provides methods to find and replace text in files by providing the path to the directory to search in and the pattern to search for.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Search for text in files by providing the path to the directory to search in and the pattern to search for\nresults = sandbox.fs.find_files(\n    path=\"workspace/src\",\n    pattern=\"text-of-interest\"\n)\nfor match in results:\n    print(f\"Absolute file path: {match.file}\")\n    print(f\"Line number: {match.line}\")\n    print(f\"Line content: {match.content}\")\n    print(\"\\n\")\n\n# Replace text in files\nsandbox.fs.replace_in_files(\n    files=[\"workspace/file1.txt\", \"workspace/file2.txt\"],\n    pattern=\"old_text\",\n    new_value=\"new_text\"\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Search for text in files; if a folder is specified, the search is recursive\nconst results = await sandbox.fs.findFiles({\n    path=\"workspace/src\",\n    pattern: \"text-of-interest\"\n})\nresults.forEach(match => {\n    console.log('Absolute file path:', match.file)\n    console.log('Line number:', match.line)\n    console.log('Line content:', match.content)\n})\n\n// Replace text in files\nawait sandbox.fs.replaceInFiles(\n    [\"workspace/file1.txt\", \"workspace/file2.txt\"],\n    \"old_text\",\n    \"new_text\"\n)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Search for TODOs in Ruby files\nmatches = sandbox.fs.find_files(\"workspace/src\", \"TODO:\")\nmatches.each do |match|\n  puts \"#{match.file}:#{match.line}: #{match.content.strip}\"\nend\n\n# Replace in specific files\nresults = sandbox.fs.replace_in_files(\n  files: [\"workspace/src/file1.rb\", \"workspace/src/file2.rb\"],\n  pattern: \"old_function\",\n  new_value: \"new_function\"\n)\n\n# Print results\nresults.each do |result|\n  if result.success\n    puts \"#{result.file}: #{result.success}\"\n  else\n    puts \"#{result.file}: #{result.error}\"\n  end\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Search for text in files\nresult, err := sandbox.FileSystem.FindFiles(ctx, \"workspace/src\", \"text-of-interest\")\nif err != nil {\n\tlog.Fatal(err)\n}\nmatches := result.([]map[string]any)\nfor _, match := range matches {\n\tfmt.Printf(\"Absolute file path: %s\\n\", match[\"file\"])\n\tfmt.Printf(\"Line number: %v\\n\", match[\"line\"])\n\tfmt.Printf(\"Line content: %s\\n\\n\", match[\"content\"])\n}\n\n// Replace text in files\n_, err = sandbox.FileSystem.ReplaceInFiles(ctx,\n\t[]string{\"workspace/file1.txt\", \"workspace/file2.txt\"},\n\t\"old_text\",\n\t\"new_text\",\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\nFind text in files:\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/find?path=&pattern='\n```\n\nReplace text in files:\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/replace' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"files\": [\n    \"\"\n  ],\n  \"newValue\": \"\",\n  \"pattern\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**find_files (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemfind_files)\n>\n> [**replace_in_files (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemreplace_in_files)\n>\n> [**findFiles (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#findfiles)\n>\n> [**replaceInFiles (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#replaceinfiles)\n>\n> [**find_files (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#find_files)\n>\n> [**replace_in_files (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#replace_in_files)\n>\n> [**FindFiles (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.FindFiles)\n>\n> [**ReplaceInFiles (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.ReplaceInFiles)\n>\n> [**find text in files (API)**](/docs/en/tools/api#daytona-toolbox/tag/file-system/GET/files/find)\n>\n> [**replace text in files (API)**](/docs/en/tools/api#daytona-toolbox/tag/file-system/POST/files/replace)\n\n### Move or rename directory or file\n\nDaytona provides methods to move or rename a directory or file in sandboxes by providing the path to the file or directory (source) and the new path to the file or directory (destination).\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Rename a file\nsandbox.fs.move_files(\n    \"workspace/data/old_name.txt\",\n    \"workspace/data/new_name.txt\"\n)\n\n# Move a file to a different directory\nsandbox.fs.move_files(\n    \"workspace/data/file.txt\",\n    \"workspace/archive/file.txt\"\n)\n\n# Move a directory\nsandbox.fs.move_files(\n    \"workspace/old_dir\",\n    \"workspace/new_dir\"\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Move a file to a new location\nawait fs.moveFiles('app/temp/data.json', 'app/data/data.json')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Rename a file\nsandbox.fs.move_files(\n  \"workspace/data/old_name.txt\",\n  \"workspace/data/new_name.txt\"\n)\n\n# Move a file to a different directory\nsandbox.fs.move_files(\n  \"workspace/data/file.txt\",\n  \"workspace/archive/file.txt\"\n)\n\n# Move a directory\nsandbox.fs.move_files(\n  \"workspace/old_dir\",\n  \"workspace/new_dir\"\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Rename a file\nerr := sandbox.FileSystem.MoveFiles(ctx, \"workspace/data/old_name.txt\", \"workspace/data/new_name.txt\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Move a file to a different directory\nerr = sandbox.FileSystem.MoveFiles(ctx, \"workspace/data/file.txt\", \"workspace/archive/file.txt\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Move a directory\nerr = sandbox.FileSystem.MoveFiles(ctx, \"workspace/old_dir\", \"workspace/new_dir\")\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/files/move?source=&destination=' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**move_files (Python SDK)**](/docs/en/python-sdk/sync/file-system/#filesystemmove_files)\n>\n> [**moveFiles (TypeScript SDK)**](/docs/en/typescript-sdk/file-system/#movefiles)\n>\n> [**move_files (Ruby SDK)**](/docs/en/ruby-sdk/file-system/#move_files)\n>\n> [**MoveFiles (Go SDK)**](/docs/en/go-sdk/daytona/#FileSystemService.MoveFiles)\n>\n> [**move or rename file or directory (API)**](/docs/en/tools/api/#daytona-toolbox/tag/file-system/POST/files/move)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/getting-started.mdx",
    "content": "---\ntitle: Getting Started\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nThis section introduces core concepts, common workflows, and next steps for using Daytona.\n\n## Dashboard\n\n[Daytona Dashboard ↗](https://app.daytona.io/) is a visual user interface where you can manage sandboxes, access API keys, view usage, and more.\nIt serves as the primary point of control for managing your Daytona resources.\n\n## SDKs\n\nDaytona provides [Python](/docs/en/python-sdk), [TypeScript](/docs/en/typescript-sdk), [Ruby](/docs/en/ruby-sdk), and [Go](/docs/en/go-sdk) SDKs to programmatically interact with sandboxes. They support sandbox lifecycle management, code execution, resource access, and more.\n\n## CLI\n\nDaytona provides command-line access to core features for interacting with Daytona Sandboxes, including managing their lifecycle, snapshots, and more.\n\nTo interact with Daytona Sandboxes from the command line, install the Daytona CLI:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Mac/Linux\">\n\n  ```bash\n  brew install daytonaio/cli/daytona\n  ```\n\n</TabItem>\n<TabItem label=\"Windows\">\n\n  ```bash\n  powershell -Command \"irm https://get.daytona.io/windows | iex\"\n  ```\n\n</TabItem>\n</Tabs>\n\nAfter installing the Daytona CLI, use the `daytona` command to interact with Daytona Sandboxes from the command line.\n\nTo upgrade the Daytona CLI to the latest version:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Mac/Linux\">\n\n```bash\nbrew upgrade daytonaio/cli/daytona\n```\n\n</TabItem>\n<TabItem label=\"Windows\">\n\n```bash\npowershell -Command \"irm https://get.daytona.io/windows | iex\"\n```\n\n</TabItem>\n</Tabs>\n\nTo view all available commands and flags, see the [CLI reference](/docs/en/tools/cli).\n\n## API\n\nDaytona provides a RESTful API for interacting with Daytona Sandboxes, including managing their lifecycle, snapshots, and more.\nIt serves as a flexible and powerful way to interact with Daytona from your own applications.\n\nTo interact with Daytona Sandboxes from the API, see the [API reference](/docs/en/tools/api).\n\n## MCP server\n\nDaytona provides a Model Context Protocol (MCP) server that enables AI agents to interact with Daytona Sandboxes programmatically. The MCP server integrates with popular AI agents including Claude, Cursor, and Windsurf.\n\nTo set up the MCP server with your AI agent:\n\n```bash\ndaytona mcp init [claude/cursor/windsurf]\n```\n\nFor more information, see the [MCP server documentation](/docs/en/mcp).\n\n## Multiple runtime support\n\nDaytona supports multiple programming language runtimes for direct code execution inside the sandbox.\n\n[TypeScript SDK](/docs/en/typescript-sdk) works across multiple **JavaScript runtimes** including **Node.js**, **browsers**, and **serverless platforms**: Cloudflare Workers, AWS Lambda, Azure Functions, etc.\n\nUsing the Daytona SDK in browser-based environments or frameworks like [**Vite**](/docs/en/getting-started#daytona-in-vite-projects) and [**Next.js**](/docs/en/getting-started#daytona-in-nextjs-projects) requires configuring node polyfills.\n\n### Daytona in Vite projects\n\nWhen using Daytona SDK in a Vite-based project, configure node polyfills to ensure compatibility.\n\nAdd the following configuration to your `vite.config.ts` file in the `plugins` array:\n\n```typescript\nimport { nodePolyfills } from 'vite-plugin-node-polyfills'\n\nexport default defineConfig({\n  plugins: [\n    // ... other plugins\n    nodePolyfills({\n      globals: { global: true, process: true, Buffer: true },\n      overrides: {\n        path: 'path-browserify-win32',\n      },\n    }),\n  ],\n  // ... rest of your config\n})\n```\n\n### Daytona in Next.js projects\n\nWhen using Daytona SDK in a Next.js project, configure node polyfills to ensure compatibility with Webpack and Turbopack bundlers.\n\nAdd the following configuration to your `next.config.ts` file:\n\n```typescript\nimport type { NextConfig } from 'next'\nimport NodePolyfillPlugin from 'node-polyfill-webpack-plugin'\nimport { env, nodeless } from 'unenv'\n\nconst { alias: turbopackAlias } = env(nodeless, {})\n\nconst nextConfig: NextConfig = {\n  // Turbopack\n  experimental: {\n    turbo: {\n      resolveAlias: {\n        ...turbopackAlias,\n      },\n    },\n  },\n  // Webpack\n  webpack: (config, { isServer }) => {\n    if (!isServer) {\n      config.plugins.push(new NodePolyfillPlugin())\n    }\n    return config\n  },\n}\n\nexport default nextConfig\n```\n\n## Guides\n\nDaytona provides a comprehensive set of guides to help you get started. The guides cover a wide range of topics, from basic usage to advanced topics, and showcase various types of integrations between Daytona and other tools.\n\nFor more information, see [guides](/docs/en/guides).\n\n## Examples\n\nDaytona provides quick examples for common sandbox operations and best practices. <br />\nThe examples are based on the Daytona [Python SDK](/docs/en/python-sdk/sync/process), [TypeScript SDK](/docs/en/typescript-sdk/process), [Go SDK](/docs/en/go-sdk/daytona#type-processservice), [Ruby SDK](/docs/en/ruby-sdk/process), [CLI](/docs/en/tools/cli), and [API](/docs/en/tools/api) references. More examples are available in the [GitHub repository ↗](https://github.com/daytonaio/daytona/tree/main/examples).\n\n### Create a sandbox\n\nCreate a [sandbox](/docs/en/sandboxes) with default settings.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona\n\ndaytona = Daytona()\nsandbox = daytona.create()\nprint(f\"Sandbox ID: {sandbox.id}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst sandbox = await daytona.create();\nconsole.log(`Sandbox ID: ${sandbox.id}`);\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n    client, err := daytona.NewClient()\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    sandbox, err := client.Create(context.Background(), nil)\n    if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Printf(\"Sandbox ID: %s\\n\", sandbox.ID)\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\nputs \"Sandbox ID: #{sandbox.id}\"\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona create\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{}'\n```\n\n</TabItem>\n</Tabs>\n\n### Create and run code in a sandbox\n\nCreate a [sandbox](/docs/en/sandboxes) and run code securely in it.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona\n\ndaytona = Daytona()\nsandbox = daytona.create()\nresponse = sandbox.process.exec(\"echo 'Hello, World!'\")\nprint(response.result)\nsandbox.delete()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst sandbox = await daytona.create();\nconst response = await sandbox.process.executeCommand('echo \"Hello, World!\"');\nconsole.log(response.result);\nawait sandbox.delete();\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n    client, err := daytona.NewClient()\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    sandbox, err := client.Create(context.Background(), nil)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    response, err := sandbox.Process.ExecuteCommand(context.Background(), \"echo 'Hello, World!'\")\n    if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Println(response.Result)\n    sandbox.Delete(context.Background())\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\nresponse = sandbox.process.exec(command: \"echo 'Hello, World!'\")\nputs response.result\ndaytona.delete(sandbox)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona create --name my-sandbox\ndaytona exec my-sandbox -- echo 'Hello, World!'\ndaytona delete my-sandbox\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\n# Create a sandbox\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{}'\n\n# Execute a command in the sandbox\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/execute' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"command\": \"echo '\\''Hello, World!'\\''\"\n}'\n\n# Delete the sandbox\ncurl 'https://app.daytona.io/api/sandbox/{sandboxId}' \\\n  --request DELETE \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\n### Create a sandbox with custom resources\n\nCreate a sandbox with [custom resources](/docs/en/sandboxes#resources) (CPU, memory, disk).\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, CreateSandboxFromImageParams, Image, Resources\n\ndaytona = Daytona()\nsandbox = daytona.create(\n    CreateSandboxFromImageParams(\n        image=Image.debian_slim(\"3.12\"),\n        resources=Resources(cpu=2, memory=4, disk=8)\n    )\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, Image } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst sandbox = await daytona.create({\n    image: Image.debianSlim('3.12'),\n    resources: { cpu: 2, memory: 4, disk: 8 }\n});\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n    client, err := daytona.NewClient()\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    sandbox, err := client.Create(context.Background(), types.ImageParams{\n        Image: daytona.DebianSlim(nil),\n        Resources: &types.Resources{\n            CPU:    2,\n            Memory: 4,\n            Disk:   8,\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create(\n    Daytona::CreateSandboxFromImageParams.new(\n        image: Daytona::Image.debian_slim('3.12'),\n        resources: Daytona::Resources.new(cpu: 2, memory: 4, disk: 8)\n    )\n)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona create --class small\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"cpu\": 2,\n  \"memory\": 4,\n  \"disk\": 8\n}'\n```\n\n</TabItem>\n</Tabs>\n\n### Create an ephemeral sandbox\n\nCreate an [ephemeral sandbox](/docs/en/sandboxes#ephemeral-sandboxes) that is automatically deleted when stopped.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, CreateSandboxFromSnapshotParams\n\ndaytona = Daytona()\nsandbox = daytona.create(\n    CreateSandboxFromSnapshotParams(ephemeral=True, auto_stop_interval=5)\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst sandbox = await daytona.create({\n    ephemeral: true,\n    autoStopInterval: 5\n});\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n    client, err := daytona.NewClient()\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    autoStop := 5\n    sandbox, err := client.Create(context.Background(), types.SnapshotParams{\n        SandboxBaseParams: types.SandboxBaseParams{\n            Ephemeral:        true,\n            AutoStopInterval: &autoStop,\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create(\n    Daytona::CreateSandboxFromSnapshotParams.new(ephemeral: true, auto_stop_interval: 5)\n)\n```\n\n</TabItem>\n\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona create --auto-stop 5 --auto-delete 0\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"autoStopInterval\": 5,\n  \"autoDeleteInterval\": 0\n}'\n```\n\n</TabItem>\n</Tabs>\n\n### Create a sandbox from a snapshot\n\nCreate a sandbox from a pre-built [snapshot](/docs/en/snapshots) for faster sandbox creation with pre-installed dependencies.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\nfrom daytona import Daytona, CreateSandboxFromSnapshotParams\n\ndaytona = Daytona()\nsandbox = daytona.create(\n    CreateSandboxFromSnapshotParams(\n        snapshot=\"my-snapshot-name\",\n        language=\"python\"\n    )\n)\n```\n\n</TabItem>\n\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst sandbox = await daytona.create({\n    snapshot: 'my-snapshot-name',\n    language: 'typescript'\n});\n```\n\n</TabItem>\n\n<TabItem label=\"Go\" icon=\"seti:go\">\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n    client, err := daytona.NewClient()\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    sandbox, err := client.Create(context.Background(), types.SnapshotParams{\n        Snapshot: \"my-snapshot-name\",\n        SandboxBaseParams: types.SandboxBaseParams{\n            Language: types.CodeLanguagePython,\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create(\n    Daytona::CreateSandboxFromSnapshotParams.new(\n        snapshot: 'my-snapshot-name',\n        language: Daytona::CodeLanguage::PYTHON\n    )\n)\n```\n\n</TabItem>\n\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n```shell\ndaytona create --snapshot my-snapshot-name\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"snapshot\": \"my-snapshot-name\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\n### Create a sandbox with a declarative image\n\nCreate a sandbox with a [declarative image](/docs/en/declarative-builder) that defines dependencies programmatically.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, CreateSandboxFromImageParams, Image\n\ndaytona = Daytona()\nimage = (\n    Image.debian_slim(\"3.12\")\n    .pip_install([\"requests\", \"pandas\", \"numpy\"])\n    .workdir(\"/home/daytona\")\n)\nsandbox = daytona.create(\n    CreateSandboxFromImageParams(image=image),\n    on_snapshot_create_logs=print\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, Image } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst image = Image.debianSlim('3.12')\n    .pipInstall(['requests', 'pandas', 'numpy'])\n    .workdir('/home/daytona');\nconst sandbox = await daytona.create(\n    { image },\n    { onSnapshotCreateLogs: console.log }\n);\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n    client, err := daytona.NewClient()\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    image := daytona.DebianSlim(nil).\n        PipInstall([]string{\"requests\", \"pandas\", \"numpy\"}).\n        Workdir(\"/home/daytona\")\n    sandbox, err := client.Create(context.Background(), types.ImageParams{\n        Image: image,\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nimage = Daytona::Image\n    .debian_slim('3.12')\n    .pip_install(['requests', 'pandas', 'numpy'])\n    .workdir('/home/daytona')\nsandbox = daytona.create(\n    Daytona::CreateSandboxFromImageParams.new(image: image),\n    on_snapshot_create_logs: proc { |chunk| puts chunk }\n)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona create --dockerfile ./Dockerfile\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"buildInfo\": {\n    \"dockerfileContent\": \"FROM python:3.12-slim\\nRUN pip install requests pandas numpy\\nWORKDIR /home/daytona\"\n  }\n}'\n```\n\n</TabItem>\n</Tabs>\n\n### Create a sandbox with volumes\n\nCreate a sandbox with a [volume](/docs/en/volumes) mounted to share data across sandboxes.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, CreateSandboxFromSnapshotParams, VolumeMount\n\ndaytona = Daytona()\nvolume = daytona.volume.get(\"my-volume\", create=True)\nsandbox = daytona.create(\n    CreateSandboxFromSnapshotParams(\n        volumes=[VolumeMount(volume_id=volume.id, mount_path=\"/home/daytona/data\")]\n    )\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst volume = await daytona.volume.get('my-volume', true);\nconst sandbox = await daytona.create({\n    volumes: [{ volumeId: volume.id, mountPath: '/home/daytona/data' }]\n});\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n    client, err := daytona.NewClient()\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    volume, err := client.Volume.Get(context.Background(), \"my-volume\")\n    if err != nil {\n        volume, err = client.Volume.Create(context.Background(), \"my-volume\")\n        if err != nil {\n            log.Fatal(err)\n        }\n    }\n\n    sandbox, err := client.Create(context.Background(), types.SnapshotParams{\n        SandboxBaseParams: types.SandboxBaseParams{\n            Volumes: []types.VolumeMount{{\n                VolumeID:  volume.ID,\n                MountPath: \"/home/daytona/data\",\n            }},\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nvolume = daytona.volume.get('my-volume', create: true)\nsandbox = daytona.create(\n    Daytona::CreateSandboxFromSnapshotParams.new(\n        volumes: [DaytonaApiClient::SandboxVolume.new(\n            volume_id: volume.id,\n            mount_path: '/home/daytona/data'\n        )]\n    )\n)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona volume create my-volume\ndaytona create --volume my-volume:/home/daytona/data\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"volumes\": [\n    {\n      \"volumeId\": \"<VOLUME_ID>\",\n      \"mountPath\": \"/home/daytona/data\"\n    }\n  ]\n}'\n```\n\n</TabItem>\n</Tabs>\n\n### Create a sandbox with a Git repository cloned\n\nCreate a sandbox with a [Git repository](/docs/en/typescript-sdk/git) cloned to manage version control.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona\n\ndaytona = Daytona()\nsandbox = daytona.create()\n\nsandbox.git.clone(\"https://github.com/daytonaio/daytona.git\", \"/home/daytona/daytona\")\nstatus = sandbox.git.status(\"/home/daytona/daytona\")\nprint(f\"Branch: {status.current_branch}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\nconst sandbox = await daytona.create();\n\nawait sandbox.git.clone('https://github.com/daytonaio/daytona.git', '/home/daytona/daytona');\nconst status = await sandbox.git.status('/home/daytona/daytona');\nconsole.log(`Branch: ${status.currentBranch}`);\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n    client, err := daytona.NewClient()\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    sandbox, err := client.Create(context.Background(), nil)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    sandbox.Git.Clone(context.Background(), \"https://github.com/daytonaio/daytona.git\", \"/home/daytona/daytona\")\n    status, err := sandbox.Git.Status(context.Background(), \"/home/daytona/daytona\")\n    if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Printf(\"Branch: %s\\n\", status.CurrentBranch)\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\n\nsandbox.git.clone(url: \"https://github.com/daytonaio/daytona.git\", path: \"/home/daytona/daytona\")\nstatus = sandbox.git.status(\"/home/daytona/daytona\")\nputs \"Branch: #{status.current_branch}\"\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\n# Create a sandbox\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{}'\n\n# Clone a Git repository in the sandbox\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/clone' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"url\": \"https://github.com/daytonaio/daytona.git\",\n  \"path\": \"/home/daytona/daytona\"\n}'\n\n# Get repository status\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/status?path=/home/daytona/daytona' \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/git-operations.mdx",
    "content": "---\ntitle: Git Operations\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona provides built-in Git support through the `git` module in sandboxes.\n\n## Basic operations\n\nDaytona provides methods to clone, check status, and manage Git repositories in sandboxes.\n\nSimilar to [file system operations](/docs/en/file-system-operations), the starting cloning directory is the current sandbox working directory. It uses the WORKDIR specified in the Dockerfile if present, or falls back to the user's home directory if not - e.g. `workspace/repo` implies `/my-work-dir/workspace/repo`, but you are free to provide an absolute `workDir` path as well (by starting the path with `/`).\n\n### Clone repositories\n\nDaytona provides methods to clone Git repositories into sandboxes. You can clone public or private repositories, specific branches, and authenticate using personal access tokens.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Basic clone\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# Clone with authentication\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\",\n    username=\"git\",\n    password=\"personal_access_token\"\n)\n\n# Clone specific branch\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\",\n    branch=\"develop\"\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Basic clone\nawait sandbox.git.clone(\n    \"https://github.com/user/repo.git\",\n    \"workspace/repo\"\n);\n\n// Clone with authentication\nawait sandbox.git.clone(\n    \"https://github.com/user/repo.git\",\n    \"workspace/repo\",\n    undefined,\n    undefined,\n    \"git\",\n    \"personal_access_token\"\n);\n\n// Clone specific branch\nawait sandbox.git.clone(\n    \"https://github.com/user/repo.git\",\n    \"workspace/repo\",\n    \"develop\"\n);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Basic clone\nsandbox.git.clone(\n  url: 'https://github.com/user/repo.git',\n  path: 'workspace/repo'\n)\n\n# Clone with authentication\nsandbox.git.clone(\n  url: 'https://github.com/user/repo.git',\n  path: 'workspace/repo',\n  username: 'git',\n  password: 'personal_access_token'\n)\n\n# Clone specific branch\nsandbox.git.clone(\n  url: 'https://github.com/user/repo.git',\n  path: 'workspace/repo',\n  branch: 'develop'\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Basic clone\nerr := sandbox.Git.Clone(ctx, \"https://github.com/user/repo.git\", \"workspace/repo\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Clone with authentication\nerr = sandbox.Git.Clone(ctx, \"https://github.com/user/repo.git\", \"workspace/repo\",\n\toptions.WithUsername(\"git\"),\n\toptions.WithPassword(\"personal_access_token\"),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Clone specific branch\nerr = sandbox.Git.Clone(ctx, \"https://github.com/user/repo.git\", \"workspace/repo\",\n\toptions.WithBranch(\"develop\"),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/clone' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"branch\": \"\",\n  \"commit_id\": \"\",\n  \"password\": \"\",\n  \"path\": \"\",\n  \"url\": \"\",\n  \"username\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**clone (Python SDK)**](/docs/en/python-sdk/sync/git/#gitclone)\n>\n> [**clone (TypeScript SDK)**](/docs/en/typescript-sdk/git/#clone)\n>\n> [**clone (Ruby SDK)**](/docs/en/ruby-sdk/git/#clone)\n>\n> [**Clone (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.Clone)\n>\n> [**clone repository (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/POST/git/clone)\n\n### Get repository status\n\nDaytona provides methods to check the status of Git repositories in sandboxes. You can get the current branch, modified files, number of commits ahead and behind main branch.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Get repository status\nstatus = sandbox.git.status(\"workspace/repo\")\nprint(f\"Current branch: {status.current_branch}\")\nprint(f\"Commits ahead: {status.ahead}\")\nprint(f\"Commits behind: {status.behind}\")\nfor file in status.file_status:\n    print(f\"File: {file.name}\")\n\n# List branches\nresponse = sandbox.git.branches(\"workspace/repo\")\nfor branch in response.branches:\n    print(f\"Branch: {branch}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Get repository status\nconst status = await sandbox.git.status(\"workspace/repo\");\nconsole.log(`Current branch: ${status.currentBranch}`);\nconsole.log(`Commits ahead: ${status.ahead}`);\nconsole.log(`Commits behind: ${status.behind}`);\nstatus.fileStatus.forEach(file => {\n    console.log(`File: ${file.name}`);\n});\n\n// List branches\nconst response = await sandbox.git.branches(\"workspace/repo\");\nresponse.branches.forEach(branch => {\n    console.log(`Branch: ${branch}`);\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Get repository status\nstatus = sandbox.git.status('workspace/repo')\nputs \"Current branch: #{status.current_branch}\"\nputs \"Commits ahead: #{status.ahead}\"\nputs \"Commits behind: #{status.behind}\"\nstatus.file_status.each do |file|\n  puts \"File: #{file.name}\"\nend\n\n# List branches\nresponse = sandbox.git.branches('workspace/repo')\nresponse.branches.each do |branch|\n  puts \"Branch: #{branch}\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Get repository status\nstatus, err := sandbox.Git.Status(ctx, \"workspace/repo\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Current branch: %s\\n\", status.CurrentBranch)\nfmt.Printf(\"Commits ahead: %d\\n\", status.Ahead)\nfmt.Printf(\"Commits behind: %d\\n\", status.Behind)\nfor _, file := range status.FileStatus {\n\tfmt.Printf(\"File: %s\\n\", file.Path)\n}\n\n// List branches\nbranches, err := sandbox.Git.Branches(ctx, \"workspace/repo\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfor _, branch := range branches {\n\tfmt.Printf(\"Branch: %s\\n\", branch)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/status?path='\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**status (Python SDK)**](/docs/en/python-sdk/sync/git/#gitstatus)\n>\n> [**status (TypeScript SDK)**](/docs/en/typescript-sdk/git/#status)\n>\n> [**status (Ruby SDK)**](/docs/en/ruby-sdk/git/#status)\n>\n> [**Status (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.Status)\n>\n> [**get Git repository status (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/GET/git/status)\n\n## Branch operations\n\nDaytona provides methods to manage branches in Git repositories. You can create, switch, and delete branches.\n\n### Create branches\n\nDaytona provides methods to create branches in Git repositories. The following snippet creates a new branch called `new-feature`.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Create a new branch\nsandbox.git.create_branch(\"workspace/repo\", \"new-feature\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Create new branch\nawait git.createBranch('workspace/repo', 'new-feature');\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Create a new branch\nsandbox.git.create_branch('workspace/repo', 'new-feature')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a new branch\nerr := sandbox.Git.CreateBranch(ctx, \"workspace/repo\", \"new-feature\")\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/branches' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"name\": \"\",\n  \"path\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**create_branch (Python SDK)**](/docs/en/python-sdk/sync/git/#gitcreate_branch)\n>\n> [**createBranch (TypeScript SDK)**](/docs/en/typescript-sdk/git/#createbranch)\n>\n> [**create_branch (Ruby SDK)**](/docs/en/ruby-sdk/git/#create_branch)\n>\n> [**CreateBranch (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.CreateBranch)\n>\n> [**create branch (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/POST/git/branches)\n\n### Checkout branches\n\nDaytona provides methods to checkout branches in Git repositories. The following snippet checks out the branch called `feature-branch`.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Checkout a branch\nsandbox.git.checkout_branch(\"workspace/repo\", \"feature-branch\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Checkout a branch\nawait git.checkoutBranch('workspace/repo', 'feature-branch');\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Checkout a branch\nsandbox.git.checkout_branch('workspace/repo', 'feature-branch')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Checkout a branch\nerr := sandbox.Git.Checkout(ctx, \"workspace/repo\", \"feature-branch\")\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/checkout' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"branch\": \"\",\n  \"path\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**checkout_branch (Python SDK)**](/docs/en/python-sdk/sync/git/#gitcheckout_branch)\n>\n> [**checkoutBranch (TypeScript SDK)**](/docs/en/typescript-sdk/git/#checkoutbranch)\n>\n> [**checkout_branch (Ruby SDK)**](/docs/en/ruby-sdk/git/#checkout_branch)\n>\n> [**Checkout (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.Checkout)\n>\n> [**checkout branch (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/POST/git/checkout)\n\n### Delete branches\n\nDaytona provides methods to delete branches in Git repositories. The following snippet deletes the branch called `old-feature`.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Delete a branch\nsandbox.git.delete_branch(\"workspace/repo\", \"old-feature\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Delete a branch\nawait git.deleteBranch('workspace/repo', 'old-feature');\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Delete a branch\nsandbox.git.delete_branch('workspace/repo', 'old-feature')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Delete a branch\nerr := sandbox.Git.DeleteBranch(ctx, \"workspace/repo\", \"old-feature\")\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/branches' \\\n  --request DELETE \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"name\": \"\",\n  \"path\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**delete_branch (Python SDK)**](/docs/en/python-sdk/sync/git/#gitdelete_branch)\n>\n> [**deleteBranch (TypeScript SDK)**](/docs/en/typescript-sdk/git/#deletebranch)\n>\n> [**delete_branch (Ruby SDK)**](/docs/en/ruby-sdk/git/#delete_branch)\n>\n> [**DeleteBranch (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.DeleteBranch)\n>\n> [**delete branch (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/DELETE/git/branches)\n\n## Stage changes\n\nDaytona provides methods to stage changes in Git repositories. You can stage specific files, all changes, and commit with a message. The following snippet stages the file `file.txt` and the `src` directory.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Stage a single file\nsandbox.git.add(\"workspace/repo\", [\"file.txt\"])\n\n# Stage multiple files\nsandbox.git.add(\"workspace/repo\", [\n    \"src/main.py\",\n    \"tests/test_main.py\",\n    \"README.md\"\n])\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Stage a single file\nawait git.add('workspace/repo', ['file.txt']);\n// Stage whole repository\nawait git.add('workspace/repo', ['.']);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Stage a single file\nsandbox.git.add('workspace/repo', ['file.txt'])\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Stage a single file\nerr := sandbox.Git.Add(ctx, \"workspace/repo\", []string{\"file.txt\"})\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Stage multiple files\nerr = sandbox.Git.Add(ctx, \"workspace/repo\", []string{\n\t\"src/main.py\",\n\t\"tests/test_main.py\",\n\t\"README.md\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Stage whole repository\nerr = sandbox.Git.Add(ctx, \"workspace/repo\", []string{\".\"})\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/add' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"files\": [\n    \"\"\n  ],\n  \"path\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**add (Python SDK)**](/docs/en/python-sdk/sync/git/#gitadd)\n>\n> [**add (TypeScript SDK)**](/docs/en/typescript-sdk/git/#add)\n>\n> [**add (Ruby SDK)**](/docs/en/ruby-sdk/git/#add)\n>\n> [**Add (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.Add)\n>\n> [**add (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/POST/git/add)\n\n## Commit changes\n\nDaytona provides methods to commit changes in Git repositories. You can commit with a message, author, and email. The following snippet commits the changes with the message `Update documentation` and the author `John Doe` and email `john@example.com`.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Stage and commit changes\nsandbox.git.add(\"workspace/repo\", [\"README.md\"])\nsandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update documentation\",\n    author=\"John Doe\",\n    email=\"john@example.com\",\n    allow_empty=True\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Stage and commit changes\nawait git.add('workspace/repo', ['README.md']);\nawait git.commit(\n  'workspace/repo',\n  'Update documentation',\n  'John Doe',\n  'john@example.com',\n  true\n);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Stage and commit changes\nsandbox.git.add('workspace/repo', ['README.md'])\nsandbox.git.commit('workspace/repo', 'Update documentation', 'John Doe', 'john@example.com', true)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Stage and commit changes\nerr := sandbox.Git.Add(ctx, \"workspace/repo\", []string{\"README.md\"})\nif err != nil {\n\tlog.Fatal(err)\n}\n\nresponse, err := sandbox.Git.Commit(ctx, \"workspace/repo\",\n\t\"Update documentation\",\n\t\"John Doe\",\n\t\"john@example.com\",\n\toptions.WithAllowEmpty(true),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Commit SHA: %s\\n\", response.SHA)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/commit' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"allow_empty\": true,\n  \"author\": \"\",\n  \"email\": \"\",\n  \"message\": \"\",\n  \"path\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**commit (Python SDK)**](/docs/en/python-sdk/sync/git/#gitcommit)\n>\n> [**commit (TypeScript SDK)**](/docs/en/typescript-sdk/git/#commit)\n>\n> [**commit (Ruby SDK)**](/docs/en/ruby-sdk/git/#commit)\n>\n> [**Commit (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.Commit)\n>\n> [**commit (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/POST/git/commit)\n\n## Remote operations\n\nDaytona provides methods to work with remote repositories in Git. You can push and pull changes from remote repositories.\n\n### Push changes\n\nDaytona provides methods to push changes to remote repositories. The following snippet pushes the changes to a public repository.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Push without authentication (for public repos or SSH)\nsandbox.git.push(\"workspace/repo\")\n\n# Push with authentication\nsandbox.git.push(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Push to a public repository\nawait git.push('workspace/repo');\n\n// Push to a private repository\nawait git.push(\n  'workspace/repo',\n  'user',\n  'token'\n);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\n# Push changes\nsandbox.git.push('workspace/repo')\n```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Push without authentication (for public repos or SSH)\nerr := sandbox.Git.Push(ctx, \"workspace/repo\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Push with authentication\nerr = sandbox.Git.Push(ctx, \"workspace/repo\",\n\toptions.WithPushUsername(\"user\"),\n\toptions.WithPushPassword(\"github_token\"),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/push' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"password\": \"\",\n  \"path\": \"\",\n  \"username\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**push (Python SDK)**](/docs/en/python-sdk/sync/git/#gitpush)\n>\n> [**push (TypeScript SDK)**](/docs/en/typescript-sdk/git/#push)\n>\n> [**push (Ruby SDK)**](/docs/en/ruby-sdk/git/#push)\n>\n> [**Push (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.Push)\n>\n> [**push (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/POST/git/push)\n\n### Pull changes\n\nDaytona provides methods to pull changes from remote repositories. The following snippet pulls the changes from a public repository.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Pull without authentication\nsandbox.git.pull(\"workspace/repo\")\n\n# Pull with authentication\nsandbox.git.pull(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Pull from a public repository\nawait git.pull('workspace/repo');\n\n// Pull from a private repository\nawait git.pull(\n  'workspace/repo',\n  'user',\n  'token'\n);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Pull changes\nsandbox.git.pull('workspace/repo')\n```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Pull without authentication\nerr := sandbox.Git.Pull(ctx, \"workspace/repo\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Pull with authentication\nerr = sandbox.Git.Pull(ctx, \"workspace/repo\",\n\toptions.WithPullUsername(\"user\"),\n\toptions.WithPullPassword(\"github_token\"),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/git/pull' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"password\": \"\",\n  \"path\": \"\",\n  \"username\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/git), [TypeScript SDK](/docs/en/typescript-sdk/git), [Ruby SDK](/docs/en/ruby-sdk/git), [Go SDK](/docs/en/go-sdk/) and [API](/docs/en/tools/api/#daytona-toolbox) references:\n\n> [**pull (Python SDK)**](/docs/en/python-sdk/sync/git/#gitpull)\n>\n> [**pull (TypeScript SDK)**](/docs/en/typescript-sdk/git/#pull)\n>\n> [**pull (Ruby SDK)**](/docs/en/ruby-sdk/git/#pull)\n>\n> [**Pull (Go SDK)**](/docs/en/go-sdk/daytona/#GitService.Pull)\n>\n> [**pull (API)**](/docs/en/tools/api/#daytona-toolbox/tag/git/POST/git/pull)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/go-sdk/daytona.mdx",
    "content": "---\ntitle: \"daytona\"\nhideTitleOnPage: true\n---\n\n{/* Code generated by gomarkdoc. DO NOT EDIT */}\n# daytona\n\n```go\nimport \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n```\n\nPackage daytona provides a Go SDK for interacting with the Daytona platform.\n\nThe Daytona SDK enables developers to programmatically create, manage, and interact with sandboxes \\- isolated development environments that can run code, execute commands, and manage files.\n\n### Getting Started\n\nCreate a client using your API key or JWT token:\n\n```\nclient, err := daytona.NewClient()\nif err != nil {\n    log.Fatal(err)\n}\n```\n\nThe client reads configuration from environment variables:\n\n- DAYTONA\\_API\\_KEY: API key for authentication\n- DAYTONA\\_JWT\\_TOKEN: JWT token for authentication \\(alternative to API key\\)\n- DAYTONA\\_ORGANIZATION\\_ID: Organization ID \\(required when using JWT token\\)\n- DAYTONA\\_API\\_URL: API URL \\(defaults to https://app.daytona.io/api\\)\n- DAYTONA\\_TARGET: Target environment\n\nOr provide configuration explicitly:\n\n```\nclient, err := daytona.NewClientWithConfig(&types.DaytonaConfig{\n    APIKey: \"your-api-key\",\n    APIUrl: \"https://your-instance.daytona.io/api\",\n})\n```\n\n### Creating Sandboxes\n\nCreate a sandbox from a snapshot:\n\n```\nsandbox, err := client.Create(ctx, types.SnapshotParams{\n    Snapshot: \"my-snapshot\",\n})\n```\n\nCreate a sandbox from a Docker image:\n\n```\nsandbox, err := client.Create(ctx, types.ImageParams{\n    Image: \"python:3.11\",\n})\n```\n\n### Working with Sandboxes\n\nExecute code in a sandbox:\n\n```\nresult, err := sandbox.Process.CodeRun(ctx, \"print('Hello, World!')\")\n```\n\nRun shell commands:\n\n```\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"ls -la\")\n```\n\n## Index\n\n- [Variables](<#variables>)\n- [type Client](<#Client>)\n  - [func NewClient\\(\\) \\(\\*Client, error\\)](<#NewClient>)\n  - [func NewClientWithConfig\\(config \\*types.DaytonaConfig\\) \\(\\*Client, error\\)](<#NewClientWithConfig>)\n  - [func \\(c \\*Client\\) Close\\(ctx context.Context\\) error](<#Client.Close>)\n  - [func \\(c \\*Client\\) Create\\(ctx context.Context, params any, opts ...func\\(\\*options.CreateSandbox\\)\\) \\(\\*Sandbox, error\\)](<#Client.Create>)\n  - [func \\(c \\*Client\\) Get\\(ctx context.Context, sandboxIDOrName string\\) \\(\\*Sandbox, error\\)](<#Client.Get>)\n  - [func \\(c \\*Client\\) List\\(ctx context.Context, labels map\\[string\\]string, page \\*int, limit \\*int\\) \\(\\*PaginatedSandboxes, error\\)](<#Client.List>)\n- [type CodeInterpreterService](<#CodeInterpreterService>)\n  - [func NewCodeInterpreterService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*CodeInterpreterService](<#NewCodeInterpreterService>)\n  - [func \\(c \\*CodeInterpreterService\\) CreateContext\\(ctx context.Context, cwd \\*string\\) \\(map\\[string\\]any, error\\)](<#CodeInterpreterService.CreateContext>)\n  - [func \\(c \\*CodeInterpreterService\\) DeleteContext\\(ctx context.Context, contextID string\\) error](<#CodeInterpreterService.DeleteContext>)\n  - [func \\(c \\*CodeInterpreterService\\) ListContexts\\(ctx context.Context\\) \\(\\[\\]map\\[string\\]any, error\\)](<#CodeInterpreterService.ListContexts>)\n  - [func \\(c \\*CodeInterpreterService\\) RunCode\\(ctx context.Context, code string, opts ...func\\(\\*options.RunCode\\)\\) \\(\\*OutputChannels, error\\)](<#CodeInterpreterService.RunCode>)\n- [type ComputerUseService](<#ComputerUseService>)\n  - [func NewComputerUseService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*ComputerUseService](<#NewComputerUseService>)\n  - [func \\(c \\*ComputerUseService\\) Display\\(\\) \\*DisplayService](<#ComputerUseService.Display>)\n  - [func \\(c \\*ComputerUseService\\) GetStatus\\(ctx context.Context\\) \\(map\\[string\\]any, error\\)](<#ComputerUseService.GetStatus>)\n  - [func \\(c \\*ComputerUseService\\) Keyboard\\(\\) \\*KeyboardService](<#ComputerUseService.Keyboard>)\n  - [func \\(c \\*ComputerUseService\\) Mouse\\(\\) \\*MouseService](<#ComputerUseService.Mouse>)\n  - [func \\(c \\*ComputerUseService\\) Recording\\(\\) \\*RecordingService](<#ComputerUseService.Recording>)\n  - [func \\(c \\*ComputerUseService\\) Screenshot\\(\\) \\*ScreenshotService](<#ComputerUseService.Screenshot>)\n  - [func \\(c \\*ComputerUseService\\) Start\\(ctx context.Context\\) error](<#ComputerUseService.Start>)\n  - [func \\(c \\*ComputerUseService\\) Stop\\(ctx context.Context\\) error](<#ComputerUseService.Stop>)\n- [type DisplayService](<#DisplayService>)\n  - [func NewDisplayService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*DisplayService](<#NewDisplayService>)\n  - [func \\(d \\*DisplayService\\) GetInfo\\(ctx context.Context\\) \\(map\\[string\\]any, error\\)](<#DisplayService.GetInfo>)\n  - [func \\(d \\*DisplayService\\) GetWindows\\(ctx context.Context\\) \\(map\\[string\\]any, error\\)](<#DisplayService.GetWindows>)\n- [type DockerImage](<#DockerImage>)\n  - [func Base\\(baseImage string\\) \\*DockerImage](<#Base>)\n  - [func DebianSlim\\(pythonVersion \\*string\\) \\*DockerImage](<#DebianSlim>)\n  - [func FromDockerfile\\(dockerfile string\\) \\*DockerImage](<#FromDockerfile>)\n  - [func \\(img \\*DockerImage\\) Add\\(source, destination string\\) \\*DockerImage](<#DockerImage.Add>)\n  - [func \\(img \\*DockerImage\\) AddLocalDir\\(localPath, remotePath string\\) \\*DockerImage](<#DockerImage.AddLocalDir>)\n  - [func \\(img \\*DockerImage\\) AddLocalFile\\(localPath, remotePath string\\) \\*DockerImage](<#DockerImage.AddLocalFile>)\n  - [func \\(img \\*DockerImage\\) AptGet\\(packages \\[\\]string\\) \\*DockerImage](<#DockerImage.AptGet>)\n  - [func \\(img \\*DockerImage\\) Cmd\\(cmd \\[\\]string\\) \\*DockerImage](<#DockerImage.Cmd>)\n  - [func \\(img \\*DockerImage\\) Contexts\\(\\) \\[\\]DockerImageContext](<#DockerImage.Contexts>)\n  - [func \\(img \\*DockerImage\\) Copy\\(source, destination string\\) \\*DockerImage](<#DockerImage.Copy>)\n  - [func \\(img \\*DockerImage\\) Dockerfile\\(\\) string](<#DockerImage.Dockerfile>)\n  - [func \\(img \\*DockerImage\\) Entrypoint\\(cmd \\[\\]string\\) \\*DockerImage](<#DockerImage.Entrypoint>)\n  - [func \\(img \\*DockerImage\\) Env\\(key, value string\\) \\*DockerImage](<#DockerImage.Env>)\n  - [func \\(img \\*DockerImage\\) Expose\\(ports \\[\\]int\\) \\*DockerImage](<#DockerImage.Expose>)\n  - [func \\(img \\*DockerImage\\) Label\\(key, value string\\) \\*DockerImage](<#DockerImage.Label>)\n  - [func \\(img \\*DockerImage\\) PipInstall\\(packages \\[\\]string, opts ...func\\(\\*options.PipInstall\\)\\) \\*DockerImage](<#DockerImage.PipInstall>)\n  - [func \\(img \\*DockerImage\\) Run\\(command string\\) \\*DockerImage](<#DockerImage.Run>)\n  - [func \\(img \\*DockerImage\\) User\\(username string\\) \\*DockerImage](<#DockerImage.User>)\n  - [func \\(img \\*DockerImage\\) Volume\\(paths \\[\\]string\\) \\*DockerImage](<#DockerImage.Volume>)\n  - [func \\(img \\*DockerImage\\) Workdir\\(path string\\) \\*DockerImage](<#DockerImage.Workdir>)\n- [type DockerImageContext](<#DockerImageContext>)\n- [type FileSystemService](<#FileSystemService>)\n  - [func NewFileSystemService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*FileSystemService](<#NewFileSystemService>)\n  - [func \\(f \\*FileSystemService\\) CreateFolder\\(ctx context.Context, path string, opts ...func\\(\\*options.CreateFolder\\)\\) error](<#FileSystemService.CreateFolder>)\n  - [func \\(f \\*FileSystemService\\) DeleteFile\\(ctx context.Context, path string, recursive bool\\) error](<#FileSystemService.DeleteFile>)\n  - [func \\(f \\*FileSystemService\\) DownloadFile\\(ctx context.Context, remotePath string, localPath \\*string\\) \\(\\[\\]byte, error\\)](<#FileSystemService.DownloadFile>)\n  - [func \\(f \\*FileSystemService\\) FindFiles\\(ctx context.Context, path, pattern string\\) \\(any, error\\)](<#FileSystemService.FindFiles>)\n  - [func \\(f \\*FileSystemService\\) GetFileInfo\\(ctx context.Context, path string\\) \\(\\*types.FileInfo, error\\)](<#FileSystemService.GetFileInfo>)\n  - [func \\(f \\*FileSystemService\\) ListFiles\\(ctx context.Context, path string\\) \\(\\[\\]\\*types.FileInfo, error\\)](<#FileSystemService.ListFiles>)\n  - [func \\(f \\*FileSystemService\\) MoveFiles\\(ctx context.Context, source, destination string\\) error](<#FileSystemService.MoveFiles>)\n  - [func \\(f \\*FileSystemService\\) ReplaceInFiles\\(ctx context.Context, files \\[\\]string, pattern, newValue string\\) \\(any, error\\)](<#FileSystemService.ReplaceInFiles>)\n  - [func \\(f \\*FileSystemService\\) SearchFiles\\(ctx context.Context, path, pattern string\\) \\(any, error\\)](<#FileSystemService.SearchFiles>)\n  - [func \\(f \\*FileSystemService\\) SetFilePermissions\\(ctx context.Context, path string, opts ...func\\(\\*options.SetFilePermissions\\)\\) error](<#FileSystemService.SetFilePermissions>)\n  - [func \\(f \\*FileSystemService\\) UploadFile\\(ctx context.Context, source any, destination string\\) error](<#FileSystemService.UploadFile>)\n- [type GitService](<#GitService>)\n  - [func NewGitService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*GitService](<#NewGitService>)\n  - [func \\(g \\*GitService\\) Add\\(ctx context.Context, path string, files \\[\\]string\\) error](<#GitService.Add>)\n  - [func \\(g \\*GitService\\) Branches\\(ctx context.Context, path string\\) \\(\\[\\]string, error\\)](<#GitService.Branches>)\n  - [func \\(g \\*GitService\\) Checkout\\(ctx context.Context, path, name string\\) error](<#GitService.Checkout>)\n  - [func \\(g \\*GitService\\) Clone\\(ctx context.Context, url, path string, opts ...func\\(\\*options.GitClone\\)\\) error](<#GitService.Clone>)\n  - [func \\(g \\*GitService\\) Commit\\(ctx context.Context, path, message, author, email string, opts ...func\\(\\*options.GitCommit\\)\\) \\(\\*types.GitCommitResponse, error\\)](<#GitService.Commit>)\n  - [func \\(g \\*GitService\\) CreateBranch\\(ctx context.Context, path, name string\\) error](<#GitService.CreateBranch>)\n  - [func \\(g \\*GitService\\) DeleteBranch\\(ctx context.Context, path, name string, opts ...func\\(\\*options.GitDeleteBranch\\)\\) error](<#GitService.DeleteBranch>)\n  - [func \\(g \\*GitService\\) Pull\\(ctx context.Context, path string, opts ...func\\(\\*options.GitPull\\)\\) error](<#GitService.Pull>)\n  - [func \\(g \\*GitService\\) Push\\(ctx context.Context, path string, opts ...func\\(\\*options.GitPush\\)\\) error](<#GitService.Push>)\n  - [func \\(g \\*GitService\\) Status\\(ctx context.Context, path string\\) \\(\\*types.GitStatus, error\\)](<#GitService.Status>)\n- [type KeyboardService](<#KeyboardService>)\n  - [func NewKeyboardService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*KeyboardService](<#NewKeyboardService>)\n  - [func \\(k \\*KeyboardService\\) Hotkey\\(ctx context.Context, keys string\\) error](<#KeyboardService.Hotkey>)\n  - [func \\(k \\*KeyboardService\\) Press\\(ctx context.Context, key string, modifiers \\[\\]string\\) error](<#KeyboardService.Press>)\n  - [func \\(k \\*KeyboardService\\) Type\\(ctx context.Context, text string, delay \\*int\\) error](<#KeyboardService.Type>)\n- [type LspServerService](<#LspServerService>)\n  - [func NewLspServerService\\(toolboxClient \\*toolbox.APIClient, languageID types.LspLanguageID, projectPath string, otel \\*otelState\\) \\*LspServerService](<#NewLspServerService>)\n  - [func \\(l \\*LspServerService\\) Completions\\(ctx context.Context, path string, position types.Position\\) \\(any, error\\)](<#LspServerService.Completions>)\n  - [func \\(l \\*LspServerService\\) DidClose\\(ctx context.Context, path string\\) error](<#LspServerService.DidClose>)\n  - [func \\(l \\*LspServerService\\) DidOpen\\(ctx context.Context, path string\\) error](<#LspServerService.DidOpen>)\n  - [func \\(l \\*LspServerService\\) DocumentSymbols\\(ctx context.Context, path string\\) \\(\\[\\]any, error\\)](<#LspServerService.DocumentSymbols>)\n  - [func \\(l \\*LspServerService\\) SandboxSymbols\\(ctx context.Context, query string\\) \\(\\[\\]any, error\\)](<#LspServerService.SandboxSymbols>)\n  - [func \\(l \\*LspServerService\\) Start\\(ctx context.Context\\) error](<#LspServerService.Start>)\n  - [func \\(l \\*LspServerService\\) Stop\\(ctx context.Context\\) error](<#LspServerService.Stop>)\n- [type MouseService](<#MouseService>)\n  - [func NewMouseService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*MouseService](<#NewMouseService>)\n  - [func \\(m \\*MouseService\\) Click\\(ctx context.Context, x, y int, button \\*string, double \\*bool\\) \\(map\\[string\\]any, error\\)](<#MouseService.Click>)\n  - [func \\(m \\*MouseService\\) Drag\\(ctx context.Context, startX, startY, endX, endY int, button \\*string\\) \\(map\\[string\\]any, error\\)](<#MouseService.Drag>)\n  - [func \\(m \\*MouseService\\) GetPosition\\(ctx context.Context\\) \\(map\\[string\\]any, error\\)](<#MouseService.GetPosition>)\n  - [func \\(m \\*MouseService\\) Move\\(ctx context.Context, x, y int\\) \\(map\\[string\\]any, error\\)](<#MouseService.Move>)\n  - [func \\(m \\*MouseService\\) Scroll\\(ctx context.Context, x, y int, direction string, amount \\*int\\) \\(bool, error\\)](<#MouseService.Scroll>)\n- [type OutputChannels](<#OutputChannels>)\n- [type PaginatedSandboxes](<#PaginatedSandboxes>)\n- [type ProcessService](<#ProcessService>)\n  - [func NewProcessService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*ProcessService](<#NewProcessService>)\n  - [func \\(p \\*ProcessService\\) CodeRun\\(ctx context.Context, code string, opts ...func\\(\\*options.CodeRun\\)\\) \\(\\*types.ExecuteResponse, error\\)](<#ProcessService.CodeRun>)\n  - [func \\(p \\*ProcessService\\) ConnectPty\\(ctx context.Context, sessionID string\\) \\(\\*PtyHandle, error\\)](<#ProcessService.ConnectPty>)\n  - [func \\(p \\*ProcessService\\) CreatePty\\(ctx context.Context, id string, opts ...func\\(\\*options.CreatePty\\)\\) \\(\\*PtyHandle, error\\)](<#ProcessService.CreatePty>)\n  - [func \\(p \\*ProcessService\\) CreatePtySession\\(ctx context.Context, id string, opts ...func\\(\\*options.PtySession\\)\\) \\(\\*types.PtySessionInfo, error\\)](<#ProcessService.CreatePtySession>)\n  - [func \\(p \\*ProcessService\\) CreateSession\\(ctx context.Context, sessionID string\\) error](<#ProcessService.CreateSession>)\n  - [func \\(p \\*ProcessService\\) DeleteSession\\(ctx context.Context, sessionID string\\) error](<#ProcessService.DeleteSession>)\n  - [func \\(p \\*ProcessService\\) ExecuteCommand\\(ctx context.Context, command string, opts ...func\\(\\*options.ExecuteCommand\\)\\) \\(\\*types.ExecuteResponse, error\\)](<#ProcessService.ExecuteCommand>)\n  - [func \\(p \\*ProcessService\\) ExecuteSessionCommand\\(ctx context.Context, sessionID, command string, runAsync bool, suppressInputEcho bool\\) \\(map\\[string\\]any, error\\)](<#ProcessService.ExecuteSessionCommand>)\n  - [func \\(p \\*ProcessService\\) GetEntrypointLogs\\(ctx context.Context\\) \\(string, error\\)](<#ProcessService.GetEntrypointLogs>)\n  - [func \\(p \\*ProcessService\\) GetEntrypointLogsStream\\(ctx context.Context, stdout, stderr chan\\<\\- string\\) error](<#ProcessService.GetEntrypointLogsStream>)\n  - [func \\(p \\*ProcessService\\) GetEntrypointSession\\(ctx context.Context\\) \\(\\*toolbox.Session, error\\)](<#ProcessService.GetEntrypointSession>)\n  - [func \\(p \\*ProcessService\\) GetPtySessionInfo\\(ctx context.Context, sessionID string\\) \\(\\*types.PtySessionInfo, error\\)](<#ProcessService.GetPtySessionInfo>)\n  - [func \\(p \\*ProcessService\\) GetSession\\(ctx context.Context, sessionID string\\) \\(map\\[string\\]any, error\\)](<#ProcessService.GetSession>)\n  - [func \\(p \\*ProcessService\\) GetSessionCommand\\(ctx context.Context, sessionID, commandID string\\) \\(map\\[string\\]any, error\\)](<#ProcessService.GetSessionCommand>)\n  - [func \\(p \\*ProcessService\\) GetSessionCommandLogs\\(ctx context.Context, sessionID, commandID string\\) \\(map\\[string\\]any, error\\)](<#ProcessService.GetSessionCommandLogs>)\n  - [func \\(p \\*ProcessService\\) GetSessionCommandLogsStream\\(ctx context.Context, sessionID, commandID string, stdout, stderr chan\\<\\- string\\) error](<#ProcessService.GetSessionCommandLogsStream>)\n  - [func \\(p \\*ProcessService\\) KillPtySession\\(ctx context.Context, sessionID string\\) error](<#ProcessService.KillPtySession>)\n  - [func \\(p \\*ProcessService\\) ListPtySessions\\(ctx context.Context\\) \\(\\[\\]\\*types.PtySessionInfo, error\\)](<#ProcessService.ListPtySessions>)\n  - [func \\(p \\*ProcessService\\) ListSessions\\(ctx context.Context\\) \\(\\[\\]map\\[string\\]any, error\\)](<#ProcessService.ListSessions>)\n  - [func \\(p \\*ProcessService\\) ResizePtySession\\(ctx context.Context, sessionID string, ptySize types.PtySize\\) \\(\\*types.PtySessionInfo, error\\)](<#ProcessService.ResizePtySession>)\n- [type PtyHandle](<#PtyHandle>)\n  - [func \\(h \\*PtyHandle\\) DataChan\\(\\) \\<\\-chan \\[\\]byte](<#PtyHandle.DataChan>)\n  - [func \\(h \\*PtyHandle\\) Disconnect\\(\\) error](<#PtyHandle.Disconnect>)\n  - [func \\(h \\*PtyHandle\\) Error\\(\\) \\*string](<#PtyHandle.Error>)\n  - [func \\(h \\*PtyHandle\\) ExitCode\\(\\) \\*int](<#PtyHandle.ExitCode>)\n  - [func \\(h \\*PtyHandle\\) IsConnected\\(\\) bool](<#PtyHandle.IsConnected>)\n  - [func \\(h \\*PtyHandle\\) Kill\\(ctx context.Context\\) error](<#PtyHandle.Kill>)\n  - [func \\(h \\*PtyHandle\\) Read\\(p \\[\\]byte\\) \\(n int, err error\\)](<#PtyHandle.Read>)\n  - [func \\(h \\*PtyHandle\\) Resize\\(ctx context.Context, cols, rows int\\) \\(\\*types.PtySessionInfo, error\\)](<#PtyHandle.Resize>)\n  - [func \\(h \\*PtyHandle\\) SendInput\\(data \\[\\]byte\\) error](<#PtyHandle.SendInput>)\n  - [func \\(h \\*PtyHandle\\) SessionID\\(\\) string](<#PtyHandle.SessionID>)\n  - [func \\(h \\*PtyHandle\\) Wait\\(ctx context.Context\\) \\(\\*types.PtyResult, error\\)](<#PtyHandle.Wait>)\n  - [func \\(h \\*PtyHandle\\) WaitForConnection\\(ctx context.Context\\) error](<#PtyHandle.WaitForConnection>)\n  - [func \\(h \\*PtyHandle\\) Write\\(p \\[\\]byte\\) \\(n int, err error\\)](<#PtyHandle.Write>)\n- [type PushAccessCredentials](<#PushAccessCredentials>)\n- [type RecordingService](<#RecordingService>)\n  - [func NewRecordingService\\(toolboxClient \\*toolbox.APIClient\\) \\*RecordingService](<#NewRecordingService>)\n  - [func \\(r \\*RecordingService\\) Delete\\(ctx context.Context, id string\\) error](<#RecordingService.Delete>)\n  - [func \\(r \\*RecordingService\\) Download\\(ctx context.Context, id string, localPath string\\) error](<#RecordingService.Download>)\n  - [func \\(r \\*RecordingService\\) Get\\(ctx context.Context, id string\\) \\(\\*toolbox.Recording, error\\)](<#RecordingService.Get>)\n  - [func \\(r \\*RecordingService\\) List\\(ctx context.Context\\) \\(\\*toolbox.ListRecordingsResponse, error\\)](<#RecordingService.List>)\n  - [func \\(r \\*RecordingService\\) Start\\(ctx context.Context, label \\*string\\) \\(\\*toolbox.Recording, error\\)](<#RecordingService.Start>)\n  - [func \\(r \\*RecordingService\\) Stop\\(ctx context.Context, id string\\) \\(\\*toolbox.Recording, error\\)](<#RecordingService.Stop>)\n- [type Sandbox](<#Sandbox>)\n  - [func NewSandbox\\(client \\*Client, toolboxClient \\*toolbox.APIClient, id string, name string, state apiclient.SandboxState, target string, autoArchiveInterval int, autoDeleteInterval int, networkBlockAll bool, networkAllowList \\*string\\) \\*Sandbox](<#NewSandbox>)\n  - [func \\(s \\*Sandbox\\) Archive\\(ctx context.Context\\) error](<#Sandbox.Archive>)\n  - [func \\(s \\*Sandbox\\) Delete\\(ctx context.Context\\) error](<#Sandbox.Delete>)\n  - [func \\(s \\*Sandbox\\) DeleteWithTimeout\\(ctx context.Context, timeout time.Duration\\) error](<#Sandbox.DeleteWithTimeout>)\n  - [func \\(s \\*Sandbox\\) GetPreviewLink\\(ctx context.Context, port int\\) \\(\\*types.PreviewLink, error\\)](<#Sandbox.GetPreviewLink>)\n  - [func \\(s \\*Sandbox\\) GetUserHomeDir\\(ctx context.Context\\) \\(string, error\\)](<#Sandbox.GetUserHomeDir>)\n  - [func \\(s \\*Sandbox\\) GetWorkingDir\\(ctx context.Context\\) \\(string, error\\)](<#Sandbox.GetWorkingDir>)\n  - [func \\(s \\*Sandbox\\) RefreshData\\(ctx context.Context\\) error](<#Sandbox.RefreshData>)\n  - [func \\(s \\*Sandbox\\) Resize\\(ctx context.Context, resources \\*types.Resources\\) error](<#Sandbox.Resize>)\n  - [func \\(s \\*Sandbox\\) ResizeWithTimeout\\(ctx context.Context, resources \\*types.Resources, timeout time.Duration\\) error](<#Sandbox.ResizeWithTimeout>)\n  - [func \\(s \\*Sandbox\\) SetAutoArchiveInterval\\(ctx context.Context, intervalMinutes \\*int\\) error](<#Sandbox.SetAutoArchiveInterval>)\n  - [func \\(s \\*Sandbox\\) SetAutoDeleteInterval\\(ctx context.Context, intervalMinutes \\*int\\) error](<#Sandbox.SetAutoDeleteInterval>)\n  - [func \\(s \\*Sandbox\\) SetLabels\\(ctx context.Context, labels map\\[string\\]string\\) error](<#Sandbox.SetLabels>)\n  - [func \\(s \\*Sandbox\\) Start\\(ctx context.Context\\) error](<#Sandbox.Start>)\n  - [func \\(s \\*Sandbox\\) StartWithTimeout\\(ctx context.Context, timeout time.Duration\\) error](<#Sandbox.StartWithTimeout>)\n  - [func \\(s \\*Sandbox\\) Stop\\(ctx context.Context\\) error](<#Sandbox.Stop>)\n  - [func \\(s \\*Sandbox\\) StopWithTimeout\\(ctx context.Context, timeout time.Duration\\) error](<#Sandbox.StopWithTimeout>)\n  - [func \\(s \\*Sandbox\\) WaitForResize\\(ctx context.Context, timeout time.Duration\\) error](<#Sandbox.WaitForResize>)\n  - [func \\(s \\*Sandbox\\) WaitForStart\\(ctx context.Context, timeout time.Duration\\) error](<#Sandbox.WaitForStart>)\n  - [func \\(s \\*Sandbox\\) WaitForStop\\(ctx context.Context, timeout time.Duration\\) error](<#Sandbox.WaitForStop>)\n- [type ScreenshotService](<#ScreenshotService>)\n  - [func NewScreenshotService\\(toolboxClient \\*toolbox.APIClient, otel \\*otelState\\) \\*ScreenshotService](<#NewScreenshotService>)\n  - [func \\(s \\*ScreenshotService\\) TakeFullScreen\\(ctx context.Context, showCursor \\*bool\\) \\(\\*types.ScreenshotResponse, error\\)](<#ScreenshotService.TakeFullScreen>)\n  - [func \\(s \\*ScreenshotService\\) TakeRegion\\(ctx context.Context, region types.ScreenshotRegion, showCursor \\*bool\\) \\(\\*types.ScreenshotResponse, error\\)](<#ScreenshotService.TakeRegion>)\n- [type SnapshotService](<#SnapshotService>)\n  - [func NewSnapshotService\\(client \\*Client\\) \\*SnapshotService](<#NewSnapshotService>)\n  - [func \\(s \\*SnapshotService\\) Create\\(ctx context.Context, params \\*types.CreateSnapshotParams\\) \\(\\*types.Snapshot, \\<\\-chan string, error\\)](<#SnapshotService.Create>)\n  - [func \\(s \\*SnapshotService\\) Delete\\(ctx context.Context, snapshot \\*types.Snapshot\\) error](<#SnapshotService.Delete>)\n  - [func \\(s \\*SnapshotService\\) Get\\(ctx context.Context, nameOrID string\\) \\(\\*types.Snapshot, error\\)](<#SnapshotService.Get>)\n  - [func \\(s \\*SnapshotService\\) List\\(ctx context.Context, page \\*int, limit \\*int\\) \\(\\*types.PaginatedSnapshots, error\\)](<#SnapshotService.List>)\n- [type VolumeService](<#VolumeService>)\n  - [func NewVolumeService\\(client \\*Client\\) \\*VolumeService](<#NewVolumeService>)\n  - [func \\(v \\*VolumeService\\) Create\\(ctx context.Context, name string\\) \\(\\*types.Volume, error\\)](<#VolumeService.Create>)\n  - [func \\(v \\*VolumeService\\) Delete\\(ctx context.Context, volume \\*types.Volume\\) error](<#VolumeService.Delete>)\n  - [func \\(v \\*VolumeService\\) Get\\(ctx context.Context, name string\\) \\(\\*types.Volume, error\\)](<#VolumeService.Get>)\n  - [func \\(v \\*VolumeService\\) List\\(ctx context.Context\\) \\(\\[\\]\\*types.Volume, error\\)](<#VolumeService.List>)\n  - [func \\(v \\*VolumeService\\) WaitForReady\\(ctx context.Context, volume \\*types.Volume, timeout time.Duration\\) \\(\\*types.Volume, error\\)](<#VolumeService.WaitForReady>)\n\n\n## Variables\n\n<a name=\"Version\"></a>Version is the semantic version of the Daytona SDK.\n\nThis value is embedded at build time from the VERSION file.\n\nExample:\n\n```\nfmt.Printf(\"Daytona SDK version: %s\\n\", daytona.Version)\n```\n\n```go\nvar Version = strings.TrimSpace(version)\n```\n\n<a name=\"Client\"></a>\n## type Client\n\nClient is the main entry point for interacting with the Daytona platform.\n\nClient provides methods to create, retrieve, list, and manage sandboxes. It handles authentication, API communication, and provides access to services like Volume and Snapshot management.\n\nCreate a Client using [NewClient](<#NewClient>) or [NewClientWithConfig](<#NewClientWithConfig>):\n\n```\nclient, err := daytona.NewClient()\nif err != nil {\n    log.Fatal(err)\n}\n```\n\nThe Client is safe for concurrent use by multiple goroutines.\n\n```go\ntype Client struct {\n\n    // Otel holds OpenTelemetry state; nil when OTel is disabled.\n    Otel *otelState\n\n    // Volume provides methods for managing persistent volumes.\n    Volume *VolumeService\n\n    // Snapshot provides methods for managing sandbox snapshots.\n    Snapshot *SnapshotService\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewClient\"></a>\n### func NewClient\n\n```go\nfunc NewClient() (*Client, error)\n```\n\nNewClient creates a new Daytona client with default configuration.\n\nNewClient reads configuration from environment variables:\n\n- DAYTONA\\_API\\_KEY or DAYTONA\\_JWT\\_TOKEN for authentication \\(one is required\\)\n- DAYTONA\\_ORGANIZATION\\_ID \\(required when using JWT token\\)\n- DAYTONA\\_API\\_URL for custom API endpoint\n- DAYTONA\\_TARGET for target environment\n\nFor explicit configuration, use [NewClientWithConfig](<#NewClientWithConfig>) instead.\n\n<a name=\"NewClientWithConfig\"></a>\n### func NewClientWithConfig\n\n```go\nfunc NewClientWithConfig(config *types.DaytonaConfig) (*Client, error)\n```\n\nNewClientWithConfig creates a new Daytona client with a custom configuration.\n\nConfiguration values provided in config take precedence over environment variables. Any configuration field left empty will fall back to the corresponding environment variable \\(see [NewClient](<#NewClient>) for the list of supported variables\\).\n\nExample:\n\n```\nclient, err := daytona.NewClientWithConfig(&types.DaytonaConfig{\n    APIKey:         \"your-api-key\",\n    APIUrl:         \"https://custom.daytona.io/api\",\n    OrganizationID: \"org-123\",\n})\nif err != nil {\n    log.Fatal(err)\n}\n```\n\nReturns an error if neither API key nor JWT token is provided, or if JWT token is provided without an organization ID.\n\n<a name=\"Client.Close\"></a>\n### func \\(\\*Client\\) Close\n\n```go\nfunc (c *Client) Close(ctx context.Context) error\n```\n\nClose shuts down the client and releases resources. When OpenTelemetry is enabled, Close flushes and shuts down the OTel providers. It is safe to call Close even when OTel is not enabled.\n\n<a name=\"Client.Create\"></a>\n### func \\(\\*Client\\) Create\n\n```go\nfunc (c *Client) Create(ctx context.Context, params any, opts ...func(*options.CreateSandbox)) (*Sandbox, error)\n```\n\nCreate creates a new sandbox with the specified parameters.\n\nThe params argument accepts either \\[types.SnapshotParams\\] to create from a snapshot, or \\[types.ImageParams\\] to create from a Docker image:\n\n```\n// Create from a snapshot\nsandbox, err := client.Create(ctx, types.SnapshotParams{\n    Snapshot: \"my-snapshot\",\n    SandboxBaseParams: types.SandboxBaseParams{\n        Name: \"my-sandbox\",\n    },\n})\n\n// Create from a Docker image\nsandbox, err := client.Create(ctx, types.ImageParams{\n    Image: \"python:3.11\",\n    Resources: &types.Resources{\n        CPU:    2,\n        Memory: 4096,\n    },\n})\n```\n\nBy default, Create waits for the sandbox to reach the started state before returning. Use \\[options.WithWaitForStart\\]\\(false\\) to return immediately after creation.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithTimeout\\]: Set maximum wait time for creation\n- \\[options.WithWaitForStart\\]: Control whether to wait for started state\n- \\[options.WithLogChannel\\]: Receive build logs during image builds\n\nReturns the created [Sandbox](<#Sandbox>) or an error if creation fails.\n\n<a name=\"Client.Get\"></a>\n### func \\(\\*Client\\) Get\n\n```go\nfunc (c *Client) Get(ctx context.Context, sandboxIDOrName string) (*Sandbox, error)\n```\n\nGet retrieves an existing sandbox by its ID or name.\n\nThe sandboxIDOrName parameter accepts either the sandbox's unique ID or its human\\-readable name. If a sandbox with the given identifier is not found, a [errors.DaytonaNotFoundError](<https://pkg.go.dev/errors/#DaytonaNotFoundError>) is returned.\n\nExample:\n\n```\nsandbox, err := client.Get(ctx, \"my-sandbox\")\nif err != nil {\n    var notFound *errors.DaytonaNotFoundError\n    if errors.As(err, &notFound) {\n        log.Println(\"Sandbox not found\")\n    }\n    return err\n}\n```\n\n<a name=\"Client.List\"></a>\n### func \\(\\*Client\\) List\n\n```go\nfunc (c *Client) List(ctx context.Context, labels map[string]string, page *int, limit *int) (*PaginatedSandboxes, error)\n```\n\nList retrieves sandboxes with optional label filtering and pagination.\n\nParameters:\n\n- labels: Optional map of labels to filter sandboxes. Pass nil for no filtering.\n- page: Optional page number \\(1\\-indexed\\). Pass nil for the first page.\n- limit: Optional number of results per page. Pass nil for the default limit.\n\nExample:\n\n```\n// List all sandboxes\nresult, err := client.List(ctx, nil, nil, nil)\n\n// List sandboxes with pagination\npage, limit := 1, 10\nresult, err := client.List(ctx, nil, &page, &limit)\n\n// Filter by labels\nresult, err := client.List(ctx, map[string]string{\"env\": \"dev\"}, nil, nil)\n\n// Iterate through results\nfor _, sandbox := range result.Items {\n    fmt.Printf(\"Sandbox: %s (state: %s)\\n\", sandbox.Name, sandbox.State)\n}\n```\n\nReturns a [PaginatedSandboxes](<#PaginatedSandboxes>) containing the matching sandboxes and pagination metadata.\n\n<a name=\"CodeInterpreterService\"></a>\n## type CodeInterpreterService\n\nCodeInterpreterService provides Python code execution capabilities for a sandbox.\n\nCodeInterpreterService enables running Python code in isolated execution contexts with support for streaming output, persistent state, and environment variables. It uses WebSockets for real\\-time output streaming. Access through \\[Sandbox.CodeInterpreter\\].\n\nExample:\n\n```\n// Simple code execution\nchannels, err := sandbox.CodeInterpreter.RunCode(ctx, \"print('Hello, World!')\")\nif err != nil {\n    return err\n}\n\n// Wait for completion and get result\nresult := <-channels.Done\nfmt.Println(result.Stdout)\n\n// With persistent context\nctxInfo, _ := sandbox.CodeInterpreter.CreateContext(ctx, nil)\ncontextID := ctxInfo[\"id\"].(string)\nchannels, _ = sandbox.CodeInterpreter.RunCode(ctx, \"x = 42\",\n    options.WithCustomContext(contextID),\n)\n<-channels.Done\nchannels, _ = sandbox.CodeInterpreter.RunCode(ctx, \"print(x)\",\n    options.WithCustomContext(contextID),\n)\n```\n\n```go\ntype CodeInterpreterService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewCodeInterpreterService\"></a>\n### func NewCodeInterpreterService\n\n```go\nfunc NewCodeInterpreterService(toolboxClient *toolbox.APIClient, otel *otelState) *CodeInterpreterService\n```\n\nNewCodeInterpreterService creates a new CodeInterpreterService.\n\nThis is typically called internally by the SDK when creating a [Sandbox](<#Sandbox>). Users should access CodeInterpreterService through \\[Sandbox.CodeInterpreter\\] rather than creating it directly.\n\n<a name=\"CodeInterpreterService.CreateContext\"></a>\n### func \\(\\*CodeInterpreterService\\) CreateContext\n\n```go\nfunc (c *CodeInterpreterService) CreateContext(ctx context.Context, cwd *string) (map[string]any, error)\n```\n\nCreateContext creates an isolated execution context for persistent state.\n\nContexts allow you to maintain state \\(variables, imports, etc.\\) across multiple code executions. Without a context, each RunCode call starts fresh.\n\nParameters:\n\n- cwd: Optional working directory for the context\n\nExample:\n\n```\n// Create a context\nctxInfo, err := sandbox.CodeInterpreter.CreateContext(ctx, nil)\nif err != nil {\n    return err\n}\ncontextID := ctxInfo[\"id\"].(string)\n\n// Use the context to maintain state\nsandbox.CodeInterpreter.RunCode(ctx, \"x = 42\", options.WithCustomContext(contextID))\nsandbox.CodeInterpreter.RunCode(ctx, \"print(x)\", options.WithCustomContext(contextID)) // prints 42\n\n// Clean up when done\nsandbox.CodeInterpreter.DeleteContext(ctx, contextID)\n```\n\nReturns context information including \"id\", \"cwd\", \"language\", \"active\", and \"createdAt\".\n\n<a name=\"CodeInterpreterService.DeleteContext\"></a>\n### func \\(\\*CodeInterpreterService\\) DeleteContext\n\n```go\nfunc (c *CodeInterpreterService) DeleteContext(ctx context.Context, contextID string) error\n```\n\nDeleteContext removes an execution context and releases its resources.\n\nParameters:\n\n- contextID: The context identifier to delete\n\nExample:\n\n```\nerr := sandbox.CodeInterpreter.DeleteContext(ctx, contextID)\n```\n\nReturns an error if the context doesn't exist or deletion fails.\n\n<a name=\"CodeInterpreterService.ListContexts\"></a>\n### func \\(\\*CodeInterpreterService\\) ListContexts\n\n```go\nfunc (c *CodeInterpreterService) ListContexts(ctx context.Context) ([]map[string]any, error)\n```\n\nListContexts returns all active execution contexts.\n\nExample:\n\n```\ncontexts, err := sandbox.CodeInterpreter.ListContexts(ctx)\nif err != nil {\n    return err\n}\nfor _, ctx := range contexts {\n    fmt.Printf(\"Context %s (language: %s)\\n\", ctx[\"id\"], ctx[\"language\"])\n}\n```\n\nReturns a slice of context information maps.\n\n<a name=\"CodeInterpreterService.RunCode\"></a>\n### func \\(\\*CodeInterpreterService\\) RunCode\n\n```go\nfunc (c *CodeInterpreterService) RunCode(ctx context.Context, code string, opts ...func(*options.RunCode)) (*OutputChannels, error)\n```\n\nRunCode executes Python code and returns channels for streaming output.\n\nThis method establishes a WebSocket connection to execute code asynchronously, streaming stdout and stderr as they become available.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithCustomContext\\]: Use a persistent context for state\n- \\[options.WithEnv\\]: Set environment variables\n- \\[options.WithInterpreterTimeout\\]: Set execution timeout\n\nExample:\n\n```\n// Basic execution\nchannels, err := sandbox.CodeInterpreter.RunCode(ctx, `\n    for i in range(5):\n        print(f\"Count: {i}\")\n`)\nif err != nil {\n    return err\n}\n\n// Stream output\nfor msg := range channels.Stdout {\n    fmt.Print(msg.Text)\n}\n\n// Get final result\nresult := <-channels.Done\nif result.Error != nil {\n    fmt.Printf(\"Error: %s\\n\", result.Error.Value)\n}\n\n// With options\nchannels, err := sandbox.CodeInterpreter.RunCode(ctx, \"import os; print(os.environ['API_KEY'])\",\n    options.WithEnv(map[string]string{\"API_KEY\": \"secret\"}),\n    options.WithInterpreterTimeout(30*time.Second),\n)\n```\n\nReturns [OutputChannels](<#OutputChannels>) for receiving streamed output, or an error if connection fails.\n\n<a name=\"ComputerUseService\"></a>\n## type ComputerUseService\n\nComputerUseService provides desktop automation operations for a sandbox.\n\nComputerUseService enables GUI automation including mouse control, keyboard input, screenshots, display management, and screen recording. The desktop environment must be started before using these features. Access through \\[Sandbox.ComputerUse\\].\n\nExample:\n\n```\ncu := sandbox.ComputerUse\n\n// Start the desktop environment\nif err := cu.Start(ctx); err != nil {\n    return err\n}\ndefer cu.Stop(ctx)\n\n// Take a screenshot\nscreenshot, err := cu.Screenshot().TakeFullScreen(ctx, nil)\nif err != nil {\n    return err\n}\n\n// Click at coordinates\ncu.Mouse().Click(ctx, 100, 200, nil, nil)\n\n// Type text\ncu.Keyboard().Type(ctx, \"Hello, World!\", nil)\n```\n\n```go\ntype ComputerUseService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewComputerUseService\"></a>\n### func NewComputerUseService\n\n```go\nfunc NewComputerUseService(toolboxClient *toolbox.APIClient, otel *otelState) *ComputerUseService\n```\n\nNewComputerUseService creates a new ComputerUseService.\n\nThis is typically called internally by the SDK when creating a [Sandbox](<#Sandbox>). Users should access ComputerUseService through \\[Sandbox.ComputerUse\\] rather than creating it directly.\n\n<a name=\"ComputerUseService.Display\"></a>\n### func \\(\\*ComputerUseService\\) Display\n\n```go\nfunc (c *ComputerUseService) Display() *DisplayService\n```\n\nDisplay returns the [DisplayService](<#DisplayService>) for display information.\n\nThe service is lazily initialized on first access.\n\n<a name=\"ComputerUseService.GetStatus\"></a>\n### func \\(\\*ComputerUseService\\) GetStatus\n\n```go\nfunc (c *ComputerUseService) GetStatus(ctx context.Context) (map[string]any, error)\n```\n\nGetStatus returns the current status of the desktop environment.\n\nExample:\n\n```\nstatus, err := cu.GetStatus(ctx)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Desktop status: %v\\n\", status[\"status\"])\n```\n\nReturns a map containing status information.\n\n<a name=\"ComputerUseService.Keyboard\"></a>\n### func \\(\\*ComputerUseService\\) Keyboard\n\n```go\nfunc (c *ComputerUseService) Keyboard() *KeyboardService\n```\n\nKeyboard returns the [KeyboardService](<#KeyboardService>) for keyboard operations.\n\nThe service is lazily initialized on first access.\n\n<a name=\"ComputerUseService.Mouse\"></a>\n### func \\(\\*ComputerUseService\\) Mouse\n\n```go\nfunc (c *ComputerUseService) Mouse() *MouseService\n```\n\nMouse returns the [MouseService](<#MouseService>) for mouse operations.\n\nThe service is lazily initialized on first access.\n\n<a name=\"ComputerUseService.Recording\"></a>\n### func \\(\\*ComputerUseService\\) Recording\n\n```go\nfunc (c *ComputerUseService) Recording() *RecordingService\n```\n\nRecording returns the [RecordingService](<#RecordingService>) for screen recording operations.\n\nThe service is lazily initialized on first access.\n\n<a name=\"ComputerUseService.Screenshot\"></a>\n### func \\(\\*ComputerUseService\\) Screenshot\n\n```go\nfunc (c *ComputerUseService) Screenshot() *ScreenshotService\n```\n\nScreenshot returns the [ScreenshotService](<#ScreenshotService>) for capturing screen images.\n\nThe service is lazily initialized on first access.\n\n<a name=\"ComputerUseService.Start\"></a>\n### func \\(\\*ComputerUseService\\) Start\n\n```go\nfunc (c *ComputerUseService) Start(ctx context.Context) error\n```\n\nStart initializes and starts the desktop environment.\n\nThe desktop environment must be started before using mouse, keyboard, or screenshot operations. Call [ComputerUseService.Stop](<#ComputerUseService.Stop>) when finished.\n\nExample:\n\n```\nif err := cu.Start(ctx); err != nil {\n    return err\n}\ndefer cu.Stop(ctx)\n```\n\nReturns an error if the desktop fails to start.\n\n<a name=\"ComputerUseService.Stop\"></a>\n### func \\(\\*ComputerUseService\\) Stop\n\n```go\nfunc (c *ComputerUseService) Stop(ctx context.Context) error\n```\n\nStop shuts down the desktop environment and releases resources.\n\nExample:\n\n```\nerr := cu.Stop(ctx)\n```\n\nReturns an error if the desktop fails to stop gracefully.\n\n<a name=\"DisplayService\"></a>\n## type DisplayService\n\nDisplayService provides display information and window management operations.\n\nDisplayService enables querying display configuration and window information. Access through [ComputerUseService.Display](<#ComputerUseService.Display>).\n\n```go\ntype DisplayService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewDisplayService\"></a>\n### func NewDisplayService\n\n```go\nfunc NewDisplayService(toolboxClient *toolbox.APIClient, otel *otelState) *DisplayService\n```\n\nNewDisplayService creates a new DisplayService.\n\n<a name=\"DisplayService.GetInfo\"></a>\n### func \\(\\*DisplayService\\) GetInfo\n\n```go\nfunc (d *DisplayService) GetInfo(ctx context.Context) (map[string]any, error)\n```\n\nGetInfo returns information about connected displays.\n\nExample:\n\n```\ninfo, err := display.GetInfo(ctx)\nif err != nil {\n    return err\n}\ndisplays := info[\"displays\"]\nfmt.Printf(\"Connected displays: %v\\n\", displays)\n```\n\nReturns a map containing display information.\n\n<a name=\"DisplayService.GetWindows\"></a>\n### func \\(\\*DisplayService\\) GetWindows\n\n```go\nfunc (d *DisplayService) GetWindows(ctx context.Context) (map[string]any, error)\n```\n\nGetWindows returns information about open windows.\n\nExample:\n\n```\nresult, err := display.GetWindows(ctx)\nif err != nil {\n    return err\n}\nwindows := result[\"windows\"]\nfmt.Printf(\"Open windows: %v\\n\", windows)\n```\n\nReturns a map containing window information.\n\n<a name=\"DockerImage\"></a>\n## type DockerImage\n\nDockerImage provides a fluent interface for building Docker images declaratively.\n\nDockerImage allows you to define Docker images using Go code instead of Dockerfiles. Methods can be chained to build up the image definition, which is then converted to a Dockerfile when used with [SnapshotService.Create](<#SnapshotService.Create>).\n\nExample:\n\n```\n// Create a Python image with dependencies\nimage := daytona.Base(\"python:3.11-slim\").\n    AptGet([]string{\"git\", \"curl\"}).\n    PipInstall([]string{\"numpy\", \"pandas\"}).\n    Workdir(\"/app\").\n    Env(\"PYTHONUNBUFFERED\", \"1\")\n\n// Use with snapshot creation\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:  \"my-python-env\",\n    DockerImage: image,\n})\n```\n\n```go\ntype DockerImage struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"Base\"></a>\n### func Base\n\n```go\nfunc Base(baseImage string) *DockerImage\n```\n\nBase creates a new Image from a base Docker image.\n\nThis is typically the starting point for building an image definition. The baseImage parameter is any valid Docker image reference.\n\nExample:\n\n```\nimage := daytona.Base(\"ubuntu:22.04\")\nimage := daytona.Base(\"python:3.11-slim\")\nimage := daytona.Base(\"node:18-alpine\")\n```\n\n<a name=\"DebianSlim\"></a>\n### func DebianSlim\n\n```go\nfunc DebianSlim(pythonVersion *string) *DockerImage\n```\n\nDebianSlim creates a Python image based on Debian slim.\n\nThis is a convenience function for creating Python environments. If pythonVersion is nil, defaults to Python 3.12.\n\nExample:\n\n```\n// Use default Python 3.12\nimage := daytona.DebianSlim(nil)\n\n// Use specific version\nversion := \"3.10\"\nimage := daytona.DebianSlim(&version)\n```\n\n<a name=\"FromDockerfile\"></a>\n### func FromDockerfile\n\n```go\nfunc FromDockerfile(dockerfile string) *DockerImage\n```\n\nFromDockerfile creates an Image from an existing Dockerfile string.\n\nUse this when you have an existing Dockerfile you want to use.\n\nExample:\n\n```\ndockerfile := `FROM python:3.11\nRUN pip install numpy\nWORKDIR /app`\nimage := daytona.FromDockerfile(dockerfile)\n```\n\n<a name=\"DockerImage.Add\"></a>\n### func \\(\\*DockerImage\\) Add\n\n```go\nfunc (img *DockerImage) Add(source, destination string) *DockerImage\n```\n\nAdd adds an ADD instruction to the image.\n\nADD supports URLs and automatic tar extraction. For simple file copying, prefer [DockerImage.Copy](<#DockerImage.Copy>).\n\nExample:\n\n```\nimage := daytona.Base(\"ubuntu:22.04\").\n    Add(\"https://example.com/app.tar.gz\", \"/app/\")\n```\n\n<a name=\"DockerImage.AddLocalDir\"></a>\n### func \\(\\*DockerImage\\) AddLocalDir\n\n```go\nfunc (img *DockerImage) AddLocalDir(localPath, remotePath string) *DockerImage\n```\n\nAddLocalDir adds a local directory to the build context and copies it to the image.\n\nThe directory is uploaded to object storage and included in the Docker build context.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    AddLocalDir(\"./src\", \"/app/src\")\n```\n\n<a name=\"DockerImage.AddLocalFile\"></a>\n### func \\(\\*DockerImage\\) AddLocalFile\n\n```go\nfunc (img *DockerImage) AddLocalFile(localPath, remotePath string) *DockerImage\n```\n\nAddLocalFile adds a local file to the build context and copies it to the image.\n\nThe file is uploaded to object storage and included in the Docker build context.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    AddLocalFile(\"./requirements.txt\", \"/app/requirements.txt\").\n    Run(\"pip install -r /app/requirements.txt\")\n```\n\n<a name=\"DockerImage.AptGet\"></a>\n### func \\(\\*DockerImage\\) AptGet\n\n```go\nfunc (img *DockerImage) AptGet(packages []string) *DockerImage\n```\n\nAptGet adds an apt\\-get install instruction for system packages.\n\nThis automatically handles updating the package list and cleaning up afterward to minimize image size.\n\nExample:\n\n```\nimage := daytona.Base(\"ubuntu:22.04\").AptGet([]string{\"git\", \"curl\", \"build-essential\"})\n```\n\n<a name=\"DockerImage.Cmd\"></a>\n### func \\(\\*DockerImage\\) Cmd\n\n```go\nfunc (img *DockerImage) Cmd(cmd []string) *DockerImage\n```\n\nCmd sets the default command for the image.\n\nIf an entrypoint is set, the cmd provides default arguments to it.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Cmd([]string{\"python\", \"app.py\"})\n```\n\n<a name=\"DockerImage.Contexts\"></a>\n### func \\(\\*DockerImage\\) Contexts\n\n```go\nfunc (img *DockerImage) Contexts() []DockerImageContext\n```\n\nContexts returns the build contexts for local files/directories.\n\nThis is called internally when creating snapshots to upload local files.\n\n<a name=\"DockerImage.Copy\"></a>\n### func \\(\\*DockerImage\\) Copy\n\n```go\nfunc (img *DockerImage) Copy(source, destination string) *DockerImage\n```\n\nCopy adds a COPY instruction to copy files into the image.\n\nFor local files, use [DockerImage.AddLocalFile](<#DockerImage.AddLocalFile>) instead, which handles uploading to the build context.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Copy(\"requirements.txt\", \"/app/requirements.txt\")\n```\n\n<a name=\"DockerImage.Dockerfile\"></a>\n### func \\(\\*DockerImage\\) Dockerfile\n\n```go\nfunc (img *DockerImage) Dockerfile() string\n```\n\nDockerfile returns the generated Dockerfile content.\n\nThis is called internally when creating snapshots.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").PipInstall([]string{\"numpy\"})\nfmt.Println(image.Dockerfile())\n// Output:\n// FROM python:3.11\n// RUN pip install numpy\n```\n\n<a name=\"DockerImage.Entrypoint\"></a>\n### func \\(\\*DockerImage\\) Entrypoint\n\n```go\nfunc (img *DockerImage) Entrypoint(cmd []string) *DockerImage\n```\n\nEntrypoint sets the entrypoint for the image.\n\nThe cmd parameter is the command and arguments as a slice.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Entrypoint([]string{\"python\", \"-m\", \"myapp\"})\n```\n\n<a name=\"DockerImage.Env\"></a>\n### func \\(\\*DockerImage\\) Env\n\n```go\nfunc (img *DockerImage) Env(key, value string) *DockerImage\n```\n\nEnv sets an environment variable in the image.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Env(\"PYTHONUNBUFFERED\", \"1\").\n    Env(\"APP_ENV\", \"production\")\n```\n\n<a name=\"DockerImage.Expose\"></a>\n### func \\(\\*DockerImage\\) Expose\n\n```go\nfunc (img *DockerImage) Expose(ports []int) *DockerImage\n```\n\nExpose declares ports that the container listens on.\n\nThis is documentation for users and tools; it doesn't actually publish ports.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Expose([]int{8080, 8443})\n```\n\n<a name=\"DockerImage.Label\"></a>\n### func \\(\\*DockerImage\\) Label\n\n```go\nfunc (img *DockerImage) Label(key, value string) *DockerImage\n```\n\nLabel adds metadata to the image.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Label(\"maintainer\", \"team@example.com\").\n    Label(\"version\", \"1.0.0\")\n```\n\n<a name=\"DockerImage.PipInstall\"></a>\n### func \\(\\*DockerImage\\) PipInstall\n\n```go\nfunc (img *DockerImage) PipInstall(packages []string, opts ...func(*options.PipInstall)) *DockerImage\n```\n\nPipInstall adds a pip install instruction for Python packages.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithFindLinks\\]: Add find\\-links URLs\n- \\[options.WithIndexURL\\]: Set custom PyPI index\n- \\[options.WithExtraIndexURLs\\]: Add extra index URLs\n- \\[options.WithPre\\]: Allow pre\\-release versions\n- \\[options.WithExtraOptions\\]: Add additional pip options\n\nExample:\n\n```\n// Basic installation\nimage := daytona.Base(\"python:3.11\").PipInstall([]string{\"numpy\", \"pandas\"})\n\n// With options\nimage := daytona.Base(\"python:3.11\").PipInstall(\n    []string{\"torch\"},\n    options.WithIndexURL(\"https://download.pytorch.org/whl/cpu\"),\n    options.WithExtraOptions(\"--no-cache-dir\"),\n)\n```\n\n<a name=\"DockerImage.Run\"></a>\n### func \\(\\*DockerImage\\) Run\n\n```go\nfunc (img *DockerImage) Run(command string) *DockerImage\n```\n\nRun adds a RUN instruction to execute a shell command.\n\nExample:\n\n```\nimage := daytona.Base(\"ubuntu:22.04\").\n    Run(\"mkdir -p /app/data\").\n    Run(\"chmod 755 /app\")\n```\n\n<a name=\"DockerImage.User\"></a>\n### func \\(\\*DockerImage\\) User\n\n```go\nfunc (img *DockerImage) User(username string) *DockerImage\n```\n\nUser sets the user for subsequent instructions and container runtime.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Run(\"useradd -m appuser\").\n    User(\"appuser\").\n    Workdir(\"/home/appuser\")\n```\n\n<a name=\"DockerImage.Volume\"></a>\n### func \\(\\*DockerImage\\) Volume\n\n```go\nfunc (img *DockerImage) Volume(paths []string) *DockerImage\n```\n\nVolume declares mount points for the container.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Volume([]string{\"/data\", \"/logs\"})\n```\n\n<a name=\"DockerImage.Workdir\"></a>\n### func \\(\\*DockerImage\\) Workdir\n\n```go\nfunc (img *DockerImage) Workdir(path string) *DockerImage\n```\n\nWorkdir sets the working directory for subsequent instructions.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").\n    Workdir(\"/app\").\n    Run(\"pip install -r requirements.txt\")\n```\n\n<a name=\"DockerImageContext\"></a>\n## type DockerImageContext\n\nDockerImageContext represents a local file or directory to include in the build context.\n\nWhen using [DockerImage.AddLocalFile](<#DockerImage.AddLocalFile>) or [DockerImage.AddLocalDir](<#DockerImage.AddLocalDir>), the file/directory is uploaded to object storage and included in the Docker build context.\n\n```go\ntype DockerImageContext struct {\n    SourcePath  string // Local path to the file or directory\n    ArchivePath string // Path within the build context archive\n}\n```\n\n<a name=\"FileSystemService\"></a>\n## type FileSystemService\n\nFileSystemService provides file system operations for a sandbox.\n\nFileSystemService enables file and directory management including creating, reading, writing, moving, and deleting files. It also supports file searching and permission management. Access through \\[Sandbox.FileSystem\\].\n\nExample:\n\n```\n// List files in a directory\nfiles, err := sandbox.FileSystem.ListFiles(ctx, \"/home/user\")\n\n// Create a directory\nerr = sandbox.FileSystem.CreateFolder(ctx, \"/home/user/mydir\")\n\n// Upload a file\nerr = sandbox.FileSystem.UploadFile(ctx, \"/local/path/file.txt\", \"/home/user/file.txt\")\n\n// Download a file\ndata, err := sandbox.FileSystem.DownloadFile(ctx, \"/home/user/file.txt\", nil)\n```\n\n```go\ntype FileSystemService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewFileSystemService\"></a>\n### func NewFileSystemService\n\n```go\nfunc NewFileSystemService(toolboxClient *toolbox.APIClient, otel *otelState) *FileSystemService\n```\n\nNewFileSystemService creates a new FileSystemService with the provided toolbox client.\n\nThis is typically called internally by the SDK when creating a [Sandbox](<#Sandbox>). Users should access FileSystemService through \\[Sandbox.FileSystem\\] rather than creating it directly.\n\n<a name=\"FileSystemService.CreateFolder\"></a>\n### func \\(\\*FileSystemService\\) CreateFolder\n\n```go\nfunc (f *FileSystemService) CreateFolder(ctx context.Context, path string, opts ...func(*options.CreateFolder)) error\n```\n\nCreateFolder creates a directory at the specified path.\n\nThe path parameter specifies the absolute path for the new directory. Parent directories are created automatically if they don't exist.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithMode\\]: Set Unix file permissions \\(defaults to \"0755\"\\)\n\nExample:\n\n```\n// Create with default permissions\nerr := sandbox.FileSystem.CreateFolder(ctx, \"/home/user/mydir\")\n\n// Create with custom permissions\nerr := sandbox.FileSystem.CreateFolder(ctx, \"/home/user/private\",\n    options.WithMode(\"0700\"),\n)\n```\n\nReturns an error if the directory creation fails.\n\n<a name=\"FileSystemService.DeleteFile\"></a>\n### func \\(\\*FileSystemService\\) DeleteFile\n\n```go\nfunc (f *FileSystemService) DeleteFile(ctx context.Context, path string, recursive bool) error\n```\n\nDeleteFile deletes a file or directory.\n\nParameters:\n\n- path: The file or directory path to delete\n- recursive: If true, delete directories and their contents recursively\n\nExample:\n\n```\n// Delete a file\nerr := sandbox.FileSystem.DeleteFile(ctx, \"/home/user/file.txt\", false)\n\n// Delete a directory recursively\nerr := sandbox.FileSystem.DeleteFile(ctx, \"/home/user/mydir\", true)\n```\n\nReturns an error if the deletion fails \\(e.g., path doesn't exist, permission denied, or attempting to delete a non\\-empty directory without recursive=true\\).\n\n<a name=\"FileSystemService.DownloadFile\"></a>\n### func \\(\\*FileSystemService\\) DownloadFile\n\n```go\nfunc (f *FileSystemService) DownloadFile(ctx context.Context, remotePath string, localPath *string) ([]byte, error)\n```\n\nDownloadFile downloads a file from the sandbox.\n\nParameters:\n\n- remotePath: The path to the file in the sandbox\n- localPath: Optional local path to save the file. If nil, only returns the data.\n\nReturns the file contents as a byte slice. If localPath is provided, also writes the contents to that local file.\n\nExample:\n\n```\n// Download and get contents\ndata, err := sandbox.FileSystem.DownloadFile(ctx, \"/home/user/file.txt\", nil)\nfmt.Println(string(data))\n\n// Download and save to local file\nlocalPath := \"/tmp/downloaded.txt\"\ndata, err := sandbox.FileSystem.DownloadFile(ctx, \"/home/user/file.txt\", &localPath)\n```\n\nReturns an error if the file doesn't exist or cannot be read.\n\n<a name=\"FileSystemService.FindFiles\"></a>\n### func \\(\\*FileSystemService\\) FindFiles\n\n```go\nfunc (f *FileSystemService) FindFiles(ctx context.Context, path, pattern string) (any, error)\n```\n\nFindFiles searches for text content within files.\n\nParameters:\n\n- path: The directory to search in\n- pattern: The text pattern to search for \\(supports regex\\)\n\nReturns a list of matches, each containing the file path, line number, and matching content.\n\nExample:\n\n```\nresult, err := sandbox.FileSystem.FindFiles(ctx, \"/home/user/project\", \"TODO:\")\nif err != nil {\n    return err\n}\nmatches := result.([]map[string]any)\nfor _, match := range matches {\n    fmt.Printf(\"%s:%d: %s\\n\", match[\"file\"], match[\"line\"], match[\"content\"])\n}\n```\n\nReturns an error if the search fails.\n\n<a name=\"FileSystemService.GetFileInfo\"></a>\n### func \\(\\*FileSystemService\\) GetFileInfo\n\n```go\nfunc (f *FileSystemService) GetFileInfo(ctx context.Context, path string) (*types.FileInfo, error)\n```\n\nGetFileInfo retrieves metadata for a file or directory.\n\nThe path parameter specifies the file or directory path.\n\nReturns \\[types.FileInfo\\] containing the file's name, size, permissions, modification time, and whether it's a directory.\n\nExample:\n\n```\ninfo, err := sandbox.FileSystem.GetFileInfo(ctx, \"/home/user/file.txt\")\nif err != nil {\n    return err\n}\nfmt.Printf(\"Size: %d bytes, Modified: %s\\n\", info.Size, info.ModifiedTime)\n```\n\nReturns an error if the path doesn't exist.\n\n<a name=\"FileSystemService.ListFiles\"></a>\n### func \\(\\*FileSystemService\\) ListFiles\n\n```go\nfunc (f *FileSystemService) ListFiles(ctx context.Context, path string) ([]*types.FileInfo, error)\n```\n\nListFiles lists files and directories in the specified path.\n\nThe path parameter specifies the directory to list.\n\nReturns a slice of \\[types.FileInfo\\] containing metadata for each file and directory, including name, size, permissions, modification time, and whether it's a directory.\n\nExample:\n\n```\nfiles, err := sandbox.FileSystem.ListFiles(ctx, \"/home/user\")\nif err != nil {\n    return err\n}\nfor _, file := range files {\n    if file.IsDirectory {\n        fmt.Printf(\"[DIR]  %s\\n\", file.Name)\n    } else {\n        fmt.Printf(\"[FILE] %s (%d bytes)\\n\", file.Name, file.Size)\n    }\n}\n```\n\nReturns an error if the path doesn't exist or isn't accessible.\n\n<a name=\"FileSystemService.MoveFiles\"></a>\n### func \\(\\*FileSystemService\\) MoveFiles\n\n```go\nfunc (f *FileSystemService) MoveFiles(ctx context.Context, source, destination string) error\n```\n\nMoveFiles moves or renames a file or directory.\n\nParameters:\n\n- source: The current path of the file or directory\n- destination: The new path for the file or directory\n\nThis operation can be used for both moving and renaming:\n\n- Same directory, different name = rename\n- Different directory = move\n\nExample:\n\n```\n// Rename a file\nerr := sandbox.FileSystem.MoveFiles(ctx, \"/home/user/old.txt\", \"/home/user/new.txt\")\n\n// Move a file to another directory\nerr := sandbox.FileSystem.MoveFiles(ctx, \"/home/user/file.txt\", \"/home/user/backup/file.txt\")\n```\n\nReturns an error if the operation fails.\n\n<a name=\"FileSystemService.ReplaceInFiles\"></a>\n### func \\(\\*FileSystemService\\) ReplaceInFiles\n\n```go\nfunc (f *FileSystemService) ReplaceInFiles(ctx context.Context, files []string, pattern, newValue string) (any, error)\n```\n\nReplaceInFiles replaces text in multiple files.\n\nParameters:\n\n- files: List of file paths to process\n- pattern: The text pattern to search for \\(supports regex\\)\n- newValue: The replacement text\n\nReturns a list of results for each file, indicating success or failure.\n\nExample:\n\n```\nfiles := []string{\"/home/user/file1.txt\", \"/home/user/file2.txt\"}\nresult, err := sandbox.FileSystem.ReplaceInFiles(ctx, files, \"oldValue\", \"newValue\")\nif err != nil {\n    return err\n}\nresults := result.([]map[string]any)\nfor _, r := range results {\n    if r[\"success\"].(bool) {\n        fmt.Printf(\"Updated: %s\\n\", r[\"file\"])\n    } else {\n        fmt.Printf(\"Failed: %s - %s\\n\", r[\"file\"], r[\"error\"])\n    }\n}\n```\n\nReturns an error if the operation fails entirely.\n\n<a name=\"FileSystemService.SearchFiles\"></a>\n### func \\(\\*FileSystemService\\) SearchFiles\n\n```go\nfunc (f *FileSystemService) SearchFiles(ctx context.Context, path, pattern string) (any, error)\n```\n\nSearchFiles searches for files matching a pattern in a directory.\n\nParameters:\n\n- path: The directory to search in\n- pattern: The glob pattern to match file names \\(e.g., \"\\*.txt\", \"test\\_\\*\"\\)\n\nReturns a map containing a \"files\" key with a list of matching file paths.\n\nExample:\n\n```\nresult, err := sandbox.FileSystem.SearchFiles(ctx, \"/home/user\", \"*.go\")\nif err != nil {\n    return err\n}\nfiles := result.(map[string]any)[\"files\"].([]string)\nfor _, file := range files {\n    fmt.Println(file)\n}\n```\n\nReturns an error if the search fails.\n\n<a name=\"FileSystemService.SetFilePermissions\"></a>\n### func \\(\\*FileSystemService\\) SetFilePermissions\n\n```go\nfunc (f *FileSystemService) SetFilePermissions(ctx context.Context, path string, opts ...func(*options.SetFilePermissions)) error\n```\n\nSetFilePermissions sets file permissions, owner, and group.\n\nThe path parameter specifies the file or directory to modify.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithPermissionMode\\]: Set Unix file permissions \\(e.g., \"0644\"\\)\n- \\[options.WithOwner\\]: Set file owner username\n- \\[options.WithGroup\\]: Set file group name\n\nExample:\n\n```\n// Set permissions only\nerr := sandbox.FileSystem.SetFilePermissions(ctx, \"/home/user/script.sh\",\n    options.WithPermissionMode(\"0755\"),\n)\n\n// Set owner and group\nerr := sandbox.FileSystem.SetFilePermissions(ctx, \"/home/user/file.txt\",\n    options.WithOwner(\"root\"),\n    options.WithGroup(\"users\"),\n)\n\n// Set all at once\nerr := sandbox.FileSystem.SetFilePermissions(ctx, \"/home/user/file.txt\",\n    options.WithPermissionMode(\"0640\"),\n    options.WithOwner(\"user\"),\n    options.WithGroup(\"staff\"),\n)\n```\n\nReturns an error if the operation fails.\n\n<a name=\"FileSystemService.UploadFile\"></a>\n### func \\(\\*FileSystemService\\) UploadFile\n\n```go\nfunc (f *FileSystemService) UploadFile(ctx context.Context, source any, destination string) error\n```\n\nUploadFile uploads a file to the sandbox.\n\nParameters:\n\n- source: Either a local file path \\(string\\) or file contents \\(\\[\\]byte\\)\n- destination: The destination path in the sandbox\n\nExample:\n\n```\n// Upload from local file path\nerr := sandbox.FileSystem.UploadFile(ctx, \"/local/path/file.txt\", \"/home/user/file.txt\")\n\n// Upload from byte slice\ncontent := []byte(\"Hello, World!\")\nerr := sandbox.FileSystem.UploadFile(ctx, content, \"/home/user/hello.txt\")\n```\n\nReturns an error if the upload fails.\n\n<a name=\"GitService\"></a>\n## type GitService\n\nGitService provides Git operations for a sandbox.\n\nGitService enables common Git workflows including cloning repositories, staging and committing changes, managing branches, and syncing with remote repositories. It is accessed through the \\[Sandbox.Git\\] field.\n\nExample:\n\n```\n// Clone a repository\nerr := sandbox.Git.Clone(ctx, \"https://github.com/user/repo.git\", \"/home/user/repo\")\n\n// Make changes and commit\nerr = sandbox.Git.Add(ctx, \"/home/user/repo\", []string{\".\"})\nresp, err := sandbox.Git.Commit(ctx, \"/home/user/repo\", \"Initial commit\", \"John Doe\", \"john@example.com\")\n\n// Push to remote\nerr = sandbox.Git.Push(ctx, \"/home/user/repo\",\n    options.WithPushUsername(\"username\"),\n    options.WithPushPassword(\"token\"),\n)\n```\n\n```go\ntype GitService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewGitService\"></a>\n### func NewGitService\n\n```go\nfunc NewGitService(toolboxClient *toolbox.APIClient, otel *otelState) *GitService\n```\n\nNewGitService creates a new GitService with the provided toolbox client.\n\nThis is typically called internally by the SDK when creating a [Sandbox](<#Sandbox>). Users should access GitService through \\[Sandbox.Git\\] rather than creating it directly.\n\n<a name=\"GitService.Add\"></a>\n### func \\(\\*GitService\\) Add\n\n```go\nfunc (g *GitService) Add(ctx context.Context, path string, files []string) error\n```\n\nAdd stages files for the next commit.\n\nThe path parameter specifies the repository directory. The files parameter is a list of file paths \\(relative to the repository root\\) to stage. Use \".\" to stage all changes.\n\nExample:\n\n```\n// Stage specific files\nerr := sandbox.Git.Add(ctx, \"/home/user/repo\", []string{\"file1.txt\", \"src/main.go\"})\n\n// Stage all changes\nerr := sandbox.Git.Add(ctx, \"/home/user/repo\", []string{\".\"})\n```\n\nReturns an error if the add operation fails.\n\n<a name=\"GitService.Branches\"></a>\n### func \\(\\*GitService\\) Branches\n\n```go\nfunc (g *GitService) Branches(ctx context.Context, path string) ([]string, error)\n```\n\nBranches lists all branches in a Git repository.\n\nThe path parameter specifies the repository directory.\n\nExample:\n\n```\nbranches, err := sandbox.Git.Branches(ctx, \"/home/user/repo\")\nif err != nil {\n    return err\n}\nfor _, branch := range branches {\n    fmt.Println(branch)\n}\n```\n\nReturns a slice of branch names or an error if the operation fails.\n\n<a name=\"GitService.Checkout\"></a>\n### func \\(\\*GitService\\) Checkout\n\n```go\nfunc (g *GitService) Checkout(ctx context.Context, path, name string) error\n```\n\nCheckout switches to a different branch or commit.\n\nThe path parameter specifies the repository directory. The name parameter specifies the branch name or commit SHA to checkout.\n\nExample:\n\n```\n// Switch to a branch\nerr := sandbox.Git.Checkout(ctx, \"/home/user/repo\", \"develop\")\n\n// Checkout a specific commit\nerr := sandbox.Git.Checkout(ctx, \"/home/user/repo\", \"abc123def\")\n```\n\nReturns an error if the checkout fails \\(e.g., branch doesn't exist, uncommitted changes\\).\n\n<a name=\"GitService.Clone\"></a>\n### func \\(\\*GitService\\) Clone\n\n```go\nfunc (g *GitService) Clone(ctx context.Context, url, path string, opts ...func(*options.GitClone)) error\n```\n\nClone clones a Git repository into the specified path.\n\nThe url parameter specifies the repository URL \\(HTTPS or SSH format\\). The path parameter specifies the destination directory for the cloned repository.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithBranch\\]: Clone a specific branch instead of the default\n- \\[options.WithCommitId\\]: Checkout a specific commit after cloning\n- \\[options.WithUsername\\]: Username for authentication \\(HTTPS\\)\n- \\[options.WithPassword\\]: Password or token for authentication \\(HTTPS\\)\n\nExample:\n\n```\n// Clone the default branch\nerr := sandbox.Git.Clone(ctx, \"https://github.com/user/repo.git\", \"/home/user/repo\")\n\n// Clone a specific branch with authentication\nerr := sandbox.Git.Clone(ctx, \"https://github.com/user/private-repo.git\", \"/home/user/repo\",\n    options.WithBranch(\"develop\"),\n    options.WithUsername(\"username\"),\n    options.WithPassword(\"github_token\"),\n)\n\n// Clone and checkout a specific commit\nerr := sandbox.Git.Clone(ctx, \"https://github.com/user/repo.git\", \"/home/user/repo\",\n    options.WithCommitId(\"abc123\"),\n)\n```\n\nReturns an error if the clone operation fails.\n\n<a name=\"GitService.Commit\"></a>\n### func \\(\\*GitService\\) Commit\n\n```go\nfunc (g *GitService) Commit(ctx context.Context, path, message, author, email string, opts ...func(*options.GitCommit)) (*types.GitCommitResponse, error)\n```\n\nCommit creates a new Git commit with the staged changes.\n\nParameters:\n\n- path: The repository directory\n- message: The commit message\n- author: The author name for the commit\n- email: The author email for the commit\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithAllowEmpty\\]: Allow creating commits with no changes\n\nExample:\n\n```\n// Create a commit\nresp, err := sandbox.Git.Commit(ctx, \"/home/user/repo\",\n    \"Add new feature\",\n    \"John Doe\",\n    \"john@example.com\",\n)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Created commit: %s\\n\", resp.SHA)\n\n// Create an empty commit\nresp, err := sandbox.Git.Commit(ctx, \"/home/user/repo\",\n    \"Empty commit for CI trigger\",\n    \"John Doe\",\n    \"john@example.com\",\n    options.WithAllowEmpty(true),\n)\n```\n\nReturns the \\[types.GitCommitResponse\\] containing the commit SHA, or an error if the commit fails.\n\n<a name=\"GitService.CreateBranch\"></a>\n### func \\(\\*GitService\\) CreateBranch\n\n```go\nfunc (g *GitService) CreateBranch(ctx context.Context, path, name string) error\n```\n\nCreateBranch creates a new branch at the current HEAD.\n\nThe path parameter specifies the repository directory. The name parameter specifies the name for the new branch.\n\nNote: This creates the branch but does not switch to it. Use [GitService.Checkout](<#GitService.Checkout>) to switch to the new branch after creation.\n\nExample:\n\n```\n// Create a new branch\nerr := sandbox.Git.CreateBranch(ctx, \"/home/user/repo\", \"feature/new-feature\")\nif err != nil {\n    return err\n}\n\n// Switch to the new branch\nerr = sandbox.Git.Checkout(ctx, \"/home/user/repo\", \"feature/new-feature\")\n```\n\nReturns an error if the branch creation fails \\(e.g., branch already exists\\).\n\n<a name=\"GitService.DeleteBranch\"></a>\n### func \\(\\*GitService\\) DeleteBranch\n\n```go\nfunc (g *GitService) DeleteBranch(ctx context.Context, path, name string, opts ...func(*options.GitDeleteBranch)) error\n```\n\nDeleteBranch deletes a branch from the repository.\n\nThe path parameter specifies the repository directory. The name parameter specifies the branch to delete.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithForce\\]: Force delete the branch even if not fully merged\n\nNote: You cannot delete the currently checked out branch.\n\nExample:\n\n```\n// Delete a merged branch\nerr := sandbox.Git.DeleteBranch(ctx, \"/home/user/repo\", \"feature/old-feature\")\n\n// Force delete an unmerged branch\nerr := sandbox.Git.DeleteBranch(ctx, \"/home/user/repo\", \"feature/abandoned\",\n    options.WithForce(true),\n)\n```\n\nReturns an error if the deletion fails.\n\n<a name=\"GitService.Pull\"></a>\n### func \\(\\*GitService\\) Pull\n\n```go\nfunc (g *GitService) Pull(ctx context.Context, path string, opts ...func(*options.GitPull)) error\n```\n\nPull fetches and merges changes from the remote repository.\n\nThe path parameter specifies the repository directory.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithPullUsername\\]: Username for authentication\n- \\[options.WithPullPassword\\]: Password or token for authentication\n\nExample:\n\n```\n// Pull from a public repository\nerr := sandbox.Git.Pull(ctx, \"/home/user/repo\")\n\n// Pull with authentication\nerr := sandbox.Git.Pull(ctx, \"/home/user/repo\",\n    options.WithPullUsername(\"username\"),\n    options.WithPullPassword(\"github_token\"),\n)\n```\n\nReturns an error if the pull fails \\(e.g., merge conflicts, authentication failure\\).\n\n<a name=\"GitService.Push\"></a>\n### func \\(\\*GitService\\) Push\n\n```go\nfunc (g *GitService) Push(ctx context.Context, path string, opts ...func(*options.GitPush)) error\n```\n\nPush pushes local commits to the remote repository.\n\nThe path parameter specifies the repository directory.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithPushUsername\\]: Username for authentication\n- \\[options.WithPushPassword\\]: Password or token for authentication\n\nExample:\n\n```\n// Push to a public repository (no auth required)\nerr := sandbox.Git.Push(ctx, \"/home/user/repo\")\n\n// Push with authentication\nerr := sandbox.Git.Push(ctx, \"/home/user/repo\",\n    options.WithPushUsername(\"username\"),\n    options.WithPushPassword(\"github_token\"),\n)\n```\n\nReturns an error if the push fails \\(e.g., authentication failure, remote rejection\\).\n\n<a name=\"GitService.Status\"></a>\n### func \\(\\*GitService\\) Status\n\n```go\nfunc (g *GitService) Status(ctx context.Context, path string) (*types.GitStatus, error)\n```\n\nStatus returns the current Git status of a repository.\n\nThe path parameter specifies the repository directory to check.\n\nThe returned \\[types.GitStatus\\] contains:\n\n- CurrentBranch: The name of the currently checked out branch\n- Ahead: Number of commits ahead of the remote tracking branch\n- Behind: Number of commits behind the remote tracking branch\n- BranchPublished: Whether the branch has been pushed to remote\n- FileStatus: List of files with their staging and working tree status\n\nExample:\n\n```\nstatus, err := sandbox.Git.Status(ctx, \"/home/user/repo\")\nif err != nil {\n    return err\n}\nfmt.Printf(\"On branch %s\\n\", status.CurrentBranch)\nfmt.Printf(\"Ahead: %d, Behind: %d\\n\", status.Ahead, status.Behind)\nfor _, file := range status.FileStatus {\n    fmt.Printf(\"%s %s\\n\", file.Status, file.Path)\n}\n```\n\nReturns an error if the status operation fails or the path is not a Git repository.\n\n<a name=\"KeyboardService\"></a>\n## type KeyboardService\n\nKeyboardService provides keyboard input operations.\n\nKeyboardService enables typing text, pressing keys, and executing keyboard shortcuts. Access through [ComputerUseService.Keyboard](<#ComputerUseService.Keyboard>).\n\n```go\ntype KeyboardService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewKeyboardService\"></a>\n### func NewKeyboardService\n\n```go\nfunc NewKeyboardService(toolboxClient *toolbox.APIClient, otel *otelState) *KeyboardService\n```\n\nNewKeyboardService creates a new KeyboardService.\n\n<a name=\"KeyboardService.Hotkey\"></a>\n### func \\(\\*KeyboardService\\) Hotkey\n\n```go\nfunc (k *KeyboardService) Hotkey(ctx context.Context, keys string) error\n```\n\nHotkey executes a keyboard shortcut.\n\nParameters:\n\n- keys: The hotkey combination as a string \\(e.g., \"ctrl\\+c\", \"alt\\+tab\"\\)\n\nExample:\n\n```\n// Copy (Ctrl+C)\nerr := keyboard.Hotkey(ctx, \"ctrl+c\")\n\n// Paste (Ctrl+V)\nerr := keyboard.Hotkey(ctx, \"ctrl+v\")\n\n// Switch windows (Alt+Tab)\nerr := keyboard.Hotkey(ctx, \"alt+tab\")\n```\n\nReturns an error if the hotkey fails.\n\n<a name=\"KeyboardService.Press\"></a>\n### func \\(\\*KeyboardService\\) Press\n\n```go\nfunc (k *KeyboardService) Press(ctx context.Context, key string, modifiers []string) error\n```\n\nPress simulates pressing a key with optional modifiers.\n\nParameters:\n\n- key: The key to press \\(e.g., \"a\", \"Enter\", \"Tab\", \"F1\"\\)\n- modifiers: Modifier keys to hold \\(e.g., \"ctrl\", \"alt\", \"shift\", \"meta\"\\)\n\nExample:\n\n```\n// Press Enter\nerr := keyboard.Press(ctx, \"Enter\", nil)\n\n// Press Ctrl+S\nerr := keyboard.Press(ctx, \"s\", []string{\"ctrl\"})\n\n// Press Ctrl+Shift+N\nerr := keyboard.Press(ctx, \"n\", []string{\"ctrl\", \"shift\"})\n```\n\nReturns an error if the key press fails.\n\n<a name=\"KeyboardService.Type\"></a>\n### func \\(\\*KeyboardService\\) Type\n\n```go\nfunc (k *KeyboardService) Type(ctx context.Context, text string, delay *int) error\n```\n\nType simulates typing the specified text.\n\nParameters:\n\n- text: The text to type\n- delay: Delay in milliseconds between keystrokes, nil for default\n\nExample:\n\n```\n// Type text with default speed\nerr := keyboard.Type(ctx, \"Hello, World!\", nil)\n\n// Type with custom delay between keystrokes\ndelay := 50\nerr := keyboard.Type(ctx, \"Slow typing\", &delay)\n```\n\nReturns an error if typing fails.\n\n<a name=\"LspServerService\"></a>\n## type LspServerService\n\nLspServerService provides Language Server Protocol \\(LSP\\) operations for a sandbox.\n\nLspServerService enables IDE\\-like features such as code completion, symbol search, and document analysis through LSP. The service manages a language server instance for a specific language and project path. Access through \\[Sandbox.Lsp\\].\n\nExample:\n\n```\n// Get LSP service for Python\nlsp := sandbox.Lsp(types.LspLanguageIDPython, \"/home/user/project\")\n\n// Start the language server\nif err := lsp.Start(ctx); err != nil {\n    return err\n}\ndefer lsp.Stop(ctx)\n\n// Open a file for analysis\nif err := lsp.DidOpen(ctx, \"/home/user/project/main.py\"); err != nil {\n    return err\n}\n\n// Get code completions\ncompletions, err := lsp.Completions(ctx, \"/home/user/project/main.py\",\n    types.Position{Line: 10, Character: 5})\n```\n\n```go\ntype LspServerService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewLspServerService\"></a>\n### func NewLspServerService\n\n```go\nfunc NewLspServerService(toolboxClient *toolbox.APIClient, languageID types.LspLanguageID, projectPath string, otel *otelState) *LspServerService\n```\n\nNewLspServerService creates a new LspServerService.\n\nThis is typically called internally by the SDK through \\[Sandbox.Lsp\\]. Users should access LspServerService through \\[Sandbox.Lsp\\] rather than creating it directly.\n\nParameters:\n\n- toolboxClient: The toolbox API client\n- languageID: The language identifier \\(e.g., \\[types.LspLanguageIDPython\\]\\)\n- projectPath: The root path of the project for LSP analysis\n\n<a name=\"LspServerService.Completions\"></a>\n### func \\(\\*LspServerService\\) Completions\n\n```go\nfunc (l *LspServerService) Completions(ctx context.Context, path string, position types.Position) (any, error)\n```\n\nCompletions returns code completion suggestions at a position.\n\nThe file should be opened with [LspServerService.DidOpen](<#LspServerService.DidOpen>) before requesting completions.\n\nParameters:\n\n- path: Absolute path to the file\n- position: Cursor position \\(line and character, 0\\-indexed\\)\n\nExample:\n\n```\nlsp.DidOpen(ctx, \"/home/user/project/main.py\")\ncompletions, err := lsp.Completions(ctx, \"/home/user/project/main.py\",\n    types.Position{Line: 10, Character: 5})\nif err != nil {\n    return err\n}\nfmt.Printf(\"Completions: %v\\n\", completions)\n```\n\nReturns completion items or an error.\n\n<a name=\"LspServerService.DidClose\"></a>\n### func \\(\\*LspServerService\\) DidClose\n\n```go\nfunc (l *LspServerService) DidClose(ctx context.Context, path string) error\n```\n\nDidClose notifies the language server that a file was closed.\n\nCall this when you're done working with a file to allow the server to release resources associated with it.\n\nParameters:\n\n- path: Absolute path to the file\n\nExample:\n\n```\nerr := lsp.DidClose(ctx, \"/home/user/project/main.py\")\n```\n\nReturns an error if the notification fails.\n\n<a name=\"LspServerService.DidOpen\"></a>\n### func \\(\\*LspServerService\\) DidOpen\n\n```go\nfunc (l *LspServerService) DidOpen(ctx context.Context, path string) error\n```\n\nDidOpen notifies the language server that a file was opened.\n\nThis should be called before requesting completions or symbols for a file. The path is automatically converted to a file:// URI if needed.\n\nParameters:\n\n- path: Absolute path to the file\n\nExample:\n\n```\nerr := lsp.DidOpen(ctx, \"/home/user/project/main.py\")\n```\n\nReturns an error if the notification fails.\n\n<a name=\"LspServerService.DocumentSymbols\"></a>\n### func \\(\\*LspServerService\\) DocumentSymbols\n\n```go\nfunc (l *LspServerService) DocumentSymbols(ctx context.Context, path string) ([]any, error)\n```\n\nDocumentSymbols returns all symbols \\(functions, classes, variables\\) in a document.\n\nParameters:\n\n- path: Absolute path to the file\n\nExample:\n\n```\nsymbols, err := lsp.DocumentSymbols(ctx, \"/home/user/project/main.py\")\nif err != nil {\n    return err\n}\nfor _, sym := range symbols {\n    fmt.Printf(\"Symbol: %v\\n\", sym)\n}\n```\n\nReturns a slice of symbol information or an error.\n\n<a name=\"LspServerService.SandboxSymbols\"></a>\n### func \\(\\*LspServerService\\) SandboxSymbols\n\n```go\nfunc (l *LspServerService) SandboxSymbols(ctx context.Context, query string) ([]any, error)\n```\n\nSandboxSymbols searches for symbols across the entire workspace.\n\nUse this to find symbols \\(functions, classes, etc.\\) by name across all files in the project.\n\nParameters:\n\n- query: Search query to match symbol names\n\nExample:\n\n```\nsymbols, err := lsp.SandboxSymbols(ctx, \"MyClass\")\nif err != nil {\n    return err\n}\nfor _, sym := range symbols {\n    fmt.Printf(\"Found: %v\\n\", sym)\n}\n```\n\nReturns a slice of matching symbols or an error.\n\n<a name=\"LspServerService.Start\"></a>\n### func \\(\\*LspServerService\\) Start\n\n```go\nfunc (l *LspServerService) Start(ctx context.Context) error\n```\n\nStart initializes and starts the language server.\n\nThe language server must be started before using other LSP operations. Call [LspServerService.Stop](<#LspServerService.Stop>) when finished to release resources.\n\nExample:\n\n```\nif err := lsp.Start(ctx); err != nil {\n    return err\n}\ndefer lsp.Stop(ctx)\n```\n\nReturns an error if the server fails to start.\n\n<a name=\"LspServerService.Stop\"></a>\n### func \\(\\*LspServerService\\) Stop\n\n```go\nfunc (l *LspServerService) Stop(ctx context.Context) error\n```\n\nStop shuts down the language server and releases resources.\n\nExample:\n\n```\nerr := lsp.Stop(ctx)\n```\n\nReturns an error if the server fails to stop gracefully.\n\n<a name=\"MouseService\"></a>\n## type MouseService\n\nMouseService provides mouse control operations.\n\nMouseService enables cursor movement, clicking, dragging, and scrolling. Access through [ComputerUseService.Mouse](<#ComputerUseService.Mouse>).\n\n```go\ntype MouseService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewMouseService\"></a>\n### func NewMouseService\n\n```go\nfunc NewMouseService(toolboxClient *toolbox.APIClient, otel *otelState) *MouseService\n```\n\nNewMouseService creates a new MouseService.\n\n<a name=\"MouseService.Click\"></a>\n### func \\(\\*MouseService\\) Click\n\n```go\nfunc (m *MouseService) Click(ctx context.Context, x, y int, button *string, double *bool) (map[string]any, error)\n```\n\nClick performs a mouse click at the specified coordinates.\n\nParameters:\n\n- x: X coordinate to click\n- y: Y coordinate to click\n- button: Mouse button \\(\"left\", \"right\", \"middle\"\\), nil for left click\n- double: Whether to double\\-click, nil for single click\n\nExample:\n\n```\n// Single left click\npos, err := mouse.Click(ctx, 100, 200, nil, nil)\n\n// Right click\nbutton := \"right\"\npos, err := mouse.Click(ctx, 100, 200, &button, nil)\n\n// Double click\ndoubleClick := true\npos, err := mouse.Click(ctx, 100, 200, nil, &doubleClick)\n```\n\nReturns a map with the click \"x\" and \"y\" coordinates.\n\n<a name=\"MouseService.Drag\"></a>\n### func \\(\\*MouseService\\) Drag\n\n```go\nfunc (m *MouseService) Drag(ctx context.Context, startX, startY, endX, endY int, button *string) (map[string]any, error)\n```\n\nDrag performs a mouse drag operation from start to end coordinates.\n\nParameters:\n\n- startX, startY: Starting coordinates\n- endX, endY: Ending coordinates\n- button: Mouse button to use, nil for left button\n\nExample:\n\n```\n// Drag from (100, 100) to (300, 300)\npos, err := mouse.Drag(ctx, 100, 100, 300, 300, nil)\n```\n\nReturns a map with the final \"x\" and \"y\" coordinates.\n\n<a name=\"MouseService.GetPosition\"></a>\n### func \\(\\*MouseService\\) GetPosition\n\n```go\nfunc (m *MouseService) GetPosition(ctx context.Context) (map[string]any, error)\n```\n\nGetPosition returns the current cursor position.\n\nExample:\n\n```\npos, err := mouse.GetPosition(ctx)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Cursor at (%v, %v)\\n\", pos[\"x\"], pos[\"y\"])\n```\n\nReturns a map with \"x\" and \"y\" coordinates.\n\n<a name=\"MouseService.Move\"></a>\n### func \\(\\*MouseService\\) Move\n\n```go\nfunc (m *MouseService) Move(ctx context.Context, x, y int) (map[string]any, error)\n```\n\nMove moves the cursor to the specified coordinates.\n\nParameters:\n\n- x: Target X coordinate\n- y: Target Y coordinate\n\nExample:\n\n```\npos, err := mouse.Move(ctx, 500, 300)\n```\n\nReturns a map with the new \"x\" and \"y\" coordinates.\n\n<a name=\"MouseService.Scroll\"></a>\n### func \\(\\*MouseService\\) Scroll\n\n```go\nfunc (m *MouseService) Scroll(ctx context.Context, x, y int, direction string, amount *int) (bool, error)\n```\n\nScroll performs a mouse scroll operation at the specified coordinates.\n\nParameters:\n\n- x, y: Coordinates where the scroll occurs\n- direction: Scroll direction \\(\"up\", \"down\", \"left\", \"right\"\\)\n- amount: Scroll amount, nil for default\n\nExample:\n\n```\n// Scroll down at position (500, 400)\nsuccess, err := mouse.Scroll(ctx, 500, 400, \"down\", nil)\n\n// Scroll up with specific amount\namount := 5\nsuccess, err := mouse.Scroll(ctx, 500, 400, \"up\", &amount)\n```\n\nReturns true if the scroll was successful.\n\n<a name=\"OutputChannels\"></a>\n## type OutputChannels\n\nOutputChannels provides channels for streaming execution output.\n\nAll channels are closed when execution completes or encounters an error. The Done channel always receives exactly one message with the final result.\n\n```go\ntype OutputChannels struct {\n    Stdout <-chan *types.OutputMessage   // Receives stdout messages as they occur\n    Stderr <-chan *types.OutputMessage   // Receives stderr messages as they occur\n    Errors <-chan *types.ExecutionError  // Receives execution errors\n    Done   <-chan *types.ExecutionResult // Receives final result when execution completes\n}\n```\n\n<a name=\"PaginatedSandboxes\"></a>\n## type PaginatedSandboxes\n\nPaginatedSandboxes represents a paginated list of sandboxes.\n\n```go\ntype PaginatedSandboxes struct {\n    Items      []*Sandbox // Sandboxes in this page\n    Total      int        // Total number of sandboxes\n    Page       int        // Current page number\n    TotalPages int        // Total number of pages\n}\n```\n\n<a name=\"ProcessService\"></a>\n## type ProcessService\n\nProcessService provides process execution operations for a sandbox.\n\nProcessService enables command execution, session management, and PTY \\(pseudo\\-terminal\\) operations. It supports both synchronous command execution and interactive terminal sessions. Access through \\[Sandbox.Process\\].\n\nExample:\n\n```\n// Execute a command\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"echo 'Hello, World!'\")\nfmt.Println(result.Result)\n\n// Execute with options\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"ls -la\",\n    options.WithCwd(\"/home/user/project\"),\n    options.WithExecuteTimeout(30*time.Second),\n)\n\n// Create an interactive PTY session\nhandle, err := sandbox.Process.CreatePty(ctx, \"my-terminal\")\ndefer handle.Disconnect()\n```\n\n```go\ntype ProcessService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewProcessService\"></a>\n### func NewProcessService\n\n```go\nfunc NewProcessService(toolboxClient *toolbox.APIClient, otel *otelState) *ProcessService\n```\n\nNewProcessService creates a new ProcessService with the provided toolbox client.\n\nThis is typically called internally by the SDK when creating a [Sandbox](<#Sandbox>). Users should access ProcessService through \\[Sandbox.Process\\] rather than creating it directly.\n\n<a name=\"ProcessService.CodeRun\"></a>\n### func \\(\\*ProcessService\\) CodeRun\n\n```go\nfunc (p *ProcessService) CodeRun(ctx context.Context, code string, opts ...func(*options.CodeRun)) (*types.ExecuteResponse, error)\n```\n\nCodeRun executes code in a language\\-specific way.\n\nNOTE: This method is currently unavailable as the toolbox\\-api\\-client\\-go does not expose a CodeRun endpoint. For code execution, use [ProcessService.ExecuteCommand](<#ProcessService.ExecuteCommand>) or [CodeInterpreterService](<#CodeInterpreterService>).\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithCodeRunParams\\]: Set code execution parameters\n- \\[options.WithCodeRunTimeout\\]: Set execution timeout\n\n<a name=\"ProcessService.ConnectPty\"></a>\n### func \\(\\*ProcessService\\) ConnectPty\n\n```go\nfunc (p *ProcessService) ConnectPty(ctx context.Context, sessionID string) (*PtyHandle, error)\n```\n\nConnectPty establishes a WebSocket connection to an existing PTY session.\n\nReturns a [PtyHandle](<#PtyHandle>) for interacting with the terminal. The handle provides:\n\n- DataChan\\(\\): Channel for receiving terminal output\n- SendInput\\(\\): Method for sending keyboard input\n- Resize\\(\\): Method for changing terminal size\n- Disconnect\\(\\): Method for closing the connection\n\nParameters:\n\n- sessionID: The PTY session to connect to\n\nExample:\n\n```\nhandle, err := sandbox.Process.ConnectPty(ctx, \"my-terminal\")\nif err != nil {\n    return err\n}\ndefer handle.Disconnect()\n\n// Wait for connection\nif err := handle.WaitForConnection(ctx); err != nil {\n    return err\n}\n\n// Read output\nfor data := range handle.DataChan() {\n    fmt.Print(string(data))\n}\n```\n\nReturns a [PtyHandle](<#PtyHandle>) for terminal interaction, or an error.\n\n<a name=\"ProcessService.CreatePty\"></a>\n### func \\(\\*ProcessService\\) CreatePty\n\n```go\nfunc (p *ProcessService) CreatePty(ctx context.Context, id string, opts ...func(*options.CreatePty)) (*PtyHandle, error)\n```\n\nCreatePty creates a new PTY session and immediately connects to it.\n\nThis is a convenience method that combines [ProcessService.CreatePtySession](<#ProcessService.CreatePtySession>) and [ProcessService.ConnectPty](<#ProcessService.ConnectPty>) into a single operation.\n\nParameters:\n\n- id: Unique identifier for the PTY session\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithCreatePtySize\\]: Set terminal dimensions\n- \\[options.WithCreatePtyEnv\\]: Set environment variables\n\nExample:\n\n```\nhandle, err := sandbox.Process.CreatePty(ctx, \"interactive-shell\",\n    options.WithCreatePtySize(types.PtySize{Rows: 24, Cols: 80}),\n    options.WithCreatePtyEnv(map[string]string{\"TERM\": \"xterm-256color\"}),\n)\nif err != nil {\n    return err\n}\ndefer handle.Disconnect()\n\n// Wait for connection\nif err := handle.WaitForConnection(ctx); err != nil {\n    return err\n}\n\n// Send a command\nhandle.SendInput([]byte(\"ls -la\\n\"))\n\n// Read output\nfor data := range handle.DataChan() {\n    fmt.Print(string(data))\n}\n```\n\nReturns a [PtyHandle](<#PtyHandle>) for terminal interaction, or an error.\n\n<a name=\"ProcessService.CreatePtySession\"></a>\n### func \\(\\*ProcessService\\) CreatePtySession\n\n```go\nfunc (p *ProcessService) CreatePtySession(ctx context.Context, id string, opts ...func(*options.PtySession)) (*types.PtySessionInfo, error)\n```\n\nCreatePtySession creates a PTY \\(pseudo\\-terminal\\) session.\n\nA PTY session provides a terminal interface for interactive applications. Use [ProcessService.ConnectPty](<#ProcessService.ConnectPty>) to connect to the session after creation.\n\nParameters:\n\n- id: Unique identifier for the session\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithPtySize\\]: Set terminal dimensions \\(rows and columns\\)\n- \\[options.WithPtyEnv\\]: Set environment variables\n\nExample:\n\n```\n// Create with default settings\nsession, err := sandbox.Process.CreatePtySession(ctx, \"my-terminal\")\n\n// Create with custom size\nsession, err := sandbox.Process.CreatePtySession(ctx, \"my-terminal\",\n    options.WithPtySize(types.PtySize{Rows: 24, Cols: 80}),\n)\n```\n\nReturns \\[types.PtySessionInfo\\] containing session details, or an error.\n\n<a name=\"ProcessService.CreateSession\"></a>\n### func \\(\\*ProcessService\\) CreateSession\n\n```go\nfunc (p *ProcessService) CreateSession(ctx context.Context, sessionID string) error\n```\n\nCreateSession creates a named session for executing multiple commands.\n\nSessions allow you to execute multiple commands while maintaining state \\(like environment variables and working directory\\) between commands.\n\nExample:\n\n```\n// Create a session\nerr := sandbox.Process.CreateSession(ctx, \"my-session\")\nif err != nil {\n    return err\n}\ndefer sandbox.Process.DeleteSession(ctx, \"my-session\")\n\n// Execute commands in the session\nresult, err := sandbox.Process.ExecuteSessionCommand(ctx, \"my-session\", \"cd /home/user\", false)\nresult, err = sandbox.Process.ExecuteSessionCommand(ctx, \"my-session\", \"pwd\", false)\n```\n\nReturns an error if session creation fails.\n\n<a name=\"ProcessService.DeleteSession\"></a>\n### func \\(\\*ProcessService\\) DeleteSession\n\n```go\nfunc (p *ProcessService) DeleteSession(ctx context.Context, sessionID string) error\n```\n\nDeleteSession removes a session and releases its resources.\n\nThe sessionID parameter identifies the session to delete.\n\nExample:\n\n```\nerr := sandbox.Process.DeleteSession(ctx, \"my-session\")\n```\n\nReturns an error if the session doesn't exist or deletion fails.\n\n<a name=\"ProcessService.ExecuteCommand\"></a>\n### func \\(\\*ProcessService\\) ExecuteCommand\n\n```go\nfunc (p *ProcessService) ExecuteCommand(ctx context.Context, command string, opts ...func(*options.ExecuteCommand)) (*types.ExecuteResponse, error)\n```\n\nExecuteCommand executes a shell command and returns the result.\n\nThe command is executed in a shell context. For complex commands, consider using proper shell escaping or wrapping in a script.\n\nOptional parameters can be configured using functional options:\n\n- \\[options.WithCwd\\]: Set the working directory for command execution\n- \\[options.WithCommandEnv\\]: Set environment variables\n- \\[options.WithExecuteTimeout\\]: Set execution timeout\n\nExample:\n\n```\n// Simple command\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"echo 'Hello'\")\nif err != nil {\n    return err\n}\nfmt.Println(result.Result)\n\n// Command with options\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"npm install\",\n    options.WithCwd(\"/home/user/project\"),\n    options.WithExecuteTimeout(5*time.Minute),\n)\n\n// Check exit code\nif result.ExitCode != 0 {\n    fmt.Printf(\"Command failed with exit code %d\\n\", result.ExitCode)\n}\n```\n\nReturns \\[types.ExecuteResponse\\] containing the output and exit code, or an error.\n\n<a name=\"ProcessService.ExecuteSessionCommand\"></a>\n### func \\(\\*ProcessService\\) ExecuteSessionCommand\n\n```go\nfunc (p *ProcessService) ExecuteSessionCommand(ctx context.Context, sessionID, command string, runAsync bool, suppressInputEcho bool) (map[string]any, error)\n```\n\nExecuteSessionCommand executes a command within a session.\n\nParameters:\n\n- sessionID: The session to execute the command in\n- command: The command to execute\n- runAsync: If true, return immediately without waiting for completion\n- suppressInputEcho: If true, suppress input echo\n\nWhen runAsync is true, use [ProcessService.GetSessionCommand](<#ProcessService.GetSessionCommand>) to check status and [ProcessService.GetSessionCommandLogs](<#ProcessService.GetSessionCommandLogs>) to retrieve output.\n\nExample:\n\n```\n// Synchronous execution\nresult, err := sandbox.Process.ExecuteSessionCommand(ctx, \"my-session\", \"ls -la\", false)\nif err != nil {\n    return err\n}\nfmt.Println(result[\"stdout\"])\n\n// Asynchronous execution\nresult, err := sandbox.Process.ExecuteSessionCommand(ctx, \"my-session\", \"long-running-cmd\", true)\ncmdID := result[\"id\"].(string)\n// Later: check status with GetSessionCommand(ctx, \"my-session\", cmdID)\n```\n\nReturns command result including id, exitCode \\(if completed\\), stdout, and stderr.\n\n<a name=\"ProcessService.GetEntrypointLogs\"></a>\n### func \\(\\*ProcessService\\) GetEntrypointLogs\n\n```go\nfunc (p *ProcessService) GetEntrypointLogs(ctx context.Context) (string, error)\n```\n\nGetEntrypointLogs retrieves the output logs of the sandbox entrypoint.\n\nExample:\n\n```\nlogs, err := sandbox.Process.GetEntrypointLogs(ctx)\nif err != nil {\n    return err\n}\nfmt.Println(logs)\n```\n\nReturns a string containing the entrypoint command output logs.\n\n<a name=\"ProcessService.GetEntrypointLogsStream\"></a>\n### func \\(\\*ProcessService\\) GetEntrypointLogsStream\n\n```go\nfunc (p *ProcessService) GetEntrypointLogsStream(ctx context.Context, stdout, stderr chan<- string) error\n```\n\nGetEntrypointLogsStream streams entrypoint logs as they become available.\n\nThis method establishes a WebSocket connection to stream sandbox entrypoint logs in real\\-time. The stdout and stderr channels receive log chunks as strings and are closed when the stream ends or an error occurs.\n\nParameters:\n\n- stdout: Channel to receive stdout output\n- stderr: Channel to receive stderr output\n\nThe caller should provide buffered channels to avoid blocking.\n\nExample:\n\n```\nstdout := make(chan string, 100)\nstderr := make(chan string, 100)\n\ngo func() {\n    err := sandbox.Process.GetEntrypointLogsStream(ctx, stdout, stderr)\n    if err != nil {\n        log.Printf(\"Stream error: %v\", err)\n    }\n}()\n\nfor {\n    select {\n    case chunk, ok := <-stdout:\n        if !ok {\n            stdout = nil\n        } else {\n            fmt.Print(chunk)\n        }\n    case chunk, ok := <-stderr:\n        if !ok {\n            stderr = nil\n        } else {\n            fmt.Fprint(os.Stderr, chunk)\n        }\n    }\n    if stdout == nil && stderr == nil {\n        break\n    }\n}\n```\n\nReturns an error if the connection fails or stream encounters an error.\n\n<a name=\"ProcessService.GetEntrypointSession\"></a>\n### func \\(\\*ProcessService\\) GetEntrypointSession\n\n```go\nfunc (p *ProcessService) GetEntrypointSession(ctx context.Context) (*toolbox.Session, error)\n```\n\nGetEntrypointSession retrieves information about the entrypoint session.\n\nReturns an entrypoint session information containing:\n\n- SessionId: The entrypoint session identifier\n- Commands: List of commands executed in the entrypoint session\n\nExample:\n\n```\ninfo, err := sandbox.Process.GetEntrypointSession(ctx)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Session: %s\\n\", info.SessionId)\n```\n\nReturns an error if the session doesn't exist.\n\n<a name=\"ProcessService.GetPtySessionInfo\"></a>\n### func \\(\\*ProcessService\\) GetPtySessionInfo\n\n```go\nfunc (p *ProcessService) GetPtySessionInfo(ctx context.Context, sessionID string) (*types.PtySessionInfo, error)\n```\n\nGetPtySessionInfo retrieves information about a PTY session.\n\nParameters:\n\n- sessionID: The PTY session identifier\n\nExample:\n\n```\ninfo, err := sandbox.Process.GetPtySessionInfo(ctx, \"my-terminal\")\nif err != nil {\n    return err\n}\nfmt.Printf(\"Terminal size: %dx%d\\n\", info.Cols, info.Rows)\n```\n\nReturns \\[types.PtySessionInfo\\] with session details, or an error.\n\n<a name=\"ProcessService.GetSession\"></a>\n### func \\(\\*ProcessService\\) GetSession\n\n```go\nfunc (p *ProcessService) GetSession(ctx context.Context, sessionID string) (map[string]any, error)\n```\n\nGetSession retrieves information about a session.\n\nThe sessionID parameter identifies the session to query.\n\nReturns a map containing:\n\n- sessionId: The session identifier\n- commands: List of commands executed in the session\n\nExample:\n\n```\ninfo, err := sandbox.Process.GetSession(ctx, \"my-session\")\nif err != nil {\n    return err\n}\nfmt.Printf(\"Session: %s\\n\", info[\"sessionId\"])\n```\n\nReturns an error if the session doesn't exist.\n\n<a name=\"ProcessService.GetSessionCommand\"></a>\n### func \\(\\*ProcessService\\) GetSessionCommand\n\n```go\nfunc (p *ProcessService) GetSessionCommand(ctx context.Context, sessionID, commandID string) (map[string]any, error)\n```\n\nGetSessionCommand retrieves the status of a command in a session.\n\nParameters:\n\n- sessionID: The session containing the command\n- commandID: The command identifier \\(from ExecuteSessionCommand result\\)\n\nExample:\n\n```\nstatus, err := sandbox.Process.GetSessionCommand(ctx, \"my-session\", cmdID)\nif err != nil {\n    return err\n}\nif exitCode, ok := status[\"exitCode\"]; ok {\n    fmt.Printf(\"Command completed with exit code: %v\\n\", exitCode)\n} else {\n    fmt.Println(\"Command still running\")\n}\n```\n\nReturns command status including id, command text, and exitCode \\(if completed\\).\n\n<a name=\"ProcessService.GetSessionCommandLogs\"></a>\n### func \\(\\*ProcessService\\) GetSessionCommandLogs\n\n```go\nfunc (p *ProcessService) GetSessionCommandLogs(ctx context.Context, sessionID, commandID string) (map[string]any, error)\n```\n\nGetSessionCommandLogs retrieves the output logs of a command.\n\nParameters:\n\n- sessionID: The session containing the command\n- commandID: The command identifier\n\nExample:\n\n```\nlogs, err := sandbox.Process.GetSessionCommandLogs(ctx, \"my-session\", cmdID)\nif err != nil {\n    return err\n}\nfmt.Println(logs[\"logs\"])\n```\n\nReturns a map containing the \"logs\" key with command output.\n\n<a name=\"ProcessService.GetSessionCommandLogsStream\"></a>\n### func \\(\\*ProcessService\\) GetSessionCommandLogsStream\n\n```go\nfunc (p *ProcessService) GetSessionCommandLogsStream(ctx context.Context, sessionID, commandID string, stdout, stderr chan<- string) error\n```\n\nGetSessionCommandLogsStream streams command logs as they become available.\n\nThis method establishes a WebSocket connection to stream logs in real\\-time. The stdout and stderr channels receive log chunks as strings and are closed when the stream ends or an error occurs.\n\nParameters:\n\n- sessionID: The session containing the command\n- commandID: The command identifier\n- stdout: Channel to receive stdout output\n- stderr: Channel to receive stderr output\n\nThe caller should provide buffered channels to avoid blocking.\n\nExample:\n\n```\nstdout := make(chan string, 100)\nstderr := make(chan string, 100)\n\ngo func() {\n    err := sandbox.Process.GetSessionCommandLogsStream(ctx, \"session\", \"cmd\", stdout, stderr)\n    if err != nil {\n        log.Printf(\"Stream error: %v\", err)\n    }\n}()\n\nfor {\n    select {\n    case chunk, ok := <-stdout:\n        if !ok {\n            stdout = nil\n        } else {\n            fmt.Print(chunk)\n        }\n    case chunk, ok := <-stderr:\n        if !ok {\n            stderr = nil\n        } else {\n            fmt.Fprint(os.Stderr, chunk)\n        }\n    }\n    if stdout == nil && stderr == nil {\n        break\n    }\n}\n```\n\nReturns an error if the connection fails or stream encounters an error.\n\n<a name=\"ProcessService.KillPtySession\"></a>\n### func \\(\\*ProcessService\\) KillPtySession\n\n```go\nfunc (p *ProcessService) KillPtySession(ctx context.Context, sessionID string) error\n```\n\nKillPtySession terminates a PTY session.\n\nThis ends the terminal session and any processes running in it.\n\nParameters:\n\n- sessionID: The PTY session to terminate\n\nExample:\n\n```\nerr := sandbox.Process.KillPtySession(ctx, \"my-terminal\")\n```\n\nReturns an error if the session doesn't exist or termination fails.\n\n<a name=\"ProcessService.ListPtySessions\"></a>\n### func \\(\\*ProcessService\\) ListPtySessions\n\n```go\nfunc (p *ProcessService) ListPtySessions(ctx context.Context) ([]*types.PtySessionInfo, error)\n```\n\nListPtySessions returns all active PTY sessions.\n\nExample:\n\n```\nsessions, err := sandbox.Process.ListPtySessions(ctx)\nif err != nil {\n    return err\n}\nfor _, session := range sessions {\n    fmt.Printf(\"PTY: %s (%dx%d)\\n\", session.ID, session.Cols, session.Rows)\n}\n```\n\nReturns a slice of \\[types.PtySessionInfo\\], or an error.\n\n<a name=\"ProcessService.ListSessions\"></a>\n### func \\(\\*ProcessService\\) ListSessions\n\n```go\nfunc (p *ProcessService) ListSessions(ctx context.Context) ([]map[string]any, error)\n```\n\nListSessions returns all active sessions.\n\nExample:\n\n```\nsessions, err := sandbox.Process.ListSessions(ctx)\nif err != nil {\n    return err\n}\nfor _, session := range sessions {\n    fmt.Printf(\"Session: %s\\n\", session[\"sessionId\"])\n}\n```\n\nReturns a slice of session information maps, or an error.\n\n<a name=\"ProcessService.ResizePtySession\"></a>\n### func \\(\\*ProcessService\\) ResizePtySession\n\n```go\nfunc (p *ProcessService) ResizePtySession(ctx context.Context, sessionID string, ptySize types.PtySize) (*types.PtySessionInfo, error)\n```\n\nResizePtySession changes the terminal dimensions of a PTY session.\n\nThis sends a SIGWINCH signal to applications, notifying them of the size change.\n\nParameters:\n\n- sessionID: The PTY session to resize\n- ptySize: New terminal dimensions\n\nExample:\n\n```\nnewSize := types.PtySize{Rows: 40, Cols: 120}\ninfo, err := sandbox.Process.ResizePtySession(ctx, \"my-terminal\", newSize)\nif err != nil {\n    return err\n}\nfmt.Printf(\"New size: %dx%d\\n\", info.Cols, info.Rows)\n```\n\nReturns updated \\[types.PtySessionInfo\\], or an error.\n\n<a name=\"PtyHandle\"></a>\n## type PtyHandle\n\nPtyHandle manages a WebSocket connection to a PTY \\(pseudo\\-terminal\\) session.\n\nPtyHandle provides methods for sending input, receiving output via channels, resizing the terminal, and managing the connection lifecycle. It implements [io.Reader](<https://pkg.go.dev/io/#Reader>) and [io.Writer](<https://pkg.go.dev/io/#Writer>) interfaces for integration with standard Go I/O.\n\nCreate a PtyHandle using [ProcessService.CreatePty](<#ProcessService.CreatePty>).\n\nExample:\n\n```\n// Create a PTY session\nhandle, err := sandbox.Process.CreatePty(ctx, \"my-pty\", nil)\nif err != nil {\n    return err\n}\ndefer handle.Disconnect()\n\n// Wait for connection to be established\nif err := handle.WaitForConnection(ctx); err != nil {\n    return err\n}\n\n// Send input\nhandle.SendInput([]byte(\"ls -la\\n\"))\n\n// Read output from channel\nfor data := range handle.DataChan() {\n    fmt.Print(string(data))\n}\n\n// Or use as io.Reader\nio.Copy(os.Stdout, handle)\n```\n\n```go\ntype PtyHandle struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"PtyHandle.DataChan\"></a>\n### func \\(\\*PtyHandle\\) DataChan\n\n```go\nfunc (h *PtyHandle) DataChan() <-chan []byte\n```\n\nDataChan returns a channel for receiving PTY output.\n\nThe channel receives raw bytes from the terminal. It is closed when the PTY session ends or the connection is closed.\n\nExample:\n\n```\nfor data := range handle.DataChan() {\n    fmt.Print(string(data))\n}\n```\n\n<a name=\"PtyHandle.Disconnect\"></a>\n### func \\(\\*PtyHandle\\) Disconnect\n\n```go\nfunc (h *PtyHandle) Disconnect() error\n```\n\nDisconnect closes the WebSocket connection and releases resources.\n\nCall this when done with the PTY session. This does not terminate the underlying process \\- use [PtyHandle.Kill](<#PtyHandle.Kill>) for that.\n\nExample:\n\n```\ndefer handle.Disconnect()\n```\n\nReturns an error if the WebSocket close fails.\n\n<a name=\"PtyHandle.Error\"></a>\n### func \\(\\*PtyHandle\\) Error\n\n```go\nfunc (h *PtyHandle) Error() *string\n```\n\nError returns the error message if the PTY session failed, or nil otherwise.\n\n<a name=\"PtyHandle.ExitCode\"></a>\n### func \\(\\*PtyHandle\\) ExitCode\n\n```go\nfunc (h *PtyHandle) ExitCode() *int\n```\n\nExitCode returns the exit code of the PTY process, or nil if still running.\n\n<a name=\"PtyHandle.IsConnected\"></a>\n### func \\(\\*PtyHandle\\) IsConnected\n\n```go\nfunc (h *PtyHandle) IsConnected() bool\n```\n\nIsConnected returns true if the WebSocket connection is active.\n\n<a name=\"PtyHandle.Kill\"></a>\n### func \\(\\*PtyHandle\\) Kill\n\n```go\nfunc (h *PtyHandle) Kill(ctx context.Context) error\n```\n\nKill terminates the PTY session and its associated process.\n\nThis operation is irreversible. The process receives a SIGKILL signal and terminates immediately.\n\nExample:\n\n```\nerr := handle.Kill(ctx)\n```\n\nReturns an error if the kill operation fails.\n\n<a name=\"PtyHandle.Read\"></a>\n### func \\(\\*PtyHandle\\) Read\n\n```go\nfunc (h *PtyHandle) Read(p []byte) (n int, err error)\n```\n\nRead implements [io.Reader](<https://pkg.go.dev/io/#Reader>) for reading PTY output.\n\nThis method blocks until data is available or the PTY closes \\(returns [io.EOF](<https://pkg.go.dev/io/#EOF>)\\). Use with [io.Copy](<https://pkg.go.dev/io/#Copy>), [bufio.Scanner](<https://pkg.go.dev/bufio/#Scanner>), or any standard Go I/O utilities.\n\nExample:\n\n```\n// Copy all output to stdout\nio.Copy(os.Stdout, handle)\n\n// Use with bufio.Scanner\nscanner := bufio.NewScanner(handle)\nfor scanner.Scan() {\n    fmt.Println(scanner.Text())\n}\n```\n\n<a name=\"PtyHandle.Resize\"></a>\n### func \\(\\*PtyHandle\\) Resize\n\n```go\nfunc (h *PtyHandle) Resize(ctx context.Context, cols, rows int) (*types.PtySessionInfo, error)\n```\n\nResize changes the PTY terminal dimensions.\n\nThis notifies terminal applications about the new dimensions via SIGWINCH signal. Call this when the terminal display size changes.\n\nParameters:\n\n- cols: Number of columns \\(width in characters\\)\n- rows: Number of rows \\(height in characters\\)\n\nExample:\n\n```\ninfo, err := handle.Resize(ctx, 120, 40)\n```\n\nReturns updated \\[types.PtySessionInfo\\] or an error.\n\n<a name=\"PtyHandle.SendInput\"></a>\n### func \\(\\*PtyHandle\\) SendInput\n\n```go\nfunc (h *PtyHandle) SendInput(data []byte) error\n```\n\nSendInput sends input data to the PTY session.\n\nThe data is sent as raw bytes and will be processed as if typed in the terminal. Use this to send commands, keystrokes, or any terminal input.\n\nExample:\n\n```\n// Send a command\nhandle.SendInput([]byte(\"ls -la\\n\"))\n\n// Send Ctrl+C\nhandle.SendInput([]byte{0x03})\n```\n\nReturns an error if the PTY is not connected or sending fails.\n\n<a name=\"PtyHandle.SessionID\"></a>\n### func \\(\\*PtyHandle\\) SessionID\n\n```go\nfunc (h *PtyHandle) SessionID() string\n```\n\nSessionID returns the unique identifier for this PTY session.\n\n<a name=\"PtyHandle.Wait\"></a>\n### func \\(\\*PtyHandle\\) Wait\n\n```go\nfunc (h *PtyHandle) Wait(ctx context.Context) (*types.PtyResult, error)\n```\n\nWait blocks until the PTY process exits and returns the result.\n\nExample:\n\n```\nresult, err := handle.Wait(ctx)\nif err != nil {\n    return err\n}\nif result.ExitCode != nil {\n    fmt.Printf(\"Process exited with code: %d\\n\", *result.ExitCode)\n}\n```\n\nReturns \\[types.PtyResult\\] with exit code and any error, or an error if the context is cancelled.\n\n<a name=\"PtyHandle.WaitForConnection\"></a>\n### func \\(\\*PtyHandle\\) WaitForConnection\n\n```go\nfunc (h *PtyHandle) WaitForConnection(ctx context.Context) error\n```\n\nWaitForConnection waits for the WebSocket connection to be established.\n\nThis method blocks until the PTY session is ready to receive input and send output, or until a timeout \\(10 seconds\\) expires. Always call this after creating a PTY to ensure the connection is ready.\n\nExample:\n\n```\nhandle, _ := sandbox.Process.CreatePty(ctx, \"my-pty\", nil)\nif err := handle.WaitForConnection(ctx); err != nil {\n    return fmt.Errorf(\"PTY connection failed: %w\", err)\n}\n```\n\nReturns an error if the connection times out or fails.\n\n<a name=\"PtyHandle.Write\"></a>\n### func \\(\\*PtyHandle\\) Write\n\n```go\nfunc (h *PtyHandle) Write(p []byte) (n int, err error)\n```\n\nWrite implements [io.Writer](<https://pkg.go.dev/io/#Writer>) for sending input to the PTY.\n\nExample:\n\n```\n// Write directly\nhandle.Write([]byte(\"echo hello\\n\"))\n\n// Use with io.Copy\nio.Copy(handle, strings.NewReader(\"echo hello\\n\"))\n```\n\n<a name=\"PushAccessCredentials\"></a>\n## type PushAccessCredentials\n\nPushAccessCredentials holds temporary credentials for uploading to object storage.\n\nThese credentials are obtained from the API and used for uploading build contexts when creating snapshots with custom [DockerImage](<#DockerImage>) definitions.\n\n```go\ntype PushAccessCredentials struct {\n    StorageURL     string `json:\"storageUrl\"`\n    AccessKey      string `json:\"accessKey\"`\n    Secret         string `json:\"secret\"`\n    SessionToken   string `json:\"sessionToken\"`\n    Bucket         string `json:\"bucket\"`\n    OrganizationID string `json:\"organizationId\"`\n}\n```\n\n<a name=\"RecordingService\"></a>\n## type RecordingService\n\nRecordingService provides screen recording operations.\n\nRecordingService enables starting, stopping, and managing screen recordings. Access through [ComputerUseService.Recording](<#ComputerUseService.Recording>).\n\n```go\ntype RecordingService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewRecordingService\"></a>\n### func NewRecordingService\n\n```go\nfunc NewRecordingService(toolboxClient *toolbox.APIClient) *RecordingService\n```\n\nNewRecordingService creates a new RecordingService.\n\n<a name=\"RecordingService.Delete\"></a>\n### func \\(\\*RecordingService\\) Delete\n\n```go\nfunc (r *RecordingService) Delete(ctx context.Context, id string) error\n```\n\nDelete deletes a recording by ID.\n\nParameters:\n\n- id: The ID of the recording to delete\n\nExample:\n\n```\nerr := cu.Recording().Delete(ctx, recordingID)\nif err != nil {\n    return err\n}\nfmt.Println(\"Recording deleted\")\n```\n\nReturns an error if the deletion fails.\n\n<a name=\"RecordingService.Download\"></a>\n### func \\(\\*RecordingService\\) Download\n\n```go\nfunc (r *RecordingService) Download(ctx context.Context, id string, localPath string) error\n```\n\nDownload downloads a recording file and saves it to a local path.\n\nThe file is streamed directly to disk without loading the entire content into memory.\n\nParameters:\n\n- id: The ID of the recording to download\n- localPath: Path to save the recording file locally\n\nExample:\n\n```\nerr := cu.Recording().Download(ctx, recordingID, \"local_recording.mp4\")\nif err != nil {\n    return err\n}\nfmt.Println(\"Recording downloaded\")\n```\n\nReturns an error if the download fails.\n\n<a name=\"RecordingService.Get\"></a>\n### func \\(\\*RecordingService\\) Get\n\n```go\nfunc (r *RecordingService) Get(ctx context.Context, id string) (*toolbox.Recording, error)\n```\n\nGet gets details of a specific recording by ID.\n\nParameters:\n\n- id: The ID of the recording to retrieve\n\nExample:\n\n```\nrecording, err := cu.Recording().Get(ctx, recordingID)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Recording: %s\\n\", recording.GetFileName())\nfmt.Printf(\"Status: %s\\n\", recording.GetStatus())\nfmt.Printf(\"Duration: %v seconds\\n\", recording.GetDurationSeconds())\n```\n\nReturns \\[toolbox.Recording\\] with recording details.\n\n<a name=\"RecordingService.List\"></a>\n### func \\(\\*RecordingService\\) List\n\n```go\nfunc (r *RecordingService) List(ctx context.Context) (*toolbox.ListRecordingsResponse, error)\n```\n\nList lists all recordings \\(active and completed\\).\n\nExample:\n\n```\nrecordings, err := cu.Recording().List(ctx)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Found %d recordings\\n\", len(recordings.GetRecordings()))\nfor _, rec := range recordings.GetRecordings() {\n    fmt.Printf(\"- %s: %s\\n\", rec.GetFileName(), rec.GetStatus())\n}\n```\n\nReturns \\[toolbox.ListRecordingsResponse\\] with all recordings.\n\n<a name=\"RecordingService.Start\"></a>\n### func \\(\\*RecordingService\\) Start\n\n```go\nfunc (r *RecordingService) Start(ctx context.Context, label *string) (*toolbox.Recording, error)\n```\n\nStart starts a new screen recording session.\n\nParameters:\n\n- label: Optional custom label for the recording\n\nExample:\n\n```\n// Start a recording with a label\nrecording, err := cu.Recording().Start(ctx, stringPtr(\"my-test-recording\"))\nif err != nil {\n    return err\n}\nfmt.Printf(\"Recording started: %s\\n\", recording.GetId())\nfmt.Printf(\"File: %s\\n\", recording.GetFilePath())\n```\n\nReturns \\[toolbox.Recording\\] with recording details.\n\n<a name=\"RecordingService.Stop\"></a>\n### func \\(\\*RecordingService\\) Stop\n\n```go\nfunc (r *RecordingService) Stop(ctx context.Context, id string) (*toolbox.Recording, error)\n```\n\nStop stops an active screen recording session.\n\nParameters:\n\n- id: The ID of the recording to stop\n\nExample:\n\n```\nresult, err := cu.Recording().Stop(ctx, recordingID)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Recording stopped: %v seconds\\n\", result.GetDurationSeconds())\nfmt.Printf(\"Saved to: %s\\n\", result.GetFilePath())\n```\n\nReturns \\[toolbox.Recording\\] with recording details.\n\n<a name=\"Sandbox\"></a>\n## type Sandbox\n\nSandbox represents a Daytona sandbox environment.\n\nA Sandbox provides an isolated development environment with file system, git, process execution, code interpretation, and desktop automation capabilities. Sandboxes can be started, stopped, archived, and deleted.\n\nAccess sandbox capabilities through the service fields:\n\n- FileSystem: File and directory operations\n- Git: Git repository operations\n- Process: Command execution and PTY sessions\n- CodeInterpreter: Python code execution\n- ComputerUse: Desktop automation \\(mouse, keyboard, screenshots\\)\n\nExample:\n\n```\n// Create and use a sandbox\nsandbox, err := client.Create(ctx)\nif err != nil {\n    return err\n}\ndefer sandbox.Delete(ctx)\n\n// Execute a command\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"echo 'Hello'\")\n\n// Work with files\nerr = sandbox.FileSystem.UploadFile(ctx, \"local.txt\", \"/home/user/remote.txt\")\n```\n\n```go\ntype Sandbox struct {\n    ID            string                 // Unique sandbox identifier\n    Name          string                 // Human-readable sandbox name\n    State         apiclient.SandboxState // Current sandbox state\n    Target        string                 // Target region/environment where the sandbox runs\n    ToolboxClient *toolbox.APIClient     // Internal API client\n\n    // AutoArchiveInterval is the time in minutes after stopping before auto-archiving.\n    // Set to 0 to disable auto-archiving.\n    AutoArchiveInterval int\n\n    // AutoDeleteInterval is the time in minutes after stopping before auto-deletion.\n    // Set to -1 to disable auto-deletion.\n    // Set to 0 to delete immediately upon stopping.\n    AutoDeleteInterval int\n\n    // NetworkBlockAll blocks all network access when true.\n    NetworkBlockAll bool\n\n    // NetworkAllowList is a comma-separated list of allowed CIDR addresses.\n    NetworkAllowList *string\n\n    FileSystem      *FileSystemService      // File system operations\n    Git             *GitService             // Git operations\n    Process         *ProcessService         // Process and PTY operations\n    CodeInterpreter *CodeInterpreterService // Python code execution\n    ComputerUse     *ComputerUseService     // Desktop automation\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewSandbox\"></a>\n### func NewSandbox\n\n```go\nfunc NewSandbox(client *Client, toolboxClient *toolbox.APIClient, id string, name string, state apiclient.SandboxState, target string, autoArchiveInterval int, autoDeleteInterval int, networkBlockAll bool, networkAllowList *string) *Sandbox\n```\n\nNewSandbox creates a new Sandbox instance.\n\nThis is typically called internally by the SDK. Users should create sandboxes using [Client.Create](<#Client.Create>) rather than calling this directly.\n\n<a name=\"Sandbox.Archive\"></a>\n### func \\(\\*Sandbox\\) Archive\n\n```go\nfunc (s *Sandbox) Archive(ctx context.Context) error\n```\n\nArchive archives the sandbox, preserving its state in cost\\-effective storage.\n\nWhen sandboxes are archived, the entire filesystem state is moved to object storage, making it possible to keep sandboxes available for extended periods at reduced cost. Use [Sandbox.Start](<#Sandbox.Start>) to unarchive and resume.\n\nExample:\n\n```\nerr := sandbox.Archive(ctx)\nif err != nil {\n    return err\n}\n// Sandbox is now archived and can be restored later\n```\n\n<a name=\"Sandbox.Delete\"></a>\n### func \\(\\*Sandbox\\) Delete\n\n```go\nfunc (s *Sandbox) Delete(ctx context.Context) error\n```\n\nDelete deletes the sandbox with a default timeout of 60 seconds.\n\nThis operation is irreversible. All data in the sandbox will be lost. For custom timeout, use [Sandbox.DeleteWithTimeout](<#Sandbox.DeleteWithTimeout>).\n\nExample:\n\n```\nerr := sandbox.Delete(ctx)\n```\n\n<a name=\"Sandbox.DeleteWithTimeout\"></a>\n### func \\(\\*Sandbox\\) DeleteWithTimeout\n\n```go\nfunc (s *Sandbox) DeleteWithTimeout(ctx context.Context, timeout time.Duration) error\n```\n\nDeleteWithTimeout deletes the sandbox with a custom timeout. 0 means no timeout.\n\nExample:\n\n```\nerr := sandbox.DeleteWithTimeout(ctx, 2*time.Minute)\n```\n\n<a name=\"Sandbox.GetPreviewLink\"></a>\n### func \\(\\*Sandbox\\) GetPreviewLink\n\n```go\nfunc (s *Sandbox) GetPreviewLink(ctx context.Context, port int) (*types.PreviewLink, error)\n```\n\nGetPreviewLink returns a preview link for accessing a port on the sandbox.\n\nThe returned PreviewLink contains both the URL and an authentication token. For private sandboxes, the token must be sent via the \"x\\-daytona\\-preview\\-token\" request header.\n\nExample:\n\n```\npreview, err := sandbox.GetPreviewLink(ctx, 3000)\nif err != nil {\n    return err\n}\nfmt.Printf(\"URL: %s\\nToken: %s\\n\", preview.URL, preview.Token)\n```\n\n<a name=\"Sandbox.GetUserHomeDir\"></a>\n### func \\(\\*Sandbox\\) GetUserHomeDir\n\n```go\nfunc (s *Sandbox) GetUserHomeDir(ctx context.Context) (string, error)\n```\n\nGetUserHomeDir returns the user's home directory path in the sandbox.\n\nExample:\n\n```\nhomeDir, err := sandbox.GetUserHomeDir(ctx)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Home directory: %s\\n\", homeDir) // e.g., \"/home/daytona\"\n```\n\n<a name=\"Sandbox.GetWorkingDir\"></a>\n### func \\(\\*Sandbox\\) GetWorkingDir\n\n```go\nfunc (s *Sandbox) GetWorkingDir(ctx context.Context) (string, error)\n```\n\nGetWorkingDir returns the current working directory in the sandbox.\n\nExample:\n\n```\nworkDir, err := sandbox.GetWorkingDir(ctx)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Working directory: %s\\n\", workDir)\n```\n\n<a name=\"Sandbox.RefreshData\"></a>\n### func \\(\\*Sandbox\\) RefreshData\n\n```go\nfunc (s *Sandbox) RefreshData(ctx context.Context) error\n```\n\nRefreshData refreshes the sandbox data from the API.\n\nThis updates the sandbox's State and other properties from the server. Useful for checking if the sandbox state has changed.\n\nExample:\n\n```\nerr := sandbox.RefreshData(ctx)\nif err != nil {\n    return err\n}\nfmt.Printf(\"Current state: %s\\n\", sandbox.State)\n```\n\n<a name=\"Sandbox.Resize\"></a>\n### func \\(\\*Sandbox\\) Resize\n\n```go\nfunc (s *Sandbox) Resize(ctx context.Context, resources *types.Resources) error\n```\n\nResize resizes the sandbox resources with a default timeout of 60 seconds.\n\nChanges the CPU, memory, or disk allocation for the sandbox. Resizing a started sandbox allows increasing CPU and memory. To resize disk or decrease resources, the sandbox must be stopped first.\n\nExample:\n\n```\n// Resize a started sandbox (CPU and memory can be increased)\nerr := sandbox.Resize(ctx, &types.Resources{CPU: 4, Memory: 8})\n\n// Resize a stopped sandbox (CPU, memory, and disk can be changed)\nsandbox.Stop(ctx)\nerr := sandbox.Resize(ctx, &types.Resources{CPU: 2, Memory: 4, Disk: 30})\n```\n\n<a name=\"Sandbox.ResizeWithTimeout\"></a>\n### func \\(\\*Sandbox\\) ResizeWithTimeout\n\n```go\nfunc (s *Sandbox) ResizeWithTimeout(ctx context.Context, resources *types.Resources, timeout time.Duration) error\n```\n\nResizeWithTimeout resizes the sandbox resources with a custom timeout.\n\nChanges the CPU, memory, or disk allocation for the sandbox. Resizing a started sandbox allows increasing CPU and memory. To resize disk or decrease resources, the sandbox must be stopped first. 0 means no timeout.\n\nExample:\n\n```\nerr := sandbox.ResizeWithTimeout(ctx, &types.Resources{CPU: 4, Memory: 8}, 2*time.Minute)\n```\n\n<a name=\"Sandbox.SetAutoArchiveInterval\"></a>\n### func \\(\\*Sandbox\\) SetAutoArchiveInterval\n\n```go\nfunc (s *Sandbox) SetAutoArchiveInterval(ctx context.Context, intervalMinutes *int) error\n```\n\nSetAutoArchiveInterval sets the auto\\-archive interval in minutes.\n\nThe sandbox will be automatically archived after being stopped for this many minutes. Set to 0 to disable auto\\-archiving \\(sandbox will never auto\\-archive\\).\n\nExample:\n\n```\n// Archive after 30 minutes of being stopped\ninterval := 30\nerr := sandbox.SetAutoArchiveInterval(ctx, &interval)\n\n// Disable auto-archiving\ninterval := 0\nerr := sandbox.SetAutoArchiveInterval(ctx, &interval)\n```\n\n<a name=\"Sandbox.SetAutoDeleteInterval\"></a>\n### func \\(\\*Sandbox\\) SetAutoDeleteInterval\n\n```go\nfunc (s *Sandbox) SetAutoDeleteInterval(ctx context.Context, intervalMinutes *int) error\n```\n\nSetAutoDeleteInterval sets the auto\\-delete interval in minutes.\n\nThe sandbox will be automatically deleted after being stopped for this many minutes.\n\nSpecial values:\n\n- \\-1: Disable auto\\-deletion \\(sandbox will never auto\\-delete\\)\n- 0: Delete immediately upon stopping\n\nExample:\n\n```\n// Delete after 60 minutes of being stopped\ninterval := 60\nerr := sandbox.SetAutoDeleteInterval(ctx, &interval)\n\n// Delete immediately when stopped\ninterval := 0\nerr := sandbox.SetAutoDeleteInterval(ctx, &interval)\n\n// Never auto-delete\ninterval := -1\nerr := sandbox.SetAutoDeleteInterval(ctx, &interval)\n```\n\n<a name=\"Sandbox.SetLabels\"></a>\n### func \\(\\*Sandbox\\) SetLabels\n\n```go\nfunc (s *Sandbox) SetLabels(ctx context.Context, labels map[string]string) error\n```\n\nSetLabels sets custom labels on the sandbox.\n\nLabels are key\\-value pairs that can be used for organization and filtering. This replaces all existing labels.\n\nExample:\n\n```\nerr := sandbox.SetLabels(ctx, map[string]string{\n    \"environment\": \"development\",\n    \"team\": \"backend\",\n    \"project\": \"api-server\",\n})\n```\n\n<a name=\"Sandbox.Start\"></a>\n### func \\(\\*Sandbox\\) Start\n\n```go\nfunc (s *Sandbox) Start(ctx context.Context) error\n```\n\nStart starts the sandbox with a default timeout of 60 seconds.\n\nIf the sandbox is already running, this is a no\\-op. For custom timeout, use [Sandbox.StartWithTimeout](<#Sandbox.StartWithTimeout>).\n\nExample:\n\n```\nerr := sandbox.Start(ctx)\nif err != nil {\n    return err\n}\n// Sandbox is now running\n```\n\n<a name=\"Sandbox.StartWithTimeout\"></a>\n### func \\(\\*Sandbox\\) StartWithTimeout\n\n```go\nfunc (s *Sandbox) StartWithTimeout(ctx context.Context, timeout time.Duration) error\n```\n\nStartWithTimeout starts the sandbox with a custom timeout.\n\nThe method blocks until the sandbox reaches the \"started\" state or the timeout is exceeded. 0 means no timeout.\n\nExample:\n\n```\nerr := sandbox.StartWithTimeout(ctx, 2*time.Minute)\nif err != nil {\n    return err\n}\n```\n\n<a name=\"Sandbox.Stop\"></a>\n### func \\(\\*Sandbox\\) Stop\n\n```go\nfunc (s *Sandbox) Stop(ctx context.Context) error\n```\n\nStop stops the sandbox with a default timeout of 60 seconds.\n\nStopping a sandbox preserves its state. Use [Sandbox.Start](<#Sandbox.Start>) to resume. For custom timeout, use [Sandbox.StopWithTimeout](<#Sandbox.StopWithTimeout>).\n\nExample:\n\n```\nerr := sandbox.Stop(ctx)\n```\n\n<a name=\"Sandbox.StopWithTimeout\"></a>\n### func \\(\\*Sandbox\\) StopWithTimeout\n\n```go\nfunc (s *Sandbox) StopWithTimeout(ctx context.Context, timeout time.Duration) error\n```\n\nStopWithTimeout stops the sandbox with a custom timeout.\n\nThe method blocks until the sandbox reaches the \"stopped\" state or the timeout is exceeded. 0 means no timeout.\n\nExample:\n\n```\nerr := sandbox.StopWithTimeout(ctx, 2*time.Minute)\n```\n\n<a name=\"Sandbox.WaitForResize\"></a>\n### func \\(\\*Sandbox\\) WaitForResize\n\n```go\nfunc (s *Sandbox) WaitForResize(ctx context.Context, timeout time.Duration) error\n```\n\nWaitForResize waits for the sandbox resize operation to complete.\n\nThis method polls the sandbox state until it's no longer resizing, encounters an error state, or the timeout is exceeded. 0 means no timeout.\n\nExample:\n\n```\nerr := sandbox.WaitForResize(ctx, 2*time.Minute)\n```\n\n<a name=\"Sandbox.WaitForStart\"></a>\n### func \\(\\*Sandbox\\) WaitForStart\n\n```go\nfunc (s *Sandbox) WaitForStart(ctx context.Context, timeout time.Duration) error\n```\n\nWaitForStart waits for the sandbox to reach the \"started\" state.\n\nThis method polls the sandbox state until it's started, encounters an error state, or the timeout is exceeded. 0 means no timeout.\n\nExample:\n\n```\nerr := sandbox.WaitForStart(ctx, 2*time.Minute)\nif err != nil {\n    return err\n}\n// Sandbox is now running\n```\n\n<a name=\"Sandbox.WaitForStop\"></a>\n### func \\(\\*Sandbox\\) WaitForStop\n\n```go\nfunc (s *Sandbox) WaitForStop(ctx context.Context, timeout time.Duration) error\n```\n\nWaitForStop waits for the sandbox to reach the \"stopped\" state.\n\nThis method polls the sandbox state until it's stopped or the timeout is exceeded. 0 means no timeout.\n\nExample:\n\n```\nerr := sandbox.WaitForStop(ctx, 2*time.Minute)\n```\n\n<a name=\"ScreenshotService\"></a>\n## type ScreenshotService\n\nScreenshotService provides screen capture operations.\n\nScreenshotService enables capturing full screen or region screenshots. Access through [ComputerUseService.Screenshot](<#ComputerUseService.Screenshot>).\n\n```go\ntype ScreenshotService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewScreenshotService\"></a>\n### func NewScreenshotService\n\n```go\nfunc NewScreenshotService(toolboxClient *toolbox.APIClient, otel *otelState) *ScreenshotService\n```\n\nNewScreenshotService creates a new ScreenshotService.\n\n<a name=\"ScreenshotService.TakeFullScreen\"></a>\n### func \\(\\*ScreenshotService\\) TakeFullScreen\n\n```go\nfunc (s *ScreenshotService) TakeFullScreen(ctx context.Context, showCursor *bool) (*types.ScreenshotResponse, error)\n```\n\nTakeFullScreen captures a screenshot of the entire screen.\n\nParameters:\n\n- showCursor: Whether to include the cursor in the screenshot, nil for default\n\nExample:\n\n```\n// Capture full screen\nscreenshot, err := ss.TakeFullScreen(ctx, nil)\nif err != nil {\n    return err\n}\n// screenshot.Image contains the base64-encoded image data\n\n// Capture with cursor visible\nshowCursor := true\nscreenshot, err := ss.TakeFullScreen(ctx, &showCursor)\n```\n\nReturns \\[types.ScreenshotResponse\\] with the captured image.\n\n<a name=\"ScreenshotService.TakeRegion\"></a>\n### func \\(\\*ScreenshotService\\) TakeRegion\n\n```go\nfunc (s *ScreenshotService) TakeRegion(ctx context.Context, region types.ScreenshotRegion, showCursor *bool) (*types.ScreenshotResponse, error)\n```\n\nTakeRegion captures a screenshot of a specific screen region.\n\nParameters:\n\n- region: The region to capture \\(X, Y, Width, Height\\)\n- showCursor: Whether to include the cursor in the screenshot, nil for default\n\nExample:\n\n```\n// Capture a 200x100 region starting at (50, 50)\nregion := types.ScreenshotRegion{X: 50, Y: 50, Width: 200, Height: 100}\nscreenshot, err := ss.TakeRegion(ctx, region, nil)\nif err != nil {\n    return err\n}\n```\n\nReturns \\[types.ScreenshotResponse\\] with the captured image.\n\n<a name=\"SnapshotService\"></a>\n## type SnapshotService\n\nSnapshotService provides snapshot \\(image template\\) management operations.\n\nSnapshotService enables creating, managing, and deleting snapshots that serve as templates for sandboxes. Snapshots can be built from Docker images or custom [DockerImage](<#DockerImage>) definitions with build contexts. Access through \\[Client.Snapshots\\].\n\nExample:\n\n```\n// Create a snapshot from an existing image\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:  \"my-python-env\",\n    Image: \"python:3.11-slim\",\n})\nif err != nil {\n    return err\n}\n\n// Stream build logs\nfor log := range logChan {\n    fmt.Println(log)\n}\n\n// Create a snapshot from a custom Image definition\nimage := daytona.Base(\"python:3.11-slim\").\n    PipInstall([]string{\"numpy\", \"pandas\"}).\n    Workdir(\"/app\")\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:  \"custom-python-env\",\n    Image: image,\n})\n```\n\n```go\ntype SnapshotService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewSnapshotService\"></a>\n### func NewSnapshotService\n\n```go\nfunc NewSnapshotService(client *Client) *SnapshotService\n```\n\nNewSnapshotService creates a new SnapshotService.\n\nThis is typically called internally by the SDK when creating a [Client](<#Client>). Users should access SnapshotService through \\[Client.Snapshots\\] rather than creating it directly.\n\n<a name=\"SnapshotService.Create\"></a>\n### func \\(\\*SnapshotService\\) Create\n\n```go\nfunc (s *SnapshotService) Create(ctx context.Context, params *types.CreateSnapshotParams) (*types.Snapshot, <-chan string, error)\n```\n\nCreate builds a new snapshot from an image and streams build logs.\n\nThe image parameter can be either a Docker image reference string \\(e.g., \"python:3.11\"\\) or an [DockerImage](<#DockerImage>) builder object for custom Dockerfile definitions.\n\nParameters:\n\n- params: Snapshot creation parameters including name, image, resources, and entrypoint\n\nExample:\n\n```\n// Create from Docker Hub image\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:  \"my-env\",\n    Image: \"python:3.11-slim\",\n})\nif err != nil {\n    return err\n}\n\n// Stream build logs\nfor log := range logChan {\n    fmt.Println(log)\n}\n\n// Create with custom image and resources\nimage := daytona.Base(\"python:3.11\").PipInstall([]string{\"numpy\"})\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:  \"custom-env\",\n    Image: image,\n    Resources: &types.Resources{CPU: 2, Memory: 4096},\n})\n```\n\nReturns the created \\[types.Snapshot\\], a channel for streaming build logs, or an error. The log channel is closed when the build completes or fails.\n\n<a name=\"SnapshotService.Delete\"></a>\n### func \\(\\*SnapshotService\\) Delete\n\n```go\nfunc (s *SnapshotService) Delete(ctx context.Context, snapshot *types.Snapshot) error\n```\n\nDelete permanently removes a snapshot.\n\nSandboxes created from this snapshot will continue to work, but no new sandboxes can be created from it after deletion.\n\nParameters:\n\n- snapshot: The snapshot to delete\n\nExample:\n\n```\nerr := client.Snapshots.Delete(ctx, snapshot)\nif err != nil {\n    return err\n}\n```\n\nReturns an error if deletion fails.\n\n<a name=\"SnapshotService.Get\"></a>\n### func \\(\\*SnapshotService\\) Get\n\n```go\nfunc (s *SnapshotService) Get(ctx context.Context, nameOrID string) (*types.Snapshot, error)\n```\n\nGet retrieves a snapshot by name or ID.\n\nParameters:\n\n- nameOrID: The snapshot name or unique ID\n\nExample:\n\n```\nsnapshot, err := client.Snapshots.Get(ctx, \"my-python-env\")\nif err != nil {\n    return err\n}\nfmt.Printf(\"Snapshot %s: %s\\n\", snapshot.Name, snapshot.State)\n```\n\nReturns the \\[types.Snapshot\\] or an error if not found.\n\n<a name=\"SnapshotService.List\"></a>\n### func \\(\\*SnapshotService\\) List\n\n```go\nfunc (s *SnapshotService) List(ctx context.Context, page *int, limit *int) (*types.PaginatedSnapshots, error)\n```\n\nList returns snapshots with optional pagination.\n\nParameters:\n\n- page: Page number \\(1\\-indexed\\), nil for first page\n- limit: Maximum snapshots per page, nil for default\n\nExample:\n\n```\n// List first page with default limit\nresult, err := client.Snapshots.List(ctx, nil, nil)\nif err != nil {\n    return err\n}\n\n// List with pagination\npage, limit := 2, 10\nresult, err := client.Snapshots.List(ctx, &page, &limit)\nfmt.Printf(\"Page %d of %d, total: %d\\n\", result.Page, result.TotalPages, result.Total)\n```\n\nReturns \\[types.PaginatedSnapshots\\] containing the snapshots and pagination info.\n\n<a name=\"VolumeService\"></a>\n## type VolumeService\n\nVolumeService provides persistent storage volume management operations.\n\nVolumeService enables creating, managing, and deleting persistent storage volumes that can be attached to sandboxes. Volumes persist data independently of sandbox lifecycle and can be shared between sandboxes. Access through \\[Client.Volumes\\].\n\nExample:\n\n```\n// Create a new volume\nvolume, err := client.Volumes.Create(ctx, \"my-data-volume\")\nif err != nil {\n    return err\n}\n\n// Wait for volume to be ready\nvolume, err = client.Volumes.WaitForReady(ctx, volume, 60*time.Second)\nif err != nil {\n    return err\n}\n\n// List all volumes\nvolumes, err := client.Volumes.List(ctx)\n```\n\n```go\ntype VolumeService struct {\n    // contains filtered or unexported fields\n}\n```\n\n<a name=\"NewVolumeService\"></a>\n### func NewVolumeService\n\n```go\nfunc NewVolumeService(client *Client) *VolumeService\n```\n\nNewVolumeService creates a new VolumeService.\n\nThis is typically called internally by the SDK when creating a [Client](<#Client>). Users should access VolumeService through \\[Client.Volumes\\] rather than creating it directly.\n\n<a name=\"VolumeService.Create\"></a>\n### func \\(\\*VolumeService\\) Create\n\n```go\nfunc (v *VolumeService) Create(ctx context.Context, name string) (*types.Volume, error)\n```\n\nCreate creates a new persistent storage volume.\n\nThe volume starts in \"pending\" state and transitions to \"ready\" when available. Use [VolumeService.WaitForReady](<#VolumeService.WaitForReady>) to wait for the volume to become ready.\n\nParameters:\n\n- name: Unique name for the volume\n\nExample:\n\n```\nvolume, err := client.Volumes.Create(ctx, \"my-data-volume\")\nif err != nil {\n    return err\n}\n\n// Wait for volume to be ready\nvolume, err = client.Volumes.WaitForReady(ctx, volume, 60*time.Second)\n```\n\nReturns the created \\[types.Volume\\] or an error.\n\n<a name=\"VolumeService.Delete\"></a>\n### func \\(\\*VolumeService\\) Delete\n\n```go\nfunc (v *VolumeService) Delete(ctx context.Context, volume *types.Volume) error\n```\n\nDelete permanently removes a volume and all its data.\n\nThis operation is irreversible. Ensure no sandboxes are using the volume before deletion.\n\nParameters:\n\n- volume: The volume to delete\n\nExample:\n\n```\nerr := client.Volumes.Delete(ctx, volume)\nif err != nil {\n    return err\n}\n```\n\nReturns an error if deletion fails.\n\n<a name=\"VolumeService.Get\"></a>\n### func \\(\\*VolumeService\\) Get\n\n```go\nfunc (v *VolumeService) Get(ctx context.Context, name string) (*types.Volume, error)\n```\n\nGet retrieves a volume by its name.\n\nParameters:\n\n- name: The volume name\n\nExample:\n\n```\nvolume, err := client.Volumes.Get(ctx, \"my-data-volume\")\nif err != nil {\n    return err\n}\nfmt.Printf(\"Volume state: %s\\n\", volume.State)\n```\n\nReturns the \\[types.Volume\\] or an error if not found.\n\n<a name=\"VolumeService.List\"></a>\n### func \\(\\*VolumeService\\) List\n\n```go\nfunc (v *VolumeService) List(ctx context.Context) ([]*types.Volume, error)\n```\n\nList returns all volumes in the organization.\n\nExample:\n\n```\nvolumes, err := client.Volumes.List(ctx)\nif err != nil {\n    return err\n}\nfor _, vol := range volumes {\n    fmt.Printf(\"Volume %s: %s\\n\", vol.Name, vol.State)\n}\n```\n\nReturns a slice of \\[types.Volume\\] or an error if the request fails.\n\n<a name=\"VolumeService.WaitForReady\"></a>\n### func \\(\\*VolumeService\\) WaitForReady\n\n```go\nfunc (v *VolumeService) WaitForReady(ctx context.Context, volume *types.Volume, timeout time.Duration) (*types.Volume, error)\n```\n\nWaitForReady waits for a volume to reach the \"ready\" state.\n\nThis method polls the volume status until it becomes ready, reaches an error state, or the timeout expires. The polling interval is 1 second.\n\nParameters:\n\n- volume: The volume to wait for\n- timeout: Maximum time to wait for the volume to become ready\n\nExample:\n\n```\nvolume, err := client.Volumes.Create(ctx, \"my-volume\")\nif err != nil {\n    return err\n}\n\n// Wait up to 2 minutes for the volume to be ready\nvolume, err = client.Volumes.WaitForReady(ctx, volume, 2*time.Minute)\nif err != nil {\n    return fmt.Errorf(\"volume failed to become ready: %w\", err)\n}\n```\n\nReturns the updated \\[types.Volume\\] when ready, or an error if the timeout expires or the volume enters an error state.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/go-sdk/errors.mdx",
    "content": "---\ntitle: \"errors\"\nhideTitleOnPage: true\n---\n\n{/* Code generated by gomarkdoc. DO NOT EDIT */}\n# errors\n\n```go\nimport \"github.com/daytonaio/daytona/libs/sdk-go/pkg/errors\"\n```\n\n## Index\n\n- [func ConvertAPIError\\(err error, httpResp \\*http.Response\\) error](<#ConvertAPIError>)\n- [func ConvertToolboxError\\(err error, httpResp \\*http.Response\\) error](<#ConvertToolboxError>)\n- [type DaytonaError](<#DaytonaError>)\n  - [func NewDaytonaError\\(message string, statusCode int, headers http.Header\\) \\*DaytonaError](<#NewDaytonaError>)\n  - [func \\(e \\*DaytonaError\\) Error\\(\\) string](<#DaytonaError.Error>)\n- [type DaytonaNotFoundError](<#DaytonaNotFoundError>)\n  - [func NewDaytonaNotFoundError\\(message string, headers http.Header\\) \\*DaytonaNotFoundError](<#NewDaytonaNotFoundError>)\n  - [func \\(e \\*DaytonaNotFoundError\\) Error\\(\\) string](<#DaytonaNotFoundError.Error>)\n- [type DaytonaRateLimitError](<#DaytonaRateLimitError>)\n  - [func NewDaytonaRateLimitError\\(message string, headers http.Header\\) \\*DaytonaRateLimitError](<#NewDaytonaRateLimitError>)\n  - [func \\(e \\*DaytonaRateLimitError\\) Error\\(\\) string](<#DaytonaRateLimitError.Error>)\n- [type DaytonaTimeoutError](<#DaytonaTimeoutError>)\n  - [func NewDaytonaTimeoutError\\(message string\\) \\*DaytonaTimeoutError](<#NewDaytonaTimeoutError>)\n  - [func \\(e \\*DaytonaTimeoutError\\) Error\\(\\) string](<#DaytonaTimeoutError.Error>)\n\n\n<a name=\"ConvertAPIError\"></a>\n## func ConvertAPIError\n\n```go\nfunc ConvertAPIError(err error, httpResp *http.Response) error\n```\n\nConvertAPIError converts api\\-client\\-go errors to SDK error types\n\n<a name=\"ConvertToolboxError\"></a>\n## func ConvertToolboxError\n\n```go\nfunc ConvertToolboxError(err error, httpResp *http.Response) error\n```\n\nConvertToolboxError converts toolbox\\-api\\-client\\-go errors to SDK error types\n\n<a name=\"DaytonaError\"></a>\n## type DaytonaError\n\nDaytonaError is the base error type for all Daytona SDK errors\n\n```go\ntype DaytonaError struct {\n    Message    string\n    StatusCode int\n    Headers    http.Header\n}\n```\n\n<a name=\"NewDaytonaError\"></a>\n### func NewDaytonaError\n\n```go\nfunc NewDaytonaError(message string, statusCode int, headers http.Header) *DaytonaError\n```\n\nNewDaytonaError creates a new DaytonaError\n\n<a name=\"DaytonaError.Error\"></a>\n### func \\(\\*DaytonaError\\) Error\n\n```go\nfunc (e *DaytonaError) Error() string\n```\n\n\n\n<a name=\"DaytonaNotFoundError\"></a>\n## type DaytonaNotFoundError\n\nDaytonaNotFoundError represents a resource not found error \\(404\\)\n\n```go\ntype DaytonaNotFoundError struct {\n    *DaytonaError\n}\n```\n\n<a name=\"NewDaytonaNotFoundError\"></a>\n### func NewDaytonaNotFoundError\n\n```go\nfunc NewDaytonaNotFoundError(message string, headers http.Header) *DaytonaNotFoundError\n```\n\nNewDaytonaNotFoundError creates a new DaytonaNotFoundError\n\n<a name=\"DaytonaNotFoundError.Error\"></a>\n### func \\(\\*DaytonaNotFoundError\\) Error\n\n```go\nfunc (e *DaytonaNotFoundError) Error() string\n```\n\n\n\n<a name=\"DaytonaRateLimitError\"></a>\n## type DaytonaRateLimitError\n\nDaytonaRateLimitError represents a rate limit error \\(429\\)\n\n```go\ntype DaytonaRateLimitError struct {\n    *DaytonaError\n}\n```\n\n<a name=\"NewDaytonaRateLimitError\"></a>\n### func NewDaytonaRateLimitError\n\n```go\nfunc NewDaytonaRateLimitError(message string, headers http.Header) *DaytonaRateLimitError\n```\n\nNewDaytonaRateLimitError creates a new DaytonaRateLimitError\n\n<a name=\"DaytonaRateLimitError.Error\"></a>\n### func \\(\\*DaytonaRateLimitError\\) Error\n\n```go\nfunc (e *DaytonaRateLimitError) Error() string\n```\n\n\n\n<a name=\"DaytonaTimeoutError\"></a>\n## type DaytonaTimeoutError\n\nDaytonaTimeoutError represents a timeout error\n\n```go\ntype DaytonaTimeoutError struct {\n    *DaytonaError\n}\n```\n\n<a name=\"NewDaytonaTimeoutError\"></a>\n### func NewDaytonaTimeoutError\n\n```go\nfunc NewDaytonaTimeoutError(message string) *DaytonaTimeoutError\n```\n\nNewDaytonaTimeoutError creates a new DaytonaTimeoutError\n\n<a name=\"DaytonaTimeoutError.Error\"></a>\n### func \\(\\*DaytonaTimeoutError\\) Error\n\n```go\nfunc (e *DaytonaTimeoutError) Error() string\n```\n\n\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/go-sdk/index.mdx",
    "content": "---\ntitle: Go SDK Reference\ndescription: Interact with Daytona Sandboxes using the Go SDK\nnext: /docs/go-sdk/daytona\n---\n\nThe Daytona Go SDK provides a powerful interface for programmatically interacting with Daytona Sandboxes.\n\n## Installation\n\nInstall the Daytona Go SDK using go get:\n\n```bash\ngo get github.com/daytonaio/daytona/libs/sdk-go\n```\n\n## Getting Started\n\n### Create a Sandbox\n\nCreate a Daytona Sandbox to run your code securely in an isolated environment. The following snippet is an example \"Hello World\" program that runs securely inside a Daytona Sandbox.\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n\t// Initialize the SDK (uses environment variables by default)\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Create a new sandbox\n\tsandbox, err := client.Create(context.Background(), nil)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// Execute a command\n\tresponse, err := sandbox.Process.ExecuteCommand(context.Background(), \"echo 'Hello, World!'\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(response.Result)\n}\n```\n\n## Configuration\n\nThe Daytona SDK can be configured using environment variables or by passing options to the constructor:\n\n```go\npackage main\n\nimport (\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Using environment variables (DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET)\n\tclient, _ := daytona.NewClient()\n\n\t// Using explicit configuration\n\tconfig := &types.DaytonaConfig{\n\t\tAPIKey: \"YOUR_API_KEY\",\n\t\tAPIUrl: \"https://app.daytona.io/api\",\n\t\tTarget: \"us\",\n\t}\n\tclient, _ = daytona.NewClientWithConfig(config)\n}\n```\n\nFor more information on configuring the Daytona SDK, see [configuration](/docs/en/configuration).\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/go-sdk/options.mdx",
    "content": "---\ntitle: \"options\"\nhideTitleOnPage: true\n---\n\n{/* Code generated by gomarkdoc. DO NOT EDIT */}\n# options\n\n```go\nimport \"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n```\n\nPackage options provides functional option types for configuring SDK operations.\n\nThis package uses the functional options pattern to provide a clean, extensible API for configuring optional parameters. Each option function returns a closure that modifies the corresponding options struct.\n\n### Usage\n\nOptions are passed as variadic arguments to SDK methods:\n\n```\nerr := sandbox.Git.Clone(ctx, url, path,\n    options.WithBranch(\"develop\"),\n    options.WithUsername(\"user\"),\n    options.WithPassword(\"token\"),\n)\n```\n\n### Generic Apply Function\n\nThe [Apply](<#Apply>) function creates a new options struct and applies all provided option functions to it:\n\n```\nopts := options.Apply(\n    options.WithBranch(\"main\"),\n    options.WithUsername(\"user\"),\n)\n// opts.Branch == \"main\", opts.Username == \"user\"\n```\n\n## Index\n\n- [func Apply\\[T any\\]\\(opts ...func\\(\\*T\\)\\) \\*T](<#Apply>)\n- [func WithAllowEmpty\\(allowEmpty bool\\) func\\(\\*GitCommit\\)](<#WithAllowEmpty>)\n- [func WithBranch\\(branch string\\) func\\(\\*GitClone\\)](<#WithBranch>)\n- [func WithCodeRunParams\\(params types.CodeRunParams\\) func\\(\\*CodeRun\\)](<#WithCodeRunParams>)\n- [func WithCodeRunTimeout\\(timeout time.Duration\\) func\\(\\*CodeRun\\)](<#WithCodeRunTimeout>)\n- [func WithCommandEnv\\(env map\\[string\\]string\\) func\\(\\*ExecuteCommand\\)](<#WithCommandEnv>)\n- [func WithCommitId\\(commitID string\\) func\\(\\*GitClone\\)](<#WithCommitId>)\n- [func WithCreatePtyEnv\\(env map\\[string\\]string\\) func\\(\\*CreatePty\\)](<#WithCreatePtyEnv>)\n- [func WithCreatePtySize\\(ptySize types.PtySize\\) func\\(\\*CreatePty\\)](<#WithCreatePtySize>)\n- [func WithCustomContext\\(contextID string\\) func\\(\\*RunCode\\)](<#WithCustomContext>)\n- [func WithCwd\\(cwd string\\) func\\(\\*ExecuteCommand\\)](<#WithCwd>)\n- [func WithEnv\\(env map\\[string\\]string\\) func\\(\\*RunCode\\)](<#WithEnv>)\n- [func WithExecuteTimeout\\(timeout time.Duration\\) func\\(\\*ExecuteCommand\\)](<#WithExecuteTimeout>)\n- [func WithExtraIndexURLs\\(urls ...string\\) func\\(\\*PipInstall\\)](<#WithExtraIndexURLs>)\n- [func WithExtraOptions\\(options string\\) func\\(\\*PipInstall\\)](<#WithExtraOptions>)\n- [func WithFindLinks\\(links ...string\\) func\\(\\*PipInstall\\)](<#WithFindLinks>)\n- [func WithForce\\(force bool\\) func\\(\\*GitDeleteBranch\\)](<#WithForce>)\n- [func WithGroup\\(group string\\) func\\(\\*SetFilePermissions\\)](<#WithGroup>)\n- [func WithIndexURL\\(url string\\) func\\(\\*PipInstall\\)](<#WithIndexURL>)\n- [func WithInterpreterTimeout\\(timeout time.Duration\\) func\\(\\*RunCode\\)](<#WithInterpreterTimeout>)\n- [func WithLogChannel\\(logChannel chan string\\) func\\(\\*CreateSandbox\\)](<#WithLogChannel>)\n- [func WithMode\\(mode string\\) func\\(\\*CreateFolder\\)](<#WithMode>)\n- [func WithOwner\\(owner string\\) func\\(\\*SetFilePermissions\\)](<#WithOwner>)\n- [func WithPassword\\(password string\\) func\\(\\*GitClone\\)](<#WithPassword>)\n- [func WithPermissionMode\\(mode string\\) func\\(\\*SetFilePermissions\\)](<#WithPermissionMode>)\n- [func WithPre\\(\\) func\\(\\*PipInstall\\)](<#WithPre>)\n- [func WithPtyEnv\\(env map\\[string\\]string\\) func\\(\\*PtySession\\)](<#WithPtyEnv>)\n- [func WithPtySize\\(size types.PtySize\\) func\\(\\*PtySession\\)](<#WithPtySize>)\n- [func WithPullPassword\\(password string\\) func\\(\\*GitPull\\)](<#WithPullPassword>)\n- [func WithPullUsername\\(username string\\) func\\(\\*GitPull\\)](<#WithPullUsername>)\n- [func WithPushPassword\\(password string\\) func\\(\\*GitPush\\)](<#WithPushPassword>)\n- [func WithPushUsername\\(username string\\) func\\(\\*GitPush\\)](<#WithPushUsername>)\n- [func WithTimeout\\(timeout time.Duration\\) func\\(\\*CreateSandbox\\)](<#WithTimeout>)\n- [func WithUsername\\(username string\\) func\\(\\*GitClone\\)](<#WithUsername>)\n- [func WithWaitForStart\\(waitForStart bool\\) func\\(\\*CreateSandbox\\)](<#WithWaitForStart>)\n- [type CodeRun](<#CodeRun>)\n- [type CreateFolder](<#CreateFolder>)\n- [type CreatePty](<#CreatePty>)\n- [type CreateSandbox](<#CreateSandbox>)\n- [type ExecuteCommand](<#ExecuteCommand>)\n- [type GitClone](<#GitClone>)\n- [type GitCommit](<#GitCommit>)\n- [type GitDeleteBranch](<#GitDeleteBranch>)\n- [type GitPull](<#GitPull>)\n- [type GitPush](<#GitPush>)\n- [type PipInstall](<#PipInstall>)\n- [type PtySession](<#PtySession>)\n- [type RunCode](<#RunCode>)\n- [type SetFilePermissions](<#SetFilePermissions>)\n\n\n<a name=\"Apply\"></a>\n## func Apply\n\n```go\nfunc Apply[T any](opts ...func(*T)) *T\n```\n\nApply creates a new instance of type T and applies all provided option functions.\n\nThis generic function enables a consistent pattern for applying functional options across different option types. It allocates a zero\\-value instance of T, then applies each option function in order.\n\nExample:\n\n```\nopts := options.Apply(\n    options.WithBranch(\"main\"),\n    options.WithUsername(\"user\"),\n)\n```\n\n<a name=\"WithAllowEmpty\"></a>\n## func WithAllowEmpty\n\n```go\nfunc WithAllowEmpty(allowEmpty bool) func(*GitCommit)\n```\n\nWithAllowEmpty allows creating a commit even when there are no staged changes.\n\nThis is useful for triggering CI/CD pipelines or marking points in history without actual code changes.\n\nExample:\n\n```\nresp, err := sandbox.Git.Commit(ctx, path, \"Trigger rebuild\", author, email,\n    options.WithAllowEmpty(true),\n)\n```\n\n<a name=\"WithBranch\"></a>\n## func WithBranch\n\n```go\nfunc WithBranch(branch string) func(*GitClone)\n```\n\nWithBranch sets the branch to clone instead of the repository's default branch.\n\nExample:\n\n```\nerr := sandbox.Git.Clone(ctx, url, path, options.WithBranch(\"develop\"))\n```\n\n<a name=\"WithCodeRunParams\"></a>\n## func WithCodeRunParams\n\n```go\nfunc WithCodeRunParams(params types.CodeRunParams) func(*CodeRun)\n```\n\nWithCodeRunParams sets the code execution parameters.\n\nExample:\n\n```\nresult, err := sandbox.Process.CodeRun(ctx, code,\n    options.WithCodeRunParams(types.CodeRunParams{Language: \"python\"}),\n)\n```\n\n<a name=\"WithCodeRunTimeout\"></a>\n## func WithCodeRunTimeout\n\n```go\nfunc WithCodeRunTimeout(timeout time.Duration) func(*CodeRun)\n```\n\nWithCodeRunTimeout sets the timeout for code execution.\n\nExample:\n\n```\nresult, err := sandbox.Process.CodeRun(ctx, code,\n    options.WithCodeRunTimeout(30*time.Second),\n)\n```\n\n<a name=\"WithCommandEnv\"></a>\n## func WithCommandEnv\n\n```go\nfunc WithCommandEnv(env map[string]string) func(*ExecuteCommand)\n```\n\nWithCommandEnv sets environment variables for the command.\n\nThese variables are added to the command's environment in addition to the sandbox's default environment.\n\nExample:\n\n```\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"echo $MY_VAR\",\n    options.WithCommandEnv(map[string]string{\"MY_VAR\": \"hello\"}),\n)\n```\n\n<a name=\"WithCommitId\"></a>\n## func WithCommitId\n\n```go\nfunc WithCommitId(commitID string) func(*GitClone)\n```\n\nWithCommitId sets a specific commit SHA to checkout after cloning.\n\nThe repository is first cloned, then the specified commit is checked out, resulting in a detached HEAD state.\n\nExample:\n\n```\nerr := sandbox.Git.Clone(ctx, url, path, options.WithCommitId(\"abc123def\"))\n```\n\n<a name=\"WithCreatePtyEnv\"></a>\n## func WithCreatePtyEnv\n\n```go\nfunc WithCreatePtyEnv(env map[string]string) func(*CreatePty)\n```\n\nWithCreatePtyEnv sets environment variables for CreatePty.\n\nExample:\n\n```\nhandle, err := sandbox.Process.CreatePty(ctx, \"my-pty\",\n    options.WithCreatePtyEnv(map[string]string{\"TERM\": \"xterm-256color\"}),\n)\n```\n\n<a name=\"WithCreatePtySize\"></a>\n## func WithCreatePtySize\n\n```go\nfunc WithCreatePtySize(ptySize types.PtySize) func(*CreatePty)\n```\n\nWithCreatePtySize sets the PTY terminal dimensions for CreatePty.\n\nExample:\n\n```\nhandle, err := sandbox.Process.CreatePty(ctx, \"my-pty\",\n    options.WithCreatePtySize(types.PtySize{Rows: 24, Cols: 80}),\n)\n```\n\n<a name=\"WithCustomContext\"></a>\n## func WithCustomContext\n\n```go\nfunc WithCustomContext(contextID string) func(*RunCode)\n```\n\nWithCustomContext sets the interpreter context ID for code execution.\n\nUsing a context allows you to maintain state \\(variables, imports, etc.\\) across multiple code executions. Create a context with CreateContext first.\n\nExample:\n\n```\nctx, _ := sandbox.CodeInterpreter.CreateContext(ctx, nil)\nchannels, err := sandbox.CodeInterpreter.RunCode(ctx, \"x = 42\",\n    options.WithCustomContext(ctx[\"id\"].(string)),\n)\n```\n\n<a name=\"WithCwd\"></a>\n## func WithCwd\n\n```go\nfunc WithCwd(cwd string) func(*ExecuteCommand)\n```\n\nWithCwd sets the working directory for command execution.\n\nExample:\n\n```\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"ls -la\",\n    options.WithCwd(\"/home/user/project\"),\n)\n```\n\n<a name=\"WithEnv\"></a>\n## func WithEnv\n\n```go\nfunc WithEnv(env map[string]string) func(*RunCode)\n```\n\nWithEnv sets environment variables for code execution.\n\nThese variables are available to the code during execution.\n\nExample:\n\n```\nchannels, err := sandbox.CodeInterpreter.RunCode(ctx, \"import os; print(os.environ['API_KEY'])\",\n    options.WithEnv(map[string]string{\"API_KEY\": \"secret\"}),\n)\n```\n\n<a name=\"WithExecuteTimeout\"></a>\n## func WithExecuteTimeout\n\n```go\nfunc WithExecuteTimeout(timeout time.Duration) func(*ExecuteCommand)\n```\n\nWithExecuteTimeout sets the timeout for command execution.\n\nIf the command doesn't complete within the timeout, it will be terminated.\n\nExample:\n\n```\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"sleep 60\",\n    options.WithExecuteTimeout(5*time.Second),\n)\n```\n\n<a name=\"WithExtraIndexURLs\"></a>\n## func WithExtraIndexURLs\n\n```go\nfunc WithExtraIndexURLs(urls ...string) func(*PipInstall)\n```\n\nWithExtraIndexURLs adds extra index URLs for pip install.\n\nExtra indexes are checked in addition to the main index URL. Useful for installing packages from both PyPI and a private index.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").PipInstall(\n    []string{\"mypackage\"},\n    options.WithExtraIndexURLs(\"https://private.example.com/simple/\"),\n)\n```\n\n<a name=\"WithExtraOptions\"></a>\n## func WithExtraOptions\n\n```go\nfunc WithExtraOptions(options string) func(*PipInstall)\n```\n\nWithExtraOptions adds extra command\\-line options for pip install.\n\nUse this for pip options not covered by other With\\* functions.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").PipInstall(\n    []string{\"mypackage\"},\n    options.WithExtraOptions(\"--no-cache-dir --upgrade\"),\n)\n```\n\n<a name=\"WithFindLinks\"></a>\n## func WithFindLinks\n\n```go\nfunc WithFindLinks(links ...string) func(*PipInstall)\n```\n\nWithFindLinks adds find\\-links URLs for pip install.\n\nFind\\-links URLs are searched for packages before the package index. Useful for installing packages from local directories or custom URLs.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").PipInstall(\n    []string{\"mypackage\"},\n    options.WithFindLinks(\"/path/to/wheels\", \"https://example.com/wheels/\"),\n)\n```\n\n<a name=\"WithForce\"></a>\n## func WithForce\n\n```go\nfunc WithForce(force bool) func(*GitDeleteBranch)\n```\n\nWithForce enables force deletion of a branch even if it's not fully merged.\n\nUse with caution as this can result in lost commits if the branch contains work that hasn't been merged elsewhere.\n\nExample:\n\n```\nerr := sandbox.Git.DeleteBranch(ctx, path, \"feature/abandoned\",\n    options.WithForce(true),\n)\n```\n\n<a name=\"WithGroup\"></a>\n## func WithGroup\n\n```go\nfunc WithGroup(group string) func(*SetFilePermissions)\n```\n\nWithGroup sets the file group.\n\nThe group should be a valid group name on the sandbox system.\n\nExample:\n\n```\nerr := sandbox.FileSystem.SetFilePermissions(ctx, \"/home/user/file.txt\",\n    options.WithGroup(\"users\"),\n)\n```\n\n<a name=\"WithIndexURL\"></a>\n## func WithIndexURL\n\n```go\nfunc WithIndexURL(url string) func(*PipInstall)\n```\n\nWithIndexURL sets the base URL of the Python Package Index.\n\nReplaces the default PyPI \\(https://pypi.org/simple\\) with a custom index.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").PipInstall(\n    []string{\"mypackage\"},\n    options.WithIndexURL(\"https://my-pypi.example.com/simple/\"),\n)\n```\n\n<a name=\"WithInterpreterTimeout\"></a>\n## func WithInterpreterTimeout\n\n```go\nfunc WithInterpreterTimeout(timeout time.Duration) func(*RunCode)\n```\n\nWithInterpreterTimeout sets the execution timeout for code.\n\nIf the code doesn't complete within the timeout, execution is terminated.\n\nExample:\n\n```\nchannels, err := sandbox.CodeInterpreter.RunCode(ctx, \"import time; time.sleep(60)\",\n    options.WithInterpreterTimeout(5*time.Second),\n)\n```\n\n<a name=\"WithLogChannel\"></a>\n## func WithLogChannel\n\n```go\nfunc WithLogChannel(logChannel chan string) func(*CreateSandbox)\n```\n\nWithLogChannel provides a channel for receiving build logs during sandbox creation.\n\nWhen creating a sandbox from a custom image that requires building, build logs are streamed to the provided channel. The channel is closed when streaming completes. If no build is required, no logs are sent and the channel remains unused.\n\nExample:\n\n```\nlogChan := make(chan string)\ngo func() {\n    for log := range logChan {\n        fmt.Println(log)\n    }\n}()\nsandbox, err := client.Create(ctx, params,\n    options.WithLogChannel(logChan),\n)\n```\n\n<a name=\"WithMode\"></a>\n## func WithMode\n\n```go\nfunc WithMode(mode string) func(*CreateFolder)\n```\n\nWithMode sets the Unix file permissions for the created folder.\n\nThe mode should be specified as an octal string \\(e.g., \"0755\", \"0700\"\\). If not specified, defaults to \"0755\".\n\nExample:\n\n```\nerr := sandbox.FileSystem.CreateFolder(ctx, \"/home/user/mydir\",\n    options.WithMode(\"0700\"),\n)\n```\n\n<a name=\"WithOwner\"></a>\n## func WithOwner\n\n```go\nfunc WithOwner(owner string) func(*SetFilePermissions)\n```\n\nWithOwner sets the file owner.\n\nThe owner should be a valid username on the sandbox system.\n\nExample:\n\n```\nerr := sandbox.FileSystem.SetFilePermissions(ctx, \"/home/user/file.txt\",\n    options.WithOwner(\"root\"),\n)\n```\n\n<a name=\"WithPassword\"></a>\n## func WithPassword\n\n```go\nfunc WithPassword(password string) func(*GitClone)\n```\n\nWithPassword sets the password or access token for HTTPS authentication when cloning.\n\nFor GitHub, use a Personal Access Token \\(PAT\\). For GitLab, use a Project Access Token or Personal Access Token. For Bitbucket, use an App Password.\n\nExample:\n\n```\nerr := sandbox.Git.Clone(ctx, url, path,\n    options.WithUsername(\"username\"),\n    options.WithPassword(\"ghp_xxxxxxxxxxxx\"),\n)\n```\n\n<a name=\"WithPermissionMode\"></a>\n## func WithPermissionMode\n\n```go\nfunc WithPermissionMode(mode string) func(*SetFilePermissions)\n```\n\nWithPermissionMode sets the Unix file permissions.\n\nThe mode should be specified as an octal string \\(e.g., \"0644\", \"0755\"\\).\n\nExample:\n\n```\nerr := sandbox.FileSystem.SetFilePermissions(ctx, \"/home/user/file.txt\",\n    options.WithPermissionMode(\"0644\"),\n)\n```\n\n<a name=\"WithPre\"></a>\n## func WithPre\n\n```go\nfunc WithPre() func(*PipInstall)\n```\n\nWithPre enables installation of pre\\-release and development versions.\n\nExample:\n\n```\nimage := daytona.Base(\"python:3.11\").PipInstall(\n    []string{\"mypackage\"},\n    options.WithPre(),\n)\n```\n\n<a name=\"WithPtyEnv\"></a>\n## func WithPtyEnv\n\n```go\nfunc WithPtyEnv(env map[string]string) func(*PtySession)\n```\n\nWithPtyEnv sets environment variables for the PTY session.\n\nExample:\n\n```\nsession, err := sandbox.Process.CreatePtySession(ctx, \"my-session\",\n    options.WithPtyEnv(map[string]string{\"TERM\": \"xterm-256color\"}),\n)\n```\n\n<a name=\"WithPtySize\"></a>\n## func WithPtySize\n\n```go\nfunc WithPtySize(size types.PtySize) func(*PtySession)\n```\n\nWithPtySize sets the PTY terminal dimensions.\n\nExample:\n\n```\nsession, err := sandbox.Process.CreatePtySession(ctx, \"my-session\",\n    options.WithPtySize(types.PtySize{Rows: 24, Cols: 80}),\n)\n```\n\n<a name=\"WithPullPassword\"></a>\n## func WithPullPassword\n\n```go\nfunc WithPullPassword(password string) func(*GitPull)\n```\n\nWithPullPassword sets the password or access token for HTTPS authentication when pulling.\n\nExample:\n\n```\nerr := sandbox.Git.Pull(ctx, path,\n    options.WithPullUsername(\"username\"),\n    options.WithPullPassword(\"ghp_xxxxxxxxxxxx\"),\n)\n```\n\n<a name=\"WithPullUsername\"></a>\n## func WithPullUsername\n\n```go\nfunc WithPullUsername(username string) func(*GitPull)\n```\n\nWithPullUsername sets the username for HTTPS authentication when pulling.\n\nExample:\n\n```\nerr := sandbox.Git.Pull(ctx, path,\n    options.WithPullUsername(\"username\"),\n    options.WithPullPassword(\"github_token\"),\n)\n```\n\n<a name=\"WithPushPassword\"></a>\n## func WithPushPassword\n\n```go\nfunc WithPushPassword(password string) func(*GitPush)\n```\n\nWithPushPassword sets the password or access token for HTTPS authentication when pushing.\n\nExample:\n\n```\nerr := sandbox.Git.Push(ctx, path,\n    options.WithPushUsername(\"username\"),\n    options.WithPushPassword(\"ghp_xxxxxxxxxxxx\"),\n)\n```\n\n<a name=\"WithPushUsername\"></a>\n## func WithPushUsername\n\n```go\nfunc WithPushUsername(username string) func(*GitPush)\n```\n\nWithPushUsername sets the username for HTTPS authentication when pushing.\n\nExample:\n\n```\nerr := sandbox.Git.Push(ctx, path,\n    options.WithPushUsername(\"username\"),\n    options.WithPushPassword(\"github_token\"),\n)\n```\n\n<a name=\"WithTimeout\"></a>\n## func WithTimeout\n\n```go\nfunc WithTimeout(timeout time.Duration) func(*CreateSandbox)\n```\n\nWithTimeout sets the maximum duration to wait for sandbox creation to complete.\n\nIf the timeout is exceeded before the sandbox is ready, Create returns an error. The default timeout is 60 seconds.\n\nExample:\n\n```\nsandbox, err := client.Create(ctx, params,\n    options.WithTimeout(5*time.Minute),\n)\n```\n\n<a name=\"WithUsername\"></a>\n## func WithUsername\n\n```go\nfunc WithUsername(username string) func(*GitClone)\n```\n\nWithUsername sets the username for HTTPS authentication when cloning.\n\nFor GitHub, GitLab, and similar services, the username is typically your account username or a placeholder like \"git\" when using tokens.\n\nExample:\n\n```\nerr := sandbox.Git.Clone(ctx, url, path,\n    options.WithUsername(\"username\"),\n    options.WithPassword(\"github_token\"),\n)\n```\n\n<a name=\"WithWaitForStart\"></a>\n## func WithWaitForStart\n\n```go\nfunc WithWaitForStart(waitForStart bool) func(*CreateSandbox)\n```\n\nWithWaitForStart controls whether \\[daytona.Client.Create\\] waits for the sandbox to reach the started state before returning.\n\nWhen true \\(the default\\), Create blocks until the sandbox is fully started and ready for use. When false, Create returns immediately after the sandbox is created, which may be in a pending or building state.\n\nExample:\n\n```\n// Return immediately without waiting for the sandbox to start\nsandbox, err := client.Create(ctx, params,\n    options.WithWaitForStart(false),\n)\n```\n\n<a name=\"CodeRun\"></a>\n## type CodeRun\n\nCodeRun holds optional parameters for \\[daytona.ProcessService.CodeRun\\].\n\n```go\ntype CodeRun struct {\n    Params  *types.CodeRunParams // Code execution parameters\n    Timeout *time.Duration       // Execution timeout\n}\n```\n\n<a name=\"CreateFolder\"></a>\n## type CreateFolder\n\nCreateFolder holds optional parameters for \\[daytona.FileSystemService.CreateFolder\\].\n\n```go\ntype CreateFolder struct {\n    Mode *string // Unix file permissions (e.g., \"0755\")\n}\n```\n\n<a name=\"CreatePty\"></a>\n## type CreatePty\n\nCreatePty holds optional parameters for \\[daytona.ProcessService.CreatePty\\].\n\n```go\ntype CreatePty struct {\n    PtySize *types.PtySize    // Terminal dimensions (rows and columns)\n    Env     map[string]string // Environment variables for the PTY session\n}\n```\n\n<a name=\"CreateSandbox\"></a>\n## type CreateSandbox\n\nCreateSandbox holds optional parameters for \\[daytona.Client.Create\\].\n\n```go\ntype CreateSandbox struct {\n    Timeout      *time.Duration // Maximum time to wait for sandbox creation\n    WaitForStart bool           // Whether to wait for the sandbox to reach started state\n    LogChannel   chan string    // Channel for receiving build logs during image builds\n}\n```\n\n<a name=\"ExecuteCommand\"></a>\n## type ExecuteCommand\n\nExecuteCommand holds optional parameters for \\[daytona.ProcessService.ExecuteCommand\\].\n\n```go\ntype ExecuteCommand struct {\n    Cwd     *string           // Working directory for command execution\n    Env     map[string]string // Environment variables\n    Timeout *time.Duration    // Command execution timeout\n}\n```\n\n<a name=\"GitClone\"></a>\n## type GitClone\n\nGitClone holds optional parameters for \\[daytona.GitService.Clone\\].\n\nFields are pointers to distinguish between unset values and zero values. Use the corresponding With\\* functions to set these options.\n\n```go\ntype GitClone struct {\n    Branch   *string // Branch to clone (defaults to repository's default branch)\n    CommitId *string // Specific commit SHA to checkout after cloning\n    Username *string // Username for HTTPS authentication\n    Password *string // Password or token for HTTPS authentication\n}\n```\n\n<a name=\"GitCommit\"></a>\n## type GitCommit\n\nGitCommit holds optional parameters for \\[daytona.GitService.Commit\\].\n\n```go\ntype GitCommit struct {\n    AllowEmpty *bool // Allow creating commits with no staged changes\n}\n```\n\n<a name=\"GitDeleteBranch\"></a>\n## type GitDeleteBranch\n\nGitDeleteBranch holds optional parameters for \\[daytona.GitService.DeleteBranch\\].\n\n```go\ntype GitDeleteBranch struct {\n    Force *bool // Force delete even if branch is not fully merged\n}\n```\n\n<a name=\"GitPull\"></a>\n## type GitPull\n\nGitPull holds optional parameters for \\[daytona.GitService.Pull\\].\n\n```go\ntype GitPull struct {\n    Username *string // Username for HTTPS authentication\n    Password *string // Password or token for HTTPS authentication\n}\n```\n\n<a name=\"GitPush\"></a>\n## type GitPush\n\nGitPush holds optional parameters for \\[daytona.GitService.Push\\].\n\n```go\ntype GitPush struct {\n    Username *string // Username for HTTPS authentication\n    Password *string // Password or token for HTTPS authentication\n}\n```\n\n<a name=\"PipInstall\"></a>\n## type PipInstall\n\nPipInstall holds optional parameters for \\[daytona.Image.PipInstall\\].\n\n```go\ntype PipInstall struct {\n    FindLinks      []string // URLs to search for packages\n    IndexURL       string   // Base URL of the Python Package Index\n    ExtraIndexURLs []string // Extra index URLs for package lookup\n    Pre            bool     // Allow pre-release and development versions\n    ExtraOptions   string   // Additional pip command-line options\n}\n```\n\n<a name=\"PtySession\"></a>\n## type PtySession\n\nPtySession holds optional parameters for \\[daytona.ProcessService.CreatePtySession\\].\n\n```go\ntype PtySession struct {\n    PtySize *types.PtySize    // Terminal dimensions (rows and columns)\n    Env     map[string]string // Environment variables for the PTY session\n}\n```\n\n<a name=\"RunCode\"></a>\n## type RunCode\n\nRunCode holds optional parameters for \\[daytona.CodeInterpreterService.RunCode\\].\n\n```go\ntype RunCode struct {\n    ContextID string            // Interpreter context ID for persistent state\n    Env       map[string]string // Environment variables for code execution\n    Timeout   *time.Duration    // Execution timeout\n}\n```\n\n<a name=\"SetFilePermissions\"></a>\n## type SetFilePermissions\n\nSetFilePermissions holds optional parameters for \\[daytona.FileSystemService.SetFilePermissions\\].\n\n```go\ntype SetFilePermissions struct {\n    Mode  *string // Unix file permissions (e.g., \"0644\")\n    Owner *string // File owner username\n    Group *string // File group name\n}\n```\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/go-sdk/types.mdx",
    "content": "---\ntitle: \"types\"\nhideTitleOnPage: true\n---\n\n{/* Code generated by gomarkdoc. DO NOT EDIT */}\n# types\n\n```go\nimport \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n```\n\n## Index\n\n- [type Chart](<#Chart>)\n- [type ChartType](<#ChartType>)\n- [type CodeLanguage](<#CodeLanguage>)\n- [type CodeRunParams](<#CodeRunParams>)\n- [type CreateSnapshotParams](<#CreateSnapshotParams>)\n- [type DaytonaConfig](<#DaytonaConfig>)\n- [type ExecuteResponse](<#ExecuteResponse>)\n- [type ExecutionArtifacts](<#ExecutionArtifacts>)\n- [type ExecutionError](<#ExecutionError>)\n- [type ExecutionResult](<#ExecutionResult>)\n- [type ExperimentalConfig](<#ExperimentalConfig>)\n- [type FileDownloadRequest](<#FileDownloadRequest>)\n- [type FileDownloadResponse](<#FileDownloadResponse>)\n- [type FileInfo](<#FileInfo>)\n- [type FileStatus](<#FileStatus>)\n- [type FileUpload](<#FileUpload>)\n- [type GitCommitResponse](<#GitCommitResponse>)\n- [type GitStatus](<#GitStatus>)\n- [type ImageParams](<#ImageParams>)\n- [type LspLanguageID](<#LspLanguageID>)\n- [type OutputMessage](<#OutputMessage>)\n- [type PaginatedSnapshots](<#PaginatedSnapshots>)\n- [type Position](<#Position>)\n- [type PreviewLink](<#PreviewLink>)\n- [type PtyResult](<#PtyResult>)\n- [type PtySessionInfo](<#PtySessionInfo>)\n- [type PtySize](<#PtySize>)\n- [type Resources](<#Resources>)\n- [type SandboxBaseParams](<#SandboxBaseParams>)\n- [type ScreenshotOptions](<#ScreenshotOptions>)\n- [type ScreenshotRegion](<#ScreenshotRegion>)\n- [type ScreenshotResponse](<#ScreenshotResponse>)\n- [type Snapshot](<#Snapshot>)\n- [type SnapshotParams](<#SnapshotParams>)\n- [type Volume](<#Volume>)\n- [type VolumeMount](<#VolumeMount>)\n\n\n<a name=\"Chart\"></a>\n## type Chart\n\nChart represents a chart\n\n```go\ntype Chart struct {\n    Type     ChartType\n    Title    string\n    Elements any\n    PNG      *string // Optional base64-encoded PNG representation\n}\n```\n\n<a name=\"ChartType\"></a>\n## type ChartType\n\n\n\n```go\ntype ChartType string\n```\n\n<a name=\"ChartTypeLine\"></a>\n\n```go\nconst (\n    ChartTypeLine           ChartType = \"line\"\n    ChartTypeScatter        ChartType = \"scatter\"\n    ChartTypeBar            ChartType = \"bar\"\n    ChartTypePie            ChartType = \"pie\"\n    ChartTypeBoxAndWhisker  ChartType = \"box_and_whisker\"\n    ChartTypeCompositeChart ChartType = \"composite_chart\"\n    ChartTypeUnknown        ChartType = \"unknown\"\n)\n```\n\n<a name=\"CodeLanguage\"></a>\n## type CodeLanguage\n\nCodeLanguage\n\n```go\ntype CodeLanguage string\n```\n\n<a name=\"CodeLanguagePython\"></a>\n\n```go\nconst (\n    CodeLanguagePython     CodeLanguage = \"python\"\n    CodeLanguageJavaScript CodeLanguage = \"javascript\"\n    CodeLanguageTypeScript CodeLanguage = \"typescript\"\n)\n```\n\n<a name=\"CodeRunParams\"></a>\n## type CodeRunParams\n\nCodeRunParams represents parameters for code execution\n\n```go\ntype CodeRunParams struct {\n    Argv []string\n    Env  map[string]string\n}\n```\n\n<a name=\"CreateSnapshotParams\"></a>\n## type CreateSnapshotParams\n\nCreateSnapshotParams represents parameters for creating a snapshot\n\n```go\ntype CreateSnapshotParams struct {\n    Name           string\n    Image          any // string or *Image\n    Resources      *Resources\n    Entrypoint     []string\n    SkipValidation *bool\n}\n```\n\n<a name=\"DaytonaConfig\"></a>\n## type DaytonaConfig\n\nDaytonaConfig represents the configuration for the Daytona client. When a field is nil, the client will fall back to environment variables or defaults.\n\n```go\ntype DaytonaConfig struct {\n    APIKey         string\n    JWTToken       string\n    OrganizationID string\n    APIUrl         string\n    Target         string\n    Experimental   *ExperimentalConfig\n}\n```\n\n<a name=\"ExecuteResponse\"></a>\n## type ExecuteResponse\n\nExecuteResponse represents a command execution response\n\n```go\ntype ExecuteResponse struct {\n    ExitCode  int\n    Result    string\n    Artifacts *ExecutionArtifacts // nil when no artifacts available\n}\n```\n\n<a name=\"ExecutionArtifacts\"></a>\n## type ExecutionArtifacts\n\nExecutionArtifacts represents execution output artifacts\n\n```go\ntype ExecutionArtifacts struct {\n    Stdout string\n    Charts []Chart\n}\n```\n\n<a name=\"ExecutionError\"></a>\n## type ExecutionError\n\nExecutionError represents a code execution error\n\n```go\ntype ExecutionError struct {\n    Name      string\n    Value     string\n    Traceback *string // Optional stack trace; nil when not available\n}\n```\n\n<a name=\"ExecutionResult\"></a>\n## type ExecutionResult\n\nExecutionResult represents code interpreter execution result\n\n```go\ntype ExecutionResult struct {\n    Stdout string\n    Stderr string\n    Charts []Chart         // Optional charts from matplotlib\n    Error  *ExecutionError // nil = success, non-nil = execution failed\n}\n```\n\n<a name=\"ExperimentalConfig\"></a>\n## type ExperimentalConfig\n\nExperimentalConfig holds experimental feature flags for the Daytona client.\n\n```go\ntype ExperimentalConfig struct {\n    OtelEnabled bool // Enable OpenTelemetry tracing and metrics\n}\n```\n\n<a name=\"FileDownloadRequest\"></a>\n## type FileDownloadRequest\n\nFileDownloadRequest\n\n```go\ntype FileDownloadRequest struct {\n    Source      string\n    Destination *string // nil = download to memory (return []byte), non-nil = save to file path\n}\n```\n\n<a name=\"FileDownloadResponse\"></a>\n## type FileDownloadResponse\n\nFileDownloadResponse represents a file download response\n\n```go\ntype FileDownloadResponse struct {\n    Source string\n    Result any     // []byte or string (path)\n    Error  *string // nil = success, non-nil = error message\n}\n```\n\n<a name=\"FileInfo\"></a>\n## type FileInfo\n\nFileInfo represents file metadata\n\n```go\ntype FileInfo struct {\n    Name         string\n    Size         int64\n    Mode         string\n    ModifiedTime time.Time\n    IsDirectory  bool\n}\n```\n\n<a name=\"FileStatus\"></a>\n## type FileStatus\n\nFileStatus represents the status of a file in git\n\n```go\ntype FileStatus struct {\n    Path   string\n    Status string\n}\n```\n\n<a name=\"FileUpload\"></a>\n## type FileUpload\n\nFileUpload represents a file to upload\n\n```go\ntype FileUpload struct {\n    Source      any // []byte or string (path)\n    Destination string\n}\n```\n\n<a name=\"GitCommitResponse\"></a>\n## type GitCommitResponse\n\nGitCommitResponse\n\n```go\ntype GitCommitResponse struct {\n    SHA string\n}\n```\n\n<a name=\"GitStatus\"></a>\n## type GitStatus\n\nGitStatus represents git repository status\n\n```go\ntype GitStatus struct {\n    CurrentBranch   string\n    Ahead           int\n    Behind          int\n    BranchPublished bool\n    FileStatus      []FileStatus\n}\n```\n\n<a name=\"ImageParams\"></a>\n## type ImageParams\n\nImageParams represents parameters for creating a sandbox from an image\n\n```go\ntype ImageParams struct {\n    SandboxBaseParams\n    Image     any // string or *Image\n    Resources *Resources\n}\n```\n\n<a name=\"LspLanguageID\"></a>\n## type LspLanguageID\n\n\n\n```go\ntype LspLanguageID string\n```\n\n<a name=\"LspLanguagePython\"></a>\n\n```go\nconst (\n    LspLanguagePython     LspLanguageID = \"python\"\n    LspLanguageJavaScript LspLanguageID = \"javascript\"\n    LspLanguageTypeScript LspLanguageID = \"typescript\"\n)\n```\n\n<a name=\"OutputMessage\"></a>\n## type OutputMessage\n\nOutputMessage represents an output message\n\n```go\ntype OutputMessage struct {\n    Type      string `json:\"type\"`\n    Text      string `json:\"text\"`\n    Name      string `json:\"name\"`\n    Value     string `json:\"value\"`\n    Traceback string `json:\"traceback\"`\n}\n```\n\n<a name=\"PaginatedSnapshots\"></a>\n## type PaginatedSnapshots\n\nPaginatedSnapshots represents a paginated list of snapshots\n\n```go\ntype PaginatedSnapshots struct {\n    Items      []*Snapshot\n    Total      int\n    Page       int\n    TotalPages int\n}\n```\n\n<a name=\"Position\"></a>\n## type Position\n\nPosition represents a position in a document\n\n```go\ntype Position struct {\n    Line      int // zero-based\n    Character int // zero-based\n}\n```\n\n<a name=\"PreviewLink\"></a>\n## type PreviewLink\n\nPreviewLink contains the URL and authentication token for a sandbox preview.\n\n```go\ntype PreviewLink struct {\n    URL   string\n    Token string\n}\n```\n\n<a name=\"PtyResult\"></a>\n## type PtyResult\n\nPtyResult represents PTY session exit information\n\n```go\ntype PtyResult struct {\n    ExitCode *int    // nil = process still running, non-nil = exit code\n    Error    *string // nil = success, non-nil = error message\n}\n```\n\n<a name=\"PtySessionInfo\"></a>\n## type PtySessionInfo\n\nPtySessionInfo represents PTY session information\n\n```go\ntype PtySessionInfo struct {\n    ID        string\n    Active    bool\n    CWD       string // Current working directory; may be empty unavailable\n    Cols      int\n    Rows      int\n    ProcessID *int // Process ID; may be nil if unavailable\n    CreatedAt time.Time\n}\n```\n\n<a name=\"PtySize\"></a>\n## type PtySize\n\nPtySize represents terminal dimensions\n\n```go\ntype PtySize struct {\n    Rows int\n    Cols int\n}\n```\n\n<a name=\"Resources\"></a>\n## type Resources\n\nResources represents resource allocation for a sandbox.\n\n```go\ntype Resources struct {\n    CPU    int\n    GPU    int\n    Memory int\n    Disk   int\n}\n```\n\n<a name=\"SandboxBaseParams\"></a>\n## type SandboxBaseParams\n\nSandboxBaseParams contains common parameters for sandbox creation.\n\n```go\ntype SandboxBaseParams struct {\n    Name                string\n    User                string\n    Language            CodeLanguage\n    EnvVars             map[string]string\n    Labels              map[string]string\n    Public              bool\n    AutoStopInterval    *int // nil = no auto-stop, 0 = immediate stop\n    AutoArchiveInterval *int // nil = no auto-archive, 0 = immediate archive\n    AutoDeleteInterval  *int // nil = no auto-delete, 0 = immediate delete\n    Volumes             []VolumeMount\n    NetworkBlockAll     bool\n    NetworkAllowList    *string\n    Ephemeral           bool\n}\n```\n\n<a name=\"ScreenshotOptions\"></a>\n## type ScreenshotOptions\n\n\n\n```go\ntype ScreenshotOptions struct {\n    ShowCursor *bool    // nil = default, true = show, false = hide\n    Format     *string  // nil = default format (PNG), or \"jpeg\", \"webp\", etc.\n    Quality    *int     // nil = default quality, 0-100 for JPEG/WebP\n    Scale      *float64 // nil = 1.0, scaling factor for the screenshot\n}\n```\n\n<a name=\"ScreenshotRegion\"></a>\n## type ScreenshotRegion\n\nScreenshotRegion represents a screenshot region\n\n```go\ntype ScreenshotRegion struct {\n    X      int\n    Y      int\n    Width  int\n    Height int\n}\n```\n\n<a name=\"ScreenshotResponse\"></a>\n## type ScreenshotResponse\n\n\n\n```go\ntype ScreenshotResponse struct {\n    Image     string // base64-encoded image data\n    Width     int\n    Height    int\n    SizeBytes *int // Size in bytes\n}\n```\n\n<a name=\"Snapshot\"></a>\n## type Snapshot\n\nSnapshot represents a Daytona snapshot\n\n```go\ntype Snapshot struct {\n    ID             string     `json:\"id\"`\n    OrganizationID string     `json:\"organizationId,omitempty\"`\n    General        bool       `json:\"general\"`\n    Name           string     `json:\"name\"`\n    ImageName      string     `json:\"imageName,omitempty\"`\n    State          string     `json:\"state\"`\n    Size           *float64   `json:\"size,omitempty\"`\n    Entrypoint     []string   `json:\"entrypoint,omitempty\"`\n    CPU            int        `json:\"cpu\"`\n    GPU            int        `json:\"gpu\"`\n    Memory         int        `json:\"mem\"` // API uses \"mem\" not \"memory\"\n    Disk           int        `json:\"disk\"`\n    ErrorReason    *string    `json:\"errorReason,omitempty\"` // nil = success, non-nil = error reason if snapshot failed\n    SkipValidation bool       `json:\"skipValidation\"`\n    CreatedAt      time.Time  `json:\"createdAt\"`\n    UpdatedAt      time.Time  `json:\"updatedAt\"`\n    LastUsedAt     *time.Time `json:\"lastUsedAt,omitempty\"`\n}\n```\n\n<a name=\"SnapshotParams\"></a>\n## type SnapshotParams\n\nSnapshotParams represents parameters for creating a sandbox from a snapshot\n\n```go\ntype SnapshotParams struct {\n    SandboxBaseParams\n    Snapshot string\n}\n```\n\n<a name=\"Volume\"></a>\n## type Volume\n\nVolume represents a Daytona volume\n\n```go\ntype Volume struct {\n    ID             string    `json:\"id\"`\n    Name           string    `json:\"name\"`\n    OrganizationID string    `json:\"organizationId\"`\n    State          string    `json:\"state\"`\n    ErrorReason    *string   `json:\"errorReason,omitempty\"`\n    CreatedAt      time.Time `json:\"createdAt\"`\n    UpdatedAt      time.Time `json:\"updatedAt\"`\n    LastUsedAt     time.Time `json:\"lastUsedAt,omitempty\"`\n}\n```\n\n<a name=\"VolumeMount\"></a>\n## type VolumeMount\n\nVolumeMount represents a volume mount configuration\n\n```go\ntype VolumeMount struct {\n    VolumeID  string\n    MountPath string\n    Subpath   *string // Optional subpath within the volume; nil = mount entire volume\n}\n```\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/agentkit/inngest-agentkit-coding-agent.mdx",
    "content": "---\ntitle: Build Coding Agent Using AgentKit and Daytona\ndescription: Step-by-step guide to building an autonomous coding agent using AgentKit framework and Daytona sandboxes.\n---\n\nimport { Image } from 'astro:assets'\n\nimport notesAppResult from '../../../../../assets/docs/images/inngest-agentkit-notes-app.gif'\n\nThis guide demonstrates how to set up and use a fully autonomous coding agent that performs software development tasks in a [Daytona](https://daytona.io) sandbox environment. The agent is built using [AgentKit](https://agentkit.inngest.com/) and leverages Daytona sandboxes for secure, isolated execution. It can create web apps, run tests, execute scripts, and more; automating multi-step workflows based on user prompts.\n\n---\n\n### 1. Workflow Overview\n\nYou provide a natural language prompt describing the software task. The agent reasons about your request, plans the steps, and executes them securely in a Daytona sandbox; handling everything from project setup to live previews.\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nClone the [repository](https://github.com/daytonaio/daytona) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/typescript/agentkit-inngest/coding-agent/anthropic\n```\n\n#### Configure Environment\n\nGet your API keys:\n\n- **Daytona API key:** [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- **Anthropic API key:** [Anthropic Console](https://console.anthropic.com/)\n\nCopy `.env.example` to `.env` and add your keys:\n\n```bash\nDAYTONA_API_KEY=your_daytona_key\nANTHROPIC_API_KEY=your_anthropic_key\n```\n\n#### Local Usage\n\n:::note[Node.js Version]\nNode.js 18 or newer is required to run the coding agent locally. Please ensure your environment meets this requirement before proceeding.\n:::\n\nInstall dependencies:\n\n```bash\nnpm install\n```\n\nRun the agent:\n\n```bash\nnpm run start\n```\n\n#### Docker\n\nBuild the Docker image:\n\n```bash\ndocker buildx build . -t coding-agent\n```\n\nRun the container:\n\n```bash\ndocker run --rm -it coding-agent\n```\n\n### 3. Configuration\n\n- **Prompt Setting:** Edit the main prompt in `network.run(...)` in `src/index.ts` to change the agent's task.\n- **Debug Logs:** Set `enableDebugLogs=true` for detailed agent flow tracking.\n\n### 4. Example Usage\n\nTry the default prompt in `src/index.ts`:\n\n```typescript\nconst result = await network.run(\n  `Create a minimal React app called \"Notes\" that lets users add, view, and delete notes. Each note should have a title and content. Use Create React App or Vite for setup. Include a simple UI with a form to add notes and a list to display them.`\n)\n```\n\n**The agent will:**\n\n- Scaffold the app\n- Install dependencies\n- Start the dev server\n- Generate a preview link\n\nTerminal output example:\n\n```\n✔️ App is ready!\nPreview: https://5173-3a828150-1573-42e3-bf9f-9793a2c2c0c2.proxy.daytona.works\n```\n\nThe image below shows the result generated in this run:\n\n<Image\n  src={notesAppResult}\n  alt=\"Notes app demo generated by coding agent\"\n  width={600}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\n### 5. Understanding the Agent's Execution Flow\n\nThe agent operates by leveraging a large language model (LLM) under the hood and has access to a suite of specialized tools. These tools enable the agent to perform everything needed inside the Daytona sandbox environment; from project setup to app deployment. At each step, the agent reasons about the current goal, decides which tool to call, and orchestrates the workflow to achieve the desired outcome.\n\nBelow is a step-by-step breakdown of how the agent builds the demo Notes app showing each iteration, the agent's message, and the tool used:\n\n#### Project Initialization\n\n**Agent message:**\n\n```\nI'll create a React app for Notes using Vite, which provides a faster and more modern setup compared to Create React App. I'll break this down into steps:\n- First, I'll create the project using Vite\n- Install necessary dependencies\n- Create the components for the Notes app\n- Implement the core functionality\n\nLet's get started:\n```\n\n**Tool used:**\n\n`shellTool` was called with command:\n\n```\nnpm create vite@latest notes -- --template react\n```\n\n#### Install Dependencies\n\n**Agent message:**\n\n```\nNow, I'll navigate to the project directory and install dependencies:\n```\n\n**Tool used:**\n\n`shellTool` was called with command:\n\n```\ncd notes && npm install\n```\n\n#### Create Components & Update App Structure\n\n**Agent message:**\n\n```\nNow, I'll create the necessary components and update the app structure:\n1. Update App.jsx\n2. Update App.css for basic styling\n```\n\n**Tool used:**\n\n`uploadFilesTool` was called to upload:\n\n```\nApp.jsx (main component logic)\nApp.css (basic styling)\n```\n\n#### Start Development Server\n\n**Agent message:**\n\n```\nNow, I'll start the development server:\n```\n\n**Tool used:**\n\n`startDevServerTool` was called with command:\n\n```\ncd notes && npm run dev\n```\n\n#### Check Dev Server Health\n\n**Agent message:**\n\n```\nLet's check the dev server health:\n```\n\n**Tool used:**\n\n`checkDevServerHealthTool` was called to verify that the development server is running and accessible.\n\n#### App Summary & Features\n\n**Agent message:**\n\n```\nGreat! I've created a minimal React Notes app with the following features:\n- Add notes with a title and content\n- View the list of notes\n- Delete individual notes\n- Basic responsive styling\n\nKey details:\n- Used Vite for project setup\n- Implemented state management with React hooks (useState)\n- Simple form for adding notes\n- Notes are stored in local state\n- Each note has a unique ID, title, and content\n- Delete functionality for individual notes\n\nDEV_SERVER_PORT=5173\n\nTASK_COMPLETED\n\nThe app is now running and ready to use. Users can:\n1. Enter a note title in the first input\n2. Enter note content in the textarea\n3. Click \"Add Note\" to save the note\n4. View notes in the list below\n5. Delete notes by clicking the \"Delete\" button next to each note\n\nWould you like me to explain any part of the implementation or make any modifications?\n```\nNotice `DEV_SERVER_PORT` and `TASK_COMPLETED` fields in the agent output message.\n\n`DEV_SERVER_PORT` value is auto-detected by the agent and used to generate the preview link for your app.\n\n`TASK_COMPLETED` signals that the task is finished which is used inside the agent routing logic.\n\n---\n\n**Key advantages:**\n\n- Secure, isolated execution\n- Multi-language support\n- Auto-detects dev server, starts it, and generates preview link\n- Detailed debug logs for agent actions\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/claude/claude-agent-sdk-connect-service-sandbox.mdx",
    "content": "---\ntitle: Build a Two-Agent Coding System with Claude and Daytona\ndescription: Step-by-step guide to building a dual-agent coding system using Claude Agent SDK and Daytona sandboxes.\n---\n\nThis guide demonstrates how to run a two-agent autonomous coding system using the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview) and Daytona sandboxes. The system consists of a **Project Manager Agent** (local) and a **Developer Agent** (in-sandbox), enabling advanced delegation, planning, and secure code execution.\n\nThe Project Manager Agent runs locally and uses the basic Anthropic interface with the `claude-sonnet-4-20250514` model for high-level planning and task delegation. The Developer Agent runs inside the Daytona sandbox and is created using the Claude Agent SDK, which leverages Claude Code for advanced coding and automation capabilities. This architecture separates high-level planning from low-level code execution for more robust automation.\n\nA key advantage of this approach is its **extensibility**: you can easily replace the Project Manager Agent with your own custom orchestrator logic, or even another agent, making the system highly reusable and adaptable to a wide range of advanced automation and coordination use cases.\n\n---\n\n### 1. Workflow Overview\n\nWhen the main module is launched, a Daytona sandbox is created for the Developer Agent, and a Project Manager Agent is initialized locally. Interaction with the system occurs via a command line chat interface. The Project Manager Agent receives prompts, plans the workflow, and delegates coding tasks to the Developer Agent. The Developer Agent executes tasks in the sandbox and streams results back to the Project Manager, who reviews and coordinates further actions. All logs and outputs from both agents are streamed in real time to the terminal, providing full visibility into the process as it is managed by the Project Manager Agent.\n\nThe Developer Agent can also host web apps and provide preview links using [Daytona Preview Links](https://www.daytona.io/docs/en/preview-and-authentication/). The Project Manager Agent will present these links and summarize the results for you.\n\nYou can continue interacting with the system until you are finished. When you exit the program, the sandbox is deleted automatically.\n\n---\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nFirst, clone the daytona [repository](https://github.com/daytonaio/daytona.git) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/typescript/anthropic/multi-agent-claude-sdk\n```\n\n#### Configure Environment\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `ANTHROPIC_API_KEY`: Required for the **Project Manager Agent** (runs locally). Get it from [Claude Developer Platform](https://console.anthropic.com/settings/keys)\n- `SANDBOX_ANTHROPIC_API_KEY`: **Optional** for the **Developer Agent** (runs in sandbox). If not provided, defaults to using `ANTHROPIC_API_KEY`. Get it from [Claude Developer Platform](https://console.anthropic.com/settings/keys)\n\nCopy `.env.example` to `.env` and add your keys:\n\n```bash\nDAYTONA_API_KEY=your_daytona_key\nANTHROPIC_API_KEY=your_anthropic_key\nSANDBOX_ANTHROPIC_API_KEY=your_anthropic_key\n```\n\n:::tip[Agent API Key Options]\nYou can use a single `ANTHROPIC_API_KEY` for both agents, or provide a separate `SANDBOX_ANTHROPIC_API_KEY` for billing/tracking purposes.\n:::\n\n:::caution[API Key Security]\nThe `SANDBOX_ANTHROPIC_API_KEY` is passed into the Daytona sandbox environment and is accessible to any code executed inside the sandbox.\n:::\n\n#### Local Usage\n\n:::note[Node.js Version]\nNode.js 18 or newer is required to run this example. Please ensure your environment meets this requirement before proceeding.\n:::\n\nInstall dependencies:\n\n```bash\nnpm install\n```\n\nRun the two-agent system:\n\n```bash\nnpm run start\n```\n\nThe system will start and wait for your prompt.\n\n---\n\n### 3. Example Usage\n\nExample chat session:\n\n```\n$ npm run start\nCreating Developer Agent sandbox...\nInstalling Developer Agent SDK...\nInitializing Developer Agent...\nInitializing Project Manager Agent...\n\n=== Two-Agent System Ready ===\nProject Manager Agent: Manages tasks and delegates to Developer (Green text)\nDeveloper Agent: Executes code in Daytona sandbox (White text)\nPress Ctrl+C at any time to exit.\n\nUser: make a lunar lander web app\n\n[Project Manager] Processing your request...\n\n[Project Manager]: I'll help you create a lunar lander web app! Let me delegate this task to the Developer Agent.\n\n<developer_task>\nCreate a lunar lander web game with the following features:\n\n- HTML/CSS/JavaScript based\n- Canvas graphics for the game\n- Physics simulation (gravity, thrust, velocity)\n- Keyboard controls (arrow keys)\n- Landing detection (safe landing vs crash)\n- Fuel management system\n- Start the game on port 80 and provide the preview URL\n  </developer_task>\n\n[Delegating to Developer Agent]...\n\nI'll help you create a lunar lander web app! Let me build a complete game with physics simulation, graphics, and controls.\n🔨 Write\n🔨 Write\n🔨 Bash\nPerfect! The web server is now running.\n\nYour Lunar Lander game is live at:\n🌐 https://80-17ac1c0f-d684-4122-93b5-8f52fd5393f8.proxy.daytona.works\n\n[Project Manager]: Excellent! The Developer Agent has successfully created your lunar lander web app. The game is now running and accessible at the preview URL above. The implementation includes:\n\n✓ Physics simulation with gravity and thrust\n✓ Canvas-based graphics\n✓ Keyboard controls for gameplay\n✓ Landing detection system\n✓ Fuel management\n✓ Web server running on port 80\n\nTASK_COMPLETE\n\n[Project Manager] All tasks completed!\n```\n\n---\n\n\n### 4. Understanding the Agent Architecture\n\nThis system is composed of two collaborating agents, each with a distinct role and implementation. Below is a step-by-step guide to how each agent operates and interacts within the workflow.\n\n#### Project Manager Agent (Terminal Orchestration)\n\n1. **User Interaction:**\n  - All user interaction occurs via the terminal with the Project Manager Agent.\n  - The Project Manager Agent is configured with a system prompt that defines its role and maintains the full conversation history.\n2. **Awareness of Developer Agent:**\n  - The Project Manager Agent knows that a Developer Agent is available inside a Daytona sandbox and can be invoked as needed.\n3. **Task Delegation:**\n  - When the Project Manager Agent determines that a coding task should be delegated, it encapsulates the task within `<developer_task>` tags in its response.\n  - The system parses these tags and, when present, invokes the Developer Agent with the specified task.\n4. **Iterative Workflow:**\n  - This process can repeat multiple times, with the Project Manager Agent reasoning about progress and delegating further tasks as needed.\n5. **Session Completion:**\n  - When the Project Manager Agent determines the overall task is complete, it outputs `TASK_COMPLETE`, which signals the system to terminate the session.\n\n#### Developer Agent (Sandbox Execution)\n\n1. **Provisioning:**\n  - The Developer Agent is provisioned inside a Daytona sandbox and is responsible for executing coding tasks.\n2. **SDK Installation:**\n  - The system installs the Claude Agent SDK in the sandbox by running `pip install` (see [process execution](/docs/en/process-code-execution#process-execution)).\n3. **Interpreter Context:**\n  - A new [code interpreter context](/docs/en/process-code-execution#stateful-code-interpreter) is created for isolated execution.\n4. **Script Upload:**\n  - The coding agent script is uploaded to the sandbox using [file uploading](/docs/file-system-operations#uploading-a-single-file).\n5. **SDK Initialization:**\n  - The Claude Agent SDK is initialized in the interpreter context (e.g., `import coding_agent`).\n6. **Task Execution:**\n  - When a `<developer_task>` is received, the system sends the task to the Developer Agent by running a Python command in the interpreter context:\n    ```typescript\n    const result = await sandbox.codeInterpreter.runCode(\n     `coding_agent.run_query_sync(os.environ.get('PROMPT', ''))`,\n     {\n      context: ctx,\n      envs: { PROMPT: task },\n      onStdout,\n      onStderr,\n     }\n    );\n    ```\n  - The Developer Agent executes the task, streams output, and returns results to the Project Manager Agent for review and further coordination.\n\n---\n\n### 5. Customization\n\nYou can customize the Project Manager Agent's behavior by modifying the system prompt in `src/index.ts`. The current implementation:\n\n- Uses `<developer_task>` tags for delegation\n- Automatically reviews Developer Agent outputs\n- Says \"TASK_COMPLETE\" when finished\n\n---\n\n### 6. Cleanup\n\nWhen you exit the main program, the Daytona sandbox and all files are automatically deleted.\n\n---\n\n**Key advantages:**\n\n- Secure, isolated execution in Daytona sandboxes\n- Hierarchical agent architecture for robust automation\n- Extensible and reusable architecture\n- Automatic dev server detection and live preview links\n- Multi-language and full-stack support\n- Simple setup and automatic cleanup\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/claude/claude-agent-sdk-interactive-terminal-sandbox.mdx",
    "content": "---\ntitle: Build a Coding Agent Using Claude Agent SDK and Daytona\ndescription: Step-by-step guide to building an autonomous coding agent using Claude Code and Daytona sandboxes.\n---\n\nimport { Image } from 'astro:assets'\n\nimport claudeAgentSDKInteractiveTerminalSandboxResult from '../../../../../assets/docs/images/claude-agent-sdk-interactive-terminal-sandbox-result.gif'\n\nThis guide demonstrates how to run an autonomous coding agent based on [Claude Code](https://code.claude.com/docs/en/overview) inside a Daytona sandbox environment. The agent uses the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview) to follow user prompts.\n\nThe agent can develop full-stack web apps, write code in any language, install dependencies, and run scripts. It can also start and manage dev servers, and generate preview links for live apps.\n\n---\n\n### 1. Workflow Overview\n\nWhen you launch the main module, a Daytona sandbox is created and a Python agent is initialized inside it. The agent is based on the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview).\n\nYou interact with the main program via a command line chat interface. The program sends your prompts to the agent inside the sandbox, which executes them and returns the results:\n\n```\n$ npm run start                                   174s\nCreating sandbox...\nInstalling Agent SDK...\nInitializing Agent SDK...\nPress Ctrl+C at any time to exit.\nUser: Build a Zelda-like game where I can move around the screen and talk to famous programmers\nThinking...\nI'll build a Zelda-like game for you! This will be a fun project with player movement and NPC interactions with famous programmers.\n🔨 Write\n🔨 Write\nNow let me start a simple HTTP server to host the game:\n🔨 Bash\nPerfect! I've created a Zelda-like game called \"Programmer's Quest\" for you! 🎮\n\n## Game Features:\n\n✨ Zelda-style gameplay:\n- Top-down 2D view with classic retro aesthetics\n- Player character with sword and shield\n- Grid-based movement system\n- Environmental obstacles (trees and rocks)\n\n👥 Famous Programmers as NPCs:\n1. Linus Torvalds - Creator of Linux\n2. Grace Hopper - COBOL pioneer and Admiral\n3. Alan Turing - Father of computer science\n4. Ada Lovelace - First computer programmer\n5. Dennis Ritchie - Creator of C and UNIX\n\n🎮 Controls:\n- Arrow Keys or WASD - Move your character\n- SPACE - Talk to NPCs when you're near them\n\n🌟 Gameplay:\n- Explore the grassy map and find all 5 legendary programmers\n- Each NPC has multiple quotes that cycle when you talk to them\n- NPCs glow when you're near them\n- Dialog boxes appear with their famous quotes\n- Track your progress in the HUD\n\n## Play Now:\n🎯 [Click here to play the game!](https://80-8e2c4d23-212a-4f1e-bb6c-abfa71aeed3a.proxy.daytona.works)\n\nThe game features smooth movement, collision detection with trees and rocks, and an immersive dialog system. Try to find and talk to all 5 famous programmers to learn their wisdom! Each has 3 different quotes that cycle as you keep talking to them.\n\nEnjoy your adventure! 🗡️✨\nUser:\n```\n\nThe agent can also host web apps and provide you with a preview link using the [Daytona Preview Links](https://www.daytona.io/docs/en/preview-and-authentication/) feature. When your task involves running or previewing a web application, the agent automatically reasons about this need, hosts the app, and generates a preview link for you to inspect the live result:\n\n<Image\n  src={claudeAgentSDKInteractiveTerminalSandboxResult}\n  alt=\"RPG game demo generated by coding agent\"\n  width={600}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\nYou can continue interacting with your agent until you are finished. When you exit the program, the sandbox will be deleted automatically.\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nFirst, clone the daytona [repository](https://github.com/daytonaio/daytona.git) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/typescript/anthropic/single-claude-agent-sdk\n```\n\n#### Configure Environment\n\nGet your API keys:\n\n- **Daytona API key:** [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- **Anthropic API key:** [Anthropic Console](https://console.anthropic.com/)\n\nCopy `.env.example` to `.env` and add your keys:\n\n```bash\nDAYTONA_API_KEY=your_daytona_key\nSANDBOX_ANTHROPIC_API_KEY=your_anthropic_key\n```\n\n:::caution[API Key Security]\nNote: The `SANDBOX_ANTHROPIC_API_KEY` key is passed into the Daytona sandbox environment and is accessible to any code executed inside the sandbox.\n:::\n\n#### Local Usage\n\n:::note[Node.js Version]\nNode.js 18 or newer is required to run this example. Please ensure your environment meets this requirement before proceeding.\n:::\n\nInstall dependencies:\n\n```bash\nnpm install\n```\n\nRun the agent:\n\n```bash\nnpm run start\n```\n\nThe agent will start and wait for your prompt.\n\n### 3. Example Usage\n\nExample chat session:\n\n```\n$ npm run start\nCreating sandbox...\nInstalling Agent SDK...\nInitializing Agent SDK...\nPress Ctrl+C at any time to exit.\nUser: Create a fun pet store landing page in Svelte\nThinking...\nI'll create a fun pet store landing page in Svelte for you! Let me set up the project and build an engaging landing page with animations and a colorful design.\n🔨 Bash\n🔨 Bash\nNow let me create a fun and engaging pet store landing page with animations, colorful sections, and interactive elements:\n🔨 Read\n> 🔨 Write\nNow let me create the component files:\n🔨 Write\n🔨 Write\n🔨 Write\n🔨 Write\n🔨 Write\nNow let's update the main CSS file and start the development server:\n🔨 Read\n🔨 Write\nNow let's start the development server:\n🔨 Bash\n🔨 TaskOutput\nPerfect! 🎉 I've created a fun and colorful pet store landing page in Svelte! Here's what I built:\n\n## Features:\n\n✨ Hero Section\n\n- Beautiful gradient background with animated floating cards\n- Eye-catching navigation bar\n- Call-to-action buttons with hover effects\n- Bouncing emoji animations\n\n🎯 Features Section\n\n- 4 key benefits (Free Delivery, Premium Quality, Special Offers, Award Winning)\n- Interactive cards with hover animations\n- Icons that rotate and scale on hover\n\n🛍️ Products Section\n\n- 6 featured products with colorful backgrounds\n- Star ratings\n- Add to cart functionality\n- Smooth hover animations\n\n📧 Newsletter Section\n\n- Vibrant gradient background with floating pet emojis\n- Email subscription form\n- Success message animation\n- Special 20% off offer\n\n👣 Footer\n\n- Comprehensive navigation links\n- Social media icons\n- Dark gradient design\n\n## Live Preview:\n\nYour pet store is now running at: https://80-b3739199-d90e-4bde-ab18-450d74c950e8.proxy.daytona.works\n\nThe page includes:\n\n- Smooth scroll behavior\n- Responsive design for mobile devices\n- Fun animations throughout\n- Interactive elements with hover effects\n- Colorful gradients and modern styling\n- Emoji-based icons for a playful feel\n\nClick the link to see your fun pet store landing page in action! 🐾\nUser:\n\n```\n\n### 4. Understanding the Agent's Architecture\n\nThis example consists of two main components:\n\n- **Main Program:** The main program is a Node.js script (`index.ts`) that runs on your local machine. It uses the Daytona SDK to create and manage a Daytona sandbox. The main program provides a command line interface for interacting with the agent inside the sandbox.\n- **Sandbox Agent:** The sandbox agent is a Python script (`coding_agent.py`) that runs inside the Daytona sandbox. It uses the Claude Agent SDK to create a customized coding agent similar to Claude Code.\n\n#### Initialization\n\nOn initialization, the main program:\n\n1. Creates a new [Daytona sandbox](/docs/en/sandboxes) with your Anthropic API key included in the environment variables.\n2. Installs the Claude Agent SDK by running `pip install` in the sandbox with [process execution](/docs/en/process-code-execution#process-execution).\n3. Creates a new [code interpreter context](/docs/en/process-code-execution#stateful-code-interpreter).\n4. Uploads the coding agent script to the sandbox with [file uploading](/docs/file-system-operations#uploading-a-single-file).\n5. Initializes the Claude Agent SDK by running `import coding_agent` in the code interpreter context.\n6. Waits for user input and sends prompts to the agent in the code interpreter context as shown below.\n\n#### Main Program Code\n\nOnce the agent is running, the program creates a readline interface to read user input and sends it to the agent.\nEach user request is passed to the agent by running a Python command in the code interpreter context:\n\n```typescript\nconst result = await sandbox.codeInterpreter.runCode(\n  `coding_agent.run_query_sync(os.environ.get('PROMPT', ''))`,\n  {\n    context: ctx,\n    envs: { PROMPT: prompt },\n    onStdout,\n    onStderr,\n  }\n)\n```\n\nThe `onStdout` and `onStderr` callbacks are used to pass the agent's output back to the main program. After the agent finishes responding to the prompt, the main program waits for the next user input.\n\n#### Sandbox Agent Code\n\nThe sandbox agent uses the [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview) to create a customized coding agent based on Claude Code.\nThe agent is initialized with a system prompt that includes the workspace directory and an example of the [preview URL format](/docs/en/preview-and-authentication):\n\n```python\nsystem_prompt = \"\"\"\nYou are running in a Daytona sandbox.\nUse the /home/daytona directory instead of /workspace for file operations.\nYour public preview URL for port 80 is: {}.\n\"\"\".format(preview_url)\n```\n\nIt also specifies the [tools and permission mode](https://platform.claude.com/docs/en/agent-sdk/quickstart#key-concepts) of the agent:\n\n```python\nclient = ClaudeSDKClient(\n  options=ClaudeAgentOptions(\n    allowed_tools=[\"Read\", \"Edit\", \"Glob\", \"Grep\", \"Bash\"],\n    permission_mode=\"acceptEdits\",\n    system_prompt=system_prompt\n  )\n)\n```\n\nThe code to run queries and receive responses follows the examples in Anthropic's [Claude Agent Python SDK documentation](https://platform.claude.com/docs/en/agent-sdk/python).\n\n#### Clean up\n\nWhen you exit the main program, the Daytona sandbox and all files are automatically deleted.\n\n**Key advantages:**\n\n- Secure, isolated execution in Daytona sandboxes\n- Communicate with the agent directly in your terminal\n- Automatic dev server detection and live preview links\n- Multi-language and full-stack support\n- Simple setup and automatic cleanup\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/claude/claude-code-run-cli-sandbox.mdx",
    "content": "---\ntitle: Run Claude Code in a Daytona Sandbox via CLI\ndescription: Learn how to run Claude Code inside a Daytona sandbox using the Daytona CLI for secure and isolated task execution.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nThis guide walks you through running Claude Code inside a Daytona sandbox using the Daytona CLI.\n\n### Prerequisites\n\n- Daytona account and API key (Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys))\n- Local terminal (macOS, Linux, or Windows)\n\n### Install the Daytona CLI\n\n<Tabs syncKey=\"os\">\n  <TabItem label=\"Mac/Linux\">\n    ```bash \n    brew install daytonaio/cli/daytona\n    ```\n  </TabItem>\n  <TabItem label=\"Windows\">\n    ```bash\n    powershell -Command \"irm https://get.daytona.io/windows | iex\" \n    ```\n  </TabItem>\n</Tabs>\n\n:::note\nAlready have the CLI? Check your version with `daytona --version`. If it's below **0.135.0**, [upgrade to the latest version](https://www.daytona.io/docs/en/getting-started/#cli).\n:::\n\n### Authenticate with Daytona\n\nLog in to your Daytona account using your API key:\n\n```bash\ndaytona login --api-key=YOUR_API_KEY\n```\n\nReplace `YOUR_API_KEY` with your actual Daytona API key.\n\n### Create a Sandbox\n\nCreate a new sandbox for running Claude Code:\n\n```bash\ndaytona sandbox create --name claude-sandbox\n```\n\nThis creates a sandbox named `claude-sandbox`, visible in your [Dashboard](https://app.daytona.io/dashboard/sandboxes). The default Daytona snapshot includes Claude Code, so the command above is all you need.\n\n:::tip\nNeed more power? Pass `--snapshot daytona-large` or `--snapshot daytona-medium` flag to increase your sandbox resources. See [default snapshots](https://www.daytona.io/docs/en/snapshots/#default-snapshots) for resource details.\n:::\n\n### Connect to the Sandbox\n\nSSH into your sandbox:\n\n```bash\ndaytona ssh claude-sandbox\n```\n\nYou now have an interactive terminal session inside the sandbox.\n\n### Run Claude Code\n\nInside the SSH session, start Claude Code:\n\n```bash\nclaude\n```\n\nOn first run, Claude Code will prompt you to authenticate:\n\n1. Copy the authentication URL displayed in the terminal\n2. Open the URL in your local browser\n3. Complete the authentication flow\n4. Copy the code provided by the browser\n5. Paste the code back into the terminal\n\nOnce authenticated, you're all set. Claude Code runs inside the sandbox while you control it from your terminal."
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/claude/claude-code-run-tasks-stream-logs-sandbox.mdx",
    "content": "---\ntitle: Running Claude Code with Daytona\ndescription: Step-by-step guide to running Claude Code with Daytona sandboxes.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nClaude Code allows you to automate and orchestrate tasks using natural language and code. With Daytona, you can easily run Claude Code inside isolated sandboxes, making it simple to experiment and execute tasks securely.\n\n## Running Claude Code in a Daytona Sandbox\n\nYou can run Claude Code and execute tasks with it directly inside a Daytona sandbox. The following examples show how to set up a sandbox, install Claude Code, run tasks programmatically, and stream logs in real time.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n> **Note:** While both sync and async modes support streaming PTY output, `AsyncDaytona` is recommended as it provides automatic background callbacks via `on_data`. The synchronous API requires blocking iteration or manual threading to handle output.\n```python\nimport os\nimport asyncio\nfrom daytona import AsyncDaytona\n\nasync def run_claude_code():\n    async with AsyncDaytona() as daytona:\n        sandbox = await daytona.create()\n\n        # Define the Claude Code command to be executed\n        claude_command = \"claude --dangerously-skip-permissions -p 'write a dad joke about penguins' --output-format stream-json --verbose\"\n\n        # Install Claude Code in the sandbox\n        await sandbox.process.exec(\"npm install -g @anthropic-ai/claude-code\")\n\n        pty_handle = await sandbox.process.create_pty_session(\n            id=\"claude\", on_data=lambda data: print(data.decode(), end=\"\")\n        )\n\n        await pty_handle.wait_for_connection()\n\n        # Run the Claude Code command inside the sandbox\n        await pty_handle.send_input(\n            f\"ANTHROPIC_API_KEY={os.environ['ANTHROPIC_API_KEY']} {claude_command}\\n\"\n        )\n\n        # Use this to close the terminal session if no more commands will be executed\n        # await pty_handle.send_input(\"exit\\n\")\n\n        await pty_handle.wait()\n\n        # If you are done and have closed the PTY terminal, it is recommended to clean up resources by deleting the sandbox\n        # await sandbox.delete()\n\nif __name__ == \"__main__\":\n    asyncio.run(run_claude_code())\n\n````\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { Daytona } from \"@daytonaio/sdk\";\n\nconst daytona = new Daytona();\n\ntry {\n    const sandbox = await daytona.create();\n\n    // Define the Claude Code command to be executed\n    const claudeCommand =\n    \"claude --dangerously-skip-permissions -p 'write a dad joke about penguins' --output-format stream-json --verbose\";\n\n    // Install Claude Code in the sandbox\n    await sandbox.process.executeCommand(\"npm install -g @anthropic-ai/claude-code\");\n\n    const ptyHandle = await sandbox.process.createPty({\n        id: \"claude\",\n        onData: (data) => {\n            process.stdout.write(data);\n        },\n    });\n\n    await ptyHandle.waitForConnection();\n\n    // Run the Claude Code command inside the sandbox\n    ptyHandle.sendInput(\n    `ANTHROPIC_API_KEY=${process.env.ANTHROPIC_API_KEY} ${claudeCommand}\\n`\n    );\n\n    // Use this to close the terminal session if no more commands will be executed\n    // ptyHandle.sendInput(\"exit\\n\")\n\n    await ptyHandle.wait();\n\n    // If you are done and have closed the PTY terminal, it is recommended to clean up resources by deleting the sandbox\n    // await sandbox.delete();\n} catch (error) {\n    console.error(\"Failed to run Claude Code in Daytona sandbox:\", error);\n}\n````\n\n</TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/claude/index.mdx",
    "content": "---\ntitle: Claude Guides\ndescription: Guides for using Claude with Daytona\ntableOfContents: false\n---\n\nimport GuidesList from '@components/GuidesList.astro'\n\nGuides for integrating Claude with Daytona.\n\n<GuidesList category=\"claude\" />"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/codex/codex-sdk-interactive-terminal-sandbox.mdx",
    "content": "---\ntitle: Build a Coding Agent Using Codex SDK and Daytona\ndescription: Step-by-step guide to building an autonomous coding agent using OpenAI Codex and Daytona sandboxes.\n---\n\nimport { Image } from 'astro:assets'\n\nimport codexSdkLunarLanderResult from '../../../../../assets/docs/images/codex-sdk-lunar-lander-result.gif'\n\nThis guide demonstrates how to run an autonomous coding agent based on [OpenAI Codex](https://chatgpt.com/features/codex) inside a Daytona sandbox environment. The agent can develop full-stack web apps, write code in any language, install dependencies, and run scripts. It can also start and manage dev servers, and generate preview links for live apps.\n\n---\n\n### 1. Workflow Overview\n\nWhen you launch the main module, a Daytona sandbox is created and a Node.js agent is initialized inside it. The agent is based on the [Codex SDK](https://developers.openai.com/codex/sdk/).\n\nYou interact with the main program via a command line chat interface. The program sends your prompts to the agent inside the sandbox, which executes them and returns the results:\n\n```\n$ npm run start\nCreating sandbox...\nInstalling Codex agent in sandbox...\nPress Ctrl+C at any time to exit.\nUser: create a 3d animated web-based, lunar lander game\nThinking...\n🔨 ✓ Run: /bin/sh -lc ls\n🔨 ✓ Run: /bin/sh -lc 'ls -a'\n🔨 ✓ Run: /bin/sh -lc 'ls .daytona'\n🔨 ✓ Run: /bin/sh -lc 'find /home/daytona -maxdepth 4 -name .git'\n📝 Add /home/daytona/index.html\n📝 Add /home/daytona/style.css\n📝 Add /home/daytona/main.js\n📝 Update /home/daytona/main.js\n- Built a self-contained 3D lunar lander experience with HUD in index.html wired to main.js.\n- Styled a glassy mission card, typography, and neon accents in style.css.\n- Implemented the Three.js scene in main.js: starfield + noisy terrain with a flattened pad, modeled lander, thrust/fuel/rotation controls, gravity/drag physics, landing/crash checks, exhaust particles, and a chase camera. Controls: Space/↑ thrust, ←/→ yaw, W/S pitch, R restart.\n\nNext steps:\n1) Serve locally (e.g., cd /home/daytona && python3 -m http.server 8080) and open https://8080-e7c5deb5-7723-4bb8-93c6-25258d9b7c53.proxy.daytona.works.\n2) Tune physics constants or terrain size if you want a harder/easier landing.\n🗒️ To-do list:\n- [x] Inspect workspace and set up project structure for web-based lunar lander game\n- [x] Implement 3D scene, lunar lander controls, physics, and game loop\n- [x] Add UI elements, polish, and quick sanity check (open file if feasible)\nUsage Summary: Cached: 71936, Input: 103238, Output: 11311\nUser: start the server\nThinking...\n🔨 ✓ Run: /bin/sh -lc 'cd /home/daytona && nohup python3 -m http.server 8080 --bind 0.0.0.0 >/home/daytona/server.log 2>&1 & echo $!'\nServer started on port 8080 (pid 274). Open the game at:\nhttps://8080-e7c5deb5-7723-4bb8-93c6-25258d9b7c53.proxy.daytona.works\n\nIf you need to stop it later: kill 274.\nUsage Summary: Cached: 4096, Input: 22231, Output: 272\nUser:\nCleaning up...\n```\n\nThe agent can also host web apps and provide you with a preview link using the [Daytona Preview Links](https://www.daytona.io/docs/en/preview-and-authentication/) feature. When your task involves running or previewing a web application, the agent automatically reasons about this need, hosts the app, and generates a preview link for you to inspect the live result:\n\n<Image\n  src={codexSdkLunarLanderResult}\n  alt=\"Lunar lander game demo generated by Codex coding agent\"\n  width={600}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\nYou can continue interacting with your agent until you are finished. When you exit the program, the sandbox will be deleted automatically.\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nFirst, clone the daytona [repository](https://github.com/daytonaio/daytona.git) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/typescript/openai/codex-sdk\n```\n\n#### Configure Environment\n\nGet your API keys:\n\n- **Daytona API key:** [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- **OpenAI API key:** [OpenAI Developer Platform](https://platform.openai.com/api-keys)\n\nCopy `.env.example` to `.env` and add your keys:\n\n```bash\nDAYTONA_API_KEY=your_daytona_key\nSANDBOX_OPENAI_API_KEY=your_openai_key\n```\n\n:::caution[API Key Security]\nNote: The `SANDBOX_OPENAI_API_KEY` key is passed into the Daytona sandbox environment and is accessible to any code executed inside the sandbox.\n:::\n\n#### Local Usage\n\n:::note[Node.js Version]\nNode.js 18 or newer is required to run this example. Please ensure your environment meets this requirement before proceeding.\n:::\n\nInstall dependencies:\n\n```bash\nnpm install\n```\n\nRun the agent:\n\n```bash\nnpm run start\n```\n\nThe agent will start and wait for your prompt.\n\n### 3. Understanding the Agent's Architecture\n\nThis example consists of two main components:\n\n- **Main Program:** The main program is a Node.js script (`src/index.ts`) that runs on your local machine. It uses the Daytona SDK to create and manage a Daytona sandbox. The main program provides a command line interface for interacting with the agent inside the sandbox.\n- **Sandbox Agent:** The sandbox agent is a Node.js script (`agent/index.ts`) that runs inside the Daytona sandbox. It uses the Codex SDK to create a customized coding agent.\n\n#### Initialization\n\nOn initialization, the main program:\n1. Creates a new [Daytona sandbox](/docs/en/sandboxes) with your OpenAI API key included in the environment variables.\n2. Configures the Codex system prompt with Daytona-specific instructions and writes it to a `.codex/config.toml` file in the sandbox.\n3. Uploads the agent package to the sandbox with [file uploading](/docs/file-system-operations#uploading-a-single-file).\n4. Installs the agent dependencies by running `npm install` in the uploaded agent directory.\n5. Waits for user input and runs the agent asynchronously for each prompt.\n\n#### Main Program Code\n\nCustom system prompts for Codex must be configured via a `.codex/config.toml` file, so the main program creates this file in the sandbox before starting the agent:\n\n```typescript\nconst systemPrompt = [\n  'You are running in a Daytona sandbox.',\n  'Use the /home/daytona directory instead of /workspace for file operations.',\n  `When running services on localhost, they will be accessible as: ${previewUrlPattern}`,\n].join(' ')\nconst config = `developer_instructions = \"${systemPrompt}\"`\nawait sandbox.fs.createFolder('.codex', '755')\nawait sandbox.fs.uploadFile(Buffer.from(config, 'utf8'), '.codex/config.toml')\n```\n\nThis prompt instructs the agent to use the correct file paths and preview link format for Daytona sandboxes.\n\nAfter installing dependencies, the main program enters a loop to read user input and send it to the agent. For each user prompt it receives, it creates a new Daytona process session to run the agent command asynchronously and stream back the output:\n\n```typescript\n// Create a session to stream the agent output\nconst sessionId = `codex-session-${Date.now()}`\nawait sandbox.process.createSession(sessionId)\n\n// Run the agent asynchronously, passing the prompt and OpenAI API key\nconst command = await sandbox.process.executeSessionCommand(sessionId, {\n  command: `${environmentPrefix({ PROMPT: prompt })} npm exec --prefix /tmp/agent tsx -- /tmp/agent/index.ts`,\n  runAsync: true,\n})\n\n// Stream agent output as it arrives\nif (!command.cmdId) throw new Error('Failed to start agent command in sandbox')\nawait sandbox.process.getSessionCommandLogs(\n  sessionId,\n  command.cmdId,\n  onStdout,\n  onStderr,\n)\n\n// Delete the session\nawait sandbox.process.deleteSession(sessionId)\n```\n\nThe `onStdout` and `onStderr` callbacks are used to pass the agent's output back to the main program. After the agent finishes responding to the prompt, the main program waits for the next user input.\n\n\n#### Sandbox Agent Code\n\nThe sandbox agent uses the [Codex SDK](https://developers.openai.com/codex/sdk/) to create a customized coding agent.\nThe agent is initialized with custom options that include the workspace directory:\n\n```typescript\n// Configure Codex options\nconst options: ThreadOptions = {\n  workingDirectory: '/home/daytona',\n  skipGitRepoCheck: true,\n  sandboxMode: 'danger-full-access',\n}\n```\n\nThe agent maintains thread state between requests by writing the thread ID to a file, allowing it to maintain context across multiple interactions:\n\n```typescript\nconst threadIdPath = '/tmp/codex-thread-id'\nconst threadId = (await readFileIfExisting(threadIdPath))?.trim()\nconst thread: Thread = threadId \n  ? codex.resumeThread(threadId, options) \n  : codex.startThread(options)\n```\n\nAdditional code to stream agent responses follows the examples in OpenAI's [Codex SDK documentation](https://github.com/openai/codex/blob/main/sdk/typescript/README.md).\n\n#### Clean up\n\nWhen you exit the main program, the Daytona sandbox and all files are automatically deleted.\n\n**Key advantages:**\n\n- Secure, isolated execution in Daytona sandboxes\n- Communicate with the agent directly in your terminal\n- Automatic dev server detection and live preview links\n- Multi-language and full-stack support\n- Thread persistence across multiple requests\n- Simple setup and automatic cleanup\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/data-analysis-with-ai.mdx",
    "content": "---\ntitle: Analyze Data with AI\ndescription: Use Daytona to run AI-generated code for data analysis and visualization.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport { Image } from 'astro:assets'\n\nimport chartImage from '../../../../assets/docs/images/chart-0.png'\n\nYou can use Daytona Sandbox to run AI-generated code to analyze data. Here's how the AI data analysis workflow typically looks:\n\n1. Your user has a dataset in CSV format or other formats.\n2. You prompt the LLM to generate code (usually Python) based on the user's data.\n3. The sandbox runs the AI-generated code and returns the results.\n4. The LLM receives feedback from the execution and can iterate multiple times to refine the code if needed.\n5. You display the final results to the user.\n\n---\n\n## Build an AI Data Analyst with Daytona\n\nThis example shows how to build an AI-powered data analyst that automatically generates insights and visualizations from CSV data using Daytona's secure sandbox environment.\n\n**What we'll build:** A system that analyzes a vehicle valuation dataset, identifies price relation to manufacturing year, and generates professional visualizations - all through natural language prompts to Claude. The system uses an agentic loop that allows Claude to iteratively refine the code based on execution results.\n\n### 1. Project Setup\n\n#### 1.1 Install Dependencies\n\nInstall the Daytona SDK and Anthropic SDK to your project:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    `bash pip install daytona anthropic python-dotenv `\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    `bash npm install @daytonaio/sdk @anthropic-ai/sdk dotenv `\n  </TabItem>\n\n  <TabItem label=\"Ruby\" icon=\"seti:ruby\">\n    `bash gem install daytona anthropic dotenv `\n  </TabItem>\n</Tabs>\n\n#### 1.2 Configure Environment\n\nGet your API keys and configure your environment:\n\n1. **Daytona API key:** Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n2. **Anthropic API key:** Get it from [Anthropic Console](https://console.anthropic.com/)\n\nCreate a `.env` file in your project:\n\n```bash\nDAYTONA_API_KEY=dtn_***\nANTHROPIC_API_KEY=sk-ant-***\n```\n\n### 2. Dataset Preparation\n\n#### 2.1 Download Dataset\n\nWe'll be using a publicly available dataset of vehicle valuation. You can download it directly from:\n\n[https://download.daytona.io/dataset.csv](https://download.daytona.io/dataset.csv)\n\nDownload the file and save it as `dataset.csv` in your project directory.\n\n#### 2.2 Initialize Sandbox\n\nNow create a [Daytona sandbox](/docs/en/sandboxes/#basic-sandbox-creation) and upload your dataset:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from dotenv import load_dotenv\n    from daytona import Daytona\n    import os\n\n    load_dotenv()\n\n    # Create sandbox\n\n    daytona = Daytona() # The sandbox language is Python by default.\n    sandbox = daytona.create()\n\n    # Upload the dataset to the sandbox\n\n    sandbox.fs.upload_file(\"dataset.csv\", \"/home/daytona/dataset.csv\")\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import 'dotenv/config'\n    import { Daytona } from '@daytonaio/sdk';\n\n    // Create sandbox\n    const daytona = new Daytona(); // The sandbox language is Python by default.\n    const sandbox = await daytona.create()\n\n    // Upload the dataset to the sandbox\n    await sandbox.fs.uploadFile('dataset.csv', '/home/daytona/dataset.csv')\n    ```\n  </TabItem>\n\n  <TabItem label=\"Ruby\" icon=\"seti:ruby\">\n    ```ruby\n    require 'daytona'\n    require 'dotenv/load'\n\n    # Create sandbox\n    daytona = Daytona::Daytona.new # The sandbox language is Python by default.\n    sandbox = daytona.create\n\n    # Upload the dataset to the sandbox\n    sandbox.fs.upload_file(File.read('dataset.csv'), '/home/daytona/dataset.csv')\n    ```\n  </TabItem>\n</Tabs>\n\n### 3. Building the AI Data Analyst\n\nNow we'll create the core functionality that connects Claude with Daytona to analyze data and generate visualizations.\n\n#### 3.1 Code Execution Handler\n\nFirst, let's create a function to handle code execution and chart extraction. This function returns execution results that can be fed back to the AI model:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import base64\n    from typing import TypedDict\n\n    class ExecutionResult(TypedDict):\n        stdout: str\n        exit_code: int\n        charts: list\n\n    def run_ai_generated_code(sandbox, ai_generated_code: str) -> ExecutionResult:\n        execution = sandbox.process.code_run(ai_generated_code)\n\n        result = ExecutionResult(\n            stdout=execution.result or \"\",\n            exit_code=execution.exit_code,\n            charts=execution.artifacts.charts if execution.artifacts else []\n        )\n\n        # Save any charts that were generated\n        if execution.artifacts and execution.artifacts.charts:\n            result_idx = 0\n            for chart in execution.artifacts.charts:\n                if chart.png:\n                    filename = f'chart-{result_idx}.png'\n                    with open(filename, 'wb') as f:\n                        f.write(base64.b64decode(chart.png))\n                    print(f'✓ Chart saved to {filename}')\n                    result_idx += 1\n\n        return result\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import fs from 'fs'\n    import { Sandbox } from '@daytonaio/sdk'\n\n    interface ExecutionResult {\n      stdout: string\n      exitCode: number\n      charts?: Array<{ png?: string }>\n    }\n\n    async function runAIGeneratedCode(\n      sandbox: Sandbox,\n      aiGeneratedCode: string\n    ): Promise<ExecutionResult> {\n      const execution = await sandbox.process.codeRun(aiGeneratedCode)\n\n      const result: ExecutionResult = {\n        stdout: execution.result || \"\",\n        exitCode: execution.exitCode,\n        charts: execution.artifacts?.charts\n      }\n\n      // Save any charts that were generated\n      if (execution.artifacts?.charts) {\n        let resultIdx = 0\n        for (const chart of execution.artifacts.charts) {\n          if (chart.png) {\n            const filename = `chart-${resultIdx}.png`\n            fs.writeFileSync(filename, chart.png, { encoding: 'base64' })\n            console.log(`✓ Chart saved to ${filename}`)\n            resultIdx++\n          }\n        }\n      }\n\n      return result\n    }\n    ```\n  </TabItem>\n</Tabs>\n\n#### 3.2 Creating the Analysis Prompt\n\nNext, we'll create the prompt that tells Claude about our dataset and what analysis we want. This prompt includes:\n\n- Dataset schema and column descriptions\n- The specific analysis request (vehicle price variation by manufacturing year)\n- Instructions for code generation\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from anthropic import Anthropic\n\n    prompt = f\"\"\"\n    I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.\n\n    Relevant columns:\n    - 'year': integer, the manufacturing year of the vehicle\n    - 'price_in_euro': float, the listed price of the vehicle in Euros\n\n    Analyze how price varies by manufacturing year.\n    Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.\n    Create a line chart showing average price per year.\n    Write Python code that analyzes the dataset based on my request and produces a matplotlib chart accordingly.\n    Always finish with plt.show() to display the chart.\"\"\"\n\n    anthropic = Anthropic()\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import Anthropic from '@anthropic-ai/sdk'\n\n    const prompt = `\n    I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.\n\n    Relevant columns:\n    - 'year': integer, the manufacturing year of the vehicle\n    - 'price_in_euro': float, the listed price of the vehicle in Euros\n\n    Analyze how price varies by manufacturing year.\n    Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.\n    Create a line chart showing average price per year.\n    Write Python code that analyzes the dataset based on my request and produces a matplotlib chart accordingly.\n    Always finish with plt.show() to display the chart.`\n\n    const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })\n    ```\n  </TabItem>\n</Tabs>\n\n#### 3.3 Tool Definition\n\nDefine the tool that allows Claude to execute Python code in the sandbox:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    tools = [\n        {\n            'name': 'run_python_code',\n            'description': 'Run Python code in the sandbox environment and get execution results',\n            'input_schema': {\n                'type': 'object',\n                'properties': {\n                    'code': {\n                        'type': 'string',\n                        'description': 'The Python code to run',\n                    },\n                },\n                'required': ['code'],\n            },\n        },\n    ]\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import type { Tool, ToolUseBlock } from '@anthropic-ai/sdk/resources/messages.mjs'\n\n    const tools: Tool[] = [\n      {\n        name: 'run_python_code',\n        description: 'Run Python code in the sandbox environment and get execution results',\n        input_schema: {\n          type: 'object',\n          properties: {\n            code: {\n              type: 'string',\n              description: 'The Python code to run',\n            },\n          },\n          required: ['code'],\n        },\n      },\n    ]\n    ```\n  </TabItem>\n</Tabs>\n\n#### 3.4 Agentic Loop Implementation\n\nNow we'll implement the agentic loop that allows Claude to iteratively refine the code based on execution feedback. This enables Claude to fix errors, handle edge cases, and improve the analysis through multiple iterations:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # Initialize conversation history\n    messages = [{'role': 'user', 'content': prompt}]\n\n    continue_loop = True\n    iteration_count = 0\n    max_iterations = 10\n\n    print(\"Starting agentic loop...\\n\")\n\n    while continue_loop and iteration_count < max_iterations:\n        iteration_count += 1\n        print(f\"\\n=== Iteration {iteration_count} ===\")\n        print(\"Waiting for the model response...\")\n\n        # Get response from Claude\n        msg = anthropic.messages.create(\n            model='claude-sonnet-4-5',\n            max_tokens=64000,\n            messages=messages,\n            tools=tools\n        )\n\n        # Log Claude's text response\n        for content_block in msg.content:\n            if content_block.type == 'text':\n                print(\"\\nClaude's response:\")\n                print(content_block.text)\n\n        # Check if Claude wants to use any tools\n        tool_uses = [block for block in msg.content if block.type == 'tool_use']\n\n        if len(tool_uses) == 0:\n            # No more tool uses, Claude is done\n            print(\"\\nTask completed - no more actions needed.\")\n            continue_loop = False\n            break\n\n        # Add Claude's response to message history\n        messages.append({'role': 'assistant', 'content': msg.content})\n\n        # Execute all tool calls and collect results\n        tool_results = []\n\n        for tool_use in tool_uses:\n            if tool_use.name == 'run_python_code':\n                code = tool_use.input['code']\n                print(\"\\n--- Executing Python code in sandbox ---\")\n                print(code)\n                print(\"--- End of code ---\\n\")\n\n                # Execute the code in the sandbox\n                execution_result = run_ai_generated_code(sandbox, code)\n\n                # Format the tool result\n                result_content = \"\"\n                if execution_result['exit_code'] == 0:\n                    result_content += \"Execution successful!\\n\\n\"\n                    if execution_result['stdout']:\n                        result_content += f\"Output:\\n{execution_result['stdout']}\\n\"\n                    if execution_result['charts'] and len(execution_result['charts']) > 0:\n                        result_content += f\"\\nGenerated {len(execution_result['charts'])} chart(s).\"\n                    else:\n                        result_content += \"\\nNote: No charts were generated. Make sure to use plt.show() to display the chart.\"\n                else:\n                    result_content += f\"Execution failed with exit code {execution_result['exit_code']}\\n\\n\"\n                    if execution_result['stdout']:\n                        result_content += f\"Output:\\n{execution_result['stdout']}\\n\"\n\n                tool_results.append({\n                    'type': 'tool_result',\n                    'tool_use_id': tool_use.id,\n                    'content': result_content\n                })\n\n                print(\"Execution result sent back to Claude.\")\n\n        # Add tool results to conversation history\n        messages.append({'role': 'user', 'content': tool_results})\n\n    if iteration_count >= max_iterations:\n        print(\"\\n⚠️  Reached maximum iteration limit. Task may not be complete.\")\n\n    print(\"\\n=== Agentic loop completed ===\")\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import type { MessageParam } from '@anthropic-ai/sdk/resources/messages.mjs'\n\n    interface CodeRunToolInput {\n      code: string\n    }\n\n    // Initialize conversation history\n    const messages: MessageParam[] = [\n      { role: 'user', content: initialPrompt }\n    ]\n\n    let continueLoop = true\n    let iterationCount = 0\n    const maxIterations = 10\n\n    console.log(\"Starting agentic loop...\\n\")\n\n    while (continueLoop && iterationCount < maxIterations) {\n      iterationCount++\n      console.log(`\\n=== Iteration ${iterationCount} ===`)\n      console.log(\"Waiting for the model response...\")\n\n      // Get response from Claude\n      const stream = anthropic.messages.stream({\n        model: 'claude-sonnet-4-5',\n        max_tokens: 64000,\n        messages: messages,\n        tools: tools\n      })\n\n      const message = await stream.finalMessage()\n\n      // Log Claude's text response\n      for (const contentBlock of message.content) {\n        if (contentBlock.type === 'text') {\n          console.log(\"\\nClaude's response:\")\n          console.log(contentBlock.text)\n        }\n      }\n\n      // Check if Claude wants to use any tools\n      const toolUses = message.content.filter(\n        (block): block is ToolUseBlock => block.type === 'tool_use'\n      )\n\n      if (toolUses.length === 0) {\n        // No more tool uses, Claude is done\n        console.log(\"\\nTask completed - no more actions needed.\")\n        continueLoop = false\n        break\n      }\n\n      // Add Claude's response to message history\n      messages.push({\n        role: 'assistant',\n        content: message.content\n      })\n\n      // Execute all tool calls and collect results\n      const toolResults = []\n\n      for (const toolUse of toolUses) {\n        if (toolUse.name === 'run_python_code') {\n          const code = (toolUse.input as CodeRunToolInput).code\n          console.log(\"\\n--- Executing Python code in sandbox ---\")\n          console.log(code)\n          console.log(\"--- End of code ---\\n\")\n\n          // Execute the code in the sandbox\n          const executionResult = await runAIGeneratedCode(sandbox, code)\n\n          // Format the tool result\n          let resultContent = \"\"\n          if (executionResult.exitCode === 0) {\n            resultContent += \"Execution successful!\\n\\n\"\n            if (executionResult.stdout) {\n              resultContent += `Output:\\n${executionResult.stdout}\\n`\n            }\n            if (executionResult.charts && executionResult.charts.length > 0) {\n              resultContent += `\\nGenerated ${executionResult.charts.length} chart(s).`\n            } else {\n              resultContent += \"\\nNote: No charts were generated. Make sure to use plt.show() to display the chart.\"\n            }\n          } else {\n            resultContent += `Execution failed with exit code ${executionResult.exitCode}\\n\\n`\n            if (executionResult.stdout) {\n              resultContent += `Output:\\n${executionResult.stdout}\\n`\n            }\n          }\n\n          toolResults.push({\n            type: 'tool_result' as const,\n            tool_use_id: toolUse.id,\n            content: resultContent\n          })\n\n          console.log(\"Execution result sent back to Claude.\")\n        }\n      }\n\n      // Add tool results to conversation history\n      messages.push({\n        role: 'user',\n        content: toolResults\n      })\n    }\n\n    if (iterationCount >= maxIterations) {\n      console.log(\"\\n⚠️  Reached maximum iteration limit. Task may not be complete.\")\n    }\n\n    console.log(\"\\n=== Agentic loop completed ===\")\n    ```\n  </TabItem>\n</Tabs>\n\nThe agentic loop works as follows:\n\n1. **Initial Request**: Send the initial prompt to Claude with the tool definition\n2. **Iteration Loop**: For each iteration (up to 10 times):\n   - Claude generates a response with optional tool calls\n   - If there are tool calls, execute the Python code in the sandbox\n   - Send execution results back to Claude (including errors or success messages)\n   - Claude can then refine the code based on the feedback\n3. **Completion**: Loop ends when Claude signals no more tool calls are needed or max iterations reached\n\nThis approach allows Claude to:\n- Fix errors if the initial code fails\n- Iterate on the analysis if results aren't satisfactory\n- Handle edge cases discovered during execution\n- Improve visualizations based on the actual data\n\n**Key advantages of this approach:**\n\n- **Secure execution:** Code runs in isolated Daytona sandboxes\n- **Automatic artifact capture:** Charts, tables, and outputs are automatically extracted\n- **Error handling:** Built-in error detection and logging\n- **Language agnostic:** While we used Python here, Daytona supports multiple languages\n\n### 4. Running Your Analysis\n\nNow you can run the complete code to see the results.\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    python data-analysis.py\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```bash\n    npx tsx data-analysis.ts\n    ```\n  </TabItem>\n</Tabs>\n\nYou should see the chart in your project directory that will look similar to this:\n\n<Image src={chartImage} alt=\"Vehicle valuation by manufacturing year chart\" width={600} style=\"max-width: 100%; height: auto; margin: 1rem 0;\" />\n\n### 5. Complete Implementation\n\nHere are the complete, ready-to-run examples with the agentic loop:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import base64\n    from dotenv import load_dotenv\n    from daytona import Daytona, Sandbox\n    from anthropic import Anthropic\n    from typing import TypedDict\n\n\n    class ExecutionResult(TypedDict):\n        stdout: str\n        exit_code: int\n        charts: list\n\n\n    def main():\n        load_dotenv()\n\n        # Create sandbox\n        daytona = Daytona()\n        sandbox = daytona.create()\n\n        # Upload the dataset to the sandbox\n        sandbox.fs.upload_file(\"dataset.csv\", \"/home/daytona/dataset.csv\")\n\n        initial_prompt = \"\"\"\n    I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.\n\n    Relevant columns:\n    - 'year': integer, the manufacturing year of the vehicle\n    - 'price_in_euro': float, the listed price of the vehicle in Euros\n\n    Analyze how price varies by manufacturing year.\n    Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.\n    Create a line chart showing average price per year.\n    Write Python code that analyzes the dataset based on my request and produces a matplotlib chart accordingly.\n    Always finish with plt.show() to display the chart.\"\"\"\n\n        anthropic = Anthropic()\n\n        tools = [\n            {\n                'name': 'run_python_code',\n                'description': 'Run Python code in the sandbox environment and get execution results',\n                'input_schema': {\n                    'type': 'object',\n                    'properties': {\n                        'code': {\n                            'type': 'string',\n                            'description': 'The Python code to run',\n                        },\n                    },\n                    'required': ['code'],\n                },\n            },\n        ]\n\n        # Initialize conversation history\n        messages = [{'role': 'user', 'content': initial_prompt}]\n\n        continue_loop = True\n        iteration_count = 0\n        max_iterations = 10\n\n        print(\"Starting agentic loop...\\n\")\n\n        while continue_loop and iteration_count < max_iterations:\n            iteration_count += 1\n            print(f\"\\n=== Iteration {iteration_count} ===\")\n            print(\"Waiting for the model response...\")\n\n            # Get response from Claude\n            msg = anthropic.messages.create(\n                model='claude-sonnet-4-5',\n                max_tokens=64000,\n                messages=messages,\n                tools=tools\n            )\n\n            # Log Claude's text response\n            for content_block in msg.content:\n                if content_block.type == 'text':\n                    print(\"\\nClaude's response:\")\n                    print(content_block.text)\n\n            # Check if Claude wants to use any tools\n            tool_uses = [block for block in msg.content if block.type == 'tool_use']\n\n            if len(tool_uses) == 0:\n                # No more tool uses, Claude is done\n                print(\"\\nTask completed - no more actions needed.\")\n                continue_loop = False\n                break\n\n            # Add Claude's response to message history\n            messages.append({'role': 'assistant', 'content': msg.content})\n\n            # Execute all tool calls and collect results\n            tool_results = []\n\n            for tool_use in tool_uses:\n                if tool_use.name == 'run_python_code':\n                    code = tool_use.input['code']\n                    print(\"\\n--- Executing Python code in sandbox ---\")\n                    print(code)\n                    print(\"--- End of code ---\\n\")\n\n                    # Execute the code in the sandbox\n                    execution_result = run_ai_generated_code(sandbox, code)\n\n                    # Format the tool result\n                    result_content = \"\"\n                    if execution_result['exit_code'] == 0:\n                        result_content += \"Execution successful!\\n\\n\"\n                        if execution_result['stdout']:\n                            result_content += f\"Output:\\n{execution_result['stdout']}\\n\"\n                        if execution_result['charts'] and len(execution_result['charts']) > 0:\n                            result_content += f\"\\nGenerated {len(execution_result['charts'])} chart(s).\"\n                        else:\n                            result_content += \"\\nNote: No charts were generated. Make sure to use plt.show() to display the chart.\"\n                    else:\n                        result_content += f\"Execution failed with exit code {execution_result['exit_code']}\\n\\n\"\n                        if execution_result['stdout']:\n                            result_content += f\"Output:\\n{execution_result['stdout']}\\n\"\n\n                    tool_results.append({\n                        'type': 'tool_result',\n                        'tool_use_id': tool_use.id,\n                        'content': result_content\n                    })\n\n                    print(\"Execution result sent back to Claude.\")\n\n            # Add tool results to conversation history\n            messages.append({'role': 'user', 'content': tool_results})\n\n        if iteration_count >= max_iterations:\n            print(\"\\n⚠️  Reached maximum iteration limit. Task may not be complete.\")\n\n        print(\"\\n=== Agentic loop completed ===\")\n\n\n    def run_ai_generated_code(sandbox: Sandbox, ai_generated_code: str) -> ExecutionResult:\n        execution = sandbox.process.code_run(ai_generated_code)\n\n        result = ExecutionResult(\n            stdout=execution.result or \"\",\n            exit_code=execution.exit_code,\n            charts=execution.artifacts.charts if execution.artifacts else []\n        )\n\n        # Save any charts that were generated\n        if execution.artifacts and execution.artifacts.charts:\n            result_idx = 0\n            for chart in execution.artifacts.charts:\n                if chart.png:\n                    filename = f'chart-{result_idx}.png'\n                    with open(filename, 'wb') as f:\n                        f.write(base64.b64decode(chart.png))\n                    print(f'✓ Chart saved to {filename}')\n                    result_idx += 1\n\n        return result\n\n\n    if __name__ == \"__main__\":\n        main()\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import \"dotenv/config\";\n    import fs from \"fs\";\n    import Anthropic from \"@anthropic-ai/sdk\";\n    import { Daytona, Sandbox } from \"@daytonaio/sdk\";\n    import type {\n      MessageParam,\n      Tool,\n      ToolUseBlock,\n    } from \"@anthropic-ai/sdk/resources/messages.mjs\";\n\n    interface CodeRunToolInput {\n      code: string;\n    }\n\n    interface ExecutionResult {\n      stdout: string;\n      exitCode: number;\n      charts?: Array<{ png?: string }>;\n    }\n\n    async function main() {\n      // Create sandbox\n      const daytona = new Daytona();\n      const sandbox = await daytona.create();\n\n      // Upload the dataset to the sandbox\n      await sandbox.fs.uploadFile(\"dataset.csv\", \"/home/daytona/dataset.csv\");\n\n      const initialPrompt = `\n    I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.\n\n    Relevant columns:\n    - 'year': integer, the manufacturing year of the vehicle\n    - 'price_in_euro': float, the listed price of the vehicle in Euros\n\n    Analyze how price varies by manufacturing year.\n    Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.\n    Create a line chart showing average price per year.\n    Write Python code that analyzes the dataset based on my request and produces a matplotlib chart accordingly.\n    Always finish with plt.show() to display the chart.`;\n\n      const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });\n\n      const tools: Tool[] = [\n        {\n          name: \"run_python_code\",\n          description: \"Run Python code in the sandbox environment and get execution results\",\n          input_schema: {\n            type: \"object\",\n            properties: {\n              code: {\n                type: \"string\",\n                description: \"The Python code to run\",\n              },\n            },\n            required: [\"code\"],\n          },\n        },\n      ];\n\n      // Initialize conversation history\n      const messages: MessageParam[] = [\n        { role: \"user\", content: initialPrompt },\n      ];\n\n      let continueLoop = true;\n      let iterationCount = 0;\n      const maxIterations = 10;\n\n      console.log(\"Starting agentic loop...\\n\");\n\n      while (continueLoop && iterationCount < maxIterations) {\n        iterationCount++;\n        console.log(`\\n=== Iteration ${iterationCount} ===`);\n        console.log(\"Waiting for the model response...\");\n\n        // Get response from Claude\n        const stream = anthropic.messages.stream({\n          model: \"claude-sonnet-4-5\",\n          max_tokens: 64000,\n          messages: messages,\n          tools: tools,\n        });\n\n        const message = await stream.finalMessage();\n\n        // Log Claude's text response\n        for (const contentBlock of message.content) {\n          if (contentBlock.type === \"text\") {\n            console.log(\"\\nClaude's response:\");\n            console.log(contentBlock.text);\n          }\n        }\n\n        // Check if Claude wants to use any tools\n        const toolUses = message.content.filter(\n          (block): block is ToolUseBlock => block.type === \"tool_use\"\n        );\n\n        if (toolUses.length === 0) {\n          // No more tool uses, Claude is done\n          console.log(\"\\nTask completed - no more actions needed.\");\n          continueLoop = false;\n          break;\n        }\n\n        // Add Claude's response to message history\n        messages.push({\n          role: \"assistant\",\n          content: message.content,\n        });\n\n        // Execute all tool calls and collect results\n        const toolResults = [];\n\n        for (const toolUse of toolUses) {\n          if (toolUse.name === \"run_python_code\") {\n            const code = (toolUse.input as CodeRunToolInput).code;\n            console.log(\"\\n--- Executing Python code in sandbox ---\");\n            console.log(code);\n            console.log(\"--- End of code ---\\n\");\n\n            // Execute the code in the sandbox\n            const executionResult = await runAIGeneratedCode(sandbox, code);\n\n            // Format the tool result\n            let resultContent = \"\";\n            if (executionResult.exitCode === 0) {\n              resultContent += `Execution successful!\\n\\n`;\n              if (executionResult.stdout) {\n                resultContent += `Output:\\n${executionResult.stdout}\\n`;\n              }\n              if (executionResult.charts && executionResult.charts.length > 0) {\n                resultContent += `\\nGenerated ${executionResult.charts.length} chart(s).`;\n              } else {\n                resultContent += `\\nNote: No charts were generated. Make sure to use plt.show() to display the chart.`;\n              }\n            } else {\n              resultContent += `Execution failed with exit code ${executionResult.exitCode}\\n\\n`;\n              if (executionResult.stdout) {\n                resultContent += `Output:\\n${executionResult.stdout}\\n`;\n              }\n            }\n\n            toolResults.push({\n              type: \"tool_result\" as const,\n              tool_use_id: toolUse.id,\n              content: resultContent,\n            });\n\n            console.log(\"Execution result sent back to Claude.\");\n          }\n        }\n\n        // Add tool results to conversation history\n        messages.push({\n          role: \"user\",\n          content: toolResults,\n        });\n      }\n\n      if (iterationCount >= maxIterations) {\n        console.log(\n          \"\\n⚠️  Reached maximum iteration limit. Task may not be complete.\"\n        );\n      }\n\n      console.log(\"\\n=== Agentic loop completed ===\");\n    }\n\n    async function runAIGeneratedCode(\n      sandbox: Sandbox,\n      aiGeneratedCode: string\n    ): Promise<ExecutionResult> {\n      const execution = await sandbox.process.codeRun(aiGeneratedCode);\n\n      const result: ExecutionResult = {\n        stdout: execution.result || \"\",\n        exitCode: execution.exitCode,\n        charts: execution.artifacts?.charts,\n      };\n\n      // Save any charts that were generated\n      if (execution.artifacts?.charts) {\n        let resultIdx = 0;\n        for (const chart of execution.artifacts.charts) {\n          if (chart.png) {\n            const filename = `chart-${resultIdx}.png`;\n            fs.writeFileSync(filename, chart.png, {\n              encoding: \"base64\",\n            });\n            console.log(`✓ Chart saved to ${filename}`);\n            resultIdx++;\n          }\n        }\n      }\n\n      return result;\n    }\n\n    main().catch(console.error);\n    ```\n  </TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/google-adk-code-generator.mdx",
    "content": "---\ntitle: Generate Verified Code With Google ADK Agent\ndescription: Build Google ADK agents that generate and test code using Daytona's isolated sandbox environment.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nThis guide demonstrates how to use the `DaytonaPlugin` for Google ADK to build an agent that generates, tests, and verifies code in a secure sandbox environment. The plugin enables agents to execute Python, JavaScript, and TypeScript code, run shell commands, and manage files within isolated Daytona sandboxes.\n\nIn this example, we build a code generator agent that takes a natural language description of a function, generates the implementation in TypeScript, creates test cases, executes them in the sandbox, and iterates until all tests pass before returning the verified code.\n\n---\n\n### 1. Workflow Overview\n\nYou describe the function you want in plain English, specifying the language (Python, JavaScript, or TypeScript). The agent generates the implementation, writes tests for it, and executes everything in a Daytona sandbox. If tests fail, the agent automatically fixes the code and re-runs until all tests pass. Only then does it return the verified, working code.\n\nThe key benefit: you receive code that has already been tested and verified, not just generated.\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nClone the Daytona repository and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona\ncd daytona/guides/python/google-adk/code-generator-agent/gemini\n```\n\n#### Install Dependencies\n\n:::note[Python Version Requirement]\nThis example requires **Python 3.10 or higher**. It's recommended to use a virtual environment (e.g., `venv` or `poetry`) to isolate project dependencies.\n:::\n\nInstall the required packages for this example:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    pip install -U google-adk daytona-adk python-dotenv\n    ```\n\n    The packages include:\n    - `google-adk`: Google's Agent Development Kit for building AI agents\n    - `daytona-adk`: Provides the `DaytonaPlugin` that enables secure code execution in Daytona sandboxes\n    - `python-dotenv`: Used for loading environment variables from `.env` file\n  </TabItem>\n</Tabs>\n\n#### Configure Environment\n\nGet your API keys and configure your environment:\n\n1. **Daytona API key:** Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n2. **Google API key:** Get it from [Google AI Studio](https://aistudio.google.com/apikey)\n\nCreate a `.env` file in your project:\n\n```bash\nDAYTONA_API_KEY=dtn_***\nGOOGLE_API_KEY=***\n```\n\n### 3. Understanding the Core Components\n\nBefore diving into the implementation, let's understand the key components we'll use:\n\n#### Google ADK Components\n\n- **Agent**: The AI model wrapper that processes requests and decides which tools to use. It receives instructions, has access to tools, and generates responses.\n- **App**: A top-level container that bundles agents with plugins into a single configuration unit. It provides centralized management for shared resources and defines the root agent for your workflow.\n- **InMemoryRunner**: The execution engine that runs agents and manages conversation state. It orchestrates the event-driven execution loop, handles message processing, and manages services like session history and artifact storage.\n\n:::note[Running the Agent]\nThere are two ways to run Google ADK agents: using the `App` class with `InMemoryRunner`, or using `InMemoryRunner` directly with just an agent. The `App` serves as a configuration container that bundles agents with plugins, while the `Runner` handles actual execution and lifecycle management. This guide uses the `App` approach for cleaner organization of agents and plugins.\n:::\n\n#### Daytona Plugin\n\nThe `DaytonaPlugin` provides tools that allow the agent to:\n- Execute code in Python, JavaScript, or TypeScript\n- Run shell commands\n- Upload and read files\n- Start long-running background processes\n\nAll operations happen in an isolated sandbox that is automatically cleaned up when done.\n\n### 4. Initialize Environment and Imports\n\nFirst, we set up our imports and load environment variables:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import asyncio\n    import logging\n\n    from dotenv import load_dotenv\n    from google.adk.agents import Agent\n    from google.adk.apps import App\n    from google.adk.runners import InMemoryRunner\n\n    from daytona_adk import DaytonaPlugin\n\n    load_dotenv()\n\n    logging.basicConfig(level=logging.DEBUG)\n    ```\n\n    **What each import does:**\n    - `asyncio`: Required for running the async ADK runner\n    - `logging`: Enables debug output to see agent reasoning\n    - `load_dotenv`: Loads API keys from your `.env` file\n    - `Agent`, `App`, `InMemoryRunner`: Core Google ADK components\n    - `DaytonaPlugin`: Provides sandbox execution tools to the agent\n\n    **Logging configuration:**\n    The `logging.basicConfig(level=logging.DEBUG)` line configures Python's logging to show detailed debug output. You can adjust the logging level by passing different values:\n    - `logging.DEBUG`: Most verbose, shows all internal operations including DaytonaPlugin sandbox creation and tool invocations\n    - `logging.INFO`: Shows informational messages about agent progress\n    - `logging.WARNING`: Shows only warnings and errors\n    - `logging.ERROR`: Shows only errors\n\n    :::tip[Behind the Scenes]\n    With `DEBUG` level logging enabled, you can see the DaytonaPlugin's internal operations, including when the sandbox is created, when the `execute_code_in_daytona` tool is invoked, and when cleanup occurs. The plugin's `plugin_name` (configurable, defaults to `daytona_plugin`) appears in these log messages, making it easy to trace plugin activity.\n    :::\n  </TabItem>\n</Tabs>\n\n### 5. Define the Response Extractor\n\nThe ADK runner returns a list of events from the agent's execution. We need a helper function to extract the final text response:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def extract_final_response(response: list) -> str:\n        \"\"\"Extract the final text response from a list of ADK events.\"\"\"\n        for event in reversed(response):\n            text_parts = []\n\n            if hasattr(event, \"text\") and event.text:\n                return event.text\n            if hasattr(event, \"content\") and event.content:\n                content = event.content\n                if hasattr(content, \"parts\") and content.parts:\n                    for part in content.parts:\n                        if hasattr(part, \"text\") and part.text:\n                            text_parts.append(part.text)\n                    if text_parts:\n                        return \"\".join(text_parts)\n                if hasattr(content, \"text\") and content.text:\n                    return content.text\n            if isinstance(event, dict):\n                text = event.get(\"text\") or event.get(\"content\", {}).get(\"text\")\n                if text:\n                    return text\n\n        return \"\"\n    ```\n\n    This function iterates through events in reverse order to find the last text response. It handles multiple possible event structures that the ADK may return.\n  </TabItem>\n</Tabs>\n\n### 6. Define the Agent Instruction\n\nThe instruction is critical - it defines how the agent behaves. Our instruction enforces a test-driven workflow:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    AGENT_INSTRUCTION = \"\"\"You are a code generator agent that writes verified, working code.\n    You support Python, JavaScript, and TypeScript.\n\n    Your workflow for every code request:\n    1. Write the function\n    2. Write tests for it\n    3. EXECUTE the code in the sandbox to verify it works - do not skip this step\n    4. If execution fails, fix and re-execute until tests pass\n    5. Once verified, respond with ONLY the function (no tests)\n\n    You must always execute code before responding. Never return untested code.\n    Only include tests in your response if the user explicitly asks for them.\n    \"\"\"\n    ```\n\n    **Key aspects of this instruction:**\n    - **Enforces execution**: The agent must run code in the sandbox before responding\n    - **Iterative fixing**: If tests fail, the agent fixes and retries\n    - **Controlled output**: By default, the final response contains only the working function. If you want to see the tests, include an instruction to return them in your prompt.\n    - **Multi-language**: Supports Python, JavaScript, and TypeScript\n  </TabItem>\n</Tabs>\n\n### 7. Configure the Daytona Plugin\n\nInitialize the plugin that provides sandbox execution capabilities:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    plugin = DaytonaPlugin(\n        labels={\"example\": \"code-generator\"},\n    )\n    ```\n\n    **Configuration options:**\n    - `labels`: Custom metadata tags for the sandbox (useful for tracking/filtering)\n    - `api_key`: Daytona API key (defaults to `DAYTONA_API_KEY` env var)\n    - `sandbox_name`: Custom name for the sandbox\n    - `plugin_name`: Name displayed in logs when the plugin logs messages (defaults to `daytona_plugin`)\n    - `env_vars`: Environment variables to set in the sandbox\n    - `auto_stop_interval`: Minutes before auto-stop (default: 15)\n    - `auto_delete_interval`: Minutes before auto-delete (disabled by default)\n  </TabItem>\n</Tabs>\n\n### 8. Create the Agent\n\nCreate the agent with the Gemini model, our instruction, and the Daytona tools:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    agent = Agent(\n        model=\"gemini-2.5-pro\",\n        name=\"code_generator_agent\",\n        instruction=AGENT_INSTRUCTION,\n        tools=plugin.get_tools(),\n    )\n    ```\n\n    **Parameters explained:**\n    - `model`: The Gemini model to use for reasoning and code generation\n    - `name`: Identifier for the agent\n    - `instruction`: The behavioral guidelines we defined\n    - `tools`: List of tools from the Daytona plugin that the agent can use\n  </TabItem>\n</Tabs>\n\n### 9. Create the App and Runner\n\nBundle the agent and plugin into an App, then run it:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    app = App(\n        name=\"code_generator_app\",\n        root_agent=agent,\n        plugins=[plugin],\n    )\n\n    async with InMemoryRunner(app=app) as runner:\n        prompt = \"Write a TypeScript function called 'groupBy' that takes an array and a key function, and groups array elements by the key. Use proper type annotations.\"\n\n        response = await runner.run_debug(prompt)\n\n        final_response = extract_final_response(response)\n        print(final_response)\n    ```\n  </TabItem>\n</Tabs>\n\n**What happens here:**\n1. The `App` bundles the agent with the plugin for proper lifecycle management\n2. `InMemoryRunner` is used as an async context manager (the `async with` statement). A context manager in Python automatically handles setup and cleanup - when the code enters the `async with` block, the runner initializes; when it exits (either normally or due to an error), the runner cleans up resources.\n3. `run_debug` sends the prompt and returns all execution events\n4. The sandbox is automatically deleted when the `async with` block exits - this cleanup happens regardless of whether the code completed successfully or raised an exception\n\n### 10. Running the Example\n\nRun the complete example:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    python main.py\n    ```\n  </TabItem>\n</Tabs>\n\n#### Understanding the Agent's Execution Flow\n\nWhen you run the code, the agent works through your request step by step. With `logging.DEBUG` enabled, you'll see detailed output including:\n\n- **DaytonaPlugin operations**: Sandbox creation, tool invocations (`execute_code_in_daytona`), and cleanup\n- **LLM requests and responses**: The prompts sent to Gemini and the responses received\n- **Plugin registration**: Confirmation that the `daytona_plugin` was registered with the agent\n\nHere's what the debug output reveals about each step:\n\n**Step 1: Sandbox Creation**\n\n```\nDEBUG:daytona_adk.plugin:Daytona sandbox created: e38f8574-48ac-48f1-a0ff-d922d02b0fcb\nINFO:google_adk.google.adk.plugins.plugin_manager:Plugin 'daytona_plugin' registered.\n```\n\nThe DaytonaPlugin creates an isolated sandbox and registers itself with the agent.\n\n**Step 2: Agent receives the request**\n\nThe agent receives your prompt and understands it needs to create a TypeScript `groupBy` function with proper type annotations.\n\n**Step 3: Agent generates code and tests**\n\nThe agent writes both the implementation and test cases, then calls the `execute_code_in_daytona` tool:\n\n```\nDEBUG:google_adk.google.adk.models.google_llm:\nLLM Response:\n-----------------------------------------------------------\nFunction calls:\nname: execute_code_in_daytona, args: {'code': \"...\", 'language': 'typescript'}\n```\n\n**Step 4: Code execution in sandbox**\n\n```\nDEBUG:daytona_adk.plugin:Before tool: execute_code_in_daytona\nDEBUG:daytona_adk.tools:Executing typescript code (length: 1570 chars)\nDEBUG:daytona_adk.tools:Code execution completed with exit_code: 0\nDEBUG:daytona_adk.plugin:After tool: execute_code_in_daytona\n```\n\nThe plugin executes the code in the isolated TypeScript environment and returns the result.\n\n**Step 5: Agent iterates if needed**\n\nIf tests fail (exit_code != 0), the agent analyzes the error, fixes the code, and re-executes until all tests pass.\n\n**Step 6: Agent returns verified code**\n\nOnce tests pass, the agent responds with only the working function. If you included an instruction to return tests in your prompt, the tests will also be included in the response.\n\n**Step 7: Cleanup**\n\n```\nINFO:daytona_adk.plugin:Deleting Daytona sandbox...\nINFO:daytona_adk.plugin:Daytona sandbox deleted.\nINFO:google_adk.google.adk.runners:Runner closed.\n```\n\nWhen the context manager exits, the sandbox is automatically deleted.\n\n#### Example Output\n\nWhen the agent completes the task, you'll see output like:\n\n````\nAGENT RESPONSE:\n------------------------------------------------------------\n```typescript\nfunction groupBy<T, K extends keyof any>(\n  array: T[],\n  keyFn: (item: T) => K\n): Record<K, T[]> {\n  return array.reduce((result, item) => {\n    const key = keyFn(item);\n    if (!result[key]) {\n      result[key] = [];\n    }\n    result[key].push(item);\n    return result;\n  }, {} as Record<K, T[]>);\n}\n```\n============================================================\n\nApp closed, sandbox cleaned up. Done!\n````\n\nThe agent has already tested this code in the sandbox before returning it, so you can trust that the implementation works correctly.\n\n#### Requesting Tests in the Response\n\nIf you want to see the tests that were executed in the sandbox, include an instruction to return them in your prompt:\n\n```python\nprompt = \"Write a TypeScript function called 'groupBy' that takes an array and a key function, and groups array elements by the key. Use proper type annotations. Return the tests also in a separate code block\"\n```\n\nWith this prompt, the agent will return both the function and the tests:\n\n````\n```typescript\nfunction groupBy<T, K extends keyof any>(\n  array: T[],\n  keyFn: (item: T) => K\n): Record<K, T[]> {\n  return array.reduce((result, item) => {\n    const key = keyFn(item);\n    if (!result[key]) {\n      result[key] = [];\n    }\n    result[key].push(item);\n    return result;\n  }, {} as Record<K, T[]>);\n}\n```\n\n```typescript\nimport { deepStrictEqual } from 'assert';\n\n// Test case 1: Group by a property of an object\nconst array1 = [\n  { id: 1, category: 'A' },\n  { id: 2, category: 'B' },\n  { id: 3, category: 'A' },\n];\nconst result1 = groupBy(array1, (item) => item.category);\ndeepStrictEqual(result1, {\n  A: [\n    { id: 1, category: 'A' },\n    { id: 3, category: 'A' },\n  ],\n  B: [{ id: 2, category: 'B' }],\n});\n\n// Test case 2: Group by length of strings\nconst array2 = ['apple', 'banana', 'cherry', 'date'];\nconst result2 = groupBy(array2, (item) => item.length);\ndeepStrictEqual(result2, {\n  5: ['apple'],\n  6: ['banana', 'cherry'],\n  4: ['date'],\n});\n\nconsole.log('All tests passed!');\n```\n````\n\n### 11. Complete Implementation\n\nHere is the complete, ready-to-run example with additional output formatting for better readability:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    \"\"\"Code Generator & Tester Agent Example.\"\"\"\n\n    import asyncio\n    import logging\n\n    from dotenv import load_dotenv\n    from google.adk.agents import Agent\n    from google.adk.apps import App\n    from google.adk.runners import InMemoryRunner\n\n    from daytona_adk import DaytonaPlugin\n\n    load_dotenv()\n\n    logging.basicConfig(level=logging.DEBUG)\n\n\n    def extract_final_response(response: list) -> str:\n        \"\"\"Extract the final text response from a list of ADK events.\"\"\"\n        for event in reversed(response):\n            text_parts = []\n\n            if hasattr(event, \"text\") and event.text:\n                return event.text\n            if hasattr(event, \"content\") and event.content:\n                content = event.content\n                if hasattr(content, \"parts\") and content.parts:\n                    for part in content.parts:\n                        if hasattr(part, \"text\") and part.text:\n                            text_parts.append(part.text)\n                    if text_parts:\n                        return \"\".join(text_parts)\n                if hasattr(content, \"text\") and content.text:\n                    return content.text\n            if isinstance(event, dict):\n                text = event.get(\"text\") or event.get(\"content\", {}).get(\"text\")\n                if text:\n                    return text\n\n        return \"\"\n\n\n    AGENT_INSTRUCTION = \"\"\"You are a code generator agent that writes verified, working code.\n    You support Python, JavaScript, and TypeScript.\n\n    Your workflow for every code request:\n    1. Write the function\n    2. Write tests for it\n    3. EXECUTE the code in the sandbox to verify it works - do not skip this step\n    4. If execution fails, fix and re-execute until tests pass\n    5. Once verified, respond with ONLY the function (no tests)\n\n    You must always execute code before responding. Never return untested code.\n    Only include tests in your response if the user explicitly asks for them.\n    \"\"\"\n\n\n    async def main() -> None:\n        \"\"\"Run the code generator agent example.\"\"\"\n        plugin = DaytonaPlugin(\n            labels={\"example\": \"code-generator\"},\n        )\n\n        agent = Agent(\n            model=\"gemini-2.5-pro\",\n            name=\"code_generator_agent\",\n            instruction=AGENT_INSTRUCTION,\n            tools=plugin.get_tools(),\n        )\n\n        app = App(\n            name=\"code_generator_app\",\n            root_agent=agent,\n            plugins=[plugin],\n        )\n\n        async with InMemoryRunner(app=app) as runner:\n            prompt = \"Write a TypeScript function called 'groupBy' that takes an array and a key function, and groups array elements by the key. Use proper type annotations.\"\n\n            print(\"\\n\" + \"=\" * 60)\n            print(\"USER PROMPT:\")\n            print(\"=\" * 60)\n            print(prompt)\n            print(\"-\" * 60)\n\n            response = await runner.run_debug(prompt)\n\n            final_response = extract_final_response(response)\n            print(\"\\nAGENT RESPONSE:\")\n            print(\"-\" * 60)\n            print(final_response)\n            print(\"=\" * 60)\n\n        print(\"\\nApp closed, sandbox cleaned up. Done!\")\n\n\n    if __name__ == \"__main__\":\n        asyncio.run(main())\n    ```\n  </TabItem>\n</Tabs>\n\n**Key advantages of this approach:**\n\n- **Verified code:** Every response has been tested in a real execution environment\n- **Secure execution:** Code runs in isolated Daytona sandboxes, not on your machine\n- **Multi-language support:** Generate and test Python, JavaScript, or TypeScript\n- **Automatic iteration:** Agent fixes issues until tests pass\n- **Flexible output:** Returns only the working function by default, or includes tests if explicitly requested in the prompt\n\n### 12. API Reference\n\nFor the complete API reference of the Daytona ADK plugin, including all available tools and configuration options, see the [daytona-adk documentation](https://github.com/daytonaio/daytona-adk-plugin#available-tools).\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/index.mdx",
    "content": "---\ntitle: Guides\ndescription: Guides for using Daytona.\n---\n\nimport GuidesList from '@components/GuidesList.astro'\n\nDaytona provides a comprehensive set of guides to help you get started.\nThe guides cover a wide range of topics, from basic usage to advanced topics, and showcase various types of integrations between Daytona and other tools.\n\n<GuidesList />"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/langchain/langchain-data-analysis.mdx",
    "content": "---\ntitle: Analyze Data With LangChain AI Agent\ndescription: Build LangChain agents that perform secure data analysis using Daytona's isolated sandbox environment.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport { Image } from 'astro:assets'\n\nimport chartImage from '../../../../../assets/docs/images/langchain-data-analysis-chart.png'\n\nThis package provides the `DaytonaDataAnalysisTool` - LangChain tool integration that enables agents to perform secure Python data analysis in a sandboxed environment. It supports multi-step workflows, file uploads/downloads, and custom result handling, making it ideal for automating data analysis tasks with LangChain agents.\n\nThis page demonstrates the use of this tool with a basic example analyzing a vehicle valuations dataset. Our goal is to analyze how vehicle prices vary by manufacturing year and create a line chart showing average price per year.\n\n---\n\n### 1. Workflow Overview\n\nYou upload your dataset and provide a natural language prompt describing the analysis you want. The agent reasons about your request, determines how to use the `DaytonaDataAnalysisTool` to perform the task on your dataset, and executes the analysis securely in a Daytona sandbox.\n\nYou provide the data and describe what insights you need - the agent handles the rest.\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nClone the [repository](https://github.com/daytonaio/daytona) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/python/langchain/data-analysis/anthropic\n```\n\n#### Install Dependencies\n\n:::note[Python Version Requirement]\nThis example requires **Python 3.10 or higher** because it uses LangChain 1.0+ syntax. It's recommended to use a virtual environment (e.g., `venv` or `poetry`) to isolate project dependencies.\n:::\n\nInstall the required packages for this example:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    pip install -U langchain langchain-anthropic langchain-daytona-data-analysis python-dotenv\n    ```\n\n    The packages include:\n    - `langchain`: LangChain framework for building AI agents\n    - `langchain-anthropic`: Integration package connecting Claude (Anthropic) APIs and LangChain\n    - `langchain-daytona-data-analysis`: Provides the `DaytonaDataAnalysisTool` for LangChain agents\n    - `python-dotenv`: Used for loading environment variables from `.env` file\n  </TabItem>\n</Tabs>\n\n#### Configure Environment\n\nGet your API keys and configure your environment:\n\n1. **Daytona API key:** Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n2. **Anthropic API key:** Get it from [Anthropic Console](https://console.anthropic.com/)\n\nCreate a `.env` file in your project:\n\n```bash\nDAYTONA_API_KEY=dtn_***\nANTHROPIC_API_KEY=sk-ant-***\n```\n\n### 3. Download Dataset\n\nWe'll be using a publicly available dataset of vehicle valuation. You can download it directly from:\n\n[https://download.daytona.io/dataset.csv](https://download.daytona.io/dataset.csv)\n\nDownload the file and save it as `dataset.csv` in your project directory.\n\n### 4. Initialize the Language Model\n\nModels are the reasoning engine of LangChain agents - they drive decision-making, determine which tools to call, and interpret results.\n\nIn this example, we'll use Anthropic's Claude model, which excels at code generation and analytical tasks.\n\nConfigure the Claude model with the following parameters:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from langchain_anthropic import ChatAnthropic\n\n    model = ChatAnthropic(\n        model_name=\"claude-sonnet-4-5-20250929\",\n        temperature=0,\n        timeout=None,\n        max_retries=2,\n        stop=None\n    )\n    ```\n\n    **Parameters explained:**\n    - `model_name`: Specifies the Claude model to use\n    - `temperature`: Tunes the degree of randomness in generation\n    - `max_retries`: Number of retries allowed for Anthropic API requests\n  </TabItem>\n</Tabs>\n\n:::tip[Learn More About Models]\nFor detailed information about LangChain models, different providers, and how to choose the right model for your use case, visit the [LangChain Models documentation](https://docs.langchain.com/oss/python/langchain/models).\n:::\n\n### 5. Define the Result Handler\n\nWhen the agent executes Python code in the sandbox, it generates artifacts like charts and output logs. We can define a handler function to process these results.\n\nThis function will extract chart data from the execution artifacts and save them as PNG files:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import base64\n    from daytona import ExecutionArtifacts\n\n    def process_data_analysis_result(result: ExecutionArtifacts):\n        # Print the standard output from code execution\n        print(\"Result stdout\", result.stdout)\n        \n        result_idx = 0\n        for chart in result.charts:\n            if chart.png:\n                # Charts are returned in base64 format\n                # Decode and save them as PNG files\n                with open(f'chart-{result_idx}.png', 'wb') as f:\n                    f.write(base64.b64decode(chart.png))\n                print(f'Chart saved to chart-{result_idx}.png')\n                result_idx += 1\n    ```\n\n    This handler processes execution artifacts by:\n    - Logging stdout output from the executed code\n    - Extracting chart data from the artifacts\n    - Decoding base64-encoded PNG charts\n    - Saving them to local files\n  </TabItem>\n</Tabs>\n\n### 6. Configure the Data Analysis Tool\n\nNow we'll initialize the `DaytonaDataAnalysisTool` and upload our dataset.\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from langchain_daytona_data_analysis import DaytonaDataAnalysisTool\n\n    # Initialize the tool with our result handler\n    DataAnalysisTool = DaytonaDataAnalysisTool(\n        on_result=process_data_analysis_result\n    )\n    \n    # Upload the dataset with metadata describing its structure\n    with open(\"./dataset.csv\", \"rb\") as f:\n        DataAnalysisTool.upload_file(\n            f,\n            description=(\n                \"This is a CSV file containing vehicle valuations. \"\n                \"Relevant columns:\\n\"\n                \"- 'year': integer, the manufacturing year of the vehicle\\n\"\n                \"- 'price_in_euro': float, the listed price of the vehicle in Euros\\n\"\n                \"Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.\"\n            )\n        )\n    ```\n\n    **Key points:**\n    - The `on_result` parameter connects our custom result handler\n    - The `description` provides context about the dataset structure to the agent\n    - Column descriptions help the agent understand how to process the data\n    - Data cleaning instructions ensure quality analysis\n  </TabItem>\n</Tabs>\n\n### 7. Create and Run the Agent\n\nFinally, we'll create the LangChain agent with our configured model and tool, then invoke it with our analysis request.\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from langchain.agents import create_agent\n\n    # Create the agent with the model and data analysis tool\n    agent = create_agent(model, tools=[DataAnalysisTool], debug=True)\n\n    # Invoke the agent with our analysis request\n    agent_response = agent.invoke({\n        \"messages\": [{\n            \"role\": \"user\",\n            \"content\": \"Analyze how vehicles price varies by manufacturing year. Create a line chart showing average price per year.\"\n        }]\n    })\n\n    # Always close the tool to clean up sandbox resources\n    DataAnalysisTool.close()\n    ```\n  </TabItem>\n</Tabs>\n\n  **What happens here:**\n    1. The agent receives your natural language request\n    2. It determines it needs to use the `DaytonaDataAnalysisTool`\n    3. Agent generates Python code to analyze the data\n    4. Code executes securely in the Daytona sandbox\n    5. Results are processed by our handler function\n    6. Charts are saved to your local directory\n    7. Sandbox resources are cleaned up at the end\n\n### 8. Running Your Analysis\n\nNow you can run the complete code to see the results.\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    python data_analysis.py\n    ```\n  </TabItem>\n</Tabs>\n\n#### Understanding the Agent's Execution Flow\n\nWhen you run the code, the agent works through your request step by step. Here's what happens in the background:\n\n**Step 1: Agent receives and interprets the request**\n\nThe agent acknowledges your analysis request:\n\n```\nAI Message: \"I'll analyze how vehicle prices vary by manufacturing year and create a line chart showing the average price per year.\"\n```\n\n**Step 2: Agent generates Python code**\n\nThe agent generates Python code to explore the dataset first:\n\n```python\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Load the dataset\ndf = pd.read_csv('/home/daytona/dataset.csv')\n\n# Display basic info about the dataset\nprint(\"Dataset shape:\", df.shape)\nprint(\"\\nFirst few rows:\")\nprint(df.head())\nprint(\"\\nColumn names:\")\nprint(df.columns.tolist())\nprint(\"\\nData types:\")\nprint(df.dtypes)\n```\n\n**Step 3: Code executes in Daytona sandbox**\n\nThe tool runs this code in a secure sandbox and returns the output:\n\n```\nResult stdout Dataset shape: (100000, 15)\n\nFirst few rows:\n   Unnamed: 0  ...                               offer_description\n0       75721  ...  ST-Line Hybrid Adapt.LED+Head-Up-Display Klima\n1       80184  ...             blue Trend,Viele Extras,Top-Zustand\n2       19864  ...    35 e-tron S line/Matrix/Pano/ACC/SONOS/LM 21\n3       76699  ...           2.0 Lifestyle Plus Automatik Navi FAP\n4       92991  ...                    1.6 T 48V 2WD Spirit LED, WR\n\n[5 rows x 15 columns]\n\nColumn names:\n['Unnamed: 0', 'brand', 'model', 'color', 'registration_date', 'year', \n 'price_in_euro', 'power_kw', 'power_ps', 'transmission_type', 'fuel_type', \n 'fuel_consumption_l_100km', 'fuel_consumption_g_km', 'mileage_in_km', \n 'offer_description']\n\nData types:\nUnnamed: 0                    int64\nbrand                        object\nmodel                        object\ncolor                        object\nregistration_date            object\nyear                         object\nprice_in_euro                object\npower_kw                     object\npower_ps                     object\ntransmission_type            object\nfuel_type                    object\nfuel_consumption_l_100km     object\nfuel_consumption_g_km        object\nmileage_in_km               float64\noffer_description            object\ndtype: object\n```\n\n**Step 4: Agent generates detailed analysis code**\n\nBased on the initial dataset information, the agent generates more specific code to examine the key columns:\n\n```python\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Load the dataset\ndf = pd.read_csv('/home/daytona/dataset.csv')\n\nprint(\"Dataset shape:\", df.shape)\nprint(\"\\nColumn names:\")\nprint(df.columns.tolist())\n\n# Check for year and price_in_euro columns\nprint(\"\\nChecking 'year' column:\")\nprint(df['year'].describe())\nprint(\"\\nMissing values in 'year':\", df['year'].isna().sum())\n\nprint(\"\\nChecking 'price_in_euro' column:\")\nprint(df['price_in_euro'].describe())\nprint(\"\\nMissing values in 'price_in_euro':\", df['price_in_euro'].isna().sum())\n```\n\n**Step 5: Execution results from sandbox**\n\nThe code executes and returns column statistics:\n\n```\nResult stdout Dataset shape: (100000, 15)\n\nColumn names:\n['Unnamed: 0', 'brand', 'model', 'color', 'registration_date', 'year', \n 'price_in_euro', 'power_kw', 'power_ps', 'transmission_type', 'fuel_type', \n 'fuel_consumption_l_100km', 'fuel_consumption_g_km', 'mileage_in_km', \n 'offer_description']\n\nChecking 'year' column:\ncount     100000\nunique        49\ntop         2019\nfreq       12056\nName: year, dtype: object\n\nMissing values in 'year': 0\n\nChecking 'price_in_euro' column:\ncount     100000\nunique     11652\ntop        19990\nfreq         665\nName: price_in_euro, dtype: object\n\nMissing values in 'price_in_euro': 0\n```\n\n**Step 6: Agent generates final analysis and visualization code**\n\nNow that the agent understands the data structure, it generates the complete analysis code with data cleaning, processing, and visualization:\n\n```python\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Load the dataset\ndf = pd.read_csv('/home/daytona/dataset.csv')\n\nprint(\"Original dataset shape:\", df.shape)\n\n# Clean the data - remove rows with missing values in year or price_in_euro\ndf_clean = df.dropna(subset=['year', 'price_in_euro'])\nprint(f\"After removing missing values: {df_clean.shape}\")\n\n# Convert to numeric and remove non-numeric values\ndf_clean['year'] = pd.to_numeric(df_clean['year'], errors='coerce')\ndf_clean['price_in_euro'] = pd.to_numeric(df_clean['price_in_euro'], errors='coerce')\n\n# Remove rows where conversion failed\ndf_clean = df_clean.dropna(subset=['year', 'price_in_euro'])\nprint(f\"After removing non-numeric values: {df_clean.shape}\")\n\n# Remove outliers using IQR method for both year and price\ndef remove_outliers(df, column):\n    Q1 = df[column].quantile(0.25)\n    Q3 = df[column].quantile(0.75)\n    IQR = Q3 - Q1\n    lower_bound = Q1 - 1.5 * IQR\n    upper_bound = Q3 + 1.5 * IQR\n    return df[(df[column] >= lower_bound) & (df[column] <= upper_bound)]\n\ndf_clean = remove_outliers(df_clean, 'year')\nprint(f\"After removing year outliers: {df_clean.shape}\")\n\ndf_clean = remove_outliers(df_clean, 'price_in_euro')\nprint(f\"After removing price outliers: {df_clean.shape}\")\n\nprint(\"\\nCleaned data summary:\")\nprint(df_clean[['year', 'price_in_euro']].describe())\n\n# Calculate average price per year\navg_price_by_year = df_clean.groupby('year')['price_in_euro'].mean().sort_index()\n\nprint(\"\\nAverage price by year:\")\nprint(avg_price_by_year)\n\n# Create line chart\nplt.figure(figsize=(14, 7))\nplt.plot(avg_price_by_year.index, avg_price_by_year.values, marker='o', \n         linewidth=2, markersize=6, color='#2E86AB')\nplt.xlabel('Manufacturing Year', fontsize=12, fontweight='bold')\nplt.ylabel('Average Price (€)', fontsize=12, fontweight='bold')\nplt.title('Average Vehicle Price by Manufacturing Year', fontsize=14, \n          fontweight='bold', pad=20)\nplt.grid(True, alpha=0.3, linestyle='--')\nplt.xticks(rotation=45)\n\n# Format y-axis to show currency\nax = plt.gca()\nax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'€{x:,.0f}'))\n\nplt.tight_layout()\nplt.show()\n\n# Additional statistics\nprint(f\"\\nTotal number of vehicles analyzed: {len(df_clean)}\")\nprint(f\"Year range: {int(df_clean['year'].min())} - {int(df_clean['year'].max())}\")\nprint(f\"Price range: €{df_clean['price_in_euro'].min():.2f} - €{df_clean['price_in_euro'].max():.2f}\")\nprint(f\"Overall average price: €{df_clean['price_in_euro'].mean():.2f}\")\n```\n\nThis comprehensive code performs data cleaning, outlier removal, calculates averages by year, and creates a professional visualization.\n\n**Step 7: Final execution and chart generation**\n\nThe code executes successfully in the sandbox, processes the data, and generates the visualization:\n\n```\nResult stdout Original dataset shape: (100000, 15)\nAfter removing missing values: (100000, 15)\nAfter removing non-numeric values: (99946, 15)\nAfter removing year outliers: (96598, 15)\nAfter removing price outliers: (90095, 15)\n\nCleaned data summary:\n               year  price_in_euro\ncount  90095.000000   90095.000000\nmean    2016.698563   22422.266707\nstd        4.457647   12964.727116\nmin     2005.000000     150.000000\n25%     2014.000000   12980.000000\n50%     2018.000000   19900.000000\n75%     2020.000000   29500.000000\nmax     2023.000000   62090.000000\n\nAverage price by year:\nyear\n2005.0     5968.124319\n2006.0     6870.881523\n2007.0     8015.234473\n2008.0     8788.644495\n2009.0     8406.198576\n2010.0    10378.815972\n2011.0    11540.640435\n2012.0    13306.642261\n2013.0    14512.707025\n2014.0    15997.682899\n2015.0    18563.864358\n2016.0    20124.556294\n2017.0    22268.083322\n2018.0    24241.123673\n2019.0    26757.469111\n2020.0    29400.163494\n2021.0    30720.168646\n2022.0    33861.717552\n2023.0    33119.840175\nName: price_in_euro, dtype: float64\n\nTotal number of vehicles analyzed: 90095\nYear range: 2005 - 2023\nPrice range: €150.00 - €62090.00\nOverall average price: €22422.27\n\nChart saved to chart-0.png\n```\n\nThe agent successfully completed the analysis, showing that vehicle prices generally increased from 2005 (€5,968) to 2022 (€33,862), with a slight decrease in 2023. The result handler captured the generated chart and saved it as `chart-0.png`.\n\nYou should see the chart in your project directory that will look similar to this:\n\n<Image src={chartImage} alt=\"Vehicle valuation by manufacturing year chart\" width={600} style=\"max-width: 100%; height: auto; margin: 1rem 0;\" />\n\n### 9. Complete Implementation\n\nHere is the complete, ready-to-run example:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n  import base64\n  from dotenv import load_dotenv\n  from langchain.agents import create_agent\n  from langchain_anthropic import ChatAnthropic\n  from daytona import ExecutionArtifacts\n  from langchain_daytona_data_analysis import DaytonaDataAnalysisTool\n\n  load_dotenv()\n\n  model = ChatAnthropic(\n      model_name=\"claude-sonnet-4-5-20250929\",\n      temperature=0,\n      timeout=None,\n      max_retries=2,\n      stop=None\n  )\n\n  def process_data_analysis_result(result: ExecutionArtifacts):\n      # Print the standard output from code execution\n      print(\"Result stdout\", result.stdout)\n      result_idx = 0\n      for chart in result.charts:\n          if chart.png:\n              # Save the png to a file\n              # The png is in base64 format.\n              with open(f'chart-{result_idx}.png', 'wb') as f:\n                  f.write(base64.b64decode(chart.png))\n              print(f'Chart saved to chart-{result_idx}.png')\n              result_idx += 1\n\n  def main():\n      DataAnalysisTool = DaytonaDataAnalysisTool(\n          on_result=process_data_analysis_result\n      )\n\n      try:\n          with open(\"./dataset.csv\", \"rb\") as f:\n              DataAnalysisTool.upload_file(\n                  f,\n                  description=(\n                      \"This is a CSV file containing vehicle valuations. \"\n                      \"Relevant columns:\\n\"\n                      \"- 'year': integer, the manufacturing year of the vehicle\\n\"\n                      \"- 'price_in_euro': float, the listed price of the vehicle in Euros\\n\"\n                      \"Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.\"\n                  )\n              )\n\n          agent = create_agent(model, tools=[DataAnalysisTool], debug=True)\n\n          agent_response = agent.invoke(\n              {\"messages\": [{\"role\": \"user\", \"content\": \"Analyze how vehicles price varies by manufacturing year. Create a line chart showing average price per year.\"}]}\n          )\n      finally:\n          DataAnalysisTool.close()\n\n  if __name__ == \"__main__\":\n      main()\n    ```\n  </TabItem>\n</Tabs>\n\n**Key advantages of this approach:**\n\n- **Secure execution:** Code runs in isolated Daytona sandbox\n- **Automatic artifact capture:** Charts, tables, and outputs are automatically extracted\n- **Natural language interface:** Describe analysis tasks in plain English\n- **Framework integration:** Seamlessly works with LangChain's agent ecosystem\n\n### 10. API Reference\n\nThe following public methods are available on `DaytonaDataAnalysisTool`:\n\n#### download_file\n\n```python\ndef download_file(remote_path: str) -> bytes\n```\n\nDownloads a file from the sandbox by its remote path.\n\n**Arguments**:\n\n- `remote_path` - str: Path to the file in the sandbox.\n\n**Returns**:\n\n- `bytes` - File contents.\n\n**Example**:\n\n```python\n# Download a file from the sandbox\nfile_bytes = tool.download_file(\"/home/daytona/results.csv\")\n```\n\n#### upload_file\n\n```python\ndef upload_file(file: IO, description: str) -> SandboxUploadedFile\n```\n\nUploads a file to the sandbox. The file is placed in `/home/daytona/`.\n\n**Arguments**:\n\n- `file` - IO: File-like object to upload.\n- `description` - str: Description of the file, explaining its purpose and the type of data it contains.\n\n**Returns**:\n\n- [`SandboxUploadedFile`](#sandboxuploadedfile) - Metadata about the uploaded file.\n\n**Example**:\n\nSuppose you want to analyze sales data for a retail business. You have a CSV file named `sales_q3_2025.csv` containing columns like `transaction_id`, `date`, `product`, `quantity`, and `revenue`. You want to upload this file and provide a description that gives context for the analysis.\n\n```python\nwith open(\"sales_q3_2025.csv\", \"rb\") as f:\n    uploaded = tool.upload_file(\n        f,\n        \"CSV file containing Q3 2025 retail sales transactions. Columns: transaction_id, date, product, quantity, revenue.\"\n    )\n```\n\n#### remove_uploaded_file\n\n```python\ndef remove_uploaded_file(uploaded_file: SandboxUploadedFile) -> None\n```\n\nRemoves a previously uploaded file from the sandbox.\n\n**Arguments**:\n\n- `uploaded_file` - [`SandboxUploadedFile`](#sandboxuploadedfile): The file to remove.\n\n**Returns**:\n\n- None\n\n**Example**:\n\n```python\n# Remove an uploaded file\ntool.remove_uploaded_file(uploaded)\n```\n\n#### get_sandbox\n\n```python\ndef get_sandbox() -> Sandbox\n```\n\nGets the current sandbox instance.\n\nThis method provides access to the Daytona sandbox instance, allowing you to inspect sandbox properties and metadata, as well as perform any sandbox-related operations. For details on available attributes and methods, see the [Sandbox](#sandbox) data structure section below.\n\n**Arguments**:\n\n- None\n\n**Returns**:\n\n- [`Sandbox`](#sandbox) - Sandbox instance.\n\n**Example**:\n\n```python\nsandbox = tool.get_sandbox()\n```\n\n#### install_python_packages\n\n```python\ndef install_python_packages(package_names: str | list[str]) -> None\n```\n\nInstalls one or more Python packages in the sandbox using pip.\n\n**Arguments**:\n\n- `package_names` - str | list[str]: Name(s) of the package(s) to install.\n\n**Returns**:\n\n- None\n\n:::note\nThe list of preinstalled packages in a sandbox can be found at [Daytona's Default Snapshot documentation](https://www.daytona.io/docs/en/snapshots/#default-snapshots).\n:::\n\n**Example**:\n\n```python\n# Install a single package\ntool.install_python_packages(\"pandas\")\n\n# Install multiple packages\ntool.install_python_packages([\"numpy\", \"matplotlib\"])\n```\n\n#### close\n\n```python\ndef close() -> None\n```\n\nCloses and deletes the sandbox environment.\n\n**Arguments**:\n\n- None\n\n**Returns**:\n\n- None\n\n:::note\nCall this method when you are finished with all data analysis tasks to properly clean up resources and avoid unnecessary usage.\n:::\n\n**Example**:\n\n```python\n# Close the sandbox and clean up\ntool.close()\n```\n\n### 11. Data Structures\n\n#### SandboxUploadedFile\nRepresents metadata about a file uploaded to the sandbox.\n\n- `name`: `str` - Name of the uploaded file in the sandbox\n- `remote_path`: `str` - Full path to the file in the sandbox\n- `description`: `str` - Description provided during upload\n\n#### Sandbox\nRepresents a Daytona sandbox instance.\n\nSee the full structure and API in the [Daytona Python SDK Sandbox documentation](https://www.daytona.io/docs/en/python-sdk/sync/sandbox/#sandbox)."
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/letta-code/letta-code-agent.mdx",
    "content": "---\ntitle: Build a Coding Agent Using Letta Code and Daytona\ndescription: Step-by-step guide to running Letta Code, a stateful coding agent with persistent memory, inside Daytona sandboxes.\n---\n\nimport { Image } from 'astro:assets'\n\nimport lettaCodeAgentResult from '../../../../../assets/docs/images/letta-code-agent-result.gif'\n\nThis guide demonstrates how to run an autonomous coding agent based on [Letta Code](https://docs.letta.com/letta-code/) inside a Daytona sandbox environment. The agent can develop web apps, write code in any language, install dependencies, and run scripts. Letta Code uses stateful agents with built-in memory, allowing conversations to persist across sessions.\n\n---\n\n### 1. Workflow Overview\n\nWhen you launch the main script, a Daytona sandbox is created and Letta Code is installed inside it. The agent is configured with a custom Daytona-aware system prompt.\n\nThe script provides an interactive CLI interface where you can chat with the agent and issue commands:\n\n```\n$ npm run start\nCreating sandbox...\nInstalling Letta Code...\nStarting Letta Code...\nInitializing agent...\nAgent initialized. Press Ctrl+C at any time to exit.\n\nUser: create a beautiful, professional themed app that lets me write markdown documents and render them live\nThinking...\n\n🔧 TodoWrite\n🔧 Write /home/daytona/markdown-editor/index.html\n🔧 TodoWrite\n🔧 Start HTTP server on port 8080\n🔧 TodoWrite\nPerfect! I've created a beautiful markdown editor with live preview for you! 🎉\n\n## Access your app here:\nhttps://8080-c157e5cb-5e11-4bb6-883d-c873169223b8.proxy.daytona.works\n\n## Features:\n\n✨ **Live Preview** — Real-time markdown rendering  \n\n📝 **Full Markdown Support** — Headers, text styles, lists, code blocks, tables, links, images  \n\n💾 **Auto-Save** — Persists to browser localStorage  \n\n📥 **Export** — Download as `.md` or standalone `.html`\n```\n\nThe agent can host web apps and provide you with a preview link using the [Daytona Preview Links](https://www.daytona.io/docs/en/preview-and-authentication/) feature. When your task involves running or previewing a web application, the agent automatically hosts the app and generates a link for you to inspect the live result:\n\n<Image\n  src={lettaCodeAgentResult}\n  alt=\"Markdown editor demo generated by Letta Code agent\"\n  width={600}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\nYou can continue interacting with your agent until you are finished. When you exit the program, the sandbox will be deleted automatically.\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nFirst, clone the daytona [repository](https://github.com/daytonaio/daytona.git) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/typescript/letta-code\n```\n\n#### Configure Environment\n\nGet your Daytona API key from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys) and your Letta API key from [Letta Platform](https://app.letta.com/api-keys).\n\nCopy `.env.example` to `.env` and add your keys:\n\n```bash\nDAYTONA_API_KEY=your_daytona_key\nSANDBOX_LETTA_API_KEY=your_letta_api_key\n```\n\n:::caution[API Key Security]\nIn this example, your Letta API key is passed into the sandbox environment and may be accessible to any code executed within it.\n:::\n\n#### Local Usage\n\n:::note[Node.js Version]\nNode.js 18 or newer is required to run this example. Please ensure your environment meets this requirement before proceeding.\n:::\n\nInstall dependencies:\n\n```bash\nnpm install\n```\n\nRun the example:\n\n```bash\nnpm run start\n```\n\nThe Letta Code agent will initialize and present an interactive prompt where you can issue commands.\n\n### 3. Understanding the Agent's Architecture\n\nThis example consists of two main TypeScript files:\n\n- **index.ts**: The main program that creates the Daytona sandbox, installs Letta Code, configures the system prompt, and provides an interactive CLI interface.\n- **letta-session.ts**: A helper class that manages PTY-based bidirectional communication with Letta Code, handling JSON message streaming and response parsing.\n\n#### Initialization\n\nOn initialization, the main program:\n1. Creates a new [Daytona sandbox](/docs/en/sandboxes) with your Letta API key included in the environment variables.\n2. Installs Letta Code globally inside the sandbox by running `npm install` with [process execution](/docs/en/process-code-execution#process-execution).\n3. Creates a [PTY (pseudoterminal)](/docs/en/pty/) session in the sandbox for bidirectional communication with Letta Code.\n4. Launches Letta Code in [bidirectional headless mode](https://docs.letta.com/letta-code/headless/) with stream-json format through the PTY.\n5. Waits for user input and sends prompts to the agent through the PTY session.\n\n#### Main Program Code\n\nThe program creates a [Daytona sandbox](/docs/en/sandboxes) with the Letta API key passed as an environment variable:\n\n```typescript\nsandbox = await daytona.create({\n  envVars: { LETTA_API_KEY: process.env.SANDBOX_LETTA_API_KEY },\n})\n```\n\n#### Running Letta Code in a Pseudoterminal\n\nA [PTY (pseudoterminal)](/docs/en/pty/) is created for bidirectional communication with Letta Code:\n\n```typescript\nthis.ptyHandle = await this.sandbox.process.createPty({\n  id: `letta-pty-${Date.now()}`,\n  onData: (data: Uint8Array) => this.handleData(data),\n})\n```\n\nLetta Code is then launched in [bidirectional headless mode](https://docs.letta.com/letta-code/headless/#bidirectional-mode) through the PTY:\n\n```typescript\nawait this.ptyHandle.sendInput(\n  `letta --new --system-custom \"${systemPrompt.replace(/\"/g, '\\\\\"')}\" --input-format stream-json --output-format stream-json --yolo -p\\n`,\n)\n```\n\nThe `stream-json` setting is used for the input and output formats, enabling our program to send and receive JSON messages to and from the agent in real-time.\n\nThe `--system-custom` prompt allows us to pass a custom system prompt to the agent. Our prompt configures the agent with Daytona-specific instructions, including a URL pattern so the agent can generate preview links.\n\nThe `--yolo` flag allows the agent to run shell commands without requiring explicit user approval for each command.\n\n#### Message Handling\n\nTo send prompts to the agent, the main script calls the `processPrompt()` method, which formats the user input as a JSON message and sends it to the PTY using `this.ptyHandle.sendInput()` as demonstrated above.\n\nFormatted user messages look like this:\n\n```json\n{\"type\": \"user\", \"message\": {\"role\": \"user\", \"content\": \"create a simple web server\"}}\n```\n\nThe agent responds with streaming JSON messages. Tool calls arrive as fragments:\n\n```json\n{\"type\": \"message\", \"message_type\": \"approval_request_message\", \"tool_call\": {\"tool_call_id\": \"call_123\", \"name\": \"Bash\", \"arguments\": \"{\\\"command\\\": \\\"python3 -m http.server 8080\\\"}\"}}\n```\n\nThese JSON fragments are parsed by the `handleParsedMessage()` method. When multiple consecutive fragments are received for the same tool call, they are combined into a single tool call object. When a tool call or message is finished, the result is formatted and displayed to the user.\n\n#### Clean up\n\nWhen you exit the main program, the Daytona sandbox and all files are automatically deleted.\n\n**Key advantages:**\n\n- Secure, isolated execution in Daytona sandboxes\n- Stateful agents with persistent memory across sessions\n- Full Letta Code capabilities including file operations and shell commands\n- Agents can be viewed in [Letta's Agent Development Environment](https://app.letta.com/)\n- Automatic preview link generation for hosted services\n- Multi-language and full-stack support\n- Simple setup and automatic cleanup\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/mastra/mastra-coding-agent.mdx",
    "content": "---\ntitle: Use Mastra Coding Agent with Daytona\ndescription: Learn how to integrate Daytona sandboxes with the Mastra coding agent for secure, isolated AI-powered development.\n---\n\nThis guide demonstrates how to configure the [Mastra coding agent](https://github.com/mastra-ai/template-coding-agent) to use Daytona sandboxes, enabling you to leverage AI capabilities for any coding-related task in a secure, isolated environment.\n\n---\n\n### 1. Workflow Overview\n\nOnce configured, you can use Mastra Studio to interact with the coding agent through a ChatGPT-like interface. This enables human-in-the-loop workflows where you can guide the agent, review its decisions, and iterate on solutions in real-time; all while the agent executes tasks securely within Daytona sandboxes.\n\n### 2. Project Setup\n\n:::note[Node.js Version]\nNode.js version 20 or higher is required to run the coding agent. Please ensure your environment meets this requirement before proceeding.\n:::\n\n#### Clone the Repository\n\nClone the Mastra coding agent template repository, which includes the agent implementation and Daytona integration:\n\n```bash\ngit clone https://github.com/mastra-ai/template-coding-agent.git\ncd template-coding-agent\n```\n\n#### Configure Environment\n\nCreate a `.env` file in the project root directory:\n\n```bash\ntouch .env\n```\n\nThe `.env` file requires the following configuration:\n\n- **LLM Provider**: The AI model provider for your coding agent\n- **Model**: The specific model to use from your chosen provider\n- **Sandbox Provider**: Daytona configuration for isolated execution\n\nFor this guide, we'll use OpenAI as the LLM provider with the `gpt-4o-mini` model:\n\n```env\nOPENAI_API_KEY=your_openai_key\nMODEL=openai/gpt-4o-mini\n```\n\nNext, configure Daytona as your sandbox provider by adding your API key (available from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys)):\n\n```env\nDAYTONA_API_KEY=your-daytona-api-key-here\n```\n\n#### Install Dependencies\n\nInstall the required packages using pnpm:\n\n```bash\npnpm install\n```\n\n### 3. Running the Agent\n\nMastra Studio provides a ChatGPT-like interface for interacting with your coding agent. This mode offers:\n\n- **Conversation History**: Previous conversations are stored and organized in threads\n- **Visual Debugging**: Inspect agent execution steps, workflow, and tool calls\n- **Model Switching**: Easily switch between different AI models\n- **Tool Inspection**: View which tools your agent is using in real-time\n\nFor a complete overview of all features and capabilities, visit the [Mastra Studio documentation](https://mastra.ai/docs/getting-started/studio).\n\nStart the dev server with:\n\n```bash\npnpm run dev\n```\n\nIf the dev server starts successfully, you'll see the terminal output displaying the URLs where you can access Mastra Studio:\n\n```bash\n│ Studio: http://localhost:4111\n│ API:    http://localhost:4111/api\n```\n\nOnce started, open the provided URL in your browser to access the interactive interface. You can interact with your agent while monitoring its workflow in the terminal, where detailed logs show execution steps and low-level parameters.\n\nBelow is an example of terminal logs generated when the agent calls the `writeFile` tool to create a JavaScript file with a basic \"Hello, world!\" output:\n\n```json\n{\n  \"text\": \"\",\n  \"toolCalls\": [\n    {\n      \"type\": \"tool-call\",\n      \"runId\": \"ab2a1d08-91c6-4028-9046-3446a721527f\",\n      \"from\": \"AGENT\",\n      \"payload\": {\n        \"toolCallId\": \"call_NiLLgBmgrYLSL0MsrG54E4A5\",\n        \"toolName\": \"writeFile\",\n        \"args\": {\n          \"sandboxId\": \"2152d23b-5742-47c2-9992-4414d4144869\",\n          \"path\": \"hello.js\",\n          \"content\": \"console.log('Hello, world!');\"\n        },\n        \"providerMetadata\": {\n          \"openai\": {\n            \"itemId\": \"fc_00bba3412cd22a2b0069399fbaeef881909b0583f359cbc33c\"\n          }\n        }\n      }\n    }\n  ],\n  \"toolResults\": [\n    {\n      \"type\": \"tool-result\",\n      \"runId\": \"ab2a1d08-91c6-4028-9046-3446a721527f\",\n      \"from\": \"AGENT\",\n      \"payload\": {\n        \"args\": {\n          \"sandboxId\": \"2152d23b-5742-47c2-9992-4414d4144869\",\n          \"path\": \"hello.js\",\n          \"content\": \"console.log('Hello, world!');\"\n        },\n        \"toolCallId\": \"call_NiLLgBmgrYLSL0MsrG54E4A5\",\n        \"toolName\": \"writeFile\",\n        \"result\": {\n          \"success\": true,\n          \"path\": \"/home/daytona/hello.js\"\n        },\n        \"providerMetadata\": {\n          \"openai\": {\n            \"itemId\": \"fc_00bba3412cd22a2b0069399fbaeef881909b0583f359cbc33c\"\n          }\n        }\n      }\n    }\n  ],\n  \"finishReason\": \"tool-calls\",\n  \"usage\": {\n    \"inputTokens\": 4243,\n    \"outputTokens\": 53,\n    \"totalTokens\": 4296,\n    \"reasoningTokens\": 0,\n    \"cachedInputTokens\": 4096\n  },\n  \"runId\": \"ab2a1d08-91c6-4028-9046-3446a721527f\"\n}\n```\n\nThese logs show complete visibility into tool execution including arguments, results, token usage with caching metrics, and unique identifiers for debugging.\n\n### 4. Example Usage\n\nLet's walk through a practical example to see the Mastra coding agent and Daytona sandbox integration in action. We'll ask the agent to complete the following task:\n\n> _\"Create a Python file with a function that reverses a string, write a test file for it, and run the tests.\"_\n\n#### Agent Workflow\n\nThe agent executes this task through a series of coordinated steps, utilizing different tools to interact with the Daytona sandbox:\n\n##### 1. Create Sandbox\n\nThe agent first provisions a new Daytona sandbox for Python development:\n\n**Tool:** `createSandbox`\n\n**Arguments:**\n\n```json\n{\n  \"name\": \"reverse_string_project\",\n  \"labels\": null,\n  \"language\": \"python\",\n  \"envVars\": null\n}\n```\n\n**Result:**\n\n```json\n{\n  \"sandboxId\": \"bdfa9456-4945-43a7-97df-b9bfbcbdc62e\"\n}\n```\n\n##### 2. Write Project Files\n\nNext, the agent creates both the implementation and test files in a single operation:\n\n**Tool:** `writeFiles`\n\n**Arguments:**\n\n```json\n{\n  \"sandboxId\": \"bdfa9456-4945-43a7-97df-b9bfbcbdc62e\",\n  \"files\": [\n    {\n      \"path\": \"reverse_string.py\",\n      \"data\": \"def reverse_string(s):\\n    \\\"\\\"\\\"Return the reversed version of the input string s.\\\"\\\"\\\"\\n    return s[::-1]\\n\"\n    },\n    {\n      \"path\": \"test_reverse_string.py\",\n      \"data\": \"import unittest\\nfrom reverse_string import reverse_string\\n\\nclass TestReverseString(unittest.TestCase):\\n    def test_regular(self):\\n        self.assertEqual(reverse_string(\\\"hello\\\"), \\\"olleh\\\")\\n    def test_empty(self):\\n        self.assertEqual(reverse_string(\\\"\\\"), \\\"\\\")\\n    def test_single_char(self):\\n        self.assertEqual(reverse_string(\\\"a\\\"), \\\"a\\\")\\n    def test_numbers(self):\\n        self.assertEqual(reverse_string(\\\"12345\\\"), \\\"54321\\\")\\n\\nif __name__ == \\\"__main__\\\":\\n    unittest.main()\\n\"\n    }\n  ]\n}\n```\n\n**Result:**\n\n```json\n{\n  \"success\": true,\n  \"filesWritten\": [\n    \"/home/daytona/reverse_string.py\",\n    \"/home/daytona/test_reverse_string.py\"\n  ]\n}\n```\n\n##### 3. Execute Tests\n\nFinally, the agent runs the test suite to verify the implementation:\n\n**Tool:** `runCommand`\n\n**Arguments:**\n\n```json\n{\n  \"sandboxId\": \"bdfa9456-4945-43a7-97df-b9bfbcbdc62e\",\n  \"command\": \"python3 test_reverse_string.py\",\n  \"envs\": null,\n  \"workingDirectory\": null,\n  \"timeoutSeconds\": 20,\n  \"captureOutput\": true\n}\n```\n\n**Result:**\n\n```json\n{\n  \"success\": true,\n  \"exitCode\": 0,\n  \"stdout\": \"....\\n----------------------------------------------------------------------\\nRan 4 tests in 0.000s\\n\\nOK\\n\",\n  \"command\": \"python3 test_reverse_string.py\",\n  \"executionTime\": 218\n}\n```\n\n#### Agent Response\n\nAfter successfully completing all steps, the agent provides a detailed summary:\n\n```\nThe project is complete! Here's what was done:\n\n✓ Created reverse_string.py with a function to reverse a string.\n✓ Created test_reverse_string.py using Python's unittest to test the function with several cases.\n✓ Ran the tests—all tests passed successfully.\n\nTest Output:\n....\n----------------------------------------------------------------------\nRan 4 tests in 0.000s\n\nOK\n\nWould you like to see the code for either file or make any changes?\n```\n\nThis example demonstrates how the agent autonomously handles the entire development workflow, from environment setup to test execution, all within the secure Daytona sandbox environment.\n\n:::tip[Sandbox Management]\nAfter the agent completes its task, you'll see the active sandbox in your [Daytona Dashboard](https://app.daytona.io/dashboard). It's recommended to clean up resources when finished, unless your use case requires the sandbox to remain active (e.g. for preview URLs or ongoing development).\n:::\n\n**Key Advantages**\n\n- **Secure Isolation**: All agent operations run in isolated Daytona sandboxes, protecting your local environment\n- **Multi-Language Support**: Execute code across different programming languages without local setup\n- **Enhanced Debugging**: Use Mastra Studio to visualize and debug agent workflows in real-time\n- **Scalable Execution**: Leverage Daytona's cloud infrastructure for resource-intensive tasks\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/openclaw/index.mdx",
    "content": "---\ntitle: OpenClaw Guides\ndescription: Guides for running OpenClaw with Daytona\ntableOfContents: false\nslug: en/guides/openclaw\n---\n\nimport GuidesList from '@components/GuidesList.astro'\n\nGuides for running OpenClaw with Daytona.\n\n<GuidesList category=\"openclaw\" />\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/openclaw/openclaw-run-secure-sandbox.mdx",
    "content": "---\ntitle: Run OpenClaw in a Daytona Sandbox via CLI\ndescription: Learn how to run OpenClaw inside a Daytona sandbox using the Daytona CLI for secure, isolated, and always-on AI assistant with Telegram and WhatsApp.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nThis guide walks you through setting up [OpenClaw](https://openclaw.ai/) inside a Daytona sandbox and configuring Telegram and WhatsApp channels.\n\nRunning OpenClaw in a Daytona sandbox keeps your AI assistant isolated from your local machine, provides a secure environment for code execution, and ensures your bot stays online 24/7 without tying up your personal computer.\n\n### Prerequisites\n\n- Daytona account and API key (Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys))\n- Local terminal (macOS, Linux, or Windows)\n\n### Install the Daytona CLI\n\n<Tabs syncKey=\"os\">\n  <TabItem label=\"Mac/Linux\">\n    ```bash\n    brew install daytonaio/cli/daytona\n    ```\n  </TabItem>\n  <TabItem label=\"Windows\">\n    ```bash\n    powershell -Command \"irm https://get.daytona.io/windows | iex\"\n    ```\n  </TabItem>\n</Tabs>\n\n:::note\nAlready have the CLI? Check your version with `daytona --version`. If it's below **0.135.0**, [upgrade to the latest version](https://www.daytona.io/docs/en/getting-started/#cli).\n:::\n\n### Authenticate with Daytona\n\nLog in to your Daytona account using your API key:\n\n```bash\ndaytona login --api-key=YOUR_API_KEY\n```\n\nReplace `YOUR_API_KEY` with your actual Daytona API key.\n\n### Create a Sandbox\n\nCreate a sandbox for running OpenClaw:\n\n```bash\ndaytona sandbox create --name openclaw --snapshot daytona-medium --auto-stop 0\n```\n\nOpenClaw comes preinstalled in the default Daytona snapshot, so the command above is all you need.\n\n:::note\nThe `--auto-stop 0` flag disables automatic shutdown, keeping OpenClaw accessible until you manually stop or delete the sandbox. The `daytona-medium` snapshot is required because the OpenClaw gateway needs a minimum of 2GB memory.\n:::\n\n### Connect to the Sandbox\n\nSSH into your sandbox:\n\n```bash\ndaytona ssh openclaw\n```\n\n### Run OpenClaw Onboarding\n\nStart the onboarding process:\n\n```bash\nopenclaw onboard\n```\n\n:::note\nThe model provider steps below are for Anthropic. If using a different provider, follow the prompts for your chosen option.\n:::\n\nFollow the prompts:\n\n1. **Security acknowledgment:** Accept to continue\n2. **Onboarding mode:** Select **Quickstart**\n3. **Model/auth provider:** Select **Anthropic**\n4. **Anthropic auth method:** Select **Anthropic API key**\n5. **Enter Anthropic API key:** Paste your API key\n6. **Default model:** Keep current (default: `anthropic/claude-opus-4-5`)\n7. **Select channel:** Choose **Skip for now** (we'll configure channels later)\n8. **Configure skills:** Select **No** (configure later based on your needs)\n9. **Enable hooks:** Select **Skip for now** (configure later based on your needs)\n10. **Gateway service:** Select **Skip** (already installed)\n\nWhen onboarding finishes, the output will display a **Dashboard ready** section with a dashboard link. Your gateway token is the value after `?token=` in the URL. Save this token - you'll need it to connect to the dashboard.\n\nAlso, OpenClaw will ask you to **Install shell completion script?** - choose whatever you prefer, this is optional and doesn't affect functionality.\n\n### Start the Gateway\n\nRun the gateway in the background:\n\n```bash\nnohup openclaw gateway run > /tmp/gateway.log 2>&1 &\n```\n\nThe `&` runs the gateway as a background process, keeping your terminal free for other commands. The `nohup` ensures the gateway keeps running even after you close the SSH connection.\n\n### Access the Dashboard\n\nThe OpenClaw dashboard is a web interface for managing your assistant, monitoring connections, and configuring channels. To access it, you need a [preview URL](https://www.daytona.io/docs/en/preview/) that exposes the gateway port running inside your sandbox.\n\nIn your local terminal (not inside the sandbox SSH session), generate the preview URL:\n\n```bash\ndaytona preview-url openclaw --port 18789\n```\n\nThis command generates a [signed preview URL](https://www.daytona.io/docs/en/preview/#signed-preview-url) that securely exposes the port.\n\nOpen the URL in your browser, go to the **Overview** section, paste your gateway token in the **Gateway Token** field, and click **Connect**.\n\n:::tip\nThe preview URL expires after 1 hour by default (customizable with `--expires` flag). When it expires, simply run the same CLI command to generate a new one.\n:::\n\n### Pair Your Browser\n\nOpenClaw uses device pairing as a security measure - only approved devices can connect to and control your assistant. When you first attempt to connect from the dashboard, your browser registers as a new device that needs approval.\n\nList pending device requests:\n\n```bash\nopenclaw devices list\n```\n\nApprove your device:\n\n```bash\nopenclaw devices approve REQUEST_ID\n```\n\nReplace `REQUEST_ID` with the value from the **Request** column.\n\nClick **Connect** again in the dashboard.\n\nOnce connected, you should see a green status indicator - your OpenClaw is now ready to use.\n\n### Security\n\nRunning OpenClaw this way provides three layers of security:\n\n1. **Preview URL:** Time-limited access to the dashboard port\n2. **Gateway token:** Required to authenticate with the dashboard\n3. **Device approval:** Only approved devices can connect and control your assistant\n\nEven if someone obtains your dashboard URL, they cannot connect without the gateway token and an approved device.\n\n:::caution\nKeep your gateway token and preview URL secret. Do not share them publicly.\n:::\n\n---\n\n### Configure Telegram\n\nSet up a Telegram bot to chat with OpenClaw.\n\n#### Create a Telegram Bot\n\n1. Open Telegram and search for **@BotFather**\n2. Send `/start`, then `/newbot`\n3. Enter a name for your bot\n4. Enter a username for your bot\n5. Copy the bot token provided\n\n#### Configure OpenClaw\n\nEnable Telegram and set your bot token:\n\n```bash\nopenclaw config set channels.telegram.enabled true\nopenclaw config set channels.telegram.botToken YOUR_BOT_TOKEN\n```\n\nVerify the configuration:\n\n```bash\nopenclaw config get channels.telegram\n```\n\n#### Restart the Gateway\n\n```bash\nopenclaw gateway stop\nnohup openclaw gateway run > /tmp/gateway.log 2>&1 &\n```\n\n#### Complete Verification\n\n1. Open your bot's chat in Telegram and click **Start**\n2. A pairing code will appear. Approve the pairing request:\n\n```bash\nopenclaw pairing approve telegram PAIRING_CODE\n```\n\nYou can now message your OpenClaw through Telegram.\n\n---\n\n### Configure WhatsApp\n\nSet up WhatsApp to chat with OpenClaw.\n\n#### Run Configuration\n\n```bash\nopenclaw config --section channels\n```\n\nWhen prompted:\n\n1. Select **Local (this machine)** for gateway location\n2. Choose **Configure/link**\n3. Select **WhatsApp (QR link)**\n4. Select **Yes** for \"Link WhatsApp now (QR)?\"\n\n#### Scan the QR Code\n\nOpen WhatsApp on your phone, go to **Settings → Linked Devices → Link a Device**, and scan the QR code displayed in your terminal.\n\nOnce paired, you'll see:\n\n```\n✅ Linked after restart; web session ready.\n```\n\n#### Set Up Your Phone Number\n\nSelect **This is my personal phone number** (or choose the other option if you have a separate phone for OpenClaw) and enter your phone number when prompted.\n\n#### Finish Configuration\n\nWhen prompted to select another channel, choose **Finished**. You'll see:\n\n```\n└  Configure complete.\n```\n\n#### Start Chatting\n\nSend a message to yourself in WhatsApp - OpenClaw will respond. You can give it instructions and information on how to behave directly in the chat.\n\n:::tip\nTo allow other users to chat with OpenClaw, add their phone numbers to the **Allow From** list in **Channels → WhatsApp** inside the dashboard. When they send a message, OpenClaw will respond.\n:::\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/openclaw/openclaw-sdk-sandbox.mdx",
    "content": "---\ntitle: Run OpenClaw in a Daytona Sandbox via SDK\ndescription: Learn how to run OpenClaw inside a Daytona sandbox using the Daytona SDK — create a sandbox programmatically and access the dashboard via a preview URL.\n---\n\nimport { Image } from 'astro:assets'\n\nimport openclawSandbox from '../../../../../assets/docs/images/openclaw-sandbox.gif'\n\nThis guide shows how to run [OpenClaw](https://openclaw.ai/) inside a Daytona sandbox using the Daytona SDK. The script automatically creates and configures a sandbox with OpenClaw and provides an authenticated [preview URL](/docs/en/preview/) for using OpenClaw in the browser.\n\n---\n\n### 1. Workflow Overview\n\nWhen you run the script, it creates a Daytona sandbox, starts the OpenClaw gateway inside it, and prints a preview link for the dashboard:\n\n```\n$ npm start\nCreating Daytona sandbox...\nConfiguring OpenClaw...\nStarting OpenClaw...\n(Ctrl+C to shut down and delete the sandbox)\n\n🔗 Secret link to Control UI: https://18789-xxxx.proxy.daytona.works?token=...\n```\n\nOpen the provided link in your browser to connect to the OpenClaw Control UI. This link contains a configuration token, and anyone can use it to connect to OpenClaw without device approval.\n\n<Image\n  src={openclawSandbox}\n  alt=\"OpenClaw Control UI running in a Daytona sandbox\"\n  width={600}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\nYou can use the Control UI to chat with your assistant, configure Telegram and WhatsApp, and manage sessions. When you exit the script (Ctrl+C), the sandbox will not be deleted unless [sandbox persistence is disabled](/docs/en/guides/openclaw/openclaw-sdk-sandbox#4-key-constants).\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nClone the Daytona [repository](https://github.com/daytonaio/daytona) and go to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/typescript/openclaw\n```\n\n#### Configure Environment\n\nGet your API key from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys).\n\nCopy `.env.example` to `.env` and add your Daytona API key:\n\n```bash\nDAYTONA_API_KEY=your_daytona_key\n```\n\nA default OpenClaw configuration is stored in `openclaw.json`. You can customize it according to the [configuration reference](https://docs.openclaw.ai/gateway/configuration-reference). You can also add additional environment variables to `.env.sandbox` (e.g. `ANTHROPIC_API_KEY` for Claude) and they will be loaded into the sandbox.\n\n#### Run the Example\n\n:::note[Node.js]\nNode.js 18 or newer is required.\n:::\n\nInstall dependencies and run:\n\n```bash\nnpm install\nnpm start\n```\n\nThe script creates the sandbox, starts the OpenClaw gateway, and prints a secret link with the token in the URL.\n\n### 3. How It Works\n\n1. The script creates a [Daytona sandbox](/docs/en/sandboxes) with `DAYTONA_SNAPSHOT` (e.g. `daytona-medium`) and loads env vars from `.env.sandbox`.\n2. Your local `openclaw.json` is merged with built-in config and written to `~/.openclaw/openclaw.json` in the sandbox.\n3. The OpenClaw gateway is started inside the sandbox on `OPENCLAW_PORT` via [process execution](/docs/en/process-code-execution).\n4. A signed [preview link](/docs/en/preview/) is generated and the token is appended as `?token=...`; this link is printed so you can open the Control UI.\n5. On Ctrl+C, the sandbox is deleted unless `PERSIST_SANDBOX` is `true`.\n\n### 4. Key Constants\n\nYou can change behavior by editing the constants in [`src/index.ts`](https://github.com/daytonaio/daytona/blob/main/guides/typescript/openclaw/src/index.ts):\n\n| Constant | Default | Description |\n|----------|---------|-------------|\n| `PERSIST_SANDBOX` | true | When true, the sandbox is not deleted when the script exits |\n| `MAKE_PUBLIC` | true | Allow anyone to access the sandbox instead of limiting to your Daytona organization |\n| `OPENCLAW_PORT` | 18789 | OpenClaw Gateway and Control UI port |\n| `SHOW_LOGS` | true | Stream OpenClaw stdout/stderr to the terminal |\n\n**Key advantages:**\n\n- Secure, isolated execution in a Daytona sandbox\n- No device approval — token in URL and `allowInsecureAuth` skip pairing\n- Control UI and channels accessible via the secret preview link\n- Optional: keep the sandbox running after exit (`PERSIST_SANDBOX`)"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/opencode/index.mdx",
    "content": "---\ntitle: OpenCode Guides\ndescription: Guides for running OpenCode with Daytona sandboxes\ntableOfContents: false\nslug: en/guides/opencode\n---\n\nimport GuidesList from '@components/GuidesList.astro'\n\nGuides for running [OpenCode](https://opencode.ai/) with Daytona.\n\n<GuidesList category=\"opencode\" />\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/opencode/opencode-plugin.mdx",
    "content": "---\ntitle: Run OpenCode with the Daytona Plugin\ndescription: Use the Daytona OpenCode plugin to run each OpenCode session in a Daytona sandbox, with automatic git sync to local branches.\n---\n\nimport { Image } from 'astro:assets'\n\nimport opencodePluginGif from '../../../../../assets/docs/images/opencode-plugin.gif'\n\nThis guide demonstrates how to run the [Daytona OpenCode plugin](https://www.npmjs.com/package/@daytonaio/opencode) which integrates Daytona sandboxes and OpenCode. When the plugin is active, all agent operations occur in secure sandboxes, with one sandbox per OpenCode session. The plugin also has the ability to sync changes between sandboxes and local Git branches.\n\n### 1. Workflow Overview\n\nWhen you run OpenCode with the Daytona plugin, sandboxes are created automatically inside OpenCode sessions. Operations such as running code, installing dependencies, and starting servers occur in the sandbox.\n\n<Image\n  src={opencodePluginGif}\n  alt=\"OpenCode with Daytona plugin — sandbox toast and git branches\"\n  width={600}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\nSandboxes are preserved until you delete the OpenCode session. If a local Git repository is detected, the plugin syncs changes between the sandbox and branches with the `opencode/` prefix. \n\n### 2. Project Setup\n\n#### Add the Plugin\n\nAdd the Daytona plugin to your project by creating or editing `opencode.json` in the project directory:\n\n```json\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"plugin\": [\"@daytonaio/opencode\"]\n}\n```\n\nOpenCode downloads the plugin automatically when it starts. To install the plugin globally instead, edit `~/.config/opencode/opencode.json` and add the same `plugin` entry.\n\n#### Configure Environment\n\nThis plugin requires a [Daytona account](https://www.daytona.io/) and [Daytona API key](https://app.daytona.io/dashboard/keys) to create sandboxes.\n\nSet your API key:\n\n```bash\nexport DAYTONA_API_KEY=\"your-api-key\"\n```\n\nOr create a `.env` file in your project root:\n\n```env\nDAYTONA_API_KEY=your-api-key\n```\n\n#### Run OpenCode\n\n:::note[Git required]\nEnsure your project is a Git repository to enable syncing changes between the sandbox and your machine.\n:::\n\nInitialize Git if needed, then start OpenCode:\n\n```bash\ngit init\nopencode\n```\n\nYou can now use OpenCode as usual. As you work, you will see notifications in OpenCode indicating sandboxes are being created and changes are being synced to local branches.\n\nTo confirm the plugin is working, type `pwd` in the chat and you should see a path like `/home/daytona/project`.\n\nTo view live logs from the plugin for debugging:\n\n```bash\ntail -f ~/.local/share/opencode/log/daytona.log\n```\n\n#### Version control\n\nIn your project directory, use Git to list and check out the branches OpenCode creates:\n\n```bash\ngit branch\ngit checkout opencode/1\n```\n\nBy default, new sessions start from the branch that was checked out when OpenCode was started. After this, synchronization only goes one way: from the sandbox to your local branch. To start working from a different branch, use git to check out that branch and start OpenCode again:\n\n```bash\ngit checkout opencode/1\nopencode\n```\n\nYou can run as many OpenCode sessions in parallel as you want. Use Git to review and merge changes.\n\n### 3. Understanding the Plugin Architecture\n\nThe Daytona plugin consists of several modules that provide custom tools, hooks for events, connections from sessions to sandboxes and system prompt transforms. These modules ensure every agent action runs in a [Daytona sandbox](/docs/en/sandboxes) and that changes sync to local Git branches:\n\n- **Custom tools:** Overrides bash, read, write, edit, etc., so they run in the sandbox.\n- **System prompt transform:** Injects sandbox path and instructions into the agent's system prompt.\n- **Event handlers:** Handles session lifecycle events including cleanup (deleting sandboxes) and idle auto-commit (syncing changes to local git branches).\n- **Session management:** Manages the creation and deletion of sandboxes and the mapping of sessions to sandboxes.\n\n#### Custom tools\n\nThe custom tools module registers overrides for OpenCode's built-in tools so that every file and process operation goes through the Daytona SDK. It receives the project `id` and `worktree` from the plugin context and returns a tool map:\n\n```typescript\nexport async function customTools(ctx: PluginInput, sessionManager: DaytonaSessionManager) {\n  logger.info('OpenCode started with Daytona plugin')\n  const projectId = ctx.project.id\n  const worktree = ctx.project.worktree\n  return {\n    bash: bashTool(sessionManager, projectId, worktree, ctx),\n    // ... read, write, edit, multiedit, patch, ls, glob, grep, lsp, getPreviewURL\n  }\n}\n```\n\nFor example, the plugin implementation of the bash tool uses the Daytona SDK to run the command in the sandbox:\n\n```typescript\nasync execute(args: { command: string; background?: boolean }, ctx: ToolContext) {\n  const sessionId = ctx.sessionID\n  const sandbox = await sessionManager.getSandbox(sessionId, projectId, worktree, pluginCtx)\n\n  if (args.background) {\n    // ... create or get exec session, then:\n    const result = await sandbox.process.executeSessionCommand(execSessionId, {\n      command: args.command,\n      runAsync: true,\n    })\n    return `Command started in background (cmdId: ${result.cmdId})`\n  } else {\n    const result = await sandbox.process.executeCommand(args.command, repoPath)\n    return `Exit code: ${result.exitCode}\\n${result.result}`\n  }\n}\n```\n\nAll stateful tools (bash, read, write, edit, glob, grep, ls, lsp, multiedit, patch) are overridden the same way. The plugin also adds a custom tool for [preview links](/docs/en/preview/).\n\n#### System prompt transform\n\nThe system prompt transform extends the system prompt to include instructions for the agent to work in the sandbox and use the background option for long-running commands:\n\n```typescript\nexport async function systemPromptTransform(ctx: PluginInput, repoPath: string) {\n  return async (input: ExperimentalChatSystemTransformInput, output: ExperimentalChatSystemTransformOutput) => {\n    output.system.push(\n      [\n        '## Daytona Sandbox Integration',\n        'This session is integrated with a Daytona sandbox.',\n        `The main project repository is located at: ${repoPath}.`,\n        'Bash commands will run in this directory.',\n        'Put all projects in the project directory. Do NOT try to use the current working directory of the host system.',\n        \"When executing long-running commands, use the 'background' option to run them asynchronously.\",\n        'Before showing a preview URL, ensure the server is running in the sandbox on that port.',\n      ].join('\\n'),\n    )\n  }\n}\n```\n\n#### Session events\n\nThe session events handler listens for OpenCode session lifecycle events and handles them appropriately. When you delete a session, the handler cleans up the corresponding sandbox. When a session becomes idle, it triggers auto-commit and sync:\n\n```typescript\nexport async function eventHandlers(ctx: PluginInput, sessionManager: DaytonaSessionManager, repoPath: string) {\n  const projectId = ctx.project.id\n  const worktree = ctx.project.worktree\n  return async (args: any) => {\n    const event = args.event\n    if (event.type === EVENT_TYPE_SESSION_DELETED) {\n      const sessionId = (event as EventSessionDeleted).properties.info.id\n      await sessionManager.deleteSandbox(sessionId, projectId)\n      toast.show({ title: 'Session deleted', message: 'Sandbox deleted successfully.', variant: 'success' })\n    } else if (event.type === EVENT_TYPE_SESSION_IDLE) {\n      const sessionId = event.properties.sessionID\n      const sandbox = await sessionManager.getSandbox(sessionId, projectId, worktree, ctx)\n      const branchNumber = sessionManager.getBranchNumberForSandbox(projectId, sandbox.id)\n      if (!branchNumber) return\n      const sessionGit = new SessionGitManager(sandbox, repoPath, worktree, branchNumber)\n      await sessionGit.autoCommitAndPull(ctx)\n    }\n  }\n}\n```\n\n#### File synchronization\n\nWhile OpenCode is in use, the plugin uses Git to keep session sandboxes and your local Git repository in sync. This only occurs if a git repository is detected in the project directory. On plugin start:\n\n1. The plugin looks for a Git repository in the local directory.\n2. A parallel repository is created in the sandbox with a single `opencode` branch, mirroring your current local branch.\n3. A `sandbox` remote is added to your local repo using an SSH connection to the sandbox.\n4. Your current `HEAD` is pushed to `opencode`, and the sandbox repo is reset to that state.\n5. On session idle, the plugin commits in the sandbox on `opencode`, then pulls into a local branch (`opencode/1`, `opencode/2`, etc.) which is unique to each sandbox. A notification is shown when the sync is complete.\n\nFor more information on how the sync is implemented, see the [SessionGitManager](https://github.com/daytonaio/daytona/blob/main/libs/opencode-plugin/.opencode/plugin/daytona/git/session-git-manager.ts) class.\n\n:::caution\nWhen the plugin syncs to local `opencode` branches, any local changes on those branches are overwritten.\n:::\n\n#### Session storage\n\nThe session manager stores which sandbox belongs to each project in JSON files (using the same base path as OpenCode via `xdg-basedir`).\n\n- **macOS:** `~/.local/share/opencode/storage/daytona/[projectid].json`\n- **Windows:** `%LOCALAPPDATA%\\opencode\\storage\\daytona\\[projectid].json`\n\nEach file holds sandbox metadata for that project's sessions so that sandboxes are retained between OpenCode uses.\n\n**Key advantages:**\n\n- Secure, isolated execution: each OpenCode session runs in its own Daytona sandbox\n- Sandboxes persist until you delete the OpenCode session\n- Live [preview links](/docs/en/preview/) when a server starts in the sandbox\n- Automatic git sync to local branches so you can review and merge agent changes\n- No script to run: add the plugin and use OpenCode as usual\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/opencode/opencode-sdk-agent.mdx",
    "content": "---\ntitle: Build a Coding Agent Using OpenCode SDK and Daytona\ndescription: Step-by-step guide to building an autonomous coding agent using OpenCode and Daytona sandboxes.\n---\n\nimport { Image } from 'astro:assets'\n\nimport opencodeSdkSyncboard from '../../../../../assets/docs/images/opencode-sdk-syncboard.gif'\n\nThis guide walks you through running the [OpenCode](https://opencode.ai/) autonomous coding agent inside a secure Daytona sandbox. The OpenCode server runs fully isolated in the sandbox and the script connects to the server using the [OpenCode SDK](https://www.npmjs.com/package/@opencode-ai/sdk).\n\nThe agent can develop full-stack web apps, write code in any language, install dependencies, and run scripts. It can also start and manage dev servers, and generate [preview links](/docs/en/preview/) for live apps.\n\n### 1. Workflow Overview\n\nWhen you run the script, it creates a Daytona sandbox, installs OpenCode, and starts the OpenCode server inside the sandbox. You send prompts and see responses in your terminal. On exit, the sandbox is deleted.\n\n```\n$ npm run start\nCreating sandbox...\nInstalling OpenCode in sandbox...\nPreview: https://4096-0626a08c-08e7-4fbe-9799-d160bac66b08.daytonaproxy01.net\nPress Ctrl+C at any time to exit.\nUser: Create a minimalist collaborative whiteboard app\nThinking...\n🔨 ✓ Run: Check current directory structure\n✓ 3 todos\n📝 Add home/daytona/SPEC.md\n✓ 2 todos\n📝 Add home/daytona/index.html\n✓ 1 todos\n✓ home/daytona/SPEC.md\n✓ https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Outfit:wght@400;500;700&display=swap (text/css; charset=utf-8)\n✓ home/daytona/index.html\n🔨 ✓ Run: List files in directory\n🔨 ✓ Run: Start HTTP server for whiteboard\n🔨 ✓ Run: Check if server is running\n✓ 0 todos\nYour minimalist collaborative whiteboard app is ready!\n\n**Preview URL:** https://8080-0626a08c-08e7-4fbe-9799-d160bac66b08.daytonaproxy01.net\n\n## SyncBoard - Features\n\n**Drawing Tools:**\n- Pencil (freehand drawing)\n- Line, Rectangle, Ellipse (shape tools with preview)\n- Eraser (removes intersecting strokes)\n\n**Customization:**\n- 6 vibrant color presets\n- 3 stroke widths (thin/medium/thick)\n- Keyboard shortcuts: `P` `L` `R` `E` `X` for tools, `1` `2` `3` for stroke widths\n\n**Collaboration:**\n- Simulated real-time collaboration with other users\n- Unique user colors for each participant\n- Auto-saves to localStorage every 2 seconds\n\n**Actions:**\n- Undo/Redo (stores 20 actions, Ctrl+Z / Ctrl+Shift+Z)\n- Clear canvas (with confirmation dialog)\n- Coordinates display in status bar\n\n**Design:**\n- Dark theme with coral/teal accents\n- Dot grid background pattern\n- Smooth animations and hover effects\n- Responsive layout for mobile devices\n\nUser: \nCleaning up...\n```\n\nWhen your task involves running or previewing a web application, the agent can host the app and generate a [preview link](/docs/en/preview/) for you to inspect the live result:\n\n<Image\n  src={opencodeSdkSyncboard}\n  alt=\"SyncBoard collaborative whiteboard app generated by OpenCode agent\"\n  width={600}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\nYou can continue interacting with your agent until you are finished. When you exit the program, the sandbox will be deleted automatically.\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nFirst, clone the Daytona [repository](https://github.com/daytonaio/daytona.git) and navigate to the OpenCode SDK example:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/typescript/opencode/opencode-sdk\n```\n\n#### Configure Environment\n\nGet your API key from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys).\n\nCopy `.env.example` to `.env` and add your key:\n\n```bash\nDAYTONA_API_KEY=your_daytona_key\n```\n\n#### Local Usage\n\n:::note[Node.js Version]\nNode.js 18 or newer is required to run this example. Please ensure your environment meets this requirement before proceeding.\n:::\n\nInstall dependencies and run the example:\n\n```bash\nnpm install\nnpm run start\n```\n\nThe agent will start and wait for your prompt.\n\n### 3. Understanding the Script\n\nOpenCode uses a client-server model: The [server](https://opencode.ai/docs/server/) manages coding agents, sessions and configuration. Clients communicate with the server [over HTTP](https://opencode.ai/docs/server/#apis) to run prompts in sessions and receive streamed responses.\n\n#### Initialization\n\nOn startup, the script:\n\n1. Creates a new [Daytona sandbox](/docs/en/sandboxes).\n2. Installs OpenCode globally in the sandbox.\n3. Starts the OpenCode server in the sandbox.\n4. Gets the preview URL for the server and creates a client with that base URL.\n5. Enters the readline loop to send prompts to the server and receive streamed responses.\n6. On Ctrl+C, deletes the sandbox and exits.\n\n#### OpenCode Server\n\nThe OpenCode server runs inside the sandbox and handles all agent work: LLM calls, tools (bash, write, etc.), and code execution. The script starts it with:\n\n```ts\nconst envVar = injectEnvVar('OPENCODE_CONFIG_CONTENT', opencodeConfig)\nconst command = await sandbox.process.executeSessionCommand(sessionId, {\n  command: `${envVar} opencode serve --port ${PORT} --hostname ${HOSTNAME}`,\n  runAsync: true,\n})\n```\n\nA custom configuration is injected which includes a system prompt. The system prompt tells the agent it runs in a sandbox, to use `/home/daytona` for file operations, and the preview URL pattern so it can provide correct preview links.\n\n#### OpenCode Client\n\nThe client runs on your machine and talks to the server using the [OpenCode SDK](https://opencode.ai/docs/sdk/). `Session.create` sets up the SDK client and subscribes to the event stream so the client can show tool activity (e.g. “✓ Run: …”, “📝 Add …”) as the agent works:\n\n```ts\nconst client = createOpencodeClient({ baseUrl })\nconst sessionRes = await client.session.create({ body: { title: 'Daytona query' } })\nconst sessionId = sessionRes.data?.id\nif (!sessionId) throw new Error('Failed to create OpenCode session:' + sessionRes.error)\nconst events = await client.event.subscribe()\n```\n\nTo send a prompt, the client calls `session.prompt` and processes events from the existing stream to show tool activity:\n\n```ts\nconst promptPromise = this.client.session.prompt({\n  path: { id: this.sessionId },\n  body: { parts: [{ type: 'text', text: query } satisfies TextPartInput] },\n})\n\nfor await (const event of takeUntil(this.events.stream, promptPromise)) {\n  printEvent(this.sessionId, event)\n}\n```\n\n#### Main loop\n\nWhen the server is ready, the script creates a session and runs a readline loop:\n\n```ts\nconst session = await Session.create(baseUrl)\nconst rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n\nwhile (true) {\n  const query = await new Promise<string>((resolve) => rl.question('User: ', resolve))\n  if (!query.trim()) continue\n  await session.runQuery(query)\n}\n```\n\nThe readline loop waits for user input, sends it to the agent, and prints the response.\n\n**Key advantages:**\n\n- Secure, isolated execution in Daytona sandboxes\n- OpenCode SDK client in your terminal; server runs in the sandbox\n- Support for 75+ LLM providers\n- All agent code execution happens inside the sandbox\n- Automatic preview link generation for deployed services\n- Custom agent configuration for Daytona-specific workflows"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/opencode/opencode-web-agent.mdx",
    "content": "---\ntitle: Build a Coding Agent Using OpenCode Web and Daytona\ndescription: Step-by-step guide to running OpenCode's web interface, an open source coding agent, inside Daytona sandboxes.\n---\n\nimport { Image } from 'astro:assets'\n\nimport opencodeResult from '../../../../../assets/docs/images/opencode-web-agent.gif'\n\nThis guide demonstrates how to run the [OpenCode](https://opencode.ai/) coding agent inside a Daytona sandbox environment using OpenCode's easy-to-use [web interface](https://opencode.ai/docs/web/).\n\nThe agent can develop web apps, write code in any language, install dependencies, and run scripts. It supports over 75 different LLM providers and can start dev servers with preview links for live apps.\n\n---\n\n### 1. Workflow Overview\n\nWhen you launch the main script, a Daytona sandbox is created and OpenCode is installed inside it. OpenCode is configured with a custom Daytona-aware agent.\n\nThe script provides a preview link to access the web interface, where you can create, configure and interact with agent sessions:\n\n```\n$ npm run start\nCreating sandbox...\nInstalling OpenCode...\nStarting OpenCode web server...\nPress Ctrl+C to stop.\n\n\n             ▄\n█▀▀█ █▀▀█ █▀▀█ █▀▀▄ █▀▀▀ █▀▀█ █▀▀█ █▀▀█\n█░░█ █░░█ █▀▀▀ █░░█ █░░░ █░░█ █░░█ █▀▀▀\n▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀  ▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀\n\n  Web interface:      https://3000-1e0f775c-c01b-40e7-8c64-062fd3dadd75.proxy.daytona.works/\n```\n\nThe agent can host web apps and provide you with a preview link using the [Daytona Preview Links](/docs/en/preview-and-authentication/) feature. When your task involves running or previewing a web application, the agent automatically reasons about this need, hosts the app, and generates a preview link for you to inspect the live result:\n\n<Image\n  src={opencodeResult}\n  alt=\"Web app demo generated by OpenCode coding agent\"\n  width={600}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\nYou can continue interacting with your agent until you are finished. When you exit the program, the sandbox will be deleted automatically.\n\n### 2. Project Setup\n\n#### Clone the Repository\n\nFirst, clone the Daytona [repository](https://github.com/daytonaio/daytona.git) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/typescript/opencode\n```\n\n#### Configure Environment\n\nGet your API key from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys).\n\nCopy `.env.example` to `.env` and add your key:\n\n```bash\nDAYTONA_API_KEY=your_daytona_key\n```\n\n#### Local Usage\n\n:::note[Node.js Version]\nNode.js 18 or newer is required to run this example. Please ensure your environment meets this requirement before proceeding.\n:::\n\nInstall dependencies:\n\n```bash\nnpm install\n```\n\nRun the example:\n\n```bash\nnpm run start\n```\n\nThe OpenCode web interface will start and wait for you to open it in your browser.\n\n### Models and API Providers\n\nOpenCode works with [over 75 LLM providers](https://opencode.ai/docs/providers/), with a free provider selected by default. You can change the model or provider at any time using the menu below the prompt input in the web interface. If your chosen provider needs an API key, you’ll be prompted to enter it.\n\n#### Persisting API Keys\n\nTo persist API keys between uses of the script, you can set them as environment variables when creating the Daytona sandbox.\n\nFor example, to use an Anthropic API key, modify the `daytona.create()` call in `src/index.ts` to include your desired API key:\n\n```typescript\nsandbox = await daytona.create({\n  envVars: {\n    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY || '',\n  },\n})\n```\n\n### 3. Understanding the Script\n\nThis example consists of a Node.js script that installs, configures and runs OpenCode inside a Daytona sandbox.\n\n#### Initialization\n\nOn initialization, the main script:\n1. Creates a new [Daytona sandbox](/docs/en/sandboxes).\n2. Installs OpenCode globally inside the sandbox using npm with [process execution](/docs/en/process-code-execution#process-execution).\n3. Creates and uploads a [custom agent configuration](https://opencode.ai/docs/agents/) with Daytona-specific system prompt.\n4. Starts the OpenCode web server inside the sandbox on port 3000.\n5. Substitutes the URL in OpenCode's output with a [Daytona preview link](/docs/en/preview-and-authentication/) for the web interface.\n\n#### Main Script Code\n\nThe script creates a session and executes OpenCode as an asynchronous command, which allows it to stream output while keeping the process alive:\n\n```typescript\nconst command = await sandbox.process.executeSessionCommand(sessionId, {\n  command: `${envVar} opencode web --port ${OPENCODE_PORT}`,\n  runAsync: true,\n})\n```\n\nWhen OpenCode starts its web server, it prints a link to its web UI using a localhost address (e.g., `http://127.0.0.1:3000`). However, since the sandbox runs remotely, this localhost link is only accessible inside the sandbox itself. To solve this, the script parses OpenCode’s output, and replaces the URL with the corresponding Daytona preview link.\n\n```typescript\nconst opencodePreviewLink = await sandbox.getPreviewLink(OPENCODE_PORT)\nconst replaceUrl = (text: string) =>\n  text.replace(\n    new RegExp(`http:\\\\/\\\\/127\\\\.0\\\\.0\\\\.1:${OPENCODE_PORT}`, 'g'),\n    opencodePreviewLink.url\n  )\n```\n\n#### OpenCode Agent Configuration\n\nA custom system prompt is used to instruct the agent on how to use Daytona sandbox paths and preview links. This prompt is packaged into a JSON configuration string, which is passed to the sandbox as the `OPENCODE_CONFIG_CONTENT` environment variable:\n\n```json\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"default_agent\": \"daytona\",\n  \"agent\": {\n    \"daytona\": {\n      \"description\": \"Daytona sandbox-aware coding agent\",\n      \"mode\": \"primary\",\n      \"prompt\": \"You are running in a Daytona sandbox. Use the /home/daytona directory instead of /workspace for file operations. When running services on localhost, they will be accessible as: <PREVIEW_URL_PATTERN>. When starting a server, always give the user the preview URL to access it. When starting a server, start it in the background with & so the command does not block further instructions.\"\n    }\n  }\n}\n```\n\nThe `<PREVIEW_URL_PATTERN>` in the agent prompt is a template URL where `{PORT}` is a placeholder for the port to access on the Daytona sandbox. This template string is created by generating a [preview link](/docs/en/preview-and-authentication/) for a specific port number and then replacing the port number with `{PORT}`.\n\n#### Clean up\n\nWhen you press `Ctrl+C`, the script automatically cleans up by deleting the sandbox:\n\n```typescript\nprocess.once('SIGINT', async () => {\n  console.log('\\nCleaning up...')\n  if (sandbox) await sandbox.delete()\n  process.exit(0)\n})\n```\n\n**Key advantages:**\n\n- Secure, isolated execution in Daytona sandboxes\n- OpenCode Web interface accessible via browser\n- Support for 75+ LLM providers\n- All agent code execution happens inside the sandbox\n- Automatic preview link generation for deployed services\n- Custom agent configuration for Daytona-specific workflows\n- Clean resource management with automatic sandbox cleanup"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/reinforcement-learning/trl-grpo-training.mdx",
    "content": "---\ntitle: Train LLMs with Reinforcement Learning Using TRL and Daytona\ndescription: Use parallel Daytona sandboxes to train code-generating LLMs with TRL's GRPO trainer.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport { Image } from 'astro:assets'\n\nimport rewardsPlot from '../../../../../assets/docs/images/trl-grpo-rewards-plot.png'\n\nThis guide demonstrates how to use Daytona sandboxes to safely execute hundreds of code completions in parallel during reinforcement learning training.\n\nWe use [TRL](https://huggingface.co/docs/trl/)'s GRPOTrainer together with 500 Daytona sandboxes evaluating completions concurrently, in order to train the `Qwen3-1.7B-Base` model on some basic code-writing tasks.\n\n---\n\n### 1. Workflow Overview\n\nThis guide presents a simple, self-contained script that performs reinforcement learning training of `Qwen3-1.7B-Base`. In particular, we use **reinforcement learning with verifiable rewards**, with the reward being computed from the test pass rate of model-written functions.\n\nThe training loop consists of following steps:\n1. **Generate**: The model produces many code completions for each prompt (e.g., 250 completions per prompt per step)\n2. **Evaluate**: Each completion runs in its own Daytona sandbox against a test suite\n3. **Reward**: Completions that pass more tests get higher rewards; errors or banned patterns get negative rewards\n4. **Update**: GRPO reinforces completions that scored above their group average\n\nThe evaluation step happens in parallel across all 500 sandboxes. The sandboxes are spawned once at the start of the training and reused throughout it, and cleaned up after the training completes.\n\n### 2. Setup\n\n#### Clone the Repository\n\n:::note[GPU Requirement]\nThis guide is written to run on a single 80GB VRAM GPU. If you want to run it on a GPU with less VRAM, you can decrease `per_device_train_batch_size` parameter, possibly increasing `gradient_accumulation_steps` proportionally if you wish to keep effective batch size at 500.\n:::\n\nClone the [Daytona repository](https://github.com/daytonaio/daytona.git) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/python/reinforcement-learning/trl\n```\n\n#### Create Virtual Environment\n\n:::note[Python Version]\nPython 3.10 or higher is required. A GPU with 80GB+ VRAM is recommended for training.\n:::\n\n```bash\npython3 -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n```\n\n#### Install Dependencies\n\n```bash\npip install -e .\n```\n\nThis installs:\n- `daytona` - Daytona SDK for sandbox management\n- `trl[vllm]` - TRL with vLLM integration for fast inference\n- `datasets` - HuggingFace datasets library\n- `python-dotenv` - Environment variable management\n\n#### Configure Environment\n\nGet your Daytona API key from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys) and create a `.env` file:\n\n```bash\nDAYTONA_API_KEY=your_daytona_api_key\n```\n\n### 3. Understanding the Code\n\nLet's walk through the key components of the training script.\n\n#### Task Definitions\n\nThe script defines coding tasks as prompts with test cases. Note that the prompts are written in completion mode rather than QA mode because `Qwen3-1.7B-Base` is a base rather than an instruct model. Each task specifies what the model should generate and how to verify correctness:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    SORTING_PROMPT = \"\"\"# I've been fiddling with different ways to sort numbers in Python.\n    # At first I just used sorted() and list.sort(), but then I decided to try\n    # my hand at writing some original sorting functions. And I succeeded!\n    # I don't call sorted(), list.sort(), heapq, or use any imports here - just plain\n    # Python and an original algorithm.\n    def sort_numbers(xs: list[int]) -> list[int]:\n        \\\"\\\"\\\"Sort a list of integers in ascending order.\n\n        Args:\n            xs: A list of integers to be sorted.\n\n        Returns:\n            A new list containing the same integers, sorted from smallest to largest.\n        \\\"\\\"\\\"\n    \"\"\"\n\n    TASKS = {\n        \"sorting\": {\n            \"prompt\": SORTING_PROMPT,\n            \"func_name\": \"sort_numbers\",\n            \"banned_patterns\": [\"sorted(\", \".sort(\", \"heapq\", \"import \", \"__import__\"],\n            \"tests\": [\n                \"[]\",\n                \"[1, 3, 2]\",\n                \"[random.randint(-1000, 1000) for _ in range(200)]\",\n                \"[random.randint(-100, 100) for _ in range(1000)]\",\n                \"list(range(0, 100)) + list(range(200, 100, -1)) + list(range(200, 300))\",\n            ],\n            \"reference\": \"sorted\",\n        },\n        # Additional tasks can be added here...\n    }\n    ```\n  </TabItem>\n</Tabs>\n\nEach task includes:\n- **prompt**: The code context the model continues from\n- **func_name**: The function name being implemented\n- **banned_patterns**: Patterns that disqualify a completion (e.g., using built-in `sorted()`)\n- **tests**: Test inputs to verify correctness\n- **reference**: The reference implementation to compare against\n\n#### How Prompts Become Completions\n\nWhen the model receives the sorting prompt, it continues the text as if completing a Python file. A typical model output might look like:\n\n```\n    if len(xs) <= 1:\n        return xs\n    pivot = xs[len(xs) // 2]\n    left = [x for x in xs if x < pivot]\n    middle = [x for x in xs if x == pivot]\n    right = [x for x in xs if x > pivot]\n    return sort_numbers(left) + middle + sort_numbers(right)\n\n# Example usage:\nprint(sort_numbers([3, 1, 4, 1, 5, 9, 2, 6]))\n```\n\nNotice the model generates the indented function body, but may also add extra content after (comments, example usage, etc.). The `sanitize_completion` function extracts only the indented lines that form the function body:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def sanitize_completion(text: str) -> str:\n        # Take lines until the first unindented line\n        lines = text.splitlines()\n        kept: List[str] = []\n        for line in lines:\n            if line and (not line.startswith(\"    \")):\n                break\n            kept.append(line)\n        return \"\\n\".join(kept).rstrip()\n    ```\n  </TabItem>\n</Tabs>\n\nAfter sanitization, the example above becomes just the function body:\n\n```python\n    if len(xs) <= 1:\n        return xs\n    pivot = xs[len(xs) // 2]\n    left = [x for x in xs if x < pivot]\n    middle = [x for x in xs if x == pivot]\n    right = [x for x in xs if x > pivot]\n    return sort_numbers(left) + middle + sort_numbers(right)\n```\n\n#### Sandbox Pool Management\n\nWe create the sandbox pool upfront and reuse sandboxes throughout training:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    EFFECTIVE_BATCH_SIZE = 500\n    # We evaluate each completion concurrently, in its own sandbox,\n    # so we spawn EFFECTIVE_BATCH_SIZE number of sandboxes.\n\n    async def _create_sandbox_pool_async(\n        daytona: AsyncDaytona, n: int = 10\n    ) -> List[AsyncSandbox]:\n        print(f\"Creating {n} sandboxes...\")\n        tasks = [daytona.create() for _ in range(n)]\n        sandboxes = await asyncio.gather(*tasks)\n        print(f\"Successfully created all {len(sandboxes)} sandboxes\")\n        return list(sandboxes)\n\n\n    async def _cleanup_sandbox_pool_async(sandbox_pool: List[AsyncSandbox]) -> None:\n        if not sandbox_pool:\n            return\n        print(\"Cleaning up sandboxes...\")\n        tasks = [sandbox.delete() for sandbox in sandbox_pool]\n        results = await asyncio.gather(*tasks, return_exceptions=True)\n        for r in results:\n            if isinstance(r, Exception):\n                print(f\"  Sandbox delete error: {type(r).__name__}: {r}\")\n        print(\"All sandboxes cleaned up\")\n    ```\n  </TabItem>\n</Tabs>\n\nThe pool size (500) is chosen to match the total batch size (`per_device_train_batch_size * gradient_accumulation_steps`), ensuring every completion in a batch can be evaluated in parallel.\n\n#### Code Evaluation\n\nThe main evaluation function ties everything together - it sanitizes the completion, checks for banned patterns, builds the test harness, executes it in a sandbox, and parses the results:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    async def evaluate_single_completion_async(\n        sandbox: AsyncSandbox,\n        raw_completion: str,\n        prompt: str,\n    ) -> EvalResult:\n        task = PROMPT_TO_TASK[prompt]\n        num_task_tests = len(task[\"tests\"])\n        body = sanitize_completion(raw_completion)\n\n        if not body.strip():\n            return _fail_result(num_task_tests)\n        if has_banned_pattern(body, task):\n            return _fail_result(num_task_tests)\n\n        code = build_test_harness(task, body)\n\n        try:\n            response = await sandbox.code_interpreter.run_code(\n                code, timeout=MAX_TIMEOUT_SECONDS\n            )\n        except DaytonaTimeoutError:\n            print(\n                f\"Completion timed out after {MAX_TIMEOUT_SECONDS}s \"\n                f\"in sandbox {getattr(sandbox, 'id', '?')}\"\n            )\n            return _fail_result(num_task_tests)\n        except Exception as e:\n            print(\n                f\"Error evaluating completion in sandbox {getattr(sandbox, 'id', '?')}: \"\n                f\"{type(e).__name__}: {e}\",\n            )\n            return _fail_result(num_task_tests)\n\n        if response.error is not None:\n            return _fail_result(num_task_tests)\n        raw_output = response.stdout.strip()\n        if not raw_output:\n            return _fail_result(num_task_tests)\n        last_line = raw_output.splitlines()[-1]\n        try:\n            results = json.loads(last_line)\n        except Exception:\n            return _fail_result(num_task_tests)\n        correct = results.get(\"results\", [])\n\n        return {\n            \"no_error\": True,\n            \"num_passed\": sum(bool(x) for x in correct),\n            \"num_tests\": len(correct),\n        }\n    ```\n  </TabItem>\n</Tabs>\n\n#### The Test Harness\n\nThe `build_test_harness` function combines the original prompt, the model's completion, and a test runner into Python code that ultimately executes on the sandbox:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def build_test_harness(task: Dict[str, Any], function_body: str) -> str:\n        prompt = task[\"prompt\"]\n        func_name = task[\"func_name\"]\n        reference_function = task[\"reference\"]\n        tests = task[\"tests\"]\n\n        tests_tuple = \",\\n        \".join(tests)\n\n        return f\"\"\"{prompt}\n{function_body}\n\nimport json\nimport random\nrandom.seed(0)\n\ndef _kadane(xs):\n        max_sum = current = xs[0]\n        for x in xs[1:]:\n            current = max(x, current + x)\n            max_sum = max(max_sum, current)\n        return max_sum\n\ndef _run_tests():\n        tests = (\n            {tests_tuple}\n        )\n        results = []\n        for xs in tests:\n            try:\n                out = {func_name}(xs.copy())\n                expected = {reference_function}(xs.copy())\n                results.append(out == expected)\n            except Exception:\n                results.append(False)\n        print(json.dumps({{\"results\": results}}))\n\nif __name__ == \"__main__\":\n        _run_tests()\n\"\"\"\n    ```\n  </TabItem>\n</Tabs>\n\nFor the sorting task with a quicksort completion, the assembled code looks like:\n\n```python\n# I've been fiddling with different ways to sort numbers in Python...\ndef sort_numbers(xs: list[int]) -> list[int]:\n    \"\"\"Sort a list of integers in ascending order...\"\"\"\n    if len(xs) <= 1:\n        return xs\n    pivot = xs[len(xs) // 2]\n    left = [x for x in xs if x < pivot]\n    middle = [x for x in xs if x == pivot]\n    right = [x for x in xs if x > pivot]\n    return sort_numbers(left) + middle + sort_numbers(right)\n\nimport json\nimport random\nrandom.seed(0)\n\ndef _run_tests():\n    tests = (\n        [],\n        [1, 3, 2],\n        [random.randint(-1000, 1000) for _ in range(200)],\n        # ... more tests\n    )\n    results = []\n    for xs in tests:\n        try:\n            out = sort_numbers(xs.copy())\n            expected = sorted(xs.copy())\n            results.append(out == expected)\n        except Exception:\n            results.append(False)\n    print(json.dumps({\"results\": results}))\n\nif __name__ == \"__main__\":\n    _run_tests()\n```\n\nWhen executed in the sandbox, this prints JSON to stdout:\n\n```json\n{\"results\": [true, true, true, false, true]}\n```\n\nThe evaluation function parses this JSON to count how many tests passed.\n\n#### Banned Pattern Detection\n\nBefore running code in the sandbox, we check for banned patterns. This prevents the model from \"cheating\" by using built-in functions:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def has_banned_pattern(text: str, task: Dict[str, Any]) -> bool:\n        banned = task.get(\"banned_patterns\", [])\n        if not banned:\n            return False\n        lowered = text.lower()\n        return any(p.lower() in lowered for p in banned)\n    ```\n  </TabItem>\n</Tabs>\n\nFor the sorting task, banned patterns include `sorted(`, `.sort(`, `heapq`, and `import`. If the model generates `return sorted(xs)`, it gets a reward of -1.0 instead of being executed - we want the model to learn to write actual sorting algorithms, not to call built-in functions.\n\n#### Parallel Batch Evaluation\n\nThe batch evaluator distributes completions across the sandbox pool:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    async def _evaluate_batch_async(\n        sandbox_pool: List[AsyncSandbox], completions: List[str], prompts: List[str]\n    ) -> List[EvalResult]:\n        print(\n            f\"Evaluating {len(completions)} completions in parallel across \"\n            f\"{len(sandbox_pool)} sandboxes...\"\n        )\n\n        async def run_one(\n            i: int, sandbox: AsyncSandbox, completion: str, prompt: str\n        ) -> EvalResult:\n            task = PROMPT_TO_TASK[prompt]\n            num_task_tests = len(task[\"tests\"])\n            try:\n                stats = await evaluate_single_completion_async(sandbox, completion, prompt)\n                print(f\"  Completion {i + 1}/{len(completions)} done\")\n                return stats\n            except Exception as e:\n                print(\n                    f\"  Completion {i + 1}/{len(completions)} failed: \"\n                    f\"{type(e).__name__}: {e}\"\n                )\n                return _fail_result(num_task_tests)\n\n        tasks = [\n            run_one(i, sandbox_pool[i % len(sandbox_pool)], completion, prompt)\n            for i, (completion, prompt) in enumerate(zip(completions, prompts))\n        ]\n\n        stats_list = await asyncio.gather(*tasks)\n        print(f\"  Done: {len(completions)}/{len(completions)} completions evaluated\")\n\n        return stats_list\n    ```\n  </TabItem>\n</Tabs>\n\nEach completion is assigned to a sandbox using round-robin distribution (`i % len(sandbox_pool)`), ensuring even load distribution.\n\n#### Reward Function\n\nThe reward function receives the results from the sandboxes and computes the corresponding scalar reward.\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def reward_func(prompts, completions, **kwargs):\n        stats_list = run_async(\n            _evaluate_batch_async(sandbox_pool, completions, prompts)\n        )\n        rewards = []\n        for s in stats_list:\n            if not s[\"no_error\"]:\n                rewards.append(-1.0)\n            elif s[\"num_tests\"] == 0:\n                rewards.append(0.0)\n            else:\n                rewards.append(s[\"num_passed\"] / s[\"num_tests\"])\n        return rewards\n    ```\n  </TabItem>\n</Tabs>\n\nThe reward scheme:\n- **-1.0**: Error, timeout, or banned pattern detected\n- **0.0**: No tests were present (shouldn't happen with valid tasks)\n- **0.0 to 1.0**: Fraction of tests passed\n\n#### Bridging Sync and Async\n\nTRL's `GRPOTrainer` expects a synchronous reward function, but the Daytona SDK uses async/await for parallel sandbox operations. We bridge these two worlds with a helper:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def main():\n        # Create a dedicated event loop for async operations\n        loop = asyncio.new_event_loop()\n        asyncio.set_event_loop(loop)\n\n        def run_async(coro: Awaitable[Any]) -> Any:\n            \"\"\"Run async code from sync context.\"\"\"\n            return loop.run_until_complete(coro)\n\n        # ... training code ...\n\n        def reward_func(prompts, completions, **kwargs):\n            # This sync function is called by TRL\n            # We use run_async to call our async evaluation\n            stats_list = run_async(\n                _evaluate_batch_async(sandbox_pool, completions, prompts)\n            )\n            # ... compute rewards ...\n            return rewards\n    ```\n  </TabItem>\n</Tabs>\n\nThis pattern lets us keep the async parallelism benefits of the Daytona SDK while working within TRL's synchronous training loop. The `run_async` helper blocks until all 500 parallel sandbox evaluations complete, then returns the results.\n\n#### Training Configuration\n\nThe GRPO trainer is configured with these parameters:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    training_args = GRPOConfig(\n        output_dir=\"training_results\",\n        per_device_train_batch_size=20,\n        # batch size chosen so the training runs comfortably on a single 80GB GPU,\n        # if running this on a GPU with less memory, reduce the batch size accordingly\n        gradient_accumulation_steps=25,\n        num_generations=EFFECTIVE_BATCH_SIZE // len(TASKS),\n        max_prompt_length=256,\n        max_completion_length=512,\n        learning_rate=8e-6,\n        num_train_epochs=1,\n        logging_steps=1,\n        report_to=\"none\",\n        max_steps=8,\n        bf16=True,\n        use_vllm=True,\n        vllm_mode=\"colocate\",\n        vllm_gpu_memory_utilization=0.15,\n        gradient_checkpointing=True,\n        loss_type=\"dapo\",\n        beta=0.01,\n    )\n    ```\n  </TabItem>\n</Tabs>\n\nKey settings explained:\n\n**Batch size and sandbox pool alignment:**\n```\nper_device_train_batch_size (20) × gradient_accumulation_steps (25) = 500\n```\nThis equals `EFFECTIVE_BATCH_SIZE`. Each training step generates exactly 500 completions, and we have exactly 500 sandboxes - so every completion evaluates in parallel with no waiting. If we had fewer sandboxes, some completions would queue up. If we had more, sandboxes would sit idle.\n\n**vLLM colocate mode:**\n```python\nuse_vllm=True,\nvllm_mode=\"colocate\",\nvllm_gpu_memory_utilization=0.15,\n```\nThis runs vLLM for fast inference on the same GPU as training. We use 15% of the GPU's memory for model generation, and the rest for training (optimizer states).\n\n**Generation settings:**\n- `num_generations=EFFECTIVE_BATCH_SIZE // len(TASKS)`: Generate 250 completions per prompt (500 / 2 tasks). With 2 prompts (sorting and max_subarray), that's 500 total per step\n- `max_completion_length=512`: Limit completion length to prevent runaway generation\n\n### 4. Running the Training\n\nStart training with:\n\n```bash\npython train.py\n```\n\nYou'll see output like:\n\n```\nCreating 500 sandboxes...\nSuccessfully created all 500 sandboxes\nEvaluating 500 completions in parallel across 500 sandboxes...\n  Completion 1/500 done\n  Completion 2/500 done\n  ...\n  Done: 500/500 completions evaluated\n```\n\nAfter training completes, metrics are saved to `training_results/metrics.jsonl` and the model is saved as `training_results/checkpoint-8`.\n\n### 5. Example Evaluation Walkthrough\n\nLet's trace through what happens when evaluating a single completion:\n\n**Step 1: Model generates a completion**\n\nThe model receives the sorting prompt and generates:\n```\n    if len(xs) <= 1:\n        return xs\n    pivot = xs[0]\n    less = [x for x in xs[1:] if x <= pivot]\n    greater = [x for x in xs[1:] if x > pivot]\n    return sort_numbers(less) + [pivot] + sort_numbers(greater)\n\n# Test\nprint(sort_numbers([3, 1, 2]))\n```\n\n**Step 2: Sanitization extracts the function body**\n\n`sanitize_completion` keeps only the indented lines:\n```python\n    if len(xs) <= 1:\n        return xs\n    pivot = xs[0]\n    less = [x for x in xs[1:] if x <= pivot]\n    greater = [x for x in xs[1:] if x > pivot]\n    return sort_numbers(less) + [pivot] + sort_numbers(greater)\n```\n\n**Step 3: Check for banned patterns**\n\n`has_banned_pattern` scans for `sorted(`, `.sort(`, `heapq`, `import`. None found, so we proceed.\n\n**Step 4: Build the test harness**\n\n`build_test_harness` assembles the full script: prompt + completion + test runner. This becomes ~50 lines of executable Python.\n\n**Step 5: Execute in sandbox**\n\n```python\nresponse = await sandbox.code_interpreter.run_code(code, timeout=1)\n```\n\nThe sandbox runs the code and returns within the 1-second timeout.\n\n**Step 6: Parse results**\n\nThe test runner printed:\n```json\n{\"results\": [true, true, true, true, true]}\n```\n\nWe parse this from `response.stdout`:\n```python\nresults = json.loads(response.stdout.strip().splitlines()[-1])\n# {\"results\": [true, true, true, true, true]}\n```\n\n**Step 7: Compute reward**\n\nAll 5 tests passed:\n```python\nreward = 5 / 5  # = 1.0\n```\n\nThis completion gets a perfect reward of 1.0, reinforcing the model to generate similar quicksort implementations.\n\n### 6. Training Results\n\nThe plot below shows average rewards over training steps. At the start, the model is very rarely writing functions that meet the task specifications, and it is often writing code that either errors out or times out. Given our large effective batch size of 500, the model achieves near-perfect performance after only 8 steps.\n\n<Image\n  src={rewardsPlot}\n  alt=\"Rewards over training steps showing improvement\"\n  width={700}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\n### 7. Adding Custom Tasks\n\nTo add a new coding task, extend the `TASKS` dictionary:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    TASKS = {\n        \"your_task\": {\n            \"prompt\": \"Your prompt here...\",\n            \"func_name\": \"function_name\",\n            \"banned_patterns\": [\"patterns\", \"to\", \"ban\"],\n            \"tests\": [\n                \"test_input_1\",\n                \"test_input_2\",\n            ],\n            \"reference\": \"reference_function\",\n        },\n    }\n    ```\n  </TabItem>\n</Tabs>\n\nThe reference function should be defined in the test harness that `build_test_harness` generates.\n\n### 8. Configuration Options\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| `EFFECTIVE_BATCH_SIZE` | 500 | Effective batch size, also equal to the number of parallel sandboxes |\n| `MAX_TIMEOUT_SECONDS` | 1 | Timeout per code execution |\n| `MODEL_NAME` | `Qwen/Qwen3-1.7B-Base` | Base model to train |\n\n:::tip[Scaling Tips]\n- Keep `per_device_train_batch_size * gradient_accumulation_steps` equal to `EFFECTIVE_BATCH_SIZE` for optimal parallelism\n- Increase `MAX_TIMEOUT_SECONDS` for tasks with more (algorithmically) complex test cases\n:::\n\n---\n\n**Key advantages of this approach:**\n\n- **Massive parallelism**: 500 sandboxes evaluate completions simultaneously\n- **Safe execution**: Generated code runs in isolated environments, protecting your system\n- **Fast feedback**: vLLM + parallel evaluation minimizes training iteration time\n- **Extensible**: Add new coding tasks by defining prompts and test cases\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/rlm/dspy-rlms.mdx",
    "content": "---\ntitle: Run DSPy RLMs on Daytona\ndescription: Use DSPy's RLM module with a Daytona-backed interpreter to safely execute LLM-generated Python code in an isolated cloud sandbox.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport { Image } from 'astro:assets'\n\nimport wealthTrajectories from '../../../../../assets/docs/images/wealth-trajectories.png'\n\n[DSPy](https://dspy.ai/)'s RLM implements [recursive language models](https://arxiv.org/abs/2512.24601), a system where an LLM writes Python code through which it can pass parts of its context to LLM calls, leading to significantly enhanced long-context reasoning.\n\nThe generated code runs in a REPL, and in this guide we use and present `DaytonaInterpreter`, which plugs into DSPy as the code-execution backend so that all generated code runs inside an isolated Daytona cloud sandbox rather than on your machine.\n\n---\n\n### 1. Setup\n\n#### Clone the Repository\n\nClone the [Daytona repository](https://github.com/daytonaio/daytona.git) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/python/dspy-rlms\n```\n\n#### Create Virtual Environment\n\n```bash\npython3.10 -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n```\n\n#### Install Dependencies\n\n```bash\npip install -e .\n```\n\nThis installs the DSPy framework and the Daytona SDK. To also run the included demo (which plots results with matplotlib), use\n\n```bash\npip install -e \".[demo]\"\n```\n\n#### Configure Environment\n\nCreate a `.env` file with your API keys:\n\n```bash\ncp .env.example .env\n# Edit .env with your keys\n```\n\nThe file needs two variables:\n\n```bash\nDAYTONA_API_KEY=your_daytona_api_key\nOPENROUTER_API_KEY=your_openrouter_api_key  # or OPENAI_API_KEY / ANTHROPIC_API_KEY\n```\n\n:::note\nGet your Daytona API key from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys). The LLM provider key depends on which model you configure in your code — the examples use OpenRouter.\n:::\n\n### 2. Basic Usage\n\nThe following example shows the basic setup — configure a model, create a `DaytonaInterpreter`, and pass it to an RLM. The generated code can call `llm_query()` to delegate semantic work back to the LLM:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import dspy\n    from dotenv import load_dotenv\n    from daytona_interpreter import DaytonaInterpreter\n\n    load_dotenv()\n\n    lm = dspy.LM(\"openrouter/google/gemini-3-flash-preview\")\n    dspy.configure(lm=lm)\n\n    interpreter = DaytonaInterpreter()\n\n    rlm = dspy.RLM(\n        signature=\"documents: list[str], question: str -> answer: str\",\n        interpreter=interpreter,\n        verbose=True,\n    )\n\n    documents = [...]  # your documents\n    result = rlm(documents=documents, question=\"Summarize the key findings across these documents.\")\n    print(result.answer)\n\n    interpreter.shutdown()\n    ```\n\n  </TabItem>\n</Tabs>\n\nInside the sandbox, the RLM might loop over the documents, call `llm_query()` to summarize each one, then aggregate the results with Python before calling `SUBMIT(answer=...)`.\n\n### 3. Workflow Overview\n\nEach RLM call runs an iterative REPL loop. The LLM writes Python code, the code executes in a Daytona sandbox, and the output is fed back to the LLM for the next iteration. Crucially, the generated code can call `llm_query()` to invoke a sub-LLM call — this is how the LLM delegates semantic work (understanding, extraction, classification) to itself while keeping the orchestration logic in Python.\n\n1. **Prompt** — RLM sends the task inputs and previous turns to the LLM\n2. **Code** — The LLM responds with reasoning and a Python code snippet\n3. **Execute** — The code runs inside a Daytona sandbox; any `llm_query()` calls are bridged back to the host LLM\n4. **Repeat** — Steps 1–3 repeat until the code calls `SUBMIT()` or the iteration limit is reached\n\n#### How Bridging Works\n\nStep 3 above mentions that `llm_query()` calls are \"bridged back to the host.\" Here's a diagram and an explanation of that process:\n\n```\nHost Process                                    Daytona Sandbox\n┌──────────────────────────────┐                ┌──────────────────────────────┐\n│      DaytonaInterpreter      │                │    Broker Server (Flask)     │\n│                              │                │                              │\n│  • polls the broker for      │   tool call,   │  • accepts requests from     │\n│    pending requests          │ e.g. llm_query │    the wrapper functions     │\n│                              │◄───────────────│                              │\n│  • calls the LLM API         │                │  • queues them for the host  │\n│    or runs tool functions    │    result      │  • returns results once the  │\n│  • posts results back        │───────────────►│    host replies              │\n│                              │                │                              │\n└──────────────────────────────┘                │      Generated Code          │\n               │                                │  • llm_query()               │\n               ▼                                │  • llm_query_batched()       │\n           LLM API                              │  • custom tool wrappers      │\n                                                └──────────────────────────────┘\n```\n\nWhen `DaytonaInterpreter` starts, it launches a small Flask broker server inside the sandbox and injects wrapper functions (`llm_query`, `llm_query_batched`, and any custom tools you provide). These wrappers POST requests to the broker and block until a result arrives. On the host side, a polling loop picks up pending requests, executes them (e.g. calls the LLM API or runs your tool function), and posts the results back to the broker. From the generated code's perspective, the wrappers look and behave like ordinary Python functions.\n\nCustom tools passed via the `tools` dict use the same mechanism, so that the host generates a matching wrapper inside the sandbox and bridges calls identically.\n\nState persists across iterations: variables, imports, and function definitions all carry over.\n\n#### Sub-LLM Calls\n\nTwo built-in functions are available inside the sandbox:\n\n- **`llm_query(prompt)`** — send a single natural-language prompt to the LLM, get a string back\n- **`llm_query_batched(prompts)`** — send multiple prompts concurrently, get a list of strings back\n\nThese execute on the host (they need LLM API access) and are bridged into the sandbox. From the generated code's perspective they are ordinary Python functions that take strings and return strings. This is what makes the pattern powerful: the LLM can write a `for` loop over 100 chapters, call `llm_query_batched()` to extract structured data from each one in parallel, then aggregate and use the results with additional Python code.\n\n### 4. Example Walkthrough\n\nThe included `demo.py` shows a realistic use of sub-LLM calls: literary analysis of _The Count of Monte Cristo_ — a ~1,300-page novel with 117 chapters — tracking the wealth trajectory of five major characters. The RLM uses `llm_query_batched()` to process chapters in parallel batches, then aggregates the results with Python.\n\n#### How the Demo Works\n\nThe script fetches the full novel text from Project Gutenberg, splits it into chapters, and passes them to an RLM configured with a typed signature:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    interpreter = DaytonaInterpreter()\n\n    rlm = dspy.RLM(\n        signature=\"chapters: list[str], task: str -> wealth_data: list[dict]\",\n        interpreter=interpreter,\n        max_iterations=40,\n        max_llm_calls=500,\n        verbose=True,\n    )\n\n    chapters = fetch_chapters()\n    print(f\"Fetched {len(chapters)} chapters\")\n\n    TASK = (\n        \"Analyze the economic trajectory of each major character across the novel. \"\n        \"For each chapter where a character's wealth status is mentioned or implied, \"\n        \"produce a dict with keys: chapter (int), character (str), wealth (int 1-10 \"\n        \"where 1=destitute and 10=richest in Paris), and event (str, brief description \"\n        \"of what changed). Track the following characters: Dantès, Danglars, Fernand/\"\n        \"Morcerf, Villefort, and Mercédès. You need to cover each chapter in the book.\"\n    )\n\n    result = rlm(chapters=chapters, task=TASK)\n    wealth_data = result.wealth_data\n    ```\n\n  </TabItem>\n</Tabs>\n\n#### What the RLM Does\n\nThe RLM's generated code follows a pattern typical of sub-LLM workloads:\n\n1. **Batch the input** — Split the 117 chapters into manageable groups\n2. **Fan out with `llm_query_batched()`** — For each batch, send a prompt like _\"Extract wealth events from these chapters as JSON\"_ — the sub-LLM calls run concurrently on the host\n3. **Parse and accumulate** — Each sub-call returns a string; the code parses the JSON and appends to a running list\n4. **Iterate** — Repeat for the next batch; state (the accumulated list) persists across REPL iterations\n5. **Submit** — Once all chapters are processed, call `SUBMIT(wealth_data=accumulated_results)`\n\nThis is the core RLM pattern: Python handles the data plumbing (batching, parsing, aggregating) while `llm_query_batched()` handles the parts that need language understanding (reading prose, identifying wealth events, rating severity).\n\n#### Running the Demo\n\n```bash\npython demo.py\n```\n\nThe script plots the results with matplotlib after the RLM finishes.\n\n:::tip\nThe demo runs up to 40 iterations and 500 sub-LLM calls. Depending on the model and provider, a full run may take several minutes and consume significant API credits.\n:::\n\n#### Results\n\nThe output is a list of `{chapter, character, wealth, event}` dictionaries that the script plots as smoothed time series:\n\n<Image\n  src={wealthTrajectories}\n  alt=\"Wealth trajectory chart showing five character arcs across 117 chapters of The Count of Monte Cristo.\"\n  width={700}\n  style=\"max-width: 100%; height: auto; margin: 1rem 0;\"\n/>\n\n### 5. Conclusion\n\nRLMs combine the LLM's language understanding with Python's ability to loop, branch, and aggregate — the generated code calls the LLM whenever it needs semantic reasoning and handles everything else with ordinary computation. `DaytonaInterpreter` makes this safe to run by executing all generated code in an isolated Daytona cloud sandbox:\n\n- **Sub-LLM recursion** — `llm_query()` and `llm_query_batched()` are bridged from the sandbox to the host, letting generated code invoke the LLM for semantic tasks like extraction, classification, and summarisation\n- **Isolation** — All generated code runs in a Daytona cloud sandbox, not on your machine\n- **Persistent state** — Variables, imports, and definitions survive across REPL iterations, so the LLM can accumulate results across batches\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/rlm/index.mdx",
    "content": "---\ntitle: Recursive Language Model Guides\ndescription: Guides for building and running Recursive Language Models (RLMs) with Daytona\ntableOfContents: false\n---\n\nimport GuidesList from '@components/GuidesList.astro'\n\nGuides for building and running Recursive Language Models with Daytona.\n\n<GuidesList category=\"rlm\" />\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/guides/rlm/recursive-language-models.mdx",
    "content": "---\ntitle: Build deep Recursive Language Models\ndescription: Implement recursive language model agents where each agent runs in its own isolated Daytona sandbox.\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nThis guide demonstrates how to build a recursive language model (RLM) agent system that uses Daytona sandboxes, based on the approach pioneered in [Recursive Language Models](https://arxiv.org/abs/2512.24601) (Zhang, Kraska, Khattab) and further explored by [Prime Intellect](https://www.primeintellect.ai/blog/rlm).\n\nWhile the original paper and Prime Intellect's implementation focus on single-level recursion (depth=1), this guide extends the concept to **unlimited recursion depth** — agents can spawn sub-agents, which can spawn their own sub-agents, and so on. Each agent runs in its own isolated Daytona sandbox with a fresh clone of the target repository.\n\n---\n\n### 1. Workflow Overview\n\nThe system implements a recursive agent architecture where agents can delegate subtasks to child agents:\n\n1. **Initialize**: Root agent receives a task and gets a Daytona sandbox with a fresh repository clone\n2. **Iterate**: Agent runs a loop: LLM call → extract Python code → execute in REPL\n3. **Delegate**: Code can call `rlm_query()` to spawn sub-agents, each with their own sandbox\n4. **Aggregate**: Sub-agents return results; parent synthesizes findings and optionally runs more code\n5. **Complete**: Root agent receives all sub-agent results, produces a git patch; all sandboxes are cleaned up\n\n```\nRoot Agent (depth=0)\n├── Sub-Agent A (depth=1)\n│   ├── Sub-Agent A1 (depth=2)\n│   └── Sub-Agent A2 (depth=2)\n└── Sub-Agent B (depth=1)\n    ├── Sub-Agent B1 (depth=2)\n    └── Sub-Agent B2 (depth=2)\n```\n\nEach agent runs in its own isolated Daytona sandbox with a fresh repository clone, enabling parallel exploration.\n\n### 2. Setup\n\n#### Clone the Repository\n\nClone the [Daytona repository](https://github.com/daytonaio/daytona.git) and navigate to the example directory:\n\n```bash\ngit clone https://github.com/daytonaio/daytona.git\ncd daytona/guides/python/recursive-language-models\n```\n\n#### Create Virtual Environment\n\n```bash\npython3.10 -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n```\n\n#### Install Dependencies\n\n```bash\npip install -e .\n```\n\nThis installs:\n- `daytona` - Daytona SDK for sandbox management\n- `litellm` - Unified LLM interface for any provider\n- `typer` - CLI framework\n- `pyyaml` - Configuration parsing\n\n#### Configure Environment\n\nGet your Daytona API key from the [Daytona Dashboard](https://app.daytona.io/dashboard/keys) and create a `.env` file:\n\n```bash\nDAYTONA_API_KEY=your_daytona_api_key\nLLM_API_KEY=your_llm_api_key\n```\n\nThe `LLM_API_KEY` is used via [LiteLLM](https://docs.litellm.ai/), supporting OpenRouter, OpenAI, Anthropic, and other providers.\n\n### 3. Running an Agent\n\nWith setup complete, let's run an agent. Here's an example that investigates TODO comments in scikit-learn:\n\n```bash\npython run.py https://github.com/scikit-learn/scikit-learn \\\n  -p \"Investigate TODO comments across this repository. Spawn sub-agents to explore different modules. Find the easiest TODO and fix it.\"\n```\n\nThis spawns a root agent that explores the codebase, delegates to sub-agents for parallel investigation, and produces a git patch fixing the easiest TODO it finds. We'll walk through the results and trace the execution in detail later, but first, let's look at how the code works.\n\n#### CLI Options\n\n| Option | Description |\n|--------|-------------|\n| `repo` | GitHub repository URL (required) |\n| `-p, --prompt` | Task prompt for the agent (required) |\n| `-b, --branch` | Branch name (optional) |\n| `--commit` | Specific commit SHA (optional) |\n| `-c, --config` | Path to config file (default: `config.yaml`) |\n| `-o, --output` | Output file for patch (default: stdout) |\n\n### 4. Understanding the Code\n\nLet's walk through the key components of the agent system.\n\n#### Agent Execution Loop\n\nEach agent runs an iteration loop that calls the LLM, extracts code blocks, and executes them. The core loop in `agent.py`:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def _run_loop(self) -> None:\n        \"\"\"Run the main iteration loop.\"\"\"\n        system_prompt = build_system_prompt(depth=self.depth)\n        messages = [{\"role\": \"system\", \"content\": system_prompt}]\n        execution_result = None\n\n        for iteration in range(self.config.rlm.max_iterations):\n            # Check global timeout\n            if self._is_timeout():\n                break\n\n            # Build user prompt with previous execution result\n            user_prompt = build_user_prompt(iteration, execution_result)\n            messages.append({\"role\": \"user\", \"content\": user_prompt})\n\n            # Get model completion\n            response = self.client.completion(messages)\n            messages.append({\"role\": \"assistant\", \"content\": response})\n\n            # Execute code blocks in REPL\n            repl_result = self.repl.execute_response(response)\n\n            # Check for final answer\n            if repl_result.final_answer is not None:\n                self._result = repl_result.final_answer\n                break\n\n            # Format result for next iteration\n            execution_result = format_execution_result(...)\n    ```\n  </TabItem>\n</Tabs>\n\nEach iteration:\n1. Builds a prompt with context from previous execution\n2. Gets an LLM completion\n3. Extracts and executes Python code blocks\n4. Checks if the agent called `FINAL()` to submit results\n5. Formats the output for the next iteration\n\n#### Sub-Agent Spawning\n\nWhen agent code calls `rlm_query()`, a new sub-agent is created with its own sandbox:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def _handle_rlm_query(self, task: str) -> str:\n        \"\"\"Spawn a sub-agent for a specific task.\"\"\"\n        # Check sandbox budget\n        if not self.sandbox_manager.budget.can_acquire():\n            return \"Error: sandbox budget exhausted\"\n\n        # Create sub-agent at depth + 1\n        sub_agent = RLMAgent(\n            client=self.client,\n            sandbox_manager=self.sandbox_manager,\n            config=self.config,\n            depth=self.depth + 1,\n            task=task,\n            # ... other params\n        )\n\n        # Run sub-agent (blocking)\n        result = sub_agent.run()\n\n        # Return result, truncated if necessary\n        return result.result or \"No result\"\n    ```\n  </TabItem>\n</Tabs>\n\nFor parallel spawning, `rlm_query_batched()` uses a thread pool:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    def _handle_rlm_query_batched(self, tasks: list[str]) -> list[str]:\n        \"\"\"Spawn multiple sub-agents in parallel.\"\"\"\n        results = [\"\"] * len(tasks)\n\n        with ThreadPoolExecutor(max_workers=10) as executor:\n            future_to_idx = {\n                executor.submit(self._handle_rlm_query, task): i\n                for i, task in enumerate(tasks)\n            }\n            for future in as_completed(future_to_idx):\n                idx = future_to_idx[future]\n                results[idx] = future.result()\n\n        return results\n    ```\n  </TabItem>\n</Tabs>\n\n#### Agent Code Interface\n\nInside the REPL, agents have access to these functions:\n\n| Function | Description |\n|----------|-------------|\n| `rlm_query(task)` | Spawn a single sub-agent, returns result string |\n| `rlm_query_batched(tasks)` | Spawn multiple sub-agents in parallel |\n| `FINAL(answer)` | Submit final result (root: triggers patch extraction) |\n| `FINAL_VAR(var_name)` | Submit the value of a variable as result |\n| `edit_file(path, old, new)` | Edit a file with syntax validation |\n\nExample spawning pattern used by agents:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # Spawn multiple sub-agents to explore different modules\n    results = rlm_query_batched([\n        \"Search for TODO comments in sklearn/linear_model/ and assess difficulty\",\n        \"Search for TODO comments in sklearn/ensemble/ and assess difficulty\",\n        \"Search for TODO comments in sklearn/tree/ and assess difficulty\",\n    ])\n\n    for i, result in enumerate(results):\n        print(f\"=== Sub-agent {i+1} findings ===\")\n        print(result)\n    ```\n  </TabItem>\n</Tabs>\n\n### 5. Example Walkthrough\n\nLet's trace what happens when we run an agent on a popular machine learning library, scikit-learn:\n\n```bash\npython run.py https://github.com/scikit-learn/scikit-learn \\\n  -p \"Investigate TODO comments across this repository. Spawn sub-agents to explore different modules under sklearn/ in parallel. For each TODO found, assess how difficult it would be to fix (easy/medium/hard). After gathering results, pick the easiest TODO and fix it.\"\n```\n\nNote that there are about 400 lines in scikit-learn that contain the substring \"# TODO\".\n\n**Step 1: Root agent explores and spawns depth-1 sub-agents**\n\nThe root agent (depth=0) examines the repository structure, identifies all sklearn modules, and spawns 25 sub-agents in parallel:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # Define the subdirectories to investigate\n    subdirs = [\n        \"cluster\", \"compose\", \"covariance\", \"cross_decomposition\", \"datasets\",\n        \"decomposition\", \"ensemble\", \"feature_extraction\", \"feature_selection\",\n        \"gaussian_process\", \"impute\", \"inspection\", \"linear_model\", \"manifold\",\n        \"metrics\", \"mixture\", \"model_selection\", \"neighbors\", \"neural_network\",\n        \"preprocessing\", \"semi_supervised\", \"svm\", \"tree\", \"utils\"\n    ]\n\n    # Create queries for sub-agents\n    queries = [\n        f\"Search for 'TODO' comments in 'sklearn/{subdir}/'. For each TODO found, provide: \"\n        f\"1. The file path and line number. 2. The content of the TODO. 3. An assessment \"\n        f\"of how difficult it would be to fix (easy/medium/hard) with a brief justification.\"\n        for subdir in subdirs\n    ]\n\n    results = rlm_query_batched(queries)\n    ```\n  </TabItem>\n</Tabs>\n\nEach of these 25 sub-agents gets its own Daytona sandbox with a fresh clone of scikit-learn.\n\n**Step 2: Depth-1 agents spawn depth-2 agents**\n\nSome depth-1 agents decide their module is too large and spawn their own sub-agents. For example, the `sklearn/metrics/` agent spawned 3 depth-2 agents:\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # Inside the sklearn/metrics/ agent (depth=1)\n    # To efficiently handle the large number of TODOs, spawn sub-agents for sub-directories\n\n    tasks = [\n        \"Identify and assess TODOs in 'sklearn/metrics/cluster/'. Provide file, line, content, and difficulty.\",\n        \"Identify and assess TODOs in 'sklearn/metrics/tests/'. Provide file, line, content, and difficulty.\",\n        \"Identify and assess TODOs in 'sklearn/metrics/_plot/' and its 'tests' sub-directory.\"\n    ]\n\n    results = rlm_query_batched(tasks)\n    ```\n  </TabItem>\n</Tabs>\n\n**Step 3: Results propagate back**\n\nEach sub-agent returns findings via `FINAL()`. Results flow back up:\n- Depth-2 → Depth-1: Detailed analysis of specific subdirectories\n- Depth-1 → Root: Module-level summaries with difficulty ratings\n\n**Step 4: Root agent synthesizes and acts**\n\nThe root agent reviews all findings, identifies the easiest TODO, and makes the fix.\n\n**Step 5: Git patch produced**\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import subprocess\n    subprocess.run(['git', 'add', '-A'], cwd='/workspace')\n    result = subprocess.run(['git', 'diff', '--cached', 'HEAD'],\n                            capture_output=True, text=True, cwd='/workspace')\n    FINAL(result.stdout)\n    ```\n  </TabItem>\n</Tabs>\n\n#### Results\n\n- Execution time: **316 seconds** (~5.3 minutes)\n- Agents spawned: **40** (25 at depth 1, 15 at depth 2)\n\n**Generated patch:**\n```diff\ndiff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py\n--- a/sklearn/utils/_array_api.py\n+++ b/sklearn/utils/_array_api.py\n@@ -19,8 +19,7 @@ from sklearn.externals.array_api_compat import numpy as np_compat\n from sklearn.utils._dataframe import is_df_or_series\n from sklearn.utils.fixes import parse_version\n\n-# TODO: complete __all__\n-__all__ = [\"xpx\"]  # we import xpx here just to re-export it, need this to appease ruff\n+__all__ = ['device', 'get_namespace', 'get_namespace_and_device', 'indexing_dtype', 'move_to', 'size', 'supported_float_dtypes', 'xpx', 'yield_namespace_device_dtype_combinations', 'yield_namespaces']\n```\n\nThe agent found the easiest TODO (`# TODO: complete __all__` in `sklearn/utils/_array_api.py`) and completed the `__all__` list with all public symbols from the module.\n\n### 6. Configuration\n\nConfigure the agent in `config.yaml`:\n\n<Tabs>\n  <TabItem label=\"YAML\" icon=\"seti:yaml\">\n    ```yaml\n    # Model configuration - using LiteLLM format\n    model:\n      name: \"openrouter/google/gemini-3-flash-preview\"\n\n    # RLM configuration\n    rlm:\n      max_sandboxes: 50\n      max_iterations: 50\n      global_timeout: 3600\n      result_truncation_limit: 10000\n    ```\n  </TabItem>\n</Tabs>\n\n| Parameter | Default | Description |\n|-----------|---------|-------------|\n| `model.name` | `openrouter/google/gemini-3-flash-preview` | LLM model in LiteLLM format |\n| `rlm.max_sandboxes` | 50 | Maximum total sandboxes across entire rollout |\n| `rlm.max_iterations` | 50 | Maximum iterations per agent |\n| `rlm.global_timeout` | 3600 | Total timeout in seconds |\n| `rlm.result_truncation_limit` | 10000 | Max chars in sub-agent results |\n\n:::tip[Scaling Tips]\n- Increase `max_sandboxes` for tasks requiring more parallel exploration\n- The sandbox budget tracks total sandboxes created over the lifetime of the rollout\n- Sub-agent sandboxes are deleted immediately after completion\n:::\n\n### 7. Viewing Results\n\nResults are saved to the `results/` directory as JSON files. Use the built-in viewer:\n\n```bash\npython -m http.server 8000\n# Open http://localhost:8000/viewer/\n```\n\nThe viewer provides:\n- Interactive tree visualization of the agent hierarchy\n- Iteration details with code and output for each agent\n- Statistics: agent count, max depth, total iterations\n\n### 8. Conclusion\n\nCurrent language models aren't specifically trained to leverage recursive delegation, so RLMs don't necessarily outperform single-agent approaches on benchmarks yet. However, the architecture demonstrates compelling properties for complex tasks.\n\nIn our scikit-learn example, 40 agents ran in parallel across the agent tree, each with its own isolated sandbox, completing the entire run in just over 5 minutes. This level of parallelism, where each agent can freely modify files, run tests, and explore without affecting others, would be difficult to achieve without per-agent sandboxes.\n\n**Key advantages of this approach:**\n\n- **Recursive decomposition**: Complex tasks naturally break into sub-tasks handled by specialized agents\n- **Isolated execution**: Each agent gets a fresh sandbox, preventing interference\n- **Parallel exploration**: `rlm_query_batched()` enables concurrent investigation"
  },
  {
    "path": "apps/docs/src/content/docs/en/index.mdx",
    "content": "---\ntitle: Daytona Documentation\ndescription: Start managing your Sandboxes with Daytona.\ntemplate: doc\nhead:\n  - tag: title\n    content: Documentation · Daytona\n  - tag: meta\n    attrs:\n      property: og:title\n      content: Documentation · Daytona\n  - tag: meta\n    attrs:\n      name: twitter:title\n      content: Documentation · Daytona\ntableOfContents: true\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona is an open-source, secure and elastic infrastructure for running AI-generated code. Daytona provides full composable computers — [sandboxes](/docs/en/sandboxes) — that you can manage programmatically using the Daytona SDKs, [CLI](/docs/en/tools/cli), and [API](/docs/en/tools/api) to run and control code execution.\n\nDaytona SDK is available for [Python](/docs/en/python-sdk), [TypeScript](/docs/en/typescript-sdk), [Ruby](/docs/en/ruby-sdk) and [Go](/docs/en/go-sdk) interfaces.\n\n## 1. Create an account\n\nOpen the [Daytona Dashboard ↗](https://app.daytona.io/) to create your account. Daytona supports account creation using an email and password, or by connecting your Google or GitHub account.\n\n## 2. Obtain an API key\n\nGenerate an API key from the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/keys) or using the [Daytona API](/docs/en/tools/api/#daytona/tag/api-keys/POST/api-keys) to authenticate SDK requests and access Daytona services.\n\n## 3. Install the SDK\n\nInstall the Daytona [Python](/docs/python-sdk), [TypeScript](/docs/typescript-sdk), [Ruby](/docs/ruby-sdk) or [Go](/docs/go-sdk) SDKs to interact with sandboxes from code.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```bash\npip install daytona\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```bash\nnpm install @daytonaio/sdk\n```\n\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```bash\ngem install daytona\n```\n\n</TabItem>\n\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```bash\ngo get github.com/daytonaio/daytona/libs/sdk-go\n```\n\n</TabItem>\n</Tabs>\n\n## 4. Create a Sandbox\n\nCreate a [sandbox](/docs/en/sandboxes) to run your code securely in an isolated environment.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n`main.py`\n\n```python\n# Import the Daytona SDK\nfrom daytona import Daytona, DaytonaConfig\n\n# Define the configuration\nconfig = DaytonaConfig(api_key=\"YOUR_API_KEY\") # Replace with your API key\n\n# Initialize the Daytona client\ndaytona = Daytona(config)\n\n# Create the Sandbox instance\nsandbox = daytona.create()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n`index.mts`\n\n```typescript\n// Import the Daytona SDK\nimport { Daytona } from '@daytonaio/sdk'\n\n// Initialize the Daytona client\nconst daytona = new Daytona({ apiKey: 'YOUR_API_KEY' }) // Replace with your API key\n\n// Create the Sandbox instance\nconst sandbox = await daytona.create()\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n`main.rb`\n\n```ruby\nrequire 'daytona'\n\n# Initialize the Daytona client\nconfig = Daytona::Config.new(api_key: 'YOUR_API_KEY') # Replace with your API key\n\n# Create the Daytona client\ndaytona = Daytona::Daytona.new(config)\n\n# Create the Sandbox instance\nsandbox = daytona.create\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n`main.go`\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\tconfig := &types.DaytonaConfig{\n        APIKey: \"YOUR_API_KEY\", // Replace with your API key\n    }\n\tclient, _ := daytona.NewClientWithConfig(config)\n\tctx := context.Background()\n\tsandbox, _ := client.Create(ctx, nil)\n\tfmt.Println(sandbox.ID)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/sandbox \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --data '{}'\n```\n\n</TabItem>\n</Tabs>\n\n:::tip\nDaytona supports multiple options to configure your environment: [in code](/docs/en/configuration#configuration-in-code), [environment variables](/docs/en/configuration#environment-variables), [.env file](/docs/en/configuration#env-file), and [default values](/docs/en/configuration#default-values).\n:::\n\n## 5. Write and run code\n\nCreate a program that runs code inside a sandbox. The following snippets are examples of \"Hello World\" programs that run securely inside a sandbox.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n`main.py`\n\n```python\n# Import the Daytona SDK\nfrom daytona import Daytona, DaytonaConfig\n\n# Define the configuration\nconfig = DaytonaConfig(api_key=\"YOUR_API_KEY\") # Replace with your API key\n\n# Initialize the Daytona client\ndaytona = Daytona(config)\n\n# Create the Sandbox instance\nsandbox = daytona.create()\n\n# Run the code securely inside the Sandbox\nresponse = sandbox.process.code_run('print(\"Hello World\")')\n\n# Check the response\nif response.exit_code != 0:\n  print(f\"Error: {response.exit_code} {response.result}\")\nelse:\n  print(response.result)\n\n# Clean up\nsandbox.delete()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n`index.mts`\n\n```typescript\n// Import the Daytona SDK\nimport { Daytona } from '@daytonaio/sdk'\n\n// Initialize the Daytona client\nconst daytona = new Daytona({ apiKey: 'YOUR_API_KEY' }) // Replace with your API key\n\n// Create the Sandbox instance\nconst sandbox = await daytona.create({\n  language: 'typescript',\n})\n\n// Run the code securely inside the Sandbox\nconst response = await sandbox.process.codeRun('console.log(\"Hello World\")')\n\n// Check the response\nif (response.exitCode !== 0) {\n  console.error(`Error: ${response.exitCode} ${response.result}`)\n} else {\n  console.log(response.result)\n}\n\n// Clean up\nawait sandbox.delete()\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n`main.rb`\n\n```ruby\nrequire 'daytona'\n\n# Initialize the Daytona client\nconfig = Daytona::Config.new(api_key: 'YOUR_API_KEY')\ndaytona = Daytona::Daytona.new(config)\n\n# Create the Sandbox instance\nsandbox = daytona.create\n\n# Run the code securely inside the Sandbox\nresponse = sandbox.process.code_run(code: 'print(\"Hello World\")')\nputs response.result\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n`main.go`\n\n```go\n// Import the Daytona SDK\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n    // Define the configuration\n    config := &types.DaytonaConfig{\n        APIKey: \"YOUR_API_KEY\", // Replace with your API key\n    }\n\n    // Initialize the Daytona client\n    client, err := daytona.NewClientWithConfig(config)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    ctx := context.Background()\n\n    // Create the Sandbox instance\n    params := types.SnapshotParams{\n        SandboxBaseParams: types.SandboxBaseParams{\n            Language: types.CodeLanguagePython,\n        },\n    }\n    sandbox, err := client.Create(ctx, params)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Run the code securely inside the Sandbox\n    result, err := sandbox.Process.ExecuteCommand(ctx, `echo \"Hello World\"`)\n\n    // Check the response\n    if err != nil {\n        log.Fatalf(\"Error: %v\", err)\n    }\n    if result.ExitCode != 0 {\n        log.Printf(\"Error: %d %s\", result.ExitCode, result.Result)\n    } else {\n        log.Println(result.Result)\n    }\n\n    // Clean up\n    sandbox.Delete(ctx)\n}\n```\n\n</TabItem>\n</Tabs>\n\n## Summary\n\nBy following the steps above, you successfully create a Daytona account, obtain an API key, install the SDK, create a sandbox, write code, and run it securely in a sandbox.\n\n## Next steps\n\nUse the following resources to interact with sandboxes:\n\n- Learn more about Daytona with the [Getting Started](/docs/en/getting-started) guide\n- Get started with [Python](/docs/en/python-sdk), [TypeScript](/docs/en/typescript-sdk), [Ruby](/docs/en/ruby-sdk) or [Go](/docs/en/go-sdk) **SDKs**\n- Install the [CLI](/docs/en/getting-started#cli) to manage sandboxes from the command line\n- Use the [API](/docs/en/tools/api) to manage sandboxes programmatically\n- View [examples](/docs/en/getting-started#examples) for common sandbox operations and best practices\n- Explore [guides](/docs/en/guides) to connect Daytona with [Claude](/docs/en/guides/claude), [OpenCode](/docs/en/guides/opencode/opencode-web-agent), [Codex](/docs/en/guides/codex/codex-sdk-interactive-terminal-sandbox), [LangChain](/docs/en/guides/langchain/langchain-data-analysis) and more\n\n:::tip\nFor faster development with AI agents and assistants, use our LLMs context files. Copy the [llms-full.txt](https://www.daytona.io/docs/llms-full.txt) and [llms.txt](https://www.daytona.io/docs/llms.txt) files and include them in your projects or chat contexts.\n:::\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/language-server-protocol.mdx",
    "content": "---\ntitle: Language Server Protocol\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona provides Language Server Protocol (LSP) support through sandbox instances. This enables advanced language features like code completion, diagnostics, and more.\n\n## Create LSP servers\n\nDaytona provides methods to create LSP servers. The `path_to_project` argument is relative to the current sandbox working directory when no leading `/` is used. The working directory is specified by WORKDIR when it is present in the Dockerfile, and otherwise falls back to the user's home directory.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, LspLanguageId\n\n# Create Sandbox\ndaytona = Daytona()\nsandbox = daytona.create()\n\n# Create LSP server for Python\nlsp_server = sandbox.create_lsp_server(\n    language_id=LspLanguageId.PYTHON,\n    path_to_project=\"workspace/project\"\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, LspLanguageId } from '@daytonaio/sdk'\n\n// Create sandbox\nconst daytona = new Daytona()\nconst sandbox = await daytona.create({\n  language: 'typescript',\n})\n\n// Create LSP server for TypeScript\nconst lspServer = await sandbox.createLspServer(\n  LspLanguageId.TYPESCRIPT,\n  'workspace/project'\n)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\n# Create Sandbox\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\n\n# Create LSP server for Python\nlsp_server = sandbox.create_lsp_server(\n  language_id: Daytona::LspServer::Language::PYTHON,\n  path_to_project: 'workspace/project'\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create sandbox\nclient, err := daytona.NewClient()\nif err != nil {\n\tlog.Fatal(err)\n}\n\nctx := context.Background()\nsandbox, err := client.Create(ctx, nil)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Get LSP service for Python\nlsp := sandbox.Lsp(types.LspLanguagePython, \"workspace/project\")\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/lsp-server/), and [Go SDK](/docs/en/go-sdk/) references:\n\n> [**create_lsp_server (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxcreate_lsp_server)\n>\n> [**createLspServer (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#createlspserver)\n>\n> [**create_lsp_server (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#create_lsp_server)\n\n### Supported languages\n\nThe supported languages for creating LSP servers with Daytona are defined by the `LspLanguageId` enum:\n\n| Enum Value                     | Description                            |\n| ------------------------------ | -------------------------------------- |\n| **`LspLanguageId.PYTHON`**     | Python language server                 |\n| **`LspLanguageId.TYPESCRIPT`** | TypeScript/JavaScript language server  |\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/lsp-server/#lsplanguageid) and [TypeScript SDK](/docs/en/typescript-sdk/lsp-server/#lsplanguageid) references:\n\n> [**LspLanguageId (Python SDK)**](/docs/en/python-sdk/sync/lsp-server/#lsplanguageid)\n>\n> [**LspLanguageId (TypeScript SDK)**](/docs/en/typescript-sdk/lsp-server/#lsplanguageid)\n\n## Start LSP servers\n\nDaytona provides methods to start LSP servers.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nlsp = sandbox.create_lsp_server(\"typescript\", \"workspace/project\")\nlsp.start()  # Initialize the server\n# Now ready for LSP operations\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst lsp = await sandbox.createLspServer('typescript', 'workspace/project')\nawait lsp.start() // Initialize the server\n// Now ready for LSP operations\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nlsp = sandbox.create_lsp_server(\n  language_id: Daytona::LspServer::Language::PYTHON,\n  path_to_project: 'workspace/project'\n)\nlsp.start  # Initialize the server\n# Now ready for LSP operations\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nlsp := sandbox.Lsp(types.LspLanguagePython, \"workspace/project\")\nerr := lsp.Start(ctx)  // Initialize the server\nif err != nil {\n\tlog.Fatal(err)\n}\n// Now ready for LSP operations\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/start' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"languageId\": \"\",\n  \"pathToProject\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/lsp-server/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/lsp/) references:\n\n> [**start (Python SDK)**](/docs/en/python-sdk/sync/lsp-server/#lspserverstart)\n>\n> [**start (TypeScript SDK)**](/docs/en/typescript-sdk/lsp-server/#start)\n>\n> [**start (Ruby SDK)**](/docs/en/ruby-sdk/lsp-server/#start)\n>\n> [**Start (Go SDK)**](/docs/en/go-sdk/daytona#LspServerService.Start)\n>\n> [**start (API)**](/docs/en/tools/api/#daytona-toolbox/tag/lsp/POST/lsp/start)\n\n## Stop LSP servers\n\nDaytona provides methods to stop LSP servers.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# When done with LSP features\nlsp.stop()  # Clean up resources\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// When done with LSP features\nawait lsp.stop() // Clean up resources\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# When done with LSP features\nlsp.stop  # Clean up resources\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// When done with LSP features\nerr := lsp.Stop(ctx)  // Clean up resources\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/stop' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"languageId\": \"\",\n  \"pathToProject\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/lsp-server/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/lsp/) references:\n\n> [**stop (Python SDK)**](/docs/en/python-sdk/sync/lsp-server/#lspserverstop)\n>\n> [**stop (TypeScript SDK)**](/docs/en/typescript-sdk/lsp-server/#stop)\n>\n> [**stop (Ruby SDK)**](/docs/en/ruby-sdk/lsp-server/#stop)\n>\n> [**Stop (Go SDK)**](/docs/en/go-sdk/daytona#LspServerService.Stop)\n>\n> [**stop (API)**](/docs/en/tools/api/#daytona-toolbox/tag/lsp/POST/lsp/stop)\n\n## Code completions\n\nDaytona provides methods to get code completions for a specific position in a file.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ncompletions = lsp_server.completions(\n    path=\"workspace/project/main.py\",\n    position={\"line\": 10, \"character\": 15}\n)\nprint(f\"Completions: {completions}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst completions = await lspServer.completions('workspace/project/main.ts', {\n  line: 10,\n  character: 15,\n})\nconsole.log('Completions:', completions)\n```\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\ncompletions = lsp_server.completions(\n  path: 'workspace/project/main.py',\n  position: { line: 10, character: 15 }\n)\nputs \"Completions: #{completions}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\ncompletions, err := lsp.Completions(ctx, \"workspace/project/main.py\",\n\ttypes.Position{Line: 10, Character: 15},\n)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Completions: %v\\n\", completions)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/completions' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"context\": {\n    \"triggerCharacter\": \"\",\n    \"triggerKind\": 1\n  },\n  \"languageId\": \"\",\n  \"pathToProject\": \"\",\n  \"position\": {\n    \"character\": 1,\n    \"line\": 1\n  },\n  \"uri\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/lsp-server/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/lsp/) references:\n\n> [**completions (Python SDK)**](/docs/en/python-sdk/sync/lsp-server/#lspservercompletions)\n>\n> [**completions (TypeScript SDK)**](/docs/en/typescript-sdk/lsp-server/#completions)\n>\n> [**completions (Ruby SDK)**](/docs/en/ruby-sdk/lsp-server/#completions)\n>\n> [**Completions (Go SDK)**](/docs/en/go-sdk/daytona#LspServerService.Completions)\n>\n> [**completions (API)**](/docs/en/tools/api/#daytona-toolbox/tag/lsp/POST/lsp/completions)\n\n## File notifications\n\nDaytona provides methods to notify the LSP server when files are opened or closed. This enables features like diagnostics and completion tracking for the specified files.\n\n### Open file\n\nNotifies the language server that a file has been opened for editing.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Notify server that a file is open\nlsp_server.did_open(\"workspace/project/main.py\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Notify server that a file is open\nawait lspServer.didOpen('workspace/project/main.ts')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Notify server that a file is open\nlsp_server.did_open('workspace/project/main.py')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Notify server that a file is open\nerr := lsp.DidOpen(ctx, \"workspace/project/main.py\")\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/did-open' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"languageId\": \"\",\n  \"pathToProject\": \"\",\n  \"uri\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/lsp-server/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/lsp/) references:\n\n> [**did_open (Python SDK)**](/docs/en/python-sdk/sync/lsp-server/#lspserverdid_open)\n>\n> [**didOpen (TypeScript SDK)**](/docs/en/typescript-sdk/lsp-server/#didopen)\n>\n> [**did_open (Ruby SDK)**](/docs/en/ruby-sdk/lsp-server/#did_open)\n>\n> [**DidOpen (Go SDK)**](/docs/en/go-sdk/daytona#LspServerService.DidOpen)\n>\n> [**did_open (API)**](/docs/en/tools/api/#daytona-toolbox/tag/lsp/POST/lsp/did-open)\n\n### Close file\n\nNotifies the language server that a file has been closed. This allows the server to clean up resources associated with that file.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Notify server that a file is closed\nlsp_server.did_close(\"workspace/project/main.py\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Notify server that a file is closed\nawait lspServer.didClose('workspace/project/main.ts')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Notify server that a file is closed\nlsp_server.did_close('workspace/project/main.py')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Notify server that a file is closed\nerr := lsp.DidClose(ctx, \"workspace/project/main.py\")\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/did-close' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"languageId\": \"\",\n  \"pathToProject\": \"\",\n  \"uri\": \"\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/lsp-server/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/lsp/) references:\n\n> [**did_close (Python SDK)**](/docs/en/python-sdk/sync/lsp-server/#lspserverdid_close)\n>\n> [**didClose (TypeScript SDK)**](/docs/en/typescript-sdk/lsp-server/#didclose)\n>\n> [**did_close (Ruby SDK)**](/docs/en/ruby-sdk/lsp-server/#did_close)\n>\n> [**DidClose (Go SDK)**](/docs/en/go-sdk/daytona#LspServerService.DidClose)\n>\n> [**did_close (API)**](/docs/en/tools/api/#daytona-toolbox/tag/lsp/POST/lsp/did-close)\n\n## Document symbols\n\nDaytona provides methods to retrieve symbols (functions, classes, variables, etc.) from a document.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsymbols = lsp_server.document_symbols(\"workspace/project/main.py\")\nfor symbol in symbols:\n    print(f\"Symbol: {symbol.name}, Kind: {symbol.kind}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst symbols = await lspServer.documentSymbols('workspace/project/main.ts')\nsymbols.forEach((symbol) => {\n  console.log(`Symbol: ${symbol.name}, Kind: ${symbol.kind}`)\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsymbols = lsp_server.document_symbols('workspace/project/main.py')\nsymbols.each do |symbol|\n  puts \"Symbol: #{symbol.name}, Kind: #{symbol.kind}\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nsymbols, err := lsp.DocumentSymbols(ctx, \"workspace/project/main.py\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfor _, symbol := range symbols {\n\tfmt.Printf(\"Symbol: %v\\n\", symbol)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/document-symbols?languageId=&pathToProject=&uri='\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/lsp-server/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/lsp/) references:\n\n> [**document_symbols (Python SDK)**](/docs/en/python-sdk/sync/lsp-server/#lspserverdocument_symbols)\n>\n> [**documentSymbols (TypeScript SDK)**](/docs/en/typescript-sdk/lsp-server/#documentsymbols)\n>\n> [**document_symbols (Ruby SDK)**](/docs/en/ruby-sdk/lsp-server/#document_symbols)\n>\n> [**DocumentSymbols (Go SDK)**](/docs/en/go-sdk/daytona#LspServerService.DocumentSymbols)\n>\n> [**document_symbols (API)**](/docs/en/tools/api/#daytona-toolbox/tag/lsp/GET/lsp/document-symbols)\n\n## Sandbox symbols\n\nDaytona provides methods to search for symbols across all files in the sandbox.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsymbols = lsp_server.sandbox_symbols(\"MyClass\")\nfor symbol in symbols:\n    print(f\"Found: {symbol.name} at {symbol.location}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst symbols = await lspServer.sandboxSymbols('MyClass')\nsymbols.forEach((symbol) => {\n  console.log(`Found: ${symbol.name} at ${symbol.location}`)\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsymbols = lsp_server.sandbox_symbols('MyClass')\nsymbols.each do |symbol|\n  puts \"Found: #{symbol.name} at #{symbol.location}\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nsymbols, err := lsp.SandboxSymbols(ctx, \"MyClass\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfor _, symbol := range symbols {\n\tfmt.Printf(\"Found: %v\\n\", symbol)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/lsp/workspacesymbols?query=&languageId=&pathToProject='\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/lsp-server/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/lsp) references:\n\n> [**sandbox_symbols (Python SDK)**](/docs/en/python-sdk/sync/lsp-server/#lspserversandbox_symbols)\n>\n> [**sandboxSymbols (TypeScript SDK)**](/docs/en/typescript-sdk/lsp-server/#sandboxsymbols)\n>\n> [**sandbox_symbols (Ruby SDK)**](/docs/en/ruby-sdk/lsp-server/#sandbox_symbols)\n>\n> [**SandboxSymbols (Go SDK)**](/docs/en/go-sdk/daytona#LspServerService.SandboxSymbols)\n>\n> [**sandbox_symbols (API)**](/docs/en/tools/api/#daytona-toolbox/tag/lsp/GET/lsp/workspacesymbols)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/limits.mdx",
    "content": "---\ntitle: Limits\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona enforces resource and requests limits to ensure fair usage and stability across all organizations.\n\n[Daytona Limits ↗](https://app.daytona.io/dashboard/limits) provides an overview of your organization's resource limits and usage.\n\n## Resources\n\nResources are shared across all running sandboxes. The number of sandboxes you can run at once depends on their individual usage.\nOrganizations are automatically placed into a tier based on verification status and have access to a compute pool consisting of:\n\n- **Compute**: Total CPU cores available\n- **Memory**: Total RAM available\n- **Storage**: Total disk space available\n\nLimits are applied to your organization's default region.\nTo unlock higher limits, complete the following steps:\n\n| **Tier**   | **Resources (vCPU / RAM / Storage)**      | **Access Requirements**                                                                              |\n| ---------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------- |\n| **Tier 1** | **`10`** / **`10GiB`** / **`30GiB`**      | Email verified                                                                                       |\n| **Tier 2** | **`100`** / **`200GiB`** / **`300GiB`**   | Credit card linked, $25 top-up, [GitHub connected](/docs/en/linked-accounts#how-to-link-an-account). |\n| **Tier 3** | **`250`** / **`500GiB`** / **`2000GiB`**  | Business email verified, $500 top-up.                                                                |\n| **Tier 4** | **`500`** / **`1000GiB`** / **`5000GiB`** | $2000 top-up every 30 days.                                                                          |\n| **Custom** | Custom limits                             | Contact [support@daytona.io](mailto:support@daytona.io)                                              |\n\nOnce you meet the criteria for a higher tier, upgrade your tier in the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/limits).\n\n### Resource usage\n\nDaytona supports managing your resources by [changing the state](/docs/sandboxes#sandbox-lifecycle) of your Sandboxes. The table below summarizes how each state affects resource usage:\n\n| **State**    | **vCPU** | **Memory** | **Storage** | **Description**                               |\n| ------------ | -------- | ---------- | ----------- | --------------------------------------------- |\n| **Running**  | ✅       | ✅         | ✅          | Counts against all limits                     |\n| **Stopped**  | ❌       | ❌         | ✅          | Frees CPU & memory, but storage is still used |\n| **Archived** | ❌       | ❌         | ❌          | Data moved to cold storage, no quota impact   |\n| **Deleted**  | ❌       | ❌         | ❌          | All resources freed                           |\n\n## Rate limits\n\nRate limits control how many API requests you can make within a specific time window.\nThese limits are applied based on your tier, authentication status, and the type of operation you're performing.\nRate limits for general authenticated requests are tracked per organization.\n\nThe following rate limits are applied for each tier:\n\n- **General requests**\n- **[Sandbox creation](#sandbox-creation)**\n- **[Sandbox lifecycle](#sandbox-lifecycle-operations)**\n\n| **Tier**   | **General Requests (per min)** | **Sandbox Creation (per min)** | **Sandbox Lifecycle (per min)** |\n| ---------- | ------------------------------ | ------------------------------ | ------------------------------- |\n| **Tier 1** | 10,000                         | 300                            | 10,000                          |\n| **Tier 2** | 20,000                         | 400                            | 20,000                          |\n| **Tier 3** | 40,000                         | 500                            | 40,000                          |\n| **Tier 4** | 50,000                         | 600                            | 50,000                          |\n| **Custom** | Custom limits                  | Custom limits                  | Custom limits                   |\n\nThe general rate limit for authenticated API requests that don't fall under sandbox creation or lifecycle operations includes:\n\n- **Listing sandboxes**\n- **Getting sandbox details**\n- **Retrieving sandbox regions**\n- **Listing snapshots**\n- **Managing volumes**\n- **Viewing audit logs**\n- and other read/management operations\n\nWhen you exceed a rate limit, subsequent requests will fail with:\n\n- **HTTP Status**: `429 Too Many Requests`\n- **Error Response**: JSON body with rate limit details\n- **Retry-After Header**: Time to wait before retrying (in seconds)\n\nUnderstanding these limits helps you build robust applications that handle rate limiting gracefully and avoid service interruptions. For more information, see [best practices](#best-practices).\n\n### Rate limit headers\n\nDaytona includes rate limit information in API response headers. Header names include a suffix based on which rate limit is triggered (e.g., `-anonymous`, `-authenticated`, `-sandbox-create`, `-sandbox-lifecycle`):\n\n| Header Pattern                          | Description                                                               |\n| --------------------------------------- | ------------------------------------------------------------------------- |\n| **`X-RateLimit-Limit-{throttler}`**     | Maximum number of requests allowed in the time window                     |\n| **`X-RateLimit-Remaining-{throttler}`** | Number of requests remaining in the current window                        |\n| **`X-RateLimit-Reset-{throttler}`**     | Time in seconds until the rate limit window resets                        |\n| **`Retry-After-{throttler}`**           | Time in seconds to wait before retrying (included when limit is exceeded) |\n\n\n### Sandbox creation\n\nThis rate limit applies to all sandbox creation methods, including [creation from snapshots](/docs/snapshots#create-snapshots), [declarative builds](/docs/declarative-builder) and any other parameters passed to `daytona.create()` ([SDK](/docs/getting-started#sdks)) or POST requests to `/api/sandbox` ([API](/docs/getting-started#api)).\n\nThis independent limit prevents resource exhaustion while allowing you to perform lifecycle operations on existing sandboxes without restriction.\n\n:::note\nTo create sandboxes at a higher rate for your use case, contact [support@daytona.io](mailto:support@daytona.io).\n:::\n\n### Sandbox lifecycle operations\n\nThis rate limit applies to lifecycle and state management operations on existing sandboxes:\n\n- [**Starting** sandboxes](/docs/tools/api#post-sandboxsandboxidornamestart) (`POST /api/sandbox/:id/start`)\n- [**Stopping** sandboxes](/docs/tools/api#post-sandboxsandboxidornamestop) (`POST /api/sandbox/:id/stop`)\n- [**Deleting** sandboxes](/docs/tools/api#delete-sandboxsandboxidorname) (`DELETE /api/sandbox/:id`)\n- [**Archiving** sandboxes](/docs/tools/api#post-sandboxsandboxidornamearchive) (`POST /api/sandbox/:id/archive`)\n- and all corresponding SDK methods\n\nThese operations have a higher limit since they're often performed more frequently during development workflows.\n\n### Rate limit errors\n\nDaytona [Python](/docs/python-sdk) or [TypeScript](/docs/en/typescript-sdk) SDKs raise or throw a `DaytonaRateLimitError` exception (Python) or error (TypeScript) when you exceed a rate limit.\n\nAll errors include [**`headers`**](#rate-limit-headers) and [**`statusCode`**](#example-rate-limit-error-response) properties, allowing access to rate limit headers directly from the error object. Headers support case-insensitive access:\n\n<Tabs>\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    try {\n      await daytona.create()\n    } catch (error) {\n      if (error instanceof DaytonaRateLimitError) {\n        console.log(error.headers?.get('x-ratelimit-remaining-sandbox-create'))\n        console.log(error.headers?.get('X-RateLimit-Remaining-Sandbox-Create')) // also works\n      }\n    }\n    ```\n  </TabItem>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    try:\n      daytona.create(snapshot=\"my-snapshot\")\n    except DaytonaRateLimitError as e:\n      print(e.headers['x-ratelimit-remaining-sandbox-create'])\n      print(e.headers['X-RateLimit-Remaining-Sandbox-Create'])  # also works\n    ```\n  </TabItem>\n  <TabItem label=\"Ruby\" icon=\"seti:ruby\">\n    ```ruby\n    begin\n      daytona.create\n    rescue Daytona::Sdk::Error => e\n      puts \"Error: #{e.message}\"\n    end\n    ```\n  </TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/python-sdk/common/errors) and [TypeScript SDK](/docs/typescript-sdk/errors) references.\n\n> [**DaytonaRateLimitError (Python SDK)**](/docs/en/python-sdk/common/errors#daytonaratelimiteerror)\n>\n> [**DaytonaRateLimitError (TypeScript SDK)**](/docs/python-sdk/common/errors#daytonaratelimiterror)\n>\n> [**DaytonaRateLimitError (Ruby SDK)**](/docs/ruby-sdk/errors#daytonaratelimiteerror)\n\n### Rate limit error response\n\nThe rate limit error response is a JSON object with the following properties:\n\n- **`statusCode`**: The HTTP status code of the error\n- **`message`**: The error message\n- **`error`**: The error type\n\n```json\n{\n  \"statusCode\": 429,\n  \"message\": \"Rate limit exceeded\",\n  \"error\": \"Too Many Requests\"\n}\n```\n\n## Tier upgrade\n\nUnlock more resources and higher rate limits by completing verification steps. For more information, see the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/limits).\n\n:::note\nFor access to custom tier requirements or resources in other regions, please contact [sales@daytona.io](mailto:sales@daytona.io).\n:::\n\n## Best practices\n\nTo work effectively within rate limits, always handle `429` errors gracefully with proper retry logic. When you receive a rate limit error, implement exponential backoff—wait progressively longer between retries (1s, 2s, 4s, 8s, etc.) to avoid overwhelming the API.\n\nThe following snippet demonstrates how to create a sandbox with retry logic using the TypeScript SDK:\n\n```typescript\nasync function createSandboxWithRetry() {\n  let retries = 0\n  const maxRetries = 5\n\n  while (retries < maxRetries) {\n    try {\n      return await daytona.create({ snapshot: 'my-snapshot' })\n    } catch (error) {\n      if (error instanceof DaytonaRateLimitError && retries < maxRetries - 1) {\n        // Use Retry-After header if available, otherwise exponential backoff\n        const retryAfter = error.headers?.get('retry-after-sandbox-create')\n        const delay = retryAfter\n          ? parseInt(retryAfter) * 1000\n          : Math.pow(2, retries) * 1000\n        await new Promise(resolve => setTimeout(resolve, delay))\n        retries++\n      } else {\n        throw error\n      }\n    }\n  }\n}\n```\n\n**Monitor [rate limit headers](#rate-limit-headers)** (e.g., `X-RateLimit-Remaining-{throttler}`, `X-RateLimit-Reset-{throttler}`) to track your consumption and implement proactive throttling before hitting limits. These headers are available on all error objects via the `headers` property.\n\n**Cache API responses** that don't frequently change, such as [sandbox lists](/docs/sandboxes#list-sandboxes) (when relatively static), [available regions](/docs/regions), and [snapshot information](/docs/snapshots). This reduces unnecessary API calls and helps you stay well within your limits.\n\n**Batch and optimize operations** by creating multiple sandboxes in parallel (within rate limits) rather than sequentially. Consider reusing existing sandboxes when possible instead of creating new ones for every task.\n\n**Efficiently manage sandbox lifecycle** to reduce API calls. [Archive sandboxes](/docs/sandboxes#archive-sandboxes) instead of deleting and recreating them, stop sandboxes when not in use rather than deleting them, and leverage [auto-stop intervals](/docs/sandboxes#auto-stop-interval) to automatically manage running sandboxes without manual intervention.\n\n**Implement request queuing** to prevent bursts that exceed limits, and use [webhooks](/docs/webhooks) instead of polling for state changes to avoid unnecessary API calls. Set up monitoring and alerts for `429` errors in your application logs so you can proactively address rate limiting issues before they impact your users.\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/linked-accounts.mdx",
    "content": "---\ntitle: Linked Accounts\n---\n\nDaytona supports linking user accounts from various identity providers. At the moment, the following providers are supported:\n\n- Google\n- GitHub\n\n:::tip\nGitHub account is one of the requirements to automatically [upgrade your organization to **Tier 2**](/docs/en/limits#tiers--rate-limit-increases).\n:::\n\n## Link account\n1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/user/account-settings) account settings.\n2. Click the **Link Account** button next to the provider you want to link.\n3. Follow the prompts to link your account.\n\n## Unlink account\n\n1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/user/account-settings) account settings.\n2. Click the **Unlink** button next to the provider you want to unlink.\n3. Follow the prompts to unlink your account.\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/log-streaming.mdx",
    "content": "---\ntitle: Log Streaming\n---\n\nLog streaming allows you to access and process logs as they are being produced, while the process is still running. When executing long-running processes in a sandbox, you often want to access and process their logs in **real-time**. \n\nReal-time streaming is especially useful for **debugging**, **monitoring**, or integrating with **observability tools**.\n\n- [**Log streaming**](#stream-logs-with-callbacks): stream logs as they are being produced, while the process is still running.\n- [**Fetching log snapshot**](#retrieve-all-existing-logs): retrieve all logs up to a certain point.\n\nThis guide covers how to use log streaming with callbacks and fetching log snapshots in both asynchronous and synchronous modes.\n\n:::note\nStarting with version `0.27.0`, you can retrieve session command logs in two distinct streams: **stdout** and **stderr**.\n:::\n\n## Stream logs with callbacks\n\nIf your sandboxed process is part of a larger system and is expected to run for an extended period (or indefinitely),\nyou can process logs asynchronously **in the background**, while the rest of your system continues executing.\n\nThis is ideal for:\n\n- Continuous monitoring\n- Debugging long-running jobs\n- Live log forwarding or visualizations\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nimport asyncio\nfrom daytona import Daytona, SessionExecuteRequest\n\nasync def main():\n  daytona = Daytona()\n  sandbox = daytona.create()\n\n  session_id = \"streaming-session\"\n  sandbox.process.create_session(session_id)\n\n  command = sandbox.process.execute_session_command(\n    session_id,\n    SessionExecuteRequest(\n      command='for i in {1..5}; do echo \"Step $i\"; echo \"Error $i\" >&2; sleep 1; done',\n      var_async=True,\n    ),\n  )\n\n  # Stream logs with separate callbacks\n  logs_task = asyncio.create_task(\n    sandbox.process.get_session_command_logs_async(\n      session_id,\n      command.cmd_id,\n      lambda stdout: print(f\"[STDOUT]: {stdout}\"),\n      lambda stderr: print(f\"[STDERR]: {stderr}\"),\n    )\n  )\n\n  print(\"Continuing execution while logs are streaming...\")\n  await asyncio.sleep(3)\n  print(\"Other operations completed!\")\n\n  # Wait for the logs to complete\n  await logs_task\n\n  sandbox.delete()\n  \nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n</TabItem>\n<TabItem label=\"Typescript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, SessionExecuteRequest } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n  const sandbox = await daytona.create()\n  const sessionId = \"exec-session-1\"\n  await sandbox.process.createSession(sessionId)\n\n  const command = await sandbox.process.executeSessionCommand(\n    sessionId,\n    {\n      command: 'for i in {1..5}; do echo \"Step $i\"; echo \"Error $i\" >&2; sleep 1; done',\n      runAsync: true,\n    },\n  )\n\n  // Stream logs with separate callbacks\n  const logsTask = sandbox.process.getSessionCommandLogs(\n    sessionId,\n    command.cmdId!,\n    (stdout) => console.log('[STDOUT]:', stdout),\n    (stderr) => console.log('[STDERR]:', stderr),\n  )\n\n  console.log('Continuing execution while logs are streaming...')\n  await new Promise((resolve) => setTimeout(resolve, 3000))\n  console.log('Other operations completed!')\n\n  // Wait for the logs to complete\n  await logsTask\n\n  await sandbox.delete()\n}\n\nmain()\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\n\nsession_id = 'streaming-session'\nsandbox.process.create_session(session_id)\n\ncommand = sandbox.process.execute_session_command(\n  session_id,\n  Daytona::SessionExecuteRequest.new(\n    command: 'for i in {1..5}; do echo \"Step $i\"; echo \"Error $i\" >&2; sleep 1; done',\n    var_async: true\n  )\n)\n\n# Stream logs using a thread\nlog_thread = Thread.new do\n  sandbox.process.get_session_command_logs_stream(\n    session_id,\n    command.cmd_id,\n    on_stdout: ->(stdout) { puts \"[STDOUT]: #{stdout}\" },\n    on_stderr: ->(stderr) { puts \"[STDERR]: #{stderr}\" }\n  )\nend\n\nputs 'Continuing execution while logs are streaming...'\nsleep(3)\nputs 'Other operations completed!'\n\n# Wait for the logs to complete\nlog_thread.join\n\ndaytona.delete(sandbox)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n\tclient, _ := daytona.NewClient()\n\tctx := context.Background()\n\tsandbox, _ := client.Create(ctx, nil)\n\n\tsessionID := \"streaming-session\"\n\tsandbox.Process.CreateSession(ctx, sessionID)\n\n\t// Execute async command that outputs to stdout and stderr\n\tcmd := `for i in 1 2 3 4 5; do echo \"Step $i\"; echo \"Error $i\" >&2; sleep 1; done`\n\tcmdResult, _ := sandbox.Process.ExecuteSessionCommand(ctx, sessionID, cmd, true)\n\tcmdID, _ := cmdResult[\"id\"].(string)\n\n\t// Create channels for stdout and stderr\n\tstdout := make(chan string, 100)\n\tstderr := make(chan string, 100)\n\n\t// Stream logs in a goroutine\n\tgo func() {\n\t\terr := sandbox.Process.GetSessionCommandLogsStream(ctx, sessionID, cmdID, stdout, stderr)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Stream error: %v\", err)\n\t\t}\n\t}()\n\n\tfmt.Println(\"Continuing execution while logs are streaming...\")\n\n\t// Read from channels until both are closed\n\tstdoutOpen, stderrOpen := true, true\n\tfor stdoutOpen || stderrOpen {\n\t\tselect {\n\t\tcase chunk, ok := <-stdout:\n\t\t\tif !ok {\n\t\t\t\tstdoutOpen = false\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(os.Stdout, \"[STDOUT]: %s\", chunk)\n\t\t\t}\n\t\tcase chunk, ok := <-stderr:\n\t\t\tif !ok {\n\t\t\t\tstderrOpen = false\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"[STDERR]: %s\", chunk)\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Println(\"Streaming completed!\")\n\tsandbox.Delete(ctx)\n}\n```\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}/command/{commandId}/logs'\n```\n</TabItem>\n\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/python-sdk/sync/process/), [TypeScript SDK](/docs/typescript-sdk/process/), [Ruby SDK](/docs/ruby-sdk/process/), [Go SDK](/docs/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/process) references.\n\n> [**get_session_command_logs_async (Python SDK)**](/docs/python-sdk/sync/process/#processget_session_command_logs_async)\n>\n> [**getSessionCommandLogs (TypeScript SDK)**](/docs/typescript-sdk/process/#getsessioncommandlogs)\n>\n> [**get_session_command_logs_async (Ruby SDK)**](/docs/ruby-sdk/process/#get_session_command_logs_async)\n>\n> [**GetSessionCommandLogsStream (Go SDK)**](/docs/go-sdk/daytona/#ProcessService.GetSessionCommandLogsStream)\n>\n> [**get session command logs (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/POST/process/session/{sessionId}/exec)\n\n## Retrieve all existing logs\n\nIf the command has a predictable duration, or if you don't need to run it in the background but want to\nperiodically check all existing logs, you can use the following example to get the logs up to the current point in time.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nimport time\nfrom daytona import Daytona, SessionExecuteRequest\n\ndaytona = Daytona()\nsandbox = daytona.create()\nsession_id = \"exec-session-1\"\nsandbox.process.create_session(session_id)\n\n# Execute a blocking command and wait for the result\ncommand = sandbox.process.execute_session_command(\n  session_id, SessionExecuteRequest(command=\"echo 'Hello from stdout' && echo 'Hello from stderr' >&2\")\n)\nprint(f\"[STDOUT]: {command.stdout}\")\nprint(f\"[STDERR]: {command.stderr}\")\nprint(f\"[OUTPUT]: {command.output}\")\n\n# Or execute command in the background and get the logs later\ncommand = sandbox.process.execute_session_command(\n  session_id, \n  SessionExecuteRequest(\n    command='while true; do if (( RANDOM % 2 )); then echo \"All good at $(date)\"; else echo \"Oops, an error at $(date)\" >&2; fi; sleep 1; done',\n    run_async=True\n  )\n)\ntime.sleep(5)\n# Get the logs up to the current point in time\nlogs = sandbox.process.get_session_command_logs(session_id, command.cmd_id)\nprint(f\"[STDOUT]: {logs.stdout}\")\nprint(f\"[STDERR]: {logs.stderr}\")\nprint(f\"[OUTPUT]: {logs.output}\")\n\nsandbox.delete()\n```\n\n</TabItem>\n<TabItem label=\"Typescript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, SessionExecuteRequest } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n  const sandbox = await daytona.create()\n  const sessionId = \"exec-session-1\"\n  await sandbox.process.createSession(sessionId)\n\n  // Execute a blocking command and wait for the result\n  const command = await sandbox.process.executeSessionCommand(\n    sessionId,\n    {\n      command: 'echo \"Hello from stdout\" && echo \"Hello from stderr\" >&2',\n    },\n  )\n  console.log(`[STDOUT]: ${command.stdout}`)\n  console.log(`[STDERR]: ${command.stderr}`)\n  console.log(`[OUTPUT]: ${command.output}`)\n\n  // Or execute command in the background and get the logs later\n  const command2 = await sandbox.process.executeSessionCommand(\n    sessionId,\n    {\n      command: 'while true; do if (( RANDOM % 2 )); then echo \"All good at $(date)\"; else echo \"Oops, an error at $(date)\" >&2; fi; sleep 1; done',\n      runAsync: true,\n    },\n  )\n  await new Promise((resolve) => setTimeout(resolve, 5000))\n  // Get the logs up to the current point in time\n  const logs = await sandbox.process.getSessionCommandLogs(sessionId, command2.cmdId!)\n  console.log(`[STDOUT]: ${logs.stdout}`)\n  console.log(`[STDERR]: ${logs.stderr}`)\n  console.log(`[OUTPUT]: ${logs.output}`)\n\n  await sandbox.delete()\n}\n\nmain()\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\nsession_id = 'exec-session-1'\nsandbox.process.create_session(session_id)\n\n# Execute a blocking command and wait for the result\ncommand = sandbox.process.execute_session_command(\n  session_id,\n  Daytona::SessionExecuteRequest.new(\n    command: 'echo \"Hello from stdout\" && echo \"Hello from stderr\" >&2'\n  )\n)\nputs \"[STDOUT]: #{command.stdout}\"\nputs \"[STDERR]: #{command.stderr}\"\nputs \"[OUTPUT]: #{command.output}\"\n\n# Or execute command in the background and get the logs later\ncommand = sandbox.process.execute_session_command(\n  session_id,\n  Daytona::SessionExecuteRequest.new(\n    command: 'while true; do if (( RANDOM % 2 )); then echo \"All good at $(date)\"; else echo \"Oops, an error at $(date)\" >&2; fi; sleep 1; done',\n    var_async: true\n  )\n)\nsleep(5)\n# Get the logs up to the current point in time\nlogs = sandbox.process.get_session_command_logs(session_id, command.cmd_id)\nputs \"[STDOUT]: #{logs.stdout}\"\nputs \"[STDERR]: #{logs.stderr}\"\nputs \"[OUTPUT]: #{logs.output}\"\n\ndaytona.delete(sandbox)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n\tclient, _ := daytona.NewClient()\n\tctx := context.Background()\n\tsandbox, _ := client.Create(ctx, nil)\n\n\tsessionID := \"exec-session-1\"\n\tsandbox.Process.CreateSession(ctx, sessionID)\n\n\t// Execute a blocking command and wait for the result\n\tcmd1, _ := sandbox.Process.ExecuteSessionCommand(ctx, sessionID,\n\t\t`echo \"Hello from stdout\" && echo \"Hello from stderr\" >&2`, false)\n\tif stdout, ok := cmd1[\"stdout\"].(string); ok {\n\t\tfmt.Printf(\"[STDOUT]: %s\\n\", stdout)\n\t}\n\tif stderr, ok := cmd1[\"stderr\"].(string); ok {\n\t\tfmt.Printf(\"[STDERR]: %s\\n\", stderr)\n\t}\n\n\t// Or execute command in the background and get the logs later\n\tcmd := `counter=1; while (( counter <= 5 )); do echo \"Count: $counter\"; ((counter++)); sleep 1; done`\n\tcmdResult, _ := sandbox.Process.ExecuteSessionCommand(ctx, sessionID, cmd, true)\n\tcmdID, _ := cmdResult[\"id\"].(string)\n\n\ttime.Sleep(5 * time.Second)\n\n\t// Get the logs up to the current point in time\n\tlogs, err := sandbox.Process.GetSessionCommandLogs(ctx, sessionID, cmdID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get logs: %v\", err)\n\t}\n\tif logContent, ok := logs[\"logs\"].(string); ok {\n\t\tfmt.Printf(\"[LOGS]: %s\\n\", logContent)\n\t}\n\n\tsandbox.Delete(ctx)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}/command/{commandId}/logs'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/python-sdk/sync/process/), [TypeScript SDK](/docs/typescript-sdk/process/), [Ruby SDK](/docs/ruby-sdk/process/), [Go SDK](/docs/go-sdk/), and [API](/docs/en/tools/api/#daytona-toolbox/tag/process) references.\n\n> [**get_session_command_logs (Python SDK)**](/docs/python-sdk/sync/process/#processget_session_command_logs)\n>\n> [**getSessionCommandLogs (TypeScript SDK)**](/docs/typescript-sdk/process/#getsessioncommandlogs)\n>\n> [**get_session_command_logs (Ruby SDK)**](/docs/ruby-sdk/process/#get_session_command_logs)\n>\n> [**GetSessionCommandLogs (Go SDK)**](/docs/go-sdk/daytona/#ProcessService.GetSessionCommandLogs)\n>\n> [**get session command logs (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/POST/process/session/{sessionId}/exec)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/mcp.mdx",
    "content": "---\ntitle: Daytona MCP Server\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona Model Context Protocol (MCP) server enables AI agents to interact with [Daytona Sandboxes](/docs/en/sandboxes) programmatically. This guide covers how to set up and use the MCP server with various AI agents.\n\n## Install Daytona CLI\n\nInstall the Daytona CLI to manage the MCP server.\n\n<Tabs syncKey=\"os\">\n<TabItem label=\"Mac/Linux\">\n\n```bash\nbrew install daytonaio/cli/daytona\n```\n\n</TabItem>\n<TabItem label=\"Windows\">\n\n```bash\npowershell -Command \"irm https://get.daytona.io/windows | iex\"\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [CLI](/docs/en/tools/cli) reference.\n\n## Authenticate with Daytona\n\nAuthenticate with Daytona to enable MCP server access.\n\n<Tabs>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona login\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [CLI](/docs/en/tools/cli#daytona-login) reference:\n\n> [**login (CLI)**](/docs/en/tools/cli#daytona-login)\n\n## Initialize MCP server\n\nDaytona provides methods to initialize the MCP server with your preferred AI agent. Supported agents include Claude, Cursor, and Windsurf.\n\n<Tabs>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\n# Initialize with Claude\ndaytona mcp init claude\n\n# Initialize with Cursor\ndaytona mcp init cursor\n\n# Initialize with Windsurf\ndaytona mcp init windsurf\n```\n\n</TabItem>\n</Tabs>\n\nAfter initialization, open your AI agent application to begin using Daytona features.\n\nFor more information, see the [CLI](/docs/en/tools/cli#daytona-mcp-init) reference:\n\n> [**mcp init (CLI)**](/docs/en/tools/cli#daytona-mcp-init)\n\n## Configure MCP server\n\nDaytona provides methods to generate MCP configuration for integration with other AI agents.\n\n<Tabs>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona mcp config\n```\n\n</TabItem>\n</Tabs>\n\nThis command outputs a JSON configuration that you can copy into your agent's settings:\n\n```json\n{\n  \"mcpServers\": {\n    \"daytona-mcp\": {\n      \"command\": \"daytona\",\n      \"args\": [\"mcp\", \"start\"],\n      \"env\": {\n        \"HOME\": \"${HOME}\",\n        \"PATH\": \"${HOME}:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin\"\n      },\n      \"logFile\": \"${HOME}/Library/Logs/daytona/daytona-mcp-server.log\"\n    }\n  }\n}\n```\n\n:::note\nFor Windows users, add the following to the `env` field:\n<br />\n```json\n\"APPDATA\": \"${APPDATA}\"\n```\n:::\n\nFor more information, see the [CLI](/docs/en/tools/cli#daytona-mcp-config) reference:\n\n> [**mcp config (CLI)**](/docs/en/tools/cli#daytona-mcp-config)\n\n## Start MCP server\n\nDaytona provides methods to manually start the MCP server.\n\n<Tabs>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona mcp start\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [CLI](/docs/en/tools/cli#daytona-mcp-start) reference:\n\n> [**mcp start (CLI)**](/docs/en/tools/cli#daytona-mcp-start)\n\n## Available tools\n\nDaytona MCP server provides the following tools for interacting with Daytona Sandboxes:\n\n- [Sandbox management](/docs/en/sandboxes)\n- [File system operations](/docs/en/file-system-operations)\n- [Git operations](/docs/en/git-operations)\n- [Process and code execution](/docs/en/process-code-execution)\n- [Computer use](/docs/en/computer-use)\n- [Preview](/docs/en/preview)\n\n## Troubleshooting\n\nTo troubleshoot issues with the Daytona MCP server, try the following:\n\n- **Authentication issues**: run `daytona login` to refresh credentials\n- **Connection errors**: verify MCP server configuration, check server status\n- **Sandbox errors**: use `daytona list` to check sandbox status\n\nIf the issue persists, contact [support@daytona.io](mailto:support@daytona.io).\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/network-limits.mdx",
    "content": "---\ntitle: Network Limits (Firewall)\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona provides network egress limiting for sandboxes to control internet access. This feature can be automatically applied based on your [organization's limits](/docs/en/limits/) or manually configured for specific sandboxes.\n\n## Tier-based network restrictions\n\nNetwork limits are automatically applied to sandboxes based on your organization's billing tier. This provides secure and controlled internet access for development environments:\n\n- **Tier 1 & Tier 2**: Network access is restricted and cannot be overridden at the sandbox level. Organization-level network restrictions take precedence over sandbox-level settings. Even with [`networkAllowList`](#create-sandboxes-with-network-restrictions) specified when creating a sandbox, the organization's network restrictions still apply\n- **Tier 3 & Tier 4**: Full internet access is available by default, with the ability to configure custom network settings\n\n> To learn more about organization tiers and limits, see [limits](/docs/en/limits/).\n\n[Essential services](#essential-services) are available on all tiers and include services essential for development: package registries, container registries, Git repositories, CDN services, platform services, and system package managers.\n\n## Create sandboxes with network restrictions\n\nDaytona provides methods to control network access when [creating sandboxes](/docs/en/sandboxes#create-sandboxes) by using the `networkAllowList` and `networkBlockAll` parameters:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import CreateSandboxFromSnapshotParams, Daytona\n\ndaytona = Daytona()\n\n# Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(\n    network_allow_list='208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'\n))\n\n# Or block all network access\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(\n    network_block_all=True\n))\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\n\nconst daytona = new Daytona()\n\n// Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)\nconst sandbox = await daytona.create({\n  networkAllowList: '208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'\n})\n\n// Or block all network access\nconst sandbox = await daytona.create({\n  networkBlockAll: true\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(\n    network_allow_list: '208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'\n  )\n)\n\n# Or block all network access\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(\n    network_block_all: true\n  )\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tctx := context.Background()\n\n\t// Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)\n\tallowList := \"208.80.154.232/32,199.16.156.103/32,192.168.1.0/24\"\n\tsandbox, err := client.Create(ctx, types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tNetworkAllowList: &allowList,\n\t\t},\n\t})\n\n\t// Or block all network access\n\tsandbox, err = client.Create(ctx, types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tNetworkBlockAll: true,\n\t\t},\n\t})\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\n# Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --data '{\n    \"networkAllowList\": \"208.80.154.232/32,199.16.156.103/32,192.168.1.0/24\"\n  }'\n\n# Or block all network access\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_API_KEY' \\\n  --data '{\n    \"networkBlockAll\": true\n  }'\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\n# Allow access to specific IP addresses (Wikipedia, X/Twitter, private network)\ndaytona create --network-allow-list '208.80.154.232/32,199.16.156.103/32,192.168.1.0/24'\n\n# Or block all network access\ndaytona create --network-block-all\n```\n\n</TabItem>\n</Tabs>\n\n:::note\nIf both `networkBlockAll` and `networkAllowList` are specified, `networkBlockAll` takes precedence and all network access will be blocked, ignoring the allow list.\n:::\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/daytona#createsandboxbaseparams), [TypeScript SDK](/docs/en/typescript-sdk/daytona#createsandboxbaseparams), [Ruby SDK](/docs/en/ruby-sdk/sandbox#network_allow_list), [Go SDK](/docs/en/go-sdk/types#SandboxBaseParams), [API](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox), and [CLI](/docs/en/tools/cli#daytona-create) references:\n\n> [**network_allow_list (Python SDK)**](/docs/en/python-sdk/sync/daytona#createsandboxbaseparams)\n>\n> [**network_block_all (Python SDK)**](/docs/en/python-sdk/sync/daytona#createsandboxbaseparams)\n>\n> [**network_allow_list (TypeScript SDK)**](/docs/en/typescript-sdk/daytona#createsandboxbaseparams)\n>\n> [**network_block_all (TypeScript SDK)**](/docs/en/typescript-sdk/daytona#createsandboxbaseparams)\n>\n> [**network_allow_list (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#network_allow_list)\n>\n> [**network_block_all (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#network_allow_list)\n>\n> [**network_allow_list (Go SDK)**](/docs/en/go-sdk/types#SandboxBaseParams)\n>\n> [**network_block_all (Go SDK)**](/docs/en/go-sdk/types#SandboxBaseParams)\n>\n> [**networkAllowList (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox)\n>\n> [**networkBlockAll (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox)\n>\n> [**--network-allow-list (CLI)**](/docs/en/tools/cli#daytona-create)\n>\n> [**--network-block-all (CLI)**](/docs/en/tools/cli#daytona-create)\n\n## Network allow list format\n\nThe network allow list is a comma-separated list of IPv4 CIDR blocks. Set your allowed networks using the `networkAllowList` parameter when [creating a sandbox](/docs/en/sandboxes#create-sandboxes).\n\n- **IPv4 only**: hostnames, domains, and IPv6 are not supported\n- **CIDR required**: every entry must include a `/` prefix length integer in the range `0` to `32` (inclusive), for example: `/32`\n- **CIDR format**: use standard CIDR notation (`A.B.C.D/N`). Do not include extra `/` segments\n- **Max 10 entries**: the list cannot contain more than 10 comma-separated items\n- **Whitespace is ignored**: entries are trimmed, so spaces around commas are ok\n\nThe following examples are valid:\n\n- **Single IP**: `208.80.154.232/32` (Wikipedia)\n- **Subnet**: `192.168.1.0/24` (Private network)\n- **Multiple networks**: `208.80.154.232/32,199.16.156.103/32,10.0.0.0/8`\n\n## Organization configuration\n\nThe network access policies for your organization are set automatically depending on your organization's limits tier and cannot be modified by organization administrators. These policies determine the default network behavior for all sandboxes in your organization.\n\n## Test network access\n\nTo test network connectivity from your sandbox:\n\n```bash\n# Test HTTP connectivity to allowed addresses\ncurl -I https://208.80.154.232\n\n# Test package manager access (allowed on all tiers)\napt update  # For Ubuntu/Debian\nnpm ping    # For Node.js\npip install --dry-run requests  # For Python\n```\n\n## Security benefits\n\nNetwork limits provide several security advantages:\n\n- **Prevents data exfiltration** from sandboxes\n- **Reduces attack surface** by limiting external connections\n- **Complies with security policies** for development environments\n- **Enables fine-grained control** over network access\n\n:::caution\nEnabling unrestricted network access may pose security risks when executing untrusted code. It is recommended to whitelist specific network addresses using `networkAllowList` or block all network access using `networkBlockAll` instead.\n\nTest network connectivity before starting critical development work and consider upgrading your tier if you need access to many external services.\n:::\n\n## Essential services\n\nDaytona provides a list of essential services that are available on all tiers and can be used for development.\n\n:::note\nThis list is continuously updated. If you require access to additional essential development services, submit a request in the [sandbox network whitelist](https://github.com/daytonaio/sandbox-network-whitelist) repository or contact [support@daytona.io](mailto:support@daytona.io).\n:::\n\n### NPM registry and package managers\n\n- **NPM Registry**: `registry.npmjs.org`, `registry.npmjs.com`, `nodejs.org`, `nodesource.com`, `npm.pkg.github.com`\n- **Yarn Packages**: `yarnpkg.com`, `*.yarnpkg.com`, `yarn.npmjs.org`, `yarnpkg.netlify.com`\n- **Bun**: `bun.sh`, `*.bun.sh`\n\n### Git hosting and version control\n\n- **GitHub**: `github.com`, `*.github.com`, `*.githubusercontent.com`, `ghcr.io`\n- **GitLab**: `gitlab.com`, `*.gitlab.com`\n- **Bitbucket**: `bitbucket.org`\n- **Azure DevOps**: `dev.azure.com`, `*.dev.azure.com`, `login.microsoftonline.com`, `visualstudio.com`, `*.visualstudio.com`, `ssh.dev.azure.com`, `vs-ssh.visualstudio.com`\n\n### Python package managers\n\n- **PyPI**: `pypi.org`, `pypi.python.org`, `files.pythonhosted.org`, `bootstrap.pypa.io`, `astral.sh`\n\n### Composer packages\n\n- **Composer**: `*.packagist.org`, `packagist.com`\n\n### Ubuntu/Debian package repositories\n\n- **Ubuntu Repos**: `*.ubuntu.com`\n- **Debian Repos**: `*.debian.org`, `cdn-fastly.deb.debian.org`\n\n### CDN and content delivery\n\n- **CDN Services**: `fastly.com`, `cloudflare.com`, `r2.cloudflarestorage.com`, `*.r2.cloudflarestorage.com`\n- **JavaScript CDNs**: `unpkg.com`, `jsdelivr.net`\n\n### AI/ML services\n\n- **Anthropic**: `*.anthropic.com`, `claude.ai`, `platform.claude.com`\n- **OpenAI**: `openai.com`, `*.openai.com`, `chatgpt.com`\n- **Google AI**: `generativelanguage.googleapis.com`, `gemini.google.com`, `aistudio.google.com`, `ai.google.dev`, `models.dev`\n- **Perplexity**: `api.perplexity.ai`\n- **DeepSeek**: `api.deepseek.com`\n- **Groq**: `api.groq.com`\n- **Expo**: `api.expo.dev`\n- **OpenRouter**: `openrouter.ai`\n- **Qwen**: `chat.qwen.ai`, `dashscope.aliyuncs.com`, `dashscope-intl.aliyuncs.com`\n- **Cursor**: `*.cursor.com`\n- **OpenCode**: `opencode.ai`, `*.opencode.ai`\n- **Other AI Services**: `api.letta.com`, `api.fireworks.ai`, `open.bigmodel.cn`, `*.z.ai`, `*.moonshot.ai`, `ai-gateway.vercel.sh`, `api.featherless.ai`\n\n### Docker registries and container services\n\n- **Docker Registries**: `docker.io`, `*.docker.io`, `*.docker.com`\n- **Microsoft Container Registry**: `mcr.microsoft.com`\n- **Kubernetes Registry**: `registry.k8s.io`\n- **Google Container Registry**: `gcr.io`, `*.gcr.io`, `registry.cloud.google.com`\n- **Quay**: `quay.io`, `quay-registry.s3.amazonaws.com`\n\n### Maven repositories\n\n- **Maven Repos**: `repo1.maven.org`, `repo.maven.apache.org`\n\n### Google Fonts\n\n- **Google Fonts**: `fonts.googleapis.com`, `fonts.gstatic.com`\n\n### AWS S3 endpoints\n\n- **US East**: `s3.us-east-1.amazonaws.com`, `s3.us-east-2.amazonaws.com`\n- **US West**: `s3.us-west-1.amazonaws.com`, `s3.us-west-2.amazonaws.com`\n- **EU**: `s3.eu-central-1.amazonaws.com`, `s3.eu-west-1.amazonaws.com`, `s3.eu-west-2.amazonaws.com`\n\n### Google Cloud Storage\n\n- **GCS**: `storage.googleapis.com`\n\n### Daytona\n\n- **Daytona**: `app.daytona.io`\n\n### Developer tools and services\n\n- **Convex**: `convex.dev`, `*.convex.dev`, `*.convex.cloud`, `*.convex.site`\n- **Heroku**: `herokuapp.com`, `*.herokuapp.com`\n- **Vercel**: `vercel.com`, `*.vercel.com`, `*.vercel.app`\n- **Supabase**: `supabase.com`, `*.supabase.com`, `supabase.co`, `*.supabase.co`\n- **Clerk**: `clerk.com`, `*.clerk.com`, `clerk.dev`, `*.clerk.dev`, `accounts.dev`, `*.accounts.dev`, `clerk.accounts.dev`, `*.clerk.accounts.dev`\n- **WorkOS**: `workos.com`, `*.workos.com`, `authkit.app`, `*.authkit.app`\n- **Inngest**: `inngest.com`, `*.inngest.com`\n- **PostHog**: `posthog.com`, `*.posthog.com`\n- **Sentry**: `sentry.io`, `*.sentry.io`, `sentry-cdn.com`, `*.sentry-cdn.com`\n- **Linear**: `linear.app`, `*.linear.app`\n- **Figma**: `figma.com`, `*.figma.com`, `*.figmafiles.com`\n- **ClickUp**: `clickup.com`, `*.clickup.com`\n- **Playwright**: `playwright.dev`, `cdn.playwright.dev`\n\n### Messaging services\n\n- **Telegram**: `api.telegram.org`\n- **WhatsApp**: `web.whatsapp.com`, `*.whatsapp.net`\n\n### LLM observability\n\n- **Langfuse**: `*.langfuse.com`, `*.cloud.langfuse.com`\n\n## Troubleshooting\n\nIf you encounter network access issues or need unrestricted network access:\n\n1. Verify your [organization tier](/docs/en/limits#tier-upgrade) in the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/limits)\n2. Verify your [network allow list](#network-allow-list-format) configuration\n3. Contact [support@daytona.io](mailto:support@daytona.io) for assistance\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/organizations.mdx",
    "content": "---\ntitle: Organizations\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona provides organizations as a way to group resources and enable collaboration. Users can work individually in their personal organization or together in a collaborative organization.\n\nNavigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard) to manage your organizations.\n\n## Personal vs Collaborative organizations\n\nEvery Daytona user starts with a personal organization, ideal for solo use and experimentation. Collaborative organizations are created manually and designed for company-wide collaboration with shared access and controls.\n\n| **Feature**        | **Personal organization**        | **Collaborative organization**                 |\n| ------------------ | -------------------------------- | ---------------------------------------------- |\n| **Creation**       | Automatic on signup              | Manually by a user                             |\n| **Members**        | Single user only                 | Multiple users (invite-based)                  |\n| **Access Control** | No roles or permissions          | Roles with granular resource-based assignments |\n| **Billing**        | Tied to individual user          | Shared across team members                     |\n| **Use Case**       | Personal testing, small projects | Company/team development and production        |\n| **Quota Scope**    | Per user                         | Shared across all members                      |\n| **Deletable**      | No                               | Yes (by Owner)                                 |\n\nUsers can switch between their personal and collaborative organizations by using the dropdown in the [Daytona Dashboard ↗](https://app.daytona.io/dashboard) sidebar. Each organization has its own sandboxes, API keys, and resource quotas.\n\n## Organization roles\n\nUsers within an organization can have one of two different roles:\n\n1. **Owners** have full administrative access to the organization and its resources. Organization owners can perform administrative actions.\n2. **Members** have no administrative access to the organization, while their access to organization resources is based on [**Assignments**](#available-assignments).\n\n## Administrative actions\n\nOrganization owners can perform administrative actions such as:\n\n- [Invite new users to the organization](#inviting-new-users)\n- [Manage pending invitations](#managing-invitations)\n- [Change role](#organization-roles) of a user in the Organization\n- [Update assignments](#available-assignments) for organization members\n- Remove user from the organization\n- Inspect audit logs\n- [Delete organization](#organization-settings)\n\n## Available assignments\n\nThe list of available assignments includes:\n\n| Assignment                    | Description                                                         |\n| ----------------------------- | ------------------------------------------------------------------- |\n| **`Viewer (required)`**       | Grants read access to all resources in the organization             |\n| **`Developer`**               | Grants the ability to create sandboxes and keys in the organization |\n| **`Sandboxes Admin`**         | Grants admin access to sandboxes in the organization                |\n| **`Snapshots Admin`**         | Grants admin access to snapshots in the organization                |\n| **`Registries Admin`**        | Grants admin access to registries in the organization               |\n| **`Volumes Admin`**           | Grants admin access to volumes in the organization                  |\n| **`Super Admin`**             | Grants full access to all resources in the organization             |\n| **`Auditor`**                 | Grants access to audit logs in the organization                     |\n| **`Infrastructure Admin`**    | Grants admin access to infrastructure in the organization           |\n\n## Manage members\n\n### Invite new users\n\nAs an organization **Owner**, to invite a new user to your organization:\n\n1. Navigate to [Members ↗](https://app.daytona.io/dashboard/members)\n2. Click the **Invite Member** button\n3. Enter the email address of the user you want to invite\n4. [Select a role](#organization-roles) for the new user. If you select the **`Member`** role, define their [assignments](#available-assignments)\n\n### Remove users\n\nAs an organization **Owner**, to remove a user from your organization:\n\n1. Navigate to [Members ↗](https://app.daytona.io/dashboard/members)\n2. Click the **Remove** button next to the user you want to remove\n3. Confirm the removal by clicking the **Remove** button\n\n## Manage invitations\n\nTo view pending invitations to join other organizations, navigate to [Invitations ↗](https://app.daytona.io/dashboard/invitations) page by expanding the dropdown at the bottom of the sidebar. \n\nOnce a user accepts an invitation to join an organization, they get access to resource quotas assigned to that organization and they may proceed by issuing a new [API key](/docs/en/api-keys) and creating sandboxes.\n\n## Organization settings\n\nThe [Settings](https://app.daytona.io/dashboard/settings) subpage in the Dashboard allows you to view the Organization ID and Name and to delete the Organization if you don't need it anymore. This action is irreversible, so please proceed with caution. Personal Organizations are there by default and cannot be deleted.\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/oss-deployment.mdx",
    "content": "---\ntitle: Open Source Deployment\n---\n\nThis guide will walk you through running Daytona Open Source locally using Docker Compose.\n\nThe compose file can be found in the [docker](https://github.com/daytonaio/daytona/tree/main/docker) folder of the Daytona repository.\n\n:::caution\n\n- This setup is still in development and is **not safe to use in production**\n- For a fully licensed stable version, [contact sales](https://www.daytona.io/contact)\n  :::\n\n## Overview\n\nThe Docker Compose configuration includes all the necessary services to run Daytona:\n\n- **API**: Main Daytona application server\n- **Proxy**: Request proxy service\n- **Runner**: Service that hosts the Daytona Runner\n- **SSH Gateway**: Service that handles sandbox SSH access\n- **Database**: PostgreSQL database for data persistence\n- **Redis**: In-memory data store for caching and sessions\n- **Dex**: OIDC authentication provider\n- **Registry**: Docker image registry with web UI\n- **MinIO**: S3-compatible object storage\n- **MailDev**: Email testing service\n- **Jaeger**: Distributed tracing\n- **PgAdmin**: Database administration interface\n\n## Quick Start\n\n1. Clone the [Daytona repository](https://github.com/daytonaio/daytona)\n2. [Install Docker and Docker Compose](https://docs.docker.com/get-docker/)\n3. Run the following command (from the root of the Daytona repo) to start all services:\n\n   ```bash\n   docker compose -f docker/docker-compose.yaml up -d\n   ```\n\n4. Access the services:\n   - Daytona Dashboard: http://localhost:3000\n     - Access Credentials: dev@daytona.io `password`\n     - Make sure that the default snapshot is active at http://localhost:3000/dashboard/snapshots\n   - PgAdmin: http://localhost:5050\n   - Registry UI: http://localhost:5100\n   - MinIO Console: http://localhost:9001 (minioadmin / minioadmin)\n\n## DNS Setup for Proxy URLs\n\nFor local development, you need to resolve `*.proxy.localhost` domains to `127.0.0.1`:\n\n```bash\n./scripts/setup-proxy-dns.sh\n```\n\nThis configures dnsmasq with `address=/proxy.localhost/127.0.0.1`.\n\n**Without this setup**, SDK examples and direct proxy access won't work.\n\n## Development Notes\n\n- The setup uses shared networking for simplified service communication\n- Database and storage data is persisted in Docker volumes\n- The registry is configured to allow image deletion for testing\n- Sandbox resource limits are disabled due to inability to partition cgroups in DinD environment where the sock is not mounted\n\n## Additional Network Options\n\n### HTTP Proxy\n\nTo configurate an outbound HTTP proxy for the Daytona services, you can set the following environment variables in the `docker-compose.yaml` file for each service that requires proxy access (the API service is the only that requires outbound access to pull images):\n\n- `HTTP_PROXY`: URL of the HTTP proxy server\n- `HTTPS_PROXY`: URL of the HTTPS proxy server\n- `NO_PROXY`: Comma-separated list of hostnames or IP addresses that should bypass the proxy\n\nThe baseline configuration for the API service should be as follows:\n\n```yaml\nenvironment:\n  - HTTP_PROXY=<your-proxy>\n  - HTTPS_PROXY=<your-proxy>\n  - NO_PROXY=localhost,runner,dex,registry,minio,jaeger,otel-collector,<your-proxy>\n```\n\n### Extra CA Certificates\n\nTo configure extra CA certificates (for example, paired with `DB_TLS` env vars), set the following environment variable in the API service:\n\n```yaml\nenvironment:\n  - NODE_EXTRA_CA_CERTS=/path/to/your/cert-bundle.pembundle\n```\n\nThe provided file is a cert bundle. Meaning it can contain multiple CA certificates in PEM format.\n\n## Environment Variables\n\nYou can customize the deployment by modifying environment variables in the `docker-compose.yaml` file.\nBelow is a full list of environment variables with their default values:\n\n### API Service\n\n| Variable                                   | Type    | Default Value                                        | Description                                                                                          |\n| ------------------------------------------ | ------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |\n| `ENCRYPTION_KEY`                           | string  | `supersecretkey`                                     | Encryption key for sensitive data (User must override outside of Compose)                            |\n| `ENCRYPTION_SALT`                          | string  | `supersecretsalt`                                    | Encryption salt for sensitive data (User must override outside of Compose)                           |\n| `PORT`                                     | number  | `3000`                                               | API service port                                                                                     |\n| `DB_HOST`                                  | string  | `db`                                                 | PostgreSQL database hostname                                                                         |\n| `DB_PORT`                                  | number  | `5432`                                               | PostgreSQL database port                                                                             |\n| `DB_USERNAME`                              | string  | `user`                                               | PostgreSQL database username                                                                         |\n| `DB_PASSWORD`                              | string  | `pass`                                               | PostgreSQL database password                                                                         |\n| `DB_DATABASE`                              | string  | `daytona`                                            | PostgreSQL database name                                                                             |\n| `DB_TLS_ENABLED`                           | boolean | `false`                                              | Enable TLS for database connection                                                                   |\n| `DB_TLS_REJECT_UNAUTHORIZED`               | boolean | `true`                                               | Reject unauthorized TLS certificates                                                                 |\n| `REDIS_HOST`                               | string  | `redis`                                              | Redis server hostname                                                                                |\n| `REDIS_PORT`                               | number  | `6379`                                               | Redis server port                                                                                    |\n| `OIDC_CLIENT_ID`                           | string  | `daytona`                                            | OIDC client identifier                                                                               |\n| `OIDC_ISSUER_BASE_URL`                     | string  | `http://dex:5556/dex`                                | OIDC issuer base URL                                                                                 |\n| `PUBLIC_OIDC_DOMAIN`                       | string  | `http://localhost:5556/dex`                          | Public OIDC domain                                                                                   |\n| `OIDC_AUDIENCE`                            | string  | `daytona`                                            | OIDC audience identifier                                                                             |\n| `OIDC_MANAGEMENT_API_ENABLED`              | boolean | (empty)                                              | Enable OIDC management API                                                                           |\n| `OIDC_MANAGEMENT_API_CLIENT_ID`            | string  | (empty)                                              | OIDC management API client ID                                                                        |\n| `OIDC_MANAGEMENT_API_CLIENT_SECRET`        | string  | (empty)                                              | OIDC management API client secret                                                                    |\n| `OIDC_MANAGEMENT_API_AUDIENCE`             | string  | (empty)                                              | OIDC management API audience                                                                         |\n| `DEFAULT_SNAPSHOT`                         | string  | `daytonaio/sandbox:0.4.3`                            | Default sandbox snapshot image                                                                       |\n| `DASHBOARD_URL`                            | string  | `http://localhost:3000/dashboard`                    | Dashboard URL                                                                                        |\n| `DASHBOARD_BASE_API_URL`                   | string  | `http://localhost:3000`                              | Dashboard base API URL                                                                               |\n| `POSTHOG_API_KEY`                          | string  | `phc_bYtEsdMDrNLydXPD4tufkBrHKgfO2zbycM30LOowYNv`    | PostHog API key for analytics                                                                        |\n| `POSTHOG_HOST`                             | string  | `https://d18ag4dodbta3l.cloudfront.net`              | PostHog host URL                                                                                     |\n| `POSTHOG_ENVIRONMENT`                      | string  | `local`                                              | PostHog environment identifier                                                                       |\n| `TRANSIENT_REGISTRY_URL`                   | string  | `http://registry:6000`                               | Transient registry URL                                                                               |\n| `TRANSIENT_REGISTRY_ADMIN`                 | string  | `admin`                                              | Transient registry admin username                                                                    |\n| `TRANSIENT_REGISTRY_PASSWORD`              | string  | `password`                                           | Transient registry admin password                                                                    |\n| `TRANSIENT_REGISTRY_PROJECT_ID`            | string  | `daytona`                                            | Transient registry project ID                                                                        |\n| `INTERNAL_REGISTRY_URL`                    | string  | `http://registry:6000`                               | Internal registry URL                                                                                |\n| `INTERNAL_REGISTRY_ADMIN`                  | string  | `admin`                                              | Internal registry admin username                                                                     |\n| `INTERNAL_REGISTRY_PASSWORD`               | string  | `password`                                           | Internal registry admin password                                                                     |\n| `INTERNAL_REGISTRY_PROJECT_ID`             | string  | `daytona`                                            | Internal registry project ID                                                                         |\n| `SMTP_HOST`                                | string  | `maildev`                                            | SMTP server hostname                                                                                 |\n| `SMTP_PORT`                                | number  | `1025`                                               | SMTP server port                                                                                     |\n| `SMTP_USER`                                | string  | (empty)                                              | SMTP username                                                                                        |\n| `SMTP_PASSWORD`                            | string  | (empty)                                              | SMTP password                                                                                        |\n| `SMTP_SECURE`                              | boolean | (empty)                                              | Enable SMTP secure connection                                                                        |\n| `SMTP_EMAIL_FROM`                          | string  | `\"Daytona Team <no-reply@daytona.io>\"`               | SMTP sender email address                                                                            |\n| `S3_ENDPOINT`                              | string  | `http://minio:9000`                                  | S3-compatible storage endpoint                                                                       |\n| `S3_STS_ENDPOINT`                          | string  | `http://minio:9000/minio/v1/assume-role`             | S3 STS endpoint                                                                                      |\n| `S3_REGION`                                | string  | `us-east-1`                                          | S3 region                                                                                            |\n| `S3_ACCESS_KEY`                            | string  | `minioadmin`                                         | S3 access key                                                                                        |\n| `S3_SECRET_KEY`                            | string  | `minioadmin`                                         | S3 secret key                                                                                        |\n| `S3_DEFAULT_BUCKET`                        | string  | `daytona`                                            | S3 default bucket name                                                                               |\n| `S3_ACCOUNT_ID`                            | string  | `/`                                                  | S3 account ID                                                                                        |\n| `S3_ROLE_NAME`                             | string  | `/`                                                  | S3 role name                                                                                         |\n| `ENVIRONMENT`                              | string  | `dev`                                                | Application environment                                                                              |\n| `MAX_AUTO_ARCHIVE_INTERVAL`                | number  | `43200`                                              | Maximum auto-archive interval (seconds)                                                              |\n| `OTEL_ENABLED`                             | boolean | `true`                                               | Enable OpenTelemetry tracing                                                                         |\n| `OTEL_COLLECTOR_URL`                       | string  | `http://jaeger:4318/v1/traces`                       | OpenTelemetry collector URL                                                                          |\n| `MAINTENANCE_MODE`                         | boolean | `false`                                              | Enable maintenance mode                                                                              |\n| `PROXY_DOMAIN`                             | string  | `proxy.localhost:4000`                               | Proxy domain                                                                                         |\n| `PROXY_PROTOCOL`                           | string  | `http`                                               | Proxy protocol                                                                                       |\n| `PROXY_API_KEY`                            | string  | `super_secret_key`                                   | Proxy API key                                                                                        |\n| `PROXY_TEMPLATE_URL`                       | string  | `http://{{PORT}}-{{sandboxId}}.proxy.localhost:4000` | Proxy template URL pattern                                                                           |\n| `PROXY_TOOLBOX_BASE_URL`                   | string  | `{PROXY_PROTOCOL}://{PROXY_DOMAIN}`                  | Proxy base URL for toolbox requests                                                                  |\n| `DEFAULT_RUNNER_DOMAIN`                    | string  | `runner:3003`                                        | Default runner domain                                                                                |\n| `DEFAULT_RUNNER_API_URL`                   | string  | `http://runner:3003`                                 | Default runner API URL                                                                               |\n| `DEFAULT_RUNNER_PROXY_URL`                 | string  | `http://runner:3003`                                 | Default runner proxy URL                                                                             |\n| `DEFAULT_RUNNER_API_KEY`                   | string  | `secret_api_token`                                   | Default runner API key                                                                               |\n| `DEFAULT_RUNNER_CPU`                       | number  | `4`                                                  | Default runner CPU allocation                                                                        |\n| `DEFAULT_RUNNER_MEMORY`                    | number  | `8`                                                  | Default runner memory allocation (GB)                                                                |\n| `DEFAULT_RUNNER_DISK`                      | number  | `50`                                                 | Default runner disk allocation (GB)                                                                  |\n| `DEFAULT_RUNNER_API_VERSION`               | string  | `0`                                                  | Default runner API version                                                                           |\n| `DEFAULT_ORG_QUOTA_TOTAL_CPU_QUOTA`        | number  | `10000`                                              | Default organization total CPU quota                                                                 |\n| `DEFAULT_ORG_QUOTA_TOTAL_MEMORY_QUOTA`     | number  | `10000`                                              | Default organization total memory quota                                                              |\n| `DEFAULT_ORG_QUOTA_TOTAL_DISK_QUOTA`       | number  | `100000`                                             | Default organization total disk quota                                                                |\n| `DEFAULT_ORG_QUOTA_MAX_CPU_PER_SANDBOX`    | number  | `100`                                                | Default organization max CPU per sandbox                                                             |\n| `DEFAULT_ORG_QUOTA_MAX_MEMORY_PER_SANDBOX` | number  | `100`                                                | Default organization max memory per sandbox                                                          |\n| `DEFAULT_ORG_QUOTA_MAX_DISK_PER_SANDBOX`   | number  | `1000`                                               | Default organization max disk per sandbox                                                            |\n| `DEFAULT_ORG_QUOTA_SNAPSHOT_QUOTA`         | number  | `1000`                                               | Default organization snapshot quota                                                                  |\n| `DEFAULT_ORG_QUOTA_MAX_SNAPSHOT_SIZE`      | number  | `1000`                                               | Default organization max snapshot size                                                               |\n| `DEFAULT_ORG_QUOTA_VOLUME_QUOTA`           | number  | `10000`                                              | Default organization volume quota                                                                    |\n| `SSH_GATEWAY_API_KEY`                      | string  | `ssh_secret_api_token`                               | SSH gateway API key                                                                                  |\n| `SSH_GATEWAY_COMMAND`                      | string  | `ssh -p 2222 {{TOKEN}}@localhost`                    | SSH gateway command template                                                                         |\n| `SSH_GATEWAY_PUBLIC_KEY`                   | string  | (Base64-encoded OpenSSH public key)                  | SSH gateway public key for authentication                                                            |\n| `SSH_GATEWAY_URL`                          | string  | `localhost:2222`                                     | SSH gateway URL                                                                                      |\n| `RUNNER_DECLARATIVE_BUILD_SCORE_THRESHOLD` | number  | `10`                                                 | Runner declarative build score threshold                                                             |\n| `RUNNER_AVAILABILITY_SCORE_THRESHOLD`      | number  | `10`                                                 | Runner availability score threshold                                                                  |\n| `RUNNER_HEALTH_TIMEOUT_SECONDS`            | number  | `3`                                                  | Runner health-check timeout in seconds                                                               |\n| `RUNNER_START_SCORE_THRESHOLD`             | number  | `3`                                                  | Runner start score threshold                                                                         |\n| `RUN_MIGRATIONS`                           | boolean | `true`                                               | Enable database migrations on startup                                                                |\n| `ADMIN_API_KEY`                            | string  | (empty)                                              | Admin API key, auto-generated if empty, used only upon initial setup, not recommended for production |\n| `ADMIN_TOTAL_CPU_QUOTA`                    | number  | `0`                                                  | Admin total CPU quota, used only upon initial setup                                                  |\n| `ADMIN_TOTAL_MEMORY_QUOTA`                 | number  | `0`                                                  | Admin total memory quota, used only upon initial setup                                               |\n| `ADMIN_TOTAL_DISK_QUOTA`                   | number  | `0`                                                  | Admin total disk quota, used only upon initial setup                                                 |\n| `ADMIN_MAX_CPU_PER_SANDBOX`                | number  | `0`                                                  | Admin max CPU per sandbox, used only upon initial setup                                              |\n| `ADMIN_MAX_MEMORY_PER_SANDBOX`             | number  | `0`                                                  | Admin max memory per sandbox, used only upon initial setup                                           |\n| `ADMIN_MAX_DISK_PER_SANDBOX`               | number  | `0`                                                  | Admin max disk per sandbox, used only upon initial setup                                             |\n| `ADMIN_SNAPSHOT_QUOTA`                     | number  | `100`                                                | Admin snapshot quota, used only upon initial setup                                                   |\n| `ADMIN_MAX_SNAPSHOT_SIZE`                  | number  | `100`                                                | Admin max snapshot size, used only upon initial setup                                                |\n| `ADMIN_VOLUME_QUOTA`                       | number  | `0`                                                  | Admin volume quota, used only upon initial setup                                                     |\n| `SKIP_USER_EMAIL_VERIFICATION`             | boolean | `true`                                               | Skip user email verification process                                                                 |\n| `RATE_LIMIT_ANONYMOUS_TTL`                 | number  | (empty)                                              | Anonymous rate limit time-to-live (seconds, empty - rate limit is disabled)                          |\n| `RATE_LIMIT_ANONYMOUS_LIMIT`               | number  | (empty)                                              | Anonymous rate limit (requests per TTL, empty - rate limit is disabled)                              |\n| `RATE_LIMIT_AUTHENTICATED_TTL`             | number  | (empty)                                              | Authenticated rate limit time-to-live (seconds, empty - rate limit is disabled)                      |\n| `RATE_LIMIT_AUTHENTICATED_LIMIT`           | number  | (empty)                                              | Authenticated rate limit (requests per TTL, empty - rate limit is disabled)                          |\n| `RATE_LIMIT_SANDBOX_CREATE_TTL`            | number  | (empty)                                              | Sandbox create rate limit time-to-live (seconds, empty - rate limit is disabled)                     |\n| `RATE_LIMIT_SANDBOX_CREATE_LIMIT`          | number  | (empty)                                              | Sandbox create rate limit (requests per TTL, empty - rate limit is disabled)                         |\n| `RATE_LIMIT_SANDBOX_LIFECYCLE_TTL`         | number  | (empty)                                              | Sandbox lifecycle rate limit time-to-live (seconds, empty - rate limit is disabled)                  |\n| `RATE_LIMIT_SANDBOX_LIFECYCLE_LIMIT`       | number  | (empty)                                              | Sandbox lifecycle rate limit (requests per TTL, empty - rate limit is disabled)                      |\n| `RATE_LIMIT_FAILED_AUTH_TTL`               | number  | (empty)                                              | Failed authentication rate limit time-to-live (seconds, empty - rate limit is disabled)              |\n| `RATE_LIMIT_FAILED_AUTH_LIMIT`             | number  | (empty)                                              | Failed authentication rate limit (requests per TTL, empty - rate limit is disabled)                  |\n| `DEFAULT_REGION_ID`                        | string  | `us`                                                 | Default region ID                                                                                    |\n| `DEFAULT_REGION_NAME`                      | string  | `us`                                                 | Default region name                                                                                  |\n| `DEFAULT_REGION_ENFORCE_QUOTAS`            | boolean | `false`                                              | Enable region-based resource limits for default region                                               |\n| `OTEL_COLLECTOR_API_KEY`                   | string  | `otel_collector_api_key`                             | OpenTelemetry collector API key for authentication (only needed if otel collector is deployed)       |\n| `CLICKHOUSE_HOST`                          | string  | (empty)                                              | ClickHouse host for querying sandbox otel                                                            |\n| `CLICKHOUSE_DATABASE`                      | string  | `otel`                                               | ClickHouse database for querying sandbox otel                                                        |\n| `CLICKHOUSE_PORT`                          | number  | `8123`                                               | ClickHouse port                                                                                      |\n| `CLICKHOUSE_USERNAME`                      | string  | (empty)                                              | ClickHouse username                                                                                  |\n| `CLICKHOUSE_PASSWORD`                      | string  | (empty)                                              | ClickHouse password                                                                                  |\n| `CLICKHOUSE_PROTOCOL`                      | string  | `https`                                              | ClickHouse protocol (e.g., `http` or `https`)                                                        |\n| `SANDBOX_OTEL_ENDPOINT_URL`                | string  | (empty)                                              | OpenTelemetry endpoint URL for sandbox traces                                                        |\n| `HEALTH_CHECK_API_KEY`                     | string  | `supersecretkey`                                     | Authentication key for the readiness health-check route.                                             |\n| `NOTIFICATION_GATEWAY_DISABLED`            | boolean | `false`                                              | Disable notification gateway service                                                                 |\n\n### Runner\n\n| Variable                                | Type    | Default Value                     | Description                                           |\n| --------------------------------------- | ------- | --------------------------------- | ----------------------------------------------------- |\n| `DAYTONA_API_URL`                       | string  | `http://api:3000/api`             | Daytona API URL                                       |\n| `DAYTONA_RUNNER_TOKEN`                  | string  | `secret_api_token`                | Runner API authentication token                       |\n| `VERSION`                               | string  | `0.0.1`                           | Runner service version                                |\n| `OTEL_LOGGING_ENABLED`                  | boolean | `false`                           | Runner OpenTelemetry logging enabled                  |\n| `OTEL_TRACING_ENABLED`                  | boolean | `false`                           | Runner OpenTelemetry tracing enabled                  |\n| `OTEL_EXPORTER_OTLP_ENDPOINT`           | string  | (empty)                           | Runner OpenTelemetry OTLP exporter endpoint           |\n| `OTEL_EXPORTER_OTLP_HEADERS`            | string  | (empty)                           | Runner OpenTelemetry OTLP exporter headers            |\n| `ENVIRONMENT`                           | string  | `development`                     | Application environment                               |\n| `API_PORT`                              | number  | `3003`                            | Runner API service port                               |\n| `LOG_FILE_PATH`                         | string  | `/home/daytona/runner/runner.log` | Path to runner log file                               |\n| `RESOURCE_LIMITS_DISABLED`              | boolean | `true`                            | Disable resource limits for sandboxes                 |\n| `AWS_ENDPOINT_URL`                      | string  | `http://minio:9000`               | AWS S3-compatible storage endpoint                    |\n| `AWS_REGION`                            | string  | `us-east-1`                       | AWS region                                            |\n| `AWS_ACCESS_KEY_ID`                     | string  | `minioadmin`                      | AWS access key ID                                     |\n| `AWS_SECRET_ACCESS_KEY`                 | string  | `minioadmin`                      | AWS secret access key                                 |\n| `AWS_DEFAULT_BUCKET`                    | string  | `daytona`                         | AWS default bucket name                               |\n| `DAEMON_START_TIMEOUT_SEC`              | number  | `60`                              | Daemon start timeout in seconds                       |\n| `SANDBOX_START_TIMEOUT_SEC`             | number  | `30`                              | Sandbox start timeout in seconds                      |\n| `USE_SNAPSHOT_ENTRYPOINT`               | boolean | `false`                           | Use snapshot entrypoint for sandbox                   |\n| `RUNNER_DOMAIN`                         | string  | (none)                            | Runner domain name (hostname for runner URLs)         |\n| `VOLUME_CLEANUP_INTERVAL`               | number  | `30s`                             | Volume cleanup interval in seconds (minimum: 10s)     |\n| `COLLECTOR_WINDOW_SIZE`                 | number  | `60`                              | Metrics collector window size (number of samples)     |\n| `CPU_USAGE_SNAPSHOT_INTERVAL`           | string  | `5s`                              | CPU usage snapshot interval duration (minimum: 1s)    |\n| `ALLOCATED_RESOURCES_SNAPSHOT_INTERVAL` | string  | `5s`                              | Allocated resources snapshot interval (minimum: 1s)   |\n| `POLL_TIMEOUT`                          | string  | `30s`                             | Poller service timeout duration (e.g., `30s`, `1m`)   |\n| `POLL_LIMIT`                            | number  | `10`                              | Maximum poll attempts per request (min: 1, max: 100)  |\n| `HEALTHCHECK_INTERVAL`                  | string  | `30s`                             | Interval between health checks (minimum: 10s)         |\n| `HEALTHCHECK_TIMEOUT`                   | string  | `10s`                             | Health check timeout duration                         |\n| `API_VERSION`                           | number  | `2`                               | Runner API version (default: 2)                       |\n| `SNAPSHOT_ERROR_CACHE_RETENTION`        | string  | `10m`                             | Snapshot error cache retention duration (minimum: 5m) |\n\n### SSH Gateway\n\n| Variable           | Type   | Default Value                        | Description                |\n| ------------------ | ------ | ------------------------------------ | -------------------------- |\n| `API_URL`          | string | `http://api:3000/api`                | Daytona API URL            |\n| `API_KEY`          | string | `ssh_secret_api_token`               | API authentication key     |\n| `SSH_PRIVATE_KEY`  | string | (Base64-encoded OpenSSH private key) | SSH private key for auth   |\n| `SSH_HOST_KEY`     | string | (Base64-encoded OpenSSH host key)    | SSH host key for server    |\n| `SSH_GATEWAY_PORT` | number | `2222`                               | SSH gateway listening port |\n\n### Proxy\n\n| Variable                  | Type    | Default Value               | Description                     |\n| ------------------------- | ------- | --------------------------- | ------------------------------- |\n| `DAYTONA_API_URL`         | string  | `http://api:3000/api`       | Daytona API URL                 |\n| `PROXY_PORT`              | number  | `4000`                      | Proxy service port              |\n| `PROXY_API_KEY`           | string  | `super_secret_key`          | Proxy API authentication key    |\n| `PROXY_PROTOCOL`          | string  | `http`                      | Proxy protocol (http or https)  |\n| `COOKIE_DOMAIN`           | string  | `$PROXY_DOMAIN`             | Cookie domain for proxy cookies |\n| `OIDC_CLIENT_ID`          | string  | `daytona`                   | OIDC client identifier          |\n| `OIDC_CLIENT_SECRET`      | string  | (empty)                     | OIDC client secret              |\n| `OIDC_DOMAIN`             | string  | `http://dex:5556/dex`       | OIDC domain                     |\n| `OIDC_PUBLIC_DOMAIN`      | string  | `http://localhost:5556/dex` | OIDC public domain              |\n| `OIDC_AUDIENCE`           | string  | `daytona`                   | OIDC audience identifier        |\n| `REDIS_HOST`              | string  | `redis`                     | Redis server hostname           |\n| `REDIS_PORT`              | number  | `6379`                      | Redis server port               |\n| `TOOLBOX_ONLY_MODE`       | boolean | `false`                     | Allow only toolbox requests     |\n| `PREVIEW_WARNING_ENABLED` | boolean | `false`                     | Enable browser preview warning  |\n| `SHUTDOWN_TIMEOUT_SEC`    | number  | `3600`                      | Shutdown timeout in seconds     |\n\n## [OPTIONAL] Configure Auth0 for Authentication\n\nThe default compose setup uses a local Dex OIDC provider for authentication. However, you can configure Auth0 as an alternative OIDC provider by following these steps:\n\n### Step 1: Create Your Auth0 Tenant\n\nBegin by navigating to https://auth0.com/signup and start the signup process. Choose your account type based on your use case - select `Company` for business applications or `Personal` for individual projects.\\\nOn the \"Let's get setup\" page, you'll need to enter your application name such as `My Daytona` and select `Single Page Application (SPA)` as the application type. For authentication methods, you can start with `Email and Password` since additional social providers like Google, GitHub, or Facebook can be added later. Once you've configured these settings, click `Create Application` in the bottom right corner.\n\n### Step 2: Configure Your Single Page Application\n\nNavigate to `Applications` > `Applications` in the left sidebar and select the application you just created. Click the `Settings` tab and scroll down to find the `Application URIs` section where you'll configure the callback and origin URLs.\nIn the `Allowed Callback URIs` field, add the following URLs:\n\n```\nhttp://localhost:3000\nhttp://localhost:3000/api/oauth2-redirect.html\nhttp://localhost:4000/callback\nhttp://proxy.localhost:4000/callback\n```\n\nFor `Allowed Logout URIs`, add:\n\n```\nhttp://localhost:3000\n```\n\nAnd for `Allowed Web Origins`, add:\n\n```\nhttp://localhost:3000\n```\n\nRemember to click `Save Changes` at the bottom of the page to apply these configurations.\n\n### Step 3: Create Machine-to-Machine Application\n\nYou'll need a Machine-to-Machine application to interact with Auth0's Management API. Go to `Applications` > `Applications` and click `Create Application`. Choose `Machine to Machine Applications` as the type and provide a descriptive name like `My Management API M2M`.\nAfter creating the application, navigate to the `APIs` tab within your new M2M application. Find and authorize the `Auth0 Management API` by clicking the toggle or authorize button.\\\nOnce authorized, click the dropdown arrow next to the Management API to configure permissions. Grant the following permissions to your M2M application:\n\n```\nread:users\nupdate:users\nread:connections\ncreate:guardian_enrollment_tickets\nread:connections_options\n```\n\nClick `Save` to apply these permission changes.\n\n### Step 4: Set Up Custom API\n\nYour Daytona application will need a custom API to handle authentication and authorization. Navigate to `Applications` > `APIs` in the left sidebar and click `Create API`. Enter a descriptive name such as `My Daytona API` and provide an identifier like `my-daytona-api`. The identifier should be a unique string that will be used in your application configuration.\\\nAfter creating the API, go to the `Permissions` tab to define the scopes your application will use. Add each of the following permissions with their corresponding descriptions:\n\n| Permission                  | Description                              |\n| --------------------------- | ---------------------------------------- |\n| `read:node`                 | Get workspace node info                  |\n| `create:node`               | Create new workspace node record         |\n| `create:user`               | Create user account                      |\n| `read:users`                | Get all user accounts                    |\n| `regenerate-key-pair:users` | Regenerate user SSH key-pair             |\n| `read:workspaces`           | Read workspaces (user scope)             |\n| `create:registry`           | Create a new docker registry auth record |\n| `read:registries`           | Get all docker registry records          |\n| `read:registry`             | Get docker registry record               |\n| `write:registry`            | Create or update docker registry record  |\n\n### Step 5: Configure Environment Variables\n\nOnce you've completed all the Auth0 setup steps, you'll need to configure environment variables in your Daytona deployment. These variables connect your application to the Auth0 services you've just configured.\n\n#### Finding Your Configuration Values\n\nYou can find the necessary values in the Auth0 dashboard. For your SPA application settings, go to `Applications` > `Applications`, select your SPA app, and click the `Settings` tab. For your M2M application, follow the same path but select your Machine-to-Machine app instead. Custom API settings are located under `Applications` > `APIs`, then select your custom API and go to `Settings`.\n\n#### API Service Configuration\n\nConfigure the following environment variables for your API service:\n\n```bash\nOIDC_CLIENT_ID=your_spa_app_client_id\nOIDC_ISSUER_BASE_URL=your_spa_app_domain\nOIDC_AUDIENCE=your_custom_api_identifier\nOIDC_MANAGEMENT_API_ENABLED=true\nOIDC_MANAGEMENT_API_CLIENT_ID=your_m2m_app_client_id\nOIDC_MANAGEMENT_API_CLIENT_SECRET=your_m2m_app_client_secret\nOIDC_MANAGEMENT_API_AUDIENCE=your_auth0_managment_api_identifier\n```\n\n#### Proxy Service Configuration\n\nFor your proxy service, configure these environment variables:\n\n```bash\nOIDC_CLIENT_ID=your_spa_app_client_id\nOIDC_CLIENT_SECRET=\nOIDC_DOMAIN=your_spa_app_domain\nOIDC_AUDIENCE=your_custom_api_identifier (with trailing slash)\n```\n\nNote that `OIDC_CLIENT_SECRET` should remain empty for your proxy environment.\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/playground.mdx",
    "content": "---\ntitle: Playground\n---\n\nDaytona provides an interactive environment (\"Playground\") for creating sandboxes, running SDK operations, and exploring Daytona features directly from your browser.\n\n- **Interactive sandbox creation**: configure and create sandboxes with custom resources\n- **Code snippet generation**: automatically generate SDK code samples based on the values configured in the [management](#management) section\n- [Web terminal](/docs/en/web-terminal): run commands directly in your sandbox through a built-in web terminal\n- [VNC access](/docs/en/vnc-access): interact with GUI applications using [Computer Use](/docs/en/computer-use) features\n\n## Access from Dashboard\n\nNavigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard/playground) to access the playground.\n\nPlayground consists of three tabs: [Sandbox](#sandbox), [Terminal](#terminal), and [VNC](#vnc). All three tabs operate on the same active sandbox.\n\n## Sandbox\n\nThe sandbox tab provides an interactive interface to configure sandboxes and perform SDK operations. The left panel contains configurable parameters organized into collapsible sections. The right panel displays auto-generated code snippets that you can inspect, copy, and run.\n\n### Management\n\nThe management section contains the parameters used to configure a sandbox. You can edit these parameters to customize your sandbox and its resources.\n\n- [sandbox language](/docs/en/sandboxes#multiple-runtime-support): select a programming language runtime for the sandbox\n- [sandbox resources](/docs/en/sandboxes#resources): configure resources allocated to the sandbox\n- [sandbox lifecycle](/docs/en/sandboxes#sandbox-lifecycle): set the sandbox lifecycle policies\n\n:::note\nIn the management section, sandboxes are only created when you explicitly click **Run**, replacing any existing playground sandbox. In the [Terminal](#terminal) or [VNC](#vnc) tabs, if there are no active sandboxes, the playground automatically creates one using the configured parameters.\n:::\n\n### File system\n\nThe file system section provides operations to manage files and directories in the sandbox. You can modify files and directories in the sandbox using the following operations:\n\n- **Create a new directory**: set the directory location and its permissions\n- **List files and directories**: set the directory location\n- **Delete files**: set the file location and delete directory checkbox\n\nFor more information, see [file system operations](/docs/en/file-system-operations).\n\n### Git operations\n\nThe Git operations section provides operations to manage Git repositories in the sandbox. You can clone, get repository status, and list branches using the following operations:\n\n- **Clone a Git repository**: set the repository URL, destination, branch, commit ID, and credentials\n- **Get repository status**: retrieve the repository status\n- **List branches**: retrieve the list of branches in the repository\n\nFor more information, see [Git operations](/docs/en/git-operations).\n\n### Process and code execution\n\nThe process and code execution section provides operations to run code snippets and shell commands directly in the sandbox. Shell commands are fixed, while code snippets change automatically based on the selected [sandbox language](/docs/en/sandboxes#multiple-runtime-support) parameter.\n\nFor more information, see [process and code execution](/docs/en/process-code-execution).\n\n## Terminal\n\nThe terminal tab provides a web-based terminal connected to the sandbox. This gives you direct command-line access to the sandbox environment for running commands, viewing files, and debugging.\n\nThe terminal runs on port `22222` and remains active as long as the sandbox is running. If the sandbox stops due to inactivity, start it again to restore terminal access.\n\n:::note\nTerminal access is restricted to authenticated members of your [organization](/docs/en/organizations).\n:::\n\nFor more information, see [web terminal](/docs/en/web-terminal).\n\n## VNC\n\nThe VNC tab provides graphical desktop access to the sandbox, enabling you to interact with GUI applications and test [Computer Use](/docs/en/computer-use) features. The left panel contains interaction controls organized into sections. The right panel displays the desktop view.\n\nFor more information, see [VNC access](/docs/en/vnc-access).\n\n### Display\n\nThe display section provides options to inspect the sandbox desktop environment.\n\n- **Get display information**: retrieve information about the available displays\n- **List open windows**: retrieve a list of currently open windows\n\nFor more information, see [display operations](/docs/en/computer-use#display-operations).\n\n### Keyboard\n\nThe keyboard section provides options to send keyboard input to the sandbox.\n\n- **Press a hotkey combination**: send a hotkey combination to the sandbox\n- **Press a key**: press a key with optional modifiers\n- **Type text**: type text into the active window\n\nFor more information, see [keyboard operations](/docs/en/computer-use#keyboard-operations).\n\n### Mouse\n\nThe mouse section provides options to control mouse input in the sandbox.\n\n- **Click**: click at a specified position\n- **Drag**: drag from one position to another\n- **Move**: move the cursor to a specified position\n- **Get cursor position**: retrieve the current cursor position\n\nFor more information, see [mouse operations](/docs/en/computer-use#mouse-operations).\n\n### Screenshot\n\nThe screenshot section provides options to capture screenshots of the sandbox desktop.\n\n- **Take a screenshot**: select format, scale, and quality, show cursor, and capture the entire screen or specific regions\n\nFor more information, see [screenshot operations](/docs/en/computer-use#screenshot-operations).\n\n## Related\n\n- [Web Terminal](/docs/en/web-terminal): browser-based terminal access for sandboxes\n- [VNC Access](/docs/en/vnc-access): graphical desktop access for sandboxes\n- [Computer Use](/docs/en/computer-use): programmatic desktop automation\n- [File System Operations](/docs/en/file-system-operations): manage files and directories in sandboxes\n- [Git Operations](/docs/en/git-operations): manage Git repositories in sandboxes\n- [Process & Code Execution](/docs/en/process-code-execution): execute commands and run code in sandboxes\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/preview.mdx",
    "content": "---\ntitle: Preview\n---\n\nimport { Tabs, TabItem } from '@astrojs/starlight/components'\n\nDaytona provides preview URLs for accessing services running in your sandboxes. Any process listening for HTTP traffic on ports `3000` - `9999` can be previewed through a generated URL.\n\nDaytona supports two types of preview URLs, each with a different authentication mechanism:\n\n- [Standard preview URL](#standard-preview-url) uses the sandbox ID in the URL and requires a token sent via header\n- [Signed preview URL](#signed-preview-url) embeds the authentication token directly in the URL, requiring no headers\n\n## Authentication\n\nIf a sandbox has its `public` property set to `true`, preview links are publicly accessible without authentication. Otherwise, authentication is required. The authentication mechanism depends on the preview URL type.\n\n:::note\nStandard and signed preview tokens are not interchangeable. The token from `get_preview_link()` must be sent via the `x-daytona-preview-token` header. The token from `create_signed_preview_url()` is embedded in the URL itself: it cannot be used as a header value, and vice versa.\n:::\n\n## Standard preview URL\n\nThe standard preview URL includes your sandbox ID in the URL and provides a separate token for authentication via the `x-daytona-preview-token` request header.\n\nURL structure: `https://{port}-{sandboxId}.{daytonaProxyDomain}`\n\nThe token resets automatically when the sandbox restarts. Any previously issued standard preview tokens become invalid. Call the `get_preview_link()` method again after starting the sandbox to obtain a fresh token. Use standard preview URLs for programmatic access and API integrations where you control the HTTP headers.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\npreview_info = sandbox.get_preview_link(3000)\n\nprint(f\"URL: {preview_info.url}\")\nprint(f\"Token: {preview_info.token}\")\n\n# Use with requests\nimport requests\nresponse = requests.get(\n    preview_info.url,\n    headers={\"x-daytona-preview-token\": preview_info.token}\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nconst previewInfo = await sandbox.getPreviewLink(3000);\n\nconsole.log(`URL: ${previewInfo.url}`);\nconsole.log(`Token: ${previewInfo.token}`);\n\n// Use with fetch\nconst response = await fetch(previewInfo.url, {\n  headers: { 'x-daytona-preview-token': previewInfo.token }\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\npreview_info = sandbox.preview_url(3000)\n\nputs \"Preview link url: #{preview_info.url}\"\nputs \"Preview link token: #{preview_info.token}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n```go\npreview, err := sandbox.GetPreviewLink(ctx, 3000)\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Printf(\"URL: %s\\n\", preview.URL)\nfmt.Printf(\"Token: %s\\n\", preview.Token)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxId}/ports/3000/preview-url' \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), [Go SDK](/docs/en/go-sdk/daytona), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**get_preview_link (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxget_preview_link)\n>\n> [**getPreviewLink (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#getpreviewlink)\n>\n> [**preview_url (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#preview_url)\n>\n> [**GetPreviewLink (Go SDK)**](/docs/en/go-sdk/daytona#Sandbox.GetPreviewLink)\n>\n> [**Get Port Preview URL (API)**](/docs/en/tools/api/#daytona/tag/sandbox/GET/sandbox/{sandboxIdOrName}/ports/{port}/preview-url)\n\n### Authentication\n\nAuthenticate by sending the token in the `x-daytona-preview-token` header:\n\n```bash\ncurl -H \"x-daytona-preview-token: vg5c0ylmcimr8b_v1ne0u6mdnvit6gc0\" \\\n  https://3000-sandbox-123456.proxy.daytona.work\n```\n\n## Signed preview URL\n\nThe signed preview URL embeds the authentication token directly in the URL, eliminating the need for separate headers. You can set a custom expiry time for the token (defaults to 60 seconds). The token persists across sandbox restarts until it expires. Tokens can be revoked manually before expiry if needed.\n\n:::tip\nAlways set the `expires_in_seconds` parameter explicitly. The default of 60 seconds is short due to security considerations. Most use cases should use at least 3600 (1 hour).\n:::\n\nURL structure: `https://{port}-{token}.{daytonaProxyDomain}`\n\nUse signed preview URLs when sharing links with users who cannot set custom headers, embedding previews in iframes or emails, or creating time-limited shareable links.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Create a signed preview URL that expires in 3600 seconds (1 hour)\nsigned_url = sandbox.create_signed_preview_url(3000, expires_in_seconds=3600)\n\nprint(f\"URL: {signed_url.url}\")  # Token is embedded in the URL\nprint(f\"Token: {signed_url.token}\")  # Can be used to revoke access\n\n# Use directly - no headers needed\nimport requests\nresponse = requests.get(signed_url.url)\n\n# Revoke the token before expiry if needed\nsandbox.expire_signed_preview_url(3000, signed_url.token)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Create a signed preview URL that expires in 3600 seconds (1 hour)\nconst signedUrl = await sandbox.getSignedPreviewUrl(3000, 3600);\n\nconsole.log(`URL: ${signedUrl.url}`);  // Token is embedded in the URL\nconsole.log(`Token: ${signedUrl.token}`);  // Can be used to revoke access\n\n// Use directly - no headers needed\nconst response = await fetch(signedUrl.url);\n\n// Revoke the token before expiry if needed\nawait sandbox.expireSignedPreviewUrl(3000, signedUrl.token);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\n# Create a signed preview URL that expires in 3600 seconds (1 hour)\nsigned_url = sandbox.create_signed_preview_url(3000, 3600)\n\nputs \"URL: #{signed_url.url}\"\nputs \"Token: #{signed_url.token}\"\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n```bash\ndaytona preview-url <sandbox-name> --port 3000 --expires 3600\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxId}/ports/3000/signed-preview-url?expiresInSeconds=3600' \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**create_signed_preview_url (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxcreate_signed_preview_url)\n>\n> [**getSignedPreviewUrl (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#getsignedpreviewurl)\n>\n> [**create_signed_preview_url (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#create_signed_preview_url)\n>\n> [**Get Signed Preview URL (API)**](/docs/en/tools/api/#daytona/tag/sandbox/GET/sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url)\n\n### Authentication\n\nThe token is embedded in the URL itself, so no additional headers are required:\n\n```bash\ncurl https://3000-<value>.proxy.daytona.work\n```\n\n:::tip\nPort `22222` is used by the [web terminal](/docs/en/web-terminal) to access the terminal using preview URLs.\n:::\n\n## Warning page\n\nWhen opening a preview link in a browser for the first time, Daytona displays a warning page. This warning informs users about potential risks of visiting the preview URL and only appears when loading the link in a browser.\n\nTo skip the warning page:\n\n- Send the `X-Daytona-Skip-Preview-Warning: true` header\n- Upgrade to [Tier 3](/docs/en/limits)\n- Deploy a [custom preview proxy](/docs/en/custom-domain-authentication)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/process-code-execution.mdx",
    "content": "---\ntitle: Process and Code Execution\n---\n\nimport { Tabs, TabItem } from '@astrojs/starlight/components';\n\nDaytona provides process and code execution capabilities through the `process` module in sandboxes.\n\n## Code execution\n\nDaytona provides methods to execute code in sandboxes. You can run code snippets in multiple languages with support for both stateless execution and stateful interpretation with persistent contexts.\n\n:::note\n\nStateless execution inherits the sandbox language that you choose at [sandbox creation](/docs/en/sandboxes#create-sandboxes) time. The stateful interpreter supports only Python.\n  :::\n\n### Run code (stateless)\n\nDaytona provides methods to run code snippets in sandboxes using stateless execution. Each invocation starts from a clean interpreter, making it ideal for independent code snippets.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Run Python code\nresponse = sandbox.process.code_run('''\ndef greet(name):\n    return f\"Hello, {name}!\"\n\nprint(greet(\"Daytona\"))\n''')\n\nprint(response.result)\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Run TypeScript code\nlet response = await sandbox.process.codeRun(`\nfunction greet(name: string): string {\n    return \\`Hello, \\${name}!\\`;\n}\n\nconsole.log(greet(\"Daytona\"));\n`);\nconsole.log(response.result);\n\n// Run code with argv and environment variables\nresponse = await sandbox.process.codeRun(\n    `\n    console.log(\\`Hello, \\${process.argv[2]}!\\`);\n    console.log(\\`FOO: \\${process.env.FOO}\\`);\n    `,\n    { \n      argv: [\"Daytona\"],\n      env: { FOO: \"BAR\" }\n    }\n);\nconsole.log(response.result);\n\n// Run code with timeout (5 seconds)\nresponse = await sandbox.process.codeRun(\n    'setTimeout(() => console.log(\"Done\"), 2000);',\n    undefined,\n    5\n);\nconsole.log(response.result);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Run Python code\nresponse = sandbox.process.code_run(code: <<~PYTHON)\n  def greet(name):\n      return f\"Hello, {name}!\"\n\n  print(greet(\"Daytona\"))\nPYTHON\n\nputs response.result\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Run code using shell command execution\n// Note: For stateless code execution in Go, use ExecuteCommand with the appropriate interpreter\nresult, err := sandbox.Process.ExecuteCommand(ctx, `python3 -c '\ndef greet(name):\n    return f\"Hello, {name}!\"\n\nprint(greet(\"Daytona\"))\n'`)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Println(result.Result)\n\n// Run code with environment variables\nresult, err = sandbox.Process.ExecuteCommand(ctx, `python3 -c 'import os; print(f\"FOO: {os.environ.get(\\\"FOO\\\")}\")'`,\n\toptions.WithCommandEnv(map[string]string{\"FOO\": \"BAR\"}),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Println(result.Result)\n\n// Run code with timeout\nresult, err = sandbox.Process.ExecuteCommand(ctx, `python3 -c 'import time; time.sleep(2); print(\"Done\")'`,\n\toptions.WithExecuteTimeout(5*time.Second),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Println(result.Result)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/code-run' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"code\": \"def greet(name):\\n    return f\\\"Hello, {name}!\\\"\\n\\nprint(greet(\\\"Daytona\\\"))\",\n  \"env\": {\n    \"FOO\": \"BAR\"\n  },\n  \"timeout\": 5000\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**code_run (Python SDK)**](/docs/en/python-sdk/sync/process/#processcode_run)\n>\n> [**codeRun (TypeScript SDK)**](/docs/en/typescript-sdk/process/#coderun)\n>\n> [**code_run (Ruby SDK)**](/docs/en/ruby-sdk/process/#code_run)\n>\n> [**ExecuteCommand (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.ExecuteCommand)\n>\n> [**execute command (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/POST/process/execute)\n\n### Run code (stateful)\n\nDaytona provides methods to run code with persistent state using the code interpreter. You can maintain variables and imports between calls, create isolated contexts, and control environment variables.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, OutputMessage\n\ndef handle_stdout(message: OutputMessage):\n    print(f\"[STDOUT] {message.output}\")\n\ndaytona = Daytona()\nsandbox = daytona.create()\n\n# Shared default context\nresult = sandbox.code_interpreter.run_code(\n    \"counter = 1\\nprint(f'Counter initialized at {counter}')\",\n    on_stdout=handle_stdout,\n)\n\n# Isolated context\nctx = sandbox.code_interpreter.create_context()\ntry:\n    sandbox.code_interpreter.run_code(\n        \"value = 'stored in ctx'\",\n        context=ctx,\n    )\n    sandbox.code_interpreter.run_code(\n        \"print(value)\",\n        context=ctx,\n        on_stdout=handle_stdout,\n    )\nfinally:\n    sandbox.code_interpreter.delete_context(ctx)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\n\nconst daytona = new Daytona()\n\nasync function main() {\n    const sandbox = await daytona.create()\n\n    // Shared default context\n    await sandbox.codeInterpreter.runCode(\n`\ncounter = 1\nprint(f'Counter initialized at {counter}')\n`,\n        { onStdout: (msg) => process.stdout.write(`[STDOUT] ${msg.output}`)},\n    )\n\n    // Isolated context\n    const ctx = await sandbox.codeInterpreter.createContext()\n    try {\n    await sandbox.codeInterpreter.runCode(\n        `value = 'stored in ctx'`,\n        { context: ctx },\n    )\n    await sandbox.codeInterpreter.runCode(\n        `print(value)`,\n        { context: ctx, onStdout: (msg) => process.stdout.write(`[STDOUT] ${msg.output}`) },\n    )\n    } finally {\n    await sandbox.codeInterpreter.deleteContext(ctx)\n    }\n}\n\nmain()\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Ruby SDK uses process.code_run for code execution\n# Stateful contexts are managed through the code interpreter API\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\n\n# Run code (stateless in Ruby SDK)\nresponse = sandbox.process.code_run(code: <<~PYTHON)\n  counter = 1\n  print(f'Counter initialized at {counter}')\nPYTHON\n\nputs response.result\n```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n```go\n// Create a code interpreter context\nctxInfo, err := sandbox.CodeInterpreter.CreateContext(ctx, nil)\nif err != nil {\n\tlog.Fatal(err)\n}\ncontextID := ctxInfo[\"id\"].(string)\n\n// Run code in the context\nchannels, err := sandbox.CodeInterpreter.RunCode(ctx,\n\t\"counter = 1\\nprint(f'Counter initialized at {counter}')\",\n\toptions.WithCustomContext(contextID),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Read output\nfor msg := range channels.Stdout {\n\tfmt.Printf(\"[STDOUT] %s\\n\", msg.Text)\n}\n\n// Clean up context\nerr = sandbox.CodeInterpreter.DeleteContext(ctx, contextID)\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\n# Create context\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/interpreter/context' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{}'\n\n# Run code in context (WebSocket endpoint)\n# Connect via WebSocket to:\n# wss://proxy.app.daytona.io/toolbox/{sandboxId}/process/interpreter/execute\n# Send JSON message:\n# {\n#   \"code\": \"counter = 1\\nprint(f\\\"Counter initialized at {counter}\\\")\",\n#   \"contextId\": \"your-context-id\"\n# }\n\n# Delete context\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/interpreter/context/{contextId}' \\\n  --request DELETE\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**run_code (Python SDK)**](/docs/en/python-sdk/sync/code-interpreter/#codeinterpreterrun_code)\n>\n> [**create_context (Python SDK)**](/docs/en/python-sdk/sync/code-interpreter/#codeinterpretercreate_context)\n>\n> [**delete_context (Python SDK)**](/docs/en/python-sdk/sync/code-interpreter/#codeinterpreterdelete_context)\n>\n> [**runCode (TypeScript SDK)**](/docs/en/typescript-sdk/code-interpreter/#runcode)\n>\n> [**createContext (TypeScript SDK)**](/docs/en/typescript-sdk/code-interpreter/#createcontext)\n>\n> [**deleteContext (TypeScript SDK)**](/docs/en/typescript-sdk/code-interpreter/#deletecontext)\n>\n> [**code_run (Ruby SDK)**](/docs/en/ruby-sdk/process/#code_run)\n>\n> [**RunCode (Go SDK)**](/docs/en/go-sdk/daytona/#CodeInterpreterService.RunCode)\n>\n> [**CreateContext (Go SDK)**](/docs/en/go-sdk/daytona/#CodeInterpreterService.CreateContext)\n>\n> [**DeleteContext (Go SDK)**](/docs/en/go-sdk/daytona/#CodeInterpreterService.DeleteContext)\n>\n> [**code interpreter (API)**](/docs/en/tools/api/#daytona-toolbox/tag/interpreter)\n\n## Command execution\n\nDaytona provides methods to execute shell commands in sandboxes. You can run commands with working directory, timeout, and environment variable options.\n\nThe working directory defaults to the sandbox working directory. It uses the WORKDIR specified in the Dockerfile if present, or falls back to the user's home directory if not (e.g., `workspace/repo` implies `/home/daytona/workspace/repo`). You can override it with an absolute path by starting the path with `/`.\n\n### Execute commands\n\nDaytona provides methods to execute shell commands in sandboxes by providing the command string and optional parameters for working directory, timeout, and environment variables. You can also use the `daytona exec` CLI command for quick command execution.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Execute any shell command\nresponse = sandbox.process.exec(\"ls -la\")\nprint(response.result)\n\n# Setting a working directory and a timeout\n\nresponse = sandbox.process.exec(\"sleep 3\", cwd=\"workspace/src\", timeout=5)\nprint(response.result)\n\n# Passing environment variables\n\nresponse = sandbox.process.exec(\"echo $CUSTOM_SECRET\", env={\n        \"CUSTOM_SECRET\": \"DAYTONA\"\n    }\n)\nprint(response.result)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n\n// Execute any shell command\nconst response = await sandbox.process.executeCommand(\"ls -la\");\nconsole.log(response.result);\n\n// Setting a working directory and a timeout\nconst response2 = await sandbox.process.executeCommand(\"sleep 3\", \"workspace/src\", undefined, 5);\nconsole.log(response2.result);\n\n// Passing environment variables\nconst response3 = await sandbox.process.executeCommand(\"echo $CUSTOM_SECRET\", \".\", {\n        \"CUSTOM_SECRET\": \"DAYTONA\"\n    }\n);\nconsole.log(response3.result);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Execute any shell command\nresponse = sandbox.process.exec(command: 'ls -la')\nputs response.result\n\n# Setting a working directory and a timeout\nresponse = sandbox.process.exec(command: 'sleep 3', cwd: 'workspace/src', timeout: 5)\nputs response.result\n\n# Passing environment variables\nresponse = sandbox.process.exec(\n  command: 'echo $CUSTOM_SECRET',\n  env: { 'CUSTOM_SECRET' => 'DAYTONA' }\n)\nputs response.result\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Execute any shell command\nresponse, err := sandbox.Process.ExecuteCommand(ctx, \"ls -la\")\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Println(response.Result)\n\n// Setting a working directory and a timeout\nresponse, err = sandbox.Process.ExecuteCommand(ctx, \"sleep 3\",\n\toptions.WithCwd(\"workspace/src\"),\n\toptions.WithExecuteTimeout(5*time.Second),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Println(response.Result)\n\n// Passing environment variables\nresponse, err = sandbox.Process.ExecuteCommand(ctx, \"echo $CUSTOM_SECRET\",\n\toptions.WithCommandEnv(map[string]string{\"CUSTOM_SECRET\": \"DAYTONA\"}),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Println(response.Result)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\n# Execute any shell command\ndaytona exec my-sandbox -- ls -la\n\n# Setting a working directory and a timeout\ndaytona exec my-sandbox --cwd workspace/src --timeout 5 -- sleep 3\n\n# Passing environment variables (use shell syntax)\ndaytona exec my-sandbox -- sh -c 'CUSTOM_SECRET=DAYTONA echo $CUSTOM_SECRET'\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/execute' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"command\": \"ls -la\",\n  \"cwd\": \"workspace\",\n  \"timeout\": 5\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/) references:\n\n> [**exec (Python SDK)**](/docs/en/python-sdk/sync/process/#processexec)\n>\n> [**executeCommand (TypeScript SDK)**](/docs/en/typescript-sdk/process/#executecommand)\n>\n> [**exec (Ruby SDK)**](/docs/en/ruby-sdk/process/#exec)\n>\n> [**ExecuteCommand (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.ExecuteCommand)\n>\n> [**daytona exec (CLI)**](/docs/en/tools/cli/#daytona-exec)\n>\n> [**execute command (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/POST/process/execute)\n\n## Session operations\n\nDaytona provides methods to manage background process sessions in sandboxes. You can create sessions, execute commands, monitor status, and manage long-running processes.\n\n### Get session status\n\nDaytona provides methods to get session status and list all sessions in a sandbox by providing the session ID.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Check session's executed commands\nsession = sandbox.process.get_session(session_id)\nprint(f\"Session {session_id}:\")\nfor command in session.commands:\n    print(f\"Command: {command.command}, Exit Code: {command.exit_code}\")\n\n# List all running sessions\n\nsessions = sandbox.process.list_sessions()\nfor session in sessions:\n    print(f\"Session: {session.session_id}, Commands: {session.commands}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Check session's executed commands\nconst session = await sandbox.process.getSession(sessionId);\nconsole.log(`Session ${sessionId}:`);\nfor (const command of session.commands) {\n    console.log(`Command: ${command.command}, Exit Code: ${command.exitCode}`);\n}\n\n// List all running sessions\nconst sessions = await sandbox.process.listSessions();\nfor (const session of sessions) {\n    console.log(`Session: ${session.sessionId}, Commands: ${session.commands}`);\n}\n```\n\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Check session's executed commands\nsession = sandbox.process.get_session(session_id)\nputs \"Session #{session_id}:\"\nsession.commands.each do |command|\n  puts \"Command: #{command.command}, Exit Code: #{command.exit_code}\"\nend\n\n# List all running sessions\nsessions = sandbox.process.list_sessions\nsessions.each do |session|\n  puts \"Session: #{session.session_id}, Commands: #{session.commands}\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Check session's executed commands\nsession, err := sandbox.Process.GetSession(ctx, sessionID)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Session %s:\\n\", sessionID)\ncommands := session[\"commands\"].([]any)\nfor _, cmd := range commands {\n\tcmdMap := cmd.(map[string]any)\n\tfmt.Printf(\"Command: %s, Exit Code: %v\\n\", cmdMap[\"command\"], cmdMap[\"exitCode\"])\n}\n\n// List all running sessions\nsessions, err := sandbox.Process.ListSessions(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfor _, sess := range sessions {\n\tfmt.Printf(\"Session: %s, Commands: %v\\n\", sess[\"sessionId\"], sess[\"commands\"])\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\n# Get session info\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}'\n\n# List all sessions\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**get_session (Python SDK)**](/docs/en/python-sdk/sync/process/#processget_session)\n>\n> [**list_sessions (Python SDK)**](/docs/en/python-sdk/sync/process/#processlist_sessions)\n>\n> [**getSession (TypeScript SDK)**](/docs/en/typescript-sdk/process/#getsession)\n>\n> [**listSessions (TypeScript SDK)**](/docs/en/typescript-sdk/process/#listsessions)\n>\n> [**get_session (Ruby SDK)**](/docs/en/ruby-sdk/process/#get_session)\n>\n> [**list_sessions (Ruby SDK)**](/docs/en/ruby-sdk/process/#list_sessions)\n>\n> [**GetSession (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.GetSession)\n>\n> [**ListSessions (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.ListSessions)\n>\n> [**get session (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/GET/process/session/{sessionId})\n>\n> [**list sessions (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/GET/process/session)\n\n### Execute interactive commands\n\nDaytona provides methods to execute interactive commands in sessions. You can send input to running commands that expect user interaction, such as confirmations or interactive tools like database CLIs and package managers.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsession_id = \"interactive-session\"\nsandbox.process.create_session(session_id)\n\n# Execute command that requires confirmation\ncommand = sandbox.process.execute_session_command(\n    session_id,\n    SessionExecuteRequest(\n        command='pip uninstall requests',\n        run_async=True,\n    ),\n)\n\n# Stream logs asynchronously\nlogs_task = asyncio.create_task(\n    sandbox.process.get_session_command_logs_async(\n        session_id,\n        command.cmd_id,\n        lambda log: print(f\"[STDOUT]: {log}\"),\n        lambda log: print(f\"[STDERR]: {log}\"),\n    )\n)\n\nawait asyncio.sleep(1)\n# Send input to the command\nsandbox.process.send_session_command_input(session_id, command.cmd_id, \"y\")\n\n# Wait for logs to complete\nawait logs_task\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst sessionId = 'interactive-session'\nawait sandbox.process.createSession(sessionId)\n\n// Execute command that requires confirmation\nconst command = await sandbox.process.executeSessionCommand(sessionId, {\n    command: 'pip uninstall requests',\n    runAsync: true,\n})\n\n// Stream logs asynchronously\nconst logPromise = sandbox.process.getSessionCommandLogs(\n    sessionId,\n    command.cmdId!,\n    (stdout) => console.log('[STDOUT]:', stdout),\n    (stderr) => console.log('[STDERR]:', stderr),\n)\n\nawait new Promise((resolve) => setTimeout(resolve, 1000))\n// Send input to the command\nawait sandbox.process.sendSessionCommandInput(sessionId, command.cmdId!, 'y')\n\n// Wait for logs to complete\nawait logPromise\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsession_id = \"interactive-session\"\nsandbox.process.create_session(session_id)\n\n# Execute command that requires confirmation\ninteractive_command = sandbox.process.execute_session_command(\n  session_id: session_id,\n  req: Daytona::SessionExecuteRequest.new(\n    command: 'pip uninstall requests',\n    run_async: true\n  )\n)\n\n# Wait a moment for the command to start\nsleep 1\n\n# Send input to the command\nsandbox.process.send_session_command_input(\n  session_id: session_id,\n  command_id: interactive_command.cmd_id,\n  data: \"y\"\n)\n\n# Get logs for the interactive command asynchronously\nsandbox.process.get_session_command_logs_async(\n  session_id: session_id,\n  command_id: interactive_command.cmd_id,\n  on_stdout: ->(log) { puts \"[STDOUT]: #{log}\" },\n  on_stderr: ->(log) { puts \"[STDERR]: #{log}\" }\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nsessionID := \"interactive-session\"\nerr := sandbox.Process.CreateSession(ctx, sessionID)\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Execute command that requires confirmation\nresult, err := sandbox.Process.ExecuteSessionCommand(ctx, sessionID, \"pip uninstall requests\", true)\nif err != nil {\n\tlog.Fatal(err)\n}\ncmdID := result[\"cmdId\"].(string)\n\n// Stream logs asynchronously\nstdout := make(chan string)\nstderr := make(chan string)\n\ngo func() {\n\terr := sandbox.Process.GetSessionCommandLogsStream(ctx, sessionID, cmdID, stdout, stderr)\n\tif err != nil {\n\t\tlog.Println(\"Log stream error:\", err)\n\t}\n}()\n\ntime.Sleep(1 * time.Second)\n\n// Note: SendSessionCommandInput is not available in Go SDK\n// Use the API endpoint directly for sending input\n\n// Read logs\nfor msg := range stdout {\n\tfmt.Printf(\"[STDOUT]: %s\\n\", msg)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\n# Create session\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\"sessionId\": \"interactive-session\"}'\n\n# Execute session command\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}/exec' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"command\": \"pip uninstall requests\",\n  \"runAsync\": true\n}'\n\n# Send input to command\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}/command/{commandId}/input' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"data\": \"y\"\n}'\n\n# Get command logs\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}/command/{commandId}/logs'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**create_session (Python SDK)**](/docs/en/python-sdk/sync/process/#processcreate_session)\n>\n> [**execute_session_command (Python SDK)**](/docs/en/python-sdk/sync/process/#processexecute_session_command)\n>\n> [**send_session_command_input (Python SDK)**](/docs/en/python-sdk/sync/process/#processsend_session_command_input)\n>\n> [**get_session_command_logs_async (Python SDK)**](/docs/en/python-sdk/sync/process/#processget_session_command_logs_async)\n>\n> [**createSession (TypeScript SDK)**](/docs/en/typescript-sdk/process/#createsession)\n>\n> [**executeSessionCommand (TypeScript SDK)**](/docs/en/typescript-sdk/process/#executesessioncommand)\n>\n> [**sendSessionCommandInput (TypeScript SDK)**](/docs/en/typescript-sdk/process/#sendsessioncommandinput)\n>\n> [**getSessionCommandLogs (TypeScript SDK)**](/docs/en/typescript-sdk/process/#getsessioncommandlogs)\n>\n> [**create_session (Ruby SDK)**](/docs/en/ruby-sdk/process/#create_session)\n>\n> [**execute_session_command (Ruby SDK)**](/docs/en/ruby-sdk/process/#execute_session_command)\n>\n> [**send_session_command_input (Ruby SDK)**](/docs/en/ruby-sdk/process/#send_session_command_input)\n>\n> [**CreateSession (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.CreateSession)\n>\n> [**ExecuteSessionCommand (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.ExecuteSessionCommand)\n>\n> [**GetSessionCommandLogsStream (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.GetSessionCommandLogsStream)\n>\n> [**create session (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/POST/process/session)\n>\n> [**execute session command (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/POST/process/session/{sessionId}/exec)\n\n## Resource management\n\nDaytona provides methods to manage session resources. You should use sessions for long-running operations, clean up sessions after execution, and handle exceptions properly.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n   ```python\n   # Python - Clean up session\n   session_id = \"long-running-cmd\"\n   try:\n       sandbox.process.create_session(session_id)\n       session = sandbox.process.get_session(session_id)\n       # Do work...\n   finally:\n       sandbox.process.delete_session(session.session_id)\n   ```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n   ```typescript\n   // TypeScript - Clean up session\n   const sessionId = \"long-running-cmd\";\n   try {\n       await sandbox.process.createSession(sessionId);\n       const session = await sandbox.process.getSession(sessionId);\n       // Do work...\n   } finally {\n       await sandbox.process.deleteSession(session.sessionId);\n   }\n   ```\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n   ```ruby\n   # Ruby - Clean up session\n   session_id = 'long-running-cmd'\n   begin\n     sandbox.process.create_session(session_id)\n     session = sandbox.process.get_session(session_id)\n     # Do work...\n   ensure\n     sandbox.process.delete_session(session.session_id)\n   end\n   ```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n   ```go\n   // Go - Clean up session\n   sessionID := \"long-running-cmd\"\n   err := sandbox.Process.CreateSession(ctx, sessionID)\n   if err != nil {\n   \tlog.Fatal(err)\n   }\n   defer sandbox.Process.DeleteSession(ctx, sessionID)\n\n   session, err := sandbox.Process.GetSession(ctx, sessionID)\n   if err != nil {\n   \tlog.Fatal(err)\n   }\n   // Do work...\n   ```\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n   ```bash\n   # Create session\n   curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session' \\\n     --request POST \\\n     --header 'Content-Type: application/json' \\\n     --data '{\"sessionId\": \"long-running-cmd\"}'\n\n   # Delete session when done\n   curl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}' \\\n     --request DELETE\n   ```\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/) references:\n\n> [**create_session (Python SDK)**](/docs/en/python-sdk/sync/process/#processcreate_session)\n>\n> [**delete_session (Python SDK)**](/docs/en/python-sdk/sync/process/#processdelete_session)\n>\n> [**createSession (TypeScript SDK)**](/docs/en/typescript-sdk/process/#createsession)\n>\n> [**deleteSession (TypeScript SDK)**](/docs/en/typescript-sdk/process/#deletesession)\n>\n> [**create_session (Ruby SDK)**](/docs/en/ruby-sdk/process/#create_session)\n>\n> [**delete_session (Ruby SDK)**](/docs/en/ruby-sdk/process/#delete_session)\n>\n> [**CreateSession (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.CreateSession)\n>\n> [**DeleteSession (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.DeleteSession)\n>\n> [**create session (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/POST/process/session)\n>\n> [**delete session (API)**](/docs/en/tools/api/#daytona-toolbox/tag/process/DELETE/process/session/{sessionId})\n\n## Error handling\n\nDaytona provides methods to handle errors when executing processes. You should handle process exceptions properly, log error details for debugging, and use try-catch blocks for error handling.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\nfrom daytona import DaytonaError\n\ntry:\n    response = sandbox.process.code_run(\"invalid python code\")\n    if response.exit_code != 0:\n        print(f\"Exit code: {response.exit_code}\")\n        print(f\"Error output: {response.result}\")\nexcept DaytonaError as e:\n    print(f\"Execution failed: {e}\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { DaytonaError } from '@daytonaio/sdk'\n\ntry {\n    const response = await sandbox.process.codeRun(\"invalid typescript code\");\n    if (response.exitCode !== 0) {\n        console.error(\"Exit code:\", response.exitCode);\n        console.error(\"Error output:\", response.result);\n    }\n} catch (e) {\n    if (e instanceof DaytonaError) {\n        console.error(\"Execution failed:\", e);\n    }\n}\n```\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\nbegin\n  response = sandbox.process.code_run(code: 'invalid python code')\n  if response.exit_code != 0\n    puts \"Exit code: #{response.exit_code}\"\n    puts \"Error output: #{response.result}\"\n  end\nrescue StandardError => e\n  puts \"Execution failed: #{e}\"\nend\n```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n```go\nresult, err := sandbox.Process.ExecuteCommand(ctx, \"python3 -c 'invalid python code'\")\nif err != nil {\n\tfmt.Println(\"Execution failed:\", err)\n}\nif result != nil && result.ExitCode != 0 {\n\tfmt.Println(\"Exit code:\", result.ExitCode)\n\tfmt.Println(\"Error output:\", result.Result)\n}\n```\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n```bash\n# API responses include exitCode field for error handling\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/execute' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"command\": \"python3 -c \\\"invalid python code\\\"\"\n}'\n\n# Response includes:\n# {\n#   \"result\": \"\",\n#   \"exitCode\": 1\n# }\n```\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references.\n\n## Common issues\n\nDaytona provides solutions for troubleshooting common issues related to process and code execution.\n\n| **Issue**                | **Solutions**                                                                                                   |\n| ------------------------ | --------------------------------------------------------------------------------------------------------------- |\n| Process execution failed | • Check command syntax<br/>• Verify required dependencies<br/>• Ensure sufficient permissions                   |\n| Process timeout          | • Adjust timeout settings<br/>• Optimize long-running operations<br/>• Consider using background processes      |\n| Resource limits          | • Monitor process memory usage<br/>• Handle process cleanup properly<br/>• Use appropriate resource constraints |\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/pty.mdx",
    "content": "---\ntitle: Pseudo Terminal (PTY)\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona provides powerful pseudo terminal (PTY) capabilities through the `process` module in sandboxes. PTY sessions allow you to create interactive terminal sessions that can execute commands, handle user input, and manage terminal operations.\n\nA PTY (Pseudo Terminal) is a virtual terminal interface that allows programs to interact with a shell as if they were connected to a real terminal. PTY sessions in Daytona enable:\n\n- **Interactive Development**: REPLs, debuggers, and development tools\n- **Build Processes**: Running and monitoring compilation, testing, or deployment\n- **System Administration**: Remote server management and configuration\n- **User Interfaces**: Terminal-based applications requiring user interaction\n\n## Create PTY session\n\nDaytona provides methods to create an interactive terminal session that can execute commands and handle user input.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona.common.pty import PtySize\n\npty_handle = sandbox.process.create_pty_session(\n    id=\"my-session\",\n    cwd=\"/workspace\",\n    envs={\"TERM\": \"xterm-256color\"},\n    pty_size=PtySize(cols=120, rows=30)\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Create a PTY session with custom configuration\nconst ptyHandle = await sandbox.process.createPty({\n  id: 'my-interactive-session',\n  cwd: '/workspace',\n  envs: { TERM: 'xterm-256color', LANG: 'en_US.UTF-8' },\n  cols: 120,\n  rows: 30,\n  onData: (data) => {\n    // Handle terminal output\n    const text = new TextDecoder().decode(data)\n    process.stdout.write(text)\n  },\n})\n\n// Wait for connection to be established\nawait ptyHandle.waitForConnection()\n\n// Send commands to the terminal\nawait ptyHandle.sendInput('ls -la\\n')\nawait ptyHandle.sendInput('echo \"Hello, PTY!\"\\n')\nawait ptyHandle.sendInput('exit\\n')\n\n// Wait for completion and get result\nconst result = await ptyHandle.wait()\nconsole.log(`PTY session completed with exit code: ${result.exitCode}`)\n\n// Clean up\nawait ptyHandle.disconnect()\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\npty_size = Daytona::PtySize.new(rows: 30, cols: 120)\npty_handle = sandbox.process.create_pty_session(\n  id: 'my-interactive-session',\n  cwd: '/workspace',\n  envs: { 'TERM' => 'xterm-256color' },\n  pty_size: pty_size\n)\n\n# Use the PTY session\npty_handle.send_input(\"ls -la\\n\")\npty_handle.send_input(\"echo 'Hello, PTY!'\\n\")\npty_handle.send_input(\"exit\\n\")\n\n# Handle output\npty_handle.each { |data| print data }\n\nputs \"PTY session completed with exit code: #{pty_handle.exit_code}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a PTY session with custom configuration\nhandle, err := sandbox.Process.CreatePty(ctx, \"my-interactive-session\",\n\toptions.WithCreatePtySize(types.PtySize{Cols: 120, Rows: 30}),\n\toptions.WithCreatePtyEnv(map[string]string{\"TERM\": \"xterm-256color\"}),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer handle.Disconnect()\n\n// Wait for connection to be established\nif err := handle.WaitForConnection(ctx); err != nil {\n\tlog.Fatal(err)\n}\n\n// Send commands to the terminal\nhandle.SendInput([]byte(\"ls -la\\n\"))\nhandle.SendInput([]byte(\"echo 'Hello, PTY!'\\n\"))\nhandle.SendInput([]byte(\"exit\\n\"))\n\n// Read output from channel\nfor data := range handle.DataChan() {\n\tfmt.Print(string(data))\n}\n\n// Wait for completion and get result\nresult, err := handle.Wait(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"PTY session completed with exit code: %d\\n\", *result.ExitCode)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/pty' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"cols\": 1,\n  \"cwd\": \"\",\n  \"envs\": {\n    \"additionalProperty\": \"\"\n  },\n  \"id\": \"\",\n  \"lazyStart\": true,\n  \"rows\": 1\n}'\n```\n\n</TabItem>\n\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/process/), [TypeScript SDK](/docs/en/typescript-sdk/process/#createpty), [Ruby SDK](/docs/en/ruby-sdk/process/), [Go SDK](/docs/en/go-sdk/daytona/#type-processservice), and [API](/docs/en/tools/api#daytona-toolbox/tag/process) references:\n\n> [**create_pty_session (Python SDK)**](/docs/en/python-sdk/sync/process/#processcreate_pty_session)\n>\n> [**createPty (TypeScript SDK)**](/docs/en/typescript-sdk/process/#createpty)\n>\n> [**create_pty_session (Ruby SDK)**](/docs/en/ruby-sdk/process/#create_pty_session)\n>\n> [**CreatePty (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.CreatePty)\n>\n> [**Create PTY session (API)**](/docs/en/tools/api#daytona-toolbox/tag/process/POST/process/pty)\n\n## Connect to PTY session\n\nDaytona provides methods to establish a connection to an existing PTY session, enabling interaction with a previously created terminal.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\npty_handle = sandbox.process.connect_pty_session(\"my-session\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Connect to an existing PTY session\nconst handle = await sandbox.process.connectPty('my-session', {\n  onData: (data) => {\n    // Handle terminal output\n    const text = new TextDecoder().decode(data)\n    process.stdout.write(text)\n  },\n})\n\n// Wait for connection to be established\nawait handle.waitForConnection()\n\n// Send commands to the existing session\nawait handle.sendInput('pwd\\n')\nawait handle.sendInput('ls -la\\n')\nawait handle.sendInput('exit\\n')\n\n// Wait for completion\nconst result = await handle.wait()\nconsole.log(`Session exited with code: ${result.exitCode}`)\n\n// Clean up\nawait handle.disconnect()\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Connect to an existing PTY session\npty_handle = sandbox.process.connect_pty_session('my-session')\npty_handle.send_input(\"echo 'Hello World'\\n\")\npty_handle.send_input(\"exit\\n\")\n\n# Handle output\npty_handle.each { |data| print data }\n\nputs \"Session exited with code: #{pty_handle.exit_code}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Connect to an existing PTY session\nhandle, err := sandbox.Process.ConnectPty(ctx, \"my-session\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer handle.Disconnect()\n\n// Wait for connection to be established\nif err := handle.WaitForConnection(ctx); err != nil {\n\tlog.Fatal(err)\n}\n\n// Send commands to the existing session\nhandle.SendInput([]byte(\"pwd\\n\"))\nhandle.SendInput([]byte(\"ls -la\\n\"))\nhandle.SendInput([]byte(\"exit\\n\"))\n\n// Read output\nfor data := range handle.DataChan() {\n\tfmt.Print(string(data))\n}\n\n// Wait for completion\nresult, err := handle.Wait(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Session exited with code: %d\\n\", *result.ExitCode)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/pty/{sessionId}/connect'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/process/), [TypeScript SDK](/docs/en/typescript-sdk/process/), [Ruby SDK](/docs/en/ruby-sdk/process/), [Go SDK](/docs/en/go-sdk/daytona/#type-processservice), and [API](/docs/en/tools/api#daytona-toolbox/tag/process) references:\n\n> [**connect_pty_session (Python SDK)**](/docs/en/python-sdk/sync/process/#processconnect_pty_session)\n>\n> [**connectPty (TypeScript SDK)**](/docs/en/typescript-sdk/process/#connectpty)\n>\n> [**connect_pty_session (Ruby SDK)**](/docs/en/ruby-sdk/process/#connect_pty_session)\n>\n> [**ConnectPty (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.ConnectPty)\n>\n> [**Connect to PTY session (API)**](/docs/en/tools/api#daytona-toolbox/tag/process/GET/process/pty/{sessionId}/connect)\n\n## List PTY sessions\n\nDaytona provides methods to list PTY sessions, allowing you to retrieve information about all PTY sessions, both active and inactive, that have been created in the sandbox.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# List all PTY sessions\nsessions = sandbox.process.list_pty_sessions()\n\nfor session in sessions:\n    print(f\"Session ID: {session.id}\")\n    print(f\"Active: {session.active}\")\n    print(f\"Created: {session.created_at}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// List all PTY sessions\nconst sessions = await sandbox.process.listPtySessions()\n\nfor (const session of sessions) {\n  console.log(`Session ID: ${session.id}`)\n  console.log(`Active: ${session.active}`)\n  console.log(`Created: ${session.createdAt}`)\n  console.log('---')\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# List all PTY sessions\nsessions = sandbox.process.list_pty_sessions\n\nsessions.each do |session|\n  puts \"Session ID: #{session.id}\"\n  puts \"Active: #{session.active}\"\n  puts \"Terminal Size: #{session.cols}x#{session.rows}\"\n  puts '---'\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// List all PTY sessions\nsessions, err := sandbox.Process.ListPtySessions(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfor _, session := range sessions {\n\tfmt.Printf(\"Session ID: %s\\n\", session.Id)\n\tfmt.Printf(\"Active: %t\\n\", session.Active)\n\tfmt.Printf(\"Terminal Size: %dx%d\\n\", session.Cols, session.Rows)\n\tfmt.Println(\"---\")\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/pty'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/process/), [TypeScript SDK](/docs/en/typescript-sdk/process/), [Ruby SDK](/docs/en/ruby-sdk/process/), [Go SDK](/docs/en/go-sdk/daytona/#type-processservice), and [API](/docs/en/tools/api#daytona-toolbox/tag/process) references:\n\n> [**list_pty_sessions (Python SDK)**](/docs/en/python-sdk/sync/process/#processlist_pty_sessions)\n>\n> [**listPtySessions (TypeScript SDK)**](/docs/en/typescript-sdk/process/#listptysessions)\n>\n> [**list_pty_sessions (Ruby SDK)**](/docs/en/ruby-sdk/process/#list_pty_sessions)\n>\n> [**ListPtySessions (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.ListPtySessions)\n>\n> [**List PTY sessions (API)**](/docs/en/tools/api#daytona-toolbox/tag/process/GET/process/pty)\n\n## Get PTY session info\n\nDaytona provides methods to get information about a specific PTY session, allowing you to retrieve comprehensive information about a specific PTY session including its current state, configuration, and metadata.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Get details about a specific PTY session\nsession_info = sandbox.process.get_pty_session_info(\"my-session\")\n\nprint(f\"Session ID: {session_info.id}\")\nprint(f\"Active: {session_info.active}\")\nprint(f\"Working Directory: {session_info.cwd}\")\nprint(f\"Terminal Size: {session_info.cols}x{session_info.rows}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Get details about a specific PTY session\nconst session = await sandbox.process.getPtySessionInfo('my-session')\n\nconsole.log(`Session ID: ${session.id}`)\nconsole.log(`Active: ${session.active}`)\nconsole.log(`Working Directory: ${session.cwd}`)\nconsole.log(`Terminal Size: ${session.cols}x${session.rows}`)\n\nif (session.processId) {\n  console.log(`Process ID: ${session.processId}`)\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Get details about a specific PTY session\nsession_info = sandbox.process.get_pty_session_info('my-session')\n\nputs \"Session ID: #{session_info.id}\"\nputs \"Active: #{session_info.active}\"\nputs \"Working Directory: #{session_info.cwd}\"\nputs \"Terminal Size: #{session_info.cols}x#{session_info.rows}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Get details about a specific PTY session\nsession, err := sandbox.Process.GetPtySessionInfo(ctx, \"my-session\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Session ID: %s\\n\", session.Id)\nfmt.Printf(\"Active: %t\\n\", session.Active)\nfmt.Printf(\"Working Directory: %s\\n\", session.Cwd)\nfmt.Printf(\"Terminal Size: %dx%d\\n\", session.Cols, session.Rows)\n\nif session.ProcessId != nil {\n\tfmt.Printf(\"Process ID: %d\\n\", *session.ProcessId)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/process/), [TypeScript SDK](/docs/en/typescript-sdk/process/), [Ruby SDK](/docs/en/ruby-sdk/process/), [Go SDK](/docs/en/go-sdk/daytona/#type-processservice), and [API](/docs/en/tools/api#daytona-toolbox/tag/process) references:\n\n> [**get_pty_session_info (Python SDK)**](/docs/en/python-sdk/sync/process/#processget_pty_session_info)\n>\n> [**getPtySessionInfo (TypeScript SDK)**](/docs/en/typescript-sdk/process/#getptysessioninfo)\n>\n> [**get_pty_session_info (Ruby SDK)**](/docs/en/ruby-sdk/process/#get_pty_session_info)\n>\n> [**GetPtySessionInfo (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.GetPtySessionInfo)\n>\n> [**Get PTY session info (API)**](/docs/en/tools/api#daytona-toolbox/tag/process/GET/process/session/{sessionId})\n\n## Kill PTY session\n\nDaytona provides methods to kill a PTY session, allowing you to forcefully terminate a PTY session and cleans up all associated resources.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Kill a specific PTY session\nsandbox.process.kill_pty_session(\"my-session\")\n\n# Verify the session no longer exists\npty_sessions = sandbox.process.list_pty_sessions()\nfor pty_session in pty_sessions:\n    print(f\"PTY session: {pty_session.id}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Kill a specific PTY session\nawait sandbox.process.killPtySession('my-session')\n\n// Verify the session is no longer active\ntry {\n  const info = await sandbox.process.getPtySessionInfo('my-session')\n  console.log(`Session still exists but active: ${info.active}`)\n} catch (error) {\n  console.log('Session has been completely removed')\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Delete a specific PTY session\nsandbox.process.delete_pty_session('my-session')\n\n# Verify the session no longer exists\nsessions = sandbox.process.list_pty_sessions\nsessions.each do |session|\n  puts \"PTY session: #{session.id}\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Kill a specific PTY session\nerr := sandbox.Process.KillPtySession(ctx, \"my-session\")\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Verify the session is no longer active\nsessions, err := sandbox.Process.ListPtySessions(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfor _, session := range sessions {\n\tfmt.Printf(\"PTY session: %s\\n\", session.Id)\n}\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/session/{sessionId}' \\\n  --request DELETE\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/process/), [TypeScript SDK](/docs/en/typescript-sdk/process/), [Ruby SDK](/docs/en/ruby-sdk/process/#delete_pty_session), [Go SDK](/docs/en/go-sdk/daytona/#type-processservice), and [API](/docs/en/tools/api#daytona-toolbox/tag/process) references:\n\n> [**kill_pty_session (Python SDK)**](/docs/en/python-sdk/sync/process/#processkill_pty_session)\n>\n> [**killPtySession (TypeScript SDK)**](/docs/en/typescript-sdk/process/#killptysession)\n>\n> [**delete_pty_session (Ruby SDK)**](/docs/en/ruby-sdk/process/#delete_pty_session)\n>\n> [**KillPtySession (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.KillPtySession)\n>\n> [**Kill PTY session (API)**](/docs/en/tools/api#daytona-toolbox/tag/process/DELETE/process/session/{sessionId})\n\n## Resize PTY session\n\nDaytona provides methods to resize a PTY session, allowing you to change the terminal dimensions of an active PTY session. This sends a SIGWINCH signal to the shell process, allowing terminal applications to adapt to the new size.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona.common.pty import PtySize\n\n# Resize a PTY session to a larger terminal\nnew_size = PtySize(rows=40, cols=150)\nupdated_info = sandbox.process.resize_pty_session(\"my-session\", new_size)\n\nprint(f\"Terminal resized to {updated_info.cols}x{updated_info.rows}\")\n\n# You can also use the PtyHandle's resize method\npty_handle.resize(new_size)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Resize a PTY session to a larger terminal\nconst updatedInfo = await sandbox.process.resizePtySession('my-session', 150, 40)\nconsole.log(`Terminal resized to ${updatedInfo.cols}x${updatedInfo.rows}`)\n\n// You can also use the PtyHandle's resize method\nawait ptyHandle.resize(150, 40) // cols, rows\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Resize a PTY session to a larger terminal\npty_size = Daytona::PtySize.new(rows: 40, cols: 150)\nsession_info = sandbox.process.resize_pty_session('my-session', pty_size)\n\nputs \"Terminal resized to #{session_info.cols}x#{session_info.rows}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Resize a PTY session to a larger terminal\nupdatedInfo, err := sandbox.Process.ResizePtySession(ctx, \"my-session\", types.PtySize{\n\tCols: 150,\n\tRows: 40,\n})\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"Terminal resized to %dx%d\\n\", updatedInfo.Cols, updatedInfo.Rows)\n\n// You can also use the PtyHandle's Resize method\ninfo, err := handle.Resize(ctx, 150, 40)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Terminal resized to %dx%d\\n\", info.Cols, info.Rows)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/process/pty/{sessionId}/resize' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"cols\": 1,\n  \"rows\": 1\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/process/), [TypeScript SDK](/docs/en/typescript-sdk/process/#resizeptysession), [Ruby SDK](/docs/en/ruby-sdk/process/), [Go SDK](/docs/en/go-sdk/daytona/#type-processservice), and [API](/docs/en/tools/api#daytona-toolbox/tag/process) references:\n\n> [**resize_pty_session (Python SDK)**](/docs/en/python-sdk/sync/process/#processresize_pty_session)\n>\n> [**resizePtySession (TypeScript SDK)**](/docs/en/typescript-sdk/process/#resizeptysession)\n>\n> [**resize_pty_session (Ruby SDK)**](/docs/en/ruby-sdk/process/#resize_pty_session)\n>\n> [**ResizePtySession (Go SDK)**](/docs/en/go-sdk/daytona/#ProcessService.ResizePtySession)\n>\n> [**Resize PTY session (API)**](/docs/en/tools/api#daytona-toolbox/tag/process/POST/process/pty/{sessionId}/resize)\n\n## Interactive commands\n\nDaytona provides methods to handle interactive commands with PTY sessions, allowing you to handle interactive commands that require user input and can be resized during execution.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nimport time\nfrom daytona import Daytona, Sandbox\nfrom daytona.common.pty import PtySize\n\ndef handle_pty_data(data: bytes):\n    text = data.decode(\"utf-8\", errors=\"replace\")\n    print(text, end=\"\")\n\n# Create PTY session\npty_handle = sandbox.process.create_pty_session(\n    id=\"interactive-session\",\n    pty_size=PtySize(cols=300, rows=100)\n)\n\n# Send interactive command\npty_handle.send_input('printf \"Are you accepting the terms and conditions? (y/n): \" && read confirm && if [ \"$confirm\" = \"y\" ]; then echo \"You accepted\"; else echo \"You did not accept\"; fi\\n')\ntime.sleep(1)\npty_handle.send_input(\"y\\n\")\n\n# Resize terminal\npty_session_info = pty_handle.resize(PtySize(cols=210, rows=110))\nprint(f\"PTY session resized to {pty_session_info.cols}x{pty_session_info.rows}\")\n\n# Exit the session\npty_handle.send_input('exit\\n')\n\n# Handle output using iterator\nfor data in pty_handle:\n    handle_pty_data(data)\n\nprint(f\"Session completed with exit code: {pty_handle.exit_code}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, Sandbox } from '@daytonaio/sdk'\n\n// Create PTY session\nconst ptyHandle = await sandbox.process.createPty({\n  id: 'interactive-session',\n  cols: 300,\n  rows: 100,\n  onData: data => {\n    const text = new TextDecoder().decode(data)\n    process.stdout.write(text)\n  },\n})\n\nawait ptyHandle.waitForConnection()\n\n// Send interactive command\nawait ptyHandle.sendInput(\n  'printf \"Are you accepting the terms and conditions? (y/n): \" && read confirm && if [ \"$confirm\" = \"y\" ]; then echo \"You accepted\"; else echo \"You did not accept\"; fi\\n'\n)\nawait new Promise(resolve => setTimeout(resolve, 1000))\nawait ptyHandle.sendInput('y\\n')\n\n// Resize terminal\nconst ptySessionInfo = await sandbox.process.resizePtySession(\n  'interactive-session',\n  210,\n  110\n)\nconsole.log(\n  `\\nPTY session resized to ${ptySessionInfo.cols}x${ptySessionInfo.rows}`\n)\n\n// Exit the session\nawait ptyHandle.sendInput('exit\\n')\n\n// Wait for completion\nconst result = await ptyHandle.wait()\nconsole.log(`Session completed with exit code: ${result.exitCode}`)\n```\n\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\nrequire 'daytona'\n\n# Create PTY session\npty_handle = sandbox.process.create_pty_session(\n  id: 'interactive-session',\n  pty_size: Daytona::PtySize.new(cols: 300, rows: 100)\n)\n\n# Handle output in a separate thread\nthread = Thread.new do\n  pty_handle.each { |data| print data }\nend\n\n# Send interactive command\npty_handle.send_input('printf \"Are you accepting the terms and conditions? (y/n): \" && read confirm && if [ \"$confirm\" = \"y\" ]; then echo \"You accepted\"; else echo \"You did not accept\"; fi' + \"\\n\")\nsleep(1)\npty_handle.send_input(\"y\\n\")\n\n# Resize terminal\npty_handle.resize(Daytona::PtySize.new(cols: 210, rows: 110))\nputs \"\\nPTY session resized\"\n\n# Exit the session\npty_handle.send_input(\"exit\\n\")\n\n# Wait for the thread to finish\nthread.join\n\nputs \"Session completed with exit code: #{pty_handle.exit_code}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create PTY session\nhandle, err := sandbox.Process.CreatePty(ctx, \"interactive-session\",\n\toptions.WithCreatePtySize(types.PtySize{Cols: 300, Rows: 100}),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer handle.Disconnect()\n\nif err := handle.WaitForConnection(ctx); err != nil {\n\tlog.Fatal(err)\n}\n\n// Handle output in a goroutine\ngo func() {\n\tfor data := range handle.DataChan() {\n\t\tfmt.Print(string(data))\n\t}\n}()\n\n// Send interactive command\nhandle.SendInput([]byte(`printf \"Are you accepting the terms and conditions? (y/n): \" && read confirm && if [ \"$confirm\" = \"y\" ]; then echo \"You accepted\"; else echo \"You did not accept\"; fi` + \"\\n\"))\ntime.Sleep(1 * time.Second)\nhandle.SendInput([]byte(\"y\\n\"))\n\n// Resize terminal\ninfo, err := handle.Resize(ctx, 210, 110)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"\\nPTY session resized to %dx%d\\n\", info.Cols, info.Rows)\n\n// Exit the session\nhandle.SendInput([]byte(\"exit\\n\"))\n\n// Wait for completion\nresult, err := handle.Wait(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Session completed with exit code: %d\\n\", *result.ExitCode)\n```\n\n</TabItem>\n</Tabs>\n\n## Long-running processes\n\nDaytona provides methods to manage long-running processes with PTY sessions, allowing you to manage long-running processes that need to be monitored or terminated.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nimport time\nimport threading\nfrom daytona import Daytona, Sandbox\nfrom daytona.common.pty import PtySize\n\ndef handle_pty_data(data: bytes):\n    text = data.decode(\"utf-8\", errors=\"replace\")\n    print(text, end=\"\")\n\n# Create PTY session\npty_handle = sandbox.process.create_pty_session(\n    id=\"long-running-session\",\n    pty_size=PtySize(cols=120, rows=30)\n)\n\n# Start a long-running process\npty_handle.send_input('while true; do echo \"Running... $(date)\"; sleep 1; done\\n')\n\n# Using thread and wait() method to handle PTY output\nthread = threading.Thread(target=pty_handle.wait, args=(handle_pty_data, 10))\nthread.start()\n\ntime.sleep(3)  # Let it run for a bit\n\nprint(\"Killing long-running process...\")\npty_handle.kill()\n\nthread.join()\n\nprint(f\"\\nProcess terminated with exit code: {pty_handle.exit_code}\")\nif pty_handle.error:\n    print(f\"Termination reason: {pty_handle.error}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, Sandbox } from '@daytonaio/sdk'\n\n// Create PTY session\nconst ptyHandle = await sandbox.process.createPty({\n  id: 'long-running-session',\n  cols: 120,\n  rows: 30,\n  onData: (data) => {\n    const text = new TextDecoder().decode(data)\n    process.stdout.write(text)\n  },\n})\n\nawait ptyHandle.waitForConnection()\n\n// Start a long-running process\nawait ptyHandle.sendInput('while true; do echo \"Running... $(date)\"; sleep 1; done\\n')\nawait new Promise(resolve => setTimeout(resolve, 3000)) // Let it run for a bit\n\nconsole.log('Killing long-running process...')\nawait ptyHandle.kill()\n\n// Wait for termination\nconst result = await ptyHandle.wait()\nconsole.log(`\\nProcess terminated with exit code: ${result.exitCode}`)\nif (result.error) {\n    console.log(`Termination reason: ${result.error}`)\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\n# Create PTY session\npty_handle = sandbox.process.create_pty_session(\n  id: 'long-running-session',\n  pty_size: Daytona::PtySize.new(cols: 120, rows: 30)\n)\n\n# Handle output in a separate thread\nthread = Thread.new do\n  pty_handle.each { |data| print data }\nend\n\n# Start a long-running process\npty_handle.send_input(\"while true; do echo \\\"Running... $(date)\\\"; sleep 1; done\\n\")\nsleep(3) # Let it run for a bit\n\nputs \"Killing long-running process...\"\npty_handle.kill\n\nthread.join\n\nputs \"\\nProcess terminated with exit code: #{pty_handle.exit_code}\"\nputs \"Termination reason: #{pty_handle.error}\" if pty_handle.error\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create PTY session\nhandle, err := sandbox.Process.CreatePty(ctx, \"long-running-session\",\n\toptions.WithCreatePtySize(types.PtySize{Cols: 120, Rows: 30}),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer handle.Disconnect()\n\nif err := handle.WaitForConnection(ctx); err != nil {\n\tlog.Fatal(err)\n}\n\n// Handle output in a goroutine\ngo func() {\n\tfor data := range handle.DataChan() {\n\t\tfmt.Print(string(data))\n\t}\n}()\n\n// Start a long-running process\nhandle.SendInput([]byte(`while true; do echo \"Running... $(date)\"; sleep 1; done` + \"\\n\"))\ntime.Sleep(3 * time.Second) // Let it run for a bit\n\nfmt.Println(\"Killing long-running process...\")\nif err := handle.Kill(ctx); err != nil {\n\tlog.Fatal(err)\n}\n\n// Wait for termination\nresult, err := handle.Wait(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"\\nProcess terminated with exit code: %d\\n\", *result.ExitCode)\nif result.Error != nil {\n\tfmt.Printf(\"Termination reason: %s\\n\", *result.Error)\n}\n```\n\n</TabItem>\n</Tabs>\n\n## Resource management\n\nDaytona provides methods to manage resource leaks with PTY sessions, allowing you to always clean up PTY sessions to prevent resource leaks.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Python: Use try/finally\npty_handle = None\ntry:\n    pty_handle = sandbox.process.create_pty_session(id=\"session\", pty_size=PtySize(cols=120, rows=30))\n    # Do work...\nfinally:\n    if pty_handle:\n        pty_handle.kill()\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// TypeScript: Use try/finally\nlet ptyHandle\ntry {\n  ptyHandle = await sandbox.process.createPty({\n    id: 'session',\n    cols: 120,\n    rows: 30,\n  })\n  // Do work...\n} finally {\n  if (ptyHandle) await ptyHandle.kill()\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Ruby: Use begin/ensure\npty_handle = nil\nbegin\n  pty_handle = sandbox.process.create_pty_session(\n    id: 'session',\n    pty_size: Daytona::PtySize.new(cols: 120, rows: 30)\n  )\n  # Do work...\nensure\n  pty_handle&.kill\nend\n```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Go: Use defer for cleanup\nhandle, err := sandbox.Process.CreatePty(ctx, \"session\",\n\toptions.WithCreatePtySize(types.PtySize{Cols: 120, Rows: 30}),\n)\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer handle.Disconnect()\n\n// Do work...\n\n// Or use Kill to terminate the process\ndefer handle.Kill(ctx)\n```\n\n</TabItem>\n</Tabs>\n\n## PtyHandle methods\n\nDaytona provides methods to interact with PTY sessions, allowing you to send input, resize the terminal, wait for completion, and manage the WebSocket connection to a PTY session.\n\n### Send input\n\nDaytona provides methods to send input to a PTY session, allowing you to send input data (keystrokes or commands) to the PTY session.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Send a command\npty_handle.send_input(\"ls -la\\n\")\n\n# Send user input\npty_handle.send_input(\"y\\n\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Send a command\nawait ptyHandle.sendInput('ls -la\\n')\n\n// Send raw bytes\nawait ptyHandle.sendInput(new Uint8Array([3])) // Ctrl+C\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Send a command\npty_handle.send_input(\"ls -la\\n\")\n\n# Send user input\npty_handle.send_input(\"y\\n\")\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Send a command\nhandle.SendInput([]byte(\"ls -la\\n\"))\n\n// Send Ctrl+C\nhandle.SendInput([]byte{0x03})\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/daytona/#type-processservice) references:\n\n> [**sendInput (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#sendinput)\n>\n> [**SendInput (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.SendInput)\n\n### Wait for completion\n\nDaytona provides methods to wait for a PTY process to exit and return the result, allowing you to wait for a PTY process to exit and return the result.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Wait with a callback for output data\ndef handle_data(data: bytes):\n    print(data.decode(\"utf-8\", errors=\"replace\"), end=\"\")\n\nresult = pty_handle.wait(on_data=handle_data, timeout=30)\nprint(f\"Exit code: {result.exit_code}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Wait for process to complete\nconst result = await ptyHandle.wait()\n\nif (result.exitCode === 0) {\n  console.log('Process completed successfully')\n} else {\n  console.log(`Process failed with code: ${result.exitCode}`)\n  if (result.error) {\n    console.log(`Error: ${result.error}`)\n  }\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Wait by iterating over output (blocks until PTY session ends)\npty_handle.each { |data| print data }\n\nif pty_handle.exit_code == 0\n  puts 'Process completed successfully'\nelse\n  puts \"Process failed with code: #{pty_handle.exit_code}\"\n  puts \"Error: #{pty_handle.error}\" if pty_handle.error\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Wait for process to complete\nresult, err := handle.Wait(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nif result.ExitCode != nil && *result.ExitCode == 0 {\n\tfmt.Println(\"Process completed successfully\")\n} else {\n\tfmt.Printf(\"Process failed with code: %d\\n\", *result.ExitCode)\n\tif result.Error != nil {\n\t\tfmt.Printf(\"Error: %s\\n\", *result.Error)\n\t}\n}\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/daytona/#type-processservice) references:\n\n> [**wait (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#wait)\n>\n> [**Wait (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.Wait)\n\n### Wait for connection\n\nDaytona provides methods to wait for the WebSocket connection to be established before sending input, allowing you to wait for the WebSocket connection to be established before sending input.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Python handles connection internally during creation\n# No explicit wait needed\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Wait for connection to be established\nawait ptyHandle.waitForConnection()\n\n// Now safe to send input\nawait ptyHandle.sendInput('echo \"Connected!\"\\n')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Ruby handles connection internally during creation\n# No explicit wait needed - can send input immediately after creation\npty_handle.send_input(\"echo 'Connected!'\\n\")\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Wait for connection to be established\nif err := handle.WaitForConnection(ctx); err != nil {\n\tlog.Fatal(err)\n}\n\n// Now safe to send input\nhandle.SendInput([]byte(\"echo 'Connected!'\\n\"))\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/daytona/#type-processservice) references:\n\n> [**waitForConnection (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#waitforconnection)\n>\n> [**WaitForConnection (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.WaitForConnection)\n\n### Kill PTY process\n\nDaytona provides methods to kill a PTY process and terminate the session from the handle.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\npty_handle.kill()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Kill a long-running process\nawait ptyHandle.kill()\n\n// Wait to confirm termination\nconst result = await ptyHandle.wait()\nconsole.log(`Process terminated with exit code: ${result.exitCode}`)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Kill a long-running process\npty_handle.kill\n\nputs \"Process terminated with exit code: #{pty_handle.exit_code}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Kill a long-running process\nif err := handle.Kill(ctx); err != nil {\n\tlog.Fatal(err)\n}\n\n// Wait to confirm termination\nresult, err := handle.Wait(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Process terminated with exit code: %d\\n\", *result.ExitCode)\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/daytona/#type-processservice) references:\n\n> [**kill (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#kill)\n>\n> [**Kill (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.Kill)\n\n### Resize from handle\n\nDaytona provides methods to resize the PTY terminal dimensions directly from the handle.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona.common.pty import PtySize\n\npty_handle.resize(PtySize(cols=120, rows=30))\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Resize to 120x30\nawait ptyHandle.resize(120, 30)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Resize to 120x30\npty_handle.resize(Daytona::PtySize.new(cols: 120, rows: 30))\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Resize to 120x30\ninfo, err := handle.Resize(ctx, 120, 30)\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"Resized to %dx%d\\n\", info.Cols, info.Rows)\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/daytona/#type-processservice) references:\n\n> [**resize (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#resize)\n>\n> [**Resize (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.Resize)\n\n### Disconnect\n\nDaytona provides methods to disconnect from a PTY session and clean up resources without killing the process.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Python: Use kill() to terminate, or let the handle go out of scope\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Always clean up when done\ntry {\n  // ... use PTY session\n} finally {\n  await ptyHandle.disconnect()\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Ruby: Use begin/ensure or kill the session\nbegin\n  # ... use PTY session\nensure\n  pty_handle.kill\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Always clean up when done using defer\nhandle, err := sandbox.Process.CreatePty(ctx, \"session\")\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer handle.Disconnect()\n\n// ... use PTY session\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/daytona/#type-processservice) references:\n\n> [**disconnect (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#disconnect)\n>\n> [**Disconnect (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.Disconnect)\n\n### Check connection status\n\nDaytona provides methods to check if a PTY session is still connected.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Python: Check by attempting operations or using session info\nsession_info = sandbox.process.get_pty_session_info(\"my-session\")\nprint(f\"Session active: {session_info.active}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nif (ptyHandle.isConnected()) {\n  console.log('PTY session is active')\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Ruby: Check by using session info\nsession_info = sandbox.process.get_pty_session_info('my-session')\nputs 'PTY session is active' if session_info.active\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nif handle.IsConnected() {\n\tfmt.Println(\"PTY session is active\")\n}\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/daytona/#type-processservice) references:\n\n> [**isConnected (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#isconnected)\n>\n> [**IsConnected (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.IsConnected)\n\n### Exit code and error\n\nDaytona provides methods to access the exit code and error message after a PTY process terminates.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# After iteration or wait completes\nprint(f\"Exit code: {pty_handle.exit_code}\")\nif pty_handle.error:\n    print(f\"Error: {pty_handle.error}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Access via getters after process terminates\nconsole.log(`Exit code: ${ptyHandle.exitCode}`)\nif (ptyHandle.error) {\n  console.log(`Error: ${ptyHandle.error}`)\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Access after process terminates\nputs \"Exit code: #{pty_handle.exit_code}\"\nputs \"Error: #{pty_handle.error}\" if pty_handle.error\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Access via methods after process terminates\nif exitCode := handle.ExitCode(); exitCode != nil {\n\tfmt.Printf(\"Exit code: %d\\n\", *exitCode)\n}\nif errMsg := handle.Error(); errMsg != nil {\n\tfmt.Printf(\"Error: %s\\n\", *errMsg)\n}\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/daytona/#type-processservice) references:\n\n> [**exitCode (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#exitcode)\n>\n> [**error (TypeScript SDK)**](/docs/en/typescript-sdk/pty-handle/#error)\n>\n> [**ExitCode (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.ExitCode)\n>\n> [**Error (Go SDK)**](/docs/en/go-sdk/daytona/#PtyHandle.Error)\n\n### Iterate over output (Python)\n\nDaytona provides methods to iterate over a PTY handle to receive output data.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Iterate over PTY output\nfor data in pty_handle:\n    text = data.decode(\"utf-8\", errors=\"replace\")\n    print(text, end=\"\")\n\nprint(f\"Session ended with exit code: {pty_handle.exit_code}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// TypeScript uses the onData callback instead\nconst ptyHandle = await sandbox.process.createPty({\n  id: 'my-session',\n  onData: (data) => {\n    const text = new TextDecoder().decode(data)\n    process.stdout.write(text)\n  },\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Iterate over PTY output\npty_handle.each do |data|\n  print data\nend\n\nputs \"Session ended with exit code: #{pty_handle.exit_code}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Go uses a channel to receive output data\nfor data := range handle.DataChan() {\n\tfmt.Print(string(data))\n}\n\n// Or use as io.Reader\nio.Copy(os.Stdout, handle)\n\nfmt.Printf(\"Session ended with exit code: %d\\n\", *handle.ExitCode())\n```\n\n</TabItem>\n</Tabs>\n\n## Error handling\n\nDaytona provides methods to monitor exit codes and handle errors appropriately with PTY sessions.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Python: Check exit codes\nresult = pty_handle.wait()\nif result.exit_code != 0:\n    print(f\"Command failed: {result.exit_code}\")\n    print(f\"Error: {result.error}\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// TypeScript: Check exit codes\nconst result = await ptyHandle.wait()\nif (result.exitCode !== 0) {\n  console.log(`Command failed: ${result.exitCode}`)\n  console.log(`Error: ${result.error}`)\n}\n```\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\n# Ruby: Check exit codes\n# The handle blocks until the PTY session completes\npty_handle.each { |data| print data }\n\nif pty_handle.exit_code != 0\n  puts \"Command failed: #{pty_handle.exit_code}\"\n  puts \"Error: #{pty_handle.error}\"\nend\n```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Go: Check exit codes\nresult, err := handle.Wait(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nif result.ExitCode != nil && *result.ExitCode != 0 {\n\tfmt.Printf(\"Command failed: %d\\n\", *result.ExitCode)\n\tif result.Error != nil {\n\t\tfmt.Printf(\"Error: %s\\n\", *result.Error)\n\t}\n}\n```\n\n</TabItem>\n</Tabs>\n\n## Troubleshooting\n\n- **Connection issues**: verify sandbox status, network connectivity, and proper session IDs\n- **Performance issues**: use appropriate terminal dimensions and efficient data handlers\n- **Process management**: use explicit `kill()` calls and proper timeout handling for long-running processes\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-code-interpreter.mdx",
    "content": "---\ntitle: \"AsyncCodeInterpreter\"\nhideTitleOnPage: true\n---\n\n## AsyncCodeInterpreter\n\n```python\nclass AsyncCodeInterpreter()\n```\n\nHandles code interpretation and execution within a Sandbox. Currently supports only Python.\n\nThis class provides methods to execute code in isolated interpreter contexts,\nmanage contexts, and stream execution output via callbacks. If subsequent code executions\nare performed in the same context, the variables, imports, and functions defined in\nthe previous execution will be available.\n\nFor other languages, use the `code_run` method from the `AsyncProcess` interface,\nor execute the appropriate command directly in the sandbox terminal.\n\n#### AsyncCodeInterpreter.\\_\\_init\\_\\_\n\n```python\ndef __init__(api_client: InterpreterApi)\n```\n\nInitialize a new AsyncCodeInterpreter instance.\n\n**Arguments**:\n\n- `api_client` - API client for interpreter operations.\n\n#### AsyncCodeInterpreter.run\\_code\n\n```python\n@intercept_errors(message_prefix=\"Failed to run code: \")\nasync def run_code(code: str,\n                   *,\n                   context: InterpreterContext | None = None,\n                   on_stdout: OutputHandler[OutputMessage] | None = None,\n                   on_stderr: OutputHandler[OutputMessage] | None = None,\n                   on_error: OutputHandler[ExecutionError] | None = None,\n                   envs: dict[str, str] | None = None,\n                   timeout: int | None = None) -> ExecutionResult\n```\n\nExecute Python code in the sandbox.\n\nBy default, code runs in the default shared context which persists variables,\nimports, and functions across executions. To run in an isolated context,\ncreate a new context with `create_context()` and pass it as `context` argument.\n\n**Arguments**:\n\n- `code` _str_ - Code to execute.\n- `context` _InterpreterContext | None_ - Context to run code in. If not provided, uses default context.\n- `on_stdout` _OutputHandler[OutputMessage] | None_ - Callback for stdout messages.\n- `on_stderr` _OutputHandler[OutputMessage] | None_ - Callback for stderr messages.\n- `on_error` _OutputHandler[ExecutionError] | None_ - Callback for execution errors\n  (e.g., syntax errors, runtime errors).\n- `envs` _dict[str, str] | None_ - Environment variables for this execution.\n- `timeout` _int | None_ - Timeout in seconds. 0 means no timeout. Default is 10 minutes.\n  \n\n**Returns**:\n\n- `ExecutionResult` - Result object containing stdout, stderr and error if any.\n  \n\n**Raises**:\n\n- `DaytonaTimeoutError` - If execution times out.\n- `DaytonaError` - If execution fails due to communication or other SDK errors.\n  \n\n**Examples**:\n\n```python\ndef handle_stdout(msg: OutputMessage):\n    print(f\"STDOUT: {msg.output}\", end=\"\")\n\ndef handle_stderr(msg: OutputMessage):\n    print(f\"STDERR: {msg.output}\", end=\"\")\n\ndef handle_error(err: ExecutionError):\n    print(f\"ERROR: {err.name}: {err.value}\")\n\ncode = '''\nimport sys\nimport time\nfor i in range(5):\n    print(i)\n    time.sleep(1)\nsys.stderr.write(\"Counting done!\")\n'''\nresult = await sandbox.code_interpreter.run_code(\n    code=code,\n    on_stdout=handle_stdout,\n    on_stderr=handle_stderr,\n    on_error=handle_error,\n    timeout=10\n)\n```\n\n#### AsyncCodeInterpreter.create\\_context\n\n```python\n@intercept_errors(message_prefix=\"Failed to create interpreter context: \")\nasync def create_context(cwd: str | None = None) -> InterpreterContext\n```\n\nCreate a new isolated interpreter context.\n\nContexts provide isolated execution environments with their own global namespace.\nVariables, imports, and functions defined in one context don't affect others.\n\n**Arguments**:\n\n- `cwd` _str | None_ - Working directory for the context. If not specified, uses sandbox working directory.\n  \n\n**Returns**:\n\n- `InterpreterContext` - The created context with its ID and metadata.\n  \n\n**Raises**:\n\n- `DaytonaError` - If context creation fails.\n  \n\n**Examples**:\n\n```python\n# Create isolated context\nctx = await sandbox.code_interpreter.create_context()\n\n# Execute code in this context\nawait sandbox.code_interpreter.run_code(\"x = 100\", context=ctx)\n\n# Variable only exists in this context\nresult = await sandbox.code_interpreter.run_code(\"print(x)\", context=ctx)  # OK\n\n# Won't see the variable in default context\nresult = await sandbox.code_interpreter.run_code(\"print(x)\")  # NameError\n\n# Clean up\nawait sandbox.code_interpreter.delete_context(ctx)\n```\n\n#### AsyncCodeInterpreter.list\\_contexts\n\n```python\n@intercept_errors(message_prefix=\"Failed to list interpreter contexts: \")\nasync def list_contexts() -> list[InterpreterContext]\n```\n\nList all user-created interpreter contexts.\n\nThe default context is not included in this list. Only contexts created\nvia `create_context()` are returned.\n\n**Returns**:\n\n- `list[InterpreterContext]` - List of context objects.\n  \n\n**Raises**:\n\n- `DaytonaError` - If listing fails.\n  \n\n**Examples**:\n\n```python\ncontexts = await sandbox.code_interpreter.list_contexts()\nfor ctx in contexts:\n    print(f\"Context {ctx.id}: {ctx.language} at {ctx.cwd}\")\n```\n\n#### AsyncCodeInterpreter.delete\\_context\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete interpreter context: \")\nasync def delete_context(context: InterpreterContext) -> None\n```\n\nDelete an interpreter context and shut down all associated processes.\n\nThis permanently removes the context and all its state (variables, imports, etc.).\nThe default context cannot be deleted.\n\n**Arguments**:\n\n- `context` _InterpreterContext_ - Context to delete.\n  \n\n**Raises**:\n\n- `DaytonaError` - If deletion fails or context not found.\n  \n\n**Examples**:\n\n```python\nctx = await sandbox.code_interpreter.create_context()\n# ... use context ...\nawait sandbox.code_interpreter.delete_context(ctx)\n```\n\n\n## OutputMessage\n\n```python\nclass OutputMessage(BaseModel)\n```\n\nRepresents stdout or stderr output from code execution.\n\n**Attributes**:\n\n- `output` - The output content.\n\n## ExecutionError\n\n```python\nclass ExecutionError(BaseModel)\n```\n\nRepresents an error that occurred during code execution.\n\n**Attributes**:\n\n- `name` - The error type/class name (e.g., \"ValueError\", \"SyntaxError\").\n- `value` - The error value.\n- `traceback` - Full traceback of the error.\n\n## ExecutionResult\n\n```python\nclass ExecutionResult(BaseModel)\n```\n\nResult of code execution.\n\n**Attributes**:\n\n- `stdout` - Standard output from the code execution.\n- `stderr` - Standard error output from the code execution.\n- `error` - Error details if execution failed, None otherwise.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-computer-use.mdx",
    "content": "---\ntitle: \"AsyncComputerUse\"\nhideTitleOnPage: true\n---\n\n## AsyncComputerUse\n\n```python\nclass AsyncComputerUse()\n```\n\nComputer Use functionality for interacting with the desktop environment.\n\nProvides access to mouse, keyboard, screenshot, display, and recording operations\nfor automating desktop interactions within a sandbox.\n\n**Attributes**:\n\n- `mouse` _AsyncMouse_ - Mouse operations interface.\n- `keyboard` _AsyncKeyboard_ - Keyboard operations interface.\n- `screenshot` _AsyncScreenshot_ - Screenshot operations interface.\n- `display` _AsyncDisplay_ - Display operations interface.\n- `recording` _AsyncRecordingService_ - Screen recording operations interface.\n\n#### AsyncComputerUse.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start computer use: \")\n@with_instrumentation()\nasync def start() -> ComputerUseStartResponse\n```\n\nStarts all computer use processes (Xvfb, xfce4, x11vnc, novnc).\n\n**Returns**:\n\n- `ComputerUseStartResponse` - Computer use start response.\n  \n\n**Example**:\n\n```python\nresult = await sandbox.computer_use.start()\nprint(\"Computer use processes started:\", result.message)\n```\n\n#### AsyncComputerUse.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop computer use: \")\n@with_instrumentation()\nasync def stop() -> ComputerUseStopResponse\n```\n\nStops all computer use processes.\n\n**Returns**:\n\n- `ComputerUseStopResponse` - Computer use stop response.\n  \n\n**Example**:\n\n```python\nresult = await sandbox.computer_use.stop()\nprint(\"Computer use processes stopped:\", result.message)\n```\n\n#### AsyncComputerUse.get\\_status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get computer use status: \")\n@with_instrumentation()\nasync def get_status() -> ComputerUseStatusResponse\n```\n\nGets the status of all computer use processes.\n\n**Returns**:\n\n- `ComputerUseStatusResponse` - Status information about all VNC desktop processes.\n  \n\n**Example**:\n\n```python\nresponse = await sandbox.computer_use.get_status()\nprint(\"Computer use status:\", response.status)\n```\n\n#### AsyncComputerUse.get\\_process\\_status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process status: \")\n@with_instrumentation()\nasync def get_process_status(process_name: str) -> ProcessStatusResponse\n```\n\nGets the status of a specific VNC process.\n\n**Arguments**:\n\n- `process_name` _str_ - Name of the process to check.\n  \n\n**Returns**:\n\n- `ProcessStatusResponse` - Status information about the specific process.\n  \n\n**Example**:\n\n```python\nxvfb_status = await sandbox.computer_use.get_process_status(\"xvfb\")\nno_vnc_status = await sandbox.computer_use.get_process_status(\"novnc\")\n```\n\n#### AsyncComputerUse.restart\\_process\n\n```python\n@intercept_errors(message_prefix=\"Failed to restart process: \")\n@with_instrumentation()\nasync def restart_process(process_name: str) -> ProcessRestartResponse\n```\n\nRestarts a specific VNC process.\n\n**Arguments**:\n\n- `process_name` _str_ - Name of the process to restart.\n  \n\n**Returns**:\n\n- `ProcessRestartResponse` - Process restart response.\n  \n\n**Example**:\n\n```python\nresult = await sandbox.computer_use.restart_process(\"xfce4\")\nprint(\"XFCE4 process restarted:\", result.message)\n```\n\n#### AsyncComputerUse.get\\_process\\_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process logs: \")\n@with_instrumentation()\nasync def get_process_logs(process_name: str) -> ProcessLogsResponse\n```\n\nGets logs for a specific VNC process.\n\n**Arguments**:\n\n- `process_name` _str_ - Name of the process to get logs for.\n  \n\n**Returns**:\n\n- `ProcessLogsResponse` - Process logs.\n  \n\n**Example**:\n\n```python\nlogs = await sandbox.computer_use.get_process_logs(\"novnc\")\nprint(\"NoVNC logs:\", logs)\n```\n\n#### AsyncComputerUse.get\\_process\\_errors\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process errors: \")\n@with_instrumentation()\nasync def get_process_errors(process_name: str) -> ProcessErrorsResponse\n```\n\nGets error logs for a specific VNC process.\n\n**Arguments**:\n\n- `process_name` _str_ - Name of the process to get error logs for.\n  \n\n**Returns**:\n\n- `ProcessErrorsResponse` - Process error logs.\n  \n\n**Example**:\n\n```python\nerrors = await sandbox.computer_use.get_process_errors(\"x11vnc\")\nprint(\"X11VNC errors:\", errors)\n```\n\n\n## AsyncMouse\n\n```python\nclass AsyncMouse()\n```\n\nMouse operations for computer use functionality.\n\n#### AsyncMouse.get\\_position\n\n```python\n@intercept_errors(message_prefix=\"Failed to get mouse position: \")\n@with_instrumentation()\nasync def get_position() -> MousePositionResponse\n```\n\nGets the current mouse cursor position.\n\n**Returns**:\n\n- `MousePositionResponse` - Current mouse position with x and y coordinates.\n  \n\n**Example**:\n\n```python\nposition = await sandbox.computer_use.mouse.get_position()\nprint(f\"Mouse is at: {position.x}, {position.y}\")\n```\n\n#### AsyncMouse.move\n\n```python\n@intercept_errors(message_prefix=\"Failed to move mouse: \")\n@with_instrumentation()\nasync def move(x: int, y: int) -> MousePositionResponse\n```\n\nMoves the mouse cursor to the specified coordinates.\n\n**Arguments**:\n\n- `x` _int_ - The x coordinate to move to.\n- `y` _int_ - The y coordinate to move to.\n  \n\n**Returns**:\n\n- `MousePositionResponse` - Position after move.\n  \n\n**Example**:\n\n```python\nresult = await sandbox.computer_use.mouse.move(100, 200)\nprint(f\"Mouse moved to: {result.x}, {result.y}\")\n```\n\n#### AsyncMouse.click\n\n```python\n@intercept_errors(message_prefix=\"Failed to click mouse: \")\n@with_instrumentation()\nasync def click(x: int,\n                y: int,\n                button: str = \"left\",\n                double: bool = False) -> MouseClickResponse\n```\n\nClicks the mouse at the specified coordinates.\n\n**Arguments**:\n\n- `x` _int_ - The x coordinate to click at.\n- `y` _int_ - The y coordinate to click at.\n- `button` _str_ - The mouse button to click ('left', 'right', 'middle').\n- `double` _bool_ - Whether to perform a double-click.\n  \n\n**Returns**:\n\n- `MouseClickResponse` - Click operation result.\n  \n\n**Example**:\n\n```python\n# Single left click\nresult = await sandbox.computer_use.mouse.click(100, 200)\n\n# Double click\ndouble_click = await sandbox.computer_use.mouse.click(100, 200, \"left\", True)\n\n# Right click\nright_click = await sandbox.computer_use.mouse.click(100, 200, \"right\")\n```\n\n#### AsyncMouse.drag\n\n```python\n@intercept_errors(message_prefix=\"Failed to drag mouse: \")\n@with_instrumentation()\nasync def drag(start_x: int,\n               start_y: int,\n               end_x: int,\n               end_y: int,\n               button: str = \"left\") -> MouseDragResponse\n```\n\nDrags the mouse from start coordinates to end coordinates.\n\n**Arguments**:\n\n- `start_x` _int_ - The starting x coordinate.\n- `start_y` _int_ - The starting y coordinate.\n- `end_x` _int_ - The ending x coordinate.\n- `end_y` _int_ - The ending y coordinate.\n- `button` _str_ - The mouse button to use for dragging.\n  \n\n**Returns**:\n\n- `MouseDragResponse` - Drag operation result.\n  \n\n**Example**:\n\n```python\nresult = await sandbox.computer_use.mouse.drag(50, 50, 150, 150)\nprint(f\"Dragged from {result.from_x},{result.from_y} to {result.to_x},{result.to_y}\")\n```\n\n#### AsyncMouse.scroll\n\n```python\n@intercept_errors(message_prefix=\"Failed to scroll mouse: \")\n@with_instrumentation()\nasync def scroll(x: int, y: int, direction: str, amount: int = 1) -> bool\n```\n\nScrolls the mouse wheel at the specified coordinates.\n\n**Arguments**:\n\n- `x` _int_ - The x coordinate to scroll at.\n- `y` _int_ - The y coordinate to scroll at.\n- `direction` _str_ - The direction to scroll ('up' or 'down').\n- `amount` _int_ - The amount to scroll.\n  \n\n**Returns**:\n\n- `bool` - Whether the scroll operation was successful.\n  \n\n**Example**:\n\n```python\n# Scroll up\nscroll_up = await sandbox.computer_use.mouse.scroll(100, 200, \"up\", 3)\n\n# Scroll down\nscroll_down = await sandbox.computer_use.mouse.scroll(100, 200, \"down\", 5)\n```\n\n## AsyncKeyboard\n\n```python\nclass AsyncKeyboard()\n```\n\nKeyboard operations for computer use functionality.\n\n#### AsyncKeyboard.type\n\n```python\n@intercept_errors(message_prefix=\"Failed to type text: \")\n@with_instrumentation()\nasync def type(text: str, delay: int | None = None) -> None\n```\n\nTypes the specified text.\n\n**Arguments**:\n\n- `text` _str_ - The text to type.\n- `delay` _int_ - Delay between characters in milliseconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the type operation fails.\n  \n\n**Example**:\n\n```python\ntry:\n    await sandbox.computer_use.keyboard.type(\"Hello, World!\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# With delay between characters\ntry:\n    await sandbox.computer_use.keyboard.type(\"Slow typing\", 100)\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n#### AsyncKeyboard.press\n\n```python\n@intercept_errors(message_prefix=\"Failed to press key: \")\n@with_instrumentation()\nasync def press(key: str, modifiers: list[str] | None = None) -> None\n```\n\nPresses a key with optional modifiers.\n\n**Arguments**:\n\n- `key` _str_ - The key to press (e.g., 'Enter', 'Escape', 'Tab', 'a', 'A').\n- `modifiers` _list[str]_ - Modifier keys ('ctrl', 'alt', 'meta', 'shift').\n  \n\n**Raises**:\n\n- `DaytonaError` - If the press operation fails.\n  \n\n**Example**:\n\n```python\n# Press Enter\ntry:\n    await sandbox.computer_use.keyboard.press(\"Return\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Press Ctrl+C\ntry:\n    await sandbox.computer_use.keyboard.press(\"c\", [\"ctrl\"])\n    print(f\"Operation success\")\n\n# Press Ctrl+Shift+T\ntry:\n    await sandbox.computer_use.keyboard.press(\"t\", [\"ctrl\", \"shift\"])\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n#### AsyncKeyboard.hotkey\n\n```python\n@intercept_errors(message_prefix=\"Failed to press hotkey: \")\n@with_instrumentation()\nasync def hotkey(keys: str) -> None\n```\n\nPresses a hotkey combination.\n\n**Arguments**:\n\n- `keys` _str_ - The hotkey combination (e.g., 'ctrl+c', 'alt+tab', 'cmd+shift+t').\n  \n\n**Raises**:\n\n- `DaytonaError` - If the hotkey operation fails.\n  \n\n**Example**:\n\n```python\n# Copy\ntry:\n    await sandbox.computer_use.keyboard.hotkey(\"ctrl+c\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Paste\ntry:\n    await sandbox.computer_use.keyboard.hotkey(\"ctrl+v\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Alt+Tab\ntry:\n    await sandbox.computer_use.keyboard.hotkey(\"alt+tab\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n## AsyncScreenshot\n\n```python\nclass AsyncScreenshot()\n```\n\nScreenshot operations for computer use functionality.\n\n#### AsyncScreenshot.take\\_full\\_screen\n\n```python\n@intercept_errors(message_prefix=\"Failed to take screenshot: \")\n@with_instrumentation()\nasync def take_full_screen(show_cursor: bool = False) -> ScreenshotResponse\n```\n\nTakes a screenshot of the entire screen.\n\n**Arguments**:\n\n- `show_cursor` _bool_ - Whether to show the cursor in the screenshot.\n  \n\n**Returns**:\n\n- `ScreenshotResponse` - Screenshot data with base64 encoded image.\n  \n\n**Example**:\n\n```python\nscreenshot = await sandbox.computer_use.screenshot.take_full_screen()\nprint(f\"Screenshot size: {screenshot.width}x{screenshot.height}\")\n\n# With cursor visible\nwith_cursor = await sandbox.computer_use.screenshot.take_full_screen(True)\n```\n\n#### AsyncScreenshot.take\\_region\n\n```python\n@intercept_errors(message_prefix=\"Failed to take region screenshot: \")\n@with_instrumentation()\nasync def take_region(region: ScreenshotRegion,\n                      show_cursor: bool = False) -> ScreenshotResponse\n```\n\nTakes a screenshot of a specific region.\n\n**Arguments**:\n\n- `region` _ScreenshotRegion_ - The region to capture.\n- `show_cursor` _bool_ - Whether to show the cursor in the screenshot.\n  \n\n**Returns**:\n\n- `ScreenshotResponse` - Screenshot data with base64 encoded image.\n  \n\n**Example**:\n\n```python\nregion = ScreenshotRegion(x=100, y=100, width=300, height=200)\nscreenshot = await sandbox.computer_use.screenshot.take_region(region)\nprint(f\"Captured region: {screenshot.region.width}x{screenshot.region.height}\")\n```\n\n#### AsyncScreenshot.take\\_compressed\n\n```python\n@intercept_errors(message_prefix=\"Failed to take compressed screenshot: \")\n@with_instrumentation()\nasync def take_compressed(\n        options: ScreenshotOptions | None = None) -> ScreenshotResponse\n```\n\nTakes a compressed screenshot of the entire screen.\n\n**Arguments**:\n\n- `options` _ScreenshotOptions | None_ - Compression and display options.\n  \n\n**Returns**:\n\n- `ScreenshotResponse` - Compressed screenshot data.\n  \n\n**Example**:\n\n```python\n# Default compression\nscreenshot = await sandbox.computer_use.screenshot.take_compressed()\n\n# High quality JPEG\njpeg = await sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"jpeg\", quality=95, show_cursor=True)\n)\n\n# Scaled down PNG\nscaled = await sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"png\", scale=0.5)\n)\n```\n\n#### AsyncScreenshot.take\\_compressed\\_region\n\n```python\n@intercept_errors(\n    message_prefix=\"Failed to take compressed region screenshot: \")\n@with_instrumentation()\nasync def take_compressed_region(\n        region: ScreenshotRegion,\n        options: ScreenshotOptions | None = None) -> ScreenshotResponse\n```\n\nTakes a compressed screenshot of a specific region.\n\n**Arguments**:\n\n- `region` _ScreenshotRegion_ - The region to capture.\n- `options` _ScreenshotOptions | None_ - Compression and display options.\n  \n\n**Returns**:\n\n- `ScreenshotResponse` - Compressed screenshot data.\n  \n\n**Example**:\n\n```python\nregion = ScreenshotRegion(x=0, y=0, width=800, height=600)\nscreenshot = await sandbox.computer_use.screenshot.take_compressed_region(\n    region,\n    ScreenshotOptions(format=\"webp\", quality=80, show_cursor=True)\n)\nprint(f\"Compressed size: {screenshot.size_bytes} bytes\")\n```\n\n## AsyncDisplay\n\n```python\nclass AsyncDisplay()\n```\n\nDisplay operations for computer use functionality.\n\n#### AsyncDisplay.get\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get display info: \")\n@with_instrumentation()\nasync def get_info() -> DisplayInfoResponse\n```\n\nGets information about the displays.\n\n**Returns**:\n\n- `DisplayInfoResponse` - Display information including primary display and all available displays.\n  \n\n**Example**:\n\n```python\ninfo = await sandbox.computer_use.display.get_info()\nprint(f\"Primary display: {info.primary_display.width}x{info.primary_display.height}\")\nprint(f\"Total displays: {info.total_displays}\")\nfor i, display in enumerate(info.displays):\n    print(f\"Display {i}: {display.width}x{display.height} at {display.x},{display.y}\")\n```\n\n#### AsyncDisplay.get\\_windows\n\n```python\n@intercept_errors(message_prefix=\"Failed to get windows: \")\n@with_instrumentation()\nasync def get_windows() -> WindowsResponse\n```\n\nGets the list of open windows.\n\n**Returns**:\n\n- `WindowsResponse` - List of open windows with their IDs and titles.\n  \n\n**Example**:\n\n```python\nwindows = await sandbox.computer_use.display.get_windows()\nprint(f\"Found {windows.count} open windows:\")\nfor window in windows.windows:\n    print(f\"- {window.title} (ID: {window.id})\")\n```\n\n## AsyncRecordingService\n\n```python\nclass AsyncRecordingService()\n```\n\nRecording operations for computer use functionality.\n\n#### AsyncRecordingService.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start recording: \")\n@with_instrumentation()\nasync def start(label: str | None = None) -> Recording\n```\n\nStarts a new screen recording session.\n\n**Arguments**:\n\n- `label` _str | None_ - Optional custom label for the recording.\n  \n\n**Returns**:\n\n- `Recording` - Recording start response.\n  \n\n**Example**:\n\n```python\n# Start a recording with a label\nrecording = await sandbox.computer_use.recording.start(\"my-test-recording\")\nprint(f\"Recording started: {recording.id}\")\nprint(f\"File: {recording.file_path}\")\n```\n\n#### AsyncRecordingService.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop recording: \")\n@with_instrumentation()\nasync def stop(recording_id: str) -> Recording\n```\n\nStops an active screen recording session.\n\n**Arguments**:\n\n- `recording_id` _str_ - The ID of the recording to stop.\n  \n\n**Returns**:\n\n- `Recording` - Recording stop response.\n  \n\n**Example**:\n\n```python\nresult = await sandbox.computer_use.recording.stop(recording.id)\nprint(f\"Recording stopped: {result.duration_seconds} seconds\")\nprint(f\"Saved to: {result.file_path}\")\n```\n\n#### AsyncRecordingService.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list recordings: \")\n@with_instrumentation()\nasync def list() -> ListRecordingsResponse\n```\n\nLists all recordings (active and completed).\n\n**Returns**:\n\n- `ListRecordingsResponse` - List of all recordings.\n  \n\n**Example**:\n\n```python\nrecordings = await sandbox.computer_use.recording.list()\nprint(f\"Found {len(recordings.recordings)} recordings\")\nfor rec in recordings.recordings:\n    print(f\"- {rec.file_name}: {rec.status}\")\n```\n\n#### AsyncRecordingService.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get recording: \")\n@with_instrumentation()\nasync def get(recording_id: str) -> Recording\n```\n\nGets details of a specific recording by ID.\n\n**Arguments**:\n\n- `recording_id` _str_ - The ID of the recording to retrieve.\n  \n\n**Returns**:\n\n- `Recording` - Recording details.\n  \n\n**Example**:\n\n```python\nrecording = await sandbox.computer_use.recording.get(recording_id)\nprint(f\"Recording: {recording.file_name}\")\nprint(f\"Status: {recording.status}\")\nprint(f\"Duration: {recording.duration_seconds} seconds\")\n```\n\n#### AsyncRecordingService.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete recording: \")\n@with_instrumentation()\nasync def delete(recording_id: str) -> None\n```\n\nDeletes a recording by ID.\n\n**Arguments**:\n\n- `recording_id` _str_ - The ID of the recording to delete.\n  \n\n**Example**:\n\n```python\nawait sandbox.computer_use.recording.delete(recording_id)\nprint(\"Recording deleted\")\n```\n\n#### AsyncRecordingService.download\n\n```python\n@intercept_errors(message_prefix=\"Failed to download recording: \")\n@with_instrumentation()\nasync def download(recording_id: str, local_path: str) -> None\n```\n\nDownloads a recording file from the Sandbox and saves it to a local file.\n\nThe file is streamed directly to disk without loading the entire content into memory.\n\n**Arguments**:\n\n- `recording_id` _str_ - The ID of the recording to download.\n- `local_path` _str_ - Path to save the recording file locally.\n  \n\n**Example**:\n\n```python\n# Download recording to file\nawait sandbox.computer_use.recording.download(recording_id, \"local_recording.mp4\")\nprint(\"Recording downloaded\")\n```\n\n## ScreenshotRegion\n\n```python\nclass ScreenshotRegion(BaseModel)\n```\n\nRegion coordinates for screenshot operations.\n\n**Attributes**:\n\n- `x` _int_ - X coordinate of the region.\n- `y` _int_ - Y coordinate of the region.\n- `width` _int_ - Width of the region.\n- `height` _int_ - Height of the region.\n\n## ScreenshotOptions\n\n```python\nclass ScreenshotOptions(BaseModel)\n```\n\nOptions for screenshot compression and display.\n\n**Attributes**:\n\n- `show_cursor` _bool | None_ - Whether to show the cursor in the screenshot.\n- `fmt` _str | None_ - Image format (e.g., 'png', 'jpeg', 'webp').\n- `quality` _int | None_ - Compression quality (0-100).\n- `scale` _float | None_ - Scale factor for the screenshot.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-daytona.mdx",
    "content": "---\ntitle: \"AsyncDaytona\"\nhideTitleOnPage: true\n---\n\n## AsyncDaytona\n\n```python\nclass AsyncDaytona()\n```\n\nMain class for interacting with the Daytona API.\n\nThis class provides asynchronous methods to create, manage, and interact with Daytona Sandboxes.\nIt can be initialized either with explicit configuration or using environment variables.\n\n**Attributes**:\n\n- `volume` _AsyncVolumeService_ - Service for managing volumes.\n- `snapshot` _AsyncSnapshotService_ - Service for managing snapshots.\n  \n\n**Example**:\n\n  Using environment variables:\n```python\nasync with AsyncDaytona() as daytona:  # Uses DAYTONA_API_KEY, DAYTONA_API_URL\n    sandbox = await daytona.create()\n```\n  \n  Using explicit configuration:\n```python\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"https://your-api.com\",\n    target=\"us\"\n)\ntry:\n    daytona = AsyncDaytona(config)\n    sandbox = await daytona.create()\nfinally:\n    await daytona.close()\n```\n  \n  Using OpenTelemetry tracing:\n```python\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    experimental={\"otelEnabled\": True}\n)\nasync with AsyncDaytona(config) as daytona:\n    sandbox = await daytona.create()\n    # All SDK operations will be traced\n# OpenTelemetry traces are flushed on close\n```\n\n#### AsyncDaytona.\\_\\_init\\_\\_\n\n```python\ndef __init__(config: DaytonaConfig | None = None)\n```\n\nInitializes Daytona instance with optional configuration.\n\nIf no config is provided, reads from environment variables:\n- `DAYTONA_API_KEY`: Required API key for authentication\n- `DAYTONA_API_URL`: Required api URL\n- `DAYTONA_TARGET`: Optional target environment (if not provided, default region for the organization is used)\n\n**Arguments**:\n\n- `config` _DaytonaConfig | None_ - Object containing api_key, api_url, and target.\n  \n\n**Raises**:\n\n- `DaytonaError` - If API key is not provided either through config or environment variables\n  \n\n**Example**:\n\n```python\nfrom daytona import Daytona, DaytonaConfig\n# Using environment variables\ndaytona1 = AsyncDaytona()\nawait daytona1.close()\n# Using explicit configuration\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"https://your-api.com\",\n    target=\"us\"\n)\ndaytona2 = AsyncDaytona(config)\nawait daytona2.close()\n```\n\n#### AsyncDaytona.\\_\\_aenter\\_\\_\n\n```python\nasync def __aenter__()\n```\n\nAsync context manager entry.\n\n#### AsyncDaytona.\\_\\_aexit\\_\\_\n\n```python\nasync def __aexit__(exc_type: type[BaseException] | None = None,\n                    exc_value: BaseException | None = None,\n                    traceback: TracebackType | None = None)\n```\n\nAsync context manager exit - ensures proper cleanup.\n\n#### AsyncDaytona.close\n\n```python\nasync def close()\n```\n\nClose the HTTP session and clean up resources.\n\nThis method should be called when you're done using the AsyncDaytona instance\nto properly close the underlying HTTP sessions and avoid resource leaks.\n\n**Example**:\n\n```python\ndaytona = AsyncDaytona()\ntry:\n    sandbox = await daytona.create()\n    # ... use sandbox ...\nfinally:\n    await daytona.close()\n```\n  \n  Or better yet, use as async context manager:\n```python\nasync with AsyncDaytona() as daytona:\n    sandbox = await daytona.create()\n    # ... use sandbox ...\n# Automatically closed\n```\n\n#### AsyncDaytona.create\n\n```python\n@overload\nasync def create(params: CreateSandboxFromSnapshotParams | None = None,\n                 *,\n                 timeout: float = 60) -> AsyncSandbox\n```\n\nCreates Sandboxes from specified or default snapshot. You can specify various parameters,\nincluding language, image, environment variables, and volumes.\n\n**Arguments**:\n\n- `params` _CreateSandboxFromSnapshotParams | None_ - Parameters for Sandbox creation. If not provided,\n  defaults to default Daytona snapshot and Python language.\n- `timeout` _float_ - Timeout (in seconds) for sandbox creation. 0 means no timeout.\n  Default is 60 seconds.\n  \n\n**Returns**:\n\n- `Sandbox` - The created Sandbox instance.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout, auto_stop_interval or auto_archive_interval is negative;\n  If sandbox fails to start or times out\n  \n\n**Example**:\n\n  Create a default Python Sandbox:\n```python\nsandbox = await daytona.create()\n```\n  \n  Create a custom Sandbox:\n```python\nparams = CreateSandboxFromSnapshotParams(\n    language=\"python\",\n    snapshot=\"my-snapshot-id\",\n    env_vars={\"DEBUG\": \"true\"},\n    auto_stop_interval=0,\n    auto_archive_interval=60,\n    auto_delete_interval=120\n)\nsandbox = await daytona.create(params, timeout=40)\n```\n\n#### AsyncDaytona.create\n\n```python\n@overload\nasync def create(\n    params: CreateSandboxFromImageParams | None = None,\n    *,\n    timeout: float = 60,\n    on_snapshot_create_logs: Callable[[str], None] | None = None\n) -> AsyncSandbox\n```\n\nCreates Sandboxes from specified image available on some registry or declarative Daytona Image.\nYou can specify various parameters, including resources, language, image, environment variables,\nand volumes. Daytona creates snapshot from provided image and uses it to create Sandbox.\n\n**Arguments**:\n\n- `params` _CreateSandboxFromImageParams | None_ - Parameters for Sandbox creation from image.\n- `timeout` _float_ - Timeout (in seconds) for sandbox creation. 0 means no timeout.\n  Default is 60 seconds.\n- `on_snapshot_create_logs` _Callable[[str], None] | None_ - This callback function\n  handles snapshot creation logs.\n  \n\n**Returns**:\n\n- `Sandbox` - The created Sandbox instance.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout, auto_stop_interval or auto_archive_interval is negative;\n  If sandbox fails to start or times out\n  \n\n**Example**:\n\n  Create a default Python Sandbox from image:\n```python\nsandbox = await daytona.create(CreateSandboxFromImageParams(image=\"debian:12.9\"))\n```\n  \n  Create a custom Sandbox from declarative Image definition:\n```python\ndeclarative_image = (\n    Image.base(\"alpine:3.18\")\n    .pipInstall([\"numpy\", \"pandas\"])\n    .env({\"MY_ENV_VAR\": \"My Environment Variable\"})\n)\nparams = CreateSandboxFromImageParams(\n    language=\"python\",\n    image=declarative_image,\n    env_vars={\"DEBUG\": \"true\"},\n    resources=Resources(cpu=2, memory=4),\n    auto_stop_interval=0,\n    auto_archive_interval=60,\n    auto_delete_interval=120\n)\nsandbox = await daytona.create(\n    params,\n    timeout=40,\n    on_snapshot_create_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n#### AsyncDaytona.delete\n\n```python\n@with_instrumentation()\nasync def delete(sandbox: AsyncSandbox, timeout: float = 60) -> None\n```\n\nDeletes a Sandbox.\n\n**Arguments**:\n\n- `sandbox` _Sandbox_ - The Sandbox instance to delete.\n- `timeout` _float_ - Timeout (in seconds) for sandbox deletion. 0 means no timeout.\n  Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If sandbox fails to delete or times out\n  \n\n**Example**:\n\n```python\nsandbox = await daytona.create()\n# ... use sandbox ...\nawait daytona.delete(sandbox)  # Clean up when done\n```\n\n#### AsyncDaytona.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get sandbox: \")\n@with_instrumentation()\nasync def get(sandbox_id_or_name: str) -> AsyncSandbox\n```\n\nGets a Sandbox by its ID or name.\n\n**Arguments**:\n\n- `sandbox_id_or_name` _str_ - The ID or name of the Sandbox to retrieve.\n  \n\n**Returns**:\n\n- `Sandbox` - The Sandbox instance.\n  \n\n**Raises**:\n\n- `DaytonaError` - If sandbox_id_or_name is not provided.\n  \n\n**Example**:\n\n```python\nsandbox = await daytona.get(\"my-sandbox-id-or-name\")\nprint(sandbox.state)\n```\n\n#### AsyncDaytona.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list sandboxes: \")\n@with_instrumentation()\nasync def list(labels: dict[str, str] | None = None,\n               page: int | None = None,\n               limit: int | None = None) -> AsyncPaginatedSandboxes\n```\n\nReturns paginated list of Sandboxes filtered by labels.\n\n**Arguments**:\n\n- `labels` _dict[str, str] | None_ - Labels to filter Sandboxes.\n- `page` _int | None_ - Page number for pagination (starting from 1).\n- `limit` _int | None_ - Maximum number of items per page.\n  \n\n**Returns**:\n\n- `AsyncPaginatedSandboxes` - Paginated list of Sandbox instances that match the labels.\n  \n\n**Example**:\n\n```python\nresult = await daytona.list(labels={\"my-label\": \"my-value\"}, page=2, limit=10)\nfor sandbox in result.items:\n    print(f\"{sandbox.id}: {sandbox.state}\")\n```\n\n#### AsyncDaytona.start\n\n```python\n@with_instrumentation()\nasync def start(sandbox: AsyncSandbox, timeout: float = 60) -> None\n```\n\nStarts a Sandbox and waits for it to be ready.\n\n**Arguments**:\n\n- `sandbox` _Sandbox_ - The Sandbox to start.\n- `timeout` _float_ - Optional timeout in seconds to wait for the Sandbox to start.\n  0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative; If Sandbox fails to start or times out\n\n#### AsyncDaytona.stop\n\n```python\n@with_instrumentation()\nasync def stop(sandbox: AsyncSandbox, timeout: float = 60) -> None\n```\n\nStops a Sandbox and waits for it to be stopped.\n\n**Arguments**:\n\n- `sandbox` _Sandbox_ - The sandbox to stop\n- `timeout` _float_ - Optional timeout (in seconds) for sandbox stop.\n  0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative; If Sandbox fails to stop or times out\n\n\n## CodeLanguage\n\n```python\nclass CodeLanguage(str, Enum)\n```\n\nProgramming languages supported by Daytona\n\n**Enum Members**:\n    - `PYTHON` (\"python\")\n    - `TYPESCRIPT` (\"typescript\")\n    - `JAVASCRIPT` (\"javascript\")\n\n## DaytonaConfig\n\n```python\nclass DaytonaConfig(BaseModel)\n```\n\nConfiguration options for initializing the Daytona client.\n\n**Attributes**:\n\n- `api_key` _str | None_ - API key for authentication with the Daytona API. If not set, it must be provided\n  via the environment variable `DAYTONA_API_KEY`, or a JWT token must be provided instead.\n- `jwt_token` _str | None_ - JWT token for authentication with the Daytona API. If not set, it must be provided\n  via the environment variable `DAYTONA_JWT_TOKEN`, or an API key must be provided instead.\n- `organization_id` _str | None_ - Organization ID used for JWT-based authentication. Required if a JWT token\n  is provided, and must be set either here or in the environment variable `DAYTONA_ORGANIZATION_ID`.\n- `api_url` _str | None_ - URL of the Daytona API. Defaults to `'https://app.daytona.io/api'` if not set\n  here or in the environment variable `DAYTONA_API_URL`.\n- `server_url` _str | None_ - Deprecated. Use `api_url` instead. This property will be removed\n  in a future version.\n- `target` _str | None_ - Target runner location for the Sandbox. Default region for the organization is used\n  if not set here or in the environment variable `DAYTONA_TARGET`.\n- `_experimental` _dict[str, any] | None_ - Configuration for experimental features.\n  \n\n**Example**:\n\n```python\nconfig = DaytonaConfig(api_key=\"your-api-key\")\n```\n```python\nconfig = DaytonaConfig(jwt_token=\"your-jwt-token\", organization_id=\"your-organization-id\")\n```\n\n## CreateSandboxBaseParams\n\n```python\nclass CreateSandboxBaseParams(BaseModel)\n```\n\nBase parameters for creating a new Sandbox.\n\n**Attributes**:\n\n- `name` _str | None_ - Name of the Sandbox.\n- `language` _CodeLanguage | CodeLanguageLiteral | None_ - Programming language for the Sandbox.\n  Defaults to \"python\".\n- `os_user` _str | None_ - OS user for the Sandbox.\n- `env_vars` _dict[str, str] | None_ - Environment variables to set in the Sandbox.\n- `labels` _dict[str, str] | None_ - Custom labels for the Sandbox.\n- `public` _bool | None_ - Whether the Sandbox should be public.\n- `timeout` _float | None_ - Timeout in seconds for Sandbox to be created and started.\n- `auto_stop_interval` _int | None_ - Interval in minutes after which Sandbox will\n  automatically stop if no Sandbox event occurs during that time. Default is 15 minutes.\n  0 means no auto-stop.\n- `auto_archive_interval` _int | None_ - Interval in minutes after which a continuously stopped Sandbox will\n  automatically archive. Default is 7 days.\n  0 means the maximum interval will be used.\n- `auto_delete_interval` _int | None_ - Interval in minutes after which a continuously stopped Sandbox will\n  automatically be deleted. By default, auto-delete is disabled.\n  Negative value means disabled, 0 means delete immediately upon stopping.\n- `volumes` _list[VolumeMount] | None_ - List of volumes mounts to attach to the Sandbox.\n- `network_block_all` _bool | None_ - Whether to block all network access for the Sandbox.\n- `network_allow_list` _str | None_ - Comma-separated list of allowed CIDR network addresses for the Sandbox.\n- `ephemeral` _bool | None_ - Whether the Sandbox should be ephemeral.\n  If True, auto_delete_interval will be set to 0.\n\n## CreateSandboxFromImageParams\n\n```python\nclass CreateSandboxFromImageParams(CreateSandboxBaseParams)\n```\n\nParameters for creating a new Sandbox from an image.\n\n**Attributes**:\n\n- `image` _str | Image_ - Custom Docker image to use for the Sandbox. If an Image object is provided,\n  the image will be dynamically built.\n- `resources` _Resources | None_ - Resource configuration for the Sandbox. If not provided, sandbox will\n  have default resources.\n\n## CreateSandboxFromSnapshotParams\n\n```python\nclass CreateSandboxFromSnapshotParams(CreateSandboxBaseParams)\n```\n\nParameters for creating a new Sandbox from a snapshot.\n\n**Attributes**:\n\n- `snapshot` _str | None_ - Name of the snapshot to use for the Sandbox.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-file-system.mdx",
    "content": "---\ntitle: \"AsyncFileSystem\"\nhideTitleOnPage: true\n---\n\n## AsyncFileSystem\n\n```python\nclass AsyncFileSystem()\n```\n\nProvides file system operations within a Sandbox.\n\nThis class implements a high-level interface to file system operations that can\nbe performed within a Daytona Sandbox.\n\n#### AsyncFileSystem.\\_\\_init\\_\\_\n\n```python\ndef __init__(api_client: FileSystemApi)\n```\n\nInitializes a new FileSystem instance.\n\n**Arguments**:\n\n- `api_client` _FileSystemApi_ - API client for Sandbox file system operations.\n\n#### AsyncFileSystem.create\\_folder\n\n```python\n@intercept_errors(message_prefix=\"Failed to create folder: \")\n@with_instrumentation()\nasync def create_folder(path: str, mode: str) -> None\n```\n\nCreates a new directory in the Sandbox at the specified path with the given\npermissions.\n\n**Arguments**:\n\n- `path` _str_ - Path where the folder should be created. Relative paths are resolved based\n  on the sandbox working directory.\n- `mode` _str_ - Folder permissions in octal format (e.g., \"755\" for rwxr-xr-x).\n  \n\n**Example**:\n\n```python\n# Create a directory with standard permissions\nawait sandbox.fs.create_folder(\"workspace/data\", \"755\")\n\n# Create a private directory\nawait sandbox.fs.create_folder(\"workspace/secrets\", \"700\")\n```\n\n#### AsyncFileSystem.delete\\_file\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete file: \")\n@with_instrumentation()\nasync def delete_file(path: str, recursive: bool = False) -> None\n```\n\nDeletes a file from the Sandbox.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file to delete. Relative paths are resolved based on the sandbox working directory.\n- `recursive` _bool_ - If the file is a directory, this must be true to delete it.\n  \n\n**Example**:\n\n```python\n# Delete a file\nawait sandbox.fs.delete_file(\"workspace/data/old_file.txt\")\n```\n\n#### AsyncFileSystem.download\\_file\n\n```python\n@overload\nasync def download_file(remote_path: str, timeout: int = 30 * 60) -> bytes\n```\n\nDownloads a file from the Sandbox. Returns the file contents as a bytes object.\nThis method is useful when you want to load the file into memory without saving it to disk.\nIt can only be used for smaller files.\n\n**Arguments**:\n\n- `remote_path` _str_ - Path to the file in the Sandbox. Relative paths are resolved based\n  on the sandbox working directory.\n- `timeout` _int_ - Timeout for the download operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Returns**:\n\n- `bytes` - The file contents as a bytes object.\n  \n\n**Example**:\n\n```python\n# Download and save a file locally\ncontent = await sandbox.fs.download_file(\"workspace/data/file.txt\")\nwith open(\"local_copy.txt\", \"wb\") as f:\n    f.write(content)\n\n# Download and process text content\ncontent = await sandbox.fs.download_file(\"workspace/data/config.json\")\nconfig = json.loads(content.decode('utf-8'))\n```\n\n#### AsyncFileSystem.download\\_file\n\n```python\n@overload\nasync def download_file(remote_path: str,\n                        local_path: str,\n                        timeout: int = 30 * 60) -> None\n```\n\nDownloads a file from the Sandbox and saves it to a local file using stream.\nThis method is useful when you want to download larger files that may not fit into memory.\n\n**Arguments**:\n\n- `remote_path` _str_ - Path to the file in the Sandbox. Relative paths are resolved based\n  on the sandbox working directory.\n- `local_path` _str_ - Path to save the file locally.\n- `timeout` _int_ - Timeout for the download operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Example**:\n\n```python\nlocal_path = \"local_copy.txt\"\nawait sandbox.fs.download_file(\"tmp/large_file.txt\", local_path)\nsize_mb = os.path.getsize(local_path) / 1024 / 1024\nprint(f\"Size of the downloaded file {local_path}: {size_mb} MB\")\n```\n\n#### AsyncFileSystem.download\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to download files: \")\n@with_instrumentation()\nasync def download_files(files: list[FileDownloadRequest],\n                         timeout: int = 30 * 60) -> list[FileDownloadResponse]\n```\n\nDownloads multiple files from the Sandbox. If the files already exist locally, they will be overwritten.\n\n**Arguments**:\n\n- `files` _list[FileDownloadRequest]_ - List of files to download.\n- `timeout` _int_ - Timeout for the download operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Returns**:\n\n- `list[FileDownloadResponse]` - List of download results.\n  \n\n**Raises**:\n\n- `Exception` - Only if the request itself fails (network issues, invalid request/response, etc.). Individual\n  file download errors are returned in the `FileDownloadResponse.error` field.\n  \n\n**Example**:\n\n```python\n# Download multiple files\nresults = await sandbox.fs.download_files([\n    FileDownloadRequest(source=\"tmp/data.json\"),\n    FileDownloadRequest(source=\"tmp/config.json\", destination=\"local_config.json\")\n])\nfor result in results:\n    if result.error:\n        print(f\"Error downloading {result.source}: {result.error}\")\n    elif result.result:\n        print(f\"Downloaded {result.source} to {result.result}\")\n```\n\n#### AsyncFileSystem.find\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to find files: \")\n@with_instrumentation()\nasync def find_files(path: str, pattern: str) -> list[Match]\n```\n\nSearches for files containing a pattern, similar to\nthe grep command.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file or directory to search. If the path is a directory,\n  the search will be performed recursively. Relative paths are resolved based\n  on the sandbox working directory.\n- `pattern` _str_ - Search pattern to match against file contents.\n  \n\n**Returns**:\n\n- `list[Match]` - List of matches found in files. Each Match object includes:\n  - file: Path to the file containing the match\n  - line: The line number where the match was found\n  - content: The matching line content\n  \n\n**Example**:\n\n```python\n# Search for TODOs in Python files\nmatches = await sandbox.fs.find_files(\"workspace/src\", \"TODO:\")\nfor match in matches:\n    print(f\"{match.file}:{match.line}: {match.content.strip()}\")\n```\n\n#### AsyncFileSystem.get\\_file\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get file info: \")\n@with_instrumentation()\nasync def get_file_info(path: str) -> FileInfo\n```\n\nGets detailed information about a file or directory, including its\nsize, permissions, and timestamps.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file or directory. Relative paths are resolved based\n  on the sandbox working directory.\n  \n\n**Returns**:\n\n- `FileInfo` - Detailed file information including:\n  - name: File name\n  - is_dir: Whether the path is a directory\n  - size: File size in bytes\n  - mode: File permissions\n  - mod_time: Last modification timestamp\n  - permissions: File permissions in octal format\n  - owner: File owner\n  - group: File group\n  \n\n**Example**:\n\n```python\n# Get file metadata\ninfo = await sandbox.fs.get_file_info(\"workspace/data/file.txt\")\nprint(f\"Size: {info.size} bytes\")\nprint(f\"Modified: {info.mod_time}\")\nprint(f\"Mode: {info.mode}\")\n\n# Check if path is a directory\ninfo = await sandbox.fs.get_file_info(\"workspace/data\")\nif info.is_dir:\n    print(\"Path is a directory\")\n```\n\n#### AsyncFileSystem.list\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to list files: \")\n@with_instrumentation()\nasync def list_files(path: str) -> list[FileInfo]\n```\n\nLists files and directories in a given path and returns their information, similar to the ls -l command.\n\n**Arguments**:\n\n- `path` _str_ - Path to the directory to list contents from. Relative paths are resolved\n  based on the sandbox working directory.\n  \n\n**Returns**:\n\n- `list[FileInfo]` - List of file and directory information. Each FileInfo\n  object includes the same fields as described in get_file_info().\n  \n\n**Example**:\n\n```python\n# List directory contents\nfiles = await sandbox.fs.list_files(\"workspace/data\")\n\n# Print files and their sizes\nfor file in files:\n    if not file.is_dir:\n        print(f\"{file.name}: {file.size} bytes\")\n\n# List only directories\ndirs = [f for f in files if f.is_dir]\nprint(\"Subdirectories:\", \", \".join(d.name for d in dirs))\n```\n\n#### AsyncFileSystem.move\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to move files: \")\n@with_instrumentation()\nasync def move_files(source: str, destination: str) -> None\n```\n\nMoves or renames a file or directory. The parent directory of the destination must exist.\n\n**Arguments**:\n\n- `source` _str_ - Path to the source file or directory. Relative paths are resolved\n  based on the sandbox working directory.\n- `destination` _str_ - Path to the destination. Relative paths are resolved based on\n  the sandbox working directory.\n  \n\n**Example**:\n\n```python\n# Rename a file\nawait sandbox.fs.move_files(\n    \"workspace/data/old_name.txt\",\n    \"workspace/data/new_name.txt\"\n)\n\n# Move a file to a different directory\nawait sandbox.fs.move_files(\n    \"workspace/data/file.txt\",\n    \"workspace/archive/file.txt\"\n)\n\n# Move a directory\nawait sandbox.fs.move_files(\n    \"workspace/old_dir\",\n    \"workspace/new_dir\"\n)\n```\n\n#### AsyncFileSystem.replace\\_in\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to replace in files: \")\n@with_instrumentation()\nasync def replace_in_files(files: list[str], pattern: str,\n                           new_value: str) -> list[ReplaceResult]\n```\n\nPerforms search and replace operations across multiple files.\n\n**Arguments**:\n\n- `files` _list[str]_ - List of file paths to perform replacements in. Relative paths are\n  resolved based on the sandbox working directory.\n- `pattern` _str_ - Pattern to search for.\n- `new_value` _str_ - Text to replace matches with.\n  \n\n**Returns**:\n\n- `list[ReplaceResult]` - List of results indicating replacements made in\n  each file. Each ReplaceResult includes:\n  - file: Path to the modified file\n  - success: Whether the operation was successful\n  - error: Error message if the operation failed\n  \n\n**Example**:\n\n```python\n# Replace in specific files\nresults = await sandbox.fs.replace_in_files(\n    files=[\"workspace/src/file1.py\", \"workspace/src/file2.py\"],\n    pattern=\"old_function\",\n    new_value=\"new_function\"\n)\n\n# Print results\nfor result in results:\n    if result.success:\n        print(f\"{result.file}: {result.success}\")\n    else:\n        print(f\"{result.file}: {result.error}\")\n```\n\n#### AsyncFileSystem.search\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to search files: \")\n@with_instrumentation()\nasync def search_files(path: str, pattern: str) -> SearchFilesResponse\n```\n\nSearches for files and directories whose names match the\nspecified pattern. The pattern can be a simple string or a glob pattern.\n\n**Arguments**:\n\n- `path` _str_ - Path to the root directory to start search from. Relative paths are resolved\n  based on the sandbox working directory.\n- `pattern` _str_ - Pattern to match against file names. Supports glob\n  patterns (e.g., \"*.py\" for Python files).\n  \n\n**Returns**:\n\n- `SearchFilesResponse` - Search results containing:\n  - files: List of matching file and directory paths\n  \n\n**Example**:\n\n```python\n# Find all Python files\nresult = await sandbox.fs.search_files(\"workspace\", \"*.py\")\nfor file in result.files:\n    print(file)\n\n# Find files with specific prefix\nresult = await sandbox.fs.search_files(\"workspace/data\", \"test_*\")\nprint(f\"Found {len(result.files)} test files\")\n```\n\n#### AsyncFileSystem.set\\_file\\_permissions\n\n```python\n@intercept_errors(message_prefix=\"Failed to set file permissions: \")\n@with_instrumentation()\nasync def set_file_permissions(path: str,\n                               mode: str | None = None,\n                               owner: str | None = None,\n                               group: str | None = None) -> None\n```\n\nSets permissions and ownership for a file or directory. Any of the parameters can be None\nto leave that attribute unchanged.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file or directory. Relative paths are resolved based on\n  the sandbox working directory.\n- `mode` _str | None_ - File mode/permissions in octal format\n  (e.g., \"644\" for rw-r--r--).\n- `owner` _str | None_ - User owner of the file.\n- `group` _str | None_ - Group owner of the file.\n  \n\n**Example**:\n\n```python\n# Make a file executable\nawait sandbox.fs.set_file_permissions(\n    path=\"workspace/scripts/run.sh\",\n    mode=\"755\"  # rwxr-xr-x\n)\n\n# Change file owner\nawait sandbox.fs.set_file_permissions(\n    path=\"workspace/data/file.txt\",\n    owner=\"daytona\",\n    group=\"daytona\"\n)\n```\n\n#### AsyncFileSystem.upload\\_file\n\n```python\n@overload\nasync def upload_file(file: bytes,\n                      remote_path: str,\n                      timeout: int = 30 * 60) -> None\n```\n\nUploads a file to the specified path in the Sandbox. If a file already exists at\nthe destination path, it will be overwritten. This method is useful when you want to upload\nsmall files that fit into memory.\n\n**Arguments**:\n\n- `file` _bytes_ - File contents as a bytes object.\n- `remote_path` _str_ - Path to the destination file. Relative paths are resolved based on\n  the sandbox working directory.\n- `timeout` _int_ - Timeout for the upload operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Example**:\n\n```python\n# Upload a text file\ncontent = b\"Hello, World!\"\nawait sandbox.fs.upload_file(content, \"tmp/hello.txt\")\n\n# Upload a local file\nwith open(\"local_file.txt\", \"rb\") as f:\n    content = f.read()\nawait sandbox.fs.upload_file(content, \"tmp/file.txt\")\n\n# Upload binary data\nimport json\ndata = {\"key\": \"value\"}\ncontent = json.dumps(data).encode('utf-8')\nawait sandbox.fs.upload_file(content, \"tmp/config.json\")\n```\n\n#### AsyncFileSystem.upload\\_file\n\n```python\n@overload\nasync def upload_file(local_path: str,\n                      remote_path: str,\n                      timeout: int = 30 * 60) -> None\n```\n\nUploads a file from the local file system to the specified path in the Sandbox.\nIf a file already exists at the destination path, it will be overwritten. This method uses\nstreaming to upload the file, so it is useful when you want to upload larger files that may\nnot fit into memory.\n\n**Arguments**:\n\n- `local_path` _str_ - Path to the local file to upload.\n- `remote_path` _str_ - Path to the destination file in the Sandbox. Relative paths are\n  resolved based on the sandbox working directory.\n- `timeout` _int_ - Timeout for the upload operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Example**:\n\n```python\nawait sandbox.fs.upload_file(\"local_file.txt\", \"tmp/large_file.txt\")\n```\n\n#### AsyncFileSystem.upload\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to upload files: \")\n@with_instrumentation()\nasync def upload_files(files: list[FileUpload],\n                       timeout: int = 30 * 60) -> None\n```\n\nUploads multiple files to the Sandbox. If files already exist at the destination paths,\nthey will be overwritten.\n\n**Arguments**:\n\n- `files` _list[FileUpload]_ - List of files to upload.\n- `timeout` _int_ - Timeout for the upload operation in seconds. 0 means no timeout. Default is 30 minutes.\n\n**Example**:\n\n```python\n# Upload multiple text files\nfiles = [\n    FileUpload(\n        source=b\"Content of file 1\",\n        destination=\"/tmp/file1.txt\"\n    ),\n    FileUpload(\n        source=\"workspace/data/file2.txt\",\n        destination=\"/tmp/file2.txt\"\n    ),\n    FileUpload(\n        source=b'{\"key\": \"value\"}',\n        destination=\"/tmp/config.json\"\n    )\n]\nawait sandbox.fs.upload_files(files)\n```\n\n\n## FileUpload\n\n```python\n@dataclass\nclass FileUpload()\n```\n\nRepresents a file to be uploaded to the Sandbox.\n\n**Attributes**:\n\n- `source` _bytes | str_ - File contents as a bytes object or a local file path. If a bytes object is provided,\n  make sure it fits into memory, otherwise use the local file path which content will be streamed to the Sandbox.\n- `destination` _str_ - Absolute destination path in the Sandbox. Relative paths are resolved based on\n  the sandbox working directory.\n\n## FileDownloadRequest\n\n```python\n@dataclass\nclass FileDownloadRequest()\n```\n\nRepresents a request to download a single file from the Sandbox.\n\n**Attributes**:\n\n- `source` _str_ - Source path in the Sandbox. Relative paths are resolved based on the user's\n  root directory.\n- `destination` _str | None_ - Destination path in the local filesystem where the file content will be\n  streamed to. If not provided, the file will be downloaded in the bytes buffer\n  (might cause memory issues if the file is large).\n\n## FileDownloadResponse\n\n```python\n@dataclass\nclass FileDownloadResponse()\n```\n\nRepresents the response to a single file download request.\n\n**Attributes**:\n\n- `source` _str_ - The original source path requested for download.\n- `result` _str | bytes | None_ - The download result - file path (if destination provided in the request)\n  or bytes content (if no destination in the request), None if failed or no data received.\n- `error` _str | None_ - Error message if the download failed, None if successful.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-git.mdx",
    "content": "---\ntitle: \"AsyncGit\"\nhideTitleOnPage: true\n---\n\n## AsyncGit\n\n```python\nclass AsyncGit()\n```\n\nProvides Git operations within a Sandbox.\n\n**Example**:\n\n```python\n# Clone a repository\nawait sandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# Check repository status\nstatus = await sandbox.git.status(\"workspace/repo\")\nprint(f\"Modified files: {status.modified}\")\n\n# Stage and commit changes\nawait sandbox.git.add(\"workspace/repo\", [\"file.txt\"])\nawait sandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update file\",\n    author=\"John Doe\",\n    email=\"john@example.com\"\n)\n```\n\n#### AsyncGit.\\_\\_init\\_\\_\n\n```python\ndef __init__(api_client: GitApi)\n```\n\nInitializes a new Git handler instance.\n\n**Arguments**:\n\n- `api_client` _GitApi_ - API client for Sandbox Git operations.\n\n#### AsyncGit.add\n\n```python\n@intercept_errors(message_prefix=\"Failed to add files: \")\n@with_instrumentation()\nasync def add(path: str, files: list[str]) -> None\n```\n\nStages the specified files for the next commit, similar to\nrunning 'git add' on the command line.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `files` _list[str]_ - List of file paths or directories to stage, relative to the repository root.\n  \n\n**Example**:\n\n```python\n# Stage a single file\nawait sandbox.git.add(\"workspace/repo\", [\"file.txt\"])\n\n# Stage multiple files\nawait sandbox.git.add(\"workspace/repo\", [\n    \"src/main.py\",\n    \"tests/test_main.py\",\n    \"README.md\"\n])\n```\n\n#### AsyncGit.branches\n\n```python\n@intercept_errors(message_prefix=\"Failed to list branches: \")\n@with_instrumentation()\nasync def branches(path: str) -> ListBranchResponse\n```\n\nLists branches in the repository.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n  \n\n**Returns**:\n\n- `ListBranchResponse` - List of branches in the repository.\n  \n\n**Example**:\n\n```python\nresponse = await sandbox.git.branches(\"workspace/repo\")\nprint(f\"Branches: {response.branches}\")\n```\n\n#### AsyncGit.clone\n\n```python\n@intercept_errors(message_prefix=\"Failed to clone repository: \")\n@with_instrumentation()\nasync def clone(url: str,\n                path: str,\n                branch: str | None = None,\n                commit_id: str | None = None,\n                username: str | None = None,\n                password: str | None = None) -> None\n```\n\nClones a Git repository into the specified path. It supports\ncloning specific branches or commits, and can authenticate with the remote\nrepository if credentials are provided.\n\n**Arguments**:\n\n- `url` _str_ - Repository URL to clone from.\n- `path` _str_ - Path where the repository should be cloned. Relative paths are resolved\n  based on the sandbox working directory.\n- `branch` _str | None_ - Specific branch to clone. If not specified,\n  clones the default branch.\n- `commit_id` _str | None_ - Specific commit to clone. If specified,\n  the repository will be left in a detached HEAD state at this commit.\n- `username` _str | None_ - Git username for authentication.\n- `password` _str | None_ - Git password or token for authentication.\n  \n\n**Example**:\n\n```python\n# Clone the default branch\nawait sandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# Clone a specific branch with authentication\nawait sandbox.git.clone(\n    url=\"https://github.com/user/private-repo.git\",\n    path=\"workspace/private\",\n    branch=\"develop\",\n    username=\"user\",\n    password=\"token\"\n)\n\n# Clone a specific commit\nawait sandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo-old\",\n    commit_id=\"abc123\"\n)\n```\n\n#### AsyncGit.commit\n\n```python\n@intercept_errors(message_prefix=\"Failed to commit changes: \")\n@with_instrumentation()\nasync def commit(path: str,\n                 message: str,\n                 author: str,\n                 email: str,\n                 allow_empty: bool = False) -> GitCommitResponse\n```\n\nCreates a new commit with the staged changes. Make sure to stage\nchanges using the add() method before committing.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `message` _str_ - Commit message describing the changes.\n- `author` _str_ - Name of the commit author.\n- `email` _str_ - Email address of the commit author.\n- `allow_empty` _bool_ - Allow creating an empty commit when no changes are staged. Defaults to False.\n  \n\n**Example**:\n\n```python\n# Stage and commit changes\nawait sandbox.git.add(\"workspace/repo\", [\"README.md\"])\nawait sandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update documentation\",\n    author=\"John Doe\",\n    email=\"john@example.com\",\n    allow_empty=True\n)\n```\n\n#### AsyncGit.push\n\n```python\n@intercept_errors(message_prefix=\"Failed to push changes: \")\n@with_instrumentation()\nasync def push(path: str,\n               username: str | None = None,\n               password: str | None = None) -> None\n```\n\nPushes all local commits on the current branch to the remote\nrepository. If the remote repository requires authentication, provide\nusername and password/token.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `username` _str | None_ - Git username for authentication.\n- `password` _str | None_ - Git password or token for authentication.\n  \n\n**Example**:\n\n```python\n# Push without authentication (for public repos or SSH)\nawait sandbox.git.push(\"workspace/repo\")\n\n# Push with authentication\nawait sandbox.git.push(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n#### AsyncGit.pull\n\n```python\n@intercept_errors(message_prefix=\"Failed to pull changes: \")\n@with_instrumentation()\nasync def pull(path: str,\n               username: str | None = None,\n               password: str | None = None) -> None\n```\n\nPulls changes from the remote repository. If the remote repository requires authentication,\nprovide username and password/token.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `username` _str | None_ - Git username for authentication.\n- `password` _str | None_ - Git password or token for authentication.\n  \n\n**Example**:\n\n```python\n# Pull without authentication\nawait sandbox.git.pull(\"workspace/repo\")\n\n# Pull with authentication\nawait sandbox.git.pull(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n#### AsyncGit.status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get status: \")\n@with_instrumentation()\nasync def status(path: str) -> GitStatus\n```\n\nGets the current Git repository status.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n  \n\n**Returns**:\n\n- `GitStatus` - Repository status information including:\n  - current_branch: Current branch name\n  - file_status: List of file statuses\n  - ahead: Number of local commits not pushed to remote\n  - behind: Number of remote commits not pulled locally\n  - branch_published: Whether the branch has been published to the remote repository\n  \n\n**Example**:\n\n```python\nstatus = await sandbox.git.status(\"workspace/repo\")\nprint(f\"On branch: {status.current_branch}\")\nprint(f\"Commits ahead: {status.ahead}\")\nprint(f\"Commits behind: {status.behind}\")\n```\n\n#### AsyncGit.checkout\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to checkout branch: \")\n@with_instrumentation()\nasync def checkout_branch(path: str, branch: str) -> None\n```\n\nCheckout branch in the repository.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `branch` _str_ - Name of the branch to checkout\n  \n\n**Example**:\n\n```python\n# Checkout a branch\nawait sandbox.git.checkout_branch(\"workspace/repo\", \"feature-branch\")\n```\n\n#### AsyncGit.create\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to create branch: \")\n@with_instrumentation()\nasync def create_branch(path: str, name: str) -> None\n```\n\nCreate branch in the repository.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `name` _str_ - Name of the new branch to create\n  \n\n**Example**:\n\n```python\n# Create a new branch\nawait sandbox.git.create_branch(\"workspace/repo\", \"new-feature\")\n```\n\n#### AsyncGit.delete\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete branch: \")\n@with_instrumentation()\nasync def delete_branch(path: str, name: str) -> None\n```\n\nDelete branch in the repository.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `name` _str_ - Name of the branch to delete\n  \n\n**Example**:\n\n```python\n# Delete a branch\nawait sandbox.git.delete_branch(\"workspace/repo\", \"old-feature\")\n```\n\n\n## GitCommitResponse\n\n```python\nclass GitCommitResponse()\n```\n\nResponse from the git commit.\n\n**Attributes**:\n\n- `sha` _str_ - The SHA of the commit\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-lsp-server.mdx",
    "content": "---\ntitle: \"AsyncLspServer\"\nhideTitleOnPage: true\n---\n\n## AsyncLspServer\n\n```python\nclass AsyncLspServer()\n```\n\nProvides Language Server Protocol functionality for code intelligence to provide\nIDE-like features such as code completion, symbol search, and more.\n\n#### AsyncLspServer.\\_\\_init\\_\\_\n\n```python\ndef __init__(language_id: LspLanguageId | LspLanguageIdLiteral,\n             path_to_project: str, api_client: LspApi)\n```\n\nInitializes a new LSP server instance.\n\n**Arguments**:\n\n- `language_id` _LspLanguageId | LspLanguageIdLiteral_ - The language server type\n  (e.g., LspLanguageId.TYPESCRIPT).\n- `path_to_project` _str_ - Absolute path to the project root directory.\n- `api_client` _LspApi_ - API client for Sandbox operations.\n\n#### AsyncLspServer.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start LSP server: \")\n@with_instrumentation()\nasync def start() -> None\n```\n\nStarts the language server.\n\nThis method must be called before using any other LSP functionality.\nIt initializes the language server for the specified language and project.\n\n**Example**:\n\n```python\nlsp = sandbox.create_lsp_server(\"typescript\", \"workspace/project\")\nawait lsp.start()  # Initialize the server\n# Now ready for LSP operations\n```\n\n#### AsyncLspServer.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop LSP server: \")\n@with_instrumentation()\nasync def stop() -> None\n```\n\nStops the language server.\n\nThis method should be called when the LSP server is no longer needed to\nfree up system resources.\n\n**Example**:\n\n```python\n# When done with LSP features\nawait lsp.stop()  # Clean up resources\n```\n\n#### AsyncLspServer.did\\_open\n\n```python\n@intercept_errors(message_prefix=\"Failed to open file: \")\n@with_instrumentation()\nasync def did_open(path: str) -> None\n```\n\nNotifies the language server that a file has been opened.\n\nThis method should be called when a file is opened in the editor to enable\nlanguage features like diagnostics and completions for that file. The server\nwill begin tracking the file's contents and providing language features.\n\n**Arguments**:\n\n- `path` _str_ - Path to the opened file. Relative paths are resolved based on the project path\n  set in the LSP server constructor.\n  \n\n**Example**:\n\n```python\n# When opening a file for editing\nawait lsp.did_open(\"workspace/project/src/index.ts\")\n# Now can get completions, symbols, etc. for this file\n```\n\n#### AsyncLspServer.did\\_close\n\n```python\n@intercept_errors(message_prefix=\"Failed to close file: \")\n@with_instrumentation()\nasync def did_close(path: str) -> None\n```\n\nNotify the language server that a file has been closed.\n\nThis method should be called when a file is closed in the editor to allow\nthe language server to clean up any resources associated with that file.\n\n**Arguments**:\n\n- `path` _str_ - Path to the closed file. Relative paths are resolved based on the project path\n  set in the LSP server constructor.\n  \n\n**Example**:\n\n```python\n# When done editing a file\nawait lsp.did_close(\"workspace/project/src/index.ts\")\n```\n\n#### AsyncLspServer.document\\_symbols\n\n```python\n@intercept_errors(message_prefix=\"Failed to get symbols from document: \")\n@with_instrumentation()\nasync def document_symbols(path: str) -> list[LspSymbol]\n```\n\nGets symbol information (functions, classes, variables, etc.) from a document.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file to get symbols from. Relative paths are resolved based on the project path\n  set in the LSP server constructor.\n  \n\n**Returns**:\n\n- `list[LspSymbol]` - List of symbols in the document. Each symbol includes:\n  - name: The symbol's name\n  - kind: The symbol's kind (function, class, variable, etc.)\n  - location: The location of the symbol in the file\n  \n\n**Example**:\n\n```python\n# Get all symbols in a file\nsymbols = await lsp.document_symbols(\"workspace/project/src/index.ts\")\nfor symbol in symbols:\n    print(f\"{symbol.kind} {symbol.name}: {symbol.location}\")\n```\n\n#### AsyncLspServer.workspace\\_symbols\n\n```python\n@deprecated(\n    reason=\n    \"Method is deprecated. Use `sandbox_symbols` instead. This method will be removed in a future version.\"\n)\n@with_instrumentation()\nasync def workspace_symbols(query: str) -> list[LspSymbol]\n```\n\nSearches for symbols matching the query string across all files\nin the Sandbox.\n\n**Arguments**:\n\n- `query` _str_ - Search query to match against symbol names.\n  \n\n**Returns**:\n\n- `list[LspSymbol]` - List of matching symbols from all files.\n\n#### AsyncLspServer.sandbox\\_symbols\n\n```python\n@intercept_errors(message_prefix=\"Failed to get symbols from sandbox: \")\n@with_instrumentation()\nasync def sandbox_symbols(query: str) -> list[LspSymbol]\n```\n\nSearches for symbols matching the query string across all files\nin the Sandbox.\n\n**Arguments**:\n\n- `query` _str_ - Search query to match against symbol names.\n  \n\n**Returns**:\n\n- `list[LspSymbol]` - List of matching symbols from all files. Each symbol\n  includes:\n  - name: The symbol's name\n  - kind: The symbol's kind (function, class, variable, etc.)\n  - location: The location of the symbol in the file\n  \n\n**Example**:\n\n```python\n# Search for all symbols containing \"User\"\nsymbols = await lsp.sandbox_symbols(\"User\")\nfor symbol in symbols:\n    print(f\"{symbol.name} in {symbol.location}\")\n```\n\n#### AsyncLspServer.completions\n\n```python\n@intercept_errors(message_prefix=\"Failed to get completions: \")\n@with_instrumentation()\nasync def completions(path: str,\n                      position: LspCompletionPosition) -> CompletionList\n```\n\nGets completion suggestions at a position in a file.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file. Relative paths are resolved based on the project path\n  set in the LSP server constructor.\n- `position` _LspCompletionPosition_ - Cursor position to get completions for.\n  \n\n**Returns**:\n\n- `CompletionList` - List of completion suggestions. The list includes:\n  - isIncomplete: Whether more items might be available\n  - items: List of completion items, each containing:\n  - label: The text to insert\n  - kind: The kind of completion\n  - detail: Additional details about the item\n  - documentation: Documentation for the item\n  - sortText: Text used to sort the item in the list\n  - filterText: Text used to filter the item\n  - insertText: The actual text to insert (if different from label)\n  \n\n**Example**:\n\n```python\n# Get completions at a specific position\npos = LspCompletionPosition(line=10, character=15)\ncompletions = await lsp.completions(\"workspace/project/src/index.ts\", pos)\nfor item in completions.items:\n    print(f\"{item.label} ({item.kind}): {item.detail}\")\n```\n\n\n## LspLanguageId\n\n```python\nclass LspLanguageId(str, Enum)\n```\n\nLanguage IDs for Language Server Protocol (LSP).\n\n**Enum Members**:\n    - `PYTHON` (\"python\")\n    - `TYPESCRIPT` (\"typescript\")\n    - `JAVASCRIPT` (\"javascript\")\n\n## LspCompletionPosition\n\n```python\n@dataclass\nclass LspCompletionPosition()\n```\n\nRepresents a zero-based completion position in a text document,\nspecified by line number and character offset.\n\n**Attributes**:\n\n- `line` _int_ - Zero-based line number in the document.\n- `character` _int_ - Zero-based character offset on the line.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-object-storage.mdx",
    "content": "---\ntitle: \"AsyncObjectStorage\"\nhideTitleOnPage: true\n---\n\n## AsyncObjectStorage\n\n```python\nclass AsyncObjectStorage()\n```\n\nAsyncObjectStorage class for interacting with object storage services.\n\n**Attributes**:\n\n- `endpoint_url` _str_ - The endpoint URL for the object storage service.\n- `aws_access_key_id` _str_ - The access key ID for the object storage service.\n- `aws_secret_access_key` _str_ - The secret access key for the object storage service.\n- `aws_session_token` _str_ - The session token for the object storage service. Used for temporary credentials.\n- `bucket_name` _str_ - The name of the bucket to use. Defaults to \"daytona-volume-builds\".\n\n#### AsyncObjectStorage.upload\n\n```python\n@with_instrumentation()\nasync def upload(path: str,\n                 organization_id: str,\n                 archive_base_path: str | None = None) -> str\n```\n\nUploads a file to the object storage service.\n\n**Arguments**:\n\n- `path` _str_ - The path to the file to upload.\n- `organization_id` _str_ - The organization ID to use.\n- `archive_base_path` _str_ - The base path to use for the archive.\n  \n\n**Returns**:\n\n- `str` - The hash of the uploaded file.\n\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-process.mdx",
    "content": "---\ntitle: \"AsyncProcess\"\nhideTitleOnPage: true\n---\n\n## AsyncProcess\n\n```python\nclass AsyncProcess()\n```\n\nHandles process and code execution within a Sandbox.\n\n#### AsyncProcess.\\_\\_init\\_\\_\n\n```python\ndef __init__(code_toolbox: SandboxCodeToolbox, api_client: ProcessApi)\n```\n\nInitialize a new Process instance.\n\n**Arguments**:\n\n- `code_toolbox` _SandboxCodeToolbox_ - Language-specific code execution toolbox.\n- `api_client` _ProcessApi_ - API client for process operations.\n\n#### AsyncProcess.exec\n\n```python\n@intercept_errors(message_prefix=\"Failed to execute command: \")\n@with_instrumentation()\nasync def exec(command: str,\n               cwd: str | None = None,\n               env: dict[str, str] | None = None,\n               timeout: int | None = None) -> ExecuteResponse\n```\n\nExecute a shell command in the Sandbox.\n\n**Arguments**:\n\n- `command` _str_ - Shell command to execute.\n- `cwd` _str | None_ - Working directory for command execution. If not\n  specified, uses the sandbox working directory.\n- `env` _dict[str, str] | None_ - Environment variables to set for the command.\n- `timeout` _int | None_ - Maximum time in seconds to wait for the command\n  to complete. 0 means wait indefinitely.\n  \n\n**Returns**:\n\n- `ExecuteResponse` - Command execution results containing:\n  - exit_code: The command's exit status\n  - result: Standard output from the command\n  - artifacts: ExecutionArtifacts object containing `stdout` (same as result)\n  and `charts` (matplotlib charts metadata)\n  \n\n**Example**:\n\n```python\n# Simple command\nresponse = await sandbox.process.exec(\"echo 'Hello'\")\nprint(response.artifacts.stdout)  # Prints: Hello\n\n# Command with working directory\nresult = await sandbox.process.exec(\"ls\", cwd=\"workspace/src\")\n\n# Command with timeout\nresult = await sandbox.process.exec(\"sleep 10\", timeout=5)\n```\n\n#### AsyncProcess.code\\_run\n\n```python\n@with_instrumentation()\nasync def code_run(code: str,\n                   params: CodeRunParams | None = None,\n                   timeout: int | None = None) -> ExecuteResponse\n```\n\nExecutes code in the Sandbox using the appropriate language runtime.\n\n**Arguments**:\n\n- `code` _str_ - Code to execute.\n- `params` _CodeRunParams | None_ - Parameters for code execution.\n- `timeout` _int | None_ - Maximum time in seconds to wait for the code\n  to complete. 0 means wait indefinitely.\n  \n\n**Returns**:\n\n- `ExecuteResponse` - Code execution result containing:\n  - exit_code: The execution's exit status\n  - result: Standard output from the code\n  - artifacts: ExecutionArtifacts object containing `stdout` (same as result)\n  and `charts` (matplotlib charts metadata)\n  \n\n**Example**:\n\n```python\n# Run Python code\nresponse = await sandbox.process.code_run('''\n    x = 10\n    y = 20\n    print(f\"Sum: {x + y}\")\n''')\nprint(response.artifacts.stdout)  # Prints: Sum: 30\n```\n  \n  Matplotlib charts are automatically detected and returned in the `charts` field\n  of the `ExecutionArtifacts` object.\n```python\ncode = '''\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nx = np.linspace(0, 10, 30)\ny = np.sin(x)\n\nplt.figure(figsize=(8, 5))\nplt.plot(x, y, 'b-', linewidth=2)\nplt.title('Line Chart')\nplt.xlabel('X-axis (seconds)')\nplt.ylabel('Y-axis (amplitude)')\nplt.grid(True)\nplt.show()\n'''\n\nresponse = await sandbox.process.code_run(code)\nchart = response.artifacts.charts[0]\n\nprint(f\"Type: {chart.type}\")\nprint(f\"Title: {chart.title}\")\nif chart.type == ChartType.LINE and isinstance(chart, LineChart):\n    print(f\"X Label: {chart.x_label}\")\n    print(f\"Y Label: {chart.y_label}\")\n    print(f\"X Ticks: {chart.x_ticks}\")\n    print(f\"X Tick Labels: {chart.x_tick_labels}\")\n    print(f\"X Scale: {chart.x_scale}\")\n    print(f\"Y Ticks: {chart.y_ticks}\")\n    print(f\"Y Tick Labels: {chart.y_tick_labels}\")\n    print(f\"Y Scale: {chart.y_scale}\")\n    print(\"Elements:\")\n    for element in chart.elements:\n        print(f\"Label: {element.label}\")\n        print(f\"Points: {element.points}\")\n```\n\n#### AsyncProcess.create\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to create session: \")\n@with_instrumentation()\nasync def create_session(session_id: str) -> None\n```\n\nCreates a new long-running background session in the Sandbox.\n\nSessions are background processes that maintain state between commands, making them ideal for\nscenarios requiring multiple related commands or persistent environment setup. You can run\nlong-running commands and monitor process status.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier for the new session.\n  \n\n**Example**:\n\n```python\n# Create a new session\nsession_id = \"my-session\"\nawait sandbox.process.create_session(session_id)\nsession = await sandbox.process.get_session(session_id)\n# Do work...\nawait sandbox.process.delete_session(session_id)\n```\n\n#### AsyncProcess.get\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session: \")\nasync def get_session(session_id: str) -> Session\n```\n\nGets a session in the Sandbox.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session to retrieve.\n  \n\n**Returns**:\n\n- `Session` - Session information including:\n  - session_id: The session's unique identifier\n  - commands: List of commands executed in the session\n  \n\n**Example**:\n\n```python\nsession = await sandbox.process.get_session(\"my-session\")\nfor cmd in session.commands:\n    print(f\"Command: {cmd.command}\")\n```\n\n#### AsyncProcess.get\\_entrypoint\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to get sandbox entrypoint session: \")\nasync def get_entrypoint_session() -> Session\n```\n\nGets the sandbox entrypoint session.\n\n**Returns**:\n\n- `Session` - Entrypoint session information including:\n  - session_id: The entrypoint session's unique identifier\n  - commands: List of commands executed in the entrypoint session\n  \n\n**Example**:\n\n```python\nsession = await sandbox.process.get_entrypoint_session()\nfor cmd in session.commands:\n    print(f\"Command: {cmd.command}\")\n```\n\n#### AsyncProcess.get\\_session\\_command\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command: \")\n@with_instrumentation()\nasync def get_session_command(session_id: str, command_id: str) -> Command\n```\n\nGets information about a specific command executed in a session.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session.\n- `command_id` _str_ - Unique identifier of the command.\n  \n\n**Returns**:\n\n- `Command` - Command information including:\n  - id: The command's unique identifier\n  - command: The executed command string\n  - exit_code: Command's exit status (if completed)\n  \n\n**Example**:\n\n```python\ncmd = await sandbox.process.get_session_command(\"my-session\", \"cmd-123\")\nif cmd.exit_code == 0:\n    print(f\"Command {cmd.command} completed successfully\")\n```\n\n#### AsyncProcess.execute\\_session\\_command\n\n```python\n@intercept_errors(message_prefix=\"Failed to execute session command: \")\n@with_instrumentation()\nasync def execute_session_command(\n        session_id: str,\n        req: SessionExecuteRequest,\n        timeout: int | None = None) -> SessionExecuteResponse\n```\n\nExecutes a command in the session.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session to use.\n- `req` _SessionExecuteRequest_ - Command execution request containing:\n  - command: The command to execute\n  - run_async: Whether to execute asynchronously\n  \n\n**Returns**:\n\n- `SessionExecuteResponse` - Command execution results containing:\n  - cmd_id: Unique identifier for the executed command\n  - output: Combined command output (stdout and stderr) (if synchronous execution)\n  - stdout: Standard output from the command\n  - stderr: Standard error from the command\n  - exit_code: Command exit status (if synchronous execution)\n  \n\n**Example**:\n\n```python\n# Execute commands in sequence, maintaining state\nsession_id = \"my-session\"\n\n# Change directory\nreq = SessionExecuteRequest(command=\"cd /workspace\")\nawait sandbox.process.execute_session_command(session_id, req)\n\n# Create a file\nreq = SessionExecuteRequest(command=\"echo 'Hello' > test.txt\")\nawait sandbox.process.execute_session_command(session_id, req)\n\n# Read the file\nreq = SessionExecuteRequest(command=\"cat test.txt\")\nresult = await sandbox.process.execute_session_command(session_id, req)\nprint(f\"Command stdout: {result.stdout}\")\nprint(f\"Command stderr: {result.stderr}\")\n```\n\n#### AsyncProcess.get\\_session\\_command\\_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command logs: \")\n@with_instrumentation()\nasync def get_session_command_logs(\n        session_id: str, command_id: str) -> SessionCommandLogsResponse\n```\n\nGet the logs for a command executed in a session.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session.\n- `command_id` _str_ - Unique identifier of the command.\n  \n\n**Returns**:\n\n- `SessionCommandLogsResponse` - Command logs including:\n  - output: Combined command output (stdout and stderr)\n  - stdout: Standard output from the command\n  - stderr: Standard error from the command\n  \n\n**Example**:\n\n```python\nlogs = await sandbox.process.get_session_command_logs(\n    \"my-session\",\n    \"cmd-123\"\n)\nprint(f\"Command stdout: {logs.stdout}\")\nprint(f\"Command stderr: {logs.stderr}\")\n```\n\n#### AsyncProcess.get\\_session\\_command\\_logs\\_async\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command logs: \")\nasync def get_session_command_logs_async(\n        session_id: str, command_id: str, on_stdout: OutputHandler[str],\n        on_stderr: OutputHandler[str]) -> None\n```\n\nAsynchronously retrieves and processes the logs for a command executed in a session as they become available.\n\nAccepts both sync and async callbacks. Async callbacks are awaited.\nBlocking synchronous operations inside callbacks may cause WebSocket\ndisconnections — use async callbacks and async libraries to avoid this.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session.\n- `command_id` _str_ - Unique identifier of the command.\n- `on_stdout` _OutputHandler[str]_ - Callback function to handle stdout log chunks as they arrive.\n- `on_stderr` _OutputHandler[str]_ - Callback function to handle stderr log chunks as they arrive.\n  \n\n**Example**:\n\n```python\nawait sandbox.process.get_session_command_logs_async(\n    \"my-session\",\n    \"cmd-123\",\n    lambda log: print(f\"[STDOUT]: {log}\"),\n    lambda log: print(f\"[STDERR]: {log}\"),\n)\n```\n\n#### AsyncProcess.get\\_entrypoint\\_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get entrypoint logs: \")\n@with_instrumentation()\nasync def get_entrypoint_logs() -> SessionCommandLogsResponse\n```\n\nGet the logs for the entrypoint session.\n\n**Returns**:\n\n- `SessionCommandLogsResponse` - Command logs including:\n  - output: Combined command output (stdout and stderr)\n  - stdout: Standard output from the command\n  - stderr: Standard error from the command\n  \n\n**Example**:\n\n```python\nlogs = await sandbox.process.get_entrypoint_logs()\nprint(f\"Command stdout: {logs.stdout}\")\nprint(f\"Command stderr: {logs.stderr}\")\n```\n\n#### AsyncProcess.get\\_entrypoint\\_logs\\_async\n\n```python\n@intercept_errors(message_prefix=\"Failed to get entrypoint logs: \")\nasync def get_entrypoint_logs_async(on_stdout: OutputHandler[str],\n                                    on_stderr: OutputHandler[str]) -> None\n```\n\nAsynchronously retrieves and processes the logs for the entrypoint session as they become available.\n\n**Arguments**:\n\n  on_stdout OutputHandler[str]: Callback function to handle stdout log chunks as they arrive.\n  on_stderr OutputHandler[str]: Callback function to handle stderr log chunks as they arrive.\n  \n\n**Example**:\n\n```python\nawait sandbox.process.get_entrypoint_logs_async(\n    lambda log: print(f\"[STDOUT]: {log}\"),\n    lambda log: print(f\"[STDERR]: {log}\"),\n)\n```\n\n#### AsyncProcess.send\\_session\\_command\\_input\n\n```python\n@intercept_errors(message_prefix=\"Failed to send session command input: \")\nasync def send_session_command_input(session_id: str, command_id: str,\n                                     data: str) -> None\n```\n\nSends input data to a command executed in a session.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session.\n- `command_id` _str_ - Unique identifier of the command.\n- `data` _str_ - Input data to send.\n\n#### AsyncProcess.list\\_sessions\n\n```python\n@intercept_errors(message_prefix=\"Failed to list sessions: \")\n@with_instrumentation()\nasync def list_sessions() -> list[Session]\n```\n\nLists all sessions in the Sandbox.\n\n**Returns**:\n\n- `list[Session]` - List of all sessions in the Sandbox.\n  \n\n**Example**:\n\n```python\nsessions = await sandbox.process.list_sessions()\nfor session in sessions:\n    print(f\"Session {session.session_id}:\")\n    print(f\"  Commands: {len(session.commands)}\")\n```\n\n#### AsyncProcess.delete\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete session: \")\n@with_instrumentation()\nasync def delete_session(session_id: str) -> None\n```\n\nTerminates and removes a session from the Sandbox, cleaning up any resources\nassociated with it.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session to delete.\n  \n\n**Example**:\n\n```python\n# Create and use a session\nawait sandbox.process.create_session(\"temp-session\")\n# ... use the session ...\n\n# Clean up when done\nawait sandbox.process.delete_session(\"temp-session\")\n```\n\n#### AsyncProcess.create\\_pty\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to create PTY session: \")\n@with_instrumentation()\nasync def create_pty_session(\n        id: str,\n        on_data: Callable[[bytes], None] | Callable[[bytes], Awaitable[None]],\n        cwd: str | None = None,\n        envs: dict[str, str] | None = None,\n        pty_size: PtySize | None = None) -> AsyncPtyHandle\n```\n\nCreates a new PTY (pseudo-terminal) session in the Sandbox.\n\nCreates an interactive terminal session that can execute commands and handle user input.\nThe PTY session behaves like a real terminal, supporting features like command history.\n\n**Arguments**:\n\n- `id` - Unique identifier for the PTY session. Must be unique within the Sandbox.\n  on_data (Callable[[bytes], None] | Callable[[bytes], Awaitable[None]]):\n  Callback function to handle PTY output data.\n- `cwd` - Working directory for the PTY session. Defaults to the sandbox's working directory.\n- `env` - Environment variables to set in the PTY session. These will be merged with\n  the Sandbox's default environment variables.\n- `pty_size` - Terminal size configuration. Defaults to 80x24 if not specified.\n  \n\n**Returns**:\n\n- `AsyncPtyHandle` - Handle for managing the created PTY session. Use this to send input,\n  receive output, resize the terminal, and manage the session lifecycle.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session creation fails or the session ID is already in use.\n\n#### AsyncProcess.connect\\_pty\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to connect PTY session: \")\n@with_instrumentation()\nasync def connect_pty_session(\n    session_id: str,\n    on_data: Callable[[bytes], None] | Callable[[bytes], Awaitable[None]]\n) -> AsyncPtyHandle\n```\n\nConnects to an existing PTY session in the Sandbox.\n\nEstablishes a WebSocket connection to an existing PTY session, allowing you to\ninteract with a previously created terminal session.\n\n**Arguments**:\n\n- `session_id` - Unique identifier of the PTY session to connect to.\n  \n\n**Returns**:\n\n- `AsyncPtyHandle` - Handle for managing the connected PTY session.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session doesn't exist or connection fails.\n\n#### AsyncProcess.list\\_pty\\_sessions\n\n```python\n@intercept_errors(message_prefix=\"Failed to list PTY sessions: \")\n@with_instrumentation()\nasync def list_pty_sessions() -> list[PtySessionInfo]\n```\n\nLists all PTY sessions in the Sandbox.\n\nRetrieves information about all PTY sessions in this Sandbox.\n\n**Returns**:\n\n- `list[PtySessionInfo]` - List of PTY session information objects containing\n  details about each session's state, creation time, and configuration.\n  \n\n**Example**:\n\n```python\n# List all PTY sessions\nsessions = await sandbox.process.list_pty_sessions()\n\nfor session in sessions:\n    print(f\"Session ID: {session.id}\")\n    print(f\"Active: {session.active}\")\n    print(f\"Created: {session.created_at}\")\n```\n\n#### AsyncProcess.get\\_pty\\_session\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get PTY session info: \")\n@with_instrumentation()\nasync def get_pty_session_info(session_id: str) -> PtySessionInfo\n```\n\nGets detailed information about a specific PTY session.\n\nRetrieves comprehensive information about a PTY session including its current state,\nconfiguration, and metadata.\n\n**Arguments**:\n\n- `session_id` - Unique identifier of the PTY session to retrieve information for.\n  \n\n**Returns**:\n\n- `PtySessionInfo` - Detailed information about the PTY session including ID, state,\n  creation time, working directory, environment variables, and more.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session doesn't exist.\n  \n\n**Example**:\n\n```python\n# Get details about a specific PTY session\nsession_info = await sandbox.process.get_pty_session_info(\"my-session\")\n\nprint(f\"Session ID: {session_info.id}\")\nprint(f\"Active: {session_info.active}\")\nprint(f\"Working Directory: {session_info.cwd}\")\nprint(f\"Terminal Size: {session_info.cols}x{session_info.rows}\")\n```\n\n#### AsyncProcess.kill\\_pty\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to kill PTY session: \")\n@with_instrumentation()\nasync def kill_pty_session(session_id: str) -> None\n```\n\nKills a PTY session and terminates its associated process.\n\nForcefully terminates the PTY session and cleans up all associated resources.\nThis will close any active connections and kill the underlying shell process.\nThis operation is irreversible. Any unsaved work in the terminal session will be lost.\n\n**Arguments**:\n\n- `session_id` - Unique identifier of the PTY session to kill.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session doesn't exist or cannot be killed.\n  \n\n**Example**:\n\n```python\n# Kill a specific PTY session\nawait sandbox.process.kill_pty_session(\"my-session\")\n\n# Verify the session no longer exists\npty_sessions = await sandbox.process.list_pty_sessions()\nfor pty_session in pty_sessions:\n    print(f\"PTY session: {pty_session.id}\")\n```\n\n#### AsyncProcess.resize\\_pty\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to resize PTY session: \")\n@with_instrumentation()\nasync def resize_pty_session(session_id: str,\n                             pty_size: PtySize) -> PtySessionInfo\n```\n\nResizes a PTY session's terminal dimensions.\n\nChanges the terminal size of an active PTY session. This is useful when the\nclient terminal is resized or when you need to adjust the display for different\noutput requirements.\n\n**Arguments**:\n\n- `session_id` - Unique identifier of the PTY session to resize.\n- `pty_size` - New terminal dimensions containing the desired columns and rows.\n  \n\n**Returns**:\n\n- `PtySessionInfo` - Updated session information reflecting the new terminal size.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session doesn't exist or resize operation fails.\n  \n\n**Example**:\n\n```python\nfrom daytona.common.pty import PtySize\n\n# Resize a PTY session to a larger terminal\nnew_size = PtySize(rows=40, cols=150)\nupdated_info = await sandbox.process.resize_pty_session(\"my-session\", new_size)\n\nprint(f\"Terminal resized to {updated_info.cols}x{updated_info.rows}\")\n\n# You can also use the AsyncPtyHandle's resize method\nawait pty_handle.resize(new_size)\n```\n\n\n## CodeRunParams\n\n```python\n@dataclass\nclass CodeRunParams()\n```\n\nParameters for code execution.\n\n**Attributes**:\n\n- `argv` _list[str] | None_ - Command line arguments\n- `env` _dict[str, str] | None_ - Environment variables\n\n## SessionExecuteRequest\n\n```python\nclass SessionExecuteRequest(ApiSessionExecuteRequest,\n                            AsyncApiSessionExecuteRequest)\n```\n\nContains the request for executing a command in a session.\n\n**Attributes**:\n\n- `command` _str_ - The command to execute.\n- `run_async` _bool | None_ - Whether to execute the command asynchronously.\n- `var_async` _bool | None_ - Deprecated. Use `run_async` instead.\n- `suppress_input_echo` _bool | None_ - Whether to suppress input echo. Default is `False`.\n\n## ExecutionArtifacts\n\n```python\n@dataclass\nclass ExecutionArtifacts()\n```\n\nArtifacts from the command execution.\n\n**Attributes**:\n\n- `stdout` _str_ - Standard output from the command, same as `result` in `ExecuteResponse`\n- `charts` _list[Chart] | None_ - List of chart metadata from matplotlib\n\n## ExecuteResponse\n\n```python\nclass ExecuteResponse(BaseModel)\n```\n\nResponse from the command execution.\n\n**Attributes**:\n\n- `exit_code` _int_ - The exit code from the command execution\n- `result` _str_ - The output from the command execution\n- `artifacts` _ExecutionArtifacts | None_ - Artifacts from the command execution\n\n## SessionExecuteResponse\n\n```python\nclass SessionExecuteResponse(ApiSessionExecuteResponse)\n```\n\nResponse from the session command execution.\n\n**Attributes**:\n\n- `cmd_id` _str_ - The ID of the executed command\n- `stdout` _str | None_ - The stdout from the command execution\n- `stderr` _str | None_ - The stderr from the command execution\n- `output` _str_ - The output from the command execution\n- `exit_code` _int_ - The exit code from the command execution\n\n## SessionCommandLogsResponse\n\n```python\n@dataclass\nclass SessionCommandLogsResponse()\n```\n\nResponse from the command logs.\n\n**Attributes**:\n\n- `output` _str | None_ - The combined output from the command\n- `stdout` _str | None_ - The stdout from the command\n- `stderr` _str | None_ - The stderr from the command\n\n#### parse\\_session\\_command\\_logs\n\n```python\ndef parse_session_command_logs(data: bytes) -> SessionCommandLogsResponse\n```\n\nParse combined stdout/stderr output into separate streams.\n\n**Arguments**:\n\n- `data` - Combined log bytes with STDOUT_PREFIX and STDERR_PREFIX markers\n  \n\n**Returns**:\n\n  SessionCommandLogsResponse with separated stdout and stderr\n\n#### demux\\_log\n\n```python\ndef demux_log(data: bytes) -> tuple[bytes, bytes]\n```\n\nDemultiplex combined stdout/stderr log data.\n\n**Arguments**:\n\n- `data` - Combined log bytes with STDOUT_PREFIX and STDERR_PREFIX markers\n  \n\n**Returns**:\n\n  Tuple of (stdout_bytes, stderr_bytes)\n\n##### OutputHandler\n\n```python\nOutputHandler = Union[\n    Callable[[T], None],\n    Callable[[T], Awaitable[None]],\n]\n```\n\nCallback type that accepts both sync and async handlers.\n\nBlocking synchronous operations inside handlers may cause WebSocket disconnections.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-sandbox.mdx",
    "content": "---\ntitle: \"AsyncSandbox\"\nhideTitleOnPage: true\n---\n\n## AsyncSandbox\n\n```python\nclass AsyncSandbox(SandboxDto)\n```\n\nRepresents a Daytona Sandbox.\n\n**Attributes**:\n\n- `fs` _AsyncFileSystem_ - File system operations interface.\n- `git` _AsyncGit_ - Git operations interface.\n- `process` _AsyncProcess_ - Process execution interface.\n- `computer_use` _AsyncComputerUse_ - Computer use operations interface for desktop automation.\n- `code_interpreter` _AsyncCodeInterpreter_ - Stateful interpreter interface for executing code.\n  Currently supports only Python. For other languages, use the `process.code_run` interface.\n- `id` _str_ - Unique identifier for the Sandbox.\n- `name` _str_ - Name of the Sandbox.\n- `organization_id` _str_ - Organization ID of the Sandbox.\n- `snapshot` _str_ - Daytona snapshot used to create the Sandbox.\n- `user` _str_ - OS user running in the Sandbox.\n- `env` _dict[str, str]_ - Environment variables set in the Sandbox.\n- `labels` _dict[str, str]_ - Custom labels attached to the Sandbox.\n- `public` _bool_ - Whether the Sandbox is publicly accessible.\n- `target` _str_ - Target location of the runner where the Sandbox runs.\n- `cpu` _int_ - Number of CPUs allocated to the Sandbox.\n- `gpu` _int_ - Number of GPUs allocated to the Sandbox.\n- `memory` _int_ - Amount of memory allocated to the Sandbox in GiB.\n- `disk` _int_ - Amount of disk space allocated to the Sandbox in GiB.\n- `state` _SandboxState_ - Current state of the Sandbox (e.g., \"started\", \"stopped\").\n- `error_reason` _str_ - Error message if Sandbox is in error state.\n- `recoverable` _bool_ - Whether the Sandbox error is recoverable.\n- `backup_state` _SandboxBackupStateEnum_ - Current state of Sandbox backup.\n- `backup_created_at` _str_ - When the backup was created.\n- `auto_stop_interval` _int_ - Auto-stop interval in minutes.\n- `auto_archive_interval` _int_ - Auto-archive interval in minutes.\n- `auto_delete_interval` _int_ - Auto-delete interval in minutes.\n- `volumes` _list[str]_ - Volumes attached to the Sandbox.\n- `build_info` _str_ - Build information for the Sandbox if it was created from dynamic build.\n- `created_at` _str_ - When the Sandbox was created.\n- `updated_at` _str_ - When the Sandbox was last updated.\n- `network_block_all` _bool_ - Whether to block all network access for the Sandbox.\n- `network_allow_list` _str_ - Comma-separated list of allowed CIDR network addresses for the Sandbox.\n\n#### AsyncSandbox.\\_\\_init\\_\\_\n\n```python\ndef __init__(sandbox_dto: SandboxDto, toolbox_api: ApiClient,\n             sandbox_api: SandboxApi, code_toolbox: SandboxCodeToolbox)\n```\n\nInitialize a new Sandbox instance.\n\n**Arguments**:\n\n- `sandbox_dto` _SandboxDto_ - The sandbox data from the API.\n- `toolbox_api` _ApiClient_ - API client for toolbox operations.\n- `sandbox_api` _SandboxApi_ - API client for Sandbox operations.\n- `code_toolbox` _SandboxCodeToolbox_ - Language-specific toolbox implementation.\n\n#### AsyncSandbox.refresh\\_data\n\n```python\n@intercept_errors(message_prefix=\"Failed to refresh sandbox data: \")\n@with_instrumentation()\nasync def refresh_data() -> None\n```\n\nRefreshes the Sandbox data from the API.\n\n**Example**:\n\n```python\nawait sandbox.refresh_data()\nprint(f\"Sandbox {sandbox.id}:\")\nprint(f\"State: {sandbox.state}\")\nprint(f\"Resources: {sandbox.cpu} CPU, {sandbox.memory} GiB RAM\")\n```\n\n#### AsyncSandbox.get\\_user\\_home\\_dir\n\n```python\n@intercept_errors(message_prefix=\"Failed to get user home directory: \")\n@with_instrumentation()\nasync def get_user_home_dir() -> str\n```\n\nGets the user's home directory path inside the Sandbox.\n\n**Returns**:\n\n- `str` - The absolute path to the user's home directory inside the Sandbox.\n  \n\n**Example**:\n\n```python\nuser_home_dir = await sandbox.get_user_home_dir()\nprint(f\"Sandbox user home: {user_home_dir}\")\n```\n\n#### AsyncSandbox.get\\_work\\_dir\n\n```python\n@intercept_errors(message_prefix=\"Failed to get working directory path: \")\n@with_instrumentation()\nasync def get_work_dir() -> str\n```\n\nGets the working directory path inside the Sandbox.\n\n**Returns**:\n\n- `str` - The absolute path to the Sandbox working directory. Uses the WORKDIR specified in\n  the Dockerfile if present, or falling back to the user's home directory if not.\n  \n\n**Example**:\n\n```python\nwork_dir = await sandbox.get_work_dir()\nprint(f\"Sandbox working directory: {work_dir}\")\n```\n\n#### AsyncSandbox.create\\_lsp\\_server\n\n```python\n@with_instrumentation()\ndef create_lsp_server(language_id: LspLanguageId | LspLanguageIdLiteral,\n                      path_to_project: str) -> AsyncLspServer\n```\n\nCreates a new Language Server Protocol (LSP) server instance.\n\nThe LSP server provides language-specific features like code completion,\ndiagnostics, and more.\n\n**Arguments**:\n\n- `language_id` _LspLanguageId | LspLanguageIdLiteral_ - The language server type (e.g., LspLanguageId.PYTHON).\n- `path_to_project` _str_ - Path to the project root directory. Relative paths are resolved\n  based on the sandbox working directory.\n  \n\n**Returns**:\n\n- `LspServer` - A new LSP server instance configured for the specified language.\n  \n\n**Example**:\n\n```python\nlsp = sandbox.create_lsp_server(\"python\", \"workspace/project\")\n```\n\n#### AsyncSandbox.set\\_labels\n\n```python\n@intercept_errors(message_prefix=\"Failed to set labels: \")\n@with_instrumentation()\nasync def set_labels(labels: dict[str, str]) -> dict[str, str]\n```\n\nSets labels for the Sandbox.\n\nLabels are key-value pairs that can be used to organize and identify Sandboxes.\n\n**Arguments**:\n\n- `labels` _dict[str, str]_ - Dictionary of key-value pairs representing Sandbox labels.\n  \n\n**Returns**:\n\n  dict[str, str]: Dictionary containing the updated Sandbox labels.\n  \n\n**Example**:\n\n```python\nnew_labels = sandbox.set_labels({\n    \"project\": \"my-project\",\n    \"environment\": \"development\",\n    \"team\": \"backend\"\n})\nprint(f\"Updated labels: {new_labels}\")\n```\n\n#### AsyncSandbox.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start sandbox: \")\n@with_timeout()\n@with_instrumentation()\nasync def start(timeout: float | None = 60)\n```\n\nStarts the Sandbox and waits for it to be ready.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative. If sandbox fails to start or times out.\n  \n\n**Example**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.start(timeout=40)  # Wait up to 40 seconds\nprint(\"Sandbox started successfully\")\n```\n\n#### AsyncSandbox.recover\n\n```python\n@intercept_errors(message_prefix=\"Failed to recover sandbox: \")\n@with_timeout()\nasync def recover(timeout: float | None = 60)\n```\n\nRecovers the Sandbox from a recoverable error and waits for it to be ready.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative. If sandbox fails to recover or times out.\n  \n\n**Example**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nawait sandbox.recover(timeout=40)  # Wait up to 40 seconds\nprint(\"Sandbox recovered successfully\")\n```\n\n#### AsyncSandbox.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop sandbox: \")\n@with_timeout()\n@with_instrumentation()\nasync def stop(timeout: float | None = 60)\n```\n\nStops the Sandbox and waits for it to be fully stopped.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative; If sandbox fails to stop or times out\n  \n\n**Example**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.stop()\nprint(\"Sandbox stopped successfully\")\n```\n\n#### AsyncSandbox.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to remove sandbox: \")\n@with_instrumentation()\nasync def delete(timeout: float | None = 60) -> None\n```\n\nDeletes the Sandbox.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Timeout (in seconds) for sandbox deletion. 0 means no timeout.\n  Default is 60 seconds.\n\n#### AsyncSandbox.wait\\_for\\_sandbox\\_start\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for sandbox to start: \")\n@with_timeout()\n@with_instrumentation()\nasync def wait_for_sandbox_start(timeout: float | None = 60) -> None\n```\n\nWaits for the Sandbox to reach the 'started' state. Polls the Sandbox status until it\nreaches the 'started' state, encounters an error or times out.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative; If Sandbox fails to start or times out\n\n#### AsyncSandbox.wait\\_for\\_sandbox\\_stop\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for sandbox to stop: \")\n@with_timeout()\n@with_instrumentation()\nasync def wait_for_sandbox_stop(timeout: float | None = 60) -> None\n```\n\nWaits for the Sandbox to reach the 'stopped' state. Polls the Sandbox status until it\nreaches the 'stopped' state, encounters an error or times out. It will wait up to 60 seconds\nfor the Sandbox to stop.\nTreats destroyed as stopped to cover ephemeral sandboxes that are automatically deleted after stopping.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative. If Sandbox fails to stop or times out.\n\n#### AsyncSandbox.set\\_autostop\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-stop interval: \")\n@with_instrumentation()\nasync def set_autostop_interval(interval: int) -> None\n```\n\nSets the auto-stop interval for the Sandbox.\n\nThe Sandbox will automatically stop after being idle (no new events) for the specified interval.\nEvents include any state changes or interactions with the Sandbox through the SDK.\nInteractions using Sandbox Previews are not included.\n\n**Arguments**:\n\n- `interval` _int_ - Number of minutes of inactivity before auto-stopping.\n  Set to 0 to disable auto-stop. Defaults to 15.\n  \n\n**Raises**:\n\n- `DaytonaError` - If interval is negative\n  \n\n**Example**:\n\n```python\n# Auto-stop after 1 hour\nsandbox.set_autostop_interval(60)\n# Or disable auto-stop\nsandbox.set_autostop_interval(0)\n```\n\n#### AsyncSandbox.set\\_auto\\_archive\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-archive interval: \")\n@with_instrumentation()\nasync def set_auto_archive_interval(interval: int) -> None\n```\n\nSets the auto-archive interval for the Sandbox.\n\nThe Sandbox will automatically archive after being continuously stopped for the specified interval.\n\n**Arguments**:\n\n- `interval` _int_ - Number of minutes after which a continuously stopped Sandbox will be auto-archived.\n  Set to 0 for the maximum interval. Default is 7 days.\n  \n\n**Raises**:\n\n- `DaytonaError` - If interval is negative\n  \n\n**Example**:\n\n```python\n# Auto-archive after 1 hour\nsandbox.set_auto_archive_interval(60)\n# Or use the maximum interval\nsandbox.set_auto_archive_interval(0)\n```\n\n#### AsyncSandbox.set\\_auto\\_delete\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-delete interval: \")\n@with_instrumentation()\nasync def set_auto_delete_interval(interval: int) -> None\n```\n\nSets the auto-delete interval for the Sandbox.\n\nThe Sandbox will automatically delete after being continuously stopped for the specified interval.\n\n**Arguments**:\n\n- `interval` _int_ - Number of minutes after which a continuously stopped Sandbox will be auto-deleted.\n  Set to negative value to disable auto-delete. Set to 0 to delete immediately upon stopping.\n  By default, auto-delete is disabled.\n  \n\n**Example**:\n\n```python\n# Auto-delete after 1 hour\nsandbox.set_auto_delete_interval(60)\n# Or delete immediately upon stopping\nsandbox.set_auto_delete_interval(0)\n# Or disable auto-delete\nsandbox.set_auto_delete_interval(-1)\n```\n\n#### AsyncSandbox.get\\_preview\\_link\n\n```python\n@intercept_errors(message_prefix=\"Failed to get preview link: \")\n@with_instrumentation()\nasync def get_preview_link(port: int) -> PortPreviewUrl\n```\n\nRetrieves the preview link for the sandbox at the specified port. If the port is closed,\nit will be opened automatically. For private sandboxes, a token is included to grant access\nto the URL.\n\n**Arguments**:\n\n- `port` _int_ - The port to open the preview link on.\n  \n\n**Returns**:\n\n- `PortPreviewUrl` - The response object for the preview link, which includes the `url`\n  and the `token` (to access private sandboxes).\n  \n\n**Example**:\n\n```python\npreview_link = sandbox.get_preview_link(3000)\nprint(f\"Preview URL: {preview_link.url}\")\nprint(f\"Token: {preview_link.token}\")\n```\n\n#### AsyncSandbox.create\\_signed\\_preview\\_url\n\n```python\n@intercept_errors(message_prefix=\"Failed to create signed preview url: \")\nasync def create_signed_preview_url(\n        port: int,\n        expires_in_seconds: int | None = None) -> SignedPortPreviewUrl\n```\n\nCreates a signed preview URL for the sandbox at the specified port.\n\n**Arguments**:\n\n- `port` _int_ - The port to open the preview link on.\n- `expires_in_seconds` _int | None_ - The number of seconds the signed preview\n  url will be valid for. Defaults to 60 seconds.\n  \n\n**Returns**:\n\n- `SignedPortPreviewUrl` - The response object for the signed preview url.\n\n#### AsyncSandbox.expire\\_signed\\_preview\\_url\n\n```python\n@intercept_errors(message_prefix=\"Failed to expire signed preview url: \")\nasync def expire_signed_preview_url(port: int, token: str) -> None\n```\n\nExpires a signed preview URL for the sandbox at the specified port.\n\n**Arguments**:\n\n- `port` _int_ - The port to expire the signed preview url on.\n- `token` _str_ - The token to expire the signed preview url on.\n\n#### AsyncSandbox.archive\n\n```python\n@intercept_errors(message_prefix=\"Failed to archive sandbox: \")\n@with_instrumentation()\nasync def archive() -> None\n```\n\nArchives the sandbox, making it inactive and preserving its state. When sandboxes are\narchived, the entire filesystem state is moved to cost-effective object storage, making it\npossible to keep sandboxes available for an extended period. The tradeoff between archived\nand stopped states is that starting an archived sandbox takes more time, depending on its size.\nSandbox must be stopped before archiving.\n\n#### AsyncSandbox.resize\n\n```python\n@intercept_errors(message_prefix=\"Failed to resize sandbox: \")\n@with_timeout()\n@with_instrumentation()\nasync def resize(resources: Resources, timeout: float | None = 60) -> None\n```\n\nResizes the Sandbox resources.\n\nChanges the CPU, memory, or disk allocation for the Sandbox. Hot resize (on running\nsandbox) only allows CPU/memory increases. Disk resize requires a stopped sandbox.\n\n**Arguments**:\n\n- `resources` _Resources_ - New resource configuration. Only specified fields will be updated.\n  - cpu: Number of CPU cores (minimum: 1). For hot resize, can only be increased.\n  - memory: Memory in GiB (minimum: 1). For hot resize, can only be increased.\n  - disk: Disk space in GiB (can only be increased, requires stopped sandbox).\n- `timeout` _Optional[float]_ - Timeout (in seconds) for the resize operation. 0 means no timeout.\n  Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If hot resize constraints are violated (CPU/memory decrease on running sandbox).\n- `DaytonaError` - If disk resize attempted on running sandbox.\n- `DaytonaError` - If disk size decrease is attempted.\n- `DaytonaError` - If resize operation times out.\n- `DaytonaError` - If no resource changes are specified.\n  \n\n**Example**:\n\n```python\n# Increase CPU/memory on running sandbox (hot resize)\nawait sandbox.resize(Resources(cpu=4, memory=8))\n\n# Change disk (sandbox must be stopped)\nawait sandbox.stop()\nawait sandbox.resize(Resources(cpu=2, memory=4, disk=30))\n```\n\n#### AsyncSandbox.wait\\_for\\_resize\\_complete\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for resize to complete: \")\n@with_timeout()\n@with_instrumentation()\nasync def wait_for_resize_complete(timeout: float | None = 60) -> None\n```\n\nWaits for the Sandbox resize operation to complete. Polls the Sandbox status until\nthe state is no longer 'resizing'.\n\n**Arguments**:\n\n- `timeout` _Optional[float]_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative. If resize operation times out.\n\n#### AsyncSandbox.create\\_ssh\\_access\n\n```python\n@intercept_errors(message_prefix=\"Failed to create SSH access: \")\n@with_instrumentation()\nasync def create_ssh_access(\n        expires_in_minutes: int | None = None) -> SshAccessDto\n```\n\nCreates an SSH access token for the sandbox.\n\n**Arguments**:\n\n- `expires_in_minutes` _int | None_ - The number of minutes the SSH access token will be valid for.\n\n#### AsyncSandbox.revoke\\_ssh\\_access\n\n```python\n@intercept_errors(message_prefix=\"Failed to revoke SSH access: \")\n@with_instrumentation()\nasync def revoke_ssh_access(token: str) -> None\n```\n\nRevokes an SSH access token for the sandbox.\n\n**Arguments**:\n\n- `token` _str_ - The token to revoke.\n\n#### AsyncSandbox.validate\\_ssh\\_access\n\n```python\n@intercept_errors(message_prefix=\"Failed to validate SSH access: \")\n@with_instrumentation()\nasync def validate_ssh_access(token: str) -> SshAccessValidationDto\n```\n\nValidates an SSH access token for the sandbox.\n\n**Arguments**:\n\n- `token` _str_ - The token to validate.\n\n#### AsyncSandbox.refresh\\_activity\n\n```python\n@intercept_errors(message_prefix=\"Failed to refresh sandbox activity: \")\nasync def refresh_activity() -> None\n```\n\nRefreshes the sandbox activity to reset the timer for automated lifecycle management actions.\n\nThis method updates the sandbox's last activity timestamp without changing its state.\nIt is useful for keeping long-running sessions alive while there is still user activity.\n\n**Example**:\n\n```python\nawait sandbox.refresh_activity()\n```\n\n\n## AsyncPaginatedSandboxes\n\n```python\nclass AsyncPaginatedSandboxes(PaginatedSandboxesDto)\n```\n\nRepresents a paginated list of Daytona Sandboxes.\n\n**Attributes**:\n\n- `items` _list[AsyncSandbox]_ - List of Sandbox instances in the current page.\n- `total` _int_ - Total number of Sandboxes across all pages.\n- `page` _int_ - Current page number.\n- `total_pages` _int_ - Total number of pages available.\n\n##### items: `list[AsyncSandbox]`\n\n```python\nitems = None\n```\n\npyright: ignore[reportIncompatibleVariableOverride]\n\n## Resources\n\n```python\n@dataclass\nclass Resources()\n```\n\nResources configuration for Sandbox.\n\n**Attributes**:\n\n- `cpu` _int | None_ - Number of CPU cores to allocate.\n- `memory` _int | None_ - Amount of memory in GiB to allocate.\n- `disk` _int | None_ - Amount of disk space in GiB to allocate.\n- `gpu` _int | None_ - Number of GPUs to allocate.\n  \n\n**Example**:\n\n```python\nresources = Resources(\n    cpu=2,\n    memory=4,  # 4GiB RAM\n    disk=20,   # 20GiB disk\n    gpu=1\n)\nparams = CreateSandboxFromImageParams(\n    image=Image.debian_slim(\"3.12\"),\n    language=\"python\",\n    resources=resources\n)\n```\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-snapshot.mdx",
    "content": "---\ntitle: \"AsyncSnapshot\"\nhideTitleOnPage: true\n---\n\n## Snapshot\n\n```python\nclass Snapshot(SyncSnapshotDto)\n```\n\nRepresents a Daytona Snapshot which is a pre-configured sandbox.\n\n**Attributes**:\n\n- `id` _str_ - Unique identifier for the Snapshot.\n- `organization_id` _str | None_ - Organization ID of the Snapshot.\n- `general` _bool_ - Whether the Snapshot is general.\n- `name` _str_ - Name of the Snapshot.\n- `image_name` _str_ - Name of the Image of the Snapshot.\n- `state` _str_ - State of the Snapshot.\n- `size` _float | int | None_ - Size of the Snapshot.\n- `entrypoint` _list[str] | None_ - Entrypoint of the Snapshot.\n- `cpu` _float | int_ - CPU of the Snapshot.\n- `gpu` _float | int_ - GPU of the Snapshot.\n- `mem` _float | int_ - Memory of the Snapshot in GiB.\n- `disk` _float | int_ - Disk of the Snapshot in GiB.\n- `error_reason` _str | None_ - Error reason of the Snapshot.\n- `created_at` _str_ - Timestamp when the Snapshot was created.\n- `updated_at` _str_ - Timestamp when the Snapshot was last updated.\n- `last_used_at` _str_ - Timestamp when the Snapshot was last used.\n\n\n## AsyncSnapshotService\n\n```python\nclass AsyncSnapshotService()\n```\n\nService for managing Daytona Snapshots. Can be used to list, get, create and delete Snapshots.\n\n#### AsyncSnapshotService.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list snapshots: \")\n@with_instrumentation()\nasync def list(page: int | None = None,\n               limit: int | None = None) -> PaginatedSnapshots\n```\n\nReturns paginated list of Snapshots.\n\n**Arguments**:\n\n- `page` _int | None_ - Page number for pagination (starting from 1).\n- `limit` _int | None_ - Maximum number of items per page.\n  \n\n**Returns**:\n\n- `PaginatedSnapshots` - Paginated list of Snapshots.\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    result = await daytona.snapshot.list(page=2, limit=10)\n    for snapshot in result.items:\n        print(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n#### AsyncSnapshotService.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete snapshot: \")\n@with_instrumentation()\nasync def delete(snapshot: Snapshot) -> None\n```\n\nDelete a Snapshot.\n\n**Arguments**:\n\n- `snapshot` _Snapshot_ - Snapshot to delete.\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    snapshot = await daytona.snapshot.get(\"test-snapshot\")\n    await daytona.snapshot.delete(snapshot)\n    print(\"Snapshot deleted\")\n```\n\n#### AsyncSnapshotService.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get snapshot: \")\n@with_instrumentation()\nasync def get(name: str) -> Snapshot\n```\n\nGet a Snapshot by name.\n\n**Arguments**:\n\n- `name` _str_ - Name of the Snapshot to get.\n  \n\n**Returns**:\n\n- `Snapshot` - The Snapshot object.\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    snapshot = await daytona.snapshot.get(\"test-snapshot-name\")\n    print(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n#### AsyncSnapshotService.create\n\n```python\n@intercept_errors(message_prefix=\"Failed to create snapshot: \")\n@with_timeout()\n@with_instrumentation()\nasync def create(params: CreateSnapshotParams,\n                 *,\n                 on_logs: Callable[[str], None] | None = None,\n                 timeout: float | None = 0) -> Snapshot\n```\n\nCreates and registers a new snapshot from the given Image definition.\n\n**Arguments**:\n\n- `params` _CreateSnapshotParams_ - Parameters for snapshot creation.\n- `on_logs` _Callable[[str], None]_ - This callback function handles snapshot creation logs.\n- `timeout` _float | None_ - Default is no timeout. Timeout in seconds (0 means no timeout).\n\n**Example**:\n\n```python\nimage = Image.debianSlim('3.12').pipInstall('numpy')\ndaytona.snapshot.create(\n    CreateSnapshotParams(name='my-snapshot', image=image),\n    on_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n#### AsyncSnapshotService.activate\n\n```python\n@with_instrumentation()\nasync def activate(snapshot: Snapshot) -> Snapshot\n```\n\nActivate a snapshot.\n\n**Arguments**:\n\n- `snapshot` _Snapshot_ - The Snapshot instance.\n\n**Returns**:\n\n- `Snapshot` - The activated Snapshot instance.\n\n#### AsyncSnapshotService.process\\_image\\_context\n\n```python\n@staticmethod\n@with_instrumentation()\nasync def process_image_context(object_storage_api: ObjectStorageApi,\n                                image: Image) -> list[str]\n```\n\nProcesses the image context by uploading it to object storage.\n\n**Arguments**:\n\n- `image` _Image_ - The Image instance.\n\n**Returns**:\n\n- `List[str]` - List of context hashes stored in object storage.\n\n## PaginatedSnapshots\n\n```python\nclass PaginatedSnapshots(PaginatedSnapshotsDto)\n```\n\nRepresents a paginated list of Daytona Snapshots.\n\n**Attributes**:\n\n- `items` _list[Snapshot]_ - List of Snapshot instances in the current page.\n- `total` _int_ - Total number of Snapshots across all pages.\n- `page` _int_ - Current page number.\n- `total_pages` _int_ - Total number of pages available.\n\n## CreateSnapshotParams\n\n```python\nclass CreateSnapshotParams(BaseModel)\n```\n\nParameters for creating a new snapshot.\n\n**Attributes**:\n\n- `name` _str_ - Name of the snapshot.\n- `image` _str | Image_ - Image of the snapshot. If a string is provided,\n  it should be available on some registry. If an Image instance is provided,\n  it will be used to create a new image in Daytona.\n- `resources` _Resources | None_ - Resources of the snapshot.\n- `entrypoint` _list[str] | None_ - Entrypoint of the snapshot.\n- `region_id` _str | None_ - ID of the region where the snapshot will be available.\n  Defaults to organization default region if not specified.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/async/async-volume.mdx",
    "content": "---\ntitle: \"AsyncVolume\"\nhideTitleOnPage: true\n---\n\n## Volume\n\n```python\nclass Volume(VolumeDto)\n```\n\nRepresents a Daytona Volume which is a shared storage volume for Sandboxes.\n\n**Attributes**:\n\n- `id` _str_ - Unique identifier for the Volume.\n- `name` _str_ - Name of the Volume.\n- `organization_id` _str_ - Organization ID of the Volume.\n- `state` _str_ - State of the Volume.\n- `created_at` _str_ - Date and time when the Volume was created.\n- `updated_at` _str_ - Date and time when the Volume was last updated.\n- `last_used_at` _str_ - Date and time when the Volume was last used.\n\n\n## AsyncVolumeService\n\n```python\nclass AsyncVolumeService()\n```\n\nService for managing Daytona Volumes. Can be used to list, get, create and delete Volumes.\n\n#### AsyncVolumeService.list\n\n```python\nasync def list() -> list[Volume]\n```\n\nList all Volumes.\n\n**Returns**:\n\n- `list[Volume]` - List of all Volumes.\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    volumes = await daytona.volume.list()\n    for volume in volumes:\n        print(f\"{volume.name} ({volume.id})\")\n```\n\n#### AsyncVolumeService.get\n\n```python\n@with_instrumentation()\nasync def get(name: str, create: bool = False) -> Volume\n```\n\nGet a Volume by name.\n\n**Arguments**:\n\n- `name` _str_ - Name of the Volume to get.\n- `create` _bool_ - If True, create a new Volume if it doesn't exist.\n  \n\n**Returns**:\n\n- `Volume` - The Volume object.\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    volume = await daytona.volume.get(\"test-volume-name\", create=True)\n    print(f\"{volume.name} ({volume.id})\")\n```\n\n#### AsyncVolumeService.create\n\n```python\n@with_instrumentation()\nasync def create(name: str) -> Volume\n```\n\nCreate a new Volume.\n\n**Arguments**:\n\n- `name` _str_ - Name of the Volume to create.\n  \n\n**Returns**:\n\n- `Volume` - The Volume object.\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    volume = await daytona.volume.create(\"test-volume\")\n    print(f\"{volume.name} ({volume.id}); state: {volume.state}\")\n```\n\n#### AsyncVolumeService.delete\n\n```python\n@with_instrumentation()\nasync def delete(volume: Volume) -> None\n```\n\nDelete a Volume.\n\n**Arguments**:\n\n- `volume` _Volume_ - Volume to delete.\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    volume = await daytona.volume.get(\"test-volume\")\n    await daytona.volume.delete(volume)\n    print(\"Volume deleted\")\n```\n\n## VolumeMount\n\n```python\nclass VolumeMount(ApiVolumeMount, AsyncApiVolumeMount)\n```\n\nRepresents a Volume mount configuration for a Sandbox.\n\n**Attributes**:\n\n- `volume_id` _str_ - ID of the volume to mount.\n- `mount_path` _str_ - Path where the volume will be mounted in the sandbox.\n- `subpath` _str | None_ - Optional S3 subpath/prefix within the volume to mount.\n  When specified, only this prefix will be accessible. When omitted,\n  the entire volume is mounted.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/common/charts.mdx",
    "content": "---\ntitle: \"Charts\"\nhideTitleOnPage: true\n---\n\n## Chart\n\n```python\nclass Chart(BaseModel)\n```\n\nRepresents a chart with metadata from matplotlib.\n\n**Attributes**:\n\n- `type` _ChartType_ - The type of chart\n- `title` _str_ - The title of the chart\n- `elements` _list[Any]_ - The elements of the chart\n- `png` _str | None_ - The PNG representation of the chart encoded in base64\n\n#### Chart.to\\_dict\n\n```python\ndef to_dict() -> dict[str, Any]\n```\n\nReturn the metadata dictionary used to create the chart.\n\n\n## ChartType\n\n```python\nclass ChartType(str, Enum)\n```\n\nChart types\n\n**Enum Members**:\n    - `LINE` (\"line\")\n    - `SCATTER` (\"scatter\")\n    - `BAR` (\"bar\")\n    - `PIE` (\"pie\")\n    - `BOX_AND_WHISKER` (\"box_and_whisker\")\n    - `COMPOSITE_CHART` (\"composite_chart\")\n    - `UNKNOWN` (\"unknown\")\n\n## Chart2D\n\n```python\nclass Chart2D(Chart)\n```\n\nRepresents a 2D chart with metadata.\n\n**Attributes**:\n\n- `x_label` _str | None_ - The label of the x-axis\n- `y_label` _str | None_ - The label of the y-axis\n\n## PointData\n\n```python\nclass PointData(BaseModel)\n```\n\nRepresents a point in a 2D chart.\n\n**Attributes**:\n\n- `label` _str_ - The label of the point\n- `points` _list[tuple[str | float, str | float]]_ - The points of the chart\n\n## PointChart\n\n```python\nclass PointChart(Chart2D)\n```\n\nRepresents a point chart with metadata.\n\n**Attributes**:\n\n- `x_ticks` _list[str | float]_ - The ticks of the x-axis\n- `x_tick_labels` _list[str]_ - The labels of the x-axis\n- `x_scale` _str_ - The scale of the x-axis\n- `y_ticks` _list[str | float]_ - The ticks of the y-axis\n- `y_tick_labels` _list[str]_ - The labels of the y-axis\n- `y_scale` _str_ - The scale of the y-axis\n- `elements` _list[PointData]_ - The points of the chart\n\n## LineChart\n\n```python\nclass LineChart(PointChart)\n```\n\nRepresents a line chart with metadata.\n\n**Attributes**:\n\n- `type` _ChartType_ - The type of chart\n\n## ScatterChart\n\n```python\nclass ScatterChart(PointChart)\n```\n\nRepresents a scatter chart with metadata.\n\n**Attributes**:\n\n- `type` _ChartType_ - The type of chart\n\n## BarData\n\n```python\nclass BarData(BaseModel)\n```\n\nRepresents a bar in a bar chart.\n\n**Attributes**:\n\n- `label` _str_ - The label of the bar\n- `group` _str_ - The group of the bar\n- `value` _str_ - The value of the bar\n\n## BarChart\n\n```python\nclass BarChart(Chart2D)\n```\n\nRepresents a bar chart with metadata.\n\n**Attributes**:\n\n- `type` _ChartType_ - The type of chart\n- `elements` _list[BarData]_ - The bars of the chart\n\n## PieData\n\n```python\nclass PieData(BaseModel)\n```\n\nRepresents a pie slice in a pie chart.\n\n**Attributes**:\n\n- `label` _str_ - The label of the pie slice\n- `angle` _float_ - The angle of the pie slice\n- `radius` _float_ - The radius of the pie slice\n- `autopct` _str | float_ - The autopct value of the pie slice\n\n## PieChart\n\n```python\nclass PieChart(Chart)\n```\n\nRepresents a pie chart with metadata.\n\n**Attributes**:\n\n- `type` _ChartType_ - The type of chart\n- `elements` _list[PieData]_ - The pie slices of the chart\n\n## BoxAndWhiskerData\n\n```python\nclass BoxAndWhiskerData(BaseModel)\n```\n\nRepresents a box and whisker in a box and whisker chart.\n\n**Attributes**:\n\n- `label` _str_ - The label of the box and whisker\n- `min` _float_ - The minimum value of the box and whisker\n- `first_quartile` _float_ - The first quartile of the box and whisker\n- `median` _float_ - The median of the box and whisker\n- `third_quartile` _float_ - The third quartile of the box and whisker\n- `max` _float_ - The maximum value of the box and whisker\n- `outliers` _list[float]_ - The outliers of the box and whisker\n\n## BoxAndWhiskerChart\n\n```python\nclass BoxAndWhiskerChart(Chart2D)\n```\n\nRepresents a box and whisker chart with metadata.\n\n**Attributes**:\n\n- `type` _ChartType_ - The type of chart\n- `elements` _list[BoxAndWhiskerData]_ - The box and whiskers of the chart\n\n## CompositeChart\n\n```python\nclass CompositeChart(Chart)\n```\n\nRepresents a composite chart with metadata. A composite chart is a chart\nthat contains multiple charts (subplots).\n\n**Attributes**:\n\n- `type` _ChartType_ - The type of chart\n- `elements` _list[Chart]_ - The charts (subplots) of the composite chart\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/common/errors.mdx",
    "content": "---\ntitle: \"Errors\"\nhideTitleOnPage: true\n---\n\n## DaytonaError\n\n```python\nclass DaytonaError(Exception)\n```\n\nBase error for Daytona SDK.\n\n**Attributes**:\n\n- `message` _str_ - Error message\n- `status_code` _int | None_ - HTTP status code if available\n- `headers` _dict[str, Any]_ - Response headers\n\n#### DaytonaError.\\_\\_init\\_\\_\n\n```python\ndef __init__(message: str,\n             status_code: int | None = None,\n             headers: Mapping[str, Any] | None = None)\n```\n\nInitialize Daytona error.\n\n**Arguments**:\n\n- `message` _str_ - Error message\n- `status_code` _int | None_ - HTTP status code if available\n- `headers` _Mapping[str, Any] | None_ - Response headers if available\n\n\n## DaytonaNotFoundError\n\n```python\nclass DaytonaNotFoundError(DaytonaError)\n```\n\nError for when a resource is not found.\n\n## DaytonaRateLimitError\n\n```python\nclass DaytonaRateLimitError(DaytonaError)\n```\n\nError for when rate limit is exceeded.\n\n## DaytonaTimeoutError\n\n```python\nclass DaytonaTimeoutError(DaytonaError)\n```\n\nError for when a timeout occurs.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/common/image.mdx",
    "content": "---\ntitle: \"Image\"\nhideTitleOnPage: true\n---\n\n## Image\n\n```python\nclass Image(BaseModel)\n```\n\nRepresents an image definition for a Daytona sandbox.\nDo not construct this class directly. Instead use one of its static factory methods,\nsuch as `Image.base()`, `Image.debian_slim()`, or `Image.from_dockerfile()`.\n\n#### Image.dockerfile\n\n```python\ndef dockerfile() -> str\n```\n\nReturns a generated Dockerfile for the image.\n\n#### Image.pip\\_install\n\n```python\ndef pip_install(*packages: str | list[str],\n                find_links: list[str] | None = None,\n                index_url: str | None = None,\n                extra_index_urls: list[str] | None = None,\n                pre: bool = False,\n                extra_options: str = \"\") -> \"Image\"\n```\n\nAdds commands to install packages using pip.\n\n**Arguments**:\n\n- `*packages` - The packages to install.\n- `find_links` - list[str] | None: The find-links to use.\n- `index_url` - str | None: The index URL to use.\n- `extra_index_urls` - list[str] | None: The extra index URLs to use.\n- `pre` - bool = False: Whether to install pre-release packages.\n- `extra_options` - str = \"\": Additional options to pass to pip. Given string is passed\n  directly to the pip install command.\n  \n\n**Returns**:\n\n- `Image` - The image with the pip install commands added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").pip_install(\"requests\", \"pandas\")\n```\n\n#### Image.pip\\_install\\_from\\_requirements\n\n```python\ndef pip_install_from_requirements(requirements_txt: str,\n                                  find_links: list[str] | None = None,\n                                  index_url: str | None = None,\n                                  extra_index_urls: list[str] | None = None,\n                                  pre: bool = False,\n                                  extra_options: str = \"\") -> \"Image\"\n```\n\nInstalls dependencies from a requirements.txt file.\n\n**Arguments**:\n\n- `requirements_txt` - str: The path to the requirements.txt file.\n- `find_links` - list[str] | None: The find-links to use.\n- `index_url` - str | None: The index URL to use.\n- `extra_index_urls` - list[str] | None: The extra index URLs to use.\n- `pre` - bool = False: Whether to install pre-release packages.\n- `extra_options` - str = \"\": Additional options to pass to pip.\n  \n\n**Returns**:\n\n- `Image` - The image with the pip install commands added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").pip_install_from_requirements(\"requirements.txt\")\n```\n\n#### Image.pip\\_install\\_from\\_pyproject\n\n```python\ndef pip_install_from_pyproject(pyproject_toml: str,\n                               optional_dependencies: list[str],\n                               find_links: str | None = None,\n                               index_url: str | None = None,\n                               extra_index_url: str | None = None,\n                               pre: bool = False,\n                               extra_options: str = \"\") -> \"Image\"\n```\n\nInstalls dependencies from a pyproject.toml file.\n\n**Arguments**:\n\n- `pyproject_toml` - str: The path to the pyproject.toml file.\n- `optional_dependencies` - list[str] = []: The optional dependencies to install from the pyproject.toml file.\n- `find_links` - str | None = None: The find-links to use.\n- `index_url` - str | None = None: The index URL to use.\n- `extra_index_url` - str | None = None: The extra index URL to use.\n- `pre` - bool = False: Whether to install pre-release packages.\n- `extra_options` - str = \"\": Additional options to pass to pip. Given string is passed\n  directly to the pip install command.\n  \n\n**Returns**:\n\n- `Image` - The image with the pip install commands added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\")                 .pip_install_from_pyproject(\"pyproject.toml\", optional_dependencies=[\"dev\"])\n```\n\n#### Image.add\\_local\\_file\n\n```python\ndef add_local_file(local_path: str | Path, remote_path: str) -> \"Image\"\n```\n\nAdds a local file to the image.\n\n**Arguments**:\n\n- `local_path` - str | Path: The path to the local file.\n- `remote_path` - str: The path to the file in the image.\n  \n\n**Returns**:\n\n- `Image` - The image with the local file added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").add_local_file(\"package.json\", \"/home/daytona/package.json\")\n```\n\n#### Image.add\\_local\\_dir\n\n```python\ndef add_local_dir(local_path: str | Path, remote_path: str) -> \"Image\"\n```\n\nAdds a local directory to the image.\n\n**Arguments**:\n\n- `local_path` - str | Path: The path to the local directory.\n- `remote_path` - str: The path to the directory in the image.\n  \n\n**Returns**:\n\n- `Image` - The image with the local directory added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").add_local_dir(\"src\", \"/home/daytona/src\")\n```\n\n#### Image.run\\_commands\n\n```python\ndef run_commands(*commands: str | list[str]) -> \"Image\"\n```\n\nRuns commands in the image.\n\n**Arguments**:\n\n- `*commands` - The commands to run.\n  \n\n**Returns**:\n\n- `Image` - The image with the commands added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").run_commands(\n    'echo \"Hello, world!\"',\n    ['bash', '-c', 'echo Hello, world, again!']\n)\n```\n\n#### Image.env\n\n```python\ndef env(env_vars: dict[str, str]) -> \"Image\"\n```\n\nSets environment variables in the image.\n\n**Arguments**:\n\n- `env_vars` - dict[str, str]: The environment variables to set.\n  \n\n**Returns**:\n\n- `Image` - The image with the environment variables added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").env({\"PROJECT_ROOT\": \"/home/daytona\"})\n```\n\n#### Image.workdir\n\n```python\ndef workdir(path: str | Path) -> \"Image\"\n```\n\nSets the working directory in the image.\n\n**Arguments**:\n\n- `path` - str | Path: The path to the working directory.\n  \n\n**Returns**:\n\n- `Image` - The image with the working directory added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").workdir(\"/home/daytona\")\n```\n\n#### Image.entrypoint\n\n```python\ndef entrypoint(entrypoint_commands: list[str]) -> \"Image\"\n```\n\nSets the entrypoint for the image.\n\n**Arguments**:\n\n- `entrypoint_commands` - list[str]: The commands to set as the entrypoint.\n  \n\n**Returns**:\n\n- `Image` - The image with the entrypoint added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").entrypoint([\"/bin/bash\"])\n```\n\n#### Image.cmd\n\n```python\ndef cmd(cmd: list[str]) -> \"Image\"\n```\n\nSets the default command for the image.\n\n**Arguments**:\n\n- `cmd` - list[str]: The commands to set as the default command.\n  \n\n**Returns**:\n\n- `Image` - The image with the default command added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").cmd([\"/bin/bash\"])\n```\n\n#### Image.dockerfile\\_commands\n\n```python\ndef dockerfile_commands(dockerfile_commands: list[str],\n                        context_dir: Path | str | None = None) -> \"Image\"\n```\n\nAdds arbitrary Dockerfile-like commands to the image.\n\n**Arguments**:\n\n- `*dockerfile_commands` - The commands to add to the Dockerfile.\n- `context_dir` - Path | str | None: The path to the context directory.\n  \n\n**Returns**:\n\n- `Image` - The image with the Dockerfile commands added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\").dockerfile_commands([\"RUN echo 'Hello, world!'\"])\n```\n\n#### Image.from\\_dockerfile\n\n```python\n@staticmethod\ndef from_dockerfile(path: str | Path) -> \"Image\"\n```\n\nCreates an Image from an existing Dockerfile.\n\n**Arguments**:\n\n- `path` - str | Path: The path to the Dockerfile.\n  \n\n**Returns**:\n\n- `Image` - The image with the Dockerfile added.\n  \n\n**Example**:\n\n```python\nimage = Image.from_dockerfile(\"Dockerfile\")\n```\n\n#### Image.base\n\n```python\n@staticmethod\ndef base(image: str) -> \"Image\"\n```\n\nCreates an Image from an existing base image.\n\n**Arguments**:\n\n- `image` - str: The base image to use.\n  \n\n**Returns**:\n\n- `Image` - The image with the base image added.\n  \n\n**Example**:\n\n```python\nimage = Image.base(\"python:3.12-slim-bookworm\")\n```\n\n#### Image.debian\\_slim\n\n```python\n@staticmethod\ndef debian_slim(\n        python_version: SupportedPythonSeries | None = None) -> \"Image\"\n```\n\nCreates a Debian slim image based on the official Python Docker image.\n\n**Arguments**:\n\n- `python_version` - SupportedPythonSeries | None: The Python version to use.\n  \n\n**Returns**:\n\n- `Image` - The image with the Debian slim image added.\n  \n\n**Example**:\n\n```python\nimage = Image.debian_slim(\"3.12\")\n```\n\n\n## Context\n\n```python\nclass Context(BaseModel)\n```\n\nContext for an image.\n\n**Attributes**:\n\n- `source_path` _str_ - The path to the source file or directory.\n- `archive_path` _str | None_ - The path inside the archive file in object storage.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/index.mdx",
    "content": "---\ntitle: Python SDK Reference\ndescription: Interact with Daytona Sandboxes using the Python SDK\nnext: /docs/python-sdk/daytona\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nThe Daytona Python SDK provides a robust interface for programmatically interacting with Daytona Sandboxes.\n\n## Installation\n\nInstall the Daytona Python SDK using pip:\n\n```bash\npip install daytona\n```\n\nOr using poetry:\n\n```bash\npoetry add daytona\n```\n\n## Getting Started\n\n### Create a Sandbox\n\nCreate a Daytona Sandbox to run your code securely in an isolated environment. The following snippet is an example \"Hello World\" program that runs securely inside a Daytona Sandbox.\n\n<Tabs>\n  <TabItem label=\"Sync\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona\n\n    def main():\n        # Initialize the SDK (uses environment variables by default)\n        daytona = Daytona()\n\n        # Create a new sandbox\n        sandbox = daytona.create()\n\n        # Execute a command\n        response = sandbox.process.exec(\"echo 'Hello, World!'\")\n        print(response.result)\n\n    if __name__ == \"__main__\":\n        main()\n    ```\n  </TabItem>\n\n  <TabItem label=\"Async\" icon=\"seti:python\">\n    ```python\n    import asyncio\n    from daytona import AsyncDaytona\n\n    async def main():\n        # Initialize the SDK (uses environment variables by default)\n        async with AsyncDaytona() as daytona:\n            # Create a new sandbox\n            sandbox = await daytona.create()\n\n            # Execute a command\n            response = await sandbox.process.exec(\"echo 'Hello, World!'\")\n            print(response.result)\n\n    if __name__ == \"__main__\":\n        asyncio.run(main())\n    ```\n  </TabItem>\n</Tabs>\n\n## Configuration\n\nThe Daytona SDK can be configured using environment variables or by passing options to the constructor:\n\n<Tabs>\n  <TabItem label=\"Sync\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, DaytonaConfig\n\n    # Using environment variables (DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET)\n    daytona = Daytona()\n\n    # Using explicit configuration\n    config = DaytonaConfig(\n        api_key=\"YOUR_API_KEY\",\n        api_url=\"https://app.daytona.io/api\",\n        target=\"us\"\n    )\n    daytona = Daytona(config)\n    ```\n  </TabItem>\n\n  <TabItem label=\"Async\" icon=\"seti:python\">\n    ```python\n    import asyncio\n    from daytona import AsyncDaytona, DaytonaConfig\n\n    async def main():\n        try:\n            # Using environment variables (DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET)\n            daytona = AsyncDaytona()\n            # Your async code here\n            pass\n        finally:\n            await daytona.close()\n\n        # Using explicit configuration\n        config = DaytonaConfig(\n            api_key=\"YOUR_API_KEY\",\n            api_url=\"https://app.daytona.io/api\",\n            target=\"us\"\n        )\n        async with AsyncDaytona(config) as daytona:\n            # Your code here\n            pass\n\n    if __name__ == \"__main__\":\n        asyncio.run(main())\n    ```\n  </TabItem>\n</Tabs>\n\nFor more information on configuring the Daytona SDK, see [configuration](/docs/en/configuration).\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/code-interpreter.mdx",
    "content": "---\ntitle: \"CodeInterpreter\"\nhideTitleOnPage: true\n---\n\n## CodeInterpreter\n\n```python\nclass CodeInterpreter()\n```\n\nHandles code interpretation and execution within a Sandbox. Currently supports only Python.\n\nThis class provides methods to execute code in isolated interpreter contexts,\nmanage contexts, and stream execution output via callbacks. If subsequent code executions\nare performed in the same context, the variables, imports, and functions defined in\nthe previous execution will be available.\n\nFor other languages, use the `code_run` method from the `Process` interface,\nor execute the appropriate command directly in the sandbox terminal.\n\n#### CodeInterpreter.\\_\\_init\\_\\_\n\n```python\ndef __init__(api_client: InterpreterApi)\n```\n\nInitialize a new CodeInterpreter instance.\n\n**Arguments**:\n\n- `api_client` - API client for interpreter operations.\n\n#### CodeInterpreter.run\\_code\n\n```python\n@intercept_errors(message_prefix=\"Failed to run code: \")\ndef run_code(code: str,\n             *,\n             context: InterpreterContext | None = None,\n             on_stdout: OutputHandler[OutputMessage] | None = None,\n             on_stderr: OutputHandler[OutputMessage] | None = None,\n             on_error: OutputHandler[ExecutionError] | None = None,\n             envs: dict[str, str] | None = None,\n             timeout: int | None = None) -> ExecutionResult\n```\n\nExecute Python code in the sandbox.\n\nBy default, code runs in the default shared context which persists variables,\nimports, and functions across executions. To run in an isolated context,\ncreate a new context with `create_context()` and pass it as `context` argument.\n\n**Arguments**:\n\n- `code` _str_ - Code to execute.\n- `context` _InterpreterContext | None_ - Context to run code in. If not provided, uses default context.\n- `on_stdout` _OutputHandler[OutputMessage] | None_ - Callback for stdout messages.\n- `on_stderr` _OutputHandler[OutputMessage] | None_ - Callback for stderr messages.\n- `on_error` _OutputHandler[ExecutionError] | None_ - Callback for execution errors\n  (e.g., syntax errors, runtime errors).\n- `envs` _dict[str, str] | None_ - Environment variables for this execution.\n- `timeout` _int | None_ - Timeout in seconds. 0 means no timeout. Default is 10 minutes.\n  \n\n**Returns**:\n\n- `ExecutionResult` - Result object containing stdout, stderr and error if any.\n  \n\n**Raises**:\n\n- `DaytonaTimeoutError` - If execution times out.\n- `DaytonaError` - If execution fails due to communication or other SDK errors.\n  \n\n**Examples**:\n\n```python\ndef handle_stdout(msg: OutputMessage):\n    print(f\"STDOUT: {msg.output}\", end=\"\")\n\ndef handle_stderr(msg: OutputMessage):\n    print(f\"STDERR: {msg.output}\", end=\"\")\n\ndef handle_error(err: ExecutionError):\n    print(f\"ERROR: {err.name}: {err.value}\")\n\ncode = '''\nimport sys\nimport time\nfor i in range(5):\n    print(i)\n    time.sleep(1)\nsys.stderr.write(\"Counting done!\")\n'''\nresult = sandbox.code_interpreter.run_code(\n    code=code,\n    on_stdout=handle_stdout,\n    on_stderr=handle_stderr,\n    on_error=handle_error,\n    timeout=10\n)\n```\n\n#### CodeInterpreter.create\\_context\n\n```python\n@intercept_errors(message_prefix=\"Failed to create interpreter context: \")\ndef create_context(cwd: str | None = None) -> InterpreterContext\n```\n\nCreate a new isolated interpreter context.\n\nContexts provide isolated execution environments with their own global namespace.\nVariables, imports, and functions defined in one context don't affect others.\n\n**Arguments**:\n\n- `cwd` _str | None_ - Working directory for the context. If not specified, uses sandbox working directory.\n  \n\n**Returns**:\n\n- `InterpreterContext` - The created context with its ID and metadata.\n  \n\n**Raises**:\n\n- `DaytonaError` - If context creation fails.\n  \n\n**Examples**:\n\n```python\n# Create isolated context\nctx = sandbox.code_interpreter.create_context()\n\n# Execute code in this context\nsandbox.code_interpreter.run_code(\"x = 100\", context=ctx)\n\n# Variable only exists in this context\nresult = sandbox.code_interpreter.run_code(\"print(x)\", context=ctx)  # OK\n\n# Won't see the variable in default context\nresult = sandbox.code_interpreter.run_code(\"print(x)\")  # NameError\n\n# Clean up\nsandbox.code_interpreter.delete_context(ctx)\n```\n\n#### CodeInterpreter.list\\_contexts\n\n```python\n@intercept_errors(message_prefix=\"Failed to list interpreter contexts: \")\ndef list_contexts() -> list[InterpreterContext]\n```\n\nList all user-created interpreter contexts.\n\nThe default context is not included in this list. Only contexts created\nvia `create_context()` are returned.\n\n**Returns**:\n\n- `list[InterpreterContext]` - List of context objects.\n  \n\n**Raises**:\n\n- `DaytonaError` - If listing fails.\n  \n\n**Examples**:\n\n```python\ncontexts = sandbox.code_interpreter.list_contexts()\nfor ctx in contexts:\n    print(f\"Context {ctx.id}: {ctx.language} at {ctx.cwd}\")\n```\n\n#### CodeInterpreter.delete\\_context\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete interpreter context: \")\ndef delete_context(context: InterpreterContext) -> None\n```\n\nDelete an interpreter context and shut down all associated processes.\n\nThis permanently removes the context and all its state (variables, imports, etc.).\nThe default context cannot be deleted.\n\n**Arguments**:\n\n- `context` _InterpreterContext_ - Context to delete.\n  \n\n**Raises**:\n\n- `DaytonaError` - If deletion fails or context not found.\n  \n\n**Examples**:\n\n```python\nctx = sandbox.code_interpreter.create_context()\n# ... use context ...\nsandbox.code_interpreter.delete_context(ctx)\n```\n\n\n## OutputMessage\n\n```python\nclass OutputMessage(BaseModel)\n```\n\nRepresents stdout or stderr output from code execution.\n\n**Attributes**:\n\n- `output` - The output content.\n\n## ExecutionError\n\n```python\nclass ExecutionError(BaseModel)\n```\n\nRepresents an error that occurred during code execution.\n\n**Attributes**:\n\n- `name` - The error type/class name (e.g., \"ValueError\", \"SyntaxError\").\n- `value` - The error value.\n- `traceback` - Full traceback of the error.\n\n## ExecutionResult\n\n```python\nclass ExecutionResult(BaseModel)\n```\n\nResult of code execution.\n\n**Attributes**:\n\n- `stdout` - Standard output from the code execution.\n- `stderr` - Standard error output from the code execution.\n- `error` - Error details if execution failed, None otherwise.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/computer-use.mdx",
    "content": "---\ntitle: \"ComputerUse\"\nhideTitleOnPage: true\n---\n\n## ComputerUse\n\n```python\nclass ComputerUse()\n```\n\nComputer Use functionality for interacting with the desktop environment.\n\nProvides access to mouse, keyboard, screenshot, display, and recording operations\nfor automating desktop interactions within a sandbox.\n\n**Attributes**:\n\n- `mouse` _Mouse_ - Mouse operations interface.\n- `keyboard` _Keyboard_ - Keyboard operations interface.\n- `screenshot` _Screenshot_ - Screenshot operations interface.\n- `display` _Display_ - Display operations interface.\n- `recording` _RecordingService_ - Screen recording operations interface.\n\n#### ComputerUse.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start computer use: \")\n@with_instrumentation()\ndef start() -> ComputerUseStartResponse\n```\n\nStarts all computer use processes (Xvfb, xfce4, x11vnc, novnc).\n\n**Returns**:\n\n- `ComputerUseStartResponse` - Computer use start response.\n  \n\n**Example**:\n\n```python\nresult = sandbox.computer_use.start()\nprint(\"Computer use processes started:\", result.message)\n```\n\n#### ComputerUse.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop computer use: \")\n@with_instrumentation()\ndef stop() -> ComputerUseStopResponse\n```\n\nStops all computer use processes.\n\n**Returns**:\n\n- `ComputerUseStopResponse` - Computer use stop response.\n  \n\n**Example**:\n\n```python\nresult = sandbox.computer_use.stop()\nprint(\"Computer use processes stopped:\", result.message)\n```\n\n#### ComputerUse.get\\_status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get computer use status: \")\n@with_instrumentation()\ndef get_status() -> ComputerUseStatusResponse\n```\n\nGets the status of all computer use processes.\n\n**Returns**:\n\n- `ComputerUseStatusResponse` - Status information about all VNC desktop processes.\n  \n\n**Example**:\n\n```python\nresponse = sandbox.computer_use.get_status()\nprint(\"Computer use status:\", response.status)\n```\n\n#### ComputerUse.get\\_process\\_status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process status: \")\n@with_instrumentation()\ndef get_process_status(process_name: str) -> ProcessStatusResponse\n```\n\nGets the status of a specific VNC process.\n\n**Arguments**:\n\n- `process_name` _str_ - Name of the process to check.\n  \n\n**Returns**:\n\n- `ProcessStatusResponse` - Status information about the specific process.\n  \n\n**Example**:\n\n```python\nxvfb_status = sandbox.computer_use.get_process_status(\"xvfb\")\nno_vnc_status = sandbox.computer_use.get_process_status(\"novnc\")\n```\n\n#### ComputerUse.restart\\_process\n\n```python\n@intercept_errors(message_prefix=\"Failed to restart process: \")\n@with_instrumentation()\ndef restart_process(process_name: str) -> ProcessRestartResponse\n```\n\nRestarts a specific VNC process.\n\n**Arguments**:\n\n- `process_name` _str_ - Name of the process to restart.\n  \n\n**Returns**:\n\n- `ProcessRestartResponse` - Process restart response.\n  \n\n**Example**:\n\n```python\nresult = sandbox.computer_use.restart_process(\"xfce4\")\nprint(\"XFCE4 process restarted:\", result.message)\n```\n\n#### ComputerUse.get\\_process\\_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process logs: \")\n@with_instrumentation()\ndef get_process_logs(process_name: str) -> ProcessLogsResponse\n```\n\nGets logs for a specific VNC process.\n\n**Arguments**:\n\n- `process_name` _str_ - Name of the process to get logs for.\n  \n\n**Returns**:\n\n- `ProcessLogsResponse` - Process logs.\n  \n\n**Example**:\n\n```python\nlogs = sandbox.computer_use.get_process_logs(\"novnc\")\nprint(\"NoVNC logs:\", logs)\n```\n\n#### ComputerUse.get\\_process\\_errors\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process errors: \")\n@with_instrumentation()\ndef get_process_errors(process_name: str) -> ProcessErrorsResponse\n```\n\nGets error logs for a specific VNC process.\n\n**Arguments**:\n\n- `process_name` _str_ - Name of the process to get error logs for.\n  \n\n**Returns**:\n\n- `ProcessErrorsResponse` - Process error logs.\n  \n\n**Example**:\n\n```python\nerrors = sandbox.computer_use.get_process_errors(\"x11vnc\")\nprint(\"X11VNC errors:\", errors)\n```\n\n\n## Mouse\n\n```python\nclass Mouse()\n```\n\nMouse operations for computer use functionality.\n\n#### Mouse.get\\_position\n\n```python\n@intercept_errors(message_prefix=\"Failed to get mouse position: \")\n@with_instrumentation()\ndef get_position() -> MousePositionResponse\n```\n\nGets the current mouse cursor position.\n\n**Returns**:\n\n- `MousePositionResponse` - Current mouse position with x and y coordinates.\n  \n\n**Example**:\n\n```python\nposition = sandbox.computer_use.mouse.get_position()\nprint(f\"Mouse is at: {position.x}, {position.y}\")\n```\n\n#### Mouse.move\n\n```python\n@intercept_errors(message_prefix=\"Failed to move mouse: \")\n@with_instrumentation()\ndef move(x: int, y: int) -> MousePositionResponse\n```\n\nMoves the mouse cursor to the specified coordinates.\n\n**Arguments**:\n\n- `x` _int_ - The x coordinate to move to.\n- `y` _int_ - The y coordinate to move to.\n  \n\n**Returns**:\n\n- `MousePositionResponse` - Position after move.\n  \n\n**Example**:\n\n```python\nresult = sandbox.computer_use.mouse.move(100, 200)\nprint(f\"Mouse moved to: {result.x}, {result.y}\")\n```\n\n#### Mouse.click\n\n```python\n@intercept_errors(message_prefix=\"Failed to click mouse: \")\n@with_instrumentation()\ndef click(x: int,\n          y: int,\n          button: str = \"left\",\n          double: bool = False) -> MouseClickResponse\n```\n\nClicks the mouse at the specified coordinates.\n\n**Arguments**:\n\n- `x` _int_ - The x coordinate to click at.\n- `y` _int_ - The y coordinate to click at.\n- `button` _str_ - The mouse button to click ('left', 'right', 'middle').\n- `double` _bool_ - Whether to perform a double-click.\n  \n\n**Returns**:\n\n- `MouseClickResponse` - Click operation result.\n  \n\n**Example**:\n\n```python\n# Single left click\nresult = sandbox.computer_use.mouse.click(100, 200)\n\n# Double click\ndouble_click = sandbox.computer_use.mouse.click(100, 200, \"left\", True)\n\n# Right click\nright_click = sandbox.computer_use.mouse.click(100, 200, \"right\")\n```\n\n#### Mouse.drag\n\n```python\n@intercept_errors(message_prefix=\"Failed to drag mouse: \")\n@with_instrumentation()\ndef drag(start_x: int,\n         start_y: int,\n         end_x: int,\n         end_y: int,\n         button: str = \"left\") -> MouseDragResponse\n```\n\nDrags the mouse from start coordinates to end coordinates.\n\n**Arguments**:\n\n- `start_x` _int_ - The starting x coordinate.\n- `start_y` _int_ - The starting y coordinate.\n- `end_x` _int_ - The ending x coordinate.\n- `end_y` _int_ - The ending y coordinate.\n- `button` _str_ - The mouse button to use for dragging.\n  \n\n**Returns**:\n\n- `MouseDragResponse` - Drag operation result.\n  \n\n**Example**:\n\n```python\nresult = sandbox.computer_use.mouse.drag(50, 50, 150, 150)\nprint(f\"Dragged from {result.from_x},{result.from_y} to {result.to_x},{result.to_y}\")\n```\n\n#### Mouse.scroll\n\n```python\n@intercept_errors(message_prefix=\"Failed to scroll mouse: \")\n@with_instrumentation()\ndef scroll(x: int, y: int, direction: str, amount: int = 1) -> bool\n```\n\nScrolls the mouse wheel at the specified coordinates.\n\n**Arguments**:\n\n- `x` _int_ - The x coordinate to scroll at.\n- `y` _int_ - The y coordinate to scroll at.\n- `direction` _str_ - The direction to scroll ('up' or 'down').\n- `amount` _int_ - The amount to scroll.\n  \n\n**Returns**:\n\n- `bool` - Whether the scroll operation was successful.\n  \n\n**Example**:\n\n```python\n# Scroll up\nscroll_up = sandbox.computer_use.mouse.scroll(100, 200, \"up\", 3)\n\n# Scroll down\nscroll_down = sandbox.computer_use.mouse.scroll(100, 200, \"down\", 5)\n```\n\n## Keyboard\n\n```python\nclass Keyboard()\n```\n\nKeyboard operations for computer use functionality.\n\n#### Keyboard.type\n\n```python\n@intercept_errors(message_prefix=\"Failed to type text: \")\n@with_instrumentation()\ndef type(text: str, delay: int | None = None) -> None\n```\n\nTypes the specified text.\n\n**Arguments**:\n\n- `text` _str_ - The text to type.\n- `delay` _int_ - Delay between characters in milliseconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the type operation fails.\n  \n\n**Example**:\n\n```python\ntry:\n    sandbox.computer_use.keyboard.type(\"Hello, World!\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# With delay between characters\ntry:\n    sandbox.computer_use.keyboard.type(\"Slow typing\", 100)\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n#### Keyboard.press\n\n```python\n@intercept_errors(message_prefix=\"Failed to press key: \")\n@with_instrumentation()\ndef press(key: str, modifiers: list[str] | None = None) -> None\n```\n\nPresses a key with optional modifiers.\n\n**Arguments**:\n\n- `key` _str_ - The key to press (e.g., 'Enter', 'Escape', 'Tab', 'a', 'A').\n- `modifiers` _list[str]_ - Modifier keys ('ctrl', 'alt', 'meta', 'shift').\n  \n\n**Raises**:\n\n- `DaytonaError` - If the press operation fails.\n  \n\n**Example**:\n\n```python\n# Press Enter\ntry:\n    sandbox.computer_use.keyboard.press(\"Return\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Press Ctrl+C\ntry:\n    sandbox.computer_use.keyboard.press(\"c\", [\"ctrl\"])\n    print(f\"Operation success\")\n\n# Press Ctrl+Shift+T\ntry:\n    sandbox.computer_use.keyboard.press(\"t\", [\"ctrl\", \"shift\"])\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n#### Keyboard.hotkey\n\n```python\n@intercept_errors(message_prefix=\"Failed to press hotkey: \")\n@with_instrumentation()\ndef hotkey(keys: str) -> None\n```\n\nPresses a hotkey combination.\n\n**Arguments**:\n\n- `keys` _str_ - The hotkey combination (e.g., 'ctrl+c', 'alt+tab', 'cmd+shift+t').\n  \n\n**Raises**:\n\n- `DaytonaError` - If the hotkey operation fails.\n  \n\n**Example**:\n\n```python\n# Copy\ntry:\n    sandbox.computer_use.keyboard.hotkey(\"ctrl+c\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Paste\ntry:\n    sandbox.computer_use.keyboard.hotkey(\"ctrl+v\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Alt+Tab\ntry:\n    sandbox.computer_use.keyboard.hotkey(\"alt+tab\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n## Screenshot\n\n```python\nclass Screenshot()\n```\n\nScreenshot operations for computer use functionality.\n\n#### Screenshot.take\\_full\\_screen\n\n```python\n@intercept_errors(message_prefix=\"Failed to take screenshot: \")\n@with_instrumentation()\ndef take_full_screen(show_cursor: bool = False) -> ScreenshotResponse\n```\n\nTakes a screenshot of the entire screen.\n\n**Arguments**:\n\n- `show_cursor` _bool_ - Whether to show the cursor in the screenshot.\n  \n\n**Returns**:\n\n- `ScreenshotResponse` - Screenshot data with base64 encoded image.\n  \n\n**Example**:\n\n```python\nscreenshot = sandbox.computer_use.screenshot.take_full_screen()\nprint(f\"Screenshot size: {screenshot.width}x{screenshot.height}\")\n\n# With cursor visible\nwith_cursor = sandbox.computer_use.screenshot.take_full_screen(True)\n```\n\n#### Screenshot.take\\_region\n\n```python\n@intercept_errors(message_prefix=\"Failed to take region screenshot: \")\n@with_instrumentation()\ndef take_region(region: ScreenshotRegion,\n                show_cursor: bool = False) -> ScreenshotResponse\n```\n\nTakes a screenshot of a specific region.\n\n**Arguments**:\n\n- `region` _ScreenshotRegion_ - The region to capture.\n- `show_cursor` _bool_ - Whether to show the cursor in the screenshot.\n  \n\n**Returns**:\n\n- `ScreenshotResponse` - Screenshot data with base64 encoded image.\n  \n\n**Example**:\n\n```python\nregion = ScreenshotRegion(x=100, y=100, width=300, height=200)\nscreenshot = sandbox.computer_use.screenshot.take_region(region)\nprint(f\"Captured region: {screenshot.region.width}x{screenshot.region.height}\")\n```\n\n#### Screenshot.take\\_compressed\n\n```python\n@intercept_errors(message_prefix=\"Failed to take compressed screenshot: \")\n@with_instrumentation()\ndef take_compressed(\n        options: ScreenshotOptions | None = None) -> ScreenshotResponse\n```\n\nTakes a compressed screenshot of the entire screen.\n\n**Arguments**:\n\n- `options` _ScreenshotOptions | None_ - Compression and display options.\n  \n\n**Returns**:\n\n- `ScreenshotResponse` - Compressed screenshot data.\n  \n\n**Example**:\n\n```python\n# Default compression\nscreenshot = sandbox.computer_use.screenshot.take_compressed()\n\n# High quality JPEG\njpeg = sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"jpeg\", quality=95, show_cursor=True)\n)\n\n# Scaled down PNG\nscaled = sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"png\", scale=0.5)\n)\n```\n\n#### Screenshot.take\\_compressed\\_region\n\n```python\n@intercept_errors(\n    message_prefix=\"Failed to take compressed region screenshot: \")\n@with_instrumentation()\ndef take_compressed_region(\n        region: ScreenshotRegion,\n        options: ScreenshotOptions | None = None) -> ScreenshotResponse\n```\n\nTakes a compressed screenshot of a specific region.\n\n**Arguments**:\n\n- `region` _ScreenshotRegion_ - The region to capture.\n- `options` _ScreenshotOptions | None_ - Compression and display options.\n  \n\n**Returns**:\n\n- `ScreenshotResponse` - Compressed screenshot data.\n  \n\n**Example**:\n\n```python\nregion = ScreenshotRegion(x=0, y=0, width=800, height=600)\nscreenshot = sandbox.computer_use.screenshot.take_compressed_region(\n    region,\n    ScreenshotOptions(format=\"webp\", quality=80, show_cursor=True)\n)\nprint(f\"Compressed size: {screenshot.size_bytes} bytes\")\n```\n\n## Display\n\n```python\nclass Display()\n```\n\nDisplay operations for computer use functionality.\n\n#### Display.get\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get display info: \")\n@with_instrumentation()\ndef get_info() -> DisplayInfoResponse\n```\n\nGets information about the displays.\n\n**Returns**:\n\n- `DisplayInfoResponse` - Display information including primary display and all available displays.\n  \n\n**Example**:\n\n```python\ninfo = sandbox.computer_use.display.get_info()\nprint(f\"Primary display: {info.primary_display.width}x{info.primary_display.height}\")\nprint(f\"Total displays: {info.total_displays}\")\nfor i, display in enumerate(info.displays):\n    print(f\"Display {i}: {display.width}x{display.height} at {display.x},{display.y}\")\n```\n\n#### Display.get\\_windows\n\n```python\n@intercept_errors(message_prefix=\"Failed to get windows: \")\n@with_instrumentation()\ndef get_windows() -> WindowsResponse\n```\n\nGets the list of open windows.\n\n**Returns**:\n\n- `WindowsResponse` - List of open windows with their IDs and titles.\n  \n\n**Example**:\n\n```python\nwindows = sandbox.computer_use.display.get_windows()\nprint(f\"Found {windows.count} open windows:\")\nfor window in windows.windows:\n    print(f\"- {window.title} (ID: {window.id})\")\n```\n\n## RecordingService\n\n```python\nclass RecordingService()\n```\n\nRecording operations for computer use functionality.\n\n#### RecordingService.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start recording: \")\n@with_instrumentation()\ndef start(label: str | None = None) -> Recording\n```\n\nStarts a new screen recording session.\n\n**Arguments**:\n\n- `label` _str | None_ - Optional custom label for the recording.\n  \n\n**Returns**:\n\n- `Recording` - Recording start response.\n  \n\n**Example**:\n\n```python\n# Start a recording with a label\nrecording = sandbox.computer_use.recording.start(\"my-test-recording\")\nprint(f\"Recording started: {recording.id}\")\nprint(f\"File: {recording.file_path}\")\n```\n\n#### RecordingService.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop recording: \")\n@with_instrumentation()\ndef stop(recording_id: str) -> Recording\n```\n\nStops an active screen recording session.\n\n**Arguments**:\n\n- `recording_id` _str_ - The ID of the recording to stop.\n  \n\n**Returns**:\n\n- `Recording` - Recording stop response.\n  \n\n**Example**:\n\n```python\nresult = sandbox.computer_use.recording.stop(recording.id)\nprint(f\"Recording stopped: {result.duration_seconds} seconds\")\nprint(f\"Saved to: {result.file_path}\")\n```\n\n#### RecordingService.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list recordings: \")\n@with_instrumentation()\ndef list() -> ListRecordingsResponse\n```\n\nLists all recordings (active and completed).\n\n**Returns**:\n\n- `ListRecordingsResponse` - List of all recordings.\n  \n\n**Example**:\n\n```python\nrecordings = sandbox.computer_use.recording.list()\nprint(f\"Found {len(recordings.recordings)} recordings\")\nfor rec in recordings.recordings:\n    print(f\"- {rec.file_name}: {rec.status}\")\n```\n\n#### RecordingService.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get recording: \")\n@with_instrumentation()\ndef get(recording_id: str) -> Recording\n```\n\nGets details of a specific recording by ID.\n\n**Arguments**:\n\n- `recording_id` _str_ - The ID of the recording to retrieve.\n  \n\n**Returns**:\n\n- `Recording` - Recording details.\n  \n\n**Example**:\n\n```python\nrecording = sandbox.computer_use.recording.get(recording_id)\nprint(f\"Recording: {recording.file_name}\")\nprint(f\"Status: {recording.status}\")\nprint(f\"Duration: {recording.duration_seconds} seconds\")\n```\n\n#### RecordingService.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete recording: \")\n@with_instrumentation()\ndef delete(recording_id: str) -> None\n```\n\nDeletes a recording by ID.\n\n**Arguments**:\n\n- `recording_id` _str_ - The ID of the recording to delete.\n  \n\n**Example**:\n\n```python\nsandbox.computer_use.recording.delete(recording_id)\nprint(\"Recording deleted\")\n```\n\n#### RecordingService.download\n\n```python\n@intercept_errors(message_prefix=\"Failed to download recording: \")\n@with_instrumentation()\ndef download(recording_id: str, local_path: str) -> None\n```\n\nDownloads a recording file from the Sandbox and saves it to a local file.\n\nThe file is streamed directly to disk without loading the entire content into memory.\n\n**Arguments**:\n\n- `recording_id` _str_ - The ID of the recording to download.\n- `local_path` _str_ - Path to save the recording file locally.\n  \n\n**Example**:\n\n```python\n# Download recording to file\nsandbox.computer_use.recording.download(recording_id, \"local_recording.mp4\")\nprint(\"Recording downloaded\")\n```\n\n## ScreenshotRegion\n\n```python\nclass ScreenshotRegion(BaseModel)\n```\n\nRegion coordinates for screenshot operations.\n\n**Attributes**:\n\n- `x` _int_ - X coordinate of the region.\n- `y` _int_ - Y coordinate of the region.\n- `width` _int_ - Width of the region.\n- `height` _int_ - Height of the region.\n\n## ScreenshotOptions\n\n```python\nclass ScreenshotOptions(BaseModel)\n```\n\nOptions for screenshot compression and display.\n\n**Attributes**:\n\n- `show_cursor` _bool | None_ - Whether to show the cursor in the screenshot.\n- `fmt` _str | None_ - Image format (e.g., 'png', 'jpeg', 'webp').\n- `quality` _int | None_ - Compression quality (0-100).\n- `scale` _float | None_ - Scale factor for the screenshot.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/daytona.mdx",
    "content": "---\ntitle: \"Daytona\"\nhideTitleOnPage: true\n---\n\n## Daytona\n\n```python\nclass Daytona()\n```\n\nMain class for interacting with the Daytona API.\n\nThis class provides methods to create, manage, and interact with Daytona Sandboxes.\nIt can be initialized either with explicit configuration or using environment variables.\n\n**Attributes**:\n\n- `volume` _VolumeService_ - Service for managing volumes.\n- `snapshot` _SnapshotService_ - Service for managing snapshots.\n  \n\n**Example**:\n\n  Using environment variables:\n```python\ndaytona = Daytona()  # Uses DAYTONA_API_KEY, DAYTONA_API_URL\nsandbox = daytona.create()\n```\n  \n  Using explicit configuration:\n```python\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"https://your-api.com\",\n    target=\"us\"\n)\ndaytona = Daytona(config)\nsandbox = daytona.create()\n```\n  \n  Using OpenTelemetry tracing:\n```python\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    experimental={\"otelEnabled\": True}  # Enable OpenTelemetry tracing through experimental config\n)\nasync with Daytona(config) as daytona:\n    sandbox = daytona.create()\n    # All SDK operations will be traced\n# OpenTelemetry traces are flushed on close\n```\n\n#### Daytona.\\_\\_init\\_\\_\n\n```python\ndef __init__(config: DaytonaConfig | None = None)\n```\n\nInitializes Daytona instance with optional configuration.\n\nIf no config is provided, reads from environment variables:\n- `DAYTONA_API_KEY`: Required API key for authentication\n- `DAYTONA_API_URL`: Required api URL\n- `DAYTONA_TARGET`: Optional target environment (if not provided, default region for the organization is used)\n\n**Arguments**:\n\n- `config` _DaytonaConfig | None_ - Object containing api_key, api_url, and target.\n  \n\n**Raises**:\n\n- `DaytonaError` - If API key is not provided either through config or environment variables\n  \n\n**Example**:\n\n```python\nfrom daytona import Daytona, DaytonaConfig\n# Using environment variables\ndaytona1 = Daytona()\n\n# Using explicit configuration\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"https://your-api.com\",\n    target=\"us\"\n)\ndaytona2 = Daytona(config)\n\n```\n\n#### Daytona.create\n\n```python\n@overload\ndef create(params: CreateSandboxFromSnapshotParams | None = None,\n           *,\n           timeout: float = 60) -> Sandbox\n```\n\nCreates Sandboxes from specified or default snapshot. You can specify various parameters,\nincluding language, image, environment variables, and volumes.\n\n**Arguments**:\n\n- `params` _CreateSandboxFromSnapshotParams | None_ - Parameters for Sandbox creation. If not provided,\n  defaults to default Daytona snapshot and Python language.\n- `timeout` _float_ - Timeout (in seconds) for sandbox creation. 0 means no timeout.\n  Default is 60 seconds.\n  \n\n**Returns**:\n\n- `Sandbox` - The created Sandbox instance.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout, auto_stop_interval or auto_archive_interval is negative;\n  If sandbox fails to start or times out\n  \n\n**Example**:\n\n  Create a default Python Sandbox:\n```python\nsandbox = daytona.create()\n```\n  \n  Create a custom Sandbox:\n```python\nparams = CreateSandboxFromSnapshotParams(\n    language=\"python\",\n    snapshot=\"my-snapshot-id\",\n    env_vars={\"DEBUG\": \"true\"},\n    auto_stop_interval=0,\n    auto_archive_interval=60,\n    auto_delete_interval=120\n)\nsandbox = daytona.create(params, timeout=40)\n```\n\n#### Daytona.create\n\n```python\n@overload\ndef create(\n        params: CreateSandboxFromImageParams | None = None,\n        *,\n        timeout: float = 60,\n        on_snapshot_create_logs: Callable[[str], None] | None = None\n) -> Sandbox\n```\n\nCreates Sandboxes from specified image available on some registry or declarative Daytona Image.\nYou can specify various parameters, including resources, language, image, environment variables,\nand volumes. Daytona creates snapshot from provided image and uses it to create Sandbox.\n\n**Arguments**:\n\n- `params` _CreateSandboxFromImageParams | None_ - Parameters for Sandbox creation from image.\n- `timeout` _float_ - Timeout (in seconds) for sandbox creation. 0 means no timeout.\n  Default is 60 seconds.\n- `on_snapshot_create_logs` _Callable[[str], None] | None_ - This callback function\n  handles snapshot creation logs.\n  \n\n**Returns**:\n\n- `Sandbox` - The created Sandbox instance.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout, auto_stop_interval or auto_archive_interval is negative;\n  If sandbox fails to start or times out\n  \n\n**Example**:\n\n  Create a default Python Sandbox from image:\n```python\nsandbox = daytona.create(CreateSandboxFromImageParams(image=\"debian:12.9\"))\n```\n  \n  Create a custom Sandbox from declarative Image definition:\n```python\ndeclarative_image = (\n    Image.base(\"alpine:3.18\")\n    .pipInstall([\"numpy\", \"pandas\"])\n    .env({\"MY_ENV_VAR\": \"My Environment Variable\"})\n)\nparams = CreateSandboxFromImageParams(\n    language=\"python\",\n    image=declarative_image,\n    env_vars={\"DEBUG\": \"true\"},\n    resources=Resources(cpu=2, memory=4),\n    auto_stop_interval=0,\n    auto_archive_interval=60,\n    auto_delete_interval=120\n)\nsandbox = daytona.create(\n    params,\n    timeout=40,\n    on_snapshot_create_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n#### Daytona.delete\n\n```python\n@with_instrumentation()\ndef delete(sandbox: Sandbox, timeout: float = 60) -> None\n```\n\nDeletes a Sandbox.\n\n**Arguments**:\n\n- `sandbox` _Sandbox_ - The Sandbox instance to delete.\n- `timeout` _float_ - Timeout (in seconds) for sandbox deletion. 0 means no timeout.\n  Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If sandbox fails to delete or times out\n  \n\n**Example**:\n\n```python\nsandbox = daytona.create()\n# ... use sandbox ...\ndaytona.delete(sandbox)  # Clean up when done\n```\n\n#### Daytona.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get sandbox: \")\n@with_instrumentation()\ndef get(sandbox_id_or_name: str) -> Sandbox\n```\n\nGets a Sandbox by its ID or name.\n\n**Arguments**:\n\n- `sandbox_id_or_name` _str_ - The ID or name of the Sandbox to retrieve.\n  \n\n**Returns**:\n\n- `Sandbox` - The Sandbox instance.\n  \n\n**Raises**:\n\n- `DaytonaError` - If sandbox_id_or_name is not provided.\n  \n\n**Example**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id-or-name\")\nprint(sandbox.state)\n```\n\n#### Daytona.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list sandboxes: \")\n@with_instrumentation()\ndef list(labels: dict[str, str] | None = None,\n         page: int | None = None,\n         limit: int | None = None) -> PaginatedSandboxes\n```\n\nReturns paginated list of Sandboxes filtered by labels.\n\n**Arguments**:\n\n- `labels` _dict[str, str] | None_ - Labels to filter Sandboxes.\n- `page` _int | None_ - Page number for pagination (starting from 1).\n- `limit` _int | None_ - Maximum number of items per page.\n  \n\n**Returns**:\n\n- `PaginatedSandboxes` - Paginated list of Sandbox instances that match the labels.\n  \n\n**Example**:\n\n```python\nresult = daytona.list(labels={\"my-label\": \"my-value\"}, page=2, limit=10)\nfor sandbox in result.items:\n    print(f\"{sandbox.id}: {sandbox.state}\")\n```\n\n#### Daytona.start\n\n```python\n@with_instrumentation()\ndef start(sandbox: Sandbox, timeout: float = 60) -> None\n```\n\nStarts a Sandbox and waits for it to be ready.\n\n**Arguments**:\n\n- `sandbox` _Sandbox_ - The Sandbox to start.\n- `timeout` _float_ - Optional timeout in seconds to wait for the Sandbox to start.\n  0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative; If Sandbox fails to start or times out\n\n#### Daytona.stop\n\n```python\n@with_instrumentation()\ndef stop(sandbox: Sandbox, timeout: float = 60) -> None\n```\n\nStops a Sandbox and waits for it to be stopped.\n\n**Arguments**:\n\n- `sandbox` _Sandbox_ - The sandbox to stop\n- `timeout` _float_ - Optional timeout (in seconds) for sandbox stop.\n  0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative; If Sandbox fails to stop or times out\n\n\n## CodeLanguage\n\n```python\nclass CodeLanguage(str, Enum)\n```\n\nProgramming languages supported by Daytona\n\n**Enum Members**:\n    - `PYTHON` (\"python\")\n    - `TYPESCRIPT` (\"typescript\")\n    - `JAVASCRIPT` (\"javascript\")\n\n## DaytonaConfig\n\n```python\nclass DaytonaConfig(BaseModel)\n```\n\nConfiguration options for initializing the Daytona client.\n\n**Attributes**:\n\n- `api_key` _str | None_ - API key for authentication with the Daytona API. If not set, it must be provided\n  via the environment variable `DAYTONA_API_KEY`, or a JWT token must be provided instead.\n- `jwt_token` _str | None_ - JWT token for authentication with the Daytona API. If not set, it must be provided\n  via the environment variable `DAYTONA_JWT_TOKEN`, or an API key must be provided instead.\n- `organization_id` _str | None_ - Organization ID used for JWT-based authentication. Required if a JWT token\n  is provided, and must be set either here or in the environment variable `DAYTONA_ORGANIZATION_ID`.\n- `api_url` _str | None_ - URL of the Daytona API. Defaults to `'https://app.daytona.io/api'` if not set\n  here or in the environment variable `DAYTONA_API_URL`.\n- `server_url` _str | None_ - Deprecated. Use `api_url` instead. This property will be removed\n  in a future version.\n- `target` _str | None_ - Target runner location for the Sandbox. Default region for the organization is used\n  if not set here or in the environment variable `DAYTONA_TARGET`.\n- `_experimental` _dict[str, any] | None_ - Configuration for experimental features.\n  \n\n**Example**:\n\n```python\nconfig = DaytonaConfig(api_key=\"your-api-key\")\n```\n```python\nconfig = DaytonaConfig(jwt_token=\"your-jwt-token\", organization_id=\"your-organization-id\")\n```\n\n## CreateSandboxBaseParams\n\n```python\nclass CreateSandboxBaseParams(BaseModel)\n```\n\nBase parameters for creating a new Sandbox.\n\n**Attributes**:\n\n- `name` _str | None_ - Name of the Sandbox.\n- `language` _CodeLanguage | CodeLanguageLiteral | None_ - Programming language for the Sandbox.\n  Defaults to \"python\".\n- `os_user` _str | None_ - OS user for the Sandbox.\n- `env_vars` _dict[str, str] | None_ - Environment variables to set in the Sandbox.\n- `labels` _dict[str, str] | None_ - Custom labels for the Sandbox.\n- `public` _bool | None_ - Whether the Sandbox should be public.\n- `timeout` _float | None_ - Timeout in seconds for Sandbox to be created and started.\n- `auto_stop_interval` _int | None_ - Interval in minutes after which Sandbox will\n  automatically stop if no Sandbox event occurs during that time. Default is 15 minutes.\n  0 means no auto-stop.\n- `auto_archive_interval` _int | None_ - Interval in minutes after which a continuously stopped Sandbox will\n  automatically archive. Default is 7 days.\n  0 means the maximum interval will be used.\n- `auto_delete_interval` _int | None_ - Interval in minutes after which a continuously stopped Sandbox will\n  automatically be deleted. By default, auto-delete is disabled.\n  Negative value means disabled, 0 means delete immediately upon stopping.\n- `volumes` _list[VolumeMount] | None_ - List of volumes mounts to attach to the Sandbox.\n- `network_block_all` _bool | None_ - Whether to block all network access for the Sandbox.\n- `network_allow_list` _str | None_ - Comma-separated list of allowed CIDR network addresses for the Sandbox.\n- `ephemeral` _bool | None_ - Whether the Sandbox should be ephemeral.\n  If True, auto_delete_interval will be set to 0.\n\n## CreateSandboxFromImageParams\n\n```python\nclass CreateSandboxFromImageParams(CreateSandboxBaseParams)\n```\n\nParameters for creating a new Sandbox from an image.\n\n**Attributes**:\n\n- `image` _str | Image_ - Custom Docker image to use for the Sandbox. If an Image object is provided,\n  the image will be dynamically built.\n- `resources` _Resources | None_ - Resource configuration for the Sandbox. If not provided, sandbox will\n  have default resources.\n\n## CreateSandboxFromSnapshotParams\n\n```python\nclass CreateSandboxFromSnapshotParams(CreateSandboxBaseParams)\n```\n\nParameters for creating a new Sandbox from a snapshot.\n\n**Attributes**:\n\n- `snapshot` _str | None_ - Name of the snapshot to use for the Sandbox.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/file-system.mdx",
    "content": "---\ntitle: \"FileSystem\"\nhideTitleOnPage: true\n---\n\n## FileSystem\n\n```python\nclass FileSystem()\n```\n\nProvides file system operations within a Sandbox.\n\nThis class implements a high-level interface to file system operations that can\nbe performed within a Daytona Sandbox.\n\n#### FileSystem.\\_\\_init\\_\\_\n\n```python\ndef __init__(api_client: FileSystemApi)\n```\n\nInitializes a new FileSystem instance.\n\n**Arguments**:\n\n- `api_client` _FileSystemApi_ - API client for Sandbox file system operations.\n\n#### FileSystem.create\\_folder\n\n```python\n@intercept_errors(message_prefix=\"Failed to create folder: \")\n@with_instrumentation()\ndef create_folder(path: str, mode: str) -> None\n```\n\nCreates a new directory in the Sandbox at the specified path with the given\npermissions.\n\n**Arguments**:\n\n- `path` _str_ - Path where the folder should be created. Relative paths are resolved based\n  on the sandbox working directory.\n- `mode` _str_ - Folder permissions in octal format (e.g., \"755\" for rwxr-xr-x).\n  \n\n**Example**:\n\n```python\n# Create a directory with standard permissions\nsandbox.fs.create_folder(\"workspace/data\", \"755\")\n\n# Create a private directory\nsandbox.fs.create_folder(\"workspace/secrets\", \"700\")\n```\n\n#### FileSystem.delete\\_file\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete file: \")\n@with_instrumentation()\ndef delete_file(path: str, recursive: bool = False) -> None\n```\n\nDeletes a file from the Sandbox.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file to delete. Relative paths are resolved based on the sandbox working directory.\n- `recursive` _bool_ - If the file is a directory, this must be true to delete it.\n  \n\n**Example**:\n\n```python\n# Delete a file\nsandbox.fs.delete_file(\"workspace/data/old_file.txt\")\n```\n\n#### FileSystem.download\\_file\n\n```python\n@overload\ndef download_file(remote_path: str, timeout: int = 30 * 60) -> bytes\n```\n\nDownloads a file from the Sandbox. Returns the file contents as a bytes object.\nThis method is useful when you want to load the file into memory without saving it to disk.\nIt can only be used for smaller files.\n\n**Arguments**:\n\n- `remote_path` _str_ - Path to the file in the Sandbox. Relative paths are resolved based\n  on the sandbox working directory.\n- `timeout` _int_ - Timeout for the download operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Returns**:\n\n- `bytes` - The file contents as a bytes object.\n  \n\n**Example**:\n\n```python\n# Download and save a file locally\ncontent = sandbox.fs.download_file(\"workspace/data/file.txt\")\nwith open(\"local_copy.txt\", \"wb\") as f:\n    f.write(content)\n\n# Download and process text content\ncontent = sandbox.fs.download_file(\"workspace/data/config.json\")\nconfig = json.loads(content.decode('utf-8'))\n```\n\n#### FileSystem.download\\_file\n\n```python\n@overload\ndef download_file(remote_path: str,\n                  local_path: str,\n                  timeout: int = 30 * 60) -> None\n```\n\nDownloads a file from the Sandbox and saves it to a local file using stream.\nThis method is useful when you want to download larger files that may not fit into memory.\n\n**Arguments**:\n\n- `remote_path` _str_ - Path to the file in the Sandbox. Relative paths are resolved based\n  on the sandbox working directory.\n- `local_path` _str_ - Path to save the file locally.\n- `timeout` _int_ - Timeout for the download operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Example**:\n\n```python\nlocal_path = \"local_copy.txt\"\nsandbox.fs.download_file(\"tmp/large_file.txt\", local_path)\nsize_mb = os.path.getsize(local_path) / 1024 / 1024\nprint(f\"Size of the downloaded file {local_path}: {size_mb} MB\")\n```\n\n#### FileSystem.download\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to download files: \")\n@with_instrumentation()\ndef download_files(files: list[FileDownloadRequest],\n                   timeout: int = 30 * 60) -> list[FileDownloadResponse]\n```\n\nDownloads multiple files from the Sandbox. If the files already exist locally, they will be overwritten.\n\n**Arguments**:\n\n- `files` _list[FileDownloadRequest]_ - List of files to download.\n- `timeout` _int_ - Timeout for the download operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Returns**:\n\n- `list[FileDownloadResponse]` - List of download results.\n  \n\n**Raises**:\n\n- `Exception` - Only if the request itself fails (network issues, invalid request/response, etc.). Individual\n  file download errors are returned in the `FileDownloadResponse.error` field.\n  \n\n**Example**:\n\n```python\n# Download multiple files\nresults = sandbox.fs.download_files([\n    FileDownloadRequest(source=\"tmp/data.json\"),\n    FileDownloadRequest(source=\"tmp/config.json\", destination=\"local_config.json\")\n])\nfor result in results:\n    if result.error:\n        print(f\"Error downloading {result.source}: {result.error}\")\n    elif result.result:\n        print(f\"Downloaded {result.source} to {result.result}\")\n```\n\n#### FileSystem.find\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to find files: \")\n@with_instrumentation()\ndef find_files(path: str, pattern: str) -> list[Match]\n```\n\nSearches for files containing a pattern, similar to\nthe grep command.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file or directory to search. If the path is a directory,\n  the search will be performed recursively. Relative paths are resolved based\n  on the sandbox working directory.\n- `pattern` _str_ - Search pattern to match against file contents.\n  \n\n**Returns**:\n\n- `list[Match]` - List of matches found in files. Each Match object includes:\n  - file: Path to the file containing the match\n  - line: The line number where the match was found\n  - content: The matching line content\n  \n\n**Example**:\n\n```python\n# Search for TODOs in Python files\nmatches = sandbox.fs.find_files(\"workspace/src\", \"TODO:\")\nfor match in matches:\n    print(f\"{match.file}:{match.line}: {match.content.strip()}\")\n```\n\n#### FileSystem.get\\_file\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get file info: \")\n@with_instrumentation()\ndef get_file_info(path: str) -> FileInfo\n```\n\nGets detailed information about a file or directory, including its\nsize, permissions, and timestamps.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file or directory. Relative paths are resolved based\n  on the sandbox working directory.\n  \n\n**Returns**:\n\n- `FileInfo` - Detailed file information including:\n  - name: File name\n  - is_dir: Whether the path is a directory\n  - size: File size in bytes\n  - mode: File permissions\n  - mod_time: Last modification timestamp\n  - permissions: File permissions in octal format\n  - owner: File owner\n  - group: File group\n  \n\n**Example**:\n\n```python\n# Get file metadata\ninfo = sandbox.fs.get_file_info(\"workspace/data/file.txt\")\nprint(f\"Size: {info.size} bytes\")\nprint(f\"Modified: {info.mod_time}\")\nprint(f\"Mode: {info.mode}\")\n\n# Check if path is a directory\ninfo = sandbox.fs.get_file_info(\"workspace/data\")\nif info.is_dir:\n    print(\"Path is a directory\")\n```\n\n#### FileSystem.list\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to list files: \")\n@with_instrumentation()\ndef list_files(path: str) -> list[FileInfo]\n```\n\nLists files and directories in a given path and returns their information, similar to the ls -l command.\n\n**Arguments**:\n\n- `path` _str_ - Path to the directory to list contents from. Relative paths are resolved\n  based on the sandbox working directory.\n  \n\n**Returns**:\n\n- `list[FileInfo]` - List of file and directory information. Each FileInfo\n  object includes the same fields as described in get_file_info().\n  \n\n**Example**:\n\n```python\n# List directory contents\nfiles = sandbox.fs.list_files(\"workspace/data\")\n\n# Print files and their sizes\nfor file in files:\n    if not file.is_dir:\n        print(f\"{file.name}: {file.size} bytes\")\n\n# List only directories\ndirs = [f for f in files if f.is_dir]\nprint(\"Subdirectories:\", \", \".join(d.name for d in dirs))\n```\n\n#### FileSystem.move\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to move files: \")\n@with_instrumentation()\ndef move_files(source: str, destination: str) -> None\n```\n\nMoves or renames a file or directory. The parent directory of the destination must exist.\n\n**Arguments**:\n\n- `source` _str_ - Path to the source file or directory. Relative paths are resolved\n  based on the sandbox working directory.\n- `destination` _str_ - Path to the destination. Relative paths are resolved based on\n  the sandbox working directory.\n  \n\n**Example**:\n\n```python\n# Rename a file\nsandbox.fs.move_files(\n    \"workspace/data/old_name.txt\",\n    \"workspace/data/new_name.txt\"\n)\n\n# Move a file to a different directory\nsandbox.fs.move_files(\n    \"workspace/data/file.txt\",\n    \"workspace/archive/file.txt\"\n)\n\n# Move a directory\nsandbox.fs.move_files(\n    \"workspace/old_dir\",\n    \"workspace/new_dir\"\n)\n```\n\n#### FileSystem.replace\\_in\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to replace in files: \")\n@with_instrumentation()\ndef replace_in_files(files: list[str], pattern: str,\n                     new_value: str) -> list[ReplaceResult]\n```\n\nPerforms search and replace operations across multiple files.\n\n**Arguments**:\n\n- `files` _list[str]_ - List of file paths to perform replacements in. Relative paths are\n  resolved based on the sandbox working directory.\n- `pattern` _str_ - Pattern to search for.\n- `new_value` _str_ - Text to replace matches with.\n  \n\n**Returns**:\n\n- `list[ReplaceResult]` - List of results indicating replacements made in\n  each file. Each ReplaceResult includes:\n  - file: Path to the modified file\n  - success: Whether the operation was successful\n  - error: Error message if the operation failed\n  \n\n**Example**:\n\n```python\n# Replace in specific files\nresults = sandbox.fs.replace_in_files(\n    files=[\"workspace/src/file1.py\", \"workspace/src/file2.py\"],\n    pattern=\"old_function\",\n    new_value=\"new_function\"\n)\n\n# Print results\nfor result in results:\n    if result.success:\n        print(f\"{result.file}: {result.success}\")\n    else:\n        print(f\"{result.file}: {result.error}\")\n```\n\n#### FileSystem.search\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to search files: \")\n@with_instrumentation()\ndef search_files(path: str, pattern: str) -> SearchFilesResponse\n```\n\nSearches for files and directories whose names match the\nspecified pattern. The pattern can be a simple string or a glob pattern.\n\n**Arguments**:\n\n- `path` _str_ - Path to the root directory to start search from. Relative paths are resolved\n  based on the sandbox working directory.\n- `pattern` _str_ - Pattern to match against file names. Supports glob\n  patterns (e.g., \"*.py\" for Python files).\n  \n\n**Returns**:\n\n- `SearchFilesResponse` - Search results containing:\n  - files: List of matching file and directory paths\n  \n\n**Example**:\n\n```python\n# Find all Python files\nresult = sandbox.fs.search_files(\"workspace\", \"*.py\")\nfor file in result.files:\n    print(file)\n\n# Find files with specific prefix\nresult = sandbox.fs.search_files(\"workspace/data\", \"test_*\")\nprint(f\"Found {len(result.files)} test files\")\n```\n\n#### FileSystem.set\\_file\\_permissions\n\n```python\n@intercept_errors(message_prefix=\"Failed to set file permissions: \")\n@with_instrumentation()\ndef set_file_permissions(path: str,\n                         mode: str | None = None,\n                         owner: str | None = None,\n                         group: str | None = None) -> None\n```\n\nSets permissions and ownership for a file or directory. Any of the parameters can be None\nto leave that attribute unchanged.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file or directory. Relative paths are resolved based on\n  the sandbox working directory.\n- `mode` _str | None_ - File mode/permissions in octal format\n  (e.g., \"644\" for rw-r--r--).\n- `owner` _str | None_ - User owner of the file.\n- `group` _str | None_ - Group owner of the file.\n  \n\n**Example**:\n\n```python\n# Make a file executable\nsandbox.fs.set_file_permissions(\n    path=\"workspace/scripts/run.sh\",\n    mode=\"755\"  # rwxr-xr-x\n)\n\n# Change file owner\nsandbox.fs.set_file_permissions(\n    path=\"workspace/data/file.txt\",\n    owner=\"daytona\",\n    group=\"daytona\"\n)\n```\n\n#### FileSystem.upload\\_file\n\n```python\n@overload\ndef upload_file(file: bytes, remote_path: str, timeout: int = 30 * 60) -> None\n```\n\nUploads a file to the specified path in the Sandbox. If a file already exists at\nthe destination path, it will be overwritten. This method is useful when you want to upload\nsmall files that fit into memory.\n\n**Arguments**:\n\n- `file` _bytes_ - File contents as a bytes object.\n- `remote_path` _str_ - Path to the destination file. Relative paths are resolved based on\n  the sandbox working directory.\n- `timeout` _int_ - Timeout for the upload operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Example**:\n\n```python\n# Upload a text file\ncontent = b\"Hello, World!\"\nsandbox.fs.upload_file(content, \"tmp/hello.txt\")\n\n# Upload a local file\nwith open(\"local_file.txt\", \"rb\") as f:\n    content = f.read()\nsandbox.fs.upload_file(content, \"tmp/file.txt\")\n\n# Upload binary data\nimport json\ndata = {\"key\": \"value\"}\ncontent = json.dumps(data).encode('utf-8')\nsandbox.fs.upload_file(content, \"tmp/config.json\")\n```\n\n#### FileSystem.upload\\_file\n\n```python\n@overload\ndef upload_file(local_path: str,\n                remote_path: str,\n                timeout: int = 30 * 60) -> None\n```\n\nUploads a file from the local file system to the specified path in the Sandbox.\nIf a file already exists at the destination path, it will be overwritten. This method uses\nstreaming to upload the file, so it is useful when you want to upload larger files that may\nnot fit into memory.\n\n**Arguments**:\n\n- `local_path` _str_ - Path to the local file to upload.\n- `remote_path` _str_ - Path to the destination file in the Sandbox. Relative paths are\n  resolved based on the sandbox working directory.\n- `timeout` _int_ - Timeout for the upload operation in seconds. 0 means no timeout. Default is 30 minutes.\n  \n\n**Example**:\n\n```python\nsandbox.fs.upload_file(\"local_file.txt\", \"tmp/large_file.txt\")\n```\n\n#### FileSystem.upload\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to upload files: \")\n@with_instrumentation()\ndef upload_files(files: list[FileUpload], timeout: int = 30 * 60) -> None\n```\n\nUploads multiple files to the Sandbox. If files already exist at the destination paths,\nthey will be overwritten.\n\n**Arguments**:\n\n- `files` _list[FileUpload]_ - List of files to upload.\n- `timeout` _int_ - Timeout for the upload operation in seconds. 0 means no timeout. Default is 30 minutes.\n\n**Example**:\n\n```python\n# Upload multiple text files\nfiles = [\n    FileUpload(\n        source=b\"Content of file 1\",\n        destination=\"/tmp/file1.txt\"\n    ),\n    FileUpload(\n        source=\"workspace/data/file2.txt\",\n        destination=\"/tmp/file2.txt\"\n    ),\n    FileUpload(\n        source=b'{\"key\": \"value\"}',\n        destination=\"/tmp/config.json\"\n    )\n]\nsandbox.fs.upload_files(files)\n```\n\n\n## FileUpload\n\n```python\n@dataclass\nclass FileUpload()\n```\n\nRepresents a file to be uploaded to the Sandbox.\n\n**Attributes**:\n\n- `source` _bytes | str_ - File contents as a bytes object or a local file path. If a bytes object is provided,\n  make sure it fits into memory, otherwise use the local file path which content will be streamed to the Sandbox.\n- `destination` _str_ - Absolute destination path in the Sandbox. Relative paths are resolved based on\n  the sandbox working directory.\n\n## FileDownloadRequest\n\n```python\n@dataclass\nclass FileDownloadRequest()\n```\n\nRepresents a request to download a single file from the Sandbox.\n\n**Attributes**:\n\n- `source` _str_ - Source path in the Sandbox. Relative paths are resolved based on the user's\n  root directory.\n- `destination` _str | None_ - Destination path in the local filesystem where the file content will be\n  streamed to. If not provided, the file will be downloaded in the bytes buffer\n  (might cause memory issues if the file is large).\n\n## FileDownloadResponse\n\n```python\n@dataclass\nclass FileDownloadResponse()\n```\n\nRepresents the response to a single file download request.\n\n**Attributes**:\n\n- `source` _str_ - The original source path requested for download.\n- `result` _str | bytes | None_ - The download result - file path (if destination provided in the request)\n  or bytes content (if no destination in the request), None if failed or no data received.\n- `error` _str | None_ - Error message if the download failed, None if successful.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/git.mdx",
    "content": "---\ntitle: \"Git\"\nhideTitleOnPage: true\n---\n\n## Git\n\n```python\nclass Git()\n```\n\nProvides Git operations within a Sandbox.\n\n**Example**:\n\n```python\n# Clone a repository\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# Check repository status\nstatus = sandbox.git.status(\"workspace/repo\")\nprint(f\"Modified files: {status.modified}\")\n\n# Stage and commit changes\nsandbox.git.add(\"workspace/repo\", [\"file.txt\"])\nsandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update file\",\n    author=\"John Doe\",\n    email=\"john@example.com\"\n)\n```\n\n#### Git.\\_\\_init\\_\\_\n\n```python\ndef __init__(api_client: GitApi)\n```\n\nInitializes a new Git handler instance.\n\n**Arguments**:\n\n- `api_client` _GitApi_ - API client for Sandbox Git operations.\n\n#### Git.add\n\n```python\n@intercept_errors(message_prefix=\"Failed to add files: \")\n@with_instrumentation()\ndef add(path: str, files: list[str]) -> None\n```\n\nStages the specified files for the next commit, similar to\nrunning 'git add' on the command line.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `files` _list[str]_ - List of file paths or directories to stage, relative to the repository root.\n  \n\n**Example**:\n\n```python\n# Stage a single file\nsandbox.git.add(\"workspace/repo\", [\"file.txt\"])\n\n# Stage multiple files\nsandbox.git.add(\"workspace/repo\", [\n    \"src/main.py\",\n    \"tests/test_main.py\",\n    \"README.md\"\n])\n```\n\n#### Git.branches\n\n```python\n@intercept_errors(message_prefix=\"Failed to list branches: \")\n@with_instrumentation()\ndef branches(path: str) -> ListBranchResponse\n```\n\nLists branches in the repository.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n  \n\n**Returns**:\n\n- `ListBranchResponse` - List of branches in the repository.\n  \n\n**Example**:\n\n```python\nresponse = sandbox.git.branches(\"workspace/repo\")\nprint(f\"Branches: {response.branches}\")\n```\n\n#### Git.clone\n\n```python\n@intercept_errors(message_prefix=\"Failed to clone repository: \")\n@with_instrumentation()\ndef clone(url: str,\n          path: str,\n          branch: str | None = None,\n          commit_id: str | None = None,\n          username: str | None = None,\n          password: str | None = None) -> None\n```\n\nClones a Git repository into the specified path. It supports\ncloning specific branches or commits, and can authenticate with the remote\nrepository if credentials are provided.\n\n**Arguments**:\n\n- `url` _str_ - Repository URL to clone from.\n- `path` _str_ - Path where the repository should be cloned. Relative paths are resolved\n  based on the sandbox working directory.\n- `branch` _str | None_ - Specific branch to clone. If not specified,\n  clones the default branch.\n- `commit_id` _str | None_ - Specific commit to clone. If specified,\n  the repository will be left in a detached HEAD state at this commit.\n- `username` _str | None_ - Git username for authentication.\n- `password` _str | None_ - Git password or token for authentication.\n  \n\n**Example**:\n\n```python\n# Clone the default branch\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# Clone a specific branch with authentication\nsandbox.git.clone(\n    url=\"https://github.com/user/private-repo.git\",\n    path=\"workspace/private\",\n    branch=\"develop\",\n    username=\"user\",\n    password=\"token\"\n)\n\n# Clone a specific commit\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo-old\",\n    commit_id=\"abc123\"\n)\n```\n\n#### Git.commit\n\n```python\n@intercept_errors(message_prefix=\"Failed to commit changes: \")\n@with_instrumentation()\ndef commit(path: str,\n           message: str,\n           author: str,\n           email: str,\n           allow_empty: bool = False) -> GitCommitResponse\n```\n\nCreates a new commit with the staged changes. Make sure to stage\nchanges using the add() method before committing.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `message` _str_ - Commit message describing the changes.\n- `author` _str_ - Name of the commit author.\n- `email` _str_ - Email address of the commit author.\n- `allow_empty` _bool, optional_ - Allow creating an empty commit when no changes are staged. Defaults to False.\n  \n\n**Example**:\n\n```python\n# Stage and commit changes\nsandbox.git.add(\"workspace/repo\", [\"README.md\"])\nsandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update documentation\",\n    author=\"John Doe\",\n    email=\"john@example.com\",\n    allow_empty=True\n)\n```\n\n#### Git.push\n\n```python\n@intercept_errors(message_prefix=\"Failed to push changes: \")\n@with_instrumentation()\ndef push(path: str,\n         username: str | None = None,\n         password: str | None = None) -> None\n```\n\nPushes all local commits on the current branch to the remote\nrepository. If the remote repository requires authentication, provide\nusername and password/token.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `username` _str | None_ - Git username for authentication.\n- `password` _str | None_ - Git password or token for authentication.\n  \n\n**Example**:\n\n```python\n# Push without authentication (for public repos or SSH)\nsandbox.git.push(\"workspace/repo\")\n\n# Push with authentication\nsandbox.git.push(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n#### Git.pull\n\n```python\n@intercept_errors(message_prefix=\"Failed to pull changes: \")\n@with_instrumentation()\ndef pull(path: str,\n         username: str | None = None,\n         password: str | None = None) -> None\n```\n\nPulls changes from the remote repository. If the remote repository requires authentication,\nprovide username and password/token.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `username` _str | None_ - Git username for authentication.\n- `password` _str | None_ - Git password or token for authentication.\n  \n\n**Example**:\n\n```python\n# Pull without authentication\nsandbox.git.pull(\"workspace/repo\")\n\n# Pull with authentication\nsandbox.git.pull(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n#### Git.status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get status: \")\n@with_instrumentation()\ndef status(path: str) -> GitStatus\n```\n\nGets the current Git repository status.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n  \n\n**Returns**:\n\n- `GitStatus` - Repository status information including:\n  - current_branch: Current branch name\n  - file_status: List of file statuses\n  - ahead: Number of local commits not pushed to remote\n  - behind: Number of remote commits not pulled locally\n  - branch_published: Whether the branch has been published to the remote repository\n  \n\n**Example**:\n\n```python\nstatus = sandbox.git.status(\"workspace/repo\")\nprint(f\"On branch: {status.current_branch}\")\nprint(f\"Commits ahead: {status.ahead}\")\nprint(f\"Commits behind: {status.behind}\")\n```\n\n#### Git.checkout\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to checkout branch: \")\n@with_instrumentation()\ndef checkout_branch(path: str, branch: str) -> None\n```\n\nCheckout branch in the repository.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `branch` _str_ - Name of the branch to checkout\n  \n\n**Example**:\n\n```python\n# Checkout a branch\nsandbox.git.checkout_branch(\"workspace/repo\", \"feature-branch\")\n```\n\n#### Git.create\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to create branch: \")\n@with_instrumentation()\ndef create_branch(path: str, name: str) -> None\n```\n\nCreate branch in the repository.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `name` _str_ - Name of the new branch to create\n  \n\n**Example**:\n\n```python\n# Create a new branch\nsandbox.git.create_branch(\"workspace/repo\", \"new-feature\")\n```\n\n#### Git.delete\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete branch: \")\n@with_instrumentation()\ndef delete_branch(path: str, name: str) -> None\n```\n\nDelete branch in the repository.\n\n**Arguments**:\n\n- `path` _str_ - Path to the Git repository root. Relative paths are resolved based on\n  the sandbox working directory.\n- `name` _str_ - Name of the branch to delete\n  \n\n**Example**:\n\n```python\n# Delete a branch\nsandbox.git.delete_branch(\"workspace/repo\", \"old-feature\")\n```\n\n\n## GitCommitResponse\n\n```python\nclass GitCommitResponse()\n```\n\nResponse from the git commit.\n\n**Attributes**:\n\n- `sha` _str_ - The SHA of the commit\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/lsp-server.mdx",
    "content": "---\ntitle: \"LspServer\"\nhideTitleOnPage: true\n---\n\n## LspServer\n\n```python\nclass LspServer()\n```\n\nProvides Language Server Protocol functionality for code intelligence to provide\nIDE-like features such as code completion, symbol search, and more.\n\n#### LspServer.\\_\\_init\\_\\_\n\n```python\ndef __init__(language_id: LspLanguageId | LspLanguageIdLiteral,\n             path_to_project: str, api_client: LspApi)\n```\n\nInitializes a new LSP server instance.\n\n**Arguments**:\n\n- `language_id` _LspLanguageId | LspLanguageIdLiteral_ - The language server type\n  (e.g., LspLanguageId.TYPESCRIPT).\n- `path_to_project` _str_ - Absolute path to the project root directory.\n- `api_client` _LspApi_ - API client for Sandbox operations.\n\n#### LspServer.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start LSP server: \")\n@with_instrumentation()\ndef start() -> None\n```\n\nStarts the language server.\n\nThis method must be called before using any other LSP functionality.\nIt initializes the language server for the specified language and project.\n\n**Example**:\n\n```python\nlsp = sandbox.create_lsp_server(\"typescript\", \"workspace/project\")\nlsp.start()  # Initialize the server\n# Now ready for LSP operations\n```\n\n#### LspServer.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop LSP server: \")\n@with_instrumentation()\ndef stop() -> None\n```\n\nStops the language server.\n\nThis method should be called when the LSP server is no longer needed to\nfree up system resources.\n\n**Example**:\n\n```python\n# When done with LSP features\nlsp.stop()  # Clean up resources\n```\n\n#### LspServer.did\\_open\n\n```python\n@intercept_errors(message_prefix=\"Failed to open file: \")\n@with_instrumentation()\ndef did_open(path: str) -> None\n```\n\nNotifies the language server that a file has been opened.\n\nThis method should be called when a file is opened in the editor to enable\nlanguage features like diagnostics and completions for that file. The server\nwill begin tracking the file's contents and providing language features.\n\n**Arguments**:\n\n- `path` _str_ - Path to the opened file. Relative paths are resolved based on the project path\n  set in the LSP server constructor.\n  \n\n**Example**:\n\n```python\n# When opening a file for editing\nlsp.did_open(\"workspace/project/src/index.ts\")\n# Now can get completions, symbols, etc. for this file\n```\n\n#### LspServer.did\\_close\n\n```python\n@intercept_errors(message_prefix=\"Failed to close file: \")\n@with_instrumentation()\ndef did_close(path: str) -> None\n```\n\nNotify the language server that a file has been closed.\n\nThis method should be called when a file is closed in the editor to allow\nthe language server to clean up any resources associated with that file.\n\n**Arguments**:\n\n- `path` _str_ - Path to the closed file. Relative paths are resolved based on the project path\n  set in the LSP server constructor.\n  \n\n**Example**:\n\n```python\n# When done editing a file\nlsp.did_close(\"workspace/project/src/index.ts\")\n```\n\n#### LspServer.document\\_symbols\n\n```python\n@intercept_errors(message_prefix=\"Failed to get symbols from document: \")\n@with_instrumentation()\ndef document_symbols(path: str) -> list[LspSymbol]\n```\n\nGets symbol information (functions, classes, variables, etc.) from a document.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file to get symbols from. Relative paths are resolved based on the project path\n  set in the LSP server constructor.\n  \n\n**Returns**:\n\n- `list[LspSymbol]` - List of symbols in the document. Each symbol includes:\n  - name: The symbol's name\n  - kind: The symbol's kind (function, class, variable, etc.)\n  - location: The location of the symbol in the file\n  \n\n**Example**:\n\n```python\n# Get all symbols in a file\nsymbols = lsp.document_symbols(\"workspace/project/src/index.ts\")\nfor symbol in symbols:\n    print(f\"{symbol.kind} {symbol.name}: {symbol.location}\")\n```\n\n#### LspServer.workspace\\_symbols\n\n```python\n@deprecated(\n    reason=\n    \"Method is deprecated. Use `sandbox_symbols` instead. This method will be removed in a future version.\"\n)\n@with_instrumentation()\ndef workspace_symbols(query: str) -> list[LspSymbol]\n```\n\nSearches for symbols matching the query string across all files\nin the Sandbox.\n\n**Arguments**:\n\n- `query` _str_ - Search query to match against symbol names.\n  \n\n**Returns**:\n\n- `list[LspSymbol]` - List of matching symbols from all files.\n\n#### LspServer.sandbox\\_symbols\n\n```python\n@intercept_errors(message_prefix=\"Failed to get symbols from sandbox: \")\n@with_instrumentation()\ndef sandbox_symbols(query: str) -> list[LspSymbol]\n```\n\nSearches for symbols matching the query string across all files\nin the Sandbox.\n\n**Arguments**:\n\n- `query` _str_ - Search query to match against symbol names.\n  \n\n**Returns**:\n\n- `list[LspSymbol]` - List of matching symbols from all files. Each symbol\n  includes:\n  - name: The symbol's name\n  - kind: The symbol's kind (function, class, variable, etc.)\n  - location: The location of the symbol in the file\n  \n\n**Example**:\n\n```python\n# Search for all symbols containing \"User\"\nsymbols = lsp.sandbox_symbols(\"User\")\nfor symbol in symbols:\n    print(f\"{symbol.name} in {symbol.location}\")\n```\n\n#### LspServer.completions\n\n```python\n@intercept_errors(message_prefix=\"Failed to get completions: \")\n@with_instrumentation()\ndef completions(path: str, position: LspCompletionPosition) -> CompletionList\n```\n\nGets completion suggestions at a position in a file.\n\n**Arguments**:\n\n- `path` _str_ - Path to the file. Relative paths are resolved based on the project path\n  set in the LSP server constructor.\n- `position` _LspCompletionPosition_ - Cursor position to get completions for.\n  \n\n**Returns**:\n\n- `CompletionList` - List of completion suggestions. The list includes:\n  - isIncomplete: Whether more items might be available\n  - items: List of completion items, each containing:\n  - label: The text to insert\n  - kind: The kind of completion\n  - detail: Additional details about the item\n  - documentation: Documentation for the item\n  - sortText: Text used to sort the item in the list\n  - filterText: Text used to filter the item\n  - insertText: The actual text to insert (if different from label)\n  \n\n**Example**:\n\n```python\n# Get completions at a specific position\npos = LspCompletionPosition(line=10, character=15)\ncompletions = lsp.completions(\"workspace/project/src/index.ts\", pos)\nfor item in completions.items:\n    print(f\"{item.label} ({item.kind}): {item.detail}\")\n```\n\n\n## LspLanguageId\n\n```python\nclass LspLanguageId(str, Enum)\n```\n\nLanguage IDs for Language Server Protocol (LSP).\n\n**Enum Members**:\n    - `PYTHON` (\"python\")\n    - `TYPESCRIPT` (\"typescript\")\n    - `JAVASCRIPT` (\"javascript\")\n\n## LspCompletionPosition\n\n```python\n@dataclass\nclass LspCompletionPosition()\n```\n\nRepresents a zero-based completion position in a text document,\nspecified by line number and character offset.\n\n**Attributes**:\n\n- `line` _int_ - Zero-based line number in the document.\n- `character` _int_ - Zero-based character offset on the line.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/object-storage.mdx",
    "content": "---\ntitle: \"ObjectStorage\"\nhideTitleOnPage: true\n---\n\n## ObjectStorage\n\n```python\nclass ObjectStorage()\n```\n\nObjectStorage class for interacting with object storage services.\n\n**Attributes**:\n\n- `endpoint_url` _str_ - The endpoint URL for the object storage service.\n- `aws_access_key_id` _str_ - The access key ID for the object storage service.\n- `aws_secret_access_key` _str_ - The secret access key for the object storage service.\n- `aws_session_token` _str_ - The session token for the object storage service. Used for temporary credentials.\n- `bucket_name` _str_ - The name of the bucket to use. Defaults to \"daytona-volume-builds\".\n\n#### ObjectStorage.upload\n\n```python\n@with_instrumentation()\ndef upload(path: str,\n           organization_id: str,\n           archive_base_path: str | None = None) -> str\n```\n\nUploads a file to the object storage service.\n\n**Arguments**:\n\n- `path` _str_ - The path to the file to upload.\n- `organization_id` _str_ - The organization ID to use.\n- `archive_base_path` _str_ - The base path to use for the archive.\n  \n\n**Returns**:\n\n- `str` - The hash of the uploaded file.\n\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/process.mdx",
    "content": "---\ntitle: \"Process\"\nhideTitleOnPage: true\n---\n\n## Process\n\n```python\nclass Process()\n```\n\nHandles process and code execution within a Sandbox.\n\n#### Process.\\_\\_init\\_\\_\n\n```python\ndef __init__(code_toolbox: SandboxCodeToolbox, api_client: ProcessApi)\n```\n\nInitialize a new Process instance.\n\n**Arguments**:\n\n- `code_toolbox` _SandboxCodeToolbox_ - Language-specific code execution toolbox.\n- `api_client` _ProcessApi_ - API client for process operations.\n\n#### Process.exec\n\n```python\n@intercept_errors(message_prefix=\"Failed to execute command: \")\n@with_instrumentation()\ndef exec(command: str,\n         cwd: str | None = None,\n         env: dict[str, str] | None = None,\n         timeout: int | None = None) -> ExecuteResponse\n```\n\nExecute a shell command in the Sandbox.\n\n**Arguments**:\n\n- `command` _str_ - Shell command to execute.\n- `cwd` _str | None_ - Working directory for command execution. If not\n  specified, uses the sandbox working directory.\n- `env` _dict[str, str] | None_ - Environment variables to set for the command.\n- `timeout` _int | None_ - Maximum time in seconds to wait for the command\n  to complete. 0 means wait indefinitely.\n  \n\n**Returns**:\n\n- `ExecuteResponse` - Command execution results containing:\n  - exit_code: The command's exit status\n  - result: Standard output from the command\n  - artifacts: ExecutionArtifacts object containing `stdout` (same as result)\n  and `charts` (matplotlib charts metadata)\n  \n\n**Example**:\n\n```python\n# Simple command\nresponse = sandbox.process.exec(\"echo 'Hello'\")\nprint(response.artifacts.stdout)  # Prints: Hello\n\n# Command with working directory\nresult = sandbox.process.exec(\"ls\", cwd=\"workspace/src\")\n\n# Command with timeout\nresult = sandbox.process.exec(\"sleep 10\", timeout=5)\n```\n\n#### Process.code\\_run\n\n```python\n@with_instrumentation()\ndef code_run(code: str,\n             params: CodeRunParams | None = None,\n             timeout: int | None = None) -> ExecuteResponse\n```\n\nExecutes code in the Sandbox using the appropriate language runtime.\n\n**Arguments**:\n\n- `code` _str_ - Code to execute.\n- `params` _CodeRunParams | None_ - Parameters for code execution.\n- `timeout` _int | None_ - Maximum time in seconds to wait for the code\n  to complete. 0 means wait indefinitely.\n  \n\n**Returns**:\n\n- `ExecuteResponse` - Code execution result containing:\n  - exit_code: The execution's exit status\n  - result: Standard output from the code\n  - artifacts: ExecutionArtifacts object containing `stdout` (same as result)\n  and `charts` (matplotlib charts metadata)\n  \n\n**Example**:\n\n```python\n# Run Python code\nresponse = sandbox.process.code_run('''\n    x = 10\n    y = 20\n    print(f\"Sum: {x + y}\")\n''')\nprint(response.artifacts.stdout)  # Prints: Sum: 30\n```\n  \n  Matplotlib charts are automatically detected and returned in the `charts` field\n  of the `ExecutionArtifacts` object.\n```python\ncode = '''\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nx = np.linspace(0, 10, 30)\ny = np.sin(x)\n\nplt.figure(figsize=(8, 5))\nplt.plot(x, y, 'b-', linewidth=2)\nplt.title('Line Chart')\nplt.xlabel('X-axis (seconds)')\nplt.ylabel('Y-axis (amplitude)')\nplt.grid(True)\nplt.show()\n'''\n\nresponse = sandbox.process.code_run(code)\nchart = response.artifacts.charts[0]\n\nprint(f\"Type: {chart.type}\")\nprint(f\"Title: {chart.title}\")\nif chart.type == ChartType.LINE and isinstance(chart, LineChart):\n    print(f\"X Label: {chart.x_label}\")\n    print(f\"Y Label: {chart.y_label}\")\n    print(f\"X Ticks: {chart.x_ticks}\")\n    print(f\"X Tick Labels: {chart.x_tick_labels}\")\n    print(f\"X Scale: {chart.x_scale}\")\n    print(f\"Y Ticks: {chart.y_ticks}\")\n    print(f\"Y Tick Labels: {chart.y_tick_labels}\")\n    print(f\"Y Scale: {chart.y_scale}\")\n    print(\"Elements:\")\n    for element in chart.elements:\n        print(f\"Label: {element.label}\")\n        print(f\"Points: {element.points}\")\n```\n\n#### Process.create\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to create session: \")\n@with_instrumentation()\ndef create_session(session_id: str) -> None\n```\n\nCreates a new long-running background session in the Sandbox.\n\nSessions are background processes that maintain state between commands, making them ideal for\nscenarios requiring multiple related commands or persistent environment setup. You can run\nlong-running commands and monitor process status.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier for the new session.\n  \n\n**Example**:\n\n```python\n# Create a new session\nsession_id = \"my-session\"\nsandbox.process.create_session(session_id)\nsession = sandbox.process.get_session(session_id)\n# Do work...\nsandbox.process.delete_session(session_id)\n```\n\n#### Process.get\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session: \")\ndef get_session(session_id: str) -> Session\n```\n\nGets a session in the Sandbox.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session to retrieve.\n  \n\n**Returns**:\n\n- `Session` - Session information including:\n  - session_id: The session's unique identifier\n  - commands: List of commands executed in the session\n  \n\n**Example**:\n\n```python\nsession = sandbox.process.get_session(\"my-session\")\nfor cmd in session.commands:\n    print(f\"Command: {cmd.command}\")\n```\n\n#### Process.get\\_entrypoint\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to get sandbox entrypoint session: \")\ndef get_entrypoint_session() -> Session\n```\n\nGets the sandbox entrypoint session.\n\n**Returns**:\n\n- `Session` - Entrypoint session information including:\n  - session_id: The entrypoint session's unique identifier\n  - commands: List of commands executed in the entrypoint session\n  \n\n**Example**:\n\n```python\nsession = sandbox.process.get_entrypoint_session()\nfor cmd in session.commands:\n    print(f\"Command: {cmd.command}\")\n```\n\n#### Process.get\\_session\\_command\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command: \")\n@with_instrumentation()\ndef get_session_command(session_id: str, command_id: str) -> Command\n```\n\nGets information about a specific command executed in a session.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session.\n- `command_id` _str_ - Unique identifier of the command.\n  \n\n**Returns**:\n\n- `Command` - Command information including:\n  - id: The command's unique identifier\n  - command: The executed command string\n  - exit_code: Command's exit status (if completed)\n  \n\n**Example**:\n\n```python\ncmd = sandbox.process.get_session_command(\"my-session\", \"cmd-123\")\nif cmd.exit_code == 0:\n    print(f\"Command {cmd.command} completed successfully\")\n```\n\n#### Process.execute\\_session\\_command\n\n```python\n@intercept_errors(message_prefix=\"Failed to execute session command: \")\n@with_instrumentation()\ndef execute_session_command(\n        session_id: str,\n        req: SessionExecuteRequest,\n        timeout: int | None = None) -> SessionExecuteResponse\n```\n\nExecutes a command in the session.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session to use.\n- `req` _SessionExecuteRequest_ - Command execution request containing:\n  - command: The command to execute\n  - run_async: Whether to execute asynchronously\n  \n\n**Returns**:\n\n- `SessionExecuteResponse` - Command execution results containing:\n  - cmd_id: Unique identifier for the executed command\n  - output: Combined command output (stdout and stderr) (if synchronous execution)\n  - stdout: Standard output from the command\n  - stderr: Standard error from the command\n  - exit_code: Command exit status (if synchronous execution)\n  \n\n**Example**:\n\n```python\n# Execute commands in sequence, maintaining state\nsession_id = \"my-session\"\n\n# Change directory\nreq = SessionExecuteRequest(command=\"cd /workspace\")\nsandbox.process.execute_session_command(session_id, req)\n\n# Create a file\nreq = SessionExecuteRequest(command=\"echo 'Hello' > test.txt\")\nsandbox.process.execute_session_command(session_id, req)\n\n# Read the file\nreq = SessionExecuteRequest(command=\"cat test.txt\")\nresult = sandbox.process.execute_session_command(session_id, req)\nprint(f\"Command stdout: {result.stdout}\")\nprint(f\"Command stderr: {result.stderr}\")\n```\n\n#### Process.get\\_session\\_command\\_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command logs: \")\n@with_instrumentation()\ndef get_session_command_logs(session_id: str,\n                             command_id: str) -> SessionCommandLogsResponse\n```\n\nGet the logs for a command executed in a session.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session.\n- `command_id` _str_ - Unique identifier of the command.\n  \n\n**Returns**:\n\n- `SessionCommandLogsResponse` - Command logs including:\n  - output: Combined command output (stdout and stderr)\n  - stdout: Standard output from the command\n  - stderr: Standard error from the command\n  \n\n**Example**:\n\n```python\nlogs = sandbox.process.get_session_command_logs(\n    \"my-session\",\n    \"cmd-123\"\n)\nprint(f\"Command stdout: {logs.stdout}\")\nprint(f\"Command stderr: {logs.stderr}\")\n```\n\n#### Process.get\\_session\\_command\\_logs\\_async\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command logs: \")\nasync def get_session_command_logs_async(\n        session_id: str, command_id: str, on_stdout: OutputHandler[str],\n        on_stderr: OutputHandler[str]) -> None\n```\n\nAsynchronously retrieves and processes the logs for a command executed in a session as they become available.\n\nAccepts both sync and async callbacks. Async callbacks are awaited.\nBlocking synchronous operations inside callbacks may cause WebSocket\ndisconnections — use async callbacks and async libraries to avoid this.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session.\n- `command_id` _str_ - Unique identifier of the command.\n- `on_stdout` _OutputHandler[str]_ - Callback function to handle stdout log chunks as they arrive.\n- `on_stderr` _OutputHandler[str]_ - Callback function to handle stderr log chunks as they arrive.\n  \n\n**Example**:\n\n```python\nawait sandbox.process.get_session_command_logs_async(\n    \"my-session\",\n    \"cmd-123\",\n    lambda log: print(f\"[STDOUT]: {log}\"),\n    lambda log: print(f\"[STDERR]: {log}\"),\n)\n```\n\n#### Process.get\\_entrypoint\\_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get entrypoint logs: \")\n@with_instrumentation()\ndef get_entrypoint_logs() -> SessionCommandLogsResponse\n```\n\nGet the logs for the entrypoint session.\n\n**Returns**:\n\n- `SessionCommandLogsResponse` - Command logs including:\n  - output: Combined command output (stdout and stderr)\n  - stdout: Standard output from the command\n  - stderr: Standard error from the command\n  \n\n**Example**:\n\n```python\nlogs = sandbox.process.get_entrypoint_logs()\nprint(f\"Command stdout: {logs.stdout}\")\nprint(f\"Command stderr: {logs.stderr}\")\n```\n\n#### Process.get\\_entrypoint\\_logs\\_async\n\n```python\n@intercept_errors(message_prefix=\"Failed to get entrypoint logs: \")\nasync def get_entrypoint_logs_async(on_stdout: OutputHandler[str],\n                                    on_stderr: OutputHandler[str]) -> None\n```\n\nAsynchronously retrieves and processes the logs for the entrypoint session as they become available.\n\n**Arguments**:\n\n  on_stdout OutputHandler[str]: Callback function to handle stdout log chunks as they arrive.\n  on_stderr OutputHandler[str]: Callback function to handle stderr log chunks as they arrive.\n  \n\n**Example**:\n\n```python\nawait sandbox.process.get_entrypoint_logs_async(\n    lambda log: print(f\"[STDOUT]: {log}\"),\n    lambda log: print(f\"[STDERR]: {log}\"),\n)\n```\n\n#### Process.send\\_session\\_command\\_input\n\n```python\n@intercept_errors(message_prefix=\"Failed to send session command input: \")\ndef send_session_command_input(session_id: str, command_id: str,\n                               data: str) -> None\n```\n\nSends input data to a command executed in a session.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session.\n- `command_id` _str_ - Unique identifier of the command.\n- `data` _str_ - Input data to send.\n\n#### Process.list\\_sessions\n\n```python\n@intercept_errors(message_prefix=\"Failed to list sessions: \")\n@with_instrumentation()\ndef list_sessions() -> list[Session]\n```\n\nLists all sessions in the Sandbox.\n\n**Returns**:\n\n- `list[Session]` - List of all sessions in the Sandbox.\n  \n\n**Example**:\n\n```python\nsessions = sandbox.process.list_sessions()\nfor session in sessions:\n    print(f\"Session {session.session_id}:\")\n    print(f\"  Commands: {len(session.commands)}\")\n```\n\n#### Process.delete\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete session: \")\n@with_instrumentation()\ndef delete_session(session_id: str) -> None\n```\n\nTerminates and removes a session from the Sandbox, cleaning up any resources\nassociated with it.\n\n**Arguments**:\n\n- `session_id` _str_ - Unique identifier of the session to delete.\n  \n\n**Example**:\n\n```python\n# Create and use a session\nsandbox.process.create_session(\"temp-session\")\n# ... use the session ...\n\n# Clean up when done\nsandbox.process.delete_session(\"temp-session\")\n```\n\n#### Process.create\\_pty\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to create PTY session: \")\n@with_instrumentation()\ndef create_pty_session(id: str,\n                       cwd: str | None = None,\n                       envs: dict[str, str] | None = None,\n                       pty_size: PtySize | None = None) -> PtyHandle\n```\n\nCreates a new PTY (pseudo-terminal) session in the Sandbox.\n\nCreates an interactive terminal session that can execute commands and handle user input.\nThe PTY session behaves like a real terminal, supporting features like command history.\n\n**Arguments**:\n\n- `id` - Unique identifier for the PTY session. Must be unique within the Sandbox.\n- `cwd` - Working directory for the PTY session. Defaults to the sandbox's working directory.\n- `env` - Environment variables to set in the PTY session. These will be merged with\n  the Sandbox's default environment variables.\n- `pty_size` - Terminal size configuration. Defaults to 80x24 if not specified.\n  \n\n**Returns**:\n\n- `PtyHandle` - Handle for managing the created PTY session. Use this to send input,\n  receive output, resize the terminal, and manage the session lifecycle.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session creation fails or the session ID is already in use.\n\n#### Process.connect\\_pty\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to connect PTY session: \")\n@with_instrumentation()\ndef connect_pty_session(session_id: str) -> PtyHandle\n```\n\nConnects to an existing PTY session in the Sandbox.\n\nEstablishes a WebSocket connection to an existing PTY session, allowing you to\ninteract with a previously created terminal session.\n\n**Arguments**:\n\n- `session_id` - Unique identifier of the PTY session to connect to.\n  \n\n**Returns**:\n\n- `PtyHandle` - Handle for managing the connected PTY session.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session doesn't exist or connection fails.\n\n#### Process.list\\_pty\\_sessions\n\n```python\n@intercept_errors(message_prefix=\"Failed to list PTY sessions: \")\n@with_instrumentation()\ndef list_pty_sessions() -> list[PtySessionInfo]\n```\n\nLists all PTY sessions in the Sandbox.\n\nRetrieves information about all PTY sessions in this Sandbox.\n\n**Returns**:\n\n- `list[PtySessionInfo]` - List of PTY session information objects containing\n  details about each session's state, creation time, and configuration.\n  \n\n**Example**:\n\n```python\n# List all PTY sessions\nsessions = sandbox.process.list_pty_sessions()\n\nfor session in sessions:\n    print(f\"Session ID: {session.id}\")\n    print(f\"Active: {session.active}\")\n    print(f\"Created: {session.created_at}\")\n```\n\n#### Process.get\\_pty\\_session\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get PTY session info: \")\n@with_instrumentation()\ndef get_pty_session_info(session_id: str) -> PtySessionInfo\n```\n\nGets detailed information about a specific PTY session.\n\nRetrieves comprehensive information about a PTY session including its current state,\nconfiguration, and metadata.\n\n**Arguments**:\n\n- `session_id` - Unique identifier of the PTY session to retrieve information for.\n  \n\n**Returns**:\n\n- `PtySessionInfo` - Detailed information about the PTY session including ID, state,\n  creation time, working directory, environment variables, and more.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session doesn't exist.\n  \n\n**Example**:\n\n```python\n# Get details about a specific PTY session\nsession_info = sandbox.process.get_pty_session_info(\"my-session\")\n\nprint(f\"Session ID: {session_info.id}\")\nprint(f\"Active: {session_info.active}\")\nprint(f\"Working Directory: {session_info.cwd}\")\nprint(f\"Terminal Size: {session_info.cols}x{session_info.rows}\")\n```\n\n#### Process.kill\\_pty\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to kill PTY session: \")\n@with_instrumentation()\ndef kill_pty_session(session_id: str) -> None\n```\n\nKills a PTY session and terminates its associated process.\n\nForcefully terminates the PTY session and cleans up all associated resources.\nThis will close any active connections and kill the underlying shell process.\nThis operation is irreversible. Any unsaved work in the terminal session will be lost.\n\n**Arguments**:\n\n- `session_id` - Unique identifier of the PTY session to kill.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session doesn't exist or cannot be killed.\n  \n\n**Example**:\n\n```python\n# Kill a specific PTY session\nsandbox.process.kill_pty_session(\"my-session\")\n\n# Verify the session no longer exists\npty_sessions = sandbox.process.list_pty_sessions()\nfor pty_session in pty_sessions:\n    print(f\"PTY session: {pty_session.id}\")\n```\n\n#### Process.resize\\_pty\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to resize PTY session: \")\n@with_instrumentation()\ndef resize_pty_session(session_id: str, pty_size: PtySize) -> PtySessionInfo\n```\n\nResizes a PTY session's terminal dimensions.\n\nChanges the terminal size of an active PTY session. This is useful when the\nclient terminal is resized or when you need to adjust the display for different\noutput requirements.\n\n**Arguments**:\n\n- `session_id` - Unique identifier of the PTY session to resize.\n- `pty_size` - New terminal dimensions containing the desired columns and rows.\n  \n\n**Returns**:\n\n- `PtySessionInfo` - Updated session information reflecting the new terminal size.\n  \n\n**Raises**:\n\n- `DaytonaError` - If the PTY session doesn't exist or resize operation fails.\n  \n\n**Example**:\n\n```python\nfrom daytona.common.pty import PtySize\n\n# Resize a PTY session to a larger terminal\nnew_size = PtySize(rows=40, cols=150)\nupdated_info = sandbox.process.resize_pty_session(\"my-session\", new_size)\n\nprint(f\"Terminal resized to {updated_info.cols}x{updated_info.rows}\")\n\n# You can also use the PtyHandle's resize method\npty_handle.resize(new_size)\n```\n\n\n## CodeRunParams\n\n```python\n@dataclass\nclass CodeRunParams()\n```\n\nParameters for code execution.\n\n**Attributes**:\n\n- `argv` _list[str] | None_ - Command line arguments\n- `env` _dict[str, str] | None_ - Environment variables\n\n## SessionExecuteRequest\n\n```python\nclass SessionExecuteRequest(ApiSessionExecuteRequest,\n                            AsyncApiSessionExecuteRequest)\n```\n\nContains the request for executing a command in a session.\n\n**Attributes**:\n\n- `command` _str_ - The command to execute.\n- `run_async` _bool | None_ - Whether to execute the command asynchronously.\n- `var_async` _bool | None_ - Deprecated. Use `run_async` instead.\n- `suppress_input_echo` _bool | None_ - Whether to suppress input echo. Default is `False`.\n\n## ExecutionArtifacts\n\n```python\n@dataclass\nclass ExecutionArtifacts()\n```\n\nArtifacts from the command execution.\n\n**Attributes**:\n\n- `stdout` _str_ - Standard output from the command, same as `result` in `ExecuteResponse`\n- `charts` _list[Chart] | None_ - List of chart metadata from matplotlib\n\n## ExecuteResponse\n\n```python\nclass ExecuteResponse(BaseModel)\n```\n\nResponse from the command execution.\n\n**Attributes**:\n\n- `exit_code` _int_ - The exit code from the command execution\n- `result` _str_ - The output from the command execution\n- `artifacts` _ExecutionArtifacts | None_ - Artifacts from the command execution\n\n## SessionExecuteResponse\n\n```python\nclass SessionExecuteResponse(ApiSessionExecuteResponse)\n```\n\nResponse from the session command execution.\n\n**Attributes**:\n\n- `cmd_id` _str_ - The ID of the executed command\n- `stdout` _str | None_ - The stdout from the command execution\n- `stderr` _str | None_ - The stderr from the command execution\n- `output` _str_ - The output from the command execution\n- `exit_code` _int_ - The exit code from the command execution\n\n## SessionCommandLogsResponse\n\n```python\n@dataclass\nclass SessionCommandLogsResponse()\n```\n\nResponse from the command logs.\n\n**Attributes**:\n\n- `output` _str | None_ - The combined output from the command\n- `stdout` _str | None_ - The stdout from the command\n- `stderr` _str | None_ - The stderr from the command\n\n#### parse\\_session\\_command\\_logs\n\n```python\ndef parse_session_command_logs(data: bytes) -> SessionCommandLogsResponse\n```\n\nParse combined stdout/stderr output into separate streams.\n\n**Arguments**:\n\n- `data` - Combined log bytes with STDOUT_PREFIX and STDERR_PREFIX markers\n  \n\n**Returns**:\n\n  SessionCommandLogsResponse with separated stdout and stderr\n\n#### demux\\_log\n\n```python\ndef demux_log(data: bytes) -> tuple[bytes, bytes]\n```\n\nDemultiplex combined stdout/stderr log data.\n\n**Arguments**:\n\n- `data` - Combined log bytes with STDOUT_PREFIX and STDERR_PREFIX markers\n  \n\n**Returns**:\n\n  Tuple of (stdout_bytes, stderr_bytes)\n\n##### OutputHandler\n\n```python\nOutputHandler = Union[\n    Callable[[T], None],\n    Callable[[T], Awaitable[None]],\n]\n```\n\nCallback type that accepts both sync and async handlers.\n\nBlocking synchronous operations inside handlers may cause WebSocket disconnections.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/sandbox.mdx",
    "content": "---\ntitle: \"Sandbox\"\nhideTitleOnPage: true\n---\n\n## Sandbox\n\n```python\nclass Sandbox(SandboxDto)\n```\n\nRepresents a Daytona Sandbox.\n\n**Attributes**:\n\n- `fs` _FileSystem_ - File system operations interface.\n- `git` _Git_ - Git operations interface.\n- `process` _Process_ - Process execution interface.\n- `computer_use` _ComputerUse_ - Computer use operations interface for desktop automation.\n- `code_interpreter` _CodeInterpreter_ - Stateful interpreter interface for executing code.\n  Currently supports only Python. For other languages, use the `process.code_run` interface.\n- `id` _str_ - Unique identifier for the Sandbox.\n- `name` _str_ - Name of the Sandbox.\n- `organization_id` _str_ - Organization ID of the Sandbox.\n- `snapshot` _str_ - Daytona snapshot used to create the Sandbox.\n- `user` _str_ - OS user running in the Sandbox.\n- `env` _dict[str, str]_ - Environment variables set in the Sandbox.\n- `labels` _dict[str, str]_ - Custom labels attached to the Sandbox.\n- `public` _bool_ - Whether the Sandbox is publicly accessible.\n- `target` _str_ - Target location of the runner where the Sandbox runs.\n- `cpu` _int_ - Number of CPUs allocated to the Sandbox.\n- `gpu` _int_ - Number of GPUs allocated to the Sandbox.\n- `memory` _int_ - Amount of memory allocated to the Sandbox in GiB.\n- `disk` _int_ - Amount of disk space allocated to the Sandbox in GiB.\n- `state` _SandboxState_ - Current state of the Sandbox (e.g., \"started\", \"stopped\").\n- `error_reason` _str_ - Error message if Sandbox is in error state.\n- `recoverable` _bool_ - Whether the Sandbox error is recoverable.\n- `backup_state` _SandboxBackupStateEnum_ - Current state of Sandbox backup.\n- `backup_created_at` _str_ - When the backup was created.\n- `auto_stop_interval` _int_ - Auto-stop interval in minutes.\n- `auto_archive_interval` _int_ - Auto-archive interval in minutes.\n- `auto_delete_interval` _int_ - Auto-delete interval in minutes.\n- `volumes` _list[str]_ - Volumes attached to the Sandbox.\n- `build_info` _str_ - Build information for the Sandbox if it was created from dynamic build.\n- `created_at` _str_ - When the Sandbox was created.\n- `updated_at` _str_ - When the Sandbox was last updated.\n- `network_block_all` _bool_ - Whether to block all network access for the Sandbox.\n- `network_allow_list` _str_ - Comma-separated list of allowed CIDR network addresses for the Sandbox.\n\n#### Sandbox.\\_\\_init\\_\\_\n\n```python\ndef __init__(sandbox_dto: SandboxDto, toolbox_api: ApiClient,\n             sandbox_api: SandboxApi, code_toolbox: SandboxCodeToolbox)\n```\n\nInitialize a new Sandbox instance.\n\n**Arguments**:\n\n- `sandbox_dto` _SandboxDto_ - The sandbox data from the API.\n- `toolbox_api` _ApiClient_ - API client for toolbox operations.\n- `sandbox_api` _SandboxApi_ - API client for Sandbox operations.\n- `code_toolbox` _SandboxCodeToolbox_ - Language-specific toolbox implementation.\n\n#### Sandbox.refresh\\_data\n\n```python\n@intercept_errors(message_prefix=\"Failed to refresh sandbox data: \")\n@with_instrumentation()\ndef refresh_data() -> None\n```\n\nRefreshes the Sandbox data from the API.\n\n**Example**:\n\n```python\nsandbox.refresh_data()\nprint(f\"Sandbox {sandbox.id}:\")\nprint(f\"State: {sandbox.state}\")\nprint(f\"Resources: {sandbox.cpu} CPU, {sandbox.memory} GiB RAM\")\n```\n\n#### Sandbox.get\\_user\\_home\\_dir\n\n```python\n@intercept_errors(message_prefix=\"Failed to get user home directory: \")\n@with_instrumentation()\ndef get_user_home_dir() -> str\n```\n\nGets the user's home directory path inside the Sandbox.\n\n**Returns**:\n\n- `str` - The absolute path to the user's home directory inside the Sandbox.\n  \n\n**Example**:\n\n```python\nuser_home_dir = sandbox.get_user_home_dir()\nprint(f\"Sandbox user home: {user_home_dir}\")\n```\n\n#### Sandbox.get\\_work\\_dir\n\n```python\n@intercept_errors(message_prefix=\"Failed to get working directory path: \")\n@with_instrumentation()\ndef get_work_dir() -> str\n```\n\nGets the working directory path inside the Sandbox.\n\n**Returns**:\n\n- `str` - The absolute path to the Sandbox working directory. Uses the WORKDIR specified in\n  the Dockerfile if present, or falling back to the user's home directory if not.\n  \n\n**Example**:\n\n```python\nwork_dir = sandbox.get_work_dir()\nprint(f\"Sandbox working directory: {work_dir}\")\n```\n\n#### Sandbox.create\\_lsp\\_server\n\n```python\n@with_instrumentation()\ndef create_lsp_server(language_id: LspLanguageId | LspLanguageIdLiteral,\n                      path_to_project: str) -> LspServer\n```\n\nCreates a new Language Server Protocol (LSP) server instance.\n\nThe LSP server provides language-specific features like code completion,\ndiagnostics, and more.\n\n**Arguments**:\n\n- `language_id` _LspLanguageId | LspLanguageIdLiteral_ - The language server type (e.g., LspLanguageId.PYTHON).\n- `path_to_project` _str_ - Path to the project root directory. Relative paths are resolved\n  based on the sandbox working directory.\n  \n\n**Returns**:\n\n- `LspServer` - A new LSP server instance configured for the specified language.\n  \n\n**Example**:\n\n```python\nlsp = sandbox.create_lsp_server(\"python\", \"workspace/project\")\n```\n\n#### Sandbox.set\\_labels\n\n```python\n@intercept_errors(message_prefix=\"Failed to set labels: \")\n@with_instrumentation()\ndef set_labels(labels: dict[str, str]) -> dict[str, str]\n```\n\nSets labels for the Sandbox.\n\nLabels are key-value pairs that can be used to organize and identify Sandboxes.\n\n**Arguments**:\n\n- `labels` _dict[str, str]_ - Dictionary of key-value pairs representing Sandbox labels.\n  \n\n**Returns**:\n\n  dict[str, str]: Dictionary containing the updated Sandbox labels.\n  \n\n**Example**:\n\n```python\nnew_labels = sandbox.set_labels({\n    \"project\": \"my-project\",\n    \"environment\": \"development\",\n    \"team\": \"backend\"\n})\nprint(f\"Updated labels: {new_labels}\")\n```\n\n#### Sandbox.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start sandbox: \")\n@with_timeout()\n@with_instrumentation()\ndef start(timeout: float | None = 60)\n```\n\nStarts the Sandbox and waits for it to be ready.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative. If sandbox fails to start or times out.\n  \n\n**Example**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.start(timeout=40)  # Wait up to 40 seconds\nprint(\"Sandbox started successfully\")\n```\n\n#### Sandbox.recover\n\n```python\n@intercept_errors(message_prefix=\"Failed to recover sandbox: \")\n@with_timeout()\ndef recover(timeout: float | None = 60)\n```\n\nRecovers the Sandbox from a recoverable error and waits for it to be ready.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative. If sandbox fails to recover or times out.\n  \n\n**Example**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.recover(timeout=40)  # Wait up to 40 seconds\nprint(\"Sandbox recovered successfully\")\n```\n\n#### Sandbox.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop sandbox: \")\n@with_timeout()\n@with_instrumentation()\ndef stop(timeout: float | None = 60)\n```\n\nStops the Sandbox and waits for it to be fully stopped.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative; If sandbox fails to stop or times out\n  \n\n**Example**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.stop()\nprint(\"Sandbox stopped successfully\")\n```\n\n#### Sandbox.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to remove sandbox: \")\n@with_instrumentation()\ndef delete(timeout: float | None = 60) -> None\n```\n\nDeletes the Sandbox.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Timeout (in seconds) for sandbox deletion. 0 means no timeout.\n  Default is 60 seconds.\n\n#### Sandbox.wait\\_for\\_sandbox\\_start\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for sandbox to start: \")\n@with_timeout()\n@with_instrumentation()\ndef wait_for_sandbox_start(timeout: float | None = 60) -> None\n```\n\nWaits for the Sandbox to reach the 'started' state. Polls the Sandbox status until it\nreaches the 'started' state, encounters an error or times out.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative; If Sandbox fails to start or times out\n\n#### Sandbox.wait\\_for\\_sandbox\\_stop\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for sandbox to stop: \")\n@with_timeout()\n@with_instrumentation()\ndef wait_for_sandbox_stop(timeout: float | None = 60) -> None\n```\n\nWaits for the Sandbox to reach the 'stopped' state. Polls the Sandbox status until it\nreaches the 'stopped' state, encounters an error or times out. It will wait up to 60 seconds\nfor the Sandbox to stop.\nTreats destroyed as stopped to cover ephemeral sandboxes that are automatically deleted after stopping.\n\n**Arguments**:\n\n- `timeout` _float | None_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative. If Sandbox fails to stop or times out.\n\n#### Sandbox.set\\_autostop\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-stop interval: \")\n@with_instrumentation()\ndef set_autostop_interval(interval: int) -> None\n```\n\nSets the auto-stop interval for the Sandbox.\n\nThe Sandbox will automatically stop after being idle (no new events) for the specified interval.\nEvents include any state changes or interactions with the Sandbox through the SDK.\nInteractions using Sandbox Previews are not included.\n\n**Arguments**:\n\n- `interval` _int_ - Number of minutes of inactivity before auto-stopping.\n  Set to 0 to disable auto-stop. Defaults to 15.\n  \n\n**Raises**:\n\n- `DaytonaError` - If interval is negative\n  \n\n**Example**:\n\n```python\n# Auto-stop after 1 hour\nsandbox.set_autostop_interval(60)\n# Or disable auto-stop\nsandbox.set_autostop_interval(0)\n```\n\n#### Sandbox.set\\_auto\\_archive\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-archive interval: \")\n@with_instrumentation()\ndef set_auto_archive_interval(interval: int) -> None\n```\n\nSets the auto-archive interval for the Sandbox.\n\nThe Sandbox will automatically archive after being continuously stopped for the specified interval.\n\n**Arguments**:\n\n- `interval` _int_ - Number of minutes after which a continuously stopped Sandbox will be auto-archived.\n  Set to 0 for the maximum interval. Default is 7 days.\n  \n\n**Raises**:\n\n- `DaytonaError` - If interval is negative\n  \n\n**Example**:\n\n```python\n# Auto-archive after 1 hour\nsandbox.set_auto_archive_interval(60)\n# Or use the maximum interval\nsandbox.set_auto_archive_interval(0)\n```\n\n#### Sandbox.set\\_auto\\_delete\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-delete interval: \")\n@with_instrumentation()\ndef set_auto_delete_interval(interval: int) -> None\n```\n\nSets the auto-delete interval for the Sandbox.\n\nThe Sandbox will automatically delete after being continuously stopped for the specified interval.\n\n**Arguments**:\n\n- `interval` _int_ - Number of minutes after which a continuously stopped Sandbox will be auto-deleted.\n  Set to negative value to disable auto-delete. Set to 0 to delete immediately upon stopping.\n  By default, auto-delete is disabled.\n  \n\n**Example**:\n\n```python\n# Auto-delete after 1 hour\nsandbox.set_auto_delete_interval(60)\n# Or delete immediately upon stopping\nsandbox.set_auto_delete_interval(0)\n# Or disable auto-delete\nsandbox.set_auto_delete_interval(-1)\n```\n\n#### Sandbox.get\\_preview\\_link\n\n```python\n@intercept_errors(message_prefix=\"Failed to get preview link: \")\n@with_instrumentation()\ndef get_preview_link(port: int) -> PortPreviewUrl\n```\n\nRetrieves the preview link for the sandbox at the specified port. If the port is closed,\nit will be opened automatically. For private sandboxes, a token is included to grant access\nto the URL.\n\n**Arguments**:\n\n- `port` _int_ - The port to open the preview link on.\n  \n\n**Returns**:\n\n- `PortPreviewUrl` - The response object for the preview link, which includes the `url`\n  and the `token` (to access private sandboxes).\n  \n\n**Example**:\n\n```python\npreview_link = sandbox.get_preview_link(3000)\nprint(f\"Preview URL: {preview_link.url}\")\nprint(f\"Token: {preview_link.token}\")\n```\n\n#### Sandbox.create\\_signed\\_preview\\_url\n\n```python\n@intercept_errors(message_prefix=\"Failed to create signed preview url: \")\ndef create_signed_preview_url(\n        port: int,\n        expires_in_seconds: int | None = None) -> SignedPortPreviewUrl\n```\n\nCreates a signed preview URL for the sandbox at the specified port.\n\n**Arguments**:\n\n- `port` _int_ - The port to open the preview link on.\n- `expires_in_seconds` _int | None_ - The number of seconds the signed preview\n  url will be valid for. Defaults to 60 seconds.\n  \n\n**Returns**:\n\n- `SignedPortPreviewUrl` - The response object for the signed preview url.\n\n#### Sandbox.expire\\_signed\\_preview\\_url\n\n```python\n@intercept_errors(message_prefix=\"Failed to expire signed preview url: \")\ndef expire_signed_preview_url(port: int, token: str) -> None\n```\n\nExpires a signed preview URL for the sandbox at the specified port.\n\n**Arguments**:\n\n- `port` _int_ - The port to expire the signed preview url on.\n- `token` _str_ - The token to expire the signed preview url on.\n\n#### Sandbox.archive\n\n```python\n@intercept_errors(message_prefix=\"Failed to archive sandbox: \")\n@with_instrumentation()\ndef archive() -> None\n```\n\nArchives the sandbox, making it inactive and preserving its state. When sandboxes are\narchived, the entire filesystem state is moved to cost-effective object storage, making it\npossible to keep sandboxes available for an extended period. The tradeoff between archived\nand stopped states is that starting an archived sandbox takes more time, depending on its size.\nSandbox must be stopped before archiving.\n\n#### Sandbox.resize\n\n```python\n@intercept_errors(message_prefix=\"Failed to resize sandbox: \")\n@with_timeout()\n@with_instrumentation()\ndef resize(resources: Resources, timeout: float | None = 60) -> None\n```\n\nResizes the Sandbox resources.\n\nChanges the CPU, memory, or disk allocation for the Sandbox. Hot resize (on running\nsandbox) only allows CPU/memory increases. Disk resize requires a stopped sandbox.\n\n**Arguments**:\n\n- `resources` _Resources_ - New resource configuration. Only specified fields will be updated.\n  - cpu: Number of CPU cores (minimum: 1). For hot resize, can only be increased.\n  - memory: Memory in GiB (minimum: 1). For hot resize, can only be increased.\n  - disk: Disk space in GiB (can only be increased, requires stopped sandbox).\n- `timeout` _Optional[float]_ - Timeout (in seconds) for the resize operation. 0 means no timeout.\n  Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If hot resize constraints are violated (CPU/memory decrease on running sandbox).\n- `DaytonaError` - If disk resize attempted on running sandbox.\n- `DaytonaError` - If disk size decrease is attempted.\n- `DaytonaError` - If resize operation times out.\n- `DaytonaError` - If no resource changes are specified.\n  \n\n**Example**:\n\n```python\n# Increase CPU/memory on running sandbox (hot resize)\nsandbox.resize(Resources(cpu=4, memory=8))\n\n# Change disk (sandbox must be stopped)\nsandbox.stop()\nsandbox.resize(Resources(cpu=2, memory=4, disk=30))\n```\n\n#### Sandbox.wait\\_for\\_resize\\_complete\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for resize to complete: \")\n@with_timeout()\n@with_instrumentation()\ndef wait_for_resize_complete(timeout: float | None = 60) -> None\n```\n\nWaits for the Sandbox resize operation to complete. Polls the Sandbox status until\nthe state is no longer 'resizing'.\n\n**Arguments**:\n\n- `timeout` _Optional[float]_ - Maximum time to wait in seconds. 0 means no timeout. Default is 60 seconds.\n  \n\n**Raises**:\n\n- `DaytonaError` - If timeout is negative. If resize operation times out.\n\n#### Sandbox.create\\_ssh\\_access\n\n```python\n@intercept_errors(message_prefix=\"Failed to create SSH access: \")\n@with_instrumentation()\ndef create_ssh_access(expires_in_minutes: int | None = None) -> SshAccessDto\n```\n\nCreates an SSH access token for the sandbox.\n\n**Arguments**:\n\n- `expires_in_minutes` _int | None_ - The number of minutes the SSH access token will be valid for.\n\n#### Sandbox.revoke\\_ssh\\_access\n\n```python\n@intercept_errors(message_prefix=\"Failed to revoke SSH access: \")\n@with_instrumentation()\ndef revoke_ssh_access(token: str) -> None\n```\n\nRevokes an SSH access token for the sandbox.\n\n**Arguments**:\n\n- `token` _str_ - The token to revoke.\n\n#### Sandbox.validate\\_ssh\\_access\n\n```python\n@intercept_errors(message_prefix=\"Failed to validate SSH access: \")\n@with_instrumentation()\ndef validate_ssh_access(token: str) -> SshAccessValidationDto\n```\n\nValidates an SSH access token for the sandbox.\n\n**Arguments**:\n\n- `token` _str_ - The token to validate.\n\n#### Sandbox.refresh\\_activity\n\n```python\n@intercept_errors(message_prefix=\"Failed to refresh sandbox activity: \")\ndef refresh_activity() -> None\n```\n\nRefreshes the sandbox activity to reset the timer for automated lifecycle management actions.\n\nThis method updates the sandbox's last activity timestamp without changing its state.\nIt is useful for keeping long-running sessions alive while there is still user activity.\n\n**Example**:\n\n```python\nsandbox.refresh_activity()\n```\n\n\n## PaginatedSandboxes\n\n```python\nclass PaginatedSandboxes(PaginatedSandboxesDto)\n```\n\nRepresents a paginated list of Daytona Sandboxes.\n\n**Attributes**:\n\n- `items` _list[Sandbox]_ - List of Sandbox instances in the current page.\n- `total` _int_ - Total number of Sandboxes across all pages.\n- `page` _int_ - Current page number.\n- `total_pages` _int_ - Total number of pages available.\n\n##### items: `list[Sandbox]`\n\n```python\nitems = None\n```\n\npyright: ignore[reportIncompatibleVariableOverride]\n\n## Resources\n\n```python\n@dataclass\nclass Resources()\n```\n\nResources configuration for Sandbox.\n\n**Attributes**:\n\n- `cpu` _int | None_ - Number of CPU cores to allocate.\n- `memory` _int | None_ - Amount of memory in GiB to allocate.\n- `disk` _int | None_ - Amount of disk space in GiB to allocate.\n- `gpu` _int | None_ - Number of GPUs to allocate.\n  \n\n**Example**:\n\n```python\nresources = Resources(\n    cpu=2,\n    memory=4,  # 4GiB RAM\n    disk=20,   # 20GiB disk\n    gpu=1\n)\nparams = CreateSandboxFromImageParams(\n    image=Image.debian_slim(\"3.12\"),\n    language=\"python\",\n    resources=resources\n)\n```\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/snapshot.mdx",
    "content": "---\ntitle: \"Snapshot\"\nhideTitleOnPage: true\n---\n\n## Snapshot\n\n```python\nclass Snapshot(SyncSnapshotDto)\n```\n\nRepresents a Daytona Snapshot which is a pre-configured sandbox.\n\n**Attributes**:\n\n- `id` _str_ - Unique identifier for the Snapshot.\n- `organization_id` _str | None_ - Organization ID of the Snapshot.\n- `general` _bool_ - Whether the Snapshot is general.\n- `name` _str_ - Name of the Snapshot.\n- `image_name` _str_ - Name of the Image of the Snapshot.\n- `state` _str_ - State of the Snapshot.\n- `size` _float | int | None_ - Size of the Snapshot.\n- `entrypoint` _list[str] | None_ - Entrypoint of the Snapshot.\n- `cpu` _float | int_ - CPU of the Snapshot.\n- `gpu` _float | int_ - GPU of the Snapshot.\n- `mem` _float | int_ - Memory of the Snapshot in GiB.\n- `disk` _float | int_ - Disk of the Snapshot in GiB.\n- `error_reason` _str | None_ - Error reason of the Snapshot.\n- `created_at` _str_ - Timestamp when the Snapshot was created.\n- `updated_at` _str_ - Timestamp when the Snapshot was last updated.\n- `last_used_at` _str_ - Timestamp when the Snapshot was last used.\n\n\n## SnapshotService\n\n```python\nclass SnapshotService()\n```\n\nService for managing Daytona Snapshots. Can be used to list, get, create and delete Snapshots.\n\n#### SnapshotService.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list snapshots: \")\n@with_instrumentation()\ndef list(page: int | None = None,\n         limit: int | None = None) -> PaginatedSnapshots\n```\n\nReturns paginated list of Snapshots.\n\n**Arguments**:\n\n- `page` _int | None_ - Page number for pagination (starting from 1).\n- `limit` _int | None_ - Maximum number of items per page.\n  \n\n**Returns**:\n\n- `PaginatedSnapshots` - Paginated list of Snapshots.\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nresult = daytona.snapshot.list(page=2, limit=10)\nfor snapshot in result.items:\n    print(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n#### SnapshotService.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete snapshot: \")\n@with_instrumentation()\ndef delete(snapshot: Snapshot) -> None\n```\n\nDelete a Snapshot.\n\n**Arguments**:\n\n- `snapshot` _Snapshot_ - Snapshot to delete.\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nsnapshot = daytona.snapshot.get(\"test-snapshot\")\ndaytona.snapshot.delete(snapshot)\nprint(\"Snapshot deleted\")\n```\n\n#### SnapshotService.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get snapshot: \")\n@with_instrumentation()\ndef get(name: str) -> Snapshot\n```\n\nGet a Snapshot by name.\n\n**Arguments**:\n\n- `name` _str_ - Name of the Snapshot to get.\n  \n\n**Returns**:\n\n- `Snapshot` - The Snapshot object.\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nsnapshot = daytona.snapshot.get(\"test-snapshot-name\")\nprint(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n#### SnapshotService.create\n\n```python\n@intercept_errors(message_prefix=\"Failed to create snapshot: \")\n@with_timeout()\n@with_instrumentation()\ndef create(params: CreateSnapshotParams,\n           *,\n           on_logs: Callable[[str], None] | None = None,\n           timeout: float | None = 0) -> Snapshot\n```\n\nCreates and registers a new snapshot from the given Image definition.\n\n**Arguments**:\n\n- `params` _CreateSnapshotParams_ - Parameters for snapshot creation.\n- `on_logs` _Callable[[str], None]_ - This callback function handles snapshot creation logs.\n- `timeout` _float | None_ - Default is no timeout. Timeout in seconds (0 means no timeout).\n\n**Example**:\n\n```python\nimage = Image.debianSlim('3.12').pipInstall('numpy')\ndaytona.snapshot.create(\n    CreateSnapshotParams(name='my-snapshot', image=image),\n    on_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n#### SnapshotService.activate\n\n```python\n@with_instrumentation()\ndef activate(snapshot: Snapshot) -> Snapshot\n```\n\nActivate a snapshot.\n\n**Arguments**:\n\n- `snapshot` _Snapshot_ - The Snapshot instance.\n\n**Returns**:\n\n- `Snapshot` - The activated Snapshot instance.\n\n#### SnapshotService.process\\_image\\_context\n\n```python\n@staticmethod\n@with_instrumentation()\ndef process_image_context(object_storage_api: ObjectStorageApi,\n                          image: Image) -> list[str]\n```\n\nProcesses the image context by uploading it to object storage.\n\n**Arguments**:\n\n- `image` _Image_ - The Image instance.\n\n**Returns**:\n\n- `list[str]` - List of context hashes stored in object storage.\n\n## PaginatedSnapshots\n\n```python\nclass PaginatedSnapshots(PaginatedSnapshotsDto)\n```\n\nRepresents a paginated list of Daytona Snapshots.\n\n**Attributes**:\n\n- `items` _list[Snapshot]_ - List of Snapshot instances in the current page.\n- `total` _int_ - Total number of Snapshots across all pages.\n- `page` _int_ - Current page number.\n- `total_pages` _int_ - Total number of pages available.\n\n## CreateSnapshotParams\n\n```python\nclass CreateSnapshotParams(BaseModel)\n```\n\nParameters for creating a new snapshot.\n\n**Attributes**:\n\n- `name` _str_ - Name of the snapshot.\n- `image` _str | Image_ - Image of the snapshot. If a string is provided,\n  it should be available on some registry. If an Image instance is provided,\n  it will be used to create a new image in Daytona.\n- `resources` _Resources | None_ - Resources of the snapshot.\n- `entrypoint` _list[str] | None_ - Entrypoint of the snapshot.\n- `region_id` _str | None_ - ID of the region where the snapshot will be available.\n  Defaults to organization default region if not specified.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/python-sdk/sync/volume.mdx",
    "content": "---\ntitle: \"Volume\"\nhideTitleOnPage: true\n---\n\n## Volume\n\n```python\nclass Volume(VolumeDto)\n```\n\nRepresents a Daytona Volume which is a shared storage volume for Sandboxes.\n\n**Attributes**:\n\n- `id` _str_ - Unique identifier for the Volume.\n- `name` _str_ - Name of the Volume.\n- `organization_id` _str_ - Organization ID of the Volume.\n- `state` _str_ - State of the Volume.\n- `created_at` _str_ - Date and time when the Volume was created.\n- `updated_at` _str_ - Date and time when the Volume was last updated.\n- `last_used_at` _str_ - Date and time when the Volume was last used.\n\n\n## VolumeService\n\n```python\nclass VolumeService()\n```\n\nService for managing Daytona Volumes. Can be used to list, get, create and delete Volumes.\n\n#### VolumeService.list\n\n```python\ndef list() -> list[Volume]\n```\n\nList all Volumes.\n\n**Returns**:\n\n- `list[Volume]` - List of all Volumes.\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nvolumes = daytona.volume.list()\nfor volume in volumes:\n    print(f\"{volume.name} ({volume.id})\")\n```\n\n#### VolumeService.get\n\n```python\n@with_instrumentation()\ndef get(name: str, create: bool = False) -> Volume\n```\n\nGet a Volume by name.\n\n**Arguments**:\n\n- `name` _str_ - Name of the Volume to get.\n- `create` _bool_ - If True, create a new Volume if it doesn't exist.\n  \n\n**Returns**:\n\n- `Volume` - The Volume object.\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nvolume = daytona.volume.get(\"test-volume-name\", create=True)\nprint(f\"{volume.name} ({volume.id})\")\n```\n\n#### VolumeService.create\n\n```python\n@with_instrumentation()\ndef create(name: str) -> Volume\n```\n\nCreate a new Volume.\n\n**Arguments**:\n\n- `name` _str_ - Name of the Volume to create.\n  \n\n**Returns**:\n\n- `Volume` - The Volume object.\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nvolume = daytona.volume.create(\"test-volume\")\nprint(f\"{volume.name} ({volume.id}); state: {volume.state}\")\n```\n\n#### VolumeService.delete\n\n```python\n@with_instrumentation()\ndef delete(volume: Volume) -> None\n```\n\nDelete a Volume.\n\n**Arguments**:\n\n- `volume` _Volume_ - Volume to delete.\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nvolume = daytona.volume.get(\"test-volume\")\ndaytona.volume.delete(volume)\nprint(\"Volume deleted\")\n```\n\n## VolumeMount\n\n```python\nclass VolumeMount(ApiVolumeMount, AsyncApiVolumeMount)\n```\n\nRepresents a Volume mount configuration for a Sandbox.\n\n**Attributes**:\n\n- `volume_id` _str_ - ID of the volume to mount.\n- `mount_path` _str_ - Path where the volume will be mounted in the sandbox.\n- `subpath` _str | None_ - Optional S3 subpath/prefix within the volume to mount.\n  When specified, only this prefix will be accessible. When omitted,\n  the entire volume is mounted.\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/regions.mdx",
    "content": "---\ntitle: Regions\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nSandboxes are isolated runtime environments that run on [runners](/docs/en/runners) — machines that form Daytona's compute plane.\n\nRunners are organized into **regions**, which are geographic or logical groupings of compute infrastructure. When creating a sandbox, you can target a specific region, and Daytona will schedule your workload on an available runner within that region.\n\nAs a result, you're able to:\n\n- Choose specific geographic locations for reduced latency\n- Comply with data residency requirements\n- Use your own runner machines for custom regions\n- Scale compute resources independently within each custom region\n\nRegions are geographic or logical groupings of runners that execute sandbox workloads. The sandbox region is specified by setting the `target` parameter on initialization:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, DaytonaConfig\n\n# Configure Daytona to use the US region\nconfig = DaytonaConfig(\n    target=\"us\"\n)\n\n# Initialize the Daytona client with the specified configuration\ndaytona = Daytona(config)\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\n// Configure Daytona to use the EU region\nconst daytona: Daytona = new Daytona({\n    target: \"eu\"\n});\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\n// Configure Daytona to use the US region\nclient, _ := daytona.NewClientWithConfig(&types.DaytonaConfig{\n    Target: \"us\",\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\n# Configure Daytona to use the EU region\nconfig = Daytona::Config.new(\n    target: \"eu\"\n)\n\n# Initialize the Daytona client with the specified configuration\ndaytona = Daytona::Daytona.new(config)\n```\n\n</TabItem>\n</Tabs>\n\n### Shared regions\n\nShared regions are managed by Daytona and available to all organizations. These regions provide immediate access to Daytona's infrastructure without any setup required.\n\nLimits are applied to your organization's default region. For access to a different shared region, contact [sales@daytona.io](mailto:sales@daytona.io).\n\n| Region        | Target   |\n| ------------- | -------- |\n| United States | **`us`** |\n| Europe        | **`eu`** |\n\n### Dedicated regions\n\nDedicated regions are managed by Daytona and provisioned exclusively for individual organizations. These regions deliver dedicated infrastructure with the operational simplicity of a managed service.\n\n:::note\nContact [sales@daytona.io](mailto:sales@daytona.io) to set up a dedicated region for your organization.\n:::\n\n### Custom regions\n\nCustom regions are created and managed by your organization, allowing you to use your own runner machines and scale compute resources independently within each region. This provides maximum control over data locality, compliance, and infrastructure configuration.\n\nAdditionally, custom regions have no limits applied for concurrent resource usage, giving you full control over capacity and performance.\n\nFor more information, see the [runners](/docs/en/runners) guide.\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/computer-use.mdx",
    "content": "---\ntitle: \"ComputerUse\"\nhideTitleOnPage: true\n---\n\n## ComputerUse\n\nInitialize a new ComputerUse instance.\n\n### Constructors\n\n#### new ComputerUse()\n\n```ruby\ndef initialize(sandbox_id:, toolbox_api:, otel_state:)\n\n```\n\nInitialize a new ComputerUse instance.\n\n**Parameters**:\n\n- `sandbox_id` _String_ - The ID of the sandbox\n- `toolbox_api` _DaytonaApiClient:ToolboxApi_ - API client for sandbox operations\n- `otel_state` _Daytona:OtelState, nil_ -\n\n**Returns**:\n\n- `ComputerUse` - a new instance of ComputerUse\n\n### Methods\n\n#### sandbox_id()\n\n```ruby\ndef sandbox_id()\n\n```\n\n**Returns**:\n\n- `String` - The ID of the sandbox\n\n#### toolbox_api()\n\n```ruby\ndef toolbox_api()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient:ToolboxApi` - API client for sandbox operations\n\n#### mouse()\n\n```ruby\ndef mouse()\n\n```\n\n**Returns**:\n\n- `Mouse` - Mouse operations interface\n\n#### keyboard()\n\n```ruby\ndef keyboard()\n\n```\n\n**Returns**:\n\n- `Keyboard` - Keyboard operations interface\n\n#### screenshot()\n\n```ruby\ndef screenshot()\n\n```\n\n**Returns**:\n\n- `Screenshot` - Screenshot operations interface\n\n#### display()\n\n```ruby\ndef display()\n\n```\n\n**Returns**:\n\n- `Display` - Display operations interface\n\n#### recording()\n\n```ruby\ndef recording()\n\n```\n\n**Returns**:\n\n- `Recording` - Screen recording operations interface\n\n#### start()\n\n```ruby\ndef start()\n\n```\n\nStarts all computer use processes (Xvfb, xfce4, x11vnc, novnc).\n\n**Returns**:\n\n- `DaytonaApiClient:ComputerUseStartResponse` - Computer use start response\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\nresult = sandbox.computer_use.start\nputs \"Computer use processes started: #{result.message}\"\n\n```\n\n#### stop()\n\n```ruby\ndef stop()\n\n```\n\nStops all computer use processes.\n\n**Returns**:\n\n- `DaytonaApiClient:ComputerUseStopResponse` - Computer use stop response\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\nresult = sandbox.computer_use.stop\nputs \"Computer use processes stopped: #{result.message}\"\n\n```\n\n#### status()\n\n```ruby\ndef status()\n\n```\n\nGets the status of all computer use processes.\n\n**Returns**:\n\n- `DaytonaApiClient:ComputerUseStatusResponse` - Status information about all VNC desktop processes\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\nresponse = sandbox.computer_use.get_status\nputs \"Computer use status: #{response.status}\"\n\n```\n\n#### get_process_status()\n\n```ruby\ndef get_process_status(process_name:)\n\n```\n\nGets the status of a specific VNC process.\n\n**Parameters**:\n\n- `process_name` _String_ - Name of the process to check\n\n**Returns**:\n\n- `DaytonaApiClient:ProcessStatusResponse` - Status information about the specific process\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\nxvfb_status = sandbox.computer_use.get_process_status(\"xvfb\")\nno_vnc_status = sandbox.computer_use.get_process_status(\"novnc\")\n\n```\n\n#### restart_process()\n\n```ruby\ndef restart_process(process_name:)\n\n```\n\nRestarts a specific VNC process.\n\n**Parameters**:\n\n- `process_name` _String_ - Name of the process to restart\n\n**Returns**:\n\n- `DaytonaApiClient:ProcessRestartResponse` - Process restart response\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\nresult = sandbox.computer_use.restart_process(\"xfce4\")\nputs \"XFCE4 process restarted: #{result.message}\"\n\n```\n\n#### get_process_logs()\n\n```ruby\ndef get_process_logs(process_name:)\n\n```\n\nGets logs for a specific VNC process.\n\n**Parameters**:\n\n- `process_name` _String_ - Name of the process to get logs for\n\n**Returns**:\n\n- `DaytonaApiClient:ProcessLogsResponse` - Process logs\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\nlogs = sandbox.computer_use.get_process_logs(\"novnc\")\nputs \"NoVNC logs: #{logs}\"\n\n```\n\n#### get_process_errors()\n\n```ruby\ndef get_process_errors(process_name:)\n\n```\n\nGets error logs for a specific VNC process.\n\n**Parameters**:\n\n- `process_name` _String_ - Name of the process to get error logs for\n\n**Returns**:\n\n- `DaytonaApiClient:ProcessErrorsResponse` - Process error logs\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\nerrors = sandbox.computer_use.get_process_errors(\"x11vnc\")\nputs \"X11VNC errors: #{errors}\"\n\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/config.mdx",
    "content": "---\ntitle: \"Config\"\nhideTitleOnPage: true\n---\n\n## Config\n\nMain class for a new Daytona::Config object.\n\n### Constructors\n\n#### new Config()\n\n```ruby\ndef initialize(api_key:, jwt_token:, api_url:, organization_id:, target:, _experimental:)\n\n```\n\nInitializes a new Daytona::Config object.\n\n**Parameters**:\n\n- `api_key` _String, nil_ - Daytona API key. Defaults to ENV['DAYTONA_API_KEY'].\n- `jwt_token` _String, nil_ - Daytona JWT token. Defaults to ENV['DAYTONA_JWT_TOKEN'].\n- `api_url` _String, nil_ - Daytona API URL. Defaults to ENV['DAYTONA_API_URL'] or Daytona::Config::API_URL.\n- `organization_id` _String, nil_ - Daytona organization ID. Defaults to ENV['DAYTONA_ORGANIZATION_ID'].\n- `target` _String, nil_ - Daytona target. Defaults to ENV['DAYTONA_TARGET'].\n- `_experimental` _Hash, nil_ - Experimental configuration options.\n\n**Returns**:\n\n- `Config` - a new instance of Config\n\n### Methods\n\n#### api_key()\n\n```ruby\ndef api_key()\n\n```\n\nAPI key for authentication with the Daytona API\n\n**Returns**:\n\n- `String, nil` - Daytona API key\n\n#### api_key=()\n\n```ruby\ndef api_key=(value)\n\n```\n\nAPI key for authentication with the Daytona API\n\n**Returns**:\n\n- `String, nil` - Daytona API key\n\n#### jwt_token()\n\n```ruby\ndef jwt_token()\n\n```\n\nJWT token for authentication with the Daytona API\n\n**Returns**:\n\n- `String, nil` - Daytona JWT token\n\n#### jwt_token=()\n\n```ruby\ndef jwt_token=(value)\n\n```\n\nJWT token for authentication with the Daytona API\n\n**Returns**:\n\n- `String, nil` - Daytona JWT token\n\n#### api_url()\n\n```ruby\ndef api_url()\n\n```\n\nURL of the Daytona API\n\n**Returns**:\n\n- `String, nil` - Daytona API URL\n\n#### api_url=()\n\n```ruby\ndef api_url=(value)\n\n```\n\nURL of the Daytona API\n\n**Returns**:\n\n- `String, nil` - Daytona API URL\n\n#### organization_id()\n\n```ruby\ndef organization_id()\n\n```\n\nOrganization ID for authentication with the Daytona API\n\n**Returns**:\n\n- `String, nil` - Daytona API URL\n\n#### organization_id=()\n\n```ruby\ndef organization_id=(value)\n\n```\n\nOrganization ID for authentication with the Daytona API\n\n**Returns**:\n\n- `String, nil` - Daytona API URL\n\n#### target()\n\n```ruby\ndef target()\n\n```\n\nTarget environment for sandboxes\n\n**Returns**:\n\n- `String, nil` - Daytona target\n\n#### target=()\n\n```ruby\ndef target=(value)\n\n```\n\nTarget environment for sandboxes\n\n**Returns**:\n\n- `String, nil` - Daytona target\n\n#### _experimental()\n\n```ruby\ndef _experimental()\n\n```\n\nExperimental configuration options\n\n**Returns**:\n\n- `Hash, nil` - Experimental configuration hash\n\n#### _experimental=()\n\n```ruby\ndef _experimental=(value)\n\n```\n\nExperimental configuration options\n\n**Returns**:\n\n- `Hash, nil` - Experimental configuration hash\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/daytona.mdx",
    "content": "---\ntitle: \"Daytona\"\nhideTitleOnPage: true\n---\n\n## Daytona\n\nDaytona class for Daytona SDK.\n\n### Constructors\n\n#### new Daytona()\n\n```ruby\ndef initialize(config)\n\n```\n\n**Parameters**:\n\n- `config` _Daytona:Config_ - Configuration options. Defaults to Daytona::Config.new\n\n**Returns**:\n\n- `Daytona` - a new instance of Daytona\n\n### Methods\n\n#### config()\n\n```ruby\ndef config()\n\n```\n\n**Returns**:\n\n- `Daytona:Config`\n\n#### api_client()\n\n```ruby\ndef api_client()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient`\n\n#### sandbox_api()\n\n```ruby\ndef sandbox_api()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient:SandboxApi`\n\n#### volume()\n\n```ruby\ndef volume()\n\n```\n\n**Returns**:\n\n- `Daytona:VolumeService`\n\n#### object_storage_api()\n\n```ruby\ndef object_storage_api()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient:ObjectStorageApi`\n\n#### snapshots_api()\n\n```ruby\ndef snapshots_api()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient:SnapshotsApi`\n\n#### snapshot()\n\n```ruby\ndef snapshot()\n\n```\n\n**Returns**:\n\n- `Daytona:SnapshotService`\n\n#### close()\n\n```ruby\ndef close()\n\n```\n\nShuts down OTel providers, flushing any pending telemetry data.\n\n**Returns**:\n\n- `void`\n\n#### create()\n\n```ruby\ndef create(params, on_snapshot_create_logs:)\n\n```\n\nCreates a sandbox with the specified parameters\n\n**Parameters**:\n\n- `params` _Daytona:CreateSandboxFromSnapshotParams, Daytona:CreateSandboxFromImageParams, Nil_ - Sandbox creation parameters\n\n**Returns**:\n\n- `Daytona:Sandbox` - The created sandbox\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If auto_stop_interval or auto_archive_interval is negative\n\n#### delete()\n\n```ruby\ndef delete(sandbox)\n\n```\n\nDeletes a Sandbox.\n\n**Parameters**:\n\n- `sandbox` _Daytona:Sandbox_ -\n\n**Returns**:\n\n- `void`\n\n#### get()\n\n```ruby\ndef get(id)\n\n```\n\nGets a Sandbox by its ID.\n\n**Parameters**:\n\n- `id` _String_ -\n\n**Returns**:\n\n- `Daytona:Sandbox`\n\n#### list()\n\n```ruby\ndef list(labels, page:, limit:)\n\n```\n\nLists Sandboxes filtered by labels.\n\n**Parameters**:\n\n- `labels` _Hash\\<String, String\\>_ -\n- `page` _Integer, Nil_ -\n- `limit` _Integer, Nil_ -\n\n**Returns**:\n\n- `Daytona:PaginatedResource`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` -\n\n#### start()\n\n```ruby\ndef start(sandbox, timeout)\n\n```\n\nStarts a Sandbox and waits for it to be ready.\n\n**Parameters**:\n\n- `sandbox` _Daytona:Sandbox_ -\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s).\n\n**Returns**:\n\n- `void`\n\n#### stop()\n\n```ruby\ndef stop(sandbox, timeout)\n\n```\n\nStops a Sandbox and waits for it to be stopped.\n\n**Parameters**:\n\n- `sandbox` _Daytona:Sandbox_ -\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s).\n\n**Returns**:\n\n- `void`\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/file-system.mdx",
    "content": "---\ntitle: \"FileSystem\"\nhideTitleOnPage: true\n---\n\n## FileSystem\n\nMain class for a new FileSystem instance.\n\n### Constructors\n\n#### new FileSystem()\n\n```ruby\ndef initialize(sandbox_id:, toolbox_api:, otel_state:)\n\n```\n\nInitializes a new FileSystem instance.\n\n**Parameters**:\n\n- `sandbox_id` _String_ - The Sandbox ID\n- `toolbox_api` _DaytonaToolboxApiClient:FileSystemApi_ - API client for Sandbox operations\n- `otel_state` _Daytona:OtelState, nil_ -\n\n**Returns**:\n\n- `FileSystem` - a new instance of FileSystem\n\n### Methods\n\n#### sandbox_id()\n\n```ruby\ndef sandbox_id()\n\n```\n\n**Returns**:\n\n- `String` - The Sandbox ID\n\n#### toolbox_api()\n\n```ruby\ndef toolbox_api()\n\n```\n\n**Returns**:\n\n- `DaytonaToolboxApiClient:FileSystemApi` - API client for Sandbox operations\n\n#### create_folder()\n\n```ruby\ndef create_folder(path, mode)\n\n```\n\nCreates a new directory in the Sandbox at the specified path with the given\npermissions.\n\n**Parameters**:\n\n- `path` _String_ - Path where the folder should be created. Relative paths are resolved based\non the sandbox working directory.\n- `mode` _String_ - Folder permissions in octal format (e.g., \"755\" for rwxr-xr-x).\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Create a directory with standard permissions\nsandbox.fs.create_folder(\"workspace/data\", \"755\")\n\n# Create a private directory\nsandbox.fs.create_folder(\"workspace/secrets\", \"700\")\n\n```\n\n#### delete_file()\n\n```ruby\ndef delete_file(path, recursive:)\n\n```\n\nDeletes a file from the Sandbox.\n\n**Parameters**:\n\n- `path` _String_ - Path to the file to delete. Relative paths are resolved based on the sandbox working directory.\n- `recursive` _Boolean_ - If the file is a directory, this must be true to delete it.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Delete a file\nsandbox.fs.delete_file(\"workspace/data/old_file.txt\")\n\n# Delete a directory recursively\nsandbox.fs.delete_file(\"workspace/old_dir\", recursive: true)\n\n```\n\n#### get_file_info()\n\n```ruby\ndef get_file_info(path)\n\n```\n\nGets detailed information about a file or directory, including its\nsize, permissions, and timestamps.\n\n**Parameters**:\n\n- `path` _String_ - Path to the file or directory. Relative paths are resolved based\non the sandbox working directory.\n\n**Returns**:\n\n- `DaytonaApiClient:FileInfo` - Detailed file information\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Get file metadata\ninfo = sandbox.fs.get_file_info(\"workspace/data/file.txt\")\nputs \"Size: #{info.size} bytes\"\nputs \"Modified: #{info.mod_time}\"\nputs \"Mode: #{info.mode}\"\n\n# Check if path is a directory\ninfo = sandbox.fs.get_file_info(\"workspace/data\")\nputs \"Path is a directory\" if info.is_dir\n\n```\n\n#### list_files()\n\n```ruby\ndef list_files(path)\n\n```\n\nLists files and directories in a given path and returns their information, similar to the ls -l command.\n\n**Parameters**:\n\n- `path` _String_ - Path to the directory to list contents from. Relative paths are resolved\nbased on the sandbox working directory.\n\n**Returns**:\n\n- `Array\\<DaytonaApiClient:FileInfo\\>` - List of file and directory information\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# List directory contents\nfiles = sandbox.fs.list_files(\"workspace/data\")\n\n# Print files and their sizes\nfiles.each do |file|\n  puts \"#{file.name}: #{file.size} bytes\" unless file.is_dir\nend\n\n# List only directories\ndirs = files.select(&:is_dir)\nputs \"Subdirectories: #{dirs.map(&:name).join(', ')}\"\n\n```\n\n#### download_file()\n\n```ruby\ndef download_file(remote_path, local_path)\n\n```\n\nDownloads a file from the Sandbox. Returns the file contents as a string.\nThis method is useful when you want to load the file into memory without saving it to disk.\nIt can only be used for smaller files.\n\n**Parameters**:\n\n- `remote_path` _String_ - Path to the file in the Sandbox. Relative paths are resolved based\non the sandbox working directory.\n- `local_path` _String, nil_ - Optional path to save the file locally. If provided, the file will be saved to disk.\n\n**Returns**:\n\n- `File, nil` - The file if local_path is nil, otherwise nil\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Download and get file content\ncontent = sandbox.fs.download_file(\"workspace/data/file.txt\")\nputs content\n\n# Download and save a file locally\nsandbox.fs.download_file(\"workspace/data/file.txt\", \"local_copy.txt\")\nsize_mb = File.size(\"local_copy.txt\") / 1024.0 / 1024.0\nputs \"Size of the downloaded file: #{size_mb} MB\"\n\n```\n\n#### upload_file()\n\n```ruby\ndef upload_file(source, remote_path)\n\n```\n\nUploads a file to the specified path in the Sandbox. If a file already exists at\nthe destination path, it will be overwritten.\n\n**Parameters**:\n\n- `source` _String, IO_ - File contents as a string/bytes or a local file path or IO object.\n- `remote_path` _String_ - Path to the destination file. Relative paths are resolved based on\nthe sandbox working directory.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Upload a text file from string content\ncontent = \"Hello, World!\"\nsandbox.fs.upload_file(content, \"tmp/hello.txt\")\n\n# Upload a local file\nsandbox.fs.upload_file(\"local_file.txt\", \"tmp/file.txt\")\n\n# Upload binary data\ndata = { key: \"value\" }.to_json\nsandbox.fs.upload_file(data, \"tmp/config.json\")\n\n```\n\n#### upload_files()\n\n```ruby\ndef upload_files(files)\n\n```\n\nUploads multiple files to the Sandbox. If files already exist at the destination paths,\nthey will be overwritten.\n\n**Parameters**:\n\n- `files` _Array\\<FileUpload\\>_ - List of files to upload.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Upload multiple files\nfiles = [\n  FileUpload.new(\"Content of file 1\", \"/tmp/file1.txt\"),\n  FileUpload.new(\"workspace/data/file2.txt\", \"/tmp/file2.txt\"),\n  FileUpload.new('{\"key\": \"value\"}', \"/tmp/config.json\")\n]\nsandbox.fs.upload_files(files)\n\n```\n\n#### find_files()\n\n```ruby\ndef find_files(path, pattern)\n\n```\n\nSearches for files containing a pattern, similar to the grep command.\n\n**Parameters**:\n\n- `path` _String_ - Path to the file or directory to search. If the path is a directory,\nthe search will be performed recursively. Relative paths are resolved based\non the sandbox working directory.\n- `pattern` _String_ - Search pattern to match against file contents.\n\n**Returns**:\n\n- `Array\\<DaytonaApiClient:Match\\>` - List of matches found in files\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Search for TODOs in Ruby files\nmatches = sandbox.fs.find_files(\"workspace/src\", \"TODO:\")\nmatches.each do |match|\n  puts \"#{match.file}:#{match.line}: #{match.content.strip}\"\nend\n\n```\n\n#### search_files()\n\n```ruby\ndef search_files(path, pattern)\n\n```\n\nSearches for files and directories whose names match the specified pattern.\nThe pattern can be a simple string or a glob pattern.\n\n**Parameters**:\n\n- `path` _String_ - Path to the root directory to start search from. Relative paths are resolved\nbased on the sandbox working directory.\n- `pattern` _String_ - Pattern to match against file names. Supports glob\npatterns (e.g., \"*.rb\" for Ruby files).\n\n**Returns**:\n\n- `DaytonaApiClient:SearchFilesResponse`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Find all Ruby files\nresult = sandbox.fs.search_files(\"workspace\", \"*.rb\")\nresult.files.each { |file| puts file }\n\n# Find files with specific prefix\nresult = sandbox.fs.search_files(\"workspace/data\", \"test_*\")\nputs \"Found #{result.files.length} test files\"\n\n```\n\n#### move_files()\n\n```ruby\ndef move_files(source, destination)\n\n```\n\nMoves or renames a file or directory. The parent directory of the destination must exist.\n\n**Parameters**:\n\n- `source` _String_ - Path to the source file or directory. Relative paths are resolved\nbased on the sandbox working directory.\n- `destination` _String_ - Path to the destination. Relative paths are resolved based on\nthe sandbox working directory.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Rename a file\nsandbox.fs.move_files(\n  \"workspace/data/old_name.txt\",\n  \"workspace/data/new_name.txt\"\n)\n\n# Move a file to a different directory\nsandbox.fs.move_files(\n  \"workspace/data/file.txt\",\n  \"workspace/archive/file.txt\"\n)\n\n# Move a directory\nsandbox.fs.move_files(\n  \"workspace/old_dir\",\n  \"workspace/new_dir\"\n)\n\n```\n\n#### replace_in_files()\n\n```ruby\ndef replace_in_files(files:, pattern:, new_value:)\n\n```\n\nPerforms search and replace operations across multiple files.\n\n**Parameters**:\n\n- `files` _Array\\<String\\>_ - List of file paths to perform replacements in. Relative paths are\nresolved based on the sandbox working directory.\n- `pattern` _String_ - Pattern to search for.\n- `new_value` _String_ - Text to replace matches with.\n\n**Returns**:\n\n- `Array\\<DaytonaApiClient:ReplaceResult\\>` - List of results indicating replacements made in each file\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Replace in specific files\nresults = sandbox.fs.replace_in_files(\n  files: [\"workspace/src/file1.rb\", \"workspace/src/file2.rb\"],\n  pattern: \"old_function\",\n  new_value: \"new_function\"\n)\n\n# Print results\nresults.each do |result|\n  if result.success\n    puts \"#{result.file}: #{result.success}\"\n  else\n    puts \"#{result.file}: #{result.error}\"\n  end\nend\n\n```\n\n#### set_file_permissions()\n\n```ruby\ndef set_file_permissions(path:, mode:, owner:, group:)\n\n```\n\nSets permissions and ownership for a file or directory. Any of the parameters can be nil\nto leave that attribute unchanged.\n\n**Parameters**:\n\n- `path` _String_ - Path to the file or directory. Relative paths are resolved based on\nthe sandbox working directory.\n- `mode` _String, nil_ - File mode/permissions in octal format (e.g., \"644\" for rw-r--r--).\n- `owner` _String, nil_ - User owner of the file.\n- `group` _String, nil_ - Group owner of the file.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the operation fails\n\n**Examples:**\n\n```ruby\n# Make a file executable\nsandbox.fs.set_file_permissions(\n  path: \"workspace/scripts/run.sh\",\n  mode: \"755\"  # rwxr-xr-x\n)\n\n# Change file owner\nsandbox.fs.set_file_permissions(\n  path: \"workspace/data/file.txt\",\n  owner: \"daytona\",\n  group: \"daytona\"\n)\n\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/git.mdx",
    "content": "---\ntitle: \"Git\"\nhideTitleOnPage: true\n---\n\n## Git\n\nMain class for a new Git handler instance.\n\n### Constructors\n\n#### new Git()\n\n```ruby\ndef initialize(sandbox_id:, toolbox_api:, otel_state:)\n\n```\n\nInitializes a new Git handler instance.\n\n**Parameters**:\n\n- `sandbox_id` _String_ - The Sandbox ID.\n- `toolbox_api` _DaytonaToolboxApiClient:GitApi_ - API client for Sandbox operations.\n- `otel_state` _Daytona:OtelState, nil_ -\n\n**Returns**:\n\n- `Git` - a new instance of Git\n\n### Methods\n\n#### sandbox_id()\n\n```ruby\ndef sandbox_id()\n\n```\n\n**Returns**:\n\n- `String` - The Sandbox ID\n\n#### toolbox_api()\n\n```ruby\ndef toolbox_api()\n\n```\n\n**Returns**:\n\n- `DaytonaToolboxApiClient:GitApi` - API client for Sandbox operations\n\n#### add()\n\n```ruby\ndef add(path, files)\n\n```\n\nStages the specified files for the next commit, similar to\nrunning 'git add' on the command line.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n- `files` _Array\\<String\\>_ - List of file paths or directories to stage, relative to the repository root.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if adding files fails\n\n**Examples:**\n\n```ruby\n# Stage a single file\nsandbox.git.add(\"workspace/repo\", [\"file.txt\"])\n\n# Stage multiple files\nsandbox.git.add(\"workspace/repo\", [\n  \"src/main.rb\",\n  \"spec/main_spec.rb\",\n  \"README.md\"\n])\n\n```\n\n#### branches()\n\n```ruby\ndef branches(path)\n\n```\n\nLists branches in the repository.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n\n**Returns**:\n\n- `DaytonaApiClient:ListBranchResponse` - List of branches in the repository.\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if listing branches fails\n\n**Examples:**\n\n```ruby\nresponse = sandbox.git.branches(\"workspace/repo\")\nputs \"Branches: #{response.branches}\"\n\n```\n\n#### clone()\n\n```ruby\ndef clone(url:, path:, branch:, commit_id:, username:, password:)\n\n```\n\nClones a Git repository into the specified path. It supports\ncloning specific branches or commits, and can authenticate with the remote\nrepository if credentials are provided.\n\n**Parameters**:\n\n- `url` _String_ - Repository URL to clone from.\n- `path` _String_ - Path where the repository should be cloned. Relative paths are resolved\nbased on the sandbox working directory.\n- `branch` _String, nil_ - Specific branch to clone. If not specified,\nclones the default branch.\n- `commit_id` _String, nil_ - Specific commit to clone. If specified,\nthe repository will be left in a detached HEAD state at this commit.\n- `username` _String, nil_ - Git username for authentication.\n- `password` _String, nil_ - Git password or token for authentication.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if cloning repository fails\n\n**Examples:**\n\n```ruby\n# Clone the default branch\nsandbox.git.clone(\n  url: \"https://github.com/user/repo.git\",\n  path: \"workspace/repo\"\n)\n\n# Clone a specific branch with authentication\nsandbox.git.clone(\n  url: \"https://github.com/user/private-repo.git\",\n  path: \"workspace/private\",\n  branch: \"develop\",\n  username: \"user\",\n  password: \"token\"\n)\n\n# Clone a specific commit\nsandbox.git.clone(\n  url: \"https://github.com/user/repo.git\",\n  path: \"workspace/repo-old\",\n  commit_id: \"abc123\"\n)\n\n```\n\n#### commit()\n\n```ruby\ndef commit(path:, message:, author:, email:, allow_empty:)\n\n```\n\nCreates a new commit with the staged changes. Make sure to stage\nchanges using the add() method before committing.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n- `message` _String_ - Commit message describing the changes.\n- `author` _String_ - Name of the commit author.\n- `email` _String_ - Email address of the commit author.\n- `allow_empty` _Boolean_ - Allow creating an empty commit when no changes are staged. Defaults to false.\n\n**Returns**:\n\n- `GitCommitResponse` - Response containing the commit SHA.\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if committing changes fails\n\n**Examples:**\n\n```ruby\n# Stage and commit changes\nsandbox.git.add(\"workspace/repo\", [\"README.md\"])\ncommit_response = sandbox.git.commit(\n  path: \"workspace/repo\",\n  message: \"Update documentation\",\n  author: \"John Doe\",\n  email: \"john@example.com\",\n  allow_empty: true\n)\nputs \"Commit SHA: #{commit_response.sha}\"\n\n```\n\n#### push()\n\n```ruby\ndef push(path:, username:, password:)\n\n```\n\nPushes all local commits on the current branch to the remote\nrepository. If the remote repository requires authentication, provide\nusername and password/token.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n- `username` _String, nil_ - Git username for authentication.\n- `password` _String, nil_ - Git password or token for authentication.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if pushing changes fails\n\n**Examples:**\n\n```ruby\n# Push without authentication (for public repos or SSH)\nsandbox.git.push(\"workspace/repo\")\n\n# Push with authentication\nsandbox.git.push(\n  path: \"workspace/repo\",\n  username: \"user\",\n  password: \"github_token\"\n)\n\n```\n\n#### pull()\n\n```ruby\ndef pull(path:, username:, password:)\n\n```\n\nPulls changes from the remote repository. If the remote repository requires authentication,\nprovide username and password/token.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n- `username` _String, nil_ - Git username for authentication.\n- `password` _String, nil_ - Git password or token for authentication.\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if pulling changes fails\n\n**Examples:**\n\n```ruby\n# Pull without authentication\nsandbox.git.pull(\"workspace/repo\")\n\n# Pull with authentication\nsandbox.git.pull(\n  path: \"workspace/repo\",\n  username: \"user\",\n  password: \"github_token\"\n)\n\n```\n\n#### status()\n\n```ruby\ndef status(path)\n\n```\n\nGets the current Git repository status.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n\n**Returns**:\n\n- `DaytonaToolboxApiClient:GitStatus` - Repository status information including:\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if getting status fails\n\n**Examples:**\n\n```ruby\nstatus = sandbox.git.status(\"workspace/repo\")\nputs \"On branch: #{status.current_branch}\"\nputs \"Commits ahead: #{status.ahead}\"\nputs \"Commits behind: #{status.behind}\"\n\n```\n\n#### checkout_branch()\n\n```ruby\ndef checkout_branch(path, branch)\n\n```\n\nCheckout branch in the repository.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n- `branch` _String_ - Name of the branch to checkout\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if checking out branch fails\n\n**Examples:**\n\n```ruby\n# Checkout a branch\nsandbox.git.checkout_branch(\"workspace/repo\", \"feature-branch\")\n\n```\n\n#### create_branch()\n\n```ruby\ndef create_branch(path, name)\n\n```\n\nCreate branch in the repository.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n- `name` _String_ - Name of the new branch to create\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if creating branch fails\n\n**Examples:**\n\n```ruby\n# Create a new branch\nsandbox.git.create_branch(\"workspace/repo\", \"new-feature\")\n\n```\n\n#### delete_branch()\n\n```ruby\ndef delete_branch(path, name)\n\n```\n\nDelete branch in the repository.\n\n**Parameters**:\n\n- `path` _String_ - Path to the Git repository root. Relative paths are resolved based on\nthe sandbox working directory.\n- `name` _String_ - Name of the branch to delete\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - if deleting branch fails\n\n**Examples:**\n\n```ruby\n# Delete a branch\nsandbox.git.delete_branch(\"workspace/repo\", \"old-feature\")\n\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/image.mdx",
    "content": "---\ntitle: \"Image\"\nhideTitleOnPage: true\n---\n\n## Image\n\nRepresents an image definition for a Daytona sandbox.\nDo not construct this class directly. Instead use one of its static factory methods,\nsuch as `Image.base()`, `Image.debian_slim()`, or `Image.from_dockerfile()`.\n\n### Constructors\n\n#### new Image()\n\n```ruby\ndef initialize(dockerfile:, context_list:)\n\n```\n\n**Parameters**:\n\n- `dockerfile` _String, nil_ - The Dockerfile content\n- `context_list` _Array\\<Context\\>_ - List of context files\n\n**Returns**:\n\n- `Image` - a new instance of Image\n\n### Methods\n\n#### dockerfile()\n\n```ruby\ndef dockerfile()\n\n```\n\n**Returns**:\n\n- `String, nil` - The generated Dockerfile for the image\n\n#### context_list()\n\n```ruby\ndef context_list()\n\n```\n\n**Returns**:\n\n- `Array\\<Context\\>` - List of context files for the image\n\n#### pip_install()\n\n```ruby\ndef pip_install(*packages, find_links:, index_url:, extra_index_urls:, pre:, extra_options:)\n\n```\n\nAdds commands to install packages using pip\n\n**Parameters**:\n\n- `packages` _Array\\<String\\>_ - The packages to install\n- `find_links` _Array\\<String\\>, nil_ - The find-links to use\n- `index_url` _String, nil_ - The index URL to use\n- `extra_index_urls` _Array\\<String\\>, nil_ - The extra index URLs to use\n- `pre` _Boolean_ - Whether to install pre-release packages\n- `extra_options` _String_ - Additional options to pass to pip\n\n**Returns**:\n\n- `Image` - The image with the pip install commands added\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").pip_install(\"requests\", \"pandas\")\n\n```\n\n#### pip_install_from_requirements()\n\n```ruby\ndef pip_install_from_requirements(requirements_txt, find_links:, index_url:, extra_index_urls:, pre:, extra_options:)\n\n```\n\nInstalls dependencies from a requirements.txt file\n\n**Parameters**:\n\n- `requirements_txt` _String_ - The path to the requirements.txt file\n- `find_links` _Array\\<String\\>, nil_ - The find-links to use\n- `index_url` _String, nil_ - The index URL to use\n- `extra_index_urls` _Array\\<String\\>, nil_ - The extra index URLs to use\n- `pre` _Boolean_ - Whether to install pre-release packages\n- `extra_options` _String_ - Additional options to pass to pip\n\n**Returns**:\n\n- `Image` - The image with the pip install commands added\n\n**Raises**:\n\n- `Sdk:Error` - If the requirements file does not exist\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").pip_install_from_requirements(\"requirements.txt\")\n\n```\n\n#### pip_install_from_pyproject()\n\n```ruby\ndef pip_install_from_pyproject(pyproject_toml, optional_dependencies:, find_links:, index_url:, extra_index_url:, pre:, extra_options:)\n\n```\n\nInstalls dependencies from a pyproject.toml file\n\n**Parameters**:\n\n- `pyproject_toml` _String_ - The path to the pyproject.toml file\n- `optional_dependencies` _Array\\<String\\>_ - The optional dependencies to install\n- `find_links` _String, nil_ - The find-links to use\n- `index_url` _String, nil_ - The index URL to use\n- `extra_index_url` _String, nil_ - The extra index URL to use\n- `pre` _Boolean_ - Whether to install pre-release packages\n- `extra_options` _String_ - Additional options to pass to pip\n\n**Returns**:\n\n- `Image` - The image with the pip install commands added\n\n**Raises**:\n\n- `Sdk:Error` - If pyproject.toml parsing is not supported\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").pip_install_from_pyproject(\"pyproject.toml\", optional_dependencies: [\"dev\"])\n\n```\n\n#### add_local_file()\n\n```ruby\ndef add_local_file(local_path, remote_path)\n\n```\n\nAdds a local file to the image\n\n**Parameters**:\n\n- `local_path` _String_ - The path to the local file\n- `remote_path` _String_ - The path to the file in the image\n\n**Returns**:\n\n- `Image` - The image with the local file added\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").add_local_file(\"package.json\", \"/home/daytona/package.json\")\n\n```\n\n#### add_local_dir()\n\n```ruby\ndef add_local_dir(local_path, remote_path)\n\n```\n\nAdds a local directory to the image\n\n**Parameters**:\n\n- `local_path` _String_ - The path to the local directory\n- `remote_path` _String_ - The path to the directory in the image\n\n**Returns**:\n\n- `Image` - The image with the local directory added\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").add_local_dir(\"src\", \"/home/daytona/src\")\n\n```\n\n#### run_commands()\n\n```ruby\ndef run_commands(*commands)\n\n```\n\nRuns commands in the image\n\n**Parameters**:\n\n- `commands` _Array\\<String\\>_ - The commands to run\n\n**Returns**:\n\n- `Image` - The image with the commands added\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").run_commands('echo \"Hello, world!\"', 'echo \"Hello again!\"')\n\n```\n\n#### env()\n\n```ruby\ndef env(env_vars)\n\n```\n\nSets environment variables in the image\n\n**Parameters**:\n\n- `env_vars` _Hash\\<String, String\\>_ - The environment variables to set\n\n**Returns**:\n\n- `Image` - The image with the environment variables added\n\n**Raises**:\n\n- `Sdk:Error` -\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").env({\"PROJECT_ROOT\" => \"/home/daytona\"})\n\n```\n\n#### workdir()\n\n```ruby\ndef workdir(path)\n\n```\n\nSets the working directory in the image\n\n**Parameters**:\n\n- `path` _String_ - The path to the working directory\n\n**Returns**:\n\n- `Image` - The image with the working directory added\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").workdir(\"/home/daytona\")\n\n```\n\n#### entrypoint()\n\n```ruby\ndef entrypoint(entrypoint_commands)\n\n```\n\nSets the entrypoint for the image\n\n**Parameters**:\n\n- `entrypoint_commands` _Array\\<String\\>_ - The commands to set as the entrypoint\n\n**Returns**:\n\n- `Image` - The image with the entrypoint added\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").entrypoint([\"/bin/bash\"])\n\n```\n\n#### cmd()\n\n```ruby\ndef cmd(cmd)\n\n```\n\nSets the default command for the image\n\n**Parameters**:\n\n- `cmd` _Array\\<String\\>_ - The commands to set as the default command\n\n**Returns**:\n\n- `Image` - The image with the default command added\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").cmd([\"/bin/bash\"])\n\n```\n\n#### dockerfile_commands()\n\n```ruby\ndef dockerfile_commands(dockerfile_commands, context_dir:)\n\n```\n\nAdds arbitrary Dockerfile-like commands to the image\n\n**Parameters**:\n\n- `dockerfile_commands` _Array\\<String\\>_ - The commands to add to the Dockerfile\n- `context_dir` _String, nil_ - The path to the context directory\n\n**Returns**:\n\n- `Image` - The image with the Dockerfile commands added\n\n**Examples:**\n\n```ruby\nimage = Image.debian_slim(\"3.12\").dockerfile_commands([\"RUN echo 'Hello, world!'\"])\n\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/index.mdx",
    "content": "---\ntitle: Ruby SDK Reference\ndescription: Interact with Daytona Sandboxes using the Ruby SDK\nnext: /docs/ruby-sdk/daytona\n---\n\nThe Daytona Ruby SDK provides a robust interface for programmatically interacting with Daytona Sandboxes.\n\n## Installation\n\nInstall the Daytona Ruby SDK using Bundler by adding it to your Gemfile:\n\n```ruby\ngem 'daytona'\n```\n\nThen run:\n\n```bash\nbundle install\n```\n\nOr install it directly:\n\n```bash\ngem install daytona\n```\n\n## Getting Started\n\nHere's a simple example to help you get started with the Daytona Ruby SDK:\n\n```ruby\nrequire 'daytona'\n\n# Initialize the SDK (uses environment variables by default)\ndaytona = Daytona::Daytona.new\n\n# Create a new sandbox\nsandbox = daytona.create\n\n# Execute a command\nresponse = sandbox.process.exec(command: \"echo 'Hello, World!'\")\nputs response.result\n\n# Clean up\ndaytona.delete(sandbox)\n```\n\n## Configuration\n\nThe SDK can be configured using environment variables or by passing options to the constructor:\n\n```ruby\nrequire 'daytona'\n\n# Using environment variables (DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET)\ndaytona = Daytona::Daytona.new\n\n# Using explicit configuration\nconfig = Daytona::Config.new(\n  api_key: 'your-api-key',\n  api_url: 'https://app.daytona.io/api',\n  target: 'us'\n)\ndaytona = Daytona::Daytona.new(config)\n```\n\n## Environment Variables\n\nThe SDK supports the following environment variables:\n\n| Variable | Description |\n|----------|-------------|\n| `DAYTONA_API_KEY` | API key for authentication |\n| `DAYTONA_API_URL` | URL of the Daytona API (defaults to `https://app.daytona.io/api`) |\n| `DAYTONA_TARGET` | Target location for Sandboxes |\n| `DAYTONA_JWT_TOKEN` | JWT token for authentication (alternative to API key) |\n| `DAYTONA_ORGANIZATION_ID` | Organization ID (required when using JWT token) |\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/lsp-server.mdx",
    "content": "---\ntitle: \"LspServer\"\nhideTitleOnPage: true\n---\n\n## LspServer\n\nLspServer class for Daytona SDK.\n\n### Constructors\n\n#### new LspServer()\n\n```ruby\ndef initialize(language_id:, path_to_project:, toolbox_api:, sandbox_id:, otel_state:)\n\n```\n\n**Parameters**:\n\n- `language_id` _Symbol_ -\n- `path_to_project` _String_ -\n- `toolbox_api` _DaytonaToolboxApiClient:LspApi_ -\n- `sandbox_id` _String_ -\n- `otel_state` _Daytona:OtelState, nil_ -\n\n**Returns**:\n\n- `LspServer` - a new instance of LspServer\n\n### Methods\n\n#### language_id()\n\n```ruby\ndef language_id()\n\n```\n\n**Returns**:\n\n- `Symbol`\n\n#### path_to_project()\n\n```ruby\ndef path_to_project()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### toolbox_api()\n\n```ruby\ndef toolbox_api()\n\n```\n\n**Returns**:\n\n- `DaytonaToolboxApiClient:LspApi`\n\n#### sandbox_id()\n\n```ruby\ndef sandbox_id()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### completions()\n\n```ruby\ndef completions(path:, position:)\n\n```\n\nGets completion suggestions at a position in a file\n\n**Parameters**:\n\n- `path` _String_ -\n- `position` _Daytona:LspServer:Position_ -\n\n**Returns**:\n\n- `DaytonaApiClient:CompletionList`\n\n#### did_close()\n\n```ruby\ndef did_close(path)\n\n```\n\nNotify the language server that a file has been closed.\nThis method should be called when a file is closed in the editor to allow\nthe language server to clean up any resources associated with that file.\n\n**Parameters**:\n\n- `path` _String_ -\n\n**Returns**:\n\n- `void`\n\n#### did_open()\n\n```ruby\ndef did_open(path)\n\n```\n\nNotifies the language server that a file has been opened.\nThis method should be called when a file is opened in the editor to enable\nlanguage features like diagnostics and completions for that file. The server\nwill begin tracking the file's contents and providing language features.\n\n**Parameters**:\n\n- `path` _String_ -\n\n**Returns**:\n\n- `void`\n\n#### document_symbols()\n\n```ruby\ndef document_symbols(path)\n\n```\n\nGets symbol information (functions, classes, variables, etc.) from a document.\n\n**Parameters**:\n\n- `path` _String_ -\n\n**Returns**:\n\n- `Array\\<DaytonaToolboxApiClient:LspSymbol]`\n\n#### sandbox_symbols()\n\n```ruby\ndef sandbox_symbols(query)\n\n```\n\nSearches for symbols matching the query string across all files\nin the Sandbox.\n\n**Parameters**:\n\n- `query` _String_ -\n\n**Returns**:\n\n- `Array\\<DaytonaToolboxApiClient:LspSymbol]`\n\n#### start()\n\n```ruby\ndef start()\n\n```\n\nStarts the language server.\nThis method must be called before using any other LSP functionality.\nIt initializes the language server for the specified language and project.\n\n**Returns**:\n\n- `void`\n\n#### stop()\n\n```ruby\ndef stop()\n\n```\n\nStops the language server.\nThis method should be called when the LSP server is no longer needed to\nfree up system resources.\n\n**Returns**:\n\n- `void`\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/object-storage.mdx",
    "content": "---\ntitle: \"ObjectStorage\"\nhideTitleOnPage: true\n---\n\n## ObjectStorage\n\nInitialize ObjectStorage with S3-compatible credentials\n\n### Constructors\n\n#### new ObjectStorage()\n\n```ruby\ndef initialize(endpoint_url:, aws_access_key_id:, aws_secret_access_key:, aws_session_token:, bucket_name:, region:)\n\n```\n\nInitialize ObjectStorage with S3-compatible credentials\n\n**Parameters**:\n\n- `endpoint_url` _String_ - The endpoint URL for the object storage service\n- `aws_access_key_id` _String_ - The access key ID for the object storage service\n- `aws_secret_access_key` _String_ - The secret access key for the object storage service\n- `aws_session_token` _String_ - The session token for the object storage service\n- `bucket_name` _String_ - The name of the bucket to use (defaults to \"daytona-volume-builds\")\n- `region` _String_ - AWS region (defaults to us-east-1)\n\n**Returns**:\n\n- `ObjectStorage` - a new instance of ObjectStorage\n\n### Methods\n\n#### bucket_name()\n\n```ruby\ndef bucket_name()\n\n```\n\n**Returns**:\n\n- `String` - The name of the S3 bucket used for object storage\n\n#### s3_client()\n\n```ruby\ndef s3_client()\n\n```\n\n**Returns**:\n\n- `Aws:S3:Client` - The S3 client\n\n#### upload()\n\n```ruby\ndef upload(path, organization_id, archive_base_path)\n\n```\n\nUploads a file to the object storage service\n\n**Parameters**:\n\n- `path` _String_ - The path to the file to upload\n- `organization_id` _String_ - The organization ID to use\n- `archive_base_path` _String, nil_ - The base path to use for the archive\n\n**Returns**:\n\n- `String` - The hash of the uploaded file\n\n**Raises**:\n\n- `Errno:ENOENT` - If the path does not exist\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/process.mdx",
    "content": "---\ntitle: \"Process\"\nhideTitleOnPage: true\n---\n\n## Process\n\nInitialize a new Process instance\n\n### Constructors\n\n#### new Process()\n\n```ruby\ndef initialize(code_toolbox:, sandbox_id:, toolbox_api:, get_preview_link:, otel_state:)\n\n```\n\nInitialize a new Process instance\n\n**Parameters**:\n\n- `code_toolbox` _Daytona:SandboxPythonCodeToolbox, Daytona:SandboxTsCodeToolbox_ -\n- `sandbox_id` _String_ - The ID of the Sandbox\n- `toolbox_api` _DaytonaToolboxApiClient:ProcessApi_ - API client for Sandbox operations\n- `get_preview_link` _Proc_ - Function to get preview link for a port\n- `otel_state` _Daytona:OtelState, nil_ -\n\n**Returns**:\n\n- `Process` - a new instance of Process\n\n### Methods\n\n#### code_toolbox()\n\n```ruby\ndef code_toolbox()\n\n```\n\n**Returns**:\n\n- `Daytona:SandboxPythonCodeToolbox, ` - Daytona::SandboxPythonCodeToolbox,\n\n#### sandbox_id()\n\n```ruby\ndef sandbox_id()\n\n```\n\n**Returns**:\n\n- `String` - The ID of the Sandbox\n\n#### toolbox_api()\n\n```ruby\ndef toolbox_api()\n\n```\n\n**Returns**:\n\n- `DaytonaToolboxApiClient:ProcessApi` - API client for Sandbox operations\n\n#### get_preview_link()\n\n```ruby\ndef get_preview_link()\n\n```\n\n**Returns**:\n\n- `Proc` - Function to get preview link for a port\n\n#### exec()\n\n```ruby\ndef exec(command:, cwd:, env:, timeout:)\n\n```\n\nExecute a shell command in the Sandbox\n\n**Parameters**:\n\n- `command` _String_ - Shell command to execute\n- `cwd` _String, nil_ - Working directory for command execution. If not specified, uses the sandbox working directory\n- `env` _Hash\\<String, String\\>, nil_ - Environment variables to set for the command\n- `timeout` _Integer, nil_ - Maximum time in seconds to wait for the command to complete. 0 means wait indefinitely\n\n**Returns**:\n\n- `ExecuteResponse` - Command execution results containing exit_code, result, and artifacts\n\n**Examples:**\n\n```ruby\n# Simple command\nresponse = sandbox.process.exec(\"echo 'Hello'\")\nputs response.artifacts.stdout\n=> \"Hello\\n\"\n\n# Command with working directory\nresult = sandbox.process.exec(\"ls\", cwd: \"workspace/src\")\n\n# Command with timeout\nresult = sandbox.process.exec(\"sleep 10\", timeout: 5)\n\n```\n\n#### code_run()\n\n```ruby\ndef code_run(code:, params:, timeout:)\n\n```\n\nExecute code in the Sandbox using the appropriate language runtime\n\n**Parameters**:\n\n- `code` _String_ - Code to execute\n- `params` _CodeRunParams, nil_ - Parameters for code execution\n- `timeout` _Integer, nil_ - Maximum time in seconds to wait for the code to complete. 0 means wait indefinitely\n\n**Returns**:\n\n- `ExecuteResponse` - Code execution result containing exit_code, result, and artifacts\n\n**Examples:**\n\n```ruby\n# Run Python code\nresponse = sandbox.process.code_run(<<~CODE)\n  x = 10\n  y = 20\n  print(f\"Sum: {x + y}\")\nCODE\nputs response.artifacts.stdout  # Prints: Sum: 30\n\n```\n\n#### create_session()\n\n```ruby\ndef create_session(session_id)\n\n```\n\nCreates a new long-running background session in the Sandbox\n\nSessions are background processes that maintain state between commands, making them ideal for\nscenarios requiring multiple related commands or persistent environment setup.\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier for the new session\n\n**Returns**:\n\n- `void`\n\n**Examples:**\n\n```ruby\n# Create a new session\nsession_id = \"my-session\"\nsandbox.process.create_session(session_id)\nsession = sandbox.process.get_session(session_id)\n# Do work...\nsandbox.process.delete_session(session_id)\n\n```\n\n#### get_session()\n\n```ruby\ndef get_session(session_id)\n\n```\n\nGets a session in the Sandbox\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the session to retrieve\n\n**Returns**:\n\n- `DaytonaApiClient:Session` - Session information including session_id and commands\n\n**Examples:**\n\n```ruby\nsession = sandbox.process.get_session(\"my-session\")\nsession.commands.each do |cmd|\n  puts \"Command: #{cmd.command}\"\nend\n\n```\n\n#### get_entrypoint_session()\n\n```ruby\ndef get_entrypoint_session()\n\n```\n\nGets the Sandbox entrypoint session\n\n**Returns**:\n\n- `DaytonaApiClient:Session` - Entrypoint session information including session_id and commands\n\n**Examples:**\n\n```ruby\nsession = sandbox.process.get_entrypoint_session()\nsession.commands.each do |cmd|\n  puts \"Command: #{cmd.command}\"\nend\n\n```\n\n#### get_session_command()\n\n```ruby\ndef get_session_command(session_id:, command_id:)\n\n```\n\nGets information about a specific command executed in a session\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the session\n- `command_id` _String_ - Unique identifier of the command\n\n**Returns**:\n\n- `DaytonaApiClient:Command` - Command information including id, command, and exit_code\n\n**Examples:**\n\n```ruby\ncmd = sandbox.process.get_session_command(session_id: \"my-session\", command_id: \"cmd-123\")\nif cmd.exit_code == 0\n  puts \"Command #{cmd.command} completed successfully\"\nend\n\n```\n\n#### execute_session_command()\n\n```ruby\ndef execute_session_command(session_id:, req:)\n\n```\n\nExecutes a command in the session\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the session to use\n- `req` _Daytona:SessionExecuteRequest_ - Command execution request containing command and run_async\n\n**Returns**:\n\n- `Daytona:SessionExecuteResponse` - Command execution results containing cmd_id, output, stdout, stderr, and exit_code\n\n**Examples:**\n\n```ruby\n# Execute commands in sequence, maintaining state\nsession_id = \"my-session\"\n\n# Change directory\nreq = Daytona::SessionExecuteRequest.new(command: \"cd /workspace\")\nsandbox.process.execute_session_command(session_id:, req:)\n\n# Create a file\nreq = Daytona::SessionExecuteRequest.new(command: \"echo 'Hello' > test.txt\")\nsandbox.process.execute_session_command(session_id:, req:)\n\n# Read the file\nreq = Daytona::SessionExecuteRequest.new(command: \"cat test.txt\")\nresult = sandbox.process.execute_session_command(session_id:, req:)\nputs \"Command stdout: #{result.stdout}\"\nputs \"Command stderr: #{result.stderr}\"\n\n```\n\n#### get_session_command_logs()\n\n```ruby\ndef get_session_command_logs(session_id:, command_id:)\n\n```\n\nGet the logs for a command executed in a session\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the session\n- `command_id` _String_ - Unique identifier of the command\n\n**Returns**:\n\n- `Daytona:SessionCommandLogsResponse` - Command logs including output, stdout, and stderr\n\n**Examples:**\n\n```ruby\nlogs = sandbox.process.get_session_command_logs(session_id: \"my-session\", command_id: \"cmd-123\")\nputs \"Command stdout: #{logs.stdout}\"\nputs \"Command stderr: #{logs.stderr}\"\n\n```\n\n#### get_session_command_logs_async()\n\n```ruby\ndef get_session_command_logs_async(session_id:, command_id:, on_stdout:, on_stderr:)\n\n```\n\nAsynchronously retrieves and processes the logs for a command executed in a session as they become available\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the session\n- `command_id` _String_ - Unique identifier of the command\n- `on_stdout` _Proc_ - Callback function to handle stdout log chunks as they arrive\n- `on_stderr` _Proc_ - Callback function to handle stderr log chunks as they arrive\n\n**Returns**:\n\n- `WebSocket:Client:Simple:Client`\n\n**Examples:**\n\n```ruby\nsandbox.process.get_session_command_logs_async(\n  session_id: \"my-session\",\n  command_id: \"cmd-123\",\n  on_stdout: ->(log) { puts \"[STDOUT]: #{log}\" },\n  on_stderr: ->(log) { puts \"[STDERR]: #{log}\" }\n)\n\n```\n\n#### get_entrypoint_logs()\n\n```ruby\ndef get_entrypoint_logs()\n\n```\n\nGet the sandbox entrypoint logs\n\n**Returns**:\n\n- `Daytona:SessionCommandLogsResponse` - Entrypoint logs including output, stdout, and stderr\n\n**Examples:**\n\n```ruby\nlogs = sandbox.process.get_entrypoint_logs()\nputs \"Command stdout: #{logs.stdout}\"\nputs \"Command stderr: #{logs.stderr}\"\n\n```\n\n#### get_entrypoint_logs_async()\n\n```ruby\ndef get_entrypoint_logs_async(on_stdout:, on_stderr:)\n\n```\n\nAsynchronously retrieves and processes the sandbox entrypoint logs as they become available\n\n**Parameters**:\n\n- `on_stdout` _Proc_ - Callback function to handle stdout log chunks as they arrive\n- `on_stderr` _Proc_ - Callback function to handle stderr log chunks as they arrive\n\n**Returns**:\n\n- `WebSocket:Client:Simple:Client`\n\n**Examples:**\n\n```ruby\nsandbox.process.get_entrypoint_logs_async(\n  on_stdout: ->(log) { puts \"[STDOUT]: #{log}\" },\n  on_stderr: ->(log) { puts \"[STDERR]: #{log}\" }\n)\n\n```\n\n#### send_session_command_input()\n\n```ruby\ndef send_session_command_input(session_id:, command_id:, data:)\n\n```\n\nSends input data to a command executed in a session\n\nThis method allows you to send input to an interactive command running in a session,\nsuch as responding to prompts or providing data to stdin.\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the session\n- `command_id` _String_ - Unique identifier of the command\n- `data` _String_ - Input data to send to the command\n\n**Returns**:\n\n- `void`\n\n#### list_sessions()\n\n```ruby\ndef list_sessions()\n\n```\n\n**Returns**:\n\n- `Array\\<DaytonaApiClient:Session\\>` - List of all sessions in the Sandbox\n\n**Examples:**\n\n```ruby\nsessions = sandbox.process.list_sessions\nsessions.each do |session|\n  puts \"Session #{session.session_id}:\"\n  puts \"  Commands: #{session.commands.length}\"\nend\n\n```\n\n#### delete_session()\n\n```ruby\ndef delete_session(session_id)\n\n```\n\nTerminates and removes a session from the Sandbox, cleaning up any resources associated with it\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the session to delete\n\n**Examples:**\n\n```ruby\n# Create and use a session\nsandbox.process.create_session(\"temp-session\")\n# ... use the session ...\n\n# Clean up when done\nsandbox.process.delete_session(\"temp-session\")\n\n```\n\n#### create_pty_session()\n\n```ruby\ndef create_pty_session(id:, cwd:, envs:, pty_size:)\n\n```\n\nCreates a new PTY (pseudo-terminal) session in the Sandbox.\n\nCreates an interactive terminal session that can execute commands and handle user input.\nThe PTY session behaves like a real terminal, supporting features like command history.\n\n**Parameters**:\n\n- `id` _String_ - Unique identifier for the PTY session. Must be unique within the Sandbox.\n- `cwd` _String, nil_ - Working directory for the PTY session. Defaults to the sandbox's working directory.\n- `envs` _Hash\\<String, String\\>, nil_ - Environment variables to set in the PTY session. These will be merged with\nthe Sandbox's default environment variables.\n- `pty_size` _PtySize, nil_ - Terminal size configuration. Defaults to 80x24 if not specified.\n\n**Returns**:\n\n- `PtyHandle` - Handle for managing the created PTY session. Use this to send input,\nreceive output, resize the terminal, and manage the session lifecycle.\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the PTY session creation fails or the session ID is already in use.\n\n**Examples:**\n\n```ruby\n# Create a basic PTY session\npty_handle = sandbox.process.create_pty_session(id: \"my-pty\")\n\n# Create a PTY session with specific size and environment\npty_size = Daytona::PtySize.new(rows: 30, cols: 120)\npty_handle = sandbox.process.create_pty_session(\n  id: \"my-pty\",\n  cwd: \"/workspace\",\n  envs: {\"NODE_ENV\" => \"development\"},\n  pty_size: pty_size\n)\n\n# Use the PTY session\npty_handle.wait_for_connection\npty_handle.send_input(\"ls -la\\n\")\nresult = pty_handle.wait\npty_handle.disconnect\n\n```\n\n#### connect_pty_session()\n\n```ruby\ndef connect_pty_session(session_id)\n\n```\n\nConnects to an existing PTY session in the Sandbox.\n\nEstablishes a WebSocket connection to an existing PTY session, allowing you to\ninteract with a previously created terminal session.\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the PTY session to connect to.\n\n**Returns**:\n\n- `PtyHandle` - Handle for managing the connected PTY session.\n\n**Raises**:\n\n- `Daytona:Sdk:Error` - If the PTY session doesn't exist or connection fails.\n\n**Examples:**\n\n```ruby\n# Connect to an existing PTY session\npty_handle = sandbox.process.connect_pty_session(\"my-pty-session\")\npty_handle.wait_for_connection\npty_handle.send_input(\"echo 'Hello World'\\n\")\nresult = pty_handle.wait\npty_handle.disconnect\n\n```\n\n#### resize_pty_session()\n\n```ruby\ndef resize_pty_session(session_id, pty_size)\n\n```\n\nResizes a PTY session to the specified dimensions\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the PTY session\n- `pty_size` _PtySize_ - New terminal size\n\n**Returns**:\n\n- `DaytonaApiClient:PtySessionInfo` - Updated PTY session information\n\n**Examples:**\n\n```ruby\npty_size = Daytona::PtySize.new(rows: 30, cols: 120)\nsession_info = sandbox.process.resize_pty_session(\"my-pty\", pty_size)\nputs \"PTY resized to #{session_info.cols}x#{session_info.rows}\"\n\n```\n\n#### delete_pty_session()\n\n```ruby\ndef delete_pty_session(session_id)\n\n```\n\nDeletes a PTY session, terminating the associated process\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the PTY session to delete\n\n**Returns**:\n\n- `void`\n\n**Examples:**\n\n```ruby\nsandbox.process.delete_pty_session(\"my-pty\")\n\n```\n\n#### list_pty_sessions()\n\n```ruby\ndef list_pty_sessions()\n\n```\n\nLists all PTY sessions in the Sandbox\n\n**Returns**:\n\n- `Array\\<DaytonaApiClient:PtySessionInfo\\>` - List of PTY session information\n\n**Examples:**\n\n```ruby\nsessions = sandbox.process.list_pty_sessions\nsessions.each do |session|\n  puts \"PTY Session #{session.id}: #{session.cols}x#{session.rows}\"\nend\n\n```\n\n#### get_pty_session_info()\n\n```ruby\ndef get_pty_session_info(session_id)\n\n```\n\nGets detailed information about a specific PTY session\n\nRetrieves comprehensive information about a PTY session including its current state,\nconfiguration, and metadata.\n\n**Parameters**:\n\n- `session_id` _String_ - Unique identifier of the PTY session to retrieve information for\n\n**Returns**:\n\n- `DaytonaApiClient:PtySessionInfo` - Detailed information about the PTY session including ID, state,\ncreation time, working directory, environment variables, and more\n\n**Examples:**\n\n```ruby\n# Get details about a specific PTY session\nsession_info = sandbox.process.get_pty_session_info(\"my-session\")\nputs \"Session ID: #{session_info.id}\"\nputs \"Active: #{session_info.active}\"\nputs \"Working Directory: #{session_info.cwd}\"\nputs \"Terminal Size: #{session_info.cols}x#{session_info.rows}\"\n\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/sandbox.mdx",
    "content": "---\ntitle: \"Sandbox\"\nhideTitleOnPage: true\n---\n\n## Sandbox\n\nSandbox class for Daytona SDK.\n\n### Constructors\n\n#### new Sandbox()\n\n```ruby\ndef initialize(code_toolbox:, sandbox_dto:, config:, sandbox_api:, otel_state:)\n\n```\n\n**Returns**:\n\n- `Sandbox` - a new instance of Sandbox\n\n### Methods\n\n#### id()\n\n```ruby\ndef id()\n\n```\n\n**Returns**:\n\n- `String` - The ID of the sandbox\n\n#### organization_id()\n\n```ruby\ndef organization_id()\n\n```\n\n**Returns**:\n\n- `String` - The organization ID of the sandbox\n\n#### snapshot()\n\n```ruby\ndef snapshot()\n\n```\n\n**Returns**:\n\n- `String` - The snapshot used for the sandbox\n\n#### user()\n\n```ruby\ndef user()\n\n```\n\n**Returns**:\n\n- `String` - The user associated with the project\n\n#### env()\n\n```ruby\ndef env()\n\n```\n\n**Returns**:\n\n- `Hash\\<String, String\\>` - Environment variables for the sandbox\n\n#### labels()\n\n```ruby\ndef labels()\n\n```\n\n**Returns**:\n\n- `Hash\\<String, String\\>` - Labels for the sandbox\n\n#### public()\n\n```ruby\ndef public()\n\n```\n\n**Returns**:\n\n- `Boolean` - Whether the sandbox http preview is public\n\n#### network_block_all()\n\n```ruby\ndef network_block_all()\n\n```\n\n**Returns**:\n\n- `Boolean` - Whether to block all network access for the sandbox\n\n#### network_allow_list()\n\n```ruby\ndef network_allow_list()\n\n```\n\n**Returns**:\n\n- `String` - Comma-separated list of allowed CIDR network addresses for the sandbox\n\n#### target()\n\n```ruby\ndef target()\n\n```\n\n**Returns**:\n\n- `String` - The target environment for the sandbox\n\n#### cpu()\n\n```ruby\ndef cpu()\n\n```\n\n**Returns**:\n\n- `Float` - The CPU quota for the sandbox\n\n#### gpu()\n\n```ruby\ndef gpu()\n\n```\n\n**Returns**:\n\n- `Float` - The GPU quota for the sandbox\n\n#### memory()\n\n```ruby\ndef memory()\n\n```\n\n**Returns**:\n\n- `Float` - The memory quota for the sandbox\n\n#### disk()\n\n```ruby\ndef disk()\n\n```\n\n**Returns**:\n\n- `Float` - The disk quota for the sandbox\n\n#### state()\n\n```ruby\ndef state()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient:SandboxState` - The state of the sandbox\n\n#### desired_state()\n\n```ruby\ndef desired_state()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient:SandboxDesiredState` - The desired state of the sandbox\n\n#### error_reason()\n\n```ruby\ndef error_reason()\n\n```\n\n**Returns**:\n\n- `String` - The error reason of the sandbox\n\n#### backup_state()\n\n```ruby\ndef backup_state()\n\n```\n\n**Returns**:\n\n- `String` - The state of the backup\n\n#### backup_created_at()\n\n```ruby\ndef backup_created_at()\n\n```\n\n**Returns**:\n\n- `String` - The creation timestamp of the last backup\n\n#### auto_stop_interval()\n\n```ruby\ndef auto_stop_interval()\n\n```\n\n**Returns**:\n\n- `Float` - Auto-stop interval in minutes (0 means disabled)\n\n#### auto_archive_interval()\n\n```ruby\ndef auto_archive_interval()\n\n```\n\n**Returns**:\n\n- `Float` - Auto-archive interval in minutes\n\n#### auto_delete_interval()\n\n```ruby\ndef auto_delete_interval()\n\n```\n\n(negative value means disabled, 0 means delete immediately upon stopping)\n\n**Returns**:\n\n- `Float` - Auto-delete interval in minutes\n\n#### volumes()\n\n```ruby\ndef volumes()\n\n```\n\n**Returns**:\n\n- `Array\\<DaytonaApiClient:SandboxVolume\\>` - Array of volumes attached to the sandbox\n\n#### build_info()\n\n```ruby\ndef build_info()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient:BuildInfo` - Build information for the sandbox\n\n#### created_at()\n\n```ruby\ndef created_at()\n\n```\n\n**Returns**:\n\n- `String` - The creation timestamp of the sandbox\n\n#### updated_at()\n\n```ruby\ndef updated_at()\n\n```\n\n**Returns**:\n\n- `String` - The last update timestamp of the sandbox\n\n#### daemon_version()\n\n```ruby\ndef daemon_version()\n\n```\n\n**Returns**:\n\n- `String` - The version of the daemon running in the sandbox\n\n#### code_toolbox()\n\n```ruby\ndef code_toolbox()\n\n```\n\n**Returns**:\n\n- `Daytona:SandboxPythonCodeToolbox, Daytona:SandboxTsCodeToolbox`\n\n#### config()\n\n```ruby\ndef config()\n\n```\n\n**Returns**:\n\n- `Daytona:Config`\n\n#### sandbox_api()\n\n```ruby\ndef sandbox_api()\n\n```\n\n**Returns**:\n\n- `DaytonaApiClient:SandboxApi`\n\n#### process()\n\n```ruby\ndef process()\n\n```\n\n**Returns**:\n\n- `Daytona:Process`\n\n#### fs()\n\n```ruby\ndef fs()\n\n```\n\n**Returns**:\n\n- `Daytona:FileSystem`\n\n#### git()\n\n```ruby\ndef git()\n\n```\n\n**Returns**:\n\n- `Daytona:Git`\n\n#### computer_use()\n\n```ruby\ndef computer_use()\n\n```\n\n**Returns**:\n\n- `Daytona:ComputerUse`\n\n#### code_interpreter()\n\n```ruby\ndef code_interpreter()\n\n```\n\n**Returns**:\n\n- `Daytona:CodeInterpreter`\n\n#### archive()\n\n```ruby\ndef archive()\n\n```\n\nArchives the sandbox, making it inactive and preserving its state. When sandboxes are\narchived, the entire filesystem state is moved to cost-effective object storage, making it\npossible to keep sandboxes available for an extended period. The tradeoff between archived\nand stopped states is that starting an archived sandbox takes more time, depending on its size.\nSandbox must be stopped before archiving.\n\n**Returns**:\n\n- `void`\n\n#### auto_archive_interval=()\n\n```ruby\ndef auto_archive_interval=(interval)\n\n```\n\nSets the auto-archive interval for the Sandbox.\nThe Sandbox will automatically archive after being continuously stopped for the specified interval.\n\n**Parameters**:\n\n- `interval` _Integer_ -\n\n**Returns**:\n\n- `Integer`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` -\n\n#### auto_delete_interval=()\n\n```ruby\ndef auto_delete_interval=(interval)\n\n```\n\nSets the auto-delete interval for the Sandbox.\nThe Sandbox will automatically delete after being continuously stopped for the specified interval.\n\n**Parameters**:\n\n- `interval` _Integer_ -\n\n**Returns**:\n\n- `Integer`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` -\n\n#### auto_stop_interval=()\n\n```ruby\ndef auto_stop_interval=(interval)\n\n```\n\nSets the auto-stop interval for the Sandbox.\nThe Sandbox will automatically stop after being idle (no new events) for the specified interval.\nEvents include any state changes or interactions with the Sandbox through the SDK.\nInteractions using Sandbox Previews are not included.\n\n**Parameters**:\n\n- `interval` _Integer_ -\n\n**Returns**:\n\n- `Integer`\n\n**Raises**:\n\n- `Daytona:Sdk:Error` -\n\n#### create_ssh_access()\n\n```ruby\ndef create_ssh_access(expires_in_minutes)\n\n```\n\nCreates an SSH access token for the sandbox.\n\n**Parameters**:\n\n- `expires_in_minutes` _Integer_ - TThe number of minutes the SSH access token will be valid for\n\n**Returns**:\n\n- `DaytonaApiClient:SshAccessDto`\n\n#### delete()\n\n```ruby\ndef delete()\n\n```\n\n**Returns**:\n\n- `void`\n\n#### get_user_home_dir()\n\n```ruby\ndef get_user_home_dir()\n\n```\n\nGets the user's home directory path for the logged in user inside the Sandbox.\n\n**Returns**:\n\n- `String` - The absolute path to the Sandbox user's home directory for the logged in user\n\n**Examples:**\n\n```ruby\nuser_home_dir = sandbox.get_user_home_dir\nputs \"Sandbox user home: #{user_home_dir}\"\n\n```\n\n#### get_work_dir()\n\n```ruby\ndef get_work_dir()\n\n```\n\nGets the working directory path inside the Sandbox.\n\n**Returns**:\n\n- `String` - The absolute path to the Sandbox working directory. Uses the WORKDIR specified\nin the Dockerfile if present, or falling back to the user's home directory if not.\n\n**Examples:**\n\n```ruby\nwork_dir = sandbox.get_work_dir\nputs \"Sandbox working directory: #{work_dir}\"\n\n```\n\n#### labels=()\n\n```ruby\ndef labels=(labels)\n\n```\n\nSets labels for the Sandbox.\n\n**Parameters**:\n\n- `labels` _Hash\\<String, String\\>_ -\n\n**Returns**:\n\n- `Hash\\<String, String\\>`\n\n#### preview_url()\n\n```ruby\ndef preview_url(port)\n\n```\n\nRetrieves the preview link for the sandbox at the specified port. If the port is closed,\nit will be opened automatically. For private sandboxes, a token is included to grant access\nto the URL.\n\n**Parameters**:\n\n- `port` _Integer_ -\n\n**Returns**:\n\n- `DaytonaApiClient:PortPreviewUrl`\n\n#### create_signed_preview_url()\n\n```ruby\ndef create_signed_preview_url(port, expires_in_seconds)\n\n```\n\nCreates a signed preview URL for the sandbox at the specified port.\n\n**Parameters**:\n\n- `port` _Integer_ - The port to open the preview link on\n- `expires_in_seconds` _Integer, nil_ - The number of seconds the signed preview URL\nwill be valid for. Defaults to 60 seconds.\n\n**Returns**:\n\n- `DaytonaApiClient:SignedPortPreviewUrl` - The signed preview URL response object\n\n**Examples:**\n\n```ruby\nsigned_url = sandbox.create_signed_preview_url(3000, 120)\nputs \"Signed URL: #{signed_url.url}\"\nputs \"Token: #{signed_url.token}\"\n\n```\n\n#### expire_signed_preview_url()\n\n```ruby\ndef expire_signed_preview_url(port, token)\n\n```\n\nExpires a signed preview URL for the sandbox at the specified port.\n\n**Parameters**:\n\n- `port` _Integer_ - The port to expire the signed preview URL on\n- `token` _String_ - The token to expire\n\n**Returns**:\n\n- `void`\n\n**Examples:**\n\n```ruby\nsandbox.expire_signed_preview_url(3000, \"token-value\")\n\n```\n\n#### refresh()\n\n```ruby\ndef refresh()\n\n```\n\nRefresh the Sandbox data from the API.\n\n**Returns**:\n\n- `void`\n\n#### refresh_activity()\n\n```ruby\ndef refresh_activity()\n\n```\n\nRefreshes the sandbox activity to reset the timer for automated lifecycle management actions.\n\nThis method updates the sandbox's last activity timestamp without changing its state.\nIt is useful for keeping long-running sessions alive while there is still user activity.\n\n**Returns**:\n\n- `void`\n\n**Examples:**\n\n```ruby\nsandbox.refresh_activity\n\n```\n\n#### revoke_ssh_access()\n\n```ruby\ndef revoke_ssh_access(token)\n\n```\n\nRevokes an SSH access token for the sandbox.\n\n**Parameters**:\n\n- `token` _String_ -\n\n**Returns**:\n\n- `void`\n\n#### start()\n\n```ruby\ndef start(timeout)\n\n```\n\nStarts the Sandbox and waits for it to be ready.\n\n**Parameters**:\n\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s).\n\n**Returns**:\n\n- `void`\n\n#### recover()\n\n```ruby\ndef recover(timeout)\n\n```\n\nRecovers the Sandbox from a recoverable error and waits for it to be ready.\n\n**Parameters**:\n\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s).\n\n**Returns**:\n\n- `void`\n\n**Examples:**\n\n```ruby\nsandbox = daytona.get('my-sandbox-id')\nsandbox.recover(timeout: 40)  # Wait up to 40 seconds\nputs 'Sandbox recovered successfully'\n\n```\n\n#### stop()\n\n```ruby\ndef stop(timeout)\n\n```\n\nStops the Sandbox and waits for it to be stopped.\n\n**Parameters**:\n\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s).\n\n**Returns**:\n\n- `void`\n\n#### resize()\n\n```ruby\ndef resize(resources, timeout)\n\n```\n\nResizes the Sandbox resources.\n\nChanges the CPU, memory, or disk allocation for the Sandbox. Resizing a started\nsandbox allows increasing CPU and memory. To resize disk or decrease resources,\nthe sandbox must be stopped first.\n\n**Parameters**:\n\n- `resources` _Daytona:Resources_ - New resource configuration\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s)\n\n**Returns**:\n\n- `void`\n\n**Raises**:\n\n- `Sdk:Error` -\n\n**Examples:**\n\n```ruby\nsandbox.resize(Daytona::Resources.new(cpu: 4, memory: 8))\n\n```\n\n```ruby\nsandbox.stop\nsandbox.resize(Daytona::Resources.new(cpu: 2, memory: 4, disk: 30))\n\n```\n\n#### wait_for_resize_complete()\n\n```ruby\ndef wait_for_resize_complete(_timeout)\n\n```\n\nWaits for the Sandbox resize operation to complete.\nPolls the Sandbox status until the state is no longer 'resizing'.\n\n**Parameters**:\n\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s)\n\n**Returns**:\n\n- `void`\n\n#### create_lsp_server()\n\n```ruby\ndef create_lsp_server(language_id:, path_to_project:)\n\n```\n\nCreates a new Language Server Protocol (LSP) server instance.\nThe LSP server provides language-specific features like code completion,\ndiagnostics, and more.\n\n**Parameters**:\n\n- `language_id` _Symbol_ - The language server type (e.g., Daytona::LspServer::Language::PYTHON)\n- `path_to_project` _String_ - Path to the project root directory. Relative paths are resolved\nbased on the sandbox working directory.\n\n**Returns**:\n\n- `Daytona:LspServer`\n\n#### validate_ssh_access()\n\n```ruby\ndef validate_ssh_access(token)\n\n```\n\nValidates an SSH access token for the sandbox.\n\n**Parameters**:\n\n- `token` _String_ -\n\n**Returns**:\n\n- `DaytonaApiClient:SshAccessValidationDto`\n\n#### wait_for_sandbox_start()\n\n```ruby\ndef wait_for_sandbox_start(_timeout)\n\n```\n\nWaits for the Sandbox to reach the 'started' state. Polls the Sandbox status until it\nreaches the 'started' state or encounters an error.\n\n**Parameters**:\n\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s).\n\n**Returns**:\n\n- `void`\n\n#### wait_for_sandbox_stop()\n\n```ruby\ndef wait_for_sandbox_stop(_timeout)\n\n```\n\nWaits for the Sandbox to reach the 'stopped' state. Polls the Sandbox status until it\nreaches the 'stopped' state or encounters an error.\nTreats destroyed as stopped to cover ephemeral sandboxes that are automatically deleted after stopping.\n\n**Parameters**:\n\n- `timeout` _Numeric_ - Maximum wait time in seconds (defaults to 60 s).\n\n**Returns**:\n\n- `void`\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/snapshot.mdx",
    "content": "---\ntitle: \"SnapshotService\"\nhideTitleOnPage: true\n---\n\n## SnapshotService\n\nSnapshotService class for Daytona SDK.\n\n### Constructors\n\n#### new SnapshotService()\n\n```ruby\ndef initialize(snapshots_api:, object_storage_api:, default_region_id:, otel_state:)\n\n```\n\n**Parameters**:\n\n- `snapshots_api` _DaytonaApiClient:SnapshotsApi_ - The snapshots API client\n- `object_storage_api` _DaytonaApiClient:ObjectStorageApi_ - The object storage API client\n- `default_region_id` _String, nil_ - Default region ID for snapshot creation\n- `otel_state` _Daytona:OtelState, nil_ -\n\n**Returns**:\n\n- `SnapshotService` - a new instance of SnapshotService\n\n### Methods\n\n#### list()\n\n```ruby\ndef list(page:, limit:)\n\n```\n\nList all Snapshots.\n\n**Parameters**:\n\n- `page` _Integer, Nil_ -\n- `limit` _Integer, Nil_ -\n\n**Returns**:\n\n- `Daytona:PaginatedResource` - Paginated list of all Snapshots\n\n**Raises**:\n\n- `Daytona:Sdk:Error` -\n\n**Examples:**\n\n```ruby\ndaytona = Daytona::Daytona.new\nresponse = daytona.snapshot.list(page: 1, limit: 10)\nsnapshots.items.each { |snapshot| puts \"#{snapshot.name} (#{snapshot.image_name})\" }\n\n```\n\n#### delete()\n\n```ruby\ndef delete(snapshot)\n\n```\n\nDelete a Snapshot.\n\n**Parameters**:\n\n- `snapshot` _Daytona:Snapshot_ - Snapshot to delete\n\n**Returns**:\n\n- `void`\n\n**Examples:**\n\n```ruby\ndaytona = Daytona::Daytona.new\nsnapshot = daytona.snapshot.get(\"demo\")\ndaytona.snapshot.delete(snapshot)\nputs \"Snapshot deleted\"\n\n```\n\n#### get()\n\n```ruby\ndef get(name)\n\n```\n\nGet a Snapshot by name.\n\n**Parameters**:\n\n- `name` _String_ - Name of the Snapshot to get\n\n**Returns**:\n\n- `Daytona:Snapshot` - The Snapshot object\n\n**Examples:**\n\n```ruby\ndaytona = Daytona::Daytona.new\nsnapshot = daytona.snapshot.get(\"demo\")\nputs \"#{snapshot.name} (#{snapshot.image_name})\"\n\n```\n\n#### create()\n\n```ruby\ndef create(params, on_logs:)\n\n```\n\nCreates and registers a new snapshot from the given Image definition.\n\n**Parameters**:\n\n- `params` _Daytona:CreateSnapshotParams_ - Parameters for snapshot creation\n- `on_logs` _Proc, Nil_ - Callback proc handling snapshot creation logs\n\n**Returns**:\n\n- `Daytona:Snapshot` - The created snapshot\n\n**Examples:**\n\n```ruby\nimage = Image.debianSlim('3.12').pipInstall('numpy')\nparams = CreateSnapshotParams.new(name: 'my-snapshot', image: image)\nsnapshot = daytona.snapshot.create(params) do |chunk|\n  print chunk\nend\n\n```\n\n#### activate()\n\n```ruby\ndef activate(snapshot)\n\n```\n\nActivate a snapshot\n\n**Parameters**:\n\n- `snapshot` _Daytona:Snapshot_ - The snapshot instance\n\n**Returns**:\n\n- `Daytona:Snapshot`\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/volume-service.mdx",
    "content": "---\ntitle: \"VolumeService\"\nhideTitleOnPage: true\n---\n\n## VolumeService\n\nService for managing Daytona Volumes. Can be used to list, get, create and delete Volumes.\n\n### Constructors\n\n#### new VolumeService()\n\n```ruby\ndef initialize(volumes_api, otel_state:)\n\n```\n\nService for managing Daytona Volumes. Can be used to list, get, create and delete Volumes.\n\n**Parameters**:\n\n- `volumes_api` _DaytonaApiClient:VolumesApi_ -\n- `otel_state` _Daytona:OtelState, nil_ -\n\n**Returns**:\n\n- `VolumeService` - a new instance of VolumeService\n\n### Methods\n\n#### create()\n\n```ruby\ndef create(name)\n\n```\n\nCreate new Volume.\n\n**Parameters**:\n\n- `name` _String_ -\n\n**Returns**:\n\n- `Daytona:Volume`\n\n#### delete()\n\n```ruby\ndef delete(volume)\n\n```\n\nDelete a Volume.\n\n**Parameters**:\n\n- `volume` _Daytona:Volume_ -\n\n**Returns**:\n\n- `void`\n\n#### get()\n\n```ruby\ndef get(name, create:)\n\n```\n\nGet a Volume by name.\n\n**Parameters**:\n\n- `name` _String_ -\n- `create` _Boolean_ -\n\n**Returns**:\n\n- `Daytona:Volume`\n\n#### list()\n\n```ruby\ndef list()\n\n```\n\nList all Volumes.\n\n**Returns**:\n\n- `Array\\<Daytona:Volume\\>`\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ruby-sdk/volume.mdx",
    "content": "---\ntitle: \"Volume\"\nhideTitleOnPage: true\n---\n\n## Volume\n\nInitialize volume from DTO\n\n### Constructors\n\n#### new Volume()\n\n```ruby\ndef initialize(volume_dto)\n\n```\n\nInitialize volume from DTO\n\n**Parameters**:\n\n- `volume_dto` _DaytonaApiClient:SandboxVolume_ -\n\n**Returns**:\n\n- `Volume` - a new instance of Volume\n\n### Methods\n\n#### id()\n\n```ruby\ndef id()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### name()\n\n```ruby\ndef name()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### organization_id()\n\n```ruby\ndef organization_id()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### state()\n\n```ruby\ndef state()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### created_at()\n\n```ruby\ndef created_at()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### updated_at()\n\n```ruby\ndef updated_at()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### last_used_at()\n\n```ruby\ndef last_used_at()\n\n```\n\n**Returns**:\n\n- `String`\n\n#### error_reason()\n\n```ruby\ndef error_reason()\n\n```\n\n**Returns**:\n\n- `String, nil`\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/runners.mdx",
    "content": "---\ntitle: Customer Managed Compute\n---\n\nRunners are machines that power Daytona's compute plane, providing the underlying infrastructure for running sandbox workloads. Each runner is responsible for:\n\n- **Workload execution**: running sandbox workloads\n- **Resource management**: allocating and monitoring CPU, memory, and disk resources\n- **Health reporting**: continuously reporting metrics and health status to the Daytona control plane\n- **Network connectivity**: managing networking, proxy connections, and SSH access for sandboxes\n\nRunners in [shared](/docs/en/regions#shared-regions) and [dedicated](/docs/en/regions#dedicated-regions) regions are fully managed by Daytona — from provisioning and maintenance to monitoring and scaling. For custom regions, you bring your own runner machines and are responsible for their management and operation.\n\n:::caution\nCustom runners are currently an experimental feature and may change in future releases.\nTo request access, please contact [support@daytona.io](mailto:support@daytona.io).\n:::\n\n## Custom regions\n\nCustom regions are created and managed by your organization, allowing you to use your own runner machines and scale compute resources independently within each region. This provides maximum control over data locality, compliance, and infrastructure configuration.\n\nAdditionally, custom regions have no limits applied for concurrent resource usage, giving you full control over capacity and performance.\n\n### Custom region configuration\n\n**name** (required)\n\n- A unique identifier for your region\n- Must contain only letters, numbers, underscores, periods, and hyphens\n- Used for targeting this region when creating a sandbox\n\n**proxyUrl** (optional)\n\n- The URL of the proxy service that routes traffic to sandboxes in this region\n- Required if the runner machines in this region are deployed in a private network\n\n**sshGatewayUrl** (optional)\n\n- The URL of the SSH gateway that handles SSH connections to sandboxes in this region\n- Required if the runner machines in this region are deployed in a private network\n\n**snapshotManagerUrl** (optional)\n\n- The URL of the snapshot manager that handles storage and retrieval of snapshots in this region\n- Required if the runner machines in this region are deployed in a private network\n\n### Custom region credentials\n\nWhen you create a custom region, Daytona will provide credentials for any optional services you configure:\n\n- An API key that should be used by your proxy service to authenticate with Daytona\n- An API key that should be used by your SSH gateway service to authenticate with Daytona\n- Basic authentication credentials that Daytona uses to access your snapshot manager service\n\n:::note\nIf needed, these credentials can always be regenerated, but you will need to redeploy the corresponding services with the updated credentials.\n:::\n\n\n## Custom runners\n\nCustom runners are created and managed by your organization, allowing you to use your own runner machines and scale compute resources independently within each custom region.\n\n### Custom runner configuration\n\n**name** (required)\n\n- A unique identifier for the runner\n- Must contain only letters, numbers, underscores, periods, and hyphens\n- Helps distinguish between multiple runners in the same region\n\n**regionId** (required)\n\n- The ID of the region this runner is assigned to\n- Must be a custom region owned by your organization\n- All runners in a region share the region's proxy and SSH gateway configuration\n\n### Custom runner token\n\nWhen you create a custom runner, Daytona will provide you with a **token** that should be used by your runner to authenticate with Daytona.\n\n:::note\nSave this token securely. You won't be able to see it again.\n:::\n\n### Installing the custom runner\n\nAfter registering a custom runner and obtaining its secure token, you need to install and configure the Daytona runner application on your infrastructure.\n\n:::note\nDetailed installation instructions for the runner application will be provided in a future update. For assistance with runner installation, please contact [support@daytona.io](mailto:support@daytona.io).\n:::\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/sandboxes.mdx",
    "content": "---\ntitle: Sandboxes\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport SandboxDiagram from '@components/SandboxDiagram.astro'\n\nDaytona provides **full composable computers** &mdash; **sandboxes** &mdash; for AI agents. Sandboxes are isolated runtime environments you can manage programmatically to run code. Each sandbox runs in isolation, giving it a dedicated kernel, filesystem, network stack, and allocated vCPU, RAM, and disk. Agents get access to a full composable computer environment where they can install packages, run servers, compile code, and manage processes.\n\nSandboxes have **1 vCPU**, **1GB RAM**, and **3GiB disk** by default. [Organizations](/docs/en/organizations) get a maximum sandbox resource limit of **4 vCPUs**, **8GB RAM**, and **10GB disk**. For more power, see [resources](#resources) or contact [support@daytona.io](mailto:support@daytona.io).\n\nSandboxes are built from OCI-compliant images. A [snapshot](/docs/en/snapshots) captures a fully configured environment: base OS, installed packages, dependencies, and configuration to create new sandboxes.\n\nEach sandbox has its own network stack with per-sandbox firewall rules. By default, sandboxes follow standard network policies, but you can restrict egress to a specific set of allowed destinations or block all outbound traffic entirely. For details on configuring network access, see [network settings](/docs/en/network-limits).\n\nFor a detailed overview of the Daytona platform, see [architecture](/docs/en/architecture).\n\n## Sandbox lifecycle\n\nThroughout its lifecycle, a Daytona Sandbox can have several different states. The diagram below shows the states and possible transitions between them.\n\n<SandboxDiagram />\n\n## Multiple runtime support\n\nDaytona Sandboxes support Python, TypeScript, and JavaScript programming language runtimes for direct code execution inside the sandbox.\n\nThe `language` parameter controls which programming language runtime is used for the sandbox:\n\n- **`python`**\n- **`typescript`**\n- **`javascript`**\n\nIf omitted, the Daytona SDK will default to `python`. To override this, explicitly set the `language` value when creating the sandbox.\n\n:::note\n**Sandbox Names**: You can specify a custom name for your sandbox using the `name` parameter. If not provided, the sandbox ID will be used as the name. Sandbox names are reusable - once a sandbox with a specific name is destroyed, that name becomes available for use again.\n:::\n\n## Create Sandboxes\n\nDaytona provides methods to create sandboxes using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/) or programatically using the Daytona [Python](/docs/en/python-sdk/sync/sandbox), [TypeScript](/docs/en/typescript-sdk/sandbox), [Ruby](/docs/en/ruby-sdk/sandbox), [Go](/docs/en/go-sdk/daytona#type-sandbox) **SDKs**, [CLI](/docs/en/tools/cli#daytona-create), or [API](/docs/en/tools/api#daytona/tag/sandbox).\n\nYou can specify [programming language runtime](/docs/en/sandboxes#multiple-runtime-support), [snapshots](/docs/en/snapshots), [resources](/docs/en/sandboxes#resources), [regions](/docs/en/regions), [environment variables](/docs/en/configuration#environment-variables), and [volumes](/docs/en/volumes) for each sandbox. Running sandboxes utilize CPU, memory, and disk storage. Every resource is charged per second of usage.\n\n1. Navigate to [Daytona Sandboxes ↗](https://app.daytona.io/dashboard/sandboxes)\n2. Click the **Create Sandbox** button\n3. Enter the name of the sandbox\n4. Select a source for the sandbox:\n\n- [Snapshot](/docs/en/snapshots): a pre-configured sandbox template\n- **Image**: OCI-compliant container image ([public](/docs/en/snapshots#using-public-images), [local](/docs/en/snapshots#using-local-images), [private registries](/docs/en/snapshots#using-images-from-private-registries)). Images require setting [sandbox resources](/docs/en/sandboxes#resources). Default: **1 vCPU**, **1GB RAM**, **3GiB disk**.\n\n5. Select a [region](/docs/en/regions): if not specified, your organization's default region will be used\n6. Define [sandbox lifecycle management](#automated-lifecycle-management) options or set as an [ephemeral sandbox](#ephemeral-sandboxes)\n7. Add environment variables in key-value pairs or import them from a **`.env`** file\n8. Add labels in key-value pairs\n9. Select network settings:\n\n- **Public HTTP preview**: allow public access to HTTP [preview URLs](/docs/en/preview)\n- **Block all network access**: block all outbound network access\n\n10. Click the **Create** button to create the sandbox\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, CreateSandboxFromSnapshotParams\n\ndaytona = Daytona()\n\n# Create a sandbox\nsandbox = daytona.create()\n\n# Create a sandbox with python\nparams = CreateSandboxFromSnapshotParams(language=\"python\")\nsandbox = daytona.create(params)\n\n# Create a sandbox with a custom name\nparams = CreateSandboxFromSnapshotParams(name=\"my_awesome_sandbox\")\nsandbox = daytona.create(params)\n\n# Create a sandbox with custom labels\nparams = CreateSandboxFromSnapshotParams(labels={\"LABEL\": \"label\"})\nsandbox = daytona.create(params)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\n\n// Create a sandbox\nconst sandbox = await daytona.create();\n\n// Create a sandbox with typescript\nconst sandbox = await daytona.create({ language: 'typescript' });\n\n// Create a sandbox with a custom name\nconst sandbox = await daytona.create({ name: 'my_awesome_sandbox' });\n\n// Create a sandbox with custom labels\nconst sandbox = await daytona.create({ labels: { LABEL: 'label' } });\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Create a sandbox\nsandbox = daytona.create\n\n# Create a sandbox with python\nparams = Daytona::CreateSandboxFromSnapshotParams.new(language: Daytona::CodeLanguage::PYTHON)\nsandbox = daytona.create(params)\n\n# Create a sandbox with custom labels\nparams = Daytona::CreateSandboxFromSnapshotParams.new(labels: { 'LABEL' => 'label' })\nsandbox = daytona.create(params)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a sandbox\nparams := types.SnapshotParams{\n    SandboxBaseParams: types.SandboxBaseParams{\n        Language: types.CodeLanguagePython,\n    },\n}\nsandbox, err := client.Create(ctx, params)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona create [flags]\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \\\n  --data '{}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), [API](/docs/en/tools/api/#daytona/), and [CLI](/docs/en/tools/cli/) references:\n\n> [**create (Python SDK)**](/docs/en/python-sdk/sync/daytona#daytonacreate)\n>\n> [**create (TypeScript SDK)**](/docs/en/typescript-sdk/daytona#create)\n>\n> [**create (Ruby SDK)**](/docs/en/ruby-sdk/daytona#create)\n>\n> [**Create (Go SDK)**](/docs/en/go-sdk/daytona/#Client.Create)\n>\n> [**create (CLI)**](/docs/en/tools/cli/#daytona-create)\n>\n> [**create (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox)\n\n### Resources\n\nSandboxes have **1 vCPU**, **1GB RAM**, and **3GiB disk** by default. Organizations get a maximum sandbox resource limit of **4 vCPUs**, **8GB RAM**, and **10GB disk**.\n\nTo set custom sandbox resources (CPU, memory, and disk space), use the `Resources` class:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, Resources, CreateSandboxFromImageParams, Image\n\ndaytona = Daytona()\n\n# Create a sandbox with custom resources\nresources = Resources(\n    cpu=2,    # 2 CPU cores\n    memory=4, # 4GB RAM\n    disk=8,   # 8GB disk space\n)\n\nparams = CreateSandboxFromImageParams(\n    image=Image.debian_slim(\"3.12\"),\n    resources=resources\n)\n\nsandbox = daytona.create(params)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, Image } from \"@daytonaio/sdk\";\n\nasync function main() {\n  const daytona = new Daytona();\n\n  // Create a sandbox with custom resources\n  const sandbox = await daytona.create({\n    image: Image.debianSlim(\"3.12\"),\n    resources: {\n      cpu: 2,     // 2 CPU cores\n      memory: 4,  // 4GB RAM\n      disk: 8,    // 8GB disk space\n    },\n  });\n}\n\nmain();\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Create a sandbox with custom resources\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromImageParams.new(\n    image: Daytona::Image.debian_slim('3.12'),\n    resources: Daytona::Resources.new(\n      cpu: 2,     # 2 CPU cores\n      memory: 4,  # 4GB RAM\n      disk: 8     # 8GB disk space\n    )\n  )\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a sandbox with custom resources\nsandbox, err := client.Create(ctx, types.ImageParams{\n    Image: \"python:3.11\",\n    Resources: &types.Resources{\n        CPU:    2,   // 2 CPU cores\n        Memory: 4,   // 4GiB RAM\n        Disk:   8,   // 8GiB disk space\n    },\n})\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\n# --memory is in MB; --disk is in GB\ndaytona create --cpu 2 --memory 4096 --disk 8\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \\\n  --data '{\n  \"cpu\": 2,\n  \"memory\": 4,\n  \"disk\": 8\n}'\n```\n\n</TabItem>\n</Tabs>\n\nAll resource parameters are optional and must be integers. If not specified, Daytona will use the default values listed below.\n\n| **Resource** | **Unit** | **Default** | **Minimum** | **Maximum** |\n| ------------ | -------- | ----------- | ----------- | ----------- |\n| CPU          | vCPU     | **`1`**     | **`1`**     | **`4`**     |\n| Memory       | GiB      | **`1`**     | **`1`**     | **`8`**     |\n| Disk         | GiB      | **`3`**     | **`1`**     | **`10`**    |\n\nMaximum values are per-sandbox limits set at the [organization](/docs/en/organizations) level. Contact [support@daytona.io](mailto:support@daytona.io) to increase limits.\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/daytona#resources), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/) references:\n\n> [**Resources (Python SDK)**](/docs/en/python-sdk/sync/sandbox#resources)\n>\n> [**Resources (TypeScript SDK)**](/docs/en/typescript-sdk/daytona#resources)\n>\n> [**Resources (Ruby SDK)**](/docs/en/ruby-sdk/daytona)\n>\n> [**Resources (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox)\n>\n> [**Resources (CLI)**](/docs/en/tools/cli/#daytona-create)\n\n### Ephemeral Sandboxes\n\nEphemeral Sandboxes are automatically deleted once they are stopped. They are useful for short-lived tasks or for testing purposes.\n\nTo create an ephemeral Sandbox, set the `ephemeral` parameter to `True` when creating a sandbox:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, CreateSandboxFromSnapshotParams\n\ndaytona = Daytona()\n\n# Create an ephemeral sandbox\nparams = CreateSandboxFromSnapshotParams(\n  ephemeral=True,\n  auto_stop_interval=5 # The ephemeral sandbox will be deleted after 5 minutes of inactivity\n)\nsandbox = daytona.create(params)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona = new Daytona();\n\n// Create an ephemeral sandbox\nconst sandbox = await daytona.create({\n  ephemeral: true,\n  autoStopInterval: 5 // The ephemeral sandbox will be deleted after 5 minutes of inactivity\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Create an ephemeral Sandbox\nparams = Daytona::CreateSandboxFromSnapshotParams.new(\n  ephemeral: true,\n  auto_stop_interval: 5 # The ephemeral sandbox will be deleted after 5 minutes of inactivity\n)\nsandbox = daytona.create(params)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create an ephemeral sandbox\nautoStopInterval := 5\nparams := types.SnapshotParams{\n    SandboxBaseParams: types.SandboxBaseParams{\n        Language:         types.CodeLanguagePython,\n        Ephemeral:        true,\n        AutoStopInterval: &autoStopInterval,\n    },\n}\nsandbox, err := client.Create(ctx, params)\n```\n\n</TabItem>\n</Tabs>\n\n:::note\nSetting [\"autoDeleteInterval: 0\"](#auto-delete-interval) has the same effect as setting \"ephemeral\" to `true`.\n:::\n\n### Network settings (Firewall)\n\nDaytona Sandboxes provide configurable network firewall controls to enhance security and manage connectivity.\nBy default, network access follows standard security policies, but you can [customize network settings](/docs/en/network-limits) when creating a sandbox.\n\n## Start Sandboxes\n\nDaytona provides options to start sandboxes in [Daytona Dashboard ↗](https://app.daytona.io/dashboard/) or programmatically using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/#daytona/) references.\n\n1. Navigate to [Daytona Sandboxes ↗](https://app.daytona.io/dashboard/sandboxes)\n2. Click the start icon (**▶**) next to the sandbox you want to start.\n\n```text\nStarting sandbox with ID: <sandbox-id>\n```\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(language=\"python\"))\n# Start Sandbox\nsandbox.start()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst sandbox = await daytona.create({ language: 'typescript' });\n// Start Sandbox\nawait sandbox.start();\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(language: Daytona::CodeLanguage::PYTHON))\n# Start Sandbox\nsandbox.start\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Start sandbox\nerr = sandbox.Start(ctx)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona start [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/start' \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/#daytona) references:\n\n> [**start (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxstart)\n>\n> [**start (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#start)\n>\n> [**start (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#start)\n>\n> [**Start (Go SDK)**](/docs/en/go-sdk/daytona/#Sandbox.Start)\n>\n> [**start (CLI)**](/docs/en/tools/cli/#daytona-start)\n>\n> [**start (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox/{sandboxIdOrName}/start)\n\n## List Sandboxes\n\nDaytona provides options to view information about sandboxes in [Daytona Dashboard ↗](https://app.daytona.io/dashboard/) via the [sandbox details page](#sandbox-details-page) or programmatically using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/daytona/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/#daytona) references.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# List all sandboxes\nresult = daytona.list()\n\n# Iterate through results\nfor sandbox in result.items:\n    print(f\"Sandbox: {sandbox.id} (state: {sandbox.state})\")\n\n# List sandboxes with labels filter\nresult = daytona.list(labels={\"env\": \"dev\"})\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// List all sandboxes\nconst result = await daytona.list();\n\n// Iterate through results\nfor (const sandbox of result.items) {\n    console.log(`Sandbox: ${sandbox.id} (state: ${sandbox.state})`);\n}\n\n// List sandboxes with labels filter\nconst filtered = await daytona.list({ 'env': 'dev' });\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# List all sandboxes\nresult = daytona.list\n\n# Iterate through results\nresult.items.each do |sandbox|\n  puts \"Sandbox: #{sandbox.id} (state: #{sandbox.state})\"\nend\n\n# List sandboxes with labels filter\nresult = daytona.list({ 'env' => 'dev' })\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// List all sandboxes\nresult, err := client.List(ctx, nil, nil, nil)\n\n// Iterate through results\nfor _, sandbox := range result.Items {\n    fmt.Printf(\"Sandbox: %s (state: %s)\\n\", sandbox.Name, sandbox.State)\n}\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona list [flags]\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/#daytona) references:\n\n> [**list (Python SDK)**](/docs/en/python-sdk/sync/daytona#daytonalist)\n>\n> [**list (TypeScript SDK)**](/docs/en/typescript-sdk/daytona#list)\n>\n> [**list (Ruby SDK)**](/docs/en/ruby-sdk/daytona#list)\n>\n> [**List (Go SDK)**](/docs/en/go-sdk/daytona/#Client.List)\n>\n> [**list (CLI)**](/docs/en/tools/cli/#daytona-list)\n>\n> [**list (API)**](/docs/en/tools/api/#daytona/tag/sandbox/GET/sandbox)\n\n### Sandbox details page\n\n[Daytona Dashboard ↗](https://app.daytona.io/dashboard/) provides a sandbox details page to view detailed information about a sandbox and interact with it directly.\n\n1. Navigate to [Daytona Sandboxes ↗](https://app.daytona.io/dashboard/sandboxes)\n2. Click on a sandbox to open its details page\n\nThe sandbox details page provides a summary of the sandbox information and actions to perform on the sandbox:\n\n- **Name**: the name of the sandbox\n- **UUID**: the unique identifier of the sandbox\n- **State**: the sandbox state with a visual indicator\n- **Actions**: [start](#start-sandboxes), [stop](#stop-sandboxes), [recover](#recover-sandboxes), [archive](#archive-sandboxes), [delete](#delete-sandboxes), refresh, [SSH access](/docs/en/ssh-access), [screen recordings](/docs/en/computer-use#screen-recording)\n- [**Region**](/docs/en/regions): the target region where the sandbox is running\n- [**Snapshot**](/docs/en/snapshots): the snapshot used to create the sandbox\n- [**Resources**](#resources): allocated sandbox CPU, memory, and disk\n- [**Lifecycle**](#sandbox-lifecycle): [auto-stop](#auto-stop-interval), [auto-archive](#auto-archive-interval), and [auto-delete](#auto-delete-interval) intervals\n- **Labels**: key-value pairs assigned to the sandbox\n- **Timestamps**: when the sandbox was created and when the last event occurred\n- [**Web terminal**](/docs/en/web-terminal): an embedded web terminal session directly in the browser\n- [**VNC**](/docs/en/vnc-access): a graphical desktop session for sandboxes that have a desktop environment\n- [**Logs**](/docs/en/experimental/otel-collection): a detailed record of user and system activity for the sandbox\n- **Metrics**: sandbox metrics data displayed as charts\n- **Traces**: distributed traces and spans collected from the sandbox\n- **Spending**: usage and cost over time\n\n## Stop Sandboxes\n\nDaytona provides methods to stop sandboxes in [Daytona Dashboard ↗](https://app.daytona.io/dashboard/) or programmatically using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), and [Ruby SDK](/docs/en/ruby-sdk/).\n\n1. Navigate to [Daytona Sandboxes ↗](https://app.daytona.io/dashboard/sandboxes)\n2. Click the stop icon (**⏹**) next to the sandbox you want to stop.\n\n```text\nStopping sandbox with ID: <sandbox-id>\n```\n\nStopped sandboxes maintain filesystem persistence while their memory state is cleared. They incur only disk usage costs and can be started again when needed.\n\nThe stopped state should be used when a sandbox is expected to be started again soon. Otherwise, it is recommended to stop and then archive the sandbox to eliminate disk usage costs.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(language=\"python\"))\n\n# Stop sandbox\nsandbox.stop()\n\nprint(sandbox.id) # 7cd11133-96c1-4cc8-9baa-c757b8f8c916\n\n# The sandbox ID can later be used to get the sandbox and start it\nsandbox = daytona.get(\"7cd11133-96c1-4cc8-9baa-c757b8f8c916\")\n\n# Start sandbox\nsandbox.start()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst sandbox = await daytona.create({ language: 'typescript' });\n\n// Stop sandbox\nawait sandbox.stop();\n\nconsole.log(sandbox.id) // 7cd11133-96c1-4cc8-9baa-c757b8f8c916\n\n// The sandbox ID can later be used to get the sandbox and start it\nconst found = await daytona.get('7cd11133-96c1-4cc8-9baa-c757b8f8c916');\n\n// Start sandbox\nawait found.start();\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(language: Daytona::CodeLanguage::PYTHON))\n\n# Stop sandbox\nsandbox.stop\n\nputs sandbox.id # 7cd11133-96c1-4cc8-9baa-c757b8f8c916\n\n# The sandbox ID can later be used to find the sandbox and start it\nsandbox = daytona.get('7cd11133-96c1-4cc8-9baa-c757b8f8c916')\n\n# Start sandbox\nsandbox.start\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Stop sandbox\nerr = sandbox.Stop(ctx)\n\nfmt.Println(sandbox.ID) // 7cd11133-96c1-4cc8-9baa-c757b8f8c916\n\n// The sandbox ID can later be used to find the sandbox and start it\nsandbox, err = client.Get(ctx, sandbox.ID)\n\n// Start sandbox\nerr = sandbox.Start(ctx)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona stop [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/stop' \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/daytona/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/#daytona) references:\n\n> [**stop (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxstop)\n>\n> [**stop (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#stop)\n>\n> [**stop (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#stop)\n>\n> [**Stop (Go SDK)**](/docs/en/go-sdk/daytona/#Sandbox.Stop)\n>\n> [**stop (CLI)**](/docs/en/tools/cli/#daytona-stop)\n>\n> [**stop (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox/{sandboxIdOrName}/stop)\n\n## Archive Sandboxes\n\nDaytona provides methods to archive sandboxes in [Daytona Dashboard ↗](https://app.daytona.io/dashboard/) or programmatically using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), and [Ruby SDK](/docs/en/ruby-sdk/).\n\nWhen sandboxes are archived, the entire filesystem state is moved to a cost-effective object storage, making it possible to keep sandboxes available for an extended period.\nStarting an archived sandbox takes more time than starting a stopped sandbox, depending on its size.\n\nA sandbox must be stopped before it can be archived and can be started again in the same way as a stopped sandbox.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Archive Sandbox\nsandbox.archive()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Archive Sandbox\nawait sandbox.archive();\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Archive Sandbox\nsandbox.archive\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Archive sandbox\nerr = sandbox.Archive(ctx)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona archive [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/archive' \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), [Go SDK](/docs/en/go-sdk/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**archive (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxarchive)\n>\n> [**archive (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#archive)\n>\n> [**archive (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#archive)\n>\n> [**Archive (Go SDK)**](/docs/en/go-sdk/daytona/#Sandbox.Archive)\n>\n> [**archive (CLI)**](/docs/en/tools/cli/#daytona-archive)\n>\n> [**archive (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox/{sandboxIdOrName}/archive)\n\n## Recover Sandboxes\n\nDaytona provides methods to recover sandboxes in [Daytona Dashboard ↗](https://app.daytona.io/dashboard/) or programmatically using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), and [Ruby SDK](/docs/en/ruby-sdk/).\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Recover sandbox\nsandbox.recover()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Recover sandbox\nawait sandbox.recover();\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Recover sandbox\nsandbox.recover\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/recover' \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**recover (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxrecover)\n>\n> [**recover (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#recover)\n>\n> [**recover (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#recover)\n>\n> [**recover (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox/{sandboxIdOrName}/recover)\n\n### Recover from error state\n\nWhen a sandbox enters an error state, it can sometimes be recovered using the `recover` method, depending on the underlying error reason. The `recoverable` flag indicates whether the error state can be resolved through an automated recovery procedure.\n\n:::note\nRecovery actions are not performed automatically because they address errors that require **further user intervention**, such as freeing up storage space.\n:::\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Check if the Sandbox is recoverable\nif sandbox.recoverable:\n    sandbox.recover()\n    print(\"Sandbox recovered successfully\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Check if the Sandbox is recoverable\nif (sandbox.recoverable) {\n    await sandbox.recover();\n    console.log('Sandbox recovered successfully');\n}\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Check if the Sandbox is in an error state before recovering\nif sandbox.state == 'error'\n  sandbox.recover\n  puts 'Sandbox recovered successfully'\nend\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/recover' \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**recover (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxrecover)\n>\n> [**recover (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#recover)\n>\n> [**recover (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#recover)\n>\n> [**recover (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox/{sandboxIdOrName}/recover)\n\n## Resize Sandboxes\n\nDaytona provides methods to resize sandbox resources (CPU, memory, and disk) after creation.\n\nResizing a started sandbox allows you to `increase CPU and memory` without interruption. \nTo `increase disk capacity` or `decrease CPU and memory`, the sandbox must be stopped first.\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, Resources\n\n    daytona = Daytona()\n    sandbox = daytona.create()\n\n    # Resize a started sandbox (CPU and memory can be increased)\n    sandbox.resize(Resources(cpu=2, memory=4))\n\n    # Resize a stopped sandbox (CPU, memory, and disk can be changed)\n    sandbox.stop()\n    sandbox.resize(Resources(cpu=4, memory=8, disk=20))\n    sandbox.start()\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona } from '@daytonaio/sdk';\n\n    const daytona = new Daytona();\n    const sandbox = await daytona.create();\n\n    // Resize a started sandbox (CPU and memory can be increased)\n    await sandbox.resize({ cpu: 2, memory: 4 });\n\n    // Resize a stopped sandbox (CPU, memory, and disk can be changed)\n    await sandbox.stop();\n    await sandbox.resize({ cpu: 4, memory: 8, disk: 20 });\n    await sandbox.start();\n    ```\n  </TabItem>\n\n  <TabItem label=\"Ruby\" icon=\"seti:ruby\">\n    ```ruby\n    require 'daytona'\n\n    daytona = Daytona::Daytona.new\n    sandbox = daytona.create\n\n    # Resize a started sandbox (CPU and memory can be increased)\n    sandbox.resize(Daytona::Resources.new(cpu: 2, memory: 4))\n\n    # Resize a stopped sandbox (CPU, memory, and disk can be changed)\n    sandbox.stop\n    sandbox.resize(Daytona::Resources.new(cpu: 4, memory: 8, disk: 20))\n    sandbox.start\n    ```\n  </TabItem>\n\n  <TabItem label=\"Go\" icon=\"seti:go\">\n    ```go\n    // Resize a started sandbox (CPU and memory can be increased)\n    err := sandbox.Resize(ctx, &types.Resources{CPU: 2, Memory: 4})\n\n    // Resize a stopped sandbox (CPU, memory, and disk can be changed)\n    err = sandbox.Stop(ctx)\n    err = sandbox.Resize(ctx, &types.Resources{CPU: 4, Memory: 8, Disk: 20})\n    err = sandbox.Start(ctx)\n    ```\n  </TabItem>\n\n  <TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/resize' \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \\\n  --data '{\n  \"cpu\": 2,\n  \"memory\": 4,\n  \"disk\": 20\n}'\n```\n\n  </TabItem>\n</Tabs>\n\n:::note\n- **started** sandboxes: CPU and memory can only be increased, not decreased. Disk cannot be changed.\n- **stopped** sandboxes: CPU, memory, and disk can be changed. Disk can only be increased.\n:::\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox#sandboxresize), [TypeScript SDK](/docs/en/typescript-sdk/sandbox#resize), [Go SDK](/docs/en/go-sdk/daytona/#Sandbox.Resize), and [Ruby SDK](/docs/en/ruby-sdk/sandbox#resize) references:\n\n> [**resize (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxresize)\n>\n> [**resize (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#resize)\n>\n> [**Resize (Go SDK)**](/docs/en/go-sdk/daytona/#Sandbox.Resize)\n>\n> [**resize (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#resize)\n\n## Delete Sandboxes\n\nDaytona provides methods to delete sandboxes in [Daytona Dashboard ↗](https://app.daytona.io/dashboard/) or programmatically using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), and [Ruby SDK](/docs/en/ruby-sdk/).\n\n1. Navigate to [Daytona Sandboxes ↗](https://app.daytona.io/dashboard/sandboxes)\n2. Click the **Delete** button next to the sandbox you want to delete.\n\n```text\nDeleting sandbox with ID: <sandbox-id>\n```\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Delete sandbox\nsandbox.delete()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Delete sandbox\nawait sandbox.delete();\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Delete sandbox\nsandbox.delete\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Delete sandbox\nerr = sandbox.Delete(ctx)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona delete [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}' \\\n  --request DELETE \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), [Go SDK](/docs/en/go-sdk/daytona/), [CLI](/docs/en/tools/cli/), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**delete (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxdelete)\n>\n> [**delete (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#delete)\n>\n> [**delete (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#delete)\n>\n> [**Delete (Go SDK)**](/docs/en/go-sdk/daytona/#Sandbox.Delete)\n>\n> [**delete (CLI)**](/docs/en/tools/cli/#daytona-delete)\n>\n> [**delete (API)**](/docs/en/tools/api/#daytona/tag/sandbox/DELETE/sandbox/{sandboxIdOrName})\n\n## Automated lifecycle management\n\nDaytona Sandboxes can be automatically stopped, archived, and deleted based on user-defined intervals.\n\n### Auto-stop interval\n\nThe auto-stop interval parameter sets the amount of time after which a running sandbox will be automatically stopped.\n\nThe auto-stop interval will trigger even if there are internal processes running in the sandbox. The system differentiates between \"internal processes\" and \"active user interaction\". Merely having a script or background task running is not sufficient to keep the sandbox alive.\n\nThe parameter can either be set to:\n\n- a time interval in minutes\n- `0`: disables the auto-stop functionality, allowing the sandbox to run indefinitely\n\nIf the parameter is not set, the default interval of `15 minutes` will be used.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(\n    snapshot=\"my-snapshot-name\",\n    # Disables the auto-stop feature - default is 15 minutes\n    auto_stop_interval=0,\n))\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst sandbox = await daytona.create({\n    snapshot: \"my-snapshot-name\",\n      // Disables the auto-stop feature - default is 15 minutes\n    autoStopInterval: 0,\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(\n    snapshot: 'my-snapshot-name',\n    # Disables the auto-stop feature - default is 15 minutes\n    auto_stop_interval: 0\n  )\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a sandbox with auto-stop disabled\nautoStopInterval := 0\nparams := types.SnapshotParams{\n    Snapshot: \"my-snapshot-name\",\n    SandboxBaseParams: types.SandboxBaseParams{\n        AutoStopInterval: &autoStopInterval,\n    },\n}\nsandbox, err := client.Create(ctx, params)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/autostop/{interval}' \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), [Go SDK](/docs/en/go-sdk/daytona/), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**set_autostop_interval (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxset_autostop_interval)\n>\n> [**setAutostopInterval (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#setautostopinterval)\n>\n> [**auto_stop_interval (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#auto_stop_interval)\n>\n> [**set_auto_stop_interval (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox/{sandboxIdOrName}/autostop/1)\n\n#### What resets the timer\n\nThe inactivity timer resets only for specific external interactions:\n\n- Accessing [sandbox previews](/docs/en/preview) (network requests through preview URLs)\n- Active [SSH connections](/docs/en/ssh-access)\n- [Daytona Toolbox SDK API](/docs/en/tools/api/#daytona-toolbox) calls\n\n#### What does not reset the timer\n\nThe following do not reset the timer:\n\n- SDK calls that are not toolbox actions\n- Background scripts (e.g., `npm run dev` run as a fire-and-forget command)\n- Long-running tasks without external interaction\n- Processes that don't involve active monitoring\n\nIf you run a long-running task like LLM inference that takes more than 15 minutes without any external interaction, the sandbox may auto-stop mid-process because the process itself doesn't count as \"activity\".\n\n### Auto-archive interval\n\nDaytona provides methods to set the auto-archive interval using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), and [Ruby SDK](/docs/en/ruby-sdk/).\n\nThe auto-archive interval parameter sets the amount of time after which a continuously stopped sandbox will be automatically archived.\n\nThe parameter can either be set to:\n\n- a time interval in minutes\n- `0`: the maximum interval of `30 days` will be used\n\nIf the parameter is not set, the default interval of `7 days` will be used.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(\n    snapshot=\"my-snapshot-name\",\n    # Auto-archive after a sandbox has been stopped for 1 hour\n    auto_archive_interval=60,\n))\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst sandbox = await daytona.create({\n    snapshot: \"my-snapshot-name\",\n    // Auto-archive after a sandbox has been stopped for 1 hour\n    autoArchiveInterval: 60,\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(\n    snapshot: 'my-snapshot-name',\n    # Auto-archive after a sandbox has been stopped for 1 hour\n    auto_archive_interval: 60\n  )\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a sandbox with auto-archive after 1 hour\nautoArchiveInterval := 60\nparams := types.SnapshotParams{\n    Snapshot: \"my-snapshot-name\",\n    SandboxBaseParams: types.SandboxBaseParams{\n        AutoArchiveInterval: &autoArchiveInterval,\n    },\n}\nsandbox, err := client.Create(ctx, params)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/autoarchive/{interval}' \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), [Go SDK](/docs/en/go-sdk/daytona/), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**set_auto_archive_interval (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxset_auto_archive_interval)\n>\n> [**setAutoArchiveInterval (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#setautoarchiveinterval)\n>\n> [**auto_archive_interval (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#auto_archive_interval)\n>\n> [**SetAutoArchiveInterval (Go SDK)**](/docs/en/go-sdk/daytona/#Sandbox.SetAutoArchiveInterval)\n>\n> [**set_auto_archive_interval (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox/{sandboxIdOrName}/autoarchive/{interval})\n\n### Auto-delete interval\n\nDaytona provides methods to set the auto-delete interval using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), and [Ruby SDK](/docs/en/ruby-sdk/).\n\nThe auto-delete interval parameter sets the amount of time after which a continuously stopped sandbox will be automatically deleted. By default, sandboxes will never be automatically deleted.\n\nThe parameter can either be set to:\n\n- a time interval in minutes\n- `-1`: disables the auto-delete functionality\n- `0`: the sandbox will be deleted immediately after stopping\n\nIf the parameter is not set, the sandbox will not be deleted automatically.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(\n    snapshot=\"my-snapshot-name\",\n    # Auto-delete after a sandbox has been stopped for 1 hour\n    auto_delete_interval=60,\n))\n\n# Delete the sandbox immediately after it has been stopped\nsandbox.set_auto_delete_interval(0)\n\n# Disable auto-deletion\nsandbox.set_auto_delete_interval(-1)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst sandbox = await daytona.create({\n    snapshot: \"my-snapshot-name\",\n    // Auto-delete after a sandbox has been stopped for 1 hour\n    autoDeleteInterval: 60,\n});\n\n// Delete the sandbox immediately after it has been stopped\nawait sandbox.setAutoDeleteInterval(0)\n\n// Disable auto-deletion\nawait sandbox.setAutoDeleteInterval(-1)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(\n    snapshot: 'my-snapshot-name',\n    # Auto-delete after a sandbox has been stopped for 1 hour\n    auto_delete_interval: 60\n  )\n)\n\n# Delete the sandbox immediately after it has been stopped\nsandbox.auto_delete_interval = 0\n\n# Disable auto-deletion\nsandbox.auto_delete_interval = -1\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a sandbox with auto-delete after 1 hour\nautoDeleteInterval := 60\nparams := types.SnapshotParams{\n    Snapshot: \"my-snapshot-name\",\n    SandboxBaseParams: types.SandboxBaseParams{\n        AutoDeleteInterval: &autoDeleteInterval,\n    },\n}\nsandbox, err := client.Create(ctx, params)\n\n// Delete the sandbox immediately after it has been stopped\nzeroInterval := 0\nerr = sandbox.SetAutoDeleteInterval(ctx, &zeroInterval)\n\n// Disable auto-deletion\ndisableInterval := -1\nerr = sandbox.SetAutoDeleteInterval(ctx, &disableInterval)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxIdOrName}/autodelete/{interval}' \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/sandbox), [TypeScript SDK](/docs/en/typescript-sdk/sandbox), [Ruby SDK](/docs/en/ruby-sdk/sandbox), [Go SDK](/docs/en/go-sdk/daytona/), and [API](/docs/en/tools/api/#daytona/tag/sandbox) references:\n\n> [**set_auto_delete_interval (Python SDK)**](/docs/en/python-sdk/sync/sandbox#sandboxset_auto_delete_interval)\n>\n> [**setAutoDeleteInterval (TypeScript SDK)**](/docs/en/typescript-sdk/sandbox#setautodeleteinterval)\n>\n> [**auto_delete_interval (Ruby SDK)**](/docs/en/ruby-sdk/sandbox#auto_delete_interval)\n>\n> [**SetAutoDeleteInterval (Go SDK)**](/docs/en/go-sdk/daytona/#Sandbox.SetAutoDeleteInterval)\n>\n> [**set_auto_delete_interval (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox/{sandboxIdOrName}/autodelete/{interval})\n\n### Running indefinitely\n\nDaytona provides methods to run sandboxes indefinitely using the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), and [Ruby SDK](/docs/en/ruby-sdk/).\n\nBy default, Daytona Sandboxes auto-stop after 15 minutes of inactivity. To keep a sandbox running without interruption, set the auto-stop interval to `0` when creating a new sandbox:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(\n    snapshot=\"my_awesome_snapshot\",\n    # Disables the auto-stop feature - default is 15 minutes\n    auto_stop_interval=0,\n))\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst sandbox = await daytona.create({\n    snapshot: \"my_awesome_snapshot\",\n    // Disables the auto-stop feature - default is 15 minutes\n    autoStopInterval: 0,\n});\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(\n    snapshot: 'my_awesome_snapshot',\n    # Disables the auto-stop feature - default is 15 minutes\n    auto_stop_interval: 0\n  )\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Disables the auto-stop feature - default is 15 minutes\nautoStopInterval := 0\nparams := types.SnapshotParams{\n    Snapshot: \"my_awesome_snapshot\",\n    SandboxBaseParams: types.SandboxBaseParams{\n        AutoStopInterval: &autoStopInterval,\n    },\n}\nsandbox, err := client.Create(ctx, params)\n```\n\n</TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/security-exhibit.mdx",
    "content": "---\ntitle: Security Exhibit\n---\n\nThe security exhibit outlines the technical and organizational security measures Daytona maintains to protect customer data processed through its platform. It covers Daytona's information security program, compliance posture, incident management procedures, and business continuity practices.\n\n:::note\nThis security exhibit supplements the Daytona [Terms of Service](https://www.daytona.io/terms-of-service) and [Data Processing Agreement](https://www.daytona.io/dpa), collectively the \"Agreement\", between Daytona Platforms, Inc. (\"Daytona\") and Customer (\"Customer\"). In the event of any conflict between this exhibit and the agreement, the agreement shall control.\n:::\n\n## Information security program\n\nDaytona maintains a comprehensive information security program designed to protect Customer data processed through its secure runtime platform. The program is aligned with industry-standard frameworks including SOC 2, ISO 27001, and incorporates controls specific to AI agent infrastructure and ephemeral compute environments.\n\n### Security policies\n\nDaytona maintains a suite of information security policies that are reviewed at least annually and updated as needed by the Chief Trust Officer. These policies are approved by executive leadership and are made available to all Daytona personnel. Policies cover, at minimum: acceptable use, access control, data classification, incident response, vulnerability management, change management, and business continuity.\n\n### Security training\n\nAll Daytona personnel with access to Customer data or production systems complete mandatory security awareness training during onboarding and annually thereafter. Training covers phishing recognition, secure coding practices, data handling procedures, incident reporting, and compliance obligations. Completion is tracked and verified.\n\n### Personnel security\n\nBackground checks are conducted on all Daytona personnel who have access to Customer data or production systems, in accordance with applicable law. All such personnel are bound by confidentiality agreements. Offboarding procedures include timely revocation of all access credentials and return of company assets.\n\n### Access control\n\nAccess to Customer data and production systems is governed by the principle of least privilege and role-based access control (RBAC). Access is granted only upon documented business need and approved by management. Access reviews are conducted quarterly. Multi-factor authentication (MFA) is enforced for all Daytona personnel with access to production infrastructure, administrative consoles, and source code repositories.\n\n### Data storage and classification\n\nDaytona classifies data according to sensitivity levels: Public, Internal, Confidential, and Restricted. Customer data is classified as Confidential at minimum. Data retention and destruction follow documented policies. Customer data is stored in the geographic region specified by the Customer's configuration where supported. Daytona does not use Customer Content to train models or improve services.\n\n### Sandbox isolation\n\nDaytona's core architecture isolates each sandbox using container and/or microVM technology, ensuring that one Customer's runtime environment cannot interact with another's. Isolation controls include: dedicated namespaces per sandbox, network segmentation preventing lateral movement between sandboxes, resource quotas (CPU, memory, storage, network bandwidth), read-only root filesystems where applicable, and configurable network allow-lists with network-level firewall rules.\n\n### Ephemeral sandbox supported\n\nDaytona sandboxes can be configured as ephemeral, meaning they are automatically deleted once stopped. When ephemeral mode is enabled, all associated compute, memory, and local storage are reclaimed upon sandbox termination, and any session-scoped credentials or tokens are revoked. This reduces the attack surface by ensuring no persistent runtime state accumulates between sessions. For non-ephemeral sandboxes, Daytona provides configurable auto-stop and auto-delete intervals to manage sandbox lifecycle and minimize exposure of idle environments.\n\n### Encryption\n\n**Encryption Standards**\n\n- **In transit**: TLS 1.2+ for all external and internal communications\n- **At rest**: AES-256 or equivalent across all storage systems\n- **Key management**: Infrastructure provider KMS with automatic rotation\n\n### Authentication and access\n\nDaytona provides identity and access management through Auth0, supporting authentication via Google and GitHub identity providers. Multi-factor authentication (MFA) is enforced for all Daytona personnel with administrative access. Daytona implements session management controls including configurable session timeouts and token revocation capabilities. Enterprise customers requiring SAML 2.0 or OIDC-based Single Sign-On (SSO) integration should contact Daytona to discuss available options.\n\n### Backup and recovery\n\nCritical Daytona platform data (control plane, configuration, metadata) is backed up regularly with a defined recovery point objective (RPO) and recovery time objective (RTO). Backups are encrypted at rest and stored in a geographically separate location from the primary infrastructure. Backup restoration procedures are tested at least annually.\n\n### Vulnerability management\n\nDaytona performs automated vulnerability scanning of its infrastructure and applications on at least a monthly basis. Identified vulnerabilities are triaged and remediated according to the following target timelines:\n\n| **Severity** | **Target** | **Example**                |\n| ------------ | ---------- | -------------------------- |\n| Critical     | 24 hours   | RCE, privilege escalation  |\n| High         | 7 days     | Auth bypass, data exposure |\n| Medium       | 30 days    | XSS, misconfigurations     |\n| Low          | 90 days    | Informational findings     |\n\n### Network security\n\nDaytona implements defense-in-depth network security controls including: network segmentation between sandbox traffic, control plane, and management interfaces; firewall rules reviewed at least annually; DDoS mitigation at the infrastructure edge; and intrusion detection and monitoring for anomalous network activity. Sandbox network access can be restricted using configurable allow-lists and network block policies.\n\n### Secure development lifecycle\n\nDaytona follows a secure software development lifecycle (SDLC) that includes: security requirements analysis during design, peer code review for all changes, automated static analysis and dependency scanning in CI/CD, container image scanning that blocks critical and high vulnerabilities, and separation of development, staging, and production environments.\n\n### Change management\n\nAll changes to production systems follow a documented change management process that includes: description and risk assessment of the change, peer review and approval, testing in non-production environments, and rollback procedures. Emergency changes follow an expedited process with retroactive documentation and review.\n\n### Third-party risk management\n\nDaytona evaluates the security posture of third-party vendors and sub-processors before engagement and on an ongoing basis. Evaluation criteria include: security certifications, data handling practices, incident response capabilities, and contractual security obligations. Sub-processors are contractually required to maintain security controls substantially similar to those described in this Exhibit and the DPA.\n\n### Patch management\n\nDaytona applies security patches to operating systems, libraries, and application dependencies in accordance with its vulnerability management SLAs. Critical patches are tested and deployed within 24 hours. Automated dependency monitoring tracks new CVEs affecting the Daytona stack.\n\n### Audit logging and monitoring\n\nDaytona maintains comprehensive audit logs of administrative actions, authentication events, access to Customer data, and system-level events. Logs are stored securely, protected against tampering, and retained for a minimum of 12 months. Security events are monitored and alerted upon in real time. Log access is restricted to authorized security personnel.\n\n### Container and runtime security\n\n:::note\nDaytona uses Sysbox as its container runtime to provide VM-level isolation without hardware virtualization overhead.\n:::\n\nSysbox enforces Linux user-namespaces on all sandboxes, ensuring that the root user inside a sandbox maps to a fully unprivileged user on the host. Each sandbox receives exclusive user-ID and group-ID mappings, so a process escaping one sandbox has no permissions to access other sandboxes or host resources.\n\nAdditional Sysbox security controls include: partial virtualization of procfs and sysfs to hide host information and prevent modification of system-wide kernel settings, immutable initial mounts that prevent sandbox processes from weakening container isolation even with root capabilities, and selective syscall interception that blocks dangerous operations while preserving compatibility with system-level workloads such as Docker-in-Docker.\n\nContainer images are built from minimal base images and scanned for vulnerabilities in CI/CD pipelines, and runtime threat detection monitors for anomalous process behavior.\n\n### Penetration testing\n\nDaytona completes penetration testing at least annually, conducted by a recognized independent third party. Testing scope includes the Daytona platform, APIs, sandbox isolation mechanisms, and control plane. A summary of test results and remediation status is available to Customers upon request.\n\n### Vulnerability disclosure program\n\nDaytona welcomes contributions from the security community to identify and responsibly disclose vulnerabilities in its platform. Daytona maintains a public Vulnerability Disclosure Policy with defined scope, exclusions, safe harbor protections, and coordinated disclosure timelines. Rewards ranging from $100 to $1,000 are offered for valid, original findings based on severity, exploitability, and report quality. Reports should be submitted to [security@daytona.io](mailto:security@daytona.io). Full program details are published in Daytona's [Security Policy](https://github.com/daytonaio/daytona/blob/main/SECURITY.md).\n\n## Compliance and certifications\n\nDaytona pursues and maintains industry-recognized compliance certifications to demonstrate its commitment to security and data protection.\n\n| **Framework** | **Status**  | **Details**                                                      |\n| ------------- | ----------- | ---------------------------------------------------------------- |\n| SOC 2 Type I  | Achieved    | Completed; report available under NDA via Trust Center.          |\n| SOC 2 Type II | In progress | Audit period underway                                            |\n| ISO 27001     | In progress | Certification in progress                                        |\n| HIPAA BAA     | Available   | Business Associate Agreements available for qualifying customers |\n\nCopies of current certifications and audit reports are available to Customers upon written request, subject to reasonable confidentiality obligations, consistent with the DPA (Section 10).\n\n## Assessments, audits, and remediation\n\n### Assessment obligations\n\nDaytona shall maintain its security program and submit to independent third-party audits at least annually to verify compliance with this Exhibit and applicable security standards. Daytona will provide copies of audit reports and certifications upon reasonable written request, subject to confidentiality obligations as set forth in the Agreement.\n\n### Remediation\n\nWhere assessments or audits identify material deficiencies, Daytona shall prepare a remediation plan and address findings within timeframes consistent with the vulnerability severity levels defined in Section 1.11.\n\n### Secure disposal\n\nUpon termination of the Agreement or at Customer's request, Daytona shall securely delete or return Customer data in accordance with the DPA (Section 8). Deletion is performed using methods that render data unrecoverable, including cryptographic erasure of encrypted storage volumes. Daytona will certify deletion upon request.\n\n## Security incident management\n\n### Incident response procedures\n\nDaytona maintains a documented incident response plan that defines roles, responsibilities, escalation procedures, and communication protocols. The plan is tested at least annually through tabletop exercises. Incidents are classified by severity and handled by a dedicated incident response team.\n\n### Notification\n\nIn the event of a Security Incident involving Customer data, Daytona shall notify the affected Customer without undue delay, consistent with the DPA (Section 15). Notification shall include, to the extent known: the nature and scope of the incident, the types of data affected, steps taken to contain and remediate, recommended Customer actions, and a point of contact for further communication. Notification may be delayed at the request of law enforcement or where delay is reasonably necessary to investigate and remediate.\n\n### Incident remediation\n\nDaytona shall cooperate fully to investigate and remedy any harm or potential harm caused by a Security Incident. The Customer shall be informed of the response plan. Any liability arising from a Security Incident shall be subject to the limitation of liability provisions set forth in the Agreement ([Terms of Service](https://www.daytona.io/terms-of-service), section 15), including the aggregate liability cap and exclusion of indirect, incidental, special, consequential, or punitive damages. Each Party is solely responsible for any regulatory fines imposed directly on it by a supervisory authority, subject to the provisions of the [Data Processing Agreement](https://www.daytona.io/dpa) (section 12).\n\n## Business continuity\n\nDaytona maintains a Business Continuity Plan (BCP) and Disaster Recovery Plan (DRP) that are reviewed and tested at least annually. The plans address: critical system recovery priorities and RTOs, data backup and restoration procedures, communication protocols during disruptions, alternative processing capabilities, and lessons-learned reviews following any activation of the BCP/DRP.\n\n## Termination obligations\n\nUpon termination or expiration of the Agreement, Daytona shall: cease all processing of Customer data except as required to complete termination; return or delete Customer data at Customer's election, in accordance with the DPA (Section 8); certify deletion upon written request; and continue to protect any Customer data lawfully retained in accordance with this Exhibit and the Agreement.\n\n## Contact and sub-processors\n\n### Security contacts\n\n| **Team**                  | **Email**                                         |\n| ------------------------- | ------------------------------------------------- |\n| Security                  | [security@daytona.io](mailto:security@daytona.io) |\n| Privacy contact           | [privacy@daytona.io](mailto:privacy@daytona.io)   |\n| Trust center              | [trust.daytona.io](https://trust.daytona.io)      |\n| Data Processing Agreement | [daytona.io/dpa](https://www.daytona.io/dpa)      |\n| General Support           | [support@daytona.io](mailto:support@daytona.io)   |\n\n### Sub-processors\n\nDaytona maintains and updates a record of sub-processors that process Customer data. The current sub-processor list is published as Exhibit C of Daytona's [Data Processing Agreement](https://www.daytona.io/dpa).\n\nDaytona will notify Customer of any material changes to its sub-processor list. If Customer reasonably objects to the appointment of a new sub-processor based on data protection concerns, the parties will discuss such concerns in good faith. If no resolution is reached, Customer may terminate the Agreement for convenience as its sole and exclusive remedy, consistent with the [Data Processing Agreement](https://www.daytona.io/dpa) (section 14).\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/snapshots.mdx",
    "content": "---\ntitle: Snapshots\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport Label from '@components/Label.astro'\n\nSnapshots are sandbox templates created from [Docker](https://www.docker.com/) or [OCI](https://opencontainers.org/) compatible images. Sandboxes can use a [default snapshot](#default-snapshots) or custom snapshots to provide a consistent and reproducible sandbox environments for your dependencies, settings, and resources.\n\nDaytona supports running [Docker](#run-docker-in-a-sandbox) and [Kubernetes](#run-kubernetes-in-a-sandbox) workloads inside sandboxes using snapshots.\n\n## Snapshot lifecycle\n\nThroughout the snapshot lifecycle, a snapshot can have the following states:\n\n| **State**          | **Description**                                 |\n| ------------------ | ----------------------------------------------- |\n| **`pending`**      | Snapshot creation requested                     |\n| **`building`**     | Snapshot is being built                         |\n| **`pulling`**      | Snapshot image is being pulled from a registry  |\n| **`active`**       | Snapshot is ready to use for creating sandboxes |\n| **`inactive`**     | Snapshot is deactivated                         |\n| **`error`**        | Snapshot creation failed                        |\n| **`build_failed`** | Snapshot build process failed                   |\n| **`removing`**     | Snapshot is being deleted                       |\n\n:::note\nInactive snapshots cannot be used to create sandboxes. They must be explicitly [re-activated](#activate-snapshots) before use. When activated, the snapshot returns to `pending` state and is re-processed before becoming `active` again.\n:::\n\n## Create Snapshots\n\nDaytona provides methods to create snapshots using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/snapshots) or programmatically using the Daytona [Python](/docs/en/python-sdk/sync/snapshot), [TypeScript](/docs/en/typescript-sdk/snapshot), [Ruby](/docs/en/ruby-sdk/snapshot), [Go](/docs/en/go-sdk/daytona#SnapshotService) **SDKs**, [CLI](/docs/en/tools/cli#daytona-snapshot), or [API](/docs/en/tools/api#daytona/tag/snapshots).\n\nSnapshots can be created using:\n\n- [public images](#using-public-images)\n- [local images](#using-local-images)\n- [images from private registries](#using-images-from-private-registries)\n- [the declarative builder](#using-the-declarative-builder)\n\n1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n2. Click the **Create Snapshot** button\n3. Enter the **snapshot name**, **image** (tag or digest), **entrypoint**, and **resources**\n\n- **Snapshot name**: Identifier used to reference the snapshot in the SDK or CLI.\n- **Image**: Base image for the snapshot. Must include either a tag or a digest (e.g., **`ubuntu:22.04`**). The **`latest`** tag is not allowed. Since images tagged `latest` get frequent updates, only specific tags are supported. Same applies to tags such as `lts` or `stable`, and we recommend avoiding those when defining an image to prevent unexpected behavior.\n- **Entrypoint** (optional): The entrypoint command for the snapshot. Ensure that the entrypoint is a long-running command. If not provided, or if the snapshot does not have an entrypoint, `sleep infinity` will be used as the default.\n- [**Resources**](/docs/en/sandboxes#resources) (optional): The resources you want the underlying Sandboxes to have. By default, Daytona Sandboxes use **1 vCPU**, **1GiB memory**, and **3GiB storage**.\n\n<Tabs>\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nimage = Image.debian_slim('3.12').pip_install('numpy')\ndaytona.snapshot.create(\n    CreateSnapshotParams(name='my-awesome-snapshot', image=image),\n    on_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst image = Image.debianSlim('3.12').pipInstall('numpy');\nawait daytona.snapshot.create({ name: 'my-awesome-snapshot', image: image }, { onLogs: console.log });\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nimage = Image.debian_slim('3.12').pip_install('numpy')\nparams = CreateSnapshotParams.new(name: 'my-awesome-snapshot', image: image)\nsnapshot = daytona.snapshot.create(params) do |chunk|\n  print chunk\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create from Docker Hub image\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:  \"my-awesome-snapshot\",\n    Image: \"python:3.11-slim\",\n})\nif err != nil {\n    return err\n}\n\n// Stream build logs\nfor log := range logChan {\n    fmt.Println(log)\n}\n\n// Create with custom image and resources\nimage := daytona.Base(\"python:3.11\").PipInstall([]string{\"numpy\"})\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:  \"my-awesome-snapshot\",\n    Image: image,\n    Resources: &types.Resources{CPU: 2, Memory: 4096},\n})\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona snapshot create my-awesome-snapshot --image python:3.11-slim --cpu 2 --memory 4\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/snapshots \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \\\n  --data '{\n    \"name\": \"my-awesome-snapshot\",\n    \"imageName\": \"python:3.11-slim\",\n    \"cpu\": 2,\n    \"memory\": 4\n  }'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/snapshot), [TypeScript SDK](/docs/en/typescript-sdk/snapshot), [Ruby SDK](/docs/en/ruby-sdk/snapshot), [Go SDK](/docs/en/go-sdk/daytona#SnapshotService.Create), [CLI](/docs/en/tools/cli#daytona-snapshot), and [API](/docs/en/tools/api/#daytona/tag/snapshots) references:\n\n> [**create (Python SDK)**](/docs/en/python-sdk/sync/snapshot#snapshotservicecreate)\n>\n> [**create (TypeScript SDK)**](/docs/en/typescript-sdk/snapshot#create)\n>\n> [**create (Ruby SDK)**](/docs/en/ruby-sdk/snapshot/#create)\n>\n> [**create (Go SDK)**](/docs/en/go-sdk/daytona#SnapshotService.Create)\n>\n> [**create (CLI)**](/docs/en/tools/cli/#daytona-snapshot-create)\n>\n> [**create (API)**](/docs/en/tools/api/#daytona/tag/snapshots/POST/snapshots)\n\n### Using public images\n\nDaytona supports creating snapshots from any publicly accessible image or container registry.\n\n1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n2. Click the **Create Snapshot** button\n3. Enter the **snapshot name** and **image** (tag or digest) of any publicly accessible image or container registry\n\nOnce the snapshot is pulled, validated, and has an `Active` state, it is ready to be used.\n\n<Tabs>\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ndaytona.snapshot.create(\n    CreateSnapshotParams(name='my-awesome-snapshot', image='python:3.11-slim'),\n    on_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nawait daytona.snapshot.create({ name: 'my-awesome-snapshot', image: 'python:3.11-slim' }, { onLogs: console.log });\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nparams = CreateSnapshotParams.new(name: 'my-awesome-snapshot', image: 'python:3.11-slim')\nsnapshot = daytona.snapshot.create(params) do |chunk|\n  print chunk\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:  \"my-awesome-snapshot\",\n    Image: \"python:3.11-slim\",\n})\nif err != nil {\n    return err\n}\n\n// Stream build logs\nfor log := range logChan {\n    fmt.Println(log)\n}\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona snapshot create my-awesome-snapshot --image python:3.11-slim\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/snapshots \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \\\n  --data '{\n    \"name\": \"my-awesome-snapshot\",\n    \"imageName\": \"python:3.11-slim\"\n  }'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/snapshot), [TypeScript SDK](/docs/en/typescript-sdk/snapshot), [Ruby SDK](/docs/en/ruby-sdk/snapshot), [Go SDK](/docs/en/go-sdk/daytona#SnapshotService.Create), [CLI](/docs/en/tools/cli#daytona-snapshot), and [API](/docs/en/tools/api/#daytona/tag/snapshots) references.\n\n> [**create (Python SDK)**](/docs/en/python-sdk/sync/snapshot#snapshotservicecreate)\n>\n> [**create (TypeScript SDK)**](/docs/en/typescript-sdk/snapshot#create)\n>\n> [**create (Ruby SDK)**](/docs/en/ruby-sdk/snapshot/#create)\n>\n> [**create (Go SDK)**](/docs/en/go-sdk/daytona#SnapshotService.Create)\n>\n> [**create (CLI)**](/docs/en/tools/cli#daytona-snapshot-create)\n>\n> [**create (API)**](/docs/en/tools/api/#daytona/tag/snapshots/POST/snapshots)\n\n### Using local images\n\nDaytona supports creating snapshots from local images or from local Dockerfiles. To create a snapshot from a local image or from a local Dockerfile, use the [Daytona CLI](/docs/en/tools/cli#daytona-snapshot).\n\nDaytona expects the local image to be built for AMD64 architecture. Therefore, the `--platform=linux/amd64` flag is required when building the Docker image if your machine is running on a different architecture.\n\n1. Ensure the image and tag you want to use is available\n\n```bash\ndocker images\n```\n\n2. Create a snapshot and push it to Daytona:\n\n```bash\ndaytona snapshot push custom-alpine:3.21 --name alpine-minimal\n```\n\n:::tip\nUse the flags `--cpu`, `--memory` and `--disk` to specify the [resources](/docs/en/sandboxes#resources) you want the underlying sandboxes to have. Example:\n<br />\n```bash\ndaytona snapshot push custom-alpine:3.21 --name alpine-minimal --cpu 2 --memory 4 --disk 8\n``` \n:::\n\nAlternatively, use the `--dockerfile` flag under `create` to pass the path to the Dockerfile you want to use and Daytona will build the snapshot for you. The `COPY`/`ADD` commands will be automatically parsed and added to the context. To manually add files to the context, use the `--context` flag.\n\n```bash\ndaytona snapshot create my-awesome-snapshot --dockerfile ./Dockerfile\n```\n\n```text\nBuilding image from /Users/user/docs/Dockerfile\nStep 1/5 : FROM alpine:latest\n\n...\n ⡿  Waiting for the Snapshot to be validated ...\n...\n\n ✓  Use 'harbor-transient.internal.daytona.app/daytona/trying-daytona:0.0.1' to create a new sandbox using this Snapshot\n```\n\n### Using images from private registries\n\nDaytona supports creating snapshots from images from [Docker Hub](#docker-hub), [Google Artifact Registry](#google-artifact-registry), [GitHub Container Registry](#github-container-registry) or other private container registries.\n\n1. Navigate to [Daytona Registries ↗](https://app.daytona.io/dashboard/registries)\n2. Click the **Add Registry** button\n3. Enter the **registry name**, **registry URL**, **username**, **password**, and **project** (if applicable)\n4. After the container registry is successfully created, navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n5. Click the **Create Snapshot** button\n6. Enter the **snapshot name** and private **image** (tag or digest). When creating the snapshot, make sure to input the entire private image name, including the registry location and project name (e.g. **`my-private-registry.com/<my-project>/custom-alpine:3.21`**)\n\nOptionally, set the **`CreateSandboxFromSnapshotParams`** field to use the custom snapshot.\n\n#### Docker Hub\n\nDaytona supports creating snapshots from Docker Hub images.\n\n1. Navigate to [Daytona Registries ↗](https://app.daytona.io/dashboard/registries)\n2. Click the **Add Registry** button\n3. Enter the **registry name**, **registry URL**, **username**, **password**, and **project** (if applicable)\n\n- **Registry URL**: `docker.io`\n- **Username**: Docker Hub username (the account with access to the image)\n- **Password**: [Docker Hub Personal Access Token](https://docs.docker.com/docker-hub/access-tokens/) (not your account password)\n- **Create the Snapshot**: `docker.io/<username>/<image>:<tag>`\n\n4. After the container registry is successfully created, navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n5. Click the **Create Snapshot** button\n6. Enter the **snapshot name** and **image** (tag or digest). When creating the snapshot, input the entire image name, including the registry location and project name (e.g. **`docker.io/<username>/<image>:<tag>`**)\n\n#### Google Artifact Registry\n\nDaytona supports creating snapshots from images from Google Artifact Registry.\n\nTo use an image from Google Artifact Registry, configure the registry using a [service account key](https://cloud.google.com/iam/docs/keys-create-delete) in JSON format.\n\n1. Navigate to [Daytona Registries ↗](https://app.daytona.io/dashboard/registries)\n2. Click the **Add Registry** button\n3. Enter the **registry name**, **registry URL**, **username**, **password**, and **project** (if applicable)\n\n- **Registry URL**: base URL for your region (e.g., `https://us-central1-docker.pkg.dev` or `https://us-central1-docker.pkg.dev/your-org`).\n- **Username**: `_json_key`\n- **Password**: Paste the full contents of your Service Account JSON key file\n- **Project**: Google Cloud Project ID\n- **Create the Snapshot**: `us-central1-docker.pkg.dev/<project>/<repo>/<image>:<tag>`\n\n4. After the container registry is successfully created, navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n5. Click the **Create Snapshot** button\n6. Enter the **snapshot name** and **image** (tag or digest). When creating the snapshot, make sure to input the entire image name, including the registry location and project name (e.g. **`us-central1-docker.pkg.dev/<project>/<repo>/<image>:<tag>`**)\n\n#### GitHub Container Registry (GHCR)\n\nDaytona supports creating snapshots from images from GitHub Container Registry (GHCR).\n\n1. Navigate to [Daytona Registries ↗](https://app.daytona.io/dashboard/registries)\n2. Click the **Add Registry** button\n3. Enter the **registry name**, **registry URL**, **username**, **password**, and **project** (if applicable)\n\n- **Registry URL**: `ghcr.io`\n- **Username**: GitHub username (the account with access to the image)\n- **Password**: [GitHub Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) (not your account password). Personal access token (PAT) requires **`write:packages`**, **`read:packages`**, and **`delete:packages`** scopes.\n\n4. After the container registry is successfully created, navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n5. Click the **Create Snapshot** button\n6. Enter the **snapshot name** and **image** (tag or digest). When creating the snapshot, make sure to input the entire image name, including the registry location and project name (e.g. **`ghcr.io/<my-project>/custom-alpine:3.21`**)\n\n#### Amazon Elastic Container Registry (ECR)\n\nDaytona supports creating snapshots from images from Amazon Elastic Container Registry.\n\n1. Navigate to [Daytona Registries ↗](https://app.daytona.io/dashboard/registries)\n2. Click the **Add Registry** button\n3. Enter the **registry name**, **registry URL**, **username**, **password**, and **project** (if applicable)\n\n- **Registry URL**: `<account_id>.dkr.ecr.<region>.amazonaws.com`\n- **Username**: `AWS`\n- **Password**: [Authorization token](https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry_auth.html)\n\n4. After the container registry is successfully created, navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n5. Click the **Create Snapshot** button\n6. Enter the **snapshot name** and **image** (tag or digest). When creating the snapshot, make sure to input the entire image name, including the registry location and repository name (e.g. **`123456789012.dkr.ecr.us-east-1.amazonaws.com/my-repo/custom-alpine:3.21`**)\n\n:::caution\nAmazon ECR authorization tokens expire after **12 hours**. Update the registry password in Daytona each time the token expires. Support for automatic renewal is coming soon.\n:::\n\n### Using the declarative builder\n\n[Declarative Builder](/docs/en/declarative-builder) provides a powerful, code-first approach to defining dependencies for Daytona Sandboxes. Instead of importing images from a container registry, you can programmatically define them using the Daytona [SDKs](/docs/en/getting-started#sdks).\n\n### Resources\n\nSnapshots can be customized with specific resource requirements. By default, Daytona Sandboxes use **1 vCPU**, **1GB RAM**, and **3GiB disk**. For more information, see [sandbox resources](/docs/en/sandboxes#resources).\n\nTo view your available resources and limits, see [limits](/docs/en/limits) or navigate to [Daytona Limits ↗](https://app.daytona.io/dashboard/limits).\n\nSnapshot resources can be customized using the `Resources` class.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import (\n    Daytona,\n    CreateSnapshotParams,\n    Image,\n    Resources,\n)\n\ndaytona = Daytona()\n\n# Create a snapshot with custom resources\ndaytona.snapshot.create(\n  CreateSnapshotParams(\n    name=\"my-awesome-snapshot\",\n    image=Image.debian_slim(\"3.12\"),\n    resources=Resources(\n      cpu=2,\n      memory=4,\n      disk=8,\n    ),\n  ),\n  on_logs=print,\n)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, Image } from '@daytonaio/sdk'\n\nconst daytona = new Daytona()\n\n// Create a snapshot with custom resources\nawait daytona.snapshot.create(\n  {\n    name: 'my-awesome-snapshot',\n    image: Image.debianSlim('3.13'),\n    resources: {\n      cpu: 2,\n      memory: 4,\n      disk: 8,\n    },\n  },\n  { onLogs: console.log }\n)\n```\n\n  </TabItem>\n\n  <TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Create a snapshot with custom resources\ndaytona.snapshot.create(\n  Daytona::CreateSnapshotParams.new(\n    name: 'my-awesome-snapshot',\n    image: Daytona::Image.debian_slim('3.12'),\n    resources: Daytona::Resources.new(\n      cpu: 2,\n      memory: 4,\n      disk: 8\n    )\n  ),\n  on_logs: proc { |chunk| puts chunk }\n)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// Create a snapshot with custom resources\nimage := daytona.Base(\"python:3.11\").PipInstall([]string{\"numpy\"})\nsnapshot, logChan, err := client.Snapshots.Create(ctx, &types.CreateSnapshotParams{\n    Name:      \"my-awesome-snapshot\",\n    Image:     image,\n    Resources: &types.Resources{CPU: 2, Memory: 4, Disk: 8},\n})\nif err != nil {\n    return err\n}\n\n// Stream build logs\nfor log := range logChan {\n    fmt.Println(log)\n}\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona snapshot create my-awesome-snapshot --image python:3.11-slim --cpu 2 --memory 4 --disk 8\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/snapshots \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \\\n  --data '{\n    \"name\": \"my-awesome-snapshot\",\n    \"imageName\": \"python:3.11-slim\",\n    \"cpu\": 2,\n    \"memory\": 4,\n    \"disk\": 8\n  }'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk), [TypeScript SDK](/docs/en/typescript-sdk), [Ruby SDK](/docs/en/ruby-sdk), [Go SDK](/docs/en/go-sdk/daytona#SnapshotService.Create), [CLI](/docs/en/tools/cli#daytona-snapshot-create), and [API](/docs/en/tools/api/#daytona/tag/snapshots) references:\n\n> [**CreateSnapshotParams (Python SDK)**](/docs/en/python-sdk/sync/snapshot#createsnapshotparams)\n>\n> [**CreateSnapshotParams (TypeScript SDK)**](/docs/en/typescript-sdk/snapshot#createsnapshotparams)\n>\n> [**CreateSnapshotParams (Ruby SDK)**](/docs/en/ruby-sdk/snapshot#create)\n>\n> [**CreateSnapshotParams (Go SDK)**](/docs/en/go-sdk/types#CreateSnapshotParams)\n>\n> [**create (CLI)**](/docs/en/tools/cli#daytona-snapshot-create)\n>\n> [**create (API)**](/docs/en/tools/api/#daytona/tag/snapshots/POST/snapshots)\n\n### Regions\n\nWhen creating a snapshot, you can specify the [region](/docs/en/regions) in which it will be available. If not specified, the snapshot will be created in your organization's default region.\n\nWhen you later create a sandbox from this snapshot, you can use the snapshot's region as the target region for the sandbox.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import (\n    Daytona,\n    CreateSnapshotParams,\n    Image,\n)\n\ndaytona = Daytona()\n\n# Create a Snapshot in a specific region\ndaytona.snapshot.create(\n  CreateSnapshotParams(\n    name=\"my-awesome-snapshot\",\n    image=Image.debian_slim(\"3.12\"),\n    region_id=\"us\",\n  ),\n  on_logs=print,\n)\n\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona, Image } from \"@daytonaio/sdk\";\n\nconst daytona = new Daytona();\n\n// Create a Snapshot in a specific region\nawait daytona.snapshot.create(\n  {\n    name: \"my-awesome-snapshot\",\n    image: Image.debianSlim(\"3.13\"),\n    regionId: \"us\",\n  },\n  { onLogs: console.log }\n);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Create a Snapshot in a specific region\ndaytona.snapshot.create(\n  Daytona::CreateSnapshotParams.new(\n    name: 'my-awesome-snapshot',\n    image: Daytona::Image.debian_slim('3.12'),\n    region_id: 'us'\n  ),\n  on_logs: proc { |chunk| puts chunk }\n)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona snapshot create my-awesome-snapshot --image python:3.11-slim --region us\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/snapshots \\\n  --request POST \\\n  --header 'Content-Type: application/json' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN' \\\n  --data '{\n    \"name\": \"my-awesome-snapshot\",\n    \"imageName\": \"python:3.11-slim\",\n    \"regionId\": \"us\"\n  }'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/snapshot), [TypeScript SDK](/docs/en/typescript-sdk/snapshot), [Ruby SDK](/docs/en/ruby-sdk/snapshot), [CLI](/docs/en/tools/cli#daytona-snapshot-create), and [API](/docs/en/tools/api/#daytona/tag/snapshots) references:\n\n> [**create (Python SDK)**](/docs/en/python-sdk/sync/snapshot#snapshotservicecreate)\n>\n> [**create (TypeScript SDK)**](/docs/en/typescript-sdk/snapshot#create)\n>\n> [**create (Ruby SDK)**](/docs/en/ruby-sdk/snapshot/#create)\n>\n> [**create (CLI)**](/docs/en/tools/cli#daytona-snapshot-create)\n>\n> [**create (API)**](/docs/en/tools/api/#daytona/tag/snapshots/POST/snapshots)\n\n## Get a Snapshot by name\n\nDaytona provides an option to get a snapshot by name.\n\nThe following snippet returns the snapshot with the specified name:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ndaytona = Daytona()\nsnapshot = daytona.snapshot.get(\"my-awesome-snapshot\")\nprint(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst daytona = new Daytona()\nconst snapshot = await daytona.snapshot.get('my-awesome-snapshot')\nconsole.log(`Snapshot ${snapshot.name} is in state ${snapshot.state}`)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\ndaytona = Daytona::Daytona.new\nsnapshot = daytona.snapshot.get('my-awesome-snapshot')\nputs \"#{snapshot.name} (#{snapshot.image_name})\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nsnapshot, err := client.Snapshots.Get(ctx, \"my-awesome-snapshot\")\nif err != nil {\n    return err\n}\nfmt.Printf(\"%s (%s)\\n\", snapshot.Name, snapshot.ImageName)\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/snapshots/my-awesome-snapshot \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/snapshot#snapshotserviceget), [TypeScript SDK](/docs/en/typescript-sdk/snapshot#get), [Ruby SDK](/docs/en/ruby-sdk/snapshot#get), [Go SDK](/docs/en/go-sdk/daytona#SnapshotService.Get), and [API](/docs/en/tools/api/#daytona/tag/snapshots) references:\n\n> [**get (Python SDK)**](/docs/en/python-sdk/sync/snapshot#snapshotserviceget)\n>\n> [**get (TypeScript SDK)**](/docs/en/typescript-sdk/snapshot#get)\n>\n> [**get (Ruby SDK)**](/docs/en/ruby-sdk/snapshot#get)\n>\n> [**get (Go SDK)**](/docs/en/go-sdk/daytona#SnapshotService.Get)\n>\n> [**get (API)**](/docs/en/tools/api/#daytona/tag/snapshots/GET/snapshots/{snapshotName})\n\n## List Snapshots\n\nDaytona provides options to list snapshots and view their details.\n\nThe following snippet lists all snapshots on the first page with a limit of 10 snapshots per page.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ndaytona = Daytona()\nresult = daytona.snapshot.list(page=2, limit=10)\nfor snapshot in result.items:\n    print(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst daytona = new Daytona()\nconst result = await daytona.snapshot.list(1, 10)\nconsole.log(`Found ${result.total} snapshots`)\nresult.items.forEach(snapshot =>\n  console.log(`${snapshot.name} (${snapshot.imageName})`)\n)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\ndaytona = Daytona::Daytona.new\nresult = daytona.snapshot.list(page: 2, limit: 10)\nresult.items.each do |snapshot|\n  puts \"#{snapshot.name} (#{snapshot.image_name})\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\n// List first page with default limit\nresult, err := client.Snapshots.List(ctx, nil, nil)\nif err != nil {\n    return err\n}\n\n// List with pagination\npage, limit := 2, 10\nresult, err := client.Snapshots.List(ctx, &page, &limit)\nfmt.Printf(\"Page %d of %d, total: %d\\n\", result.Page, result.TotalPages, result.Total)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\n# List snapshots with pagination\ndaytona snapshot list --page 2 --limit 10\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/snapshots?page=2&limit=10' \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/snapshot), [TypeScript SDK](/docs/en/typescript-sdk/snapshot), [Ruby SDK](/docs/en/ruby-sdk/snapshot), [Go SDK](/docs/en/go-sdk/daytona#SnapshotService.List), [CLI](/docs/en/tools/cli#daytona-snapshot-list), and [API](/docs/en/tools/api/#daytona/tag/snapshots) references.\n\n> [**list (Python SDK)**](/docs/en/python-sdk/sync/snapshot#snapshotservicelist)\n>\n> [**list (TypeScript SDK)**](/docs/en/typescript-sdk/snapshot#list)\n>\n> [**list (Ruby SDK)**](/docs/en/ruby-sdk/snapshot#list)\n>\n> [**list (Go SDK)**](/docs/en/go-sdk/daytona#SnapshotService.List)\n>\n> [**list (CLI)**](/docs/en/tools/cli#daytona-snapshot-list)\n>\n> [**list (API)**](/docs/en/tools/api#daytona/tag/snapshots/GET/snapshots)\n\n## Activate Snapshots\n\nSnapshots automatically become inactive after 2 weeks of not being used. To activate an inactive snapshot:\n\n1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n2. Click the three dots at the end of the row for the snapshot you want to activate\n3. Click the **Activate** button\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\ndaytona = Daytona()\nsnapshot = daytona.snapshot.get(\"my-inactive-snapshot\")\nactivated_snapshot = daytona.snapshot.activate(snapshot)\nprint(f\"Snapshot {activated_snapshot.name} activated\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nconst daytona = new Daytona()\nconst snapshot = await daytona.snapshot.get(\"my-inactive-snapshot\")\nconst activatedSnapshot = await daytona.snapshot.activate(snapshot)\nconsole.log(`Snapshot ${activatedSnapshot.name} activated`)\n```\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\ndaytona = Daytona::Daytona.new\nsnapshot = daytona.snapshot.get('my-inactive-snapshot')\nactivated_snapshot = daytona.snapshot.activate(snapshot)\nputs \"Snapshot #{activated_snapshot.name} activated\"\n```\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/snapshots/my-inactive-snapshot/activate \\\n  --request POST \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/snapshot#snapshotserviceactivate), [TypeScript SDK](/docs/en/typescript-sdk/snapshot#activate), [Ruby SDK](/docs/en/ruby-sdk/snapshot#activate), and [API](/docs/en/tools/api/#daytona/tag/snapshots) references:\n\n> [**activate (Python SDK)**](/docs/en/python-sdk/sync/snapshot#snapshotserviceactivate)\n>\n> [**activate (TypeScript SDK)**](/docs/en/typescript-sdk/snapshot#activate)\n>\n> [**activate (Ruby SDK)**](/docs/en/ruby-sdk/snapshot#activate)\n>\n> [**activate (API)**](/docs/en/tools/api/#daytona/tag/snapshots/POST/snapshots/{snapshotName}/activate)\n\n## Deactivate Snapshots\n\nDaytona provides an option to deactivate snapshots. Deactivated snapshots are not available for new sandboxes.\n\n1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n2. Click the three dots at the end of the row for the snapshot you want to deactivate\n3. Click the **Deactivate** button\n\n## Delete Snapshots\n\nDaytona provides options to delete snapshots. Deleted snapshots cannot be recovered.\n\n1. Navigate to [Daytona Snapshots ↗](https://app.daytona.io/dashboard/snapshots)\n2. Click the three dots at the end of the row for the snapshot you want to delete\n3. Click the **Delete** button\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\ndaytona = Daytona()\nsnapshot = daytona.snapshot.get(\"my-awesome-snapshot\")\ndaytona.snapshot.delete(snapshot)\nprint(\"Snapshot deleted\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nconst daytona = new Daytona()\nconst snapshot = await daytona.snapshot.get(\"my-awesome-snapshot\")\nawait daytona.snapshot.delete(snapshot)\nconsole.log(\"Snapshot deleted\")\n```\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n```ruby\ndaytona = Daytona::Daytona.new\nsnapshot = daytona.snapshot.get('my-awesome-snapshot')\ndaytona.snapshot.delete(snapshot)\nputs 'Snapshot deleted'\n```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n```go\nsnapshot, err := client.Snapshots.Get(ctx, \"my-awesome-snapshot\")\nif err != nil {\n    return err\n}\nerr = client.Snapshots.Delete(ctx, snapshot)\nif err != nil {\n    return err\n}\nfmt.Println(\"Snapshot deleted\")\n```\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona snapshot delete my-awesome-snapshot\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl https://app.daytona.io/api/snapshots/my-awesome-snapshot \\\n  --request DELETE \\\n  --header 'Authorization: Bearer YOUR_SECRET_TOKEN'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/sync/snapshot#snapshotservicedelete), [TypeScript SDK](/docs/en/typescript-sdk/snapshot#delete), [Ruby SDK](/docs/en/ruby-sdk/snapshot#delete), [Go SDK](/docs/en/go-sdk/daytona#SnapshotService.Delete), [CLI](/docs/en/tools/cli#daytona-snapshot-delete), and [API](/docs/en/tools/api/#daytona/tag/snapshots) references:\n\n> [**delete (Python SDK)**](/docs/en/python-sdk/sync/snapshot#snapshotservicedelete)\n>\n> [**delete (TypeScript SDK)**](/docs/en/typescript-sdk/snapshot#delete)\n>\n> [**delete (Ruby SDK)**](/docs/en/ruby-sdk/snapshot#delete)\n>\n> [**delete (Go SDK)**](/docs/en/go-sdk/daytona#SnapshotService.Delete)\n>\n> [**delete (CLI)**](/docs/en/tools/cli#daytona-snapshot-delete)\n>\n> [**delete (API)**](/docs/en/tools/api/#daytona/tag/snapshots/DELETE/snapshots/{snapshotName})\n\n## Run Docker in a Sandbox\n\nDaytona Sandboxes can run Docker containers inside them (**Docker-in-Docker**), enabling you to build, test, and deploy containerized applications. This is particularly useful when your projects have dependencies on external services like databases, message queues, or other microservices.\n\nAgents can seamlessly interact with these services since they run within the same sandbox environment, providing better isolation and security compared to external service dependencies. The following use cases are supported:\n\n- Run databases (PostgreSQL, Redis, MySQL) and other services\n- Build and test containerized applications\n- Deploy microservices and their dependencies\n- Create isolated development environments with full container orchestration\n\n:::note\nDocker-in-Docker Sandboxes require additional resources due to the Docker daemon overhead. Consider allocating at least 2 vCPU and 4GiB of memory for optimal performance.\n:::\n\n### Create a Docker-in-Docker Snapshot\n\nDaytona provides an option to create a snapshot with Docker support using pre-built Docker-in-Docker images as a base or by manually installing Docker in a custom image.\n\n#### Using pre-built images\n\nThe following base images are widely used for creating Docker-in-Docker snapshots or can be used as a base for a custom Dockerfile:\n\n- `docker:28.3.3-dind`: official Docker-in-Docker image (Alpine-based, lightweight)\n- `docker:28.3.3-dind-rootless`: rootless Docker-in-Docker for enhanced security\n- `docker:28.3.2-dind-alpine3.22`: Docker-in-Docker image with Alpine 3.22\n\n#### Using manual installation\n\nAlternatively, install Docker manually in a custom Dockerfile:\n\n```dockerfile\nFROM ubuntu:22.04\n# Install Docker using the official install script\nRUN curl -fsSL https://get.docker.com | VERSION=28.3.3 sh -\n```\n\n### Run Docker Compose in a Sandbox\n\nDocker Compose allows you to define and run multi-container applications. With Docker-in-Docker enabled in a Daytona Sandbox, you can use Docker Compose to orchestrate services like databases, caches, and application containers.\n\nFirst, create a Docker-in-Docker snapshot using the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/snapshots) or [CLI](/docs/en/tools/cli#daytona-snapshot-create) with one of the [pre-built images](#using-pre-built-images) (e.g., `docker:28.3.3-dind`). Then use the following snippet to run Docker Compose services inside a sandbox:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, CreateSandboxFromSnapshotParams\n\n# Initialize the Daytona client\ndaytona = Daytona()\n\n# Create a sandbox from a Docker-in-Docker snapshot\nsandbox = daytona.create(CreateSandboxFromSnapshotParams(snapshot='docker-dind'))\n\n# Create a docker-compose.yml file\ncompose_content = '''\nservices:\n  web:\n    image: nginx:alpine\n    ports:\n      - \"8080:80\"\n'''\nsandbox.fs.upload_file(compose_content.encode(), 'docker-compose.yml')\n\n# Start Docker Compose services\nresult = sandbox.process.exec('docker compose -p demo up -d')\nprint(result.result)\n\n# Check running services\nresult = sandbox.process.exec('docker compose -p demo ps')\nprint(result.result)\n\n# Clean up\nsandbox.process.exec('docker compose -p demo down')\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\n\n// Initialize the Daytona client\nconst daytona = new Daytona()\n\n// Create a sandbox from a Docker-in-Docker snapshot\nconst sandbox = await daytona.create({ snapshot: 'docker-dind' })\n\n// Create a docker-compose.yml file\nconst composeContent = `\nservices:\n  web:\n    image: nginx:alpine\n    ports:\n      - \"8080:80\"\n`\nawait sandbox.fs.uploadFile(Buffer.from(composeContent), 'docker-compose.yml')\n\n// Start Docker Compose services\nlet result = await sandbox.process.executeCommand('docker compose -p demo up -d')\nconsole.log(result.result)\n\n// Check running services\nresult = await sandbox.process.executeCommand('docker compose -p demo ps')\nconsole.log(result.result)\n\n// Clean up\nawait sandbox.process.executeCommand('docker compose -p demo down')\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\n# Initialize the Daytona client\ndaytona = Daytona::Daytona.new\n\n# Create a sandbox from a Docker-in-Docker snapshot\nsandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(snapshot: 'docker-dind'))\n\n# Create a docker-compose.yml file\ncompose_content = <<~YAML\nservices:\n  web:\n    image: nginx:alpine\n    ports:\n      - \"8080:80\"\nYAML\nsandbox.fs.upload_file(compose_content, 'docker-compose.yml')\n\n# Start Docker Compose services\nresult = sandbox.process.exec(command: 'docker compose -p demo up -d')\nputs result.result\n\n# Check running services\nresult = sandbox.process.exec(command: 'docker compose -p demo ps')\nputs result.result\n\n# Clean up\nsandbox.process.exec(command: 'docker compose -p demo down')\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/sdk-go/daytona\"\n\t\"github.com/daytonaio/sdk-go/types\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\t// Initialize the Daytona client\n\tclient, _ := daytona.NewDaytona(nil)\n\n\t// Create a sandbox from a Docker-in-Docker snapshot\n\tsandbox, _ := client.Create(ctx, &types.CreateSandboxFromSnapshotParams{\n\t\tSnapshot: daytona.Ptr(\"docker-dind\"),\n\t}, nil)\n\n\t// Create a docker-compose.yml file\n\tcomposeContent := `\nservices:\n  web:\n    image: nginx:alpine\n    ports:\n      - \"8080:80\"\n`\n\tsandbox.Fs.UploadFile(ctx, []byte(composeContent), \"docker-compose.yml\")\n\n\t// Start Docker Compose services\n\tresult, _ := sandbox.Process.ExecuteCommand(ctx, \"docker compose -p demo up -d\", nil)\n\tfmt.Println(result.Result)\n\n\t// Check running services\n\tresult, _ = sandbox.Process.ExecuteCommand(ctx, \"docker compose -p demo ps\", nil)\n\tfmt.Println(result.Result)\n\n\t// Clean up\n\tsandbox.Process.ExecuteCommand(ctx, \"docker compose -p demo down\", nil)\n}\n```\n\n</TabItem>\n</Tabs>\n\n## Run Kubernetes in a Sandbox\n\nDaytona Sandboxes can run a Kubernetes cluster inside the sandbox. Kubernetes runs entirely inside the sandbox and is removed when the sandbox is deleted, keeping environments secure and reproducible.\n\n### Run k3s in a Sandbox\n\nThe following snippet installs and starts a k3s cluster inside a sandbox and lists all running pods.\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\nimport { setTimeout } from 'timers/promises'\n\n// Initialize the Daytona client\nconst daytona = new Daytona()\n\n// Create the sandbox instance\nconst sandbox = await daytona.create()\n\n// Run the k3s installation script\nconst response = await sandbox.process.executeCommand(\n  'curl -sfL https://get.k3s.io | sh -'\n)\n\n// Run k3s\nconst sessionName = 'k3s-server'\nawait sandbox.process.createSession(sessionName)\nconst k3s = await sandbox.process.executeSessionCommand(sessionName, {\n  command: 'sudo /usr/local/bin/k3s server',\n  async: true,\n})\n\n// Give time to k3s to fully start\nawait setTimeout(30000)\n\n// Get all pods\nconst pods = await sandbox.process.executeCommand(\n  'sudo /usr/local/bin/kubectl get pod -A'\n)\nconsole.log(pods.result)\n```\n\n## Default Snapshots\n\nWhen a sandbox is created with no snapshot specified, Daytona uses a default snapshot that includes `python`, `node`, their language servers, and several common pip packages. Daytona provides three default snapshot sizes:\n\n| **Snapshot**         | **vCPU** | **Memory** | **Storage** |\n| -------------------- | -------- | ---------- | ----------- |\n| **`daytona-small`**  | 1        | 1GiB       | 3GiB        |\n| **`daytona-medium`** | 2        | 4GiB       | 8GiB        |\n| **`daytona-large`**  | 4        | 8GiB       | 10GiB       |\n\nAll default snapshots are based on the `daytonaio/sandbox:<version>` image. For more information, see the [Dockerfile](https://github.com/daytonaio/daytona/blob/main/images/sandbox/Dockerfile).\n\n### Python packages (pip)\n\n- `anthropic` (v0.76.0)\n- `beautifulsoup4` (v4.14.3)\n- `claude-agent-sdk` (v0.1.22)\n- `daytona` (v0.134.0)\n- `django` (v6.0.1)\n- `flask` (v3.1.2)\n- `huggingface-hub` (v0.36.0)\n- `instructor` (v1.14.4)\n- `keras` (v3.13.0)\n- `langchain` (v1.2.7)\n- `llama-index` (v0.14.13)\n- `matplotlib` (v3.10.8)\n- `numpy` (v2.4.1)\n- `ollama` (v0.6.1)\n- `openai` (v2.15.0)\n- `opencv-python` (v4.13.0.90)\n- `pandas` (v2.3.3)\n- `pillow` (v12.1.0)\n- `pydantic-ai` (v1.47.0)\n- `requests` (v2.32.5)\n- `scikit-learn` (v1.8.0)\n- `scipy` (v1.17.0)\n- `seaborn` (v0.13.2)\n- `sqlalchemy` (v2.0.46)\n- `torch` (v2.10.0)\n- `transformers` (v4.57.6)\n\n### Node.js packages (npm)\n\n- `@anthropic-ai/claude-code` (v2.1.19)\n- `bun` (v1.3.6)\n- `openclaw` (v2026.2.1)\n- `opencode-ai` (v1.1.35)\n- `ts-node` (v10.9.2)\n- `typescript` (v5.9.3)\n- `typescript-language-server` (v5.1.3)\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/ssh-access.mdx",
    "content": "---\ntitle: SSH Access\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona provides SSH access to your sandboxes using token-based authentication. This allows you to connect from local terminals, IDEs, and development tools without installing additional software.\n\n## Access from Dashboard\n\nCreate an SSH access token directly from the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/sandboxes).\n\n1. Navigate to [Sandboxes ↗](https://app.daytona.io/dashboard/sandboxes)\n2. Locate the sandbox you want to create an SSH access token for\n3. Click the sandbox options menu (**⋮**)\n4. Select **Create SSH Access**\n5. Set the expiration time (defaults to 60 minutes)\n6. Click **Create**\n\nDaytona generates a token and displays it in the modal. Copy the token and use it to connect to your sandbox.\n\n## Access via CLI\n\nDaytona provides a CLI command to create an SSH access token for a sandbox:\n\n```shell  \ndaytona create\n```\n\nWhen you create a sandbox, Daytona displays the SSH command automatically in the output:\n\n```text\nSandbox '<sandboxId>' created successfully\nConnect via SSH:         daytona ssh <sandboxId>\nOpen the Web Terminal:   https://22222-<sandboxId>.proxy.daytona.work\n```\n\nTo SSH into an existing sandbox, use the following command:\n\n```bash\ndaytona ssh <sandbox> --expires 60\n```\n\n## Access via token\n\nYou can create SSH access tokens programmatically. The token can then be used to connect manually:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona\n\ndaytona = Daytona()\nsandbox = daytona.get(\"sandbox-abc123\")\n\n# Create SSH access token\nssh_access = sandbox.create_ssh_access(expires_in_minutes=60)\nprint(f\"SSH Token: {ssh_access.token}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\n\nconst daytona = new Daytona()\nconst sandbox = await daytona.get('sandbox-abc123')\n\n// Create SSH access token\nconst sshAccess = await sandbox.createSshAccess(60)\nconsole.log(`SSH Token: ${sshAccess.token}`)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.get('sandbox-abc123')\n\n# Create SSH access token\nssh_access = sandbox.create_ssh_access(expires_in_minutes: 60)\nputs \"SSH Token: #{ssh_access.token}\"\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxId}/ssh-access?expiresInMinutes=60' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\nTo connect to your sandbox, use the following command:\n\n```bash\nssh <token>@ssh.app.daytona.io\n```\n\n## Connect with VS Code\n\nYou can connect VS Code directly to your sandbox using the Remote SSH extension.\n\n1. Install the [Remote Explorer extension ↗](https://marketplace.visualstudio.com/items?itemName=ms-vscode.remote-explorer)\n2. Add a new SSH connection\n3. When prompted for the SSH connection URL, paste the SSH command from above\n\nFor more information, see the [VS Code Remote SSH documentation ↗](https://code.visualstudio.com/docs/remote/ssh).\n\n## Connect with JetBrains IDEs\n\nJetBrains Gateway provides remote development support for connecting to your sandbox.\n\n1. Download [JetBrains Gateway ↗](https://www.jetbrains.com/remote-development/gateway/)\n2. Add a new connection\n3. When prompted for the SSH connection URL, paste the SSH command from above\n4. Select the IDE to install in your sandbox\n\n## Token management\n\n### Expiration\n\nSSH access tokens expire automatically after 60 minutes. You can specify a custom expiration time when creating the token using the `expires_in_minutes` parameter.\n\n### Revoke token\n\nRevoke SSH access tokens before expiry:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Revoke specific SSH access token for the sandbox\nsandbox.revoke_ssh_access(token=\"specific-token\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Revoke specific SSH access token for the sandbox\nawait sandbox.revokeSshAccess('specific-token')\n```\n\n</TabItem>\n\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Revoke specific SSH access token for the sandbox\nsandbox.revoke_ssh_access(token: 'specific-token')\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\n# Revoke specific SSH access token\ncurl 'https://app.daytona.io/api/sandbox/{sandboxId}/ssh-access?token=specific-token' \\\n  --request DELETE \\\n  --header 'Authorization: Bearer <API_KEY>'\n\n# Revoke all SSH access for the sandbox\ncurl 'https://app.daytona.io/api/sandbox/{sandboxId}/ssh-access' \\\n  --request DELETE \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\n## Related\n\n- [Web Terminal](/docs/en/web-terminal): browser-based terminal access to sandboxes\n- [Preview](/docs/en/preview): generate preview URLs for accessing sandbox services\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/tools/api.mdx",
    "content": "---\ntitle: Daytona API Reference\ndescription: A reference of supported operations using the Daytona API.\ntableOfContents: false\n---\n\nimport ApiReference from '@components/ApiReference.astro'\n\n<ApiReference />\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/tools/cli.mdx",
    "content": "---\ntitle: CLI\ndescription: A reference of supported operations using the Daytona CLI.\nsidebar:\n  label: Daytona CLI Reference\n---\nimport Aside from \"@components/Aside.astro\";\nimport Label from \"@components/Label.astro\";\n\nThe `daytona` command-line tool provides access to Daytona's core features including managing Snapshots and the lifecycle of Daytona Sandboxes. View the installation instructions by clicking [here](/docs/getting-started#cli).\n\nThis reference lists all commands supported by the `daytona` command-line tool complete with a description of their behaviour, and any supported flags.\nYou can access this documentation on a per-command basis by appending the `--help`/`-h` flag when invoking `daytona`.\n\n## daytona\nDaytona CLI\n\n```shell\ndaytona [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n| `--version` | `-v` | Display the version of Daytona |\n\n\n## daytona archive\nArchive a sandbox\n\n```shell\ndaytona archive [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona autocomplete\nAdds a completion script for your shell environment\n\n```shell\ndaytona autocomplete [bash|zsh|fish|powershell] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n<Aside type=\"note\">\nIf using bash shell environment, make sure you have bash-completion installed in order to get full autocompletion functionality.\nLinux Installation: ```sudo apt-get install bash-completion```\nmacOS Installation: ```brew install bash-completion```\n</Aside>\n\n## daytona create\nCreate a new sandbox\n\n```shell\ndaytona create [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--auto-archive` |  | Auto-archive interval in minutes (0 means the maximum interval will be used) |\n| `--auto-delete` |  | Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping) |\n| `--auto-stop` |  | Auto-stop interval in minutes (0 means disabled) |\n| `--class` |  | Sandbox class type (small, medium, large) |\n| `--context` | `-c` | Files or directories to include in the build context (can be specified multiple times) |\n| `--cpu` |  | CPU cores allocated to the sandbox |\n| `--disk` |  | Disk space allocated to the sandbox in GB |\n| `--dockerfile` | `-f` | Path to Dockerfile for Sandbox snapshot |\n| `--env` | `-e` | Environment variables (format: KEY=VALUE) |\n| `--gpu` |  | GPU units allocated to the sandbox |\n| `--label` | `-l` | Labels (format: KEY=VALUE) |\n| `--memory` |  | Memory allocated to the sandbox in MB |\n| `--name` |  | Name of the sandbox |\n| `--network-allow-list` |  | Comma-separated list of allowed CIDR network addresses for the sandbox |\n| `--network-block-all` |  | Whether to block all network access for the sandbox |\n| `--public` |  | Make sandbox publicly accessible |\n| `--snapshot` |  | Snapshot to use for the sandbox |\n| `--target` |  | Target region (eu, us) |\n| `--user` |  | User associated with the sandbox |\n| `--volume` | `-v` | Volumes to mount (format: VOLUME_NAME:MOUNT_PATH) |\n| `--help` |  | help for daytona |\n\n\n## daytona delete\nDelete a sandbox\n\n```shell\ndaytona delete [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--all` | `-a` | Delete all sandboxes |\n| `--help` |  | help for daytona |\n\n\n## daytona docs\nOpens the Daytona documentation in your default browser.\n\n```shell\ndaytona docs [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona exec\nExecute a command in a sandbox\n\n```shell\ndaytona exec [SANDBOX_ID | SANDBOX_NAME] -- [COMMAND] [ARGS...] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--cwd` |  | Working directory for command execution |\n| `--timeout` |  | Command timeout in seconds (0 for no timeout) |\n| `--help` |  | help for daytona |\n\n\n## daytona info\nGet sandbox info\n\n```shell\ndaytona info [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | Output format. Must be one of (yaml, json) |\n| `--help` |  | help for daytona |\n\n\n## daytona list\nList sandboxes\n\n```shell\ndaytona list [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | Output format. Must be one of (yaml, json) |\n| `--limit` | `-l` | Maximum number of items per page |\n| `--page` | `-p` | Page number for pagination (starting from 1) |\n| `--help` |  | help for daytona |\n\n\n## daytona login\nLog in to Daytona\n\n```shell\ndaytona login [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--api-key` |  | API key to use for authentication |\n| `--help` |  | help for daytona |\n\n\n## daytona logout\nLogout from Daytona\n\n```shell\ndaytona logout [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona mcp\nManage Daytona MCP Server\n\n```shell\ndaytona mcp [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona mcp config\nOutputs JSON configuration for Daytona MCP Server\n\n```shell\ndaytona mcp config [AGENT_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona mcp init\nInitialize Daytona MCP Server with an agent (currently supported: claude, windsurf, cursor)\n\n\n```shell\ndaytona mcp init [AGENT_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona mcp start\nStart Daytona MCP Server\n\n```shell\ndaytona mcp start [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona organization\nManage Daytona organizations\n\n```shell\ndaytona organization [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona organization create\nCreate a new organization and set it as active\n\n```shell\ndaytona organization create [ORGANIZATION_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona organization delete\nDelete an organization\n\n```shell\ndaytona organization delete [ORGANIZATION] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona organization list\nList all organizations\n\n```shell\ndaytona organization list [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | Output format. Must be one of (yaml, json) |\n| `--help` |  | help for daytona |\n\n\n## daytona organization use\nSet active organization\n\n```shell\ndaytona organization use [ORGANIZATION] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona preview-url\nGet signed preview URL for a sandbox port\n\n```shell\ndaytona preview-url [SANDBOX_ID | SANDBOX_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--expires` |  | URL expiration time in seconds |\n| `--port` | `-p` | Port number to get preview URL for (required) |\n| `--help` |  | help for daytona |\n\n\n## daytona snapshot\nManage Daytona snapshots\n\n```shell\ndaytona snapshot [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona snapshot create\nCreate a snapshot\n\n```shell\ndaytona snapshot create [SNAPSHOT] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--context` | `-c` | Files or directories to include in the build context (can be specified multiple times). If not provided, context will be automatically determined from COPY/ADD commands in the Dockerfile |\n| `--cpu` |  | CPU cores that will be allocated to the underlying sandboxes (default: 1) |\n| `--disk` |  | Disk space that will be allocated to the underlying sandboxes in GB (default: 3) |\n| `--dockerfile` | `-f` | Path to Dockerfile to build |\n| `--entrypoint` | `-e` | The entrypoint command for the snapshot |\n| `--image` | `-i` | The image name for the snapshot |\n| `--memory` |  | Memory that will be allocated to the underlying sandboxes in GB (default: 1) |\n| `--region` |  | ID of the region where the snapshot will be available (defaults to organization default region) |\n| `--help` |  | help for daytona |\n\n\n## daytona snapshot delete\nDelete a snapshot\n\n```shell\ndaytona snapshot delete [SNAPSHOT_ID] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--all` | `-a` | Delete all snapshots |\n| `--help` |  | help for daytona |\n\n\n## daytona snapshot list\nList all snapshots\n\n```shell\ndaytona snapshot list [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | Output format. Must be one of (yaml, json) |\n| `--limit` | `-l` | Maximum number of items per page |\n| `--page` | `-p` | Page number for pagination (starting from 1) |\n| `--help` |  | help for daytona |\n\n\n## daytona snapshot push\nPush local snapshot\n\n```shell\ndaytona snapshot push [SNAPSHOT] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--cpu` |  | CPU cores that will be allocated to the underlying sandboxes (default: 1) |\n| `--disk` |  | Disk space that will be allocated to the underlying sandboxes in GB (default: 3) |\n| `--entrypoint` | `-e` | The entrypoint command for the image |\n| `--memory` |  | Memory that will be allocated to the underlying sandboxes in GB (default: 1) |\n| `--name` | `-n` | Specify the Snapshot name |\n| `--region` |  | ID of the region where the snapshot will be available (defaults to organization default region) |\n| `--help` |  | help for daytona |\n\n\n## daytona ssh\nSSH into a sandbox\n\n```shell\ndaytona ssh [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--expires` |  | SSH access token expiration time in minutes (defaults to 24 hours) |\n| `--help` |  | help for daytona |\n\n\n## daytona start\nStart a sandbox\n\n```shell\ndaytona start [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona stop\nStop a sandbox\n\n```shell\ndaytona stop [SANDBOX_ID] | [SANDBOX_NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona version\nPrint the version number\n\n```shell\ndaytona version [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona volume\nManage Daytona volumes\n\n```shell\ndaytona volume [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona volume create\nCreate a volume\n\n```shell\ndaytona volume create [NAME] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--size` | `-s` | Size of the volume in GB |\n| `--help` |  | help for daytona |\n\n\n## daytona volume delete\nDelete a volume\n\n```shell\ndaytona volume delete [VOLUME_ID] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` |  | help for daytona |\n\n\n## daytona volume get\nGet volume details\n\n```shell\ndaytona volume get [VOLUME_ID] [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | Output format. Must be one of (yaml, json) |\n| `--help` |  | help for daytona |\n\n\n## daytona volume list\nList all volumes\n\n```shell\ndaytona volume list [flags]\n```\n\n__Flags__\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | Output format. Must be one of (yaml, json) |\n| `--help` |  | help for daytona |\n\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/charts.mdx",
    "content": "---\ntitle: \"Charts\"\nhideTitleOnPage: true\n---\n\n\n## ChartType\n\nChart types\n\n**Enum Members**:\n\n- `BAR` (\"bar\")\n- `LINE` (\"line\")\n- `PIE` (\"pie\")\n- `SCATTER` (\"scatter\")\n- `UNKNOWN` (\"unknown\")\n\n## parseChart()\n\n```ts\nfunction parseChart(data: any): Chart\n```\n\n**Parameters**:\n\n- `data` _any_\n\n\n**Returns**:\n\n- `Chart`\n\n***\n\n\n## BarChart\n\n```ts\ntype BarChart = Chart2D & {\n  elements: BarData[];\n  type: BAR;\n};\n```\n\nRepresents a bar chart with metadata.\n\n**Type declaration**:\n\n- `elements` _BarData\\[\\]_ - The bars of the chart\n- `type` _BAR_ - The type of chart\n    \n\n\n## BarData\n\n```ts\ntype BarData = {\n  group: string;\n  label: string;\n  value: string;\n};\n```\n\nRepresents a bar in a bar chart.\n\n**Type declaration**:\n\n- `group` _string_ - The group of the bar\n- `label` _string_ - The label of the bar\n- `value` _string_ - The value of the bar\n    \n\n\n## BoxAndWhiskerChart\n\n```ts\ntype BoxAndWhiskerChart = Chart2D & {\n  elements: BoxAndWhiskerData[];\n  type: BOX_AND_WHISKER;\n};\n```\n\nRepresents a box and whisker chart with metadata.\n\n**Type declaration**:\n\n- `elements` _BoxAndWhiskerData\\[\\]_ - The box and whiskers of the chart\n- `type` _BOX\\_AND\\_WHISKER_ - The type of chart\n    \n\n\n## BoxAndWhiskerData\n\n```ts\ntype BoxAndWhiskerData = {\n  first_quartile: number;\n  label: string;\n  max: number;\n  median: number;\n  min: number;\n  outliers: number[];\n};\n```\n\nRepresents a box and whisker in a box and whisker chart.\n\n**Type declaration**:\n\n- `first\\_quartile` _number_ - The first quartile of the box and whisker\n- `label` _string_ - The label of the box and whisker\n- `max` _number_ - The third quartile of the box and whisker\n- `median` _number_ - The median of the box and whisker\n- `min` _number_ - The minimum value of the box and whisker\n- `outliers` _number\\[\\]_\n\n\n## Chart\n\n```ts\ntype Chart = {\n  elements: any[];\n  png: string;\n  title: string;\n  type: ChartType;\n};\n```\n\nRepresents a chart with metadata from matplotlib.\n\n**Type declaration**:\n\n- `elements` _any\\[\\]_ - The elements of the chart\n- `png?` _string_ - The PNG representation of the chart encoded in base64\n- `title` _string_ - The title of the chart\n- `type` _ChartType_ - The type of chart\n    \n\n\n## Chart2D\n\n```ts\ntype Chart2D = Chart & {\n  x_label: string;\n  y_label: string;\n};\n```\n\nRepresents a 2D chart with metadata.\n\n**Type declaration**:\n\n- `x\\_label?` _string_ - The label of the x-axis\n- `y\\_label?` _string_ - The label of the y-axis\n    \n\n\n## CompositeChart\n\n```ts\ntype CompositeChart = Chart & {\n  elements: Chart[];\n  type: COMPOSITE_CHART;\n};\n```\n\nRepresents a composite chart with metadata.\n\n**Type declaration**:\n\n- `elements` _Chart\\[\\]_ - The charts of the composite chart\n- `type` _COMPOSITE\\_CHART_ - The type of chart\n    \n\n\n## LineChart\n\n```ts\ntype LineChart = PointChart & {\n  type: LINE;\n};\n```\n\nRepresents a line chart with metadata.\n\n**Type declaration**:\n\n- `type` _LINE_ - The type of chart\n    \n\n\n## PieChart\n\n```ts\ntype PieChart = Chart & {\n  elements: PieData[];\n  type: PIE;\n};\n```\n\nRepresents a pie chart with metadata.\n\n**Type declaration**:\n\n- `elements` _PieData\\[\\]_ - The pie slices of the chart\n- `type` _PIE_ - The type of chart\n    \n\n\n## PieData\n\n```ts\ntype PieData = {\n  angle: number;\n  label: string;\n  radius: number;\n};\n```\n\nRepresents a pie slice in a pie chart.\n\n**Type declaration**:\n\n- `angle` _number_ - The angle of the pie slice\n- `label` _string_ - The label of the pie slice\n- `radius` _number_ - The radius of the pie slice\n    \n\n\n## PointChart\n\n```ts\ntype PointChart = Chart2D & {\n  elements: PointData[];\n  x_scale: string;\n  x_tick_labels: string[];\n  x_ticks: (number | string)[];\n  y_scale: string;\n  y_tick_labels: string[];\n  y_ticks: (number | string)[];\n};\n```\n\nRepresents a point chart with metadata.\n\n**Type declaration**:\n\n- `elements` _PointData\\[\\]_ - The points of the chart\n- `x\\_scale` _string_ - The scale of the x-axis\n- `x\\_tick\\_labels` _string\\[\\]_ - The labels of the x-axis\n- `x\\_ticks` _\\(number \\| string\\)\\[\\]_ - The ticks of the x-axis\n- `y\\_scale` _string_ - The scale of the y-axis\n- `y\\_tick\\_labels` _string\\[\\]_ - The labels of the y-axis\n- `y\\_ticks` _\\(number \\| string\\)\\[\\]_ - The ticks of the y-axis\n    \n\n\n## PointData\n\n```ts\ntype PointData = {\n  label: string;\n  points: [number | string, number | string][];\n};\n```\n\nRepresents a point in a 2D chart.\n\n**Type declaration**:\n\n- `label` _string_ - The label of the point\n- `points` _\\[number \\| string, number \\| string\\]\\[\\]_ - The points of the chart\n    \n\n\n## ScatterChart\n\n```ts\ntype ScatterChart = PointChart & {\n  type: SCATTER;\n};\n```\n\nRepresents a scatter chart with metadata.\n\n**Type declaration**:\n\n- `type` _SCATTER_ - The type of chart\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/code-interpreter.mdx",
    "content": "---\ntitle: \"CodeInterpreter\"\nhideTitleOnPage: true\n---\n\n\n## CodeInterpreter\n\nHandles Python code interpretation and execution within a Sandbox.\n\nProvides methods to execute code (currently only Python) in isolated interpreter contexts,\nmanage contexts, and stream execution output via callbacks.\n\nFor other languages, use the `codeRun` method from the `Process` interface, or execute the appropriate command directly in the sandbox terminal.\n\n### Constructors\n\n#### new CodeInterpreter()\n\n```ts\nnew CodeInterpreter(\n   clientConfig: Configuration, \n   apiClient: InterpreterApi, \n   getPreviewToken: () => Promise<string>): CodeInterpreter\n```\n\n**Parameters**:\n\n- `clientConfig` _Configuration_\n- `apiClient` _InterpreterApi_\n- `getPreviewToken` _\\(\\) =\\> Promise\\<string\\>_\n\n\n**Returns**:\n\n- `CodeInterpreter`\n\n### Methods\n\n#### createContext()\n\n```ts\ncreateContext(cwd?: string): Promise<InterpreterContext>\n```\n\nCreate a new isolated interpreter context.\n\n**Parameters**:\n\n- `cwd?` _string_ - Working directory for the context. Uses sandbox working directory if omitted.\n\n\n**Returns**:\n\n- `Promise<InterpreterContext>` - The created context.\n\n**Example:**\n\n```ts\nconst ctx = await sandbox.codeInterpreter.createContext()\nawait sandbox.codeInterpreter.runCode('x = 10', { context: ctx })\nawait sandbox.codeInterpreter.deleteContext(ctx.id!)\n```\n\n***\n\n#### deleteContext()\n\n```ts\ndeleteContext(context: InterpreterContext): Promise<void>\n```\n\nDelete an interpreter context and shut down its worker process.\n\n**Parameters**:\n\n- `context` _InterpreterContext_ - Context to delete.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nconst ctx = await sandbox.codeInterpreter.createContext()\n// ... use context ...\nawait sandbox.codeInterpreter.deleteContext(ctx)\n```\n\n***\n\n#### listContexts()\n\n```ts\nlistContexts(): Promise<InterpreterContext[]>\n```\n\nList all user-created interpreter contexts (default context is excluded).\n\n**Returns**:\n\n- `Promise<InterpreterContext[]>` - List of contexts.\n\n**Example:**\n\n```ts\nconst contexts = await sandbox.codeInterpreter.listContexts()\nfor (const ctx of contexts) {\n  console.log(ctx.id, ctx.language, ctx.cwd)\n}\n```\n\n***\n\n#### runCode()\n\n```ts\nrunCode(code: string, options: RunCodeOptions): Promise<ExecutionResult>\n```\n\nRun Python code in the sandbox.\n\n**Parameters**:\n\n- `code` _string_ - Code to run.\n- `options` _RunCodeOptions = {}_ - Execution options (context, envs, callbacks, timeout).\n\n\n**Returns**:\n\n- `Promise<ExecutionResult>` - ExecutionResult containing stdout, stderr and optional error info.\n\n**Example:**\n\n```ts\nconst handleStdout = (msg: OutputMessage) => process.stdout.write(`STDOUT: ${msg.output}`)\nconst handleStderr = (msg: OutputMessage) => process.stdout.write(`STDERR: ${msg.output}`)\nconst handleError = (err: ExecutionError) =>\n  console.error(`ERROR: ${err.name}: ${err.value}\\n${err.traceback ?? ''}`)\n\nconst code = `\nimport sys\nimport time\nfor i in range(5):\n    print(i)\n    time.sleep(1)\nsys.stderr.write(\"Counting done!\")\n`\n\nconst result = await codeInterpreter.runCode(code, {\n  onStdout: handleStdout,\n  onStderr: handleStderr,\n  onError: handleError,\n  timeout: 10,\n})\n```\n\n***\n\n\n## ExecutionError\n\nRepresents an error that occurred during code execution.\n\n**Properties**:\n\n- `name` _string_ - Error type/class name (e.g., \"ValueError\", \"SyntaxError\").\n- `traceback?` _string_ - Full traceback for the error, if available.\n- `value` _string_ - Error value/message.\n## ExecutionResult\n\nResult of code execution.\n\n**Properties**:\n\n- `error?` _ExecutionError_ - Details about an execution error, if one occurred.\n- `stderr` _string_ - Standard error captured during execution.\n- `stdout` _string_ - Standard output captured during execution.\n## OutputMessage\n\nRepresents stdout or stderr output from code execution.\n\n**Properties**:\n\n- `output` _string_ - Output content.\n## RunCodeOptions\n\nOptions for executing code in the interpreter.\n\n**Properties**:\n\n- `context?` _InterpreterContext_ - Interpreter context to run code in.\n- `envs?` _Record\\<string, string\\>_ - Environment variables for this execution.\n- `onError()?` _\\(error: ExecutionError\\) =\\> any_ - Callback for execution errors (e.g., runtime exceptions).\n    \n    **Parameters**:\n    \n    - `error` _ExecutionError_\n    \n    \n    **Returns**:\n    \n    - `any`\n- `onStderr()?` _\\(message: OutputMessage\\) =\\> any_ - Callback for stderr messages.\n    \n    **Parameters**:\n    \n    - `message` _OutputMessage_\n    \n    \n    **Returns**:\n    \n    - `any`\n- `onStdout()?` _\\(message: OutputMessage\\) =\\> any_ - Callback for stdout messages.\n    \n    **Parameters**:\n    \n    - `message` _OutputMessage_\n    \n    \n    **Returns**:\n    \n    - `any`\n- `timeout?` _number_ - Timeout in seconds. Set to 0 for no timeout. Default is 10 minutes."
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/computer-use.mdx",
    "content": "---\ntitle: \"ComputerUse\"\nhideTitleOnPage: true\n---\n\n\n## ComputerUse\n\nComputer Use functionality for interacting with the desktop environment.\n\n**Properties**:\n\n- `display` _Display_ - Display operations interface\n- `keyboard` _Keyboard_ - Keyboard operations interface\n- `mouse` _Mouse_ - Mouse operations interface\n- `recording` _RecordingService_ - Screen recording operations interface\n- `screenshot` _Screenshot_ - Screenshot operations interface\n    \n\n\n\n\nProvides access to mouse, keyboard, screenshot, display, and recording operations\nfor automating desktop interactions within a sandbox.\n\n### Constructors\n\n#### new ComputerUse()\n\n```ts\nnew ComputerUse(apiClient: ComputerUseApi): ComputerUse\n```\n\n**Parameters**:\n\n- `apiClient` _ComputerUseApi_\n\n\n**Returns**:\n\n- `ComputerUse`\n\n### Methods\n\n#### getProcessErrors()\n\n```ts\ngetProcessErrors(processName: string): Promise<ProcessErrorsResponse>\n```\n\nGets error logs for a specific VNC process\n\n**Parameters**:\n\n- `processName` _string_ - Name of the process to get error logs for\n\n\n**Returns**:\n\n- `Promise<ProcessErrorsResponse>` - Process error logs\n\n**Example:**\n\n```typescript\nconst errorsResp = await sandbox.computerUse.getProcessErrors('x11vnc');\nconsole.log('X11VNC errors:', errorsResp.errors);\n```\n\n***\n\n#### getProcessLogs()\n\n```ts\ngetProcessLogs(processName: string): Promise<ProcessLogsResponse>\n```\n\nGets logs for a specific VNC process\n\n**Parameters**:\n\n- `processName` _string_ - Name of the process to get logs for\n\n\n**Returns**:\n\n- `Promise<ProcessLogsResponse>` - Process logs\n\n**Example:**\n\n```typescript\nconst logsResp = await sandbox.computerUse.getProcessLogs('novnc');\nconsole.log('NoVNC logs:', logsResp.logs);\n```\n\n***\n\n#### getProcessStatus()\n\n```ts\ngetProcessStatus(processName: string): Promise<ProcessStatusResponse>\n```\n\nGets the status of a specific VNC process\n\n**Parameters**:\n\n- `processName` _string_ - Name of the process to check\n\n\n**Returns**:\n\n- `Promise<ProcessStatusResponse>` - Status information about the specific process\n\n**Example:**\n\n```typescript\nconst xvfbStatus = await sandbox.computerUse.getProcessStatus('xvfb');\nconst noVncStatus = await sandbox.computerUse.getProcessStatus('novnc');\n```\n\n***\n\n#### getStatus()\n\n```ts\ngetStatus(): Promise<ComputerUseStatusResponse>\n```\n\nGets the status of all computer use processes\n\n**Returns**:\n\n- `Promise<ComputerUseStatusResponse>` - Status information about all VNC desktop processes\n\n**Example:**\n\n```typescript\nconst status = await sandbox.computerUse.getStatus();\nconsole.log('Computer use status:', status.status);\n```\n\n***\n\n#### restartProcess()\n\n```ts\nrestartProcess(processName: string): Promise<ProcessRestartResponse>\n```\n\nRestarts a specific VNC process\n\n**Parameters**:\n\n- `processName` _string_ - Name of the process to restart\n\n\n**Returns**:\n\n- `Promise<ProcessRestartResponse>` - Process restart response\n\n**Example:**\n\n```typescript\nconst result = await sandbox.computerUse.restartProcess('xfce4');\nconsole.log('XFCE4 process restarted:', result.message);\n```\n\n***\n\n#### start()\n\n```ts\nstart(): Promise<ComputerUseStartResponse>\n```\n\nStarts all computer use processes (Xvfb, xfce4, x11vnc, novnc)\n\n**Returns**:\n\n- `Promise<ComputerUseStartResponse>` - Computer use start response\n\n**Example:**\n\n```typescript\nconst result = await sandbox.computerUse.start();\nconsole.log('Computer use processes started:', result.message);\n```\n\n***\n\n#### stop()\n\n```ts\nstop(): Promise<ComputerUseStopResponse>\n```\n\nStops all computer use processes\n\n**Returns**:\n\n- `Promise<ComputerUseStopResponse>` - Computer use stop response\n\n**Example:**\n\n```typescript\nconst result = await sandbox.computerUse.stop();\nconsole.log('Computer use processes stopped:', result.message);\n```\n## Display\n\nDisplay operations for computer use functionality\n\n### Constructors\n\n#### new Display()\n\n```ts\nnew Display(apiClient: ComputerUseApi): Display\n```\n\n**Parameters**:\n\n- `apiClient` _ComputerUseApi_\n\n\n**Returns**:\n\n- `Display`\n\n### Methods\n\n#### getInfo()\n\n```ts\ngetInfo(): Promise<DisplayInfoResponse>\n```\n\nGets information about the displays\n\n**Returns**:\n\n- `Promise<DisplayInfoResponse>` - Display information including primary display and all available displays\n\n**Example:**\n\n```typescript\nconst info = await sandbox.computerUse.display.getInfo();\nconsole.log(`Primary display: ${info.primary_display.width}x${info.primary_display.height}`);\nconsole.log(`Total displays: ${info.total_displays}`);\ninfo.displays.forEach((display, index) => {\n  console.log(`Display ${index}: ${display.width}x${display.height} at ${display.x},${display.y}`);\n});\n```\n\n***\n\n#### getWindows()\n\n```ts\ngetWindows(): Promise<WindowsResponse>\n```\n\nGets the list of open windows\n\n**Returns**:\n\n- `Promise<WindowsResponse>` - List of open windows with their IDs and titles\n\n**Example:**\n\n```typescript\nconst windows = await sandbox.computerUse.display.getWindows();\nconsole.log(`Found ${windows.count} open windows:`);\nwindows.windows.forEach(window => {\n  console.log(`- ${window.title} (ID: ${window.id})`);\n});\n```\n\n***\n\n\n## Keyboard\n\nKeyboard operations for computer use functionality\n\n### Constructors\n\n#### new Keyboard()\n\n```ts\nnew Keyboard(apiClient: ComputerUseApi): Keyboard\n```\n\n**Parameters**:\n\n- `apiClient` _ComputerUseApi_\n\n\n**Returns**:\n\n- `Keyboard`\n\n### Methods\n\n#### hotkey()\n\n```ts\nhotkey(keys: string): Promise<void>\n```\n\nPresses a hotkey combination\n\n**Parameters**:\n\n- `keys` _string_ - The hotkey combination (e.g., 'ctrl+c', 'alt+tab', 'cmd+shift+t')\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf the hotkey operation fails\n\n**Example:**\n\n```typescript\n// Copy\ntry {\n  await sandbox.computerUse.keyboard.hotkey('ctrl+c');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// Paste\ntry {\n  await sandbox.computerUse.keyboard.hotkey('ctrl+v');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// Alt+Tab\ntry {\n  await sandbox.computerUse.keyboard.hotkey('alt+tab');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n```\n\n***\n\n#### press()\n\n```ts\npress(key: string, modifiers?: string[]): Promise<void>\n```\n\nPresses a key with optional modifiers\n\n**Parameters**:\n\n- `key` _string_ - The key to press (e.g., 'Enter', 'Escape', 'Tab', 'a', 'A')\n- `modifiers?` _string\\[\\] = \\[\\]_ - Modifier keys ('ctrl', 'alt', 'meta', 'shift')\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf the press operation fails\n\n**Example:**\n\n```typescript\n// Press Enter\ntry {\n  await sandbox.computerUse.keyboard.press('Return');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// Press Ctrl+C\ntry {\n  await sandbox.computerUse.keyboard.press('c', ['ctrl']);\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// Press Ctrl+Shift+T\ntry {\n  await sandbox.computerUse.keyboard.press('t', ['ctrl', 'shift']);\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n```\n\n***\n\n#### type()\n\n```ts\ntype(text: string, delay?: number): Promise<void>\n```\n\nTypes the specified text\n\n**Parameters**:\n\n- `text` _string_ - The text to type\n- `delay?` _number_ - Delay between characters in milliseconds\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf the type operation fails\n\n**Example:**\n\n```typescript\ntry {\n  await sandbox.computerUse.keyboard.type('Hello, World!');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// With delay between characters\ntry {\n  await sandbox.computerUse.keyboard.type('Slow typing', 100);\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n```\n\n***\n\n\n## Mouse\n\nMouse operations for computer use functionality\n\n### Constructors\n\n#### new Mouse()\n\n```ts\nnew Mouse(apiClient: ComputerUseApi): Mouse\n```\n\n**Parameters**:\n\n- `apiClient` _ComputerUseApi_\n\n\n**Returns**:\n\n- `Mouse`\n\n### Methods\n\n#### click()\n\n```ts\nclick(\n   x: number, \n   y: number, \n   button?: string, \ndouble?: boolean): Promise<MouseClickResponse>\n```\n\nClicks the mouse at the specified coordinates\n\n**Parameters**:\n\n- `x` _number_ - The x coordinate to click at\n- `y` _number_ - The y coordinate to click at\n- `button?` _string = 'left'_ - The mouse button to click ('left', 'right', 'middle')\n- `double?` _boolean = false_ - Whether to perform a double-click\n\n\n**Returns**:\n\n- `Promise<MouseClickResponse>` - Click operation result\n\n**Example:**\n\n```typescript\n// Single left click\nconst result = await sandbox.computerUse.mouse.click(100, 200);\n\n// Double click\nconst doubleClick = await sandbox.computerUse.mouse.click(100, 200, 'left', true);\n\n// Right click\nconst rightClick = await sandbox.computerUse.mouse.click(100, 200, 'right');\n```\n\n***\n\n#### drag()\n\n```ts\ndrag(\n   startX: number, \n   startY: number, \n   endX: number, \n   endY: number, \nbutton?: string): Promise<MouseDragResponse>\n```\n\nDrags the mouse from start coordinates to end coordinates\n\n**Parameters**:\n\n- `startX` _number_ - The starting x coordinate\n- `startY` _number_ - The starting y coordinate\n- `endX` _number_ - The ending x coordinate\n- `endY` _number_ - The ending y coordinate\n- `button?` _string = 'left'_ - The mouse button to use for dragging\n\n\n**Returns**:\n\n- `Promise<MouseDragResponse>` - Drag operation result\n\n**Example:**\n\n```typescript\nconst result = await sandbox.computerUse.mouse.drag(50, 50, 150, 150);\nconsole.log(`Dragged from ${result.from.x},${result.from.y} to ${result.to.x},${result.to.y}`);\n```\n\n***\n\n#### getPosition()\n\n```ts\ngetPosition(): Promise<MousePositionResponse>\n```\n\nGets the current mouse cursor position\n\n**Returns**:\n\n- `Promise<MousePositionResponse>` - Current mouse position with x and y coordinates\n\n**Example:**\n\n```typescript\nconst position = await sandbox.computerUse.mouse.getPosition();\nconsole.log(`Mouse is at: ${position.x}, ${position.y}`);\n```\n\n***\n\n#### move()\n\n```ts\nmove(x: number, y: number): Promise<MousePositionResponse>\n```\n\nMoves the mouse cursor to the specified coordinates\n\n**Parameters**:\n\n- `x` _number_ - The x coordinate to move to\n- `y` _number_ - The y coordinate to move to\n\n\n**Returns**:\n\n- `Promise<MousePositionResponse>` - Position after move\n\n**Example:**\n\n```typescript\nconst result = await sandbox.computerUse.mouse.move(100, 200);\nconsole.log(`Mouse moved to: ${result.x}, ${result.y}`);\n```\n\n***\n\n#### scroll()\n\n```ts\nscroll(\n   x: number, \n   y: number, \n   direction: \"up\" | \"down\", \namount?: number): Promise<boolean>\n```\n\nScrolls the mouse wheel at the specified coordinates\n\n**Parameters**:\n\n- `x` _number_ - The x coordinate to scroll at\n- `y` _number_ - The y coordinate to scroll at\n- `direction` _The direction to scroll_ - `\"up\"` | `\"down\"`\n- `amount?` _number = 1_ - The amount to scroll\n\n\n**Returns**:\n\n- `Promise<boolean>` - Whether the scroll operation was successful\n\n**Example:**\n\n```typescript\n// Scroll up\nconst scrollUp = await sandbox.computerUse.mouse.scroll(100, 200, 'up', 3);\n\n// Scroll down\nconst scrollDown = await sandbox.computerUse.mouse.scroll(100, 200, 'down', 5);\n```\n\n***\n\n\n## RecordingService\n\nRecording operations for computer use functionality.\n\n### Constructors\n\n#### new RecordingService()\n\n```ts\nnew RecordingService(apiClient: ComputerUseApi): RecordingService\n```\n\n**Parameters**:\n\n- `apiClient` _ComputerUseApi_\n\n\n**Returns**:\n\n- `RecordingService`\n\n### Methods\n\n#### delete()\n\n```ts\ndelete(id: string): Promise<void>\n```\n\nDeletes a recording by ID\n\n**Parameters**:\n\n- `id` _string_ - The ID of the recording to delete\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```typescript\nawait sandbox.computerUse.recording.delete(recordingId);\nconsole.log('Recording deleted');\n```\n\n***\n\n#### download()\n\n```ts\ndownload(id: string, localPath: string): Promise<void>\n```\n\nDownloads a recording file and saves it to a local path\n\nThe file is streamed directly to disk without loading the entire content into memory.\n\n**Parameters**:\n\n- `id` _string_ - The ID of the recording to download\n- `localPath` _string_ - Path to save the recording file locally\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```typescript\n// Download recording to file\nawait sandbox.computerUse.recording.download(recordingId, 'local_recording.mp4');\nconsole.log('Recording downloaded');\n```\n\n***\n\n#### get()\n\n```ts\nget(id: string): Promise<Recording>\n```\n\nGets details of a specific recording by ID\n\n**Parameters**:\n\n- `id` _string_ - The ID of the recording to retrieve\n\n\n**Returns**:\n\n- `Promise<Recording>` - Recording details\n\n**Example:**\n\n```typescript\nconst recording = await sandbox.computerUse.recording.get(recordingId);\nconsole.log(`Recording: ${recording.fileName}`);\nconsole.log(`Status: ${recording.status}`);\nconsole.log(`Duration: ${recording.durationSeconds} seconds`);\n```\n\n***\n\n#### list()\n\n```ts\nlist(): Promise<ListRecordingsResponse>\n```\n\nLists all recordings (active and completed)\n\n**Returns**:\n\n- `Promise<ListRecordingsResponse>` - List of all recordings\n\n**Example:**\n\n```typescript\nconst recordings = await sandbox.computerUse.recording.list();\nconsole.log(`Found ${recordings.recordings.length} recordings`);\nrecordings.recordings.forEach(rec => {\n  console.log(`- ${rec.fileName}: ${rec.status}`);\n});\n```\n\n***\n\n#### start()\n\n```ts\nstart(label?: string): Promise<Recording>\n```\n\nStarts a new screen recording session\n\n**Parameters**:\n\n- `label?` _string_ - Optional custom label for the recording\n\n\n**Returns**:\n\n- `Promise<Recording>` - Started recording details\n\n**Example:**\n\n```typescript\n// Start a recording with a label\nconst recording = await sandbox.computerUse.recording.start('my-test-recording');\nconsole.log(`Recording started: ${recording.id}`);\nconsole.log(`File: ${recording.filePath}`);\n```\n\n***\n\n#### stop()\n\n```ts\nstop(id: string): Promise<Recording>\n```\n\nStops an active screen recording session\n\n**Parameters**:\n\n- `id` _string_ - The ID of the recording to stop\n\n\n**Returns**:\n\n- `Promise<Recording>` - Stopped recording details\n\n**Example:**\n\n```typescript\nconst result = await sandbox.computerUse.recording.stop(recording.id);\nconsole.log(`Recording stopped: ${result.durationSeconds} seconds`);\nconsole.log(`Saved to: ${result.filePath}`);\n```\n\n***\n\n\n## Screenshot\n\nScreenshot operations for computer use functionality\n\n### Constructors\n\n#### new Screenshot()\n\n```ts\nnew Screenshot(apiClient: ComputerUseApi): Screenshot\n```\n\n**Parameters**:\n\n- `apiClient` _ComputerUseApi_\n\n\n**Returns**:\n\n- `Screenshot`\n\n### Methods\n\n#### takeCompressed()\n\n```ts\ntakeCompressed(options?: ScreenshotOptions): Promise<ScreenshotResponse>\n```\n\nTakes a compressed screenshot of the entire screen\n\n**Parameters**:\n\n- `options?` _ScreenshotOptions = {}_ - Compression and display options\n\n\n**Returns**:\n\n- `Promise<ScreenshotResponse>` - Compressed screenshot data\n\n**Example:**\n\n```typescript\n// Default compression\nconst screenshot = await sandbox.computerUse.screenshot.takeCompressed();\n\n// High quality JPEG\nconst jpeg = await sandbox.computerUse.screenshot.takeCompressed({\n  format: 'jpeg',\n  quality: 95,\n  showCursor: true\n});\n\n// Scaled down PNG\nconst scaled = await sandbox.computerUse.screenshot.takeCompressed({\n  format: 'png',\n  scale: 0.5\n});\n```\n\n***\n\n#### takeCompressedRegion()\n\n```ts\ntakeCompressedRegion(region: ScreenshotRegion, options?: ScreenshotOptions): Promise<ScreenshotResponse>\n```\n\nTakes a compressed screenshot of a specific region\n\n**Parameters**:\n\n- `region` _ScreenshotRegion_ - The region to capture\n- `options?` _ScreenshotOptions = {}_ - Compression and display options\n\n\n**Returns**:\n\n- `Promise<ScreenshotResponse>` - Compressed screenshot data\n\n**Example:**\n\n```typescript\nconst region = { x: 0, y: 0, width: 800, height: 600 };\nconst screenshot = await sandbox.computerUse.screenshot.takeCompressedRegion(region, {\n  format: 'webp',\n  quality: 80,\n  showCursor: true\n});\nconsole.log(`Compressed size: ${screenshot.size_bytes} bytes`);\n```\n\n***\n\n#### takeFullScreen()\n\n```ts\ntakeFullScreen(showCursor?: boolean): Promise<ScreenshotResponse>\n```\n\nTakes a screenshot of the entire screen\n\n**Parameters**:\n\n- `showCursor?` _boolean = false_ - Whether to show the cursor in the screenshot\n\n\n**Returns**:\n\n- `Promise<ScreenshotResponse>` - Screenshot data with base64 encoded image\n\n**Example:**\n\n```typescript\nconst screenshot = await sandbox.computerUse.screenshot.takeFullScreen();\nconsole.log(`Screenshot size: ${screenshot.width}x${screenshot.height}`);\n\n// With cursor visible\nconst withCursor = await sandbox.computerUse.screenshot.takeFullScreen(true);\n```\n\n***\n\n#### takeRegion()\n\n```ts\ntakeRegion(region: ScreenshotRegion, showCursor?: boolean): Promise<ScreenshotResponse>\n```\n\nTakes a screenshot of a specific region\n\n**Parameters**:\n\n- `region` _ScreenshotRegion_ - The region to capture\n- `showCursor?` _boolean = false_ - Whether to show the cursor in the screenshot\n\n\n**Returns**:\n\n- `Promise<ScreenshotResponse>` - Screenshot data with base64 encoded image\n\n**Example:**\n\n```typescript\nconst region = { x: 100, y: 100, width: 300, height: 200 };\nconst screenshot = await sandbox.computerUse.screenshot.takeRegion(region);\nconsole.log(`Captured region: ${screenshot.region.width}x${screenshot.region.height}`);\n```\n\n***\n\n\n## ScreenshotOptions\n\nInterface for screenshot compression options\n\n**Properties**:\n\n- `format?` _string_\n- `quality?` _number_\n- `scale?` _number_\n- `showCursor?` _boolean_\n## ScreenshotRegion\n\nInterface for region coordinates used in screenshot operations\n\n**Properties**:\n\n- `height` _number_\n- `width` _number_\n- `x` _number_\n- `y` _number_"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/daytona.mdx",
    "content": "---\ntitle: \"Daytona\"\nhideTitleOnPage: true\n---\n\n\n## Daytona\n\nMain class for interacting with the Daytona API.\nProvides methods for creating, managing, and interacting with Daytona Sandboxes.\nCan be initialized either with explicit configuration or using environment variables.\n\n**Properties**:\n\n- `snapshot` _SnapshotService_ - Service for managing Daytona Snapshots\n- `volume` _VolumeService_ - Service for managing Daytona Volumes\n    \n\n\n\n\n**Examples:**\n\n```ts\n// Using environment variables\n// Uses DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET\nconst daytona = new Daytona();\nconst sandbox = await daytona.create();\n```\n\n```ts\n// Using explicit configuration\nconst config: DaytonaConfig = {\n    apiKey: \"your-api-key\",\n    apiUrl: \"https://your-api.com\",\n    target: \"us\"\n};\nconst daytona = new Daytona(config);\n```\n\n```ts\n// Disposes daytona and flushes traces when done\nawait using daytona = new Daytona({\n  otelEnabled: true,\n});\n@class\n```\n\n### Implements\n\n- `AsyncDisposable`\n\n### Constructors\n\n#### new Daytona()\n\n```ts\nnew Daytona(config?: DaytonaConfig): Daytona\n```\n\nCreates a new Daytona client instance.\n\n**Parameters**:\n\n- `config?` _DaytonaConfig_ - Configuration options\n\n\n**Returns**:\n\n- `Daytona`\n\n**Throws**:\n\n- `DaytonaError` - When API key is missing\n\n### Methods\n\n#### \\[asyncDispose\\]()\n\n```ts\nasyncDispose: Promise<void>\n```\n\n**Returns**:\n\n- `Promise<void>`\n\n##### Implementation of\n\n```ts\nAsyncDisposable.[asyncDispose]\n```\n\n***\n\n#### create()\n\n##### Call Signature\n\n```ts\ncreate(params?: CreateSandboxFromSnapshotParams, options?: {\n  timeout: number;\n}): Promise<Sandbox>\n```\n\nCreates Sandboxes from specified or default snapshot. You can specify various parameters,\nincluding language, image, environment variables, and volumes.\n\n**Parameters**:\n\n- `params?` _CreateSandboxFromSnapshotParams_ - Parameters for Sandbox creation from snapshot\n- `options?` _Options for the create operation_\n- `timeout?` _number_ - Timeout in seconds (0 means no timeout, default is 60)\n\n**Returns**:\n\n- `Promise<Sandbox>` - The created Sandbox instance\n\n**Examples:**\n\n```ts\nconst sandbox = await daytona.create();\n```\n\n```ts\n// Create a custom sandbox\nconst params: CreateSandboxFromSnapshotParams = {\n    language: 'typescript',\n    snapshot: 'my-snapshot-id',\n    envVars: {\n        NODE_ENV: 'development',\n        DEBUG: 'true'\n    },\n    autoStopInterval: 60,\n    autoArchiveInterval: 60,\n    autoDeleteInterval: 120\n};\nconst sandbox = await daytona.create(params, { timeout: 100 });\n```\n\n##### Call Signature\n\n```ts\ncreate(params?: CreateSandboxFromImageParams, options?: {\n  onSnapshotCreateLogs: (chunk: string) => void;\n  timeout: number;\n}): Promise<Sandbox>\n```\n\nCreates Sandboxes from specified image available on some registry or declarative Daytona Image. You can specify various parameters,\nincluding resources, language, image, environment variables, and volumes. Daytona creates snapshot from\nprovided image and uses it to create Sandbox.\n\n**Parameters**:\n\n- `params?` _CreateSandboxFromImageParams_ - Parameters for Sandbox creation from image\n- `options?` _Options for the create operation_\n- `onSnapshotCreateLogs?` _\\(chunk: string\\) =\\> void_ - Callback function to handle snapshot creation logs.\n- `timeout?` _number_ - Timeout in seconds (0 means no timeout, default is 60)\n\n**Returns**:\n\n- `Promise<Sandbox>` - The created Sandbox instance\n\n**Examples:**\n\n```ts\nconst sandbox = await daytona.create({ image: 'debian:12.9' }, { timeout: 90, onSnapshotCreateLogs: console.log });\n```\n\n```ts\n// Create a custom sandbox\nconst image = Image.base('alpine:3.18').pipInstall('numpy');\nconst params: CreateSandboxFromImageParams = {\n    language: 'typescript',\n    image,\n    envVars: {\n        NODE_ENV: 'development',\n        DEBUG: 'true'\n    },\n    resources: {\n        cpu: 2,\n        memory: 4 // 4GB RAM\n    },\n    autoStopInterval: 60,\n    autoArchiveInterval: 60,\n    autoDeleteInterval: 120\n};\nconst sandbox = await daytona.create(params, { timeout: 100, onSnapshotCreateLogs: console.log });\n```\n\n***\n\n#### delete()\n\n```ts\ndelete(sandbox: Sandbox, timeout: number): Promise<void>\n```\n\nDeletes a Sandbox.\n\n**Parameters**:\n\n- `sandbox` _Sandbox_ - The Sandbox to delete\n- `timeout` _number = 60_ - Timeout in seconds (0 means no timeout, default is 60)\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\nawait daytona.delete(sandbox);\n```\n\n***\n\n#### get()\n\n```ts\nget(sandboxIdOrName: string): Promise<Sandbox>\n```\n\nGets a Sandbox by its ID or name.\n\n**Parameters**:\n\n- `sandboxIdOrName` _string_ - The ID or name of the Sandbox to retrieve\n\n\n**Returns**:\n\n- `Promise<Sandbox>` - The Sandbox\n\n**Example:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id-or-name');\nconsole.log(`Sandbox state: ${sandbox.state}`);\n```\n\n***\n\n#### list()\n\n```ts\nlist(\n   labels?: Record<string, string>, \n   page?: number, \nlimit?: number): Promise<PaginatedSandboxes>\n```\n\nReturns paginated list of Sandboxes filtered by labels.\n\n**Parameters**:\n\n- `labels?` _Record\\<string, string\\>_ - Labels to filter Sandboxes\n- `page?` _number_ - Page number for pagination (starting from 1)\n- `limit?` _number_ - Maximum number of items per page\n\n\n**Returns**:\n\n- `Promise<PaginatedSandboxes>` - Paginated list of Sandboxes that match the labels.\n\n**Example:**\n\n```ts\nconst result = await daytona.list({ 'my-label': 'my-value' }, 2, 10);\nfor (const sandbox of result.items) {\n    console.log(`${sandbox.id}: ${sandbox.state}`);\n}\n```\n\n***\n\n#### start()\n\n```ts\nstart(sandbox: Sandbox, timeout?: number): Promise<void>\n```\n\nStarts a Sandbox and waits for it to be ready.\n\n**Parameters**:\n\n- `sandbox` _Sandbox_ - The Sandbox to start\n- `timeout?` _number_ - Optional timeout in seconds (0 means no timeout)\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\n// Wait up to 60 seconds for the sandbox to start\nawait daytona.start(sandbox, 60);\n```\n\n***\n\n#### stop()\n\n```ts\nstop(sandbox: Sandbox): Promise<void>\n```\n\nStops a Sandbox.\n\n**Parameters**:\n\n- `sandbox` _Sandbox_ - The Sandbox to stop\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\nawait daytona.stop(sandbox);\n```\n## CodeLanguage\n\nSupported programming languages for code execution\n\nPython is used as the default sandbox language when no language is explicitly specified.\n\n**Enum Members**:\n\n- `JAVASCRIPT` (\"javascript\")\n- `PYTHON` (\"python\")\n- `TYPESCRIPT` (\"typescript\")\n\n## CreateSandboxBaseParams\n\nBase parameters for creating a new Sandbox.\n\n**Properties**:\n\n- `autoArchiveInterval?` _number_ - Auto-archive interval in minutes (0 means the maximum interval will be used). Default is 7 days.\n- `autoDeleteInterval?` _number_ - Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping). By default, auto-delete is disabled.\n- `autoStopInterval?` _number_ - Auto-stop interval in minutes (0 means disabled). Default is 15 minutes.\n- `envVars?` _Record\\<string, string\\>_ - Optional environment variables to set in the Sandbox\n- `ephemeral?` _boolean_ - Whether the Sandbox should be ephemeral. If true, autoDeleteInterval will be set to 0.\n- `labels?` _Record\\<string, string\\>_ - Sandbox labels\n- `language?` _string_ - Programming language for direct code execution. Defaults to \"python\" if not specified.\n- `name?` _string_\n- `networkAllowList?` _string_ - Comma-separated list of allowed CIDR network addresses for the Sandbox\n- `networkBlockAll?` _boolean_ - Whether to block all network access for the Sandbox\n- `public?` _boolean_ - Is the Sandbox port preview public\n- `user?` _string_ - Optional os user to use for the Sandbox\n- `volumes?` _VolumeMount\\[\\]_ - Optional array of volumes to mount to the Sandbox\n## CreateSandboxFromImageParams\n\nParameters for creating a new Sandbox.\n\n**Properties**:\n\n- `autoArchiveInterval?` _number_\n- `autoDeleteInterval?` _number_\n- `autoStopInterval?` _number_\n- `envVars?` _Record\\<string, string\\>_\n- `ephemeral?` _boolean_\n- `image` _string \\| Image_ - Custom Docker image to use for the Sandbox. If an Image object is provided,\n    the image will be dynamically built.\n- `labels?` _Record\\<string, string\\>_\n- `language?` _string_\n- `name?` _string_\n- `networkAllowList?` _string_\n- `networkBlockAll?` _boolean_\n- `public?` _boolean_\n- `resources?` _Resources_ - Resource allocation for the Sandbox. If not provided, sandbox will\n    have default resources.\n- `user?` _string_\n- `volumes?` _VolumeMount\\[\\]_\n## CreateSandboxFromSnapshotParams\n\nParameters for creating a new Sandbox from a snapshot.\n\n**Properties**:\n\n- `autoArchiveInterval?` _number_\n- `autoDeleteInterval?` _number_\n- `autoStopInterval?` _number_\n- `envVars?` _Record\\<string, string\\>_\n- `ephemeral?` _boolean_\n- `labels?` _Record\\<string, string\\>_\n- `language?` _string_\n- `name?` _string_\n- `networkAllowList?` _string_\n- `networkBlockAll?` _boolean_\n- `public?` _boolean_\n- `snapshot?` _string_ - Name of the snapshot to use for the Sandbox.\n- `user?` _string_\n- `volumes?` _VolumeMount\\[\\]_\n## DaytonaConfig\n\nConfiguration options for initializing the Daytona client.\n\n**Properties**:\n\n- `\\_experimental?` _Record\\<string, any\\>_ - Configuration for experimental features\n- `apiKey?` _string_ - API key for authentication with the Daytona API\n- `apiUrl?` _string_ - URL of the Daytona API. Defaults to 'https://app.daytona.io/api'\n    if not set here and not set in environment variable DAYTONA_API_URL.\n- `jwtToken?` _string_ - JWT token for authentication with the Daytona API. If not set, it must be provided\n    via the environment variable `DAYTONA_JWT_TOKEN`, or an API key must be provided instead.\n- `organizationId?` _string_ - Organization ID used for JWT-based authentication. Required if a JWT token\n    is provided, and must be set either here or in the environment variable `DAYTONA_ORGANIZATION_ID`.\n- ~~`serverUrl?`~~ _string_ - **_Deprecated_** - Use `apiUrl` instead. This property will be removed in future versions.\n- `target?` _string_ - Target location for Sandboxes\n    \n\n\n\n\n**Example:**\n\n```ts\nconst config: DaytonaConfig = {\n    apiKey: \"your-api-key\",\n    apiUrl: \"https://your-api.com\",\n    target: \"us\"\n};\nconst daytona = new Daytona(config);\n```\n## Resources\n\nResource allocation for a Sandbox.\n\n**Properties**:\n\n- `cpu?` _number_ - CPU allocation for the Sandbox in cores\n- `disk?` _number_ - Disk space allocation for the Sandbox in GiB\n- `gpu?` _number_ - GPU allocation for the Sandbox in units\n- `memory?` _number_ - Memory allocation for the Sandbox in GiB\n    \n\n\n\n\n**Example:**\n\n```ts\nconst resources: SandboxResources = {\n    cpu: 2,\n    memory: 4,  // 4GiB RAM\n    disk: 20    // 20GiB disk\n};\n```\n## VolumeMount\n\nRepresents a volume mount for a Sandbox.\n\n**Properties**:\n\n- `mountPath` _string_ - Path on the Sandbox to mount the Volume\n    \n- `subpath?` _string_ - Optional subpath within the volume to mount. When specified, only this S3 prefix will be accessible. When omitted, the entire volume is mounted.\n    - _Inherited from_: `SandboxVolume.subpath`\n- `volumeId` _string_ - ID of the Volume to mount\n    \n\n\n\n**Extends:**\n\n- `SandboxVolume`"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/errors.mdx",
    "content": "---\ntitle: \"Errors\"\nhideTitleOnPage: true\n---\n\n\n## DaytonaError\n\nBase error for Daytona SDK.\n\n**Properties**:\n\n- `headers?` _AxiosHeaders_ - Response headers if available\n- `statusCode?` _number_ - HTTP status code if available\n    \n\n\n\n\n**Extends:**\n\n- `Error`\n\n### Extended by\n\n- `DaytonaNotFoundError`\n- `DaytonaRateLimitError`\n- `DaytonaTimeoutError`\n\n### Constructors\n\n#### new DaytonaError()\n\n```ts\nnew DaytonaError(\n   message: string, \n   statusCode?: number, \n   headers?: AxiosHeaders): DaytonaError\n```\n\n**Parameters**:\n\n- `message` _string_\n- `statusCode?` _number_\n- `headers?` _AxiosHeaders_\n\n\n**Returns**:\n\n- `DaytonaError`\n\n##### Overrides\n\n```ts\nError.constructor\n```\n## DaytonaNotFoundError\n\nBase error for Daytona SDK.\n\n**Properties**:\n\n- `headers?` _AxiosHeaders_ - Response headers if available\n    - _Inherited from_: `DaytonaError.headers`\n- `statusCode?` _number_ - HTTP status code if available\n    \n    - _Inherited from_: `DaytonaError.statusCode`\n\n\n\n\n**Extends:**\n\n- `DaytonaError`\n\n### Constructors\n\n#### new DaytonaNotFoundError()\n\n```ts\nnew DaytonaNotFoundError(\n   message: string, \n   statusCode?: number, \n   headers?: AxiosHeaders): DaytonaNotFoundError\n```\n\n**Parameters**:\n\n- `message` _string_\n- `statusCode?` _number_\n- `headers?` _AxiosHeaders_\n\n\n**Returns**:\n\n- `DaytonaNotFoundError`\n\n##### Overrides\n\n`DaytonaError`.`constructor`\n## DaytonaRateLimitError\n\nError thrown when rate limit is exceeded.\n\n**Properties**:\n\n- `headers?` _AxiosHeaders_ - Response headers if available\n    - _Inherited from_: `DaytonaError.headers`\n- `statusCode?` _number_ - HTTP status code if available\n    \n    - _Inherited from_: `DaytonaError.statusCode`\n\n\n\n\n**Extends:**\n\n- `DaytonaError`\n\n### Constructors\n\n#### new DaytonaRateLimitError()\n\n```ts\nnew DaytonaRateLimitError(\n   message: string, \n   statusCode?: number, \n   headers?: AxiosHeaders): DaytonaRateLimitError\n```\n\n**Parameters**:\n\n- `message` _string_\n- `statusCode?` _number_\n- `headers?` _AxiosHeaders_\n\n\n**Returns**:\n\n- `DaytonaRateLimitError`\n\n##### Overrides\n\n`DaytonaError`.`constructor`\n## DaytonaTimeoutError\n\nError thrown when a timeout occurs.\n\n**Properties**:\n\n- `headers?` _AxiosHeaders_ - Response headers if available\n    - _Inherited from_: `DaytonaError.headers`\n- `statusCode?` _number_ - HTTP status code if available\n    - _Inherited from_: `DaytonaError.statusCode`\n\n\n\n**Extends:**\n\n- `DaytonaError`\n\n### Constructors\n\n#### new DaytonaTimeoutError()\n\n```ts\nnew DaytonaTimeoutError(\n   message: string, \n   statusCode?: number, \n   headers?: AxiosHeaders): DaytonaTimeoutError\n```\n\n**Parameters**:\n\n- `message` _string_\n- `statusCode?` _number_\n- `headers?` _AxiosHeaders_\n\n\n**Returns**:\n\n- `DaytonaTimeoutError`\n\n##### Overrides\n\n`DaytonaError`.`constructor`"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/execute-response.mdx",
    "content": "---\ntitle: \"ExecuteResponse\"\nhideTitleOnPage: true\n---\n\n\n## ExecuteResponse\n\nResponse from the command execution.\n\n**Properties**:\n\n- `artifacts?` _ExecutionArtifacts_ - Artifacts from the command execution\n- `exitCode` _number_ - The exit code from the command execution\n- `result` _string_ - The output from the command execution\n## ExecutionArtifacts\n\nArtifacts from the command execution.\n\n**Properties**:\n\n- `charts?` _Chart\\[\\]_ - List of chart metadata from matplotlib\n- `stdout` _string_ - Standard output from the command, same as `result` in `ExecuteResponse`"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/file-system.mdx",
    "content": "---\ntitle: \"FileSystem\"\nhideTitleOnPage: true\n---\n\n\n## FileSystem\n\nProvides file system operations within a Sandbox.\n\n### Constructors\n\n#### new FileSystem()\n\n```ts\nnew FileSystem(clientConfig: Configuration, apiClient: FileSystemApi): FileSystem\n```\n\n**Parameters**:\n\n- `clientConfig` _Configuration_\n- `apiClient` _FileSystemApi_\n\n\n**Returns**:\n\n- `FileSystem`\n\n### Methods\n\n#### createFolder()\n\n```ts\ncreateFolder(path: string, mode: string): Promise<void>\n```\n\nCreate a new directory in the Sandbox with specified permissions.\n\n**Parameters**:\n\n- `path` _string_ - Path where the directory should be created. Relative paths are resolved based on the sandbox working directory.\n- `mode` _string_ - Directory permissions in octal format (e.g. \"755\")\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Create a directory with standard permissions\nawait fs.createFolder('app/data', '755');\n```\n\n***\n\n#### deleteFile()\n\n```ts\ndeleteFile(path: string, recursive?: boolean): Promise<void>\n```\n\nDeletes a file or directory from the Sandbox.\n\n**Parameters**:\n\n- `path` _string_ - Path to the file or directory to delete. Relative paths are resolved based on the sandbox working directory.\n- `recursive?` _boolean_ - If the file is a directory, this must be true to delete it.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Delete a file\nawait fs.deleteFile('app/temp.log');\n```\n\n***\n\n#### downloadFile()\n\n##### Call Signature\n\n```ts\ndownloadFile(remotePath: string, timeout?: number): Promise<Buffer<ArrayBufferLike>>\n```\n\nDownloads a file from the Sandbox. This method loads the entire file into memory, so it is not recommended\nfor downloading large files.\n\n**Parameters**:\n\n- `remotePath` _string_ - Path to the file to download. Relative paths are resolved based on the sandbox working directory.\n- `timeout?` _number_ - Timeout for the download operation in seconds. 0 means no timeout.\n    Default is 30 minutes.\n\n**Returns**:\n\n- `Promise<Buffer<ArrayBufferLike>>` - The file contents as a Buffer.\n\n**Example:**\n\n```ts\n// Download and process a file\nconst fileBuffer = await fs.downloadFile('tmp/data.json');\nconsole.log('File content:', fileBuffer.toString());\n```\n\n##### Call Signature\n\n```ts\ndownloadFile(\n   remotePath: string, \n   localPath: string, \ntimeout?: number): Promise<void>\n```\n\nDownloads a file from the Sandbox and saves it to a local file. This method uses streaming to download the file,\nso it is recommended for downloading larger files.\n\n**Parameters**:\n\n- `remotePath` _string_ - Path to the file to download in the Sandbox. Relative paths are resolved based on the sandbox working directory.\n- `localPath` _string_ - Path to save the downloaded file.\n- `timeout?` _number_ - Timeout for the download operation in seconds. 0 means no timeout.\n    Default is 30 minutes.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Download and save a file\nawait fs.downloadFile('tmp/data.json', 'local_file.json');\n```\n\n***\n\n#### downloadFiles()\n\n```ts\ndownloadFiles(files: FileDownloadRequest[], timeoutSec?: number): Promise<FileDownloadResponse[]>\n```\n\nDownloads multiple files from the Sandbox. If the files already exist locally, they will be overwritten.\n\n**Parameters**:\n\n- `files` _FileDownloadRequest\\[\\]_ - Array of file download requests.\n- `timeoutSec?` _number = ..._ - Timeout for the download operation in seconds. 0 means no timeout.\n    Default is 30 minutes.\n\n\n**Returns**:\n\n- `Promise<FileDownloadResponse[]>` - Array of download results.\n\n**Throws**:\n\nIf the request itself fails (network issues, invalid request/response, etc.). Individual\nfile download errors are returned in the `FileDownloadResponse.error` field.\n\n**Example:**\n\n```ts\n// Download multiple files\nconst results = await fs.downloadFiles([\n  { source: 'tmp/data.json' },\n  { source: 'tmp/config.json', destination: 'local_config.json' }\n]);\nresults.forEach(result => {\n  if (result.error) {\n    console.error(`Error downloading ${result.source}: ${result.error}`);\n  } else if (result.result) {\n    console.log(`Downloaded ${result.source} to ${result.result}`);\n  }\n});\n```\n\n***\n\n#### findFiles()\n\n```ts\nfindFiles(path: string, pattern: string): Promise<Match[]>\n```\n\nSearches for text patterns within files in the Sandbox.\n\n**Parameters**:\n\n- `path` _string_ - Directory to search in. Relative paths are resolved based on the sandbox working directory.\n- `pattern` _string_ - Search pattern\n\n\n**Returns**:\n\n- `Promise<Match[]>` - Array of matches with file and line information\n\n**Example:**\n\n```ts\n// Find all TODO comments in TypeScript files\nconst matches = await fs.findFiles('app/src', 'TODO:');\nmatches.forEach(match => {\n  console.log(`${match.file}:${match.line}: ${match.content}`);\n});\n```\n\n***\n\n#### getFileDetails()\n\n```ts\ngetFileDetails(path: string): Promise<FileInfo>\n```\n\nRetrieves detailed information about a file or directory.\n\n**Parameters**:\n\n- `path` _string_ - Path to the file or directory. Relative paths are resolved based on the sandbox working directory.\n\n\n**Returns**:\n\n- `Promise<FileInfo>` - Detailed file information including size, permissions, modification time\n\n**Example:**\n\n```ts\n// Get file details\nconst info = await fs.getFileDetails('app/config.json');\nconsole.log(`Size: ${info.size}, Modified: ${info.modTime}`);\n```\n\n***\n\n#### listFiles()\n\n```ts\nlistFiles(path: string): Promise<FileInfo[]>\n```\n\nLists contents of a directory in the Sandbox.\n\n**Parameters**:\n\n- `path` _string_ - Directory path to list. Relative paths are resolved based on the sandbox working directory.\n\n\n**Returns**:\n\n- `Promise<FileInfo[]>` - Array of file and directory information\n\n**Example:**\n\n```ts\n// List directory contents\nconst files = await fs.listFiles('app/src');\nfiles.forEach(file => {\n  console.log(`${file.name} (${file.size} bytes)`);\n});\n```\n\n***\n\n#### moveFiles()\n\n```ts\nmoveFiles(source: string, destination: string): Promise<void>\n```\n\nMoves or renames a file or directory.\n\n**Parameters**:\n\n- `source` _string_ - Source path. Relative paths are resolved based on the sandbox working directory.\n- `destination` _string_ - Destination path. Relative paths are resolved based on the sandbox working directory.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Move a file to a new location\nawait fs.moveFiles('app/temp/data.json', 'app/data/data.json');\n```\n\n***\n\n#### replaceInFiles()\n\n```ts\nreplaceInFiles(\n   files: string[], \n   pattern: string, \nnewValue: string): Promise<ReplaceResult[]>\n```\n\nReplaces text content in multiple files.\n\n**Parameters**:\n\n- `files` _string\\[\\]_ - Array of file paths to process. Relative paths are resolved based on the sandbox working directory.\n- `pattern` _string_ - Pattern to replace\n- `newValue` _string_ - Replacement text\n\n\n**Returns**:\n\n- `Promise<ReplaceResult[]>` - Results of the replace operation for each file\n\n**Example:**\n\n```ts\n// Update version number across multiple files\nconst results = await fs.replaceInFiles(\n  ['app/package.json', 'app/version.ts'],\n  '\"version\": \"1.0.0\"',\n  '\"version\": \"1.1.0\"'\n);\n```\n\n***\n\n#### searchFiles()\n\n```ts\nsearchFiles(path: string, pattern: string): Promise<SearchFilesResponse>\n```\n\nSearches for files and directories by name pattern in the Sandbox.\n\n**Parameters**:\n\n- `path` _string_ - Directory to search in. Relative paths are resolved based on the sandbox working directory.\n- `pattern` _string_ - File name pattern (supports globs)\n\n\n**Returns**:\n\n- `Promise<SearchFilesResponse>` - Search results with matching files\n\n**Example:**\n\n```ts\n// Find all TypeScript files\nconst result = await fs.searchFiles('app', '*.ts');\nresult.files.forEach(file => console.log(file));\n```\n\n***\n\n#### setFilePermissions()\n\n```ts\nsetFilePermissions(path: string, permissions: FilePermissionsParams): Promise<void>\n```\n\nSets permissions and ownership for a file or directory.\n\n**Parameters**:\n\n- `path` _string_ - Path to the file or directory. Relative paths are resolved based on the sandbox working directory.\n- `permissions` _FilePermissionsParams_ - Permission settings\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Set file permissions and ownership\nawait fs.setFilePermissions('app/script.sh', {\n  owner: 'daytona',\n  group: 'users',\n  mode: '755'  // Execute permission for shell script\n});\n```\n\n***\n\n#### uploadFile()\n\n##### Call Signature\n\n```ts\nuploadFile(\n   file: Buffer, \n   remotePath: string, \ntimeout?: number): Promise<void>\n```\n\nUploads a file to the Sandbox. This method loads the entire file into memory, so it is not recommended\nfor uploading large files.\n\n**Parameters**:\n\n- `file` _Buffer_ - Buffer of the file to upload.\n- `remotePath` _string_ - Destination path in the Sandbox. Relative paths are resolved based on the sandbox working directory.\n- `timeout?` _number_ - Timeout for the upload operation in seconds. 0 means no timeout.\n    Default is 30 minutes.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Upload a configuration file\nawait fs.uploadFile(Buffer.from('{\"setting\": \"value\"}'), 'tmp/config.json');\n```\n\n##### Call Signature\n\n```ts\nuploadFile(\n   localPath: string, \n   remotePath: string, \ntimeout?: number): Promise<void>\n```\n\nUploads a file from the local file system to the Sandbox. This method uses streaming to upload the file,\nso it is recommended for uploading larger files.\n\n**Parameters**:\n\n- `localPath` _string_ - Path to the local file to upload.\n- `remotePath` _string_ - Destination path in the Sandbox. Relative paths are resolved based on the sandbox working directory.\n- `timeout?` _number_ - Timeout for the upload operation in seconds. 0 means no timeout.\n    Default is 30 minutes.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Upload a local file\nawait fs.uploadFile('local_file.txt', 'tmp/file.txt');\n```\n\n***\n\n#### uploadFiles()\n\n```ts\nuploadFiles(files: FileUpload[], timeout?: number): Promise<void>\n```\n\nUploads multiple files to the Sandbox. If files already exist at the destination paths,\nthey will be overwritten.\n\n**Parameters**:\n\n- `files` _FileUpload\\[\\]_ - Array of files to upload.\n- `timeout?` _number = ..._ - Timeout for the upload operation in seconds. 0 means no timeout.\n    Default is 30 minutes.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Upload multiple text files\nconst files = [\n  {\n    source: Buffer.from('Content of file 1'),\n    destination: '/tmp/file1.txt'\n  },\n  {\n    source: 'app/data/file2.txt',\n    destination: '/tmp/file2.txt'\n  },\n  {\n    source: Buffer.from('{\"key\": \"value\"}'),\n    destination: '/tmp/config.json'\n  }\n];\nawait fs.uploadFiles(files);\n```\n\n***\n\n\n## DownloadMetadata\n\nRepresents metadata for a file download operation.\n\n**Properties**:\n\n- `destination?` _string_ - Destination path in the local filesystem where the file content will be streamed to.\n- `error?` _string_ - Error message if the download failed, undefined if successful.\n- `result?` _string \\| Buffer\\<ArrayBufferLike\\> \\| Uint8Array\\<ArrayBufferLike\\>_ - The download result - file path (if destination provided in the request)\n    or bytes content (if no destination in the request), undefined if failed or no data received.\n## FileDownloadRequest\n\nRepresents a request to download a single file from the Sandbox.\n\n**Properties**:\n\n- `destination?` _string_ - Destination path in the local filesystem where the file content will be\n    streamed to. If not provided, the file will be downloaded in the bytes buffer (might cause memory issues if the file is large).\n- `source` _string_ - Source path in the Sandbox. Relative paths are resolved based on the user's\n    root directory.\n## FileDownloadResponse\n\nRepresents the response to a single file download request.\n\n**Properties**:\n\n- `error?` _string_ - Error message if the download failed, undefined if successful.\n- `result?` _string \\| Buffer\\<ArrayBufferLike\\>_ - The download result - file path (if destination provided in the request)\n    or bytes content (if no destination in the request), undefined if failed or no data received.\n- `source` _string_ - The original source path requested for download.\n## FilePermissionsParams\n\nParameters for setting file permissions in the Sandbox.\n\n**Properties**:\n\n- `group?` _string_ - Group owner of the file\n- `mode?` _string_ - File mode/permissions in octal format (e.g. \"644\")\n- `owner?` _string_ - User owner of the file\n    \n\n\n\n\n**Example:**\n\n```ts\nconst permissions: FilePermissionsParams = {\n  mode: '644',\n  owner: 'daytona',\n  group: 'users'\n};\n```\n## FileUpload\n\nRepresents a file to be uploaded to the Sandbox.\n\n**Properties**:\n\n- `destination` _string_ - Absolute destination path in the Sandbox. Relative paths are resolved based on the sandbox working directory.\n- `source` _string \\| Buffer\\<ArrayBufferLike\\>_ - File to upload. If a Buffer, it is interpreted as the file content which is loaded into memory.\n    Make sure it fits into memory, otherwise use the local file path which content will be streamed to the Sandbox."
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/git.mdx",
    "content": "---\ntitle: \"Git\"\nhideTitleOnPage: true\n---\n\n\n## Git\n\nProvides Git operations within a Sandbox.\n\n### Constructors\n\n#### new Git()\n\n```ts\nnew Git(apiClient: GitApi): Git\n```\n\n**Parameters**:\n\n- `apiClient` _GitApi_\n\n\n**Returns**:\n\n- `Git`\n\n### Methods\n\n#### add()\n\n```ts\nadd(path: string, files: string[]): Promise<void>\n```\n\nStages the specified files for the next commit, similar to\nrunning 'git add' on the command line.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n- `files` _string\\[\\]_ - List of file paths or directories to stage, relative to the repository root\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Examples:**\n\n```ts\n// Stage a single file\nawait git.add('workspace/repo', ['file.txt']);\n```\n\n```ts\n// Stage whole repository\nawait git.add('workspace/repo', ['.']);\n```\n\n***\n\n#### branches()\n\n```ts\nbranches(path: string): Promise<ListBranchResponse>\n```\n\nList branches in the repository.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n\n\n**Returns**:\n\n- `Promise<ListBranchResponse>` - List of branches in the repository\n\n**Example:**\n\n```ts\nconst response = await git.branches('workspace/repo');\nconsole.log(`Branches: ${response.branches}`);\n```\n\n***\n\n#### checkoutBranch()\n\n```ts\ncheckoutBranch(path: string, branch: string): Promise<void>\n```\n\nCheckout branche in the repository.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n- `branch` _string_ - Name of the branch to checkout\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nawait git.checkoutBranch('workspace/repo', 'new-feature');\n```\n\n***\n\n#### clone()\n\n```ts\nclone(\n   url: string, \n   path: string, \n   branch?: string, \n   commitId?: string, \n   username?: string, \npassword?: string): Promise<void>\n```\n\nClones a Git repository into the specified path. It supports\ncloning specific branches or commits, and can authenticate with the remote\nrepository if credentials are provided.\n\n**Parameters**:\n\n- `url` _string_ - Repository URL to clone from\n- `path` _string_ - Path where the repository should be cloned. Relative paths are resolved based on the sandbox working directory.\n- `branch?` _string_ - Specific branch to clone. If not specified, clones the default branch\n- `commitId?` _string_ - Specific commit to clone. If specified, the repository will be left in a detached HEAD state at this commit\n- `username?` _string_ - Git username for authentication\n- `password?` _string_ - Git password or token for authentication\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Examples:**\n\n```ts\n// Clone the default branch\nawait git.clone(\n  'https://github.com/user/repo.git',\n  'workspace/repo'\n);\n```\n\n```ts\n// Clone a specific branch with authentication\nawait git.clone(\n  'https://github.com/user/private-repo.git',\n  'workspace/private',\n  branch='develop',\n  username='user',\n  password='token'\n);\n```\n\n```ts\n// Clone a specific commit\nawait git.clone(\n  'https://github.com/user/repo.git',\n  'workspace/repo-old',\n  commitId='abc123'\n);\n```\n\n***\n\n#### commit()\n\n```ts\ncommit(\n   path: string, \n   message: string, \n   author: string, \n   email: string, \nallowEmpty?: boolean): Promise<GitCommitResponse>\n```\n\nCommits staged changes.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n- `message` _string_ - Commit message describing the changes\n- `author` _string_ - Name of the commit author\n- `email` _string_ - Email address of the commit author\n- `allowEmpty?` _boolean_ - Allow creating an empty commit when no changes are staged\n\n\n**Returns**:\n\n- `Promise<GitCommitResponse>`\n\n**Example:**\n\n```ts\n// Stage and commit changes\nawait git.add('workspace/repo', ['README.md']);\nawait git.commit(\n  'workspace/repo',\n  'Update documentation',\n  'John Doe',\n  'john@example.com',\n  true\n);\n```\n\n***\n\n#### createBranch()\n\n```ts\ncreateBranch(path: string, name: string): Promise<void>\n```\n\nCreate branch in the repository.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n- `name` _string_ - Name of the new branch to create\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nawait git.createBranch('workspace/repo', 'new-feature');\n```\n\n***\n\n#### deleteBranch()\n\n```ts\ndeleteBranch(path: string, name: string): Promise<void>\n```\n\nDelete branche in the repository.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n- `name` _string_ - Name of the branch to delete\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nawait git.deleteBranch('workspace/repo', 'new-feature');\n```\n\n***\n\n#### pull()\n\n```ts\npull(\n   path: string, \n   username?: string, \npassword?: string): Promise<void>\n```\n\nPulls changes from the remote repository.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n- `username?` _string_ - Git username for authentication\n- `password?` _string_ - Git password or token for authentication\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Examples:**\n\n```ts\n// Pull from a public repository\nawait git.pull('workspace/repo');\n```\n\n```ts\n// Pull from a private repository\nawait git.pull(\n  'workspace/repo',\n  'user',\n  'token'\n);\n```\n\n***\n\n#### push()\n\n```ts\npush(\n   path: string, \n   username?: string, \npassword?: string): Promise<void>\n```\n\nPush local changes to the remote repository.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n- `username?` _string_ - Git username for authentication\n- `password?` _string_ - Git password or token for authentication\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Examples:**\n\n```ts\n// Push to a public repository\nawait git.push('workspace/repo');\n```\n\n```ts\n// Push to a private repository\nawait git.push(\n  'workspace/repo',\n  'user',\n  'token'\n);\n```\n\n***\n\n#### status()\n\n```ts\nstatus(path: string): Promise<GitStatus>\n```\n\nGets the current status of the Git repository.\n\n**Parameters**:\n\n- `path` _string_ - Path to the Git repository root. Relative paths are resolved based on the sandbox working directory.\n\n\n**Returns**:\n\n- `Promise<GitStatus>` - Current repository status including:\n    - currentBranch: Name of the current branch\n    - ahead: Number of commits ahead of the remote branch\n    - behind: Number of commits behind the remote branch\n    - branchPublished: Whether the branch has been published to the remote repository\n    - fileStatus: List of file statuses\n\n**Example:**\n\n```ts\nconst status = await sandbox.git.status('workspace/repo');\nconsole.log(`Current branch: ${status.currentBranch}`);\nconsole.log(`Commits ahead: ${status.ahead}`);\nconsole.log(`Commits behind: ${status.behind}`);\n```\n\n***\n\n\n## GitCommitResponse\n\nResponse from the git commit.\n\n**Properties**:\n\n- `sha` _string_ - The SHA of the commit"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/image.mdx",
    "content": "---\ntitle: \"Image\"\nhideTitleOnPage: true\n---\n\n\n## Image\n\nRepresents an image definition for a Daytona sandbox.\nDo not construct this class directly. Instead use one of its static factory methods,\nsuch as `Image.base()`, `Image.debianSlim()` or `Image.fromDockerfile()`.\n\n### Accessors\n\n#### contextList\n\n##### Get Signature\n\n```ts\nget contextList(): Context[]\n```\n\n###### Returns\n\n`Context`[]\n\nThe list of context files to be added to the image.\n\n***\n\n#### dockerfile\n\n##### Get Signature\n\n```ts\nget dockerfile(): string\n```\n\n**Returns**:\n\n- `string` - The Dockerfile content.\n\n### Methods\n\n#### base()\n\n```ts\nstatic base(image: string): Image\n```\n\nCreates an Image from an existing base image.\n\n**Parameters**:\n\n- `image` _string_ - The base image to use.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image.base('python:3.12-slim-bookworm')\n```\n\n***\n\n#### debianSlim()\n\n```ts\nstatic debianSlim(pythonVersion?: \"3.9\" | \"3.10\" | \"3.11\" | \"3.12\" | \"3.13\"): Image\n```\n\nCreates a Debian slim image based on the official Python Docker image.\n\n**Parameters**:\n\n- `pythonVersion?` _The Python version to use._ - `\"3.9\"` | `\"3.10\"` | `\"3.11\"` | `\"3.12\"` | `\"3.13\"`\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image.debianSlim('3.12')\n```\n\n***\n\n#### fromDockerfile()\n\n```ts\nstatic fromDockerfile(path: string): Image\n```\n\nCreates an Image from an existing Dockerfile.\n\n**Parameters**:\n\n- `path` _string_ - The path to the Dockerfile.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image.fromDockerfile('Dockerfile')\n```\n\n***\n\n#### addLocalDir()\n\n```ts\naddLocalDir(localPath: string, remotePath: string): Image\n```\n\nAdds a local directory to the image.\n\n**Parameters**:\n\n- `localPath` _string_ - The path to the local directory.\n- `remotePath` _string_ - The path of the directory in the image.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .addLocalDir('src', '/home/daytona/src')\n```\n\n***\n\n#### addLocalFile()\n\n```ts\naddLocalFile(localPath: string, remotePath: string): Image\n```\n\nAdds a local file to the image.\n\n**Parameters**:\n\n- `localPath` _string_ - The path to the local file.\n- `remotePath` _string_ - The path of the file in the image.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .addLocalFile('requirements.txt', '/home/daytona/requirements.txt')\n```\n\n***\n\n#### cmd()\n\n```ts\ncmd(cmd: string[]): Image\n```\n\nSets the default command for the image.\n\n**Parameters**:\n\n- `cmd` _string\\[\\]_ - The command to set as the default command.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .cmd(['/bin/bash'])\n```\n\n***\n\n#### dockerfileCommands()\n\n```ts\ndockerfileCommands(dockerfileCommands: string[], contextDir?: string): Image\n```\n\nExtends an image with arbitrary Dockerfile-like commands.\n\n**Parameters**:\n\n- `dockerfileCommands` _string\\[\\]_ - The commands to add to the Dockerfile.\n- `contextDir?` _string_ - The path to the context directory.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .dockerfileCommands(['RUN echo \"Hello, world!\"'])\n```\n\n***\n\n#### entrypoint()\n\n```ts\nentrypoint(entrypointCommands: string[]): Image\n```\n\nSets the entrypoint for the image.\n\n**Parameters**:\n\n- `entrypointCommands` _string\\[\\]_ - The commands to set as the entrypoint.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .entrypoint(['/bin/bash'])\n```\n\n***\n\n#### env()\n\n```ts\nenv(envVars: Record<string, string>): Image\n```\n\nSets environment variables in the image.\n\n**Parameters**:\n\n- `envVars` _Record\\<string, string\\>_ - The environment variables to set.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .env({ FOO: 'bar' })\n```\n\n***\n\n#### pipInstall()\n\n```ts\npipInstall(packages: string | string[], options?: PipInstallOptions): Image\n```\n\nAdds commands to install packages using pip.\n\n**Parameters**:\n\n- `packages` _The packages to install._ - `string` | `string`[]\n- `options?` _PipInstallOptions_ - The options for the pip install command.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image.debianSlim('3.12').pipInstall('numpy', { findLinks: ['https://pypi.org/simple'] })\n```\n\n***\n\n#### pipInstallFromPyproject()\n\n```ts\npipInstallFromPyproject(pyprojectToml: string, options?: PyprojectOptions): Image\n```\n\nInstalls dependencies from a pyproject.toml file.\n\n**Parameters**:\n\n- `pyprojectToml` _string_ - The path to the pyproject.toml file.\n- `options?` _PyprojectOptions_ - The options for the pip install command.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image.debianSlim('3.12')\nimage.pipInstallFromPyproject('pyproject.toml', { optionalDependencies: ['dev'] })\n```\n\n***\n\n#### pipInstallFromRequirements()\n\n```ts\npipInstallFromRequirements(requirementsTxt: string, options?: PipInstallOptions): Image\n```\n\nInstalls dependencies from a requirements.txt file.\n\n**Parameters**:\n\n- `requirementsTxt` _string_ - The path to the requirements.txt file.\n- `options?` _PipInstallOptions_ - The options for the pip install command.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image.debianSlim('3.12')\nimage.pipInstallFromRequirements('requirements.txt', { findLinks: ['https://pypi.org/simple'] })\n```\n\n***\n\n#### runCommands()\n\n```ts\nrunCommands(...commands: (string | string[])[]): Image\n```\n\nRuns commands in the image.\n\n**Parameters**:\n\n- `commands` _...\\(string \\| string\\[\\]\\)\\[\\]_ - The commands to run.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .runCommands(\n   'echo \"Hello, world!\"',\n   ['bash', '-c', 'echo Hello, world, again!']\n )\n```\n\n***\n\n#### workdir()\n\n```ts\nworkdir(dirPath: string): Image\n```\n\nSets the working directory in the image.\n\n**Parameters**:\n\n- `dirPath` _string_ - The path to the working directory.\n\n\n**Returns**:\n\n- `Image` - The Image instance.\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .workdir('/home/daytona')\n```\n\n***\n\n\n## Context\n\nRepresents a context file to be added to the image.\n\n**Properties**:\n\n- `archivePath` _string_ - The path inside the archive file in object storage.\n- `sourcePath` _string_ - The path to the source file or directory.\n## PipInstallOptions\n\nOptions for the pip install command.\n\n**Properties**:\n\n- `extraIndexUrls?` _string\\[\\]_ - The extra index URLs to use for the pip install command.\n- `extraOptions?` _string_ - The extra options to use for the pip install command. Given string is passed directly to the pip install command.\n- `findLinks?` _string\\[\\]_ - The find-links to use for the pip install command.\n- `indexUrl?` _string_ - The index URL to use for the pip install command.\n- `pre?` _boolean_ - Whether to install pre-release versions.\n    \n\n\n\n\n### Extended by\n\n- `PyprojectOptions`\n## PyprojectOptions\n\nOptions for the pip install command from a pyproject.toml file.\n\n**Properties**:\n\n- `extraIndexUrls?` _string\\[\\]_ - The extra index URLs to use for the pip install command.\n    - _Inherited from_: `PipInstallOptions.extraIndexUrls`\n- `extraOptions?` _string_ - The extra options to use for the pip install command. Given string is passed directly to the pip install command.\n    - _Inherited from_: `PipInstallOptions.extraOptions`\n- `findLinks?` _string\\[\\]_ - The find-links to use for the pip install command.\n    - _Inherited from_: `PipInstallOptions.findLinks`\n- `indexUrl?` _string_ - The index URL to use for the pip install command.\n    - _Inherited from_: `PipInstallOptions.indexUrl`\n- `optionalDependencies?` _string\\[\\]_ - The optional dependencies to install.\n- `pre?` _boolean_ - Whether to install pre-release versions.\n    - _Inherited from_: `PipInstallOptions.pre`\n\n\n\n**Extends:**\n\n- `PipInstallOptions`"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/index.mdx",
    "content": "---\ntitle: TypeScript SDK Reference\ndescription: Interact with Daytona Sandboxes using the TypeScript SDK\nnext: /docs/typescript-sdk/daytona\n---\n\nThe Daytona TypeScript SDK provides a powerful interface for programmatically interacting with Daytona Sandboxes.\n\n## Installation\n\nInstall the Daytona TypeScript SDK using npm:\n\n```bash\nnpm install @daytonaio/sdk\n```\n\nOr using yarn:\n\n```bash\nyarn add @daytonaio/sdk\n```\n\n## Getting Started\n\n### Create a Sandbox\n\nCreate a Daytona Sandbox to run your code securely in an isolated environment. The following snippet is an example “Hello World” program that runs securely inside a Daytona Sandbox.\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  // Initialize the SDK (uses environment variables by default)\n  const daytona = new Daytona()\n\n  // Create a new sandbox\n  const sandbox = await daytona.create({\n    language: 'typescript',\n    envVars: { NODE_ENV: 'development' },\n  })\n\n  // Execute a command\n  const response = await sandbox.process.executeCommand('echo \"Hello, World!\"')\n  console.log(response.result)\n}\n\nmain().catch(console.error)\n```\n\n## Configuration\n\nThe Daytona SDK can be configured using environment variables or by passing options to the constructor:\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\n// Using environment variables (DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET)\nconst daytona = new Daytona();\n\n// Using explicit configuration\nconst daytona = new Daytona({\n  apiKey: 'YOUR_API_KEY',\n  apiUrl: 'https://app.daytona.io/api',\n  target: 'us'\n});\n```\n\nFor more information on configuring the Daytona SDK, see [configuration](/docs/en/configuration).\n\n## Multiple runtime support\n\nDaytona supports multiple programming language runtimes for direct code execution inside the sandbox.\n\n[TypeScript SDK](/docs/en/typescript-sdk) works across multiple **JavaScript runtimes** including **Node.js**, **browsers**, and **serverless platforms**: Cloudflare Workers, AWS Lambda, Azure Functions, etc.\n\nUsing the Daytona SDK in browser-based environments or frameworks like [**Vite**](/docs/en/getting-started#daytona-in-vite-projects) and [**Next.js**](/docs/en/getting-started#daytona-in-nextjs-projects) requires configuring node polyfills.\n\n### Daytona in Vite projects\n\nWhen using Daytona SDK in a Vite-based project, configure node polyfills to ensure compatibility.\n\nAdd the following configuration to your `vite.config.ts` file in the `plugins` array:\n\n```typescript\nimport { nodePolyfills } from 'vite-plugin-node-polyfills'\n\nexport default defineConfig({\n  plugins: [\n    // ... other plugins\n    nodePolyfills({\n      globals: { global: true, process: true, Buffer: true },\n      overrides: {\n        path: 'path-browserify-win32',\n      },\n    }),\n  ],\n  // ... rest of your config\n})\n```\n\n### Daytona in Next.js projects\n\nWhen using Daytona SDK in a Next.js project, configure node polyfills to ensure compatibility with Webpack and Turbopack bundlers.\n\nAdd the following configuration to your `next.config.ts` file:\n\n```typescript\nimport type { NextConfig } from 'next'\nimport NodePolyfillPlugin from 'node-polyfill-webpack-plugin'\nimport { env, nodeless } from 'unenv'\n\nconst { alias: turbopackAlias } = env(nodeless, {})\n\nconst nextConfig: NextConfig = {\n  // Turbopack\n  experimental: {\n    turbo: {\n      resolveAlias: {\n        ...turbopackAlias,\n      },\n    },\n  },\n  // Webpack\n  webpack: (config, { isServer }) => {\n    if (!isServer) {\n      config.plugins.push(new NodePolyfillPlugin())\n    }\n    return config\n  },\n}\n\nexport default nextConfig\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/lsp-server.mdx",
    "content": "---\ntitle: \"LspServer\"\nhideTitleOnPage: true\n---\n\n\n## LspServer\n\nProvides Language Server Protocol functionality for code intelligence to provide\nIDE-like features such as code completion, symbol search, and more.\n\n### Constructors\n\n#### new LspServer()\n\n```ts\nnew LspServer(\n   languageId: LspLanguageId, \n   pathToProject: string, \n   apiClient: LspApi): LspServer\n```\n\n**Parameters**:\n\n- `languageId` _LspLanguageId_\n- `pathToProject` _string_\n- `apiClient` _LspApi_\n\n\n**Returns**:\n\n- `LspServer`\n\n### Methods\n\n#### completions()\n\n```ts\ncompletions(path: string, position: Position): Promise<CompletionList>\n```\n\nGets completion suggestions at a position in a file.\n\n**Parameters**:\n\n- `path` _string_ - Path to the file. Relative paths are resolved based on the project path\n    set in the LSP server constructor.\n- `position` _Position_ - The position in the file where completion was requested\n\n\n**Returns**:\n\n- `Promise<CompletionList>` - List of completion suggestions. The list includes:\n    - isIncomplete: Whether more items might be available\n    - items: List of completion items, each containing:\n    - label: The text to insert\n    - kind: The kind of completion\n    - detail: Additional details about the item\n    - documentation: Documentation for the item\n    - sortText: Text used to sort the item in the list\n    - filterText: Text used to filter the item\n    - insertText: The actual text to insert (if different from label)\n\n**Example:**\n\n```ts\n// Get completions at a specific position\nconst completions = await lsp.completions('workspace/project/src/index.ts', {\n  line: 10,\n  character: 15\n});\ncompletions.items.forEach(item => {\n  console.log(`${item.label} (${item.kind}): ${item.detail}`);\n});\n```\n\n***\n\n#### didClose()\n\n```ts\ndidClose(path: string): Promise<void>\n```\n\nNotifies the language server that a file has been closed, should be called when a file is closed\nin the editor to allow the language server to clean up any resources associated with that file.\n\n**Parameters**:\n\n- `path` _string_ - Path to the closed file. Relative paths are resolved based on the project path\n    set in the LSP server constructor.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// When done editing a file\nawait lsp.didClose('workspace/project/src/index.ts');\n```\n\n***\n\n#### didOpen()\n\n```ts\ndidOpen(path: string): Promise<void>\n```\n\nNotifies the language server that a file has been opened, enabling\nlanguage features like diagnostics and completions for that file. The server\nwill begin tracking the file's contents and providing language features.\n\n**Parameters**:\n\n- `path` _string_ - Path to the opened file. Relative paths are resolved based on the sandbox working directory.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// When opening a file for editing\nawait lsp.didOpen('workspace/project/src/index.ts');\n// Now can get completions, symbols, etc. for this file\n```\n\n***\n\n#### documentSymbols()\n\n```ts\ndocumentSymbols(path: string): Promise<LspSymbol[]>\n```\n\nGet symbol information (functions, classes, variables, etc.) from a document.\n\n**Parameters**:\n\n- `path` _string_ - Path to the file to get symbols from. Relative paths are resolved based on the project path\n    set in the LSP server constructor.\n\n\n**Returns**:\n\n- `Promise<LspSymbol[]>` - List of symbols in the document. Each symbol includes:\n    - name: The symbol's name\n    - kind: The symbol's kind (function, class, variable, etc.)\n    - location: The location of the symbol in the file\n\n**Example:**\n\n```ts\n// Get all symbols in a file\nconst symbols = await lsp.documentSymbols('workspace/project/src/index.ts');\nsymbols.forEach(symbol => {\n  console.log(`${symbol.kind} ${symbol.name}: ${symbol.location}`);\n});\n```\n\n***\n\n#### sandboxSymbols()\n\n```ts\nsandboxSymbols(query: string): Promise<LspSymbol[]>\n```\n\nSearches for symbols matching the query string across the entire Sandbox.\n\n**Parameters**:\n\n- `query` _string_ - Search query to match against symbol names\n\n\n**Returns**:\n\n- `Promise<LspSymbol[]>` - List of matching symbols from all files. Each symbol includes:\n    - name: The symbol's name\n    - kind: The symbol's kind (function, class, variable, etc.)\n    - location: The location of the symbol in the file\n\n**Example:**\n\n```ts\n// Search for all symbols containing \"User\"\nconst symbols = await lsp.sandboxSymbols('User');\nsymbols.forEach(symbol => {\n  console.log(`${symbol.name} (${symbol.kind}) in ${symbol.location}`);\n});\n```\n\n***\n\n#### start()\n\n```ts\nstart(): Promise<void>\n```\n\nStarts the language server, must be called before using any other LSP functionality.\nIt initializes the language server for the specified language and project.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nconst lsp = await sandbox.createLspServer('typescript', 'workspace/project');\nawait lsp.start();  // Initialize the server\n// Now ready for LSP operations\n```\n\n***\n\n#### stop()\n\n```ts\nstop(): Promise<void>\n```\n\nStops the language server, should be called when the LSP server is no longer needed to\nfree up system resources.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// When done with LSP features\nawait lsp.stop();  // Clean up resources\n```\n\n***\n\n#### ~~workspaceSymbols()~~\n\n```ts\nworkspaceSymbols(query: string): Promise<LspSymbol[]>\n```\n\nSearches for symbols matching the query string across the entire Sandbox.\n\n**Parameters**:\n\n- `query` _string_ - Search query to match against symbol names\n\n\n**Returns**:\n\n- `Promise<LspSymbol[]>` - List of matching symbols from all files. Each symbol includes:\n    - name: The symbol's name\n    - kind: The symbol's kind (function, class, variable, etc.)\n    - location: The location of the symbol in the file\n\n##### Deprecated\n\nUse `sandboxSymbols` instead. This method will be removed in a future version.\n\n***\n\n\n## LspLanguageId\n\nSupported language server types.\n\n**Enum Members**:\n\n- `JAVASCRIPT` (\"javascript\")\n- `PYTHON` (\"python\")\n- `TYPESCRIPT` (\"typescript\")\n\n## Position\n\nRepresents a zero-based position within a text document,\nspecified by line number and character offset.\n\n**Properties**:\n\n- `character` _number_ - Zero-based character offset on the line\n- `line` _number_ - Zero-based line number in the document\n\n\n\n**Example:**\n\n```ts\nconst position: Position = {\n  line: 10,     // Line 11 (zero-based)\n  character: 15  // Character 16 on the line (zero-based)\n};\n```"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/object-storage.mdx",
    "content": "---\ntitle: \"ObjectStorage\"\nhideTitleOnPage: true\n---\n\n\n## ObjectStorage\n\nObjectStorage class for interacting with object storage services.\n\n### Param\n\nThe configuration for the object storage service.\n\n### Constructors\n\n#### new ObjectStorage()\n\n```ts\nnew ObjectStorage(config: ObjectStorageConfig): ObjectStorage\n```\n\n**Parameters**:\n\n- `config` _ObjectStorageConfig_\n\n\n**Returns**:\n\n- `ObjectStorage`\n\n### Methods\n\n#### upload()\n\n```ts\nupload(\n   path: string, \n   organizationId: string, \narchiveBasePath: string): Promise<string>\n```\n\nUpload a file or directory to object storage.\n\n**Parameters**:\n\n- `path` _string_ - The path to the file or directory to upload.\n- `organizationId` _string_ - The organization ID to use for the upload.\n- `archiveBasePath` _string_ - The base path to use for the archive.\n\n\n**Returns**:\n\n- `Promise<string>` - The hash of the uploaded file or directory.\n\n***\n\n\n## ObjectStorageConfig\n\nConfiguration for the ObjectStorage class.\n\n**Properties**:\n\n- `accessKeyId` _string_ - The access key ID for the object storage service.\n- `bucketName?` _string_ - The name of the bucket to use.\n- `endpointUrl` _string_ - The endpoint URL for the object storage service.\n- `secretAccessKey` _string_ - The secret access key for the object storage service.\n- `sessionToken?` _string_ - The session token for the object storage service. Used for temporary credentials."
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/process.mdx",
    "content": "---\ntitle: \"Process\"\nhideTitleOnPage: true\n---\n\n\n## CodeRunParams\n\nParameters for code execution.\n\n**Properties**:\n\n- `argv?` _string\\[\\]_ - Command line arguments\n- `env?` _Record\\<string, string\\>_ - Environment variables\n    \n\n\n\n\n### Constructors\n\n#### new CodeRunParams()\n\n```ts\nnew CodeRunParams(): CodeRunParams\n```\n\n**Returns**:\n\n- `CodeRunParams`\n## Process\n\nHandles process and code execution within a Sandbox.\n\n### Constructors\n\n#### new Process()\n\n```ts\nnew Process(\n   clientConfig: Configuration, \n   codeToolbox: SandboxCodeToolbox, \n   apiClient: ProcessApi, \n   getPreviewToken: () => Promise<string>): Process\n```\n\n**Parameters**:\n\n- `clientConfig` _Configuration_\n- `codeToolbox` _SandboxCodeToolbox_\n- `apiClient` _ProcessApi_\n- `getPreviewToken` _\\(\\) =\\> Promise\\<string\\>_\n\n\n**Returns**:\n\n- `Process`\n\n### Methods\n\n#### codeRun()\n\n```ts\ncodeRun(\n   code: string, \n   params?: CodeRunParams, \ntimeout?: number): Promise<ExecuteResponse>\n```\n\nExecutes code in the Sandbox using the appropriate language runtime.\n\n**Parameters**:\n\n- `code` _string_ - Code to execute\n- `params?` _CodeRunParams_ - Parameters for code execution\n- `timeout?` _number_ - Maximum time in seconds to wait for execution to complete\n\n\n**Returns**:\n\n- `Promise<ExecuteResponse>` - Code execution results containing:\n    - exitCode: The execution's exit status\n    - result: Standard output from the code\n    - artifacts: ExecutionArtifacts object containing `stdout` (same as result) and `charts` (matplotlib charts metadata)\n\n**Examples:**\n\n```ts\n// Run TypeScript code\nconst response = await process.codeRun(`\n  const x = 10;\n  const y = 20;\n  console.log(\\`Sum: \\${x + y}\\`);\n`);\nconsole.log(response.artifacts.stdout);  // Prints: Sum: 30\n```\n\n```ts\n// Run Python code with matplotlib\nconst response = await process.codeRun(`\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nx = np.linspace(0, 10, 30)\ny = np.sin(x)\n\nplt.figure(figsize=(8, 5))\nplt.plot(x, y, 'b-', linewidth=2)\nplt.title('Line Chart')\nplt.xlabel('X-axis (seconds)')\nplt.ylabel('Y-axis (amplitude)')\nplt.grid(True)\nplt.show()\n`);\n\nif (response.artifacts?.charts) {\n  const chart = response.artifacts.charts[0];\n\n  console.log(`Type: ${chart.type}`);\n  console.log(`Title: ${chart.title}`);\n  if (chart.type === ChartType.LINE) {\n    const lineChart = chart as LineChart\n    console.log('X Label:', lineChart.x_label)\n    console.log('Y Label:', lineChart.y_label)\n    console.log('X Ticks:', lineChart.x_ticks)\n    console.log('Y Ticks:', lineChart.y_ticks)\n    console.log('X Tick Labels:', lineChart.x_tick_labels)\n    console.log('Y Tick Labels:', lineChart.y_tick_labels)\n    console.log('X Scale:', lineChart.x_scale)\n    console.log('Y Scale:', lineChart.y_scale)\n    console.log('Elements:')\n    console.dir(lineChart.elements, { depth: null })\n  }\n}\n```\n\n***\n\n#### connectPty()\n\n```ts\nconnectPty(sessionId: string, options?: PtyConnectOptions): Promise<PtyHandle>\n```\n\nConnect to an existing PTY session in the sandbox.\n\nEstablishes a WebSocket connection to an existing PTY session, allowing you to\ninteract with a previously created terminal session.\n\n**Parameters**:\n\n- `sessionId` _string_ - ID of the PTY session to connect to\n- `options?` _PtyConnectOptions_ - Options for the connection including data handler\n\n\n**Returns**:\n\n- `Promise<PtyHandle>` - PTY handle for managing the session\n\n**Example:**\n\n```ts\n// Connect to an existing PTY session\nconst handle = await process.connectPty('my-session', {\n  onData: (data) => {\n    // Handle terminal output\n    const text = new TextDecoder().decode(data);\n    process.stdout.write(text);\n  },\n});\n\n// Wait for connection to be established\nawait handle.waitForConnection();\n\n// Send commands to the existing session\nawait handle.sendInput('pwd\\n');\nawait handle.sendInput('ls -la\\n');\nawait handle.sendInput('exit\\n');\n\n// Wait for completion\nconst result = await handle.wait();\nconsole.log(`Session exited with code: ${result.exitCode}`);\n\n// Clean up\nawait handle.disconnect();\n```\n\n***\n\n#### createPty()\n\n```ts\ncreatePty(options?: PtyCreateOptions & PtyConnectOptions): Promise<PtyHandle>\n```\n\nCreate a new PTY (pseudo-terminal) session in the sandbox.\n\nCreates an interactive terminal session that can execute commands and handle user input.\nThe PTY session behaves like a real terminal, supporting features like command history.\n\n**Parameters**:\n\n- `options?` _PtyCreateOptions & PtyConnectOptions_ - PTY session configuration including creation and connection options\n\n\n**Returns**:\n\n- `Promise<PtyHandle>` - PTY handle for managing the session\n\n**Example:**\n\n```ts\n// Create a PTY session with custom configuration\nconst ptyHandle = await process.createPty({\n  id: 'my-interactive-session',\n  cwd: '/workspace',\n  envs: { TERM: 'xterm-256color', LANG: 'en_US.UTF-8' },\n  cols: 120,\n  rows: 30,\n  onData: (data) => {\n    // Handle terminal output\n    const text = new TextDecoder().decode(data);\n    process.stdout.write(text);\n  },\n});\n\n// Wait for connection to be established\nawait ptyHandle.waitForConnection();\n\n// Send commands to the terminal\nawait ptyHandle.sendInput('ls -la\\n');\nawait ptyHandle.sendInput('echo \"Hello, PTY!\"\\n');\nawait ptyHandle.sendInput('exit\\n');\n\n// Wait for completion and get result\nconst result = await ptyHandle.wait();\nconsole.log(`PTY session completed with exit code: ${result.exitCode}`);\n\n// Clean up\nawait ptyHandle.disconnect();\n```\n\n***\n\n#### createSession()\n\n```ts\ncreateSession(sessionId: string): Promise<void>\n```\n\nCreates a new long-running background session in the Sandbox.\n\nSessions are background processes that maintain state between commands, making them ideal for\nscenarios requiring multiple related commands or persistent environment setup. You can run\nlong-running commands and monitor process status.\n\n**Parameters**:\n\n- `sessionId` _string_ - Unique identifier for the new session\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Create a new session\nconst sessionId = 'my-session';\nawait process.createSession(sessionId);\nconst session = await process.getSession(sessionId);\n// Do work...\nawait process.deleteSession(sessionId);\n```\n\n***\n\n#### deleteSession()\n\n```ts\ndeleteSession(sessionId: string): Promise<void>\n```\n\nDelete a session from the Sandbox.\n\n**Parameters**:\n\n- `sessionId` _string_ - Unique identifier of the session to delete\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Clean up a completed session\nawait process.deleteSession('my-session');\n```\n\n***\n\n#### executeCommand()\n\n```ts\nexecuteCommand(\n   command: string, \n   cwd?: string, \n   env?: Record<string, string>, \ntimeout?: number): Promise<ExecuteResponse>\n```\n\nExecutes a shell command in the Sandbox.\n\n**Parameters**:\n\n- `command` _string_ - Shell command to execute\n- `cwd?` _string_ - Working directory for command execution. If not specified, uses the sandbox working directory.\n- `env?` _Record\\<string, string\\>_ - Environment variables to set for the command\n- `timeout?` _number_ - Maximum time in seconds to wait for the command to complete. 0 means wait indefinitely.\n\n\n**Returns**:\n\n- `Promise<ExecuteResponse>` - Command execution results containing:\n    - exitCode: The command's exit status\n    - result: Standard output from the command\n    - artifacts: ExecutionArtifacts object containing `stdout` (same as result) and `charts` (matplotlib charts metadata)\n\n**Examples:**\n\n```ts\n// Simple command\nconst response = await process.executeCommand('echo \"Hello\"');\nconsole.log(response.artifacts.stdout);  // Prints: Hello\n```\n\n```ts\n// Command with working directory\nconst result = await process.executeCommand('ls', 'workspace/src');\n```\n\n```ts\n// Command with timeout\nconst result = await process.executeCommand('sleep 10', undefined, 5);\n```\n\n***\n\n#### executeSessionCommand()\n\n```ts\nexecuteSessionCommand(\n   sessionId: string, \n   req: SessionExecuteRequest, \ntimeout?: number): Promise<SessionExecuteResponse>\n```\n\nExecutes a command in an existing session.\n\n**Parameters**:\n\n- `sessionId` _string_ - Unique identifier of the session to use\n- `req` _SessionExecuteRequest_ - Command execution request containing:\n    - command: The command to execute\n    - runAsync: Whether to execute asynchronously\n    - suppressInputEcho: Whether to suppress input echo. Default is `false`.\n- `timeout?` _number_ - Timeout in seconds\n\n\n**Returns**:\n\n- `Promise<SessionExecuteResponse>` - Command execution results containing:\n    - cmdId: Unique identifier for the executed command\n    - output: Combined command output (stdout and stderr) (if synchronous execution)\n    - stdout: Standard output from the command\n    - stderr: Standard error from the command\n    - exitCode: Command exit status (if synchronous execution)\n\n**Example:**\n\n```ts\n// Execute commands in sequence, maintaining state\nconst sessionId = 'my-session';\n\n// Change directory\nawait process.executeSessionCommand(sessionId, {\n  command: 'cd /home/daytona'\n});\n\n// Run command in new directory\nconst result = await process.executeSessionCommand(sessionId, {\n  command: 'pwd'\n});\nconsole.log('[STDOUT]:', result.stdout);\nconsole.log('[STDERR]:', result.stderr);\n```\n\n***\n\n#### getEntrypointLogs()\n\n##### Call Signature\n\n```ts\ngetEntrypointLogs(): Promise<SessionCommandLogsResponse>\n```\n\nGet the logs for the sandbox entrypoint session.\n\n**Returns**:\n\n- `Promise<SessionCommandLogsResponse>` - Command logs containing: output (combined stdout and stderr), stdout and stderr\n\n**Example:**\n\n```ts\nconst logs = await process.getEntrypointLogs();\nconsole.log('[STDOUT]:', logs.stdout);\nconsole.log('[STDERR]:', logs.stderr);\n```\n\n##### Call Signature\n\n```ts\ngetEntrypointLogs(onStdout: (chunk: string) => void, onStderr: (chunk: string) => void): Promise<void>\n```\n\nAsynchronously retrieve and process the logs for the entrypoint session as they become available.\n\n**Parameters**:\n\n- `onStdout` _\\(chunk: string\\) =\\> void_ - Callback function to handle stdout log chunks\n- `onStderr` _\\(chunk: string\\) =\\> void_ - Callback function to handle stderr log chunks\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nconst logs = await process.getEntrypointLogs((chunk) => {\n  console.log('[STDOUT]:', chunk);\n}, (chunk) => {\n  console.log('[STDERR]:', chunk);\n});\n```\n\n***\n\n#### getEntrypointSession()\n\n```ts\ngetEntrypointSession(): Promise<Session>\n```\n\nGet the sandbox entrypoint session\n\n**Returns**:\n\n- `Promise<Session>` - Entrypoint session information including:\n    - sessionId: The entrypoint session's unique identifier\n    - commands: List of commands executed in the entrypoint session\n\n**Example:**\n\n```ts\nconst session = await process.getEntrypointSession();\nsession.commands.forEach(cmd => {\n  console.log(`Command: ${cmd.command}`);\n});\n```\n\n***\n\n#### getPtySessionInfo()\n\n```ts\ngetPtySessionInfo(sessionId: string): Promise<PtySessionInfo>\n```\n\nGet detailed information about a specific PTY session.\n\nRetrieves comprehensive information about a PTY session including its current state,\nconfiguration, and metadata.\n\n**Parameters**:\n\n- `sessionId` _string_ - ID of the PTY session to retrieve information for\n\n\n**Returns**:\n\n- `Promise<PtySessionInfo>` - PTY session information\n\n**Throws**:\n\nIf the PTY session doesn't exist\n\n**Example:**\n\n```ts\n// Get details about a specific PTY session\nconst session = await process.getPtySessionInfo('my-session');\n\nconsole.log(`Session ID: ${session.id}`);\nconsole.log(`Active: ${session.active}`);\nconsole.log(`Working Directory: ${session.cwd}`);\nconsole.log(`Terminal Size: ${session.cols}x${session.rows}`);\n\nif (session.processId) {\n  console.log(`Process ID: ${session.processId}`);\n}\n```\n\n***\n\n#### getSession()\n\n```ts\ngetSession(sessionId: string): Promise<Session>\n```\n\nGet a session in the sandbox.\n\n**Parameters**:\n\n- `sessionId` _string_ - Unique identifier of the session to retrieve\n\n\n**Returns**:\n\n- `Promise<Session>` - Session information including:\n    - sessionId: The session's unique identifier\n    - commands: List of commands executed in the session\n\n**Example:**\n\n```ts\nconst session = await process.getSession('my-session');\nsession.commands.forEach(cmd => {\n  console.log(`Command: ${cmd.command}`);\n});\n```\n\n***\n\n#### getSessionCommand()\n\n```ts\ngetSessionCommand(sessionId: string, commandId: string): Promise<Command>\n```\n\nGets information about a specific command executed in a session.\n\n**Parameters**:\n\n- `sessionId` _string_ - Unique identifier of the session\n- `commandId` _string_ - Unique identifier of the command\n\n\n**Returns**:\n\n- `Promise<Command>` - Command information including:\n    - id: The command's unique identifier\n    - command: The executed command string\n    - exitCode: Command's exit status (if completed)\n\n**Example:**\n\n```ts\nconst cmd = await process.getSessionCommand('my-session', 'cmd-123');\nif (cmd.exitCode === 0) {\n  console.log(`Command ${cmd.command} completed successfully`);\n}\n```\n\n***\n\n#### getSessionCommandLogs()\n\n##### Call Signature\n\n```ts\ngetSessionCommandLogs(sessionId: string, commandId: string): Promise<SessionCommandLogsResponse>\n```\n\nGet the logs for a command executed in a session.\n\n**Parameters**:\n\n- `sessionId` _string_ - Unique identifier of the session\n- `commandId` _string_ - Unique identifier of the command\n\n**Returns**:\n\n- `Promise<SessionCommandLogsResponse>` - Command logs containing: output (combined stdout and stderr), stdout and stderr\n\n**Example:**\n\n```ts\nconst logs = await process.getSessionCommandLogs('my-session', 'cmd-123');\nconsole.log('[STDOUT]:', logs.stdout);\nconsole.log('[STDERR]:', logs.stderr);\n```\n\n##### Call Signature\n\n```ts\ngetSessionCommandLogs(\n   sessionId: string, \n   commandId: string, \n   onStdout: (chunk: string) => void, \nonStderr: (chunk: string) => void): Promise<void>\n```\n\nAsynchronously retrieve and process the logs for a command executed in a session as they become available.\n\n**Parameters**:\n\n- `sessionId` _string_ - Unique identifier of the session\n- `commandId` _string_ - Unique identifier of the command\n- `onStdout` _\\(chunk: string\\) =\\> void_ - Callback function to handle stdout log chunks\n- `onStderr` _\\(chunk: string\\) =\\> void_ - Callback function to handle stderr log chunks\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nconst logs = await process.getSessionCommandLogs('my-session', 'cmd-123', (chunk) => {\n  console.log('[STDOUT]:', chunk);\n}, (chunk) => {\n  console.log('[STDERR]:', chunk);\n});\n```\n\n***\n\n#### killPtySession()\n\n```ts\nkillPtySession(sessionId: string): Promise<void>\n```\n\nKill a PTY session and terminate its associated process.\n\nForcefully terminates the PTY session and cleans up all associated resources.\nThis will close any active connections and kill the underlying shell process.\n\n**Parameters**:\n\n- `sessionId` _string_ - ID of the PTY session to kill\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf the PTY session doesn't exist or cannot be killed\n\n##### Note\n\nThis operation is irreversible. Any unsaved work in the terminal session will be lost.\n\n**Example:**\n\n```ts\n// Kill a specific PTY session\nawait process.killPtySession('my-session');\n\n// Verify the session is no longer active\ntry {\n  const info = await process.getPtySessionInfo('my-session');\n  console.log(`Session still exists but active: ${info.active}`);\n} catch (error) {\n  console.log('Session has been completely removed');\n}\n```\n\n***\n\n#### listPtySessions()\n\n```ts\nlistPtySessions(): Promise<PtySessionInfo[]>\n```\n\nList all PTY sessions in the sandbox.\n\nRetrieves information about all PTY sessions, both active and inactive,\nthat have been created in this sandbox.\n\n**Returns**:\n\n- `Promise<PtySessionInfo[]>` - Array of PTY session information\n\n**Example:**\n\n```ts\n// List all PTY sessions\nconst sessions = await process.listPtySessions();\n\nfor (const session of sessions) {\n  console.log(`Session ID: ${session.id}`);\n  console.log(`Active: ${session.active}`);\n  console.log(`Created: ${session.createdAt}`);\n  }\n  console.log('---');\n}\n```\n\n***\n\n#### listSessions()\n\n```ts\nlistSessions(): Promise<Session[]>\n```\n\nLists all active sessions in the Sandbox.\n\n**Returns**:\n\n- `Promise<Session[]>` - Array of active sessions\n\n**Example:**\n\n```ts\nconst sessions = await process.listSessions();\nsessions.forEach(session => {\n  console.log(`Session ${session.sessionId}:`);\n  session.commands.forEach(cmd => {\n    console.log(`- ${cmd.command} (${cmd.exitCode})`);\n  });\n});\n```\n\n***\n\n#### resizePtySession()\n\n```ts\nresizePtySession(\n   sessionId: string, \n   cols: number, \nrows: number): Promise<PtySessionInfo>\n```\n\nResize a PTY session's terminal dimensions.\n\nChanges the terminal size of an active PTY session. This is useful when the\nclient terminal is resized or when you need to adjust the display for different\noutput requirements.\n\n**Parameters**:\n\n- `sessionId` _string_ - ID of the PTY session to resize\n- `cols` _number_ - New number of terminal columns\n- `rows` _number_ - New number of terminal rows\n\n\n**Returns**:\n\n- `Promise<PtySessionInfo>` - Updated session information reflecting the new terminal size\n\n**Throws**:\n\nIf the PTY session doesn't exist or resize operation fails\n\n##### Note\n\nThe resize operation will send a SIGWINCH signal to the shell process,\nallowing terminal applications to adapt to the new size.\n\n**Example:**\n\n```ts\n// Resize a PTY session to a larger terminal\nconst updatedInfo = await process.resizePtySession('my-session', 150, 40);\nconsole.log(`Terminal resized to ${updatedInfo.cols}x${updatedInfo.rows}`);\n\n// You can also use the PtyHandle's resize method\nawait ptyHandle.resize(150, 40); // cols, rows\n```\n\n***\n\n#### sendSessionCommandInput()\n\n```ts\nsendSessionCommandInput(\n   sessionId: string, \n   commandId: string, \ndata: string): Promise<void>\n```\n\nSends input data to a command executed in a session.\n\n**Parameters**:\n\n- `sessionId` _string_ - Unique identifier of the session\n- `commandId` _string_ - Unique identifier of the command\n- `data` _string_ - Input data to send\n\n\n**Returns**:\n\n- `Promise<void>`\n\n***\n\n\n## SessionCommandLogsResponse\n\n**Properties**:\n\n- `output?` _string_\n- `stderr?` _string_\n- `stdout?` _string_\n## SessionExecuteResponse\n\n**Extends:**\n\n**Properties**:\n\n- `cmdId` _string_\n    - _Inherited from_: `SessionExecuteResponse.cmdId`\n- `exitCode?` _number_\n    - _Inherited from_: `SessionExecuteResponse.exitCode`\n- `output?` _string_\n    - _Inherited from_: `SessionExecuteResponse.output`\n- `stderr?` _string_\n- `stdout?` _string_\n\n\n\n\n- `SessionExecuteResponse`\n## MAX\\_PREFIX\\_LEN\n\n```ts\nconst MAX_PREFIX_LEN: number;\n```\n\n***\n\n\n## STDERR\\_PREFIX\\_BYTES\n\n```ts\nconst STDERR_PREFIX_BYTES: Uint8Array<ArrayBuffer>;\n```\n\n***\n\n\n## STDOUT\\_PREFIX\\_BYTES\n\n```ts\nconst STDOUT_PREFIX_BYTES: Uint8Array<ArrayBuffer>;\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/pty-handle.mdx",
    "content": "---\ntitle: \"PtyHandle\"\nhideTitleOnPage: true\n---\n\n\n## PtyHandle\n\nPTY session handle for managing a single PTY session.\n\n**Properties**:\n\n- `sessionId` _string_\n\n\n\nProvides methods for sending input, resizing the terminal, waiting for completion,\nand managing the WebSocket connection to a PTY session.\n\n**Example:**\n\n```typescript\n// Create a PTY session\nconst ptyHandle = await process.createPty({\n  id: 'my-session',\n  cols: 120,\n  rows: 30,\n  onData: (data) => {\n    const text = new TextDecoder().decode(data);\n    process.stdout.write(text);\n  },\n});\n\n// Send commands\nawait ptyHandle.sendInput('ls -la\\n');\nawait ptyHandle.sendInput('exit\\n');\n\n// Wait for completion\nconst result = await ptyHandle.wait();\nconsole.log(`PTY exited with code: ${result.exitCode}`);\n\n// Clean up\nawait ptyHandle.disconnect();\n```\n\n### Accessors\n\n#### error\n\n##### Get Signature\n\n```ts\nget error(): string\n```\n\nError message if the PTY failed\n\n**Returns**:\n\n- `string`\n\n***\n\n#### exitCode\n\n##### Get Signature\n\n```ts\nget exitCode(): number\n```\n\nExit code of the PTY process (if terminated)\n\n**Returns**:\n\n- `number`\n\n### Constructors\n\n#### new PtyHandle()\n\n```ts\nnew PtyHandle(\n   ws: WebSocket, \n   handleResize: (cols: number, rows: number) => Promise<PtySessionInfo>, \n   handleKill: () => Promise<void>, \n   onPty: (data: Uint8Array) => void | Promise<void>, \n   sessionId: string): PtyHandle\n```\n\n**Parameters**:\n\n- `ws` _WebSocket_\n- `handleResize` _\\(cols: number, rows: number\\) =\\> Promise\\<PtySessionInfo\\>_\n- `handleKill` _\\(\\) =\\> Promise\\<void\\>_\n- `onPty` _\\(data: Uint8Array\\) =\\> void \\| Promise\\<void\\>_\n- `sessionId` _string_\n\n\n**Returns**:\n\n- `PtyHandle`\n\n### Methods\n\n#### disconnect()\n\n```ts\ndisconnect(): Promise<void>\n```\n\nDisconnect from the PTY session and clean up resources.\n\nCloses the WebSocket connection and releases any associated resources.\nShould be called when done with the PTY session.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Always clean up when done\ntry {\n  // ... use PTY session\n} finally {\n  await ptyHandle.disconnect();\n}\n```\n\n***\n\n#### isConnected()\n\n```ts\nisConnected(): boolean\n```\n\nCheck if connected to the PTY session\n\n**Returns**:\n\n- `boolean`\n\n***\n\n#### kill()\n\n```ts\nkill(): Promise<void>\n```\n\nKill the PTY process and terminate the session.\n\nForcefully terminates the PTY session and its associated process.\nThis operation is irreversible and will cause the PTY to exit immediately.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf the kill operation fails\n\n**Example:**\n\n```ts\n// Kill a long-running process\nawait ptyHandle.kill();\n\n// Wait to confirm termination\nconst result = await ptyHandle.wait();\nconsole.log(`Process terminated with exit code: ${result.exitCode}`);\n```\n\n***\n\n#### resize()\n\n```ts\nresize(cols: number, rows: number): Promise<PtySessionInfo>\n```\n\nResize the PTY terminal dimensions.\n\nChanges the terminal size which will notify terminal applications\nabout the new dimensions via SIGWINCH signal.\n\n**Parameters**:\n\n- `cols` _number_ - New number of terminal columns\n- `rows` _number_ - New number of terminal rows\n\n\n**Returns**:\n\n- `Promise<PtySessionInfo>`\n\n**Example:**\n\n```ts\n// Resize to 120x30\nawait ptyHandle.resize(120, 30);\n```\n\n***\n\n#### sendInput()\n\n```ts\nsendInput(data: string | Uint8Array<ArrayBufferLike>): Promise<void>\n```\n\nSend input data to the PTY session.\n\nSends keyboard input or commands to the terminal session. The data will be\nprocessed as if it was typed in the terminal.\n\n**Parameters**:\n\n- `data` _Input data to send \\(commands, keystrokes, etc.\\)_ - `string` | `Uint8Array`\\<`ArrayBufferLike`\\>\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf PTY is not connected or sending fails\n\n**Example:**\n\n```ts\n// Send a command\nawait ptyHandle.sendInput('ls -la\\n');\n\n// Send raw bytes\nawait ptyHandle.sendInput(new Uint8Array([3])); // Ctrl+C\n```\n\n***\n\n#### wait()\n\n```ts\nwait(): Promise<PtyResult>\n```\n\nWait for the PTY process to exit and return the result.\n\nThis method blocks until the PTY process terminates and returns\ninformation about how it exited.\n\n**Returns**:\n\n- `Promise<PtyResult>` - Result containing exit code and error information\n\n**Example:**\n\n```ts\n// Wait for process to complete\nconst result = await ptyHandle.wait();\n\nif (result.exitCode === 0) {\n  console.log('Process completed successfully');\n} else {\n  console.log(`Process failed with code: ${result.exitCode}`);\n  if (result.error) {\n    console.log(`Error: ${result.error}`);\n  }\n}\n```\n\n***\n\n#### waitForConnection()\n\n```ts\nwaitForConnection(): Promise<void>\n```\n\nWait for the WebSocket connection to be established.\n\nThis method ensures the PTY session is ready to receive input and send output.\nIt waits for the server to confirm the connection is established.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf connection times out (10 seconds) or connection fails"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/pty.mdx",
    "content": "---\ntitle: \"Pty\"\nhideTitleOnPage: true\n---\n\n\n## PtyConnectOptions\n\nOptions for connecting to a PTY session\n\n**Properties**:\n\n- `onData()` _\\(data: Uint8Array\\) =\\> void \\| Promise\\<void\\>_ - Callback to handle PTY output data\n    \n    **Parameters**:\n    \n    - `data` _Uint8Array_\n    \n    \n    ##### Returns\n    \n    `void` \\| `Promise<void>`\n## PtyCreateOptions\n\nOptions for creating a PTY session\n\n**Properties**:\n\n- `cols?` _number_ - Number of terminal columns\n- `cwd?` _string_ - Starting directory for the PTY session, defaults to the sandbox's working directory\n- `envs?` _Record\\<string, string\\>_ - Environment variables for the PTY session\n- `id` _string_ - The unique identifier for the PTY session\n- `rows?` _number_ - Number of terminal rows\n## PtyResult\n\nPTY session result on exit\n\n**Properties**:\n\n- `error?` _string_ - Error message if the PTY failed\n- `exitCode?` _number_ - Exit code when the PTY process ends"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/sandbox.mdx",
    "content": "---\ntitle: \"Sandbox\"\nhideTitleOnPage: true\n---\n\n\n## Sandbox\n\nRepresents a Daytona Sandbox.\n\n**Properties**:\n\n- `autoArchiveInterval?` _number_ - Auto-archive interval in minutes\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.autoArchiveInterval\n    ```\n- `autoDeleteInterval?` _number_ - Auto-delete interval in minutes\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.autoDeleteInterval\n    ```\n- `autoStopInterval?` _number_ - Auto-stop interval in minutes\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.autoStopInterval\n    ```\n- `backupCreatedAt?` _string_ - When the backup was created\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.backupCreatedAt\n    ```\n- `backupState?` _SandboxBackupStateEnum_ - Current state of Sandbox backup\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.backupState\n    ```\n- `buildInfo?` _BuildInfo_ - Build information for the Sandbox if it was created from dynamic build\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.buildInfo\n    ```\n- `codeInterpreter` _CodeInterpreter_ - Stateful interpreter interface for executing code.\n    Currently supports only Python. For other languages, use the `process.codeRun` method.\n- `computerUse` _ComputerUse_ - Computer use operations interface for desktop automation\n- `cpu` _number_ - Number of CPUs allocated to the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.cpu\n    ```\n- `createdAt?` _string_ - When the Sandbox was created\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.createdAt\n    ```\n- `disk` _number_ - Amount of disk space allocated to the Sandbox in GiB\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.disk\n    ```\n- `env` _Record\\<string, string\\>_ - Environment variables set in the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.env\n    ```\n- `errorReason?` _string_ - Error message if Sandbox is in error state\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.errorReason\n    ```\n- `fs` _FileSystem_ - File system operations interface\n- `git` _Git_ - Git operations interface\n- `gpu` _number_ - Number of GPUs allocated to the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.gpu\n    ```\n- `id` _string_ - Unique identifier for the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.id\n    ```\n- `labels` _Record\\<string, string\\>_ - Custom labels attached to the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.labels\n    ```\n- `memory` _number_ - Amount of memory allocated to the Sandbox in GiB\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.memory\n    ```\n- `name` _string_ - The name of the sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.name\n    ```\n- `networkAllowList?` _string_ - Comma-separated list of allowed CIDR network addresses for the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.networkAllowList\n    ```\n- `networkBlockAll` _boolean_ - Whether to block all network access for the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.networkBlockAll\n    ```\n- `organizationId` _string_ - Organization ID of the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.organizationId\n    ```\n- `process` _Process_ - Process execution interface\n- `public` _boolean_ - Whether the Sandbox is publicly accessible\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.public\n    ```\n- `recoverable?` _boolean_ - Whether the Sandbox error is recoverable.\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.recoverable\n    ```\n- `snapshot?` _string_ - Daytona snapshot used to create the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.snapshot\n    ```\n- `state?` _SandboxState_ - Current state of the Sandbox (e.g., \"started\", \"stopped\")\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.state\n    ```\n- `target` _string_ - Target location of the runner where the Sandbox runs\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.target\n    ```\n- `toolboxProxyUrl` _string_ - The toolbox proxy URL for the sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.toolboxProxyUrl\n    ```\n- `updatedAt?` _string_ - When the Sandbox was last updated\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.updatedAt\n    ```\n- `user` _string_ - OS user running in the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.user\n    ```\n- `volumes?` _SandboxVolume\\[\\]_ - Volumes attached to the Sandbox\n    \n    ##### Implementation of\n    \n    ```ts\n    SandboxDto.volumes\n    ```\n    \n\n\n\n\n### Implements\n\n- `Sandbox`\n\n### Constructors\n\n#### new Sandbox()\n\n```ts\nnew Sandbox(\n   sandboxDto: Sandbox, \n   clientConfig: Configuration, \n   axiosInstance: AxiosInstance, \n   sandboxApi: SandboxApi, \n   codeToolbox: SandboxCodeToolbox): Sandbox\n```\n\nCreates a new Sandbox instance\n\n**Parameters**:\n\n- `sandboxDto` _Sandbox_ - The API Sandbox instance\n- `clientConfig` _Configuration_\n- `axiosInstance` _AxiosInstance_\n- `sandboxApi` _SandboxApi_ - API client for Sandbox operations\n- `codeToolbox` _SandboxCodeToolbox_ - Language-specific toolbox implementation\n\n\n**Returns**:\n\n- `Sandbox`\n\n### Methods\n\n#### archive()\n\n```ts\narchive(): Promise<void>\n```\n\nArchives the sandbox, making it inactive and preserving its state. When sandboxes are archived, the entire filesystem\nstate is moved to cost-effective object storage, making it possible to keep sandboxes available for an extended period.\nThe tradeoff between archived and stopped states is that starting an archived sandbox takes more time, depending on its size.\nSandbox must be stopped before archiving.\n\n**Returns**:\n\n- `Promise<void>`\n\n***\n\n#### createLspServer()\n\n```ts\ncreateLspServer(languageId: string, pathToProject: string): Promise<LspServer>\n```\n\nCreates a new Language Server Protocol (LSP) server instance.\n\nThe LSP server provides language-specific features like code completion,\ndiagnostics, and more.\n\n**Parameters**:\n\n- `languageId` _string_ - The language server type (e.g., \"typescript\")\n- `pathToProject` _string_ - Path to the project root directory. Relative paths are resolved based on the sandbox working directory.\n\n\n**Returns**:\n\n- `Promise<LspServer>` - A new LSP server instance configured for the specified language\n\n**Example:**\n\n```ts\nconst lsp = await sandbox.createLspServer('typescript', 'workspace/project');\n```\n\n***\n\n#### createSshAccess()\n\n```ts\ncreateSshAccess(expiresInMinutes?: number): Promise<SshAccessDto>\n```\n\nCreates an SSH access token for the sandbox.\n\n**Parameters**:\n\n- `expiresInMinutes?` _number_ - The number of minutes the SSH access token will be valid for.\n\n\n**Returns**:\n\n- `Promise<SshAccessDto>` - The SSH access token.\n\n***\n\n#### delete()\n\n```ts\ndelete(timeout: number): Promise<void>\n```\n\nDeletes the Sandbox.\n\n**Parameters**:\n\n- `timeout` _number = 60_\n\n\n**Returns**:\n\n- `Promise<void>`\n\n***\n\n#### expireSignedPreviewUrl()\n\n```ts\nexpireSignedPreviewUrl(port: number, token: string): Promise<void>\n```\n\nExpires a signed preview url for the sandbox at the specified port.\n\n**Parameters**:\n\n- `port` _number_ - The port to expire the signed preview url on.\n- `token` _string_ - The token to expire the signed preview url on.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n***\n\n#### getPreviewLink()\n\n```ts\ngetPreviewLink(port: number): Promise<PortPreviewUrl>\n```\n\nRetrieves the preview link for the sandbox at the specified port. If the port is closed,\nit will be opened automatically. For private sandboxes, a token is included to grant access\nto the URL.\n\n**Parameters**:\n\n- `port` _number_ - The port to open the preview link on.\n\n\n**Returns**:\n\n- `Promise<PortPreviewUrl>` - The response object for the preview link, which includes the `url`\n    and the `token` (to access private sandboxes).\n\n**Example:**\n\n```ts\nconst previewLink = await sandbox.getPreviewLink(3000);\nconsole.log(`Preview URL: ${previewLink.url}`);\nconsole.log(`Token: ${previewLink.token}`);\n```\n\n***\n\n#### getSignedPreviewUrl()\n\n```ts\ngetSignedPreviewUrl(port: number, expiresInSeconds?: number): Promise<SignedPortPreviewUrl>\n```\n\nRetrieves a signed preview url for the sandbox at the specified port.\n\n**Parameters**:\n\n- `port` _number_ - The port to open the preview link on.\n- `expiresInSeconds?` _number_ - The number of seconds the signed preview url will be valid for. Defaults to 60 seconds.\n\n\n**Returns**:\n\n- `Promise<SignedPortPreviewUrl>` - The response object for the signed preview url.\n\n***\n\n#### getUserHomeDir()\n\n```ts\ngetUserHomeDir(): Promise<string>\n```\n\nGets the user's home directory path for the logged in user inside the Sandbox.\n\n**Returns**:\n\n- `Promise<string>` - The absolute path to the Sandbox user's home directory for the logged in user\n\n**Example:**\n\n```ts\nconst userHomeDir = await sandbox.getUserHomeDir();\nconsole.log(`Sandbox user home: ${userHomeDir}`);\n```\n\n***\n\n#### ~~getUserRootDir()~~\n\n```ts\ngetUserRootDir(): Promise<string>\n```\n\n**Returns**:\n\n- `Promise<string>`\n\n##### Deprecated\n\nUse `getUserHomeDir` instead. This method will be removed in a future version.\n\n***\n\n#### getWorkDir()\n\n```ts\ngetWorkDir(): Promise<string>\n```\n\nGets the working directory path inside the Sandbox.\n\n**Returns**:\n\n- `Promise<string>` - The absolute path to the Sandbox working directory. Uses the WORKDIR specified\n    in the Dockerfile if present, or falling back to the user's home directory if not.\n\n**Example:**\n\n```ts\nconst workDir = await sandbox.getWorkDir();\nconsole.log(`Sandbox working directory: ${workDir}`);\n```\n\n***\n\n#### recover()\n\n```ts\nrecover(timeout?: number): Promise<void>\n```\n\nRecover the Sandbox from a recoverable error and wait for it to be ready.\n\n**Parameters**:\n\n- `timeout?` _number = 60_ - Maximum time to wait in seconds. 0 means no timeout.\n    Defaults to 60-second timeout.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\n- `DaytonaError` - If Sandbox fails to recover or times out\n\n**Example:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\nawait sandbox.recover();\nconsole.log('Sandbox recovered successfully');\n```\n\n***\n\n#### refreshActivity()\n\n```ts\nrefreshActivity(): Promise<void>\n```\n\nRefreshes the sandbox activity to reset the timer for automated lifecycle management actions.\n\nThis method updates the sandbox's last activity timestamp without changing its state.\nIt is useful for keeping long-running sessions alive while there is still user activity.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Keep sandbox activity alive\nawait sandbox.refreshActivity();\n```\n\n***\n\n#### refreshData()\n\n```ts\nrefreshData(): Promise<void>\n```\n\nRefreshes the Sandbox data from the API.\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nawait sandbox.refreshData();\nconsole.log(`Sandbox ${sandbox.id}:`);\nconsole.log(`State: ${sandbox.state}`);\nconsole.log(`Resources: ${sandbox.cpu} CPU, ${sandbox.memory} GiB RAM`);\n```\n\n***\n\n#### resize()\n\n```ts\nresize(resources: Resources, timeout?: number): Promise<void>\n```\n\nResizes the Sandbox resources.\n\nChanges the CPU, memory, or disk allocation for the Sandbox. Hot resize (on running\nsandbox) only allows CPU/memory increases. Disk resize requires a stopped sandbox.\n\n**Parameters**:\n\n- `resources` _Resources_ - New resource configuration. Only specified fields will be updated.\n    - cpu: Number of CPU cores (minimum: 1). For hot resize, can only be increased.\n    - memory: Memory in GiB (minimum: 1). For hot resize, can only be increased.\n    - disk: Disk space in GiB (can only be increased, requires stopped sandbox).\n- `timeout?` _number = 60_ - Timeout in seconds for the resize operation. 0 means no timeout.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\n- If hot resize constraints are violated, disk resize attempted on running sandbox,\n  disk size decrease is attempted, no resource changes are specified, or resize operation times out.\n\n**Example:**\n\n```ts\n// Increase CPU/memory on running sandbox (hot resize)\nawait sandbox.resize({ cpu: 4, memory: 8 });\n\n// Change disk (sandbox must be stopped)\nawait sandbox.stop();\nawait sandbox.resize({ cpu: 2, memory: 4, disk: 30 });\n```\n\n***\n\n#### revokeSshAccess()\n\n```ts\nrevokeSshAccess(token: string): Promise<void>\n```\n\nRevokes an SSH access token for the sandbox.\n\n**Parameters**:\n\n- `token` _string_ - The token to revoke.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n***\n\n#### setAutoArchiveInterval()\n\n```ts\nsetAutoArchiveInterval(interval: number): Promise<void>\n```\n\nSet the auto-archive interval for the Sandbox.\n\nThe Sandbox will automatically archive after being continuously stopped for the specified interval.\n\n**Parameters**:\n\n- `interval` _number_ - Number of minutes after which a continuously stopped Sandbox will be auto-archived.\n    Set to 0 for the maximum interval. Default is 7 days.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\n- `DaytonaError` - If interval is not a non-negative integer\n\n**Example:**\n\n```ts\n// Auto-archive after 1 hour\nawait sandbox.setAutoArchiveInterval(60);\n// Or use the maximum interval\nawait sandbox.setAutoArchiveInterval(0);\n```\n\n***\n\n#### setAutoDeleteInterval()\n\n```ts\nsetAutoDeleteInterval(interval: number): Promise<void>\n```\n\nSet the auto-delete interval for the Sandbox.\n\nThe Sandbox will automatically delete after being continuously stopped for the specified interval.\n\n**Parameters**:\n\n- `interval` _number_ - Number of minutes after which a continuously stopped Sandbox will be auto-deleted.\n    Set to negative value to disable auto-delete. Set to 0 to delete immediately upon stopping.\n    By default, auto-delete is disabled.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// Auto-delete after 1 hour\nawait sandbox.setAutoDeleteInterval(60);\n// Or delete immediately upon stopping\nawait sandbox.setAutoDeleteInterval(0);\n// Or disable auto-delete\nawait sandbox.setAutoDeleteInterval(-1);\n```\n\n***\n\n#### setAutostopInterval()\n\n```ts\nsetAutostopInterval(interval: number): Promise<void>\n```\n\nSet the auto-stop interval for the Sandbox.\n\nThe Sandbox will automatically stop after being idle (no new events) for the specified interval.\nEvents include any state changes or interactions with the Sandbox through the sdk.\nInteractions using Sandbox Previews are not included.\n\n**Parameters**:\n\n- `interval` _number_ - Number of minutes of inactivity before auto-stopping.\n    Set to 0 to disable auto-stop. Default is 15 minutes.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\n- `DaytonaError` - If interval is not a non-negative integer\n\n**Example:**\n\n```ts\n// Auto-stop after 1 hour\nawait sandbox.setAutostopInterval(60);\n// Or disable auto-stop\nawait sandbox.setAutostopInterval(0);\n```\n\n***\n\n#### setLabels()\n\n```ts\nsetLabels(labels: Record<string, string>): Promise<Record<string, string>>\n```\n\nSets labels for the Sandbox.\n\nLabels are key-value pairs that can be used to organize and identify Sandboxes.\n\n**Parameters**:\n\n- `labels` _Record\\<string, string\\>_ - Dictionary of key-value pairs representing Sandbox labels\n\n\n**Returns**:\n\n- `Promise<Record<string, string>>`\n\n**Example:**\n\n```ts\n// Set sandbox labels\nawait sandbox.setLabels({\n  project: 'my-project',\n  environment: 'development',\n  team: 'backend'\n});\n```\n\n***\n\n#### start()\n\n```ts\nstart(timeout?: number): Promise<void>\n```\n\nStart the Sandbox.\n\nThis method starts the Sandbox and waits for it to be ready.\n\n**Parameters**:\n\n- `timeout?` _number = 60_ - Maximum time to wait in seconds. 0 means no timeout.\n    Defaults to 60-second timeout.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\n- `DaytonaError` - If Sandbox fails to start or times out\n\n**Example:**\n\n```ts\nconst sandbox = await daytona.getCurrentSandbox('my-sandbox');\nawait sandbox.start(40);  // Wait up to 40 seconds\nconsole.log('Sandbox started successfully');\n```\n\n***\n\n#### stop()\n\n```ts\nstop(timeout?: number): Promise<void>\n```\n\nStops the Sandbox.\n\nThis method stops the Sandbox and waits for it to be fully stopped.\n\n**Parameters**:\n\n- `timeout?` _number = 60_ - Maximum time to wait in seconds. 0 means no timeout.\n    Defaults to 60-second timeout.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\nawait sandbox.stop();\nconsole.log('Sandbox stopped successfully');\n```\n\n***\n\n#### validateSshAccess()\n\n```ts\nvalidateSshAccess(token: string): Promise<SshAccessValidationDto>\n```\n\nValidates an SSH access token for the sandbox.\n\n**Parameters**:\n\n- `token` _string_ - The token to validate.\n\n\n**Returns**:\n\n- `Promise<SshAccessValidationDto>` - The SSH access validation result.\n\n***\n\n#### waitForResizeComplete()\n\n```ts\nwaitForResizeComplete(timeout?: number): Promise<void>\n```\n\nWaits for the Sandbox resize operation to complete.\n\nThis method polls the Sandbox status until the state is no longer 'resizing'.\n\n**Parameters**:\n\n- `timeout?` _number = 60_ - Maximum time to wait in seconds. 0 means no timeout.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\n- If the sandbox ends up in an error state or resize times out.\n\n***\n\n#### waitUntilStarted()\n\n```ts\nwaitUntilStarted(timeout?: number): Promise<void>\n```\n\nWaits for the Sandbox to reach the 'started' state.\n\nThis method polls the Sandbox status until it reaches the 'started' state\nor encounters an error.\n\n**Parameters**:\n\n- `timeout?` _number = 60_ - Maximum time to wait in seconds. 0 means no timeout.\n    Defaults to 60 seconds.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\n- `DaytonaError` - If the sandbox ends up in an error state or fails to start within the timeout period.\n\n***\n\n#### waitUntilStopped()\n\n```ts\nwaitUntilStopped(timeout?: number): Promise<void>\n```\n\nWait for Sandbox to reach 'stopped' state.\n\nThis method polls the Sandbox status until it reaches the 'stopped' state\nor encounters an error.\n\n**Parameters**:\n\n- `timeout?` _number = 60_ - Maximum time to wait in seconds. 0 means no timeout.\n    Defaults to 60 seconds.\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\n- `DaytonaError` - If the sandbox fails to stop within the timeout period.\n## PaginatedSandboxes\n\n**Extends:**\n\n**Properties**:\n\n- `items` _Sandbox\\[\\]_\n- `page` _number_\n    - _Inherited from_: `PaginatedSandboxes.page`\n- `total` _number_\n    - _Inherited from_: `PaginatedSandboxes.total`\n- `totalPages` _number_\n    - _Inherited from_: `PaginatedSandboxes.totalPages`\n\n\n\n\n- `Omit`\\<`PaginatedSandboxesDto`, `\"items\"`\\>\n## SandboxCodeToolbox\n\nInterface defining methods that a code toolbox must implement\n\n### Methods\n\n#### getRunCommand()\n\n```ts\ngetRunCommand(code: string, params?: CodeRunParams): string\n```\n\nGenerates a command to run the provided code\n\n**Parameters**:\n\n- `code` _string_\n- `params?` _CodeRunParams_\n\n\n**Returns**:\n\n- `string`\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/snapshot.mdx",
    "content": "---\ntitle: \"Snapshot\"\nhideTitleOnPage: true\n---\n\n\n## SnapshotService\n\nService for managing Daytona Snapshots. Can be used to list, get, create and delete Snapshots.\n\n### Constructors\n\n#### new SnapshotService()\n\n```ts\nnew SnapshotService(\n   clientConfig: Configuration, \n   snapshotsApi: SnapshotsApi, \n   objectStorageApi: ObjectStorageApi, \n   defaultRegionId?: string): SnapshotService\n```\n\n**Parameters**:\n\n- `clientConfig` _Configuration_\n- `snapshotsApi` _SnapshotsApi_\n- `objectStorageApi` _ObjectStorageApi_\n- `defaultRegionId?` _string_\n\n\n**Returns**:\n\n- `SnapshotService`\n\n### Methods\n\n#### activate()\n\n```ts\nactivate(snapshot: Snapshot): Promise<Snapshot>\n```\n\nActivates a snapshot.\n\n**Parameters**:\n\n- `snapshot` _Snapshot_ - Snapshot to activate\n\n\n**Returns**:\n\n- `Promise<Snapshot>` - The activated Snapshot instance\n\n***\n\n#### create()\n\n```ts\ncreate(params: CreateSnapshotParams, options: {\n  onLogs: (chunk: string) => void;\n  timeout: number;\n}): Promise<Snapshot>\n```\n\nCreates and registers a new snapshot from the given Image definition.\n\n**Parameters**:\n\n- `params` _CreateSnapshotParams_ - Parameters for snapshot creation.\n- `options` _Options for the create operation._\n- `onLogs?` _\\(chunk: string\\) =\\> void_ - This callback function handles snapshot creation logs.\n- `timeout?` _number_ - Default is no timeout. Timeout in seconds (0 means no timeout).\n\n\n**Returns**:\n\n- `Promise<Snapshot>`\n\n**Example:**\n\n```ts\nconst image = Image.debianSlim('3.12').pipInstall('numpy');\nawait daytona.snapshot.create({ name: 'my-snapshot', image: image }, { onLogs: console.log });\n```\n\n***\n\n#### delete()\n\n```ts\ndelete(snapshot: Snapshot): Promise<void>\n```\n\nDeletes a Snapshot.\n\n**Parameters**:\n\n- `snapshot` _Snapshot_ - Snapshot to delete\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf the Snapshot does not exist or cannot be deleted\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst snapshot = await daytona.snapshot.get(\"snapshot-name\");\nawait daytona.snapshot.delete(snapshot);\nconsole.log(\"Snapshot deleted successfully\");\n```\n\n***\n\n#### get()\n\n```ts\nget(name: string): Promise<Snapshot>\n```\n\nGets a Snapshot by its name.\n\n**Parameters**:\n\n- `name` _string_ - Name of the Snapshot to retrieve\n\n\n**Returns**:\n\n- `Promise<Snapshot>` - The requested Snapshot\n\n**Throws**:\n\nIf the Snapshot does not exist or cannot be accessed\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst snapshot = await daytona.snapshot.get(\"snapshot-name\");\nconsole.log(`Snapshot ${snapshot.name} is in state ${snapshot.state}`);\n```\n\n***\n\n#### list()\n\n```ts\nlist(page?: number, limit?: number): Promise<PaginatedSnapshots>\n```\n\nList paginated list of Snapshots.\n\n**Parameters**:\n\n- `page?` _number_ - Page number for pagination (starting from 1)\n- `limit?` _number_ - Maximum number of items per page\n\n\n**Returns**:\n\n- `Promise<PaginatedSnapshots>` - Paginated list of Snapshots\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst result = await daytona.snapshot.list(2, 10);\nconsole.log(`Found ${result.total} snapshots`);\nresult.items.forEach(snapshot => console.log(`${snapshot.name} (${snapshot.imageName})`));\n```\n\n***\n\n\n## PaginatedSnapshots\n\nRepresents a paginated list of Daytona Snapshots.\n\n**Properties**:\n\n- `items` _Snapshot\\[\\]_ - List of Snapshot instances in the current page.\n- `page` _number_ - Current page number.\n    - _Inherited from_: `Omit.page`\n- `total` _number_ - Total number of Snapshots across all pages.\n    - _Inherited from_: `Omit.total`\n- `totalPages` _number_ - Total number of pages available.\n    \n    - _Inherited from_: `Omit.totalPages`\n\n\n\n\n**Extends:**\n\n- `Omit`\\<`PaginatedSnapshotsDto`, `\"items\"`\\>\n## CreateSnapshotParams\n\n```ts\ntype CreateSnapshotParams = {\n  entrypoint: string[];\n  image: string | Image;\n  name: string;\n  regionId: string;\n  resources: Resources;\n};\n```\n\nParameters for creating a new snapshot.\n\n**Type declaration**:\n\n- `entrypoint?` _string\\[\\]_\n- `image` _string \\| Image_\n- `name` _string_\n- `regionId?` _string_\n- `resources?` _Resources_\n\n\n## Snapshot\n\n```ts\ntype Snapshot = SnapshotDto & {\n  __brand: \"Snapshot\";\n};\n```\n\nRepresents a Daytona Snapshot which is a pre-configured sandbox.\n\n**Type declaration**:\n\n- `\\_\\_brand` _\"Snapshot\"_\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/typescript-sdk/volume.mdx",
    "content": "---\ntitle: \"Volume\"\nhideTitleOnPage: true\n---\n\n\n## VolumeService\n\nService for managing Daytona Volumes.\n\nThis service provides methods to list, get, create, and delete Volumes.\n\nVolumes can be mounted to Sandboxes with an optional subpath parameter to mount\nonly a specific S3 prefix within the volume. When no subpath is specified,\nthe entire volume is mounted.\n\n### Constructors\n\n#### new VolumeService()\n\n```ts\nnew VolumeService(volumesApi: VolumesApi): VolumeService\n```\n\n**Parameters**:\n\n- `volumesApi` _VolumesApi_\n\n\n**Returns**:\n\n- `VolumeService`\n\n### Methods\n\n#### create()\n\n```ts\ncreate(name: string): Promise<Volume>\n```\n\nCreates a new Volume with the specified name.\n\n**Parameters**:\n\n- `name` _string_ - Name for the new Volume\n\n\n**Returns**:\n\n- `Promise<Volume>` - The newly created Volume\n\n**Throws**:\n\nIf the Volume cannot be created\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst volume = await daytona.volume.create(\"my-data-volume\");\nconsole.log(`Created volume ${volume.name} with ID ${volume.id}`);\n```\n\n***\n\n#### delete()\n\n```ts\ndelete(volume: Volume): Promise<void>\n```\n\nDeletes a Volume.\n\n**Parameters**:\n\n- `volume` _Volume_ - Volume to delete\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nIf the Volume does not exist or cannot be deleted\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst volume = await daytona.volume.get(\"volume-name\");\nawait daytona.volume.delete(volume);\nconsole.log(\"Volume deleted successfully\");\n```\n\n***\n\n#### get()\n\n```ts\nget(name: string, create: boolean): Promise<Volume>\n```\n\nGets a Volume by its name.\n\n**Parameters**:\n\n- `name` _string_ - Name of the Volume to retrieve\n- `create` _boolean = false_ - Whether to create the Volume if it does not exist\n\n\n**Returns**:\n\n- `Promise<Volume>` - The requested Volume\n\n**Throws**:\n\nIf the Volume does not exist or cannot be accessed\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst volume = await daytona.volume.get(\"volume-name\", true);\nconsole.log(`Volume ${volume.name} is in state ${volume.state}`);\n```\n\n***\n\n#### list()\n\n```ts\nlist(): Promise<Volume[]>\n```\n\nLists all available Volumes.\n\n**Returns**:\n\n- `Promise<Volume[]>` - List of all Volumes accessible to the user\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst volumes = await daytona.volume.list();\nconsole.log(`Found ${volumes.length} volumes`);\nvolumes.forEach(vol => console.log(`${vol.name} (${vol.id})`));\n```\n\n***\n\n\n## Volume\n\n```ts\ntype Volume = VolumeDto & {\n  __brand: \"Volume\";\n};\n```\n\nRepresents a Daytona Volume which is a shared storage volume for Sandboxes.\n\n**Type declaration**:\n\n- `\\_\\_brand` _\"Volume\"_\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/vnc-access.mdx",
    "content": "---\ntitle: VNC Access\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nVNC (Virtual Network Computing) access provides a graphical desktop environment for your Daytona Sandbox directly in the browser. This allows you to interact with GUI applications, desktop tools, and visual interfaces running inside your sandbox.\n\nVNC and [Computer Use](/docs/en/computer-use) work together to enable both manual and automated desktop interactions. VNC provides the visual interface for users to manually interact with the desktop, while Computer Use provides the programmatic API for AI agents to automate mouse, keyboard, and screenshot operations. Through VNC, you can observe AI agents performing automated tasks via Computer Use in real-time.\n\n- **GUI application development**: build and test desktop applications with visual interfaces\n- **Browser testing**: run and debug web applications in a full browser environment\n- **Visual debugging**: inspect graphical output and UI behavior in real-time\n- **Desktop tool access**: use graphical IDEs, design tools, or other desktop software\n- **Agent observation**: watch AI agents perform automated tasks through Computer Use\n\n:::note[Sandbox image requirement]\nVNC and Computer Use require a sandbox with the default image. Sandboxes created with custom images do not include VNC support unless you install the [required packages](#required-packages).\n:::\n\n## Access VNC from Dashboard\n\nAccess the VNC desktop environment directly from the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/sandboxes).\n\n1. Navigate to [Daytona Sandboxes ↗](https://app.daytona.io/dashboard/sandboxes)\n2. Locate the sandbox you want to access via VNC\n3. Click the options menu (**⋮**) next to the sandbox\n4. Select **VNC** from the dropdown menu\n\nThis opens a VNC viewer in your browser with a **Connect** button.\n\n5. Click **Connect** to establish the VNC session\n\nOnce connected, a full desktop environment loads in your browser, providing mouse and keyboard control over the sandbox's graphical interface.\n\n:::note\nVNC sessions remain active as long as the sandbox is running. If the sandbox auto-stops due to inactivity, you need to start the sandbox again before reconnecting via VNC.\n:::\n\n## Programmatic VNC management\n\nDaytona provides methods to [start](#start-vnc), [stop](#stop-vnc), and [monitor](#get-vnc-status) VNC sessions and processes programmatically using the [Computer Use](/docs/en/computer-use) references as part of automated workflows.\n\n### Start VNC\n\nStart all VNC processes (Xvfb, xfce4, x11vnc, novnc) in the sandbox to enable desktop access.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresult = sandbox.computer_use.start()\nprint(\"VNC processes started:\", result.message)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst result = await sandbox.computerUse.start();\nconsole.log('VNC processes started:', result.message);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresult = sandbox.computer_use.start\nputs \"VNC processes started: #{result.message}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nerr := sandbox.ComputerUse.Start(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer sandbox.ComputerUse.Stop(ctx)\n\nfmt.Println(\"VNC processes started\")\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/start' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Computer Use](/docs/en/computer-use#start-computer-use) reference.\n\n> [**start (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computerusestart)\n>\n> [**start (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#start)\n>\n> [**start (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#start)\n>\n> [**Start (Go SDK)**](/docs/en/go-sdk/daytona#ComputerUseService.Start)\n>\n> [**Start Computer Use Processes (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/start)\n\n### Stop VNC\n\nStop all VNC processes in the sandbox.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresult = sandbox.computer_use.stop()\nprint(\"VNC processes stopped:\", result.message)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst result = await sandbox.computerUse.stop();\nconsole.log('VNC processes stopped:', result.message);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresult = sandbox.computer_use.stop\nputs \"VNC processes stopped: #{result.message}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nerr := sandbox.ComputerUse.Stop(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Println(\"VNC processes stopped\")\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/stop' \\\n  --request POST\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Computer Use](/docs/en/computer-use#stop-computer-use) reference.\n\n> [**stop (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computerusestop)\n>\n> [**stop (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#stop)\n>\n> [**stop (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#stop)\n>\n> [**Stop (Go SDK)**](/docs/en/go-sdk/daytona#ComputerUseService.Stop)\n>\n> [**Stop Computer Use Processes (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/POST/computeruse/stop)\n\n### Get VNC status\n\nCheck the status of VNC processes to verify they are running.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nresponse = sandbox.computer_use.get_status()\nprint(\"VNC status:\", response.status)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst status = await sandbox.computerUse.getStatus();\nconsole.log('VNC status:', status.status);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nresponse = sandbox.computer_use.status\nputs \"VNC status: #{response.status}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nstatus, err := sandbox.ComputerUse.GetStatus(ctx)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nfmt.Printf(\"VNC status: %v\\n\", status[\"status\"])\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://proxy.app.daytona.io/toolbox/{sandboxId}/computeruse/status'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Computer Use](/docs/en/computer-use#get-status) reference.\n\n> [**get_status (Python SDK)**](/docs/en/python-sdk/sync/computer-use#computeruseget_status)\n>\n> [**getStatus (TypeScript SDK)**](/docs/en/typescript-sdk/computer-use#getstatus)\n>\n> [**status (Ruby SDK)**](/docs/en/ruby-sdk/computer-use#status)\n>\n> [**GetStatus (Go SDK)**](/docs/en/go-sdk/daytona#ComputerUseService.GetStatus)\n>\n> [**Get Computer Use Status (API)**](/docs/en/tools/api/#daytona-toolbox/tag/computer-use/GET/computeruse/status)\n\nFor additional process management operations including restarting individual processes and viewing logs, see the [Computer Use](/docs/en/computer-use) reference.\n\n## Automating desktop interactions\n\nOnce VNC is running, you can automate desktop interactions using Computer Use. This enables AI agents to programmatically control the mouse, keyboard, and capture screenshots within the VNC session.\n\n**Available operations:**\n\n- **Mouse**: click, move, drag, scroll, and get cursor position\n- **Keyboard**: type text, press keys, and execute hotkey combinations\n- **Screenshot**: capture full screen, regions, or compressed images\n- **Display**: get display information and list open windows\n\nFor complete documentation on automating desktop interactions, see [Computer Use](/docs/en/computer-use).\n\n> **Example**: Automated browser interaction\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Start VNC processes\nsandbox.computer_use.start()\n\n# Click to open browser\nsandbox.computer_use.mouse.click(50, 50)\n\n# Type a URL\nsandbox.computer_use.keyboard.type(\"https://www.daytona.io/docs/\")\nsandbox.computer_use.keyboard.press(\"Return\")\n\n# Take a screenshot\nscreenshot = sandbox.computer_use.screenshot.take_full_screen()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Start VNC processes\nawait sandbox.computerUse.start();\n\n// Click to open browser\nawait sandbox.computerUse.mouse.click(50, 50);\n\n// Type a URL\nawait sandbox.computerUse.keyboard.type('https://www.daytona.io/docs/');\nawait sandbox.computerUse.keyboard.press('Return');\n\n// Take a screenshot\nconst screenshot = await sandbox.computerUse.screenshot.takeFullScreen();\n```\n\n</TabItem>\n</Tabs>\n\n## Required packages\n\nThe default sandbox image includes all packages required for VNC and Computer Use. If you are using a custom image, you need to install the following packages.\n\n### VNC and desktop environment\n\n| Package              | Description                                |\n| -------------------- | ------------------------------------------ |\n| **`xvfb`**           | X Virtual Framebuffer for headless display |\n| **`xfce4`**          | Desktop environment                        |\n| **`xfce4-terminal`** | Terminal emulator                          |\n| **`x11vnc`**         | VNC server                                 |\n| **`novnc`**          | Web-based VNC client                       |\n| **`dbus-x11`**       | D-Bus session support                      |\n\n### X11 libraries\n\n| Library           | Description                                 |\n| ----------------- | ------------------------------------------- |\n| **`libx11-6`**    | X11 client library                          |\n| **`libxrandr2`**  | X11 RandR extension (display configuration) |\n| **`libxext6`**    | X11 extensions library                      |\n| **`libxrender1`** | X11 rendering extension                     |\n| **`libxfixes3`**  | X11 fixes extension                         |\n| **`libxss1`**     | X11 screen saver extension                  |\n| **`libxtst6`**    | X11 testing extension (input simulation)    |\n| **`libxi6`**      | X11 input extension                         |\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/volumes.mdx",
    "content": "---\ntitle: Volumes\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport Label from '@components/Label.astro'\n\nVolumes are FUSE-based mounts that provide shared file access across Daytona Sandboxes. They enable sandboxes to read from large files instantly - no need to upload files manually to each sandbox. Volume data is stored in an S3-compatible object store.\n\n- multiple volumes can be mounted to a single sandbox\n- a single volume can be mounted to multiple sandboxes\n\n## Create volumes\n\nDaytona provides volumes as a shared storage solution for sandboxes. To create a volume:\n\n1. Navigate to [Daytona Volumes ↗](https://app.daytona.io/dashboard/volumes)\n2. Click the **Create Volume** button\n3. Enter the volume name\n\nThe following snippets demonstrate how to create a volume using the Daytona SDK:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ndaytona = Daytona()\nvolume = daytona.volume.create(\"my-awesome-volume\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst daytona = new Daytona();\nconst volume = await daytona.volume.create(\"my-awesome-volume\");\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\ndaytona = Daytona::Daytona.new\nvolume = daytona.volume.create(\"my-awesome-volume\")\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nclient, err := daytona.NewClient()\nif err != nil {\n    log.Fatal(err)\n}\nvolume, err := client.Volume.Create(context.Background(), \"my-awesome-volume\")\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona volume create my-awesome-volume\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/volumes' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"name\": \"my-awesome-volume\"\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona) references:\n\n> [**volume.create (Python SDK)**](/docs/python-sdk/sync/volume/#volumeservicecreate)\n>\n> [**volume.create (TypeScript SDK)**](/docs/typescript-sdk/volume/#create)\n>\n> [**volume.create (Ruby SDK)**](/docs/ruby-sdk/volume-service/#create)\n>\n> [**Volume.Create (Go SDK)**](/docs/go-sdk/daytona/#VolumeService.Create)\n>\n> [**create volume (API)**](/docs/en/tools/api/#daytona/tag/volumes/POST/volumes)\n\n## Mount volumes\n\nDaytona provides an option to mount a volume to a sandbox. Once a volume is created, it can be mounted to a sandbox by specifying it in the `CreateSandboxFromSnapshotParams` object. Volume mount paths must meet the following requirements:\n\n- **Must be absolute paths**: Mount paths must start with `/` (e.g., `/home/daytona/volume`)\n- **Cannot be root directory**: Cannot mount to `/` or `//`\n- **No relative path components**: Cannot contain `/../`, `/./`, or end with `/..` or `/.`\n- **No consecutive slashes**: Cannot contain multiple consecutive slashes like `//` (except at the beginning)\n- **Cannot mount to system directories**: The following system directories are prohibited: `/proc`, `/sys`, `/dev`, `/boot`, `/etc`, `/bin`, `/sbin`, `/lib`, `/lib64`\n\nThe following snippets demonstrate how to mount a volume to a sandbox:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nimport os\nfrom daytona import CreateSandboxFromSnapshotParams, Daytona, VolumeMount\n\ndaytona = Daytona()\n\n# Create a new volume or get an existing one\nvolume = daytona.volume.get(\"my-volume\", create=True)\n\n# Mount the volume to the sandbox\nmount_dir_1 = \"/home/daytona/volume\"\n\nparams = CreateSandboxFromSnapshotParams(\n    language=\"python\",\n    volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_1)],\n)\nsandbox = daytona.create(params)\n\n# Mount a specific subpath within the volume\n# This is useful for isolating data or implementing multi-tenancy\nparams = CreateSandboxFromSnapshotParams(\n    language=\"python\",\n    volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_1, subpath=\"users/alice\")],\n)\nsandbox2 = daytona.create(params)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\nimport path from 'path'\n\nconst daytona = new Daytona()\n\n//  Create a new volume or get an existing one\nconst volume = await daytona.volume.get('my-volume', true)\n\n// Mount the volume to the sandbox\nconst mountDir1 = '/home/daytona/volume'\n\nconst sandbox1 = await daytona.create({\n  language: 'typescript',\n  volumes: [{ volumeId: volume.id, mountPath: mountDir1 }],\n})\n\n// Mount a specific subpath within the volume\n// This is useful for isolating data or implementing multi-tenancy\nconst sandbox2 = await daytona.create({\n  language: 'typescript',\n  volumes: [\n    { volumeId: volume.id, mountPath: mountDir1, subpath: 'users/alice' },\n  ],\n})\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Create a new volume or get an existing one\nvolume = daytona.volume.get('my-volume', create: true)\n\n# Mount the volume to the sandbox\nmount_dir = '/home/daytona/volume'\n\nparams = Daytona::CreateSandboxFromSnapshotParams.new(\n  language: Daytona::CodeLanguage::PYTHON,\n  volumes: [DaytonaApiClient::SandboxVolume.new(volume_id: volume.id, mount_path: mount_dir)]\n)\nsandbox = daytona.create(params)\n\n# Mount a specific subpath within the volume\n# This is useful for isolating data or implementing multi-tenancy\nparams2 = Daytona::CreateSandboxFromSnapshotParams.new(\n  language: Daytona::CodeLanguage::PYTHON,\n  volumes: [DaytonaApiClient::SandboxVolume.new(\n    volume_id: volume.id,\n    mount_path: mount_dir,\n    subpath: 'users/alice'\n  )]\n)\nsandbox2 = daytona.create(params2)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nclient, err := daytona.NewClient()\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Create a new volume or get an existing one\nvolume, err := client.Volume.Get(context.Background(), \"my-volume\")\nif err != nil {\n\t// If volume doesn't exist, create it\n\tvolume, err = client.Volume.Create(context.Background(), \"my-volume\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\n// Mount the volume to the sandbox\nmountDir := \"/home/daytona/volume\"\n\nsandbox1, err := client.Create(context.Background(), types.SnapshotParams{\n\tSandboxBaseParams: types.SandboxBaseParams{\n\t\tLanguage: types.CodeLanguagePython,\n\t\tVolumes: []types.VolumeMount{\n\t\t\t{VolumeID: volume.ID, MountPath: mountDir},\n\t\t},\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\n\n// Mount a specific subpath within the volume\n// This is useful for isolating data or implementing multi-tenancy\nsubpath := \"users/alice\"\nsandbox2, err := client.Create(context.Background(), types.SnapshotParams{\n\tSandboxBaseParams: types.SandboxBaseParams{\n\t\tLanguage: types.CodeLanguagePython,\n\t\tVolumes: []types.VolumeMount{\n\t\t\t{VolumeID: volume.ID, MountPath: mountDir, Subpath: &subpath},\n\t\t},\n\t},\n})\nif err != nil {\n\tlog.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona volume create my-volume\ndaytona create --volume my-volume:/home/daytona/volume\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox' \\\n  --request POST \\\n  --header 'Authorization: Bearer <API_KEY>' \\\n  --header 'Content-Type: application/json' \\\n  --data '{\n  \"volumes\": [\n    {\n      \"volumeId\": \"<VOLUME_ID>\",\n      \"mountPath\": \"/home/daytona/volume\"\n    }\n  ]\n}'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona) references:\n\n> [**CreateSandboxFromSnapshotParams (Python SDK)**](/docs/python-sdk/sync/daytona#createsandboxfromsnapshotparams)\n>\n> [**CreateSandboxFromSnapshotParams (TypeScript SDK)**](/docs/typescript-sdk/daytona#createsandboxfromsnapshotparams)\n>\n> [**create (Ruby SDK)**](/docs/en/ruby-sdk/daytona#create)\n>\n> [**Create (Go SDK)**](/docs/en/go-sdk/daytona/#Client.Create)\n>\n> [**create sandbox (API)**](/docs/en/tools/api/#daytona/tag/sandbox/POST/sandbox)\n\n## Work with volumes\n\nDaytona provides an option to read from and write to the volume just like any other directory in the sandbox file system. Files written to the volume persist beyond the lifecycle of any individual sandbox.\n\nThe following snippet demonstrate how to read from and write to a volume:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\n# Write to a file in the mounted volume using the Sandbox file system API\nsandbox.fs.upload_file(b\"Hello from Daytona volume!\", \"/home/daytona/volume/example.txt\")\n\n# When you're done with the sandbox, you can remove it\n# The volume will persist even after the sandbox is removed\nsandbox.delete()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\n// Write to a file in the mounted volume using the Sandbox file system API\nawait sandbox1.fs.uploadFile(Buffer.from('Hello from Daytona volume!'), '/home/daytona/volume/example.txt')\n\n// When you're done with the sandbox, you can remove it\n// The volume will persist even after the sandbox is removed\nawait daytona.delete(sandbox1)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\n# Write to a file in the mounted volume using the Sandbox file system API\nsandbox.fs.upload_file('Hello from Daytona volume!', '/home/daytona/volume/example.txt')\n\n# When you're done with the sandbox, you can remove it\n# The volume will persist even after the sandbox is removed\ndaytona.delete(sandbox)\n```\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nimport (\n    \"context\"\n    \"log\"\n)\n\n// Write to a file in the mounted volume\nerr := sandbox1.FileSystem.UploadFile(context.Background(), []byte(\"Hello from Daytona volume!\"), \"/home/daytona/volume/example.txt\")\nif err != nil {\n    log.Fatal(err)\n}\n\n// When you're done with the sandbox, you can remove it\n// The volume will persist even after the sandbox is removed\nerr = sandbox1.Delete(context.Background())\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), and [Go SDK](/docs/en/go-sdk/) references.\n\n## Get a volume by name\n\nDaytona provides an option to get a volume by its name.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ndaytona = Daytona()\nvolume = daytona.volume.get(\"my-awesome-volume\", create=True)\nprint(f\"{volume.name} ({volume.id})\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst daytona = new Daytona()\nconst volume = await daytona.volume.get('my-awesome-volume', true)\nconsole.log(`Volume ${volume.name} is in state ${volume.state}`)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\ndaytona = Daytona::Daytona.new\nvolume = daytona.volume.get('my-awesome-volume', create: true)\nputs \"#{volume.name} (#{volume.id})\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nclient, err := daytona.NewClient()\nif err != nil {\n    log.Fatal(err)\n}\nvolume, err := client.Volume.Get(context.Background(), \"my-awesome-volume\")\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Printf(\"Volume %s is in state %s\\n\", volume.Name, volume.State)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona volume get my-awesome-volume\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/volumes/by-name/my-awesome-volume' \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona) references:\n\n> [**volume.get (Python SDK)**](/docs/en/python-sdk/sync/volume#volumeserviceget)\n>\n> [**volume.get (TypeScript SDK)**](/docs/en/typescript-sdk/volume#get)\n>\n> [**volume.get (Ruby SDK)**](/docs/ruby-sdk/volume-service#get)\n>\n> [**Volume.Get (Go SDK)**](/docs/go-sdk/daytona/#VolumeService.Get)\n>\n> [**get volume by name (API)**](/docs/en/tools/api/#daytona/tag/volumes/GET/volumes/by-name/{name})\n\n## List volumes\n\nDaytona provides an option to list all volumes.\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\ndaytona = Daytona()\nvolumes = daytona.volume.list()\nfor volume in volumes:\n    print(f\"{volume.name} ({volume.id})\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst daytona = new Daytona()\nconst volumes = await daytona.volume.list()\nconsole.log(`Found ${volumes.length} volumes`)\nvolumes.forEach(vol => console.log(`${vol.name} (${vol.id})`))\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\ndaytona = Daytona::Daytona.new\nvolumes = daytona.volume.list\nvolumes.each do |volume|\n  puts \"#{volume.name} (#{volume.id})\"\nend\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nclient, err := daytona.NewClient()\nif err != nil {\n    log.Fatal(err)\n}\nvolumes, err := client.Volume.List(context.Background())\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Printf(\"Found %d volumes\\n\", len(volumes))\nfor _, vol := range volumes {\n    fmt.Printf(\"%s (%s)\\n\", vol.Name, vol.ID)\n}\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona volume list\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/volumes' \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona) references:\n\n> [**volume.list (Python SDK)**](/docs/en/python-sdk/sync/volume#volumeservicelist)\n>\n> [**volume.list (TypeScript SDK)**](/docs/en/typescript-sdk/volume#list)\n>\n> [**volume.list (Ruby SDK)**](/docs/ruby-sdk/volume-service#list)\n>\n> [**Volume.List (Go SDK)**](/docs/go-sdk/daytona/#VolumeService.List)\n>\n> [**list volumes (API)**](/docs/en/tools/api/#daytona/tag/volumes/GET/volumes)\n\n## Delete volumes\n\nDaytona provides an option to delete a volume. Deleted volumes cannot be recovered.\n\nThe following snippet demonstrate how to delete a volume:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nvolume = daytona.volume.get(\"my-volume\", create=True)\ndaytona.volume.delete(volume)\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst volume = await daytona.volume.get('my-volume', true)\nawait daytona.volume.delete(volume)\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nvolume = daytona.volume.get('my-volume', create: true)\ndaytona.volume.delete(volume)\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nclient, err := daytona.NewClient()\nif err != nil {\n    log.Fatal(err)\n}\nvolume, err := client.Volume.Get(context.Background(), \"my-volume\")\nif err != nil {\n    log.Fatal(err)\n}\nerr = client.Volume.Delete(context.Background(), volume)\nif err != nil {\n    log.Fatal(err)\n}\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```shell\ndaytona volume delete <VOLUME_ID>\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/volumes/<VOLUME_ID>' \\\n  --request DELETE \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\nFor more information, see the [Python SDK](/docs/en/python-sdk/), [TypeScript SDK](/docs/en/typescript-sdk/), [Ruby SDK](/docs/en/ruby-sdk/), [Go SDK](/docs/en/go-sdk/), and [API](/docs/en/tools/api/#daytona) references:\n\n> [**volume.delete (Python SDK)**](/docs/python-sdk/sync/volume/#volumeservicedelete)\n>\n> [**volume.delete (TypeScript SDK)**](/docs/typescript-sdk/volume/#delete)\n>\n> [**volume.delete (Ruby SDK)**](/docs/ruby-sdk/volume-service/#delete)\n>\n> [**Volume.Delete (Go SDK)**](/docs/go-sdk/daytona/#VolumeService.Delete)\n>\n> [**delete volume (API)**](/docs/en/tools/api/#daytona/tag/volumes/DELETE/volumes/{volumeId})\n\n## Limitations\n\nSince volumes are FUSE-based mounts, they can not be used for applications that require block storage access (like database tables).\nVolumes are generally slower for both read and write operations compared to the local sandbox file system.\n\n## Pricing & Limits\n\nDaytona Volumes are included at no additional cost. Each organization can create up to 100 volumes, and volume data does not count against your storage quota.\n\nYou can view your current volume usage in the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/volumes).\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/vpn-connections.mdx",
    "content": "---\ntitle: VPN Connections\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nVPN connections are a way to connect your Daytona Sandboxes to private networks. By establishing a VPN connection, your sandbox can access network resources using private IP addresses and can be accessed by other devices on the same VPN network.\n\nThis integration enables communication between your development environment and existing infrastructure, allowing you to test applications against services within the private network, access shared development resources, and collaborate with team members.\n\nDaytona supports the following VPN network providers:\n\n- [Tailscale](#tailscale)\n- [OpenVPN](#openvpn)\n\n:::note\nFor connecting to a VPN network, you need to [create or access your Daytona Sandbox](/docs/en/sandboxes), **have access to your VPN network provider credentials**, and be on [**Tier 3** or higher](/docs/en/limits#resources).\n:::\n\n## Tailscale\n\nDaytona provides multiple ways to connect to a Daytona Sandbox with a Tailscale network:\n\n- [Connect with browser login](#connect-with-browser-login)\n- [Connect with auth key](#connect-with-auth-key)\n- [Connect with web terminal](#connect-with-web-terminal)\n\nWhen you connect a Daytona Sandbox to a Tailscale network, the sandbox becomes part of your private Tailscale network, allowing you to access resources that are available within the network and enabling other devices on the network to access the sandbox.\n\nThis integration makes your sandbox appear as a device within your Tailscale network, with its own Tailscale IP address and access to other devices and services on the network.\n\n### Connect with browser login\n\nThe browser login method initiates an interactive authentication flow where Tailscale generates a unique login URL that you visit in your web browser to authenticate the Dayona Sandbox.\n\nThe process involves installing Tailscale, starting the daemon, initiating the login process, and then polling for the authentication status until the connection is established.\n\nThe following snippet demonstrates connecting to a Tailscale network using a browser login.\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, DaytonaConfig\nimport time\nimport re\n\n# Configuration\nDAYTONA_API_KEY = \"YOUR_API_KEY\" # Replace with your API key\n\n# Initialize the Daytona client\nconfig = DaytonaConfig(api_key=DAYTONA_API_KEY)\ndaytona = Daytona(config)\n\ndef setup_tailscale_vpn_interactive():\n    \"\"\"\n    Connect a Daytona sandbox to a Tailscale network using the Python SDK.\n    Uses interactive login via browser URL (no auth key required).\n    \"\"\"\n    # Create the sandbox\n    print(\"Creating sandbox...\")\n    sandbox = daytona.create()\n    print(f\"Sandbox created: {sandbox.id}\")\n\n    # Step 1: Install Tailscale\n    print(\"\\nInstalling Tailscale (this may take a few minutes)...\")\n    response = sandbox.process.exec(\n        \"curl -fsSL https://tailscale.com/install.sh | sh\",\n        timeout=300\n    )\n    if response.exit_code != 0:\n        print(f\"Error installing Tailscale: {response.result}\")\n        return sandbox\n    print(\"Tailscale installed successfully.\")\n\n    # Step 2: Start tailscaled daemon in background\n    print(\"\\nStarting tailscaled daemon...\")\n    sandbox.process.exec(\"nohup sudo tailscaled > /dev/null 2>&1 &\", timeout=10)\n\n    # Wait for daemon to initialize\n    time.sleep(3)\n\n    # Step 3: Run tailscale up in background and capture output to a file\n    print(\"\\nInitiating Tailscale login...\")\n    sandbox.process.exec(\n        \"sudo tailscale up > /tmp/tailscale-login.txt 2>&1 &\",\n        timeout=10\n    )\n\n    # Wait for the login URL to be written to the file\n    time.sleep(3)\n\n    # Read the login URL from the output file\n    response = sandbox.process.exec(\"cat /tmp/tailscale-login.txt\", timeout=10)\n    output = response.result\n    url_match = re.search(r'https://login\\.tailscale\\.com/a/[^\\s]+', output)\n\n    if url_match:\n        login_url = url_match.group(0)\n        print(f\"\\n{'='*60}\")\n        print(\"To authenticate, visit this URL in your browser:\")\n        print(f\"\\n  {login_url}\")\n        print(f\"\\n{'='*60}\")\n        print(\"\\nWaiting for authentication...\")\n\n        # Poll for connection status\n        max_wait = 300\n        poll_interval = 5\n        waited = 0\n\n        while waited < max_wait:\n            time.sleep(poll_interval)\n            waited += poll_interval\n\n            status_response = sandbox.process.exec(\"tailscale status 2>&1\", timeout=30)\n            status_output = status_response.result\n\n            # Check if connected\n            if status_response.exit_code == 0 and \"logged out\" not in status_output.lower():\n                # Verify IP is assigned\n                ip_response = sandbox.process.exec(\"tailscale ip -4 2>&1\", timeout=10)\n                if ip_response.exit_code == 0 and ip_response.result.strip():\n                    print(f\"\\nConnected to Tailscale network!\")\n                    print(f\"Tailscale IP: {ip_response.result.strip()}\")\n                    break\n\n            print(f\"  Still waiting... ({waited}s)\")\n        else:\n            print(\"\\nTimeout waiting for authentication. Please try again.\")\n            return sandbox\n    else:\n        # Already connected or different output\n        print(f\"Output from tailscale up:\\n{output}\")\n\n        # Check if already connected\n        status_response = sandbox.process.exec(\"tailscale status\", timeout=30)\n        if status_response.exit_code == 0:\n            print(\"\\nTailscale status:\")\n            print(status_response.result)\n\n    # Final status check\n    print(\"\\nFinal Tailscale status:\")\n    response = sandbox.process.exec(\"tailscale status\", timeout=30)\n    print(response.result)\n\n    return sandbox\n\nif __name__ == \"__main__\":\n    sandbox = setup_tailscale_vpn_interactive()\n\n```\n\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\n\n// Configuration\nconst DAYTONA_API_KEY = 'YOUR_API_KEY' // Replace with your API key\n\n// Initialize the Daytona client\nconst daytona = new Daytona({\n  apiKey: DAYTONA_API_KEY,\n})\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nasync function setupTailscaleVpnInteractive(): Promise<void> {\n  /**\n   * Connect a Daytona sandbox to a Tailscale network using the TypeScript SDK.\n   * Uses interactive login via browser URL (no auth key required).\n   */\n\n  // Create the sandbox\n  console.log('Creating sandbox...')\n  const sandbox = await daytona.create()\n  console.log(`Sandbox created: ${sandbox.id}`)\n\n  // Step 1: Install Tailscale\n  console.log('\\nInstalling Tailscale (this may take a few minutes)...')\n  let response = await sandbox.process.executeCommand(\n    'curl -fsSL https://tailscale.com/install.sh | sh',\n    undefined, // cwd\n    undefined, // env\n    300 // timeout\n  )\n  if (response.exitCode !== 0) {\n    console.log(`Error installing Tailscale: ${response.result}`)\n    return\n  }\n  console.log('Tailscale installed successfully.')\n\n  // Step 2: Start tailscaled daemon in background\n  console.log('\\nStarting tailscaled daemon...')\n  await sandbox.process.executeCommand(\n    'nohup sudo tailscaled > /dev/null 2>&1 &',\n    undefined, // cwd\n    undefined, // env\n    10 // timeout\n  )\n\n  // Wait for daemon to initialize\n  await sleep(3000)\n\n  // Step 3: Run tailscale up in background and capture output to a file\n  console.log('\\nInitiating Tailscale login...')\n  await sandbox.process.executeCommand(\n    'sudo tailscale up > /tmp/tailscale-login.txt 2>&1 &',\n    undefined, // cwd\n    undefined, // env\n    10 // timeout\n  )\n\n  // Wait for the login URL to be written to the file\n  await sleep(3000)\n\n  // Read the login URL from the output file\n  response = await sandbox.process.executeCommand(\n    'cat /tmp/tailscale-login.txt',\n    undefined, // cwd\n    undefined, // env\n    10 // timeout\n  )\n  const output = response.result || ''\n  const urlMatch = output.match(/https:\\/\\/login\\.tailscale\\.com\\/a\\/[^\\s]+/)\n\n  if (urlMatch) {\n    const loginUrl = urlMatch[0]\n    console.log('\\n' + '='.repeat(60))\n    console.log('To authenticate, visit this URL in your browser:')\n    console.log(`\\n  ${loginUrl}`)\n    console.log('\\n' + '='.repeat(60))\n    console.log('\\nWaiting for authentication...')\n\n    // Poll for connection status\n    const maxWait = 300 // 5 minutes max wait\n    const pollInterval = 5\n    let waited = 0\n\n    while (waited < maxWait) {\n      await sleep(pollInterval * 1000)\n      waited += pollInterval\n\n      const statusResponse = await sandbox.process.executeCommand(\n        'tailscale status 2>&1',\n        undefined, // cwd\n        undefined, // env\n        30 // timeout\n      )\n      const statusOutput = statusResponse.result || ''\n\n      // Check if we're connected (status shows our machine without login prompt)\n      if (\n        statusResponse.exitCode === 0 &&\n        !statusOutput.toLowerCase().includes('logged out')\n      ) {\n        // Verify we have an IP assigned\n        const ipResponse = await sandbox.process.executeCommand(\n          'tailscale ip -4 2>&1',\n          undefined, // cwd\n          undefined, // env\n          10 // timeout\n        )\n        if (ipResponse.exitCode === 0 && ipResponse.result?.trim()) {\n          console.log('\\nConnected to Tailscale network!')\n          console.log(`Tailscale IP: ${ipResponse.result.trim()}`)\n          break\n        }\n      }\n\n      console.log(`  Still waiting... (${waited}s)`)\n    }\n\n    if (waited >= maxWait) {\n      console.log('\\nTimeout waiting for authentication. Please try again.')\n      return\n    }\n  } else {\n    // Maybe already connected or different output\n    console.log(`Output from tailscale up:\\n${output}`)\n\n    // Check if already connected\n    const statusResponse = await sandbox.process.executeCommand(\n      'tailscale status',\n      undefined, // cwd\n      undefined, // env\n      30 // timeout\n    )\n    if (statusResponse.exitCode === 0) {\n      console.log('\\nTailscale status:')\n      console.log(statusResponse.result)\n    }\n  }\n\n  // Final status check\n  console.log('\\nFinal Tailscale status:')\n  response = await sandbox.process.executeCommand(\n    'tailscale status',\n    undefined, // cwd\n    undefined, // env\n    30 // timeout\n  )\n  console.log(response.result)\n}\n\n// Run the main function\nsetupTailscaleVpnInteractive().catch(console.error)\n```\n\n  </TabItem>\n</Tabs>\n\nOnce the connection is established and authentication is complete, the sandbox will maintain its connection as long as the service is running.\n\n### Connect with auth key\n\nUsing an auth key provides a non-interactive way to connect your Daytona Sandbox to Tailscale, making it suitable for automated scripts, CI/CD pipelines, or any scenario where manual browser interaction is not available.\n\n1. Access your [Tailscale admin console ↗](https://login.tailscale.com/admin/machines)\n2. Click **Add device** and select **Linux server**\n3. Apply the configuration and click **Generate install script**\n\nThis will generate a script that you can use to install Tailscale and connect to the Tailscale network.\n\n```bash\ncurl -fsSL https://tailscale.com/install.sh | sh && sudo tailscale up --auth-key=tskey-auth-<AUTH_KEY>\n```\n\nCopy the auth key from the generated script and use it to connect your Daytona Sandbox to Tailscale:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nfrom daytona import Daytona, DaytonaConfig\nimport time\n\n# Configuration\nDAYTONA_API_KEY = \"YOUR_API_KEY\" # Replace with your API key\nTAILSCALE_AUTH_KEY = \"YOUR_AUTH_KEY\" # Replace with your auth key\n\n# Initialize the Daytona client\nconfig = DaytonaConfig(api_key=DAYTONA_API_KEY)\ndaytona = Daytona(config)\n\n\ndef setup_tailscale_vpn(auth_key: str):\n\"\"\"\nConnect a Daytona sandbox to a Tailscale network using the Python SDK.\nUses auth-key for non-interactive authentication.\n\"\"\"\n# Create the sandbox\nprint(\"Creating sandbox...\")\nsandbox = daytona.create()\nprint(f\"Sandbox created: {sandbox.id}\")\n\n# Step 1: Install Tailscale\nprint(\"\\nInstalling Tailscale (this may take a few minutes)...\")\nresponse = sandbox.process.exec(\n    \"curl -fsSL https://tailscale.com/install.sh | sh\",\n    timeout=300\n)\nif response.exit_code != 0:\n    print(f\"Error installing Tailscale: {response.result}\")\n    return sandbox\nprint(\"Tailscale installed successfully.\")\n\n# Step 2: Start tailscaled daemon manually (systemd doesn't auto-start in sandboxes)\nprint(\"\\nStarting tailscaled daemon...\")\nsandbox.process.exec(\"nohup sudo tailscaled > /dev/null 2>&1 &\", timeout=10)\n\n# Wait for daemon to initialize\ntime.sleep(3)\n\n  # Step 3: Connect with auth key\n  print(\"\\nConnecting to Tailscale network...\")\n  response = sandbox.process.exec(\n      f\"sudo tailscale up --auth-key={auth_key}\",\n      timeout=60\n  )\n\n  if response.exit_code != 0:\n      print(f\"Error connecting: {response.result}\")\n      return sandbox\n\n  print(\"Connected to Tailscale network.\")\n\n  # Verify connection status\n  print(\"\\nChecking Tailscale status...\")\n  response = sandbox.process.exec(\"tailscale status\", timeout=30)\n  print(f\"Status:\\n{response.result}\")\n\n  return sandbox\n\n\nif __name__ == \"__main__\":\n  sandbox = setup_tailscale_vpn(TAILSCALE_AUTH_KEY)\n\n```\n\n</TabItem>\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\n\n// Configuration\nconst DAYTONA_API_KEY = 'YOUR_API_KEY' // Replace with your API key\nconst TAILSCALE_AUTH_KEY = 'YOUR_AUTH_KEY' // Replace with your auth key\n\n// Initialize the Daytona client\nconst daytona = new Daytona({\n  apiKey: DAYTONA_API_KEY,\n})\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nasync function setupTailscaleVpn(authKey: string): Promise<void> {\n  /**\n   * Connect a Daytona sandbox to a Tailscale network using the TypeScript SDK.\n   * Uses auth-key for non-interactive authentication.\n   */\n\n  // Create the sandbox\n  console.log('Creating sandbox...')\n  const sandbox = await daytona.create()\n  console.log(`Sandbox created: ${sandbox.id}`)\n\n  // Step 1: Install Tailscale\n  console.log('\\nInstalling Tailscale (this may take a few minutes)...')\n  let response = await sandbox.process.executeCommand(\n    'curl -fsSL https://tailscale.com/install.sh | sh',\n    undefined, // cwd\n    undefined, // env\n    300 // timeout\n  )\n  if (response.exitCode !== 0) {\n    console.log(`Error installing Tailscale: ${response.result}`)\n    return\n  }\n  console.log('Tailscale installed successfully.')\n\n  // Step 2: Start tailscaled daemon manually (systemd doesn't auto-start in sandboxes)\n  console.log('\\nStarting tailscaled daemon...')\n  await sandbox.process.executeCommand(\n    'nohup sudo tailscaled > /dev/null 2>&1 &',\n    undefined, // cwd\n    undefined, // env\n    10 // timeout\n  )\n\n  // Wait for daemon to initialize\n  await sleep(3000)\n\n  // Step 3: Connect with auth key\n  console.log('\\nConnecting to Tailscale network...')\n  response = await sandbox.process.executeCommand(\n    `sudo tailscale up --auth-key=${authKey}`,\n    undefined, // cwd\n    undefined, // env\n    60 // timeout\n  )\n\n  if (response.exitCode !== 0) {\n    console.log(`Error connecting: ${response.result}`)\n    return\n  }\n\n  console.log('Connected to Tailscale network.')\n\n  // Verify connection status\n  console.log('\\nChecking Tailscale status...')\n  response = await sandbox.process.executeCommand(\n    'tailscale status',\n    undefined, // cwd\n    undefined, // env\n    30 // timeout\n  )\n  console.log(`Status:\\n${response.result}`)\n}\n\n// Run the main function\nsetupTailscaleVpn(TAILSCALE_AUTH_KEY).catch(console.error)\n```\n\n</TabItem>\n</Tabs>\n\nOnce the connection is established and authentication is complete, the sandbox will maintain its connection as long as the service is running.\n\n### Connect with web terminal\n\nFor working directly in the terminal or for more control over the Tailscale connection process, you can set up Tailscale manually through the Daytona [web terminal](/docs/en/web-terminal) or [SSH](/docs/en/ssh-access).\n\nThis approach provides visibility into each step of the installation and connection process, and allows you to customize the setup if needed. The process involves installing Tailscale, starting the daemon in a persistent session using tmux, and then authenticating through the interactive login flow.\n\n1. Navigate to your sandbox [web terminal](/docs/en/web-terminal) in [Daytona Dashboard ↗](https://app.daytona.io/), or [access it via SSH](/docs/en/ssh-access)\n2. Install Tailscale using the official installation script:\n\n```bash\ncurl -fsSL https://tailscale.com/install.sh | sh\n```\n\nThis begins the Tailscale installation process and initializes the Tailscale CLI inside the sandbox. Daytona requires the Tailscale daemon to be running in the background to connect the sandbox to the Tailscale network.\n\nThe recommended approach is to run it in a detached tmux (or similar) session to ensure the daemon is running in the background:\n\n3. Install tmux\n\n```bash\nsudo apt install tmux\n```\n\n4. Start the Tailscale daemon in a detached tmux session\n\n```bash\ntmux new -d -s tailscale 'sudo tailscaled'\n```\n\n5. Connect and authenticate your sandbox with the Tailscale network\n\n```bash\nsudo tailscale up\n```\n\n6. Visit the authentication URL in the web browser and follow the instructions to authenticate\n\n```txt\nTo authenticate, visit:\nhttps://login.tailscale.com/a/<id>\n```\n\nOnce authenticated, you will see the following confirmation message:\n\n```txt\nYour device <id> is logged in to the <address> tailnet.\n```\n\nYou've now successfully connected your Daytona sandbox to your Tailscale network. The sandbox should appear in your [Tailscale dashboard](https://login.tailscale.com/admin/machines).\n\n## OpenVPN\n\nDaytona provides multiple ways to connect to a Daytona Sandbox with an OpenVPN network:\n\n- [Connect with client configuration](#connect-with-client-configuration)\n- [Connect with web terminal](#connect-with-web-terminal)\n\nOpenVPN uses a client-server model where your Daytona Sandbox acts as a client connecting to an OpenVPN server. This approach is suitable for connecting to existing corporate VPNs, accessing resources behind firewalls, or integrating with infrastructure that already uses OpenVPN.\n\n:::note\nConnecting a Daytona Sandbox to OpenVPN network requires a [client configuration file](#client-configuration-file).\n:::\n\n### Client configuration file\n\nClient configuration file contains the connection parameters, certificates, and keys required to establish a secure connection to your OpenVPN server. This file is typically provided by your network administrator or generated from your OpenVPN server setup.\n\nThe configuration file should be named `client.ovpn` or similar, and it must contain all the required connection settings, including server address, port, protocol, encryption settings, and authentication credentials. To create this file, you can use a text editor such as nano or vim, or upload it to your sandbox if you have it prepared elsewhere.\n\nThe following snippet is an example of a client configuration file. Replace the placeholders with the actual values provided by your OpenVPN server.\n\n```bash\nclient\nproto udp\nexplicit-exit-notify\nremote <YOUR_OPENVPN_SERVER_IP> <YOUR_OPENVPN_SERVER_PORT>\ndev tun\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\nremote-cert-tls server\nverify-x509-name <YOUR_OPENVPN_SERVER_NAME> name\nauth SHA256\nauth-nocache\ncipher AES-128-GCM\nignore-unknown-option data-ciphers\ndata-ciphers AES-128-GCM\nncp-ciphers AES-128-GCM\ntls-client\ntls-version-min 1.2\ntls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256\ntls-ciphersuites TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256\nignore-unknown-option block-outside-dns\nsetenv opt block-outside-dns # Prevent Windows 10 DNS leak\nverb 3\n<ca>\n-----BEGIN CERTIFICATE-----\n<YOUR_OPENVPN_SERVER_CERTIFICATE>\n-----END CERTIFICATE-----\n</ca>\n<cert>\n-----BEGIN CERTIFICATE-----\n<YOUR_OPENVPN_CLIENT_CERTIFICATE>\n-----END CERTIFICATE-----\n</cert>\n<key>\n-----BEGIN PRIVATE KEY-----\n<YOUR_OPENVPN_CLIENT_PRIVATE_KEY>\n-----END PRIVATE KEY-----\n</key>\n<tls-crypt-v2>\n-----BEGIN OpenVPN tls-crypt-v2 client key-----\n<YOUR_OPENVPN_TLS_CRYPT_V2_CLIENT_KEY>\n-----END OpenVPN tls-crypt-v2 client key-----\n</tls-crypt-v2>\n```\n\n### Connect with client configuration\n\n<Tabs>\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\nfrom daytona import Daytona, DaytonaConfig\nimport time\n\n# Configuration\nDAYTONA_API_KEY = \"YOUR_API_KEY\" # Replace with your API key\n\n# OpenVPN client configuration (paste your .ovpn config here)\nOPENVPN_CONFIG = \"\"\"\n\"\"\".strip()\n\n# Initialize the Daytona client\nconfig = DaytonaConfig(api_key=DAYTONA_API_KEY)\ndaytona = Daytona(config)\n\n\ndef setup_openvpn(ovpn_config: str):\n    \"\"\"\n    Connect a Daytona sandbox to an OpenVPN network using the Python SDK.\n    \"\"\"\n    # Create the sandbox\n    print(\"Creating sandbox...\")\n    sandbox = daytona.create()\n    print(f\"Sandbox created: {sandbox.id}\")\n\n    # Step 1: Install OpenVPN\n    print(\"\\nInstalling OpenVPN...\")\n    response = sandbox.process.exec(\n        \"sudo apt update && sudo apt install -y openvpn\",\n        timeout=120\n    )\n    if response.exit_code != 0:\n        print(f\"Error installing OpenVPN: {response.result}\")\n        return sandbox\n    print(\"OpenVPN installed successfully.\")\n\n    # Step 2: Write the OpenVPN config file\n    print(\"\\nWriting OpenVPN configuration...\")\n    sandbox.fs.upload_file(ovpn_config.encode(), \"/home/daytona/client.ovpn\")\n    print(\"Configuration written to /home/daytona/client.ovpn\")\n\n    # Step 3: Start OpenVPN in background\n    print(\"\\nStarting OpenVPN tunnel...\")\n    sandbox.process.exec(\n        \"nohup sudo openvpn /home/daytona/client.ovpn > /tmp/openvpn.log 2>&1 &\",\n        timeout=10\n    )\n\n    # Wait for connection to establish\n    print(\"Waiting for VPN connection to establish...\")\n    time.sleep(10)\n\n    # Step 4: Verify connection\n    print(\"\\nVerifying OpenVPN connection...\")\n\n    # Check if tun interface exists\n    response = sandbox.process.exec(\"ip addr show tun0\", timeout=10)\n    if response.exit_code == 0:\n        print(\"VPN tunnel interface (tun0) is up:\")\n        print(response.result)\n    else:\n        print(\"Warning: tun0 interface not found. Checking OpenVPN logs...\")\n        log_response = sandbox.process.exec(\"cat /tmp/openvpn.log\", timeout=10)\n        print(f\"OpenVPN log:\\n{log_response.result}\")\n        return sandbox\n\n    # Get public IP through VPN\n    print(\"\\nChecking public IP (should be VPN server IP)...\")\n    response = sandbox.process.exec(\"curl -s ifconfig.me\", timeout=30)\n    if response.exit_code == 0:\n        print(f\"Public IP: {response.result}\")\n    else:\n        print(f\"Could not determine public IP: {response.result}\")\n\n    print(\"\\nOpenVPN connection established successfully.\")\n    return sandbox\n\n\nif __name__ == \"__main__\":\n    sandbox = setup_openvpn(OPENVPN_CONFIG)\n\n    ```\n  </TabItem>\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\n// Configuration\nconst DAYTONA_API_KEY = \"YOUR_API_KEY\"; // Replace with your API key\n\n// OpenVPN client configuration (paste your .ovpn config here)\nconst OPENVPN_CONFIG = `\n`.trim();\n\n// Initialize the Daytona client\nconst daytona = new Daytona({\n  apiKey: DAYTONA_API_KEY,\n});\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nasync function setupOpenvpn(ovpnConfig: string): Promise<void> {\n  /**\n   * Connect a Daytona sandbox to an OpenVPN network using the TypeScript SDK.\n   */\n\n  // Create the sandbox\n  console.log(\"Creating sandbox...\");\n  const sandbox = await daytona.create();\n  console.log(`Sandbox created: ${sandbox.id}`);\n\n  // Step 1: Install OpenVPN\n  console.log(\"\\nInstalling OpenVPN...\");\n  let response = await sandbox.process.executeCommand(\n    \"sudo apt update && sudo apt install -y openvpn\",\n    undefined,  // cwd\n    undefined,  // env\n    120         // timeout\n  );\n  if (response.exitCode !== 0) {\n    console.log(`Error installing OpenVPN: ${response.result}`);\n    return;\n  }\n  console.log(\"OpenVPN installed successfully.\");\n\n  // Step 2: Write the OpenVPN config file\n  console.log(\"\\nWriting OpenVPN configuration...\");\n  // Use heredoc to write the config file\n  await sandbox.process.executeCommand(\n    `cat << 'OVPNEOF' > /home/daytona/client.ovpn\n${ovpnConfig}\nOVPNEOF`,\n    undefined,\n    undefined,\n    30\n  );\n  console.log(\"Configuration written to /home/daytona/client.ovpn\");\n\n  // Step 3: Start OpenVPN in background\n  console.log(\"\\nStarting OpenVPN tunnel...\");\n  await sandbox.process.executeCommand(\n    \"nohup sudo openvpn /home/daytona/client.ovpn > /tmp/openvpn.log 2>&1 &\",\n    undefined,  // cwd\n    undefined,  // env\n    10          // timeout\n  );\n\n  // Wait for connection to establish\n  console.log(\"Waiting for VPN connection to establish...\");\n  await sleep(10000);\n\n  // Step 4: Verify connection\n  console.log(\"\\nVerifying OpenVPN connection...\");\n\n  // Check if tun interface exists\n  response = await sandbox.process.executeCommand(\n    \"ip addr show tun0\",\n    undefined,  // cwd\n    undefined,  // env\n    10          // timeout\n  );\n  if (response.exitCode === 0) {\n    console.log(\"VPN tunnel interface (tun0) is up:\");\n    console.log(response.result);\n  } else {\n    console.log(\"Warning: tun0 interface not found. Checking OpenVPN logs...\");\n    const logResponse = await sandbox.process.executeCommand(\n      \"cat /tmp/openvpn.log\",\n      undefined,  // cwd\n      undefined,  // env\n      10          // timeout\n    );\n    console.log(`OpenVPN log:\\n${logResponse.result}`);\n    return;\n  }\n\n  // Get public IP through VPN\n  console.log(\"\\nChecking public IP (should be VPN server IP)...\");\n  response = await sandbox.process.executeCommand(\n    \"curl -s ifconfig.me\",\n    undefined,  // cwd\n    undefined,  // env\n    30          // timeout\n  );\n  if (response.exitCode === 0) {\n    console.log(`Public IP: ${response.result}`);\n  } else {\n    console.log(`Could not determine public IP: ${response.result}`);\n  }\n\n  console.log(\"\\nOpenVPN connection established successfully.\");\n}\n\n// Run the main function\nsetupOpenvpn(OPENVPN_CONFIG).catch(console.error);\n\n    ```\n  </TabItem>\n</Tabs>\n\n### Connect with web terminal\n\nDaytona provides a [web terminal](/docs/en/web-terminal) for interacting with your sandboxes, allowing you to install OpenVPN and connect to your OpenVPN network.\n\n1. Navigate to your sandbox [web terminal](/docs/en/web-terminal) in [Daytona Dashboard ↗](https://app.daytona.io/) by clicking on the Terminal icon `>_`, or [access it via SSH](/docs/en/ssh-access)\n\n2. Install OpenVPN and tmux\n\n```bash\nsudo apt update && sudo apt install -y openvpn tmux\n```\n\n3. Create the OpenVPN [client configuration file](#client-configuration-file) for your Daytona sandbox\n\n```bash\nsudo nano client.ovpn\n```\n\n4. Save the file by pressing `Ctrl+O`, then `Enter`, and exit by pressing `Ctrl+X`\n\nDaytona requires the OpenVPN tunnel to be running in the background to connect the sandbox to the OpenVPN network. The recommended approach is to run it in a detached tmux (or similar) session:\n\n5. Start OpenVPN tunnel in a background tmux session\n\n```bash\ntmux new -d -s openvpn 'sudo openvpn client.ovpn'\n```\n\nThis starts the OpenVPN tunnel in a background tmux session that persists even if you disconnect from the sandbox.\n\n6. Verify the OpenVPN connection by running the following command\n\n```bash\ncurl ifconfig.me\n```\n\nThis will return the IP address of the sandbox connected to the OpenVPN network.\n\nYou've now successfully connected your Daytona sandbox to your OpenVPN network."
  },
  {
    "path": "apps/docs/src/content/docs/en/web-terminal.mdx",
    "content": "---\ntitle: Web Terminal\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona provides a browser-based web terminal for interacting with your sandboxes. The web terminal allows you to run commands, view files, and debug directly from your browser without installing any local tools.\n\n- **Remote command execution**: run shell commands directly in your sandbox\n- **File management**: navigate the file system, view and edit files\n- **Debugging**: inspect logs, monitor processes, and troubleshoot issues\n- **Package management**: install dependencies and configure your environment\n\n## Access from Dashboard\n\nAccess the web terminal directly from the [Daytona Dashboard ↗](https://app.daytona.io/dashboard/sandboxes).\n\n1. Navigate to [Sandboxes ↗](https://app.daytona.io/dashboard/sandboxes)\n2. Locate the running sandbox you want to access\n3. Click the terminal icon **`>_`**\n\nThis opens the web terminal in a new browser tab, providing a full terminal session connected to your sandbox. The web terminal is available only for sandboxes in the `STARTED` state. If your sandbox is stopped, start it before attempting to access the terminal.\n\n## Access via CLI\n\nWhen you create a sandbox using the Daytona CLI, the web terminal URL is displayed automatically in the output.\n\n```shell\ndaytona create\n```\n\nThe CLI output includes the terminal URL:\n\n```text\nSandbox '<sandboxId>' created successfully\nConnect via SSH:         daytona ssh <sandboxId>\nOpen the Web Terminal:   https://22222-<sandboxId>.proxy.daytona.work\n```\n\n## Access via URL\n\nThe web terminal runs on port `22222` inside each sandbox. You can obtain the terminal URL programmatically using [Preview URLs](/docs/en/preview).\n\nPass port `22222` to the preview URL method:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n\n```python\nterminal_info = sandbox.get_preview_link(22222)\nprint(f\"Web Terminal URL: {terminal_info.url}\")\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n\n```typescript\nconst terminalInfo = await sandbox.getPreviewLink(22222);\nconsole.log(`Web Terminal URL: ${terminalInfo.url}`);\n```\n\n</TabItem>\n<TabItem label=\"Ruby\" icon=\"seti:ruby\">\n\n```ruby\nterminal_info = sandbox.preview_url(22222)\nputs \"Web Terminal URL: #{terminal_info.url}\"\n```\n\n</TabItem>\n<TabItem label=\"Go\" icon=\"seti:go\">\n\n```go\nurl, err := sandbox.GetPreviewLink(ctx, 22222)\n```\n\n</TabItem>\n<TabItem label=\"CLI\" icon=\"seti:shell\">\n\n```bash\ndaytona preview-url <sandbox-name> --port 22222\n```\n\n</TabItem>\n<TabItem label=\"API\" icon=\"seti:json\">\n\n```bash\ncurl 'https://app.daytona.io/api/sandbox/{sandboxId}/ports/22222/preview-url' \\\n  --header 'Authorization: Bearer <API_KEY>'\n```\n\n</TabItem>\n</Tabs>\n\n## Security\n\nTerminal access is restricted to authenticated members of your [Organization](/docs/en/organizations). Even when a sandbox has its `public` parameter set to `true`, the web terminal remains accessible only to organization members.\n\n:::warning\nThe web terminal provides full shell access to your sandbox. Treat terminal URLs with the same care as SSH credentials. Do not share terminal URLs with untrusted parties.\n:::\n\n## Related\n\n- [SSH Access](/docs/en/ssh-access): connect to your sandbox from a local terminal or IDE\n- [Pseudo Terminal (PTY)](/docs/en/pty): programmatic terminal sessions for automated workflows\n- [Process and Code Execution](/docs/en/process-code-execution): execute commands and run code in sandboxes\n- [Preview](/docs/en/preview): generate preview URLs for accessing sandbox services\n"
  },
  {
    "path": "apps/docs/src/content/docs/en/webhooks.mdx",
    "content": "---\ntitle: Webhooks\ndescription: Connect your applications to Daytona events in real-time with webhooks for automation, monitoring, and integrations.\n---\n\nWebhooks are HTTP callbacks that Daytona sends to your specified endpoints when specific events occur.\nThink of them as \"reverse API calls\" - instead of your application asking Daytona for updates, Daytona\nproactively notifies your application when something important happens.\n\nWebhooks enable powerful automation and integration scenarios:\n\n- **Real-time notifications**: get instant alerts when sandboxes are created, started, or stopped\n- **Automated workflows**: trigger deployment pipelines when snapshots are created\n- **Monitoring & analytics**: track usage patterns and resource utilization across organizations\n- **Integration**: connect Daytona with existing tools like Slack, Discord, or custom applications\n- **Audit & compliance**: maintain detailed logs of all important changes\n\n:::note\nWebhooks are available to organization admins and members with appropriate permissions. If you don't see **Webhooks** in [Daytona Dashboard ↗](https://app.daytona.io/dashboard), contact [support@daytona.io](mailto:support@daytona.io) to enable webhooks for your organization. Provide your organization ID (found in your organization settings) when requesting access.\n:::\n\n## Accessing webhooks\n\nDaytona provides a webhook management interface to access and manage webhook endpoints.\n\n1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard)\n2. Click **Webhooks** in the sidebar\n\nThe webhooks management interface contains two tabs: [Endpoints](#endpoints) and [Messages](#messages).\n\n### Endpoints\n\nThe endpoints tab lists all the webhook endpoints for the organization. Each endpoint has the following details:\n\n- **Name**: the name of the webhook endpoint\n- **URL**: the URL of the webhook endpoint\n- **Status**: the status of the webhook endpoint\n- **Created**: the timestamp when the webhook endpoint was created\n\nClicking on an endpoint opens the endpoint details page with additional endpoint configuration details: **name**, **URL**, **events**, **status**, **delivery statistics**, and **event history**.\n\n### Messages\n\nThe messages tab lists all the webhook messages for the organization. Each message has the following details:\n\n- **Message ID**: the ID of the webhook message\n- **Event type**: the event type of the webhook message\n- **Timestamp**: the timestamp when the webhook message was created\n\nClicking on a message opens the message details dialog with additional message details: **message ID**, **event type**, **timestamp**, **payload**, and **delivery attempts**.\n\nDelivery attempts are shown in a separate table with the following columns:\n\n- **Status**: the status of the delivery attempt\n- **URL**: the URL of the delivery attempt\n- **Timestamp**: the timestamp when the delivery attempt was created\n\nExpanding a delivery attempt displays additional delivery attempt details: **status code**, **duration**, **trigger**, **endpoint ID**, and **response body**.\n\n## Create webhook endpoints\n\nDaytona provides a webhook management interface to create webhook endpoints.\n\n1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard)\n2. Click **Webhooks** in the sidebar\n3. Click **Add Endpoint**\n4. Configure your endpoint:\n\n- **Endpoint name**: a name for the endpoint\n- **Endpoint URL**: HTTPS endpoint where you want to receive events\n- [Events](#webhook-events): select which events to subscribe to\n\n5. Click **Create**\n\n## Edit webhook endpoints\n\nDaytona provides a webhook management interface to edit webhook endpoints.\n\n1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard)\n2. Click **Webhooks** in the sidebar\n3. Select a webhook endpoint from the [Endpoints](#endpoints) tab\n4. Click the three dots menu (**⋮**) and select **Edit**\n5. Update the endpoint details\n6. Click **Save**\n\n## Delete webhook endpoints\n\nDaytona provides a webhook management interface to delete webhook endpoints.\n\n1. Navigate to [Daytona Dashboard ↗](https://app.daytona.io/dashboard)\n2. Click **Webhooks** in the sidebar\n3. Select a webhook endpoint from the [Endpoints](#endpoints) tab\n4. Click the three dots menu (**⋮**) and select **Delete**\n5. Confirm the deletion\n\n## Webhook events\n\nDaytona sends webhooks for lifecycle events across your infrastructure resources. You can subscribe to specific event types or receive all events and filter them in your application.\n\nFor more information, see the [API](/docs/en/tools/api/#daytona/tag/webhooks) reference:\n\n> [**Send a webhook message (API)**](/docs/en/tools/api/#daytona/tag/webhooks/POST/webhooks/organizations/{organizationId}/send)\n>\n> [**Get delivery attempts for a webhook message (API)**](/docs/en/tools/api/#daytona/tag/webhooks/GET/webhooks/organizations/{organizationId}/messages/{messageId}/attempts)\n\n### Sandbox events\n\n| Event Type                  | Description                    |\n| --------------------------- | ------------------------------ |\n| **`sandbox.created`**       | A new sandbox has been created |\n| **`sandbox.state.updated`** | A sandbox's state has changed  |\n\n### Snapshot events\n\n| Event Type                   | Description                     |\n| ---------------------------- | ------------------------------- |\n| **`snapshot.created`**       | A new snapshot has been created |\n| **`snapshot.state.updated`** | A snapshot's state has changed  |\n| **`snapshot.removed`**       | A snapshot has been removed     |\n\n### Volume events\n\n| Event Type                 | Description                   |\n| -------------------------- | ----------------------------- |\n| **`volume.created`**       | A new volume has been created |\n| **`volume.state.updated`** | A volume's state has changed  |\n\n## Webhook payload format\n\nAll webhook payloads are JSON objects following a consistent format with common fields and event-specific data.\n\n**Common Fields:**\n\n| Field           | Type   | Description                                     |\n| --------------- | ------ | ----------------------------------------------- |\n| **`event`**     | string | Event type identifier (e.g., `sandbox.created`) |\n| **`timestamp`** | string | ISO 8601 timestamp when the event occurred      |\n\n### **`sandbox.created`**\n\nSent when a new sandbox is created.\n\n```json\n{\n  \"event\": \"sandbox.created\",\n  \"timestamp\": \"2025-12-19T10:30:00.000Z\",\n  \"id\": \"sandbox123\",\n  \"organizationId\": \"org123\",\n  \"state\": \"started\",\n  \"class\": \"small\",\n  \"createdAt\": \"2025-12-19T10:30:00.000Z\"\n}\n```\n\n| Field                | Type   | Description                                     |\n| -------------------- | ------ | ----------------------------------------------- |\n| **`id`**             | string | Sandbox ID                                      |\n| **`organizationId`** | string | Organization ID                                 |\n| **`state`**          | string | Sandbox state                                   |\n| **`class`**          | string | Sandbox class (`small`, `medium`, or `large`)   |\n| **`createdAt`**      | string | ISO 8601 timestamp when the sandbox was created |\n\n### **`sandbox.state.updated`**\n\nSent when a sandbox's state changes.\n\n```json\n{\n  \"event\": \"sandbox.state.updated\",\n  \"timestamp\": \"2025-12-19T10:30:00.000Z\",\n  \"id\": \"sandbox123\",\n  \"organizationId\": \"org123\",\n  \"oldState\": \"started\",\n  \"newState\": \"stopped\",\n  \"updatedAt\": \"2025-12-19T10:30:00.000Z\"\n}\n```\n\n| Field                | Type   | Description                                          |\n| -------------------- | ------ | ---------------------------------------------------- |\n| **`id`**             | string | Sandbox ID                                           |\n| **`organizationId`** | string | Organization ID                                      |\n| **`oldState`**       | string | Previous sandbox state                               |\n| **`newState`**       | string | New sandbox state                                    |\n| **`updatedAt`**      | string | ISO 8601 timestamp when the sandbox was last updated |\n\n### **`snapshot.created`**\n\nSent when a new snapshot is created.\n\n```json\n{\n  \"event\": \"snapshot.created\",\n  \"timestamp\": \"2025-12-19T10:30:00.000Z\",\n  \"id\": \"snapshot123\",\n  \"name\": \"my-snapshot\",\n  \"organizationId\": \"org123\",\n  \"state\": \"active\",\n  \"createdAt\": \"2025-12-19T10:30:00.000Z\"\n}\n```\n\n| Field                | Type   | Description                                      |\n| -------------------- | ------ | ------------------------------------------------ |\n| **`id`**             | string | Snapshot ID                                      |\n| **`name`**           | string | Snapshot name                                    |\n| **`organizationId`** | string | Organization ID                                  |\n| **`state`**          | string | Snapshot state                                   |\n| **`createdAt`**      | string | ISO 8601 timestamp when the snapshot was created |\n\n### **`snapshot.state.updated`**\n\nSent when a snapshot's state changes.\n\n```json\n{\n  \"event\": \"snapshot.state.updated\",\n  \"timestamp\": \"2025-12-19T10:30:00.000Z\",\n  \"id\": \"snapshot123\",\n  \"name\": \"my-snapshot\",\n  \"organizationId\": \"org123\",\n  \"oldState\": \"building\",\n  \"newState\": \"active\",\n  \"updatedAt\": \"2025-12-19T10:30:00.000Z\"\n}\n```\n\n| Field                | Type   | Description                                           |\n| -------------------- | ------ | ----------------------------------------------------- |\n| **`id`**             | string | Snapshot ID                                           |\n| **`name`**           | string | Snapshot name                                         |\n| **`organizationId`** | string | Organization ID                                       |\n| **`oldState`**       | string | Previous snapshot state                               |\n| **`newState`**       | string | New snapshot state                                    |\n| **`updatedAt`**      | string | ISO 8601 timestamp when the snapshot was last updated |\n\n### **`snapshot.removed`**\n\nSent when a snapshot is removed.\n\n```json\n{\n  \"event\": \"snapshot.removed\",\n  \"timestamp\": \"2025-12-19T10:30:00.000Z\",\n  \"id\": \"snapshot123\",\n  \"name\": \"my-snapshot\",\n  \"organizationId\": \"org123\",\n  \"removedAt\": \"2025-12-19T10:30:00.000Z\"\n}\n```\n\n| Field                | Type   | Description                                      |\n| -------------------- | ------ | ------------------------------------------------ |\n| **`id`**             | string | Snapshot ID                                      |\n| **`name`**           | string | Snapshot name                                    |\n| **`organizationId`** | string | Organization ID                                  |\n| **`removedAt`**      | string | ISO 8601 timestamp when the snapshot was removed |\n\n### **`volume.created`**\n\nSent when a new volume is created.\n\n```json\n{\n  \"event\": \"volume.created\",\n  \"timestamp\": \"2025-12-19T10:30:00.000Z\",\n  \"id\": \"vol-12345678\",\n  \"name\": \"my-volume\",\n  \"organizationId\": \"org123\",\n  \"state\": \"ready\",\n  \"createdAt\": \"2025-12-19T10:30:00.000Z\"\n}\n```\n\n| Field                | Type   | Description                                    |\n| -------------------- | ------ | ---------------------------------------------- |\n| **`id`**             | string | Volume ID                                      |\n| **`name`**           | string | Volume name                                    |\n| **`organizationId`** | string | Organization ID                                |\n| **`state`**          | string | Volume state                                   |\n| **`createdAt`**      | string | ISO 8601 timestamp when the volume was created |\n\n### **`volume.state.updated`**\n\nSent when a volume's state changes.\n\n```json\n{\n  \"event\": \"volume.state.updated\",\n  \"timestamp\": \"2025-12-19T10:30:00.000Z\",\n  \"id\": \"vol-12345678\",\n  \"name\": \"my-volume\",\n  \"organizationId\": \"org123\",\n  \"oldState\": \"creating\",\n  \"newState\": \"ready\",\n  \"updatedAt\": \"2025-12-19T10:30:00.000Z\"\n}\n```\n\n| Field                | Type   | Description                                         |\n| -------------------- | ------ | --------------------------------------------------- |\n| **`id`**             | string | Volume ID                                           |\n| **`name`**           | string | Volume name                                         |\n| **`organizationId`** | string | Organization ID                                     |\n| **`oldState`**       | string | Previous volume state                               |\n| **`newState`**       | string | New volume state                                    |\n| **`updatedAt`**      | string | ISO 8601 timestamp when the volume was last updated |\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/404.md",
    "content": "---\ntitle: \"問題が発生しました · Daytona\"\ntemplate: doc\neditUrl: false\ntableOfContents: false\npagefind: false\nhead:\n  - tag: title\n    content: 問題が発生しました · Daytona\nhero:\n  title: \"問題が発生しました\"\n  tagline: お探しのページは見つかりませんでした。\n---\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/api-keys.mdx",
    "content": "---\ntitle: API Keys\n---\n\nDaytonaのAPIキーは、[Daytona API](/docs/ja/tools/api)へのリクエストを認証するために使用します。\n\n[Configuration](/docs/ja/configuration)ページでは、`DAYTONA_API_KEY` 環境変数の設定方法を説明しています。\n\nAPIキーを管理するには、Dashboardの[Keys](https://app.daytona.io/dashboard/keys)セクションに移動します。`Create Key` をクリックして新しいキーを作成し、クリップボードにコピーします。\n\n## 権限\n\n新しいAPIキーを追加する際、キーに付与する権限のセットを選択するよう求められます:\n\n| 権限 | 説明 |\n|------------|-------------|\n| **`Sandboxes`** | サンドボックスの作成および管理を許可します |\n| **`Snapshots`** | スナップショットの作成および管理を許可します |\n| **`Registries`** | レジストリの作成および管理を許可します |\n| **`Volumes`** | ボリュームの作成および管理を許可します |\n\n各権限には細かなスコープがあります:\n\n- `write:*` は作成および更新\n- `delete:*` はリソースの削除\n\n例: `write:sandboxes`, `delete:sandboxes`"
  },
  {
    "path": "apps/docs/src/content/docs/ja/audit-logs.mdx",
    "content": "---\ntitle: 監査ログ\ndescription: Daytona の組織全体にわたるすべてのユーザー操作を表示および監視します。\n---\n\nDaytona の監査ログは、組織全体のユーザーおよびシステムのアクティビティを詳細に記録します。サンドボックスのライフサイクルイベント、ユーザーアクセス、システム変更などの追跡にご利用ください。\n\n[Dashboard](https://app.daytona.io/dashboard/audit-logs) から監査ログにアクセスできます。\n\n## 前提条件\n\n監査ログを利用できるのは次のユーザーです：\n- **管理者** - すべての監査ログへのフルアクセス\n- **メンバー** - 監査ログの権限が付与されている場合のみアクセス可能\n\n監査ログにアクセスできない場合は、組織の管理者にお問い合わせください。\n\n## リアルタイム更新\n\n監査ログページの右上にある**リアルタイム更新**のトグルを有効にすると、新しいイベントの発生に合わせてログが自動的に更新されます。\n\n## ログ構造\n\n各ログエントリには次の列が含まれます:\n\n| Field     | 説明                                       |\n|---------- |--------------------------------------------|\n| **Time**  | アクションが発生した日時のタイムスタンプ（UTC） |\n| **User**  | アクションを実行したユーザーのメールアドレス   |\n| **Action**| 実行された操作                               |\n| **Target**| 影響を受けたリソースの種類                    |\n| **Outcome**| 結果のステータスコードとメッセージ            |\n\n### 例\n\n```text\nTime:       5時間前 (7/31/2025, 8:15:27 AM)\nUser:       janedoe@acme.com\nAction:     create\nTarget:     sandbox (ID: 10f249ad-...)\nOutcome:    Success (200)\n```\n\n## ユースケース\n\n- **セキュリティ監査**: 不正アクセスやサンドボックスの不正利用を監視\n- **デバッグ**: サンドボックスのライフサイクルに関する問題を把握（例：起動失敗）\n- **コンプライアンス向けエクスポート**: 内部監査や外部監査に向けてログをエクスポート（近日対応）\n\n## アクション\n\n以下は、Daytona によって記録されるアクションの全一覧です：\n\n```text\ncreate, read, update, delete, login,\nset_default, update_role, update_assigned_roles, update_quota,\nsuspend, unsuspend, accept, decline,\nlink_account, unlink_account, leave_organization,\nregenerate_key_pair, update_scheduling,\nstart, stop, replace_labels, create_backup,\nupdate_public_status, set_auto_stop_interval,\nset_auto_archive_interval, set_auto_delete_interval, archive,\nget_port_preview_url, toggle_state, set_general_status, activate,\nupdate_network_settings,\ntoolbox_delete_file, toolbox_download_file, toolbox_create_folder,\ntoolbox_move_file, toolbox_set_file_permissions, toolbox_replace_in_files,\ntoolbox_upload_file, toolbox_bulk_upload_files,\ntoolbox_git_add_files, toolbox_git_create_branch, toolbox_git_delete_branch,\ntoolbox_git_clone_repository, toolbox_git_commit_changes,\ntoolbox_git_pull_changes, toolbox_git_push_changes,\ntoolbox_git_checkout_branch, toolbox_execute_command,\ntoolbox_create_session, toolbox_session_execute_command,\ntoolbox_delete_session, toolbox_computer_use_start,\ntoolbox_computer_use_stop, toolbox_computer_use_restart_process\n```\n\n## ターゲット\n\n各アクションは特定のリソースタイプを対象とします。対象となり得るものは次のとおりです:\n\n```text\napi_key, organization, organization_invitation,\norganization_role, organization_user, docker_registry,\nrunner, sandbox, snapshot, user, volume\n```\n\n## 結果\n\nOutcome フィールドはアクションの結果を示します。ステータスは標準的な HTTP セマンティクスに従います:\n\n| 結果 | 説明 |\n|---------|-------------|\n| **情報** | 情報（1xx コード） |\n| **成功** | アクション成功（2xx コード） |\n| **リダイレクト** | リダイレクト（3xx コード） |\n| **エラー** | クライアント/サーバー エラー（4xx/5xx） |\n\nエラーの例:\n\n- `400` – サンドボックスが起動していません\n- `403` – 認可されていません\n- `500` – 内部エラー\n\n{/* ## Filtering & Pagination\n\nYou can filter and search logs by:\n\n- Action type\n- Target resource\n- Outcome status\n- User email\n\nUse the page size selector to change how many results are shown per page. */} "
  },
  {
    "path": "apps/docs/src/content/docs/ja/billing.mdx",
    "content": "---\ntitle: 請求\n---\n\nDashboard の「請求」サブページでは、組織の請求情報を表示します。\n\n## ウォレット\n\nウォレットでは、組織のウォレット残高と今月のクレジット消費額を表示します。\n\n## 自動チャージ\n\n組織はウォレットに対する自動チャージのルールを設定できます。\n\n- **しきい値** — ウォレット残高がこの金額まで下がると、チャージが実行されます。  \n- **ターゲット** — ウォレット残高がこの金額まで補充されます。\n\n自動チャージを無効化するには、**しきい値** と **ターゲット** の両方を `0` に設定してください。\n\n## コスト内訳\n\n「コスト内訳」チャートでは、リソースごとのコストを表示します。\n\nCPU、RAM、ストレージの使用量を確認でき、エリアチャートと棒グラフを切り替えられます。"
  },
  {
    "path": "apps/docs/src/content/docs/ja/configuration.mdx",
    "content": "---\ntitle: 構成\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\n## 環境変数を設定する\n\nDaytona で認証するには API キーが必要です。API キーは Daytona プラットフォームから取得できます。\n\n1. [Daytona Dashboard](https://app.daytona.io/dashboard/) にアクセスします。\n2. API Keys を開きます。\n3. **`Create Key`** ボタンをクリックします。\n4. **`.env`** ファイルで **`DAYTONA_API_KEY`** 環境変数を設定し、API キーを追加します。\n5. **`.env`** ファイルで **`DAYTONA_API_URL`** 環境変数を設定し、Daytona の API URL を指定します。\n\n## 構成オプション\n\nDaytona SDK では、Python と TypeScript で `DaytonaConfig` クラスを使用して設定を行えます。`DaytonaConfig` クラスは次のパラメータを受け取ります。\n\n- `api_key`: Daytona の APIキー\n- `api_url`: Daytona の API の URL\n- `target`: サンドボックスを作成する Daytona のターゲット（リージョン）\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\nfrom daytona import DaytonaConfig\n\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"your-api-url\",\n    target=\"us\"\n)\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { DaytonaConfig } from '@daytonaio/sdk';\n\nconst config: DaytonaConfig = {\n    apiKey: \"your-api-key\",          \n    apiUrl: \"your-api-url\",     \n    target: \"us\"                  \n};\n```\n\n</TabItem>\n</Tabs>\n\n## 環境変数\n\nDaytona SDK は設定に環境変数を利用できます。SDK は次の環境変数を自動的に参照します：\n\n| Variable              | Description                                | Optional |\n| --------------------- | ------------------------------------------ | -------- |\n| **`DAYTONA_API_KEY`** | Daytona の APIキー。                        |          |\n| **`DAYTONA_API_URL`** | Daytona API の URL。                        | Yes      |\n| **`DAYTONA_TARGET`**  | サンドボックスを作成する Daytona のターゲット（ターゲット（リージョン））。 | Yes      |\n\n### 環境変数の設定\n\nDaytona SDK は環境変数から設定を読み込みます。以下の方法で設定できます。\n\n- [**`.env`** ファイルを使用](#using-a-env-file)\n- [シェル環境を使用](#using-shell-environment)\n\n#### **`.env`** ファイルを使用\n\nプロジェクトのルートディレクトリに `.env` ファイルを作成します：\n\n```bash\nDAYTONA_API_KEY=your-api-key\nDAYTONA_API_URL=https://your-api-url\nDAYTONA_TARGET=us\n```\n\n- `DAYTONA_API_KEY`: Daytona の APIキー。\n- `DAYTONA_API_URL`: Daytona API の URL。\n- `DAYTONA_TARGET`: サンドボックスを作成する Daytona のターゲット（ターゲット（リージョン））。\n\n#### シェル環境を使用\n\nシェルで環境変数を設定します：\n\n<Tabs syncKey=\"shell\">\n<TabItem label=\"Bash/Zsh\" icon=\"seti:shell\">\n```bash\nexport DAYTONA_API_KEY=your-api-key\nexport DAYTONA_API_URL=https://your-api-url\n```\n</TabItem>\n<TabItem label=\"Windows PowerShell\" icon=\"seti:powershell\">\n```bash\n$env:DAYTONA_API_KEY=\"your-api-key\"\n$env:DAYTONA_API_URL=\"https://your-api-url\"\n```\n</TabItem>\n</Tabs>\n\n## 設定の優先順位\n\nSDK は設定に対して次の優先順位（高い順）を適用します:\n\n1. コード内で明示的に指定された設定\n2. 環境変数\n3. 設定ファイル\n4. デフォルト値\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/custom-domain-authentication.mdx",
    "content": "---\ntitle: カスタムプレビュープロキシ\ndescription: 独自のドメインとロジックでプレビュープロキシをカスタマイズします。\n---\n\nDaytona では、サンドボックスのプレビューURLを処理するために、独自のカスタムプレビュープロキシをデプロイできます。これにより、カスタムドメイン、認証、エラーハンドリング、スタイリングなど、プレビューエクスペリエンスを完全に制御できます。\n\n**カスタムプレビュープロキシで可能なこと:**\n\n- **カスタムドメイン:** 独自ドメイン配下でプロキシをホスト（例: `preview.yourcompany.com`）\n- **ユーザー認証:** プライベートプレビュー向けの独自認証ロジックを実装\n- **スマートなサンドボックス管理:** 転送前に停止中のサンドボックスを自動的に起動\n- **カスタムエラーページ:** ブランドに合わせてエラーページの見た目をカスタマイズ\n- **プレビュー警告の制御:** Daytona のプレビュー警告を無効化\n- **CORS 管理:** Daytona の既定の CORS 設定を上書き\n\n---\n\n## 仕組み\n\nユーザーがプレビューURLにアクセスすると、カスタムプロキシがリクエストを受け取り、次のことが可能です:\n\n1. カスタムロジックでユーザーを認証する\n2. サンドボックスの状態を確認し、必要に応じて起動する\n3. 実際のサンドボックスへリクエストを転送する\n4. カスタムのスタイルやエラーページでレスポンスを処理する\n5. Daytonaの動作を制御するためのカスタムヘッダーを送信する\n\n---\n\n## Daytona ヘッダー\n\nプロキシは、Daytona の動作を制御するための特殊なヘッダーを送信できます：\n\n#### プレビュー警告の無効化\n\nDaytona のプレビュー警告ページを無効化するには、次を送信します：\n\n```\nX-Daytona-Skip-Preview-Warning: true\n```\n\n#### CORS の無効化\n\nDaytona の既定の CORS 設定を上書きするには、次を送信します：\n\n```\nX-Daytona-Disable-CORS: true\n```\n\n#### 認証\n\n非公開のプレビューリンクでは、次を送信する必要があります：\n\n```\nX-Daytona-Preview-Token: {sandboxToken}\n```\n\n`sandboxToken` は [Daytona SDK または API](/docs/ja/preview-and-authentication) から取得できます。\n\n---\n\n## 例\n\nカスタムプレビュー用プロキシのサンプルは [GitHub](https://github.com/daytonaio/daytona-proxy-samples) にあります。\n\n- [TypeScript サンプル](https://github.com/daytonaio/daytona-proxy-samples/tree/main/typescript)\n- [Go サンプル](https://github.com/daytonaio/daytona-proxy-samples/tree/main/go)\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/data-analysis-with-ai.mdx",
    "content": "---\ntitle: AI でデータを分析する\ndescription: Daytona を使って、AI 生成コードでデータ分析と可視化を実行します。\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport { Image } from 'astro:assets'\n\nimport chartImage from '../../../assets/docs/images/chart-0.png'\n\nDaytona のサンドボックス（Daytonaが管理する隔離された一時的な実行環境）を使えば、AI が生成したコードでデータを分析できます。一般的な AI によるデータ分析のワークフローは次のとおりです。\n\n1. ユーザーは CSV などの形式でデータセットを用意します。\n2. ユーザーのデータに基づいてコード（通常は Python）を生成するよう、LLM に指示します。\n3. サンドボックスが AI 生成コードを実行し、結果を返します。\n4. 結果をユーザーに表示します。\n\n## Daytona で AI データアナリストを構築する\n\nこの例では、Daytona の安全なサンドボックス環境を用いて、CSV データから自動的に洞察と可視化を生成する AI 搭載のデータアナリストを構築する方法を示します。\n\n**作成するもの:** 車両評価データセットを分析し、製造年と価格の関係を特定し、プロフェッショナルな可視化を生成するシステムです。すべて自然言語プロンプトで Claude に指示して実行します。\n\n### 1. プロジェクトのセットアップ\n\n#### 1.1 依存関係のインストール\n\nDaytona SDK と Anthropic SDK をプロジェクトにインストールします:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    `bash pip install daytona anthropic python-dotenv `\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    `bash npm install @daytonaio/sdk @anthropic-ai/sdk dotenv `\n  </TabItem>\n</Tabs>\n\n#### 1.2 環境設定\n\nAPIキーを取得し、環境を設定します:\n\n1. **Daytona API key:** [Daytona Dashboard](https://app.daytona.io/dashboard/keys) から取得\n2. **Anthropic API key:** [Anthropic Console](https://console.anthropic.com/) から取得\n\nプロジェクトに `.env` ファイルを作成します:\n\n```bash\nDAYTONA_API_KEY=dtn_***\nANTHROPIC_API_KEY=sk-ant-***\n```\n\n### 2. データセットの準備\n\n#### 2.1 データセットのダウンロード\n\n公開されている車両評価データセットを使用します。以下から直接ダウンロードできます:\n\n[https://download.daytona.io/dataset.csv](https://download.daytona.io/dataset.csv)\n\nファイルをダウンロードし、プロジェクトディレクトリに `dataset.csv` として保存します。\n\n#### 2.2 サンドボックスの初期化\n\nDaytona のサンドボックスを作成し、データセットをアップロードします:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from dotenv import load_dotenv\n    from daytona import Daytona\n    import os\n\n    load_dotenv()\n\n    # Create sandbox\n\n    daytona = Daytona()\n    sandbox = daytona.create()\n\n    # Upload the dataset to the sandbox\n\n    sandbox.fs.upload_file(\"dataset.csv\", \"/home/daytona/dataset.csv\")\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import 'dotenv/config'\n    import { Daytona } from '@daytonaio/sdk';\n\n    // Create sandbox\n    const daytona = new Daytona();\n    const sandbox = await daytona.create()\n\n    // Upload the dataset to the sandbox\n    await sandbox.fs.uploadFile('dataset.csv', '/home/daytona/dataset.csv')\n    ```\n  </TabItem>\n</Tabs>\n\n### 3. AI データアナリストの構築\n\nここでは、Claude と Daytona を連携させてデータを分析し、可視化を生成する中核機能を作成します。\n\n#### 3.1 コード実行ハンドラー\n\nまず、コード実行とチャート抽出を処理する関数を作成します:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import base64\n\n    def run_ai_generated_code(sandbox, ai_generated_code):\n      execution = sandbox.process.code_run(ai_generated_code)\n      if execution.exit_code != 0:\n        print('AI-generated code had an error.')\n        print(execution.exit_code)\n        print(execution.result)\n        return\n\n      # Check for charts in execution artifacts\n      if not execution.artifacts or not execution.artifacts.charts:\n        print('No charts found in execution artifacts')\n        return\n\n      result_idx = 0\n      for result in execution.artifacts.charts:\n        if result.png: # Save the png to a file (png is in base64 format)\n          with open(f'chart-{result_idx}.png', 'wb') as f:\n            f.write(base64.b64decode(result.png))\n            print(f'Chart saved to chart-{result_idx}.png')\n            result_idx += 1\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import fs from 'fs'\n\n    async function runAIGeneratedCode(sandbox, aiGeneratedCode: string) {\n      const execution = await sandbox.process.codeRun(aiGeneratedCode)\n      if (execution.exitCode != 0) {\n        console.error('AI-generated code had an error.')\n        console.log(execution.exitCode)\n        console.log(execution.result)\n        return\n      }\n\n      // Check for charts in execution artifacts\n      if (!execution.artifacts || !execution.artifacts.charts) {\n        console.log('No charts found in execution artifacts')\n        return\n      }\n\n      let resultIdx = 0\n      for (const result of execution.artifacts.charts) {\n        if (result.png) {\n          // Save the png to a file (png is in base64 format)\n          fs.writeFileSync(`chart-${resultIdx}.png`, result.png, { encoding: 'base64' })\n          console.log(`Chart saved to chart-${resultIdx}.png`)\n          resultIdx++\n        }\n      }\n    }\n    ```\n  </TabItem>\n</Tabs>\n\n#### 3.2 分析用プロンプトの作成\n\n次に、データセットと求める分析内容をClaudeに伝えるプロンプトを作成します。このプロンプトには以下が含まれます。\n\n- データセットのスキーマと列の説明\n- 具体的な分析リクエスト（製造年別の平均価格の推移）\n- コード生成に関する指示\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from anthropic import Anthropic\n\n    prompt = f\"\"\"\n    I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.\n\n    Relevant columns:\n    - 'year': integer, the manufacturing year of the vehicle\n    - 'price_in_euro': float, the listed price of the vehicle in Euros\n\n    Analyze how price varies by manufacturing year.  \n    Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.  \n    Create a line chart showing average price per year.\n    Write Python code that analyzes the dataset based on my request and produces right chart accordingly.\n    Finish with a plt.show()\"\"\"\n\n    anthropic = Anthropic()\n    print('Waiting for the model response...')\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import Anthropic from '@anthropic-ai/sdk'\n\n    const prompt = `\n    I have a CSV file with vehicle valuations saved in the sandbox at /home/daytona/dataset.csv.\n\n    Relevant columns:\n    - 'year': integer, the manufacturing year of the vehicle\n    - 'price_in_euro': float, the listed price of the vehicle in Euros\n\n    Analyze how price varies by manufacturing year.  \n    Drop rows where 'year' or 'price_in_euro' is missing, non-numeric, or an outlier.  \n    Create a line chart showing average price per year.\n    Write Python code that analyzes the dataset based on my request and produces right chart accordingly.\n    Finish with a plt.show()`\n\n    const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })\n    console.log('Waiting for the model response...')\n    ```\n  </TabItem>\n</Tabs>\n\n#### 3.3 ツール呼び出しのセットアップ\n\nここでは、ツール呼び出しを使用してClaudeをDaytonaのサンドボックスに接続します。これにより、Claudeは生成したPythonコードを自動的に実行できます。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    msg = anthropic.messages.create(\n        model='claude-3-5-sonnet-20240620',\n        max_tokens=1024,\n        messages=[{'role': 'user', 'content': prompt}],\n        tools=[\n            {\n                'name': 'run_python_code',\n                'description': 'Run Python code',\n                'input_schema': {\n                    'type': 'object',\n                    'properties': {\n                        'code': {\n                            'type': 'string',\n                            'description': 'The Python code to run',\n                        },\n                    },\n                    'required': ['code'],\n                },\n            },\n        ],\n    )\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    const msg = await anthropic.messages.create({\n      model: 'claude-3-5-sonnet-20240620',\n      max_tokens: 1024,\n      messages: [{ role: 'user', content: prompt }],\n      tools: [\n        {\n          name: 'run_python_code',\n          description: 'Run Python code',\n          input_schema: {\n            type: 'object',\n            properties: {\n              code: {\n                type: 'string',\n                description: 'The Python code to run',\n              },\n            },\n            required: ['code'],\n          },\n        },\n      ],\n    })\n    ```\n  </TabItem>\n</Tabs>\n\n#### 3.4 レスポンス処理\n\n最後に、Claude のレスポンスを解析し、生成されたコードを Daytona のサンドボックスで実行します:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    for content_block in msg.content:\n        if content_block.type == 'tool_use':\n            if content_block.name == 'run_python_code':\n                code = content_block.input['code']\n                print('Will run following code in the Sandbox:\\n', code)\n                # Execute the code in the sandbox\n                run_ai_generated_code(sandbox, code)\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    interface CodeRunToolInput {\n      code: string\n    }\n\n    for (const contentBlock of msg.content) {\n      if (contentBlock.type === 'tool_use') {\n        if (contentBlock.name === 'run_python_code') {\n          const code = (contentBlock.input as CodeRunToolInput).code\n          console.log('Will run following code in the Sandbox:\\n', code)\n          // Execute the code in the sandbox\n          await runAIGeneratedCode(sandbox, code)\n        }\n      }\n    }\n\n    ```\n  </TabItem>\n</Tabs>\n\n以上です。作成した `run_ai_generated_code` 関数はチャートの保存を自動的に処理します。Claude が `plt.show()` で可視化を生成すると、Daytona がそれをチャートの成果物として取得し、PNG ファイルとして保存します。\n\n主な利点:\n\n- セキュアな実行: 分離された Daytona のサンドボックスでコードを実行\n- 成果物の自動取得: チャート、テーブル、出力を自動的に抽出\n- エラーハンドリング: 組み込みのエラー検出とロギング\n- 言語非依存: ここでは Python を使用しましたが、Daytona は複数言語をサポート\n\n### 4. 分析の実行\n\n完全なコードを実行して結果を確認します。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    python data-analysis.py\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```bash\n    npx tsx data-analysis.ts\n    ```\n  </TabItem>\n</Tabs>\n\nプロジェクトディレクトリ内に、次のようなチャートが出力されるはずです:\n\n<Image src={chartImage} alt=\"製造年別の車両評価額チャート\" width={600} style=\"max-width: 100%; height: auto; margin: 1rem 0;\" />\n\n### 5. 完全な実装\n\n以下に、すぐに実行できるサンプル一式を示します:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    import base64\n    from dotenv import load_dotenv\n    from daytona import Daytona, Sandbox\n    from anthropic import Anthropic\n\n\n    def main():\n        load_dotenv()\n        # サンドボックスを作成\n        daytona = Daytona()\n        sandbox = daytona.create()\n        \n        # データセットをサンドボックスへアップロード\n        sandbox.fs.upload_file(\"dataset.csv\", \"/home/daytona/dataset.csv\")\n        \n        prompt = f\"\"\"\n    /home/daytona/dataset.csv のサンドボックスに、車両の評価額が保存された CSV ファイルがあります。\n\n    関連する列:\n    - 'year': 整数型、車両の製造年\n    - 'price_in_euro': 浮動小数点型、車両のユーロ建て掲載価格\n\n    製造年ごとの価格変動を分析してください。  \n    'year' または 'price_in_euro' が欠損、非数値、または外れ値の行は除外してください。  \n    年ごとの平均価格を示す折れ線グラフを作成してください。\n    この要件に基づいてデータセットを分析し、適切なグラフを生成する Python コードを書いてください。\n    最後に plt.show() で終了してください\"\"\"\n\n        anthropic = Anthropic()\n        print('モデルの応答を待機中...')\n        msg = anthropic.messages.create(\n            model='claude-3-5-sonnet-20240620',\n            max_tokens=1024,\n            messages=[{'role': 'user', 'content': prompt}],\n            tools=[\n                {\n                    'name': 'run_python_code',\n                    'description': 'Python コードを実行',\n                    'input_schema': {\n                        'type': 'object',\n                        'properties': {\n                            'code': {\n                                'type': 'string',\n                                'description': '実行する Python コード',\n                            },\n                        },\n                        'required': ['code'],\n                    },\n                },\n            ],\n        )\n\n        for content_block in msg.content:\n            if content_block.type == 'tool_use':\n                if content_block.name == 'run_python_code':\n                    code = content_block.input['code']\n                    print('サンドボックスで次のコードを実行します:\\n', code)\n                    # サンドボックス内でコードを実行\n                    run_ai_generated_code(sandbox, code)\n\n\n    def run_ai_generated_code(sandbox: Sandbox, ai_generated_code: str):\n        execution = sandbox.process.code_run(ai_generated_code)\n        if execution.exit_code != 0:\n            print('AI 生成コードでエラーが発生しました。')\n            print(execution.exit_code)\n            print(execution.result)\n            return\n        \n        # すべての結果を走査し、グラフを表す png ファイルがあるか確認\n        if not execution.artifacts or not execution.artifacts.charts:\n            print('実行成果物にグラフが見つかりませんでした')\n            print(execution.artifacts)\n            return\n\n        result_idx = 0\n        for result in execution.artifacts.charts:\n            if result.png:\n                # png をファイルに保存\n                # png は base64 形式です。\n                with open(f'chart-{result_idx}.png', 'wb') as f:\n                    f.write(base64.b64decode(result.png))\n                print(f'グラフを chart-{result_idx}.png に保存しました')\n                result_idx += 1\n\n\n    if __name__ == \"__main__\":\n        main()\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import 'dotenv/config'\n    import fs from 'fs'\n    import Anthropic from '@anthropic-ai/sdk'\n    import { Daytona, Sandbox } from '@daytonaio/sdk';\n\n\n    async function main() {\n      // サンドボックスを作成\n      const daytona = new Daytona();\n      const sandbox = await daytona.create()\n\n      // データセットをサンドボックスにアップロード\n      await sandbox.fs.uploadFile('dataset.csv', '/home/daytona/dataset.csv')\n\n      const prompt = `\n    サンドボックス内の /home/daytona/dataset.csv に車両評価のCSVファイルがあります。\n\n    関連列:\n    - 'year': 整数、車両の製造年\n    - 'price_in_euro': 浮動小数点数、ユーロ建ての掲載価格\n\n    製造年ごとの価格の変動を分析してください。  \n    'year' または 'price_in_euro' が欠損、非数値、または外れ値の行は除外してください。  \n    年ごとの平均価格を示す折れ線グラフを作成してください。\n    リクエストに基づいてデータセットを分析し、適切なグラフを生成する Python コードを書いてください。\n    最後に plt.show() で終了してください`\n\n      const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })\n      console.log('モデルの応答を待っています...')\n      const msg = await anthropic.messages.create({\n        model: 'claude-3-5-sonnet-20240620',\n        max_tokens: 1024,\n        messages: [{ role: 'user', content: prompt }],\n        tools: [\n          {\n            name: 'run_python_code',\n            description: 'Python コードを実行',\n            input_schema: {\n              type: 'object',\n              properties: {\n                code: {\n                  type: 'string',\n                  description: '実行する Python コード',\n                },\n              },\n              required: ['code'],\n            },\n          },\n        ],\n      })\n\n      interface CodeRunToolInput {\n        code: string\n      }\n\n      for (const contentBlock of msg.content) {\n        if (contentBlock.type === 'tool_use') {\n          if (contentBlock.name === 'run_python_code') {\n            const code = (contentBlock.input as CodeRunToolInput).code\n            console.log('サンドボックスで次のコードを実行します:\\n', code)\n            // サンドボックスでコードを実行\n            await runAIGeneratedCode(sandbox, code)\n          }\n        }\n      }\n    }\n\n    async function runAIGeneratedCode(sandbox: Sandbox, aiGeneratedCode: string) {\n      const execution = await sandbox.process.codeRun(aiGeneratedCode)\n      if (execution.exitCode != 0) {\n        console.error('AI生成コードでエラーが発生しました。')\n        console.log(execution.exitCode)\n        console.log(execution.result)\n        process.exit(1)\n      }\n      // すべての結果を確認し、グラフを表す PNG ファイルがあるかを特に確認します。\n      if (!execution.artifacts || !execution.artifacts.charts) {\n        console.log('実行成果物にチャートが見つかりません')\n        console.log(execution.artifacts)\n        return\n      }\n\n      let resultIdx = 0\n      for (const result of execution.artifacts.charts) {\n        if (result.png) {\n          // PNG をファイルに保存\n          // PNG は base64 形式です。\n          fs.writeFileSync(`chart-${resultIdx}.png`, result.png, { encoding: 'base64' })\n          console.log(`チャートを chart-${resultIdx}.png に保存しました`)\n          resultIdx++\n        }\n      }\n    }\n\n    main().catch(console.error);\n    ```\n  </TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/declarative-builder.mdx",
    "content": "---\ntitle: 宣言的ビルダー\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona（サンドボックスの作成・管理プラットフォーム）の宣言的ビルダーは、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）の依存関係をコードファーストで定義する強力な手法を提供します。コンテナレジストリからイメージを取り込む代わりに、SDKを用いてプログラム的に定義できます。\n\n## 概要\n\n宣言的ビルダーシステムは、主に次の2つのワークフローをサポートします。\n\n1. **動的イメージ**: サンドボックス（Daytonaが管理する隔離された一時的な実行環境）作成時に、依存関係の異なるイメージをオンデマンドでビルド\n2. **事前構築済みスナップショット**: 複数のサンドボックスで共有可能な、すぐに使えるスナップショット（サンドボックス作成に使う事前設定済みの再利用可能なイメージ／テンプレート）を作成・登録\n\n以下の機能を提供します。完全なAPIリファレンスとメソッドシグネチャについては、[Python](/docs/ja/python-sdk/common/image) および [TypeScript](/docs/ja/typescript-sdk/image) のSDKリファレンスを参照してください。\n\n### ベースイメージの選択\n\n- **Debianベースの環境**（Pythonと必須のビルドツールをプリインストール）\n- **カスタムベースイメージ**（任意のDockerレジストリまたは既存のコンテナイメージ由来）\n- **Dockerfileの取り込み**（既存のDockerfileのインポートと拡張）\n\n### パッケージ管理\n\n- **Pythonパッケージのインストール**（`pip`、`requirements.txt`、`pyproject.toml`に対応）\n- **高度なpipオプション**（カスタムインデックス、find-links、オプション依存関係など）\n\n### ファイルシステム操作\n\n- **ファイルのコピー**（ローカル開発環境からイメージへ）\n- **ディレクトリのコピー**（大量ファイル転送やプロジェクトセットアップに対応）\n- **作業ディレクトリの設定**（デフォルトの実行コンテキストを指定）\n\n### 環境構成\n\n- **環境変数**（アプリケーション設定やシークレット用）\n- **シェルコマンドの実行**（イメージビルド中）\n- **コンテナのランタイム設定**（エントリポイントやデフォルトコマンドを含む）\n\n詳細なメソッドシグネチャや使用例については、[Python](/docs/ja/python-sdk/common/image) および [TypeScript](/docs/ja/typescript-sdk/image) のSDKリファレンスを参照してください。\n\n## 動的イメージビルド\n\nサンドボックス作成時に、その場でイメージを生成できます。既存のどのイメージにも含まれていない特定の依存関係を持つ新しいサンドボックスを用意したい場合に有用です。\n\n新規のイメージを定義することも、既存のイメージに特定の依存関係を追加することも可能です（例: `pip` パッケージや `apt-get install` コマンド）。\\\nこれにより、ビルド処理のために自前のコンピュートリソースを使う必要がなくなり、Daytonaのインフラストラクチャにオフロードできます。\\\n各バージョンごとに個別のスナップショットを登録・検証する必要もありません。依存関係リストを素早く反復しやすくなり、また、数十〜数百の類似ユースケース/セットアップ向けにわずかに異なるバージョンを用意することもできます。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # Define the dynamic image\n    dynamic_image = (\n        Image.debian_slim(\"3.12\")\n        .pip_install([\"pytest\", \"pytest-cov\", \"mypy\", \"ruff\", \"black\", \"gunicorn\"])\n        .run_commands(\"apt-get update && apt-get install -y git curl\", \"mkdir -p /home/daytona/project\")\n        .workdir(\"/home/daytona/project\")\n        .env({\"ENV_VAR\": \"My Environment Variable\"})\n        .add_local_file(\"file_example.txt\", \"/home/daytona/project/file_example.txt\")\n    )\n\n    # Create a new Sandbox with the dynamic image and stream the build logs\n\n    sandbox = daytona.create(\n        CreateSandboxFromImageParams(\n            image=dynamic_image,\n        ),\n        timeout=0,\n        on_snapshot_create_logs=print,\n    )\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    // Define the dynamic image\n    const dynamicImage = Image.debianSlim('3.13')\n        .pipInstall(['pytest', 'pytest-cov', 'black', 'isort', 'mypy', 'ruff'])\n        .runCommands('apt-get update && apt-get install -y git', 'mkdir -p /home/daytona/project')\n        .workdir('/home/daytona/project')\n        .env({\n          NODE_ENV: 'development',\n        })\n        .addLocalFile('file_example.txt', '/home/daytona/project/file_example.txt')\n\n    // Create a new Sandbox with the dynamic image and stream the build logs\n    const sandbox = await daytona.create(\n      {\n        image: dynamicImage,\n      },\n      {\n        timeout: 0,\n        onSnapshotCreateLogs: console.log,\n      }\n    )\n    ```\n  </TabItem>\n</Tabs>\n\n:::tip\n動的イメージからのサンドボックス作成を一度実行すると、そのイメージは24時間キャッシュされ、同じランナー上での後続のサンドボックス作成はほぼ即時に完了します。\n\nつまり、毎回同じスクリプトを使えば、Daytonaがイメージのキャッシュを適切に処理します。\n:::\n\n## 事前ビルド済みスナップショットの作成\n\n特定の依存関係を含む新しいDaytonaのスナップショットを準備し、必要なときに複数のサンドボックスで即座に使いたい場合は、事前ビルド済みのスナップショットを作成できます。\n\nこのスナップショットはDaytonaダッシュボード上に表示され続け、永続的にキャッシュされるため、再ビルドは不要です。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # スナップショット用の一意の名前を生成\n    snapshot_name = f\"python-example:{int(time.time())}\"\n\n    # イメージに追加するデータを含むローカルファイルを作成\n\n    with open(\"file_example.txt\", \"w\") as f:\n        f.write(\"Hello, World!\")\n\n    # 一般的なデータサイエンスパッケージを含むPythonイメージを作成\n\n    image = (\n        Image.debian_slim(\"3.12\")\n        .pip_install([\"numpy\", \"pandas\", \"matplotlib\", \"scipy\", \"scikit-learn\", \"jupyter\"])\n        .run_commands(\n            \"apt-get update && apt-get install -y git\",\n            \"groupadd -r daytona && useradd -r -g daytona -m daytona\",\n            \"mkdir -p /home/daytona/workspace\",\n        )\n        .dockerfile_commands([\"USER daytona\"])\n        .workdir(\"/home/daytona/workspace\")\n        .env({\"MY_ENV_VAR\": \"My Environment Variable\"})\n        .add_local_file(\"file_example.txt\", \"/home/daytona/workspace/file_example.txt\")\n    )\n\n    # スナップショットを作成し、ビルドログをストリーミング出力\n\n    print(f\"=== Creating Snapshot: {snapshot_name} ===\")\n    daytona.snapshot.create(\n        CreateSnapshotParams(\n            name=snapshot_name,\n            image=image,\n            resources=Resources(\n                cpu=1,\n                memory=1,\n                disk=3,\n            ),\n        ),\n        on_logs=print,\n    )\n\n    # 事前ビルド済みのスナップショットを使って新しいサンドボックスを作成\n\n    sandbox = daytona.create(\n        CreateSandboxFromSnapshotParams(\n            snapshot=snapshot_name\n        )\n    )\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    // イメージ用の一意の名前を生成\n    const snapshotName = `node-example:${Date.now()}`\n    console.log(`Creating Snapshot with name: ${snapshotName}`)\n\n    // スナップショットに追加するデータを含むローカルファイルを作成\n    const localFilePath = 'file_example.txt'\n    const localFileContent = 'Hello, World!'\n    fs.writeFileSync(localFilePath, localFileContent)\n\n    // 一般的なデータサイエンスパッケージを含むPythonイメージを作成\n    const image = Image.debianSlim('3.12')\n        .pipInstall(['numpy', 'pandas', 'matplotlib', 'scipy', 'scikit-learn'])\n        .runCommands(\n          'apt-get update && apt-get install -y git',\n          'groupadd -r daytona && useradd -r -g daytona -m daytona',\n          'mkdir -p /home/daytona/workspace'\n        )\n        .dockerfileCommands(['USER daytona'])\n        .workdir('/home/daytona/workspace')\n        .env({\n            MY_ENV_VAR: 'My Environment Variable',\n        })\n        .addLocalFile(localFilePath, '/home/daytona/workspace/file_example.txt')\n\n    # スナップショットを作成し、ビルドログをストリーミング出力\n    console.log(`=== Creating Snapshot: ${snapshotName} ===`)\n    await daytona.snapshot.create(\n        {\n          name: snapshotName,\n          image,\n          resources: {\n            cpu: 1,\n            memory: 1,\n            disk: 3,\n          },\n        },\n        {\n          onLogs: console.log,\n        },\n      )\n\n    // 事前ビルド済みのスナップショットを使って新しいサンドボックスを作成\n    const sandbox = await daytona.create({\n        snapshot: snapshotName,\n    })\n    ```\n  </TabItem>\n</Tabs>\n\n## 既存の Dockerfile を利用する\n\n既存の Dockerfile をイメージのベースとして使いたい場合は、次のようにインポートできます。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    image = Image.from_dockerfile(\"app/Dockerfile\").pip_install([\"numpy\"])\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    const image = Image.fromDockerfile(\"app/Dockerfile\").pipInstall(['numpy'])\n    ```\n  </TabItem>\n</Tabs>\n\n## ベストプラクティス\n\n1. **レイヤー最適化**: 関連する操作をまとめて、Dockerのレイヤー数を抑える\n2. **キャッシュの活用**: 同一のビルドコマンドとコンテキストはキャッシュされ、以降のビルドはほぼ即時に完了する\n3. **セキュリティ**: アプリケーションのワークロード用に非rootユーザーを作成する\n4. **リソース効率**: 適切な場合はスリムなベースイメージを使用する\n5. **コンテキストの最小化**: ビルドコンテキストには必要なファイルだけを含める\n\n宣言的ビルダーは、Dockerの強力さと柔軟性を損なうことなく、コンテナイメージ作成に対するプログラム的で保守しやすいアプローチを提供し、開発ワークフローを効率化します。\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/file-system-operations.mdx",
    "content": "---\ntitle: ファイルシステム操作\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona（サンドボックスという隔離されたクラウド開発環境を作成・管理するプラットフォーム）のSDKは、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）内の`fs`モジュールを通じて、充実したファイルシステム操作機能を提供します。本ガイドでは、利用可能なすべてのファイルシステム操作とベストプラクティスについて説明します。\n\n## 基本操作\n\nDaytona SDK は、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）内のファイルシステムとやり取りする機能を提供します。ファイルの一覧表示、ディレクトリ作成、ファイルの読み書きなど、さまざまな操作を実行できます。\n\n簡潔さのため、ファイル操作はデフォルトでサンドボックスユーザーのホームディレクトリ直下で行われる前提です。例えば、`workspace` は `/home/[username]/workspace` を意味します。先頭にスラッシュ `/` を付けた絶対パスを作業ディレクトリとして指定することも可能です。\n\n### ファイルとディレクトリの一覧表示\n\nDaytona SDK は、Python と TypeScript を用いてサンドボックス内のファイルやディレクトリを一覧表示できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# List files in a directory\nfiles = sandbox.fs.list_files(\"workspace\")\n\nfor file in files:\n    print(f\"Name: {file.name}\")\n    print(f\"Is directory: {file.is_dir}\")\n    print(f\"Size: {file.size}\")\n    print(f\"Modified: {file.mod_time}\")\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// List files in a directory\nconst files = await sandbox.fs.listFiles(\"workspace\")\n\nfiles.forEach(file => {\n    console.log(`Name: ${file.name}`)\n    console.log(`Is directory: ${file.isDir}`)\n    console.log(`Size: ${file.size}`)\n    console.log(`Modified: ${file.modTime}`)\n})\n```\n\n</TabItem>\n</Tabs>\n\n### ディレクトリの作成\n\nDaytona SDK は、Python と TypeScript で特定のパーミッションを指定してディレクトリを作成できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Create with specific permissions\nsandbox.fs.create_folder(\"workspace/new-dir\", \"755\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Create with specific permissions\nawait sandbox.fs.createFolder(\"workspace/new-dir\", \"755\")\n```\n\n</TabItem>\n</Tabs>\n\n### ファイルのアップロード\n\nDaytona SDK は、Python と TypeScript を用いて、サンドボックス内でのファイルの読み取り、書き込み、アップロード、ダウンロード、削除を行うための機能を提供します。\n\n#### 単一ファイルのアップロード\n\n単一ファイルをアップロードする場合は、次のように実行します。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Upload a single file\nwith open(\"local_file.txt\", \"rb\") as f:\n    content = f.read()\nsandbox.fs.upload_file(content, \"remote_file.txt\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Upload a single file\nconst fileContent = Buffer.from('Hello, World!')\nawait sandbox.fs.uploadFile(fileContent, \"data.txt\")\n```\n\n</TabItem>\n</Tabs>\n\n#### 複数ファイルのアップロード\n\n以下は、1回のメソッド呼び出しで複数ファイルを効率的にアップロードする例です。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Upload multiple files at once\nfiles_to_upload = []\n\nwith open(\"file1.txt\", \"rb\") as f1:\n    files_to_upload.append(FileUpload(\n        source=f1.read(),\n        destination=\"data/file1.txt\",\n    ))\n\nwith open(\"file2.txt\", \"rb\") as f2:\n    files_to_upload.append(FileUpload(\n        source=f2.read(),\n        destination=\"data/file2.txt\",\n    ))\n\nwith open(\"settings.json\", \"rb\") as f3:\n    files_to_upload.append(FileUpload(\n        source=f3.read(),\n        destination=\"config/settings.json\",\n    ))\n\nsandbox.fs.upload_files(files_to_upload)\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Upload multiple files at once\nconst files = [\n    {\n        source: Buffer.from('Content of file 1'),\n        destination: 'data/file1.txt',\n    },\n    {\n        source: Buffer.from('Content of file 2'),\n        destination: 'data/file2.txt',\n    },\n    {\n        source: Buffer.from('{\"key\": \"value\"}'),\n        destination: 'config/settings.json',\n    }\n]\n\nawait sandbox.fs.uploadFiles(files)\n```\n\n</TabItem>\n</Tabs>\n\n### ファイルのダウンロード\n\n次のコマンドは、サンドボックスユーザーのホームディレクトリから `file1.txt` をダウンロードし、その内容を出力します。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n\ncontent = sandbox.fs.download_file(\"file1.txt\")\n\nwith open(\"local_file.txt\", \"wb\") as f:\n    f.write(content)\n\nprint(content.decode('utf-8'))\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n\nconst downloadedFile = await sandbox.fs.downloadFile(\"file1.txt\")\n\nconsole.log('File content:', downloadedFile.toString())\n\n```\n\n</TabItem>\n</Tabs>\n\n### ファイルの削除\n\n不要になったファイルは、`delete_file` 関数で削除できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n\nsandbox.fs.delete_file(\"workspace/file.txt\")\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n\nawait sandbox.fs.deleteFile(\"workspace/file.txt\")\n```\n\n</TabItem>\n</Tabs>\n\n## 高度な操作\n\nDaytona SDK は、ファイル権限の設定・取得、検索と置換などの高度なファイルシステム操作を提供します。\n\n### ファイル権限\n\nDaytona SDK では、Python と TypeScript から、ファイル権限の設定・取得や、ディレクトリ権限の再帰的な設定が行えます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Set file permissions\nsandbox.fs.set_file_permissions(\"workspace/file.txt\", \"644\")\n\n# Get file permissions\n\nfile_info = sandbox.fs.get_file_info(\"workspace/file.txt\")\nprint(f\"Permissions: {file_info.permissions}\")\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Set file permissions\nawait sandbox.fs.setFilePermissions(\"workspace/file.txt\", { mode: \"644\" })\n\n// Get file permissions\nconst fileInfo = await sandbox.fs.getFileDetails(\"workspace/file.txt\")\nconsole.log(`Permissions: ${fileInfo.permissions}`)\n```\n\n</TabItem>\n</Tabs>\n\n### ファイルの検索と置換\n\nDaytona SDK では、Python と TypeScript から、ファイル内のテキストの検索および置換を行えます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Search for text in files; if a folder is specified, the search is recursive\nresults = sandbox.fs.find_files(\n    path=\"workspace/src\",\n    pattern=\"text-of-interest\"\n)\nfor match in results:\n    print(f\"Absolute file path: {match.file}\")\n    print(f\"Line number: {match.line}\")\n    print(f\"Line content: {match.content}\")\n    print(\"\\n\")\n\n# Replace text in files\n\nsandbox.fs.replace_in_files(\n    files=[\"workspace/file1.txt\", \"workspace/file2.txt\"],\n    pattern=\"old_text\",\n    new_value=\"new_text\"\n)\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Search for text in files; if a folder is specified, the search is recursive\nconst results = await sandbox.fs.findFiles({\n    path=\"workspace/src\",\n    pattern: \"text-of-interest\"\n})\nresults.forEach(match => {\n    console.log('Absolute file path:', match.file)\n    console.log('Line number:', match.line)\n    console.log('Line content:', match.content)\n})\n\n// Replace text in files\nawait sandbox.fs.replaceInFiles(\n    [\"workspace/file1.txt\", \"workspace/file2.txt\"],\n    \"old_text\",\n    \"new_text\"\n)\n```\n\n</TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/getting-started.mdx",
    "content": "---\ntitle: はじめに\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona SDKはDaytonaと連携するための公式[Python](/docs/ja/python-sdk)および[TypeScript](/docs/ja/typescript-sdk)インターフェースを提供し、開発環境をプログラムで管理し、コードを実行できます。[Python SDK](/docs/ja/python-sdk)は同期・非同期の両方のプログラミングモデルをサポートしており、非同期クラスには`Async`の接頭辞が付きます。\n\n手順に従って、AIエージェント向けの最初のDaytona サンドボックス（Daytonaが管理する隔離された一時的な実行環境）を作成・実行しましょう。\n\n環境変数の設定やステージング環境での実験的機能へのアクセスなど、追加の設定手順については[Configuration](/docs/ja/configuration)を参照してください。\n\n## Daytona SDK をインストールする\n\nDaytona は、Daytona プラットフォームと連携するための公式 Python および TypeScript の SDK を提供しています。お好みの方法で SDK をインストールしてください。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    pip install daytona\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```bash\n    # npm を使用\n    npm install @daytonaio/sdk\n\n    # yarn を使用\n    yarn add @daytonaio/sdk\n\n    # pnpm を使用\n    pnpm add @daytonaio/sdk\n    ```\n  </TabItem>\n</Tabs>\n\n## サンドボックス内でコードを実行する\n\n次のコードを実行して、Daytona のサンドボックスを作成し、コマンドを実行します。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, DaytonaConfig\n\n    # Daytona クライアントを初期化\n    daytona = Daytona(DaytonaConfig(api_key=\"YOUR_API_KEY\"))\n\n    # サンドボックスのインスタンスを作成\n    sandbox = daytona.create()\n\n    # サンドボックス内で安全にコードを実行\n    response = sandbox.process.code_run('print(\"Sum of 3 and 4 is \" + str(3 + 4))')\n    if response.exit_code != 0:\n        print(f\"Error running code: {response.exit_code} {response.result}\")\n    else:\n        print(response.result)\n\n    # サンドボックスをクリーンアップ\n    sandbox.delete()\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona } from '@daytonaio/sdk'\n\n    async function main() {\n      // Daytona クライアントを初期化\n      const daytona = new Daytona({\n        apiKey: 'YOUR_API_KEY',\n      })\n\n      let sandbox;\n      try {\n        // サンドボックスのインスタンスを作成\n        sandbox = await daytona.create({\n          language: \"python\",\n        });\n        // サンドボックス内で安全にコードを実行\n        const response = await sandbox.process.codeRun(\n          'print(\"Sum of 3 and 4 is \" + str(3 + 4))'\n        );\n        if (response.exitCode !== 0) {\n          console.error(\"Error running code:\", response.exitCode, response.result);\n        } else {\n          console.log(response.result);\n        }\n      } catch (error) {\n        console.error(\"Sandbox flow error:\", error);\n      } finally {\n        // サンドボックスをクリーンアップ\n        if (sandbox) {\n          await sandbox.delete();\n        }\n      }\n    }\n\n    main().catch(console.error)\n\n    ```\n  </TabItem>\n</Tabs>\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    python main.py\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```bash\n    npx tsx ./index.ts\n    ```\n  </TabItem>\n</Tabs>\n\n## アプリをプレビュー\n\n次のスニペットは、シンプルな Flask アプリを含むファイルを Daytona のサンドボックスにアップロードします。Web サーバーはポート `3000` で起動し、提供されたプレビューURLからアクセスできます。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, DaytonaConfig, SessionExecuteRequest\n\n    daytona = Daytona(DaytonaConfig(api_key=\"YOUR_API_KEY\"))\n\n    sandbox = daytona.create()\n\n    app_code = b'''\n    from flask import Flask\n\n    app = Flask(__name__)\n\n    @app.route('/')\n    def hello():\n        return \"\"\"\n        <!DOCTYPE html>\n        <html>\n        <head>\n            <title>Hello World</title>\n            <link rel=\"icon\" href=\"https://www.daytona.io/favicon.ico\">\n        </head>\n        <body style=\"display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #0a0a0a; font-family: Arial, sans-serif;\">\n            <div style=\"text-align: center; padding: 2rem; border-radius: 10px; background-color: white; box-shadow: 0 4px 8px rgba(0,0,0,0.1);\">\n                <img src=\"https://raw.githubusercontent.com/daytonaio/daytona/main/assets/images/Daytona-logotype-black.png\" alt=\"Daytona Logo\" style=\"width: 180px; margin: 10px 0px;\">\n                <p>This web app is running in a Daytona sandbox!</p>\n            </div>\n        </body>\n        </html>\n        \"\"\"\n\n    if __name__ == '__main__':\n        app.run(host='0.0.0.0', port=3000)\n    '''\n\n    # Save the Flask app to a file\n\n    sandbox.fs.upload_file(app_code, \"app.py\")\n\n    # Create a new session and execute a command\n\n    exec_session_id = \"python-app-session\"\n    sandbox.process.create_session(exec_session_id)\n\n    sandbox.process.execute_session_command(exec_session_id, SessionExecuteRequest(\n        command=\"python /app.py\",\n        var_async=True\n    ))\n\n    # Get the preview link for the Flask app\n\n    preview_info = sandbox.get_preview_link(3000)\n    print(f\"Flask app is available at: {preview_info.url}\")\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona } from '@daytonaio/sdk';\n\n    const daytona = new Daytona(({\n      apiKey: \"YOUR_API_KEY\"\n    }));\n\n    async function main() {\n      const sandbox = await daytona.create();\n\n      const appCode = Buffer.from(`\n    from flask import Flask\n\n    app = Flask(__name__)\n\n    @app.route('/')\n    def hello():\n        return \"\"\"\n        <!DOCTYPE html>\n        <html>\n        <head>\n            <title>Hello World</title>\n            <link rel=\"icon\" href=\"https://www.daytona.io/favicon.ico\">\n        </head>\n        <body style=\"display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #0a0a0a; font-family: Arial, sans-serif;\">\n            <div style=\"text-align: center; padding: 2rem; border-radius: 10px; background-color: white; box-shadow: 0 4px 8px rgba(0,0,0,0.1);\">\n                <img src=\"https://raw.githubusercontent.com/daytonaio/daytona/main/assets/images/Daytona-logotype-black.png\" alt=\"Daytona Logo\" style=\"width: 180px; margin: 10px 0px;\">\n                <p>This web app is running in a Daytona sandbox!</p>\n            </div>\n        </body>\n        </html>\n        \"\"\"\n\n    if __name__ == '__main__':\n        app.run(host='0.0.0.0', port=3000)\n      `);\n\n      // Save the Flask app to a file\n      await sandbox.fs.uploadFile(appCode, \"app.py\");\n\n      // Create a new session and execute a command\n      const execSessionId = \"python-app-session\";\n      await sandbox.process.createSession(execSessionId);\n\n      await sandbox.process.executeSessionCommand(execSessionId, ({\n        command: `python app.py`,\n        async: true,\n      }));\n\n      // Get the preview link for the Flask app\n      const previewInfo = await sandbox.getPreviewLink(3000);\n      console.log(`Flask app is available at: ${previewInfo.url}`);\n    }\n\n    main().catch(error => console.error(\"Error:\", error));\n\n    ```\n  </TabItem>\n</Tabs>\n\nこのエンドポイントにプログラムからアクセスする必要がありますか？[プレビューと認証](/docs/ja/preview-and-authentication)をご覧ください。\n\n:::tip\nポート `22222` のプレビューURLを表示するか、Dashboard -> Sandboxes に移動して Terminal のアイコンをクリックすると、サンドボックスの[Web Terminal](/docs/ja/web-terminal)にアクセスできます。\n:::\n\n## LLM に接続する\n\n次のスニペットは、Anthropic API を用いて LLM に接続し、Claude に 25 の階乗を求めるコードの生成を依頼し、そのコードを Daytona のサンドボックス（Daytonaが管理する隔離された一時的な実行環境）内で実行します。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ````python\n    import os\n    import re\n    import requests\n    from daytona import Daytona, DaytonaConfig\n    from dotenv import load_dotenv\n\n    load_dotenv()\n\n    daytona = Daytona(DaytonaConfig())\n\n    sandbox = daytona.create()\n\n    def get_claude_response(api_key, prompt):\n        url = \"https://api.anthropic.com/v1/messages\"\n        headers = {\n            \"x-api-key\": api_key,\n            \"anthropic-version\": \"2023-06-01\",\n            \"Content-Type\": \"application/json\"\n        }\n        data = {\n            \"model\": \"claude-3-7-sonnet-latest\",\n            \"max_tokens\": 256,\n            \"messages\": [{\"role\": \"user\", \"content\": prompt}]\n        }\n        response = requests.post(url, json=data, headers=headers)\n        if response.status_code == 200:\n            content = response.json().get(\"content\", [])\n            return \"\".join([item[\"text\"] for item in content if item[\"type\"] == \"text\"])\n        else:\n            return f\"Error {response.status_code}: {response.text}\"\n\n    prompt = \"25 の階乗を返す Python コード。出力はコードのみ。説明なし。前置きなし。コメントなし。単一のコードブロックで生のコードのみ。\"\n\n    result = get_claude_response(os.environ[\"ANTHROPIC_API_KEY\"], prompt)\n\n    code_match = re.search(r\"```python\\n(.*?)```\", result, re.DOTALL)\n\n    code = code_match.group(1) if code_match else result\n    code = code.replace('\\\\', '\\\\\\\\')\n\n    # サンドボックス内で Python コードを実行し、結果を取得\n\n    response = sandbox.process.code_run(code)\n    print(\"The factorial of 25 is\", response.result)\n\n    ````\n\n    スニペットを実行する:\n\n    ```bash\n    ANTHROPIC_API_KEY=\"your-anthropic-api-key\"\n    DAYTONA_API_KEY=\"your-daytona-api-key\"\n    DAYTONA_TARGET=us\n    python claude-example.py\n    ```\n\n    ```bash\n    > 25 の階乗は 15511210043330985984000000 です\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ````typescript\n    import { Daytona } from '@daytonaio/sdk'\n    import * as dotenv from 'dotenv'\n    import axios from 'axios'\n\n    dotenv.config()\n\n    const daytona = new Daytona()\n\n    async function getClaudeResponse(apiKey: string, prompt: string): Promise<string> {\n      const url = \"https://api.anthropic.com/v1/messages\"\n      const headers = {\n        \"x-api-key\": apiKey,\n        \"anthropic-version\": \"2023-06-01\",\n        \"Content-Type\": \"application/json\"\n      }\n      const data = {\n        \"model\": \"claude-3-7-sonnet-latest\",\n        \"max_tokens\": 256,\n        \"messages\": [{\"role\": \"user\", \"content\": prompt}]\n      }\n\n      try {\n        const response = await axios.post(url, data, { headers })\n        if (response.status === 200) {\n          const content = response.data.content || []\n          return content\n            .filter((item: any) => item.type === \"text\")\n            .map((item: any) => item.text)\n            .join(\"\")\n        } else {\n          return `Error ${response.status}: ${response.statusText}`\n        }\n      } catch (error: any) {\n        return `Error: ${error.message}`\n      }\n    }\n\n    async function main() {\n      const sandbox = await daytona.create()\n\n      const prompt = \"25 の階乗を返す Python コード。コードのみを出力。説明なし。前置きなし。コメントなし。単一のコードブロックに生のコードのみ。\"\n      \n      const result = await getClaudeResponse(process.env.ANTHROPIC_API_KEY || \"\", prompt)\n      \n      // レスポンスから正規表現でコードを抽出\n      const codeMatch = result.match(/```python\\n(.*?)```/s)\n      \n      let code = codeMatch ? codeMatch[1] : result\n      code = code.replace(/\\\\/g, '\\\\\\\\')\n      \n      // 抽出したコードをサンドボックスで実行\n      const response = await sandbox.process.codeRun(code)\n      console.log(\"The factorial of 25 is\", response.result)\n    }\n\n    main().catch(console.error)\n\n    ````\n\n    スニペットを実行する:\n\n    ```bash\n    ANTHROPIC_API_KEY=\"your-anthropic-api-key\"\n    DAYTONA_API_KEY=\"your-daytona-api-key\"\n    DAYTONA_TARGET=us\n    npx ts-node claude-example.ts\n    ```\n\n    ```bash\n    > 25の階乗は 15511210043330985984000000 です\n    ```\n  </TabItem>\n</Tabs>\n\n## 追加の例\n\nDaytona SDK の [Python の例](https://github.com/daytonaio/daytona/tree/main/examples/python) または [TypeScript/JavaScript の例](https://github.com/daytonaio/daytona/tree/main/examples/typescript) を使ってサンドボックス（Daytonaが管理する隔離された一時的な実行環境）を作成し、コードを実行しましょう。\n\nLLM を活用して Daytona 上での開発を加速できます。/llms.txt ファイルをコピーし、プロジェクトやチャットのコンテキストに含めてください: [llms-full.txt](https://www.daytona.io/docs/llms-full.txt) または [llms.txt](https://www.daytona.io/docs/llms.txt)\n\n[GitHub](https://github.com/daytonaio/daytona) 上の Daytona SDK リポジトリを参照して、さらに詳しく学びましょう。\n\n## ViteプロジェクトでのDaytona\n\nViteベースのプロジェクトでDaytona SDKを使用する場合、互換性を確保するためにNodeのポリフィルを設定する必要があります。`vite.config.ts` のplugins配列に以下の設定を追加してください：\n\n```typescript\nimport { nodePolyfills } from 'vite-plugin-node-polyfills'\n\nexport default defineConfig({\n  plugins: [\n    // ... other plugins\n    nodePolyfills({\n      globals: { global: true, process: true, Buffer: true },\n      overrides: {\n        path: 'path-browserify-win32',\n      },\n    }),\n  ],\n  // ... rest of your config\n})\n```\n\n## Next.js プロジェクトにおける Daytona\n\nNext.js プロジェクトで Daytona SDK を使用する場合、利用中のバンドラーに応じて Webpack や Turbopack との互換性を保つため、Node のポリフィルを設定する必要があります。次の設定を `next.config.ts` に追加してください:\n\n```typescript\nimport type { NextConfig } from 'next'\nimport NodePolyfillPlugin from 'node-polyfill-webpack-plugin'\nimport { env, nodeless } from 'unenv'\n\nconst { alias: turbopackAlias } = env(nodeless, {})\n\nconst nextConfig: NextConfig = {\n  // Turbopack\n  experimental: {\n    turbo: {\n      resolveAlias: {\n        ...turbopackAlias,\n      },\n    },\n  },\n  // Webpack\n  webpack: (config, { isServer }) => {\n    if (!isServer) {\n      config.plugins.push(new NodePolyfillPlugin())\n    }\n    return config\n  },\n}\n\nexport default nextConfig\n```\n\n## Daytona CLI のセットアップ\n\n[ローカルデバイス上のイメージ](/docs/ja/snapshots#using-a-local-image)を使用する場合、またはコマンドラインインターフェースでサンドボックスを管理したい場合は、次のコマンドで Daytona CLI をインストールしてください:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Mac/Linux\">\n    ```bash\n    brew install daytonaio/cli/daytona\n    ```\n  </TabItem>\n\n  <TabItem label=\"Windows\">\n    ```bash\n    powershell -Command \"irm https://get.daytona.io/windows | iex\"\n    ```\n  </TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/git-operations.mdx",
    "content": "---\ntitle: Git操作\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona SDKは、Sandbox内の`git`モジュールを通じてGitの組み込みサポートを提供します。本ガイドでは、利用可能なすべてのGit操作とベストプラクティスを解説します。\n\n## 基本操作\n\nDaytona SDKは、Sandbox（Daytonaが管理する隔離された一時的な実行環境）内でGitリポジトリのクローン、ステータス確認、管理を行う機能を提供します。`git`モジュールを使ってGitリポジトリを操作できます。\n\nファイル操作と同様に、クローンの基準ディレクトリは現在のSandboxユーザーのホームです。例えば、`workspace/repo` は `/home/[username]/workspace/repo` を意味します。先頭を `/` にすることで作業ディレクトリに絶対パスも指定できます。\n\n### リポジトリのクローン\n\nDaytona SDKは、PythonおよびTypeScriptからSandboxにGitリポジトリをクローンできます。パブリック/プライベートリポジトリ、特定ブランチのクローンに対応し、Personal Access Tokenを用いた認証も可能です。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Basic clone\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# Clone with authentication\n\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\",\n    username=\"git\",\n    password=\"personal_access_token\"\n)\n\n# Clone specific branch\n\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\",\n    branch=\"develop\"\n)\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Basic clone\nawait sandbox.git.clone(\n    \"https://github.com/user/repo.git\",\n    \"workspace/repo\"\n);\n\n// Clone with authentication\nawait sandbox.git.clone(\n    \"https://github.com/user/repo.git\",\n    \"workspace/repo\",\n    undefined,\n    undefined,\n    \"git\",\n    \"personal_access_token\"\n);\n\n// Clone specific branch\nawait sandbox.git.clone(\n    \"https://github.com/user/repo.git\",\n    \"workspace/repo\",\n    \"develop\"\n);\n```\n\n</TabItem>\n</Tabs>\n\n### リポジトリのステータス\n\nDaytona SDKは、Sandbox内のGitリポジトリのステータス確認にも対応しています。PythonおよびTypeScriptで、現在のブランチ、変更ファイル、メインブランチに対する先行/遅行コミット数を取得できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Get repository status\nstatus = sandbox.git.status(\"workspace/repo\")\nprint(f\"Current branch: {status.current_branch}\")\nprint(f\"Commits ahead: {status.ahead}\")\nprint(f\"Commits behind: {status.behind}\")\nfor file in status.file_status:\n    print(f\"File: {file.name}\")\n\n# List branches\n\nresponse = sandbox.git.branches(\"workspace/repo\")\nfor branch in response.branches:\n    print(f\"Branch: {branch}\")\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// Get repository status\nconst status = await sandbox.git.status(\"workspace/repo\");\nconsole.log(`Current branch: ${status.currentBranch}`);\nconsole.log(`Commits ahead: ${status.ahead}`);\nconsole.log(`Commits behind: ${status.behind}`);\nstatus.fileStatus.forEach(file => {\n    console.log(`File: ${file.name}`);\n});\n\n// List branches\nconst response = await sandbox.git.branches(\"workspace/repo\");\nresponse.branches.forEach(branch => {\n    console.log(`Branch: ${branch}`);\n});\n```\n\n</TabItem>\n</Tabs>\n\n## ブランチ操作\n\nDaytona SDK は、Git リポジトリのブランチ管理機能を提供します。ブランチの作成・切り替え・削除が可能です。\n\n### ブランチの管理\n\nDaytona SDK では、Python と TypeScript から Git リポジトリのブランチを作成・切り替え・削除できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# 新しいブランチを作成\nsandbox.git.create_branch(\"workspace/repo\", \"feature/new-feature\")\n\n# ブランチを切り替え\nsandbox.git.checkout_branch(\"workspace/repo\", \"feature/new-feature\")\n\n# ブランチを削除\nsandbox.git.delete_branch(\"workspace/repo\", \"feature/old-feature\")\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// 新しいブランチを作成\nawait sandbox.git.createBranch(\"workspace/repo\", \"feature/new-feature\");\n\n// ブランチを切り替え\nawait sandbox.git.checkoutBranch(\"workspace/repo\", \"feature/new-feature\");\n\n// ブランチを削除\nawait sandbox.git.deleteBranch(\"workspace/repo\", \"feature/old-feature\");\n```\n\n</TabItem>\n</Tabs>\n\n## ステージングとコミット\n\nDaytona SDK では、Git リポジトリの変更をステージしてコミットできます。Python と TypeScript から、特定のファイルのみ、またはすべての変更をステージし、メッセージ付きでコミットできます。\n\n### 変更の扱い\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# 特定のファイルをステージ\nsandbox.git.add(\"workspace/repo\", [\"file1.txt\", \"file2.txt\"])\n\n# すべての変更をステージ\nsandbox.git.add(\"workspace/repo\", [\".\"])\n\n# 変更をコミット\nsandbox.git.commit(\"workspace/repo\", \"feat: add new feature\", \"John Doe\", \"john@example.com\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// 特定のファイルをステージ\nawait sandbox.git.add(\"workspace/repo\", [\"file1.txt\", \"file2.txt\"]);\n\n// すべての変更をステージ\nawait sandbox.git.add(\"workspace/repo\", [\".\"]);\n\n// 変更をコミット\nawait sandbox.git.commit(\"workspace/repo\", \"feat: add new feature\", \"John Doe\", \"john@example.com\");\n```\n\n</TabItem>\n</Tabs>\n\n## リモート操作\n\nDaytona SDK は Git のリモートリポジトリを扱う機能を提供します。変更のプッシュ、変更のプル、リモートの一覧表示が可能です。\n\n### リモートの操作\n\nDaytona SDK は、Python と TypeScript から Git リポジトリに対してプッシュ、プル、リモートの一覧表示を行う機能を提供します。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# 変更をプッシュ\nsandbox.git.push(\"workspace/repo\")\n\n# 変更をプル\nsandbox.git.pull(\"workspace/repo\")\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// 変更をプッシュ\nawait sandbox.git.push(\"workspace/repo\");\n\n// 変更をプル\nawait sandbox.git.pull(\"workspace/repo\");\n```\n\n</TabItem>\n</Tabs>"
  },
  {
    "path": "apps/docs/src/content/docs/ja/index.mdx",
    "content": "---\ntitle: Daytona Documentation\ndescription: Daytona でサンドボックスの管理を始めましょう。\ntemplate: doc\nhead:\n  - tag: title\n    content: Documentation · Daytona\n  - tag: meta\n    attrs:\n        property: og:title\n        content: Documentation · Daytona\n  - tag: meta\n    attrs:\n        name: twitter:title\n        content: Documentation · Daytona\ntableOfContents: false\n---\n\nimport { Tabs, TabItem } from '@astrojs/starlight/components';\nimport ExploreMore from '@components/ExploreMore.astro';\n\nDaytona SDK は Daytona と対話するための公式の Python および TypeScript インターフェースを提供し、開発環境をプログラムから管理してコードを実行できます。\n\n### クイックスタート\n\nDaytona のサンドボックスで最初のコードを実行しましょう。AI アシスタントとの開発を加速するために、[LLMs のコンテキストファイル](/docs/ja/getting-started#additional-examples)を活用してください。\n\n#### 1. APIキーを取得する\n\n- Daytona の[ダッシュボード](https://app.daytona.io/dashboard)に移動します。\n- 新しい[APIキー](https://app.daytona.io/dashboard/keys)を作成します。安全な場所に保存してください。再表示はされません。\n\n#### 2. SDK をインストールする\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    pip install daytona\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```bash\n    npm install @daytonaio/sdk\n    ```\n  </TabItem>\n</Tabs>\n\n#### 3. コードを書く\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    次の名前のファイルを作成します: `main.py`\n\n    ```python\n    from daytona import Daytona, DaytonaConfig\n\n    # 設定を定義\n\n    config = DaytonaConfig(api_key=\"your-api-key\")\n\n    # Daytona クライアントを初期化\n\n    daytona = Daytona(config)\n\n    # サンドボックスのインスタンスを作成\n\n    sandbox = daytona.create()\n\n    # サンドボックス内で安全にコードを実行\n\n    response = sandbox.process.code_run('print(\"Hello World from code!\")')\n    if response.exit_code != 0:\n      print(f\"Error: {response.exit_code} {response.result}\")\n    else:\n        print(response.result)\n\n    # 後片付け\n\n    sandbox.delete()\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    次の名前のファイルを作成します: `index.mts`\n\n    ```typescript\n    import { Daytona } from '@daytonaio/sdk';\n\n    // Daytona クライアントを初期化\n    const daytona = new Daytona({ apiKey: 'your-api-key' });\n\n    // サンドボックスのインスタンスを作成\n    const sandbox = await daytona.create({\n      language: 'typescript',\n    });\n\n    // サンドボックス内で安全にコードを実行\n    const response = await sandbox.process.codeRun('console.log(\"Hello World from code!\")')\n    console.log(response.result);\n\n    // 後片付け\n    await sandbox.delete()\n    ```\n  </TabItem>\n</Tabs>\n\n:::note\n`your-api-key` は Daytona ダッシュボードで取得した値に置き換えてください。\n:::\n\n#### 4. 実行する\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```bash\n    python main.py\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```bash\n    npx tsx index.mts\n    ```\n  </TabItem>\n</Tabs>\n\n#### ✅ 今やったこと\n\n- Daytona SDK をインストールしました。\n- セキュアなサンドボックス環境を作成しました。\n- そのサンドボックス内でコードをリモート実行しました。\n- 出力をローカルで取得して表示しました。\n\nこれで、Daytona を使ったセキュアで分離されたコード実行を開始できます。\n\n<ExploreMore />\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/language-server-protocol.mdx",
    "content": "---\ntitle: Language Server Protocol\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona（デイトナ）SDKは、サンドボックスインスタンス経由でLSP（Language Server Protocol）をサポートします。これにより、コード補完や診断などの高度な言語機能を利用できます。\n\n## LSPサーバーの作成\n\nDaytona（デイトナ）SDKは、PythonおよびTypeScriptでLSPサーバーを作成する機能を提供します。`path_to_project` の基準パスはデフォルトで現在のサンドボックスユーザーのホーム直下です。たとえば `workspace/project` は `/home/[username]/workspace/project` を指します。先頭を `/` にすることで絶対パスも指定できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\nfrom daytona import Daytona, LspLanguageId\n\n# サンドボックスを作成\n\ndaytona = Daytona()\nsandbox = daytona.create()\n\n# Python用のLSPサーバーを作成\n\nlsp_server = sandbox.create_lsp_server(\n    language_id=LspLanguageId.PYTHON,\n    path_to_project=\"workspace/project\"\n)\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { Daytona, LspLanguageId } from '@daytonaio/sdk'\n\n// サンドボックスを作成\nconst daytona = new Daytona()\nconst sandbox = await daytona.create({\n    language: 'typescript'\n})\n\n// TypeScript用のLSPサーバーを作成\nconst lspServer = await sandbox.createLspServer(\n    LspLanguageId.TYPESCRIPT,\n    \"workspace/project\"\n)\n```\n\n</TabItem>\n</Tabs>\n\n## サポート対象の言語\n\nDaytona SDK では、Python および TypeScript の `LspLanguageId` 列挙体を使用して、各種言語向けの LSP サーバーを作成できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\nfrom daytona import LspLanguageId\n\n# 利用可能な言語 ID\n\nLspLanguageId.PYTHON\nLspLanguageId.TYPESCRIPT\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { LspLanguageId } from '@daytonaio/sdk'\n\n// 利用可能な言語 ID\nLspLanguageId.PYTHON      \nLspLanguageId.TYPESCRIPT    \n```\n\n</TabItem>\n</Tabs>\n\n- `LspLanguageId.PYTHON`: Python 向け言語サーバー。\n- `LspLanguageId.TYPESCRIPT`: TypeScript/JavaScript 向け言語サーバー。\n\n## LSP 機能\n\nDaytona SDK は、コード解析や編集のための各種 LSP 機能を提供します。\n\n### コード補完\n\nDaytona SDK では、Python と TypeScript を用いて、ファイル内の特定位置のコード補完候補を取得できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\ncompletions = lsp_server.completions(\n    path=\"workspace/project/main.py\",\n    position={\"line\": 10, \"character\": 15}\n)\nprint(f\"Completions: {completions}\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nconst completions = await lspServer.completions(\n    \"workspace/project/main.ts\",\n    { line: 10, character: 15 }\n)\nconsole.log('Completions:', completions)\n```\n</TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/limits.mdx",
    "content": "---\ntitle: 制限\n---\n\nDaytonaは、すべての組織での公平な利用と安定性を確保するため、リソース制限を適用しています。組織は、次のリソースで構成されるコンピュートプールにアクセスできます:\n\n- **vCPU** — 利用可能なCPUコアの総数\n- **Memory** — 利用可能なRAMの総量\n- **Storage** — 利用可能なディスク容量の総量\n\nこれらのリソースはプールされ、稼働中のすべてのサンドボックス間で共有されます。\\\n同時に実行できるサンドボックス数は、各サンドボックスが使用するCPU、RAM、ストレージの量によって異なります。リソース使用量の設定や見積もり方法は、[サンドボックス管理のドキュメント](https://www.daytona.io/docs/sandboxes/)を参照してください。\n\n## ティアと上限引き上げ\n\n組織は認証状況に基づいて自動的にティアに割り当てられます。\\\n以下の手順を完了すると、より高い上限を利用できるようになります:\n\n| ティア   | リソース (vCPU / RAM / Storage) | アクセス要件                                                                                                            |\n| ------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |\n| ティア 1 | 10 / 10GiB / 30GiB               | メール認証済み                                                                                                          |\n| ティア 2 | 100 / 200GiB / 300GiB            | クレジットカード連携、$25 のチャージ、[GitHub 連携](https://www.daytona.io/docs/linked-accounts#how-to-link-an-account)。 |\n| ティア 3 | 250 / 500GiB / 2000GiB           | 企業メール認証済み、電話番号認証済み、$500 のチャージ。                                                                   |\n| ティア 4 | 500 / 1000GiB / 5000GiB          | 30 日ごとに $2000 のチャージ。                                                                                           |\n| カスタム | カスタム上限                      | [support@daytona.io](mailto:support@daytona.io) までご連絡ください                                                       |\n\nより高いティアの条件を満たしたら、[Dashboard](https://app.daytona.io/dashboard/limits) の「Upgrade」ボタンをクリックしてアップグレードしてください。\n\n:::tip\n\n### 利用状況を動的に管理する\n\nサンドボックスの状態によるリソースへの影響は次のとおりです:\n\n- **Running:** Compute、Memory、Storage を使用します。\n- **Stopped:** Compute と Memory は解放されますが、Storage は引き続き使用します。\n- **Archived:** データをコールドストレージに移し、すべてのリソースを解放します。\n- **Deleted:** 完全に削除され、すべてのリソースが解放されます。\n\n:::\n\n現在の使用量と上限は [Dashboard](https://app.daytona.io/dashboard/limits) で確認できます。\n\n## さらに必要ですか？\n\nより高い、または特別な上限が必要な場合は、[support@daytona.io](mailto:support@daytona.io) までお問い合わせください。\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/linked-accounts.mdx",
    "content": "---\ntitle: 連携済みアカウント\n---\n\nDaytona は、さまざまなアイデンティティプロバイダーのユーザーアカウント連携をサポートしています。現時点でサポートされているプロバイダーは次のとおりです：\n\n- Google\n- GitHub\n\nこれにより、Daytona アカウントへのログインに異なるプロバイダーを利用できます。\n\n:::tip\n\n#### より高い使用上限を解放\n\nGitHub アカウントの連携は、Tier 2 へ自動アップグレードされるための要件の一つです。\n\n:::\n\n## アカウントをリンクする方法\n\nアカウントをリンクするには、Daytona ダッシュボードの[Linked Accounts](https://app.daytona.io/dashboard/user/linked-accounts)ページに移動し、リンクしたいアカウントプロバイダーの「Link Account」ボタンをクリックします。\n\n## アカウントの連携解除方法\n\nアカウントの連携を解除するには、Daytona ダッシュボードの [Linked Accounts](https://app.daytona.io/dashboard/user/linked-accounts) ページを開き、連携を解除したいアカウントプロバイダーの「Unlink」ボタンをクリックします。\n\n## さらにサポートが必要ですか？\n\n他のアイデンティティプロバイダーへの対応が必要な場合は、[support@daytona.io](mailto:support@daytona.io) までご連絡ください。\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/log-streaming.mdx",
    "content": "---\ntitle: ログストリーミング\n---\n\nサンドボックス（隔離された一時的な実行環境）で長時間動作するプロセスを扱う場合、**リアルタイム**でログにアクセスし処理したいことがよくあります。\n\nDaytona（サンドボックスを作成・管理するプラットフォーム）のSDKは次の両方をサポートします:\n\n- `Fetching log snapshot` — 指定時点までのすべてのログを取得します。\n- `Log streaming` — プロセスの実行中に生成されるログをストリーミングします。\n\nこのガイドでは、非同期モードと同期モードの両方でログストリーミングを使用する方法を説明します。\nリアルタイムストリーミングは、**デバッグ**、**モニタリング**、および**可観測性ツール**との統合に特に有用です。\n\n## 非同期\n\nサンドボックス（隔離された一時的な実行環境）内のプロセスが大規模なシステムの一部で、長時間（あるいは無期限に）稼働する場合でも、\nシステムの他の処理を進めながら、ログを**バックグラウンド**で非同期に処理できます。\n\nこの方法は次の用途に最適です:\n\n- 継続的な監視\n- 長時間実行ジョブのデバッグ\n- ライブログの転送や可視化\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\nimport asyncio\nfrom daytona import Daytona, SessionExecuteRequest\n\nasync def main():\n    daytona = Daytona()\n    sandbox = daytona.create()\n\n    try:\n        session_id = \"exec-session-1\"\n        sandbox.process.create_session(session_id)\n\n        command = sandbox.process.execute_session_command(\n            session_id,\n            SessionExecuteRequest(\n                command='for i in {1..10}; do echo \"Processing step $i...\"; sleep 1; done',\n                var_async=True,\n            ),\n        )\n\n        logs_task = asyncio.create_task(\n            sandbox.process.get_session_command_logs_async(\n                session_id, command.cmd_id, lambda chunk: print(f\"Log chunk: {chunk}\")\n            )\n        )\n\n        print(\"Continuing execution while logs are streaming...\")\n        await asyncio.sleep(1)\n        print(\"Other operations completed!\")\n\n        print(\"At the end wait for any asynchronous task to complete and clean up resources...\")\n        await logs_task\n    except Exception as e:\n        print(f\"Error: {e}\")\n    finally:\n        print(\"Cleaning up sandbox...\")\n        sandbox.delete()\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n\n```\n</TabItem>\n  <TabItem label=\"Typescript\" icon=\"seti:typescript\">\n  ```typescript\n  import { Daytona, Sandbox } from '@daytonaio/sdk'\n\n  async function main() {\n    const daytona = new Daytona()\n    const sandbox = await daytona.create()\n\n    try {           \n      const sessionId = 'exec-session-async-logs'\n      await sandbox.process.createSession(sessionId)\n\n      const command = await sandbox.process.executeSessionCommand(sessionId, {\n        command: 'for i in {1..10}; do echo \"Processing step $i...\"; sleep 1; done',\n        async: true,\n      })\n\n      const logTask = sandbox.process.getSessionCommandLogs(sessionId, command.cmdId!, (chunk) => {\n        console.log('Log chunk:', chunk)\n      })\n\n      console.log('Continuing execution while logs are streaming...')\n      sleep(1)\n      console.log('Other operations completed!')\n\n      console.log('At the end wait for any asynchronous task to complete and clean up resources...')\n      await logTask\n    } catch (error) {\n      console.error('Error:', error)\n    } finally {\n      console.log('Cleaning up sandbox...')\n      await sandbox.delete()\n    }\n  }\n\n  main()\n  ```\n\n  </TabItem>\n</Tabs>\n\n## 同期実行\n\nコマンドの実行時間が予測できる場合、またはバックグラウンドで動かす必要がない場合は、\nログストリームを同期的に処理できます。たとえば、ログをファイルやその他のストレージに書き出せます。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n  ```python\n  import asyncio\n  import os\n  from daytona import Daytona, SessionExecuteRequest\n\n  async def main():\n      daytona = Daytona()\n      sandbox = daytona.create()\n\n      try:\n          session_id = \"exec-session-1\"\n          sandbox.process.create_session(session_id)\n\n          command = sandbox.process.execute_session_command(\n              session_id,\n              SessionExecuteRequest(\n                  command='counter=1; while (( counter <= 5 )); do echo \"Count: $counter\"; ((counter++)); sleep 2; done',\n                  var_async=True,\n              ),\n          )\n\n          log_file_path = f\"./logs/logs-session_{session_id}-command_{command.cmd_id}.log\"\n          os.makedirs(os.path.dirname(log_file_path), exist_ok=True)\n\n          with open(log_file_path, \"w\") as log_file:\n              def handle_chunk(chunk: str):\n                  #  nullバイトを削除\n                  clean_chunk = chunk.replace(\"\\x00\", \"\")\n                  #  ファイルに書き込む\n                  log_file.write(clean_chunk)\n                  log_file.flush()\n\n              await sandbox.process.get_session_command_logs_async(\n                  session_id, command.cmd_id, handle_chunk\n              )\n      except Exception as e:\n          print(f\"Error: {e}\")\n      finally:\n          print(\"Cleaning up sandbox...\")\n          sandbox.delete()\n\n  if __name__ == \"__main__\":\n      asyncio.run(main())\n\n  ```\n  </TabItem>\n  <TabItem label=\"Typescript\" icon=\"seti:typescript\">\n  ```typescript\n  import { Daytona, Sandbox } from '@daytonaio/sdk'\n\n  async function main() {\n    const daytona = new Daytona()\n    const sandbox = await daytona.create()\n\n    try {           \n      const sessionId = 'exec-session-async-logs'\n      await sandbox.process.createSession(sessionId)\n\n      const command = await sandbox.process.executeSessionCommand(sessionId, {\n        command: 'counter=1; while (( counter <= 5 )); do echo \"Count: $counter\"; ((counter++)); sleep 2; done',\n        async: true,\n      })\n\n      const logFilePath = `./logs/logs-session-${sessionId}-command-${command.cmdId}.log`\n      const logsDir = path.dirname(logFilePath)\n      if (!fs.existsSync(logsDir)) {\n        fs.mkdirSync(logsDir, { recursive: true })\n      }\n\n      const stream = fs.createWriteStream(logFilePath)\n      await sandbox.process.getSessionCommandLogs(sessionId, command.cmdId!, (chunk) => {\n        const cleanChunk = chunk.replace(/\\x00/g, '')\n        stream.write(cleanChunk)\n      })\n      stream.end()\n      await logTask\n    } catch (error) {\n      console.error('Error:', error)\n    } finally {\n      console.log('Cleaning up sandbox...')\n      await sandbox.delete()\n    }\n  }\n\n  main()\n  ```\n\n  </TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/mcp.mdx",
    "content": "---\ntitle: Daytona MCPサーバー\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona Model Context Protocol (MCP) サーバーは、AIエージェントがDaytonaの機能にプログラムからアクセスし、操作できるようにします。本ガイドでは、各種AIエージェントでMCPサーバーをセットアップして利用する方法を解説します。\n\n## 前提条件\n\n開始する前に、以下を用意してください:\n\n- Daytona アカウント\n- Daytona CLI がインストールされていること\n- 互換性のある AI エージェント（Claude Desktop App、Claude Code、Cursor、または Windsurf）\n\n## インストールとセットアップ\n\n### 1. Daytona CLI のインストール\n\n<Tabs syncKey=\"os\">\n<TabItem label=\"Mac/Linux\">\n```bash\nbrew install daytonaio/cli/daytona\n```\n\n</TabItem>\n<TabItem label=\"Windows\">\n```bash\npowershell -Command \"irm https://get.daytona.io/windows | iex\"\n```\n</TabItem>\n</Tabs>\n\n### 2. Daytona に認証する\n\n```bash\ndaytona login\n```\n\n### 3. MCPサーバーを初期化\n\n使用するAIエージェントで Daytona の MCPサーバーを初期化します:\n\n```bash\ndaytona mcp init [claude/cursor/windsurf]\n```\n\n### 4. AIエージェントを起動\n\n初期化後、AIエージェントのアプリケーションを起動して、Daytona の機能の利用を開始します。\n\n## 他のAIエージェントとの統合\n\nDaytona MCP を他のAIエージェントと統合するには、次の手順に従ってください。\n\n1. MCP の設定を生成します:\n\n```bash\ndaytona mcp config\n```\n\nこのコマンドは、エージェントの設定にコピーできる JSON 設定を出力します:\n\n```json\n{\n  \"mcpServers\": {\n    \"daytona-mcp\": {\n      \"command\": \"daytona\",\n      \"args\": [\"mcp\", \"start\"],\n      \"env\": {\n        \"HOME\": \"${HOME}\",\n        \"PATH\": \"${HOME}:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin\"\n      },\n      \"logFile\": \"${HOME}/Library/Logs/daytona/daytona-mcp-server.log\"\n    }\n  }\n}\n```\n\n:::note\nWindows ユーザーは、`env` フィールドに次を追加してください:\n\n```json\n\"APPDATA\": \"${APPDATA}\"\n```\n\n:::\n\n2. 設定を反映するため、AI エージェントを開き直すか再起動します。\n\n## 利用可能なツール\n\n### サンドボックス管理\n\n- **サンドボックスの作成**\n\n  - 新しい Daytona サンドボックスを作成します\n  - パラメータ:\n    - `target` (default: \"us\"): ターゲット (リージョン)\n    - `snapshot`: サンドボックス用のスナップショット (任意)\n    - `auto_stop_interval` (default: \"15\"): 自動停止までの分数 (0 で無効)\n    - `auto_archive_interval` (default: \"10080\"): 自動アーカイブまでの分数 (0 の場合は最大間隔が適用)\n\n- **サンドボックスの破棄**\n  - 既存の Daytona サンドボックスを削除します\n\n### ファイル操作\n\n- **ファイルのダウンロード**\n\n  - Daytona サンドボックスからファイルをダウンロードします\n  - コンテンツをテキストまたは base64 エンコード画像として返します\n  - パラメータ:\n    - `file_path`: ファイルパス\n\n- **ファイルのアップロード**\n\n  - Daytona サンドボックスにファイルをアップロードします\n  - テキストまたは base64 エンコードのバイナリをサポート\n  - 必要な親ディレクトリを自動作成\n  - 適切な権限でセッション中はファイルを保持\n  - 上書き制御をサポートし、元のファイル形式を維持\n  - パラメータ:\n    - `file_path`: アップロードするファイルのパス\n    - `content`: アップロードするファイルの内容\n    - `encoding`: アップロードするファイルのエンコーディング\n    - `overwrite`: 既存の場合に上書きするか\n\n- **フォルダーの作成**\n\n  - サンドボックスに新しいディレクトリを作成します\n  - パラメータ:\n    - `folder_path`: 作成するパス\n    - `mode`: ディレクトリのパーミッション (default: 0755)\n\n- **ファイル情報の取得**\n\n  - ファイル情報を取得します\n  - パラメータ:\n    - `file_path`: ファイルパス\n\n- **ファイル一覧**\n\n  - ディレクトリの内容を一覧表示します\n  - パラメータ:\n    - `path`: ディレクトリパス (デフォルトはカレントディレクトリ)\n\n- **ファイルの移動**\n\n  - ファイルを移動またはリネームします\n  - パラメータ:\n    - `source_path`: ソースの場所\n    - `dest_path`: 移動先の場所\n\n- **ファイルの削除**\n  - ファイルまたはディレクトリを削除します\n  - パラメータ:\n    - `file_path`: 削除対象のパス\n\n### プレビュー\n\n- **プレビューリンク**\n  - Web アプリケーション向けにアクセス可能なプレビュー URL を生成します\n  - ローカルポートを外部に公開するための安全なトンネルを作成\n  - 指定ポートのサーバー稼働状況を検証\n  - トラブルシューティング用の診断情報を提供\n  - サービス整理のためのカスタム説明とメタデータをサポート\n  - パラメータ:\n    - `port`: 公開するポート\n    - `description`: サービスの説明\n    - `check_server`: ポートでサーバーが稼働中かを確認\n\n### Git 操作\n\n- **Git Clone**\n  - Git リポジトリをクローンします\n  - パラメータ:\n    - `url`: リポジトリの URL\n    - `path`: ターゲットディレクトリ (デフォルトはカレント)\n    - `branch`: クローンするブランチ\n    - `commit_id`: クローンする特定のコミット\n    - `username`: Git ユーザー名\n    - `password`: Git パスワード\n\n### コマンド実行\n\n- **コマンドの実行**\n  - Daytona 環境でシェルコマンドを実行します\n  - stdout、stderr、終了コードを返します\n  - コマンドはサンドボックスユーザー権限で実行されます\n  - パラメータ:\n    - `command`: 実行するコマンド\n\n## トラブルシューティング\n\n一般的な問題と解決策:\n\n- **認証の問題**\n\n  - 資格情報を更新するために `daytona login` を実行する\n\n- **接続エラー**\n\n  - MCPサーバーの構成を確認する\n  - サーバーのステータスを確認する\n\n- **サンドボックスのエラー**\n  - `daytona sandbox list` を使用してサンドボックスのステータスを確認する\n\n## サポート\n\nサポートが必要な場合は、次をご利用ください:\n\n- [daytona.io](https://daytona.io) をご覧ください\n- support@daytona.io までお問い合わせください\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/organizations.mdx",
    "content": "---\ntitle: Organizations\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona（サンドボックスの作成・管理を行うプラットフォーム）における組織（Daytona内のリソース・ユーザーのグループ化、役割・課金・制限の管理）は、リソースをまとめ、共同作業を可能にするための単位です。ユーザーは個人の組織（Personal Organization）で単独作業することも、共同組織（Collaborative Organization）で協働することもできます。\n\n### 個人組織と共同組織の違い\n\nすべてのDaytonaユーザーは、単独利用や検証に最適な**個人組織（Personal Organization）**から始まります。**共同組織（Collaborative Organization）**はユーザーが手動で作成し、共有アクセスとコントロールにより、会社全体でのコラボレーション向けに設計されています。\n\n| 機能                 | 個人組織（Personal Organization） | 共同組織（Collaborative Organization）          |\n| -------------------- | --------------------------------- | ---------------------------------------------- |\n| **作成**             | サインアップ時に自動               | ユーザーによる手動                              |\n| **メンバー**         | 単一ユーザーのみ                   | 複数ユーザー（招待制）                          |\n| **アクセス制御**     | 役割や権限なし                     | 役割とリソース単位の細分化された割り当て        |\n| **課金**             | 個人ユーザーに紐づく               | チームメンバー間で共有                          |\n| **ユースケース**     | 個人のテスト・小規模プロジェクト   | 会社／チームの開発および本番運用                |\n| **クォータの範囲**   | ユーザー単位                       | 全メンバーで共有                                |\n| **削除可能性**       | ❌ いいえ                          | ✅ はい（オーナーが実行）                       |\n\nユーザーはサイドバーのドロップダウンで個人組織と共同組織を切り替えられます。各組織には、それぞれ独自のサンドボックス（Daytonaが管理する隔離された一時的な実行環境）、APIキー（DAYTONA_API_KEY、Daytona API／SDK認証用の資格情報）、およびリソースクォータがあります。\n\n## 組織（Organization）の役割（Roles）\n\n組織内のユーザーは、`Owner` と `Member` の2種類の**役割**のいずれかを持ちます。`Owner` は組織およびそのリソースに対して完全な管理権限を持ちます。`Member` は組織に対する管理権限はありませんが、組織リソースへのアクセスは**割り当て／役割（Assignments）**に基づいて決まります。\n\n### 管理アクション\n\n組織の `Owner` は次のような管理アクションを実行できます:\n\n- 組織に新しいユーザーを招待する\n- 保留中の招待を管理する\n- 組織内のユーザーの役割を変更する\n- 組織の `Member` の割り当て（Assignments）を更新する\n- 組織からユーザーを削除する\n- 監査ログ（Audit Logs）を閲覧する\n- 組織を削除する\n\n## 新規ユーザーの招待\n\n組織（Organization）の `Owner` は、組織に新しいユーザーを招待できます。_Members ページ_に移動し、_Invite Member_ をクリックして、招待するユーザーのメールアドレスを入力し、**Role** を選択します。\n`Member` の役割を選択した場合は、**割り当て（Assignments）** も設定できます。\n\n## 利用可能な割り当て\n\n利用可能な**割り当て**の一覧は次のとおりです：\n\n| 割り当て                 | 説明                                                                 |\n| ----------------------- | -------------------------------------------------------------------- |\n| **`Viewer (required)`** | 組織内のすべてのリソースに対する読み取り権限を付与します            |\n| **`Developer`**         | 組織内でサンドボックス（Daytonaが管理する隔離された一時的な実行環境）とキーを作成する権限を付与します |\n| **`Sandboxes Admin`**   | 組織内のサンドボックスに対する管理者権限を付与します                |\n| **`Snapshots Admin`**   | 組織内のスナップショット（サンドボックス作成に使う事前設定済みの再利用可能なイメージ／テンプレート）に対する管理者権限を付与します |\n| **`Registries Admin`**  | 組織内のレジストリに対する管理者権限を付与します                     |\n| **`Volumes Admin`**     | 組織内のボリューム（S3互換オブジェクトストレージをバックエンドとするFUSEベースの共有ストレージマウント）に対する管理者権限を付与します |\n| **`Super Admin`**       | 組織内のすべてのリソースに対するフルアクセス権限を付与します         |\n| **`Auditor`**           | 組織内の監査ログ（組織レベルでのユーザー・システム操作を記録するログ）へのアクセス権限を付与します |\n\n## 招待の管理\n\n他の組織（Organization）への参加招待の保留中一覧を表示するには、サイドバー下部のドロップダウンを開き、_Invitations_ をクリックして _Invitations ページ_ に移動します。ユーザーが組織（Organization）への招待を承諾すると、その組織に割り当てられたリソースクォータにアクセスできるようになり、新しい APIキー（DAYTONA_API_KEY、Daytona API/SDK認証用の資格情報）を発行してサンドボックス（Daytonaが管理する隔離された一時的な実行環境）を作成できるようになります。\n\n## 設定\n\nDashboard の「設定」サブページでは、組織（Organization）のIDと名前を確認でき、不要になった場合は組織を削除できます。この操作は取り消せないため、慎重に実行してください。個人用の組織は既定で用意されており、削除できません。\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/preview-and-authentication.mdx",
    "content": "---\ntitle: プレビューと認証\n---\n\nimport { Tabs, TabItem } from '@astrojs/starlight/components';\n\nポート範囲 `3000-9999` でHTTPトラフィックを待ち受けるプロセスは、プレビューリンクで公開して確認できます。\n\nプレビューリンクの形式はポート番号とサンドボックス（Sandbox）IDの組み合わせです。例:\n`https://3000-sandbox-123456.proxy.daytona.work`\n\nサンドボックスの `public` プロパティが `true` の場合、これらのリンクは一般公開されます。そうでない場合、プレビューリンクにアクセスできるのは当該サンドボックスの組織（Organization）ユーザーのみです。\n\nプログラムからアクセスする場合（例: `curl`）、プレビュートークン（x-daytona-preview-token）をヘッダーに指定してプレビューURLへアクセスします:\n\n```bash\ncurl -H \"x-daytona-preview-token: vg5c0ylmcimr8b_v1ne0u6mdnvit6gc0\" \\\nhttps://3000-sandbox-123456.proxy.daytona.work\n```\n\n特定のポートに対応するプレビューリンクとトークンを取得するには、SDKのメソッドを使用します:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n\npreview_info = sandbox.get_preview_link(3000)\n\nprint(f\"Preview link url: {preview_info.url}\")\nprint(f\"Preview link token: {preview_info.token}\")\n\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n\nconst previewInfo = await sandbox.getPreviewLink(3000);\n\nconsole.log(`Preview link url: ${previewInfo.url}`);\nconsole.log(`Preview link token: ${previewInfo.token}`);\n\n```\n\n</TabItem>\n</Tabs>"
  },
  {
    "path": "apps/docs/src/content/docs/ja/process-code-execution.mdx",
    "content": "---\ntitle: プロセスとコード実行\n---\n\nimport { Tabs, TabItem } from '@astrojs/starlight/components';\n\nDaytonaのTS SDK / Python SDKは、サンドボックス内の`process`モジュールを通じて強力なプロセスとコード実行機能を提供します。本ガイドでは、利用可能なプロセス操作のすべてとベストプラクティスを解説します。\n\n## プロセスとコード実行\n\nDaytona SDK は、Python と TypeScript でコードを実行できます。\n\n### コードの実行\n\nDaytona SDK は、Python と TypeScript のコードスニペット実行に対応しています。入力、タイムアウト、環境変数を指定して実行できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# Python コードを実行\nresponse = sandbox.process.code_run('''\ndef greet(name):\n    return f\"Hello, {name}!\"\n\nprint(greet(\"Daytona\"))\n''')\n\nprint(response.result)\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// TypeScript コードを実行\nlet response = await sandbox.process.codeRun(`\nfunction greet(name: string): string {\n    return \\`Hello, \\${name}!\\`;\n}\n\nconsole.log(greet(\"Daytona\"));\n`);\nconsole.log(response.result);\n\n// argv と環境変数を指定して実行\nresponse = await sandbox.process.codeRun(\n    `\n    console.log(\\`Hello, \\${process.argv[2]}!\\`);\n    console.log(\\`FOO: \\${process.env.FOO}\\`);\n    `,\n    { \n      argv: [\"Daytona\"],\n      env: { FOO: \"BAR\" }\n    }\n);\nconsole.log(response.result);\n\n// タイムアウトを指定して実行\nresponse = await sandbox.process.codeRun(\n    'setTimeout(() => console.log(\"Done\"), 2000);',\n    undefined,\n    5000\n);\nconsole.log(response.result);\n```\n\n</TabItem>\n</Tabs>\n\n## プロセスとコード実行\n\nDaytona SDK は、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）内でシェルコマンドを実行し、バックグラウンドプロセスを管理できます。実行時の作業ディレクトリはデフォルトで現在のサンドボックスユーザーのホーム配下です。たとえば `workspace/repo` は `/home/[username]/workspace/repo` を指しますが、絶対パス（先頭を `/` にする）を指定して上書きできます。\n\n### コマンドの実行\n\nDaytona SDK は、Python と TypeScript からシェルコマンドを実行できます。標準入力、タイムアウト、環境変数を指定してコマンドを実行可能です。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# 任意のシェルコマンドを実行\nresponse = sandbox.process.exec(\"ls -la\")\nprint(response.result)\n\n# 作業ディレクトリとタイムアウトを設定\nresponse = sandbox.process.exec(\"sleep 3\", cwd=\"workspace/src\", timeout=5)\nprint(response.result)\n\n# 環境変数を渡す\nresponse = sandbox.process.exec(\"echo $CUSTOM_SECRET\", env={\n        \"CUSTOM_SECRET\": \"DAYTONA\"\n    }\n)\nprint(response.result)\n\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n\n// 任意のシェルコマンドを実行\nconst response = await sandbox.process.executeCommand(\"ls -la\");\nconsole.log(response.result);\n\n// 作業ディレクトリとタイムアウトを設定\nconst response2 = await sandbox.process.executeCommand(\"sleep 3\", \"workspace/src\", undefined, 5);\nconsole.log(response2.result);\n\n// 環境変数を渡す\nconst response3 = await sandbox.process.executeCommand(\"echo $CUSTOM_SECRET\", \"~\", {\n        \"CUSTOM_SECRET\": \"DAYTONA\"\n    }\n);\nconsole.log(response3.result);\n\n```\n\n</TabItem>\n</Tabs>\n\n## セッション（バックグラウンドプロセス）\n\nDaytona SDK は、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）内でバックグラウンドプロセスのセッションを開始・停止・管理する機能を提供します。長時間実行のコマンドを走らせ、プロセスの状態を監視し、稼働中のすべてのプロセスを一覧できます。\n\n### 長時間実行プロセスの管理\n\nDaytona SDK は、バックグラウンドプロセスの開始および停止機能を提供します。長時間実行のコマンドを実行し、プロセスの状態を監視できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\n# セッションで実行されたコマンドを確認\nsession = sandbox.process.get_session(session_id)\nprint(f\"Session {session_id}:\")\nfor command in session.commands:\n    print(f\"Command: {command.command}, Exit Code: {command.exit_code}\")\n\n# 実行中のすべてのセッションを一覧表示\nsessions = sandbox.process.list_sessions()\nfor session in sessions:\n    print(f\"PID: {session.id}, Commands: {session.commands}\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\n// セッションで実行されたコマンドを確認\nconst session = await sandbox.process.getSession(sessionId);\nconsole.log(`Session ${sessionId}:`);\nfor (const command of session.commands) {\n    console.log(`Command: ${command.command}, Exit Code: ${command.exitCode}`);\n}\n\n// 実行中のすべてのセッションを一覧表示\nconst sessions = await sandbox.process.listSessions();\nfor (const session of sessions) {\n    console.log(`PID: ${session.id}, Commands: ${session.commands}`);\n}\n```\n</TabItem>\n</Tabs>\n\n## ベストプラクティス\n\nDaytona SDK は、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）におけるプロセスとコード実行（サンドボックス内でのコマンド／コード実行モジュール）のベストプラクティスを提供します。\n\n1. **リソース管理**\n\n- 長時間実行の処理にはセッションを使用する\n- 実行後はセッションを確実にクリーンアップする\n- セッションで発生する例外を適切に処理する\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n   ```python\n   # Python - セッションのクリーンアップ\n   session_id = \"long-running-cmd\"\n   try:\n       sandbox.process.create_session(session_id)\n       session = sandbox.process.get_session(session_id)\n       # 処理を実行...\n   finally:\n       sandbox.process.delete_session(session.session_id)\n   ```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n   ```typescript\n   // TypeScript - セッションのクリーンアップ\n   const sessionId = \"long-running-cmd\";\n   try {\n       await sandbox.process.createSession(sessionId);\n       const session = await sandbox.process.getSession(sessionId);\n       // 処理を実行...\n   } finally {\n       await sandbox.process.deleteSession(session.sessionId);\n   }\n   ```\n</TabItem>\n</Tabs>\n\n2. **エラーハンドリング**\n\n- プロセスの例外を適切に処理する\n- デバッグのためにエラーの詳細を記録する\n- エラーハンドリングには try-catch ブロックを使用する\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\ntry:\n    response = sandbox.process.code_run(\"invalid python code\")\nexcept ProcessExecutionError as e:\n    print(f\"Execution failed: {e}\")\n    print(f\"Exit code: {e.exit_code}\")\n    print(f\"Error output: {e.stderr}\")\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\ntry {\n    const response = await sandbox.process.codeRun(\"invalid typescript code\");\n} catch (e) {\n    if (e instanceof ProcessExecutionError) {\n        console.error(\"Execution failed:\", e);\n        console.error(\"Exit code:\", e.exitCode);\n        console.error(\"Error output:\", e.stderr);\n    }\n}\n```\n</TabItem>\n</Tabs>\n\n## よくある問題\n\nDaytona SDK は、プロセスとコードの実行（プロセスとコード実行）に関する一般的な問題のトラブルシューティング手段を提供します。\n\n### プロセス実行に失敗する\n\n- コマンドの構文を確認する\n- 必要な依存関係を満たしているか確認する\n- 必要な権限が付与されていることを確認する\n\n### プロセスがタイムアウトする\n\n- タイムアウト設定を調整する\n- 長時間実行タスクを最適化する\n- バックグラウンド処理の利用を検討する\n\n### リソース制限\n\n- プロセスのメモリ使用量を監視する\n- プロセスのクリーンアップを適切に行う\n- 適切なリソース制約を設定する\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-computer-use.mdx",
    "content": "---\ntitle: \"AsyncComputerUse\"\nhideTitleOnPage: true\n---\n\n## AsyncComputerUse\n\n```python\nclass AsyncComputerUse()\n```\n\nデスクトップ環境と対話するためのコンピューター操作（Computer Use）機能。\n\nサンドボックス（Daytonaが管理する隔離された一時的な実行環境）内でのデスクトップ操作自動化のために、マウス、キーボード、スクリーンショット、ディスプレイの各操作にアクセスできます。\n\n**属性**:\n\n- `mouse` _AsyncMouse_ - マウス操作インターフェース。\n- `keyboard` _AsyncKeyboard_ - キーボード操作インターフェース。\n- `screenshot` _AsyncScreenshot_ - スクリーンショット操作インターフェース。\n- `display` _AsyncDisplay_ - ディスプレイ操作インターフェース。\n\n#### AsyncComputerUse.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start computer use: \")\nasync def start() -> ComputerUseStartResponse\n```\n\nすべてのコンピューター操作プロセス（Xvfb、xfce4、x11vnc、novnc）を起動します。\n\n**戻り値**:\n\n- `ComputerUseStartResponse` - コンピューター操作の起動レスポンス。\n  \n\n**例**:\n\n```python\nresult = await sandbox.computer_use.start()\nprint(\"Computer use processes started:\", result.message)\n```\n\n#### AsyncComputerUse.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop computer use: \")\nasync def stop() -> ComputerUseStopResponse\n```\n\nすべてのコンピューター操作プロセスを停止します。\n\n**戻り値**:\n\n- `ComputerUseStopResponse` - コンピューター操作の停止レスポンス。\n  \n\n**例**:\n\n```python\nresult = await sandbox.computer_use.stop()\nprint(\"Computer use processes stopped:\", result.message)\n```\n\n#### AsyncComputerUse.get\\_status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get computer use status: \")\nasync def get_status() -> ComputerUseStatusResponse\n```\n\nすべてのコンピューター操作プロセスのステータスを取得します。\n\n**戻り値**:\n\n- `ComputerUseStatusResponse` - すべてのVNCデスクトッププロセスに関するステータス情報。\n  \n\n**例**:\n\n```python\nresponse = await sandbox.computer_use.get_status()\nprint(\"Computer use status:\", response.status)\n```\n\n#### AsyncComputerUse.get\\_process\\_status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process status: \")\nasync def get_process_status(process_name: str) -> ProcessStatusResponse\n```\n\n特定のVNCプロセスのステータスを取得します。\n\n**引数**:\n\n- `process_name` _str_ - 確認するプロセス名。\n  \n\n**戻り値**:\n\n- `ProcessStatusResponse` - 指定したプロセスに関するステータス情報。\n  \n\n**例**:\n\n```python\nxvfb_status = await sandbox.computer_use.get_process_status(\"xvfb\")\nno_vnc_status = await sandbox.computer_use.get_process_status(\"novnc\")\n```\n\n#### AsyncComputerUse.restart\\_process\n\n```python\n@intercept_errors(message_prefix=\"Failed to restart process: \")\nasync def restart_process(process_name: str) -> ProcessRestartResponse\n```\n\n特定のVNCプロセスを再起動します。\n\n**引数**:\n\n- `process_name` _str_ - 再起動するプロセス名。\n  \n\n**戻り値**:\n\n- `ProcessRestartResponse` - プロセス再起動のレスポンス。\n  \n\n**例**:\n\n```python\nresult = await sandbox.computer_use.restart_process(\"xfce4\")\nprint(\"XFCE4 process restarted:\", result.message)\n```\n\n#### AsyncComputerUse.get\\_process\\_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process logs: \")\nasync def get_process_logs(process_name: str) -> ProcessLogsResponse\n```\n\n特定のVNCプロセスのログを取得します。\n\n**引数**:\n\n- `process_name` _str_ - ログを取得するプロセス名。\n  \n\n**戻り値**:\n\n- `ProcessLogsResponse` - プロセスのログ。\n  \n\n**例**:\n\n```python\nlogs = await sandbox.computer_use.get_process_logs(\"novnc\")\nprint(\"NoVNC logs:\", logs)\n```\n\n#### AsyncComputerUse.get\\_process\\_errors\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process errors: \")\nasync def get_process_errors(process_name: str) -> ProcessErrorsResponse\n```\n\n特定のVNCプロセスのエラーログを取得します。\n\n**引数**:\n\n- `process_name` _str_ - エラーログを取得するプロセス名。\n  \n\n**戻り値**:\n\n- `ProcessErrorsResponse` - プロセスのエラーログ。\n  \n\n**例**:\n\n```python\nerrors = await sandbox.computer_use.get_process_errors(\"x11vnc\")\nprint(\"X11VNC errors:\", errors)\n```\n\n\n## AsyncMouse\n\n```python\nclass AsyncMouse()\n```\n\nコンピューター操作機能のためのマウス操作。\n\n#### AsyncMouse.get\\_position\n\n```python\n@intercept_errors(message_prefix=\"Failed to get mouse position: \")\nasync def get_position() -> MousePosition\n```\n\n現在のマウスカーソル位置を取得します。\n\n**Returns**:\n\n- `MousePosition` - x座標とy座標を含む現在のマウス位置。\n  \n\n**Example**:\n\n```python\nposition = await sandbox.computer_use.mouse.get_position()\nprint(f\"Mouse is at: {position.x}, {position.y}\")\n```\n\n#### AsyncMouse.move\n\n```python\n@intercept_errors(message_prefix=\"Failed to move mouse: \")\nasync def move(x: int, y: int) -> MouseMoveResponse\n```\n\nマウスカーソルを指定した座標に移動します。\n\n**Arguments**:\n\n- `x` _int_ - 移動先のx座標。\n- `y` _int_ - 移動先のy座標。\n  \n\n**Returns**:\n\n- `MouseMoveResponse` - 移動操作の結果。\n  \n\n**Example**:\n\n```python\nresult = await sandbox.computer_use.mouse.move(100, 200)\nprint(f\"Mouse moved to: {result.x}, {result.y}\")\n```\n\n#### AsyncMouse.click\n\n```python\n@intercept_errors(message_prefix=\"Failed to click mouse: \")\nasync def click(x: int,\n                y: int,\n                button: str = \"left\",\n                double: bool = False) -> MouseClickResponse\n```\n\n指定した座標でマウスをクリックします。\n\n**Arguments**:\n\n- `x` _int_ - クリックするx座標。\n- `y` _int_ - クリックするy座標。\n- `button` _str_ - クリックするマウスボタン（'left'、'right'、'middle'）。\n- `double` _bool_ - ダブルクリックを行うかどうか。\n  \n\n**Returns**:\n\n- `MouseClickResponse` - クリック操作の結果。\n  \n\n**Example**:\n\n```python\n# Single left click\nresult = await sandbox.computer_use.mouse.click(100, 200)\n\n# Double click\ndouble_click = await sandbox.computer_use.mouse.click(100, 200, \"left\", True)\n\n# Right click\nright_click = await sandbox.computer_use.mouse.click(100, 200, \"right\")\n```\n\n#### AsyncMouse.drag\n\n```python\n@intercept_errors(message_prefix=\"Failed to drag mouse: \")\nasync def drag(start_x: int,\n               start_y: int,\n               end_x: int,\n               end_y: int,\n               button: str = \"left\") -> MouseDragResponse\n```\n\n開始座標から終了座標までマウスをドラッグします。\n\n**Arguments**:\n\n- `start_x` _int_ - 開始x座標。\n- `start_y` _int_ - 開始y座標。\n- `end_x` _int_ - 終了x座標。\n- `end_y` _int_ - 終了y座標。\n- `button` _str_ - ドラッグに使用するマウスボタン。\n  \n\n**Returns**:\n\n- `MouseDragResponse` - ドラッグ操作の結果。\n  \n\n**Example**:\n\n```python\nresult = await sandbox.computer_use.mouse.drag(50, 50, 150, 150)\nprint(f\"Dragged from {result.from_x},{result.from_y} to {result.to_x},{result.to_y}\")\n```\n\n#### AsyncMouse.scroll\n\n```python\n@intercept_errors(message_prefix=\"Failed to scroll mouse: \")\nasync def scroll(x: int, y: int, direction: str, amount: int = 1) -> bool\n```\n\n指定した座標でマウスホイールをスクロールします。\n\n**Arguments**:\n\n- `x` _int_ - スクロールするx座標。\n- `y` _int_ - スクロールするy座標。\n- `direction` _str_ - スクロール方向（'up' または 'down'）。\n- `amount` _int_ - スクロール量。\n  \n\n**Returns**:\n\n- `bool` - スクロール操作が成功したかどうか。\n  \n\n**Example**:\n\n```python\n# Scroll up\nscroll_up = await sandbox.computer_use.mouse.scroll(100, 200, \"up\", 3)\n\n# Scroll down\nscroll_down = await sandbox.computer_use.mouse.scroll(100, 200, \"down\", 5)\n```\n\n## AsyncKeyboard\n\n```python\nclass AsyncKeyboard()\n```\n\nコンピューター操作（Computer Use）機能におけるキーボード操作。\n\n#### AsyncKeyboard.type\n\n```python\n@intercept_errors(message_prefix=\"Failed to type text: \")\nasync def type(text: str, delay: Optional[int] = None) -> None\n```\n\n指定したテキストを入力します。\n\n**Arguments**:\n\n- `text` _str_ - 入力するテキスト。\n- `delay` _int_ - 文字ごとの遅延（ミリ秒）。\n  \n\n**Raises**:\n\n- `DaytonaError` - 入力処理に失敗した場合。\n  \n\n**Example**:\n\n```python\ntry:\n    await sandbox.computer_use.keyboard.type(\"Hello, World!\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# 文字ごとに遅延を入れる場合\ntry:\n    await sandbox.computer_use.keyboard.type(\"Slow typing\", 100)\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n#### AsyncKeyboard.press\n\n```python\n@intercept_errors(message_prefix=\"Failed to press key: \")\nasync def press(key: str, modifiers: Optional[List[str]] = None) -> None\n```\n\n必要に応じてモディファイアキーと組み合わせてキーを押します。\n\n**Arguments**:\n\n- `key` _str_ - 押下するキー（例: 'Enter', 'Escape', 'Tab', 'a', 'A'）。\n- `modifiers` _List[str]_ - モディファイアキー（'ctrl', 'alt', 'meta', 'shift'）。\n  \n\n**Raises**:\n\n- `DaytonaError` - キー押下処理に失敗した場合。\n  \n\n**Example**:\n\n```python\n# Enter を押す\ntry:\n    await sandbox.computer_use.keyboard.press(\"Return\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Ctrl+C を押す\ntry:\n    await sandbox.computer_use.keyboard.press(\"c\", [\"ctrl\"])\n    print(f\"Operation success\")\n\n# Ctrl+Shift+T を押す\ntry:\n    await sandbox.computer_use.keyboard.press(\"t\", [\"ctrl\", \"shift\"])\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n#### AsyncKeyboard.hotkey\n\n```python\n@intercept_errors(message_prefix=\"Failed to press hotkey: \")\nasync def hotkey(keys: str) -> None\n```\n\nホットキーの組み合わせを押します。\n\n**Arguments**:\n\n- `keys` _str_ - ホットキーの組み合わせ（例: 'ctrl+c', 'alt+tab', 'cmd+shift+t'）。\n  \n\n**Raises**:\n\n- `DaytonaError` - ホットキー処理に失敗した場合。\n  \n\n**Example**:\n\n```python\n# コピー\ntry:\n    await sandbox.computer_use.keyboard.hotkey(\"ctrl+c\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# ペースト\ntry:\n    await sandbox.computer_use.keyboard.hotkey(\"ctrl+v\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Alt+Tab\ntry:\n    await sandbox.computer_use.keyboard.hotkey(\"alt+tab\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n## AsyncScreenshot\n\n```python\nclass AsyncScreenshot()\n```\n\nコンピューター操作（Computer Use）機能向けのスクリーンショット処理。\n\n#### AsyncScreenshot.take\\_full\\_screen\n\n```python\n@intercept_errors(message_prefix=\"Failed to take screenshot: \")\nasync def take_full_screen(show_cursor: bool = False) -> ScreenshotResponse\n```\n\n画面全体のスクリーンショットを取得します。\n\n**引数**:\n\n- `show_cursor` _bool_ - スクリーンショットにカーソルを表示するかどうか。\n  \n\n**戻り値**:\n\n- `ScreenshotResponse` - 画像をbase64エンコードしたスクリーンショットデータ。\n  \n\n**例**:\n\n```python\nscreenshot = await sandbox.computer_use.screenshot.take_full_screen()\nprint(f\"Screenshot size: {screenshot.width}x{screenshot.height}\")\n\n# With cursor visible\nwith_cursor = await sandbox.computer_use.screenshot.take_full_screen(True)\n```\n\n#### AsyncScreenshot.take\\_region\n\n```python\n@intercept_errors(message_prefix=\"Failed to take region screenshot: \")\nasync def take_region(region: ScreenshotRegion,\n                      show_cursor: bool = False) -> RegionScreenshotResponse\n```\n\n指定した領域のスクリーンショットを取得します。\n\n**引数**:\n\n- `region` _ScreenshotRegion_ - 取得対象の領域。\n- `show_cursor` _bool_ - スクリーンショットにカーソルを表示するかどうか。\n  \n\n**戻り値**:\n\n- `RegionScreenshotResponse` - 画像をbase64エンコードしたスクリーンショットデータ。\n  \n\n**例**:\n\n```python\nregion = ScreenshotRegion(x=100, y=100, width=300, height=200)\nscreenshot = await sandbox.computer_use.screenshot.take_region(region)\nprint(f\"Captured region: {screenshot.region.width}x{screenshot.region.height}\")\n```\n\n#### AsyncScreenshot.take\\_compressed\n\n```python\n@intercept_errors(message_prefix=\"Failed to take compressed screenshot: \")\nasync def take_compressed(\n    options: Optional[ScreenshotOptions] = None\n) -> CompressedScreenshotResponse\n```\n\n画面全体の圧縮スクリーンショットを取得します。\n\n**引数**:\n\n- `options` _ScreenshotOptions_ - 圧縮および表示のオプション。\n  \n\n**戻り値**:\n\n- `CompressedScreenshotResponse` - 圧縮済みスクリーンショットデータ。\n  \n\n**例**:\n\n```python\n# Default compression\nscreenshot = await sandbox.computer_use.screenshot.take_compressed()\n\n# High quality JPEG\njpeg = await sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"jpeg\", quality=95, show_cursor=True)\n)\n\n# Scaled down PNG\nscaled = await sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"png\", scale=0.5)\n)\n```\n\n#### AsyncScreenshot.take\\_compressed\\_region\n\n```python\n@intercept_errors(\n    message_prefix=\"Failed to take compressed region screenshot: \")\nasync def take_compressed_region(\n    region: ScreenshotRegion,\n    options: Optional[ScreenshotOptions] = None\n) -> CompressedScreenshotResponse\n```\n\n指定した領域の圧縮スクリーンショットを取得します。\n\n**引数**:\n\n- `region` _ScreenshotRegion_ - 取得対象の領域。\n- `options` _ScreenshotOptions_ - 圧縮および表示のオプション。\n  \n\n**戻り値**:\n\n- `CompressedScreenshotResponse` - 圧縮済みスクリーンショットデータ。\n  \n\n**例**:\n\n```python\nregion = ScreenshotRegion(x=0, y=0, width=800, height=600)\nscreenshot = await sandbox.computer_use.screenshot.take_compressed_region(\n    region,\n    ScreenshotOptions(format=\"webp\", quality=80, show_cursor=True)\n)\nprint(f\"Compressed size: {screenshot.size_bytes} bytes\")\n```\n\n## AsyncDisplay\n\n```python\nclass AsyncDisplay()\n```\n\nコンピューター操作機能向けのディスプレイ操作。\n\n#### AsyncDisplay.get\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get display info: \")\nasync def get_info() -> DisplayInfoResponse\n```\n\nディスプレイ情報を取得します。\n\n**Returns**:\n\n- `DisplayInfoResponse` - プライマリディスプレイおよび利用可能なすべてのディスプレイを含む情報。\n  \n\n**Example**:\n\n```python\ninfo = await sandbox.computer_use.display.get_info()\nprint(f\"Primary display: {info.primary_display.width}x{info.primary_display.height}\")\nprint(f\"Total displays: {info.total_displays}\")\nfor i, display in enumerate(info.displays):\n    print(f\"Display {i}: {display.width}x{display.height} at {display.x},{display.y}\")\n```\n\n#### AsyncDisplay.get\\_windows\n\n```python\n@intercept_errors(message_prefix=\"Failed to get windows: \")\nasync def get_windows() -> WindowsResponse\n```\n\n開いているウィンドウの一覧を取得します。\n\n**Returns**:\n\n- `WindowsResponse` - IDとタイトルを含む開いているウィンドウの一覧。\n  \n\n**Example**:\n\n```python\nwindows = await sandbox.computer_use.display.get_windows()\nprint(f\"Found {windows.count} open windows:\")\nfor window in windows.windows:\n    print(f\"- {window.title} (ID: {window.id})\")\n```\n\n## ScreenshotRegion\n\n```python\nclass ScreenshotRegion()\n```\n\nスクリーンショット操作のための領域座標。\n\n**属性**:\n\n- `x` _int_ - 領域のX座標。\n- `y` _int_ - 領域のY座標。\n- `width` _int_ - 領域の幅。\n- `height` _int_ - 領域の高さ。\n\n## ScreenshotOptions\n\n```python\nclass ScreenshotOptions()\n```\n\nスクリーンショットの圧縮や表示に関するオプション。\n\n**属性**:\n\n- `show_cursor` _bool_ - スクリーンショットにカーソルを表示するかどうか。\n- `fmt` _str_ - 画像形式（例: 'png'、'jpeg'、'webp'）。\n- `quality` _int_ - 圧縮品質（0〜100）。\n- `scale` _float_ - スクリーンショットの拡大率。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-daytona.mdx",
    "content": "---\ntitle: \"AsyncDaytona\"\nhideTitleOnPage: true\n---\n\n## AsyncDaytona\n\n```python\nclass AsyncDaytona()\n```\n\nDaytona API と対話するためのメインクラス。\n\nこのクラスは、Daytona サンドボックスの作成・管理・操作を非同期メソッドで提供します。\n明示的な設定、または環境変数を用いて初期化できます。\n\n**属性**:\n\n- `volume` _AsyncVolumeService_ - ボリュームを管理するサービス。\n- `snapshot` _AsyncSnapshotService_ - スナップショットを管理するサービス。\n  \n\n**例**:\n\n  環境変数を使用する場合:\n```python\nasync with AsyncDaytona() as daytona:  # Uses DAYTONA_API_KEY, DAYTONA_API_URL\n    sandbox = await daytona.create()\n```\n  \n  明示的な設定を使用する場合:\n```python\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"https://your-api.com\",\n    target=\"us\"\n)\ntry:\n    daytona = AsyncDaytona(config)\n    sandbox = await daytona.create()\nfinally:\n    await daytona.close()\n```\n\n#### AsyncDaytona.__init__\n\n```python\ndef __init__(config: Optional[DaytonaConfig] = None)\n```\n\n任意の設定で Daytona インスタンスを初期化します。\n\nconfig が指定されていない場合、次の環境変数から読み取ります:\n- `DAYTONA_API_KEY`: 認証に必要な API キー（必須）\n- `DAYTONA_API_URL`: API の URL（必須）\n- `DAYTONA_TARGET`: ターゲット環境（任意、デフォルトは 'us'）\n\n**引数**:\n\n- `config` _Optional[DaytonaConfig]_ - api_key、api_url、target を含むオブジェクト。\n  \n\n**送出**:\n\n- `DaytonaError` - API キーが config または環境変数で提供されていない場合\n  \n\n**例**:\n\n```python\nfrom daytona import Daytona, DaytonaConfig\n# 環境変数を使用\ndaytona1 = AsyncDaytona()\nawait daytona1.close()\n# 明示的な設定を使用\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"https://your-api.com\",\n    target=\"us\"\n)\ndaytona2 = AsyncDaytona(config)\nawait daytona2.close()\n```\n\n#### AsyncDaytona.__aenter__\n\n```python\nasync def __aenter__()\n```\n\n非同期コンテキストマネージャへのエントリ。\n\n#### AsyncDaytona.__aexit__\n\n```python\nasync def __aexit__(exc_type, exc_value, traceback)\n```\n\n非同期コンテキストマネージャの終了—適切なクリーンアップを保証します。\n\n#### AsyncDaytona.close\n\n```python\nasync def close()\n```\n\nHTTP セッションを閉じてリソースをクリーンアップします。\n\nこのメソッドは AsyncDaytona インスタンスの使用を終えたときに呼び出し、\n基盤となる HTTP セッションを適切に閉じてリソースリークを防ぎます。\n\n**例**:\n\n```python\ndaytona = AsyncDaytona()\ntry:\n    sandbox = await daytona.create()\n    # ... use sandbox ...\nfinally:\n    await daytona.close()\n```\n  \n  あるいは、非同期コンテキストマネージャとして使用するのが望ましいです:\n```python\nasync with AsyncDaytona() as daytona:\n    sandbox = await daytona.create()\n    # ... use sandbox ...\n# 自動的にクローズされます\n```\n\n#### AsyncDaytona.create\n\n```python\n@overload\nasync def create(params: Optional[CreateSandboxFromSnapshotParams] = None,\n                 *,\n                 timeout: Optional[float] = 60) -> AsyncSandbox\n```\n\n指定された、またはデフォルトのスナップショットからサンドボックスを作成します。言語、イメージ、環境変数、ボリュームなど、さまざまなパラメータを指定できます。\n\n**引数**:\n\n- `params` _Optional[CreateSandboxFromSnapshotParams]_ - サンドボックス作成用のパラメータ。指定しない場合は、\n  デフォルトの Daytona スナップショットと Python 言語が使用されます。\n- `timeout` _Optional[float]_ - サンドボックス作成のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n  デフォルトは 60 秒です。\n  \n\n**戻り値**:\n\n- `Sandbox` - 作成されたサンドボックスインスタンス。\n  \n\n**送出**:\n\n- `DaytonaError` - timeout、auto_stop_interval、または auto_archive_interval が負の場合、\n  またはサンドボックスの起動に失敗した／タイムアウトした場合\n  \n\n**例**:\n\n  デフォルトの Python サンドボックスを作成:\n```python\nsandbox = await daytona.create()\n```\n  \n  カスタムサンドボックスを作成:\n```python\nparams = CreateSandboxFromSnapshotParams(\n    language=\"python\",\n    snapshot=\"my-snapshot-id\",\n    env_vars={\"DEBUG\": \"true\"},\n    auto_stop_interval=0,\n    auto_archive_interval=60,\n    auto_delete_interval=120\n)\nsandbox = await daytona.create(params, timeout=40)\n```\n\n#### AsyncDaytona.create\n\n```python\n@overload\nasync def create(\n        params: Optional[CreateSandboxFromImageParams] = None,\n        *,\n        timeout: Optional[float] = 60,\n        on_snapshot_create_logs: Callable[[str], None] = None) -> AsyncSandbox\n```\n\n指定したレジストリで利用可能なイメージ、または宣言的な Daytona イメージからサンドボックスを作成します。\nリソース、言語、イメージ、環境変数、ボリュームなど、さまざまなパラメータを指定できます。Daytona は指定されたイメージからスナップショットを作成し、それを用いてサンドボックスを作成します。\n\n**引数**:\n\n- `params` _Optional[CreateSandboxFromImageParams]_ - イメージからサンドボックスを作成するためのパラメータ。\n- `timeout` _Optional[float]_ - サンドボックス作成のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n  デフォルトは 60 秒です。\n- `on_snapshot_create_logs` _Callable[[str], None]_ - スナップショット作成ログを処理するコールバック関数。\n  \n\n**戻り値**:\n\n- `Sandbox` - 作成されたサンドボックスインスタンス。\n  \n\n**例外**:\n\n- `DaytonaError` - timeout、auto_stop_interval、または auto_archive_interval が負の場合、\n  もしくはサンドボックスの起動に失敗した場合やタイムアウトした場合\n  \n\n**例**:\n\n  既定の Python サンドボックスをイメージから作成:\n```python\nsandbox = await daytona.create(CreateSandboxFromImageParams(image=\"debian:12.9\"))\n```\n  \n  宣言的なイメージ定義からカスタムサンドボックスを作成:\n```python\ndeclarative_image = (\n    Image.base(\"alpine:3.18\")\n    .pipInstall([\"numpy\", \"pandas\"])\n    .env({\"MY_ENV_VAR\": \"My Environment Variable\"})\n)\nparams = CreateSandboxFromImageParams(\n    language=\"python\",\n    image=declarative_image,\n    env_vars={\"DEBUG\": \"true\"},\n    resources=Resources(cpu=2, memory=4),\n    auto_stop_interval=0,\n    auto_archive_interval=60,\n    auto_delete_interval=120\n)\nsandbox = await daytona.create(\n    params,\n    timeout=40,\n    on_snapshot_create_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n#### AsyncDaytona.delete\n\n```python\nasync def delete(sandbox: AsyncSandbox, timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスを削除します。\n\n**引数**:\n\n- `sandbox` _Sandbox_ - 削除するサンドボックスインスタンス。\n- `timeout` _Optional[float]_ - サンドボックス削除のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n  デフォルトは 60 秒です。\n  \n\n**例外**:\n\n- `DaytonaError` - サンドボックスの削除に失敗した場合、またはタイムアウトした場合\n  \n\n**例**:\n\n```python\nsandbox = await daytona.create()\n# ... use sandbox ...\nawait daytona.delete(sandbox)  # 完了時にクリーンアップ\n```\n\n#### AsyncDaytona.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get sandbox: \")\nasync def get(sandbox_id: str) -> AsyncSandbox\n```\n\nID でサンドボックスを取得します。\n\n**引数**:\n\n- `sandbox_id` _str_ - 取得するサンドボックスの ID。\n  \n\n**戻り値**:\n\n- `Sandbox` - サンドボックスインスタンス。\n  \n\n**例外**:\n\n- `DaytonaError` - sandbox_id が指定されていない場合。\n  \n\n**例**:\n\n```python\nsandbox = await daytona.get(\"my-sandbox-id\")\nprint(sandbox.status)\n```\n\n#### AsyncDaytona.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list sandboxes: \")\nasync def list(labels: Optional[Dict[str, str]] = None) -> List[AsyncSandbox]\n```\n\nラベルでフィルタリングされたサンドボックスの一覧を取得します。\n\n**引数**:\n\n- `labels` _Optional[Dict[str, str]]_ - サンドボックスをフィルタリングするためのラベル。\n  \n\n**戻り値**:\n\n- `List[Sandbox]` - ラベルに一致するサンドボックスインスタンスのリスト。\n  \n\n**例**:\n\n```python\nsandboxes = await daytona.list(labels={\"my-label\": \"my-value\"})\nfor sandbox in sandboxes:\n    print(f\"{sandbox.id}: {sandbox.status}\")\n```\n\n#### AsyncDaytona.start\n\n```python\nasync def start(sandbox: AsyncSandbox, timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスを起動し、準備完了になるまで待機します。\n\n**引数**:\n\n- `sandbox` _Sandbox_ - 起動するサンドボックス。\n- `timeout` _Optional[float]_ - サンドボックスの起動完了を待機するタイムアウト（秒）。省略可。\n  0 はタイムアウトなしを意味します。デフォルトは 60 秒です。\n  \n\n**例外**:\n\n- `DaytonaError` - タイムアウトが負の値の場合、またはサンドボックスの起動に失敗した場合・タイムアウトした場合\n\n#### AsyncDaytona.stop\n\n```python\nasync def stop(sandbox: AsyncSandbox, timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスを停止し、停止完了まで待機します。\n\n**引数**:\n\n- `sandbox` _Sandbox_ - 停止するサンドボックス。\n- `timeout` _Optional[float]_ - サンドボックスの停止完了を待機するタイムアウト（秒）。省略可。\n  0 はタイムアウトなしを意味します。デフォルトは 60 秒です。\n  \n\n**例外**:\n\n- `DaytonaError` - タイムアウトが負の値の場合、またはサンドボックスの停止に失敗した場合・タイムアウトした場合\n\n\n## CodeLanguage\n\n```python\n@dataclass\nclass CodeLanguage(Enum)\n```\n\nDaytona がサポートするプログラミング言語\n\n**列挙体メンバー**:\n    - `PYTHON` (\"python\")\n    - `TYPESCRIPT` (\"typescript\")\n    - `JAVASCRIPT` (\"javascript\")\n\n## DaytonaConfig\n\n```python\nclass DaytonaConfig(BaseModel)\n```\n\nDaytona クライアントを初期化するための設定オプション。\n\n**属性**:\n\n- `api_key` _Optional[str]_ - Daytona API への認証に使用する API キー。未設定の場合は\n  環境変数 `DAYTONA_API_KEY` で指定するか、代わりに JWT トークンを指定する必要があります。\n- `jwt_token` _Optional[str]_ - Daytona API への認証に使用する JWT トークン。未設定の場合は\n  環境変数 `DAYTONA_JWT_TOKEN` で指定するか、代わりに API キーを指定する必要があります。\n- `organization_id` _Optional[str]_ - JWT ベース認証で使用する組織 ID。JWT トークンが指定されている場合は必須で、\n  ここで指定するか、環境変数 `DAYTONA_ORGANIZATION_ID` に設定する必要があります。\n- `api_url` _Optional[str]_ - Daytona API の URL。ここまたは環境変数 `DAYTONA_API_URL` で未設定の場合は、\n  既定値は `'https://app.daytona.io/api'` です。\n- `server_url` _Optional[str]_ - 廃止予定。代わりに `api_url` を使用してください。このプロパティは\n  将来のバージョンで削除されます。\n- `target` _Optional[str]_ - サンドボックスのターゲットとなるランナーのロケーション。ここまたは\n  環境変数 `DAYTONA_TARGET` で未設定の場合は、既定で `'us'` になります。\n  \n\n**例**:\n\n```python\nconfig = DaytonaConfig(api_key=\"your-api-key\")\n```\n```python\nconfig = DaytonaConfig(jwt_token=\"your-jwt-token\", organization_id=\"your-organization-id\")\n```\n\n## CreateSandboxBaseParams\n\n```python\nclass CreateSandboxBaseParams(BaseModel)\n```\n\n新しいサンドボックスを作成するための基本パラメータ。\n\n**属性**:\n\n- `language` _Optional[CodeLanguage]_ - サンドボックスのプログラミング言語。既定は \"python\"。\n- `os_user` _Optional[str]_ - サンドボックスの OS ユーザー。\n- `env_vars` _Optional[Dict[str, str]]_ - サンドボックスで設定する環境変数。\n- `labels` _Optional[Dict[str, str]]_ - サンドボックスのカスタムラベル。\n- `public` _Optional[bool]_ - サンドボックスを公開にするかどうか。\n- `timeout` _Optional[float]_ - サンドボックスの作成と起動のタイムアウト（秒）。\n- `auto_stop_interval` _Optional[int]_ - サンドボックスでイベントが発生しない場合に、\n  自動的に停止するまでの間隔（分）。既定は 15 分。\n  0 は自動停止なしを意味します。\n- `auto_archive_interval` _Optional[int]_ - 連続して停止状態のサンドボックスが\n  自動的にアーカイブされるまでの間隔（分）。既定は 7 日。\n  0 は最大の間隔が使用されることを意味します。\n- `auto_delete_interval` _Optional[int]_ - 連続して停止状態のサンドボックスが\n  自動的に削除されるまでの間隔（分）。既定では自動削除は無効です。\n  負の値は無効、0 は停止と同時に即削除を意味します。\n- `volumes` _Optional[List[VolumeMount]]_ - サンドボックスにアタッチするボリュームのマウント一覧。\n- `network_block_all` _Optional[bool]_ - サンドボックスのすべてのネットワークアクセスをブロックするかどうか。\n- `network_allow_list` _Optional[str]_ - サンドボックスで許可する CIDR ネットワークアドレスのカンマ区切りリスト。\n\n## CreateSandboxFromImageParams\n\n```python\nclass CreateSandboxFromImageParams(CreateSandboxBaseParams)\n```\n\nイメージから新規サンドボックスを作成するためのパラメータ。\n\n**属性**:\n\n- `image` _Union[str, Image]_ - サンドボックスで使用するカスタム Docker イメージ。Image オブジェクトが渡された場合は、\n  イメージが動的にビルドされます。\n- `resources` _Optional[Resources]_ - サンドボックスのリソース設定。指定しない場合、サンドボックスは\n  デフォルトのリソースを使用します。\n\n## CreateSandboxFromSnapshotParams\n\n```python\nclass CreateSandboxFromSnapshotParams(CreateSandboxBaseParams)\n```\n\nスナップショットから新しいサンドボックスを作成するためのパラメーター。\n\n**属性**:\n\n- `snapshot` _Optional[str]_ - サンドボックスに使用するスナップショットの名前。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-file-system.mdx",
    "content": "---\ntitle: \"AsyncFileSystem\"\nhideTitleOnPage: true\n---\n\n## AsyncFileSystem\n\n```python\nclass AsyncFileSystem()\n```\n\nサンドボックス内でのファイルシステム操作を提供します。\n\nこのクラスは、Daytona サンドボックス内で実行できるファイルシステム操作に対する高水準インターフェースを実装します。\n\n#### AsyncFileSystem.\\_\\_init\\_\\_\n\n```python\ndef __init__(sandbox_id: str, toolbox_api: ToolboxApi,\n             get_root_dir: Callable[[], Awaitable[str]])\n```\n\n新しい FileSystem インスタンスを初期化します。\n\n**Arguments**:\n\n- `sandbox_id` _str_ - サンドボックス ID。\n- `toolbox_api` _ToolboxApi_ - サンドボックス操作用の API クライアント。\n- `get_root_dir` _Callable[[], str]_ - サンドボックスの既定のルートディレクトリを取得する関数。\n\n#### AsyncFileSystem.create\\_folder\n\n```python\n@intercept_errors(message_prefix=\"Failed to create folder: \")\nasync def create_folder(path: str, mode: str) -> None\n```\n\n指定されたパスに、与えられた権限でサンドボックス内に新しいディレクトリを作成します。\n\n**Arguments**:\n\n- `path` _str_ - フォルダを作成するパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `mode` _str_ - 8 進数形式のフォルダ権限（例: \"755\" は rwxr-xr-x）。\n  \n\n**Example**:\n\n```python\n# 標準的な権限でディレクトリを作成\nawait sandbox.fs.create_folder(\"workspace/data\", \"755\")\n\n# プライベートなディレクトリを作成\nawait sandbox.fs.create_folder(\"workspace/secrets\", \"700\")\n```\n\n#### AsyncFileSystem.delete\\_file\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete file: \")\nasync def delete_file(path: str) -> None\n```\n\nサンドボックスからファイルを削除します。\n\n**Arguments**:\n\n- `path` _str_ - 削除するファイルへの絶対パス。\n  \n\n**Example**:\n\n```python\n# ファイルを削除\nawait sandbox.fs.delete_file(\"workspace/data/old_file.txt\")\n```\n\n#### AsyncFileSystem.download\\_file\n\n```python\n@overload\nasync def download_file(remote_path: str, timeout: int = 30 * 60) -> bytes\n```\n\nサンドボックスからファイルをダウンロードします。ファイル内容を bytes オブジェクトとして返します。\nディスクに保存せずにメモリに読み込みたい場合に便利です。\n小さなファイルにのみ使用できます。\n\n**Arguments**:\n\n- `remote_path` _str_ - サンドボックス内のファイルへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `timeout` _int_ - ダウンロード処理のタイムアウト（秒）。0 はタイムアウトなし。デフォルトは 30 分。\n  \n\n**Returns**:\n\n- `bytes` - ファイル内容の bytes オブジェクト。\n  \n\n**Example**:\n\n```python\n# ダウンロードしてローカルに保存\ncontent = await sandbox.fs.download_file(\"workspace/data/file.txt\")\nwith open(\"local_copy.txt\", \"wb\") as f:\n    f.write(content)\n\n# ダウンロードしてテキスト内容を処理\ncontent = await sandbox.fs.download_file(\"workspace/data/config.json\")\nconfig = json.loads(content.decode('utf-8'))\n```\n\n#### AsyncFileSystem.download\\_file\n\n```python\n@overload\nasync def download_file(remote_path: str,\n                        local_path: str,\n                        timeout: int = 30 * 60) -> None\n```\n\nサンドボックスからファイルをダウンロードし、ストリーミングでローカルファイルに保存します。\nメモリに収まりきらない可能性のある大きなファイルをダウンロードしたい場合に便利です。\n\n**Arguments**:\n\n- `remote_path` _str_ - サンドボックス内のファイルへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `local_path` _str_ - ローカルに保存するファイルのパス。\n- `timeout` _int_ - ダウンロード処理のタイムアウト（秒）。0 はタイムアウトなし。デフォルトは 30 分。\n  \n\n**Example**:\n\n```python\nlocal_path = \"local_copy.txt\"\nawait sandbox.fs.download_file(\"tmp/large_file.txt\", local_path)\nsize_mb = os.path.getsize(local_path) / 1024 / 1024\nprint(f\"Size of the downloaded file {local_path}: {size_mb} MB\")\n```\n\n#### AsyncFileSystem.find\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to find files: \")\nasync def find_files(path: str, pattern: str) -> List[Match]\n```\n\nパターンを含むファイルを検索します。`grep` コマンドに似ています。\n\n**引数**:\n\n- `path` _str_ - 検索対象のファイルまたはディレクトリへのパス。パスがディレクトリの場合は再帰的に検索されます。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `pattern` _str_ - ファイル内容に対してマッチングを行う検索パターン。\n  \n\n**戻り値**:\n\n- `List[Match]` - ファイル内で見つかった一致のリスト。各 Match オブジェクトには次が含まれます:\n  - file: 一致を含むファイルのパス\n  - line: 一致が見つかった行番号\n  - content: 一致した行の内容\n  \n\n**例**:\n\n```python\n# Search for TODOs in Python files\nmatches = await sandbox.fs.find_files(\"workspace/src\", \"TODO:\")\nfor match in matches:\n    print(f\"{match.file}:{match.line}: {match.content.strip()}\")\n```\n\n#### AsyncFileSystem.get\\_file\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get file info: \")\nasync def get_file_info(path: str) -> FileInfo\n```\n\nファイルまたはディレクトリの詳細情報（サイズ、パーミッション、タイムスタンプなど）を取得します。\n\n**引数**:\n\n- `path` _str_ - ファイルまたはディレクトリへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `FileInfo` - 次を含む詳細なファイル情報:\n  - name: ファイル名\n  - is_dir: パスがディレクトリかどうか\n  - size: バイト単位のファイルサイズ\n  - mode: ファイルのパーミッション\n  - mod_time: 最終更新タイムスタンプ\n  - permissions: 8進数形式のファイルパーミッション\n  - owner: ファイルの所有者\n  - group: ファイルのグループ\n  \n\n**例**:\n\n```python\n# Get file metadata\ninfo = await sandbox.fs.get_file_info(\"workspace/data/file.txt\")\nprint(f\"Size: {info.size} bytes\")\nprint(f\"Modified: {info.mod_time}\")\nprint(f\"Mode: {info.mode}\")\n\n# Check if path is a directory\ninfo = await sandbox.fs.get_file_info(\"workspace/data\")\nif info.is_dir:\n    print(\"Path is a directory\")\n```\n\n#### AsyncFileSystem.list\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to list files: \")\nasync def list_files(path: str) -> List[FileInfo]\n```\n\n指定したパス内のファイルとディレクトリを一覧表示し、その情報を返します。`ls -l` コマンドに似ています。\n\n**引数**:\n\n- `path` _str_ - 内容を一覧表示するディレクトリへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `List[FileInfo]` - ファイルおよびディレクトリ情報のリスト。各 FileInfo オブジェクトには、get_file_info() で説明したのと同じフィールドが含まれます。\n  \n\n**例**:\n\n```python\n# List directory contents\nfiles = await sandbox.fs.list_files(\"workspace/data\")\n\n# Print files and their sizes\nfor file in files:\n    if not file.is_dir:\n        print(f\"{file.name}: {file.size} bytes\")\n\n# List only directories\ndirs = [f for f in files if f.is_dir]\nprint(\"Subdirectories:\", \", \".join(d.name for d in dirs))\n```\n\n#### AsyncFileSystem.move\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to move files: \")\nasync def move_files(source: str, destination: str) -> None\n```\n\nファイルまたはディレクトリを移動または名前変更します。移動先の親ディレクトリは存在している必要があります。\n\n**引数**:\n\n- `source` _str_ - 移動元のファイルまたはディレクトリへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `destination` _str_ - 移動先のパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n  \n\n**例**:\n\n```python\n# Rename a file\nawait sandbox.fs.move_files(\n    \"workspace/data/old_name.txt\",\n    \"workspace/data/new_name.txt\"\n)\n\n# Move a file to a different directory\nawait sandbox.fs.move_files(\n    \"workspace/data/file.txt\",\n    \"workspace/archive/file.txt\"\n)\n\n# Move a directory\nawait sandbox.fs.move_files(\n    \"workspace/old_dir\",\n    \"workspace/new_dir\"\n)\n```\n\n#### AsyncFileSystem.replace\\_in\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to replace in files: \")\nasync def replace_in_files(files: List[str], pattern: str,\n                           new_value: str) -> List[ReplaceResult]\n```\n\n複数のファイルに対して検索および置換を実行します。\n\n**引数**:\n\n- `files` _List[str]_ - 置換を実行するファイルパスのリスト。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `pattern` _str_ - 検索するパターン。\n- `new_value` _str_ - 一致箇所を置換するテキスト。\n  \n\n**戻り値**:\n\n- `List[ReplaceResult]` - 各ファイルで行われた置換を示す結果のリスト。各 ReplaceResult には次が含まれます:\n  - file: 変更されたファイルのパス\n  - success: 操作が成功したかどうか\n  - error: 操作が失敗した場合のエラーメッセージ\n  \n\n**例**:\n\n```python\n# 特定のファイルで置換する\nresults = await sandbox.fs.replace_in_files(\n    files=[\"workspace/src/file1.py\", \"workspace/src/file2.py\"],\n    pattern=\"old_function\",\n    new_value=\"new_function\"\n)\n\n# 結果を出力する\nfor result in results:\n    if result.success:\n        print(f\"{result.file}: {result.success}\")\n    else:\n        print(f\"{result.file}: {result.error}\")\n```\n\n#### AsyncFileSystem.search\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to search files: \")\nasync def search_files(path: str, pattern: str) -> SearchFilesResponse\n```\n\n名前が指定のパターンに一致するファイルおよびディレクトリを検索します。パターンは単純な文字列またはグロブパターンに対応します。\n\n**引数**:\n\n- `path` _str_ - 検索を開始するルートディレクトリへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `pattern` _str_ - ファイル名と照合するパターン。グロブ\n  パターンをサポートします（例: Python ファイルの場合は \"*.py\"）。\n  \n\n**戻り値**:\n\n- `SearchFilesResponse` - 次を含む検索結果:\n  - files: 一致したファイルおよびディレクトリのパス一覧\n  \n\n**例**:\n\n```python\n# すべての Python ファイルを探す\nresult = await sandbox.fs.search_files(\"workspace\", \"*.py\")\nfor file in result.files:\n    print(file)\n\n# 特定の接頭辞を持つファイルを探す\nresult = await sandbox.fs.search_files(\"workspace/data\", \"test_*\")\nprint(f\"Found {len(result.files)} test files\")\n```\n\n#### AsyncFileSystem.set\\_file\\_permissions\n\n```python\n@intercept_errors(message_prefix=\"Failed to set file permissions: \")\nasync def set_file_permissions(path: str,\n                               mode: str = None,\n                               owner: str = None,\n                               group: str = None) -> None\n```\n\nファイルまたはディレクトリのパーミッションと所有権を設定します。いずれのパラメータも None にすると、その属性は変更されません。\n\n**引数**:\n\n- `path` _str_ - ファイルまたはディレクトリへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `mode` _Optional[str]_ - 8 進数表記のファイルモード／パーミッション\n  （例: \"644\" は rw-r--r--）。\n- `owner` _Optional[str]_ - ファイルの所有ユーザー。\n- `group` _Optional[str]_ - ファイルの所有グループ。\n  \n\n**例**:\n\n```python\n# ファイルを実行可能にする\nawait sandbox.fs.set_file_permissions(\n    path=\"workspace/scripts/run.sh\",\n    mode=\"755\"  # rwxr-xr-x\n)\n\n# ファイルの所有者を変更する\nawait sandbox.fs.set_file_permissions(\n    path=\"workspace/data/file.txt\",\n    owner=\"daytona\",\n    group=\"daytona\"\n)\n```\n\n#### AsyncFileSystem.upload\\_file\n\n```python\n@overload\nasync def upload_file(file: bytes,\n                      remote_path: str,\n                      timeout: int = 30 * 60) -> None\n```\n\nサンドボックス内の指定パスにファイルをアップロードします。宛先パスに既にファイルが存在する場合は上書きされます。メモリに収まる小さなファイルをアップロードする際に有用です。\n\n**引数**:\n\n- `file` _bytes_ - バイト列オブジェクトとしてのファイル内容。\n- `remote_path` _str_ - 宛先ファイルへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `timeout` _int_ - アップロード操作のタイムアウト（秒）。0 はタイムアウトなしを意味します。デフォルトは 30 分です。\n  \n\n**例**:\n\n```python\n# テキストファイルをアップロード\ncontent = b\"Hello, World!\"\nawait sandbox.fs.upload_file(content, \"tmp/hello.txt\")\n\n# ローカルファイルをアップロード\nwith open(\"local_file.txt\", \"rb\") as f:\n    content = f.read()\nawait sandbox.fs.upload_file(content, \"tmp/file.txt\")\n\n# バイナリデータをアップロード\nimport json\ndata = {\"key\": \"value\"}\ncontent = json.dumps(data).encode('utf-8')\nawait sandbox.fs.upload_file(content, \"tmp/config.json\")\n```\n\n#### AsyncFileSystem.upload\\_file\n\n```python\n@overload\nasync def upload_file(local_path: str,\n                      remote_path: str,\n                      timeout: int = 30 * 60) -> None\n```\n\nローカルファイルシステムからサンドボックス内の指定パスにファイルをアップロードします。\n宛先パスにすでにファイルが存在する場合は上書きされます。このメソッドは\nストリーミングでファイルをアップロードするため、メモリに収まりきらない可能性のある大きなファイルの\nアップロードに有用です。\n\n**引数**:\n\n- `local_path` _str_ - アップロードするローカルファイルのパス。\n- `remote_path` _str_ - サンドボックス内の宛先ファイルのパス。相対パスは\n  ユーザーのルートディレクトリを基準に解決されます。\n- `timeout` _int_ - アップロード処理のタイムアウト（秒）。0 はタイムアウトなしを意味します。デフォルトは30分。\n  \n\n**例**:\n\n```python\nawait sandbox.fs.upload_file(\"local_file.txt\", \"tmp/large_file.txt\")\n```\n\n#### AsyncFileSystem.upload\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to upload files: \")\nasync def upload_files(files: List[FileUpload],\n                       timeout: int = 30 * 60) -> None\n```\n\n複数のファイルをサンドボックスにアップロードします。宛先パスにすでにファイルが存在する場合は、\n上書きされます。\n\n**引数**:\n\n- `files` _List[FileUpload]_ - アップロードするファイルのリスト。\n- `timeout` _int_ - アップロード処理のタイムアウト（秒）。0 はタイムアウトなしを意味します。デフォルトは30分。\n\n**例**:\n\n```python\n# 複数のテキストファイルをアップロード\nfiles = [\n    FileUpload(\n        source=b\"Content of file 1\",\n        destination=\"/tmp/file1.txt\"\n    ),\n    FileUpload(\n        source=\"workspace/data/file2.txt\",\n        destination=\"/tmp/file2.txt\"\n    ),\n    FileUpload(\n        source=b'{\"key\": \"value\"}',\n        destination=\"/tmp/config.json\"\n    )\n]\nawait sandbox.fs.upload_files(files)\n```\n\n\n## FileUpload\n\n```python\n@dataclass\nclass FileUpload()\n```\n\nサンドボックスにアップロードするファイルを表します。\n\n**属性**:\n\n- `source` _Union[bytes, str]_ - バイト列またはローカルファイルパスで指定するファイル内容。バイト列を指定する場合はメモリに収まることを確認し、そうでない場合はローカルファイルパスを使用してください。ローカルファイルの内容はサンドボックスへストリーミングされます。\n- `destination` _str_ - サンドボックス内の絶対パス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-git.mdx",
    "content": "---\ntitle: \"AsyncGit\"\nhideTitleOnPage: true\n---\n\n## AsyncGit\n\n```python\nclass AsyncGit()\n```\n\nサンドボックス内でGit操作を提供します。\n\n**例**:\n\n```python\n# リポジトリをクローン\nawait sandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# リポジトリのステータスを確認\nstatus = await sandbox.git.status(\"workspace/repo\")\nprint(f\"Modified files: {status.modified}\")\n\n# 変更をステージしてコミット\nawait sandbox.git.add(\"workspace/repo\", [\"file.txt\"])\nawait sandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update file\",\n    author=\"John Doe\",\n    email=\"john@example.com\"\n)\n```\n\n#### AsyncGit.__init__\n\n```python\ndef __init__(sandbox_id: str, toolbox_api: ToolboxApi,\n             get_root_dir: Callable[[], Awaitable[str]])\n```\n\n新しいGitハンドラーインスタンスを初期化します。\n\n**引数**:\n\n- `sandbox_id` _str_ - サンドボックスID。\n- `toolbox_api` _ToolboxApi_ - サンドボックス操作用のAPIクライアント。\n- `get_root_dir` _Callable[[], str]_ - サンドボックスのデフォルトのルートディレクトリを取得する関数。\n\n#### AsyncGit.add\n\n```python\n@intercept_errors(message_prefix=\"Failed to add files: \")\nasync def add(path: str, files: List[str]) -> None\n```\n\n指定したファイルを次回のコミットに向けてステージします。コマンドラインで\n「git add」を実行するのと同様です。\n\n**引数**:\n\n- `path` _str_ - Gitリポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `files` _List[str]_ - リポジトリルートからの相対パスで、ステージするファイルまたはディレクトリのリスト。\n  \n\n**例**:\n\n```python\n# 単一ファイルをステージ\nawait sandbox.git.add(\"workspace/repo\", [\"file.txt\"])\n\n# 複数ファイルをステージ\nawait sandbox.git.add(\"workspace/repo\", [\n    \"src/main.py\",\n    \"tests/test_main.py\",\n    \"README.md\"\n])\n```\n\n#### AsyncGit.branches\n\n```python\n@intercept_errors(message_prefix=\"Failed to list branches: \")\nasync def branches(path: str) -> ListBranchResponse\n```\n\nリポジトリ内のブランチを一覧表示します。\n\n**引数**:\n\n- `path` _str_ - Gitリポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n  \n\n**返り値**:\n\n- `ListBranchResponse` - リポジトリ内のブランチ一覧。\n  \n\n**例**:\n\n```python\nresponse = await sandbox.git.branches(\"workspace/repo\")\nprint(f\"Branches: {response.branches}\")\n```\n\n#### AsyncGit.clone\n\n```python\n@intercept_errors(message_prefix=\"Failed to clone repository: \")\nasync def clone(url: str,\n                path: str,\n                branch: Optional[str] = None,\n                commit_id: Optional[str] = None,\n                username: Optional[str] = None,\n                password: Optional[str] = None) -> None\n```\n\n指定したパスにGitリポジトリをクローンします。特定のブランチまたはコミットの\nクローンに対応し、認証情報が指定された場合はリモートリポジトリへの\n認証も可能です。\n\n**引数**:\n\n- `url` _str_ - クローン元のリポジトリURL。\n- `path` _str_ - リポジトリをクローンするパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `branch` _Optional[str]_ - クローンするブランチ。未指定の場合は\n  デフォルトブランチをクローンします。\n- `commit_id` _Optional[str]_ - クローンするコミット。指定された場合、\n  リポジトリはこのコミットのdetached HEAD状態になります。\n- `username` _Optional[str]_ - 認証用のGitユーザー名。\n- `password` _Optional[str]_ - 認証用のGitパスワードまたはトークン。\n  \n\n**例**:\n\n```python\n# デフォルトブランチをクローン\nawait sandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# 認証付きで特定のブランチをクローン\nawait sandbox.git.clone(\n    url=\"https://github.com/user/private-repo.git\",\n    path=\"workspace/private\",\n    branch=\"develop\",\n    username=\"user\",\n    password=\"token\"\n)\n\n# 特定のコミットをクローン\nawait sandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo-old\",\n    commit_id=\"abc123\"\n)\n```\n\n#### AsyncGit.commit\n\n```python\n@intercept_errors(message_prefix=\"Failed to commit changes: \")\nasync def commit(path: str,\n                 message: str,\n                 author: str,\n                 email: str,\n                 allow_empty: bool = False) -> GitCommitResponse\n```\n\nステージ済みの変更から新しいコミットを作成します。コミットする前に必ず add() メソッドで変更をステージしてください。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `message` _str_ - 変更内容を説明するコミットメッセージ。\n- `author` _str_ - コミット作者の名前。\n- `email` _str_ - コミット作者のメールアドレス。\n- `allow_empty` _bool, optional_ - 変更がステージされていない場合でも空のコミットの作成を許可します。デフォルトは False。\n  \n\n**例**:\n\n```python\n# 変更をステージしてコミットする\nawait sandbox.git.add(\"workspace/repo\", [\"README.md\"])\nawait sandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update documentation\",\n    author=\"John Doe\",\n    email=\"john@example.com\",\n    allow_empty=True\n)\n```\n\n#### AsyncGit.push\n\n```python\n@intercept_errors(message_prefix=\"Failed to push changes: \")\nasync def push(path: str,\n               username: Optional[str] = None,\n               password: Optional[str] = None) -> None\n```\n\n現在のブランチのすべてのローカルコミットをリモートリポジトリにプッシュします。リモートリポジトリが認証を必要とする場合は、ユーザー名とパスワード／トークンを指定してください。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `username` _Optional[str]_ - 認証用の Git ユーザー名。\n- `password` _Optional[str]_ - 認証用の Git パスワードまたはトークン。\n  \n\n**例**:\n\n```python\n# 認証なしでプッシュ（公開リポジトリや SSH の場合）\nawait sandbox.git.push(\"workspace/repo\")\n\n# 認証ありでプッシュ\nawait sandbox.git.push(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n#### AsyncGit.pull\n\n```python\n@intercept_errors(message_prefix=\"Failed to pull changes: \")\nasync def pull(path: str,\n               username: Optional[str] = None,\n               password: Optional[str] = None) -> None\n```\n\nリモートリポジトリから変更をプルします。リモートリポジトリが認証を必要とする場合は、ユーザー名とパスワード／トークンを指定してください。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `username` _Optional[str]_ - 認証用の Git ユーザー名。\n- `password` _Optional[str]_ - 認証用の Git パスワードまたはトークン。\n  \n\n**例**:\n\n```python\n# 認証なしでプル\nawait sandbox.git.pull(\"workspace/repo\")\n\n# 認証ありでプル\nawait sandbox.git.pull(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n#### AsyncGit.status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get status: \")\nasync def status(path: str) -> GitStatus\n```\n\n現在の Git リポジトリのステータスを取得します。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `GitStatus` - 以下を含むリポジトリのステータス情報:\n  - current_branch: 現在のブランチ名\n  - file_status: ファイルのステータス一覧\n  - ahead: リモートに未プッシュのローカルコミット数\n  - behind: ローカルに未プルのリモートコミット数\n  - branch_published: ブランチがリモートリポジトリに公開済みかどうか\n  \n\n**例**:\n\n```python\nstatus = await sandbox.git.status(\"workspace/repo\")\nprint(f\"On branch: {status.current_branch}\")\nprint(f\"Commits ahead: {status.ahead}\")\nprint(f\"Commits behind: {status.behind}\")\n```\n\n#### AsyncGit.checkout_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to checkout branch: \")\nasync def checkout_branch(path: str, branch: str) -> None\n```\n\nリポジトリでブランチをチェックアウトします。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `branch` _str_ - チェックアウトするブランチ名\n  \n\n**例**:\n\n```python\n# ブランチをチェックアウト\nawait sandbox.git.checkout_branch(\"workspace/repo\", \"feature-branch\")\n```\n\n#### AsyncGit.create_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to create branch: \")\nasync def create_branch(path: str, name: str) -> None\n```\n\nリポジトリでブランチを作成します。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `name` _str_ - 作成する新しいブランチ名\n  \n\n**例**:\n\n```python\n# 新しいブランチを作成\nawait sandbox.git.create_branch(\"workspace/repo\", \"new-feature\")\n```\n\n#### AsyncGit.delete\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete branch: \")\nasync def delete_branch(path: str, name: str) -> None\n```\n\nリポジトリ内のブランチを削除します。\n\n**引数**:\n\n- `path` _str_ - Gitリポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `name` _str_ - 削除するブランチ名\n  \n\n**例**:\n\n```python\n# ブランチを削除\nawait sandbox.git.delete_branch(\"workspace/repo\", \"old-feature\")\n```\n\n\n## GitCommitResponse\n\n```python\nclass GitCommitResponse()\n```\n\nGit の commit 操作に対するレスポンス。\n\n**属性**:\n\n- `sha` _str_ - コミットの SHA\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-lsp-server.mdx",
    "content": "---\ntitle: \"AsyncLspServer\"\nhideTitleOnPage: true\n---\n\n## AsyncLspServer\n\n```python\nclass AsyncLspServer()\n```\n\nコードインテリジェンスのための Language Server Protocol 機能を提供し、コード補完やシンボル検索などの IDE 相当の機能を実現します。\n\n#### AsyncLspServer.__init__\n\n```python\ndef __init__(language_id: LspLanguageId, path_to_project: str,\n             toolbox_api: ToolboxApi, sandbox_id: str)\n```\n\n新しい LSP サーバーインスタンスを初期化します。\n\n**引数**:\n\n- `language_id` _LspLanguageId_ - 言語サーバーの種類（例: LspLanguageId.TYPESCRIPT）。\n- `path_to_project` _str_ - プロジェクトのルートディレクトリへの絶対パス。\n- `toolbox_api` _ToolboxApi_ - サンドボックス操作用の API クライアント。\n- `instance` _SandboxInstance_ - このサーバーが属するサンドボックスインスタンス。\n\n#### AsyncLspServer.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start LSP server: \")\nasync def start() -> None\n```\n\n言語サーバーを起動します。\n\nこのメソッドは、他の LSP 機能を使用する前に呼び出す必要があります。指定した言語とプロジェクト向けに言語サーバーを初期化します。\n\n**例**:\n\n```python\nlsp = sandbox.create_lsp_server(\"typescript\", \"workspace/project\")\nawait lsp.start()  # Initialize the server\n# Now ready for LSP operations\n```\n\n#### AsyncLspServer.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop LSP server: \")\nasync def stop() -> None\n```\n\n言語サーバーを停止します。\n\nLSP サーバーが不要になったときは、システムリソースを解放するためにこのメソッドを呼び出してください。\n\n**例**:\n\n```python\n# When done with LSP features\nawait lsp.stop()  # Clean up resources\n```\n\n#### AsyncLspServer.did_open\n\n```python\n@intercept_errors(message_prefix=\"Failed to open file: \")\nasync def did_open(path: str) -> None\n```\n\nファイルが開かれたことを言語サーバーに通知します。\n\nこのメソッドは、エディタでファイルを開いたときに呼び出し、そのファイルに対する診断や補完などの言語機能を有効化します。サーバーはファイル内容の追跡を開始し、言語機能を提供します。\n\n**引数**:\n\n- `path` _str_ - 開いたファイルのパス。相対パスは LSP サーバーのコンストラクタで設定されたプロジェクトパスに基づいて解決されます。\n  \n\n**例**:\n\n```python\n# When opening a file for editing\nawait lsp.did_open(\"workspace/project/src/index.ts\")\n# Now can get completions, symbols, etc. for this file\n```\n\n#### AsyncLspServer.did_close\n\n```python\n@intercept_errors(message_prefix=\"Failed to close file: \")\nasync def did_close(path: str) -> None\n```\n\nファイルが閉じられたことを言語サーバーに通知します。\n\nこのメソッドは、エディタでファイルを閉じたときに呼び出し、そのファイルに関連するリソースを言語サーバーがクリーンアップできるようにします。\n\n**引数**:\n\n- `path` _str_ - 閉じたファイルのパス。相対パスは LSP サーバーのコンストラクタで設定されたプロジェクトパスに基づいて解決されます。\n  \n\n**例**:\n\n```python\n# When done editing a file\nawait lsp.did_close(\"workspace/project/src/index.ts\")\n```\n\n#### AsyncLspServer.document_symbols\n\n```python\n@intercept_errors(message_prefix=\"Failed to get symbols from document: \")\nasync def document_symbols(path: str) -> List[LspSymbol]\n```\n\nドキュメントからシンボル情報（関数、クラス、変数など）を取得します。\n\n**引数**:\n\n- `path` _str_ - シンボルを取得するファイルのパス。相対パスは LSP サーバーのコンストラクタで設定されたプロジェクトパスに基づいて解決されます。\n  \n\n**戻り値**:\n\n- `List[LspSymbol]` - ドキュメント内のシンボルのリスト。各シンボルには以下が含まれます:\n  - name: シンボル名\n  - kind: シンボルの種類（関数、クラス、変数など）\n  - location: ファイル内のシンボルの位置\n  \n\n**例**:\n\n```python\n# Get all symbols in a file\nsymbols = await lsp.document_symbols(\"workspace/project/src/index.ts\")\nfor symbol in symbols:\n    print(f\"{symbol.kind} {symbol.name}: {symbol.location}\")\n```\n\n#### AsyncLspServer.workspace_symbols\n\n```python\n@deprecated(\n    reason=\n    \"Method is deprecated. Use `sandbox_symbols` instead. This method will be removed in a future version.\"\n)\nasync def workspace_symbols(query: str) -> List[LspSymbol]\n```\n\nサンドボックス内のすべてのファイルを対象に、クエリ文字列に一致するシンボルを検索します。\n\n**引数**:\n\n- `query` _str_ - シンボル名に対してマッチさせる検索クエリ。\n  \n\n**戻り値**:\n\n- `List[LspSymbol]` - すべてのファイルから一致したシンボルのリスト。\n\n#### AsyncLspServer.sandbox\\_symbols\n\n```python\n@intercept_errors(message_prefix=\"Failed to get symbols from sandbox: \")\nasync def sandbox_symbols(query: str) -> List[LspSymbol]\n```\n\nサンドボックス内のすべてのファイルを対象に、クエリ文字列に一致するシンボルを検索します。\n\n**引数**:\n\n- `query` _str_ - シンボル名に対してマッチさせる検索クエリ。\n  \n\n**戻り値**:\n\n- `List[LspSymbol]` - すべてのファイルから一致したシンボルのリスト。各シンボルには次が含まれます:\n  - name: シンボル名\n  - kind: シンボルの種別（関数、クラス、変数など）\n  - location: ファイル内でのシンボルの位置\n  \n\n**例**:\n\n```python\n# \"User\" を含むすべてのシンボルを検索\nsymbols = await lsp.sandbox_symbols(\"User\")\nfor symbol in symbols:\n    print(f\"{symbol.name} in {symbol.location}\")\n```\n\n#### AsyncLspServer.completions\n\n```python\n@intercept_errors(message_prefix=\"Failed to get completions: \")\nasync def completions(path: str, position: Position) -> CompletionList\n```\n\nファイル内の指定位置での補完候補を取得します。\n\n**引数**:\n\n- `path` _str_ - ファイルパス。相対パスは、LSP サーバーのコンストラクタで設定されたプロジェクトパスを基準に解決されます。\n- `position` _Position_ - 補完候補を取得するカーソル位置。\n  \n\n**戻り値**:\n\n- `CompletionList` - 補完候補のリスト。次を含みます:\n  - isIncomplete: 追加の項目が存在する可能性があるか\n  - items: 補完アイテムのリスト。各アイテムには次が含まれます:\n  - label: 挿入するテキスト\n  - kind: 補完の種別\n  - detail: アイテムに関する追加情報\n  - documentation: アイテムのドキュメント\n  - sortText: リスト内での並び替えに用いるテキスト\n  - filterText: フィルタリングに用いるテキスト\n  - insertText: 実際に挿入するテキスト（label と異なる場合）\n  \n\n**例**:\n\n```python\n# 指定位置で補完候補を取得\npos = Position(line=10, character=15)\ncompletions = await lsp.completions(\"workspace/project/src/index.ts\", pos)\nfor item in completions.items:\n    print(f\"{item.label} ({item.kind}): {item.detail}\")\n```\n\n\n## LspLanguageId\n\n```python\nclass LspLanguageId(Enum)\n```\n\nLSP（Language Server Protocol）の言語ID。\n\n**列挙メンバー**:\n    - `PYTHON` (\"python\")\n    - `TYPESCRIPT` (\"typescript\")\n    - `JAVASCRIPT` (\"javascript\")\n\n## Position\n\n```python\nclass Position()\n```\n\nテキストドキュメント内の0始まりの位置を表し、行番号と文字オフセットで指定します。\n\n**属性**:\n\n- `line` _int_ - ドキュメント内の0始まりの行番号。\n- `character` _int_ - 行内の0始まりの文字オフセット。\n\n#### Position.__init__\n\n```python\ndef __init__(line: int, character: int)\n```\n\n新しい Position インスタンスを初期化します。\n\n**引数**:\n\n- `line` _int_ - ドキュメント内の0始まりの行番号。\n- `character` _int_ - 行内の0始まりの文字オフセット。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-object-storage.mdx",
    "content": "---\ntitle: \"AsyncObjectStorage\"\nhideTitleOnPage: true\n---\n\n## AsyncObjectStorage\n\n```python\nclass AsyncObjectStorage()\n```\n\nオブジェクトストレージサービスとやり取りするための AsyncObjectStorage クラス。\n\n**Attributes**:\n\n- `endpoint_url` _str_ - オブジェクトストレージサービスのエンドポイントURL。\n- `aws_access_key_id` _str_ - オブジェクトストレージサービスのアクセスキーID。\n- `aws_secret_access_key` _str_ - オブジェクトストレージサービスのシークレットアクセスキー。\n- `aws_session_token` _str_ - オブジェクトストレージサービスのセッショントークン。一時的な認証情報に使用。\n- `bucket_name` _str_ - 使用するバケット名。既定値は \"daytona-volume-builds\"。\n\n#### AsyncObjectStorage.upload\n\n```python\nasync def upload(path: str,\n                 organization_id: str,\n                 archive_base_path: str | None = None) -> str\n```\n\nファイルをオブジェクトストレージサービスにアップロードします。\n\n**Arguments**:\n\n- `path` _str_ - アップロードするファイルのパス。\n- `organization_id` _str_ - 使用する組織ID。\n- `archive_base_path` _str_ - アーカイブに使用するベースパス。\n  \n\n**Returns**:\n\n- `str` - アップロードしたファイルのハッシュ値。\n\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-sandbox.mdx",
    "content": "---\ntitle: \"AsyncSandbox\"\nhideTitleOnPage: true\n---\n\n## AsyncSandbox\n\n```python\nclass AsyncSandbox(SandboxDto)\n```\n\nDaytona のサンドボックスを表します。\n\n**属性**:\n\n- `fs` _AsyncFileSystem_ - ファイルシステム操作インターフェース。\n- `git` _AsyncGit_ - Git 操作インターフェース。\n- `process` _AsyncProcess_ - プロセス実行インターフェース。\n- `computer_use` _AsyncComputerUse_ - デスクトップ自動化のためのコンピューター使用インターフェース。\n- `id` _str_ - サンドボックスの一意の識別子。\n- `organization_id` _str_ - サンドボックスの組織 ID。\n- `snapshot` _str_ - サンドボックスの作成に使用された Daytona のスナップショット。\n- `user` _str_ - サンドボックス内で実行中の OS ユーザー。\n- `env` _Dict[str, str]_ - サンドボックス内で設定される環境変数。\n- `labels` _Dict[str, str]_ - サンドボックスに付与されたカスタムラベル。\n- `public` _bool_ - サンドボックスが公開アクセス可能かどうか。\n- `target` _str_ - サンドボックスを実行するランナーのターゲット（リージョン）。\n- `cpu` _int_ - サンドボックスに割り当てられた CPU 数。\n- `gpu` _int_ - サンドボックスに割り当てられた GPU 数。\n- `memory` _int_ - サンドボックスに割り当てられたメモリ容量（GiB）。\n- `disk` _int_ - サンドボックスに割り当てられたディスク容量（GiB）。\n- `state` _SandboxState_ - サンドボックスの現在の状態（例: \"started\", \"stopped\"）。\n- `error_reason` _str_ - サンドボックスがエラー状態の場合のエラーメッセージ。\n- `backup_state` _SandboxBackupStateEnum_ - サンドボックスのバックアップ状態。\n- `backup_created_at` _str_ - バックアップの作成時刻。\n- `auto_stop_interval` _int_ - 自動停止の間隔（分）。\n- `auto_archive_interval` _int_ - 自動アーカイブの間隔（分）。\n- `auto_delete_interval` _int_ - 自動削除の間隔（分）。\n- `runner_domain` _str_ - サンドボックスのランナーのドメイン名。\n- `volumes` _List[str]_ - サンドボックスに接続されたボリューム。\n- `build_info` _str_ - 動的ビルドから作成された場合のビルド情報。\n- `created_at` _str_ - サンドボックスの作成時刻。\n- `updated_at` _str_ - サンドボックスの最終更新時刻。\n- `network_block_all` _bool_ - サンドボックスの全ネットワークアクセスをブロックするかどうか。\n- `network_allow_list` _str_ - サンドボックスで許可される CIDR ネットワークアドレスのカンマ区切りリスト。\n\n#### AsyncSandbox.__init__\n\n```python\ndef __init__(sandbox_dto: SandboxDto, sandbox_api: SandboxApi,\n             toolbox_api: ToolboxApi, code_toolbox: SandboxCodeToolbox)\n```\n\n新しいサンドボックスインスタンスを初期化します。\n\n**引数**:\n\n- `id` _str_ - サンドボックスの一意の識別子。\n- `instance` _SandboxInstance_ - 基盤となるサンドボックスインスタンス。\n- `sandbox_api` _SandboxApi_ - サンドボックス操作用の API クライアント。\n- `toolbox_api` _ToolboxApi_ - ツールボックス操作用の API クライアント。\n- `code_toolbox` _SandboxCodeToolbox_ - 言語別のツールボックス実装。\n\n#### AsyncSandbox.refresh_data\n\n```python\nasync def refresh_data() -> None\n```\n\nAPI からサンドボックスのデータを更新します。\n\n**例**:\n\n```python\nawait sandbox.refresh_data()\nprint(f\"Sandbox {sandbox.id}:\")\nprint(f\"State: {sandbox.state}\")\nprint(f\"Resources: {sandbox.cpu} CPU, {sandbox.memory} GiB RAM\")\n```\n\n#### AsyncSandbox.get_user_root_dir\n\n```python\n@intercept_errors(message_prefix=\"Failed to get sandbox root directory: \")\nasync def get_user_root_dir() -> str\n```\n\nサンドボックス内でログイン中のユーザーのルートディレクトリのパスを取得します。\n\n**戻り値**:\n\n- `str` - ログイン中のユーザー向けサンドボックスのルートディレクトリへの絶対パス。\n  \n\n**例**:\n\n```python\nroot_dir = await sandbox.get_user_root_dir()\nprint(f\"Sandbox root: {root_dir}\")\n```\n\n#### AsyncSandbox.create_lsp_server\n\n```python\ndef create_lsp_server(language_id: LspLanguageId,\n                      path_to_project: str) -> AsyncLspServer\n```\n\n新しい Language Server Protocol (LSP) サーバーインスタンスを作成します。\n\nLSP サーバーは、コード補完や診断などの言語固有機能を提供します。\n\n**引数**:\n\n- `language_id` _LspLanguageId_ - 言語サーバーの種類（例: LspLanguageId.PYTHON）。\n- `path_to_project` _str_ - プロジェクトのルートディレクトリへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `LspServer` - 指定した言語向けに構成された新しい LSP サーバーインスタンス。\n  \n\n**例**:\n\n```python\nlsp = sandbox.create_lsp_server(\"python\", \"workspace/project\")\n```\n\n#### AsyncSandbox.set\\_labels\n\n```python\n@intercept_errors(message_prefix=\"Failed to set labels: \")\nasync def set_labels(labels: Dict[str, str]) -> Dict[str, str]\n```\n\nサンドボックスにラベルを設定します。\n\nラベルは、サンドボックスを整理・識別するために使えるキーと値のペアです。\n\n**引数**:\n\n- `labels` _Dict[str, str]_ - サンドボックスのラベルを表すキーと値のペアのディクショナリ。\n  \n\n**戻り値**:\n\n  Dict[str, str]: 更新後のサンドボックスのラベルを含むディクショナリ。\n  \n\n**例**:\n\n```python\nnew_labels = sandbox.set_labels({\n    \"project\": \"my-project\",\n    \"environment\": \"development\",\n    \"team\": \"backend\"\n})\nprint(f\"Updated labels: {new_labels}\")\n```\n\n#### AsyncSandbox.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start sandbox: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Sandbox {self.id} failed to start within the {timeout} seconds timeout period\"\n))\nasync def start(timeout: Optional[float] = 60)\n```\n\nサンドボックスを起動し、準備完了まで待機します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - 最大待機時間（秒）。0 はタイムアウトなし。デフォルトは 60 秒。\n  \n\n**例外**:\n\n- `DaytonaError` - タイムアウトが負の場合。サンドボックスの起動に失敗した場合、またはタイムアウトした場合。\n  \n\n**例**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.start(timeout=40)  # 最大 40 秒待機\nprint(\"Sandbox started successfully\")\n```\n\n#### AsyncSandbox.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop sandbox: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Sandbox {self.id} failed to stop within the {timeout} seconds timeout period\"\n))\nasync def stop(timeout: Optional[float] = 60)\n```\n\nサンドボックスを停止し、完全に停止するまで待機します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - 最大待機時間（秒）。0 はタイムアウトなし。デフォルトは 60 秒。\n  \n\n**例外**:\n\n- `DaytonaError` - タイムアウトが負の場合、またはサンドボックスの停止に失敗した場合／タイムアウトした場合。\n  \n\n**例**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.stop()\nprint(\"Sandbox stopped successfully\")\n```\n\n#### AsyncSandbox.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to remove sandbox: \")\nasync def delete(timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスを削除します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - サンドボックス削除のタイムアウト（秒）。0 はタイムアウトなし。\n  デフォルトは 60 秒。\n\n#### AsyncSandbox.wait\\_for\\_sandbox\\_start\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for sandbox to start: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Sandbox {self.id} failed to become ready within the {timeout} seconds timeout period\"\n))\nasync def wait_for_sandbox_start(timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスが「started」状態になるまで待機します。サンドボックスのステータスをポーリングし、\n「started」になるか、エラーが発生するか、タイムアウトするまで待機します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - 最大待機時間（秒）。0 はタイムアウトなし。デフォルトは 60 秒。\n  \n\n**例外**:\n\n- `DaytonaError` - タイムアウトが負の場合、またはサンドボックスの起動に失敗／タイムアウトした場合。\n\n#### AsyncSandbox.wait\\_for\\_sandbox\\_stop\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for sandbox to stop: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Sandbox {self.id} failed to become stopped within the {timeout} seconds timeout period\"\n))\nasync def wait_for_sandbox_stop(timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスが「stopped」状態になるまで待機します。サンドボックスのステータスをポーリングし、\n「stopped」状態に到達するか、エラーが発生するか、タイムアウトするまで待機します。最大 60 秒間、\nサンドボックスの停止を待機します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - 待機する最大時間（秒）。0 はタイムアウトなし。デフォルトは 60 秒。\n  \n\n**送出**:\n\n- `DaytonaError` - タイムアウトが負の場合。サンドボックスの停止に失敗した場合、またはタイムアウトした場合。\n\n#### AsyncSandbox.set\\_autostop\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-stop interval: \")\nasync def set_autostop_interval(interval: int) -> None\n```\n\nサンドボックスの自動停止間隔を設定します。\n\n指定した間隔のあいだアイドル（新規イベントなし）が続くと、サンドボックスは自動的に停止します。\nイベントには、SDK を通じたサンドボックスのあらゆる状態変更や操作が含まれます。\nサンドボックスのプレビューを用いた操作は含まれません。\n\n**引数**:\n\n- `interval` _int_ - 自動停止までの非アクティブ時間（分）。\n  0 に設定すると自動停止を無効化。デフォルトは 15。\n  \n\n**送出**:\n\n- `DaytonaError` - interval が負の場合\n  \n\n**例**:\n\n```python\n# 1 時間後に自動停止\nsandbox.set_autostop_interval(60)\n# もしくは自動停止を無効化\nsandbox.set_autostop_interval(0)\n```\n\n#### AsyncSandbox.set\\_auto\\_archive\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-archive interval: \")\nasync def set_auto_archive_interval(interval: int) -> None\n```\n\nサンドボックスの自動アーカイブ間隔を設定します。\n\n指定した間隔のあいだ連続して停止状態が続くと、サンドボックスは自動的にアーカイブされます。\n\n**引数**:\n\n- `interval` _int_ - 連続停止中のサンドボックスが自動アーカイブされるまでの分数。\n  0 に設定すると最大の間隔になります。デフォルトは 7 日。\n  \n\n**送出**:\n\n- `DaytonaError` - interval が負の場合\n  \n\n**例**:\n\n```python\n# 1 時間後に自動アーカイブ\nsandbox.set_auto_archive_interval(60)\n# もしくは最大の間隔を使用\nsandbox.set_auto_archive_interval(0)\n```\n\n#### AsyncSandbox.set\\_auto\\_delete\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-delete interval: \")\nasync def set_auto_delete_interval(interval: int) -> None\n```\n\nサンドボックスの自動削除間隔を設定します。\n\n指定した間隔のあいだ連続して停止状態が続くと、サンドボックスは自動的に削除されます。\n\n**引数**:\n\n- `interval` _int_ - 連続停止中のサンドボックスが自動削除されるまでの分数。\n  自動削除を無効化するには負の値を設定。停止時に即時削除するには 0 を設定。\n  既定では自動削除は無効です。\n  \n\n**例**:\n\n```python\n# 1 時間後に自動削除\nsandbox.set_auto_delete_interval(60)\n# もしくは停止時に即時削除\nsandbox.set_auto_delete_interval(0)\n# もしくは自動削除を無効化\nsandbox.set_auto_delete_interval(-1)\n```\n\n#### AsyncSandbox.get\\_preview\\_link\n\n```python\n@intercept_errors(message_prefix=\"Failed to get preview link: \")\nasync def get_preview_link(port: int) -> PortPreviewUrl\n```\n\n指定したポートのサンドボックスに対するプレビューリンクを取得します。ポートが閉じている場合は\n自動的に開かれます。プライベートなサンドボックスの場合は、URL へのアクセスを許可するトークンが\n含まれます。\n\n**引数**:\n\n- `port` _int_ - プレビューリンクを開くポート。\n  \n\n**戻り値**:\n\n- `PortPreviewUrl` - プレビューリンクのレスポンスオブジェクト。`url`\n  と `token`（プライベートなサンドボックスへのアクセス用）を含みます。\n  \n\n**例**:\n\n```python\npreview_link = sandbox.get_preview_link(3000)\nprint(f\"Preview URL: {preview_link.url}\")\nprint(f\"Token: {preview_link.token}\")\n```\n\n#### AsyncSandbox.archive\n\n```python\n@intercept_errors(message_prefix=\"Failed to archive sandbox: \")\nasync def archive() -> None\n```\n\nサンドボックスをアーカイブし、非アクティブ化して状態を保持します。サンドボックスが\nアーカイブされると、ファイルシステムの状態全体がコスト効率の高いオブジェクトストレージに移され、\n長期間にわたってサンドボックスを保持できます。アーカイブ状態と停止状態の\nトレードオフは、サンドボックスのサイズに応じて、アーカイブされたサンドボックスの起動により\n時間がかかる点です。アーカイブ前にサンドボックスは停止している必要があります。\n\n\n## リソース\n\n```python\n@dataclass\nclass Resources()\n```\n\nサンドボックスのリソース構成。\n\n**属性**:\n\n- `cpu` _Optional[int]_ - 割り当てるCPUコア数。\n- `memory` _Optional[int]_ - 割り当てるメモリ容量（GiB）。\n- `disk` _Optional[int]_ - 割り当てるディスク容量（GiB）。\n- `gpu` _Optional[int]_ - 割り当てるGPU数。\n  \n\n**例**:\n\n```python\nresources = Resources(\n    cpu=2,\n    memory=4,  # 4GiB RAM\n    disk=20,   # 20GiB disk\n    gpu=1\n)\nparams = CreateSandboxFromImageParams(\n    image=Image.debian_slim(\"3.12\"),\n    language=\"python\",\n    resources=resources\n)\n```\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-snapshot.mdx",
    "content": "---\ntitle: \"AsyncSnapshot\"\nhideTitleOnPage: true\n---\n\n## スナップショット\n\n```python\nclass Snapshot(SnapshotDto)\n```\n\nDaytona（サンドボックスの作成・管理を行うプラットフォーム）における、事前構成済みのサンドボックスであるスナップショット（リソースや依存関係を含む再利用可能なイメージ/テンプレート）を表します。\n\n**属性**:\n\n- `id` _StrictStr_ - スナップショットの一意の識別子。\n- `organization_id` _Optional[StrictStr]_ - スナップショットの組織（ユーザー・リソースのグループ化、役割・課金・制限を含む）ID。\n- `general` _Optional[bool]_ - スナップショットが汎用かどうか。\n- `name` _StrictStr_ - スナップショットの名称。\n- `image_name` _StrictStr_ - スナップショットのイメージ名。\n- `state` _StrictStr_ - スナップショットの状態。\n- `size` _Optional[Union[StrictFloat, StrictInt]]_ - スナップショットのサイズ。\n- `entrypoint` _Optional[List[str]]_ - スナップショットのエントリーポイント。\n- `cpu` _Union[StrictFloat, StrictInt]_ - スナップショットのCPU。\n- `gpu` _Union[StrictFloat, StrictInt]_ - スナップショットのGPU。\n- `mem` _Union[StrictFloat, StrictInt]_ - スナップショットのメモリ（GiB）。\n- `disk` _Union[StrictFloat, StrictInt]_ - スナップショットのディスク（GiB）。\n- `error_reason` _Optional[StrictStr]_ - スナップショットのエラー理由。\n- `created_at` _StrictStr_ - スナップショットの作成時刻。\n- `updated_at` _StrictStr_ - スナップショットの最終更新時刻。\n- `last_used_at` _StrictStr_ - スナップショットの最終使用時刻。\n\n\n## AsyncSnapshotService\n\n```python\nclass AsyncSnapshotService()\n```\n\nDaytonaのスナップショット（スナップショット（リソースや依存関係を含む再利用可能なイメージ/テンプレート））を管理するサービス。スナップショットの一覧、取得、作成、削除に使用できます。\n\n#### AsyncSnapshotService.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list snapshots: \")\nasync def list() -> List[Snapshot]\n```\n\nすべてのスナップショットを一覧します。\n\n**戻り値**:\n\n- `List[Snapshot]` - すべてのスナップショットのリスト。\n  \n\n**例**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    snapshots = await daytona.snapshot.list()\n    for snapshot in snapshots:\n        print(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n#### AsyncSnapshotService.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete snapshot: \")\nasync def delete(snapshot: Snapshot) -> None\n```\n\nスナップショットを削除します。\n\n**引数**:\n\n- `snapshot` _Snapshot_ - 削除するスナップショット。\n  \n\n**例**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    snapshot = await daytona.snapshot.get(\"test-snapshot\")\n    await daytona.snapshot.delete(snapshot)\n    print(\"Snapshot deleted\")\n```\n\n#### AsyncSnapshotService.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get snapshot: \")\nasync def get(name: str) -> Snapshot\n```\n\n名前を指定してスナップショットを取得します。\n\n**引数**:\n\n- `name` _str_ - 取得するスナップショット名。\n  \n\n**戻り値**:\n\n- `Snapshot` - 取得したスナップショット。\n  \n\n**例**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    snapshot = await daytona.snapshot.get(\"test-snapshot-name\")\n    print(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n#### AsyncSnapshotService.create\n\n```python\n@intercept_errors(message_prefix=\"Failed to create snapshot: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Failed to create snapshot within {timeout} seconds timeout period.\"))\nasync def create(params: CreateSnapshotParams,\n                 *,\n                 on_logs: Callable[[str], None] = None,\n                 timeout: Optional[float] = 0) -> Snapshot\n```\n\n指定されたImage定義から新しいスナップショットを作成し、登録します。\n\n**引数**:\n\n- `params` _CreateSnapshotParams_ - スナップショット作成用パラメータ。\n- `on_logs` _Callable[[str], None]_ - スナップショット作成時のログを処理するコールバック関数。\n- `timeout` _Optional[float]_ - 既定ではタイムアウトなし。秒数で指定（0はタイムアウトなし）。\n\n**例**:\n\n```python\nimage = Image.debianSlim('3.12').pipInstall('numpy')\ndaytona.snapshot.create(\n    CreateSnapshotParams(name='my-snapshot', image=image),\n    on_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n#### AsyncSnapshotService.activate\n\n```python\nasync def activate(snapshot: Snapshot) -> Snapshot\n```\n\nスナップショットをアクティブ化します。\n\n**引数**:\n\n- `snapshot` _Snapshot_ - 対象のスナップショットインスタンス。\n\n**戻り値**:\n\n- `Snapshot` - アクティブ化されたスナップショットインスタンス。\n\n#### AsyncSnapshotService.process\\_image\\_context\n\n```python\n@staticmethod\nasync def process_image_context(object_storage_api: ObjectStorageApi,\n                                image: Image) -> List[str]\n```\n\nイメージのコンテキストをオブジェクトストレージにアップロードして処理します。\n\n**引数**:\n\n- `image` _Image_ - 対象のImageインスタンス。\n\n**戻り値**:\n\n- `List[str]` - オブジェクトストレージに保存されたコンテキストハッシュのリスト。\n\n## CreateSnapshotParams\n\n```python\nclass CreateSnapshotParams(BaseModel)\n```\n\n新しいスナップショットを作成するためのパラメータ。\n\n**属性**:\n\n- `name` _Optional[str]_ - スナップショット名。\n- `image` _Union[str, Image]_ - スナップショットのイメージ。文字列が指定された場合は、\n  いずれかのレジストリで利用可能である必要があります。Image インスタンスが指定された場合は、\n  Daytonaで新しいイメージを作成する際に使用されます。\n- `resources` _Optional[Resources]_ - スナップショットのリソース。\n- `entrypoint` _Optional[List[str]]_ - スナップショットのエントリポイント。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/async/async-volume.mdx",
    "content": "---\ntitle: \"AsyncVolume\"\nhideTitleOnPage: true\n---\n\n## ボリューム\n\n```python\nclass Volume(VolumeDto)\n```\n\nDaytonaのボリューム（S3互換オブジェクトストレージをバックエンドとするFUSEベースの共有ストレージマウント）を表します。サンドボックス間で共有可能なストレージです。\n\n**属性**:\n\n- `id` _StrictStr_ - ボリュームの一意な識別子。\n- `name` _StrictStr_ - ボリューム名。\n- `organization_id` _StrictStr_ - ボリュームが属する組織ID。\n- `state` _StrictStr_ - ボリュームの状態。\n- `created_at` _StrictStr_ - ボリュームの作成日時。\n- `updated_at` _StrictStr_ - ボリュームの最終更新日時。\n- `last_used_at` _StrictStr_ - ボリュームの最終使用日時。\n\n\n## AsyncVolumeService\n\n```python\nclass AsyncVolumeService()\n```\n\nDaytonaのボリューム（ボリューム（S3互換オブジェクトストレージをバックエンドとするFUSEベースの共有ストレージマウント））を管理するサービスです。ボリュームの一覧、取得、作成、削除に使用できます。\n\n#### AsyncVolumeService.list\n\n```python\nasync def list() -> List[Volume]\n```\n\nすべてのボリュームを一覧表示します。\n\n**Returns**:\n\n- `List[Volume]` - すべてのボリュームのリスト。\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    volumes = await daytona.volume.list()\n    for volume in volumes:\n        print(f\"{volume.name} ({volume.id})\")\n```\n\n#### AsyncVolumeService.get\n\n```python\nasync def get(name: str, create: bool = False) -> Volume\n```\n\n名前を指定してボリュームを取得します。\n\n**Arguments**:\n\n- `name` _str_ - 取得するボリューム名。\n- `create` _bool_ - True の場合、存在しなければ新規にボリュームを作成します。\n  \n\n**Returns**:\n\n- `Volume` - 取得したボリュームオブジェクト。\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    volume = await daytona.volume.get(\"test-volume-name\", create=True)\n    print(f\"{volume.name} ({volume.id})\")\n```\n\n#### AsyncVolumeService.create\n\n```python\nasync def create(name: str) -> Volume\n```\n\n新しいボリュームを作成します。\n\n**Arguments**:\n\n- `name` _str_ - 作成するボリューム名。\n  \n\n**Returns**:\n\n- `Volume` - 作成されたボリュームオブジェクト。\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    volume = await daytona.volume.create(\"test-volume\")\n    print(f\"{volume.name} ({volume.id}); state: {volume.state}\")\n```\n\n#### AsyncVolumeService.delete\n\n```python\nasync def delete(volume: Volume) -> None\n```\n\nボリュームを削除します。\n\n**Arguments**:\n\n- `volume` _Volume_ - 削除するボリューム。\n  \n\n**Example**:\n\n```python\nasync with AsyncDaytona() as daytona:\n    volume = await daytona.volume.get(\"test-volume\")\n    await daytona.volume.delete(volume)\n    print(\"Volume deleted\")\n```\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/common/charts.mdx",
    "content": "---\ntitle: \"チャート\"\nhideTitleOnPage: true\n---\n\n## チャート\n\n```python\nclass Chart()\n```\n\nmatplotlib のメタデータを含むチャートを表します。\n\n**属性**:\n\n- `type` _ChartType_ - チャートのタイプ\n- `title` _str_ - チャートのタイトル\n- `elements` _List[Any]_ - チャートの要素\n- `png` _Optional[str]_ - base64 でエンコードされたチャートの PNG 表現\n\n\n## ChartType\n\n```python\nclass ChartType(str, Enum)\n```\n\nチャートタイプ\n\n**列挙メンバー**:\n    - `LINE` (\"line\")\n    - `SCATTER` (\"scatter\")\n    - `BAR` (\"bar\")\n    - `PIE` (\"pie\")\n    - `BOX_AND_WHISKER` (\"box_and_whisker\")\n    - `COMPOSITE_CHART` (\"composite_chart\")\n    - `UNKNOWN` (\"unknown\")\n\n## Chart2D\n\n```python\nclass Chart2D(Chart)\n```\n\nメタデータを含む2次元チャートを表します。\n\n**属性**:\n\n- `x_label` _Optional[str]_ - x軸のラベル\n- `y_label` _Optional[str]_ - y軸のラベル\n\n## PointData\n\n```python\nclass PointData()\n```\n\n2Dチャート上の点を表します。\n\n**属性**:\n\n- `label` _str_ - 点のラベル\n- `points` _List[Tuple[Union[str, float], Union[str, float]]]_ - チャート上の点の配列\n\n## PointChart\n\n```python\nclass PointChart(Chart2D)\n```\n\nメタデータ付きの散布図（ポイントチャート）を表します。\n\n**属性**:\n\n- `x_ticks` _List[Union[str, float]]_ - x軸の目盛\n- `x_tick_labels` _List[str]_ - x軸の目盛ラベル\n- `x_scale` _str_ - x軸のスケール\n- `y_ticks` _List[Union[str, float]]_ - y軸の目盛\n- `y_tick_labels` _List[str]_ - y軸の目盛ラベル\n- `y_scale` _str_ - y軸のスケール\n- `elements` _List[PointData]_ - 図の点要素\n\n## LineChart\n\n```python\nclass LineChart(PointChart)\n```\n\nメタデータ付きの折れ線グラフを表します。\n\n**属性**:\n\n- `type` _ChartType_ - チャートの種類\n\n## ScatterChart\n\n```python\nclass ScatterChart(PointChart)\n```\n\nメタデータを含む散布図を表します。\n\n**属性**:\n\n- `type` _ChartType_ - チャートのタイプ\n\n## BarData\n\n```python\nclass BarData()\n```\n\n棒グラフの1本の棒を表します。\n\n**属性**:\n\n- `label` _str_ - 棒のラベル\n- `group` _str_ - 棒のグループ\n- `value` _str_ - 棒の値\n\n## BarChart\n\n```python\nclass BarChart(Chart2D)\n```\n\nメタデータ付きの棒グラフを表します。\n\n**属性**:\n\n- `type` _ChartType_ - グラフのタイプ\n- `elements` _List[BarData]_ - 棒（バー）のリスト\n\n## PieData\n\n```python\nclass PieData()\n```\n\n円グラフのスライス（扇形）を表します。\n\n**属性**:\n\n- `label` _str_ - スライスのラベル\n- `angle` _float_ - スライスの角度\n- `radius` _float_ - スライスの半径\n- `autopct` _float_ - スライスのautopct値\n\n## PieChart\n\n```python\nclass PieChart(Chart)\n```\n\nメタデータを持つ円グラフを表します。\n\n**属性**:\n\n- `type` _ChartType_ - グラフの種類\n- `elements` _List[PieData]_ - 円グラフのスライス\n\n## BoxAndWhiskerData\n\n```python\nclass BoxAndWhiskerData()\n```\n\n箱ひげ図における箱ひげを表します。\n\n**属性**:\n\n- `label` _str_ - 箱ひげのラベル\n- `min` _float_ - 箱ひげの最小値\n- `first_quartile` _float_ - 箱ひげの第1四分位数\n- `median` _float_ - 箱ひげの中央値\n- `third_quartile` _float_ - 箱ひげの第3四分位数\n- `max` _float_ - 箱ひげの最大値\n- `outliers` _List[float]_ - 箱ひげの外れ値\n\n## BoxAndWhiskerChart\n\n```python\nclass BoxAndWhiskerChart(Chart2D)\n```\n\nメタデータ付きの箱ひげ図を表します。\n\n**属性**:\n\n- `type` _ChartType_ - チャートのタイプ\n- `elements` _List[BoxAndWhiskerData]_ - チャートの箱ひげ要素\n\n## CompositeChart\n\n```python\nclass CompositeChart(Chart)\n```\n\nメタデータを持つ複合チャートを表します。複合チャートは、複数のチャート（サブプロット）で構成されるチャートです。\n\n**属性**:\n\n- `type` _ChartType_ - チャートのタイプ\n- `elements` _List[Chart]_ - 複合チャートを構成するチャート（サブプロット）\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/common/errors.mdx",
    "content": "---\ntitle: \"エラー\"\nhideTitleOnPage: true\n---\n\n## DaytonaError\n\n```python\nclass DaytonaError(Exception)\n```\n\nDaytona SDKの基底エラー。\n\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/common/image.mdx",
    "content": "---\ntitle: \"イメージ（画像）\"\nhideTitleOnPage: true\n---\n\n## イメージ\n\n```python\nclass Image(BaseModel)\n```\n\nDaytona のサンドボックス用イメージ定義を表します。\nこのクラスを直接インスタンス化しないでください。代わりに `Image.base()`、`Image.debian_slim()`、`Image.from_dockerfile()` などの静的ファクトリメソッドを使用します。\n\n#### Image.dockerfile\n\n```python\ndef dockerfile() -> str\n```\n\nこのイメージ向けに生成された Dockerfile を返します。\n\n#### Image.pip_install\n\n```python\ndef pip_install(*packages: Union[str, list[str]],\n                find_links: Optional[list[str]] = None,\n                index_url: Optional[str] = None,\n                extra_index_urls: Optional[list[str]] = None,\n                pre: bool = False,\n                extra_options: str = \"\") -> \"Image\"\n```\n\npip を使用してパッケージをインストールするコマンドを追加します。\n\n**引数**:\n\n- `*packages` - インストールするパッケージ。\n- `find_links` - Optional[list[str]]: 使用する find-links。\n- `index_url` - Optional[str]: 使用する index URL。\n- `extra_index_urls` - Optional[list[str]]: 使用する追加の index URL。\n- `pre` - bool = False: プレリリース版パッケージをインストールするかどうか。\n- `extra_options` - str = \"\": pip に渡す追加オプション。指定した文字列は\n  そのまま pip install コマンドに渡されます。\n  \n\n**戻り値**:\n\n- `Image` - pip install コマンドが追加されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").pip_install(\"requests\", \"pandas\")\n```\n\n#### Image.pip_install_from_requirements\n\n```python\ndef pip_install_from_requirements(requirements_txt: str,\n                                  find_links: Optional[list[str]] = None,\n                                  index_url: Optional[str] = None,\n                                  extra_index_urls: Optional[list[str]] = None,\n                                  pre: bool = False,\n                                  extra_options: str = \"\") -> \"Image\"\n```\n\nrequirements.txt から依存関係をインストールします。\n\n**引数**:\n\n- `requirements_txt` - str: requirements.txt へのパス。\n- `find_links` - Optional[list[str]]: 使用する find-links。\n- `index_url` - Optional[str]: 使用する index URL。\n- `extra_index_urls` - Optional[list[str]]: 使用する追加の index URL。\n- `pre` - bool = False: プレリリース版パッケージをインストールするかどうか。\n- `extra_options` - str = \"\": pip に渡す追加オプション。\n  \n\n**戻り値**:\n\n- `Image` - pip install コマンドが追加されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").pip_install_from_requirements(\"requirements.txt\")\n```\n\n#### Image.pip_install_from_pyproject\n\n```python\ndef pip_install_from_pyproject(pyproject_toml: str,\n                               optional_dependencies: list[str],\n                               find_links: Optional[str] = None,\n                               index_url: Optional[str] = None,\n                               extra_index_url: Optional[str] = None,\n                               pre: bool = False,\n                               extra_options: str = \"\") -> \"Image\"\n```\n\npyproject.toml から依存関係をインストールします。\n\n**引数**:\n\n- `pyproject_toml` - str: pyproject.toml へのパス。\n- `optional_dependencies` - list[str] = []: pyproject.toml からインストールする任意の依存関係。\n- `find_links` - Optional[str] = None: 使用する find-links。\n- `index_url` - Optional[str] = None: 使用する index URL。\n- `extra_index_url` - Optional[str] = None: 使用する追加の index URL。\n- `pre` - bool = False: プレリリース版パッケージをインストールするかどうか。\n- `extra_options` - str = \"\": pip に渡す追加オプション。指定した文字列は\n  そのまま pip install コマンドに渡されます。\n  \n\n**戻り値**:\n\n- `Image` - pip install コマンドが追加されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\")                 .pip_install_from_pyproject(\"pyproject.toml\", optional_dependencies=[\"dev\"])\n```\n\n#### Image.add_local_file\n\n```python\ndef add_local_file(local_path: Union[str, Path], remote_path: str) -> \"Image\"\n```\n\nローカルファイルをイメージに追加します。\n\n**引数**:\n\n- `local_path` - Union[str, Path]: ローカルファイルへのパス。\n- `remote_path` - str: イメージ内のファイルのパス。\n  \n\n**戻り値**:\n\n- `Image` - ローカルファイルが追加されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").add_local_file(\"package.json\", \"/home/daytona/package.json\")\n```\n\n#### Image.add\\_local\\_dir\n\n```python\ndef add_local_dir(local_path: Union[str, Path], remote_path: str) -> \"Image\"\n```\n\nローカルディレクトリをイメージに追加します。\n\n**引数**:\n\n- `local_path` - Union[str, Path]: ローカルディレクトリへのパス。\n- `remote_path` - str: イメージ内のディレクトリへのパス。\n  \n\n**戻り値**:\n\n- `Image` - ローカルディレクトリが追加されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").add_local_dir(\"src\", \"/home/daytona/src\")\n```\n\n#### Image.run\\_commands\n\n```python\ndef run_commands(*commands: Union[str, list[str]]) -> \"Image\"\n```\n\nイメージ内でコマンドを実行します。\n\n**引数**:\n\n- `*commands` - 実行するコマンド列。\n  \n\n**戻り値**:\n\n- `Image` - コマンドが追加されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").run_commands(\n    'echo \"Hello, world!\"',\n    ['bash', '-c', 'echo Hello, world, again!']\n)\n```\n\n#### Image.env\n\n```python\ndef env(env_vars: dict[str, str]) -> \"Image\"\n```\n\nイメージ内の環境変数を設定します。\n\n**引数**:\n\n- `env_vars` - dict[str, str]: 設定する環境変数。\n  \n\n**戻り値**:\n\n- `Image` - 環境変数が追加されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").env({\"PROJECT_ROOT\": \"/home/daytona\"})\n```\n\n#### Image.workdir\n\n```python\ndef workdir(path: Union[str, Path]) -> \"Image\"\n```\n\nイメージ内の作業ディレクトリを設定します。\n\n**引数**:\n\n- `path` - Union[str, Path]: 作業ディレクトリへのパス。\n  \n\n**戻り値**:\n\n- `Image` - 作業ディレクトリが設定されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").workdir(\"/home/daytona\")\n```\n\n#### Image.entrypoint\n\n```python\ndef entrypoint(entrypoint_commands: list[str]) -> \"Image\"\n```\n\nイメージのエントリポイントを設定します。\n\n**引数**:\n\n- `entrypoint_commands` - list[str]: エントリポイントとして設定するコマンド。\n  \n\n**戻り値**:\n\n- `Image` - エントリポイントが設定されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").entrypoint([\"/bin/bash\"])\n```\n\n#### Image.cmd\n\n```python\ndef cmd(cmd: list[str]) -> \"Image\"\n```\n\nイメージのデフォルトコマンドを設定します。\n\n**引数**:\n\n- `cmd` - list[str]: デフォルトコマンドとして設定するコマンド。\n  \n\n**戻り値**:\n\n- `Image` - デフォルトコマンドが設定されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").cmd([\"/bin/bash\"])\n```\n\n#### Image.dockerfile\\_commands\n\n```python\ndef dockerfile_commands(\n        dockerfile_commands: list[str],\n        context_dir: Optional[Union[Path, str]] = None) -> \"Image\"\n```\n\n任意のDockerfile風のコマンドをイメージに追加します。\n\n**引数**:\n\n- `*dockerfile_commands` - Dockerfileに追加するコマンド。\n- `context_dir` - Optional[Union[Path, str]]: コンテキストディレクトリへのパス。\n  \n\n**戻り値**:\n\n- `Image` - Dockerfileコマンドが追加されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\").dockerfile_commands([\"RUN echo 'Hello, world!'\"])\n```\n\n#### Image.from\\_dockerfile\n\n```python\n@staticmethod\ndef from_dockerfile(path: Union[str, Path]) -> \"Image\"\n```\n\n既存のDockerfileからImageを作成します。\n\n**引数**:\n\n- `path` - Union[str, Path]: Dockerfileへのパス。\n  \n\n**戻り値**:\n\n- `Image` - Dockerfileを元に作成されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.from_dockerfile(\"Dockerfile\")\n```\n\n#### Image.base\n\n```python\n@staticmethod\ndef base(image: str) -> \"Image\"\n```\n\n既存のベースイメージからImageを作成します。\n\n**引数**:\n\n- `image` - str: 使用するベースイメージ。\n  \n\n**戻り値**:\n\n- `Image` - ベースイメージを基に作成されたイメージ。\n  \n\n**例**:\n\n```python\nimage = Image.base(\"python:3.12-slim-bookworm\")\n```\n\n#### Image.debian\\_slim\n\n```python\n@staticmethod\ndef debian_slim(\n        python_version: Optional[SupportedPythonSeries] = None) -> \"Image\"\n```\n\n公式の Python Docker イメージをベースにした Debian slim イメージを作成します。\n\n**引数**:\n\n- `python_version` - Optional[SupportedPythonSeries]: 使用する Python のバージョン。\n  \n\n**戻り値**:\n\n- `Image` - Debian slim イメージを追加した Image。\n  \n\n**例**:\n\n```python\nimage = Image.debian_slim(\"3.12\")\n```\n\n\n## コンテキスト\n\n```python\nclass Context(BaseModel)\n```\n\nイメージに関するコンテキスト。\n\n**属性**:\n\n- `source_path` _str_ - 元ファイルまたはディレクトリへのパス。\n- `archive_path` _Optional[str]_ - オブジェクトストレージ内のアーカイブファイル内でのパス。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/index.mdx",
    "content": "---\ntitle: Python SDK リファレンス\ndescription: Python SDK を使用して Daytona サンドボックスとやり取りする\nnext: /docs/python-sdk/daytona\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona の Python SDK は、Daytona サンドボックスとプログラム的にやり取りするための堅牢なインターフェースを提供します。\n\n## インストール\n\npip で Daytona の Python SDK をインストールします:\n\n```bash\npip install daytona\n```\n\nまたは poetry を使用します:\n\n```bash\npoetry add daytona\n```\n\n## はじめに\n\nDaytona の Python SDK を使い始めるためのシンプルな例を示します。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Sync\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona\n\n    def main():\n        # SDK を初期化（既定で環境変数を使用）\n        daytona = Daytona()\n\n        # サンドボックスを新規作成\n        sandbox = daytona.create()\n\n        # コマンドを実行\n        response = sandbox.process.exec(\"echo 'Hello, World!'\")\n        print(response.result)\n\n    if __name__ == \"__main__\":\n        main()\n    ```\n  </TabItem>\n\n  <TabItem label=\"Async\" icon=\"seti:python\">\n    ```python\n    import asyncio\n    from daytona import AsyncDaytona\n\n    async def main():\n        # SDK を初期化（既定で環境変数を使用）\n        async with AsyncDaytona() as daytona:\n            # サンドボックスを新規作成\n            sandbox = await daytona.create()\n\n            # コマンドを実行\n            response = await sandbox.process.exec(\"echo 'Hello, World!'\")\n            print(response.result)\n\n    if __name__ == \"__main__\":\n        asyncio.run(main())\n    ```\n  </TabItem>\n</Tabs>\n\n## 構成\n\nSDK は環境変数を使うか、コンストラクタにオプションを渡して設定できます:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Sync\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, DaytonaConfig\n\n    # 環境変数を使用 (DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET)\n    daytona = Daytona()\n\n    # 明示的な設定を使用\n    config = DaytonaConfig(\n        api_key=\"your-api-key\",\n        api_url=\"https://app.daytona.io/api\",\n        target=\"us\"\n    )\n    daytona = Daytona(config)\n    ```\n  </TabItem>\n\n  <TabItem label=\"Async\" icon=\"seti:python\">\n    ```python\n    import asyncio\n    from daytona import AsyncDaytona, DaytonaConfig\n\n    async def main():\n        try:\n            # 環境変数を使用 (DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET)\n            daytona = AsyncDaytona()\n            # 非同期コードをここに記述\n            pass\n        finally:\n            await daytona.close()\n\n        # 明示的な設定を使用\n        config = DaytonaConfig(\n            api_key=\"your-api-key\",\n            api_url=\"https://app.daytona.io/api\",\n            target=\"us\"\n        )\n        async with AsyncDaytona(config) as daytona:\n            # ここにコードを記述\n            pass\n\n    if __name__ == \"__main__\":\n        asyncio.run(main())\n    ```\n  </TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/computer-use.mdx",
    "content": "---\ntitle: \"コンピューター使用\"\nhideTitleOnPage: true\n---\n\n## ComputerUse\n\n```python\nclass ComputerUse()\n```\n\nデスクトップ環境と対話するためのコンピューター使用機能。\n\nサンドボックス内でのデスクトップ操作を自動化するために、マウス、キーボード、スクリーンショット、ディスプレイの操作にアクセスできます。\n\n**属性**:\n\n- `mouse` _Mouse_ - マウス操作インターフェース。\n- `keyboard` _Keyboard_ - キーボード操作インターフェース。\n- `screenshot` _Screenshot_ - スクリーンショット操作インターフェース。\n- `display` _Display_ - ディスプレイ操作インターフェース。\n\n#### ComputerUse.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start computer use: \")\ndef start() -> ComputerUseStartResponse\n```\n\nすべてのコンピューター使用プロセス（Xvfb、xfce4、x11vnc、novnc）を起動します。\n\n**戻り値**:\n\n- `ComputerUseStartResponse` - コンピューター使用の起動レスポンス。\n  \n\n**例**:\n\n```python\nresult = sandbox.computer_use.start()\nprint(\"Computer use processes started:\", result.message)\n```\n\n#### ComputerUse.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop computer use: \")\ndef stop() -> ComputerUseStopResponse\n```\n\nすべてのコンピューター使用プロセスを停止します。\n\n**戻り値**:\n\n- `ComputerUseStopResponse` - コンピューター使用の停止レスポンス。\n  \n\n**例**:\n\n```python\nresult = sandbox.computer_use.stop()\nprint(\"Computer use processes stopped:\", result.message)\n```\n\n#### ComputerUse.get_status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get computer use status: \")\ndef get_status() -> ComputerUseStatusResponse\n```\n\nすべてのコンピューター使用プロセスのステータスを取得します。\n\n**戻り値**:\n\n- `ComputerUseStatusResponse` - すべてのVNCデスクトッププロセスに関するステータス情報。\n  \n\n**例**:\n\n```python\nresponse = sandbox.computer_use.get_status()\nprint(\"Computer use status:\", response.status)\n```\n\n#### ComputerUse.get_process_status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process status: \")\ndef get_process_status(process_name: str) -> ProcessStatusResponse\n```\n\n特定のVNCプロセスのステータスを取得します。\n\n**引数**:\n\n- `process_name` _str_ - 確認するプロセス名。\n  \n\n**戻り値**:\n\n- `ProcessStatusResponse` - 指定したプロセスに関するステータス情報。\n  \n\n**例**:\n\n```python\nxvfb_status = sandbox.computer_use.get_process_status(\"xvfb\")\nno_vnc_status = sandbox.computer_use.get_process_status(\"novnc\")\n```\n\n#### ComputerUse.restart_process\n\n```python\n@intercept_errors(message_prefix=\"Failed to restart process: \")\ndef restart_process(process_name: str) -> ProcessRestartResponse\n```\n\n特定のVNCプロセスを再起動します。\n\n**引数**:\n\n- `process_name` _str_ - 再起動するプロセス名。\n  \n\n**戻り値**:\n\n- `ProcessRestartResponse` - プロセス再起動レスポンス。\n  \n\n**例**:\n\n```python\nresult = sandbox.computer_use.restart_process(\"xfce4\")\nprint(\"XFCE4 process restarted:\", result.message)\n```\n\n#### ComputerUse.get_process_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process logs: \")\ndef get_process_logs(process_name: str) -> ProcessLogsResponse\n```\n\n特定のVNCプロセスのログを取得します。\n\n**引数**:\n\n- `process_name` _str_ - ログを取得するプロセス名。\n  \n\n**戻り値**:\n\n- `ProcessLogsResponse` - プロセスのログ。\n  \n\n**例**:\n\n```python\nlogs = sandbox.computer_use.get_process_logs(\"novnc\")\nprint(\"NoVNC logs:\", logs)\n```\n\n#### ComputerUse.get_process_errors\n\n```python\n@intercept_errors(message_prefix=\"Failed to get process errors: \")\ndef get_process_errors(process_name: str) -> ProcessErrorsResponse\n```\n\n特定のVNCプロセスのエラーログを取得します。\n\n**引数**:\n\n- `process_name` _str_ - エラーログを取得するプロセス名。\n  \n\n**戻り値**:\n\n- `ProcessErrorsResponse` - プロセスのエラーログ。\n  \n\n**例**:\n\n```python\nerrors = sandbox.computer_use.get_process_errors(\"x11vnc\")\nprint(\"X11VNC errors:\", errors)\n```\n\n\n## マウス\n\n```python\nclass Mouse()\n```\n\nコンピューター使用機能のマウス操作。\n\n#### Mouse.get\\_position\n\n```python\n@intercept_errors(message_prefix=\"Failed to get mouse position: \")\ndef get_position() -> MousePosition\n```\n\n現在のマウスカーソル位置を取得します。\n\n**戻り値**:\n\n- `MousePosition` - 現在のマウス位置（x および y 座標）。\n  \n\n**例**:\n\n```python\nposition = sandbox.computer_use.mouse.get_position()\nprint(f\"Mouse is at: {position.x}, {position.y}\")\n```\n\n#### Mouse.move\n\n```python\n@intercept_errors(message_prefix=\"Failed to move mouse: \")\ndef move(x: int, y: int) -> MouseMoveResponse\n```\n\nマウスカーソルを指定した座標に移動します。\n\n**引数**:\n\n- `x` _int_ - 移動先の x 座標。\n- `y` _int_ - 移動先の y 座標。\n  \n\n**戻り値**:\n\n- `MouseMoveResponse` - 移動操作の結果。\n  \n\n**例**:\n\n```python\nresult = sandbox.computer_use.mouse.move(100, 200)\nprint(f\"Mouse moved to: {result.x}, {result.y}\")\n```\n\n#### Mouse.click\n\n```python\n@intercept_errors(message_prefix=\"Failed to click mouse: \")\ndef click(x: int,\n          y: int,\n          button: str = \"left\",\n          double: bool = False) -> MouseClickResponse\n```\n\n指定した座標でクリックします。\n\n**引数**:\n\n- `x` _int_ - クリックする x 座標。\n- `y` _int_ - クリックする y 座標。\n- `button` _str_ - クリックするボタン（'left'、'right'、'middle'）。\n- `double` _bool_ - ダブルクリックを行うかどうか。\n  \n\n**戻り値**:\n\n- `MouseClickResponse` - クリック操作の結果。\n  \n\n**例**:\n\n```python\n# Single left click\nresult = sandbox.computer_use.mouse.click(100, 200)\n\n# Double click\ndouble_click = sandbox.computer_use.mouse.click(100, 200, \"left\", True)\n\n# Right click\nright_click = sandbox.computer_use.mouse.click(100, 200, \"right\")\n```\n\n#### Mouse.drag\n\n```python\n@intercept_errors(message_prefix=\"Failed to drag mouse: \")\ndef drag(start_x: int,\n         start_y: int,\n         end_x: int,\n         end_y: int,\n         button: str = \"left\") -> MouseDragResponse\n```\n\n開始座標から終了座標までドラッグします。\n\n**引数**:\n\n- `start_x` _int_ - 開始 x 座標。\n- `start_y` _int_ - 開始 y 座標。\n- `end_x` _int_ - 終了 x 座標。\n- `end_y` _int_ - 終了 y 座標。\n- `button` _str_ - ドラッグに使用するボタン。\n  \n\n**戻り値**:\n\n- `MouseDragResponse` - ドラッグ操作の結果。\n  \n\n**例**:\n\n```python\nresult = sandbox.computer_use.mouse.drag(50, 50, 150, 150)\nprint(f\"Dragged from {result.from_x},{result.from_y} to {result.to_x},{result.to_y}\")\n```\n\n#### Mouse.scroll\n\n```python\n@intercept_errors(message_prefix=\"Failed to scroll mouse: \")\ndef scroll(x: int, y: int, direction: str, amount: int = 1) -> bool\n```\n\n指定した座標でマウスホイールをスクロールします。\n\n**引数**:\n\n- `x` _int_ - スクロールする x 座標。\n- `y` _int_ - スクロールする y 座標。\n- `direction` _str_ - スクロール方向（'up' または 'down'）。\n- `amount` _int_ - スクロール量。\n  \n\n**戻り値**:\n\n- `bool` - スクロール操作が成功したかどうか。\n  \n\n**例**:\n\n```python\n# Scroll up\nscroll_up = sandbox.computer_use.mouse.scroll(100, 200, \"up\", 3)\n\n# Scroll down\nscroll_down = sandbox.computer_use.mouse.scroll(100, 200, \"down\", 5)\n```\n\n## キーボード\n\n```python\nclass Keyboard()\n```\n\nコンピューター使用機能向けのキーボード操作。\n\n#### Keyboard.type\n\n```python\n@intercept_errors(message_prefix=\"Failed to type text: \")\ndef type(text: str, delay: Optional[int] = None) -> None\n```\n\n指定したテキストを入力します。\n\n**引数**:\n\n- `text` _str_ - 入力するテキスト。\n- `delay` _int_ - 文字間の遅延（ミリ秒）。\n  \n\n**送出**:\n\n- `DaytonaError` - 入力処理に失敗した場合。\n  \n\n**例**:\n\n```python\ntry:\n    sandbox.computer_use.keyboard.type(\"Hello, World!\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# 文字間に遅延を設ける場合\ntry:\n    sandbox.computer_use.keyboard.type(\"Slow typing\", 100)\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n#### Keyboard.press\n\n```python\n@intercept_errors(message_prefix=\"Failed to press key: \")\ndef press(key: str, modifiers: Optional[List[str]] = None) -> None\n```\n\n必要に応じてモディファイアを併用してキーを押します。\n\n**引数**:\n\n- `key` _str_ - 押すキー（例: 'Enter', 'Escape', 'Tab', 'a', 'A'）。\n- `modifiers` _List[str]_ - モディファイアキー（'ctrl', 'alt', 'meta', 'shift'）。\n  \n\n**送出**:\n\n- `DaytonaError` - キー押下処理に失敗した場合。\n  \n\n**例**:\n\n```python\n# Enter を押す\ntry:\n    sandbox.computer_use.keyboard.press(\"Return\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Ctrl+C を押す\ntry:\n    sandbox.computer_use.keyboard.press(\"c\", [\"ctrl\"])\n    print(f\"Operation success\")\n\n# Ctrl+Shift+T を押す\ntry:\n    sandbox.computer_use.keyboard.press(\"t\", [\"ctrl\", \"shift\"])\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n#### Keyboard.hotkey\n\n```python\n@intercept_errors(message_prefix=\"Failed to press hotkey: \")\ndef hotkey(keys: str) -> None\n```\n\nホットキーの組み合わせを押します。\n\n**引数**:\n\n- `keys` _str_ - ホットキーの組み合わせ（例: 'ctrl+c', 'alt+tab', 'cmd+shift+t'）。\n  \n\n**送出**:\n\n- `DaytonaError` - ホットキー処理に失敗した場合。\n  \n\n**例**:\n\n```python\n# コピー\ntry:\n    sandbox.computer_use.keyboard.hotkey(\"ctrl+c\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# ペースト\ntry:\n    sandbox.computer_use.keyboard.hotkey(\"ctrl+v\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n\n# Alt+Tab\ntry:\n    sandbox.computer_use.keyboard.hotkey(\"alt+tab\")\n    print(f\"Operation success\")\nexcept Exception as e:\n    print(f\"Operation failed: {e}\")\n```\n\n## スクリーンショット\n\n```python\nclass Screenshot()\n```\n\nコンピューター使用機能のスクリーンショット操作。\n\n#### Screenshot.take\\_full\\_screen\n\n```python\n@intercept_errors(message_prefix=\"Failed to take screenshot: \")\ndef take_full_screen(show_cursor: bool = False) -> ScreenshotResponse\n```\n\n画面全体のスクリーンショットを撮影します。\n\n**引数**:\n\n- `show_cursor` _bool_ - スクリーンショットにカーソルを表示するかどうか。\n  \n\n**戻り値**:\n\n- `ScreenshotResponse` - 画像をbase64エンコードしたスクリーンショットデータ。\n  \n\n**例**:\n\n```python\nscreenshot = sandbox.computer_use.screenshot.take_full_screen()\nprint(f\"Screenshot size: {screenshot.width}x{screenshot.height}\")\n\n# カーソルを表示\nwith_cursor = sandbox.computer_use.screenshot.take_full_screen(True)\n```\n\n#### Screenshot.take\\_region\n\n```python\n@intercept_errors(message_prefix=\"Failed to take region screenshot: \")\ndef take_region(region: ScreenshotRegion,\n                show_cursor: bool = False) -> RegionScreenshotResponse\n```\n\n指定した領域のスクリーンショットを撮影します。\n\n**引数**:\n\n- `region` _ScreenshotRegion_ - 取得する領域。\n- `show_cursor` _bool_ - スクリーンショットにカーソルを表示するかどうか。\n  \n\n**戻り値**:\n\n- `RegionScreenshotResponse` - 画像をbase64エンコードしたスクリーンショットデータ。\n  \n\n**例**:\n\n```python\nregion = ScreenshotRegion(x=100, y=100, width=300, height=200)\nscreenshot = sandbox.computer_use.screenshot.take_region(region)\nprint(f\"Captured region: {screenshot.region.width}x{screenshot.region.height}\")\n```\n\n#### Screenshot.take\\_compressed\n\n```python\n@intercept_errors(message_prefix=\"Failed to take compressed screenshot: \")\ndef take_compressed(\n    options: Optional[ScreenshotOptions] = None\n) -> CompressedScreenshotResponse\n```\n\n画面全体の圧縮スクリーンショットを撮影します。\n\n**引数**:\n\n- `options` _ScreenshotOptions_ - 圧縮および表示のオプション。\n  \n\n**戻り値**:\n\n- `CompressedScreenshotResponse` - 圧縮されたスクリーンショットデータ。\n  \n\n**例**:\n\n```python\n# 既定の圧縮\nscreenshot = sandbox.computer_use.screenshot.take_compressed()\n\n# 高品質JPEG\njpeg = sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"jpeg\", quality=95, show_cursor=True)\n)\n\n# 縮小PNG\nscaled = sandbox.computer_use.screenshot.take_compressed(\n    ScreenshotOptions(format=\"png\", scale=0.5)\n)\n```\n\n#### Screenshot.take\\_compressed\\_region\n\n```python\n@intercept_errors(\n    message_prefix=\"Failed to take compressed region screenshot: \")\ndef take_compressed_region(\n    region: ScreenshotRegion,\n    options: Optional[ScreenshotOptions] = None\n) -> CompressedScreenshotResponse\n```\n\n指定した領域の圧縮スクリーンショットを撮影します。\n\n**引数**:\n\n- `region` _ScreenshotRegion_ - 取得する領域。\n- `options` _ScreenshotOptions_ - 圧縮および表示のオプション。\n  \n\n**戻り値**:\n\n- `CompressedScreenshotResponse` - 圧縮されたスクリーンショットデータ。\n  \n\n**例**:\n\n```python\nregion = ScreenshotRegion(x=0, y=0, width=800, height=600)\nscreenshot = sandbox.computer_use.screenshot.take_compressed_region(\n    region,\n    ScreenshotOptions(format=\"webp\", quality=80, show_cursor=True)\n)\nprint(f\"Compressed size: {screenshot.size_bytes} bytes\")\n```\n\n## ディスプレイ\n\n```python\nclass Display()\n```\n\nコンピューター使用機能のディスプレイ操作を提供します。\n\n#### Display.get_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get display info: \")\ndef get_info() -> DisplayInfoResponse\n```\n\nディスプレイ情報を取得します。\n\n**戻り値**:\n\n- `DisplayInfoResponse` - プライマリーディスプレイおよび利用可能なすべてのディスプレイを含む情報。\n  \n\n**例**:\n\n```python\ninfo = sandbox.computer_use.display.get_info()\nprint(f\"Primary display: {info.primary_display.width}x{info.primary_display.height}\")\nprint(f\"Total displays: {info.total_displays}\")\nfor i, display in enumerate(info.displays):\n    print(f\"Display {i}: {display.width}x{display.height} at {display.x},{display.y}\")\n```\n\n#### Display.get_windows\n\n```python\n@intercept_errors(message_prefix=\"Failed to get windows: \")\ndef get_windows() -> WindowsResponse\n```\n\n開いているウィンドウの一覧を取得します。\n\n**戻り値**:\n\n- `WindowsResponse` - ID とタイトルを含む開いているウィンドウの一覧。\n  \n\n**例**:\n\n```python\nwindows = sandbox.computer_use.display.get_windows()\nprint(f\"Found {windows.count} open windows:\")\nfor window in windows.windows:\n    print(f\"- {window.title} (ID: {window.id})\")\n```\n\n## ScreenshotRegion\n\n```python\nclass ScreenshotRegion()\n```\n\nスクリーンショット操作用の領域座標。\n\n**属性**:\n\n- `x` _int_ - 領域のX座標。\n- `y` _int_ - 領域のY座標。\n- `width` _int_ - 領域の幅。\n- `height` _int_ - 領域の高さ。\n\n## ScreenshotOptions\n\n```python\nclass ScreenshotOptions()\n```\n\nスクリーンショットの圧縮および表示に関するオプション。\n\n**属性**:\n\n- `show_cursor` _bool_ - スクリーンショットにカーソルを表示するかどうか。\n- `fmt` _str_ - 画像形式（例：'png'、'jpeg'、'webp'）。\n- `quality` _int_ - 圧縮品質（0〜100）。\n- `scale` _float_ - スクリーンショットのスケール係数。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/daytona.mdx",
    "content": "---\ntitle: \"Daytona\"\nhideTitleOnPage: true\n---\n\n## Daytona\n\n```python\nclass Daytona()\n```\n\nDaytona API と対話するためのメインクラス。\n\nこのクラスは、Daytona サンドボックスの作成・管理・操作のためのメソッドを提供します。\n明示的な設定または環境変数を用いて初期化できます。\n\n**属性**:\n\n- `volume` _VolumeService_ - ボリュームを管理するサービス。\n- `snapshot` _SnapshotService_ - スナップショットを管理するサービス。\n  \n\n**例**:\n\n  環境変数を使用する場合:\n```python\ndaytona = Daytona()  # Uses DAYTONA_API_KEY, DAYTONA_API_URL\nsandbox = daytona.create()\n```\n  \n  明示的な設定を使用する場合:\n```python\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"https://your-api.com\",\n    target=\"us\"\n)\ndaytona = Daytona(config)\nsandbox = daytona.create()\n```\n\n#### Daytona.\\_\\_init\\_\\_\n\n```python\ndef __init__(config: Optional[DaytonaConfig] = None)\n```\n\n任意の設定で Daytona インスタンスを初期化します。\n\n設定が提供されない場合、環境変数から読み込みます:\n- `DAYTONA_API_KEY`: 認証に必要な API キー\n- `DAYTONA_API_URL`: 必須の API URL\n- `DAYTONA_TARGET`: 任意のターゲット環境（既定は 'us'）\n\n**引数**:\n\n- `config` _Optional[DaytonaConfig]_ - api_key、api_url、target を含むオブジェクト。\n  \n\n**送出**:\n\n- `DaytonaError` - 設定または環境変数のいずれからも API キーが提供されていない場合\n  \n\n**例**:\n\n```python\nfrom daytona import Daytona, DaytonaConfig\n# Using environment variables\ndaytona1 = Daytona()\n\n# Using explicit configuration\nconfig = DaytonaConfig(\n    api_key=\"your-api-key\",\n    api_url=\"https://your-api.com\",\n    target=\"us\"\n)\ndaytona2 = Daytona(config)\n\n```\n\n#### Daytona.create\n\n```python\n@overload\ndef create(params: Optional[CreateSandboxFromSnapshotParams] = None,\n           *,\n           timeout: Optional[float] = 60) -> Sandbox\n```\n\n指定された、または既定のスナップショットからサンドボックスを作成します。言語、イメージ、環境変数、ボリュームなど、さまざまなパラメータを指定できます。\n\n**引数**:\n\n- `params` _Optional[CreateSandboxFromSnapshotParams]_ - サンドボックス作成のためのパラメータ。未指定の場合は、\n  既定の Daytona スナップショットと Python 言語が使用されます。\n- `timeout` _Optional[float]_ - サンドボックス作成のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n  既定は 60 秒。\n  \n\n**返り値**:\n\n- `Sandbox` - 作成されたサンドボックスインスタンス。\n  \n\n**送出**:\n\n- `DaytonaError` - timeout、auto_stop_interval、または auto_archive_interval が負の場合、\n  あるいはサンドボックスの起動に失敗した、またはタイムアウトした場合\n  \n\n**例**:\n\n  既定の Python サンドボックスを作成:\n```python\nsandbox = daytona.create()\n```\n  \n  カスタムサンドボックスを作成:\n```python\nparams = CreateSandboxFromSnapshotParams(\n    language=\"python\",\n    snapshot=\"my-snapshot-id\",\n    env_vars={\"DEBUG\": \"true\"},\n    auto_stop_interval=0,\n    auto_archive_interval=60,\n    auto_delete_interval=120\n)\nsandbox = daytona.create(params, timeout=40)\n```\n\n#### Daytona.create\n\n```python\n@overload\ndef create(params: Optional[CreateSandboxFromImageParams] = None,\n           *,\n           timeout: Optional[float] = 60,\n           on_snapshot_create_logs: Callable[[str], None] = None) -> Sandbox\n```\n\nレジストリで利用可能な指定イメージ、または宣言的な Daytona イメージからサンドボックスを作成します。\nリソース、言語、イメージ、環境変数、ボリュームなど、さまざまなパラメータを指定できます。Daytona は提供されたイメージからスナップショットを作成し、それを用いてサンドボックスを作成します。\n\n**引数**:\n\n- `params` _Optional[CreateSandboxFromImageParams]_ - イメージからサンドボックスを作成するためのパラメータ。\n- `timeout` _Optional[float]_ - サンドボックス作成のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n  既定は 60 秒。\n- `on_snapshot_create_logs` _Callable[[str], None]_ - スナップショット作成ログを処理するコールバック関数。\n  \n\n**返り値**:\n\n- `Sandbox` - 作成されたサンドボックスインスタンス。\n  \n\n**送出**:\n\n- `DaytonaError` - timeout、auto_stop_interval、または auto_archive_interval が負の場合、\n  あるいはサンドボックスの起動に失敗した、またはタイムアウトした場合\n  \n\n**例**:\n\n  イメージから既定の Python サンドボックスを作成:\n```python\nsandbox = daytona.create(CreateSandboxFromImageParams(image=\"debian:12.9\"))\n```\n  \n  宣言的なイメージ定義からカスタムサンドボックスを作成:\n```python\ndeclarative_image = (\n    Image.base(\"alpine:3.18\")\n    .pipInstall([\"numpy\", \"pandas\"])\n    .env({\"MY_ENV_VAR\": \"My Environment Variable\"})\n)\nparams = CreateSandboxFromImageParams(\n    language=\"python\",\n    image=declarative_image,\n    env_vars={\"DEBUG\": \"true\"},\n    resources=Resources(cpu=2, memory=4),\n    auto_stop_interval=0,\n    auto_archive_interval=60,\n    auto_delete_interval=120\n)\nsandbox = daytona.create(\n    params,\n    timeout=40,\n    on_snapshot_create_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n#### Daytona.delete\n\n```python\ndef delete(sandbox: Sandbox, timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスを削除します。\n\n**引数**:\n\n- `sandbox` _Sandbox_ - 削除するサンドボックスインスタンス。\n- `timeout` _Optional[float]_ - サンドボックス削除のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n  既定は 60 秒です。\n  \n\n**送出**:\n\n- `DaytonaError` - サンドボックスの削除に失敗した場合、またはタイムアウトした場合\n  \n\n**例**:\n\n```python\nsandbox = daytona.create()\n# ... サンドボックスを利用 ...\ndaytona.delete(sandbox)  # 終了時にクリーンアップ\n```\n\n#### Daytona.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get sandbox: \")\ndef get(sandbox_id: str) -> Sandbox\n```\n\nID でサンドボックスを取得します。\n\n**引数**:\n\n- `sandbox_id` _str_ - 取得するサンドボックスの ID。\n  \n\n**戻り値**:\n\n- `Sandbox` - サンドボックスインスタンス。\n  \n\n**送出**:\n\n- `DaytonaError` - `sandbox_id` が指定されていない場合。\n  \n\n**例**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nprint(sandbox.status)\n```\n\n#### Daytona.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list sandboxes: \")\ndef list(labels: Optional[Dict[str, str]] = None) -> List[Sandbox]\n```\n\nラベルでフィルタリングされたサンドボックスを一覧表示します。\n\n**引数**:\n\n- `labels` _Optional[Dict[str, str]]_ - サンドボックスをフィルタリングするためのラベル。\n  \n\n**戻り値**:\n\n- `List[Sandbox]` - ラベルに一致するサンドボックスインスタンスのリスト。\n  \n\n**例**:\n\n```python\nsandboxes = daytona.list(labels={\"my-label\": \"my-value\"})\nfor sandbox in sandboxes:\n    print(f\"{sandbox.id}: {sandbox.status}\")\n```\n\n#### Daytona.start\n\n```python\ndef start(sandbox: Sandbox, timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスを起動し、準備完了まで待機します。\n\n**引数**:\n\n- `sandbox` _Sandbox_ - 起動するサンドボックス。\n- `timeout` _Optional[float]_ - サンドボックスの起動完了を待つ任意のタイムアウト（秒）。\n  0 はタイムアウトなしを意味します。既定は 60 秒です。\n  \n\n**送出**:\n\n- `DaytonaError` - タイムアウトが負の場合、またはサンドボックスの起動に失敗／タイムアウトした場合\n\n#### Daytona.stop\n\n```python\ndef stop(sandbox: Sandbox, timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスを停止し、停止完了まで待機します。\n\n**引数**:\n\n- `sandbox` _Sandbox_ - 停止するサンドボックス。\n- `timeout` _Optional[float]_ - サンドボックス停止の任意のタイムアウト（秒）。\n  0 はタイムアウトなしを意味します。既定は 60 秒です。\n  \n\n**送出**:\n\n- `DaytonaError` - タイムアウトが負の場合、またはサンドボックスの停止に失敗／タイムアウトした場合\n\n\n## CodeLanguage\n\n```python\n@dataclass\nclass CodeLanguage(Enum)\n```\n\nDaytona がサポートするプログラミング言語\n\n**列挙型メンバー**:\n    - `PYTHON` (\"python\")\n    - `TYPESCRIPT` (\"typescript\")\n    - `JAVASCRIPT` (\"javascript\")\n\n## DaytonaConfig\n\n```python\nclass DaytonaConfig(BaseModel)\n```\n\nDaytona クライアントを初期化するための設定オプション。\n\n**属性**:\n\n- `api_key` _Optional[str]_ - Daytona API で認証するための APIキー。未設定の場合は、環境変数 `DAYTONA_API_KEY` で指定するか、代わりに JWT トークンを指定する必要があります。\n- `jwt_token` _Optional[str]_ - Daytona API で認証するための JWT トークン。未設定の場合は、環境変数 `DAYTONA_JWT_TOKEN` で指定するか、代わりに APIキーを指定する必要があります。\n- `organization_id` _Optional[str]_ - JWT ベース認証で使用される 組織 ID。JWT トークンが指定された場合に必須で、ここで指定するか、環境変数 `DAYTONA_ORGANIZATION_ID` に設定する必要があります。\n- `api_url` _Optional[str]_ - Daytona API の URL。未設定の場合は `'https://app.daytona.io/api'` がデフォルトとなり、ここまたは環境変数 `DAYTONA_API_URL` で設定できます。\n- `server_url` _Optional[str]_ - 非推奨です。代わりに `api_url` を使用してください。このプロパティは将来のバージョンで削除されます。\n- `target` _Optional[str]_ - サンドボックスのターゲット（リージョン）/ランナーの場所。未設定の場合のデフォルトは `'us'` で、ここまたは環境変数 `DAYTONA_TARGET` で設定できます。\n  \n\n**例**:\n\n```python\nconfig = DaytonaConfig(api_key=\"your-api-key\")\n```\n```python\nconfig = DaytonaConfig(jwt_token=\"your-jwt-token\", organization_id=\"your-organization-id\")\n```\n\n## CreateSandboxBaseParams\n\n```python\nclass CreateSandboxBaseParams(BaseModel)\n```\n\n新しいサンドボックスを作成するための基本パラメーター。\n\n**属性**:\n\n- `language` _Optional[CodeLanguage]_ - サンドボックスのプログラミング言語。デフォルトは「python」。\n- `os_user` _Optional[str]_ - サンドボックスのOSユーザー。\n- `env_vars` _Optional[Dict[str, str]]_ - サンドボックスに設定する環境変数。\n- `labels` _Optional[Dict[str, str]]_ - サンドボックスのカスタムラベル。\n- `public` _Optional[bool]_ - サンドボックスを公開にするかどうか。\n- `timeout` _Optional[float]_ - サンドボックスの作成および起動のタイムアウト（秒）。\n- `auto_stop_interval` _Optional[int]_ - 指定した時間内にサンドボックスイベントが発生しなかった場合に自動停止するまでの間隔（分）。デフォルトは15分。\n  0は自動停止なしを意味します。\n- `auto_archive_interval` _Optional[int]_ - 連続して停止しているサンドボックスが自動的にアーカイブされるまでの間隔（分）。デフォルトは7日。\n  0は最大の間隔が使用されることを意味します。\n- `auto_delete_interval` _Optional[int]_ - 連続して停止しているサンドボックスが自動的に削除されるまでの間隔（分）。デフォルトでは自動削除は無効です。\n  負の値は無効、0は停止直後に即時削除を意味します。\n- `volumes` _Optional[List[VolumeMount]]_ - サンドボックスにアタッチするボリュームのマウント一覧。\n- `network_block_all` _Optional[bool]_ - サンドボックスのすべてのネットワークアクセスをブロックするかどうか。\n- `network_allow_list` _Optional[str]_ - サンドボックスで許可するCIDRネットワークアドレスのカンマ区切りリスト。\n\n## CreateSandboxFromImageParams\n\n```python\nclass CreateSandboxFromImageParams(CreateSandboxBaseParams)\n```\n\nイメージから新しいサンドボックスを作成するためのパラメータ。\n\n**属性**:\n\n- `image` _Union[str, Image]_ - サンドボックスに使用するカスタム Docker イメージ。Image オブジェクトが指定された場合は、\n  イメージが動的にビルドされます。\n- `resources` _Optional[Resources]_ - サンドボックスのリソース構成。指定しない場合は、サンドボックスに\n  既定のリソースが割り当てられます。\n\n## CreateSandboxFromSnapshotParams\n\n```python\nclass CreateSandboxFromSnapshotParams(CreateSandboxBaseParams)\n```\n\nスナップショットから新しいサンドボックスを作成するためのパラメータ。\n\n**属性**:\n\n- `snapshot` _Optional[str]_ - サンドボックスに使用するスナップショット名。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/file-system.mdx",
    "content": "---\ntitle: \"ファイルシステム\"\nhideTitleOnPage: true\n---\n\n## FileSystem\n\n```python\nclass FileSystem()\n```\n\nサンドボックス内のファイルシステム操作を提供します。\n\nこのクラスは、Daytona のサンドボックス内で実行できるファイルシステム操作に対する高水準インターフェースを実装します。\n\n#### FileSystem.\\_\\_init\\_\\_\n\n```python\ndef __init__(sandbox_id: str, toolbox_api: ToolboxApi,\n             get_root_dir: Callable[[], str])\n```\n\n新しい FileSystem インスタンスを初期化します。\n\n**引数**:\n\n- `sandbox_id` _str_ - サンドボックス ID。\n- `toolbox_api` _ToolboxApi_ - サンドボックス操作用の API クライアント。\n- `get_root_dir` _Callable[[], str]_ - サンドボックスのデフォルトのルートディレクトリを取得する関数。\n\n#### FileSystem.create\\_folder\n\n```python\n@intercept_errors(message_prefix=\"Failed to create folder: \")\ndef create_folder(path: str, mode: str) -> None\n```\n\n指定したパスに、与えられた権限でサンドボックス内に新しいディレクトリを作成します。\n\n**引数**:\n\n- `path` _str_ - フォルダを作成するパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `mode` _str_ - 8 進数形式のフォルダ権限（例: \"755\" は rwxr-xr-x）。\n  \n\n**例**:\n\n```python\n# 標準的な権限でディレクトリを作成\nsandbox.fs.create_folder(\"workspace/data\", \"755\")\n\n# プライベートディレクトリを作成\nsandbox.fs.create_folder(\"workspace/secrets\", \"700\")\n```\n\n#### FileSystem.delete\\_file\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete file: \")\ndef delete_file(path: str) -> None\n```\n\nサンドボックスからファイルを削除します。\n\n**引数**:\n\n- `path` _str_ - 削除するファイルへの絶対パス。\n  \n\n**例**:\n\n```python\n# ファイルを削除\nsandbox.fs.delete_file(\"workspace/data/old_file.txt\")\n```\n\n#### FileSystem.download\\_file\n\n```python\n@overload\ndef download_file(remote_path: str, timeout: int = 30 * 60) -> bytes\n```\n\nサンドボックスからファイルをダウンロードします。ファイル内容を bytes オブジェクトとして返します。\nディスクに保存せずにファイルをメモリに読み込みたい場合に便利です。\n小さなファイルにのみ使用できます。\n\n**引数**:\n\n- `remote_path` _str_ - サンドボックス内のファイルへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `timeout` _int_ - ダウンロード処理のタイムアウト（秒）。0 はタイムアウトなし。デフォルトは 30 分。\n  \n\n**戻り値**:\n\n- `bytes` - ファイル内容の bytes オブジェクト。\n  \n\n**例**:\n\n```python\n# ダウンロードしてローカルに保存\ncontent = sandbox.fs.download_file(\"workspace/data/file.txt\")\nwith open(\"local_copy.txt\", \"wb\") as f:\n    f.write(content)\n\n# ダウンロードしてテキスト内容を処理\ncontent = sandbox.fs.download_file(\"workspace/data/config.json\")\nconfig = json.loads(content.decode('utf-8'))\n```\n\n#### FileSystem.download\\_file\n\n```python\n@overload\ndef download_file(remote_path: str,\n                  local_path: str,\n                  timeout: int = 30 * 60) -> None\n```\n\nサンドボックスからファイルをダウンロードし、ストリームでローカルファイルに保存します。\nメモリに収まりきらない可能性のある大きなファイルをダウンロードしたい場合に便利です。\n\n**引数**:\n\n- `remote_path` _str_ - サンドボックス内のファイルへのパス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `local_path` _str_ - ローカルにファイルを保存するパス。\n- `timeout` _int_ - ダウンロード処理のタイムアウト（秒）。0 はタイムアウトなし。デフォルトは 30 分。\n  \n\n**例**:\n\n```python\nlocal_path = \"local_copy.txt\"\nsandbox.fs.download_file(\"tmp/large_file.txt\", local_path)\nsize_mb = os.path.getsize(local_path) / 1024 / 1024\nprint(f\"Size of the downloaded file {local_path}: {size_mb} MB\")\n```\n\n#### FileSystem.find\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to find files: \")\ndef find_files(path: str, pattern: str) -> List[Match]\n```\n\nパターンに一致するファイルを検索します。`grep` コマンドに似ています。\n\n**引数**:\n\n- `path` _str_ - 検索対象のファイルまたはディレクトリのパス。パスがディレクトリの場合、\n  検索は再帰的に実行されます。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `pattern` _str_ - ファイル内容に対して照合する検索パターン。\n  \n\n**戻り値**:\n\n- `List[Match]` - ファイル内で見つかった一致のリスト。各 Match オブジェクトには以下が含まれます:\n  - file: 一致が含まれるファイルのパス\n  - line: 一致が見つかった行番号\n  - content: 一致した行の内容\n  \n\n**例**:\n\n```python\n# Search for TODOs in Python files\nmatches = sandbox.fs.find_files(\"workspace/src\", \"TODO:\")\nfor match in matches:\n    print(f\"{match.file}:{match.line}: {match.content.strip()}\")\n```\n\n#### FileSystem.get\\_file\\_info\n\n```python\n@intercept_errors(message_prefix=\"Failed to get file info: \")\ndef get_file_info(path: str) -> FileInfo\n```\n\nファイルまたはディレクトリの詳細情報を取得します。サイズ、パーミッション、タイムスタンプを含みます。\n\n**引数**:\n\n- `path` _str_ - ファイルまたはディレクトリのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `FileInfo` - 次を含む詳細なファイル情報:\n  - name: ファイル名\n  - is_dir: パスがディレクトリかどうか\n  - size: バイト単位のファイルサイズ\n  - mode: ファイルのパーミッション\n  - mod_time: 最終更新タイムスタンプ\n  - permissions: 8 進数表記のファイルパーミッション\n  - owner: ファイル所有者\n  - group: ファイルグループ\n  \n\n**例**:\n\n```python\n# Get file metadata\ninfo = sandbox.fs.get_file_info(\"workspace/data/file.txt\")\nprint(f\"Size: {info.size} bytes\")\nprint(f\"Modified: {info.mod_time}\")\nprint(f\"Mode: {info.mode}\")\n\n# Check if path is a directory\ninfo = sandbox.fs.get_file_info(\"workspace/data\")\nif info.is_dir:\n    print(\"Path is a directory\")\n```\n\n#### FileSystem.list\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to list files: \")\ndef list_files(path: str) -> List[FileInfo]\n```\n\n指定したパス内のファイルとディレクトリを一覧表示し、その情報を返します。`ls -l` コマンドに似ています。\n\n**引数**:\n\n- `path` _str_ - 内容を一覧表示するディレクトリのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `List[FileInfo]` - ファイルおよびディレクトリ情報のリスト。各 FileInfo\n  オブジェクトには get_file_info() と同じフィールドが含まれます。\n  \n\n**例**:\n\n```python\n# List directory contents\nfiles = sandbox.fs.list_files(\"workspace/data\")\n\n# Print files and their sizes\nfor file in files:\n    if not file.is_dir:\n        print(f\"{file.name}: {file.size} bytes\")\n\n# List only directories\ndirs = [f for f in files if f.is_dir]\nprint(\"Subdirectories:\", \", \".join(d.name for d in dirs))\n```\n\n#### FileSystem.move\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to move files: \")\ndef move_files(source: str, destination: str) -> None\n```\n\nファイルまたはディレクトリを移動またはリネームします。宛先の親ディレクトリは存在している必要があります。\n\n**引数**:\n\n- `source` _str_ - 移動元のファイルまたはディレクトリのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `destination` _str_ - 移動先のパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n  \n\n**例**:\n\n```python\n# Rename a file\nsandbox.fs.move_files(\n    \"workspace/data/old_name.txt\",\n    \"workspace/data/new_name.txt\"\n)\n\n# Move a file to a different directory\nsandbox.fs.move_files(\n    \"workspace/data/file.txt\",\n    \"workspace/archive/file.txt\"\n)\n\n# Move a directory\nsandbox.fs.move_files(\n    \"workspace/old_dir\",\n    \"workspace/new_dir\"\n)\n```\n\n#### FileSystem.replace\\_in\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to replace in files: \")\ndef replace_in_files(files: List[str], pattern: str,\n                     new_value: str) -> List[ReplaceResult]\n```\n\n複数ファイルに対して検索と置換を実行します。\n\n**引数**:\n\n- `files` _List[str]_ - 置換を実行するファイルパスのリスト。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `pattern` _str_ - 検索するパターン。\n- `new_value` _str_ - マッチした部分を置き換えるテキスト。\n  \n\n**戻り値**:\n\n- `List[ReplaceResult]` - 各ファイルで行われた置換を示す結果のリスト。各 ReplaceResult には次が含まれます:\n  - file: 変更されたファイルのパス\n  - success: 操作が成功したかどうか\n  - error: 操作が失敗した場合のエラーメッセージ\n  \n\n**例**:\n\n```python\n# 特定のファイルで置換を実行\nresults = sandbox.fs.replace_in_files(\n    files=[\"workspace/src/file1.py\", \"workspace/src/file2.py\"],\n    pattern=\"old_function\",\n    new_value=\"new_function\"\n)\n\n# 結果を出力\nfor result in results:\n    if result.success:\n        print(f\"{result.file}: {result.success}\")\n    else:\n        print(f\"{result.file}: {result.error}\")\n```\n\n#### FileSystem.search\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to search files: \")\ndef search_files(path: str, pattern: str) -> SearchFilesResponse\n```\n\n指定したパターンに一致する名前のファイルやディレクトリを検索します。パターンは単純な文字列またはグロブパターンを指定できます。\n\n**引数**:\n\n- `path` _str_ - 検索を開始するルートディレクトリのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `pattern` _str_ - ファイル名にマッチさせるパターン。グロブ\n  パターン（例: Python ファイルなら \"*.py\"）をサポートします。\n  \n\n**戻り値**:\n\n- `SearchFilesResponse` - 検索結果を含みます:\n  - files: 一致したファイルおよびディレクトリのパスのリスト\n  \n\n**例**:\n\n```python\n# すべての Python ファイルを検索\nresult = sandbox.fs.search_files(\"workspace\", \"*.py\")\nfor file in result.files:\n    print(file)\n\n# 特定のプレフィックスを持つファイルを検索\nresult = sandbox.fs.search_files(\"workspace/data\", \"test_*\")\nprint(f\"Found {len(result.files)} test files\")\n```\n\n#### FileSystem.set\\_file\\_permissions\n\n```python\n@intercept_errors(message_prefix=\"Failed to set file permissions: \")\ndef set_file_permissions(path: str,\n                         mode: str = None,\n                         owner: str = None,\n                         group: str = None) -> None\n```\n\nファイルまたはディレクトリのパーミッションと所有権を設定します。いずれのパラメータも None を指定すると、その属性は変更されません。\n\n**引数**:\n\n- `path` _str_ - ファイルまたはディレクトリのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `mode` _Optional[str]_ - 8 進数形式のファイルモード/パーミッション\n  （例: \"644\" は rw-r--r--）。\n- `owner` _Optional[str]_ - ファイルの所有ユーザー。\n- `group` _Optional[str]_ - ファイルの所有グループ。\n  \n\n**例**:\n\n```python\n# ファイルを実行可能にする\nsandbox.fs.set_file_permissions(\n    path=\"workspace/scripts/run.sh\",\n    mode=\"755\"  # rwxr-xr-x\n)\n\n# ファイルの所有者を変更\nsandbox.fs.set_file_permissions(\n    path=\"workspace/data/file.txt\",\n    owner=\"daytona\",\n    group=\"daytona\"\n)\n```\n\n#### FileSystem.upload\\_file\n\n```python\n@overload\ndef upload_file(file: bytes, remote_path: str, timeout: int = 30 * 60) -> None\n```\n\nサンドボックス内の指定したパスにファイルをアップロードします。宛先に同名のファイルが既に存在する場合は上書きされます。メモリに収まる小さなファイルをアップロードする場合に適しています。\n\n**引数**:\n\n- `file` _bytes_ - バイト列オブジェクトとしてのファイル内容。\n- `remote_path` _str_ - 宛先ファイルのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `timeout` _int_ - アップロード処理のタイムアウト（秒）。0 はタイムアウトなし。デフォルトは 30 分。\n  \n\n**例**:\n\n```python\n# テキストファイルをアップロード\ncontent = b\"Hello, World!\"\nsandbox.fs.upload_file(content, \"tmp/hello.txt\")\n\n# ローカルファイルをアップロード\nwith open(\"local_file.txt\", \"rb\") as f:\n    content = f.read()\nsandbox.fs.upload_file(content, \"tmp/file.txt\")\n\n# バイナリデータをアップロード\nimport json\ndata = {\"key\": \"value\"}\ncontent = json.dumps(data).encode('utf-8')\nsandbox.fs.upload_file(content, \"tmp/config.json\")\n```\n\n#### FileSystem.upload\\_file\n\n```python\n@overload\ndef upload_file(local_path: str,\n                remote_path: str,\n                timeout: int = 30 * 60) -> None\n```\n\nローカルファイルシステムからサンドボックス内の指定パスにファイルをアップロードします。\n宛先パスにすでにファイルが存在する場合は上書きされます。このメソッドは\nストリーミングでファイルをアップロードするため、メモリに収まりきらない大きなファイルの\nアップロードに適しています。\n\n**引数**:\n\n- `local_path` _str_ - アップロードするローカルファイルのパス。\n- `remote_path` _str_ - サンドボックス内の宛先ファイルのパス。相対パスは\n  ユーザーのルートディレクトリを基準に解決されます。\n- `timeout` _int_ - アップロード処理のタイムアウト（秒）。0 はタイムアウトなし。既定は 30 分。\n  \n\n**例**:\n\n```python\nsandbox.fs.upload_file(\"local_file.txt\", \"tmp/large_file.txt\")\n```\n\n#### FileSystem.upload\\_files\n\n```python\n@intercept_errors(message_prefix=\"Failed to upload files: \")\ndef upload_files(files: List[FileUpload], timeout: int = 30 * 60) -> None\n```\n\n複数のファイルをサンドボックスにアップロードします。宛先パスにすでにファイルが存在する場合は\n上書きされます。\n\n**引数**:\n\n- `files` _List[FileUpload]_ - アップロードするファイルのリスト。\n- `timeout` _int_ - アップロード処理のタイムアウト（秒）。0 はタイムアウトなし。既定は 30 分。\n\n**例**:\n\n```python\n# 複数のテキストファイルをアップロード\nfiles = [\n    FileUpload(\n        source=b\"Content of file 1\",\n        destination=\"/tmp/file1.txt\"\n    ),\n    FileUpload(\n        source=\"workspace/data/file2.txt\",\n        destination=\"/tmp/file2.txt\"\n    ),\n    FileUpload(\n        source=b'{\"key\": \"value\"}',\n        destination=\"/tmp/config.json\"\n    )\n]\nsandbox.fs.upload_files(files)\n```\n\n\n## FileUpload\n\n```python\n@dataclass\nclass FileUpload()\n```\n\nサンドボックスにアップロードするファイルを表します。\n\n**属性**:\n\n- `source` _Union[bytes, str]_ - ファイル内容。バイト列オブジェクト、またはローカルファイルパスを指定できます。バイト列を指定する場合は、メモリに収まるサイズであることを確認してください。そうでない場合は、内容がサンドボックスへストリーミングされるローカルファイルパスを使用してください。\n- `destination` _str_ - サンドボックス内の保存先の絶対パス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/git.mdx",
    "content": "---\ntitle: \"Git\"\nhideTitleOnPage: true\n---\n\n## Git\n\n```python\nclass Git()\n```\n\nサンドボックス内での Git 操作を提供します。\n\n**例**:\n\n```python\n# リポジトリをクローン\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# リポジトリのステータスを確認\nstatus = sandbox.git.status(\"workspace/repo\")\nprint(f\"Modified files: {status.modified}\")\n\n# 変更をステージしてコミット\nsandbox.git.add(\"workspace/repo\", [\"file.txt\"])\nsandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update file\",\n    author=\"John Doe\",\n    email=\"john@example.com\"\n)\n```\n\n#### Git.__init__\n\n```python\ndef __init__(sandbox_id: str, toolbox_api: ToolboxApi,\n             get_root_dir: Callable[[], str])\n```\n\n新しい Git ハンドラーのインスタンスを初期化します。\n\n**引数**:\n\n- `sandbox_id` _str_ - サンドボックス ID。\n- `toolbox_api` _ToolboxApi_ - サンドボックス操作用の API クライアント。\n- `get_root_dir` _Callable[[], str]_ - サンドボックスのデフォルトのルートディレクトリを取得する関数。\n\n#### Git.add\n\n```python\n@intercept_errors(message_prefix=\"Failed to add files: \")\ndef add(path: str, files: List[str]) -> None\n```\n\n指定したファイルを次回のコミットに向けてステージします。コマンドラインで\n`git add` を実行するのと同様です。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `files` _List[str]_ - ステージするファイルまたはディレクトリのリスト。リポジトリルートからの相対パス。\n  \n\n**例**:\n\n```python\n# 単一ファイルをステージ\nsandbox.git.add(\"workspace/repo\", [\"file.txt\"])\n\n# 複数ファイルをステージ\nsandbox.git.add(\"workspace/repo\", [\n    \"src/main.py\",\n    \"tests/test_main.py\",\n    \"README.md\"\n])\n```\n\n#### Git.branches\n\n```python\n@intercept_errors(message_prefix=\"Failed to list branches: \")\ndef branches(path: str) -> ListBranchResponse\n```\n\nリポジトリ内のブランチを一覧表示します。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `ListBranchResponse` - リポジトリ内のブランチ一覧。\n  \n\n**例**:\n\n```python\nresponse = sandbox.git.branches(\"workspace/repo\")\nprint(f\"Branches: {response.branches}\")\n```\n\n#### Git.clone\n\n```python\n@intercept_errors(message_prefix=\"Failed to clone repository: \")\ndef clone(url: str,\n          path: str,\n          branch: Optional[str] = None,\n          commit_id: Optional[str] = None,\n          username: Optional[str] = None,\n          password: Optional[str] = None) -> None\n```\n\n指定したパスに Git リポジトリをクローンします。特定のブランチやコミットの\nクローンに対応し、認証情報が提供された場合はリモートリポジトリへの\n認証も可能です。\n\n**引数**:\n\n- `url` _str_ - クローン元のリポジトリ URL。\n- `path` _str_ - リポジトリをクローンするパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `branch` _Optional[str]_ - クローンするブランチ。未指定の場合は\n  デフォルトブランチをクローンします。\n- `commit_id` _Optional[str]_ - チェックアウトする特定のコミット。指定した場合、\n  リポジトリはこのコミットで detached HEAD 状態になります。\n- `username` _Optional[str]_ - 認証用の Git ユーザー名。\n- `password` _Optional[str]_ - 認証用の Git パスワードまたはトークン。\n  \n\n**例**:\n\n```python\n# デフォルトブランチをクローン\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo\"\n)\n\n# 認証付きで特定のブランチをクローン\nsandbox.git.clone(\n    url=\"https://github.com/user/private-repo.git\",\n    path=\"workspace/private\",\n    branch=\"develop\",\n    username=\"user\",\n    password=\"token\"\n)\n\n# 特定のコミットをクローン\nsandbox.git.clone(\n    url=\"https://github.com/user/repo.git\",\n    path=\"workspace/repo-old\",\n    commit_id=\"abc123\"\n)\n```\n\n#### Git.commit\n\n```python\n@intercept_errors(message_prefix=\"Failed to commit changes: \")\ndef commit(path: str,\n           message: str,\n           author: str,\n           email: str,\n           allow_empty: bool = False) -> GitCommitResponse\n```\n\nステージ済みの変更で新しいコミットを作成します。コミットする前に必ず add() メソッドで\n変更をステージしてください。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `message` _str_ - 変更内容を説明するコミットメッセージ。\n- `author` _str_ - コミット作者の名前。\n- `email` _str_ - コミット作者のメールアドレス。\n- `allow_empty` _bool, optional_ - 変更がステージされていない場合でも空のコミットを作成できるようにします。デフォルトは False。\n  \n\n**例**:\n\n```python\n# 変更をステージしてコミットする\nsandbox.git.add(\"workspace/repo\", [\"README.md\"])\nsandbox.git.commit(\n    path=\"workspace/repo\",\n    message=\"Update documentation\",\n    author=\"John Doe\",\n    email=\"john@example.com\",\n    allow_empty=True\n)\n```\n\n#### Git.push\n\n```python\n@intercept_errors(message_prefix=\"Failed to push changes: \")\ndef push(path: str,\n         username: Optional[str] = None,\n         password: Optional[str] = None) -> None\n```\n\n現在のブランチのすべてのローカルコミットをリモート\nリポジトリにプッシュします。リモートリポジトリが認証を要求する場合は、\nusername と password/token を指定してください。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `username` _Optional[str]_ - 認証用の Git ユーザー名。\n- `password` _Optional[str]_ - 認証用の Git パスワードまたはトークン。\n  \n\n**例**:\n\n```python\n# 認証なしでプッシュ（公開リポジトリや SSH の場合）\nsandbox.git.push(\"workspace/repo\")\n\n# 認証ありでプッシュ\nsandbox.git.push(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n#### Git.pull\n\n```python\n@intercept_errors(message_prefix=\"Failed to pull changes: \")\ndef pull(path: str,\n         username: Optional[str] = None,\n         password: Optional[str] = None) -> None\n```\n\nリモートリポジトリから変更をプルします。リモートリポジトリが認証を要求する場合は、\nusername と password/token を指定してください。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `username` _Optional[str]_ - 認証用の Git ユーザー名。\n- `password` _Optional[str]_ - 認証用の Git パスワードまたはトークン。\n  \n\n**例**:\n\n```python\n# 認証なしでプル\nsandbox.git.pull(\"workspace/repo\")\n\n# 認証ありでプル\nsandbox.git.pull(\n    path=\"workspace/repo\",\n    username=\"user\",\n    password=\"github_token\"\n)\n```\n\n#### Git.status\n\n```python\n@intercept_errors(message_prefix=\"Failed to get status: \")\ndef status(path: str) -> GitStatus\n```\n\n現在の Git リポジトリのステータスを取得します。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `GitStatus` - リポジトリのステータス情報（以下を含む）:\n  - current_branch: 現在のブランチ名\n  - file_status: ファイルの状態のリスト\n  - ahead: リモートに未プッシュのローカルコミット数\n  - behind: ローカルに未プルのリモートコミット数\n  - branch_published: ブランチがリモートリポジトリに公開済みかどうか\n  \n\n**例**:\n\n```python\nstatus = sandbox.git.status(\"workspace/repo\")\nprint(f\"On branch: {status.current_branch}\")\nprint(f\"Commits ahead: {status.ahead}\")\nprint(f\"Commits behind: {status.behind}\")\n```\n\n#### Git.checkout\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to checkout branch: \")\ndef checkout_branch(path: str, branch: str) -> None\n```\n\nリポジトリでブランチをチェックアウトします。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `branch` _str_ - チェックアウトするブランチ名\n  \n\n**例**:\n\n```python\n# ブランチをチェックアウト\nsandbox.git.checkout_branch(\"workspace/repo\", \"feature-branch\")\n```\n\n#### Git.create\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to create branch: \")\ndef create_branch(path: str, name: str) -> None\n```\n\nリポジトリでブランチを作成します。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `name` _str_ - 作成する新しいブランチ名\n  \n\n**例**:\n\n```python\n# 新しいブランチを作成\nsandbox.git.create_branch(\"workspace/repo\", \"new-feature\")\n```\n\n#### Git.delete\\_branch\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete branch: \")\ndef delete_branch(path: str, name: str) -> None\n```\n\nリポジトリ内のブランチを削除します。\n\n**引数**:\n\n- `path` _str_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n- `name` _str_ - 削除するブランチ名\n  \n\n**例**:\n\n```python\n# ブランチを削除する\nsandbox.git.delete_branch(\"workspace/repo\", \"old-feature\")\n```\n\n\n## GitCommitResponse\n\n```python\nclass GitCommitResponse()\n```\n\nGit の commit に対するレスポンス。\n\n**属性**:\n\n- `sha` _str_ - コミットの SHA\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/lsp-server.mdx",
    "content": "---\ntitle: \"LSPサーバー\"\nhideTitleOnPage: true\n---\n\n## LspServer\n\n```python\nclass LspServer()\n```\n\nコードインテリジェンスのための Language Server Protocol 機能を提供し、コード補完やシンボル検索などの IDE 風の機能を実現します。\n\n#### LspServer.__init__\n\n```python\ndef __init__(language_id: LspLanguageId, path_to_project: str,\n             toolbox_api: ToolboxApi, sandbox_id: str)\n```\n\n新しい LSP サーバーインスタンスを初期化します。\n\n**引数**:\n\n- `language_id` _LspLanguageId_ - 言語サーバーの種類（例: LspLanguageId.TYPESCRIPT）。\n- `path_to_project` _str_ - プロジェクトのルートディレクトリへの絶対パス。\n- `toolbox_api` _ToolboxApi_ - サンドボックス操作用の API クライアント。\n- `instance` _SandboxInstance_ - このサーバーが属するサンドボックスインスタンス。\n\n#### LspServer.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start LSP server: \")\ndef start() -> None\n```\n\n言語サーバーを起動します。\n\nこのメソッドは他の LSP 機能を使用する前に呼び出す必要があります。指定された言語とプロジェクトに対して言語サーバーを初期化します。\n\n**例**:\n\n```python\nlsp = sandbox.create_lsp_server(\"typescript\", \"workspace/project\")\nlsp.start()  # Initialize the server\n# Now ready for LSP operations\n```\n\n#### LspServer.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop LSP server: \")\ndef stop() -> None\n```\n\n言語サーバーを停止します。\n\nこのメソッドは LSP サーバーが不要になったときに呼び出して、システムリソースを解放します。\n\n**例**:\n\n```python\n# When done with LSP features\nlsp.stop()  # Clean up resources\n```\n\n#### LspServer.did_open\n\n```python\n@intercept_errors(message_prefix=\"Failed to open file: \")\ndef did_open(path: str) -> None\n```\n\nファイルが開かれたことを言語サーバーに通知します。\n\nエディタでファイルを開いたときにこのメソッドを呼び出すと、そのファイルに対する診断や補完などの言語機能が有効になります。サーバーはファイル内容の追跡を開始し、言語機能を提供します。\n\n**引数**:\n\n- `path` _str_ - 開いたファイルへのパス。相対パスは LSP サーバーのコンストラクタで設定されたプロジェクトパスに基づいて解決されます。\n  \n\n**例**:\n\n```python\n# When opening a file for editing\nlsp.did_open(\"workspace/project/src/index.ts\")\n# Now can get completions, symbols, etc. for this file\n```\n\n#### LspServer.did_close\n\n```python\n@intercept_errors(message_prefix=\"Failed to close file: \")\ndef did_close(path: str) -> None\n```\n\nファイルが閉じられたことを言語サーバーに通知します。\n\nエディタでファイルを閉じたときにこのメソッドを呼び出すことで、そのファイルに関連するリソースを言語サーバーがクリーンアップできます。\n\n**引数**:\n\n- `path` _str_ - 閉じたファイルへのパス。相対パスは LSP サーバーのコンストラクタで設定されたプロジェクトパスに基づいて解決されます。\n  \n\n**例**:\n\n```python\n# When done editing a file\nlsp.did_close(\"workspace/project/src/index.ts\")\n```\n\n#### LspServer.document_symbols\n\n```python\n@intercept_errors(message_prefix=\"Failed to get symbols from document: \")\ndef document_symbols(path: str) -> List[LspSymbol]\n```\n\nドキュメントからシンボル情報（関数、クラス、変数など）を取得します。\n\n**引数**:\n\n- `path` _str_ - シンボルを取得するファイルへのパス。相対パスは LSP サーバーのコンストラクタで設定されたプロジェクトパスに基づいて解決されます。\n  \n\n**戻り値**:\n\n- `List[LspSymbol]` - ドキュメント内のシンボル一覧。各シンボルには以下が含まれます:\n  - name: シンボル名\n  - kind: シンボルの種類（function、class、variable など）\n  - location: ファイル内でのシンボルの位置\n  \n\n**例**:\n\n```python\n# Get all symbols in a file\nsymbols = lsp.document_symbols(\"workspace/project/src/index.ts\")\nfor symbol in symbols:\n    print(f\"{symbol.kind} {symbol.name}: {symbol.location}\")\n```\n\n#### LspServer.workspace_symbols\n\n```python\n@deprecated(\n    reason=\n    \"Method is deprecated. Use `sandbox_symbols` instead. This method will be removed in a future version.\"\n)\ndef workspace_symbols(query: str) -> List[LspSymbol]\n```\n\nクエリ文字列に一致するシンボルをサンドボックス内の全ファイルから検索します。\n\n**引数**:\n\n- `query` _str_ - シンボル名に照合する検索クエリ。\n  \n\n**戻り値**:\n\n- `List[LspSymbol]` - すべてのファイルからの一致シンボルの一覧。\n\n#### LspServer.sandbox_symbols\n\n```python\n@intercept_errors(message_prefix=\"Failed to get symbols from sandbox: \")\ndef sandbox_symbols(query: str) -> List[LspSymbol]\n```\n\nクエリ文字列に一致するシンボルを、サンドボックス内のすべてのファイルから検索します。\n\n**引数**:\n\n- `query` _str_ - シンボル名に対して照合する検索クエリ。\n  \n\n**返り値**:\n\n- `List[LspSymbol]` - すべてのファイルから一致したシンボルの一覧。各シンボルには次が含まれます:\n  - name: シンボル名\n  - kind: シンボルの種別（function、class、variable など）\n  - location: ファイル内でのシンボル位置\n  \n\n**例**:\n\n```python\n# 「User」を含むすべてのシンボルを検索\nsymbols = lsp.sandbox_symbols(\"User\")\nfor symbol in symbols:\n    print(f\"{symbol.name} in {symbol.location}\")\n```\n\n#### LspServer.completions\n\n```python\n@intercept_errors(message_prefix=\"Failed to get completions: \")\ndef completions(path: str, position: Position) -> CompletionList\n```\n\nファイル内の指定位置で補完候補を取得します。\n\n**引数**:\n\n- `path` _str_ - ファイルパス。相対パスは、LSP サーバーのコンストラクターで設定したプロジェクトパスを基準に解決されます。\n- `position` _Position_ - 補完を取得するカーソル位置。\n  \n\n**返り値**:\n\n- `CompletionList` - 補完候補の一覧。以下を含みます:\n  - isIncomplete: さらに項目が利用可能な可能性があるか\n  - items: 補完項目のリスト。各項目には次が含まれます:\n  - label: 挿入するテキスト\n  - kind: 補完の種別\n  - detail: 項目に関する追加情報\n  - documentation: 項目のドキュメント\n  - sortText: 一覧でのソートに使うテキスト\n  - filterText: フィルターに使うテキスト\n  - insertText: 実際に挿入するテキスト（label と異なる場合）\n  \n\n**例**:\n\n```python\n# 特定の位置で補完候補を取得\npos = Position(line=10, character=15)\ncompletions = lsp.completions(\"workspace/project/src/index.ts\", pos)\nfor item in completions.items:\n    print(f\"{item.label} ({item.kind}): {item.detail}\")\n```\n\n\n## LspLanguageId\n\n```python\nclass LspLanguageId(Enum)\n```\n\nLSP（言語サーバープロトコル）で使用する言語ID。\n\n**列挙メンバー**:\n    - `PYTHON` (\"python\")\n    - `TYPESCRIPT` (\"typescript\")\n    - `JAVASCRIPT` (\"javascript\")\n\n## Position\n\n```python\nclass Position()\n```\n\nテキストドキュメント内のゼロ基準の位置を表し、行番号と文字オフセットで指定します。\n\n**属性**:\n\n- `line` _int_ - ドキュメント内のゼロ基準の行番号。\n- `character` _int_ - 行内のゼロ基準の文字オフセット。\n\n#### Position.\\_\\_init\\_\\_\n\n```python\ndef __init__(line: int, character: int)\n```\n\n新しい Position インスタンスを初期化します。\n\n**引数**:\n\n- `line` _int_ - ドキュメント内のゼロ基準の行番号。\n- `character` _int_ - 行内のゼロ基準の文字オフセット。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/object-storage.mdx",
    "content": "---\ntitle: \"オブジェクトストレージ\"\nhideTitleOnPage: true\n---\n\n## ObjectStorage\n\n```python\nclass ObjectStorage()\n```\n\nオブジェクトストレージサービスと連携するための ObjectStorage クラス。\n\n**属性**:\n\n- `endpoint_url` _str_ - オブジェクトストレージサービスのエンドポイントURL。\n- `aws_access_key_id` _str_ - オブジェクトストレージサービスのアクセスキーID。\n- `aws_secret_access_key` _str_ - オブジェクトストレージサービスのシークレットアクセスキー。\n- `aws_session_token` _str_ - オブジェクトストレージサービスのセッショントークン。短期認証情報に使用。\n- `bucket_name` _str_ - 使用するバケット名。既定値は \"daytona-volume-builds\"。\n\n#### ObjectStorage.upload\n\n```python\ndef upload(path: str,\n           organization_id: str,\n           archive_base_path: str | None = None) -> str\n```\n\nファイルをオブジェクトストレージサービスにアップロードします。\n\n**引数**:\n\n- `path` _str_ - アップロードするファイルのパス。\n- `organization_id` _str_ - 使用する組織ID。\n- `archive_base_path` _str_ - アーカイブのベースパス。\n  \n\n**戻り値**:\n\n- `str` - アップロードしたファイルのハッシュ。\n\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/process.mdx",
    "content": "---\ntitle: \"プロセス\"\nhideTitleOnPage: true\n---\n\n## プロセス\n\n```python\nclass Process()\n```\n\nサンドボックス内でのプロセスおよびコード実行を扱います。\n\n#### Process.\\_\\_init\\_\\_\n\n```python\ndef __init__(sandbox_id: str, code_toolbox: SandboxPythonCodeToolbox,\n             toolbox_api: ToolboxApi, get_root_dir: Callable[[], str])\n```\n\n新しい Process インスタンスを初期化します。\n\n**引数**:\n\n- `sandbox_id` _str_ - サンドボックスの ID。\n- `code_toolbox` _SandboxPythonCodeToolbox_ - 言語固有のコード実行ツールボックス。\n- `toolbox_api` _ToolboxApi_ - サンドボックス操作用の API クライアント。\n- `get_root_dir` _Callable[[], str]_ - サンドボックスの既定のルートディレクトリを取得する関数。\n\n#### Process.exec\n\n```python\n@intercept_errors(message_prefix=\"Failed to execute command: \")\ndef exec(command: str,\n         cwd: Optional[str] = None,\n         env: Optional[Dict[str, str]] = None,\n         timeout: Optional[int] = None) -> ExecuteResponse\n```\n\nサンドボックスでシェルコマンドを実行します。\n\n**引数**:\n\n- `command` _str_ - 実行するシェルコマンド。\n- `cwd` _Optional[str]_ - コマンド実行時の作業ディレクトリ。指定しない場合はサンドボックスのルートディレクトリを使用します。既定はユーザーのルートディレクトリです。\n- `env` _Optional[Dict[str, str]]_ - コマンドに設定する環境変数。\n- `timeout` _Optional[int]_ - コマンドの完了を待機する最大時間（秒）。0 は無期限待機を意味します。\n  \n\n**戻り値**:\n\n- `ExecuteResponse` - コマンド実行結果を含みます:\n  - exit_code: コマンドの終了ステータス\n  - result: コマンドの標準出力\n  - artifacts: `stdout`（result と同じ）および `charts`（matplotlib のチャートのメタデータ）を含む ExecutionArtifacts オブジェクト\n  \n\n**例**:\n\n```python\n# シンプルなコマンド\nresponse = sandbox.process.exec(\"echo 'Hello'\")\nprint(response.artifacts.stdout)  # 出力: Hello\n\n# 作業ディレクトリを指定したコマンド\nresult = sandbox.process.exec(\"ls\", cwd=\"workspace/src\")\n\n# タイムアウト付きのコマンド\nresult = sandbox.process.exec(\"sleep 10\", timeout=5)\n```\n\n#### Process.code\\_run\n\n```python\ndef code_run(code: str,\n             params: Optional[CodeRunParams] = None,\n             timeout: Optional[int] = None) -> ExecuteResponse\n```\n\n適切な言語ランタイムを用いてサンドボックスでコードを実行します。\n\n**引数**:\n\n- `code` _str_ - 実行するコード。\n- `params` _Optional[CodeRunParams]_ - コード実行のパラメータ。\n- `timeout` _Optional[int]_ - コードの完了を待機する最大時間（秒）。0 は無期限待機を意味します。\n  \n\n**戻り値**:\n\n- `ExecuteResponse` - コード実行結果を含みます:\n  - exit_code: 実行の終了ステータス\n  - result: コードの標準出力\n  - artifacts: `stdout`（result と同じ）および `charts`（matplotlib のチャートのメタデータ）を含む ExecutionArtifacts オブジェクト\n  \n\n**例**:\n\n```python\n# Python コードを実行\nresponse = sandbox.process.code_run('''\n    x = 10\n    y = 20\n    print(f\"Sum: {x + y}\")\n''')\nprint(response.artifacts.stdout)  # 出力: Sum: 30\n```\n  \n  Matplotlib のチャートは自動検出され、`ExecutionArtifacts` オブジェクトの `charts` フィールドで返されます。\n```python\ncode = '''\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nx = np.linspace(0, 10, 30)\ny = np.sin(x)\n\nplt.figure(figsize=(8, 5))\nplt.plot(x, y, 'b-', linewidth=2)\nplt.title('Line Chart')\nplt.xlabel('X-axis (seconds)')\nplt.ylabel('Y-axis (amplitude)')\nplt.grid(True)\nplt.show()\n'''\n\nresponse = sandbox.process.code_run(code)\nchart = response.artifacts.charts[0]\n\nprint(f\"Type: {chart.type}\")\nprint(f\"Title: {chart.title}\")\nif chart.type == ChartType.LINE and isinstance(chart, LineChart):\n    print(f\"X Label: {chart.x_label}\")\n    print(f\"Y Label: {chart.y_label}\")\n    print(f\"X Ticks: {chart.x_ticks}\")\n    print(f\"X Tick Labels: {chart.x_tick_labels}\")\n    print(f\"X Scale: {chart.x_scale}\")\n    print(f\"Y Ticks: {chart.y_ticks}\")\n    print(f\"Y Tick Labels: {chart.y_tick_labels}\")\n    print(f\"Y Scale: {chart.y_scale}\")\n    print(\"Elements:\")\n    for element in chart.elements:\n        print(f\"Label: {element.label}\")\n        print(f\"Points: {element.points}\")\n```\n\n#### Process.create\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to create session: \")\ndef create_session(session_id: str) -> None\n```\n\nサンドボックスに新しい常駐型のバックグラウンドセッションを作成します。\n\nセッションはバックグラウンドプロセスで、コマンド間の状態を維持します。関連する複数のコマンド実行や環境の恒常的なセットアップが必要なシナリオに最適です。長時間実行のコマンドを走らせ、プロセスの状態を監視できます。\n\n**引数**:\n\n- `session_id` _str_ - 新規セッションの一意な識別子。\n  \n\n**例**:\n\n```python\n# Create a new session\nsession_id = \"my-session\"\nsandbox.process.create_session(session_id)\nsession = sandbox.process.get_session(session_id)\n# Do work...\nsandbox.process.delete_session(session_id)\n```\n\n#### Process.get\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session: \")\ndef get_session(session_id: str) -> Session\n```\n\nサンドボックス内のセッションを取得します。\n\n**引数**:\n\n- `session_id` _str_ - 取得するセッションの一意な識別子。\n  \n\n**戻り値**:\n\n- `Session` - 次の情報を含むセッション情報:\n  - session_id: セッションの一意な識別子\n  - commands: セッションで実行されたコマンドの一覧\n  \n\n**例**:\n\n```python\nsession = sandbox.process.get_session(\"my-session\")\nfor cmd in session.commands:\n    print(f\"Command: {cmd.command}\")\n```\n\n#### Process.get\\_session\\_command\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command: \")\ndef get_session_command(session_id: str, command_id: str) -> Command\n```\n\nセッション内で実行された特定のコマンドに関する情報を取得します。\n\n**引数**:\n\n- `session_id` _str_ - セッションの一意な識別子。\n- `command_id` _str_ - コマンドの一意な識別子。\n  \n\n**戻り値**:\n\n- `Command` - 次の情報を含むコマンド情報:\n  - id: コマンドの一意な識別子\n  - command: 実行されたコマンド文字列\n  - exit_code: 終了ステータス（完了している場合）\n  \n\n**例**:\n\n```python\ncmd = sandbox.process.get_session_command(\"my-session\", \"cmd-123\")\nif cmd.exit_code == 0:\n    print(f\"Command {cmd.command} completed successfully\")\n```\n\n#### Process.execute\\_session\\_command\n\n```python\n@intercept_errors(message_prefix=\"Failed to execute session command: \")\ndef execute_session_command(\n        session_id: str,\n        req: SessionExecuteRequest,\n        timeout: Optional[int] = None) -> SessionExecuteResponse\n```\n\nセッション内でコマンドを実行します。\n\n**引数**:\n\n- `session_id` _str_ - 使用するセッションの一意な識別子。\n- `req` _SessionExecuteRequest_ - 次を含むコマンド実行リクエスト:\n  - command: 実行するコマンド\n  - run_async: 非同期で実行するかどうか\n  \n\n**戻り値**:\n\n- `SessionExecuteResponse` - 次を含むコマンド実行結果:\n  - cmd_id: 実行されたコマンドの一意な識別子\n  - output: コマンドの出力（同期実行の場合）\n  - exit_code: 終了ステータス（同期実行の場合）\n  \n\n**例**:\n\n```python\n# Execute commands in sequence, maintaining state\nsession_id = \"my-session\"\n\n# Change directory\nreq = SessionExecuteRequest(command=\"cd /workspace\")\nsandbox.process.execute_session_command(session_id, req)\n\n# Create a file\nreq = SessionExecuteRequest(command=\"echo 'Hello' > test.txt\")\nsandbox.process.execute_session_command(session_id, req)\n\n# Read the file\nreq = SessionExecuteRequest(command=\"cat test.txt\")\nresult = sandbox.process.execute_session_command(session_id, req)\nprint(result.output)  # Prints: Hello\n```\n\n#### Process.get\\_session\\_command\\_logs\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command logs: \")\ndef get_session_command_logs(session_id: str, command_id: str) -> str\n```\n\nセッションで実行したコマンドのログを取得します。セッション内で実行したコマンドの出力（stdout と stderr）を完全に取得します。\n\n**引数**:\n\n- `session_id` _str_ - セッションの一意な識別子。\n- `command_id` _str_ - コマンドの一意な識別子。\n  \n\n**戻り値**:\n\n- `str` - stdout と stderr の両方を含む完全なコマンド出力。\n  \n\n**例**:\n\n```python\nlogs = sandbox.process.get_session_command_logs(\n    \"my-session\",\n    \"cmd-123\"\n)\nprint(f\"Command output: {logs}\")\n```\n\n#### Process.get\\_session\\_command\\_logs\\_async\n\n```python\n@intercept_errors(message_prefix=\"Failed to get session command logs: \")\nasync def get_session_command_logs_async(\n        session_id: str, command_id: str, on_logs: Callable[[str],\n                                                            None]) -> None\n```\n\nセッションで実行されたコマンドのログを、利用可能になり次第、非同期で取得して処理します。\n\n**引数**:\n\n- `session_id` _str_ - セッションの一意の識別子。\n- `command_id` _str_ - コマンドの一意の識別子。\n- `on_logs` _Callable[[str], None]_ - 受信したログチャンクを処理するコールバック関数。\n  \n\n**例**:\n\n```python\nawait sandbox.process.get_session_command_logs_async(\n    \"my-session\",\n    \"cmd-123\",\n    lambda chunk: print(f\"Log chunk: {chunk}\")\n)\n```\n\n#### Process.list\\_sessions\n\n```python\n@intercept_errors(message_prefix=\"Failed to list sessions: \")\ndef list_sessions() -> List[Session]\n```\n\nサンドボックス内のすべてのセッションを一覧表示します。\n\n**戻り値**:\n\n- `List[Session]` - サンドボックス内のすべてのセッションのリスト。\n  \n\n**例**:\n\n```python\nsessions = sandbox.process.list_sessions()\nfor session in sessions:\n    print(f\"Session {session.session_id}:\")\n    print(f\"  Commands: {len(session.commands)}\")\n```\n\n#### Process.delete\\_session\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete session: \")\ndef delete_session(session_id: str) -> None\n```\n\nサンドボックス内のセッションを終了して削除し、関連リソースをクリーンアップします。\n\n**引数**:\n\n- `session_id` _str_ - 削除するセッションの一意の識別子。\n  \n\n**例**:\n\n```python\n# Create and use a session\nsandbox.process.create_session(\"temp-session\")\n# ... use the session ...\n\n# Clean up when done\nsandbox.process.delete_session(\"temp-session\")\n```\n\n\n## CodeRunParams\n\n```python\n@dataclass\nclass CodeRunParams()\n```\n\nコード実行用のパラメータ。\n\n**属性**:\n\n- `argv` _Optional[List[str]]_ - コマンドライン引数\n- `env` _Optional[Dict[str, str]]_ - 環境変数\n\n## SessionExecuteRequest\n\n```python\nclass SessionExecuteRequest(ApiSessionExecuteRequest,\n                            AsyncApiSessionExecuteRequest)\n```\n\nセッションでコマンドを実行するためのリクエストです。\n\n**属性**:\n\n- `command` _str_ - 実行するコマンド。\n- `run_async` _Optional[bool]_ - コマンドを非同期で実行するかどうか。\n- `var_async` _Optional[bool]_ - 非推奨。代わりに `run_async` を使用してください。\n\n## 実行成果物\n\n```python\nclass ExecutionArtifacts()\n```\n\nコマンド実行で得られる成果物。\n\n**属性**:\n\n- `stdout` _str_ - コマンドの標準出力。`ExecuteResponse` の `result` と同一\n- `charts` _Optional[List[Chart]]_ - matplotlib のチャートメタデータのリスト\n\n## ExecuteResponse\n\n```python\nclass ExecuteResponse(ClientExecuteResponse)\n```\n\nコマンド実行のレスポンス。\n\n**属性**:\n\n- `exit_code` _int_ - コマンド実行の終了コード\n- `result` _str_ - コマンド実行の出力\n- `artifacts` _Optional[ExecutionArtifacts]_ - コマンド実行の実行成果物\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/sandbox.mdx",
    "content": "---\ntitle: \"サンドボックス\"\nhideTitleOnPage: true\n---\n\n## サンドボックス\n\n```python\nclass Sandbox(SandboxDto)\n```\n\nDaytona のサンドボックスを表します。\n\n**属性**:\n\n- `fs` _FileSystem_ - ファイルシステム操作インターフェース。\n- `git` _Git_ - Git 操作インターフェース。\n- `process` _Process_ - プロセス実行インターフェース。\n- `computer_use` _ComputerUse_ - デスクトップ自動化のためのコンピューター使用インターフェース。\n- `id` _str_ - サンドボックスの一意の識別子。\n- `organization_id` _str_ - サンドボックスの組織 ID。\n- `snapshot` _str_ - サンドボックスの作成に使用された Daytona のスナップショット。\n- `user` _str_ - サンドボックス内で稼働する OS ユーザー。\n- `env` _Dict[str, str]_ - サンドボックスで設定される環境変数。\n- `labels` _Dict[str, str]_ - サンドボックスに付与されたカスタムラベル。\n- `public` _bool_ - サンドボックスが公開アクセス可能かどうか。\n- `target` _str_ - サンドボックスが実行されるランナーのターゲット(リージョン)。\n- `cpu` _int_ - サンドボックスに割り当てられた CPU 数。\n- `gpu` _int_ - サンドボックスに割り当てられた GPU 数。\n- `memory` _int_ - サンドボックスに割り当てられたメモリ量（GiB）。\n- `disk` _int_ - サンドボックスに割り当てられたディスク容量（GiB）。\n- `state` _SandboxState_ - サンドボックスの現在の状態（例: \"started\"、\"stopped\"）。\n- `error_reason` _str_ - サンドボックスがエラー状態の場合のエラーメッセージ。\n- `backup_state` _SandboxBackupStateEnum_ - サンドボックスのバックアップの現在の状態。\n- `backup_created_at` _str_ - バックアップが作成された日時。\n- `auto_stop_interval` _int_ - 自動停止の間隔（分）。\n- `auto_archive_interval` _int_ - 自動アーカイブの間隔（分）。\n- `auto_delete_interval` _int_ - 自動削除の間隔（分）。\n- `runner_domain` _str_ - サンドボックスのランナーのドメイン名。\n- `volumes` _List[str]_ - サンドボックスに接続されたボリューム。\n- `build_info` _str_ - 動的ビルドから作成された場合のサンドボックスのビルド情報。\n- `created_at` _str_ - サンドボックスが作成された日時。\n- `updated_at` _str_ - サンドボックスが最後に更新された日時。\n- `network_block_all` _bool_ - サンドボックスのすべてのネットワークアクセスをブロックするかどうか。\n- `network_allow_list` _str_ - サンドボックスで許可される CIDR ネットワークアドレスのカンマ区切りリスト。\n\n#### Sandbox.\\_\\_init\\_\\_\n\n```python\ndef __init__(sandbox_dto: SandboxDto, sandbox_api: SandboxApi,\n             toolbox_api: ToolboxApi, code_toolbox: SandboxCodeToolbox)\n```\n\n新しいサンドボックスインスタンスを初期化します。\n\n**引数**:\n\n- `id` _str_ - サンドボックスの一意の識別子。\n- `instance` _SandboxInstance_ - 基盤となるサンドボックスインスタンス。\n- `sandbox_api` _SandboxApi_ - サンドボックス操作用の API クライアント。\n- `toolbox_api` _ToolboxApi_ - ツールボックス操作用の API クライアント。\n- `code_toolbox` _SandboxCodeToolbox_ - 言語固有のツールボックス実装。\n\n#### Sandbox.refresh\\_data\n\n```python\ndef refresh_data() -> None\n```\n\nAPI からサンドボックスのデータをリフレッシュします。\n\n**例**:\n\n```python\nsandbox.refresh_data()\nprint(f\"Sandbox {sandbox.id}:\")\nprint(f\"State: {sandbox.state}\")\nprint(f\"Resources: {sandbox.cpu} CPU, {sandbox.memory} GiB RAM\")\n```\n\n#### Sandbox.get\\_user\\_root\\_dir\n\n```python\n@intercept_errors(message_prefix=\"Failed to get sandbox root directory: \")\ndef get_user_root_dir() -> str\n```\n\nサンドボックス内でログイン中のユーザーのルートディレクトリパスを取得します。\n\n**戻り値**:\n\n- `str` - ログイン中のユーザー用サンドボックスのルートディレクトリの絶対パス。\n  \n\n**例**:\n\n```python\nroot_dir = sandbox.get_user_root_dir()\nprint(f\"Sandbox root: {root_dir}\")\n```\n\n#### Sandbox.create\\_lsp\\_server\n\n```python\ndef create_lsp_server(language_id: LspLanguageId,\n                      path_to_project: str) -> LspServer\n```\n\n新しい Language Server Protocol (LSP) サーバーインスタンスを作成します。\n\nLSP サーバーは、コード補完、診断などの言語固有の機能を提供します。\n\n**引数**:\n\n- `language_id` _LspLanguageId_ - 言語サーバーの種類（例: LspLanguageId.PYTHON）。\n- `path_to_project` _str_ - プロジェクトのルートディレクトリへのパス。相対パスはユーザーの\n  ルートディレクトリを基準に解決されます。\n  \n\n**戻り値**:\n\n- `LspServer` - 指定した言語向けに構成された新しい LSP サーバーインスタンス。\n  \n\n**例**:\n\n```python\nlsp = sandbox.create_lsp_server(\"python\", \"workspace/project\")\n```\n\n#### Sandbox.set\\_labels\n\n```python\n@intercept_errors(message_prefix=\"Failed to set labels: \")\ndef set_labels(labels: Dict[str, str]) -> Dict[str, str]\n```\n\nサンドボックスにラベルを設定します。\n\nラベルはサンドボックスを整理・識別するために使用できるキーと値のペアです。\n\n**引数**:\n\n- `labels` _Dict[str, str]_ - サンドボックスのラベルを表すキーと値のペアのディクショナリ。\n  \n\n**戻り値**:\n\n  Dict[str, str]: 更新後のサンドボックスのラベルを含むディクショナリ。\n  \n\n**例**:\n\n```python\nnew_labels = sandbox.set_labels({\n    \"project\": \"my-project\",\n    \"environment\": \"development\",\n    \"team\": \"backend\"\n})\nprint(f\"Updated labels: {new_labels}\")\n```\n\n#### Sandbox.start\n\n```python\n@intercept_errors(message_prefix=\"Failed to start sandbox: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Sandbox {self.id} failed to start within the {timeout} seconds timeout period\"\n))\ndef start(timeout: Optional[float] = 60)\n```\n\nサンドボックスを起動し、準備完了になるまで待機します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - 待機する最大時間（秒）。0 はタイムアウトなしを意味します。デフォルトは 60 秒。\n  \n\n**送出**:\n\n- `DaytonaError` - タイムアウトが負の場合、またはサンドボックスの起動に失敗／タイムアウトした場合。\n  \n\n**例**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.start(timeout=40)  # 最大 40 秒待機\nprint(\"Sandbox started successfully\")\n```\n\n#### Sandbox.stop\n\n```python\n@intercept_errors(message_prefix=\"Failed to stop sandbox: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Sandbox {self.id} failed to stop within the {timeout} seconds timeout period\"\n))\ndef stop(timeout: Optional[float] = 60)\n```\n\nサンドボックスを停止し、完全に停止するまで待機します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - 待機する最大時間（秒）。0 はタイムアウトなしを意味します。デフォルトは 60 秒。\n  \n\n**送出**:\n\n- `DaytonaError` - タイムアウトが負の場合、またはサンドボックスの停止に失敗／タイムアウトした場合。\n  \n\n**例**:\n\n```python\nsandbox = daytona.get(\"my-sandbox-id\")\nsandbox.stop()\nprint(\"Sandbox stopped successfully\")\n```\n\n#### Sandbox.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to remove sandbox: \")\ndef delete(timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスを削除します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - サンドボックス削除のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n  デフォルトは 60 秒。\n\n#### Sandbox.wait\\_for\\_sandbox\\_start\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for sandbox to start: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Sandbox {self.id} failed to become ready within the {timeout} seconds timeout period\"\n))\ndef wait_for_sandbox_start(timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスが「started」状態になるまで待機します。サンドボックスのステータスをポーリングし、\n「started」状態に達するか、エラーが発生するか、タイムアウトするまで待機します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - 待機する最大時間（秒）。0 はタイムアウトなしを意味します。デフォルトは 60 秒。\n  \n\n**送出**:\n\n- `DaytonaError` - タイムアウトが負の場合、またはサンドボックスの起動に失敗／タイムアウトした場合。\n\n#### Sandbox.wait\\_for\\_sandbox\\_stop\n\n```python\n@intercept_errors(\n    message_prefix=\"Failure during waiting for sandbox to stop: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Sandbox {self.id} failed to become stopped within the {timeout} seconds timeout period\"\n))\ndef wait_for_sandbox_stop(timeout: Optional[float] = 60) -> None\n```\n\nサンドボックスが「stopped」状態になるまで待機します。サンドボックスのステータスをポーリングし、\n「stopped」状態に達するか、エラーが発生するか、タイムアウトするまで待機します。サンドボックスが停止するまで最長 60 秒待機します。\n\n**引数**:\n\n- `timeout` _Optional[float]_ - 待機する最大時間（秒）。0 はタイムアウトなしを意味します。デフォルトは 60 秒。\n  \n\n**送出**:\n\n- `DaytonaError` - タイムアウトが負の場合、またはサンドボックスの停止に失敗／タイムアウトした場合。\n\n#### Sandbox.set\\_autostop\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-stop interval: \")\ndef set_autostop_interval(interval: int) -> None\n```\n\nサンドボックスの自動停止間隔を設定します。\n\nサンドボックスは、指定した間隔のあいだアイドル状態（新しいイベントなし）が続くと自動的に停止します。\nイベントには、SDK を介したサンドボックスとの状態変更や操作が含まれます。\nサンドボックスのプレビュー経由の操作は含まれません。\n\n**引数**:\n\n- `interval` _int_ - 自動停止までの非アクティブ時間（分）。\n  0 に設定すると自動停止を無効化します。デフォルトは 15。\n  \n\n**送出**:\n\n- `DaytonaError` - interval が負の場合\n  \n\n**例**:\n\n```python\n# 1時間後に自動停止\nsandbox.set_autostop_interval(60)\n# または自動停止を無効化\nsandbox.set_autostop_interval(0)\n```\n\n#### Sandbox.set\\_auto\\_archive\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-archive interval: \")\ndef set_auto_archive_interval(interval: int) -> None\n```\n\nサンドボックスの自動アーカイブ間隔を設定します。\n\nサンドボックスは、指定した間隔のあいだ連続して停止状態が続くと自動的にアーカイブされます。\n\n**引数**:\n\n- `interval` _int_ - 連続して停止してから自動アーカイブされるまでの分数。\n  0 に設定すると最大間隔になります。デフォルトは 7 日。\n  \n\n**送出**:\n\n- `DaytonaError` - interval が負の場合\n  \n\n**例**:\n\n```python\n# 1時間後に自動アーカイブ\nsandbox.set_auto_archive_interval(60)\n# または最大間隔を使用\nsandbox.set_auto_archive_interval(0)\n```\n\n#### Sandbox.set\\_auto\\_delete\\_interval\n\n```python\n@intercept_errors(message_prefix=\"Failed to set auto-delete interval: \")\ndef set_auto_delete_interval(interval: int) -> None\n```\n\nサンドボックスの自動削除間隔を設定します。\n\nサンドボックスは、指定した間隔のあいだ連続して停止状態が続くと自動的に削除されます。\n\n**引数**:\n\n- `interval` _int_ - 連続して停止してから自動削除されるまでの分数。\n  負の値に設定すると自動削除を無効化します。0 に設定すると停止時に即時削除します。\n  既定では自動削除は無効です。\n  \n\n**例**:\n\n```python\n# 1時間後に自動削除\nsandbox.set_auto_delete_interval(60)\n# または停止時に即時削除\nsandbox.set_auto_delete_interval(0)\n# または自動削除を無効化\nsandbox.set_auto_delete_interval(-1)\n```\n\n#### Sandbox.get\\_preview\\_link\n\n```python\n@intercept_errors(message_prefix=\"Failed to get preview link: \")\ndef get_preview_link(port: int) -> PortPreviewUrl\n```\n\n指定したポートのサンドボックスのプレビューリンクを取得します。ポートが閉じている場合は\n自動的に開かれます。プライベートなサンドボックスでは、URL にアクセス権を与える\nトークンが含まれます。\n\n**引数**:\n\n- `port` _int_ - プレビューリンクを開くポート。\n  \n\n**返り値**:\n\n- `PortPreviewUrl` - プレビューリンクのレスポンスオブジェクト。`url`\n  と（プライベートなサンドボックスにアクセスするための）`token` を含みます。\n  \n\n**例**:\n\n```python\npreview_link = sandbox.get_preview_link(3000)\nprint(f\"Preview URL: {preview_link.url}\")\nprint(f\"Token: {preview_link.token}\")\n```\n\n#### Sandbox.archive\n\n```python\n@intercept_errors(message_prefix=\"Failed to archive sandbox: \")\ndef archive() -> None\n```\n\nサンドボックスをアーカイブし、非アクティブ化して状態を保持します。サンドボックスが\nアーカイブされると、ファイルシステム全体の状態はコスト効率の高いオブジェクトストレージに移動され、\n長期間にわたりサンドボックスを利用可能な状態に保つことができます。アーカイブ状態と\n停止状態のトレードオフは、アーカイブされたサンドボックスの起動には、そのサイズに応じて\nより時間がかかる点です。アーカイブする前にサンドボックスは停止している必要があります。\n\n\n## リソース\n\n```python\n@dataclass\nclass Resources()\n```\n\nサンドボックスのリソース設定。\n\n**属性**:\n\n- `cpu` _Optional[int]_ - 割り当てる CPU コア数。\n- `memory` _Optional[int]_ - 割り当てるメモリ容量（GiB）。\n- `disk` _Optional[int]_ - 割り当てるディスク容量（GiB）。\n- `gpu` _Optional[int]_ - 割り当てる GPU 数。\n  \n\n**例**:\n\n```python\nresources = Resources(\n    cpu=2,\n    memory=4,  # 4GiB RAM\n    disk=20,   # 20GiB disk\n    gpu=1\n)\nparams = CreateSandboxFromImageParams(\n    image=Image.debian_slim(\"3.12\"),\n    language=\"python\",\n    resources=resources\n)\n```\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/snapshot.mdx",
    "content": "---\ntitle: \"スナップショット\"\nhideTitleOnPage: true\n---\n\n## スナップショット\n\n```python\nclass Snapshot(SnapshotDto)\n```\n\n事前に構成されたサンドボックスである Daytona のスナップショットを表します。\n\n**属性**:\n\n- `id` _StrictStr_ - スナップショットの一意の識別子。\n- `organization_id` _Optional[StrictStr]_ - スナップショットの組織ID。\n- `general` _Optional[bool]_ - スナップショットが汎用かどうか。\n- `name` _StrictStr_ - スナップショット名。\n- `image_name` _StrictStr_ - スナップショットのイメージ名。\n- `state` _StrictStr_ - スナップショットの状態。\n- `size` _Optional[Union[StrictFloat, StrictInt]]_ - スナップショットのサイズ。\n- `entrypoint` _Optional[List[str]]_ - スナップショットのエントリポイント。\n- `cpu` _Union[StrictFloat, StrictInt]_ - スナップショットの CPU。\n- `gpu` _Union[StrictFloat, StrictInt]_ - スナップショットの GPU。\n- `mem` _Union[StrictFloat, StrictInt]_ - スナップショットのメモリ（GiB）。\n- `disk` _Union[StrictFloat, StrictInt]_ - スナップショットのディスク（GiB）。\n- `error_reason` _Optional[StrictStr]_ - スナップショットのエラー理由。\n- `created_at` _StrictStr_ - スナップショットの作成時刻。\n- `updated_at` _StrictStr_ - スナップショットの最終更新時刻。\n- `last_used_at` _StrictStr_ - スナップショットの最終使用時刻。\n\n\n## SnapshotService\n\n```python\nclass SnapshotService()\n```\n\nDaytonaのスナップショットを管理するサービス。スナップショットの一覧、取得、作成、削除に使用できます。\n\n#### SnapshotService.list\n\n```python\n@intercept_errors(message_prefix=\"Failed to list snapshots: \")\ndef list() -> List[Snapshot]\n```\n\nすべてのスナップショットを一覧します。\n\n**Returns**:\n\n- `List[Snapshot]` - すべてのスナップショットのリスト。\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nsnapshots = daytona.snapshot.list()\nfor snapshot in snapshots:\n    print(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n#### SnapshotService.delete\n\n```python\n@intercept_errors(message_prefix=\"Failed to delete snapshot: \")\ndef delete(snapshot: Snapshot) -> None\n```\n\nスナップショットを削除します。\n\n**Arguments**:\n\n- `snapshot` _Snapshot_ - 削除するスナップショット。\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nsnapshot = daytona.snapshot.get(\"test-snapshot\")\ndaytona.snapshot.delete(snapshot)\nprint(\"Snapshot deleted\")\n```\n\n#### SnapshotService.get\n\n```python\n@intercept_errors(message_prefix=\"Failed to get snapshot: \")\ndef get(name: str) -> Snapshot\n```\n\n名前でスナップショットを取得します。\n\n**Arguments**:\n\n- `name` _str_ - 取得するスナップショットの名前。\n  \n\n**Returns**:\n\n- `Snapshot` - 取得したスナップショットオブジェクト。\n  \n\n**Example**:\n\n```python\ndaytona = Daytona()\nsnapshot = daytona.snapshot.get(\"test-snapshot-name\")\nprint(f\"{snapshot.name} ({snapshot.image_name})\")\n```\n\n#### SnapshotService.create\n\n```python\n@intercept_errors(message_prefix=\"Failed to create snapshot: \")\n@with_timeout(error_message=lambda self, timeout: (\n    f\"Failed to create snapshot within {timeout} seconds timeout period.\"))\ndef create(params: CreateSnapshotParams,\n           *,\n           on_logs: Callable[[str], None] = None,\n           timeout: Optional[float] = 0) -> Snapshot\n```\n\n指定されたImage定義から新しいスナップショットを作成し、登録します。\n\n**Arguments**:\n\n- `params` _CreateSnapshotParams_ - スナップショット作成用のパラメータ。\n- `on_logs` _Callable[[str], None]_ - スナップショット作成時のログを処理するコールバック関数。\n- `timeout` _Optional[float]_ - 既定ではタイムアウトなし。タイムアウト秒数（0は無制限）。\n\n**Example**:\n\n```python\nimage = Image.debianSlim('3.12').pipInstall('numpy')\ndaytona.snapshot.create(\n    CreateSnapshotParams(name='my-snapshot', image=image),\n    on_logs=lambda chunk: print(chunk, end=\"\"),\n)\n```\n\n#### SnapshotService.activate\n\n```python\ndef activate(snapshot: Snapshot) -> Snapshot\n```\n\nスナップショットをアクティブ化します。\n\n**Arguments**:\n\n- `snapshot` _Snapshot_ - 対象のスナップショットインスタンス。\n\n**Returns**:\n\n- `Snapshot` - アクティブ化されたスナップショットインスタンス。\n\n#### SnapshotService.process\\_image\\_context\n\n```python\n@staticmethod\ndef process_image_context(object_storage_api: ObjectStorageApi,\n                          image: Image) -> List[str]\n```\n\nイメージのコンテキストをオブジェクトストレージにアップロードして処理します。\n\n**Arguments**:\n\n- `image` _Image_ - Imageインスタンス。\n\n**Returns**:\n\n- `List[str]` - オブジェクトストレージに保存されたコンテキストハッシュのリスト。\n\n## CreateSnapshotParams\n\n```python\nclass CreateSnapshotParams(BaseModel)\n```\n\n新規スナップショット作成用のパラメータ。\n\n**属性**:\n\n- `name` _Optional[str]_ - スナップショット名。\n- `image` _Union[str, Image]_ - スナップショットのイメージ。文字列が指定された場合は、\n  いずれかのレジストリで利用可能である必要があります。Image インスタンスが指定された場合は、\n  Daytona で新しいイメージを作成するために使用されます。\n- `resources` _Optional[Resources]_ - スナップショットのリソース。\n- `entrypoint` _Optional[List[str]]_ - スナップショットのエントリポイント。\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/python-sdk/sync/volume.mdx",
    "content": "---\ntitle: \"ボリューム\"\nhideTitleOnPage: true\n---\n\n## ボリューム\n\n```python\nclass Volume(VolumeDto)\n```\n\nDaytona のボリュームを表し、サンドボックス向けの共有ストレージボリュームです。\n\n**属性**:\n\n- `id` _StrictStr_ - ボリュームの一意の識別子。\n- `name` _StrictStr_ - ボリューム名。\n- `organization_id` _StrictStr_ - ボリュームの組織ID。\n- `state` _StrictStr_ - ボリュームの状態。\n- `created_at` _StrictStr_ - ボリュームの作成日時。\n- `updated_at` _StrictStr_ - ボリュームの最終更新日時。\n- `last_used_at` _StrictStr_ - ボリュームの最終使用日時。\n\n\n## VolumeService\n\n```python\nclass VolumeService()\n```\n\nDaytonaのボリュームを管理するサービス。ボリュームの一覧、取得、作成、削除に利用できます。\n\n#### VolumeService.list\n\n```python\ndef list() -> List[Volume]\n```\n\nすべてのボリュームを一覧表示します。\n\n**戻り値**:\n\n- `List[Volume]` - すべてのボリュームのリスト。\n  \n\n**例**:\n\n```python\ndaytona = Daytona()\nvolumes = daytona.volume.list()\nfor volume in volumes:\n    print(f\"{volume.name} ({volume.id})\")\n```\n\n#### VolumeService.get\n\n```python\ndef get(name: str, create: bool = False) -> Volume\n```\n\nボリューム名を指定して取得します。\n\n**引数**:\n\n- `name` _str_ - 取得するボリュームの名前。\n- `create` _bool_ - True の場合、存在しないときは新規に作成します。\n  \n\n**戻り値**:\n\n- `Volume` - 取得したボリュームオブジェクト。\n  \n\n**例**:\n\n```python\ndaytona = Daytona()\nvolume = daytona.volume.get(\"test-volume-name\", create=True)\nprint(f\"{volume.name} ({volume.id})\")\n```\n\n#### VolumeService.create\n\n```python\ndef create(name: str) -> Volume\n```\n\n新しいボリュームを作成します。\n\n**引数**:\n\n- `name` _str_ - 作成するボリュームの名前。\n  \n\n**戻り値**:\n\n- `Volume` - 作成されたボリュームオブジェクト。\n  \n\n**例**:\n\n```python\ndaytona = Daytona()\nvolume = daytona.volume.create(\"test-volume\")\nprint(f\"{volume.name} ({volume.id}); state: {volume.state}\")\n```\n\n#### VolumeService.delete\n\n```python\ndef delete(volume: Volume) -> None\n```\n\nボリュームを削除します。\n\n**引数**:\n\n- `volume` _Volume_ - 削除するボリューム。\n  \n\n**例**:\n\n```python\ndaytona = Daytona()\nvolume = daytona.volume.get(\"test-volume\")\ndaytona.volume.delete(volume)\nprint(\"Volume deleted\")\n```\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/regions.mdx",
    "content": "---\ntitle: リージョンの選択\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytona は現在、以下のリージョンで利用可能です。\n\n- 米国（US）\n- 欧州（EU）\n\nDaytona の[設定](/docs/ja/configuration)手順でリージョンを選択できます。\n\n```python\nfrom daytona import Daytona, DaytonaConfig\n\nconfig = DaytonaConfig(\n    target=\"us\"\n)\n\ndaytona = Daytona(config)\n```\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\nconst daytona: Daytona = new Daytona({\n    target: \"eu\"\n});\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/sandbox-management.mdx",
    "content": "---\ntitle: サンドボックス管理\n---\n\nimport sandboxDiagram from '@assets/docs/sandbox-states.svg?raw'\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport Image from 'astro/components/Image.astro'\n\nサンドボックス（Daytonaが管理する隔離された一時的な実行環境）は、Daytonaによって管理される開発用の隔離環境です。本ガイドでは、TS SDK／Python SDKを用いてサンドボックスを作成・管理・削除する方法を解説します。\nデフォルトでは、サンドボックスは非アクティブ状態が15分続くと自動停止し、**vCPU 1**、**RAM 1GB**、**ディスク 3GiB**を使用します。\n\n## サンドボックスのライフサイクル\n\nライフサイクル全体を通じて、Daytonaのサンドボックス（Daytonaが管理する隔離された一時的な実行環境）は複数の状態を取り得ます。以下の図は、それぞれの状態と遷移の可能性を示します。\n\n<Fragment set:html={sandboxDiagram} />\n\nデフォルトでは、サンドボックスは非アクティブな状態が`15 minutes`続くと自動停止し、停止から`7 days`後に自動アーカイブされます。中断なく無期限に稼働させるには、作成時に自動停止の値を`0`に設定してください。\n\n## サンドボックスの作成\n\nDaytona SDK は、デフォルトまたはカスタム構成でサンドボックスを作成する機能を提供します。サンドボックスに対して、言語、[スナップショット](/docs/ja/snapshots)、リソース、環境変数、ボリュームを指定できます。\n稼働中のサンドボックスは CPU、メモリ、ディスクストレージを消費します。各リソースは使用秒単位で課金されます。\n\n:::tip\n自動停止の間隔を延長したい場合は、サンドボックス作成時に[自動停止間隔パラメータを設定](/docs/ja/sandboxes#auto-stop-interval)できます。\n:::\n\n### 基本的なサンドボックスの作成\n\nDaytona SDK には、Python と TypeScript により、デフォルト構成、特定の言語、またはカスタムラベルでサンドボックスを作成するメソッドが用意されています。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, CreateSandboxFromSnapshotParams\n\n    daytona = Daytona()\n\n    # Create a basic Sandbox\n\n    sandbox = daytona.create()\n\n    # Create a Sandbox with specific language\n\n    params = CreateSandboxFromSnapshotParams(language=\"python\")\n    sandbox = daytona.create(params)\n\n    # Create a Sandbox with custom labels\n\n    params = CreateSandboxFromSnapshotParams(labels={\"SOME_LABEL\": \"my-label\"})\n    sandbox = daytona.create(params)\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona } from '@daytonaio/sdk';\n\n    const daytona = new Daytona();\n\n    // Create a basic Sandbox\n    const sandbox = await daytona.create();\n\n    // Create a Sandbox with specific language\n    const sandbox = await daytona.create({ language: 'typescript' });\n\n    // Create a Sandbox with custom labels\n    const sandbox = await daytona.create({ labels: { SOME_LABEL: 'my-label' } });\n    ```\n  </TabItem>\n</Tabs>\n\nサンドボックスが積極的に使用されていない場合は、停止することを推奨します。これは、[stop コマンドの使用](/docs/ja/sandboxes#stop-and-start-sandbox)による手動操作、または[自動停止間隔の設定](/docs/ja/sandboxes#auto-stop-and-auto-archive)による自動化で行えます。\n\n:::note\nDaytona はデフォルトのスナップショットを用いたウォーム状態のサンドボックスプールを維持しています。\\\n利用可能な場合はコールドブートせず、ミリ秒単位でサンドボックスが起動します。\n:::\n\n### サンドボックスのリソース\n\nDaytona のサンドボックスは、デフォルトで **1 vCPU**、**1GB RAM**、**3GiB ディスク**を備えています。\n\nより高い性能が必要ですか？`Resources` クラスを使用して、必要な構成を正確に指定できます。CPU、メモリ、ディスク容量はすべてカスタマイズ可能です。\n\n[ダッシュボード](https://app.daytona.io/dashboard/limits)で利用可能なリソースと上限を確認してください。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, Resources, CreateSandboxFromImageParams, Image\n\n    daytona = Daytona()\n\n    # Create a Sandbox with custom resources\n\n    resources = Resources(\n        cpu=2,  # 2 CPU cores\n        memory=4,  # 4GB RAM\n        disk=8,  # 8GB disk space\n    )\n\n    params = CreateSandboxFromImageParams(\n        image=Image.debian_slim(\"3.12\"),\n        resources=resources\n    )\n\n    sandbox = daytona.create(params)\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona, Image } from \"@daytonaio/sdk\";\n\n    async function main() {\n      const daytona = new Daytona();\n\n      // Create a Sandbox with custom resources\n      const sandbox = await daytona.create({\n        image: Image.debianSlim(\"3.13\"),\n        resources: {\n          cpu: 2, // 2 CPU cores\n          memory: 4, // 4GB RAM\n          disk: 8, // 8GB disk space\n        },\n      });\n    }\n\n    main();\n    ```\n  </TabItem>\n</Tabs>\n\n:::note\nすべてのリソースパラメータは任意です。指定しない場合、Daytona は選択した言語やユースケースに適したデフォルト値を使用します。\n:::\n\n### ネットワーク設定\n\nDaytona のサンドボックスは、セキュリティ強化と接続性管理のため、ネットワークアクセス制御を構成可能に提供します。デフォルトでは標準的なセキュリティポリシーに従いますが、サンドボックス作成時にネットワーク設定をカスタマイズできます。\n\n- すべてのネットワークアクセスをブロックするには、`networkBlockAll` を `True` に設定します\n- 特定のアドレスにアクセスを制限するには、`networkAllowList` に最大 5 つの CIDR ブロックをカンマ区切りで設定します\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, CreateSandboxFromSnapshotParams\n\n    daytona = Daytona()\n\n    # すべてのネットワークアクセスをブロック\n\n    params = CreateSandboxFromSnapshotParams(\n      network_block_all=True\n    )\n    sandbox = daytona.create(params)\n\n    # 許可するネットワークアドレスを明示的に指定\n\n    params = CreateSandboxFromSnapshotParams(\n      network_allow_list=\"192.168.1.0/16,10.0.0.0/24\"\n    )\n    sandbox = daytona.create(params)\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona } from '@daytonaio/sdk';\n\n    const daytona = new Daytona();\n\n    // すべてのネットワークアクセスをブロック\n    const sandbox = await daytona.create({\n      networkBlockAll: true\n    });\n\n    // 許可するネットワークアドレスを明示的に指定\n    const sandbox = await daytona.create({\n      networkAllowList: '192.168.1.0/16,10.0.0.0/24'\n    });\n    ```\n  </TabItem>\n</Tabs>\n\n:::caution\n信頼できないコードを実行する場合、無制限のネットワークアクセスを有効にするとセキュリティリスクが生じる可能性があります。\n代わりに、`networkAllowList` を使用して特定のネットワークアドレスを許可リストに追加するか、`networkBlockAll` を使用してすべてのネットワークアクセスをブロックすることを推奨します。\n:::\n\n## サンドボックス情報\n\nDaytona SDK は、Python と TypeScript で、ID、ルートディレクトリ、状態などサンドボックスに関する情報を取得するためのメソッドを提供します。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # サンドボックス ID を取得\n    sandbox_id = sandbox.id\n\n    # サンドボックスユーザーのルートディレクトリを取得\n    root_dir = sandbox.get_user_root_dir()\n\n    # サンドボックスの ID・自動停止間隔・状態を取得\n    print(sandbox.id)\n    print(sandbox.auto_stop_interval)\n    print(sandbox.state)\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    // サンドボックス ID を取得\n    const sandboxId = sandbox.id;\n\n    // サンドボックスユーザーのルートディレクトリを取得\n    const rootDir = await sandbox.getUserRootDir();\n\n    // サンドボックスの ID・自動停止間隔・状態を取得\n    console.log(sandbox.id)\n    console.log(sandbox.autoStopInterval)\n    console.log(sandbox.state)\n    ```\n  </TabItem>\n</Tabs>\n\n特定のポートのプレビュー URL を取得するには、[プレビューと認証](/docs/ja/preview-and-authentication)を参照してください。\n\n## サンドボックスの停止と起動\n\nDaytona SDK は、Python と TypeScript でサンドボックスを停止・起動するためのメソッドを提供します。\n\n停止したサンドボックスは、メモリ状態がクリアされますが、ファイルシステムは保持されます。ディスク使用量のコストのみが発生し、必要に応じて再度起動できます。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    sandbox = daytona.create(CreateSandboxParams(language=\"python\"))\n\n    # Stop Sandbox\n\n    sandbox.stop()\n\n    print(sandbox.id) # 7cd11133-96c1-4cc8-9baa-c757b8f8c916\n\n    # The sandbox ID can later be used to get the sandbox and start it\n\n    sandbox = daytona.get(\"7cd11133-96c1-4cc8-9baa-c757b8f8c916\")\n\n    # Start Sandbox\n\n    sandbox.start()\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    const sandbox = await daytona.create({ language: 'typescript' });\n\n    // Stop Sandbox\n    await sandbox.stop();\n\n    console.log(sandbox.id) // 7cd11133-96c1-4cc8-9baa-c757b8f8c916\n\n    // The sandbox ID can later be used to get the sandbox and start it\n\n    const sandbox = await daytona.get(\"7cd11133-96c1-4cc8-9baa-c757b8f8c916\");\n\n    // Start Sandbox\n    await sandbox.start();\n    ```\n  </TabItem>\n</Tabs>\n\n近く再起動する見込みがある場合は、停止状態を利用してください。そうでない場合は、ディスク使用量のコストをなくすため、停止後にサンドボックスをアーカイブすることを推奨します。\n\n## サンドボックスのアーカイブ\n\nDaytona SDK は、Python と TypeScript からサンドボックスをアーカイブするためのメソッドを提供します。\n\nサンドボックスをアーカイブすると、ファイルシステム全体の状態がコスト効率の高いオブジェクトストレージに移され、サンドボックスを長期間利用可能な状態で保持できます。\nアーカイブされたサンドボックスの起動には、サイズに応じて、停止中のサンドボックスよりも時間がかかります。\n\nサンドボックスはアーカイブ前に停止している必要があり、停止中のサンドボックスと同様の手順で再度起動できます。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # Archive Sandbox\n    sandbox.archive()\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    // Archive Sandbox\n    await sandbox.archive();\n    ```\n  </TabItem>\n</Tabs>\n\n## サンドボックスの削除\n\nDaytona SDK には、Python と TypeScript でサンドボックスを削除するためのメソッドが用意されています。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    # サンドボックスを削除\n    sandbox.delete()\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    // サンドボックスを削除\n    await sandbox.delete();\n    ```\n  </TabItem>\n</Tabs>\n\n:::tip\nターミナルからサンドボックスを管理したい場合は、[Daytona CLI](/docs/ja/getting-started#cli)をご確認ください:\n\n```bash\ndaytona sandbox list\n```\n\n```text\n\n    Sandbox               State           Region        Last Event\n    ────────────────────────────────────────────────────────────────────────────────────\n    ugliest_quokka        STARTED         us            1 hour ago\n\n    associated_yak        STARTED         us            14 hours ago\n\n    developed_lemur       STARTED         us            17 hours ago\n\n```\n\n```bash\ndaytona sandbox start|stop|remove --all\n```\n\n```text\nすべてのサンドボックスを削除しました\n```\n\n:::\n\n## 自動ライフサイクル管理\n\nDaytona のサンドボックスは、ユーザーが指定した間隔に基づいて自動で停止、アーカイブ、削除できます。\n\n### 自動停止の間隔\n\n自動停止の間隔パラメータは、稼働中のサンドボックスを自動停止するまでの時間を設定します。\n\nパラメータは次のいずれかで設定できます:\n\n- 分単位の時間間隔\n- `0`（自動停止を無効にし、サンドボックスを無期限に稼働させる）\n\nパラメータが未設定の場合、デフォルトの `15` 分が使用されます。\n\n:::\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    sandbox = daytona.create(CreateSandboxFromSnapshotParams(\n        snapshot=\"my-snapshot-name\",\n        auto_stop_interval=0,  # 自動停止を無効化 - デフォルトは 15 分\n    ))\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    const sandbox = await daytona.create({\n        snapshot: \"my-snapshot-name\",\n        autoStopInterval: 0, // 自動停止を無効化 - デフォルトは 15 分\n    });\n    ```\n  </TabItem>\n</Tabs>\n\n### 自動アーカイブの間隔\n\n自動アーカイブの間隔パラメータは、停止状態が継続しているサンドボックスを自動アーカイブするまでの時間を設定します。\n\nパラメータは次のいずれかで設定できます:\n\n- 分単位の時間間隔\n- `0`（最大間隔の `30 days` が適用される）\n\nパラメータが未設定の場合、デフォルトの `7 days` が使用されます。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    sandbox = daytona.create(CreateSandboxFromSnapshotParams(\n        snapshot=\"my-snapshot-name\",\n        auto_archive_interval=60 # 停止後 1 時間で自動アーカイブ\n    ))\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    const sandbox = await daytona.create({\n        snapshot: \"my-snapshot-name\",\n        autoArchiveInterval: 60 // 停止後 1 時間で自動アーカイブ\n    });\n    ```\n  </TabItem>\n</Tabs>\n\n### 自動削除の間隔\n\n自動削除の間隔パラメータは、停止状態が継続しているサンドボックスを自動削除するまでの時間を設定します。デフォルトでは、サンドボックスは自動削除されません。\n\nパラメータは次のいずれかで設定できます:\n\n- 分単位の時間間隔\n- `-1`（自動削除を無効化）\n- `0`（停止直後に即時削除）\n\nパラメータが未設定の場合、サンドボックスは自動削除されません。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    sandbox = daytona.create(CreateSandboxFromSnapshotParams(\n        snapshot=\"my-snapshot-name\",\n        auto_delete_interval=60,  # 停止後 1 時間で自動削除\n    ))\n\n    # 停止直後に即時削除する\n    sandbox.set_auto_delete_interval(0)\n\n    # 自動削除を無効化する\n    sandbox.set_auto_delete_interval(-1)\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    const sandbox = await daytona.create({\n        snapshot: \"my-snapshot-name\",\n        autoDeleteInterval: 60, // 停止後 1 時間で自動削除\n    });\n\n    // 停止直後に即時削除する\n    await sandbox.setAutoDeleteInterval(0)\n\n    // 自動削除を無効化する\n    await sandbox.setAutoDeleteInterval(-1)\n    ```\n  </TabItem>\n</Tabs>\n\n## 無期限で実行\n\nデフォルトでは、サンドボックスは15分間操作がないと自動停止します。中断なくサンドボックスを稼働させ続けるには、新しいサンドボックスを作成する際に自動停止間隔を`0`に設定してください。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    sandbox = daytona.create(CreateSandboxFromSnapshotParams(\n        snapshot=\"my-snapshot-name\",\n        auto_stop_interval=0,  # 自動停止を無効化（デフォルトは15分）\n    ))\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    const sandbox = await daytona.create({\n        snapshot: \"my-snapshot-name\",\n        autoStopInterval: 0, // 自動停止を無効化（デフォルトは15分）\n    });\n    ```\n  </TabItem>\n</Tabs>\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/snapshots.mdx",
    "content": "---\ntitle: スナップショット\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\nimport Label from '@components/Label.astro'\n\nスナップショット（サンドボックス作成に使う再利用可能な事前設定イメージ／テンプレート）は、Daytona のサンドボックス（Daytona が管理する隔離された一時的な計算環境）に必要な依存関係、ツール、環境設定、リソース要件をすべて含む事前構成済みテンプレートです。Daytona は、標準的な [Docker](https://www.docker.com/) または [OCI](https://opencontainers.org/) 互換イメージからのスナップショット作成をサポートします。\n\n## スナップショットの作成\n\nサンドボックスを起動する際、Daytona は `python`、`node`、`pip` ならびに一般的な pip パッケージなどの有用なユーティリティがプリインストールされたシンプルなイメージに基づくスナップショットを使用します。詳細は[以下](#default-snapshot)を参照してください。\n\nこの挙動は上書き可能です。ダッシュボードにアクセスし、[Snapshots](https://app.daytona.io/dashboard/snapshots) をクリックしてから `Create Snapshot` を選択すると、カスタムスナップショットを作成できます。\n\nスナップショットのイメージには、Docker Hub の `alpine:3.21.3` や `debian:12.10` のような公開イメージの名前とタグ、または別の公開コンテナレジストリ（例: `my-public-registry.com/custom-alpine:3.21`）のイメージを指定できます。\n\nentrypoint フィールドは任意です。イメージに長時間稼働する entrypoint がない場合、Daytona は自動的に `sleep infinity` を実行して、作成直後にコンテナが即時終了しないようにします。\n\n:::note\n`latest` タグのイメージは頻繁に更新されるため、特定のタグ（例: `0.1.0`）のみがサポートされます。同様に、`lts` や `stable` といったタグも避けることを推奨します。\n:::\n\nスナップショットがプルおよび検証され、`Active` 状態になれば使用可能です。使用するカスタムスナップショットを指定するために、`CreateSandboxFromSnapshotParams` オブジェクトを定義します:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    sandbox = daytona.create(CreateSandboxFromSnapshotParams(\n        snapshot=\"my-snapshot-name\",\n    ))\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    const sandbox = await daytona.create({\n      snapshot: \"my-snapshot-name\",\n    })\n    ```\n  </TabItem>\n</Tabs>\n\n完全な例:\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import Daytona, CreateSandboxFromSnapshotParams\n\n    daytona = Daytona()\n\n    sandbox = daytona.create(CreateSandboxFromSnapshotParams(\n        snapshot=\"my-snapshot-name\",\n    ))\n\n    response = sandbox.process.code_run('print(\"Sum of 3 and 4 is \" + str(3 + 4))')\n    if response.exit_code != 0:\n        print(f\"Error running code: {response.exit_code} {response.result}\")\n    else:\n        print(response.result)\n\n    sandbox.delete()\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona } from '@daytonaio/sdk'\n\n    async function main() {\n      // Initialize the Daytona client\n      const daytona = new Daytona()\n\n      try {\n        // Create the Sandbox instance\n        const sandbox = await daytona.create({\n          snapshot: \"my-snapshot-name\",\n        })\n        // Run the code securely inside the Sandbox\n        const response = await sandbox.process.codeRun(\n          'print(\"Sum of 3 and 4 is \" + str(3 + 4))',\n        )\n        if (response.exitCode !== 0) {\n          console.error('Error running code:', response.exitCode, response.result)\n        } else {\n          console.log(response.result)\n        }\n      } catch (error) {\n        console.error('Sandbox flow error:', error)\n      } finally {\n        // Clean up the Sandbox\n        await sandbox.delete()\n      }\n    }\n\n    main()\n    ```\n  </TabItem>\n</Tabs>\n\n### スナップショットのリソース\n\nスナップショットには Daytona サンドボックスのリソース要件が含まれます。デフォルトでは、Daytona サンドボックスは **1 vCPU**、**1GB RAM**、**3GiB ディスク**を備えています。\n\nより高いパフォーマンスが必要ですか？`Resources` クラスを使用して、必要な CPU、メモリ、ディスク容量を正確に指定できます。\n\n利用可能なリソースと上限は[ダッシュボード](https://app.daytona.io/dashboard/limits)で確認してください。\n\n<Tabs syncKey=\"language\">\n  <TabItem label=\"Python\" icon=\"seti:python\">\n    ```python\n    from daytona import (\n        Daytona,\n        CreateSnapshotParams,\n        Image,\n        Resources,\n        CreateSandboxFromSnapshotParams,\n    )\n\n    daytona = Daytona()\n\n    # カスタムリソースを指定してスナップショットを作成\n\n    daytona.snapshot.create(\n        CreateSnapshotParams(\n            name=\"my-snapshot\",\n            image=Image.debian_slim(\"3.12\"),\n            resources=Resources(\n              cpu=2,\n              memory=4,\n              disk=8,\n            ),\n        ),\n        on_logs=print,\n    )\n\n    # カスタムスナップショットからサンドボックスを作成\n\n    sandbox = daytona.create(\n        CreateSandboxFromSnapshotParams(\n            snapshot=\"my-snapshot\",\n        )\n    )\n\n    ```\n  </TabItem>\n\n  <TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n    ```typescript\n    import { Daytona, Image } from \"@daytonaio/sdk\";\n\n    async function main() {\n      const daytona = new Daytona();\n\n      // カスタムリソースを指定してスナップショットを作成\n      await daytona.snapshot.create(\n        {\n          name: \"my-snapshot\",\n          image: Image.debianSlim(\"3.13\"),\n          resources: {\n            cpu: 2,\n            memory: 4,\n            disk: 8,\n          },\n        },\n        { onLogs: console.log }\n      );\n\n      // カスタムスナップショットからサンドボックスを作成\n      const sandbox = await daytona.create({\n        snapshot: \"my-snapshot\",\n      });\n    }\n\n    main();\n    ```\n  </TabItem>\n</Tabs>\n\n:::note\nすべてのリソースパラメータは任意です。指定しない場合、Daytonaはデフォルト値を使用します。\n:::\n\n### プライベートレジストリのイメージ\n\n一般公開されていないイメージからスナップショットを作成するには、まずそのイメージのプライベートコンテナレジストリを追加します。\n\n1. ダッシュボードの[Registries](https://app.daytona.io/dashboard/registries)ページに移動\n2. `Add Registry`ボタンをクリック\n3. 適切なカスタム名、URL、ユーザー名、パスワード、プロジェクト（該当する場合）を入力\n4. コンテナレジストリを作成したら、[Snapshots](https://app.daytona.io/dashboard/snapshots)ページに戻る\n5. スナップショット作成時は、レジストリURLとプロジェクト名（該当する場合）を含むプライベートイメージ名全体を入力すること（例: `my-private-registry.com/<my-project>/custom-alpine:3.21`）\n\nこの先の手順は同じです。`CreateSandboxFromSnapshotParams`のフィールドにそのカスタムスナップショットを指定すれば、追加の認証は不要です。\n\n#### プライベートな Docker Hub イメージの使用\n\nプライベートな Docker Hub イメージを使用するには、Docker Hub の認証情報で[コンテナレジストリを追加](/docs/ja/snapshots#images-from-private-registries)します。\n\n- Registry URL: `docker.io` を指定\n- Username: Docker Hub のユーザー名（プライベートイメージにアクセスできるアカウント）\n- Password: [Docker Hub Personal Access Token](https://docs.docker.com/docker-hub/access-tokens/)を使用（アカウントのパスワードではない）\n- スナップショットの作成: レジストリを追加後、イメージ名としてフルイメージパスを指定してスナップショットを作成（例: `docker.io/<username>/<image>:<tag>`）\n\n### ローカルイメージの使用\n\nプライベートコンテナレジストリを手動で用意してイメージをプッシュする手間を避けるために、[Daytona CLI](/docs/ja/getting-started#cli)を使ってローカルイメージやローカルの Dockerfile からスナップショットを作成し、サンドボックスで使用できます。\n\n`docker images` を実行して使用したいイメージとタグが存在することを確認したら、`daytona snapshot push <your_local_docker_image>` コマンドでスナップショットを作成して Daytona にプッシュします。例:\n\n```bash\ndaytona snapshot push custom-alpine:3.21 --name alpine-minimal\n```\n\n:::tip\n`--cpu`、`--memory`、`--disk` フラグを使って、基盤となるサンドボックス（Sandbox）に割り当てるリソースを指定します。\n\nたとえば `daytona snapshot push custom-alpine:3.21 --name alpine-minimal --cpu 2 --memory 4 --disk 8` は、2 vCPU、4GiB メモリ、8GiB ディスク容量の Alpine サンドボックスを作成します。\n:::\n\n:::note\nDaytona はローカルイメージが AMD64 アーキテクチャ向けにビルドされていることを前提としています。したがって、お使いのマシンが別のアーキテクチャの場合は、Docker イメージをビルドする際に `--platform=linux/amd64` フラグが必要です。\n\n詳しくは [CLI ドキュメント](/docs/ja/tools/cli#daytona-snapshot-push) を参照してください。\n:::\n\nまだ目的のイメージをビルドしておらず、Dockerfile が用意できている場合は、SDK の宣言的ビルダー（Declarative Builder）を利用できます。詳しくは[こちら](/docs/ja/getting-started#declarative-builder)をご覧ください。\n\nまた、CLI で実行する場合は、`create` で `--dockerfile` フラグに使用したい Dockerfile のパスを渡すと、Daytona がスナップショット（Snapshot）をビルドします:\n\n```bash\ndaytona snapshot create data-analysis01 --dockerfile ./Dockerfile --context ./requirements.txt\n```\n\n```text\nBuilding image from /Users/idagelic/docs/Dockerfile\nStep 1/5 : FROM alpine:latest\n\n...\n\n ⡿  Waiting for the Snapshot to be validated ...\n\n ...\n\n ✓  Use 'harbor-transient.internal.daytona.app/daytona/trying-daytona:0.0.1' to create a new sandbox using this Snapshot\n\n```\n\n## スナップショットの削除\n\n作成したカスタムスナップショットの削除は簡単です。[Snapshots](https://app.daytona.io/dashboard/snapshots) ページに移動し、削除したいスナップショットの行末にある三点アイコンをクリックして表示される `Delete` ボタンを選択してください。\n\n:::tip\n\n削除せずに一時的に無効化したい場合は、`Disable` をクリックします。これにより、新しいサンドボックスではそのスナップショットが使用されなくなりますが、スナップショット自体は削除されません。\n\n:::\n\n## サンドボックスでDockerを実行する\n\nDaytonaのサンドボックスは内部でDockerコンテナを実行できます（Docker-in-Docker）。これにより、コンテナ化されたアプリケーションのビルド、テスト、デプロイが可能になります。特に、データベース、メッセージキュー、その他のマイクロサービスなど外部サービスに依存するプロジェクトで有用です。\n\nこれらのサービスは同一のサンドボックス環境内で稼働するため、エージェントはシームレスに連携でき、外部サービス依存と比べて優れた分離性とセキュリティを提供します。\n\n### DinDスナップショットの作成\n\n事前構築されたDocker-in-Dockerイメージをベースにするか、カスタムイメージにDockerを手動でインストールすることで、Docker対応のスナップショットを作成できます。\n\n#### 事前構築イメージの利用\n\n以下のベースイメージはDocker-in-Dockerスナップショットの作成に広く使われており、カスタムDockerfileのベースとしても利用できます:\n\n- `docker:28.3.3-dind` - 公式のDocker-in-Dockerイメージ（Alpineベースで軽量）\n- `docker:28.3.3-dind-rootless` - セキュリティを強化したRootless Docker-in-Docker\n- `docker:28.3.2-dind-alpine3.22` - Alpine 3.22ベースのDocker-in-Dockerイメージ\n\n#### Dockerの手動インストール\n\nあるいは、カスタムDockerfileでDockerを手動インストールできます:\n\n```dockerfile\nFROM ubuntu:22.04\n# 公式のインストールスクリプトを使用してDockerをインストールする\nRUN curl -fsSL https://get.docker.com | VERSION=28.3.3 sh -\n```\n\n### ユースケース\n\n- データベース（PostgreSQL、Redis、MySQL）やその他のサービスの実行\n- コンテナ化アプリケーションのビルドとテスト\n- マイクロサービスとその依存関係のデプロイ\n- フル機能のコンテナオーケストレーションを備えた分離型開発環境の作成\n\n:::note\nDocker-in-Dockerのサンドボックスは、Dockerデーモンのオーバーヘッドにより追加のリソースを必要とします。最適なパフォーマンスのために、少なくとも2 vCPUと4GiBのメモリを割り当てることを検討してください。\n:::\n\n## デフォルトのスナップショット\n\nDaytona が使用するデフォルトのスナップショットは、`python` と `node`、それぞれの LSP に加えて、以下の `pip` 事前インストール済みパッケージを含むイメージをベースにしています:\n\n- `beautifulsoup4` (v4.13.3)\n- `django` (v5.1.7)\n- `flask` (v3.1.0)\n- `keras` (v3.9.0)\n- `matplotlib` (v3.10.1)\n- `numpy` (v2.2.3)\n- `openai` (v1.65.4)\n- `opencv-python` (v4.11.0.86)\n- `pandas` (v2.2.3)\n- `pillow` (v11.1.0)\n- `pydantic-ai` (v0.0.35)\n- `requests` (v2.32.3)\n- `scikit-learn` (v1.6.1)\n- `scipy` (v1.15.2)\n- `seaborn` (v0.13.2)\n- `SQLAlchemy` (v2.0.38)\n- `transformers` (v4.49.0)\n- `anthropic` (v0.49.0)\n- `daytona_sdk` (v0.11.1)\n- `huggingface` (v0.0.1)\n- `instructor` (v1.7.3)\n- `langchain` (v0.3.20)\n- `llama-index` (v0.12.22)\n- `ollama` (v0.4.7)"
  },
  {
    "path": "apps/docs/src/content/docs/ja/tools/api.mdx",
    "content": "---\ntitle: API\ndescription: Daytona APIで利用可能な操作のリファレンス。\n---\n\nimport Label from '@components/Label.astro'\n\n## POST /api-keys\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`201`** | APIキーが正常に作成されました。 |\n\n## GET /api-keys\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | APIキーが正常に取得されました。 |\n| **`500`** | APIキーの取得中にエラーが発生しました。 |\n\n\n## GET /api-keys/current\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）の ID を指定します |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | APIキーが正常に取得されました。 |\n\n\n## GET /api-keys/\\{name\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | いいえ | undefined | JWT と併用して 組織（Organization）の ID を指定します |\n| **`name`** | path | はい | undefined | undefined |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | APIキーが正常に取得されました。 |\n\n## DELETE /api-keys/\\{name\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`name`** | path | true | undefined | undefined |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | APIキーは正常に削除されました。 |\n\n\n## GET /organizations/invitations\n\n### 応答\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 組織の招待一覧 |\n\n\n## GET /organizations/invitations/count\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 組織の招待数 |\n\n\n## POST /organizations/invitations/\\{invitationId\\}/accept\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`invitationId`** | path | true | undefined | 招待ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 組織（Organization）の招待を正常に承諾しました |\n\n\n## POST /organizations/invitations/\\{invitationId\\}/decline\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`invitationId`** | path | true | undefined | 招待ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 組織の招待を辞退しました |\n\n\n## POST /organizations\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`201`** | 組織の作成に成功しました |\n\n## GET /organizations\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 組織のリスト |\n\n\n## GET /organizations/\\{organizationId\\}\n\n### パラメータ\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織ID |\n\n### レスポンス\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 組織の詳細 |\n\n## DELETE /organizations/\\{organizationId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | 組織を正常に削除しました |\n\n\n## GET /organizations/\\{organizationId\\}/usage\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | パス | 必須 | undefined | 組織ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 現在の利用状況の概要 |\n\n\n## PATCH /organizations/\\{organizationId\\}/quota\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | パス | 必須 | undefined | 組織ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 組織の詳細 |\n\n\n## POST /organizations/\\{organizationId\\}/leave\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | 組織から正常に退出しました |\n\n\n## POST /organizations/\\{organizationId\\}/suspend\n\n### パラメータ\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n\n### 応答\n| Status Code | Description |\n| :-------- | :---------- |\n| **`204`** | 組織の一時停止に成功 |\n\n\n## POST /organizations/\\{organizationId\\}/unsuspend\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`204`** | 組織（Organization）の一時停止を解除しました |\n\n\n## POST /organizations/\\{organizationId\\}/roles\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`201`** | 組織のロールを正常に作成しました |\n\n## GET /organizations/\\{organizationId\\}/roles\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 組織のロール一覧 |\n\n\n## PUT /organizations/\\{organizationId\\}/roles/\\{roleId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織ID |\n| **`roleId`** | path | true | undefined | ロールID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ロールを正常に更新しました |\n\n## DELETE /organizations/\\{organizationId\\}/roles/\\{roleId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織ID |\n| **`roleId`** | path | true | undefined | ロールID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | 組織のロールを正常に削除しました |\n\n\n## GET /organizations/\\{organizationId\\}/users\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 組織メンバーのリスト |\n\n\n## POST /organizations/\\{organizationId\\}/users/\\{userId\\}/role\n\n### パラメーター\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n| **`userId`** | path | true | undefined | ユーザーID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ロールを正常に更新しました |\n\n\n## POST /organizations/\\{organizationId\\}/users/\\{userId\\}/assigned-roles\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織ID（Daytona内のリソースとユーザーのグループ化、ロールや請求など） |\n| **`userId`** | path | true | undefined | ユーザーID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 割り当て／ロールを正常に更新しました |\n\n\n## DELETE /organizations/\\{organizationId\\}/users/\\{userId\\}\n\n### パラメーター\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織ID |\n| **`userId`** | path | true | undefined | ユーザーID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | 組織からユーザーを正常に削除しました |\n\n\n## POST /organizations/\\{organizationId\\}/invitations\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`201`** | 組織への招待が正常に作成されました |\n\n## GET /organizations/\\{organizationId\\}/invitations\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 未処理の組織招待の一覧 |\n\n\n## PUT /organizations/\\{organizationId\\}/invitations/\\{invitationId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織ID |\n| **`invitationId`** | path | true | undefined | 招待ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 組織の招待を正常に更新しました |\n\n\n## POST /organizations/\\{organizationId\\}/invitations/\\{invitationId\\}/cancel\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`organizationId`** | path | true | undefined | 組織（Organization）ID |\n| **`invitationId`** | path | true | undefined | 招待（Invitation）ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | 組織の招待を正常にキャンセルしました |\n\n\n## GET /users/me\n\n### 応答\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ユーザー詳細 |\n\n\n## POST /users\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`201`** |  |\n\n## GET /users\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** |  |\n\n\n## POST /users/\\{id\\}/regenerate-key-pair\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`id`** | パス | 必須 | 未定義 | 未定義 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`201`** |  |\n\n\n## GET /users/account-providers\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 利用可能なアカウントプロバイダー |\n\n\n## POST /users/linked-accounts\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | アカウントのリンクが成功しました |\n\n\n## DELETE /users/linked-accounts/\\{provider\\}/\\{providerUserId\\}\n\n### パラメーター\n| 名称 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`provider`** | path | true | undefined | undefined |\n| **`providerUserId`** | path | true | undefined | undefined |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | アカウントの連携を解除しました |\n\n\n## GET /users/\\{id\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`id`** | パス | 必須 | 未定義 | 未定義 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ユーザーの詳細 |\n\n\n## GET /sandbox\n\n### パラメータ\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定する |\n| **`verbose`** | query | false | undefined | 詳細出力を含める |\n| **`labels`** | query | false | undefined | フィルタ用の JSON エンコード済みラベル |\n\n### レスポンス\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | すべてのサンドボックス（Sandbox）の一覧 |\n\n## POST /sandbox\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定します |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | サンドボックス（Sandbox）が正常に作成されました。 |\n\n\n## GET /sandbox/\\{sandboxId\\}\n\n### パラメータ\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定 |\n| **`verbose`** | query | false | undefined | 詳細出力を含める |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n\n### レスポンス\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | サンドボックスの詳細 |\n\n## DELETE /sandbox/\\{sandboxId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n| **`force`** | query | true | undefined | 強制削除を行うかどうか |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | サンドボックスを削除しました |\n\n\n## POST /sandbox/\\{sandboxId\\}/start\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | サンドボックスを起動しました |\n\n\n## POST /sandbox/\\{sandboxId\\}/stop\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | サンドボックスを停止しました |\n\n\n## PUT /sandbox/\\{sandboxId\\}/labels\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）の ID を指定します |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ラベルを正常に置換しました |\n\n\n## POST /sandbox/\\{sandboxId\\}/backup\n\n### パラメータ\n| 名前 | ロケーション | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）の ID を指定します |\n| **`sandboxId`** | path | true | undefined | サンドボックス（隔離された一時的な実行環境）の ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | サンドボックスのバックアップの開始を受け付けました |\n\n\n## POST /sandbox/\\{sandboxId\\}/public/\\{isPublic\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n| **`isPublic`** | path | true | undefined | 設定する公開状態 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`201`** |  |\n\n\n## POST /sandbox/\\{sandboxId\\}/autostop/\\{interval\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定 |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n| **`interval`** | path | true | undefined | 自動停止（Auto-stop）の間隔（分）。0 で無効化 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 自動停止（Auto-stop）の間隔を設定しました |\n\n\n## POST /sandbox/\\{sandboxId\\}/autoarchive/\\{interval\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | いいえ | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | はい | undefined | サンドボックス（Sandbox）の ID |\n| **`interval`** | path | はい | undefined | 自動アーカイブ（Auto-archive）の間隔（分）。0 の場合は最大間隔が適用されます |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 自動アーカイブの間隔を設定しました |\n\n\n## POST /sandbox/\\{sandboxId\\}/archive\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | サンドボックス（Sandbox）をアーカイブしました |\n\n\n## GET /sandbox/\\{sandboxId\\}/ports/\\{port\\}/preview-url\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n| **`port`** | path | true | undefined | プレビューリンクの URL を取得するポート番号 |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 指定したポートのプレビューリンクの URL |\n\n\n## GET /sandbox/\\{sandboxId\\}/build-logs\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | ヘッダー | いいえ | 未定義 | JWT と併用して 組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）の ID を指定 |\n| **`sandboxId`** | パス | はい | 未定義 | サンドボックス（隔離された一時的な実行環境）の ID |\n| **`follow`** | クエリ | いいえ | 未定義 | ログストリームをフォローするかどうか |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ビルドログのストリーム |\n\n\n## POST /runners\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`201`** |  |\n\n## GET /runners\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** |  |\n\n\n## PATCH /runners/\\{id\\}/scheduling\n\n### パラメーター\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`id`** | パス | 必須 | 未定義 | 未定義 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** |  |\n\n\n## GET /runners/by-sandbox/\\{sandboxId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ランナー（サンドボックスがスケジュールおよび実行される基盤の計算ノード/ホスト）が見つかりました |\n\n\n## GET /runners/by-snapshot\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`ref`** | query | true | undefined | スナップショットの内部名 |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | スナップショットに対して見つかったランナー（サンドボックスがスケジュールおよび実行される基盤の計算ノード/ホスト） |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/project-dir\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して、組織（Organization）IDを指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | プロジェクトディレクトリを正常に取得しました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/files\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | いいえ | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | はい | undefined | なし |\n| **`path`** | query | いいえ | undefined | なし |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ファイル一覧の取得に成功 |\n\n## DELETE /toolbox/\\{sandboxId\\}/toolbox/files\nサンドボックス内のファイルを削除\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | なし |\n| **`path`** | query | true | undefined | なし |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ファイルを正常に削除しました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/files/download\nサンドボックスからファイルをダウンロード\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）IDを指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ファイルを正常にダウンロードしました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/files/find\nサンドボックス内のファイルでテキスト／パターンを検索\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）IDを指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n| **`pattern`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 検索が正常に完了しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/files/folder\nサンドボックス内にフォルダを作成\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | 未定義 |\n| **`path`** | query | true | undefined | 未定義 |\n| **`mode`** | query | true | undefined | 未定義 |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | フォルダを作成しました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/files/info\nサンドボックス内のファイル情報を取得\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ファイル情報の取得に成功 |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/files/move\nサンドボックス内のファイルを移動\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`source`** | query | true | undefined | undefined |\n| **`destination`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ファイルを正常に移動しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/files/permissions\nサンドボックス内のファイルの所有者／グループ／権限を設定\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n| **`owner`** | query | false | undefined | undefined |\n| **`group`** | query | false | undefined | undefined |\n| **`mode`** | query | false | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ファイルの権限を正常に更新しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/files/replace\nサンドボックス（隔離された一時的な実行環境）内の複数ファイルでテキスト／パターンを一括置換する\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定する |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | テキストを正常に置換しました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/files/search\nサンドボックス（隔離された一時的な実行環境）内のファイルを検索\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（組織）IDを指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n| **`pattern`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 検索が正常に完了しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/files/upload\nサンドボックス内にファイルをアップロード\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ファイルのアップロードに成功しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/files/bulk-upload\nサンドボックス内に複数ファイルをアップロード\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織 ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ファイルを正常にアップロードしました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/git/add\nファイルを Git のコミットに追加します\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して、組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ファイルを Git に正常に追加しました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/git/branches\nGit リポジトリからブランチ一覧を取得\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ブランチ一覧の取得に成功しました |\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/git/branches\nGit リポジトリにブランチを作成\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定 |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ブランチの作成に成功しました |\n\n## DELETE /toolbox/\\{sandboxId\\}/toolbox/git/branches\nGit リポジトリのブランチを削除\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ブランチを正常に削除しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/git/clone\nGitリポジトリをクローンする\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）IDを指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | リポジトリを正常にクローンしました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/git/commit\nGit リポジトリに変更をコミットします\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織 ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 変更のコミットに成功しました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/git/history\nGit リポジトリのコミット履歴を取得\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）ID を指定する |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | コミット履歴を正常に取得しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/git/pull\nリモートから変更を取得する（pull）\n\n### Parameters\n| 名称 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定する |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 変更を正常に取得しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/git/push\n変更をリモートにプッシュする\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）IDを指定する |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 変更のプッシュに成功 |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/git/checkout\ngit リポジトリでブランチまたはコミットをチェックアウトする\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定する |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ブランチを正常にチェックアウトしました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/git/status\nGit リポジトリのステータスを取得\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`path`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | Git ステータスを正常に取得しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/process/execute\nサンドボックス（隔離された一時的な実行環境）内でコマンドを同期的に実行します\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）の ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | コマンドが正常に実行されました |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/process/session\nサンドボックス内のすべてのアクティブなセッションを一覧表示します\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）IDを指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | セッションを正常に取得しました |\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/process/session\nサンドボックス（隔離された一時的な実行環境）内で新しいセッションを作成する\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）IDを指定する |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** |  |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/process/session/\\{sessionId\\}\nIDでセッションを取得する\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | いいえ | undefined | JWTと併用して組織（Organization）IDを指定します |\n| **`sandboxId`** | path | はい | undefined | undefined |\n| **`sessionId`** | path | はい | undefined | undefined |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | セッションの取得に成功しました |\n\n## DELETE /toolbox/\\{sandboxId\\}/toolbox/process/session/\\{sessionId\\}\n特定のセッションを削除します\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`sessionId`** | path | true | undefined | undefined |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | セッションを正常に削除しました |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/process/session/\\{sessionId\\}/exec\n特定のセッションでコマンドを実行する\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）IDを指定する |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`sessionId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | コマンドが正常に実行された |\n| **`202`** | コマンドを受け付け、処理中 |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/process/session/\\{sessionId\\}/command/\\{commandId\\}\nIDでセッションコマンドを取得\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織IDを指定 |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`sessionId`** | path | true | undefined | undefined |\n| **`commandId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | セッションコマンドを正常に取得 |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/process/session/\\{sessionId\\}/command/\\{commandId\\}/logs\nセッション内の特定のコマンドのログを取得します\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`sessionId`** | path | true | undefined | undefined |\n| **`commandId`** | path | true | undefined | undefined |\n| **`follow`** | query | false | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | コマンドのログストリーム |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/lsp/completions\nCompletion リクエストは、指定したカーソル位置の補完候補を算出するために、クライアントからサーバーへ送信されます。\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織 ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | OK |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/lsp/did-close\nドキュメントがクライアント側で閉じられた際に、クライアントからサーバーへ送信されるドキュメントクローズ通知です。\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | OK |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/lsp/did-open\nドキュメントのオープン通知は、新規に開いたテキストドキュメントを知らせるため、クライアントからサーバーへ送信されます。\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | OK |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/lsp/document-symbols\nドキュメントシンボルのリクエストはクライアントからサーバーに送信されます。\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`languageId`** | query | true | undefined | undefined |\n| **`pathToProject`** | query | true | undefined | undefined |\n| **`uri`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | OK |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/lsp/start\nサンドボックスのプロジェクト内で LSP（言語サーバープロトコル）サーバープロセスを開始します\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 正常 |\n\n\n## POST /toolbox/\\{sandboxId\\}/toolbox/lsp/stop\nサンドボックス内のプロジェクトで動作する LSP（言語サーバープロトコル）サーバープロセスを停止します\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | OK |\n\n\n## GET /toolbox/\\{sandboxId\\}/toolbox/lsp/workspace-symbols\nワークスペースシンボルリクエストは、クライアントからサーバーに送られ、クエリ文字列に合致するプロジェクト全体のシンボルを一覧します。\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）IDを指定します |\n| **`sandboxId`** | path | true | undefined | undefined |\n| **`languageId`** | query | true | undefined | undefined |\n| **`pathToProject`** | query | true | undefined | undefined |\n| **`query`** | query | true | undefined | undefined |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | OK |\n\n\n## POST /snapshots\n\n### Parameters\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | いいえ | undefined | JWT と併用して 組織（Organization）ID を指定します |\n\n### Responses\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | スナップショットが正常に作成されました。 |\n| **`400`** | 不正なリクエスト - タグ「:latest」のスナップショットは許可されていません |\n\n## GET /snapshots\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）のIDを指定 |\n| **`limit`** | query | false | undefined | 1ページあたりの件数 |\n| **`page`** | query | false | undefined | ページ番号 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ページネーション対応のスナップショット（Snapshot）一覧 |\n\n\n## GET /snapshots/\\{id\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）IDを指定 |\n| **`id`** | path | true | undefined | スナップショット（Snapshot）のIDまたは名前 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | スナップショット |\n| **`404`** | スナップショットが見つかりません |\n\n## DELETE /snapshots/\\{id\\}\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`id`** | path | true | undefined | スナップショット（Snapshot）ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | スナップショットを削除しました |\n\n\n## PATCH /snapshots/\\{id\\}/toggle\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）のIDを指定します |\n| **`id`** | path | true | undefined | スナップショット（Snapshot）のID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | スナップショットの状態を切り替えました |\n\n\n## PATCH /snapshots/\\{id\\}/general\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`id`** | path | true | undefined | スナップショット（Snapshot）ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | スナップショットの general ステータスが設定されました |\n\n\n## GET /snapshots/\\{id\\}/build-logs\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定 |\n| **`id`** | path | true | undefined | スナップショット（Snapshot）ID |\n| **`follow`** | query | false | undefined | ログストリームをフォローするかどうか |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** |  |\n\n\n## POST /snapshots/\\{id\\}/activate\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定します |\n| **`id`** | path | true | undefined | スナップショット（Snapshot）ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | スナップショットを正常に有効化しました。 |\n| **`400`** | 不正なリクエスト - スナップショットがすでに有効、非アクティブ状態ではない、または関連するランナー（サンドボックスがスケジュールおよび実行される基盤の計算ノード/ホスト）があります |\n| **`404`** | スナップショットが見つかりません |\n\n\n## GET /workspace\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定する |\n| **`verbose`** | query | false | undefined | 詳細出力を含める |\n| **`labels`** | query | false | undefined | フィルタに使用する JSON エンコード済みラベル |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | すべてのワークスペースの一覧 |\n\n## POST /workspace\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織IDを指定します |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ワークスペースの作成に成功しました。 |\n\n\n## GET /workspace/\\{workspaceId\\}\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）の ID を指定 |\n| **`verbose`** | query | false | undefined | 冗長な出力を含める |\n| **`workspaceId`** | path | true | undefined | ワークスペースの ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ワークスペースの詳細 |\n\n## DELETE /workspace/\\{workspaceId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定 |\n| **`workspaceId`** | path | true | undefined | ワークスペースの ID |\n| **`force`** | query | true | undefined | 未定義 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ワークスペースを削除しました |\n\n\n## POST /workspace/\\{workspaceId\\}/start\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`workspaceId`** | path | true | undefined | ワークスペースの ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ワークスペースを起動しました |\n\n\n## POST /workspace/\\{workspaceId\\}/stop\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`workspaceId`** | path | true | undefined | ワークスペースのID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ワークスペースを停止しました |\n\n\n## PUT /workspace/\\{workspaceId\\}/labels\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`workspaceId`** | path | true | undefined | ワークスペース ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ラベルを正常に置換しました |\n\n\n## POST /workspace/\\{workspaceId\\}/backup\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）のIDを指定します |\n| **`workspaceId`** | path | true | undefined | ワークスペースのID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ワークスペースのバックアップの開始を受け付けました |\n\n\n## POST /workspace/\\{workspaceId\\}/public/\\{isPublic\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）の ID を指定します |\n| **`workspaceId`** | path | true | undefined | ワークスペースの ID |\n| **`isPublic`** | path | true | undefined | 設定する公開ステータス |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`201`** |  |\n\n\n## POST /workspace/\\{workspaceId\\}/autostop/\\{interval\\}\n\n### パラメータ\n| 名前 | ロケーション | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）ID を指定します |\n| **`workspaceId`** | path | true | undefined | ワークスペースのID |\n| **`interval`** | path | true | undefined | 自動停止（サンドボックスのライフサイクルを制御する自動タイマー）の間隔（分）。0 で無効化 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 自動停止（サンドボックスのライフサイクルを制御する自動タイマー）の間隔を設定しました |\n\n\n## POST /workspace/\\{workspaceId\\}/autoarchive/\\{interval\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）のIDを指定します |\n| **`workspaceId`** | path | true | undefined | ワークスペースのID |\n| **`interval`** | path | true | undefined | 自動アーカイブ間隔（分）。0 を指定すると最大間隔が使用されます |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 自動アーカイブ間隔を設定しました |\n\n\n## POST /sandbox/\\{sandboxId\\}/autodelete/\\{interval\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定 |\n| **`sandboxId`** | path | true | undefined | サンドボックス（Sandbox）の ID |\n| **`interval`** | path | true | undefined | 自動削除の間隔（分）。負の値で無効、0 で停止時に即時削除 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | 自動削除の間隔を設定しました |\n\n\n## POST /workspace/\\{workspaceId\\}/archive\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | ヘッダー | いいえ | 未定義 | JWT と併用して組織（Organization）IDを指定します |\n| **`workspaceId`** | パス | はい | 未定義 | 未定義 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ワークスペースをアーカイブしました |\n\n\n## GET /workspace/\\{workspaceId\\}/ports/\\{port\\}/preview-url\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定 |\n| **`workspaceId`** | path | true | undefined | ワークスペース ID |\n| **`port`** | path | true | undefined | プレビューリンクを取得するポート番号 |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 指定したポートのプレビューリンク |\n\n\n## GET /workspace/\\{workspaceId\\}/build-logs\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWTと併用して組織（Organization）のIDを指定します |\n| **`workspaceId`** | path | true | undefined | ワークスペースID |\n| **`follow`** | query | false | undefined | ログストリームをフォローするかどうか |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ビルドログのストリーム |\n\n\n## GET /preview/\\{sandboxId\\}/public\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`sandboxId`** | path | true | undefined | サンドボックス（隔離された一時的な実行環境）のID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | サンドボックスの公開状態 |\n\n\n## GET /preview/\\{sandboxId\\}/validate/\\{authToken\\}\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`sandboxId`** | path | true | undefined | サンドボックスのID |\n| **`authToken`** | path | true | undefined | サンドボックスの認証トークン |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | サンドボックス認証トークンの検証結果 |\n\n\n## GET /preview/\\{sandboxId\\}/access\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`sandboxId`** | パス | 必須 | undefined | undefined |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** |  |\n\n\n## GET /volumes\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して 組織（Organization）ID を指定します |\n| **`includeDeleted`** | query | false | undefined | レスポンスに削除済みのボリューム（Volume）を含めます |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | すべてのボリューム（Volume）の一覧 |\n\n## POST /volumes\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Daytona内のリソースとユーザーのグループ化、ロールや請求など）の ID を指定します |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | ボリューム（S3互換オブジェクトストレージをバックエンドに持つFUSEベースの共有ストレージ）が正常に作成されました。 |\n\n\n## GET /volumes/\\{volumeId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）のIDを指定します |\n| **`volumeId`** | path | true | undefined | ボリューム（Volume）のID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ボリュームの詳細 |\n\n## DELETE /volumes/\\{volumeId\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Daytona 内のリソースとユーザーのグループ化、ロールや請求など）の ID を指定します |\n| **`volumeId`** | path | true | undefined | ボリューム（S3互換オブジェクトストレージをバックエンドに持つFUSEベースの共有ストレージ）の ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ボリュームは削除対象としてマークされました |\n\n\n## GET /volumes/by-name/\\{name\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`name`** | path | true | undefined | ボリューム（S3互換オブジェクトストレージをバックエンドに持つFUSEベースの共有ストレージ）の名前 |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | ボリュームの詳細 |\n\n\n## POST /docker-registry\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して、組織（Organization）のIDを指定します |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`201`** | Dockerレジストリが正常に作成されました。 |\n\n## GET /docker-registry\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | いいえ | undefined | JWT と併用して組織（Organization）ID を指定する |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | すべての Docker レジストリの一覧 |\n\n\n## GET /docker-registry/registry-push-access\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して、組織（Organization）ID を指定します |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 一時的なレジストリへのアクセス権が発行されました |\n\n\n## GET /docker-registry/\\{id\\}\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）の ID を指定します |\n| **`id`** | path | true | undefined | Docker レジストリの ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | Docker レジストリ |\n\n## PATCH /docker-registry/\\{id\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織 ID を指定します |\n| **`id`** | path | true | undefined | Docker レジストリの ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`200`** | Docker レジストリを正常に更新しました。 |\n\n## DELETE /docker-registry/\\{id\\}\n\n### パラメータ\n| 名前 | 位置 | 必須 | 型 | 説明 |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`id`** | path | true | undefined | Docker レジストリの ID |\n\n### レスポンス\n| ステータスコード | 説明 |\n| :-------- | :---------- |\n| **`204`** | Docker レジストリが正常に削除されました。 |\n\n\n## POST /docker-registry/\\{id\\}/set-default\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n| **`id`** | path | true | undefined | Docker レジストリの ID |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | Docker レジストリをデフォルトに設定しました。 |\n\n\n## GET /object-storage/push-access\n\n### Parameters\n| Name | Location | Required | Type | Description |\n| :--- | :------- | :------- | :--- | :---------- |\n| **`X-Daytona-Organization-ID`** | header | false | undefined | JWT と併用して組織（Organization）ID を指定します |\n\n### Responses\n| Status Code | Description |\n| :-------- | :---------- |\n| **`200`** | 一時的なストレージアクセスが生成されます |\n\n\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/tools/cli.mdx",
    "content": "---\ntitle: CLI\ndescription: Daytona（デイトナ）CLI で利用可能な操作のリファレンス。\nsidebar:\n  label: Daytona CLI リファレンス\n---\n\nimport Aside from '@components/Aside.astro'\nimport Label from '@components/Label.astro'\n\n`daytona` コマンドラインツールは、Daytona（デイトナ）のコア機能へのアクセスを提供し、スナップショットの管理や Daytona サンドボックスのライフサイクル管理を行えます。インストール手順は[こちら](/docs/ja/getting-started#setting-up-the-daytona-cli)をご覧ください。\n\n本リファレンスでは、`daytona` コマンドラインツールでサポートされているすべてのコマンドを、その動作の説明および対応フラグとともに一覧しています。`daytona` 実行時に `--help` または `-h` フラグを付けることで、各コマンドごとのドキュメントを参照できます。\n\n## daytona\n\nDaytona CLI\n\n```shell\ndaytona [flags]\n```\n\n**フラグ**\n| ロング | ショート | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示します |\n| `--version` | `-v` | Daytona のバージョンを表示します |\n\n## daytona autocomplete\n\nシェル環境に補完スクリプトを追加します\n\n```shell\ndaytona autocomplete [bash|zsh|fish|powershell] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n<Aside type=\"note\">\n  bash シェルを使用している場合、オートコンプリート機能をフルに利用するには bash-completion がインストールされていることを確認してください。Linux のインストール: `sudo\n          apt-get install bash-completion` macOS のインストール: `brew install\n          bash-completion`\n</Aside>\n\n## daytona docs\n\n既定のブラウザでDaytona（デイトナ）のドキュメントを開きます。\n\n```shell\ndaytona docs [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona login\n\nDaytona（デイトナ）にログイン\n\n```shell\ndaytona login [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--api-key` | | 認証に使用するAPIキー |\n| `--help` | | daytonaのヘルプ |\n\n## daytona logout\n\nDaytona（デイトナ）からログアウトします\n\n```shell\ndaytona logout [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona mcp\n\nDaytona MCPサーバー（Model Context Protocol）を管理する\n\n```shell\ndaytona mcp [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona mcp config\n\nDaytona MCPサーバー用のJSON設定を出力します\n\n```shell\ndaytona mcp config [AGENT_NAME] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona mcp init\n\nエージェントを指定して Daytona MCPサーバー を初期化します（現在サポート: claude、windsurf、cursor）\n\n```shell\ndaytona mcp init [AGENT_NAME] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona mcp start\n\nDaytona MCPサーバーを起動します\n\n```shell\ndaytona mcp start [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona organization\n\nDaytona（デイトナ）の組織を管理する\n\n```shell\ndaytona organization [flags]\n```\n\n**フラグ**\n| ロング | ショート | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona organization create\n\n新しい組織を作成し、アクティブとして設定します\n\n```shell\ndaytona organization create [ORGANIZATION_NAME] [flags]\n```\n\n**フラグ**\n| ロング | ショート | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona organization delete\n\n組織を削除する\n\n```shell\ndaytona organization delete [ORGANIZATION] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona organization list\n\nすべての組織を一覧表示します\n\n```shell\ndaytona organization list [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | 出力形式。yaml または json のいずれか |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona organization use\n\nアクティブな組織を設定する\n\n```shell\ndaytona organization use [ORGANIZATION] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona sandbox\n\nDaytona（デイトナ）のサンドボックスを管理します\n\n```shell\ndaytona sandbox [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona sandbox create\n\n新しいサンドボックスを作成\n\n```shell\ndaytona sandbox create [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--auto-archive` | | 自動アーカイブの間隔（分）（0 は最大の間隔が使用されます） |\n| `--auto-delete` | | 自動削除の間隔（分）（負の値で無効、0 は停止後に即時削除） |\n| `--auto-stop` | | 自動停止の間隔（分）（0 は無効） |\n| `--class` | | サンドボックスのクラス種別（small、medium、large） |\n| `--context` | `-c` | ビルドコンテキストに含めるファイルまたはディレクトリ（複数回指定可） |\n| `--cpu` | | サンドボックスに割り当てる CPU コア数 |\n| `--disk` | | サンドボックスに割り当てるディスク容量（GB） |\n| `--dockerfile` | `-f` | サンドボックスのスナップショット用 Dockerfile のパス |\n| `--env` | `-e` | 環境変数（形式: KEY=VALUE） |\n| `--gpu` | | サンドボックスに割り当てる GPU ユニット |\n| `--label` | `-l` | ラベル（形式: KEY=VALUE） |\n| `--memory` | | サンドボックスに割り当てるメモリ（MB） |\n| `--public` | | サンドボックスを公開アクセス可能にする |\n| `--snapshot` | | サンドボックスに使用するスナップショット |\n| `--target` | | ターゲット（リージョン）（eu, us） |\n| `--user` | | サンドボックスに関連付けるユーザー |\n| `--volume` | `-v` | マウントするボリューム（形式: VOLUME\\_NAME:MOUNT\\_PATH） |\n| `--help` | | daytona のヘルプ |\n\n## daytona sandbox delete\n\nサンドボックスを削除\n\n```shell\ndaytona sandbox delete [SANDBOX_ID] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--all` | `-a` | すべてのサンドボックスを削除 |\n| `--force` | `-f` | 強制的に削除 |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona sandbox info\n\nサンドボックス情報を取得する\n\n```shell\ndaytona sandbox info [SANDBOX_ID] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | 出力形式。yaml または json のいずれかを指定します |\n| `--verbose` | `-v` | 詳細な出力を含める |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona sandbox list\n\nサンドボックスを一覧表示します\n\n```shell\ndaytona sandbox list [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | 出力形式。yaml または json のいずれか |\n| `--limit` | `-l` | 1ページあたりの最大件数 |\n| `--page` | `-p` | ページ番号（1から開始） |\n| `--verbose` | `-v` | 冗長な出力を含める |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona sandbox start\n\nサンドボックスを起動する\n\n```shell\ndaytona sandbox start [SANDBOX_ID] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--all` | `-a` | すべてのサンドボックスを起動する |\n| `--help` | | daytona のヘルプ |\n\n## daytona sandbox stop\n\nサンドボックスを停止する\n\n```shell\ndaytona sandbox stop [SANDBOX_ID] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--all` | `-a` | すべてのサンドボックスを停止 |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona snapshot\n\nDaytona（デイトナ）のスナップショットを管理する\n\n```shell\ndaytona snapshot [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona snapshot create\n\nスナップショットを作成\n\n```shell\ndaytona snapshot create [SNAPSHOT] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--context` | `-c` | ビルドコンテキストに含めるファイルまたはディレクトリ（複数回指定可） |\n| `--cpu` | | サンドボックスに割り当てる CPU コア数（既定: 1） |\n| `--disk` | | サンドボックスに割り当てるディスク容量（GB）（既定: 3） |\n| `--dockerfile` | `-f` | ビルド対象の Dockerfile のパス |\n| `--entrypoint` | `-e` | スナップショットのエントリーポイントコマンド |\n| `--image` | `-i` | スナップショットのイメージ名 |\n| `--memory` | | サンドボックスに割り当てるメモリ容量（GB）（既定: 1） |\n| `--help` | | daytona のヘルプ |\n\n## daytona snapshot delete\n\nスナップショットを削除します\n\n```shell\ndaytona snapshot delete [SNAPSHOT_ID] [flags]\n```\n\n**フラグ**\n| ロング | ショート | 説明 |\n| :--- | :---- | :---------- |\n| `--all` | `-a` | すべてのスナップショットを削除します |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona snapshot list\n\nすべてのスナップショットを一覧表示します\n\n```shell\ndaytona snapshot list [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | 出力形式。yaml または json のいずれか |\n| `--limit` | `-l` | 1ページあたりの最大件数 |\n| `--page` | `-p` | ページネーション用のページ番号（1から） |\n| `--help` | | daytona のヘルプ |\n\n## daytona snapshot push\n\nローカルのスナップショットをプッシュします\n\n```shell\ndaytona snapshot push [SNAPSHOT] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--cpu` | | サンドボックスに割り当てるCPUコア数（デフォルト: 1） |\n| `--disk` | | サンドボックスに割り当てるディスク容量（GB、デフォルト: 3） |\n| `--entrypoint` | `-e` | イメージのエントリポイントコマンド |\n| `--memory` | | サンドボックスに割り当てるメモリ容量（GB、デフォルト: 1） |\n| `--name` | `-n` | スナップショット名を指定 |\n| `--help` | | daytonaのヘルプ |\n\n## daytona version\n\nバージョン番号を表示します\n\n```shell\ndaytona version [flags]\n```\n\n**フラグ**\n| ロング | ショート | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona volume\n\nDaytona（デイトナ）のボリュームを管理します\n\n```shell\ndaytona volume [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona volume create\n\nボリュームを作成します\n\n```shell\ndaytona volume create [NAME] [flags]\n```\n\n**フラグ**\n| ロング | ショート | 説明 |\n| :--- | :---- | :---------- |\n| `--size` | `-s` | ボリュームのサイズ（GB） |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona volume delete\n\nボリュームを削除します\n\n```shell\ndaytona volume delete [VOLUME_ID] [flags]\n```\n\n**フラグ**\n| Long | Short | Description |\n| :--- | :---- | :---------- |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona volume get\n\nボリュームの詳細を取得する\n\n```shell\ndaytona volume get [VOLUME_ID] [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | 出力形式。yaml または json のいずれか |\n| `--help` | | daytona のヘルプを表示 |\n\n## daytona volume list\n\nすべてのボリュームを一覧表示します\n\n```shell\ndaytona volume list [flags]\n```\n\n**フラグ**\n| Long | Short | 説明 |\n| :--- | :---- | :---------- |\n| `--format` | `-f` | 出力形式。yaml または json のいずれか |\n| `--help` | | daytona のヘルプを表示 |"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/charts.mdx",
    "content": "---\ntitle: \"チャート\"\nhideTitleOnPage: true\n---\n\n\n## ChartType\n\nチャートの種類\n\n**列挙メンバー**:\n\n- `BAR`（\"bar\"）\n- `LINE`（\"line\"）\n- `PIE`（\"pie\"）\n- `SCATTER`（\"scatter\"）\n- `UNKNOWN`（\"unknown\"）\n\n## parseChart()\n\n```ts\nfunction parseChart(data: any): Chart\n```\n\n**パラメータ**:\n\n- `data` _any_\n\n\n**戻り値**:\n\n- `Chart`\n\n***\n\n\n## BarChart\n\n```ts\ntype BarChart = Chart2D & {\n  elements: BarData[];\n  type: BAR;\n};\n```\n\nメタデータを含む棒グラフを表します。\n\n**型定義**:\n\n- `elements` _BarData\\[\\]_ - 棒グラフの要素\n- `type` _BAR_ - グラフの種類\n    \n\n\n## BarData\n\n```ts\ntype BarData = {\n  group: string;\n  label: string;\n  value: string;\n};\n```\n\n棒グラフの1本のバーを表します。\n\n**型定義**:\n\n- `group` _string_ - バーの属するグループ\n- `label` _string_ - バーのラベル\n- `value` _string_ - バーの値\n    \n\n\n## BoxAndWhiskerChart\n\n```ts\ntype BoxAndWhiskerChart = Chart2D & {\n  elements: BoxAndWhiskerData[];\n  type: BOX_AND_WHISKER;\n};\n```\n\nメタデータを含む箱ひげ図を表します。\n\n**型定義**:\n\n- `elements` _BoxAndWhiskerData\\[\\]_ - 図の箱ひげ要素\n- `type` _BOX\\_AND\\_WHISKER_ - 図の種類\n    \n\n\n## BoxAndWhiskerData\n\n```ts\ntype BoxAndWhiskerData = {\n  first_quartile: number;\n  label: string;\n  max: number;\n  median: number;\n  min: number;\n  outliers: number[];\n};\n```\n\n箱ひげ図の箱ひげを表します。\n\n**型定義**:\n\n- `first_quartile` _number_ - 箱ひげの第1四分位数\n- `label` _string_ - 箱ひげのラベル\n- `max` _number_ - 箱ひげの第3四分位数\n- `median` _number_ - 箱ひげの中央値\n- `min` _number_ - 箱ひげの最小値\n- `outliers` _number[]_\n\n\n## チャート\n\n```ts\ntype Chart = {\n  elements: any[];\n  png: string;\n  title: string;\n  type: ChartType;\n};\n```\n\nmatplotlib のメタデータを含むチャートを表します。\n\n**型定義**:\n\n- `elements` _any\\[\\]_ - チャートの要素\n- `png?` _string_ - base64 でエンコードされたチャートの PNG 表現\n- `title` _string_ - チャートのタイトル\n- `type` _ChartType_ - チャートのタイプ\n    \n\n\n## Chart2D\n\n```ts\ntype Chart2D = Chart & {\n  x_label: string;\n  y_label: string;\n};\n```\n\nメタデータを持つ2次元チャートを表します。\n\n**型宣言**:\n\n- `x\\_label?` _string_ - x軸のラベル\n- `y\\_label?` _string_ - y軸のラベル\n    \n\n\n## CompositeChart\n\n```ts\ntype CompositeChart = Chart & {\n  elements: Chart[];\n  type: COMPOSITE_CHART;\n};\n```\n\nメタデータを含む合成チャートを表します。\n\n**型宣言**:\n\n- `elements` _Chart\\[\\]_ - 合成チャートを構成するチャート群\n- `type` _COMPOSITE\\_CHART_ - チャートのタイプ\n    \n\n\n## LineChart\n\n```ts\ntype LineChart = PointChart & {\n  type: LINE;\n};\n```\n\nメタデータを含む折れ線グラフを表します。\n\n**型定義**:\n\n- `type` _LINE_ - チャートのタイプ\n    \n\n\n## PieChart\n\n```ts\ntype PieChart = Chart & {\n  elements: PieData[];\n  type: PIE;\n};\n```\n\nメタデータを含む円グラフを表します。\n\n**型定義**:\n\n- `elements` _PieData\\[\\]_ - グラフの各扇形（スライス）\n- `type` _PIE_ - グラフのタイプ\n    \n\n\n## PieData\n\n```ts\ntype PieData = {\n  angle: number;\n  label: string;\n  radius: number;\n};\n```\n\n円グラフのスライス（扇形）を表します。\n\n**型定義**:\n\n- `angle` _number_ - スライスの角度\n- `label` _string_ - スライスのラベル\n- `radius` _number_ - スライスの半径\n    \n\n\n## PointChart\n\n```ts\ntype PointChart = Chart2D & {\n  elements: PointData[];\n  x_scale: string;\n  x_tick_labels: string[];\n  x_ticks: (number | string)[];\n  y_scale: string;\n  y_tick_labels: string[];\n  y_ticks: (number | string)[];\n};\n```\n\nメタデータを含む点グラフを表します。\n\n**型定義**:\n\n- `elements` _PointData\\[\\]_ - グラフの点\n- `x\\_scale` _string_ - x軸のスケール\n- `x\\_tick\\_labels` _string\\[\\]_ - x軸の目盛ラベル\n- `x\\_ticks` _\\(number \\| string\\)\\[\\]_ - x軸の目盛\n- `y\\_scale` _string_ - y軸のスケール\n- `y\\_tick\\_labels` _string\\[\\]_ - y軸の目盛ラベル\n- `y\\_ticks` _\\(number \\| string\\)\\[\\]_ - y軸の目盛\n    \n\n\n## PointData\n\n```ts\ntype PointData = {\n  label: string;\n  points: [number | string, number | string][];\n};\n```\n\n2Dチャートのデータ点を表します。\n\n**型宣言**:\n\n- `label` _string_ - 点のラベル\n- `points` _\\[number \\| string, number \\| string\\]\\[\\]_ - チャートの座標点一覧\n    \n\n\n## ScatterChart\n\n```ts\ntype ScatterChart = PointChart & {\n  type: SCATTER;\n};\n```\n\nメタデータを持つ散布図を表します。\n\n**型宣言**:\n\n- `type` _SCATTER_ - チャートの種類\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/computer-use.mdx",
    "content": "---\ntitle: \"Computer Use\"\nhideTitleOnPage: true\n---\n\n\n## ComputerUse\n\nデスクトップ環境と対話するためのコンピュータ操作機能。\n\n**プロパティ**:\n\n- `display` _Display_ - ディスプレイ操作インターフェース\n- `keyboard` _Keyboard_ - キーボード操作インターフェース\n- `mouse` _Mouse_ - マウス操作インターフェース\n- `screenshot` _Screenshot_ - スクリーンショット操作インターフェース\n    \n\n\n\n\nサンドボックス（Daytonaで管理される隔離された一時的な計算環境）内でのデスクトップ操作を自動化するために、マウス、キーボード、スクリーンショット、ディスプレイの各操作にアクセスできます。\n\n### コンストラクタ\n\n#### new ComputerUse()\n\n```ts\nnew ComputerUse(sandboxId: string, toolboxApi: ToolboxApi): ComputerUse\n```\n\n**パラメータ**:\n\n- `sandboxId` _string_\n- `toolboxApi` _ToolboxApi_\n\n\n**戻り値**:\n\n- `ComputerUse`\n\n### メソッド\n\n#### getProcessErrors()\n\n```ts\ngetProcessErrors(processName: string): Promise<ProcessErrorsResponse>\n```\n\n特定のVNCプロセスのエラーログを取得します\n\n**パラメータ**:\n\n- `processName` _string_ - エラーログを取得するプロセス名\n\n\n**戻り値**:\n\n- `Promise<ProcessErrorsResponse>` - プロセスのエラーログ\n\n**例:**\n\n```typescript\nconst errorsResp = await sandbox.computerUse.getProcessErrors('x11vnc');\nconsole.log('X11VNC errors:', errorsResp.errors);\n```\n\n***\n\n#### getProcessLogs()\n\n```ts\ngetProcessLogs(processName: string): Promise<ProcessLogsResponse>\n```\n\n特定のVNCプロセスのログを取得します\n\n**パラメータ**:\n\n- `processName` _string_ - ログを取得するプロセス名\n\n\n**戻り値**:\n\n- `Promise<ProcessLogsResponse>` - プロセスのログ\n\n**例:**\n\n```typescript\nconst logsResp = await sandbox.computerUse.getProcessLogs('novnc');\nconsole.log('NoVNC logs:', logsResp.logs);\n```\n\n***\n\n#### getProcessStatus()\n\n```ts\ngetProcessStatus(processName: string): Promise<ProcessStatusResponse>\n```\n\n特定のVNCプロセスのステータスを取得します\n\n**パラメータ**:\n\n- `processName` _string_ - 確認するプロセス名\n\n\n**戻り値**:\n\n- `Promise<ProcessStatusResponse>` - 特定のプロセスに関するステータス情報\n\n**例:**\n\n```typescript\nconst xvfbStatus = await sandbox.computerUse.getProcessStatus('xvfb');\nconst noVncStatus = await sandbox.computerUse.getProcessStatus('novnc');\n```\n\n***\n\n#### getStatus()\n\n```ts\ngetStatus(): Promise<ComputerUseStatusResponse>\n```\n\nすべてのコンピュータ操作プロセスのステータスを取得します\n\n**戻り値**:\n\n- `Promise<ComputerUseStatusResponse>` - すべてのVNCデスクトッププロセスに関するステータス情報\n\n**例:**\n\n```typescript\nconst status = await sandbox.computerUse.getStatus();\nconsole.log('Computer use status:', status.status);\n```\n\n***\n\n#### restartProcess()\n\n```ts\nrestartProcess(processName: string): Promise<ProcessRestartResponse>\n```\n\n特定のVNCプロセスを再起動します\n\n**パラメータ**:\n\n- `processName` _string_ - 再起動するプロセス名\n\n\n**戻り値**:\n\n- `Promise<ProcessRestartResponse>` - プロセス再起動のレスポンス\n\n**例:**\n\n```typescript\nconst result = await sandbox.computerUse.restartProcess('xfce4');\nconsole.log('XFCE4 process restarted:', result.message);\n```\n\n***\n\n#### start()\n\n```ts\nstart(): Promise<ComputerUseStartResponse>\n```\n\nすべてのコンピュータ操作プロセス（Xvfb、xfce4、x11vnc、novnc）を開始します\n\n**戻り値**:\n\n- `Promise<ComputerUseStartResponse>` - コンピュータ操作の開始レスポンス\n\n**例:**\n\n```typescript\nconst result = await sandbox.computerUse.start();\nconsole.log('Computer use processes started:', result.message);\n```\n\n***\n\n#### stop()\n\n```ts\nstop(): Promise<ComputerUseStopResponse>\n```\n\nすべてのコンピュータ操作プロセスを停止します\n\n**戻り値**:\n\n- `Promise<ComputerUseStopResponse>` - コンピュータ操作の停止レスポンス\n\n**例:**\n\n```typescript\nconst result = await sandbox.computerUse.stop();\nconsole.log('Computer use processes stopped:', result.message);\n```\n## Display\n\nコンピュータ操作機能のためのディスプレイ操作\n\n### コンストラクタ\n\n#### new Display()\n\n```ts\nnew Display(sandboxId: string, toolboxApi: ToolboxApi): Display\n```\n\n**パラメータ**:\n\n- `sandboxId` _string_\n- `toolboxApi` _ToolboxApi_\n\n\n**戻り値**:\n\n- `Display`\n\n### メソッド\n\n#### getInfo()\n\n```ts\ngetInfo(): Promise<DisplayInfoResponse>\n```\n\nディスプレイに関する情報を取得します\n\n**戻り値**:\n\n- `Promise<DisplayInfoResponse>` - プライマリディスプレイおよび利用可能なすべてのディスプレイを含むディスプレイ情報\n\n**例:**\n\n```typescript\nconst info = await sandbox.computerUse.display.getInfo();\nconsole.log(`Primary display: ${info.primary_display.width}x${info.primary_display.height}`);\nconsole.log(`Total displays: ${info.total_displays}`);\ninfo.displays.forEach((display, index) => {\n  console.log(`Display ${index}: ${display.width}x${display.height} at ${display.x},${display.y}`);\n});\n```\n\n***\n\n#### getWindows()\n\n```ts\ngetWindows(): Promise<WindowsResponse>\n```\n\n開いているウィンドウの一覧を取得します\n\n**戻り値**:\n\n- `Promise<WindowsResponse>` - IDとタイトルを含む開いているウィンドウの一覧\n\n**例:**\n\n```typescript\nconst windows = await sandbox.computerUse.display.getWindows();\nconsole.log(`Found ${windows.count} open windows:`);\nwindows.windows.forEach(window => {\n  console.log(`- ${window.title} (ID: ${window.id})`);\n});\n```\n\n***\n\n\n## キーボード\n\nコンピュータ操作機能のためのキーボード操作\n\n### コンストラクター\n\n#### new Keyboard()\n\n```ts\nnew Keyboard(sandboxId: string, toolboxApi: ToolboxApi): Keyboard\n```\n\n**パラメータ**:\n\n- `sandboxId` _string_\n- `toolboxApi` _ToolboxApi_\n\n\n**戻り値**:\n\n- `Keyboard`\n\n### メソッド\n\n#### hotkey()\n\n```ts\nhotkey(keys: string): Promise<void>\n```\n\nホットキーの組み合わせを送信します\n\n**パラメータ**:\n\n- `keys` _string_ - ホットキーの組み合わせ（例: 'ctrl+c', 'alt+tab', 'cmd+shift+t'）\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**スロー**:\n\nホットキー操作に失敗した場合\n\n**例:**\n\n```typescript\n// Copy\ntry {\n  await sandbox.computerUse.keyboard.hotkey('ctrl+c');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// Paste\ntry {\n  await sandbox.computerUse.keyboard.hotkey('ctrl+v');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// Alt+Tab\ntry {\n  await sandbox.computerUse.keyboard.hotkey('alt+tab');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n```\n\n***\n\n#### press()\n\n```ts\npress(key: string, modifiers?: string[]): Promise<void>\n```\n\n必要に応じて修飾キーと併せてキーを押下します\n\n**パラメータ**:\n\n- `key` _string_ - 押下するキー（例: 'Enter', 'Escape', 'Tab', 'a', 'A')\n- `modifiers?` _string\\[\\] = \\[\\]_ - 修飾キー（'ctrl', 'alt', 'meta', 'shift'）\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**スロー**:\n\nキー押下操作に失敗した場合\n\n**例:**\n\n```typescript\n// Press Enter\ntry {\n  await sandbox.computerUse.keyboard.press('Return');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// Press Ctrl+C\ntry {\n  await sandbox.computerUse.keyboard.press('c', ['ctrl']);\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// Press Ctrl+Shift+T\ntry {\n  await sandbox.computerUse.keyboard.press('t', ['ctrl', 'shift']);\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n```\n\n***\n\n#### type()\n\n```ts\ntype(text: string, delay?: number): Promise<void>\n```\n\n指定したテキストを入力します\n\n**パラメータ**:\n\n- `text` _string_ - 入力するテキスト\n- `delay?` _number_ - 文字間の遅延（ミリ秒）\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**スロー**:\n\n入力操作に失敗した場合\n\n**例:**\n\n```typescript\ntry {\n  await sandbox.computerUse.keyboard.type('Hello, World!');\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n\n// With delay between characters\ntry {\n  await sandbox.computerUse.keyboard.type('Slow typing', 100);\n  console.log('Operation success');\n} catch (e) {\n  console.log('Operation failed:', e);\n}\n```\n\n***\n\n\n## Mouse\n\nコンピュータ操作（Computer Use）機能におけるマウス操作\n\n### Constructors\n\n#### new Mouse()\n\n```ts\nnew Mouse(sandboxId: string, toolboxApi: ToolboxApi): Mouse\n```\n\n**Parameters**:\n\n- `sandboxId` _string_\n- `toolboxApi` _ToolboxApi_\n\n\n**Returns**:\n\n- `Mouse`\n\n### Methods\n\n#### click()\n\n```ts\nclick(\n   x: number, \n   y: number, \n   button?: string, \ndouble?: boolean): Promise<MouseClickResponse>\n```\n\n指定した座標でマウスクリックを実行します\n\n**Parameters**:\n\n- `x` _number_ - クリック先のx座標\n- `y` _number_ - クリック先のy座標\n- `button?` _string = 'left'_ - 使用するマウスボタン（'left'、'right'、'middle'）\n- `double?` _boolean = false_ - ダブルクリックを行うかどうか\n\n\n**Returns**:\n\n- `Promise<MouseClickResponse>` - クリック操作の結果\n\n**Example:**\n\n```typescript\n// Single left click\nconst result = await sandbox.computerUse.mouse.click(100, 200);\n\n// Double click\nconst doubleClick = await sandbox.computerUse.mouse.click(100, 200, 'left', true);\n\n// Right click\nconst rightClick = await sandbox.computerUse.mouse.click(100, 200, 'right');\n```\n\n***\n\n#### drag()\n\n```ts\ndrag(\n   startX: number, \n   startY: number, \n   endX: number, \n   endY: number, \nbutton?: string): Promise<MouseDragResponse>\n```\n\n開始座標から終了座標までドラッグします\n\n**Parameters**:\n\n- `startX` _number_ - 開始x座標\n- `startY` _number_ - 開始y座標\n- `endX` _number_ - 終了x座標\n- `endY` _number_ - 終了y座標\n- `button?` _string = 'left'_ - ドラッグに使用するマウスボタン\n\n\n**Returns**:\n\n- `Promise<MouseDragResponse>` - ドラッグ操作の結果\n\n**Example:**\n\n```typescript\nconst result = await sandbox.computerUse.mouse.drag(50, 50, 150, 150);\nconsole.log(`Dragged from ${result.from.x},${result.from.y} to ${result.to.x},${result.to.y}`);\n```\n\n***\n\n#### getPosition()\n\n```ts\ngetPosition(): Promise<MousePosition>\n```\n\n現在のマウスカーソル位置を取得します\n\n**Returns**:\n\n- `Promise<MousePosition>` - x座標とy座標を含む現在のマウス位置\n\n**Example:**\n\n```typescript\nconst position = await sandbox.computerUse.mouse.getPosition();\nconsole.log(`Mouse is at: ${position.x}, ${position.y}`);\n```\n\n***\n\n#### move()\n\n```ts\nmove(x: number, y: number): Promise<MouseMoveResponse>\n```\n\n指定した座標にマウスカーソルを移動します\n\n**Parameters**:\n\n- `x` _number_ - 移動先のx座標\n- `y` _number_ - 移動先のy座標\n\n\n**Returns**:\n\n- `Promise<MouseMoveResponse>` - 移動操作の結果\n\n**Example:**\n\n```typescript\nconst result = await sandbox.computerUse.mouse.move(100, 200);\nconsole.log(`Mouse moved to: ${result.x}, ${result.y}`);\n```\n\n***\n\n#### scroll()\n\n```ts\nscroll(\n   x: number, \n   y: number, \n   direction: \"up\" | \"down\", \namount?: number): Promise<boolean>\n```\n\n指定した座標でマウスホイールをスクロールします\n\n**Parameters**:\n\n- `x` _number_ - スクロール先のx座標\n- `y` _number_ - スクロール先のy座標\n- `direction` _スクロール方向_ - `\"up\"` | `\"down\"`\n- `amount?` _number = 1_ - スクロール量\n\n\n**Returns**:\n\n- `Promise<boolean>` - スクロール操作が成功したかどうか\n\n**Example:**\n\n```typescript\n// Scroll up\nconst scrollUp = await sandbox.computerUse.mouse.scroll(100, 200, 'up', 3);\n\n// Scroll down\nconst scrollDown = await sandbox.computerUse.mouse.scroll(100, 200, 'down', 5);\n```\n\n***\n\n\n## スクリーンショット\n\nコンピュータ操作機能におけるスクリーンショット操作\n\n### コンストラクタ\n\n#### new Screenshot()\n\n```ts\nnew Screenshot(sandboxId: string, toolboxApi: ToolboxApi): Screenshot\n```\n\n**パラメータ**:\n\n- `sandboxId` _string_\n- `toolboxApi` _ToolboxApi_\n\n\n**戻り値**:\n\n- `Screenshot`\n\n### メソッド\n\n#### takeCompressed()\n\n```ts\ntakeCompressed(options?: ScreenshotOptions): Promise<CompressedScreenshotResponse>\n```\n\n画面全体の圧縮スクリーンショットを取得します\n\n**パラメータ**:\n\n- `options?` _ScreenshotOptions = {}_ - 圧縮および表示のオプション\n\n\n**戻り値**:\n\n- `Promise<CompressedScreenshotResponse>` - 圧縮スクリーンショットのデータ\n\n**例:**\n\n```typescript\n// 既定の圧縮\nconst screenshot = await sandbox.computerUse.screenshot.takeCompressed();\n\n// 高品質 JPEG\nconst jpeg = await sandbox.computerUse.screenshot.takeCompressed({\n  format: 'jpeg',\n  quality: 95,\n  showCursor: true\n});\n\n// 縮小した PNG\nconst scaled = await sandbox.computerUse.screenshot.takeCompressed({\n  format: 'png',\n  scale: 0.5\n});\n```\n\n***\n\n#### takeCompressedRegion()\n\n```ts\ntakeCompressedRegion(region: ScreenshotRegion, options?: ScreenshotOptions): Promise<CompressedScreenshotResponse>\n```\n\n特定の領域の圧縮スクリーンショットを取得します\n\n**パラメータ**:\n\n- `region` _ScreenshotRegion_ - 取得対象の領域\n- `options?` _ScreenshotOptions = {}_ - 圧縮および表示のオプション\n\n\n**戻り値**:\n\n- `Promise<CompressedScreenshotResponse>` - 圧縮スクリーンショットのデータ\n\n**例:**\n\n```typescript\nconst region = { x: 0, y: 0, width: 800, height: 600 };\nconst screenshot = await sandbox.computerUse.screenshot.takeCompressedRegion(region, {\n  format: 'webp',\n  quality: 80,\n  showCursor: true\n});\nconsole.log(`Compressed size: ${screenshot.size_bytes} bytes`);\n```\n\n***\n\n#### takeFullScreen()\n\n```ts\ntakeFullScreen(showCursor?: boolean): Promise<ScreenshotResponse>\n```\n\n画面全体のスクリーンショットを取得します\n\n**パラメータ**:\n\n- `showCursor?` _boolean = false_ - スクリーンショットにカーソルを表示するかどうか\n\n\n**戻り値**:\n\n- `Promise<ScreenshotResponse>` - 画像を base64 でエンコードしたスクリーンショットデータ\n\n**例:**\n\n```typescript\nconst screenshot = await sandbox.computerUse.screenshot.takeFullScreen();\nconsole.log(`Screenshot size: ${screenshot.width}x${screenshot.height}`);\n\n// カーソルを表示する場合\nconst withCursor = await sandbox.computerUse.screenshot.takeFullScreen(true);\n```\n\n***\n\n#### takeRegion()\n\n```ts\ntakeRegion(region: ScreenshotRegion, showCursor?: boolean): Promise<RegionScreenshotResponse>\n```\n\n特定の領域のスクリーンショットを取得します\n\n**パラメータ**:\n\n- `region` _ScreenshotRegion_ - 取得対象の領域\n- `showCursor?` _boolean = false_ - スクリーンショットにカーソルを表示するかどうか\n\n\n**戻り値**:\n\n- `Promise<RegionScreenshotResponse>` - 画像を base64 でエンコードしたスクリーンショットデータ\n\n**例:**\n\n```typescript\nconst region = { x: 100, y: 100, width: 300, height: 200 };\nconst screenshot = await sandbox.computerUse.screenshot.takeRegion(region);\nconsole.log(`Captured region: ${screenshot.region.width}x${screenshot.region.height}`);\n```\n\n***\n\n\n## ScreenshotOptions\n\nスクリーンショット圧縮オプション用のインターフェース\n\n**プロパティ**:\n\n- `format?` _string_\n- `quality?` _number_\n- `scale?` _number_\n- `showCursor?` _boolean_\n## ScreenshotRegion\n\nスクリーンショット操作で使用される領域座標のインターフェース\n\n**プロパティ**:\n\n- `height` _number_\n- `width` _number_\n- `x` _number_\n- `y` _number_"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/daytona.mdx",
    "content": "---\ntitle: \"Daytona\"\nhideTitleOnPage: true\n---\n\n\n## Daytona\n\nDaytona API と対話するためのメインクラス。\nDaytona サンドボックスの作成、管理、操作のためのメソッドを提供します。\n明示的な設定または環境変数を使用して初期化できます。\n\n**プロパティ**:\n\n- `snapshot` _SnapshotService_ - Daytona スナップショットを管理するサービス\n- `volume` _VolumeService_ - Daytona ボリュームを管理するサービス\n    \n\n\n\n\n**例:**\n\n```ts\n// Using environment variables\n// Uses DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET\nconst daytona = new Daytona();\nconst sandbox = await daytona.create();\n```\n\n```ts\n// Using explicit configuration\nconst config: DaytonaConfig = {\n    apiKey: \"your-api-key\",\n    apiUrl: \"https://your-api.com\",\n    target: \"us\"\n};\nconst daytona = new Daytona(config);\n\n@class\n```\n\n### コンストラクター\n\n#### new Daytona()\n\n```ts\nnew Daytona(config?: DaytonaConfig): Daytona\n```\n\n新しい Daytona クライアントインスタンスを作成します。\n\n**パラメータ**:\n\n- `config?` _DaytonaConfig_ - 設定オプション\n\n\n**戻り値**:\n\n- `Daytona`\n\n**スロー**:\n\n- `DaytonaError` - API キーが指定されていない場合\n\n### メソッド\n\n#### create()\n\n##### 呼び出しシグネチャ\n\n```ts\ncreate(params?: CreateSandboxFromSnapshotParams, options?: {\n  timeout: number;\n}): Promise<Sandbox>\n```\n\n指定済みまたはデフォルトのスナップショットからサンドボックスを作成します。言語、イメージ、環境変数、ボリュームなど、さまざまなパラメータを指定できます。\n\n**パラメータ**:\n\n- `params?` _CreateSandboxFromSnapshotParams_ - スナップショットからサンドボックスを作成するためのパラメータ\n- `options?` _作成処理のオプション_\n- `timeout?` _number_ - タイムアウト（秒）（0 はタイムアウトなし、デフォルトは 60）\n\n**戻り値**:\n\n- `Promise<Sandbox>` - 作成されたサンドボックスインスタンス\n\n**例:**\n\n```ts\nconst sandbox = await daytona.create();\n```\n\n```ts\n// Create a custom sandbox\nconst params: CreateSandboxFromSnapshotParams = {\n    language: 'typescript',\n    snapshot: 'my-snapshot-id',\n    envVars: {\n        NODE_ENV: 'development',\n        DEBUG: 'true'\n    },\n    autoStopInterval: 60,\n    autoArchiveInterval: 60,\n    autoDeleteInterval: 120\n};\nconst sandbox = await daytona.create(params, { timeout: 100 });\n```\n\n##### 呼び出しシグネチャ\n\n```ts\ncreate(params?: CreateSandboxFromImageParams, options?: {\n  onSnapshotCreateLogs: (chunk: string) => void;\n  timeout: number;\n}): Promise<Sandbox>\n```\n\nレジストリで利用可能な指定イメージ、または宣言的 Daytona イメージからサンドボックスを作成します。リソース、言語、イメージ、環境変数、ボリュームなど、さまざまなパラメータを指定できます。Daytona は提供されたイメージからスナップショットを作成し、それを用いてサンドボックスを作成します。\n\n**パラメータ**:\n\n- `params?` _CreateSandboxFromImageParams_ - イメージからサンドボックスを作成するためのパラメータ\n- `options?` _作成処理のオプション_\n- `onSnapshotCreateLogs?` _\\(chunk: string\\) =\\> void_ - スナップショット作成ログを処理するコールバック関数\n- `timeout?` _number_ - タイムアウト（秒）（0 はタイムアウトなし、デフォルトは 60）\n\n**戻り値**:\n\n- `Promise<Sandbox>` - 作成されたサンドボックスインスタンス\n\n**例:**\n\n```ts\nconst sandbox = await daytona.create({ image: 'debian:12.9' }, { timeout: 90, onSnapshotCreateLogs: console.log });\n```\n\n```ts\n// Create a custom sandbox\nconst image = Image.base('alpine:3.18').pipInstall('numpy');\nconst params: CreateSandboxFromImageParams = {\n    language: 'typescript',\n    image,\n    envVars: {\n        NODE_ENV: 'development',\n        DEBUG: 'true'\n    },\n    resources: {\n        cpu: 2,\n        memory: 4 // 4GB RAM\n    },\n    autoStopInterval: 60,\n    autoArchiveInterval: 60,\n    autoDeleteInterval: 120\n};\nconst sandbox = await daytona.create(params, { timeout: 100, onSnapshotCreateLogs: console.log });\n```\n\n***\n\n#### delete()\n\n```ts\ndelete(sandbox: Sandbox, timeout: number): Promise<void>\n```\n\nサンドボックスを削除します。\n\n**パラメータ**:\n\n- `sandbox` _Sandbox_ - 削除するサンドボックス\n- `timeout` _number = 60_ - タイムアウト（秒）（0 はタイムアウトなし、デフォルトは 60）\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\nawait daytona.delete(sandbox);\n```\n\n***\n\n#### get()\n\n```ts\nget(sandboxId: string): Promise<Sandbox>\n```\n\nID でサンドボックスを取得します。\n\n**パラメータ**:\n\n- `sandboxId` _string_ - 取得するサンドボックスの ID\n\n\n**戻り値**:\n\n- `Promise<Sandbox>` - 対象のサンドボックス\n\n**例:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\nconsole.log(`Sandbox state: ${sandbox.state}`);\n```\n\n***\n\n#### list()\n\n```ts\nlist(labels?: Record<string, string>): Promise<Sandbox[]>\n```\n\nラベルでフィルタしたサンドボックスを一覧表示します。\n\n**パラメータ**:\n\n- `labels?` _Record\\<string, string\\>_ - サンドボックスを絞り込むラベル\n\n\n**戻り値**:\n\n- `Promise<Sandbox[]>` - ラベルに一致するサンドボックスの配列。\n\n**例:**\n\n```ts\nconst sandboxes = await daytona.list({ 'my-label': 'my-value' });\nfor (const sandbox of sandboxes) {\n    console.log(`${sandbox.id}: ${sandbox.state}`);\n}\n```\n\n***\n\n#### start()\n\n```ts\nstart(sandbox: Sandbox, timeout?: number): Promise<void>\n```\n\nサンドボックスを起動し、準備完了になるまで待機します。\n\n**パラメータ**:\n\n- `sandbox` _Sandbox_ - 起動するサンドボックス\n- `timeout?` _number_ - 任意のタイムアウト（秒）（0 はタイムアウトなし）\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\n// サンドボックスの起動を最大 60 秒待機\nawait daytona.start(sandbox, 60);\n```\n\n***\n\n#### stop()\n\n```ts\nstop(sandbox: Sandbox): Promise<void>\n```\n\nサンドボックスを停止します。\n\n**パラメータ**:\n\n- `sandbox` _Sandbox_ - 停止するサンドボックス\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\nconst sandbox = await daytona.get('my-sandbox-id');\nawait daytona.stop(sandbox);\n```\n## CodeLanguage\n\nコード実行でサポートされているプログラミング言語\n\n**列挙メンバー**:\n\n- `JAVASCRIPT` (\"javascript\")\n- `PYTHON` (\"python\")\n- `TYPESCRIPT` (\"typescript\")\n\n## CreateSandboxBaseParams\n\n新しいサンドボックスを作成するための基本パラメータ。\n\n**プロパティ**:\n\n- `autoArchiveInterval?` _number_ - 自動アーカイブの間隔（分）。0 は最大間隔を使用することを意味します。デフォルトは 7 日。\n- `autoDeleteInterval?` _number_ - 自動削除の間隔（分）。負の値は無効、0 は停止時に即時削除を意味します。デフォルトでは自動削除は無効です。\n- `autoStopInterval?` _number_ - 自動停止の間隔（分）。0 は無効を意味します。デフォルトは 15 分。\n- `envVars?` _Record\\<string, string\\>_ - サンドボックスに設定する任意の環境変数\n- `labels?` _Record\\<string, string\\>_ - サンドボックスのラベル\n- `language?` _string_ - 直接コード実行用のプログラミング言語\n- `networkAllowList?` _string_ - サンドボックスで許可する CIDR ネットワークアドレスのカンマ区切りリスト\n- `networkBlockAll?` _boolean_ - サンドボックスのネットワークアクセスをすべてブロックするかどうか\n- `public?` _boolean_ - サンドボックスのポートプレビューを公開するかどうか\n- `user?` _string_ - サンドボックスで使用する任意の OS ユーザー\n- `volumes?` _VolumeMount\\[\\]_ - サンドボックスにマウントする任意のボリューム配列\n## CreateSandboxFromImageParams\n\n新しいサンドボックスを作成するためのパラメータ。\n\n**プロパティ**:\n\n- `autoArchiveInterval?` _number_\n- `autoDeleteInterval?` _number_\n- `autoStopInterval?` _number_\n- `envVars?` _Record\\<string, string\\>_\n- `image` _string \\| Image_ - サンドボックスに使用するカスタム Docker イメージ。Image オブジェクトが指定された場合は、\n    イメージが動的にビルドされます。\n- `labels?` _Record\\<string, string\\>_\n- `language?` _string_\n- `networkAllowList?` _string_\n- `networkBlockAll?` _boolean_\n- `public?` _boolean_\n- `resources?` _Resources_ - サンドボックスのリソース割り当て。指定しない場合、サンドボックスは\n    既定のリソースを使用します。\n- `user?` _string_\n- `volumes?` _VolumeMount\\[\\]_\n## CreateSandboxFromSnapshotParams\n\nスナップショットから新しいサンドボックスを作成するためのパラメータ。\n\n**プロパティ**:\n\n- `autoArchiveInterval?` _number_\n- `autoDeleteInterval?` _number_\n- `autoStopInterval?` _number_\n- `envVars?` _Record\\<string, string\\>_\n- `labels?` _Record\\<string, string\\>_\n- `language?` _string_\n- `networkAllowList?` _string_\n- `networkBlockAll?` _boolean_\n- `public?` _boolean_\n- `snapshot?` _string_ - サンドボックスに使用するスナップショット名。\n- `user?` _string_\n- `volumes?` _VolumeMount\\[\\]_\n## DaytonaConfig\n\nDaytona クライアントを初期化するための設定オプション。\n\n**プロパティ**:\n\n- `apiKey?` _string_ - Daytona API で認証するための API キー\n- `apiUrl?` _string_ - Daytona API の URL。ここで未設定で、かつ環境変数 DAYTONA_API_URL でも未設定の場合は、既定で 'https://app.daytona.io/api' が使用されます。\n- `jwtToken?` _string_ - Daytona API で認証するための JWT トークン。未設定の場合は、\n    環境変数 `DAYTONA_JWT_TOKEN` で指定するか、代わりに API キーを指定する必要があります。\n- `organizationId?` _string_ - JWT ベース認証で使用される組織 ID。JWT トークンが指定されている場合に必須で、ここで設定するか、環境変数 `DAYTONA_ORGANIZATION_ID` で設定する必要があります。\n- ~~`serverUrl?`~~ _string_ - **_非推奨_** - 代わりに `apiUrl` を使用してください。このプロパティは今後のバージョンで削除されます。\n- `target?` _string_ - サンドボックスのターゲット（ロケーション）\n    \n\n\n**例:**\n\n```ts\nconst config: DaytonaConfig = {\n    apiKey: \"your-api-key\",\n    apiUrl: \"https://your-api.com\",\n    target: \"us\"\n};\nconst daytona = new Daytona(config);\n```\n## Resources\n\nサンドボックスのリソース割り当て。\n\n**プロパティ**:\n\n- `cpu?` _number_ - サンドボックスの CPU 割り当て（コア数）\n- `disk?` _number_ - サンドボックスのディスク割り当て（GiB）\n- `gpu?` _number_ - サンドボックスの GPU 割り当て（ユニット）\n- `memory?` _number_ - サンドボックスのメモリ割り当て（GiB）\n    \n\n\n**例:**\n\n```ts\nconst resources: SandboxResources = {\n    cpu: 2,\n    memory: 4,  // 4GiB RAM\n    disk: 20    // 20GiB disk\n};\n```\n## VolumeMount\n\nサンドボックスのボリュームマウントを表します。\n\n**プロパティ**:\n\n- `mountPath` _string_ - サンドボックス上でボリュームをマウントするパス\n    \n- `volumeId` _string_ - マウントするボリュームのID\n    \n\n\n\n**継承:**\n\n- `SandboxVolume`"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/errors.mdx",
    "content": "---\ntitle: \"エラー\"\nhideTitleOnPage: true\n---\n\n\n## DaytonaError\n\nDaytona SDKの基底エラー。\n\n**継承:**\n\n- `Error`\n\n### 派生クラス\n\n- `DaytonaNotFoundError`\n\n### コンストラクタ\n\n#### new DaytonaError()\n\n_継承元_: `Error.constructor`\n\n```ts\nnew DaytonaError(message?: string): DaytonaError\n```\n\n**パラメータ**:\n\n- `message?` _string_\n\n\n**戻り値**:\n\n- `DaytonaError`\n\n#### new DaytonaError()\n\n_継承元_: `Error.constructor`\n\n```ts\nnew DaytonaError(message?: string, options?: ErrorOptions): DaytonaError\n```\n\n**パラメータ**:\n\n- `message?` _string_\n- `options?` _ErrorOptions_\n\n\n**戻り値**:\n\n- `DaytonaError`\n\n***\n\n\n## DaytonaNotFoundError\n\nDaytona SDK の基本となるエラー。\n\n**継承:**\n\n- `DaytonaError`\n\n### コンストラクタ\n\n#### new DaytonaNotFoundError()\n\n_継承元_: `DaytonaError.constructor`\n\n```ts\nnew DaytonaNotFoundError(message?: string): DaytonaNotFoundError\n```\n\n**パラメータ**:\n\n- `message?` _string_\n\n\n**戻り値**:\n\n- `DaytonaNotFoundError`\n\n#### new DaytonaNotFoundError()\n\n_継承元_: `DaytonaError.constructor`\n\n```ts\nnew DaytonaNotFoundError(message?: string, options?: ErrorOptions): DaytonaNotFoundError\n```\n\n**パラメータ**:\n\n- `message?` _string_\n- `options?` _ErrorOptions_\n\n\n**戻り値**:\n\n- `DaytonaNotFoundError`\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/execute-response.mdx",
    "content": "---\ntitle: \"ExecuteResponse\"\nhideTitleOnPage: true\n---\n\n\n## ExecuteResponse\n\nコマンド実行のレスポンス。\n\n**プロパティ**:\n\n- `artifacts?` _ExecutionArtifacts_ - コマンド実行で生成された実行アーティファクト\n- `exitCode` _number_ - コマンド実行の終了コード\n- `result` _string_ - コマンド実行の出力\n\n**継承:**\n\n- `ExecuteResponse`\n## ExecutionArtifacts\n\nコマンド実行で生成されたアーティファクト。\n\n**プロパティ**:\n\n- `charts?` _Chart\\[\\]_ - matplotlib 由来のチャートメタデータのリスト\n- `stdout` _string_ - コマンドの標準出力。`ExecuteResponse` の `result` と同一"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/file-system.mdx",
    "content": "---\ntitle: \"ファイルシステム\"\nhideTitleOnPage: true\n---\n\n\n## FileSystem\n\nサンドボックス内でのファイルシステム操作を提供します。\n\n### Constructors\n\n#### new FileSystem()\n\n```ts\nnew FileSystem(\n   sandboxId: string, \n   clientConfig: Configuration, \n   toolboxApi: ToolboxApi, \n   getRootDir: () => Promise<string>): FileSystem\n```\n\n**Parameters**:\n\n- `sandboxId` _string_\n- `clientConfig` _Configuration_\n- `toolboxApi` _ToolboxApi_\n- `getRootDir` _\\(\\) =\\> Promise\\<string\\>_\n\n\n**Returns**:\n\n- `FileSystem`\n\n### Methods\n\n#### createFolder()\n\n```ts\ncreateFolder(path: string, mode: string): Promise<void>\n```\n\n指定した権限でサンドボックス内に新しいディレクトリを作成します。\n\n**Parameters**:\n\n- `path` _string_ - ディレクトリを作成するパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `mode` _string_ - 8 進数形式のディレクトリ権限（例: \"755\"）\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// 標準的な権限でディレクトリを作成\nawait fs.createFolder('app/data', '755');\n```\n\n***\n\n#### deleteFile()\n\n```ts\ndeleteFile(path: string): Promise<void>\n```\n\nサンドボックスからファイルまたはディレクトリを削除します。\n\n**Parameters**:\n\n- `path` _string_ - 削除するファイルまたはディレクトリのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// ファイルを削除\nawait fs.deleteFile('app/temp.log');\n```\n\n***\n\n#### downloadFile()\n\n##### Call Signature\n\n```ts\ndownloadFile(remotePath: string, timeout?: number): Promise<Buffer<ArrayBufferLike>>\n```\n\nサンドボックスからファイルをダウンロードします。このメソッドはファイル全体をメモリに読み込むため、\n大きなファイルのダウンロードには推奨されません。\n\n**Parameters**:\n\n- `remotePath` _string_ - ダウンロードするファイルのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `timeout?` _number_ - ダウンロード操作のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n    既定は 30 分です。\n\n**Returns**:\n\n- `Promise<Buffer<ArrayBufferLike>>` - ファイル内容を表す Buffer。\n\n**Example:**\n\n```ts\n// ファイルをダウンロードして処理\nconst fileBuffer = await fs.downloadFile('tmp/data.json');\nconsole.log('File content:', fileBuffer.toString());\n```\n\n##### Call Signature\n\n```ts\ndownloadFile(\n   remotePath: string, \n   localPath: string, \ntimeout?: number): Promise<void>\n```\n\nサンドボックスからファイルをダウンロードしてローカルファイルに保存します。このメソッドはストリーミングを使用して\nファイルをダウンロードするため、より大きなファイルのダウンロードに適しています。\n\n**Parameters**:\n\n- `remotePath` _string_ - サンドボックス内でダウンロードするファイルのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `localPath` _string_ - ダウンロードしたファイルの保存先パス。\n- `timeout?` _number_ - ダウンロード操作のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n    既定は 30 分です。\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// ファイルをダウンロードして保存\nawait fs.downloadFile('tmp/data.json', 'local_file.json');\n```\n\n***\n\n#### findFiles()\n\n```ts\nfindFiles(path: string, pattern: string): Promise<Match[]>\n```\n\nサンドボックス内のファイルでテキストパターンを検索します。\n\n**Parameters**:\n\n- `path` _string_ - 検索対象のディレクトリ。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `pattern` _string_ - 検索パターン\n\n\n**Returns**:\n\n- `Promise<Match[]>` - ファイルおよび行情報を含む一致結果の配列\n\n**Example:**\n\n```ts\n// TypeScript ファイル内の TODO コメントをすべて検索\nconst matches = await fs.findFiles('app/src', 'TODO:');\nmatches.forEach(match => {\n  console.log(`${match.file}:${match.line}: ${match.content}`);\n});\n```\n\n***\n\n#### getFileDetails()\n\n```ts\ngetFileDetails(path: string): Promise<FileInfo>\n```\n\nファイルまたはディレクトリの詳細情報を取得します。\n\n**Parameters**:\n\n- `path` _string_ - ファイルまたはディレクトリのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n\n\n**Returns**:\n\n- `Promise<FileInfo>` - サイズ、権限、更新時刻などの詳細情報\n\n**Example:**\n\n```ts\n// ファイルの詳細を取得\nconst info = await fs.getFileDetails('app/config.json');\nconsole.log(`Size: ${info.size}, Modified: ${info.modTime}`);\n```\n\n***\n\n#### listFiles()\n\n```ts\nlistFiles(path: string): Promise<FileInfo[]>\n```\n\nサンドボックス内のディレクトリの内容を一覧表示します。\n\n**パラメータ**:\n\n- `path` _string_ - 一覧表示するディレクトリのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n\n\n**戻り値**:\n\n- `Promise<FileInfo[]>` - ファイルおよびディレクトリ情報の配列\n\n**例:**\n\n```ts\n// List directory contents\nconst files = await fs.listFiles('app/src');\nfiles.forEach(file => {\n  console.log(`${file.name} (${file.size} bytes)`);\n});\n```\n\n***\n\n#### moveFiles()\n\n```ts\nmoveFiles(source: string, destination: string): Promise<void>\n```\n\nファイルまたはディレクトリを移動または名前変更します。\n\n**パラメータ**:\n\n- `source` _string_ - 移動元のパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `destination` _string_ - 移動先のパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// Move a file to a new location\nawait fs.moveFiles('app/temp/data.json', 'app/data/data.json');\n```\n\n***\n\n#### replaceInFiles()\n\n```ts\nreplaceInFiles(\n   files: string[], \n   pattern: string, \nnewValue: string): Promise<ReplaceResult[]>\n```\n\n複数のファイル内のテキストを置換します。\n\n**パラメータ**:\n\n- `files` _string\\[\\]_ - 処理するファイルパスの配列。相対パスはユーザーの\n- `pattern` _string_ - 置換対象のパターン\n- `newValue` _string_ - 置換後のテキスト\n\n\n**戻り値**:\n\n- `Promise<ReplaceResult[]>` - 各ファイルに対する置換結果\n\n**例:**\n\n```ts\n// Update version number across multiple files\nconst results = await fs.replaceInFiles(\n  ['app/package.json', 'app/version.ts'],\n  '\"version\": \"1.0.0\"',\n  '\"version\": \"1.1.0\"'\n);\n```\n\n***\n\n#### searchFiles()\n\n```ts\nsearchFiles(path: string, pattern: string): Promise<SearchFilesResponse>\n```\n\nサンドボックス内で、名前パターンに一致するファイルやディレクトリを検索します。\n\n**パラメータ**:\n\n- `path` _string_ - 検索対象のディレクトリ。相対パスはユーザーの\n- `pattern` _string_ - ファイル名のパターン（グロブ対応）\n\n\n**戻り値**:\n\n- `Promise<SearchFilesResponse>` - 一致したファイルを含む検索結果\n\n**例:**\n\n```ts\n// Find all TypeScript files\nconst result = await fs.searchFiles('app', '*.ts');\nresult.files.forEach(file => console.log(file));\n```\n\n***\n\n#### setFilePermissions()\n\n```ts\nsetFilePermissions(path: string, permissions: FilePermissionsParams): Promise<void>\n```\n\nファイルまたはディレクトリの権限と所有権を設定します。\n\n**パラメータ**:\n\n- `path` _string_ - ファイルまたはディレクトリのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `permissions` _FilePermissionsParams_ - 権限設定\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// Set file permissions and ownership\nawait fs.setFilePermissions('app/script.sh', {\n  owner: 'daytona',\n  group: 'users',\n  mode: '755'  // シェルスクリプトに実行権限を付与\n});\n```\n\n***\n\n#### uploadFile()\n\n##### 呼び出しシグネチャ\n\n```ts\nuploadFile(\n   file: Buffer, \n   remotePath: string, \ntimeout?: number): Promise<void>\n```\n\nサンドボックスにファイルをアップロードします。このメソッドはファイル全体をメモリに読み込むため、大きなファイルのアップロードには推奨されません。\n\n**パラメータ**:\n\n- `file` _Buffer_ - アップロードするファイルのバッファ。\n- `remotePath` _string_ - サンドボックス内のアップロード先パス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `timeout?` _number_ - アップロード処理のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n    既定値は30分です。\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// Upload a configuration file\nawait fs.uploadFile(Buffer.from('{\"setting\": \"value\"}'), 'tmp/config.json');\n```\n\n##### 呼び出しシグネチャ\n\n```ts\nuploadFile(\n   localPath: string, \n   remotePath: string, \ntimeout?: number): Promise<void>\n```\n\nローカルファイルシステムからサンドボックスへファイルをアップロードします。このメソッドはストリーミングでアップロードを行うため、大きなファイルのアップロードに適しています。\n\n**パラメータ**:\n\n- `localPath` _string_ - アップロードするローカルファイルのパス。\n- `remotePath` _string_ - サンドボックス内の保存先パス。相対パスはユーザーのルートディレクトリを基準に解決されます。\n- `timeout?` _number_ - アップロード操作のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n    既定値は 30 分です。\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// ローカルファイルをアップロード\nawait fs.uploadFile('local_file.txt', 'tmp/file.txt');\n```\n\n***\n\n#### uploadFiles()\n\n```ts\nuploadFiles(files: FileUpload[], timeout?: number): Promise<void>\n```\n\n複数のファイルをサンドボックスにアップロードします。保存先パスに既にファイルが存在する場合は上書きされます。\n\n**パラメータ**:\n\n- `files` _FileUpload\\[\\]_ - アップロードするファイルの配列。\n- `timeout?` _number = ..._ - アップロード操作のタイムアウト（秒）。0 はタイムアウトなしを意味します。\n    既定値は 30 分です。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// 複数のテキストファイルをアップロード\nconst files = [\n  {\n    source: Buffer.from('Content of file 1'),\n    destination: '/tmp/file1.txt'\n  },\n  {\n    source: 'app/data/file2.txt',\n    destination: '/tmp/file2.txt'\n  },\n  {\n    source: Buffer.from('{\"key\": \"value\"}'),\n    destination: '/tmp/config.json'\n  }\n];\nawait fs.uploadFiles(files);\n```\n\n***\n\n\n## FilePermissionsParams\n\nサンドボックス内のファイル権限を設定するためのパラメータ。\n\n**プロパティ**:\n\n- `group?` _string_ - ファイルのグループ所有者\n- `mode?` _string_ - 8進数形式のファイルモード／権限（例: \"644\"）\n- `owner?` _string_ - ファイルのユーザー所有者\n    \n\n\n\n\n**例:**\n\n```ts\nconst permissions: FilePermissionsParams = {\n  mode: '644',\n  owner: 'daytona',\n  group: 'users'\n};\n```\n## FileUpload\n\nサンドボックスにアップロードするファイルを表します。\n\n**プロパティ**:\n\n- `destination` _string_ - サンドボックス内の絶対パス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `source` _string \\| Buffer\\<ArrayBufferLike\\>_ - アップロード対象のファイル。Buffer の場合、ファイル内容として解釈され、メモリに読み込まれます。\n    メモリに収まることを確認してください。収まらない場合はローカルファイルパスを使用すると、その内容がサンドボックスへストリーミングされます。"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/git.mdx",
    "content": "---\ntitle: \"Git\"\nhideTitleOnPage: true\n---\n\n\n## Git\n\nサンドボックス内での Git 操作を提供します。\n\n### Constructors\n\n#### new Git()\n\n```ts\nnew Git(\n   sandboxId: string, \n   toolboxApi: ToolboxApi, \n   getRootDir: () => Promise<string>): Git\n```\n\n**Parameters**:\n\n- `sandboxId` _string_\n- `toolboxApi` _ToolboxApi_\n- `getRootDir` _\\(\\) =\\> Promise\\<string\\>_\n\n\n**Returns**:\n\n- `Git`\n\n### Methods\n\n#### add()\n\n```ts\nadd(path: string, files: string[]): Promise<void>\n```\n\n指定したファイルを次回のコミットに向けてステージします。コマンドラインで\n「git add」を実行するのと同様です。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `files` _string\\[\\]_ - リポジトリルートからの相対パスで指定する、ステージ対象のファイルまたはディレクトリの一覧\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Examples:**\n\n```ts\n// 単一ファイルをステージ\nawait git.add('workspace/repo', ['file.txt']);\n```\n\n```ts\n// リポジトリ全体をステージ\nawait git.add('workspace/repo', ['.']);\n```\n\n***\n\n#### branches()\n\n```ts\nbranches(path: string): Promise<ListBranchResponse>\n```\n\nリポジトリ内のブランチを一覧表示します。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n\n\n**Returns**:\n\n- `Promise<ListBranchResponse>` - リポジトリ内のブランチ一覧\n\n**Example:**\n\n```ts\nconst response = await git.branches('workspace/repo');\nconsole.log(`Branches: ${response.branches}`);\n```\n\n***\n\n#### checkoutBranch()\n\n```ts\ncheckoutBranch(path: string, branch: string): Promise<void>\n```\n\nリポジトリでブランチをチェックアウトします。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `branch` _string_ - チェックアウトするブランチ名\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nawait git.checkoutBranch('workspace/repo', 'new-feature');\n```\n\n***\n\n#### clone()\n\n```ts\nclone(\n   url: string, \n   path: string, \n   branch?: string, \n   commitId?: string, \n   username?: string, \npassword?: string): Promise<void>\n```\n\n指定したパスに Git リポジトリをクローンします。\n特定のブランチまたはコミットのクローンに対応し、認証情報が提供されている場合は\nリモートリポジトリへの認証も行います。\n\n**Parameters**:\n\n- `url` _string_ - クローン元のリポジトリ URL\n- `path` _string_ - リポジトリをクローンするパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `branch?` _string_ - クローンするブランチ。未指定の場合はデフォルトブランチをクローン\n- `commitId?` _string_ - クローンするコミット。指定された場合、リポジトリはそのコミットの分離 HEAD 状態になります\n- `username?` _string_ - 認証に用いる Git ユーザー名\n- `password?` _string_ - 認証に用いる Git パスワードまたはトークン\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Examples:**\n\n```ts\n// デフォルトブランチをクローン\nawait git.clone(\n  'https://github.com/user/repo.git',\n  'workspace/repo'\n);\n```\n\n```ts\n// 認証付きで特定ブランチをクローン\nawait git.clone(\n  'https://github.com/user/private-repo.git',\n  'workspace/private',\n  branch='develop',\n  username='user',\n  password='token'\n);\n```\n\n```ts\n// 特定のコミットをクローン\nawait git.clone(\n  'https://github.com/user/repo.git',\n  'workspace/repo-old',\n  commitId='abc123'\n);\n```\n\n***\n\n#### commit()\n\n```ts\ncommit(\n   path: string, \n   message: string, \n   author: string, \n   email: string, \nallowEmpty?: boolean): Promise<GitCommitResponse>\n```\n\nステージ済みの変更をコミットします。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `message` _string_ - 変更内容を説明するコミットメッセージ\n- `author` _string_ - コミットの作成者名\n- `email` _string_ - コミット作成者のメールアドレス\n- `allowEmpty?` _boolean_ - 変更がステージされていない場合でも空のコミットの作成を許可\n\n\n**Returns**:\n\n- `Promise<GitCommitResponse>`\n\n**Example:**\n\n```ts\n// 変更をステージしてコミットする\nawait git.add('workspace/repo', ['README.md']);\nawait git.commit(\n  'workspace/repo',\n  'ドキュメントを更新',\n  'John Doe',\n  'john@example.com',\n  true\n);\n```\n\n***\n\n#### createBranch()\n\n```ts\ncreateBranch(path: string, name: string): Promise<void>\n```\n\nリポジトリでブランチを作成します。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `name` _string_ - 作成する新しいブランチ名\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nawait git.createBranch('workspace/repo', 'new-feature');\n```\n\n***\n\n#### deleteBranch()\n\n```ts\ndeleteBranch(path: string, name: string): Promise<void>\n```\n\nリポジトリでブランチを削除します。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `name` _string_ - 削除するブランチ名\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\nawait git.deleteBranch('workspace/repo', 'new-feature');\n```\n\n***\n\n#### pull()\n\n```ts\npull(\n   path: string, \n   username?: string, \npassword?: string): Promise<void>\n```\n\nリモートリポジトリから変更を取得します。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `username?` _string_ - 認証用の Git ユーザー名\n- `password?` _string_ - 認証用の Git パスワードまたはトークン\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Examples:**\n\n```ts\n// 公開リポジトリから pull する\nawait git.pull('workspace/repo');\n```\n\n```ts\n// 非公開リポジトリから pull する\nawait git.pull(\n  'workspace/repo',\n  'user',\n  'token'\n);\n```\n\n***\n\n#### push()\n\n```ts\npush(\n   path: string, \n   username?: string, \npassword?: string): Promise<void>\n```\n\nローカルの変更をリモートリポジトリへ push します。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n- `username?` _string_ - 認証用の Git ユーザー名\n- `password?` _string_ - 認証用の Git パスワードまたはトークン\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Examples:**\n\n```ts\n// 公開リポジトリへ push する\nawait git.push('workspace/repo');\n```\n\n```ts\n// 非公開リポジトリへ push する\nawait git.push(\n  'workspace/repo',\n  'user',\n  'token'\n);\n```\n\n***\n\n#### status()\n\n```ts\nstatus(path: string): Promise<GitStatus>\n```\n\nGit リポジトリの現在のステータスを取得します。\n\n**Parameters**:\n\n- `path` _string_ - Git リポジトリのルートへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n\n\n**Returns**:\n\n- `Promise<GitStatus>` - 現在のリポジトリのステータス（以下を含む）:\n    - currentBranch: 現在のブランチ名\n    - ahead: リモートブランチより先行しているコミット数\n    - behind: リモートブランチより遅れているコミット数\n    - branchPublished: ブランチがリモートリポジトリに公開済みかどうか\n    - fileStatus: ファイルのステータス一覧\n\n**Example:**\n\n```ts\nconst status = await sandbox.git.status('workspace/repo');\nconsole.log(`Current branch: ${status.currentBranch}`);\nconsole.log(`Commits ahead: ${status.ahead}`);\nconsole.log(`Commits behind: ${status.behind}`);\n```\n\n***\n\n\n## GitCommitResponse\n\ngit commit のレスポンス。\n\n**プロパティ**:\n\n- `sha` _string_ - コミットのSHA"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/image.mdx",
    "content": "---\ntitle: \"イメージ\"\nhideTitleOnPage: true\n---\n\n\n## Image\n\nDaytona のサンドボックス用イメージ定義を表します。\nこのクラスを直接インスタンス化しないでください。代わりに `Image.base()`、`Image.debianSlim()`、`Image.fromDockerfile()` などの静的ファクトリメソッドを使用してください。\n\n### Accessors\n\n#### contextList\n\n##### Get Signature\n\n```ts\nget contextList(): Context[]\n```\n\n###### Returns\n\n`Context`[]\n\nイメージに追加されるコンテキストファイルの一覧。\n\n***\n\n#### dockerfile\n\n##### Get Signature\n\n```ts\nget dockerfile(): string\n```\n\n**Returns**:\n\n- `string` - Dockerfile の内容。\n\n### Methods\n\n#### base()\n\n```ts\nstatic base(image: string): Image\n```\n\n既存のベースイメージから Image を作成します。\n\n**Parameters**:\n\n- `image` _string_ - 使用するベースイメージ。\n\n\n**Returns**:\n\n- `Image` - Image インスタンス。\n\n**Example:**\n\n```ts\nconst image = Image.base('python:3.12-slim-bookworm')\n```\n\n***\n\n#### debianSlim()\n\n```ts\nstatic debianSlim(pythonVersion?: \"3.9\" | \"3.10\" | \"3.11\" | \"3.12\" | \"3.13\"): Image\n```\n\n公式の Python Docker イメージに基づく Debian slim イメージを作成します。\n\n**Parameters**:\n\n- `pythonVersion?` _使用する Python のバージョン。_ - `\"3.9\"` | `\"3.10\"` | `\"3.11\"` | `\"3.12\"` | `\"3.13\"`\n\n\n**Returns**:\n\n- `Image` - Image インスタンス。\n\n**Example:**\n\n```ts\nconst image = Image.debianSlim('3.12')\n```\n\n***\n\n#### fromDockerfile()\n\n```ts\nstatic fromDockerfile(path: string): Image\n```\n\n既存の Dockerfile から Image を作成します。\n\n**Parameters**:\n\n- `path` _string_ - Dockerfile へのパス。\n\n\n**Returns**:\n\n- `Image` - Image インスタンス。\n\n**Example:**\n\n```ts\nconst image = Image.fromDockerfile('Dockerfile')\n```\n\n***\n\n#### addLocalDir()\n\n```ts\naddLocalDir(localPath: string, remotePath: string): Image\n```\n\nローカルディレクトリをイメージに追加します。\n\n**Parameters**:\n\n- `localPath` _string_ - ローカルディレクトリのパス。\n- `remotePath` _string_ - イメージ内のディレクトリのパス。\n\n\n**Returns**:\n\n- `Image` - Image インスタンス。\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .addLocalDir('src', '/home/daytona/src')\n```\n\n***\n\n#### addLocalFile()\n\n```ts\naddLocalFile(localPath: string, remotePath: string): Image\n```\n\nローカルファイルをイメージに追加します。\n\n**Parameters**:\n\n- `localPath` _string_ - ローカルファイルのパス。\n- `remotePath` _string_ - イメージ内のファイルのパス。\n\n\n**Returns**:\n\n- `Image` - Image インスタンス。\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .addLocalFile('requirements.txt', '/home/daytona/requirements.txt')\n```\n\n***\n\n#### cmd()\n\n```ts\ncmd(cmd: string[]): Image\n```\n\nイメージのデフォルトコマンドを設定します。\n\n**Parameters**:\n\n- `cmd` _string\\[\\]_ - デフォルトとして設定するコマンド。\n\n\n**Returns**:\n\n- `Image` - Image インスタンス。\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .cmd(['/bin/bash'])\n```\n\n***\n\n#### dockerfileCommands()\n\n```ts\ndockerfileCommands(dockerfileCommands: string[], contextDir?: string): Image\n```\n\n任意の Dockerfile 形式のコマンドでイメージを拡張します。\n\n**Parameters**:\n\n- `dockerfileCommands` _string\\[\\]_ - Dockerfile に追加するコマンド。\n- `contextDir?` _string_ - コンテキストディレクトリのパス。\n\n\n**Returns**:\n\n- `Image` - Image インスタンス。\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .dockerfileCommands(['RUN echo \"Hello, world!\"'])\n```\n\n***\n\n#### entrypoint()\n\n```ts\nentrypoint(entrypointCommands: string[]): Image\n```\n\nイメージのエントリーポイントを設定します。\n\n**Parameters**:\n\n- `entrypointCommands` _string\\[\\]_ - エントリーポイントとして設定するコマンド。\n\n\n**Returns**:\n\n- `Image` - Image インスタンス。\n\n**Example:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .entrypoint(['/bin/bash'])\n```\n\n***\n\n#### env()\n\n```ts\nenv(envVars: Record<string, string>): Image\n```\n\nイメージ内の環境変数を設定します。\n\n**パラメーター**:\n\n- `envVars` _Record\\<string, string\\>_ - 設定する環境変数。\n\n**戻り値**:\n\n- `Image` - Image インスタンス。\n\n**例:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .env({ FOO: 'bar' })\n```\n\n***\n\n#### pipInstall()\n\n```ts\npipInstall(packages: string | string[], options?: PipInstallOptions): Image\n```\n\npip を使用してパッケージをインストールするコマンドを追加します。\n\n**パラメーター**:\n\n- `packages` _インストールするパッケージ_ - `string` | `string`[]\n- `options?` _PipInstallOptions_ - pip インストールコマンドのオプション。\n\n**戻り値**:\n\n- `Image` - Image インスタンス。\n\n**例:**\n\n```ts\nconst image = Image.debianSlim('3.12').pipInstall('numpy', { findLinks: ['https://pypi.org/simple'] })\n```\n\n***\n\n#### pipInstallFromPyproject()\n\n```ts\npipInstallFromPyproject(pyprojectToml: string, options?: PyprojectOptions): Image\n```\n\npyproject.toml ファイルから依存関係をインストールします。\n\n**パラメーター**:\n\n- `pyprojectToml` _string_ - pyproject.toml ファイルのパス。\n- `options?` _PyprojectOptions_ - pip インストールコマンドのオプション。\n\n**戻り値**:\n\n- `Image` - Image インスタンス。\n\n**例:**\n\n```ts\nconst image = Image.debianSlim('3.12')\nimage.pipInstallFromPyproject('pyproject.toml', { optionalDependencies: ['dev'] })\n```\n\n***\n\n#### pipInstallFromRequirements()\n\n```ts\npipInstallFromRequirements(requirementsTxt: string, options?: PipInstallOptions): Image\n```\n\nrequirements.txt ファイルから依存関係をインストールします。\n\n**パラメーター**:\n\n- `requirementsTxt` _string_ - requirements.txt ファイルのパス。\n- `options?` _PipInstallOptions_ - pip インストールコマンドのオプション。\n\n**戻り値**:\n\n- `Image` - Image インスタンス。\n\n**例:**\n\n```ts\nconst image = Image.debianSlim('3.12')\nimage.pipInstallFromRequirements('requirements.txt', { findLinks: ['https://pypi.org/simple'] })\n```\n\n***\n\n#### runCommands()\n\n```ts\nrunCommands(...commands: (string | string[])[]): Image\n```\n\nイメージ内でコマンドを実行します。\n\n**パラメーター**:\n\n- `commands` _...\\(string \\| string\\[\\]\\)\\[\\]_ - 実行するコマンド。\n\n**戻り値**:\n\n- `Image` - Image インスタンス。\n\n**例:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .runCommands(\n   'echo \"Hello, world!\"',\n   ['bash', '-c', 'echo Hello, world, again!']\n )\n```\n\n***\n\n#### workdir()\n\n```ts\nworkdir(dirPath: string): Image\n```\n\nイメージ内の作業ディレクトリを設定します。\n\n**パラメーター**:\n\n- `dirPath` _string_ - 作業ディレクトリのパス。\n\n**戻り値**:\n\n- `Image` - Image インスタンス。\n\n**例:**\n\n```ts\nconst image = Image\n .debianSlim('3.12')\n .workdir('/home/daytona')\n```\n\n***\n\n\n## コンテキスト\n\nイメージに追加するコンテキストファイルを表します。\n\n**プロパティ**:\n\n- `archivePath` _string_ - オブジェクトストレージ内のアーカイブの内部パス。\n- `sourcePath` _string_ - ソースファイルまたはディレクトリへのパス。\n## PipInstallOptions\n\npip install コマンド用のオプション。\n\n**プロパティ**:\n\n- `extraIndexUrls?` _string\\[\\]_ - pip install コマンドで使用する追加のインデックス URL。\n- `extraOptions?` _string_ - pip install コマンドで使用する追加オプション。指定した文字列がそのまま pip install コマンドに渡されます。\n- `findLinks?` _string\\[\\]_ - pip install コマンドで使用する find-links。\n- `indexUrl?` _string_ - pip install コマンドで使用するインデックス URL。\n- `pre?` _boolean_ - プレリリース版をインストールするかどうか。\n    \n\n\n\n\n### により拡張\n\n- `PyprojectOptions`\n## PyprojectOptions\n\npyproject.toml からの pip install コマンド用オプション。\n\n**プロパティ**:\n\n- `extraIndexUrls?` _string\\[\\]_ - pip install コマンドで使用する追加のインデックス URL。\n    - _継承元_: `PipInstallOptions.extraIndexUrls`\n- `extraOptions?` _string_ - pip install コマンドに渡す追加オプション。指定した文字列がそのまま pip install コマンドに渡されます。\n    - _継承元_: `PipInstallOptions.extraOptions`\n- `findLinks?` _string\\[\\]_ - pip install コマンドで使用する find-links。\n    - _継承元_: `PipInstallOptions.findLinks`\n- `indexUrl?` _string_ - pip install コマンドで使用するインデックス URL。\n    - _継承元_: `PipInstallOptions.indexUrl`\n- `optionalDependencies?` _string\\[\\]_ - 任意でインストールする依存関係。\n- `pre?` _boolean_ - プレリリース版をインストールするかどうか。\n    - _継承元_: `PipInstallOptions.pre`\n\n\n\n**継承:** \n\n- `PipInstallOptions`"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/index.mdx",
    "content": "---\ntitle: TypeScript SDK リファレンス\ndescription: TypeScript SDK を使用して Daytona のサンドボックスを操作する\nnext: /docs/typescript-sdk/daytona\n---\n\nDaytona の TypeScript SDK は、Daytona のサンドボックスをプログラムから操作するための強力なインターフェースを提供します。\n\n## インストール\n\nnpm を使用して Daytona の TypeScript SDK をインストールします：\n\n```bash\nnpm install @daytonaio/sdk\n```\n\nまたは yarn を使用します：\n\n```bash\nyarn add @daytonaio/sdk\n```\n\n## はじめに\n\nDaytona の TypeScript SDK を使い始めるための簡単な例を紹介します:\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  // SDK を初期化（デフォルトで環境変数を使用）\n  const daytona = new Daytona()\n\n  // 新しいサンドボックスを作成\n  const sandbox = await daytona.create({\n    language: 'typescript',\n    envVars: { NODE_ENV: 'development' },\n  })\n\n  // コマンドを実行\n  const response = await sandbox.process.executeCommand('echo \"Hello, World!\"')\n  console.log(response.result)\n}\n\nmain().catch(console.error)\n```\n\n## 設定\n\nSDK は環境変数を使うか、コンストラクターにオプションを渡して設定できます:\n\n```typescript\nimport { Daytona } from '@daytonaio/sdk';\n\n// 環境変数を使用 (DAYTONA_API_KEY, DAYTONA_API_URL, DAYTONA_TARGET)\nconst daytona = new Daytona();\n\n// 明示的な設定を指定\nconst daytona = new Daytona({\n  apiKey: 'your-api-key',\n  apiUrl: 'https://app.daytona.io/api',\n  target: 'us'\n});\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/lsp-server.mdx",
    "content": "---\ntitle: \"LspServer\"\nhideTitleOnPage: true\n---\n\n\n## LspServer\n\nコードインテリジェンスのための Language Server Protocol 機能を提供し、コード補完やシンボル検索など、IDEに近い機能を実現します。\n\n### Constructors\n\n#### new LspServer()\n\n```ts\nnew LspServer(\n   languageId: LspLanguageId, \n   pathToProject: string, \n   toolboxApi: ToolboxApi, \n   sandboxId: string): LspServer\n```\n\n**Parameters**:\n\n- `languageId` _LspLanguageId_\n- `pathToProject` _string_\n- `toolboxApi` _ToolboxApi_\n- `sandboxId` _string_\n\n\n**Returns**:\n\n- `LspServer`\n\n### Methods\n\n#### completions()\n\n```ts\ncompletions(path: string, position: Position): Promise<CompletionList>\n```\n\nファイル内の指定位置での補完候補を取得します。\n\n**Parameters**:\n\n- `path` _string_ - ファイルパス。相対パスはLSPサーバーのコンストラクタで設定されたプロジェクトパスを基準に解決されます。\n- `position` _Position_ - 補完を要求したファイル内の位置\n\n\n**Returns**:\n\n- `Promise<CompletionList>` - 補完候補のリスト。次を含みます:\n    - isIncomplete: さらに候補が存在する可能性があるかどうか\n    - items: 補完アイテムのリスト。各アイテムには以下が含まれます:\n    - label: 挿入するテキスト\n    - kind: 補完の種類\n    - detail: アイテムに関する追加情報\n    - documentation: アイテムのドキュメント\n    - sortText: リスト内でのソートに用いるテキスト\n    - filterText: フィルタに用いるテキスト\n    - insertText: 実際に挿入するテキスト（label と異なる場合）\n\n**Example:**\n\n```ts\n// Get completions at a specific position\nconst completions = await lsp.completions('workspace/project/src/index.ts', {\n  line: 10,\n  character: 15\n});\ncompletions.items.forEach(item => {\n  console.log(`${item.label} (${item.kind}): ${item.detail}`);\n});\n```\n\n***\n\n#### didClose()\n\n```ts\ndidClose(path: string): Promise<void>\n```\n\nエディタでファイルが閉じられたことを言語サーバーに通知します。これにより、当該ファイルに関連するリソースをクリーンアップできます。\n\n**Parameters**:\n\n- `path` _string_ - 閉じられたファイルのパス。相対パスはLSPサーバーのコンストラクタで設定されたプロジェクトパスを基準に解決されます。\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// When done editing a file\nawait lsp.didClose('workspace/project/src/index.ts');\n```\n\n***\n\n#### didOpen()\n\n```ts\ndidOpen(path: string): Promise<void>\n```\n\nファイルが開かれたことを言語サーバーに通知し、そのファイルに対する診断や補完などの言語機能を有効化します。サーバーはファイル内容の追跡を開始し、言語機能を提供します。\n\n**Parameters**:\n\n- `path` _string_ - 開いたファイルのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Example:**\n\n```ts\n// When opening a file for editing\nawait lsp.didOpen('workspace/project/src/index.ts');\n// Now can get completions, symbols, etc. for this file\n```\n\n***\n\n#### documentSymbols()\n\n```ts\ndocumentSymbols(path: string): Promise<LspSymbol[]>\n```\n\nドキュメントからシンボル情報（関数、クラス、変数など）を取得します。\n\n**Parameters**:\n\n- `path` _string_ - シンボルを取得するファイルのパス。相対パスはLSPサーバーのコンストラクタで設定されたプロジェクトパスを基準に解決されます。\n\n\n**Returns**:\n\n- `Promise<LspSymbol[]>` - ドキュメント内のシンボルのリスト。各シンボルには以下が含まれます:\n    - name: シンボル名\n    - kind: シンボルの種類（関数、クラス、変数など）\n    - location: ファイル内のシンボル位置\n\n**Example:**\n\n```ts\n// Get all symbols in a file\nconst symbols = await lsp.documentSymbols('workspace/project/src/index.ts');\nsymbols.forEach(symbol => {\n  console.log(`${symbol.kind} ${symbol.name}: ${symbol.location}`);\n});\n```\n\n***\n\n#### sandboxSymbols()\n\n```ts\nsandboxSymbols(query: string): Promise<LspSymbol[]>\n```\n\nクエリ文字列に一致するシンボルをサンドボックス（Daytonaが管理する隔離された一時的な実行環境）全体から検索します。\n\n**パラメータ**:\n\n- `query` _string_ - シンボル名に対して照合する検索クエリ\n\n\n**戻り値**:\n\n- `Promise<LspSymbol[]>` - すべてのファイルから一致したシンボルの一覧。各シンボルには以下が含まれます:\n    - name: シンボル名\n    - kind: シンボルの種類（function、class、variable など）\n    - location: ファイル内でのシンボルの位置\n\n**例:**\n\n```ts\n// \"User\" を含むすべてのシンボルを検索\nconst symbols = await lsp.sandboxSymbols('User');\nsymbols.forEach(symbol => {\n  console.log(`${symbol.name} (${symbol.kind}) in ${symbol.location}`);\n});\n```\n\n***\n\n#### start()\n\n```ts\nstart(): Promise<void>\n```\n\nLanguage Server を起動します。ほかの LSP 機能を使う前に呼び出す必要があります。\n指定した言語とプロジェクトのために Language Server を初期化します。\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\nconst lsp = await sandbox.createLspServer('typescript', 'workspace/project');\nawait lsp.start();  // サーバーを初期化\n// これで LSP 操作の準備ができました\n```\n\n***\n\n#### stop()\n\n```ts\nstop(): Promise<void>\n```\n\nLanguage Server を停止します。不要になったら呼び出して、\nシステムリソースを解放してください。\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// LSP 機能の利用が終わったら\nawait lsp.stop();  // リソースをクリーンアップ\n```\n\n***\n\n#### ~~workspaceSymbols()~~\n\n```ts\nworkspaceSymbols(query: string): Promise<LspSymbol[]>\n```\n\nクエリ文字列に一致するシンボルをサンドボックス（Daytonaが管理する隔離された一時的な実行環境）全体から検索します。\n\n**パラメータ**:\n\n- `query` _string_ - シンボル名に対して照合する検索クエリ\n\n\n**戻り値**:\n\n- `Promise<LspSymbol[]>` - すべてのファイルから一致したシンボルの一覧。各シンボルには以下が含まれます:\n    - name: シンボル名\n    - kind: シンボルの種類（function、class、variable など）\n    - location: ファイル内でのシンボルの位置\n\n##### 非推奨\n\n代わりに `sandboxSymbols` を使用してください。このメソッドは今後のバージョンで削除されます。\n\n***\n\n\n## LspLanguageId\n\nサポート対象の言語サーバータイプ。\n\n**列挙メンバー**:\n\n- `JAVASCRIPT` (\"javascript\")\n- `PYTHON` (\"python\")\n- `TYPESCRIPT` (\"typescript\")\n\n## Position\n\nテキストドキュメント内のゼロ基準の位置を表し、\n行番号と文字オフセットで指定します。\n\n**プロパティ**:\n\n- `character` _number_ - 行内のゼロ基準の文字オフセット\n- `line` _number_ - ドキュメント内のゼロ基準の行番号\n\n\n\n**例:**\n\n```ts\nconst position: Position = {\n  line: 10,     // 11 行目（ゼロ基準）\n  character: 15  // 行内の 16 文字目（ゼロ基準）\n};\n```"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/object-storage.mdx",
    "content": "---\ntitle: \"ObjectStorage\"\nhideTitleOnPage: true\n---\n\n\n## ObjectStorage\n\nオブジェクトストレージサービスとやり取りするための ObjectStorage クラス。\n\n### Param\n\nオブジェクトストレージサービスの構成。\n\n### Constructors\n\n#### new ObjectStorage()\n\n```ts\nnew ObjectStorage(config: ObjectStorageConfig): ObjectStorage\n```\n\n**Parameters**:\n\n- `config` _ObjectStorageConfig_\n\n\n**Returns**:\n\n- `ObjectStorage`\n\n### Methods\n\n#### upload()\n\n```ts\nupload(\n   path: string, \n   organizationId: string, \narchiveBasePath: string): Promise<string>\n```\n\nファイルまたはディレクトリをオブジェクトストレージにアップロードします。\n\n**Parameters**:\n\n- `path` _string_ - アップロード対象のファイルまたはディレクトリのパス。\n- `organizationId` _string_ - アップロードに使用する組織ID。\n- `archiveBasePath` _string_ - アーカイブで使用するベースパス。\n\n\n**Returns**:\n\n- `Promise<string>` - アップロードされたファイルまたはディレクトリのハッシュ値。\n***\n\n\n## ObjectStorageConfig\n\nObjectStorage クラスの設定。\n\n**プロパティ**:\n\n- `accessKeyId` _string_ - オブジェクトストレージサービスのアクセスキー ID。\n- `bucketName?` _string_ - 使用するバケット名。\n- `endpointUrl` _string_ - オブジェクトストレージサービスのエンドポイント URL。\n- `secretAccessKey` _string_ - オブジェクトストレージサービスのシークレットアクセスキー。\n- `sessionToken?` _string_ - オブジェクトストレージサービスのセッショントークン（一時的な認証情報で使用）。"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/process.mdx",
    "content": "---\ntitle: \"プロセス\"\nhideTitleOnPage: true\n---\n\n\n## CodeRunParams\n\nコード実行用のパラメータ。\n\n**プロパティ**:\n\n- `argv?` _string\\[\\]_ - コマンドライン引数\n- `env?` _Record\\<string, string\\>_ - 環境変数\n    \n\n\n\n\n### コンストラクタ\n\n#### new CodeRunParams()\n\n```ts\nnew CodeRunParams(): CodeRunParams\n```\n\n**戻り値**:\n\n- `CodeRunParams`\n## プロセス\n\nサンドボックス内でのプロセスおよびコード実行を扱います。\n\n### コンストラクタ\n\n#### new Process()\n\n```ts\nnew Process(\n   sandboxId: string, \n   clientConfig: Configuration, \n   codeToolbox: SandboxCodeToolbox, \n   toolboxApi: ToolboxApi, \n   getRootDir: () => Promise<string>): Process\n```\n\n**パラメータ**:\n\n- `sandboxId` _string_\n- `clientConfig` _Configuration_\n- `codeToolbox` _SandboxCodeToolbox_\n- `toolboxApi` _ToolboxApi_\n- `getRootDir` _\\(\\) =\\> Promise\\<string\\>_\n\n\n**戻り値**:\n\n- `Process`\n\n### メソッド\n\n#### codeRun()\n\n```ts\ncodeRun(\n   code: string, \n   params?: CodeRunParams, \ntimeout?: number): Promise<ExecuteResponse>\n```\n\n適切な言語ランタイムを用いてサンドボックス内でコードを実行します。\n\n**パラメータ**:\n\n- `code` _string_ - 実行するコード\n- `params?` _CodeRunParams_ - コード実行用のパラメータ\n- `timeout?` _number_ - 実行完了を待機する最大時間（秒）\n\n\n**戻り値**:\n\n- `Promise<ExecuteResponse>` - 以下を含むコード実行結果:\n    - exitCode: 実行の終了ステータス\n    - result: コードの標準出力\n    - artifacts: `stdout`（result と同じ）および `charts`（matplotlib のチャートメタデータ）を含む ExecutionArtifacts オブジェクト\n\n**例:**\n\n```ts\n// TypeScript コードを実行\nconst response = await process.codeRun(`\n  const x = 10;\n  const y = 20;\n  console.log(\\`Sum: \\${x + y}\\`);\n`);\nconsole.log(response.artifacts.stdout);  // 出力: Sum: 30\n```\n\n```ts\n// matplotlib を用いた Python コードを実行\nconst response = await process.codeRun(`\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nx = np.linspace(0, 10, 30)\ny = np.sin(x)\n\nplt.figure(figsize=(8, 5))\nplt.plot(x, y, 'b-', linewidth=2)\nplt.title('Line Chart')\nplt.xlabel('X-axis (seconds)')\nplt.ylabel('Y-axis (amplitude)')\nplt.grid(True)\nplt.show()\n`);\n\nif (response.artifacts?.charts) {\n  const chart = response.artifacts.charts[0];\n\n  console.log(`Type: ${chart.type}`);\n  console.log(`Title: ${chart.title}`);\n  if (chart.type === ChartType.LINE) {\n    const lineChart = chart as LineChart\n    console.log('X Label:', lineChart.x_label)\n    console.log('Y Label:', lineChart.y_label)\n    console.log('X Ticks:', lineChart.x_ticks)\n    console.log('Y Ticks:', lineChart.y_ticks)\n    console.log('X Tick Labels:', lineChart.x_tick_labels)\n    console.log('Y Tick Labels:', lineChart.y_tick_labels)\n    console.log('X Scale:', lineChart.x_scale)\n    console.log('Y Scale:', lineChart.y_scale)\n    console.log('Elements:')\n    console.dir(lineChart.elements, { depth: null })\n  }\n}\n```\n\n***\n\n#### createSession()\n\n```ts\ncreateSession(sessionId: string): Promise<void>\n```\n\nサンドボックス内に新しい長時間実行のバックグラウンドセッションを作成します。\n\nセッションはコマンド間で状態を保持するバックグラウンドプロセスであり、関連する複数のコマンドや永続的な環境設定が必要なシナリオに最適です。長時間実行のコマンドを実行し、プロセスの状態を監視できます。\n\n**パラメータ**:\n\n- `sessionId` _string_ - 新しいセッションの一意の識別子\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// 新しいセッションを作成\nconst sessionId = 'my-session';\nawait process.createSession(sessionId);\nconst session = await process.getSession(sessionId);\n// 作業を実行...\nawait process.deleteSession(sessionId);\n```\n\n***\n\n#### deleteSession()\n\n```ts\ndeleteSession(sessionId: string): Promise<void>\n```\n\nサンドボックスからセッションを削除します。\n\n**パラメータ**:\n\n- `sessionId` _string_ - 削除するセッションの一意の識別子\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// 完了したセッションをクリーンアップ\nawait process.deleteSession('my-session');\n```\n\n***\n\n#### executeCommand()\n\n```ts\nexecuteCommand(\n   command: string, \n   cwd?: string, \n   env?: Record<string, string>, \ntimeout?: number): Promise<ExecuteResponse>\n```\n\nサンドボックスでシェルコマンドを実行します。\n\n**Parameters**:\n\n- `command` _string_ - 実行するシェルコマンド\n- `cwd?` _string_ - コマンド実行時の作業ディレクトリ。未指定の場合はサンドボックスのルートディレクトリを使用します。\n    既定値はユーザーのルートディレクトリです。\n- `env?` _Record\\<string, string\\>_ - コマンドに設定する環境変数\n- `timeout?` _number_ - コマンドの完了を待機する最大時間（秒）。0 は無期限に待機します。\n\n\n**Returns**:\n\n- `Promise<ExecuteResponse>` - コマンド実行結果。以下を含む:\n    - exitCode: コマンドの終了ステータス\n    - result: コマンドの標準出力\n    - artifacts: ExecutionArtifacts オブジェクト（`stdout`（result と同じ）と `charts`（matplotlib のチャートメタデータ）を含む）\n\n**Examples:**\n\n```ts\n// Simple command\nconst response = await process.executeCommand('echo \"Hello\"');\nconsole.log(response.artifacts.stdout);  // Prints: Hello\n```\n\n```ts\n// Command with working directory\nconst result = await process.executeCommand('ls', 'workspace/src');\n```\n\n```ts\n// Command with timeout\nconst result = await process.executeCommand('sleep 10', undefined, 5);\n```\n\n***\n\n#### executeSessionCommand()\n\n```ts\nexecuteSessionCommand(\n   sessionId: string, \n   req: SessionExecuteRequest, \ntimeout?: number): Promise<SessionExecuteResponse>\n```\n\n既存のセッションでコマンドを実行します。\n\n**Parameters**:\n\n- `sessionId` _string_ - 使用するセッションの一意の識別子\n- `req` _SessionExecuteRequest_ - コマンド実行リクエスト。以下を含む:\n    - command: 実行するコマンド\n    - runAsync: 非同期で実行するかどうか\n- `timeout?` _number_ - タイムアウト（秒）\n\n\n**Returns**:\n\n- `Promise<SessionExecuteResponse>` - コマンド実行結果。以下を含む:\n    - cmdId: 実行されたコマンドの一意の識別子\n    - output: コマンド出力（同期実行の場合）\n    - exitCode: コマンドの終了ステータス（同期実行の場合）\n\n**Example:**\n\n```ts\n// Execute commands in sequence, maintaining state\nconst sessionId = 'my-session';\n\n// Change directory\nawait process.executeSessionCommand(sessionId, {\n  command: 'cd /home/daytona'\n});\n\n// Run command in new directory\nconst result = await process.executeSessionCommand(sessionId, {\n  command: 'pwd'\n});\nconsole.log(result.output);  // Prints: /home/daytona\n```\n\n***\n\n#### getSession()\n\n```ts\ngetSession(sessionId: string): Promise<Session>\n```\n\nサンドボックス内のセッションを取得します。\n\n**Parameters**:\n\n- `sessionId` _string_ - 取得するセッションの一意の識別子\n\n\n**Returns**:\n\n- `Promise<Session>` - セッション情報。以下を含む:\n    - sessionId: セッションの一意の識別子\n    - commands: セッション内で実行されたコマンドの一覧\n\n**Example:**\n\n```ts\nconst session = await process.getSession('my-session');\nsession.commands.forEach(cmd => {\n  console.log(`Command: ${cmd.command}`);\n});\n```\n\n***\n\n#### getSessionCommand()\n\n```ts\ngetSessionCommand(sessionId: string, commandId: string): Promise<Command>\n```\n\nセッションで実行された特定のコマンドに関する情報を取得します。\n\n**Parameters**:\n\n- `sessionId` _string_ - セッションの一意の識別子\n- `commandId` _string_ - コマンドの一意の識別子\n\n\n**Returns**:\n\n- `Promise<Command>` - コマンド情報。以下を含む:\n    - id: コマンドの一意の識別子\n    - command: 実行されたコマンド文字列\n    - exitCode: コマンドの終了ステータス（完了している場合）\n\n**Example:**\n\n```ts\nconst cmd = await process.getSessionCommand('my-session', 'cmd-123');\nif (cmd.exitCode === 0) {\n  console.log(`Command ${cmd.command} completed successfully`);\n}\n```\n\n***\n\n#### getSessionCommandLogs()\n\n##### Call Signature\n\n```ts\ngetSessionCommandLogs(sessionId: string, commandId: string): Promise<string>\n```\n\nセッションで実行されたコマンドのログを取得します。\n\n**Parameters**:\n\n- `sessionId` _string_ - セッションの一意の識別子\n- `commandId` _string_ - コマンドの一意の識別子\n\n**Returns**:\n\n- `Promise<string>` - コマンドのログ\n\n**Example:**\n\n```ts\nconst logs = await process.getSessionCommandLogs('my-session', 'cmd-123');\nconsole.log('Command output:', logs);\n```\n\n##### Call Signature\n\n```ts\ngetSessionCommandLogs(\n   sessionId: string, \n   commandId: string, \nonLogs: (chunk: string) => void): Promise<void>\n```\n\nセッションで実行されたコマンドのログを、利用可能になり次第、非同期で取得・処理します。\n\n**パラメーター**:\n\n- `sessionId` _string_ - セッションの一意の識別子\n- `commandId` _string_ - コマンドの一意の識別子\n- `onLogs` _\\(chunk: string\\) =\\> void_ - 各ログチャンクを処理するコールバック関数\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\nconst logs = await process.getSessionCommandLogs('my-session', 'cmd-123', (chunk) => {\n  console.log('Log chunk:', chunk);\n});\n```\n\n***\n\n#### listSessions()\n\n```ts\nlistSessions(): Promise<Session[]>\n```\n\nサンドボックス内のすべてのアクティブなセッションを一覧表示します。\n\n**戻り値**:\n\n- `Promise<Session[]>` - アクティブなセッションの配列\n\n**例:**\n\n```ts\nconst sessions = await process.listSessions();\nsessions.forEach(session => {\n  console.log(`Session ${session.sessionId}:`);\n  session.commands.forEach(cmd => {\n    console.log(`- ${cmd.command} (${cmd.exitCode})`);\n  });\n});\n```\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/sandbox.mdx",
    "content": "---\ntitle: \"サンドボックス\"\nhideTitleOnPage: true\n---\n\n\n## サンドボックス\n\nDaytona のサンドボックスを表します。\n\n**プロパティ**:\n\n- `autoArchiveInterval?` _number_ - 自動アーカイブの間隔（分）\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.autoArchiveInterval\n    ```\n- `autoDeleteInterval?` _number_ - 自動削除の間隔（分）\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.autoDeleteInterval\n    ```\n- `autoStopInterval?` _number_ - 自動停止の間隔（分）\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.autoStopInterval\n    ```\n- `backupCreatedAt?` _string_ - バックアップの作成時刻\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.backupCreatedAt\n    ```\n- `backupState?` _SandboxBackupStateEnum_ - サンドボックスのバックアップの現在の状態\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.backupState\n    ```\n- `buildInfo?` _BuildInfo_ - 動的ビルドから作成された場合のサンドボックスのビルド情報\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.buildInfo\n    ```\n- `computerUse` _ComputerUse_ - デスクトップ自動化のためのコンピューター使用操作インターフェース\n- `cpu` _number_ - サンドボックスに割り当てられた CPU 数\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.cpu\n    ```\n- `createdAt?` _string_ - サンドボックスの作成時刻\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.createdAt\n    ```\n- `disk` _number_ - サンドボックスに割り当てられたディスク容量（GiB）\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.disk\n    ```\n- `env` _Record\\<string, string\\>_ - サンドボックスで設定される環境変数\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.env\n    ```\n- `errorReason?` _string_ - サンドボックスがエラー状態の場合のエラーメッセージ\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.errorReason\n    ```\n- `fs` _FileSystem_ - ファイルシステム操作インターフェース\n- `git` _Git_ - Git 操作インターフェース\n- `gpu` _number_ - サンドボックスに割り当てられた GPU 数\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.gpu\n    ```\n- `id` _string_ - サンドボックスの一意の識別子\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.id\n    ```\n- `labels` _Record\\<string, string\\>_ - サンドボックスに付与されたカスタムラベル\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.labels\n    ```\n- `memory` _number_ - サンドボックスに割り当てられたメモリ容量（GiB）\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.memory\n    ```\n- `networkAllowList?` _string_ - サンドボックスで許可される CIDR ネットワークアドレスのカンマ区切りリスト\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.networkAllowList\n    ```\n- `networkBlockAll` _boolean_ - サンドボックスのネットワークアクセスをすべてブロックするかどうか\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.networkBlockAll\n    ```\n- `organizationId` _string_ - サンドボックスの組織 ID\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.organizationId\n    ```\n- `process` _Process_ - プロセス実行インターフェース\n- `public` _boolean_ - サンドボックスが公開アクセス可能かどうか\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.public\n    ```\n- `runnerDomain?` _string_ - サンドボックスのランナーのドメイン名\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.runnerDomain\n    ```\n- `snapshot?` _string_ - サンドボックスの作成に使用された Daytona のスナップショット\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.snapshot\n    ```\n- `state?` _SandboxState_ - サンドボックスの現在の状態（例: \"started\", \"stopped\"）\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.state\n    ```\n- `target` _string_ - サンドボックスが実行されるランナーのターゲット（リージョン）\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.target\n    ```\n- `updatedAt?` _string_ - サンドボックスの最終更新時刻\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.updatedAt\n    ```\n- `user` _string_ - サンドボックスで実行中の OS ユーザー\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.user\n    ```\n- `volumes?` _SandboxVolume\\[\\]_ - サンドボックスに接続されたボリューム\n    \n    ##### 実装\n    \n    ```ts\n    SandboxDto.volumes\n    ```\n    \n\n\n\n\n### 実装\n\n- `Sandbox`\n\n### コンストラクター\n\n#### new Sandbox()\n\n```ts\nnew Sandbox(\n   sandboxDto: Sandbox, \n   clientConfig: Configuration, \n   sandboxApi: SandboxApi, \n   toolboxApi: ToolboxApi, \n   codeToolbox: SandboxCodeToolbox): Sandbox\n```\n\n新しい Sandbox インスタンスを作成します。\n\n**パラメーター**:\n\n- `sandboxDto` _Sandbox_ - API の Sandbox インスタンス\n- `clientConfig` _Configuration_\n- `sandboxApi` _SandboxApi_ - サンドボックス操作用の API クライアント\n- `toolboxApi` _ToolboxApi_ - ツールボックス操作用の API クライアント\n- `codeToolbox` _SandboxCodeToolbox_ - 言語別ツールボックス実装\n\n\n**戻り値**:\n\n- `Sandbox`\n\n### メソッド\n\n#### archive()\n\n```ts\narchive(): Promise<void>\n```\n\nサンドボックスをアーカイブし、非アクティブ化して状態を保持します。サンドボックスをアーカイブすると、\nファイルシステム全体の状態はコスト効率の高いオブジェクトストレージに移され、長期間利用可能な状態を維持できます。\nアーカイブ状態と停止状態の違いは、サイズに応じてアーカイブ済みサンドボックスの起動により時間がかかる点です。\nアーカイブ前にサンドボックスは停止している必要があります。\n\n**戻り値**:\n\n- `Promise<void>`\n\n***\n\n#### createLspServer()\n\n```ts\ncreateLspServer(languageId: string, pathToProject: string): Promise<LspServer>\n```\n\n新しい Language Server Protocol (LSP) サーバーインスタンスを作成します。\n\nLSP サーバーはコード補完、診断などの言語機能を提供します。\n\n**パラメーター**:\n\n- `languageId` _string_ - 言語サーバーの種類（例: \"typescript\"）\n- `pathToProject` _string_ - プロジェクトのルートディレクトリへのパス。相対パスはユーザーの\n    ルートディレクトリを基準に解決されます。\n\n\n**戻り値**:\n\n- `Promise<LspServer>` - 指定言語向けに構成された新規 LSP サーバーインスタンス\n\n**例:**\n\n```ts\nconst lsp = await sandbox.createLspServer('typescript', 'workspace/project');\n```\n\n***\n\n#### delete()\n\n```ts\ndelete(timeout: number): Promise<void>\n```\n\nサンドボックスを削除します。\n\n**パラメーター**:\n\n- `timeout` _number = 60_\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n***\n\n#### getPreviewLink()\n\n```ts\ngetPreviewLink(port: number): Promise<PortPreviewUrl>\n```\n\n指定したポートのプレビューリンクを取得します。ポートが閉じている場合は自動的に開きます。\nプライベートなサンドボックスでは、URL へのアクセスを許可するトークンが含まれます。\n\n**パラメーター**:\n\n- `port` _number_ - プレビューリンクを開くポート\n\n\n**戻り値**:\n\n- `Promise<PortPreviewUrl>` - プレビューリンクのレスポンスオブジェクト。`url`\n    と `token`（プライベートサンドボックスにアクセスするため）を含みます。\n\n**例:**\n\n```ts\nconst previewLink = await sandbox.getPreviewLink(3000);\nconsole.log(`Preview URL: ${previewLink.url}`);\nconsole.log(`Token: ${previewLink.token}`);\n```\n\n***\n\n#### getUserRootDir()\n\n```ts\ngetUserRootDir(): Promise<string>\n```\n\nサンドボックス内の、ログイン中ユーザーのルートディレクトリパスを取得します。\n\n**戻り値**:\n\n- `Promise<string>` - ログイン中ユーザーのサンドボックスのルートディレクトリへの絶対パス\n\n**例:**\n\n```ts\nconst rootDir = await sandbox.getUserRootDir();\nconsole.log(`Sandbox root: ${rootDir}`);\n```\n\n***\n\n#### refreshData()\n\n```ts\nrefreshData(): Promise<void>\n```\n\nAPI からサンドボックスのデータを再取得して更新します。\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\nawait sandbox.refreshData();\nconsole.log(`Sandbox ${sandbox.id}:`);\nconsole.log(`State: ${sandbox.state}`);\nconsole.log(`Resources: ${sandbox.cpu} CPU, ${sandbox.memory} GiB RAM`);\n```\n\n***\n\n#### setAutoArchiveInterval()\n\n```ts\nsetAutoArchiveInterval(interval: number): Promise<void>\n```\n\nサンドボックスの自動アーカイブ間隔を設定します。\n\n指定した時間連続して停止状態が続いた場合、自動的にアーカイブされます。\n\n**パラメーター**:\n\n- `interval` _number_ - 連続停止から自動アーカイブまでの分数。\n    最大間隔にするには 0 を指定します。デフォルトは 7 日です。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**スロー**:\n\n- `DaytonaError` - interval が非負の整数でない場合\n\n**例:**\n\n```ts\n// 1 時間後に自動アーカイブ\nawait sandbox.setAutoArchiveInterval(60);\n// 最大間隔を使用\nawait sandbox.setAutoArchiveInterval(0);\n```\n\n***\n\n#### setAutoDeleteInterval()\n\n```ts\nsetAutoDeleteInterval(interval: number): Promise<void>\n```\n\nサンドボックス（Daytonaが管理する隔離された一時的なコンピュート環境）の自動削除間隔を設定します。\n\n指定した間隔のあいだ連続して停止状態が続くと、サンドボックスは自動的に削除されます。\n\n**パラメータ**:\n\n- `interval` _number_ - 連続停止後に自動削除されるまでの分数。\n    自動削除を無効化するには負の値を設定します。停止と同時に即時削除するには 0 を設定します。\n    既定では自動削除は無効です。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\n// 1時間後に自動削除\nawait sandbox.setAutoDeleteInterval(60);\n// 停止と同時に即時削除\nawait sandbox.setAutoDeleteInterval(0);\n// 自動削除を無効化\nawait sandbox.setAutoDeleteInterval(-1);\n```\n\n***\n\n#### setAutostopInterval()\n\n```ts\nsetAutostopInterval(interval: number): Promise<void>\n```\n\nサンドボックスの自動停止間隔を設定します。\n\n指定した間隔のあいだアイドル（新しいイベントなし）が続くと、サンドボックスは自動的に停止します。\nイベントには、SDK を通じたサンドボックスへの状態変更や各種インタラクションが含まれます。\nSandbox Previews を用いたインタラクションは含まれません。\n\n**パラメータ**:\n\n- `interval` _number_ - 自動停止までの非アクティブ時間（分）。\n    自動停止を無効化するには 0 を設定します。既定は 15 分です。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**スロー**:\n\n- `DaytonaError` - interval が非負の整数でない場合\n\n**例:**\n\n```ts\n// 1時間後に自動停止\nawait sandbox.setAutostopInterval(60);\n// 自動停止を無効化\nawait sandbox.setAutostopInterval(0);\n```\n\n***\n\n#### setLabels()\n\n```ts\nsetLabels(labels: Record<string, string>): Promise<Record<string, string>>\n```\n\nサンドボックスにラベルを設定します。\n\nラベルは、サンドボックスの整理や識別に使用できるキーと値のペアです。\n\n**パラメータ**:\n\n- `labels` _Record\\<string, string\\>_ - サンドボックスのラベルを表すキーと値のペアの辞書\n\n\n**戻り値**:\n\n- `Promise<Record<string, string>>`\n\n**例:**\n\n```ts\n// サンドボックスのラベルを設定\nawait sandbox.setLabels({\n  project: 'my-project',\n  environment: 'development',\n  team: 'backend'\n});\n```\n\n***\n\n#### start()\n\n```ts\nstart(timeout?: number): Promise<void>\n```\n\nサンドボックスを起動します。\n\nこのメソッドはサンドボックスを起動し、準備完了になるまで待機します。\n\n**パラメータ**:\n\n- `timeout?` _number = 60_ - 待機する最大時間（秒）。0 はタイムアウトなしを意味します。\n    既定は 60 秒のタイムアウトです。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**スロー**:\n\n- `DaytonaError` - サンドボックスの起動に失敗した場合、またはタイムアウトした場合\n\n**例:**\n\n```ts\nconst sandbox = await daytona.getCurrentSandbox('my-sandbox');\nawait sandbox.start(40);  // 最大 40 秒待機\nconsole.log('Sandbox started successfully');\n```\n\n***\n\n#### stop()\n\n```ts\nstop(timeout?: number): Promise<void>\n```\n\nサンドボックスを停止します。\n\nこのメソッドはサンドボックスを停止し、完全に停止するまで待機します。\n\n**パラメータ**:\n\n- `timeout?` _number = 60_ - 待機する最大時間（秒）。0 はタイムアウトなしを意味します。\n    既定は 60 秒のタイムアウトです。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**例:**\n\n```ts\nconst sandbox = await daytona.getCurrentSandbox('my-sandbox');\nawait sandbox.stop();\nconsole.log('Sandbox stopped successfully');\n```\n\n***\n\n#### waitUntilStarted()\n\n```ts\nwaitUntilStarted(timeout?: number): Promise<void>\n```\n\nサンドボックスが 'started' 状態に到達するまで待機します。\n\nこのメソッドは、サンドボックスが 'started' 状態に到達するか\nエラーが発生するまでステータスをポーリングします。\n\n**パラメータ**:\n\n- `timeout?` _number = 60_ - 待機する最大時間（秒）。0 はタイムアウトなしを意味します。\n    既定は 60 秒です。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**スロー**:\n\n- `DaytonaError` - サンドボックスがエラー状態になった場合、またはタイムアウト内に起動できなかった場合\n\n***\n\n#### waitUntilStopped()\n\n```ts\nwaitUntilStopped(timeout?: number): Promise<void>\n```\n\nサンドボックスが 'stopped' 状態に到達するまで待機します。\n\nこのメソッドは、サンドボックスが 'stopped' 状態に到達するか\nエラーが発生するまでステータスをポーリングします。\n\n**パラメータ**:\n\n- `timeout?` _number = 60_ - 待機する最大時間（秒）。0 はタイムアウトなしを意味します。\n    既定は 60 秒です。\n\n\n**戻り値**:\n\n- `Promise<void>`\n\n**スロー**:\n\n- `DaytonaError` - サンドボックスがタイムアウト内に停止できなかった場合\n## SandboxCodeToolbox\n\nコードツールボックスが実装すべきメソッドを定義するインターフェース\n\n### Methods\n\n#### getRunCommand()\n\n```ts\ngetRunCommand(code: string, params?: CodeRunParams): string\n```\n\n与えられたコードを実行するためのコマンドを生成します\n\n**Parameters**:\n\n- `code` _string_\n- `params?` _CodeRunParams_\n\n\n**Returns**:\n\n- `string`\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/snapshot.mdx",
    "content": "---\ntitle: \"スナップショット\"\nhideTitleOnPage: true\n---\n\n\n## SnapshotService\n\nDaytona スナップショットを管理するためのサービス。スナップショットの一覧表示、取得、作成、削除に利用できます。\n\n### Constructors\n\n#### new SnapshotService()\n\n```ts\nnew SnapshotService(\n   clientConfig: Configuration, \n   snapshotsApi: SnapshotsApi, \n   objectStorageApi: ObjectStorageApi): SnapshotService\n```\n\n**Parameters**:\n\n- `clientConfig` _Configuration_\n- `snapshotsApi` _SnapshotsApi_\n- `objectStorageApi` _ObjectStorageApi_\n\n\n**Returns**:\n\n- `SnapshotService`\n\n### Methods\n\n#### activate()\n\n```ts\nactivate(snapshot: Snapshot): Promise<Snapshot>\n```\n\nスナップショットを有効化します。\n\n**Parameters**:\n\n- `snapshot` _Snapshot_ - 有効化するスナップショット\n\n\n**Returns**:\n\n- `Promise<Snapshot>` - 有効化された Snapshot インスタンス\n\n***\n\n#### create()\n\n```ts\ncreate(params: CreateSnapshotParams, options: {\n  onLogs: (chunk: string) => void;\n  timeout: number;\n}): Promise<Snapshot>\n```\n\n指定された Image 定義から新しいスナップショットを作成して登録します。\n\n**Parameters**:\n\n- `params` _CreateSnapshotParams_ - スナップショット作成用のパラメータ。\n- `options` _作成処理のオプション。_\n- `onLogs?` _\\(chunk: string\\) =\\> void_ - スナップショット作成時のログを処理するコールバック関数。\n- `timeout?` _number_ - 既定ではタイムアウトなし。秒単位（0 はタイムアウトなし）。\n\n\n**Returns**:\n\n- `Promise<Snapshot>`\n\n**Example:**\n\n```ts\nconst image = Image.debianSlim('3.12').pipInstall('numpy');\nawait daytona.snapshot.create({ name: 'my-snapshot', image: image }, { onLogs: console.log });\n```\n\n***\n\n#### delete()\n\n```ts\ndelete(snapshot: Snapshot): Promise<void>\n```\n\nスナップショットを削除します。\n\n**Parameters**:\n\n- `snapshot` _Snapshot_ - 削除するスナップショット\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nスナップショットが存在しない、または削除できない場合\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst snapshot = await daytona.snapshot.get(\"snapshot-name\");\nawait daytona.snapshot.delete(snapshot);\nconsole.log(\"Snapshot deleted successfully\");\n```\n\n***\n\n#### get()\n\n```ts\nget(name: string): Promise<Snapshot>\n```\n\n名前を指定してスナップショットを取得します。\n\n**Parameters**:\n\n- `name` _string_ - 取得するスナップショットの名前\n\n\n**Returns**:\n\n- `Promise<Snapshot>` - 要求されたスナップショット\n\n**Throws**:\n\nスナップショットが存在しない、またはアクセスできない場合\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst snapshot = await daytona.snapshot.get(\"snapshot-name\");\nconsole.log(`Snapshot ${snapshot.name} is in state ${snapshot.state}`);\n```\n\n***\n\n#### list()\n\n```ts\nlist(): Promise<Snapshot[]>\n```\n\nすべてのスナップショットを一覧表示します。\n\n**Returns**:\n\n- `Promise<Snapshot[]>` - ユーザーがアクセス可能なすべてのスナップショットの一覧\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst snapshots = await daytona.snapshot.list();\nconsole.log(`Found ${snapshots.length} snapshots`);\nsnapshots.forEach(snapshot => console.log(`${snapshot.name} (${snapshot.imageName})`));\n```\n\n***\n\n\n## CreateSnapshotParams\n\n```ts\ntype CreateSnapshotParams = {\n  entrypoint: string[];\n  image: string | Image;\n  name: string;\n  resources: Resources;\n};\n```\n\n新規スナップショットを作成するためのパラメータ。\n\n**型宣言**:\n\n- `entrypoint?` _string\\[\\]_\n- `image` _string \\| Image_\n- `name` _string_\n- `resources?` _Resources_\n\n\n## スナップショット\n\n```ts\ntype Snapshot = SnapshotDto & {\n  __brand: \"Snapshot\";\n};\n```\n\nあらかじめ構成されたサンドボックスである Daytona のスナップショットを表します。\n\n**型定義**:\n\n- `\\_\\_brand` _\"Snapshot\"_\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/typescript-sdk/volume.mdx",
    "content": "---\ntitle: \"ボリューム\"\nhideTitleOnPage: true\n---\n\n\n## VolumeService\n\nDaytonaのボリューム（S3互換オブジェクトストレージをバックエンドとするFUSEベースの共有ストレージマウント）を管理するサービス。\n\nこのサービスは、ボリュームの一覧取得、参照、作成、削除の各メソッドを提供します。\n\n### Constructors\n\n#### new VolumeService()\n\n```ts\nnew VolumeService(volumesApi: VolumesApi): VolumeService\n```\n\n**Parameters**:\n\n- `volumesApi` _VolumesApi_\n\n\n**Returns**:\n\n- `VolumeService`\n\n### Methods\n\n#### create()\n\n```ts\ncreate(name: string): Promise<Volume>\n```\n\n指定した名前で新しいボリュームを作成します。\n\n**Parameters**:\n\n- `name` _string_ - 新規ボリュームの名前\n\n\n**Returns**:\n\n- `Promise<Volume>` - 作成されたボリューム\n\n**Throws**:\n\nボリュームを作成できない場合\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst volume = await daytona.volume.create(\"my-data-volume\");\nconsole.log(`Created volume ${volume.name} with ID ${volume.id}`);\n```\n\n***\n\n#### delete()\n\n```ts\ndelete(volume: Volume): Promise<void>\n```\n\nボリュームを削除します。\n\n**Parameters**:\n\n- `volume` _Volume_ - 削除するボリューム\n\n\n**Returns**:\n\n- `Promise<void>`\n\n**Throws**:\n\nボリュームが存在しない、または削除できない場合\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst volume = await daytona.volume.get(\"volume-name\");\nawait daytona.volume.delete(volume);\nconsole.log(\"Volume deleted successfully\");\n```\n\n***\n\n#### get()\n\n```ts\nget(name: string, create: boolean): Promise<Volume>\n```\n\n名前を指定してボリュームを取得します。\n\n**Parameters**:\n\n- `name` _string_ - 取得するボリューム名\n- `create` _boolean = false_ - 存在しない場合に作成するかどうか\n\n\n**Returns**:\n\n- `Promise<Volume>` - 取得されたボリューム\n\n**Throws**:\n\nボリュームが存在しない、またはアクセスできない場合\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst volume = await daytona.volume.get(\"volume-name\", true);\nconsole.log(`Volume ${volume.name} is in state ${volume.state}`);\n```\n\n***\n\n#### list()\n\n```ts\nlist(): Promise<Volume[]>\n```\n\n利用可能なすべてのボリュームを一覧表示します。\n\n**Returns**:\n\n- `Promise<Volume[]>` - ユーザーがアクセス可能なすべてのボリュームの一覧\n\n**Example:**\n\n```ts\nconst daytona = new Daytona();\nconst volumes = await daytona.volume.list();\nconsole.log(`Found ${volumes.length} volumes`);\nvolumes.forEach(vol => console.log(`${vol.name} (${vol.id})`));\n```\n\n***\n\n\n## ボリューム（Volume）\n\n```ts\ntype Volume = VolumeDto & {\n  __brand: \"Volume\";\n};\n```\n\nDaytona（サンドボックスを作成・管理するプラットフォーム）のボリューム（S3互換オブジェクトストレージをバックエンドとするFUSEベースの共有ストレージマウント）を表します。サンドボックス（Daytonaが管理する隔離された一時的なコンピュート環境）間で共有されるストレージです。\n\n**型定義**:\n\n- `\\_\\_brand` _\"Volume\"_\n\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/volumes.mdx",
    "content": "---\ntitle: ボリューム\n---\n\nimport Label from '@components/Label.astro'\nimport { Tabs, TabItem } from '@astrojs/starlight/components';\n\nボリュームは、サンドボックス間でファイルを共有してアクセスできる、FUSE ベースのマウントです。これにより、サンドボックスは大容量ファイルを即座に読み取れ、各サンドボックスへ手動でアップロードする必要がありません。ボリュームのデータは S3 互換のオブジェクトストレージに保存されます。\n\n- 複数のボリュームを 1 つのサンドボックスにマウント可能  \n- 1 つのボリュームを複数のサンドボックスにマウント可能\n\n## ボリュームの作成\n\nサンドボックスにボリュームをマウントする前に、先に作成しておく必要があります。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```bash\nvolume = daytona.volume.get(\"my-volume\", create=True)\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```bash\nconst volume = await daytona.volume.get('my-volume', true)\n```\n</TabItem>\n</Tabs>\n\n## ボリュームのマウント\n\nボリュームを作成したら、`CreateSandboxFromSnapshotParams` オブジェクトで指定してサンドボックスにマウントできます:\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\nimport os\nfrom daytona import CreateSandboxFromSnapshotParams, Daytona, VolumeMount\n\ndaytona = Daytona()\n\n# 新しいボリュームを作成するか、既存のボリュームを取得する\nvolume = daytona.volume.get(\"my-volume\", create=True)\n\n# ボリュームをサンドボックスにマウントする\nmount_dir_1 = \"/home/daytona/volume\"\n\nparams = CreateSandboxFromSnapshotParams(\n    language=\"python\",\n    volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_1)],\n)\nsandbox = daytona.create(params)\n\n# サンドボックスの利用が終わったら、削除できます\n# サンドボックスを削除しても、ボリュームは保持されます\nsandbox.delete()\n\n# ボリューム内の特定のサブパスをマウントします\n# これは、データの分離やマルチテナントの実装に役立ちます\nparams = CreateSandboxFromSnapshotParams(\n    language=\"python\",\n    volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_1, subpath=\"users/alice\")],\n)\nsandbox2 = daytona.create(params)\n\nsandbox2.delete()\n```\n\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nimport { Daytona } from '@daytonaio/sdk'\nimport path from 'path'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  // 新しいボリュームを作成するか、既存のボリュームを取得する\n  const volume = await daytona.volume.get('my-volume', true)\n\n  // ボリュームをサンドボックスにマウントする\n  const mountDir1 = '/home/daytona/volume'\n\n  const sandbox1 = await daytona.create({\n    language: 'typescript',\n    volumes: [{ volumeId: volume.id, mountPath: mountDir1 }],\n  })\n  \n  // サンドボックスの利用が終わったら、削除できます\n  // サンドボックスを削除しても、ボリュームは保持されます\n  await sandbox1.delete()\n\n  // ボリューム内の特定のサブパスをマウントします\n  // これは、データの分離やマルチテナントの実装に役立ちます\n  const sandbox2 = await daytona.create({\n    language: 'typescript',\n    volumes: [{ volumeId: volume.id, mountPath: mountDir1, subpath: 'users/alice' }],\n  })\n\n  await sandbox2.delete()\n}\n\nmain()\n\n```\n\n</TabItem>\n</Tabs>\n\n## ボリュームの削除\n\nボリュームが不要になった場合は削除できます。\n\n<Tabs syncKey=\"language\">\n<TabItem label=\"Python\" icon=\"seti:python\">\n```python\nvolume = daytona.volume.get(\"my-volume\", create=True)\ndaytona.volume.delete(volume)\n```\n</TabItem>\n<TabItem label=\"TypeScript\" icon=\"seti:typescript\">\n```typescript\nconst volume = await daytona.volume.get('my-volume', true)\nawait daytona.volume.delete(volume)\n```\n</TabItem>\n</Tabs>\n\n## ボリュームの操作\n\nマウントされると、サンドボックスのファイルシステム内の他のディレクトリと同様に、そのボリュームへの読み書きが行えます。ボリュームに書き込まれたファイルは、個々のサンドボックスのライフサイクルを超えて保持されます。\n\n## 制限事項\n\nボリュームはFUSEベースのマウントであるため、ブロックストレージへのアクセスを必要とするアプリケーション（データベースのテーブルなど）では使用できません。\nボリュームは、ローカルのサンドボックスのファイルシステムと比べて、読み取り・書き込みの両方の操作が一般的に遅くなります。"
  },
  {
    "path": "apps/docs/src/content/docs/ja/web-terminal.mdx",
    "content": "---\ntitle: Web Terminal\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nDaytonaはサンドボックス（Daytonaが管理する隔離された一時的な計算環境）と対話するためのWeb Terminalを提供しており、ファイルの表示、コマンドの実行、デバッグを手軽に行えます。\n\n[Sandbox list](https://app.daytona.io/dashboard/sandboxes) の Access 列にある、実行中の任意のサンドボックスの Terminal アイコン `>_` をクリックすると開けます。標準で有効になっており、ポート `22222` でアクセスできます。\n\n```text\n\nID                    State         Region     Created             Access\n──────────────────────────────────────────────────────────────────────────────\nsandbox-963e3f71      STARTED       us         12 minutes ago      >_\n\n```\n\n:::note\nTerminal へのアクセスは非常に機密性の高い操作であるため、`CreateSandboxFromSnapshotParams` や `CreateSandboxFromImageParams` で `public` パラメータを `True` に設定した場合でも、あなたの組織（Daytona内のリソースとユーザーのグループ）のユーザーにのみ許可されます。\n:::\n"
  },
  {
    "path": "apps/docs/src/content/docs/ja/webhooks.mdx",
    "content": "---\ntitle: Webhooks\ndescription: 自動化・監視・連携のために、リアルタイムでDaytonaのイベントをアプリケーションに接続するWebhooks。\n---\n\nimport { TabItem, Tabs } from '@astrojs/starlight/components'\n\nWebhooksは、特定のイベントが発生した際に、Daytonaが指定したエンドポイントへ送信するHTTPコールバックです。\nいわば「逆方向のAPIコール」です。アプリケーション側がDaytonaに更新を問い合わせるのではなく、重要なイベントが発生するとDaytonaが能動的にアプリケーションへ通知します。\n\n## ユースケース\n\nWebhooks により、強力な自動化と統合が可能になります。\n\n- **リアルタイム通知**: サンドボックスの作成・起動・停止時に即時にアラートを受け取る\n- **自動化ワークフロー**: スナップショット作成時にデプロイメントパイプラインを起動する\n- **監視と分析**: 組織全体の利用傾向やリソース消費を追跡する\n- **統合**: Daytona を Slack、Discord、カスタムアプリケーションなどの既存ツールと連携する\n- **監査とコンプライアンス**: 重要な変更の詳細なログを保持する\n\n---\n\n## はじめに\n\n### Webhooks へのアクセス\n\nダッシュボードのサイドバーに **Webhooks** が表示されていない場合は、[support@daytona.io](mailto:support@daytona.io) までご連絡のうえ、組織向けに Webhooks の有効化をリクエストしてください。アクセス申請の際は、組織設定で確認できる組織 ID を併せてご提供ください。\n\n組織で Webhooks が有効化されたら:\n\n1. [Daytona Dashboard](https://app.daytona.io/dashboard) にアクセスします\n2. 左サイドバーの **Webhooks** をクリックします\n3. Webhook の管理インターフェースにアクセスできます\n\n:::note\nWebhooks は、組織の管理者および適切な権限を持つメンバーが利用できます。\n:::\n\n---\n\n## Webhookエンドポイントの管理\n\n### エンドポイントの作成\n\nWebhookイベントの受信を開始するには:\n\n1. Webhookダッシュボードの**Endpoints**タブに移動します\n2. **Add Endpoint**をクリックします\n3. エンドポイントを設定します:\n   - **Endpoint URL**: イベントを受信するHTTPSエンドポイント\n   - **Description**: このエンドポイントの説明\n   - **Subscribe to events**: 受信するイベントを選択\n\n### エンドポイントのテスト\n\n運用開始前に、Webhookエンドポイントをテストします:\n\n1. **Endpoints**リストからWebhooksを選択します\n2. **Testing**タブに移動します\n3. テストイベントを設定して送信します\n4. エンドポイントがテストペイロードを正しく受信していることを確認します\n5. アプリケーションがWebhookの形式を正しく処理できることを確認します\n\n---\n\n## 利用可能なイベント\n\nDaytona は、インフラストラクチャ リソース全体のライフサイクルイベントについて Webhook を送信します。特定のイベントタイプに購読することも、すべてのイベントを受け取ってアプリケーション内でフィルタリングすることもできます。\n\n##### イベントカテゴリ\n\n- サンドボックスのライフサイクルイベント\n- スナップショットのライフサイクルイベント\n- ボリュームのライフサイクルイベント\n\n---\n\n## Webhook ペイロード形式\n\nすべての Webhook イベントは一貫した構造に従います。\n\n```json\n{\n  \"event\": \"event.type\",\n  \"timestamp\": \"2024-01-15T10:30:00Z\",\n  \"data\": {\n    // イベント固有のデータ\n  }\n}\n```\n\n**共通フィールド:**\n\n- `event`: イベントの種類（例: \"sandbox.created\"）\n- `timestamp`: イベント発生時刻（ISO 8601）\n- `data`: 関連情報を含むイベント固有のペイロード\n\n---\n\n## 監視とアクティビティ\n\n### アクティビティ\n\n**アクティビティ** タブでは、配信統計、イベント量の推移、パフォーマンス指標など、Webhook のアクティビティを可視化して確認でき、Webhook 連携の健全性の監視に役立ちます。\n\n### イベントログ\n\n**ログ** タブには、トラブルシューティングおよび監視のために、イベント履歴、配信ステータス、再試行情報など、Webhook 配信に関する詳細が表示されます。\n"
  },
  {
    "path": "apps/docs/src/content/i18n/en.json",
    "content": "{\n  \"header.copyForLlms\": \"Copy for LLM\",\n  \"header.viewAsMarkdown\": \"View as Markdown\",\n  \"footer.needHelp\": \"Need help?\",\n  \"footer.reachSupport\": \"Reach support\",\n  \"footer.latestUpdates\": \"Latest project updates?\",\n  \"footer.viewChangelog\": \"View Changelog\",\n  \"footer.dotfilesInsider\": \"Dotfiles Insider\",\n  \"footer.readBlog\": \"Read our blog\",\n  \"footer.privacyPolicy\": \"Privacy policy\",\n  \"footer.termsOfService\": \"Terms of Service\",\n  \"footer.LLMs\": \"LLMs\",\n  \"header.documentation\": \"Docs\",\n  \"header.references\": \"References\",\n  \"header.customers\": \"Customers\",\n  \"header.startups\": \"Startups\",\n  \"header.blog\": \"Blog\",\n  \"header.pricing\": \"Pricing\",\n  \"header.guides\": \"Guides\",\n  \"header.changelog\": \"Changelog\",\n  \"tableOfContents.title\": \"Contents\",\n  \"exploreMore.exploreMore\": \"Explore More\",\n  \"expressiveCode.copyButtonCopied\": \"Copied!\",\n  \"expressiveCode.copyButtonTooltip\": \"Copy to clipboard\",\n  \"expressiveCode.terminalWindowFallbackTitle\": \"Terminal window\",\n  \"pagefind.clear_search\": \"Clear\",\n  \"pagefind.load_more\": \"Load more results\",\n  \"pagefind.search_label\": \"Search this site\",\n  \"pagefind.filters_label\": \"Filters\",\n  \"pagefind.zero_results\": \"No results for [SEARCH_TERM]\",\n  \"pagefind.many_results\": \"[COUNT] results for [SEARCH_TERM]\",\n  \"pagefind.one_result\": \"[COUNT] result for [SEARCH_TERM]\",\n  \"pagefind.alt_search\": \"No results for [SEARCH_TERM]. Showing results for [DIFFERENT_TERM] instead\",\n  \"pagefind.search_suggestion\": \"No results for [SEARCH_TERM]. Try one of the following searches:\",\n  \"pagefind.searching\": \"Searching for [SEARCH_TERM]...\",\n  \"sidebarconfig.home\": \"Home\",\n  \"sidebarconfig.architecture\": \"Architecture\",\n  \"sidebarconfig.architectureDescription\": \"Learn about the Daytona platform architecture.\",\n  \"sidebarconfig.quickStart\": \"Quick Start\",\n  \"sidebarconfig.reference\": \"Reference\",\n  \"sidebarconfig.documentation\": \"Docs\",\n  \"sidebarconfig.guides\": \"Guides\",\n  \"sidebarconfig.tsSdkReference\": \"TypeScript SDK\",\n  \"sidebarconfig.pythonSdkReference\": \"Python SDK\",\n  \"sidebarconfig.rubySdkReference\": \"Ruby SDK\",\n  \"sidebarconfig.goSdkReference\": \"Go SDK\",\n  \"sidebarconfig.apiReference\": \"API\",\n  \"sidebarconfig.cliReference\": \"CLI\",\n  \"sidebarconfig.introduction\": \"Introduction\",\n  \"sidebarconfig.gettingStarted\": \"Getting Started\",\n  \"sidebarconfig.gettingStartedDescription\": \"Learn about Daytona SDK and how it can help you manage your development environments.\",\n  \"sidebarconfig.configuration\": \"Configuration\",\n  \"sidebarconfig.environment\": \"Environment\",\n  \"sidebarconfig.configurationDescription\": \"Get started with Daytona SDK and learn how to use and configure your development environments.\",\n  \"sidebarconfig.sandboxes\": \"Sandboxes\",\n  \"sidebarconfig.sandboxesDescription\": \"Learn how to create, manage, and remove Sandboxes using the Daytona SDK.\",\n  \"sidebarconfig.snapshots\": \"Snapshots\",\n  \"sidebarconfig.snapshotsDescription\": \"Learn how to create, manage and remove Snapshots using the Daytona SDK.\",\n  \"sidebarconfig.declarativeBuilder\": \"Declarative Builder\",\n  \"sidebarconfig.declarativeBuilderDescription\": \"Learn how to dynamically build Snapshots from Docker/OCI compatible images using the Daytona SDK.\",\n  \"sidebarconfig.volumes\": \"Volumes\",\n  \"sidebarconfig.volumesDescription\": \"Learn how to manage volumes in your Daytona Sandboxes.\",\n  \"sidebarconfig.accountManagement\": \"Account management\",\n  \"sidebarconfig.apiKeys\": \"API Keys\",\n  \"sidebarconfig.apiKeysDescription\": \"Daytona API Key management and scopes.\",\n  \"sidebarconfig.organizations\": \"Organizations\",\n  \"sidebarconfig.organizationsDescription\": \"Learn how to create, manage, and remove Organizations using the Daytona SDK.\",\n  \"sidebarconfig.limits\": \"Limits\",\n  \"sidebarconfig.limitsDescription\": \"Limits and tiers assigned to Organizations.\",\n  \"sidebarconfig.rateLimits\": \"Rate Limits\",\n  \"sidebarconfig.rateLimitsDescription\": \"API rate limits for authenticated and anonymous requests.\",\n  \"sidebarconfig.billing\": \"Billing\",\n  \"sidebarconfig.billingDescription\": \"Billing management for Organizations.\",\n  \"sidebarconfig.linkedAccounts\": \"Linked Accounts\",\n  \"sidebarconfig.linkedAccountsDescription\": \"Linked Accounts for Users.\",\n  \"sidebarconfig.agentTools\": \"Agent Tools\",\n  \"sidebarconfig.humanTools\": \"Human Tools\",\n  \"sidebarconfig.systemTools\": \"System Tools\",\n  \"sidebarconfig.fileSystem\": \"File System\",\n  \"sidebarconfig.fileSystemDescription\": \"Learn how to manage files and directories in your Sandboxes using the Daytona SDK.\",\n  \"sidebarconfig.gitOperations\": \"Git Operations\",\n  \"sidebarconfig.gitOperationsDescription\": \"Learn how to manage Git repositories in your Sandboxes using the Daytona SDK.\",\n  \"sidebarconfig.languageServerProtocol\": \"Language Server Protocol\",\n  \"sidebarconfig.languageServerProtocolDescription\": \"Learn how to use Language Server Protocol (LSP) support in your Sandboxes using the Daytona SDK.\",\n  \"sidebarconfig.processCodeExecution\": \"Process & Code Execution\",\n  \"sidebarconfig.processCodeExecutionDescription\": \"Learn about running commands and code in isolated environments using the Daytona SDK.\",\n  \"sidebarconfig.logStreaming\": \"Log Streaming\",\n  \"sidebarconfig.logStreamingDescription\": \"Learn how to stream logs from your Sandboxes using the Daytona SDK.\",\n  \"sidebarconfig.computerUse\": \"Computer Use\",\n  \"sidebarconfig.computerUseLinux\": \"Linux\",\n  \"sidebarconfig.computerUseLinuxDescription\": \"Computer use capabilities and automation for Linux environments.\",\n  \"sidebarconfig.computerUseWindows\": \"Windows\",\n  \"sidebarconfig.computerUseWindowsDescription\": \"Computer use capabilities and automation for Windows environments.\",\n  \"sidebarconfig.computerUseMacOS\": \"macOS\",\n  \"sidebarconfig.computerUseMacOSDescription\": \"Computer use capabilities and automation for macOS environments.\",\n  \"sidebarconfig.other\": \"Other\",\n  \"sidebarconfig.webTerminal\": \"Web Terminal\",\n  \"sidebarconfig.webTerminalDescription\": \"Web Terminal access to Daytona Sandboxes.\",\n  \"sidebarconfig.networkLimits\": \"Network Limits\",\n  \"sidebarconfig.networkLimitsDescription\": \"Network egress limits for Daytona Sandboxes.\",\n  \"sidebarconfig.sshAccess\": \"SSH Access\",\n  \"sidebarconfig.vncAccess\": \"VNC Access\",\n  \"sidebarconfig.vncAccessDescription\": \"VNC access to Daytona Sandboxes.\",\n  \"sidebarconfig.vpnConnection\": \"VPN Connections\",\n  \"sidebarconfig.vpnConnectionDescription\": \"Connect Daytona Sandboxes to VPN networks.\",\n  \"sidebarconfig.sshAccessDescription\": \"SSH access to Daytona Sandboxes.\",\n  \"sidebarconfig.playground\": \"Playground\",\n  \"sidebarconfig.playgroundDescription\": \"Playground for Daytona Sandboxes.\",\n  \"sidebarconfig.preview\": \"Preview\",\n  \"sidebarconfig.previewDescription\": \"Preview URLs and authentication tokens.\",\n  \"sidebarconfig.customPreviewProxy\": \"Custom Preview Proxy\",\n  \"sidebarconfig.customPreviewProxyDescription\": \"Deploy your own preview proxy with custom domains, authentication, and styling.\",\n  \"sidebarconfig.auditLogs\": \"Audit Logs\",\n  \"sidebarconfig.auditLogsDescription\": \"Monitor and track activities across your Daytona organization.\",\n  \"sidebarconfig.securityExhibit\": \"Security Exhibit\",\n  \"sidebarconfig.securityExhibitDescription\": \"Technical and organizational security measures Daytona maintains to protect customer data processed through its platform.\",\n  \"sidebarconfig.webhooks\": \"Webhooks\",\n  \"sidebarconfig.webhooksDescription\": \"Receive real-time notifications when events occur in your Daytona organization.\",\n  \"sidebarconfig.regions\": \"Regions\",\n  \"sidebarconfig.regionsDescription\": \"Region types and custom infrastructure.\",\n  \"sidebarconfig.runners\": \"Runners\",\n  \"sidebarconfig.runnersDescription\": \"Runner types and custom infrastructure.\",\n  \"sidebarconfig.customerManagedCompute\": \"Customer Managed Compute\",\n  \"sidebarconfig.customerManagedComputeDescription\": \"Customer managed compute for Daytona Sandboxes.\",\n  \"sidebarconfig.mcpServer\": \"MCP Server\",\n  \"sidebarconfig.daytona\": \"Daytona\",\n  \"sidebarconfig.sandbox\": \"Sandbox\",\n  \"sidebarconfig.common\": \"Common\",\n  \"sidebarconfig.syncPython\": \"Sync Python\",\n  \"sidebarconfig.asyncPython\": \"Async Python\",\n  \"sidebarconfig.asyncDaytona\": \"AsyncDaytona\",\n  \"sidebarconfig.asyncSandbox\": \"AsyncSandbox\",\n  \"sidebarconfig.dataAnalysis\": \"Data Analysis with AI\",\n  \"sidebarconfig.ossDeployment\": \"Open Source\",\n  \"sidebarconfig.deployments\": \"Deployments\",\n  \"sidebarconfig.security\": \"Security\",\n  \"sidebarconfig.integrations\": \"Guides\",\n  \"sidebarconfig.langchain\": \"LangChain\",\n  \"sidebarconfig.claudeCode\": \"Claude Code\",\n  \"sidebarconfig.inngestAgentKit\": \"AgentKit\",\n  \"sidebarconfig.mastra\": \"Mastra\",\n  \"sidebarconfig.opencode\": \"OpenCode\",\n  \"sidebarconfig.claude\": \"Claude\",\n  \"sidebarconfig.openclaw\": \"OpenClaw\",\n  \"sidebarconfig.codex\": \"Codex\",\n  \"sidebarconfig.googleAdk\": \"Google ADK\",\n  \"sidebarconfig.lettacode\": \"Letta Code\",\n  \"sidebarconfig.trlGrpo\": \"TRL\",\n  \"sidebarconfig.rlm\": \"RLMs\",\n  \"sidebarconfig.recursiveLms\": \"RLMs\",\n  \"sidebarconfig.dspyRlms\": \"RLMs via DSPy\",\n  \"sidebarconfig.pty\": \"Pseudo Terminal (PTY)\",\n  \"sidebarconfig.ptyDescription\": \"Learn how to manage PTY sessions in your Sandboxes using the Daytona SDK.\",\n  \"sidebarconfig.experimental\": \"Experimental\",\n  \"sidebarconfig.otelCollection\": \"OpenTelemetry Collection\"\n}\n"
  },
  {
    "path": "apps/docs/src/content/i18n/ja.json",
    "content": "{\n  \"footer.needHelp\": \"お困りですか？\",\n  \"footer.reachSupport\": \"サポートに連絡\",\n  \"footer.latestUpdates\": \"最新のプロジェクト更新はありますか？\",\n  \"footer.viewChangelog\": \"変更履歴を表示\",\n  \"footer.dotfilesInsider\": \"Dotfiles Insider\",\n  \"footer.readBlog\": \"当社のブログをお読みください\",\n  \"footer.privacyPolicy\": \"プライバシーポリシー\",\n  \"footer.termsOfService\": \"利用規約\",\n  \"header.documentation\": \"ドキュメント\",\n  \"tableOfContents.title\": \"目次\",\n  \"exploreMore.exploreMore\": \"さらに詳しく見る\",\n  \"expressiveCode.copyButtonCopied\": \"コピーしました！\",\n  \"expressiveCode.copyButtonTooltip\": \"クリップボードにコピー\",\n  \"expressiveCode.terminalWindowFallbackTitle\": \"ターミナルウィンドウ\",\n  \"pagefind.clear_search\": \"クリア\",\n  \"pagefind.load_more\": \"さらに結果を読み込む\",\n  \"pagefind.search_label\": \"このサイトを検索\",\n  \"pagefind.filters_label\": \"フィルター\",\n  \"pagefind.zero_results\": \"[SEARCH_TERM] の結果はありません\",\n  \"pagefind.many_results\": \"[COUNT] 件の結果（[SEARCH_TERM]）\",\n  \"pagefind.one_result\": \"[COUNT] 件の結果（[SEARCH_TERM]）\",\n  \"pagefind.alt_search\": \"[SEARCH_TERM] の結果は見つかりませんでした。代わりに [DIFFERENT_TERM] の結果を表示しています\",\n  \"pagefind.search_suggestion\": \"[SEARCH_TERM] に一致する結果はありません。次のいずれかの検索をお試しください：\",\n  \"pagefind.searching\": \"[SEARCH_TERM] を検索しています...\",\n  \"sidebarconfig.home\": \"ホーム\",\n  \"sidebarconfig.documentation\": \"ドキュメント\",\n  \"sidebarconfig.tsSdkReference\": \"TypeScript SDK リファレンス\",\n  \"sidebarconfig.pythonSdkReference\": \"Python SDK リファレンス\",\n  \"sidebarconfig.rubySdkReference\": \"Ruby SDK リファレンス\",\n  \"sidebarconfig.apiReference\": \"APIリファレンス\",\n  \"sidebarconfig.cliReference\": \"CLI リファレンス\",\n  \"sidebarconfig.introduction\": \"概要\",\n  \"sidebarconfig.gettingStarted\": \"はじめに\",\n  \"sidebarconfig.gettingStartedDescription\": \"Daytona SDKの概要と、開発環境の管理にどのように役立つかを学びましょう。\",\n  \"sidebarconfig.configuration\": \"設定\",\n  \"sidebarconfig.configurationDescription\": \"DaytonaのTS SDK / Python SDKの利用を開始し、開発環境の使い方と設定方法を学びましょう。\",\n  \"sidebarconfig.sandboxes\": \"サンドボックス\",\n  \"sidebarconfig.sandboxesDescription\": \"DaytonaのTS SDK / Python SDKを使用してサンドボックス（Daytonaが管理する隔離された一時的な実行環境）を作成・管理・削除する方法を学びます。\",\n  \"sidebarconfig.snapshots\": \"スナップショット\",\n  \"sidebarconfig.snapshotsDescription\": \"Daytona SDK を使用してスナップショット（サンドボックス作成に使用する事前設定済みの再利用可能なイメージ/テンプレート）の作成、管理、削除方法を学びます。\",\n  \"sidebarconfig.declarativeBuilder\": \"宣言的ビルダー\",\n  \"sidebarconfig.declarativeBuilderDescription\": \"Daytona SDK を使用して、Docker/OCI 互換イメージからスナップショット（サンドボックス作成に使用する事前設定済みの再利用可能なイメージ/テンプレート）を動的に構築する方法を学びます。\",\n  \"sidebarconfig.volumes\": \"ボリューム（S3互換オブジェクトストレージをバックエンドとするFUSEベースの共有ストレージ）\",\n  \"sidebarconfig.volumesDescription\": \"Daytonaのサンドボックス（Daytonaが管理する隔離された一時的な実行環境）でボリューム（S3互換オブジェクトストレージをバックエンドとするFUSEベースの共有ストレージ）を管理する方法を学びましょう。\",\n  \"sidebarconfig.accountManagement\": \"アカウント管理\",\n  \"sidebarconfig.apiKeys\": \"APIキー\",\n  \"sidebarconfig.apiKeysDescription\": \"Daytona APIキーの管理とスコープ。\",\n  \"sidebarconfig.organizations\": \"組織\",\n  \"sidebarconfig.organizationsDescription\": \"Daytona SDK を使用して、組織（Organization）の作成、管理、削除方法を学びましょう。\",\n  \"sidebarconfig.limits\": \"制限\",\n  \"sidebarconfig.limitsDescription\": \"組織に割り当てられた制限とティア。\",\n  \"sidebarconfig.billing\": \"請求\",\n  \"sidebarconfig.billingDescription\": \"組織の請求管理。\",\n  \"sidebarconfig.linkedAccounts\": \"リンク済みアカウント\",\n  \"sidebarconfig.linkedAccountsDescription\": \"ユーザーのリンク済みアカウント\",\n  \"sidebarconfig.agentToolbox\": \"エージェントツールボックス\",\n  \"sidebarconfig.fileSystem\": \"ファイルシステム\",\n  \"sidebarconfig.fileSystemDescription\": \"DaytonaのTS SDK / Python SDKを使用して、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）内のファイルとディレクトリを管理する方法を学びましょう。\",\n  \"sidebarconfig.gitOperations\": \"Git 操作\",\n  \"sidebarconfig.gitOperationsDescription\": \"Daytona SDK を使用して、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）内で Git リポジトリを管理する方法を学びます。\",\n  \"sidebarconfig.languageServerProtocol\": \"Language Server Protocol\",\n  \"sidebarconfig.languageServerProtocolDescription\": \"Daytona SDK を使用して、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）で LSP（言語サーバープロトコル）のサポートを利用する方法を学びます。\",\n  \"sidebarconfig.processCodeExecution\": \"プロセス＆コード実行\",\n  \"sidebarconfig.processCodeExecutionDescription\": \"Daytona SDK を使用して、隔離された環境でコマンドやコードを実行する方法を学びます。\",\n  \"sidebarconfig.logStreaming\": \"ログストリーミング\",\n  \"sidebarconfig.logStreamingDescription\": \"DaytonaのTS SDK / Python SDKを使用して、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）からログをストリーミングする方法を学びましょう。\",\n  \"sidebarconfig.computerUse\": \"コンピューター使用\",\n  \"sidebarconfig.computerUseLinux\": \"Linux\",\n  \"sidebarconfig.computerUseLinuxDescription\": \"Linux環境でのコンピューター使用機能と自動化。\",\n  \"sidebarconfig.computerUseWindows\": \"Windows\",\n  \"sidebarconfig.computerUseWindowsDescription\": \"Windows環境でのコンピューター使用機能と自動化。\",\n  \"sidebarconfig.computerUseMacOS\": \"macOS\",\n  \"sidebarconfig.computerUseMacOSDescription\": \"macOS環境でのコンピューター使用機能と自動化。\",\n  \"sidebarconfig.other\": \"その他\",\n  \"sidebarconfig.webTerminal\": \"Webターミナル\",\n  \"sidebarconfig.webTerminalDescription\": \"Daytona サンドボックス（Daytonaが管理する隔離された一時的な実行環境）へのWebターミナルアクセス。\",\n  \"sidebarconfig.sshAccess\": \"SSHアクセス\",\n  \"sidebarconfig.sshAccessDescription\": \"Daytona サンドボックス（Daytonaが管理する隔離された一時的な実行環境）へのSSHアクセス。\",\n  \"sidebarconfig.previewAuthentication\": \"プレビューと認証\",\n  \"sidebarconfig.previewAuthenticationDescription\": \"プレビューURLと認証トークン。\",\n  \"sidebarconfig.customDomainAuthentication\": \"カスタムプレビュープロキシ\",\n  \"sidebarconfig.customDomainAuthenticationDescription\": \"プレビュー用プロキシを独自のドメインとロジックでカスタマイズします。\",\n  \"sidebarconfig.auditLogs\": \"監査ログ\",\n  \"sidebarconfig.auditLogsDescription\": \"Daytona の組織（組織全体）でのアクティビティを監視・追跡します。\",\n  \"sidebarconfig.webhooks\": \"Webhook\",\n  \"sidebarconfig.webhooksDescription\": \"Daytona の組織でイベントが発生した際に、リアルタイム通知を受け取ります。\",\n  \"sidebarconfig.regions\": \"リージョン\",\n  \"sidebarconfig.regionsDescription\": \"Daytonaのサンドボックス（サンドボックス（Daytonaが管理する隔離された一時的な実行環境））を起動するリージョン（ターゲット（リージョン））を設定します。\",\n  \"sidebarconfig.mcpServer\": \"MCPサーバー\",\n  \"sidebarconfig.daytona\": \"Daytona\",\n  \"sidebarconfig.sandbox\": \"サンドボックス（Daytonaが管理する隔離された一時的な実行環境）\",\n  \"sidebarconfig.common\": \"共通\",\n  \"sidebarconfig.syncPython\": \"Python を同期\",\n  \"sidebarconfig.asyncPython\": \"非同期Python\",\n  \"sidebarconfig.asyncDaytona\": \"AsyncDaytona\",\n  \"sidebarconfig.asyncSandbox\": \"AsyncSandbox\",\n  \"sidebarconfig.dataAnalysis\": \"AIによるデータ分析\",\n  \"sidebarconfig.pty\": \"擬似ターミナル (PTY)\",\n  \"sidebarconfig.ptyDescription\": \"DaytonaのTS SDK / Python SDKを使用して、サンドボックス（Daytonaが管理する隔離された一時的な実行環境）でPTYセッションを管理する方法を学びます。\"\n}\n"
  },
  {
    "path": "apps/docs/src/data/i18n/ja.json",
    "content": "{\n  \"2e675b4cced33496.t\": \"div\",\n  \"2e675b4cced33496.i\": 1,\n  \"2e675b4cced33496.c.t\": \"a\",\n  \"2e675b4cced33496.c.i\": 2,\n  \"2e675b4cced33496.c.c\": \"デモを申し込む\",\n  \"43b449db9b205d7e\": \"スター\",\n  \"28b93171152b0f3f\": \"daytona.io を検索\"\n}"
  },
  {
    "path": "apps/docs/src/env.d.ts",
    "content": "// eslint-disable-next-line\n/// <reference path=\"../.astro/types.d.ts\" />\n"
  },
  {
    "path": "apps/docs/src/fonts/font-face.css",
    "content": "@font-face {\n  font-family: 'Berkeley Mono';\n  src: url('./BerkeleyMono-Regular.otf');\n  font-weight: 400;\n  font-display: swap;\n}\n\n@font-face {\n  font-family: 'Inter';\n  src: url('./Inter-Regular.ttf');\n  font-weight: 400;\n  font-display: swap;\n}\n\n@font-face {\n  font-family: 'Inter';\n  src: url('./Inter-Medium.ttf');\n  font-weight: 500;\n  font-display: swap;\n}\n\n@font-face {\n  font-family: 'Inter';\n  src: url('./Inter-SemiBold.ttf');\n  font-weight: 600;\n  font-display: swap;\n}\n"
  },
  {
    "path": "apps/docs/src/i18n/generateI18nConfig.ts",
    "content": "import { getLocaleProperties } from 'generaltranslation'\n\nimport config from '../../gt.config.json'\n\n/**\n * Generates the i18n config for Astro.\n * @returns The i18n config for Astro.\n */\nexport function generateI18nConfig() {\n  return {\n    defaultLocale: config.defaultLocale,\n    locales: Object.fromEntries(\n      config.locales.map(locale => [\n        locale,\n        {\n          lang: locale,\n          label: getLocaleProperties(locale).nativeLanguageName,\n        },\n      ])\n    ),\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/i18n/generateI18nSchema.ts",
    "content": "import { z } from 'astro:content'\n\nimport defaultI18n from '../content/i18n/en.json'\n\n/**\n * Generates a schema for the i18n data.\n * @returns The schema for the i18n data.\n */\nexport function generateI18nSchema() {\n  return z.object({\n    ...Object.fromEntries(\n      Object.keys(defaultI18n).map(key => [key, z.string().optional()])\n    ),\n  })\n}\n"
  },
  {
    "path": "apps/docs/src/i18n/loadTranslations.ts",
    "content": "/**\n * Loads the translations for a given locale.\n * @param locale - The locale to load translations for.\n * @returns The translations for the given locale.\n */\nexport default async function loadTranslations(locale: string) {\n  const t = await import(`../data/i18n/${locale}.json`)\n  return t.default\n}\n"
  },
  {
    "path": "apps/docs/src/i18n/routing.ts",
    "content": "/**\n * Language Detection with Static Page Preservation\n *\n * This catch-all route provides browser-based language detection while maintaining static\n * MDX page generation. Since we want to keep all content pages static for performance,\n * we cannot use Astro middleware (which would require server-side rendering and has no\n * access to request headers for static pages).\n *\n * Implementation:\n * - Used with a dynamic route with prerender=false to access request headers for language detection\n * - Implements custom request forwarding since Astro.rewrite() doesn't properly route to static pages\n * - Acts as a transparent proxy that fetches the appropriate localized content and forwards the response\n *\n * This approach preserves static generation benefits while enabling dynamic language routing.\n */\nimport config from '../../gt.config.json'\n\nconst defaultLocale = config.defaultLocale\nconst allLocales = [defaultLocale, ...config.locales]\n\n/**\n * Detects preferred language from Accept-Language header\n */\nexport function getPreferredLanguage(request: Request): string {\n  const acceptLanguage = request.headers.get('accept-language')\n  if (!acceptLanguage) return defaultLocale\n\n  const supportedLocales = [defaultLocale, ...config.locales]\n  const languages = acceptLanguage\n    .split(',')\n    .map(lang => lang.split(';')[0].trim().toLowerCase())\n    .map(lang => lang.split('-')[0]) // Convert en-US to en\n\n  for (const lang of languages) {\n    if (supportedLocales.includes(lang)) {\n      return lang\n    }\n  }\n\n  return defaultLocale // fallback\n}\n\n/**\n * Checks if a path segment contains a locale prefix to prevent infinite loops\n */\nexport function isLocalizedPath(slug: string | undefined): boolean {\n  if (!slug) return false\n  const firstSegment = slug.split('/')[0]\n  return allLocales.includes(firstSegment)\n}\n\n/**\n * Creates a transparent proxy request to serve localized content\n * This bypasses Astro.rewrite() limitations with static routes\n */\nexport async function proxyLocalizedContent(\n  targetPath: string,\n  originalRequest: Request\n): Promise<Response> {\n  try {\n    const targetUrl = new URL(targetPath, new URL(originalRequest.url).origin)\n\n    const response = await fetch(targetUrl.toString(), {\n      method: originalRequest.method,\n      headers: originalRequest.headers,\n      body: originalRequest.body,\n    })\n\n    // Filter out headers that cause compression issues\n    const filteredHeaders = new Headers()\n    for (const [key, value] of response.headers.entries()) {\n      // Skip headers that can cause decoding issues when proxying\n      if (\n        !['content-encoding', 'content-length', 'transfer-encoding'].includes(\n          key.toLowerCase()\n        )\n      ) {\n        filteredHeaders.set(key, value)\n      }\n    }\n\n    // Create a new response with filtered headers\n    return new Response(response.body, {\n      status: response.status,\n      statusText: response.statusText,\n      headers: filteredHeaders,\n    })\n  } catch (error) {\n    console.error('Proxy request failed:', error)\n    return new Response('Internal Server Error', { status: 500 })\n  }\n}\n\n/**\n * Main routing handler for language detection and content serving\n */\nexport async function handleLanguageRouting(\n  request: Request,\n  slug = '',\n  redirectFn: (path: string) => Response\n): Promise<Response> {\n  // Don't handle already-localized paths to prevent infinite loops\n  if (isLocalizedPath(slug)) {\n    return new Response('Not Found', { status: 404 })\n  }\n\n  const preferredLanguage = getPreferredLanguage(request)\n\n  if (preferredLanguage !== defaultLocale) {\n    // Redirect to localized version (changes URL)\n    return redirectFn(`/docs/${preferredLanguage}/${slug}`)\n  } else {\n    // Proxy to English version (maintains clean URL)\n    return proxyLocalizedContent(`/docs/${defaultLocale}/${slug}`, request)\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/i18n/utils.ts",
    "content": "import config from '../../gt.config.json'\n\nconst defaultLocale = config.defaultLocale\n\n/**\n * Localizes a path to a given locale.\n * @param path - The path to localize.\n * @param locale - The locale to localize to.\n * @param currentLocale - The current locale.\n * @returns The localized path.\n */\nexport function localizePath(\n  path: string,\n  locale: string = defaultLocale,\n  currentLocale?: string\n): string {\n  if (!currentLocale || !path.startsWith(`/docs/${currentLocale}`)) {\n    return path.replace(`/docs`, `/docs/${locale}`)\n  }\n  return path.replace(`/docs/${currentLocale}`, `/docs/${locale}`)\n}\n"
  },
  {
    "path": "apps/docs/src/middleware.ts",
    "content": "import { defineMiddleware } from 'astro:middleware'\n\nimport { redirects } from './utils/redirects'\n\nexport const onRequest = defineMiddleware(({ request, redirect }, next) => {\n  const url = new URL(request.url)\n  const path = url.pathname.replace(/\\/$/, '')\n\n  // Match /docs/old-slug or /docs/{locale}/old-slug\n  const match = path.match(/^\\/docs(?:\\/([a-z]{2}))?\\/(.+)$/)\n  if (match) {\n    const locale = match[1]\n    const slug = match[2]\n    const newSlug = redirects[slug]\n    if (newSlug) {\n      const target = locale ? `/docs/${locale}/${newSlug}` : `/docs/${newSlug}`\n      return redirect(target, 301)\n    }\n  }\n\n  return next()\n})\n"
  },
  {
    "path": "apps/docs/src/pages/[...slug].astro",
    "content": "---\nimport { handleLanguageRouting } from '../i18n/routing'\n\nexport const prerender = false\n\nreturn await handleLanguageRouting(\n  Astro.request,\n  Astro.params.slug,\n  (path: string) => Astro.redirect(path)\n)\n---\n"
  },
  {
    "path": "apps/docs/src/pages/index.astro",
    "content": "---\nimport { handleLanguageRouting } from '../i18n/routing'\n\nexport const prerender = false\n\nreturn await handleLanguageRouting(\n  Astro.request,\n  Astro.params.slug,\n  (path: string) => Astro.redirect(path)\n)\n---\n"
  },
  {
    "path": "apps/docs/src/styles/_color.scss",
    "content": "body {\n  --white: #fff;\n  --bg-color: #0a0a0a;\n  --primary-text-color: #fff;\n  --secondary-text-color: #a2a2a2;\n  --accent-text-color: #d0cfcf;\n  --hover-color: #2ecc71;\n  --highlight-color: #007fff;\n  --border-color: #414141;\n  --nav-color: #828282;\n  --border: 1px solid var(--border-color);\n  --gradient-color: linear-gradient(180deg, #007fff, #8558de);\n  --gradient-hover-color: linear-gradient(90deg, #007fff 0%, #8558de 100%);\n  --active-state-color: #dedede;\n  --border-extra: #585858;\n  --block-bg-color: #161616;\n  --secondary-btn-color: #08ae78;\n  --active-border: 1px solid #525252;\n  --img-desc-text: #686868;\n  --secondary-hover-color: #88dfa2;\n  --blue-code-text: #3498db;\n  --orange-code-text: #e67e22;\n  --yellow-code-text: #f1c40f;\n  --purple-code-text: #8558de;\n  --img-border-color: #777777;\n  --blue-link: #59acff;\n  --system-error: #e74c3c;\n  --cta-surface-neutral-primary: #252525;\n\n  --foreground-color: #fafafa;\n\n  --selection-bg-color: #2fcc712b;\n  --selection-text-color: #2fcc71;\n}\n\nhtml[data-theme='light'] body {\n  --bg-color: #fff;\n  --border-color: #dedede;\n  --border-extra: #dedede;\n  --nav-color: #828282;\n  --primary-text-color: #121212;\n  --secondary-text-color: #686868;\n  --border: 1px solid var(--border-color);\n  --block-bg-color: #f7f7f7;\n  --active-border: 1px solid var(--border-color);\n  --darken-secondary-text-color: #424242;\n  --blue-link: #005fbe;\n  --cta-surface-neutral-primary: #dedede;\n  --hover-color: #08ae78;\n  --secondary-hover-color: #08ae78;\n\n  --foreground-color: #636363;\n\n  --selection-text-color: #058157;\n}\n"
  },
  {
    "path": "apps/docs/src/styles/_typography.scss",
    "content": "h1 {\n  font-family: 'Berkeley Mono', monospace;\n  font-size: 2.5rem;\n  font-weight: 400;\n  line-height: 1.2;\n  color: var(--primary-text-color);\n  letter-spacing: -0.04em;\n  margin-bottom: 64px;\n  @include for-tablet-screen-sizes {\n    font-size: 2.5rem;\n    margin-bottom: 40px;\n  }\n\n  @include for-mobile-screen-sizes {\n    font-size: 1.75rem;\n    margin-bottom: 32px;\n  }\n}\n\nh2 {\n  font-family: 'Berkeley Mono', monospace;\n  font-size: 2rem;\n  font-weight: 400;\n  line-height: 1.2;\n  color: var(--primary-text-color);\n  letter-spacing: -0.06em;\n  margin-bottom: 40px;\n  @include for-tablet-screen-sizes {\n    font-size: 1.75rem;\n    margin-bottom: 32px;\n  }\n\n  @include for-mobile-screen-sizes {\n    font-size: 1.5rem;\n    margin-bottom: 24px;\n  }\n}\n\nh3 {\n  font-family: 'Berkeley Mono', monospace;\n  font-size: 1.5rem;\n  font-weight: 400;\n  line-height: 1.2;\n  color: var(--primary-text-color);\n  letter-spacing: -0.04em;\n  margin-bottom: 24px;\n  @include for-tablet-screen-sizes {\n    font-size: 1.375rem;\n    margin-bottom: 20px;\n  }\n  @include for-mobile-screen-sizes {\n    margin-bottom: 16px;\n  }\n}\n\nh4 {\n  font-family: 'Berkeley Mono', monospace;\n  font-size: 1.25rem;\n  font-weight: 400;\n  line-height: 1.3;\n  color: var(--primary-text-color);\n  letter-spacing: -0.04em;\n  margin-bottom: 16px;\n  @include for-tablet-screen-sizes {\n    font-size: 1.25rem;\n    margin-bottom: 12px;\n  }\n  @include for-mobile-screen-sizes {\n    margin-bottom: 8px;\n  }\n}\n\nh5 {\n  font-family: 'Berkeley Mono', monospace;\n  font-size: 1.25rem;\n  font-weight: 400;\n  line-height: 1.4;\n  color: var(--primary-text-color);\n  letter-spacing: -0.04em;\n  margin-bottom: 16px;\n  @include for-tablet-screen-sizes {\n    font-size: 1.125rem;\n    margin-bottom: 12px;\n  }\n  @include for-mobile-screen-sizes {\n    margin-bottom: 8px;\n  }\n}\n\nh6 {\n  font-family: 'Berkeley Mono', monospace;\n  font-size: 1.25rem;\n  font-weight: 400;\n  line-height: 1.2;\n  color: var(--primary-text-color);\n  letter-spacing: -0.04em;\n  text-transform: uppercase;\n  margin-bottom: 16px;\n  @include for-tablet-screen-sizes {\n    font-size: 1rem;\n    margin-bottom: 12px;\n  }\n  @include for-mobile-screen-sizes {\n    margin-bottom: 8px;\n  }\n}\n\np {\n  font-family: 'Inter', sans-serif;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.6;\n  letter-spacing: -0.01rem;\n  color: var(--secondary-text-color);\n  //  color: var(--accent-text-color);\n}\n\na {\n  font-family: 'Inter', sans-serif;\n  font-size: 1rem;\n  font-weight: 400;\n  line-height: 1.6;\n  letter-spacing: -0.01rem;\n  color: var(--secondary-text-color);\n  text-decoration: none;\n}\n\nol {\n  margin-block-start: 0;\n  margin-block-end: 0;\n  padding-inline-start: 0;\n}\n\nhr {\n  border: none;\n  height: 1px;\n  color: var(--border-color);\n  background-color: var(--border-color);\n}\n\nstrong {\n  font-family: 'Inter', sans-serif;\n  font-weight: bold;\n  line-height: 1.6;\n  letter-spacing: -0.01em;\n  color: var(--primary-text-color);\n}\n\ncode {\n  text-wrap: wrap !important;\n  white-space: pre-wrap;\n  font-weight: 300;\n  letter-spacing: 0.008rem;\n  font-size: 0.875rem;\n  color: var(--primary-text-color);\n}\n\ndt {\n  font-weight: bold;\n  color: var(--primary-text-color);\n}\n\ndd {\n  display: inline-block;\n  margin-left: 2em;\n}\n"
  },
  {
    "path": "apps/docs/src/styles/_variables.scss",
    "content": "$screen-xs: 650px;\n$screen-lg: 1024px;\n$screen-l: 1280px;\n$screen-xl: 1400px;\n"
  },
  {
    "path": "apps/docs/src/styles/components/burger-menu.scss",
    "content": "@charset \"UTF-8\";\n/*!\n * Hamburgers\n * @description Tasty CSS-animated hamburgers\n * @author Jonathan Suh @jonsuh\n * @site https://jonsuh.com/hamburgers\n * @link https://github.com/jonsuh/hamburgers\n */\n\n// Settings\n// ==================================================\n$hamburger-padding-x: 0 !default;\n$hamburger-padding-y: 0 !default;\n$hamburger-layer-width: 10px !default;\n$hamburger-layer-height: 1px !default;\n$hamburger-layer-spacing: 2px !default;\n$hamburger-layer-color: var(--primary-text-color) !default;\n$hamburger-layer-border-radius: 6px !default;\n$hamburger-hover-opacity: 1 !default;\n$hamburger-active-layer-color: $hamburger-layer-color !default;\n$hamburger-active-hover-opacity: $hamburger-hover-opacity !default;\n\n// To use CSS filters as the hover effect instead of opacity,\n// set $hamburger-hover-use-filter as true and\n// change the value of $hamburger-hover-filter accordingly.\n$hamburger-hover-use-filter: false !default;\n$hamburger-hover-filter: opacity(50%) !default;\n$hamburger-active-hover-filter: $hamburger-hover-filter !default;\n\n// Types (Remove or comment out what you don’t need)\n// ==================================================\n$hamburger-types: (\n  3dx,\n  3dx-r,\n  3dy,\n  3dy-r,\n  3dxy,\n  3dxy-r,\n  arrow,\n  arrow-r,\n  arrowalt,\n  arrowalt-r,\n  arrowturn,\n  arrowturn-r,\n  boring,\n  collapse,\n  collapse-r,\n  elastic,\n  elastic-r,\n  emphatic,\n  emphatic-r,\n  minus,\n  slider,\n  slider-r,\n  spin,\n  spin-r,\n  spring,\n  spring-r,\n  stand,\n  stand-r,\n  squeeze,\n  vortex,\n  vortex-r\n) !default;\n\n// Base Hamburger (We need this)\n// ==================================================\n\n// Hamburger types\n// ==================================================\n\n// ==================================================\n// Cooking up additional types:\n//\n// The Sass for each hamburger type should be nested\n// inside an @if directive to check whether or not\n// it exists in $hamburger-types so only the CSS for\n// included types are generated.\n//\n// e.g. hamburgers/types/_new-type.scss\n//\n// @if index($hamburger-types, new-type) {\n//   .hamburger--new-type {\n//     ...\n//   }\n// }\n\n// Hamburger\n// ==================================================\n.hamburger {\n  padding: $hamburger-padding-y $hamburger-padding-x;\n  display: inline-block;\n  cursor: pointer;\n  outline: none;\n  transition-property: opacity, filter;\n  transition-duration: 0.15s;\n  transition-timing-function: linear;\n\n  // Normalize (<button>)\n  font: inherit;\n  color: inherit;\n  text-transform: none;\n  background-color: transparent;\n  border: 0;\n  margin: 0;\n  overflow: visible;\n\n  &:hover {\n    @if $hamburger-hover-use-filter == true {\n      filter: $hamburger-hover-filter;\n    } @else {\n      opacity: $hamburger-hover-opacity;\n    }\n  }\n\n  &.is-active {\n    @include for-hover-state {\n      &:hover {\n        @if $hamburger-hover-use-filter == true {\n          filter: $hamburger-active-hover-filter;\n        } @else {\n          opacity: $hamburger-active-hover-opacity;\n        }\n      }\n    }\n\n    .hamburger-inner,\n    .hamburger-inner::after,\n    .hamburger-inner::before {\n      background-color: $hamburger-active-layer-color;\n    }\n  }\n}\n\n.search {\n  img {\n    width: $hamburger-layer-width;\n  }\n}\n\n.hamburger-box {\n  width: 10px;\n  height: 10px;\n  display: block;\n  position: relative;\n  padding: 10px;\n  border: var(--border);\n\n  @include for-tablet-screen-sizes {\n    width: 9px;\n    height: 9px;\n  }\n\n  @include for-mobile-screen-sizes {\n    width: 9px;\n    height: 8px;\n  }\n}\n\n.hamburger-inner {\n  display: block;\n  top: 50%;\n  margin-top: calc($hamburger-layer-height / -2);\n  left: 8px;\n\n  &,\n  &::after,\n  &::before {\n    width: 13px;\n    height: $hamburger-layer-height;\n    background-color: $hamburger-layer-color;\n    border-radius: $hamburger-layer-border-radius;\n    position: absolute;\n    transition-property: transform;\n    transition-duration: 0.15s;\n    transition-timing-function: ease;\n    background-color: #fff;\n  }\n\n  &::after,\n  &::before {\n    content: '';\n    display: block;\n  }\n\n  &::before {\n    top: ($hamburger-layer-spacing + $hamburger-layer-height) * -1;\n  }\n\n  &::after {\n    bottom: ($hamburger-layer-spacing + $hamburger-layer-height) * -1;\n  }\n}\n\n@if index($hamburger-types, spin) {\n  /*\n\t * Spin\n\t */\n  .hamburger--spin {\n    .hamburger-inner {\n      transition-duration: 0.22s;\n      transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);\n\n      &::before {\n        transition:\n          top 0.1s 0.25s ease-in,\n          opacity 0.1s ease-in;\n      }\n\n      &::after {\n        transition:\n          bottom 0.1s 0.25s ease-in,\n          transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19);\n      }\n    }\n\n    &.is-active {\n      .hamburger-inner {\n        transform: rotate(225deg);\n        transition-delay: 0.12s;\n        transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);\n\n        &::before {\n          top: 0;\n          opacity: 0;\n          transition:\n            top 0.1s ease-out,\n            opacity 0.1s 0.12s ease-out;\n        }\n\n        &::after {\n          bottom: 0;\n          transform: rotate(-90deg);\n          transition:\n            bottom 0.1s ease-out,\n            transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1);\n        }\n      }\n    }\n  }\n}\n\n.mobile-menu {\n  display: none;\n  background-color: #0a0a0a;\n  color: var(--primary-text-color);\n  position: absolute;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  z-index: 1;\n\n  .nav__item a {\n    border: none;\n  }\n}\n\n.mobile-navigation {\n  display: none;\n\n  @include for-tablet-screen-sizes {\n    display: flex;\n    align-items: center;\n\n    .nav__items_side_menu {\n      column-gap: 0;\n    }\n  }\n  position: relative;\n  z-index: 999;\n  background: var(--bg-color);\n  padding: 20px;\n\n  @include for-tablet-screen-sizes {\n    padding: 20px 0;\n    align-items: center;\n  }\n  @include for-mobile-screen-sizes {\n    padding: 20px;\n  }\n}\n\n.mobile-menu.show-menu {\n  height: 100vh;\n  margin-top: 70px;\n  padding: 10px 20px 40px;\n  background: var(--bg-color);\n\n  @include for-tablet-screen-sizes {\n    padding: 0 60px;\n    margin-top: 63px;\n    z-index: 999;\n  }\n\n  @include for-mobile-screen-sizes {\n    padding: 10px 20px 40px;\n  }\n}\n\n.mobile-menu {\n  transition: 0.6s;\n  width: 100%;\n  height: 100%;\n  top: -100%;\n  display: none;\n  box-sizing: border-box;\n\n  ul {\n    list-style: none;\n    padding: 0;\n    display: flex;\n    flex-direction: column;\n    align-items: left;\n    gap: 16px;\n    margin-bottom: 40px;\n\n    li {\n      border-top: var(--border);\n      padding-top: 16px;\n    }\n  }\n\n  a {\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 1rem;\n    font-weight: 400;\n    line-height: 1.3;\n    color: var(--primary-text-color);\n  }\n}\n\n@include for-tablet-screen-sizes {\n  .mobile-menu.show-menu {\n    display: block;\n    padding: 0;\n    margin-top: 138px;\n    height: fit-content;\n  }\n\n  @include for-mobile-screen-sizes {\n    .mobile-menu.show-menu {\n      padding: 0 20px;\n    }\n  }\n\n  .hamburger.show-menu .hamburger-inner {\n    background-color: transparent !important;\n    &::before {\n      top: -1px;\n      transform: rotate(45deg) translateY(1px) translateX(1px);\n    }\n\n    &::after {\n      bottom: 1px;\n      transform: rotate(-45deg) translateY(1px) translateX(-1px);\n    }\n  }\n\n  .hamburger.show-menu {\n    display: block;\n  }\n}\n\n.mobile-nav-btn {\n  display: none;\n\n  @include for-tablet-screen-sizes {\n    display: grid;\n    gap: 10px;\n    margin-top: 16px;\n    margin-bottom: 28px;\n    margin-left: unset;\n  }\n\n  .github {\n    background: var(--block-bg-color);\n    border-radius: 3px;\n\n    a {\n      display: flex;\n      gap: 8px;\n      justify-content: center;\n      line-height: 2.14;\n    }\n  }\n\n  .call {\n    background: #007fff33;\n    text-align: center;\n    border-radius: 3px;\n\n    a {\n      line-height: 2.14;\n      color: #007fff;\n    }\n  }\n\n  .call .nav__link {\n    transition: 0.6s;\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/styles/components/cards.scss",
    "content": ".image-card {\n  width: 100%;\n  aspect-ratio: 1;\n  justify-content: center;\n  align-items: center;\n  background: var(--block-bg-color);\n  transition: 0.6s;\n  border-radius: 3px;\n\n  @include for-hover-state {\n    &:hover {\n      opacity: 0.6;\n    }\n  }\n\n  figure {\n    display: flex;\n    padding: 14px;\n    height: 100%;\n    justify-content: center;\n    align-items: center;\n    img {\n      object-fit: scale-down;\n      width: 100%;\n      max-width: 52px;\n      height: 100%;\n      transition: 0.6s;\n    }\n  }\n}\n\n.title-card {\n  text-decoration: none !important;\n  width: 100%;\n  border-radius: 3px;\n\n  @include for-hover-state {\n    opacity: 1;\n    &:hover h6 {\n      color: var(--hover-color);\n    }\n  }\n\n  figure {\n    display: flex;\n    width: 100%;\n    background: var(--block-bg-color);\n    justify-content: center;\n    align-items: center;\n    margin-bottom: 10px;\n    aspect-ratio: 15 / 8;\n    > svg path {\n      fill: var(--primary-text-color);\n    }\n\n    @include for-mobile-screen-sizes {\n      display: grid;\n      justify-content: center;\n      aspect-ratio: unset;\n      height: 120px;\n    }\n  }\n\n  h6 {\n    font-family: 'Inter', sans-serif;\n    line-height: 1.2;\n    letter-spacing: -0.01rem;\n    font-size: 1rem;\n    font-weight: 600;\n    color: var(--primary-text-color);\n    text-transform: none;\n    transition: 0.6s;\n  }\n}\n\n.description-card {\n  text-decoration: none !important;\n  border-radius: 3px;\n\n  @include for-mobile-screen-sizes {\n    font-size: 0.75rem;\n    font-weight: 500;\n    line-height: 1.4;\n    letter-spacing: -0.015em;\n  }\n\n  @include for-hover-state {\n    &:hover {\n      a {\n        opacity: 1;\n      }\n      h6 {\n        color: var(--hover-color);\n      }\n\n      .system-options-img {\n        border-color: var(--hover-color);\n      }\n    }\n  }\n\n  p {\n    font-family: 'Inter', sans-serif;\n    font-size: 1rem;\n    font-weight: 400;\n    line-height: 1.6;\n    letter-spacing: -0.01em;\n    color: var(--secondary-text-color);\n  }\n\n  figure {\n    width: 100%;\n    background: var(--block-bg-color);\n    display: grid;\n    place-items: center;\n    justify-content: center;\n    align-items: center;\n    margin-bottom: 16px;\n    border: 1px solid var(--block-bg-color);\n    transition: 0.6s;\n    aspect-ratio: 2/1;\n    > svg {\n      rect,\n      line {\n        stroke: var(--primary-text-color);\n      }\n    }\n  }\n\n  h6 {\n    font-family: 'Berkeley Mono', monospace;\n    line-height: 1.4;\n    letter-spacing: -0.04em;\n    color: var(--primary-text-color);\n    font-size: 1rem;\n    text-transform: none;\n    transition: 0.6s;\n    margin-bottom: 5px;\n  }\n}\n\nh6 {\n  font-weight: 700;\n  letter-spacing: -0.05rem;\n  line-height: 1;\n}\n\n.card-grid {\n  margin-bottom: 80px;\n}\n\n.link-card {\n  display: flex;\n  flex-direction: column;\n  padding: 12px;\n  border: 1px solid var(--border-color);\n  border-radius: 8px;\n  text-decoration: none !important;\n  background: transparent;\n  transition:\n    border-color 0.2s ease,\n    background-color 0.2s ease;\n  height: 100%;\n  width: 100%;\n\n  .title {\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 1rem;\n    font-weight: 600;\n    color: var(--primary-text-color);\n    margin-bottom: 8px;\n    display: block;\n  }\n\n  .description p {\n    font-family: 'Inter', sans-serif;\n    font-size: 0.875rem;\n    line-height: 1.5;\n    color: var(--secondary-text-color);\n    display: block;\n  }\n\n  &:hover {\n    background-color: var(--block-bg-color);\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/styles/components/docs-footer.scss",
    "content": ".docs-footer__container {\n  font-family: 'Inter', sans-serif;\n\n  &__support-links,\n  &__bottom-bar {\n    grid-column-start: 2;\n    margin: 0;\n\n    @include for-tablet-screen-sizes {\n      grid-column-start: 1;\n    }\n  }\n\n  &__support-links {\n    border-bottom: var(--border);\n    padding-bottom: 20px;\n    margin-bottom: 20px;\n\n    p {\n      font-size: 0.75rem;\n      line-height: 1.4;\n      color: var(--secondary-text-color);\n      letter-spacing: 0.015rem;\n\n      img {\n        margin-right: 5px;\n      }\n\n      a {\n        font-size: 0.75rem;\n        font-weight: 500;\n        line-height: 1.4;\n        letter-spacing: 0.015rem;\n        color: var(--primary-text-color);\n        transition: 0.6s;\n\n        @include for-hover-state {\n          &:hover {\n            opacity: 0.6;\n          }\n        }\n      }\n    }\n  }\n\n  &__bottom {\n    display: flex;\n    flex-wrap: wrap;\n    flex-direction: row;\n    margin: 27px 0 17px;\n    align-items: center;\n    gap: 14px;\n\n    &-block {\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      gap: 14px;\n\n      @include for-mobile-screen-sizes {\n        flex: 1 1 50%;\n      }\n\n      p {\n        font-family: 'Berkeley Mono', monospace;\n        font-size: 0.75rem;\n        letter-spacing: -0.0075rem;\n        text-transform: uppercase;\n        color: var(--primary-text-color);\n        line-height: 1;\n      }\n\n      .divider {\n        &::before {\n          content: '/';\n          display: block;\n          color: var(--border-color);\n          font-size: 0.875rem;\n          font-family: 'Berkeley Mono', monospace;\n          font-weight: 400;\n\n          @include for-mobile-screen-sizes {\n            display: none;\n          }\n        }\n      }\n    }\n\n    .menu-list {\n      display: flex;\n      gap: 16px;\n      order: 1;\n\n      @include for-mobile-screen-sizes {\n        order: 2;\n      }\n\n      a {\n        font-size: 0.75rem;\n        line-height: 1.4;\n        letter-spacing: -0.015rem;\n        font-weight: 500;\n        color: var(--secondary-text-color);\n        transition: 0.6s;\n\n        @include for-hover-state {\n          &:hover {\n            opacity: 0.6;\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/styles/components/markdown.scss",
    "content": ".markdown-content {\n  > :not(h1, h2, h3, h4, h5, h6, p, aside) {\n    margin-bottom: 60px;\n    @include for-mobile-screen-sizes {\n      margin-bottom: 40px;\n    }\n  }\n\n  svg {\n    max-width: 100%;\n  }\n\n  > h2[id],\n  > h3[id],\n  > h4[id],\n  > h5[id] {\n    margin-top: 56px;\n    margin-bottom: 16px;\n    position: relative;\n\n    .heading-anchor {\n      opacity: 0;\n      position: absolute;\n      right: 100%;\n      top: 52%;\n      transform: translateY(-50%);\n      padding-right: 0.25em;\n      font-size: 0.875em;\n      color: var(--secondary-text-color);\n      text-decoration: none;\n      transition: opacity 150ms ease, color 150ms ease;\n\n      @include for-hover-state {\n        &:hover {\n          color: var(--hover-color);\n        }\n      }\n\n      @include for-mobile-screen-sizes {\n        position: absolute;\n        right: 100%;\n        margin-right: 0.1em;\n        padding-right: 0;\n\n        &.visible {\n          opacity: 1;\n        }\n      }\n    }\n\n    @include for-hover-state {\n      &:hover .heading-anchor {\n        opacity: 1;\n      }\n    }\n  }\n\n  > p {\n    margin: 24px 0;\n  }\n\n  > hr {\n    margin: 40px 0;\n  }\n\n  > :first-child {\n    margin-top: 0 !important;\n    padding-top: 0 !important;\n  }\n\n  > :last-child {\n    margin-bottom: 0;\n  }\n\n  > p,\n  ol,\n  ul {\n    a {\n      color: var(--primary-text-color);\n      font-weight: 500;\n      text-decoration: underline;\n      text-decoration-color: var(--active-state-color);\n      text-underline-offset: 3.2px;\n      transition-duration: 250ms;\n\n      @include for-hover-state {\n        &:hover {\n          // opacity: 0.6;\n          color: var(--primary-text-color);\n          text-decoration-color: var(--hover-color);\n        }\n      }\n\n      // This color is overwriting every a tag\n      //&:visited {\n      //  color: var(--secondary-text-color) !important;\n      //}\n    }\n  }\n\n\n  > p {\n    @include for-mobile-screen-sizes {\n      margin-bottom: 40px;\n    }\n  }\n\n  p > code,\n  strong > code {\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 0.875rem;\n    font-weight: 400;\n    line-height: 1.6;\n    letter-spacing: -0.04em;\n    border: 0.5px solid var(--border-extra);\n    padding: 2px 6px;\n    color: var(--hover-color);\n    background-color: var(--block-bg-color);\n    border-radius: 4px;\n    white-space: nowrap;\n  }\n\n  > blockquote {\n    margin: 0 0 34px;\n    border-left: 2px solid var(--hover-color);\n    padding-left: 20px;\n    font-style: italic;\n    font-weight: 300;\n    opacity: 0.9;\n    @include for-tablet-screen-sizes {\n      margin: 63px 0 40px;\n      padding-left: 30px;\n    }\n\n    @include for-mobile-screen-sizes {\n      margin: 43px 0 39px;\n    }\n\n    & svg path {\n      fill: var(--hover-color);\n    }\n\n    code {\n      background-color: var(--nav-color);\n      padding: 0.14rem 0.4rem;\n      border-radius: 4px;\n      font-size: 0.8rem;\n      font-style: normal;\n    }\n\n    strong {\n      font-style: normal;\n    }\n\n    a {\n      color: var(--accent-color);\n      font-weight: 300;\n      text-decoration: underline;\n      font-style: normal;\n      text-decoration-color: var(--accent-color);\n      text-underline-offset: 3.2px;\n      transition-duration: 250ms;\n\n      @include for-hover-state {\n        &:hover {\n          // opacity: 0.6;\n          text-decoration-color: var(--hover-color);\n        }\n      }\n    }\n\n    p {\n      margin-top: 11px;\n      letter-spacing: -0.14px;\n      padding-right: 4px;\n\n      @include for-tablet-screen-sizes {\n        font-size: 1.25rem;\n        line-height: 1.4;\n        margin-top: 10px;\n        letter-spacing: -0.0125rem;\n      }\n\n      @include for-mobile-screen-sizes {\n        letter-spacing: -0.25px;\n        padding-right: 0;\n        margin-top: 7px;\n      }\n    }\n\n    .author-handle {\n      font-size: 1rem;\n      font-weight: 400;\n      line-height: 1.4;\n      letter-spacing: -0.01rem;\n      color: var(--secondary-text-color);\n      display: flex;\n      gap: 15px;\n      text-transform: uppercase;\n      font-family: 'Berkeley Mono', monospace;\n      padding-top: 4px;\n\n      @include for-tablet-screen-sizes {\n        margin-top: 14px;\n      }\n    }\n  }\n  > .table-wrapper {\n    position: relative;\n\n    > table {\n      border-collapse: collapse;\n      color: var(--primary-text-color);\n      width: 100%;\n\n      th,\n      td {\n        padding: 0.5rem;\n        text-align: left;\n        word-break: break-word;\n        max-width: 10vw;\n      }\n\n      td {\n        font-family: 'Inter', sans-serif;\n        font-size: 1rem;\n        font-weight: 400;\n        line-height: 1.6;\n        letter-spacing: -0.01rem;\n        border-bottom: 1px solid var(--border-extra);\n      }\n\n      th {\n        font-family: 'Berkeley Mono', monospace;\n        font-size: 0.75rem;\n        font-weight: 400;\n        line-height: 1;\n        letter-spacing: -0.0075rem;\n        text-transform: uppercase;\n        border-bottom: 3px solid var(--border-extra);\n      }\n    }\n  }\n\n  @include for-mobile-screen-sizes {\n    > .table-wrapper {\n      overflow-x: auto;\n      white-space: nowrap;\n      padding: 0 20px;\n      margin: 0 -20px;\n      mask-image: linear-gradient(\n        to right,\n        transparent,\n        black 30px,\n        black calc(100% - 30px),\n        transparent 100%\n      );\n\n      > table {\n        th,\n        td {\n          max-width: fit-content;\n        }\n      }\n    }\n  }\n\n  > ol {\n    padding-inline-start: 18px;\n    margin: 0 0 24px;\n    li {\n      padding-left: 10px;\n      margin: 0 0 4px;\n      font-family: Inter, sans-serif;\n      font-weight: 400;\n      font-size: 1rem;\n      line-height: 1.6;\n      letter-spacing: -0.01em;\n      color: var(--secondary-text-color);\n      &::marker {\n        color: var(--primary-text-color);\n      }\n\n      p {\n        margin: 0;\n      }\n\n      &:last-child {\n        margin-bottom: 0;\n      }\n    }\n\n    @include for-tablet-screen-sizes {\n      font-size: 1rem;\n    }\n  }\n\n  > ul {\n    // background: var(--block-bg-color);\n    padding: 0px 10px 0 0;\n    margin-bottom: 24px;\n    margin-top: 0;\n    list-style-image: url(/src/assets/icons/facts.svg);\n    margin-left: 14px;\n\n    @include for-mobile-screen-sizes {\n      margin-bottom: 40px;\n    }\n\n    li {\n      font-family: Inter, sans-serif;\n      font-weight: 400;\n      font-size: 1rem;\n      line-height: 1.6;\n      letter-spacing: -0.01em;\n      padding-left: 10px;\n      margin: 0 0 4px;\n      color: var(--secondary-text-color);\n\n      strong {\n        font-weight: 400;\n      }\n\n      code {\n        font-family: 'Berkeley Mono', monospace;\n        font-size: 0.88rem;\n        font-weight: 400;\n        line-height: 1.4;\n        color: var(--hover-color);\n        letter-spacing: -0.02em;\n        background-color: var(--block-bg-color);\n        padding: 0.1rem 0.4rem;\n        border-radius: 4px;\n      }\n\n      a {\n        font-weight: 400;\n        color: var(--primary-text-color);\n        @include for-mobile-screen-sizes {\n          font-size: 1rem;\n        }\n      }\n\n      &:last-child {\n        margin-bottom: 0;\n      }\n    }\n\n    li > ul {\n      padding: 0 15px;\n      margin: 0;\n      list-style: none;\n\n      li:before {\n        content: '- ';\n        color: var(--primary-text-color);\n      }\n    }\n  }\n\n  > details.idp-details {\n    cursor: pointer;\n    pointer-events: all;\n    padding: 0.6rem 0;\n    color: var(--primary-text-color);\n    margin: 1.4rem 0;\n    border-top: 1px solid #2ecc71;\n    border-bottom: 1px solid #2ecc71;\n  }\n\n  .container {\n    border: 1px solid #2ecc71;\n    margin: 1.2rem auto 0.6rem;\n  }\n\n  .keyboard-shortcut {\n    font-family: 'Inter', sans-serif;\n    font-size: 0.75rem;\n    font-weight: 500;\n    line-height: 1.4;\n    letter-spacing: -0.015rem;\n    border: 1px solid var(--secondary-text-color);\n    border-radius: 3px;\n    box-shadow: 0 1px 0 0 var(--secondary-text-color);\n    padding: 0.8px 6px;\n    color: var(--primary-text-color);\n  }\n\n  .container tbody {\n    width: 100%;\n  }\n  .container tr {\n    display: flexbox;\n  }\n\n  .container td,\n  th {\n    padding: 6px 16px;\n    text-align: center;\n    color: var(--primary-text-color);\n  }\n\n  .table-color tr:nth-child(even) {\n    background-color: var(--cta-surface-neutral-primary);\n  }\n\n  .table-color tr > td:nth-child(1) {\n    height: 100%;\n  }\n\n  .table-row {\n    display: flex;\n  }\n\n  > details[open] {\n    border-top: 0;\n    border-bottom: 0;\n    transition-duration: 250ms;\n    cursor: auto;\n  }\n\n  > details[open] > summary {\n    cursor: pointer;\n    font-family: 'Inter', sans-serif;\n    font-size: 1rem;\n  }\n\n  .starlight-aside {\n    margin-top: 32px;\n    margin-bottom: 32px;\n    padding: 24px;\n    border-inline-start: 2px solid;\n    background-color: var(--block-bg-color);\n    a {\n      font-family: Inter, sans-serif;\n      font-size: 1rem;\n      font-weight: 600;\n      line-height: 1.6;\n      letter-spacing: -0.01em;\n      text-decoration: underline;\n\n      color: var(--primary-text-color);\n      opacity: 1;\n      transition: opacity 0.6s;\n\n      @include for-hover-state {\n        &:hover {\n          opacity: 0.6;\n        }\n      }\n    }\n    &__title {\n      font-family: 'Berkeley Mono', monospace;\n      font-size: 1rem;\n      line-height: 1.4;\n      letter-spacing: -0.04em;\n      text-transform: capitalize;\n      color: var(--primary-text-color);\n      > svg {\n        width: 1rem;\n        height: 1rem;\n      }\n    }\n    &__content {\n      margin: 24px 0 0 0;\n      padding: 0;\n    }\n    &--note {\n      border-color: var(--blue-code-text);\n      .starlight-aside__icon {\n        color: var(--blue-code-text);\n      }\n    }\n    &--tip {\n      border-color: var(--hover-color);\n      .starlight-aside__icon {\n        color: var(--hover-color);\n      }\n    }\n    &--caution {\n      border-color: var(--system-error);\n      .starlight-aside__icon {\n        color: var(--system-error);\n      }\n    }\n    &--danger {\n      border-color: var(--system-error);\n      .starlight-aside__icon {\n        color: var(--system-error);\n      }\n    }\n\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n\n  .expressive-code {\n    margin-top: 0px;\n    margin-bottom: 32px;\n    border: 1px solid var(--border-extra);\n    border-radius: 3px;\n\n    .copy {\n      display: flex;\n    }\n\n    &[data-language='text'] .copy {\n      display: none;\n    }\n\n    .frame.is-terminal {\n      .header {\n        display: none;\n        border: none;\n        background: var(--bg-color);\n        border-bottom: 1px solid var(--border-extra);\n        color: var(--secondary-text-color);\n        border-radius: 3px;\n\n        &:before {\n          left: 8px;\n          height: 8px;\n          opacity: 1;\n          background-color: var(--border-extra);\n        }\n\n        &:after {\n          content: none;\n        }\n      }\n\n      .copy {\n        --button-spacing: 8px;\n      }\n    }\n\n    .copy .feedback {\n      background-color: var(--hover-color);\n      &:after {\n        border-inline-start-color: var(--hover-color);\n      }\n    }\n\n    .frame pre {\n      background: var(--bg-color);\n    }\n\n    pre {\n      border: none;\n      border-radius: 3px !important;\n    }\n\n    pre > code {\n      padding: 16px 0;\n    }\n\n    .ec-line {\n      font-family: 'Berkeley Mono', monospace;\n      font-size: 0.875rem;\n      font-weight: 400;\n      line-height: 1.6;\n      letter-spacing: -0.035rem;\n    }\n\n    .copy {\n      background: unset;\n      opacity: 1;\n      --button-spacing: 0.5rem;\n      button {\n        opacity: 1;\n        background-color: var(--bg-color);\n\n        &:after {\n          background-color: var(--secondary-text-color);\n          mask-image: url('/src/assets/icons/copy.svg');\n        }\n\n        &:before {\n          border: none;\n          opacity: 1;\n        }\n\n        &:hover {\n          div {\n            opacity: 0;\n          }\n          &:after {\n            background-color: var(--hover-color);\n          }\n        }\n      }\n    }\n  }\n\n  > starlight-tabs {\n    margin-bottom: 56px;\n\n    &:has(section[role='tabpanel'] > .expressive-code:first-child)\n      .tablist-wrapper\n      ul[role='tablist'] {\n      border-bottom: 1px solid transparent;\n    }\n\n    .tablist-wrapper {\n      margin-bottom: -1px;\n    }\n\n    .tablist-wrapper {\n      ul[role='tablist'] {\n        width: calc(100% - 5px);\n        margin: 0 auto;\n        border-bottom: 1px solid var(--border-extra);\n      }\n\n      .tab {\n        margin-bottom: -1px;\n        &:last-child {\n          a {\n            margin-right: 0;\n          }\n        }\n        a {\n          font-family: 'Berkeley Mono', monospace;\n          text-transform: uppercase;\n          font-size: 0.9em;\n          padding: 0;\n          margin-right: 16px;\n          font-weight: 400;\n          letter-spacing: -0.0075rem;\n          border-bottom: 1px solid transparent;\n          line-height: 28px;\n\n          &[role='tab'][aria-selected='true'] {\n            border-bottom: 1px solid var(--primary-text-color);\n          }\n        }\n      }\n    }\n\n    > section[role='tabpanel'] {\n      padding-left: 0;\n      padding-right: 0;\n      margin-left: 0;\n      margin-right: 0;\n      padding-top: 0px;\n      margin-top: 0px;\n    }\n\n    ol {\n      margin-top: 16px;\n      margin-bottom: 8px;\n    }\n\n    p {\n      margin-top: 16px;\n      margin-bottom: 16px;\n    }\n  }\n\n  .label {\n    margin-top: 0px;\n    margin-bottom: 40px;\n    padding-left: 8px;\n    border-inline-start: 1px solid;\n    background-color: var(--bg-color);\n    border-color: var(--hover-color);\n  }\n\n  .label p {\n    font-size: 0.9rem;\n  }\n}\n\nsection {\n  padding-left: 2em;\n  padding-top: 1em;\n}\n"
  },
  {
    "path": "apps/docs/src/styles/components/navbar.scss",
    "content": ".navbar {\n  background: var(--bg-color);\n\n  nav {\n    border-bottom: var(--border);\n  }\n\n  .logo-divider {\n    display: flex;\n    &:after {\n      content: '/';\n      font-family: 'Berkeley Mono', monospace;\n      font-size: 0.875rem;\n      line-height: 1.38;\n      letter-spacing: -0.04em;\n      color: var(--secondary-text-color);\n      align-self: center;\n      padding: 0 16px 0 20px;\n    }\n  }\n\n  .daytona-logo {\n    display: flex;\n\n    & svg {\n      width: 117px;\n      height: 26px;\n    }\n\n    & svg path {\n      fill: var(--primary-text-color);\n    }\n\n    & svg rect {\n      stroke: var(--primary-text-color);\n    }\n\n    @include for-hover-state {\n      &:hover svg {\n        opacity: 0.6;\n      }\n    }\n\n    // @include for-tablet-screen-sizes {\n    //   display: grid;\n    //   grid-template-columns: 24px 1fr;\n    //   align-items: center;\n    //   svg {\n    //     width: 26px;\n    //     height: 26px;\n    //   }\n    // }\n  }\n  .dotfiles-logo {\n    font-family: 'Berkeley Mono', monospace;\n    font-weight: 400;\n    font-size: 1rem;\n    line-height: 1.2;\n    letter-spacing: -0.01em;\n    display: flex;\n    align-items: center;\n    color: var(--primary-text-color);\n    padding-right: 4px;\n\n    & svg {\n      margin-right: 0.5rem;\n      > path,\n      circle {\n        transition: 0.6s;\n        stroke: var(--hover-color);\n      }\n    }\n    @include for-tablet-screen-sizes {\n      > svg {\n        display: none;\n      }\n    }\n\n    @include for-hover-state {\n      &:hover {\n        opacity: 0.6;\n      }\n    }\n  }\n\n  .navbar-item {\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 0.875rem;\n    line-height: 1.4;\n    font-weight: 400;\n    letter-spacing: -0.04em;\n    text-transform: uppercase;\n    color: var(--primary-text-color);\n    padding-right: 8px;\n    padding-left: 8px;\n\n    @include for-hover-state {\n      &:hover {\n        opacity: 0.6;\n      }\n    }\n  }\n\n  .desktop-only {\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    padding: 16px 0;\n    max-width: 1248px;\n    margin: auto;\n\n    @include for-tablet-screen-sizes {\n      display: none;\n    }\n  }\n\n  .nav__items_menu {\n    display: flex;\n    font-family: 'Berkeley Mono', monospace;\n    font-size: 0.875rem;\n    text-transform: uppercase;\n    list-style: none;\n    text-decoration: none;\n    line-height: 1.3;\n    letter-spacing: -0.035rem;\n    transition: 0.6s;\n    &:before {\n      content: '/';\n      font-family: 'Berkeley Mono', monospace;\n      font-size: 0.875rem;\n      line-height: 1.38;\n      letter-spacing: -0.035rem;\n      color: var(--border-color);\n      align-self: center;\n      padding: 0 16px;\n    }\n\n    ul {\n      display: flex;\n      column-gap: 16px;\n      list-style: none;\n      padding: 0;\n      margin: 0;\n    }\n\n    a {\n      @include for-hover-state {\n        &:hover {\n          color: var(--hover-color);\n        }\n      }\n    }\n  }\n}\n\n.nav__items_side_menu {\n  display: flex;\n  flex-shrink: 0;\n  margin-left: auto;\n  column-gap: 8px;\n  align-items: center;\n\n  .nav__item_search {\n    @include for-tablet-screen-sizes {\n      border: var(--border);\n    }\n\n    @include for-hover-state {\n      &:hover button {\n        cursor: pointer;\n      }\n    }\n\n    .nav__link {\n      display: inline;\n      vertical-align: middle;\n      padding: 7px 0;\n\n      & svg {\n        @include for-tablet-screen-sizes {\n          width: 12px;\n          height: 12px;\n        }\n\n        path {\n          transition: 0.6s;\n          fill: var(--primary-text-color);\n        }\n      }\n\n      @include for-hover-state {\n        &:hover svg path {\n          opacity: 0.6;\n          transition: 0.6s;\n          cursor: pointer;\n        }\n      }\n\n      @include for-tablet-screen-sizes {\n        display: grid;\n        justify-content: center;\n        align-items: center;\n        padding: 1px 0 0;\n        width: 29px;\n        height: 29px;\n      }\n\n      @include for-mobile-screen-sizes {\n        width: 28px;\n        height: 28px;\n        justify-content: center;\n\n        & svg {\n          width: 11px;\n          height: 11px;\n        }\n      }\n    }\n  }\n\n  .nav__item_search,\n  .nav__item_hamburger__menu {\n    a {\n      text-align: center;\n      justify-content: center;\n      line-height: 0;\n      text-transform: uppercase;\n    }\n  }\n\n  .nav__item_hamburger__menu {\n    display: flex;\n    align-items: center;\n  }\n\n  .call,\n  .github {\n    border-radius: 3px;\n    transition: 0.6s;\n\n    a {\n      font-size: 0.875rem;\n      font-family: 'Berkeley Mono', monospace;\n      font-weight: 400;\n      padding: 4px 16px;\n      border-radius: 3px;\n      height: 30px;\n      display: inline-block;\n      text-transform: none;\n    }\n  }\n\n  .call {\n    background: #007fff33;\n    padding: 1px 0;\n    flex-shrink: 0;\n\n    a {\n      color: #007fff;\n    }\n\n    @include for-hover-state {\n      &:hover {\n        background: #007fff99;\n\n        a {\n          color: #fff;\n        }\n      }\n    }\n  }\n\n  .github {\n    background: var(--block-bg-color);\n    border: var(--border);\n    border-color: var(--block-bg-color);\n\n    a {\n      min-width: 100px;\n      display: flex;\n      gap: 8px;\n      align-items: center;\n      color: var(--primary-text-color);\n    }\n\n    & svg path {\n      transition: 0.6s;\n      fill: var(--secondary-text-color);\n    }\n\n    @include for-hover-state {\n      &:hover {\n        background: var(--secondary-text-color);\n        border-color: var(--secondary-text-color);\n\n        a {\n          color: var(--white);\n        }\n\n        & svg path {\n          fill: var(--white);\n        }\n      }\n    }\n\n    img {\n      display: block;\n    }\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/styles/components/page-frame.scss",
    "content": ".page {\n  display: flex;\n  flex-direction: column;\n  min-height: 100vh;\n  margin: 0 auto;\n  max-width: 1248px;\n\n  @include for-pc-screen-sizes {\n    margin: 0 80px;\n  }\n\n  @include for-laptop-screen-sizes {\n    margin: 0 28px;\n  }\n\n  @include for-mobile-screen-sizes {\n    margin: 0 20px;\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/styles/components/search.scss",
    "content": "#search-icon {\n  background: -var(--bg-color);\n  cursor: pointer;\n}\n\n#search-icon-mobile {\n  position: absolute;\n  margin-right: 52px;\n  top: 40px;\n  right: 16px;\n  transform: translateY(-50%);\n  cursor: pointer;\n  z-index: 10;\n}\n\nnav.mobile-navigation {\n  @media (max-width: 650px) {\n    margin: 0 -20px;\n    padding: 20px;\n  }\n}\n\n.searchbox-wrapper {\n  position: fixed;\n  margin-top: 32px;\n  margin-bottom: 0px;\n  top: 32px;\n  left: 0;\n  right: 0;\n  width: 100%;\n  max-width: 1248px;\n  background: var(--bg-color);\n  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n  max-height: 100%;\n  overflow-y: auto;\n  margin-left: auto;\n  margin-right: auto;\n}\n\n.search-bar-container {\n  position: sticky;\n  top: 0;\n  background: var(--bg-color);\n  padding: 12px 12px 12px 12px;\n  border: none;\n  margin-bottom: 0px;\n  z-index: 1;\n}\n\n.search-content {\n  padding: 0 20px;\n  flex-grow: 1;\n}\n\n.search-index-filters {\n  display: flex;\n  flex-wrap: wrap;\n  gap: 8px;\n  margin-top: 0px;\n  margin-bottom: 16px;\n  align-items: center;\n}\n\n.search-index-filter-chip {\n  padding: 8px 16px;\n  border-radius: 4px;\n  border: 1px solid var(--border-color, #e0e0e0);\n  background: var(--bg-color);\n  color: var(--primary-text-color);\n  font-size: 14px;\n  font-weight: 500;\n  cursor: pointer;\n  transition: border-color 0.15s, background 0.15s;\n\n  &:hover {\n    border-color: var(--secondary-text-color);\n  }\n\n  &.active {\n    border-color: var(--primary-text-color);\n    background: var(--block-bg-color);\n    color: var(--primary-text-color);\n  }\n\n  html[data-theme='light'] &.active {\n    border-color: var(--secondary-text-color);\n    background: var(--block-bg-color);\n    color: var(--primary-text-color);\n  }\n}\n\n.searchbox-wrapper::-webkit-scrollbar {\n  display: none;\n}\n\n.ais-SearchBox-form {\n  max-width: 1248px;\n  margin: 0 auto;\n  display: block;\n  height: 72px;\n  border: none;\n}\n\n.ais-SearchBox-input {\n  width: 100%;\n  border-radius: 4px;\n  border: 1px solid var(--secondary-text-color);\n  padding: 16px;\n  font-size: 15px;\n  text-align: left;\n  box-sizing: border-box;\n  margin-bottom: 40px;\n  background: var(--bg-color);\n}\n\n.ais-SearchBox-input:focus {\n  outline: none;\n  border: 1px solid var(--secondary-text-color);\n}\n\n.ais-SearchBox-submit,\n.ais-SearchBox-reset {\n  display: none;\n}\n\n.stats-pagination-wrapper {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  width: 100%;\n  max-width: 1248px;\n  margin: 0 auto;\n  padding-bottom: 16px;\n}\n\n.ais-Pagination {\n  display: flex;\n  list-style-type: none;\n  padding: 0;\n  margin: 0;\n  white-space: nowrap;\n  flex-wrap: nowrap;\n  overflow-x: visible;\n}\n\n.ais-Pagination-item {\n  display: inline-block;\n  margin: 0 5px;\n  flex-shrink: 0;\n}\n\n.ais-Pagination-link {\n  text-decoration: none;\n  padding: 4px 4px;\n  font-size: 14px;\n}\n\n.ais-Pagination::-webkit-scrollbar {\n  display: none;\n}\n\n.ais-Stats {\n  margin: 0;\n  font-size: 16px;\n}\n\n.custom-stats {\n  font-size: 20px;\n}\n\n.ais-Hits-list {\n  max-width: 1248px;\n  margin: 0 auto;\n  display: grid;\n  grid-template-columns: repeat(2, 1fr);\n  gap: 8px;\n  padding: 0;\n  padding-bottom: 32px;\n}\n\n[data-index='website'] .ais-Hits-list {\n  padding-bottom: 256px;\n}\n\n@media (max-width: 768px) {\n  .ais-Hits-list {\n    grid-template-columns: 1fr;\n  }\n\n  .custom-stats {\n    font-size: 16px;\n  }\n}\n\n.ais-Hits-item {\n  list-style: none;\n  margin: 0;\n  padding: 8px;\n}\n\n.ais-Highlight-highlighted,\nmark {\n  color: var(--highlight-color);\n  background-color: var(--bg-color);\n  font-style: normal;\n}\n\n.no-scroll {\n  overflow: hidden;\n}\n"
  },
  {
    "path": "apps/docs/src/styles/init.scss",
    "content": "html {\n  scroll-behavior: smooth;\n  scroll-padding-top: 60px;\n}\n\nbody {\n  background-color: var(--bg-color);\n}\n\nmain {\n  width: 100%;\n  height: 100%;\n  margin: 0;\n  padding: 0;\n  display: flex;\n  flex-direction: column;\n  background: var(--bg-color);\n  gap: 16px;\n}\n\nsection {\n  max-width: 1248px;\n  //margin: 0 80px;\n  padding-bottom: 0 !important;\n\n  @include for-laptop-screen-sizes {\n    margin: 0 40px;\n  }\n\n  @include for-mobile-screen-sizes {\n    margin: 0 20px;\n  }\n}\n\na {\n  text-decoration: unset;\n}\npre > code {\n  text-wrap: wrap !important;\n  white-space: pre-wrap;\n}\n\n::selection {\n  background-color: var(--selection-bg-color);\n  color: var(--selection-text-color);\n}\n"
  },
  {
    "path": "apps/docs/src/styles/mixins.scss",
    "content": "@mixin for-mobile-screen-sizes {\n  @media screen and (max-width: #{$screen-xs}) {\n    @content;\n  }\n}\n\n@mixin for-tablet-screen-sizes {\n  @media screen and (max-width: #{$screen-lg}) {\n    @content;\n  }\n}\n\n@mixin for-laptop-screen-sizes {\n  @media screen and (max-width: #{$screen-l}) {\n    @content;\n  }\n}\n\n@mixin for-pc-screen-sizes {\n  @media screen and (max-width: #{$screen-xl}) {\n    @content;\n  }\n}\n\n@mixin for-hover-state {\n  @media (hover: hover) and (pointer: fine) {\n    @content;\n  }\n}\n"
  },
  {
    "path": "apps/docs/src/styles/style.scss",
    "content": "@import './_color.scss';\n@import './_variables.scss';\n@import './mixins.scss';\n@import './init.scss';\n@import './_typography.scss';\n\n// components\n\n@import './components/markdown.scss';\n@import './components/navbar.scss';\n@import './components/burger-menu.scss';\n@import './components/page-frame.scss';\n@import './components/docs-footer.scss';\n@import './components/cards.scss';\n// @import './components/ides.scss';\n// @import './components/lois-backup.scss';\n"
  },
  {
    "path": "apps/docs/src/utils/md.js",
    "content": "export const processMarkdownContent = content =>\n  content\n    .replace(/^---[\\s\\S]*?---\\s*/, '')\n    .split('\\n')\n    .filter(line => {\n      const trimmed = line.trim()\n      return !(\n        /^(import\\s+.*from\\s+['\"](@components\\/|@assets\\/|@astrojs\\/starlight\\/components).*['\"];?|export\\s+(default|const|let|function|class)\\b)/.test(\n          trimmed\n        ) ||\n        trimmed.startsWith('<Tab') ||\n        trimmed.startsWith('</Tab')\n      )\n    })\n    .join('\\n')\n    .trim()\n\nconst ensureTrailingSlash = (value = '') =>\n  value.endsWith('/') ? value : `${value}/`\n\nconst isHttpUrl = url => url.startsWith('http://') || url.startsWith('https://')\n\nexport const toMarkdownUrl = (href, docsBaseUrl) => {\n  if (!href) return href\n\n  const base = ensureTrailingSlash(docsBaseUrl || 'https://daytona.io/docs')\n  let baseUrl\n  let targetUrl\n\n  try {\n    baseUrl = new URL(base)\n    targetUrl = new URL(href, baseUrl)\n  } catch {\n    return href\n  }\n\n  if (!isHttpUrl(targetUrl.href)) return href\n  if (!targetUrl.href.startsWith(baseUrl.href)) return href\n  if (/\\.mdx?$/i.test(targetUrl.pathname)) return targetUrl.href\n\n  let docPath = targetUrl.pathname.slice(baseUrl.pathname.length)\n  docPath = docPath.replace(/\\/+/g, '/').replace(/\\/+$/, '')\n\n  if (!docPath) docPath = 'index'\n  if (docPath.endsWith('/index')) {\n    const trimmed = docPath.slice(0, -'/index'.length)\n    docPath = trimmed || 'index'\n  }\n\n  const mdPath = docPath === 'index' ? 'index.md' : `${docPath}.md`\n  const anchor = targetUrl.hash || ''\n\n  return `${baseUrl.origin}${baseUrl.pathname}${mdPath}${anchor}`\n}\n\nexport const rewriteLinksToMd = (markdown, docsBaseUrl) => {\n  if (!markdown) return markdown\n\n  return markdown.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (match, text, href) => {\n    const trimmedHref = href.trim()\n\n    if (\n      !trimmedHref ||\n      trimmedHref.startsWith('#') ||\n      trimmedHref.startsWith('mailto:') ||\n      trimmedHref.startsWith('tel:')\n    ) {\n      return match\n    }\n\n    const rewritten = toMarkdownUrl(trimmedHref, docsBaseUrl)\n    if (!rewritten || rewritten === trimmedHref) {\n      return match\n    }\n\n    return `[${text}](${rewritten})`\n  })\n}\n\nexport default rewriteLinksToMd\n"
  },
  {
    "path": "apps/docs/src/utils/navigation.ts",
    "content": "// Navigation Configuration\n// This file defines the relationship between main navigation items and their related pages\nimport fs from 'node:fs'\nimport path from 'node:path'\n\nimport { NavigationCategory } from '../content/config'\n\nexport interface NavigationItem {\n  type: 'link' | 'group'\n  label?: string\n}\n\nexport interface NavigationLink extends NavigationItem {\n  type: 'link'\n  href: string\n  label: string\n  translations?: {\n    [key: string]: string\n  }\n  description?: string\n  disablePagination?: boolean\n  attrs?: {\n    icon?: string\n    [key: string]: any\n  }\n  external?: boolean\n  hideInSidebar?: boolean\n}\n\nexport interface MainNavigationLink extends NavigationLink {\n  // All links with that category will be shown in the sidebar when the link is active\n  relatedGroupCategory: NavigationCategory\n}\n\nexport interface NavigationGroup extends NavigationItem {\n  type: 'group'\n  // The category of the group, all links with that category will be shown in the sidebar when\n  // the link with that category or the main link that is related to the category is active\n  category: NavigationCategory\n  // Used to indicate the context of the current page.\n  // If the current page is the first item in the list, it is also used as the previous link in the pagination component.\n  // The referenced page should be a `MainNavigationLink`. It is ignored for `NavigationCategory.MAIN` groups.\n  homePageHref?: string\n  autopopulateFromDir?: string\n  translations?: {\n    [key: string]: string\n  }\n  entries?: (NavigationLink | MainNavigationLink)[]\n}\n\n// HELPER FUNCTIONS\n\nfunction normalizePath(path: string): string {\n  return path.replace(/\\/$/, '')\n}\n\nfunction getMainNavGroup(sidebarConfig: NavigationGroup[]): NavigationGroup {\n  return sidebarConfig.find(\n    group => group.category === NavigationCategory.MAIN\n  ) as NavigationGroup\n}\n\nfunction getNavGroupsByCategory(\n  sidebarConfig: NavigationGroup[],\n  category: NavigationCategory\n): NavigationGroup[] {\n  return sidebarConfig.filter(group => group.category === category)\n}\n\nfunction getNavLinksByCategory(\n  sidebarConfig: NavigationGroup[],\n  category: NavigationCategory\n): NavigationLink[] {\n  const groups = getNavGroupsByCategory(sidebarConfig, category)\n  return groups.flatMap(group => group.entries || []) as NavigationLink[]\n}\n\nfunction getNavGroupByHref(\n  sidebarConfig: NavigationGroup[],\n  href: string\n): NavigationGroup | undefined {\n  for (const group of sidebarConfig) {\n    if (!group.entries) continue\n\n    for (const entry of group.entries) {\n      if (entry.type === 'link' && comparePaths(entry.href, href)) {\n        return group\n      }\n    }\n  }\n  return undefined\n}\n\nfunction getNavLinkByHref(\n  sidebarConfig: NavigationGroup[],\n  href: string,\n  group?: NavigationGroup\n): NavigationLink | undefined {\n  group = group ?? getNavGroupByHref(sidebarConfig, href)\n\n  if (!group) return undefined\n\n  if (!group.entries) return undefined\n\n  return group.entries.find(\n    entry => entry.type === 'link' && comparePaths(entry.href, href)\n  ) as NavigationLink\n}\n\nfunction toCamelCase(filename: string): string {\n  const nameWithoutExt = path.parse(filename).name\n\n  return nameWithoutExt\n    .split(/[-_\\s]/)\n    .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n    .join('')\n}\n\nfunction populateEntriesFromDir(\n  group: NavigationGroup,\n  workspaceRoot: string = process.cwd()\n): NavigationLink[] {\n  if (!group.autopopulateFromDir) return group?.entries || []\n\n  const dirPath = path.join(\n    workspaceRoot,\n    '/src/content',\n    group.autopopulateFromDir\n  )\n\n  if (!fs.existsSync(dirPath)) {\n    console.warn(\n      `Directory ${dirPath} does not exist, cannot autopopulate navigation group`\n    )\n    return group?.entries || []\n  }\n\n  try {\n    const files = fs.readdirSync(dirPath, { withFileTypes: true })\n\n    const existingHrefs = new Set(\n      (group.entries || [])\n        .filter(entry => entry.type === 'link')\n        .map(entry => (entry as NavigationLink).href)\n    )\n\n    const entries = files\n      .filter(file => file.isFile())\n      .filter(file => !['index.md', 'index.mdx'].includes(file.name))\n      .filter(file => {\n        const ext = path.extname(file.name).toLowerCase()\n        return ext === '.md' || ext === '.mdx'\n      })\n      .map(file => {\n        const fileName = path.parse(file.name).name\n        const pathWithoutExt = path.join(\n          group.autopopulateFromDir || '',\n          fileName\n        )\n        const href = `${pathWithoutExt}`\n\n        const label = toCamelCase(fileName)\n\n        return {\n          type: 'link',\n          href,\n          label,\n        } as NavigationLink\n      })\n      .filter(entry => !existingHrefs.has(entry.href))\n\n    return [...(group.entries || []), ...entries]\n  } catch (error) {\n    console.error(`Error reading directory ${dirPath}:`, error)\n    return group?.entries || []\n  }\n}\n\nfunction processAutopopulateGroups(sidebarConfig: NavigationGroup[]) {\n  sidebarConfig.forEach(group => {\n    if (group.autopopulateFromDir) {\n      group.entries = populateEntriesFromDir(group)\n      group.autopopulateFromDir = undefined\n    }\n  })\n}\n\nexport function getPagination(\n  sidebarConfig: NavigationGroup[],\n  currentPath: string\n): {\n  prev?: { href: string; label: string }\n  next?: { href: string; label: string }\n} {\n  processAutopopulateGroups(sidebarConfig)\n\n  currentPath = currentPath.replace(/\\/$/, '')\n  const result: {\n    prev?: { href: string; label: string }\n    next?: { href: string; label: string }\n  } = {}\n\n  const link = getNavLinkByHref(sidebarConfig, currentPath)\n  if (!link || link.disablePagination) return result\n\n  const group = getNavGroupByHref(sidebarConfig, currentPath)\n\n  if (!group) return result\n\n  if (group.category === NavigationCategory.MAIN) {\n    const links = getNavLinksByCategory(\n      sidebarConfig,\n      (link as MainNavigationLink).relatedGroupCategory\n    )\n    if (links && links.length > 1) {\n      result.next = { href: links[1].href, label: links[1].label }\n    }\n  } else {\n    const links = getNavLinksByCategory(sidebarConfig, group.category)\n\n    const index = links.findIndex(link => comparePaths(link.href, currentPath))\n\n    if (index === 0) {\n      if (group.homePageHref) {\n        const homePageLink = getNavLinkByHref(sidebarConfig, group.homePageHref)\n        if (homePageLink) {\n          result.prev = { href: homePageLink.href, label: homePageLink.label }\n        }\n      }\n    } else {\n      result.prev = {\n        href: links[index - 1].href,\n        label: links[index - 1].label,\n      }\n    }\n\n    if (index != links.length - 1) {\n      result.next = {\n        href: links[index + 1].href,\n        label: links[index + 1].label,\n      }\n    }\n  }\n  return result\n}\n\nexport function getSidebar(\n  sidebarConfig: NavigationGroup[],\n  currentPath: string\n): NavigationGroup[] {\n  processAutopopulateGroups(sidebarConfig)\n\n  currentPath = currentPath.replace(/\\/$/, '')\n  const mainGroup = getMainNavGroup(sidebarConfig)\n  const currentGroup = getNavGroupByHref(sidebarConfig, currentPath)\n\n  // If no current group found, return GENERAL category groups as default\n  if (!currentGroup) {\n    const generalGroups = getNavGroupsByCategory(\n      sidebarConfig,\n      NavigationCategory.GENERAL\n    )\n    return generalGroups.map(group => ({\n      ...group,\n      entries: group.entries?.filter(\n        entry =>\n          entry.type !== 'link' || !(entry as NavigationLink).hideInSidebar\n      ),\n    }))\n  }\n\n  let relatedGroups: NavigationGroup[] = []\n\n  if (currentGroup.category === NavigationCategory.MAIN && mainGroup) {\n    const currentLink = getNavLinkByHref(\n      sidebarConfig,\n      currentPath,\n      currentGroup\n    ) as MainNavigationLink\n\n    if (!currentLink) {\n      const generalGroups = getNavGroupsByCategory(\n        sidebarConfig,\n        NavigationCategory.GENERAL\n      )\n      return generalGroups\n    }\n\n    relatedGroups = getNavGroupsByCategory(\n      sidebarConfig,\n      currentLink.relatedGroupCategory\n    )\n  } else {\n    relatedGroups = getNavGroupsByCategory(sidebarConfig, currentGroup.category)\n  }\n\n  // Filter out links with hideInSidebar from related groups\n  const filteredRelatedGroups = relatedGroups.map(group => ({\n    ...group,\n    entries: group.entries?.filter(\n      entry => entry.type !== 'link' || !(entry as NavigationLink).hideInSidebar\n    ),\n  }))\n\n  return filteredRelatedGroups\n}\n\nexport function getExploreMoreData(\n  sidebarConfig: NavigationGroup[],\n  currentPath: string\n) {\n  processAutopopulateGroups(sidebarConfig)\n\n  currentPath = currentPath.replace(/\\/$/, '')\n\n  // Check if this is the main docs index page\n  const isMainIndex =\n    currentPath.endsWith('/docs') ||\n    currentPath.match(/\\/docs\\/[a-z]{2}$/) !== null\n\n  let relatedGroups: NavigationGroup[]\n\n  if (isMainIndex) {\n    // For main index, show GENERAL category groups\n    relatedGroups = getNavGroupsByCategory(\n      sidebarConfig,\n      NavigationCategory.GENERAL\n    )\n  } else {\n    const link = getNavLinkByHref(\n      sidebarConfig,\n      currentPath\n    ) as MainNavigationLink\n    if (!link || !link.relatedGroupCategory) {\n      return []\n    }\n    relatedGroups = getNavGroupsByCategory(\n      sidebarConfig,\n      link.relatedGroupCategory\n    )\n  }\n\n  return relatedGroups.map(group => {\n    const items = (group.entries || [])\n      .filter(entry => !entry.hideInSidebar)\n      .map(navLink => {\n        return {\n          title: navLink.label,\n          subtitle: navLink.description || '',\n          href: navLink.href,\n        }\n      })\n\n    return {\n      title: group.label || '',\n      items,\n    }\n  })\n}\n\nexport function comparePaths(path1: string, path2: string): boolean {\n  return normalizePath(path1) === normalizePath(path2)\n}\n\nexport interface HeaderActiveState {\n  isTypescriptSdkActive: boolean\n  isPythonSdkActive: boolean\n  isRubySdkActive: boolean\n  isGoSdkActive: boolean\n  isApiActive: boolean\n  isCliActive: boolean\n  isReferencesActive: boolean\n  isGuidesActive: boolean\n}\n\nexport function getHeaderActiveState(\n  baseUrl: string,\n  currentPath: string\n): HeaderActiveState {\n  const referencePaths = {\n    typescriptSdk: `${baseUrl}/en/typescript-sdk`,\n    pythonSdk: `${baseUrl}/en/python-sdk`,\n    rubySdk: `${baseUrl}/en/ruby-sdk`,\n    goSdk: `${baseUrl}/en/go-sdk`,\n    api: `${baseUrl}/en/tools/api`,\n    cli: `${baseUrl}/en/tools/cli`,\n  }\n\n  const isTypescriptSdkActive = isActiveOrParentPath(\n    referencePaths.typescriptSdk,\n    currentPath\n  )\n  const isPythonSdkActive = isActiveOrParentPath(\n    referencePaths.pythonSdk,\n    currentPath\n  )\n  const isRubySdkActive = isActiveOrParentPath(\n    referencePaths.rubySdk,\n    currentPath\n  )\n  const isGoSdkActive = isActiveOrParentPath(referencePaths.goSdk, currentPath)\n  const isApiActive = isActiveOrParentPath(referencePaths.api, currentPath)\n  const isCliActive = isActiveOrParentPath(referencePaths.cli, currentPath)\n\n  return {\n    isTypescriptSdkActive,\n    isPythonSdkActive,\n    isRubySdkActive,\n    isGoSdkActive,\n    isApiActive,\n    isCliActive,\n    isReferencesActive:\n      isTypescriptSdkActive ||\n      isPythonSdkActive ||\n      isRubySdkActive ||\n      isGoSdkActive ||\n      isApiActive ||\n      isCliActive,\n    isGuidesActive: isActiveOrParentPath(`${baseUrl}/en/guides`, currentPath),\n  }\n}\n\nexport function isActiveOrParentPath(\n  entryPath: string,\n  currentPath: string\n): boolean {\n  const normalizedEntry = normalizePath(entryPath)\n  const normalizedCurrent = normalizePath(currentPath)\n\n  if (normalizedEntry === normalizedCurrent) {\n    return true\n  }\n\n  const segments = normalizedEntry.split('/').filter(Boolean)\n  if (segments.length < 3) {\n    return false\n  }\n\n  return normalizedCurrent.startsWith(normalizedEntry + '/')\n}\n"
  },
  {
    "path": "apps/docs/src/utils/redirects.ts",
    "content": "import { redirects as _redirects } from '../../server/util/redirects.mjs'\n\nexport const redirects: Record<string, string> = _redirects\n"
  },
  {
    "path": "apps/docs/tailwind.config.js",
    "content": "/** @type {import('tailwindcss').Config} */\nexport default {\n  content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],\n  theme: {\n    extend: {},\n  },\n  plugins: [],\n}\n"
  },
  {
    "path": "apps/docs/tools/update-api-reference.js",
    "content": "import * as _fs from 'fs'\nimport { parseArgs } from 'util'\n\nconst __dirname = import.meta.dirname\n\nconst fs = _fs.promises\n\n// content to appear above the commands outline\nconst prepend = `---\ntitle: API\ndescription: A reference of supported operations using the Daytona API.\n---\n\nimport Label from '@components/Label.astro'\n`\n\n// content to appear below the commands outline\nconst append = ``\n\nfunction escape(str) {\n  return str.replace(/\\{/g, '\\\\{').replace(/\\}/g, '\\\\}')\n}\n\nfunction swaggerToMarkdown(swaggerJSON) {\n  let output = ''\n\n  for (const path of Object.keys(swaggerJSON.paths)) {\n    const methods = swaggerJSON.paths[path]\n\n    for (const method of Object.keys(methods)) {\n      const methodDetails = methods[method]\n      let { description, responses, parameters } = methodDetails\n\n      responses = responses ? responses : {}\n      parameters = parameters ? parameters : {}\n\n      output += `## ${method.toUpperCase()} ${escape(path)}\\n`\n      if (description) {\n        output += `${description}\\n`\n      }\n      output += '\\n'\n\n      if (Object.keys(parameters).length > 0) {\n        output += '### Parameters\\n'\n\n        output += `| Name | Location | Required | Type | Description |\\n`\n        output += `| :--- | :------- | :------- | :--- | :---------- |\\n`\n\n        for (const param of Object.keys(parameters)) {\n          const responseDetails = parameters[param]\n          const {\n            name,\n            in: location,\n            required,\n            type,\n            description: paramDescription,\n          } = responseDetails\n\n          output += `| **\\`${name}\\`** | ${location} | ${required} | ${type} | ${paramDescription} |\\n`\n        }\n\n        output += '\\n'\n      }\n\n      if (Object.keys(responses).length > 0) {\n        output += '### Responses\\n'\n\n        output += `| Status Code | Description |\\n`\n        output += `| :-------- | :---------- |\\n`\n\n        for (const response of Object.keys(responses)) {\n          const responseDetails = responses[response]\n          const { description: responseDescription } = responseDetails\n\n          output += `| **\\`${response}\\`** | ${responseDescription} |\\n`\n        }\n\n        output += '\\n'\n      }\n    }\n\n    output += '\\n'\n  }\n\n  return output\n}\n\nasync function process(args) {\n  const { output, ref } = args.values\n  const swaggerJSON = JSON.parse(\n    await fs.readFile(\n      `${__dirname}/../../../dist/apps/api/openapi.json`,\n      'utf8'\n    )\n  )\n\n  const markdown = swaggerToMarkdown(swaggerJSON)\n\n  console.log(`writing to '${output}'...`)\n  await fs.writeFile(output, `${prepend}\\n${markdown}\\n${append}`)\n  console.log('done')\n}\n\nconst commandOpts = {\n  ref: {\n    type: 'string',\n    default: `v0.14.0`,\n  },\n  output: {\n    type: 'string',\n    short: 'o',\n    default: `${__dirname}/../src/content/docs/en/tools/api.mdx`,\n  },\n}\n\nconst args = parseArgs({ options: commandOpts })\nprocess(args)\n"
  },
  {
    "path": "apps/docs/tools/update-cli-reference.js",
    "content": "import * as _fs from 'fs'\nimport { join } from 'path'\nimport { parseArgs } from 'util'\nimport * as yaml from 'yaml'\n\nconst fs = _fs.promises\n\nconst __dirname = import.meta.dirname\n\n// Default local path relative to this script (apps/docs/tools -> apps/cli/hack/docs)\nconst DEFAULT_LOCAL_PATH = join(__dirname, '../../cli/hack/docs')\n\n// content to appear above the commands outline\nconst prepend = `---\ntitle: CLI\ndescription: A reference of supported operations using the Daytona CLI.\nsidebar:\n  label: Daytona CLI Reference\n---\nimport Aside from \"@components/Aside.astro\";\nimport Label from \"@components/Label.astro\";\n\nThe \\`daytona\\` command-line tool provides access to Daytona's core features including managing Snapshots and the lifecycle of Daytona Sandboxes. View the installation instructions by clicking [here](/docs/getting-started#cli).\n\nThis reference lists all commands supported by the \\`daytona\\` command-line tool complete with a description of their behaviour, and any supported flags.\nYou can access this documentation on a per-command basis by appending the \\`--help\\`/\\`-h\\` flag when invoking \\`daytona\\`.\n`\n\n// content to appear below the commands outline\nconst append = ``\n\nconst notes = {\n  'daytona autocomplete': `\\n<Aside type=\"note\">\nIf using bash shell environment, make sure you have bash-completion installed in order to get full autocompletion functionality.\nLinux Installation: \\`\\`\\`sudo apt-get install bash-completion\\`\\`\\`\nmacOS Installation: \\`\\`\\`brew install bash-completion\\`\\`\\`\n</Aside>`,\n}\n\nasync function fetchRawDocs(ref) {\n  const url =\n    'https://api.github.com/repos/daytonaio/daytona/contents/apps/cli/hack/docs'\n  const request = await fetch(`${url}?ref=${ref}`)\n  const response = await request.json()\n\n  const files = []\n\n  for (const file of response) {\n    const { download_url } = file\n\n    if (!download_url) continue\n\n    const contentsReq = await fetch(download_url)\n    let contents = await contentsReq.text()\n\n    contents = yaml.parse(contents)\n\n    files.push(contents)\n  }\n\n  return files\n}\n\nasync function readLocalDocs(localPath) {\n  const dirEntries = await fs.readdir(localPath)\n  const yamlFiles = dirEntries.filter(f => f.endsWith('.yaml'))\n\n  const files = []\n\n  for (const fileName of yamlFiles) {\n    const filePath = join(localPath, fileName)\n    const contents = await fs.readFile(filePath, 'utf-8')\n    files.push(yaml.parse(contents))\n  }\n\n  return files\n}\n\nfunction flagToRow(flag) {\n  let { name, shorthand, usage } = flag\n\n  name = `\\`--${name}\\``\n  shorthand = shorthand ? `\\`-${shorthand}\\`` : ''\n  usage = usage ? usage : ''\n  if (usage.endsWith('\\n')) {\n    usage = usage.slice(0, -1)\n  }\n\n  return `| ${name} | ${shorthand} | ${usage} |\\n`\n}\n\nfunction yamlToMarkdown(files) {\n  return files.map(rawDoc => {\n    let output = ''\n    output += `## ${rawDoc.name}\\n`\n    output += `${rawDoc.synopsis}\\n\\n`\n\n    if (!rawDoc.usage) {\n      rawDoc.usage = `${rawDoc.name} [flags]`\n    }\n\n    output += '```shell\\n'\n    output += `${rawDoc.usage}\\n`\n    output += '```\\n\\n'\n\n    output += '__Flags__\\n'\n    output += '| Long | Short | Description |\\n'\n    output += '| :--- | :---- | :---------- |\\n'\n\n    if (rawDoc.options) {\n      for (const flag of rawDoc.options) {\n        const row = flagToRow(flag)\n        output += row\n      }\n    }\n\n    if (rawDoc.inherited_options) {\n      for (const flag of rawDoc.inherited_options) {\n        const row = flagToRow(flag)\n        output += row\n      }\n    }\n\n    if (notes[rawDoc.name]) {\n      output += notes[rawDoc.name]\n    }\n\n    output += '\\n'\n\n    return output\n  })\n}\n\nasync function process(args) {\n  const { output, ref, local, path } = args.values\n\n  let files\n  if (local || path) {\n    const localPath = path || DEFAULT_LOCAL_PATH\n    console.log(`reading local docs from ${localPath}...`)\n    files = await readLocalDocs(localPath)\n  } else {\n    console.log(`fetching docs for ${ref} from GitHub...`)\n    files = await fetchRawDocs(ref)\n  }\n\n  const transformed = yamlToMarkdown(files)\n\n  const singleMarkdown = transformed.join('\\n')\n  console.log(`writing to '${output}'...`)\n  await fs.writeFile(output, `${prepend}\\n${singleMarkdown}\\n${append}`)\n  console.log('done')\n}\n\nconst commandOpts = {\n  ref: {\n    type: 'string',\n    default: 'main',\n  },\n  local: {\n    type: 'boolean',\n    short: 'l',\n    default: false,\n  },\n  path: {\n    type: 'string',\n    short: 'p',\n  },\n  output: {\n    type: 'string',\n    short: 'o',\n    default: `${__dirname}/../src/content/docs/en/tools/cli.mdx`,\n  },\n}\n\nconst args = parseArgs({ options: commandOpts })\nprocess(args)\n"
  },
  {
    "path": "apps/docs/tools/update-llms.js",
    "content": "import fs from 'fs'\nimport matter from 'gray-matter'\nimport path, { dirname } from 'path'\nimport { fileURLToPath } from 'url'\n\nimport { processMarkdownContent, rewriteLinksToMd } from '../src/utils/md.js'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nconst PUBLIC_WEB_URL = (\n  process.env.PUBLIC_WEB_URL || 'https://daytona.io'\n).replace(/\\/$/, '')\nconst DOCS_BASE_URL = `${PUBLIC_WEB_URL}/docs`\n\nconst BUILD_OUTPUT_DIR = path.join(\n  __dirname,\n  '../../../dist/apps/docs/client'\n)\nconst STATIC_LOCALE = 'en'\nconst STATIC_DOCS_OUTPUT_DIR = path.join(BUILD_OUTPUT_DIR, STATIC_LOCALE)\nconst STATIC_DOCS_OUTPUT_DIR_ROOT = BUILD_OUTPUT_DIR\n\nconst packageJson = JSON.parse(\n  fs.readFileSync(path.join(__dirname, '../../../package.json'), 'utf8')\n)\nconst version = packageJson.version\n\nconst getCurrentDate = () => {\n  const date = new Date()\n  return date.toISOString().split('T')[0] // YYYY-MM-DD format\n}\n\nconst getVersionHeader = () => {\n  return [\n    `# Daytona Documentation v${version}`,\n    `# Generated on: ${getCurrentDate()}`,\n    '',\n  ].join('\\n')\n}\n\n// Only include English docs\nconst DOCS_PATH = path.join(__dirname, '../src/content/docs/en')\nconst EXCLUDE_FILES = new Set(['404.md', 'api.mdx'])\n\nconst ensureLeadingSlash = value =>\n  value.startsWith('/') ? value : `/${value}`\n\nconst normalizeSlugPath = slug => {\n  if (!slug) return '/'\n\n  let value = ensureLeadingSlash(slug.replace(/\\\\/g, '/'))\n  value = value.replace(/\\/+/g, '/')\n\n  if (value.endsWith('/index')) {\n    value = value.slice(0, -'/index'.length) || '/'\n  }\n\n  if (value !== '/' && value.endsWith('/')) {\n    value = value.slice(0, -1)\n  }\n\n  return value || '/'\n}\n\nconst getOutputRelativeSlug = normalizedSlug =>\n  !normalizedSlug || normalizedSlug === '/'\n    ? 'docs'\n    : normalizedSlug.replace(/^\\//, '')\n\nconst getSlugFromFilePath = filePath =>\n  filePath\n    .replace(DOCS_PATH, '')\n    .replace(/\\\\/g, '/')\n    .replace(/\\.mdx?$/, '')\n\nconst extractSubHeadings = (content, slug) => {\n  const headingRegex = /^(#{2,3})\\s+(.*)/gm\n  const headings = []\n  let match\n\n  while ((match = headingRegex.exec(content)) !== null) {\n    const headingSlug = `${slug}#${match[2]\n      .toLowerCase()\n      .replace(/\\s+/g, '-')\n      .replace(/[^a-z0-9-]/g, '')}`\n    headings.push({ title: match[2].trim(), url: `/docs/en${headingSlug}` })\n  }\n\n  return headings\n}\n\nconst parseMarkdownFile = (filePath, fileContent) => {\n  const { content, data } = matter(fileContent)\n  const cleanContent = processMarkdownContent(content)\n  const rewrittenContent = rewriteLinksToMd(cleanContent, DOCS_BASE_URL)\n  const slug = getSlugFromFilePath(filePath)\n  const normalizedSlug = normalizeSlugPath(slug)\n  const title =\n    data.title || cleanContent.match(/^#\\s+(.*)/)?.[1]?.trim() || 'Untitled'\n\n  return {\n    entries: [\n      {\n        title,\n        url: normalizedSlug === '/' ? '/docs/en' : `/docs/en${normalizedSlug}`,\n      },\n      ...extractSubHeadings(cleanContent, normalizedSlug),\n    ],\n    doc: {\n      slug: normalizedSlug,\n      content: rewrittenContent,\n    },\n    cleanContent,\n  }\n}\n\nconst searchDocs = () => {\n  const results = []\n  const docs = []\n  const fullContentArray = []\n\n  const traverseDirectory = directory => {\n    fs.readdirSync(directory).forEach(file => {\n      const fullPath = path.join(directory, file)\n      const stat = fs.statSync(fullPath)\n\n      if (stat.isDirectory()) {\n        traverseDirectory(fullPath)\n      } else if (\n        stat.isFile() &&\n        (file.endsWith('.md') || file.endsWith('.mdx')) &&\n        !EXCLUDE_FILES.has(file)\n      ) {\n        const fileContent = fs.readFileSync(fullPath, 'utf8')\n        const { entries, doc, cleanContent } = parseMarkdownFile(\n          fullPath,\n          fileContent\n        )\n\n        fullContentArray.push(cleanContent)\n        results.push(...entries)\n        docs.push(doc)\n      }\n    })\n  }\n\n  traverseDirectory(DOCS_PATH)\n  return {\n    results,\n    docs,\n    fullContent: fullContentArray.join('\\n\\n'),\n  }\n}\n\nconst generateLlmsTxtFile = docsData => {\n  const llmsContent = [\n    getVersionHeader(),\n    '# Daytona',\n    '',\n    '> Secure and Elastic Infrastructure for Running Your Al-Generated Code.',\n    '',\n    '## Docs',\n    '',\n    ...docsData.map(doc => `- [${doc.title}](${PUBLIC_WEB_URL}${doc.url})`),\n  ]\n  const output = rewriteLinksToMd(llmsContent.join('\\n'), DOCS_BASE_URL)\n  if (!fs.existsSync(BUILD_OUTPUT_DIR)) {\n    fs.mkdirSync(BUILD_OUTPUT_DIR, { recursive: true })\n  }\n  fs.writeFileSync(\n    path.join(BUILD_OUTPUT_DIR, 'llms.txt'),\n    output,\n    'utf8'\n  )\n  console.log('llms.txt index updated')\n}\n\nconst generateLlmsFullTxtFile = fullContent => {\n  const content = [getVersionHeader(), fullContent].join('\\n\\n')\n  const output = rewriteLinksToMd(content, DOCS_BASE_URL)\n  if (!fs.existsSync(BUILD_OUTPUT_DIR)) {\n    fs.mkdirSync(BUILD_OUTPUT_DIR, { recursive: true })\n  }\n  fs.writeFileSync(\n    path.join(BUILD_OUTPUT_DIR, 'llms-full.txt'),\n    output,\n    'utf8'\n  )\n  console.log('llms-full.txt index updated')\n}\n\nconst generateStaticMarkdownFiles = docs => {\n  const writeMarkdownFile = (outputPath, content) => {\n    fs.mkdirSync(path.dirname(outputPath), { recursive: true })\n    fs.writeFileSync(outputPath, content, 'utf8')\n    console.log(\n      `Static markdown page generated for \"${path.relative(\n        STATIC_DOCS_OUTPUT_DIR_ROOT,\n        outputPath\n      )}\"`\n    )\n  }\n\n  docs.forEach(({ slug, content }) => {\n    const relativeSlug = getOutputRelativeSlug(slug)\n    const localeOutputPath = path.join(\n      STATIC_DOCS_OUTPUT_DIR,\n      `${relativeSlug}.md`\n    )\n    const rootOutputPath = path.join(\n      STATIC_DOCS_OUTPUT_DIR_ROOT,\n      `${relativeSlug}.md`\n    )\n\n    writeMarkdownFile(localeOutputPath, content)\n\n    if (rootOutputPath !== localeOutputPath) {\n      writeMarkdownFile(rootOutputPath, content)\n    }\n\n    if (slug === '/' || slug === '') {\n      const rootLocaleAlias = path.join(\n        STATIC_DOCS_OUTPUT_DIR_ROOT,\n        `${STATIC_LOCALE}.md`\n      )\n      writeMarkdownFile(rootLocaleAlias, content)\n    }\n  })\n}\n\nconst main = () => {\n  const { results, fullContent, docs } = searchDocs()\n  generateLlmsTxtFile(results)\n  generateLlmsFullTxtFile(fullContent)\n  generateStaticMarkdownFiles(docs)\n}\n\nmain()\n"
  },
  {
    "path": "apps/docs/tools/update-search.js",
    "content": "import fs from 'fs'\nimport matter from 'gray-matter'\nimport path from 'path'\nimport { dirname } from 'path'\nimport { fileURLToPath } from 'url'\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\nconst DOCS_PATH = path.join(__dirname, '../src/content/docs/en')\nconst SDK_FOLDER_NAMES = []\nconst SDK_FOLDERS = fs\n  .readdirSync(DOCS_PATH)\n  .filter(directoryName => {\n    const fullPath = path.join(DOCS_PATH, directoryName)\n    return fs.statSync(fullPath).isDirectory() && directoryName.endsWith('-sdk')\n  })\n  .map(directoryName => {\n    SDK_FOLDER_NAMES.push(directoryName)\n    return path.join(DOCS_PATH, directoryName)\n  })\nconst CLI_FILE_PATH = path.join(DOCS_PATH, 'tools/cli.mdx')\nconst EXCLUDE_FILES = ['404.md', 'index.mdx', 'api.mdx']\n\nfunction findWorkspaceRoot(startPath) {\n  let current = path.resolve(startPath)\n  const root = path.resolve(current, '/')\n\n  while (current !== root) {\n    const packageJson = path.join(current, 'package.json')\n    const appsDocs = path.join(current, 'apps/docs')\n\n    if (fs.existsSync(packageJson) && fs.existsSync(appsDocs)) {\n      return current\n    }\n\n    const parent = path.resolve(current, '..')\n    if (parent === current) break\n    current = parent\n  }\n\n  return process.cwd()\n}\n\nconst WORKSPACE_ROOT = findWorkspaceRoot(__dirname)\nconst MAIN_API_PATH = path.join(\n  WORKSPACE_ROOT,\n  'dist/apps/api/openapi.3.1.0.json'\n)\nconst TOOLBOX_API_PATH = path.join(\n  WORKSPACE_ROOT,\n  'apps/daemon/pkg/toolbox/docs/swagger.json'\n)\n\nfunction processContent(content) {\n  return content\n    .split('\\n')\n    .filter(\n      line =>\n        !line.trim().startsWith('import') && !line.trim().startsWith('export')\n    )\n    .join('\\n')\n    .trim()\n}\n\nfunction extractSentences(text) {\n  // Return text\n  const match = text.match(/[^.!?]*[.!?]/g)\n  const sentences = match ? match.map(m => m.trim()) : text.trim().split('\\n')\n  return sentences.length > 0\n    ? sentences.filter(s => s.endsWith('.')).join(' ')\n    : ''\n}\n\nfunction extractHyperlinks(text) {\n  return text.replace(/\\[([^\\]]+)\\]\\(([^\\)]+)\\)/g, '$1')\n}\n\nfunction isSentence(sentence) {\n  return /^[A-Z0-9\\[]/.test(sentence.trim())\n}\n\nfunction isSentenceWithoutPunctuation(sentence) {\n  const trimmed = sentence.trim()\n  return (\n    /^[A-Z0-9\\[]/.test(trimmed) &&\n    !trimmed.includes('\\n') &&\n    !/[.!?]$/.test(trimmed)\n  )\n}\n\nfunction extractRealSentence(text) {\n  const sentences = text\n    .split(/\\n\\n+/)\n    .map(s => s.trim())\n    .filter(s => s.length > 0)\n  for (const sentence of sentences) {\n    if (isSentence(sentence)) {\n      const extracted = extractSentences(sentence)\n      if (extracted) {\n        return extracted\n      }\n      if (isSentenceWithoutPunctuation(sentence)) {\n        return sentence\n      }\n    }\n  }\n  return ''\n}\n\nfunction extractCodeSnippets(content) {\n  const codeRegexes = [\n    /```(?:python|py)\\n([\\s\\S]*?)```/g,\n    /```(?:typescript|ts|tsx)\\n([\\s\\S]*?)```/g,\n    /```(?:bash|shell|sh)\\n([\\s\\S]*?)```/g,\n  ]\n  const codeSnippets = []\n\n  codeRegexes.forEach(regex => {\n    let match\n    while ((match = regex.exec(content)) !== null) {\n      const code = match[1].trim()\n      if (code) codeSnippets.push(code)\n    }\n  })\n\n  return codeSnippets.join('\\n\\n')\n}\n\nfunction extractHeadings(content, tag, slug) {\n  // First, temporarily replace code blocks with placeholders to avoid matching # inside code\n  const codeBlockRegex = /```[\\s\\S]*?```/g\n  const codeBlocks = []\n  let codeBlockIndex = 0\n\n  const contentWithoutCode = content.replace(codeBlockRegex, match => {\n    const placeholder = `___CODE_BLOCK_${codeBlockIndex++}___`\n    codeBlocks.push(match)\n    return placeholder\n  })\n\n  // Extract headings from content without code blocks\n  const headingRegex = /^(#{1,6})\\s+(.+)$/gm\n  const headings = []\n  const headingMatches = []\n  let match\n\n  // Collect all heading positions from content WITHOUT code blocks -> we use them later to restore code blocks\n  while ((match = headingRegex.exec(contentWithoutCode)) !== null) {\n    headingMatches.push({\n      title: match[2].trim().replace(/\\\\_/g, '_'),\n      index: match.index,\n      length: match[0].length,\n    })\n  }\n\n  // Process each heading content\n  for (let i = 0; i < headingMatches.length; i++) {\n    const current = headingMatches[i]\n    const next = headingMatches[i + 1]\n\n    // Content below current heading and the next heading (or end)\n    const startIndex = current.index + current.length\n    const endIndex = next ? next.index : contentWithoutCode.length\n    let currentTextBelow = contentWithoutCode.substring(startIndex, endIndex)\n\n    // Restore code blocks\n    currentTextBelow = currentTextBelow.replace(\n      /___CODE_BLOCK_(\\d+)___/g,\n      (match, index) => {\n        return codeBlocks[parseInt(index)]\n      }\n    )\n\n    currentTextBelow = currentTextBelow.trim()\n\n    const heading = current.title\n    const description = extractHyperlinks(extractRealSentence(currentTextBelow))\n    const codeSnippets = extractCodeSnippets(currentTextBelow)\n    const headingSlug = `${slug}#${heading\n      .toLowerCase()\n      .replace(/\\s+/g, '-')\n      .replace(/[^a-z0-9-_]/g, '')}`\n\n    headings.push({\n      title: heading,\n      description,\n      codeSnippets,\n      tag,\n      url: `/docs${headingSlug}`,\n      slug: headingSlug,\n    })\n  }\n\n  return headings\n}\n\nfunction parseMarkdownFile(filePath, tag) {\n  const fileContent = fs.readFileSync(filePath, 'utf8')\n  const { content, data } = matter(fileContent)\n\n  const cleanContent = processContent(content)\n\n  const title = data.title || cleanContent.match(/^#\\s+(.*)/)?.[1] || 'Untitled'\n  const description =\n    data.description || extractHyperlinks(extractRealSentence(cleanContent))\n  const slug = filePath\n    .replace(DOCS_PATH, '')\n    .replace(/\\\\/g, '/')\n    .replace(/\\.mdx?$/, '')\n  const headings = extractHeadings(cleanContent, tag, slug)\n\n  const mainData = {\n    title,\n    description,\n    tag,\n    url: `/docs${slug}`,\n    slug,\n  }\n\n  return [mainData, ...headings]\n}\n\nfunction parseOpenAPISpec(specPath, apiName, baseUrl) {\n  const records = []\n\n  if (!fs.existsSync(specPath)) {\n    console.warn(`OpenAPI spec not found: ${specPath}`)\n    return records\n  }\n\n  try {\n    const specContent = fs.readFileSync(specPath, 'utf8')\n    const spec = JSON.parse(specContent)\n\n    // Handle both OpenAPI 3.x and Swagger 2.0\n    const isSwagger2 = spec.swagger === '2.0'\n    const paths = spec.paths || {}\n    const urlPrefix = baseUrl || '/docs/tools/api'\n\n    Object.entries(paths).forEach(([path, pathItem]) => {\n      if (!pathItem) return\n\n      const operations = [\n        'get',\n        'post',\n        'put',\n        'delete',\n        'patch',\n        'head',\n        'options',\n      ]\n\n      operations.forEach(method => {\n        const operation = pathItem[method]\n        if (!operation) return\n\n        const operationId = operation.operationId || `${method}${path}`\n        const summary = operation.summary || ''\n        const description = operation.description || ''\n        const tags = Array.isArray(operation.tags) ? operation.tags : []\n\n        // Extract parameter descriptions\n        const parameters = (operation.parameters || [])\n          .map(param => {\n            const paramDesc = param.description || ''\n            const paramName = param.name || ''\n            const paramIn = param.in || ''\n            return `${paramIn} ${paramName}: ${paramDesc}`\n          })\n          .filter(Boolean)\n          .join('; ')\n\n        // Extract response descriptions\n        const responseDescriptions = Object.entries(operation.responses || {})\n          .map(([code, response]) => {\n            const respDesc =\n              response?.description ||\n              (typeof response === 'string' ? response : '')\n            return respDesc ? `${code}: ${respDesc}` : null\n          })\n          .filter(Boolean)\n          .join('; ')\n\n        // Build searchable content\n        const searchableContent = [\n          summary,\n          description,\n          ...tags,\n          path,\n          method.toUpperCase(),\n          operationId,\n          parameters,\n          responseDescriptions,\n        ]\n          .filter(Boolean)\n          .join(' ')\n\n        // Create title (e.g., \"GET /api/sandboxes - Create sandbox\")\n        const title = `${method.toUpperCase()} ${path}${summary ? ` - ${summary}` : ''}`\n\n        // Build description from available fields\n        const recordDescription =\n          description ||\n          summary ||\n          `${method.toUpperCase()} endpoint for ${path}`\n\n        // Create slug for linking\n        const slug = `${path}${operationId ? `#${operationId}` : ''}`\n\n        // Use first tag for URL, or fallback to path-based tag\n        const primaryTag =\n          tags.length > 0\n            ? tags[0]\n            : path.split('/').filter(Boolean)[0] || 'default'\n\n        // For toolbox API, use 'daytona-toolbox' in the URL hash\n        const hashApiName = apiName === 'toolbox' ? 'daytona-toolbox' : apiName\n\n        // Format URL to match the hash format: #apiName/tag/tagName/METHOD/path\n        const scalarHash = `${hashApiName}/tag/${primaryTag}/${method.toUpperCase()}${path}`\n\n        records.push({\n          title,\n          description: recordDescription,\n          tag: 'API',\n          url: `${urlPrefix}#${scalarHash}`,\n          slug: `api-${apiName}-${slug.replace(/\\//g, '-').replace(/[^a-z0-9-]/gi, '')}`,\n          apiName,\n          method: method.toUpperCase(),\n          path,\n          operationId,\n          tags: tags.join(', '),\n          searchableContent,\n        })\n      })\n    })\n  } catch (error) {\n    console.error(`Error parsing OpenAPI spec ${specPath}:`, error.message)\n  }\n\n  return records\n}\n\nfunction searchDocs() {\n  const docsRecords = []\n  const cliRecords = []\n  const sdkRecords = []\n  const apiRecords = []\n  let objectID = 1\n\n  function traverseDirectory(directory, tag, recordsData) {\n    const files = fs.readdirSync(directory)\n\n    files.forEach(file => {\n      const fullPath = path.join(directory, file)\n      const stat = fs.statSync(fullPath)\n\n      if (stat.isDirectory()) {\n        const directoryName = path.basename(fullPath)\n        switch (tag) {\n          case 'Documentation':\n            if (SDK_FOLDER_NAMES.includes(directoryName)) return\n            break\n          case 'SDK':\n            // For SDK we traverse all subfolders inside given initial SDK directory\n            break\n        }\n        // Traverse directory if we passed the checks\n        traverseDirectory(fullPath, tag, recordsData)\n      } else if (\n        stat.isFile() &&\n        (file.endsWith('.md') || file.endsWith('.mdx')) &&\n        ![...EXCLUDE_FILES, path.basename(CLI_FILE_PATH)].includes(file) //CLI file is handled separately -> exclude it from directory traversals\n      ) {\n        parseMarkdownFile(fullPath, tag).forEach(data =>\n          recordsData.push({\n            ...data,\n            objectID: objectID++,\n          })\n        )\n      }\n    })\n  }\n\n  traverseDirectory(DOCS_PATH, 'Documentation', docsRecords)\n\n  SDK_FOLDERS.forEach(sdkFolderPath =>\n    traverseDirectory(sdkFolderPath, 'SDK', sdkRecords)\n  )\n\n  parseMarkdownFile(CLI_FILE_PATH, 'CLI').forEach(data =>\n    cliRecords.push({\n      ...data,\n      objectID: objectID++,\n    })\n  )\n\n  const mainApiRecords = parseOpenAPISpec(\n    MAIN_API_PATH,\n    'daytona',\n    '/docs/tools/api'\n  )\n  const toolboxApiRecords = parseOpenAPISpec(\n    TOOLBOX_API_PATH,\n    'toolbox',\n    '/docs/tools/api'\n  )\n\n  const allApiRecords = mainApiRecords.concat(toolboxApiRecords)\n  allApiRecords.forEach(data => {\n    apiRecords.push({\n      ...data,\n      objectID: objectID++,\n    })\n  })\n\n  return { docsRecords, cliRecords, sdkRecords, apiRecords }\n}\n\nfunction main() {\n  const { docsRecords, cliRecords, sdkRecords, apiRecords } = searchDocs()\n  const fileRecords = [\n    { fileName: 'docs', records: docsRecords },\n    { fileName: 'cli', records: cliRecords },\n    { fileName: 'sdk', records: sdkRecords },\n    { fileName: 'api', records: apiRecords },\n  ]\n\n  const outputDir = path.join(__dirname, '../../../dist/apps/docs/client')\n  if (!fs.existsSync(outputDir)) {\n    fs.mkdirSync(outputDir, { recursive: true })\n  }\n\n  fileRecords.forEach(({ fileName, records }) =>\n    fs.writeFileSync(\n      path.join(outputDir, `${fileName}.json`),\n      JSON.stringify(records, null, 2),\n      'utf8'\n    )\n  )\n  console.log('search index updated')\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n  main()\n}\n"
  },
  {
    "path": "apps/docs/tsconfig.json",
    "content": "{\n  \"extends\": \"astro/tsconfigs/strict\",\n  \"compilerOptions\": {\n    \"jsx\": \"react-jsx\",\n    \"jsxImportSource\": \"react\",\n    \"strictNullChecks\": true,\n    \"allowImportingTsExtensions\": true,\n    \"moduleResolution\": \"bundler\",\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"@assets/*\": [\"src/assets/*\"],\n      \"@styles/*\": [\"src/styles/*\"],\n      \"@components/*\": [\"src/components/*\"],\n      \"@helpers/*\": [\"src/helpers/*\"],\n      \"@utils/*\": [\"src/utils/*\"]\n    }\n  }\n}\n"
  },
  {
    "path": "apps/docs/vite-env.d.ts",
    "content": "/// <reference types=\"vite-plugin-svgr/client\" />\n"
  },
  {
    "path": "apps/docs/vite.config.js",
    "content": "import svgr from 'vite-plugin-svgr'\n\nexport default {\n  plugins: [svgr()],\n}\n"
  },
  {
    "path": "apps/otel-collector/Dockerfile",
    "content": "FROM node:22-alpine AS build\n\nENV CI=true\n\nRUN npm install -g corepack && corepack enable\n\nCOPY --from=golang:1.25.4-alpine /usr/local/go/ /usr/local/go/\n\nENV PATH=\"/usr/local/go/bin:${PATH}\"\n\nRUN apk add --no-cache git\n\nWORKDIR /daytona\n\n# Yarn caching layer\nCOPY package.json yarn.lock .yarnrc.yml ./\nRUN yarn install --immutable\n\n# Nx config\nCOPY nx.json ./\n\n# Go dependency layer (cached unless go.mod/go.sum change)\nCOPY go.work go.work.sum ./\nCOPY apps/otel-collector/exporter/go.mod apps/otel-collector/exporter/go.sum apps/otel-collector/exporter/\nCOPY libs/api-client-go/go.mod libs/api-client-go/go.sum libs/api-client-go/\nCOPY libs/common-go/go.mod libs/common-go/go.sum libs/common-go/\nRUN head -1 go.work > go.work.tmp && printf '\\nuse (\\n\\t./apps/otel-collector/exporter\\n\\t./libs/api-client-go\\n\\t./libs/common-go\\n)\\n' >> go.work.tmp && mv go.work.tmp go.work\n\nENV NX_DAEMON=false\nENV GONOSUMDB=github.com/daytonaio/daytona\n\nRUN go -C apps/otel-collector/exporter mod download && \\\n    go -C libs/api-client-go mod download && \\\n    go -C libs/common-go mod download\n\n# Go source\nCOPY apps/otel-collector/ apps/otel-collector/\nCOPY libs/api-client-go/ libs/api-client-go/\nCOPY libs/common-go/ libs/common-go/\nRUN mkdir -p dist/apps/otel-collector\n\nRUN yarn nx build otel-collector --configuration=production --nxBail=true\n\nFROM alpine:3.18 AS otel-collector\n\nRUN apk add --no-cache curl\n\nWORKDIR /usr/local/bin\n\nCOPY --from=build /daytona/dist/apps/otel-collector/daytona-otel-collector daytona-otel-collector\nCOPY --from=build /daytona/apps/otel-collector/config.yaml /otelcol/collector-config.yaml\n\nRUN chmod +x daytona-otel-collector\n\nHEALTHCHECK CMD [ \"curl\", \"-f\", \"http://localhost:13133/health/status\" ]\n\nEXPOSE 4317\nEXPOSE 4318\nEXPOSE 13133\nEXPOSE 8888\n\nENTRYPOINT [\"daytona-otel-collector\"]\n\nCMD [\"--config\", \"/otelcol/collector-config.yaml\"]\n"
  },
  {
    "path": "apps/otel-collector/builder-config.dev.yaml",
    "content": "dist:\n  name: daytona-otel-collector\n  description: Daytona OpenTelemetry Collector\n  output_path: dist/apps/otel-collector\n\nexporters:\n  - gomod: github.com/daytonaio/otel-collector/exporter v0.0.1\n    name: daytonaexporter\n    path: apps/otel-collector/exporter\n\nreceivers:\n  - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.144.0\n\nprocessors:\n  - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.144.0\n  - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.144.0\n\nextensions:\n  - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.144.0\n  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckv2extension v0.144.0\n\nreplaces:\n  - github.com/daytonaio/daytona/libs/api-client-go => ../../../libs/api-client-go\n  - github.com/daytonaio/common-go => ../../../libs/common-go\n"
  },
  {
    "path": "apps/otel-collector/builder-config.yaml",
    "content": "dist:\n  name: daytona-otel-collector\n  description: Daytona OpenTelemetry Collector\n  output_path: dist/apps/otel-collector\n\nexporters:\n  - gomod: github.com/daytonaio/otel-collector/exporter v0.0.1\n    name: daytonaexporter\n    path: apps/otel-collector/exporter\n  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/clickhouseexporter v0.144.0\n    name: clickhouse\n\nreceivers:\n  - gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.144.0\n\nprocessors:\n  - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.144.0\n  - gomod: go.opentelemetry.io/collector/processor/memorylimiterprocessor v0.144.0\n\nextensions:\n  - gomod: go.opentelemetry.io/collector/extension/zpagesextension v0.144.0\n  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/healthcheckv2extension v0.144.0\n\nreplaces:\n  - github.com/daytonaio/daytona/libs/api-client-go => ../../../libs/api-client-go\n  - github.com/daytonaio/common-go => ../../../libs/common-go\n"
  },
  {
    "path": "apps/otel-collector/config.dev.yaml",
    "content": "# OpenTelemetry Collector configuration for Daytona\n\nreceivers:\n  otlp:\n    protocols:\n      http:\n        endpoint: 0.0.0.0:4318\n        include_metadata: true\n\nexporters:\n  daytona_exporter:\n    # Sandbox authentication header name\n    sandbox_auth_token_header: 'sandbox-auth-token'\n\n    # Cache TTL for endpoint configurations\n    cache_ttl: 5m\n\n    # Default timeout for OTLP export requests\n    default_timeout: 30s\n\n    # Retry settings for failed exports\n    retry_on_failure:\n      enabled: true\n      initial_interval: 5s\n      max_interval: 30s\n      max_elapsed_time: 5m\n\n    # Daytona API configuration\n    api_url: ${env:DAYTONA_API_URL:-http://localhost:3000/api}\n    api_key: ${env:DAYTONA_API_KEY:-otel_collector_api_key}\n\n    # Optional Redis configuration for caching\n    redis:\n      host: '${env:REDIS_HOST:-redis}'\n      port: '${env:REDIS_PORT:-6379}'\n      password: '${env:REDIS_PASSWORD:-}'\n\nextensions:\n  healthcheckv2:\n    use_v2: true\n    component_health:\n      include_permanent_errors: false\n      include_recoverable_errors: true\n      recovery_duration: 5m\n    http:\n      endpoint: '0.0.0.0:13133'\n      status:\n        enabled: true\n        path: '/health/status'\n      config:\n        enabled: true\n        path: '/health/config'\n    grpc:\n      endpoint: '0.0.0.0:13132'\n      transport: 'tcp'\n\nservice:\n  extensions: [healthcheckv2]\n  pipelines:\n    traces:\n      receivers: [otlp]\n      exporters: [daytona_exporter]\n    metrics:\n      receivers: [otlp]\n      exporters: [daytona_exporter]\n    logs:\n      receivers: [otlp]\n      exporters: [daytona_exporter]\n"
  },
  {
    "path": "apps/otel-collector/config.yaml",
    "content": "# OpenTelemetry Collector configuration for Daytona\n\nreceivers:\n  otlp:\n    protocols:\n      http:\n        endpoint: 0.0.0.0:4318\n        include_metadata: true\n\nexporters:\n  daytona_exporter:\n    # Sandbox authentication header name\n    sandbox_auth_token_header: 'sandbox-auth-token'\n\n    # Cache TTL for endpoint configurations\n    cache_ttl: 5m\n\n    # Default timeout for OTLP export requests\n    default_timeout: 30s\n\n    sending_queue:\n      queue_size: ${env:DAYTONA_EXPORTER_SENDING_QUEUE_SIZE:-1000}\n\n    # Retry settings for failed exports\n    retry_on_failure:\n      enabled: true\n      initial_interval: 5s\n      max_interval: 30s\n      max_elapsed_time: 5m\n\n    # Daytona API configuration\n    api_url: ${env:DAYTONA_API_URL:-http://localhost:3000/api}\n    api_key: ${env:DAYTONA_API_KEY:-otel_collector_api_key}\n\n    # Optional Redis configuration for caching\n    redis:\n      host: '${env:REDIS_HOST:-redis}'\n      port: '${env:REDIS_PORT:-6379}'\n      password: '${env:REDIS_PASSWORD:-}'\n\n  clickhouse:\n    endpoint: ${env:CLICKHOUSE_ENDPOINT}\n    database: otel\n    ttl: ${env:CLICKHOUSE_TTL:-72h}\n    username: default\n    password: ${env:CLICKHOUSE_PASSWORD}\n\n    sending_queue:\n      queue_size: ${env:CLICKHOUSE_EXPORTER_SENDING_QUEUE_SIZE:-1000}\n\n    retry_on_failure:\n      enabled: true\n      initial_interval: 5s\n      max_interval: 30s\n      max_elapsed_time: 300s\n\nextensions:\n  healthcheckv2:\n    use_v2: true\n    component_health:\n      include_permanent_errors: false\n      include_recoverable_errors: true\n      recovery_duration: 5m\n    http:\n      endpoint: '0.0.0.0:13133'\n      status:\n        enabled: true\n        path: '/health/status'\n      config:\n        enabled: true\n        path: '/health/config'\n    grpc:\n      endpoint: '0.0.0.0:13132'\n      transport: 'tcp'\n\nservice:\n  extensions: [healthcheckv2]\n  pipelines:\n    traces:\n      receivers: [otlp]\n      exporters: [daytona_exporter, clickhouse]\n    metrics:\n      receivers: [otlp]\n      exporters: [daytona_exporter, clickhouse]\n    logs:\n      receivers: [otlp]\n      exporters: [daytona_exporter, clickhouse]\n"
  },
  {
    "path": "apps/otel-collector/exporter/config.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage exporter\n\nimport (\n\t\"time\"\n\n\t\"github.com/daytonaio/common-go/pkg/cache\"\n\t\"go.opentelemetry.io/collector/config/configretry\"\n\t\"go.opentelemetry.io/collector/exporter/exporterhelper\"\n)\n\n// Config defines the configuration for the custom exporter.\ntype Config struct {\n\t// SandboxAuthTokenHeader is the HTTP header name that contains the sandbox auth token.\n\t// Default: \"sandbox-auth-token\"\n\tSandboxAuthTokenHeader string `mapstructure:\"sandbox_auth_token_header\"`\n\n\t// CacheTTL is the duration to cache endpoint configurations.\n\t// Default: 5m\n\tCacheTTL time.Duration `mapstructure:\"cache_ttl\"`\n\n\t// DefaultTimeout is the timeout for OTLP export requests.\n\t// Default: 30s\n\tDefaultTimeout time.Duration `mapstructure:\"default_timeout\"`\n\n\t// RetrySettings defines the retry behavior for failed exports.\n\tRetrySettings configretry.BackOffConfig `mapstructure:\"retry_on_failure\"`\n\n\t// SendingQueue configures the queueing and batching behavior for sending requests to Daytona API.\n\tSendingQueue exporterhelper.QueueBatchConfig `mapstructure:\"sending_queue\"`\n\n\t// Daytona API configuration.\n\tApiUrl string `mapstructure:\"api_url\"`\n\tApiKey string `mapstructure:\"api_key\"`\n\n\t// Optional Redis config for caching endpoint configurations.\n\tRedis *cache.RedisConfig `mapstructure:\"redis\"`\n}\n\n// Validate checks if the configuration is valid.\nfunc (cfg *Config) Validate() error {\n\t// Add validation logic here if needed\n\treturn nil\n}\n"
  },
  {
    "path": "apps/otel-collector/exporter/exporter.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage exporter\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"sync\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/otel-collector/exporter/internal/config\"\n\t\"go.opentelemetry.io/collector/client\"\n\t\"go.opentelemetry.io/collector/consumer/consumererror\"\n\t\"go.opentelemetry.io/collector/pdata/plog\"\n\t\"go.opentelemetry.io/collector/pdata/plog/plogotlp\"\n\t\"go.opentelemetry.io/collector/pdata/pmetric\"\n\t\"go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp\"\n\t\"go.opentelemetry.io/collector/pdata/ptrace\"\n\t\"go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp\"\n\t\"go.uber.org/zap\"\n\t\"google.golang.org/grpc/metadata\"\n)\n\ntype IExporter[T any] interface {\n\tpush(context.Context, T) error\n\texportViaHTTP(context.Context, T, *apiclient.OtelConfig) error\n\textractSandboxToken(context.Context) (string, error)\n\tgetBody(T) ([]byte, error)\n\tshutdown(context.Context) error\n}\n\ntype Exporter[T any] struct {\n\tconfig   *Config\n\tresolver *config.Resolver\n\tlogger   *zap.Logger\n\troute    string\n\n\thttpClients map[string]*http.Client //lint:ignore U1000 Used in private methods consumed by the built collector\n\tmu          sync.RWMutex            //lint:ignore U1000 Used in private methods consumed by the built collector\n\t_getBody    func(T) ([]byte, error)\n}\n\ntype exporterConfig struct {\n\tconfig   *Config\n\tlogger   *zap.Logger\n\tresolver *config.Resolver\n}\n\nfunc newMetricExporter(cfg exporterConfig) IExporter[pmetric.Metrics] {\n\treturn &Exporter[pmetric.Metrics]{\n\t\tconfig:   cfg.config,\n\t\tresolver: cfg.resolver,\n\t\tlogger:   cfg.logger,\n\t\troute:    \"v1/metrics\",\n\t\t_getBody: func(md pmetric.Metrics) ([]byte, error) {\n\t\t\treq := pmetricotlp.NewExportRequestFromMetrics(md)\n\t\t\treturn req.MarshalProto()\n\t\t},\n\t}\n}\n\nfunc newLogsExporter(cfg exporterConfig) IExporter[plog.Logs] {\n\treturn &Exporter[plog.Logs]{\n\t\tconfig:   cfg.config,\n\t\tresolver: cfg.resolver,\n\t\tlogger:   cfg.logger,\n\t\troute:    \"v1/logs\",\n\t\t_getBody: func(ld plog.Logs) ([]byte, error) {\n\t\t\treq := plogotlp.NewExportRequestFromLogs(ld)\n\t\t\treturn req.MarshalProto()\n\t\t},\n\t}\n}\n\nfunc newTracesExporter(cfg exporterConfig) IExporter[ptrace.Traces] {\n\treturn &Exporter[ptrace.Traces]{\n\t\tconfig:   cfg.config,\n\t\tresolver: cfg.resolver,\n\t\tlogger:   cfg.logger,\n\t\troute:    \"v1/traces\",\n\t\t_getBody: func(td ptrace.Traces) ([]byte, error) {\n\t\t\treq := ptraceotlp.NewExportRequestFromTraces(td)\n\t\t\treturn req.MarshalProto()\n\t\t},\n\t}\n}\n\n//lint:ignore U1000 Used by the built collector\nfunc (e *Exporter[T]) push(ctx context.Context, data T) error {\n\t// Extract sandbox token from context metadata\n\tsandboxToken, err := e.extractSandboxToken(ctx)\n\tif err != nil {\n\t\treturn consumererror.NewPermanent(fmt.Errorf(\"failed to extract sandbox token: %w\", err))\n\t}\n\n\t// Get endpoint configuration\n\tendpointConfig, err := e.resolver.GetOrganizationOtelConfig(ctx, sandboxToken)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get endpoint config for sandbox %w\", err)\n\t}\n\n\tif endpointConfig == nil {\n\t\te.logger.Debug(\"No endpoint configuration found for sandbox token, dropping data\")\n\t\treturn nil\n\t}\n\n\te.logger.Debug(\"Exporting data\",\n\t\tzap.String(\"protocol\", \"http\"),\n\t\tzap.String(\"endpoint\", endpointConfig.Endpoint),\n\t)\n\n\t// Route to appropriate protocol handler\n\treturn e.exportViaHTTP(ctx, data, endpointConfig)\n}\n\n//lint:ignore U1000 Used by the built collector\nfunc (e *Exporter[T]) getBody(data T) ([]byte, error) {\n\treturn e._getBody(data)\n}\n\n//lint:ignore U1000 Used by the built collector\nfunc (e *Exporter[T]) exportViaHTTP(ctx context.Context, data T, cfg *apiclient.OtelConfig) error {\n\thttpClient := e.getOrCreateHTTPClient(cfg)\n\n\t// Create OTLP request and marshal to protobuf\n\tbody, err := e.getBody(data)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshal logs: %w\", err)\n\t}\n\n\t// Create HTTP request\n\tendpoint := cfg.Endpoint\n\tif endpoint[len(endpoint)-1] != '/' {\n\t\tendpoint += \"/\"\n\t}\n\tendpoint += e.route\n\n\thttpReq, err := http.NewRequestWithContext(ctx, \"POST\", endpoint, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create HTTP request: %w\", err)\n\t}\n\n\thttpReq.Header.Set(\"Content-Type\", \"application/x-protobuf\")\n\tfor k, v := range cfg.Headers {\n\t\thttpReq.Header.Set(k, v)\n\t}\n\n\t// Send request\n\tresp, err := httpClient.Do(httpReq)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to send HTTP request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// Check response status\n\tif resp.StatusCode < 200 || resp.StatusCode >= 300 {\n\t\tbodyBytes, _ := io.ReadAll(resp.Body)\n\t\treturn fmt.Errorf(\"HTTP request failed with status %d: %s\", resp.StatusCode, string(bodyBytes))\n\t}\n\n\treturn nil\n}\n\nfunc (e *Exporter[T]) getOrCreateHTTPClient(cfg *apiclient.OtelConfig) *http.Client {\n\te.mu.RLock()\n\tif e.httpClients == nil {\n\t\te.mu.RUnlock()\n\t\te.mu.Lock()\n\t\te.httpClients = make(map[string]*http.Client)\n\t\te.mu.Unlock()\n\t\te.mu.RLock()\n\t}\n\n\tclient, exists := e.httpClients[cfg.Endpoint]\n\te.mu.RUnlock()\n\n\tif exists {\n\t\treturn client\n\t}\n\n\t// Create new HTTP client\n\te.mu.Lock()\n\tdefer e.mu.Unlock()\n\n\t// Double-check after acquiring write lock\n\tif client, exists := e.httpClients[cfg.Endpoint]; exists {\n\t\treturn client\n\t}\n\n\tclient = &http.Client{\n\t\tTransport: http.DefaultTransport,\n\t}\n\n\te.httpClients[cfg.Endpoint] = client\n\n\treturn client\n}\n\nfunc (e *Exporter[T]) extractSandboxToken(ctx context.Context) (string, error) {\n\t// Try to get client info first (contains HTTP headers)\n\tclientInfo := client.FromContext(ctx)\n\tif token := clientInfo.Metadata.Get(e.config.SandboxAuthTokenHeader); len(token) > 0 {\n\t\treturn token[0], nil\n\t}\n\n\t// Fallback: try gRPC metadata (if using gRPC protocol)\n\tif md, ok := metadata.FromIncomingContext(ctx); ok {\n\t\tif tokens := md.Get(e.config.SandboxAuthTokenHeader); len(tokens) > 0 {\n\t\t\treturn tokens[0], nil\n\t\t}\n\t}\n\n\treturn \"\", fmt.Errorf(\"sandbox token header '%s' not found in metadata\", e.config.SandboxAuthTokenHeader)\n}\n\n//lint:ignore U1000 Used by the built collector\nfunc (e *Exporter[T]) shutdown(ctx context.Context) error {\n\te.mu.Lock()\n\tdefer e.mu.Unlock()\n\n\tif e.httpClients == nil {\n\t\treturn nil\n\t}\n\n\tfor _, client := range e.httpClients {\n\t\t// Close idle connections\n\t\tif transport, ok := client.Transport.(*http.Transport); ok {\n\t\t\ttransport.CloseIdleConnections()\n\t\t}\n\t}\n\n\te.httpClients = nil\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/otel-collector/exporter/factory.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage exporter\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"go.opentelemetry.io/collector/component\"\n\t\"go.opentelemetry.io/collector/config/configoptional\"\n\t\"go.opentelemetry.io/collector/config/configretry\"\n\t\"go.opentelemetry.io/collector/exporter\"\n\t\"go.opentelemetry.io/collector/exporter/exporterhelper\"\n\n\tcommon_cache \"github.com/daytonaio/common-go/pkg/cache\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/otel-collector/exporter/internal/config\"\n)\n\nconst (\n\ttypeStr   = \"daytona_exporter\"\n\tstability = component.StabilityLevelBeta\n)\n\n// NewFactory creates a factory for the custom exporter.\nfunc NewFactory() exporter.Factory {\n\treturn exporter.NewFactory(\n\t\tcomponent.MustNewType(typeStr),\n\t\tcreateDefaultConfig,\n\t\texporter.WithTraces(createTracesExporter, stability),\n\t\texporter.WithMetrics(createMetricsExporter, stability),\n\t\texporter.WithLogs(createLogsExporter, stability),\n\t)\n}\n\n// createDefaultConfig creates the default configuration for the exporter.\nfunc createDefaultConfig() component.Config {\n\treturn &Config{\n\t\tSandboxAuthTokenHeader: \"sandbox-auth-token\",\n\t\tCacheTTL:               5 * time.Minute,\n\t\tDefaultTimeout:         30 * time.Second,\n\t\tRetrySettings:          configretry.NewDefaultBackOffConfig(),\n\t\tSendingQueue:           exporterhelper.NewDefaultQueueConfig(),\n\t}\n}\n\n// createTracesExporter creates a new trace exporter.\nfunc createTracesExporter(\n\tctx context.Context,\n\tset exporter.Settings,\n\tcfg component.Config,\n) (exporter.Traces, error) {\n\tc := cfg.(*Config)\n\n\tclientConfig := apiclient.NewConfiguration()\n\tclientConfig.Servers = apiclient.ServerConfigurations{\n\t\t{\n\t\t\tURL: c.ApiUrl,\n\t\t},\n\t}\n\n\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+c.ApiKey)\n\tapiClient := apiclient.NewAPIClient(clientConfig)\n\n\tapiClient.GetConfig().HTTPClient = &http.Client{\n\t\tTransport: http.DefaultTransport,\n\t}\n\n\tvar cache common_cache.ICache[apiclient.OtelConfig]\n\n\tif c.Redis != nil {\n\t\tredisCache, err := common_cache.NewRedisCache[apiclient.OtelConfig](c.Redis, \"org-otel-config:\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcache = redisCache\n\t} else {\n\t\tcache = common_cache.NewMapCache[apiclient.OtelConfig](ctx)\n\t}\n\n\tresolver := config.NewResolver(cache, set.Logger, apiClient, c.CacheTTL)\n\n\tte := newTracesExporter(exporterConfig{\n\t\tconfig:   c,\n\t\tresolver: resolver,\n\t\tlogger:   set.Logger,\n\t})\n\n\treturn exporterhelper.NewTraces(\n\t\tctx,\n\t\tset,\n\t\tcfg,\n\t\tte.push,\n\t\texporterhelper.WithRetry(c.RetrySettings),\n\t\texporterhelper.WithQueue(configoptional.Some(c.SendingQueue)),\n\t\texporterhelper.WithTimeout(exporterhelper.TimeoutConfig{Timeout: c.DefaultTimeout}),\n\t\texporterhelper.WithShutdown(te.shutdown),\n\t)\n}\n\n// createMetricsExporter creates a new metrics exporter.\nfunc createMetricsExporter(\n\tctx context.Context,\n\tset exporter.Settings,\n\tcfg component.Config,\n) (exporter.Metrics, error) {\n\tc := cfg.(*Config)\n\n\tclientConfig := apiclient.NewConfiguration()\n\tclientConfig.Servers = apiclient.ServerConfigurations{\n\t\t{\n\t\t\tURL: c.ApiUrl,\n\t\t},\n\t}\n\n\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+c.ApiKey)\n\tapiClient := apiclient.NewAPIClient(clientConfig)\n\n\tapiClient.GetConfig().HTTPClient = &http.Client{\n\t\tTransport: http.DefaultTransport,\n\t}\n\n\tvar cache common_cache.ICache[apiclient.OtelConfig]\n\t// Create cache and resolver\n\tif c.Redis != nil {\n\t\tredisCache, err := common_cache.NewRedisCache[apiclient.OtelConfig](c.Redis, \"org-otel-config:\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcache = redisCache\n\t} else {\n\t\tcache = common_cache.NewMapCache[apiclient.OtelConfig](ctx)\n\t}\n\tresolver := config.NewResolver(cache, set.Logger, apiClient, c.CacheTTL)\n\n\tme := newMetricExporter(exporterConfig{\n\t\tconfig:   c,\n\t\tresolver: resolver,\n\t\tlogger:   set.Logger,\n\t})\n\n\treturn exporterhelper.NewMetrics(\n\t\tctx,\n\t\tset,\n\t\tcfg,\n\t\tme.push,\n\t\texporterhelper.WithRetry(c.RetrySettings),\n\t\texporterhelper.WithQueue(configoptional.Some(c.SendingQueue)),\n\t\texporterhelper.WithTimeout(exporterhelper.TimeoutConfig{Timeout: c.DefaultTimeout}),\n\t\texporterhelper.WithShutdown(me.shutdown),\n\t)\n}\n\n// createLogsExporter creates a new logs exporter.\nfunc createLogsExporter(\n\tctx context.Context,\n\tset exporter.Settings,\n\tcfg component.Config,\n) (exporter.Logs, error) {\n\tc := cfg.(*Config)\n\n\tclientConfig := apiclient.NewConfiguration()\n\tclientConfig.Servers = apiclient.ServerConfigurations{\n\t\t{\n\t\t\tURL: c.ApiUrl,\n\t\t},\n\t}\n\n\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+c.ApiKey)\n\tapiClient := apiclient.NewAPIClient(clientConfig)\n\n\tapiClient.GetConfig().HTTPClient = &http.Client{\n\t\tTransport: http.DefaultTransport,\n\t}\n\n\t// Create cache and resolver\n\tvar cache common_cache.ICache[apiclient.OtelConfig]\n\tif c.Redis != nil {\n\t\tredisCache, err := common_cache.NewRedisCache[apiclient.OtelConfig](c.Redis, \"org-otel-config:\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcache = redisCache\n\t} else {\n\t\tcache = common_cache.NewMapCache[apiclient.OtelConfig](ctx)\n\t}\n\tresolver := config.NewResolver(cache, set.Logger, apiClient, c.CacheTTL)\n\n\tle := newLogsExporter(exporterConfig{\n\t\tconfig:   c,\n\t\tresolver: resolver,\n\t\tlogger:   set.Logger,\n\t})\n\n\treturn exporterhelper.NewLogs(\n\t\tctx,\n\t\tset,\n\t\tcfg,\n\t\tle.push,\n\t\texporterhelper.WithRetry(c.RetrySettings),\n\t\texporterhelper.WithQueue(configoptional.Some(c.SendingQueue)),\n\t\texporterhelper.WithTimeout(exporterhelper.TimeoutConfig{Timeout: c.DefaultTimeout}),\n\t\texporterhelper.WithShutdown(le.shutdown),\n\t)\n}\n"
  },
  {
    "path": "apps/otel-collector/exporter/go.mod",
    "content": "module github.com/daytonaio/otel-collector/exporter\n\ngo 1.25.4\n\nrequire (\n\tgithub.com/daytonaio/daytona/libs/api-client-go v0.138.0\n\tgo.opentelemetry.io/collector/client v1.50.0\n\tgo.opentelemetry.io/collector/component v1.50.0\n\tgo.opentelemetry.io/collector/config/configoptional v1.50.0\n\tgo.opentelemetry.io/collector/config/configretry v1.50.0\n\tgo.opentelemetry.io/collector/consumer/consumererror v0.144.0\n\tgo.opentelemetry.io/collector/exporter v1.50.0\n\tgo.opentelemetry.io/collector/exporter/exporterhelper v0.144.0\n\tgo.opentelemetry.io/collector/pdata v1.50.0\n\tgo.uber.org/zap v1.27.1\n\tgoogle.golang.org/grpc v1.79.3\n)\n\nrequire (\n\tgithub.com/cenkalti/backoff/v5 v5.0.3 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/go-viper/mapstructure/v2 v2.5.0 // indirect\n\tgithub.com/gobwas/glob v0.2.3 // indirect\n\tgithub.com/hashicorp/go-version v1.8.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/knadh/koanf/maps v0.1.2 // indirect\n\tgithub.com/knadh/koanf/providers/confmap v1.0.0 // indirect\n\tgithub.com/knadh/koanf/v2 v2.3.0 // indirect\n\tgithub.com/mitchellh/copystructure v1.2.0 // indirect\n\tgithub.com/mitchellh/reflectwalk v1.0.2 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/rogpeppe/go-internal v1.14.1 // indirect\n\tgithub.com/stretchr/testify v1.11.1 // indirect\n\tgo.opentelemetry.io/collector/confmap v1.50.0 // indirect\n\tgo.opentelemetry.io/collector/confmap/xconfmap v0.144.0 // indirect\n\tgo.opentelemetry.io/collector/consumer v1.50.0 // indirect\n\tgo.opentelemetry.io/collector/extension v1.50.0 // indirect\n\tgo.opentelemetry.io/collector/extension/xextension v0.144.0 // indirect\n\tgo.opentelemetry.io/collector/featuregate v1.50.0 // indirect\n\tgo.opentelemetry.io/collector/internal/componentalias v0.144.0 // indirect\n\tgo.opentelemetry.io/collector/pdata/pprofile v0.144.0 // indirect\n\tgo.opentelemetry.io/collector/pdata/xpdata v0.144.0 // indirect\n\tgo.opentelemetry.io/collector/pipeline v1.50.0 // indirect\n\tgo.opentelemetry.io/collector/pipeline/xpipeline v0.144.0 // indirect\n\tgo.opentelemetry.io/otel v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.40.0 // indirect\n\tgo.uber.org/multierr v1.11.0 // indirect\n\tgo.yaml.in/yaml/v3 v3.0.4 // indirect\n\tgolang.org/x/net v0.49.0 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n\tgolang.org/x/text v0.33.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "apps/otel-collector/exporter/go.sum",
    "content": "github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=\ngithub.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/daytonaio/daytona/libs/api-client-go v0.138.0 h1:bdp394Auzt4ibPxjop0znCc+Na4ZWlse4dxwjWHipJw=\ngithub.com/daytonaio/daytona/libs/api-client-go v0.138.0/go.mod h1:1wKpdKRwUzXN7KqR+8MMpq2iEGrprBCgFgFbli89DMo=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=\ngithub.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=\ngithub.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=\ngithub.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=\ngithub.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo=\ngithub.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI=\ngithub.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE=\ngithub.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A=\ngithub.com/knadh/koanf/v2 v2.3.0 h1:Qg076dDRFHvqnKG97ZEsi9TAg2/nFTa9hCdcSa1lvlM=\ngithub.com/knadh/koanf/v2 v2.3.0/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=\ngithub.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=\ngithub.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=\ngithub.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/collector/client v1.50.0 h1:T0WC2bU252x9a7kRZNyyADpkRN6j4HnlfHTnbxc0ElU=\ngo.opentelemetry.io/collector/client v1.50.0/go.mod h1:fFG6F0BeKMMlIj9POp71ynIH+XG8BvIxt+9dqfWNmZA=\ngo.opentelemetry.io/collector/component v1.50.0 h1:AvIhCc/J7tXlKZDETPDMDp6g6pwa3FBD6c0Q8h2u3xA=\ngo.opentelemetry.io/collector/component v1.50.0/go.mod h1:S0p+mq0ZvEEN67BKWt0atC5cHn2Km8vBeeIZuYzD0XU=\ngo.opentelemetry.io/collector/component/componenttest v0.144.0 h1:Ah7E3OVdc3QKu8gyxpxkm4a5TAypUIAICNgY/6GW0sY=\ngo.opentelemetry.io/collector/config/configoptional v1.50.0 h1:XDRdpdyr3OwZOH/RsRjlHJ6qLQL3pX2lfU9FQbTuKBg=\ngo.opentelemetry.io/collector/config/configoptional v1.50.0/go.mod h1:+YcrjSyOX12UdGs91ijQJegAM+Uc8KJ1dpbGT9l15xY=\ngo.opentelemetry.io/collector/config/configretry v1.50.0 h1:pqpX/552geDSqDqTpQsbSuOOy9qUi7RhEZp5ypxtJ1Q=\ngo.opentelemetry.io/collector/config/configretry v1.50.0/go.mod h1:ZSTYqAJCq4qf+/4DGoIxCElDIl5yHt8XxEbcnpWBbMM=\ngo.opentelemetry.io/collector/confmap v1.50.0 h1:ty8pqwn5lwVX3i7RkP9myDOlG8rNUAAtyTQHHatDfhg=\ngo.opentelemetry.io/collector/confmap v1.50.0/go.mod h1:VtbDxsXGkMpQEWUQLmkgT9XBvsbSEPg4FzhaW8HPuVw=\ngo.opentelemetry.io/collector/confmap/xconfmap v0.144.0 h1:jMyiAFt9kyiS1xIOebAV9tuAWd9pwxbcS3CNGsRxaF0=\ngo.opentelemetry.io/collector/confmap/xconfmap v0.144.0/go.mod h1:T6emD9jNoWzBR9ESJ0nONvqM4ClJykkvIPT2sYNqgKk=\ngo.opentelemetry.io/collector/consumer v1.50.0 h1:Sxbue3zNH3IJla+vUyMXEiomfRJaS6wemZd4qv5na48=\ngo.opentelemetry.io/collector/consumer v1.50.0/go.mod h1:GB6gfWsZyeTBWn+Cb3ITkJaH4aA5NW0r2Dm+VLFnD/M=\ngo.opentelemetry.io/collector/consumer/consumererror v0.144.0 h1:bDnvbqp/FSyErSt60HQmDYXEDbWiav49H6m872zbHnw=\ngo.opentelemetry.io/collector/consumer/consumererror v0.144.0/go.mod h1:gODumKlgGfW9s5XVnL5dp+glXipaX+PSKX7W4x+FkFI=\ngo.opentelemetry.io/collector/consumer/consumertest v0.144.0 h1:R2iR10e2rK+9xCCyl/OH0A/SyYzAauFGePovNQlOz90=\ngo.opentelemetry.io/collector/consumer/xconsumer v0.144.0 h1:7J6FCC2qAR2ZHKYX9hH1zvH0+G8E0mc1FZ1V8y/ZAkg=\ngo.opentelemetry.io/collector/exporter v1.50.0 h1:CgzSk8+nVki5pAHe9F2LR0hn8U5OD6LEtyslQuwT52k=\ngo.opentelemetry.io/collector/exporter v1.50.0/go.mod h1:0JyxyYufP9G2puO72T68/10qXfbZvOSUFDla/yXyGQM=\ngo.opentelemetry.io/collector/exporter/exporterhelper v0.144.0 h1:Ea1N1MVaaBUrsolDFazVF1PiT+uD5I/cbKxl5ezXLmw=\ngo.opentelemetry.io/collector/exporter/exporterhelper v0.144.0/go.mod h1:UQ2QRWRjfJjHlc/H48ZwppLmVcoFFhkUkH/Eb9G3L4I=\ngo.opentelemetry.io/collector/exporter/exportertest v0.144.0 h1:h/xHMQmvEaeYwrqEPsXxSvMEGZ0shaCOCbq1/l+2NLU=\ngo.opentelemetry.io/collector/exporter/xexporter v0.144.0 h1:Ztloi1hbCesqAv0TV7xcuClKiDyA6vNwuHl69CXV/LM=\ngo.opentelemetry.io/collector/extension v1.50.0 h1:hNMLDmYslnfO3Q/MdhrSVn+kCAeyxkGA+Qbx+Jtct8M=\ngo.opentelemetry.io/collector/extension v1.50.0/go.mod h1:VLKQToEnO+9x3/Z8L2FoARAXs+moNui35Spj96y5LO4=\ngo.opentelemetry.io/collector/extension/extensiontest v0.144.0 h1:cuLJHJwSB6L/vy2gD61cmqbNh9ToAXB2sBVEGN69W7M=\ngo.opentelemetry.io/collector/extension/xextension v0.144.0 h1:Ax2g4BF/YzrFB0WDraeHaZdtmTeAkhLLnTLE4EOdT0E=\ngo.opentelemetry.io/collector/extension/xextension v0.144.0/go.mod h1:ZJkgXgS5ECu8d5AuPu+yoKJdx7BonE+bp1LrLxd3o6g=\ngo.opentelemetry.io/collector/featuregate v1.50.0 h1:nROGw8VpLuc2/PExnL6ammUpr2y7pozpbwgae6zU4s0=\ngo.opentelemetry.io/collector/featuregate v1.50.0/go.mod h1:/1bclXgP91pISaEeNulRxzzmzMTm4I5Xih2SnI4HRSo=\ngo.opentelemetry.io/collector/internal/componentalias v0.144.0 h1:LO9QWYbce01aP38i5RI6UQsCSa5FSv6fs55qobpvMGQ=\ngo.opentelemetry.io/collector/internal/componentalias v0.144.0/go.mod h1:oAZoM7bcqeeQ2mpXaThkhGeTzxceZ6/LnIlUZ7GiC40=\ngo.opentelemetry.io/collector/internal/testutil v0.144.0 h1:lSI9FBQI21eAxJ/L52pAYxsvKhU5dm9HqXGnKp8XAes=\ngo.opentelemetry.io/collector/pdata v1.50.0 h1:vES5c9jT9HzOhHEg1OIjPxk4qKIjA+Dao8dxU3oePU0=\ngo.opentelemetry.io/collector/pdata v1.50.0/go.mod h1:G18lFpQYh4473PiEPqLd7BKfc8a/j+Fl4EfHWy1Ylx8=\ngo.opentelemetry.io/collector/pdata/pprofile v0.144.0 h1:jzgIl+Hhjr5sfJDals+6Zl0IS1EUtZBChvv+j05Ih44=\ngo.opentelemetry.io/collector/pdata/pprofile v0.144.0/go.mod h1:mipJI/T20uy/+iD3QrzmRUPGenJRhBJj8qGXDpLWoQs=\ngo.opentelemetry.io/collector/pdata/testdata v0.144.0 h1:zg1XWm/S/fBrFy5lr56DLrI5PVFB2sZxU0q5Yf/71Ko=\ngo.opentelemetry.io/collector/pdata/xpdata v0.144.0 h1:83Eei0VYbGyThHB5BRBwGUMLZSePShjse2eHgm41NIM=\ngo.opentelemetry.io/collector/pdata/xpdata v0.144.0/go.mod h1:uKSjEHBBIKAx0udPjB40+xR4sUAhfnfzKfpWz+nIzik=\ngo.opentelemetry.io/collector/pipeline v1.50.0 h1:yOOSvkzpX3yOfO4qvLsUhQflFZ9MI4FmcL+gsAx/WgQ=\ngo.opentelemetry.io/collector/pipeline v1.50.0/go.mod h1:xUrAqiebzYbrgxyoXSkk6/Y3oi5Sy3im2iCA51LwUAI=\ngo.opentelemetry.io/collector/pipeline/xpipeline v0.144.0 h1:KoEWLrK7+qps+eo6paHpRWQat4FX1jy7XArrgOQoCXY=\ngo.opentelemetry.io/collector/pipeline/xpipeline v0.144.0/go.mod h1:2/giOwggQfWb6NY7shJe7Y/DjpKFsAD2m2PX3POuVnI=\ngo.opentelemetry.io/collector/receiver v1.50.0 h1:X6FDV7j0vf/9jm1+OIiUknj0LLBNvsKHQFXS42hKRzg=\ngo.opentelemetry.io/collector/receiver/receivertest v0.144.0 h1:In2XIG7G0gX1up5T9CjsaYRIssl6HUcUSkfUwc5Mcs0=\ngo.opentelemetry.io/collector/receiver/xreceiver v0.144.0 h1:Oj4EUvPL8MUWZHxZKQLsL2oyBcPUWmDE0d1ZyGNyhIM=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE=\ngo.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI=\ngo.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8=\ngo.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA=\ngo.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk=\ngo.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=\ngo.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=\ngo.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=\ngo.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=\ngo.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=\ngo.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=\ngolang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=\ngonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=\ngoogle.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "apps/otel-collector/exporter/internal/config/resolver.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage config\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tcommon_cache \"github.com/daytonaio/common-go/pkg/cache\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"go.uber.org/zap\"\n)\n\n// Resolver handles retrieving and caching endpoint configurations.\ntype Resolver struct {\n\tcache     common_cache.ICache[apiclient.OtelConfig]\n\tlogger    *zap.Logger\n\tapiclient *apiclient.APIClient\n\tcacheTTL  time.Duration\n}\n\n// NewResolver creates a new configuration resolver.\nfunc NewResolver(cache common_cache.ICache[apiclient.OtelConfig], logger *zap.Logger, apiClient *apiclient.APIClient, cacheTTL time.Duration) *Resolver {\n\treturn &Resolver{\n\t\tcache:     cache,\n\t\tlogger:    logger,\n\t\tapiclient: apiClient,\n\t\tcacheTTL:  cacheTTL,\n\t}\n}\n\nfunc (r *Resolver) GetOrganizationOtelConfig(ctx context.Context, authToken string) (*apiclient.OtelConfig, error) {\n\totelConfig, err := r.cache.Get(ctx, authToken)\n\tif err == nil {\n\t\tif otelConfig.Endpoint == \"(none)\" {\n\t\t\treturn nil, nil\n\t\t}\n\t\treturn otelConfig, nil\n\t}\n\n\totelConfig, res, err := r.apiclient.OrganizationsAPI.GetOrganizationOtelConfigBySandboxAuthToken(context.Background(), authToken).Execute()\n\tif err != nil && res != nil && res.StatusCode != 404 {\n\t\treturn nil, err\n\t}\n\n\t// Store this in cache to prevent repeated api calls for orgs that don't have otel endpoints\n\tconfig := &apiclient.OtelConfig{\n\t\tEndpoint: \"(none)\",\n\t}\n\n\tif otelConfig != nil {\n\t\tconfig = &apiclient.OtelConfig{\n\t\t\tEndpoint: otelConfig.Endpoint,\n\t\t\tHeaders:  otelConfig.Headers,\n\t\t}\n\t}\n\n\tif err := r.cache.Set(ctx, authToken, *config, r.cacheTTL); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif config.Endpoint == \"(none)\" {\n\t\treturn nil, nil\n\t}\n\n\treturn config, nil\n}\n\n// InvalidateCache removes a specific sandbox configuration from the cache.\nfunc (r *Resolver) InvalidateCache(ctx context.Context, sandboxID string) error {\n\treturn r.cache.Delete(ctx, sandboxID)\n}\n"
  },
  {
    "path": "apps/otel-collector/project.json",
    "content": "{\n  \"name\": \"otel-collector\",\n  \"$schema\": \"../../runner_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"application\",\n  \"sourceRoot\": \"apps/otel-collector\",\n  \"tags\": [],\n  \"targets\": {\n    \"build\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"commands\": [\n          \"go run -mod=mod go.opentelemetry.io/collector/cmd/builder@v0.144.0 --config {projectRoot}/builder-config.dev.yaml\"\n        ],\n        \"env\": {\n          \"GOWORK\": \"off\"\n        }\n      },\n      \"configurations\": {\n        \"production\": {\n          \"commands\": [\n            \"go run -mod=mod go.opentelemetry.io/collector/cmd/builder@v0.144.0 --config {projectRoot}/builder-config.yaml\"\n          ]\n        }\n      },\n      \"cache\": true,\n      \"outputs\": [\"{workspaceRoot}/dist/apps/otel-collector/**/*\"],\n      \"inputs\": [\"default\", \"!{projectRoot}/config.yaml\", \"!{projectRoot}/config.dev.yaml\"]\n    },\n    \"serve\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"commands\": [\"dist/apps/otel-collector/daytona-otel-collector --config {projectRoot}/config.dev.yaml\"]\n      },\n      \"configurations\": {\n        \"production\": {\n          \"commands\": [\"dist/apps/otel-collector/daytona-otel-collector --config {projectRoot}/config.yaml\"]\n        }\n      },\n      \"dependsOn\": [\"build\"]\n    },\n    \"format\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cd {projectRoot}/exporter && go fmt ./...\"\n      }\n    },\n    \"test\": {\n      \"executor\": \"@nx-go/nx-go:test\"\n    },\n    \"lint\": {\n      \"executor\": \"@nx-go/nx-go:lint\"\n    },\n    \"check-version-env\": {},\n    \"docker\": {\n      \"options\": {\n        \"target\": \"otel-collector\"\n      }\n    },\n    \"push-manifest\": {}\n  }\n}\n"
  },
  {
    "path": "apps/proxy/Dockerfile",
    "content": "FROM node:22-alpine AS build\n\nENV CI=true\n\nRUN npm install -g corepack && corepack enable\n\nCOPY --from=golang:1.25.4-alpine /usr/local/go/ /usr/local/go/\n\nENV PATH=\"/usr/local/go/bin:${PATH}\"\n\nRUN apk add --no-cache git\n\nWORKDIR /daytona\n\n# Yarn caching layer\nCOPY package.json yarn.lock .yarnrc.yml ./\nRUN yarn install --immutable\n\n# Nx config\nCOPY nx.json ./\n\n# Go dependency layer (cached unless go.mod/go.sum change)\nCOPY go.work go.work.sum ./\nCOPY apps/proxy/go.mod apps/proxy/go.sum apps/proxy/\nCOPY libs/common-go/go.mod libs/common-go/go.sum libs/common-go/\nCOPY libs/api-client-go/go.mod libs/api-client-go/go.sum libs/api-client-go/\nRUN head -1 go.work > go.work.tmp && printf '\\nuse (\\n\\t./apps/proxy\\n\\t./libs/common-go\\n\\t./libs/api-client-go\\n)\\n' >> go.work.tmp && mv go.work.tmp go.work\n\nENV NX_DAEMON=false\nENV GONOSUMDB=github.com/daytonaio/daytona\n\nRUN go -C apps/proxy mod download && go -C libs/common-go mod download && go -C libs/api-client-go mod download\n\n# Go source\nCOPY apps/proxy/ apps/proxy/\nCOPY libs/common-go/ libs/common-go/\nCOPY libs/api-client-go/ libs/api-client-go/\n\nARG VERSION=0.0.1\nRUN --mount=type=cache,target=/root/.cache/go-build \\\n  VERSION=$VERSION yarn nx build proxy --configuration=production --nxBail=true\n\nFROM alpine:3.18 AS proxy\n\nRUN apk add --no-cache curl\n\nWORKDIR /usr/local/bin\n\nCOPY --from=build /daytona/dist/apps/proxy daytona-proxy\n\nRUN chmod +x daytona-proxy\n\nHEALTHCHECK CMD [ \"curl\", \"-f\", \"http://localhost:4000/health\" ]\n\nENTRYPOINT [\"daytona-proxy\"]\n"
  },
  {
    "path": "apps/proxy/cmd/proxy/config/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage config\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/daytonaio/common-go/pkg/cache\"\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/go-playground/validator/v10\"\n\t\"github.com/joho/godotenv\"\n\t\"github.com/kelseyhightower/envconfig\"\n)\n\ntype Config struct {\n\tProxyPort             int                `envconfig:\"PROXY_PORT\" validate:\"required\"`\n\tProxyProtocol         string             `envconfig:\"PROXY_PROTOCOL\" validate:\"required\"`\n\tProxyApiKey           string             `envconfig:\"PROXY_API_KEY\" validate:\"required\"`\n\tCookieDomain          *string            `envconfig:\"COOKIE_DOMAIN\"`\n\tTLSCertFile           string             `envconfig:\"TLS_CERT_FILE\"`\n\tTLSKeyFile            string             `envconfig:\"TLS_KEY_FILE\"`\n\tEnableTLS             bool               `envconfig:\"ENABLE_TLS\"`\n\tDaytonaApiUrl         string             `envconfig:\"DAYTONA_API_URL\" validate:\"required\"`\n\tOidc                  OidcConfig         `envconfig:\"OIDC\"`\n\tRedis                 *cache.RedisConfig `envconfig:\"REDIS\"`\n\tToolboxOnlyMode       bool               `envconfig:\"TOOLBOX_ONLY_MODE\"`\n\tPreviewWarningEnabled bool               `envconfig:\"PREVIEW_WARNING_ENABLED\"`\n\tShutdownTimeoutSec    int                `envconfig:\"SHUTDOWN_TIMEOUT_SEC\"`\n\tApiClient             *apiclient.APIClient\n}\n\ntype OidcConfig struct {\n\tClientId     string  `envconfig:\"CLIENT_ID\"`\n\tClientSecret string  `envconfig:\"CLIENT_SECRET\"`\n\tDomain       string  `envconfig:\"DOMAIN\"`\n\tPublicDomain *string `envconfig:\"PUBLIC_DOMAIN\"`\n\tAudience     string  `envconfig:\"AUDIENCE\"`\n}\n\nvar DEFAULT_PROXY_PORT int = 4000\n\nvar config *Config\n\nfunc GetConfig() (*Config, error) {\n\tif config != nil {\n\t\treturn config, nil\n\t}\n\n\tconfig = &Config{}\n\n\t// Load .env files\n\terr := godotenv.Overload(\".env\", \".env.local\", \".env.production\")\n\tif err != nil {\n\t\tlog.Println(\"Warning: Error loading .env file:\", err)\n\t\t// Continue anyway, as environment variables might be set directly\n\t}\n\n\terr = envconfig.Process(\"\", config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar validate = validator.New()\n\terr = validate.Struct(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif config.ProxyPort == 0 {\n\t\tconfig.ProxyPort = DEFAULT_PROXY_PORT\n\t}\n\n\tif config.ShutdownTimeoutSec == 0 {\n\t\tconfig.ShutdownTimeoutSec = 60 * 60 // default to 1 hour\n\t}\n\n\tif config.Redis != nil {\n\t\tif config.Redis.Host == nil || *config.Redis.Host == \"\" {\n\t\t\tconfig.Redis = nil\n\t\t}\n\t}\n\n\tclientConfig := apiclient.NewConfiguration()\n\tclientConfig.Servers = apiclient.ServerConfigurations{\n\t\t{\n\t\t\tURL: config.DaytonaApiUrl,\n\t\t},\n\t}\n\n\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+config.ProxyApiKey)\n\n\tconfig.ApiClient = apiclient.NewAPIClient(clientConfig)\n\n\tconfig.ApiClient.GetConfig().HTTPClient = &http.Client{\n\t\tTransport: http.DefaultTransport,\n\t}\n\n\tctx := context.Background()\n\n\t// Retry fetching Daytona API config with exponential backoff\n\terr = utils.RetryWithExponentialBackoff(\n\t\tctx,\n\t\t\"get Daytona API config\",\n\t\t10,\n\t\ttime.Second,\n\t\t1*time.Minute,\n\t\tfunc() error {\n\t\t\tapiConfig, _, err := config.ApiClient.ConfigAPI.ConfigControllerGetConfig(ctx).Execute()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif config.Oidc.ClientId == \"\" {\n\t\t\t\tconfig.Oidc.ClientId = apiConfig.Oidc.ClientId\n\t\t\t}\n\n\t\t\tif config.Oidc.Domain == \"\" {\n\t\t\t\tconfig.Oidc.Domain = apiConfig.Oidc.Issuer\n\n\t\t\t\tif !strings.HasSuffix(config.Oidc.Domain, \"/\") {\n\t\t\t\t\tconfig.Oidc.Domain += \"/\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif config.Oidc.Audience == \"\" {\n\t\t\t\tconfig.Oidc.Audience = apiConfig.Oidc.Audience\n\t\t\t}\n\n\t\t\treturn nil\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn config, nil\n}\n"
  },
  {
    "path": "apps/proxy/cmd/proxy/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/daytonaio/proxy/cmd/proxy/config\"\n\t\"github.com/daytonaio/proxy/pkg/proxy\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc main() {\n\tconfig, err := config.GetConfig()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\tsigChan := make(chan os.Signal, 1)\n\tsignal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)\n\n\terrChan := make(chan error, 1)\n\tgo func() {\n\t\terrChan <- proxy.StartProxy(ctx, config)\n\t}()\n\n\tvar lastSignalTime time.Time\n\n\tfor {\n\t\tselect {\n\t\tcase <-sigChan:\n\t\t\tif lastSignalTime.IsZero() {\n\t\t\t\tlog.Info(\"Received shutdown, initiating graceful shutdown (press Ctrl+C again to force)\")\n\t\t\t\tcancel()\n\t\t\t\tlastSignalTime = time.Now()\n\t\t\t} else if time.Since(lastSignalTime) < 100*time.Millisecond {\n\t\t\t\t// If started as a subprocess, the app might receive multiple signals in quick succession instead of one\n\t\t\t\t// Debounce very closely spaced signals\n\t\t\t\tlog.Info(\"Received second signal, but within debounce period, ignoring\")\n\t\t\t} else {\n\t\t\t\tlog.Info(\"Received second signal, forcing exit\")\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\t\tcase err := <-errChan:\n\t\t\tif err != nil {\n\t\t\t\tlog.Fatalf(\"Proxy exited with error: %v\", err)\n\t\t\t} else {\n\t\t\t\tlog.Info(\"Proxy exited gracefully\")\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/proxy/go.mod",
    "content": "module github.com/daytonaio/proxy\n\ngo 1.25.4\n\nrequire (\n\tgithub.com/coreos/go-oidc/v3 v3.12.0\n\tgithub.com/gin-contrib/cors v1.7.5\n\tgithub.com/gin-gonic/gin v1.10.1\n\tgithub.com/go-playground/validator/v10 v10.27.0\n\tgithub.com/gorilla/securecookie v1.1.2\n\tgithub.com/joho/godotenv v1.5.1\n\tgithub.com/kelseyhightower/envconfig v1.4.0\n\tgithub.com/mssola/useragent v1.0.0\n\tgithub.com/sirupsen/logrus v1.9.3\n\tgolang.org/x/oauth2 v0.34.0\n)\n\nrequire (\n\tgithub.com/bytedance/sonic v1.14.0 // indirect\n\tgithub.com/bytedance/sonic/loader v0.3.0 // indirect\n\tgithub.com/cloudwego/base64x v0.1.6 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/gabriel-vasile/mimetype v1.4.10 // indirect\n\tgithub.com/gin-contrib/sse v1.1.0 // indirect\n\tgithub.com/go-jose/go-jose/v4 v4.1.3 // indirect\n\tgithub.com/go-playground/locales v0.14.1 // indirect\n\tgithub.com/go-playground/universal-translator v0.18.1 // indirect\n\tgithub.com/goccy/go-json v0.10.5 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.3.0 // indirect\n\tgithub.com/kr/pretty v0.3.1 // indirect\n\tgithub.com/leodido/go-urn v1.4.0 // indirect\n\tgithub.com/mattn/go-isatty v0.0.20 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.4 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/rogpeppe/go-internal v1.14.1 // indirect\n\tgithub.com/stretchr/testify v1.11.1 // indirect\n\tgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirect\n\tgithub.com/ugorji/go/codec v1.3.0 // indirect\n\tgolang.org/x/arch v0.20.0 // indirect\n\tgolang.org/x/crypto v0.47.0 // indirect\n\tgolang.org/x/net v0.49.0 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n\tgolang.org/x/text v0.33.0 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n"
  },
  {
    "path": "apps/proxy/go.sum",
    "content": "github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=\ngithub.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=\ngithub.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=\ngithub.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=\ngithub.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=\ngithub.com/gin-contrib/cors v1.7.5 h1:cXC9SmofOrRg0w9PigwGlHG3ztswH6bqq4vJVXnvYMk=\ngithub.com/gin-contrib/cors v1.7.5/go.mod h1:4q3yi7xBEDDWKapjT2o1V7mScKDDr8k+jZ0fSquGoy0=\ngithub.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=\ngithub.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=\ngithub.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=\ngithub.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=\ngithub.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=\ngithub.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=\ngithub.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=\ngithub.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=\ngithub.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=\ngithub.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=\ngithub.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=\ngithub.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=\ngithub.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=\ngithub.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=\ngithub.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=\ngithub.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=\ngithub.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=\ngithub.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=\ngithub.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/mssola/useragent v1.0.0 h1:WRlDpXyxHDNfvZaPEut5Biveq86Ze4o4EMffyMxmH5o=\ngithub.com/mssola/useragent v1.0.0/go.mod h1:hz9Cqz4RXusgg1EdI4Al0INR62kP7aPSRNHnpU+b85Y=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=\ngithub.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=\ngithub.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=\ngolang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=\ngolang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=\ngolang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=\ngolang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "apps/proxy/internal/buildinfo.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage internal\n\nvar (\n\tVersion = \"v0.0.0-dev\"\n)\n"
  },
  {
    "path": "apps/proxy/pkg/proxy/auth.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc (p *Proxy) Authenticate(ctx *gin.Context, sandboxIdOrSignedToken string, port float32) (sandboxId string, didRedirect bool, err error) {\n\tvar authErrors []string\n\n\t// Try Authorization header with Bearer token\n\tbearerToken := p.getBearerToken(ctx)\n\tif bearerToken != \"\" {\n\t\tisValid, err := p.getSandboxBearerTokenValid(ctx, sandboxIdOrSignedToken, bearerToken)\n\t\tif err != nil {\n\t\t\tauthErrors = append(authErrors, fmt.Sprintf(\"Bearer token validation error: %v\", err))\n\t\t} else if isValid != nil && *isValid {\n\t\t\treturn sandboxIdOrSignedToken, false, nil\n\t\t} else {\n\t\t\tauthErrors = append(authErrors, \"Bearer token is invalid\")\n\t\t}\n\t}\n\n\t// Try auth key from header\n\tauthKey := ctx.Request.Header.Get(SANDBOX_AUTH_KEY_HEADER)\n\tif authKey != \"\" {\n\t\tctx.Request.Header.Del(SANDBOX_AUTH_KEY_HEADER)\n\t\tisValid, err := p.getSandboxAuthKeyValid(ctx, sandboxIdOrSignedToken, authKey)\n\t\tif err != nil {\n\t\t\tauthErrors = append(authErrors, fmt.Sprintf(\"Auth key header validation error: %v\", err))\n\t\t} else if isValid != nil && *isValid {\n\t\t\treturn sandboxIdOrSignedToken, false, nil\n\t\t} else {\n\t\t\tauthErrors = append(authErrors, \"Auth key header is invalid\")\n\t\t}\n\t}\n\n\t// Try auth key from query parameter\n\tqueryAuthKey := ctx.Query(SANDBOX_AUTH_KEY_QUERY_PARAM)\n\tif queryAuthKey != \"\" {\n\t\tisValid, err := p.getSandboxAuthKeyValid(ctx, sandboxIdOrSignedToken, queryAuthKey)\n\t\tif err != nil {\n\t\t\tauthErrors = append(authErrors, fmt.Sprintf(\"Auth key query param validation error: %v\", err))\n\t\t} else if isValid != nil && *isValid {\n\t\t\t// Remove the auth key from the query string\n\t\t\tnewQuery := ctx.Request.URL.Query()\n\t\t\tnewQuery.Del(SANDBOX_AUTH_KEY_QUERY_PARAM)\n\t\t\tctx.Request.URL.RawQuery = newQuery.Encode()\n\t\t\treturn sandboxIdOrSignedToken, false, nil\n\t\t} else {\n\t\t\tauthErrors = append(authErrors, \"Auth key query parameter is invalid\")\n\t\t}\n\t}\n\n\t// Try cookie authentication\n\tcookieSandboxId, err := ctx.Cookie(SANDBOX_AUTH_COOKIE_NAME + sandboxIdOrSignedToken)\n\tif err == nil && cookieSandboxId != \"\" {\n\t\tdecodedValue := \"\"\n\t\terr = p.secureCookie.Decode(SANDBOX_AUTH_COOKIE_NAME+sandboxIdOrSignedToken, cookieSandboxId, &decodedValue)\n\t\tif err != nil {\n\t\t\tauthErrors = append(authErrors, fmt.Sprintf(\"Cookie decoding error: %v\", err))\n\t\t} else {\n\t\t\treturn decodedValue, false, nil\n\t\t}\n\t}\n\n\tif !ctx.GetBool(IS_TOOLBOX_REQUEST_KEY) {\n\t\tcookieDomain := p.getCookieDomain(ctx.Request.Host)\n\t\tsandboxId, err = p.getSandboxIdFromSignedPreviewUrlToken(ctx, sandboxIdOrSignedToken, port, cookieDomain)\n\t\tif err == nil {\n\t\t\treturn sandboxId, false, nil\n\t\t} else {\n\t\t\tauthErrors = append(authErrors, err.Error())\n\t\t}\n\n\t\t// All authentication methods failed, redirect to auth URL\n\t\tauthUrl, err := p.getAuthUrl(ctx, sandboxIdOrSignedToken)\n\t\tif err != nil {\n\t\t\treturn sandboxIdOrSignedToken, false, fmt.Errorf(\"failed to get auth URL: %w\", err)\n\t\t}\n\n\t\tctx.Redirect(http.StatusTemporaryRedirect, authUrl)\n\t}\n\n\t// Return error with details about what failed\n\tvar errorMsg string\n\tif len(authErrors) > 0 {\n\t\terrorMsg = fmt.Sprintf(\"authentication failed: %s\", strings.Join(authErrors, \",\"))\n\t} else {\n\t\terrorMsg = \"missing authentication: provide a preview access token (via header, query parameter, or cookie) or use an API key or JWT\"\n\t}\n\n\treturn sandboxIdOrSignedToken, !ctx.GetBool(IS_TOOLBOX_REQUEST_KEY), common_errors.NewUnauthorizedError(errors.New(errorMsg))\n}\n\nfunc (p *Proxy) getBearerToken(ctx *gin.Context) string {\n\tauthHeader := ctx.Request.Header.Get(\"Authorization\")\n\tif authHeader != \"\" && strings.HasPrefix(authHeader, \"Bearer \") {\n\t\treturn strings.TrimSpace(strings.TrimPrefix(authHeader, \"Bearer \"))\n\t}\n\treturn \"\"\n}\n\nfunc (p *Proxy) getSandboxIdFromSignedPreviewUrlToken(ctx *gin.Context, sandboxIdOrSignedToken string, port float32, cookieDomain string) (string, error) {\n\tvar sandboxId string\n\terr := utils.RetryWithExponentialBackoff(ctx.Request.Context(), \"getSandboxIdFromSignedPreviewUrlToken\", proxyMaxRetries, proxyBaseDelay, proxyMaxDelay, func() error {\n\t\ts, _, e := p.apiclient.PreviewAPI.GetSandboxIdFromSignedPreviewUrlToken(ctx.Request.Context(), sandboxIdOrSignedToken, port).Execute()\n\t\tsandboxId = s\n\t\topenapiErr := common_errors.ConvertOpenAPIError(e)\n\n\t\tif openapiErr != nil && !common_errors.IsRetryableOpenAPIError(openapiErr) {\n\t\t\treturn &utils.NonRetryableError{Err: openapiErr}\n\t\t}\n\n\t\treturn openapiErr\n\t})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tencoded, err := p.secureCookie.Encode(SANDBOX_AUTH_COOKIE_NAME+sandboxIdOrSignedToken, sandboxId)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to encode cookie: %w\", err)\n\t}\n\n\tctx.SetCookie(SANDBOX_AUTH_COOKIE_NAME+sandboxIdOrSignedToken, encoded, 3600, \"/\", cookieDomain, p.config.EnableTLS, true)\n\n\treturn sandboxId, nil\n}\n"
  },
  {
    "path": "apps/proxy/pkg/proxy/auth_callback.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/coreos/go-oidc/v3/oidc\"\n\t\"github.com/gin-gonic/gin\"\n\t\"golang.org/x/oauth2\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n)\n\nfunc (p *Proxy) AuthCallback(ctx *gin.Context) {\n\tif ctx.Query(\"error\") != \"\" {\n\t\terr := ctx.Query(\"error\")\n\t\tif ctx.Query(\"error_description\") != \"\" {\n\t\t\terr = ctx.Query(\"error_description\")\n\t\t}\n\t\tctx.Error(common_errors.NewUnauthorizedError(errors.New(err)))\n\t\treturn\n\t}\n\n\tcode := ctx.Query(\"code\")\n\tif code == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"no code in callback\")))\n\t\treturn\n\t}\n\n\tstate := ctx.Query(\"state\")\n\tif state == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"no state in callback\")))\n\t\treturn\n\t}\n\n\t// Decode state\n\tstateJson, err := base64.URLEncoding.DecodeString(state)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to decode state: %w\", err)))\n\t\treturn\n\t}\n\n\tvar stateData map[string]string\n\terr = json.Unmarshal(stateJson, &stateData)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to unmarshal state: %w\", err)))\n\t\treturn\n\t}\n\n\treturnTo := stateData[\"returnTo\"]\n\tif returnTo == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"no returnTo in state\")))\n\t\treturn\n\t}\n\n\tsandboxId := stateData[\"sandboxId\"]\n\tif sandboxId == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"no sandboxId in state\")))\n\t\treturn\n\t}\n\n\t// Retrieve PKCE code verifier from secure cookie\n\tcodeVerifierCookie, err := ctx.Cookie(\"pkce_verifier\")\n\tif err != nil || codeVerifierCookie == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"authentication state verification failed\")))\n\t\treturn\n\t}\n\tvar codeVerifier string\n\tif err := p.secureCookie.Decode(\"pkce_verifier\", codeVerifierCookie, &codeVerifier); err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to decode pkce_verifier cookie: %w\", err)))\n\t\treturn\n\t}\n\n\tcookieDomain := p.getCookieDomain(ctx.Request.Host)\n\n\t// Clear the PKCE cookie\n\tctx.SetCookie(\"pkce_verifier\", \"\", -1, \"/\", cookieDomain, p.config.EnableTLS, true)\n\n\t// Exchange code for token\n\tauthContext, endpoint, err := p.getOidcEndpoint(ctx)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to initialize OIDC provider: %w\", err)))\n\t\treturn\n\t}\n\n\toauth2Config := oauth2.Config{\n\t\tClientID:     p.config.Oidc.ClientId,\n\t\tClientSecret: p.config.Oidc.ClientSecret,\n\t\tRedirectURL:  fmt.Sprintf(\"%s://%s/callback\", p.config.ProxyProtocol, ctx.Request.Host),\n\t\tEndpoint:     *endpoint,\n\t\tScopes:       []string{oidc.ScopeOpenID, \"profile\"},\n\t}\n\n\ttoken, err := oauth2Config.Exchange(authContext, code, oauth2.VerifierOption(codeVerifier))\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to exchange token: %w\", err)))\n\t\treturn\n\t}\n\n\thasAccess, err := p.hasSandboxAccess(ctx, sandboxId, token.AccessToken)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewInternalServerError(fmt.Errorf(\"failed to verify sandbox access: %w\", err)))\n\t\treturn\n\t}\n\tif !hasAccess {\n\t\tctx.Error(common_errors.NewNotFoundError(errors.New(\"sandbox not found\")))\n\t\treturn\n\t}\n\n\tencoded, err := p.secureCookie.Encode(SANDBOX_AUTH_COOKIE_NAME+sandboxId, sandboxId)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to encode cookie: %w\", err)))\n\t\treturn\n\t}\n\n\tctx.SetCookie(SANDBOX_AUTH_COOKIE_NAME+sandboxId, encoded, 3600, \"/\", cookieDomain, p.config.EnableTLS, true)\n\n\t// Redirect back to the original URL\n\tctx.Redirect(http.StatusFound, returnTo)\n}\n\nfunc (p *Proxy) getAuthUrl(ctx *gin.Context, sandboxId string) (string, error) {\n\t_, endpoint, err := p.getOidcEndpoint(ctx)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to initialize OIDC endpoint: %w\", err)\n\t}\n\n\t_, _, baseHost, err := p.parseHost(ctx.Request.Host)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to parse request host: %w\", err)\n\t}\n\n\toauth2Config := oauth2.Config{\n\t\tClientID:     p.config.Oidc.ClientId,\n\t\tClientSecret: p.config.Oidc.ClientSecret,\n\t\tRedirectURL:  fmt.Sprintf(\"%s://%s/callback\", p.config.ProxyProtocol, baseHost),\n\t\tEndpoint:     *endpoint,\n\t\tScopes:       []string{oidc.ScopeOpenID, \"profile\"},\n\t}\n\n\tstate, err := GenerateRandomState()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to generate random state: %w\", err)\n\t}\n\n\t// Generate PKCE code verifier and store in secure cookie\n\tcodeVerifier := oauth2.GenerateVerifier()\n\tencodedVerifier, err := p.secureCookie.Encode(\"pkce_verifier\", codeVerifier)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to encode pkce_verifier cookie: %w\", err)\n\t}\n\n\tcookieDomain := p.getCookieDomain(baseHost)\n\n\tctx.SetCookie(\"pkce_verifier\", encodedVerifier, 300, \"/\", cookieDomain, p.config.EnableTLS, true)\n\n\t// Store the original request URL in the state\n\tstateData := map[string]string{\n\t\t\"state\":     state,\n\t\t\"returnTo\":  fmt.Sprintf(\"%s://%s%s\", p.config.ProxyProtocol, ctx.Request.Host, ctx.Request.URL.String()),\n\t\t\"sandboxId\": sandboxId,\n\t}\n\tstateJson, err := json.Marshal(stateData)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to marshal state: %w\", err)\n\t}\n\tencodedState := base64.URLEncoding.EncodeToString(stateJson)\n\n\tauthURL := oauth2Config.AuthCodeURL(\n\t\tencodedState,\n\t\toauth2.SetAuthURLParam(\"audience\", p.config.Oidc.Audience),\n\t\toauth2.S256ChallengeOption(codeVerifier),\n\t)\n\n\treturn authURL, nil\n}\n\nfunc (p *Proxy) hasSandboxAccess(ctx context.Context, sandboxId string, authToken string) (bool, error) {\n\tapiClient := p.getUserApiClient(ctx, authToken)\n\n\t_, res, err := apiClient.PreviewAPI.HasSandboxAccess(context.Background(), sandboxId).Execute()\n\tif res != nil && res.StatusCode == http.StatusOK {\n\t\treturn true, nil\n\t}\n\topenapiErr := common_errors.ConvertOpenAPIError(err)\n\n\tif openapiErr != nil {\n\t\tif res != nil && res.StatusCode >= 400 && res.StatusCode < 500 &&\n\t\t\tres.StatusCode != http.StatusRequestTimeout && res.StatusCode != http.StatusTooManyRequests {\n\t\t\treturn false, nil\n\t\t}\n\t\tif !common_errors.IsRetryableOpenAPIError(openapiErr) {\n\t\t\treturn false, &utils.NonRetryableError{Err: openapiErr}\n\t\t}\n\n\t\treturn false, openapiErr\n\t}\n\n\treturn false, nil\n}\n\nfunc (p *Proxy) getUserApiClient(ctx context.Context, authToken string) *apiclient.APIClient {\n\tclientConfig := apiclient.NewConfiguration()\n\tclientConfig.Servers = apiclient.ServerConfigurations{\n\t\t{\n\t\t\tURL: p.config.DaytonaApiUrl,\n\t\t},\n\t}\n\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+authToken)\n\tif ginCtx, ok := ctx.(*gin.Context); ok {\n\t\tclientConfig.AddDefaultHeader(\"X-Forwarded-For\", ginCtx.ClientIP())\n\t}\n\n\tapiClient := apiclient.NewAPIClient(clientConfig)\n\n\treturn apiClient\n}\n\nfunc (p *Proxy) getOidcEndpoint(ctx context.Context) (context.Context, *oauth2.Endpoint, error) {\n\tproviderCtx := ctx\n\t// If the public domain is set, override the issuer URL to the private domain\n\tif p.config.Oidc.PublicDomain != nil && *p.config.Oidc.PublicDomain != \"\" {\n\t\tproviderCtx = oidc.InsecureIssuerURLContext(ctx, p.config.Oidc.Domain)\n\t}\n\tprovider, err := oidc.NewProvider(providerCtx, p.config.Oidc.Domain)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to initialize OIDC provider: %w\", err)\n\t}\n\n\tendpoint := provider.Endpoint()\n\n\t// Override endpoints to use internal domain\n\tif p.config.Oidc.PublicDomain != nil && *p.config.Oidc.PublicDomain != \"\" {\n\t\tendpoint.TokenURL = strings.Replace(endpoint.TokenURL, *p.config.Oidc.PublicDomain, p.config.Oidc.Domain, 1)\n\t\t// endpoint.AuthURL = strings.Replace(endpoint.AuthURL, *p.config.Oidc.PublicDomain, p.config.Oidc.Domain, 1)\n\t\tendpoint.DeviceAuthURL = strings.Replace(endpoint.DeviceAuthURL, *p.config.Oidc.PublicDomain, p.config.Oidc.Domain, 1)\n\t}\n\n\treturn providerCtx, &endpoint, nil\n}\n\nfunc (p *Proxy) getCookieDomain(host string) string {\n\tif p.cookieDomain != nil {\n\t\treturn *p.cookieDomain\n\t}\n\treturn GetCookieDomainFromHost(host)\n}\n\nfunc GenerateRandomState() (string, error) {\n\tb := make([]byte, 32)\n\t_, err := rand.Read(b)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn base64.URLEncoding.EncodeToString(b), nil\n}\n\nfunc GetCookieDomainFromHost(host string) string {\n\thost = strings.Split(host, \":\")[0]\n\treturn fmt.Sprintf(\".%s\", host)\n}\n"
  },
  {
    "path": "apps/proxy/pkg/proxy/get_sandbox_build_target.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"regexp\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc (p *Proxy) getSandboxBuildTarget(ctx *gin.Context) (*url.URL, map[string]string, error) {\n\t// Extract sandbox ID from the path\n\tmatch := regexp.MustCompile(`^/sandboxes/([\\w-]+)/build-logs$`).FindStringSubmatch(ctx.Request.URL.Path)\n\tif len(match) != 2 {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"sandbox ID is required\")))\n\t\treturn nil, nil, errors.New(\"sandbox ID is required\")\n\t}\n\n\tsandboxId := match[1]\n\n\tsandbox, err := p.getSandbox(ctx, sandboxId)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn nil, nil, fmt.Errorf(\"failed to get sandbox: %w\", err)\n\t}\n\n\tif sandbox.BuildInfo == nil {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"sandbox has no build info\")))\n\t\treturn nil, nil, errors.New(\"sandbox has no build info\")\n\t}\n\n\trunnerInfo, err := p.getRunnerInfo(ctx, *sandbox.RunnerId)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn nil, nil, fmt.Errorf(\"failed to get runner info: %w\", err)\n\t}\n\n\tqueryParams := ctx.Request.URL.Query()\n\tqueryParams.Add(\"snapshotRef\", sandbox.BuildInfo.SnapshotRef)\n\n\t// Build the target URL\n\ttargetURL := fmt.Sprintf(\"%s/snapshots/logs\", runnerInfo.ApiUrl)\n\n\t// Create the complete target URL with path\n\ttarget, err := url.Parse(targetURL)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to parse target URL: %w\", err)))\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse target URL: %w\", err)\n\t}\n\ttarget.RawQuery = queryParams.Encode()\n\n\treturn target, map[string]string{\n\t\t\"X-Daytona-Authorization\": fmt.Sprintf(\"Bearer %s\", runnerInfo.ApiKey),\n\t\t\"X-Forwarded-Host\":        ctx.Request.Host,\n\t}, nil\n}\n\nfunc (p *Proxy) getSandbox(ctx *gin.Context, sandboxId string) (*apiclient.Sandbox, error) {\n\tvar sandbox *apiclient.Sandbox\n\tbearerToken := p.getBearerToken(ctx)\n\tapiClient := p.getUserApiClient(ctx, bearerToken)\n\n\terr := utils.RetryWithExponentialBackoff(ctx, \"getSandbox\", proxyMaxRetries, proxyBaseDelay, proxyMaxDelay, func() error {\n\t\ts, _, e := apiClient.SandboxAPI.GetSandbox(ctx, sandboxId).Execute()\n\t\tsandbox = s\n\t\topenapiErr := common_errors.ConvertOpenAPIError(e)\n\n\t\tif openapiErr != nil && !common_errors.IsRetryableOpenAPIError(openapiErr) {\n\t\t\treturn &utils.NonRetryableError{Err: openapiErr}\n\t\t}\n\n\t\treturn openapiErr\n\t})\n\treturn sandbox, err\n}\n"
  },
  {
    "path": "apps/proxy/pkg/proxy/get_sandbox_target.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/gin-gonic/gin\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc (p *Proxy) GetProxyTarget(ctx *gin.Context) (*url.URL, map[string]string, error) {\n\tvar targetPort, targetPath, sandboxIdOrSignedToken string\n\n\tif ctx.GetBool(IS_TOOLBOX_REQUEST_KEY) {\n\t\t// Expected format: /toolbox/<sandboxID>/<targetPath>\n\t\tvar err error\n\t\ttargetPort, sandboxIdOrSignedToken, targetPath, err = p.parseToolboxSubpath(ctx.Param(\"path\"))\n\t\tif err != nil {\n\t\t\tctx.Error(common_errors.NewBadRequestError(err))\n\t\t\treturn nil, nil, err\n\t\t}\n\t} else {\n\t\t// Extract port and sandbox ID from the host header\n\t\t// Expected format: 1234-<sandboxId | token>.proxy.domain\n\t\tvar err error\n\t\ttargetPort, sandboxIdOrSignedToken, _, err = p.parseHost(ctx.Request.Host)\n\t\tif err != nil {\n\t\t\tctx.Error(common_errors.NewBadRequestError(err))\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\ttargetPath = ctx.Param(\"path\")\n\t}\n\n\tif targetPort == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"target port is required\")))\n\t\treturn nil, nil, errors.New(\"target port is required\")\n\t}\n\n\tif sandboxIdOrSignedToken == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"sandbox ID or signed token is required\")))\n\t\treturn nil, nil, errors.New(\"sandbox ID or signed token is required\")\n\t}\n\n\tsandboxId := sandboxIdOrSignedToken\n\n\tisPublic, err := p.getSandboxPublic(ctx, sandboxIdOrSignedToken)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to get sandbox public status: %w\", err)))\n\t\treturn nil, nil, fmt.Errorf(\"failed to get sandbox public status: %w\", err)\n\t}\n\n\tif !*isPublic || targetPort == TERMINAL_PORT || targetPort == TOOLBOX_PORT || targetPort == RECORDING_DASHBOARD_PORT {\n\t\tportFloat, err := strconv.ParseFloat(targetPort, 64)\n\t\tif err != nil {\n\t\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to parse target port: %w\", err)))\n\t\t\treturn nil, nil, fmt.Errorf(\"failed to parse target port: %w\", err)\n\t\t}\n\t\tvar didRedirect bool\n\t\tsandboxId, didRedirect, err = p.Authenticate(ctx, sandboxIdOrSignedToken, float32(portFloat))\n\t\tif err != nil {\n\t\t\tif !didRedirect {\n\t\t\t\tctx.Error(err)\n\t\t\t}\n\t\t\treturn nil, nil, err\n\t\t}\n\t}\n\n\trunnerInfo, err := p.getSandboxRunnerInfo(ctx, sandboxId)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to get runner info: %w\", err)))\n\t\treturn nil, nil, fmt.Errorf(\"failed to get runner info: %w\", err)\n\t}\n\n\t// Skip last activity update if header is set\n\tif ctx.Request.Header.Get(SKIP_LAST_ACTIVITY_UPDATE_HEADER) != \"true\" {\n\t\tdoneCh := make(chan struct{})\n\t\tgo p.updateLastActivity(ctx.Request.Context(), sandboxId, true, doneCh)\n\t\tctx.Request.Header.Del(SKIP_LAST_ACTIVITY_UPDATE_HEADER)\n\t\tctx.Set(ACTIVITY_POLL_STOP_KEY, func() {\n\t\t\tclose(doneCh)\n\t\t})\n\t}\n\n\t// Build the target URL\n\ttargetURL := fmt.Sprintf(\"%s/sandboxes/%s/toolbox/proxy/%s\", runnerInfo.ApiUrl, sandboxId, targetPort)\n\tif ctx.GetBool(IS_TOOLBOX_REQUEST_KEY) {\n\t\ttargetURL = fmt.Sprintf(\"%s/sandboxes/%s/toolbox\", runnerInfo.ApiUrl, sandboxId)\n\t}\n\n\t// Ensure path always has a leading slash but not duplicate slashes\n\tif targetPath == \"\" {\n\t\ttargetPath = \"/\"\n\t} else if !strings.HasPrefix(targetPath, \"/\") {\n\t\ttargetPath = \"/\" + targetPath\n\t}\n\n\t// Create the complete target URL with path\n\ttarget, err := url.Parse(fmt.Sprintf(\"%s%s\", targetURL, targetPath))\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to parse target URL: %w\", err)))\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse target URL: %w\", err)\n\t}\n\n\treturn target, map[string]string{\n\t\t\"X-Daytona-Authorization\": fmt.Sprintf(\"Bearer %s\", runnerInfo.ApiKey),\n\t\t\"X-Forwarded-Host\":        ctx.Request.Host,\n\t}, nil\n}\n\nfunc (p *Proxy) getSandboxRunnerInfo(ctx context.Context, sandboxId string) (*RunnerInfo, error) {\n\trunnerInfo, err := p.sandboxRunnerCache.Get(ctx, sandboxId)\n\tif err == nil {\n\t\treturn runnerInfo, nil\n\t}\n\n\tvar runner *apiclient.RunnerFull\n\terr = utils.RetryWithExponentialBackoff(ctx, \"getSandboxRunnerInfo\", proxyMaxRetries, proxyBaseDelay, proxyMaxDelay, func() error {\n\t\tr, _, e := p.apiclient.RunnersAPI.GetRunnerBySandboxId(context.Background(), sandboxId).Execute()\n\t\trunner = r\n\t\topenapiErr := common_errors.ConvertOpenAPIError(e)\n\n\t\tif openapiErr != nil && !common_errors.IsRetryableOpenAPIError(openapiErr) {\n\t\t\treturn &utils.NonRetryableError{Err: openapiErr}\n\t\t}\n\n\t\treturn openapiErr\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif runner.ProxyUrl == nil {\n\t\treturn nil, errors.New(\"runner proxy URL not found\")\n\t}\n\n\tinfo := RunnerInfo{\n\t\tApiUrl: *runner.ProxyUrl,\n\t\tApiKey: runner.ApiKey,\n\t}\n\n\terr = p.sandboxRunnerCache.Set(ctx, sandboxId, info, 2*time.Minute)\n\tif err != nil {\n\t\tlog.Errorf(\"Failed to set runner info in cache: %v\", err)\n\t}\n\n\treturn &info, nil\n}\n\nfunc (p *Proxy) getSandboxPublic(ctx context.Context, sandboxId string) (*bool, error) {\n\tisPublicCache, err := p.sandboxPublicCache.Get(ctx, sandboxId)\n\tif err == nil {\n\t\treturn isPublicCache, nil\n\t}\n\n\tvar isPublic bool\n\terr = utils.RetryWithExponentialBackoff(ctx, \"getSandboxPublic\", proxyMaxRetries, proxyBaseDelay, proxyMaxDelay, func() error {\n\t\t_, res, err := p.apiclient.PreviewAPI.IsSandboxPublic(context.Background(), sandboxId).Execute()\n\t\tif res != nil && res.StatusCode == http.StatusOK {\n\t\t\tisPublic = true\n\t\t\treturn nil\n\t\t}\n\t\topenapiErr := common_errors.ConvertOpenAPIError(err)\n\n\t\tif openapiErr != nil {\n\t\t\tif res != nil && res.StatusCode >= 400 && res.StatusCode < 500 &&\n\t\t\t\tres.StatusCode != http.StatusRequestTimeout && res.StatusCode != http.StatusTooManyRequests {\n\t\t\t\tisPublic = false\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif !common_errors.IsRetryableOpenAPIError(openapiErr) {\n\t\t\t\treturn &utils.NonRetryableError{Err: openapiErr}\n\t\t\t}\n\t\t\treturn openapiErr\n\t\t}\n\t\tisPublic = false\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif cacheErr := p.sandboxPublicCache.Set(ctx, sandboxId, isPublic, 1*time.Hour); cacheErr != nil {\n\t\tlog.Errorf(\"Failed to set sandbox public in cache: %v\", cacheErr)\n\t}\n\n\treturn &isPublic, nil\n}\n\nfunc (p *Proxy) getSandboxAuthKeyValid(ctx context.Context, sandboxId string, authKey string) (*bool, error) {\n\tapiValidation := func() (bool, error) {\n\t\t_, resp, err := p.apiclient.PreviewAPI.IsValidAuthToken(context.Background(), sandboxId, authKey).Execute()\n\t\tif resp != nil && resp.StatusCode == http.StatusOK {\n\t\t\treturn true, nil\n\t\t}\n\t\topenapiErr := common_errors.ConvertOpenAPIError(err)\n\n\t\tif openapiErr != nil {\n\t\t\tif resp != nil && resp.StatusCode >= 400 && resp.StatusCode < 500 &&\n\t\t\t\tresp.StatusCode != http.StatusRequestTimeout && resp.StatusCode != http.StatusTooManyRequests {\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t\tif !common_errors.IsRetryableOpenAPIError(openapiErr) {\n\t\t\t\treturn false, &utils.NonRetryableError{Err: openapiErr}\n\t\t\t}\n\t\t\treturn false, openapiErr\n\t\t}\n\t\treturn false, nil\n\t}\n\n\treturn p.validateAndCache(ctx, sandboxId, authKey, apiValidation)\n}\n\nfunc (p *Proxy) getSandboxBearerTokenValid(ctx context.Context, sandboxId string, bearerToken string) (*bool, error) {\n\tapiValidation := func() (bool, error) {\n\t\treturn p.hasSandboxAccess(ctx, sandboxId, bearerToken)\n\t}\n\n\treturn p.validateAndCache(ctx, sandboxId, bearerToken, apiValidation)\n}\n\nfunc (p *Proxy) validateAndCache(\n\tctx context.Context,\n\tsandboxId string,\n\tauthKey string,\n\tapiValidation func() (bool, error),\n) (*bool, error) {\n\tcacheKey := fmt.Sprintf(\"%s:%s\", sandboxId, authKey)\n\tauthKeyValidCache, err := p.sandboxAuthKeyValidCache.Get(ctx, cacheKey)\n\tif err == nil {\n\t\treturn authKeyValidCache, nil\n\t}\n\n\tvar isValid bool\n\tvalidationErr := utils.RetryWithExponentialBackoff(ctx, \"validateAndCache\", proxyMaxRetries, proxyBaseDelay, proxyMaxDelay, func() error {\n\t\tresult, err := apiValidation()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tisValid = result\n\t\treturn nil\n\t})\n\tif validationErr != nil {\n\t\treturn nil, validationErr\n\t}\n\n\tif err := p.sandboxAuthKeyValidCache.Set(ctx, cacheKey, isValid, 2*time.Minute); err != nil {\n\t\tlog.Errorf(\"Failed to set sandbox auth key valid in cache: %v\", err)\n\t}\n\n\treturn &isValid, nil\n}\n\nfunc (p *Proxy) parseHost(host string) (targetPort string, sandboxIdOrSignedToken string, baseHost string, err error) {\n\t// Extract port and sandbox ID from the host header\n\t// Expected format: 1234-some-id-uuid.proxy.domain\n\tif host == \"\" {\n\t\treturn \"\", \"\", \"\", errors.New(\"host is required\")\n\t}\n\n\t// Split the host to extract the port and sandbox ID\n\tparts := strings.Split(host, \".\")\n\tif len(parts) == 0 {\n\t\treturn \"\", \"\", \"\", errors.New(\"invalid host format\")\n\t}\n\n\tif len(parts) < 2 {\n\t\treturn \"\", \"\", \"\", errors.New(\"invalid host format: must have subdomain\")\n\t}\n\n\t// Extract port from the first part (e.g., \"1234-some-id-uuid\")\n\thostPrefix := parts[0]\n\tbefore, after, ok := strings.Cut(hostPrefix, \"-\")\n\tif !ok {\n\t\treturn \"\", \"\", \"\", errors.New(\"invalid host format: port and sandbox ID not found\")\n\t}\n\n\ttargetPort = before\n\n\t// Check that port is numeric\n\tif _, err := strconv.Atoi(targetPort); err != nil {\n\t\treturn \"\", \"\", \"\", fmt.Errorf(\"invalid port '%s': must be numeric\", targetPort)\n\t}\n\n\tsandboxIdOrSignedToken = after\n\t// Join remaining parts to form the base domain (e.g., \"proxy.domain\")\n\tbaseHost = strings.Join(parts[1:], \".\")\n\n\treturn targetPort, sandboxIdOrSignedToken, baseHost, nil\n}\n\n// updateLastActivity updates the last activity timestamp for a sandbox.\n// If shouldPollUpdate is true, it starts a goroutine that updates every 50 seconds.\nfunc (p *Proxy) updateLastActivity(ctx context.Context, sandboxId string, shouldPollUpdate bool, doneCh chan struct{}) {\n\t// Prevent frequent updates by caching the last update\n\tcached, err := p.sandboxLastActivityUpdateCache.Has(ctx, sandboxId)\n\tif err != nil {\n\t\t// If cache doesn't work, skip the update to avoid spamming the API\n\t\tlog.Errorf(\"failed to check last activity update cache for sandbox %s: %v\", sandboxId, err)\n\t\treturn\n\t}\n\n\t// Poll interval is 50 seconds to avoid spamming the API which will also cache updates for 45 seconds\n\tpollInterval := 50 * time.Second\n\n\tif !cached {\n\t\t_, err := p.apiclient.SandboxAPI.UpdateLastActivity(ctx, sandboxId).Execute()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlog.Errorf(\"failed to update last activity for sandbox %s: %v\", sandboxId, err)\n\t\t\treturn\n\t\t}\n\n\t\t// Expire a bit before the poll interval to avoid skipping one interval\n\t\terr = p.sandboxLastActivityUpdateCache.Set(ctx, sandboxId, true, pollInterval-5*time.Second)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"failed to set last activity update cache for sandbox %s: %v\", sandboxId, err)\n\t\t}\n\t}\n\n\tif shouldPollUpdate {\n\t\t// Update keep alive every pollInterval until stopped\n\t\tgo func() {\n\t\t\tticker := time.NewTicker(pollInterval)\n\t\t\tdefer ticker.Stop()\n\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase <-ticker.C:\n\t\t\t\t\tp.updateLastActivity(context.WithoutCancel(ctx), sandboxId, false, doneCh)\n\t\t\t\tcase <-doneCh:\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n}\n\nfunc (p *Proxy) parseToolboxSubpath(path string) (string, string, string, error) {\n\t// Expected format: /toolbox/<sandboxID>/<path>\n\tif path == \"\" {\n\t\treturn \"\", \"\", \"\", errors.New(\"path is required\")\n\t}\n\n\tif !strings.HasPrefix(path, \"/toolbox/\") {\n\t\treturn \"\", \"\", \"\", errors.New(\"path must start with /toolbox/\")\n\t}\n\n\t// Trim prefix and split by \"/\"\n\tparts := strings.SplitN(strings.TrimPrefix(path, \"/toolbox/\"), \"/\", 2)\n\tif len(parts) < 2 {\n\t\treturn \"\", \"\", \"\", errors.New(\"path must be of format /toolbox/<sandboxId>/<path>\")\n\t}\n\n\tsandboxID := parts[0]\n\ttargetPath := \"/\" + parts[1]\n\n\treturn TOOLBOX_PORT, sandboxID, targetPath, nil\n}\n"
  },
  {
    "path": "apps/proxy/pkg/proxy/get_snapshot_target.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/gin-gonic/gin\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc (p *Proxy) getSnapshotTarget(ctx *gin.Context) (*url.URL, map[string]string, error) {\n\t// Extract snapshot ID from the path\n\tmatch := regexp.MustCompile(`^/snapshots/([\\w-]+)/build-logs$`).FindStringSubmatch(ctx.Request.URL.Path)\n\tif len(match) != 2 {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"snapshot ID is required\")))\n\t\treturn nil, nil, errors.New(\"snapshot ID is required\")\n\t}\n\n\tsnapshotId := match[1]\n\n\tsnapshot, err := p.getSnapshot(ctx, snapshotId)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn nil, nil, fmt.Errorf(\"failed to get snapshot: %w\", err)\n\t}\n\n\tif snapshot.Ref == nil {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"snapshot has no snapshot reference\")))\n\t\treturn nil, nil, errors.New(\"snapshot has no snapshot reference\")\n\t}\n\n\tif snapshot.InitialRunnerId == nil {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"snapshot has no initial runner\")))\n\t\treturn nil, nil, errors.New(\"snapshot has no initial runner\")\n\t}\n\n\trunnerInfo, err := p.getRunnerInfo(ctx, *snapshot.InitialRunnerId)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn nil, nil, fmt.Errorf(\"failed to get runner info: %w\", err)\n\t}\n\n\tqueryParams := ctx.Request.URL.Query()\n\tqueryParams.Add(\"snapshotRef\", *snapshot.Ref)\n\n\t// Build the target URL\n\ttargetURL := fmt.Sprintf(\"%s/snapshots/logs\", runnerInfo.ApiUrl)\n\n\t// Create the complete target URL with path\n\ttarget, err := url.Parse(targetURL)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to parse target URL: %w\", err)))\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse target URL: %w\", err)\n\t}\n\ttarget.RawQuery = queryParams.Encode()\n\n\treturn target, map[string]string{\n\t\t\"X-Daytona-Authorization\": fmt.Sprintf(\"Bearer %s\", runnerInfo.ApiKey),\n\t\t\"X-Forwarded-Host\":        ctx.Request.Host,\n\t}, nil\n}\n\nfunc (p *Proxy) getSnapshot(ctx *gin.Context, snapshotId string) (*apiclient.SnapshotDto, error) {\n\tvar snapshot *apiclient.SnapshotDto\n\tbearerToken := p.getBearerToken(ctx)\n\tapiClient := p.getUserApiClient(ctx, bearerToken)\n\n\terr := utils.RetryWithExponentialBackoff(ctx, \"getSnapshot\", proxyMaxRetries, proxyBaseDelay, proxyMaxDelay, func() error {\n\t\ts, _, e := apiClient.SnapshotsAPI.GetSnapshot(ctx, snapshotId).Execute()\n\t\tsnapshot = s\n\t\topenapiErr := common_errors.ConvertOpenAPIError(e)\n\n\t\tif openapiErr != nil && !common_errors.IsRetryableOpenAPIError(openapiErr) {\n\t\t\treturn &utils.NonRetryableError{Err: openapiErr}\n\t\t}\n\n\t\treturn openapiErr\n\t})\n\treturn snapshot, err\n}\n\nfunc (p *Proxy) getRunnerInfo(ctx context.Context, runnerId string) (*RunnerInfo, error) {\n\trunnerInfo, err := p.runnerCache.Get(ctx, runnerId)\n\tif err == nil {\n\t\treturn runnerInfo, nil\n\t}\n\n\tvar runner *apiclient.RunnerFull\n\terr = utils.RetryWithExponentialBackoff(ctx, \"getRunnerInfo\", proxyMaxRetries, proxyBaseDelay, proxyMaxDelay, func() error {\n\t\tr, _, e := p.apiclient.RunnersAPI.GetRunnerFullById(context.Background(), runnerId).Execute()\n\t\trunner = r\n\t\topenapiErr := common_errors.ConvertOpenAPIError(e)\n\n\t\tif openapiErr != nil && !common_errors.IsRetryableOpenAPIError(openapiErr) {\n\t\t\treturn &utils.NonRetryableError{Err: openapiErr}\n\t\t}\n\n\t\treturn openapiErr\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif runner.ApiUrl == nil {\n\t\treturn nil, errors.New(\"runner API URL not found\")\n\t}\n\n\tinfo := RunnerInfo{\n\t\tApiUrl: *runner.ApiUrl,\n\t\tApiKey: runner.ApiKey,\n\t}\n\n\terr = p.runnerCache.Set(ctx, runnerId, info, 2*time.Minute)\n\tif err != nil {\n\t\tlog.Errorf(\"Failed to set runner info in cache: %v\", err)\n\t}\n\n\treturn &info, nil\n}\n"
  },
  {
    "path": "apps/proxy/pkg/proxy/proxy.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"maps\"\n\t\"net\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"slices\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/proxy/cmd/proxy/config\"\n\t\"github.com/daytonaio/proxy/internal\"\n\t\"github.com/gin-contrib/cors\"\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/gorilla/securecookie\"\n\n\tcommon_cache \"github.com/daytonaio/common-go/pkg/cache\"\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\tcommon_proxy \"github.com/daytonaio/common-go/pkg/proxy\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype RunnerInfo struct {\n\tApiUrl string `json:\"apiUrl\"`\n\tApiKey string `json:\"apiKey\"`\n}\n\nconst SANDBOX_AUTH_KEY_HEADER = \"X-Daytona-Preview-Token\"\nconst SANDBOX_AUTH_KEY_QUERY_PARAM = \"DAYTONA_SANDBOX_AUTH_KEY\"\nconst SANDBOX_AUTH_COOKIE_NAME = \"daytona-sandbox-auth-\"\nconst SKIP_LAST_ACTIVITY_UPDATE_HEADER = \"X-Daytona-Skip-Last-Activity-Update\"\nconst ACTIVITY_POLL_STOP_KEY = \"daytona-activity-poll-stop\"\nconst TERMINAL_PORT = \"22222\"\nconst TOOLBOX_PORT = \"2280\"\nconst RECORDING_DASHBOARD_PORT = \"33333\"\nconst IS_TOOLBOX_REQUEST_KEY = \"is-toolbox-request\"\n\n// stopActivityPoll retrieves and calls the activity poll stop function from the gin context.\n// This ensures the polling goroutine is stopped when the request (including WebSocket) finishes.\nfunc stopActivityPoll(ctx *gin.Context) {\n\tif stopFn, exists := ctx.Get(ACTIVITY_POLL_STOP_KEY); exists {\n\t\tif fn, ok := stopFn.(func()); ok {\n\t\t\tfn()\n\t\t}\n\t}\n}\n\ntype Proxy struct {\n\tconfig       *config.Config\n\tsecureCookie *securecookie.SecureCookie\n\tcookieDomain *string\n\n\tapiclient                      *apiclient.APIClient\n\trunnerCache                    common_cache.ICache[RunnerInfo]\n\tsandboxRunnerCache             common_cache.ICache[RunnerInfo]\n\tsandboxPublicCache             common_cache.ICache[bool]\n\tsandboxAuthKeyValidCache       common_cache.ICache[bool]\n\tsandboxLastActivityUpdateCache common_cache.ICache[bool]\n}\n\nfunc StartProxy(ctx context.Context, config *config.Config) error {\n\tproxy := &Proxy{\n\t\tconfig: config,\n\t}\n\n\tproxy.secureCookie = securecookie.New([]byte(config.ProxyApiKey), nil)\n\tif config.CookieDomain != nil {\n\t\tcookieDomain := GetCookieDomainFromHost(*config.CookieDomain)\n\t\tproxy.cookieDomain = &cookieDomain\n\t}\n\n\tproxy.apiclient = config.ApiClient\n\n\tif config.Redis != nil {\n\t\tvar err error\n\t\tproxy.sandboxRunnerCache, err = common_cache.NewRedisCache[RunnerInfo](config.Redis, \"proxy:sandbox-runner-info:\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tproxy.runnerCache, err = common_cache.NewRedisCache[RunnerInfo](config.Redis, \"proxy:runner-info:\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tproxy.sandboxPublicCache, err = common_cache.NewRedisCache[bool](config.Redis, \"proxy:sandbox-public:\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tproxy.sandboxAuthKeyValidCache, err = common_cache.NewRedisCache[bool](config.Redis, \"proxy:sandbox-auth-key-valid:\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tproxy.sandboxLastActivityUpdateCache, err = common_cache.NewRedisCache[bool](config.Redis, \"proxy:sandbox-last-activity-update:\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tproxy.sandboxRunnerCache = common_cache.NewMapCache[RunnerInfo](ctx)\n\t\tproxy.runnerCache = common_cache.NewMapCache[RunnerInfo](ctx)\n\t\tproxy.sandboxPublicCache = common_cache.NewMapCache[bool](ctx)\n\t\tproxy.sandboxAuthKeyValidCache = common_cache.NewMapCache[bool](ctx)\n\t\tproxy.sandboxLastActivityUpdateCache = common_cache.NewMapCache[bool](ctx)\n\t}\n\n\tshutdownWg := &sync.WaitGroup{}\n\n\trouter := gin.New()\n\trouter.Use(func(ctx *gin.Context) {\n\t\tshutdownWg.Add(1)\n\n\t\tcleanupOnce := sync.Once{}\n\t\tcleanup := func() {\n\t\t\tcleanupOnce.Do(func() {\n\t\t\t\tstopActivityPoll(ctx)\n\t\t\t\tshutdownWg.Done()\n\t\t\t})\n\t\t}\n\n\t\t// Wrap the response writer to monitor connection\n\t\tmonitor := &common_proxy.ConnectionMonitor{\n\t\t\tResponseWriter: ctx.Writer,\n\t\t\tOnConnClosed:   cleanup,\n\t\t}\n\t\tctx.Writer = monitor\n\n\t\t// For non-WebSocket connections, cleanup on defer\n\t\tdefer cleanup()\n\n\t\tcommon_errors.Recovery()(ctx)\n\t})\n\n\trouter.Use(common_errors.NewErrorMiddleware(func(ctx *gin.Context, err error) common_errors.ErrorResponse {\n\t\treturn common_errors.ErrorResponse{\n\t\t\tStatusCode: http.StatusInternalServerError,\n\t\t\tMessage:    err.Error(),\n\t\t}\n\t}))\n\n\trouter.Use(func(ctx *gin.Context) {\n\t\tif ctx.Request.Header.Get(\"X-Daytona-Disable-CORS\") == \"true\" {\n\t\t\tctx.Request.Header.Del(\"X-Daytona-Disable-CORS\")\n\t\t\treturn\n\t\t}\n\n\t\tcorsConfig := cors.DefaultConfig()\n\t\tcorsConfig.AllowOriginFunc = func(origin string) bool {\n\t\t\treturn true\n\t\t}\n\t\tcorsConfig.AllowCredentials = true\n\t\tcorsConfig.AllowHeaders = slices.Collect(maps.Keys(ctx.Request.Header))\n\t\tcorsConfig.AllowHeaders = append(corsConfig.AllowHeaders, ctx.Request.Header.Values(\"Access-Control-Request-Headers\")...)\n\n\t\tcors.New(corsConfig)(ctx)\n\t})\n\n\tif config.PreviewWarningEnabled {\n\t\trouter.Use(proxy.browserWarningMiddleware())\n\t}\n\n\trouter.Any(\"/*path\", func(ctx *gin.Context) {\n\t\tif ctx.Request.Method == \"POST\" && ctx.Request.URL.Path == ACCEPT_PREVIEW_PAGE_WARNING_PATH {\n\t\t\thandleAcceptProxyWarning(ctx, config.ProxyProtocol == \"https\")\n\t\t\treturn\n\t\t}\n\n\t\ttargetPort, _, _, err := proxy.parseHost(ctx.Request.Host)\n\t\t// if the host is not valid, we don't proxy the request\n\t\tif err != nil {\n\t\t\tswitch ctx.Request.Method {\n\t\t\tcase \"GET\":\n\t\t\t\t{\n\t\t\t\t\tswitch ctx.Request.URL.Path {\n\t\t\t\t\tcase \"/callback\":\n\t\t\t\t\t\tproxy.AuthCallback(ctx)\n\t\t\t\t\t\treturn\n\t\t\t\t\tcase \"/health\":\n\t\t\t\t\t\tctx.JSON(http.StatusOK, gin.H{\"status\": \"ok\", \"version\": internal.Version})\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tif regexp.MustCompile(`^/snapshots/[\\w-]+/build-logs$`).MatchString(ctx.Request.URL.Path) {\n\t\t\t\t\t\tcommon_proxy.NewProxyRequestHandler(proxy.getSnapshotTarget, nil)(ctx)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tif regexp.MustCompile(`^/sandboxes/[\\w-]+/build-logs$`).MatchString(ctx.Request.URL.Path) {\n\t\t\t\t\t\tcommon_proxy.NewProxyRequestHandler(proxy.getSandboxBuildTarget, nil)(ctx)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(ctx.Request.URL.Path, \"/toolbox/\") {\n\t\t\t\tctx.Set(IS_TOOLBOX_REQUEST_KEY, true)\n\t\t\t\t_, sandboxID, _, err := proxy.parseToolboxSubpath(ctx.Request.URL.Path)\n\t\t\t\tif err != nil {\n\t\t\t\t\tctx.Error(common_errors.NewNotFoundError(errors.New(\"not found\")))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tprefix := fmt.Sprintf(\"/toolbox/%s\", sandboxID)\n\n\t\t\t\tmodifyResponse := func(res *http.Response) error {\n\t\t\t\t\tif res.StatusCode >= 300 && res.StatusCode < 400 {\n\t\t\t\t\t\tif loc := res.Header.Get(\"Location\"); !strings.HasPrefix(loc, prefix) {\n\t\t\t\t\t\t\tres.Header.Set(\"Location\", prefix+loc)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tcommon_proxy.NewProxyRequestHandler(proxy.GetProxyTarget, modifyResponse)(ctx)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tctx.Error(common_errors.NewNotFoundError(errors.New(\"not found\")))\n\t\t\treturn\n\t\t}\n\n\t\t// If toolbox only mode is enabled, only allow requests to the toolbox port\n\t\tif targetPort != TOOLBOX_PORT && proxy.config.ToolboxOnlyMode {\n\t\t\tctx.Error(common_errors.NewNotFoundError(errors.New(\"not found\")))\n\t\t\treturn\n\t\t}\n\n\t\tcommon_proxy.NewProxyRequestHandler(proxy.GetProxyTarget, nil)(ctx)\n\t})\n\n\thttpServer := &http.Server{\n\t\tAddr:    fmt.Sprintf(\":%d\", config.ProxyPort),\n\t\tHandler: router,\n\t}\n\n\tlistener, err := net.Listen(\"tcp\", httpServer.Addr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlog.Infof(\"Proxy server is running on port %d\", config.ProxyPort)\n\n\tserveErr := make(chan error, 1)\n\tgo func() {\n\t\tif config.EnableTLS {\n\t\t\tserveErr <- httpServer.ServeTLS(listener, config.TLSCertFile, config.TLSKeyFile)\n\t\t} else {\n\t\t\tserveErr <- httpServer.Serve(listener)\n\t\t}\n\t}()\n\n\tselect {\n\tcase err := <-serveErr:\n\t\treturn err\n\tcase <-ctx.Done():\n\t\terrChan := make(chan error, 1)\n\t\tshutdownCtx, cancel := context.WithTimeout(context.Background(), time.Duration(config.ShutdownTimeoutSec)*time.Second)\n\t\tdefer cancel()\n\n\t\tgo func() {\n\t\t\terr := httpServer.Shutdown(shutdownCtx)\n\t\t\tif err != nil {\n\t\t\t\terrChan <- err\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\twgChan := make(chan struct{})\n\n\t\t\tgo func() {\n\t\t\t\tlog.Info(\"Waiting for active requests to finish...\")\n\t\t\t\tshutdownWg.Wait()\n\t\t\t\tlog.Info(\"All active requests finished, shutting down proxy\")\n\t\t\t\tclose(wgChan)\n\t\t\t}()\n\n\t\t\tselect {\n\t\t\tcase <-shutdownCtx.Done():\n\t\t\t\terrChan <- fmt.Errorf(\"shutdown timeout reached, forcing exit\")\n\t\t\tcase <-wgChan:\n\t\t\t\terrChan <- nil\n\t\t\t}\n\n\t\t\terrChan <- nil\n\t\t}()\n\n\t\treturn <-errChan\n\t}\n}\n"
  },
  {
    "path": "apps/proxy/pkg/proxy/retry.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport \"time\"\n\nconst (\n\tproxyMaxRetries = 3\n\tproxyBaseDelay  = 150 * time.Millisecond\n\tproxyMaxDelay   = 1 * time.Second\n)\n"
  },
  {
    "path": "apps/proxy/pkg/proxy/warning_page.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage proxy\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/mssola/useragent\"\n)\n\nconst (\n\tSKIP_PREVIEW_WARNING_HEADER      = \"X-Daytona-Skip-Preview-Warning\"\n\tPREVIEW_PAGE_ACCEPT_COOKIE_NAME  = \"daytona-preview-page-accepted\"\n\tPREVIEW_PAGE_COOKIE_MAX_AGE      = 1 * 24 * 60 * 60 // 1 day in seconds\n\tACCEPT_PREVIEW_PAGE_WARNING_PATH = \"/accept-daytona-preview-warning\"\n)\n\nfunc handleAcceptProxyWarning(ctx *gin.Context, secure bool) {\n\t// Set SameSite attribute based on security context\n\tif secure {\n\t\t// For HTTPS, use SameSite=None to allow cross-origin iframe usage\n\t\tctx.SetSameSite(http.SameSiteNoneMode)\n\t} else {\n\t\t// For HTTP (local dev), use SameSite=Lax\n\t\tctx.SetSameSite(http.SameSiteLaxMode)\n\t}\n\n\t// Set the acceptance cookie\n\tctx.SetCookie(\n\t\tPREVIEW_PAGE_ACCEPT_COOKIE_NAME,\n\t\t\"true\",\n\t\tPREVIEW_PAGE_COOKIE_MAX_AGE,\n\t\t\"/\",\n\t\tstrings.Split(ctx.Request.Host, \":\")[0],\n\t\tsecure,\n\t\ttrue,\n\t)\n\n\t// Redirect to the original URL or root\n\tredirectURL := ctx.Query(\"redirect\")\n\tif redirectURL == \"\" {\n\t\tredirectURL = \"/\"\n\t}\n\n\tctx.Redirect(http.StatusFound, redirectURL)\n}\n\n// browserWarningMiddleware is the middleware that checks for browsers and shows warning\nfunc (p *Proxy) browserWarningMiddleware() gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tif ctx.Request.Header.Get(SKIP_PREVIEW_WARNING_HEADER) == \"true\" {\n\t\t\tctx.Next()\n\t\t\treturn\n\t\t}\n\n\t\tuserAgent := ctx.Request.UserAgent()\n\n\t\t// Skip warning for non-browser requests\n\t\tif !isBrowser(userAgent) {\n\t\t\tctx.Next()\n\t\t\treturn\n\t\t}\n\n\t\t// Skip warning for WebSocket requests\n\t\tif isWebSocketRequest(ctx.Request) {\n\t\t\tctx.Next()\n\t\t\treturn\n\t\t}\n\n\t\t// Skip warning if user has already accepted\n\t\tif hasAcceptedWarning(ctx) {\n\t\t\tctx.Next()\n\t\t\treturn\n\t\t}\n\n\t\t// Skip warning for the acceptance endpoint itself or auth callbacks\n\t\ttargetPort, _, _, err := p.parseHost(ctx.Request.Host)\n\t\tif err != nil {\n\t\t\tswitch ctx.Request.Method {\n\t\t\tcase \"GET\":\n\t\t\t\tswitch ctx.Request.URL.Path {\n\t\t\t\tcase \"/callback\", \"/health\":\n\t\t\t\t\tctx.Next()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ctx.Request.URL.Path == ACCEPT_PREVIEW_PAGE_WARNING_PATH || targetPort == TERMINAL_PORT || targetPort == TOOLBOX_PORT || targetPort == RECORDING_DASHBOARD_PORT {\n\t\t\tctx.Next()\n\t\t\treturn\n\t\t}\n\n\t\t// Serve the warning page\n\t\tserveWarningPage(ctx, p.config.EnableTLS)\n\t\tctx.Abort() // Stop further processing\n\t}\n}\n\n// serveWarningPage serves the static HTML warning page\nfunc serveWarningPage(c *gin.Context, https bool) {\n\thtmlContent := `<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>Daytona Preview - Warning</title>\n    <style>\n      * {\n        margin: 0;\n        padding: 0;\n        box-sizing: border-box;\n      }\n\n      body {\n        font-family:\n          -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;\n        background: #0a0a0a;\n        color: #ffffff;\n        min-height: 100vh;\n        display: flex;\n        flex-direction: column;\n      }\n\n      .header {\n        padding: 1rem 2rem;\n        border-bottom: 1px solid #1a1a1a;\n        background: #000;\n      }\n\n      .logo {\n        display: flex;\n        align-items: center;\n        font-size: 1.5rem;\n        font-weight: 600;\n        color: #fff;\n      }\n\n      .logo::before {\n        content: '⚡';\n        margin-right: 0.5rem;\n        font-size: 1.8rem;\n      }\n\n      .container {\n        flex: 1;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        padding: 2rem;\n      }\n\n      .warning-card {\n        background: #1a1a1a;\n        border: 1px solid #333;\n        border-radius: 12px;\n        padding: 3rem 2.5rem;\n        max-width: 600px;\n\n        text-align: center;\n        box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);\n      }\n\n      .warning-icon {\n        font-size: 4rem;\n        margin-bottom: 1.5rem;\n        color: #ffa500;\n      }\n\n      .warning-title {\n        font-size: 2rem;\n        font-weight: 700;\n        margin-bottom: 1rem;\n        color: #fff;\n      }\n\n      .warning-subtitle {\n        font-size: 1.1rem;\n\n        margin-bottom: 2rem;\n        line-height: 1.5;\n      }\n\n      .warning-text {\n        font-size: 0.95rem;\n        color: #ccc;\n        line-height: 1.6;\n        margin-bottom: 2.5rem;\n        text-align: left;\n        background: #0f0f0f;\n        padding: 1.5rem;\n        border-radius: 8px;\n        border: 1px solid #2a2a2a;\n      }\n\n      .warning-text strong {\n        color: #ffa500;\n      }\n\n      .button-container {\n        display: flex;\n        gap: 1rem;\n        justify-content: center;\n        flex-wrap: wrap;\n      }\n\n      .btn {\n        padding: 0.875rem 2rem;\n        border: none;\n        border-radius: 8px;\n        font-size: 1rem;\n        font-weight: 600;\n        cursor: pointer;\n        transition: all 0.2s ease;\n        text-decoration: none;\n        display: inline-flex;\n        align-items: center;\n        gap: 0.5rem;\n        min-width: 160px;\n        justify-content: center;\n      }\n\n      .btn-primary {\n        background: #0066ff;\n        color: white;\n      }\n\n      .footer {\n        padding: 1rem 2rem;\n        text-align: center;\n        font-size: 0.85rem;\n        color: #666;\n        border-top: 1px solid #1a1a1a;\n      }\n\n      a {\n        color: #ffffff;\n      }\n\n      @media (max-width: 768px) {\n        .container {\n          padding: 1rem;\n        }\n\n        .warning-card {\n          padding: 2rem 1.5rem;\n        }\n\n        .warning-title {\n          font-size: 1.5rem;\n        }\n\n        .button-container {\n          flex-direction: column;\n        }\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"container\">\n      <div class=\"warning-card\">\n        <div class=\"warning-icon\">⚠️</div>\n        <h1 class=\"warning-title\">Preview URL Warning</h1>\n        <p class=\"warning-subtitle\">You are about to visit <strong>%s</strong></p>\n\n        <div class=\"warning-text\">\n          • This website is served through <a href=\"https://daytona.io\" target=\"_blank\">daytona.io</a><br />\n          • Content and functionality may change without notice<br />\n          • You should only visit this website if you trust whoever sent the link to<br />\n          • Be careful about disclosing personal or financial information like passwords, phone numbers, or credit cards<br />\n          • To get rid of this warning for your organization, visit our docs: <a href=\"https://daytona.io/docs/en/preview-and-authentication\" target=\"_blank\">https://daytona.io/docs/en/preview-and-authentication</a>\n        </div>\n\n        <form action=\"%s\" method=\"POST\" style=\"margin: 0\">\n          <div class=\"button-container\">\n            <button type=\"submit\" class=\"btn btn-primary\">I Understand, Continue</button>\n          </div>\n        </form>\n      </div>\n    </div>\n\n    <div class=\"footer\">Powered by Daytona - Secure and Elastic Infrastructure for AI-Generated Code</div>\n  </body>\n</html>`\n\n\tprotocol := \"http://\"\n\tif https {\n\t\tprotocol = \"https://\"\n\t}\n\n\tredirectPath := protocol + c.Request.Host + c.Request.URL.String()\n\tredirectUrl := ACCEPT_PREVIEW_PAGE_WARNING_PATH + \"?redirect=\" + url.QueryEscape(redirectPath)\n\n\tc.Header(\"Content-Type\", \"text/html; charset=utf-8\")\n\tc.String(http.StatusOK, fmt.Sprintf(htmlContent, redirectPath, redirectUrl))\n}\n\n// isBrowser checks if the request is coming from a web browser\nfunc isBrowser(userAgent string) bool {\n\tua := useragent.New(userAgent)\n\n\tbrowser, _ := ua.Browser()\n\tbrowser = strings.ToLower(browser)\n\n\tbrowsers := []string{\"chrome\", \"firefox\", \"safari\", \"edge\", \"brave\", \"vivaldi\", \"samsung\", \"opera\"}\n\n\treturn slices.Contains(browsers, browser)\n}\n\n// hasAcceptedWarning checks if the user has already accepted the warning\nfunc hasAcceptedWarning(c *gin.Context) bool {\n\tcookie, err := c.Cookie(PREVIEW_PAGE_ACCEPT_COOKIE_NAME)\n\treturn err == nil && cookie == \"true\"\n}\n\n// isWebSocketRequest checks if the request is a WebSocket upgrade request\nfunc isWebSocketRequest(req *http.Request) bool {\n\tconnection := strings.ToLower(req.Header.Get(\"Connection\"))\n\tupgrade := strings.ToLower(req.Header.Get(\"Upgrade\"))\n\n\treturn upgrade == \"websocket\" && connection == \"upgrade\"\n}\n"
  },
  {
    "path": "apps/proxy/project.json",
    "content": "{\n  \"name\": \"proxy\",\n  \"$schema\": \"../../runner_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"application\",\n  \"sourceRoot\": \"apps/proxy\",\n  \"tags\": [],\n  \"targets\": {\n    \"build\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"options\": {\n        \"main\": \"{projectRoot}/cmd/proxy/main.go\",\n        \"outputPath\": \"dist/apps/proxy\"\n      },\n      \"configurations\": {\n        \"production\": {\n          \"flags\": [\"-ldflags \\\"-X 'github.com/daytonaio/proxy/internal.Version=$VERSION'\\\"\"]\n        }\n      },\n      \"inputs\": [\"goProduction\", \"^goProduction\", { \"env\": \"VERSION\" }]\n    },\n    \"serve\": {\n      \"executor\": \"@nx-go/nx-go:serve\",\n      \"options\": {\n        \"cmd\": \"gow\",\n        \"cwd\": \".\",\n        \"main\": \"{projectRoot}/cmd/proxy/main.go\"\n      },\n      \"configurations\": {\n        \"production\": {}\n      }\n    },\n    \"format\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cd {projectRoot} && go fmt ./...\"\n      }\n    },\n    \"test\": {\n      \"executor\": \"@nx-go/nx-go:test\"\n    },\n    \"lint\": {\n      \"executor\": \"@nx-go/nx-go:lint\"\n    },\n    \"check-version-env\": {},\n    \"docker\": {\n      \"options\": {\n        \"target\": \"proxy\"\n      }\n    },\n    \"push-manifest\": {}\n  }\n}\n"
  },
  {
    "path": "apps/runner/.gitignore",
    "content": "pkg/daemon/static/*\n!*.gitkeep\n"
  },
  {
    "path": "apps/runner/Dockerfile",
    "content": "FROM node:22-alpine AS build\n\nENV CI=true\n\nRUN npm install -g corepack && corepack enable\n\nCOPY --from=golang:1.25.4-alpine /usr/local/go/ /usr/local/go/\n\nENV PATH=\"/usr/local/go/bin:${PATH}\"\n\nRUN apk add --no-cache git\n\nWORKDIR /daytona\n\n# Yarn caching layer\nCOPY package.json yarn.lock .yarnrc.yml ./\nRUN yarn install --immutable\n\n# Nx config\nCOPY nx.json ./\n\n# Go dependency layer (cached unless go.mod/go.sum change)\nCOPY go.work go.work.sum ./\nCOPY apps/runner/go.mod apps/runner/go.sum apps/runner/\nCOPY apps/daemon/go.mod apps/daemon/go.sum apps/daemon/\nCOPY libs/common-go/go.mod libs/common-go/go.sum libs/common-go/\nCOPY libs/api-client-go/go.mod libs/api-client-go/go.sum libs/api-client-go/\nRUN head -1 go.work > go.work.tmp && printf '\\nuse (\\n\\t./apps/runner\\n\\t./apps/daemon\\n\\t./libs/common-go\\n\\t./libs/api-client-go\\n)\\n' >> go.work.tmp && mv go.work.tmp go.work\n\nENV NX_DAEMON=false\nENV GONOSUMDB=github.com/daytonaio/daytona\n\nRUN go -C apps/runner mod download \\\n  && go -C apps/daemon mod download \\\n  && go -C libs/common-go mod download \\\n  && go -C libs/api-client-go mod download\n\n# Go source\nCOPY apps/runner/ apps/runner/\nCOPY apps/daemon/ apps/daemon/\nCOPY libs/common-go/ libs/common-go/\nCOPY libs/api-client-go/ libs/api-client-go/\nCOPY libs/computer-use/ libs/computer-use/\n\n# Pre-built computer-use binary and build script\nCOPY dist/libs/computer-use-amd64 dist/libs/computer-use-amd64\n\nARG VERSION=0.0.1\nRUN --mount=type=cache,target=/root/.cache/go-build \\\n  SKIP_COMPUTER_USE_BUILD=true VERSION=$VERSION yarn nx build runner --configuration=production --nxBail=true\n\nFROM docker:28.2.2-dind-alpine3.22 AS runner\n\nRUN apk add --no-cache curl rsync\n\nWORKDIR /usr/local/bin\n\nCOPY --from=build /daytona/dist/apps/runner daytona-runner\n\nRUN chmod +x daytona-runner\n\nRUN mkdir -p /etc/docker && echo '{\"insecure-registries\": [\"registry:6000\"]}' > /etc/docker/daemon.json\n\nHEALTHCHECK CMD [ \"curl\", \"-f\", \"http://localhost:3003/\" ]\n\nENTRYPOINT [\"sh\", \"-c\", \"/usr/local/bin/dockerd-entrypoint.sh & daytona-runner\"]\n"
  },
  {
    "path": "apps/runner/cmd/runner/config/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage config\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/go-playground/validator/v10\"\n\t\"github.com/kelseyhightower/envconfig\"\n\t\"github.com/vishvananda/netlink\"\n)\n\ntype Config struct {\n\tDaytonaApiUrl                      string        `envconfig:\"DAYTONA_API_URL\"`\n\tApiToken                           string        `envconfig:\"DAYTONA_RUNNER_TOKEN\"`\n\tApiPort                            int           `envconfig:\"API_PORT\"`\n\tApiLogRequests                     bool          `envconfig:\"API_LOG_REQUESTS\" default:\"false\"`\n\tTLSCertFile                        string        `envconfig:\"TLS_CERT_FILE\"`\n\tTLSKeyFile                         string        `envconfig:\"TLS_KEY_FILE\"`\n\tEnableTLS                          bool          `envconfig:\"ENABLE_TLS\"`\n\tOtelLoggingEnabled                 bool          `envconfig:\"OTEL_LOGGING_ENABLED\"`\n\tOtelTracingEnabled                 bool          `envconfig:\"OTEL_TRACING_ENABLED\"`\n\tOtelEndpoint                       string        `envconfig:\"OTEL_EXPORTER_OTLP_ENDPOINT\"`\n\tOtelHeaders                        string        `envconfig:\"OTEL_EXPORTER_OTLP_HEADERS\"`\n\tBackupInfoCacheRetention           time.Duration `envconfig:\"BACKUP_INFO_CACHE_RETENTION\" default:\"168h\" validate:\"min=5m\"`\n\tEnvironment                        string        `envconfig:\"ENVIRONMENT\"`\n\tContainerRuntime                   string        `envconfig:\"CONTAINER_RUNTIME\"`\n\tContainerNetwork                   string        `envconfig:\"CONTAINER_NETWORK\"`\n\tLogFilePath                        string        `envconfig:\"LOG_FILE_PATH\"`\n\tAWSRegion                          string        `envconfig:\"AWS_REGION\"`\n\tAWSEndpointUrl                     string        `envconfig:\"AWS_ENDPOINT_URL\"`\n\tAWSAccessKeyId                     string        `envconfig:\"AWS_ACCESS_KEY_ID\"`\n\tAWSSecretAccessKey                 string        `envconfig:\"AWS_SECRET_ACCESS_KEY\"`\n\tAWSDefaultBucket                   string        `envconfig:\"AWS_DEFAULT_BUCKET\"`\n\tResourceLimitsDisabled             bool          `envconfig:\"RESOURCE_LIMITS_DISABLED\"`\n\tDaemonStartTimeoutSec              int           `envconfig:\"DAEMON_START_TIMEOUT_SEC\"`\n\tSandboxStartTimeoutSec             int           `envconfig:\"SANDBOX_START_TIMEOUT_SEC\"`\n\tUseSnapshotEntrypoint              bool          `envconfig:\"USE_SNAPSHOT_ENTRYPOINT\"`\n\tDomain                             string        `envconfig:\"RUNNER_DOMAIN\" validate:\"omitempty,hostname|ip\"`\n\tVolumeCleanupInterval              time.Duration `envconfig:\"VOLUME_CLEANUP_INTERVAL\" default:\"30s\" validate:\"min=10s\"`\n\tVolumeCleanupDryRun                bool          `envconfig:\"VOLUME_CLEANUP_DRY_RUN\" default:\"true\"`\n\tVolumeCleanupExclusionPeriod       time.Duration `envconfig:\"VOLUME_CLEANUP_EXCLUSION_PERIOD\" default:\"120s\" validate:\"min=0s\"`\n\tPollTimeout                        time.Duration `envconfig:\"POLL_TIMEOUT\" default:\"30s\"`\n\tPollLimit                          int           `envconfig:\"POLL_LIMIT\" default:\"10\" validate:\"min=1,max=100\"`\n\tCollectorWindowSize                int           `envconfig:\"COLLECTOR_WINDOW_SIZE\" default:\"60\" validate:\"min=1\"`\n\tCPUUsageSnapshotInterval           time.Duration `envconfig:\"CPU_USAGE_SNAPSHOT_INTERVAL\" default:\"5s\" validate:\"min=1s\"`\n\tAllocatedResourcesSnapshotInterval time.Duration `envconfig:\"ALLOCATED_RESOURCES_SNAPSHOT_INTERVAL\" default:\"5s\" validate:\"min=1s\"`\n\tHealthcheckInterval                time.Duration `envconfig:\"HEALTHCHECK_INTERVAL\" default:\"30s\" validate:\"min=10s\"`\n\tHealthcheckTimeout                 time.Duration `envconfig:\"HEALTHCHECK_TIMEOUT\" default:\"10s\"`\n\tBackupTimeoutMin                   int           `envconfig:\"BACKUP_TIMEOUT_MIN\" default:\"60\" validate:\"min=1\"`\n\tApiVersion                         int           `envconfig:\"API_VERSION\" default:\"2\"`\n\tInitializeDaemonTelemetry          bool          `envconfig:\"INITIALIZE_DAEMON_TELEMETRY\" default:\"true\"`\n\tSnapshotErrorCacheRetention        time.Duration `envconfig:\"SNAPSHOT_ERROR_CACHE_RETENTION\" default:\"10m\" validate:\"min=5m\"`\n}\n\nvar DEFAULT_API_PORT int = 8080\n\nvar config *Config\n\nfunc GetConfig() (*Config, error) {\n\tif config != nil {\n\t\treturn config, nil\n\t}\n\n\tconfig = &Config{}\n\n\terr := envconfig.Process(\"\", config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar validate = validator.New()\n\terr = validate.Struct(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif config.DaytonaApiUrl == \"\" {\n\t\t// For backward compatibility\n\t\tserverUrl := os.Getenv(\"SERVER_URL\")\n\t\tif serverUrl == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"DAYTONA_API_URL or SERVER_URL is required\")\n\t\t}\n\t\tconfig.DaytonaApiUrl = serverUrl\n\t}\n\n\tif config.ApiToken == \"\" {\n\t\t// For backward compatibility\n\t\tapiToken := os.Getenv(\"API_TOKEN\")\n\t\tif apiToken == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"DAYTONA_RUNNER_TOKEN or API_TOKEN is required\")\n\t\t}\n\t\tconfig.ApiToken = apiToken\n\t}\n\n\tif config.ApiPort == 0 {\n\t\tconfig.ApiPort = DEFAULT_API_PORT\n\t}\n\n\tif config.Domain == \"\" {\n\t\tip, err := getOutboundIP()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfig.Domain = ip.String()\n\t}\n\n\treturn config, nil\n}\n\nfunc (c *Config) GetOtelHeaders() map[string]string {\n\theaders := map[string]string{}\n\tfor _, pair := range strings.Split(c.OtelHeaders, \",\") {\n\t\tpair = strings.TrimSpace(pair)\n\t\tif pair == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tk, v, found := strings.Cut(pair, \"=\")\n\t\tif !found {\n\t\t\tcontinue\n\t\t}\n\n\t\theaders[strings.TrimSpace(k)] = strings.TrimSpace(v)\n\t}\n\n\treturn headers\n}\n\nfunc GetContainerRuntime() string {\n\treturn config.ContainerRuntime\n}\n\nfunc GetContainerNetwork() string {\n\treturn config.ContainerNetwork\n}\n\nfunc GetEnvironment() string {\n\treturn config.Environment\n}\n\nfunc GetBuildLogFilePath(snapshotRef string) (string, error) {\n\t// Extract image name from various snapshot ref formats:\n\t// - registry:5000/daytona/daytona-<hash>\n\t// - daytona-<hash>\n\t// - daytona-<hash>:tag\n\t// - cr.preprod.daytona.io/sbox/daytona/daytona-<hash>:daytona\n\n\tbuildId := snapshotRef\n\n\t// Remove tag if present (everything after last colon that's not part of a port)\n\t// A tag colon will come after the last slash\n\tlastSlashIndex := strings.LastIndex(buildId, \"/\")\n\tlastColonIndex := strings.LastIndex(buildId, \":\")\n\n\tif lastColonIndex > lastSlashIndex && lastColonIndex != -1 {\n\t\t// This colon is a tag separator, not a port separator\n\t\tbuildId = buildId[:lastColonIndex]\n\t}\n\n\t// Extract the image name (last component after the last slash)\n\tif lastSlashIndex := strings.LastIndex(buildId, \"/\"); lastSlashIndex != -1 {\n\t\tbuildId = buildId[lastSlashIndex+1:]\n\t}\n\n\tc, err := GetConfig()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tlogPath := filepath.Join(filepath.Dir(c.LogFilePath), \"builds\", buildId)\n\n\tif err := os.MkdirAll(filepath.Dir(logPath), 0755); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create log directory: %w\", err)\n\t}\n\n\tif _, err := os.OpenFile(logPath, os.O_CREATE, 0644); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create log file: %w\", err)\n\t}\n\n\treturn logPath, nil\n}\n\n// getOutboundIP returns the IP address of the default route's network interface\nfunc getOutboundIP() (net.IP, error) {\n\troutes, err := netlink.RouteList(nil, netlink.FAMILY_V4)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list routes: %w\", err)\n\t}\n\n\t// Find the default route (destination 0.0.0.0/0)\n\tfor _, route := range routes {\n\t\tif route.Dst == nil || route.Dst.IP.Equal(net.IPv4zero) {\n\t\t\t// Get the link (interface) for this route\n\t\t\tlink, err := netlink.LinkByIndex(route.LinkIndex)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to get link: %w\", err)\n\t\t\t}\n\n\t\t\t// Get addresses for this interface\n\t\t\taddrs, err := netlink.AddrList(link, netlink.FAMILY_V4)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to get addresses: %w\", err)\n\t\t\t}\n\n\t\t\tif len(addrs) > 0 {\n\t\t\t\treturn addrs[0].IP, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"no default route found\")\n}\n"
  },
  {
    "path": "apps/runner/cmd/runner/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\t\"github.com/daytonaio/common-go/pkg/telemetry\"\n\t\"github.com/daytonaio/runner/cmd/runner/config\"\n\t\"github.com/daytonaio/runner/internal\"\n\t\"github.com/daytonaio/runner/internal/metrics\"\n\t\"github.com/daytonaio/runner/pkg/api\"\n\t\"github.com/daytonaio/runner/pkg/cache\"\n\t\"github.com/daytonaio/runner/pkg/daemon\"\n\t\"github.com/daytonaio/runner/pkg/docker\"\n\t\"github.com/daytonaio/runner/pkg/netrules\"\n\t\"github.com/daytonaio/runner/pkg/runner\"\n\t\"github.com/daytonaio/runner/pkg/runner/v2/executor\"\n\t\"github.com/daytonaio/runner/pkg/runner/v2/healthcheck\"\n\t\"github.com/daytonaio/runner/pkg/runner/v2/poller\"\n\t\"github.com/daytonaio/runner/pkg/services\"\n\t\"github.com/daytonaio/runner/pkg/sshgateway\"\n\t\"github.com/daytonaio/runner/pkg/telemetry/filters\"\n\t\"github.com/docker/docker/client\"\n\t\"github.com/lmittmann/tint\"\n\t\"github.com/mattn/go-isatty\"\n\t\"go.opentelemetry.io/otel\"\n)\n\nfunc main() {\n\tos.Exit(run())\n}\n\nfunc run() int {\n\t// Init slog logger\n\tlogger := slog.New(tint.NewHandler(os.Stdout, &tint.Options{\n\t\tNoColor:    !isatty.IsTerminal(os.Stdout.Fd()),\n\t\tTimeFormat: time.RFC3339,\n\t\tLevel:      log.ParseLogLevel(os.Getenv(\"LOG_LEVEL\")),\n\t}))\n\n\tslog.SetDefault(logger)\n\n\tcfg, err := config.GetConfig()\n\tif err != nil {\n\t\tlogger.Error(\"Failed to get config\", \"error\", err)\n\t\treturn 2\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\tif cfg.OtelLoggingEnabled && cfg.OtelEndpoint != \"\" {\n\t\tlogger.Info(\"OpenTelemetry logging is enabled\")\n\n\t\ttelemetryConfig := telemetry.Config{\n\t\t\tEndpoint:       cfg.OtelEndpoint,\n\t\t\tHeaders:        cfg.GetOtelHeaders(),\n\t\t\tServiceName:    \"daytona-runner\",\n\t\t\tServiceVersion: internal.Version,\n\t\t\tEnvironment:    cfg.Environment,\n\t\t}\n\n\t\t// Initialize OpenTelemetry logging\n\t\tnewLogger, lp, err := telemetry.InitLogger(ctx, logger, telemetryConfig)\n\t\tif err != nil {\n\t\t\tlogger.ErrorContext(ctx, \"Failed to initialize logger\", \"error\", err)\n\t\t\treturn 2\n\t\t}\n\n\t\t// Reassign logger to the new OTEL-enabled logger returned by InitLogger.\n\t\t// This ensures that all subsequent code uses the logger instance that has OTEL support.\n\t\tlogger = newLogger\n\n\t\tdefer telemetry.ShutdownLogger(logger, lp)\n\t}\n\n\tif cfg.OtelTracingEnabled && cfg.OtelEndpoint != \"\" {\n\t\tlogger.Info(\"OpenTelemetry tracing is enabled\")\n\n\t\ttelemetryConfig := telemetry.Config{\n\t\t\tEndpoint:       cfg.OtelEndpoint,\n\t\t\tHeaders:        cfg.GetOtelHeaders(),\n\t\t\tServiceName:    \"daytona-runner\",\n\t\t\tServiceVersion: internal.Version,\n\t\t\tEnvironment:    cfg.Environment,\n\t\t}\n\n\t\t// Initialize OpenTelemetry tracing with a custom filter to ignore 404 errors\n\t\ttp, err := telemetry.InitTracer(ctx, telemetryConfig, &filters.NotFoundExporterFilter{})\n\t\tif err != nil {\n\t\t\tlogger.ErrorContext(ctx, \"Failed to initialize tracer\", \"error\", err)\n\t\t\treturn 2\n\t\t}\n\t\tdefer telemetry.ShutdownTracer(logger, tp)\n\t}\n\n\tcli, err := client.NewClientWithOpts(\n\t\tclient.FromEnv,\n\t\tclient.WithAPIVersionNegotiation(),\n\t\tclient.WithTraceProvider(otel.GetTracerProvider()),\n\t)\n\tif err != nil {\n\t\tlogger.Error(\"Error creating Docker client\", \"error\", err)\n\t\treturn 2\n\t}\n\n\t// Initialize net rules manager\n\tpersistent := cfg.Environment != \"development\"\n\tnetRulesManager, err := netrules.NewNetRulesManager(logger, persistent)\n\tif err != nil {\n\t\tlogger.Error(\"Failed to initialize net rules manager\", \"error\", err)\n\t\treturn 2\n\t}\n\n\t// Start net rules manager\n\tif err = netRulesManager.Start(); err != nil {\n\t\tlogger.Error(\"Failed to start net rules manager\", \"error\", err)\n\t\treturn 2\n\t}\n\tdefer netRulesManager.Stop()\n\n\tdaemonPath, err := daemon.WriteStaticBinary(\"daemon-amd64\")\n\tif err != nil {\n\t\tlogger.Error(\"Error writing daemon binary\", \"error\", err)\n\t\treturn 2\n\t}\n\n\tpluginPath, err := daemon.WriteStaticBinary(\"daytona-computer-use\")\n\tif err != nil {\n\t\tlogger.Error(\"Error writing plugin binary\", \"error\", err)\n\t\treturn 2\n\t}\n\n\tbackupInfoCache := cache.NewBackupInfoCache(ctx, cfg.BackupInfoCacheRetention)\n\n\tdockerClient, err := docker.NewDockerClient(docker.DockerClientConfig{\n\t\tApiClient:                    cli,\n\t\tBackupInfoCache:              backupInfoCache,\n\t\tLogger:                       logger,\n\t\tAWSRegion:                    cfg.AWSRegion,\n\t\tAWSEndpointUrl:               cfg.AWSEndpointUrl,\n\t\tAWSAccessKeyId:               cfg.AWSAccessKeyId,\n\t\tAWSSecretAccessKey:           cfg.AWSSecretAccessKey,\n\t\tDaemonPath:                   daemonPath,\n\t\tComputerUsePluginPath:        pluginPath,\n\t\tNetRulesManager:              netRulesManager,\n\t\tResourceLimitsDisabled:       cfg.ResourceLimitsDisabled,\n\t\tUseSnapshotEntrypoint:        cfg.UseSnapshotEntrypoint,\n\t\tVolumeCleanupInterval:        cfg.VolumeCleanupInterval,\n\t\tVolumeCleanupDryRun:          cfg.VolumeCleanupDryRun,\n\t\tVolumeCleanupExclusionPeriod: cfg.VolumeCleanupExclusionPeriod,\n\t\tBackupTimeoutMin:             cfg.BackupTimeoutMin,\n\t\tInitializeDaemonTelemetry:    cfg.InitializeDaemonTelemetry,\n\t})\n\tif err != nil {\n\t\tlogger.Error(\"Error creating Docker client wrapper\", \"error\", err)\n\t\treturn 2\n\t}\n\n\t// Start Docker events monitor\n\tmonitorOpts := docker.MonitorOptions{\n\t\tOnDestroyEvent: func(ctx context.Context) {\n\t\t\tdockerClient.CleanupOrphanedVolumeMounts(ctx)\n\t\t},\n\t}\n\tmonitor := docker.NewDockerMonitor(logger, cli, netRulesManager, monitorOpts)\n\tmonitorErrChan := make(chan error)\n\tgo func() {\n\t\tlogger.Info(\"Starting Docker monitor\")\n\t\terr = monitor.Start()\n\t\tif err != nil {\n\t\t\tmonitorErrChan <- err\n\t\t}\n\t}()\n\tdefer monitor.Stop()\n\n\tsandboxService := services.NewSandboxService(logger, backupInfoCache, dockerClient)\n\n\t// Initialize sandbox state synchronization service\n\tsandboxSyncService := services.NewSandboxSyncService(services.SandboxSyncServiceConfig{\n\t\tLogger:   logger,\n\t\tDocker:   dockerClient,\n\t\tInterval: 10 * time.Second, // Sync every 10 seconds\n\t})\n\tsandboxSyncService.StartSyncProcess(ctx)\n\n\t// Initialize SSH Gateway if enabled\n\tvar sshGatewayService *sshgateway.Service\n\tif sshgateway.IsSSHGatewayEnabled() {\n\t\tsshGatewayService = sshgateway.NewService(logger, dockerClient)\n\n\t\tgo func() {\n\t\t\tlogger.Info(\"Starting SSH Gateway\")\n\t\t\tif err := sshGatewayService.Start(ctx); err != nil {\n\t\t\t\tlogger.Error(\"SSH Gateway error\", \"error\", err)\n\t\t\t}\n\t\t}()\n\t} else {\n\t\tlogger.Info(\"Gateway disabled - set SSH_GATEWAY_ENABLE=true to enable\")\n\t}\n\n\t// Create metrics collector\n\tmetricsCollector := metrics.NewCollector(metrics.CollectorConfig{\n\t\tLogger:                             logger,\n\t\tDocker:                             dockerClient,\n\t\tWindowSize:                         cfg.CollectorWindowSize,\n\t\tCPUUsageSnapshotInterval:           cfg.CPUUsageSnapshotInterval,\n\t\tAllocatedResourcesSnapshotInterval: cfg.AllocatedResourcesSnapshotInterval,\n\t})\n\tmetricsCollector.Start(ctx)\n\n\t_, err = runner.GetInstance(&runner.RunnerInstanceConfig{\n\t\tLogger:             logger,\n\t\tBackupInfoCache:    backupInfoCache,\n\t\tSnapshotErrorCache: cache.NewSnapshotErrorCache(ctx, cfg.SnapshotErrorCacheRetention),\n\t\tDocker:             dockerClient,\n\t\tSandboxService:     sandboxService,\n\t\tMetricsCollector:   metricsCollector,\n\t\tNetRulesManager:    netRulesManager,\n\t\tSSHGatewayService:  sshGatewayService,\n\t})\n\tif err != nil {\n\t\tlogger.Error(\"Failed to initialize runner instance\", \"error\", err)\n\t\treturn 2\n\t}\n\n\tif cfg.ApiVersion == 2 {\n\t\thealthcheckService, err := healthcheck.NewService(&healthcheck.HealthcheckServiceConfig{\n\t\t\tInterval:   cfg.HealthcheckInterval,\n\t\t\tTimeout:    cfg.HealthcheckTimeout,\n\t\t\tCollector:  metricsCollector,\n\t\t\tLogger:     logger,\n\t\t\tDomain:     cfg.Domain,\n\t\t\tApiPort:    cfg.ApiPort,\n\t\t\tProxyPort:  cfg.ApiPort,\n\t\t\tTlsEnabled: cfg.EnableTLS,\n\t\t\tDocker:     dockerClient,\n\t\t})\n\t\tif err != nil {\n\t\t\tlogger.Error(\"Failed to create healthcheck service\", \"error\", err)\n\t\t\treturn 2\n\t\t}\n\n\t\tgo func() {\n\t\t\tlogger.Info(\"Starting healthcheck service\")\n\t\t\thealthcheckService.Start(ctx)\n\t\t}()\n\n\t\texecutorService, err := executor.NewExecutor(&executor.ExecutorConfig{\n\t\t\tLogger:    logger,\n\t\t\tDocker:    dockerClient,\n\t\t\tCollector: metricsCollector,\n\t\t})\n\t\tif err != nil {\n\t\t\tlogger.Error(\"Failed to create executor service\", \"error\", err)\n\t\t\treturn 2\n\t\t}\n\n\t\tpollerService, err := poller.NewService(&poller.PollerServiceConfig{\n\t\t\tPollTimeout: cfg.PollTimeout,\n\t\t\tPollLimit:   cfg.PollLimit,\n\t\t\tLogger:      logger,\n\t\t\tExecutor:    executorService,\n\t\t})\n\t\tif err != nil {\n\t\t\tlogger.Error(\"Failed to create poller service\", \"error\", err)\n\t\t\treturn 2\n\t\t}\n\n\t\tgo func() {\n\t\t\tlogger.Info(\"Starting poller service\")\n\t\t\tpollerService.Start(ctx)\n\t\t}()\n\t}\n\n\tapiServer := api.NewApiServer(api.ApiServerConfig{\n\t\tLogger:      logger,\n\t\tApiPort:     cfg.ApiPort,\n\t\tApiToken:    cfg.ApiToken,\n\t\tTLSCertFile: cfg.TLSCertFile,\n\t\tTLSKeyFile:  cfg.TLSKeyFile,\n\t\tEnableTLS:   cfg.EnableTLS,\n\t\tLogRequests: cfg.ApiLogRequests,\n\t})\n\n\tapiServerErrChan := make(chan error)\n\n\tgo func() {\n\t\terr := apiServer.Start(ctx)\n\t\tapiServerErrChan <- err\n\t}()\n\n\tinterruptChannel := make(chan os.Signal, 1)\n\tsignal.Notify(interruptChannel, os.Interrupt, syscall.SIGTERM)\n\n\tselect {\n\tcase err := <-apiServerErrChan:\n\t\tlogger.Error(\"API server error\", \"error\", err)\n\t\treturn 1\n\tcase <-interruptChannel:\n\t\tlogger.Info(\"Signal received, shutting down\")\n\t\tapiServer.Stop()\n\t\tlogger.Info(\"Shutdown complete\")\n\t\treturn 143 // SIGTERM\n\tcase err := <-monitorErrChan:\n\t\tlogger.Error(\"Docker monitor error\", \"error\", err)\n\t\treturn 1\n\t}\n}\n"
  },
  {
    "path": "apps/runner/go.mod",
    "content": "module github.com/daytonaio/runner\n\ngo 1.25.4\n\nrequire (\n\tgithub.com/containerd/errdefs v1.0.0\n\tgithub.com/coreos/go-iptables v0.8.0\n\tgithub.com/daytonaio/daytona/libs/api-client-go v0.149.0\n\tgithub.com/docker/docker v28.5.2+incompatible\n\tgithub.com/docker/go-units v0.5.0\n\tgithub.com/gin-gonic/gin v1.10.1\n\tgithub.com/go-playground/validator/v10 v10.27.0\n\tgithub.com/google/go-containerregistry v0.20.7\n\tgithub.com/gorilla/websocket v1.5.3\n\tgithub.com/kelseyhightower/envconfig v1.4.0\n\tgithub.com/lmittmann/tint v1.1.2\n\tgithub.com/mattn/go-isatty v0.0.20\n\tgithub.com/minio/minio-go/v7 v7.0.91\n\tgithub.com/opencontainers/image-spec v1.1.1\n\tgithub.com/orcaman/concurrent-map/v2 v2.0.1\n\tgithub.com/prometheus/client_golang v1.23.2\n\tgithub.com/samber/slog-gin v1.20.1\n\tgithub.com/shirou/gopsutil/v4 v4.25.12\n\tgithub.com/swaggo/files v1.0.1\n\tgithub.com/swaggo/gin-swagger v1.6.0\n\tgithub.com/swaggo/swag v1.16.4\n\tgithub.com/vishvananda/netlink v1.3.1\n\tgo.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.63.0\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0\n\tgo.opentelemetry.io/otel v1.40.0\n\tgo.opentelemetry.io/otel/sdk v1.40.0\n\tgo.opentelemetry.io/otel/trace v1.40.0\n\tgolang.org/x/crypto v0.47.0\n)\n\nrequire (\n\tgithub.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect\n\tgithub.com/KyleBanks/depth v1.2.1 // indirect\n\tgithub.com/Microsoft/go-winio v0.6.2 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/bytedance/sonic v1.14.0 // indirect\n\tgithub.com/bytedance/sonic/loader v0.3.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/cloudwego/base64x v0.1.6 // indirect\n\tgithub.com/containerd/errdefs/pkg v0.3.0 // indirect\n\tgithub.com/containerd/stargz-snapshotter/estargz v0.18.1 // indirect\n\tgithub.com/creack/pty v1.1.23 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/docker/cli v29.2.0+incompatible // indirect\n\tgithub.com/docker/distribution v2.8.3+incompatible // indirect\n\tgithub.com/docker/docker-credential-helpers v0.9.3 // indirect\n\tgithub.com/docker/go-connections v0.5.0 // indirect\n\tgithub.com/dustin/go-humanize v1.0.1 // indirect\n\tgithub.com/ebitengine/purego v0.9.1 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/gabriel-vasile/mimetype v1.4.10 // indirect\n\tgithub.com/gin-contrib/sse v1.1.0 // indirect\n\tgithub.com/go-ini/ini v1.67.0 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-ole/go-ole v1.3.0 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.21.0 // indirect\n\tgithub.com/go-openapi/jsonreference v0.21.0 // indirect\n\tgithub.com/go-openapi/spec v0.21.0 // indirect\n\tgithub.com/go-openapi/swag v0.23.0 // indirect\n\tgithub.com/go-playground/locales v0.14.1 // indirect\n\tgithub.com/go-playground/universal-translator v0.18.1 // indirect\n\tgithub.com/goccy/go-json v0.10.5 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/klauspost/compress v1.18.1 // indirect\n\tgithub.com/klauspost/cpuid/v2 v2.3.0 // indirect\n\tgithub.com/leodido/go-urn v1.4.0 // indirect\n\tgithub.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 // indirect\n\tgithub.com/mailru/easyjson v0.7.7 // indirect\n\tgithub.com/minio/crc64nvme v1.0.1 // indirect\n\tgithub.com/minio/md5-simd v1.1.2 // indirect\n\tgithub.com/mitchellh/go-homedir v1.1.0 // indirect\n\tgithub.com/moby/docker-image-spec v1.3.1 // indirect\n\tgithub.com/moby/sys/sequential v0.6.0 // indirect\n\tgithub.com/moby/term v0.5.2 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect\n\tgithub.com/morikuni/aec v1.0.0 // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/pelletier/go-toml/v2 v2.2.4 // indirect\n\tgithub.com/pkg/errors v0.9.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect\n\tgithub.com/prometheus/client_model v0.6.2 // indirect\n\tgithub.com/prometheus/common v0.67.1 // indirect\n\tgithub.com/prometheus/procfs v0.17.0 // indirect\n\tgithub.com/rs/xid v1.6.0 // indirect\n\tgithub.com/sirupsen/logrus v1.9.3 // indirect\n\tgithub.com/tklauser/go-sysconf v0.3.16 // indirect\n\tgithub.com/tklauser/numcpus v0.11.0 // indirect\n\tgithub.com/twitchyliquid64/golang-asm v0.15.1 // indirect\n\tgithub.com/ugorji/go/codec v1.3.0 // indirect\n\tgithub.com/vbatts/tar-split v0.12.2 // indirect\n\tgithub.com/vishvananda/netns v0.0.5 // indirect\n\tgithub.com/yusufpapurcu/wmi v1.2.4 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.40.0 // indirect\n\tgo.yaml.in/yaml/v2 v2.4.3 // indirect\n\tgolang.org/x/arch v0.20.0 // indirect\n\tgolang.org/x/net v0.49.0 // indirect\n\tgolang.org/x/sync v0.19.0 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n\tgolang.org/x/text v0.33.0 // indirect\n\tgolang.org/x/time v0.10.0 // indirect\n\tgolang.org/x/tools v0.40.0 // indirect\n\tgoogle.golang.org/grpc v1.79.3 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tgotest.tools/v3 v3.5.1 // indirect\n)\n"
  },
  {
    "path": "apps/runner/go.sum",
    "content": "github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=\ngithub.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=\ngithub.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=\ngithub.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=\ngithub.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=\ngithub.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=\ngithub.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=\ngithub.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=\ngithub.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=\ngithub.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=\ngithub.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=\ngithub.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=\ngithub.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=\ngithub.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=\ngithub.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=\ngithub.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=\ngithub.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=\ngithub.com/containerd/stargz-snapshotter/estargz v0.18.1 h1:cy2/lpgBXDA3cDKSyEfNOFMA/c10O1axL69EU7iirO8=\ngithub.com/containerd/stargz-snapshotter/estargz v0.18.1/go.mod h1:ALIEqa7B6oVDsrF37GkGN20SuvG/pIMm7FwP7ZmRb0Q=\ngithub.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc=\ngithub.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=\ngithub.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=\ngithub.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/daytonaio/daytona/libs/api-client-go v0.149.0 h1:afxGwDJOOK8m9Gxp4Rru0pKwoEkJDl4v0qxUn1f2pho=\ngithub.com/daytonaio/daytona/libs/api-client-go v0.149.0/go.mod h1:1wKpdKRwUzXN7KqR+8MMpq2iEGrprBCgFgFbli89DMo=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/docker/cli v29.2.0+incompatible h1:9oBd9+YM7rxjZLfyMGxjraKBKE4/nVyvVfN4qNl9XRM=\ngithub.com/docker/cli v29.2.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=\ngithub.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=\ngithub.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=\ngithub.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=\ngithub.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=\ngithub.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=\ngithub.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=\ngithub.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=\ngithub.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=\ngithub.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=\ngithub.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=\ngithub.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=\ngithub.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=\ngithub.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=\ngithub.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=\ngithub.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=\ngithub.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=\ngithub.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=\ngithub.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=\ngithub.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=\ngithub.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=\ngithub.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=\ngithub.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=\ngithub.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=\ngithub.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=\ngithub.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=\ngithub.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=\ngithub.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=\ngithub.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=\ngithub.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=\ngithub.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=\ngithub.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=\ngithub.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=\ngithub.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=\ngithub.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=\ngithub.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=\ngithub.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=\ngithub.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=\ngithub.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=\ngithub.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=\ngithub.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I=\ngithub.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=\ngithub.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII=\ngithub.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=\ngithub.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=\ngithub.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=\ngithub.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=\ngithub.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=\ngithub.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=\ngithub.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=\ngithub.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=\ngithub.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w=\ngithub.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=\ngithub.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3 h1:PwQumkgq4/acIiZhtifTV5OUqqiP82UAl0h87xj/l9k=\ngithub.com/lufia/plan9stats v0.0.0-20251013123823-9fd1530e3ec3/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=\ngithub.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=\ngithub.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY=\ngithub.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=\ngithub.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=\ngithub.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=\ngithub.com/minio/minio-go/v7 v7.0.91 h1:tWLZnEfo3OZl5PoXQwcwTAPNNrjyWwOh6cbZitW5JQc=\ngithub.com/minio/minio-go/v7 v7.0.91/go.mod h1:uvMUcGrpgeSAAI6+sD3818508nUyMULw94j2Nxku/Go=\ngithub.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=\ngithub.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=\ngithub.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=\ngithub.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=\ngithub.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=\ngithub.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=\ngithub.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=\ngithub.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=\ngithub.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=\ngithub.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=\ngithub.com/orcaman/concurrent-map/v2 v2.0.1 h1:jOJ5Pg2w1oeB6PeDurIYf6k9PQ+aTITr/6lP/L/zp6c=\ngithub.com/orcaman/concurrent-map/v2 v2.0.1/go.mod h1:9Eq3TG2oBe5FirmYWQfYO5iH1q0Jv47PLaNK++uCdOM=\ngithub.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=\ngithub.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=\ngithub.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=\ngithub.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=\ngithub.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=\ngithub.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=\ngithub.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=\ngithub.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI=\ngithub.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q=\ngithub.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=\ngithub.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=\ngithub.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=\ngithub.com/samber/slog-gin v1.20.1 h1:75wbryS7XrmGcVu/lfOwSFWWjmGoqV4GlE41nQFP0a4=\ngithub.com/samber/slog-gin v1.20.1/go.mod h1:7R4VMQGENllRLLnwGyoB5nUSB+qzxThpGe5G02xla6o=\ngithub.com/shirou/gopsutil/v4 v4.25.12 h1:e7PvW/0RmJ8p8vPGJH4jvNkOyLmbkXgXW4m6ZPic6CY=\ngithub.com/shirou/gopsutil/v4 v4.25.12/go.mod h1:EivAfP5x2EhLp2ovdpKSozecVXn1TmuG7SMzs/Wh4PU=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngithub.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=\ngithub.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=\ngithub.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=\ngithub.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=\ngithub.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=\ngithub.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg=\ngithub.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=\ngithub.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=\ngithub.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=\ngithub.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=\ngithub.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=\ngithub.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=\ngithub.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=\ngithub.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=\ngithub.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4=\ngithub.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=\ngithub.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=\ngithub.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=\ngithub.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=\ngithub.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=\ngithub.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.63.0 h1:5kSIJ0y8ckZZKoDhZHdVtcyjVi6rXyAwyaR8mp4zLbg=\ngo.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.63.0/go.mod h1:i+fIMHvcSQtsIY82/xgiVWRklrNt/O6QriHLjzGeY+s=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=\ngo.opentelemetry.io/contrib/propagators/b3 v1.38.0 h1:uHsCCOSKl0kLrV2dLkFK+8Ywk9iKa/fptkytc6aFFEo=\ngo.opentelemetry.io/contrib/propagators/b3 v1.38.0/go.mod h1:wMRSZJZcY8ya9mApLLhwIMjqmApy2o/Ml+62lhvxyHU=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0/go.mod h1:khvBS2IggMFNwZK/6lEeHg/W57h/IX6J4URh57fuI40=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=\ngo.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=\ngo.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=\ngo.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=\ngo.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=\ngo.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=\ngolang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=\ngolang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=\ngolang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=\ngolang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=\ngolang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=\ngolang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=\ngolang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=\ngolang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=\ngolang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=\ngolang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=\ngoogle.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngoogle.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=\ngotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=\n"
  },
  {
    "path": "apps/runner/internal/buildinfo.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage internal\n\nvar (\n\tVersion = \"v0.0.0-dev\"\n)\n"
  },
  {
    "path": "apps/runner/internal/constants/auth.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage constants\n\nconst BEARER_AUTH_HEADER = \"Bearer\"\n\nconst AUTHORIZATION_HEADER = \"Authorization\"\n\nconst DAYTONA_AUTHORIZATION_HEADER = \"X-Daytona-Authorization\"\n"
  },
  {
    "path": "apps/runner/internal/metrics/collector.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage metrics\n\nimport (\n\t\"container/ring\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/daytonaio/runner/pkg/docker\"\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/shirou/gopsutil/v4/cpu\"\n\t\"github.com/shirou/gopsutil/v4/disk\"\n\t\"github.com/shirou/gopsutil/v4/load\"\n\t\"github.com/shirou/gopsutil/v4/mem\"\n)\n\n// CollectorConfig holds configuration for the metrics collector\ntype CollectorConfig struct {\n\tLogger                             *slog.Logger\n\tDocker                             *docker.DockerClient\n\tWindowSize                         int\n\tCPUUsageSnapshotInterval           time.Duration\n\tAllocatedResourcesSnapshotInterval time.Duration\n}\n\n// Collector collects system metrics\ntype Collector struct {\n\tdocker *docker.DockerClient\n\tlog    *slog.Logger\n\n\t// CPU usage - ring buffer for sliding window\n\tcpuRing  *ring.Ring\n\tcpuMutex sync.RWMutex\n\n\tresourcesMutex      sync.RWMutex\n\tallocatedCPU        float32\n\tallocatedMemoryGiB  float32\n\tallocatedDiskGiB    float32\n\tstartedSandboxCount float32\n\n\t// Intervals for snapshotting metrics in seconds\n\tcpuUsageSnapshotInterval           time.Duration\n\tallocatedResourcesSnapshotInterval time.Duration\n}\n\n// CPUSnapshot represents a point-in-time CPU measurement\ntype CPUSnapshot struct {\n\ttimestamp  time.Time\n\tcpuPercent float64\n}\n\n// Metrics holds runner metrics\ntype Metrics struct {\n\tCPULoadAverage        float32\n\tCPUUsagePercentage    float32\n\tMemoryUsagePercentage float32\n\tDiskUsagePercentage   float32\n\tAllocatedCPU          float32\n\tAllocatedMemoryGiB    float32\n\tAllocatedDiskGiB      float32\n\tSnapshotCount         float32\n\tTotalCPU              float32\n\tTotalRAMGiB           float32\n\tTotalDiskGiB          float32\n\tStartedSandboxCount   float32\n}\n\n// NewCollector creates a new metrics collector\nfunc NewCollector(cfg CollectorConfig) *Collector {\n\treturn &Collector{\n\t\tlog:                                cfg.Logger.With(slog.String(\"component\", \"metrics\")),\n\t\tdocker:                             cfg.Docker,\n\t\tcpuRing:                            ring.New(cfg.WindowSize),\n\t\tcpuUsageSnapshotInterval:           cfg.CPUUsageSnapshotInterval,\n\t\tallocatedResourcesSnapshotInterval: cfg.AllocatedResourcesSnapshotInterval,\n\t}\n}\n\n// Start begins needed metrics collection processes\nfunc (c *Collector) Start(ctx context.Context) {\n\tgo c.snapshotCPUUsage(ctx)\n\tgo c.snapshotAllocatedResources(ctx)\n}\n\n// Collect gathers current system metrics\nfunc (c *Collector) Collect(ctx context.Context) (*Metrics, error) {\n\ttimeout := 30 * time.Second\n\ttimeoutCtx, cancel := context.WithTimeout(ctx, timeout)\n\tdefer cancel()\n\n\tfor {\n\t\tselect {\n\t\tcase <-timeoutCtx.Done():\n\t\t\treturn nil, errors.New(\"timeout collecting metrics\")\n\t\tdefault:\n\t\t\tmetrics, err := c.collect(timeoutCtx)\n\t\t\tif err != nil {\n\t\t\t\tc.log.DebugContext(ctx, \"Failed to collect metrics\", \"error\", err)\n\t\t\t\ttime.Sleep(1 * time.Second)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\treturn metrics, nil\n\t\t}\n\t}\n}\n\nfunc (c *Collector) collect(ctx context.Context) (*Metrics, error) {\n\tmetrics := &Metrics{}\n\n\t// Collect CPU count\n\tcpuCount, err := cpu.CountsWithContext(ctx, true)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to collect CPU count: %v\", err)\n\t}\n\tmetrics.TotalCPU = float32(cpuCount)\n\n\t// Update CPU load averages\n\t// Make sure that `cpuCount` exists and is greater than 0\n\tloadAvg, err := load.Avg()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to collect CPU load averages: %v\", err)\n\t}\n\tif cpuCount <= 0 {\n\t\treturn nil, errors.New(\"CPU count must be greater than zero\")\n\t}\n\tmetrics.CPULoadAverage = float32(loadAvg.Load15) / float32(cpuCount)\n\n\t// Collect CPU usage\n\tcpuUsage, err := c.collectCPUUsageAverage()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to collect CPU usage: %v\", err)\n\t}\n\tmetrics.CPUUsagePercentage = float32(cpuUsage)\n\n\t// Collect memory usage and total\n\tmemStats, err := mem.VirtualMemoryWithContext(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to collect memory usage: %v\", err)\n\t}\n\tmetrics.MemoryUsagePercentage = float32(memStats.UsedPercent)\n\t// Convert bytes to GiB (1 GiB = 1024^3 bytes)\n\tmetrics.TotalRAMGiB = float32(memStats.Total) / (1024 * 1024 * 1024)\n\n\t// Collect disk usage and total\n\tdiskStats, err := disk.UsageWithContext(ctx, \"/var/lib/docker\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to collect disk usage: %v\", err)\n\t}\n\tmetrics.DiskUsagePercentage = float32(diskStats.UsedPercent)\n\t// Convert bytes to GiB (1 GiB = 1024^3 bytes)\n\tmetrics.TotalDiskGiB = float32(diskStats.Total) / (1024 * 1024 * 1024)\n\n\t// Get snapshot count\n\tinfo, err := c.docker.ApiClient().Info(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get snapshot count: %v\", err)\n\t}\n\tmetrics.SnapshotCount = float32(info.Images)\n\n\tc.resourcesMutex.RLock()\n\tmetrics.AllocatedCPU = c.allocatedCPU\n\tmetrics.AllocatedMemoryGiB = c.allocatedMemoryGiB\n\tmetrics.AllocatedDiskGiB = c.allocatedDiskGiB\n\tmetrics.StartedSandboxCount = c.startedSandboxCount\n\tc.resourcesMutex.RUnlock()\n\n\treturn metrics, nil\n}\n\n// snapshotCPUUsage runs in a background goroutine, continuously monitoring CPU usage\nfunc (c *Collector) snapshotCPUUsage(ctx context.Context) {\n\tticker := time.NewTicker(c.cpuUsageSnapshotInterval)\n\tdefer ticker.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tc.log.InfoContext(ctx, \"CPU usage snapshotting stopped\")\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\t// Add a new CPU snapshot to the ring buffer\n\t\t\tcpuPercent, err := cpu.PercentWithContext(ctx, 0, false)\n\t\t\tif err != nil {\n\t\t\t\tc.log.WarnContext(ctx, \"Failed to collect next CPU usage ring\", \"error\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tc.cpuMutex.Lock()\n\t\t\tc.cpuRing.Value = CPUSnapshot{\n\t\t\t\ttimestamp:  time.Now(),\n\t\t\t\tcpuPercent: cpuPercent[0],\n\t\t\t}\n\t\t\tc.cpuRing = c.cpuRing.Next()\n\t\t\tc.cpuMutex.Unlock()\n\t\t}\n\t}\n}\n\n// collectCPUUsageAverage calculates the average CPU usage from the ring buffer\nfunc (c *Collector) collectCPUUsageAverage() (float64, error) {\n\tvar total float64\n\tvar count int\n\n\tc.cpuMutex.RLock()\n\tdefer c.cpuMutex.RUnlock()\n\n\tc.cpuRing.Do(func(x interface{}) {\n\t\tif x != nil {\n\t\t\tsnapshot, ok := x.(CPUSnapshot)\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttotal += snapshot.cpuPercent\n\t\t\tcount++\n\t\t}\n\t})\n\n\tif count == 0 {\n\t\treturn -1.0, errors.New(\"CPU metrics not yet available\")\n\t}\n\n\treturn total / float64(count), nil\n}\n\nfunc (c *Collector) snapshotAllocatedResources(ctx context.Context) {\n\tticker := time.NewTicker(c.allocatedResourcesSnapshotInterval)\n\tdefer ticker.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tc.log.InfoContext(ctx, \"Allocated resources snapshotting stopped\")\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\tcontainers, err := c.docker.ApiClient().ContainerList(ctx, container.ListOptions{All: true})\n\t\t\tif err != nil {\n\t\t\t\tc.log.ErrorContext(ctx, \"Error listing containers when getting allocated resources\", \"error\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvar totalAllocatedCpuMicroseconds float32 = 0 // CPU quota in microseconds per period\n\t\t\tvar totalAllocatedMemoryBytes float32 = 0     // Memory in bytes\n\t\t\tvar totalAllocatedDiskGB float32 = 0          // Disk in GB\n\t\t\tvar startedSandboxCount float32 = 0           // Count of running containers\n\n\t\t\tfor _, ctr := range containers {\n\t\t\t\tcpu, memory, disk, err := c.getContainerAllocatedResources(ctx, ctr.ID)\n\t\t\t\tif err != nil {\n\t\t\t\t\tc.log.WarnContext(ctx, \"Failed to get allocated resources for container\", \"container_id\", ctr.ID, \"error\", err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// For CPU and memory: only count running containers\n\t\t\t\tif ctr.State == \"running\" {\n\t\t\t\t\ttotalAllocatedCpuMicroseconds += cpu\n\t\t\t\t\ttotalAllocatedMemoryBytes += memory\n\t\t\t\t\tstartedSandboxCount++\n\t\t\t\t}\n\n\t\t\t\t// For disk: count all containers (running and stopped)\n\t\t\t\ttotalAllocatedDiskGB += disk\n\t\t\t}\n\n\t\t\t// Convert to original API units\n\t\t\tc.resourcesMutex.Lock()\n\t\t\tc.allocatedCPU = totalAllocatedCpuMicroseconds / 100000                 // Convert back to vCPUs\n\t\t\tc.allocatedMemoryGiB = totalAllocatedMemoryBytes / (1024 * 1024 * 1024) // Convert back to GB\n\t\t\tc.allocatedDiskGiB = totalAllocatedDiskGB\n\t\t\tc.startedSandboxCount = startedSandboxCount\n\t\t\tc.resourcesMutex.Unlock()\n\t\t}\n\t}\n}\n\nfunc (c *Collector) getContainerAllocatedResources(ctx context.Context, containerId string) (float32, float32, float32, error) {\n\t// Inspect the container to get its resource configuration\n\tcontainerJSON, err := c.docker.ContainerInspect(ctx, containerId)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\n\tif containerJSON.HostConfig == nil {\n\t\treturn 0, 0, 0, nil\n\t}\n\n\tvar allocatedCpu, allocatedMemory, allocatedDisk float32 = 0, 0, 0\n\n\tresources := containerJSON.HostConfig.Resources\n\n\tif resources.CPUQuota > 0 {\n\t\tallocatedCpu = float32(resources.CPUQuota)\n\t}\n\n\tif resources.Memory > 0 {\n\t\tallocatedMemory = float32(resources.Memory)\n\t}\n\n\tif containerJSON.HostConfig.StorageOpt == nil {\n\t\treturn allocatedCpu, allocatedMemory, 0, nil\n\t}\n\n\t// Disk allocation from StorageOpt (assuming xfs filesystem)\n\tstorageGB, err := common.ParseStorageOptSizeGB(containerJSON.HostConfig.StorageOpt)\n\tif err != nil {\n\t\treturn allocatedCpu, allocatedMemory, 0, fmt.Errorf(\"error parsing storage quota for container %s: %v\", containerId, err)\n\t}\n\n\tif storageGB > 0 {\n\t\tallocatedDisk = float32(storageGB)\n\t}\n\n\treturn allocatedCpu, allocatedMemory, allocatedDisk, nil\n}\n"
  },
  {
    "path": "apps/runner/internal/util/error_extract.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage util\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\nfunc ExtractErrorPart(errorMsg string) string {\n\tr := regexp.MustCompile(`(unable to find user [^:]+)`)\n\n\tmatches := r.FindStringSubmatch(errorMsg)\n\n\tif len(matches) < 2 {\n\t\treturn errorMsg\n\t}\n\n\treturn fmt.Sprintf(\"bad request: %s\", matches[1])\n}\n"
  },
  {
    "path": "apps/runner/packaging/deb/DEBIAN/control",
    "content": "Package: daytona-runner\nVersion: ${VERSION}\nSection: utils\nPriority: optional\nArchitecture: amd64\nMaintainer: Daytona <support@daytona.io>\nDescription: Daytona Runner\n The Daytona Runner manages execution of jobs and sandboxes\n for the Daytona development environment platform.\nHomepage: https://github.com/daytonaio/daytona\n"
  },
  {
    "path": "apps/runner/packaging/deb/DEBIAN/postinst",
    "content": "#!/bin/bash\nset -e\n\n# Create necessary directories\nmkdir -p /var/lib/daytona/runner\nmkdir -p /var/log/daytona\nmkdir -p /etc/daytona\n\n# Create default environment file if it doesn't exist\nif [ ! -f /etc/daytona/runner.env ]; then\n    cat > /etc/daytona/runner.env <<EOF\n# Daytona Runner Environment Variables\n# Add your configuration here, for example:\n# DAYTONA_API_URL=https://api.daytona.io\n# DAYTONA_RUNNER_TOKEN=your-token-here\nEOF\n    chmod 600 /etc/daytona/runner.env\nfi\n\n# Reload systemd daemon\nsystemctl daemon-reload\n\necho \"Daytona Runner installed successfully\"\necho \"\"\necho \"Next steps:\"\necho \"1. Configure environment variables in /etc/daytona/runner.env\"\necho \"2. Enable and start the service: systemctl enable --now daytona-runner\"\necho \"\"\necho \"To check service status: systemctl status daytona-runner\"\n\nexit 0\n"
  },
  {
    "path": "apps/runner/packaging/deb/DEBIAN/postrm",
    "content": "#!/bin/bash\nset -e\n\n# Reload systemd daemon to remove the service\nsystemctl daemon-reload\n\n# On purge, remove configuration and data\nif [ \"$1\" = \"purge\" ]; then\n    rm -rf /etc/daytona/runner.env\n    rm -rf /var/lib/daytona/runner\n    rm -rf /var/log/daytona\nfi\n\nexit 0\n"
  },
  {
    "path": "apps/runner/packaging/deb/DEBIAN/prerm",
    "content": "#!/bin/bash\nset -e\n\n# Stop the service if it's running\nif systemctl is-active --quiet daytona-runner.service; then\n    systemctl stop daytona-runner.service\nfi\n\n# Disable the service\nif systemctl is-enabled --quiet daytona-runner.service; then\n    systemctl disable daytona-runner.service\nfi\n\nexit 0\n"
  },
  {
    "path": "apps/runner/packaging/systemd/daytona-runner.service",
    "content": "[Unit]\nDescription=Daytona Runner Service\nDocumentation=https://github.com/daytonaio/daytona\nAfter=network.target\nWants=network-online.target\n\n[Service]\nType=simple\nUser=root\nGroup=root\nWorkingDirectory=/var/lib/daytona/runner\n\n# Binary location\nExecStart=/opt/daytona/runner\n\n# Environment file for configuration\nEnvironmentFile=-/etc/daytona/runner.env\n\n# Restart policy\nRestart=on-failure\nRestartSec=5s\n\n# Security hardening\nNoNewPrivileges=true\nPrivateTmp=true\nProtectSystem=strict\nProtectHome=true\nReadWritePaths=/var/lib/daytona/runner /var/log/daytona /etc/iptables /tmp\n\n# Resource limits\nLimitNOFILE=65536\nLimitNPROC=4096\n\n# Logging\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=daytona-runner\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "apps/runner/pkg/api/controllers/command_logs.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage controllers\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/proxy\"\n\t\"github.com/gin-gonic/gin\"\n\n\t\"github.com/gorilla/websocket\"\n)\n\nfunc ProxyCommandLogsStream(ctx *gin.Context, logger *slog.Logger) {\n\treqCtx := ctx.Request.Context()\n\ttargetURL, extraHeaders, err := getProxyTarget(ctx)\n\tif err != nil {\n\t\t// Error already sent to the context\n\t\treturn\n\t}\n\n\tif ctx.Query(\"follow\") != \"true\" {\n\t\tproxy.NewProxyRequestHandler(func(ctx *gin.Context) (*url.URL, map[string]string, error) {\n\t\t\treturn targetURL, extraHeaders, nil\n\t\t}, nil)(ctx)\n\t\treturn\n\t}\n\n\tfullTargetURL := strings.Replace(targetURL.String(), \"http://\", \"ws://\", 1)\n\n\tws, _, err := websocket.DefaultDialer.DialContext(context.Background(), fullTargetURL+\"?follow=true\", nil)\n\tif err != nil {\n\t\tctx.Error(errors.NewBadRequestError(fmt.Errorf(\"failed to create outgoing request: %w\", err)))\n\t\treturn\n\t}\n\n\tctx.Header(\"Content-Type\", \"application/octet-stream\")\n\n\tws.SetCloseHandler(func(code int, text string) error {\n\t\tif code == websocket.CloseNormalClosure {\n\t\t\treturn nil\n\t\t}\n\t\tctx.AbortWithStatus(code)\n\t\treturn nil\n\t})\n\n\tdefer ws.Close()\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\tdefault:\n\t\t\t_, msg, err := ws.ReadMessage()\n\t\t\tif err != nil {\n\t\t\t\tif websocket.IsCloseError(err, websocket.CloseNormalClosure) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tlogger.ErrorContext(reqCtx, \"Error reading message\", \"error\", err)\n\t\t\t\tws.Close()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t_, err = ctx.Writer.Write(msg)\n\t\t\tif err != nil {\n\t\t\t\tlogger.ErrorContext(reqCtx, \"Error writing message\", \"error\", err)\n\t\t\t\tws.Close()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tctx.Writer.Flush()\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/controllers/health.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\npackage controllers\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/daytonaio/runner/internal\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// HealthCheck \t\t\tgodoc\n//\n//\t@Summary\t\tHealth check\n//\t@Description\tHealth check\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tmap[string]string\n//\t@Router\t\t\t/ [get]\n//\n//\t@id\t\t\t\tHealthCheck\nfunc HealthCheck(ctx *gin.Context) {\n\tctx.JSON(http.StatusOK, gin.H{\n\t\t\"status\":  \"ok\",\n\t\t\"version\": internal.Version,\n\t})\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/controllers/info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage controllers\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/daytonaio/runner/internal\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/models\"\n\t\"github.com/daytonaio/runner/pkg/runner\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// RunnerInfo \t\t\tgodoc\n//\n//\t@Summary\t\tRunner info\n//\t@Description\tRunner info with system metrics\n//\t@Produce\t\tjson\n//\t@Success\t\t200\t{object}\tdto.RunnerInfoResponseDTO\n//\t@Router\t\t\t/info [get]\n//\n//\t@id\t\t\t\tRunnerInfo\nfunc RunnerInfo(ctx *gin.Context) {\n\trunnerInstance, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tmetrics, err := runnerInstance.MetricsCollector.Collect(ctx.Request.Context())\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tservicesInfo := runnerInstance.InspectRunnerServices(ctx.Request.Context())\n\n\tresponse := dto.RunnerInfoResponseDTO{\n\t\tServiceHealth: mapRunnerServiceInfoToDTO(servicesInfo),\n\t\tMetrics: &dto.RunnerMetrics{\n\t\t\tCurrentCpuLoadAverage:        float64(metrics.CPULoadAverage),\n\t\t\tCurrentCpuUsagePercentage:    float64(metrics.CPUUsagePercentage),\n\t\t\tCurrentMemoryUsagePercentage: float64(metrics.MemoryUsagePercentage),\n\t\t\tCurrentDiskUsagePercentage:   float64(metrics.DiskUsagePercentage),\n\t\t\tCurrentAllocatedCpu:          float64(metrics.AllocatedCPU),\n\t\t\tCurrentAllocatedMemoryGiB:    float64(metrics.AllocatedMemoryGiB),\n\t\t\tCurrentAllocatedDiskGiB:      float64(metrics.AllocatedDiskGiB),\n\t\t\tCurrentSnapshotCount:         int(metrics.SnapshotCount),\n\t\t\tCurrentStartedSandboxes:      int64(metrics.StartedSandboxCount),\n\t\t},\n\t\tAppVersion: internal.Version,\n\t}\n\n\tctx.JSON(http.StatusOK, response)\n}\n\nfunc mapRunnerServiceInfoToDTO(servicesInfo []models.RunnerServiceInfo) []*dto.RunnerServiceInfo {\n\trunnerServicesInfoDTO := make([]*dto.RunnerServiceInfo, 0)\n\n\tfor _, serviceInfo := range servicesInfo {\n\t\tserviceInfoDto := &dto.RunnerServiceInfo{\n\t\t\tServiceName: serviceInfo.ServiceName,\n\t\t\tHealthy:     serviceInfo.Healthy,\n\t\t}\n\n\t\tif serviceInfo.Err != nil {\n\t\t\terrReason := serviceInfo.Err.Error()\n\t\t\tserviceInfoDto.ErrorReason = &errReason\n\t\t}\n\n\t\trunnerServicesInfoDTO = append(runnerServicesInfoDTO, serviceInfoDto)\n\t}\n\n\treturn runnerServicesInfoDTO\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/controllers/proxy.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage controllers\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\tproxy \"github.com/daytonaio/common-go/pkg/proxy\"\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\t\"github.com/daytonaio/runner/pkg/runner\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// ProxyRequest handles proxying requests to a sandbox's container\n//\n//\t@Tags\t\t\ttoolbox\n//\t@Summary\t\tProxy requests to the sandbox toolbox\n//\t@Description\tForwards the request to the specified sandbox's container\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\ttrue\t\"Sandbox ID\"\n//\t@Param\t\t\tpath\t\tpath\t\tstring\ttrue\t\"Path to forward\"\n//\t@Success\t\t200\t\t\t{object}\tany\t\t\"Proxied response\"\n//\t@Failure\t\t400\t\t\t{object}\tstring\t\"Bad request\"\n//\t@Failure\t\t401\t\t\t{object}\tstring\t\"Unauthorized\"\n//\t@Failure\t\t404\t\t\t{object}\tstring\t\"Sandbox container not found\"\n//\t@Failure\t\t409\t\t\t{object}\tstring\t\"Sandbox container conflict\"\n//\t@Failure\t\t500\t\t\t{object}\tstring\t\"Internal server error\"\n//\t@Router\t\t\t/sandboxes/{sandboxId}/toolbox/{path} [get]\n//\t@Router\t\t\t/sandboxes/{sandboxId}/toolbox/{path} [post]\n//\t@Router\t\t\t/sandboxes/{sandboxId}/toolbox/{path} [delete]\nfunc ProxyRequest(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tif ctx.Request.Header.Get(\"Upgrade\") != \"websocket\" && regexp.MustCompile(`^/process/session/.+/command/.+/logs$`).MatchString(ctx.Param(\"path\")) {\n\t\t\tif ctx.Query(\"follow\") == \"true\" {\n\t\t\t\tProxyCommandLogsStream(ctx, logger)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tproxy.NewProxyRequestHandler(getProxyTarget, nil)(ctx)\n\t}\n}\n\nfunc getProxyTarget(ctx *gin.Context) (*url.URL, map[string]string, error) {\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn nil, nil, err\n\t}\n\n\tsandboxId := ctx.Param(\"sandboxId\")\n\tif sandboxId == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"sandbox ID is required\")))\n\t\treturn nil, nil, errors.New(\"sandbox ID is required\")\n\t}\n\n\t// Resolve the container IP with retries to handle transient Docker\n\t// networking states where the container exists but has no IP yet.\n\tvar containerIP string\n\tvar containerNotFound bool\n\terr = utils.RetryWithExponentialBackoff(ctx.Request.Context(), \"resolve container IP\", 3, 100*time.Millisecond, 500*time.Millisecond, func() error {\n\t\tcontainer, err := runner.Docker.ContainerInspect(ctx.Request.Context(), sandboxId)\n\t\tif err != nil {\n\t\t\tcontainerNotFound = true\n\t\t\treturn &utils.NonRetryableError{Err: fmt.Errorf(\"sandbox container not found: %w\", err)}\n\t\t}\n\n\t\tfor _, network := range container.NetworkSettings.Networks {\n\t\t\tcontainerIP = network.IPAddress\n\t\t\tbreak\n\t\t}\n\n\t\tif containerIP == \"\" {\n\t\t\treturn errors.New(\"no IP address found\")\n\t\t}\n\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\tif containerNotFound {\n\t\t\tctx.Error(common_errors.NewNotFoundError(err))\n\t\t} else {\n\t\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"%w. Is the Sandbox started?\", err)))\n\t\t}\n\t\treturn nil, nil, err\n\t}\n\n\t// Build the target URL\n\ttargetURL := fmt.Sprintf(\"http://%s:2280\", containerIP)\n\n\t// Get the wildcard path and normalize it\n\tpath := ctx.Param(\"path\")\n\n\t// Ensure path always has a leading slash but not duplicate slashes\n\tif path == \"\" {\n\t\tpath = \"/\"\n\t} else if !strings.HasPrefix(path, \"/\") {\n\t\tpath = \"/\" + path\n\t}\n\n\t// Create the complete target URL with path\n\ttarget, err := url.Parse(fmt.Sprintf(\"%s%s\", targetURL, path))\n\tif err != nil {\n\t\tctx.Error(common_errors.NewBadRequestError(fmt.Errorf(\"failed to parse target URL: %w\", err)))\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse target URL: %w\", err)\n\t}\n\n\treturn target, nil, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/controllers/sandbox.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage controllers\n\nimport (\n\t\"log/slog\"\n\t\"net/http\"\n\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n\t\"github.com/daytonaio/runner/pkg/runner\"\n\t\"github.com/gin-gonic/gin\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\n// Create \t\t\tgodoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tCreate a sandbox\n//\t@Description\tCreate a sandbox\n//\t@Param\t\t\tsandbox\tbody\tdto.CreateSandboxDTO\ttrue\t\"Create sandbox\"\n//\t@Produce\t\tjson\n//\t@Success\t\t201\t{object}\tdto.StartSandboxResponse\n//\t@Failure\t\t400\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes [post]\n//\n//\t@id\t\t\t\tCreate\nfunc Create(ctx *gin.Context) {\n\tvar createSandboxDto dto.CreateSandboxDTO\n\terr := ctx.ShouldBindJSON(&createSandboxDto)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\t_, daemonVersion, err := runner.Docker.Create(ctx.Request.Context(), createSandboxDto)\n\tif err != nil {\n\t\tcommon.ContainerOperationCount.WithLabelValues(\"create\", string(common.PrometheusOperationStatusFailure)).Inc()\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tcommon.ContainerOperationCount.WithLabelValues(\"create\", string(common.PrometheusOperationStatusSuccess)).Inc()\n\n\tctx.JSON(http.StatusCreated, dto.StartSandboxResponse{\n\t\tDaemonVersion: daemonVersion,\n\t})\n}\n\n// Destroy \t\t\tgodoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tDestroy sandbox\n//\t@Description\tDestroy sandbox\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\ttrue\t\"Sandbox ID\"\n//\t@Success\t\t200\t\t\t{string}\tstring\t\"Sandbox destroyed\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/destroy [post]\n//\n//\t@id\t\t\t\tDestroy\nfunc Destroy(ctx *gin.Context) {\n\tsandboxId := ctx.Param(\"sandboxId\")\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\terr = runner.Docker.Destroy(ctx.Request.Context(), sandboxId)\n\tif err != nil {\n\t\tcommon.ContainerOperationCount.WithLabelValues(\"destroy\", string(common.PrometheusOperationStatusFailure)).Inc()\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tcommon.ContainerOperationCount.WithLabelValues(\"destroy\", string(common.PrometheusOperationStatusSuccess)).Inc()\n\n\tctx.JSON(http.StatusOK, \"Sandbox destroyed\")\n}\n\n// CreateBackup godoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tCreate sandbox backup\n//\t@Description\tCreate sandbox backup\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\t\t\t\ttrue\t\"Sandbox ID\"\n//\t@Param\t\t\tsandbox\t\tbody\t\tdto.CreateBackupDTO\ttrue\t\"Create backup\"\n//\t@Success\t\t201\t\t\t{string}\tstring\t\t\t\t\"Backup started\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/backup [post]\n//\n//\t@id\t\t\t\tCreateBackup\nfunc CreateBackup(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tsandboxId := ctx.Param(\"sandboxId\")\n\n\t\tvar createBackupDTO dto.CreateBackupDTO\n\t\terr := ctx.ShouldBindJSON(&createBackupDTO)\n\t\tif err != nil {\n\t\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\t\treturn\n\t\t}\n\n\t\trunner, err := runner.GetInstance(nil)\n\t\tif err != nil {\n\t\t\tctx.Error(err)\n\t\t\treturn\n\t\t}\n\n\t\terr = runner.Docker.CreateBackupAsync(ctx.Request.Context(), sandboxId, createBackupDTO)\n\t\tif err != nil {\n\t\t\tsetErr := runner.BackupInfoCache.SetBackupState(ctx.Request.Context(), sandboxId, enums.BackupStateFailed, err)\n\t\t\tif setErr != nil {\n\t\t\t\tlogger.DebugContext(ctx.Request.Context(), \"failed to update backup info\", \"error\", setErr)\n\t\t\t}\n\n\t\t\tctx.Error(err)\n\t\t\treturn\n\t\t}\n\n\t\tctx.JSON(http.StatusCreated, \"Backup started\")\n\t}\n}\n\n// Resize \t\t\tgodoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tResize sandbox\n//\t@Description\tResize sandbox\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\t\t\t\t\ttrue\t\"Sandbox ID\"\n//\t@Param\t\t\tsandbox\t\tbody\t\tdto.ResizeSandboxDTO\ttrue\t\"Resize sandbox\"\n//\t@Success\t\t200\t\t\t{string}\tstring\t\t\t\t\t\"Sandbox resized\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/resize [post]\n//\n//\t@id\t\t\t\tResize\nfunc Resize(ctx *gin.Context) {\n\tvar resizeDto dto.ResizeSandboxDTO\n\terr := ctx.ShouldBindJSON(&resizeDto)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\tsandboxId := ctx.Param(\"sandboxId\")\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\terr = runner.Docker.Resize(ctx.Request.Context(), sandboxId, resizeDto)\n\tif err != nil {\n\t\tcommon.ContainerOperationCount.WithLabelValues(\"resize\", string(common.PrometheusOperationStatusFailure)).Inc()\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tcommon.ContainerOperationCount.WithLabelValues(\"resize\", string(common.PrometheusOperationStatusSuccess)).Inc()\n\n\tctx.JSON(http.StatusOK, \"Sandbox resized\")\n}\n\n// UpdateNetworkSettings godoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tUpdate sandbox network settings\n//\t@Description\tUpdate sandbox network settings\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\t\t\t\t\t\t\ttrue\t\"Sandbox ID\"\n//\t@Param\t\t\tsandbox\t\tbody\t\tdto.UpdateNetworkSettingsDTO\ttrue\t\"Update network settings\"\n//\t@Success\t\t200\t\t\t{string}\tstring\t\t\t\t\t\t\t\"Network settings updated\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/network-settings [post]\n//\n//\t@id\t\t\t\tUpdateNetworkSettings\nfunc UpdateNetworkSettings(ctx *gin.Context) {\n\tvar updateNetworkSettingsDto dto.UpdateNetworkSettingsDTO\n\terr := ctx.ShouldBindJSON(&updateNetworkSettingsDto)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\tsandboxId := ctx.Param(\"sandboxId\")\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\terr = runner.Docker.UpdateNetworkSettings(ctx.Request.Context(), sandboxId, updateNetworkSettingsDto)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, \"Network settings updated\")\n}\n\n// GetNetworkSettings godoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tGet sandbox network settings\n//\t@Description\tGet sandbox network settings\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\t\t\t\t\t\t\ttrue\t\"Sandbox ID\"\n//\t@Success\t\t200\t\t\t{object}\tdto.UpdateNetworkSettingsDTO\t\"Network settings\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/network-settings [get]\n//\n//\t@id\t\t\t\tGetNetworkSettings\nfunc GetNetworkSettings(ctx *gin.Context) {\n\t// TODO: Implement GetNetworkSettings in Docker client\n\t// sandboxId := ctx.Param(\"sandboxId\")\n\t// runner := runner.GetInstance(nil)\n\t// networkSettings, err := runner.Docker.GetNetworkSettings(ctx.Request.Context(), sandboxId)\n\t// if err != nil {\n\t// \tctx.Error(err)\n\t// \treturn\n\t// }\n\n\t// For now, return empty settings\n\tnetworkSettings := dto.UpdateNetworkSettingsDTO{\n\t\tNetworkBlockAll:  nil,\n\t\tNetworkAllowList: nil,\n\t}\n\n\tctx.JSON(http.StatusOK, networkSettings)\n}\n\n// Start \t\t\tgodoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tStart sandbox\n//\t@Description\tStart sandbox\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\t\t\t\t\t\ttrue\t\"Sandbox ID\"\n//\t@Param\t\t\tmetadata\tbody\t\tobject\t\t\t\t\t\tfalse\t\"Metadata\"\n//\t@Param\t\t\ttoken\t\tquery\t\tstring\t\t\t\t\t\tfalse\t\"Auth token\"\n//\t@Success\t\t200\t\t\t{object}\tdto.StartSandboxResponse\t\"Sandbox started\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/start [post]\n//\n//\t@id\t\t\t\tStart\nfunc Start(ctx *gin.Context) {\n\tsandboxId := ctx.Param(\"sandboxId\")\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tvar metadata map[string]string\n\terr = ctx.ShouldBindJSON(&metadata)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\tvar authToken *string\n\ttokenQuery := ctx.Query(\"token\")\n\tif tokenQuery != \"\" {\n\t\tauthToken = &tokenQuery\n\t}\n\n\t_, daemonVersion, err := runner.Docker.Start(ctx.Request.Context(), sandboxId, authToken, metadata)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, dto.StartSandboxResponse{\n\t\tDaemonVersion: daemonVersion,\n\t})\n}\n\n// Stop \t\t\tgodoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tStop sandbox\n//\t@Description\tStop sandbox\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\ttrue\t\"Sandbox ID\"\n//\t@Success\t\t200\t\t\t{string}\tstring\t\"Sandbox stopped\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/stop [post]\n//\n//\t@id\t\t\t\tStop\nfunc Stop(ctx *gin.Context) {\n\tsandboxId := ctx.Param(\"sandboxId\")\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\terr = runner.Docker.Stop(ctx.Request.Context(), sandboxId)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, \"Sandbox stopped\")\n}\n\n// Info godoc\n//\n//\t@Tags\t\t\tsandbox\n//\t@Summary\t\tGet sandbox info\n//\t@Description\tGet sandbox info\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\t\t\t\ttrue\t\"Sandbox ID\"\n//\t@Success\t\t200\t\t\t{object}\tSandboxInfoResponse\t\"Sandbox info\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId} [get]\n//\n//\t@id\t\t\t\tInfo\nfunc Info(ctx *gin.Context) {\n\tsandboxId := ctx.Param(\"sandboxId\")\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tinfo, err := runner.SandboxService.GetSandboxInfo(ctx.Request.Context(), sandboxId)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tvar daemonVersion *string\n\tif info.SandboxState == enums.SandboxStateStarted {\n\t\tdaemonVersionStr, err := runner.Docker.GetDaemonVersion(ctx.Request.Context(), sandboxId)\n\t\tif err == nil {\n\t\t\tdaemonVersion = &daemonVersionStr\n\t\t}\n\t}\n\n\tctx.JSON(http.StatusOK, SandboxInfoResponse{\n\t\tState:         info.SandboxState,\n\t\tBackupState:   info.BackupState,\n\t\tBackupError:   info.BackupErrorReason,\n\t\tDaemonVersion: daemonVersion,\n\t})\n}\n\ntype SandboxInfoResponse struct {\n\tState         enums.SandboxState `json:\"state\"`\n\tBackupState   enums.BackupState  `json:\"backupState\"`\n\tBackupError   *string            `json:\"backupError,omitempty\"`\n\tDaemonVersion *string            `json:\"daemonVersion,omitempty\"`\n} //\t@name\tSandboxInfoResponse\n\n// Recover godoc\n//\n//\t@Summary\t\tRecover sandbox from error state\n//\t@Description\tRecover sandbox from error state using specified recovery type\n//\t@Tags\t\t\tsandbox\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\t\t\t\t\ttrue\t\"Sandbox ID\"\n//\t@Param\t\t\trecovery\tbody\t\tdto.RecoverSandboxDTO\ttrue\t\"Recovery parameters\"\n//\t@Success\t\t200\t\t\t{string}\tstring\t\t\t\t\t\"Sandbox recovered\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/recover [post]\n//\n//\t@id\t\t\t\tRecover\nfunc Recover(ctx *gin.Context) {\n\tvar recoverDto dto.RecoverSandboxDTO\n\terr := ctx.ShouldBindJSON(&recoverDto)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\tsandboxId := ctx.Param(\"sandboxId\")\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\terr = runner.Docker.RecoverSandbox(ctx.Request.Context(), sandboxId, recoverDto)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, \"Sandbox recovered\")\n}\n\n// IsRecoverable godoc\n//\n//\t@Summary\t\tCheck if sandbox error is recoverable\n//\t@Description\tCheck if the sandbox's error reason indicates a recoverable error\n//\t@Tags\t\t\tsandbox\n//\t@Accept\t\t\tjson\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsandboxId\tpath\t\tstring\t\t\t\t\ttrue\t\"Sandbox ID\"\n//\t@Param\t\t\trequest\t\tbody\t\tdto.IsRecoverableDTO\ttrue\t\"Error reason to check\"\n//\t@Success\t\t200\t\t\t{object}\tdto.IsRecoverableResponse\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/sandboxes/{sandboxId}/is-recoverable [post]\n//\n//\t@id\t\t\t\tIsRecoverable\nfunc IsRecoverable(ctx *gin.Context) {\n\tvar request dto.IsRecoverableDTO\n\tif err := ctx.ShouldBindJSON(&request); err != nil {\n\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\trecoverable := common.IsRecoverable(request.ErrorReason)\n\n\tctx.JSON(http.StatusOK, dto.IsRecoverableResponse{\n\t\tRecoverable: recoverable,\n\t})\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/controllers/snapshot.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage controllers\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"context\"\n\n\t\"github.com/daytonaio/runner/cmd/runner/config\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/runner\"\n\t\"github.com/gin-gonic/gin\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\n// TagImage godoc\n//\n//\t@Tags\t\t\tsnapshots\n//\t@Summary\t\tTag an image\n//\t@Deprecated\t\tNew snapshot tags are sent in PullSnapshot\n//\t@Description\tTag an existing local image with a new target reference\n//\t@Param\t\t\trequest\tbody\t\tdto.TagImageRequestDTO\ttrue\t\"Tag image request\"\n//\t@Success\t\t200\t\t{string}\tstring\t\t\t\t\t\"Image successfully tagged\"\n//\t@Failure\t\t400\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t{object}\tcommon_errors.ErrorResponse\n//\n//\t@Router\t\t\t/snapshots/tag [post]\n//\n//\t@id\t\t\t\tTagImage\nfunc TagImage(ctx *gin.Context) {\n\tvar request dto.TagImageRequestDTO\n\tif err := ctx.ShouldBindJSON(&request); err != nil {\n\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\texists, err := runner.Docker.ImageExists(ctx.Request.Context(), request.SourceImage, false)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tif !exists {\n\t\tctx.Error(common_errors.NewNotFoundError(fmt.Errorf(\"source image not found: %s\", request.SourceImage)))\n\t\treturn\n\t}\n\n\tif !strings.Contains(request.TargetImage, \":\") || strings.HasSuffix(request.TargetImage, \":\") {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"targetImage must include a valid tag\")))\n\t\treturn\n\t}\n\n\tif err := runner.Docker.TagImage(ctx.Request.Context(), request.SourceImage, request.TargetImage); err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, \"Image tagged successfully\")\n}\n\n// PullSnapshot godoc\n//\n//\t@Tags\t\t\tsnapshots\n//\t@Summary\t\tPull a snapshot\n//\t@Description\tPull a snapshot from a registry and optionally push to another registry. The operation runs asynchronously and returns 202 immediately.\n//\t@Param\t\t\trequest\tbody\t\tdto.PullSnapshotRequestDTO\ttrue\t\"Pull snapshot\"\n//\t@Success\t\t202\t\t{string}\tstring\t\t\t\t\t\t\"Snapshot pull started\"\n//\t@Failure\t\t400\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t{object}\tcommon_errors.ErrorResponse\n//\n//\t@Router\t\t\t/snapshots/pull [post]\n//\n//\t@id\t\t\t\tPullSnapshot\nfunc PullSnapshot(generalCtx context.Context, logger *slog.Logger) func(ctx *gin.Context) {\n\treturn func(ctx *gin.Context) {\n\t\tvar request dto.PullSnapshotRequestDTO\n\t\terr := ctx.ShouldBindJSON(&request)\n\t\tif err != nil {\n\t\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\t\treturn\n\t\t}\n\n\t\trunner, err := runner.GetInstance(nil)\n\t\tif err != nil {\n\t\t\tctx.Error(err)\n\t\t\treturn\n\t\t}\n\n\t\tcacheKey := request.Snapshot\n\t\tif request.DestinationRef != nil {\n\t\t\tcacheKey = *request.DestinationRef\n\t\t}\n\n\t\terr = runner.SnapshotErrorCache.RemoveError(generalCtx, cacheKey)\n\t\tif err != nil {\n\t\t\tlogger.ErrorContext(generalCtx, \"Failed to remove snapshot error cache entry\", \"cacheKey\", cacheKey, \"error\", err)\n\t\t}\n\n\t\tgo func() {\n\t\t\terr := runner.Docker.PullSnapshot(generalCtx, request)\n\t\t\tif err != nil {\n\t\t\t\tlogger.DebugContext(generalCtx, \"Pull snapshot failed\", \"cacheKey\", cacheKey, \"error\", err)\n\t\t\t\terr = runner.SnapshotErrorCache.SetError(generalCtx, cacheKey, err.Error())\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.ErrorContext(generalCtx, \"Failed to set snapshot error cache entry\", \"cacheKey\", cacheKey, \"error\", err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr = runner.SnapshotErrorCache.RemoveError(generalCtx, cacheKey)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.ErrorContext(generalCtx, \"Failed to remove snapshot error cache entry\", \"cacheKey\", cacheKey, \"error\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\n\t\tctx.JSON(http.StatusAccepted, \"Snapshot pull started\")\n\t}\n}\n\n// BuildSnapshot godoc\n//\n//\t@Tags\t\t\tsnapshots\n//\t@Summary\t\tBuild a snapshot\n//\t@Description\tBuild a snapshot from a Dockerfile and context hashes. The operation runs asynchronously and returns 202 immediately.\n//\t@Param\t\t\trequest\tbody\t\tdto.BuildSnapshotRequestDTO\ttrue\t\"Build snapshot request\"\n//\t@Success\t\t202\t\t{string}\tstring\t\t\t\t\t\t\"Snapshot build started\"\n//\t@Failure\t\t400\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t{object}\tcommon_errors.ErrorResponse\n//\n//\t@Router\t\t\t/snapshots/build [post]\n//\n//\t@id\t\t\t\tBuildSnapshot\nfunc BuildSnapshot(generalCtx context.Context, logger *slog.Logger) func(ctx *gin.Context) {\n\treturn func(ctx *gin.Context) {\n\t\tvar request dto.BuildSnapshotRequestDTO\n\t\terr := ctx.ShouldBindJSON(&request)\n\t\tif err != nil {\n\t\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\t\treturn\n\t\t}\n\n\t\tif !strings.Contains(request.Snapshot, \":\") || strings.HasSuffix(request.Snapshot, \":\") {\n\t\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"snapshot name must include a valid tag\")))\n\t\t\treturn\n\t\t}\n\n\t\trunner, err := runner.GetInstance(nil)\n\t\tif err != nil {\n\t\t\tctx.Error(err)\n\t\t\treturn\n\t\t}\n\n\t\terr = runner.SnapshotErrorCache.RemoveError(generalCtx, request.Snapshot)\n\t\tif err != nil {\n\t\t\tlogger.ErrorContext(generalCtx, \"Failed to remove snapshot error cache entry\", \"cacheKey\", request.Snapshot, \"error\", err)\n\t\t}\n\n\t\tgo func() {\n\t\t\terr := runner.Docker.BuildSnapshot(generalCtx, request)\n\t\t\tif err != nil {\n\t\t\t\tlogger.DebugContext(generalCtx, \"Build snapshot failed\", \"cacheKey\", request.Snapshot, \"error\", err)\n\t\t\t\terr = runner.SnapshotErrorCache.SetError(generalCtx, request.Snapshot, err.Error())\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.ErrorContext(generalCtx, \"Failed to set snapshot error cache entry\", \"cacheKey\", request.Snapshot, \"error\", err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr = runner.SnapshotErrorCache.RemoveError(generalCtx, request.Snapshot)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.ErrorContext(generalCtx, \"Failed to remove snapshot error cache entry\", \"cacheKey\", request.Snapshot, \"error\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\n\t\tctx.JSON(http.StatusAccepted, \"Snapshot build started\")\n\t}\n}\n\n// SnapshotExists godoc\n//\n//\t@Tags\t\t\tsnapshots\n//\t@Summary\t\tCheck if a snapshot exists\n//\t@Description\tCheck if a specified snapshot exists locally\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsnapshot\tquery\t\tstring\ttrue\t\"Snapshot name and tag\"\texample:\"nginx:latest\"\n//\t@Success\t\t200\t\t\t{object}\tSnapshotExistsResponse\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/snapshots/exists [get]\n//\n//\t@id\t\t\t\tSnapshotExists\nfunc SnapshotExists(ctx *gin.Context) {\n\tsnapshot := ctx.Query(\"snapshot\")\n\tif snapshot == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"snapshot parameter is required\")))\n\t\treturn\n\t}\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\texists, err := runner.Docker.ImageExists(ctx.Request.Context(), snapshot, false)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, SnapshotExistsResponse{\n\t\tExists: exists,\n\t})\n}\n\n// RemoveSnapshot godoc\n//\n//\t@Tags\t\t\tsnapshots\n//\t@Summary\t\tRemove a snapshot\n//\t@Description\tRemove a specified snapshot from the local system\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsnapshot\tquery\t\tstring\ttrue\t\"Snapshot name and tag\"\texample:\"nginx:latest\"\n//\t@Success\t\t200\t\t\t{string}\tstring\t\"Snapshot successfully removed\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t409\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/snapshots/remove [post]\n//\n//\t@id\t\t\t\tRemoveSnapshot\nfunc RemoveSnapshot(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tsnapshot := ctx.Query(\"snapshot\")\n\t\tif snapshot == \"\" {\n\t\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"snapshot parameter is required\")))\n\t\t\treturn\n\t\t}\n\n\t\trunner, err := runner.GetInstance(nil)\n\t\tif err != nil {\n\t\t\tctx.Error(err)\n\t\t\treturn\n\t\t}\n\n\t\terr = runner.Docker.RemoveImage(ctx.Request.Context(), snapshot, true)\n\t\tif err != nil {\n\t\t\tctx.Error(err)\n\t\t\treturn\n\t\t}\n\n\t\terr = runner.SnapshotErrorCache.RemoveError(ctx.Request.Context(), snapshot)\n\t\tif err != nil {\n\t\t\tlogger.ErrorContext(ctx.Request.Context(), \"Failed to remove snapshot error cache entry\", \"cacheKey\", snapshot, \"error\", err)\n\t\t}\n\n\t\tctx.JSON(http.StatusOK, \"Snapshot removed successfully\")\n\t}\n}\n\ntype SnapshotExistsResponse struct {\n\tExists bool `json:\"exists\" example:\"true\"`\n} //\t@name\tSnapshotExistsResponse\n\n// GetBuildLogs godoc\n//\n//\t@Tags\t\t\tsnapshots\n//\t@Summary\t\tGet build logs\n//\t@Description\tStream build logs\n//\t@Param\t\t\tsnapshotRef\tquery\t\tstring\ttrue\t\"Snapshot ref\"\n//\t@Param\t\t\tfollow\t\tquery\t\tboolean\tfalse\t\"Whether to follow the log output\"\n//\t@Success\t\t200\t\t\t{string}\tstring\t\"Build logs stream\"\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\n//\t@Router\t\t\t/snapshots/logs [get]\n//\n//\t@id\t\t\t\tGetBuildLogs\nfunc GetBuildLogs(logger *slog.Logger) gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\treqCtx := ctx.Request.Context()\n\t\tsnapshotRef := ctx.Query(\"snapshotRef\")\n\t\tif snapshotRef == \"\" {\n\t\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"snapshotRef parameter is required\")))\n\t\t\treturn\n\t\t}\n\n\t\tfollow := ctx.Query(\"follow\") == \"true\"\n\n\t\tlogFilePath, err := config.GetBuildLogFilePath(snapshotRef)\n\t\tif err != nil {\n\t\t\tctx.Error(common_errors.NewCustomError(http.StatusInternalServerError, err.Error(), \"INTERNAL_SERVER_ERROR\"))\n\t\t\treturn\n\t\t}\n\n\t\tif _, err := os.Stat(logFilePath); os.IsNotExist(err) {\n\t\t\tctx.Error(common_errors.NewNotFoundError(fmt.Errorf(\"build logs not found for ref: %s\", snapshotRef)))\n\t\t\treturn\n\t\t}\n\n\t\tctx.Header(\"Content-Type\", \"application/octet-stream\")\n\n\t\tfile, err := os.Open(logFilePath)\n\t\tif err != nil {\n\t\t\tctx.Error(common_errors.NewCustomError(http.StatusInternalServerError, err.Error(), \"INTERNAL_SERVER_ERROR\"))\n\t\t\treturn\n\t\t}\n\t\tdefer file.Close()\n\n\t\t// If not following, just return the entire file content\n\t\tif !follow {\n\t\t\t_, err = io.Copy(ctx.Writer, file)\n\t\t\tif err != nil {\n\t\t\t\tctx.Error(common_errors.NewCustomError(http.StatusInternalServerError, err.Error(), \"INTERNAL_SERVER_ERROR\"))\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\treader := bufio.NewReader(file)\n\t\trunner, err := runner.GetInstance(nil)\n\t\tif err != nil {\n\t\t\tctx.Error(err)\n\t\t\treturn\n\t\t}\n\n\t\tcheckSnapshotRef := snapshotRef\n\n\t\t// Fixed tag for instances where we are not looking for an entry with snapshot ID\n\t\tif strings.HasPrefix(snapshotRef, \"daytona\") {\n\t\t\tcheckSnapshotRef = snapshotRef + \":daytona\"\n\t\t}\n\n\t\tflusher, ok := ctx.Writer.(http.Flusher)\n\t\tif !ok {\n\t\t\tctx.Error(common_errors.NewCustomError(http.StatusInternalServerError, \"Streaming not supported\", \"STREAMING_NOT_SUPPORTED\"))\n\t\t\treturn\n\t\t}\n\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\tline, err := reader.ReadBytes('\\n')\n\t\t\t\tif err != nil && err != io.EOF {\n\t\t\t\t\tlogger.ErrorContext(reqCtx, \"Error reading log file\", \"error\", err)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif len(line) > 0 {\n\t\t\t\t\t_, writeErr := ctx.Writer.Write(line)\n\t\t\t\t\tif writeErr != nil {\n\t\t\t\t\t\tlogger.ErrorContext(reqCtx, \"Error writing to response\", \"error\", writeErr)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tflusher.Flush()\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\n\t\tfor {\n\t\t\texists, err := runner.Docker.ImageExists(ctx.Request.Context(), checkSnapshotRef, false)\n\t\t\tif err != nil {\n\t\t\t\tlogger.ErrorContext(reqCtx, \"Error checking build status\", \"error\", err)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif exists {\n\t\t\t\t// If snapshot exists, build is complete, allow time for the last logs to be written and break the loop\n\t\t\t\ttime.Sleep(1 * time.Second)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\ttime.Sleep(250 * time.Millisecond)\n\t\t}\n\t}\n}\n\n// GetSnapshotInfo godoc\n//\n//\t@Tags\t\t\tsnapshots\n//\t@Summary\t\tGet snapshot information\n//\t@Description\tGet information about a specified snapshot including size and entrypoint. Returns 422 if the last pull/build operation failed, with the error reason in the message.\n//\t@Produce\t\tjson\n//\t@Param\t\t\tsnapshot\tquery\t\tstring\ttrue\t\"Snapshot name and tag\"\texample:\"nginx:latest\"\n//\t@Success\t\t200\t\t\t{object}\tdto.SnapshotInfoResponse\n//\t@Failure\t\t400\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t422\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Router\t\t\t/snapshots/info [get]\n//\n//\t@id\t\t\t\tGetSnapshotInfo\nfunc GetSnapshotInfo(ctx *gin.Context) {\n\tsnapshot := ctx.Query(\"snapshot\")\n\tif snapshot == \"\" {\n\t\tctx.Error(common_errors.NewBadRequestError(errors.New(\"snapshot parameter is required\")))\n\t\treturn\n\t}\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\texists, err := runner.Docker.ImageExists(ctx.Request.Context(), snapshot, false)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tif !exists {\n\t\terrReason, err := runner.SnapshotErrorCache.GetError(ctx.Request.Context(), snapshot)\n\t\tif err == nil && errReason != nil {\n\t\t\tctx.Error(common_errors.NewUnprocessableEntityError(errors.New(*errReason)))\n\t\t\treturn\n\t\t}\n\t\tctx.Error(common_errors.NewNotFoundError(fmt.Errorf(\"snapshot not found: %s\", snapshot)))\n\t\treturn\n\t}\n\n\tinfo, err := runner.Docker.GetImageInfo(ctx.Request.Context(), snapshot)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, dto.SnapshotInfoResponse{\n\t\tName:       snapshot,\n\t\tSizeGB:     float64(info.Size) / (1024 * 1024 * 1024), // Convert bytes to GB\n\t\tEntrypoint: info.Entrypoint,\n\t\tCmd:        info.Cmd,\n\t\tHash:       dto.HashWithoutPrefix(info.Hash),\n\t})\n}\n\n// InspectSnapshotInRegistry godoc\n//\n//\t@Tags\t\t\tsnapshots\n//\t@Summary\t\tInspect a snapshot in a registry\n//\t@Description\tInspect a specified snapshot in a registry\n//\t@Produce\t\tjson\n//\t@Param\t\t\trequest\tbody\t\tdto.InspectSnapshotInRegistryRequestDTO\ttrue\t\"Inspect snapshot in registry request\"\n//\t@Success\t\t200\t\t{object}\tdto.SnapshotDigestResponse\n//\t@Failure\t\t400\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t401\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t404\t\t{object}\tcommon_errors.ErrorResponse\n//\t@Failure\t\t500\t\t{object}\tcommon_errors.ErrorResponse\n//\n//\t@Router\t\t\t/snapshots/inspect [post]\n//\t@id\t\t\t\tInspectSnapshotInRegistry\nfunc InspectSnapshotInRegistry(ctx *gin.Context) {\n\tvar request dto.InspectSnapshotInRegistryRequestDTO\n\terr := ctx.ShouldBindJSON(&request)\n\tif err != nil {\n\t\tctx.Error(common_errors.NewInvalidBodyRequestError(err))\n\t\treturn\n\t}\n\n\trunner, err := runner.GetInstance(nil)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tdigest, err := runner.Docker.InspectImageInRegistry(ctx.Request.Context(), request.Snapshot, request.Registry)\n\tif err != nil {\n\t\tctx.Error(err)\n\t\treturn\n\t}\n\n\tctx.JSON(http.StatusOK, dto.SnapshotDigestResponse{\n\t\tHash:   dto.HashWithoutPrefix(digest.Digest),\n\t\tSizeGB: float64(digest.Size) / (1024 * 1024 * 1024),\n\t})\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/docs/docs.go",
    "content": "// Package docs Code generated by swaggo/swag. DO NOT EDIT\npackage docs\n\nimport \"github.com/swaggo/swag\"\n\nconst docTemplate = `{\n    \"schemes\": {{ marshal .Schemes }},\n    \"swagger\": \"2.0\",\n    \"info\": {\n        \"description\": \"{{escape .Description}}\",\n        \"title\": \"{{.Title}}\",\n        \"contact\": {},\n        \"version\": \"{{.Version}}\"\n    },\n    \"host\": \"{{.Host}}\",\n    \"basePath\": \"{{.BasePath}}\",\n    \"paths\": {\n        \"/\": {\n            \"get\": {\n                \"description\": \"Health check\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"summary\": \"Health check\",\n                \"operationId\": \"HealthCheck\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"type\": \"object\",\n                            \"additionalProperties\": {\n                                \"type\": \"string\"\n                            }\n                        }\n                    }\n                }\n            }\n        },\n        \"/info\": {\n            \"get\": {\n                \"description\": \"Runner info with system metrics\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"summary\": \"Runner info\",\n                \"operationId\": \"RunnerInfo\",\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/RunnerInfoResponseDTO\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes\": {\n            \"post\": {\n                \"description\": \"Create a sandbox\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Create a sandbox\",\n                \"operationId\": \"Create\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Create sandbox\",\n                        \"name\": \"sandbox\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/CreateSandboxDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"201\": {\n                        \"description\": \"Created\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/StartSandboxResponse\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}\": {\n            \"get\": {\n                \"description\": \"Get sandbox info\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Get sandbox info\",\n                \"operationId\": \"Info\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Sandbox info\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SandboxInfoResponse\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/backup\": {\n            \"post\": {\n                \"description\": \"Create sandbox backup\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Create sandbox backup\",\n                \"operationId\": \"CreateBackup\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Create backup\",\n                        \"name\": \"sandbox\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/CreateBackupDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"201\": {\n                        \"description\": \"Backup started\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/destroy\": {\n            \"post\": {\n                \"description\": \"Destroy sandbox\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Destroy sandbox\",\n                \"operationId\": \"Destroy\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Sandbox destroyed\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/is-recoverable\": {\n            \"post\": {\n                \"description\": \"Check if the sandbox's error reason indicates a recoverable error\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Check if sandbox error is recoverable\",\n                \"operationId\": \"IsRecoverable\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Error reason to check\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/IsRecoverableDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/IsRecoverableResponse\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/network-settings\": {\n            \"get\": {\n                \"description\": \"Get sandbox network settings\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Get sandbox network settings\",\n                \"operationId\": \"GetNetworkSettings\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Network settings\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/UpdateNetworkSettingsDTO\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            },\n            \"post\": {\n                \"description\": \"Update sandbox network settings\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Update sandbox network settings\",\n                \"operationId\": \"UpdateNetworkSettings\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Update network settings\",\n                        \"name\": \"sandbox\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/UpdateNetworkSettingsDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Network settings updated\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/recover\": {\n            \"post\": {\n                \"description\": \"Recover sandbox from error state using specified recovery type\",\n                \"consumes\": [\n                    \"application/json\"\n                ],\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Recover sandbox from error state\",\n                \"operationId\": \"Recover\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Recovery parameters\",\n                        \"name\": \"recovery\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/RecoverSandboxDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Sandbox recovered\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/resize\": {\n            \"post\": {\n                \"description\": \"Resize sandbox\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Resize sandbox\",\n                \"operationId\": \"Resize\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Resize sandbox\",\n                        \"name\": \"sandbox\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ResizeSandboxDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Sandbox resized\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/start\": {\n            \"post\": {\n                \"description\": \"Start sandbox\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Start sandbox\",\n                \"operationId\": \"Start\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"description\": \"Metadata\",\n                        \"name\": \"metadata\",\n                        \"in\": \"body\",\n                        \"schema\": {\n                            \"type\": \"object\"\n                        }\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Auth token\",\n                        \"name\": \"token\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Sandbox started\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/StartSandboxResponse\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/stop\": {\n            \"post\": {\n                \"description\": \"Stop sandbox\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"sandbox\"\n                ],\n                \"summary\": \"Stop sandbox\",\n                \"operationId\": \"Stop\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Sandbox stopped\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/sandboxes/{sandboxId}/toolbox/{path}\": {\n            \"get\": {\n                \"description\": \"Forwards the request to the specified sandbox's container\",\n                \"tags\": [\n                    \"toolbox\"\n                ],\n                \"summary\": \"Proxy requests to the sandbox toolbox\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Path to forward\",\n                        \"name\": \"path\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Proxied response\",\n                        \"schema\": {}\n                    },\n                    \"400\": {\n                        \"description\": \"Bad request\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Sandbox container not found\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Sandbox container conflict\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal server error\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    }\n                }\n            },\n            \"post\": {\n                \"description\": \"Forwards the request to the specified sandbox's container\",\n                \"tags\": [\n                    \"toolbox\"\n                ],\n                \"summary\": \"Proxy requests to the sandbox toolbox\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Path to forward\",\n                        \"name\": \"path\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Proxied response\",\n                        \"schema\": {}\n                    },\n                    \"400\": {\n                        \"description\": \"Bad request\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Sandbox container not found\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Sandbox container conflict\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal server error\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    }\n                }\n            },\n            \"delete\": {\n                \"description\": \"Forwards the request to the specified sandbox's container\",\n                \"tags\": [\n                    \"toolbox\"\n                ],\n                \"summary\": \"Proxy requests to the sandbox toolbox\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Sandbox ID\",\n                        \"name\": \"sandboxId\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Path to forward\",\n                        \"name\": \"path\",\n                        \"in\": \"path\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Proxied response\",\n                        \"schema\": {}\n                    },\n                    \"400\": {\n                        \"description\": \"Bad request\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Sandbox container not found\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Sandbox container conflict\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal server error\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/snapshots/build\": {\n            \"post\": {\n                \"description\": \"Build a snapshot from a Dockerfile and context hashes. The operation runs asynchronously and returns 202 immediately.\",\n                \"tags\": [\n                    \"snapshots\"\n                ],\n                \"summary\": \"Build a snapshot\",\n                \"operationId\": \"BuildSnapshot\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Build snapshot request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/BuildSnapshotRequestDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"202\": {\n                        \"description\": \"Snapshot build started\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/snapshots/exists\": {\n            \"get\": {\n                \"description\": \"Check if a specified snapshot exists locally\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"snapshots\"\n                ],\n                \"summary\": \"Check if a snapshot exists\",\n                \"operationId\": \"SnapshotExists\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Snapshot name and tag\",\n                        \"name\": \"snapshot\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SnapshotExistsResponse\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/snapshots/info\": {\n            \"get\": {\n                \"description\": \"Get information about a specified snapshot including size and entrypoint. Returns 422 if the last pull/build operation failed, with the error reason in the message.\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"snapshots\"\n                ],\n                \"summary\": \"Get snapshot information\",\n                \"operationId\": \"GetSnapshotInfo\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Snapshot name and tag\",\n                        \"name\": \"snapshot\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SnapshotInfoResponse\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"422\": {\n                        \"description\": \"Unprocessable Entity\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/snapshots/inspect\": {\n            \"post\": {\n                \"description\": \"Inspect a specified snapshot in a registry\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"snapshots\"\n                ],\n                \"summary\": \"Inspect a snapshot in a registry\",\n                \"operationId\": \"InspectSnapshotInRegistry\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Inspect snapshot in registry request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/InspectSnapshotInRegistryRequest\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"OK\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/SnapshotDigestResponse\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/snapshots/logs\": {\n            \"get\": {\n                \"description\": \"Stream build logs\",\n                \"tags\": [\n                    \"snapshots\"\n                ],\n                \"summary\": \"Get build logs\",\n                \"operationId\": \"GetBuildLogs\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Snapshot ref\",\n                        \"name\": \"snapshotRef\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    },\n                    {\n                        \"type\": \"boolean\",\n                        \"description\": \"Whether to follow the log output\",\n                        \"name\": \"follow\",\n                        \"in\": \"query\"\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Build logs stream\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/snapshots/pull\": {\n            \"post\": {\n                \"description\": \"Pull a snapshot from a registry and optionally push to another registry. The operation runs asynchronously and returns 202 immediately.\",\n                \"tags\": [\n                    \"snapshots\"\n                ],\n                \"summary\": \"Pull a snapshot\",\n                \"operationId\": \"PullSnapshot\",\n                \"parameters\": [\n                    {\n                        \"description\": \"Pull snapshot\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/PullSnapshotRequestDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"202\": {\n                        \"description\": \"Snapshot pull started\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/snapshots/remove\": {\n            \"post\": {\n                \"description\": \"Remove a specified snapshot from the local system\",\n                \"produces\": [\n                    \"application/json\"\n                ],\n                \"tags\": [\n                    \"snapshots\"\n                ],\n                \"summary\": \"Remove a snapshot\",\n                \"operationId\": \"RemoveSnapshot\",\n                \"parameters\": [\n                    {\n                        \"type\": \"string\",\n                        \"description\": \"Snapshot name and tag\",\n                        \"name\": \"snapshot\",\n                        \"in\": \"query\",\n                        \"required\": true\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Snapshot successfully removed\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        },\n        \"/snapshots/tag\": {\n            \"post\": {\n                \"description\": \"Tag an existing local image with a new target reference\",\n                \"tags\": [\n                    \"snapshots\"\n                ],\n                \"summary\": \"Tag an image\",\n                \"operationId\": \"TagImage\",\n                \"deprecated\": true,\n                \"parameters\": [\n                    {\n                        \"description\": \"Tag image request\",\n                        \"name\": \"request\",\n                        \"in\": \"body\",\n                        \"required\": true,\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/TagImageRequestDTO\"\n                        }\n                    }\n                ],\n                \"responses\": {\n                    \"200\": {\n                        \"description\": \"Image successfully tagged\",\n                        \"schema\": {\n                            \"type\": \"string\"\n                        }\n                    },\n                    \"400\": {\n                        \"description\": \"Bad Request\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"401\": {\n                        \"description\": \"Unauthorized\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"404\": {\n                        \"description\": \"Not Found\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"409\": {\n                        \"description\": \"Conflict\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    },\n                    \"500\": {\n                        \"description\": \"Internal Server Error\",\n                        \"schema\": {\n                            \"$ref\": \"#/definitions/ErrorResponse\"\n                        }\n                    }\n                }\n            }\n        }\n    },\n    \"definitions\": {\n        \"BuildSnapshotRequestDTO\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"dockerfile\",\n                \"organizationId\"\n            ],\n            \"properties\": {\n                \"context\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"dockerfile\": {\n                    \"type\": \"string\"\n                },\n                \"organizationId\": {\n                    \"type\": \"string\"\n                },\n                \"pushToInternalRegistry\": {\n                    \"type\": \"boolean\"\n                },\n                \"registry\": {\n                    \"$ref\": \"#/definitions/RegistryDTO\"\n                },\n                \"snapshot\": {\n                    \"description\": \"Snapshot ID and tag or the build's hash\",\n                    \"type\": \"string\"\n                },\n                \"sourceRegistries\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/RegistryDTO\"\n                    }\n                }\n            }\n        },\n        \"CreateBackupDTO\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"registry\",\n                \"snapshot\"\n            ],\n            \"properties\": {\n                \"registry\": {\n                    \"$ref\": \"#/definitions/RegistryDTO\"\n                },\n                \"snapshot\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"CreateSandboxDTO\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"id\",\n                \"osUser\",\n                \"snapshot\",\n                \"userId\"\n            ],\n            \"properties\": {\n                \"authToken\": {\n                    \"type\": \"string\"\n                },\n                \"cpuQuota\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                },\n                \"entrypoint\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"env\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"fromVolumeId\": {\n                    \"type\": \"string\"\n                },\n                \"gpuQuota\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 0\n                },\n                \"id\": {\n                    \"type\": \"string\"\n                },\n                \"memoryQuota\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                },\n                \"metadata\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"networkAllowList\": {\n                    \"type\": \"string\"\n                },\n                \"networkBlockAll\": {\n                    \"type\": \"boolean\"\n                },\n                \"organizationId\": {\n                    \"description\": \"Nullable for backward compatibility\",\n                    \"type\": \"string\"\n                },\n                \"osUser\": {\n                    \"type\": \"string\"\n                },\n                \"otelEndpoint\": {\n                    \"type\": \"string\"\n                },\n                \"regionId\": {\n                    \"type\": \"string\"\n                },\n                \"registry\": {\n                    \"$ref\": \"#/definitions/RegistryDTO\"\n                },\n                \"skipStart\": {\n                    \"type\": \"boolean\"\n                },\n                \"snapshot\": {\n                    \"type\": \"string\"\n                },\n                \"storageQuota\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                },\n                \"userId\": {\n                    \"type\": \"string\"\n                },\n                \"volumes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/dto.VolumeDTO\"\n                    }\n                }\n            }\n        },\n        \"ErrorResponse\": {\n            \"description\": \"Error response\",\n            \"type\": \"object\",\n            \"required\": [\n                \"message\",\n                \"path\",\n                \"statusCode\",\n                \"timestamp\"\n            ],\n            \"properties\": {\n                \"code\": {\n                    \"type\": \"string\",\n                    \"example\": \"BAD_REQUEST\"\n                },\n                \"message\": {\n                    \"type\": \"string\",\n                    \"example\": \"Bad request\"\n                },\n                \"method\": {\n                    \"type\": \"string\",\n                    \"example\": \"GET\"\n                },\n                \"path\": {\n                    \"type\": \"string\",\n                    \"example\": \"/api/resource\"\n                },\n                \"statusCode\": {\n                    \"type\": \"integer\",\n                    \"example\": 400\n                },\n                \"timestamp\": {\n                    \"type\": \"string\",\n                    \"example\": \"2023-01-01T12:00:00Z\"\n                }\n            }\n        },\n        \"InspectSnapshotInRegistryRequest\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"snapshot\"\n            ],\n            \"properties\": {\n                \"registry\": {\n                    \"$ref\": \"#/definitions/RegistryDTO\"\n                },\n                \"snapshot\": {\n                    \"type\": \"string\",\n                    \"example\": \"nginx:latest\"\n                }\n            }\n        },\n        \"IsRecoverableDTO\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"errorReason\"\n            ],\n            \"properties\": {\n                \"errorReason\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"IsRecoverableResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"recoverable\": {\n                    \"type\": \"boolean\"\n                }\n            }\n        },\n        \"PullSnapshotRequestDTO\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"snapshot\"\n            ],\n            \"properties\": {\n                \"destinationRef\": {\n                    \"type\": \"string\"\n                },\n                \"destinationRegistry\": {\n                    \"$ref\": \"#/definitions/RegistryDTO\"\n                },\n                \"newTag\": {\n                    \"type\": \"string\"\n                },\n                \"registry\": {\n                    \"$ref\": \"#/definitions/RegistryDTO\"\n                },\n                \"snapshot\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"RecoverSandboxDTO\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"errorReason\",\n                \"osUser\",\n                \"userId\"\n            ],\n            \"properties\": {\n                \"backupErrorReason\": {\n                    \"type\": \"string\"\n                },\n                \"cpuQuota\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                },\n                \"env\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                        \"type\": \"string\"\n                    }\n                },\n                \"errorReason\": {\n                    \"type\": \"string\"\n                },\n                \"fromVolumeId\": {\n                    \"type\": \"string\"\n                },\n                \"gpuQuota\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 0\n                },\n                \"memoryQuota\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                },\n                \"networkAllowList\": {\n                    \"type\": \"string\"\n                },\n                \"networkBlockAll\": {\n                    \"type\": \"boolean\"\n                },\n                \"osUser\": {\n                    \"type\": \"string\"\n                },\n                \"snapshot\": {\n                    \"type\": \"string\"\n                },\n                \"storageQuota\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                },\n                \"userId\": {\n                    \"type\": \"string\"\n                },\n                \"volumes\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/dto.VolumeDTO\"\n                    }\n                }\n            }\n        },\n        \"RegistryDTO\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"url\"\n            ],\n            \"properties\": {\n                \"password\": {\n                    \"type\": \"string\"\n                },\n                \"project\": {\n                    \"type\": \"string\"\n                },\n                \"url\": {\n                    \"type\": \"string\"\n                },\n                \"username\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"ResizeSandboxDTO\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"cpu\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                },\n                \"disk\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                },\n                \"gpu\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 0\n                },\n                \"memory\": {\n                    \"type\": \"integer\",\n                    \"minimum\": 1\n                }\n            }\n        },\n        \"RunnerInfoResponseDTO\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"appVersion\": {\n                    \"type\": \"string\"\n                },\n                \"metrics\": {\n                    \"$ref\": \"#/definitions/RunnerMetrics\"\n                },\n                \"serviceHealth\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"$ref\": \"#/definitions/RunnerServiceInfo\"\n                    }\n                }\n            }\n        },\n        \"RunnerMetrics\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"currentAllocatedCpu\": {\n                    \"type\": \"number\"\n                },\n                \"currentAllocatedDiskGiB\": {\n                    \"type\": \"number\"\n                },\n                \"currentAllocatedMemoryGiB\": {\n                    \"type\": \"number\"\n                },\n                \"currentCpuLoadAverage\": {\n                    \"type\": \"number\"\n                },\n                \"currentCpuUsagePercentage\": {\n                    \"type\": \"number\"\n                },\n                \"currentDiskUsagePercentage\": {\n                    \"type\": \"number\"\n                },\n                \"currentMemoryUsagePercentage\": {\n                    \"type\": \"number\"\n                },\n                \"currentSnapshotCount\": {\n                    \"type\": \"integer\"\n                },\n                \"currentStartedSandboxes\": {\n                    \"type\": \"integer\"\n                }\n            }\n        },\n        \"RunnerServiceInfo\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"healthy\",\n                \"serviceName\"\n            ],\n            \"properties\": {\n                \"errorReason\": {\n                    \"type\": \"string\"\n                },\n                \"healthy\": {\n                    \"type\": \"boolean\"\n                },\n                \"serviceName\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"SandboxInfoResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"backupError\": {\n                    \"type\": \"string\"\n                },\n                \"backupState\": {\n                    \"$ref\": \"#/definitions/enums.BackupState\"\n                },\n                \"daemonVersion\": {\n                    \"type\": \"string\"\n                },\n                \"state\": {\n                    \"$ref\": \"#/definitions/enums.SandboxState\"\n                }\n            }\n        },\n        \"SnapshotDigestResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"hash\": {\n                    \"type\": \"string\",\n                    \"example\": \"a7be6198544f09a75b26e6376459b47c5b9972e7351d440e092c4faa9ea064ff\"\n                },\n                \"sizeGB\": {\n                    \"type\": \"number\",\n                    \"example\": 0.13\n                }\n            }\n        },\n        \"SnapshotExistsResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"exists\": {\n                    \"type\": \"boolean\",\n                    \"example\": true\n                }\n            }\n        },\n        \"SnapshotInfoResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"cmd\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    },\n                    \"example\": [\n                        \"[\\\"nginx\\\"\",\n                        \"\\\"-g\\\"\",\n                        \"\\\"daemon off;\\\"]\"\n                    ]\n                },\n                \"entrypoint\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                        \"type\": \"string\"\n                    },\n                    \"example\": [\n                        \"[\\\"nginx\\\"\",\n                        \"\\\"-g\\\"\",\n                        \"\\\"daemon off;\\\"]\"\n                    ]\n                },\n                \"hash\": {\n                    \"type\": \"string\",\n                    \"example\": \"a7be6198544f09a75b26e6376459b47c5b9972e7351d440e092c4faa9ea064ff\"\n                },\n                \"name\": {\n                    \"type\": \"string\",\n                    \"example\": \"nginx:latest\"\n                },\n                \"sizeGB\": {\n                    \"type\": \"number\",\n                    \"example\": 0.13\n                }\n            }\n        },\n        \"StartSandboxResponse\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"daemonVersion\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"TagImageRequestDTO\": {\n            \"type\": \"object\",\n            \"required\": [\n                \"sourceImage\",\n                \"targetImage\"\n            ],\n            \"properties\": {\n                \"sourceImage\": {\n                    \"type\": \"string\"\n                },\n                \"targetImage\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"UpdateNetworkSettingsDTO\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"networkAllowList\": {\n                    \"type\": \"string\"\n                },\n                \"networkBlockAll\": {\n                    \"type\": \"boolean\"\n                },\n                \"networkLimitEgress\": {\n                    \"type\": \"boolean\"\n                }\n            }\n        },\n        \"dto.VolumeDTO\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"mountPath\": {\n                    \"type\": \"string\"\n                },\n                \"subpath\": {\n                    \"type\": \"string\"\n                },\n                \"volumeId\": {\n                    \"type\": \"string\"\n                }\n            }\n        },\n        \"enums.BackupState\": {\n            \"type\": \"string\",\n            \"enum\": [\n                \"NONE\",\n                \"PENDING\",\n                \"IN_PROGRESS\",\n                \"COMPLETED\",\n                \"FAILED\"\n            ],\n            \"x-enum-varnames\": [\n                \"BackupStateNone\",\n                \"BackupStatePending\",\n                \"BackupStateInProgress\",\n                \"BackupStateCompleted\",\n                \"BackupStateFailed\"\n            ]\n        },\n        \"enums.SandboxState\": {\n            \"type\": \"string\",\n            \"enum\": [\n                \"creating\",\n                \"restoring\",\n                \"destroyed\",\n                \"destroying\",\n                \"started\",\n                \"stopped\",\n                \"starting\",\n                \"stopping\",\n                \"resizing\",\n                \"error\",\n                \"unknown\",\n                \"pulling_snapshot\"\n            ],\n            \"x-enum-varnames\": [\n                \"SandboxStateCreating\",\n                \"SandboxStateRestoring\",\n                \"SandboxStateDestroyed\",\n                \"SandboxStateDestroying\",\n                \"SandboxStateStarted\",\n                \"SandboxStateStopped\",\n                \"SandboxStateStarting\",\n                \"SandboxStateStopping\",\n                \"SandboxStateResizing\",\n                \"SandboxStateError\",\n                \"SandboxStateUnknown\",\n                \"SandboxStatePullingSnapshot\"\n            ]\n        }\n    },\n    \"securityDefinitions\": {\n        \"Bearer\": {\n            \"description\": \"Type \\\"Bearer\\\" followed by a space and an API token.\",\n            \"type\": \"apiKey\",\n            \"name\": \"Authorization\",\n            \"in\": \"header\"\n        }\n    },\n    \"security\": [\n        {\n            \"Bearer\": []\n        }\n    ]\n}`\n\n// SwaggerInfo holds exported Swagger Info so clients can modify it\nvar SwaggerInfo = &swag.Spec{\n\tVersion:          \"v0.0.0-dev\",\n\tHost:             \"\",\n\tBasePath:         \"\",\n\tSchemes:          []string{},\n\tTitle:            \"Daytona Runner API\",\n\tDescription:      \"Daytona Runner API\",\n\tInfoInstanceName: \"swagger\",\n\tSwaggerTemplate:  docTemplate,\n\tLeftDelim:        \"{{\",\n\tRightDelim:       \"}}\",\n}\n\nfunc init() {\n\tswag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/docs/swagger.json",
    "content": "{\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"Daytona Runner API\",\n    \"title\": \"Daytona Runner API\",\n    \"contact\": {},\n    \"version\": \"v0.0.0-dev\"\n  },\n  \"paths\": {\n    \"/\": {\n      \"get\": {\n        \"description\": \"Health check\",\n        \"produces\": [\"application/json\"],\n        \"summary\": \"Health check\",\n        \"operationId\": \"HealthCheck\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"additionalProperties\": {\n                \"type\": \"string\"\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/info\": {\n      \"get\": {\n        \"description\": \"Runner info with system metrics\",\n        \"produces\": [\"application/json\"],\n        \"summary\": \"Runner info\",\n        \"operationId\": \"RunnerInfo\",\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/RunnerInfoResponseDTO\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes\": {\n      \"post\": {\n        \"description\": \"Create a sandbox\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Create a sandbox\",\n        \"operationId\": \"Create\",\n        \"parameters\": [\n          {\n            \"description\": \"Create sandbox\",\n            \"name\": \"sandbox\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/CreateSandboxDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Created\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/StartSandboxResponse\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}\": {\n      \"get\": {\n        \"description\": \"Get sandbox info\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Get sandbox info\",\n        \"operationId\": \"Info\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Sandbox info\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/SandboxInfoResponse\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/backup\": {\n      \"post\": {\n        \"description\": \"Create sandbox backup\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Create sandbox backup\",\n        \"operationId\": \"CreateBackup\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Create backup\",\n            \"name\": \"sandbox\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/CreateBackupDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"Backup started\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/destroy\": {\n      \"post\": {\n        \"description\": \"Destroy sandbox\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Destroy sandbox\",\n        \"operationId\": \"Destroy\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Sandbox destroyed\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/is-recoverable\": {\n      \"post\": {\n        \"description\": \"Check if the sandbox's error reason indicates a recoverable error\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Check if sandbox error is recoverable\",\n        \"operationId\": \"IsRecoverable\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Error reason to check\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/IsRecoverableDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/IsRecoverableResponse\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/network-settings\": {\n      \"get\": {\n        \"description\": \"Get sandbox network settings\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Get sandbox network settings\",\n        \"operationId\": \"GetNetworkSettings\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Network settings\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/UpdateNetworkSettingsDTO\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Update sandbox network settings\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Update sandbox network settings\",\n        \"operationId\": \"UpdateNetworkSettings\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Update network settings\",\n            \"name\": \"sandbox\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/UpdateNetworkSettingsDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Network settings updated\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/recover\": {\n      \"post\": {\n        \"description\": \"Recover sandbox from error state using specified recovery type\",\n        \"consumes\": [\"application/json\"],\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Recover sandbox from error state\",\n        \"operationId\": \"Recover\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Recovery parameters\",\n            \"name\": \"recovery\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/RecoverSandboxDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Sandbox recovered\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/resize\": {\n      \"post\": {\n        \"description\": \"Resize sandbox\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Resize sandbox\",\n        \"operationId\": \"Resize\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Resize sandbox\",\n            \"name\": \"sandbox\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/ResizeSandboxDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Sandbox resized\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/start\": {\n      \"post\": {\n        \"description\": \"Start sandbox\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Start sandbox\",\n        \"operationId\": \"Start\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"description\": \"Metadata\",\n            \"name\": \"metadata\",\n            \"in\": \"body\",\n            \"schema\": {\n              \"type\": \"object\"\n            }\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Auth token\",\n            \"name\": \"token\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Sandbox started\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/StartSandboxResponse\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/stop\": {\n      \"post\": {\n        \"description\": \"Stop sandbox\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"sandbox\"],\n        \"summary\": \"Stop sandbox\",\n        \"operationId\": \"Stop\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Sandbox stopped\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/sandboxes/{sandboxId}/toolbox/{path}\": {\n      \"get\": {\n        \"description\": \"Forwards the request to the specified sandbox's container\",\n        \"tags\": [\"toolbox\"],\n        \"summary\": \"Proxy requests to the sandbox toolbox\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Path to forward\",\n            \"name\": \"path\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Proxied response\",\n            \"schema\": {}\n          },\n          \"400\": {\n            \"description\": \"Bad request\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Sandbox container not found\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Sandbox container conflict\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal server error\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          }\n        }\n      },\n      \"post\": {\n        \"description\": \"Forwards the request to the specified sandbox's container\",\n        \"tags\": [\"toolbox\"],\n        \"summary\": \"Proxy requests to the sandbox toolbox\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Path to forward\",\n            \"name\": \"path\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Proxied response\",\n            \"schema\": {}\n          },\n          \"400\": {\n            \"description\": \"Bad request\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Sandbox container not found\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Sandbox container conflict\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal server error\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          }\n        }\n      },\n      \"delete\": {\n        \"description\": \"Forwards the request to the specified sandbox's container\",\n        \"tags\": [\"toolbox\"],\n        \"summary\": \"Proxy requests to the sandbox toolbox\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Sandbox ID\",\n            \"name\": \"sandboxId\",\n            \"in\": \"path\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"description\": \"Path to forward\",\n            \"name\": \"path\",\n            \"in\": \"path\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Proxied response\",\n            \"schema\": {}\n          },\n          \"400\": {\n            \"description\": \"Bad request\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Sandbox container not found\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Sandbox container conflict\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal server error\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          }\n        }\n      }\n    },\n    \"/snapshots/build\": {\n      \"post\": {\n        \"description\": \"Build a snapshot from a Dockerfile and context hashes. The operation runs asynchronously and returns 202 immediately.\",\n        \"tags\": [\"snapshots\"],\n        \"summary\": \"Build a snapshot\",\n        \"operationId\": \"BuildSnapshot\",\n        \"parameters\": [\n          {\n            \"description\": \"Build snapshot request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/BuildSnapshotRequestDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"202\": {\n            \"description\": \"Snapshot build started\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/snapshots/exists\": {\n      \"get\": {\n        \"description\": \"Check if a specified snapshot exists locally\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"snapshots\"],\n        \"summary\": \"Check if a snapshot exists\",\n        \"operationId\": \"SnapshotExists\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Snapshot name and tag\",\n            \"name\": \"snapshot\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/SnapshotExistsResponse\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/snapshots/info\": {\n      \"get\": {\n        \"description\": \"Get information about a specified snapshot including size and entrypoint. Returns 422 if the last pull/build operation failed, with the error reason in the message.\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"snapshots\"],\n        \"summary\": \"Get snapshot information\",\n        \"operationId\": \"GetSnapshotInfo\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Snapshot name and tag\",\n            \"name\": \"snapshot\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/SnapshotInfoResponse\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"422\": {\n            \"description\": \"Unprocessable Entity\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/snapshots/inspect\": {\n      \"post\": {\n        \"description\": \"Inspect a specified snapshot in a registry\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"snapshots\"],\n        \"summary\": \"Inspect a snapshot in a registry\",\n        \"operationId\": \"InspectSnapshotInRegistry\",\n        \"parameters\": [\n          {\n            \"description\": \"Inspect snapshot in registry request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/InspectSnapshotInRegistryRequest\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"OK\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/SnapshotDigestResponse\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/snapshots/logs\": {\n      \"get\": {\n        \"description\": \"Stream build logs\",\n        \"tags\": [\"snapshots\"],\n        \"summary\": \"Get build logs\",\n        \"operationId\": \"GetBuildLogs\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Snapshot ref\",\n            \"name\": \"snapshotRef\",\n            \"in\": \"query\",\n            \"required\": true\n          },\n          {\n            \"type\": \"boolean\",\n            \"description\": \"Whether to follow the log output\",\n            \"name\": \"follow\",\n            \"in\": \"query\"\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Build logs stream\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/snapshots/pull\": {\n      \"post\": {\n        \"description\": \"Pull a snapshot from a registry and optionally push to another registry. The operation runs asynchronously and returns 202 immediately.\",\n        \"tags\": [\"snapshots\"],\n        \"summary\": \"Pull a snapshot\",\n        \"operationId\": \"PullSnapshot\",\n        \"parameters\": [\n          {\n            \"description\": \"Pull snapshot\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/PullSnapshotRequestDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"202\": {\n            \"description\": \"Snapshot pull started\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/snapshots/remove\": {\n      \"post\": {\n        \"description\": \"Remove a specified snapshot from the local system\",\n        \"produces\": [\"application/json\"],\n        \"tags\": [\"snapshots\"],\n        \"summary\": \"Remove a snapshot\",\n        \"operationId\": \"RemoveSnapshot\",\n        \"parameters\": [\n          {\n            \"type\": \"string\",\n            \"description\": \"Snapshot name and tag\",\n            \"name\": \"snapshot\",\n            \"in\": \"query\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Snapshot successfully removed\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    },\n    \"/snapshots/tag\": {\n      \"post\": {\n        \"description\": \"Tag an existing local image with a new target reference\",\n        \"tags\": [\"snapshots\"],\n        \"summary\": \"Tag an image\",\n        \"operationId\": \"TagImage\",\n        \"deprecated\": true,\n        \"parameters\": [\n          {\n            \"description\": \"Tag image request\",\n            \"name\": \"request\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"$ref\": \"#/definitions/TagImageRequestDTO\"\n            }\n          }\n        ],\n        \"responses\": {\n          \"200\": {\n            \"description\": \"Image successfully tagged\",\n            \"schema\": {\n              \"type\": \"string\"\n            }\n          },\n          \"400\": {\n            \"description\": \"Bad Request\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"401\": {\n            \"description\": \"Unauthorized\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"404\": {\n            \"description\": \"Not Found\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"409\": {\n            \"description\": \"Conflict\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          },\n          \"500\": {\n            \"description\": \"Internal Server Error\",\n            \"schema\": {\n              \"$ref\": \"#/definitions/ErrorResponse\"\n            }\n          }\n        }\n      }\n    }\n  },\n  \"definitions\": {\n    \"BuildSnapshotRequestDTO\": {\n      \"type\": \"object\",\n      \"required\": [\"dockerfile\", \"organizationId\"],\n      \"properties\": {\n        \"context\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"dockerfile\": {\n          \"type\": \"string\"\n        },\n        \"organizationId\": {\n          \"type\": \"string\"\n        },\n        \"pushToInternalRegistry\": {\n          \"type\": \"boolean\"\n        },\n        \"registry\": {\n          \"$ref\": \"#/definitions/RegistryDTO\"\n        },\n        \"snapshot\": {\n          \"description\": \"Snapshot ID and tag or the build's hash\",\n          \"type\": \"string\"\n        },\n        \"sourceRegistries\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RegistryDTO\"\n          }\n        }\n      }\n    },\n    \"CreateBackupDTO\": {\n      \"type\": \"object\",\n      \"required\": [\"registry\", \"snapshot\"],\n      \"properties\": {\n        \"registry\": {\n          \"$ref\": \"#/definitions/RegistryDTO\"\n        },\n        \"snapshot\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"CreateSandboxDTO\": {\n      \"type\": \"object\",\n      \"required\": [\"id\", \"osUser\", \"snapshot\", \"userId\"],\n      \"properties\": {\n        \"authToken\": {\n          \"type\": \"string\"\n        },\n        \"cpuQuota\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        },\n        \"entrypoint\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"fromVolumeId\": {\n          \"type\": \"string\"\n        },\n        \"gpuQuota\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"id\": {\n          \"type\": \"string\"\n        },\n        \"memoryQuota\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        },\n        \"metadata\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"networkAllowList\": {\n          \"type\": \"string\"\n        },\n        \"networkBlockAll\": {\n          \"type\": \"boolean\"\n        },\n        \"organizationId\": {\n          \"description\": \"Nullable for backward compatibility\",\n          \"type\": \"string\"\n        },\n        \"osUser\": {\n          \"type\": \"string\"\n        },\n        \"otelEndpoint\": {\n          \"type\": \"string\"\n        },\n        \"regionId\": {\n          \"type\": \"string\"\n        },\n        \"registry\": {\n          \"$ref\": \"#/definitions/RegistryDTO\"\n        },\n        \"skipStart\": {\n          \"type\": \"boolean\"\n        },\n        \"snapshot\": {\n          \"type\": \"string\"\n        },\n        \"storageQuota\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        },\n        \"userId\": {\n          \"type\": \"string\"\n        },\n        \"volumes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/dto.VolumeDTO\"\n          }\n        }\n      }\n    },\n    \"ErrorResponse\": {\n      \"description\": \"Error response\",\n      \"type\": \"object\",\n      \"required\": [\"message\", \"path\", \"statusCode\", \"timestamp\"],\n      \"properties\": {\n        \"code\": {\n          \"type\": \"string\",\n          \"example\": \"BAD_REQUEST\"\n        },\n        \"message\": {\n          \"type\": \"string\",\n          \"example\": \"Bad request\"\n        },\n        \"method\": {\n          \"type\": \"string\",\n          \"example\": \"GET\"\n        },\n        \"path\": {\n          \"type\": \"string\",\n          \"example\": \"/api/resource\"\n        },\n        \"statusCode\": {\n          \"type\": \"integer\",\n          \"example\": 400\n        },\n        \"timestamp\": {\n          \"type\": \"string\",\n          \"example\": \"2023-01-01T12:00:00Z\"\n        }\n      }\n    },\n    \"InspectSnapshotInRegistryRequest\": {\n      \"type\": \"object\",\n      \"required\": [\"snapshot\"],\n      \"properties\": {\n        \"registry\": {\n          \"$ref\": \"#/definitions/RegistryDTO\"\n        },\n        \"snapshot\": {\n          \"type\": \"string\",\n          \"example\": \"nginx:latest\"\n        }\n      }\n    },\n    \"IsRecoverableDTO\": {\n      \"type\": \"object\",\n      \"required\": [\"errorReason\"],\n      \"properties\": {\n        \"errorReason\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"IsRecoverableResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"recoverable\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"PullSnapshotRequestDTO\": {\n      \"type\": \"object\",\n      \"required\": [\"snapshot\"],\n      \"properties\": {\n        \"destinationRef\": {\n          \"type\": \"string\"\n        },\n        \"destinationRegistry\": {\n          \"$ref\": \"#/definitions/RegistryDTO\"\n        },\n        \"newTag\": {\n          \"type\": \"string\"\n        },\n        \"registry\": {\n          \"$ref\": \"#/definitions/RegistryDTO\"\n        },\n        \"snapshot\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"RecoverSandboxDTO\": {\n      \"type\": \"object\",\n      \"required\": [\"errorReason\", \"osUser\", \"userId\"],\n      \"properties\": {\n        \"backupErrorReason\": {\n          \"type\": \"string\"\n        },\n        \"cpuQuota\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        },\n        \"env\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"type\": \"string\"\n          }\n        },\n        \"errorReason\": {\n          \"type\": \"string\"\n        },\n        \"fromVolumeId\": {\n          \"type\": \"string\"\n        },\n        \"gpuQuota\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"memoryQuota\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        },\n        \"networkAllowList\": {\n          \"type\": \"string\"\n        },\n        \"networkBlockAll\": {\n          \"type\": \"boolean\"\n        },\n        \"osUser\": {\n          \"type\": \"string\"\n        },\n        \"snapshot\": {\n          \"type\": \"string\"\n        },\n        \"storageQuota\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        },\n        \"userId\": {\n          \"type\": \"string\"\n        },\n        \"volumes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/dto.VolumeDTO\"\n          }\n        }\n      }\n    },\n    \"RegistryDTO\": {\n      \"type\": \"object\",\n      \"required\": [\"url\"],\n      \"properties\": {\n        \"password\": {\n          \"type\": \"string\"\n        },\n        \"project\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"username\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"ResizeSandboxDTO\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cpu\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        },\n        \"disk\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        },\n        \"gpu\": {\n          \"type\": \"integer\",\n          \"minimum\": 0\n        },\n        \"memory\": {\n          \"type\": \"integer\",\n          \"minimum\": 1\n        }\n      }\n    },\n    \"RunnerInfoResponseDTO\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"appVersion\": {\n          \"type\": \"string\"\n        },\n        \"metrics\": {\n          \"$ref\": \"#/definitions/RunnerMetrics\"\n        },\n        \"serviceHealth\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/RunnerServiceInfo\"\n          }\n        }\n      }\n    },\n    \"RunnerMetrics\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"currentAllocatedCpu\": {\n          \"type\": \"number\"\n        },\n        \"currentAllocatedDiskGiB\": {\n          \"type\": \"number\"\n        },\n        \"currentAllocatedMemoryGiB\": {\n          \"type\": \"number\"\n        },\n        \"currentCpuLoadAverage\": {\n          \"type\": \"number\"\n        },\n        \"currentCpuUsagePercentage\": {\n          \"type\": \"number\"\n        },\n        \"currentDiskUsagePercentage\": {\n          \"type\": \"number\"\n        },\n        \"currentMemoryUsagePercentage\": {\n          \"type\": \"number\"\n        },\n        \"currentSnapshotCount\": {\n          \"type\": \"integer\"\n        },\n        \"currentStartedSandboxes\": {\n          \"type\": \"integer\"\n        }\n      }\n    },\n    \"RunnerServiceInfo\": {\n      \"type\": \"object\",\n      \"required\": [\"healthy\", \"serviceName\"],\n      \"properties\": {\n        \"errorReason\": {\n          \"type\": \"string\"\n        },\n        \"healthy\": {\n          \"type\": \"boolean\"\n        },\n        \"serviceName\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"SandboxInfoResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"backupError\": {\n          \"type\": \"string\"\n        },\n        \"backupState\": {\n          \"$ref\": \"#/definitions/enums.BackupState\"\n        },\n        \"daemonVersion\": {\n          \"type\": \"string\"\n        },\n        \"state\": {\n          \"$ref\": \"#/definitions/enums.SandboxState\"\n        }\n      }\n    },\n    \"SnapshotDigestResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"hash\": {\n          \"type\": \"string\",\n          \"example\": \"a7be6198544f09a75b26e6376459b47c5b9972e7351d440e092c4faa9ea064ff\"\n        },\n        \"sizeGB\": {\n          \"type\": \"number\",\n          \"example\": 0.13\n        }\n      }\n    },\n    \"SnapshotExistsResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"exists\": {\n          \"type\": \"boolean\",\n          \"example\": true\n        }\n      }\n    },\n    \"SnapshotInfoResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"cmd\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"example\": [\"[\\\"nginx\\\"\", \"\\\"-g\\\"\", \"\\\"daemon off;\\\"]\"]\n        },\n        \"entrypoint\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"example\": [\"[\\\"nginx\\\"\", \"\\\"-g\\\"\", \"\\\"daemon off;\\\"]\"]\n        },\n        \"hash\": {\n          \"type\": \"string\",\n          \"example\": \"a7be6198544f09a75b26e6376459b47c5b9972e7351d440e092c4faa9ea064ff\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"example\": \"nginx:latest\"\n        },\n        \"sizeGB\": {\n          \"type\": \"number\",\n          \"example\": 0.13\n        }\n      }\n    },\n    \"StartSandboxResponse\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"daemonVersion\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"TagImageRequestDTO\": {\n      \"type\": \"object\",\n      \"required\": [\"sourceImage\", \"targetImage\"],\n      \"properties\": {\n        \"sourceImage\": {\n          \"type\": \"string\"\n        },\n        \"targetImage\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"UpdateNetworkSettingsDTO\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"networkAllowList\": {\n          \"type\": \"string\"\n        },\n        \"networkBlockAll\": {\n          \"type\": \"boolean\"\n        },\n        \"networkLimitEgress\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"dto.VolumeDTO\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"mountPath\": {\n          \"type\": \"string\"\n        },\n        \"subpath\": {\n          \"type\": \"string\"\n        },\n        \"volumeId\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"enums.BackupState\": {\n      \"type\": \"string\",\n      \"enum\": [\"NONE\", \"PENDING\", \"IN_PROGRESS\", \"COMPLETED\", \"FAILED\"],\n      \"x-enum-varnames\": [\n        \"BackupStateNone\",\n        \"BackupStatePending\",\n        \"BackupStateInProgress\",\n        \"BackupStateCompleted\",\n        \"BackupStateFailed\"\n      ]\n    },\n    \"enums.SandboxState\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"creating\",\n        \"restoring\",\n        \"destroyed\",\n        \"destroying\",\n        \"started\",\n        \"stopped\",\n        \"starting\",\n        \"stopping\",\n        \"resizing\",\n        \"error\",\n        \"unknown\",\n        \"pulling_snapshot\"\n      ],\n      \"x-enum-varnames\": [\n        \"SandboxStateCreating\",\n        \"SandboxStateRestoring\",\n        \"SandboxStateDestroyed\",\n        \"SandboxStateDestroying\",\n        \"SandboxStateStarted\",\n        \"SandboxStateStopped\",\n        \"SandboxStateStarting\",\n        \"SandboxStateStopping\",\n        \"SandboxStateResizing\",\n        \"SandboxStateError\",\n        \"SandboxStateUnknown\",\n        \"SandboxStatePullingSnapshot\"\n      ]\n    }\n  },\n  \"securityDefinitions\": {\n    \"Bearer\": {\n      \"description\": \"Type \\\"Bearer\\\" followed by a space and an API token.\",\n      \"type\": \"apiKey\",\n      \"name\": \"Authorization\",\n      \"in\": \"header\"\n    }\n  },\n  \"security\": [\n    {\n      \"Bearer\": []\n    }\n  ]\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/docs/swagger.yaml",
    "content": "definitions:\n  BuildSnapshotRequestDTO:\n    properties:\n      context:\n        items:\n          type: string\n        type: array\n      dockerfile:\n        type: string\n      organizationId:\n        type: string\n      pushToInternalRegistry:\n        type: boolean\n      registry:\n        $ref: '#/definitions/RegistryDTO'\n      snapshot:\n        description: Snapshot ID and tag or the build's hash\n        type: string\n      sourceRegistries:\n        items:\n          $ref: '#/definitions/RegistryDTO'\n        type: array\n    required:\n      - dockerfile\n      - organizationId\n    type: object\n  CreateBackupDTO:\n    properties:\n      registry:\n        $ref: '#/definitions/RegistryDTO'\n      snapshot:\n        type: string\n    required:\n      - registry\n      - snapshot\n    type: object\n  CreateSandboxDTO:\n    properties:\n      authToken:\n        type: string\n      cpuQuota:\n        minimum: 1\n        type: integer\n      entrypoint:\n        items:\n          type: string\n        type: array\n      env:\n        additionalProperties:\n          type: string\n        type: object\n      fromVolumeId:\n        type: string\n      gpuQuota:\n        minimum: 0\n        type: integer\n      id:\n        type: string\n      memoryQuota:\n        minimum: 1\n        type: integer\n      metadata:\n        additionalProperties:\n          type: string\n        type: object\n      networkAllowList:\n        type: string\n      networkBlockAll:\n        type: boolean\n      organizationId:\n        description: Nullable for backward compatibility\n        type: string\n      osUser:\n        type: string\n      otelEndpoint:\n        type: string\n      regionId:\n        type: string\n      registry:\n        $ref: '#/definitions/RegistryDTO'\n      skipStart:\n        type: boolean\n      snapshot:\n        type: string\n      storageQuota:\n        minimum: 1\n        type: integer\n      userId:\n        type: string\n      volumes:\n        items:\n          $ref: '#/definitions/dto.VolumeDTO'\n        type: array\n    required:\n      - id\n      - osUser\n      - snapshot\n      - userId\n    type: object\n  ErrorResponse:\n    description: Error response\n    properties:\n      code:\n        example: BAD_REQUEST\n        type: string\n      message:\n        example: Bad request\n        type: string\n      method:\n        example: GET\n        type: string\n      path:\n        example: /api/resource\n        type: string\n      statusCode:\n        example: 400\n        type: integer\n      timestamp:\n        example: '2023-01-01T12:00:00Z'\n        type: string\n    required:\n      - message\n      - path\n      - statusCode\n      - timestamp\n    type: object\n  InspectSnapshotInRegistryRequest:\n    properties:\n      registry:\n        $ref: '#/definitions/RegistryDTO'\n      snapshot:\n        example: nginx:latest\n        type: string\n    required:\n      - snapshot\n    type: object\n  IsRecoverableDTO:\n    properties:\n      errorReason:\n        type: string\n    required:\n      - errorReason\n    type: object\n  IsRecoverableResponse:\n    properties:\n      recoverable:\n        type: boolean\n    type: object\n  PullSnapshotRequestDTO:\n    properties:\n      destinationRef:\n        type: string\n      destinationRegistry:\n        $ref: '#/definitions/RegistryDTO'\n      newTag:\n        type: string\n      registry:\n        $ref: '#/definitions/RegistryDTO'\n      snapshot:\n        type: string\n    required:\n      - snapshot\n    type: object\n  RecoverSandboxDTO:\n    properties:\n      backupErrorReason:\n        type: string\n      cpuQuota:\n        minimum: 1\n        type: integer\n      env:\n        additionalProperties:\n          type: string\n        type: object\n      errorReason:\n        type: string\n      fromVolumeId:\n        type: string\n      gpuQuota:\n        minimum: 0\n        type: integer\n      memoryQuota:\n        minimum: 1\n        type: integer\n      networkAllowList:\n        type: string\n      networkBlockAll:\n        type: boolean\n      osUser:\n        type: string\n      snapshot:\n        type: string\n      storageQuota:\n        minimum: 1\n        type: integer\n      userId:\n        type: string\n      volumes:\n        items:\n          $ref: '#/definitions/dto.VolumeDTO'\n        type: array\n    required:\n      - errorReason\n      - osUser\n      - userId\n    type: object\n  RegistryDTO:\n    properties:\n      password:\n        type: string\n      project:\n        type: string\n      url:\n        type: string\n      username:\n        type: string\n    required:\n      - url\n    type: object\n  ResizeSandboxDTO:\n    properties:\n      cpu:\n        minimum: 1\n        type: integer\n      disk:\n        minimum: 1\n        type: integer\n      gpu:\n        minimum: 0\n        type: integer\n      memory:\n        minimum: 1\n        type: integer\n    type: object\n  RunnerInfoResponseDTO:\n    properties:\n      appVersion:\n        type: string\n      metrics:\n        $ref: '#/definitions/RunnerMetrics'\n      serviceHealth:\n        items:\n          $ref: '#/definitions/RunnerServiceInfo'\n        type: array\n    type: object\n  RunnerMetrics:\n    properties:\n      currentAllocatedCpu:\n        type: number\n      currentAllocatedDiskGiB:\n        type: number\n      currentAllocatedMemoryGiB:\n        type: number\n      currentCpuLoadAverage:\n        type: number\n      currentCpuUsagePercentage:\n        type: number\n      currentDiskUsagePercentage:\n        type: number\n      currentMemoryUsagePercentage:\n        type: number\n      currentSnapshotCount:\n        type: integer\n      currentStartedSandboxes:\n        type: integer\n    type: object\n  RunnerServiceInfo:\n    properties:\n      errorReason:\n        type: string\n      healthy:\n        type: boolean\n      serviceName:\n        type: string\n    required:\n      - healthy\n      - serviceName\n    type: object\n  SandboxInfoResponse:\n    properties:\n      backupError:\n        type: string\n      backupState:\n        $ref: '#/definitions/enums.BackupState'\n      daemonVersion:\n        type: string\n      state:\n        $ref: '#/definitions/enums.SandboxState'\n    type: object\n  SnapshotDigestResponse:\n    properties:\n      hash:\n        example: a7be6198544f09a75b26e6376459b47c5b9972e7351d440e092c4faa9ea064ff\n        type: string\n      sizeGB:\n        example: 0.13\n        type: number\n    type: object\n  SnapshotExistsResponse:\n    properties:\n      exists:\n        example: true\n        type: boolean\n    type: object\n  SnapshotInfoResponse:\n    properties:\n      cmd:\n        example:\n          - '[\"nginx\"'\n          - '\"-g\"'\n          - '\"daemon off;\"]'\n        items:\n          type: string\n        type: array\n      entrypoint:\n        example:\n          - '[\"nginx\"'\n          - '\"-g\"'\n          - '\"daemon off;\"]'\n        items:\n          type: string\n        type: array\n      hash:\n        example: a7be6198544f09a75b26e6376459b47c5b9972e7351d440e092c4faa9ea064ff\n        type: string\n      name:\n        example: nginx:latest\n        type: string\n      sizeGB:\n        example: 0.13\n        type: number\n    type: object\n  StartSandboxResponse:\n    properties:\n      daemonVersion:\n        type: string\n    type: object\n  TagImageRequestDTO:\n    properties:\n      sourceImage:\n        type: string\n      targetImage:\n        type: string\n    required:\n      - sourceImage\n      - targetImage\n    type: object\n  UpdateNetworkSettingsDTO:\n    properties:\n      networkAllowList:\n        type: string\n      networkBlockAll:\n        type: boolean\n      networkLimitEgress:\n        type: boolean\n    type: object\n  dto.VolumeDTO:\n    properties:\n      mountPath:\n        type: string\n      subpath:\n        type: string\n      volumeId:\n        type: string\n    type: object\n  enums.BackupState:\n    enum:\n      - NONE\n      - PENDING\n      - IN_PROGRESS\n      - COMPLETED\n      - FAILED\n    type: string\n    x-enum-varnames:\n      - BackupStateNone\n      - BackupStatePending\n      - BackupStateInProgress\n      - BackupStateCompleted\n      - BackupStateFailed\n  enums.SandboxState:\n    enum:\n      - creating\n      - restoring\n      - destroyed\n      - destroying\n      - started\n      - stopped\n      - starting\n      - stopping\n      - resizing\n      - error\n      - unknown\n      - pulling_snapshot\n    type: string\n    x-enum-varnames:\n      - SandboxStateCreating\n      - SandboxStateRestoring\n      - SandboxStateDestroyed\n      - SandboxStateDestroying\n      - SandboxStateStarted\n      - SandboxStateStopped\n      - SandboxStateStarting\n      - SandboxStateStopping\n      - SandboxStateResizing\n      - SandboxStateError\n      - SandboxStateUnknown\n      - SandboxStatePullingSnapshot\ninfo:\n  contact: {}\n  description: Daytona Runner API\n  title: Daytona Runner API\n  version: v0.0.0-dev\npaths:\n  /:\n    get:\n      description: Health check\n      operationId: HealthCheck\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            additionalProperties:\n              type: string\n            type: object\n      summary: Health check\n  /info:\n    get:\n      description: Runner info with system metrics\n      operationId: RunnerInfo\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/RunnerInfoResponseDTO'\n      summary: Runner info\n  /sandboxes:\n    post:\n      description: Create a sandbox\n      operationId: Create\n      parameters:\n        - description: Create sandbox\n          in: body\n          name: sandbox\n          required: true\n          schema:\n            $ref: '#/definitions/CreateSandboxDTO'\n      produces:\n        - application/json\n      responses:\n        '201':\n          description: Created\n          schema:\n            $ref: '#/definitions/StartSandboxResponse'\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Create a sandbox\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}:\n    get:\n      description: Get sandbox info\n      operationId: Info\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Sandbox info\n          schema:\n            $ref: '#/definitions/SandboxInfoResponse'\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Get sandbox info\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/backup:\n    post:\n      description: Create sandbox backup\n      operationId: CreateBackup\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Create backup\n          in: body\n          name: sandbox\n          required: true\n          schema:\n            $ref: '#/definitions/CreateBackupDTO'\n      produces:\n        - application/json\n      responses:\n        '201':\n          description: Backup started\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Create sandbox backup\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/destroy:\n    post:\n      description: Destroy sandbox\n      operationId: Destroy\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Sandbox destroyed\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Destroy sandbox\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/is-recoverable:\n    post:\n      consumes:\n        - application/json\n      description: Check if the sandbox's error reason indicates a recoverable error\n      operationId: IsRecoverable\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Error reason to check\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/IsRecoverableDTO'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/IsRecoverableResponse'\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Check if sandbox error is recoverable\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/network-settings:\n    get:\n      description: Get sandbox network settings\n      operationId: GetNetworkSettings\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Network settings\n          schema:\n            $ref: '#/definitions/UpdateNetworkSettingsDTO'\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Get sandbox network settings\n      tags:\n        - sandbox\n    post:\n      description: Update sandbox network settings\n      operationId: UpdateNetworkSettings\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Update network settings\n          in: body\n          name: sandbox\n          required: true\n          schema:\n            $ref: '#/definitions/UpdateNetworkSettingsDTO'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Network settings updated\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Update sandbox network settings\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/recover:\n    post:\n      consumes:\n        - application/json\n      description: Recover sandbox from error state using specified recovery type\n      operationId: Recover\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Recovery parameters\n          in: body\n          name: recovery\n          required: true\n          schema:\n            $ref: '#/definitions/RecoverSandboxDTO'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Sandbox recovered\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Recover sandbox from error state\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/resize:\n    post:\n      description: Resize sandbox\n      operationId: Resize\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Resize sandbox\n          in: body\n          name: sandbox\n          required: true\n          schema:\n            $ref: '#/definitions/ResizeSandboxDTO'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Sandbox resized\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Resize sandbox\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/start:\n    post:\n      description: Start sandbox\n      operationId: Start\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Metadata\n          in: body\n          name: metadata\n          schema:\n            type: object\n        - description: Auth token\n          in: query\n          name: token\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Sandbox started\n          schema:\n            $ref: '#/definitions/StartSandboxResponse'\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Start sandbox\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/stop:\n    post:\n      description: Stop sandbox\n      operationId: Stop\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Sandbox stopped\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Stop sandbox\n      tags:\n        - sandbox\n  /sandboxes/{sandboxId}/toolbox/{path}:\n    delete:\n      description: Forwards the request to the specified sandbox's container\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Path to forward\n          in: path\n          name: path\n          required: true\n          type: string\n      responses:\n        '200':\n          description: Proxied response\n          schema: {}\n        '400':\n          description: Bad request\n          schema:\n            type: string\n        '401':\n          description: Unauthorized\n          schema:\n            type: string\n        '404':\n          description: Sandbox container not found\n          schema:\n            type: string\n        '409':\n          description: Sandbox container conflict\n          schema:\n            type: string\n        '500':\n          description: Internal server error\n          schema:\n            type: string\n      summary: Proxy requests to the sandbox toolbox\n      tags:\n        - toolbox\n    get:\n      description: Forwards the request to the specified sandbox's container\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Path to forward\n          in: path\n          name: path\n          required: true\n          type: string\n      responses:\n        '200':\n          description: Proxied response\n          schema: {}\n        '400':\n          description: Bad request\n          schema:\n            type: string\n        '401':\n          description: Unauthorized\n          schema:\n            type: string\n        '404':\n          description: Sandbox container not found\n          schema:\n            type: string\n        '409':\n          description: Sandbox container conflict\n          schema:\n            type: string\n        '500':\n          description: Internal server error\n          schema:\n            type: string\n      summary: Proxy requests to the sandbox toolbox\n      tags:\n        - toolbox\n    post:\n      description: Forwards the request to the specified sandbox's container\n      parameters:\n        - description: Sandbox ID\n          in: path\n          name: sandboxId\n          required: true\n          type: string\n        - description: Path to forward\n          in: path\n          name: path\n          required: true\n          type: string\n      responses:\n        '200':\n          description: Proxied response\n          schema: {}\n        '400':\n          description: Bad request\n          schema:\n            type: string\n        '401':\n          description: Unauthorized\n          schema:\n            type: string\n        '404':\n          description: Sandbox container not found\n          schema:\n            type: string\n        '409':\n          description: Sandbox container conflict\n          schema:\n            type: string\n        '500':\n          description: Internal server error\n          schema:\n            type: string\n      summary: Proxy requests to the sandbox toolbox\n      tags:\n        - toolbox\n  /snapshots/build:\n    post:\n      description: Build a snapshot from a Dockerfile and context hashes. The operation\n        runs asynchronously and returns 202 immediately.\n      operationId: BuildSnapshot\n      parameters:\n        - description: Build snapshot request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/BuildSnapshotRequestDTO'\n      responses:\n        '202':\n          description: Snapshot build started\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Build a snapshot\n      tags:\n        - snapshots\n  /snapshots/exists:\n    get:\n      description: Check if a specified snapshot exists locally\n      operationId: SnapshotExists\n      parameters:\n        - description: Snapshot name and tag\n          in: query\n          name: snapshot\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/SnapshotExistsResponse'\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Check if a snapshot exists\n      tags:\n        - snapshots\n  /snapshots/info:\n    get:\n      description: Get information about a specified snapshot including size and entrypoint.\n        Returns 422 if the last pull/build operation failed, with the error reason\n        in the message.\n      operationId: GetSnapshotInfo\n      parameters:\n        - description: Snapshot name and tag\n          in: query\n          name: snapshot\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/SnapshotInfoResponse'\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '422':\n          description: Unprocessable Entity\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Get snapshot information\n      tags:\n        - snapshots\n  /snapshots/inspect:\n    post:\n      description: Inspect a specified snapshot in a registry\n      operationId: InspectSnapshotInRegistry\n      parameters:\n        - description: Inspect snapshot in registry request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/InspectSnapshotInRegistryRequest'\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: OK\n          schema:\n            $ref: '#/definitions/SnapshotDigestResponse'\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Inspect a snapshot in a registry\n      tags:\n        - snapshots\n  /snapshots/logs:\n    get:\n      description: Stream build logs\n      operationId: GetBuildLogs\n      parameters:\n        - description: Snapshot ref\n          in: query\n          name: snapshotRef\n          required: true\n          type: string\n        - description: Whether to follow the log output\n          in: query\n          name: follow\n          type: boolean\n      responses:\n        '200':\n          description: Build logs stream\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Get build logs\n      tags:\n        - snapshots\n  /snapshots/pull:\n    post:\n      description: Pull a snapshot from a registry and optionally push to another\n        registry. The operation runs asynchronously and returns 202 immediately.\n      operationId: PullSnapshot\n      parameters:\n        - description: Pull snapshot\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/PullSnapshotRequestDTO'\n      responses:\n        '202':\n          description: Snapshot pull started\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Pull a snapshot\n      tags:\n        - snapshots\n  /snapshots/remove:\n    post:\n      description: Remove a specified snapshot from the local system\n      operationId: RemoveSnapshot\n      parameters:\n        - description: Snapshot name and tag\n          in: query\n          name: snapshot\n          required: true\n          type: string\n      produces:\n        - application/json\n      responses:\n        '200':\n          description: Snapshot successfully removed\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Remove a snapshot\n      tags:\n        - snapshots\n  /snapshots/tag:\n    post:\n      deprecated: true\n      description: Tag an existing local image with a new target reference\n      operationId: TagImage\n      parameters:\n        - description: Tag image request\n          in: body\n          name: request\n          required: true\n          schema:\n            $ref: '#/definitions/TagImageRequestDTO'\n      responses:\n        '200':\n          description: Image successfully tagged\n          schema:\n            type: string\n        '400':\n          description: Bad Request\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '401':\n          description: Unauthorized\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '404':\n          description: Not Found\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '409':\n          description: Conflict\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n        '500':\n          description: Internal Server Error\n          schema:\n            $ref: '#/definitions/ErrorResponse'\n      summary: Tag an image\n      tags:\n        - snapshots\nsecurity:\n  - Bearer: []\nsecurityDefinitions:\n  Bearer:\n    description: Type \"Bearer\" followed by a space and an API token.\n    in: header\n    name: Authorization\n    type: apiKey\nswagger: '2.0'\n"
  },
  {
    "path": "apps/runner/pkg/api/dto/backup.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage dto\n\ntype CreateBackupDTO struct {\n\tRegistry RegistryDTO `json:\"registry\" validate:\"required\"`\n\tSnapshot string      `json:\"snapshot\" validate:\"required\"`\n} //\t@name\tCreateBackupDTO\n"
  },
  {
    "path": "apps/runner/pkg/api/dto/image.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage dto\n\ntype PullSnapshotRequestDTO struct {\n\tSnapshot            string       `json:\"snapshot\" validate:\"required\"`\n\tRegistry            *RegistryDTO `json:\"registry,omitempty\"`\n\tDestinationRegistry *RegistryDTO `json:\"destinationRegistry,omitempty\"`\n\tDestinationRef      *string      `json:\"destinationRef,omitempty\"`\n\tNewTag              *string      `json:\"newTag,omitempty\"`\n} //\t@name\tPullSnapshotRequestDTO\n\ntype BuildSnapshotRequestDTO struct {\n\tSnapshot               string        `json:\"snapshot,omitempty\"` // Snapshot ID and tag or the build's hash\n\tSourceRegistries       []RegistryDTO `json:\"sourceRegistries,omitempty\"`\n\tRegistry               *RegistryDTO  `json:\"registry,omitempty\"`\n\tDockerfile             string        `json:\"dockerfile\" validate:\"required\"`\n\tOrganizationId         string        `json:\"organizationId\" validate:\"required\"`\n\tContext                []string      `json:\"context\"`\n\tPushToInternalRegistry bool          `json:\"pushToInternalRegistry\"`\n} //\t@name\tBuildSnapshotRequestDTO\n\ntype TagImageRequestDTO struct {\n\tSourceImage string `json:\"sourceImage\" validate:\"required\"`\n\tTargetImage string `json:\"targetImage\" validate:\"required\"`\n} //\t@name\tTagImageRequestDTO\n"
  },
  {
    "path": "apps/runner/pkg/api/dto/info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage dto\n\ntype RunnerMetrics struct {\n\tCurrentCpuLoadAverage        float64 `json:\"currentCpuLoadAverage\"`\n\tCurrentCpuUsagePercentage    float64 `json:\"currentCpuUsagePercentage\"`\n\tCurrentMemoryUsagePercentage float64 `json:\"currentMemoryUsagePercentage\"`\n\tCurrentDiskUsagePercentage   float64 `json:\"currentDiskUsagePercentage\"`\n\tCurrentAllocatedCpu          float64 `json:\"currentAllocatedCpu\"`\n\tCurrentAllocatedMemoryGiB    float64 `json:\"currentAllocatedMemoryGiB\"`\n\tCurrentAllocatedDiskGiB      float64 `json:\"currentAllocatedDiskGiB\"`\n\tCurrentSnapshotCount         int     `json:\"currentSnapshotCount\"`\n\tCurrentStartedSandboxes      int64   `json:\"currentStartedSandboxes\"`\n} //\t@name\tRunnerMetrics\n\ntype RunnerServiceInfo struct {\n\tServiceName string  `json:\"serviceName\" validate:\"required\"`\n\tHealthy     bool    `json:\"healthy\" validate:\"required\"`\n\tErrorReason *string `json:\"errorReason,omitempty\"`\n} // @name RunnerServiceInfo\n\ntype RunnerInfoResponseDTO struct {\n\tServiceHealth []*RunnerServiceInfo `json:\"serviceHealth,omitempty\"`\n\tMetrics       *RunnerMetrics       `json:\"metrics,omitempty\"`\n\tAppVersion    string               `json:\"appVersion\"`\n} //\t@name\tRunnerInfoResponseDTO\n"
  },
  {
    "path": "apps/runner/pkg/api/dto/registry.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage dto\n\ntype RegistryDTO struct {\n\tUrl      string  `json:\"url\" validate:\"required\"`\n\tProject  *string `json:\"project\" validate:\"optional,omitempty\"`\n\tUsername *string `json:\"username\" validate:\"omitempty\"`\n\tPassword *string `json:\"password\" validate:\"omitempty\"`\n} //\t@name\tRegistryDTO\n\nfunc (r *RegistryDTO) HasAuth() bool {\n\treturn r.Username != nil && r.Password != nil && *r.Username != \"\" && *r.Password != \"\"\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/dto/sandbox.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage dto\n\ntype CreateSandboxDTO struct {\n\tId               string            `json:\"id\" validate:\"required\"`\n\tFromVolumeId     string            `json:\"fromVolumeId,omitempty\"`\n\tUserId           string            `json:\"userId\" validate:\"required\"`\n\tSnapshot         string            `json:\"snapshot\" validate:\"required\"`\n\tOsUser           string            `json:\"osUser\" validate:\"required\"`\n\tCpuQuota         int64             `json:\"cpuQuota\" validate:\"min=1\"`\n\tGpuQuota         int64             `json:\"gpuQuota\" validate:\"min=0\"`\n\tMemoryQuota      int64             `json:\"memoryQuota\" validate:\"min=1\"`\n\tStorageQuota     int64             `json:\"storageQuota\" validate:\"min=1\"`\n\tEnv              map[string]string `json:\"env,omitempty\"`\n\tRegistry         *RegistryDTO      `json:\"registry,omitempty\"`\n\tEntrypoint       []string          `json:\"entrypoint,omitempty\"`\n\tVolumes          []VolumeDTO       `json:\"volumes,omitempty\"`\n\tNetworkBlockAll  *bool             `json:\"networkBlockAll,omitempty\"`\n\tNetworkAllowList *string           `json:\"networkAllowList,omitempty\"`\n\tMetadata         map[string]string `json:\"metadata,omitempty\"`\n\tAuthToken        *string           `json:\"authToken,omitempty\"`\n\tOtelEndpoint     *string           `json:\"otelEndpoint,omitempty\"`\n\tSkipStart        *bool             `json:\"skipStart,omitempty\"`\n\n\t// Nullable for backward compatibility\n\tOrganizationId *string `json:\"organizationId,omitempty\"`\n\tRegionId       *string `json:\"regionId,omitempty\"`\n} //\t@name\tCreateSandboxDTO\n\ntype ResizeSandboxDTO struct {\n\tCpu    int64 `json:\"cpu,omitempty\" validate:\"omitempty,min=1\"`\n\tGpu    int64 `json:\"gpu,omitempty\" validate:\"omitempty,min=0\"`\n\tMemory int64 `json:\"memory,omitempty\" validate:\"omitempty,min=1\"`\n\tDisk   int64 `json:\"disk,omitempty\" validate:\"omitempty,min=1\"`\n} //\t@name\tResizeSandboxDTO\n\ntype UpdateNetworkSettingsDTO struct {\n\tNetworkBlockAll    *bool   `json:\"networkBlockAll,omitempty\"`\n\tNetworkAllowList   *string `json:\"networkAllowList,omitempty\"`\n\tNetworkLimitEgress *bool   `json:\"networkLimitEgress,omitempty\"`\n} //\t@name\tUpdateNetworkSettingsDTO\n\ntype RecoverSandboxDTO struct {\n\tFromVolumeId      string            `json:\"fromVolumeId,omitempty\"`\n\tUserId            string            `json:\"userId\" validate:\"required\"`\n\tSnapshot          *string           `json:\"snapshot,omitempty\"`\n\tOsUser            string            `json:\"osUser\" validate:\"required\"`\n\tCpuQuota          int64             `json:\"cpuQuota\" validate:\"min=1\"`\n\tGpuQuota          int64             `json:\"gpuQuota\" validate:\"min=0\"`\n\tMemoryQuota       int64             `json:\"memoryQuota\" validate:\"min=1\"`\n\tStorageQuota      int64             `json:\"storageQuota\" validate:\"min=1\"`\n\tEnv               map[string]string `json:\"env,omitempty\"`\n\tVolumes           []VolumeDTO       `json:\"volumes,omitempty\"`\n\tNetworkBlockAll   *bool             `json:\"networkBlockAll,omitempty\"`\n\tNetworkAllowList  *string           `json:\"networkAllowList,omitempty\"`\n\tErrorReason       string            `json:\"errorReason\" validate:\"required\"`\n\tBackupErrorReason string            `json:\"backupErrorReason,omitempty\"`\n} //\t@name\tRecoverSandboxDTO\n\ntype IsRecoverableDTO struct {\n\tErrorReason string `json:\"errorReason\" validate:\"required\"`\n} //\t@name\tIsRecoverableDTO\n\ntype IsRecoverableResponse struct {\n\tRecoverable bool `json:\"recoverable\"`\n} //\t@name\tIsRecoverableResponse\ntype StartSandboxResponse struct {\n\tDaemonVersion string `json:\"daemonVersion\"`\n} //\t@name\tStartSandboxResponse\n"
  },
  {
    "path": "apps/runner/pkg/api/dto/snapshot.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage dto\n\nimport \"strings\"\n\ntype SnapshotInfoResponse struct {\n\tName       string   `json:\"name\" example:\"nginx:latest\"`\n\tSizeGB     float64  `json:\"sizeGB\" example:\"0.13\"`\n\tEntrypoint []string `json:\"entrypoint,omitempty\" example:\"[\\\"nginx\\\",\\\"-g\\\",\\\"daemon off;\\\"]\"`\n\tCmd        []string `json:\"cmd,omitempty\" example:\"[\\\"nginx\\\",\\\"-g\\\",\\\"daemon off;\\\"]\"`\n\tHash       string   `json:\"hash,omitempty\" example:\"a7be6198544f09a75b26e6376459b47c5b9972e7351d440e092c4faa9ea064ff\"`\n} //\t@name\tSnapshotInfoResponse\n\ntype SnapshotDigestResponse struct {\n\tHash   string  `json:\"hash\" example:\"a7be6198544f09a75b26e6376459b47c5b9972e7351d440e092c4faa9ea064ff\"`\n\tSizeGB float64 `json:\"sizeGB\" example:\"0.13\"`\n} //\t@name\tSnapshotDigestResponse\n\ntype InspectSnapshotInRegistryRequestDTO struct {\n\tSnapshot string       `json:\"snapshot\" validate:\"required\" example:\"nginx:latest\"`\n\tRegistry *RegistryDTO `json:\"registry,omitempty\"`\n} //\t@name\tInspectSnapshotInRegistryRequest\n\nfunc HashWithoutPrefix(hash string) string {\n\treturn strings.TrimPrefix(hash, \"sha256:\")\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/dto/volume.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage dto\n\ntype VolumeDTO struct {\n\tVolumeId  string  `json:\"volumeId\"`\n\tMountPath string  `json:\"mountPath\"`\n\tSubpath   *string `json:\"subpath,omitempty\"`\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/middlewares/auth.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage middlewares\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/runner/internal/constants\"\n\t\"github.com/gin-gonic/gin\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\nfunc AuthMiddleware(apiToken string) gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tauthHeader := ctx.GetHeader(constants.DAYTONA_AUTHORIZATION_HEADER)\n\t\tif authHeader == \"\" {\n\t\t\tauthHeader = ctx.GetHeader(constants.AUTHORIZATION_HEADER)\n\t\t}\n\n\t\tctx.Request.Header.Del(constants.DAYTONA_AUTHORIZATION_HEADER)\n\n\t\tif authHeader == \"\" {\n\t\t\tctx.Error(common_errors.NewUnauthorizedError(errors.New(\"authorization header required\")))\n\t\t\tctx.Abort()\n\t\t\treturn\n\t\t}\n\n\t\t// Split \"Bearer <token>\"\n\t\tparts := strings.Split(authHeader, \" \")\n\t\tif len(parts) != 2 || parts[0] != constants.BEARER_AUTH_HEADER {\n\t\t\tctx.Error(common_errors.NewUnauthorizedError(errors.New(\"invalid authorization header format\")))\n\t\t\tctx.Abort()\n\t\t\treturn\n\t\t}\n\n\t\ttoken := parts[1]\n\n\t\tif token != apiToken {\n\t\t\tctx.Error(common_errors.NewUnauthorizedError(errors.New(\"invalid token\")))\n\t\t\tctx.Abort()\n\t\t\treturn\n\t\t}\n\n\t\t// Authentication successful, continue to the next handler\n\t\tctx.Next()\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/middlewares/recoverable_errors.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage middlewares\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfunc RecoverableErrorsMiddleware() gin.HandlerFunc {\n\treturn func(ctx *gin.Context) {\n\t\tctx.Next()\n\t\terrs := ctx.Errors\n\t\tif len(errs) > 0 {\n\t\t\terr := errs.Last()\n\t\t\tif common.IsRecoverable(err.Err.Error()) {\n\t\t\t\tres := map[string]any{\n\t\t\t\t\t\"errorReason\": err.Err.Error() + \" - you may attempt a recovery action\",\n\t\t\t\t\t\"recoverable\": true,\n\t\t\t\t}\n\t\t\t\tb, marshalErr := json.Marshal(res)\n\t\t\t\tif marshalErr == nil {\n\t\t\t\t\tctx.Errors = []*gin.Error{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tErr:  common_errors.NewCustomError(http.StatusBadRequest, string(b), \"BAD_REQUEST\"),\n\t\t\t\t\t\t\tType: gin.ErrorTypePublic,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/server.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\n//\t@title\t\t\tDaytona Runner API\n//\t@version\t\tv0.0.0-dev\n//\t@description\tDaytona Runner API\n\n//\t@securityDefinitions.apikey\tBearer\n//\t@in\t\t\t\t\t\t\theader\n//\t@name\t\t\t\t\t\tAuthorization\n//\t@description\t\t\t\tType \"Bearer\" followed by a space and an API token.\n\n//\t@Security\tBearer\n\npackage api\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/daytonaio/runner/cmd/runner/config\"\n\t\"github.com/daytonaio/runner/internal\"\n\t\"github.com/daytonaio/runner/pkg/api/controllers\"\n\t\"github.com/daytonaio/runner/pkg/api/docs\"\n\t\"github.com/daytonaio/runner/pkg/api/middlewares\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n\t\"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/gin-gonic/gin/binding\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\tsloggin \"github.com/samber/slog-gin\"\n\n\tswaggerfiles \"github.com/swaggo/files\"\n\tginSwagger \"github.com/swaggo/gin-swagger\"\n)\n\ntype ApiServerConfig struct {\n\tLogger      *slog.Logger\n\tApiPort     int\n\tApiToken    string\n\tTLSCertFile string\n\tTLSKeyFile  string\n\tEnableTLS   bool\n\tLogRequests bool\n}\n\nfunc NewApiServer(config ApiServerConfig) *ApiServer {\n\treturn &ApiServer{\n\t\tlogger:      config.Logger.With(slog.String(\"component\", \"server\")),\n\t\tapiPort:     config.ApiPort,\n\t\tapiToken:    config.ApiToken,\n\t\ttlsCertFile: config.TLSCertFile,\n\t\ttlsKeyFile:  config.TLSKeyFile,\n\t\tenableTLS:   config.EnableTLS,\n\t\tlogRequests: config.LogRequests,\n\t}\n}\n\ntype ApiServer struct {\n\tlogger      *slog.Logger\n\tapiPort     int\n\tapiToken    string\n\ttlsCertFile string\n\ttlsKeyFile  string\n\tenableTLS   bool\n\thttpServer  *http.Server\n\trouter      *gin.Engine\n\tlogRequests bool\n}\n\nfunc (a *ApiServer) Start(ctx context.Context) error {\n\tdocs.SwaggerInfo.Description = \"Daytona Runner API\"\n\tdocs.SwaggerInfo.Title = \"Daytona Runner API\"\n\tdocs.SwaggerInfo.BasePath = \"/\"\n\tdocs.SwaggerInfo.Version = internal.Version\n\n\t_, err := net.Dial(\"tcp\", fmt.Sprintf(\":%d\", a.apiPort))\n\tif err == nil {\n\t\treturn fmt.Errorf(\"cannot start API server, port %d is already in use\", a.apiPort)\n\t}\n\n\tbinding.Validator = new(DefaultValidator)\n\n\tgin.DefaultWriter = &log.InfoLogWriter{}\n\tgin.DefaultErrorWriter = &log.ErrorLogWriter{}\n\n\ta.router = gin.New()\n\ta.router.Use(common_errors.Recovery())\n\n\tgin.SetMode(gin.ReleaseMode)\n\tif config.GetEnvironment() == \"development\" {\n\t\tgin.SetMode(gin.DebugMode)\n\t}\n\n\tif a.logRequests {\n\t\ta.router.Use(sloggin.New(a.logger))\n\t}\n\ta.router.Use(otelgin.Middleware(\"daytona-runner\"))\n\ta.router.Use(common_errors.NewErrorMiddleware(common.HandlePossibleDockerError))\n\ta.router.Use(middlewares.RecoverableErrorsMiddleware())\n\n\tpublic := a.router.Group(\"/\")\n\tpublic.GET(\"\", controllers.HealthCheck)\n\n\tif config.GetEnvironment() == \"development\" {\n\t\tpublic.GET(\"/api/*any\", ginSwagger.WrapHandler(swaggerfiles.Handler))\n\t}\n\n\tprotected := a.router.Group(\"/\")\n\tprotected.Use(middlewares.AuthMiddleware(a.apiToken))\n\n\tmetricsController := protected.Group(\"/metrics\")\n\t{\n\t\tmetricsController.GET(\"\", gin.WrapH(promhttp.Handler()))\n\t}\n\n\tinfoController := protected.Group(\"/info\")\n\t{\n\t\tinfoController.GET(\"\", controllers.RunnerInfo)\n\t}\n\n\tsandboxControllerLogger := a.logger.With(slog.String(\"component\", \"sandbox_controller\"))\n\tsandboxController := protected.Group(\"/sandboxes\")\n\t{\n\t\tsandboxController.POST(\"\", controllers.Create)\n\t\tsandboxController.GET(\"/:sandboxId\", controllers.Info)\n\t\tsandboxController.POST(\"/:sandboxId/destroy\", controllers.Destroy)\n\t\tsandboxController.POST(\"/:sandboxId/start\", controllers.Start)\n\t\tsandboxController.POST(\"/:sandboxId/stop\", controllers.Stop)\n\t\tsandboxController.POST(\"/:sandboxId/backup\", controllers.CreateBackup(sandboxControllerLogger))\n\t\tsandboxController.POST(\"/:sandboxId/resize\", controllers.Resize)\n\t\tsandboxController.POST(\"/:sandboxId/recover\", controllers.Recover)\n\t\tsandboxController.POST(\"/:sandboxId/is-recoverable\", controllers.IsRecoverable)\n\t\tsandboxController.POST(\"/:sandboxId/network-settings\", controllers.UpdateNetworkSettings)\n\n\t\t// Add proxy endpoint within the sandbox controller for toolbox\n\t\t// Using Any() to handle all HTTP methods for the toolbox proxy\n\t\tsandboxController.Any(\"/:sandboxId/toolbox/*path\", controllers.ProxyRequest(sandboxControllerLogger))\n\t}\n\n\tsnapshotControllerLogger := a.logger.With(slog.String(\"component\", \"snapshot_controller\"))\n\tsnapshotController := protected.Group(\"/snapshots\")\n\t{\n\t\tsnapshotController.POST(\"/pull\", controllers.PullSnapshot(ctx, snapshotControllerLogger))\n\t\tsnapshotController.POST(\"/build\", controllers.BuildSnapshot(ctx, snapshotControllerLogger))\n\t\tsnapshotController.POST(\"/tag\", controllers.TagImage)\n\t\tsnapshotController.GET(\"/exists\", controllers.SnapshotExists)\n\t\tsnapshotController.GET(\"/info\", controllers.GetSnapshotInfo)\n\t\tsnapshotController.POST(\"/remove\", controllers.RemoveSnapshot(snapshotControllerLogger))\n\t\tsnapshotController.GET(\"/logs\", controllers.GetBuildLogs(snapshotControllerLogger))\n\t\tsnapshotController.POST(\"/inspect\", controllers.InspectSnapshotInRegistry)\n\t}\n\n\ta.httpServer = &http.Server{\n\t\tAddr:    fmt.Sprintf(\":%d\", a.apiPort),\n\t\tHandler: a.router,\n\t}\n\n\tlistener, err := net.Listen(\"tcp\", a.httpServer.Addr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terrChan := make(chan error)\n\tgo func() {\n\t\tif a.enableTLS {\n\t\t\t// Start HTTPS server\n\t\t\terrChan <- a.httpServer.ServeTLS(listener, a.tlsCertFile, a.tlsKeyFile)\n\t\t} else {\n\t\t\t// Start HTTP server\n\t\t\terrChan <- a.httpServer.Serve(listener)\n\t\t}\n\t}()\n\n\treturn <-errChan\n}\n\nfunc (a *ApiServer) Stop() {\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\tdefer cancel()\n\tif err := a.httpServer.Shutdown(ctx); err != nil {\n\t\ta.logger.Error(\"Failed to shutdown API server\", \"error\", err)\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/api/validator.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage api\n\nimport (\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/gin-gonic/gin/binding\"\n\t\"github.com/go-playground/validator/v10\"\n)\n\ntype DefaultValidator struct {\n\tonce     sync.Once\n\tvalidate *validator.Validate\n}\n\nvar _ binding.StructValidator = &DefaultValidator{}\n\ntype SliceValidationError []error\n\nfunc (err SliceValidationError) Error() string {\n\tif len(err) == 0 {\n\t\treturn \"\"\n\t}\n\n\tvar b strings.Builder\n\tfor i := 0; i < len(err); i++ {\n\t\tif err[i] != nil {\n\t\t\tif b.Len() > 0 {\n\t\t\t\tb.WriteString(\"\\n\")\n\t\t\t}\n\t\t\tb.WriteString(\"[\" + strconv.Itoa(i) + \"]: \" + err[i].Error())\n\t\t}\n\t}\n\treturn b.String()\n}\n\nfunc (v *DefaultValidator) ValidateStruct(obj any) error {\n\tif obj == nil {\n\t\treturn nil\n\t}\n\n\tvalue := reflect.ValueOf(obj)\n\tswitch value.Kind() {\n\tcase reflect.Ptr:\n\t\tif value.Elem().Kind() != reflect.Struct {\n\t\t\treturn v.ValidateStruct(value.Elem().Interface())\n\t\t}\n\t\treturn v.validateStruct(obj)\n\tcase reflect.Struct:\n\t\treturn v.validateStruct(obj)\n\tcase reflect.Slice, reflect.Array:\n\t\tcount := value.Len()\n\t\tvalidateRet := make(SliceValidationError, 0)\n\t\tfor i := 0; i < count; i++ {\n\t\t\tif err := v.ValidateStruct(value.Index(i).Interface()); err != nil {\n\t\t\t\tvalidateRet = append(validateRet, err)\n\t\t\t}\n\t\t}\n\t\tif len(validateRet) == 0 {\n\t\t\treturn nil\n\t\t}\n\t\treturn validateRet\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc (v *DefaultValidator) Engine() interface{} {\n\tv.lazyinit()\n\treturn v.validate\n}\n\nfunc (v *DefaultValidator) validateStruct(obj any) error {\n\tv.lazyinit()\n\treturn v.validate.Struct(obj)\n}\n\nfunc (v *DefaultValidator) lazyinit() {\n\tv.once.Do(func() {\n\t\tv.validate = validator.New(validator.WithRequiredStructEnabled())\n\t\tv.validate.SetTagName(\"validate\")\n\t\t_ = v.validate.RegisterValidation(\"optional\", func(fl validator.FieldLevel) bool {\n\t\t\treturn true\n\t\t}, true)\n\t})\n}\n"
  },
  {
    "path": "apps/runner/pkg/apiclient/api_client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage apiclient\n\nimport (\n\t\"net/http\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/runner/cmd/runner/config\"\n\t\"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n)\n\nvar apiClient *apiclient.APIClient\n\nconst DaytonaSourceHeader = \"X-Daytona-Source\"\n\nfunc GetApiClient() (*apiclient.APIClient, error) {\n\tc, err := config.GetConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar newApiClient *apiclient.APIClient\n\n\tserverUrl := c.DaytonaApiUrl\n\n\tclientConfig := apiclient.NewConfiguration()\n\tclientConfig.Servers = apiclient.ServerConfigurations{\n\t\t{\n\t\t\tURL: serverUrl,\n\t\t},\n\t}\n\n\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+c.ApiToken)\n\n\tclientConfig.AddDefaultHeader(DaytonaSourceHeader, \"runner\")\n\n\tnewApiClient = apiclient.NewAPIClient(clientConfig)\n\n\tnewApiClient.GetConfig().HTTPClient = &http.Client{\n\t\tTransport: otelhttp.NewTransport(http.DefaultTransport),\n\t}\n\n\tapiClient = newApiClient\n\treturn apiClient, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/cache/backup_info_cache.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage cache\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/daytonaio/runner/pkg/models\"\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n\n\tcommon_cache \"github.com/daytonaio/common-go/pkg/cache\"\n)\n\ntype BackupInfoCache struct {\n\tcommon_cache.ICache[models.BackupInfo]\n\tretention time.Duration\n}\n\nfunc NewBackupInfoCache(ctx context.Context, retention time.Duration) *BackupInfoCache {\n\treturn &BackupInfoCache{\n\t\tICache:    common_cache.NewMapCache[models.BackupInfo](ctx),\n\t\tretention: retention,\n\t}\n}\n\nfunc (c *BackupInfoCache) SetBackupState(ctx context.Context, sandboxId string, state enums.BackupState, err error) error {\n\tentry := models.BackupInfo{\n\t\tState: state,\n\t\tError: err,\n\t}\n\n\treturn c.Set(ctx, sandboxId, entry, c.retention)\n}\n"
  },
  {
    "path": "apps/runner/pkg/cache/snapshot_error_cache.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage cache\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tcommon_cache \"github.com/daytonaio/common-go/pkg/cache\"\n)\n\ntype SnapshotErrorCache struct {\n\tcommon_cache.ICache[string]\n\tretention time.Duration\n}\n\nfunc NewSnapshotErrorCache(ctx context.Context, retention time.Duration) *SnapshotErrorCache {\n\treturn &SnapshotErrorCache{\n\t\tICache:    common_cache.NewMapCache[string](ctx),\n\t\tretention: retention,\n\t}\n}\n\nfunc (c *SnapshotErrorCache) SetError(ctx context.Context, snapshot string, errReason string) error {\n\treturn c.Set(ctx, snapshot, errReason, c.retention)\n}\n\nfunc (c *SnapshotErrorCache) GetError(ctx context.Context, snapshot string) (*string, error) {\n\treturn c.Get(ctx, snapshot)\n}\n\nfunc (c *SnapshotErrorCache) RemoveError(ctx context.Context, snapshot string) error {\n\treturn c.Delete(ctx, snapshot)\n}\n"
  },
  {
    "path": "apps/runner/pkg/common/container.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\nfunc GetContainerIpAddress(ctx context.Context, container *container.InspectResponse) string {\n\tif container == nil {\n\t\treturn \"\"\n\t}\n\n\tif container.NetworkSettings == nil {\n\t\treturn \"\"\n\t}\n\n\tif container.NetworkSettings.Networks == nil {\n\t\treturn \"\"\n\t}\n\n\tif networkSettings, ok := container.NetworkSettings.Networks[\"bridge\"]; ok && networkSettings != nil {\n\t\treturn networkSettings.IPAddress\n\t}\n\n\treturn \"\"\n}\n"
  },
  {
    "path": "apps/runner/pkg/common/daemon.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nconst DAEMON_PATH = \"/usr/local/bin/daytona\"\n"
  },
  {
    "path": "apps/runner/pkg/common/errors.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/containerd/errdefs\"\n\t\"github.com/daytonaio/runner/internal/util\"\n\t\"github.com/gin-gonic/gin\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\nfunc HandlePossibleDockerError(ctx *gin.Context, err error) common_errors.ErrorResponse {\n\tif errdefs.IsUnauthorized(err) || strings.Contains(err.Error(), \"unauthorized\") {\n\t\treturn common_errors.ErrorResponse{\n\t\t\tStatusCode: http.StatusUnauthorized,\n\t\t\tMessage:    fmt.Sprintf(\"unauthorized: %s\", err.Error()),\n\t\t\tCode:       \"UNAUTHORIZED\",\n\t\t\tTimestamp:  time.Now(),\n\t\t\tPath:       ctx.Request.URL.Path,\n\t\t\tMethod:     ctx.Request.Method,\n\t\t}\n\t} else if errdefs.IsConflict(err) {\n\t\treturn common_errors.ErrorResponse{\n\t\t\tStatusCode: http.StatusConflict,\n\t\t\tMessage:    fmt.Sprintf(\"conflict: %s\", err.Error()),\n\t\t\tCode:       \"CONFLICT\",\n\t\t\tTimestamp:  time.Now(),\n\t\t\tPath:       ctx.Request.URL.Path,\n\t\t\tMethod:     ctx.Request.Method,\n\t\t}\n\t} else if errdefs.IsInvalidArgument(err) {\n\t\treturn common_errors.ErrorResponse{\n\t\t\tStatusCode: http.StatusBadRequest,\n\t\t\tMessage:    fmt.Sprintf(\"bad request: %s\", err.Error()),\n\t\t\tCode:       \"BAD_REQUEST\",\n\t\t\tTimestamp:  time.Now(),\n\t\t\tPath:       ctx.Request.URL.Path,\n\t\t\tMethod:     ctx.Request.Method,\n\t\t}\n\t} else if errdefs.IsNotFound(err) {\n\t\treturn common_errors.ErrorResponse{\n\t\t\tStatusCode: http.StatusNotFound,\n\t\t\tMessage:    fmt.Sprintf(\"not found: %s\", err.Error()),\n\t\t\tCode:       \"NOT_FOUND\",\n\t\t\tTimestamp:  time.Now(),\n\t\t\tPath:       ctx.Request.URL.Path,\n\t\t\tMethod:     ctx.Request.Method,\n\t\t}\n\t} else if errdefs.IsInternal(err) {\n\t\tif strings.Contains(err.Error(), \"unable to find user\") {\n\t\t\treturn common_errors.ErrorResponse{\n\t\t\t\tStatusCode: http.StatusBadRequest,\n\t\t\t\tMessage:    util.ExtractErrorPart(err.Error()),\n\t\t\t\tCode:       \"BAD_REQUEST\",\n\t\t\t\tTimestamp:  time.Now(),\n\t\t\t\tPath:       ctx.Request.URL.Path,\n\t\t\t\tMethod:     ctx.Request.Method,\n\t\t\t}\n\t\t}\n\t}\n\n\treturn common_errors.ErrorResponse{\n\t\tStatusCode: http.StatusInternalServerError,\n\t\tMessage:    err.Error(),\n\t\tCode:       \"INTERNAL_SERVER_ERROR\",\n\t\tTimestamp:  time.Now(),\n\t\tPath:       ctx.Request.URL.Path,\n\t\tMethod:     ctx.Request.Method,\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/common/metrics.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/client_golang/prometheus/promauto\"\n)\n\ntype PrometheusOperationStatus string\n\nconst (\n\tPrometheusOperationStatusSuccess PrometheusOperationStatus = \"success\"\n\tPrometheusOperationStatusFailure PrometheusOperationStatus = \"failure\"\n)\n\n// Define your metrics\nvar (\n\t// Histogram to track duration of container operations\n\tContainerOperationDuration = promauto.NewHistogramVec(\n\t\tprometheus.HistogramOpts{\n\t\t\tName: \"container_operation_duration_seconds\",\n\t\t\tHelp: \"Time taken for container operations in seconds\",\n\t\t\t// Buckets optimized for detecting anomalies in operation durations\n\t\t\tBuckets: []float64{0.1, 0.25, 0.5, 0.75, 1, 2, 3, 5, 7.5, 10, 15, 30, 60, 120, 300},\n\t\t},\n\t\t[]string{\"operation\"},\n\t)\n\n\t// Counter to track occurrence of container operations with status\n\tContainerOperationCount = promauto.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tName: \"container_operation_total\",\n\t\t\tHelp: \"Total number of container operations\",\n\t\t},\n\t\t[]string{\"operation\", \"status\"},\n\t)\n)\n"
  },
  {
    "path": "apps/runner/pkg/common/recovery.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/runner/pkg/models\"\n)\n\n// Patterns that indicate recoverable errors mapped to their recovery types\nvar recoverableErrorPatterns = map[models.RecoveryType][]string{\n\tmodels.RecoveryTypeStorageExpansion: {\n\t\t\"no space left on device\",\n\t\t\"storage limit\",\n\t\t\"disk quota exceeded\",\n\t},\n\t// Add more recovery types here as needed:\n\t// dto.RecoveryTypeNetworkFailure: {\n\t//     \"network unreachable\",\n\t//     \"connection timeout\",\n\t// },\n}\n\n// DeduceRecoveryType determines if an error reason indicates a recoverable error\n// and returns the appropriate recovery type, or UnknownRecoveryType if not recoverable\nfunc DeduceRecoveryType(errorReason string) models.RecoveryType {\n\tif errorReason == \"\" {\n\t\treturn models.UnknownRecoveryType\n\t}\n\n\terrorReasonLower := strings.ToLower(errorReason)\n\n\tfor recoveryType, patterns := range recoverableErrorPatterns {\n\t\tfor _, pattern := range patterns {\n\t\t\tif strings.Contains(errorReasonLower, pattern) {\n\t\t\t\treturn recoveryType\n\t\t\t}\n\t\t}\n\t}\n\n\treturn models.UnknownRecoveryType\n}\n\n// IsRecoverable checks if an error reason is recoverable (any type)\nfunc IsRecoverable(errorReason string) bool {\n\treturn DeduceRecoveryType(errorReason) != models.UnknownRecoveryType\n}\n\nfunc FormatRecoverableError(err error) error {\n\tmsg := err.Error()\n\n\tif IsRecoverable(msg) {\n\t\tres := map[string]any{\n\t\t\t\"errorReason\": msg,\n\t\t\t\"recoverable\": true,\n\t\t}\n\t\tb, marshalErr := json.Marshal(res)\n\t\tif marshalErr == nil {\n\t\t\treturn errors.New(string(b))\n\t\t}\n\t}\n\n\treturn err\n}\n"
  },
  {
    "path": "apps/runner/pkg/common/rsync.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// RsyncCopy copies files from srcPath to destPath using rsync with full attribute preservation.\n// It uses rsync with -aAX flags to preserve permissions, ownership, timestamps, symlinks,\n// devices, ACLs, and extended attributes.\n//\n// The timeout parameter specifies how long to wait for the rsync operation to complete.\n// Trailing slashes are automatically added to paths to ensure contents are copied, not directories.\nfunc RsyncCopy(ctx context.Context, logger *slog.Logger, srcPath, destPath string) error {\n\tlogger.DebugContext(ctx, \"rsync copy\", \"source\", srcPath, \"destination\", destPath)\n\n\t// Use rsync with -aAX flags:\n\t// -a = archive mode (preserves permissions, ownership, timestamps, symlinks, devices)\n\t// -A = preserve ACLs\n\t// -X = preserve extended attributes (xattrs)\n\t// Trailing slashes ensure we copy contents, not the directory itself\n\tsrc := filepath.Clean(srcPath) + \"/\"\n\tdest := filepath.Clean(destPath) + \"/\"\n\trsyncCmd := exec.CommandContext(ctx, \"rsync\", \"-aAX\", src, dest)\n\n\tvar rsyncOut strings.Builder\n\tvar rsyncErr strings.Builder\n\trsyncCmd.Stdout = &rsyncOut\n\trsyncCmd.Stderr = &rsyncErr\n\n\tlogger.DebugContext(ctx, \"Starting rsync...\")\n\tif err := rsyncCmd.Run(); err != nil {\n\t\tif errMsg := rsyncErr.String(); errMsg != \"\" {\n\t\t\tlogger.ErrorContext(ctx, \"rsync stderr\", \"stderr\", errMsg)\n\t\t}\n\t\treturn fmt.Errorf(\"rsync failed: %w\", err)\n\t}\n\n\tif outMsg := rsyncOut.String(); outMsg != \"\" {\n\t\tlogger.DebugContext(ctx, \"rsync output\", \"output\", outMsg)\n\t}\n\n\tlogger.InfoContext(ctx, \"Successfully completed rsync copy\")\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/common/storage.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage common\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/docker/go-units\"\n)\n\n// ParseStorageOptSizeGB parses the size value from Docker StorageOpt[\"size\"] and returns GB as float64.\n// Docker storage-opt uses binary units (GiB) for both string (\"3G\") and numeric formats.\n// Supports formats like \"10G\", \"10240M\", \"10737418240\" (bytes), etc.\nfunc ParseStorageOptSizeGB(storageOpt map[string]string) (float64, error) {\n\tif storageOpt == nil {\n\t\treturn 0, fmt.Errorf(\"storageOpt is nil\")\n\t}\n\n\tsizeStr, ok := storageOpt[\"size\"]\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"size not found in storageOpt\")\n\t}\n\n\t// Parse size string using docker units library which handles various formats\n\tsizeBytes, err := units.RAMInBytes(sizeStr)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to parse storage size '%s': %w\", sizeStr, err)\n\t}\n\n\t// Convert bytes to GB\n\treturn float64(sizeBytes) / (1024 * 1024 * 1024), nil\n}\n\n// GBToBytes converts gigabytes to bytes\nfunc GBToBytes(gb float64) int64 {\n\treturn int64(gb * 1024 * 1024 * 1024)\n}\n"
  },
  {
    "path": "apps/runner/pkg/daemon/assets.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage daemon\n\nimport (\n\t\"embed\"\n)\n\n//go:embed static/*\nvar static embed.FS\n"
  },
  {
    "path": "apps/runner/pkg/daemon/static/.gitkeep",
    "content": ""
  },
  {
    "path": "apps/runner/pkg/daemon/util.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage daemon\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\nfunc WriteStaticBinary(name string) (string, error) {\n\tdaemonBinary, err := static.ReadFile(fmt.Sprintf(\"static/%s\", name))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tpwd, err := os.Getwd()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\ttmpBinariesDir := filepath.Join(pwd, \".tmp\", \"binaries\")\n\terr = os.MkdirAll(tmpBinariesDir, 0755)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tdaemonPath := filepath.Join(tmpBinariesDir, name)\n\t_, err = os.Stat(daemonPath)\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn \"\", err\n\t}\n\n\tif err == nil {\n\t\terr = os.Remove(daemonPath)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\n\terr = os.WriteFile(daemonPath, daemonBinary, 0755)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn daemonPath, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/backup.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"time\"\n\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n\n\tcmap \"github.com/orcaman/concurrent-map/v2\"\n)\n\ntype backupContext struct {\n\tctx    context.Context\n\tcancel context.CancelFunc\n}\n\nvar backup_context_map = cmap.New[backupContext]()\n\nfunc (d *DockerClient) CreateBackup(ctx context.Context, containerId string, backupDto dto.CreateBackupDTO) error {\n\t// Cancel a backup if it's already in progress\n\tbackup_context, ok := backup_context_map.Get(containerId)\n\tif ok {\n\t\tbackup_context.cancel()\n\t}\n\n\td.logger.InfoContext(ctx, \"Creating backup for container\", \"containerId\", containerId)\n\n\treturn d.createBackup(containerId, backupDto)\n}\n\nfunc (d *DockerClient) CreateBackupAsync(ctx context.Context, containerId string, backupDto dto.CreateBackupDTO) error {\n\t// Cancel a backup if it's already in progress\n\tbackup_context, ok := backup_context_map.Get(containerId)\n\tif ok {\n\t\tbackup_context.cancel()\n\t}\n\n\td.logger.InfoContext(ctx, \"Creating backup for container\", \"containerId\", containerId)\n\n\tgo func() {\n\t\terr := d.createBackup(containerId, backupDto)\n\t\tif err != nil {\n\t\t\td.logger.ErrorContext(ctx, \"Error creating backup for container\", \"containerId\", containerId, \"error\", err)\n\t\t}\n\t}()\n\n\treturn nil\n}\n\nfunc (d *DockerClient) createBackup(containerId string, backupDto dto.CreateBackupDTO) error {\n\tctx, cancel := context.WithTimeout(context.Background(), time.Duration(d.backupTimeoutMin)*time.Minute)\n\n\tdefer func() {\n\t\tbackupContext, ok := backup_context_map.Get(containerId)\n\t\tif ok {\n\t\t\tbackupContext.cancel()\n\t\t}\n\t\tbackup_context_map.Remove(containerId)\n\t}()\n\n\tbackup_context_map.Set(containerId, backupContext{ctx, cancel})\n\n\tcacheErr := d.backupInfoCache.SetBackupState(ctx, containerId, enums.BackupStateInProgress, nil)\n\tif cacheErr != nil {\n\t\td.logger.DebugContext(ctx, \"Failed to update backup info\", \"error\", cacheErr)\n\t}\n\n\terr := d.commitContainer(ctx, containerId, backupDto.Snapshot)\n\tif err != nil {\n\t\tif errors.Is(err, context.Canceled) {\n\t\t\tcacheErr := d.backupInfoCache.SetBackupState(ctx, containerId, enums.BackupStateNone, nil)\n\t\t\tif cacheErr != nil {\n\t\t\t\td.logger.DebugContext(ctx, \"Failed to update backup info\", \"error\", cacheErr)\n\t\t\t}\n\n\t\t\td.logger.InfoContext(ctx, \"Backup canceled for container\", \"containerId\", containerId)\n\t\t\treturn err\n\t\t}\n\n\t\tif errors.Is(err, context.DeadlineExceeded) {\n\t\t\tcacheErr := d.backupInfoCache.SetBackupState(ctx, containerId, enums.BackupStateFailed, err)\n\t\t\tif cacheErr != nil {\n\t\t\t\td.logger.DebugContext(ctx, \"Failed to update backup info\", \"error\", cacheErr)\n\t\t\t}\n\n\t\t\td.logger.ErrorContext(ctx, \"Backup timed out during commit\", \"containerId\", containerId)\n\t\t\treturn err\n\t\t}\n\n\t\td.logger.ErrorContext(ctx, \"Error committing container\", \"containerId\", containerId, \"error\", err)\n\n\t\tcacheErr := d.backupInfoCache.SetBackupState(ctx, containerId, enums.BackupStateFailed, err)\n\t\tif cacheErr != nil {\n\t\t\td.logger.DebugContext(ctx, \"Failed to update backup info\", \"error\", cacheErr)\n\t\t}\n\n\t\treturn err\n\t}\n\n\terr = d.PushImage(ctx, backupDto.Snapshot, &backupDto.Registry)\n\tif err != nil {\n\t\tif errors.Is(err, context.Canceled) {\n\t\t\tcacheErr := d.backupInfoCache.SetBackupState(ctx, containerId, enums.BackupStateNone, nil)\n\t\t\tif cacheErr != nil {\n\t\t\t\td.logger.DebugContext(ctx, \"Failed to update backup info\", \"error\", cacheErr)\n\t\t\t}\n\n\t\t\td.logger.InfoContext(ctx, \"Backup canceled for container\", \"containerId\", containerId)\n\t\t\treturn err\n\t\t}\n\n\t\tif errors.Is(err, context.DeadlineExceeded) {\n\t\t\tcacheErr := d.backupInfoCache.SetBackupState(ctx, containerId, enums.BackupStateFailed, err)\n\t\t\tif cacheErr != nil {\n\t\t\t\td.logger.DebugContext(ctx, \"Failed to update backup info\", \"error\", cacheErr)\n\t\t\t}\n\n\t\t\td.logger.ErrorContext(ctx, \"Backup timed out during push\", \"containerId\", containerId)\n\t\t\treturn err\n\t\t}\n\n\t\td.logger.ErrorContext(ctx, \"Error pushing image\", \"image\", backupDto.Snapshot, \"error\", err)\n\n\t\tcacheErr := d.backupInfoCache.SetBackupState(ctx, containerId, enums.BackupStateFailed, err)\n\t\tif cacheErr != nil {\n\t\t\td.logger.DebugContext(ctx, \"Failed to update backup info\", \"error\", cacheErr)\n\t\t}\n\n\t\treturn err\n\t}\n\n\tcacheErr = d.backupInfoCache.SetBackupState(ctx, containerId, enums.BackupStateCompleted, nil)\n\tif cacheErr != nil {\n\t\td.logger.DebugContext(ctx, \"Failed to update backup info\", \"error\", cacheErr)\n\t}\n\n\td.logger.InfoContext(ctx, \"Backup created successfully\", \"snapshot\", backupDto.Snapshot, \"containerId\", containerId)\n\n\terr = d.RemoveImage(ctx, backupDto.Snapshot, true)\n\tif err != nil {\n\t\td.logger.ErrorContext(ctx, \"Error removing image\", \"image\", backupDto.Snapshot, \"error\", err)\n\t\t// Don't set backup to failed because the image is already pushed\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\t\"github.com/daytonaio/runner/pkg/cache\"\n\t\"github.com/daytonaio/runner/pkg/netrules\"\n\t\"github.com/docker/docker/api/types/system\"\n\t\"github.com/docker/docker/client\"\n)\n\ntype DockerClientConfig struct {\n\tApiClient                    client.APIClient\n\tBackupInfoCache              *cache.BackupInfoCache\n\tLogger                       *slog.Logger\n\tAWSRegion                    string\n\tAWSEndpointUrl               string\n\tAWSAccessKeyId               string\n\tAWSSecretAccessKey           string\n\tDaemonPath                   string\n\tComputerUsePluginPath        string\n\tNetRulesManager              *netrules.NetRulesManager\n\tResourceLimitsDisabled       bool\n\tDaemonStartTimeoutSec        int\n\tSandboxStartTimeoutSec       int\n\tUseSnapshotEntrypoint        bool\n\tVolumeCleanupInterval        time.Duration\n\tVolumeCleanupDryRun          bool\n\tVolumeCleanupExclusionPeriod time.Duration\n\tBackupTimeoutMin             int\n\tInitializeDaemonTelemetry    bool\n}\n\nfunc NewDockerClient(config DockerClientConfig) (*DockerClient, error) {\n\tlogger := slog.Default().With(slog.String(\"component\", \"docker-client\"))\n\tif config.Logger != nil {\n\t\tlogger = config.Logger.With(slog.String(\"component\", \"docker-client\"))\n\t}\n\n\tif config.DaemonStartTimeoutSec <= 0 {\n\t\tlogger.Warn(\"Invalid daemon start timeout value. Using default value of 60 seconds\")\n\t\tconfig.DaemonStartTimeoutSec = 60\n\t}\n\n\tif config.SandboxStartTimeoutSec <= 0 {\n\t\tlogger.Warn(\"Invalid sandbox start timeout value. Using default value of 30 seconds\")\n\t\tconfig.SandboxStartTimeoutSec = 30\n\t}\n\n\tif config.BackupTimeoutMin <= 0 {\n\t\tlogger.Warn(\"Invalid backup timeout value. Using default value of 60 minutes\")\n\t\tconfig.BackupTimeoutMin = 60\n\t}\n\n\tvar info system.Info\n\terr := utils.RetryWithExponentialBackoff(\n\t\tcontext.Background(),\n\t\t\"get Docker info\",\n\t\t8,\n\t\t1*time.Second,\n\t\t5*time.Second,\n\t\tfunc() error {\n\t\t\tvar infoErr error\n\t\t\tinfo, infoErr = config.ApiClient.Info(context.Background())\n\t\t\treturn infoErr\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get Docker info: %w\", err)\n\t}\n\n\tfilesystem := \"\"\n\n\tfor _, driver := range info.DriverStatus {\n\t\tif driver[0] == \"Backing Filesystem\" {\n\t\t\tfilesystem = driver[1]\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn &DockerClient{\n\t\tapiClient:                    config.ApiClient,\n\t\tbackupInfoCache:              config.BackupInfoCache,\n\t\tlogger:                       logger,\n\t\tawsRegion:                    config.AWSRegion,\n\t\tawsEndpointUrl:               config.AWSEndpointUrl,\n\t\tawsAccessKeyId:               config.AWSAccessKeyId,\n\t\tawsSecretAccessKey:           config.AWSSecretAccessKey,\n\t\tvolumeMutexes:                make(map[string]*sync.Mutex),\n\t\tdaemonPath:                   config.DaemonPath,\n\t\tcomputerUsePluginPath:        config.ComputerUsePluginPath,\n\t\tnetRulesManager:              config.NetRulesManager,\n\t\tresourceLimitsDisabled:       config.ResourceLimitsDisabled,\n\t\tdaemonStartTimeoutSec:        config.DaemonStartTimeoutSec,\n\t\tsandboxStartTimeoutSec:       config.SandboxStartTimeoutSec,\n\t\tuseSnapshotEntrypoint:        config.UseSnapshotEntrypoint,\n\t\tvolumeCleanupInterval:        config.VolumeCleanupInterval,\n\t\tvolumeCleanupDryRun:          config.VolumeCleanupDryRun,\n\t\tvolumeCleanupExclusionPeriod: config.VolumeCleanupExclusionPeriod,\n\t\tbackupTimeoutMin:             config.BackupTimeoutMin,\n\t\tinitializeDaemonTelemetry:    config.InitializeDaemonTelemetry,\n\t\tfilesystem:                   filesystem,\n\t}, nil\n}\n\nfunc (d *DockerClient) ApiClient() client.APIClient {\n\treturn d.apiClient\n}\n\ntype DockerClient struct {\n\tapiClient                    client.APIClient\n\tbackupInfoCache              *cache.BackupInfoCache\n\tlogger                       *slog.Logger\n\tawsRegion                    string\n\tawsEndpointUrl               string\n\tawsAccessKeyId               string\n\tawsSecretAccessKey           string\n\tvolumeMutexes                map[string]*sync.Mutex\n\tvolumeMutexesMutex           sync.Mutex\n\tdaemonPath                   string\n\tcomputerUsePluginPath        string\n\tnetRulesManager              *netrules.NetRulesManager\n\tresourceLimitsDisabled       bool\n\tdaemonStartTimeoutSec        int\n\tsandboxStartTimeoutSec       int\n\tuseSnapshotEntrypoint        bool\n\tvolumeCleanupInterval        time.Duration\n\tvolumeCleanupDryRun          bool\n\tvolumeCleanupExclusionPeriod time.Duration\n\tbackupTimeoutMin             int\n\tvolumeCleanupMutex           sync.Mutex\n\tlastVolumeCleanup            time.Time\n\tinitializeDaemonTelemetry    bool\n\tfilesystem                   string\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/container_commit.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/image\"\n)\n\nfunc (d *DockerClient) commitContainer(ctx context.Context, containerId, imageName string) error {\n\tconst maxRetries = 3\n\n\tfor attempt := 1; attempt <= maxRetries; attempt++ {\n\t\td.logger.InfoContext(ctx, \"Committing container\", \"containerId\", containerId, \"attempt\", attempt, \"maxRetries\", maxRetries)\n\n\t\tcommitResp, err := d.apiClient.ContainerCommit(ctx, containerId, container.CommitOptions{\n\t\t\tReference: imageName,\n\t\t\tPause:     false,\n\t\t})\n\t\tif err == nil {\n\t\t\td.logger.InfoContext(ctx, \"Container committed successfully\", \"containerId\", containerId, \"imageId\", commitResp.ID)\n\t\t\treturn nil\n\t\t}\n\n\t\t// Check if the error is related to \"failed to get digest\" and try export/import fallback\n\t\tif strings.Contains(err.Error(), \"Error response from daemon: failed to get digest\") {\n\t\t\td.logger.WarnContext(ctx, \"Commit failed with digest error, attempting export/import fallback for container\", \"containerId\", containerId)\n\n\t\t\terr = d.exportImportContainer(ctx, containerId, imageName)\n\t\t\tif err == nil {\n\t\t\t\td.logger.InfoContext(ctx, \"Container successfully backed up using export/import method\", \"containerId\", containerId)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\td.logger.ErrorContext(ctx, \"Export/import fallback also failed for container\", \"containerId\", containerId, \"error\", err)\n\t\t}\n\n\t\tif attempt < maxRetries {\n\t\t\td.logger.WarnContext(ctx, \"Failed to commit container\", \"containerId\", containerId, \"attempt\", attempt, \"maxRetries\", maxRetries, \"error\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\treturn fmt.Errorf(\"failed to commit container after %d attempts: %w\", maxRetries, err)\n\t}\n\n\treturn nil\n}\n\nfunc (d *DockerClient) exportImportContainer(ctx context.Context, containerId, imageName string) error {\n\td.logger.InfoContext(ctx, \"Exporting container and importing as image\", \"containerId\", containerId, \"imageName\", imageName)\n\n\t// First, inspect the container to get its configuration\n\tcontainerInfo, err := d.ContainerInspect(ctx, containerId)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Export the container\n\texportReader, err := d.apiClient.ContainerExport(ctx, containerId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to export container %s: %w\", containerId, err)\n\t}\n\tdefer exportReader.Close()\n\n\t// Prepare import options with container configuration\n\timportOptions := image.ImportOptions{\n\t\tMessage: fmt.Sprintf(\"Imported from container %s\", containerId),\n\t}\n\n\t// Build the configuration changes to preserve CMD, ENTRYPOINT, ENV, etc.\n\tvar changes []string\n\n\t// Preserve CMD if it exists\n\tif len(containerInfo.Config.Cmd) > 0 {\n\t\tcmdStr := buildDockerfileCmd(containerInfo.Config.Cmd)\n\t\tchanges = append(changes, fmt.Sprintf(\"CMD %s\", cmdStr))\n\t}\n\n\t// Preserve ENTRYPOINT if it exists\n\tif len(containerInfo.Config.Entrypoint) > 0 {\n\t\tentrypointStr := buildDockerfileCmd(containerInfo.Config.Entrypoint)\n\t\tchanges = append(changes, fmt.Sprintf(\"ENTRYPOINT %s\", entrypointStr))\n\t}\n\n\t// Preserve environment variables\n\tif len(containerInfo.Config.Env) > 0 {\n\t\tfor _, env := range containerInfo.Config.Env {\n\t\t\tsplitEnv := strings.SplitN(env, \"=\", 2)\n\t\t\tif len(splitEnv) != 2 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Quote the value to handle spaces and special characters\n\t\t\tenv = fmt.Sprintf(`%s=\"%s\"`, splitEnv[0], splitEnv[1])\n\t\t\tchanges = append(changes, fmt.Sprintf(`ENV %s`, env))\n\t\t}\n\t}\n\n\t// Preserve working directory\n\tif containerInfo.Config.WorkingDir != \"\" {\n\t\tchanges = append(changes, fmt.Sprintf(\"WORKDIR %s\", containerInfo.Config.WorkingDir))\n\t}\n\n\t// Preserve exposed ports\n\tif len(containerInfo.Config.ExposedPorts) > 0 {\n\t\tfor port := range containerInfo.Config.ExposedPorts {\n\t\t\tchanges = append(changes, fmt.Sprintf(\"EXPOSE %s\", string(port)))\n\t\t}\n\t}\n\n\t// Preserve user\n\tif containerInfo.Config.User != \"\" {\n\t\tchanges = append(changes, fmt.Sprintf(\"USER %s\", containerInfo.Config.User))\n\t}\n\n\t// Apply the changes\n\timportOptions.Changes = changes\n\n\td.logger.InfoContext(ctx, \"Applying configuration changes\", \"changes\", changes)\n\n\timportResponse, err := d.apiClient.ImageImport(ctx, image.ImportSource{\n\t\tSource:     exportReader,\n\t\tSourceName: \"-\",\n\t}, imageName, importOptions)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to import container %s as image %s: %w\", containerId, imageName, err)\n\t}\n\tdefer importResponse.Close()\n\n\t// Read the import response to completion\n\t_, err = io.ReadAll(importResponse)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read import response for container %s: %w\", containerId, err)\n\t}\n\n\td.logger.InfoContext(ctx, \"Container successfully exported and imported as image with preserved configuration\", \"containerId\", containerId, \"imageName\", imageName)\n\treturn nil\n}\n\n// buildDockerfileCmd converts a slice of command arguments to a properly formatted Dockerfile CMD/ENTRYPOINT string\nfunc buildDockerfileCmd(cmd []string) string {\n\tif len(cmd) == 0 {\n\t\treturn \"\"\n\t}\n\n\t// Use JSON array format for better compatibility\n\tvar quotedArgs []string\n\tfor _, arg := range cmd {\n\t\t// Escape quotes and backslashes in the argument\n\t\tescaped := strings.ReplaceAll(arg, \"\\\\\", \"\\\\\\\\\")\n\t\tescaped = strings.ReplaceAll(escaped, \"\\\"\", \"\\\\\\\"\")\n\t\tquotedArgs = append(quotedArgs, fmt.Sprintf(\"\\\"%s\\\"\", escaped))\n\t}\n\n\treturn fmt.Sprintf(\"[%s]\", strings.Join(quotedArgs, \", \"))\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/container_configs.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/runner/cmd/runner/config\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/api/types/network\"\n\t\"github.com/docker/docker/api/types/strslice\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\nfunc (d *DockerClient) getContainerConfigs(sandboxDto dto.CreateSandboxDTO, image *image.InspectResponse, volumeMountPathBinds []string) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) {\n\tcontainerConfig, err := d.getContainerCreateConfig(sandboxDto, image)\n\tif err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\n\thostConfig, err := d.getContainerHostConfig(sandboxDto, volumeMountPathBinds)\n\tif err != nil {\n\t\treturn nil, nil, nil, err\n\t}\n\n\tnetworkingConfig := d.getContainerNetworkingConfig()\n\treturn containerConfig, hostConfig, networkingConfig, nil\n}\n\nfunc (d *DockerClient) getContainerCreateConfig(sandboxDto dto.CreateSandboxDTO, image *image.InspectResponse) (*container.Config, error) {\n\tif image == nil {\n\t\treturn nil, fmt.Errorf(\"image not found for sandbox: %s\", sandboxDto.Id)\n\t}\n\n\tenvVars := []string{\n\t\t\"DAYTONA_SANDBOX_ID=\" + sandboxDto.Id,\n\t\t\"DAYTONA_SANDBOX_SNAPSHOT=\" + sandboxDto.Snapshot,\n\t\t\"DAYTONA_SANDBOX_USER=\" + sandboxDto.OsUser,\n\t}\n\n\tfor key, value := range sandboxDto.Env {\n\t\tenvVars = append(envVars, fmt.Sprintf(\"%s=%s\", key, value))\n\t}\n\n\tif sandboxDto.OtelEndpoint != nil && *sandboxDto.OtelEndpoint != \"\" {\n\t\tenvVars = append(envVars, \"DAYTONA_OTEL_ENDPOINT=\"+*sandboxDto.OtelEndpoint)\n\t}\n\n\tif sandboxDto.OrganizationId != nil && *sandboxDto.OrganizationId != \"\" {\n\t\tenvVars = append(envVars, \"DAYTONA_ORGANIZATION_ID=\"+*sandboxDto.OrganizationId)\n\t}\n\n\tif sandboxDto.RegionId != nil && *sandboxDto.RegionId != \"\" {\n\t\tenvVars = append(envVars, \"DAYTONA_REGION_ID=\"+*sandboxDto.RegionId)\n\t}\n\n\tlabels := make(map[string]string)\n\tif len(sandboxDto.Volumes) > 0 {\n\t\tvolumeMountPaths := make([]string, len(sandboxDto.Volumes))\n\t\tfor i, v := range sandboxDto.Volumes {\n\t\t\tvolumeMountPaths[i] = v.MountPath\n\t\t}\n\t\tlabels[\"daytona.volume_mount_paths\"] = strings.Join(volumeMountPaths, \",\")\n\t}\n\tif sandboxDto.Metadata != nil {\n\t\tif orgID, ok := sandboxDto.Metadata[\"organizationId\"]; ok && orgID != \"\" {\n\t\t\tlabels[\"daytona.organization_id\"] = orgID\n\t\t}\n\t\tif orgName, ok := sandboxDto.Metadata[\"organizationName\"]; ok && orgName != \"\" {\n\t\t\tlabels[\"daytona.organization_name\"] = orgName\n\t\t}\n\t}\n\n\tworkingDir := \"\"\n\tcmd := []string{}\n\tentrypoint := sandboxDto.Entrypoint\n\tif !d.useSnapshotEntrypoint {\n\t\tif image.Config.WorkingDir != \"\" {\n\t\t\tworkingDir = image.Config.WorkingDir\n\t\t}\n\n\t\t// If workingDir is empty, append flag env var to envVars\n\t\tif workingDir == \"\" {\n\t\t\tenvVars = append(envVars, \"DAYTONA_USER_HOME_AS_WORKDIR=true\")\n\t\t}\n\n\t\tentrypoint = []string{common.DAEMON_PATH}\n\n\t\tif len(sandboxDto.Entrypoint) != 0 {\n\t\t\tcmd = append(cmd, sandboxDto.Entrypoint...)\n\t\t} else {\n\t\t\tif slices.Equal(image.Config.Entrypoint, strslice.StrSlice{common.DAEMON_PATH}) {\n\t\t\t\tcmd = append(cmd, image.Config.Cmd...)\n\t\t\t} else {\n\t\t\t\tcmd = append(cmd, image.Config.Entrypoint...)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &container.Config{\n\t\tHostname:     sandboxDto.Id,\n\t\tImage:        sandboxDto.Snapshot,\n\t\tWorkingDir:   workingDir,\n\t\tEnv:          envVars,\n\t\tEntrypoint:   entrypoint,\n\t\tCmd:          cmd,\n\t\tLabels:       labels,\n\t\tAttachStdout: true,\n\t\tAttachStderr: true,\n\t}, nil\n}\n\nfunc (d *DockerClient) getContainerHostConfig(sandboxDto dto.CreateSandboxDTO, volumeMountPathBinds []string) (*container.HostConfig, error) {\n\tvar binds []string\n\n\tbinds = append(binds, fmt.Sprintf(\"%s:%s:ro\", d.daemonPath, common.DAEMON_PATH))\n\n\t// Mount the plugin if available\n\tif d.computerUsePluginPath != \"\" {\n\t\tbinds = append(binds, fmt.Sprintf(\"%s:/usr/local/lib/daytona-computer-use:ro\", d.computerUsePluginPath))\n\t}\n\n\tif len(volumeMountPathBinds) > 0 {\n\t\tbinds = append(binds, volumeMountPathBinds...)\n\t}\n\n\thostConfig := &container.HostConfig{\n\t\tPrivileged: true,\n\t\tBinds:      binds,\n\t}\n\n\tif sandboxDto.OtelEndpoint != nil && strings.Contains(*sandboxDto.OtelEndpoint, \"host.docker.internal\") {\n\t\thostConfig.ExtraHosts = []string{\n\t\t\t\"host.docker.internal:host-gateway\",\n\t\t}\n\t}\n\n\tif !d.resourceLimitsDisabled {\n\t\thostConfig.Resources = container.Resources{\n\t\t\tCPUPeriod:  100000,\n\t\t\tCPUQuota:   sandboxDto.CpuQuota * 100000,\n\t\t\tMemory:     common.GBToBytes(float64(sandboxDto.MemoryQuota)),\n\t\t\tMemorySwap: common.GBToBytes(float64(sandboxDto.MemoryQuota)),\n\t\t}\n\t}\n\n\tcontainerRuntime := config.GetContainerRuntime()\n\tif containerRuntime != \"\" {\n\t\thostConfig.Runtime = containerRuntime\n\t}\n\n\tif d.filesystem == \"xfs\" {\n\t\thostConfig.StorageOpt = map[string]string{\n\t\t\t\"size\": fmt.Sprintf(\"%dG\", sandboxDto.StorageQuota),\n\t\t}\n\t}\n\n\treturn hostConfig, nil\n}\n\nfunc (d *DockerClient) getContainerNetworkingConfig() *network.NetworkingConfig {\n\tcontainerNetwork := config.GetContainerNetwork()\n\tif containerNetwork != \"\" {\n\t\treturn &network.NetworkingConfig{\n\t\t\tEndpointsConfig: map[string]*network.EndpointSettings{\n\t\t\t\tcontainerNetwork: {},\n\t\t\t},\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/container_exec.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/pkg/stdcopy\"\n)\n\ntype ExecResult struct {\n\tStdOut   string\n\tStdErr   string\n\tExitCode int\n}\n\n// todo send stdout for writer os.STD_OUT\nfunc (d *DockerClient) execSync(ctx context.Context, containerId string, execOptions container.ExecOptions, execStartOptions container.ExecStartOptions) (*ExecResult, error) {\n\texecOptions.Env = append([]string{\"DEBIAN_FRONTEND=noninteractive\"}, execOptions.Env...)\n\n\tresponse, err := d.apiClient.ContainerExecCreate(ctx, containerId, execOptions)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresult, err := d.inspectExecResp(ctx, response.ID, execStartOptions)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\nfunc (d *DockerClient) inspectExecResp(ctx context.Context, execID string, execStartOptions container.ExecStartOptions) (*ExecResult, error) {\n\tresp, err := d.apiClient.ContainerExecAttach(ctx, execID, execStartOptions)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Close()\n\n\t// read the output\n\toutputDone := make(chan error)\n\n\toutBuf := bytes.Buffer{}\n\terrBuf := bytes.Buffer{}\n\n\tgo func() {\n\t\toutMw := io.MultiWriter(&outBuf, &log.DebugLogWriter{})\n\t\terrMw := io.MultiWriter(&errBuf, &log.DebugLogWriter{})\n\n\t\t_, copyErr := stdcopy.StdCopy(outMw, errMw, resp.Reader)\n\t\toutputDone <- copyErr\n\t}()\n\n\tselect {\n\tcase err := <-outputDone:\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbreak\n\n\tcase <-ctx.Done():\n\t\treturn nil, ctx.Err()\n\t}\n\n\tstdout, err := io.ReadAll(&outBuf)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstderr, err := io.ReadAll(&errBuf)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tres, err := d.apiClient.ContainerExecInspect(ctx, execID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &ExecResult{\n\t\tExitCode: res.ExitCode,\n\t\tStdOut:   string(stdout),\n\t\tStdErr:   string(stderr),\n\t}, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/container_inspect.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/containerd/errdefs\"\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/docker/docker/api/types/container\"\n)\n\nfunc (d *DockerClient) ContainerInspect(ctx context.Context, containerId string) (*container.InspectResponse, error) {\n\tcontainer, err := d.apiClient.ContainerInspect(ctx, containerId)\n\tif err != nil {\n\t\terrMsg := fmt.Errorf(\"failed to inspect sandbox container %s: %w\", containerId, err)\n\n\t\tif errdefs.IsNotFound(err) {\n\t\t\treturn nil, common_errors.NewNotFoundError(errMsg)\n\t\t}\n\n\t\treturn nil, errMsg\n\t}\n\n\treturn &container, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/create.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"maps\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/containerd/errdefs\"\n\t\"github.com/daytonaio/common-go/pkg/timer\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n\t\"github.com/docker/docker/api/types/image\"\n\tv1 \"github.com/opencontainers/image-spec/specs-go/v1\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\nfunc (d *DockerClient) Create(ctx context.Context, sandboxDto dto.CreateSandboxDTO) (string, string, error) {\n\tdefer timer.Timer()()\n\n\tstartTime := time.Now()\n\tdefer func() {\n\t\tobs, err := common.ContainerOperationDuration.GetMetricWithLabelValues(\"create\")\n\t\tif err == nil {\n\t\t\tobs.Observe(time.Since(startTime).Seconds())\n\t\t}\n\t}()\n\n\tstate, err := d.GetSandboxState(ctx, sandboxDto.Id)\n\tif err != nil && state == enums.SandboxStateError {\n\t\treturn \"\", \"\", err\n\t}\n\n\tif state == enums.SandboxStateStarted || state == enums.SandboxStatePullingSnapshot || state == enums.SandboxStateStarting {\n\t\tc, err := d.ContainerInspect(ctx, sandboxDto.Id)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", err\n\t\t}\n\n\t\tcontainerIP := common.GetContainerIpAddress(ctx, c)\n\t\tif containerIP == \"\" {\n\t\t\treturn \"\", \"\", errors.New(\"sandbox IP not found? Is the sandbox started?\")\n\t\t}\n\n\t\tdaemonVersion, err := d.waitForDaemonRunning(ctx, containerIP, sandboxDto.AuthToken)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", err\n\t\t}\n\n\t\treturn sandboxDto.Id, daemonVersion, nil\n\t}\n\n\tif state == enums.SandboxStateStopped || state == enums.SandboxStateCreating {\n\t\tmetadata := maps.Clone(sandboxDto.Metadata)\n\t\tif len(sandboxDto.Volumes) > 0 {\n\t\t\tif metadata == nil {\n\t\t\t\tmetadata = make(map[string]string)\n\t\t\t}\n\t\t\tvolumesJSON, err := json.Marshal(sandboxDto.Volumes)\n\t\t\tif err == nil {\n\t\t\t\tmetadata[\"volumes\"] = string(volumesJSON)\n\t\t\t}\n\t\t}\n\t\t_, daemonVersion, err := d.Start(ctx, sandboxDto.Id, sandboxDto.AuthToken, metadata)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", err\n\t\t}\n\n\t\treturn sandboxDto.Id, daemonVersion, nil\n\t}\n\n\timage, err := d.PullImage(ctx, sandboxDto.Snapshot, sandboxDto.Registry)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\terr = d.validateImageArchitecture(image)\n\tif err != nil {\n\t\td.logger.ErrorContext(ctx, \"Failed to validate image architecture\", \"error\", err)\n\t\treturn \"\", \"\", err\n\t}\n\n\tvolumeMountPathBinds := make([]string, 0)\n\tif sandboxDto.Volumes != nil {\n\t\tvolumeMountPathBinds, err = d.getVolumesMountPathBinds(ctx, sandboxDto.Volumes)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", err\n\t\t}\n\t}\n\n\tcontainerConfig, hostConfig, networkingConfig, err := d.getContainerConfigs(sandboxDto, image, volumeMountPathBinds)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\tc, err := d.apiClient.ContainerCreate(ctx, containerConfig, hostConfig, networkingConfig, &v1.Platform{\n\t\tArchitecture: \"amd64\",\n\t\tOS:           \"linux\",\n\t}, sandboxDto.Id)\n\tif err != nil {\n\t\t// Container already exists and is being created by another process\n\t\tif errdefs.IsConflict(err) {\n\t\t\treturn sandboxDto.Id, \"\", nil\n\t\t}\n\t\treturn \"\", \"\", err\n\t}\n\n\t// Skip starting the container if explicitly requested\n\tif sandboxDto.SkipStart != nil && *sandboxDto.SkipStart {\n\t\treturn c.ID, \"\", nil\n\t}\n\n\trunningContainer, daemonVersion, err := d.Start(ctx, sandboxDto.Id, sandboxDto.AuthToken, sandboxDto.Metadata)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\tcontainerShortId := runningContainer.ID[:12]\n\n\tip := common.GetContainerIpAddress(ctx, runningContainer)\n\tif sandboxDto.NetworkBlockAll != nil && *sandboxDto.NetworkBlockAll {\n\t\tgo func() {\n\t\t\terr = d.netRulesManager.SetNetworkRules(containerShortId, ip, \"\")\n\t\t\tif err != nil {\n\t\t\t\td.logger.ErrorContext(ctx, \"Failed to update sandbox network settings\", \"error\", err)\n\t\t\t}\n\t\t}()\n\t} else if sandboxDto.NetworkAllowList != nil && *sandboxDto.NetworkAllowList != \"\" {\n\t\tgo func() {\n\t\t\terr = d.netRulesManager.SetNetworkRules(containerShortId, ip, *sandboxDto.NetworkAllowList)\n\t\t\tif err != nil {\n\t\t\t\td.logger.ErrorContext(ctx, \"Failed to update sandbox network settings\", \"error\", err)\n\t\t\t}\n\t\t}()\n\t}\n\n\tif sandboxDto.Metadata != nil && sandboxDto.Metadata[\"limitNetworkEgress\"] == \"true\" {\n\t\tgo func() {\n\t\t\terr = d.netRulesManager.SetNetworkLimiter(containerShortId, ip)\n\t\t\tif err != nil {\n\t\t\t\td.logger.ErrorContext(ctx, \"Failed to update sandbox network settings\", \"error\", err)\n\t\t\t}\n\t\t}()\n\t}\n\n\treturn c.ID, daemonVersion, nil\n}\n\nfunc (p *DockerClient) validateImageArchitecture(image *image.InspectResponse) error {\n\tdefer timer.Timer()()\n\n\tif image == nil {\n\t\treturn fmt.Errorf(\"image not found\")\n\t}\n\n\tarch := strings.ToLower(image.Architecture)\n\tvalidArchs := []string{\"amd64\", \"x86_64\"}\n\n\tfor _, validArch := range validArchs {\n\t\tif arch == validArch {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn common_errors.NewConflictError(fmt.Errorf(\"image %s architecture (%s) is not x64 compatible\", image.ID, image.Architecture))\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/daemon.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/timer\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/docker/docker/api/types/container\"\n\t\"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\nfunc (d *DockerClient) startDaytonaDaemon(ctx context.Context, containerId string, workDir string) error {\n\tdefer timer.Timer()()\n\n\tvar envVars []string\n\tif workDir == \"\" {\n\t\tenvVars = append(envVars, \"DAYTONA_USER_HOME_AS_WORKDIR=true\")\n\t}\n\n\texecOptions := container.ExecOptions{\n\t\tCmd:          []string{common.DAEMON_PATH},\n\t\tAttachStdout: true,\n\t\tAttachStderr: true,\n\t\tWorkingDir:   workDir,\n\t\tEnv:          envVars,\n\t\tTty:          true,\n\t}\n\n\texecStartOptions := container.ExecStartOptions{\n\t\tDetach: false,\n\t}\n\n\tresult, err := d.execSync(ctx, containerId, execOptions, execStartOptions)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif result.ExitCode != 0 {\n\t\treturn fmt.Errorf(\"failed to start daytona daemon with exit code %d: %s\", result.ExitCode, result.StdErr)\n\t}\n\n\treturn nil\n}\n\nfunc (d *DockerClient) waitForDaemonRunning(ctx context.Context, containerIP string, authToken *string) (string, error) {\n\tdefer timer.Timer()()\n\n\ttracer := otel.Tracer(\"runner\")\n\tctx, span := tracer.Start(ctx, \"wait_for_daemon_running\",\n\t\ttrace.WithAttributes(attribute.String(\"container.ip\", containerIP)),\n\t)\n\tdefer span.End()\n\n\t// Build the target URL\n\ttargetURL := fmt.Sprintf(\"http://%s:2280/version\", containerIP)\n\ttarget, err := url.Parse(targetURL)\n\tif err != nil {\n\t\tspan.RecordError(err)\n\t\tspan.SetStatus(codes.Error, \"failed to parse target URL\")\n\t\treturn \"\", common_errors.NewBadRequestError(fmt.Errorf(\"failed to parse target URL: %w\", err))\n\t}\n\n\t// Use a plain HTTP client for polling to avoid creating noisy trace spans for each failed retry\n\tpollingClient := &http.Client{\n\t\tTimeout: 1 * time.Second,\n\t}\n\n\ttimeout := time.Duration(d.daemonStartTimeoutSec) * time.Second\n\ttimeoutCtx, cancel := context.WithTimeout(ctx, timeout)\n\tdefer cancel()\n\n\tretries := 0\n\tfor {\n\t\tselect {\n\t\tcase <-timeoutCtx.Done():\n\t\t\tspan.SetAttributes(attribute.Int(\"retries\", retries))\n\t\t\tspan.RecordError(fmt.Errorf(\"timeout waiting for daemon to start\"))\n\t\t\tspan.SetStatus(codes.Error, \"timeout waiting for daemon to start\")\n\t\t\treturn \"\", fmt.Errorf(\"timeout waiting for daemon to start\")\n\t\tdefault:\n\t\t\tversion, err := d.getDaemonVersion(ctx, target, pollingClient)\n\t\t\tif err != nil {\n\t\t\t\tretries++\n\t\t\t\ttime.Sleep(5 * time.Millisecond)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tspan.SetAttributes(attribute.Int(\"retries\", retries))\n\t\t\tspan.SetStatus(codes.Ok, \"daemon ready\")\n\n\t\t\t// For backward compatibility, only initialize daemon if authToken is provided\n\t\t\tif authToken == nil {\n\t\t\t\treturn version, nil\n\t\t\t}\n\n\t\t\t// Optimistically initialize the daemon in parallel while waiting for it to be ready, to save time.\n\t\t\t// If initialization fails, log the error but do not fail the entire process, as the daemon is already running at this point.\n\t\t\totelClient := &http.Client{\n\t\t\t\tTimeout:   1 * time.Second,\n\t\t\t\tTransport: otelhttp.NewTransport(http.DefaultTransport),\n\t\t\t}\n\t\t\tgo func() {\n\t\t\t\t// Don't cancel context\n\t\t\t\tinitContext := context.WithoutCancel(ctx)\n\t\t\t\terr := d.initializeDaemon(initContext, containerIP, *authToken, otelClient)\n\t\t\t\tif err != nil {\n\t\t\t\t\td.logger.ErrorContext(initContext, \"Failed to initialize daemon telemetry\", \"error\", err)\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\treturn version, nil\n\t\t}\n\t}\n}\n\ntype sandboxToken struct {\n\tToken string `json:\"token\"`\n}\n\nfunc (d *DockerClient) initializeDaemon(ctx context.Context, containerIP string, token string, client *http.Client) error {\n\tif client == nil {\n\t\treturn fmt.Errorf(\"http client is nil\")\n\t}\n\n\tif !d.initializeDaemonTelemetry {\n\t\treturn nil\n\t}\n\n\tsandboxToken := sandboxToken{\n\t\tToken: token,\n\t}\n\n\tjsonData, err := json.Marshal(sandboxToken)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshal sandbox token data: %w\", err)\n\t}\n\n\turl := fmt.Sprintf(\"http://%s:2280/init\", containerIP)\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(jsonData))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create init request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to initialize daemon: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"daemon returned non-200 status code: %d\", resp.StatusCode)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/daemon_version.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n)\n\ntype daemonVersionResponse struct {\n\tVersion string `json:\"version\" example:\"0.1.0\"`\n}\n\nfunc (d *DockerClient) GetDaemonVersion(ctx context.Context, sandboxId string) (string, error) {\n\tc, err := d.ContainerInspect(ctx, sandboxId)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tcontainerIP := common.GetContainerIpAddress(ctx, c)\n\tif containerIP == \"\" {\n\t\treturn \"\", errors.New(\"sandbox IP not found? Is the sandbox started?\")\n\t}\n\n\ttargetUrl := fmt.Sprintf(\"http://%s:2280/version\", containerIP)\n\ttarget, err := url.Parse(targetUrl)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tclient := &http.Client{\n\t\tTimeout:   1 * time.Second,\n\t\tTransport: otelhttp.NewTransport(http.DefaultTransport),\n\t}\n\n\treturn d.getDaemonVersion(ctx, target, client)\n}\n\nfunc (d *DockerClient) getDaemonVersion(ctx context.Context, targetUrl *url.URL, client *http.Client) (string, error) {\n\tif client == nil {\n\t\treturn \"\", fmt.Errorf(\"http client is nil\")\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, targetUrl.String(), nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\n\tvar versionResponse daemonVersionResponse\n\terr = json.NewDecoder(resp.Body).Decode(&versionResponse)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn versionResponse.Version, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/destroy.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/containerd/errdefs\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n\t\"github.com/docker/docker/api/types/container\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n)\n\nfunc (d *DockerClient) Destroy(ctx context.Context, containerId string) error {\n\tstartTime := time.Now()\n\tdefer func() {\n\t\tobs, err := common.ContainerOperationDuration.GetMetricWithLabelValues(\"destroy\")\n\t\tif err == nil {\n\t\t\tobs.Observe(time.Since(startTime).Seconds())\n\t\t}\n\t}()\n\n\t// Cancel a backup if it's already in progress\n\tbackup_context, ok := backup_context_map.Get(containerId)\n\tif ok {\n\t\tbackup_context.cancel()\n\t}\n\n\tct, err := d.ContainerInspect(ctx, containerId)\n\tif err != nil {\n\t\tif common_errors.IsNotFoundError(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\n\t// Ignore err because we want to destroy the container even if it exited\n\tstate, _ := d.getSandboxState(ctx, ct)\n\tif state == enums.SandboxStateDestroyed || state == enums.SandboxStateDestroying {\n\t\td.logger.DebugContext(ctx, \"Sandbox is already destroyed or destroying\", \"containerId\", containerId)\n\t\treturn nil\n\t}\n\n\tif state == enums.SandboxStateStopped {\n\t\terr = d.apiClient.ContainerRemove(ctx, containerId, container.RemoveOptions{\n\t\t\tForce:         false,\n\t\t\tRemoveVolumes: true,\n\t\t})\n\t\tif err == nil {\n\t\t\tgo func() {\n\t\t\t\tcontainerShortId := ct.ID[:12]\n\t\t\t\terr := d.netRulesManager.DeleteNetworkRules(containerShortId)\n\t\t\t\tif err != nil {\n\t\t\t\t\td.logger.ErrorContext(ctx, \"Failed to delete sandbox network settings\", \"error\", err)\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\treturn nil\n\t\t}\n\n\t\t// Handle not found case\n\t\tif errdefs.IsNotFound(err) {\n\t\t\treturn nil\n\t\t}\n\n\t\td.logger.WarnContext(ctx, \"Failed to remove stopped sandbox without force\", \"error\", err)\n\t\td.logger.WarnContext(ctx, \"Trying to remove stopped sandbox with force\")\n\t}\n\n\t// Use exponential backoff helper for container removal\n\terr = utils.RetryWithExponentialBackoff(\n\t\tctx,\n\t\tfmt.Sprintf(\"remove sandbox %s\", containerId),\n\t\tutils.DEFAULT_MAX_RETRIES,\n\t\tutils.DEFAULT_BASE_DELAY,\n\t\tutils.DEFAULT_MAX_DELAY,\n\t\tfunc() error {\n\t\t\treturn d.apiClient.ContainerRemove(ctx, containerId, container.RemoveOptions{\n\t\t\t\tForce: true,\n\t\t\t})\n\t\t},\n\t)\n\tif err != nil {\n\t\t// Handle NotFound error case\n\t\tif errdefs.IsNotFound(err) {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\n\tgo func() {\n\t\tcontainerShortId := ct.ID[:12]\n\t\terr := d.netRulesManager.DeleteNetworkRules(containerShortId)\n\t\tif err != nil {\n\t\t\td.logger.ErrorContext(ctx, \"Failed to delete sandbox network settings\", \"error\", err)\n\t\t}\n\t}()\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/image_build.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\t\"github.com/daytonaio/runner/cmd/runner/config\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/storage\"\n\n\t\"github.com/docker/docker/api/types/build\"\n\tdocker_registry \"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/pkg/jsonmessage\"\n)\n\nfunc (d *DockerClient) BuildImage(ctx context.Context, buildImageDto dto.BuildSnapshotRequestDTO) error {\n\tif !strings.Contains(buildImageDto.Snapshot, \":\") || strings.HasSuffix(buildImageDto.Snapshot, \":\") {\n\t\treturn fmt.Errorf(\"invalid image format: must contain exactly one colon (e.g., 'myimage:1.0')\")\n\t}\n\n\td.logger.InfoContext(ctx, \"Building image\")\n\n\t// Check if image already exists\n\texists, err := d.ImageExists(ctx, buildImageDto.Snapshot, true)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to check if image exists: %w\", err)\n\t}\n\tif exists {\n\t\td.logger.InfoContext(ctx, \"Image already built\")\n\t\treturn nil\n\t}\n\n\t// Create a build context from the provided hashes\n\tbuildContextTar := new(bytes.Buffer)\n\ttarWriter := tar.NewWriter(buildContextTar)\n\tdefer tarWriter.Close()\n\n\tdockerfileContent := []byte(buildImageDto.Dockerfile)\n\tdockerfileHeader := &tar.Header{\n\t\tName: \"Dockerfile\",\n\t\tMode: 0644,\n\t\tSize: int64(len(dockerfileContent)),\n\t}\n\tif err := tarWriter.WriteHeader(dockerfileHeader); err != nil {\n\t\treturn fmt.Errorf(\"failed to write Dockerfile header to tar: %w\", err)\n\t}\n\tif _, err := tarWriter.Write(dockerfileContent); err != nil {\n\t\treturn fmt.Errorf(\"failed to write Dockerfile to tar: %w\", err)\n\t}\n\n\t// Add context files if provided\n\tif len(buildImageDto.Context) > 0 {\n\t\tstorageClient, err := storage.GetObjectStorageClient()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to initialize object storage client: %w\", err)\n\t\t}\n\n\t\t// Process each hash and extract the corresponding tar file\n\t\tfor _, hash := range buildImageDto.Context {\n\t\t\t// Get the tar file from object storage\n\t\t\ttarData, err := storageClient.GetObject(ctx, buildImageDto.OrganizationId, hash)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to get tar from storage with hash %s: %w\", hash, err)\n\t\t\t}\n\n\t\t\td.logger.InfoContext(ctx, \"Processing context file with hash\", \"hash\", hash, \"bytes\", len(tarData))\n\n\t\t\tif len(tarData) == 0 {\n\t\t\t\treturn fmt.Errorf(\"empty tar file received for hash %s\", hash)\n\t\t\t}\n\n\t\t\ttarReader := tar.NewReader(bytes.NewReader(tarData))\n\n\t\t\t// Extract each file from the tar and add it to the build context\n\t\t\tfor {\n\t\t\t\theader, err := tarReader.Next()\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\tbreak // End of tar archive\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\td.logger.WarnContext(ctx, \"Error reading tar with hash\", \"hash\", hash, \"error\", err)\n\t\t\t\t\t// Skip this tar file and continue with the next one\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// Skip directories\n\t\t\t\tif header.Typeflag == tar.TypeDir {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfileContent := new(bytes.Buffer)\n\t\t\t\t_, err = io.Copy(fileContent, tarReader)\n\t\t\t\tif err != nil {\n\t\t\t\t\td.logger.WarnContext(ctx, \"Failed to read file from tar\", \"file\", header.Name, \"error\", err)\n\t\t\t\t\tcontinue // Skip this file and continue with the next one\n\t\t\t\t}\n\n\t\t\t\tbuildHeader := &tar.Header{\n\t\t\t\t\tName: header.Name,\n\t\t\t\t\tMode: header.Mode,\n\t\t\t\t\tSize: int64(fileContent.Len()),\n\t\t\t\t}\n\n\t\t\t\tif err := tarWriter.WriteHeader(buildHeader); err != nil {\n\t\t\t\t\td.logger.WarnContext(ctx, \"Failed to write tar header\", \"file\", header.Name, \"error\", err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif _, err := tarWriter.Write(fileContent.Bytes()); err != nil {\n\t\t\t\t\td.logger.WarnContext(ctx, \"Failed to write file to tar\", \"file\", header.Name, \"error\", err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\td.logger.InfoContext(ctx, \"Added file to build context\", \"file\", header.Name)\n\t\t\t}\n\t\t}\n\t}\n\n\tbuildContext := io.NopCloser(buildContextTar)\n\n\tvar authConfigs map[string]docker_registry.AuthConfig\n\n\tif len(buildImageDto.SourceRegistries) > 0 {\n\t\tauthConfigs = make(map[string]docker_registry.AuthConfig, len(buildImageDto.SourceRegistries)*2)\n\t\tfor _, sourceRegistry := range buildImageDto.SourceRegistries {\n\t\t\tif !sourceRegistry.HasAuth() {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tauthConfig := docker_registry.AuthConfig{\n\t\t\t\tUsername: *sourceRegistry.Username,\n\t\t\t\tPassword: *sourceRegistry.Password,\n\t\t\t}\n\n\t\t\turl := sourceRegistry.Url\n\t\t\turl = strings.TrimPrefix(url, \"https://\")\n\t\t\turl = strings.TrimPrefix(url, \"http://\")\n\n\t\t\t// Docker's build API expects 'index.docker.io/v1/' for Docker Hub auth\n\t\t\tif url == \"docker.io\" {\n\t\t\t\tauthConfigs[\"https://index.docker.io/v1/\"] = authConfig\n\t\t\t} else {\n\t\t\t\tauthConfigs[\"https://\"+url] = authConfig\n\t\t\t\tauthConfigs[\"http://\"+url] = authConfig\n\t\t\t}\n\t\t}\n\t}\n\n\tresp, err := d.apiClient.ImageBuild(ctx, buildContext, build.ImageBuildOptions{\n\t\tTags:        []string{buildImageDto.Snapshot},\n\t\tDockerfile:  \"Dockerfile\",\n\t\tRemove:      true,\n\t\tForceRemove: true,\n\t\tPullParent:  true,\n\t\tPlatform:    \"linux/amd64\", // Force AMD64 architecture\n\t\tAuthConfigs: authConfigs,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to build image: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tlogFilePath, err := config.GetBuildLogFilePath(buildImageDto.Snapshot)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar writer io.Writer = &log.DebugLogWriter{}\n\n\tlogFile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)\n\tif err != nil {\n\t\td.logger.ErrorContext(ctx, \"Failed to open log file\", \"error\", err)\n\t} else {\n\t\tdefer logFile.Close()\n\t\twriter = io.MultiWriter(&log.DebugLogWriter{}, logFile)\n\t}\n\n\terr = jsonmessage.DisplayJSONMessagesStream(resp.Body, writer, 0, true, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\td.logger.InfoContext(ctx, \"Image built successfully\")\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/image_exists.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/image\"\n)\n\nfunc (d *DockerClient) ImageExists(ctx context.Context, imageName string, includeLatest bool) (bool, error) {\n\timageName = strings.Replace(imageName, \"docker.io/\", \"\", 1)\n\n\tif strings.HasSuffix(imageName, \":latest\") && !includeLatest {\n\t\treturn false, nil\n\t}\n\n\timages, err := d.apiClient.ImageList(ctx, image.ListOptions{\n\t\tFilters: filters.NewArgs(filters.Arg(\"reference\", imageName)),\n\t})\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tfound := false\n\tfor _, image := range images {\n\t\t// Check RepoTags for tag-based references\n\t\tfor _, tag := range image.RepoTags {\n\t\t\tif strings.HasPrefix(tag, imageName) {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif found {\n\t\t\tbreak\n\t\t}\n\n\t\t// Check RepoDigests for digest-based references\n\t\tfor _, digest := range image.RepoDigests {\n\t\t\tif strings.HasPrefix(digest, imageName) || strings.HasSuffix(digest, strings.TrimPrefix(imageName, \"library/\")) {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif found {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif found {\n\t\td.logger.InfoContext(ctx, \"Image already pulled\", \"imageName\", imageName)\n\t}\n\n\treturn found, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/image_info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n)\n\ntype ImageInfo struct {\n\tSize       int64\n\tEntrypoint []string\n\tCmd        []string\n\tHash       string // Image hash/digest\n}\n\ntype ImageDigest struct {\n\tDigest string\n\tSize   int64\n}\n\nfunc (d *DockerClient) GetImageInfo(ctx context.Context, imageName string) (*ImageInfo, error) {\n\tinspect, err := d.apiClient.ImageInspect(ctx, imageName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Extract digest from RepoDigests instead of using ID\n\thash := inspect.ID // fallback to ID if no digest found\n\tif len(inspect.RepoDigests) > 0 {\n\t\t// RepoDigests format is like: \"image@sha256:abc123...\"\n\t\tfor _, repoDigest := range inspect.RepoDigests {\n\t\t\tif strings.Contains(repoDigest, \"@\") {\n\t\t\t\tparts := strings.Split(repoDigest, \"@\")\n\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\thash = parts[1]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &ImageInfo{\n\t\tSize:       inspect.Size,\n\t\tEntrypoint: inspect.Config.Entrypoint,\n\t\tCmd:        inspect.Config.Cmd,\n\t\tHash:       hash,\n\t}, nil\n}\n\nfunc (d *DockerClient) InspectImageInRegistry(ctx context.Context, imageName string, registry *dto.RegistryDTO) (*ImageDigest, error) {\n\tdigest, err := d.apiClient.DistributionInspect(ctx, imageName, getRegistryAuth(registry))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttotalSize, err := getImageSizeFromRegistry(ctx, imageName, registry)\n\tif err != nil {\n\t\td.logger.WarnContext(ctx, \"Failed to get image size from registry manifest\", \"imageName\", imageName, \"error\", err)\n\t\ttotalSize = digest.Descriptor.Size\n\t\td.logger.WarnContext(ctx, \"Falling back to descriptor size\", \"imageName\", imageName, \"size\", totalSize)\n\t}\n\n\treturn &ImageDigest{\n\t\tDigest: digest.Descriptor.Digest.String(),\n\t\tSize:   totalSize,\n\t}, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/image_pull.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\t\"github.com/daytonaio/common-go/pkg/timer\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/pkg/jsonmessage\"\n)\n\nfunc (d *DockerClient) PullImage(ctx context.Context, imageName string, reg *dto.RegistryDTO) (*image.InspectResponse, error) {\n\tdefer timer.Timer()()\n\n\ttag := \"latest\"\n\tlastColonIndex := strings.LastIndex(imageName, \":\")\n\tif lastColonIndex != -1 {\n\t\ttag = imageName[lastColonIndex+1:]\n\t}\n\n\tif tag != \"latest\" {\n\t\tinspect, err := d.apiClient.ImageInspect(ctx, imageName)\n\t\tif err == nil {\n\t\t\treturn &inspect, nil\n\t\t}\n\t}\n\n\td.logger.InfoContext(ctx, \"Pulling image\", \"imageName\", imageName)\n\n\tresponseBody, err := d.apiClient.ImagePull(ctx, imageName, image.PullOptions{\n\t\tRegistryAuth: getRegistryAuth(reg),\n\t\tPlatform:     \"linux/amd64\",\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer responseBody.Close()\n\n\terr = jsonmessage.DisplayJSONMessagesStream(responseBody, io.Writer(&log.DebugLogWriter{}), 0, true, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\td.logger.InfoContext(ctx, \"Image pulled successfully\", \"imageName\", imageName)\n\n\tinspect, err := d.apiClient.ImageInspect(ctx, imageName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &inspect, nil\n}\n\nfunc getRegistryAuth(reg *dto.RegistryDTO) string {\n\tif reg == nil || !reg.HasAuth() {\n\t\t// Sometimes registry auth fails if \"\" is sent, so sending \"empty\" instead\n\t\treturn \"empty\"\n\t}\n\n\tauthConfig := registry.AuthConfig{\n\t\tUsername: *reg.Username,\n\t\tPassword: *reg.Password,\n\t}\n\tencodedJSON, err := json.Marshal(authConfig)\n\tif err != nil {\n\t\t// Sometimes registry auth fails if \"\" is sent, so sending \"empty\" instead\n\t\treturn \"empty\"\n\t}\n\n\treturn base64.URLEncoding.EncodeToString(encodedJSON)\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/image_push.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/pkg/jsonmessage\"\n)\n\nfunc (d *DockerClient) PushImage(ctx context.Context, imageName string, reg *dto.RegistryDTO) error {\n\td.logger.InfoContext(ctx, \"Pushing image\", \"imageName\", imageName)\n\n\tresponseBody, err := d.apiClient.ImagePush(ctx, imageName, image.PushOptions{\n\t\tRegistryAuth: getRegistryAuth(reg),\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer responseBody.Close()\n\n\terr = jsonmessage.DisplayJSONMessagesStream(responseBody, io.Writer(&log.DebugLogWriter{}), 0, true, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\td.logger.InfoContext(ctx, \"Image pushed successfully\", \"imageName\", imageName)\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/image_remove.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\n\t\"github.com/containerd/errdefs\"\n\t\"github.com/docker/docker/api/types/image\"\n)\n\nfunc (d *DockerClient) RemoveImage(ctx context.Context, imageName string, force bool) error {\n\t_, err := d.apiClient.ImageRemove(ctx, imageName, image.RemoveOptions{\n\t\tForce:         force,\n\t\tPruneChildren: true,\n\t})\n\tif err != nil {\n\t\tif errdefs.IsNotFound(err) {\n\t\t\td.logger.InfoContext(ctx, \"Image already removed and not found\", \"imageName\", imageName)\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\n\td.logger.InfoContext(ctx, \"Image deleted successfully\", \"imageName\", imageName)\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/monitor.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"log/slog\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/daytonaio/runner/pkg/netrules\"\n\t\"github.com/docker/docker/api/types/events\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/client\"\n)\n\ntype MonitorOptions struct {\n\tOnDestroyEvent func(ctx context.Context)\n}\n\ntype DockerMonitor struct {\n\tapiClient       client.APIClient\n\tlog             *slog.Logger\n\tctx             context.Context\n\tcancel          context.CancelFunc\n\tnetRulesManager *netrules.NetRulesManager\n\topts            MonitorOptions\n}\n\nfunc NewDockerMonitor(logger *slog.Logger, apiClient client.APIClient, netRulesManager *netrules.NetRulesManager, opts MonitorOptions) *DockerMonitor {\n\tctx, cancel := context.WithCancel(context.Background())\n\n\treturn &DockerMonitor{\n\t\tapiClient:       apiClient,\n\t\tlog:             logger.With(slog.String(\"component\", \"docker_monitor\")),\n\t\tctx:             ctx,\n\t\tcancel:          cancel,\n\t\tnetRulesManager: netRulesManager,\n\t\topts:            opts,\n\t}\n}\n\nfunc (dm *DockerMonitor) Stop() {\n\tdm.cancel()\n}\n\nfunc (dm *DockerMonitor) Start() error {\n\t// Start periodic reconciliation\n\tgo dm.reconcilerLoop()\n\n\t// Main monitoring loop\n\tfor {\n\t\tselect {\n\t\tcase <-dm.ctx.Done():\n\t\t\tdm.log.Info(\"Context cancelled, stopping monitor...\")\n\t\t\treturn dm.ctx.Err()\n\n\t\tdefault:\n\t\t\tif err := dm.monitorEvents(); err != nil {\n\t\t\t\tif isConnectionError(err) {\n\t\t\t\t\tdm.log.Warn(\"Events stream ended\", \"error\", err)\n\t\t\t\t\tdm.log.Info(\"Reopening events stream in 2 seconds...\")\n\t\t\t\t\ttime.Sleep(2 * time.Second)\n\t\t\t\t\tcontinue\n\t\t\t\t} else {\n\t\t\t\t\tdm.log.Error(\"Fatal error in monitoring\", \"error\", err)\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// isConnectionError checks if the error is related to connection loss\nfunc isConnectionError(err error) bool {\n\tif err == nil {\n\t\treturn false\n\t}\n\n\t// io.EOF is the normal way the Docker Events stream ends\n\tif err == io.EOF {\n\t\treturn true\n\t}\n\n\terrStr := err.Error()\n\treturn strings.Contains(errStr, \"connection refused\") ||\n\t\tstrings.Contains(errStr, \"connection reset\") ||\n\t\tstrings.Contains(errStr, \"broken pipe\") ||\n\t\tstrings.Contains(errStr, \"no such host\") ||\n\t\tstrings.Contains(errStr, \"timeout\") ||\n\t\tstrings.Contains(errStr, \"context deadline exceeded\") ||\n\t\tstrings.Contains(errStr, \"unexpected EOF\") ||\n\t\tstrings.Contains(errStr, \"Cannot connect to the Docker daemon\")\n}\n\n// monitorEvents handles the actual event monitoring with proper error handling\nfunc (dm *DockerMonitor) monitorEvents() error {\n\t// Create event filters to monitor only container create and stop events\n\teventFilters := events.ListOptions{\n\t\tFilters: filters.NewArgs(\n\t\t\tfilters.Arg(\"type\", \"container\"),\n\t\t\tfilters.Arg(\"event\", \"start\"),\n\t\t\tfilters.Arg(\"event\", \"stop\"),\n\t\t\tfilters.Arg(\"event\", \"kill\"),\n\t\t\tfilters.Arg(\"event\", \"destroy\"),\n\t\t),\n\t}\n\n\t// Start listening for events\n\teventsChan, errsChan := dm.apiClient.Events(dm.ctx, eventFilters)\n\n\t// Reconnection established successfully\n\tdm.reconcileNetworkRules(\"filter\", \"DOCKER-USER\")\n\tdm.reconcileNetworkRules(\"mangle\", \"PREROUTING\")\n\n\tfor {\n\t\tselect {\n\t\tcase event := <-eventsChan:\n\t\t\tdm.log.Debug(\"Received event\", \"event\", event)\n\t\t\tdm.handleContainerEvent(event)\n\n\t\tcase err := <-errsChan:\n\t\t\tif err != nil {\n\t\t\t\tdm.log.Warn(\"Events stream ended\", \"error\", err)\n\t\t\t\treturn err\n\t\t\t}\n\n\t\tcase <-dm.ctx.Done():\n\t\t\treturn dm.ctx.Err()\n\t\t}\n\t}\n}\n\nfunc (dm *DockerMonitor) handleContainerEvent(event events.Message) {\n\tcontainerID := event.Actor.ID\n\taction := event.Action\n\n\tswitch action {\n\tcase \"start\":\n\t\tct, err := dm.apiClient.ContainerInspect(dm.ctx, containerID)\n\t\tif err != nil {\n\t\t\tdm.log.Error(\"Error inspecting container\", \"error\", err)\n\t\t\treturn\n\t\t}\n\t\tshortContainerID := containerID[:12]\n\t\terr = dm.netRulesManager.AssignNetworkRules(shortContainerID, common.GetContainerIpAddress(dm.ctx, &ct))\n\t\tif err != nil {\n\t\t\tdm.log.Error(\"Error assigning network rules\", \"error\", err)\n\t\t}\n\tcase \"stop\":\n\tcase \"kill\":\n\t\tshortContainerID := containerID[:12]\n\t\terr := dm.netRulesManager.UnassignNetworkRules(shortContainerID)\n\t\tif err != nil {\n\t\t\tdm.log.Error(\"Error unassigning network rules\", \"error\", err)\n\t\t}\n\t\terr = dm.netRulesManager.RemoveNetworkLimiter(shortContainerID)\n\t\tif err != nil {\n\t\t\tdm.log.Error(\"Error removing network limiter\", \"error\", err)\n\t\t}\n\tcase \"destroy\":\n\t\tshortContainerID := containerID[:12]\n\t\terr := dm.netRulesManager.DeleteNetworkRules(shortContainerID)\n\t\tif err != nil {\n\t\t\tdm.log.Error(\"Error deleting network rules\", \"error\", err)\n\t\t}\n\t\tif dm.opts.OnDestroyEvent != nil {\n\t\t\tgo dm.opts.OnDestroyEvent(dm.ctx)\n\t\t}\n\t}\n}\n\n// reconcileNetworkRules is called when reconnection is established\nfunc (dm *DockerMonitor) reconcileNetworkRules(table string, chain string) {\n\t// List all DOCKER-USER rules that jump to Daytona chains\n\trules, err := dm.netRulesManager.ListDaytonaRules(table, chain)\n\tif err != nil {\n\t\tdm.log.Error(\"Error listing Daytona rules\", \"error\", err)\n\t\treturn\n\t}\n\n\tfor _, rule := range rules {\n\t\t// Parse the rule to extract chain name and source IP\n\t\targs, err := netrules.ParseRuleArguments(rule)\n\t\tif err != nil {\n\t\t\tdm.log.Error(\"Error parsing rule\", \"rule\", rule, \"error\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Find the chain name and source IP from the rule arguments\n\t\tvar chainName, sourceIP string\n\t\tfor i, arg := range args {\n\t\t\tif arg == \"-j\" && i+1 < len(args) {\n\t\t\t\tchainName = args[i+1]\n\t\t\t}\n\t\t\tif arg == \"-s\" && i+1 < len(args) {\n\t\t\t\tsourceIP = args[i+1]\n\t\t\t}\n\t\t}\n\n\t\tif chainName == \"\" || sourceIP == \"\" {\n\t\t\tdm.log.Warn(\"Could not extract chain name or source IP from rule\", \"rule\", rule)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Extract container ID from chain name (remove DAYTONA-SB- prefix)\n\t\tcontainerID := strings.TrimPrefix(chainName, \"DAYTONA-SB-\")\n\t\tif containerID == chainName {\n\t\t\tdm.log.Warn(\"Invalid chain name format\", \"chainName\", chainName)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Inspect the container to get its current IP\n\t\tcontainer, err := dm.apiClient.ContainerInspect(dm.ctx, containerID)\n\t\tif err != nil {\n\t\t\tdm.log.Error(\"Error inspecting container\", \"containerID\", containerID, \"error\", err)\n\t\t\t// Container doesn't exist, unassign the rules\n\t\t\tif err := dm.netRulesManager.UnassignNetworkRules(containerID); err != nil {\n\t\t\t\tdm.log.Error(\"Error unassigning rules for non-existent container\", \"containerID\", containerID, \"error\", err)\n\t\t\t} else {\n\t\t\t\tdm.log.Info(\"Unassigned rules for non-existent container\", \"containerID\", containerID)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tipAddress := common.GetContainerIpAddress(dm.ctx, &container)\n\n\t\t// Check if the container IP matches the rule's source IP\n\t\t// Handle CIDR notation by extracting just the IP part\n\t\truleIP := sourceIP\n\t\tif strings.Contains(sourceIP, \"/\") {\n\t\t\truleIP = strings.Split(sourceIP, \"/\")[0]\n\t\t}\n\n\t\tif ipAddress != ruleIP {\n\t\t\tdm.log.Warn(\"IP mismatch for container\", \"containerID\", containerID, \"ruleIP\", ruleIP, \"containerIP\", ipAddress)\n\n\t\t\t// Delete only this specific mismatched rule\n\t\t\tif err := dm.netRulesManager.DeleteChainRule(table, chain, rule); err != nil {\n\t\t\t\tdm.log.Error(\"Error deleting mismatched rule for container\", \"containerID\", containerID, \"error\", err)\n\t\t\t} else {\n\t\t\t\tdm.log.Info(\"Deleted mismatched rule for container\", \"containerID\", containerID)\n\t\t\t}\n\t\t}\n\t}\n}\n\n// reconcileChains removes orphaned chains for non-existent containers\nfunc (dm *DockerMonitor) reconcileChains(table string) {\n\t// List all chains that start with DAYTONA-SB-\n\tchains, err := dm.netRulesManager.ListDaytonaChains(table)\n\tif err != nil {\n\t\tdm.log.Error(\"Error listing Daytona chains\", \"error\", err)\n\t\treturn\n\t}\n\n\tfor _, chain := range chains {\n\t\t// Extract container ID from chain name (remove DAYTONA-SB- prefix)\n\t\tcontainerID := strings.TrimPrefix(chain, \"DAYTONA-SB-\")\n\t\tif containerID == chain {\n\t\t\tdm.log.Warn(\"Invalid chain name format\", \"chain\", chain)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check if the container exists\n\t\t_, err := dm.apiClient.ContainerInspect(dm.ctx, containerID)\n\t\tif err != nil {\n\t\t\tdm.log.Info(\"Container does not exist, deleting chain\", \"containerID\", containerID, \"chain\", chain)\n\n\t\t\t// Delete the orphaned chain\n\t\t\tif err := dm.netRulesManager.ClearAndDeleteChain(table, chain); err != nil {\n\t\t\t\tdm.log.Error(\"Error deleting orphaned chain\", \"chain\", chain, \"error\", err)\n\t\t\t} else {\n\t\t\t\tdm.log.Info(\"Deleted orphaned chain\", \"chain\", chain)\n\t\t\t}\n\t\t}\n\t}\n}\n\n// reconcilerLoop runs reconciliation every minute\nfunc (dm *DockerMonitor) reconcilerLoop() {\n\tticker := time.NewTicker(1 * time.Minute)\n\tdefer ticker.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-dm.ctx.Done():\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\tdm.log.Debug(\"Reconciling network rules\")\n\t\t\tdm.reconcileNetworkRules(\"filter\", \"DOCKER-USER\")\n\t\t\tdm.reconcileNetworkRules(\"mangle\", \"PREROUTING\")\n\t\t\tdm.reconcileChains(\"filter\")\n\t\t\tdm.reconcileChains(\"mangle\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/network.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n)\n\nfunc (d *DockerClient) UpdateNetworkSettings(ctx context.Context, containerId string, updateNetworkSettingsDto dto.UpdateNetworkSettingsDTO) error {\n\tinfo, err := d.ContainerInspect(ctx, containerId)\n\tif err != nil {\n\t\treturn err\n\t}\n\tcontainerShortId := info.ID[:12]\n\n\tipAddress := common.GetContainerIpAddress(ctx, info)\n\n\t// Return error if container does not have an IP address\n\tif ipAddress == \"\" {\n\t\treturn errors.New(\"sandbox does not have an IP address\")\n\t}\n\n\tif updateNetworkSettingsDto.NetworkBlockAll != nil && *updateNetworkSettingsDto.NetworkBlockAll {\n\t\terr = d.netRulesManager.SetNetworkRules(containerShortId, ipAddress, \"\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if updateNetworkSettingsDto.NetworkAllowList != nil {\n\t\terr = d.netRulesManager.SetNetworkRules(containerShortId, ipAddress, *updateNetworkSettingsDto.NetworkAllowList)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif updateNetworkSettingsDto.NetworkLimitEgress != nil && *updateNetworkSettingsDto.NetworkLimitEgress {\n\t\terr = d.netRulesManager.SetNetworkLimiter(containerShortId, ipAddress)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/ping.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n)\n\nfunc (d *DockerClient) Ping(ctx context.Context) error {\n\t_, err := d.apiClient.Ping(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"docker ping failed: %w\", err)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/recover.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/daytonaio/runner/pkg/models\"\n)\n\nfunc (d *DockerClient) RecoverSandbox(ctx context.Context, sandboxId string, recoverDto dto.RecoverSandboxDTO) error {\n\t// Deduce recovery type from error reason\n\trecoveryType := common.DeduceRecoveryType(recoverDto.ErrorReason)\n\tif recoveryType == models.UnknownRecoveryType {\n\t\treturn fmt.Errorf(\"unable to deduce recovery type from error reason: %s\", recoverDto.ErrorReason)\n\t}\n\n\tswitch recoveryType {\n\tcase models.RecoveryTypeStorageExpansion:\n\t\treturn d.RecoverFromStorageLimit(ctx, sandboxId, float64(recoverDto.StorageQuota))\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported recovery type: %s\", recoveryType)\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/recover_from_storage_limit.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/runner/pkg/common\"\n)\n\n// RecoverFromStorageLimit attempts to recover a sandbox from storage limit issues\n// by expanding its storage quota by creating new ones with 100MB increments up to 10% of original.\nfunc (d *DockerClient) RecoverFromStorageLimit(ctx context.Context, sandboxId string, originalStorageQuota float64) error {\n\toriginalContainer, err := d.ContainerInspect(ctx, sandboxId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to inspect container: %w\", err)\n\t}\n\n\t// Get current storage size from StorageOpt\n\tcurrentStorage := float64(0)\n\tif originalContainer.HostConfig.StorageOpt != nil {\n\t\tstorageGB, err := common.ParseStorageOptSizeGB(originalContainer.HostConfig.StorageOpt)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcurrentStorage = storageGB\n\t}\n\n\tmaxExpansion := originalStorageQuota * 0.1 // 10% of original\n\tcurrentExpansion := currentStorage - originalStorageQuota\n\tincrement := 0.1 // ~107MB\n\tnewExpansion := currentExpansion + increment\n\tnewStorageQuota := originalStorageQuota + newExpansion\n\n\td.logger.InfoContext(ctx, \"Sandbox storage recovery\",\n\t\t\"sandboxId\", sandboxId,\n\t\t\"originalStorageQuota\", originalStorageQuota,\n\t\t\"currentStorage\", currentStorage,\n\t\t\"currentExpansion\", currentExpansion,\n\t\t\"increment\", increment,\n\t\t\"newExpansion\", newExpansion,\n\t\t\"newStorageQuota\", newStorageQuota,\n\t\t\"maxExpansion\", maxExpansion,\n\t)\n\n\t// Validate expansion limit\n\tif newExpansion > maxExpansion {\n\t\treturn fmt.Errorf(\"storage cannot be further expanded\")\n\t}\n\n\t// Stop container if running\n\tif originalContainer.State.Running {\n\t\td.logger.InfoContext(ctx, \"Stopping sandbox\", \"sandboxId\", sandboxId)\n\t\terr = d.stopContainerWithRetry(ctx, sandboxId, 10)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to stop sandbox: %w\", err)\n\t\t}\n\t}\n\n\treturn d.ContainerDiskResize(ctx, sandboxId, newStorageQuota, 0, 0, \"recovery\")\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/registry_manifest.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\n// getImageSizeFromRegistry fetches the manifest from a container registry and calculates\n// the total (compressed) image size by summing all layer sizes + config size.\n// This is needed because Docker's DistributionInspect only returns the manifest\n// descriptor size, not the total image size.\nfunc getImageSizeFromRegistry(ctx context.Context, imageName string, registry *dto.RegistryDTO) (int64, error) {\n\tref, err := name.ParseReference(imageName)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to parse image reference: %w\", err)\n\t}\n\n\topts := []remote.Option{\n\t\tremote.WithContext(ctx),\n\t\tremote.WithPlatform(v1.Platform{OS: \"linux\", Architecture: \"amd64\"}),\n\t}\n\n\tif registry != nil && registry.HasAuth() {\n\t\topts = append(opts, remote.WithAuth(&authn.Basic{\n\t\t\tUsername: *registry.Username,\n\t\t\tPassword: *registry.Password,\n\t\t}))\n\t}\n\n\tdesc, err := remote.Get(ref, opts...)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to get image descriptor from registry: %w\", err)\n\t}\n\n\timg, err := desc.Image()\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to resolve image from descriptor: %w\", err)\n\t}\n\n\tmanifest, err := img.Manifest()\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"failed to get image manifest: %w\", err)\n\t}\n\n\tvar totalSize int64\n\ttotalSize += manifest.Config.Size\n\tfor _, layer := range manifest.Layers {\n\t\ttotalSize += layer.Size\n\t}\n\n\tif totalSize == 0 {\n\t\treturn 0, fmt.Errorf(\"manifest reported zero total size for %s\", imageName)\n\t}\n\n\treturn totalSize, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/resize.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\tv1 \"github.com/opencontainers/image-spec/specs-go/v1\"\n)\n\nfunc (d *DockerClient) Resize(ctx context.Context, sandboxId string, sandboxDto dto.ResizeSandboxDTO) error {\n\t// Handle disk resize (requires container recreation)\n\t// Value of 0 means \"don't change\" (minimum valid value is 1)\n\tif sandboxDto.Disk > 0 {\n\t\t// Validate container is stopped (disk resize is cold-only)\n\t\tcontainerInfo, err := d.ContainerInspect(ctx, sandboxId)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to inspect container: %w\", err)\n\t\t}\n\t\tif containerInfo.State.Running {\n\t\t\treturn fmt.Errorf(\"disk resize requires stopped container\")\n\t\t}\n\n\t\terr = d.ContainerDiskResize(ctx, sandboxId, float64(sandboxDto.Disk), sandboxDto.Cpu, sandboxDto.Memory, \"resize\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// CPU/memory already applied during container recreation\n\t\treturn nil\n\t}\n\n\t// Check if there's anything to resize (CPU/memory only, no disk change)\n\tif sandboxDto.Cpu == 0 && sandboxDto.Memory == 0 {\n\t\treturn nil // Nothing to resize\n\t}\n\n\t// Build resources with only the fields that need to change (0 = don't change)\n\tresources := container.Resources{}\n\tif sandboxDto.Cpu > 0 {\n\t\tresources.CPUQuota = sandboxDto.Cpu * 100000 // 1 core = 100000\n\t\tresources.CPUPeriod = 100000\n\t}\n\tif sandboxDto.Memory > 0 {\n\t\tresources.Memory = common.GBToBytes(float64(sandboxDto.Memory))\n\t\tresources.MemorySwap = resources.Memory // Disable swap\n\t}\n\n\t_, err := d.apiClient.ContainerUpdate(ctx, sandboxId, container.UpdateConfig{\n\t\tResources: resources,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// ContainerDiskResize recreates a container with new storage size, preserving data via rsync.\n// Optionally updates CPU/memory at the same time (0 = don't change).\n// Used by both storage recovery and disk resize.\n// Container must be stopped before calling this function.\nfunc (d *DockerClient) ContainerDiskResize(ctx context.Context, sandboxId string, newStorageGB float64, cpu int64, memory int64, operationName string) error {\n\tif d.filesystem != \"xfs\" {\n\t\treturn fmt.Errorf(\"%s requires XFS filesystem, current filesystem: %s\", operationName, d.filesystem)\n\t}\n\n\td.logger.InfoContext(ctx, \"Starting operation for sandbox with new storage\", \"operation\", operationName, \"sandboxId\", sandboxId, \"newStorageGB\", newStorageGB)\n\n\toriginalContainer, err := d.ContainerInspect(ctx, sandboxId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to inspect container: %w\", err)\n\t}\n\n\t// Get overlay2 path for data copy\n\tvar overlayDiffPath string\n\tif originalContainer.GraphDriver.Name == \"overlay2\" {\n\t\tif upperDir, ok := originalContainer.GraphDriver.Data[\"UpperDir\"]; ok {\n\t\t\toverlayDiffPath = upperDir\n\t\t\td.logger.DebugContext(ctx, \"Overlay2 UpperDir\", \"path\", overlayDiffPath)\n\t\t}\n\t}\n\n\t// Rename container after validation checks to reduce error handling complexity\n\ttimestamp := time.Now().Unix()\n\toldName := fmt.Sprintf(\"%s-%s-%d\", sandboxId, operationName, timestamp)\n\td.logger.DebugContext(ctx, \"Renaming sandbox\", \"oldName\", oldName)\n\n\terr = d.apiClient.ContainerRename(ctx, sandboxId, oldName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to rename container: %w\", err)\n\t}\n\n\t// Ensure the image is available for container recreation.\n\t// If the image tag was pruned (e.g., declarative-build or backup snapshot),\n\t// fall back to the image ID — Docker retains layers while the container exists.\n\timageRef := originalContainer.Config.Image\n\timageExists, _ := d.ImageExists(ctx, imageRef, true)\n\tif !imageExists {\n\t\td.logger.Warn(\"Image is not found by tag, falling back to image ID\", \"imageRef\", imageRef, \"imageID\", originalContainer.Image)\n\t\toriginalContainer.Config.Image = originalContainer.Image\n\t}\n\n\t// Create new container with new storage\n\tnewHostConfig := originalContainer.HostConfig\n\tnewStorageBytes := common.GBToBytes(newStorageGB)\n\tif newHostConfig.StorageOpt == nil {\n\t\tnewHostConfig.StorageOpt = make(map[string]string)\n\t}\n\tnewHostConfig.StorageOpt[\"size\"] = fmt.Sprintf(\"%d\", newStorageBytes)\n\td.logger.DebugContext(ctx, \"Setting storage\", \"bytes\", newStorageBytes, \"gigabytes\", float64(newStorageBytes)/(1024*1024*1024), \"filesystem\", d.filesystem)\n\n\t// Apply CPU/memory changes if specified (0 = don't change)\n\tif cpu > 0 {\n\t\tnewHostConfig.CPUQuota = cpu * 100000\n\t\tnewHostConfig.CPUPeriod = 100000\n\t\td.logger.DebugContext(ctx, \"Setting CPU quota\", \"cores\", cpu)\n\t}\n\tif memory > 0 {\n\t\tnewHostConfig.Memory = common.GBToBytes(float64(memory))\n\t\tnewHostConfig.MemorySwap = newHostConfig.Memory\n\t\td.logger.DebugContext(ctx, \"Setting memory\", \"gigabytes\", memory)\n\t}\n\n\terr = utils.RetryWithExponentialBackoff(\n\t\tctx,\n\t\tfmt.Sprintf(\"create sandbox %s\", sandboxId),\n\t\tutils.DEFAULT_MAX_RETRIES,\n\t\tutils.DEFAULT_BASE_DELAY,\n\t\tutils.DEFAULT_MAX_DELAY,\n\t\tfunc() error {\n\t\t\t_, createErr := d.apiClient.ContainerCreate(\n\t\t\t\tctx,\n\t\t\t\toriginalContainer.Config,\n\t\t\t\tnewHostConfig,\n\t\t\t\tnil,\n\t\t\t\t&v1.Platform{\n\t\t\t\t\tArchitecture: \"amd64\",\n\t\t\t\t\tOS:           \"linux\",\n\t\t\t\t},\n\t\t\t\tsandboxId,\n\t\t\t)\n\t\t\treturn createErr\n\t\t},\n\t)\n\tif err != nil {\n\t\t_ = d.apiClient.ContainerRename(ctx, oldName, sandboxId)\n\t\treturn fmt.Errorf(\"failed to create new container: %w\", err)\n\t}\n\n\t// Copy data directly between overlay2 layers using rsync\n\tif overlayDiffPath != \"\" {\n\t\td.logger.DebugContext(ctx, \"Copying data directly between overlay2 layers using rsync\")\n\t\terr = d.copyContainerOverlayData(ctx, overlayDiffPath, sandboxId)\n\t\tif err != nil {\n\t\t\td.logger.ErrorContext(ctx, \"Failed to copy overlay data\", \"error\", err)\n\t\t\td.logger.WarnContext(ctx, \"Old sandbox preserved as for manual data recovery\", \"oldName\", oldName)\n\t\t\t_ = d.apiClient.ContainerRemove(ctx, sandboxId, container.RemoveOptions{Force: true})\n\t\t\t_ = d.apiClient.ContainerRename(ctx, oldName, sandboxId)\n\t\t\treturn fmt.Errorf(\"failed to copy data: %w\", err)\n\t\t}\n\t\td.logger.DebugContext(ctx, \"Data copy completed\")\n\t} else {\n\t\td.logger.WarnContext(ctx, \"Could not determine old container overlay2 path, skipping data copy\")\n\t}\n\n\t// Remove old container after successful data copy\n\td.logger.DebugContext(ctx, \"Removing old container\", \"oldName\", oldName)\n\terr = d.apiClient.ContainerRemove(ctx, oldName, container.RemoveOptions{Force: true})\n\tif err != nil {\n\t\td.logger.WarnContext(ctx, \"Failed to remove old container\", \"oldName\", oldName, \"error\", err)\n\t}\n\n\td.logger.InfoContext(ctx, \"Operation completed - container ready to be started\", \"operation\", operationName, \"sandboxId\", sandboxId)\n\treturn nil\n}\n\n// copyContainerOverlayData copies overlay2 data from old container path to new container\n// by inspecting the new container for its overlay path and using rsync to copy the data\nfunc (d *DockerClient) copyContainerOverlayData(ctx context.Context, oldContainerOverlayPath, newContainerId string) error {\n\t// Get the new container's overlay2 UpperDir\n\tnewContainer, err := d.ContainerInspect(ctx, newContainerId)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to inspect new container: %w\", err)\n\t}\n\n\tvar newUpperDir string\n\tif newContainer.GraphDriver.Name == \"overlay2\" {\n\t\tif upperDir, ok := newContainer.GraphDriver.Data[\"UpperDir\"]; ok {\n\t\t\tnewUpperDir = upperDir\n\t\t\td.logger.DebugContext(ctx, \"New container overlay2 UpperDir\", \"newUpperDir\", newUpperDir)\n\t\t}\n\t}\n\n\tif newUpperDir == \"\" {\n\t\td.logger.WarnContext(ctx, \"Could not determine new container overlay2 path, skipping data copy\")\n\t\treturn nil\n\t}\n\n\td.logger.DebugContext(ctx, \"Copying overlay data\", \"from\", oldContainerOverlayPath, \"to\", newUpperDir)\n\n\t// Use rsync with timeout to copy data\n\tcopyCtx, cancel := context.WithTimeout(ctx, 5*time.Minute)\n\tdefer cancel()\n\n\treturn common.RsyncCopy(copyCtx, d.logger, oldContainerOverlayPath, newUpperDir)\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/snapshot_build.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n)\n\nfunc (d *DockerClient) BuildSnapshot(ctx context.Context, req dto.BuildSnapshotRequestDTO) error {\n\terr := d.BuildImage(ctx, req)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttag := req.Snapshot\n\n\tif req.PushToInternalRegistry {\n\t\tif req.Registry.Project == nil {\n\t\t\treturn common_errors.NewBadRequestError(errors.New(\"project is required when pushing to internal registry\"))\n\t\t}\n\t\ttag = fmt.Sprintf(\"%s/%s/%s\", req.Registry.Url, *req.Registry.Project, req.Snapshot)\n\t}\n\n\terr = d.TagImage(ctx, req.Snapshot, tag)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif req.PushToInternalRegistry {\n\t\terr = d.PushImage(ctx, tag, req.Registry)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/snapshot_pull.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n)\n\nfunc (d *DockerClient) PullSnapshot(ctx context.Context, req dto.PullSnapshotRequestDTO) error {\n\t// Pull the image using the pull registry (or none for public images)\n\t_, err := d.PullImage(ctx, req.Snapshot, req.Registry)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif req.NewTag != nil {\n\t\terr = d.TagImage(ctx, req.Snapshot, *req.NewTag)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif req.DestinationRegistry != nil {\n\t\tif req.DestinationRegistry.Project == nil {\n\t\t\treturn common_errors.NewBadRequestError(errors.New(\"project is required when pushing to registry\"))\n\t\t}\n\n\t\tvar targetRef string\n\n\t\t// If destination ref is provided, use it directly; otherwise build it from the image info\n\t\tif req.DestinationRef != nil {\n\t\t\ttargetRef = *req.DestinationRef\n\t\t} else {\n\t\t\t// Get image info to retrieve the hash\n\t\t\timageInfo, err := d.GetImageInfo(ctx, req.Snapshot)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tref := \"daytona-\" + getHashWithoutPrefix(imageInfo.Hash) + \":daytona\"\n\t\t\ttargetRef = fmt.Sprintf(\"%s/%s/%s\", req.DestinationRegistry.Url, *req.DestinationRegistry.Project, ref)\n\t\t}\n\n\t\t// Tag the image for the target registry\n\t\terr = d.TagImage(ctx, req.Snapshot, targetRef)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Push the tagged image\n\t\terr = d.PushImage(ctx, targetRef, req.DestinationRegistry)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc getHashWithoutPrefix(hash string) string {\n\treturn strings.TrimPrefix(hash, \"sha256:\")\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/start.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"slices\"\n\t\"time\"\n\n\t\"github.com/daytonaio/common-go/pkg/timer\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/strslice\"\n)\n\nfunc (d *DockerClient) Start(ctx context.Context, containerId string, authToken *string, metadata map[string]string) (*container.InspectResponse, string, error) {\n\tdefer timer.Timer()()\n\n\t// Cancel a backup if it's already in progress\n\tbackup_context, ok := backup_context_map.Get(containerId)\n\tif ok {\n\t\tbackup_context.cancel()\n\t}\n\n\tc, err := d.ContainerInspect(ctx, containerId)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\n\tif c.State.Running {\n\t\tcontainerIP := common.GetContainerIpAddress(ctx, c)\n\t\tif containerIP == \"\" {\n\t\t\treturn nil, \"\", errors.New(\"sandbox IP not found? Is the sandbox started?\")\n\t\t}\n\n\t\tdaemonVersion, err := d.waitForDaemonRunning(ctx, containerIP, authToken)\n\t\tif err != nil {\n\t\t\treturn nil, \"\", err\n\t\t}\n\n\t\treturn c, daemonVersion, nil\n\t}\n\n\t// Re-establish FUSE mounts that may have died since the container was last running.\n\tif volumesJSON, ok := metadata[\"volumes\"]; ok {\n\t\tvar volumes []dto.VolumeDTO\n\t\tif err := json.Unmarshal([]byte(volumesJSON), &volumes); err == nil && len(volumes) > 0 {\n\t\t\t_, err = d.getVolumesMountPathBinds(ctx, volumes)\n\t\t\tif err != nil {\n\t\t\t\td.logger.ErrorContext(ctx, \"Failed to ensure volume FUSE mounts\", \"error\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\terr = d.apiClient.ContainerStart(ctx, containerId, container.StartOptions{})\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\n\t// make sure container is running\n\trunningContainer, err := d.waitForContainerRunning(ctx, containerId)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\n\tcontainerIP := common.GetContainerIpAddress(ctx, runningContainer)\n\tif containerIP == \"\" {\n\t\treturn nil, \"\", errors.New(\"sandbox IP not found? Is the sandbox started?\")\n\t}\n\n\tif !slices.Equal(c.Config.Entrypoint, strslice.StrSlice{common.DAEMON_PATH}) {\n\t\tprocessesCtx := context.Background()\n\t\tgo func() {\n\t\t\tif err := d.startDaytonaDaemon(processesCtx, containerId, c.Config.WorkingDir); err != nil {\n\t\t\t\td.logger.ErrorContext(ctx, \"Failed to start Daytona daemon\", \"error\", err)\n\t\t\t}\n\t\t}()\n\t}\n\n\t// If daemon is the sandbox entrypoint (common.DAEMON_PATH), it is started as part of the sandbox;\n\t// Otherwise, the daemon is started separately above.\n\t// In either case, we wait for it here.\n\tdaemonVersion, err := d.waitForDaemonRunning(ctx, containerIP, authToken)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\n\tif metadata[\"limitNetworkEgress\"] == \"true\" {\n\t\tgo func() {\n\t\t\tcontainerShortId := c.ID[:12]\n\t\t\terr = d.netRulesManager.SetNetworkLimiter(containerShortId, containerIP)\n\t\t\tif err != nil {\n\t\t\t\td.logger.ErrorContext(ctx, \"Failed to set network limiter\", \"error\", err)\n\t\t\t}\n\t\t}()\n\t}\n\n\treturn runningContainer, daemonVersion, nil\n}\n\nfunc (d *DockerClient) waitForContainerRunning(ctx context.Context, containerId string) (*container.InspectResponse, error) {\n\tdefer timer.Timer()()\n\n\ttimeout := time.Duration(d.sandboxStartTimeoutSec) * time.Second\n\ttimeoutCtx, cancel := context.WithTimeout(ctx, timeout)\n\tdefer cancel()\n\n\tticker := time.NewTicker(10 * time.Millisecond)\n\tdefer ticker.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-timeoutCtx.Done():\n\t\t\treturn nil, errors.New(\"timeout waiting for the sandbox to start - please ensure that your entrypoint is long-running\")\n\t\tcase <-ticker.C:\n\t\t\tc, err := d.ContainerInspect(timeoutCtx, containerId)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif c.State.Running {\n\t\t\t\treturn c, nil\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/state.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n\t\"github.com/docker/docker/api/types/container\"\n\n\tcommon_errors \"github.com/daytonaio/common-go/pkg/errors\"\n)\n\nfunc (d *DockerClient) GetSandboxState(ctx context.Context, sandboxId string) (enums.SandboxState, error) {\n\tif sandboxId == \"\" {\n\t\treturn enums.SandboxStateUnknown, nil\n\t}\n\n\tct, err := d.ContainerInspect(ctx, sandboxId)\n\tif err != nil {\n\t\tif common_errors.IsNotFoundError(err) {\n\t\t\treturn enums.SandboxStateDestroyed, nil\n\t\t}\n\t\treturn enums.SandboxStateError, err\n\t}\n\n\treturn d.getSandboxState(ctx, ct)\n}\n\nfunc (d *DockerClient) getSandboxState(ctx context.Context, ct *container.InspectResponse) (enums.SandboxState, error) {\n\tif ct == nil {\n\t\treturn enums.SandboxStateUnknown, errors.New(\"invalid sandbox reference\")\n\t}\n\n\tswitch ct.State.Status {\n\tcase container.StateCreated:\n\t\treturn enums.SandboxStateCreating, nil\n\n\tcase container.StateRunning:\n\t\tif d.isContainerPullingImage(ctx, ct.ID) {\n\t\t\treturn enums.SandboxStatePullingSnapshot, nil\n\t\t}\n\t\treturn enums.SandboxStateStarted, nil\n\n\tcase container.StatePaused:\n\t\treturn enums.SandboxStateStopped, nil\n\n\tcase container.StateRestarting:\n\t\treturn enums.SandboxStateStarting, nil\n\n\tcase container.StateRemoving:\n\t\treturn enums.SandboxStateDestroying, nil\n\n\tcase container.StateExited:\n\t\tif ct.State.ExitCode == 0 || ct.State.ExitCode == 137 || ct.State.ExitCode == 143 || ct.State.ExitCode == 255 {\n\t\t\treturn enums.SandboxStateStopped, nil\n\t\t}\n\t\treturn enums.SandboxStateError, fmt.Errorf(\"sandbox exited with code %d, reason: %s\", ct.State.ExitCode, ct.State.Error)\n\n\tcase container.StateDead:\n\t\treturn enums.SandboxStateDestroyed, nil\n\n\tdefault:\n\t\treturn enums.SandboxStateUnknown, nil\n\t}\n}\n\n// isContainerPullingImage checks if the container is still in image pulling phase\nfunc (d *DockerClient) isContainerPullingImage(ctx context.Context, containerId string) bool {\n\toptions := container.LogsOptions{\n\t\tShowStdout: true,\n\t\tShowStderr: true,\n\t\tTail:       \"10\", // Look at last 10 lines\n\t}\n\n\tlogs, err := d.apiClient.ContainerLogs(ctx, containerId, options)\n\tif err != nil {\n\t\treturn false\n\t}\n\tdefer logs.Close()\n\n\t// Read logs and check for pull messages\n\tbuf := make([]byte, 1024)\n\tn, _ := logs.Read(buf)\n\tlogContent := string(buf[:n])\n\n\treturn strings.Contains(logContent, \"Pulling from\") ||\n\t\tstrings.Contains(logContent, \"Downloading\") ||\n\t\tstrings.Contains(logContent, \"Extracting\")\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/stop.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n\t\"github.com/docker/docker/api/types/container\"\n)\n\nfunc (d *DockerClient) Stop(ctx context.Context, containerId string) error {\n\t// Deduce sandbox state first\n\tstate, err := d.GetSandboxState(ctx, containerId)\n\tif err == nil && state == enums.SandboxStateStopped {\n\t\td.logger.DebugContext(ctx, \"Sandbox is already stopped\", \"containerId\", containerId)\n\t\treturn nil\n\t}\n\n\tif err != nil {\n\t\td.logger.WarnContext(ctx, \"Failed to get sandbox state\", \"containerId\", containerId, \"error\", err)\n\t\td.logger.WarnContext(ctx, \"Continuing with stop operation\")\n\t}\n\n\t// Cancel a backup if it's already in progress\n\tbackup_context, ok := backup_context_map.Get(containerId)\n\tif ok {\n\t\tbackup_context.cancel()\n\t}\n\n\terr = d.stopContainerWithRetry(ctx, containerId, 10)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Wait for container to actually stop\n\tstatusCh, errCh := d.apiClient.ContainerWait(ctx, containerId, container.WaitConditionNotRunning)\n\tselect {\n\tcase err := <-errCh:\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error waiting for sandbox %s to stop: %w\", containerId, err)\n\t\t}\n\tcase <-statusCh:\n\t\t// Container stopped successfully\n\t\treturn nil\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\t}\n\n\td.logger.DebugContext(ctx, \"Sandbox stopped successfully\", \"containerId\", containerId)\n\treturn nil\n}\n\n// stopContainerWithRetry attempts to stop the specified container by sending a stop signal,\n// retrying the operation with exponential backoff up to a maximum number of attempts.\n// If stopping fails after all retries, it falls back to forcefully killing the container.\n//\n// Parameters:\n//   - ctx: context for cancellation and timeout\n//   - containerId: ID of the container to stop\n//   - timeout: number of seconds to wait for graceful stop before forcing a kill\n//\n// Returns an error if the container could not be stopped or killed.\nfunc (d *DockerClient) stopContainerWithRetry(ctx context.Context, containerId string, timeout int) error {\n\t// Use exponential backoff helper for container stopping\n\terr := utils.RetryWithExponentialBackoff(\n\t\tctx,\n\t\tfmt.Sprintf(\"stop sandbox %s\", containerId),\n\t\tutils.DEFAULT_MAX_RETRIES,\n\t\tutils.DEFAULT_BASE_DELAY,\n\t\tutils.DEFAULT_MAX_DELAY,\n\t\tfunc() error {\n\t\t\treturn d.apiClient.ContainerStop(ctx, containerId, container.StopOptions{\n\t\t\t\tSignal:  \"SIGTERM\",\n\t\t\t\tTimeout: &timeout,\n\t\t\t})\n\t\t},\n\t)\n\tif err != nil {\n\t\td.logger.WarnContext(ctx, \"Failed to stop sandbox for multiple attempts\", \"containerId\", containerId, \"attempts\", utils.DEFAULT_MAX_RETRIES, \"error\", err)\n\t\td.logger.WarnContext(ctx, \"Trying to kill sandbox\", \"containerId\", containerId)\n\t\terr = d.apiClient.ContainerKill(ctx, containerId, \"KILL\")\n\t\tif err != nil {\n\t\t\td.logger.WarnContext(ctx, \"Failed to kill sandbox\", \"containerId\", containerId, \"error\", err)\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/tag_image.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc (d *DockerClient) TagImage(ctx context.Context, sourceImage string, targetImage string) error {\n\td.logger.InfoContext(ctx, \"Tagging image\", \"sourceImage\", sourceImage, \"targetImage\", targetImage)\n\n\t// Extract repository and tag from targetImage\n\tlastColonIndex := strings.LastIndex(targetImage, \":\")\n\tvar repo, tag string\n\n\tif lastColonIndex == -1 {\n\t\treturn fmt.Errorf(\"invalid target image format: %s\", targetImage)\n\t} else {\n\t\trepo = targetImage[:lastColonIndex]\n\t\ttag = targetImage[lastColonIndex+1:]\n\t}\n\n\tif repo == \"\" || tag == \"\" {\n\t\treturn fmt.Errorf(\"invalid target image format: %s\", targetImage)\n\t}\n\n\terr := d.apiClient.ImageTag(ctx, sourceImage, targetImage)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\td.logger.InfoContext(ctx, \"Image tagged successfully\", \"sourceImage\", sourceImage, \"targetImage\", targetImage)\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/volumes_cleanup.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// normalizePath removes all trailing slashes from a path to ensure consistent comparison.\n// This handles cases where Docker API might return paths with trailing slashes (single or multiple).\nfunc normalizePath(path string) string {\n\treturn strings.TrimRight(path, \"/\")\n}\n\n// CleanupOrphanedVolumeMounts removes volume mount directories that are no longer used by any container.\n// Throttled to run at most once per volumeCleanupInterval (default 30s).\n// Skips directories within exclusion period to avoid race conditions during sandbox creation.\nfunc (d *DockerClient) CleanupOrphanedVolumeMounts(ctx context.Context) {\n\td.volumeCleanupMutex.Lock()\n\tdefer d.volumeCleanupMutex.Unlock()\n\n\tif d.volumeCleanupInterval > 0 && time.Since(d.lastVolumeCleanup) < d.volumeCleanupInterval {\n\t\treturn\n\t}\n\td.lastVolumeCleanup = time.Now()\n\n\tdryRun := d.volumeCleanupDryRun\n\td.logger.InfoContext(ctx, \"Volume cleanup\", \"dry-run\", dryRun)\n\n\tvolumeMountBasePath := getVolumeMountBasePath()\n\tmountDirs, err := filepath.Glob(filepath.Join(volumeMountBasePath, volumeMountPrefix+\"*\"))\n\tif err != nil || len(mountDirs) == 0 {\n\t\treturn\n\t}\n\n\tinUse, err := d.getInUseVolumeMounts(ctx)\n\tif err != nil {\n\t\td.logger.ErrorContext(ctx, \"Volume cleanup aborted\", \"error\", err)\n\t\treturn\n\t}\n\n\texclusionPeriod := d.volumeCleanupExclusionPeriod\n\n\tfor _, dir := range mountDirs {\n\t\tif inUse[normalizePath(dir)] {\n\t\t\tcontinue\n\t\t}\n\t\tif d.isRecentlyCreated(dir, exclusionPeriod) {\n\t\t\tcontinue\n\t\t}\n\t\tif dryRun {\n\t\t\td.logger.InfoContext(ctx, \"[DRY-RUN] Would clean orphaned volume mount\", \"path\", dir)\n\t\t\tcontinue\n\t\t}\n\t\td.logger.InfoContext(ctx, \"Cleaning orphaned volume mount\", \"path\", dir)\n\t\td.unmountAndRemoveDir(ctx, dir)\n\t}\n}\n\nfunc (d *DockerClient) getInUseVolumeMounts(ctx context.Context) (map[string]bool, error) {\n\tinUse := make(map[string]bool)\n\tprefix := filepath.Join(getVolumeMountBasePath(), volumeMountPrefix)\n\n\tcontainers, err := d.apiClient.ContainerList(ctx, container.ListOptions{All: true})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Use Mounts from list response - avoids expensive ContainerInspect calls\n\tfor _, ct := range containers {\n\t\tfor _, m := range ct.Mounts {\n\t\t\tsrc := normalizePath(m.Source)\n\t\t\tif strings.HasPrefix(src, prefix) {\n\t\t\t\tinUse[src] = true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn inUse, nil\n}\n\nfunc (d *DockerClient) unmountAndRemoveDir(ctx context.Context, path string) {\n\tmountBasePath := getVolumeMountBasePath()\n\tvolumeMountPath := filepath.Join(mountBasePath, volumeMountPrefix)\n\tcleanPath := filepath.Clean(path)\n\tif !strings.HasPrefix(cleanPath, volumeMountPath) {\n\t\treturn\n\t}\n\n\tif d.isDirectoryMounted(cleanPath) {\n\t\tif err := exec.Command(\"umount\", cleanPath).Run(); err != nil {\n\t\t\td.logger.ErrorContext(ctx, \"Failed to unmount directory\", \"path\", cleanPath, \"error\", err)\n\t\t\treturn\n\t\t}\n\t\t// Was FUSE mounted, data is on S3 - safe to remove\n\t\tif err := os.RemoveAll(cleanPath); err != nil {\n\t\t\td.logger.ErrorContext(ctx, \"Failed to remove directory\", \"path\", cleanPath, \"error\", err)\n\t\t}\n\t\treturn\n\t}\n\n\t// Not mounted - might have unsynced local data\n\tif d.isDirEmpty(ctx, cleanPath) {\n\t\tif err := os.Remove(cleanPath); err != nil {\n\t\t\td.logger.ErrorContext(ctx, \"Failed to remove directory\", \"path\", cleanPath, \"error\", err)\n\t\t}\n\t\treturn\n\t}\n\n\ttimestamp := time.Now().Unix()\n\tgarbagePath := filepath.Join(mountBasePath, fmt.Sprintf(\"garbage-%d-%s\", timestamp, strings.TrimPrefix(filepath.Base(cleanPath), volumeMountPrefix)))\n\td.logger.DebugContext(ctx, \"Renaming non-empty volume directory\", \"path\", garbagePath)\n\tif err := os.Rename(cleanPath, garbagePath); err != nil {\n\t\td.logger.ErrorContext(ctx, \"Failed to rename directory\", \"path\", cleanPath, \"error\", err)\n\t}\n}\n\nfunc (d *DockerClient) isDirEmpty(ctx context.Context, path string) bool {\n\tentries, err := os.ReadDir(path)\n\tif err != nil {\n\t\td.logger.ErrorContext(ctx, \"Failed to read directory\", \"path\", path, \"error\", err)\n\t\treturn false\n\t}\n\treturn len(entries) == 0\n}\n\nfunc (d *DockerClient) isRecentlyCreated(path string, exclusionPeriod time.Duration) bool {\n\tif exclusionPeriod <= 0 {\n\t\treturn false\n\t}\n\tinfo, err := os.Stat(path)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\t// Use ctime (inode change time) instead of mtime (content modification time)\n\tstat, ok := info.Sys().(*syscall.Stat_t)\n\tif !ok {\n\t\t// Fallback to mtime if syscall.Stat_t is not available\n\t\treturn time.Since(info.ModTime()) < exclusionPeriod\n\t}\n\tctime := time.Unix(stat.Ctim.Sec, stat.Ctim.Nsec)\n\treturn time.Since(ctime) < exclusionPeriod\n}\n"
  },
  {
    "path": "apps/runner/pkg/docker/volumes_mountpaths.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"crypto/md5\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/daytonaio/common-go/pkg/log\"\n\t\"github.com/daytonaio/runner/cmd/runner/config\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n)\n\nconst volumeMountPrefix = \"daytona-volume-\"\n\nfunc getVolumeMountBasePath() string {\n\tif config.GetEnvironment() == \"development\" {\n\t\treturn \"/tmp\"\n\t}\n\treturn \"/mnt\"\n}\n\nfunc (d *DockerClient) getVolumesMountPathBinds(ctx context.Context, volumes []dto.VolumeDTO) ([]string, error) {\n\tvolumeMountPathBinds := make([]string, 0)\n\n\tfor _, vol := range volumes {\n\t\tvolumeIdPrefixed := fmt.Sprintf(\"%s%s\", volumeMountPrefix, vol.VolumeId)\n\t\trunnerVolumeMountPath := d.getRunnerVolumeMountPath(volumeIdPrefixed, vol.Subpath)\n\n\t\t// Create unique key for this volume+subpath combination for mutex\n\t\tvolumeKey := d.getVolumeKey(volumeIdPrefixed, vol.Subpath)\n\n\t\t// Get or create mutex for this volume+subpath\n\t\td.volumeMutexesMutex.Lock()\n\t\tvolumeMutex, exists := d.volumeMutexes[volumeKey]\n\t\tif !exists {\n\t\t\tvolumeMutex = &sync.Mutex{}\n\t\t\td.volumeMutexes[volumeKey] = volumeMutex\n\t\t}\n\t\td.volumeMutexesMutex.Unlock()\n\n\t\t// Lock this specific volume's mutex\n\t\tvolumeMutex.Lock()\n\t\tdefer volumeMutex.Unlock()\n\n\t\tsubpathStr := \"\"\n\t\tif vol.Subpath != nil {\n\t\t\tsubpathStr = *vol.Subpath\n\t\t}\n\n\t\tif d.isDirectoryMounted(runnerVolumeMountPath) {\n\t\t\td.logger.InfoContext(ctx, \"volume is already mounted\", \"volumeId\", volumeIdPrefixed, \"subpath\", subpathStr, \"runnerVolumeMountPath\", runnerVolumeMountPath)\n\t\t\tvolumeMountPathBinds = append(volumeMountPathBinds, fmt.Sprintf(\"%s/:%s/\", runnerVolumeMountPath, vol.MountPath))\n\t\t\tcontinue\n\t\t}\n\n\t\t// Track if directory existed before we create it\n\t\t_, statErr := os.Stat(runnerVolumeMountPath)\n\t\tdirExisted := statErr == nil\n\n\t\terr := os.MkdirAll(runnerVolumeMountPath, 0755)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create mount directory %s: %s\", runnerVolumeMountPath, err)\n\t\t}\n\n\t\td.logger.InfoContext(ctx, \"mounting S3 volume\", \"volumeId\", volumeIdPrefixed, \"subpath\", subpathStr, \"runnerVolumeMountPath\", runnerVolumeMountPath)\n\n\t\tcmd := d.getMountCmd(ctx, volumeIdPrefixed, vol.Subpath, runnerVolumeMountPath)\n\t\terr = cmd.Run()\n\t\tif err != nil {\n\t\t\tif !dirExisted {\n\t\t\t\tos.Remove(runnerVolumeMountPath)\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"failed to mount S3 volume %s (subpath: %s) to %s: %s\", volumeIdPrefixed, subpathStr, runnerVolumeMountPath, err)\n\t\t}\n\n\t\t// Wait for FUSE mount to be fully ready before proceeding\n\t\terr = d.waitForMountReady(ctx, runnerVolumeMountPath)\n\t\tif err != nil {\n\t\t\tif !dirExisted {\n\t\t\t\tumountErr := exec.Command(\"umount\", runnerVolumeMountPath).Run()\n\t\t\t\tif umountErr != nil {\n\t\t\t\t\td.logger.WarnContext(ctx, \"Failed to unmount directory during cleanup\", \"path\", runnerVolumeMountPath, \"error\", umountErr)\n\t\t\t\t}\n\t\t\t\tremoveErr := os.Remove(runnerVolumeMountPath)\n\t\t\t\tif removeErr != nil {\n\t\t\t\t\td.logger.WarnContext(ctx, \"Failed to remove mount directory during cleanup\", \"path\", runnerVolumeMountPath, \"error\", removeErr)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"mount %s not ready after mounting: %s\", runnerVolumeMountPath, err)\n\t\t}\n\n\t\td.logger.InfoContext(ctx, \"mounted S3 volume\", \"volumeId\", volumeIdPrefixed, \"subpath\", subpathStr, \"runnerVolumeMountPath\", runnerVolumeMountPath)\n\n\t\tvolumeMountPathBinds = append(volumeMountPathBinds, fmt.Sprintf(\"%s/:%s/\", runnerVolumeMountPath, vol.MountPath))\n\t}\n\n\treturn volumeMountPathBinds, nil\n}\n\nfunc (d *DockerClient) getRunnerVolumeMountPath(volumeId string, subpath *string) string {\n\t// If subpath is provided, create a unique mount point for this volume+subpath combination\n\tmountDirName := volumeId\n\tif subpath != nil && *subpath != \"\" {\n\t\t// Create a short hash of the subpath to keep the path reasonable\n\t\thash := md5.Sum([]byte(*subpath))\n\t\thashStr := hex.EncodeToString(hash[:])[:8]\n\t\tmountDirName = fmt.Sprintf(\"%s-%s\", volumeId, hashStr)\n\t}\n\n\tvolumePath := filepath.Join(getVolumeMountBasePath(), mountDirName)\n\n\treturn volumePath\n}\n\nfunc (d *DockerClient) getVolumeKey(volumeId string, subpath *string) string {\n\tif subpath == nil || *subpath == \"\" {\n\t\treturn volumeId\n\t}\n\treturn fmt.Sprintf(\"%s:%s\", volumeId, *subpath)\n}\n\nfunc (d *DockerClient) isDirectoryMounted(path string) bool {\n\tcmd := exec.Command(\"mountpoint\", path)\n\t_, err := cmd.Output()\n\n\treturn err == nil\n}\n\n// waitForMountReady waits for a FUSE mount to be fully accessible\n// FUSE mounts can be asynchronous - the mount command may return before the filesystem is ready\n// This prevents a race condition where the container writes to the directory before the mount is ready\nfunc (d *DockerClient) waitForMountReady(ctx context.Context, path string) error {\n\tmaxAttempts := 50 // 5 seconds total (50 * 100ms)\n\tsleepDuration := 100 * time.Millisecond\n\n\tfor i := 0; i < maxAttempts; i++ {\n\t\t// First verify the mountpoint is still registered\n\t\tif !d.isDirectoryMounted(path) {\n\t\t\treturn fmt.Errorf(\"mount disappeared during readiness check\")\n\t\t}\n\n\t\t// Try to stat the mount point to ensure filesystem is responsive\n\t\t// This will fail if FUSE is not ready yet\n\t\t_, err := os.Stat(path)\n\t\tif err == nil {\n\t\t\t// Try to read directory to ensure it's fully operational\n\t\t\t_, err = os.ReadDir(path)\n\t\t\tif err == nil {\n\t\t\t\td.logger.InfoContext(ctx, \"mount is ready\", \"path\", path, \"attempts\", i+1)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\n\t\t// Wait a bit before retrying\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn fmt.Errorf(\"context cancelled while waiting for mount ready: %w\", ctx.Err())\n\t\tcase <-time.After(sleepDuration):\n\t\t\t// Continue to next iteration\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"mount did not become ready within timeout\")\n}\n\nfunc (d *DockerClient) getMountCmd(ctx context.Context, volume string, subpath *string, path string) *exec.Cmd {\n\targs := []string{\"--allow-other\", \"--allow-delete\", \"--allow-overwrite\", \"--file-mode\", \"0666\", \"--dir-mode\", \"0777\"}\n\n\tif subpath != nil && *subpath != \"\" {\n\t\t// Ensure subpath ends with /\n\t\tprefix := *subpath\n\t\tif !strings.HasSuffix(prefix, \"/\") {\n\t\t\tprefix = prefix + \"/\"\n\t\t}\n\t\targs = append(args, \"--prefix\", prefix)\n\t}\n\n\targs = append(args, volume, path)\n\n\tvar envVars []string\n\tif d.awsEndpointUrl != \"\" {\n\t\tenvVars = append(envVars, \"AWS_ENDPOINT_URL=\"+d.awsEndpointUrl)\n\t}\n\tif d.awsAccessKeyId != \"\" {\n\t\tenvVars = append(envVars, \"AWS_ACCESS_KEY_ID=\"+d.awsAccessKeyId)\n\t}\n\tif d.awsSecretAccessKey != \"\" {\n\t\tenvVars = append(envVars, \"AWS_SECRET_ACCESS_KEY=\"+d.awsSecretAccessKey)\n\t}\n\tif d.awsRegion != \"\" {\n\t\tenvVars = append(envVars, \"AWS_REGION=\"+d.awsRegion)\n\t}\n\n\t// No systemd (containerized) — daemon orphan survives runner restarts naturally.\n\tcmd := exec.Command(\"mount-s3\", args...)\n\tcmd.Env = envVars\n\n\t_, err := os.Stat(\"/run/systemd/system\")\n\tif err == nil {\n\t\t// Isolate mount-s3 in its own cgroup so the FUSE daemon survives runner restarts.\n\t\tsdArgs := []string{\"--scope\"}\n\t\tfor _, env := range envVars {\n\t\t\tsdArgs = append(sdArgs, \"--setenv=\"+env)\n\t\t}\n\t\tsdArgs = append(sdArgs, \"--\", \"mount-s3\")\n\t\tsdArgs = append(sdArgs, args...)\n\t\tcmd = exec.CommandContext(ctx, \"systemd-run\", sdArgs...)\n\t}\n\n\tcmd.Stderr = io.Writer(&log.ErrorLogWriter{})\n\tcmd.Stdout = io.Writer(&log.InfoLogWriter{})\n\n\treturn cmd\n}\n"
  },
  {
    "path": "apps/runner/pkg/models/backup_info.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage models\n\nimport (\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n)\n\ntype BackupInfo struct {\n\tState enums.BackupState\n\tError error\n}\n"
  },
  {
    "path": "apps/runner/pkg/models/enums/sandbox_state.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage enums\n\ntype SandboxState string\n\nconst (\n\tSandboxStateCreating        SandboxState = \"creating\"\n\tSandboxStateRestoring       SandboxState = \"restoring\"\n\tSandboxStateDestroyed       SandboxState = \"destroyed\"\n\tSandboxStateDestroying      SandboxState = \"destroying\"\n\tSandboxStateStarted         SandboxState = \"started\"\n\tSandboxStateStopped         SandboxState = \"stopped\"\n\tSandboxStateStarting        SandboxState = \"starting\"\n\tSandboxStateStopping        SandboxState = \"stopping\"\n\tSandboxStateResizing        SandboxState = \"resizing\"\n\tSandboxStateError           SandboxState = \"error\"\n\tSandboxStateUnknown         SandboxState = \"unknown\"\n\tSandboxStatePullingSnapshot SandboxState = \"pulling_snapshot\"\n)\n\nfunc (s SandboxState) String() string {\n\treturn string(s)\n}\n"
  },
  {
    "path": "apps/runner/pkg/models/enums/snapshot_state.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage enums\n\ntype BackupState string\n\nconst (\n\tBackupStateNone       BackupState = \"NONE\"\n\tBackupStatePending    BackupState = \"PENDING\"\n\tBackupStateInProgress BackupState = \"IN_PROGRESS\"\n\tBackupStateCompleted  BackupState = \"COMPLETED\"\n\tBackupStateFailed     BackupState = \"FAILED\"\n)\n\nfunc (s BackupState) String() string {\n\treturn string(s)\n}\n"
  },
  {
    "path": "apps/runner/pkg/models/recovery_type.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage models\n\n// RecoveryType represents the type of recovery operation\ntype RecoveryType string\n\nconst (\n\tRecoveryTypeStorageExpansion RecoveryType = \"storage-expansion\"\n\tUnknownRecoveryType          RecoveryType = \"\"\n)\n"
  },
  {
    "path": "apps/runner/pkg/models/sandbox_info.go",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage models\n\nimport \"github.com/daytonaio/runner/pkg/models/enums\"\n\ntype SandboxInfo struct {\n\tSandboxState      enums.SandboxState\n\tBackupState       enums.BackupState\n\tBackupErrorReason *string\n}\n"
  },
  {
    "path": "apps/runner/pkg/models/service_info.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage models\n\ntype RunnerServiceInfo struct {\n\tServiceName string\n\tHealthy     bool\n\tErr         error\n}\n"
  },
  {
    "path": "apps/runner/pkg/netrules/assign.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage netrules\n\n// AssignNetworkRules assigns network rules to a container by inserting a rule in DOCKER-USER chain\nfunc (manager *NetRulesManager) AssignNetworkRules(name string, sourceIp string) error {\n\t// Add prefix to chain name\n\tchainName := formatChainName(name)\n\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\t// check does the chain exist\n\texists, err := manager.ipt.ChainExists(\"filter\", chainName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// return if the chain does not exist\n\tif !exists {\n\t\treturn nil\n\t}\n\n\treturn manager.ipt.InsertUnique(\"filter\", \"DOCKER-USER\", 1, \"-j\", chainName, \"-s\", sourceIp, \"-p\", \"all\")\n}\n"
  },
  {
    "path": "apps/runner/pkg/netrules/delete.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage netrules\n\nimport \"strings\"\n\n// DeleteNetworkRules completely removes network rules for a container\nfunc (manager *NetRulesManager) DeleteNetworkRules(name string) error {\n\t// Add prefix to chain name\n\tchainName := formatChainName(name)\n\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\t// First unassign the rules from the container (atomic within the same mutex)\n\trules, err := manager.ipt.List(\"filter\", \"DOCKER-USER\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Find and remove rules that reference our chain\n\tfor _, rule := range rules {\n\t\tif strings.Contains(rule, chainName) {\n\t\t\t// Parse the rule to extract arguments\n\t\t\targs, err := ParseRuleArguments(rule)\n\t\t\tif err != nil {\n\t\t\t\t// Skip malformed rules\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif err := manager.ipt.Delete(\"filter\", \"DOCKER-USER\", args...); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\t// Then delete the chain and all its rules\n\treturn manager.ipt.ClearAndDeleteChain(\"filter\", chainName)\n}\n"
  },
  {
    "path": "apps/runner/pkg/netrules/limiter.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage netrules\n\nimport \"strings\"\n\n// SetNetworkLimiter creates and configures network rules for a container\nfunc (manager *NetRulesManager) SetNetworkLimiter(name string, sourceIp string) error {\n\n\t// Add prefix to chain name\n\tchainName := formatChainName(name)\n\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\t// Create the chain (ignores if already exists)\n\terr := manager.ipt.NewChain(\"mangle\", chainName)\n\tif err != nil && !strings.Contains(err.Error(), \"Chain already exists\") {\n\t\treturn err\n\t}\n\n\t// Clear existing rules to ensure clean state\n\tif err := manager.ipt.ClearChain(\"mangle\", chainName); err != nil {\n\t\treturn err\n\t}\n\n\t// Add rule to mark packets\n\tif err := manager.ipt.AppendUnique(\"mangle\", chainName, \"-j\", \"MARK\", \"--set-mark\", \"999\"); err != nil {\n\t\treturn err\n\t}\n\n\t// Assign the rules to the container IP\n\tif err := manager.ipt.AppendUnique(\"mangle\", \"PREROUTING\", \"-j\", chainName, \"-s\", sourceIp, \"-p\", \"all\"); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// RemoveNetworkLimiter removes the network limiter for a container\nfunc (manager *NetRulesManager) RemoveNetworkLimiter(name string) error {\n\tchainName := formatChainName(name)\n\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\t// First unassign the rules from the container\n\trules, err := manager.ipt.List(\"mangle\", \"PREROUTING\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Find and remove rules that reference our chain\n\tfor _, rule := range rules {\n\t\tif strings.Contains(rule, chainName) {\n\t\t\t// Parse the rule to extract arguments\n\t\t\targs, err := ParseRuleArguments(rule)\n\t\t\tif err != nil {\n\t\t\t\t// Skip malformed rules\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif err := manager.ipt.Delete(\"mangle\", \"PREROUTING\", args...); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\t// Delete the chain and all its rules\n\treturn manager.ipt.ClearAndDeleteChain(\"mangle\", chainName)\n}\n"
  },
  {
    "path": "apps/runner/pkg/netrules/netrules.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage netrules\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"log/slog\"\n\t\"os/exec\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/coreos/go-iptables/iptables\"\n)\n\n// NetRulesManager provides thread-safe operations for managing network rules\ntype NetRulesManager struct {\n\tlog        *slog.Logger\n\tipt        *iptables.IPTables\n\tmu         sync.Mutex\n\tpersistent bool\n\tctx        context.Context\n\tcancel     context.CancelFunc\n}\n\n// NewNetRulesManager creates a new instance of NetRulesManager\nfunc NewNetRulesManager(logger *slog.Logger, persistent bool) (*NetRulesManager, error) {\n\tipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif logger == nil {\n\t\treturn nil, errors.New(\"logger can't be nil\")\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\n\treturn &NetRulesManager{\n\t\tlog:        logger.With(slog.String(\"component\", \"netrules_manager\")),\n\t\tipt:        ipt,\n\t\tpersistent: persistent,\n\t\tctx:        ctx,\n\t\tcancel:     cancel,\n\t}, nil\n}\n\nfunc (manager *NetRulesManager) Start() error {\n\t// Start periodic reconciliation\n\tif manager.persistent {\n\t\tgo manager.persistRulesLoop()\n\t}\n\n\treturn nil\n}\n\n// Stop gracefully stops the NetRulesManager\nfunc (manager *NetRulesManager) Stop() {\n\tif manager.cancel != nil {\n\t\tmanager.cancel()\n\t}\n}\n\n// saveIptablesRules saves the current iptables rules to make them persistent\nfunc (manager *NetRulesManager) saveIptablesRules() error {\n\tif manager.persistent {\n\t\tcmd := exec.Command(\"sh\", \"-c\", \"iptables-save > /etc/iptables/rules.v4\")\n\t\treturn cmd.Run()\n\t}\n\treturn nil\n}\n\n// ListDaytonaRules returns all DOCKER-USER rules that jump to Daytona chains\nfunc (manager *NetRulesManager) ListDaytonaRules(table string, chain string) ([]string, error) {\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\trules, err := manager.ipt.List(table, chain)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar daytonaRules []string\n\tfor _, rule := range rules {\n\t\tif strings.Contains(rule, ChainPrefix) {\n\t\t\tdaytonaRules = append(daytonaRules, rule)\n\t\t}\n\t}\n\n\treturn daytonaRules, nil\n}\n\n// DeleteChainRule deletes a specific rule from a specific chain\nfunc (manager *NetRulesManager) DeleteChainRule(table string, chain string, rule string) error {\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\targs, err := ParseRuleArguments(rule)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn manager.ipt.Delete(table, chain, args...)\n}\n\n// ListDaytonaChains returns all chains that start with DAYTONA-SB-\nfunc (manager *NetRulesManager) ListDaytonaChains(table string) ([]string, error) {\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\tchains, err := manager.ipt.ListChains(table)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar daytonaChains []string\n\tfor _, chain := range chains {\n\t\tif strings.HasPrefix(chain, ChainPrefix) {\n\t\t\tdaytonaChains = append(daytonaChains, chain)\n\t\t}\n\t}\n\n\treturn daytonaChains, nil\n}\n\n// ClearAndDeleteChain deletes a specific table chain\nfunc (manager *NetRulesManager) ClearAndDeleteChain(table string, name string) error {\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\treturn manager.ipt.ClearAndDeleteChain(table, name)\n}\n\n// persistRulesLoop persists the iptables rules\nfunc (manager *NetRulesManager) persistRulesLoop() {\n\tticker := time.NewTicker(time.Minute)\n\tdefer ticker.Stop()\n\n\tmanager.log.Info(\"Starting iptables persistence loop\")\n\n\tfor {\n\t\tselect {\n\t\tcase <-manager.ctx.Done():\n\t\t\tmanager.log.Info(\"Stopping iptables persistence loop\")\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\tif err := manager.saveIptablesRules(); err != nil {\n\t\t\t\tmanager.log.Error(\"Failed to save iptables rules\", \"error\", err)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/netrules/set.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage netrules\n\nimport \"strings\"\n\n// SetNetworkRules creates and configures network rules for a container\nfunc (manager *NetRulesManager) SetNetworkRules(name string, sourceIp string, networkAllowList string) error {\n\t// Parse the allowed networks\n\tallowedNetworks, err := parseCidrNetworks(networkAllowList)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Add prefix to chain name\n\tchainName := formatChainName(name)\n\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\t// Create the chain (ignores if already exists)\n\terr = manager.ipt.NewChain(\"filter\", chainName)\n\tif err != nil && !strings.Contains(err.Error(), \"Chain already exists\") {\n\t\treturn err\n\t}\n\n\t// Clear existing rules to ensure clean state\n\tif err := manager.ipt.ClearChain(\"filter\", chainName); err != nil {\n\t\treturn err\n\t}\n\n\t// Add rules to allow traffic from the specified networks\n\tfor _, network := range allowedNetworks {\n\t\tif err := manager.ipt.AppendUnique(\"filter\", chainName, \"-j\", \"RETURN\", \"-d\", network.String(), \"-p\", \"all\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Add a final rule to block all other traffic\n\tif err := manager.ipt.AppendUnique(\"filter\", chainName, \"-j\", \"DROP\", \"-p\", \"all\"); err != nil {\n\t\treturn err\n\t}\n\n\t// Assign the rules to the container (atomic within the same mutex)\n\tif err := manager.ipt.InsertUnique(\"filter\", \"DOCKER-USER\", 1, \"-j\", chainName, \"-s\", sourceIp, \"-p\", \"all\"); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/netrules/unassign.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage netrules\n\nimport \"strings\"\n\n// UnassignNetworkRules removes network rules assignment from a container\nfunc (manager *NetRulesManager) UnassignNetworkRules(name string) error {\n\t// Add prefix to chain name\n\tchainName := formatChainName(name)\n\n\tmanager.mu.Lock()\n\tdefer manager.mu.Unlock()\n\n\t// Get all rules from DOCKER-USER chain\n\trules, err := manager.ipt.List(\"filter\", \"DOCKER-USER\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Find and remove rules that reference our chain\n\tfor _, rule := range rules {\n\t\tif strings.Contains(rule, chainName) {\n\t\t\t// Parse the rule to extract arguments\n\t\t\targs, err := ParseRuleArguments(rule)\n\t\t\tif err != nil {\n\t\t\t\t// Skip malformed rules\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif err := manager.ipt.Delete(\"filter\", \"DOCKER-USER\", args...); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/netrules/utils.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage netrules\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n)\n\nconst (\n\t// ChainPrefix is the prefix used for all Daytona sandbox chains\n\tChainPrefix = \"DAYTONA-SB-\"\n)\n\n// ParseCidrNetworks parses a comma-separated list of CIDR networks and returns them as an array\nfunc parseCidrNetworks(networks string) ([]*net.IPNet, error) {\n\tnetworkList := strings.Split(networks, \",\")\n\tvar cidrs []*net.IPNet\n\n\tfor _, network := range networkList {\n\t\ttrimmedNetwork := strings.TrimSpace(network)\n\t\tif trimmedNetwork == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t_, ipNet, err := net.ParseCIDR(trimmedNetwork)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcidrs = append(cidrs, ipNet)\n\t}\n\n\treturn cidrs, nil\n}\n\n// ParseRuleArguments parses an iptables rule string and returns the arguments\nfunc ParseRuleArguments(rule string) ([]string, error) {\n\t// Remove the \"-A CHAIN_NAME \" prefix and split into arguments\n\t// Rule format: \"-A DOCKER-USER -s 172.17.0.2/32 -j chain_name\"\n\tif strings.HasPrefix(rule, \"-A \") {\n\t\t// Find the first space after \"-A CHAIN_NAME\"\n\t\tparts := strings.SplitN(rule, \" \", 3)\n\t\tif len(parts) >= 3 {\n\t\t\treturn strings.Fields(parts[2]), nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"invalid rule format: %s\", rule)\n}\n\n// formatChainName adds the DAYTONA-SB- prefix to a chain name if it doesn't already have it\nfunc formatChainName(name string) string {\n\tif strings.HasPrefix(name, ChainPrefix) {\n\t\treturn name\n\t}\n\treturn ChainPrefix + name\n}\n"
  },
  {
    "path": "apps/runner/pkg/runner/runner.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage runner\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"log/slog\"\n\t\"time\"\n\n\t\"github.com/daytonaio/runner/internal/metrics\"\n\t\"github.com/daytonaio/runner/pkg/cache\"\n\t\"github.com/daytonaio/runner/pkg/docker\"\n\t\"github.com/daytonaio/runner/pkg/models\"\n\t\"github.com/daytonaio/runner/pkg/netrules\"\n\t\"github.com/daytonaio/runner/pkg/services\"\n\t\"github.com/daytonaio/runner/pkg/sshgateway\"\n)\n\ntype RunnerInstanceConfig struct {\n\tLogger             *slog.Logger\n\tBackupInfoCache    *cache.BackupInfoCache\n\tSnapshotErrorCache *cache.SnapshotErrorCache\n\tDocker             *docker.DockerClient\n\tMetricsCollector   *metrics.Collector\n\tSandboxService     *services.SandboxService\n\tNetRulesManager    *netrules.NetRulesManager\n\tSSHGatewayService  *sshgateway.Service\n}\n\ntype Runner struct {\n\tLogger             *slog.Logger\n\tBackupInfoCache    *cache.BackupInfoCache\n\tSnapshotErrorCache *cache.SnapshotErrorCache\n\tDocker             *docker.DockerClient\n\tMetricsCollector   *metrics.Collector\n\tSandboxService     *services.SandboxService\n\tNetRulesManager    *netrules.NetRulesManager\n\tSSHGatewayService  *sshgateway.Service\n}\n\nvar runner *Runner\n\nfunc GetInstance(config *RunnerInstanceConfig) (*Runner, error) {\n\tif config != nil && runner != nil {\n\t\treturn nil, errors.New(\"runner instance already initialized\")\n\t}\n\n\tif runner == nil {\n\t\tif config == nil {\n\t\t\treturn nil, errors.New(\"runner instance not initialized and no config provided\")\n\t\t}\n\n\t\tlogger := slog.Default()\n\t\tif config.Logger != nil {\n\t\t\tlogger = config.Logger\n\t\t}\n\n\t\trunner = &Runner{\n\t\t\tLogger:             logger.With(slog.String(\"component\", \"runner\")),\n\t\t\tBackupInfoCache:    config.BackupInfoCache,\n\t\t\tSnapshotErrorCache: config.SnapshotErrorCache,\n\t\t\tDocker:             config.Docker,\n\t\t\tSandboxService:     config.SandboxService,\n\t\t\tMetricsCollector:   config.MetricsCollector,\n\t\t\tNetRulesManager:    config.NetRulesManager,\n\t\t\tSSHGatewayService:  config.SSHGatewayService,\n\t\t}\n\t}\n\n\treturn runner, nil\n}\n\nfunc (r *Runner) InspectRunnerServices(ctx context.Context) []models.RunnerServiceInfo {\n\trunnerServicesInfo := make([]models.RunnerServiceInfo, 0)\n\n\tpingCtx, cancel := context.WithTimeout(ctx, 2*time.Second)\n\tdefer cancel()\n\n\tdockerHealth := models.RunnerServiceInfo{\n\t\tServiceName: \"docker\",\n\t\tHealthy:     true,\n\t}\n\n\terr := r.Docker.Ping(pingCtx)\n\tif err != nil {\n\t\tr.Logger.WarnContext(ctx, \"Failed to ping Docker daemon\", \"error\", err)\n\t\tdockerHealth.Healthy = false\n\t\tdockerHealth.Err = err\n\t}\n\n\trunnerServicesInfo = append(runnerServicesInfo, dockerHealth)\n\n\treturn runnerServicesInfo\n}\n"
  },
  {
    "path": "apps/runner/pkg/runner/v2/executor/backup.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage executor\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n)\n\nfunc (e *Executor) createBackup(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar createBackupDto dto.CreateBackupDTO\n\terr := e.parsePayload(job.Payload, &createBackupDto)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal payload: %w\", err)\n\t}\n\n\t// TODO: is state cache needed?\n\treturn nil, e.docker.CreateBackup(ctx, job.ResourceId, createBackupDto)\n}\n"
  },
  {
    "path": "apps/runner/pkg/runner/v2/executor/executor.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage executor\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net/http\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\t\"go.opentelemetry.io/otel/trace\"\n\n\t\"github.com/daytonaio/common-go/pkg/utils\"\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/runner/internal/metrics\"\n\trunnerapiclient \"github.com/daytonaio/runner/pkg/apiclient\"\n\t\"github.com/daytonaio/runner/pkg/docker\"\n)\n\ntype ExecutorConfig struct {\n\tDocker    *docker.DockerClient\n\tCollector *metrics.Collector\n\tLogger    *slog.Logger\n}\n\n// Executor handles job execution\ntype Executor struct {\n\tlog       *slog.Logger\n\tclient    *apiclient.APIClient\n\tdocker    *docker.DockerClient\n\tcollector *metrics.Collector\n}\n\n// NewExecutor creates a new job executor\nfunc NewExecutor(cfg *ExecutorConfig) (*Executor, error) {\n\tapiClient, err := runnerapiclient.GetApiClient()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create API client: %w\", err)\n\t}\n\n\treturn &Executor{\n\t\tlog:       cfg.Logger.With(slog.String(\"component\", \"executor\")),\n\t\tclient:    apiClient,\n\t\tdocker:    cfg.Docker,\n\t\tcollector: cfg.Collector,\n\t}, nil\n}\n\n// Execute processes a job and updates its status\nfunc (e *Executor) Execute(ctx context.Context, job *apiclient.Job) {\n\t// Extract trace context from job to continue distributed trace\n\tctx = e.extractTraceContext(ctx, job)\n\n\t// Build log fields\n\tjobLog := e.log.With(\n\t\tslog.String(\"job_id\", job.GetId()),\n\t\tslog.String(\"job_type\", string(job.GetType())),\n\t)\n\n\t// Add resource info if present\n\tif resourceType := job.GetResourceType(); resourceType != \"\" {\n\t\tjobLog = jobLog.With(slog.String(\"resource_type\", resourceType))\n\t}\n\tif resourceId := job.GetResourceId(); resourceId != \"\" {\n\t\tjobLog = jobLog.With(slog.String(\"resource_id\", resourceId))\n\t}\n\n\t// Add trace info to logs if available\n\tif spanCtx := trace.SpanContextFromContext(ctx); spanCtx.IsValid() {\n\t\tjobLog = jobLog.With(\n\t\t\tslog.String(\"trace_id\", spanCtx.TraceID().String()),\n\t\t\tslog.String(\"span_id\", spanCtx.SpanID().String()),\n\t\t)\n\t}\n\n\tjobLog.InfoContext(ctx, \"Executing job\")\n\n\t// Execute the job based on type\n\tresultMetadata, err := e.executeJob(ctx, job)\n\n\t// Update job status\n\tstatus := apiclient.JOBSTATUS_COMPLETED\n\tvar errorMessage *string\n\tif err != nil {\n\t\tstatus = apiclient.JOBSTATUS_FAILED\n\t\terrMsg := err.Error()\n\t\terrorMessage = &errMsg\n\t\tjobLog.ErrorContext(ctx, \"Job failed\", \"error\", err)\n\t} else {\n\t\tjobLog.InfoContext(ctx, \"Job completed successfully\")\n\t}\n\n\t// Report status to API\n\tif err := e.updateJobStatus(ctx, job.GetId(), status, resultMetadata, errorMessage); err != nil {\n\t\tjobLog.ErrorContext(ctx, \"Failed to update job status\", \"error\", err)\n\t}\n}\n\n// executeJob dispatches to the appropriate handler based on job type\nfunc (e *Executor) executeJob(ctx context.Context, job *apiclient.Job) (any, error) {\n\t// Create a span for the job execution\n\ttracer := otel.Tracer(\"runner\")\n\tctx, span := tracer.Start(ctx, fmt.Sprintf(\"execute_%s\", job.GetType()),\n\t\ttrace.WithAttributes(\n\t\t\tattribute.String(\"job.id\", job.GetId()),\n\t\t\tattribute.String(\"job.type\", string(job.GetType())),\n\t\t\tattribute.String(\"job.status\", string(job.GetStatus())),\n\t\t),\n\t)\n\tdefer span.End()\n\n\t// Add resource attributes if present\n\tif resourceType := job.GetResourceType(); resourceType != \"\" {\n\t\tspan.SetAttributes(attribute.String(\"resource.type\", resourceType))\n\t}\n\tif resourceId := job.GetResourceId(); resourceId != \"\" {\n\t\tspan.SetAttributes(attribute.String(\"resource.id\", resourceId))\n\t}\n\n\t// Dispatch to handler\n\tvar resultMetadata any\n\tvar err error\n\tswitch job.GetType() {\n\tcase apiclient.JOBTYPE_CREATE_SANDBOX:\n\t\tresultMetadata, err = e.createSandbox(ctx, job)\n\tcase apiclient.JOBTYPE_START_SANDBOX:\n\t\tresultMetadata, err = e.startSandbox(ctx, job)\n\tcase apiclient.JOBTYPE_STOP_SANDBOX:\n\t\tresultMetadata, err = e.stopSandbox(ctx, job)\n\tcase apiclient.JOBTYPE_DESTROY_SANDBOX:\n\t\tresultMetadata, err = e.destroySandbox(ctx, job)\n\tcase apiclient.JOBTYPE_RESIZE_SANDBOX:\n\t\tresultMetadata, err = e.resizeSandbox(ctx, job)\n\tcase apiclient.JOBTYPE_CREATE_BACKUP:\n\t\tresultMetadata, err = e.createBackup(ctx, job)\n\tcase apiclient.JOBTYPE_BUILD_SNAPSHOT:\n\t\tresultMetadata, err = e.buildSnapshot(ctx, job)\n\tcase apiclient.JOBTYPE_PULL_SNAPSHOT:\n\t\tresultMetadata, err = e.pullSnapshot(ctx, job)\n\tcase apiclient.JOBTYPE_REMOVE_SNAPSHOT:\n\t\tresultMetadata, err = e.removeSnapshot(ctx, job)\n\tcase apiclient.JOBTYPE_UPDATE_SANDBOX_NETWORK_SETTINGS:\n\t\tresultMetadata, err = e.updateNetworkSettings(ctx, job)\n\tcase apiclient.JOBTYPE_INSPECT_SNAPSHOT_IN_REGISTRY:\n\t\tresultMetadata, err = e.inspectSnapshotInRegistry(ctx, job)\n\tcase apiclient.JOBTYPE_RECOVER_SANDBOX:\n\t\tresultMetadata, err = e.recoverSandbox(ctx, job)\n\tdefault:\n\t\terr = fmt.Errorf(\"unknown job type: %s\", job.GetType())\n\t}\n\n\t// Record error in span if present\n\tif err != nil {\n\t\tspan.RecordError(err)\n\t\tspan.SetAttributes(attribute.Bool(\"error\", true))\n\t\tspan.SetStatus(codes.Error, \"job execution failed\")\n\t}\n\n\treturn resultMetadata, err\n}\n\n// updateJobStatus reports job completion status to the API\nfunc (e *Executor) updateJobStatus(ctx context.Context, jobID string, status apiclient.JobStatus, resultMetadata any, errorMessage *string) error {\n\t// Create a span for the API call - otelhttp will create a child span for the HTTP request\n\ttracer := otel.Tracer(\"runner\")\n\tctx, span := tracer.Start(ctx, \"update_job_status\",\n\t\ttrace.WithSpanKind(trace.SpanKindClient),\n\t\ttrace.WithAttributes(\n\t\t\tattribute.String(\"job.id\", jobID),\n\t\t\tattribute.String(\"job.status\", string(status)),\n\t\t),\n\t)\n\tdefer span.End()\n\n\tif errorMessage != nil {\n\t\tspan.SetAttributes(attribute.String(\"job.error\", *errorMessage))\n\t}\n\n\tupdateStatus := apiclient.NewUpdateJobStatus(status)\n\tif errorMessage != nil {\n\t\tupdateStatus.SetErrorMessage(*errorMessage)\n\t}\n\n\tif resultMetadata != nil {\n\t\tresultMetadataJSON, err := json.Marshal(resultMetadata)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to marshal result metadata: %w\", err)\n\t\t}\n\t\tupdateStatus.SetResultMetadata(string(resultMetadataJSON))\n\t}\n\n\terr := utils.RetryWithExponentialBackoff(\n\t\tctx,\n\t\tfmt.Sprintf(\"update job %s status to %s\", jobID, status),\n\t\tutils.DEFAULT_MAX_RETRIES,\n\t\tutils.DEFAULT_BASE_DELAY,\n\t\tutils.DEFAULT_MAX_DELAY,\n\t\tfunc() error {\n\t\t\treq := e.client.JobsAPI.UpdateJobStatus(ctx, jobID).UpdateJobStatus(*updateStatus)\n\t\t\t_, httpResp, err := req.Execute()\n\t\t\tif err != nil && httpResp != nil && httpResp.StatusCode >= http.StatusBadRequest && httpResp.StatusCode < http.StatusInternalServerError {\n\t\t\t\treturn &utils.NonRetryableError{Err: fmt.Errorf(\"HTTP %d: %w\", httpResp.StatusCode, err)}\n\t\t\t}\n\t\t\treturn err\n\t\t},\n\t)\n\n\tif err != nil {\n\t\tspan.RecordError(err)\n\t\tspan.SetAttributes(attribute.Bool(\"error\", true))\n\t\tspan.SetStatus(codes.Error, \"update job status failed\")\n\t}\n\n\treturn err\n}\n\n// parsePayload is a helper to parse job payload into a specific type\nfunc (e *Executor) parsePayload(payload *string, target interface{}) error {\n\tif payload == nil || *payload == \"\" {\n\t\treturn fmt.Errorf(\"payload is required\")\n\t}\n\n\tif err := json.Unmarshal([]byte(*payload), target); err != nil {\n\t\treturn fmt.Errorf(\"failed to unmarshal payload: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// extractTraceContext extracts OpenTelemetry trace context from the job\n// and returns a new context with the trace information to continue distributed tracing\nfunc (e *Executor) extractTraceContext(ctx context.Context, job *apiclient.Job) context.Context {\n\ttraceContext := job.GetTraceContext()\n\tif len(traceContext) == 0 {\n\t\te.log.DebugContext(ctx, \"no trace context in job\", \"job_id\", job.GetId())\n\t\treturn ctx\n\t}\n\n\t// Convert map[string]interface{} to map[string]string for propagation\n\tcarrier := make(propagation.MapCarrier)\n\tfor k, v := range traceContext {\n\t\tif strVal, ok := v.(string); ok {\n\t\t\tcarrier[k] = strVal\n\t\t}\n\t}\n\n\t// Use W3C Trace Context propagator to extract trace info\n\tpropagator := propagation.TraceContext{}\n\tctx = propagator.Extract(ctx, carrier)\n\n\t// Log trace information if extracted successfully\n\tif spanCtx := trace.SpanContextFromContext(ctx); spanCtx.IsValid() {\n\t\te.log.DebugContext(ctx, \"extracted trace context from job\",\n\t\t\tslog.String(\"job_id\", job.GetId()),\n\t\t\tslog.String(\"trace_id\", spanCtx.TraceID().String()),\n\t\t\tslog.String(\"span_id\", spanCtx.SpanID().String()),\n\t\t\tslog.Bool(\"sampled\", spanCtx.IsSampled()),\n\t\t)\n\t} else {\n\t\te.log.WarnContext(ctx, \"trace context present but invalid\",\n\t\t\tslog.String(\"job_id\", job.GetId()),\n\t\t\tslog.Any(\"trace_context\", traceContext),\n\t\t)\n\t}\n\n\treturn ctx\n}\n"
  },
  {
    "path": "apps/runner/pkg/runner/v2/executor/sandbox.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage executor\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n\t\"github.com/daytonaio/runner/pkg/common\"\n)\n\nfunc (e *Executor) createSandbox(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar createSandboxDto dto.CreateSandboxDTO\n\terr := e.parsePayload(job.Payload, &createSandboxDto)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal payload: %w\", err)\n\t}\n\n\t_, daemonVersion, err := e.docker.Create(ctx, createSandboxDto)\n\tif err != nil {\n\t\tcommon.ContainerOperationCount.WithLabelValues(\"create\", string(common.PrometheusOperationStatusFailure)).Inc()\n\t\treturn nil, common.FormatRecoverableError(err)\n\t}\n\n\tcommon.ContainerOperationCount.WithLabelValues(\"create\", string(common.PrometheusOperationStatusSuccess)).Inc()\n\n\treturn dto.StartSandboxResponse{\n\t\tDaemonVersion: daemonVersion,\n\t}, nil\n}\n\nfunc (e *Executor) startSandbox(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar payload StartSandboxPayload\n\terr := e.parsePayload(job.Payload, &payload)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal payload: %w\", err)\n\t}\n\n\t_, daemonVersion, err := e.docker.Start(ctx, job.ResourceId, payload.AuthToken, payload.Metadata)\n\tif err != nil {\n\t\treturn nil, common.FormatRecoverableError(err)\n\t}\n\n\treturn dto.StartSandboxResponse{\n\t\tDaemonVersion: daemonVersion,\n\t}, nil\n}\n\nfunc (e *Executor) stopSandbox(ctx context.Context, job *apiclient.Job) (any, error) {\n\terr := e.docker.Stop(ctx, job.ResourceId)\n\tif err != nil {\n\t\treturn nil, common.FormatRecoverableError(err)\n\t}\n\n\treturn nil, nil\n}\n\nfunc (e *Executor) destroySandbox(ctx context.Context, job *apiclient.Job) (any, error) {\n\terr := e.docker.Destroy(ctx, job.ResourceId)\n\tif err != nil {\n\t\tcommon.ContainerOperationCount.WithLabelValues(\"destroy\", string(common.PrometheusOperationStatusFailure)).Inc()\n\t\treturn nil, common.FormatRecoverableError(err)\n\t}\n\n\tcommon.ContainerOperationCount.WithLabelValues(\"destroy\", string(common.PrometheusOperationStatusSuccess)).Inc()\n\n\treturn nil, nil\n}\n\nfunc (e *Executor) updateNetworkSettings(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar updateNetworkSettingsDto dto.UpdateNetworkSettingsDTO\n\terr := e.parsePayload(job.Payload, &updateNetworkSettingsDto)\n\tif err != nil {\n\t\treturn nil, common.FormatRecoverableError(fmt.Errorf(\"failed to unmarshal payload: %w\", err))\n\t}\n\n\treturn nil, e.docker.UpdateNetworkSettings(ctx, job.ResourceId, updateNetworkSettingsDto)\n}\n\nfunc (e *Executor) recoverSandbox(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar recoverSandboxDto dto.RecoverSandboxDTO\n\terr := e.parsePayload(job.Payload, &recoverSandboxDto)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal payload: %w\", err)\n\t}\n\n\terr = e.docker.RecoverSandbox(ctx, job.ResourceId, recoverSandboxDto)\n\tif err != nil {\n\t\treturn nil, common.FormatRecoverableError(err)\n\t}\n\n\treturn nil, nil\n}\n\nfunc (e *Executor) resizeSandbox(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar resizeSandboxDto dto.ResizeSandboxDTO\n\terr := e.parsePayload(job.Payload, &resizeSandboxDto)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal payload: %w\", err)\n\t}\n\n\terr = e.docker.Resize(ctx, job.ResourceId, resizeSandboxDto)\n\tif err != nil {\n\t\tcommon.ContainerOperationCount.WithLabelValues(\"resize\", string(common.PrometheusOperationStatusFailure)).Inc()\n\t\treturn nil, common.FormatRecoverableError(err)\n\t}\n\n\tcommon.ContainerOperationCount.WithLabelValues(\"resize\", string(common.PrometheusOperationStatusSuccess)).Inc()\n\n\treturn nil, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/runner/v2/executor/snapshot.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage executor\n\nimport (\n\t\"context\"\n\t\"errors\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/runner/pkg/api/dto\"\n)\n\nfunc (e *Executor) buildSnapshot(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar request dto.BuildSnapshotRequestDTO\n\terr := e.parsePayload(job.Payload, &request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\terr = e.docker.BuildSnapshot(ctx, request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo, err := e.docker.GetImageInfo(ctx, request.Snapshot)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfoResponse := dto.SnapshotInfoResponse{\n\t\tName:       request.Snapshot,\n\t\tSizeGB:     float64(info.Size) / (1024 * 1024 * 1024), // Convert bytes to GB\n\t\tEntrypoint: info.Entrypoint,\n\t\tCmd:        info.Cmd,\n\t\tHash:       dto.HashWithoutPrefix(info.Hash),\n\t}\n\n\treturn infoResponse, nil\n}\n\nfunc (e *Executor) pullSnapshot(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar request dto.PullSnapshotRequestDTO\n\terr := e.parsePayload(job.Payload, &request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\terr = e.docker.PullSnapshot(ctx, request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo, err := e.docker.GetImageInfo(ctx, request.Snapshot)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfoResponse := dto.SnapshotInfoResponse{\n\t\tName:       request.Snapshot,\n\t\tSizeGB:     float64(info.Size) / (1024 * 1024 * 1024), // Convert bytes to GB\n\t\tEntrypoint: info.Entrypoint,\n\t\tCmd:        info.Cmd,\n\t\tHash:       dto.HashWithoutPrefix(info.Hash),\n\t}\n\n\treturn infoResponse, nil\n}\n\nfunc (e *Executor) removeSnapshot(ctx context.Context, job *apiclient.Job) (any, error) {\n\tif job.Payload == nil || *job.Payload == \"\" {\n\t\treturn nil, errors.New(\"payload is required\")\n\t}\n\n\treturn nil, e.docker.RemoveImage(ctx, *job.Payload, true)\n}\n\nfunc (e *Executor) inspectSnapshotInRegistry(ctx context.Context, job *apiclient.Job) (any, error) {\n\tvar request dto.InspectSnapshotInRegistryRequestDTO\n\terr := e.parsePayload(job.Payload, &request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdigest, err := e.docker.InspectImageInRegistry(ctx, request.Snapshot, request.Registry)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn dto.SnapshotDigestResponse{\n\t\tHash:   dto.HashWithoutPrefix(digest.Digest),\n\t\tSizeGB: float64(digest.Size) / (1024 * 1024 * 1024),\n\t}, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/runner/v2/executor/types.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage executor\n\ntype StartSandboxPayload struct {\n\tAuthToken *string           `json:\"authToken,omitempty\"`\n\tMetadata  map[string]string `json:\"metadata,omitempty\"`\n}\n"
  },
  {
    "path": "apps/runner/pkg/runner/v2/healthcheck/healthcheck.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage healthcheck\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"time\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"github.com/daytonaio/runner/internal\"\n\t\"github.com/daytonaio/runner/internal/metrics\"\n\trunnerapiclient \"github.com/daytonaio/runner/pkg/apiclient\"\n\t\"github.com/daytonaio/runner/pkg/docker\"\n)\n\ntype HealthcheckServiceConfig struct {\n\tInterval   time.Duration\n\tTimeout    time.Duration\n\tCollector  *metrics.Collector\n\tLogger     *slog.Logger\n\tDomain     string\n\tApiPort    int\n\tProxyPort  int\n\tTlsEnabled bool\n\tDocker     *docker.DockerClient\n}\n\n// Service handles healthcheck reporting to the API\ntype Service struct {\n\tlog        *slog.Logger\n\tinterval   time.Duration\n\ttimeout    time.Duration\n\tcollector  *metrics.Collector\n\tclient     *apiclient.APIClient\n\tdomain     string\n\tapiPort    int\n\tproxyPort  int\n\ttlsEnabled bool\n\tdocker     *docker.DockerClient\n}\n\n// NewService creates a new healthcheck service\nfunc NewService(cfg *HealthcheckServiceConfig) (*Service, error) {\n\tapiClient, err := runnerapiclient.GetApiClient()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create API client: %w\", err)\n\t}\n\n\tif cfg.Docker == nil {\n\t\treturn nil, fmt.Errorf(\"docker client is required for healthcheck service\")\n\t}\n\n\tlogger := slog.Default()\n\tif cfg.Logger != nil {\n\t\tlogger = cfg.Logger\n\t}\n\n\treturn &Service{\n\t\tlog:        logger.With(slog.String(\"component\", \"healthcheck\")),\n\t\tclient:     apiClient,\n\t\tinterval:   cfg.Interval,\n\t\ttimeout:    cfg.Timeout,\n\t\tcollector:  cfg.Collector,\n\t\tdomain:     cfg.Domain,\n\t\tapiPort:    cfg.ApiPort,\n\t\tproxyPort:  cfg.ProxyPort,\n\t\ttlsEnabled: cfg.TlsEnabled,\n\t\tdocker:     cfg.Docker,\n\t}, nil\n}\n\n// Start begins the healthcheck loop\nfunc (s *Service) Start(ctx context.Context) {\n\tticker := time.NewTicker(s.interval)\n\tdefer ticker.Stop()\n\n\t// Send initial healthcheck immediately\n\tif err := s.sendHealthcheck(ctx); err != nil {\n\t\ts.log.WarnContext(ctx, \"Failed to send initial healthcheck\", \"error\", err)\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\ts.log.InfoContext(ctx, \"Healthcheck loop stopped\")\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\tif err := s.sendHealthcheck(ctx); err != nil {\n\t\t\t\ts.log.WarnContext(ctx, \"Failed to send healthcheck\", \"error\", err)\n\t\t\t\t// Continue trying - don't crash\n\t\t\t}\n\t\t}\n\t}\n}\n\n// sendHealthcheck sends a healthcheck to the API\nfunc (s *Service) sendHealthcheck(ctx context.Context) error {\n\t// Create context with timeout\n\treqCtx, cancel := context.WithTimeout(ctx, s.timeout)\n\tdefer cancel()\n\n\t// Build healthcheck request\n\thealthcheck := apiclient.NewRunnerHealthcheck(internal.Version)\n\thealthcheck.SetDomain(s.domain)\n\n\tproxyUrl := fmt.Sprintf(\"http://%s:%d\", s.domain, s.proxyPort)\n\tapiUrl := fmt.Sprintf(\"http://%s:%d\", s.domain, s.apiPort)\n\n\tif s.tlsEnabled {\n\t\tapiUrl = fmt.Sprintf(\"https://%s:%d\", s.domain, s.apiPort)\n\t\tproxyUrl = fmt.Sprintf(\"https://%s:%d\", s.domain, s.proxyPort)\n\t}\n\n\thealthcheck.SetProxyUrl(proxyUrl)\n\thealthcheck.SetApiUrl(apiUrl)\n\n\tdockerHealth := apiclient.RunnerServiceHealth{\n\t\tServiceName: \"docker\",\n\t\tHealthy:     true,\n\t}\n\n\terr := s.docker.Ping(reqCtx)\n\tif err != nil {\n\t\ts.log.WarnContext(reqCtx, \"Failed to ping Docker daemon\", \"error\", err)\n\n\t\terrStr := err.Error()\n\t\tdockerHealth.Healthy = false\n\t\tdockerHealth.ErrorReason = &errStr\n\t}\n\n\thealthcheck.SetServiceHealth([]apiclient.RunnerServiceHealth{dockerHealth})\n\n\t// Collect metrics\n\tm, err := s.collector.Collect(reqCtx)\n\tif err != nil {\n\t\ts.log.WarnContext(reqCtx, \"Failed to collect metrics for healthcheck\", \"error\", err)\n\t} else {\n\t\thealthcheck.SetMetrics(apiclient.RunnerHealthMetrics{\n\t\t\tCurrentCpuLoadAverage:        m.CPULoadAverage,\n\t\t\tCurrentCpuUsagePercentage:    m.CPUUsagePercentage,\n\t\t\tCurrentMemoryUsagePercentage: m.MemoryUsagePercentage,\n\t\t\tCurrentDiskUsagePercentage:   m.DiskUsagePercentage,\n\t\t\tCurrentAllocatedCpu:          m.AllocatedCPU,\n\t\t\tCurrentAllocatedMemoryGiB:    m.AllocatedMemoryGiB,\n\t\t\tCurrentAllocatedDiskGiB:      m.AllocatedDiskGiB,\n\t\t\tCurrentSnapshotCount:         m.SnapshotCount,\n\t\t\tCurrentStartedSandboxes:      m.StartedSandboxCount,\n\t\t\tCpu:                          m.TotalCPU,\n\t\t\tMemoryGiB:                    m.TotalRAMGiB,\n\t\t\tDiskGiB:                      m.TotalDiskGiB,\n\t\t})\n\t}\n\n\treq := s.client.RunnersAPI.RunnerHealthcheck(reqCtx).RunnerHealthcheck(*healthcheck)\n\t_, err = req.Execute()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ts.log.DebugContext(reqCtx, \"Healthcheck sent successfully\")\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/runner/v2/poller/poller.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage poller\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"time\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\trunnerapiclient \"github.com/daytonaio/runner/pkg/apiclient\"\n\t\"github.com/daytonaio/runner/pkg/runner/v2/executor\"\n)\n\ntype PollerServiceConfig struct {\n\tPollTimeout time.Duration\n\tPollLimit   int\n\tLogger      *slog.Logger\n\tExecutor    *executor.Executor\n}\n\n// Service handles job polling from the API\ntype Service struct {\n\tlog         *slog.Logger\n\tpollTimeout time.Duration\n\tpollLimit   int\n\texecutor    *executor.Executor\n\tclient      *apiclient.APIClient\n}\n\n// NewService creates a new poller service\nfunc NewService(cfg *PollerServiceConfig) (*Service, error) {\n\tapiClient, err := runnerapiclient.GetApiClient()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create API client: %w\", err)\n\t}\n\n\treturn &Service{\n\t\tlog:         cfg.Logger.With(slog.String(\"component\", \"poller\")),\n\t\tpollTimeout: cfg.PollTimeout,\n\t\tpollLimit:   cfg.PollLimit,\n\t\texecutor:    cfg.Executor,\n\t\tclient:      apiClient,\n\t}, nil\n}\n\n// Start begins the job polling loop\nfunc (s *Service) Start(ctx context.Context) {\n\tinProgressJobs, _, err := s.client.JobsAPI.ListJobs(ctx).Status(apiclient.JOBSTATUS_IN_PROGRESS).Execute()\n\tif err != nil {\n\t\t// Only log error\n\t\ts.log.WarnContext(ctx, \"Failed to fetch IN_PROGRESS jobs\", \"error\", err)\n\t} else {\n\t\tif inProgressJobs != nil && len(inProgressJobs.Items) > 0 {\n\t\t\ts.log.InfoContext(ctx, \"Found IN_PROGRESS jobs\", \"count\", len(inProgressJobs.Items))\n\t\t\tfor _, job := range inProgressJobs.Items {\n\t\t\t\tgo s.executor.Execute(ctx, &job)\n\t\t\t}\n\t\t} else {\n\t\t\ts.log.InfoContext(ctx, \"No IN_PROGRESS jobs found\")\n\t\t}\n\t}\n\n\ts.log.InfoContext(ctx, \"Starting job poller\")\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\ts.log.InfoContext(ctx, \"Job poller stopped\")\n\t\t\treturn\n\t\tdefault:\n\t\t\t// Poll for jobs\n\t\t\tjobs, err := s.pollJobs(ctx)\n\t\t\tif err != nil {\n\t\t\t\ts.log.ErrorContext(ctx, \"Failed to poll jobs\", \"error\", err)\n\t\t\t\t// Wait a bit before retrying on error\n\t\t\t\ttime.Sleep(5 * time.Second)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Process jobs\n\t\t\tif len(jobs) > 0 {\n\t\t\t\ts.log.DebugContext(ctx, \"Received jobs\", \"count\", len(jobs))\n\t\t\t\tfor _, job := range jobs {\n\t\t\t\t\t// Execute job in goroutine for parallel processing\n\t\t\t\t\tgo s.executor.Execute(ctx, &job)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// pollJobs polls the API for pending jobs\nfunc (s *Service) pollJobs(ctx context.Context) ([]apiclient.Job, error) {\n\t// Build poll request\n\ttimeout := float32(s.pollTimeout.Seconds())\n\tlimit := float32(s.pollLimit)\n\n\treq := s.client.JobsAPI.PollJobs(ctx).\n\t\tTimeout(timeout).\n\t\tLimit(limit)\n\n\t// Execute poll request\n\tresp, httpResp, err := req.Execute()\n\tif err != nil {\n\t\t// Check if it's a timeout (expected for long polling)\n\t\tif httpResp != nil && httpResp.StatusCode == 408 {\n\t\t\t// Timeout is normal for long polling, just return empty\n\t\t\treturn []apiclient.Job{}, nil\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tif resp == nil {\n\t\treturn []apiclient.Job{}, nil\n\t}\n\n\treturn resp.GetJobs(), nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/services/sandbox.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage services\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\n\t\"github.com/daytonaio/runner/pkg/cache\"\n\t\"github.com/daytonaio/runner/pkg/docker\"\n\t\"github.com/daytonaio/runner/pkg/models\"\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n)\n\ntype SandboxService struct {\n\tbackupInfoCache *cache.BackupInfoCache\n\tdocker          *docker.DockerClient\n\tlog             *slog.Logger\n}\n\nfunc NewSandboxService(logger *slog.Logger, backupInfoCache *cache.BackupInfoCache, docker *docker.DockerClient) *SandboxService {\n\treturn &SandboxService{\n\t\tlog:             logger.With(slog.String(\"component\", \"sandbox_service\")),\n\t\tbackupInfoCache: backupInfoCache,\n\t\tdocker:          docker,\n\t}\n}\n\nfunc (s *SandboxService) GetSandboxInfo(ctx context.Context, sandboxId string) (*models.SandboxInfo, error) {\n\tsandboxState, err := s.docker.GetSandboxState(ctx, sandboxId)\n\tif err != nil {\n\t\ts.log.Warn(\"Failed to get sandbox state\", \"sandboxId\", sandboxId, \"error\", err)\n\t\treturn nil, err\n\t}\n\n\tbackupInfo, err := s.backupInfoCache.Get(ctx, sandboxId)\n\tif err != nil {\n\t\treturn &models.SandboxInfo{\n\t\t\tSandboxState: sandboxState,\n\t\t\tBackupState:  enums.BackupStateNone,\n\t\t}, nil\n\t}\n\n\tsandboxInfo := &models.SandboxInfo{\n\t\tSandboxState: sandboxState,\n\t\tBackupState:  backupInfo.State,\n\t}\n\n\tvar backupErrReason string\n\tif backupInfo.Error != nil {\n\t\tbackupErrReason = backupInfo.Error.Error()\n\t\tsandboxInfo.BackupErrorReason = &backupErrReason\n\t}\n\n\treturn sandboxInfo, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/services/sandbox_sync.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage services\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"time\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\trunnerapiclient \"github.com/daytonaio/runner/pkg/apiclient\"\n\t\"github.com/daytonaio/runner/pkg/docker\"\n\t\"github.com/daytonaio/runner/pkg/models/enums\"\n\t\"github.com/docker/docker/api/types/container\"\n)\n\ntype SandboxSyncServiceConfig struct {\n\tLogger   *slog.Logger\n\tDocker   *docker.DockerClient\n\tInterval time.Duration\n}\n\ntype SandboxSyncService struct {\n\tlog      *slog.Logger\n\tdocker   *docker.DockerClient\n\tinterval time.Duration\n\tclient   *apiclient.APIClient\n}\n\nfunc NewSandboxSyncService(config SandboxSyncServiceConfig) *SandboxSyncService {\n\treturn &SandboxSyncService{\n\t\tlog:      config.Logger.With(slog.String(\"component\", \"sandbox_sync_service\")),\n\t\tdocker:   config.Docker,\n\t\tinterval: config.Interval,\n\t}\n}\n\nfunc (s *SandboxSyncService) GetLocalContainerStates(ctx context.Context) (map[string]enums.SandboxState, error) {\n\tcontainers, err := s.docker.ApiClient().ContainerList(ctx, container.ListOptions{\n\t\tAll: true, // Include stopped containers\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list containers: %w\", err)\n\t}\n\n\tcontainerStates := make(map[string]enums.SandboxState)\n\n\tfor _, container := range containers {\n\t\t// Extract sandbox ID from container name or labels\n\t\tsandboxId := s.extractSandboxId(container)\n\t\tif sandboxId == \"\" {\n\t\t\tcontinue // Skip non-sandbox containers\n\t\t}\n\n\t\t// Get the current state of this container\n\t\tstate, err := s.docker.GetSandboxState(ctx, sandboxId)\n\t\tif err != nil {\n\t\t\ts.log.DebugContext(ctx, \"Failed to get state for sandbox\", \"sandboxId\", sandboxId, \"error\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\tcontainerStates[sandboxId] = state\n\t}\n\n\treturn containerStates, nil\n}\n\nfunc (s *SandboxSyncService) GetRemoteSandboxStates(ctx context.Context) (map[string]apiclient.SandboxState, error) {\n\tif s.client == nil {\n\t\tclient, err := runnerapiclient.GetApiClient()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get API client: %w\", err)\n\t\t}\n\t\ts.client = client\n\t}\n\tsandboxes, _, err := s.client.SandboxAPI.GetSandboxesForRunner(ctx).\n\t\tStates(string(apiclient.SANDBOXSTATE_STARTED)).SkipReconcilingSandboxes(true).\n\t\tExecute()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get sandboxes from API: %w\", err)\n\t}\n\n\tremoteSandboxes := make(map[string]apiclient.SandboxState)\n\tfor _, sandbox := range sandboxes {\n\t\tif sandbox.Id != \"\" {\n\t\t\tremoteSandboxes[sandbox.Id] = *sandbox.State\n\t\t}\n\t}\n\n\treturn remoteSandboxes, nil\n}\n\nfunc (s *SandboxSyncService) SyncSandboxState(ctx context.Context, sandboxId string, localState enums.SandboxState) error {\n\t_, err := s.client.SandboxAPI.UpdateSandboxState(ctx, sandboxId).UpdateSandboxStateDto(*apiclient.NewUpdateSandboxStateDto(\n\t\tstring(s.convertToApiState(localState)),\n\t)).Execute()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get sandbox %s: %w\", sandboxId, err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *SandboxSyncService) PerformSync(ctx context.Context) error {\n\tlocalStates, err := s.GetLocalContainerStates(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get local container states: %w\", err)\n\t}\n\n\tremoteStates, err := s.GetRemoteSandboxStates(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get remote sandbox states: %w\", err)\n\t}\n\n\t// Compare states and sync differences\n\tsyncCount := 0\n\tfor sandboxId, localState := range localStates {\n\t\tremoteState, exists := remoteStates[sandboxId]\n\t\tif !exists {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Convert remote state to local state format for comparison\n\t\tconvertedRemoteState := s.convertFromApiState(remoteState)\n\n\t\tif localState != convertedRemoteState {\n\t\t\ts.log.InfoContext(ctx, \"State mismatch for sandbox\", \"sandboxId\", sandboxId, \"localState\", localState, \"remoteState\", convertedRemoteState)\n\n\t\t\terr := s.SyncSandboxState(ctx, sandboxId, localState)\n\t\t\tif err != nil {\n\t\t\t\ts.log.ErrorContext(ctx, \"Failed to sync state for sandbox\", \"sandboxId\", sandboxId, \"error\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsyncCount++\n\t\t}\n\t}\n\n\tif syncCount > 0 {\n\t\ts.log.InfoContext(ctx, \"Synchronized sandbox states\", \"syncCount\", syncCount)\n\t}\n\n\treturn nil\n}\n\n// StartSyncProcess starts a background goroutine that synchronizes sandbox states\nfunc (s *SandboxSyncService) StartSyncProcess(ctx context.Context) {\n\ts.log.InfoContext(ctx, \"Starting sandbox sync process\")\n\tgo func() {\n\t\t// Perform initial sync\n\t\terr := s.PerformSync(ctx)\n\t\tif err != nil {\n\t\t\ts.log.ErrorContext(ctx, \"Failed to perform initial sync\", \"error\", err)\n\t\t}\n\n\t\t// Set up ticker for periodic sync\n\t\tticker := time.NewTicker(s.interval)\n\t\tdefer ticker.Stop()\n\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ticker.C:\n\t\t\t\terr := s.PerformSync(ctx)\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.log.ErrorContext(ctx, \"Failed to perform sync\", \"error\", err)\n\t\t\t\t}\n\t\t\tcase <-ctx.Done():\n\t\t\t\ts.log.InfoContext(ctx, \"Sandbox sync service stopped\")\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n}\n\nfunc (s *SandboxSyncService) extractSandboxId(container container.Summary) string {\n\tif len(container.Names) > 0 && len(container.Names[0]) > 1 {\n\t\tname := container.Names[0][1:] // Remove leading \"/\"\n\t\treturn name\n\t}\n\n\treturn \"\"\n}\n\nfunc (s *SandboxSyncService) convertToApiState(localState enums.SandboxState) apiclient.SandboxState {\n\tswitch localState {\n\tcase enums.SandboxStateCreating:\n\t\treturn apiclient.SANDBOXSTATE_CREATING\n\tcase enums.SandboxStateRestoring:\n\t\treturn apiclient.SANDBOXSTATE_RESTORING\n\tcase enums.SandboxStateDestroyed:\n\t\treturn apiclient.SANDBOXSTATE_DESTROYED\n\tcase enums.SandboxStateDestroying:\n\t\treturn apiclient.SANDBOXSTATE_DESTROYING\n\tcase enums.SandboxStateStarted:\n\t\treturn apiclient.SANDBOXSTATE_STARTED\n\tcase enums.SandboxStateStopped:\n\t\treturn apiclient.SANDBOXSTATE_STOPPED\n\tcase enums.SandboxStateStarting:\n\t\treturn apiclient.SANDBOXSTATE_STARTING\n\tcase enums.SandboxStateStopping:\n\t\treturn apiclient.SANDBOXSTATE_STOPPING\n\tcase enums.SandboxStateError:\n\t\treturn apiclient.SANDBOXSTATE_ERROR\n\tcase enums.SandboxStatePullingSnapshot:\n\t\treturn apiclient.SANDBOXSTATE_PULLING_SNAPSHOT\n\tdefault:\n\t\treturn apiclient.SANDBOXSTATE_UNKNOWN\n\t}\n}\n\nfunc (s *SandboxSyncService) convertFromApiState(apiState apiclient.SandboxState) enums.SandboxState {\n\tswitch apiState {\n\tcase apiclient.SANDBOXSTATE_CREATING:\n\t\treturn enums.SandboxStateCreating\n\tcase apiclient.SANDBOXSTATE_RESTORING:\n\t\treturn enums.SandboxStateRestoring\n\tcase apiclient.SANDBOXSTATE_DESTROYED:\n\t\treturn enums.SandboxStateDestroyed\n\tcase apiclient.SANDBOXSTATE_DESTROYING:\n\t\treturn enums.SandboxStateDestroying\n\tcase apiclient.SANDBOXSTATE_STARTED:\n\t\treturn enums.SandboxStateStarted\n\tcase apiclient.SANDBOXSTATE_STOPPED:\n\t\treturn enums.SandboxStateStopped\n\tcase apiclient.SANDBOXSTATE_STARTING:\n\t\treturn enums.SandboxStateStarting\n\tcase apiclient.SANDBOXSTATE_STOPPING:\n\t\treturn enums.SandboxStateStopping\n\tcase apiclient.SANDBOXSTATE_ERROR:\n\t\treturn enums.SandboxStateError\n\tcase apiclient.SANDBOXSTATE_PULLING_SNAPSHOT:\n\t\treturn enums.SandboxStatePullingSnapshot\n\tdefault:\n\t\treturn enums.SandboxStateUnknown\n\t}\n}\n"
  },
  {
    "path": "apps/runner/pkg/sshgateway/config.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sshgateway\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/x509\"\n\t\"encoding/base64\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\n\t\"golang.org/x/crypto/ssh\"\n)\n\nconst (\n\tSSH_GATEWAY_PORT = 2220\n)\n\n// IsSSHGatewayEnabled checks if the SSH gateway should be enabled\nfunc IsSSHGatewayEnabled() bool {\n\treturn os.Getenv(\"SSH_GATEWAY_ENABLE\") == \"true\"\n}\n\n// GetSSHGatewayPort returns the SSH gateway port\nfunc GetSSHGatewayPort() int {\n\tif port := os.Getenv(\"SSH_GATEWAY_PORT\"); port != \"\" {\n\t\tif parsedPort, err := strconv.Atoi(port); err == nil {\n\t\t\treturn parsedPort\n\t\t}\n\t}\n\treturn SSH_GATEWAY_PORT\n}\n\n// GetSSHPublicKey returns the SSH public key from configuration\n// Get ssh public key of ssh gateway - external ssh gateway, not runner ssh gateway\n// Should be base64 encoded\nfunc GetSSHPublicKey() (string, error) {\n\tpublicKey := os.Getenv(\"SSH_PUBLIC_KEY\")\n\tif publicKey == \"\" {\n\t\treturn \"\", fmt.Errorf(\"SSH_PUBLIC_KEY environment variable not set\")\n\t}\n\n\tdecodedKey, err := base64.StdEncoding.DecodeString(publicKey)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to base64 decode SSH_PUBLIC_KEY: %w\", err)\n\t}\n\n\treturn string(decodedKey), nil\n}\n\n// GetSSHHostKeyPath returns the SSH host key path from configuration\nfunc GetSSHHostKeyPath() string {\n\tif path := os.Getenv(\"SSH_HOST_KEY_PATH\"); path != \"\" {\n\t\treturn path\n\t}\n\treturn \"/root/.ssh/id_rsa\"\n}\n\n// GetSSHHostKey returns the SSH host key from configuration\nfunc GetSSHHostKey() (ssh.Signer, error) {\n\thostKeyPath := GetSSHHostKeyPath()\n\n\t// Check if host key file exists\n\tif _, err := os.Stat(hostKeyPath); os.IsNotExist(err) {\n\t\t// Generate new host key if file doesn't exist\n\t\tif err := generateAndSaveHostKey(hostKeyPath); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to generate host key: %w\", err)\n\t\t}\n\t}\n\n\t// Read the host key file\n\thostKeyBytes, err := os.ReadFile(hostKeyPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read host key file: %w\", err)\n\t}\n\n\t// Parse the private key to get the public key\n\tsigner, err := ssh.ParsePrivateKey(hostKeyBytes)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse host key: %w\", err)\n\t}\n\n\treturn signer, nil\n}\n\n// generateAndSaveHostKey generates a new RSA host key and saves it to the file\nfunc generateAndSaveHostKey(hostKeyPath string) error {\n\t// Create directory if it doesn't exist\n\tdir := filepath.Dir(hostKeyPath)\n\tif err := os.MkdirAll(dir, 0700); err != nil {\n\t\treturn fmt.Errorf(\"failed to create directory: %w\", err)\n\t}\n\n\t// Generate a new RSA key pair\n\tprivateKey, err := rsa.GenerateKey(rand.Reader, 2048)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to generate RSA key: %w\", err)\n\t}\n\n\t// Encode private key to PEM format\n\tprivateKeyPEM := &pem.Block{\n\t\tType:  \"RSA PRIVATE KEY\",\n\t\tBytes: x509.MarshalPKCS1PrivateKey(privateKey),\n\t}\n\n\t// Save private key to file\n\tprivateKeyFile, err := os.OpenFile(hostKeyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create host key file: %w\", err)\n\t}\n\tdefer privateKeyFile.Close()\n\n\tif err := pem.Encode(privateKeyFile, privateKeyPEM); err != nil {\n\t\treturn fmt.Errorf(\"failed to encode private key: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/sshgateway/service.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage sshgateway\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"log/slog\"\n\t\"net\"\n\t\"time\"\n\n\t\"github.com/daytonaio/runner/pkg/common\"\n\t\"github.com/daytonaio/runner/pkg/docker\"\n\t\"golang.org/x/crypto/ssh\"\n)\n\ntype Service struct {\n\tlog          *slog.Logger\n\tdockerClient *docker.DockerClient\n\tport         int\n}\n\nfunc NewService(logger *slog.Logger, dockerClient *docker.DockerClient) *Service {\n\tport := GetSSHGatewayPort()\n\n\tservice := &Service{\n\t\tlog:          logger.With(slog.String(\"component\", \"ssh_gateway_service\")),\n\t\tdockerClient: dockerClient,\n\t\tport:         port,\n\t}\n\n\treturn service\n}\n\n// GetPort returns the port the SSH gateway is configured to use\nfunc (s *Service) GetPort() int {\n\treturn s.port\n}\n\n// Start starts the SSH gateway server\nfunc (s *Service) Start(ctx context.Context) error {\n\t// Get the public key from configuration\n\tpublicKeyString, err := GetSSHPublicKey()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get SSH public key from config: %w\", err)\n\t}\n\n\t// Parse the public key from config\n\tconfigPublicKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(publicKeyString))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse SSH public key from config: %w\", err)\n\t}\n\n\t// Get the host key from configuration\n\thostKey, err := GetSSHHostKey()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get SSH host key from config: %w\", err)\n\t}\n\n\tserverConfig := &ssh.ServerConfig{\n\t\tPublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {\n\t\t\t// The username should be the sandbox ID\n\t\t\tsandboxId := conn.User()\n\n\t\t\t// Check if the provided key matches the configured public key\n\t\t\tif key.Type() == configPublicKey.Type() && bytes.Equal(key.Marshal(), configPublicKey.Marshal()) {\n\t\t\t\treturn &ssh.Permissions{\n\t\t\t\t\tExtensions: map[string]string{\n\t\t\t\t\t\t\"sandbox-id\": sandboxId,\n\t\t\t\t\t},\n\t\t\t\t}, nil\n\t\t\t}\n\n\t\t\ts.log.WarnContext(ctx, \"Public key authentication failed for sandbox\", \"sandboxID\", sandboxId)\n\t\t\treturn nil, fmt.Errorf(\"authentication failed\")\n\t\t},\n\t\tNoClientAuth: false,\n\t}\n\n\tserverConfig.AddHostKey(hostKey)\n\n\tlistener, err := net.Listen(\"tcp\", fmt.Sprintf(\":%d\", s.port))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to listen on port %d: %w\", s.port, err)\n\t}\n\tdefer listener.Close()\n\n\ts.log.InfoContext(ctx, \"SSH Gateway listening on port\", \"port\", s.port)\n\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn nil\n\t\tdefault:\n\t\t\tconn, err := listener.Accept()\n\t\t\tif err != nil {\n\t\t\t\ts.log.WarnContext(ctx, \"Failed to accept incoming connection\", \"error\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tgo s.handleConnection(conn, serverConfig)\n\t\t}\n\t}\n}\n\n// handleConnection handles an individual SSH connection\nfunc (s *Service) handleConnection(conn net.Conn, serverConfig *ssh.ServerConfig) {\n\tdefer conn.Close()\n\n\t// Perform SSH handshake\n\tserverConn, chans, reqs, err := ssh.NewServerConn(conn, serverConfig)\n\tif err != nil {\n\t\ts.log.Warn(\"Failed to handshake\", \"error\", err)\n\t\treturn\n\t}\n\tdefer serverConn.Close()\n\n\tsandboxId := serverConn.Permissions.Extensions[\"sandbox-id\"]\n\n\t// Handle global requests\n\tgo func() {\n\t\tfor req := range reqs {\n\t\t\tif req == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ts.log.Debug(\"Global request\", \"requestType\", req.Type)\n\t\t\t// For now, just discard requests, but in a full implementation\n\t\t\t// these would be forwarded to the sandbox\n\t\t\tif req.WantReply {\n\t\t\t\tif err := req.Reply(false, []byte(\"not implemented\")); err != nil {\n\t\t\t\t\ts.log.Warn(\"Failed to reply to global request\", \"error\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Handle channels\n\tfor newChannel := range chans {\n\t\tgo s.handleChannel(newChannel, sandboxId)\n\t}\n}\n\n// handleChannel handles an individual SSH channel\nfunc (s *Service) handleChannel(newChannel ssh.NewChannel, sandboxId string) {\n\ts.log.Debug(\"New channel\", \"channelType\", newChannel.ChannelType(), \"sandboxID\", sandboxId)\n\n\t// Accept the channel from the client\n\tclientChannel, clientRequests, err := newChannel.Accept()\n\tif err != nil {\n\t\ts.log.Warn(\"Could not accept client channel\", \"error\", err)\n\t\treturn\n\t}\n\tdefer clientChannel.Close()\n\n\t// Connect to the sandbox container via toolbox\n\tsandboxChannel, sandboxRequests, err := s.connectToSandbox(sandboxId, newChannel.ChannelType(), newChannel.ExtraData())\n\tif err != nil {\n\t\ts.log.Warn(\"Could not connect to sandbox\", \"sandboxID\", sandboxId, \"error\", err)\n\t\tclientChannel.Close()\n\t\treturn\n\t}\n\tdefer sandboxChannel.Close()\n\n\t// Forward requests from client to sandbox\n\tgo func() {\n\t\tfor req := range clientRequests {\n\t\t\tif req == nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ts.log.Debug(\"Client request\", \"requestType\", req.Type, \"sandboxID\", sandboxId)\n\n\t\t\tok, err := sandboxChannel.SendRequest(req.Type, req.WantReply, req.Payload)\n\t\t\tif req.WantReply {\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.log.Warn(\"Failed to send request to sandbox\", \"requestType\", req.Type, \"sandboxID\", sandboxId, \"error\", err)\n\t\t\t\t\tif replyErr := req.Reply(false, []byte(err.Error())); replyErr != nil {\n\t\t\t\t\t\ts.log.Warn(\"Failed to reply to client request\", \"error\", replyErr)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif replyErr := req.Reply(ok, nil); replyErr != nil {\n\t\t\t\t\t\ts.log.Warn(\"Failed to reply to client request\", \"error\", replyErr)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Forward requests from sandbox to client\n\tgo func() {\n\t\tfor req := range sandboxRequests {\n\t\t\tif req == nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ts.log.Debug(\"Sandbox request\", \"requestType\", req.Type, \"sandboxID\", sandboxId)\n\n\t\t\tok, err := clientChannel.SendRequest(req.Type, req.WantReply, req.Payload)\n\t\t\tif req.WantReply {\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.log.Warn(\"Failed to send request to client\", \"requestType\", req.Type, \"sandboxID\", sandboxId, \"error\", err)\n\t\t\t\t\tif replyErr := req.Reply(false, []byte(err.Error())); replyErr != nil {\n\t\t\t\t\t\ts.log.Warn(\"Failed to reply to sandbox request\", \"error\", replyErr)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif replyErr := req.Reply(ok, nil); replyErr != nil {\n\t\t\t\t\t\ts.log.Warn(\"Failed to reply to sandbox request\", \"error\", replyErr)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Bidirectional data forwarding\n\tgo func() {\n\t\t_, err := io.Copy(sandboxChannel, clientChannel)\n\t\tif err != nil {\n\t\t\ts.log.Debug(\"Client to sandbox copy error\", \"error\", err)\n\t\t}\n\t}()\n\n\t_, err = io.Copy(clientChannel, sandboxChannel)\n\tif err != nil {\n\t\ts.log.Debug(\"Sandbox to client copy error\", \"error\", err)\n\t}\n\n\ts.log.Debug(\"Channel closed for sandbox\", \"sandboxID\", sandboxId)\n}\n\n// connectToSandbox connects to the sandbox container via the toolbox\nfunc (s *Service) connectToSandbox(sandboxId, channelType string, extraData []byte) (ssh.Channel, <-chan *ssh.Request, error) {\n\t// Get sandbox details via toolbox API\n\tsandboxDetails, err := s.getSandboxDetails(sandboxId)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to get sandbox details: %w\", err)\n\t}\n\n\t// Create SSH client config to connect to the sandbox\n\tclientConfig := &ssh.ClientConfig{\n\t\tUser:            sandboxDetails.User,\n\t\tAuth:            []ssh.AuthMethod{ssh.Password(\"sandbox-ssh\")}, // Use hardcoded password for sandbox auth\n\t\tHostKeyCallback: ssh.InsecureIgnoreHostKey(),\n\t\tTimeout:         30 * time.Second,\n\t}\n\n\t// Connect to the sandbox container via toolbox\n\tsandboxClient, err := ssh.Dial(\"tcp\", fmt.Sprintf(\"%s:22220\", sandboxDetails.Hostname), clientConfig)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to connect to sandbox: %w\", err)\n\t}\n\n\t// Open channel to the sandbox\n\tsandboxChannel, sandboxRequests, err := sandboxClient.OpenChannel(channelType, extraData)\n\tif err != nil {\n\t\tsandboxClient.Close()\n\t\treturn nil, nil, fmt.Errorf(\"failed to open channel to sandbox: %w\", err)\n\t}\n\n\t// Return the real sandbox channel and requests\n\treturn sandboxChannel, sandboxRequests, nil\n}\n\n// getSandboxDetails gets sandbox information via docker client\nfunc (s *Service) getSandboxDetails(sandboxId string) (*SandboxDetails, error) {\n\t// Get container details via docker client\n\tcontainer, err := s.dockerClient.ContainerInspect(context.Background(), sandboxId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to inspect container %s: %w\", sandboxId, err)\n\t}\n\n\t// Get container IP address\n\tcontainerIP := common.GetContainerIpAddress(context.Background(), container)\n\tif containerIP == \"\" {\n\t\treturn nil, fmt.Errorf(\"sandbox IP not found for %s\", sandboxId)\n\t}\n\n\treturn &SandboxDetails{\n\t\tUser:     \"daytona\",\n\t\tHostname: containerIP,\n\t}, nil\n}\n\n// SandboxDetails contains information about a sandbox\ntype SandboxDetails struct {\n\tUser     string `json:\"user\"`\n\tHostname string `json:\"hostname\"`\n}\n"
  },
  {
    "path": "apps/runner/pkg/storage/client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage storage\n\nimport (\n\t\"context\"\n)\n\n// ObjectStorageClient defines the interface for object storage operations\ntype ObjectStorageClient interface {\n\tGetObject(ctx context.Context, organizationId, hash string) ([]byte, error)\n}\n"
  },
  {
    "path": "apps/runner/pkg/storage/minio_client.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage storage\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/runner/cmd/runner/config\"\n\t\"github.com/minio/minio-go/v7\"\n\t\"github.com/minio/minio-go/v7/pkg/credentials\"\n)\n\nconst CONTEXT_TAR_FILE_NAME = \"context.tar\"\n\ntype minioClient struct {\n\tclient     *minio.Client\n\tbucketName string\n}\n\nvar instance ObjectStorageClient\n\nfunc GetObjectStorageClient() (ObjectStorageClient, error) {\n\tif instance != nil {\n\t\treturn instance, nil\n\t}\n\n\trunnerConfig, err := config.GetConfig()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tendpoint := runnerConfig.AWSEndpointUrl\n\taccessKeyId := runnerConfig.AWSAccessKeyId\n\tsecretKey := runnerConfig.AWSSecretAccessKey\n\tbucketName := runnerConfig.AWSDefaultBucket\n\tregion := runnerConfig.AWSRegion\n\n\tendpoint = strings.TrimPrefix(endpoint, \"http://\")\n\tendpoint = strings.TrimPrefix(endpoint, \"https://\")\n\n\tuseSSL := strings.Contains(endpoint, \"https\")\n\n\tif endpoint == \"\" || accessKeyId == \"\" || secretKey == \"\" || bucketName == \"\" || region == \"\" {\n\t\treturn nil, fmt.Errorf(\"missing S3 configuration - endpoint, access key, secret key, region, or bucket name not provided\")\n\t}\n\n\tclient, err := minio.New(endpoint, &minio.Options{\n\t\tCreds:  credentials.NewStaticV4(accessKeyId, secretKey, \"\"),\n\t\tSecure: useSSL,\n\t\tRegion: region,\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create S3 client: %w\", err)\n\t}\n\n\tinstance = &minioClient{\n\t\tclient:     client,\n\t\tbucketName: bucketName,\n\t}\n\n\treturn instance, nil\n}\n\nfunc (m *minioClient) GetObject(ctx context.Context, organizationId, hash string) ([]byte, error) {\n\tobjectPath := fmt.Sprintf(\"%s/%s/%s\", organizationId, hash, CONTEXT_TAR_FILE_NAME)\n\tobj, err := m.client.GetObject(ctx, m.bucketName, objectPath, minio.GetObjectOptions{})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get object from storage: %w\", err)\n\t}\n\tdefer obj.Close()\n\n\tdata, err := io.ReadAll(obj)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read object data: %w\", err)\n\t}\n\n\treturn data, nil\n}\n"
  },
  {
    "path": "apps/runner/pkg/telemetry/filters/not_found.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage filters\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\tsdktrace \"go.opentelemetry.io/otel/sdk/trace\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.37.0\"\n)\n\ntype NotFoundExporterFilter struct{}\n\n// Apply wraps the given exporter so that HTTP 404 spans recorded as errors\n// have their status downgraded to Unset before export. The spans themselves\n// are still exported, preserving trace continuity.\nfunc (f *NotFoundExporterFilter) Apply(exporter sdktrace.SpanExporter) sdktrace.SpanExporter {\n\treturn &notFoundStatusExporter{next: exporter}\n}\n\n// notFoundStatusExporter adjusts HTTP 404 spans that were classified as errors\n// so they are exported with status Unset instead of Error. This handles optimistic\n// error handling patterns where 404 responses are expected (e.g., checking if a\n// resource exists before creating it).\ntype notFoundStatusExporter struct {\n\tnext sdktrace.SpanExporter\n}\n\nfunc (e *notFoundStatusExporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error {\n\tadjusted := make([]sdktrace.ReadOnlySpan, len(spans))\n\tfor i, span := range spans {\n\t\tif span.Status().Code == codes.Error && isHTTP404(span) {\n\t\t\tadjusted[i] = &statusOverrideSpan{\n\t\t\t\tReadOnlySpan: span,\n\t\t\t\tstatus:       sdktrace.Status{Code: codes.Unset},\n\t\t\t}\n\t\t} else {\n\t\t\tadjusted[i] = span\n\t\t}\n\t}\n\treturn e.next.ExportSpans(ctx, adjusted)\n}\n\nfunc (e *notFoundStatusExporter) Shutdown(ctx context.Context) error {\n\treturn e.next.Shutdown(ctx)\n}\n\n// statusOverrideSpan wraps a ReadOnlySpan and replaces its Status.\ntype statusOverrideSpan struct {\n\tsdktrace.ReadOnlySpan\n\tstatus sdktrace.Status\n}\n\nfunc (s *statusOverrideSpan) Status() sdktrace.Status {\n\treturn s.status\n}\n\n// isHTTP404 reports whether a span represents an HTTP 404 response.\n// It checks both the current semconv key (http.response.status_code, semconv v1.20+)\n// and the legacy key (http.status_code) for compatibility with older instrumentation.\nfunc isHTTP404(s sdktrace.ReadOnlySpan) bool {\n\tfor _, attr := range s.Attributes() {\n\t\tif attr.Key == semconv.HTTPResponseStatusCodeKey || attr.Key == attribute.Key(\"http.status_code\") {\n\t\t\treturn attr.Value.AsInt64() == 404\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "apps/runner/project.json",
    "content": "{\n  \"name\": \"runner\",\n  \"$schema\": \"../../runner_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"application\",\n  \"sourceRoot\": \"apps/runner\",\n  \"tags\": [],\n  \"targets\": {\n    \"copy-daemon-bin\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cp dist/apps/daemon-amd64 {projectRoot}/pkg/daemon/static/daemon-amd64\"\n      },\n      \"cache\": true,\n      \"inputs\": [{ \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }],\n      \"outputs\": [\"{projectRoot}/pkg/daemon/static/daemon-amd64\"],\n      \"dependsOn\": [\n        {\n          \"target\": \"build-amd64\",\n          \"projects\": \"daemon\"\n        }\n      ]\n    },\n    \"copy-computeruse-plugin\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"cwd\": \"{workspaceRoot}\",\n        \"command\": \"cp dist/libs/computer-use-amd64 {projectRoot}/pkg/daemon/static/daytona-computer-use\"\n      },\n      \"cache\": true,\n      \"inputs\": [\n        \"{workspaceRoot}/dist/libs/computer-use-amd64\",\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ],\n      \"outputs\": [\"{projectRoot}/pkg/daemon/static/daytona-computer-use\"],\n      \"dependsOn\": [\n        {\n          \"target\": \"build-amd64\",\n          \"projects\": \"computer-use\"\n        }\n      ]\n    },\n    \"build\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"options\": {\n        \"main\": \"{projectRoot}/cmd/runner/main.go\",\n        \"outputPath\": \"dist/apps/runner\",\n        \"flags\": [\"-ldflags \\\"-X 'github.com/daytonaio/runner/internal.Version=$VERSION'\\\"\"]\n      },\n      \"dependsOn\": [\"copy-daemon-bin\", \"copy-computeruse-plugin\", \"check-version-env\"],\n      \"inputs\": [\n        \"goProduction\",\n        \"^goProduction\",\n        { \"env\": \"VERSION\" },\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ]\n    },\n    \"build-amd64\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"options\": {\n        \"main\": \"{projectRoot}/cmd/runner/main.go\",\n        \"outputPath\": \"dist/apps/runner-amd64\",\n        \"env\": {\n          \"GOARCH\": \"amd64\",\n          \"GOOS\": \"linux\"\n        },\n        \"flags\": [\"-ldflags \\\"-X 'github.com/daytonaio/runner/internal.Version=$VERSION'\\\"\"]\n      },\n      \"dependsOn\": [\"copy-daemon-bin\", \"copy-computeruse-plugin\", \"check-version-env\"],\n      \"inputs\": [\n        \"goProduction\",\n        \"^goProduction\",\n        { \"env\": \"VERSION\" },\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ]\n    },\n    \"serve\": {\n      \"executor\": \"@nx-go/nx-go:serve\",\n      \"options\": {\n        \"cmd\": \"sudo -E PATH=/usr/local/go/bin:$PATH $(which gow)\",\n        \"cwd\": \".\",\n        \"main\": \"{projectRoot}/cmd/runner/main.go\"\n      },\n      \"configurations\": {\n        \"production\": {}\n      },\n      \"dependsOn\": [\n        {\n          \"target\": \"build\",\n          \"projects\": \"daemon\"\n        },\n        \"copy-daemon-bin\",\n        \"copy-computeruse-plugin\"\n      ]\n    },\n    \"format\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cd {projectRoot} && go fmt ./... && prettier --write \\\"**/*.{yaml,json}\\\"\"\n      }\n    },\n    \"test\": {\n      \"executor\": \"@nx-go/nx-go:test\"\n    },\n    \"lint\": {\n      \"executor\": \"@nx-go/nx-go:lint\"\n    },\n    \"openapi\": {\n      \"executor\": \"nx:run-commands\",\n      \"cache\": true,\n      \"inputs\": [\"{projectRoot}/pkg/api/**/*.go\", \"!{projectRoot}/pkg/api/**/*_test.go\"],\n      \"outputs\": [\n        \"{projectRoot}/pkg/api/docs/swagger.json\",\n        \"{projectRoot}/pkg/api/docs/swagger.yaml\",\n        \"{projectRoot}/pkg/api/docs/docs.go\"\n      ],\n      \"options\": {\n        \"cwd\": \"{projectRoot}/pkg/api\",\n        \"command\": \"swag fmt && swag init --parseDependency --parseInternal --parseDepth 1 -o docs -g server.go && prettier --write \\\"**/*.{yaml,html,json}\\\"\"\n      }\n    },\n    \"check-version-env\": {},\n    \"docker\": {\n      \"options\": {\n        \"target\": \"runner\"\n      },\n      \"dependsOn\": [\n        \"check-version-env\",\n        {\n          \"target\": \"build-amd64\",\n          \"projects\": \"computer-use\"\n        }\n      ]\n    },\n    \"package-deb\": {\n      \"executor\": \"nx:run-commands\",\n      \"cache\": true,\n      \"inputs\": [\n        \"{projectRoot}/packaging/**/*\",\n        { \"env\": \"VERSION\" },\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ],\n      \"outputs\": [\"{workspaceRoot}/dist/apps/runner-deb/**/*\"],\n      \"options\": {\n        \"commands\": [\n          \"mkdir -p dist/apps/runner-deb/deb/opt/daytona\",\n          \"mkdir -p dist/apps/runner-deb/deb/etc/systemd/system\",\n          \"mkdir -p dist/apps/runner-deb/deb/DEBIAN\",\n          \"cp dist/apps/runner-amd64 dist/apps/runner-deb/deb/opt/daytona/runner\",\n          \"cp {projectRoot}/packaging/systemd/daytona-runner.service dist/apps/runner-deb/deb/etc/systemd/system/\",\n          \"cp {projectRoot}/packaging/deb/DEBIAN/postinst {projectRoot}/packaging/deb/DEBIAN/prerm {projectRoot}/packaging/deb/DEBIAN/postrm dist/apps/runner-deb/deb/DEBIAN/\",\n          \"VERSION=${VERSION:-0.1.0} envsubst < {projectRoot}/packaging/deb/DEBIAN/control > dist/apps/runner-deb/deb/DEBIAN/control\",\n          \"dpkg-deb --build dist/apps/runner-deb/deb dist/apps/runner-deb/daytona-runner_${VERSION:-0.0.0-dev}_amd64.deb\"\n        ],\n        \"parallel\": false\n      },\n      \"dependsOn\": [\"build-amd64\", \"check-version-env\"]\n    },\n    \"push-manifest\": {}\n  },\n  \"implicitDependencies\": [\"computer-use\", \"daemon\"]\n}\n"
  },
  {
    "path": "apps/snapshot-manager/.gitignore",
    "content": "data\n"
  },
  {
    "path": "apps/snapshot-manager/Dockerfile",
    "content": "FROM node:22-alpine AS build\n\nENV CI=true\n\nRUN npm install -g corepack && corepack enable\n\nCOPY --from=golang:1.25.4-alpine /usr/local/go/ /usr/local/go/\n\nENV PATH=\"/usr/local/go/bin:${PATH}\"\n\nRUN apk add --no-cache git\n\nWORKDIR /daytona\n\n# Yarn caching layer\nCOPY package.json yarn.lock .yarnrc.yml ./\nRUN yarn install --immutable\n\n# Nx config\nCOPY nx.json ./\n\n# Go dependency layer (cached unless go.mod/go.sum change)\nCOPY go.work go.work.sum ./\nCOPY apps/snapshot-manager/go.mod apps/snapshot-manager/go.sum apps/snapshot-manager/\nRUN head -1 go.work > go.work.tmp && printf '\\nuse (\\n\\t./apps/snapshot-manager\\n)\\n' >> go.work.tmp && mv go.work.tmp go.work\n\nENV NX_DAEMON=false\nENV GONOSUMDB=github.com/daytonaio/daytona\n\nRUN cd apps/snapshot-manager && go mod download\n\n# Go source\nCOPY apps/snapshot-manager/ apps/snapshot-manager/\n\nARG VERSION=0.0.1\nRUN --mount=type=cache,target=/root/.cache/go-build \\\n  VERSION=$VERSION yarn nx build snapshot-manager --configuration=production --nxBail=true\n\nFROM alpine:3.18 AS snapshot-manager\n\nRUN apk add --no-cache curl\n\nWORKDIR /usr/local/bin\n\nCOPY --from=build /daytona/dist/apps/snapshot-manager daytona-snapshot-manager\n\nRUN chmod +x daytona-snapshot-manager\n\nENTRYPOINT [\"daytona-snapshot-manager\"]\n"
  },
  {
    "path": "apps/snapshot-manager/cmd/main.go",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log/slog\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\n\t\"github.com/daytonaio/snapshot-manager/internal/config\"\n\t\"github.com/daytonaio/snapshot-manager/internal/logger\"\n\t\"github.com/daytonaio/snapshot-manager/internal/server\"\n)\n\nfunc main() {\n\tlog := logger.NewLogger()\n\n\tcfg, err := config.Load()\n\tif err != nil {\n\t\tlog.Error(\"Failed to load configuration\", slog.String(\"error\", err.Error()))\n\t\tos.Exit(1)\n\t}\n\n\tserverCfg, err := server.BuildConfig(cfg)\n\tif err != nil {\n\t\tlog.Error(\"Failed to build server configuration\", slog.String(\"error\", err.Error()))\n\t\tos.Exit(1)\n\t}\n\n\tserverInstance, err := server.NewServer(serverCfg, log)\n\tif err != nil {\n\t\tlog.Error(\"Failed to create server instance\", slog.String(\"error\", err.Error()))\n\t\tos.Exit(1)\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\n\tsigChan := make(chan os.Signal, 1)\n\tsignal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)\n\n\tgo func() {\n\t\tsig := <-sigChan\n\t\tlog.Info(\"Received shutdown signal\", slog.String(\"signal\", sig.String()))\n\t\tcancel()\n\t}()\n\n\tif err := serverInstance.Start(ctx); err != nil {\n\t\tlog.Error(\"Registry error\", slog.String(\"error\", err.Error()))\n\t\tos.Exit(1)\n\t}\n\n\tlog.Info(\"Daytona Snapshot manager stopped\")\n}\n"
  },
  {
    "path": "apps/snapshot-manager/go.mod",
    "content": "module github.com/daytonaio/snapshot-manager\n\ngo 1.25\n\nrequire (\n\tgithub.com/distribution/distribution/v3 v3.0.0\n\tgithub.com/kelseyhightower/envconfig v1.4.0\n\tgithub.com/lmittmann/tint v1.1.2\n\tgithub.com/mattn/go-isatty v0.0.20\n\tgithub.com/sirupsen/logrus v1.9.3\n\tgolang.org/x/crypto v0.47.0\n)\n\nrequire (\n\tgithub.com/aws/aws-sdk-go v1.55.5 // indirect\n\tgithub.com/beorn7/perks v1.0.1 // indirect\n\tgithub.com/cenkalti/backoff/v4 v4.3.0 // indirect\n\tgithub.com/cenkalti/backoff/v5 v5.0.3 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.3.0 // indirect\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/docker/docker-credential-helpers v0.9.3 // indirect\n\tgithub.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect\n\tgithub.com/docker/go-metrics v0.0.1 // indirect\n\tgithub.com/felixge/httpsnoop v1.0.4 // indirect\n\tgithub.com/go-logr/logr v1.4.3 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/google/uuid v1.6.0 // indirect\n\tgithub.com/gorilla/handlers v1.5.2 // indirect\n\tgithub.com/gorilla/mux v1.8.1 // indirect\n\tgithub.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect\n\tgithub.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect\n\tgithub.com/hashicorp/golang-lru/v2 v2.0.5 // indirect\n\tgithub.com/jmespath/go-jmespath v0.4.0 // indirect\n\tgithub.com/klauspost/compress v1.18.1 // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/opencontainers/image-spec v1.1.1 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/prometheus/client_golang v1.23.2 // indirect\n\tgithub.com/prometheus/client_model v0.6.2 // indirect\n\tgithub.com/prometheus/common v0.67.1 // indirect\n\tgithub.com/prometheus/procfs v0.17.0 // indirect\n\tgithub.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 // indirect\n\tgithub.com/redis/go-redis/extra/redisotel/v9 v9.0.5 // indirect\n\tgithub.com/redis/go-redis/v9 v9.10.0 // indirect\n\tgo.opentelemetry.io/auto/sdk v1.2.1 // indirect\n\tgo.opentelemetry.io/contrib/bridges/prometheus v0.57.0 // indirect\n\tgo.opentelemetry.io/contrib/exporters/autoexport v0.57.0 // indirect\n\tgo.opentelemetry.io/otel v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/prometheus v0.54.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 // indirect\n\tgo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect\n\tgo.opentelemetry.io/otel/log v0.14.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/sdk/log v0.14.0 // indirect\n\tgo.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.40.0 // indirect\n\tgo.opentelemetry.io/proto/otlp v1.9.0 // indirect\n\tgo.yaml.in/yaml/v2 v2.4.3 // indirect\n\tgolang.org/x/net v0.49.0 // indirect\n\tgolang.org/x/sync v0.19.0 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n\tgolang.org/x/text v0.33.0 // indirect\n\tgoogle.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect\n\tgoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect\n\tgoogle.golang.org/grpc v1.79.3 // indirect\n\tgoogle.golang.org/protobuf v1.36.11 // indirect\n\tgopkg.in/yaml.v2 v2.4.0 // indirect\n)\n"
  },
  {
    "path": "apps/snapshot-manager/go.sum",
    "content": "github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=\ngithub.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=\ngithub.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=\ngithub.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=\ngithub.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=\ngithub.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=\ngithub.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=\ngithub.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=\ngithub.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=\ngithub.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=\ngithub.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=\ngithub.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=\ngithub.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=\ngithub.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM=\ngithub.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=\ngithub.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=\ngithub.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=\ngithub.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=\ngithub.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=\ngithub.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=\ngithub.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=\ngithub.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=\ngithub.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=\ngithub.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=\ngithub.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=\ngithub.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=\ngithub.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=\ngithub.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=\ngithub.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=\ngithub.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=\ngithub.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=\ngithub.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=\ngithub.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak=\ngithub.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw=\ngithub.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU=\ngithub.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=\ngithub.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=\ngithub.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=\ngithub.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=\ngithub.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co=\ngithub.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=\ngithub.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=\ngithub.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w=\ngithub.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=\ngithub.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=\ngithub.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=\ngithub.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=\ngithub.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=\ngithub.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=\ngithub.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=\ngithub.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=\ngithub.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI=\ngithub.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=\ngithub.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=\ngithub.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=\ngithub.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho=\ngithub.com/redis/go-redis/extra/rediscmd/v9 v9.0.5/go.mod h1:fyalQWdtzDBECAQFBJuQe5bzQ02jGd5Qcbgb97Flm7U=\ngithub.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb27yVE+gIAfeqp8LUCc=\ngithub.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ=\ngithub.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=\ngithub.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs=\ngithub.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=\ngithub.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=\ngithub.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngithub.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=\ngo.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=\ngo.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=\ngo.opentelemetry.io/contrib/bridges/prometheus v0.57.0 h1:UW0+QyeyBVhn+COBec3nGhfnFe5lwB0ic1JBVjzhk0w=\ngo.opentelemetry.io/contrib/bridges/prometheus v0.57.0/go.mod h1:ppciCHRLsyCio54qbzQv0E4Jyth/fLWDTJYfvWpcSVk=\ngo.opentelemetry.io/contrib/exporters/autoexport v0.57.0 h1:jmTVJ86dP60C01K3slFQa2NQ/Aoi7zA+wy7vMOKD9H4=\ngo.opentelemetry.io/contrib/exporters/autoexport v0.57.0/go.mod h1:EJBheUMttD/lABFyLXhce47Wr6DPWYReCzaZiXadH7g=\ngo.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=\ngo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls=\ngo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0/go.mod h1:hKvJwTzJdp90Vh7p6q/9PAOd55dI6WA6sWj62a/JvSs=\ngo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0 h1:QQqYw3lkrzwVsoEX0w//EhH/TCnpRdEenKBOOEIMjWc=\ngo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.14.0/go.mod h1:gSVQcr17jk2ig4jqJ2DX30IdWH251JcNAecvrqTxH1s=\ngo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0 h1:j7ZSD+5yn+lo3sGV69nW04rRR0jhYnBwjuX3r0HvnK0=\ngo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.32.0/go.mod h1:WXbYJTUaZXAbYd8lbgGuvih0yuCfOFC5RJoYnoLcGz8=\ngo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 h1:9y5sHvAxWzft1WQ4BwqcvA+IFVUJ1Ya75mSAUnFEVwE=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc=\ngo.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU=\ngo.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU=\ngo.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 h1:0BSddrtQqLEylcErkeFrJBmwFzcqfQq9+/uxfTZq+HE=\ngo.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0 h1:SZmDnHcgp3zwlPBS2JX2urGYe/jBKEIT6ZedHRUyCz8=\ngo.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.32.0/go.mod h1:fdWW0HtZJ7+jNpTKUR0GpMEDP69nR8YBJQxNiVCE3jk=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 h1:kJxSDN4SgWWTjG/hPp3O7LCGLcHXFlvS2/FFOrwL+SE=\ngo.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7iZeKJdeB8/NYHrJ48fdGc71Llo5bJ1J4DWUE=\ngo.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM=\ngo.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno=\ngo.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=\ngo.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=\ngo.opentelemetry.io/otel/sdk/log v0.14.0 h1:JU/U3O7N6fsAXj0+CXz21Czg532dW2V4gG1HE/e8Zrg=\ngo.opentelemetry.io/otel/sdk/log v0.14.0/go.mod h1:imQvII+0ZylXfKU7/wtOND8Hn4OpT3YUoIgqJVksUkM=\ngo.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM=\ngo.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA=\ngo.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=\ngo.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=\ngo.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=\ngo.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=\ngo.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=\ngo.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=\ngo.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=\ngonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ=\ngoogle.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=\ngoogle.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "apps/snapshot-manager/internal/buildinfo.go",
    "content": "// Copyright Daytona Platforms Inc.\n// SPDX-License-Identifier: AGPL-3.0\n\npackage internal\n\nvar (\n\tVersion = \"v0.0.0-dev\"\n)\n"
  },
  {
    "path": "apps/snapshot-manager/internal/config/config.go",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage config\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/kelseyhightower/envconfig\"\n)\n\n// AuthType represents the authentication method for the registry\ntype AuthType string\n\nconst (\n\tAuthTypeNone  AuthType = \"none\"\n\tAuthTypeBasic AuthType = \"basic\"\n)\n\ntype Config struct {\n\tAddr     string `envconfig:\"SNAPSHOT_MANAGER_ADDR\" default:\":5000\"`\n\tLogLevel string `envconfig:\"SNAPSHOT_MANAGER_LOG_LEVEL\" default:\"info\"`\n\n\t// Storage configuration\n\tStorageDriver       string `envconfig:\"SNAPSHOT_MANAGER_STORAGE_DRIVER\" default:\"filesystem\"`\n\tStorageDir          string `envconfig:\"SNAPSHOT_MANAGER_STORAGE_DIR\" default:\"./data\"`\n\tStorageDeleteEnable bool   `envconfig:\"SNAPSHOT_MANAGER_STORAGE_DELETE_ENABLED\" default:\"false\"`\n\n\t// Cache configuration\n\tCacheEnabled bool   `envconfig:\"SNAPSHOT_MANAGER_CACHE_ENABLED\" default:\"true\"`\n\tCacheDriver  string `envconfig:\"SNAPSHOT_MANAGER_CACHE_DRIVER\" default:\"inmemory\"`\n\n\t// S3 storage configuration\n\tS3Region         string `envconfig:\"SNAPSHOT_MANAGER_STORAGE_S3_REGION\"`\n\tS3Bucket         string `envconfig:\"SNAPSHOT_MANAGER_STORAGE_S3_BUCKET\"`\n\tS3AccessKey      string `envconfig:\"SNAPSHOT_MANAGER_STORAGE_S3_ACCESSKEY\"`\n\tS3SecretKey      string `envconfig:\"SNAPSHOT_MANAGER_STORAGE_S3_SECRETKEY\"`\n\tS3RegionEndpoint string `envconfig:\"SNAPSHOT_MANAGER_STORAGE_S3_REGIONENDPOINT\"`\n\tS3Encrypt        bool   `envconfig:\"SNAPSHOT_MANAGER_STORAGE_S3_ENCRYPT\" default:\"false\"`\n\tS3Secure         bool   `envconfig:\"SNAPSHOT_MANAGER_STORAGE_S3_SECURE\" default:\"true\"`\n\tS3RootDirectory  string `envconfig:\"SNAPSHOT_MANAGER_STORAGE_S3_ROOTDIRECTORY\"`\n\n\t// TLS configuration\n\tTLSCertificate string `envconfig:\"SNAPSHOT_MANAGER_HTTP_TLS_CERTIFICATE\"`\n\tTLSKey         string `envconfig:\"SNAPSHOT_MANAGER_HTTP_TLS_KEY\"`\n\n\t// Authentication\n\tAuthType         AuthType `envconfig:\"SNAPSHOT_MANAGER_AUTH_TYPE\" default:\"none\"`\n\tAuthUsername     string   `envconfig:\"SNAPSHOT_MANAGER_AUTH_USERNAME\"`\n\tAuthPassword     string   `envconfig:\"SNAPSHOT_MANAGER_AUTH_PASSWORD\"`\n\tAuthHtpasswdPath string   `envconfig:\"SNAPSHOT_MANAGER_AUTH_HTPASSWD_PATH\"`\n\n\t// HTTP secret for multi-instance deployments\n\tHTTPSecret string `envconfig:\"SNAPSHOT_MANAGER_HTTP_SECRET\"`\n}\n\nfunc Load() (*Config, error) {\n\tvar cfg Config\n\tif err := envconfig.Process(\"\", &cfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to process env config: %w\", err)\n\t}\n\n\tif err := cfg.Validate(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cfg, nil\n}\n\nfunc (c *Config) Validate() error {\n\tswitch c.StorageDriver {\n\tcase \"filesystem\":\n\t\t// filesystem is valid with defaults\n\tcase \"s3\":\n\t\tif c.S3Region == \"\" || c.S3Bucket == \"\" {\n\t\t\treturn fmt.Errorf(\"S3 storage requires SNAPSHOT_MANAGER_STORAGE_S3_REGION and SNAPSHOT_MANAGER_STORAGE_S3_BUCKET\")\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported storage driver: %s\", c.StorageDriver)\n\t}\n\n\tif c.TLSCertificate != \"\" && c.TLSKey == \"\" {\n\t\treturn fmt.Errorf(\"SNAPSHOT_MANAGER_HTTP_TLS_KEY is required when SNAPSHOT_MANAGER_HTTP_TLS_CERTIFICATE is set\")\n\t}\n\n\tif err := c.validateAuth(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (c *Config) validateAuth() error {\n\tswitch c.AuthType {\n\tcase AuthTypeNone:\n\t\t// No authentication required\n\tcase AuthTypeBasic:\n\t\tif c.AuthUsername == \"\" || c.AuthPassword == \"\" {\n\t\t\treturn fmt.Errorf(\"SNAPSHOT_MANAGER_AUTH_USERNAME and SNAPSHOT_MANAGER_AUTH_PASSWORD are required when SNAPSHOT_MANAGER_AUTH_TYPE is 'basic'\")\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported auth type: %s (supported: none, basic)\", c.AuthType)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "apps/snapshot-manager/internal/logger/logger.go",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage logger\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"log/slog\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/lmittmann/tint\"\n\t\"github.com/mattn/go-isatty\"\n\t\"github.com/sirupsen/logrus\"\n)\n\nfunc NewLogger() *slog.Logger {\n\tlog := slog.New(tint.NewHandler(os.Stdout, &tint.Options{\n\t\tNoColor:    !isatty.IsTerminal(os.Stdout.Fd()),\n\t\tTimeFormat: time.RFC3339,\n\t\tLevel:      parseLogLevel(os.Getenv(\"LOG_LEVEL\")),\n\t}))\n\tslog.SetDefault(log)\n\n\t// Redirect logrus (used by distribution registry) to slog\n\tlogrus.SetOutput(io.Discard)\n\tlogrus.AddHook(&slogHook{logger: log})\n\n\treturn log\n}\n\n// slogHook redirects logrus logs to slog\ntype slogHook struct {\n\tlogger *slog.Logger\n}\n\nfunc (h *slogHook) Levels() []logrus.Level {\n\treturn logrus.AllLevels\n}\n\nfunc (h *slogHook) Fire(entry *logrus.Entry) error {\n\tattrs := make([]slog.Attr, 0, len(entry.Data))\n\tfor k, v := range entry.Data {\n\t\tattrs = append(attrs, slog.Any(k, v))\n\t}\n\n\tlevel := slog.LevelInfo\n\tswitch entry.Level {\n\tcase logrus.TraceLevel, logrus.DebugLevel:\n\t\tlevel = slog.LevelDebug\n\tcase logrus.InfoLevel:\n\t\tlevel = slog.LevelInfo\n\tcase logrus.WarnLevel:\n\t\tlevel = slog.LevelWarn\n\tcase logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:\n\t\tlevel = slog.LevelError\n\t}\n\n\th.logger.LogAttrs(context.Background(), level, entry.Message, attrs...)\n\treturn nil\n}\n\n// parseLogLevel converts a string log level to slog.Level\nfunc parseLogLevel(level string) slog.Level {\n\tswitch strings.ToLower(level) {\n\tcase \"debug\":\n\t\treturn slog.LevelDebug\n\tcase \"info\":\n\t\treturn slog.LevelInfo\n\tcase \"warn\", \"warning\":\n\t\treturn slog.LevelWarn\n\tcase \"error\":\n\t\treturn slog.LevelError\n\tdefault:\n\t\treturn slog.LevelInfo\n\t}\n}\n"
  },
  {
    "path": "apps/snapshot-manager/internal/server/config.go",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage server\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/daytonaio/snapshot-manager/internal/config\"\n\t\"github.com/distribution/distribution/v3/configuration\"\n\t\"golang.org/x/crypto/bcrypt\"\n)\n\n// BuildConfig creates a distribution registry configuration from the app config\nfunc BuildConfig(cfg *config.Config) (*configuration.Configuration, error) {\n\tbuilder := NewConfigBuilder()\n\n\tbuilder.WithAddr(cfg.Addr)\n\tbuilder.WithLogLevel(cfg.LogLevel)\n\n\tswitch cfg.StorageDriver {\n\tcase \"filesystem\":\n\t\tbuilder.WithFilesystemStorage(cfg.StorageDir)\n\tcase \"s3\":\n\t\ts3Params := make(map[string]interface{})\n\t\tif cfg.S3AccessKey != \"\" {\n\t\t\ts3Params[\"accesskey\"] = cfg.S3AccessKey\n\t\t}\n\t\tif cfg.S3SecretKey != \"\" {\n\t\t\ts3Params[\"secretkey\"] = cfg.S3SecretKey\n\t\t}\n\t\tif cfg.S3RegionEndpoint != \"\" {\n\t\t\ts3Params[\"regionendpoint\"] = cfg.S3RegionEndpoint\n\t\t}\n\t\tif cfg.S3RootDirectory != \"\" {\n\t\t\ts3Params[\"rootdirectory\"] = cfg.S3RootDirectory\n\t\t}\n\t\ts3Params[\"encrypt\"] = cfg.S3Encrypt\n\t\ts3Params[\"secure\"] = cfg.S3Secure\n\t\tbuilder.WithS3Storage(cfg.S3Region, cfg.S3Bucket, s3Params)\n\t}\n\n\tif cfg.StorageDeleteEnable {\n\t\tbuilder.WithDelete(true)\n\t}\n\n\tif cfg.CacheEnabled {\n\t\tbuilder.WithCache(cfg.CacheDriver)\n\t}\n\n\tif cfg.TLSCertificate != \"\" {\n\t\tbuilder.WithTLS(cfg.TLSCertificate, cfg.TLSKey)\n\t}\n\n\t// Configure authentication based on AuthType\n\tswitch cfg.AuthType {\n\tcase config.AuthTypeBasic:\n\t\thtpasswdPath, err := generateHtpasswdFile(cfg.AuthUsername, cfg.AuthPassword)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to generate htpasswd file: %w\", err)\n\t\t}\n\t\tbuilder.WithAuth(htpasswdPath)\n\tcase config.AuthTypeNone:\n\t\t// Check for legacy htpasswd path configuration\n\t\tif cfg.AuthHtpasswdPath != \"\" {\n\t\t\tbuilder.WithAuth(cfg.AuthHtpasswdPath)\n\t\t}\n\t}\n\n\tif cfg.HTTPSecret != \"\" {\n\t\tbuilder.WithHTTPSecret(cfg.HTTPSecret)\n\t}\n\n\treturn builder.Build()\n}\n\n// generateHtpasswdFile creates a temporary htpasswd file with the given credentials\nfunc generateHtpasswdFile(username, password string) (string, error) {\n\thashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to hash password: %w\", err)\n\t}\n\n\thtpasswdContent := fmt.Sprintf(\"%s:%s\\n\", username, string(hashedPassword))\n\n\ttmpFile, err := os.CreateTemp(\"\", \"htpasswd-*\")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create htpasswd file: %w\", err)\n\t}\n\tdefer tmpFile.Close()\n\n\tif _, err := tmpFile.WriteString(htpasswdContent); err != nil {\n\t\tos.Remove(tmpFile.Name())\n\t\treturn \"\", fmt.Errorf(\"failed to write htpasswd file: %w\", err)\n\t}\n\n\treturn tmpFile.Name(), nil\n}\n\n// ConfigBuilder provides a fluent interface for building registry configurations\ntype ConfigBuilder struct {\n\tconfig *configuration.Configuration\n}\n\n// NewConfigBuilder creates a new configuration builder with sensible defaults\nfunc NewConfigBuilder() *ConfigBuilder {\n\treturn &ConfigBuilder{\n\t\tconfig: &configuration.Configuration{\n\t\t\tVersion: \"0.1\",\n\t\t\tLog: configuration.Log{\n\t\t\t\tLevel:     configuration.Loglevel(\"info\"),\n\t\t\t\tFormatter: \"text\",\n\t\t\t},\n\t\t\tHTTP: configuration.HTTP{\n\t\t\t\tAddr: \":5000\",\n\t\t\t\tHeaders: http.Header{\n\t\t\t\t\t\"X-Content-Type-Options\": []string{\"nosniff\"},\n\t\t\t\t},\n\t\t\t},\n\t\t\tStorage: make(configuration.Storage),\n\t\t\tCatalog: configuration.Catalog{\n\t\t\t\tMaxEntries: 1000, // Enable catalog with default max entries\n\t\t\t},\n\t\t},\n\t}\n}\n\n// WithFilesystemStorage configures filesystem storage\nfunc (cb *ConfigBuilder) WithFilesystemStorage(rootDir string) *ConfigBuilder {\n\tcb.config.Storage[\"filesystem\"] = configuration.Parameters{\n\t\t\"rootdirectory\": rootDir,\n\t}\n\treturn cb\n}\n\n// WithS3Storage configures S3 storage\nfunc (cb *ConfigBuilder) WithS3Storage(region, bucket string, params map[string]interface{}) *ConfigBuilder {\n\ts3Params := configuration.Parameters{\n\t\t\"region\": region,\n\t\t\"bucket\": bucket,\n\t}\n\t// Merge additional params\n\tfor k, v := range params {\n\t\ts3Params[k] = v\n\t}\n\tcb.config.Storage[\"s3\"] = s3Params\n\treturn cb\n}\n\n// WithAddr sets the HTTP address\nfunc (cb *ConfigBuilder) WithAddr(addr string) *ConfigBuilder {\n\tcb.config.HTTP.Addr = addr\n\treturn cb\n}\n\n// WithLogLevel sets the log level\nfunc (cb *ConfigBuilder) WithLogLevel(level string) *ConfigBuilder {\n\tcb.config.Log.Level = configuration.Loglevel(level)\n\treturn cb\n}\n\n// WithTLS enables TLS with the given certificate and key files\nfunc (cb *ConfigBuilder) WithTLS(certFile, keyFile string) *ConfigBuilder {\n\tcb.config.HTTP.TLS = configuration.TLS{\n\t\tCertificate: certFile,\n\t\tKey:         keyFile,\n\t}\n\treturn cb\n}\n\n// WithAuth enables htpasswd authentication\nfunc (cb *ConfigBuilder) WithAuth(htpasswdPath string) *ConfigBuilder {\n\tcb.config.Auth = configuration.Auth{\n\t\t\"htpasswd\": configuration.Parameters{\n\t\t\t\"realm\": \"Registry Realm\",\n\t\t\t\"path\":  htpasswdPath,\n\t\t},\n\t}\n\treturn cb\n}\n\n// WithDelete enables or disables blob deletion\nfunc (cb *ConfigBuilder) WithDelete(enabled bool) *ConfigBuilder {\n\tcb.config.Storage[\"delete\"] = configuration.Parameters{\n\t\t\"enabled\": enabled,\n\t}\n\treturn cb\n}\n\n// WithCache enables in-memory blob descriptor caching\nfunc (cb *ConfigBuilder) WithCache(driver string) *ConfigBuilder {\n\tcb.config.Storage[\"cache\"] = configuration.Parameters{\n\t\t\"blobdescriptor\": driver,\n\t}\n\treturn cb\n}\n\n// WithCatalog configures the catalog endpoint with a maximum number of entries\nfunc (cb *ConfigBuilder) WithCatalog(maxEntries int) *ConfigBuilder {\n\tcb.config.Catalog = configuration.Catalog{\n\t\tMaxEntries: maxEntries,\n\t}\n\treturn cb\n}\n\n// WithHTTPSecret sets a shared secret for multi-instance deployments\n// This is REQUIRED when running multiple registry instances behind a load balancer\nfunc (cb *ConfigBuilder) WithHTTPSecret(secret string) *ConfigBuilder {\n\tcb.config.HTTP.Secret = secret\n\treturn cb\n}\n\n// WithRawConfig allows direct access to the underlying configuration\n// This is useful for advanced configurations not covered by the builder\nfunc (cb *ConfigBuilder) WithRawConfig(fn func(*configuration.Configuration)) *ConfigBuilder {\n\tfn(cb.config)\n\treturn cb\n}\n\n// Build returns the built configuration\nfunc (cb *ConfigBuilder) Build() (*configuration.Configuration, error) {\n\t// Validate that at least one storage driver is configured\n\thasDriver := false\n\tfor key := range cb.config.Storage {\n\t\tif key != \"delete\" && key != \"maintenance\" && key != \"cache\" {\n\t\t\thasDriver = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !hasDriver {\n\t\treturn nil, fmt.Errorf(\"no storage driver configured\")\n\t}\n\treturn cb.config, nil\n}\n\n// Config returns the raw configuration (for advanced users who want to modify it directly)\nfunc (cb *ConfigBuilder) Config() *configuration.Configuration {\n\treturn cb.config\n}\n"
  },
  {
    "path": "apps/snapshot-manager/internal/server/server.go",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage server\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log/slog\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/daytonaio/snapshot-manager/internal\"\n\t\"github.com/distribution/distribution/v3/configuration\"\n\t_ \"github.com/distribution/distribution/v3/registry/auth/htpasswd\"\n\t\"github.com/distribution/distribution/v3/registry/handlers\"\n\t_ \"github.com/distribution/distribution/v3/registry/storage/driver/filesystem\"\n\t_ \"github.com/distribution/distribution/v3/registry/storage/driver/s3-aws\"\n)\n\ntype Server struct {\n\tapp    *handlers.App\n\tconfig *configuration.Configuration\n\tserver *http.Server\n\tlogger *slog.Logger\n}\n\n// NewServer creates a new registry server with the given configuration\nfunc NewServer(config *configuration.Configuration, logger *slog.Logger) (*Server, error) {\n\tif logger == nil {\n\t\tlogger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{\n\t\t\tLevel: slog.LevelInfo,\n\t\t}))\n\t}\n\n\t// Validate storage configuration\n\tif len(config.Storage) == 0 {\n\t\treturn nil, fmt.Errorf(\"storage configuration is required\")\n\t}\n\n\t// Create storage directory if using filesystem driver\n\tif fsParams, ok := config.Storage[\"filesystem\"]; ok {\n\t\tif rootDir, ok := fsParams[\"rootdirectory\"].(string); ok {\n\t\t\tif err := os.MkdirAll(rootDir, 0755); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to create storage directory: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &Server{\n\t\tconfig: config,\n\t\tlogger: logger,\n\t}, nil\n}\n\n// Start starts the registry server and blocks until context is cancelled\nfunc (s *Server) Start(ctx context.Context) error {\n\t// Create the registry app\n\tapp := handlers.NewApp(ctx, s.config)\n\ts.app = app\n\n\t// Create HTTP server with health check endpoint\n\tmux := http.NewServeMux()\n\tmux.HandleFunc(\"/healthz\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.WriteHeader(http.StatusOK)\n\t\tw.Write([]byte(\"ok\"))\n\t})\n\tmux.Handle(\"/\", app)\n\n\ts.server = &http.Server{\n\t\tAddr:    s.config.HTTP.Addr,\n\t\tHandler: mux,\n\t}\n\n\ts.logger.Info(\"Daytona snapshot-manager started\",\n\t\tslog.String(\"version\", internal.Version),\n\t\tslog.String(\"addr\", s.config.HTTP.Addr),\n\t\tslog.Any(\"storage\", s.getStorageInfo()),\n\t)\n\n\t// Start the server\n\terrChan := make(chan error, 1)\n\tgo func() {\n\t\tvar err error\n\t\tif s.config.HTTP.TLS.Certificate != \"\" {\n\t\t\ts.logger.Info(\"Starting with TLS\",\n\t\t\t\tslog.String(\"cert\", s.config.HTTP.TLS.Certificate),\n\t\t\t)\n\t\t\terr = s.server.ListenAndServeTLS(s.config.HTTP.TLS.Certificate, s.config.HTTP.TLS.Key)\n\t\t} else {\n\t\t\terr = s.server.ListenAndServe()\n\t\t}\n\t\tif err != nil && err != http.ErrServerClosed {\n\t\t\terrChan <- err\n\t\t}\n\t}()\n\n\t// Wait for context cancellation or error\n\tselect {\n\tcase err := <-errChan:\n\t\treturn fmt.Errorf(\"server error: %w\", err)\n\tcase <-ctx.Done():\n\t\treturn s.Shutdown(context.Background())\n\t}\n}\n\n// Shutdown gracefully shuts down the registry server\nfunc (s *Server) Shutdown(ctx context.Context) error {\n\ts.logger.Info(\"Shutting down Daytona snapshot-manager...\")\n\tif s.server != nil {\n\t\treturn s.server.Shutdown(ctx)\n\t}\n\treturn nil\n}\n\n// getStorageInfo returns a human-readable storage configuration info\nfunc (s *Server) getStorageInfo() map[string]interface{} {\n\tinfo := make(map[string]interface{})\n\tfor driver := range s.config.Storage {\n\t\tif driver == \"delete\" || driver == \"maintenance\" || driver == \"cache\" {\n\t\t\tcontinue\n\t\t}\n\t\tinfo[\"driver\"] = driver\n\t\tif params, ok := s.config.Storage[driver]; ok {\n\t\t\t// Add relevant params based on driver\n\t\t\tswitch driver {\n\t\t\tcase \"filesystem\":\n\t\t\t\tif rootDir, ok := params[\"rootdirectory\"].(string); ok {\n\t\t\t\t\tinfo[\"rootdirectory\"] = rootDir\n\t\t\t\t}\n\t\t\tcase \"s3\":\n\t\t\t\tif region, ok := params[\"region\"].(string); ok {\n\t\t\t\t\tinfo[\"region\"] = region\n\t\t\t\t}\n\t\t\t\tif bucket, ok := params[\"bucket\"].(string); ok {\n\t\t\t\t\tinfo[\"bucket\"] = bucket\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn info\n}\n"
  },
  {
    "path": "apps/snapshot-manager/project.json",
    "content": "{\n  \"name\": \"snapshot-manager\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"application\",\n  \"sourceRoot\": \"apps/snapshot-manager\",\n  \"tags\": [],\n  \"targets\": {\n    \"build\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"options\": {\n        \"main\": \"{projectRoot}/cmd/main.go\",\n        \"outputPath\": \"dist/apps/snapshot-manager\",\n        \"env\": {\n          \"CGO_ENABLED\": \"0\"\n        }\n      },\n      \"configurations\": {\n        \"production\": {\n          \"flags\": [\"-ldflags \\\"-X 'github.com/daytonaio/snapshot-manager/internal.Version=$VERSION'\\\"\"]\n        }\n      },\n      \"inputs\": [\"goProduction\", \"^goProduction\", { \"env\": \"VERSION\" }]\n    },\n    \"serve\": {\n      \"executor\": \"@nx-go/nx-go:serve\",\n      \"options\": {\n        \"cmd\": \"gow\",\n        \"main\": \"{projectRoot}/cmd/main.go\"\n      }\n    },\n    \"test\": {\n      \"executor\": \"@nx-go/nx-go:test\"\n    },\n    \"lint\": {\n      \"executor\": \"@nx-go/nx-go:lint\"\n    },\n    \"tidy\": {\n      \"executor\": \"@nx-go/nx-go:tidy\"\n    },\n    \"check-version-env\": {},\n    \"docker\": {\n      \"options\": {\n        \"target\": \"snapshot-manager\"\n      }\n    },\n    \"push-manifest\": {}\n  }\n}\n"
  },
  {
    "path": "apps/ssh-gateway/Dockerfile",
    "content": "FROM node:22-alpine AS build\n\nENV CI=true\n\nRUN npm install -g corepack && corepack enable\n\nCOPY --from=golang:1.25.4-alpine /usr/local/go/ /usr/local/go/\n\nENV PATH=\"/usr/local/go/bin:${PATH}\"\n\nRUN apk add --no-cache git\n\nWORKDIR /daytona\n\n# Yarn caching layer\nCOPY package.json yarn.lock .yarnrc.yml ./\nRUN yarn install --immutable\n\n# Nx config\nCOPY nx.json ./\n\n# Go dependency layer (cached unless go.mod/go.sum change)\nCOPY go.work go.work.sum ./\nCOPY apps/ssh-gateway/go.mod apps/ssh-gateway/go.sum apps/ssh-gateway/\nCOPY libs/api-client-go/go.mod libs/api-client-go/go.sum libs/api-client-go/\nRUN head -1 go.work > go.work.tmp && printf '\\nuse (\\n\\t./apps/ssh-gateway\\n\\t./libs/api-client-go\\n)\\n' >> go.work.tmp && mv go.work.tmp go.work\n\nENV NX_DAEMON=false\nENV GONOSUMDB=github.com/daytonaio/daytona\n\nRUN go -C apps/ssh-gateway mod download && go -C libs/api-client-go mod download\n\n# Go source\nCOPY apps/ssh-gateway/ apps/ssh-gateway/\nCOPY libs/api-client-go/ libs/api-client-go/\n\nRUN yarn nx build ssh-gateway --configuration=production --nxBail=true\n\nFROM alpine:3.18 AS ssh-gateway\n\nWORKDIR /usr/local/bin\n\nCOPY --from=build /daytona/dist/apps/ssh-gateway daytona-ssh-gateway\n\nRUN chmod +x daytona-ssh-gateway\n\nEXPOSE 2222\n\nENTRYPOINT [\"daytona-ssh-gateway\"]\n"
  },
  {
    "path": "apps/ssh-gateway/README.md",
    "content": "# SSH Gateway\n\nA standalone SSH gateway application that authenticates users using tokens and proxies connections to Daytona runners.\n\n## Features\n\n- **Token-based authentication**: Username is used as the authentication token\n- **Automatic runner discovery**: Validates tokens and finds the appropriate runner\n- **SSH keypair management**: Retrieves SSH credentials from runners automatically\n- **Connection proxying**: Seamlessly forwards SSH connections to runners\n\n## Usage\n\n### Connection Format\n\n```bash\nssh -p 2222 <TOKEN>@<GATEWAY_HOST>\n```\n\n**Example:**\n\n```bash\nssh -p 2222 Fg8Jx2nPtWAVY5pVN0TlUcbCDNPF-ePB@localhost\n```\n\nWhere:\n\n- `Fg8Jx2nPtWAVY5pVN0TlUcbCDNPF-ePB` is the SSH access token\n- `localhost` is the SSH gateway host\n- `2222` is the SSH gateway port\n\n### How It Works\n\n1. **Authentication**: The gateway extracts the token from the username\n2. **Token Validation**: Calls the Daytona API to validate the token and get runner information\n3. **Credential Retrieval**: Fetches the SSH keypair from the identified runner\n4. **Connection Proxying**: Establishes a connection to the runner's SSH gateway (port 2222)\n5. **Session Forwarding**: Proxies the SSH session between the client and the runner\n\n## Configuration\n\n### Environment Variables\n\n| Variable           | Description                           | Default                 | Required |\n| ------------------ | ------------------------------------- | ----------------------- | -------- |\n| `SSH_GATEWAY_PORT` | Port for the SSH gateway to listen on | `2222`                  | No       |\n| `API_URL`          | Daytona API base URL                  | `http://localhost:3000` | No       |\n| `API_KEY`          | Daytona API authentication key        | -                       | **Yes**  |\n\n### Example Environment\n\n```bash\nexport SSH_GATEWAY_PORT=2222\nexport API_URL=https://api.daytona.example.com\nexport API_KEY=your-api-key-here\n```\n\n## Building\n\n### Local Build\n\n```bash\ngo mod tidy\ngo build -o ssh-gateway .\n```\n\n### Docker Build\n\n```bash\ndocker build -t ssh-gateway .\n```\n\n## Running\n\n### Local Execution\n\n```bash\n./ssh-gateway\n```\n\n### Docker Execution\n\n```bash\ndocker run -p 2222:2222 \\\n  -e API_URL=https://api.daytona.example.com \\\n  -e API_KEY=your-api-key-here \\\n  ssh-gateway\n```\n\n## Security\n\n- **No password authentication**: Only token-based authentication is supported\n- **No public key authentication**: Public keys are not accepted\n- **Temporary host keys**: The gateway generates new host keys on each startup\n- **Secure token validation**: All tokens are validated against the Daytona API\n- **Runner isolation**: Each connection is isolated to its specific runner\n\n## Architecture\n\n```\nSSH Client → SSH Gateway → Daytona API → Runner SSH Gateway\n     ↓              ↓           ↓              ↓\n  Token Auth   Validate    Get Keypair    SSH Session\n```\n\n## API Endpoints Used\n\n- `GET /sandbox/ssh-access/validate?token={token}` - Validate SSH access token\n- `GET /runners/{id}/ssh-keypair` - Get runner SSH keypair\n\n## Error Handling\n\nThe gateway provides clear error messages for common failure scenarios:\n\n- Invalid or expired tokens\n- Runner unavailability\n- Network connectivity issues\n- Authentication failures\n\n## Logging\n\nThe application logs all connection attempts and errors for debugging and monitoring purposes.\n"
  },
  {
    "path": "apps/ssh-gateway/go.mod",
    "content": "module github.com/daytonaio/ssh-gateway\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/sirupsen/logrus v1.9.3\n\tgolang.org/x/crypto v0.47.0\n)\n\nrequire (\n\tgithub.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect\n\tgithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect\n\tgithub.com/stretchr/testify v1.11.1 // indirect\n\tgolang.org/x/sys v0.40.0 // indirect\n)\n"
  },
  {
    "path": "apps/ssh-gateway/go.sum",
    "content": "github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=\ngithub.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=\ngolang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=\ngolang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=\ngolang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\n"
  },
  {
    "path": "apps/ssh-gateway/main.go",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\npackage main\n\nimport (\n\t\"context\"\n\t\"crypto/x509\"\n\t\"encoding/base64\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tapiclient \"github.com/daytonaio/daytona/libs/api-client-go\"\n\t\"golang.org/x/crypto/ssh\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst (\n\tdefaultPort = 2222\n\trunnerPort  = 2220\n)\n\ntype SSHGateway struct {\n\tport       int\n\tapiClient  *apiclient.APIClient\n\thostKey    ssh.Signer\n\tprivateKey ssh.Signer\n\tpublicKey  ssh.PublicKey\n}\n\nfunc main() {\n\tport := getEnvInt(\"SSH_GATEWAY_PORT\", defaultPort)\n\tapiURL := getEnv(\"API_URL\", \"http://localhost:3000\")\n\tapiKey := getEnv(\"API_KEY\", \"\")\n\tsshPk := getEnv(\"SSH_PRIVATE_KEY\", \"\")\n\tsshHostKey := getEnv(\"SSH_HOST_KEY\", \"\")\n\n\tif apiKey == \"\" {\n\t\tlog.Fatal(\"API_KEY environment variable is required\")\n\t}\n\n\tif sshPk == \"\" {\n\t\tlog.Fatal(\"SSH_PRIVATE_KEY environment variable is required\")\n\t}\n\n\tif sshHostKey == \"\" {\n\t\tlog.Fatal(\"SSH_HOST_KEY environment variable is required\")\n\t}\n\n\t// Decode base64 encoded private key\n\tdecodedPk, err := base64.StdEncoding.DecodeString(sshPk)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to base64 decode SSH_PRIVATE_KEY: %v\", err)\n\t}\n\n\t// Decode base64 encoded host key\n\tdecodedHostKey, err := base64.StdEncoding.DecodeString(sshHostKey)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to base64 decode SSH_HOST_KEY: %v\", err)\n\t}\n\n\tclientConfig := apiclient.NewConfiguration()\n\tclientConfig.Servers = apiclient.ServerConfigurations{\n\t\t{\n\t\t\tURL: apiURL,\n\t\t},\n\t}\n\n\tclientConfig.AddDefaultHeader(\"Authorization\", \"Bearer \"+apiKey)\n\n\tapiClient := apiclient.NewAPIClient(clientConfig)\n\n\tapiClient.GetConfig().HTTPClient = &http.Client{\n\t\tTransport: http.DefaultTransport,\n\t}\n\n\t// Load the host key from environment variable\n\thostKey, err := parsePrivateKey(string(decodedHostKey))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to parse host key from SSH_HOST_KEY: %v\", err)\n\t}\n\n\t// Load the private key from environment variable\n\tprivateKey, err := parsePrivateKey(string(decodedPk))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to parse private key from SSH_PRIVATE_KEY: %v\", err)\n\t}\n\n\t// Generate public key from private key\n\tpublicKey := privateKey.PublicKey()\n\n\tgateway := &SSHGateway{\n\t\tport:       port,\n\t\tapiClient:  apiClient,\n\t\thostKey:    hostKey,\n\t\tprivateKey: privateKey,\n\t\tpublicKey:  publicKey,\n\t}\n\n\tlog.Printf(\"Host key loaded from SSH_HOST_KEY environment variable (base64 decoded)\")\n\tlog.Printf(\"Private key loaded from SSH_PRIVATE_KEY environment variable (base64 decoded)\")\n\tlog.Printf(\"Public key generated: %s\", string(ssh.MarshalAuthorizedKey(publicKey)))\n\n\tlog.Printf(\"Starting SSH Gateway on port %d\", port)\n\tif err := gateway.Start(); err != nil {\n\t\tlog.Fatalf(\"Failed to start SSH Gateway: %v\", err)\n\t}\n}\n\nfunc (g *SSHGateway) Start() error {\n\tserverConfig := &ssh.ServerConfig{\n\t\t// Allow no client auth initially, we'll handle it in the connection handler\n\t\tNoClientAuth: true,\n\t\t// Disable password authentication completely\n\t\tPasswordCallback: func(conn ssh.ConnMetadata, password []byte) (*ssh.Permissions, error) {\n\t\t\treturn nil, fmt.Errorf(\"password authentication not allowed\")\n\t\t},\n\t\t// Custom authentication handler\n\t\tAuthLogCallback: func(conn ssh.ConnMetadata, method string, err error) {\n\t\t\tif err != nil {\n\t\t\t\tlog.Printf(\"Authentication failed for user %s: %v\", conn.User(), err)\n\t\t\t}\n\t\t},\n\t}\n\n\t// Add host key\n\tserverConfig.AddHostKey(g.hostKey)\n\n\tlistener, err := net.Listen(\"tcp\", fmt.Sprintf(\":%d\", g.port))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to listen on port %d: %w\", g.port, err)\n\t}\n\tdefer listener.Close()\n\n\tlog.Printf(\"SSH Gateway listening on port %d\", g.port)\n\n\tfor {\n\t\tconn, err := listener.Accept()\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Failed to accept incoming connection: %v\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\tgo g.handleConnection(conn, serverConfig)\n\t}\n}\n\nfunc (g *SSHGateway) handleConnection(conn net.Conn, serverConfig *ssh.ServerConfig) {\n\tdefer conn.Close()\n\n\t// Perform SSH handshake\n\tserverConn, chans, reqs, err := ssh.NewServerConn(conn, serverConfig)\n\tif err != nil {\n\t\tlog.Printf(\"Failed to handshake: %v\", err)\n\t\treturn\n\t}\n\tdefer serverConn.Close()\n\n\t// Extract token from username and validate it\n\ttoken := serverConn.User()\n\tif token == \"\" {\n\t\tlog.Printf(\"No token provided in username\")\n\t\tconn.Close()\n\t\treturn\n\t}\n\n\tlog.Printf(\"Validating token: %s\", token)\n\n\t// Validate the token using the API\n\tvalidation, _, err := g.apiClient.SandboxAPI.ValidateSshAccess(context.Background()).Token(token).Execute()\n\tif err != nil {\n\t\tlog.Printf(\"Failed to validate SSH access: %v\", err)\n\t\tconn.Close()\n\t\treturn\n\t}\n\n\tif !validation.Valid {\n\t\tlog.Printf(\"Invalid token: %s\", token)\n\t\tconn.Close()\n\t\treturn\n\t}\n\n\trunner, _, err := g.apiClient.RunnersAPI.GetRunnerBySandboxId(context.Background(), validation.SandboxId).Execute()\n\tif err != nil {\n\t\tlog.Printf(\"Failed to get runner by sandbox ID: %v\", err)\n\t\tconn.Close()\n\t\treturn\n\t}\n\n\tif runner.Domain == nil {\n\t\tlog.Printf(\"Runner domain is nil for sandbox ID: %s\", validation.SandboxId)\n\t\tg.sendErrorAndClose(conn, \"Runner domain not found. Cannot establish SSH connection.\")\n\t\treturn\n\t}\n\n\trunnerID := runner.Id\n\trunnerDomain := *runner.Domain\n\tsandboxId := validation.SandboxId\n\n\tlog.Printf(\"Token validated, SSH connection established for runner: %s\", runnerID)\n\n\t// Check if the sandbox is started before proceeding\n\tif sandboxId != \"\" {\n\t\tlog.Printf(\"Checking sandbox state for sandbox: %s\", sandboxId)\n\t\tsandbox, _, err := g.apiClient.SandboxAPI.GetSandbox(context.Background(), sandboxId).Execute()\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Failed to get sandbox state for %s: %v\", sandboxId, err)\n\t\t\t// Send error message to client and close connection\n\t\t\tg.sendErrorAndClose(conn, fmt.Sprintf(\"Failed to verify sandbox state: %v\", err))\n\t\t\treturn\n\t\t}\n\n\t\tif sandbox.State == nil || *sandbox.State != apiclient.SANDBOXSTATE_STARTED {\n\t\t\tstate := \"unknown\"\n\t\t\tif sandbox.State != nil {\n\t\t\t\tstate = string(*sandbox.State)\n\t\t\t}\n\n\t\t\tlog.Printf(\"Sandbox %s is not started (state: %s), closing connection\", sandboxId, state)\n\t\t\tg.sendErrorAndClose(conn, fmt.Sprintf(\"Sandbox is not started (state: %s). Please start the sandbox before attempting to connect.\", state))\n\t\t\treturn\n\t\t}\n\n\t\tlog.Printf(\"Sandbox %s is started, allowing SSH connection\", sandboxId)\n\t} else {\n\t\tlog.Printf(\"No sandbox ID provided, proceeding with connection\")\n\t}\n\n\t// Handle global requests\n\tgo func() {\n\t\tfor req := range reqs {\n\t\t\tif req == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlog.Printf(\"Global request: %s\", req.Type)\n\t\t\t// For now, just discard requests\n\t\t\tif req.WantReply {\n\t\t\t\treq.Reply(false, []byte(\"not implemented\")) // nolint:errcheck\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Handle channels\n\tfor newChannel := range chans {\n\t\tgo g.handleChannel(newChannel, runnerID, runnerDomain, token, sandboxId)\n\t}\n}\n\nfunc (g *SSHGateway) handleChannel(newChannel ssh.NewChannel, runnerID string, runnerDomain string, token string, sandboxId string) {\n\tlog.Printf(\"New channel: %s for runner: %s\", newChannel.ChannelType(), runnerID)\n\n\t// Accept the channel from the client\n\tclientChannel, clientRequests, err := newChannel.Accept()\n\tif err != nil {\n\t\tlog.Printf(\"Could not accept client channel: %v\", err)\n\t\treturn\n\t}\n\tdefer clientChannel.Close()\n\n\t// Use the loaded private key instead of fetching from API\n\tsigner := g.privateKey\n\n\t// Connect to the runner's SSH gateway\n\trunnerConn, err := g.connectToRunner(sandboxId, runnerDomain, signer)\n\tif err != nil {\n\t\tlog.Printf(\"Failed to connect to runner: %v\", err)\n\t\tclientChannel.Close()\n\t\treturn\n\t}\n\tdefer runnerConn.Close()\n\n\t// Open channel to the runner\n\trunnerChannel, runnerRequests, err := runnerConn.OpenChannel(newChannel.ChannelType(), newChannel.ExtraData())\n\tif err != nil {\n\t\tlog.Printf(\"Failed to open channel to runner: %v\", err)\n\t\treturn\n\t}\n\tdefer runnerChannel.Close()\n\n\t// Forward requests from client to runner\n\tgo func() {\n\t\tfor req := range clientRequests {\n\t\t\tif req == nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlog.Printf(\"Client request: %s for runner %s\", req.Type, runnerID)\n\n\t\t\tok, err := runnerChannel.SendRequest(req.Type, req.WantReply, req.Payload)\n\t\t\tif req.WantReply {\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Printf(\"Failed to send request to runner: %v\", err)\n\t\t\t\t\treq.Reply(false, []byte(err.Error())) // nolint:errcheck\n\t\t\t\t} else {\n\t\t\t\t\treq.Reply(ok, nil) // nolint:errcheck\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Forward requests from runner to client\n\tgo func() {\n\t\tfor req := range runnerRequests {\n\t\t\tif req == nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlog.Printf(\"Runner request: %s for runner %s\", req.Type, runnerID)\n\n\t\t\tok, err := clientChannel.SendRequest(req.Type, req.WantReply, req.Payload)\n\t\t\tif req.WantReply {\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Printf(\"Failed to send request to client: %v\", err)\n\t\t\t\t\treq.Reply(false, []byte(err.Error())) // nolint:errcheck\n\t\t\t\t} else {\n\t\t\t\t\treq.Reply(ok, nil) // nolint:errcheck\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Bidirectional data forwarding\n\tgo func() {\n\t\t_, err := io.Copy(runnerChannel, clientChannel)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Client to runner copy error: %v\", err)\n\t\t}\n\t}()\n\n\tkeepAliveContext, cancel := context.WithCancel(context.Background())\n\tdefer cancel()\n\t// Keep sandbox alive while connection is open\n\tgo func() {\n\t\t// Update immediately upon starting\n\t\t_, err := g.apiClient.SandboxAPI.UpdateLastActivity(keepAliveContext, sandboxId).Execute()\n\t\tif err != nil {\n\t\t\tlog.Warnf(\"failed to update last activity for sandbox %s (will retry): %v\", sandboxId, err)\n\t\t}\n\n\t\t// Then every 45 seconds\n\t\tticker := time.NewTicker(45 * time.Second)\n\t\tdefer ticker.Stop()\n\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ticker.C:\n\t\t\t\t_, err := g.apiClient.SandboxAPI.UpdateLastActivity(keepAliveContext, sandboxId).Execute()\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Errorf(\"failed to update last activity for sandbox %s: %v\", sandboxId, err)\n\t\t\t\t}\n\t\t\tcase <-keepAliveContext.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\t_, err = io.Copy(clientChannel, runnerChannel)\n\tif err != nil {\n\t\tlog.Printf(\"Runner to client copy error: %v\", err)\n\t}\n\n\tlog.Printf(\"Channel closed for runner: %s\", runnerID)\n}\n\nfunc (g *SSHGateway) connectToRunner(sandboxId string, runnerDomain string, signer ssh.Signer) (*ssh.Client, error) {\n\t// Use runner domain if available, otherwise use localhost\n\thost := runnerDomain\n\tif host == \"\" {\n\t\thost = \"localhost\"\n\t}\n\n\t// Handle case with port: if runnerDomain contains a port, remove it\n\t// For example: \"localtest.me:3003\" -> \"localtest.me\"\n\tif strings.Contains(host, \":\") {\n\t\tif idx := strings.Index(host, \":\"); idx != -1 {\n\t\t\thost = host[:idx]\n\t\t}\n\t}\n\n\t// Ensure host is not empty after processing\n\tif host == \"\" {\n\t\treturn nil, fmt.Errorf(\"invalid host: empty host after processing runner domain\")\n\t}\n\n\tconfig := &ssh.ClientConfig{\n\t\tUser: sandboxId, // Default username for sandbox\n\t\tAuth: []ssh.AuthMethod{\n\t\t\tssh.PublicKeys(signer),\n\t\t},\n\t\tHostKeyCallback: ssh.InsecureIgnoreHostKey(),\n\t\tTimeout:         30 * time.Second,\n\t}\n\n\tclient, err := ssh.Dial(\"tcp\", fmt.Sprintf(\"%s:%d\", host, runnerPort), config)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to dial runner: %w\", err)\n\t}\n\n\treturn client, nil\n}\n\n// sendErrorAndClose sends an error message to the client and closes the connection\nfunc (g *SSHGateway) sendErrorAndClose(conn net.Conn, errorMessage string) {\n\tlog.Printf(\"Sending error to client: %s\", errorMessage)\n\n\t// For now, just close the connection\n\t// The client will see \"Connection closed by remote host\"\n\t// In a more sophisticated implementation, we could send a proper SSH disconnect message\n\t// but this requires restructuring the connection handling\n\tconn.Close()\n}\n\nfunc parsePrivateKey(privateKeyPEM string) (ssh.Signer, error) {\n\t// First try to parse as OpenSSH format (newer format)\n\tsigner, err := ssh.ParsePrivateKey([]byte(privateKeyPEM))\n\tif err == nil {\n\t\treturn signer, nil\n\t}\n\n\t// If OpenSSH parsing fails, try PKCS1 format (older format)\n\tblock, _ := pem.Decode([]byte(privateKeyPEM))\n\tif block == nil {\n\t\treturn nil, fmt.Errorf(\"failed to decode PEM block\")\n\t}\n\n\tprivateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse private key (tried OpenSSH and PKCS1 formats): %w\", err)\n\t}\n\n\tsigner, err = ssh.NewSignerFromKey(privateKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create SSH signer: %w\", err)\n\t}\n\n\treturn signer, nil\n}\n\n// GetPublicKeyString returns the public key in authorized_keys format\nfunc (g *SSHGateway) GetPublicKeyString() string {\n\treturn string(ssh.MarshalAuthorizedKey(g.publicKey))\n}\n\n// GetPublicKey returns the SSH public key\nfunc (g *SSHGateway) GetPublicKey() ssh.PublicKey {\n\treturn g.publicKey\n}\n\nfunc getEnv(key, defaultValue string) string {\n\tif value := os.Getenv(key); value != \"\" {\n\t\treturn value\n\t}\n\treturn defaultValue\n}\n\nfunc getEnvInt(key string, defaultValue int) int {\n\tif value := os.Getenv(key); value != \"\" {\n\t\tif intValue, err := strconv.Atoi(value); err == nil {\n\t\t\treturn intValue\n\t\t}\n\t}\n\treturn defaultValue\n}\n"
  },
  {
    "path": "apps/ssh-gateway/project.json",
    "content": "{\n  \"name\": \"ssh-gateway\",\n  \"$schema\": \"../../runner_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"application\",\n  \"sourceRoot\": \"apps/ssh-gateway\",\n  \"tags\": [],\n  \"targets\": {\n    \"build\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"inputs\": [\"goProduction\"],\n      \"options\": {\n        \"main\": \"github.com/daytonaio/ssh-gateway\",\n        \"outputPath\": \"dist/apps/ssh-gateway\"\n      },\n      \"configurations\": {\n        \"production\": {}\n      }\n    },\n    \"serve\": {\n      \"executor\": \"@nx-go/nx-go:serve\",\n      \"options\": {\n        \"cmd\": \"gow\",\n        \"cwd\": \".\",\n        \"main\": \"github.com/daytonaio/ssh-gateway\"\n      },\n      \"configurations\": {\n        \"production\": {}\n      }\n    },\n    \"format\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"command\": \"cd {projectRoot} && go fmt ./...\"\n      }\n    },\n    \"test\": {\n      \"executor\": \"@nx-go/nx-go:test\"\n    },\n    \"lint\": {\n      \"executor\": \"@nx-go/nx-go:lint\"\n    },\n    \"check-version-env\": {},\n    \"docker\": {\n      \"options\": {\n        \"target\": \"ssh-gateway\"\n      }\n    },\n    \"push-manifest\": {}\n  }\n}\n"
  },
  {
    "path": "components.json",
    "content": "{\n  \"$schema\": \"https://ui.shadcn.com/schema.json\",\n  \"style\": \"default\",\n  \"rsc\": false,\n  \"tsx\": true,\n  \"tailwind\": {\n    \"config\": \"apps/dashboard/tailwind.config.js\",\n    \"css\": \"apps/dashboard/src/index.css\",\n    \"baseColor\": \"neutral\",\n    \"cssVariables\": true,\n    \"prefix\": \"\"\n  },\n  \"aliases\": {\n    \"components\": \"@/components\",\n    \"ui\": \"@/components/ui\",\n    \"utils\": \"@/lib/utils\",\n    \"hooks\": \"@/hooks\"\n  },\n  \"iconLibrary\": \"lucide\"\n}\n"
  },
  {
    "path": "docker/README.md",
    "content": "# Docker Compose Setup for Daytona\n\nThis folder contains a Docker Compose setup for running Daytona locally.\n\n⚠️ **Important**:\n\n- This setup is still in development and is **not safe to use in production**\n- A separate deployment guide will be provided for production scenarios\n\n## Overview\n\nThe Docker Compose configuration includes all the necessary services to run Daytona:\n\n- **API**: Main Daytona application server\n- **Proxy**: Request proxy service\n- **Runner**: Service that hosts the Daytona Runner\n- **SSH Gateway**: Service that handles sandbox SSH access\n- **Database**: PostgreSQL database for data persistence\n- **Redis**: In-memory data store for caching and sessions\n- **Dex**: OIDC authentication provider\n- **Registry**: Docker image registry with web UI\n- **MinIO**: S3-compatible object storage\n- **MailDev**: Email testing service\n- **Jaeger**: Distributed tracing\n- **PgAdmin**: Database administration interface\n\n## Quick Start\n\n1. Start all services (from the root of the Daytona repo):\n\n   ```bash\n   docker compose -f docker/docker-compose.yaml up -d\n   ```\n\n2. Access the services:\n   - Daytona Dashboard: http://localhost:3000\n     - Access Credentials: dev@daytona.io `password`\n     - Make sure that the default snapshot is active at http://localhost:3000/dashboard/snapshots\n   - PgAdmin: http://localhost:5050\n   - Registry UI: http://localhost:5100\n   - MinIO Console: http://localhost:9001 (minioadmin / minioadmin)\n\n## DNS Setup for Proxy URLs\n\nFor local development, you need to resolve `*.proxy.localhost` domains to `127.0.0.1`:\n\n```bash\n./scripts/setup-proxy-dns.sh\n```\n\nThis configures dnsmasq with `address=/proxy.localhost/127.0.0.1`.\n\n**Without this setup**, SDK examples and direct proxy access won't work.\n\n## Development Notes\n\n- The setup uses shared networking for simplified service communication\n- Database and storage data is persisted in Docker volumes\n- The registry is configured to allow image deletion for testing\n- Sandbox resource limits are disabled due to inability to partition cgroups in DinD environment where the sock is not mounted\n\n<br><br><br>\n\n# Auth0 Configuration Guide for Daytona\n\n## Step 1: Create Your Auth0 Tenant\n\nBegin by navigating to https://auth0.com/signup and start the signup process. Choose your account type based on your use case - select `Company` for business applications or `Personal` for individual projects.\\\nOn the \"Let's get setup\" page, you'll need to enter your application name such as `My Daytona` and select `Single Page Application (SPA)` as the application type. For authentication methods, you can start with `Email and Password` since additional social providers like Google, GitHub, or Facebook can be added later. Once you've configured these settings, click `Create Application` in the bottom right corner.\n\n## Step 2: Configure Your Single Page Application\n\nNavigate to `Applications` > `Applications` in the left sidebar and select the application you just created. Click the `Settings` tab and scroll down to find the `Application URIs` section where you'll configure the callback and origin URLs.\nIn the `Allowed Callback URIs` field, add the following URLs:\n\n```\nhttp://localhost:3000\nhttp://localhost:3000/api/oauth2-redirect.html\nhttp://localhost:4000/callback\nhttp://proxy.localhost:4000/callback\n```\n\nFor `Allowed Logout URIs`, add:\n\n```\nhttp://localhost:3000\n```\n\nAnd for `Allowed Web Origins`, add:\n\n```\nhttp://localhost:3000\n```\n\nRemember to click `Save Changes` at the bottom of the page to apply these configurations.\n\n## Step 3: Create Machine-to-Machine Application\n\nYou'll need a Machine-to-Machine application to interact with Auth0's Management API. Go to `Applications` > `Applications` and click `Create Application`. Choose `Machine to Machine Applications` as the type and provide a descriptive name like `My Management API M2M`.\nAfter creating the application, navigate to the `APIs` tab within your new M2M application. Find and authorize the `Auth0 Management API` by clicking the toggle or authorize button.\\\nOnce authorized, click the dropdown arrow next to the Management API to configure permissions. Grant the following permissions to your M2M application:\n\n```\nread:users\nupdate:users\nread:connections\ncreate:guardian_enrollment_tickets\nread:connections_options\n```\n\nClick `Save` to apply these permission changes.\n\n## Step 4: Set Up Custom API\n\nYour Daytona application will need a custom API to handle authentication and authorization. Navigate to `Applications` > `APIs` in the left sidebar and click `Create API`. Enter a descriptive name such as `My Daytona API` and provide an identifier like `my-daytona-api`. The identifier should be a unique string that will be used in your application configuration.\\\nAfter creating the API, go to the `Permissions` tab to define the scopes your application will use. Add each of the following permissions with their corresponding descriptions:\n\n| Permission | Description |\n|------------|-------------|\n| `read:node` | Get workspace node info |\n| `create:node` | Create new workspace node record |\n| `create:user` | Create user account |\n| `read:users` | Get all user accounts |\n| `regenerate-key-pair:users` | Regenerate user SSH key-pair |\n| `read:workspaces` | Read workspaces (user scope) |\n| `create:registry` | Create a new docker registry auth record |\n| `read:registries` | Get all docker registry records |\n| `read:registry` | Get docker registry record |\n| `write:registry` | Create or update docker registry record |\n\n## Step 5: Configure Environment Variables\n\nOnce you've completed all the Auth0 setup steps, you'll need to configure environment variables in your Daytona deployment. These variables connect your application to the Auth0 services you've just configured.\n\n### Finding Your Configuration Values\n\nYou can find the necessary values in the Auth0 dashboard. For your SPA application settings, go to `Applications` > `Applications`, select your SPA app, and click the `Settings` tab. For your M2M application, follow the same path but select your Machine-to-Machine app instead. Custom API settings are located under `Applications` > `APIs`, then select your custom API and go to `Settings`.\n\n### API Service Configuration\n\nConfigure the following environment variables for your API service:\n\n```bash\nOIDC_CLIENT_ID=your_spa_app_client_id\nOIDC_ISSUER_BASE_URL=your_spa_app_domain\nOIDC_AUDIENCE=your_custom_api_identifier\nOIDC_MANAGEMENT_API_ENABLED=true\nOIDC_MANAGEMENT_API_CLIENT_ID=your_m2m_app_client_id\nOIDC_MANAGEMENT_API_CLIENT_SECRET=your_m2m_app_client_secret\nOIDC_MANAGEMENT_API_AUDIENCE=your_auth0_managment_api_identifier\n```\n\n### Proxy Service Configuration\n\nFor your proxy service, configure these environment variables:\n\n```bash\nOIDC_CLIENT_ID=your_spa_app_client_id\nOIDC_CLIENT_SECRET=\nOIDC_DOMAIN=your_spa_app_domain\nOIDC_AUDIENCE=your_custom_api_identifier (with trailing slash)\n```\n\nNote that `OIDC_CLIENT_SECRET` should remain empty for your proxy environment.\n"
  },
  {
    "path": "docker/dex/config.yaml",
    "content": "# config.yaml\nissuer: http://localhost:5556/dex\nstorage:\n  type: sqlite3\n  config:\n    file: /var/dex/dex.db\n\nweb:\n  http: 0.0.0.0:5556\n  allowedOrigins: ['*']\n  allowedHeaders: ['x-requested-with']\nstaticClients:\n  - id: daytona\n    redirectURIs:\n      - 'http://localhost:3000'\n      - 'http://localhost:3000/api/oauth2-redirect.html'\n      - 'http://localhost:3009/callback'\n      - 'http://proxy.localhost:4000/callback'\n    name: 'Daytona'\n    public: true\nenablePasswordDB: true\nstaticPasswords:\n  - email: 'dev@daytona.io'\n    # password generated with:\n    # echo password | htpasswd -BinC 10 admin | cut -d: -f2\n    hash: '$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W'\n    username: 'admin'\n    userID: '1234'\n"
  },
  {
    "path": "docker/docker-compose.build.override.yaml",
    "content": "name: daytona\nservices:\n  api:\n    build:\n      context: ../\n      dockerfile: apps/api/Dockerfile\n      target: daytona\n  \n  proxy:\n    build:\n      context: ../\n      dockerfile: apps/proxy/Dockerfile\n      target: proxy\n\n  runner:\n    build:\n      context: ../\n      dockerfile: apps/runner/Dockerfile\n      target: runner\n\n  ssh-gateway:\n    build:\n      context: ../\n      dockerfile: apps/ssh-gateway/Dockerfile\n      target: ssh-gateway"
  },
  {
    "path": "docker/docker-compose.yaml",
    "content": "name: daytona\nservices:\n  api:\n    image: daytonaio/daytona-api\n    ports:\n      - 3000:3000\n    environment:\n      - OTEL_ENABLED=true\n      - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318\n      # Default to slim image for faster startup\n      - DEFAULT_SNAPSHOT=daytonaio/sandbox:0.5.0-slim\n      - ENCRYPTION_KEY=supersecretkey\n      - ENCRYPTION_SALT=supersecretsalt\n      - NODE_ENV=production\n      - PORT=3000\n      - DB_HOST=db\n      - DB_PORT=5432\n      - DB_USERNAME=user\n      - DB_PASSWORD=pass\n      - DB_DATABASE=daytona\n      - REDIS_HOST=redis\n      - REDIS_PORT=6379\n      - OIDC_CLIENT_ID=daytona\n      - OIDC_ISSUER_BASE_URL=http://dex:5556/dex\n      - PUBLIC_OIDC_DOMAIN=http://localhost:5556/dex\n      - OIDC_AUDIENCE=daytona\n      - OIDC_MANAGEMENT_API_ENABLED=\n      - OIDC_MANAGEMENT_API_CLIENT_ID=\n      - OIDC_MANAGEMENT_API_CLIENT_SECRET=\n      - OIDC_MANAGEMENT_API_AUDIENCE=\n      - DASHBOARD_URL=http://localhost:3000/dashboard\n      - DASHBOARD_BASE_API_URL=http://localhost:3000\n      - POSTHOG_API_KEY=phc_bYtEsdMDrNLydXPD4tufkBrHKgfO2zbycM30LOowYNv\n      - POSTHOG_HOST=https://d18ag4dodbta3l.cloudfront.net\n      - POSTHOG_ENVIRONMENT=local\n      - TRANSIENT_REGISTRY_URL=http://registry:6000\n      - TRANSIENT_REGISTRY_ADMIN=admin\n      - TRANSIENT_REGISTRY_PASSWORD=password\n      - TRANSIENT_REGISTRY_PROJECT_ID=daytona\n      - INTERNAL_REGISTRY_URL=http://registry:6000\n      - INTERNAL_REGISTRY_ADMIN=admin\n      - INTERNAL_REGISTRY_PASSWORD=password\n      - INTERNAL_REGISTRY_PROJECT_ID=daytona\n      - SMTP_HOST=maildev\n      - SMTP_PORT=1025\n      - SMTP_USER=\n      - SMTP_PASSWORD=\n      - SMTP_SECURE=\n      - SMTP_EMAIL_FROM=Daytona Team <no-reply@daytona.io>\n      - S3_ENDPOINT=http://minio:9000\n      - S3_STS_ENDPOINT=http://minio:9000/minio/v1/assume-role\n      - S3_REGION=us-east-1\n      - S3_ACCESS_KEY=minioadmin\n      - S3_SECRET_KEY=minioadmin\n      - S3_DEFAULT_BUCKET=daytona\n      - S3_ACCOUNT_ID=/\n      - S3_ROLE_NAME=/\n      - ENVIRONMENT=docker-compose\n      - MAX_AUTO_ARCHIVE_INTERVAL=43200\n      - MAINTENANCE_MODE=false\n      - PROXY_DOMAIN=proxy.localhost:4000\n      - PROXY_PROTOCOL=http\n      - PROXY_API_KEY=super_secret_key\n      - PROXY_TEMPLATE_URL=http://{{PORT}}-{{sandboxId}}.proxy.localhost:4000\n      - DEFAULT_RUNNER_DOMAIN=runner:3003\n      - DEFAULT_RUNNER_API_URL=http://runner:3003\n      - DEFAULT_RUNNER_PROXY_URL=http://runner:3003\n      - DEFAULT_RUNNER_API_KEY=secret_api_token\n      - DEFAULT_RUNNER_CPU=4\n      - DEFAULT_RUNNER_MEMORY=8\n      - DEFAULT_RUNNER_DISK=50\n      - DEFAULT_RUNNER_NAME=default\n      - DEFAULT_REGION_ID=us\n      - DEFAULT_REGION_NAME=us\n      - DEFAULT_REGION_ENFORCE_QUOTAS=false\n      - DEFAULT_ORG_QUOTA_TOTAL_CPU_QUOTA=10000\n      - DEFAULT_ORG_QUOTA_TOTAL_MEMORY_QUOTA=10000\n      - DEFAULT_ORG_QUOTA_TOTAL_DISK_QUOTA=100000\n      - DEFAULT_ORG_QUOTA_MAX_CPU_PER_SANDBOX=100\n      - DEFAULT_ORG_QUOTA_MAX_MEMORY_PER_SANDBOX=100\n      - DEFAULT_ORG_QUOTA_MAX_DISK_PER_SANDBOX=1000\n      - DEFAULT_ORG_QUOTA_SNAPSHOT_QUOTA=1000\n      - DEFAULT_ORG_QUOTA_MAX_SNAPSHOT_SIZE=1000\n      - DEFAULT_ORG_QUOTA_VOLUME_QUOTA=10000\n      - SSH_GATEWAY_API_KEY=ssh_secret_api_token\n      - SSH_GATEWAY_COMMAND=ssh -p 2222 {{TOKEN}}@localhost\n      - SSH_GATEWAY_PUBLIC_KEY=c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCZ1FEZUtocFdOYVhVNkpSMnJXekc1NlZJeksrcmsrdForcCtVUmwyeWF5cWRnZGg2bnVOL1NtVnJsYmV4MGlrRVZZemdRWUIwWno5M2dqOVhxSkd4WjJiMHVoSDFzNkp2bnhKZVdIK05rbjBNMzRiRjZkeVloZ3o4M0JaTitWcElJdnVDT1pxYWE4VnlRWjhPdjVLMU00enlmQnFCMld3ejcwZEVWUnFaMnVZckd5U0RqUUIrU3hRQ3phY0djb2JRQTFUd2QxdEJvSk5BaVpPWXFSU3d6TmNoTk5hZHlxSHRGdkZRQ0hhNjZWaVBmQ0FVUGt2cEN6ZGh3TmJGdVhGVWkxbnZOWkx4M056RU41M05LWUhZcWU3Y3dXZkI4QjBoRDhDd3hmSDd6T0o1b1RCMnBMVVlsUWpZRDNsN3k4SkFTbDZpYkpuR1A1SWczVXpZWlRIdUdkNzVXWktnNTRJTVROQlFPMWpJdE9HL0orUm1XbzB0YTdpRkF6ZExyL1BmbDdXTVMwbEZhSm9scTdUVmJLUG1JODFTOU04VEgrbXhLbGZ5b2NqZzhwSUdlQUllcEo3dXl1Vk1xT2wxeVVuSFNycDRlVEVlR0k3NlpCOFRoUzhkYnBLUTIvb2RYMHkwc3FSZDI0Y2lGdnM0dnZVaW80NFdYNlNWRG54dXpWRHc1Rzg9IGRheXRvbmFAMDQwNjZiZDIwY2Vi\n      - SSH_GATEWAY_URL=localhost:2222\n      - RUNNER_DECLARATIVE_BUILD_SCORE_THRESHOLD=10\n      - RUNNER_AVAILABILITY_SCORE_THRESHOLD=10\n      - RUNNER_START_SCORE_THRESHOLD=3\n      - SKIP_USER_EMAIL_VERIFICATION=true\n      - RUN_MIGRATIONS=true\n      - OTEL_COLLECTOR_API_KEY=otel_collector_api_key\n      - HEALTH_CHECK_API_KEY=supersecretkey\n    networks:\n      - daytona-network\n    restart: always\n    privileged: true\n    depends_on:\n      - db\n      - runner\n      - redis\n      - dex\n      - registry\n\n  proxy:\n    image: daytonaio/daytona-proxy\n    environment:\n      - DAYTONA_API_URL=http://api:3000/api\n      - PROXY_PORT=4000\n      - PROXY_API_KEY=super_secret_key\n      - PROXY_PROTOCOL=http\n      - OIDC_CLIENT_ID=daytona\n      - OIDC_CLIENT_SECRET=\n      - OIDC_DOMAIN=http://dex:5556/dex\n      - OIDC_PUBLIC_DOMAIN=http://localhost:5556/dex\n      - OIDC_AUDIENCE=daytona\n      - REDIS_HOST=redis\n      - REDIS_PORT=6379\n      - TOOLBOX_ONLY_MODE=false\n      - PREVIEW_WARNING_ENABLED=false\n    networks:\n      - daytona-network\n    ports:\n      - 4000:4000\n    restart: always\n\n  runner:\n    image: daytonaio/daytona-runner\n    environment:\n      - ENVIRONMENT=development\n      - API_PORT=3003\n      - DAYTONA_RUNNER_TOKEN=secret_api_token\n      - LOG_FILE_PATH=/home/daytona/runner/runner.log\n      - RESOURCE_LIMITS_DISABLED=true\n      - AWS_ENDPOINT_URL=http://minio:9000\n      - AWS_REGION=us-east-1\n      - AWS_ACCESS_KEY_ID=minioadmin\n      - AWS_SECRET_ACCESS_KEY=minioadmin\n      - AWS_DEFAULT_BUCKET=daytona\n      - DAYTONA_API_URL=http://api:3000/api\n      - RUNNER_DOMAIN=runner\n      - SSH_GATEWAY_ENABLE=true\n      - SSH_PUBLIC_KEY=c3NoLXJzYSBBQUFBQjNOemFDMXljMkVBQUFBREFRQUJBQUFCZ1FEZUtocFdOYVhVNkpSMnJXekc1NlZJeksrcmsrdForcCtVUmwyeWF5cWRnZGg2bnVOL1NtVnJsYmV4MGlrRVZZemdRWUIwWno5M2dqOVhxSkd4WjJiMHVoSDFzNkp2bnhKZVdIK05rbjBNMzRiRjZkeVloZ3o4M0JaTitWcElJdnVDT1pxYWE4VnlRWjhPdjVLMU00enlmQnFCMld3ejcwZEVWUnFaMnVZckd5U0RqUUIrU3hRQ3phY0djb2JRQTFUd2QxdEJvSk5BaVpPWXFSU3d6TmNoTk5hZHlxSHRGdkZRQ0hhNjZWaVBmQ0FVUGt2cEN6ZGh3TmJGdVhGVWkxbnZOWkx4M056RU41M05LWUhZcWU3Y3dXZkI4QjBoRDhDd3hmSDd6T0o1b1RCMnBMVVlsUWpZRDNsN3k4SkFTbDZpYkpuR1A1SWczVXpZWlRIdUdkNzVXWktnNTRJTVROQlFPMWpJdE9HL0orUm1XbzB0YTdpRkF6ZExyL1BmbDdXTVMwbEZhSm9scTdUVmJLUG1JODFTOU04VEgrbXhLbGZ5b2NqZzhwSUdlQUllcEo3dXl1Vk1xT2wxeVVuSFNycDRlVEVlR0k3NlpCOFRoUzhkYnBLUTIvb2RYMHkwc3FSZDI0Y2lGdnM0dnZVaW80NFdYNlNWRG54dXpWRHc1Rzg9IGRheXRvbmFAMDQwNjZiZDIwY2Vi\n    networks:\n      - daytona-network\n    ports:\n      - 3003:3003\n    privileged: true\n    restart: always\n\n  ssh-gateway:\n    image: daytonaio/daytona-ssh-gateway\n    environment:\n      - API_URL=http://api:3000/api\n      - API_KEY=ssh_secret_api_token\n      - SSH_PRIVATE_KEY=LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFZRUEzaW9hVmpXbDFPaVVkcTFzeHVlbFNNeXZxNVByV2ZxZmxFWmRzbXNxbllIWWVwN2pmMHBsCmE1VzNzZElwQkZXTTRFR0FkR2MvZDRJL1Y2aVJzV2RtOUxvUjliT2liNThTWGxoL2paSjlETitHeGVuY21JWU0vTndXVGYKbGFTQ0w3Z2ptYW1tdkZja0dmRHIrU3RUT004bndhZ2Rsc00rOUhSRlVhbWRybUt4c2tnNDBBZmtzVUFzMm5CbktHMEFOVQo4SGRiUWFDVFFJbVRtS2tVc016WElUVFduY3FoN1JieFVBaDJ1dWxZajN3Z0ZENUw2UXMzWWNEV3hibHhWSXRaN3pXUzhkCnpjeERlZHpTbUIyS251M01GbndmQWRJUS9Bc01YeCs4emllYUV3ZHFTMUdKVUkyQTk1ZTh2Q1FFcGVvbXlaeGorU0lOMU0KMkdVeDdobmUrVm1Tb09lQ0RFelFVRHRZeUxUaHZ5ZmtabHFOTFd1NGhRTTNTNi96MzVlMWpFdEpSV2lhSmF1MDFXeWo1aQpQTlV2VFBFeC9wc1NwWDhxSEk0UEtTQm5nQ0hxU2U3c3JsVEtqcGRjbEp4MHE2ZUhreEhoaU8rbVFmRTRVdkhXNlNrTnY2CkhWOU10TEtrWGR1SEloYjdPTDcxSXFPT0ZsK2tsUTU4YnMxUThPUnZBQUFGa0VOTllCMURUV0FkQUFBQUIzTnphQzF5YzIKRUFBQUdCQU40cUdsWTFwZFRvbEhhdGJNYm5wVWpNcjZ1VDYxbjZuNVJHWGJKcktwMkIySHFlNDM5S1pXdVZ0N0hTS1FSVgpqT0JCZ0hSblAzZUNQMWVva2JGblp2UzZFZld6b20rZkVsNVlmNDJTZlF6ZmhzWHAzSmlHRFB6Y0ZrMzVXa2dpKzRJNW1wCnByeFhKQm53Ni9rclV6alBKOEdvSFpiRFB2UjBSVkdwbmE1aXNiSklPTkFINUxGQUxOcHdaeWh0QURWUEIzVzBHZ2swQ0oKazVpcEZMRE0xeUUwMXAzS29lMFc4VkFJZHJycFdJOThJQlErUytrTE4ySEExc1c1Y1ZTTFdlODFrdkhjM01RM25jMHBnZAppcDd0ekJaOEh3SFNFUHdMREY4ZnZNNG5taE1IYWt0UmlWQ05nUGVYdkx3a0JLWHFKc21jWS9raURkVE5obE1lNFozdmxaCmtxRG5nZ3hNMEZBN1dNaTA0YjhuNUdaYWpTMXJ1SVVETjB1djg5K1h0WXhMU1VWb21pV3J0TlZzbytZanpWTDB6eE1mNmIKRXFWL0toeU9EeWtnWjRBaDZrbnU3SzVVeW82WFhKU2NkS3VuaDVNUjRZanZwa0h4T0ZMeDF1a3BEYitoMWZUTFN5cEYzYgpoeUlXK3ppKzlTS2pqaFpmcEpVT2ZHN05VUERrYndBQUFBTUJBQUVBQUFHQVFVRjRydTNmSWVTWEJ5ejFrSThtRzNZVCszCi9kVjNhb1BQTldQandBTG5lZlVKVXZHWXFPczhVc1NjMERRMFNsdHBGRzIrb2YyRWludG1YTE5hSzd1UktXaCtjVnhWZWkKRzVnL0R5U0NHcS9sZEdpMjVRNHE3bkx2RWtRMTRvNXo5ZEpadVJZQ3p3YTdZNmVkdmgvQVBORjdMN3pmYlhuUkl4OGtTeQpEakRySlFUVnV6VTJWV0lXU3F0TmdiQlNxVlhuU1FsM3hGQkdYa3RxaWpiVE1kMWFFaGtRT2VBSGdHdFkxbTRvdjcrVmxxClNzZnBvREF0T2tkY1RvT2o2RU50d05yS1dHL2g4QW5XVWptVjlPZ0h2UEFXR2hlTndlYXdvOW5lVVdseDZUcDNrVUdxdzYKVU9HTlYwN2lsOUdWU1JMa3hFUDlSMHZKZStxM3VIUDUzQ2NVNDI0S3hPQ1d6OERJK3BjT0N5R0QrOHZqYllOTlNPR3Z3YwowcjRsa2dDMUE5TWNLelFHcit5S1FIcXhndjlZdWRUYXFLSUhDWU0zL2J4dktwK2FjMXdEV1lCc0ZJSklRSU9mN2JpQ0E2CnYyaFlDMWRUb2V1NnlCbmtXMWVmZWJkZFE0RXl1ZzhTRVQrY3FrV1lYOWJwTi92SmZmV1F0VytEQ3RRdEF5ZEtWeEFBQUEKd0NCZTRtd01oT0dOUzhKeVVCNXVrczhvVTdGNnZGWjBTa3liUmxsK3pGaGVKSy9yNlhGZkxTeEpKaXF0NG1IQXdwTEJxMApqdHBIMlY2TjNVNEhmdHg4M3lXKzZWcmc2Mkp5NnZHazhJQ1I0bHRIOXVVRnlWb2piRFVtZ2pZMmpidkd6a2lOc2IzRi9wCmRvdnBJRHdabVAvOGo3U1dpYTFBQzFBM3RYNDg5eUc1NC9GY2JsZHhBelBJZkFOZzJNd0RERXBMZ3VGOXIwY1hqNzUwWGkKMUxyOUNuMjM0RDJuYmpXRmxOY1o0OHh3R2h0SThEWkFQbGt6YXJLcEVmbHpxOTRBQUFBTUVBNEZEMG1ZZEo2NDhBMDJBYgpxc3pRZGprampEV3dGQ1hRbE5lcEY2R2RTTS84V1NtYmFGb3hYZlFmNWVLSHRMQWNzVnBPSitkRnpZaEViQmcvaklrMmIxCktOY3RnK1lDWHZTTElPbmIrSVYwUFVZK0Z6NGFXU2tucTY4Q1QyR1N3K0krVlRsc3FRTXVBbjBPc2lGUmdXSFhuS000YU8KN2tDWlhUSm9xdFo0SzNJZTJ3RGtneEdkcnhCcVFkWWlkczQxVmJndlZLbXNNYVl6NHVvRk9hQVdiVlREOVN3ODdwa2oyRwo2dUNGSmZzK3g4d0dibGpsS2kwdWdQRndwVU94dk5BQUFBd1FEOWkxZDVKd1h2TUl3MzhqSjNubGNlc2U1RmM2M0x0N2IvClRpTzN1bGpCNXFnM2JHc1Y2Z1FBcEhaeTV6NWtIQ0E3TksyMVhtOUNzODhyU3p3ZTJHcllleVJkNjFKaWFRaWpsa3U2MlQKa05Bb0RjOHhoeS9yd3M5dmxUMFJrUDRNejI3cDREVFFaT0pCQ09CMHJLYVY1cFBxTHNDWm1YTHZ2dVpkQzdIUGJremY5SApHYXFwcWc1UWNESW9zWHowcFZneGVQZnJpV0NlZyt0UC8vOXJDanIwdjJMMGhrOWJydUtNTXdYK3IvU0lab0haNTJOSlJaClJRKzV6VGNtRlJIU3NBQUFBVVpHRjVkRzl1WVVBd05EQTJObUprTWpCalpXSUJBZ01FQlFZSAotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0=\n      - SSH_HOST_KEY=LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJGd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFRRUF1K0xKeXQvS3Y2VmlhWkI2am5KUFM1N0ZwWjJGajdWNGYvNXFLYTY1U3lwRFpXWVBzT2NpCkhuRE93elpsVU1Sd2VyaWJHcmsxM2JZZGdWM2taeVNzUGdDV2xERzlPbXVwb2kzWjYzeUUyYXlvKy9RQUxJQjdxc0NKcVMKNjZodm45ZTBGMHh4MGFuUVdCR09Fa1hMZ0IrdTRSNThoL0dtZkM3WDU5RERIK21Hb0thSjMxek1ZQWFyMTV0NDN2Q3BiYgpNb1lCbmNtWWtrVDJNeXhxQ3MrdjZNYmN0ZmRBTks0UHhyc2dGV1I0a0s0T3pjYjJrMFZCMzRoSHdMMTBUcEVIZDI3bjhBCmV1RU1PUEVIK3RFOEtwRmFaR3NDNS9aV1FZUitncEM3SG01YVBnWjUzanF3TkNCZFprekpZNTZjUEx5SHZoeXV4K1h0RGEKdlhoSkhTRWszUUFBQTlDOElNL1B2Q0RQendBQUFBZHpjMmd0Y25OaEFBQUJBUUM3NHNuSzM4cS9wV0pwa0hxT2NrOUxucwpXbG5ZV1B0WGgvL21vcHJybExLa05sWmcrdzV5SWVjTTdETm1WUXhIQjZ1SnNhdVRYZHRoMkJYZVJuSkt3K0FKYVVNYjA2CmE2bWlMZG5yZklUWnJLajc5QUFzZ0h1cXdJbXBMcnFHK2YxN1FYVEhIUnFkQllFWTRTUmN1QUg2N2hIbnlIOGFaOEx0Zm4KME1NZjZZYWdwb25mWE14Z0JxdlhtM2plOEtsdHN5aGdHZHlaaVNSUFl6TEdvS3o2L294dHkxOTBBMHJnL0d1eUFWWkhpUQpyZzdOeHZhVFJVSGZpRWZBdlhST2tRZDNidWZ3QjY0UXc0OFFmNjBUd3FrVnBrYXdMbjlsWkJoSDZDa0xzZWJsbytCbm5lCk9yQTBJRjFtVE1sam5wdzh2SWUrSEs3SDVlME5xOWVFa2RJU1RkQUFBQUF3RUFBUUFBQVFBeUJpTG1FZ21nVnY5SnpmN2oKZUVubWYySnVRdTl4b01aeGhhSnNjS25DK29DeE9haEoySEE4SEpyZ1hOWkMxOXArd2pJQnZuZzZES2YwYnJSR1JmeGFFYgp3RnZ1eDc1bmhteHNCenMxYUh3akhIeTJKVWR1ejJQSWNxZFZlU1luTDc0eVNkY3dGSDkxUTA5SlRDM3ZjZ0FVemhJbis4CjN3MkdRQnc1S0FKNlA2TzNYNFJQMkpoLzA2UlpqYWIvbzJManBWUHRKVXhxN0tkekZYSzUyZ25oKzJGL0p2ZHFJcTRDVncKT0VPdUNOS282MzJBYS8rUFl5NDlhaVY0YkVmUDZZWUlxaFpxekR6UjNNNncwb3ZQRGMvcjFveGlSaDA5dTlFTEtFK1FoNQpkeGR0SDIrVmFMTnVWQ2JzL09FZXVYNXRPQm1mS2k3TjYrSkZFckxoMkZkOUFBQUFnRDcwOWdRZ2kvZ1RZYjdWOGsxcmo5Cm5tajU3dmFFaTY4MFY5TkdqbFBjdWtPNHQ5Vk5HVzhjMVZVdjFJaGhKN3RySUtsWG5PTnRQa0hWeUh5SUxocGVUQ3N2bXkKMUhJSFErUUViYlF6cldDYVA3MFE2d1JXQm9XeTJVbzIwRUgreE1nUkdBSk1adE41OW1GN0t5MUVCUkYzMUI4Mmo2Q2JwTgpYeCtoNE15b2ZXQUFBQWdRRDU2eDhwVklBMXNJQjFRWTFsUlZ4RW92Q0x4bXlaeVR2RzlIbThjT2FqeUZoY1dCNWljZXFvCkNrY3ZncXozNDVUaVBVVFd4eW9PNkJTYVlIbEYxUVI3a1BTU1dsUENRRTFxbGgyQXNoZDV3bHlyV1U5elAxNkExSWQxV0MKL0M1QngvUjRhSkpyM1N3S2RaenFkTHhRTGc4RFhIbWdZOXVNVlpVb2hQbVBkZml3QUFBSUVBd0hVN1g3aDV5REtrMUVORQp4RE82UjVXclU2M3hXNjVOdlBsS0ZzcE13Zks2QWZyZUdIbFUrTlhWZmRNNGlra0dDMXQ5Wisrc2ZKcXJlckxaVUdGSlAzClVOUkg1WGNnR0dMeUVDQi9EblJSRzJaMGNtYzFVWlBpMUJ6MnVSRll3aW5rbDNaWHA3TlJrV2ZudUpsRUlXVk9TMUY5NTYKa01DbURPMlNSUUhHbWpjQUFBQVVjM05vTFdkaGRHVjNZWGt0YUc5emRDMXJaWGtCQWdNRUJRWUgKLS0tLS1FTkQgT1BFTlNTSCBQUklWQVRFIEtFWS0tLS0t\n      - SSH_GATEWAY_PORT=2222\n    networks:\n      - daytona-network\n    ports:\n      - 2222:2222\n    restart: always\n\n  dex:\n    image: dexidp/dex:v2.42.0\n    volumes:\n      - ./dex/config.yaml:/etc/dex/config.yaml\n      - dex_db:/var/dex\n    entrypoint: ['sh', '-c', 'touch /var/dex/dex.db && exec dex serve /etc/dex/config.yaml']\n    networks:\n      - daytona-network\n    ports:\n      - 5556:5556\n    healthcheck:\n      test: [\"CMD\", \"wget\", \"--spider\", \"--quiet\", \"http://localhost:5556/dex/.well-known/openid-configuration\"]\n\n  db:\n    image: postgres:18\n    environment:\n      - POSTGRES_PASSWORD=pass\n      - POSTGRES_USER=user\n      - POSTGRES_DB=daytona\n    networks:\n      - daytona-network\n    volumes:\n      - db_data:/var/lib/postgresql/18/docker\n\n  pgadmin:\n    image: dpage/pgadmin4:9.2.0\n    entrypoint: ['sh', '-c', 'chmod 600 /pgpass && exec /entrypoint.sh']\n    environment:\n      PGADMIN_DEFAULT_EMAIL: dev@daytona.io\n      PGADMIN_DEFAULT_PASSWORD: pgadmin\n      PGADMIN_CONFIG_SERVER_MODE: 'False'\n      PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: 'False'\n    user: root\n    volumes:\n      - ./pgadmin4/servers.json:/pgadmin4/servers.json\n      - ./pgadmin4/pgpass:/pgpass\n    depends_on:\n      - db\n    ports:\n      - 5050:80\n    networks:\n      - daytona-network\n\n  redis:\n    image: redis:latest\n    networks:\n      - daytona-network\n\n  registry-ui:\n    image: joxit/docker-registry-ui:main\n    restart: always\n    environment:\n      - SINGLE_REGISTRY=true\n      - REGISTRY_TITLE=Docker Registry UI\n      - DELETE_IMAGES=true\n      - SHOW_CONTENT_DIGEST=true\n      - NGINX_PROXY_PASS_URL=http://registry:6000\n      - SHOW_CATALOG_NB_TAGS=true\n      - CATALOG_MIN_BRANCHES=1\n      - CATALOG_MAX_BRANCHES=1\n      - TAGLIST_PAGE_SIZE=100\n      - REGISTRY_SECURED=false\n      - CATALOG_ELEMENTS_LIMIT=1000\n    networks:\n      - daytona-network\n    ports:\n      - 5100:80\n\n  registry:\n    image: registry:2.8.2\n    restart: always\n    environment:\n      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Origin: '[http://registry-ui.example.com]'\n      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Methods: '[HEAD,GET,OPTIONS,DELETE]'\n      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Credentials: '[true]'\n      REGISTRY_HTTP_HEADERS_Access-Control-Allow-Headers: '[Authorization,Accept,Cache-Control]'\n      REGISTRY_HTTP_HEADERS_Access-Control-Expose-Headers: '[Docker-Content-Digest]'\n      REGISTRY_STORAGE_DELETE_ENABLED: 'true'\n      REGISTRY_HTTP_ADDR: registry:6000\n    volumes:\n      - registry:/var/lib/registry\n    networks:\n      - daytona-network\n    ports:\n      - 6000:6000\n\n  maildev:\n    image: maildev/maildev\n    networks:\n      - daytona-network\n    ports:\n      - 1080:1080\n\n  minio:\n    image: minio/minio:latest\n    environment:\n      - MINIO_ROOT_USER=minioadmin\n      - MINIO_ROOT_PASSWORD=minioadmin\n      - MINIO_IDENTITY_STS_EXPIRY=\"24h\"\n    volumes:\n      - minio_data:/data\n    command: server /data --console-address \":9001\"\n    networks:\n      - daytona-network\n    ports:\n      - 9001:9001\n\n  jaeger:\n    image: jaegertracing/all-in-one:1.67.0\n    networks:\n      - daytona-network\n    ports:\n      - 16686:16686\n\n  otel-collector:\n    image: otel/opentelemetry-collector-contrib:0.138.0\n    volumes:\n      - ./otel/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml\n    networks:\n      - daytona-network\n\nvolumes:\n  registry: {}\n  minio_data: {}\n  db_data: {}\n  dex_db: {}\n\nnetworks:\n  daytona-network:\n    driver: bridge\n"
  },
  {
    "path": "docker/otel/otel-collector-config.yaml",
    "content": "receivers:\n  otlp:\n    protocols:\n      grpc:\n        endpoint: 0.0.0.0:4317\n      http:\n        endpoint: 0.0.0.0:4318\n\nprocessors:\n  batch:\n\nexporters:\n  # Logs to console\n  debug:\n    verbosity: detailed\n\n  # Metrics to Prometheus endpoint\n  prometheus:\n    endpoint: 0.0.0.0:9090\n    namespace: otel\n\n  # Traces to Jaeger\n  otlp/jaeger:\n    endpoint: jaeger:4317\n    tls:\n      insecure: true\n\nservice:\n  pipelines:\n    traces:\n      receivers: [otlp]\n      processors: [batch]\n      exporters: [otlp/jaeger]\n\n    metrics:\n      receivers: [otlp]\n      processors: [batch]\n      exporters: [prometheus]\n\n    logs:\n      receivers: [otlp]\n      processors: [batch]\n      exporters: [debug]\n"
  },
  {
    "path": "docker/pgadmin4/pgpass",
    "content": "db:5432:*:user:pass"
  },
  {
    "path": "docker/pgadmin4/servers.json",
    "content": "{\n  \"Servers\": {\n    \"1\": {\n      \"Name\": \"Daytona\",\n      \"Group\": \"Servers\",\n      \"Host\": \"db\",\n      \"Port\": 5432,\n      \"MaintenanceDB\": \"postgres\",\n      \"Username\": \"user\",\n      \"PassFile\": \"/pgpass\"\n    }\n  }\n}\n"
  },
  {
    "path": "ecosystem.config.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nmodule.exports = {\n  apps: [\n    {\n      name: 'daytona',\n      script: './dist/apps/api/main.js',\n      instances: 4,\n      exec_mode: 'cluster',\n      watch: false,\n      env: {\n        NODE_ENV: 'production',\n        PM2_CLUSTER: 'true',\n      },\n      wait_ready: true,\n      kill_timeout: 30000,\n      listen_timeout: 10000,\n    },\n  ],\n}\n"
  },
  {
    "path": "eslint.config.mjs",
    "content": "import nx from '@nx/eslint-plugin'\nimport react from 'eslint-plugin-react'\nimport reactHooks from 'eslint-plugin-react-hooks'\n\n/** @type {import('eslint').Linter.Config[]} */\nexport default [\n  ...nx.configs['flat/base'],\n  ...nx.configs['flat/typescript'],\n  ...nx.configs['flat/javascript'],\n  {\n    ignores: [\n      '**/dist',\n      '**/vite.config.*.timestamp*',\n      '**/vitest.config.*.timestamp*',\n      'apps/docs/**',\n      'libs/*api-client*/**',\n    ],\n  },\n  {\n    files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],\n    plugins: {\n      react,\n      'react-hooks': reactHooks,\n    },\n    rules: {\n      '@nx/enforce-module-boundaries': [\n        'error',\n        {\n          enforceBuildableLibDependency: true,\n          allow: ['^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?js$'],\n          depConstraints: [\n            {\n              sourceTag: '*',\n              onlyDependOnLibsWithTags: ['*'],\n            },\n          ],\n        },\n      ],\n    },\n  },\n  {\n    files: ['**/*.ts', '**/*.tsx', '**/*.cts', '**/*.mts', '**/*.js', '**/*.jsx', '**/*.cjs', '**/*.mjs'],\n    // Override or add rules here\n    rules: {\n      '@typescript-eslint/interface-name-prefix': 'off',\n      '@typescript-eslint/explicit-function-return-type': 'off',\n      '@typescript-eslint/explicit-module-boundary-types': 'off',\n      '@typescript-eslint/no-explicit-any': 'off',\n      '@typescript-eslint/no-useless-escape': 'off',\n    },\n  },\n  {\n    files: ['src/migrations/**/*.ts'],\n    rules: {\n      quotes: 'off',\n    },\n  },\n]\n"
  },
  {
    "path": "examples/go/auto_archive/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Example 1: Default interval\n\tlog.Println(\"=== Example 1: Default auto-archive interval ===\")\n\tparams1 := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox1, err := client.Create(ctx, params1, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Default auto-archive interval: %d minutes\\n\", sandbox1.AutoArchiveInterval)\n\n\t// Example 2: Set interval to 1 hour\n\tlog.Println(\"\\n=== Example 2: Update auto-archive interval to 60 minutes ===\")\n\tinterval := 60\n\tif err := sandbox1.SetAutoArchiveInterval(ctx, &interval); err != nil {\n\t\tlog.Fatalf(\"Failed to set auto-archive interval: %v\", err)\n\t}\n\n\t// Refresh sandbox info to see the updated interval\n\tsandbox1, err = client.Get(ctx, sandbox1.ID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Updated auto-archive interval: %d minutes\\n\", sandbox1.AutoArchiveInterval)\n\n\t// Clean up first sandbox\n\tif err := sandbox1.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t}\n\n\t// Example 3: Max interval\n\tlog.Println(\"\\n=== Example 3: Sandbox with max interval (never archive) ===\")\n\tmaxInterval := 0\n\tparams2 := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage:            types.CodeLanguagePython,\n\t\t\tAutoArchiveInterval: &maxInterval,\n\t\t},\n\t}\n\n\tsandbox2, err := client.Create(ctx, params2, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Auto-archive interval: %d (never archive)\\n\", sandbox2.AutoArchiveInterval)\n\n\t// Clean up second sandbox\n\tif err := sandbox2.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t}\n\n\t// Example 4: 1 day interval\n\tlog.Println(\"\\n=== Example 4: Sandbox with 1 day auto-archive interval ===\")\n\toneDayInterval := 1440 // 24 hours * 60 minutes\n\tparams3 := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage:            types.CodeLanguagePython,\n\t\t\tAutoArchiveInterval: &oneDayInterval,\n\t\t},\n\t}\n\n\tsandbox3, err := client.Create(ctx, params3, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Auto-archive interval: %d minutes (1 day)\\n\", sandbox3.AutoArchiveInterval)\n\n\t// Clean up third sandbox\n\tif err := sandbox3.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t}\n\n\tlog.Println(\"\\n✓ All auto-archive examples completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/auto_delete/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Example 1: Auto-delete is disabled by default\n\tlog.Println(\"=== Example 1: Default auto-delete interval (disabled) ===\")\n\tparams1 := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox1, err := client.Create(ctx, params1, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Default auto-delete interval: %d (disabled)\\n\", sandbox1.AutoDeleteInterval)\n\n\t// Example 2: Auto-delete after the Sandbox has been stopped for 1 hour\n\tlog.Println(\"\\n=== Example 2: Set auto-delete to 60 minutes after stop ===\")\n\tinterval := 60\n\tif err := sandbox1.SetAutoDeleteInterval(ctx, &interval); err != nil {\n\t\tlog.Fatalf(\"Failed to set auto-delete interval: %v\", err)\n\t}\n\n\t// Refresh sandbox info\n\tsandbox1, err = client.Get(ctx, sandbox1.ID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Updated auto-delete interval: %d minutes\\n\", sandbox1.AutoDeleteInterval)\n\n\t// Example 3: Delete immediately upon stopping\n\tlog.Println(\"\\n=== Example 3: Delete immediately upon stopping (0 minutes) ===\")\n\timmediateInterval := 0\n\tif err := sandbox1.SetAutoDeleteInterval(ctx, &immediateInterval); err != nil {\n\t\tlog.Fatalf(\"Failed to set auto-delete interval: %v\", err)\n\t}\n\n\t// Refresh sandbox info\n\tsandbox1, err = client.Get(ctx, sandbox1.ID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Updated auto-delete interval: %d (immediate)\\n\", sandbox1.AutoDeleteInterval)\n\n\t// Example 4: Disable auto-delete\n\tlog.Println(\"\\n=== Example 4: Disable auto-delete (-1) ===\")\n\tdisableInterval := -1\n\tif err := sandbox1.SetAutoDeleteInterval(ctx, &disableInterval); err != nil {\n\t\tlog.Fatalf(\"Failed to set auto-delete interval: %v\", err)\n\t}\n\n\t// Refresh sandbox info\n\tsandbox1, err = client.Get(ctx, sandbox1.ID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Updated auto-delete interval: %d (disabled)\\n\", sandbox1.AutoDeleteInterval)\n\n\t// Clean up first sandbox\n\tif err := sandbox1.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t}\n\n\t// Example 5: Auto-delete after the Sandbox has been stopped for 1 day\n\tlog.Println(\"\\n=== Example 5: Sandbox with 1 day auto-delete interval ===\")\n\toneDayInterval := 1440 // 24 hours * 60 minutes\n\tparams2 := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage:           types.CodeLanguagePython,\n\t\t\tAutoDeleteInterval: &oneDayInterval,\n\t\t},\n\t}\n\n\tsandbox2, err := client.Create(ctx, params2, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Auto-delete interval: %d minutes (1 day)\\n\", sandbox2.AutoDeleteInterval)\n\n\t// Clean up second sandbox\n\tif err := sandbox2.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t}\n\n\tlog.Println(\"\\n✓ All auto-delete examples completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/build_logs/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n\t\"github.com/google/uuid\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Example 1: Simple log streaming with direct output\n\tlog.Println(\"=== Example 1: Simple Build Log Streaming ===\")\n\tsimpleLogStreaming(ctx, client)\n\n\tlog.Println(\"\\n✓ All build log streaming examples completed successfully!\")\n}\n\n// Example 1: Simple log streaming with direct output\nfunc simpleLogStreaming(ctx context.Context, client *daytona.Client) {\n\tlog.Println(\"Creating sandbox with simple log streaming...\")\n\n\timage := daytona.Base(\"python:3.12-slim\").\n\t\tPipInstall([]string{\"requests\"}, options.WithFindLinks(\"https://pypi.org/simple\")).\n\t\tWorkdir(\"/app\")\n\n\tname := fmt.Sprintf(\"simple-logs-sandbox-%s\", uuid.New().String())\n\tparams := types.ImageParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tName: name,\n\t\t},\n\t\tImage: image,\n\t\tResources: &types.Resources{\n\t\t\tCPU:    1,\n\t\t\tMemory: 1,\n\t\t},\n\t}\n\n\tlogChan := make(chan string, 100)\n\n\tgo func() {\n\t\tfor logLine := range logChan {\n\t\t\tfmt.Printf(\"[BUILD] %s\\n\", logLine)\n\t\t}\n\t}()\n\n\tsandbox, err := client.Create(ctx, params, options.WithTimeout(120*time.Second), options.WithLogChannel(logChan))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Sandbox created: %s (ID: %s)\\n\", sandbox.Name, sandbox.ID)\n\n\t// Clean up\n\tdefer func() {\n\t\tlog.Println(\"Cleaning up sandbox...\")\n\t\tif err := sandbox.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t}\n\t}()\n}\n"
  },
  {
    "path": "examples/go/code_interpreter/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox with Python\n\tlog.Println(\"Creating sandbox...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\\n\", sandbox.Name, sandbox.ID)\n\n\t// Get the code interpreter service for this sandbox\n\tinterpreter := sandbox.CodeInterpreter\n\n\t// Example 1: Simple code execution\n\tlog.Println(\"=== Example 1: Simple Python execution ===\")\n\tchannels, err := interpreter.RunCode(\n\t\tctx,\n\t\t\"print('Hello from Daytona!')\\nprint('Python version:', __import__('sys').version)\",\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to run code: %v\", err)\n\t}\n\n\t// Wait for execution to complete\n\tresult := <-channels.Done\n\tlog.Printf(\"Output:\\n%s\\n\", result.Stdout)\n\tif result.Stderr != \"\" {\n\t\tlog.Printf(\"Stderr:\\n%s\\n\", result.Stderr)\n\t}\n\tif result.Error != nil {\n\t\tlog.Printf(\"Error: %s - %s\\n\", result.Error.Name, result.Error.Value)\n\t}\n\n\t// Example 2: Execution with real-time streaming\n\tlog.Println(\"\\n=== Example 2: Execution with real-time streaming ===\")\n\n\tchannels, err = interpreter.RunCode(\n\t\tctx,\n\t\t`import time\nfor i in range(5):\n    print(f\"Processing step {i+1}...\")\n    time.sleep(0.5)\nprint(\"Done!\")`,\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to run code: %v\", err)\n\t}\n\n\t// Start goroutines to read from channels in real-time\n\tgo func() {\n\t\tfor msg := range channels.Stdout {\n\t\t\tlog.Printf(\"[STDOUT] %s\", msg.Text)\n\t\t}\n\t}()\n\tgo func() {\n\t\tfor msg := range channels.Stderr {\n\t\t\tlog.Printf(\"[STDERR] %s\", msg.Text)\n\t\t}\n\t}()\n\tgo func() {\n\t\tfor execErr := range channels.Errors {\n\t\t\tlog.Printf(\"[ERROR] %s: %s\\n\", execErr.Name, execErr.Value)\n\t\t\tif execErr.Traceback != nil {\n\t\t\t\tlog.Printf(\"Traceback:\\n%s\\n\", *execErr.Traceback)\n\t\t\t}\n\t\t}\n\t}()\n\n\t// Wait for execution to complete\n\t<-channels.Done\n\tlog.Printf(\"Execution completed\\n\")\n\n\t// Example 3: Code execution with environment variables\n\tlog.Println(\"\\n=== Example 3: Using environment variables ===\")\n\tenv := map[string]string{\n\t\t\"MY_VAR\":    \"Hello\",\n\t\t\"MY_NUMBER\": \"42\",\n\t}\n\tchannels, err = interpreter.RunCode(\n\t\tctx,\n\t\t`import os\nprint(f\"MY_VAR: {os.environ.get('MY_VAR')}\")\nprint(f\"MY_NUMBER: {os.environ.get('MY_NUMBER')}\")`,\n\t\toptions.WithEnv(env),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to run code: %v\", err)\n\t}\n\tresult = <-channels.Done\n\tlog.Printf(\"Output:\\n%s\\n\", result.Stdout)\n\n\t// Example 4: Error handling with channels\n\tlog.Println(\"\\n=== Example 4: Error handling with channels ===\")\n\n\tchannels, err = interpreter.RunCode(\n\t\tctx,\n\t\t`# This will cause a runtime error\nx = 1 / 0`,\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to run code: %v\", err)\n\t}\n\n\t// Read from error channel in real-time\n\tgo func() {\n\t\tfor execErr := range channels.Errors {\n\t\t\tlog.Printf(\"Caught error: %s\\n\", execErr.Name)\n\t\t\tlog.Printf(\"Message: %s\\n\", execErr.Value)\n\t\t\tif execErr.Traceback != nil {\n\t\t\t\tlog.Printf(\"Traceback:\\n%s\\n\", *execErr.Traceback)\n\t\t\t}\n\t\t}\n\t}()\n\n\tresult = <-channels.Done\n\tif result.Error != nil {\n\t\tlog.Printf(\"Execution completed with error: %s\\n\", result.Error.Name)\n\t}\n\n\t// Example 5: Using custom timeout\n\tlog.Println(\"\\n=== Example 5: Execution with timeout ===\")\n\n\tchannels, err = interpreter.RunCode(\n\t\tctx,\n\t\t`import time\nprint(\"Starting long operation...\")\ntime.sleep(10)  # This will timeout after 2 seconds\nprint(\"This won't be printed\")`,\n\t\toptions.WithInterpreterTimeout(2*time.Second),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to run code: %v\", err)\n\t}\n\n\t// Read stdout in real-time\n\tgo func() {\n\t\tfor msg := range channels.Stdout {\n\t\t\tlog.Printf(\"[STDOUT] %s\", msg.Text)\n\t\t}\n\t}()\n\n\tresult = <-channels.Done\n\tif result.Error != nil {\n\t\tlog.Printf(\"Expected timeout error: %s - %s\\n\", result.Error.Name, result.Error.Value)\n\t}\n\n\t// Example 6: Working with data and computations\n\tlog.Println(\"\\n=== Example 6: Data processing ===\")\n\tchannels, err = interpreter.RunCode(\n\t\tctx,\n\t\t`import json\n\n# Simulate data processing\ndata = [1, 2, 3, 4, 5]\nsquared = [x**2 for x in data]\nprint(f\"Original: {data}\")\nprint(f\"Squared: {squared}\")\nprint(f\"Sum: {sum(squared)}\")\n\n# Output as JSON\nresult = {\n    \"original\": data,\n    \"squared\": squared,\n    \"sum\": sum(squared)\n}\nprint(json.dumps(result, indent=2))`,\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to run code: %v\", err)\n\t}\n\tresult = <-channels.Done\n\tlog.Printf(\"Output:\\n%s\\n\", result.Stdout)\n\n\t// Example 7: Creating and using a custom context\n\tlog.Println(\"\\n=== Example 7: Using custom interpreter context ===\")\n\tcwd := \"/tmp\"\n\tcontextInfo, err := interpreter.CreateContext(ctx, &cwd)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create context: %v\", err)\n\t}\n\tlog.Printf(\"Created context: %v\\n\", contextInfo[\"id\"])\n\n\t// Use the custom context\n\tcontextID := contextInfo[\"id\"].(string)\n\tchannels, err = interpreter.RunCode(\n\t\tctx,\n\t\t`import os\nprint(f\"Current directory: {os.getcwd()}\")\nprint(f\"Files: {os.listdir('.')[:5]}\")  # Show first 5 files`,\n\t\toptions.WithCustomContext(contextID),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to run code in custom context: %v\", err)\n\t}\n\tresult = <-channels.Done\n\tlog.Printf(\"Output:\\n%s\\n\", result.Stdout)\n\n\t// Delete the sandbox\n\tlog.Println(\"\\n=== Cleaning up ===\")\n\tif err := sandbox.Delete(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to delete sandbox: %v\", err)\n\t}\n\tlog.Println(\"✓ Sandbox deleted\")\n\n\tlog.Println(\"\\n✓ All code interpreter examples completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/computer_use/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox with desktop environment support\n\tlog.Println(\"Creating sandbox with desktop environment...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\", sandbox.Name, sandbox.ID)\n\tdefer func() {\n\t\tlog.Println(\"\\nCleaning up...\")\n\t\tif err := sandbox.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"✓ Sandbox deleted\")\n\t\t}\n\t}()\n\n\t// Start the desktop environment\n\tlog.Println(\"\\nStarting desktop environment...\")\n\tif err := sandbox.ComputerUse.Start(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to start desktop environment: %v\", err)\n\t}\n\tlog.Println(\"✓ Desktop environment started\")\n\n\t// Wait for desktop to be ready\n\ttime.Sleep(3 * time.Second)\n\n\t// Check desktop status\n\tstatus, err := sandbox.ComputerUse.GetStatus(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get desktop status: %v\", err)\n\t}\n\tlog.Printf(\"Desktop status: %v\\n\", status)\n\n\t// Example 1: Display Information\n\tlog.Println(\"\\n=== Display Information ===\")\n\tdisplayInfo, err := sandbox.ComputerUse.Display().GetInfo(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get display info: %v\", err)\n\t}\n\tlog.Printf(\"Display info: %v\\n\", displayInfo)\n\n\t// Example 2: Mouse Operations\n\tlog.Println(\"\\n=== Mouse Operations ===\")\n\n\t// Get current mouse position\n\tmousePos, err := sandbox.ComputerUse.Mouse().GetPosition(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get mouse position: %v\", err)\n\t}\n\tlog.Printf(\"Current mouse position: %v\\n\", mousePos)\n\n\t// Move mouse to a specific position\n\tnewPos, err := sandbox.ComputerUse.Mouse().Move(ctx, 100, 100)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to move mouse: %v\", err)\n\t}\n\tlog.Printf(\"✓ Moved mouse to: %v\\n\", newPos)\n\n\t// Click at current position\n\tclickPos, err := sandbox.ComputerUse.Mouse().Click(ctx, 100, 100, nil, nil)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to click mouse: %v\", err)\n\t}\n\tlog.Printf(\"✓ Clicked at: %v\\n\", clickPos)\n\n\t// Click with specific button (left, right, middle)\n\tleftButton := \"left\"\n\tdoubleClick := true\n\t_, err = sandbox.ComputerUse.Mouse().Click(ctx, 150, 150, &leftButton, &doubleClick)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to double click: %v\", err)\n\t}\n\tlog.Println(\"✓ Double-clicked with left button\")\n\n\t// Drag operation\n\tdragResult, err := sandbox.ComputerUse.Mouse().Drag(ctx, 100, 100, 200, 200, &leftButton)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to drag: %v\", err)\n\t}\n\tlog.Printf(\"✓ Dragged from (100,100) to (200,200), final position: %v\\n\", dragResult)\n\n\t// Scroll operation\n\t// TOFIX: timing out?\n\t// amount := 3\n\t// scrollSuccess, err := sandbox.ComputerUse.Mouse().Scroll(ctx, 300, 300, \"down\", &amount)\n\t// if err != nil {\n\t// \tlog.Fatalf(\"Failed to scroll: %v\", err)\n\t// }\n\t// log.Printf(\"✓ Scrolled down, success: %v\\n\", scrollSuccess)\n\n\t// Example 3: Keyboard Operations\n\tlog.Println(\"\\n=== Keyboard Operations ===\")\n\n\t// Type text\n\tif err := sandbox.ComputerUse.Keyboard().Type(ctx, \"Hello, Daytona!\", nil); err != nil {\n\t\tlog.Fatalf(\"Failed to type text: %v\", err)\n\t}\n\tlog.Println(\"✓ Typed: 'Hello, Daytona!'\")\n\n\t// Type with delay between characters\n\tdelay := 50 // milliseconds\n\tif err := sandbox.ComputerUse.Keyboard().Type(ctx, \"Slow typing...\", &delay); err != nil {\n\t\tlog.Fatalf(\"Failed to type with delay: %v\", err)\n\t}\n\tlog.Println(\"✓ Typed with delay: 'Slow typing...'\")\n\n\t// Press a key with modifiers\n\tmodifiers := []string{\"ctrl\"}\n\tif err := sandbox.ComputerUse.Keyboard().Press(ctx, \"c\", modifiers); err != nil {\n\t\tlog.Fatalf(\"Failed to press key: %v\", err)\n\t}\n\tlog.Println(\"✓ Pressed: Ctrl+C\")\n\n\t// Press multiple modifiers\n\tmodifiers = []string{\"ctrl\", \"shift\"}\n\tif err := sandbox.ComputerUse.Keyboard().Press(ctx, \"t\", modifiers); err != nil {\n\t\tlog.Fatalf(\"Failed to press key combo: %v\", err)\n\t}\n\tlog.Println(\"✓ Pressed: Ctrl+Shift+T\")\n\n\t// Execute hotkey\n\tif err := sandbox.ComputerUse.Keyboard().Hotkey(ctx, \"alt+tab\"); err != nil {\n\t\tlog.Fatalf(\"Failed to press hotkey: %v\", err)\n\t}\n\tlog.Println(\"✓ Pressed hotkey: Alt+Tab\")\n\n\t// Example 4: Screenshots\n\tlog.Println(\"\\n=== Screenshot Operations ===\")\n\n\t// Take full screen screenshot\n\tshowCursor := true\n\tscreenshot, err := sandbox.ComputerUse.Screenshot().TakeFullScreen(ctx, &showCursor)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to take screenshot: %v\", err)\n\t}\n\tlog.Printf(\"✓ Full screen screenshot taken (cursor visible)\\n\")\n\n\t// Save screenshot to file\n\tif screenshot.Image != \"\" {\n\t\tscreenshotData, err := base64.StdEncoding.DecodeString(screenshot.Image)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Warning: Failed to decode screenshot: %v\\n\", err)\n\t\t} else {\n\t\t\tfilename := \"fullscreen_screenshot.png\"\n\t\t\tif err := os.WriteFile(filename, screenshotData, 0644); err != nil {\n\t\t\t\tlog.Printf(\"Warning: Failed to save screenshot: %v\\n\", err)\n\t\t\t} else {\n\t\t\t\tlog.Printf(\"✓ Saved screenshot to: %s\\n\", filename)\n\t\t\t}\n\t\t}\n\t}\n\n\t// TOFIX: needs backend fix for this to work\n\t// // Take regional screenshot\n\t// region := types.ScreenshotRegion{\n\t// \tX:      100,\n\t// \tY:      100,\n\t// \tWidth:  400,\n\t// \tHeight: 300,\n\t// }\n\t// hideCursor := false\n\t// regionScreenshot, err := sandbox.ComputerUse.Screenshot().TakeRegion(ctx, region, &hideCursor)\n\t// if err != nil {\n\t// \tlog.Fatalf(\"Failed to take region screenshot: %v\", err)\n\t// }\n\t// log.Printf(\"✓ Regional screenshot taken (region: %dx%d at %d,%d)\\n\",\n\t// \tregion.Width, region.Height, region.X, region.Y)\n\n\t// // Save region screenshot\n\t// if regionScreenshot.Image != \"\" {\n\t// \tscreenshotData, err := base64.StdEncoding.DecodeString(regionScreenshot.Image)\n\t// \tif err != nil {\n\t// \t\tlog.Printf(\"Warning: Failed to decode region screenshot: %v\\n\", err)\n\t// \t} else {\n\t// \t\tfilename := \"region_screenshot.png\"\n\t// \t\tif err := os.WriteFile(filename, screenshotData, 0644); err != nil {\n\t// \t\t\tlog.Printf(\"Warning: Failed to save region screenshot: %v\\n\", err)\n\t// \t\t} else {\n\t// \t\t\tlog.Printf(\"✓ Saved region screenshot to: %s\\n\", filename)\n\t// \t\t}\n\t// \t}\n\t// }\n\n\t// Example 5: Window Management\n\tlog.Println(\"\\n=== Window Management ===\")\n\twindows, err := sandbox.ComputerUse.Display().GetWindows(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get windows: %v\", err)\n\t}\n\tlog.Printf(\"Open windows: %v\\n\", windows)\n\n\t// Stop the desktop environment\n\tlog.Println(\"\\nStopping desktop environment...\")\n\tif err := sandbox.ComputerUse.Stop(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to stop desktop environment: %v\", err)\n\t}\n\tlog.Println(\"✓ Desktop environment stopped\")\n\tlog.Println(\"\\n✓ All computer use operations completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/exec_sessions/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox\n\tlog.Println(\"Creating sandbox...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\", sandbox.Name, sandbox.ID)\n\tdefer func() {\n\t\tlog.Println(\"\\nCleaning up...\")\n\t\tif err := sandbox.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"✓ Sandbox deleted\")\n\t\t}\n\t}()\n\n\t// Example 1: Create an exec session\n\tlog.Println(\"\\n=== Example 1: Creating and using an exec session ===\")\n\tsessionID := \"exec-session-1\"\n\n\t// Create the session\n\terr = sandbox.Process.CreateSession(ctx, sessionID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create session: %v\", err)\n\t}\n\tlog.Printf(\"✓ Created session: %s\\n\", sessionID)\n\n\t// Get session details\n\tsessionDetails, err := sandbox.Process.GetSession(ctx, sessionID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get session: %v\", err)\n\t}\n\tlog.Printf(\"Session details: %+v\\n\", sessionDetails)\n\n\t// Execute a first command in the session\n\tlog.Println(\"\\nExecuting first command in session...\")\n\tcmd1, err := sandbox.Process.ExecuteSessionCommand(ctx, sessionID, \"export FOO=BAR\", false, false)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to execute session command: %v\", err)\n\t}\n\tlog.Printf(\"✓ Command executed (ID: %s)\\n\", cmd1[\"id\"])\n\n\t// Get the updated session details\n\tsessionDetails, err = sandbox.Process.GetSession(ctx, sessionID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get session: %v\", err)\n\t}\n\tlog.Printf(\"Session updated with command: %v\\n\", sessionDetails)\n\n\t// Execute a second command to verify environment variable\n\tlog.Println(\"\\nExecuting second command in session...\")\n\tcmd2, err := sandbox.Process.ExecuteSessionCommand(ctx, sessionID, \"echo $FOO\", false, false)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to execute second command: %v\", err)\n\t}\n\tif stdout, ok := cmd2[\"stdout\"].(string); ok {\n\t\tlog.Printf(\"FOO=%s\\n\", stdout)\n\t}\n\n\t// Get logs for the command\n\tcmdID, _ := cmd2[\"id\"].(string)\n\tlogs, err := sandbox.Process.GetSessionCommandLogs(ctx, sessionID, cmdID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get command logs: %v\", err)\n\t}\n\tif logContent, ok := logs[\"logs\"].(string); ok {\n\t\tlog.Printf(\"Command logs: %s\\n\", logContent)\n\t}\n\n\t// Delete the session\n\tif err := sandbox.Process.DeleteSession(ctx, sessionID); err != nil {\n\t\tlog.Fatalf(\"Failed to delete session: %v\", err)\n\t}\n\tlog.Println(\"✓ Session deleted\")\n\n\t// Example 2: Session execution with async command\n\tlog.Println(\"\\n=== Example 2: Session with Async Command Execution ===\")\n\tasyncSessionID := \"exec-session-async\"\n\terr = sandbox.Process.CreateSession(ctx, asyncSessionID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create async session: %v\", err)\n\t}\n\n\tlog.Println(\"Executing long running command asynchronously...\")\n\tcmd := \"counter=1; while (( counter <= 3 )); do echo \\\"Count: $counter\\\"; ((counter++)); sleep 1; done\"\n\tcmdResult, err := sandbox.Process.ExecuteSessionCommand(ctx, asyncSessionID, cmd, true, false)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to execute async command: %v\", err)\n\t}\n\n\tcmdIDAsync, _ := cmdResult[\"id\"].(string)\n\tlog.Printf(\"Command started with ID: %s\\n\", cmdIDAsync)\n\n\t// Poll for command completion\n\tlog.Println(\"Waiting for command to complete...\")\n\ttime.Sleep(4 * time.Second)\n\n\t// Get command status\n\tcmdStatus, err := sandbox.Process.GetSessionCommand(ctx, asyncSessionID, cmdIDAsync)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get command status: %v\", err)\n\t}\n\tlog.Printf(\"Command status: %+v\\n\", cmdStatus)\n\n\t// Get logs after completion\n\tlogsAsync, err := sandbox.Process.GetSessionCommandLogs(ctx, asyncSessionID, cmdIDAsync)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get logs: %v\", err)\n\t}\n\tif logContent, ok := logsAsync[\"logs\"].(string); ok {\n\t\tlog.Printf(\"Command logs:\\n%s\\n\", logContent)\n\t}\n\n\t// Delete the async session\n\tif err := sandbox.Process.DeleteSession(ctx, asyncSessionID); err != nil {\n\t\tlog.Fatalf(\"Failed to delete async session: %v\", err)\n\t}\n\tlog.Println(\"✓ Async session deleted\")\n\n\tlog.Println(\"\\n✓ All session examples completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/filesystem/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox with Python\n\tlog.Println(\"Creating sandbox...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\", sandbox.Name, sandbox.ID)\n\tdefer func() {\n\t\tlog.Println(\"\\nCleaning up...\")\n\t\tif err := sandbox.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"✓ Sandbox deleted\")\n\t\t}\n\t}()\n\n\t// File system operations\n\tlog.Println(\"\\nPerforming file operations...\")\n\n\t// Create a test file\n\ttestContent := []byte(\"Hello, Daytona!\\nThis is a test file.\")\n\ttestPath := \"/tmp/test.txt\"\n\n\tif err := sandbox.FileSystem.UploadFile(ctx, testContent, testPath); err != nil {\n\t\tlog.Fatalf(\"Failed to upload file: %v\", err)\n\t}\n\tlog.Printf(\"✓ Uploaded file to %s\\n\", testPath)\n\n\t// Download the file\n\tdownloadedContent, err := sandbox.FileSystem.DownloadFile(ctx, testPath, nil)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to download file: %v\", err)\n\t}\n\tlog.Printf(\"✓ Downloaded file content: %s\\n\", string(downloadedContent))\n\n\t// Create a folder\n\tfolderPath := \"/tmp/test-folder\"\n\tif err := sandbox.FileSystem.CreateFolder(ctx, folderPath); err != nil {\n\t\tlog.Fatalf(\"Failed to create folder: %v\", err)\n\t}\n\tlog.Printf(\"✓ Created folder at %s\\n\", folderPath)\n\n\t// List files in /tmp\n\tfiles, err := sandbox.FileSystem.ListFiles(ctx, \"/tmp\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to list files: %v\", err)\n\t}\n\tlog.Printf(\"\\nFiles in /tmp:\\n\")\n\tfor _, file := range files {\n\t\tlog.Printf(\"  - %s (%d bytes)\\n\", file.Name, file.Size)\n\t}\n\n\tlog.Println(\"\\n✓ All file operations completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/fromimage/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Example 1: Create a sandbox from a simple base image string\n\tlog.Println(\"=== Example 1: Creating sandbox from base image string ===\")\n\tparams1 := types.ImageParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tName: \"simple-image-sandbox\",\n\t\t\tEnvVars: map[string]string{\n\t\t\t\t\"ENV\": \"production\",\n\t\t\t},\n\t\t},\n\t\tImage: \"python:3.12-slim\",\n\t\tResources: &types.Resources{\n\t\t\tCPU:    1,\n\t\t\tMemory: 1,\n\t\t},\n\t}\n\n\tlogChan := make(chan string, 100)\n\tgo func() {\n\t\tfor logLine := range logChan {\n\t\t\tlog.Printf(\"[BUILD] %s\\n\", logLine)\n\t\t}\n\t}()\n\n\tsandbox1, err := client.Create(ctx, params1, options.WithTimeout(120*time.Second), options.WithLogChannel(logChan))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox from image string: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\\n\", sandbox1.Name, sandbox1.ID)\n\n\t// Clean up first sandbox\n\tdefer func() {\n\t\tlog.Println(\"Cleaning up first sandbox...\")\n\t\tif err := sandbox1.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"✓ First sandbox deleted\")\n\t\t}\n\t}()\n\n\t// Example 2: Create a custom image with Python packages\n\tlog.Println(\"=== Example 2: Creating custom image with Python packages ===\")\n\timage2 := daytona.Base(\"python:3.12-slim-bookworm\").\n\t\tPipInstall([]string{\"numpy\", \"pandas\", \"matplotlib\"}, options.WithFindLinks(\"https://pypi.org/simple\")).\n\t\tEnv(\"APP_ENV\", \"development\").\n\t\tWorkdir(\"/app\")\n\n\tparams2 := types.ImageParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tName: \"custom-python-sandbox\",\n\t\t},\n\t\tImage: image2,\n\t\tResources: &types.Resources{\n\t\t\tCPU:    1,\n\t\t\tMemory: 1,\n\t\t},\n\t}\n\n\tlogChan2 := make(chan string, 100)\n\tgo func() {\n\t\tfor logLine := range logChan2 {\n\t\t\tlog.Printf(\"[BUILD] %s\\n\", logLine)\n\t\t}\n\t}()\n\tsandbox2, err := client.Create(ctx, params2, options.WithTimeout(120*time.Second), options.WithLogChannel(logChan2))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox with custom image: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\\n\", sandbox2.Name, sandbox2.ID)\n\n\tdefer func() {\n\t\tlog.Println(\"Cleaning up second sandbox...\")\n\t\tif err := sandbox2.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"✓ Second sandbox deleted\")\n\t\t}\n\t}()\n\n\t// Verify packages are installed\n\tlog.Println(\"Verifying Python packages are installed...\")\n\tresult, err := sandbox2.Process.ExecuteCommand(ctx, \"python3 -c 'import numpy, pandas, matplotlib; print(\\\"All packages imported successfully!\\\")'\")\n\tif err != nil {\n\t\tlog.Printf(\"Failed to verify packages: %v\", err)\n\t} else {\n\t\tlog.Printf(\"✓ %s\\n\\n\", result.Result)\n\t}\n\n\t// Example 3: Create an image with local files (if available)\n\tlog.Println(\"=== Example 3: Creating image with local files ===\")\n\n\t// Create temporary test files for demonstration\n\ttmpDir := \"/tmp/daytona-example\"\n\tif err := os.MkdirAll(tmpDir, 0755); err != nil {\n\t\tlog.Printf(\"Warning: Could not create temp directory: %v\", err)\n\t} else {\n\t\t// Create a sample config file\n\t\tconfigPath := tmpDir + \"/config.json\"\n\t\tconfigContent := []byte(`{\n  \"app_name\": \"Daytona Example\",\n  \"version\": \"1.0.0\",\n  \"features\": {\n    \"logging\": true,\n    \"metrics\": true\n  }\n}`)\n\t\tif err := os.WriteFile(configPath, configContent, 0644); err != nil {\n\t\t\tlog.Printf(\"Warning: Could not create config file: %v\", err)\n\t\t}\n\n\t\t// Create a sample Python script\n\t\tscriptPath := tmpDir + \"/app.py\"\n\t\tscriptContent := []byte(`#!/usr/bin/env python3\nimport json\nimport os\n\ndef main():\n    config_path = '/app/config.json'\n    if os.path.exists(config_path):\n        with open(config_path, 'r') as f:\n            config = json.load(f)\n        print(f\"App: {config['app_name']}\")\n        print(f\"Version: {config['version']}\")\n        print(\"Configuration loaded successfully!\")\n    else:\n        print(\"Config file not found!\")\n\nif __name__ == '__main__':\n    main()\n`)\n\t\tif err := os.WriteFile(scriptPath, scriptContent, 0755); err != nil {\n\t\t\tlog.Printf(\"Warning: Could not create script file: %v\", err)\n\t\t}\n\n\t\t// Create image with local files\n\t\timage3 := daytona.Base(\"python:3.12-slim-bookworm\").\n\t\t\tAddLocalFile(configPath, \"/app/config.json\").\n\t\t\tAddLocalFile(scriptPath, \"/app/app.py\").\n\t\t\tWorkdir(\"/app\").\n\t\t\tRun(\"chmod +x /app/app.py\")\n\n\t\tparams3 := types.ImageParams{\n\t\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\t\tName: \"sandbox-with-files\",\n\t\t\t},\n\t\t\tImage: image3,\n\t\t}\n\n\t\tlogChan3 := make(chan string, 100)\n\t\tgo func() {\n\t\t\tfor logLine := range logChan3 {\n\t\t\t\tlog.Printf(\"[BUILD] %s\\n\", logLine)\n\t\t\t}\n\t\t}()\n\t\tsandbox3, err := client.Create(ctx, params3, options.WithTimeout(120*time.Second), options.WithLogChannel(logChan3))\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Failed to create sandbox with local files: %v\", err)\n\t\t}\n\n\t\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\\n\", sandbox3.Name, sandbox3.ID)\n\n\t\tdefer func() {\n\t\t\tlog.Println(\"Cleaning up third sandbox...\")\n\t\t\tif err := sandbox3.Delete(ctx); err != nil {\n\t\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t\t} else {\n\t\t\t\tlog.Println(\"✓ Third sandbox deleted\")\n\t\t\t}\n\t\t\t// Clean up temp files\n\t\t\tos.RemoveAll(tmpDir)\n\t\t}()\n\n\t\t// Verify files were copied\n\t\tlog.Println(\"Verifying local files were copied...\")\n\t\tresult, err := sandbox3.Process.ExecuteCommand(ctx, \"python3 /app/app.py\")\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Failed to run app: %v\", err)\n\t\t} else {\n\t\t\tlog.Printf(\"✓ App output:\\n%s\\n\\n\", result.Result)\n\t\t}\n\n\t\t// List files in /app\n\t\tfiles, err := sandbox3.FileSystem.ListFiles(ctx, \"/app\")\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Failed to list files: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"Files in /app:\")\n\t\t\tfor _, file := range files {\n\t\t\t\tlog.Printf(\"  - %s (%d bytes)\\n\", file.Name, file.Size)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Example 4: Using DebianSlim helper\n\tlog.Println(\"\\n=== Example 4: Using DebianSlim helper ===\")\n\tpythonVersion := \"3.11\"\n\timage4 := daytona.DebianSlim(&pythonVersion).\n\t\tPipInstall([]string{\"requests\", \"flask\"}, options.WithFindLinks(\"https://pypi.org/simple\")).\n\t\tExpose([]int{5000}).\n\t\tEnv(\"FLASK_APP\", \"app.py\").\n\t\tWorkdir(\"/app\")\n\n\tparams4 := types.ImageParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tName: \"debian-slim-sandbox\",\n\t\t},\n\t\tImage: image4,\n\t}\n\n\tlogChan4 := make(chan string, 100)\n\tgo func() {\n\t\tfor logLine := range logChan4 {\n\t\t\tlog.Printf(\"[BUILD] %s\\n\", logLine)\n\t\t}\n\t}()\n\tsandbox4, err := client.Create(ctx, params4, options.WithTimeout(120*time.Second), options.WithLogChannel(logChan4))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create DebianSlim sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\", sandbox4.Name, sandbox4.ID)\n\n\tdefer func() {\n\t\tlog.Println(\"Cleaning up fourth sandbox...\")\n\t\tif err := sandbox4.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"✓ Fourth sandbox deleted\")\n\t\t}\n\t}()\n\n\t// Verify Python version\n\tresult, err = sandbox4.Process.ExecuteCommand(ctx, \"python3 --version\")\n\tif err != nil {\n\t\tlog.Printf(\"Failed to get Python version: %v\", err)\n\t} else {\n\t\tlog.Printf(\"Python version: %s\\n\", result.Result)\n\t}\n\n\t// Verify packages\n\tresult, err = sandbox4.Process.ExecuteCommand(ctx, \"bash -c \\\"pip list | grep -E '(requests|flask)'\\\"\")\n\tif err != nil {\n\t\tlog.Printf(\"Failed to list packages: %v\", err)\n\t} else {\n\t\tlog.Printf(\"Installed packages:\\n%s\\n\", result.Result)\n\t}\n\n\tlog.Println(\"\\n✓ All image builder examples completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/git_operations/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox\n\tlog.Println(\"Creating sandbox...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\", sandbox.Name, sandbox.ID)\n\tdefer func() {\n\t\tlog.Println(\"\\nCleaning up...\")\n\t\tif err := sandbox.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"✓ Sandbox deleted\")\n\t\t}\n\t}()\n\n\t// Git operations example\n\tlog.Println(\"\\nGit operations example...\")\n\trepoPath := \"/tmp/test-repo\"\n\n\t// Create directory for repo\n\tif err := sandbox.FileSystem.CreateFolder(ctx, repoPath); err != nil {\n\t\tlog.Fatalf(\"Failed to create repo directory: %v\", err)\n\t}\n\n\t// Clone a public repository\n\trepoURL := \"https://github.com/daytonaio/daytona.git\"\n\tlog.Printf(\"Cloning %s...\\n\", repoURL)\n\tif err := sandbox.Git.Clone(ctx, repoURL, repoPath); err != nil {\n\t\tlog.Fatalf(\"Failed to clone repository: %v\", err)\n\t}\n\tlog.Println(\"✓ Repository cloned\")\n\n\t// Example with options:\n\t// err := sandbox.Git.Clone(ctx, repoURL, repoPath,\n\t// \toptions.WithBranch(\"main\"),\n\t// \toptions.WithUsername(\"user\"),\n\t// \toptions.WithPassword(\"pass\"),\n\t// )\n\n\t// Get status\n\tstatus, err := sandbox.Git.Status(ctx, repoPath)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get git status: %v\", err)\n\t}\n\tlog.Printf(\"Current branch: %s\\n\", status.CurrentBranch)\n\n\t// List branches\n\tbranches, err := sandbox.Git.Branches(ctx, repoPath)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to list branches: %v\", err)\n\t}\n\tlog.Printf(\"Branches: %v\\n\", branches)\n\n\tlog.Println(\"\\n✓ All git operations completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/lifecycle/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox\n\tlog.Println(\"Creating sandbox...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"✓ Sandbox created: %s (ID: %s, State: %s)\\n\", sandbox.Name, sandbox.ID, sandbox.State)\n\n\t// Set labels on the sandbox\n\tlog.Println(\"\\nSetting labels on sandbox...\")\n\tlabels := map[string]string{\n\t\t\"public\": \"true\",\n\t\t\"env\":    \"development\",\n\t}\n\tif err := sandbox.SetLabels(ctx, labels); err != nil {\n\t\tlog.Fatalf(\"Failed to set labels: %v\", err)\n\t}\n\tlog.Println(\"✓ Labels set successfully\")\n\n\t// Stop the sandbox\n\tlog.Println(\"\\nStopping sandbox...\")\n\tif err := sandbox.Stop(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to stop sandbox: %v\", err)\n\t}\n\tlog.Println(\"✓ Sandbox stopped\")\n\n\t// Get the sandbox info to verify state\n\tsandbox, err = client.Get(ctx, sandbox.ID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Sandbox state after stop: %s\\n\", sandbox.State)\n\n\t// Start the sandbox\n\tlog.Println(\"\\nStarting sandbox...\")\n\tif err := sandbox.Start(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to start sandbox: %v\", err)\n\t}\n\tlog.Println(\"✓ Sandbox started\")\n\n\t// Get the sandbox info again\n\tlog.Println(\"\\nGetting existing sandbox...\")\n\texistingSandbox, err := client.Get(ctx, sandbox.ID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get sandbox: %v\", err)\n\t}\n\tlog.Printf(\"✓ Got existing sandbox: %s (State: %s)\\n\", existingSandbox.Name, existingSandbox.State)\n\n\t// Execute a command to verify it's running\n\tlog.Println(\"\\nExecuting command on sandbox...\")\n\tresult, err := existingSandbox.Process.ExecuteCommand(ctx, \"echo \\\"Hello World from exec!\\\"\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to execute command: %v\", err)\n\t}\n\n\tif result.ExitCode != 0 {\n\t\tlog.Printf(\"Command failed with exit code %d: %s\\n\", result.ExitCode, result.Result)\n\t} else {\n\t\tlog.Printf(\"Command output: %s\\n\", result.Result)\n\t}\n\n\t// List all sandboxes\n\tlog.Println(\"\\nListing all sandboxes...\")\n\tpage := 1\n\tlimit := 10\n\tsandboxList, err := client.List(ctx, nil, &page, &limit)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to list sandboxes: %v\", err)\n\t}\n\n\tlog.Printf(\"Total sandboxes: %d\\n\", sandboxList.Total)\n\tif len(sandboxList.Items) > 0 {\n\t\tlog.Printf(\"First sandbox -> ID: %s, State: %s\\n\", sandboxList.Items[0].ID, sandboxList.Items[0].State)\n\t}\n\n\t// Delete the sandbox\n\tlog.Println(\"\\nDeleting sandbox...\")\n\tif err := sandbox.Delete(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to delete sandbox: %v\", err)\n\t}\n\tlog.Println(\"✓ Sandbox deleted\")\n\n\tlog.Println(\"\\n✓ All lifecycle operations completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/lsp_usage/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create Daytona client\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox with Python\n\tlog.Println(\"Creating sandbox...\")\n\tsandbox, err := client.Create(ctx, &types.ImageParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t\tImage: \"python:3.11\",\n\t\tResources: &types.Resources{\n\t\t\tCPU:    1,\n\t\t\tMemory: 1,\n\t\t},\n\t}, options.WithTimeout(120*time.Second))\n\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tdefer func() {\n\t\tlog.Println(\"\\nCleaning up sandbox...\")\n\t\t_ = sandbox.Delete(ctx)\n\t}()\n\n\tlog.Printf(\"Sandbox created: %s (state: %s)\\n\", sandbox.Name, sandbox.State)\n\n\t// Create a Python file to work with\n\tlog.Println(\"\\nCreating Python file...\")\n\tpythonCode := `def greet(name):\n    \"\"\"Greet someone by name.\"\"\"\n    return f\"Hello, {name}!\"\n\ndef calculate_sum(a, b):\n    \"\"\"Calculate the sum of two numbers.\"\"\"\n    return a + b\n\n# Main code\nif __name__ == \"__main__\":\n    print(greet(\"World\"))\n    print(calculate_sum(5, 3))\n`\n\n\tworkDir, err := sandbox.GetWorkingDir(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get working directory: %v\", err)\n\t}\n\n\tif err := sandbox.FileSystem.UploadFile(ctx, []byte(pythonCode), workDir+\"/main.py\"); err != nil {\n\t\tlog.Fatalf(\"Failed to create Python file: %v\", err)\n\t}\n\n\t// Create LSP server for Python\n\tlog.Println(\"\\nCreating LSP server for Python...\")\n\tlsp := daytona.NewLspServerService(sandbox.ToolboxClient, types.LspLanguagePython, workDir, client.Otel)\n\n\t// Start the LSP server\n\tlog.Println(\"Starting LSP server...\")\n\tif err := lsp.Start(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to start LSP server: %v\", err)\n\t}\n\tdefer func() {\n\t\tlog.Println(\"Stopping LSP server...\")\n\t\t_ = lsp.Stop(ctx)\n\t}()\n\n\t// Notify LSP about the opened file\n\tlog.Println(\"Notifying LSP about opened file...\")\n\tif err := lsp.DidOpen(ctx, \"main.py\"); err != nil {\n\t\tlog.Fatalf(\"Failed to notify LSP: %v\", err)\n\t}\n\n\t// Get document symbols\n\tlog.Println(\"\\nGetting document symbols...\")\n\tsymbols, err := lsp.DocumentSymbols(ctx, \"main.py\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get document symbols: %v\", err)\n\t}\n\n\tlog.Printf(\"\\nFound %d symbols in main.py\\n\", len(symbols))\n\tif len(symbols) > 0 {\n\t\tlog.Println(\"Document symbols retrieved successfully!\")\n\t}\n\n\t// Get completions at a specific position\n\tlog.Println(\"\\nGetting code completions at line 10, character 10...\")\n\tcompletions, err := lsp.Completions(ctx, \"main.py\", types.Position{Line: 10, Character: 10})\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get completions: %v\", err)\n\t}\n\n\tif completions != nil {\n\t\tlog.Println(\"Code completions retrieved successfully!\")\n\t} else {\n\t\tlog.Println(\"No completions available\")\n\t}\n\n\t// TODO: why is search for sandbox symbols not working?\n\t// Search for symbols in the workspace\n\t// Note: workspace-symbols endpoint may not be available in all environments\n\tlog.Println(\"\\nSearching for 'greet' in workspace...\")\n\tworkspaceSymbols, err := lsp.SandboxSymbols(ctx, \"greet\")\n\tif err != nil {\n\t\tlog.Printf(\"Workspace symbols search not available: %v\\n\", err)\n\t} else {\n\t\tlog.Printf(\"Found %d workspace symbols matching 'greet'\\n\", len(workspaceSymbols))\n\t}\n\n\t// Close the file\n\tlog.Println(\"\\nClosing file...\")\n\tif err := lsp.DidClose(ctx, \"main.py\"); err != nil {\n\t\tlog.Fatalf(\"Failed to close file: %v\", err)\n\t}\n\n\tlog.Println(\"\\n✅ LSP server demo completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/network_settings/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Example 1: Default network settings\n\tlog.Println(\"=== Example 1: Default network settings ===\")\n\tparams1 := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox1, err := client.Create(ctx, params1, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Network Block All: %v\\n\", sandbox1.NetworkBlockAll)\n\tlog.Printf(\"Network Allow List: %s\\n\", getNetworkAllowList(sandbox1))\n\n\t// Clean up\n\tif err := sandbox1.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t}\n\n\t// Example 2: Block all network access\n\tlog.Println(\"\\n=== Example 2: Block all network access ===\")\n\tblockAll := true\n\tparams2 := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage:        types.CodeLanguagePython,\n\t\t\tNetworkBlockAll: blockAll,\n\t\t},\n\t}\n\n\tsandbox2, err := client.Create(ctx, params2, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Network Block All: %v\\n\", sandbox2.NetworkBlockAll)\n\tlog.Printf(\"Network Allow List: %s\\n\", getNetworkAllowList(sandbox2))\n\n\t// Clean up\n\tif err := sandbox2.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t}\n\n\t// Example 3: Explicitly allow list of network addresses\n\tlog.Println(\"\\n=== Example 3: Allow list of network addresses ===\")\n\tallowList := \"192.168.1.0/16,10.0.0.0/24\"\n\tparams3 := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage:         types.CodeLanguagePython,\n\t\t\tNetworkAllowList: &allowList,\n\t\t},\n\t}\n\n\tsandbox3, err := client.Create(ctx, params3, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tlog.Printf(\"Network Block All: %v\\n\", sandbox3.NetworkBlockAll)\n\tlog.Printf(\"Network Allow List: %s\\n\", getNetworkAllowList(sandbox3))\n\n\t// Clean up\n\tif err := sandbox3.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t}\n\n\tlog.Println(\"\\n✓ All network settings examples completed successfully!\")\n}\n\nfunc getNetworkAllowList(sandbox *daytona.Sandbox) string {\n\tif sandbox.NetworkAllowList != nil {\n\t\treturn *sandbox.NetworkAllowList\n\t}\n\treturn \"(not set)\"\n}\n"
  },
  {
    "path": "examples/go/pagination/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Example 1: Paginate through sandboxes with labels\n\tlog.Println(\"=== Example 1: Paginate Sandboxes with Labels ===\")\n\tlabels := map[string]string{\n\t\t\"my-label\": \"my-value\",\n\t}\n\tpage := 2\n\tlimit := 10\n\n\tsandboxList, err := client.List(ctx, labels, &page, &limit)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to list sandboxes: %v\", err)\n\t}\n\n\tlog.Printf(\"Total sandboxes: %d\\n\", sandboxList.Total)\n\tlog.Printf(\"Page: %d, Limit: %d\\n\", page, limit)\n\tfor _, sandbox := range sandboxList.Items {\n\t\tlog.Printf(\"  - %s: %s\\n\", sandbox.ID, sandbox.State)\n\t}\n\n\t// Example 2: Paginate through snapshots\n\tlog.Println(\"\\n=== Example 2: Paginate Snapshots ===\")\n\tsnapshotPage := 2\n\tsnapshotLimit := 10\n\n\tsnapshotList, err := client.Snapshot.List(ctx, &snapshotPage, &snapshotLimit)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to list snapshots: %v\", err)\n\t}\n\n\tlog.Printf(\"Found %d snapshots\\n\", snapshotList.Total)\n\tlog.Printf(\"Page: %d, Limit: %d\\n\", snapshotPage, snapshotLimit)\n\tfor _, snapshot := range snapshotList.Items {\n\t\tlog.Printf(\"  - %s (%s)\\n\", snapshot.Name, snapshot.ImageName)\n\t}\n\n\tlog.Println(\"\\n✓ All pagination examples completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/pty_channel/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create Daytona client\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox\n\tlog.Println(\"Creating sandbox...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\tdefer func() {\n\t\t_ = sandbox.Delete(ctx)\n\t}()\n\n\tlog.Printf(\"✓ Created sandbox: %s\\n\", sandbox.ID)\n\n\t// Create a PTY session\n\thandle, err := sandbox.Process.CreatePty(ctx, \"demo-session\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create PTY: %v\", err)\n\t}\n\tdefer func() {\n\t\t_ = handle.Disconnect()\n\t}()\n\n\t// Wait for connection\n\tif err := handle.WaitForConnection(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to wait for connection: %v\", err)\n\t}\n\n\tlog.Println(\"✓ Connected to PTY\")\n\n\t// Read output from the channel\n\tgo func() {\n\t\tfor data := range handle.DataChan() {\n\t\t\tfmt.Print(string(data))\n\t\t}\n\t}()\n\n\t// Send some commands\n\t_ = handle.SendInput([]byte(\"echo 'Hello from PTY!'\\n\"))\n\t_ = handle.SendInput([]byte(\"pwd\\n\"))\n\t_ = handle.SendInput([]byte(\"ls -la\\n\"))\n\t_ = handle.SendInput([]byte(\"exit\\n\"))\n\n\t// Wait for the PTY to exit\n\tresult, err := handle.Wait(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to wait for PTY: %v\", err)\n\t}\n\n\tlog.Printf(\"\\n✓ PTY exited with code: %d\\n\", *result.ExitCode)\n}\n"
  },
  {
    "path": "examples/go/run_examples.sh",
    "content": "#!/bin/bash\n\n# Exit on error\nset -e\n\n# Color codes for output\nGREEN='\\033[0;32m'\nBLUE='\\033[0;34m'\nRED='\\033[0;31m'\nNC='\\033[0m' # No Color\n\n# Find all example main.go files\nexamples=$(find ./ -name \"main.go\" -type f | sort)\n\necho -e \"${BLUE}Running all examples with DAYTONA_API_KEY${NC}\"\necho \"================================================\"\necho \"\"\n\n# Counter for tracking\ntotal=$(echo \"$examples\" | wc -l | tr -d ' ')\ncurrent=0\n\n# Run each example\nfor example in $examples; do\n    current=$((current + 1))\n    example_dir=$(dirname \"$example\")\n    example_name=$(basename \"$example_dir\")\n\n    echo -e \"${BLUE}[$current/$total] Running example: ${GREEN}$example_name${NC}\"\n    echo \"Command: go run $example\"\n    echo \"---\"\n\n    if go run \"$example\"; then\n        echo -e \"${GREEN}✓ $example_name completed successfully${NC}\"\n    else\n        echo -e \"${RED}✗ $example_name failed${NC}\"\n        # Continue running other examples even if one fails\n        # Remove 'set -e' behavior for individual examples\n    fi\n\n    echo \"\"\ndone\n\necho -e \"${GREEN}All examples completed!${NC}\"\n"
  },
  {
    "path": "examples/go/sandbox/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a sandbox with Python\n\tlog.Println(\"\\nCreating sandbox...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t\tEnvVars: map[string]string{\n\t\t\t\t\"EXAMPLE_VAR\": \"example_value\",\n\t\t\t},\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params, options.WithTimeout(90*time.Second))\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\", sandbox.Name, sandbox.ID)\n\n\t// Get sandbox info\n\thomeDir, err := sandbox.GetUserHomeDir(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get home directory: %v\", err)\n\t}\n\tlog.Printf(\"Home directory: %s\\n\", homeDir)\n\n\tworkDir, err := sandbox.GetWorkingDir(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get working directory: %v\", err)\n\t}\n\tlog.Printf(\"Working directory: %s\\n\", workDir)\n\n\tlog.Println(\"Listing all sandboxes...\")\n\tpage := 1\n\tlimit := 10\n\tallSandboxes, err := client.List(ctx, nil, &page, &limit)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to list sandboxes: %v\", err)\n\t}\n\n\tlog.Printf(\"Total sandboxes: %d\\n\", allSandboxes.Total)\n\tfor _, sb := range allSandboxes.Items {\n\t\tlog.Printf(\"  - %s (State: %s)\\n\", sb.Name, sb.State)\n\t}\n\n\t// Delete the sandbox\n\tlog.Println(\"\\nCleaning up...\")\n\tif err := sandbox.Delete(ctx); err != nil {\n\t\tlog.Fatalf(\"Failed to delete sandbox: %v\", err)\n\t}\n\tlog.Println(\"✓ Sandbox deleted\")\n\n\tlog.Println(\"\\n✓ All sandbox operations completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/snapshots_simple/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Snapshot operations example\n\tpage := 1\n\tlimit := 5\n\tlog.Println(\"Snapshot operations example...\")\n\tsnapshots, err := client.Snapshot.List(ctx, &page, &limit)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to list snapshots: %v\", err)\n\t}\n\n\tlog.Printf(\"Total snapshots: %d\\n\", snapshots.Total)\n\tfor _, snap := range snapshots.Items {\n\t\tlog.Printf(\"  - %s (State: %s)\\n\", snap.Name, snap.State)\n\t}\n\n\tlog.Println(\"\\n✓ Snapshot operations completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/snapshots_withlogstreaming/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n\t\"github.com/google/uuid\"\n)\n\n// This example demonstrates creating a snapshot with log streaming\nfunc exampleSnapshotWithLogs() {\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a snapshot from a simple base image with log streaming\n\tlog.Println(\"Creating snapshot from base image with log streaming...\")\n\tlog.Println(\"=\" + string(make([]byte, 60)) + \"=\")\n\n\tsnapshotName := fmt.Sprintf(\"example-snapshot-with-logs-%s\", uuid.New().String())\n\n\t// Define the snapshot creation parameters\n\tparams := &types.CreateSnapshotParams{\n\t\tName:  snapshotName,\n\t\tImage: \"ubuntu:22.04\",\n\t\tResources: &types.Resources{\n\t\t\tCPU:    1,\n\t\t\tMemory: 1,\n\t\t},\n\t}\n\n\t// Create the snapshot and get the log channel\n\tsnapshot, logChan, err := client.Snapshot.Create(ctx, params)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create snapshot: %v\", err)\n\t}\n\n\t// Read logs from the channel until it's closed\n\tfor logLine := range logChan {\n\t\tfmt.Println(logLine)\n\t}\n\n\tlog.Printf(\"\\n✓ Snapshot created successfully!\")\n\tlog.Printf(\"  Name: %s\\n\", snapshot.Name)\n\tlog.Printf(\"  ID: %s\\n\", snapshot.ID)\n\tlog.Printf(\"  State: %s\\n\", snapshot.State)\n\tlog.Printf(\"  Image: %s\\n\", snapshot.ImageName)\n\n\t// Optional: Clean up - delete the snapshot\n\tlog.Println(\"\\nCleaning up - deleting snapshot...\")\n\tif err := client.Snapshot.Delete(ctx, snapshot); err != nil {\n\t\tlog.Printf(\"Warning: Failed to delete snapshot: %v\", err)\n\t} else {\n\t\tlog.Println(\"✓ Snapshot deleted successfully!\")\n\t}\n}\n\n// This example demonstrates creating a snapshot with a custom Dockerfile\nfunc exampleSnapshotWithCustomImage() {\n\t// Create a new Daytona client\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\tlog.Println(\"\\n\\nCreating snapshot with custom image (Python + packages)...\")\n\tlog.Println(\"=\" + string(make([]byte, 60)) + \"=\")\n\n\t// Build a custom image with Python and some packages\n\timage := daytona.Base(\"python:3.11-slim\").\n\t\tRun(\"apt-get update && apt-get install -y git curl\").\n\t\tRun(\"pip install --no-cache-dir requests numpy pandas\")\n\n\tname := fmt.Sprintf(\"example-python-snapshot-%s\", uuid.New().String())\n\tparams := &types.CreateSnapshotParams{\n\t\tName:  name,\n\t\tImage: image,\n\t\tResources: &types.Resources{\n\t\t\tCPU:    1,\n\t\t\tMemory: 1,\n\t\t},\n\t}\n\n\t// Create the snapshot and get the log channel\n\tsnapshot, logChan, err := client.Snapshot.Create(ctx, params)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create snapshot: %v\", err)\n\t}\n\n\t// Read logs from the channel until it's closed\n\tfor logLine := range logChan {\n\t\tfmt.Println(\"This LOG is from the channel: \" + logLine)\n\t}\n\n\tlog.Printf(\"\\n✓ Custom snapshot created successfully!\")\n\tlog.Printf(\"  Name: %s\\n\", snapshot.Name)\n\tlog.Printf(\"  ID: %s\\n\", snapshot.ID)\n\tlog.Printf(\"  State: %s\\n\", snapshot.State)\n\n\t// Optional: Clean up\n\tlog.Println(\"\\nCleaning up - deleting snapshot...\")\n\tif err := client.Snapshot.Delete(ctx, snapshot); err != nil {\n\t\tlog.Printf(\"Warning: Failed to delete snapshot: %v\", err)\n\t} else {\n\t\tlog.Println(\"✓ Snapshot deleted successfully!\")\n\t}\n}\n\nfunc main() {\n\tlog.Println(\"Snapshot with Log Streaming Examples\")\n\tlog.Println(\"=====================================\")\n\n\texampleSnapshotWithLogs()\n\n\texampleSnapshotWithCustomImage()\n\n\tlog.Println(\"\\n\\n✓ All examples completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/stream_logs/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\tlog.Println(\"Creating sandbox...\")\n\tparams := types.SnapshotParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t},\n\t}\n\n\tsandbox, err := client.Create(ctx, params)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create sandbox: %v\", err)\n\t}\n\n\tlog.Printf(\"Created sandbox: %s (ID: %s)\\n\", sandbox.Name, sandbox.ID)\n\tdefer func() {\n\t\tlog.Println(\"\\nCleaning up...\")\n\t\tif err := sandbox.Delete(ctx); err != nil {\n\t\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t\t} else {\n\t\t\tlog.Println(\"Sandbox deleted\")\n\t\t}\n\t}()\n\n\t// Create a session for running async commands\n\tsessionID := \"stream-logs-session\"\n\terr = sandbox.Process.CreateSession(ctx, sessionID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create session: %v\", err)\n\t}\n\tlog.Printf(\"Created session: %s\\n\", sessionID)\n\tdefer func() {\n\t\tif err := sandbox.Process.DeleteSession(ctx, sessionID); err != nil {\n\t\t\tlog.Printf(\"Failed to delete session: %v\", err)\n\t\t}\n\t}()\n\n\t// Execute a command that produces output over time (async)\n\tlog.Println(\"\\n=== Streaming Logs Example ===\")\n\tlog.Println(\"Starting a long-running command asynchronously...\")\n\n\t// This command outputs to both stdout and stderr over 5 seconds\n\tcmd := `for i in 1 2 3 4 5; do\n\t\techo \"stdout: iteration $i\"\n\t\techo \"stderr: error message $i\" >&2\n\t\tsleep 1\n\tdone\n\techo \"stdout: done!\"`\n\n\tcmdResult, err := sandbox.Process.ExecuteSessionCommand(ctx, sessionID, cmd, true, false)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to execute async command: %v\", err)\n\t}\n\n\tcmdID, _ := cmdResult[\"id\"].(string)\n\tlog.Printf(\"Command started with ID: %s\\n\", cmdID)\n\n\t// Stream the logs as they come in\n\tlog.Println(\"\\nStreaming logs (stdout in green, stderr in red):\")\n\tlog.Println(\"---\")\n\n\t// Create buffered channels for stdout and stderr\n\tstdout := make(chan string, 100)\n\tstderr := make(chan string, 100)\n\n\t// Start streaming in a goroutine\n\tstreamErr := make(chan error, 1)\n\tgo func() {\n\t\terr := sandbox.Process.GetSessionCommandLogsStream(ctx, sessionID, cmdID, stdout, stderr)\n\t\tstreamErr <- err\n\t}()\n\n\t// Read from channels until both are closed\n\t// Buffer partial lines to avoid jumbled output when stdout/stderr interleave\n\tstdoutOpen, stderrOpen := true, true\n\tvar stdoutBuf, stderrBuf string\n\n\tprintLines := func(buf *string, prefix, color string, w *os.File) {\n\t\tfor {\n\t\t\tidx := strings.Index(*buf, \"\\n\")\n\t\t\tif idx == -1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tline := (*buf)[:idx+1]\n\t\t\t*buf = (*buf)[idx+1:]\n\t\t\tfmt.Fprintf(w, \"%s[%s] %s\\033[0m\", color, prefix, line)\n\t\t}\n\t}\n\n\tfor stdoutOpen || stderrOpen {\n\t\tselect {\n\t\tcase chunk, ok := <-stdout:\n\t\t\tif !ok {\n\t\t\t\tstdoutOpen = false\n\t\t\t\tif stdoutBuf != \"\" {\n\t\t\t\t\tfmt.Fprintf(os.Stdout, \"\\033[32m[STDOUT] %s\\033[0m\\n\", stdoutBuf)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstdoutBuf += chunk\n\t\t\t\tprintLines(&stdoutBuf, \"STDOUT\", \"\\033[32m\", os.Stdout)\n\t\t\t}\n\t\tcase chunk, ok := <-stderr:\n\t\t\tif !ok {\n\t\t\t\tstderrOpen = false\n\t\t\t\tif stderrBuf != \"\" {\n\t\t\t\t\tfmt.Fprintf(os.Stderr, \"\\033[31m[STDERR] %s\\033[0m\\n\", stderrBuf)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstderrBuf += chunk\n\t\t\t\tprintLines(&stderrBuf, \"STDERR\", \"\\033[31m\", os.Stderr)\n\t\t\t}\n\t\t}\n\t}\n\n\tlog.Println(\"---\")\n\n\t// Check for streaming errors\n\tif err := <-streamErr; err != nil {\n\t\tlog.Printf(\"Stream ended with error: %v\", err)\n\t} else {\n\t\tlog.Println(\"Stream completed successfully!\")\n\t}\n\n\t// Verify the command completed\n\tcmdStatus, err := sandbox.Process.GetSessionCommand(ctx, sessionID, cmdID)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to get command status: %v\", err)\n\t}\n\tif exitCode, ok := cmdStatus[\"exitCode\"]; ok {\n\t\tlog.Printf(\"Command exit code: %v\\n\", exitCode)\n\t}\n\n\tlog.Println(\"\\nAll streaming logs examples completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/volumes/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n)\n\nfunc main() {\n\t// Create a new Daytona client using environment variables\n\t// Set DAYTONA_API_KEY before running\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Volume operations example\n\tlog.Println(\"Volume operations example...\")\n\tvolumes, err := client.Volume.List(ctx)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to list volumes: %v\", err)\n\t}\n\n\tlog.Printf(\"Total volumes: %d\\n\", len(volumes))\n\tfor _, vol := range volumes {\n\t\tlog.Printf(\"  - %s (ID: %s)\\n\", vol.Name, vol.ID)\n\t}\n\n\tlog.Println(\"\\n✓ Volume operations completed successfully!\")\n}\n"
  },
  {
    "path": "examples/go/volumes_with_sandbox/main.go",
    "content": "// Copyright 2025 Daytona Platforms Inc.\n// SPDX-License-Identifier: Apache-2.0\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"time\"\n\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/daytona\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/options\"\n\t\"github.com/daytonaio/daytona/libs/sdk-go/pkg/types\"\n)\n\nfunc main() {\n\t// Create Daytona client (uses DAYTONA_API_KEY from environment)\n\tclient, err := daytona.NewClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create client: %v\", err)\n\t}\n\n\tctx := context.Background()\n\n\t// Create a volume with a unique name\n\tvolumeName := fmt.Sprintf(\"data-volume-%d\", time.Now().Unix())\n\tlog.Printf(\"Creating volume: %s\\n\", volumeName)\n\tvolume, err := client.Volume.Create(ctx, volumeName)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to create volume: %v\", err)\n\t}\n\tlog.Printf(\"✓ Created volume: %s (ID: %s, State: %s)\\n\", volume.Name, volume.ID, volume.State)\n\n\t// Wait for volume to be ready\n\tlog.Println(\"Waiting for volume to become ready...\")\n\tvolume, err = client.Volume.WaitForReady(ctx, volume, 60*time.Second)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed waiting for volume: %v\", err)\n\t}\n\tlog.Printf(\"✓ Volume is now ready (State: %s)\\n\", volume.State)\n\n\t// Create a sandbox with the volume mounted\n\tlog.Printf(\"Creating sandbox with volume ID: %s mounted at /data\\n\", volume.ID)\n\tparams := types.ImageParams{\n\t\tSandboxBaseParams: types.SandboxBaseParams{\n\t\t\tName:     \"sandbox-with-volume\",\n\t\t\tLanguage: types.CodeLanguagePython,\n\t\t\tVolumes: []types.VolumeMount{\n\t\t\t\t{\n\t\t\t\t\tVolumeID:  volume.ID,\n\t\t\t\t\tMountPath: \"/data\",\n\t\t\t\t\tSubpath:   nil, // Mount entire volume\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tImage: \"python:3.12-slim\",\n\t}\n\n\tlogChan := make(chan string, 100)\n\tgo func() {\n\t\tfor logLine := range logChan {\n\t\t\tlog.Printf(\"[BUILD] %s\\n\", logLine)\n\t\t}\n\t}()\n\tsandbox, err := client.Create(ctx, params, options.WithLogChannel(logChan))\n\tif err != nil {\n\t\tlog.Printf(\"Failed to create sandbox with volume: %v\", err)\n\t\t// Clean up volume and exit\n\t\t_ = client.Volume.Delete(ctx, volume)\n\t\tlog.Fatalf(\"Exiting due to error\")\n\t}\n\n\tlog.Printf(\"✓ Created sandbox: %s (ID: %s)\\n\", sandbox.Name, sandbox.ID)\n\n\t// Verify volume is mounted by listing the directory\n\tresult, err := sandbox.Process.ExecuteCommand(ctx, \"ls -la /data\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to execute command: %v\", err)\n\t}\n\tlog.Printf(\"Volume mounted at /data:\\n%s\\n\", result.Result)\n\n\t// Write a file to the volume\n\t_, err = sandbox.Process.ExecuteCommand(ctx, \"echo 'Hello from volume!' > /data/test.txt\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to write to volume: %v\", err)\n\t}\n\tlog.Printf(\"✓ Wrote file to volume\\n\")\n\n\t// Read the file back\n\tresult, err = sandbox.Process.ExecuteCommand(ctx, \"cat /data/test.txt\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to read from volume: %v\", err)\n\t}\n\tlog.Printf(\"File content: %s\\n\", result.Result)\n\n\t// Clean up\n\tlog.Println(\"Cleaning up...\")\n\tif err := sandbox.Delete(ctx); err != nil {\n\t\tlog.Printf(\"Failed to delete sandbox: %v\", err)\n\t} else {\n\t\tlog.Println(\"✓ Deleted sandbox\")\n\t}\n\n\t// Delete volume (should still be in active state)\n\tif err := client.Volume.Delete(ctx, volume); err != nil {\n\t\tlog.Printf(\"Failed to delete volume: %v\", err)\n\t} else {\n\t\tlog.Println(\"✓ Deleted volume\")\n\t}\n\n\tlog.Println(\"✓ Done\")\n}\n"
  },
  {
    "path": "examples/jupyter/daytona.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Daytona SDK Examples\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Load the Daytona SDK and create a sandbox\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import base64\\n\",\n    \"import io\\n\",\n    \"import os\\n\",\n    \"from pprint import pp\\n\",\n    \"from typing import cast\\n\",\n    \"\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"import numpy as np\\n\",\n    \"from numpy.typing import NDArray\\n\",\n    \"\\n\",\n    \"from daytona import (\\n\",\n    \"    BarChart,\\n\",\n    \"    CompositeChart,\\n\",\n    \"    CreateSandboxFromImageParams,\\n\",\n    \"    Daytona,\\n\",\n    \"    Image,\\n\",\n    \"    LineChart,\\n\",\n    \"    LspCompletionPosition,\\n\",\n    \"    SessionExecuteRequest,\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"daytona = Daytona()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"sandbox = daytona.create(\\n\",\n    \"    CreateSandboxFromImageParams(\\n\",\n    \"        image=(\\n\",\n    \"            Image.base(\\\"python:3.13.4-bookworm\\\")\\n\",\n    \"            .run_commands(\\n\",\n    \"                \\\"apt-get update && apt-get install -y nodejs npm\\\",\\n\",\n    \"                \\\"npm install -g typescript typescript-language-server\\\",\\n\",\n    \"            )\\n\",\n    \"            .pip_install(\\\"matplotlib\\\")\\n\",\n    \"        ),\\n\",\n    \"    ),\\n\",\n    \"    timeout=200,\\n\",\n    \"    on_snapshot_create_logs=print,\\n\",\n    \")\\n\",\n    \"\\n\",\n    \"print(sandbox.id)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code and Command Execution\\n\",\n    \"\\n\",\n    \"### Code Execution\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"response = sandbox.process.code_run('print(\\\"Hello World!\\\")')\\n\",\n    \"if response.exit_code != 0:\\n\",\n    \"    print(f\\\"Error: {response.exit_code} {response.result}\\\")\\n\",\n    \"else:\\n\",\n    \"    print(response.result)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Command Execution\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"response = sandbox.process.exec('echo \\\"Hello World from exec!\\\"', timeout=10)\\n\",\n    \"if response.exit_code != 0:\\n\",\n    \"    print(f\\\"Error: {response.exit_code} {response.result}\\\")\\n\",\n    \"else:\\n\",\n    \"    print(response.result)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Exec Sessions\\n\",\n    \"\\n\",\n    \"Sessions can be used to execute multiple commands in a single shell that preserves context between commands.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"exec_session_id = \\\"exec-session-1\\\"\\n\",\n    \"sandbox.process.create_session(exec_session_id)\\n\",\n    \"session = sandbox.process.get_session(exec_session_id)\\n\",\n    \"pp(session)\\n\",\n    \"print()\\n\",\n    \"\\n\",\n    \"# Execute the first command in the session\\n\",\n    \"execCommand1 = sandbox.process.execute_session_command(exec_session_id, SessionExecuteRequest(command=\\\"export FOO=BAR\\\"))\\n\",\n    \"if execCommand1.exit_code != 0:\\n\",\n    \"    print(f\\\"Error: {execCommand1.exit_code} {execCommand1.output}\\\")\\n\",\n    \"\\n\",\n    \"# Get the command details\\n\",\n    \"session_command = sandbox.process.get_session_command(exec_session_id, execCommand1.cmd_id)\\n\",\n    \"pp(session_command)\\n\",\n    \"print()\\n\",\n    \"\\n\",\n    \"# Execute a second command in the session and see that the environment variable is set\\n\",\n    \"execCommand2 = sandbox.process.execute_session_command(exec_session_id, SessionExecuteRequest(command=\\\"echo $FOO\\\"))\\n\",\n    \"if execCommand2.exit_code != 0:\\n\",\n    \"    print(f\\\"Error: {execCommand2.exit_code} {execCommand2.output}\\\")\\n\",\n    \"else:\\n\",\n    \"    print(f\\\"Output: {execCommand2.output}\\\\n\\\")\\n\",\n    \"\\n\",\n    \"logs = sandbox.process.get_session_command_logs(exec_session_id, execCommand2.cmd_id)\\n\",\n    \"print(f\\\"Logs stdout: {logs.stdout}\\\")\\n\",\n    \"print(f\\\"Logs stderr: {logs.stderr}\\\")\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Charts\\n\",\n    \"\\n\",\n    \"Daytona automatically detects any plot creations while running remote code and saves them in `response.artifacts.charts`. This feature is available only for **Matplotlib** plots.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"code = \\\"\\\"\\\"\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"\\n\",\n    \"# Data\\n\",\n    \"categories = ['A', 'B', 'C', 'D']\\n\",\n    \"values = [20, 35, 30, 10]\\n\",\n    \"\\n\",\n    \"# Plot\\n\",\n    \"plt.figure(figsize=(8, 5))\\n\",\n    \"plt.bar(categories, values, color='skyblue', edgecolor='black')\\n\",\n    \"\\n\",\n    \"# Labels and title\\n\",\n    \"plt.xlabel('Category')\\n\",\n    \"plt.ylabel('Value')\\n\",\n    \"plt.title('Bar Chart Example')\\n\",\n    \"\\n\",\n    \"plt.grid(axis='y', linestyle='--', alpha=0.7)\\n\",\n    \"plt.tight_layout()\\n\",\n    \"plt.show()\\n\",\n    \"\\\"\\\"\\\"\\n\",\n    \"\\n\",\n    \"response = sandbox.process.code_run(code)\\n\",\n    \"if response.artifacts and response.artifacts.charts:\\n\",\n    \"    chart = response.artifacts.charts[0]\\n\",\n    \"\\n\",\n    \"    if chart.png:\\n\",\n    \"        img_data = base64.b64decode(chart.png)\\n\",\n    \"        img = cast(NDArray[np.uint8], plt.imread(io.BytesIO(img_data)))\\n\",\n    \"        _ = plt.imshow(img)\\n\",\n    \"        _ = plt.axis(\\\"off\\\")\\n\",\n    \"        plt.show()\\n\",\n    \"\\n\",\n    \"    print(f\\\"type: {chart.type}\\\")\\n\",\n    \"    print(f\\\"title: {chart.title}\\\")\\n\",\n    \"    if isinstance(chart, BarChart):\\n\",\n    \"        print(f\\\"x_label: {chart.x_label}\\\")\\n\",\n    \"        print(f\\\"y_label: {chart.y_label}\\\")\\n\",\n    \"        print(\\\"elements:\\\")\\n\",\n    \"        for element in chart.elements:\\n\",\n    \"            print(f\\\"\\\\n\\\\tlabel: {element.label}\\\")\\n\",\n    \"            print(f\\\"\\\\tgroup: {element.group}\\\")\\n\",\n    \"            print(f\\\"\\\\tvalue: {element.value}\\\")\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Composite Charts\\n\",\n    \"All subplots are included as individual `Chart` instances within the `elements` list of a parent `Chart` of type `CompositeChart`.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"code = \\\"\\\"\\\"\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"import numpy as np\\n\",\n    \"\\n\",\n    \"# Data for bar chart\\n\",\n    \"categories = ['A', 'B', 'C', 'D']\\n\",\n    \"bar_values = [20, 35, 30, 10]\\n\",\n    \"\\n\",\n    \"# Data for line chart\\n\",\n    \"x = np.linspace(0, 10, 100)\\n\",\n    \"y1 = np.sin(x)\\n\",\n    \"y2 = np.cos(x)\\n\",\n    \"y3 = np.tan(x) * 0.1  # scaled to fit nicely\\n\",\n    \"\\n\",\n    \"# Create a figure with 2 subplots\\n\",\n    \"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))\\n\",\n    \"\\n\",\n    \"# --- Bar Chart (subplot 1) ---\\n\",\n    \"ax1.bar(categories, bar_values, color='skyblue', edgecolor='black')\\n\",\n    \"ax1.set_title('Bar Chart')\\n\",\n    \"ax1.set_xlabel('Category')\\n\",\n    \"ax1.set_ylabel('Value')\\n\",\n    \"ax1.grid(axis='y', linestyle='--', alpha=0.7)\\n\",\n    \"\\n\",\n    \"# --- Line Chart with 3 lines (subplot 2) ---\\n\",\n    \"ax2.plot(x, y1, label='sin(x)', linewidth=2)\\n\",\n    \"ax2.plot(x, y2, label='cos(x)', linewidth=2)\\n\",\n    \"ax2.plot(x, y3, label='0.1 * tan(x)', linewidth=2)\\n\",\n    \"ax2.set_title('Line Chart with 3 Lines')\\n\",\n    \"ax2.set_xlabel('X-axis')\\n\",\n    \"ax2.set_ylabel('Y-axis')\\n\",\n    \"ax2.grid(True, linestyle='--', alpha=0.7)\\n\",\n    \"ax2.legend()\\n\",\n    \"\\n\",\n    \"# Add main title\\n\",\n    \"fig.suptitle('Composite Chart Example', fontsize=16)\\n\",\n    \"\\n\",\n    \"# Adjust layout and show\\n\",\n    \"plt.tight_layout()\\n\",\n    \"plt.show()\\n\",\n    \"\\\"\\\"\\\"\\n\",\n    \"\\n\",\n    \"response = sandbox.process.code_run(code)\\n\",\n    \"if response.artifacts and response.artifacts.charts:\\n\",\n    \"    chart = response.artifacts.charts[0]\\n\",\n    \"\\n\",\n    \"    if chart.png:\\n\",\n    \"        img_data = base64.b64decode(chart.png)\\n\",\n    \"        img = cast(NDArray[np.uint8], plt.imread(io.BytesIO(img_data)))\\n\",\n    \"        _ = plt.imshow(img)\\n\",\n    \"        _ = plt.axis(\\\"off\\\")\\n\",\n    \"        plt.show()\\n\",\n    \"\\n\",\n    \"print(f\\\"type: {chart.type}\\\")\\n\",\n    \"print(f\\\"title: {chart.title}\\\")\\n\",\n    \"if isinstance(chart, CompositeChart):\\n\",\n    \"    for subplot in chart.elements:\\n\",\n    \"        print(f\\\"\\\\n\\\\ttype: {subplot.type}\\\")\\n\",\n    \"        print(f\\\"\\\\ttitle: {subplot.title}\\\")\\n\",\n    \"        if isinstance(subplot, BarChart):\\n\",\n    \"            print(f\\\"\\\\tx_label: {subplot.x_label}\\\")\\n\",\n    \"            print(f\\\"\\\\ty_label: {subplot.y_label}\\\")\\n\",\n    \"            print(\\\"\\\\telements:\\\")\\n\",\n    \"            for element in subplot.elements:\\n\",\n    \"                print(f\\\"\\\\n\\\\t\\\\tlabel: {element.label}\\\")\\n\",\n    \"                print(f\\\"\\\\t\\\\tgroup: {element.group}\\\")\\n\",\n    \"                print(f\\\"\\\\t\\\\tvalue: {element.value}\\\")\\n\",\n    \"        elif isinstance(subplot, LineChart):\\n\",\n    \"            print(f\\\"\\\\tx_label: {subplot.x_label}\\\")\\n\",\n    \"            print(f\\\"\\\\ty_label: {subplot.y_label}\\\")\\n\",\n    \"            print(f\\\"\\\\tx_ticks: {subplot.x_ticks}\\\")\\n\",\n    \"            print(f\\\"\\\\tx_tick_labels: {subplot.x_tick_labels}\\\")\\n\",\n    \"            print(f\\\"\\\\tx_scale: {subplot.x_scale}\\\")\\n\",\n    \"            print(f\\\"\\\\ty_ticks: {subplot.y_ticks}\\\")\\n\",\n    \"            print(f\\\"\\\\ty_tick_labels: {subplot.y_tick_labels}\\\")\\n\",\n    \"            print(f\\\"\\\\ty_scale: {subplot.y_scale}\\\")\\n\",\n    \"            print(\\\"\\\\telements:\\\")\\n\",\n    \"            for element in subplot.elements:\\n\",\n    \"                print(f\\\"\\\\n\\\\t\\\\tlabel: {element.label}\\\")\\n\",\n    \"                print(f\\\"\\\\t\\\\tpoints: {element.points}\\\")\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## File System\\n\",\n    \"\\n\",\n    \"- List Files\\n\",\n    \"- Create Folder\\n\",\n    \"- Upload File\\n\",\n    \"- Download File\\n\",\n    \"- Replace in Files\\n\",\n    \"- Search Files\\n\",\n    \"- Get File Info\\n\",\n    \"- Move Files\\n\",\n    \"- Delete File\\n\",\n    \"- Set File Permissions\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# List files in the sandbox\\n\",\n    \"files = sandbox.fs.list_files(\\\".\\\")\\n\",\n    \"pp(files)\\n\",\n    \"\\n\",\n    \"# Create a new directory in the sandbox\\n\",\n    \"new_dir = \\\"new-dir\\\"\\n\",\n    \"sandbox.fs.create_folder(new_dir, \\\"755\\\")\\n\",\n    \"\\n\",\n    \"file_path = os.path.join(new_dir, \\\"data.txt\\\")\\n\",\n    \"\\n\",\n    \"# Add a new file to the sandbox\\n\",\n    \"file_content = b\\\"Hello, World!\\\"\\n\",\n    \"sandbox.fs.upload_file(file_content, file_path)\\n\",\n    \"\\n\",\n    \"# Search for the file we just added\\n\",\n    \"matches = sandbox.fs.find_files(\\\".\\\", \\\"World!\\\")\\n\",\n    \"pp(matches)\\n\",\n    \"\\n\",\n    \"# Replace the contents of the file\\n\",\n    \"_ = sandbox.fs.replace_in_files([file_path], \\\"Hello, World!\\\", \\\"Goodbye, World!\\\")\\n\",\n    \"\\n\",\n    \"# Read the file\\n\",\n    \"downloaded_file = sandbox.fs.download_file(file_path)\\n\",\n    \"print(\\\"File content:\\\", downloaded_file.decode(\\\"utf-8\\\"))\\n\",\n    \"\\n\",\n    \"# Change the file permissions\\n\",\n    \"sandbox.fs.set_file_permissions(file_path, mode=\\\"777\\\")\\n\",\n    \"\\n\",\n    \"# Get file info\\n\",\n    \"file_info = sandbox.fs.get_file_info(file_path)\\n\",\n    \"pp(file_info)  # Should show the new permissions\\n\",\n    \"\\n\",\n    \"# Move the file to the new location\\n\",\n    \"new_file_path = \\\"moved-data.txt\\\"\\n\",\n    \"sandbox.fs.move_files(file_path, new_file_path)\\n\",\n    \"\\n\",\n    \"# Find the file in the new location\\n\",\n    \"search_results = sandbox.fs.search_files(\\\".\\\", \\\"moved-data.txt\\\")\\n\",\n    \"pp(search_results)\\n\",\n    \"\\n\",\n    \"# Delete the file\\n\",\n    \"sandbox.fs.delete_file(new_file_path)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Git\\n\",\n    \"\\n\",\n    \"- Clone Repository\\n\",\n    \"- Pull Repository\\n\",\n    \"- List Branches\\n\",\n    \"- Delete a Branch\\n\",\n    \"- Create a Branch\\n\",\n    \"- Checkout a Branch\\n\",\n    \"- Git Log\\n\",\n    \"- Git Status\\n\",\n    \"- Git Add\\n\",\n    \"- Git Commit\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"project_dir = \\\"learn-typescript\\\"\\n\",\n    \"\\n\",\n    \"# Clone the repository\\n\",\n    \"sandbox.git.clone(\\\"https://github.com/panaverse/learn-typescript\\\", project_dir, \\\"master\\\")\\n\",\n    \"\\n\",\n    \"sandbox.git.pull(project_dir)\\n\",\n    \"\\n\",\n    \"branches = sandbox.git.branches(project_dir)\\n\",\n    \"pp(branches)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## LSP\\n\",\n    \"\\n\",\n    \"- Start Language Server\\n\",\n    \"- Notify Language Server of Document Change\\n\",\n    \"- Get Completions\\n\",\n    \"- Document Symbols\\n\",\n    \"- Workspace Symbols\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"project_dir = \\\"learn-typescript\\\"\\n\",\n    \"\\n\",\n    \"# Search for the file we want to work on\\n\",\n    \"matches = sandbox.fs.find_files(project_dir, \\\"var obj1 = new Base();\\\")\\n\",\n    \"print(\\\"Matches:\\\", matches)\\n\",\n    \"\\n\",\n    \"# Start the language server\\n\",\n    \"lsp = sandbox.create_lsp_server(\\\"typescript\\\", project_dir)\\n\",\n    \"lsp.start()\\n\",\n    \"\\n\",\n    \"# Notify the language server of the document we want to work on\\n\",\n    \"lsp.did_open(matches[0].file)\\n\",\n    \"\\n\",\n    \"# Get symbols in the document\\n\",\n    \"symbols = lsp.document_symbols(matches[0].file)\\n\",\n    \"print(\\\"Symbols:\\\", symbols)\\n\",\n    \"\\n\",\n    \"# Fix the error in the document\\n\",\n    \"_ = sandbox.fs.replace_in_files([matches[0].file], \\\"var obj1 = new Base();\\\", \\\"var obj1 = new E();\\\")\\n\",\n    \"\\n\",\n    \"# Notify the language server of the document change\\n\",\n    \"lsp.did_close(matches[0].file)\\n\",\n    \"lsp.did_open(matches[0].file)\\n\",\n    \"\\n\",\n    \"# Get completions at a specific position\\n\",\n    \"completions = lsp.completions(matches[0].file, LspCompletionPosition(line=12, character=18))\\n\",\n    \"print(\\\"Completions:\\\", completions)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Sandbox Management\\n\",\n    \"\\n\",\n    \"- List Sandboxes\\n\",\n    \"- Stop Sandbox\\n\",\n    \"- Start Sandbox\\n\",\n    \"- Remove Sandbox\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"result = daytona.list()\\n\",\n    \"print(f\\\"Total sandboxes count: {result.total}\\\")\\n\",\n    \"\\n\",\n    \"for s in result.items:\\n\",\n    \"    print(f\\\"Sandbox ID: {s.id}, State: {s.state}\\\")\\n\",\n    \"    print()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"daytona.stop(sandbox)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"daytona.start(sandbox)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"daytona.delete(sandbox)\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \".venv\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.10.12\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 2\n}\n"
  },
  {
    "path": "examples/otel-dashboards/grafana/README.md",
    "content": "# Grafana Dashboard for Daytona Sandbox Monitoring\n\nThis directory contains a pre-configured Grafana dashboard for monitoring Daytona Sandbox resources including CPU, Memory, and Disk utilization using Prometheus metrics.\n\n## Dashboard Overview\n\nThe dashboard provides comprehensive monitoring across multiple pages:\n\n- **Resource Overview**: High-level view of all sandboxes with aggregate metrics\n- **CPU Details**: Detailed CPU utilization, limits, and heatmaps\n- **Memory Details**: Memory usage patterns and limits\n- **Disk Details**: Filesystem usage and space breakdown\n\n## Prerequisites\n\n- Grafana Cloud account (free tier available)\n- Daytona account with access to Experimental settings\n\n## Setup\n\n### Step 1: Create a Grafana Cloud Account\n\n1. Go to [grafana.com](https://grafana.com) and click **Create free account**\n2. Sign up with email, Google, or GitHub\n3. Create a new stack (choose a region close to you)\n\n### Step 2: Set Up OpenTelemetry Connection\n\n1. In Grafana Cloud Portal, go to **Connections** → **Add new connection**\n2. Search for **OpenTelemetry (OTLP)** and select it\n3. Follow the setup wizard:\n   - **Choose instrumentation method**: Select **OpenTelemetry SDK**, then your language\n   - **Choose your infrastructure**: Select **Linux**\n4. **Create a Grafana Cloud Access token**:\n   - Click **Create a Grafana Cloud Access token for your application**\n   - Name it something like `daytona-otel-token`\n   - Select **All scopes**\n   - Click **Create** and **save the token**\n5. **Get your configuration values** from the instrumentation instructions:\n   - Note the `OTEL_EXPORTER_OTLP_ENDPOINT` value (e.g., `https://otlp-gateway-prod-eu-central-0.grafana.net/otlp`)\n   - Note the `OTEL_EXPORTER_OTLP_HEADERS` value (e.g., `Authorization=Basic MTUxNzAz...`)\n\n### Step 3: Configure Daytona\n\n1. Go to the [Daytona Dashboard](https://app.daytona.io)\n2. Navigate to **Settings** → **Experimental**\n3. Enter the values from Step 2:\n   - **OTLP Endpoint**: The endpoint URL from Grafana (e.g., `https://otlp-gateway-prod-eu-central-0.grafana.net/otlp`)\n   - **OTLP Headers**: The Authorization header from Grafana (e.g., `Authorization=Basic MTUxNzAz...`)\n4. Click **Save**\n\n### Step 4: Verify Metrics Are Flowing\n\n1. Create a sandbox in Daytona and let it run for a few minutes\n2. In Grafana Cloud, go to **Observability** → **Application** to see your sandboxes\n3. Or go to **Explore**, select your Prometheus data source, and run:\n\n   ```promql\n   {__name__=~\"daytona_sandbox.*\"}\n   ```\n\n4. You should see metrics appearing for each sandbox\n\n### Step 5: Import the Dashboard\n\n1. In Grafana Cloud, click **Dashboards** in the left menu\n2. Click **New** → **Import**\n3. Click **Upload dashboard JSON file** and select `dashboard.json`\n4. Select your Prometheus data source from the dropdown (e.g., `grafanacloud-<stack>-prom`)\n5. Click **Import**\n\n## Dashboard Variables\n\nThe dashboard uses template variables for flexible filtering:\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `$datasource` | Prometheus data source selector | Auto-detected |\n| `$service` | Filter by `service_name` label (multi-select) | All services |\n| `$interval` | Time aggregation interval (for custom panels) | 1m |\n\n### Interval Options\n\nThe `$interval` variable is available for custom panels you may add:\n\n- **1m**: Fine-grained, best for real-time monitoring\n- **5m**: Balanced detail and performance\n- **10m**: Good for hourly analysis\n- **30m**: Overview of trends\n- **1h**: Long-term trend analysis\n\n## Widget Descriptions\n\n### Resource Overview Page\n\n| Widget | Type | Description |\n|--------|------|-------------|\n| Sandbox Count | Stat | Total number of active sandboxes reporting metrics |\n| Critical Services | Stat | Count of services exceeding resource thresholds (with color coding) |\n| Services Resource Overview | Table | Detailed metrics per service (CPU%, Memory%, Disk%, limits) |\n| CPU Utilization by Service | Time Series | CPU usage percentage over time per service |\n| Memory Utilization by Service | Time Series | Memory usage percentage over time per service |\n| Disk Utilization by Service | Time Series | Disk usage percentage over time per service |\n| Top CPU Consumers | Bar Gauge | Services with highest average CPU usage |\n| Top Memory Consumers | Bar Gauge | Services with highest average memory usage |\n| Top Disk Consumers | Bar Gauge | Services with highest average disk usage |\n| Resource Pressure Score | Time Series | Combined weighted score of all resource utilization |\n\n### CPU Details Page\n\n| Widget | Type | Description |\n|--------|------|-------------|\n| CPU Utilization Timeseries | Time Series | Detailed CPU usage over time per service |\n| Current CPU by Service | Stat | Current CPU % with threshold coloring |\n| CPU Limit by Service | Table | CPU cores limit, average, and peak usage |\n| CPU Usage Heatmap | Heatmap | Distribution of CPU usage values over time |\n\n### Memory Details Page\n\n| Widget | Type | Description |\n|--------|------|-------------|\n| Memory Utilization Timeseries | Time Series | Memory usage percentage over time |\n| Current Memory by Service | Stat | Current memory % with threshold coloring |\n| Memory Usage in GB | Time Series (Area) | Absolute memory usage in gigabytes |\n| Memory Limits and Usage | Table | Memory used, limit, average, and peak % |\n\n### Disk Details Page\n\n| Widget | Type | Description |\n|--------|------|-------------|\n| Disk Utilization Timeseries | Time Series | Disk usage percentage over time |\n| Current Disk by Service | Stat | Current disk % with threshold coloring |\n| Disk Usage in GB | Time Series (Area) | Absolute disk usage in gigabytes |\n| Disk Space Breakdown | Table | Used, available, total space, and utilization % |\n\n## Alert Thresholds\n\nThe dashboard includes pre-configured color thresholds for visual alerting:\n\n| Resource | Warning (Yellow) | Critical (Red) |\n|----------|-----------------|----------------|\n| CPU | 70% | 85% |\n| Memory | 80% | 90% |\n| Disk | 75% | 85% |\n\nThese thresholds are configured in stat panels and provide immediate visual feedback when resources are constrained.\n\n## Metrics Reference\n\nAll metrics follow the OTEL to Prometheus naming convention (dots become underscores, units are appended as suffixes):\n\n| OTEL Metric | Prometheus Metric | Description | Unit |\n|-------------|-------------------|-------------|------|\n| `daytona.sandbox.cpu.utilization` | `daytona_sandbox_cpu_utilization_percent` | CPU usage percentage | % (0-100) |\n| `daytona.sandbox.cpu.limit` | `daytona_sandbox_cpu_limit_cores` | CPU cores limit | cores |\n| `daytona.sandbox.memory.utilization` | `daytona_sandbox_memory_utilization_percent` | Memory usage percentage | % (0-100) |\n| `daytona.sandbox.memory.usage` | `daytona_sandbox_memory_usage_bytes` | Memory used | bytes |\n| `daytona.sandbox.memory.limit` | `daytona_sandbox_memory_limit_bytes` | Memory limit | bytes |\n| `daytona.sandbox.filesystem.utilization` | `daytona_sandbox_filesystem_utilization_percent` | Disk usage percentage | % (0-100) |\n| `daytona.sandbox.filesystem.usage` | `daytona_sandbox_filesystem_usage_bytes` | Disk space used | bytes |\n| `daytona.sandbox.filesystem.available` | `daytona_sandbox_filesystem_available_bytes` | Available disk space | bytes |\n| `daytona.sandbox.filesystem.total` | `daytona_sandbox_filesystem_total_bytes` | Total disk space | bytes |\n\n### Labels\n\nAll metrics include the `service_name` label identifying the sandbox.\n\n## Troubleshooting\n\n### No Data Showing\n\n1. **Verify metrics are being received**: Run this PromQL query in Grafana Explore:\n\n   ```promql\n   daytona_sandbox_cpu_utilization_percent\n   ```\n\n2. **Check data source connection**: Go to **Connections** → **Data Sources** → your Prometheus source → **Test**\n3. **Verify time range**: Ensure the dashboard time picker includes when metrics were sent\n4. **Check service filter**: Try selecting \"All\" for the `$service` variable\n\n### High Cardinality Warnings\n\nIf you have many sandboxes, consider:\n\n- Reducing the time range\n- Using larger aggregation intervals\n- Filtering to specific services\n\n### Panel Shows \"No Data\"\n\n- Verify the metric exists in Grafana Explore using `{__name__=~\"daytona.*\"}`\n- Check label names match: `service_name` (not `service.name`)\n- Ensure sandboxes are running and generating metrics\n\n### Dashboard Import Fails\n\n1. Ensure JSON is valid: `jq . dashboard.json`\n2. Check that you have dashboard creation permissions in Grafana Cloud\n\n## Customization\n\n### Modifying Panels\n\n1. Import the dashboard to Grafana\n2. Enter edit mode (click pencil icon or press `e`)\n3. Modify panels as needed\n4. Save the dashboard\n\n### Adding New Panels\n\n1. Click **Add** → **Visualization**\n2. Select your Prometheus data source\n3. Write PromQL queries using the metrics listed above\n4. Example for custom metric:\n\n   ```promql\n   avg(daytona_sandbox_cpu_utilization_percent{service_name=~\"$service\"}) by (service_name)\n   ```\n\n### Adjusting Thresholds\n\n1. Edit the desired stat panel\n2. Go to **Field** → **Thresholds**\n3. Modify warning and critical values\n4. Save the panel\n\n### Exporting Customized Dashboard\n\n1. Click the share icon in the top navigation bar\n2. Select **Export**\n3. Enable **Export for sharing externally**\n4. Click **Save to file**\n5. Replace `dashboard.json` with your customized version\n\n## Additional Resources\n\n- [Grafana Cloud Documentation](https://grafana.com/docs/grafana-cloud/)\n- [Grafana Cloud OTLP Documentation](https://grafana.com/docs/grafana-cloud/send-data/otlp/)\n- [PromQL Query Language](https://prometheus.io/docs/prometheus/latest/querying/basics/)\n"
  },
  {
    "path": "examples/otel-dashboards/grafana/dashboard.json",
    "content": "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n      \"label\": \"Prometheus\",\n      \"description\": \"Prometheus data source for Daytona sandbox metrics\",\n      \"type\": \"datasource\",\n      \"pluginId\": \"prometheus\",\n      \"pluginName\": \"Prometheus\"\n    }\n  ],\n  \"__elements\": {},\n  \"__requires\": [\n    {\n      \"type\": \"grafana\",\n      \"id\": \"grafana\",\n      \"name\": \"Grafana\",\n      \"version\": \"9.0.0\"\n    },\n    {\n      \"type\": \"datasource\",\n      \"id\": \"prometheus\",\n      \"name\": \"Prometheus\",\n      \"version\": \"1.0.0\"\n    },\n    {\n      \"type\": \"panel\",\n      \"id\": \"stat\",\n      \"name\": \"Stat\",\n      \"version\": \"\"\n    },\n    {\n      \"type\": \"panel\",\n      \"id\": \"table\",\n      \"name\": \"Table\",\n      \"version\": \"\"\n    },\n    {\n      \"type\": \"panel\",\n      \"id\": \"timeseries\",\n      \"name\": \"Time series\",\n      \"version\": \"\"\n    },\n    {\n      \"type\": \"panel\",\n      \"id\": \"bargauge\",\n      \"name\": \"Bar gauge\",\n      \"version\": \"\"\n    },\n    {\n      \"type\": \"panel\",\n      \"id\": \"heatmap\",\n      \"name\": \"Heatmap\",\n      \"version\": \"\"\n    }\n  ],\n  \"annotations\": {\n    \"list\": [\n      {\n        \"builtIn\": 1,\n        \"datasource\": {\n          \"type\": \"grafana\",\n          \"uid\": \"-- Grafana --\"\n        },\n        \"enable\": true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0, 211, 255, 1)\",\n        \"name\": \"Annotations & Alerts\",\n        \"type\": \"dashboard\"\n      }\n    ]\n  },\n  \"description\": \"Comprehensive CPU, Memory, and Disk monitoring for Daytona Sandboxes using Prometheus metrics from OpenTelemetry.\",\n  \"editable\": true,\n  \"fiscalYearStartMonth\": 0,\n  \"graphTooltip\": 1,\n  \"id\": null,\n  \"links\": [],\n  \"panels\": [\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 100,\n      \"panels\": [],\n      \"title\": \"Resource Overview\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Total number of active sandboxes reporting metrics\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 4,\n        \"x\": 0,\n        \"y\": 1\n      },\n      \"id\": 1,\n      \"options\": {\n        \"colorMode\": \"value\",\n        \"graphMode\": \"none\",\n        \"justifyMode\": \"auto\",\n        \"orientation\": \"auto\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"textMode\": \"auto\"\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"count(daytona_sandbox_cpu_utilization_percent)\",\n          \"instant\": false,\n          \"legendFormat\": \"Active Sandboxes\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Sandbox Count\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Count of services exceeding resource thresholds (CPU > 80%, Memory > 80%, or Disk > 80%)\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 1\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 3\n              }\n            ]\n          }\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 4,\n        \"x\": 4,\n        \"y\": 1\n      },\n      \"id\": 2,\n      \"options\": {\n        \"colorMode\": \"value\",\n        \"graphMode\": \"none\",\n        \"justifyMode\": \"auto\",\n        \"orientation\": \"auto\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"lastNotNull\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"textMode\": \"auto\"\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"count(daytona_sandbox_cpu_utilization_percent > 80 or daytona_sandbox_memory_utilization_percent > 80 or daytona_sandbox_filesystem_utilization_percent > 80) or vector(0)\",\n          \"instant\": false,\n          \"legendFormat\": \"Over Threshold\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Critical Services\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Detailed metrics per service including CPU, Memory, and Disk utilization with limits\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"custom\": {\n            \"align\": \"auto\",\n            \"cellOptions\": {\n              \"type\": \"auto\"\n            },\n            \"inspect\": false\n          },\n          \"mappings\": [],\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 70\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 85\n              }\n            ]\n          }\n        },\n        \"overrides\": [\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"CPU %\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"unit\",\n                \"value\": \"percent\"\n              },\n              {\n                \"id\": \"custom.cellOptions\",\n                \"value\": {\n                  \"mode\": \"gradient\",\n                  \"type\": \"gauge\"\n                }\n              },\n              {\n                \"id\": \"max\",\n                \"value\": 100\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Memory %\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"unit\",\n                \"value\": \"percent\"\n              },\n              {\n                \"id\": \"custom.cellOptions\",\n                \"value\": {\n                  \"mode\": \"gradient\",\n                  \"type\": \"gauge\"\n                }\n              },\n              {\n                \"id\": \"max\",\n                \"value\": 100\n              },\n              {\n                \"id\": \"thresholds\",\n                \"value\": {\n                  \"mode\": \"absolute\",\n                  \"steps\": [\n                    {\n                      \"color\": \"green\",\n                      \"value\": null\n                    },\n                    {\n                      \"color\": \"yellow\",\n                      \"value\": 80\n                    },\n                    {\n                      \"color\": \"red\",\n                      \"value\": 90\n                    }\n                  ]\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Disk %\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"unit\",\n                \"value\": \"percent\"\n              },\n              {\n                \"id\": \"custom.cellOptions\",\n                \"value\": {\n                  \"mode\": \"gradient\",\n                  \"type\": \"gauge\"\n                }\n              },\n              {\n                \"id\": \"max\",\n                \"value\": 100\n              },\n              {\n                \"id\": \"thresholds\",\n                \"value\": {\n                  \"mode\": \"absolute\",\n                  \"steps\": [\n                    {\n                      \"color\": \"green\",\n                      \"value\": null\n                    },\n                    {\n                      \"color\": \"yellow\",\n                      \"value\": 75\n                    },\n                    {\n                      \"color\": \"red\",\n                      \"value\": 85\n                    }\n                  ]\n                }\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Memory Used (GB)\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"unit\",\n                \"value\": \"decgbytes\"\n              },\n              {\n                \"id\": \"decimals\",\n                \"value\": 2\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Memory Limit (GB)\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"unit\",\n                \"value\": \"decgbytes\"\n              },\n              {\n                \"id\": \"decimals\",\n                \"value\": 2\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Disk Used (GB)\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"unit\",\n                \"value\": \"decgbytes\"\n              },\n              {\n                \"id\": \"decimals\",\n                \"value\": 2\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"Disk Total (GB)\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"unit\",\n                \"value\": \"decgbytes\"\n              },\n              {\n                \"id\": \"decimals\",\n                \"value\": 2\n              }\n            ]\n          },\n          {\n            \"matcher\": {\n              \"id\": \"byName\",\n              \"options\": \"CPU Cores\"\n            },\n            \"properties\": [\n              {\n                \"id\": \"decimals\",\n                \"value\": 1\n              }\n            ]\n          }\n        ]\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 16,\n        \"x\": 8,\n        \"y\": 1\n      },\n      \"id\": 3,\n      \"options\": {\n        \"cellHeight\": \"sm\",\n        \"footer\": {\n          \"countRows\": false,\n          \"fields\": \"\",\n          \"reducer\": [\n            \"sum\"\n          ],\n          \"show\": false\n        },\n        \"showHeader\": true,\n        \"sortBy\": [\n          {\n            \"desc\": true,\n            \"displayName\": \"CPU %\"\n          }\n        ]\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}\",\n          \"format\": \"table\",\n          \"instant\": false,\n          \"legendFormat\": \"__auto\",\n          \"refId\": \"CPU\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"daytona_sandbox_cpu_limit_cores{service_name=~\\\"$service\\\"}\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": false,\n          \"legendFormat\": \"__auto\",\n          \"refId\": \"CPU_LIMIT\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"daytona_sandbox_memory_utilization_percent{service_name=~\\\"$service\\\"}\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": false,\n          \"legendFormat\": \"__auto\",\n          \"refId\": \"MEMORY\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"daytona_sandbox_memory_usage_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": false,\n          \"legendFormat\": \"__auto\",\n          \"refId\": \"MEMORY_USAGE\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"daytona_sandbox_memory_limit_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": false,\n          \"legendFormat\": \"__auto\",\n          \"refId\": \"MEMORY_LIMIT\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"daytona_sandbox_filesystem_utilization_percent{service_name=~\\\"$service\\\"}\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": false,\n          \"legendFormat\": \"__auto\",\n          \"refId\": \"DISK\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"daytona_sandbox_filesystem_usage_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": false,\n          \"legendFormat\": \"__auto\",\n          \"refId\": \"DISK_USAGE\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"exemplar\": false,\n          \"expr\": \"daytona_sandbox_filesystem_total_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n          \"format\": \"table\",\n          \"hide\": false,\n          \"instant\": false,\n          \"legendFormat\": \"__auto\",\n          \"refId\": \"DISK_TOTAL\"\n        }\n      ],\n      \"title\": \"Services Resource Overview\",\n      \"transformations\": [\n        {\n          \"id\": \"joinByField\",\n          \"options\": {\n            \"byField\": \"service_name\",\n            \"mode\": \"outer\"\n          }\n        },\n        {\n          \"id\": \"organize\",\n          \"options\": {\n            \"excludeByName\": {\n              \"Time\": true,\n              \"Time 1\": true,\n              \"Time 2\": true,\n              \"Time 3\": true,\n              \"Time 4\": true,\n              \"Time 5\": true,\n              \"Time 6\": true,\n              \"Time 7\": true,\n              \"Time 8\": true,\n              \"__name__\": true,\n              \"__name__ 1\": true,\n              \"__name__ 2\": true,\n              \"__name__ 3\": true,\n              \"__name__ 4\": true,\n              \"__name__ 5\": true,\n              \"__name__ 6\": true,\n              \"__name__ 7\": true,\n              \"__name__ 8\": true,\n              \"instance\": true,\n              \"instance 1\": true,\n              \"instance 2\": true,\n              \"instance 3\": true,\n              \"instance 4\": true,\n              \"instance 5\": true,\n              \"instance 6\": true,\n              \"instance 7\": true,\n              \"instance 8\": true,\n              \"job\": true,\n              \"job 1\": true,\n              \"job 2\": true,\n              \"job 3\": true,\n              \"job 4\": true,\n              \"job 5\": true,\n              \"job 6\": true,\n              \"job 7\": true,\n              \"job 8\": true\n            },\n            \"includeByName\": {},\n            \"indexByName\": {},\n            \"renameByName\": {\n              \"Value #CPU\": \"CPU %\",\n              \"Value #CPU_LIMIT\": \"CPU Cores\",\n              \"Value #DISK\": \"Disk %\",\n              \"Value #DISK_TOTAL\": \"Disk Total (GB)\",\n              \"Value #DISK_USAGE\": \"Disk Used (GB)\",\n              \"Value #MEMORY\": \"Memory %\",\n              \"Value #MEMORY_LIMIT\": \"Memory Limit (GB)\",\n              \"Value #MEMORY_USAGE\": \"Memory Used (GB)\",\n              \"service_name\": \"Service\"\n            }\n          }\n        }\n      ],\n      \"type\": \"table\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"CPU usage percentage over time per service\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 10,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"never\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"line\"\n            }\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 70\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 85\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 0,\n        \"y\": 5\n      },\n      \"id\": 4,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"mean\",\n            \"max\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}\",\n          \"legendFormat\": \"{{service_name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"CPU Utilization by Service\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Memory usage percentage over time per service\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 10,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"never\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"line\"\n            }\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 80\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 90\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 0,\n        \"y\": 11\n      },\n      \"id\": 5,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"mean\",\n            \"max\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"daytona_sandbox_memory_utilization_percent{service_name=~\\\"$service\\\"}\",\n          \"legendFormat\": \"{{service_name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Memory Utilization by Service\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Disk usage percentage over time per service\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 10,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"never\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"line\"\n            }\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 75\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 85\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 0,\n        \"y\": 17\n      },\n      \"id\": 6,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"mean\",\n            \"max\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"daytona_sandbox_filesystem_utilization_percent{service_name=~\\\"$service\\\"}\",\n          \"legendFormat\": \"{{service_name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Disk Utilization by Service\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Services with highest average CPU usage over the last hour\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 70\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 85\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 8,\n        \"y\": 9\n      },\n      \"id\": 7,\n      \"options\": {\n        \"displayMode\": \"gradient\",\n        \"maxVizHeight\": 300,\n        \"minVizHeight\": 10,\n        \"minVizWidth\": 0,\n        \"namePlacement\": \"auto\",\n        \"orientation\": \"horizontal\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"mean\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"showUnfilled\": true,\n        \"sizing\": \"auto\",\n        \"valueMode\": \"color\"\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"topk(10, avg by (service_name) (avg_over_time(daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}[1h])))\",\n          \"legendFormat\": \"{{service_name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Top CPU Consumers\",\n      \"type\": \"bargauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Services with highest average memory usage over the last hour\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 80\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 90\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 16,\n        \"y\": 9\n      },\n      \"id\": 8,\n      \"options\": {\n        \"displayMode\": \"gradient\",\n        \"maxVizHeight\": 300,\n        \"minVizHeight\": 10,\n        \"minVizWidth\": 0,\n        \"namePlacement\": \"auto\",\n        \"orientation\": \"horizontal\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"mean\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"showUnfilled\": true,\n        \"sizing\": \"auto\",\n        \"valueMode\": \"color\"\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"topk(10, avg by (service_name) (avg_over_time(daytona_sandbox_memory_utilization_percent{service_name=~\\\"$service\\\"}[1h])))\",\n          \"legendFormat\": \"{{service_name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Top Memory Consumers\",\n      \"type\": \"bargauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Services with highest average disk usage over the last hour\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"thresholds\"\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 75\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 85\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 8,\n        \"y\": 15\n      },\n      \"id\": 9,\n      \"options\": {\n        \"displayMode\": \"gradient\",\n        \"maxVizHeight\": 300,\n        \"minVizHeight\": 10,\n        \"minVizWidth\": 0,\n        \"namePlacement\": \"auto\",\n        \"orientation\": \"horizontal\",\n        \"reduceOptions\": {\n          \"calcs\": [\n            \"mean\"\n          ],\n          \"fields\": \"\",\n          \"values\": false\n        },\n        \"showUnfilled\": true,\n        \"sizing\": \"auto\",\n        \"valueMode\": \"color\"\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"topk(10, avg by (service_name) (avg_over_time(daytona_sandbox_filesystem_utilization_percent{service_name=~\\\"$service\\\"}[1h])))\",\n          \"legendFormat\": \"{{service_name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Top Disk Consumers\",\n      \"type\": \"bargauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"prometheus\",\n        \"uid\": \"${datasource}\"\n      },\n      \"description\": \"Combined weighted score of CPU (33%), Memory (33%), and Disk (34%) utilization\",\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"color\": {\n            \"mode\": \"palette-classic\"\n          },\n          \"custom\": {\n            \"axisBorderShow\": false,\n            \"axisCenteredZero\": false,\n            \"axisColorMode\": \"text\",\n            \"axisLabel\": \"\",\n            \"axisPlacement\": \"auto\",\n            \"barAlignment\": 0,\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 10,\n            \"gradientMode\": \"none\",\n            \"hideFrom\": {\n              \"legend\": false,\n              \"tooltip\": false,\n              \"viz\": false\n            },\n            \"insertNulls\": false,\n            \"lineInterpolation\": \"smooth\",\n            \"lineWidth\": 2,\n            \"pointSize\": 5,\n            \"scaleDistribution\": {\n              \"type\": \"linear\"\n            },\n            \"showPoints\": \"never\",\n            \"spanNulls\": false,\n            \"stacking\": {\n              \"group\": \"A\",\n              \"mode\": \"none\"\n            },\n            \"thresholdsStyle\": {\n              \"mode\": \"line\"\n            }\n          },\n          \"mappings\": [],\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"mode\": \"absolute\",\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 70\n              },\n              {\n                \"color\": \"red\",\n                \"value\": 85\n              }\n            ]\n          },\n          \"unit\": \"percent\"\n        },\n        \"overrides\": []\n      },\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 16,\n        \"y\": 15\n      },\n      \"id\": 10,\n      \"options\": {\n        \"legend\": {\n          \"calcs\": [\n            \"mean\",\n            \"max\"\n          ],\n          \"displayMode\": \"table\",\n          \"placement\": \"bottom\",\n          \"showLegend\": true\n        },\n        \"tooltip\": {\n          \"mode\": \"multi\",\n          \"sort\": \"desc\"\n        }\n      },\n      \"pluginVersion\": \"9.0.0\",\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"editorMode\": \"code\",\n          \"expr\": \"(avg by (service_name) (daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}) * 0.33) + (avg by (service_name) (daytona_sandbox_memory_utilization_percent{service_name=~\\\"$service\\\"}) * 0.33) + (avg by (service_name) (daytona_sandbox_filesystem_utilization_percent{service_name=~\\\"$service\\\"}) * 0.34)\",\n          \"legendFormat\": \"{{service_name}}\",\n          \"range\": true,\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Resource Pressure Score\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": true,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 23\n      },\n      \"id\": 200,\n      \"panels\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"CPU usage percentage over time per service\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"smooth\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"line\"\n                }\n              },\n              \"mappings\": [],\n              \"max\": 100,\n              \"min\": 0,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"yellow\",\n                    \"value\": 70\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 85\n                  }\n                ]\n              },\n              \"unit\": \"percent\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 16,\n            \"x\": 0,\n            \"y\": 24\n          },\n          \"id\": 11,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\",\n                \"min\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"desc\"\n            }\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"CPU Utilization Timeseries\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Current CPU utilization percentage by service with threshold coloring\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"thresholds\"\n              },\n              \"mappings\": [],\n              \"max\": 100,\n              \"min\": 0,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"yellow\",\n                    \"value\": 70\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 85\n                  }\n                ]\n              },\n              \"unit\": \"percent\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 8,\n            \"x\": 16,\n            \"y\": 24\n          },\n          \"id\": 12,\n          \"options\": {\n            \"colorMode\": \"background\",\n            \"graphMode\": \"area\",\n            \"justifyMode\": \"auto\",\n            \"orientation\": \"horizontal\",\n            \"reduceOptions\": {\n              \"calcs\": [\n                \"lastNotNull\"\n              ],\n              \"fields\": \"\",\n              \"values\": false\n            },\n            \"textMode\": \"auto\"\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Current CPU by Service\",\n          \"type\": \"stat\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"CPU cores limit, average, and peak usage per service\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"thresholds\"\n              },\n              \"custom\": {\n                \"align\": \"auto\",\n                \"cellOptions\": {\n                  \"type\": \"auto\"\n                },\n                \"inspect\": false\n              },\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  }\n                ]\n              }\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Avg CPU %\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"percent\"\n                  },\n                  {\n                    \"id\": \"thresholds\",\n                    \"value\": {\n                      \"mode\": \"absolute\",\n                      \"steps\": [\n                        {\n                          \"color\": \"green\",\n                          \"value\": null\n                        },\n                        {\n                          \"color\": \"yellow\",\n                          \"value\": 70\n                        },\n                        {\n                          \"color\": \"red\",\n                          \"value\": 85\n                        }\n                      ]\n                    }\n                  },\n                  {\n                    \"id\": \"custom.cellOptions\",\n                    \"value\": {\n                      \"mode\": \"gradient\",\n                      \"type\": \"gauge\"\n                    }\n                  },\n                  {\n                    \"id\": \"max\",\n                    \"value\": 100\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Peak CPU %\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"percent\"\n                  },\n                  {\n                    \"id\": \"thresholds\",\n                    \"value\": {\n                      \"mode\": \"absolute\",\n                      \"steps\": [\n                        {\n                          \"color\": \"green\",\n                          \"value\": null\n                        },\n                        {\n                          \"color\": \"yellow\",\n                          \"value\": 70\n                        },\n                        {\n                          \"color\": \"red\",\n                          \"value\": 85\n                        }\n                      ]\n                    }\n                  },\n                  {\n                    \"id\": \"custom.cellOptions\",\n                    \"value\": {\n                      \"mode\": \"gradient\",\n                      \"type\": \"gauge\"\n                    }\n                  },\n                  {\n                    \"id\": \"max\",\n                    \"value\": 100\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"CPU Cores Limit\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"decimals\",\n                    \"value\": 1\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 32\n          },\n          \"id\": 13,\n          \"options\": {\n            \"cellHeight\": \"sm\",\n            \"footer\": {\n              \"countRows\": false,\n              \"fields\": \"\",\n              \"reducer\": [\n                \"sum\"\n              ],\n              \"show\": false\n            },\n            \"showHeader\": true,\n            \"sortBy\": [\n              {\n                \"desc\": true,\n                \"displayName\": \"Avg CPU %\"\n              }\n            ]\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"daytona_sandbox_cpu_limit_cores{service_name=~\\\"$service\\\"}\",\n              \"format\": \"table\",\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"LIMIT\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"avg_over_time(daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}[1h])\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"AVG\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"max_over_time(daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}[1h])\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"PEAK\"\n            }\n          ],\n          \"title\": \"CPU Limit by Service\",\n          \"transformations\": [\n            {\n              \"id\": \"joinByField\",\n              \"options\": {\n                \"byField\": \"service_name\",\n                \"mode\": \"outer\"\n              }\n            },\n            {\n              \"id\": \"organize\",\n              \"options\": {\n                \"excludeByName\": {\n                  \"Time\": true,\n                  \"Time 1\": true,\n                  \"Time 2\": true,\n                  \"Time 3\": true,\n                  \"__name__\": true,\n                  \"__name__ 1\": true,\n                  \"__name__ 2\": true,\n                  \"__name__ 3\": true,\n                  \"instance\": true,\n                  \"instance 1\": true,\n                  \"instance 2\": true,\n                  \"instance 3\": true,\n                  \"job\": true,\n                  \"job 1\": true,\n                  \"job 2\": true,\n                  \"job 3\": true\n                },\n                \"includeByName\": {},\n                \"indexByName\": {},\n                \"renameByName\": {\n                  \"Value #AVG\": \"Avg CPU %\",\n                  \"Value #LIMIT\": \"CPU Cores Limit\",\n                  \"Value #PEAK\": \"Peak CPU %\",\n                  \"service_name\": \"Service\"\n                }\n              }\n            }\n          ],\n          \"type\": \"table\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Distribution of CPU usage values over time\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"custom\": {\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                }\n              }\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 6,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 32\n          },\n          \"id\": 14,\n          \"options\": {\n            \"calculate\": true,\n            \"calculation\": {\n              \"xBuckets\": {\n                \"mode\": \"size\"\n              },\n              \"yBuckets\": {\n                \"mode\": \"count\",\n                \"value\": \"10\"\n              }\n            },\n            \"cellGap\": 1,\n            \"color\": {\n              \"exponent\": 0.5,\n              \"fill\": \"dark-orange\",\n              \"mode\": \"scheme\",\n              \"reverse\": false,\n              \"scale\": \"exponential\",\n              \"scheme\": \"Oranges\",\n              \"steps\": 64\n            },\n            \"exemplars\": {\n              \"color\": \"rgba(255,0,255,0.7)\"\n            },\n            \"filterValues\": {\n              \"le\": 1e-9\n            },\n            \"legend\": {\n              \"show\": true\n            },\n            \"rowsFrame\": {\n              \"layout\": \"auto\"\n            },\n            \"tooltip\": {\n              \"mode\": \"single\",\n              \"showColorScale\": false,\n              \"yHistogram\": false\n            },\n            \"yAxis\": {\n              \"axisPlacement\": \"left\",\n              \"reverse\": false,\n              \"unit\": \"percent\"\n            }\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_cpu_utilization_percent{service_name=~\\\"$service\\\"}\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"CPU Usage Heatmap\",\n          \"type\": \"heatmap\"\n        }\n      ],\n      \"title\": \"CPU Details\",\n      \"type\": \"row\"\n    },\n    {\n      \"collapsed\": true,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 24\n      },\n      \"id\": 300,\n      \"panels\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Memory usage percentage over time per service\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"smooth\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"line\"\n                }\n              },\n              \"mappings\": [],\n              \"max\": 100,\n              \"min\": 0,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"yellow\",\n                    \"value\": 80\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 90\n                  }\n                ]\n              },\n              \"unit\": \"percent\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 16,\n            \"x\": 0,\n            \"y\": 25\n          },\n          \"id\": 21,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\",\n                \"min\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"desc\"\n            }\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_memory_utilization_percent{service_name=~\\\"$service\\\"}\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Memory Utilization Timeseries\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Current memory utilization percentage by service with threshold coloring\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"thresholds\"\n              },\n              \"mappings\": [],\n              \"max\": 100,\n              \"min\": 0,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"yellow\",\n                    \"value\": 80\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 90\n                  }\n                ]\n              },\n              \"unit\": \"percent\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 8,\n            \"x\": 16,\n            \"y\": 25\n          },\n          \"id\": 22,\n          \"options\": {\n            \"colorMode\": \"background\",\n            \"graphMode\": \"area\",\n            \"justifyMode\": \"auto\",\n            \"orientation\": \"horizontal\",\n            \"reduceOptions\": {\n              \"calcs\": [\n                \"lastNotNull\"\n              ],\n              \"fields\": \"\",\n              \"values\": false\n            },\n            \"textMode\": \"auto\"\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_memory_utilization_percent{service_name=~\\\"$service\\\"}\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Current Memory by Service\",\n          \"type\": \"stat\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Absolute memory usage in gigabytes over time\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 30,\n                \"gradientMode\": \"opacity\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"smooth\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"mappings\": [],\n              \"min\": 0,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  }\n                ]\n              },\n              \"unit\": \"decgbytes\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 33\n          },\n          \"id\": 23,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"desc\"\n            }\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_memory_usage_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Memory Usage in GB\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Memory used, limit, average, and peak utilization per service\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"thresholds\"\n              },\n              \"custom\": {\n                \"align\": \"auto\",\n                \"cellOptions\": {\n                  \"type\": \"auto\"\n                },\n                \"inspect\": false\n              },\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  }\n                ]\n              }\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Used (GB)\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"decgbytes\"\n                  },\n                  {\n                    \"id\": \"decimals\",\n                    \"value\": 2\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Limit (GB)\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"decgbytes\"\n                  },\n                  {\n                    \"id\": \"decimals\",\n                    \"value\": 2\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Avg %\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"percent\"\n                  },\n                  {\n                    \"id\": \"thresholds\",\n                    \"value\": {\n                      \"mode\": \"absolute\",\n                      \"steps\": [\n                        {\n                          \"color\": \"green\",\n                          \"value\": null\n                        },\n                        {\n                          \"color\": \"yellow\",\n                          \"value\": 80\n                        },\n                        {\n                          \"color\": \"red\",\n                          \"value\": 90\n                        }\n                      ]\n                    }\n                  },\n                  {\n                    \"id\": \"custom.cellOptions\",\n                    \"value\": {\n                      \"mode\": \"gradient\",\n                      \"type\": \"gauge\"\n                    }\n                  },\n                  {\n                    \"id\": \"max\",\n                    \"value\": 100\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Peak %\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"percent\"\n                  },\n                  {\n                    \"id\": \"thresholds\",\n                    \"value\": {\n                      \"mode\": \"absolute\",\n                      \"steps\": [\n                        {\n                          \"color\": \"green\",\n                          \"value\": null\n                        },\n                        {\n                          \"color\": \"yellow\",\n                          \"value\": 80\n                        },\n                        {\n                          \"color\": \"red\",\n                          \"value\": 90\n                        }\n                      ]\n                    }\n                  },\n                  {\n                    \"id\": \"custom.cellOptions\",\n                    \"value\": {\n                      \"mode\": \"gradient\",\n                      \"type\": \"gauge\"\n                    }\n                  },\n                  {\n                    \"id\": \"max\",\n                    \"value\": 100\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 33\n          },\n          \"id\": 24,\n          \"options\": {\n            \"cellHeight\": \"sm\",\n            \"footer\": {\n              \"countRows\": false,\n              \"fields\": \"\",\n              \"reducer\": [\n                \"sum\"\n              ],\n              \"show\": false\n            },\n            \"showHeader\": true,\n            \"sortBy\": [\n              {\n                \"desc\": true,\n                \"displayName\": \"Avg %\"\n              }\n            ]\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"daytona_sandbox_memory_usage_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n              \"format\": \"table\",\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"USED\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"daytona_sandbox_memory_limit_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"LIMIT\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"avg_over_time(daytona_sandbox_memory_utilization_percent{service_name=~\\\"$service\\\"}[1h])\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"AVG\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"max_over_time(daytona_sandbox_memory_utilization_percent{service_name=~\\\"$service\\\"}[1h])\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"PEAK\"\n            }\n          ],\n          \"title\": \"Memory Limits and Usage\",\n          \"transformations\": [\n            {\n              \"id\": \"joinByField\",\n              \"options\": {\n                \"byField\": \"service_name\",\n                \"mode\": \"outer\"\n              }\n            },\n            {\n              \"id\": \"organize\",\n              \"options\": {\n                \"excludeByName\": {\n                  \"Time\": true,\n                  \"Time 1\": true,\n                  \"Time 2\": true,\n                  \"Time 3\": true,\n                  \"Time 4\": true,\n                  \"__name__\": true,\n                  \"__name__ 1\": true,\n                  \"__name__ 2\": true,\n                  \"__name__ 3\": true,\n                  \"__name__ 4\": true,\n                  \"instance\": true,\n                  \"instance 1\": true,\n                  \"instance 2\": true,\n                  \"instance 3\": true,\n                  \"instance 4\": true,\n                  \"job\": true,\n                  \"job 1\": true,\n                  \"job 2\": true,\n                  \"job 3\": true,\n                  \"job 4\": true\n                },\n                \"includeByName\": {},\n                \"indexByName\": {},\n                \"renameByName\": {\n                  \"Value #AVG\": \"Avg %\",\n                  \"Value #LIMIT\": \"Limit (GB)\",\n                  \"Value #PEAK\": \"Peak %\",\n                  \"Value #USED\": \"Used (GB)\",\n                  \"service_name\": \"Service\"\n                }\n              }\n            }\n          ],\n          \"type\": \"table\"\n        }\n      ],\n      \"title\": \"Memory Details\",\n      \"type\": \"row\"\n    },\n    {\n      \"collapsed\": true,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 25\n      },\n      \"id\": 400,\n      \"panels\": [\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Disk usage percentage over time per service\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 10,\n                \"gradientMode\": \"none\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"smooth\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"line\"\n                }\n              },\n              \"mappings\": [],\n              \"max\": 100,\n              \"min\": 0,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"yellow\",\n                    \"value\": 75\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 85\n                  }\n                ]\n              },\n              \"unit\": \"percent\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 16,\n            \"x\": 0,\n            \"y\": 26\n          },\n          \"id\": 31,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\",\n                \"min\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"desc\"\n            }\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_filesystem_utilization_percent{service_name=~\\\"$service\\\"}\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Disk Utilization Timeseries\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Current disk utilization percentage by service with threshold coloring\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"thresholds\"\n              },\n              \"mappings\": [],\n              \"max\": 100,\n              \"min\": 0,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  },\n                  {\n                    \"color\": \"yellow\",\n                    \"value\": 75\n                  },\n                  {\n                    \"color\": \"red\",\n                    \"value\": 85\n                  }\n                ]\n              },\n              \"unit\": \"percent\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 8,\n            \"x\": 16,\n            \"y\": 26\n          },\n          \"id\": 32,\n          \"options\": {\n            \"colorMode\": \"background\",\n            \"graphMode\": \"area\",\n            \"justifyMode\": \"auto\",\n            \"orientation\": \"horizontal\",\n            \"reduceOptions\": {\n              \"calcs\": [\n                \"lastNotNull\"\n              ],\n              \"fields\": \"\",\n              \"values\": false\n            },\n            \"textMode\": \"auto\"\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_filesystem_utilization_percent{service_name=~\\\"$service\\\"}\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Current Disk by Service\",\n          \"type\": \"stat\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Absolute disk usage in gigabytes over time\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"palette-classic\"\n              },\n              \"custom\": {\n                \"axisBorderShow\": false,\n                \"axisCenteredZero\": false,\n                \"axisColorMode\": \"text\",\n                \"axisLabel\": \"\",\n                \"axisPlacement\": \"auto\",\n                \"barAlignment\": 0,\n                \"drawStyle\": \"line\",\n                \"fillOpacity\": 30,\n                \"gradientMode\": \"opacity\",\n                \"hideFrom\": {\n                  \"legend\": false,\n                  \"tooltip\": false,\n                  \"viz\": false\n                },\n                \"insertNulls\": false,\n                \"lineInterpolation\": \"smooth\",\n                \"lineWidth\": 1,\n                \"pointSize\": 5,\n                \"scaleDistribution\": {\n                  \"type\": \"linear\"\n                },\n                \"showPoints\": \"never\",\n                \"spanNulls\": false,\n                \"stacking\": {\n                  \"group\": \"A\",\n                  \"mode\": \"none\"\n                },\n                \"thresholdsStyle\": {\n                  \"mode\": \"off\"\n                }\n              },\n              \"mappings\": [],\n              \"min\": 0,\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  }\n                ]\n              },\n              \"unit\": \"decgbytes\"\n            },\n            \"overrides\": []\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 0,\n            \"y\": 34\n          },\n          \"id\": 33,\n          \"options\": {\n            \"legend\": {\n              \"calcs\": [\n                \"mean\",\n                \"max\"\n              ],\n              \"displayMode\": \"table\",\n              \"placement\": \"right\",\n              \"showLegend\": true\n            },\n            \"tooltip\": {\n              \"mode\": \"multi\",\n              \"sort\": \"desc\"\n            }\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"expr\": \"daytona_sandbox_filesystem_usage_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n              \"legendFormat\": \"{{service_name}}\",\n              \"range\": true,\n              \"refId\": \"A\"\n            }\n          ],\n          \"title\": \"Disk Usage in GB\",\n          \"type\": \"timeseries\"\n        },\n        {\n          \"datasource\": {\n            \"type\": \"prometheus\",\n            \"uid\": \"${datasource}\"\n          },\n          \"description\": \"Disk space used, available, total, and utilization percentage per service\",\n          \"fieldConfig\": {\n            \"defaults\": {\n              \"color\": {\n                \"mode\": \"thresholds\"\n              },\n              \"custom\": {\n                \"align\": \"auto\",\n                \"cellOptions\": {\n                  \"type\": \"auto\"\n                },\n                \"inspect\": false\n              },\n              \"mappings\": [],\n              \"thresholds\": {\n                \"mode\": \"absolute\",\n                \"steps\": [\n                  {\n                    \"color\": \"green\",\n                    \"value\": null\n                  }\n                ]\n              }\n            },\n            \"overrides\": [\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Used (GB)\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"decgbytes\"\n                  },\n                  {\n                    \"id\": \"decimals\",\n                    \"value\": 2\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Available (GB)\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"decgbytes\"\n                  },\n                  {\n                    \"id\": \"decimals\",\n                    \"value\": 2\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Total (GB)\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"decgbytes\"\n                  },\n                  {\n                    \"id\": \"decimals\",\n                    \"value\": 2\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Avg %\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"percent\"\n                  },\n                  {\n                    \"id\": \"thresholds\",\n                    \"value\": {\n                      \"mode\": \"absolute\",\n                      \"steps\": [\n                        {\n                          \"color\": \"green\",\n                          \"value\": null\n                        },\n                        {\n                          \"color\": \"yellow\",\n                          \"value\": 75\n                        },\n                        {\n                          \"color\": \"red\",\n                          \"value\": 85\n                        }\n                      ]\n                    }\n                  },\n                  {\n                    \"id\": \"custom.cellOptions\",\n                    \"value\": {\n                      \"mode\": \"gradient\",\n                      \"type\": \"gauge\"\n                    }\n                  },\n                  {\n                    \"id\": \"max\",\n                    \"value\": 100\n                  }\n                ]\n              },\n              {\n                \"matcher\": {\n                  \"id\": \"byName\",\n                  \"options\": \"Peak %\"\n                },\n                \"properties\": [\n                  {\n                    \"id\": \"unit\",\n                    \"value\": \"percent\"\n                  },\n                  {\n                    \"id\": \"thresholds\",\n                    \"value\": {\n                      \"mode\": \"absolute\",\n                      \"steps\": [\n                        {\n                          \"color\": \"green\",\n                          \"value\": null\n                        },\n                        {\n                          \"color\": \"yellow\",\n                          \"value\": 75\n                        },\n                        {\n                          \"color\": \"red\",\n                          \"value\": 85\n                        }\n                      ]\n                    }\n                  },\n                  {\n                    \"id\": \"custom.cellOptions\",\n                    \"value\": {\n                      \"mode\": \"gradient\",\n                      \"type\": \"gauge\"\n                    }\n                  },\n                  {\n                    \"id\": \"max\",\n                    \"value\": 100\n                  }\n                ]\n              }\n            ]\n          },\n          \"gridPos\": {\n            \"h\": 8,\n            \"w\": 12,\n            \"x\": 12,\n            \"y\": 34\n          },\n          \"id\": 34,\n          \"options\": {\n            \"cellHeight\": \"sm\",\n            \"footer\": {\n              \"countRows\": false,\n              \"fields\": \"\",\n              \"reducer\": [\n                \"sum\"\n              ],\n              \"show\": false\n            },\n            \"showHeader\": true,\n            \"sortBy\": [\n              {\n                \"desc\": true,\n                \"displayName\": \"Avg %\"\n              }\n            ]\n          },\n          \"pluginVersion\": \"9.0.0\",\n          \"targets\": [\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"daytona_sandbox_filesystem_usage_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n              \"format\": \"table\",\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"USED\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"daytona_sandbox_filesystem_available_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"AVAILABLE\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"daytona_sandbox_filesystem_total_bytes{service_name=~\\\"$service\\\"} / 1073741824\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"TOTAL\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"avg_over_time(daytona_sandbox_filesystem_utilization_percent{service_name=~\\\"$service\\\"}[1h])\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"AVG\"\n            },\n            {\n              \"datasource\": {\n                \"type\": \"prometheus\",\n                \"uid\": \"${datasource}\"\n              },\n              \"editorMode\": \"code\",\n              \"exemplar\": false,\n              \"expr\": \"max_over_time(daytona_sandbox_filesystem_utilization_percent{service_name=~\\\"$service\\\"}[1h])\",\n              \"format\": \"table\",\n              \"hide\": false,\n              \"instant\": false,\n              \"legendFormat\": \"__auto\",\n              \"refId\": \"PEAK\"\n            }\n          ],\n          \"title\": \"Disk Space Breakdown\",\n          \"transformations\": [\n            {\n              \"id\": \"joinByField\",\n              \"options\": {\n                \"byField\": \"service_name\",\n                \"mode\": \"outer\"\n              }\n            },\n            {\n              \"id\": \"organize\",\n              \"options\": {\n                \"excludeByName\": {\n                  \"Time\": true,\n                  \"Time 1\": true,\n                  \"Time 2\": true,\n                  \"Time 3\": true,\n                  \"Time 4\": true,\n                  \"Time 5\": true,\n                  \"__name__\": true,\n                  \"__name__ 1\": true,\n                  \"__name__ 2\": true,\n                  \"__name__ 3\": true,\n                  \"__name__ 4\": true,\n                  \"__name__ 5\": true,\n                  \"instance\": true,\n                  \"instance 1\": true,\n                  \"instance 2\": true,\n                  \"instance 3\": true,\n                  \"instance 4\": true,\n                  \"instance 5\": true,\n                  \"job\": true,\n                  \"job 1\": true,\n                  \"job 2\": true,\n                  \"job 3\": true,\n                  \"job 4\": true,\n                  \"job 5\": true\n                },\n                \"includeByName\": {},\n                \"indexByName\": {},\n                \"renameByName\": {\n                  \"Value #AVAILABLE\": \"Available (GB)\",\n                  \"Value #AVG\": \"Avg %\",\n                  \"Value #PEAK\": \"Peak %\",\n                  \"Value #TOTAL\": \"Total (GB)\",\n                  \"Value #USED\": \"Used (GB)\",\n                  \"service_name\": \"Service\"\n                }\n              }\n            }\n          ],\n          \"type\": \"table\"\n        }\n      ],\n      \"title\": \"Disk Details\",\n      \"type\": \"row\"\n    }\n  ],\n  \"schemaVersion\": 38,\n  \"tags\": [\n    \"daytona\",\n    \"sandbox\",\n    \"opentelemetry\",\n    \"prometheus\"\n  ],\n  \"templating\": {\n    \"list\": [\n      {\n        \"current\": {},\n        \"description\": \"Prometheus data source containing Daytona sandbox metrics\",\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"label\": \"Data Source\",\n        \"multi\": false,\n        \"name\": \"datasource\",\n        \"options\": [],\n        \"query\": \"prometheus\",\n        \"queryValue\": \"\",\n        \"refresh\": 1,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"type\": \"datasource\"\n      },\n      {\n        \"allValue\": \".*\",\n        \"current\": {},\n        \"datasource\": {\n          \"type\": \"prometheus\",\n          \"uid\": \"${datasource}\"\n        },\n        \"definition\": \"label_values(daytona_sandbox_cpu_utilization_percent, service_name)\",\n        \"description\": \"Filter by sandbox service name\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"label\": \"Service\",\n        \"multi\": true,\n        \"name\": \"service\",\n        \"options\": [],\n        \"query\": {\n          \"qryType\": 1,\n          \"query\": \"label_values(daytona_sandbox_cpu_utilization_percent, service_name)\",\n          \"refId\": \"PrometheusVariableQueryEditor-VariableQuery\"\n        },\n        \"refresh\": 2,\n        \"regex\": \"\",\n        \"skipUrlSync\": false,\n        \"sort\": 1,\n        \"type\": \"query\"\n      },\n      {\n        \"current\": {\n          \"selected\": false,\n          \"text\": \"1m\",\n          \"value\": \"1m\"\n        },\n        \"description\": \"Time aggregation interval for averaging metrics\",\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"label\": \"Interval\",\n        \"multi\": false,\n        \"name\": \"interval\",\n        \"options\": [\n          {\n            \"selected\": true,\n            \"text\": \"1m\",\n            \"value\": \"1m\"\n          },\n          {\n            \"selected\": false,\n            \"text\": \"5m\",\n            \"value\": \"5m\"\n          },\n          {\n            \"selected\": false,\n            \"text\": \"10m\",\n            \"value\": \"10m\"\n          },\n          {\n            \"selected\": false,\n            \"text\": \"30m\",\n            \"value\": \"30m\"\n          },\n          {\n            \"selected\": false,\n            \"text\": \"1h\",\n            \"value\": \"1h\"\n          }\n        ],\n        \"query\": \"1m,5m,10m,30m,1h\",\n        \"queryValue\": \"\",\n        \"skipUrlSync\": false,\n        \"type\": \"custom\"\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-1h\",\n    \"to\": \"now\"\n  },\n  \"timepicker\": {\n    \"refresh_intervals\": [\n      \"5s\",\n      \"10s\",\n      \"30s\",\n      \"1m\",\n      \"5m\",\n      \"15m\",\n      \"30m\",\n      \"1h\"\n    ]\n  },\n  \"timezone\": \"\",\n  \"title\": \"Daytona Sandbox Resource Monitoring\",\n  \"uid\": \"daytona-sandbox-monitoring\",\n  \"version\": 1,\n  \"weekStart\": \"\"\n}\n"
  },
  {
    "path": "examples/otel-dashboards/new-relic/README.md",
    "content": "# New Relic Dashboard for Daytona Sandbox Monitoring\n\nThis directory contains a pre-configured New Relic dashboard for monitoring Daytona Sandbox resources including CPU, Memory, and Disk utilization.\n\n## Dashboard Overview\n\nThe dashboard provides comprehensive monitoring across multiple pages:\n\n- **Resource Overview**: High-level view of all sandboxes with aggregate metrics\n- **CPU Details**: Detailed CPU utilization, limits, and heatmaps\n- **Memory Details**: Memory usage patterns and limits\n- **Disk Details**: Filesystem usage and space breakdown\n\n## Prerequisites\n\n- New Relic account with access to create dashboards\n- Your New Relic Account ID\n- `jq` installed (for the automated setup script)\n- New Relic CLI (`newrelic`) installed (optional, for CLI import)\n\n## Preparing the Dashboard\n\nBefore importing, you need to add your Account ID into the `dashboard.json`.\n\n### Quick Setup (One-Liner)\n\n```bash\njq --arg account_id \"YOUR_ACCOUNT_ID\" 'walk(if type == \"object\" and has(\"accountIds\") then .accountIds = [($account_id | tonumber)] else . end)' dashboard.json > dashboard-configured.json\n```\n\nReplace `YOUR_ACCOUNT_ID` with your actual numeric Account ID (e.g., `1234567`).\n\n**Example:**\n\n```bash\njq --arg account_id \"1234567\" 'walk(if type == \"object\" and has(\"accountIds\") then .accountIds = [($account_id | tonumber)] else . end)' dashboard.json > dashboard-configured.json\n```\n\nThis will create `dashboard-configured.json` ready for import.\n\n## Import via Web UI\n\n1. **Find Your Account ID**:\n   - Log in to [New Relic](https://one.newrelic.com)\n   - Click on your account name in the bottom left\n   - Your Account ID is displayed in the account dropdown\n\n2. **Prepare the Dashboard**:\n\n   ```bash\n   jq --arg account_id \"YOUR_ACCOUNT_ID\" 'walk(if type == \"object\" and has(\"accountIds\") then .accountIds = [($account_id | tonumber)] else . end)' dashboard.json > dashboard-configured.json\n   ```\n\n3. **Import the Dashboard**:\n   - Go to [New Relic Dashboards](https://one.newrelic.com/dashboards)\n   - Click **\"Import dashboard\"** in the top right\n   - Upload `dashboard-configured.json`\n   - Click **\"Import dashboard\"**\n\n4. **Verify**:\n   - The dashboard should now appear in your dashboards list\n   - Named: \"Daytona Sandbox Resource Monitoring - Multi-Service\"\n\n## Dashboard Widgets\n\n### Resource Overview Page\n\n- **Sandbox Count**: Total number of active sandboxes\n- **Critical Services**: Count of services exceeding resource thresholds\n- **Services Resource Overview**: Detailed table of all metrics per service\n- **CPU/Memory/Disk Utilization**: Time-series graphs per service\n- **Top Consumers**: Bar charts showing highest resource usage\n- **Resource Pressure Score**: Combined metric showing overall resource strain\n\n### Detailed Pages\n\nEach resource type (CPU, Memory, Disk) has a dedicated page with:\n\n- Time-series utilization graphs\n- Current values with threshold alerts\n- Usage in absolute units (cores, GB)\n- Limits and capacity information\n- Historical averages and peak values\n\n## Alert Thresholds\n\nThe dashboard includes pre-configured alert severities:\n\n- **CPU**: Warning at 70%, Critical at 85%\n- **Memory**: Warning at 80%, Critical at 90%\n- **Disk**: Warning at 75%, Critical at 85%\n\n## Metrics Tracked\n\nAll metrics are prefixed with `daytona.sandbox.`:\n\n- `cpu.utilization`: CPU usage percentage\n- `cpu.limit`: CPU cores limit\n- `memory.utilization`: Memory usage percentage\n- `memory.usage`: Memory used in bytes\n- `memory.limit`: Memory limit in bytes\n- `filesystem.utilization`: Disk usage percentage\n- `filesystem.usage`: Disk space used in bytes\n- `filesystem.available`: Available disk space in bytes\n- `filesystem.total`: Total disk space in bytes\n\n## Troubleshooting\n\n### Dashboard Import Fails\n\n1. Ensure JSON is valid: `jq . dashboard-configured.json`\n2. Verify Account ID is numeric (not a string)\n3. Check that you have dashboard creation permissions\n\n### jq Not Installed\n\nIf the command fails:\n\n- Install `jq`: `brew install jq` (macOS) or `apt-get install jq` (Linux)\n- Verify installation: `jq --version`\n\n## Customization\n\nTo modify the dashboard:\n\n1. Import it to New Relic\n2. Edit widgets through the UI\n3. Export the modified dashboard\n4. Replace `dashboard.json` with your customized version\n\n## Additional Resources\n\n- [New Relic Dashboard Documentation](https://docs.newrelic.com/docs/query-your-data/explore-query-data/dashboards/introduction-dashboards/)\n- [NRQL Query Language](https://docs.newrelic.com/docs/query-your-data/nrql-new-relic-query-language/get-started/introduction-nrql-new-relics-query-language/)\n- [New Relic CLI](https://github.com/newrelic/newrelic-cli)\n"
  },
  {
    "path": "examples/otel-dashboards/new-relic/dashboard.json",
    "content": "{\n  \"name\": \"Daytona Sandbox Resource Monitoring - Multi-Service\",\n  \"description\": \"Comprehensive CPU, Memory, and Disk monitoring for Daytona Sandboxes\",\n  \"permissions\": \"PUBLIC_READ_WRITE\",\n  \"pages\": [\n    {\n      \"name\": \"Resource Overview\",\n      \"description\": \"High-level overview of all Daytona Sandbox\",\n      \"widgets\": [\n        {\n          \"title\": \"Sandbox Count\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 1,\n            \"width\": 2,\n            \"height\": 2\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.billboard\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT uniqueCount(service.name) as 'Active Sandboxes' FROM Metric WHERE service.name LIKE 'sandbox-%' SINCE 5 minutes ago\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Critical Services\",\n          \"layout\": {\n            \"column\": 3,\n            \"row\": 1,\n            \"width\": 2,\n            \"height\": 2\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.billboard\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT uniqueCount(service.name) as 'Over Threshold' FROM Metric WHERE daytona.sandbox.cpu.utilization > 80 OR daytona.sandbox.memory.utilization > 80 OR daytona.sandbox.filesystem.utilization > 80 SINCE 5 minutes ago\"\n              }\n            ],\n            \"thresholds\": [\n              {\n                \"alertSeverity\": \"WARNING\",\n                \"value\": 1\n              },\n              {\n                \"alertSeverity\": \"CRITICAL\",\n                \"value\": 3\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Services Resource Overview\",\n          \"layout\": {\n            \"column\": 5,\n            \"row\": 1,\n            \"width\": 8,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.table\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT latest(service.name) as 'Service', latest(daytona.sandbox.cpu.utilization) as 'CPU %', latest(daytona.sandbox.cpu.`limit`) as 'CPU Cores', latest(daytona.sandbox.memory.utilization) as 'Memory %', latest(daytona.sandbox.memory.usage) / 1073741824 as 'Memory Used (GB)', latest(daytona.sandbox.memory.`limit`) / 1073741824 as 'Memory Limit (GB)', latest(daytona.sandbox.filesystem.utilization) as 'Disk %', latest(daytona.sandbox.filesystem.usage) / 1073741824 as 'Disk Used (GB)', latest(daytona.sandbox.filesystem.total) / 1073741824 as 'Disk Total (GB)' FROM Metric FACET service.name SINCE 5 minutes ago LIMIT 100\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"CPU Utilization by Service\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 3,\n            \"width\": 4,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.line\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.cpu.utilization) as 'CPU %' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ],\n            \"yAxisLeft\": {\n              \"max\": 100,\n              \"min\": 0\n            }\n          }\n        },\n        {\n          \"title\": \"Memory Utilization by Service\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 6,\n            \"width\": 4,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.line\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.memory.utilization) as 'Memory %' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ],\n            \"yAxisLeft\": {\n              \"max\": 100,\n              \"min\": 0\n            }\n          }\n        },\n        {\n          \"title\": \"Disk Utilization by Service\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 9,\n            \"width\": 4,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.line\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.filesystem.utilization) as 'Disk %' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ],\n            \"yAxisLeft\": {\n              \"max\": 100,\n              \"min\": 0\n            }\n          }\n        },\n        {\n          \"title\": \"Top CPU Consumers\",\n          \"layout\": {\n            \"column\": 5,\n            \"row\": 5,\n            \"width\": 4,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.bar\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.cpu.utilization) as 'Avg CPU %' FROM Metric FACET service.name SINCE 1 hour ago LIMIT 10\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Top Memory Consumers\",\n          \"layout\": {\n            \"column\": 9,\n            \"row\": 5,\n            \"width\": 4,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.bar\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.memory.utilization) as 'Avg Memory %' FROM Metric FACET service.name SINCE 1 hour ago LIMIT 10\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Top Disk Consumers\",\n          \"layout\": {\n            \"column\": 5,\n            \"row\": 8,\n            \"width\": 4,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.bar\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.filesystem.utilization) as 'Avg Disk %' FROM Metric FACET service.name SINCE 1 hour ago LIMIT 10\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Services Over Threshold\",\n          \"layout\": {\n            \"column\": 9,\n            \"row\": 8,\n            \"width\": 4,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.table\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT latest(service.name) as 'Service', latest(daytona.sandbox.cpu.utilization) as 'CPU %', latest(daytona.sandbox.memory.utilization) as 'Memory %', latest(daytona.sandbox.filesystem.utilization) as 'Disk %' FROM Metric WHERE daytona.sandbox.cpu.utilization > 80 OR daytona.sandbox.memory.utilization > 80 OR daytona.sandbox.filesystem.utilization > 80 FACET service.name SINCE 5 minutes ago\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Resource Pressure Score\",\n          \"layout\": {\n            \"column\": 5,\n            \"row\": 11,\n            \"width\": 8,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.line\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT (average(daytona.sandbox.cpu.utilization) * 0.33) + (average(daytona.sandbox.memory.utilization) * 0.33) + (average(daytona.sandbox.filesystem.utilization) * 0.34) as 'Resource Pressure Score' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ],\n            \"yAxisLeft\": {\n              \"max\": 100,\n              \"min\": 0\n            }\n          }\n        }\n      ]\n    },\n    {\n      \"name\": \"CPU Details\",\n      \"description\": \"Detailed CPU metrics\",\n      \"widgets\": [\n        {\n          \"title\": \"CPU Utilization Timeseries\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 1,\n            \"width\": 8,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.line\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.cpu.utilization) as 'CPU %' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ],\n            \"yAxisLeft\": {\n              \"max\": 100,\n              \"min\": 0\n            }\n          }\n        },\n        {\n          \"title\": \"Current CPU by Service\",\n          \"layout\": {\n            \"column\": 9,\n            \"row\": 1,\n            \"width\": 4,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.billboard\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT latest(daytona.sandbox.cpu.utilization) as 'CPU %' FROM Metric FACET service.name SINCE 1 minute ago\"\n              }\n            ],\n            \"thresholds\": [\n              {\n                \"alertSeverity\": \"WARNING\",\n                \"value\": 70\n              },\n              {\n                \"alertSeverity\": \"CRITICAL\",\n                \"value\": 85\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"CPU Limit by Service\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 5,\n            \"width\": 6,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.table\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT latest(daytona.sandbox.cpu.`limit`) as 'CPU Cores Limit', average(daytona.sandbox.cpu.utilization) as 'Avg CPU %', max(daytona.sandbox.cpu.utilization) as 'Peak CPU %' FROM Metric FACET service.name SINCE 1 hour ago\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"CPU Usage Heatmap\",\n          \"layout\": {\n            \"column\": 7,\n            \"row\": 5,\n            \"width\": 6,\n            \"height\": 3\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.heatmap\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT histogram(daytona.sandbox.cpu.utilization, 10, 10) FROM Metric FACET service.name SINCE 1 hour ago\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    {\n      \"name\": \"Memory Details\",\n      \"description\": \"Detailed memory metrics\",\n      \"widgets\": [\n        {\n          \"title\": \"Memory Utilization Timeseries\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 1,\n            \"width\": 8,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.line\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.memory.utilization) as 'Memory %' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ],\n            \"yAxisLeft\": {\n              \"max\": 100,\n              \"min\": 0\n            }\n          }\n        },\n        {\n          \"title\": \"Current Memory by Service\",\n          \"layout\": {\n            \"column\": 9,\n            \"row\": 1,\n            \"width\": 4,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.billboard\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT latest(daytona.sandbox.memory.utilization) as 'Memory %' FROM Metric FACET service.name SINCE 1 minute ago\"\n              }\n            ],\n            \"thresholds\": [\n              {\n                \"alertSeverity\": \"WARNING\",\n                \"value\": 80\n              },\n              {\n                \"alertSeverity\": \"CRITICAL\",\n                \"value\": 90\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Memory Usage in GB\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 5,\n            \"width\": 6,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.area\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.memory.usage) / 1073741824 as 'Used GB' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Memory Limits and Usage\",\n          \"layout\": {\n            \"column\": 7,\n            \"row\": 5,\n            \"width\": 6,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.table\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT latest(daytona.sandbox.memory.usage) / 1073741824 as 'Used (GB)', latest(daytona.sandbox.memory.`limit`) / 1073741824 as 'Limit (GB)', average(daytona.sandbox.memory.utilization) as 'Avg %', max(daytona.sandbox.memory.utilization) as 'Peak %' FROM Metric FACET service.name SINCE 1 hour ago\"\n              }\n            ]\n          }\n        }\n      ]\n    },\n    {\n      \"name\": \"Disk Details\",\n      \"description\": \"Detailed filesystem/disk metrics\",\n      \"widgets\": [\n        {\n          \"title\": \"Disk Utilization Timeseries\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 1,\n            \"width\": 8,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.line\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.filesystem.utilization) as 'Disk %' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ],\n            \"yAxisLeft\": {\n              \"max\": 100,\n              \"min\": 0\n            }\n          }\n        },\n        {\n          \"title\": \"Current Disk by Service\",\n          \"layout\": {\n            \"column\": 9,\n            \"row\": 1,\n            \"width\": 4,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.billboard\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT latest(daytona.sandbox.filesystem.utilization) as 'Disk %' FROM Metric FACET service.name SINCE 1 minute ago\"\n              }\n            ],\n            \"thresholds\": [\n              {\n                \"alertSeverity\": \"WARNING\",\n                \"value\": 75\n              },\n              {\n                \"alertSeverity\": \"CRITICAL\",\n                \"value\": 85\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Disk Usage in GB\",\n          \"layout\": {\n            \"column\": 1,\n            \"row\": 5,\n            \"width\": 6,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.area\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT average(daytona.sandbox.filesystem.usage) / 1073741824 as 'Used GB', average(daytona.sandbox.filesystem.total) / 1073741824 as 'Total GB' FROM Metric FACET service.name TIMESERIES AUTO\"\n              }\n            ]\n          }\n        },\n        {\n          \"title\": \"Disk Space Breakdown\",\n          \"layout\": {\n            \"column\": 7,\n            \"row\": 5,\n            \"width\": 6,\n            \"height\": 4\n          },\n          \"linkedEntityGuids\": null,\n          \"visualization\": {\n            \"id\": \"viz.table\"\n          },\n          \"rawConfiguration\": {\n            \"nrqlQueries\": [\n              {\n                \"accountIds\": [],\n                \"query\": \"SELECT latest(daytona.sandbox.filesystem.usage) / 1073741824 as 'Used (GB)', latest(daytona.sandbox.filesystem.available) / 1073741824 as 'Available (GB)', latest(daytona.sandbox.filesystem.total) / 1073741824 as 'Total (GB)', average(daytona.sandbox.filesystem.utilization) as 'Avg %', max(daytona.sandbox.filesystem.utilization) as 'Peak %' FROM Metric FACET service.name SINCE 1 hour ago\"\n              }\n            ]\n          }\n        }\n      ]\n    }\n  ]\n}\n"
  },
  {
    "path": "examples/python/auto-archive/_async/auto_archive.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona, CreateSandboxFromSnapshotParams\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        # Default interval\n        sandbox1 = await daytona.create()\n        print(sandbox1.auto_archive_interval)\n\n        # Set interval to 1 hour\n        await sandbox1.set_auto_archive_interval(60)\n        print(sandbox1.auto_archive_interval)\n\n        # Max interval\n        sandbox2 = await daytona.create(params=CreateSandboxFromSnapshotParams(auto_archive_interval=0))\n        print(sandbox2.auto_archive_interval)\n\n        # 1 day interval\n        sandbox3 = await daytona.create(params=CreateSandboxFromSnapshotParams(auto_archive_interval=1440))\n        print(sandbox3.auto_archive_interval)\n\n        await sandbox1.delete()\n        await sandbox2.delete()\n        await sandbox3.delete()\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/auto-archive/auto_archive.py",
    "content": "from daytona import CreateSandboxFromSnapshotParams, Daytona\n\n\ndef main():\n    daytona = Daytona()\n\n    # Default interval\n    sandbox1 = daytona.create()\n    print(sandbox1.auto_archive_interval)\n\n    # Set interval to 1 hour\n    sandbox1.set_auto_archive_interval(60)\n    print(sandbox1.auto_archive_interval)\n\n    # Max interval\n    sandbox2 = daytona.create(params=CreateSandboxFromSnapshotParams(auto_archive_interval=0))\n    print(sandbox2.auto_archive_interval)\n\n    # 1 day interval\n    sandbox3 = daytona.create(params=CreateSandboxFromSnapshotParams(auto_archive_interval=1440))\n    print(sandbox3.auto_archive_interval)\n\n    sandbox1.delete()\n    sandbox2.delete()\n    sandbox3.delete()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/auto-delete/_async/auto_delete.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona, CreateSandboxFromSnapshotParams\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        # Auto-delete is disabled by default\n        sandbox1 = await daytona.create()\n        print(sandbox1.auto_delete_interval)\n\n        # Auto-delete after the Sandbox has been stopped for 1 hour\n        await sandbox1.set_auto_delete_interval(60)\n        print(sandbox1.auto_delete_interval)\n\n        # Delete immediately upon stopping\n        await sandbox1.set_auto_delete_interval(0)\n        print(sandbox1.auto_delete_interval)\n\n        # Disable auto-delete\n        await sandbox1.set_auto_delete_interval(-1)\n        print(sandbox1.auto_delete_interval)\n\n        # Auto-delete after the Sandbox has been stopped for 1 day\n        sandbox2 = await daytona.create(params=CreateSandboxFromSnapshotParams(auto_delete_interval=1440))\n        print(sandbox2.auto_delete_interval)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/auto-delete/auto_delete.py",
    "content": "from daytona import CreateSandboxFromSnapshotParams, Daytona\n\n\ndef main():\n    daytona = Daytona()\n\n    # Auto-delete is disabled by default\n    sandbox1 = daytona.create()\n    print(sandbox1.auto_delete_interval)\n\n    # Auto-delete after the Sandbox has been stopped for 1 hour\n    sandbox1.set_auto_delete_interval(60)\n    print(sandbox1.auto_delete_interval)\n\n    # Delete immediately upon stopping\n    sandbox1.set_auto_delete_interval(0)\n    print(sandbox1.auto_delete_interval)\n\n    # Disable auto-delete\n    sandbox1.set_auto_delete_interval(-1)\n    print(sandbox1.auto_delete_interval)\n\n    # Auto-delete after the Sandbox has been stopped for 1 day\n    sandbox2 = daytona.create(params=CreateSandboxFromSnapshotParams(auto_delete_interval=1440))\n    print(sandbox2.auto_delete_interval)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/charts/_async/main.py",
    "content": "import asyncio\nimport base64\nimport os\nimport time\n\nfrom daytona import (\n    AsyncDaytona,\n    BarChart,\n    BoxAndWhiskerChart,\n    Chart,\n    ChartType,\n    CompositeChart,\n    CreateSandboxFromImageParams,\n    Image,\n    LineChart,\n    PieChart,\n    ScatterChart,\n)\n\ncode = \"\"\"\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Sample data\nx = np.linspace(0, 10, 30)\ny = np.sin(x)\ncategories = ['A', 'B', 'C', 'D', 'E']\nvalues = [40, 63, 15, 25, 8]\nbox_data = [np.random.normal(0, std, 100) for std in range(1, 6)]\n\n# 1. Line Chart\nplt.figure(figsize=(8, 5))\nplt.plot(x, y, 'b-', linewidth=2)\nplt.title('Line Chart')\nplt.xlabel('X-axis (seconds)')\nplt.ylabel('Y-axis (amplitude)')\nplt.grid(True)\nplt.show()\n\n# 2. Scatter Plot\nplt.figure(figsize=(8, 5))\nplt.scatter(x, y, c=y, cmap='viridis', s=100*np.abs(y))\nplt.colorbar(label='Value (normalized)')\nplt.title('Scatter Plot')\nplt.xlabel('X-axis (time in seconds)')\nplt.ylabel('Y-axis (signal strength)')\nplt.show()\n\n# 3. Bar Chart\nplt.figure(figsize=(10, 6))\nplt.bar(categories, values, color='skyblue', edgecolor='navy')\nplt.title('Bar Chart')\nplt.xlabel('Categories')\nplt.ylabel('Values (count)')\nplt.show()\n\n# 4. Pie Chart\nplt.figure(figsize=(8, 8))\nplt.pie(values, labels=categories,\n        autopct='%1.1f%%',\n        colors=plt.cm.Set3.colors, shadow=True, startangle=90)\nplt.title('Pie Chart (Distribution in %)')\nplt.axis('equal')\nplt.legend()\nplt.show()\n\n# 5. Box and Whisker Plot\nplt.figure(figsize=(10, 6))\nplt.boxplot(box_data, patch_artist=True, \n            boxprops=dict(facecolor='lightblue'),\n            medianprops=dict(color='red', linewidth=2))\nplt.title('Box and Whisker Plot')\nplt.xlabel('Groups (Experiment IDs)')\nplt.ylabel('Values (measurement units)')\nplt.grid(True, linestyle='--', alpha=0.7)\nplt.show()\n\"\"\"\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        sandbox = await daytona.create(\n            CreateSandboxFromImageParams(\n                image=Image.debian_slim(\"3.13\").pip_install(\"matplotlib\"),\n            ),\n            on_snapshot_create_logs=print,\n        )\n        response = await sandbox.process.code_run(code)\n\n        if response.exit_code != 0:\n            print(f\"Error: {response.exit_code} {response.result}\")\n        else:\n            if response.artifacts and response.artifacts.charts:\n                for chart in response.artifacts.charts:\n                    if chart.png:\n                        img_data = base64.b64decode(chart.png)\n                    else:\n                        print(f\"No PNG data for chart: '{chart.title}'\")\n                        continue\n                    script_dir = os.path.dirname(os.path.abspath(__file__))\n                    if chart.title:\n                        filename = os.path.join(script_dir, f\"{chart.title}.png\")\n                    else:\n                        filename = os.path.join(script_dir, f\"chart_{time.time()}.png\")\n                    with open(filename, \"wb\") as f:\n                        _ = f.write(img_data)\n                    print(f\"Image saved as: {filename}\")\n\n                    print_chart(chart)\n            else:\n                print(\"No charts found\")\n\n        await daytona.delete(sandbox)\n\n\ndef print_chart(chart: Chart):\n    print(f\"Type: {chart.type}\")\n    print(f\"Title: {chart.title}\")\n\n    if chart.type == ChartType.LINE and isinstance(chart, LineChart):\n        print(f\"X Label: {chart.x_label}\")\n        print(f\"Y Label: {chart.y_label}\")\n        print(f\"X Ticks: {chart.x_ticks}\")\n        print(f\"X Tick Labels: {chart.x_tick_labels}\")\n        print(f\"X Scale: {chart.x_scale}\")\n        print(f\"Y Ticks: {chart.y_ticks}\")\n        print(f\"Y Tick Labels: {chart.y_tick_labels}\")\n        print(f\"Y Scale: {chart.y_scale}\")\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tPoints: {element.points}\")\n    elif chart.type == ChartType.SCATTER and isinstance(chart, ScatterChart):\n        print(f\"X Label: {chart.x_label}\")\n        print(f\"Y Label: {chart.y_label}\")\n        print(f\"X Ticks: {chart.x_ticks}\")\n        print(f\"X Tick Labels: {chart.x_tick_labels}\")\n        print(f\"X Scale: {chart.x_scale}\")\n        print(f\"Y Ticks: {chart.y_ticks}\")\n        print(f\"Y Tick Labels: {chart.y_tick_labels}\")\n        print(f\"Y Scale: {chart.y_scale}\")\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tPoints: {element.points}\")\n    elif chart.type == ChartType.BAR and isinstance(chart, BarChart):\n        print(f\"X Label: {chart.x_label}\")\n        print(f\"Y Label: {chart.y_label}\")\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tGroup: {element.group}\")\n            print(f\"\\tValue: {element.value}\")\n    elif chart.type == ChartType.PIE and isinstance(chart, PieChart):\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tAngle: {element.angle}\")\n            print(f\"\\tRadius: {element.radius}\")\n            print(f\"\\tAutopct: {element.autopct}\")\n    elif chart.type == ChartType.BOX_AND_WHISKER and isinstance(chart, BoxAndWhiskerChart):\n        print(f\"X Label: {chart.x_label}\")\n        print(f\"Y Label: {chart.y_label}\")\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tMin: {element.min}\")\n            print(f\"\\tFirst Quartile: {element.first_quartile}\")\n            print(f\"\\tMedian: {element.median}\")\n            print(f\"\\tThird Quartile: {element.third_quartile}\")\n            print(f\"\\tMax: {element.max}\")\n            print(f\"\\tOutliers: {element.outliers}\")\n    elif chart.type == ChartType.COMPOSITE_CHART and isinstance(chart, CompositeChart):\n        print(\"Elements:\\n\")\n        for element in chart.elements:\n            print_chart(element)\n    print()\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/charts/main.py",
    "content": "import base64\nimport os\nimport time\n\nfrom daytona import (\n    BarChart,\n    BoxAndWhiskerChart,\n    Chart,\n    ChartType,\n    CompositeChart,\n    CreateSandboxFromImageParams,\n    Daytona,\n    Image,\n    LineChart,\n    PieChart,\n    ScatterChart,\n)\n\ncode = \"\"\"\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Sample data\nx = np.linspace(0, 10, 30)\ny = np.sin(x)\ncategories = ['A', 'B', 'C', 'D', 'E']\nvalues = [40, 63, 15, 25, 8]\nbox_data = [np.random.normal(0, std, 100) for std in range(1, 6)]\n\n# 1. Line Chart\nplt.figure(figsize=(8, 5))\nplt.plot(x, y, 'b-', linewidth=2)\nplt.title('Line Chart')\nplt.xlabel('X-axis (seconds)')\nplt.ylabel('Y-axis (amplitude)')\nplt.grid(True)\nplt.show()\n\n# 2. Scatter Plot\nplt.figure(figsize=(8, 5))\nplt.scatter(x, y, c=y, cmap='viridis', s=100*np.abs(y))\nplt.colorbar(label='Value (normalized)')\nplt.title('Scatter Plot')\nplt.xlabel('X-axis (time in seconds)')\nplt.ylabel('Y-axis (signal strength)')\nplt.show()\n\n# 3. Bar Chart\nplt.figure(figsize=(10, 6))\nplt.bar(categories, values, color='skyblue', edgecolor='navy')\nplt.title('Bar Chart')\nplt.xlabel('Categories')\nplt.ylabel('Values (count)')\nplt.show()\n\n# 4. Pie Chart\nplt.figure(figsize=(8, 8))\nplt.pie(values, labels=categories,\n        autopct='%1.1f%%',\n        colors=plt.cm.Set3.colors, shadow=True, startangle=90)\nplt.title('Pie Chart (Distribution in %)')\nplt.axis('equal')\nplt.legend()\nplt.show()\n\n# 5. Box and Whisker Plot\nplt.figure(figsize=(10, 6))\nplt.boxplot(box_data, patch_artist=True, \n            boxprops=dict(facecolor='lightblue'),\n            medianprops=dict(color='red', linewidth=2))\nplt.title('Box and Whisker Plot')\nplt.xlabel('Groups (Experiment IDs)')\nplt.ylabel('Values (measurement units)')\nplt.grid(True, linestyle='--', alpha=0.7)\nplt.show()\n\"\"\"\n\n\ndef main():\n    daytona = Daytona()\n    sandbox = daytona.create(\n        CreateSandboxFromImageParams(\n            image=Image.debian_slim(\"3.13\").pip_install(\"matplotlib\"),\n        ),\n        on_snapshot_create_logs=print,\n    )\n    response = sandbox.process.code_run(code)\n\n    if response.exit_code != 0:\n        print(f\"Error: {response.exit_code} {response.result}\")\n    else:\n        if response.artifacts and response.artifacts.charts:\n            for chart in response.artifacts.charts:\n                if chart.png:\n                    img_data = base64.b64decode(chart.png)\n                else:\n                    print(f\"No PNG data for chart: '{chart.title}'\")\n                    continue\n                script_dir = os.path.dirname(os.path.abspath(__file__))\n                if chart.title:\n                    filename = os.path.join(script_dir, f\"{chart.title}.png\")\n                else:\n                    filename = os.path.join(script_dir, f\"chart_{time.time()}.png\")\n                with open(filename, \"wb\") as f:\n                    _ = f.write(img_data)\n                print(f\"Image saved as: {filename}\")\n\n                print_chart(chart)\n        else:\n            print(\"No charts found\")\n\n    daytona.delete(sandbox)\n\n\ndef print_chart(chart: Chart):\n    print(f\"Type: {chart.type}\")\n    print(f\"Title: {chart.title}\")\n\n    if chart.type == ChartType.LINE and isinstance(chart, LineChart):\n        print(f\"X Label: {chart.x_label}\")\n        print(f\"Y Label: {chart.y_label}\")\n        print(f\"X Ticks: {chart.x_ticks}\")\n        print(f\"X Tick Labels: {chart.x_tick_labels}\")\n        print(f\"X Scale: {chart.x_scale}\")\n        print(f\"Y Ticks: {chart.y_ticks}\")\n        print(f\"Y Tick Labels: {chart.y_tick_labels}\")\n        print(f\"Y Scale: {chart.y_scale}\")\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tPoints: {element.points}\")\n    elif chart.type == ChartType.SCATTER and isinstance(chart, ScatterChart):\n        print(f\"X Label: {chart.x_label}\")\n        print(f\"Y Label: {chart.y_label}\")\n        print(f\"X Ticks: {chart.x_ticks}\")\n        print(f\"X Tick Labels: {chart.x_tick_labels}\")\n        print(f\"X Scale: {chart.x_scale}\")\n        print(f\"Y Ticks: {chart.y_ticks}\")\n        print(f\"Y Tick Labels: {chart.y_tick_labels}\")\n        print(f\"Y Scale: {chart.y_scale}\")\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tPoints: {element.points}\")\n    elif chart.type == ChartType.BAR and isinstance(chart, BarChart):\n        print(f\"X Label: {chart.x_label}\")\n        print(f\"Y Label: {chart.y_label}\")\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tGroup: {element.group}\")\n            print(f\"\\tValue: {element.value}\")\n    elif chart.type == ChartType.PIE and isinstance(chart, PieChart):\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tAngle: {element.angle}\")\n            print(f\"\\tRadius: {element.radius}\")\n            print(f\"\\tAutopct: {element.autopct}\")\n    elif chart.type == ChartType.BOX_AND_WHISKER and isinstance(chart, BoxAndWhiskerChart):\n        print(f\"X Label: {chart.x_label}\")\n        print(f\"Y Label: {chart.y_label}\")\n        print(\"Elements:\")\n        for element in chart.elements:\n            print(f\"\\n\\tLabel: {element.label}\")\n            print(f\"\\tMin: {element.min}\")\n            print(f\"\\tFirst Quartile: {element.first_quartile}\")\n            print(f\"\\tMedian: {element.median}\")\n            print(f\"\\tThird Quartile: {element.third_quartile}\")\n            print(f\"\\tMax: {element.max}\")\n            print(f\"\\tOutliers: {element.outliers}\")\n    elif chart.type == ChartType.COMPOSITE_CHART and isinstance(chart, CompositeChart):\n        print(\"Elements:\\n\")\n        for element in chart.elements:\n            print_chart(element)\n    print()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/declarative-image/_async/main.py",
    "content": "import asyncio\nimport time\n\nfrom daytona import (\n    AsyncDaytona,\n    CreateSandboxFromImageParams,\n    CreateSandboxFromSnapshotParams,\n    CreateSnapshotParams,\n    Image,\n    Resources,\n)\n\n\nasync def main():\n    daytona = AsyncDaytona()\n\n    try:\n        # Generate unique name for the snapshot to avoid conflicts\n        snapshot_name = f\"python-example:{int(time.time())}\"\n\n        # Create local file with some data and add it to the image\n        with open(\"file_example.txt\", \"w\") as f:\n            _ = f.write(\"Hello, World!\")\n\n        # Create a Python image with common data science packages\n        image = (\n            Image.debian_slim(\"3.12\")\n            .pip_install([\"numpy\", \"pandas\", \"matplotlib\", \"scipy\", \"scikit-learn\", \"jupyter\"])\n            .run_commands(\n                \"apt-get update && apt-get install -y git\",\n                \"groupadd -r daytona && useradd -r -g daytona -m daytona\",\n                \"mkdir -p /home/daytona/workspace\",\n            )\n            .dockerfile_commands([\"USER daytona\"])\n            .workdir(\"/home/daytona/workspace\")\n            .env({\"MY_ENV_VAR\": \"My Environment Variable\"})\n            .add_local_file(\"file_example.txt\", \"/home/daytona/workspace/file_example.txt\")\n        )\n\n        # Create the image\n        print(f\"=== Creating Snapshot: {snapshot_name} ===\")\n        _ = await daytona.snapshot.create(\n            CreateSnapshotParams(\n                name=snapshot_name,\n                image=image,\n                resources=Resources(\n                    cpu=1,\n                    memory=1,\n                    disk=3,\n                ),\n            ),\n            on_logs=print,\n        )\n\n        # Create first sandbox using the pre-built image\n        print(\"\\n=== Creating Sandbox from Pre-built Image ===\")\n        sandbox1 = await daytona.create(CreateSandboxFromSnapshotParams(snapshot=snapshot_name))\n\n        try:\n            # Verify the first sandbox environment\n            print(\"Verifying sandbox from pre-built image:\")\n            response = await sandbox1.process.exec(\"python --version && pip list\")\n            print(\"Python environment:\")\n            print(response.result)\n\n            # Verify the file was added to the image\n            response = await sandbox1.process.exec(\"cat file_example.txt\")\n            print(\"File content:\")\n            print(response.result)\n        finally:\n            # Clean up first sandbox\n            await daytona.delete(sandbox1)\n\n        # Create second sandbox with a new dynamic image\n        print(\"=== Creating Sandbox with Dynamic Image ===\")\n\n        # Define a new dynamic image for the second sandbox\n        dynamic_image = (\n            Image.debian_slim(\"3.11\")\n            .pip_install([\"pytest\", \"pytest-cov\", \"black\", \"isort\", \"mypy\", \"ruff\"])\n            .run_commands(\"apt-get update && apt-get install -y git\", \"mkdir -p /home/daytona/project\")\n            .workdir(\"/home/daytona/project\")\n            .env({\"ENV_VAR\": \"My Environment Variable\"})\n        )\n\n        # Create sandbox with the dynamic image\n        sandbox2 = await daytona.create(\n            CreateSandboxFromImageParams(\n                image=dynamic_image,\n            ),\n            timeout=0,\n            on_snapshot_create_logs=print,\n        )\n\n        try:\n            # Verify the second sandbox environment\n            print(\"Verifying sandbox with dynamic image:\")\n            response = await sandbox2.process.exec(\"pip list | grep -E 'pytest|black|isort|mypy|ruff'\")\n            print(\"Development tools:\")\n            print(response.result)\n        finally:\n            # Clean up second sandbox\n            await daytona.delete(sandbox2)\n    finally:\n        await daytona.close()\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/declarative-image/main.py",
    "content": "import time\n\nfrom daytona import (\n    CreateSandboxFromImageParams,\n    CreateSandboxFromSnapshotParams,\n    CreateSnapshotParams,\n    Daytona,\n    Image,\n    Resources,\n)\n\n\ndef main():\n    daytona = Daytona()\n\n    # Generate unique name for the snapshot to avoid conflicts\n    snapshot_name = f\"python-example:{int(time.time())}\"\n\n    # Create local file with some data and add it to the image\n    with open(\"file_example.txt\", \"w\") as f:\n        _ = f.write(\"Hello, World!\")\n\n    # Create a Python image with common data science packages\n    image = (\n        Image.debian_slim(\"3.12\")\n        .pip_install([\"numpy\", \"pandas\", \"matplotlib\", \"scipy\", \"scikit-learn\", \"jupyter\"])\n        .run_commands(\n            \"apt-get update && apt-get install -y git\",\n            \"groupadd -r daytona && useradd -r -g daytona -m daytona\",\n            \"mkdir -p /home/daytona/workspace\",\n        )\n        .workdir(\"/home/daytona/workspace\")\n        .env({\"MY_ENV_VAR\": \"My Environment Variable\"})\n        .add_local_file(\"file_example.txt\", \"/home/daytona/workspace/file_example.txt\")\n    )\n\n    # Create the snapshot\n    print(f\"=== Creating Snapshot: {snapshot_name} ===\")\n    _ = daytona.snapshot.create(\n        CreateSnapshotParams(\n            name=snapshot_name,\n            image=image,\n            resources=Resources(\n                cpu=1,\n                memory=1,\n                disk=3,\n            ),\n        ),\n        on_logs=print,\n    )\n\n    # Create first sandbox using the pre-built image\n    print(\"\\n=== Creating Sandbox from Pre-built Image ===\")\n    sandbox1 = daytona.create(CreateSandboxFromSnapshotParams(snapshot=snapshot_name))\n\n    try:\n        # Verify the first sandbox environment\n        print(\"Verifying sandbox from pre-built image:\")\n        response = sandbox1.process.exec(\"python --version && pip list\")\n        print(\"Python environment:\")\n        print(response.result)\n\n        # Verify the file was added to the image\n        response = sandbox1.process.exec(\"cat file_example.txt\")\n        print(\"File content:\")\n        print(response.result)\n    finally:\n        # Clean up first sandbox\n        daytona.delete(sandbox1)\n\n    # Create second sandbox with a new dynamic image\n    print(\"=== Creating Sandbox with Dynamic Image ===\")\n\n    # Define a new dynamic image for the second sandbox\n    dynamic_image = (\n        Image.debian_slim(\"3.11\")\n        .pip_install([\"pytest\", \"pytest-cov\", \"black\", \"isort\", \"mypy\", \"ruff\"])\n        .run_commands(\"apt-get update && apt-get install -y git\", \"mkdir -p /home/daytona/project\")\n        .workdir(\"/home/daytona/project\")\n        .env({\"ENV_VAR\": \"My Environment Variable\"})\n    )\n\n    # Create sandbox with the dynamic image\n    sandbox2 = daytona.create(\n        CreateSandboxFromImageParams(\n            image=dynamic_image,\n        ),\n        timeout=0,\n        on_snapshot_create_logs=print,\n    )\n\n    try:\n        # Verify the second sandbox environment\n        print(\"Verifying sandbox with dynamic image:\")\n        response = sandbox2.process.exec(\"pip list | grep -E 'pytest|black|isort|mypy|ruff'\")\n        print(\"Development tools:\")\n        print(response.result)\n    finally:\n        # Clean up second sandbox\n        daytona.delete(sandbox2)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/exec-command/_async/exec.py",
    "content": "import asyncio\n\nfrom daytona import (\n    AsyncDaytona,\n    AsyncSandbox,\n    CreateSandboxFromImageParams,\n    DaytonaTimeoutError,\n    ExecutionError,\n    OutputMessage,\n    Resources,\n)\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        params = CreateSandboxFromImageParams(\n            image=\"python:3.9.23-slim\",\n            language=\"python\",\n            resources=Resources(\n                cpu=1,\n                memory=1,\n                disk=3,\n            ),\n        )\n        sandbox = await daytona.create(params, timeout=150, on_snapshot_create_logs=print)\n\n        try:\n            # Run the code securely inside the sandbox\n            response = await sandbox.process.code_run('print(\"Hello World!\")')\n            if response.exit_code != 0:\n                print(f\"Error: {response.exit_code} {response.result}\")\n            else:\n                print(response.result)\n\n            # Execute an os command in the sandbox\n            response = await sandbox.process.exec('echo \"Hello World from exec!\"', timeout=10)\n            if response.exit_code != 0:\n                print(f\"Error: {response.exit_code} {response.result}\")\n            else:\n                print(response.result)\n\n            await stateful_code_interpreter(sandbox)\n        finally:\n            await daytona.delete(sandbox)\n\n\nasync def stateful_code_interpreter(sandbox: AsyncSandbox):\n    def handle_stdout(message: OutputMessage):\n        print(f\"[STDOUT] {message.output}\")\n\n    def handle_stderr(message: OutputMessage):\n        print(f\"[STDERR] {message.output}\")\n\n    def handle_error(error: ExecutionError):\n        print(f\"[ERROR] {error.name}: {error.value}\\n{error.traceback}\")\n\n    print(\"\\n\" + \"=\" * 60)\n    print(\"Stateful Code Interpreter\")\n    print(\"=\" * 60)\n\n    print(\"=\" * 10 + \" Statefulness in the default context \" + \"=\" * 10)\n    result = await sandbox.code_interpreter.run_code(\"counter = 1\\nprint(f'Initialized counter = {counter}')\")\n    print(f\"[STDOUT] {result.stdout}\")\n\n    _ = await sandbox.code_interpreter.run_code(\n        \"counter += 1\\nprint(f'Counter after second call = {counter}')\",\n        on_stdout=handle_stdout,\n        on_stderr=handle_stderr,\n        on_error=handle_error,\n    )\n\n    print(\"=\" * 10 + \" Context isolation \" + \"=\" * 10)\n    ctx = await sandbox.code_interpreter.create_context()\n    try:\n        _ = await sandbox.code_interpreter.run_code(\n            \"value = 'stored in isolated context'\\nprint(f'Isolated context value: {value}')\",\n            context=ctx,\n            on_stdout=handle_stdout,\n            on_stderr=handle_stderr,\n            on_error=handle_error,\n        )\n\n        print(\"-\" * 3 + \" Print value from same context \" + \"-\" * 3)\n        ctx_result = await sandbox.code_interpreter.run_code(\n            \"print(f'Value still available: {value}')\",\n            context=ctx,\n        )\n        print(f\"[STDOUT] {ctx_result.stdout}\")\n\n        print(\"-\" * 3 + \" Print value from different context \" + \"-\" * 3)\n        _ = await sandbox.code_interpreter.run_code(\n            \"print(value)\",\n            on_stdout=handle_stdout,\n            on_stderr=handle_stderr,\n            on_error=handle_error,\n        )\n    finally:\n        await sandbox.code_interpreter.delete_context(ctx)\n\n    print(\"=\" * 10 + \" Timeout handling \" + \"=\" * 10)\n    try:\n        code = \"\"\"\nimport time\nprint('Starting long running task...')\ntime.sleep(5)\nprint('Finished!')\n\"\"\"\n        _ = await sandbox.code_interpreter.run_code(\n            code,\n            timeout=1,\n            on_stdout=handle_stdout,\n            on_stderr=handle_stderr,\n            on_error=handle_error,\n        )\n    except DaytonaTimeoutError as exc:\n        print(f\"Timed out as expected: {exc}\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/exec-command/_async/exec_logs_async.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona, SessionExecuteRequest\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        sandbox = await daytona.create()\n\n        try:\n            session_id = \"exec-session-1\"\n            await sandbox.process.create_session(session_id)\n\n            command = await sandbox.process.execute_session_command(\n                session_id,\n                SessionExecuteRequest(\n                    command=(\n                        'printf \"Enter your name: \\\\n\" && read name && printf \"Hello, %s\\\\n\" \"$name\"; '\n                        'counter=1; while (( counter <= 3 )); do echo \"Count: $counter\"; '\n                        \"((counter++)); sleep 2; done; non-existent-command\"\n                    ),\n                    run_async=True,\n                ),\n            )\n\n            logs_task = asyncio.create_task(\n                sandbox.process.get_session_command_logs_async(\n                    session_id,\n                    command.cmd_id,\n                    lambda log: print(f\"[STDOUT]: {log}\"),\n                    lambda log: print(f\"[STDERR]: {log}\"),\n                )\n            )\n\n            print(\"Continuing execution while logs are streaming...\")\n            await asyncio.sleep(1)\n            print(\"Sending input to the command\")\n            await sandbox.process.send_session_command_input(session_id, command.cmd_id, \"Alice\")\n            print(\"Input sent to the command\")\n            print(\"Other operations completed!\")\n\n            print(\"Now waiting for logs to complete...\")\n            await logs_task\n        except Exception as e:\n            print(f\"Error: {e}\")\n        finally:\n            print(\"Cleaning up sandbox...\")\n            await daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/exec-command/_async/exec_session.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona, SessionExecuteRequest\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        sandbox = await daytona.create()\n\n        exec_session_id = \"exec-session-1\"\n        await sandbox.process.create_session(exec_session_id)\n\n        # Get the session details any time\n        session = await sandbox.process.get_session(exec_session_id)\n        print(session)\n\n        # Execute a first command in the session\n        exec_command1 = await sandbox.process.execute_session_command(\n            exec_session_id, SessionExecuteRequest(command=\"export FOO=BAR\")\n        )\n        if exec_command1.exit_code != 0:\n            print(f\"Error: {exec_command1.exit_code} {exec_command1.stderr}\")\n\n        # Get the session details again to see the command has been executed\n        session = await sandbox.process.get_session(exec_session_id)\n        print(session)\n\n        # Get the command details\n        session_command = await sandbox.process.get_session_command(exec_session_id, exec_command1.cmd_id)\n        print(session_command)\n\n        # Execute a second command in the session and see that the environment variable is set\n        exec_command2 = await sandbox.process.execute_session_command(\n            exec_session_id, SessionExecuteRequest(command=\"echo $FOO\")\n        )\n        if exec_command2.exit_code != 0:\n            print(f\"Error: {exec_command2.exit_code} {exec_command2.stderr}\")\n        else:\n            print(exec_command2.stdout)\n\n        print(\"Now getting logs for the second command\")\n        logs = await sandbox.process.get_session_command_logs(exec_session_id, exec_command2.cmd_id)\n        print(f\"[STDOUT]: {logs.stdout}\")\n        print(f\"[STDERR]: {logs.stderr}\")\n\n        # You can also list all active sessions\n        sessions = await sandbox.process.list_sessions()\n        print(sessions)\n\n        # And of course you can delete the session at any time\n        await sandbox.process.delete_session(exec_session_id)\n\n        await daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/exec-command/exec.py",
    "content": "from daytona import (\n    CreateSandboxFromImageParams,\n    Daytona,\n    DaytonaTimeoutError,\n    ExecutionError,\n    OutputMessage,\n    Resources,\n    Sandbox,\n)\n\n\ndef main():\n    daytona = Daytona()\n\n    params = CreateSandboxFromImageParams(\n        image=\"python:3.9.23-slim\",\n        language=\"python\",\n        resources=Resources(\n            cpu=1,\n            memory=1,\n            disk=3,\n        ),\n    )\n    sandbox = daytona.create(params, timeout=150, on_snapshot_create_logs=print)\n\n    # Run the code securely inside the sandbox\n    response = sandbox.process.code_run('print(\"Hello World!\")')\n    if response.exit_code != 0:\n        print(f\"Error: {response.exit_code} {response.result}\")\n    else:\n        print(response.result)\n\n    # Execute an os command in the sandbox\n    response = sandbox.process.exec('echo \"Hello World from exec!\"', timeout=10)\n    if response.exit_code != 0:\n        print(f\"Error: {response.exit_code} {response.result}\")\n    else:\n        print(response.result)\n\n    stateful_code_interpreter(sandbox)\n\n    daytona.delete(sandbox)\n\n\ndef stateful_code_interpreter(sandbox: Sandbox):\n    def handle_stdout(message: OutputMessage):\n        print(f\"[STDOUT] {message.output}\")\n\n    def handle_stderr(message: OutputMessage):\n        print(f\"[STDERR] {message.output}\")\n\n    def handle_error(error: ExecutionError):\n        print(f\"[ERROR] {error.name}: {error.value}\\n{error.traceback}\")\n\n    print(\"\\n\" + \"=\" * 60)\n    print(\"Stateful Code Interpreter\")\n    print(\"=\" * 60)\n\n    print(\"=\" * 10 + \" Statefulness in the default context \" + \"=\" * 10)\n    result = sandbox.code_interpreter.run_code(\"counter = 1\\nprint(f'Initialized counter = {counter}')\")\n    print(f\"[STDOUT] {result.stdout}\")\n\n    result = sandbox.code_interpreter.run_code(\n        \"counter += 1\\nprint(f'Counter after second call = {counter}')\",\n        on_stdout=handle_stdout,\n        on_stderr=handle_stderr,\n        on_error=handle_error,\n    )\n\n    print(\"=\" * 10 + \" Context isolation \" + \"=\" * 10)\n    ctx = sandbox.code_interpreter.create_context()\n    try:\n        ctx_result = sandbox.code_interpreter.run_code(\n            \"value = 'stored in isolated context'\\nprint(f'Isolated context value: {value}')\",\n            context=ctx,\n            on_stdout=handle_stdout,\n            on_stderr=handle_stderr,\n            on_error=handle_error,\n        )\n\n        print(\"-\" * 3 + \" Print value from same context \" + \"-\" * 3)\n        ctx_result = sandbox.code_interpreter.run_code(\n            \"print(f'Value still available: {value}')\",\n            context=ctx,\n        )\n        print(f\"[STDOUT] {ctx_result.stdout}\")\n\n        print(\"-\" * 3 + \" Print value from different context \" + \"-\" * 3)\n        _ = sandbox.code_interpreter.run_code(\n            \"print(value)\",\n            on_stdout=handle_stdout,\n            on_stderr=handle_stderr,\n            on_error=handle_error,\n        )\n    finally:\n        sandbox.code_interpreter.delete_context(ctx)\n\n    print(\"=\" * 10 + \" Timeout handling \" + \"=\" * 10)\n    try:\n        code = \"\"\"\nimport time\nprint('Starting long running task...')\ntime.sleep(5)\nprint('Finished!')\n\"\"\"\n        _ = sandbox.code_interpreter.run_code(\n            code,\n            timeout=1,\n            on_stdout=handle_stdout,\n            on_stderr=handle_stderr,\n            on_error=handle_error,\n        )\n    except DaytonaTimeoutError as exc:\n        print(f\"Timed out as expected: {exc}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/exec-command/exec_logs_async.py",
    "content": "import asyncio\n\nfrom daytona import Daytona, SessionExecuteRequest\n\n\nasync def main():\n    daytona = Daytona()\n    sandbox = daytona.create()\n\n    try:\n        session_id = \"exec-session-1\"\n        sandbox.process.create_session(session_id)\n\n        command = sandbox.process.execute_session_command(\n            session_id,\n            SessionExecuteRequest(\n                command=(\n                    'printf \"Enter your name: \\\\n\" && read name && printf \"Hello, %s\\\\n\" \"$name\"; '\n                    'counter=1; while (( counter <= 3 )); do echo \"Count: $counter\"; '\n                    \"((counter++)); sleep 2; done; non-existent-command\"\n                ),\n                run_async=True,\n            ),\n        )\n\n        logs_task = asyncio.create_task(\n            sandbox.process.get_session_command_logs_async(\n                session_id,\n                command.cmd_id,\n                lambda log: print(f\"[STDOUT]: {log}\"),\n                lambda log: print(f\"[STDERR]: {log}\"),\n            )\n        )\n\n        print(\"Continuing execution while logs are streaming...\")\n        await asyncio.sleep(1)\n        print(\"Sending input to the command\")\n        sandbox.process.send_session_command_input(session_id, command.cmd_id, \"Alice\")\n        print(\"Input sent to the command\")\n        print(\"Other operations completed!\")\n\n        print(\"Now waiting for logs to complete...\")\n        await logs_task\n    except Exception as e:\n        print(f\"Error: {e}\")\n    finally:\n        print(\"Cleaning up sandbox...\")\n        daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/exec-command/exec_session.py",
    "content": "from daytona import Daytona, SessionExecuteRequest\n\n\ndef main():\n    daytona = Daytona()\n    sandbox = daytona.create()\n\n    exec_session_id = \"exec-session-1\"\n    sandbox.process.create_session(exec_session_id)\n\n    # Get the session details any time\n    session = sandbox.process.get_session(exec_session_id)\n    print(session)\n\n    # Execute a first command in the session\n    exec_command1 = sandbox.process.execute_session_command(\n        exec_session_id, SessionExecuteRequest(command=\"export FOO=BAR\")\n    )\n    if exec_command1.exit_code != 0:\n        print(f\"Error: {exec_command1.exit_code} {exec_command1.stderr}\")\n\n    # Get the session details again to see the command has been executed\n    session = sandbox.process.get_session(exec_session_id)\n    print(session)\n\n    # Get the command details\n    session_command = sandbox.process.get_session_command(exec_session_id, exec_command1.cmd_id)\n    print(session_command)\n\n    # Execute a second command in the session and see that the environment variable is set\n    exec_command2 = sandbox.process.execute_session_command(exec_session_id, SessionExecuteRequest(command=\"echo $FOO\"))\n    if exec_command2.exit_code != 0:\n        print(f\"Error: {exec_command2.exit_code} {exec_command2.stderr}\")\n    else:\n        print(exec_command2.stdout)\n\n    print(\"Now getting logs for the second command\")\n    logs = sandbox.process.get_session_command_logs(exec_session_id, exec_command2.cmd_id)\n    print(f\"[STDOUT]: {logs.stdout}\")\n    print(f\"[STDERR]: {logs.stderr}\")\n\n    # You can also list all active sessions\n    sessions = sandbox.process.list_sessions()\n    print(sessions)\n\n    # And of course you can delete the session at any time\n    sandbox.process.delete_session(exec_session_id)\n\n    daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/file-operations/_async/main.py",
    "content": "import asyncio\nimport json\nimport os\nfrom datetime import datetime\n\nfrom daytona import AsyncDaytona, CreateSandboxFromSnapshotParams, FileDownloadRequest, FileUpload\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        params = CreateSandboxFromSnapshotParams(\n            language=\"python\",\n        )\n\n        # First, create a sandbox\n        sandbox = await daytona.create(params)\n        print(f\"Created sandbox with ID: {sandbox.id}\")\n\n        # List files in the sandbox\n        files = await sandbox.fs.list_files(\".\")\n        print(\"Initial files:\", files)\n\n        # Create a new directory in the sandbox\n        new_dir = \"project-files\"\n        await sandbox.fs.create_folder(new_dir, \"755\")\n\n        # Create a local file for demonstration\n        local_file_path = \"local-example.txt\"\n        with open(local_file_path, \"w\", encoding=\"utf-8\") as f:\n            _ = f.write(\"This is a local file created for demonstration purposes\")\n\n        # Create a configuration file with JSON data\n        config_data = json.dumps(\n            {\"name\": \"project-config\", \"version\": \"1.0.0\", \"settings\": {\"debug\": True, \"maxConnections\": 10}}, indent=2\n        )\n\n        # Upload multiple files at once - both from local path and from bytes\n        await sandbox.fs.upload_files(\n            [\n                FileUpload(source=local_file_path, destination=os.path.join(new_dir, \"example.txt\")),\n                FileUpload(source=config_data.encode(\"utf-8\"), destination=os.path.join(new_dir, \"config.json\")),\n                FileUpload(\n                    source=b'#!/bin/bash\\necho \"Hello from script!\"\\nexit 0',\n                    destination=os.path.join(new_dir, \"script.sh\"),\n                ),\n            ]\n        )\n\n        # Execute commands on the sandbox to verify files and make them executable\n        print(\"Verifying uploaded files:\")\n        ls_result = await sandbox.process.exec(f\"ls -la {new_dir}\")\n        print(ls_result.result)\n\n        # Make the script executable\n        _ = await sandbox.process.exec(f\"chmod +x {os.path.join(new_dir, 'script.sh')}\")\n\n        # Run the script\n        print(\"Running script:\")\n        script_result = await sandbox.process.exec(f\"{os.path.join(new_dir, 'script.sh')}\")\n        print(script_result.result)\n\n        # Search for files in the project\n        matches = await sandbox.fs.search_files(new_dir, \"*.json\")\n        print(\"JSON files found:\", matches)\n\n        # Replace content in config file\n        _ = await sandbox.fs.replace_in_files([os.path.join(new_dir, \"config.json\")], '\"debug\": true', '\"debug\": false')\n\n        # Download multiple files - mix of local file and memory download\n        print(\"Downloading multiple files:\")\n        download_results = await sandbox.fs.download_files(\n            [\n                FileDownloadRequest(source=os.path.join(new_dir, \"config.json\"), destination=\"local-config.json\"),\n                FileDownloadRequest(source=os.path.join(new_dir, \"example.txt\")),\n                FileDownloadRequest(source=os.path.join(new_dir, \"script.sh\"), destination=\"local-script.sh\"),\n            ]\n        )\n\n        for result in download_results:\n            if result.error:\n                print(f\"Error downloading {result.source}: {result.error}\")\n            elif isinstance(result.result, str):\n                print(f\"Downloaded {result.source} to {result.result}\")\n            elif result.result:\n                print(f\"Downloaded {result.source} to memory ({len(result.result)} bytes)\")\n            else:\n                print(f\"Downloaded {result.source} to None (unknown result type)\")\n\n        # Single file download example\n        print(\"Single file download example:\")\n        config_content = await sandbox.fs.download_file(os.path.join(new_dir, \"config.json\"))\n        print(\"Config content:\", config_content.decode(\"utf-8\"))\n\n        # Create a report of all operations\n        report_data = f\"\"\"\n        Project Files Report:\n        ---------------------\n        Time: {datetime.now().isoformat()}\n        Files: {len(matches.files)} JSON files found\n        Config: {'Production mode' if b'\"debug\": false' in config_content else 'Debug mode'}\n        Script: {'Executed successfully' if script_result.exit_code == 0 else 'Failed'}\n        \"\"\".strip()\n\n        # Save the report\n        await sandbox.fs.upload_file(report_data.encode(\"utf-8\"), os.path.join(new_dir, \"report.txt\"))\n\n        # Clean up local file\n        os.remove(local_file_path)\n        if os.path.exists(\"local-config.json\"):\n            os.remove(\"local-config.json\")\n        if os.path.exists(\"local-script.sh\"):\n            os.remove(\"local-script.sh\")\n\n        # Delete the sandbox\n        await daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/file-operations/main.py",
    "content": "import json\nimport os\nfrom datetime import datetime\n\nfrom daytona import CreateSandboxFromSnapshotParams, Daytona, FileDownloadRequest, FileUpload\n\n\ndef main():\n    daytona = Daytona()\n    params = CreateSandboxFromSnapshotParams(\n        language=\"python\",\n    )\n\n    # First, create a sandbox\n    sandbox = daytona.create(params)\n    print(f\"Created sandbox with ID: {sandbox.id}\")\n\n    # List files in the sandbox\n    files = sandbox.fs.list_files(\".\")\n    print(\"Initial files:\", files)\n\n    # Create a new directory in the sandbox\n    new_dir = \"project-files\"\n    sandbox.fs.create_folder(new_dir, \"755\")\n\n    # Create a local file for demonstration\n    local_file_path = \"local-example.txt\"\n    with open(local_file_path, \"w\", encoding=\"utf-8\") as f:\n        _ = f.write(\"This is a local file created for demonstration purposes\")\n\n    # Create a configuration file with JSON data\n    config_data = json.dumps(\n        {\"name\": \"project-config\", \"version\": \"1.0.0\", \"settings\": {\"debug\": True, \"maxConnections\": 10}}, indent=2\n    )\n\n    # Upload multiple files at once - both from local path and from bytes\n    sandbox.fs.upload_files(\n        [\n            FileUpload(source=local_file_path, destination=os.path.join(new_dir, \"example.txt\")),\n            FileUpload(source=config_data.encode(\"utf-8\"), destination=os.path.join(new_dir, \"config.json\")),\n            FileUpload(\n                source=b'#!/bin/bash\\necho \"Hello from script!\"\\nexit 0', destination=os.path.join(new_dir, \"script.sh\")\n            ),\n        ]\n    )\n\n    # Execute commands on the sandbox to verify files and make them executable\n    print(\"Verifying uploaded files:\")\n    ls_result = sandbox.process.exec(f\"ls -la {new_dir}\")\n    print(ls_result.result)\n\n    # Make the script executable\n    _ = sandbox.process.exec(f\"chmod +x {os.path.join(new_dir, 'script.sh')}\")\n\n    # Run the script\n    print(\"Running script:\")\n    script_result = sandbox.process.exec(f\"{os.path.join(new_dir, 'script.sh')}\")\n    print(script_result.result)\n\n    # Search for files in the project\n    matches = sandbox.fs.search_files(new_dir, \"*.json\")\n    print(\"JSON files found:\", matches)\n\n    # Replace content in config file\n    _ = sandbox.fs.replace_in_files([os.path.join(new_dir, \"config.json\")], '\"debug\": true', '\"debug\": false')\n\n    # Download multiple files - mix of local file and memory download\n    print(\"Downloading multiple files:\")\n    download_results = sandbox.fs.download_files(\n        [\n            FileDownloadRequest(source=os.path.join(new_dir, \"config.json\"), destination=\"local-config.json\"),\n            FileDownloadRequest(source=os.path.join(new_dir, \"example.txt\")),\n            FileDownloadRequest(source=os.path.join(new_dir, \"script.sh\"), destination=\"local-script.sh\"),\n        ]\n    )\n\n    for result in download_results:\n        if result.error:\n            print(f\"Error downloading {result.source}: {result.error}\")\n        elif isinstance(result.result, str):\n            print(f\"Downloaded {result.source} to {result.result}\")\n        elif result.result:\n            print(f\"Downloaded {result.source} to memory ({len(result.result)} bytes)\")\n        else:\n            print(f\"Downloaded {result.source} to None (unknown result type)\")\n\n    # Single file download example\n    print(\"Single file download example:\")\n    config_content = sandbox.fs.download_file(os.path.join(new_dir, \"config.json\"))\n    print(\"Config content:\", config_content.decode(\"utf-8\"))\n\n    # Create a report of all operations\n    report_data = f\"\"\"\n    Project Files Report:\n    ---------------------\n    Time: {datetime.now().isoformat()}\n    Files: {len(matches.files)} JSON files found\n    Config: {'Production mode' if b'\"debug\": false' in config_content else 'Debug mode'}\n    Script: {'Executed successfully' if script_result.exit_code == 0 else 'Failed'}\n    \"\"\".strip()\n\n    # Save the report\n    sandbox.fs.upload_file(report_data.encode(\"utf-8\"), os.path.join(new_dir, \"report.txt\"))\n\n    # Clean up local file\n    os.remove(local_file_path)\n    if os.path.exists(\"local-config.json\"):\n        os.remove(\"local-config.json\")\n    if os.path.exists(\"local-script.sh\"):\n        os.remove(\"local-script.sh\")\n\n    # Delete the sandbox\n    daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/git-lsp/_async/main.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona, CreateSandboxFromImageParams, Image, LspCompletionPosition\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        sandbox = await daytona.create(\n            CreateSandboxFromImageParams(\n                image=(\n                    Image.base(\"ubuntu:25.10\").run_commands(\n                        \"apt-get update && apt-get install -y --no-install-recommends nodejs npm coreutils\",\n                        \"curl -fsSL https://deb.nodesource.com/setup_20.x | bash -\",\n                        \"apt-get install -y nodejs\",\n                        \"npm install -g ts-node typescript typescript-language-server\",\n                    )\n                ),\n            ),\n            timeout=200,\n            on_snapshot_create_logs=print,\n        )\n\n        try:\n            project_dir = \"learn-typescript\"\n\n            # Clone the repository\n            await sandbox.git.clone(\n                \"https://github.com/panaverse/learn-typescript\",\n                project_dir,\n                \"master\",\n            )\n\n            await sandbox.git.pull(project_dir)\n\n            # Search for the file we want to work on\n            matches = await sandbox.fs.find_files(project_dir, \"var obj1 = new Base();\")\n            print(\"Matches:\", matches)\n\n            # Start the language server\n            lsp = sandbox.create_lsp_server(\"typescript\", project_dir)\n            await lsp.start()\n\n            # Notify the language server of the document we want to work on\n            await lsp.did_open(matches[0].file)\n\n            # Get symbols in the document\n            symbols = await lsp.document_symbols(matches[0].file)\n            print(\"Symbols:\", symbols)\n\n            # Fix the error in the document\n            _ = await sandbox.fs.replace_in_files([matches[0].file], \"var obj1 = new Base();\", \"var obj1 = new E();\")\n\n            # Notify the language server of the document change\n            await lsp.did_close(matches[0].file)\n            await lsp.did_open(matches[0].file)\n\n            # Get completions at a specific position\n            completions = await lsp.completions(matches[0].file, LspCompletionPosition(line=12, character=18))\n            print(\"Completions:\", completions)\n\n        except Exception as error:\n            print(\"Error executing example:\", error)\n        finally:\n            # Cleanup\n            await daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/git-lsp/main.py",
    "content": "from daytona import CreateSandboxFromImageParams, Daytona, Image, LspCompletionPosition\n\n\ndef main():\n    daytona = Daytona()\n\n    sandbox = daytona.create(\n        CreateSandboxFromImageParams(\n            image=(\n                Image.base(\"ubuntu:25.10\").run_commands(\n                    \"apt-get update && apt-get install -y --no-install-recommends nodejs npm coreutils\",\n                    \"curl -fsSL https://deb.nodesource.com/setup_20.x | bash -\",\n                    \"apt-get install -y nodejs\",\n                    \"npm install -g ts-node typescript typescript-language-server\",\n                )\n            ),\n        ),\n        timeout=200,\n        on_snapshot_create_logs=print,\n    )\n\n    try:\n        project_dir = \"learn-typescript\"\n\n        # Clone the repository\n        sandbox.git.clone(\n            \"https://github.com/panaverse/learn-typescript\",\n            project_dir,\n            \"master\",\n        )\n\n        sandbox.git.pull(project_dir)\n\n        # Search for the file we want to work on\n        matches = sandbox.fs.find_files(project_dir, \"var obj1 = new Base();\")\n        print(\"Matches:\", matches)\n\n        # Start the language server\n        lsp = sandbox.create_lsp_server(\"typescript\", project_dir)\n        lsp.start()\n\n        # Notify the language server of the document we want to work on\n        lsp.did_open(matches[0].file)\n\n        # Get symbols in the document\n        symbols = lsp.document_symbols(matches[0].file)\n        print(\"Symbols:\", symbols)\n\n        # Fix the error in the document\n        _ = sandbox.fs.replace_in_files([matches[0].file], \"var obj1 = new Base();\", \"var obj1 = new E();\")\n\n        # Notify the language server of the document change\n        lsp.did_close(matches[0].file)\n        lsp.did_open(matches[0].file)\n\n        # Get completions at a specific position\n        completions = lsp.completions(matches[0].file, LspCompletionPosition(line=12, character=18))\n        print(\"Completions:\", completions)\n\n    except Exception as error:\n        print(\"Error executing example:\", error)\n    finally:\n        # Cleanup\n        daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/lifecycle/_async/lifecycle.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        print(\"Creating sandbox\")\n        sandbox = await daytona.create()\n        print(\"Sandbox created\")\n\n        _ = await sandbox.set_labels(\n            {\n                \"public\": \"true\",\n            }\n        )\n\n        print(\"Stopping sandbox\")\n        await daytona.stop(sandbox)\n        print(\"Sandbox stopped\")\n\n        print(\"Starting sandbox\")\n        await daytona.start(sandbox)\n        print(\"Sandbox started\")\n\n        print(\"Getting existing sandbox\")\n        existing_sandbox = await daytona.get(sandbox.id)\n        print(\"Get existing sandbox\")\n\n        response = await existing_sandbox.process.exec('echo \"Hello World from exec!\"', cwd=\"/home/daytona\", timeout=10)\n        if response.exit_code != 0:\n            print(f\"Error: {response.exit_code} {response.result}\")\n        else:\n            print(response.result)\n\n        result = await daytona.list()\n        print(\"Total sandboxes count:\", result.total)\n\n        print(f\"Printing first sandbox -> id: {result.items[0].id} state: {result.items[0].state}\")\n\n        print(\"Removing sandbox\")\n        await daytona.delete(sandbox)\n        print(\"Sandbox removed\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/lifecycle/lifecycle.py",
    "content": "from daytona import Daytona\n\n\ndef main():\n    daytona = Daytona()\n\n    print(\"Creating sandbox\")\n    sandbox = daytona.create()\n    print(\"Sandbox created\")\n\n    _ = sandbox.set_labels(\n        {\n            \"public\": \"true\",\n        }\n    )\n\n    print(\"Stopping sandbox\")\n    daytona.stop(sandbox)\n    print(\"Sandbox stopped\")\n\n    print(\"Starting sandbox\")\n    daytona.start(sandbox)\n    print(\"Sandbox started\")\n\n    print(\"Getting existing sandbox\")\n    existing_sandbox = daytona.get(sandbox.id)\n    print(\"Get existing sandbox\")\n\n    response = existing_sandbox.process.exec('echo \"Hello World from exec!\"', cwd=\"/home/daytona\", timeout=10)\n    if response.exit_code != 0:\n        print(f\"Error: {response.exit_code} {response.result}\")\n    else:\n        print(response.result)\n\n    result = daytona.list()\n    print(\"Total sandboxes count:\", result.total)\n\n    print(f\"Printing first sandbox -> id: {result.items[0].id} state: {result.items[0].state}\")\n\n    print(\"Removing sandbox\")\n    daytona.delete(sandbox)\n    print(\"Sandbox removed\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/network-settings/_async/main.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona, CreateSandboxFromSnapshotParams\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        # Default settings\n        sandbox1 = await daytona.create()\n        print(\"network_block_all:\", sandbox1.network_block_all)\n        print(\"network_allow_list:\", sandbox1.network_allow_list)\n\n        # Block all network access\n        sandbox2 = await daytona.create(params=CreateSandboxFromSnapshotParams(network_block_all=True))\n        print(\"network_block_all:\", sandbox2.network_block_all)\n        print(\"network_allow_list:\", sandbox2.network_allow_list)\n\n        # Explicitly allow list of network addresses\n        sandbox3 = await daytona.create(\n            params=CreateSandboxFromSnapshotParams(network_allow_list=\"192.168.1.0/16,10.0.0.0/24\")\n        )\n        print(\"network_block_all:\", sandbox3.network_block_all)\n        print(\"network_allow_list:\", sandbox3.network_allow_list)\n\n        await sandbox1.delete()\n        await sandbox2.delete()\n        await sandbox3.delete()\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/network-settings/main.py",
    "content": "from daytona import CreateSandboxFromSnapshotParams, Daytona\n\n\ndef main():\n    daytona = Daytona()\n\n    # Default settings\n    sandbox1 = daytona.create()\n    print(\"network_block_all:\", sandbox1.network_block_all)\n    print(\"network_allow_list:\", sandbox1.network_allow_list)\n\n    # Block all network access\n    sandbox2 = daytona.create(params=CreateSandboxFromSnapshotParams(network_block_all=True))\n    print(\"network_block_all:\", sandbox2.network_block_all)\n    print(\"network_allow_list:\", sandbox2.network_allow_list)\n\n    # Explicitly allow list of network addresses\n    sandbox3 = daytona.create(params=CreateSandboxFromSnapshotParams(network_allow_list=\"192.168.1.0/16,10.0.0.0/24\"))\n    print(\"network_block_all:\", sandbox3.network_block_all)\n    print(\"network_allow_list:\", sandbox3.network_allow_list)\n\n    sandbox1.delete()\n    sandbox2.delete()\n    sandbox3.delete()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/pagination/_async/sandbox.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        result = await daytona.list(labels={\"my-label\": \"my-value\"}, page=2, limit=10)\n        for sandbox in result.items:\n            print(f\"{sandbox.id}: {sandbox.state}\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/pagination/_async/snapshot.py",
    "content": "import asyncio\n\nfrom daytona import AsyncDaytona\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        result = await daytona.snapshot.list(page=2, limit=10)\n        for snapshot in result.items:\n            print(f\"{snapshot.name} ({snapshot.image_name})\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/pagination/sandbox.py",
    "content": "from daytona import Daytona\n\n\ndef main():\n    daytona = Daytona()\n\n    result = daytona.list(labels={\"my-label\": \"my-value\"}, page=2, limit=10)\n    for sandbox in result.items:\n        print(f\"{sandbox.id}: {sandbox.state}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/pagination/snapshot.py",
    "content": "from daytona import Daytona\n\n\ndef main():\n    daytona = Daytona()\n\n    result = daytona.snapshot.list(page=2, limit=10)\n    for snapshot in result.items:\n        print(f\"{snapshot.name} ({snapshot.image_name})\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/pty/_async/main.py",
    "content": "import asyncio\nimport sys\n\nfrom daytona import AsyncDaytona, AsyncSandbox, PtySize\n\n\nasync def interactive_pty_session(sandbox: AsyncSandbox):\n    print(\"=== First PTY Session: Interactive Command with Exit ===\")\n\n    pty_session_id = \"interactive-pty-session\"\n\n    # Create PTY session with data handler\n    def handle_pty_data(data: bytes):\n        # Decode UTF-8 bytes to text and write directly to preserve terminal formatting\n        text = data.decode(\"utf-8\", errors=\"replace\")\n        _ = sys.stdout.write(text)\n        _ = sys.stdout.flush()\n\n    # Create PTY session with custom dimensions and data handler\n    pty_handle = await sandbox.process.create_pty_session(\n        id=pty_session_id, pty_size=PtySize(cols=120, rows=30), on_data=handle_pty_data\n    )\n\n    # Send interactive command\n    await pty_handle.send_input('printf \"Enter your name: \" && read name && printf \"Hello, %s\\\\n\" \"$name\"\\n')\n\n    # Wait and respond\n    await asyncio.sleep(1)\n    await pty_handle.send_input(\"Bob\\n\")\n\n    await asyncio.sleep(1)\n    pty_session_info = await sandbox.process.resize_pty_session(pty_session_id, PtySize(cols=80, rows=25))\n    print(f\"\\nPTY session resized to {pty_session_info.cols}x{pty_session_info.rows}\")\n\n    # Send another command\n    await asyncio.sleep(1)\n    await pty_handle.send_input(\"ls -la\\n\")\n\n    # Send exit command\n    await asyncio.sleep(1)\n    await pty_handle.send_input(\"exit\\n\")\n\n    # Wait for PTY to exit\n    result = await pty_handle.wait()\n    print(f\"\\nPTY session exited with code: {result.exit_code}\")\n    if result.error:\n        print(f\"Error: {result.error}\")\n\n\nasync def kill_pty_session(sandbox: AsyncSandbox):\n    print(\"\\n=== Second PTY Session: Kill PTY Session ===\")\n\n    pty_session_id = \"kill-pty-session\"\n\n    # Create PTY session with data handler\n    def handle_pty_data(data: bytes):\n        # Decode UTF-8 bytes to text and write directly to preserve terminal formatting\n        text = data.decode(\"utf-8\", errors=\"replace\")\n        _ = sys.stdout.write(text)\n        _ = sys.stdout.flush()\n\n    # Create PTY session\n    pty_handle = await sandbox.process.create_pty_session(\n        id=pty_session_id, pty_size=PtySize(cols=120, rows=30), on_data=handle_pty_data\n    )\n\n    # Send a long-running command\n    print(\"\\nSending long-running command (infinite loop)...\")\n    await pty_handle.send_input('while true; do echo \"Running... $(date)\"; sleep 1; done\\n')\n\n    # Let it run for a few seconds\n    await asyncio.sleep(3)\n\n    # Kill the PTY session\n    await pty_handle.kill()\n\n    # Wait for PTY to terminate\n    result = await pty_handle.wait()\n    print(f\"\\nPTY session terminated. Exit code: {result.exit_code}\")\n    if result.error:\n        print(f\"Error: {result.error}\")\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        sandbox = await daytona.create()\n\n        try:\n            # Interactive PTY session with exit\n            await interactive_pty_session(sandbox)\n            # PTY session killed with .kill()\n            await kill_pty_session(sandbox)\n        except Exception as error:\n            print(f\"Error executing PTY commands: {error}\")\n        finally:\n            print(f\"\\nDeleting sandbox: {sandbox.id}\")\n            await daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/pty/main.py",
    "content": "import sys\nimport threading\nimport time\n\nfrom daytona import Daytona, PtySize, Sandbox\n\n\ndef interactive_pty_session(sandbox: Sandbox):\n    print(\"=== First PTY Session: Interactive Command with Exit ===\")\n\n    pty_session_id = \"interactive-pty-session\"\n\n    # Create PTY session (returns PtyHandle in sync version)\n    pty_handle = sandbox.process.create_pty_session(id=pty_session_id, pty_size=PtySize(cols=120, rows=30))\n\n    def handle_pty_data(data: bytes):\n        # Decode UTF-8 bytes to text and write directly to preserve terminal formatting\n        text = data.decode(\"utf-8\", errors=\"replace\")\n        _ = sys.stdout.write(text)\n        _ = sys.stdout.flush()\n\n    # Send interactive command\n    print(\"\\nSending interactive read command...\")\n    pty_handle.send_input('printf \"Enter your name: \" && read name && printf \"Hello, %s\\\\n\" \"$name\"\\n')\n\n    # Wait and respond\n    time.sleep(1)\n    pty_handle.send_input(\"Alice\\n\")\n\n    _ = pty_handle.resize(PtySize(cols=80, rows=25))\n\n    # Send another command\n    time.sleep(1)\n    pty_handle.send_input(\"ls -la\\n\")\n\n    # Send exit command\n    time.sleep(1)\n    pty_handle.send_input(\"exit\\n\")\n\n    # Using iterator to handle PTY data\n    print(\"\\n--- Using iterator approach to handle PTY output ---\")\n    for data in pty_handle:\n        handle_pty_data(data)\n\n    print(f\"\\nPTY session exited with code: {pty_handle.exit_code}\")\n    if pty_handle.error:\n        print(f\"Error: {pty_handle.error}\")\n\n\ndef kill_pty_session(sandbox: Sandbox):\n    print(\"\\n=== Second PTY Session: Kill PTY Session ===\")\n\n    pty_session_id = \"kill-pty-session\"\n\n    # Create PTY session\n    pty_handle = sandbox.process.create_pty_session(id=pty_session_id, pty_size=PtySize(cols=120, rows=30))\n\n    def handle_pty_data(data: bytes):\n        # Decode UTF-8 bytes to text and write directly to preserve terminal formatting\n        text = data.decode(\"utf-8\", errors=\"replace\")\n        _ = sys.stdout.write(text)\n        _ = sys.stdout.flush()\n\n    # Send a long-running command\n    print(\"\\nSending long-running command (infinite loop)...\")\n    pty_handle.send_input('while true; do echo \"Running... $(date)\"; sleep 1; done\\n')\n\n    # Using thread and wait() method to handle PTY output\n    thread = threading.Thread(target=pty_handle.wait, args=(handle_pty_data, 10))\n    thread.start()\n\n    # Let it run for a few seconds\n    time.sleep(3)\n\n    # Kill the PTY session\n    pty_handle.kill()\n\n    thread.join()\n\n    print(f\"\\nPTY session terminated. Exit code: {pty_handle.exit_code}\")\n    if pty_handle.error:\n        print(f\"Error: {pty_handle.error}\")\n\n\ndef main():\n    daytona = Daytona()\n    sandbox = daytona.create()\n\n    try:\n        # interactive PTY session with exit\n        interactive_pty_session(sandbox)\n        # PTY session killed with .kill()\n        kill_pty_session(sandbox)\n    except Exception as error:\n        print(f\"Error executing PTY commands: {error}\")\n    finally:\n        # Cleanup\n        print(f\"\\nDeleting sandbox: {sandbox.id}\")\n        daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/region/_async/main.py",
    "content": "import asyncio\nimport time\n\nfrom daytona import AsyncDaytona, CreateSandboxFromSnapshotParams, CreateSnapshotParams, DaytonaConfig, Image\n\n\nasync def main():\n    async with AsyncDaytona(DaytonaConfig(target=\"us\")) as daytona:\n        snapshot1 = f\"us-{int(time.time() * 1000)}\"\n        print(f\"Creating snapshot {snapshot1}\")\n        try:\n            _ = await daytona.snapshot.create(\n                CreateSnapshotParams(\n                    name=snapshot1,\n                    image=Image.debian_slim(\"3.12\"),\n                    region_id=\"us\",\n                )\n            )\n        except Exception as e:\n            print(e)\n        print(\"--------------------------------\")\n\n        snapshot2 = f\"eu-{int(time.time() * 1000)}\"\n        print(f\"Creating snapshot {snapshot2}\")\n        try:\n            _ = await daytona.snapshot.create(\n                CreateSnapshotParams(\n                    name=snapshot2,\n                    image=Image.debian_slim(\"3.13\"),\n                    region_id=\"eu\",\n                )\n            )\n        except Exception as e:\n            print(\"error\", e)\n        print(\"--------------------------------\")\n\n        print(f\"Creating sandbox from snapshot {snapshot1}\")\n        try:\n            sandbox = await daytona.create(CreateSandboxFromSnapshotParams(snapshot=snapshot1))\n            await daytona.delete(sandbox)\n        except Exception as e:\n            print(e)\n        print(\"--------------------------------\")\n\n        print(f\"Creating sandbox from snapshot {snapshot2}\")\n        try:\n            sandbox = await daytona.create(CreateSandboxFromSnapshotParams(snapshot=snapshot2))\n            await daytona.delete(sandbox)\n        except Exception as e:\n            print(\"error\", e)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/region/main.py",
    "content": "import time\n\nfrom daytona import CreateSandboxFromSnapshotParams, CreateSnapshotParams, Daytona, DaytonaConfig, Image\n\n\ndef main():\n    daytona = Daytona(DaytonaConfig(target=\"us\"))\n\n    snapshot1 = f\"us-{int(time.time() * 1000)}\"\n    print(f\"Creating snapshot {snapshot1}\")\n    try:\n        _ = daytona.snapshot.create(\n            CreateSnapshotParams(\n                name=snapshot1,\n                image=Image.debian_slim(\"3.12\"),\n                region_id=\"us\",\n            )\n        )\n    except Exception as e:\n        print(e)\n    print(\"--------------------------------\")\n\n    snapshot2 = f\"eu-{int(time.time() * 1000)}\"\n    print(f\"Creating snapshot {snapshot2}\")\n    try:\n        _ = daytona.snapshot.create(\n            CreateSnapshotParams(\n                name=snapshot2,\n                image=Image.debian_slim(\"3.13\"),\n                region_id=\"eu\",\n            )\n        )\n    except Exception as e:\n        print(\"error\", e)\n    print(\"--------------------------------\")\n\n    print(f\"Creating sandbox from snapshot {snapshot1}\")\n    try:\n        sandbox = daytona.create(CreateSandboxFromSnapshotParams(snapshot=snapshot1))\n        daytona.delete(sandbox)\n    except Exception as e:\n        print(e)\n    print(\"--------------------------------\")\n\n    print(f\"Creating sandbox from snapshot {snapshot2}\")\n    try:\n        sandbox = daytona.create(CreateSandboxFromSnapshotParams(snapshot=snapshot2))\n        daytona.delete(sandbox)\n    except Exception as e:\n        print(\"error\", e)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/python/volumes/_async/volume.py",
    "content": "import asyncio\nimport os\n\nfrom daytona import AsyncDaytona, CreateSandboxFromSnapshotParams, VolumeMount\n\n\nasync def main():\n    async with AsyncDaytona() as daytona:\n        # Create a new volume or get an existing one\n        volume = await daytona.volume.get(\"my-volume\", create=True)\n\n        # Mount the volume to the sandbox\n        mount_dir_1 = \"/home/daytona/volume\"\n\n        params = CreateSandboxFromSnapshotParams(\n            language=\"python\",\n            volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_1)],\n        )\n        sandbox = await daytona.create(params)\n\n        # Create a new directory in the mount directory\n        new_dir = os.path.join(mount_dir_1, \"new-dir\")\n        await sandbox.fs.create_folder(new_dir, \"755\")\n\n        # Create a new file in the mount directory\n        new_file = os.path.join(mount_dir_1, \"new-file.txt\")\n        await sandbox.fs.upload_file(b\"Hello, World!\", new_file)\n\n        # Create a new sandbox with the same volume\n        # and mount it to the different path\n        mount_dir_2 = \"/home/daytona/my-files\"\n\n        params = CreateSandboxFromSnapshotParams(\n            language=\"python\",\n            volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_2)],\n        )\n        sandbox2 = await daytona.create(params)\n\n        # List files in the mount directory\n        files = await sandbox2.fs.list_files(mount_dir_2)\n        print(\"Files:\", files)\n\n        # Get the file from the mount directory\n        file = await sandbox2.fs.download_file(os.path.join(mount_dir_2, \"new-file.txt\"))\n        print(\"File:\", file)\n\n        # Mount a specific subpath within the volume\n        # This is useful for isolating data or implementing multi-tenancy\n        mount_dir_3 = \"/home/daytona/subpath\"\n\n        params = CreateSandboxFromSnapshotParams(\n            language=\"python\",\n            volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_3, subpath=\"users/alice\")],\n        )\n        sandbox3 = await daytona.create(params)\n\n        # This sandbox will only see files within the 'users/alice' subpath\n        # Create a file in the subpath\n        subpath_file = os.path.join(mount_dir_3, \"alice-file.txt\")\n        await sandbox3.fs.upload_file(b\"Hello from Alice's subpath!\", subpath_file)\n\n        # The file is stored at: volume-root/users/alice/alice-file.txt\n        # but appears at: /home/daytona/subpath/alice-file.txt in the sandbox\n\n        # Cleanup\n        await daytona.delete(sandbox)\n        await daytona.delete(sandbox2)\n        await daytona.delete(sandbox3)\n        # daytona.volume.delete(volume)\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "examples/python/volumes/volume.py",
    "content": "import os\n\nfrom daytona import CreateSandboxFromSnapshotParams, Daytona, VolumeMount\n\n\ndef main():\n    daytona = Daytona()\n\n    # Create a new volume or get an existing one\n    volume = daytona.volume.get(\"my-volume\", create=True)\n\n    # Mount the volume to the sandbox\n    mount_dir_1 = \"/home/daytona/volume\"\n\n    params = CreateSandboxFromSnapshotParams(\n        language=\"python\",\n        volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_1)],\n    )\n    sandbox = daytona.create(params)\n\n    # Create a new directory in the mount directory\n    new_dir = os.path.join(mount_dir_1, \"new-dir\")\n    sandbox.fs.create_folder(new_dir, \"755\")\n\n    # Create a new file in the mount directory\n    new_file = os.path.join(mount_dir_1, \"new-file.txt\")\n    sandbox.fs.upload_file(b\"Hello, World!\", new_file)\n\n    # Create a new sandbox with the same volume\n    # and mount it to the different path\n    mount_dir_2 = \"/home/daytona/my-files\"\n\n    params = CreateSandboxFromSnapshotParams(\n        language=\"python\",\n        volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_2)],\n    )\n    sandbox2 = daytona.create(params)\n\n    # List files in the mount directory\n    files = sandbox2.fs.list_files(mount_dir_2)\n    print(\"Files:\", files)\n\n    # Get the file from the mount directory\n    file = sandbox2.fs.download_file(os.path.join(mount_dir_2, \"new-file.txt\"))\n    print(\"File:\", file)\n\n    # Mount a specific subpath within the volume\n    # This is useful for isolating data or implementing multi-tenancy\n    mount_dir_3 = \"/home/daytona/subpath\"\n\n    params = CreateSandboxFromSnapshotParams(\n        language=\"python\",\n        volumes=[VolumeMount(volume_id=volume.id, mount_path=mount_dir_3, subpath=\"users/alice\")],\n    )\n    sandbox3 = daytona.create(params)\n\n    # This sandbox will only see files within the 'users/alice' subpath\n    # Create a file in the subpath\n    subpath_file = os.path.join(mount_dir_3, \"alice-file.txt\")\n    sandbox3.fs.upload_file(b\"Hello from Alice's subpath!\", subpath_file)\n\n    # The file is stored at: volume-root/users/alice/alice-file.txt\n    # but appears at: /home/daytona/subpath/alice-file.txt in the sandbox\n\n    # Cleanup\n    daytona.delete(sandbox)\n    daytona.delete(sandbox2)\n    daytona.delete(sandbox3)\n    # daytona.volume.delete(volume)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/ruby/README.md",
    "content": "# Ruby SDK Examples\n\nThis directory contains example scripts demonstrating how to use the Daytona Ruby SDK.\n\n## Prerequisites\n\n1. **Environment Variables** - Configure your API credentials using one of these methods:\n\n   **Option A: Using .env files (Recommended)**\n\n   Create a `.env.local` file in the directory where you run your code:\n\n   ```bash\n   # Required (choose one authentication method)\n   DAYTONA_API_KEY=your-api-key\n   # OR\n   DAYTONA_JWT_TOKEN=your-jwt-token\n   DAYTONA_ORGANIZATION_ID=your-org-id  # required when using JWT token\n\n   # Optional\n   DAYTONA_API_URL=https://app.daytona.io/api  # defaults to this if not specified\n   DAYTONA_TARGET=us  # defaults to your organization's default region\n   ```\n\n   The SDK automatically loads only Daytona-specific variables from `.env` and `.env.local` files in the current working directory, where `.env.local` overrides `.env`. Runtime environment variables always take precedence over `.env` files.\n\n   **Option B: Export manually**\n\n   ```bash\n   export DAYTONA_API_KEY=\"your-api-key\"\n   export DAYTONA_API_URL=\"https://app.daytona.io/api\"  # optional, this is the default\n   export DAYTONA_TARGET=\"us\"  # optional\n   ```\n\n2. **Ruby** - Ensure Ruby is installed (the devcontainer includes Ruby 3.4.5)\n\n3. **Devcontainer Setup** - The devcontainer automatically sets up the Ruby environment with the SDK libraries in your `RUBYLIB` path\n\n## Running Examples\n\nUse the `ruby` command to run any example:\n\n```bash\nruby examples/ruby/<example-folder>/<script>.rb\n```\n\nFor example:\n\n```bash\nruby examples/ruby/exec-command/exec_session.rb\nruby examples/ruby/lifecycle/lifecycle.rb\nruby examples/ruby/file-operations/main.rb\n```\n\nThe SDK and all client libraries are loaded from source files in the `libs/` directory, so any changes you make to the SDK will be reflected immediately when you run examples.\n\n## How It Works\n\nThe devcontainer sets up the following environment variables:\n\n- **`RUBYLIB`** - Includes paths to the SDK and client library source files\n- **`BUNDLE_GEMFILE`** - Points to the SDK's Gemfile for dependency management\n\nThis allows you to use plain `ruby` commands while still loading everything from source, ensuring all changes are reflected automatically.\n"
  },
  {
    "path": "examples/ruby/auto-archive/auto_archive.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Default interval\nfirst_sandbox = daytona.create\nputs \"Default auto archive interval: #{first_sandbox.auto_archive_interval}\"\n\n# Set interval to 1 hour\nfirst_sandbox.auto_archive_interval = 60\nputs \"Auto archive interval: #{first_sandbox.auto_archive_interval}\"\n\n# Max interval\nsecond_sandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(auto_archive_interval: 0))\nputs \"Max auto archive interval: #{second_sandbox.auto_archive_interval}\"\n\n# 1 day interval\nthird_sandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(auto_archive_interval: 24 * 60))\nputs \"Auto archive interval: #{third_sandbox.auto_archive_interval}\"\n\ndaytona.delete(first_sandbox)\ndaytona.delete(second_sandbox)\ndaytona.delete(third_sandbox)\n"
  },
  {
    "path": "examples/ruby/auto-delete/auto_delete.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Auto delete disabled by default\nfirst_sandbox = daytona.create\nputs \"Default auto delete interval: #{first_sandbox.auto_delete_interval}\"\n\n# Auto delete after the Sandbox has been stopped for 1 hour\nfirst_sandbox.auto_delete_interval = 60\nputs \"Auto delete interval: #{first_sandbox.auto_delete_interval}\"\n\n# Delete immediately upon stopping\nfirst_sandbox.auto_delete_interval = 0\nputs \"Auto delete interval: #{first_sandbox.auto_delete_interval}\"\n\n# Disable auto delete\nfirst_sandbox.auto_delete_interval = -1\nputs \"Auto delete interval: #{first_sandbox.auto_delete_interval}\"\n\n# Auto delete after the Sandbox has been stopped for 1 day\nsecond_sandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(auto_delete_interval: 24 * 60))\nputs \"Auto delete interval: #{second_sandbox.auto_delete_interval}\"\n\ndaytona.delete(first_sandbox)\ndaytona.delete(second_sandbox)\n"
  },
  {
    "path": "examples/ruby/charts/main.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'base64'\nrequire 'daytona'\n\nCODE = <<~PYTHON\n  import matplotlib.pyplot as plt\n  import numpy as np\n\n  # Sample data\n  x = np.linspace(0, 10, 30)\n  y = np.sin(x)\n  categories = ['A', 'B', 'C', 'D', 'E']\n  values = [40, 63, 15, 25, 8]\n  box_data = [np.random.normal(0, std, 100) for std in range(1, 6)]\n\n  # 1. Line Chart\n  plt.figure(figsize=(8, 5))\n  plt.plot(x, y, 'b-', linewidth=2)\n  plt.title('Line Chart')\n  plt.xlabel('X-axis (seconds)')\n  plt.ylabel('Y-axis (amplitude)')\n  plt.grid(True)\n  plt.show()\n\n  # 2. Scatter Plot\n  plt.figure(figsize=(8, 5))\n  plt.scatter(x, y, c=y, cmap='viridis', s=100*np.abs(y))\n  plt.colorbar(label='Value (normalized)')\n  plt.title('Scatter Plot')\n  plt.xlabel('X-axis (time in seconds)')\n  plt.ylabel('Y-axis (signal strength)')\n  plt.show()\n\n  # 3. Bar Chart\n  plt.figure(figsize=(10, 6))\n  plt.bar(categories, values, color='skyblue', edgecolor='navy')\n  plt.title('Bar Chart')\n  plt.xlabel('Categories')\n  plt.ylabel('Values (count)')\n  plt.show()\n\n  # 4. Pie Chart\n  plt.figure(figsize=(8, 8))\n  plt.pie(values, labels=categories,\n          autopct='%1.1f%%',\n          colors=plt.cm.Set3.colors, shadow=True, startangle=90)\n  plt.title('Pie Chart (Distribution in %)')\n  plt.axis('equal')\n  plt.legend()\n  plt.show()\n\n  # 5. Box and Whisker Plot\n  plt.figure(figsize=(10, 6))\n  plt.boxplot(box_data, patch_artist=True,\n              boxprops=dict(facecolor='lightblue'),\n              medianprops=dict(color='red', linewidth=2))\n  plt.title('Box and Whisker Plot')\n  plt.xlabel('Groups (Experiment IDs)')\n  plt.ylabel('Values (measurement units)')\n  plt.grid(True, linestyle='--', alpha=0.7)\n  plt.show()\nPYTHON\n\ndef main\n  daytona = Daytona::Daytona.new\n\n  sandbox = daytona.create(\n    Daytona::CreateSandboxFromImageParams.new(\n      image: Daytona::Image.debian_slim('3.13').pip_install('matplotlib')\n    ),\n    on_snapshot_create_logs: proc { print _1 }\n  )\n  response = sandbox.process.code_run(code: CODE)\n\n  if response.exit_code == 0\n    response.artifacts.charts.each do |chart|\n      img_data = Base64.decode64(chart.png)\n      title = chart.title || Time.now.to_i\n      filename = \"#{title}.png\"\n      File.binwrite(File.expand_path(filename, __dir__), img_data)\n\n      puts \"Image saved as #{filename}\"\n      print_chart(chart)\n    end\n  else\n    puts \"Error: #{response.exit_code} #{response.result}\"\n  end\n\n  daytona.delete(sandbox)\nend\n\ndef print_chart(chart)\n  puts \"Type: #{chart.type}\"\n  puts \"Title: #{chart.title}\"\n\n  case chart.type\n  when Daytona::Charts::ChartType::LINE\n    puts \"X Label: #{chart.x_label}\"\n    puts \"Y Label: #{chart.title}\"\n    puts \"X Ticks: #{chart.x_ticks}\"\n    puts \"X Tick Labels: #{chart.x_tick_labels}\"\n    puts \"X Scale: #{chart.x_scale}\"\n    puts \"Y Ticks: #{chart.y_ticks}\"\n    puts \"Y Tick Labels: #{chart.y_tick_labels}\"\n    puts \"Y Scale: #{chart.y_scale}\"\n    puts 'Elements:'\n    chart.elements.each do |element|\n      puts \"\\n  Label: #{element.label}\"\n      puts \"  Points: #{element.points}\"\n    end\n  when Daytona::Charts::ChartType::SCATTER\n    puts \"X Label: #{chart.x_label}\"\n    puts \"Y Label: #{chart.y_label}\"\n    puts \"X Ticks: #{chart.x_ticks}\"\n    puts \"X Tick Labels: #{chart.x_tick_labels}\"\n    puts \"X Scale: #{chart.x_scale}\"\n    puts \"Y Ticks: #{chart.y_ticks}\"\n    puts \"Y Tick Labels: #{chart.y_tick_labels}\"\n    puts \"Y Scale: #{chart.y_scale}\"\n    puts 'Elements:'\n    chart.elements.each do |element|\n      puts \"\\n  Label: #{element.label}\"\n      puts \"  Points: #{element.points}\"\n    end\n  when Daytona::Charts::ChartType::BAR\n    puts \"X Label: #{chart.x_label}\"\n    puts \"Y Label: #{chart.y_label}\"\n    puts 'Elements:'\n    chart.elements.each do |element|\n      puts \"\\n  Label: #{element.label}\"\n      puts \"  Group: #{element.group}\"\n      puts \"  Value: #{element.value}\"\n    end\n  when Daytona::Charts::ChartType::PIE\n    puts 'Elements:'\n    chart.elements.each do |element|\n      puts \"\\n  Label: #{element.label}\"\n      puts \"  Angle: #{element.angle}\"\n      puts \"  Radius: #{element.radius}\"\n      puts \"  Autopct: #{element.autopct}\"\n    end\n  when Daytona::Charts::ChartType::BOX_AND_WHISKER\n    puts \"X Label: #{chart.x_label}\"\n    puts \"Y Label: #{chart.y_label}\"\n    puts 'Elements:'\n    chart.elements.each do |element|\n      puts \"\\n  Label: #{element.label}\"\n      puts \"  Min: #{element.min}\"\n      puts \"  First Quartile: #{element.first_quartile}\"\n      puts \"  Median: #{element.median}\"\n      puts \"  Third Quartile: #{element.third_quartile}\"\n      puts \"  Max: #{element.max}\"\n      puts \"  Outliers: #{element.outliers}\"\n    end\n  when Daytona::Charts::ChartType::COMPOSITE_CHART\n    puts \"Elements:\\n\"\n    chart.element.each { print_chart(_1) }\n  else\n    raise ArgumentError, \"Unknown chart: #{chart.type}\"\n  end\nend\n\nmain\n"
  },
  {
    "path": "examples/ruby/declarative-image/main.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Generate unique name for the snapshot to avoid conflicts\nsnapshot_name = \"python-example:#{Time.now.to_i}\"\n\nFile.write('file_example.txt', 'Hello, World!')\n\n# Create a Python image with common data science packages\nimage =\n  Daytona::Image\n  .debian_slim('3.12')\n  .pip_install(%w[numpy pandas matplotlib scipy scikit-learn jupyter])\n  .run_commands(\n    'apt-get update && apt-get install -y git',\n    'groupadd -r daytona && useradd -r -g daytona -m daytona',\n    'mkdir -p /home/daytona/workspace'\n  )\n  .workdir('/home/daytona/workspace')\n  .env(MY_ENV_VAR: 'My Environment Variable')\n  .add_local_file('file_example.txt', '/home/daytona/workspace/file_example.txt')\n\ndaytona.snapshot.create(\n  Daytona::CreateSnapshotParams.new(\n    name: snapshot_name,\n    image:,\n    resources: Daytona::Resources.new(cpu: 1, memory: 1, disk: 3)\n  ),\n  on_logs: proc { |chunk| puts chunk }\n)\n\n# Create first sandbox using the pre-built image\nsandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(snapshot: snapshot_name))\n\n# Verify the first sandbox environment\nresponse = sandbox.process.exec(command: 'python --version && pip list')\nputs \"Python environment: #{response.result}\"\n\n# Verify the file was added to the image\nresponse = sandbox.process.exec(command: 'cat file_example.txt')\nputs \"File content: #{response.result}\"\n\n# Create sandbox with the dynamic image\ndynamic_image =\n  Daytona::Image\n  .debian_slim('3.11')\n  .pip_install(%w[pytest pytest-cov black isort mypy ruff])\n  .run_commands('apt-get update && apt-get install -y git', 'mkdir -p /home/daytona/project')\n  .workdir('/home/daytona/project')\n  .env(ENV_VAR: 'My Environment Variable')\n\nother_sandbox = daytona.create(\n  Daytona::CreateSandboxFromImageParams.new(image: dynamic_image),\n  on_snapshot_create_logs: proc { |chunk| puts chunk }\n)\n\n# Verify the other sandbox environment\nresponse = other_sandbox.process.exec(command: \"pip list | grep -E 'pytest|black|isort|mypy|ruff'\")\nputs \"Development tools: #{response.result}\"\n\n# Cleanup\nFile.delete('file_example.txt') if File.exist?('file_example.txt')\ndaytona.delete(sandbox)\ndaytona.delete(other_sandbox)\n"
  },
  {
    "path": "examples/ruby/exec-command/exec.rb",
    "content": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\nrequire 'daytona'\n\ndef basic_exec(sandbox)\n  # Run some Python code directly (sandbox is configured for Python)\n  code_result = sandbox.process.code_run(code: 'print(\"Hello World from code!\")')\n  if code_result.exit_code == 0\n    puts code_result.result\n  else\n    puts \"Error running code: #{code_result.exit_code}\"\n  end\n\n  # Run OS command\n  cmd_result = sandbox.process.exec(command: 'echo \"Hello World from CMD!\"')\n  if cmd_result.exit_code == 0\n    puts cmd_result.result\n  else\n    puts \"Error running command: #{cmd_result.exit_code}\"\n  end\nend\n\ndef session_exec(sandbox)\n  # Exec session\n  # Session allows for multiple commands to be executed in the same context\n  sandbox.process.create_session('exec-session-1')\n\n  # Get the session details any time\n  session = sandbox.process.get_session('exec-session-1')\n  puts \"session: #{session.inspect}\"\n\n  # Execute a first command in the session\n  command = sandbox.process.execute_session_command(\n    session_id: 'exec-session-1',\n    req: Daytona::SessionExecuteRequest.new(command: 'export FOO=BAR')\n  )\n\n  # Get the session details again to see the command has been executed\n  session_updated = sandbox.process.get_session('exec-session-1')\n  puts \"sessionUpdated: #{session_updated.inspect}\"\n\n  # Get the command details\n  session_command = sandbox.process.get_session_command(\n    session_id: 'exec-session-1',\n    command_id: command.cmd_id\n  )\n  puts \"sessionCommand: #{session_command.inspect}\"\n\n  # Execute a second command in the session and see that the environment variable is set\n  response = sandbox.process.execute_session_command(\n    session_id: 'exec-session-1',\n    req: Daytona::SessionExecuteRequest.new(command: 'echo $FOO')\n  )\n  puts \"FOO=#{response.stdout}\"\n\n  # We can also get the logs for the command any time after it is executed\n  logs = sandbox.process.get_session_command_logs(\n    session_id: 'exec-session-1',\n    command_id: response.cmd_id\n  )\n  puts \"[STDOUT]: #{logs.stdout}\"\n  puts \"[STDERR]: #{logs.stderr}\"\n\n  # We can also delete the session\n  sandbox.process.delete_session('exec-session-1')\nend\n\ndef session_exec_logs_async(sandbox)\n  puts 'Executing long running command in a session and streaming logs asynchronously...'\n\n  session_id = 'exec-session-async-logs'\n  sandbox.process.create_session(session_id)\n\n  command = sandbox.process.execute_session_command(\n    session_id: session_id,\n    req: Daytona::SessionExecuteRequest.new(\n      command: 'counter=1; while (( counter <= 3 )); do echo \"Count: $counter\"; ((counter++)); sleep 2; done; non-existent-command',\n      run_async: true\n    )\n  )\n\n  sandbox.process.get_session_command_logs_async(\n    session_id: session_id,\n    command_id: command.cmd_id,\n    on_stdout: ->(stdout) { puts \"[STDOUT]: #{stdout}\" },\n    on_stderr: ->(stderr) { puts \"[STDERR]: #{stderr}\" }\n  )\nend\n\ndef stateful_code_interpreter(sandbox)\n  log_stdout = ->(msg) { print \"[STDOUT] #{msg.output}\" }\n  log_stderr = ->(msg) { print \"[STDERR] #{msg.output}\" }\n  log_error = lambda do |err|\n    print \"[ERROR] #{err.name}: #{err.value}\\n\"\n    print \"#{err.traceback}\\n\" unless err.traceback.empty?\n  end\n\n  puts \"\\n#{'=' * 60}\"\n  puts 'Stateful Code Interpreter'\n  puts '=' * 60\n\n  puts ('=' * 10) + ' Statefulness in the default context ' + ('=' * 10)\n  result = sandbox.code_interpreter.run_code(\n    \"counter = 1\\nprint(f'Initialized counter = {counter}')\"\n  )\n  print \"[STDOUT] #{result.stdout}\"\n\n  sandbox.code_interpreter.run_code(\n    \"counter += 1\\nprint(f'Counter after second call = {counter}')\",\n    on_stdout: log_stdout,\n    on_stderr: log_stderr,\n    on_error: log_error\n  )\n\n  puts ('=' * 10) + ' Context isolation ' + ('=' * 10)\n  ctx = sandbox.code_interpreter.create_context\n  begin\n    sandbox.code_interpreter.run_code(\n      \"value = 'stored in isolated context'\\nprint(f'Isolated context value: {value}')\",\n      context: ctx,\n      on_stdout: log_stdout,\n      on_stderr: log_stderr,\n      on_error: log_error\n    )\n\n    puts ('-' * 3) + ' Print value from same context ' + ('-' * 3)\n    ctx_result = sandbox.code_interpreter.run_code(\n      \"print(f'Value still available: {value}')\",\n      context: ctx\n    )\n    print \"[STDOUT] #{ctx_result.stdout}\"\n\n    puts ('-' * 3) + ' Print value from different context ' + ('-' * 3)\n    sandbox.code_interpreter.run_code(\n      'print(value)',\n      on_stdout: log_stdout,\n      on_stderr: log_stderr,\n      on_error: log_error\n    )\n  ensure\n    sandbox.code_interpreter.delete_context(ctx)\n  end\n\n  puts ('=' * 10) + ' Timeout handling ' + ('=' * 10)\n  begin\n    code = <<~PYTHON\n      import time\n      print('Starting long running task...')\n      time.sleep(5)\n      print('Finished!')\n    PYTHON\n\n    sandbox.code_interpreter.run_code(\n      code,\n      timeout: 1,\n      on_stdout: log_stdout,\n      on_stderr: log_stderr,\n      on_error: log_error\n    )\n  rescue Daytona::Sdk::TimeoutError => e\n    puts \"Timed out as expected: #{e.message}\"\n  end\nend\n\ndef main\n  daytona = Daytona::Daytona.new\n\n  # First, create a sandbox\n  image = Daytona::Image.base('python:3.9.23-slim')\n\n  params = Daytona::CreateSandboxFromImageParams.new(\n    image: image,\n    language: 'python',\n    auto_stop_interval: 60,\n    auto_archive_interval: 60,\n    auto_delete_interval: 120,\n    resources: Daytona::Resources.new(cpu: 2, memory: 2, disk: 10)\n  )\n\n  sandbox = daytona.create(\n    params,\n    on_snapshot_create_logs: ->(chunk) { print chunk }\n  )\n\n  begin\n    basic_exec(sandbox)\n    session_exec(sandbox)\n    session_exec_logs_async(sandbox)\n    stateful_code_interpreter(sandbox)\n  rescue StandardError => e\n    puts \"Error executing commands: #{e.message}\"\n    puts e.backtrace\n  ensure\n    # Cleanup\n    daytona.delete(sandbox)\n  end\nend\n\nmain if __FILE__ == $PROGRAM_NAME\n"
  },
  {
    "path": "examples/ruby/exec-command/exec_session.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\n\nsession_id = 'exec-session-1'\nsandbox.process.create_session(session_id)\n\n# Get the session details\nsession = sandbox.process.get_session(session_id)\nputs session\n\n# Execute first command in the session\nfirst_command = sandbox.process.execute_session_command(\n  session_id: session_id,\n  req: Daytona::SessionExecuteRequest.new(command: 'export FOO=BAR')\n)\n\nif first_command.exit_code == 0\n  puts first_command.output\nelse\n  puts \"Error: #{first_command.exit_code} #{first_command.stderr}\"\nend\n\n# Get the session details again to see the command has been executed\nsession = sandbox.process.get_session(session_id)\nputs session.commands\n\n# Get the command details\ncommand = sandbox.process.get_session_command(session_id: session_id, command_id: first_command.cmd_id)\nputs command\n\n# Execute second command in the session and observe the environment variable is set\nsecond_command = sandbox.process.execute_session_command(\n  session_id: session_id,\n  req: Daytona::SessionExecuteRequest.new(command: 'echo $FOO')\n)\n\nif second_command.exit_code == 0\n  puts second_command.output\nelse\n  puts \"Error: #{second_command.exit_code} #{second_command.stderr}\"\nend\n\n# Get logs for the second command\nlogs = sandbox.process.get_session_command_logs(session_id: session_id, command_id: second_command.cmd_id)\nputs \"[STDOUT] #{logs.stdout}\"\nputs \"[STDERR] #{logs.stderr}\"\n\n# Demonstrate sending input to an interactive command\nputs \"\\n--- Testing send_session_command_input ---\"\ninteractive_command = sandbox.process.execute_session_command(\n  session_id: session_id,\n  req: Daytona::SessionExecuteRequest.new(\n    command: 'printf \"Enter your name: \\n\" && read name && printf \"Hello, %s\\n\" \"$name\"',\n    run_async: true\n  )\n)\n\n# Wait a moment for the command to start\nsleep 1\n\n# Send input to the command\nputs 'Sending input to the command...'\nsandbox.process.send_session_command_input(\n  session_id: session_id,\n  command_id: interactive_command.cmd_id,\n  data: 'Alice'\n)\nputs 'Input sent to the command'\n\n# Get logs for the interactive command asynchronously\nputs 'Retrieving command logs...'\nsandbox.process.get_session_command_logs_async(\n  session_id: session_id,\n  command_id: interactive_command.cmd_id,\n  on_stdout: ->(log) { puts \"[STDOUT]: #{log}\" },\n  on_stderr: ->(log) { puts \"[STDERR]: #{log}\" }\n)\nputs 'Command completed with interactive input'\n\n# List active sessions\nsessions = sandbox.process.list_sessions\nputs sessions\n\n# Delete the session\nsandbox.process.delete_session(session_id)\n\n# Cleanup resources\ndaytona.delete(sandbox)\n"
  },
  {
    "path": "examples/ruby/file-operations/main.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'json'\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nparams = Daytona::CreateSandboxFromSnapshotParams.new(language: Daytona::CodeLanguage::PYTHON)\n\n# Create a Sandbox\nsandbox = daytona.create(params)\nputs \"Created sandbox ##{sandbox.id}\"\n\n# List files in the Sandbox\nfiles = sandbox.fs.list_files('.')\nputs \"Initial files: #{files}\"\n\n# Create a new directory directory in the Sandbox\nproject_files = 'project-files'\nsandbox.fs.create_folder(project_files, '755')\n\n# Create local file for demonstration\nlocal_file_path = 'local-example.txt'\nFile.write(local_file_path, 'This is a local file created for demonstration purposes')\n\n# Create a configuration file with JSON data\nconfig_data = JSON.dump(name: 'project-config', version: '1.0.0', settings: { debug: true, max_connections: 10 })\n\n# Upload multiple files at once - both from local path and from bytes\nscript = <<~BASH\n  #!/bin/bash\n  echo \"Hello from script!\"\n  exit 0\nBASH\nsandbox.fs.upload_files(\n  [Daytona::FileUpload.new(local_file_path, File.join(project_files, 'example.txt')),\n   Daytona::FileUpload.new(config_data, File.join(project_files, 'config.json')),\n   Daytona::FileUpload.new(script, File.join(project_files, 'script.sh'))]\n)\n\n# Execute commands on the sandbox to verify files and make them executable\nls_cmd = sandbox.process.exec(command: \"ls -la #{project_files}\")\nputs ls_cmd.result\n\n# Make the script executable\nsandbox.process.exec(command: \"chmod +x #{File.join(project_files, 'script.sh')}\")\n\n# Run the script\nrun_cmd = sandbox.process.exec(command: \"./#{File.join(project_files, 'script.sh')}\")\nputs run_cmd.result\n\n# Search for files in the project\nmatches = sandbox.fs.search_files(project_files, '*.json')\nputs \"JSON files found: #{matches}\"\n\n# Download from remote and save it locally\nsandbox.fs.download_file(File.join(project_files, 'config.json'), 'local-config.json')\nfile = File.new('local-config.json')\nputs \"Content of local-config.json: #{file.read}\"\nputs \"Size of the downloaded file: #{file.size} bytes\"\n\n# Download from remote and get the reference to temporary file\nfile = sandbox.fs.download_file(File.join(project_files, 'example.txt'))\nputs \"Content of example.txt: #{file.open.read}\"\nputs \"Size of the downloaded file: #{file.size} bytes\"\n\n# Cleanup\nFile.delete('local-config.json') if File.exist?('local-config.json')\nFile.delete('example.txt') if File.exist?('example.txt')\ndaytona.delete(sandbox)\n"
  },
  {
    "path": "examples/ruby/git-lsp/main.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromImageParams.new(\n    image: Daytona::Image.base('ubuntu:25.10').run_commands(\n      'apt-get update && apt-get install -y --no-install-recommends nodejs npm coreutils',\n      'curl -fsSL https://deb.nodesource.com/setup_20.x | bash -',\n      'apt-get install -y nodejs',\n      'npm install -g ts-node typescript typescript-language-server'\n    ),\n    timeout: 200\n  )\n)\n\nproject_dir = 'learn-typescript'\n\n# Clone the repository\nsandbox.git.clone(\n  url: 'https://github.com/panaverse/learn-typescript',\n  path: project_dir,\n  branch: 'master'\n)\n\nsandbox.git.pull(path: project_dir)\n\n# Search for the file we want to work on\nmatches = sandbox.fs.find_files(project_dir, 'var obj1 = new Base();')\nputs \"Matches: #{matches}\"\n\n# Start the language server\nlsp = sandbox.create_lsp_server(language_id: Daytona::LspServer::Language::TYPESCRIPT, path_to_project: project_dir)\nlsp.start\n\n# Notify the language server of the document we want to work on\nlsp.did_open(matches.first.file)\n\n# Get symbols in the document\nsymbols = lsp.document_symbols(matches.first.file)\nputs \"Symbols: #{symbols}\"\n\n# Fix the error in the document\nsandbox.fs.replace_in_files(\n  files: [matches.first.file],\n  pattern: 'var obj1 = new Base();',\n  new_value: 'var obj1 = new E();'\n)\n\n# Notify the language server of the document change\nlsp.did_close(matches.first.file)\nlsp.did_open(matches.first.file)\n\n# Get completions at a specific position\ncompletions = lsp.completions(\n  path: matches.first.file,\n  position: Daytona::LspServer::Position.new(line: 12, character: 18)\n)\nprint(\"Completions: #{completions}\")\n\ndaytona.delete(sandbox)\n"
  },
  {
    "path": "examples/ruby/lifecycle/lifecycle.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\nputs 'Creating sandbox'\nsandbox = daytona.create\nputs 'Sandbox created'\n\nputs 'Replacing sandbox labels'\nsandbox.labels = { public: true }\nputs \"Sandbox labels: #{sandbox.labels}\"\n\nputs 'Stopping sandbox'\ndaytona.stop(sandbox)\nputs \"Sandbox #{sandbox.state}\"\n\nputs 'Starting sandbox'\ndaytona.start(sandbox)\nputs \"Sandbox #{sandbox.state}\"\n\nputs 'Getting existing sandbox'\nsandbox = daytona.get(sandbox.id)\nputs 'Retrieved existing sandbox'\n\nresponse = sandbox.process.exec(command: 'echo \"Hello World from exec!\"', cwd: '/home/daytona', timeout: 10)\nif response.exit_code == 0\n  puts response.result\nelse\n  puts \"Error: #{response.exit_code} #{response.result}\"\nend\n\nresult = daytona.list\nputs \"Total sandboxes count: #{result.total.to_i}\"\n\nputs \"Printing sandboxes[0] -> id: #{result.items.first.id} state: #{result.items.first.state}\"\n\nputs 'Removing sandbox'\ndaytona.delete(sandbox)\nputs 'Sandbox removed'\n"
  },
  {
    "path": "examples/ruby/network-settings/main.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Default settings\nfirst_sandbox = daytona.create\nputs \"Network block all: #{first_sandbox.network_block_all}\"\nputs \"Network allow list: #{first_sandbox.network_allow_list}\"\n\n# Block all network access\nsecond_sandbox = daytona.create(Daytona::CreateSandboxFromSnapshotParams.new(network_block_all: true))\nputs \"Network block all: #{second_sandbox.network_block_all}\"\nputs \"Network allow list: #{second_sandbox.network_allow_list}\"\n\n# Explicitly allow list of network addresses\nthird_sandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(network_allow_list: '192.168.1.0/16,10.0.0.0/24')\n)\nputs \"Network block all: #{third_sandbox.network_block_all}\"\nputs \"Network allow list: #{third_sandbox.network_allow_list}\"\n\ndaytona.delete(first_sandbox)\ndaytona.delete(second_sandbox)\ndaytona.delete(third_sandbox)\n"
  },
  {
    "path": "examples/ruby/pagination/sandbox.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\nresult = daytona.list({ 'my-label' => 'my-value' }, page: 2, limit: 10)\nresult.items.each do |sandbox|\n  puts \"#{sandbox.id} (#{sandbox.state})\"\nend\n"
  },
  {
    "path": "examples/ruby/pagination/snapshot.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\nresult = daytona.snapshot.list(page: 2, limit: 10)\nresult.items.each do |snapshot|\n  puts \"#{snapshot.name} (#{snapshot.image_name})\"\nend\n"
  },
  {
    "path": "examples/ruby/pty/main.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\nsandbox = daytona.create\n\nputs '=== First PTY Session: Interactive Command with Exit ==='\npty_session_id = 'interactive-pty-session'\n\n# Create PTY session\nhandle = sandbox.process.create_pty_session(id: pty_session_id, pty_size: Daytona::PtySize.new(cols: 120, rows: 30))\n\nthread = Thread.new do\n  # Using iterator to handle PTY data\n  print(\"\\n--- Using iterator approach to handle PTY output ---\")\n  handle.each { |data| puts data }\nend\n\n# Send interactive command\nhandle.send_input(\"printf 'Enter your name: ' && read name && printf 'Hello %s\\n' \\\"$name\\\"\\n\")\n\n# Wait and respond\nsleep(1)\nhandle.send_input(\"Alice\\n\")\n\nhandle.resize(Daytona::PtySize.new(cols: 80, rows: 25))\n\n# Send another command\nsleep(1)\nhandle.send_input(\"ls -la\\n\")\n\n# Send exit command\nsleep(1)\nhandle.send_input(\"exit\\n\")\n\nthread.join\n\nputs \"\\nPTY session exited with code: #{handle.exit_code}\"\nputs \"Error: #{handle.error}\" if handle.error\n\nputs '=== Second PTY Session: Kill PTY Session ==='\n\npty_session_id = 'kill-pty-session'\n\n# Create PTY session\nhandle = sandbox.process.create_pty_session(id: pty_session_id, pty_size: Daytona::PtySize.new(cols: 120, rows: 30))\n\n# Send a long-running command\nhandle.send_input(\"while true; do echo \\\"Running... $(date)\\\"; sleep 1; done\\n\")\n\n[\n  Thread.new { handle.each { |data| puts data } },\n  Thread.new { sleep(3) and handle.kill }\n].each(&:join)\n\nputs \"PTY session terminated. Exit code: #{handle.exit_code}\"\nputs \"Error: #{handle.error}\" if handle.error\n\n# Cleanup\ndaytona.delete(sandbox)\n"
  },
  {
    "path": "examples/ruby/volumes/volume.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'daytona'\n\ndaytona = Daytona::Daytona.new\n\n# Create a new volume or get an existing one\nvolume = daytona.volume.get('my-volume', create: true)\n\n# Mount the volume to the sandbox\nmount_dir = '/home/daytona/volume'\n\nsandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(\n    language: Daytona::CodeLanguage::PYTHON,\n    volumes: [DaytonaApiClient::SandboxVolume.new(volume_id: volume.id, mount_path: mount_dir)]\n  )\n)\n\n# Create a new directory in the mount directory\nnew_dir = File.expand_path('new-dir', mount_dir)\nsandbox.fs.create_folder(new_dir, '755')\n\n# Create a new file in the mount directory\nnew_file = File.expand_path('new-file.txt', mount_dir)\nsandbox.fs.upload_file('Hello world', new_file)\n\n# List files in the mount directory\nfiles = sandbox.fs.list_files(mount_dir)\nputs \"Files: #{files}\"\n\n# Create a new sandbox with the same volume\n# and mount it to the different path\nother_dir = '/home/daytona/my-files'\nother_sandbox = daytona.create(\n  Daytona::CreateSandboxFromSnapshotParams.new(\n    language: Daytona::CodeLanguage::PYTHON,\n    volumes: [DaytonaApiClient::SandboxVolume.new(volume_id: volume.id, mount_path: other_dir)]\n  )\n)\n\n# List files in the mount directory\nfiles = other_sandbox.fs.list_files(other_dir)\nputs \"Files: #{files}\"\n\n# Get the file from the mount directory\nfile = other_sandbox.fs.download_file(File.expand_path('new-file.txt', other_dir))\nputs \"File: #{file}\"\n\n# Cleanup\ndaytona.delete(sandbox)\ndaytona.delete(other_sandbox)\ndaytona.volume.delete(volume)\n"
  },
  {
    "path": "examples/typescript/auto-archive/index.ts",
    "content": "import { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  // Default interval\n  const sandbox1 = await daytona.create()\n  console.log(sandbox1.autoArchiveInterval)\n\n  // Set interval to 1 hour\n  await sandbox1.setAutoArchiveInterval(60)\n  console.log(sandbox1.autoArchiveInterval)\n\n  // Max interval\n  const sandbox2 = await daytona.create({\n    autoArchiveInterval: 0,\n  })\n  console.log(sandbox2.autoArchiveInterval)\n\n  // 1 day interval\n  const sandbox3 = await daytona.create({\n    autoArchiveInterval: 1440,\n  })\n  console.log(sandbox3.autoArchiveInterval)\n\n  await sandbox1.delete()\n  await sandbox2.delete()\n  await sandbox3.delete()\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "examples/typescript/auto-delete/index.ts",
    "content": "import { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  // Auto-delete is disabled by default\n  const sandbox1 = await daytona.create()\n  console.log(sandbox1.autoDeleteInterval)\n\n  // Auto-delete after the Sandbox has been stopped for 1 hour\n  await sandbox1.setAutoDeleteInterval(60)\n  console.log(sandbox1.autoDeleteInterval)\n\n  // Delete immediately upon stopping\n  await sandbox1.setAutoDeleteInterval(0)\n  console.log(sandbox1.autoDeleteInterval)\n\n  // Disable auto-delete\n  await sandbox1.setAutoDeleteInterval(-1)\n  console.log(sandbox1.autoDeleteInterval)\n\n  // Auto-delete after the Sandbox has been stopped for 1 day\n  const sandbox2 = await daytona.create({\n    autoDeleteInterval: 1440,\n  })\n  console.log(sandbox2.autoDeleteInterval)\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "examples/typescript/charts/index.ts",
    "content": "import {\n  BarChart,\n  BoxAndWhiskerChart,\n  Chart,\n  ChartType,\n  CompositeChart,\n  Daytona,\n  LineChart,\n  PieChart,\n  ScatterChart,\n  Image,\n} from '@daytonaio/sdk'\nimport * as fs from 'fs'\nimport * as path from 'path'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  //  first, create a sandbox\n  const sandbox = await daytona.create(\n    {\n      image: Image.debianSlim('3.13').pipInstall('matplotlib'),\n    },\n    {\n      onSnapshotCreateLogs: console.log,\n    },\n  )\n\n  try {\n    const response = await sandbox.process.codeRun(code)\n    if (response.exitCode !== 0) {\n      console.error('Execution failed with exit code', response.exitCode)\n      console.error('Output:', response.artifacts?.stdout)\n      return\n    }\n    for (const chart of response.artifacts?.charts || []) {\n      saveChartImage(chart)\n      printChart(chart)\n    }\n  } catch (error) {\n    console.error('Execution error:', error)\n  } finally {\n    //  cleanup\n    await daytona.delete(sandbox)\n  }\n}\n\nmain()\n\nconst code = `\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Sample data\nx = np.linspace(0, 10, 30)\ny = np.sin(x)\ncategories = ['A', 'B', 'C', 'D', 'E']\nvalues = [40, 63, 15, 25, 8]\nbox_data = [np.random.normal(0, std, 100) for std in range(1, 6)]\n\n# 1. Line Chart\nplt.figure(figsize=(8, 5))\nplt.plot(x, y, 'b-', linewidth=2)\nplt.title('Line Chart')\nplt.xlabel('X-axis (seconds)')  # Added unit\nplt.ylabel('Y-axis (amplitude)')  # Added unit\nplt.grid(True)\nplt.show()\n\n# 2. Scatter Plot\nplt.figure(figsize=(8, 5))\nplt.scatter(x, y, c=y, cmap='viridis', s=100*np.abs(y))\nplt.colorbar(label='Value (normalized)')  # Added unit\nplt.title('Scatter Plot')\nplt.xlabel('X-axis (time in seconds)')  # Added unit\nplt.ylabel('Y-axis (signal strength)')  # Added unit\nplt.show()\n\n# 3. Bar Chart\nplt.figure(figsize=(10, 6))\nplt.bar(categories, values, color='skyblue', edgecolor='navy')\nplt.title('Bar Chart')\nplt.xlabel('Categories')  # No change (categories don't have units)\nplt.ylabel('Values (count)')  # Added unit\nplt.show()\n\n# 4. Pie Chart\nplt.figure(figsize=(8, 8))\nplt.pie(values, labels=categories,\n        autopct='%1.1f%%',\n        colors=plt.cm.Set3.colors, shadow=True, startangle=90)\nplt.title('Pie Chart (Distribution in %)')  # Modified title\nplt.axis('equal')  # Equal aspect ratio ensures the pie chart is circular\nplt.legend()\nplt.show()\n\n# 5. Box and Whisker Plot\nplt.figure(figsize=(10, 6))\nplt.boxplot(box_data, patch_artist=True, \n            boxprops=dict(facecolor='lightblue'),\n            medianprops=dict(color='red', linewidth=2))\nplt.title('Box and Whisker Plot')\nplt.xlabel('Groups (Experiment IDs)')  # Added unit\nplt.ylabel('Values (measurement units)')  # Added unit\nplt.grid(True, linestyle='--', alpha=0.7)\nplt.show()\n`\n\nfunction printChart(chart: Chart) {\n  console.log('Type:', chart.type)\n  console.log('Title:', chart.title)\n\n  if (chart.type === ChartType.LINE) {\n    const lineChart = chart as LineChart\n    console.log('X Label:', lineChart.x_label)\n    console.log('Y Label:', lineChart.y_label)\n    console.log('X Ticks:', lineChart.x_ticks)\n    console.log('Y Ticks:', lineChart.y_ticks)\n    console.log('X Tick Labels:', lineChart.x_tick_labels)\n    console.log('Y Tick Labels:', lineChart.y_tick_labels)\n    console.log('X Scale:', lineChart.x_scale)\n    console.log('Y Scale:', lineChart.y_scale)\n    console.log('Elements:')\n    console.dir(lineChart.elements, { depth: null })\n  } else if (chart.type === ChartType.SCATTER) {\n    const scatterChart = chart as ScatterChart\n    console.log('X Label:', scatterChart.x_label)\n    console.log('Y Label:', scatterChart.y_label)\n    console.log('X Ticks:', scatterChart.x_ticks)\n    console.log('Y Ticks:', scatterChart.y_ticks)\n    console.log('X Tick Labels:', scatterChart.x_tick_labels)\n    console.log('Y Tick Labels:', scatterChart.y_tick_labels)\n    console.log('X Scale:', scatterChart.x_scale)\n    console.log('Y Scale:', scatterChart.y_scale)\n    console.log('Elements:')\n    console.dir(scatterChart.elements, { depth: null })\n  } else if (chart.type === ChartType.BAR) {\n    const barChart = chart as BarChart\n    console.log('X Label:', barChart.x_label)\n    console.log('Y Label:', barChart.y_label)\n    console.log('Elements:', barChart.elements)\n  } else if (chart.type === ChartType.PIE) {\n    const pieChart = chart as PieChart\n    console.log('Elements:', pieChart.elements)\n  } else if (chart.type === ChartType.BOX_AND_WHISKER) {\n    const boxAndWhiskerChart = chart as BoxAndWhiskerChart\n    console.log('X Label:', boxAndWhiskerChart.x_label)\n    console.log('Y Label:', boxAndWhiskerChart.y_label)\n    console.log('Elements:', boxAndWhiskerChart.elements)\n  } else if (chart.type === ChartType.COMPOSITE_CHART) {\n    const compositeChart = chart as CompositeChart\n    console.log('Elements:\\n')\n    compositeChart.elements.forEach(printChart)\n  }\n  console.log()\n}\n\nfunction saveChartImage(chart: Chart) {\n  if (!chart.png) {\n    console.log('No image data available for this chart')\n    return\n  }\n  const imgData = Buffer.from(chart.png, 'base64')\n  const scriptDir = __dirname\n  const filename = chart.title\n    ? path.join(scriptDir, `${chart.title}.png`)\n    : path.join(scriptDir, `chart_${Date.now()}.png`)\n  fs.writeFileSync(filename, imgData)\n  console.log(`Image saved as: ${filename}`)\n}\n"
  },
  {
    "path": "examples/typescript/declarative-image/index.ts",
    "content": "import { Daytona, Image } from '@daytonaio/sdk'\nimport fs from 'fs'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  // Generate unique name for the snapshot to avoid conflicts\n  const snapshotName = `node-example:${Date.now()}`\n  console.log(`Creating snapshot with name: ${snapshotName}`)\n\n  // Create a local file with some data\n  const localFilePath = 'file_example.txt'\n  const localFileContent = 'Hello, World!'\n  fs.writeFileSync(localFilePath, localFileContent)\n\n  // Create a Python image with common data science packages\n  const image = Image.debianSlim('3.12')\n    .pipInstall(['numpy', 'pandas', 'matplotlib', 'scipy', 'scikit-learn'])\n    .runCommands('apt-get update && apt-get install -y git', 'mkdir -p /home/daytona/workspace')\n    .workdir('/home/daytona/workspace')\n    .env({\n      MY_ENV_VAR: 'My Environment Variable',\n    })\n    .addLocalFile(localFilePath, '/home/daytona/workspace/file_example.txt')\n\n  // Create the snapshot\n  console.log(`=== Creating Snapshot: ${snapshotName} ===`)\n  await daytona.snapshot.create(\n    {\n      name: snapshotName,\n      image,\n      resources: {\n        cpu: 1,\n        memory: 1,\n        disk: 3,\n      },\n    },\n    {\n      onLogs: console.log,\n    },\n  )\n\n  // Create first sandbox using the pre-built image\n  console.log('\\n=== Creating Sandbox from Pre-built Snapshot ===')\n  const sandbox1 = await daytona.create({\n    snapshot: snapshotName,\n  })\n\n  try {\n    // Verify the first sandbox environment\n    console.log('Verifying sandbox from pre-built image:')\n    const nodeResponse = await sandbox1.process.executeCommand('python --version && pip list')\n    console.log('Python environment:')\n    console.log(nodeResponse.result)\n\n    // Verify the file was added to the image\n    const fileContent = await sandbox1.process.executeCommand('cat file_example.txt')\n    console.log('File content:')\n    console.log(fileContent.result)\n  } finally {\n    // Clean up first sandbox\n    await daytona.delete(sandbox1)\n  }\n\n  // Create second sandbox with a new dynamic image\n  console.log('\\n=== Creating Sandbox with Dynamic Image ===')\n\n  // Define a new dynamic image for the second sandbox\n  const dynamicImage = Image.debianSlim('3.13')\n    .pipInstall(['pytest', 'pytest-cov', 'black', 'isort', 'mypy', 'ruff'])\n    .runCommands('apt-get update && apt-get install -y git', 'mkdir -p /home/daytona/project')\n    .workdir('/home/daytona/project')\n    .env({\n      NODE_ENV: 'development',\n    })\n\n  // Create sandbox with the dynamic image\n  const sandbox2 = await daytona.create(\n    {\n      image: dynamicImage,\n    },\n    {\n      timeout: 0,\n      onSnapshotCreateLogs: console.log,\n    },\n  )\n\n  try {\n    // Verify the second sandbox environment\n    console.log('Verifying sandbox with dynamic image:')\n    const toolsResponse = await sandbox2.process.executeCommand('pip list | grep -E \"pytest|black|isort|mypy|ruff\"')\n    console.log('Development tools:')\n    console.log(toolsResponse.result)\n  } finally {\n    // Clean up second sandbox\n    await daytona.delete(sandbox2)\n  }\n}\n\nmain().catch((error) => {\n  console.error('Error:', error)\n  process.exit(1)\n})\n"
  },
  {
    "path": "examples/typescript/exec-command/index.ts",
    "content": "import { Daytona, Sandbox, Image, DaytonaTimeoutError, ExecutionError, OutputMessage } from '@daytonaio/sdk'\n\nasync function basicExec(sandbox: Sandbox) {\n  //  run some typescript code directly\n  const codeResult = await sandbox.process.codeRun('console.log(\"Hello World from code!\")')\n  if (codeResult.exitCode !== 0) {\n    console.error('Error running code:', codeResult.exitCode)\n  } else {\n    console.log(codeResult.result)\n  }\n\n  //  run os command\n  const cmdResult = await sandbox.process.executeCommand('echo \"Hello World from CMD!\"')\n  if (cmdResult.exitCode !== 0) {\n    console.error('Error running code:', cmdResult.exitCode)\n  } else {\n    console.log(cmdResult.result)\n  }\n}\n\nasync function sessionExec(sandbox: Sandbox) {\n  //  exec session\n  //  session allows for multiple commands to be executed in the same context\n  await sandbox.process.createSession('exec-session-1')\n\n  //  get the session details any time\n  const session = await sandbox.process.getSession('exec-session-1')\n  console.log('session: ', session)\n\n  //  execute a first command in the session\n  const command = await sandbox.process.executeSessionCommand('exec-session-1', {\n    command: 'export FOO=BAR',\n  })\n\n  //  get the session details again to see the command has been executed\n  const sessionUpdated = await sandbox.process.getSession('exec-session-1')\n  console.log('sessionUpdated: ', sessionUpdated)\n\n  //  get the command details\n  const sessionCommand = await sandbox.process.getSessionCommand('exec-session-1', command.cmdId)\n  console.log('sessionCommand: ', sessionCommand)\n\n  //  execute a second command in the session and see that the environment variable is set\n  const response = await sandbox.process.executeSessionCommand('exec-session-1', {\n    command: 'echo $FOO',\n  })\n  console.log(`FOO=${response.stdout}`)\n\n  //  we can also get the logs for the command any time after it is executed\n  const logs = await sandbox.process.getSessionCommandLogs('exec-session-1', response.cmdId)\n  console.log('[STDOUT]:', logs.stdout)\n  console.log('[STDERR]:', logs.stderr)\n\n  //  we can also delete the session\n  await sandbox.process.deleteSession('exec-session-1')\n}\n\nasync function sessionExecLogsAsync(sandbox: Sandbox) {\n  console.log('Executing long running command in a session and streaming logs asynchronously...')\n\n  const sessionId = 'exec-session-async-logs'\n  await sandbox.process.createSession(sessionId)\n\n  const command = await sandbox.process.executeSessionCommand(sessionId, {\n    command:\n      'printf \"Enter your name: \\\\n\" && read name && printf \"Hello, %s\\\\n\" \"$name\"; ' +\n      'counter=1; while (( counter <= 3 )); do echo \"Count: $counter\"; ' +\n      '((counter++)); sleep 2; done; non-existent-command',\n    runAsync: true,\n  })\n\n  console.log('sending input to the command after 1 second')\n  await new Promise((resolve) => setTimeout(resolve, 1000))\n  await sandbox.process.sendSessionCommandInput(sessionId, command.cmdId!, 'Alice')\n  console.log('input sent to the command')\n\n  await sandbox.process.getSessionCommandLogs(\n    sessionId,\n    command.cmdId,\n    (stdout) => console.log('[STDOUT]:', stdout),\n    (stderr) => console.log('[STDERR]:', stderr),\n  )\n}\n\nasync function statefulCodeInterpreter(sandbox: Sandbox) {\n  const logStdout = (msg: OutputMessage) => process.stdout.write(`[STDOUT] ${msg.output}`)\n  const logStderr = (msg: OutputMessage) => process.stdout.write(`[STDERR] ${msg.output}`)\n  const logError = (err: ExecutionError) => {\n    process.stdout.write(`[ERROR] ${err.name}: ${err.value}\\n`)\n    if (err.traceback) {\n      process.stdout.write(`${err.traceback}\\n`)\n    }\n  }\n\n  console.log('\\n' + '='.repeat(60))\n  console.log('Stateful Code Interpreter')\n  console.log('='.repeat(60))\n  const baseline = await sandbox.codeInterpreter.runCode(`counter = 1\nprint(f'Initialized counter = {counter}')`)\n  process.stdout.write(`[STDOUT] ${baseline.stdout}`)\n\n  await sandbox.codeInterpreter.runCode(\n    `counter += 1\nprint(f'Counter after second call = {counter}')`,\n    {\n      onStdout: logStdout,\n      onStderr: logStderr,\n      onError: logError,\n    },\n  )\n\n  console.log('\\n' + '='.repeat(60))\n  console.log('Context isolation')\n  console.log('='.repeat(60))\n  const ctx = await sandbox.codeInterpreter.createContext()\n  try {\n    await sandbox.codeInterpreter.runCode(\n      `value = 'stored in isolated context'\nprint(f'Isolated context value: {value}')`,\n      {\n        context: ctx,\n        onStdout: logStdout,\n        onStderr: logStderr,\n        onError: logError,\n      },\n    )\n\n    console.log('--- Print value from same context ---')\n    const ctxResult = await sandbox.codeInterpreter.runCode(\"print(f'Value still available: {value}')\", {\n      context: ctx,\n    })\n    process.stdout.write(`[STDOUT] ${ctxResult.stdout}`)\n\n    console.log('--- Print value from different context ---')\n    await sandbox.codeInterpreter.runCode('print(value)', {\n      onStdout: logStdout,\n      onStderr: logStderr,\n      onError: logError,\n    })\n  } finally {\n    await sandbox.codeInterpreter.deleteContext(ctx)\n  }\n\n  console.log('\\n' + '='.repeat(60))\n  console.log('Timeout handling')\n  console.log('='.repeat(60))\n  try {\n    await sandbox.codeInterpreter.runCode(\n      `import time\nprint('Starting long running task...')\ntime.sleep(5)\nprint('Finished!')`,\n      {\n        timeout: 1,\n        onStdout: logStdout,\n        onStderr: logStderr,\n        onError: logError,\n      },\n    )\n  } catch (error) {\n    if (error instanceof DaytonaTimeoutError) {\n      console.log(`Timed out as expected: ${error.message}`)\n    } else {\n      throw error\n    }\n  }\n}\n\nasync function main() {\n  const daytona = new Daytona()\n\n  //  first, create a sandbox\n  const sandbox = await daytona.create(\n    {\n      image: Image.base('ubuntu:22.04').runCommands(\n        'apt-get update',\n        'apt-get install -y --no-install-recommends python3 python3-pip python3-venv',\n        'apt-get install -y --no-install-recommends nodejs npm coreutils',\n        'curl -fsSL https://deb.nodesource.com/setup_20.x | bash -',\n        'apt-get install -y nodejs',\n        'npm install -g ts-node typescript',\n      ),\n      language: 'typescript',\n      autoStopInterval: 60,\n      autoArchiveInterval: 60,\n      autoDeleteInterval: 120,\n    },\n    {\n      timeout: 200,\n      onSnapshotCreateLogs: console.log,\n    },\n  )\n\n  try {\n    await basicExec(sandbox)\n    await sessionExec(sandbox)\n    await sessionExecLogsAsync(sandbox)\n    await statefulCodeInterpreter(sandbox)\n  } catch (error) {\n    console.error('Error executing commands:', error)\n  } finally {\n    //  cleanup\n    await daytona.delete(sandbox)\n  }\n}\n\nmain()\n"
  },
  {
    "path": "examples/typescript/file-operations/index.ts",
    "content": "import { Daytona } from '@daytonaio/sdk'\nimport * as fs from 'fs'\nimport * as path from 'path'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  //  first, create a sandbox\n  const sandbox = await daytona.create()\n\n  try {\n    console.log(`Created sandbox with ID: ${sandbox.id}`)\n\n    //  list files in the sandbox\n    const files = await sandbox.fs.listFiles('.')\n    console.log('Initial files:', files)\n\n    //  create a new directory in the sandbox\n    const newDir = 'project-files'\n    await sandbox.fs.createFolder(newDir, '755')\n\n    // Create a local file for demonstration\n    const localFilePath = 'local-example.txt'\n    fs.writeFileSync(localFilePath, 'This is a local file created for use case purposes')\n\n    // Create a configuration file with JSON data\n    const configData = JSON.stringify(\n      {\n        name: 'project-config',\n        version: '1.0.0',\n        settings: {\n          debug: true,\n          maxConnections: 10,\n        },\n      },\n      null,\n      2,\n    )\n\n    // Upload multiple files at once - both from local path and from buffers\n    await sandbox.fs.uploadFiles([\n      {\n        source: localFilePath,\n        destination: path.join(newDir, 'example.txt'),\n      },\n      {\n        source: Buffer.from(configData),\n        destination: path.join(newDir, 'config.json'),\n      },\n      {\n        source: Buffer.from('#!/bin/bash\\necho \"Hello from script!\"\\nexit 0'),\n        destination: path.join(newDir, 'script.sh'),\n      },\n    ])\n\n    // Execute commands on the sandbox to verify files and make them executable\n    console.log('Verifying uploaded files:')\n    const lsResult = await sandbox.process.executeCommand(`ls -la ${newDir}`)\n    console.log(lsResult.result)\n\n    // Make the script executable\n    await sandbox.process.executeCommand(`chmod +x ${path.join(newDir, 'script.sh')}`)\n\n    // Run the script\n    console.log('Running script:')\n    const scriptResult = await sandbox.process.executeCommand(`${path.join(newDir, 'script.sh')}`)\n    console.log(scriptResult.result)\n\n    //  search for files in the project\n    const matches = await sandbox.fs.searchFiles(newDir, '*.json')\n    console.log('JSON files found:', matches)\n\n    //  replace content in config file\n    await sandbox.fs.replaceInFiles([path.join(newDir, 'config.json')], '\"debug\": true', '\"debug\": false')\n\n    // Download multiple files - mix of local file and memory download\n    console.log('Downloading multiple files:')\n    const downloadResults = await sandbox.fs.downloadFiles([\n      {\n        source: path.join(newDir, 'config.json'),\n        destination: 'local-config.json',\n      },\n      {\n        source: path.join(newDir, 'example.txt'),\n      },\n      {\n        source: path.join(newDir, 'script.sh'),\n        destination: 'local-script.sh',\n      },\n    ])\n\n    for (const result of downloadResults) {\n      if (result.error) {\n        console.error(`Error downloading ${result.source}: ${result.error}`)\n      } else if (typeof result.result === 'string') {\n        console.log(`Downloaded ${result.source} to ${result.result}`)\n      } else {\n        console.log(`Downloaded ${result.source} to memory (${result.result?.length} bytes)`)\n      }\n    }\n\n    // Single file download example\n    console.log('Single file download example:')\n    const reportBuffer = await sandbox.fs.downloadFile(path.join(newDir, 'config.json'))\n    console.log('Config content:', reportBuffer.toString())\n\n    // Create a report of all operations\n    const reportData = `\nProject Files Report:\n---------------------\nTime: ${new Date().toISOString()}\nFiles: ${matches.files.length} JSON files found\nConfig: ${reportBuffer.includes('\"debug\": false') ? 'Production mode' : 'Debug mode'}\nScript: ${scriptResult.exitCode === 0 ? 'Executed successfully' : 'Failed'}\n    `.trim()\n\n    // Save the report\n    await sandbox.fs.uploadFile(Buffer.from(reportData), path.join(newDir, 'report.txt'))\n\n    // Clean up local file\n    fs.unlinkSync(localFilePath)\n    if (fs.existsSync('local-config.json')) fs.unlinkSync('local-config.json')\n    if (fs.existsSync('local-script.sh')) fs.unlinkSync('local-script.sh')\n  } catch (error) {\n    console.error('Error:', error)\n  } finally {\n    //  cleanup\n    await daytona.delete(sandbox)\n  }\n}\n\nmain()\n"
  },
  {
    "path": "examples/typescript/git-lsp/index.ts",
    "content": "import { Daytona, Image } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  //  first, create a sandbox\n  const sandbox = await daytona.create(\n    {\n      image: Image.base('ubuntu:25.10').runCommands(\n        'apt-get update && apt-get install -y --no-install-recommends nodejs npm coreutils',\n        'curl -fsSL https://deb.nodesource.com/setup_20.x | bash -',\n        'apt-get install -y nodejs',\n        'npm install -g ts-node typescript typescript-language-server',\n      ),\n      language: 'typescript',\n    },\n    {\n      onSnapshotCreateLogs: console.log,\n    },\n  )\n\n  try {\n    const projectDir = 'learn-typescript'\n\n    //  clone the repository\n    await sandbox.git.clone('https://github.com/panaverse/learn-typescript', projectDir, 'master')\n\n    //  search for the file we want to work on\n    const matches = await sandbox.fs.findFiles(projectDir, 'var obj1 = new Base();')\n    console.log('Matches:', matches)\n\n    //  start the language server\n    const lsp = await sandbox.createLspServer('typescript', projectDir)\n    await lsp.start()\n\n    //  notify the language server of the document we want to work on\n    await lsp.didOpen(matches[0].file!)\n\n    //  get symbols in the document\n    const symbols = await lsp.documentSymbols(matches[0].file!)\n    console.log('Symbols:', symbols)\n\n    //  fix the error in the document\n    await sandbox.fs.replaceInFiles([matches[0].file!], 'var obj1 = new Base();', 'var obj1 = new E();')\n\n    //  notify the language server of the document change\n    await lsp.didClose(matches[0].file!)\n    await lsp.didOpen(matches[0].file!)\n\n    //  get completions at a specific position\n    const completions = await lsp.completions(matches[0].file!, {\n      line: 12,\n      character: 18,\n    })\n    console.log('Completions:', completions)\n  } catch (error) {\n    console.error('Error creating sandbox:', error)\n  } finally {\n    //  cleanup\n    await daytona.delete(sandbox)\n  }\n}\n\nmain()\n"
  },
  {
    "path": "examples/typescript/lifecycle/index.ts",
    "content": "import { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  console.log('Creating sandbox')\n  const sandbox = await daytona.create()\n  console.log('Sandbox created')\n\n  await sandbox.setLabels({\n    public: 'true',\n  })\n\n  console.log('Stopping sandbox')\n  await sandbox.stop()\n  console.log('Sandbox stopped')\n\n  console.log('Starting sandbox')\n  await sandbox.start()\n  console.log('Sandbox started')\n\n  console.log('Getting existing sandbox')\n  const existingSandbox = await daytona.get(sandbox.id)\n  console.log('Got existing sandbox')\n\n  const response = await existingSandbox.process.executeCommand(\n    'echo \"Hello World from exec!\"',\n    undefined,\n    undefined,\n    10,\n  )\n  if (response.exitCode !== 0) {\n    console.error(`Error: ${response.exitCode} ${response.result}`)\n  } else {\n    console.log(response.result)\n  }\n\n  const result = await daytona.list()\n  console.log('Total sandboxes count:', result.total)\n\n  console.log(`Printing first sandbox -> id: ${result.items[0].id} state: ${result.items[0].state}`)\n\n  console.log('Deleting sandbox')\n  await sandbox.delete()\n  console.log('Sandbox deleted')\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "examples/typescript/network-settings/index.ts",
    "content": "import { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  // Default settings\n  const sandbox1 = await daytona.create()\n  console.log('networkBlockAll:', sandbox1.networkBlockAll)\n  console.log('networkAllowList:', sandbox1.networkAllowList)\n\n  // Block all network access\n  const sandbox2 = await daytona.create({\n    networkBlockAll: true,\n  })\n  console.log('networkBlockAll:', sandbox2.networkBlockAll)\n  console.log('networkAllowList:', sandbox2.networkAllowList)\n\n  // Explicitly allow list of network addresses\n  const sandbox3 = await daytona.create({\n    networkAllowList: '192.168.1.0/16,10.0.0.0/24',\n  })\n  console.log('networkBlockAll:', sandbox3.networkBlockAll)\n  console.log('networkAllowList:', sandbox3.networkAllowList)\n\n  await sandbox1.delete()\n  await sandbox2.delete()\n  await sandbox3.delete()\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "examples/typescript/pagination/sandbox.ts",
    "content": "import { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  const result = await daytona.list({ 'my-label': 'my-value' }, 2, 10)\n  for (const sandbox of result.items) {\n    console.log(`${sandbox.id}: ${sandbox.state}`)\n  }\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "examples/typescript/pagination/snapshot.ts",
    "content": "import { Daytona } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  const result = await daytona.snapshot.list(2, 10)\n  console.log(`Found ${result.total} snapshots`)\n  result.items.forEach((snapshot) => console.log(`${snapshot.name} (${snapshot.imageName})`))\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "examples/typescript/pty/index.ts",
    "content": "import { Daytona, Sandbox } from '@daytonaio/sdk'\n\nasync function interactivePtySession(sandbox: Sandbox) {\n  console.log('=== First PTY Session: Interactive Command with Exit ===')\n\n  const ptySessionId = 'interactive-pty-session'\n\n  // Create PTY session with data handler\n  const ptyHandle = await sandbox.process.createPty({\n    id: ptySessionId,\n    cols: 120,\n    rows: 30,\n    onData: (data) => {\n      // Decode UTF-8 bytes to text and write directly to preserve terminal formatting\n      const text = new TextDecoder().decode(data)\n      process.stdout.write(text)\n    },\n  })\n\n  // Send interactive command\n  console.log('\\nSending interactive read command...')\n  await ptyHandle.sendInput('printf \"Enter your name: \" && read name && printf \"Hello, %s\\\\n\" \"$name\"\\n')\n\n  // Wait and respond\n  await new Promise((resolve) => setTimeout(resolve, 1000))\n  await ptyHandle.sendInput('Bob\\n')\n\n  // Resize the PTY session\n  const ptySessionInfo = await sandbox.process.resizePtySession(ptySessionId, 80, 25)\n  console.log(`\\nPTY session resized to ${ptySessionInfo.cols}x${ptySessionInfo.rows}`)\n\n  // Send another command\n  await new Promise((resolve) => setTimeout(resolve, 1000))\n  await ptyHandle.sendInput('ls -la\\n')\n\n  // Send exit command\n  await new Promise((resolve) => setTimeout(resolve, 1000))\n  await ptyHandle.sendInput('exit\\n')\n\n  // Wait for PTY to exit\n  const result = await ptyHandle.wait()\n  console.log(`\\nPTY session exited with code: ${result.exitCode}`)\n  if (result.error) {\n    console.log(`Error: ${result.error}`)\n  }\n}\n\nasync function killPtySession(sandbox: Sandbox) {\n  console.log('\\n=== Second PTY Session: Kill PTY Session ===')\n\n  const ptySessionId = 'kill-pty-session'\n\n  // Create PTY session with data handler\n  const ptyHandle = await sandbox.process.createPty({\n    id: ptySessionId,\n    cols: 120,\n    rows: 30,\n    onData: (data) => {\n      // Decode UTF-8 bytes to text and write directly to preserve terminal formatting\n      const text = new TextDecoder().decode(data)\n      process.stdout.write(text)\n    },\n  })\n\n  // Send a long-running command\n  console.log('\\nSending long-running command (infinite loop)...')\n  await ptyHandle.sendInput('while true; do echo \"Running... $(date)\"; sleep 1; done\\n')\n\n  // Let it run for a few seconds\n  await new Promise((resolve) => setTimeout(resolve, 3000))\n\n  // Kill the PTY session\n  await ptyHandle.kill()\n\n  // Wait for PTY to terminate\n  const result = await ptyHandle.wait()\n  console.log(`\\nPTY session terminated. Exit code: ${result.exitCode}`)\n  if (result.error) {\n    console.log(`Error: ${result.error}`)\n  }\n}\n\nasync function main() {\n  const daytona = new Daytona()\n  const sandbox = await daytona.create()\n\n  try {\n    // Interactive PTY session with exit\n    await interactivePtySession(sandbox)\n    // PTY session killed with .kill()\n    await killPtySession(sandbox)\n  } catch (error) {\n    console.error('Error executing PTY commands:', error)\n  } finally {\n    console.log(`\\nDeleting sandbox: ${sandbox.id}`)\n    await daytona.delete(sandbox)\n  }\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "examples/typescript/region/index.tsx",
    "content": "import { Daytona, Image } from '@daytonaio/sdk'\n\nasync function main() {\n  const daytona = new Daytona({\n    target: 'us',\n  })\n\n  const snapshot1 = `us-${Date.now()}`\n  console.log(`Creating snapshot ${snapshot1}`)\n  try {\n    await daytona.snapshot.create({\n      name: snapshot1,\n      image: Image.debianSlim('3.12'),\n      regionId: 'us',\n    })\n  } catch (error: any) {\n    console.error(error?.message)\n  }\n  console.log('--------------------------------')\n\n  const snapshot2 = `eu-${Date.now()}`\n  console.log(`Creating snapshot ${snapshot2}`)\n  try {\n    await daytona.snapshot.create({\n      name: snapshot2,\n      image: Image.debianSlim('3.13'),\n      regionId: 'eu',\n    })\n  } catch (error: any) {\n    console.error('error', error?.message)\n  }\n  console.log('--------------------------------')\n\n  console.log(`Creating sandbox from snapshot ${snapshot1}`)\n  try {\n    const sandbox = await daytona.create({\n      snapshot: snapshot1,\n    })\n    await daytona.delete(sandbox)\n  } catch (error: any) {\n    console.error(error?.message)\n  }\n  console.log('--------------------------------')\n\n  console.log(`Creating sandbox from snapshot ${snapshot2}`)\n  try {\n    const sandbox = await daytona.create({\n      snapshot: snapshot2,\n    })\n    await daytona.delete(sandbox)\n  } catch (error: any) {\n    console.error('error', error?.message)\n  }\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "examples/typescript/volumes/index.ts",
    "content": "import { Daytona } from '@daytonaio/sdk'\nimport path from 'path'\n\nasync function main() {\n  const daytona = new Daytona()\n\n  //  Create a new volume or get an existing one\n  const volume = await daytona.volume.get('my-volume', true)\n\n  // Mount the volume to the sandbox\n  const mountDir1 = '/home/daytona/volume'\n\n  const sandbox1 = await daytona.create({\n    language: 'typescript',\n    volumes: [{ volumeId: volume.id, mountPath: mountDir1 }],\n  })\n\n  // Create a new directory in the mount directory\n  const newDir = path.join(mountDir1, 'new-dir')\n  await sandbox1.fs.createFolder(newDir, '755')\n\n  // Create a new file in the mount directory\n  const newFile = path.join(mountDir1, 'new-file.txt')\n  await sandbox1.fs.uploadFile(Buffer.from('Hello, World!'), newFile)\n\n  // Create a new sandbox with the same volume\n  // and mount it to the different path\n  const mountDir2 = '/home/daytona/my-files'\n\n  const sandbox2 = await daytona.create({\n    language: 'typescript',\n    volumes: [{ volumeId: volume.id, mountPath: mountDir2 }],\n  })\n\n  // List files in the mount directory\n  const files = await sandbox2.fs.listFiles(mountDir2)\n  console.log('Files:', files)\n\n  // Get the file from the first sandbox\n  const file = await sandbox1.fs.downloadFile(newFile)\n  console.log('File:', file.toString())\n\n  // Mount a specific subpath within the volume\n  // This is useful for isolating data or implementing multi-tenancy\n  const mountDir3 = '/home/daytona/subpath'\n\n  const sandbox3 = await daytona.create({\n    language: 'typescript',\n    volumes: [{ volumeId: volume.id, mountPath: mountDir3, subpath: 'users/alice' }],\n  })\n\n  // This sandbox will only see files within the 'users/alice' subpath\n  // Create a file in the subpath\n  const subpathFile = path.join(mountDir3, 'alice-file.txt')\n  await sandbox3.fs.uploadFile(Buffer.from(\"Hello from Alice's subpath!\"), subpathFile)\n\n  // The file is stored at: volume-root/users/alice/alice-file.txt\n  // but appears at: /home/daytona/subpath/alice-file.txt in the sandbox\n\n  // Cleanup\n  await daytona.delete(sandbox1)\n  await daytona.delete(sandbox2)\n  await daytona.delete(sandbox3)\n  // await daytona.volume.delete(volume)\n}\n\nmain()\n"
  },
  {
    "path": "functions/auth0/setCustomClaims.onExecutePostLogin.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Handler that will be called during the execution of a PostLogin flow.\n *\n * @param {Event} event - Details about the user and the context in which they are logging in.\n * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.\n */\nexports.onExecutePostLogin = async (event, api) => {\n  api.accessToken.setCustomClaim('email', event.user.email)\n  api.accessToken.setCustomClaim('name', event.user.name)\n  api.accessToken.setCustomClaim('email_verified', event.user.email_verified)\n  api.accessToken.setCustomClaim(\n    'phone_verified',\n    event.user.enrolledFactors && event.user.enrolledFactors.some((f) => f.type === 'phone' && f.method === 'sms'),\n  )\n  api.accessToken.setCustomClaim('identities', event.user.identities)\n  api.idToken.setCustomClaim('identities', event.user.identities)\n  api.idToken.setCustomClaim(\n    'phone_verified',\n    event.user.enrolledFactors && event.user.enrolledFactors.some((f) => f.type === 'phone' && f.method === 'sms'),\n  )\n}\n"
  },
  {
    "path": "functions/auth0/validateEmailUnused.onExecutePostLogin.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Handler that will be called during the execution of a PostLogin flow.\n *\n * @param {Event} event - Details about the user and the context in which they are logging in.\n * @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.\n */\nexports.onExecutePostLogin = async (event, api) => {\n  // Skip validation when performing account linking\n  if (event.request.query?.accountLinking === 'true') {\n    return\n  }\n\n  // User object must have an email address\n  if (!event.user.email) {\n    return api.access.deny('Please ensure your email address is public')\n  }\n\n  const ManagementClient = require('auth0').ManagementClient\n\n  const management = new ManagementClient({\n    domain: event.secrets.DOMAIN,\n    clientId: event.secrets.CLIENT_ID,\n    clientSecret: event.secrets.CLIENT_SECRET,\n    scope: 'read:users',\n  })\n\n  // Fetch users with this email address in the Auth0 database\n  let users = []\n\n  try {\n    users = await management.getUsersByEmail(event.user.email)\n  } catch (error) {\n    console.error('Failed to fetch Auth0 users:', error)\n    return api.access.deny('Something went wrong, please try again later')\n  }\n\n  // Skip validation if this is the only user with this email address\n  if (users.length <= 1) {\n    return\n  }\n\n  // Deny access if this user doesn't exist in the Daytona database\n  try {\n    const response = await fetch(`${event.secrets.DAYTONA_API_URL}/users/${event.user.user_id}`, {\n      headers: {\n        Authorization: `Bearer ${event.secrets.DAYTONA_API_KEY}`,\n      },\n    })\n\n    if (!response.ok) {\n      return api.access.deny('Something went wrong, please try again later')\n    }\n  } catch (error) {\n    console.error('Failed to fetch Daytona users:', error)\n    return api.access.deny('Something went wrong, please try again later')\n  }\n}\n"
  },
  {
    "path": "functions/auth0/validateEmailUnused.onExecutePreRegister.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Handler that will be called during the execution of a PreUserRegistration flow.\n *\n * @param {Event} event - Details about the context and user that is attempting to register.\n * @param {PreUserRegistrationAPI} api - Interface whose methods can be used to change the behavior of the signup.\n */\nexports.onExecutePreUserRegistration = async (event, api) => {\n  const ManagementClient = require('auth0').ManagementClient\n\n  const management = new ManagementClient({\n    domain: event.secrets.DOMAIN,\n    clientId: event.secrets.CLIENT_ID,\n    clientSecret: event.secrets.CLIENT_SECRET,\n    scope: 'read:users update:users',\n  })\n\n  try {\n    // Search for users with the same email\n    const users = await management.getUsersByEmail(event.user.email)\n\n    if (users.length >= 1) {\n      return api.access.deny('Email already used', 'Something went wrong, please try again later')\n    }\n  } catch (error) {\n    console.error('Failed to fetch users:', error)\n    return api.access.deny('Could not fetch users', 'Something went wrong, please try again later')\n  }\n}\n"
  },
  {
    "path": "functions/auth0/verifyAliasEmail.onExecutePreRegister.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\n/**\n * Handler that will be called during the execution of a PreUserRegistration flow.\n *\n * @param {Event} event - Details about the context and user that is attempting to register.\n * @param {PreUserRegistrationAPI} api - Interface whose methods can be used to change the behavior of the signup.\n */\nexports.onExecutePreUserRegistration = async (event, api) => {\n  if (event.user.email?.includes('+')) {\n    return api.access.deny(`Email alias detected: ${event.user.email}`, 'Email aliases not allowed')\n  }\n}\n"
  },
  {
    "path": "go.work",
    "content": "go 1.25.4\n\nuse (\n\t./apps/cli\n\t./apps/daemon\n\t./apps/otel-collector/exporter\n\t./apps/proxy\n\t./apps/runner\n\t./apps/snapshot-manager\n\t./apps/ssh-gateway\n\t./libs/api-client-go\n\t./libs/common-go\n\t./libs/computer-use\n\t./libs/sdk-go\n\t./libs/toolbox-api-client-go\n)\n"
  },
  {
    "path": "guides/python/ai-data-analyst/litellm/.gitignore",
    "content": "# Agent output files\nchart-*.png\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# Virtual Environments\nvenv/\nenv/\nENV/\nenv.bak/\nvenv.bak/\n.venv/\n.virtualenv/\n.pyenv/\n\n# Poetry\npoetry.lock\n.poetry/\n\n# Pipenv\nPipfile.lock\n\n# pyenv\n.python-version\n\n# Conda\nconda-meta/\n.conda/\n\n# PyCharm\n.idea/\n*.iml\n\n# VS Code\n.vscode/\n*.code-workspace\n\n# Jupyter Notebook\n.ipynb_checkpoints/\n*.ipynb_checkpoints/\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.env.local\n.env.*.local\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# macOS\n.DS_Store\n\n# Windows\nThumbs.db\nehthumbs.db\nDesktop.ini\n\n# Linux\n*~\n\n# Temporary files\n*.tmp\n*.bak\n*.swp\n*~"
  },
  {
    "path": "guides/python/ai-data-analyst/litellm/README.md",
    "content": "# LiteLLM Data Analysis Example (LiteLLM + Daytona)\n\n## Overview\n\nThis example demonstrates how to build a data analysis tool using [LiteLLM](https://litellm.ai/) and [Daytona](https://daytona.io) sandboxes. The script executes Python code in an isolated environment to analyze cafe sales data, enabling automated data analysis workflows with natural language prompts.\n\nIn this example, the agent analyzes a cafe sales dataset to find the three highest revenue products for January and visualizes the results in a bar chart.\n\n## Features\n\n- **Multiple LLM Providers:** Easily switch between different LLM providers including Anthropic, OpenAI, Mistral, and more through LiteLLM\n- **Secure sandbox execution:** All Python code runs in isolated Daytona sandboxes\n- **Natural language interface:** Describe your analysis task in plain English\n- **Automatic chart generation:** Visualizations are automatically saved as PNG files\n- **File handling:** Upload datasets and process results within the sandbox\n\n## Requirements\n\n- **Python:** Version 3.10 or higher is required\n\n> [!TIP]\n> It's recommended to use a virtual environment (`venv` or `poetry`) to isolate project dependencies.\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n### Required\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n\n### LLM Provider API Keys (choose one based on your provider)\n\n- `ANTHROPIC_API_KEY`: Required if using Anthropic models (default)\n- `OPENAI_API_KEY`: Required if using OpenAI models\n- `MISTRAL_API_KEY`: Required if using Mistral AI models\n- `DEEPSEEK_API_KEY`: Required if using DeepSeek models\n- `OPENROUTER_API_KEY`: Required if using OpenRouter models\n- See [Providers](https://docs.litellm.ai/docs/providers) for a complete list of providers and required API keys.\n\nCreate a `.env` file in the project directory with the appropriate variables for your chosen provider.\n\n## Getting Started\n\n### Setup and Run\n\n1. Create and activate a virtual environment:\n\n   ```bash\n   python3.10 -m venv venv  \n   source venv/bin/activate  # On Windows: venv\\Scripts\\activate\n   ```\n\n2. Install dependencies:\n\n   ```bash\n   pip install -e .\n   ```\n\n3. Run the example:\n\n   ```bash\n   python ai_data_analyst.py\n   ```\n\n## How It Works\n\n1. An LLM call generates Python code based on the data format and prompt\n2. A new Daytona sandbox is created, containing the data file\n3. The Python code is executed in the sandbox\n4. Any generated charts are saved as PNG files\n5. A second LLM call summarizes the code execution results\n\n## Configuration\n\n### Analysis Customization\n\nThe main prompt is configured in the `user_prompt` variable in `ai_data_analyst.py`:\n\n```typescript\nconst userPrompt = `Give the three highest revenue products for the month of January and show them as a bar chart.`;\n```\n\nYou can modify this to analyze different aspects of the data or try different visualization types.\n\nThe example uses `cafe_sales_data.csv`. To use your own dataset, replace this file and update the filename in the script if needed.\n\n### LLM Provider Configuration\n\nBy default, the example uses the following models, as specified in `ai_data_analyst.py`:\n\n```python\nCODING_MODEL = \"anthropic/claude-sonnet-4-0\"\nSUMMARY_MODEL = \"anthropic/claude-haiku-4-5\"\n```\n\nThe coding model is used for high accuracy code generation, and the summary model is used for fast summarization.\n\nOther suggested models include:\n\n- `openai/gpt-5.1`\n- `mistral/mistral-large-latest`\n- `deepseek/deepseek-chat`\n- `openrouter/moonshotai/kimi-k2`\n\nSee [Providers](https://docs.litellm.ai/docs/providers) for all supported models\n\n## Example Output\n\nWhen the script completes, you'll see output similar to:\n\n```\nPrompt: Give the three highest revenue products for the month of January and show them as a bar chart.\nGenerating code...\nRunning code...\n✓ Chart saved to chart-0.png\nResponse: Great! It looks like you successfully executed the code and identified the top three revenue-generating products for January:\n\n1. **Matcha Espresso Fusion** with a total revenue of \\$2,603.81.\n2. **Oat Milk Latte** with a total revenue of \\$2,548.65.\n3. **Nitro Cold Brew** with a total revenue of \\$2,242.41.\n```\n\nThe chart will be saved as `chart-0.png` in your project directory, showing a bar chart of the top three revenue-generating products for January.\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [LiteLLM Documentation](https://docs.litellm.ai/docs/)\n- [LiteLLM Providers](https://docs.litellm.ai/docs/providers)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/python/ai-data-analyst/litellm/ai_data_analyst.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport base64\nimport re\nfrom pathlib import Path\n\nfrom litellm import completion  # pylint: disable=import-error\n\n# pylint: disable=import-error\nfrom daytona import CreateSandboxFromSnapshotParams, Daytona\n\nCODING_MODEL = \"anthropic/claude-sonnet-4-0\"\nSUMMARY_MODEL = \"anthropic/claude-haiku-4-5\"\n\n\n# Helper function to extract Python code from a given string\ndef extract_python(text: str) -> str:\n    match = re.search(r\"```python([\\s\\S]*?)```\", text)\n    return match.group(1).strip() if match else \"\"\n\n\n# Make sure you have the DAYTONA_API_KEY environment variable set\ndef main() -> None:\n    daytona = Daytona()\n    sandbox = None\n\n    try:\n        # Create a Python sandbox\n        sandbox = daytona.create(CreateSandboxFromSnapshotParams(language=\"python\"))\n\n        csv_path = \"cafe_sales_data.csv\"\n        sandbox_csv_path = csv_path\n\n        # Upload the CSV file to the sandbox\n        sandbox.fs.upload_file(str(csv_path), sandbox_csv_path)\n\n        # Generate the system prompt with the first few rows of data for context\n        with Path(csv_path).open(\"r\", encoding=\"utf-8\") as f:\n            csv_sample = \"\".join(f.readlines()[:3]).strip()\n\n        # Define the user prompt\n        user_prompt = \"Give the three highest revenue products for the month of January and show them as a bar chart.\"\n        print(\"Prompt:\", user_prompt)\n\n        system_prompt = (\n            \"\\nYou are a helpful assistant that analyzes data.\\n\"\n            \"To run Python code in a sandbox, output a single block of code.\\n\"\n            f\"The sandbox:\\n - has pandas and numpy installed.\\n - contains {sandbox_csv_path}.\"\n            \"Plot any charts that you create.\"\n            f\"The first few rows of {sandbox_csv_path} are:\\n\"\n            f\"{csv_sample}\\n\"\n            \"After seeing the results of the code, answer the user's query.\"\n        )\n\n        # Generate the Python code with the LLM\n        print(\"Generating code...\")\n        messages = [\n            {\"role\": \"system\", \"content\": system_prompt},\n            {\"role\": \"user\", \"content\": user_prompt},\n        ]\n\n        # LiteLLM supports a variety of model providers\n        # Make sure to have the right environment variables set\n        llm_output = completion(\n            model=CODING_MODEL,\n            messages=messages,\n        )\n\n        first_message = llm_output.choices[0].message\n        print(\"LLM output:\", first_message)\n        messages.append({\"role\": first_message.role, \"content\": first_message.content})\n\n        # Extract and execute Python code from the LLM's response\n        print(\"Running code...\")\n        code = extract_python(first_message.content or \"\")\n        exec_result = sandbox.process.code_run(code)\n\n        messages.append(\n            {\n                \"role\": \"user\",\n                \"content\": f\"Code execution result:\\n{exec_result.result}.\",\n            },\n        )\n\n        artifacts = getattr(exec_result, \"artifacts\", None)\n        charts = getattr(artifacts, \"charts\", None) if artifacts is not None else None\n        if charts:\n            for index, chart in enumerate(charts):\n                png_data = chart.get(\"png\") if isinstance(chart, dict) else getattr(chart, \"png\", None)\n                if png_data:\n                    filename = f\"chart-{index}.png\"\n                    Path(filename).write_bytes(base64.b64decode(png_data))\n                    print(f\"✓ Chart saved to {filename}\")\n\n        # Generate the final response with the LLM\n        summary = completion(\n            model=SUMMARY_MODEL,\n            messages=messages,\n        )\n\n        print(\"Response:\", summary.choices[0].message.content)\n\n    finally:\n        if sandbox is not None:\n            daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "guides/python/ai-data-analyst/litellm/cafe_sales_data.csv",
    "content": "date,item,quantity,unit_price,revenue,time\n2024-01-01,Single-Origin Pour Over,20,5.44,108.78,08:00:00\n2024-01-01,Oat Milk Latte,14,6.08,85.15,08:00:36\n2024-01-01,Honey Lavender Latte,10,6.28,62.83,08:01:12\n2024-01-01,Turmeric Ginger Latte,10,6.29,62.87,08:01:49\n2024-01-01,Cold Brew Concentrate,11,5.92,65.14,08:02:25\n2024-01-01,Nitro Cold Brew,9,6.18,55.63,08:03:02\n2024-01-01,Matcha Espresso Fusion,16,6.52,104.25,08:03:38\n2024-01-01,Blue Pea Flower Tea,20,4.61,92.27,08:04:14\n2024-01-01,Sourdough Toast,9,5.93,53.41,08:04:51\n2024-01-01,Almond Butter Croissant,4,5.45,21.8,08:05:27\n2024-01-01,Vegan Morning Bun,6,5.85,35.12,08:06:04\n2024-01-02,Single-Origin Pour Over,10,5.76,57.57,08:06:40\n2024-01-02,Oat Milk Latte,6,6.0,36.01,08:07:16\n2024-01-02,Honey Lavender Latte,8,6.86,54.87,08:07:53\n2024-01-02,Turmeric Ginger Latte,8,6.42,51.4,08:08:29\n2024-01-02,Cold Brew Concentrate,10,5.86,58.63,08:09:06\n2024-01-02,Nitro Cold Brew,5,6.26,31.32,08:09:42\n2024-01-02,Matcha Espresso Fusion,8,6.8,54.44,08:10:18\n2024-01-02,Blue Pea Flower Tea,7,4.55,31.83,08:10:55\n2024-01-02,Sourdough Toast,6,6.31,37.86,08:11:31\n2024-01-02,Almond Butter Croissant,3,5.18,15.54,08:12:08\n2024-01-02,Vegan Morning Bun,15,5.8,86.93,08:12:44\n2024-01-03,Single-Origin Pour Over,9,5.58,50.26,08:13:20\n2024-01-03,Oat Milk Latte,9,5.81,52.26,08:13:57\n2024-01-03,Honey Lavender Latte,1,6.71,6.71,08:14:33\n2024-01-03,Turmeric Ginger Latte,10,6.49,64.85,08:15:10\n2024-01-03,Cold Brew Concentrate,17,5.74,97.63,08:15:46\n2024-01-03,Nitro Cold Brew,17,6.43,109.38,08:16:22\n2024-01-03,Matcha Espresso Fusion,16,6.71,107.39,08:16:59\n2024-01-03,Blue Pea Flower Tea,2,4.54,9.08,08:17:35\n2024-01-03,Sourdough Toast,17,6.22,105.75,08:18:12\n2024-01-03,Almond Butter Croissant,18,5.31,95.56,08:18:48\n2024-01-03,Vegan Morning Bun,8,5.55,44.38,08:19:24\n2024-01-04,Single-Origin Pour Over,12,5.38,64.55,08:20:01\n2024-01-04,Oat Milk Latte,12,5.87,70.46,08:20:37\n2024-01-04,Honey Lavender Latte,6,6.87,41.21,08:21:14\n2024-01-04,Turmeric Ginger Latte,14,6.46,90.44,08:21:50\n2024-01-04,Cold Brew Concentrate,21,5.67,119.1,08:22:26\n2024-01-04,Nitro Cold Brew,11,6.55,72.02,08:23:03\n2024-01-04,Matcha Espresso Fusion,20,6.98,139.68,08:23:39\n2024-01-04,Blue Pea Flower Tea,15,4.66,69.93,08:24:16\n2024-01-04,Sourdough Toast,13,5.99,77.84,08:24:52\n2024-01-04,Almond Butter Croissant,5,5.12,25.62,08:25:28\n2024-01-04,Vegan Morning Bun,13,5.97,77.63,08:26:05\n2024-01-05,Single-Origin Pour Over,12,5.31,63.7,08:26:41\n2024-01-05,Oat Milk Latte,17,6.07,103.15,08:27:18\n2024-01-05,Honey Lavender Latte,1,6.39,6.39,08:27:54\n2024-01-05,Turmeric Ginger Latte,7,6.12,42.81,08:28:30\n2024-01-05,Cold Brew Concentrate,7,5.77,40.38,08:29:07\n2024-01-05,Nitro Cold Brew,13,6.03,78.41,08:29:43\n2024-01-05,Matcha Espresso Fusion,15,6.92,103.85,08:30:20\n2024-01-05,Blue Pea Flower Tea,7,4.56,31.93,08:30:56\n2024-01-05,Sourdough Toast,16,6.37,101.95,08:31:32\n2024-01-05,Almond Butter Croissant,5,5.28,26.42,08:32:09\n2024-01-05,Vegan Morning Bun,18,5.61,100.99,08:32:45\n2024-01-06,Single-Origin Pour Over,12,5.42,65.03,08:33:22\n2024-01-06,Oat Milk Latte,15,5.97,89.57,08:33:58\n2024-01-06,Honey Lavender Latte,13,6.29,81.8,08:34:34\n2024-01-06,Turmeric Ginger Latte,9,6.48,58.34,08:35:11\n2024-01-06,Cold Brew Concentrate,15,5.6,84.04,08:35:47\n2024-01-06,Nitro Cold Brew,16,6.47,103.56,08:36:24\n2024-01-06,Matcha Espresso Fusion,14,6.73,94.27,08:37:00\n2024-01-06,Blue Pea Flower Tea,8,4.45,35.63,08:37:36\n2024-01-06,Sourdough Toast,14,6.02,84.32,08:38:13\n2024-01-06,Almond Butter Croissant,13,5.63,73.21,08:38:49\n2024-01-06,Vegan Morning Bun,13,5.74,74.61,08:39:26\n2024-01-07,Single-Origin Pour Over,8,5.79,46.3,08:40:02\n2024-01-07,Oat Milk Latte,8,6.38,51.02,08:40:38\n2024-01-07,Honey Lavender Latte,11,6.44,70.8,08:41:15\n2024-01-07,Turmeric Ginger Latte,21,6.54,137.38,08:41:51\n2024-01-07,Cold Brew Concentrate,14,6.05,84.72,08:42:28\n2024-01-07,Nitro Cold Brew,9,6.2,55.84,08:43:04\n2024-01-07,Matcha Espresso Fusion,9,6.85,61.66,08:43:40\n2024-01-07,Blue Pea Flower Tea,3,4.31,12.94,08:44:17\n2024-01-07,Sourdough Toast,12,6.25,75.04,08:44:53\n2024-01-07,Almond Butter Croissant,18,5.15,92.7,08:45:30\n2024-01-07,Vegan Morning Bun,14,5.96,83.37,08:46:06\n2024-01-08,Single-Origin Pour Over,11,5.8,63.76,08:46:42\n2024-01-08,Oat Milk Latte,7,6.09,42.6,08:47:19\n2024-01-08,Honey Lavender Latte,17,6.35,107.98,08:47:55\n2024-01-08,Turmeric Ginger Latte,12,6.54,78.47,08:48:32\n2024-01-08,Cold Brew Concentrate,14,5.55,77.67,08:49:08\n2024-01-08,Nitro Cold Brew,8,6.57,52.6,08:49:44\n2024-01-08,Matcha Espresso Fusion,11,6.79,74.69,08:50:21\n2024-01-08,Blue Pea Flower Tea,8,4.37,34.96,08:50:57\n2024-01-08,Sourdough Toast,12,6.03,72.4,08:51:34\n2024-01-08,Almond Butter Croissant,25,5.4,135.08,08:52:10\n2024-01-08,Vegan Morning Bun,11,5.74,63.17,08:52:46\n2024-01-09,Single-Origin Pour Over,6,5.43,32.57,08:53:23\n2024-01-09,Oat Milk Latte,13,6.27,81.5,08:53:59\n2024-01-09,Honey Lavender Latte,9,6.41,57.67,08:54:36\n2024-01-09,Turmeric Ginger Latte,9,6.31,56.81,08:55:12\n2024-01-09,Cold Brew Concentrate,5,5.94,29.71,08:55:48\n2024-01-09,Nitro Cold Brew,11,6.52,71.69,08:56:25\n2024-01-09,Matcha Espresso Fusion,20,6.75,135.08,08:57:01\n2024-01-09,Blue Pea Flower Tea,15,4.28,64.2,08:57:38\n2024-01-09,Sourdough Toast,1,6.14,6.14,08:58:14\n2024-01-09,Almond Butter Croissant,7,5.09,35.61,08:58:50\n2024-01-09,Vegan Morning Bun,15,5.67,85.08,08:59:27\n2024-01-10,Single-Origin Pour Over,9,5.52,49.65,09:00:03\n2024-01-10,Oat Milk Latte,11,5.84,64.29,09:00:40\n2024-01-10,Honey Lavender Latte,13,6.71,87.18,09:01:16\n2024-01-10,Turmeric Ginger Latte,21,6.03,126.57,09:01:52\n2024-01-10,Cold Brew Concentrate,17,5.77,98.11,09:02:29\n2024-01-10,Nitro Cold Brew,10,6.19,61.92,09:03:05\n2024-01-10,Matcha Espresso Fusion,12,7.14,85.71,09:03:42\n2024-01-10,Blue Pea Flower Tea,11,4.73,52.01,09:04:18\n2024-01-10,Sourdough Toast,14,6.16,86.26,09:04:54\n2024-01-10,Almond Butter Croissant,17,5.11,86.91,09:05:31\n2024-01-10,Vegan Morning Bun,11,6.04,66.42,09:06:07\n2024-01-11,Single-Origin Pour Over,9,5.69,51.18,09:06:44\n2024-01-11,Oat Milk Latte,21,6.05,127.03,09:07:20\n2024-01-11,Honey Lavender Latte,10,6.58,65.8,09:07:56\n2024-01-11,Turmeric Ginger Latte,13,6.57,85.36,09:08:33\n2024-01-11,Cold Brew Concentrate,13,5.72,74.42,09:09:09\n2024-01-11,Nitro Cold Brew,10,6.04,60.37,09:09:46\n2024-01-11,Matcha Espresso Fusion,8,6.98,55.82,09:10:22\n2024-01-11,Blue Pea Flower Tea,20,4.56,91.2,09:10:58\n2024-01-11,Sourdough Toast,1,5.94,5.94,09:11:35\n2024-01-11,Almond Butter Croissant,12,5.59,67.03,09:12:11\n2024-01-11,Vegan Morning Bun,17,6.08,103.4,09:12:48\n2024-01-12,Single-Origin Pour Over,15,5.41,81.19,09:13:24\n2024-01-12,Oat Milk Latte,26,5.82,151.44,09:14:00\n2024-01-12,Honey Lavender Latte,13,6.75,87.69,09:14:37\n2024-01-12,Turmeric Ginger Latte,12,6.08,72.99,09:15:13\n2024-01-12,Cold Brew Concentrate,5,5.55,27.74,09:15:50\n2024-01-12,Nitro Cold Brew,11,6.44,70.82,09:16:26\n2024-01-12,Matcha Espresso Fusion,24,7.01,168.34,09:17:02\n2024-01-12,Blue Pea Flower Tea,17,4.67,79.44,09:17:39\n2024-01-12,Sourdough Toast,21,6.1,128.16,09:18:15\n2024-01-12,Almond Butter Croissant,17,5.29,89.99,09:18:52\n2024-01-12,Vegan Morning Bun,12,5.85,70.17,09:19:28\n2024-01-13,Single-Origin Pour Over,9,5.53,49.78,09:20:04\n2024-01-13,Oat Milk Latte,13,5.82,75.61,09:20:41\n2024-01-13,Honey Lavender Latte,8,6.59,52.68,09:21:17\n2024-01-13,Turmeric Ginger Latte,8,6.37,50.97,09:21:54\n2024-01-13,Cold Brew Concentrate,11,6.08,66.87,09:22:30\n2024-01-13,Nitro Cold Brew,18,6.26,112.62,09:23:06\n2024-01-13,Matcha Espresso Fusion,13,6.91,89.77,09:23:43\n2024-01-13,Blue Pea Flower Tea,20,4.43,88.52,09:24:19\n2024-01-13,Sourdough Toast,12,6.4,76.77,09:24:56\n2024-01-13,Almond Butter Croissant,6,5.03,30.19,09:25:32\n2024-01-13,Vegan Morning Bun,17,5.53,93.93,09:26:08\n2024-01-14,Single-Origin Pour Over,7,5.74,40.15,09:26:45\n2024-01-14,Oat Milk Latte,20,6.11,122.16,09:27:21\n2024-01-14,Honey Lavender Latte,14,6.86,96.05,09:27:58\n2024-01-14,Turmeric Ginger Latte,16,6.03,96.53,09:28:34\n2024-01-14,Cold Brew Concentrate,2,5.86,11.72,09:29:10\n2024-01-14,Nitro Cold Brew,13,6.61,85.99,09:29:47\n2024-01-14,Matcha Espresso Fusion,11,6.59,72.49,09:30:23\n2024-01-14,Blue Pea Flower Tea,15,4.6,69.05,09:31:00\n2024-01-14,Sourdough Toast,7,6.1,42.68,09:31:36\n2024-01-14,Almond Butter Croissant,10,5.26,52.55,09:32:12\n2024-01-14,Vegan Morning Bun,11,6.15,67.64,09:32:49\n2024-01-15,Single-Origin Pour Over,13,5.38,69.91,09:33:25\n2024-01-15,Oat Milk Latte,18,6.35,114.27,09:34:02\n2024-01-15,Honey Lavender Latte,21,6.38,134.02,09:34:38\n2024-01-15,Turmeric Ginger Latte,5,6.21,31.07,09:35:14\n2024-01-15,Cold Brew Concentrate,6,5.51,33.09,09:35:51\n2024-01-15,Nitro Cold Brew,3,6.43,19.29,09:36:27\n2024-01-15,Matcha Espresso Fusion,13,6.9,89.74,09:37:04\n2024-01-15,Blue Pea Flower Tea,6,4.7,28.22,09:37:40\n2024-01-15,Sourdough Toast,6,6.24,37.45,09:38:16\n2024-01-15,Almond Butter Croissant,6,5.25,31.51,09:38:53\n2024-01-15,Vegan Morning Bun,7,6.14,42.95,09:39:29\n2024-01-16,Single-Origin Pour Over,4,5.53,22.14,09:40:06\n2024-01-16,Oat Milk Latte,8,6.34,50.75,09:40:42\n2024-01-16,Honey Lavender Latte,20,6.72,134.35,09:41:18\n2024-01-16,Turmeric Ginger Latte,7,6.24,43.65,09:41:55\n2024-01-16,Cold Brew Concentrate,11,5.82,64.01,09:42:31\n2024-01-16,Nitro Cold Brew,13,6.14,79.77,09:43:08\n2024-01-16,Matcha Espresso Fusion,3,6.82,20.46,09:43:44\n2024-01-16,Blue Pea Flower Tea,22,4.73,104.16,09:44:20\n2024-01-16,Sourdough Toast,13,6.22,80.92,09:44:57\n2024-01-16,Almond Butter Croissant,5,5.57,27.84,09:45:33\n2024-01-16,Vegan Morning Bun,1,5.74,5.74,09:46:10\n2024-01-17,Single-Origin Pour Over,12,5.45,65.38,09:46:46\n2024-01-17,Oat Milk Latte,15,6.15,92.32,09:47:22\n2024-01-17,Honey Lavender Latte,13,6.47,84.14,09:47:59\n2024-01-17,Turmeric Ginger Latte,21,6.3,132.22,09:48:35\n2024-01-17,Cold Brew Concentrate,10,5.59,55.94,09:49:12\n2024-01-17,Nitro Cold Brew,9,6.43,57.9,09:49:48\n2024-01-17,Matcha Espresso Fusion,12,6.54,78.48,09:50:24\n2024-01-17,Blue Pea Flower Tea,1,4.37,4.37,09:51:01\n2024-01-17,Sourdough Toast,16,6.3,100.88,09:51:37\n2024-01-17,Almond Butter Croissant,19,5.63,106.89,09:52:14\n2024-01-17,Vegan Morning Bun,18,5.79,104.24,09:52:50\n2024-01-18,Single-Origin Pour Over,4,5.58,22.31,09:53:26\n2024-01-18,Oat Milk Latte,13,6.16,80.02,09:54:03\n2024-01-18,Honey Lavender Latte,11,6.34,69.76,09:54:39\n2024-01-18,Turmeric Ginger Latte,12,6.01,72.11,09:55:16\n2024-01-18,Cold Brew Concentrate,16,6.02,96.38,09:55:52\n2024-01-18,Nitro Cold Brew,12,6.28,75.35,09:56:28\n2024-01-18,Matcha Espresso Fusion,13,6.75,87.72,09:57:05\n2024-01-18,Blue Pea Flower Tea,9,4.76,42.84,09:57:41\n2024-01-18,Sourdough Toast,13,6.07,78.96,09:58:18\n2024-01-18,Almond Butter Croissant,7,5.11,35.79,09:58:54\n2024-01-18,Vegan Morning Bun,10,6.06,60.59,09:59:30\n2024-01-19,Single-Origin Pour Over,14,5.77,80.82,10:00:07\n2024-01-19,Oat Milk Latte,9,5.81,52.26,10:00:43\n2024-01-19,Honey Lavender Latte,19,6.57,124.8,10:01:20\n2024-01-19,Turmeric Ginger Latte,10,6.56,65.63,10:01:56\n2024-01-19,Cold Brew Concentrate,19,5.64,107.14,10:02:32\n2024-01-19,Nitro Cold Brew,5,6.55,32.74,10:03:09\n2024-01-19,Matcha Espresso Fusion,13,6.71,87.23,10:03:45\n2024-01-19,Blue Pea Flower Tea,17,4.48,76.09,10:04:22\n2024-01-19,Sourdough Toast,7,6.08,42.57,10:04:58\n2024-01-19,Almond Butter Croissant,13,5.19,67.5,10:05:34\n2024-01-19,Vegan Morning Bun,5,6.04,30.21,10:06:11\n2024-01-20,Single-Origin Pour Over,6,5.36,32.18,10:06:47\n2024-01-20,Oat Milk Latte,8,5.76,46.08,10:07:24\n2024-01-20,Honey Lavender Latte,9,6.53,58.74,10:08:00\n2024-01-20,Turmeric Ginger Latte,1,6.56,6.56,10:08:36\n2024-01-20,Cold Brew Concentrate,9,5.84,52.59,10:09:13\n2024-01-20,Nitro Cold Brew,22,6.05,133.14,10:09:49\n2024-01-20,Matcha Espresso Fusion,15,7.05,105.68,10:10:26\n2024-01-20,Blue Pea Flower Tea,12,4.85,58.22,10:11:02\n2024-01-20,Sourdough Toast,7,6.11,42.75,10:11:38\n2024-01-20,Almond Butter Croissant,18,5.59,100.54,10:12:15\n2024-01-20,Vegan Morning Bun,7,5.9,41.3,10:12:51\n2024-01-21,Single-Origin Pour Over,21,5.36,112.65,10:13:28\n2024-01-21,Oat Milk Latte,13,5.91,76.82,10:14:04\n2024-01-21,Honey Lavender Latte,10,6.74,67.38,10:14:40\n2024-01-21,Turmeric Ginger Latte,8,6.45,51.61,10:15:17\n2024-01-21,Cold Brew Concentrate,15,6.02,90.24,10:15:53\n2024-01-21,Nitro Cold Brew,17,6.1,103.65,10:16:30\n2024-01-21,Matcha Espresso Fusion,10,6.82,68.2,10:17:06\n2024-01-21,Blue Pea Flower Tea,12,4.8,57.58,10:17:42\n2024-01-21,Sourdough Toast,2,5.93,11.86,10:18:19\n2024-01-21,Almond Butter Croissant,10,5.26,52.56,10:18:55\n2024-01-21,Vegan Morning Bun,8,5.78,46.26,10:19:32\n2024-01-22,Single-Origin Pour Over,16,5.72,91.52,10:20:08\n2024-01-22,Oat Milk Latte,17,6.07,103.14,10:20:44\n2024-01-22,Honey Lavender Latte,17,6.34,107.83,10:21:21\n2024-01-22,Turmeric Ginger Latte,11,6.53,71.8,10:21:57\n2024-01-22,Cold Brew Concentrate,12,5.5,66.06,10:22:34\n2024-01-22,Nitro Cold Brew,4,6.45,25.81,10:23:10\n2024-01-22,Matcha Espresso Fusion,10,6.93,69.31,10:23:46\n2024-01-22,Blue Pea Flower Tea,21,4.89,102.6,10:24:23\n2024-01-22,Sourdough Toast,10,5.81,58.11,10:24:59\n2024-01-22,Almond Butter Croissant,21,5.41,113.64,10:25:36\n2024-01-22,Vegan Morning Bun,15,5.67,85.06,10:26:12\n2024-01-23,Single-Origin Pour Over,10,5.8,57.99,10:26:48\n2024-01-23,Oat Milk Latte,14,6.06,84.78,10:27:25\n2024-01-23,Honey Lavender Latte,13,6.3,81.91,10:28:01\n2024-01-23,Turmeric Ginger Latte,10,6.52,65.17,10:28:38\n2024-01-23,Cold Brew Concentrate,16,6.02,96.35,10:29:14\n2024-01-23,Nitro Cold Brew,13,6.26,81.4,10:29:50\n2024-01-23,Matcha Espresso Fusion,9,6.5,58.51,10:30:27\n2024-01-23,Blue Pea Flower Tea,8,4.67,37.4,10:31:03\n2024-01-23,Sourdough Toast,9,6.2,55.77,10:31:40\n2024-01-23,Almond Butter Croissant,4,5.29,21.16,10:32:16\n2024-01-23,Vegan Morning Bun,7,5.72,40.04,10:32:52\n2024-01-24,Single-Origin Pour Over,12,5.38,64.61,10:33:29\n2024-01-24,Oat Milk Latte,19,6.08,115.48,10:34:05\n2024-01-24,Honey Lavender Latte,16,6.28,100.46,10:34:42\n2024-01-24,Turmeric Ginger Latte,7,6.17,43.22,10:35:18\n2024-01-24,Cold Brew Concentrate,8,5.67,45.37,10:35:54\n2024-01-24,Nitro Cold Brew,13,6.23,80.93,10:36:31\n2024-01-24,Matcha Espresso Fusion,14,7.11,99.57,10:37:07\n2024-01-24,Blue Pea Flower Tea,5,4.72,23.62,10:37:44\n2024-01-24,Sourdough Toast,11,5.92,65.1,10:38:20\n2024-01-24,Almond Butter Croissant,14,5.19,72.64,10:38:56\n2024-01-24,Vegan Morning Bun,15,5.8,86.98,10:39:33\n2024-01-25,Single-Origin Pour Over,16,5.59,89.48,10:40:09\n2024-01-25,Oat Milk Latte,18,5.89,106.01,10:40:46\n2024-01-25,Honey Lavender Latte,17,6.55,111.3,10:41:22\n2024-01-25,Turmeric Ginger Latte,6,6.47,38.8,10:41:58\n2024-01-25,Cold Brew Concentrate,6,5.56,33.39,10:42:35\n2024-01-25,Nitro Cold Brew,18,6.44,115.97,10:43:11\n2024-01-25,Matcha Espresso Fusion,16,6.58,105.3,10:43:48\n2024-01-25,Blue Pea Flower Tea,2,4.34,8.69,10:44:24\n2024-01-25,Sourdough Toast,21,5.83,122.35,10:45:00\n2024-01-25,Almond Butter Croissant,7,5.5,38.52,10:45:37\n2024-01-25,Vegan Morning Bun,14,5.99,83.82,10:46:13\n2024-01-26,Single-Origin Pour Over,16,5.41,86.48,10:46:50\n2024-01-26,Oat Milk Latte,10,5.83,58.32,10:47:26\n2024-01-26,Honey Lavender Latte,8,6.52,52.17,10:48:02\n2024-01-26,Turmeric Ginger Latte,8,6.56,52.45,10:48:39\n2024-01-26,Cold Brew Concentrate,16,5.79,92.71,10:49:15\n2024-01-26,Nitro Cold Brew,14,6.29,87.99,10:49:52\n2024-01-26,Matcha Espresso Fusion,6,6.71,40.29,10:50:28\n2024-01-26,Blue Pea Flower Tea,13,4.74,61.6,10:51:04\n2024-01-26,Sourdough Toast,12,5.94,71.29,10:51:41\n2024-01-26,Almond Butter Croissant,3,5.64,16.92,10:52:17\n2024-01-26,Vegan Morning Bun,5,5.5,27.51,10:52:54\n2024-01-27,Single-Origin Pour Over,12,5.35,64.22,10:53:30\n2024-01-27,Oat Milk Latte,22,6.17,135.68,10:54:06\n2024-01-27,Honey Lavender Latte,14,6.3,88.21,10:54:43\n2024-01-27,Turmeric Ginger Latte,15,6.52,97.75,10:55:19\n2024-01-27,Cold Brew Concentrate,16,5.87,93.85,10:55:56\n2024-01-27,Nitro Cold Brew,9,6.05,54.47,10:56:32\n2024-01-27,Matcha Espresso Fusion,14,6.79,95.11,10:57:08\n2024-01-27,Blue Pea Flower Tea,19,4.66,88.63,10:57:45\n2024-01-27,Sourdough Toast,9,6.34,57.09,10:58:21\n2024-01-27,Almond Butter Croissant,11,5.19,57.06,10:58:58\n2024-01-27,Vegan Morning Bun,14,5.8,81.21,10:59:34\n2024-01-28,Single-Origin Pour Over,13,5.78,75.13,11:00:10\n2024-01-28,Oat Milk Latte,6,5.94,35.64,11:00:47\n2024-01-28,Honey Lavender Latte,4,6.44,25.77,11:01:23\n2024-01-28,Turmeric Ginger Latte,2,6.04,12.09,11:02:00\n2024-01-28,Cold Brew Concentrate,15,5.95,89.23,11:02:36\n2024-01-28,Nitro Cold Brew,7,6.12,42.85,11:03:12\n2024-01-28,Matcha Espresso Fusion,4,6.53,26.13,11:03:49\n2024-01-28,Blue Pea Flower Tea,7,4.86,33.99,11:04:25\n2024-01-28,Sourdough Toast,21,5.76,121.01,11:05:02\n2024-01-28,Almond Butter Croissant,1,5.21,5.21,11:05:38\n2024-01-28,Vegan Morning Bun,12,6.13,73.6,11:06:14\n2024-01-29,Single-Origin Pour Over,15,5.83,87.42,11:06:51\n2024-01-29,Oat Milk Latte,12,5.97,71.65,11:07:27\n2024-01-29,Honey Lavender Latte,6,6.49,38.93,11:08:04\n2024-01-29,Turmeric Ginger Latte,14,6.45,90.23,11:08:40\n2024-01-29,Cold Brew Concentrate,7,5.55,38.86,11:09:16\n2024-01-29,Nitro Cold Brew,12,6.5,78.01,11:09:53\n2024-01-29,Matcha Espresso Fusion,16,6.64,106.3,11:10:29\n2024-01-29,Blue Pea Flower Tea,18,4.76,85.67,11:11:06\n2024-01-29,Sourdough Toast,6,5.86,35.15,11:11:42\n2024-01-29,Almond Butter Croissant,13,5.4,70.25,11:12:18\n2024-01-29,Vegan Morning Bun,12,5.69,68.3,11:12:55\n2024-01-30,Single-Origin Pour Over,13,5.72,74.3,11:13:31\n2024-01-30,Oat Milk Latte,14,6.02,84.27,11:14:08\n2024-01-30,Honey Lavender Latte,6,6.27,37.62,11:14:44\n2024-01-30,Turmeric Ginger Latte,19,6.59,125.26,11:15:20\n2024-01-30,Cold Brew Concentrate,28,5.96,166.94,11:15:57\n2024-01-30,Nitro Cold Brew,17,6.16,104.76,11:16:33\n2024-01-30,Matcha Espresso Fusion,5,6.93,34.63,11:17:10\n2024-01-30,Blue Pea Flower Tea,20,4.35,87.09,11:17:46\n2024-01-30,Sourdough Toast,19,6.21,118.03,11:18:22\n2024-01-30,Almond Butter Croissant,20,5.03,100.58,11:18:59\n2024-01-30,Vegan Morning Bun,13,5.98,77.69,11:19:35\n2024-01-31,Single-Origin Pour Over,12,5.34,64.09,11:20:12\n2024-01-31,Oat Milk Latte,14,6.35,88.91,11:20:48\n2024-01-31,Honey Lavender Latte,3,6.65,19.96,11:21:24\n2024-01-31,Turmeric Ginger Latte,14,6.56,91.82,11:22:01\n2024-01-31,Cold Brew Concentrate,12,5.91,70.94,11:22:37\n2024-01-31,Nitro Cold Brew,7,6.6,46.21,11:23:14\n2024-01-31,Matcha Espresso Fusion,12,6.98,83.71,11:23:50\n2024-01-31,Blue Pea Flower Tea,9,4.68,42.11,11:24:26\n2024-01-31,Sourdough Toast,13,6.16,80.09,11:25:03\n2024-01-31,Almond Butter Croissant,16,5.4,86.34,11:25:39\n2024-01-31,Vegan Morning Bun,13,5.84,75.86,11:26:16\n2024-02-01,Single-Origin Pour Over,10,5.26,52.64,11:26:52\n2024-02-01,Oat Milk Latte,14,6.18,86.48,11:27:28\n2024-02-01,Honey Lavender Latte,16,6.28,100.54,11:28:05\n2024-02-01,Turmeric Ginger Latte,7,6.53,45.71,11:28:41\n2024-02-01,Cold Brew Concentrate,18,5.6,100.83,11:29:18\n2024-02-01,Nitro Cold Brew,8,6.01,48.1,11:29:54\n2024-02-01,Matcha Espresso Fusion,10,6.71,67.1,11:30:30\n2024-02-01,Blue Pea Flower Tea,8,4.44,35.55,11:31:07\n2024-02-01,Sourdough Toast,20,6.36,127.17,11:31:43\n2024-02-01,Almond Butter Croissant,7,5.63,39.41,11:32:20\n2024-02-01,Vegan Morning Bun,8,5.55,44.41,11:32:56\n2024-02-02,Single-Origin Pour Over,14,5.49,76.86,11:33:32\n2024-02-02,Oat Milk Latte,20,5.94,118.84,11:34:09\n2024-02-02,Honey Lavender Latte,11,6.58,72.35,11:34:45\n2024-02-02,Turmeric Ginger Latte,8,6.16,49.29,11:35:22\n2024-02-02,Cold Brew Concentrate,15,6.07,91.11,11:35:58\n2024-02-02,Nitro Cold Brew,4,6.38,25.52,11:36:34\n2024-02-02,Matcha Espresso Fusion,16,6.84,109.5,11:37:11\n2024-02-02,Blue Pea Flower Tea,9,4.65,41.87,11:37:47\n2024-02-02,Sourdough Toast,7,6.2,43.37,11:38:24\n2024-02-02,Almond Butter Croissant,16,5.17,82.77,11:39:00\n2024-02-02,Vegan Morning Bun,5,6.02,30.09,11:39:36\n2024-02-03,Single-Origin Pour Over,15,5.48,82.14,11:40:13\n2024-02-03,Oat Milk Latte,15,6.32,94.74,11:40:49\n2024-02-03,Honey Lavender Latte,14,6.59,92.23,11:41:26\n2024-02-03,Turmeric Ginger Latte,2,6.56,13.11,11:42:02\n2024-02-03,Cold Brew Concentrate,14,6.0,83.94,11:42:38\n2024-02-03,Nitro Cold Brew,16,6.6,105.56,11:43:15\n2024-02-03,Matcha Espresso Fusion,30,6.86,205.94,11:43:51\n2024-02-03,Blue Pea Flower Tea,12,4.61,55.34,11:44:28\n2024-02-03,Sourdough Toast,19,6.03,114.6,11:45:04\n2024-02-03,Almond Butter Croissant,8,5.29,42.29,11:45:40\n2024-02-03,Vegan Morning Bun,1,5.59,5.59,11:46:17\n2024-02-04,Single-Origin Pour Over,12,5.56,66.76,11:46:53\n2024-02-04,Oat Milk Latte,11,6.35,69.85,11:47:30\n2024-02-04,Honey Lavender Latte,11,6.79,74.68,11:48:06\n2024-02-04,Turmeric Ginger Latte,1,6.43,6.43,11:48:42\n2024-02-04,Cold Brew Concentrate,9,5.91,53.15,11:49:19\n2024-02-04,Nitro Cold Brew,2,6.26,12.52,11:49:55\n2024-02-04,Matcha Espresso Fusion,8,6.98,55.85,11:50:32\n2024-02-04,Blue Pea Flower Tea,8,4.39,35.09,11:51:08\n2024-02-04,Sourdough Toast,9,6.39,57.54,11:51:44\n2024-02-04,Almond Butter Croissant,7,5.64,39.51,11:52:21\n2024-02-04,Vegan Morning Bun,4,5.79,23.15,11:52:57\n2024-02-05,Single-Origin Pour Over,11,5.82,64.06,11:53:34\n2024-02-05,Oat Milk Latte,16,6.32,101.16,11:54:10\n2024-02-05,Honey Lavender Latte,12,6.78,81.35,11:54:46\n2024-02-05,Turmeric Ginger Latte,12,6.11,73.32,11:55:23\n2024-02-05,Cold Brew Concentrate,17,6.01,102.11,11:55:59\n2024-02-05,Nitro Cold Brew,12,6.6,79.2,11:56:36\n2024-02-05,Matcha Espresso Fusion,11,7.1,78.11,11:57:12\n2024-02-05,Blue Pea Flower Tea,14,4.4,61.62,11:57:48\n2024-02-05,Sourdough Toast,12,6.12,73.48,11:58:25\n2024-02-05,Almond Butter Croissant,13,5.41,70.3,11:59:01\n2024-02-05,Vegan Morning Bun,18,5.76,103.59,11:59:38\n2024-02-06,Single-Origin Pour Over,13,5.63,73.19,12:00:14\n2024-02-06,Oat Milk Latte,10,5.98,59.83,12:00:50\n2024-02-06,Honey Lavender Latte,7,6.37,44.59,12:01:27\n2024-02-06,Turmeric Ginger Latte,9,6.43,57.91,12:02:03\n2024-02-06,Cold Brew Concentrate,7,6.05,42.35,12:02:40\n2024-02-06,Nitro Cold Brew,6,6.06,36.36,12:03:16\n2024-02-06,Matcha Espresso Fusion,11,7.04,77.42,12:03:52\n2024-02-06,Blue Pea Flower Tea,14,4.79,67.0,12:04:29\n2024-02-06,Sourdough Toast,10,6.18,61.76,12:05:05\n2024-02-06,Almond Butter Croissant,12,5.29,63.48,12:05:42\n2024-02-06,Vegan Morning Bun,12,5.93,71.18,12:06:18\n2024-02-07,Single-Origin Pour Over,2,5.5,11.01,12:06:54\n2024-02-07,Oat Milk Latte,5,5.86,29.29,12:07:31\n2024-02-07,Honey Lavender Latte,9,6.65,59.89,12:08:07\n2024-02-07,Turmeric Ginger Latte,17,6.49,110.26,12:08:44\n2024-02-07,Cold Brew Concentrate,20,5.71,114.15,12:09:20\n2024-02-07,Nitro Cold Brew,7,6.54,45.81,12:09:56\n2024-02-07,Matcha Espresso Fusion,7,7.05,49.36,12:10:33\n2024-02-07,Blue Pea Flower Tea,9,4.5,40.46,12:11:09\n2024-02-07,Sourdough Toast,16,5.94,95.02,12:11:46\n2024-02-07,Almond Butter Croissant,6,5.48,32.9,12:12:22\n2024-02-07,Vegan Morning Bun,15,6.02,90.23,12:12:58\n2024-02-08,Single-Origin Pour Over,5,5.42,27.1,12:13:35\n2024-02-08,Oat Milk Latte,12,6.12,73.42,12:14:11\n2024-02-08,Honey Lavender Latte,7,6.67,46.7,12:14:48\n2024-02-08,Turmeric Ginger Latte,15,6.59,98.86,12:15:24\n2024-02-08,Cold Brew Concentrate,14,6.12,85.72,12:16:00\n2024-02-08,Nitro Cold Brew,13,6.18,80.32,12:16:37\n2024-02-08,Matcha Espresso Fusion,12,6.75,81.04,12:17:13\n2024-02-08,Blue Pea Flower Tea,11,4.32,47.52,12:17:50\n2024-02-08,Sourdough Toast,9,5.87,52.87,12:18:26\n2024-02-08,Almond Butter Croissant,23,5.6,128.7,12:19:02\n2024-02-08,Vegan Morning Bun,13,5.68,73.88,12:19:39\n2024-02-09,Single-Origin Pour Over,11,5.29,58.18,12:20:15\n2024-02-09,Oat Milk Latte,10,6.35,63.5,12:20:52\n2024-02-09,Honey Lavender Latte,14,6.56,91.91,12:21:28\n2024-02-09,Turmeric Ginger Latte,8,6.17,49.38,12:22:04\n2024-02-09,Cold Brew Concentrate,13,5.94,77.24,12:22:41\n2024-02-09,Nitro Cold Brew,12,6.63,79.58,12:23:17\n2024-02-09,Matcha Espresso Fusion,13,6.65,86.51,12:23:54\n2024-02-09,Blue Pea Flower Tea,10,4.63,46.27,12:24:30\n2024-02-09,Sourdough Toast,9,5.99,53.92,12:25:06\n2024-02-09,Almond Butter Croissant,7,5.21,36.44,12:25:43\n2024-02-09,Vegan Morning Bun,5,5.87,29.34,12:26:19\n2024-02-10,Single-Origin Pour Over,16,5.5,87.95,12:26:56\n2024-02-10,Oat Milk Latte,14,6.36,89.04,12:27:32\n2024-02-10,Honey Lavender Latte,5,6.52,32.6,12:28:08\n2024-02-10,Turmeric Ginger Latte,2,6.5,12.99,12:28:45\n2024-02-10,Cold Brew Concentrate,9,5.72,51.5,12:29:21\n2024-02-10,Nitro Cold Brew,19,6.05,115.02,12:29:58\n2024-02-10,Matcha Espresso Fusion,10,6.72,67.16,12:30:34\n2024-02-10,Blue Pea Flower Tea,11,4.37,48.1,12:31:10\n2024-02-10,Sourdough Toast,18,6.07,109.22,12:31:47\n2024-02-10,Almond Butter Croissant,15,5.31,79.7,12:32:23\n2024-02-10,Vegan Morning Bun,13,6.15,79.89,12:33:00\n2024-02-11,Single-Origin Pour Over,11,5.67,62.34,12:33:36\n2024-02-11,Oat Milk Latte,10,6.13,61.32,12:34:12\n2024-02-11,Honey Lavender Latte,17,6.49,110.33,12:34:49\n2024-02-11,Turmeric Ginger Latte,12,6.58,78.97,12:35:25\n2024-02-11,Cold Brew Concentrate,14,5.9,82.62,12:36:02\n2024-02-11,Nitro Cold Brew,10,6.39,63.86,12:36:38\n2024-02-11,Matcha Espresso Fusion,9,7.1,63.86,12:37:14\n2024-02-11,Blue Pea Flower Tea,5,4.68,23.39,12:37:51\n2024-02-11,Sourdough Toast,18,6.16,110.9,12:38:27\n2024-02-11,Almond Butter Croissant,12,5.01,60.06,12:39:04\n2024-02-11,Vegan Morning Bun,13,6.14,79.84,12:39:40\n2024-02-12,Single-Origin Pour Over,10,5.88,58.77,12:40:16\n2024-02-12,Oat Milk Latte,7,6.19,43.31,12:40:53\n2024-02-12,Honey Lavender Latte,8,6.51,52.08,12:41:29\n2024-02-12,Turmeric Ginger Latte,21,6.2,130.14,12:42:06\n2024-02-12,Cold Brew Concentrate,8,5.58,44.65,12:42:42\n2024-02-12,Nitro Cold Brew,18,6.13,110.38,12:43:18\n2024-02-12,Matcha Espresso Fusion,7,6.93,48.48,12:43:55\n2024-02-12,Blue Pea Flower Tea,8,4.45,35.56,12:44:31\n2024-02-12,Sourdough Toast,15,6.13,92.0,12:45:08\n2024-02-12,Almond Butter Croissant,16,5.31,84.95,12:45:44\n2024-02-12,Vegan Morning Bun,7,5.96,41.72,12:46:20\n2024-02-13,Single-Origin Pour Over,1,5.29,5.29,12:46:57\n2024-02-13,Oat Milk Latte,15,6.21,93.16,12:47:33\n2024-02-13,Honey Lavender Latte,6,6.62,39.73,12:48:10\n2024-02-13,Turmeric Ginger Latte,7,6.35,44.43,12:48:46\n2024-02-13,Cold Brew Concentrate,8,5.67,45.37,12:49:22\n2024-02-13,Nitro Cold Brew,16,6.47,103.48,12:49:59\n2024-02-13,Matcha Espresso Fusion,15,6.91,103.63,12:50:35\n2024-02-13,Blue Pea Flower Tea,12,4.43,53.2,12:51:12\n2024-02-13,Sourdough Toast,16,5.9,94.47,12:51:48\n2024-02-13,Almond Butter Croissant,13,5.5,71.47,12:52:24\n2024-02-13,Vegan Morning Bun,7,5.9,41.28,12:53:01\n2024-02-14,Single-Origin Pour Over,14,5.73,80.23,12:53:37\n2024-02-14,Oat Milk Latte,8,5.99,47.92,12:54:14\n2024-02-14,Honey Lavender Latte,8,6.64,53.11,12:54:50\n2024-02-14,Turmeric Ginger Latte,12,6.01,72.15,12:55:26\n2024-02-14,Cold Brew Concentrate,17,5.91,100.45,12:56:03\n2024-02-14,Nitro Cold Brew,9,6.24,56.19,12:56:39\n2024-02-14,Matcha Espresso Fusion,13,7.1,92.36,12:57:16\n2024-02-14,Blue Pea Flower Tea,15,4.57,68.52,12:57:52\n2024-02-14,Sourdough Toast,18,5.78,104.11,12:58:28\n2024-02-14,Almond Butter Croissant,18,5.09,91.63,12:59:05\n2024-02-14,Vegan Morning Bun,10,6.14,61.42,12:59:41\n2024-02-15,Single-Origin Pour Over,10,5.69,56.87,13:00:18\n2024-02-15,Oat Milk Latte,13,5.87,76.29,13:00:54\n2024-02-15,Honey Lavender Latte,13,6.74,87.62,13:01:31\n2024-02-15,Turmeric Ginger Latte,1,6.48,6.48,13:02:07\n2024-02-15,Cold Brew Concentrate,14,6.02,84.27,13:02:43\n2024-02-15,Nitro Cold Brew,20,6.55,131.07,13:03:20\n2024-02-15,Matcha Espresso Fusion,16,6.73,107.76,13:03:56\n2024-02-15,Blue Pea Flower Tea,11,4.84,53.29,13:04:33\n2024-02-15,Sourdough Toast,18,6.22,111.9,13:05:09\n2024-02-15,Almond Butter Croissant,13,5.33,69.32,13:05:45\n2024-02-15,Vegan Morning Bun,12,5.64,67.68,13:06:22\n2024-02-16,Single-Origin Pour Over,1,5.88,5.88,13:06:58\n2024-02-16,Oat Milk Latte,14,5.87,82.12,13:07:35\n2024-02-16,Honey Lavender Latte,16,6.33,101.29,13:08:11\n2024-02-16,Turmeric Ginger Latte,22,6.45,141.96,13:08:47\n2024-02-16,Cold Brew Concentrate,4,6.12,24.48,13:09:24\n2024-02-16,Nitro Cold Brew,21,6.07,127.49,13:10:00\n2024-02-16,Matcha Espresso Fusion,4,6.82,27.29,13:10:37\n2024-02-16,Blue Pea Flower Tea,16,4.49,71.83,13:11:13\n2024-02-16,Sourdough Toast,15,5.8,87.02,13:11:49\n2024-02-16,Almond Butter Croissant,13,5.31,69.05,13:12:26\n2024-02-16,Vegan Morning Bun,7,5.72,40.03,13:13:02\n2024-02-17,Single-Origin Pour Over,17,5.86,99.69,13:13:39\n2024-02-17,Oat Milk Latte,13,6.21,80.67,13:14:15\n2024-02-17,Honey Lavender Latte,7,6.68,46.77,13:14:51\n2024-02-17,Turmeric Ginger Latte,8,6.21,49.67,13:15:28\n2024-02-17,Cold Brew Concentrate,12,6.01,72.18,13:16:04\n2024-02-17,Nitro Cold Brew,22,6.6,145.12,13:16:41\n2024-02-17,Matcha Espresso Fusion,19,6.57,124.79,13:17:17\n2024-02-17,Blue Pea Flower Tea,10,4.51,45.09,13:17:53\n2024-02-17,Sourdough Toast,16,6.16,98.62,13:18:30\n2024-02-17,Almond Butter Croissant,15,5.6,83.94,13:19:06\n2024-02-17,Vegan Morning Bun,11,5.74,63.17,13:19:43\n2024-02-18,Single-Origin Pour Over,9,5.9,53.06,13:20:19\n2024-02-18,Oat Milk Latte,5,5.95,29.74,13:20:55\n2024-02-18,Honey Lavender Latte,4,6.56,26.26,13:21:32\n2024-02-18,Turmeric Ginger Latte,11,6.62,72.81,13:22:08\n2024-02-18,Cold Brew Concentrate,11,5.9,64.91,13:22:45\n2024-02-18,Nitro Cold Brew,11,6.51,71.61,13:23:21\n2024-02-18,Matcha Espresso Fusion,8,6.73,53.88,13:23:57\n2024-02-18,Blue Pea Flower Tea,10,4.76,47.62,13:24:34\n2024-02-18,Sourdough Toast,10,6.2,62.04,13:25:10\n2024-02-18,Almond Butter Croissant,11,5.17,56.9,13:25:47\n2024-02-18,Vegan Morning Bun,1,5.63,5.63,13:26:23\n2024-02-19,Single-Origin Pour Over,19,5.51,104.63,13:26:59\n2024-02-19,Oat Milk Latte,13,5.85,76.02,13:27:36\n2024-02-19,Honey Lavender Latte,3,6.9,20.7,13:28:12\n2024-02-19,Turmeric Ginger Latte,14,6.16,86.28,13:28:49\n2024-02-19,Cold Brew Concentrate,15,6.12,91.79,13:29:25\n2024-02-19,Nitro Cold Brew,9,6.19,55.72,13:30:01\n2024-02-19,Matcha Espresso Fusion,10,7.01,70.14,13:30:38\n2024-02-19,Blue Pea Flower Tea,12,4.52,54.29,13:31:14\n2024-02-19,Sourdough Toast,13,6.23,81.03,13:31:51\n2024-02-19,Almond Butter Croissant,12,5.32,63.82,13:32:27\n2024-02-19,Vegan Morning Bun,17,5.76,97.97,13:33:03\n2024-02-20,Single-Origin Pour Over,2,5.33,10.65,13:33:40\n2024-02-20,Oat Milk Latte,2,6.36,12.71,13:34:16\n2024-02-20,Honey Lavender Latte,21,6.55,137.45,13:34:53\n2024-02-20,Turmeric Ginger Latte,13,6.51,84.6,13:35:29\n2024-02-20,Cold Brew Concentrate,14,6.12,85.72,13:36:05\n2024-02-20,Nitro Cold Brew,9,6.08,54.76,13:36:42\n2024-02-20,Matcha Espresso Fusion,9,7.0,63.04,13:37:18\n2024-02-20,Blue Pea Flower Tea,11,4.59,50.49,13:37:55\n2024-02-20,Sourdough Toast,11,6.23,68.54,13:38:31\n2024-02-20,Almond Butter Croissant,13,5.05,65.62,13:39:07\n2024-02-20,Vegan Morning Bun,5,5.52,27.58,13:39:44\n2024-02-21,Single-Origin Pour Over,17,5.45,92.61,13:40:20\n2024-02-21,Oat Milk Latte,9,6.32,56.89,13:40:57\n2024-02-21,Honey Lavender Latte,12,6.52,78.26,13:41:33\n2024-02-21,Turmeric Ginger Latte,14,6.6,92.46,13:42:09\n2024-02-21,Cold Brew Concentrate,12,5.97,71.61,13:42:46\n2024-02-21,Nitro Cold Brew,15,6.41,96.19,13:43:22\n2024-02-21,Matcha Espresso Fusion,14,6.89,96.52,13:43:59\n2024-02-21,Blue Pea Flower Tea,15,4.61,69.18,13:44:35\n2024-02-21,Sourdough Toast,5,6.11,30.53,13:45:11\n2024-02-21,Almond Butter Croissant,10,5.36,53.59,13:45:48\n2024-02-21,Vegan Morning Bun,9,5.73,51.61,13:46:24\n2024-02-22,Single-Origin Pour Over,6,5.27,31.6,13:47:01\n2024-02-22,Oat Milk Latte,21,6.26,131.54,13:47:37\n2024-02-22,Honey Lavender Latte,1,6.43,6.43,13:48:13\n2024-02-22,Turmeric Ginger Latte,12,6.56,78.77,13:48:50\n2024-02-22,Cold Brew Concentrate,8,5.76,46.06,13:49:26\n2024-02-22,Nitro Cold Brew,13,6.64,86.37,13:50:03\n2024-02-22,Matcha Espresso Fusion,9,6.54,58.9,13:50:39\n2024-02-22,Blue Pea Flower Tea,10,4.29,42.95,13:51:15\n2024-02-22,Sourdough Toast,11,6.34,69.73,13:51:52\n2024-02-22,Almond Butter Croissant,9,5.62,50.54,13:52:28\n2024-02-22,Vegan Morning Bun,10,5.95,59.46,13:53:05\n2024-02-23,Single-Origin Pour Over,15,5.29,79.34,13:53:41\n2024-02-23,Oat Milk Latte,8,6.18,49.42,13:54:17\n2024-02-23,Honey Lavender Latte,16,6.44,103.01,13:54:54\n2024-02-23,Turmeric Ginger Latte,1,6.4,6.4,13:55:30\n2024-02-23,Cold Brew Concentrate,7,5.71,39.99,13:56:07\n2024-02-23,Nitro Cold Brew,13,6.5,84.51,13:56:43\n2024-02-23,Matcha Espresso Fusion,5,6.75,33.75,13:57:19\n2024-02-23,Blue Pea Flower Tea,11,4.5,49.53,13:57:56\n2024-02-23,Sourdough Toast,14,6.0,84.04,13:58:32\n2024-02-23,Almond Butter Croissant,14,5.64,78.94,13:59:09\n2024-02-23,Vegan Morning Bun,23,5.53,127.17,13:59:45\n2024-02-24,Single-Origin Pour Over,9,5.71,51.42,14:00:21\n2024-02-24,Oat Milk Latte,14,5.97,83.52,14:00:58\n2024-02-24,Honey Lavender Latte,9,6.36,57.27,14:01:34\n2024-02-24,Turmeric Ginger Latte,9,6.59,59.33,14:02:11\n2024-02-24,Cold Brew Concentrate,2,6.03,12.06,14:02:47\n2024-02-24,Nitro Cold Brew,9,6.35,57.14,14:03:23\n2024-02-24,Matcha Espresso Fusion,5,6.63,33.13,14:04:00\n2024-02-24,Blue Pea Flower Tea,16,4.34,69.48,14:04:36\n2024-02-24,Sourdough Toast,7,6.17,43.17,14:05:13\n2024-02-24,Almond Butter Croissant,3,5.25,15.76,14:05:49\n2024-02-24,Vegan Morning Bun,5,5.76,28.78,14:06:25\n2024-02-25,Single-Origin Pour Over,9,5.61,50.48,14:07:02\n2024-02-25,Oat Milk Latte,13,6.35,82.49,14:07:38\n2024-02-25,Honey Lavender Latte,9,6.62,59.58,14:08:15\n2024-02-25,Turmeric Ginger Latte,10,6.5,65.0,14:08:51\n2024-02-25,Cold Brew Concentrate,10,6.03,60.26,14:09:27\n2024-02-25,Nitro Cold Brew,8,6.42,51.32,14:10:04\n2024-02-25,Matcha Espresso Fusion,10,6.72,67.23,14:10:40\n2024-02-25,Blue Pea Flower Tea,5,4.87,24.33,14:11:17\n2024-02-25,Sourdough Toast,12,6.38,76.59,14:11:53\n2024-02-25,Almond Butter Croissant,20,5.57,111.44,14:12:29\n2024-02-25,Vegan Morning Bun,15,6.09,91.3,14:13:06\n2024-02-26,Single-Origin Pour Over,10,5.76,57.65,14:13:42\n2024-02-26,Oat Milk Latte,8,5.93,47.43,14:14:19\n2024-02-26,Honey Lavender Latte,13,6.56,85.26,14:14:55\n2024-02-26,Turmeric Ginger Latte,11,6.37,70.11,14:15:31\n2024-02-26,Cold Brew Concentrate,9,6.09,54.8,14:16:08\n2024-02-26,Nitro Cold Brew,9,6.5,58.5,14:16:44\n2024-02-26,Matcha Espresso Fusion,10,7.07,70.72,14:17:21\n2024-02-26,Blue Pea Flower Tea,15,4.34,65.06,14:17:57\n2024-02-26,Sourdough Toast,14,6.09,85.29,14:18:33\n2024-02-26,Almond Butter Croissant,10,5.27,52.68,14:19:10\n2024-02-26,Vegan Morning Bun,7,5.62,39.31,14:19:46\n2024-02-27,Single-Origin Pour Over,8,5.54,44.35,14:20:23\n2024-02-27,Oat Milk Latte,7,6.23,43.59,14:20:59\n2024-02-27,Honey Lavender Latte,12,6.31,75.7,14:21:35\n2024-02-27,Turmeric Ginger Latte,7,6.26,43.79,14:22:12\n2024-02-27,Cold Brew Concentrate,10,5.61,56.11,14:22:48\n2024-02-27,Nitro Cold Brew,12,6.29,75.51,14:23:25\n2024-02-27,Matcha Espresso Fusion,10,6.65,66.49,14:24:01\n2024-02-27,Blue Pea Flower Tea,12,4.28,51.37,14:24:37\n2024-02-27,Sourdough Toast,17,6.0,101.98,14:25:14\n2024-02-27,Almond Butter Croissant,5,5.19,25.97,14:25:50\n2024-02-27,Vegan Morning Bun,21,5.71,119.98,14:26:27\n2024-02-28,Single-Origin Pour Over,10,5.9,58.98,14:27:03\n2024-02-28,Oat Milk Latte,2,6.35,12.7,14:27:39\n2024-02-28,Honey Lavender Latte,16,6.36,101.68,14:28:16\n2024-02-28,Turmeric Ginger Latte,12,6.41,76.91,14:28:52\n2024-02-28,Cold Brew Concentrate,9,5.86,52.78,14:29:29\n2024-02-28,Nitro Cold Brew,15,6.34,95.05,14:30:05\n2024-02-28,Matcha Espresso Fusion,17,6.52,110.76,14:30:41\n2024-02-28,Blue Pea Flower Tea,2,4.59,9.18,14:31:18\n2024-02-28,Sourdough Toast,17,5.79,98.5,14:31:54\n2024-02-28,Almond Butter Croissant,11,5.57,61.31,14:32:31\n2024-02-28,Vegan Morning Bun,14,6.0,83.95,14:33:07\n2024-02-29,Single-Origin Pour Over,10,5.64,56.42,14:33:43\n2024-02-29,Oat Milk Latte,8,6.19,49.49,14:34:20\n2024-02-29,Honey Lavender Latte,1,6.49,6.49,14:34:56\n2024-02-29,Turmeric Ginger Latte,12,6.46,77.54,14:35:33\n2024-02-29,Cold Brew Concentrate,10,5.68,56.85,14:36:09\n2024-02-29,Nitro Cold Brew,13,6.23,80.96,14:36:45\n2024-02-29,Matcha Espresso Fusion,11,6.55,72.02,14:37:22\n2024-02-29,Blue Pea Flower Tea,10,4.51,45.05,14:37:58\n2024-02-29,Sourdough Toast,14,6.12,85.64,14:38:35\n2024-02-29,Almond Butter Croissant,4,5.15,20.62,14:39:11\n2024-02-29,Vegan Morning Bun,11,5.83,64.11,14:39:47\n2024-03-01,Single-Origin Pour Over,8,5.37,42.95,14:40:24\n2024-03-01,Oat Milk Latte,9,5.88,52.89,14:41:00\n2024-03-01,Honey Lavender Latte,11,6.74,74.15,14:41:37\n2024-03-01,Turmeric Ginger Latte,16,6.54,104.58,14:42:13\n2024-03-01,Cold Brew Concentrate,13,6.03,78.44,14:42:49\n2024-03-01,Nitro Cold Brew,8,6.15,49.19,14:43:26\n2024-03-01,Matcha Espresso Fusion,12,6.84,82.04,14:44:02\n2024-03-01,Blue Pea Flower Tea,15,4.9,73.44,14:44:39\n2024-03-01,Sourdough Toast,13,5.8,75.4,14:45:15\n2024-03-01,Almond Butter Croissant,4,5.23,20.94,14:45:51\n2024-03-01,Vegan Morning Bun,15,6.14,92.15,14:46:28\n2024-03-02,Single-Origin Pour Over,8,5.35,42.79,14:47:04\n2024-03-02,Oat Milk Latte,12,6.39,76.63,14:47:41\n2024-03-02,Honey Lavender Latte,9,6.88,61.89,14:48:17\n2024-03-02,Turmeric Ginger Latte,14,6.38,89.27,14:48:53\n2024-03-02,Cold Brew Concentrate,15,5.51,82.65,14:49:30\n2024-03-02,Nitro Cold Brew,12,6.3,75.66,14:50:06\n2024-03-02,Matcha Espresso Fusion,15,6.51,97.69,14:50:43\n2024-03-02,Blue Pea Flower Tea,9,4.88,43.88,14:51:19\n2024-03-02,Sourdough Toast,6,6.17,36.99,14:51:55\n2024-03-02,Almond Butter Croissant,7,5.48,38.36,14:52:32\n2024-03-02,Vegan Morning Bun,19,5.64,107.07,14:53:08\n2024-03-03,Single-Origin Pour Over,13,5.36,69.71,14:53:45\n2024-03-03,Oat Milk Latte,3,6.32,18.97,14:54:21\n2024-03-03,Honey Lavender Latte,11,6.86,75.42,14:54:57\n2024-03-03,Turmeric Ginger Latte,3,6.24,18.72,14:55:34\n2024-03-03,Cold Brew Concentrate,20,5.78,115.66,14:56:10\n2024-03-03,Nitro Cold Brew,15,6.17,92.51,14:56:47\n2024-03-03,Matcha Espresso Fusion,19,6.77,128.57,14:57:23\n2024-03-03,Blue Pea Flower Tea,12,4.7,56.37,14:57:59\n2024-03-03,Sourdough Toast,8,6.36,50.9,14:58:36\n2024-03-03,Almond Butter Croissant,4,5.04,20.18,14:59:12\n2024-03-03,Vegan Morning Bun,9,5.96,53.6,14:59:49\n2024-03-04,Single-Origin Pour Over,17,5.4,91.8,15:00:25\n2024-03-04,Oat Milk Latte,13,6.02,78.29,15:01:01\n2024-03-04,Honey Lavender Latte,15,6.26,93.96,15:01:38\n2024-03-04,Turmeric Ginger Latte,22,6.48,142.58,15:02:14\n2024-03-04,Cold Brew Concentrate,5,5.9,29.49,15:02:51\n2024-03-04,Nitro Cold Brew,13,6.32,82.17,15:03:27\n2024-03-04,Matcha Espresso Fusion,19,6.79,129.1,15:04:03\n2024-03-04,Blue Pea Flower Tea,5,4.85,24.26,15:04:40\n2024-03-04,Sourdough Toast,9,5.94,53.43,15:05:16\n2024-03-04,Almond Butter Croissant,7,5.39,37.71,15:05:53\n2024-03-04,Vegan Morning Bun,15,5.71,85.59,15:06:29\n2024-03-05,Single-Origin Pour Over,10,5.54,55.36,15:07:05\n2024-03-05,Oat Milk Latte,2,6.04,12.07,15:07:42\n2024-03-05,Honey Lavender Latte,6,6.67,40.04,15:08:18\n2024-03-05,Turmeric Ginger Latte,12,6.5,78.0,15:08:55\n2024-03-05,Cold Brew Concentrate,4,5.58,22.32,15:09:31\n2024-03-05,Nitro Cold Brew,1,6.02,6.02,15:10:07\n2024-03-05,Matcha Espresso Fusion,9,6.57,59.15,15:10:44\n2024-03-05,Blue Pea Flower Tea,4,4.48,17.93,15:11:20\n2024-03-05,Sourdough Toast,24,6.23,149.44,15:11:57\n2024-03-05,Almond Butter Croissant,2,5.34,10.68,15:12:33\n2024-03-05,Vegan Morning Bun,9,5.78,52.06,15:13:09\n2024-03-06,Single-Origin Pour Over,7,5.6,39.22,15:13:46\n2024-03-06,Oat Milk Latte,2,6.34,12.68,15:14:22\n2024-03-06,Honey Lavender Latte,5,6.68,33.42,15:14:59\n2024-03-06,Turmeric Ginger Latte,10,6.21,62.08,15:15:35\n2024-03-06,Cold Brew Concentrate,22,5.53,121.74,15:16:11\n2024-03-06,Nitro Cold Brew,9,6.55,58.99,15:16:48\n2024-03-06,Matcha Espresso Fusion,17,6.52,110.87,15:17:24\n2024-03-06,Blue Pea Flower Tea,11,4.65,51.14,15:18:01\n2024-03-06,Sourdough Toast,9,6.17,55.56,15:18:37\n2024-03-06,Almond Butter Croissant,16,5.26,84.21,15:19:13\n2024-03-06,Vegan Morning Bun,5,5.61,28.06,15:19:50\n2024-03-07,Single-Origin Pour Over,10,5.83,58.3,15:20:26\n2024-03-07,Oat Milk Latte,9,5.93,53.38,15:21:03\n2024-03-07,Honey Lavender Latte,6,6.89,41.34,15:21:39\n2024-03-07,Turmeric Ginger Latte,12,6.58,78.98,15:22:15\n2024-03-07,Cold Brew Concentrate,9,6.07,54.65,15:22:52\n2024-03-07,Nitro Cold Brew,9,6.19,55.72,15:23:28\n2024-03-07,Matcha Espresso Fusion,13,6.6,85.75,15:24:05\n2024-03-07,Blue Pea Flower Tea,7,4.3,30.08,15:24:41\n2024-03-07,Sourdough Toast,13,5.87,76.35,15:25:17\n2024-03-07,Almond Butter Croissant,12,5.56,66.67,15:25:54\n2024-03-07,Vegan Morning Bun,16,5.72,91.45,15:26:30\n2024-03-08,Single-Origin Pour Over,13,5.48,71.2,15:27:07\n2024-03-08,Oat Milk Latte,4,5.95,23.79,15:27:43\n2024-03-08,Honey Lavender Latte,13,6.33,82.3,15:28:19\n2024-03-08,Turmeric Ginger Latte,11,6.09,67.03,15:28:56\n2024-03-08,Cold Brew Concentrate,18,6.09,109.65,15:29:32\n2024-03-08,Nitro Cold Brew,22,6.35,139.8,15:30:09\n2024-03-08,Matcha Espresso Fusion,11,6.93,76.27,15:30:45\n2024-03-08,Blue Pea Flower Tea,18,4.65,83.68,15:31:21\n2024-03-08,Sourdough Toast,10,5.88,58.82,15:31:58\n2024-03-08,Almond Butter Croissant,18,5.63,101.37,15:32:34\n2024-03-08,Vegan Morning Bun,4,5.73,22.92,15:33:11\n2024-03-09,Single-Origin Pour Over,14,5.78,80.94,15:33:47\n2024-03-09,Oat Milk Latte,6,5.95,35.7,15:34:23\n2024-03-09,Honey Lavender Latte,21,6.62,138.97,15:35:00\n2024-03-09,Turmeric Ginger Latte,12,6.58,78.9,15:35:36\n2024-03-09,Cold Brew Concentrate,14,5.55,77.72,15:36:13\n2024-03-09,Nitro Cold Brew,10,6.22,62.15,15:36:49\n2024-03-09,Matcha Espresso Fusion,12,7.1,85.24,15:37:25\n2024-03-09,Blue Pea Flower Tea,17,4.65,79.13,15:38:02\n2024-03-09,Sourdough Toast,8,6.07,48.55,15:38:38\n2024-03-09,Almond Butter Croissant,15,5.31,79.66,15:39:15\n2024-03-09,Vegan Morning Bun,10,5.93,59.25,15:39:51\n2024-03-10,Single-Origin Pour Over,2,5.85,11.71,15:40:27\n2024-03-10,Oat Milk Latte,7,6.0,41.99,15:41:04\n2024-03-10,Honey Lavender Latte,12,6.45,77.39,15:41:40\n2024-03-10,Turmeric Ginger Latte,10,6.21,62.05,15:42:17\n2024-03-10,Cold Brew Concentrate,3,6.01,18.03,15:42:53\n2024-03-10,Nitro Cold Brew,17,6.2,105.34,15:43:29\n2024-03-10,Matcha Espresso Fusion,11,7.14,78.52,15:44:06\n2024-03-10,Blue Pea Flower Tea,13,4.33,56.3,15:44:42\n2024-03-10,Sourdough Toast,7,5.9,41.27,15:45:19\n2024-03-10,Almond Butter Croissant,13,5.24,68.13,15:45:55\n2024-03-10,Vegan Morning Bun,18,5.54,99.71,15:46:31\n2024-03-11,Single-Origin Pour Over,13,5.28,68.59,15:47:08\n2024-03-11,Oat Milk Latte,16,5.99,95.78,15:47:44\n2024-03-11,Honey Lavender Latte,9,6.31,56.76,15:48:21\n2024-03-11,Turmeric Ginger Latte,12,6.42,77.02,15:48:57\n2024-03-11,Cold Brew Concentrate,10,5.53,55.26,15:49:33\n2024-03-11,Nitro Cold Brew,15,6.31,94.67,15:50:10\n2024-03-11,Matcha Espresso Fusion,15,7.02,105.3,15:50:46\n2024-03-11,Blue Pea Flower Tea,15,4.75,71.31,15:51:23\n2024-03-11,Sourdough Toast,10,6.19,61.89,15:51:59\n2024-03-11,Almond Butter Croissant,13,5.62,73.05,15:52:35\n2024-03-11,Vegan Morning Bun,3,6.07,18.2,15:53:12\n2024-03-12,Single-Origin Pour Over,11,5.75,63.21,15:53:48\n2024-03-12,Oat Milk Latte,10,6.02,60.23,15:54:25\n2024-03-12,Honey Lavender Latte,12,6.51,78.14,15:55:01\n2024-03-12,Turmeric Ginger Latte,1,6.38,6.38,15:55:37\n2024-03-12,Cold Brew Concentrate,10,5.88,58.78,15:56:14\n2024-03-12,Nitro Cold Brew,6,6.27,37.65,15:56:50\n2024-03-12,Matcha Espresso Fusion,15,7.03,105.49,15:57:27\n2024-03-12,Blue Pea Flower Tea,2,4.35,8.7,15:58:03\n2024-03-12,Sourdough Toast,19,5.87,111.55,15:58:39\n2024-03-12,Almond Butter Croissant,20,5.45,109.02,15:59:16\n2024-03-12,Vegan Morning Bun,14,5.89,82.48,15:59:52\n2024-03-13,Single-Origin Pour Over,11,5.45,59.96,16:00:29\n2024-03-13,Oat Milk Latte,7,5.75,40.27,16:01:05\n2024-03-13,Honey Lavender Latte,15,6.88,103.13,16:01:41\n2024-03-13,Turmeric Ginger Latte,12,6.08,72.95,16:02:18\n2024-03-13,Cold Brew Concentrate,15,5.85,87.69,16:02:54\n2024-03-13,Nitro Cold Brew,14,6.04,84.59,16:03:31\n2024-03-13,Matcha Espresso Fusion,10,7.14,71.38,16:04:07\n2024-03-13,Blue Pea Flower Tea,10,4.57,45.69,16:04:43\n2024-03-13,Sourdough Toast,13,5.91,76.89,16:05:20\n2024-03-13,Almond Butter Croissant,5,5.4,27.01,16:05:56\n2024-03-13,Vegan Morning Bun,23,6.03,138.6,16:06:33\n2024-03-14,Single-Origin Pour Over,8,5.57,44.58,16:07:09\n2024-03-14,Oat Milk Latte,11,6.12,67.32,16:07:45\n2024-03-14,Honey Lavender Latte,5,6.38,31.92,16:08:22\n2024-03-14,Turmeric Ginger Latte,14,6.08,85.13,16:08:58\n2024-03-14,Cold Brew Concentrate,16,6.0,96.04,16:09:35\n2024-03-14,Nitro Cold Brew,14,6.34,88.69,16:10:11\n2024-03-14,Matcha Espresso Fusion,19,6.82,129.63,16:10:47\n2024-03-14,Blue Pea Flower Tea,10,4.62,46.2,16:11:24\n2024-03-14,Sourdough Toast,18,6.17,110.98,16:12:00\n2024-03-14,Almond Butter Croissant,13,5.29,68.8,16:12:37\n2024-03-14,Vegan Morning Bun,15,5.84,87.64,16:13:13\n2024-03-15,Single-Origin Pour Over,14,5.64,79.01,16:13:49\n2024-03-15,Oat Milk Latte,10,5.79,57.93,16:14:26\n2024-03-15,Honey Lavender Latte,13,6.66,86.58,16:15:02\n2024-03-15,Turmeric Ginger Latte,14,6.64,93.02,16:15:39\n2024-03-15,Cold Brew Concentrate,9,6.06,54.58,16:16:15\n2024-03-15,Nitro Cold Brew,17,6.61,112.39,16:16:51\n2024-03-15,Matcha Espresso Fusion,1,6.85,6.85,16:17:28\n2024-03-15,Blue Pea Flower Tea,7,4.35,30.45,16:18:04\n2024-03-15,Sourdough Toast,9,6.23,56.09,16:18:41\n2024-03-15,Almond Butter Croissant,14,5.23,73.23,16:19:17\n2024-03-15,Vegan Morning Bun,15,6.14,92.05,16:19:53\n2024-03-16,Single-Origin Pour Over,9,5.48,49.28,16:20:30\n2024-03-16,Oat Milk Latte,3,6.15,18.45,16:21:06\n2024-03-16,Honey Lavender Latte,6,6.48,38.88,16:21:43\n2024-03-16,Turmeric Ginger Latte,15,6.3,94.57,16:22:19\n2024-03-16,Cold Brew Concentrate,5,5.95,29.77,16:22:55\n2024-03-16,Nitro Cold Brew,1,6.33,6.33,16:23:32\n2024-03-16,Matcha Espresso Fusion,17,7.04,119.63,16:24:08\n2024-03-16,Blue Pea Flower Tea,7,4.56,31.95,16:24:45\n2024-03-16,Sourdough Toast,18,5.77,103.87,16:25:21\n2024-03-16,Almond Butter Croissant,14,5.11,71.54,16:25:57\n2024-03-16,Vegan Morning Bun,13,5.73,74.49,16:26:34\n2024-03-17,Single-Origin Pour Over,15,5.77,86.57,16:27:10\n2024-03-17,Oat Milk Latte,1,6.32,6.32,16:27:47\n2024-03-17,Honey Lavender Latte,14,6.84,95.74,16:28:23\n2024-03-17,Turmeric Ginger Latte,10,6.4,63.99,16:28:59\n2024-03-17,Cold Brew Concentrate,6,5.62,33.74,16:29:36\n2024-03-17,Nitro Cold Brew,12,6.39,76.64,16:30:12\n2024-03-17,Matcha Espresso Fusion,7,6.7,46.9,16:30:49\n2024-03-17,Blue Pea Flower Tea,19,4.75,90.27,16:31:25\n2024-03-17,Sourdough Toast,15,6.16,92.47,16:32:01\n2024-03-17,Almond Butter Croissant,14,5.44,76.09,16:32:38\n2024-03-17,Vegan Morning Bun,1,5.9,5.9,16:33:14\n2024-03-18,Single-Origin Pour Over,10,5.64,56.41,16:33:51\n2024-03-18,Oat Milk Latte,8,5.81,46.46,16:34:27\n2024-03-18,Honey Lavender Latte,5,6.68,33.42,16:35:03\n2024-03-18,Turmeric Ginger Latte,11,6.64,73.03,16:35:40\n2024-03-18,Cold Brew Concentrate,6,6.09,36.52,16:36:16\n2024-03-18,Nitro Cold Brew,15,6.45,96.79,16:36:53\n2024-03-18,Matcha Espresso Fusion,14,7.13,99.81,16:37:29\n2024-03-18,Blue Pea Flower Tea,14,4.51,63.15,16:38:05\n2024-03-18,Sourdough Toast,6,5.99,35.94,16:38:42\n2024-03-18,Almond Butter Croissant,14,5.45,76.28,16:39:18\n2024-03-18,Vegan Morning Bun,3,5.87,17.61,16:39:55\n2024-03-19,Single-Origin Pour Over,8,5.72,45.72,16:40:31\n2024-03-19,Oat Milk Latte,11,6.23,68.48,16:41:07\n2024-03-19,Honey Lavender Latte,8,6.29,50.31,16:41:44\n2024-03-19,Turmeric Ginger Latte,11,6.46,71.11,16:42:20\n2024-03-19,Cold Brew Concentrate,14,5.74,80.42,16:42:57\n2024-03-19,Nitro Cold Brew,13,6.39,83.04,16:43:33\n2024-03-19,Matcha Espresso Fusion,17,7.12,121.07,16:44:09\n2024-03-19,Blue Pea Flower Tea,16,4.49,71.82,16:44:46\n2024-03-19,Sourdough Toast,16,6.32,101.09,16:45:22\n2024-03-19,Almond Butter Croissant,13,5.13,66.65,16:45:59\n2024-03-19,Vegan Morning Bun,8,5.67,45.37,16:46:35\n2024-03-20,Single-Origin Pour Over,5,5.4,27.0,16:47:11\n2024-03-20,Oat Milk Latte,13,6.26,81.36,16:47:48\n2024-03-20,Honey Lavender Latte,16,6.61,105.71,16:48:24\n2024-03-20,Turmeric Ginger Latte,11,6.14,67.56,16:49:01\n2024-03-20,Cold Brew Concentrate,8,5.68,45.42,16:49:37\n2024-03-20,Nitro Cold Brew,10,6.39,63.89,16:50:13\n2024-03-20,Matcha Espresso Fusion,18,6.66,119.89,16:50:50\n2024-03-20,Blue Pea Flower Tea,12,4.81,57.67,16:51:26\n2024-03-20,Sourdough Toast,16,5.94,95.02,16:52:03\n2024-03-20,Almond Butter Croissant,9,5.36,48.21,16:52:39\n2024-03-20,Vegan Morning Bun,15,5.71,85.64,16:53:15\n2024-03-21,Single-Origin Pour Over,15,5.42,81.33,16:53:52\n2024-03-21,Oat Milk Latte,4,6.2,24.8,16:54:28\n2024-03-21,Honey Lavender Latte,17,6.71,114.08,16:55:05\n2024-03-21,Turmeric Ginger Latte,12,6.56,78.72,16:55:41\n2024-03-21,Cold Brew Concentrate,6,5.72,34.33,16:56:17\n2024-03-21,Nitro Cold Brew,20,6.46,129.24,16:56:54\n2024-03-21,Matcha Espresso Fusion,15,6.63,99.41,16:57:30\n2024-03-21,Blue Pea Flower Tea,14,4.45,62.31,16:58:07\n2024-03-21,Sourdough Toast,18,6.36,114.42,16:58:43\n2024-03-21,Almond Butter Croissant,10,5.52,55.21,16:59:19\n2024-03-21,Vegan Morning Bun,16,5.62,89.84,16:59:56\n2024-03-22,Single-Origin Pour Over,21,5.72,120.12,17:00:32\n2024-03-22,Oat Milk Latte,17,6.1,103.74,17:01:09\n2024-03-22,Honey Lavender Latte,5,6.57,32.84,17:01:45\n2024-03-22,Turmeric Ginger Latte,8,6.31,50.51,17:02:21\n2024-03-22,Cold Brew Concentrate,14,5.57,77.98,17:02:58\n2024-03-22,Nitro Cold Brew,13,6.53,84.89,17:03:34\n2024-03-22,Matcha Espresso Fusion,1,6.66,6.66,17:04:11\n2024-03-22,Blue Pea Flower Tea,16,4.38,70.14,17:04:47\n2024-03-22,Sourdough Toast,14,5.8,81.17,17:05:23\n2024-03-22,Almond Butter Croissant,7,5.09,35.62,17:06:00\n2024-03-22,Vegan Morning Bun,14,5.68,79.57,17:06:36\n2024-03-23,Single-Origin Pour Over,12,5.43,65.13,17:07:13\n2024-03-23,Oat Milk Latte,23,5.78,132.9,17:07:49\n2024-03-23,Honey Lavender Latte,7,6.39,44.72,17:08:25\n2024-03-23,Turmeric Ginger Latte,17,6.37,108.25,17:09:02\n2024-03-23,Cold Brew Concentrate,7,5.64,39.46,17:09:38\n2024-03-23,Nitro Cold Brew,11,6.6,72.57,17:10:15\n2024-03-23,Matcha Espresso Fusion,9,6.68,60.08,17:10:51\n2024-03-23,Blue Pea Flower Tea,13,4.43,57.58,17:11:27\n2024-03-23,Sourdough Toast,17,6.1,103.65,17:12:04\n2024-03-23,Almond Butter Croissant,12,5.05,60.57,17:12:40\n2024-03-23,Vegan Morning Bun,21,5.91,124.16,17:13:17\n2024-03-24,Single-Origin Pour Over,9,5.45,49.05,17:13:53\n2024-03-24,Oat Milk Latte,22,5.79,127.43,17:14:29\n2024-03-24,Honey Lavender Latte,18,6.82,122.72,17:15:06\n2024-03-24,Turmeric Ginger Latte,5,6.3,31.52,17:15:42\n2024-03-24,Cold Brew Concentrate,1,6.03,6.03,17:16:19\n2024-03-24,Nitro Cold Brew,14,6.34,88.69,17:16:55\n2024-03-24,Matcha Espresso Fusion,11,6.98,76.76,17:17:31\n2024-03-24,Blue Pea Flower Tea,10,4.61,46.14,17:18:08\n2024-03-24,Sourdough Toast,12,5.85,70.19,17:18:44\n2024-03-24,Almond Butter Croissant,11,5.2,57.17,17:19:21\n2024-03-24,Vegan Morning Bun,1,6.15,6.15,17:19:57\n2024-03-25,Single-Origin Pour Over,6,5.62,33.69,17:20:33\n2024-03-25,Oat Milk Latte,5,5.91,29.54,17:21:10\n2024-03-25,Honey Lavender Latte,17,6.51,110.64,17:21:46\n2024-03-25,Turmeric Ginger Latte,13,6.27,81.51,17:22:23\n2024-03-25,Cold Brew Concentrate,15,6.01,90.22,17:22:59\n2024-03-25,Nitro Cold Brew,10,6.01,60.14,17:23:35\n2024-03-25,Matcha Espresso Fusion,11,6.85,75.35,17:24:12\n2024-03-25,Blue Pea Flower Tea,5,4.55,22.76,17:24:48\n2024-03-25,Sourdough Toast,8,5.88,47.02,17:25:25\n2024-03-25,Almond Butter Croissant,11,5.61,61.68,17:26:01\n2024-03-25,Vegan Morning Bun,6,5.69,34.15,17:26:37\n2024-03-26,Single-Origin Pour Over,19,5.29,100.57,17:27:14\n2024-03-26,Oat Milk Latte,12,6.01,72.08,17:27:50\n2024-03-26,Honey Lavender Latte,11,6.63,72.89,17:28:27\n2024-03-26,Turmeric Ginger Latte,15,6.09,91.39,17:29:03\n2024-03-26,Cold Brew Concentrate,8,5.67,45.35,17:29:39\n2024-03-26,Nitro Cold Brew,13,6.52,84.7,17:30:16\n2024-03-26,Matcha Espresso Fusion,5,6.62,33.1,17:30:52\n2024-03-26,Blue Pea Flower Tea,8,4.63,37.0,17:31:29\n2024-03-26,Sourdough Toast,9,6.39,57.48,17:32:05\n2024-03-26,Almond Butter Croissant,10,5.47,54.73,17:32:41\n2024-03-26,Vegan Morning Bun,12,5.66,67.91,17:33:18\n2024-03-27,Single-Origin Pour Over,6,5.38,32.31,17:33:54\n2024-03-27,Oat Milk Latte,3,6.13,18.39,17:34:31\n2024-03-27,Honey Lavender Latte,7,6.41,44.84,17:35:07\n2024-03-27,Turmeric Ginger Latte,10,6.54,65.38,17:35:43\n2024-03-27,Cold Brew Concentrate,9,5.57,50.14,17:36:20\n2024-03-27,Nitro Cold Brew,9,6.47,58.23,17:36:56\n2024-03-27,Matcha Espresso Fusion,12,6.57,78.85,17:37:33\n2024-03-27,Blue Pea Flower Tea,18,4.41,79.35,17:38:09\n2024-03-27,Sourdough Toast,7,5.97,41.82,17:38:45\n2024-03-27,Almond Butter Croissant,7,5.21,36.48,17:39:22\n2024-03-27,Vegan Morning Bun,8,5.6,44.8,17:39:58\n2024-03-28,Single-Origin Pour Over,13,5.76,74.91,17:40:35\n2024-03-28,Oat Milk Latte,13,6.1,79.26,17:41:11\n2024-03-28,Honey Lavender Latte,5,6.59,32.97,17:41:47\n2024-03-28,Turmeric Ginger Latte,11,6.03,66.34,17:42:24\n2024-03-28,Cold Brew Concentrate,14,5.56,77.88,17:43:00\n2024-03-28,Nitro Cold Brew,12,6.18,74.22,17:43:37\n2024-03-28,Matcha Espresso Fusion,15,6.76,101.45,17:44:13\n2024-03-28,Blue Pea Flower Tea,15,4.34,65.03,17:44:49\n2024-03-28,Sourdough Toast,6,6.14,36.86,17:45:26\n2024-03-28,Almond Butter Croissant,7,5.63,39.44,17:46:02\n2024-03-28,Vegan Morning Bun,16,5.72,91.5,17:46:39\n2024-03-29,Single-Origin Pour Over,19,5.7,108.35,17:47:15\n2024-03-29,Oat Milk Latte,10,5.8,58.01,17:47:51\n2024-03-29,Honey Lavender Latte,8,6.49,51.91,17:48:28\n2024-03-29,Turmeric Ginger Latte,3,6.32,18.96,17:49:04\n2024-03-29,Cold Brew Concentrate,13,5.65,73.4,17:49:41\n2024-03-29,Nitro Cold Brew,9,6.34,57.05,17:50:17\n2024-03-29,Matcha Espresso Fusion,7,6.92,48.44,17:50:53\n2024-03-29,Blue Pea Flower Tea,14,4.73,66.28,17:51:30\n2024-03-29,Sourdough Toast,13,6.11,79.45,17:52:06\n2024-03-29,Almond Butter Croissant,6,5.63,33.77,17:52:43\n2024-03-29,Vegan Morning Bun,10,5.94,59.45,17:53:19\n2024-03-30,Single-Origin Pour Over,18,5.52,99.27,17:53:55\n2024-03-30,Oat Milk Latte,8,5.88,47.02,17:54:32\n2024-03-30,Honey Lavender Latte,8,6.55,52.41,17:55:08\n2024-03-30,Turmeric Ginger Latte,9,6.01,54.11,17:55:45\n2024-03-30,Cold Brew Concentrate,12,5.71,68.54,17:56:21\n2024-03-30,Nitro Cold Brew,3,6.03,18.09,17:56:57\n2024-03-30,Matcha Espresso Fusion,7,6.51,45.58,17:57:34\n2024-03-30,Blue Pea Flower Tea,4,4.48,17.9,17:58:10\n2024-03-30,Sourdough Toast,9,6.28,56.54,17:58:47\n2024-03-30,Almond Butter Croissant,10,5.35,53.54,17:59:23\n2024-03-30,Vegan Morning Bun,12,5.6,67.19,18:00:00\n"
  },
  {
    "path": "guides/python/ai-data-analyst/litellm/pyproject.toml",
    "content": "[project]\nname = \"ai-data-analyst-litellm\"\nversion = \"0.1.0\"\ndescription = \"Daytona + LiteLLM data analyst example in Python\"\nrequires-python = \">=3.10,<4.0\"\n\ndependencies = [\n  \"litellm\",\n  \"daytona\",\n]\n\n[tool.setuptools]\npy-modules = []\n"
  },
  {
    "path": "guides/python/ai-data-analyst/openai/.gitignore",
    "content": "# Agent output files\nchart-*.png\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# Virtual Environments\nvenv/\nenv/\nENV/\nenv.bak/\nvenv.bak/\n.venv/\n.virtualenv/\n.pyenv/\n\n# Poetry\npoetry.lock\n.poetry/\n\n# Pipenv\nPipfile.lock\n\n# pyenv\n.python-version\n\n# Conda\nconda-meta/\n.conda/\n\n# PyCharm\n.idea/\n*.iml\n\n# VS Code\n.vscode/\n*.code-workspace\n\n# Jupyter Notebook\n.ipynb_checkpoints/\n*.ipynb_checkpoints/\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.env.local\n.env.*.local\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# macOS\n.DS_Store\n\n# Windows\nThumbs.db\nehthumbs.db\nDesktop.ini\n\n# Linux\n*~\n\n# Temporary files\n*.tmp\n*.bak\n*.swp\n*~"
  },
  {
    "path": "guides/python/ai-data-analyst/openai/README.md",
    "content": "# OpenAI Data Analysis Example (OpenAI + Daytona)\n\n## Overview\n\nThis example demonstrates how to build a data analysis tool using [OpenAI's API](https://platform.openai.com/) and [Daytona](https://daytona.io) sandboxes. The script executes Python code in an isolated environment to analyze cafe sales data, enabling automated data analysis workflows with natural language prompts.\n\nIn this example, the agent analyzes a cafe sales dataset to find the three highest revenue products for January and visualizes the results in a bar chart.\n\n## Features\n\n- **Secure sandbox execution:** All Python code runs in isolated Daytona sandboxes\n- **Natural language interface:** Describe your analysis task in plain English\n- **Automatic chart generation:** Visualizations are automatically saved as PNG files\n- **File handling:** Upload datasets and process results within the sandbox\n\n## Requirements\n\n- **Python:** Version 3.10 or higher is required\n\n> [!TIP]\n> It's recommended to use a virtual environment (`venv` or `poetry`) to isolate project dependencies.\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `OPENAI_API_KEY`: Required for OpenAI API access. Get it from [OpenAI Platform](https://platform.openai.com/api-keys)\n\nCreate a `.env` file in the project directory with these variables.\n\n## Getting Started\n\n### Setup and Run\n\n1. Create and activate a virtual environment:\n\n   ```bash\n   python3.10 -m venv venv  \n   source venv/bin/activate  # On Windows: venv\\Scripts\\activate\n   ```\n\n2. Install dependencies:\n\n   ```bash\n   pip install -e .\n   ```\n\n3. Run the example:\n\n   ```bash\n   python ai_data_analyst.py\n   ```\n\n## How It Works\n\n1. An LLM call generates Python code based on the data format and prompt\n2. A new Daytona sandbox is created, containing the data file\n3. The Python code is executed in the sandbox\n4. Any generated charts are saved as PNG files\n5. A second LLM call summarizes the code execution results\n\n## Configuration\n\n### Analysis Customization\n\nThe main prompt is configured in the `user_prompt` variable in `ai_data_analyst.py`:\n\n```typescript\nconst userPrompt = `Give the three highest revenue products for the month of January and show them as a bar chart.`;\n```\n\nYou can modify this to analyze different aspects of the data or try different visualization types.\n\nThe example uses `cafe_sales_data.csv`. To use your own dataset, replace this file and update the filename in the script if needed.\n\n### OpenAI Model Configuration\n\nBy default, the example uses the following models, as specified in `ai_data_analyst.py`:\n\n```python\nCODING_MODEL = \"gpt-5.1\"\nSUMMARY_MODEL = \"gpt-4o\"\n```\n\nThe coding model is used for high accuracy code generation, and the summary model is used for fast summarization.\n\nSee [Models](https://platform.openai.com/docs/models) for all supported models\n\n## Example Output\n\nWhen the script completes, you'll see output similar to:\n\n```\nPrompt: Give the three highest revenue products for the month of January and show them as a bar chart.\nGenerating code...\nRunning code...\n✓ Chart saved to chart-0.png\nResponse: Great! It looks like you successfully executed the code and identified the top three revenue-generating products for January:\n\n1. **Matcha Espresso Fusion** with a total revenue of \\$2,603.81.\n2. **Oat Milk Latte** with a total revenue of \\$2,548.65.\n3. **Nitro Cold Brew** with a total revenue of \\$2,242.41.\n```\n\nThe chart will be saved as `chart-0.png` in your project directory, showing a bar chart of the top three revenue-generating products for January.\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [OpenAI API Documentation](https://platform.openai.com/docs/api-reference)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/python/ai-data-analyst/openai/ai_data_analyst.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport base64\nimport re\nfrom pathlib import Path\n\nfrom openai import OpenAI\n\n# pylint: disable=import-error\nfrom daytona import CreateSandboxFromSnapshotParams, Daytona\n\nCODING_MODEL = \"gpt-5.1\"\nSUMMARY_MODEL = \"gpt-4o\"\n\n\n# Helper function to extract Python code from a given string\ndef extract_python(text: str) -> str:\n    match = re.search(r\"```python([\\s\\S]*?)```\", text)\n    return match.group(1).strip() if match else \"\"\n\n\n# Make sure you have the DAYTONA_API_KEY and OPENAI_API_KEY environment variables set\ndef main() -> None:\n    daytona = Daytona()\n    sandbox = None\n\n    try:\n        # Create a Python sandbox\n        sandbox = daytona.create(CreateSandboxFromSnapshotParams(language=\"python\"))\n\n        csv_path = \"cafe_sales_data.csv\"\n        sandbox_csv_path = csv_path\n\n        # Upload the CSV file to the sandbox\n        sandbox.fs.upload_file(str(csv_path), sandbox_csv_path)\n\n        # Generate the system prompt with the first few rows of data for context\n        with Path(csv_path).open(\"r\", encoding=\"utf-8\") as f:\n            csv_sample = \"\".join(f.readlines()[:3]).strip()\n\n        # Define the user prompt\n        user_prompt = \"Give the three highest revenue products for the month of January and show them as a bar chart.\"\n        print(\"Prompt:\", user_prompt)\n\n        system_prompt = (\n            \"\\nYou are a helpful assistant that analyzes data.\\n\"\n            \"To run Python code in a sandbox, output a single block of code.\\n\"\n            f\"The sandbox:\\n - has pandas and numpy installed.\\n - contains {sandbox_csv_path}.\"\n            \"Plot any charts that you create.\"\n            f\"The first few rows of {sandbox_csv_path} are:\\n\"\n            f\"{csv_sample}\\n\"\n            \"After seeing the results of the code, answer the user's query.\"\n        )\n\n        # Generate the Python code with the LLM\n        print(\"Generating code...\")\n        client = OpenAI()\n        messages = [\n            {\"role\": \"system\", \"content\": system_prompt},\n            {\"role\": \"user\", \"content\": user_prompt},\n        ]\n\n        completion = client.chat.completions.create(\n            model=CODING_MODEL,\n            messages=messages,\n        )\n\n        first_message = completion.choices[0].message\n        messages.append({\"role\": first_message.role, \"content\": first_message.content})\n\n        # Extract and execute Python code from the LLM's response\n        print(\"Running code...\")\n        code = extract_python(first_message.content or \"\")\n        exec_result = sandbox.process.code_run(code)\n\n        artifacts = getattr(exec_result, \"artifacts\", None)\n        charts = getattr(artifacts, \"charts\", None) if artifacts is not None else None\n        if charts:\n            for index, chart in enumerate(charts):\n                png_data = chart.get(\"png\") if isinstance(chart, dict) else getattr(chart, \"png\", None)\n                if png_data:\n                    filename = f\"chart-{index}.png\"\n                    Path(filename).write_bytes(base64.b64decode(png_data))\n                    print(f\"✓ Chart saved to {filename}\")\n\n        messages.append(\n            {\n                \"role\": \"user\",\n                \"content\": f\"Code execution result:\\n{exec_result.result}.\",\n            }\n        )\n\n        # Generate the final response with the LLM\n        summary = client.chat.completions.create(\n            model=SUMMARY_MODEL,\n            messages=messages,\n        )\n\n        print(\"Response:\", summary.choices[0].message.content)\n\n    finally:\n        if sandbox is not None:\n            daytona.delete(sandbox)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "guides/python/ai-data-analyst/openai/cafe_sales_data.csv",
    "content": "date,item,quantity,unit_price,revenue,time\n2024-01-01,Single-Origin Pour Over,20,5.44,108.78,08:00:00\n2024-01-01,Oat Milk Latte,14,6.08,85.15,08:00:36\n2024-01-01,Honey Lavender Latte,10,6.28,62.83,08:01:12\n2024-01-01,Turmeric Ginger Latte,10,6.29,62.87,08:01:49\n2024-01-01,Cold Brew Concentrate,11,5.92,65.14,08:02:25\n2024-01-01,Nitro Cold Brew,9,6.18,55.63,08:03:02\n2024-01-01,Matcha Espresso Fusion,16,6.52,104.25,08:03:38\n2024-01-01,Blue Pea Flower Tea,20,4.61,92.27,08:04:14\n2024-01-01,Sourdough Toast,9,5.93,53.41,08:04:51\n2024-01-01,Almond Butter Croissant,4,5.45,21.8,08:05:27\n2024-01-01,Vegan Morning Bun,6,5.85,35.12,08:06:04\n2024-01-02,Single-Origin Pour Over,10,5.76,57.57,08:06:40\n2024-01-02,Oat Milk Latte,6,6.0,36.01,08:07:16\n2024-01-02,Honey Lavender Latte,8,6.86,54.87,08:07:53\n2024-01-02,Turmeric Ginger Latte,8,6.42,51.4,08:08:29\n2024-01-02,Cold Brew Concentrate,10,5.86,58.63,08:09:06\n2024-01-02,Nitro Cold Brew,5,6.26,31.32,08:09:42\n2024-01-02,Matcha Espresso Fusion,8,6.8,54.44,08:10:18\n2024-01-02,Blue Pea Flower Tea,7,4.55,31.83,08:10:55\n2024-01-02,Sourdough Toast,6,6.31,37.86,08:11:31\n2024-01-02,Almond Butter Croissant,3,5.18,15.54,08:12:08\n2024-01-02,Vegan Morning Bun,15,5.8,86.93,08:12:44\n2024-01-03,Single-Origin Pour Over,9,5.58,50.26,08:13:20\n2024-01-03,Oat Milk Latte,9,5.81,52.26,08:13:57\n2024-01-03,Honey Lavender Latte,1,6.71,6.71,08:14:33\n2024-01-03,Turmeric Ginger Latte,10,6.49,64.85,08:15:10\n2024-01-03,Cold Brew Concentrate,17,5.74,97.63,08:15:46\n2024-01-03,Nitro Cold Brew,17,6.43,109.38,08:16:22\n2024-01-03,Matcha Espresso Fusion,16,6.71,107.39,08:16:59\n2024-01-03,Blue Pea Flower Tea,2,4.54,9.08,08:17:35\n2024-01-03,Sourdough Toast,17,6.22,105.75,08:18:12\n2024-01-03,Almond Butter Croissant,18,5.31,95.56,08:18:48\n2024-01-03,Vegan Morning Bun,8,5.55,44.38,08:19:24\n2024-01-04,Single-Origin Pour Over,12,5.38,64.55,08:20:01\n2024-01-04,Oat Milk Latte,12,5.87,70.46,08:20:37\n2024-01-04,Honey Lavender Latte,6,6.87,41.21,08:21:14\n2024-01-04,Turmeric Ginger Latte,14,6.46,90.44,08:21:50\n2024-01-04,Cold Brew Concentrate,21,5.67,119.1,08:22:26\n2024-01-04,Nitro Cold Brew,11,6.55,72.02,08:23:03\n2024-01-04,Matcha Espresso Fusion,20,6.98,139.68,08:23:39\n2024-01-04,Blue Pea Flower Tea,15,4.66,69.93,08:24:16\n2024-01-04,Sourdough Toast,13,5.99,77.84,08:24:52\n2024-01-04,Almond Butter Croissant,5,5.12,25.62,08:25:28\n2024-01-04,Vegan Morning Bun,13,5.97,77.63,08:26:05\n2024-01-05,Single-Origin Pour Over,12,5.31,63.7,08:26:41\n2024-01-05,Oat Milk Latte,17,6.07,103.15,08:27:18\n2024-01-05,Honey Lavender Latte,1,6.39,6.39,08:27:54\n2024-01-05,Turmeric Ginger Latte,7,6.12,42.81,08:28:30\n2024-01-05,Cold Brew Concentrate,7,5.77,40.38,08:29:07\n2024-01-05,Nitro Cold Brew,13,6.03,78.41,08:29:43\n2024-01-05,Matcha Espresso Fusion,15,6.92,103.85,08:30:20\n2024-01-05,Blue Pea Flower Tea,7,4.56,31.93,08:30:56\n2024-01-05,Sourdough Toast,16,6.37,101.95,08:31:32\n2024-01-05,Almond Butter Croissant,5,5.28,26.42,08:32:09\n2024-01-05,Vegan Morning Bun,18,5.61,100.99,08:32:45\n2024-01-06,Single-Origin Pour Over,12,5.42,65.03,08:33:22\n2024-01-06,Oat Milk Latte,15,5.97,89.57,08:33:58\n2024-01-06,Honey Lavender Latte,13,6.29,81.8,08:34:34\n2024-01-06,Turmeric Ginger Latte,9,6.48,58.34,08:35:11\n2024-01-06,Cold Brew Concentrate,15,5.6,84.04,08:35:47\n2024-01-06,Nitro Cold Brew,16,6.47,103.56,08:36:24\n2024-01-06,Matcha Espresso Fusion,14,6.73,94.27,08:37:00\n2024-01-06,Blue Pea Flower Tea,8,4.45,35.63,08:37:36\n2024-01-06,Sourdough Toast,14,6.02,84.32,08:38:13\n2024-01-06,Almond Butter Croissant,13,5.63,73.21,08:38:49\n2024-01-06,Vegan Morning Bun,13,5.74,74.61,08:39:26\n2024-01-07,Single-Origin Pour Over,8,5.79,46.3,08:40:02\n2024-01-07,Oat Milk Latte,8,6.38,51.02,08:40:38\n2024-01-07,Honey Lavender Latte,11,6.44,70.8,08:41:15\n2024-01-07,Turmeric Ginger Latte,21,6.54,137.38,08:41:51\n2024-01-07,Cold Brew Concentrate,14,6.05,84.72,08:42:28\n2024-01-07,Nitro Cold Brew,9,6.2,55.84,08:43:04\n2024-01-07,Matcha Espresso Fusion,9,6.85,61.66,08:43:40\n2024-01-07,Blue Pea Flower Tea,3,4.31,12.94,08:44:17\n2024-01-07,Sourdough Toast,12,6.25,75.04,08:44:53\n2024-01-07,Almond Butter Croissant,18,5.15,92.7,08:45:30\n2024-01-07,Vegan Morning Bun,14,5.96,83.37,08:46:06\n2024-01-08,Single-Origin Pour Over,11,5.8,63.76,08:46:42\n2024-01-08,Oat Milk Latte,7,6.09,42.6,08:47:19\n2024-01-08,Honey Lavender Latte,17,6.35,107.98,08:47:55\n2024-01-08,Turmeric Ginger Latte,12,6.54,78.47,08:48:32\n2024-01-08,Cold Brew Concentrate,14,5.55,77.67,08:49:08\n2024-01-08,Nitro Cold Brew,8,6.57,52.6,08:49:44\n2024-01-08,Matcha Espresso Fusion,11,6.79,74.69,08:50:21\n2024-01-08,Blue Pea Flower Tea,8,4.37,34.96,08:50:57\n2024-01-08,Sourdough Toast,12,6.03,72.4,08:51:34\n2024-01-08,Almond Butter Croissant,25,5.4,135.08,08:52:10\n2024-01-08,Vegan Morning Bun,11,5.74,63.17,08:52:46\n2024-01-09,Single-Origin Pour Over,6,5.43,32.57,08:53:23\n2024-01-09,Oat Milk Latte,13,6.27,81.5,08:53:59\n2024-01-09,Honey Lavender Latte,9,6.41,57.67,08:54:36\n2024-01-09,Turmeric Ginger Latte,9,6.31,56.81,08:55:12\n2024-01-09,Cold Brew Concentrate,5,5.94,29.71,08:55:48\n2024-01-09,Nitro Cold Brew,11,6.52,71.69,08:56:25\n2024-01-09,Matcha Espresso Fusion,20,6.75,135.08,08:57:01\n2024-01-09,Blue Pea Flower Tea,15,4.28,64.2,08:57:38\n2024-01-09,Sourdough Toast,1,6.14,6.14,08:58:14\n2024-01-09,Almond Butter Croissant,7,5.09,35.61,08:58:50\n2024-01-09,Vegan Morning Bun,15,5.67,85.08,08:59:27\n2024-01-10,Single-Origin Pour Over,9,5.52,49.65,09:00:03\n2024-01-10,Oat Milk Latte,11,5.84,64.29,09:00:40\n2024-01-10,Honey Lavender Latte,13,6.71,87.18,09:01:16\n2024-01-10,Turmeric Ginger Latte,21,6.03,126.57,09:01:52\n2024-01-10,Cold Brew Concentrate,17,5.77,98.11,09:02:29\n2024-01-10,Nitro Cold Brew,10,6.19,61.92,09:03:05\n2024-01-10,Matcha Espresso Fusion,12,7.14,85.71,09:03:42\n2024-01-10,Blue Pea Flower Tea,11,4.73,52.01,09:04:18\n2024-01-10,Sourdough Toast,14,6.16,86.26,09:04:54\n2024-01-10,Almond Butter Croissant,17,5.11,86.91,09:05:31\n2024-01-10,Vegan Morning Bun,11,6.04,66.42,09:06:07\n2024-01-11,Single-Origin Pour Over,9,5.69,51.18,09:06:44\n2024-01-11,Oat Milk Latte,21,6.05,127.03,09:07:20\n2024-01-11,Honey Lavender Latte,10,6.58,65.8,09:07:56\n2024-01-11,Turmeric Ginger Latte,13,6.57,85.36,09:08:33\n2024-01-11,Cold Brew Concentrate,13,5.72,74.42,09:09:09\n2024-01-11,Nitro Cold Brew,10,6.04,60.37,09:09:46\n2024-01-11,Matcha Espresso Fusion,8,6.98,55.82,09:10:22\n2024-01-11,Blue Pea Flower Tea,20,4.56,91.2,09:10:58\n2024-01-11,Sourdough Toast,1,5.94,5.94,09:11:35\n2024-01-11,Almond Butter Croissant,12,5.59,67.03,09:12:11\n2024-01-11,Vegan Morning Bun,17,6.08,103.4,09:12:48\n2024-01-12,Single-Origin Pour Over,15,5.41,81.19,09:13:24\n2024-01-12,Oat Milk Latte,26,5.82,151.44,09:14:00\n2024-01-12,Honey Lavender Latte,13,6.75,87.69,09:14:37\n2024-01-12,Turmeric Ginger Latte,12,6.08,72.99,09:15:13\n2024-01-12,Cold Brew Concentrate,5,5.55,27.74,09:15:50\n2024-01-12,Nitro Cold Brew,11,6.44,70.82,09:16:26\n2024-01-12,Matcha Espresso Fusion,24,7.01,168.34,09:17:02\n2024-01-12,Blue Pea Flower Tea,17,4.67,79.44,09:17:39\n2024-01-12,Sourdough Toast,21,6.1,128.16,09:18:15\n2024-01-12,Almond Butter Croissant,17,5.29,89.99,09:18:52\n2024-01-12,Vegan Morning Bun,12,5.85,70.17,09:19:28\n2024-01-13,Single-Origin Pour Over,9,5.53,49.78,09:20:04\n2024-01-13,Oat Milk Latte,13,5.82,75.61,09:20:41\n2024-01-13,Honey Lavender Latte,8,6.59,52.68,09:21:17\n2024-01-13,Turmeric Ginger Latte,8,6.37,50.97,09:21:54\n2024-01-13,Cold Brew Concentrate,11,6.08,66.87,09:22:30\n2024-01-13,Nitro Cold Brew,18,6.26,112.62,09:23:06\n2024-01-13,Matcha Espresso Fusion,13,6.91,89.77,09:23:43\n2024-01-13,Blue Pea Flower Tea,20,4.43,88.52,09:24:19\n2024-01-13,Sourdough Toast,12,6.4,76.77,09:24:56\n2024-01-13,Almond Butter Croissant,6,5.03,30.19,09:25:32\n2024-01-13,Vegan Morning Bun,17,5.53,93.93,09:26:08\n2024-01-14,Single-Origin Pour Over,7,5.74,40.15,09:26:45\n2024-01-14,Oat Milk Latte,20,6.11,122.16,09:27:21\n2024-01-14,Honey Lavender Latte,14,6.86,96.05,09:27:58\n2024-01-14,Turmeric Ginger Latte,16,6.03,96.53,09:28:34\n2024-01-14,Cold Brew Concentrate,2,5.86,11.72,09:29:10\n2024-01-14,Nitro Cold Brew,13,6.61,85.99,09:29:47\n2024-01-14,Matcha Espresso Fusion,11,6.59,72.49,09:30:23\n2024-01-14,Blue Pea Flower Tea,15,4.6,69.05,09:31:00\n2024-01-14,Sourdough Toast,7,6.1,42.68,09:31:36\n2024-01-14,Almond Butter Croissant,10,5.26,52.55,09:32:12\n2024-01-14,Vegan Morning Bun,11,6.15,67.64,09:32:49\n2024-01-15,Single-Origin Pour Over,13,5.38,69.91,09:33:25\n2024-01-15,Oat Milk Latte,18,6.35,114.27,09:34:02\n2024-01-15,Honey Lavender Latte,21,6.38,134.02,09:34:38\n2024-01-15,Turmeric Ginger Latte,5,6.21,31.07,09:35:14\n2024-01-15,Cold Brew Concentrate,6,5.51,33.09,09:35:51\n2024-01-15,Nitro Cold Brew,3,6.43,19.29,09:36:27\n2024-01-15,Matcha Espresso Fusion,13,6.9,89.74,09:37:04\n2024-01-15,Blue Pea Flower Tea,6,4.7,28.22,09:37:40\n2024-01-15,Sourdough Toast,6,6.24,37.45,09:38:16\n2024-01-15,Almond Butter Croissant,6,5.25,31.51,09:38:53\n2024-01-15,Vegan Morning Bun,7,6.14,42.95,09:39:29\n2024-01-16,Single-Origin Pour Over,4,5.53,22.14,09:40:06\n2024-01-16,Oat Milk Latte,8,6.34,50.75,09:40:42\n2024-01-16,Honey Lavender Latte,20,6.72,134.35,09:41:18\n2024-01-16,Turmeric Ginger Latte,7,6.24,43.65,09:41:55\n2024-01-16,Cold Brew Concentrate,11,5.82,64.01,09:42:31\n2024-01-16,Nitro Cold Brew,13,6.14,79.77,09:43:08\n2024-01-16,Matcha Espresso Fusion,3,6.82,20.46,09:43:44\n2024-01-16,Blue Pea Flower Tea,22,4.73,104.16,09:44:20\n2024-01-16,Sourdough Toast,13,6.22,80.92,09:44:57\n2024-01-16,Almond Butter Croissant,5,5.57,27.84,09:45:33\n2024-01-16,Vegan Morning Bun,1,5.74,5.74,09:46:10\n2024-01-17,Single-Origin Pour Over,12,5.45,65.38,09:46:46\n2024-01-17,Oat Milk Latte,15,6.15,92.32,09:47:22\n2024-01-17,Honey Lavender Latte,13,6.47,84.14,09:47:59\n2024-01-17,Turmeric Ginger Latte,21,6.3,132.22,09:48:35\n2024-01-17,Cold Brew Concentrate,10,5.59,55.94,09:49:12\n2024-01-17,Nitro Cold Brew,9,6.43,57.9,09:49:48\n2024-01-17,Matcha Espresso Fusion,12,6.54,78.48,09:50:24\n2024-01-17,Blue Pea Flower Tea,1,4.37,4.37,09:51:01\n2024-01-17,Sourdough Toast,16,6.3,100.88,09:51:37\n2024-01-17,Almond Butter Croissant,19,5.63,106.89,09:52:14\n2024-01-17,Vegan Morning Bun,18,5.79,104.24,09:52:50\n2024-01-18,Single-Origin Pour Over,4,5.58,22.31,09:53:26\n2024-01-18,Oat Milk Latte,13,6.16,80.02,09:54:03\n2024-01-18,Honey Lavender Latte,11,6.34,69.76,09:54:39\n2024-01-18,Turmeric Ginger Latte,12,6.01,72.11,09:55:16\n2024-01-18,Cold Brew Concentrate,16,6.02,96.38,09:55:52\n2024-01-18,Nitro Cold Brew,12,6.28,75.35,09:56:28\n2024-01-18,Matcha Espresso Fusion,13,6.75,87.72,09:57:05\n2024-01-18,Blue Pea Flower Tea,9,4.76,42.84,09:57:41\n2024-01-18,Sourdough Toast,13,6.07,78.96,09:58:18\n2024-01-18,Almond Butter Croissant,7,5.11,35.79,09:58:54\n2024-01-18,Vegan Morning Bun,10,6.06,60.59,09:59:30\n2024-01-19,Single-Origin Pour Over,14,5.77,80.82,10:00:07\n2024-01-19,Oat Milk Latte,9,5.81,52.26,10:00:43\n2024-01-19,Honey Lavender Latte,19,6.57,124.8,10:01:20\n2024-01-19,Turmeric Ginger Latte,10,6.56,65.63,10:01:56\n2024-01-19,Cold Brew Concentrate,19,5.64,107.14,10:02:32\n2024-01-19,Nitro Cold Brew,5,6.55,32.74,10:03:09\n2024-01-19,Matcha Espresso Fusion,13,6.71,87.23,10:03:45\n2024-01-19,Blue Pea Flower Tea,17,4.48,76.09,10:04:22\n2024-01-19,Sourdough Toast,7,6.08,42.57,10:04:58\n2024-01-19,Almond Butter Croissant,13,5.19,67.5,10:05:34\n2024-01-19,Vegan Morning Bun,5,6.04,30.21,10:06:11\n2024-01-20,Single-Origin Pour Over,6,5.36,32.18,10:06:47\n2024-01-20,Oat Milk Latte,8,5.76,46.08,10:07:24\n2024-01-20,Honey Lavender Latte,9,6.53,58.74,10:08:00\n2024-01-20,Turmeric Ginger Latte,1,6.56,6.56,10:08:36\n2024-01-20,Cold Brew Concentrate,9,5.84,52.59,10:09:13\n2024-01-20,Nitro Cold Brew,22,6.05,133.14,10:09:49\n2024-01-20,Matcha Espresso Fusion,15,7.05,105.68,10:10:26\n2024-01-20,Blue Pea Flower Tea,12,4.85,58.22,10:11:02\n2024-01-20,Sourdough Toast,7,6.11,42.75,10:11:38\n2024-01-20,Almond Butter Croissant,18,5.59,100.54,10:12:15\n2024-01-20,Vegan Morning Bun,7,5.9,41.3,10:12:51\n2024-01-21,Single-Origin Pour Over,21,5.36,112.65,10:13:28\n2024-01-21,Oat Milk Latte,13,5.91,76.82,10:14:04\n2024-01-21,Honey Lavender Latte,10,6.74,67.38,10:14:40\n2024-01-21,Turmeric Ginger Latte,8,6.45,51.61,10:15:17\n2024-01-21,Cold Brew Concentrate,15,6.02,90.24,10:15:53\n2024-01-21,Nitro Cold Brew,17,6.1,103.65,10:16:30\n2024-01-21,Matcha Espresso Fusion,10,6.82,68.2,10:17:06\n2024-01-21,Blue Pea Flower Tea,12,4.8,57.58,10:17:42\n2024-01-21,Sourdough Toast,2,5.93,11.86,10:18:19\n2024-01-21,Almond Butter Croissant,10,5.26,52.56,10:18:55\n2024-01-21,Vegan Morning Bun,8,5.78,46.26,10:19:32\n2024-01-22,Single-Origin Pour Over,16,5.72,91.52,10:20:08\n2024-01-22,Oat Milk Latte,17,6.07,103.14,10:20:44\n2024-01-22,Honey Lavender Latte,17,6.34,107.83,10:21:21\n2024-01-22,Turmeric Ginger Latte,11,6.53,71.8,10:21:57\n2024-01-22,Cold Brew Concentrate,12,5.5,66.06,10:22:34\n2024-01-22,Nitro Cold Brew,4,6.45,25.81,10:23:10\n2024-01-22,Matcha Espresso Fusion,10,6.93,69.31,10:23:46\n2024-01-22,Blue Pea Flower Tea,21,4.89,102.6,10:24:23\n2024-01-22,Sourdough Toast,10,5.81,58.11,10:24:59\n2024-01-22,Almond Butter Croissant,21,5.41,113.64,10:25:36\n2024-01-22,Vegan Morning Bun,15,5.67,85.06,10:26:12\n2024-01-23,Single-Origin Pour Over,10,5.8,57.99,10:26:48\n2024-01-23,Oat Milk Latte,14,6.06,84.78,10:27:25\n2024-01-23,Honey Lavender Latte,13,6.3,81.91,10:28:01\n2024-01-23,Turmeric Ginger Latte,10,6.52,65.17,10:28:38\n2024-01-23,Cold Brew Concentrate,16,6.02,96.35,10:29:14\n2024-01-23,Nitro Cold Brew,13,6.26,81.4,10:29:50\n2024-01-23,Matcha Espresso Fusion,9,6.5,58.51,10:30:27\n2024-01-23,Blue Pea Flower Tea,8,4.67,37.4,10:31:03\n2024-01-23,Sourdough Toast,9,6.2,55.77,10:31:40\n2024-01-23,Almond Butter Croissant,4,5.29,21.16,10:32:16\n2024-01-23,Vegan Morning Bun,7,5.72,40.04,10:32:52\n2024-01-24,Single-Origin Pour Over,12,5.38,64.61,10:33:29\n2024-01-24,Oat Milk Latte,19,6.08,115.48,10:34:05\n2024-01-24,Honey Lavender Latte,16,6.28,100.46,10:34:42\n2024-01-24,Turmeric Ginger Latte,7,6.17,43.22,10:35:18\n2024-01-24,Cold Brew Concentrate,8,5.67,45.37,10:35:54\n2024-01-24,Nitro Cold Brew,13,6.23,80.93,10:36:31\n2024-01-24,Matcha Espresso Fusion,14,7.11,99.57,10:37:07\n2024-01-24,Blue Pea Flower Tea,5,4.72,23.62,10:37:44\n2024-01-24,Sourdough Toast,11,5.92,65.1,10:38:20\n2024-01-24,Almond Butter Croissant,14,5.19,72.64,10:38:56\n2024-01-24,Vegan Morning Bun,15,5.8,86.98,10:39:33\n2024-01-25,Single-Origin Pour Over,16,5.59,89.48,10:40:09\n2024-01-25,Oat Milk Latte,18,5.89,106.01,10:40:46\n2024-01-25,Honey Lavender Latte,17,6.55,111.3,10:41:22\n2024-01-25,Turmeric Ginger Latte,6,6.47,38.8,10:41:58\n2024-01-25,Cold Brew Concentrate,6,5.56,33.39,10:42:35\n2024-01-25,Nitro Cold Brew,18,6.44,115.97,10:43:11\n2024-01-25,Matcha Espresso Fusion,16,6.58,105.3,10:43:48\n2024-01-25,Blue Pea Flower Tea,2,4.34,8.69,10:44:24\n2024-01-25,Sourdough Toast,21,5.83,122.35,10:45:00\n2024-01-25,Almond Butter Croissant,7,5.5,38.52,10:45:37\n2024-01-25,Vegan Morning Bun,14,5.99,83.82,10:46:13\n2024-01-26,Single-Origin Pour Over,16,5.41,86.48,10:46:50\n2024-01-26,Oat Milk Latte,10,5.83,58.32,10:47:26\n2024-01-26,Honey Lavender Latte,8,6.52,52.17,10:48:02\n2024-01-26,Turmeric Ginger Latte,8,6.56,52.45,10:48:39\n2024-01-26,Cold Brew Concentrate,16,5.79,92.71,10:49:15\n2024-01-26,Nitro Cold Brew,14,6.29,87.99,10:49:52\n2024-01-26,Matcha Espresso Fusion,6,6.71,40.29,10:50:28\n2024-01-26,Blue Pea Flower Tea,13,4.74,61.6,10:51:04\n2024-01-26,Sourdough Toast,12,5.94,71.29,10:51:41\n2024-01-26,Almond Butter Croissant,3,5.64,16.92,10:52:17\n2024-01-26,Vegan Morning Bun,5,5.5,27.51,10:52:54\n2024-01-27,Single-Origin Pour Over,12,5.35,64.22,10:53:30\n2024-01-27,Oat Milk Latte,22,6.17,135.68,10:54:06\n2024-01-27,Honey Lavender Latte,14,6.3,88.21,10:54:43\n2024-01-27,Turmeric Ginger Latte,15,6.52,97.75,10:55:19\n2024-01-27,Cold Brew Concentrate,16,5.87,93.85,10:55:56\n2024-01-27,Nitro Cold Brew,9,6.05,54.47,10:56:32\n2024-01-27,Matcha Espresso Fusion,14,6.79,95.11,10:57:08\n2024-01-27,Blue Pea Flower Tea,19,4.66,88.63,10:57:45\n2024-01-27,Sourdough Toast,9,6.34,57.09,10:58:21\n2024-01-27,Almond Butter Croissant,11,5.19,57.06,10:58:58\n2024-01-27,Vegan Morning Bun,14,5.8,81.21,10:59:34\n2024-01-28,Single-Origin Pour Over,13,5.78,75.13,11:00:10\n2024-01-28,Oat Milk Latte,6,5.94,35.64,11:00:47\n2024-01-28,Honey Lavender Latte,4,6.44,25.77,11:01:23\n2024-01-28,Turmeric Ginger Latte,2,6.04,12.09,11:02:00\n2024-01-28,Cold Brew Concentrate,15,5.95,89.23,11:02:36\n2024-01-28,Nitro Cold Brew,7,6.12,42.85,11:03:12\n2024-01-28,Matcha Espresso Fusion,4,6.53,26.13,11:03:49\n2024-01-28,Blue Pea Flower Tea,7,4.86,33.99,11:04:25\n2024-01-28,Sourdough Toast,21,5.76,121.01,11:05:02\n2024-01-28,Almond Butter Croissant,1,5.21,5.21,11:05:38\n2024-01-28,Vegan Morning Bun,12,6.13,73.6,11:06:14\n2024-01-29,Single-Origin Pour Over,15,5.83,87.42,11:06:51\n2024-01-29,Oat Milk Latte,12,5.97,71.65,11:07:27\n2024-01-29,Honey Lavender Latte,6,6.49,38.93,11:08:04\n2024-01-29,Turmeric Ginger Latte,14,6.45,90.23,11:08:40\n2024-01-29,Cold Brew Concentrate,7,5.55,38.86,11:09:16\n2024-01-29,Nitro Cold Brew,12,6.5,78.01,11:09:53\n2024-01-29,Matcha Espresso Fusion,16,6.64,106.3,11:10:29\n2024-01-29,Blue Pea Flower Tea,18,4.76,85.67,11:11:06\n2024-01-29,Sourdough Toast,6,5.86,35.15,11:11:42\n2024-01-29,Almond Butter Croissant,13,5.4,70.25,11:12:18\n2024-01-29,Vegan Morning Bun,12,5.69,68.3,11:12:55\n2024-01-30,Single-Origin Pour Over,13,5.72,74.3,11:13:31\n2024-01-30,Oat Milk Latte,14,6.02,84.27,11:14:08\n2024-01-30,Honey Lavender Latte,6,6.27,37.62,11:14:44\n2024-01-30,Turmeric Ginger Latte,19,6.59,125.26,11:15:20\n2024-01-30,Cold Brew Concentrate,28,5.96,166.94,11:15:57\n2024-01-30,Nitro Cold Brew,17,6.16,104.76,11:16:33\n2024-01-30,Matcha Espresso Fusion,5,6.93,34.63,11:17:10\n2024-01-30,Blue Pea Flower Tea,20,4.35,87.09,11:17:46\n2024-01-30,Sourdough Toast,19,6.21,118.03,11:18:22\n2024-01-30,Almond Butter Croissant,20,5.03,100.58,11:18:59\n2024-01-30,Vegan Morning Bun,13,5.98,77.69,11:19:35\n2024-01-31,Single-Origin Pour Over,12,5.34,64.09,11:20:12\n2024-01-31,Oat Milk Latte,14,6.35,88.91,11:20:48\n2024-01-31,Honey Lavender Latte,3,6.65,19.96,11:21:24\n2024-01-31,Turmeric Ginger Latte,14,6.56,91.82,11:22:01\n2024-01-31,Cold Brew Concentrate,12,5.91,70.94,11:22:37\n2024-01-31,Nitro Cold Brew,7,6.6,46.21,11:23:14\n2024-01-31,Matcha Espresso Fusion,12,6.98,83.71,11:23:50\n2024-01-31,Blue Pea Flower Tea,9,4.68,42.11,11:24:26\n2024-01-31,Sourdough Toast,13,6.16,80.09,11:25:03\n2024-01-31,Almond Butter Croissant,16,5.4,86.34,11:25:39\n2024-01-31,Vegan Morning Bun,13,5.84,75.86,11:26:16\n2024-02-01,Single-Origin Pour Over,10,5.26,52.64,11:26:52\n2024-02-01,Oat Milk Latte,14,6.18,86.48,11:27:28\n2024-02-01,Honey Lavender Latte,16,6.28,100.54,11:28:05\n2024-02-01,Turmeric Ginger Latte,7,6.53,45.71,11:28:41\n2024-02-01,Cold Brew Concentrate,18,5.6,100.83,11:29:18\n2024-02-01,Nitro Cold Brew,8,6.01,48.1,11:29:54\n2024-02-01,Matcha Espresso Fusion,10,6.71,67.1,11:30:30\n2024-02-01,Blue Pea Flower Tea,8,4.44,35.55,11:31:07\n2024-02-01,Sourdough Toast,20,6.36,127.17,11:31:43\n2024-02-01,Almond Butter Croissant,7,5.63,39.41,11:32:20\n2024-02-01,Vegan Morning Bun,8,5.55,44.41,11:32:56\n2024-02-02,Single-Origin Pour Over,14,5.49,76.86,11:33:32\n2024-02-02,Oat Milk Latte,20,5.94,118.84,11:34:09\n2024-02-02,Honey Lavender Latte,11,6.58,72.35,11:34:45\n2024-02-02,Turmeric Ginger Latte,8,6.16,49.29,11:35:22\n2024-02-02,Cold Brew Concentrate,15,6.07,91.11,11:35:58\n2024-02-02,Nitro Cold Brew,4,6.38,25.52,11:36:34\n2024-02-02,Matcha Espresso Fusion,16,6.84,109.5,11:37:11\n2024-02-02,Blue Pea Flower Tea,9,4.65,41.87,11:37:47\n2024-02-02,Sourdough Toast,7,6.2,43.37,11:38:24\n2024-02-02,Almond Butter Croissant,16,5.17,82.77,11:39:00\n2024-02-02,Vegan Morning Bun,5,6.02,30.09,11:39:36\n2024-02-03,Single-Origin Pour Over,15,5.48,82.14,11:40:13\n2024-02-03,Oat Milk Latte,15,6.32,94.74,11:40:49\n2024-02-03,Honey Lavender Latte,14,6.59,92.23,11:41:26\n2024-02-03,Turmeric Ginger Latte,2,6.56,13.11,11:42:02\n2024-02-03,Cold Brew Concentrate,14,6.0,83.94,11:42:38\n2024-02-03,Nitro Cold Brew,16,6.6,105.56,11:43:15\n2024-02-03,Matcha Espresso Fusion,30,6.86,205.94,11:43:51\n2024-02-03,Blue Pea Flower Tea,12,4.61,55.34,11:44:28\n2024-02-03,Sourdough Toast,19,6.03,114.6,11:45:04\n2024-02-03,Almond Butter Croissant,8,5.29,42.29,11:45:40\n2024-02-03,Vegan Morning Bun,1,5.59,5.59,11:46:17\n2024-02-04,Single-Origin Pour Over,12,5.56,66.76,11:46:53\n2024-02-04,Oat Milk Latte,11,6.35,69.85,11:47:30\n2024-02-04,Honey Lavender Latte,11,6.79,74.68,11:48:06\n2024-02-04,Turmeric Ginger Latte,1,6.43,6.43,11:48:42\n2024-02-04,Cold Brew Concentrate,9,5.91,53.15,11:49:19\n2024-02-04,Nitro Cold Brew,2,6.26,12.52,11:49:55\n2024-02-04,Matcha Espresso Fusion,8,6.98,55.85,11:50:32\n2024-02-04,Blue Pea Flower Tea,8,4.39,35.09,11:51:08\n2024-02-04,Sourdough Toast,9,6.39,57.54,11:51:44\n2024-02-04,Almond Butter Croissant,7,5.64,39.51,11:52:21\n2024-02-04,Vegan Morning Bun,4,5.79,23.15,11:52:57\n2024-02-05,Single-Origin Pour Over,11,5.82,64.06,11:53:34\n2024-02-05,Oat Milk Latte,16,6.32,101.16,11:54:10\n2024-02-05,Honey Lavender Latte,12,6.78,81.35,11:54:46\n2024-02-05,Turmeric Ginger Latte,12,6.11,73.32,11:55:23\n2024-02-05,Cold Brew Concentrate,17,6.01,102.11,11:55:59\n2024-02-05,Nitro Cold Brew,12,6.6,79.2,11:56:36\n2024-02-05,Matcha Espresso Fusion,11,7.1,78.11,11:57:12\n2024-02-05,Blue Pea Flower Tea,14,4.4,61.62,11:57:48\n2024-02-05,Sourdough Toast,12,6.12,73.48,11:58:25\n2024-02-05,Almond Butter Croissant,13,5.41,70.3,11:59:01\n2024-02-05,Vegan Morning Bun,18,5.76,103.59,11:59:38\n2024-02-06,Single-Origin Pour Over,13,5.63,73.19,12:00:14\n2024-02-06,Oat Milk Latte,10,5.98,59.83,12:00:50\n2024-02-06,Honey Lavender Latte,7,6.37,44.59,12:01:27\n2024-02-06,Turmeric Ginger Latte,9,6.43,57.91,12:02:03\n2024-02-06,Cold Brew Concentrate,7,6.05,42.35,12:02:40\n2024-02-06,Nitro Cold Brew,6,6.06,36.36,12:03:16\n2024-02-06,Matcha Espresso Fusion,11,7.04,77.42,12:03:52\n2024-02-06,Blue Pea Flower Tea,14,4.79,67.0,12:04:29\n2024-02-06,Sourdough Toast,10,6.18,61.76,12:05:05\n2024-02-06,Almond Butter Croissant,12,5.29,63.48,12:05:42\n2024-02-06,Vegan Morning Bun,12,5.93,71.18,12:06:18\n2024-02-07,Single-Origin Pour Over,2,5.5,11.01,12:06:54\n2024-02-07,Oat Milk Latte,5,5.86,29.29,12:07:31\n2024-02-07,Honey Lavender Latte,9,6.65,59.89,12:08:07\n2024-02-07,Turmeric Ginger Latte,17,6.49,110.26,12:08:44\n2024-02-07,Cold Brew Concentrate,20,5.71,114.15,12:09:20\n2024-02-07,Nitro Cold Brew,7,6.54,45.81,12:09:56\n2024-02-07,Matcha Espresso Fusion,7,7.05,49.36,12:10:33\n2024-02-07,Blue Pea Flower Tea,9,4.5,40.46,12:11:09\n2024-02-07,Sourdough Toast,16,5.94,95.02,12:11:46\n2024-02-07,Almond Butter Croissant,6,5.48,32.9,12:12:22\n2024-02-07,Vegan Morning Bun,15,6.02,90.23,12:12:58\n2024-02-08,Single-Origin Pour Over,5,5.42,27.1,12:13:35\n2024-02-08,Oat Milk Latte,12,6.12,73.42,12:14:11\n2024-02-08,Honey Lavender Latte,7,6.67,46.7,12:14:48\n2024-02-08,Turmeric Ginger Latte,15,6.59,98.86,12:15:24\n2024-02-08,Cold Brew Concentrate,14,6.12,85.72,12:16:00\n2024-02-08,Nitro Cold Brew,13,6.18,80.32,12:16:37\n2024-02-08,Matcha Espresso Fusion,12,6.75,81.04,12:17:13\n2024-02-08,Blue Pea Flower Tea,11,4.32,47.52,12:17:50\n2024-02-08,Sourdough Toast,9,5.87,52.87,12:18:26\n2024-02-08,Almond Butter Croissant,23,5.6,128.7,12:19:02\n2024-02-08,Vegan Morning Bun,13,5.68,73.88,12:19:39\n2024-02-09,Single-Origin Pour Over,11,5.29,58.18,12:20:15\n2024-02-09,Oat Milk Latte,10,6.35,63.5,12:20:52\n2024-02-09,Honey Lavender Latte,14,6.56,91.91,12:21:28\n2024-02-09,Turmeric Ginger Latte,8,6.17,49.38,12:22:04\n2024-02-09,Cold Brew Concentrate,13,5.94,77.24,12:22:41\n2024-02-09,Nitro Cold Brew,12,6.63,79.58,12:23:17\n2024-02-09,Matcha Espresso Fusion,13,6.65,86.51,12:23:54\n2024-02-09,Blue Pea Flower Tea,10,4.63,46.27,12:24:30\n2024-02-09,Sourdough Toast,9,5.99,53.92,12:25:06\n2024-02-09,Almond Butter Croissant,7,5.21,36.44,12:25:43\n2024-02-09,Vegan Morning Bun,5,5.87,29.34,12:26:19\n2024-02-10,Single-Origin Pour Over,16,5.5,87.95,12:26:56\n2024-02-10,Oat Milk Latte,14,6.36,89.04,12:27:32\n2024-02-10,Honey Lavender Latte,5,6.52,32.6,12:28:08\n2024-02-10,Turmeric Ginger Latte,2,6.5,12.99,12:28:45\n2024-02-10,Cold Brew Concentrate,9,5.72,51.5,12:29:21\n2024-02-10,Nitro Cold Brew,19,6.05,115.02,12:29:58\n2024-02-10,Matcha Espresso Fusion,10,6.72,67.16,12:30:34\n2024-02-10,Blue Pea Flower Tea,11,4.37,48.1,12:31:10\n2024-02-10,Sourdough Toast,18,6.07,109.22,12:31:47\n2024-02-10,Almond Butter Croissant,15,5.31,79.7,12:32:23\n2024-02-10,Vegan Morning Bun,13,6.15,79.89,12:33:00\n2024-02-11,Single-Origin Pour Over,11,5.67,62.34,12:33:36\n2024-02-11,Oat Milk Latte,10,6.13,61.32,12:34:12\n2024-02-11,Honey Lavender Latte,17,6.49,110.33,12:34:49\n2024-02-11,Turmeric Ginger Latte,12,6.58,78.97,12:35:25\n2024-02-11,Cold Brew Concentrate,14,5.9,82.62,12:36:02\n2024-02-11,Nitro Cold Brew,10,6.39,63.86,12:36:38\n2024-02-11,Matcha Espresso Fusion,9,7.1,63.86,12:37:14\n2024-02-11,Blue Pea Flower Tea,5,4.68,23.39,12:37:51\n2024-02-11,Sourdough Toast,18,6.16,110.9,12:38:27\n2024-02-11,Almond Butter Croissant,12,5.01,60.06,12:39:04\n2024-02-11,Vegan Morning Bun,13,6.14,79.84,12:39:40\n2024-02-12,Single-Origin Pour Over,10,5.88,58.77,12:40:16\n2024-02-12,Oat Milk Latte,7,6.19,43.31,12:40:53\n2024-02-12,Honey Lavender Latte,8,6.51,52.08,12:41:29\n2024-02-12,Turmeric Ginger Latte,21,6.2,130.14,12:42:06\n2024-02-12,Cold Brew Concentrate,8,5.58,44.65,12:42:42\n2024-02-12,Nitro Cold Brew,18,6.13,110.38,12:43:18\n2024-02-12,Matcha Espresso Fusion,7,6.93,48.48,12:43:55\n2024-02-12,Blue Pea Flower Tea,8,4.45,35.56,12:44:31\n2024-02-12,Sourdough Toast,15,6.13,92.0,12:45:08\n2024-02-12,Almond Butter Croissant,16,5.31,84.95,12:45:44\n2024-02-12,Vegan Morning Bun,7,5.96,41.72,12:46:20\n2024-02-13,Single-Origin Pour Over,1,5.29,5.29,12:46:57\n2024-02-13,Oat Milk Latte,15,6.21,93.16,12:47:33\n2024-02-13,Honey Lavender Latte,6,6.62,39.73,12:48:10\n2024-02-13,Turmeric Ginger Latte,7,6.35,44.43,12:48:46\n2024-02-13,Cold Brew Concentrate,8,5.67,45.37,12:49:22\n2024-02-13,Nitro Cold Brew,16,6.47,103.48,12:49:59\n2024-02-13,Matcha Espresso Fusion,15,6.91,103.63,12:50:35\n2024-02-13,Blue Pea Flower Tea,12,4.43,53.2,12:51:12\n2024-02-13,Sourdough Toast,16,5.9,94.47,12:51:48\n2024-02-13,Almond Butter Croissant,13,5.5,71.47,12:52:24\n2024-02-13,Vegan Morning Bun,7,5.9,41.28,12:53:01\n2024-02-14,Single-Origin Pour Over,14,5.73,80.23,12:53:37\n2024-02-14,Oat Milk Latte,8,5.99,47.92,12:54:14\n2024-02-14,Honey Lavender Latte,8,6.64,53.11,12:54:50\n2024-02-14,Turmeric Ginger Latte,12,6.01,72.15,12:55:26\n2024-02-14,Cold Brew Concentrate,17,5.91,100.45,12:56:03\n2024-02-14,Nitro Cold Brew,9,6.24,56.19,12:56:39\n2024-02-14,Matcha Espresso Fusion,13,7.1,92.36,12:57:16\n2024-02-14,Blue Pea Flower Tea,15,4.57,68.52,12:57:52\n2024-02-14,Sourdough Toast,18,5.78,104.11,12:58:28\n2024-02-14,Almond Butter Croissant,18,5.09,91.63,12:59:05\n2024-02-14,Vegan Morning Bun,10,6.14,61.42,12:59:41\n2024-02-15,Single-Origin Pour Over,10,5.69,56.87,13:00:18\n2024-02-15,Oat Milk Latte,13,5.87,76.29,13:00:54\n2024-02-15,Honey Lavender Latte,13,6.74,87.62,13:01:31\n2024-02-15,Turmeric Ginger Latte,1,6.48,6.48,13:02:07\n2024-02-15,Cold Brew Concentrate,14,6.02,84.27,13:02:43\n2024-02-15,Nitro Cold Brew,20,6.55,131.07,13:03:20\n2024-02-15,Matcha Espresso Fusion,16,6.73,107.76,13:03:56\n2024-02-15,Blue Pea Flower Tea,11,4.84,53.29,13:04:33\n2024-02-15,Sourdough Toast,18,6.22,111.9,13:05:09\n2024-02-15,Almond Butter Croissant,13,5.33,69.32,13:05:45\n2024-02-15,Vegan Morning Bun,12,5.64,67.68,13:06:22\n2024-02-16,Single-Origin Pour Over,1,5.88,5.88,13:06:58\n2024-02-16,Oat Milk Latte,14,5.87,82.12,13:07:35\n2024-02-16,Honey Lavender Latte,16,6.33,101.29,13:08:11\n2024-02-16,Turmeric Ginger Latte,22,6.45,141.96,13:08:47\n2024-02-16,Cold Brew Concentrate,4,6.12,24.48,13:09:24\n2024-02-16,Nitro Cold Brew,21,6.07,127.49,13:10:00\n2024-02-16,Matcha Espresso Fusion,4,6.82,27.29,13:10:37\n2024-02-16,Blue Pea Flower Tea,16,4.49,71.83,13:11:13\n2024-02-16,Sourdough Toast,15,5.8,87.02,13:11:49\n2024-02-16,Almond Butter Croissant,13,5.31,69.05,13:12:26\n2024-02-16,Vegan Morning Bun,7,5.72,40.03,13:13:02\n2024-02-17,Single-Origin Pour Over,17,5.86,99.69,13:13:39\n2024-02-17,Oat Milk Latte,13,6.21,80.67,13:14:15\n2024-02-17,Honey Lavender Latte,7,6.68,46.77,13:14:51\n2024-02-17,Turmeric Ginger Latte,8,6.21,49.67,13:15:28\n2024-02-17,Cold Brew Concentrate,12,6.01,72.18,13:16:04\n2024-02-17,Nitro Cold Brew,22,6.6,145.12,13:16:41\n2024-02-17,Matcha Espresso Fusion,19,6.57,124.79,13:17:17\n2024-02-17,Blue Pea Flower Tea,10,4.51,45.09,13:17:53\n2024-02-17,Sourdough Toast,16,6.16,98.62,13:18:30\n2024-02-17,Almond Butter Croissant,15,5.6,83.94,13:19:06\n2024-02-17,Vegan Morning Bun,11,5.74,63.17,13:19:43\n2024-02-18,Single-Origin Pour Over,9,5.9,53.06,13:20:19\n2024-02-18,Oat Milk Latte,5,5.95,29.74,13:20:55\n2024-02-18,Honey Lavender Latte,4,6.56,26.26,13:21:32\n2024-02-18,Turmeric Ginger Latte,11,6.62,72.81,13:22:08\n2024-02-18,Cold Brew Concentrate,11,5.9,64.91,13:22:45\n2024-02-18,Nitro Cold Brew,11,6.51,71.61,13:23:21\n2024-02-18,Matcha Espresso Fusion,8,6.73,53.88,13:23:57\n2024-02-18,Blue Pea Flower Tea,10,4.76,47.62,13:24:34\n2024-02-18,Sourdough Toast,10,6.2,62.04,13:25:10\n2024-02-18,Almond Butter Croissant,11,5.17,56.9,13:25:47\n2024-02-18,Vegan Morning Bun,1,5.63,5.63,13:26:23\n2024-02-19,Single-Origin Pour Over,19,5.51,104.63,13:26:59\n2024-02-19,Oat Milk Latte,13,5.85,76.02,13:27:36\n2024-02-19,Honey Lavender Latte,3,6.9,20.7,13:28:12\n2024-02-19,Turmeric Ginger Latte,14,6.16,86.28,13:28:49\n2024-02-19,Cold Brew Concentrate,15,6.12,91.79,13:29:25\n2024-02-19,Nitro Cold Brew,9,6.19,55.72,13:30:01\n2024-02-19,Matcha Espresso Fusion,10,7.01,70.14,13:30:38\n2024-02-19,Blue Pea Flower Tea,12,4.52,54.29,13:31:14\n2024-02-19,Sourdough Toast,13,6.23,81.03,13:31:51\n2024-02-19,Almond Butter Croissant,12,5.32,63.82,13:32:27\n2024-02-19,Vegan Morning Bun,17,5.76,97.97,13:33:03\n2024-02-20,Single-Origin Pour Over,2,5.33,10.65,13:33:40\n2024-02-20,Oat Milk Latte,2,6.36,12.71,13:34:16\n2024-02-20,Honey Lavender Latte,21,6.55,137.45,13:34:53\n2024-02-20,Turmeric Ginger Latte,13,6.51,84.6,13:35:29\n2024-02-20,Cold Brew Concentrate,14,6.12,85.72,13:36:05\n2024-02-20,Nitro Cold Brew,9,6.08,54.76,13:36:42\n2024-02-20,Matcha Espresso Fusion,9,7.0,63.04,13:37:18\n2024-02-20,Blue Pea Flower Tea,11,4.59,50.49,13:37:55\n2024-02-20,Sourdough Toast,11,6.23,68.54,13:38:31\n2024-02-20,Almond Butter Croissant,13,5.05,65.62,13:39:07\n2024-02-20,Vegan Morning Bun,5,5.52,27.58,13:39:44\n2024-02-21,Single-Origin Pour Over,17,5.45,92.61,13:40:20\n2024-02-21,Oat Milk Latte,9,6.32,56.89,13:40:57\n2024-02-21,Honey Lavender Latte,12,6.52,78.26,13:41:33\n2024-02-21,Turmeric Ginger Latte,14,6.6,92.46,13:42:09\n2024-02-21,Cold Brew Concentrate,12,5.97,71.61,13:42:46\n2024-02-21,Nitro Cold Brew,15,6.41,96.19,13:43:22\n2024-02-21,Matcha Espresso Fusion,14,6.89,96.52,13:43:59\n2024-02-21,Blue Pea Flower Tea,15,4.61,69.18,13:44:35\n2024-02-21,Sourdough Toast,5,6.11,30.53,13:45:11\n2024-02-21,Almond Butter Croissant,10,5.36,53.59,13:45:48\n2024-02-21,Vegan Morning Bun,9,5.73,51.61,13:46:24\n2024-02-22,Single-Origin Pour Over,6,5.27,31.6,13:47:01\n2024-02-22,Oat Milk Latte,21,6.26,131.54,13:47:37\n2024-02-22,Honey Lavender Latte,1,6.43,6.43,13:48:13\n2024-02-22,Turmeric Ginger Latte,12,6.56,78.77,13:48:50\n2024-02-22,Cold Brew Concentrate,8,5.76,46.06,13:49:26\n2024-02-22,Nitro Cold Brew,13,6.64,86.37,13:50:03\n2024-02-22,Matcha Espresso Fusion,9,6.54,58.9,13:50:39\n2024-02-22,Blue Pea Flower Tea,10,4.29,42.95,13:51:15\n2024-02-22,Sourdough Toast,11,6.34,69.73,13:51:52\n2024-02-22,Almond Butter Croissant,9,5.62,50.54,13:52:28\n2024-02-22,Vegan Morning Bun,10,5.95,59.46,13:53:05\n2024-02-23,Single-Origin Pour Over,15,5.29,79.34,13:53:41\n2024-02-23,Oat Milk Latte,8,6.18,49.42,13:54:17\n2024-02-23,Honey Lavender Latte,16,6.44,103.01,13:54:54\n2024-02-23,Turmeric Ginger Latte,1,6.4,6.4,13:55:30\n2024-02-23,Cold Brew Concentrate,7,5.71,39.99,13:56:07\n2024-02-23,Nitro Cold Brew,13,6.5,84.51,13:56:43\n2024-02-23,Matcha Espresso Fusion,5,6.75,33.75,13:57:19\n2024-02-23,Blue Pea Flower Tea,11,4.5,49.53,13:57:56\n2024-02-23,Sourdough Toast,14,6.0,84.04,13:58:32\n2024-02-23,Almond Butter Croissant,14,5.64,78.94,13:59:09\n2024-02-23,Vegan Morning Bun,23,5.53,127.17,13:59:45\n2024-02-24,Single-Origin Pour Over,9,5.71,51.42,14:00:21\n2024-02-24,Oat Milk Latte,14,5.97,83.52,14:00:58\n2024-02-24,Honey Lavender Latte,9,6.36,57.27,14:01:34\n2024-02-24,Turmeric Ginger Latte,9,6.59,59.33,14:02:11\n2024-02-24,Cold Brew Concentrate,2,6.03,12.06,14:02:47\n2024-02-24,Nitro Cold Brew,9,6.35,57.14,14:03:23\n2024-02-24,Matcha Espresso Fusion,5,6.63,33.13,14:04:00\n2024-02-24,Blue Pea Flower Tea,16,4.34,69.48,14:04:36\n2024-02-24,Sourdough Toast,7,6.17,43.17,14:05:13\n2024-02-24,Almond Butter Croissant,3,5.25,15.76,14:05:49\n2024-02-24,Vegan Morning Bun,5,5.76,28.78,14:06:25\n2024-02-25,Single-Origin Pour Over,9,5.61,50.48,14:07:02\n2024-02-25,Oat Milk Latte,13,6.35,82.49,14:07:38\n2024-02-25,Honey Lavender Latte,9,6.62,59.58,14:08:15\n2024-02-25,Turmeric Ginger Latte,10,6.5,65.0,14:08:51\n2024-02-25,Cold Brew Concentrate,10,6.03,60.26,14:09:27\n2024-02-25,Nitro Cold Brew,8,6.42,51.32,14:10:04\n2024-02-25,Matcha Espresso Fusion,10,6.72,67.23,14:10:40\n2024-02-25,Blue Pea Flower Tea,5,4.87,24.33,14:11:17\n2024-02-25,Sourdough Toast,12,6.38,76.59,14:11:53\n2024-02-25,Almond Butter Croissant,20,5.57,111.44,14:12:29\n2024-02-25,Vegan Morning Bun,15,6.09,91.3,14:13:06\n2024-02-26,Single-Origin Pour Over,10,5.76,57.65,14:13:42\n2024-02-26,Oat Milk Latte,8,5.93,47.43,14:14:19\n2024-02-26,Honey Lavender Latte,13,6.56,85.26,14:14:55\n2024-02-26,Turmeric Ginger Latte,11,6.37,70.11,14:15:31\n2024-02-26,Cold Brew Concentrate,9,6.09,54.8,14:16:08\n2024-02-26,Nitro Cold Brew,9,6.5,58.5,14:16:44\n2024-02-26,Matcha Espresso Fusion,10,7.07,70.72,14:17:21\n2024-02-26,Blue Pea Flower Tea,15,4.34,65.06,14:17:57\n2024-02-26,Sourdough Toast,14,6.09,85.29,14:18:33\n2024-02-26,Almond Butter Croissant,10,5.27,52.68,14:19:10\n2024-02-26,Vegan Morning Bun,7,5.62,39.31,14:19:46\n2024-02-27,Single-Origin Pour Over,8,5.54,44.35,14:20:23\n2024-02-27,Oat Milk Latte,7,6.23,43.59,14:20:59\n2024-02-27,Honey Lavender Latte,12,6.31,75.7,14:21:35\n2024-02-27,Turmeric Ginger Latte,7,6.26,43.79,14:22:12\n2024-02-27,Cold Brew Concentrate,10,5.61,56.11,14:22:48\n2024-02-27,Nitro Cold Brew,12,6.29,75.51,14:23:25\n2024-02-27,Matcha Espresso Fusion,10,6.65,66.49,14:24:01\n2024-02-27,Blue Pea Flower Tea,12,4.28,51.37,14:24:37\n2024-02-27,Sourdough Toast,17,6.0,101.98,14:25:14\n2024-02-27,Almond Butter Croissant,5,5.19,25.97,14:25:50\n2024-02-27,Vegan Morning Bun,21,5.71,119.98,14:26:27\n2024-02-28,Single-Origin Pour Over,10,5.9,58.98,14:27:03\n2024-02-28,Oat Milk Latte,2,6.35,12.7,14:27:39\n2024-02-28,Honey Lavender Latte,16,6.36,101.68,14:28:16\n2024-02-28,Turmeric Ginger Latte,12,6.41,76.91,14:28:52\n2024-02-28,Cold Brew Concentrate,9,5.86,52.78,14:29:29\n2024-02-28,Nitro Cold Brew,15,6.34,95.05,14:30:05\n2024-02-28,Matcha Espresso Fusion,17,6.52,110.76,14:30:41\n2024-02-28,Blue Pea Flower Tea,2,4.59,9.18,14:31:18\n2024-02-28,Sourdough Toast,17,5.79,98.5,14:31:54\n2024-02-28,Almond Butter Croissant,11,5.57,61.31,14:32:31\n2024-02-28,Vegan Morning Bun,14,6.0,83.95,14:33:07\n2024-02-29,Single-Origin Pour Over,10,5.64,56.42,14:33:43\n2024-02-29,Oat Milk Latte,8,6.19,49.49,14:34:20\n2024-02-29,Honey Lavender Latte,1,6.49,6.49,14:34:56\n2024-02-29,Turmeric Ginger Latte,12,6.46,77.54,14:35:33\n2024-02-29,Cold Brew Concentrate,10,5.68,56.85,14:36:09\n2024-02-29,Nitro Cold Brew,13,6.23,80.96,14:36:45\n2024-02-29,Matcha Espresso Fusion,11,6.55,72.02,14:37:22\n2024-02-29,Blue Pea Flower Tea,10,4.51,45.05,14:37:58\n2024-02-29,Sourdough Toast,14,6.12,85.64,14:38:35\n2024-02-29,Almond Butter Croissant,4,5.15,20.62,14:39:11\n2024-02-29,Vegan Morning Bun,11,5.83,64.11,14:39:47\n2024-03-01,Single-Origin Pour Over,8,5.37,42.95,14:40:24\n2024-03-01,Oat Milk Latte,9,5.88,52.89,14:41:00\n2024-03-01,Honey Lavender Latte,11,6.74,74.15,14:41:37\n2024-03-01,Turmeric Ginger Latte,16,6.54,104.58,14:42:13\n2024-03-01,Cold Brew Concentrate,13,6.03,78.44,14:42:49\n2024-03-01,Nitro Cold Brew,8,6.15,49.19,14:43:26\n2024-03-01,Matcha Espresso Fusion,12,6.84,82.04,14:44:02\n2024-03-01,Blue Pea Flower Tea,15,4.9,73.44,14:44:39\n2024-03-01,Sourdough Toast,13,5.8,75.4,14:45:15\n2024-03-01,Almond Butter Croissant,4,5.23,20.94,14:45:51\n2024-03-01,Vegan Morning Bun,15,6.14,92.15,14:46:28\n2024-03-02,Single-Origin Pour Over,8,5.35,42.79,14:47:04\n2024-03-02,Oat Milk Latte,12,6.39,76.63,14:47:41\n2024-03-02,Honey Lavender Latte,9,6.88,61.89,14:48:17\n2024-03-02,Turmeric Ginger Latte,14,6.38,89.27,14:48:53\n2024-03-02,Cold Brew Concentrate,15,5.51,82.65,14:49:30\n2024-03-02,Nitro Cold Brew,12,6.3,75.66,14:50:06\n2024-03-02,Matcha Espresso Fusion,15,6.51,97.69,14:50:43\n2024-03-02,Blue Pea Flower Tea,9,4.88,43.88,14:51:19\n2024-03-02,Sourdough Toast,6,6.17,36.99,14:51:55\n2024-03-02,Almond Butter Croissant,7,5.48,38.36,14:52:32\n2024-03-02,Vegan Morning Bun,19,5.64,107.07,14:53:08\n2024-03-03,Single-Origin Pour Over,13,5.36,69.71,14:53:45\n2024-03-03,Oat Milk Latte,3,6.32,18.97,14:54:21\n2024-03-03,Honey Lavender Latte,11,6.86,75.42,14:54:57\n2024-03-03,Turmeric Ginger Latte,3,6.24,18.72,14:55:34\n2024-03-03,Cold Brew Concentrate,20,5.78,115.66,14:56:10\n2024-03-03,Nitro Cold Brew,15,6.17,92.51,14:56:47\n2024-03-03,Matcha Espresso Fusion,19,6.77,128.57,14:57:23\n2024-03-03,Blue Pea Flower Tea,12,4.7,56.37,14:57:59\n2024-03-03,Sourdough Toast,8,6.36,50.9,14:58:36\n2024-03-03,Almond Butter Croissant,4,5.04,20.18,14:59:12\n2024-03-03,Vegan Morning Bun,9,5.96,53.6,14:59:49\n2024-03-04,Single-Origin Pour Over,17,5.4,91.8,15:00:25\n2024-03-04,Oat Milk Latte,13,6.02,78.29,15:01:01\n2024-03-04,Honey Lavender Latte,15,6.26,93.96,15:01:38\n2024-03-04,Turmeric Ginger Latte,22,6.48,142.58,15:02:14\n2024-03-04,Cold Brew Concentrate,5,5.9,29.49,15:02:51\n2024-03-04,Nitro Cold Brew,13,6.32,82.17,15:03:27\n2024-03-04,Matcha Espresso Fusion,19,6.79,129.1,15:04:03\n2024-03-04,Blue Pea Flower Tea,5,4.85,24.26,15:04:40\n2024-03-04,Sourdough Toast,9,5.94,53.43,15:05:16\n2024-03-04,Almond Butter Croissant,7,5.39,37.71,15:05:53\n2024-03-04,Vegan Morning Bun,15,5.71,85.59,15:06:29\n2024-03-05,Single-Origin Pour Over,10,5.54,55.36,15:07:05\n2024-03-05,Oat Milk Latte,2,6.04,12.07,15:07:42\n2024-03-05,Honey Lavender Latte,6,6.67,40.04,15:08:18\n2024-03-05,Turmeric Ginger Latte,12,6.5,78.0,15:08:55\n2024-03-05,Cold Brew Concentrate,4,5.58,22.32,15:09:31\n2024-03-05,Nitro Cold Brew,1,6.02,6.02,15:10:07\n2024-03-05,Matcha Espresso Fusion,9,6.57,59.15,15:10:44\n2024-03-05,Blue Pea Flower Tea,4,4.48,17.93,15:11:20\n2024-03-05,Sourdough Toast,24,6.23,149.44,15:11:57\n2024-03-05,Almond Butter Croissant,2,5.34,10.68,15:12:33\n2024-03-05,Vegan Morning Bun,9,5.78,52.06,15:13:09\n2024-03-06,Single-Origin Pour Over,7,5.6,39.22,15:13:46\n2024-03-06,Oat Milk Latte,2,6.34,12.68,15:14:22\n2024-03-06,Honey Lavender Latte,5,6.68,33.42,15:14:59\n2024-03-06,Turmeric Ginger Latte,10,6.21,62.08,15:15:35\n2024-03-06,Cold Brew Concentrate,22,5.53,121.74,15:16:11\n2024-03-06,Nitro Cold Brew,9,6.55,58.99,15:16:48\n2024-03-06,Matcha Espresso Fusion,17,6.52,110.87,15:17:24\n2024-03-06,Blue Pea Flower Tea,11,4.65,51.14,15:18:01\n2024-03-06,Sourdough Toast,9,6.17,55.56,15:18:37\n2024-03-06,Almond Butter Croissant,16,5.26,84.21,15:19:13\n2024-03-06,Vegan Morning Bun,5,5.61,28.06,15:19:50\n2024-03-07,Single-Origin Pour Over,10,5.83,58.3,15:20:26\n2024-03-07,Oat Milk Latte,9,5.93,53.38,15:21:03\n2024-03-07,Honey Lavender Latte,6,6.89,41.34,15:21:39\n2024-03-07,Turmeric Ginger Latte,12,6.58,78.98,15:22:15\n2024-03-07,Cold Brew Concentrate,9,6.07,54.65,15:22:52\n2024-03-07,Nitro Cold Brew,9,6.19,55.72,15:23:28\n2024-03-07,Matcha Espresso Fusion,13,6.6,85.75,15:24:05\n2024-03-07,Blue Pea Flower Tea,7,4.3,30.08,15:24:41\n2024-03-07,Sourdough Toast,13,5.87,76.35,15:25:17\n2024-03-07,Almond Butter Croissant,12,5.56,66.67,15:25:54\n2024-03-07,Vegan Morning Bun,16,5.72,91.45,15:26:30\n2024-03-08,Single-Origin Pour Over,13,5.48,71.2,15:27:07\n2024-03-08,Oat Milk Latte,4,5.95,23.79,15:27:43\n2024-03-08,Honey Lavender Latte,13,6.33,82.3,15:28:19\n2024-03-08,Turmeric Ginger Latte,11,6.09,67.03,15:28:56\n2024-03-08,Cold Brew Concentrate,18,6.09,109.65,15:29:32\n2024-03-08,Nitro Cold Brew,22,6.35,139.8,15:30:09\n2024-03-08,Matcha Espresso Fusion,11,6.93,76.27,15:30:45\n2024-03-08,Blue Pea Flower Tea,18,4.65,83.68,15:31:21\n2024-03-08,Sourdough Toast,10,5.88,58.82,15:31:58\n2024-03-08,Almond Butter Croissant,18,5.63,101.37,15:32:34\n2024-03-08,Vegan Morning Bun,4,5.73,22.92,15:33:11\n2024-03-09,Single-Origin Pour Over,14,5.78,80.94,15:33:47\n2024-03-09,Oat Milk Latte,6,5.95,35.7,15:34:23\n2024-03-09,Honey Lavender Latte,21,6.62,138.97,15:35:00\n2024-03-09,Turmeric Ginger Latte,12,6.58,78.9,15:35:36\n2024-03-09,Cold Brew Concentrate,14,5.55,77.72,15:36:13\n2024-03-09,Nitro Cold Brew,10,6.22,62.15,15:36:49\n2024-03-09,Matcha Espresso Fusion,12,7.1,85.24,15:37:25\n2024-03-09,Blue Pea Flower Tea,17,4.65,79.13,15:38:02\n2024-03-09,Sourdough Toast,8,6.07,48.55,15:38:38\n2024-03-09,Almond Butter Croissant,15,5.31,79.66,15:39:15\n2024-03-09,Vegan Morning Bun,10,5.93,59.25,15:39:51\n2024-03-10,Single-Origin Pour Over,2,5.85,11.71,15:40:27\n2024-03-10,Oat Milk Latte,7,6.0,41.99,15:41:04\n2024-03-10,Honey Lavender Latte,12,6.45,77.39,15:41:40\n2024-03-10,Turmeric Ginger Latte,10,6.21,62.05,15:42:17\n2024-03-10,Cold Brew Concentrate,3,6.01,18.03,15:42:53\n2024-03-10,Nitro Cold Brew,17,6.2,105.34,15:43:29\n2024-03-10,Matcha Espresso Fusion,11,7.14,78.52,15:44:06\n2024-03-10,Blue Pea Flower Tea,13,4.33,56.3,15:44:42\n2024-03-10,Sourdough Toast,7,5.9,41.27,15:45:19\n2024-03-10,Almond Butter Croissant,13,5.24,68.13,15:45:55\n2024-03-10,Vegan Morning Bun,18,5.54,99.71,15:46:31\n2024-03-11,Single-Origin Pour Over,13,5.28,68.59,15:47:08\n2024-03-11,Oat Milk Latte,16,5.99,95.78,15:47:44\n2024-03-11,Honey Lavender Latte,9,6.31,56.76,15:48:21\n2024-03-11,Turmeric Ginger Latte,12,6.42,77.02,15:48:57\n2024-03-11,Cold Brew Concentrate,10,5.53,55.26,15:49:33\n2024-03-11,Nitro Cold Brew,15,6.31,94.67,15:50:10\n2024-03-11,Matcha Espresso Fusion,15,7.02,105.3,15:50:46\n2024-03-11,Blue Pea Flower Tea,15,4.75,71.31,15:51:23\n2024-03-11,Sourdough Toast,10,6.19,61.89,15:51:59\n2024-03-11,Almond Butter Croissant,13,5.62,73.05,15:52:35\n2024-03-11,Vegan Morning Bun,3,6.07,18.2,15:53:12\n2024-03-12,Single-Origin Pour Over,11,5.75,63.21,15:53:48\n2024-03-12,Oat Milk Latte,10,6.02,60.23,15:54:25\n2024-03-12,Honey Lavender Latte,12,6.51,78.14,15:55:01\n2024-03-12,Turmeric Ginger Latte,1,6.38,6.38,15:55:37\n2024-03-12,Cold Brew Concentrate,10,5.88,58.78,15:56:14\n2024-03-12,Nitro Cold Brew,6,6.27,37.65,15:56:50\n2024-03-12,Matcha Espresso Fusion,15,7.03,105.49,15:57:27\n2024-03-12,Blue Pea Flower Tea,2,4.35,8.7,15:58:03\n2024-03-12,Sourdough Toast,19,5.87,111.55,15:58:39\n2024-03-12,Almond Butter Croissant,20,5.45,109.02,15:59:16\n2024-03-12,Vegan Morning Bun,14,5.89,82.48,15:59:52\n2024-03-13,Single-Origin Pour Over,11,5.45,59.96,16:00:29\n2024-03-13,Oat Milk Latte,7,5.75,40.27,16:01:05\n2024-03-13,Honey Lavender Latte,15,6.88,103.13,16:01:41\n2024-03-13,Turmeric Ginger Latte,12,6.08,72.95,16:02:18\n2024-03-13,Cold Brew Concentrate,15,5.85,87.69,16:02:54\n2024-03-13,Nitro Cold Brew,14,6.04,84.59,16:03:31\n2024-03-13,Matcha Espresso Fusion,10,7.14,71.38,16:04:07\n2024-03-13,Blue Pea Flower Tea,10,4.57,45.69,16:04:43\n2024-03-13,Sourdough Toast,13,5.91,76.89,16:05:20\n2024-03-13,Almond Butter Croissant,5,5.4,27.01,16:05:56\n2024-03-13,Vegan Morning Bun,23,6.03,138.6,16:06:33\n2024-03-14,Single-Origin Pour Over,8,5.57,44.58,16:07:09\n2024-03-14,Oat Milk Latte,11,6.12,67.32,16:07:45\n2024-03-14,Honey Lavender Latte,5,6.38,31.92,16:08:22\n2024-03-14,Turmeric Ginger Latte,14,6.08,85.13,16:08:58\n2024-03-14,Cold Brew Concentrate,16,6.0,96.04,16:09:35\n2024-03-14,Nitro Cold Brew,14,6.34,88.69,16:10:11\n2024-03-14,Matcha Espresso Fusion,19,6.82,129.63,16:10:47\n2024-03-14,Blue Pea Flower Tea,10,4.62,46.2,16:11:24\n2024-03-14,Sourdough Toast,18,6.17,110.98,16:12:00\n2024-03-14,Almond Butter Croissant,13,5.29,68.8,16:12:37\n2024-03-14,Vegan Morning Bun,15,5.84,87.64,16:13:13\n2024-03-15,Single-Origin Pour Over,14,5.64,79.01,16:13:49\n2024-03-15,Oat Milk Latte,10,5.79,57.93,16:14:26\n2024-03-15,Honey Lavender Latte,13,6.66,86.58,16:15:02\n2024-03-15,Turmeric Ginger Latte,14,6.64,93.02,16:15:39\n2024-03-15,Cold Brew Concentrate,9,6.06,54.58,16:16:15\n2024-03-15,Nitro Cold Brew,17,6.61,112.39,16:16:51\n2024-03-15,Matcha Espresso Fusion,1,6.85,6.85,16:17:28\n2024-03-15,Blue Pea Flower Tea,7,4.35,30.45,16:18:04\n2024-03-15,Sourdough Toast,9,6.23,56.09,16:18:41\n2024-03-15,Almond Butter Croissant,14,5.23,73.23,16:19:17\n2024-03-15,Vegan Morning Bun,15,6.14,92.05,16:19:53\n2024-03-16,Single-Origin Pour Over,9,5.48,49.28,16:20:30\n2024-03-16,Oat Milk Latte,3,6.15,18.45,16:21:06\n2024-03-16,Honey Lavender Latte,6,6.48,38.88,16:21:43\n2024-03-16,Turmeric Ginger Latte,15,6.3,94.57,16:22:19\n2024-03-16,Cold Brew Concentrate,5,5.95,29.77,16:22:55\n2024-03-16,Nitro Cold Brew,1,6.33,6.33,16:23:32\n2024-03-16,Matcha Espresso Fusion,17,7.04,119.63,16:24:08\n2024-03-16,Blue Pea Flower Tea,7,4.56,31.95,16:24:45\n2024-03-16,Sourdough Toast,18,5.77,103.87,16:25:21\n2024-03-16,Almond Butter Croissant,14,5.11,71.54,16:25:57\n2024-03-16,Vegan Morning Bun,13,5.73,74.49,16:26:34\n2024-03-17,Single-Origin Pour Over,15,5.77,86.57,16:27:10\n2024-03-17,Oat Milk Latte,1,6.32,6.32,16:27:47\n2024-03-17,Honey Lavender Latte,14,6.84,95.74,16:28:23\n2024-03-17,Turmeric Ginger Latte,10,6.4,63.99,16:28:59\n2024-03-17,Cold Brew Concentrate,6,5.62,33.74,16:29:36\n2024-03-17,Nitro Cold Brew,12,6.39,76.64,16:30:12\n2024-03-17,Matcha Espresso Fusion,7,6.7,46.9,16:30:49\n2024-03-17,Blue Pea Flower Tea,19,4.75,90.27,16:31:25\n2024-03-17,Sourdough Toast,15,6.16,92.47,16:32:01\n2024-03-17,Almond Butter Croissant,14,5.44,76.09,16:32:38\n2024-03-17,Vegan Morning Bun,1,5.9,5.9,16:33:14\n2024-03-18,Single-Origin Pour Over,10,5.64,56.41,16:33:51\n2024-03-18,Oat Milk Latte,8,5.81,46.46,16:34:27\n2024-03-18,Honey Lavender Latte,5,6.68,33.42,16:35:03\n2024-03-18,Turmeric Ginger Latte,11,6.64,73.03,16:35:40\n2024-03-18,Cold Brew Concentrate,6,6.09,36.52,16:36:16\n2024-03-18,Nitro Cold Brew,15,6.45,96.79,16:36:53\n2024-03-18,Matcha Espresso Fusion,14,7.13,99.81,16:37:29\n2024-03-18,Blue Pea Flower Tea,14,4.51,63.15,16:38:05\n2024-03-18,Sourdough Toast,6,5.99,35.94,16:38:42\n2024-03-18,Almond Butter Croissant,14,5.45,76.28,16:39:18\n2024-03-18,Vegan Morning Bun,3,5.87,17.61,16:39:55\n2024-03-19,Single-Origin Pour Over,8,5.72,45.72,16:40:31\n2024-03-19,Oat Milk Latte,11,6.23,68.48,16:41:07\n2024-03-19,Honey Lavender Latte,8,6.29,50.31,16:41:44\n2024-03-19,Turmeric Ginger Latte,11,6.46,71.11,16:42:20\n2024-03-19,Cold Brew Concentrate,14,5.74,80.42,16:42:57\n2024-03-19,Nitro Cold Brew,13,6.39,83.04,16:43:33\n2024-03-19,Matcha Espresso Fusion,17,7.12,121.07,16:44:09\n2024-03-19,Blue Pea Flower Tea,16,4.49,71.82,16:44:46\n2024-03-19,Sourdough Toast,16,6.32,101.09,16:45:22\n2024-03-19,Almond Butter Croissant,13,5.13,66.65,16:45:59\n2024-03-19,Vegan Morning Bun,8,5.67,45.37,16:46:35\n2024-03-20,Single-Origin Pour Over,5,5.4,27.0,16:47:11\n2024-03-20,Oat Milk Latte,13,6.26,81.36,16:47:48\n2024-03-20,Honey Lavender Latte,16,6.61,105.71,16:48:24\n2024-03-20,Turmeric Ginger Latte,11,6.14,67.56,16:49:01\n2024-03-20,Cold Brew Concentrate,8,5.68,45.42,16:49:37\n2024-03-20,Nitro Cold Brew,10,6.39,63.89,16:50:13\n2024-03-20,Matcha Espresso Fusion,18,6.66,119.89,16:50:50\n2024-03-20,Blue Pea Flower Tea,12,4.81,57.67,16:51:26\n2024-03-20,Sourdough Toast,16,5.94,95.02,16:52:03\n2024-03-20,Almond Butter Croissant,9,5.36,48.21,16:52:39\n2024-03-20,Vegan Morning Bun,15,5.71,85.64,16:53:15\n2024-03-21,Single-Origin Pour Over,15,5.42,81.33,16:53:52\n2024-03-21,Oat Milk Latte,4,6.2,24.8,16:54:28\n2024-03-21,Honey Lavender Latte,17,6.71,114.08,16:55:05\n2024-03-21,Turmeric Ginger Latte,12,6.56,78.72,16:55:41\n2024-03-21,Cold Brew Concentrate,6,5.72,34.33,16:56:17\n2024-03-21,Nitro Cold Brew,20,6.46,129.24,16:56:54\n2024-03-21,Matcha Espresso Fusion,15,6.63,99.41,16:57:30\n2024-03-21,Blue Pea Flower Tea,14,4.45,62.31,16:58:07\n2024-03-21,Sourdough Toast,18,6.36,114.42,16:58:43\n2024-03-21,Almond Butter Croissant,10,5.52,55.21,16:59:19\n2024-03-21,Vegan Morning Bun,16,5.62,89.84,16:59:56\n2024-03-22,Single-Origin Pour Over,21,5.72,120.12,17:00:32\n2024-03-22,Oat Milk Latte,17,6.1,103.74,17:01:09\n2024-03-22,Honey Lavender Latte,5,6.57,32.84,17:01:45\n2024-03-22,Turmeric Ginger Latte,8,6.31,50.51,17:02:21\n2024-03-22,Cold Brew Concentrate,14,5.57,77.98,17:02:58\n2024-03-22,Nitro Cold Brew,13,6.53,84.89,17:03:34\n2024-03-22,Matcha Espresso Fusion,1,6.66,6.66,17:04:11\n2024-03-22,Blue Pea Flower Tea,16,4.38,70.14,17:04:47\n2024-03-22,Sourdough Toast,14,5.8,81.17,17:05:23\n2024-03-22,Almond Butter Croissant,7,5.09,35.62,17:06:00\n2024-03-22,Vegan Morning Bun,14,5.68,79.57,17:06:36\n2024-03-23,Single-Origin Pour Over,12,5.43,65.13,17:07:13\n2024-03-23,Oat Milk Latte,23,5.78,132.9,17:07:49\n2024-03-23,Honey Lavender Latte,7,6.39,44.72,17:08:25\n2024-03-23,Turmeric Ginger Latte,17,6.37,108.25,17:09:02\n2024-03-23,Cold Brew Concentrate,7,5.64,39.46,17:09:38\n2024-03-23,Nitro Cold Brew,11,6.6,72.57,17:10:15\n2024-03-23,Matcha Espresso Fusion,9,6.68,60.08,17:10:51\n2024-03-23,Blue Pea Flower Tea,13,4.43,57.58,17:11:27\n2024-03-23,Sourdough Toast,17,6.1,103.65,17:12:04\n2024-03-23,Almond Butter Croissant,12,5.05,60.57,17:12:40\n2024-03-23,Vegan Morning Bun,21,5.91,124.16,17:13:17\n2024-03-24,Single-Origin Pour Over,9,5.45,49.05,17:13:53\n2024-03-24,Oat Milk Latte,22,5.79,127.43,17:14:29\n2024-03-24,Honey Lavender Latte,18,6.82,122.72,17:15:06\n2024-03-24,Turmeric Ginger Latte,5,6.3,31.52,17:15:42\n2024-03-24,Cold Brew Concentrate,1,6.03,6.03,17:16:19\n2024-03-24,Nitro Cold Brew,14,6.34,88.69,17:16:55\n2024-03-24,Matcha Espresso Fusion,11,6.98,76.76,17:17:31\n2024-03-24,Blue Pea Flower Tea,10,4.61,46.14,17:18:08\n2024-03-24,Sourdough Toast,12,5.85,70.19,17:18:44\n2024-03-24,Almond Butter Croissant,11,5.2,57.17,17:19:21\n2024-03-24,Vegan Morning Bun,1,6.15,6.15,17:19:57\n2024-03-25,Single-Origin Pour Over,6,5.62,33.69,17:20:33\n2024-03-25,Oat Milk Latte,5,5.91,29.54,17:21:10\n2024-03-25,Honey Lavender Latte,17,6.51,110.64,17:21:46\n2024-03-25,Turmeric Ginger Latte,13,6.27,81.51,17:22:23\n2024-03-25,Cold Brew Concentrate,15,6.01,90.22,17:22:59\n2024-03-25,Nitro Cold Brew,10,6.01,60.14,17:23:35\n2024-03-25,Matcha Espresso Fusion,11,6.85,75.35,17:24:12\n2024-03-25,Blue Pea Flower Tea,5,4.55,22.76,17:24:48\n2024-03-25,Sourdough Toast,8,5.88,47.02,17:25:25\n2024-03-25,Almond Butter Croissant,11,5.61,61.68,17:26:01\n2024-03-25,Vegan Morning Bun,6,5.69,34.15,17:26:37\n2024-03-26,Single-Origin Pour Over,19,5.29,100.57,17:27:14\n2024-03-26,Oat Milk Latte,12,6.01,72.08,17:27:50\n2024-03-26,Honey Lavender Latte,11,6.63,72.89,17:28:27\n2024-03-26,Turmeric Ginger Latte,15,6.09,91.39,17:29:03\n2024-03-26,Cold Brew Concentrate,8,5.67,45.35,17:29:39\n2024-03-26,Nitro Cold Brew,13,6.52,84.7,17:30:16\n2024-03-26,Matcha Espresso Fusion,5,6.62,33.1,17:30:52\n2024-03-26,Blue Pea Flower Tea,8,4.63,37.0,17:31:29\n2024-03-26,Sourdough Toast,9,6.39,57.48,17:32:05\n2024-03-26,Almond Butter Croissant,10,5.47,54.73,17:32:41\n2024-03-26,Vegan Morning Bun,12,5.66,67.91,17:33:18\n2024-03-27,Single-Origin Pour Over,6,5.38,32.31,17:33:54\n2024-03-27,Oat Milk Latte,3,6.13,18.39,17:34:31\n2024-03-27,Honey Lavender Latte,7,6.41,44.84,17:35:07\n2024-03-27,Turmeric Ginger Latte,10,6.54,65.38,17:35:43\n2024-03-27,Cold Brew Concentrate,9,5.57,50.14,17:36:20\n2024-03-27,Nitro Cold Brew,9,6.47,58.23,17:36:56\n2024-03-27,Matcha Espresso Fusion,12,6.57,78.85,17:37:33\n2024-03-27,Blue Pea Flower Tea,18,4.41,79.35,17:38:09\n2024-03-27,Sourdough Toast,7,5.97,41.82,17:38:45\n2024-03-27,Almond Butter Croissant,7,5.21,36.48,17:39:22\n2024-03-27,Vegan Morning Bun,8,5.6,44.8,17:39:58\n2024-03-28,Single-Origin Pour Over,13,5.76,74.91,17:40:35\n2024-03-28,Oat Milk Latte,13,6.1,79.26,17:41:11\n2024-03-28,Honey Lavender Latte,5,6.59,32.97,17:41:47\n2024-03-28,Turmeric Ginger Latte,11,6.03,66.34,17:42:24\n2024-03-28,Cold Brew Concentrate,14,5.56,77.88,17:43:00\n2024-03-28,Nitro Cold Brew,12,6.18,74.22,17:43:37\n2024-03-28,Matcha Espresso Fusion,15,6.76,101.45,17:44:13\n2024-03-28,Blue Pea Flower Tea,15,4.34,65.03,17:44:49\n2024-03-28,Sourdough Toast,6,6.14,36.86,17:45:26\n2024-03-28,Almond Butter Croissant,7,5.63,39.44,17:46:02\n2024-03-28,Vegan Morning Bun,16,5.72,91.5,17:46:39\n2024-03-29,Single-Origin Pour Over,19,5.7,108.35,17:47:15\n2024-03-29,Oat Milk Latte,10,5.8,58.01,17:47:51\n2024-03-29,Honey Lavender Latte,8,6.49,51.91,17:48:28\n2024-03-29,Turmeric Ginger Latte,3,6.32,18.96,17:49:04\n2024-03-29,Cold Brew Concentrate,13,5.65,73.4,17:49:41\n2024-03-29,Nitro Cold Brew,9,6.34,57.05,17:50:17\n2024-03-29,Matcha Espresso Fusion,7,6.92,48.44,17:50:53\n2024-03-29,Blue Pea Flower Tea,14,4.73,66.28,17:51:30\n2024-03-29,Sourdough Toast,13,6.11,79.45,17:52:06\n2024-03-29,Almond Butter Croissant,6,5.63,33.77,17:52:43\n2024-03-29,Vegan Morning Bun,10,5.94,59.45,17:53:19\n2024-03-30,Single-Origin Pour Over,18,5.52,99.27,17:53:55\n2024-03-30,Oat Milk Latte,8,5.88,47.02,17:54:32\n2024-03-30,Honey Lavender Latte,8,6.55,52.41,17:55:08\n2024-03-30,Turmeric Ginger Latte,9,6.01,54.11,17:55:45\n2024-03-30,Cold Brew Concentrate,12,5.71,68.54,17:56:21\n2024-03-30,Nitro Cold Brew,3,6.03,18.09,17:56:57\n2024-03-30,Matcha Espresso Fusion,7,6.51,45.58,17:57:34\n2024-03-30,Blue Pea Flower Tea,4,4.48,17.9,17:58:10\n2024-03-30,Sourdough Toast,9,6.28,56.54,17:58:47\n2024-03-30,Almond Butter Croissant,10,5.35,53.54,17:59:23\n2024-03-30,Vegan Morning Bun,12,5.6,67.19,18:00:00\n"
  },
  {
    "path": "guides/python/ai-data-analyst/openai/pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools>=42\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"openai-data-analysis-openai\"\nversion = \"0.1.0\"\ndescription = \"Daytona + OpenAI data analyst example in Python\"\nauthors = [\n    {name = \"Daytona Team\", email = \"support@daytona.io\"}\n]\nreadme = \"README.md\"\nrequires-python = \">=3.10\"\ndependencies = [\n    \"openai>=1.3.0,<2.0.0\",\n    \"daytona>=0.1.0,<1.0.0\",\n    \"python-dotenv>=1.0.0,<2.0.0\"\n]"
  },
  {
    "path": "guides/python/dspy-rlms/.gitignore",
    "content": "venv/\n__pycache__/\n.env\nmonte_cristo.txt\n"
  },
  {
    "path": "guides/python/dspy-rlms/README.md",
    "content": "# Run DSPy RLMs on Daytona\n\n## Overview\n\nDSPy's [RLM (Recursive Language Model)](https://dspy.ai/) module gives an LLM a Python REPL. The LLM writes code, executes it, sees the output, and repeats — building up state across iterations until it calls `SUBMIT()` with a final answer. Within that code, the LLM can also call `llm_query()` to invoke sub-LLM reasoning (the \"recursive\" part), mixing procedural computation with natural-language understanding.\n\n`DaytonaInterpreter` is a `CodeInterpreter` backend that runs all of this inside a Daytona cloud sandbox, so LLM-generated code never executes on the host.\n\n## Features\n\n- **Sandboxed REPL:** LLM-generated code runs in an isolated Daytona sandbox\n- **Persistent state:** Variables and imports survive across iterations within a session\n- **Sub-LLM calls:** `llm_query()` and `llm_query_batched()` are bridged into the sandbox, letting generated code invoke nested LLM reasoning\n- **Custom tools:** Host-side Python functions (database queries, APIs, etc.) can be passed into the sandbox through a broker server\n- **Typed SUBMIT:** Output fields can have explicit types so the LLM knows the expected schema\n- **Context manager:** `DaytonaInterpreter` supports `with` for automatic cleanup\n\n## Requirements\n\n- **Python:** Version 3.10 or higher\n\n## Environment Variables\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `OPENROUTER_API_KEY`, `OPENAI_API_KEY`, or `ANTHROPIC_API_KEY`: Required for your LLM provider (depending on which model you use)\n\n## Getting Started\n\n### Setup and Run\n\n1. Create and activate a virtual environment:\n\n```bash\npython3.10 -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n```\n\n2. Install dependencies:\n\n```bash\npip install -e .\n```\n\nTo also run `demo.py` (which plots results with matplotlib), install with the demo extra:\n\n```bash\npip install -e \".[demo]\"\n```\n\n3. Set your API keys in `.env` (copy from `.env.example`):\n\n```bash\ncp .env.example .env\n# Edit .env with your DAYTONA_API_KEY and LLM provider key\n```\n\n4. Run the example:\n\n```bash\npython demo.py\n```\n\n## How It Works\n\n### The REPL loop\n\nEach RLM call runs an iterative loop:\n\n1. RLM prompts the LLM with the task inputs and the REPL history so far\n2. The LLM responds with reasoning and a Python code snippet\n3. The code executes in the Daytona sandbox\n4. The output (stdout, errors, or a final result) is appended to the REPL history\n5. Steps 1–4 repeat until the code calls `SUBMIT()` or the iteration limit is reached\n\nState persists across iterations — variables, imports, and function definitions all carry over. This lets the LLM explore data incrementally, inspect intermediate results with `print()`, and refine its approach before committing a final answer.\n\n```\n         ┌──────────────────────────────────┐\n         │            DSPy RLM              │\n         │                                  │\n         │  Prompt LLM (inputs + history)   │\n         │         │                        │\n         │         ▼                        │\n         │  LLM writes Python code          │\n         │         │                        │\n         │         ▼                        │\n         │  Execute in sandbox ─────────────┼──▶ Daytona Sandbox\n         │         │                        │    (persistent REPL)\n         │         ▼                        │\n         │  Append output to history        │\n         │         │                        │\n         │         ▼                        │\n         │  SUBMIT() called? ──no──▶ loop   │\n         │         │                        │\n         │        yes                       │\n         │         ▼                        │\n         │  Return final answer             │\n         └──────────────────────────────────┘\n```\n\n### Sub-LLM calls\n\nThe generated code has access to two built-in functions for invoking an LLM from within the REPL:\n\n- `llm_query(prompt)` — send a single prompt, get a string back\n- `llm_query_batched(prompts)` — send multiple prompts concurrently\n\nThis is what makes RLM \"recursive\": the LLM can write code that delegates semantic work to another LLM call, then processes the result with Python. For example:\n\n```python\ntexts = [page1, page2, page3]\nsummaries = llm_query_batched([f\"Summarize: {t}\" for t in texts])\ncombined = \"\\n\".join(summaries)\nSUBMIT(answer=combined)\n```\n\nThese functions execute on the host (they need LLM API access). `DaytonaInterpreter` bridges them into the sandbox through the broker, the same mechanism used for custom tools.\n\n### Custom tools\n\nYou can pass host-side functions into the sandbox via the `tools` dict. The interpreter bridges them using a broker server that runs inside the sandbox:\n\n1. A Flask server starts inside the sandbox on port 3000\n2. For each tool, a wrapper function is injected into the sandbox that calls the broker over HTTP\n3. The host polls the broker for pending requests, executes the function, and posts the result back\n\nFrom the LLM's perspective, these look like regular Python functions.\n\n## Usage Examples\n\n### Basic: Reasoning with RLM\n\n```python\nimport dspy\nfrom dotenv import load_dotenv\nfrom daytona_interpreter import DaytonaInterpreter\n\nload_dotenv()\n\n# Configure the LLM\nlm = dspy.LM(\"openrouter/google/gemini-3-flash-preview\")\ndspy.configure(lm=lm)\n\n# Create an RLM with the Daytona interpreter\ninterpreter = DaytonaInterpreter()\n\nrlm = dspy.RLM(\n    signature=\"question -> answer: str\",\n    interpreter=interpreter,\n    verbose=True,\n)\n\nresult = rlm(question=\"What is the sum of the first 10 prime numbers?\")\nprint(result.answer)\n\ninterpreter.shutdown()\n```\n\n### With Custom Tools\n\nPass host-side functions into the sandbox so the LLM's generated code can call them:\n\n```python\nimport json\nimport dspy\nfrom dotenv import load_dotenv\nfrom daytona_interpreter import DaytonaInterpreter\n\nload_dotenv()\n\nlm = dspy.LM(\"openrouter/google/gemini-3-flash-preview\")\ndspy.configure(lm=lm)\n\n# Define tools that run on the host\ndef search_knowledge_base(query: str) -> str:\n    \"\"\"Search a knowledge base and return relevant results.\"\"\"\n    # Replace with your actual search logic\n    return json.dumps({\"results\": [f\"Result for: {query}\"]})\n\n# Pass tools to the interpreter\ninterpreter = DaytonaInterpreter(tools={\"search_knowledge_base\": search_knowledge_base})\n\nrlm = dspy.RLM(\n    signature=\"question -> answer: str\",\n    interpreter=interpreter,\n    verbose=True,\n)\n\nresult = rlm(question=\"Search for information about Python generators and summarize it.\")\nprint(result.answer)\n\ninterpreter.shutdown()\n```\n\nInside the sandbox, the LLM can call `search_knowledge_base(...)` like a regular function. The call is routed to the host through the broker. See [Custom tools](#custom-tools) for how this works.\n\n## Key Concepts\n\n### SUBMIT\n\n`SUBMIT()` ends the REPL loop and returns a final answer. Its arguments match the output fields of the DSPy signature:\n\n```python\nSUBMIT(answer=\"The sum is 129\")\n```\n\nIf the signature has typed output fields, `SUBMIT` gets a typed signature in the sandbox so the LLM knows the expected schema:\n\n```python\n# Automatically generated:\ndef SUBMIT(answer: str):\n    ...\n```\n\nIf the LLM never calls `SUBMIT()` within the iteration limit, RLM falls back to extracting an answer from the REPL history.\n\n### Broker\n\nThe broker is a small Flask server inside the sandbox that bridges function calls between the sandbox and the host. It handles both RLM's built-in `llm_query` / `llm_query_batched` and any custom tools you provide. It starts automatically when tools are present.\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [DSPy](https://dspy.ai/) — The framework for programming with foundation models\n- [Daytona](https://www.daytona.io/) — Secure cloud development environments\n- [Recursive Language Models](https://arxiv.org/abs/2512.24601) — Zhang, Kraska, Khattab\n"
  },
  {
    "path": "guides/python/dspy-rlms/daytona_interpreter.py",
    "content": "# Copyright Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport inspect\nimport json\nimport keyword\nimport logging\nimport math\nimport threading\nimport time\nimport urllib.error\nimport urllib.request\nimport uuid\nfrom concurrent.futures import Future, ThreadPoolExecutor\nfrom typing import Any, Callable\n\nfrom dspy.primitives.code_interpreter import CodeInterpreterError, FinalOutput\n\nlogger = logging.getLogger(__name__)\n\n\n# =============================================================================\n# DaytonaInterpreter - Implements CodeInterpreter protocol using Daytona\n# =============================================================================\n\n# Python setup code injected into the Daytona context.\n# Defines FinalOutput exception and SUBMIT function for early termination.\n_SETUP_CODE = '''\nimport json as _json\n\nclass FinalOutput(BaseException):\n    \"\"\"Control-flow exception to signal completion (like StopIteration).\"\"\"\n    pass\n\n_FINAL_OUTPUT_MARKER = \"__DSPY_FINAL_OUTPUT__\"\n\ndef SUBMIT(output=None, **kwargs):\n    \"\"\"Submit final output and terminate execution.\"\"\"\n    if kwargs:\n        result = kwargs\n    elif output is not None:\n        result = {\"output\": output}\n    else:\n        result = {}\n    # Encode the result so we can detect it in stdout\n    print(f\"{_FINAL_OUTPUT_MARKER}{_json.dumps(result)}{_FINAL_OUTPUT_MARKER}\")\n    raise FinalOutput(result)\n'''\n\n\n# Flask broker server code to be uploaded and run in the sandbox.\n# This server mediates tool calls between sandbox code and the host.\n_BROKER_SERVER_CODE = '''\n\"\"\"Broker server for mediating tool calls between sandbox and host.\"\"\"\nimport json\nimport threading\nimport time\nimport uuid\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n# Thread-safe storage for pending requests and results\n_lock = threading.Lock()\n_pending_requests = {}  # id -> {tool_name, args, kwargs, claimed, claimed_at, lease_token}\n_results = {}  # id -> result\n\n@app.route(\"/health\", methods=[\"GET\"])\ndef health():\n    \"\"\"Health check endpoint.\"\"\"\n    return jsonify({\"status\": \"ok\"})\n\n@app.route(\"/tool_call\", methods=[\"POST\"])\ndef tool_call():\n    \"\"\"Sandbox code calls this to request a tool execution.\n\n    Blocks until the host provides a result (polling with timeout).\n    \"\"\"\n    data = request.json\n    call_id = data.get(\"id\")\n    tool_name = data.get(\"tool_name\")\n    args = data.get(\"args\", [])\n    kwargs = data.get(\"kwargs\", {})\n\n    # Register the pending request\n    with _lock:\n        _pending_requests[call_id] = {\n            \"tool_name\": tool_name,\n            \"args\": args,\n            \"kwargs\": kwargs,\n            \"claimed\": False,\n            \"claimed_at\": None,\n            \"lease_token\": None,\n        }\n\n    # Poll for result (50ms interval, 2 minute timeout)\n    timeout = 120.0\n    interval = 0.05\n    elapsed = 0.0\n\n    while elapsed < timeout:\n        with _lock:\n            if call_id in _results:\n                result = _results.pop(call_id)\n                _pending_requests.pop(call_id, None)\n                return jsonify({\"result\": result})\n        time.sleep(interval)\n        elapsed += interval\n\n    # Timeout - clean up and return error\n    with _lock:\n        _pending_requests.pop(call_id, None)\n\n    return jsonify({\"error\": \"Tool call timeout\"}), 504\n\n@app.route(\"/pending\", methods=[\"GET\"])\ndef get_pending():\n    \"\"\"Host polls this to get pending tool requests.\n\n    Returns up to `max` requests. Claims use short leases so abandoned claims\n    can be recovered if a worker crashes before posting a result.\n    \"\"\"\n    try:\n        max_items = int(request.args.get(\"max\", \"1\"))\n    except ValueError:\n        max_items = 1\n    if max_items < 1:\n        max_items = 1\n    try:\n        lease_seconds = float(request.args.get(\"lease_seconds\", \"60\"))\n    except ValueError:\n        lease_seconds = 30.0\n    if lease_seconds < 1:\n        lease_seconds = 1.0\n\n    requests_out = []\n    with _lock:\n        now = time.time()\n        # Return up to `max` pending requests that don't have a result yet.\n        for call_id, req in _pending_requests.items():\n            if len(requests_out) >= max_items:\n                break\n            if call_id in _results:\n                continue\n            claimed_at = req.get(\"claimed_at\")\n            if req.get(\"claimed\") and isinstance(claimed_at, (int, float)):\n                if now - claimed_at < lease_seconds:\n                    continue\n            claim_token = str(uuid.uuid4())\n            req[\"claimed\"] = True\n            req[\"claimed_at\"] = now\n            req[\"lease_token\"] = claim_token\n            requests_out.append({\n                \"id\": call_id,\n                \"tool_name\": req[\"tool_name\"],\n                \"args\": req[\"args\"],\n                \"kwargs\": req[\"kwargs\"],\n                \"claim_token\": claim_token,\n            })\n    return jsonify({\"requests\": requests_out})\n\n@app.route(\"/result/<call_id>\", methods=[\"POST\"])\ndef post_result(call_id):\n    \"\"\"Host calls this to provide tool execution result for a valid claim.\"\"\"\n    data = request.json\n    result = data.get(\"result\")\n    claim_token = data.get(\"claim_token\")\n\n    with _lock:\n        req = _pending_requests.get(call_id)\n        if req is None:\n            return jsonify({\"error\": \"Unknown or expired call_id\"}), 404\n        expected_token = req.get(\"lease_token\")\n        if not expected_token or claim_token != expected_token:\n            return jsonify({\"error\": \"Stale or invalid claim token\"}), 409\n        _results[call_id] = result\n        # Invalidate the lease token so a late duplicate post is rejected.\n        req[\"lease_token\"] = None\n\n    return jsonify({\"status\": \"ok\"})\n\nif __name__ == \"__main__\":\n    app.run(host=\"0.0.0.0\", port=3000, threaded=True)\n'''\n\n\n# Template for generating tool wrapper functions in the sandbox\n_TOOL_WRAPPER_TEMPLATE = '''\ndef {tool_name}({signature}):\n    \"\"\"Wrapper for {tool_name} tool - calls host via broker.\"\"\"\n    import json as _json\n    import urllib.request as _urllib_request\n    import uuid as _uuid\n\n    call_id = str(_uuid.uuid4())\n    payload = _json.dumps({{\n        \"id\": call_id,\n        \"tool_name\": \"{tool_name}\",\n        \"args\": [{args_list}],\n        \"kwargs\": {{{kwargs_dict}}},\n    }}).encode(\"utf-8\")\n\n    req = _urllib_request.Request(\n        \"http://localhost:3000/tool_call\",\n        data=payload,\n        headers={{\"Content-Type\": \"application/json\"}},\n        method=\"POST\",\n    )\n\n    with _urllib_request.urlopen(req, timeout=130) as resp:\n        data = _json.loads(resp.read().decode(\"utf-8\"))\n\n    if \"error\" in data:\n        raise RuntimeError(f\"Tool call failed: {{data['error']}}\")\n\n    result = data.get(\"result\")\n    # Try to parse JSON result, otherwise return as-is\n    if isinstance(result, str):\n        try:\n            return _json.loads(result)\n        except (ValueError, _json.JSONDecodeError):\n            return result\n    return result\n'''\n\n\nclass DaytonaInterpreter:\n    \"\"\"Remote interpreter using Daytona sandbox for Python execution.\n\n    Implements the CodeInterpreter protocol for secure code execution in a\n    Daytona cloud sandbox. The sandbox provides isolated execution with\n    persistent state across calls.\n\n    Prerequisites:\n        - Daytona SDK: pip install daytona\n        - DAYTONA_API_KEY environment variable set\n\n    Example:\n        ```python\n        # Basic execution\n        with DaytonaInterpreter() as interp:\n            result = interp.execute(\"print(1 + 2)\")  # Returns \"3\"\n        ```\n    \"\"\"\n\n    def __init__(\n        self,\n        tools: dict[str, Callable[..., str]] | None = None,\n        output_fields: list[dict] | None = None,\n        sandbox_params: dict[str, Any] | None = None,\n        max_concurrent_tool_calls: int = 32,\n        tool_claim_lease_seconds: float = 60.0,\n        max_retries: int = 3,\n        retry_delay: float = 2.0,\n    ) -> None:\n        \"\"\"\n        Args:\n            tools: Dictionary mapping tool names to callable functions.\n            output_fields: List of output field definitions for typed SUBMIT signature.\n            sandbox_params: Optional parameters to pass to Daytona sandbox creation.\n            max_concurrent_tool_calls: Maximum host-side parallel tool workers.\n            tool_claim_lease_seconds: Claim lease duration used by broker recovery.\n            max_retries: Max attempts for transient errors (e.g. WebSocket drops).\n            retry_delay: Seconds to wait between retries.\n        \"\"\"\n        self.tools = dict(tools) if tools else {}\n        self.output_fields = output_fields\n        self.sandbox_params = sandbox_params or {}\n        if max_concurrent_tool_calls < 1:\n            raise ValueError(\"max_concurrent_tool_calls must be >= 1\")\n        if tool_claim_lease_seconds < 1:\n            raise ValueError(\"tool_claim_lease_seconds must be >= 1\")\n        if max_retries < 1:\n            raise ValueError(\"max_retries must be >= 1\")\n        self.max_concurrent_tool_calls = max_concurrent_tool_calls\n        self.tool_claim_lease_seconds = float(tool_claim_lease_seconds)\n        self._max_retries = max_retries\n        self._retry_delay = float(retry_delay)\n\n        self._daytona = None\n        self._sandbox = None\n        self._context = None\n        self._initialized = False\n        self._session_execute_request = None\n\n        # Broker-related state\n        self._broker_url = None  # Preview URL for broker (e.g., https://xxx.preview.daytona.work)\n        self._broker_token = None  # Auth token for preview URL\n        self._broker_session_id = None  # Session ID for the broker process\n\n        # Track which tools have been injected into the sandbox so we can\n        # detect when RLM (or the user) adds new ones after start().\n        self._injected_tools: set[str] = set()\n\n        # Track whether typed SUBMIT has been registered, so we can detect\n        # when RLM sets output_fields after start().\n        self._submit_registered: bool = False\n\n    @property\n    def _final_output_marker(self) -> str:\n        return \"__DSPY_FINAL_OUTPUT__\"\n\n    def start(self) -> None:\n        \"\"\"Initialize the Daytona sandbox and interpreter context.\"\"\"\n        if self._initialized:\n            return\n\n        try:\n            from daytona import Daytona, SessionExecuteRequest  # pylint: disable=import-outside-toplevel\n\n            self._session_execute_request = SessionExecuteRequest\n        except ImportError as exc:\n            raise CodeInterpreterError(\n                \"Daytona not installed. Install with: pip install daytona\\n\"\n                \"Also ensure DAYTONA_API_KEY environment variable is set.\"\n            ) from exc\n\n        logger.info(\"Creating Daytona sandbox...\")\n        self._daytona = Daytona()\n        self._sandbox = self._daytona.create(**self.sandbox_params)\n        logger.info(\"Sandbox created: %s\", self._sandbox.id)\n\n        # Create isolated interpreter context\n        self._context = self._sandbox.code_interpreter.create_context()\n        logger.info(\"Interpreter context created: %s\", self._context.id)\n\n        # Run setup code to define SUBMIT and FinalOutput\n        self._run_setup_code()\n\n        # Start broker and inject tools if we have any at init time.\n        # Tools may also be added later (e.g. RLM injects llm_query after\n        # start), so execute() checks for new tools on every call.\n        if self.tools:\n            self._start_broker()\n            self._inject_tool_wrappers()\n\n        self._initialized = True\n\n    def _run_setup_code(self) -> None:\n        \"\"\"Run initialization code in the sandbox context.\"\"\"\n        result = self._sandbox.code_interpreter.run_code(\n            _SETUP_CODE,\n            context=self._context,\n        )\n        if result.error:\n            raise CodeInterpreterError(f\"Failed to initialize sandbox: {result.error.value}\")\n\n        # If we have typed output fields, override SUBMIT with typed signature\n        self._register_typed_submit()\n\n    def _register_typed_submit(self) -> None:\n        \"\"\"Register typed SUBMIT if output_fields are set and not yet registered.\"\"\"\n        if not self.output_fields or self._submit_registered:\n            return\n        submit_code = self._generate_typed_submit()\n        result = self._sandbox.code_interpreter.run_code(\n            submit_code,\n            context=self._context,\n        )\n        if result.error:\n            raise CodeInterpreterError(f\"Failed to register SUBMIT: {result.error.value}\")\n        self._submit_registered = True\n        logger.info(\"Registered typed SUBMIT with fields: %s\", [f[\"name\"] for f in self.output_fields])\n\n    def _generate_typed_submit(self) -> str:\n        \"\"\"Generate SUBMIT function with typed output field signature.\"\"\"\n        if not self.output_fields:\n            return \"\"\n\n        sig_parts = []\n        for field in self.output_fields:\n            part = field[\"name\"]\n            if \"type\" in field:\n                part += f\": {field['type']}\"\n            sig_parts.append(part)\n\n        dict_parts = [f'\"{f[\"name\"]}\": {f[\"name\"]}' for f in self.output_fields]\n\n        return f'''\ndef SUBMIT({\", \".join(sig_parts)}):\n    \"\"\"Submit final output and terminate execution.\"\"\"\n    result = {{{\", \".join(dict_parts)}}}\n    print(f\"{{_FINAL_OUTPUT_MARKER}}{{_json.dumps(result)}}{{_FINAL_OUTPUT_MARKER}}\")\n    raise FinalOutput(result)\n'''\n\n    def _start_broker(self) -> None:\n        \"\"\"Upload and start the broker server in the sandbox.\"\"\"\n        if not self.tools:\n            return  # No tools, no broker needed\n\n        logger.info(\"Starting broker server in sandbox...\")\n\n        # Write broker server code to sandbox using code_interpreter\n        write_code = f\"\"\"\nimport os\nbroker_code = {repr(_BROKER_SERVER_CODE)}\nwith open(\"/home/daytona/broker_server.py\", \"w\") as f:\n    f.write(broker_code)\nprint(\"Broker server code written\")\n\"\"\"\n        result = self._sandbox.code_interpreter.run_code(write_code, context=self._context)\n        if result.error:\n            raise CodeInterpreterError(f\"Failed to write broker server: {result.error.value}\")\n\n        # Start broker server as background process\n        self._broker_session_id = f\"broker-{uuid.uuid4().hex[:8]}\"\n        self._sandbox.process.create_session(self._broker_session_id)\n        self._sandbox.process.execute_session_command(\n            self._broker_session_id,\n            self._session_execute_request(\n                command=\"cd /home/daytona && python broker_server.py\",\n                run_async=True,\n            ),\n        )\n\n        # Get preview link for port 3000\n        preview = self._sandbox.get_preview_link(3000)\n        self._broker_url = preview.url\n        self._broker_token = preview.token\n        logger.info(\"Broker preview URL: %s\", self._broker_url)\n\n        # Wait for broker to be ready\n        self._wait_for_broker_health()\n\n    def _wait_for_broker_health(self, timeout: float = 30.0) -> None:\n        \"\"\"Poll broker health endpoint until ready.\"\"\"\n        url = f\"{self._broker_url}/health\"\n        headers = {\"x-daytona-preview-token\": self._broker_token}\n\n        start_time = time.time()\n        while time.time() - start_time < timeout:\n            try:\n                req = urllib.request.Request(url, headers=headers, method=\"GET\")\n                with urllib.request.urlopen(req, timeout=5) as resp:\n                    if resp.status == 200:\n                        logger.info(\"Broker server is ready\")\n                        return\n            except (urllib.error.URLError, urllib.error.HTTPError, OSError):\n                pass\n            time.sleep(0.5)\n\n        raise CodeInterpreterError(\"Broker server failed to start within timeout\")\n\n    def _inject_tool_wrappers(self) -> None:\n        \"\"\"Inject tool wrapper functions into the sandbox context.\n\n        Only injects tools that haven't been injected yet, so this is safe\n        to call repeatedly (e.g. after RLM adds llm_query / llm_query_batched).\n        \"\"\"\n        if not self.tools:\n            return\n\n        for tool_name, tool_func in self.tools.items():\n            if tool_name in self._injected_tools:\n                continue\n            if not tool_name.isidentifier() or keyword.iskeyword(tool_name):\n                raise CodeInterpreterError(f\"Invalid tool name: '{tool_name}'\")\n            wrapper_code = self._generate_tool_wrapper(tool_name, tool_func)\n            result = self._sandbox.code_interpreter.run_code(\n                wrapper_code,\n                context=self._context,\n            )\n            if result.error:\n                raise CodeInterpreterError(f\"Failed to inject tool '{tool_name}': {result.error.value}\")\n            self._injected_tools.add(tool_name)\n            logger.info(\"Injected tool wrapper: %s\", tool_name)\n\n    def _generate_tool_wrapper(self, tool_name: str, tool_func: Callable) -> str:\n        \"\"\"Generate a wrapper function for a tool that calls the broker.\"\"\"\n        sig = inspect.signature(tool_func)\n        params = list(sig.parameters.values())\n\n        # Build signature parts\n        sig_parts = []\n        args_list = []\n        kwargs_dict = []\n        last_positional_only_idx = max(\n            (i for i, param in enumerate(params) if param.kind == inspect.Parameter.POSITIONAL_ONLY),\n            default=-1,\n        )\n        added_kw_only_separator = False\n\n        def format_param(param: inspect.Parameter) -> str:\n            if param.default is inspect.Parameter.empty:\n                return param.name\n            return f\"{param.name}={repr(param.default)}\"\n\n        for i, param in enumerate(params):\n            if param.kind == inspect.Parameter.POSITIONAL_ONLY:\n                sig_parts.append(format_param(param))\n                args_list.append(param.name)\n                if i == last_positional_only_idx:\n                    sig_parts.append(\"/\")\n            elif param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD:\n                sig_parts.append(format_param(param))\n                if param.default is inspect.Parameter.empty:\n                    args_list.append(param.name)\n                else:\n                    kwargs_dict.append(f'\"{param.name}\": {param.name}')\n            elif param.kind == inspect.Parameter.VAR_POSITIONAL:\n                sig_parts.append(f\"*{param.name}\")\n                # *args gets passed as args list\n                args_list.append(f\"*{param.name}\")\n                added_kw_only_separator = True\n            elif param.kind == inspect.Parameter.KEYWORD_ONLY:\n                if not added_kw_only_separator:\n                    sig_parts.append(\"*\")\n                    added_kw_only_separator = True\n                sig_parts.append(format_param(param))\n                kwargs_dict.append(f'\"{param.name}\": {param.name}')\n            elif param.kind == inspect.Parameter.VAR_KEYWORD:\n                sig_parts.append(f\"**{param.name}\")\n                # **kwargs gets merged\n                kwargs_dict.append(f\"**{param.name}\")\n            else:\n                raise CodeInterpreterError(f\"Unsupported parameter kind for tool '{tool_name}': {param.kind}\")\n\n        signature = \", \".join(sig_parts)\n        args_str = \", \".join(args_list)\n        kwargs_str = \", \".join(kwargs_dict)\n\n        return _TOOL_WRAPPER_TEMPLATE.format(\n            tool_name=tool_name,\n            signature=signature,\n            args_list=args_str,\n            kwargs_dict=kwargs_str,\n        )\n\n    def _poll_and_execute_tools(self, code_done_event: threading.Event) -> None:\n        \"\"\"Poll for pending tool requests and execute them on the host.\"\"\"\n        headers = {\"x-daytona-preview-token\": self._broker_token}\n        lease_seconds = self.tool_claim_lease_seconds\n\n        def fetch_pending(max_items: int) -> list[dict[str, Any]]:\n            url_pending = f\"{self._broker_url}/pending?max={max_items}&lease_seconds={lease_seconds}\"\n            req = urllib.request.Request(url_pending, headers=headers, method=\"GET\")\n            with urllib.request.urlopen(req, timeout=5) as resp:\n                data = json.loads(resp.read().decode(\"utf-8\"))\n            if isinstance(data, dict) and isinstance(data.get(\"requests\"), list):\n                return [r for r in data[\"requests\"] if isinstance(r, dict) and \"id\" in r]\n            if isinstance(data, dict) and \"id\" in data:\n                return [data]\n            return []\n\n        def execute_one(pending: dict[str, Any]) -> None:\n            call_id = pending[\"id\"]\n            tool_name = pending[\"tool_name\"]\n            args = pending.get(\"args\", [])\n            kwargs = pending.get(\"kwargs\", {})\n            claim_token = pending.get(\"claim_token\")\n\n            logger.info(\"Executing tool on host: %s(%s, %s)\", tool_name, args, kwargs)\n\n            try:\n                tool_func = self.tools.get(tool_name)\n                if tool_func is None:\n                    result = json.dumps({\"error\": f\"Unknown tool: {tool_name}\"})\n                else:\n                    result = tool_func(*args, **kwargs)\n                    if not isinstance(result, str):\n                        result = json.dumps(result)\n            except Exception as e:\n                result = json.dumps({\"error\": str(e)})\n\n            logger.info(\"Tool result for %s: %.500s\", tool_name, result)\n\n            url_result = f\"{self._broker_url}/result/{call_id}\"\n            payload = json.dumps({\"result\": result, \"claim_token\": claim_token}).encode(\"utf-8\")\n            req = urllib.request.Request(\n                url_result,\n                data=payload,\n                headers={**headers, \"Content-Type\": \"application/json\"},\n                method=\"POST\",\n            )\n            try:\n                with urllib.request.urlopen(req, timeout=5):\n                    pass\n            except urllib.error.HTTPError as e:\n                # Expected when this worker's lease expired and another worker took over.\n                if e.code in (404, 409):\n                    logger.info(\"Discarded stale tool result for call %s (HTTP %s)\", call_id, e.code)\n                    return\n                raise\n\n            logger.info(\"Tool result posted for call %s\", call_id)\n\n        inflight: dict[str, Future[None]] = {}\n\n        with ThreadPoolExecutor(max_workers=self.max_concurrent_tool_calls) as executor:\n            while not code_done_event.is_set() or inflight:\n                for call_id, fut in list(inflight.items()):\n                    if not fut.done():\n                        continue\n                    inflight.pop(call_id, None)\n                    try:\n                        fut.result()\n                    except Exception as e:\n                        logger.warning(\"Tool execution failed for call %s: %s\", call_id, e)\n\n                if code_done_event.is_set():\n                    time.sleep(0.01)\n                    continue\n\n                capacity = self.max_concurrent_tool_calls - len(inflight)\n                if capacity > 0:\n                    try:\n                        for pending in fetch_pending(capacity):\n                            call_id = pending.get(\"id\")\n                            if not call_id or call_id in inflight:\n                                continue\n                            inflight[call_id] = executor.submit(execute_one, pending)\n                    except (urllib.error.URLError, urllib.error.HTTPError, OSError):\n                        pass\n                    except Exception as e:\n                        logger.warning(\"Error in tool polling loop: %s\", e)\n\n                time.sleep(0.05)\n\n    def _inject_variables(self, code: str, variables: dict[str, Any]) -> str:\n        \"\"\"Insert Python assignments for each variable at the top of the code.\"\"\"\n        if not variables:\n            return code\n\n        for key in variables:\n            if not key.isidentifier() or keyword.iskeyword(key):\n                raise CodeInterpreterError(f\"Invalid variable name: '{key}'\")\n\n        assignments = [f\"{k} = {self._serialize_value(v)}\" for k, v in variables.items()]\n        return \"\\n\".join(assignments) + \"\\n\" + code\n\n    def _serialize_value(self, value: Any) -> str:\n        \"\"\"Convert a Python value to a string that can be evaluated.\"\"\"\n\n        # Use Python literals (not JSON) so nested bool/None serialize correctly.\n        def to_literal(obj: Any) -> str:\n            if obj is None:\n                return \"None\"\n            if isinstance(obj, bool):\n                return \"True\" if obj else \"False\"\n            if isinstance(obj, int):\n                return repr(obj)\n            if isinstance(obj, float):\n                if math.isnan(obj):\n                    return \"float('nan')\"\n                if math.isinf(obj):\n                    return \"float('inf')\" if obj > 0 else \"float('-inf')\"\n                return repr(obj)\n            if isinstance(obj, str):\n                return repr(obj)\n            if isinstance(obj, list):\n                return \"[\" + \", \".join(to_literal(v) for v in obj) + \"]\"\n            if isinstance(obj, tuple):\n                inner = \", \".join(to_literal(v) for v in obj)\n                if len(obj) == 1:\n                    inner += \",\"\n                return \"(\" + inner + \")\"\n            if isinstance(obj, set):\n                if not obj:\n                    return \"set()\"\n                return \"{\" + \", \".join(to_literal(v) for v in obj) + \"}\"\n            if isinstance(obj, dict):\n                parts = []\n                for k, v in obj.items():\n                    parts.append(f\"{to_literal(k)}: {to_literal(v)}\")\n                return \"{\" + \", \".join(parts) + \"}\"\n            raise CodeInterpreterError(f\"Unsupported value type: {type(obj).__name__}\")\n\n        try:\n            return to_literal(value)\n        except TypeError as exc:\n            raise CodeInterpreterError(f\"Unsupported value type: {type(value).__name__}\") from exc\n\n    def execute(\n        self,\n        code: str,\n        variables: dict[str, Any] | None = None,\n    ) -> Any:\n        \"\"\"Execute Python code in the Daytona sandbox.\n\n        Args:\n            code: Python code to execute.\n            variables: Variables to inject into the namespace before execution.\n\n        Returns:\n            One of:\n            - FinalOutput: If SUBMIT() was called in code\n            - str: Captured stdout from print() statements\n            - None: If no output was produced\n\n        Raises:\n            CodeInterpreterError: On runtime errors\n            SyntaxError: On invalid Python syntax\n        \"\"\"\n        if not self._initialized:\n            self.start()\n\n        if variables:\n            code = self._inject_variables(code, variables)\n\n        # RLM sets output_fields after start(), so register typed SUBMIT\n        # lazily on first execute() that has them.\n        self._register_typed_submit()\n\n        # RLM (and users) can add tools to self.tools after start().\n        # For example, RLM injects llm_query and llm_query_batched before\n        # each execution via interpreter.tools.update(...).  We lazily\n        # start the broker on first use and inject any new wrappers.\n        if self.tools:\n            if not self._broker_url:\n                self._start_broker()\n            new_tools = set(self.tools) - self._injected_tools\n            if new_tools:\n                self._inject_tool_wrappers()\n\n        # If we have tools, run with polling loop; otherwise run directly\n        last_error: Exception | None = None\n        for attempt in range(1, self._max_retries + 1):\n            try:\n                if self.tools and self._broker_url:\n                    return self._execute_with_tools(code)\n                return self._execute_direct(code)\n            except (CodeInterpreterError, SyntaxError):\n                raise\n            except Exception as e:\n                if attempt < self._max_retries and self._is_transient_error(e):\n                    logger.warning(\n                        \"Transient error on attempt %d/%d, retrying in %.1fs: %s\",\n                        attempt,\n                        self._max_retries,\n                        self._retry_delay,\n                        e,\n                    )\n                    last_error = e\n                    time.sleep(self._retry_delay)\n                    continue\n                raise\n\n        raise last_error  # type: ignore[misc]  # unreachable but keeps mypy happy\n\n    @staticmethod\n    def _is_transient_error(error: Exception) -> bool:\n        \"\"\"Return True if the error looks like a transient connection issue.\"\"\"\n        msg = str(error).lower()\n        return any(\n            phrase in msg\n            for phrase in [\n                \"keepalive ping timeout\",\n                \"ping timeout\",\n                \"connection reset\",\n                \"broken pipe\",\n                \"close code 1011\",\n            ]\n        )\n\n    def _execute_direct(self, code: str) -> Any:\n        \"\"\"Execute code directly without tool support.\"\"\"\n        stdout_parts = []\n\n        def on_stdout(msg):\n            stdout_parts.append(msg.output)\n\n        stderr_parts = []\n\n        def on_stderr(msg):\n            stderr_parts.append(msg.output)\n\n        result = self._sandbox.code_interpreter.run_code(\n            code,\n            context=self._context,\n            on_stdout=on_stdout,\n            on_stderr=on_stderr,\n            timeout=0,\n        )\n\n        stdout = \"\".join(stdout_parts)\n        return self._process_result(result, stdout)\n\n    def _execute_with_tools(self, code: str) -> Any:\n        \"\"\"Execute code with tool polling support.\"\"\"\n        # Storage for results from the code execution thread\n        execution_result = {\"result\": None, \"stdout\": \"\", \"error\": None}\n        code_done_event = threading.Event()\n\n        stdout_parts = []\n\n        def on_stdout(msg):\n            stdout_parts.append(msg.output)\n\n        stderr_parts = []\n\n        def on_stderr(msg):\n            stderr_parts.append(msg.output)\n\n        def run_code():\n            try:\n                result = self._sandbox.code_interpreter.run_code(\n                    code,\n                    context=self._context,\n                    on_stdout=on_stdout,\n                    on_stderr=on_stderr,\n                    timeout=0,\n                )\n                execution_result[\"result\"] = result\n                execution_result[\"stdout\"] = \"\".join(stdout_parts)\n            except Exception as e:\n                execution_result[\"error\"] = e\n            finally:\n                code_done_event.set()\n\n        # Start code execution in background thread\n        code_thread = threading.Thread(target=run_code)\n        code_thread.start()\n\n        # Poll for tool calls while code is running\n        self._poll_and_execute_tools(code_done_event)\n\n        # Wait for code thread to finish\n        code_thread.join()\n\n        # Check for thread-level errors\n        err = execution_result[\"error\"]\n        if err is not None:\n            raise err\n\n        return self._process_result(\n            execution_result[\"result\"],\n            execution_result[\"stdout\"],\n        )\n\n    def _process_result(self, result, stdout: str) -> Any:\n        \"\"\"Process execution result and return appropriate output.\"\"\"\n        # Check for FinalOutput marker in stdout\n        if self._final_output_marker in stdout:\n            return self._extract_final_output(stdout)\n\n        # Check for errors\n        if result.error:\n            error_name = result.error.name\n            error_value = result.error.value\n\n            if error_name == \"FinalOutput\":\n                return self._extract_final_output(stdout)\n\n            if error_name == \"SyntaxError\":\n                raise SyntaxError(f\"Invalid Python syntax: {error_value}\")\n            raise CodeInterpreterError(f\"{error_name}: {error_value}\")\n\n        return stdout.strip() if stdout.strip() else None\n\n    def _extract_final_output(self, stdout: str) -> FinalOutput:\n        \"\"\"Extract FinalOutput from stdout containing the marker.\"\"\"\n        marker = self._final_output_marker\n        start = stdout.find(marker)\n        if start == -1:\n            return FinalOutput({})\n\n        start += len(marker)\n        end = stdout.find(marker, start)\n        if end == -1:\n            return FinalOutput({})\n\n        json_str = stdout[start:end]\n        try:\n            output = json.loads(json_str)\n            return FinalOutput(output)\n        except json.JSONDecodeError:\n            return FinalOutput({})\n\n    def shutdown(self) -> None:\n        \"\"\"Release resources and delete the Daytona sandbox.\"\"\"\n        # Delete broker session if running\n        if self._broker_session_id and self._sandbox:\n            try:\n                self._sandbox.process.delete_session(self._broker_session_id)\n                logger.info(\"Deleted broker session\")\n            except Exception as e:\n                logger.warning(\"Failed to delete broker session: %s\", e)\n\n        if self._context and self._sandbox:\n            try:\n                self._sandbox.code_interpreter.delete_context(self._context)\n                logger.info(\"Deleted interpreter context\")\n            except Exception as e:\n                logger.warning(\"Failed to delete context: %s\", e)\n\n        if self._sandbox:\n            try:\n                self._sandbox.delete()\n                logger.info(\"Deleted sandbox\")\n            except Exception as e:\n                logger.warning(\"Failed to delete sandbox: %s\", e)\n\n        self._context = None\n        self._sandbox = None\n        self._daytona = None\n        self._initialized = False\n        self._broker_url = None\n        self._broker_token = None\n        self._broker_session_id = None\n        self._injected_tools = set()\n        self._submit_registered = False\n\n    def __enter__(self):\n        self.start()\n        return self\n\n    def __exit__(self, *_):\n        self.shutdown()\n\n    def __call__(self, code: str, variables: dict[str, Any] | None = None) -> Any:\n        return self.execute(code, variables)\n"
  },
  {
    "path": "guides/python/dspy-rlms/demo.py",
    "content": "# Copyright Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport json\nimport logging\nimport re\nimport urllib.request\nfrom collections import defaultdict\nfrom pathlib import Path\n\nimport dspy\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom daytona_interpreter import DaytonaInterpreter\nfrom dotenv import load_dotenv\n\nload_dotenv(override=True)\n\nlogging.basicConfig(level=logging.INFO)\n\n# ── Fetch and split the novel ────────────────────────────────────────────────\n\nGUTENBERG_URL = \"https://www.gutenberg.org/cache/epub/1184/pg1184.txt\"\nCACHE_PATH = Path(__file__).parent / \"monte_cristo.txt\"\n\n\ndef fetch_chapters() -> list[str]:\n    \"\"\"Download The Count of Monte Cristo and split into chapters.\"\"\"\n    if CACHE_PATH.exists():\n        text = CACHE_PATH.read_text(encoding=\"utf-8\")\n    else:\n        with urllib.request.urlopen(GUTENBERG_URL) as resp:\n            text = resp.read().decode(\"utf-8\")\n        CACHE_PATH.write_text(text, encoding=\"utf-8\")\n\n    # Strip Project Gutenberg header/footer.\n    # \"Chapter 1.\" appears twice: once in the table of contents and once\n    # at the actual start of the narrative.  Skip the TOC by searching\n    # from after the first occurrence.\n    first = text.find(\"Chapter 1.\")\n    start = text.find(\"Chapter 1.\", first + 1)\n    if start == -1:\n        start = first  # fallback if only one occurrence\n    end = text.rfind(\"*** END OF THE PROJECT GUTENBERG EBOOK\")\n    if end == -1:\n        end = len(text)\n    text = text[start:end]\n\n    # Split on chapter headings like \" Chapter 1. Marseilles—The Arrival\"\n    parts = re.split(r\"(?:^|\\n)\\s*Chapter \\d+\\.\", text)\n    # First element is empty (before Chapter 1), rest are chapter bodies\n    # Re-attach chapter numbers for context\n    chapter_list = []\n    for i, body in enumerate(parts[1:], start=1):\n        chapter_list.append(f\"Chapter {i}.{body}\")\n\n    return chapter_list\n\n\n# ── Configure DSPy ───────────────────────────────────────────────────────────\n\nlm = dspy.LM(\"openrouter/google/gemini-3-flash-preview\")\ndspy.configure(lm=lm)\n\n# ── Run RLM analysis ────────────────────────────────────────────────────────\n\ninterpreter = DaytonaInterpreter()\n\nrlm = dspy.RLM(\n    signature=\"chapters: list[str], task: str -> wealth_data: list[dict]\",\n    interpreter=interpreter,\n    max_iterations=40,\n    max_llm_calls=500,\n    verbose=True,\n)\n\nchapters = fetch_chapters()\nprint(f\"Fetched {len(chapters)} chapters\")\n\nTASK = (\n    \"Analyze the economic trajectory of each major character across the novel. \"\n    \"For each chapter where a character's wealth status is mentioned or implied, \"\n    \"produce a dict with keys: chapter (int), character (str), wealth (int 1-10 \"\n    \"where 1=destitute and 10=richest in Paris), and event (str, brief description \"\n    \"of what changed). Track the following characters: Dantès, Danglars, Fernand/\"\n    \"Morcerf, Villefort, and Mercédès. You need to cover each chapter in the book.\"\n)\n\nWEALTH_DATA_PATH = Path(__file__).parent / \"wealth_data.json\"\n\ntry:\n    result = rlm(chapters=chapters, task=TASK)\n    wealth_data = result.wealth_data\n    WEALTH_DATA_PATH.write_text(json.dumps(wealth_data, indent=2), encoding=\"utf-8\")\n    print(f\"Saved {len(wealth_data)} entries to {WEALTH_DATA_PATH}\")\nexcept Exception:\n    logging.exception(\"RLM analysis failed\")\n    raise\nfinally:\n    interpreter.shutdown()\n\n# ── Plot ─────────────────────────────────────────────────────────────────────\n\n# Group by character\nseries = defaultdict(lambda: ([], []))\nfor row in wealth_data:\n    xs, ys = series[row[\"character\"]]\n    xs.append(row[\"chapter\"])\n    ys.append(row[\"wealth\"])\n\nprint(f\"\\n{len(wealth_data)} data points across {len(series)} characters\")\n\nCHARACTER_COLORS = {\n    \"Dantès\": \"#e0e0e0\",\n    \"Danglars\": \"#f25c78\",\n    \"Fernand/Morcerf\": \"#f0b840\",\n    \"Villefort\": \"#58c4a7\",\n    \"Mercédès\": \"#b48eed\",\n}\n\n\ndef smooth(values, window=7):\n    if len(values) < window:\n        return np.array(values, dtype=float)\n    kernel = np.ones(window) / window\n    padded = np.pad(values, (window // 2, window // 2), mode=\"edge\")\n    return np.convolve(padded, kernel, mode=\"valid\")\n\n\nplt.style.use(\"dark_background\")\nplt.rcParams.update(\n    {\n        \"font.family\": \"serif\",\n        \"font.size\": 14,\n        \"axes.spines.top\": False,\n        \"axes.spines.right\": False,\n        \"axes.facecolor\": \"#0d1117\",\n        \"figure.facecolor\": \"#0d1117\",\n    }\n)\n\nfig, ax = plt.subplots(figsize=(14, 9))\n\nfor char, (xs, ys) in sorted(series.items()):\n    color = CHARACTER_COLORS.get(char, \"#888888\")\n    ys_arr = np.array(ys, dtype=float)\n    ys_smooth = smooth(ys_arr)\n    ax.plot(xs, ys_smooth, linewidth=2.2, color=color, label=char, zorder=3)\n    ax.scatter(xs, ys_arr, s=8, color=color, alpha=0.25, zorder=2)\n\nax.set_yticks([1, 10])\nax.set_yticklabels([\"Destitute\", \"Richest\\nin Paris\"], fontsize=13)\nax.set_ylim(0.5, 10.5)\n\nax.set_xlim(1, 117)\nax.set_xticks(range(1, 117, 10))\nax.set_xlabel(\"Chapter\", fontsize=15)\n\nax.yaxis.grid(True, alpha=0.1, linestyle=\"--\", color=\"#ffffff\")\nax.xaxis.grid(False)\n\nax.set_title(\"The Count of Monte Cristo — Character Wealth Trajectories\", fontsize=18, fontweight=\"bold\", pad=14)\n\nax.legend(\n    loc=\"upper left\",\n    frameon=True,\n    framealpha=0.6,\n    fancybox=True,\n    edgecolor=\"#333333\",\n    fontsize=13,\n    ncol=1,\n    bbox_to_anchor=(0.01, 0.93),\n)\n\nplt.tight_layout()\nplt.savefig(\"wealth_trajectories.png\", dpi=180, bbox_inches=\"tight\")\nprint(\"\\nSaved wealth_trajectories.png\")\nplt.show()\n"
  },
  {
    "path": "guides/python/dspy-rlms/pyproject.toml",
    "content": "[project]\nname = \"dspy-rlms\"\nversion = \"0.1.0\"\ndescription = \"DSPy Recursive Language Models with Daytona sandboxed code execution\"\nreadme = \"README.md\"\nrequires-python = \">=3.10\"\ndependencies = [\n    \"dspy>=2.6.0\",\n    \"daytona>=0.136.0\",\n    \"python-dotenv>=1.0.0\",\n]\n\n[project.optional-dependencies]\ndemo = [\n    \"matplotlib>=3.8.0\",\n]\n\n[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[tool.setuptools]\npy-modules = [\"daytona_interpreter\"]\n"
  },
  {
    "path": "guides/python/google-adk/code-generator-agent/gemini/.gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# Virtual Environments\nvenv/\nenv/\nENV/\nenv.bak/\nvenv.bak/\n.venv/\n.virtualenv/\n.pyenv/\n\n# Poetry\npoetry.lock\n.poetry/\n\n# Pipenv\nPipfile.lock\n\n# pyenv\n.python-version\n\n# Conda\nconda-meta/\n.conda/\n\n# PyCharm\n.idea/\n*.iml\n\n# VS Code\n.vscode/\n*.code-workspace\n\n# Jupyter Notebook\n.ipynb_checkpoints/\n*.ipynb_checkpoints/\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.env.local\n.env.*.local\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# macOS\n.DS_Store\n\n# Windows\nThumbs.db\nehthumbs.db\nDesktop.ini\n\n# Linux\n*~\n\n# Temporary files\n*.tmp\n*.bak\n*.swp\n*~\n\n# Example Data & Generated Outputs\n*.csv\n*.xlsx\n*.xls\n*.json\n*.parquet\n*.png\n*.jpg\n*.jpeg\n*.gif\n*.svg\n*.pdf\n\n"
  },
  {
    "path": "guides/python/google-adk/code-generator-agent/gemini/README.md",
    "content": "# Code Generator Agent Example (Google ADK + Daytona)\n\n## Overview\n\nThis example demonstrates how to build a [Google ADK](https://google.github.io/adk-docs/) agent that generates and verifies code using [Daytona](https://daytona.io) sandboxes. The agent uses the `DaytonaPlugin` to execute code in an isolated environment, enabling automated code generation workflows with built-in testing.\n\nIn this example, the agent is tasked with writing a TypeScript `groupBy` function that takes an array and a key function, then groups array elements by the key. The agent generates the implementation, creates test cases, executes them in the sandbox, and iterates until all tests pass before returning the verified code.\n\n## Features\n\n- **Secure sandbox execution:** All code runs in isolated Daytona sandboxes\n- **Multi-language support:** Generate code in Python, JavaScript, or TypeScript\n- **Automatic testing:** Agent creates and runs tests to verify implementations\n- **Iterative refinement:** Agent fixes code until tests pass before responding\n- **Natural language interface:** Describe your function in plain English\n\n## Requirements\n\n- **Python:** Version 3.10 or higher is required\n\n> [!TIP]\n> It's recommended to use a virtual environment (`venv` or `poetry`) to isolate project dependencies.\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `GOOGLE_API_KEY`: Required for Gemini model access. Get it from [Google AI Studio](https://aistudio.google.com/apikey)\n\nSee the `.env.example` file for the exact structure. Copy `.env.example` to `.env` and fill in your API keys before running.\n\n## Getting Started\n\nBefore proceeding, complete the following steps:\n\n1. Ensure Python 3.10 or higher is installed\n2. Copy `.env.example` to `.env` and add your API keys\n\n### Setup and Run\n\n1. Create and activate a virtual environment:\n\n   ```bash\n   python3.10 -m venv venv\n   source venv/bin/activate  # On Windows: venv\\Scripts\\activate\n   ```\n\n2. Install dependencies:\n\n   ```bash\n   pip install -U google-adk daytona-adk python-dotenv\n   ```\n\n3. Run the example:\n\n   ```bash\n   python main.py\n   ```\n\n## Configuration\n\n- **Agent Instruction:** The `AGENT_INSTRUCTION` constant in `main.py` defines the agent's behavior. You can customize this to change how the agent approaches code generation and testing.\n\n## How It Works\n\nWhen you run the example, the agent follows this workflow:\n\n1. **Receive Request:** The agent receives your natural language description of a function\n2. **Generate Code:** Agent writes the function implementation in the specified language\n3. **Create Tests:** Agent generates test cases to verify the implementation\n4. **Execute in Sandbox:** Code and tests run in an isolated Daytona sandbox\n5. **Iterate:** If tests fail, agent fixes the code and re-executes until tests pass\n6. **Return Result:** Once verified, the agent returns only the working function code\n7. **Cleanup:** Sandbox resources are automatically cleaned up\n\n## Example Output\n\nWhen the agent completes the task, you'll see output like:\n\n````\nAGENT RESPONSE:\n------------------------------------------------------------\n```typescript\nfunction groupBy<T, K extends keyof any>(\n  array: T[],\n  keyFn: (item: T) => K\n): Record<K, T[]> {\n  return array.reduce((result, item) => {\n    const key = keyFn(item);\n    if (!result[key]) {\n      result[key] = [];\n    }\n    result[key].push(item);\n    return result;\n  }, {} as Record<K, T[]>);\n}\n```\n============================================================\n\nApp closed, sandbox cleaned up. Done!\n````\n\nThe agent has already tested this code in the sandbox before returning it, so you can trust that the implementation works correctly.\n\n## API Reference\n\nFor the complete API reference, see the [daytona-adk documentation](https://github.com/daytonaio/daytona-adk-plugin#available-tools).\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [Google ADK Documentation](https://google.github.io/adk-docs/)\n- [Daytona ADK Plugin](https://pypi.org/project/daytona-adk/)\n- [Daytona](https://daytona.io)\n"
  },
  {
    "path": "guides/python/google-adk/code-generator-agent/gemini/main.py",
    "content": "# Copyright Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Code Generator & Tester Agent Example.\"\"\"\n\nimport asyncio\nimport logging\n\nfrom daytona_adk import DaytonaPlugin  # pylint: disable=import-error\nfrom dotenv import load_dotenv\nfrom google.adk.agents import Agent  # pylint: disable=import-error\nfrom google.adk.apps import App  # pylint: disable=import-error\nfrom google.adk.runners import InMemoryRunner  # pylint: disable=import-error\n\nload_dotenv()\n\nlogging.basicConfig(level=logging.DEBUG)\n\n\ndef extract_final_response(response: list) -> str:\n    \"\"\"Extract the final text response from a list of ADK events.\"\"\"\n    for event in reversed(response):\n        text_parts = []\n\n        if hasattr(event, \"text\") and event.text:\n            return event.text\n        if hasattr(event, \"content\") and event.content:\n            content = event.content\n            if hasattr(content, \"parts\") and content.parts:\n                for part in content.parts:\n                    if hasattr(part, \"text\") and part.text:\n                        text_parts.append(part.text)\n                if text_parts:\n                    return \"\".join(text_parts)\n            if hasattr(content, \"text\") and content.text:\n                return content.text\n        if isinstance(event, dict):\n            text = event.get(\"text\") or event.get(\"content\", {}).get(\"text\")\n            if text:\n                return text\n\n    return \"\"\n\n\nAGENT_INSTRUCTION = \"\"\"You are a code generator agent that writes verified, working code.\nYou support Python, JavaScript, and TypeScript.\n\nYour workflow for every code request:\n1. Write the function\n2. Write tests for it\n3. EXECUTE the code in the sandbox to verify it works - do not skip this step\n4. If execution fails, fix and re-execute until tests pass\n5. Once verified, respond with ONLY the function (no tests)\n\nYou must always execute code before responding. Never return untested code.\nOnly include tests in your response if the user explicitly asks for them.\n\"\"\"\n\n\nasync def main() -> None:\n    \"\"\"Run the code generator agent example.\"\"\"\n    plugin = DaytonaPlugin(\n        labels={\"example\": \"code-generator\"},\n    )\n\n    agent = Agent(\n        model=\"gemini-2.5-pro\",\n        name=\"code_generator_agent\",\n        instruction=AGENT_INSTRUCTION,\n        tools=plugin.get_tools(),\n    )\n\n    app = App(\n        name=\"code_generator_app\",\n        root_agent=agent,\n        plugins=[plugin],\n    )\n\n    async with InMemoryRunner(app=app) as runner:\n        prompt = (\n            \"Write a TypeScript function called 'groupBy' that takes an array \"\n            \"and a key function, and groups array elements by the key. \"\n            \"Use proper type annotations.\"\n        )\n\n        print(\"\\n\" + \"=\" * 60)\n        print(\"USER PROMPT:\")\n        print(\"=\" * 60)\n        print(prompt)\n        print(\"-\" * 60)\n\n        response = await runner.run_debug(prompt)\n\n        final_response = extract_final_response(response)\n        print(\"\\nAGENT RESPONSE:\")\n        print(\"-\" * 60)\n        print(final_response)\n        print(\"=\" * 60)\n\n    print(\"\\nApp closed, sandbox cleaned up. Done!\")\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n"
  },
  {
    "path": "guides/python/langchain/data-analysis/anthropic/.gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# Virtual Environments\nvenv/\nenv/\nENV/\nenv.bak/\nvenv.bak/\n.venv/\n.virtualenv/\n.pyenv/\n\n# Poetry\npoetry.lock\n.poetry/\n\n# Pipenv\nPipfile.lock\n\n# pyenv\n.python-version\n\n# Conda\nconda-meta/\n.conda/\n\n# PyCharm\n.idea/\n*.iml\n\n# VS Code\n.vscode/\n*.code-workspace\n\n# Jupyter Notebook\n.ipynb_checkpoints/\n*.ipynb_checkpoints/\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.env.local\n.env.*.local\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# macOS\n.DS_Store\n\n# Windows\nThumbs.db\nehthumbs.db\nDesktop.ini\n\n# Linux\n*~\n\n# Temporary files\n*.tmp\n*.bak\n*.swp\n*~\n\n# Example Data & Generated Outputs\n*.csv\n*.xlsx\n*.xls\n*.json\n*.parquet\n*.png\n*.jpg\n*.jpeg\n*.gif\n*.svg\n*.pdf\n\n"
  },
  {
    "path": "guides/python/langchain/data-analysis/anthropic/README.md",
    "content": "# LangChain Data Analysis Example (LangChain + Daytona)\n\n## Overview\n\nThis example demonstrates how to build a [LangChain](https://www.langchain.com/) agent that performs secure data analysis using [Daytona](https://daytona.io) sandboxes. The agent uses the `DaytonaDataAnalysisTool` to execute Python code in an isolated environment, enabling automated data analysis workflows with natural language prompts.\n\nIn this example, the agent analyzes a vehicle valuations dataset to understand how vehicle prices vary by manufacturing year and generates a line chart showing average price per year.\n\n## Features\n\n- **Secure sandbox execution:** All Python code runs in isolated Daytona sandboxes\n- **Natural language interface:** Describe your analysis task in plain English\n- **Automatic artifact handling:** Charts and outputs are automatically captured and saved\n- **Multi-step reasoning:** Agent breaks down complex analysis into logical steps\n- **File management:** Upload datasets, download results, and manage sandbox files\n- **Custom result handlers:** Process execution artifacts (charts, logs) as needed\n\n## Requirements\n\n- **Python:** Version 3.10 or higher is required (for LangChain 1.0+ syntax)\n\n> [!TIP]\n> It's recommended to use a virtual environment (`venv` or `poetry`) to isolate project dependencies.\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `ANTHROPIC_API_KEY`: Required for Claude AI model access. Get it from [Anthropic Console](https://console.anthropic.com/)\n\nSee the `.env.example` file for the exact structure. Copy `.env.example` to `.env` and fill in your API keys before running.\n\n## Getting Started\n\nBefore proceeding, complete the following steps:\n\n1. Ensure Python 3.10 or higher is installed\n2. Copy `.env.example` to `.env` and add your API keys\n3. Download the dataset (instructions below)\n\n### Setup and Run\n\n1. Create and activate a virtual environment:\n\n   ```bash\n   python3.10 -m venv venv  \n   source venv/bin/activate  # On Windows: venv\\Scripts\\activate\n   ```\n\n2. Install dependencies:\n\n   ```bash\n   pip install -U langchain langchain-anthropic langchain-daytona-data-analysis python-dotenv\n   ```\n\n3. Download the dataset:\n\n   ```bash\n   curl -o dataset.csv https://download.daytona.io/dataset.csv\n   ```\n\n   Or download manually from [https://download.daytona.io/dataset.csv](https://download.daytona.io/dataset.csv) and save as `dataset.csv`\n\n4. Run the example:\n\n   ```bash\n   python data_analysis.py\n   ```\n\n## Configuration\n\n- **Analysis Prompt:** The main prompt is configured in the `agent.invoke()` call inside `data_analysis.py`. You can modify this prompt to analyze different aspects of the data or try different visualization types.\n\n- **Dataset Description:** When uploading the dataset, provide a clear description of the columns and data cleaning instructions to help the agent understand how to process the data.\n\n- **Result Handler:** The `process_data_analysis_result()` function processes execution artifacts. You can customize this to handle different output types (charts, tables, logs, etc.).\n\n## How It Works\n\nWhen you run the example, the agent follows this workflow:\n\n1. **Dataset Upload:** The CSV file is uploaded to the Daytona sandbox with metadata describing its structure\n2. **Agent Reasoning:** The agent receives your natural language request and plans the analysis steps\n3. **Code Generation:** Agent generates Python code to explore, clean, and analyze the data\n4. **Sandbox Execution:** Code runs securely in the Daytona sandbox environment\n5. **Artifact Processing:** Charts and outputs are captured and processed by your custom handler\n6. **Cleanup:** Sandbox resources are automatically cleaned up\n\nYou provide the data and describe what insights you need - the agent handles the rest.\n\n## Example Output\n\nWhen the agent completes the analysis, you'll see output like:\n\n```\nResult stdout Original dataset shape: (100000, 15)\nAfter removing missing values: (100000, 15)\nAfter removing non-numeric values: (99946, 15)\nAfter removing year outliers: (96598, 15)\nAfter removing price outliers: (90095, 15)\n\nCleaned data summary:\n               year  price_in_euro\ncount  90095.000000   90095.000000\nmean    2016.698563   22422.266707\nstd        4.457647   12964.727116\nmin     2005.000000     150.000000\n25%     2014.000000   12980.000000\n50%     2018.000000   19900.000000\n75%     2020.000000   29500.000000\nmax     2023.000000   62090.000000\n\nAverage price by year:\nyear\n2005.0     5968.124319\n2006.0     6870.881523\n2007.0     8015.234473\n2008.0     8788.644495\n2009.0     8406.198576\n2010.0    10378.815972\n2011.0    11540.640435\n2012.0    13306.642261\n2013.0    14512.707025\n2014.0    15997.682899\n2015.0    18563.864358\n2016.0    20124.556294\n2017.0    22268.083322\n2018.0    24241.123673\n2019.0    26757.469111\n2020.0    29400.163494\n2021.0    30720.168646\n2022.0    33861.717552\n2023.0    33119.840175\nName: price_in_euro, dtype: float64\n\nTotal number of vehicles analyzed: 90095\nYear range: 2005 - 2023\nPrice range: €150.00 - €62090.00\nOverall average price: €22422.27\n\nChart saved to chart-0.png\n```\n\nThe agent generates a professional line chart showing how average vehicle prices increased from 2005 (€5,968) to 2022 (€33,862), with a slight decrease in 2023. The chart is saved as `chart-0.png` in your project directory.\n\n## API Reference\n\nThe `DaytonaDataAnalysisTool` provides these key methods:\n\n### download_file\n\n```python\ndef download_file(remote_path: str) -> bytes\n```\n\nDownloads a file from the sandbox by its remote path.\n\n### upload_file\n\n```python\ndef upload_file(file: IO, description: str) -> SandboxUploadedFile\n```\n\nUploads a file to the sandbox with a description of its structure and contents.\n\n### install_python_packages\n\n```python\ndef install_python_packages(package_names: str | list[str]) -> None\n```\n\nInstalls Python packages in the sandbox using pip.\n\n### close\n\n```python\ndef close() -> None\n```\n\nCloses and deletes the sandbox environment. Always call this when finished to clean up resources.\n\nFor the complete API reference and additional methods, see the [documentation](https://www.daytona.io/docs/en/langchain-data-analysis/#10-api-reference).\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [LangChain](https://docs.langchain.com/)\n- [Daytona](https://daytona.io)\n"
  },
  {
    "path": "guides/python/langchain/data-analysis/anthropic/data_analysis.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"LangChain data analysis example using Daytona sandboxes.\"\"\"\nimport base64\n\nfrom dotenv import load_dotenv\nfrom langchain.agents import create_agent  # pylint: disable=import-error\nfrom langchain_anthropic import ChatAnthropic  # pylint: disable=import-error\n\n# pylint: disable=import-error\nfrom langchain_daytona_data_analysis import DaytonaDataAnalysisTool\n\nfrom daytona import ExecutionArtifacts\n\nload_dotenv()\n\nmodel = ChatAnthropic(model_name=\"claude-sonnet-4-5-20250929\", temperature=0, timeout=None, max_retries=2, stop=None)\n\n\ndef process_data_analysis_result(result: ExecutionArtifacts):\n    # Print the standard output from code execution\n    print(\"Result stdout\", result.stdout)\n    result_idx = 0\n    for chart in result.charts:\n        if chart.png:\n            # Save the png to a file\n            # The png is in base64 format.\n            with open(f\"chart-{result_idx}.png\", \"wb\") as f:\n                f.write(base64.b64decode(chart.png))\n            print(f\"Chart saved to chart-{result_idx}.png\")\n            result_idx += 1\n\n\ndef main():\n    data_analysis_tool = DaytonaDataAnalysisTool(on_result=process_data_analysis_result)\n\n    try:\n        with open(\"./dataset.csv\", \"rb\") as f:\n            data_analysis_tool.upload_file(\n                f,\n                description=(\n                    \"This is a CSV file containing vehicle valuations. \"\n                    \"Relevant columns:\\n\"\n                    \"- 'year': integer, the manufacturing year of the vehicle\\n\"\n                    \"- 'price_in_euro': float, the listed price \"\n                    \"of the vehicle in Euros\\n\"\n                    \"Drop rows where 'year' or 'price_in_euro' is missing, \"\n                    \"non-numeric, or an outlier.\"\n                ),\n            )\n\n        agent = create_agent(model, tools=[data_analysis_tool], debug=True)\n\n        agent.invoke(\n            {\n                \"messages\": [\n                    {\n                        \"role\": \"user\",\n                        \"content\": \"Analyze how vehicles price varies by \"\n                        \"manufacturing year. Create a line chart showing \"\n                        \"average price per year.\",\n                    }\n                ]\n            }\n        )\n    finally:\n        data_analysis_tool.close()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "guides/python/recursive-language-models/.gitignore",
    "content": "venv/\n__pycache__/\n*__pycache__/\n.env\n"
  },
  {
    "path": "guides/python/recursive-language-models/README.md",
    "content": "# Run Recursive Language Models on Daytona\n\n## Overview\n\nThis guide demonstrates how to implement a recursive language model (RLM) agent system built on Daytona sandboxes, based on the approach pioneered in [Recursive Language Models](https://arxiv.org/abs/2512.24601) (Zhang, Kraska, Khattab). Unlike traditional single-agent approaches, agents can spawn sub-agents recursively, each in its own isolated sandbox with a fresh clone of the target repository.\n\nThe system enables tree-structured problem decomposition: a root agent can delegate subtasks to child agents, which can spawn their own children, creating a hierarchy of specialized workers collaborating on complex software engineering tasks.\n\n## Features\n\n- **Sandboxed code execution:** Each agent runs in an isolated Daytona sandbox with a fresh repository clone\n- **Recursive agent spawning:** Agents spawn sub-agents via `rlm_query()`, each with their own sandbox\n- **Parallel sub-agent execution:** `rlm_query_batched()` spawns multiple sub-agents concurrently using thread pools\n- **Budget management:** Global sandbox limit (default: 25) shared across the entire agent tree\n- **LLM agnostic:** LiteLLM integration enables any provider (OpenRouter, OpenAI, Anthropic, etc.)\n- **Git patch output:** Root agents produce git patches as their final output\n- **Interactive viewer:** Web-based D3.js visualization of agent execution trees\n\n## Requirements\n\n- **Python:** Version 3.10 or higher\n\n## Environment Variables\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `LLM_API_KEY`: Required for your LLM provider via [LiteLLM](https://docs.litellm.ai/) (OpenRouter, OpenAI, Anthropic, etc.)\n\n## Getting Started\n\n### Setup and Run\n\n1. Create and activate a virtual environment:\n\n```bash\npython3.10 -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n```\n\n2. Install dependencies:\n\n```bash\npip install -e .\n```\n\n3. Set your API keys in `.env` (copy from `.env.example`):\n\n```bash\ncp .env.example .env\n# Edit .env with your DAYTONA_API_KEY and LLM_API_KEY\n```\n\n4. Run the agent:\n\n```bash\npython run.py https://github.com/user/repo --prompt \"Fix the bug in auth.py\"\n```\n\n### CLI Options\n\n- `repo` - GitHub repository URL (required, positional)\n- `-p, --prompt` - Task prompt for the agent (required)\n- `-b, --branch` - Branch name (optional)\n- `--commit` - Specific commit SHA (optional)\n- `-c, --config` - Path to YAML configuration file (default: `config.yaml`)\n- `-o, --output` - Output file for the patch (default: stdout)\n- `--verbose / --quiet` - Enable verbose output (default: verbose)\n\n## Configuration\n\nThe script has several configurable parameters in `config.yaml`:\n\n### Sandbox Settings\n\n- `max_sandboxes`: Maximum total sandboxes that can be created over the entire run (default: 50)\n- `global_timeout`: Total timeout in seconds for the entire run (default: 1800 = 30 minutes)\n\n### Model Settings\n\n- `model.name`: The LLM model to use in LiteLLM format (default: `openrouter/google/gemini-3-flash-preview`)\n\n### Agent Settings\n\n- `max_iterations`: Maximum iterations per agent before timeout (default: 50)\n- `result_truncation_limit`: Maximum characters for sub-agent results (default: 20000)\n\n## How It Works\n\nThe system runs a recursive agent architecture where each agent operates in its own sandbox.\n\n1. **Initialization:** Load config and create root agent (depth=0) with a Daytona sandbox containing a fresh clone of the target repository\n2. **Iteration loop:** The agent runs an iteration loop: LLM call → extract Python code blocks → execute in REPL\n3. **Sub-agent spawning:** When code calls `rlm_query(task)`, a new sub-agent is created with its own sandbox\n4. **Recursive delegation:** Sub-agents can spawn their own sub-agents (unlimited depth)\n5. **Result propagation:** Results flow back up the tree as sub-agents complete\n6. **Completion:** Root agent calls `FINAL()` or times out, producing a git patch of all changes\n7. **Cleanup:** Sandboxes are deleted and results are logged to JSON\n\n## Agent Hierarchy Example\n\n```\nRoot Agent (depth=0)\n├── Sub-Agent A (depth=1)\n│   ├── Sub-Agent A1 (depth=2)\n│   └── Sub-Agent A2 (depth=2)\n└── Sub-Agent B (depth=1)\n    ├── Sub-Agent B1 (depth=2)\n    └── Sub-Agent B2 (depth=2)\n```\n\n## Key Functions Available in Agent Code\n\n| Function | Description |\n| -------- | ----------- |\n| `rlm_query(task)` | Spawn a single sub-agent with the given task, returns result string |\n| `rlm_query_batched(tasks)` | Spawn multiple sub-agents in parallel, returns list of result strings |\n| `FINAL(answer)` | Submit final result (root agent: triggers git patch extraction) |\n| `FINAL_VAR(var_name)` | Submit the value of a variable as the result |\n| `edit_file(path, old, new)` | Edit a file with syntax validation |\n\nVariables and imports persist between iterations within the same agent.\n\n## Viewer\n\nStart a local server and open the viewer to visualize agent execution:\n\n```bash\npython -m http.server 8000\n# Open http://localhost:8000/viewer/\n```\n\nThe viewer provides:\n\n- Interactive tree visualization of the agent hierarchy\n- Iteration details with code and output for each agent\n\n## Output\n\nAfter running, results are saved in the `results/` directory:\n\n- `{run_id}.detail.json`: Full agent tree with all iterations, code blocks, and outputs\n- `index.json`: Index of all runs for the viewer\n- Final output: Git patch printed to stdout (or saved to `-o` file)\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [Recursive Language Models](https://arxiv.org/abs/2512.24601) - Zhang, Kraska, Khattab\n- [LiteLLM](https://docs.litellm.ai/)\n"
  },
  {
    "path": "guides/python/recursive-language-models/config.yaml",
    "content": "# Configuration for deeper-rlm\n\n# Model configuration - using LiteLLM format\nmodel:\n  name: \"openrouter/google/gemini-3-flash-preview\"\n\n# RLM configuration\nrlm:\n  max_sandboxes: 50\n  max_iterations: 50\n  global_timeout: 1800  # 30 minutes\n  result_truncation_limit: 20000\n"
  },
  {
    "path": "guides/python/recursive-language-models/output_logging/__init__.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Logging utilities for deeper-rlm.\"\"\"\n\nfrom output_logging.console import ConsoleOutput\nfrom output_logging.tree_logger import TreeLogger\n\n__all__ = [\"TreeLogger\", \"ConsoleOutput\"]\n"
  },
  {
    "path": "guides/python/recursive-language-models/output_logging/console.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Simple console output for deeper-rlm.\"\"\"\n\nfrom rlm.types import AgentResult, Iteration\n\n\nclass ConsoleOutput:\n    \"\"\"Console output for real-time progress display.\"\"\"\n\n    def __init__(self, verbose: bool = True):\n        self.verbose = verbose\n\n    def iteration(self, agent_id: str, depth: int, iteration: Iteration) -> None:\n        \"\"\"Display an iteration's details.\"\"\"\n        if not self.verbose:\n            return\n\n        prefix = \"  \" * depth\n        print(f\"{prefix}Agent {agent_id} - Iteration {iteration.iteration}\")\n\n        for block in iteration.parsed_code_blocks:\n            print(f\"{prefix}Code:\")\n            # Indent code block\n            code_preview = block.code[:500]\n            for line in code_preview.split(\"\\n\"):\n                print(f\"{prefix}  {line}\")\n\n            if block.stdout:\n                truncated = block.stdout[:300] + \"...\" if len(block.stdout) > 300 else block.stdout\n                print(f\"{prefix}Output: {truncated}\")\n\n            if block.error:\n                print(f\"{prefix}Error: {block.error[:200]}\")\n\n    def agent_spawn(self, _parent_id: str, child_id: str, task: str, depth: int) -> None:\n        \"\"\"Display sub-agent spawn.\"\"\"\n        if not self.verbose:\n            return\n\n        prefix = \"  \" * depth\n        truncated_task = task[:80] + \"...\" if len(task) > 80 else task\n        print(f\"{prefix}Spawning sub-agent {child_id}: {truncated_task}\")\n\n    def agent_complete(self, agent_id: str, depth: int, result: str | None) -> None:\n        \"\"\"Display agent completion.\"\"\"\n        if not self.verbose:\n            return\n\n        prefix = \"  \" * depth\n        if result:\n            truncated = result[:100] + \"...\" if len(result) > 100 else result\n            print(f\"{prefix}Agent {agent_id} complete: {truncated}\")\n        else:\n            print(f\"{prefix}Agent {agent_id} complete (no result)\")\n\n    def tree_view(self, agent: AgentResult) -> None:\n        \"\"\"Display agent tree structure.\"\"\"\n        print(\"\\nAgent Tree:\")\n        self._print_tree(agent, prefix=\"\")\n\n    def _print_tree(self, agent: AgentResult, prefix: str, connector: str = \"\") -> None:\n        \"\"\"Recursively print tree structure.\"\"\"\n        task_preview = \"\"\n        if agent.task:\n            task_preview = f\": {agent.task[:40]}...\" if len(agent.task) > 40 else f\": {agent.task}\"\n        iters = len(agent.iterations)\n        print(f\"{prefix}{connector}{agent.agent_id} (depth={agent.depth}, iters={iters}){task_preview}\")\n\n        # Calculate the base prefix for children based on our connector\n        if connector == \"└─\":\n            child_base = prefix + \"  \"  # Last child, use spaces\n        elif connector == \"├─\":\n            child_base = prefix + \"| \"  # More siblings, continue line\n        else:\n            child_base = prefix  # Root node\n\n        for i, sub in enumerate(agent.spawned_agents):\n            is_last = i == len(agent.spawned_agents) - 1\n            child_connector = \"└─\" if is_last else \"├─\"\n            self._print_tree(sub, child_base, child_connector)\n"
  },
  {
    "path": "guides/python/recursive-language-models/output_logging/tree_logger.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Tree-structured JSON logger for deeper-rlm.\"\"\"\n\nimport json\nfrom pathlib import Path\nfrom typing import Any\n\nfrom rlm.types import AgentResult\n\n\nclass TreeLogger:\n    \"\"\"\n    Logger that saves results in nested JSON tree format.\n\n    Creates a detail file per run with full agent tree and all iterations.\n    \"\"\"\n\n    def __init__(self, output_dir: str | Path):\n        \"\"\"\n        Initialize the logger.\n\n        Args:\n            output_dir: Directory for output files\n        \"\"\"\n        self.output_dir = Path(output_dir)\n        self.output_dir.mkdir(parents=True, exist_ok=True)\n\n    def log_agent_result(self, agent: AgentResult, run_id: str) -> Path:\n        \"\"\"\n        Log an agent result.\n\n        Args:\n            agent: Agent result to log\n            run_id: Unique run identifier\n\n        Returns:\n            Path to the detail file\n        \"\"\"\n        # Write detail\n        detail_path = self.output_dir / f\"{run_id}.detail.json\"\n        detail = {\n            \"run_id\": run_id,\n            \"root_agent\": self._serialize_agent(agent),\n        }\n        with open(detail_path, \"w\") as f:\n            json.dump(detail, f, indent=2, default=str)\n\n        # Update index.json for viewer\n        self._update_index()\n\n        return detail_path\n\n    def _update_index(self) -> None:\n        \"\"\"Update index.json with list of available detail files.\"\"\"\n        files = sorted(\n            [f.name for f in self.output_dir.glob(\"*.detail.json\")],\n            key=lambda f: self.output_dir.joinpath(f).stat().st_mtime,\n            reverse=True,\n        )\n        index_path = self.output_dir / \"index.json\"\n        with open(index_path, \"w\") as f:\n            json.dump(files, f, indent=2)\n\n    def _serialize_agent(self, agent: AgentResult) -> dict[str, Any]:\n        \"\"\"Serialize an agent result to dict.\"\"\"\n        return {\n            \"agent_id\": agent.agent_id,\n            \"depth\": agent.depth,\n            \"sandbox_id\": agent.sandbox_id,\n            \"task\": agent.task,\n            \"iterations\": [\n                {\n                    \"iteration\": it.iteration,\n                    \"prompt\": it.prompt,\n                    \"raw_response\": it.raw_response,\n                    \"parsed_code_blocks\": [\n                        {\n                            \"code\": block.code,\n                            \"stdout\": block.stdout,\n                            \"stderr\": block.stderr,\n                            \"execution_time\": block.execution_time,\n                            \"error\": block.error,\n                        }\n                        for block in it.parsed_code_blocks\n                    ],\n                    \"spawned_agents\": [self._serialize_agent(sub) for sub in it.spawned_agents],\n                }\n                for it in agent.iterations\n            ],\n            \"spawned_agents\": [self._serialize_agent(sub) for sub in agent.spawned_agents],\n            \"result\": agent.result,\n            \"result_truncated\": agent.result_truncated,\n            \"usage\": {\n                \"input_tokens\": agent.usage.input_tokens,\n                \"output_tokens\": agent.usage.output_tokens,\n                \"cost\": agent.usage.cost,\n            },\n            \"execution_time\": agent.execution_time,\n            \"error\": agent.error,\n        }\n"
  },
  {
    "path": "guides/python/recursive-language-models/pyproject.toml",
    "content": "[project]\nname = \"deeper-rlm\"\nversion = \"0.1.0\"\ndescription = \"Recursive Language Model agent system with unlimited depth recursion\"\nreadme = \"README.md\"\nrequires-python = \">=3.10\"\ndependencies = [\n    \"litellm>=1.50.0\",\n    \"daytona>=0.128.1\",\n    \"pyyaml>=6.0\",\n    \"typer>=0.12.0\",\n    \"python-dotenv>=1.0.0\",\n]\n\n[project.optional-dependencies]\ndev = [\n    \"pytest>=8.0.0\",\n    \"ruff>=0.6.0\",\n]\n\n[project.scripts]\ndeeper-rlm = \"run:main\"\n\n[build-system]\nrequires = [\"hatchling\"]\nbuild-backend = \"hatchling.build\"\n\n[tool.hatch.build.targets.wheel]\npackages = [\"rlm\", \"output_logging\"]\n\n"
  },
  {
    "path": "guides/python/recursive-language-models/rlm/__init__.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"RLM core module.\"\"\"\n\n# pylint: disable=import-outside-toplevel\n\n\n# Lazy imports to avoid circular dependencies\ndef __getattr__(name):\n    if name == \"RLMAgent\":\n        from rlm.agent import RLMAgent\n\n        return RLMAgent\n    if name == \"AgentResult\":\n        from rlm.types import AgentResult\n\n        return AgentResult\n    if name == \"RLMConfig\":\n        from rlm.types import RLMConfig\n\n        return RLMConfig\n    raise AttributeError(f\"module {__name__!r} has no attribute {name!r}\")\n\n\n__all__ = [\"RLMAgent\", \"AgentResult\", \"RLMConfig\"]  # pylint: disable=undefined-all-variable\n"
  },
  {
    "path": "guides/python/recursive-language-models/rlm/agent.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Core RLM agent implementation.\"\"\"\n\nimport logging\nimport threading\nimport time\nimport uuid\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\nfrom typing import TYPE_CHECKING, Callable\n\nfrom rlm import prompts\nfrom rlm.client import BaseLMClient\nfrom rlm.repl import DaytonaREPL\nfrom rlm.sandbox import SandboxExecutor, SandboxManager\nfrom rlm.types import AgentResult, Config, Iteration, UsageStats\n\nif TYPE_CHECKING:\n    from output_logging.console import ConsoleOutput\n\n    from daytona import Sandbox\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass RLMAgent:\n    \"\"\"\n    Recursive Language Model agent.\n\n    Executes in a Daytona sandbox, can spawn sub-agents via rlm_query().\n    \"\"\"\n\n    def __init__(\n        self,\n        client: BaseLMClient,\n        sandbox_manager: SandboxManager,\n        config: Config,\n        problem_statement: str,\n        instance_id: str,\n        repo_url: str,\n        depth: int = 0,\n        task: str | None = None,\n        on_iteration: Callable[[Iteration], None] | None = None,\n        global_start_time: float | None = None,\n        output: \"ConsoleOutput | None\" = None,\n        existing_sandbox: \"Sandbox | None\" = None,\n    ):\n        \"\"\"\n        Initialize the agent.\n\n        Args:\n            client: LLM client for completions\n            sandbox_manager: Manager for creating sandboxes\n            config: RLM configuration\n            problem_statement: Problem statement / task description\n            instance_id: Instance identifier (e.g. repo name)\n            repo_url: GitHub repository URL for creating sub-agent sandboxes\n            depth: Recursion depth (0 = root)\n            task: Task delegated by parent (None for root)\n            on_iteration: Callback for iteration logging\n            global_start_time: Start time for timeout tracking\n            output: Console output for progress display\n            existing_sandbox: Pre-created sandbox to use\n        \"\"\"\n        self.client = client\n        self.sandbox_manager = sandbox_manager\n        self.config = config\n        self.problem_statement = problem_statement\n        self.instance_id = instance_id\n        self.repo_url = repo_url\n        self.depth = depth\n        self.task = task\n        self.on_iteration = on_iteration\n        self.global_start_time = global_start_time or time.time()\n        self.output = output\n        self.existing_sandbox = existing_sandbox\n\n        self.agent_id = f\"agent_{uuid.uuid4().hex[:8]}\"\n        self.sandbox: \"Sandbox | None\" = None\n        self.sandbox_id: str | None = None\n        self.repl: DaytonaREPL | None = None\n\n        self._iterations: list[Iteration] = []\n        self._spawned_agents: list[AgentResult] = []\n        self._usage = UsageStats()\n        self._result: str | None = None\n        self._lock = threading.Lock()\n\n    def run(self) -> AgentResult:\n        \"\"\"\n        Run the agent to completion.\n\n        Returns:\n            AgentResult with final answer, iterations, usage, etc.\n        \"\"\"\n        start_time = time.time()\n\n        try:\n            # Create or use existing sandbox\n            if self.existing_sandbox is not None:\n                self.sandbox = self.existing_sandbox\n                self.sandbox_id = self.sandbox.id\n                logger.info(f\"Agent {self.agent_id} (depth={self.depth}) \" f\"using existing sandbox {self.sandbox_id}\")\n            else:\n                self.sandbox, info = self.sandbox_manager.create_sandbox_from_repo(\n                    repo_url=self._get_repo_url(),\n                )\n                self.sandbox_id = info.sandbox_id\n                logger.info(f\"Agent {self.agent_id} (depth={self.depth}) created sandbox {self.sandbox_id}\")\n\n            # Determine task content for REPL variable\n            # Root agents get the problem statement, sub-agents get their assigned task\n            task_content = self.problem_statement if self.depth == 0 else self.task\n\n            # Initialize REPL with handlers and task variable\n            self.repl = DaytonaREPL(\n                sandbox=self.sandbox,\n                rlm_query_handler=self._handle_rlm_query,\n                rlm_query_batched_handler=self._handle_rlm_query_batched,\n                initial_variables={\"task\": task_content},\n                conda_env=None,\n            )\n\n            # Run iteration loop\n            self._run_loop()\n\n        except Exception as e:\n            logger.error(f\"Agent {self.agent_id} error: {e}\")\n            # Notify console of completion (with error)\n            if self.output:\n                self.output.agent_complete(self.agent_id, self.depth, None)\n            # Root agents use problem_statement, sub-agents use task\n            task_for_log = self.problem_statement if self.depth == 0 else self.task\n            return AgentResult(\n                agent_id=self.agent_id,\n                depth=self.depth,\n                sandbox_id=self.sandbox_id or \"\",\n                task=task_for_log,\n                iterations=self._iterations,\n                spawned_agents=self._spawned_agents,\n                result=None,\n                usage=self._usage,\n                execution_time=time.time() - start_time,\n                error=str(e),\n            )\n        finally:\n            # Cleanup REPL (stops broker and poller thread)\n            if self.repl:\n                self.repl.cleanup()\n\n            # Cleanup sandbox - but NOT for root agent (may be needed after)\n            if self.sandbox_id and self.depth > 0:\n                self.sandbox_manager.delete_sandbox(self.sandbox_id)\n\n        # Notify console of completion\n        if self.output:\n            self.output.agent_complete(self.agent_id, self.depth, self._result)\n\n        # Root agents use problem_statement, sub-agents use task\n        task_for_log = self.problem_statement if self.depth == 0 else self.task\n        return AgentResult(\n            agent_id=self.agent_id,\n            depth=self.depth,\n            sandbox_id=self.sandbox_id or \"\",\n            task=task_for_log,\n            iterations=self._iterations,\n            spawned_agents=self._spawned_agents,\n            result=self._result,\n            result_truncated=len(self._result or \"\") > self.config.rlm.result_truncation_limit,\n            usage=self._usage,\n            execution_time=time.time() - start_time,\n        )\n\n    def _get_repo_url(self) -> str:\n        \"\"\"Get the repository URL for creating sub-agent sandboxes.\"\"\"\n        return self.repo_url\n\n    def _run_loop(self) -> None:\n        \"\"\"Run the main iteration loop.\"\"\"\n        # Build system prompt\n        system_prompt = prompts.build_system_prompt(depth=self.depth)\n\n        messages = [{\"role\": \"system\", \"content\": system_prompt}]\n        execution_result = None\n\n        for iteration in range(self.config.rlm.max_iterations):\n            # Check global timeout\n            if self._is_timeout():\n                logger.warning(f\"Agent {self.agent_id} hit global timeout\")\n                break\n\n            # Build user prompt\n            user_prompt = prompts.build_user_prompt(iteration, execution_result)\n            messages.append({\"role\": \"user\", \"content\": user_prompt})\n\n            # Get model completion\n            logger.debug(f\"Agent {self.agent_id} iteration {iteration}\")\n            response = self.client.completion(messages)\n            self._usage += self.client.last_usage\n\n            # Add assistant response to history\n            messages.append({\"role\": \"assistant\", \"content\": response})\n\n            # Execute code blocks\n            repl_result = self.repl.execute_response(response)\n\n            # Create iteration record\n            iter_record = Iteration(\n                iteration=iteration,\n                prompt=messages[-2][\"content\"],  # User prompt\n                raw_response=response,\n                parsed_code_blocks=repl_result.code_blocks,\n                spawned_agents=[],  # Will be populated below\n            )\n            self._iterations.append(iter_record)\n\n            # Call iteration callback\n            if self.on_iteration:\n                self.on_iteration(iter_record)\n\n            # Check for final answer (FINAL_VAR is resolved to final_answer in execution script)\n            if repl_result.final_answer is not None:\n                self._result = repl_result.final_answer\n                logger.info(f\"Agent {self.agent_id} returned final answer\")\n                break\n\n            # Format execution result for next iteration\n            if repl_result.code_blocks:\n                result_parts = []\n                for block in repl_result.code_blocks:\n                    result_parts.append(\n                        prompts.format_execution_result(block.code, block.stdout, block.stderr, block.error)\n                    )\n                execution_result = \"\\n\\n\".join(result_parts)\n            else:\n                execution_result = None\n\n        # If no final answer, try to extract patch from sandbox (root only)\n        if self._result is None and self.depth == 0:\n            self._result = self._extract_patch()\n\n    def _handle_rlm_query(self, task: str) -> str:\n        \"\"\"\n        Handle an rlm_query() call by spawning a sub-agent.\n\n        Args:\n            task: Task for the sub-agent\n\n        Returns:\n            Sub-agent's result string\n        \"\"\"\n        logger.info(f\"Agent {self.agent_id} spawning sub-agent for: {task[:50]}...\")\n\n        # Check budget\n        if not self.sandbox_manager.budget.can_acquire():\n            budget = self.sandbox_manager.budget\n            return (\n                f\"Error: Cannot spawn sub-agent - sandbox budget exhausted \"\n                f\"({budget.status.created}/{budget.max} used). \"\n                f\"Complete the task with the resources you have.\"\n            )\n\n        # Create sub-agent\n        sub_agent = RLMAgent(\n            client=self.client,\n            sandbox_manager=self.sandbox_manager,\n            config=self.config,\n            problem_statement=self.problem_statement,\n            instance_id=self.instance_id,\n            repo_url=self.repo_url,\n            depth=self.depth + 1,\n            task=task,\n            on_iteration=self.on_iteration,\n            global_start_time=self.global_start_time,\n            output=self.output,\n        )\n\n        # Notify console of spawn\n        if self.output:\n            self.output.agent_spawn(\n                parent_id=self.agent_id,\n                child_id=sub_agent.agent_id,\n                task=task,\n                depth=self.depth + 1,\n            )\n\n        # Run sub-agent\n        result = sub_agent.run()\n        with self._lock:\n            self._spawned_agents.append(result)\n            self._usage += result.usage\n\n        # Return result, truncated if necessary\n        if result.error:\n            return f\"Sub-agent error: {result.error}\"\n\n        answer = result.result or \"Sub-agent did not return a result.\"\n\n        # Truncate if too long\n        limit = self.config.rlm.result_truncation_limit\n        if len(answer) > limit:\n            answer = answer[:limit] + f\"\\n\\n[TRUNCATED - {len(answer) - limit} chars omitted]\"\n\n        return answer\n\n    def _handle_rlm_query_batched(self, tasks: list[str]) -> list[str]:\n        \"\"\"\n        Handle rlm_query_batched() by spawning multiple sub-agents in parallel.\n\n        Args:\n            tasks: List of tasks for sub-agents\n\n        Returns:\n            List of result strings\n        \"\"\"\n        logger.info(f\"Agent {self.agent_id} spawning {len(tasks)} sub-agents in parallel\")\n\n        # Check budget upfront\n        if not self.sandbox_manager.budget.can_acquire(len(tasks)):\n            remaining = self.sandbox_manager.budget.remaining\n            return [\n                f\"Error: Cannot spawn {len(tasks)} sub-agents - \"\n                f\"only {remaining} sandbox slots remaining. \"\n                f\"Reduce batch size or use sequential rlm_query() calls.\"\n            ] * len(tasks)\n\n        results = [\"\"] * len(tasks)\n\n        # Run sub-agents in parallel using thread pool\n        with ThreadPoolExecutor(max_workers=min(len(tasks), 10)) as executor:\n            future_to_idx = {executor.submit(self._handle_rlm_query, task): i for i, task in enumerate(tasks)}\n\n            for future in as_completed(future_to_idx):\n                idx = future_to_idx[future]\n                try:\n                    results[idx] = future.result()\n                except Exception as e:\n                    results[idx] = f\"Error spawning sub-agent: {e}\"\n\n        return results\n\n    def _extract_patch(self) -> str | None:\n        \"\"\"\n        Extract git diff from the sandbox (fallback if no FINAL() called).\n\n        Returns:\n            Git diff string or None\n        \"\"\"\n        if self.sandbox is None:\n            return None\n\n        try:\n            executor = SandboxExecutor(self.sandbox)\n\n            # Stage all changes\n            executor.execute(\"git add -A\")\n\n            # Get diff\n            result = executor.execute(\"git diff --cached HEAD\")\n            if result[\"returncode\"] == 0 and result[\"output\"].strip():\n                return result[\"output\"].strip()\n\n            # Try unstaged diff as fallback\n            result = executor.execute(\"git diff HEAD\")\n            if result[\"returncode\"] == 0 and result[\"output\"].strip():\n                return result[\"output\"].strip()\n\n        except Exception as e:\n            logger.warning(f\"Failed to extract patch: {e}\")\n\n        return None\n\n    def _is_timeout(self) -> bool:\n        \"\"\"Check if global timeout has been exceeded.\"\"\"\n        elapsed = time.time() - self.global_start_time\n        return elapsed >= self.config.rlm.global_timeout\n"
  },
  {
    "path": "guides/python/recursive-language-models/rlm/budget.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Sandbox budget tracking for deeper-rlm.\"\"\"\n\nimport threading\nfrom dataclasses import dataclass\n\n\n@dataclass\nclass BudgetStatus:\n    \"\"\"Current budget status.\"\"\"\n\n    max_sandboxes: int\n    created: int\n    active: int\n    remaining: int\n\n\nclass SandboxBudget:\n    \"\"\"\n    Thread-safe sandbox budget tracker.\n\n    Tracks the total number of sandboxes that can be created across the entire\n    RLM tree, regardless of depth level.\n    \"\"\"\n\n    def __init__(self, max_sandboxes: int):\n        \"\"\"\n        Initialize the budget tracker.\n\n        Args:\n            max_sandboxes: Maximum total sandboxes that can be created\n        \"\"\"\n        self.max = max_sandboxes\n        self.created = 0\n        self.active = 0\n        self._lock = threading.Lock()\n\n    def try_acquire(self, count: int = 1) -> bool:\n        \"\"\"\n        Try to acquire sandbox slots.\n\n        Args:\n            count: Number of slots to acquire\n\n        Returns:\n            True if slots were acquired, False if budget exhausted\n        \"\"\"\n        with self._lock:\n            if self.created + count > self.max:\n                return False\n            self.created += count\n            self.active += count\n            return True\n\n    def release(self, count: int = 1) -> None:\n        \"\"\"\n        Release sandbox slots (mark as no longer active).\n\n        Note: This doesn't restore budget - created count stays the same.\n        Budget tracks total sandboxes ever created, not concurrent ones.\n\n        Args:\n            count: Number of slots to release\n        \"\"\"\n        with self._lock:\n            self.active = max(0, self.active - count)\n\n    @property\n    def remaining(self) -> int:\n        \"\"\"Get remaining sandbox budget.\"\"\"\n        with self._lock:\n            return self.max - self.created\n\n    @property\n    def status(self) -> BudgetStatus:\n        \"\"\"Get current budget status.\"\"\"\n        with self._lock:\n            return BudgetStatus(\n                max_sandboxes=self.max,\n                created=self.created,\n                active=self.active,\n                remaining=self.max - self.created,\n            )\n\n    def can_acquire(self, count: int = 1) -> bool:\n        \"\"\"\n        Check if count slots can be acquired without actually acquiring.\n\n        Useful for checking batch feasibility before starting.\n\n        Args:\n            count: Number of slots to check\n\n        Returns:\n            True if slots are available\n        \"\"\"\n        with self._lock:\n            return self.created + count <= self.max\n\n    def __repr__(self) -> str:\n        status = self.status\n        return (\n            f\"SandboxBudget(max={status.max_sandboxes}, \"\n            f\"created={status.created}, active={status.active}, \"\n            f\"remaining={status.remaining})\"\n        )\n"
  },
  {
    "path": "guides/python/recursive-language-models/rlm/client.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"LiteLLM-based unified client for all LLM providers.\"\"\"\n\nimport logging\nimport time\nfrom abc import ABC, abstractmethod\nfrom typing import Any\n\nimport litellm  # pylint: disable=import-error\nfrom rlm.types import UsageStats\n\nlogger = logging.getLogger(__name__)\n\n\nclass BaseLMClient(ABC):\n    \"\"\"Base class for all language model clients.\"\"\"\n\n    def __init__(self, model_name: str, **kwargs):\n        self.model_name = model_name\n        self.kwargs = kwargs\n        self._last_usage = UsageStats()\n\n    @abstractmethod\n    def completion(self, prompt: str | list[dict[str, Any]]) -> str:\n        \"\"\"Generate a completion for the given prompt.\"\"\"\n        raise NotImplementedError\n\n    @property\n    def last_usage(self) -> UsageStats:\n        \"\"\"Get usage stats from the last completion call.\"\"\"\n        return self._last_usage\n\n\nclass LiteLLMClient(BaseLMClient):\n    \"\"\"\n    Unified LLM client using LiteLLM.\n\n    Supports all providers via LiteLLM's model naming convention:\n    - OpenRouter: \"openrouter/google/gemini-3-flash-preview\"\n    - OpenAI: \"gpt-4o\"\n    - Anthropic: \"claude-3-opus-20240229\"\n    \"\"\"\n\n    def __init__(\n        self,\n        model_name: str,\n        api_key: str | None = None,\n        **kwargs,\n    ):\n        super().__init__(model_name=model_name, **kwargs)\n        self.api_key = api_key\n\n    def completion(self, prompt: str | list[dict[str, Any]], max_retries: int = 5) -> str:\n        messages = self._prepare_messages(prompt)\n\n        for attempt in range(max_retries):\n            response = litellm.completion(\n                model=self.model_name,\n                messages=messages,\n                api_key=self.api_key,\n            )\n            self._track_usage(response)\n\n            if response.choices and response.choices[0].message.content:\n                return response.choices[0].message.content\n\n            # Empty response - retry\n            if attempt < max_retries - 1:\n                logger.warning(f\"Empty API response, retrying ({attempt + 1}/{max_retries})\")\n                time.sleep(1 * (attempt + 1))  # Backoff\n\n        raise ValueError(\"API returned empty response after retries\")\n\n    def _prepare_messages(self, prompt: str | list[dict[str, Any]]) -> list[dict[str, Any]]:\n        \"\"\"Prepare messages for API.\"\"\"\n        if isinstance(prompt, str):\n            return [{\"role\": \"user\", \"content\": prompt}]\n        if isinstance(prompt, list):\n            return prompt\n        raise ValueError(f\"Invalid prompt type: {type(prompt)}\")\n\n    def _track_usage(self, response):\n        \"\"\"Track token usage from response.\"\"\"\n        usage = getattr(response, \"usage\", None)\n        if usage is None:\n            self._last_usage = UsageStats()\n            return\n\n        input_tokens = getattr(usage, \"prompt_tokens\", 0) or 0\n        output_tokens = getattr(usage, \"completion_tokens\", 0) or 0\n\n        # Use LiteLLM's cost calculation\n        try:\n            cost = litellm.completion_cost(response)\n        except Exception:\n            cost = 0\n\n        self._last_usage = UsageStats(\n            input_tokens=input_tokens,\n            output_tokens=output_tokens,\n            cost=cost,\n        )\n\n\ndef create_client(model_name: str, api_key: str) -> LiteLLMClient:\n    \"\"\"Create an LLM client using LiteLLM.\"\"\"\n    return LiteLLMClient(model_name=model_name, api_key=api_key)\n"
  },
  {
    "path": "guides/python/recursive-language-models/rlm/prompts.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"System prompts for deeper-rlm agents.\"\"\"\n\nROOT_AGENT_PROMPT = \"\"\"You are a software engineering agent. Complete the task described below.\n\n## Task Access\n\nYour task is stored in the REPL variable `task`. To see it, run:\n\n```python\nprint(task)\n```\n\nYou MUST print this variable to see your assignment before proceeding.\n\n## Environment\n- Repository: /workspace\n- Python execution: Write ONE ```python block per response\n- Shell access via os.system()\n\n## CRITICAL RULES\n1. Each response must have exactly ONE ```python block\n2. Variables and imports PERSIST between responses - you can build on previous work\n3. You only need to import modules once per session\n4. Start with a THOUGHT section explaining your reasoning\n5. Wait for the result before your next action\n\n## Response Format\n\nTHOUGHT: [Your reasoning here]\n\n```python\n# Your single command here\n```\n\n## Commands\n\nView files (with line numbers):\n```python\nimport os\nos.system('nl -ba /workspace/path/to/file.py | head -50')\n```\n\nSearch:\n```python\nimport os\nos.system('grep -rn \"pattern\" /workspace/src/')\n```\n\nEdit files (REQUIRED - safe and validates syntax):\n```python\nresult = edit_file(\n    \"/workspace/path/to/file.py\",\n    \"def old_function():\",  # exact text to find (must be unique)\n    \"def new_function():\"   # replacement text\n)\nprint(result)  # Shows success or error message\n```\n\nThe edit_file() function:\n- Checks that old_string is unique (prevents wrong replacements)\n- Validates Python syntax BEFORE writing (catches errors early)\n- Use replace_all=True to replace multiple occurrences\n\n**NEVER use raw file I/O (open(), write(), writelines()).**\nAlways use edit_file() for ALL file modifications.\n\n## Sub-Agents (HIGHLY RECOMMENDED)\n\nYou have access to sub-agents that can help you explore and investigate. Each sub-agent:\n- Gets its own FRESH sandbox (clean repo copy)\n- Can spawn its own sub-agents for complex sub-tasks\n- Returns detailed findings you can act on\n\n**IMPORTANT: Do NOT try to read the entire codebase yourself.** If the task involves\nexploring multiple files, modules, or directories, spawn sub-agents to do it in parallel.\nThis is much faster and more effective than reading everything sequentially.\n\n**When to spawn sub-agents:**\n- Exploring unfamiliar codebases (spawn agents for different directories)\n- Tasks requiring investigation of multiple areas\n- Any time you'd need to read more than 3-4 files\n\n**Spawning pattern:**\n```python\nresults = rlm_query_batched([\n    \"Investigate [aspect 1] - read the relevant source files and report what you find\",\n    \"Investigate [aspect 2] - trace the code flow and identify the key components\",\n    \"Investigate [aspect 3] - check related files and understand the context\"\n])\nfor i, r in enumerate(results):\n    print(f\"=== Sub-agent {{i+1}} findings ===\")\n    print(r)\n```\n\n**Give sub-agents SELF-CONTAINED tasks.** Each sub-agent only sees its own task string -\nit has NO knowledge of what other sub-agents are doing or what the parent is working on.\nNever use relative references like \"remaining files\", \"the other modules\", or\n\"everything else\" - be explicit about exactly which files/directories each sub-agent\nshould examine.\n\n## Workflow\n1. Print task: see your assignment with print(task)\n2. Explore: find relevant files with grep/ls\n3. Read: view files with nl -ba to see line numbers\n4. Edit: use edit_file() with unique context strings\n5. Verify: check your changes work as expected\n6. Submit: generate diff with git diff\n\n## Submitting Your Work\n\n```python\nimport subprocess\nsubprocess.run(['git', 'add', '-A'], cwd='/workspace')\nresult = subprocess.run(['git', 'diff', '--cached', 'HEAD'],\n                        capture_output=True, text=True, cwd='/workspace')\nFINAL(result.stdout)\n```\"\"\"\n\n\nSUBAGENT_FRESH_PROMPT = \"\"\"You are a sub-agent spawned to help with a specific task.\n\n## Task Access\n\nYour task is stored in the REPL variable `task`. To see it, run:\n\n```python\nprint(task)\n```\n\nYou MUST print this variable to see your assignment before proceeding.\n\n## Your Role\n\nKey facts about your environment:\n- You have a FRESH copy of the repository (clean, no parent's edits)\n- Your job is to investigate/analyze and return findings\n- You CANNOT modify the parent's files\n- Return your findings as a string via FINAL(\"...\")\n\n## Environment\n- Repository: /workspace\n- Python execution: Write ONE ```python block per response\n- Variables and imports PERSIST between responses - you can build on previous work\n- Shell access via os.system()\n\n## Commands\n\n```python\nimport os\nos.system('nl -ba /workspace/file.py | head -50')  # View with line numbers\nos.system('grep -rn \"pattern\" /workspace/')  # Search\n\n# Edit files (safe - validates syntax before writing)\nresult = edit_file(\"/workspace/file.py\", \"old_text\", \"new_text\")\nprint(result)\n```\n\n{subagent_motivation}\n\n## Returning Results\n\n**CRITICAL**: Your parent agent ONLY sees what you put inside FINAL(). All your other\noutput (print statements, analysis, intermediate work) is NOT visible to them.\n\nPut your COMPLETE findings in FINAL() - file paths, line numbers, analysis, everything\nuseful you discovered. A short summary like \"Done\" or \"Analysis complete\" is useless;\nthe parent needs the actual details to act on them.\"\"\"\n\n\nSAFEGUARD_PROMPT = \"\"\"STOP. Do NOT edit files or call FINAL() yet.\n\nFirst:\n1. Print your task with print(task) to see your assignment\n2. Find relevant files with grep\n3. Read them with nl -ba to see line numbers\n4. Understand the code before making changes\"\"\"\n\n\ndef get_subagent_motivation(depth: int) -> str:\n    \"\"\"\n    Get sub-agent motivation text based on depth.\n\n    Depth 1: Strong encouragement to use sub-agents\n    Depth 2+: Neutral - sub-agents available but not pushed\n    \"\"\"\n    if depth == 1:\n        return \"\"\"## Sub-Agents (HIGHLY RECOMMENDED)\n\nYou can spawn sub-agents to help with your investigation. Each sub-agent:\n- Gets its own FRESH sandbox (clean repo copy)\n- Can explore independently and return findings\n- Runs in parallel when using rlm_query_batched()\n\n**IMPORTANT: Do NOT try to read many files yourself.** If your task requires exploring\nmultiple files or directories, spawn sub-agents to do it in parallel. This is faster\nand more thorough.\n\n**When to spawn sub-agents:**\n- Your task involves multiple files or modules\n- You need to search across different parts of the codebase\n- Any time you'd need to read more than 2-3 files\n\n**Spawning pattern:**\n```python\nresults = rlm_query_batched([\n    \"Investigate [aspect 1] and report findings\",\n    \"Investigate [aspect 2] and report findings\"\n])\nfor i, r in enumerate(results):\n    print(f\"=== Sub-agent {{i+1}} ===\")\n    print(r)\n```\n\n**Give sub-agents SELF-CONTAINED tasks.** Each sub-agent only sees its own task string -\nit has NO knowledge of what other sub-agents are doing. Never use relative references\nlike \"remaining files\" or \"the other modules\" - be explicit about exactly which\nfiles/directories each sub-agent should examine.\"\"\"\n\n    # depth >= 2\n    return \"\"\"## Sub-Agents\n\nYou can spawn sub-agents if needed for complex sub-tasks:\n```python\nresult = rlm_query(\"Specific task description\")\n# or for parallel execution:\nresults = rlm_query_batched([\"Task 1\", \"Task 2\"])\n```\n\nEach sub-agent gets its own fresh sandbox and returns findings as a string.\"\"\"\n\n\ndef build_system_prompt(depth: int) -> str:\n    \"\"\"\n    Build the system prompt for an agent.\n\n    Tasks are stored in REPL variables and accessed via print(task),\n    not embedded in the system prompt.\n\n    Args:\n        depth: Agent depth (0 = root)\n\n    Returns:\n        System prompt string\n    \"\"\"\n    if depth == 0:\n        return ROOT_AGENT_PROMPT\n\n    # Get depth-based motivation for sub-agents\n    motivation = get_subagent_motivation(depth)\n\n    return SUBAGENT_FRESH_PROMPT.format(\n        subagent_motivation=motivation,\n    )\n\n\ndef build_user_prompt(iteration: int, execution_result: str | None = None) -> str:\n    \"\"\"\n    Build the user prompt for an iteration.\n\n    Args:\n        iteration: Current iteration number (0-indexed)\n        execution_result: Result from previous code execution\n\n    Returns:\n        User prompt string\n    \"\"\"\n    if iteration == 0:\n        return SAFEGUARD_PROMPT + \"\\n\\nBegin by exploring the codebase.\"\n\n    parts = []\n    if execution_result:\n        parts.append(execution_result)\n\n    if iteration < 3:\n        parts.append(\"\\nContinue investigating.\")\n    else:\n        parts.append(\"\\nContinue. If ready, make your changes and submit via FINAL().\")\n\n    return \"\\n\".join(parts)\n\n\ndef format_execution_result(code: str, stdout: str, stderr: str, error: str | None = None) -> str:\n    \"\"\"\n    Format code execution result for display to the model.\n\n    Args:\n        code: The executed code\n        stdout: Standard output\n        stderr: Standard error\n        error: Error message if any\n\n    Returns:\n        Formatted result string\n    \"\"\"\n    parts = [f\"```python\\n{code}\\n```\"]\n\n    if stdout:\n        parts.append(f\"\\nOutput:\\n```\\n{stdout}\\n```\")\n\n    if stderr:\n        parts.append(f\"\\nStderr:\\n```\\n{stderr}\\n```\")\n\n    if error:\n        parts.append(f\"\\nError:\\n```\\n{error}\\n```\")\n\n    return \"\\n\".join(parts)\n"
  },
  {
    "path": "guides/python/recursive-language-models/rlm/repl.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"REPL execution for deeper-rlm agents.\n\nUses a broker server pattern for blocking rlm_query() calls:\n- Flask broker server runs inside the sandbox on port 8080\n- Sandbox code calls rlm_query() which POSTs to broker and BLOCKS\n- External poller thread polls broker for pending requests\n- Poller spawns sub-agent, gets result, POSTs back to broker\n- Sandbox code unblocks with actual result\n\"\"\"\n\nimport base64\nimport json\nimport logging\nimport re\nimport textwrap\nimport time\nfrom dataclasses import dataclass, field\nfrom threading import Event, Lock, Thread\nfrom typing import TYPE_CHECKING, Callable\n\nimport requests\nfrom rlm.types import CodeBlockResult\n\nfrom daytona import SessionExecuteRequest\n\nif TYPE_CHECKING:\n    from daytona import Sandbox\n\n\ndef _retry_file_op(op_func, max_retries: int = 3, operation_name: str = \"file operation\"):\n    \"\"\"Retry a file operation on transient errors (307 redirects, 502, etc).\"\"\"\n    last_error = None\n    for attempt in range(max_retries):\n        try:\n            return op_func()\n        except Exception as e:\n            last_error = e\n            error_str = str(e)\n            # Retry on redirect or gateway errors\n            if any(x in error_str for x in [\"307\", \"302\", \"502\", \"503\", \"504\", \"Redirect\", \"Gateway\"]):\n                if attempt < max_retries - 1:\n                    logger.warning(f\"{operation_name} failed, retrying ({attempt + 1}/{max_retries}): {e}\")\n                    time.sleep(2 * (attempt + 1))\n                    continue\n            raise\n    raise last_error\n\n\nlogger = logging.getLogger(__name__)\n\n\n# Regex pattern to find ```python code blocks\nCODE_BLOCK_PATTERN = re.compile(\n    r\"```python\\s*\\n(.*?)```\",\n    re.DOTALL | re.IGNORECASE,\n)\n\n# =============================================================================\n# Broker Server Script (runs inside sandbox, handles rlm_query request queue)\n# =============================================================================\n\n_BROKER_SCRIPT = textwrap.dedent(\n    '''\nimport json\nimport threading\nimport time\nimport uuid\nfrom flask import Flask, request, jsonify\n\napp = Flask(__name__)\n\n# Request queue: {request_id: {\"request\": {...}, \"response\": None, \"event\": Event}}\npending_requests = {}\nlock = threading.Lock()\ncondition = threading.Condition(lock)\n\n@app.route(\"/health\")\ndef health():\n    return jsonify({\"status\": \"ok\"})\n\n@app.route(\"/enqueue\", methods=[\"POST\"])\ndef enqueue():\n    \"\"\"Called by sandbox code to submit an rlm_query request and wait for response.\"\"\"\n    data = request.json\n    request_id = str(uuid.uuid4())\n    event = threading.Event()\n\n    with condition:\n        pending_requests[request_id] = {\n            \"request\": data,\n            \"response\": None,\n            \"event\": event,\n        }\n        condition.notify_all()  # Wake up any waiting /pending calls\n\n    # Wait for response (with timeout)\n    event.wait(timeout=1800)\n\n    with lock:\n        entry = pending_requests.pop(request_id, None)\n\n    if entry and entry[\"response\"] is not None:\n        return jsonify(entry[\"response\"])\n    else:\n        return jsonify({\"error\": \"Request timed out\"}), 504\n\n@app.route(\"/pending\")\ndef get_pending():\n    \"\"\"Called by parent process poller to long-poll for pending requests.\"\"\"\n    timeout_s = float(request.args.get(\"timeout_s\", 0))\n    deadline = time.time() + timeout_s\n\n    with condition:\n        while True:\n            pending = [\n                {\"id\": rid, \"request\": entry[\"request\"]}\n                for rid, entry in pending_requests.items()\n                if entry[\"response\"] is None\n            ]\n            if pending or time.time() >= deadline:\n                return jsonify({\"pending\": pending})\n\n            remaining = deadline - time.time()\n            if remaining <= 0:\n                return jsonify({\"pending\": []})\n            condition.wait(timeout=min(remaining, 1.0))\n\n@app.route(\"/respond\", methods=[\"POST\"])\ndef respond():\n    \"\"\"Called by parent process poller to submit a response.\"\"\"\n    data = request.json\n    request_id = data.get(\"id\")\n    response = data.get(\"response\")\n\n    with lock:\n        if request_id in pending_requests:\n            pending_requests[request_id][\"response\"] = response\n            pending_requests[request_id][\"event\"].set()\n            return jsonify({\"status\": \"ok\"})\n\n    return jsonify({\"error\": \"Request not found\"}), 404\n\nif __name__ == \"__main__\":\n    app.run(host=\"0.0.0.0\", port=8080, threaded=True)\n'''\n)\n\n\n@dataclass\nclass REPLResult:\n    \"\"\"Result of executing code in the REPL.\"\"\"\n\n    code_blocks: list[CodeBlockResult] = field(default_factory=list)\n    final_answer: str | None = None\n    final_var_name: str | None = None\n\n\ndef find_code_blocks(response: str) -> list[str]:\n    \"\"\"Extract Python code blocks from a model response.\"\"\"\n    matches = CODE_BLOCK_PATTERN.findall(response)\n    return [match.strip() for match in matches if match.strip()]\n\n\ndef find_final_answer(response: str) -> tuple[str | None, str | None]:\n    \"\"\"Find FINAL() or FINAL_VAR() call in response.\"\"\"\n    final_match = re.search(r'FINAL\\s*\\(\\s*[\"\\'](.+?)[\"\\']\\s*\\)', response, re.DOTALL)\n    if final_match:\n        return final_match.group(1), \"FINAL\"\n\n    final_var_match = re.search(r\"FINAL\\s*\\(\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*\\)\", response)\n    if final_var_match:\n        return final_var_match.group(1), \"FINAL_VAR\"\n\n    final_var_match2 = re.search(r'FINAL_VAR\\s*\\(\\s*[\"\\'](.+?)[\"\\']\\s*\\)', response)\n    if final_var_match2:\n        return final_var_match2.group(1), \"FINAL_VAR\"\n\n    return None, None\n\n\nclass DaytonaREPL:\n    \"\"\"\n    REPL environment that executes Python code in a Daytona sandbox.\n\n    Uses a broker server pattern for blocking rlm_query() calls:\n    - Flask broker runs inside sandbox on port 8080\n    - rlm_query() blocks until sub-agent returns result\n    - External poller thread handles sub-agent spawning\n    \"\"\"\n\n    BROKER_PORT = 8080\n    LONG_POLL_TIMEOUT = 30  # seconds\n\n    def __init__(\n        self,\n        sandbox: \"Sandbox\",\n        rlm_query_handler: Callable[[str], str],\n        rlm_query_batched_handler: Callable[[list[str]], list[str]],\n        cwd: str = \"/workspace\",\n        conda_env: str = \"testbed\",\n        initial_variables: dict[str, str] | None = None,\n    ):\n        \"\"\"\n        Initialize the REPL.\n\n        Args:\n            sandbox: Daytona sandbox instance\n            rlm_query_handler: Callback for rlm_query() - spawns sub-agent\n            rlm_query_batched_handler: Callback for rlm_query_batched()\n            cwd: Working directory\n            conda_env: Conda environment\n            initial_variables: Variables to inject into the REPL namespace (e.g., {\"task\": \"...\"})\n        \"\"\"\n        self.sandbox = sandbox\n        self.cwd = cwd\n        self.conda_env = conda_env\n        self.rlm_query_handler = rlm_query_handler\n        self.rlm_query_batched_handler = rlm_query_batched_handler\n        self.initial_variables = initial_variables or {}\n\n        # Broker state\n        self.broker_session_id: str | None = None\n        self.broker_url: str | None = None\n        self.broker_token: str | None = None\n        self.poller_thread: Thread | None = None\n        self.poller_stop: Event = Event()\n        self._poller_lock: Lock = Lock()\n\n        # REPL state\n        self._final_answer: str | None = None\n        self._final_var_name: str | None = None\n\n        # Start broker\n        self._start_broker()\n\n    def _start_broker(self):\n        \"\"\"Start the broker server in the sandbox and begin polling.\"\"\"\n        logger.info(\"Starting broker server in sandbox...\")\n\n        # Upload broker script with retry\n        _retry_file_op(\n            lambda: self.sandbox.fs.upload_file(_BROKER_SCRIPT.encode(\"utf-8\"), \"/tmp/rlm_broker.py\"),\n            operation_name=\"broker script upload\",\n        )\n\n        # Install flask in the conda environment (may already be installed)\n        logger.info(\"Installing flask in sandbox...\")\n        if self.conda_env:\n            install_cmd = f\"conda run -n {self.conda_env} pip install flask requests dill -q\"\n        else:\n            install_cmd = \"pip install flask requests dill -q\"\n        self.sandbox.process.exec(install_cmd, timeout=120)\n\n        # Start broker in background session with conda env\n        self.broker_session_id = \"rlm-broker\"\n        self.sandbox.process.create_session(self.broker_session_id)\n\n        if self.conda_env:\n            broker_cmd = f\"conda run -n {self.conda_env} python /tmp/rlm_broker.py\"\n        else:\n            broker_cmd = \"python /tmp/rlm_broker.py\"\n\n        self.sandbox.process.execute_session_command(\n            self.broker_session_id,\n            SessionExecuteRequest(\n                command=broker_cmd,\n                run_async=True,\n            ),\n        )\n\n        # Get preview URL for HTTP communication\n        preview = self.sandbox.get_preview_link(self.BROKER_PORT)\n        self.broker_url = preview.url\n        self.broker_token = preview.token\n        logger.info(f\"Broker URL: {self.broker_url}\")\n\n        # Wait for broker to be ready\n        self._wait_for_broker()\n\n        # Start polling thread\n        self.poller_stop.clear()\n        self.poller_thread = Thread(target=self._poll_broker, daemon=True)\n        self.poller_thread.start()\n        logger.info(\"Broker poller thread started\")\n\n    def _preview_headers(self) -> dict[str, str]:\n        \"\"\"Return headers required for preview URL authentication.\"\"\"\n        return {\n            \"X-Daytona-Preview-Token\": self.broker_token or \"\",\n            \"X-Daytona-Skip-Preview-Warning\": \"true\",\n        }\n\n    def _wait_for_broker(self, max_wait: int = 30):\n        \"\"\"Wait for broker to be ready by probing /health endpoint.\"\"\"\n        logger.info(\"Waiting for broker to be ready...\")\n        for i in range(max_wait * 2):\n            try:\n                resp = requests.get(\n                    f\"{self.broker_url}/health\",\n                    headers=self._preview_headers(),\n                    timeout=2,\n                )\n                if resp.ok:\n                    logger.info(f\"Broker ready after {i * 0.5:.1f}s\")\n                    return\n            except requests.RequestException:\n                pass\n            time.sleep(0.5)\n        raise TimeoutError(\"Broker failed to start within timeout\")\n\n    def _poll_broker(self):\n        \"\"\"Poll the broker for pending rlm_query requests using long-polling.\"\"\"\n        session = requests.Session()\n        logger.info(\"Broker poller started\")\n\n        while not self.poller_stop.is_set():\n            try:\n                resp = session.get(\n                    f\"{self.broker_url}/pending\",\n                    params={\"timeout_s\": self.LONG_POLL_TIMEOUT},\n                    headers=self._preview_headers(),\n                    timeout=self.LONG_POLL_TIMEOUT + 5,\n                )\n\n                for item in resp.json().get(\"pending\", []):\n                    request_id = item[\"id\"]\n                    req_data = item[\"request\"]\n\n                    # Handle the request\n                    response = self._handle_request(req_data)\n\n                    # Post response back to broker\n                    session.post(\n                        f\"{self.broker_url}/respond\",\n                        headers=self._preview_headers(),\n                        json={\"id\": request_id, \"response\": response},\n                        timeout=10,\n                    )\n\n            except requests.RequestException as e:\n                if not self.poller_stop.is_set():\n                    logger.debug(f\"Poller request failed: {e}\")\n                    time.sleep(1)\n\n        logger.info(\"Broker poller stopped\")\n\n    def _handle_request(self, req_data: dict) -> dict:\n        \"\"\"Handle an rlm_query request from the sandbox.\"\"\"\n        req_type = req_data.get(\"type\")\n\n        if req_type == \"single\":\n            task = req_data.get(\"task\", \"\")\n            logger.info(f\"Handling rlm_query: {task[:60]}...\")\n            try:\n                result = self.rlm_query_handler(task)\n                return {\"result\": result}\n            except Exception as e:\n                logger.exception(f\"Error handling rlm_query: {e}\")\n                return {\"error\": str(e)}\n\n        elif req_type == \"batched\":\n            tasks = req_data.get(\"tasks\", [])\n            logger.info(f\"Handling rlm_query_batched with {len(tasks)} tasks\")\n            try:\n                results = self.rlm_query_batched_handler(tasks)\n                return {\"results\": results}\n            except Exception as e:\n                logger.exception(f\"Error handling rlm_query_batched: {e}\")\n                return {\"error\": str(e)}\n\n        return {\"error\": f\"Unknown request type: {req_type}\"}\n\n    def _build_execution_script(self, code: str) -> str:\n        \"\"\"\n        Build a Python script that executes code with blocking rlm_query().\n\n        The script:\n        - Sets up rlm_query() that blocks via HTTP to broker\n        - Sets up FINAL/FINAL_VAR functions\n        - Injects initial variables (e.g., task) into the namespace\n        - Executes the user code\n        - Captures stdout/stderr\n        - Uses dill for state persistence (variables AND imports persist)\n        \"\"\"\n        code_b64 = base64.b64encode(code.encode()).decode()\n\n        # Encode initial variables as base64 to avoid escaping issues\n        initial_vars_b64 = base64.b64encode(json.dumps(self.initial_variables).encode()).decode()\n\n        return textwrap.dedent(\n            f'''\nimport sys\nimport io\nimport json\nimport base64\nimport traceback\nimport os\nimport requests\n\ntry:\n    import dill\nexcept ImportError:\n    import pickle as dill\n\n# =============================================================================\n# File Editing Function (Claude Code style)\n# =============================================================================\n\ndef edit_file(file_path: str, old_string: str, new_string: str, replace_all: bool = False) -> str:\n    \"\"\"\n    Edit a file by replacing old_string with new_string.\n\n    Args:\n        file_path: Path to the file to edit\n        old_string: The exact text to find and replace (must be unique unless replace_all=True)\n        new_string: The text to replace it with\n        replace_all: If True, replace all occurrences. If False, old_string must be unique.\n\n    Returns:\n        Success message or error description\n\n    Example:\n        edit_file(\"/workspace/src/module.py\", \"def old_func():\", \"def new_func():\")\n    \"\"\"\n    import os\n\n    # Check file exists\n    if not os.path.exists(file_path):\n        return \"Error: File not found: {{}}\".format(file_path)\n\n    # Read file\n    try:\n        with open(file_path, 'r', encoding='utf-8') as f:\n            content = f.read()\n    except Exception as e:\n        return \"Error reading file: {{}}\".format(e)\n\n    # Check old_string exists\n    if old_string not in content:\n        # Provide helpful debug info\n        lines = old_string.split('\\\\n')\n        first_line = lines[0][:50] if lines else old_string[:50]\n        return \"Error: old_string not found in {{}}. First line: '{{}}...'\".format(\n            file_path, first_line)\n\n    # Check uniqueness (unless replace_all)\n    count = content.count(old_string)\n    if count > 1 and not replace_all:\n        return \"Error: old_string appears {{}} times in {{}}. \".format(count, file_path) + \\\n            \"Use replace_all=True or provide more context to make it unique.\"\n\n    # Perform replacement\n    if replace_all:\n        new_content = content.replace(old_string, new_string)\n        replaced_count = count\n    else:\n        new_content = content.replace(old_string, new_string, 1)\n        replaced_count = 1\n\n    # Verify the edit was valid Python if it's a .py file\n    if file_path.endswith('.py'):\n        try:\n            compile(new_content, file_path, 'exec')\n        except SyntaxError as e:\n            return \"Error: Edit would create invalid Python syntax: {{}}\".format(e)\n\n    # Write file\n    try:\n        with open(file_path, 'w', encoding='utf-8') as f:\n            f.write(new_content)\n    except Exception as e:\n        return \"Error writing file: {{}}\".format(e)\n\n    suffix = 's' if replaced_count > 1 else ''\n    return \"Successfully edited {{}} ({{}} replacement{{}})\".format(\n        file_path, replaced_count, suffix)\n\n\n# =============================================================================\n# LLM Query Functions (via local broker - BLOCKING)\n# =============================================================================\n\nBROKER_URL = \"http://127.0.0.1:{self.BROKER_PORT}\"\n\ndef rlm_query(task: str) -> str:\n    \"\"\"Query a sub-agent via the broker. BLOCKS until result is ready.\"\"\"\n    try:\n        response = requests.post(\n            BROKER_URL + \"/enqueue\",\n            json={{\"type\": \"single\", \"task\": task}},\n            timeout=1800,\n        )\n        data = response.json()\n        if data.get(\"error\"):\n            return \"Error: {{}}\".format(data['error'])\n        return data.get(\"result\", \"Error: No result\")\n    except Exception as e:\n        return \"Error: rlm_query failed - {{}}\".format(e)\n\n\ndef rlm_query_batched(tasks: list) -> list:\n    \"\"\"Query multiple sub-agents in parallel. BLOCKS until all results ready.\"\"\"\n    try:\n        response = requests.post(\n            BROKER_URL + \"/enqueue\",\n            json={{\"type\": \"batched\", \"tasks\": tasks}},\n            timeout=1800,\n        )\n        data = response.json()\n        if data.get(\"error\"):\n            return [\"Error: {{}}\".format(data['error'])] * len(tasks)\n        return data.get(\"results\", [\"Error: No result\"] * len(tasks))\n    except Exception as e:\n        return [\"Error: rlm_query_batched failed - {{}}\".format(e)] * len(tasks)\n\n\n# =============================================================================\n# State Management (using dill for complex objects including modules)\n# =============================================================================\n\nSTATE_FILE = \"/tmp/rlm_state.dill\"\n\ndef load_state():\n    if os.path.exists(STATE_FILE):\n        try:\n            with open(STATE_FILE, \"rb\") as f:\n                return dill.load(f)\n        except:\n            pass\n    return {{}}\n\ndef save_state(state):\n    clean_state = {{}}\n    for k, v in state.items():\n        if k.startswith(\"_\"):\n            continue\n        try:\n            dill.dumps(v)\n            clean_state[k] = v\n        except:\n            pass\n    with open(STATE_FILE, \"wb\") as f:\n        dill.dump(clean_state, f)\n\ndef serialize_locals(state):\n    result = {{}}\n    for k, v in state.items():\n        if k.startswith(\"_\"):\n            continue\n        try:\n            result[k] = repr(v)\n        except:\n            result[k] = \"<{{}}>\".format(type(v).__name__)\n    return result\n\n# =============================================================================\n# FINAL functions\n# =============================================================================\n\n_final_answer = None\n_final_var_name = None\n\ndef FINAL(answer):\n    \"\"\"Return final answer to parent.\"\"\"\n    global _final_answer\n    _final_answer = str(answer)\n\ndef FINAL_VAR(variable_name):\n    \"\"\"Return a variable as final answer.\"\"\"\n    global _final_var_name\n    _final_var_name = variable_name.strip().strip(\"\\\\\"\\\\'\")\n\n# =============================================================================\n# Execution\n# =============================================================================\n\n_locals = load_state()\n\n_globals = {{\n    \"__builtins__\": __builtins__,\n    \"__name__\": \"__main__\",\n    \"rlm_query\": rlm_query,\n    \"rlm_query_batched\": rlm_query_batched,\n    \"FINAL\": FINAL,\n    \"FINAL_VAR\": FINAL_VAR,\n    \"edit_file\": edit_file,\n}}\n\n# Inject initial variables (e.g., task)\n_initial_vars = json.loads(base64.b64decode(\"{initial_vars_b64}\").decode())\n_globals.update(_initial_vars)\n\ncode = base64.b64decode(\"{code_b64}\").decode()\n\nstdout_buf = io.StringIO()\nstderr_buf = io.StringIO()\nold_stdout, old_stderr = sys.stdout, sys.stderr\n\ntry:\n    sys.stdout = stdout_buf\n    sys.stderr = stderr_buf\n    combined = {{**_globals, **_locals}}\n    exec(code, combined, combined)\n    # Update locals with new variables\n    for key, value in combined.items():\n        if key not in _globals and not key.startswith(\"_\"):\n            _locals[key] = value\nexcept Exception as e:\n    traceback.print_exc(file=stderr_buf)\nfinally:\n    sys.stdout = old_stdout\n    sys.stderr = old_stderr\n\nsave_state(_locals)\n\n# Handle FINAL_VAR\n_final_answer_resolved = _final_answer\nif _final_var_name and _final_var_name in _locals:\n    _final_answer_resolved = str(_locals[_final_var_name])\n\n# Print stdout first\nprint(stdout_buf.getvalue(), end=\"\")\n\n# Print JSON result marker\nprint(\"___REPL_RESULT___\", end=\"\")\nprint(json.dumps({{\n    \"stderr\": stderr_buf.getvalue(),\n    \"final_answer\": _final_answer_resolved,\n    \"final_var_name\": _final_var_name,\n    \"locals\": serialize_locals(_locals),\n}}))\n'''\n        )\n\n    def execute_code(self, code: str) -> CodeBlockResult:\n        \"\"\"Execute a Python code block in the sandbox.\"\"\"\n        start_time = time.time()\n\n        # Build execution script\n        script = self._build_execution_script(code)\n\n        # Write script to file to avoid shell escaping issues (with retry)\n        _retry_file_op(\n            lambda: self.sandbox.fs.upload_file(script.encode(\"utf-8\"), \"/tmp/exec_script.py\"),\n            operation_name=\"exec script upload\",\n        )\n\n        # Execute in sandbox with conda environment\n        if self.conda_env:\n            cmd = f\"conda run -n {self.conda_env} --no-capture-output python /tmp/exec_script.py\"\n        else:\n            cmd = \"python /tmp/exec_script.py\"\n\n        # Execute with retry for transient errors (502, etc)\n        max_retries = 3\n        for attempt in range(max_retries):\n            try:\n                result = self.sandbox.process.exec(cmd, cwd=self.cwd, timeout=1800)\n                break\n            except Exception as e:\n                error_str = str(e)\n                # Retry on 502/503/504 gateway errors\n                if any(code in error_str for code in [\"502\", \"503\", \"504\", \"Bad Gateway\"]):\n                    if attempt < max_retries - 1:\n                        logger.warning(\n                            f\"Command execution failed with gateway error, \" f\"retrying ({attempt + 1}/{max_retries})\"\n                        )\n                        time.sleep(2 * (attempt + 1))\n                        continue\n                raise\n\n        execution_time = time.time() - start_time\n        output = result.result or \"\"\n\n        # Parse output\n        stdout = \"\"\n        stderr = \"\"\n        error = None\n\n        try:\n            if \"___REPL_RESULT___\" in output:\n                parts = output.split(\"___REPL_RESULT___\")\n                stdout = parts[0]\n                if len(parts) > 1:\n                    result_json = json.loads(parts[1])\n                    stderr = result_json.get(\"stderr\", \"\")\n                    self._final_answer = result_json.get(\"final_answer\")\n                    self._final_var_name = result_json.get(\"final_var_name\")\n            else:\n                stdout = output\n                if result.exit_code != 0:\n                    error = output\n        except (json.JSONDecodeError, IndexError) as e:\n            stdout = output\n            logger.warning(f\"Failed to parse REPL result: {e}\")\n\n        return CodeBlockResult(\n            code=code,\n            stdout=stdout,\n            stderr=stderr,\n            execution_time=execution_time,\n            error=error,\n        )\n\n    def execute_response(self, response: str) -> REPLResult:\n        \"\"\"Execute all Python code blocks in a model response.\"\"\"\n        result = REPLResult()\n\n        # Find and execute Python code blocks\n        code_blocks = find_code_blocks(response)\n\n        for code in code_blocks:\n            block_result = self.execute_code(code)\n            result.code_blocks.append(block_result)\n\n            # Check for final answer\n            if self._final_answer is not None:\n                result.final_answer = self._final_answer\n                break\n            if self._final_var_name is not None:\n                result.final_var_name = self._final_var_name\n                break\n\n        # Also check response text for FINAL() that might not be in code\n        if result.final_answer is None and result.final_var_name is None:\n            answer, answer_type = find_final_answer(response)\n            if answer_type == \"FINAL\":\n                result.final_answer = answer\n            elif answer_type == \"FINAL_VAR\":\n                result.final_var_name = answer\n\n        return result\n\n    def cleanup(self):\n        \"\"\"Stop the broker and cleanup resources.\"\"\"\n        logger.info(\"Cleaning up REPL...\")\n\n        # Stop poller thread\n        self.poller_stop.set()\n        if self.poller_thread is not None:\n            self.poller_thread.join(timeout=2)\n            self.poller_thread = None\n\n        # Delete broker session\n        if self.broker_session_id:\n            try:\n                self.sandbox.process.delete_session(self.broker_session_id)\n            except Exception as e:\n                logger.debug(f\"Failed to delete broker session: {e}\")\n            self.broker_session_id = None\n\n    def __del__(self):\n        self.cleanup()\n"
  },
  {
    "path": "guides/python/recursive-language-models/rlm/sandbox.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Daytona sandbox management for deeper-rlm.\"\"\"\n\nimport logging\nfrom dataclasses import dataclass\nfrom typing import TYPE_CHECKING, Any\n\nfrom rlm.budget import SandboxBudget\n\nfrom daytona import CreateSandboxFromImageParams, Daytona, DaytonaConfig, Image\n\nif TYPE_CHECKING:\n    from daytona import Sandbox\n\n\nlogger = logging.getLogger(__name__)\n\n\n@dataclass\nclass SandboxInfo:\n    \"\"\"Information about a sandbox.\"\"\"\n\n    sandbox_id: str\n    instance_id: str\n\n\nclass SandboxManager:\n    \"\"\"\n    Manages Daytona sandboxes for RLM agents.\n\n    Handles:\n    - Sandbox creation from GitHub repos\n    - Budget tracking\n    - Sandbox cleanup\n    \"\"\"\n\n    def __init__(\n        self,\n        api_key: str,\n        budget: SandboxBudget,\n    ):\n        \"\"\"\n        Initialize the sandbox manager.\n\n        Args:\n            api_key: Daytona API key\n            budget: Shared sandbox budget tracker\n        \"\"\"\n        self.budget = budget\n\n        # Initialize Daytona client\n        daytona_config = DaytonaConfig(api_key=api_key)\n        self.daytona = Daytona(daytona_config)\n\n        # Track active sandboxes\n        self._active_sandboxes: dict[str, \"Sandbox\"] = {}\n\n    def create_sandbox_from_repo(\n        self,\n        repo_url: str,\n        branch: str | None = None,\n        commit: str | None = None,\n    ) -> tuple[\"Sandbox\", SandboxInfo]:\n        \"\"\"\n        Create a sandbox from a GitHub repository.\n\n        Args:\n            repo_url: GitHub repository URL\n            branch: Optional branch name (default: repo's default branch)\n            commit: Optional commit SHA to checkout\n\n        Returns:\n            Tuple of (Sandbox, SandboxInfo)\n\n        Raises:\n            RuntimeError: If budget exhausted or sandbox creation fails\n        \"\"\"\n        # Check budget\n        if not self.budget.try_acquire():\n            raise RuntimeError(\n                f\"Cannot create sandbox - budget exhausted \" f\"({self.budget.status.created}/{self.budget.max} used)\"\n            )\n\n        try:\n            # Create a base image with git installed (needed for agent to produce diffs)\n            base_image = (\n                Image.debian_slim(\"3.11\").run_commands(\"apt-get update && apt-get install -y git\").workdir(\"/workspace\")\n            )\n\n            logger.info(f\"Creating sandbox from base image for repo: {repo_url}\")\n            sandbox = self.daytona.create(\n                CreateSandboxFromImageParams(image=base_image),\n                timeout=0,  # No timeout for image build\n                on_snapshot_create_logs=lambda msg: logger.debug(f\"Image build: {msg}\"),\n            )\n\n            # Clone the repository\n            logger.info(f\"Cloning repository: {repo_url}\")\n            sandbox.git.clone(\n                url=repo_url,\n                path=\"/workspace\",\n                branch=branch,\n            )\n\n            # Checkout specific commit if provided\n            if commit:\n                logger.info(f\"Checking out commit: {commit}\")\n                result = sandbox.process.exec(\n                    f\"git checkout {commit}\",\n                    cwd=\"/workspace\",\n                    timeout=60,\n                )\n                if result.exit_code != 0:\n                    raise RuntimeError(f\"Failed to checkout commit {commit}: {result.result}\")\n\n            # Extract repo name for info\n            repo_name = repo_url.rstrip(\"/\").split(\"/\")[-1].replace(\".git\", \"\")\n\n            info = SandboxInfo(\n                sandbox_id=sandbox.id,\n                instance_id=repo_name,\n            )\n\n            self._active_sandboxes[sandbox.id] = sandbox\n            logger.info(f\"Sandbox created: {sandbox.id}\")\n\n            return sandbox, info\n\n        except Exception as e:\n            # Release budget on failure\n            self.budget.release()\n            raise RuntimeError(f\"Failed to create sandbox from repo: {e}\") from e\n\n    def delete_sandbox(self, sandbox_id: str) -> None:\n        \"\"\"\n        Delete a sandbox and release budget.\n\n        Args:\n            sandbox_id: ID of sandbox to delete\n        \"\"\"\n        sandbox = self._active_sandboxes.pop(sandbox_id, None)\n        if sandbox is not None:\n            try:\n                sandbox.delete()\n                logger.info(f\"Sandbox deleted: {sandbox_id}\")\n            except Exception as e:\n                logger.warning(f\"Error deleting sandbox {sandbox_id}: {e}\")\n            finally:\n                self.budget.release()\n\n    def get_sandbox(self, sandbox_id: str) -> \"Sandbox | None\":\n        \"\"\"Get an active sandbox by ID.\"\"\"\n        return self._active_sandboxes.get(sandbox_id)\n\n    def cleanup_all(self) -> None:\n        \"\"\"Clean up all active sandboxes.\"\"\"\n        sandbox_ids = list(self._active_sandboxes.keys())\n        for sandbox_id in sandbox_ids:\n            self.delete_sandbox(sandbox_id)\n\n\nclass SandboxExecutor:\n    \"\"\"\n    Executes commands in a Daytona sandbox.\n\n    Wraps commands with conda environment activation.\n    \"\"\"\n\n    def __init__(self, sandbox: \"Sandbox\", cwd: str = \"/workspace\", conda_env: str = \"testbed\"):\n        \"\"\"\n        Initialize the executor.\n\n        Args:\n            sandbox: Daytona sandbox instance\n            cwd: Default working directory\n            conda_env: Conda environment to activate\n        \"\"\"\n        self.sandbox = sandbox\n        self.cwd = cwd\n        self.conda_env = conda_env\n\n    def execute(\n        self,\n        command: str,\n        cwd: str | None = None,\n        timeout: int = 120,\n    ) -> dict[str, Any]:\n        \"\"\"\n        Execute a command in the sandbox.\n\n        Args:\n            command: Shell command to execute\n            cwd: Working directory (defaults to self.cwd)\n            timeout: Timeout in seconds\n\n        Returns:\n            Dict with 'output' and 'returncode'\n        \"\"\"\n        effective_cwd = cwd or self.cwd\n        wrapped_command = self._wrap_command(command)\n\n        logger.debug(f\"Executing: {command}\")\n        logger.debug(f\"Wrapped: {wrapped_command}\")\n\n        try:\n            response = self.sandbox.process.exec(\n                wrapped_command,\n                cwd=effective_cwd,\n                timeout=timeout,\n            )\n\n            return {\n                \"output\": response.result or \"\",\n                \"returncode\": response.exit_code,\n            }\n        except Exception as e:\n            logger.error(f\"Command execution error: {e}\")\n            return {\n                \"output\": str(e),\n                \"returncode\": 1,\n            }\n\n    def _wrap_command(self, command: str) -> str:\n        \"\"\"Wrap command with conda environment activation.\"\"\"\n        quoted = self._shell_quote(command)\n        return f\"conda run -n {self.conda_env} --no-capture-output bash -c {quoted}\"\n\n    def _shell_quote(self, s: str) -> str:\n        \"\"\"Safely quote a string for shell execution.\"\"\"\n        return \"'\" + s.replace(\"'\", \"'\\\"'\\\"'\") + \"'\"\n"
  },
  {
    "path": "guides/python/recursive-language-models/rlm/types.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Core type definitions for deeper-rlm.\"\"\"\n\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\nfrom typing import Any\n\nimport yaml\n\n\n@dataclass\nclass ModelConfig:\n    \"\"\"LLM model configuration.\"\"\"\n\n    name: str  # LiteLLM format, e.g. \"openrouter/google/gemini-3-flash-preview\"\n\n\n@dataclass\nclass RLMConfig:\n    \"\"\"RLM execution configuration.\"\"\"\n\n    max_sandboxes: int\n    max_iterations: int\n    global_timeout: int\n    result_truncation_limit: int\n\n\n@dataclass\nclass Config:\n    \"\"\"Complete configuration.\"\"\"\n\n    model: ModelConfig\n    rlm: RLMConfig\n\n    @classmethod\n    def from_yaml(cls, path: str | Path) -> \"Config\":\n        \"\"\"Load configuration from a YAML file.\"\"\"\n        with open(path) as f:\n            data: dict[str, Any] = yaml.safe_load(f)\n\n        model = data[\"model\"]\n        rlm = data[\"rlm\"]\n\n        return cls(\n            model=ModelConfig(name=model[\"name\"]),\n            rlm=RLMConfig(\n                max_sandboxes=rlm[\"max_sandboxes\"],\n                max_iterations=rlm[\"max_iterations\"],\n                global_timeout=rlm[\"global_timeout\"],\n                result_truncation_limit=rlm[\"result_truncation_limit\"],\n            ),\n        )\n\n\n@dataclass\nclass UsageStats:\n    \"\"\"Token usage statistics.\"\"\"\n\n    input_tokens: int = 0\n    output_tokens: int = 0\n    cost: float = 0.0\n\n    def __add__(self, other: \"UsageStats\") -> \"UsageStats\":\n        return UsageStats(\n            input_tokens=self.input_tokens + other.input_tokens,\n            output_tokens=self.output_tokens + other.output_tokens,\n            cost=self.cost + other.cost,\n        )\n\n\n@dataclass\nclass CodeBlockResult:\n    \"\"\"Result of executing a code block.\"\"\"\n\n    code: str\n    stdout: str\n    stderr: str\n    execution_time: float\n    error: str | None = None\n\n\n@dataclass\nclass Iteration:\n    \"\"\"A single iteration of agent execution.\"\"\"\n\n    iteration: int\n    prompt: str | list[dict[str, str]]\n    raw_response: str\n    parsed_code_blocks: list[CodeBlockResult] = field(default_factory=list)\n    spawned_agents: list[\"AgentResult\"] = field(default_factory=list)\n\n\n@dataclass\nclass AgentResult:\n    \"\"\"Result from an RLM agent execution.\"\"\"\n\n    agent_id: str\n    depth: int\n    sandbox_id: str\n    task: str | None = None  # None for root agent\n\n    iterations: list[Iteration] = field(default_factory=list)\n    spawned_agents: list[\"AgentResult\"] = field(default_factory=list)\n\n    result: str | None = None  # The FINAL() answer\n    result_truncated: bool = False\n    usage: UsageStats = field(default_factory=UsageStats)\n    execution_time: float = 0.0\n    error: str | None = None\n"
  },
  {
    "path": "guides/python/recursive-language-models/run.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n\"\"\"Main entry point for deeper-rlm.\"\"\"\n\nimport logging\nimport os\nfrom datetime import datetime\nfrom pathlib import Path\n\nimport typer\nfrom dotenv import load_dotenv\nfrom output_logging.console import ConsoleOutput\nfrom output_logging.tree_logger import TreeLogger\nfrom rlm.agent import RLMAgent\nfrom rlm.budget import SandboxBudget\nfrom rlm.client import create_client\nfrom rlm.sandbox import SandboxManager\nfrom rlm.types import Config\n\n# Load environment variables\nload_dotenv()\n\n# Setup logging\nlogging.basicConfig(\n    level=logging.INFO,\n    format=\"%(asctime)s - %(name)s - %(levelname)s - %(message)s\",\n)\nlogger = logging.getLogger(__name__)\n\n\ndef main(\n    repo: str = typer.Argument(..., help=\"GitHub repository URL\"),\n    prompt: str = typer.Option(..., \"--prompt\", \"-p\", help=\"Task prompt for the agent\"),\n    branch: str = typer.Option(None, \"--branch\", \"-b\", help=\"Branch name\"),\n    commit: str = typer.Option(None, \"--commit\", help=\"Specific commit SHA\"),\n    config_path: Path = typer.Option(\n        Path(\"config.yaml\"),\n        \"--config\",\n        \"-c\",\n        help=\"Path to YAML configuration file\",\n    ),\n    output_file: Path = typer.Option(\n        None,\n        \"--output\",\n        \"-o\",\n        help=\"Output file for the patch (default: stdout)\",\n    ),\n    verbose: bool = typer.Option(\n        True,\n        \"--verbose/--quiet\",\n        help=\"Enable verbose output\",\n    ),\n):\n    \"\"\"Run deeper-rlm agent on a GitHub repository.\"\"\"\n    print(\"deeper-rlm\")\n    print()\n\n    # Load configuration\n    try:\n        config = Config.from_yaml(config_path)\n    except Exception as e:\n        print(f\"Error loading config: {e}\")\n        raise typer.Exit(1)\n\n    # Validate config\n    if config.model is None:\n        print(\"Error: No model configured\")\n        raise typer.Exit(1)\n\n    print(f\"Repository: {repo}\")\n    if branch:\n        print(f\"Branch: {branch}\")\n    if commit:\n        print(f\"Commit: {commit}\")\n    print(f\"Model: {config.model.name}\")\n    print(f\"Max sandboxes: {config.rlm.max_sandboxes}\")\n    print()\n\n    # Setup output\n    output_handler = ConsoleOutput(verbose=verbose)\n\n    try:\n        # Get API keys from environment\n        model_api_key = os.environ[\"LLM_API_KEY\"]\n        daytona_api_key = os.environ[\"DAYTONA_API_KEY\"]\n\n        # Create LLM client\n        client = create_client(\n            model_name=config.model.name,\n            api_key=model_api_key,\n        )\n\n        # Create sandbox budget and manager\n        budget = SandboxBudget(config.rlm.max_sandboxes)\n        sandbox_manager = SandboxManager(\n            api_key=daytona_api_key,\n            budget=budget,\n        )\n\n        try:\n            # Create sandbox from GitHub repo\n            print(\"Creating sandbox from repository...\")\n            sandbox, _ = sandbox_manager.create_sandbox_from_repo(\n                repo_url=repo,\n                branch=branch,\n                commit=commit,\n            )\n            print(f\"Sandbox created: {sandbox.id}\")\n            print()\n\n            # Extract repo name for logging\n            repo_name = repo.rstrip(\"/\").split(\"/\")[-1].replace(\".git\", \"\")\n\n            # Create agent\n            agent = RLMAgent(\n                client=client,\n                sandbox_manager=sandbox_manager,\n                config=config,\n                problem_statement=prompt,\n                instance_id=repo_name,\n                repo_url=repo,\n                depth=0,\n                on_iteration=lambda it: output_handler.iteration(agent.agent_id, 0, it),\n                output=output_handler,\n                existing_sandbox=sandbox,\n            )\n\n            # Run agent\n            print(f\"Starting agent with prompt: {prompt[:80]}...\")\n            print()\n            agent_result = agent.run()\n\n            # Get the patch\n            patch = agent_result.result\n\n            # Display results\n            print()\n            print(\"=\" * 40)\n            print(\"Results\")\n            print(\"=\" * 40)\n\n            if patch:\n                print(f\"Patch generated ({len(patch)} chars)\")\n                print()\n\n                if output_file:\n                    output_file.write_text(patch)\n                    print(f\"Patch saved to: {output_file}\")\n                else:\n                    print(\"--- Patch ---\")\n                    print(patch)\n                    print(\"--- End Patch ---\")\n            else:\n                print(\"No patch was generated\")\n\n            # Show stats\n            print()\n            print(f\"Total iterations: {len(agent_result.iterations)}\")\n            print(f\"Sub-agents spawned: {len(agent_result.spawned_agents)}\")\n            print(f\"Execution time: {agent_result.execution_time:.1f}s\")\n            print(f\"Total cost: ${agent_result.usage.cost:.4f}\")\n\n            # Show tree view\n            if agent_result:\n                output_handler.tree_view(agent_result)\n\n            # Save results for viewer\n            tree_logger = TreeLogger(\"results\")\n            run_id = f\"{repo_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}\"\n            result_path = tree_logger.log_agent_result(agent_result, run_id)\n            print(f\"\\nResults saved to: {result_path}\")\n\n        finally:\n            # Always cleanup sandboxes, even on failure\n            sandbox_manager.cleanup_all()\n\n    except Exception as e:\n        logger.exception(\"Error running agent\")\n        print(f\"Error: {e}\")\n        raise typer.Exit(1)\n\n\nif __name__ == \"__main__\":\n    typer.run(main)\n"
  },
  {
    "path": "guides/python/recursive-language-models/viewer/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>RLM Agent Viewer</title>\n    <script src=\"https://d3js.org/d3.v7.min.js\"></script>\n    <style>\n        * {\n            box-sizing: border-box;\n            margin: 0;\n            padding: 0;\n        }\n\n        body {\n            font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n            background: #0a0a0b;\n            color: #fafafa;\n            min-height: 100vh;\n            overflow: hidden;\n        }\n\n        .header {\n            position: fixed;\n            top: 0;\n            left: 0;\n            right: 0;\n            padding: 16px 24px;\n            background: rgba(10, 10, 11, 0.95);\n            backdrop-filter: blur(12px);\n            border-bottom: 1px solid #1f1f23;\n            z-index: 100;\n            display: flex;\n            align-items: center;\n            gap: 24px;\n        }\n\n        .header h1 {\n            font-size: 1rem;\n            font-weight: 600;\n            color: #fafafa;\n        }\n\n        .stats {\n            display: flex;\n            gap: 20px;\n            font-size: 0.75rem;\n            color: #71717a;\n        }\n\n        .stats span {\n            display: flex;\n            align-items: center;\n            gap: 6px;\n        }\n\n        .stats .value {\n            color: #a1a1aa;\n            font-family: 'SF Mono', Monaco, monospace;\n        }\n\n        .result-select {\n            background: #18181b;\n            border: 1px solid #27272a;\n            border-radius: 6px;\n            padding: 8px 12px;\n            color: #fafafa;\n            font-size: 0.8125rem;\n            font-family: 'SF Mono', Monaco, monospace;\n            cursor: pointer;\n            min-width: 280px;\n        }\n\n        .result-select:hover {\n            border-color: #3f3f46;\n        }\n\n        .result-select:focus {\n            outline: none;\n            border-color: #4ade80;\n        }\n\n        .result-select option {\n            background: #18181b;\n            color: #fafafa;\n        }\n\n        .empty-state {\n            position: fixed;\n            top: 50%;\n            left: 50%;\n            transform: translate(-50%, -50%);\n            text-align: center;\n            color: #52525b;\n        }\n\n        .empty-state h2 {\n            font-size: 1.125rem;\n            font-weight: 500;\n            margin-bottom: 8px;\n            color: #71717a;\n        }\n\n        .empty-state p {\n            font-size: 0.875rem;\n        }\n\n        .hidden { display: none !important; }\n        input[type=\"file\"] { display: none; }\n\n        #canvas {\n            position: fixed;\n            top: 60px;\n            left: 0;\n            right: 0;\n            bottom: 0;\n        }\n\n        /* Question bubble */\n        .q-bubble {\n            fill: #1a1a2e;\n            stroke: #2d2d4a;\n            stroke-width: 1;\n        }\n\n        .q-bubble:hover {\n            stroke: #4a4a6a;\n        }\n\n        /* Answer bubble */\n        .a-bubble {\n            fill: #0a1a0a;\n            stroke: #14532d;\n            stroke-width: 1;\n        }\n\n        .a-bubble:hover {\n            stroke: #22c55e;\n        }\n\n        .a-bubble.error {\n            fill: #1a0a0a;\n            stroke: #7f1d1d;\n        }\n\n        /* Text styles */\n        .bubble-label {\n            font-size: 9px;\n            font-weight: 600;\n            text-transform: uppercase;\n            letter-spacing: 0.1em;\n        }\n\n        .bubble-text {\n            font-size: 12px;\n            line-height: 1.5;\n            user-select: text;\n            -webkit-user-select: text;\n            cursor: text;\n            pointer-events: all;\n        }\n\n        .q-group, .a-group {\n            pointer-events: all;\n        }\n\n        .q-text {\n            fill: #c4c4d4;\n        }\n\n        .a-text {\n            fill: #86efac;\n        }\n\n        .a-text.error {\n            fill: #fca5a5;\n        }\n\n        /* Agent header */\n        .agent-label {\n            font-size: 10px;\n            font-weight: 600;\n            text-transform: uppercase;\n            letter-spacing: 0.05em;\n        }\n\n        .agent-id {\n            font-size: 9px;\n            font-family: 'SF Mono', Monaco, monospace;\n            fill: #52525b;\n        }\n\n        /* Arrow and call count */\n        .arrow-line {\n            fill: none;\n            stroke-width: 3;\n            stroke: #52525b;\n        }\n\n        .arrow-head {\n            fill: #52525b;\n        }\n\n        .call-badge {\n            cursor: pointer;\n        }\n\n        .call-badge-bg {\n            fill: #27272a;\n            stroke: #3f3f46;\n            stroke-width: 1;\n            transition: all 0.15s ease;\n        }\n\n        .call-badge:hover .call-badge-bg {\n            fill: #3f3f46;\n            stroke: #52525b;\n        }\n\n        .call-badge-text {\n            font-size: 10px;\n            font-weight: 500;\n            fill: #a1a1aa;\n            font-family: 'SF Mono', Monaco, monospace;\n        }\n\n        .call-badge:hover .call-badge-text {\n            fill: #fafafa;\n        }\n\n        /* Spawn connector */\n        .spawn-line {\n            fill: none;\n            stroke-width: 1.6;\n            stroke-opacity: 0.65;\n            stroke-dasharray: 5 4;\n            stroke-linecap: round;\n        }\n\n        .spawn-arrow {\n            fill-opacity: 0.8;\n        }\n\n        /* Depth bands */\n        .depth-band {\n            fill-opacity: 0.02;\n        }\n\n        .depth-band-line {\n            stroke: #27272a;\n            stroke-width: 1.5;\n            stroke-opacity: 0.8;\n        }\n\n        .depth-label {\n            font-size: 10px;\n            font-weight: 600;\n            text-transform: uppercase;\n            letter-spacing: 0.1em;\n            fill: #27272a;\n        }\n\n        /* Modal */\n        .modal-overlay {\n            position: fixed;\n            top: 0;\n            left: 0;\n            width: 100%;\n            height: 100%;\n            background: rgba(0, 0, 0, 0.85);\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            z-index: 1000;\n            opacity: 0;\n            visibility: hidden;\n            transition: all 0.2s ease;\n        }\n\n        .modal-overlay.visible {\n            opacity: 1;\n            visibility: visible;\n        }\n\n        .modal {\n            background: #111113;\n            border: 1px solid #27272a;\n            border-radius: 16px;\n            width: 90%;\n            max-width: 900px;\n            max-height: 85vh;\n            display: flex;\n            flex-direction: column;\n            transform: translateY(20px) scale(0.98);\n            transition: transform 0.2s ease;\n            overflow: hidden;\n        }\n\n        .modal-overlay.visible .modal {\n            transform: translateY(0) scale(1);\n        }\n\n        .modal-header {\n            padding: 20px 24px;\n            border-bottom: 1px solid #27272a;\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            background: #18181b;\n        }\n\n        .modal-title {\n            display: flex;\n            align-items: center;\n            gap: 12px;\n        }\n\n        .modal-title h3 {\n            font-size: 0.875rem;\n            font-weight: 500;\n            color: #fafafa;\n            font-family: 'SF Mono', Monaco, monospace;\n        }\n\n        .modal-badge {\n            padding: 4px 10px;\n            border-radius: 6px;\n            font-size: 0.6875rem;\n            font-weight: 600;\n        }\n\n        .modal-badge.depth-0 { background: #14532d; color: #4ade80; }\n        .modal-badge.depth-1 { background: #1e3a5f; color: #60a5fa; }\n        .modal-badge.depth-2 { background: #3b0764; color: #c084fc; }\n        .modal-badge.depth-3 { background: #431407; color: #fb923c; }\n\n        .modal-close {\n            background: #27272a;\n            border: none;\n            color: #71717a;\n            width: 32px;\n            height: 32px;\n            border-radius: 8px;\n            cursor: pointer;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 1.25rem;\n            transition: all 0.15s ease;\n        }\n\n        .modal-close:hover {\n            background: #3f3f46;\n            color: #fafafa;\n        }\n\n        .modal-body {\n            padding: 24px;\n            overflow-y: auto;\n            flex: 1;\n        }\n\n        .iteration-block {\n            margin-bottom: 24px;\n            padding: 20px;\n            background: #18181b;\n            border-radius: 12px;\n            border: 1px solid #27272a;\n        }\n\n        .iteration-block:last-child {\n            margin-bottom: 0;\n        }\n\n        .iteration-header {\n            font-size: 0.75rem;\n            color: #52525b;\n            margin-bottom: 16px;\n            font-weight: 600;\n            text-transform: uppercase;\n            letter-spacing: 0.05em;\n        }\n\n        .code-block {\n            background: #0a0a0c;\n            border-radius: 8px;\n            padding: 16px;\n            margin-bottom: 12px;\n            overflow-x: auto;\n            border: 1px solid #1f1f23;\n        }\n\n        .code-block pre {\n            font-size: 0.8125rem;\n            color: #e4e4e7;\n            line-height: 1.6;\n            font-family: 'SF Mono', Monaco, 'Fira Code', monospace;\n            margin: 0;\n            white-space: pre-wrap;\n            word-break: break-word;\n        }\n\n        .output-block {\n            background: #071507;\n            border-radius: 8px;\n            padding: 16px;\n            margin-top: 8px;\n            border: 1px solid #14532d;\n        }\n\n        .output-block pre {\n            font-size: 0.75rem;\n            color: #4ade80;\n            line-height: 1.5;\n            font-family: 'SF Mono', Monaco, monospace;\n            margin: 0;\n            white-space: pre-wrap;\n            word-break: break-word;\n            max-height: 300px;\n            overflow-y: auto;\n        }\n\n        .stderr-block {\n            background: #150707;\n            border-color: #7f1d1d;\n        }\n\n        .stderr-block pre {\n            color: #f87171;\n        }\n    </style>\n</head>\n<body>\n    <div class=\"header\">\n        <select class=\"result-select\" id=\"resultSelect\">\n            <option value=\"\">Select a run...</option>\n        </select>\n        <div class=\"stats\">\n            <span>Agents: <span class=\"value\" id=\"totalAgents\">0</span></span>\n            <span>Depth: <span class=\"value\" id=\"maxDepth\">0</span></span>\n            <span>Iterations: <span class=\"value\" id=\"totalIterations\">0</span></span>\n        </div>\n    </div>\n\n    <div class=\"empty-state\" id=\"emptyState\">\n        <h2>No result selected</h2>\n        <p>Choose a result file from the dropdown above</p>\n    </div>\n\n    <svg id=\"canvas\"></svg>\n\n    <!-- Modal -->\n    <div class=\"modal-overlay\" id=\"modalOverlay\">\n        <div class=\"modal\">\n            <div class=\"modal-header\">\n                <div class=\"modal-title\">\n                    <span class=\"modal-badge\" id=\"modalBadge\">Depth 0</span>\n                    <h3 id=\"modalAgentId\">agent_xxx</h3>\n                    <span style=\"color: #52525b; font-size: 0.75rem;\" id=\"modalIterCount\"></span>\n                </div>\n                <button class=\"modal-close\" id=\"modalClose\">&times;</button>\n            </div>\n            <div class=\"modal-body\" id=\"modalBody\"></div>\n        </div>\n    </div>\n\n    <script>\n        const COLORS = {\n            depth: ['#4ade80', '#60a5fa', '#c084fc', '#fb923c'],\n            depthBg: ['#14532d', '#1e3a5f', '#3b0764', '#431407'],\n            bandBg: ['rgba(74, 222, 128, 0.02)', 'rgba(96, 165, 250, 0.02)', 'rgba(192, 132, 252, 0.02)', 'rgba(251, 146, 60, 0.02)']\n        };\n\n        const LAYOUT = {\n            bubblePadding: 16,\n            bubbleRadius: 12,\n            minBubbleWidth: 200,\n            maxBubbleWidth: 320,\n            arrowGap: 150,\n            rowGap: 80,\n            colGap: 24,\n            lineHeight: 16,\n            fontSize: 12\n        };\n\n        let svg, container, zoom;\n        const resultSelect = document.getElementById('resultSelect');\n        const emptyState = document.getElementById('emptyState');\n        const modalOverlay = document.getElementById('modalOverlay');\n\n        function init() {\n            svg = d3.select('#canvas').attr('width', '100%').attr('height', '100%');\n            zoom = d3.zoom()\n                .scaleExtent([0.1, 3])\n                .filter((e) => {\n                    // Don't zoom/pan when clicking on text (allow text selection)\n                    const target = e.target;\n                    if (target.tagName === 'text' || target.tagName === 'tspan') return false;\n                    if (target.closest && target.closest('.bubble-text')) return false;\n                    // Allow wheel zoom and right-click pan, block left-click on text\n                    return !e.button;\n                })\n                .on('zoom', (e) => container.attr('transform', e.transform));\n            svg.call(zoom);\n            container = svg.append('g');\n\n            // Load available results\n            loadResultsList();\n        }\n\n        // Fetch available results from index.json\n        async function loadResultsList() {\n            try {\n                const response = await fetch('../results/index.json');\n                const files = await response.json();\n\n                resultSelect.innerHTML = '<option value=\"\">Select a run...</option>';\n                files.forEach(file => {\n                    const option = document.createElement('option');\n                    option.value = file;\n                    // Show cleaner name (remove .detail.json)\n                    option.textContent = file.replace('.detail.json', '');\n                    resultSelect.appendChild(option);\n                });\n\n                if (files.length === 0) {\n                    emptyState.querySelector('h2').textContent = 'No results found';\n                    emptyState.querySelector('p').textContent = 'Run an agent first to generate results';\n                } else {\n                    // Auto-load the most recent result (first in list)\n                    resultSelect.value = files[0];\n                    loadResult(files[0]);\n                }\n            } catch (err) {\n                emptyState.querySelector('h2').textContent = 'No results found';\n                emptyState.querySelector('p').textContent = 'Run an agent first to generate results';\n            }\n        }\n\n        // Load a specific result file\n        async function loadResult(filename) {\n            try {\n                const response = await fetch(`../results/${filename}`);\n                const data = await response.json();\n                if (data.root_agent) {\n                    emptyState.classList.add('hidden');\n                    renderData(data);\n                }\n            } catch (err) {\n                console.error('Error loading result:', err);\n            }\n        }\n\n        // Handle result selection\n        resultSelect.addEventListener('change', (e) => {\n            const filename = e.target.value;\n            if (filename) loadResult(filename);\n        });\n\n        function measureText(text, fontSize = 12, fontFamily = 'Inter, sans-serif') {\n            const canvas = document.createElement('canvas');\n            const ctx = canvas.getContext('2d');\n            ctx.font = `${fontSize}px ${fontFamily}`;\n            return ctx.measureText(text).width;\n        }\n\n        function wrapTextLines(text, maxWidth, fontSize = 12) {\n            if (!text) return [''];\n\n            // Convert literal \\n strings to actual newlines (from escaped JSON)\n            text = text.replace(/\\\\n/g, '\\n');\n\n            // Split by newlines first, then wrap each paragraph\n            const paragraphs = text.split('\\n');\n            const allLines = [];\n\n            for (const para of paragraphs) {\n                if (!para.trim()) {\n                    allLines.push(''); // Preserve empty lines\n                    continue;\n                }\n\n                const words = para.split(/\\s+/);\n                let currentLine = '';\n\n                for (const word of words) {\n                    const testLine = currentLine ? `${currentLine} ${word}` : word;\n                    if (measureText(testLine, fontSize) <= maxWidth) {\n                        currentLine = testLine;\n                    } else {\n                        if (currentLine) allLines.push(currentLine);\n                        currentLine = word;\n                    }\n                }\n                if (currentLine) allLines.push(currentLine);\n            }\n\n            return allLines.length ? allLines : [''];\n        }\n\n        // Detect which iterations spawned sub-agents by looking at code + stdout\n        function detectSpawnIterations(iterations) {\n            const spawnIters = [];\n            for (let i = 0; i < iterations.length; i++) {\n                const it = iterations[i];\n                const blocks = it.parsed_code_blocks || [];\n                for (const cb of blocks) {\n                    const code = cb.code || '';\n                    const stdout = cb.stdout || '';\n                    // Check for rlm_query call AND sub-agent results in stdout\n                    if (code.includes('rlm_query') &&\n                        (stdout.includes('=== Sub-agent') || stdout.includes('findings ==='))) {\n                        spawnIters.push(i);\n                        break;\n                    }\n                }\n            }\n            return spawnIters;\n        }\n\n        // Build timeline segments: [{type: 'iterations', count, startIdx, endIdx}, {type: 'spawn', iterIdx}, ...]\n        function buildTimelineSegments(iterations, spawnIters, childCount) {\n            if (iterations.length === 0) return [{ type: 'iterations', count: 0 }];\n            if (spawnIters.length === 0) {\n                // No spawns - single segment\n                return [{ type: 'iterations', count: iterations.length, startIdx: 0, endIdx: iterations.length - 1 }];\n            }\n\n            const segments = [];\n            let lastIdx = 0;\n\n            for (const spawnIdx of spawnIters) {\n                // Iterations before this spawn (not including the spawn iteration)\n                if (spawnIdx > lastIdx) {\n                    segments.push({\n                        type: 'iterations',\n                        count: spawnIdx - lastIdx,\n                        startIdx: lastIdx,\n                        endIdx: spawnIdx - 1\n                    });\n                }\n                // The spawn point\n                segments.push({ type: 'spawn', iterIdx: spawnIdx, childCount });\n                lastIdx = spawnIdx + 1;\n            }\n\n            // Iterations after last spawn\n            if (lastIdx < iterations.length) {\n                segments.push({\n                    type: 'iterations',\n                    count: iterations.length - lastIdx,\n                    startIdx: lastIdx,\n                    endIdx: iterations.length - 1\n                });\n            }\n\n            return segments;\n        }\n\n        function renderData(data) {\n            emptyState.classList.add('hidden');\n            container.selectAll('*').remove();\n\n            // Timeline layout constants\n            const ITER_WIDTH = 25;    // pixels per iteration\n            const SPAWN_WIDTH = 40;   // pixels for spawn marker\n            const MIN_ARROW_WIDTH = LAYOUT.arrowGap;\n            const TIMELINE = {\n                gap: 8,\n                endPad: 8,\n                markerMargin: 16,\n                badgeMinW: 32,\n                badgePadX: 16,\n                badgeFontSize: 10,\n                spawnR: 8,\n                spawnFontSize: 11,\n                monoFont: \"'SF Mono', Monaco, monospace\"\n            };\n\n            function generatePastelColors(count) {\n                // Deterministic, evenly spaced hues (pastel-ish)\n                const colors = [];\n                if (count <= 0) return colors;\n                for (let i = 0; i < count; i++) {\n                    const hue = (i * 360) / count;\n                    const sat = 60;\n                    const light = 72;\n                    colors.push(`hsl(${hue}, ${sat}%, ${light}%)`);\n                }\n                return colors;\n            }\n\n            // Extract agents\n            const agents = [];\n            function extract(agent, depth = 0, parent = null) {\n                const iterations = agent.iterations || [];\n                const childCount = (agent.spawned_agents || []).length;\n                const spawnIters = detectSpawnIterations(iterations);\n                const segments = buildTimelineSegments(iterations, spawnIters, childCount);\n\n                // Distribute children across detected spawn markers (best-effort; detail.json doesn't record exact mapping)\n                const spawnSegCount = segments.filter(s => s.type === 'spawn').length;\n                if (childCount > 0 && spawnSegCount === 0) {\n                    segments.push({\n                        type: 'spawn',\n                        iterIdx: Math.max(0, iterations.length - 1),\n                        assignedChildren: childCount,\n                        childStartIdx: 0,\n                        childEndIdx: childCount - 1,\n                        synthetic: true\n                    });\n                } else if (spawnSegCount > 0) {\n                    const base = Math.floor(childCount / spawnSegCount);\n                    const rem = childCount % spawnSegCount;\n                    let childIdx = 0;\n                    let spawnIdx = 0;\n                    segments.forEach(seg => {\n                        if (seg.type !== 'spawn') return;\n                        const assigned = base + (spawnIdx < rem ? 1 : 0);\n                        seg.assignedChildren = assigned;\n                        seg.childStartIdx = childIdx;\n                        seg.childEndIdx = childIdx + assigned - 1;\n                        childIdx += assigned;\n                        spawnIdx += 1;\n                    });\n                }\n\n                // Calculate arrow width based on segments\n                let arrowWidth = segments.reduce((sum, seg) => {\n                    if (seg.type === 'iterations') return sum + Math.max(seg.count * ITER_WIDTH, 40);\n                    if (seg.type === 'spawn') return sum + SPAWN_WIDTH;\n                    return sum;\n                }, 0);\n\n                // Ensure arrow is long enough to fit all timeline markers (badges + spawn labels + gaps)\n                function segmentWidth(seg) {\n                    if (seg.type === 'iterations') {\n                        if (!seg.count) return 0;\n                        const textW = measureText(String(seg.count), TIMELINE.badgeFontSize, TIMELINE.monoFont);\n                        return Math.max(TIMELINE.badgeMinW, textW + TIMELINE.badgePadX);\n                    }\n                    if (seg.type === 'spawn') {\n                        const n = seg.assignedChildren ?? 0;\n                        if (n <= 0) return 0;\n                        const label = `↓${n}`;\n                        const textW = measureText(label, TIMELINE.spawnFontSize, TIMELINE.monoFont);\n                        return Math.max(TIMELINE.spawnR * 2, textW + 6);\n                    }\n                    return 0;\n                }\n\n                const enrichedSegments = segments.map(seg => ({ ...seg, width: segmentWidth(seg) }));\n                const visibleSegments = enrichedSegments.filter(seg => seg.width > 0);\n                const timelineWidth = visibleSegments.reduce((sum, seg) => sum + seg.width, 0) +\n                    Math.max(0, visibleSegments.length - 1) * TIMELINE.gap;\n\n                arrowWidth = Math.max(\n                    arrowWidth,\n                    MIN_ARROW_WIDTH,\n                    timelineWidth + 2 * TIMELINE.endPad + 2 * TIMELINE.markerMargin\n                ) + 40; // Extra padding for arrows\n\n                const node = {\n                    id: agent.agent_id,\n                    depth: agent.depth ?? depth,\n                    spawnColor: null,\n                    task: agent.task || (depth === 0 ? data.instance_id : ''),\n                    result: agent.result || '',\n                    error: agent.error || '',\n                    iterations: iterations,\n                    segments: enrichedSegments,\n                    spawnIters: spawnIters,\n                    arrowWidth: arrowWidth,\n                    children: [],\n                    parent\n                };\n                agents.push(node);\n                for (const child of (agent.spawned_agents || [])) {\n                    node.children.push(extract(child, depth + 1, node));\n                }\n                return node;\n            }\n            const root = extract(data.root_agent);\n\n            // Assign pastel colors only to agents that spawn children (so circles/arrows are distinct without overwhelming)\n            const spawnParents = agents\n                .filter(a => a.children.length > 0)\n                .sort((a, b) => a.id.localeCompare(b.id));\n            const palette = generatePastelColors(spawnParents.length);\n            spawnParents.forEach((a, i) => { a.spawnColor = palette[i]; });\n\n            // Stats\n            const maxDepth = Math.max(...agents.map(a => a.depth));\n            const totalIters = agents.reduce((s, a) => s + a.iterations.length, 0);\n            document.getElementById('totalAgents').textContent = agents.length;\n            document.getElementById('maxDepth').textContent = maxDepth;\n            document.getElementById('totalIterations').textContent = totalIters;\n\n            // Compute bubble sizes\n            const contentWidth = LAYOUT.maxBubbleWidth - LAYOUT.bubblePadding * 2;\n            const MAX_LINES = 6; // Truncate long content in bubbles\n            agents.forEach(a => {\n                const qLinesAll = wrapTextLines(a.task, contentWidth);\n                const aLinesAll = wrapTextLines(a.result || a.error || 'Processing...', contentWidth);\n\n                // Truncate for display, mark if truncated\n                a.qLines = qLinesAll.slice(0, MAX_LINES);\n                a.aLines = aLinesAll.slice(0, MAX_LINES);\n                a.qTruncated = qLinesAll.length > MAX_LINES;\n                a.aTruncated = aLinesAll.length > MAX_LINES;\n\n                if (a.qTruncated) a.qLines.push('... (click to see full)');\n                if (a.aTruncated) a.aLines.push('... (click to see full)');\n\n                a.qHeight = Math.max(40, a.qLines.length * LAYOUT.lineHeight + LAYOUT.bubblePadding * 2 + 20);\n                a.aHeight = Math.max(40, a.aLines.length * LAYOUT.lineHeight + LAYOUT.bubblePadding * 2 + 20);\n                a.totalHeight = Math.max(a.qHeight, a.aHeight);\n            });\n\n            // Tree layout: calculate subtree widths bottom-up, then position top-down\n            function calculateSubtreeWidth(node) {\n                const nodeWidth = LAYOUT.maxBubbleWidth + node.arrowWidth + LAYOUT.maxBubbleWidth;\n                if (node.children.length === 0) {\n                    node.subtreeWidth = nodeWidth;\n                } else {\n                    const childrenWidth = node.children.reduce((sum, child) => {\n                        return sum + calculateSubtreeWidth(child);\n                    }, 0) + (node.children.length - 1) * LAYOUT.colGap;\n                    node.subtreeWidth = Math.max(nodeWidth, childrenWidth);\n                }\n                return node.subtreeWidth;\n            }\n\n            function assignPositions(node, x, y) {\n                const nodeWidth = LAYOUT.maxBubbleWidth + node.arrowWidth + LAYOUT.maxBubbleWidth;\n                // Center this node within its subtree width\n                node.x = x + (node.subtreeWidth - nodeWidth) / 2;\n                node.y = y;\n                node.rowHeight = node.totalHeight;\n\n                if (node.children.length > 0) {\n                    const childY = y + node.totalHeight + LAYOUT.rowGap;\n                    let childX = x;\n                    for (const child of node.children) {\n                        assignPositions(child, childX, childY);\n                        childX += child.subtreeWidth + LAYOUT.colGap;\n                    }\n                }\n            }\n\n            calculateSubtreeWidth(root);\n            assignPositions(root, 50, 50);\n\n            // Group by depth for stats and depth bands\n            const byDepth = {};\n            agents.forEach(a => {\n                byDepth[a.depth] = byDepth[a.depth] || [];\n                byDepth[a.depth].push(a);\n            });\n\n            function computeTimelineMarkers(node) {\n                const qX = node.x;\n                const aX = node.x + LAYOUT.maxBubbleWidth + node.arrowWidth;\n                const arrowY = node.y + node.totalHeight / 2;\n                const arrowX1 = qX + LAYOUT.maxBubbleWidth;\n                const arrowX2 = aX;\n\n                const lineX1 = arrowX1 + TIMELINE.endPad;\n                const lineX2 = arrowX2 - TIMELINE.endPad;\n                const lineW = Math.max(0, lineX2 - lineX1);\n\n                const contentX1 = lineX1 + TIMELINE.markerMargin;\n                const contentX2 = lineX2 - TIMELINE.markerMargin;\n                const contentW = Math.max(0, contentX2 - contentX1);\n\n                const visibleSegments = node.segments.filter(seg =>\n                    (seg.type === 'iterations' && seg.count > 0) ||\n                    (seg.type === 'spawn' && (seg.assignedChildren ?? 0) > 0)\n                );\n\n                const totalBadgeWidth = visibleSegments.reduce((sum, seg) => {\n                    const fallbackW = seg.type === 'spawn' ? TIMELINE.spawnR * 2 : TIMELINE.badgeMinW;\n                    return sum + (seg.width ?? fallbackW);\n                }, 0) + Math.max(0, visibleSegments.length - 1) * TIMELINE.gap;\n\n                let segX = contentX1 + (contentW - totalBadgeWidth) / 2;\n                const childMarkers = new Array(node.children.length).fill(null);\n                let fallbackMarker = null;\n\n                visibleSegments.forEach(seg => {\n                    const segW = seg.width ?? (seg.type === 'spawn' ? TIMELINE.spawnR * 2 : TIMELINE.badgeMinW);\n                    if (seg.type === 'spawn') {\n                        const n = seg.assignedChildren ?? 0;\n                        if (n <= 0) {\n                            segX += segW + TIMELINE.gap;\n                            return;\n                        }\n\n                        const cx = segX + segW / 2;\n                        const marker = { iterIdx: seg.iterIdx, x: cx, y: arrowY };\n                        fallbackMarker ||= marker;\n\n                        const startIdx = seg.childStartIdx ?? 0;\n                        const endIdx = seg.childEndIdx ?? (startIdx + n - 1);\n                        for (let childIdx = startIdx; childIdx <= endIdx; childIdx++) {\n                            if (childIdx >= 0 && childIdx < node.children.length) {\n                                childMarkers[childIdx] = marker;\n                            }\n                        }\n                    }\n                    segX += segW + TIMELINE.gap;\n                });\n\n                // Fallback: if any child wasn't assigned to a spawn marker, point it at the first marker (or center of arrow).\n                if (node.children.length) {\n                    const centerMarker = fallbackMarker || { iterIdx: 0, x: contentX1 + contentW / 2, y: arrowY };\n                    for (let i = 0; i < childMarkers.length; i++) {\n                        if (!childMarkers[i]) childMarkers[i] = centerMarker;\n                    }\n                }\n\n                return { arrowY, lineX1, lineX2, lineW, contentX1, contentX2, contentW, childMarkers };\n            }\n\n            agents.forEach(node => {\n                node.timeline = computeTimelineMarkers(node);\n            });\n\n            // Calculate bounds\n            const allX = agents.flatMap(a => [a.x, a.x + LAYOUT.maxBubbleWidth * 2 + a.arrowWidth]);\n            const allY = agents.flatMap(a => [a.y, a.y + a.totalHeight]);\n            const minX = Math.min(...allX) - 100;\n            const maxX = Math.max(...allX) + 100;\n            const minY = Math.min(...allY) - 50;\n            const maxY = Math.max(...allY) + 50;\n\n            // Draw depth bands based on actual agent positions\n            for (let d = 0; d <= maxDepth; d++) {\n                const row = byDepth[d] || [];\n                if (row.length === 0) continue;\n\n                // Get Y range from actual positioned agents at this depth\n                const depthMinY = Math.min(...row.map(a => a.y));\n                const depthMaxY = Math.max(...row.map(a => a.y + a.totalHeight));\n                const bandY = depthMinY - 30;\n                const bandH = depthMaxY - depthMinY + LAYOUT.rowGap - 20;\n\n                container.append('rect')\n                    .attr('class', 'depth-band')\n                    .attr('x', minX)\n                    .attr('y', bandY)\n                    .attr('width', maxX - minX)\n                    .attr('height', bandH)\n                    .attr('fill', COLORS.bandBg[Math.min(d, 3)])\n                    .attr('rx', 0);\n\n                if (d > 0) {\n                    container.append('line')\n                        .attr('class', 'depth-band-line')\n                        .attr('x1', minX).attr('y1', bandY)\n                        .attr('x2', maxX).attr('y2', bandY);\n                }\n\n                container.append('text')\n                    .attr('class', 'depth-label')\n                    .attr('x', minX + 20)\n                    .attr('y', bandY + 20)\n                    .text(`DEPTH ${d}`);\n            }\n\n            // Draw spawn connectors\n            const defs = container.append('defs');\n\n            // Arrowhead for spawn connectors (inherits each connector's stroke color)\n            defs.append('marker')\n                .attr('id', 'spawn-arrow')\n                .attr('viewBox', '0 -4 8 8')\n                .attr('refX', 6).attr('refY', 0)\n                .attr('markerWidth', 6).attr('markerHeight', 6)\n                .attr('orient', 'auto')\n                .append('path')\n                .attr('d', 'M0,-4L8,0L0,4')\n                .attr('class', 'spawn-arrow')\n                .attr('fill', 'context-stroke');\n\n            agents.forEach(a => {\n                a.children.forEach((child, childIdx) => {\n                    const childMarker = a.timeline?.childMarkers?.[childIdx] || null;\n                    const parentColor = a.spawnColor || COLORS.depth[Math.min(a.depth, 3)];\n\n                    // Parent -> Child Q (spawn arrow)\n                    const spawnX1 = childMarker ? childMarker.x : a.x + LAYOUT.maxBubbleWidth + a.arrowWidth / 2;\n                    const spawnY1 = childMarker ? childMarker.y : a.y + a.totalHeight / 2;\n                    const spawnX2 = child.x + LAYOUT.maxBubbleWidth / 2;\n                    const spawnY2 = child.y;\n                    const spawnMidY = a.y + a.totalHeight + (child.y - a.y - a.totalHeight) / 2;\n\n                    container.append('path')\n                        .attr('class', 'spawn-line')\n                        .attr('stroke', parentColor)\n                        .attr('d', `M${spawnX1},${spawnY1} L${spawnX1},${spawnMidY} L${spawnX2},${spawnMidY} L${spawnX2},${spawnY2}`)\n                        .attr('marker-end', 'url(#spawn-arrow)');\n                });\n            });\n\n            // Draw Q -> A arrows with call count\n            defs.append('marker')\n                .attr('id', 'qa-arrow')\n                .attr('viewBox', '0 -5 10 10')\n                .attr('refX', 8).attr('refY', 0)\n                .attr('markerWidth', 8).attr('markerHeight', 8)\n                .attr('orient', 'auto')\n                .append('path')\n                .attr('d', 'M0,-5L10,0L0,5')\n                .attr('class', 'arrow-head');\n\n            agents.forEach(node => {\n                const color = COLORS.depth[Math.min(node.depth, 3)];\n                const bgColor = COLORS.depthBg[Math.min(node.depth, 3)];\n                const g = container.append('g');\n\n                const qX = node.x;\n                const aX = node.x + LAYOUT.maxBubbleWidth + node.arrowWidth;\n                const centerY = node.y + node.totalHeight / 2;\n\n                // Question bubble (clickable if truncated)\n                const qG = g.append('g').attr('class', 'q-group');\n                if (node.qTruncated) qG.style('cursor', 'pointer').on('click', () => showTextModal('Question', node.task, node));\n                qG.append('rect')\n                    .attr('class', 'q-bubble')\n                    .attr('x', qX).attr('y', node.y)\n                    .attr('width', LAYOUT.maxBubbleWidth)\n                    .attr('height', node.totalHeight)\n                    .attr('rx', LAYOUT.bubbleRadius);\n\n                // Q label\n                qG.append('text')\n                    .attr('class', 'bubble-label')\n                    .attr('x', qX + LAYOUT.bubblePadding)\n                    .attr('y', node.y + LAYOUT.bubblePadding + 8)\n                    .attr('fill', '#6366f1')\n                    .text('QUESTION');\n\n                // Agent badge\n                qG.append('rect')\n                    .attr('x', qX + LAYOUT.maxBubbleWidth - 70)\n                    .attr('y', node.y + LAYOUT.bubblePadding - 2)\n                    .attr('width', 56).attr('height', 16)\n                    .attr('rx', 4).attr('fill', bgColor);\n                qG.append('text')\n                    .attr('class', 'agent-label')\n                    .attr('x', qX + LAYOUT.maxBubbleWidth - 42)\n                    .attr('y', node.y + LAYOUT.bubblePadding + 9)\n                    .attr('text-anchor', 'middle')\n                    .attr('fill', color)\n                    .style('font-size', '8px')\n                    .text(`D${node.depth}`);\n                qG.append('text')\n                    .attr('class', 'agent-id')\n                    .attr('x', qX + LAYOUT.maxBubbleWidth - LAYOUT.bubblePadding)\n                    .attr('y', node.y + LAYOUT.bubblePadding + 24)\n                    .attr('text-anchor', 'end')\n                    .text(node.id.replace('agent_', ''));\n\n                // Q text\n                const qTextG = qG.append('text')\n                    .attr('class', 'bubble-text q-text')\n                    .attr('x', qX + LAYOUT.bubblePadding)\n                    .attr('y', node.y + LAYOUT.bubblePadding + 36);\n                node.qLines.forEach((line, i) => {\n                    qTextG.append('tspan')\n                        .attr('x', qX + LAYOUT.bubblePadding)\n                        .attr('dy', i === 0 ? 0 : LAYOUT.lineHeight)\n                        .text(line || ' '); // Use space for empty lines to preserve height\n                });\n\n                // Answer bubble (clickable if truncated)\n                const aG = g.append('g').attr('class', 'a-group');\n                if (node.aTruncated) aG.style('cursor', 'pointer').on('click', () => showTextModal('Answer', node.result || node.error, node));\n                aG.append('rect')\n                    .attr('class', node.error ? 'a-bubble error' : 'a-bubble')\n                    .attr('x', aX).attr('y', node.y)\n                    .attr('width', LAYOUT.maxBubbleWidth)\n                    .attr('height', node.totalHeight)\n                    .attr('rx', LAYOUT.bubbleRadius);\n\n                // A label\n                aG.append('text')\n                    .attr('class', 'bubble-label')\n                    .attr('x', aX + LAYOUT.bubblePadding)\n                    .attr('y', node.y + LAYOUT.bubblePadding + 8)\n                    .attr('fill', node.error ? '#ef4444' : '#22c55e')\n                    .text('ANSWER');\n\n                // A text\n                const aTextG = aG.append('text')\n                    .attr('class', node.error ? 'bubble-text a-text error' : 'bubble-text a-text')\n                    .attr('x', aX + LAYOUT.bubblePadding)\n                    .attr('y', node.y + LAYOUT.bubblePadding + 36);\n                node.aLines.forEach((line, i) => {\n                    aTextG.append('tspan')\n                        .attr('x', aX + LAYOUT.bubblePadding)\n                        .attr('dy', i === 0 ? 0 : LAYOUT.lineHeight)\n                        .text(line || ' '); // Use space for empty lines to preserve height\n                });\n\n                // Arrow between Q and A with timeline segments\n                const arrowY = centerY;\n                const arrowX1 = qX + LAYOUT.maxBubbleWidth;\n                const arrowX2 = aX;\n                const endPad = TIMELINE.endPad;\n                const markerMargin = TIMELINE.markerMargin;\n\n                // Draw the main arrow line\n                g.append('line')\n                    .attr('class', 'arrow-line')\n                    .attr('x1', arrowX1 + endPad).attr('y1', arrowY)\n                    .attr('x2', arrowX2 - endPad).attr('y2', arrowY)\n                    .attr('marker-end', 'url(#qa-arrow)');\n\n                // Draw timeline segments - small fixed-size badges\n                const gap = TIMELINE.gap;\n                const badgeH = 20;\n                const badgeY = arrowY - badgeH / 2;\n                const spawnR = TIMELINE.spawnR;\n\n                const lineX1 = arrowX1 + endPad;\n                const lineX2 = arrowX2 - endPad;\n                const lineW = Math.max(0, lineX2 - lineX1);\n                const contentX1 = lineX1 + markerMargin;\n                const contentX2 = lineX2 - markerMargin;\n                const contentW = Math.max(0, contentX2 - contentX1);\n                const visibleSegments = node.segments.filter(seg =>\n                    (seg.type === 'iterations' && seg.count > 0) ||\n                    (seg.type === 'spawn' && (seg.assignedChildren ?? 0) > 0)\n                );\n\n                // Center the badges on the arrow\n                const totalBadgeWidth = visibleSegments.reduce((sum, seg) => {\n                    const fallbackW = seg.type === 'spawn' ? spawnR * 2 : TIMELINE.badgeMinW;\n                    return sum + (seg.width ?? fallbackW);\n                }, 0) + Math.max(0, visibleSegments.length - 1) * gap;\n\n                let segX = contentX1 + (contentW - totalBadgeWidth) / 2;\n\n                visibleSegments.forEach((seg) => {\n                    if (seg.type === 'iterations' && seg.count > 0) {\n                        const segW = seg.width ?? TIMELINE.badgeMinW;\n\n                        const badge = g.append('g')\n                            .attr('class', 'call-badge')\n                            .style('cursor', 'pointer')\n                            .on('click', () => openModal(node, seg.startIdx, seg.endIdx));\n\n                        badge.append('rect')\n                            .attr('class', 'call-badge-bg')\n                            .attr('x', segX).attr('y', badgeY)\n                            .attr('width', segW).attr('height', badgeH)\n                            .attr('rx', 4);\n\n                        badge.append('text')\n                            .attr('class', 'call-badge-text')\n                            .attr('x', segX + segW / 2)\n                            .attr('y', badgeY + badgeH / 2 + 3)\n                            .attr('text-anchor', 'middle')\n                            .text(seg.count);\n\n                        segX += segW + gap;\n                    } else if (seg.type === 'spawn') {\n                        const segW = seg.width ?? spawnR * 2;\n                        const n = seg.assignedChildren ?? 0;\n                        if (n <= 0) {\n                            segX += segW + gap;\n                            return;\n                        }\n\n                        const cx = segX + segW / 2;\n                        const spawnColor = node.spawnColor || color;\n\n                        g.append('circle')\n                            .attr('cx', cx)\n                            .attr('cy', arrowY)\n                            .attr('r', spawnR)\n                            .attr('fill', spawnColor)\n                            .attr('stroke', '#18181b')\n                            .attr('stroke-width', 2)\n                            .style('cursor', 'pointer')\n                            .on('click', () => openModal(node, seg.iterIdx, seg.iterIdx));\n\n                        // Small \"spawn\" indicator (count)\n                        g.append('text')\n                            .attr('x', cx)\n                            .attr('y', arrowY - spawnR - 6)\n                            .attr('text-anchor', 'middle')\n                            .attr('fill', '#71717a')\n                            .style('font-size', `${TIMELINE.spawnFontSize}px`)\n                            .style('font-family', TIMELINE.monoFont)\n                            .style('paint-order', 'stroke')\n                            .style('stroke', '#0a0a0b')\n                            .style('stroke-width', 3)\n                            .text(`↓${n}`);\n\n                        segX += segW + gap;\n                    }\n                });\n            });\n\n            // Center view\n            const bounds = container.node().getBBox();\n            const scale = Math.min(\n                (window.innerWidth - 80) / bounds.width,\n                (window.innerHeight - 140) / bounds.height,\n                0.9\n            );\n            svg.call(zoom.transform, d3.zoomIdentity\n                .translate(\n                    (window.innerWidth - bounds.width * scale) / 2 - bounds.x * scale,\n                    (window.innerHeight - bounds.height * scale) / 2 - bounds.y * scale + 30\n                )\n                .scale(scale)\n            );\n        }\n\n        function openModal(node, startIdx = 0, endIdx = null) {\n            // Filter iterations by range if specified\n            const allIters = node.iterations;\n            const end = endIdx !== null ? endIdx + 1 : allIters.length;\n            const filteredIters = allIters.slice(startIdx, end);\n            const isFiltered = startIdx > 0 || end < allIters.length;\n\n            document.getElementById('modalBadge').textContent = `Depth ${node.depth}`;\n            document.getElementById('modalBadge').className = `modal-badge depth-${Math.min(node.depth, 3)}`;\n            document.getElementById('modalAgentId').textContent = node.id;\n\n            // Show range info if filtered\n            const rangeText = isFiltered\n                ? `Iterations ${startIdx}-${end - 1} (of ${allIters.length} total)`\n                : `${allIters.length} code executions`;\n            document.getElementById('modalIterCount').textContent = rangeText;\n\n            const body = document.getElementById('modalBody');\n            body.innerHTML = filteredIters.map((iter, idx) => {\n                const blocks = iter.parsed_code_blocks || [];\n                const actualIdx = startIdx + idx;\n                const rawResponse = iter.raw_response || '';\n\n                // If no parsed blocks, show raw response instead\n                const content = blocks.length > 0\n                    ? blocks.map(block => `\n                        <div class=\"code-block\">\n                            <pre>${escapeHtml(block.code || '')}</pre>\n                        </div>\n                        ${block.stdout ? `<div class=\"output-block\"><pre>${escapeHtml(block.stdout)}</pre></div>` : ''}\n                        ${block.stderr ? `<div class=\"output-block stderr-block\"><pre>${escapeHtml(block.stderr)}</pre></div>` : ''}\n                    `).join('')\n                    : `<div class=\"code-block\" style=\"background: #1a1a2e;\"><pre style=\"color: #a1a1aa;\">${escapeHtml(rawResponse) || '(no response)'}</pre></div>`;\n\n                return `\n                    <div class=\"iteration-block\">\n                        <div class=\"iteration-header\">Iteration ${iter.iteration ?? actualIdx}${blocks.length === 0 ? ' <span style=\"color:#71717a;font-size:10px;\">(raw response)</span>' : ''}</div>\n                        ${content}\n                    </div>\n                `;\n            }).join('') || '<p style=\"color: #52525b; text-align: center; padding: 40px;\">No code executions</p>';\n\n            modalOverlay.classList.add('visible');\n        }\n\n        function closeModal() {\n            modalOverlay.classList.remove('visible');\n        }\n\n        function showTextModal(title, text, node) {\n            document.getElementById('modalBadge').textContent = `Depth ${node.depth}`;\n            document.getElementById('modalBadge').className = `modal-badge depth-${Math.min(node.depth, 3)}`;\n            document.getElementById('modalAgentId').textContent = node.id;\n            document.getElementById('modalIterCount').textContent = title;\n\n            // Convert literal \\n to real newlines\n            const processedText = (text || '').replace(/\\\\n/g, '\\n');\n\n            const body = document.getElementById('modalBody');\n            body.innerHTML = `<div class=\"code-block\" style=\"background: #1a1a2e; white-space: pre-wrap; word-break: break-word;\"><pre style=\"color: #e4e4e7;\">${escapeHtml(processedText)}</pre></div>`;\n\n            modalOverlay.classList.add('visible');\n        }\n\n        document.getElementById('modalClose').addEventListener('click', closeModal);\n        modalOverlay.addEventListener('click', (e) => {\n            if (e.target === modalOverlay) closeModal();\n        });\n        document.addEventListener('keydown', (e) => {\n            if (e.key === 'Escape') closeModal();\n        });\n\n        function escapeHtml(text) {\n            const div = document.createElement('div');\n            div.textContent = text;\n            return div.innerHTML;\n        }\n\n        init();\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "guides/python/reinforcement-learning/trl/.gitignore",
    "content": "# Training output files\ntraining_results/\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# Virtual Environments\nvenv/\nenv/\nENV/\nenv.bak/\nvenv.bak/\n.venv/\n.virtualenv/\n.pyenv/\n\n# Poetry\npoetry.lock\n.poetry/\n\n# Pipenv\nPipfile.lock\n\n# pyenv\n.python-version\n\n# Conda\nconda-meta/\n.conda/\n\n# PyCharm\n.idea/\n*.iml\n\n# VS Code\n.vscode/\n*.code-workspace\n\n# Jupyter Notebook\n.ipynb_checkpoints/\n*.ipynb_checkpoints/\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.env.local\n.env.*.local\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# macOS\n.DS_Store\n\n# Windows\nThumbs.db\nehthumbs.db\nDesktop.ini\n\n# Linux\n*~\n\n# Temporary files\n*.tmp\n*.bak\n*.swp\n*~\n"
  },
  {
    "path": "guides/python/reinforcement-learning/trl/README.md",
    "content": "# Running RL Rollouts on Sandboxes Guide (TRL + Daytona)\n\n## Overview\n\nThis guide demonstrates how to integrate Daytona with TRL ([Transformer Reinforcement Learning](https://github.com/huggingface/trl)) in order to run the code generated in rollouts, in Daytona sandboxes. We combine TRL's synchronous trainer with parallelized, asynchronous execution in sandboxes.\n\nIn the guide, we use GRPO to train `Qwen3-1.7B-Base` model on two code writing tasks: a sorting function, and a function to find the maximal contiguous subarray sum.\n\n## Features\n\n- **Sandboxed code execution:** Generated code runs in isolated Daytona sandboxes, preventing harmful code from affecting your system\n- **Parallel evaluation:** Multiple completions are evaluated concurrently across a pool of sandboxes\n- **Test-based rewards:** Reward signal uses the test pass rate\n- **vLLM integration:** Uses vLLM in colocate mode for running both training and generation on 1 GPU\n- **Multi-task training:** Easily extensible to new coding tasks by adding to the `TASKS` dictionary\n\n## Requirements\n\n- **Python:** Version 3.10 or higher\n- **GPU:** Required for training and vLLM inference, 80 GB VRAM or more recommended\n\n## Environment Variables\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n\n## Getting Started\n\n### Setup and Run\n\n1. Create and activate a virtual environment:\n\n```bash\npython3.10 -m venv venv  \nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n```\n\n2. Install dependencies:\n\n```bash\npip install -e .\n```\n\n3. Set your Daytona API key in `.env` (copy from `.env.example`):\n\n```bash\ncp .env.example .env\n# edit .env with your API key\n```\n\n4. Run the training:\n\n```bash\npython train.py\n```\n\n## Configuration\n\nThe script has several configurable parameters:\n\n### Sandbox Settings\n\n- `EFFECTIVE_BATCH_SIZE`: The effective batch size for training, also equal to the number of Daytona sandboxes to create (default: 500).\n- `MAX_TIMEOUT_SECONDS`: Timeout for code execution in each sandbox (default: 1 second). Prevents infinite loops from blocking training.\n\n### Model Settings\n\n- `MODEL_NAME`: The base model to train (default: `Qwen/Qwen3-1.7B-Base`)\n\n### Training Settings (GRPOConfig)\n\nKey parameters in the training configuration:\n\n- `per_device_train_batch_size`: Batch size per device (default: 20)\n- `gradient_accumulation_steps`: Steps to accumulate before update (default: 25)\n- `max_steps`: Total training steps (default: 8)\n- `max_completion_length`: Maximum tokens for generated code (default: 512)\n\n### Adding New Tasks\n\nTo add a new coding task, add an entry to the `TASKS` dictionary:\n\n```python\nTASKS = {\n    \"your_task\": {\n        \"prompt\": \"Your prompt here...\",\n        \"func_name\": \"function_name\",\n        \"banned_patterns\": [\"patterns\", \"to\", \"ban\"],\n        \"tests\": [\n            \"test_input_1\",\n            \"test_input_2\",\n        ],\n        \"reference\": \"expected_output_expression\",\n    },\n}\n```\n\n## How It Works\n\nThe script runs reinforcement learning training using TRL's GRPOTrainer.\n\n1. **Sandbox pool:** Daytona sandboxes are created upfront for safe, parallel code execution\n2. **Generation:** The model generates N completions per prompt via vLLM\n3. **Sanitization:** Completions using banned patterns (e.g., using built-in functions) are rejected\n4. **Evaluation:** Each completion runs in a Daytona sandbox against the test suite\n5. **Reward:** -1 for errors or banned patterns; otherwise, the reward is the fraction of tests passed\n6. **Policy update:** GRPO reinforces completions that scored higher than their group average\n7. **Cleanup:** When training finishes, sandboxes are deleted\n\n## Output\n\nAfter training finishes, the trained model is saved in `training_results` folder. The metrics computed during the training run can be found in `training_results/metrics.jsonl`.\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [TRL (Transformer Reinforcement Learning)](https://huggingface.co/docs/trl/)\n- [Daytona](https://daytona.io)\n- [vLLM](https://docs.vllm.ai/)\n"
  },
  {
    "path": "guides/python/reinforcement-learning/trl/pyproject.toml",
    "content": "[project]\nname = \"daytona-trl-grpo-training\"\nversion = \"0.1.0\"\ndescription = \"GRPO training with sandboxed code evaluation using Daytona\"\nauthors = [\n    {name = \"Lovre Pesut\", email = \"lpesut@daytona.io\"}\n]\nreadme = \"README.md\"\nrequires-python = \">=3.10\"\ndependencies = [\n    \"daytona>=0.128.1,<1.0.0\",\n    \"datasets>=3.0.0\",\n    \"trl[vllm]>=0.26.0\",\n    \"python-dotenv>=1.2.1\",\n]\n"
  },
  {
    "path": "guides/python/reinforcement-learning/trl/train.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\nimport asyncio\nimport json\nimport os\nfrom typing import Any, Awaitable, Dict, List, TypedDict\n\nfrom datasets import Dataset\nfrom dotenv import load_dotenv\nfrom trl import GRPOConfig, GRPOTrainer\n\nfrom daytona import AsyncDaytona, AsyncSandbox\nfrom daytona.common.errors import DaytonaTimeoutError\n\nload_dotenv()\n\nEFFECTIVE_BATCH_SIZE = 500\n# We evaluate each completion concurrently, in its own sandbox,\n# so we spawn EFFECTIVE_BATCH_SIZE number of sandboxes.\nMAX_TIMEOUT_SECONDS = 1\nMODEL_NAME = \"Qwen/Qwen3-1.7B-Base\"\n\nSORTING_PROMPT = \"\"\"# I've been fiddling with different ways to sort numbers in Python.\n# At first I just used sorted() and list.sort(), but then I decided to try\n# my hand at writing some original sorting functions. And I succeeded!\n# I don't call sorted(), list.sort(), heapq, or use any imports here - just plain\n# Python and an original algorithm.\ndef sort_numbers(xs: list[int]) -> list[int]:\n    \\\"\\\"\\\"Sort a list of integers in ascending order.\n\n    Args:\n        xs: A list of integers to be sorted.\n\n    Returns:\n        A new list containing the same integers, sorted from smallest to largest.\n    \\\"\\\"\\\"\n\"\"\"\n\nMAX_SUBARRAY_PROMPT = \"\"\"# I've been exploring different ways to compute the maximum sum of a contiguous\n# subarray in Python. At first I wrote a straightforward brute-force version\n# with nested loops, but now I'm trying to come up with my own cleaner\n# implementation. There are lots of possible approaches here, and this function\n# is just my original take on the problem.\ndef max_subarray_sum(xs: list[int]) -> int:\n    \\\"\\\"\\\"Return the maximum sum of a non-empty contiguous subarray.\n\n    Args:\n        xs: A non-empty list of integers.\n\n    Returns:\n        The largest possible sum of any contiguous subarray of xs.\n    \\\"\\\"\\\"\n\"\"\"\n\nTASKS = {\n    \"sorting\": {\n        \"prompt\": SORTING_PROMPT,\n        \"func_name\": \"sort_numbers\",\n        \"banned_patterns\": [\"sorted(\", \".sort(\", \"heapq\", \"import \", \"__import__\"],\n        \"tests\": [\n            \"[]\",\n            \"[1, 3, 2]\",\n            \"[random.randint(-1000, 1000) for _ in range(200)]\",\n            \"[random.randint(-100, 100) for _ in range(1000)]\",\n            \"list(range(0, 100)) + list(range(200, 100, -1)) + list(range(200, 300))\",\n        ],\n        \"reference\": \"sorted\",\n    },\n    \"max_subarray\": {\n        \"prompt\": MAX_SUBARRAY_PROMPT,\n        \"func_name\": \"max_subarray_sum\",\n        \"banned_patterns\": [],\n        \"tests\": [\n            \"[5]\",\n            \"[-3]\",\n            \"[-2, -3, -1, -4]\",\n            \"[-2, 1, -3, 4, -1, 2, 1, -5, 4]\",\n            \"[1, 2, 3, 4]\",\n            \"[random.randint(-1000, 1000) for _ in range(200)]\",\n            \"[random.randint(-100, 100) for _ in range(1000)]\",\n        ],\n        \"reference\": \"_kadane\",\n    },\n}\n\nPROMPT_TO_TASK = {task[\"prompt\"]: task for task in TASKS.values()}\n\n\nasync def _create_sandbox_pool_async(daytona: AsyncDaytona, n: int = 10) -> List[AsyncSandbox]:\n    print(f\"Creating {n} sandboxes...\")\n    tasks = [daytona.create() for _ in range(n)]\n    sandboxes = await asyncio.gather(*tasks)\n    print(f\"Successfully created all {len(sandboxes)} sandboxes\")\n    return list(sandboxes)\n\n\nasync def _cleanup_sandbox_pool_async(sandbox_pool: List[AsyncSandbox]) -> None:\n    if not sandbox_pool:\n        return\n    print(\"Cleaning up sandboxes...\")\n    tasks = [sandbox.delete() for sandbox in sandbox_pool]\n    results = await asyncio.gather(*tasks, return_exceptions=True)\n    for r in results:\n        if isinstance(r, Exception):\n            print(f\"  Sandbox delete error: {type(r).__name__}: {r}\")\n    print(\"All sandboxes cleaned up\")\n\n\nclass EvalResult(TypedDict):\n    no_error: bool\n    num_passed: int\n    num_tests: int\n\n\ndef _fail_result(num_tests: int) -> EvalResult:\n    return {\"no_error\": False, \"num_passed\": 0, \"num_tests\": num_tests}\n\n\ndef sanitize_completion(text: str) -> str:\n    # Since the model continues the body of the function,\n    # we take lines until the first unindented line.\n    lines = text.splitlines()\n    kept: List[str] = []\n    for line in lines:\n        if line and (not line.startswith(\"    \")):\n            break\n        kept.append(line)\n    return \"\\n\".join(kept).rstrip()\n\n\ndef has_banned_pattern(text: str, task: Dict[str, Any]) -> bool:\n    banned = task.get(\"banned_patterns\", [])\n    if not banned:\n        return False\n    lowered = text.lower()\n    return any(p.lower() in lowered for p in banned)\n\n\ndef build_test_harness(task: Dict[str, Any], function_body: str) -> str:\n    prompt = task[\"prompt\"]\n    func_name = task[\"func_name\"]\n    reference_function = task[\"reference\"]\n    tests = task[\"tests\"]\n\n    tests_tuple = \",\\n        \".join(tests)\n\n    return f\"\"\"{prompt}\n{function_body}\n\nimport json\nimport random\nrandom.seed(0)\n\ndef _kadane(xs):\n    max_sum = current = xs[0]\n    for x in xs[1:]:\n        current = max(x, current + x)\n        max_sum = max(max_sum, current)\n    return max_sum\n\ndef _run_tests():\n    tests = (\n        {tests_tuple}\n    )\n    results = []\n    for xs in tests:\n        try:\n            out = {func_name}(xs.copy())\n            expected = {reference_function}(xs.copy())\n            results.append(out == expected)\n        except Exception:\n            results.append(False)\n    print(json.dumps({{\"results\": results}}))\n\nif __name__ == \"__main__\":\n    _run_tests()\n\"\"\"\n\n\nasync def evaluate_single_completion_async(\n    sandbox: AsyncSandbox,\n    raw_completion: str,\n    prompt: str,\n) -> EvalResult:\n    task = PROMPT_TO_TASK[prompt]\n    num_task_tests = len(task[\"tests\"])\n    body = sanitize_completion(raw_completion)\n\n    if not body.strip():\n        return _fail_result(num_task_tests)\n    if has_banned_pattern(body, task):\n        return _fail_result(num_task_tests)\n\n    code = build_test_harness(task, body)\n\n    try:\n        response = await sandbox.code_interpreter.run_code(code, timeout=MAX_TIMEOUT_SECONDS)\n    except DaytonaTimeoutError:\n        print(f\"Completion timed out after {MAX_TIMEOUT_SECONDS}s \" f\"in sandbox {getattr(sandbox, 'id', '?')}\")\n        return _fail_result(num_task_tests)\n    except Exception as e:\n        print(\n            f\"Error evaluating completion in sandbox {getattr(sandbox, 'id', '?')}: \" f\"{type(e).__name__}: {e}\",\n        )\n        return _fail_result(num_task_tests)\n\n    if response.error is not None:\n        return _fail_result(num_task_tests)\n    raw_output = response.stdout.strip()\n    if not raw_output:\n        return _fail_result(num_task_tests)\n    last_line = raw_output.splitlines()[-1]\n    try:\n        results = json.loads(last_line)\n    except Exception:\n        return _fail_result(num_task_tests)\n    correct = results.get(\"results\", [])\n\n    return {\n        \"no_error\": True,\n        \"num_passed\": sum(bool(x) for x in correct),\n        \"num_tests\": len(correct),\n    }\n\n\nasync def _evaluate_batch_async(\n    sandbox_pool: List[AsyncSandbox], completions: List[str], prompts: List[str]\n) -> List[EvalResult]:\n    print(f\"Evaluating {len(completions)} completions in parallel across \" f\"{len(sandbox_pool)} sandboxes...\")\n\n    async def run_one(i: int, sandbox: AsyncSandbox, completion: str, prompt: str) -> EvalResult:\n        task = PROMPT_TO_TASK[prompt]\n        num_task_tests = len(task[\"tests\"])\n        try:\n            stats = await evaluate_single_completion_async(sandbox, completion, prompt)\n            print(f\"  Completion {i + 1}/{len(completions)} done\")\n            return stats\n        except Exception as e:\n            print(f\"  Completion {i + 1}/{len(completions)} failed: \" f\"{type(e).__name__}: {e}\")\n            return _fail_result(num_task_tests)\n\n    tasks = [\n        run_one(i, sandbox_pool[i % len(sandbox_pool)], completion, prompt)\n        for i, (completion, prompt) in enumerate(zip(completions, prompts))\n    ]\n\n    stats_list = await asyncio.gather(*tasks)\n    print(f\"  Done: {len(completions)}/{len(completions)} completions evaluated\")\n\n    return stats_list\n\n\ndef main():\n    # Create local event loop for mixing sync training library with async sandbox API\n    loop = asyncio.new_event_loop()\n    asyncio.set_event_loop(loop)\n\n    def run_async(coro: Awaitable[Any]) -> Any:\n        \"\"\"Helper to run async code from sync context (e.g., reward functions).\"\"\"\n        return loop.run_until_complete(coro)\n\n    daytona = AsyncDaytona()\n\n    sandbox_pool: List[AsyncSandbox] = []\n\n    training_args = GRPOConfig(\n        output_dir=\"training_results\",\n        per_device_train_batch_size=20,\n        # batch size chosen so the training runs comfortably on a single 80GB GPU,\n        # if running this on a GPU with less memory, reduce the batch size accordingly\n        gradient_accumulation_steps=25,\n        num_generations=EFFECTIVE_BATCH_SIZE // len(TASKS),\n        max_prompt_length=256,\n        max_completion_length=512,\n        learning_rate=8e-6,\n        num_train_epochs=1,\n        logging_steps=1,\n        report_to=\"none\",\n        max_steps=8,\n        bf16=True,\n        use_vllm=True,\n        vllm_mode=\"colocate\",\n        vllm_gpu_memory_utilization=0.15,\n        gradient_checkpointing=True,\n        loss_type=\"dapo\",\n        beta=0.01,\n    )\n    assert EFFECTIVE_BATCH_SIZE % len(TASKS) == 0, \"EFFECTIVE_BATCH_SIZE must be divisible by number of tasks.\"\n    assert (\n        training_args.per_device_train_batch_size * training_args.gradient_accumulation_steps\n    ) == EFFECTIVE_BATCH_SIZE, \"The total batch size must equal the sandbox pool size.\"\n\n    try:\n        sandbox_pool = run_async(_create_sandbox_pool_async(daytona, n=EFFECTIVE_BATCH_SIZE))\n\n        train_dataset = Dataset.from_dict({\"prompt\": [task[\"prompt\"] for task in TASKS.values()]})\n\n        def reward_func(prompts, completions, **_kwargs):\n            stats_list = run_async(_evaluate_batch_async(sandbox_pool, completions, prompts))\n            rewards = []\n            for s in stats_list:\n                if not s[\"no_error\"]:\n                    rewards.append(-1.0)\n                elif s[\"num_tests\"] == 0:\n                    rewards.append(0.0)\n                else:\n                    rewards.append(s[\"num_passed\"] / s[\"num_tests\"])\n            return rewards\n\n        trainer = GRPOTrainer(\n            model=MODEL_NAME,\n            args=training_args,\n            train_dataset=train_dataset,\n            reward_funcs=[reward_func],\n        )\n\n        trainer.train()\n\n        os.makedirs(training_args.output_dir, exist_ok=True)\n        log_path = os.path.join(training_args.output_dir, \"metrics.jsonl\")\n        with open(log_path, \"w\") as f:\n            for rec in trainer.state.log_history:\n                f.write(json.dumps(rec) + \"\\n\")\n        print(\"wrote logs to\", log_path)\n\n    finally:\n        if sandbox_pool:\n            run_async(_cleanup_sandbox_pool_async(sandbox_pool))\n\n        try:\n            run_async(daytona.close())\n            print(\"Daytona client closed\")\n        except Exception as e:\n            print(f\"Error closing Daytona client: {type(e).__name__}: {e}\")\n\n        loop.close()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "guides/typescript/agentkit-inngest/coding-agent/anthropic/.gitignore",
    "content": "# Node.js\nnode_modules/\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# dotenv environment files\n.env\n\n# VS Code\n.vscode/\n\n# Daytona SDK and sandbox artifacts\n.daytona/\nsandbox/\n\n# Build output\n/dist/\n/build/\n\n# TypeScript\n*.tsbuildinfo\n\n# Logs\nlogs/\n*.log\n\n# OS files\n.DS_Store\nThumbs.db\n\n# Misc\n*.swp\n*.swo\n\n# Ignore coverage reports\ncoverage/\n\n# Ignore generated files\n*.out\n*.tmp\n\n# Ignore Copilot agent artifacts\ncopilot-agent-*\n"
  },
  {
    "path": "guides/typescript/agentkit-inngest/coding-agent/anthropic/Dockerfile",
    "content": "FROM node:20-alpine\n\nWORKDIR /app\n\nCOPY package.json package-lock.json* ./\nRUN npm install --production\n\nCOPY . .\n\nCMD [\"npm\", \"run\", \"start\"]"
  },
  {
    "path": "guides/typescript/agentkit-inngest/coding-agent/anthropic/README.md",
    "content": "# Coding Agent Example (AgentKit + Daytona)\n\n## Overview\n\nThis project demonstrates a fully autonomous coding agent capable of performing software development tasks in a [Daytona](https://daytona.io) sandbox environment. The agent is built using [AgentKit](https://agentkit.inngest.com/) and leverages Daytona sandboxes for secure, isolated execution. The agent can create simple web apps, run tests, execute scripts, and more - all by reasoning about the user's request and automating the necessary steps.\n\n## Features\n\n- **Multi-language support:** The agent can use any language supported by Daytona sandboxes\n- **Web app creation:** Automatically scaffolds and builds simple web applications.\n- **Dev server orchestration:** Detects when a development server is needed, starts it, and generates a preview link for live app inspection.\n- **File and directory management:** Creates, uploads, reads, and deletes files and directories as needed.\n- **Script and test execution:** Runs arbitrary scripts and test suites.\n- **Automated reasoning:** Plans and executes multi-step development workflows based on user prompts.\n- **Debug logging:** Detailed agent flow tracking enabled via `enableDebugLogs=true`.\n\n## Requirements\n\n- **Node.js:** Version 18 or higher is required.\n\n## Environment Variables\n\nTo run the coding agent, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `ANTHROPIC_API_KEY`: Because Anthropic is the default model provider, you must set `ANTHROPIC_API_KEY` in your environment. By default the agent uses `claude-3-5-haiku-20241022` model with a preset token limit.\n\n> [!Note]\n> You can change the token setting and the model (see all available Anthropic models at [AgentKit Supported Models](https://agentkit.inngest.com/concepts/models#list-of-supported-models)). To use a different model provider, follow the instructions at [AgentKit Model Setup](https://agentkit.inngest.com/concepts/models#create-a-model-instance).\n\nSee the `.env.example` file for the exact structure and variable names. Copy `.env.example` to `.env` and fill in your API keys before running the agent.\n\n## Getting Started\n\nBefore proceeding with either Local or Docker setup, complete the following steps:\n\n1. Navigate to this directory in your terminal\n2. Copy `.env.example` to `.env` and add your API keys\n\n### 1. Local Setup\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the agent:\n\n   ```bash\n   npm run start\n   ```\n\n### 2. Docker Setup\n\n1. Build the Docker image:\n\n   ```bash\n   docker buildx build . -t coding-agent\n   ```\n\n2. Run the container:\n\n   ```bash\n   docker run --rm -it coding-agent\n   ```\n\n## Configuration\n\n- **Prompt Setting:** The main prompt for the agent is configured in the `network.run(...)` call inside [`src/index.ts`](src/index.ts). You can edit this prompt to change the agent's task or try different app ideas and workflows.\n\n- **Debug Logs:** Detailed agent flow tracking is enabled by setting `enableDebugLogs=true`. This will log all agent iterations and tool actions for transparency and troubleshooting.\n\n## Example Usage\n\nTo showcase the agent, try running the default prompt in `src/index.ts`:\n\n```typescript\nconst result = await network.run(\n  `Create a minimal React app called \"Notes\" that lets users add, view, and delete notes. Each note should have a title and content. Use Create React App or Vite for setup. Include a simple UI with a form to add notes and a list to display them.`\n);\n```\n\nThe agent will:\n\n- Scaffold the app\n- Install dependencies\n- Start the dev server\n- Generate a preview link for you to view the app\n\nYou can inspect the terminal logs to monitor what the agent is doing, observe its evolution, and see how it corrects mistakes from errors during the process.\n\nWhen the agent finishes, you should see terminal output like:\n\n> ✔️ App is ready!\n> Preview: https://5173-3a828150-1573-42e3-bf9f-9793a2c2c0c2.proxy.daytona.works\n\nYou can view the app on the given preview link above. The image below shows the result generated in this run:\n\n![Notes App Demo](../../../../../apps/docs/src/assets/docs/images/inngest-agentkit-notes-app.gif)\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [AgentKit](https://agentkit.inngest.com/)\n- [Daytona](https://daytona.io)\n"
  },
  {
    "path": "guides/typescript/agentkit-inngest/coding-agent/anthropic/package.json",
    "content": "{\n  \"name\": \"daytona-coding-agent\",\n  \"version\": \"1.0.0\",\n  \"description\": \"AgentKit coding agent powered by Daytona\",\n  \"license\": \"ISC\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"start\": \"tsc; node dist/index.js\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^24.10.1\",\n    \"ts-node\": \"^10.9.2\",\n    \"typescript\": \"^5.9.3\"\n  },\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.117.0\",\n    \"@inngest/agent-kit\": \"^0.13.2\",\n    \"dotenv\": \"^17.2.3\",\n    \"zod\": \"^4.1.13\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/agentkit-inngest/coding-agent/anthropic/src/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport 'dotenv/config'\n\nimport { z } from 'zod'\nimport { createAgent, createNetwork, createTool, anthropic } from '@inngest/agent-kit'\nimport { CodeRunParams, DaytonaError } from '@daytonaio/sdk'\nimport { getSandbox, extractTextMessageContent, logDebug } from './utils.js'\nimport type { FileUpload } from '@daytonaio/sdk/src/FileSystem.js'\nimport { Buffer } from 'buffer'\n\nasync function main() {\n  const codeRunTool = createTool({\n    name: 'codeRunTool',\n    description: `Executes code in the Daytona sandbox. Use this tool to run code snippets, scripts, or application entry points.\nParameters:\n    - code: Code to execute.\n    - argv: Command line arguments to pass to the code.\n    - env: Environment variables for the code execution, as key-value pairs.`,\n    parameters: z.object({\n      code: z.string(),\n      argv: z.array(z.string()).nullable(),\n      env: z.record(z.string(), z.string()).nullable(),\n    }),\n    handler: async ({ code, argv, env }, { network }) => {\n      try {\n        const sandbox = await getSandbox(network)\n        const codeRunParams = new CodeRunParams()\n        codeRunParams.argv = argv ?? []\n        codeRunParams.env = env ?? {}\n        console.log(`[TOOL: codeRunTool]\\nParams: ${codeRunParams}\\n${code}`)\n        const response = await sandbox.process.codeRun(code, codeRunParams)\n        const responseMessage = `Code run result: ${response.result}${\n          response.artifacts?.stdout ? `\\nStdout: ${response.artifacts.stdout}` : ''\n        }`\n        logDebug(responseMessage)\n        return responseMessage\n      } catch (error) {\n        console.error('Error executing code:', error)\n        if (error instanceof DaytonaError) return `Code execution Daytona error: ${error.message}`\n        else return 'Error executing code'\n      }\n    },\n  })\n\n  const shellTool = createTool({\n    name: 'shellTool',\n    description: `Executes a shell command inside the Daytona sandbox environment. Use this tool for tasks like installing packages, running scripts, or manipulating files via shell commands. Never use this tool to start a development server; always use startDevServerTool for this purpose.\nParameters:\n    - shellCommand: Shell command to execute (e.g., \"npm install\", \"ls -la\").\n    - env: Environment variables to set for the command as key-value pairs (e.g. { \"NODE_ENV\": \"production\" }).`,\n    parameters: z.object({\n      shellCommand: z.string(),\n      env: z.record(z.string(), z.string()).nullable(),\n    }),\n    handler: async ({ shellCommand, env }, { network }) => {\n      try {\n        const sandbox = await getSandbox(network)\n        console.log(`[TOOL: shellTool]\\nCommand: ${shellCommand}\\nEnv: ${JSON.stringify(env)}`)\n        const response = await sandbox.process.executeCommand(shellCommand, undefined, env ?? {})\n        const responseMessage = `Command result: ${response.result}${\n          response.artifacts?.stdout ? `\\nStdout: ${response.artifacts.stdout}` : ''\n        }`\n        logDebug(responseMessage)\n        return responseMessage\n      } catch (error) {\n        console.error('Error executing shell command:', error)\n        if (error instanceof DaytonaError) return `Shell command execution Daytona error: ${error.message}`\n        else return 'Error executing shell command'\n      }\n    },\n  })\n\n  const uploadFilesTool = createTool({\n    name: 'uploadFilesTool',\n    description: `Uploads one or more files to the Daytona sandbox. Use this tool to transfer source code, configuration files, or other assets required for execution or setup. If a file already exists at the specified path, its contents will be replaced with the new content provided. To update a file, simply upload it again with the desired content.\nParameters:\n  - files: Array of files to upload. Each file object must have:\n    - path (string): The destination file path in the sandbox.\n    - content (string): The full contents of the file as a string.\n    Example: files: [{ path: \"src/index.ts\", content: \"console.log('Hello world');\" }]\nNote: Always use double quotes (\") for the outer 'content' string property. When writing JavaScript or TypeScript file content, use single quotes (') for string literals inside the file. For JSON files, always convert the object to a string before passing as 'content'.`,\n    parameters: z.object({\n      files: z.array(\n        z.object({\n          path: z.string(),\n          content: z.string(),\n        }),\n      ),\n    }),\n    handler: async ({ files }, { network }) => {\n      try {\n        // Handle case when model hallucinates and passes files as string instead of specificed array format\n        if (typeof files === 'string') {\n          try {\n            files = JSON.parse(files)\n          } catch {\n            throw new TypeError(\n              \"Parameter 'files' must be an array, not a string. If you are passing a string, it must be valid JSON representing an array.\",\n            )\n          }\n        }\n        files = files.map((file) => ({\n          ...file,\n          content:\n            // Handle case when model hallucinates and passes JSON files content as object instead of string\n            typeof file.content === 'string' ? file.content : JSON.stringify(file.content, null, 2),\n        }))\n        const sandbox = await getSandbox(network)\n        console.log(`[TOOL: uploadFilesTool]`)\n        logDebug(`Uploading files: ${files.map((f) => 'Path: ' + f.path + '\\nContent: ' + f.content).join('\\n\\n')}`)\n        const filesToUpload: FileUpload[] = files.map((file) => ({\n          source: Buffer.from(file.content, 'utf-8'),\n          destination: file.path,\n        }))\n        await sandbox.fs.uploadFiles(filesToUpload)\n        const uploadFilesMessage = `Successfully created or updated files: ${files.map((f) => f.path).join(', ')}`\n        logDebug(uploadFilesMessage)\n        return uploadFilesMessage\n      } catch (error) {\n        console.error('Error creating/uploading files:', error)\n        if (error instanceof DaytonaError) return `Files create/upload Daytona error: ${error.message}`\n        else return 'Error creating/uploading files'\n      }\n    },\n  })\n\n  const readFileTool = createTool({\n    name: 'readFileTool',\n    description: `Reads the contents of a file from the Daytona sandbox. Use this tool to retrieve source code, configuration files, or other assets for analysis or processing.`,\n    parameters: z.object({\n      filePath: z.string(),\n    }),\n    handler: async ({ filePath }, { network }) => {\n      try {\n        const sandbox = await getSandbox(network)\n        console.log(`[TOOL: readFileTool]\\nFile path: ${filePath}`)\n        const fileBuffer = await sandbox.fs.downloadFile(filePath)\n        const fileContent = fileBuffer.toString('utf-8')\n        const readFileMessage = `Successfully read file: ${filePath}\\nContent:\\n${fileContent}`\n        logDebug(readFileMessage)\n        return fileContent\n      } catch (error) {\n        console.error('Error reading file:', error)\n        if (error instanceof DaytonaError) return `File reading Daytona error: ${error.message}`\n        else return 'Error reading file'\n      }\n    },\n  })\n\n  const deleteFileTool = createTool({\n    name: 'deleteFileTool',\n    description: `Deletes a file from the Daytona sandbox. Use this tool to remove unnecessary or temporary files from the sandbox environment.`,\n    parameters: z.object({\n      filePath: z.string(),\n    }),\n    handler: async ({ filePath }, { network }) => {\n      try {\n        const sandbox = await getSandbox(network)\n        console.log(`[TOOL: deleteFileTool]\\nFile path: ${filePath}`)\n        await sandbox.fs.deleteFile(filePath)\n        const deleteFileMessage = `Successfully deleted file: ${filePath}`\n        logDebug(deleteFileMessage)\n        return deleteFileMessage\n      } catch (error) {\n        console.error('Error deleting file:', error)\n        if (error instanceof DaytonaError) return `File deletion Daytona error: ${error.message}`\n        else return 'Error deleting file'\n      }\n    },\n  })\n\n  const createDirectoryTool = createTool({\n    name: 'createDirectoryTool',\n    description: `Creates a new directory in the Daytona sandbox. Use this tool to prepare folder structures for projects, uploads, or application data.\nParameters:\n    - directoryPath: The directory path to create.`,\n    parameters: z.object({\n      directoryPath: z.string(),\n    }),\n    handler: async ({ directoryPath }, { network }) => {\n      try {\n        const sandbox = await getSandbox(network)\n        console.log(`[TOOL: createDirectoryTool]\\nDirectory path: ${directoryPath}`)\n        await sandbox.fs.createFolder(directoryPath, '755')\n        const createDirectoryMessage = `Successfully created directory: ${directoryPath}`\n        logDebug(createDirectoryMessage)\n        return createDirectoryMessage\n      } catch (error) {\n        console.error('Error creating directory:', error)\n        if (error instanceof DaytonaError) return `Directory creation Daytona error: ${error.message}`\n        else return 'Error creating directory'\n      }\n    },\n  })\n\n  const deleteDirectoryTool = createTool({\n    name: 'deleteDirectoryTool',\n    description: `Deletes a directory from the Daytona sandbox. Use this tool to remove unnecessary or temporary directories from the sandbox environment.`,\n    parameters: z.object({\n      directoryPath: z.string(),\n    }),\n    handler: async ({ directoryPath }, { network }) => {\n      try {\n        const sandbox = await getSandbox(network)\n        console.log(`[TOOL: deleteDirectoryTool]\\nDirectory path: ${directoryPath}`)\n        await sandbox.fs.deleteFile(directoryPath, true)\n        const deleteDirectoryMessage = `Successfully deleted directory: ${directoryPath}`\n        logDebug(deleteDirectoryMessage)\n        return deleteDirectoryMessage\n      } catch (error) {\n        console.error('Error deleting directory:', error)\n        if (error instanceof DaytonaError) return `Directory deletion Daytona error: ${error.message}`\n        else return 'Error deleting directory'\n      }\n    },\n  })\n\n  const startDevServerTool = createTool({\n    name: 'startDevServerTool',\n    description: `Starts a development server in the sandbox environment. Use this tool to start any development server (e.g., Next.js, React, etc.). Never use shellTool to start a development server; always use this tool for that purpose.\nParameters:\n  - startCommand: The shell command to start the development server (e.g., \"npm run dev\").`,\n    parameters: z.object({\n      startCommand: z.string(),\n    }),\n    handler: async ({ startCommand }, { network }) => {\n      try {\n        const sandbox = await getSandbox(network)\n        console.log(`[TOOL: startDevServerTool]\\nStart command: ${startCommand}`)\n        const sessionId = 'start-dev-server-cmd'\n        const sessions = await sandbox.process.listSessions()\n        let session = sessions.find((s) => s.sessionId === sessionId)\n        if (!session) {\n          network.state.data.devServerSessionId = sessionId\n          await sandbox.process.createSession(sessionId)\n          session = await sandbox.process.getSession(sessionId)\n        }\n        const sessionExecuteResponse = await sandbox.process.executeSessionCommand(session.sessionId, {\n          command: startCommand,\n          runAsync: true,\n        })\n        network.state.data.devServerSessionCommandId = sessionExecuteResponse.cmdId\n        const startDevServerMessage = `Successfully started dev server with command: ${startCommand}`\n        logDebug(startDevServerMessage)\n        return startDevServerMessage\n      } catch (error) {\n        console.error('Error starting dev server:', error)\n        if (error instanceof DaytonaError) return `Dev server start Daytona error: ${error.message}`\n        else return 'Error starting dev server'\n      }\n    },\n  })\n\n  const checkDevServerHealthTool = createTool({\n    name: 'checkDevServerHealthTool',\n    description: `Checks the health of a development server. Use this tool after starting a dev server to verify it is running and accessible.`,\n    parameters: z.object({}),\n    handler: async (_params, { network }) => {\n      try {\n        console.log(`[TOOL: checkDevServerHealthTool]`)\n        await new Promise((resolve) => setTimeout(resolve, 1000))\n        const sandbox = await getSandbox(network)\n        const devServerCommandLogs = await sandbox.process.getSessionCommandLogs(\n          network.state.data.devServerSessionId,\n          network.state.data.devServerSessionCommandId,\n        )\n        const healthMessage = `Dev server health check result:\\nStdout: ${devServerCommandLogs.stdout}\\nStderr: ${devServerCommandLogs.stderr}`\n        logDebug(healthMessage)\n        return healthMessage\n      } catch (error) {\n        console.error('Error checking dev server health:', error)\n        if (error instanceof DaytonaError) return `Dev server health check Daytona error: ${error.message}`\n        return `Error checking dev server health`\n      }\n    },\n  })\n\n  const codingAgent = createAgent({\n    name: 'Coding Agent',\n    description: 'An autonomous coding agent for building software in a Daytona sandbox',\n    system: `You are a coding agent designed to help the user achieve software development tasks. You have access to a Daytona sandbox environment.\n\nCapabilities:\n- You can execute code snippets or scripts.\n- You can run shell commands to install dependencies, manipulate files, and set up environments.\n- You can create, upload, and organize files and directories to build basic applications and project structures.\n\nWorkspace Instructions:\n- You do not need to define, set up, or specify the workspace directory. Assume you are already inside a default workspace directory that is ready for app creation.\n- All file and folder operations (create, upload, organize) should use paths relative to this default workspace.\n- Do not attempt to create or configure the workspace itself; focus only on the requested development tasks.\n\nGuidelines:\n- Always analyze the user's request and plan your steps before taking action.\n- Prefer automation and scripting over manual or interactive steps.\n- When installing packages or running commands that may prompt for input, use flags (e.g., '-y') to avoid blocking.\n- If you are developing an app that is served with a development server (e.g. Next.js, React):\n  1. Return the port information in the form: DEV_SERVER_PORT=$PORT (replace $PORT with the actual port number).\n  2. Start the development server.\n  3. After starting the dev server, always check its health in the next iteration. Only mark the task as complete if the health check passes: there must be no stderr output, no errors thrown, and the stdout content must not indicate a problem (such as error messages, stack traces, or failed startup). If any of these are present, diagnose and fix the issue before completing the task.\n- When you have completed the requested task, set the \"TASK_COMPLETED\" string in your output to signal that the app is finished.\n`,\n    model: anthropic({\n      model: 'claude-opus-4-0',\n      defaultParameters: {\n        max_tokens: 1024,\n      },\n    }),\n    tools: [\n      shellTool,\n      codeRunTool,\n      uploadFilesTool,\n      readFileTool,\n      deleteFileTool,\n      createDirectoryTool,\n      deleteDirectoryTool,\n      startDevServerTool,\n      checkDevServerHealthTool,\n    ],\n  })\n\n  const network = createNetwork({\n    name: 'coding-agent-network',\n    agents: [codingAgent],\n    maxIter: 30,\n    defaultRouter: ({ network, callCount }) => {\n      const previousIterationMessageContent = extractTextMessageContent(network.state.results.at(-1))\n      if (previousIterationMessageContent) logDebug(`Iteration message:\\n${previousIterationMessageContent}\\n`)\n      console.log(`\\n ===== Iteration #${callCount + 1} =====\\n`)\n      if (callCount > 0) {\n        if (previousIterationMessageContent.includes('TASK_COMPLETED')) {\n          const isDevServerAppMessage = network.state.results\n            .map((result) => extractTextMessageContent(result))\n            .find((messageContent) => messageContent.includes('DEV_SERVER_PORT'))\n          if (isDevServerAppMessage) {\n            const portMatch = isDevServerAppMessage.match(/DEV_SERVER_PORT=([0-9]+)/)\n            const port = portMatch && portMatch[1] ? parseInt(portMatch[1], 10) : undefined\n            if (port) network.state.data.devServerPort = port\n          }\n          return\n        }\n      }\n      return codingAgent\n    },\n  })\n\n  const result = await network.run(\n    `Create a minimal React app called \"Notes\" that lets users add, view, and delete notes. Each note should have a title and content. Use Create React App or Vite for setup. Include a simple UI with a form to add notes and a list to display them.`,\n  )\n\n  try {\n    const sandbox = await getSandbox(result)\n    const devServerPort = result.state.data.devServerPort\n    if (devServerPort) {\n      const previewInfo = await sandbox.getPreviewLink(devServerPort)\n      console.log('\\x1b[32m✔ App is ready!\\x1b[0m\\n\\x1b[36mPreview: ' + previewInfo.url + '\\x1b[0m')\n    } else sandbox.delete()\n  } catch (error) {\n    console.error('An error occurred during the final phase:', error)\n  }\n}\n\nmain()\n"
  },
  {
    "path": "guides/typescript/agentkit-inngest/coding-agent/anthropic/src/utils.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona, Sandbox } from '@daytonaio/sdk'\nimport { AgentResult, NetworkRun } from '@inngest/agent-kit'\nimport type { TextMessage } from '@inngest/agent-kit'\n\nexport function extractTextMessageContent(result: AgentResult | undefined): string {\n  const textMessage = result?.output.find((msg) => msg.type === 'text') as TextMessage\n  if (!textMessage || !textMessage.content) return ''\n  if (typeof textMessage.content === 'string') return textMessage.content\n  if (Array.isArray(textMessage.content)) {\n    return textMessage.content.map((c) => c.text).join('')\n  }\n  return ''\n}\n\nexport async function createSandbox(network?: NetworkRun<Record<string, any>>) {\n  const daytona = new Daytona()\n  let sandbox: Sandbox\n  try {\n    sandbox = await daytona.create()\n  } catch (error) {\n    throw new Error(`Failed to create Daytona sandbox: ${error}`)\n  }\n  if (network) network.state.data.sandbox = sandbox\n  return sandbox\n}\n\nexport async function getSandbox(network?: NetworkRun<Record<string, any>>) {\n  let sandbox = network?.state.data.sandbox as Sandbox\n  if (!sandbox) sandbox = await createSandbox(network)\n  return sandbox\n}\n\nexport const logDebug = (message: string) => {\n  const enableDebugLogs = false\n  if (enableDebugLogs) console.log(message)\n}\n"
  },
  {
    "path": "guides/typescript/agentkit-inngest/coding-agent/anthropic/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"outDir\": \"./dist\",\n    \"module\": \"nodenext\",\n    \"target\": \"esnext\",\n    \"types\": [],\n    \"sourceMap\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"exactOptionalPropertyTypes\": true,\n    \"strict\": true,\n    \"jsx\": \"react-jsx\",\n    \"verbatimModuleSyntax\": true,\n    \"isolatedModules\": true,\n    \"noUncheckedSideEffectImports\": true,\n    \"moduleDetection\": \"force\",\n    \"skipLibCheck\": true,\n  }\n}\n"
  },
  {
    "path": "guides/typescript/ai-data-analyst/openai/.gitignore",
    "content": "# Agent output files\nchart-*.png\n\n# Node.js\nnode_modules/\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# dotenv environment files\n.env\n\n# VS Code\n.vscode/\n\n# Daytona SDK and sandbox artifacts\n.daytona/\nsandbox/\n\n# Build output\n/dist/\n/build/\n\n# TypeScript\n*.tsbuildinfo\n\n# Logs\nlogs/\n*.log\n\n# OS files\n.DS_Store\nThumbs.db\n\n# Misc\n*.swp\n*.swo\n\n# Ignore coverage reports\ncoverage/\n\n# Ignore generated files\n*.out\n*.tmp\n\n# Ignore Copilot agent artifacts\ncopilot-agent-*"
  },
  {
    "path": "guides/typescript/ai-data-analyst/openai/README.md",
    "content": "# OpenAI Data Analysis Example (OpenAI + Daytona)\n\n## Overview\n\nThis example demonstrates how to build a data analysis tool using [OpenAI's API](https://platform.openai.com/) and [Daytona](https://daytona.io) sandboxes. The script executes Python code in an isolated environment to analyze cafe sales data, enabling automated data analysis workflows with natural language prompts.\n\nIn this example, the agent analyzes a cafe sales dataset to find the three highest revenue products for January and visualizes the results in a bar chart.\n\n## Features\n\n- **Secure sandbox execution:** All Python code runs in isolated Daytona sandboxes\n- **Natural language interface:** Describe your analysis task in plain English\n- **Automatic chart generation:** Visualizations are automatically saved as PNG files\n- **File handling:** Upload datasets and process results within the sandbox\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher is required\n- **npm:** Included with Node.js installation\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `OPENAI_API_KEY`: Required for OpenAI API access. Get it from [OpenAI Platform](https://platform.openai.com/api-keys)\n\nCreate a `.env` file in the project directory with these variables.\n\n## Getting Started\n\n### Setup and Run\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the example:\n\n   ```bash\n   npm run start\n   ```\n\n## How It Works\n\n1. An LLM call generates Python code based on the data format and prompt\n2. A new Daytona sandbox is created, containing the data file\n3. The Python code is executed in the sandbox\n4. Any generated charts are saved as PNG files\n5. A second LLM call summarizes the code execution results\n\n## Configuration\n\n### Analysis Customization\n\nThe main prompt is configured in the `userPrompt` variable in `index.ts`:\n\n```typescript\nconst userPrompt = `Give the three highest revenue products for the month of January and show them as a bar chart.`;\n```\n\nYou can modify this to analyze different aspects of the data or try different visualization types.\n\nThe example uses `cafe_sales_data.csv`. To use your own dataset, replace this file and update the filename in the script if needed.\n\n### OpenAI Model Configuration\n\nBy default, the example uses the following models, as specified in `index.ts`:\n\n```python\nconst CODING_MODEL = \"gpt-5.1\"\nconst SUMMARY_MODEL = \"gpt-4o\"\n```\n\nThe coding model is used for high accuracy code generation, and the summary model is used for fast summarization.\n\nSee [Models](https://platform.openai.com/docs/models) for all supported models\n\n## Example Output\n\nWhen the script completes, you'll see output similar to:\n\n```\nPrompt: Give the three highest revenue products for the month of January and show them as a bar chart.\nGenerating code...\nRunning code...\n✓ Chart saved to chart-0.png\nResponse: Great! It looks like you successfully executed the code and identified the top three revenue-generating products for January:\n\n1. **Matcha Espresso Fusion** with a total revenue of \\$2,603.81.\n2. **Oat Milk Latte** with a total revenue of \\$2,548.65.\n3. **Nitro Cold Brew** with a total revenue of \\$2,242.41.\n```\n\nThe chart will be saved as `chart-0.png` in your project directory, showing a bar chart of the top three revenue-generating products for January.\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [OpenAI API Documentation](https://platform.openai.com/docs/api-reference)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/typescript/ai-data-analyst/openai/cafe_sales_data.csv",
    "content": "date,item,quantity,unit_price,revenue,time\n2024-01-01,Single-Origin Pour Over,20,5.44,108.78,08:00:00\n2024-01-01,Oat Milk Latte,14,6.08,85.15,08:00:36\n2024-01-01,Honey Lavender Latte,10,6.28,62.83,08:01:12\n2024-01-01,Turmeric Ginger Latte,10,6.29,62.87,08:01:49\n2024-01-01,Cold Brew Concentrate,11,5.92,65.14,08:02:25\n2024-01-01,Nitro Cold Brew,9,6.18,55.63,08:03:02\n2024-01-01,Matcha Espresso Fusion,16,6.52,104.25,08:03:38\n2024-01-01,Blue Pea Flower Tea,20,4.61,92.27,08:04:14\n2024-01-01,Sourdough Toast,9,5.93,53.41,08:04:51\n2024-01-01,Almond Butter Croissant,4,5.45,21.8,08:05:27\n2024-01-01,Vegan Morning Bun,6,5.85,35.12,08:06:04\n2024-01-02,Single-Origin Pour Over,10,5.76,57.57,08:06:40\n2024-01-02,Oat Milk Latte,6,6.0,36.01,08:07:16\n2024-01-02,Honey Lavender Latte,8,6.86,54.87,08:07:53\n2024-01-02,Turmeric Ginger Latte,8,6.42,51.4,08:08:29\n2024-01-02,Cold Brew Concentrate,10,5.86,58.63,08:09:06\n2024-01-02,Nitro Cold Brew,5,6.26,31.32,08:09:42\n2024-01-02,Matcha Espresso Fusion,8,6.8,54.44,08:10:18\n2024-01-02,Blue Pea Flower Tea,7,4.55,31.83,08:10:55\n2024-01-02,Sourdough Toast,6,6.31,37.86,08:11:31\n2024-01-02,Almond Butter Croissant,3,5.18,15.54,08:12:08\n2024-01-02,Vegan Morning Bun,15,5.8,86.93,08:12:44\n2024-01-03,Single-Origin Pour Over,9,5.58,50.26,08:13:20\n2024-01-03,Oat Milk Latte,9,5.81,52.26,08:13:57\n2024-01-03,Honey Lavender Latte,1,6.71,6.71,08:14:33\n2024-01-03,Turmeric Ginger Latte,10,6.49,64.85,08:15:10\n2024-01-03,Cold Brew Concentrate,17,5.74,97.63,08:15:46\n2024-01-03,Nitro Cold Brew,17,6.43,109.38,08:16:22\n2024-01-03,Matcha Espresso Fusion,16,6.71,107.39,08:16:59\n2024-01-03,Blue Pea Flower Tea,2,4.54,9.08,08:17:35\n2024-01-03,Sourdough Toast,17,6.22,105.75,08:18:12\n2024-01-03,Almond Butter Croissant,18,5.31,95.56,08:18:48\n2024-01-03,Vegan Morning Bun,8,5.55,44.38,08:19:24\n2024-01-04,Single-Origin Pour Over,12,5.38,64.55,08:20:01\n2024-01-04,Oat Milk Latte,12,5.87,70.46,08:20:37\n2024-01-04,Honey Lavender Latte,6,6.87,41.21,08:21:14\n2024-01-04,Turmeric Ginger Latte,14,6.46,90.44,08:21:50\n2024-01-04,Cold Brew Concentrate,21,5.67,119.1,08:22:26\n2024-01-04,Nitro Cold Brew,11,6.55,72.02,08:23:03\n2024-01-04,Matcha Espresso Fusion,20,6.98,139.68,08:23:39\n2024-01-04,Blue Pea Flower Tea,15,4.66,69.93,08:24:16\n2024-01-04,Sourdough Toast,13,5.99,77.84,08:24:52\n2024-01-04,Almond Butter Croissant,5,5.12,25.62,08:25:28\n2024-01-04,Vegan Morning Bun,13,5.97,77.63,08:26:05\n2024-01-05,Single-Origin Pour Over,12,5.31,63.7,08:26:41\n2024-01-05,Oat Milk Latte,17,6.07,103.15,08:27:18\n2024-01-05,Honey Lavender Latte,1,6.39,6.39,08:27:54\n2024-01-05,Turmeric Ginger Latte,7,6.12,42.81,08:28:30\n2024-01-05,Cold Brew Concentrate,7,5.77,40.38,08:29:07\n2024-01-05,Nitro Cold Brew,13,6.03,78.41,08:29:43\n2024-01-05,Matcha Espresso Fusion,15,6.92,103.85,08:30:20\n2024-01-05,Blue Pea Flower Tea,7,4.56,31.93,08:30:56\n2024-01-05,Sourdough Toast,16,6.37,101.95,08:31:32\n2024-01-05,Almond Butter Croissant,5,5.28,26.42,08:32:09\n2024-01-05,Vegan Morning Bun,18,5.61,100.99,08:32:45\n2024-01-06,Single-Origin Pour Over,12,5.42,65.03,08:33:22\n2024-01-06,Oat Milk Latte,15,5.97,89.57,08:33:58\n2024-01-06,Honey Lavender Latte,13,6.29,81.8,08:34:34\n2024-01-06,Turmeric Ginger Latte,9,6.48,58.34,08:35:11\n2024-01-06,Cold Brew Concentrate,15,5.6,84.04,08:35:47\n2024-01-06,Nitro Cold Brew,16,6.47,103.56,08:36:24\n2024-01-06,Matcha Espresso Fusion,14,6.73,94.27,08:37:00\n2024-01-06,Blue Pea Flower Tea,8,4.45,35.63,08:37:36\n2024-01-06,Sourdough Toast,14,6.02,84.32,08:38:13\n2024-01-06,Almond Butter Croissant,13,5.63,73.21,08:38:49\n2024-01-06,Vegan Morning Bun,13,5.74,74.61,08:39:26\n2024-01-07,Single-Origin Pour Over,8,5.79,46.3,08:40:02\n2024-01-07,Oat Milk Latte,8,6.38,51.02,08:40:38\n2024-01-07,Honey Lavender Latte,11,6.44,70.8,08:41:15\n2024-01-07,Turmeric Ginger Latte,21,6.54,137.38,08:41:51\n2024-01-07,Cold Brew Concentrate,14,6.05,84.72,08:42:28\n2024-01-07,Nitro Cold Brew,9,6.2,55.84,08:43:04\n2024-01-07,Matcha Espresso Fusion,9,6.85,61.66,08:43:40\n2024-01-07,Blue Pea Flower Tea,3,4.31,12.94,08:44:17\n2024-01-07,Sourdough Toast,12,6.25,75.04,08:44:53\n2024-01-07,Almond Butter Croissant,18,5.15,92.7,08:45:30\n2024-01-07,Vegan Morning Bun,14,5.96,83.37,08:46:06\n2024-01-08,Single-Origin Pour Over,11,5.8,63.76,08:46:42\n2024-01-08,Oat Milk Latte,7,6.09,42.6,08:47:19\n2024-01-08,Honey Lavender Latte,17,6.35,107.98,08:47:55\n2024-01-08,Turmeric Ginger Latte,12,6.54,78.47,08:48:32\n2024-01-08,Cold Brew Concentrate,14,5.55,77.67,08:49:08\n2024-01-08,Nitro Cold Brew,8,6.57,52.6,08:49:44\n2024-01-08,Matcha Espresso Fusion,11,6.79,74.69,08:50:21\n2024-01-08,Blue Pea Flower Tea,8,4.37,34.96,08:50:57\n2024-01-08,Sourdough Toast,12,6.03,72.4,08:51:34\n2024-01-08,Almond Butter Croissant,25,5.4,135.08,08:52:10\n2024-01-08,Vegan Morning Bun,11,5.74,63.17,08:52:46\n2024-01-09,Single-Origin Pour Over,6,5.43,32.57,08:53:23\n2024-01-09,Oat Milk Latte,13,6.27,81.5,08:53:59\n2024-01-09,Honey Lavender Latte,9,6.41,57.67,08:54:36\n2024-01-09,Turmeric Ginger Latte,9,6.31,56.81,08:55:12\n2024-01-09,Cold Brew Concentrate,5,5.94,29.71,08:55:48\n2024-01-09,Nitro Cold Brew,11,6.52,71.69,08:56:25\n2024-01-09,Matcha Espresso Fusion,20,6.75,135.08,08:57:01\n2024-01-09,Blue Pea Flower Tea,15,4.28,64.2,08:57:38\n2024-01-09,Sourdough Toast,1,6.14,6.14,08:58:14\n2024-01-09,Almond Butter Croissant,7,5.09,35.61,08:58:50\n2024-01-09,Vegan Morning Bun,15,5.67,85.08,08:59:27\n2024-01-10,Single-Origin Pour Over,9,5.52,49.65,09:00:03\n2024-01-10,Oat Milk Latte,11,5.84,64.29,09:00:40\n2024-01-10,Honey Lavender Latte,13,6.71,87.18,09:01:16\n2024-01-10,Turmeric Ginger Latte,21,6.03,126.57,09:01:52\n2024-01-10,Cold Brew Concentrate,17,5.77,98.11,09:02:29\n2024-01-10,Nitro Cold Brew,10,6.19,61.92,09:03:05\n2024-01-10,Matcha Espresso Fusion,12,7.14,85.71,09:03:42\n2024-01-10,Blue Pea Flower Tea,11,4.73,52.01,09:04:18\n2024-01-10,Sourdough Toast,14,6.16,86.26,09:04:54\n2024-01-10,Almond Butter Croissant,17,5.11,86.91,09:05:31\n2024-01-10,Vegan Morning Bun,11,6.04,66.42,09:06:07\n2024-01-11,Single-Origin Pour Over,9,5.69,51.18,09:06:44\n2024-01-11,Oat Milk Latte,21,6.05,127.03,09:07:20\n2024-01-11,Honey Lavender Latte,10,6.58,65.8,09:07:56\n2024-01-11,Turmeric Ginger Latte,13,6.57,85.36,09:08:33\n2024-01-11,Cold Brew Concentrate,13,5.72,74.42,09:09:09\n2024-01-11,Nitro Cold Brew,10,6.04,60.37,09:09:46\n2024-01-11,Matcha Espresso Fusion,8,6.98,55.82,09:10:22\n2024-01-11,Blue Pea Flower Tea,20,4.56,91.2,09:10:58\n2024-01-11,Sourdough Toast,1,5.94,5.94,09:11:35\n2024-01-11,Almond Butter Croissant,12,5.59,67.03,09:12:11\n2024-01-11,Vegan Morning Bun,17,6.08,103.4,09:12:48\n2024-01-12,Single-Origin Pour Over,15,5.41,81.19,09:13:24\n2024-01-12,Oat Milk Latte,26,5.82,151.44,09:14:00\n2024-01-12,Honey Lavender Latte,13,6.75,87.69,09:14:37\n2024-01-12,Turmeric Ginger Latte,12,6.08,72.99,09:15:13\n2024-01-12,Cold Brew Concentrate,5,5.55,27.74,09:15:50\n2024-01-12,Nitro Cold Brew,11,6.44,70.82,09:16:26\n2024-01-12,Matcha Espresso Fusion,24,7.01,168.34,09:17:02\n2024-01-12,Blue Pea Flower Tea,17,4.67,79.44,09:17:39\n2024-01-12,Sourdough Toast,21,6.1,128.16,09:18:15\n2024-01-12,Almond Butter Croissant,17,5.29,89.99,09:18:52\n2024-01-12,Vegan Morning Bun,12,5.85,70.17,09:19:28\n2024-01-13,Single-Origin Pour Over,9,5.53,49.78,09:20:04\n2024-01-13,Oat Milk Latte,13,5.82,75.61,09:20:41\n2024-01-13,Honey Lavender Latte,8,6.59,52.68,09:21:17\n2024-01-13,Turmeric Ginger Latte,8,6.37,50.97,09:21:54\n2024-01-13,Cold Brew Concentrate,11,6.08,66.87,09:22:30\n2024-01-13,Nitro Cold Brew,18,6.26,112.62,09:23:06\n2024-01-13,Matcha Espresso Fusion,13,6.91,89.77,09:23:43\n2024-01-13,Blue Pea Flower Tea,20,4.43,88.52,09:24:19\n2024-01-13,Sourdough Toast,12,6.4,76.77,09:24:56\n2024-01-13,Almond Butter Croissant,6,5.03,30.19,09:25:32\n2024-01-13,Vegan Morning Bun,17,5.53,93.93,09:26:08\n2024-01-14,Single-Origin Pour Over,7,5.74,40.15,09:26:45\n2024-01-14,Oat Milk Latte,20,6.11,122.16,09:27:21\n2024-01-14,Honey Lavender Latte,14,6.86,96.05,09:27:58\n2024-01-14,Turmeric Ginger Latte,16,6.03,96.53,09:28:34\n2024-01-14,Cold Brew Concentrate,2,5.86,11.72,09:29:10\n2024-01-14,Nitro Cold Brew,13,6.61,85.99,09:29:47\n2024-01-14,Matcha Espresso Fusion,11,6.59,72.49,09:30:23\n2024-01-14,Blue Pea Flower Tea,15,4.6,69.05,09:31:00\n2024-01-14,Sourdough Toast,7,6.1,42.68,09:31:36\n2024-01-14,Almond Butter Croissant,10,5.26,52.55,09:32:12\n2024-01-14,Vegan Morning Bun,11,6.15,67.64,09:32:49\n2024-01-15,Single-Origin Pour Over,13,5.38,69.91,09:33:25\n2024-01-15,Oat Milk Latte,18,6.35,114.27,09:34:02\n2024-01-15,Honey Lavender Latte,21,6.38,134.02,09:34:38\n2024-01-15,Turmeric Ginger Latte,5,6.21,31.07,09:35:14\n2024-01-15,Cold Brew Concentrate,6,5.51,33.09,09:35:51\n2024-01-15,Nitro Cold Brew,3,6.43,19.29,09:36:27\n2024-01-15,Matcha Espresso Fusion,13,6.9,89.74,09:37:04\n2024-01-15,Blue Pea Flower Tea,6,4.7,28.22,09:37:40\n2024-01-15,Sourdough Toast,6,6.24,37.45,09:38:16\n2024-01-15,Almond Butter Croissant,6,5.25,31.51,09:38:53\n2024-01-15,Vegan Morning Bun,7,6.14,42.95,09:39:29\n2024-01-16,Single-Origin Pour Over,4,5.53,22.14,09:40:06\n2024-01-16,Oat Milk Latte,8,6.34,50.75,09:40:42\n2024-01-16,Honey Lavender Latte,20,6.72,134.35,09:41:18\n2024-01-16,Turmeric Ginger Latte,7,6.24,43.65,09:41:55\n2024-01-16,Cold Brew Concentrate,11,5.82,64.01,09:42:31\n2024-01-16,Nitro Cold Brew,13,6.14,79.77,09:43:08\n2024-01-16,Matcha Espresso Fusion,3,6.82,20.46,09:43:44\n2024-01-16,Blue Pea Flower Tea,22,4.73,104.16,09:44:20\n2024-01-16,Sourdough Toast,13,6.22,80.92,09:44:57\n2024-01-16,Almond Butter Croissant,5,5.57,27.84,09:45:33\n2024-01-16,Vegan Morning Bun,1,5.74,5.74,09:46:10\n2024-01-17,Single-Origin Pour Over,12,5.45,65.38,09:46:46\n2024-01-17,Oat Milk Latte,15,6.15,92.32,09:47:22\n2024-01-17,Honey Lavender Latte,13,6.47,84.14,09:47:59\n2024-01-17,Turmeric Ginger Latte,21,6.3,132.22,09:48:35\n2024-01-17,Cold Brew Concentrate,10,5.59,55.94,09:49:12\n2024-01-17,Nitro Cold Brew,9,6.43,57.9,09:49:48\n2024-01-17,Matcha Espresso Fusion,12,6.54,78.48,09:50:24\n2024-01-17,Blue Pea Flower Tea,1,4.37,4.37,09:51:01\n2024-01-17,Sourdough Toast,16,6.3,100.88,09:51:37\n2024-01-17,Almond Butter Croissant,19,5.63,106.89,09:52:14\n2024-01-17,Vegan Morning Bun,18,5.79,104.24,09:52:50\n2024-01-18,Single-Origin Pour Over,4,5.58,22.31,09:53:26\n2024-01-18,Oat Milk Latte,13,6.16,80.02,09:54:03\n2024-01-18,Honey Lavender Latte,11,6.34,69.76,09:54:39\n2024-01-18,Turmeric Ginger Latte,12,6.01,72.11,09:55:16\n2024-01-18,Cold Brew Concentrate,16,6.02,96.38,09:55:52\n2024-01-18,Nitro Cold Brew,12,6.28,75.35,09:56:28\n2024-01-18,Matcha Espresso Fusion,13,6.75,87.72,09:57:05\n2024-01-18,Blue Pea Flower Tea,9,4.76,42.84,09:57:41\n2024-01-18,Sourdough Toast,13,6.07,78.96,09:58:18\n2024-01-18,Almond Butter Croissant,7,5.11,35.79,09:58:54\n2024-01-18,Vegan Morning Bun,10,6.06,60.59,09:59:30\n2024-01-19,Single-Origin Pour Over,14,5.77,80.82,10:00:07\n2024-01-19,Oat Milk Latte,9,5.81,52.26,10:00:43\n2024-01-19,Honey Lavender Latte,19,6.57,124.8,10:01:20\n2024-01-19,Turmeric Ginger Latte,10,6.56,65.63,10:01:56\n2024-01-19,Cold Brew Concentrate,19,5.64,107.14,10:02:32\n2024-01-19,Nitro Cold Brew,5,6.55,32.74,10:03:09\n2024-01-19,Matcha Espresso Fusion,13,6.71,87.23,10:03:45\n2024-01-19,Blue Pea Flower Tea,17,4.48,76.09,10:04:22\n2024-01-19,Sourdough Toast,7,6.08,42.57,10:04:58\n2024-01-19,Almond Butter Croissant,13,5.19,67.5,10:05:34\n2024-01-19,Vegan Morning Bun,5,6.04,30.21,10:06:11\n2024-01-20,Single-Origin Pour Over,6,5.36,32.18,10:06:47\n2024-01-20,Oat Milk Latte,8,5.76,46.08,10:07:24\n2024-01-20,Honey Lavender Latte,9,6.53,58.74,10:08:00\n2024-01-20,Turmeric Ginger Latte,1,6.56,6.56,10:08:36\n2024-01-20,Cold Brew Concentrate,9,5.84,52.59,10:09:13\n2024-01-20,Nitro Cold Brew,22,6.05,133.14,10:09:49\n2024-01-20,Matcha Espresso Fusion,15,7.05,105.68,10:10:26\n2024-01-20,Blue Pea Flower Tea,12,4.85,58.22,10:11:02\n2024-01-20,Sourdough Toast,7,6.11,42.75,10:11:38\n2024-01-20,Almond Butter Croissant,18,5.59,100.54,10:12:15\n2024-01-20,Vegan Morning Bun,7,5.9,41.3,10:12:51\n2024-01-21,Single-Origin Pour Over,21,5.36,112.65,10:13:28\n2024-01-21,Oat Milk Latte,13,5.91,76.82,10:14:04\n2024-01-21,Honey Lavender Latte,10,6.74,67.38,10:14:40\n2024-01-21,Turmeric Ginger Latte,8,6.45,51.61,10:15:17\n2024-01-21,Cold Brew Concentrate,15,6.02,90.24,10:15:53\n2024-01-21,Nitro Cold Brew,17,6.1,103.65,10:16:30\n2024-01-21,Matcha Espresso Fusion,10,6.82,68.2,10:17:06\n2024-01-21,Blue Pea Flower Tea,12,4.8,57.58,10:17:42\n2024-01-21,Sourdough Toast,2,5.93,11.86,10:18:19\n2024-01-21,Almond Butter Croissant,10,5.26,52.56,10:18:55\n2024-01-21,Vegan Morning Bun,8,5.78,46.26,10:19:32\n2024-01-22,Single-Origin Pour Over,16,5.72,91.52,10:20:08\n2024-01-22,Oat Milk Latte,17,6.07,103.14,10:20:44\n2024-01-22,Honey Lavender Latte,17,6.34,107.83,10:21:21\n2024-01-22,Turmeric Ginger Latte,11,6.53,71.8,10:21:57\n2024-01-22,Cold Brew Concentrate,12,5.5,66.06,10:22:34\n2024-01-22,Nitro Cold Brew,4,6.45,25.81,10:23:10\n2024-01-22,Matcha Espresso Fusion,10,6.93,69.31,10:23:46\n2024-01-22,Blue Pea Flower Tea,21,4.89,102.6,10:24:23\n2024-01-22,Sourdough Toast,10,5.81,58.11,10:24:59\n2024-01-22,Almond Butter Croissant,21,5.41,113.64,10:25:36\n2024-01-22,Vegan Morning Bun,15,5.67,85.06,10:26:12\n2024-01-23,Single-Origin Pour Over,10,5.8,57.99,10:26:48\n2024-01-23,Oat Milk Latte,14,6.06,84.78,10:27:25\n2024-01-23,Honey Lavender Latte,13,6.3,81.91,10:28:01\n2024-01-23,Turmeric Ginger Latte,10,6.52,65.17,10:28:38\n2024-01-23,Cold Brew Concentrate,16,6.02,96.35,10:29:14\n2024-01-23,Nitro Cold Brew,13,6.26,81.4,10:29:50\n2024-01-23,Matcha Espresso Fusion,9,6.5,58.51,10:30:27\n2024-01-23,Blue Pea Flower Tea,8,4.67,37.4,10:31:03\n2024-01-23,Sourdough Toast,9,6.2,55.77,10:31:40\n2024-01-23,Almond Butter Croissant,4,5.29,21.16,10:32:16\n2024-01-23,Vegan Morning Bun,7,5.72,40.04,10:32:52\n2024-01-24,Single-Origin Pour Over,12,5.38,64.61,10:33:29\n2024-01-24,Oat Milk Latte,19,6.08,115.48,10:34:05\n2024-01-24,Honey Lavender Latte,16,6.28,100.46,10:34:42\n2024-01-24,Turmeric Ginger Latte,7,6.17,43.22,10:35:18\n2024-01-24,Cold Brew Concentrate,8,5.67,45.37,10:35:54\n2024-01-24,Nitro Cold Brew,13,6.23,80.93,10:36:31\n2024-01-24,Matcha Espresso Fusion,14,7.11,99.57,10:37:07\n2024-01-24,Blue Pea Flower Tea,5,4.72,23.62,10:37:44\n2024-01-24,Sourdough Toast,11,5.92,65.1,10:38:20\n2024-01-24,Almond Butter Croissant,14,5.19,72.64,10:38:56\n2024-01-24,Vegan Morning Bun,15,5.8,86.98,10:39:33\n2024-01-25,Single-Origin Pour Over,16,5.59,89.48,10:40:09\n2024-01-25,Oat Milk Latte,18,5.89,106.01,10:40:46\n2024-01-25,Honey Lavender Latte,17,6.55,111.3,10:41:22\n2024-01-25,Turmeric Ginger Latte,6,6.47,38.8,10:41:58\n2024-01-25,Cold Brew Concentrate,6,5.56,33.39,10:42:35\n2024-01-25,Nitro Cold Brew,18,6.44,115.97,10:43:11\n2024-01-25,Matcha Espresso Fusion,16,6.58,105.3,10:43:48\n2024-01-25,Blue Pea Flower Tea,2,4.34,8.69,10:44:24\n2024-01-25,Sourdough Toast,21,5.83,122.35,10:45:00\n2024-01-25,Almond Butter Croissant,7,5.5,38.52,10:45:37\n2024-01-25,Vegan Morning Bun,14,5.99,83.82,10:46:13\n2024-01-26,Single-Origin Pour Over,16,5.41,86.48,10:46:50\n2024-01-26,Oat Milk Latte,10,5.83,58.32,10:47:26\n2024-01-26,Honey Lavender Latte,8,6.52,52.17,10:48:02\n2024-01-26,Turmeric Ginger Latte,8,6.56,52.45,10:48:39\n2024-01-26,Cold Brew Concentrate,16,5.79,92.71,10:49:15\n2024-01-26,Nitro Cold Brew,14,6.29,87.99,10:49:52\n2024-01-26,Matcha Espresso Fusion,6,6.71,40.29,10:50:28\n2024-01-26,Blue Pea Flower Tea,13,4.74,61.6,10:51:04\n2024-01-26,Sourdough Toast,12,5.94,71.29,10:51:41\n2024-01-26,Almond Butter Croissant,3,5.64,16.92,10:52:17\n2024-01-26,Vegan Morning Bun,5,5.5,27.51,10:52:54\n2024-01-27,Single-Origin Pour Over,12,5.35,64.22,10:53:30\n2024-01-27,Oat Milk Latte,22,6.17,135.68,10:54:06\n2024-01-27,Honey Lavender Latte,14,6.3,88.21,10:54:43\n2024-01-27,Turmeric Ginger Latte,15,6.52,97.75,10:55:19\n2024-01-27,Cold Brew Concentrate,16,5.87,93.85,10:55:56\n2024-01-27,Nitro Cold Brew,9,6.05,54.47,10:56:32\n2024-01-27,Matcha Espresso Fusion,14,6.79,95.11,10:57:08\n2024-01-27,Blue Pea Flower Tea,19,4.66,88.63,10:57:45\n2024-01-27,Sourdough Toast,9,6.34,57.09,10:58:21\n2024-01-27,Almond Butter Croissant,11,5.19,57.06,10:58:58\n2024-01-27,Vegan Morning Bun,14,5.8,81.21,10:59:34\n2024-01-28,Single-Origin Pour Over,13,5.78,75.13,11:00:10\n2024-01-28,Oat Milk Latte,6,5.94,35.64,11:00:47\n2024-01-28,Honey Lavender Latte,4,6.44,25.77,11:01:23\n2024-01-28,Turmeric Ginger Latte,2,6.04,12.09,11:02:00\n2024-01-28,Cold Brew Concentrate,15,5.95,89.23,11:02:36\n2024-01-28,Nitro Cold Brew,7,6.12,42.85,11:03:12\n2024-01-28,Matcha Espresso Fusion,4,6.53,26.13,11:03:49\n2024-01-28,Blue Pea Flower Tea,7,4.86,33.99,11:04:25\n2024-01-28,Sourdough Toast,21,5.76,121.01,11:05:02\n2024-01-28,Almond Butter Croissant,1,5.21,5.21,11:05:38\n2024-01-28,Vegan Morning Bun,12,6.13,73.6,11:06:14\n2024-01-29,Single-Origin Pour Over,15,5.83,87.42,11:06:51\n2024-01-29,Oat Milk Latte,12,5.97,71.65,11:07:27\n2024-01-29,Honey Lavender Latte,6,6.49,38.93,11:08:04\n2024-01-29,Turmeric Ginger Latte,14,6.45,90.23,11:08:40\n2024-01-29,Cold Brew Concentrate,7,5.55,38.86,11:09:16\n2024-01-29,Nitro Cold Brew,12,6.5,78.01,11:09:53\n2024-01-29,Matcha Espresso Fusion,16,6.64,106.3,11:10:29\n2024-01-29,Blue Pea Flower Tea,18,4.76,85.67,11:11:06\n2024-01-29,Sourdough Toast,6,5.86,35.15,11:11:42\n2024-01-29,Almond Butter Croissant,13,5.4,70.25,11:12:18\n2024-01-29,Vegan Morning Bun,12,5.69,68.3,11:12:55\n2024-01-30,Single-Origin Pour Over,13,5.72,74.3,11:13:31\n2024-01-30,Oat Milk Latte,14,6.02,84.27,11:14:08\n2024-01-30,Honey Lavender Latte,6,6.27,37.62,11:14:44\n2024-01-30,Turmeric Ginger Latte,19,6.59,125.26,11:15:20\n2024-01-30,Cold Brew Concentrate,28,5.96,166.94,11:15:57\n2024-01-30,Nitro Cold Brew,17,6.16,104.76,11:16:33\n2024-01-30,Matcha Espresso Fusion,5,6.93,34.63,11:17:10\n2024-01-30,Blue Pea Flower Tea,20,4.35,87.09,11:17:46\n2024-01-30,Sourdough Toast,19,6.21,118.03,11:18:22\n2024-01-30,Almond Butter Croissant,20,5.03,100.58,11:18:59\n2024-01-30,Vegan Morning Bun,13,5.98,77.69,11:19:35\n2024-01-31,Single-Origin Pour Over,12,5.34,64.09,11:20:12\n2024-01-31,Oat Milk Latte,14,6.35,88.91,11:20:48\n2024-01-31,Honey Lavender Latte,3,6.65,19.96,11:21:24\n2024-01-31,Turmeric Ginger Latte,14,6.56,91.82,11:22:01\n2024-01-31,Cold Brew Concentrate,12,5.91,70.94,11:22:37\n2024-01-31,Nitro Cold Brew,7,6.6,46.21,11:23:14\n2024-01-31,Matcha Espresso Fusion,12,6.98,83.71,11:23:50\n2024-01-31,Blue Pea Flower Tea,9,4.68,42.11,11:24:26\n2024-01-31,Sourdough Toast,13,6.16,80.09,11:25:03\n2024-01-31,Almond Butter Croissant,16,5.4,86.34,11:25:39\n2024-01-31,Vegan Morning Bun,13,5.84,75.86,11:26:16\n2024-02-01,Single-Origin Pour Over,10,5.26,52.64,11:26:52\n2024-02-01,Oat Milk Latte,14,6.18,86.48,11:27:28\n2024-02-01,Honey Lavender Latte,16,6.28,100.54,11:28:05\n2024-02-01,Turmeric Ginger Latte,7,6.53,45.71,11:28:41\n2024-02-01,Cold Brew Concentrate,18,5.6,100.83,11:29:18\n2024-02-01,Nitro Cold Brew,8,6.01,48.1,11:29:54\n2024-02-01,Matcha Espresso Fusion,10,6.71,67.1,11:30:30\n2024-02-01,Blue Pea Flower Tea,8,4.44,35.55,11:31:07\n2024-02-01,Sourdough Toast,20,6.36,127.17,11:31:43\n2024-02-01,Almond Butter Croissant,7,5.63,39.41,11:32:20\n2024-02-01,Vegan Morning Bun,8,5.55,44.41,11:32:56\n2024-02-02,Single-Origin Pour Over,14,5.49,76.86,11:33:32\n2024-02-02,Oat Milk Latte,20,5.94,118.84,11:34:09\n2024-02-02,Honey Lavender Latte,11,6.58,72.35,11:34:45\n2024-02-02,Turmeric Ginger Latte,8,6.16,49.29,11:35:22\n2024-02-02,Cold Brew Concentrate,15,6.07,91.11,11:35:58\n2024-02-02,Nitro Cold Brew,4,6.38,25.52,11:36:34\n2024-02-02,Matcha Espresso Fusion,16,6.84,109.5,11:37:11\n2024-02-02,Blue Pea Flower Tea,9,4.65,41.87,11:37:47\n2024-02-02,Sourdough Toast,7,6.2,43.37,11:38:24\n2024-02-02,Almond Butter Croissant,16,5.17,82.77,11:39:00\n2024-02-02,Vegan Morning Bun,5,6.02,30.09,11:39:36\n2024-02-03,Single-Origin Pour Over,15,5.48,82.14,11:40:13\n2024-02-03,Oat Milk Latte,15,6.32,94.74,11:40:49\n2024-02-03,Honey Lavender Latte,14,6.59,92.23,11:41:26\n2024-02-03,Turmeric Ginger Latte,2,6.56,13.11,11:42:02\n2024-02-03,Cold Brew Concentrate,14,6.0,83.94,11:42:38\n2024-02-03,Nitro Cold Brew,16,6.6,105.56,11:43:15\n2024-02-03,Matcha Espresso Fusion,30,6.86,205.94,11:43:51\n2024-02-03,Blue Pea Flower Tea,12,4.61,55.34,11:44:28\n2024-02-03,Sourdough Toast,19,6.03,114.6,11:45:04\n2024-02-03,Almond Butter Croissant,8,5.29,42.29,11:45:40\n2024-02-03,Vegan Morning Bun,1,5.59,5.59,11:46:17\n2024-02-04,Single-Origin Pour Over,12,5.56,66.76,11:46:53\n2024-02-04,Oat Milk Latte,11,6.35,69.85,11:47:30\n2024-02-04,Honey Lavender Latte,11,6.79,74.68,11:48:06\n2024-02-04,Turmeric Ginger Latte,1,6.43,6.43,11:48:42\n2024-02-04,Cold Brew Concentrate,9,5.91,53.15,11:49:19\n2024-02-04,Nitro Cold Brew,2,6.26,12.52,11:49:55\n2024-02-04,Matcha Espresso Fusion,8,6.98,55.85,11:50:32\n2024-02-04,Blue Pea Flower Tea,8,4.39,35.09,11:51:08\n2024-02-04,Sourdough Toast,9,6.39,57.54,11:51:44\n2024-02-04,Almond Butter Croissant,7,5.64,39.51,11:52:21\n2024-02-04,Vegan Morning Bun,4,5.79,23.15,11:52:57\n2024-02-05,Single-Origin Pour Over,11,5.82,64.06,11:53:34\n2024-02-05,Oat Milk Latte,16,6.32,101.16,11:54:10\n2024-02-05,Honey Lavender Latte,12,6.78,81.35,11:54:46\n2024-02-05,Turmeric Ginger Latte,12,6.11,73.32,11:55:23\n2024-02-05,Cold Brew Concentrate,17,6.01,102.11,11:55:59\n2024-02-05,Nitro Cold Brew,12,6.6,79.2,11:56:36\n2024-02-05,Matcha Espresso Fusion,11,7.1,78.11,11:57:12\n2024-02-05,Blue Pea Flower Tea,14,4.4,61.62,11:57:48\n2024-02-05,Sourdough Toast,12,6.12,73.48,11:58:25\n2024-02-05,Almond Butter Croissant,13,5.41,70.3,11:59:01\n2024-02-05,Vegan Morning Bun,18,5.76,103.59,11:59:38\n2024-02-06,Single-Origin Pour Over,13,5.63,73.19,12:00:14\n2024-02-06,Oat Milk Latte,10,5.98,59.83,12:00:50\n2024-02-06,Honey Lavender Latte,7,6.37,44.59,12:01:27\n2024-02-06,Turmeric Ginger Latte,9,6.43,57.91,12:02:03\n2024-02-06,Cold Brew Concentrate,7,6.05,42.35,12:02:40\n2024-02-06,Nitro Cold Brew,6,6.06,36.36,12:03:16\n2024-02-06,Matcha Espresso Fusion,11,7.04,77.42,12:03:52\n2024-02-06,Blue Pea Flower Tea,14,4.79,67.0,12:04:29\n2024-02-06,Sourdough Toast,10,6.18,61.76,12:05:05\n2024-02-06,Almond Butter Croissant,12,5.29,63.48,12:05:42\n2024-02-06,Vegan Morning Bun,12,5.93,71.18,12:06:18\n2024-02-07,Single-Origin Pour Over,2,5.5,11.01,12:06:54\n2024-02-07,Oat Milk Latte,5,5.86,29.29,12:07:31\n2024-02-07,Honey Lavender Latte,9,6.65,59.89,12:08:07\n2024-02-07,Turmeric Ginger Latte,17,6.49,110.26,12:08:44\n2024-02-07,Cold Brew Concentrate,20,5.71,114.15,12:09:20\n2024-02-07,Nitro Cold Brew,7,6.54,45.81,12:09:56\n2024-02-07,Matcha Espresso Fusion,7,7.05,49.36,12:10:33\n2024-02-07,Blue Pea Flower Tea,9,4.5,40.46,12:11:09\n2024-02-07,Sourdough Toast,16,5.94,95.02,12:11:46\n2024-02-07,Almond Butter Croissant,6,5.48,32.9,12:12:22\n2024-02-07,Vegan Morning Bun,15,6.02,90.23,12:12:58\n2024-02-08,Single-Origin Pour Over,5,5.42,27.1,12:13:35\n2024-02-08,Oat Milk Latte,12,6.12,73.42,12:14:11\n2024-02-08,Honey Lavender Latte,7,6.67,46.7,12:14:48\n2024-02-08,Turmeric Ginger Latte,15,6.59,98.86,12:15:24\n2024-02-08,Cold Brew Concentrate,14,6.12,85.72,12:16:00\n2024-02-08,Nitro Cold Brew,13,6.18,80.32,12:16:37\n2024-02-08,Matcha Espresso Fusion,12,6.75,81.04,12:17:13\n2024-02-08,Blue Pea Flower Tea,11,4.32,47.52,12:17:50\n2024-02-08,Sourdough Toast,9,5.87,52.87,12:18:26\n2024-02-08,Almond Butter Croissant,23,5.6,128.7,12:19:02\n2024-02-08,Vegan Morning Bun,13,5.68,73.88,12:19:39\n2024-02-09,Single-Origin Pour Over,11,5.29,58.18,12:20:15\n2024-02-09,Oat Milk Latte,10,6.35,63.5,12:20:52\n2024-02-09,Honey Lavender Latte,14,6.56,91.91,12:21:28\n2024-02-09,Turmeric Ginger Latte,8,6.17,49.38,12:22:04\n2024-02-09,Cold Brew Concentrate,13,5.94,77.24,12:22:41\n2024-02-09,Nitro Cold Brew,12,6.63,79.58,12:23:17\n2024-02-09,Matcha Espresso Fusion,13,6.65,86.51,12:23:54\n2024-02-09,Blue Pea Flower Tea,10,4.63,46.27,12:24:30\n2024-02-09,Sourdough Toast,9,5.99,53.92,12:25:06\n2024-02-09,Almond Butter Croissant,7,5.21,36.44,12:25:43\n2024-02-09,Vegan Morning Bun,5,5.87,29.34,12:26:19\n2024-02-10,Single-Origin Pour Over,16,5.5,87.95,12:26:56\n2024-02-10,Oat Milk Latte,14,6.36,89.04,12:27:32\n2024-02-10,Honey Lavender Latte,5,6.52,32.6,12:28:08\n2024-02-10,Turmeric Ginger Latte,2,6.5,12.99,12:28:45\n2024-02-10,Cold Brew Concentrate,9,5.72,51.5,12:29:21\n2024-02-10,Nitro Cold Brew,19,6.05,115.02,12:29:58\n2024-02-10,Matcha Espresso Fusion,10,6.72,67.16,12:30:34\n2024-02-10,Blue Pea Flower Tea,11,4.37,48.1,12:31:10\n2024-02-10,Sourdough Toast,18,6.07,109.22,12:31:47\n2024-02-10,Almond Butter Croissant,15,5.31,79.7,12:32:23\n2024-02-10,Vegan Morning Bun,13,6.15,79.89,12:33:00\n2024-02-11,Single-Origin Pour Over,11,5.67,62.34,12:33:36\n2024-02-11,Oat Milk Latte,10,6.13,61.32,12:34:12\n2024-02-11,Honey Lavender Latte,17,6.49,110.33,12:34:49\n2024-02-11,Turmeric Ginger Latte,12,6.58,78.97,12:35:25\n2024-02-11,Cold Brew Concentrate,14,5.9,82.62,12:36:02\n2024-02-11,Nitro Cold Brew,10,6.39,63.86,12:36:38\n2024-02-11,Matcha Espresso Fusion,9,7.1,63.86,12:37:14\n2024-02-11,Blue Pea Flower Tea,5,4.68,23.39,12:37:51\n2024-02-11,Sourdough Toast,18,6.16,110.9,12:38:27\n2024-02-11,Almond Butter Croissant,12,5.01,60.06,12:39:04\n2024-02-11,Vegan Morning Bun,13,6.14,79.84,12:39:40\n2024-02-12,Single-Origin Pour Over,10,5.88,58.77,12:40:16\n2024-02-12,Oat Milk Latte,7,6.19,43.31,12:40:53\n2024-02-12,Honey Lavender Latte,8,6.51,52.08,12:41:29\n2024-02-12,Turmeric Ginger Latte,21,6.2,130.14,12:42:06\n2024-02-12,Cold Brew Concentrate,8,5.58,44.65,12:42:42\n2024-02-12,Nitro Cold Brew,18,6.13,110.38,12:43:18\n2024-02-12,Matcha Espresso Fusion,7,6.93,48.48,12:43:55\n2024-02-12,Blue Pea Flower Tea,8,4.45,35.56,12:44:31\n2024-02-12,Sourdough Toast,15,6.13,92.0,12:45:08\n2024-02-12,Almond Butter Croissant,16,5.31,84.95,12:45:44\n2024-02-12,Vegan Morning Bun,7,5.96,41.72,12:46:20\n2024-02-13,Single-Origin Pour Over,1,5.29,5.29,12:46:57\n2024-02-13,Oat Milk Latte,15,6.21,93.16,12:47:33\n2024-02-13,Honey Lavender Latte,6,6.62,39.73,12:48:10\n2024-02-13,Turmeric Ginger Latte,7,6.35,44.43,12:48:46\n2024-02-13,Cold Brew Concentrate,8,5.67,45.37,12:49:22\n2024-02-13,Nitro Cold Brew,16,6.47,103.48,12:49:59\n2024-02-13,Matcha Espresso Fusion,15,6.91,103.63,12:50:35\n2024-02-13,Blue Pea Flower Tea,12,4.43,53.2,12:51:12\n2024-02-13,Sourdough Toast,16,5.9,94.47,12:51:48\n2024-02-13,Almond Butter Croissant,13,5.5,71.47,12:52:24\n2024-02-13,Vegan Morning Bun,7,5.9,41.28,12:53:01\n2024-02-14,Single-Origin Pour Over,14,5.73,80.23,12:53:37\n2024-02-14,Oat Milk Latte,8,5.99,47.92,12:54:14\n2024-02-14,Honey Lavender Latte,8,6.64,53.11,12:54:50\n2024-02-14,Turmeric Ginger Latte,12,6.01,72.15,12:55:26\n2024-02-14,Cold Brew Concentrate,17,5.91,100.45,12:56:03\n2024-02-14,Nitro Cold Brew,9,6.24,56.19,12:56:39\n2024-02-14,Matcha Espresso Fusion,13,7.1,92.36,12:57:16\n2024-02-14,Blue Pea Flower Tea,15,4.57,68.52,12:57:52\n2024-02-14,Sourdough Toast,18,5.78,104.11,12:58:28\n2024-02-14,Almond Butter Croissant,18,5.09,91.63,12:59:05\n2024-02-14,Vegan Morning Bun,10,6.14,61.42,12:59:41\n2024-02-15,Single-Origin Pour Over,10,5.69,56.87,13:00:18\n2024-02-15,Oat Milk Latte,13,5.87,76.29,13:00:54\n2024-02-15,Honey Lavender Latte,13,6.74,87.62,13:01:31\n2024-02-15,Turmeric Ginger Latte,1,6.48,6.48,13:02:07\n2024-02-15,Cold Brew Concentrate,14,6.02,84.27,13:02:43\n2024-02-15,Nitro Cold Brew,20,6.55,131.07,13:03:20\n2024-02-15,Matcha Espresso Fusion,16,6.73,107.76,13:03:56\n2024-02-15,Blue Pea Flower Tea,11,4.84,53.29,13:04:33\n2024-02-15,Sourdough Toast,18,6.22,111.9,13:05:09\n2024-02-15,Almond Butter Croissant,13,5.33,69.32,13:05:45\n2024-02-15,Vegan Morning Bun,12,5.64,67.68,13:06:22\n2024-02-16,Single-Origin Pour Over,1,5.88,5.88,13:06:58\n2024-02-16,Oat Milk Latte,14,5.87,82.12,13:07:35\n2024-02-16,Honey Lavender Latte,16,6.33,101.29,13:08:11\n2024-02-16,Turmeric Ginger Latte,22,6.45,141.96,13:08:47\n2024-02-16,Cold Brew Concentrate,4,6.12,24.48,13:09:24\n2024-02-16,Nitro Cold Brew,21,6.07,127.49,13:10:00\n2024-02-16,Matcha Espresso Fusion,4,6.82,27.29,13:10:37\n2024-02-16,Blue Pea Flower Tea,16,4.49,71.83,13:11:13\n2024-02-16,Sourdough Toast,15,5.8,87.02,13:11:49\n2024-02-16,Almond Butter Croissant,13,5.31,69.05,13:12:26\n2024-02-16,Vegan Morning Bun,7,5.72,40.03,13:13:02\n2024-02-17,Single-Origin Pour Over,17,5.86,99.69,13:13:39\n2024-02-17,Oat Milk Latte,13,6.21,80.67,13:14:15\n2024-02-17,Honey Lavender Latte,7,6.68,46.77,13:14:51\n2024-02-17,Turmeric Ginger Latte,8,6.21,49.67,13:15:28\n2024-02-17,Cold Brew Concentrate,12,6.01,72.18,13:16:04\n2024-02-17,Nitro Cold Brew,22,6.6,145.12,13:16:41\n2024-02-17,Matcha Espresso Fusion,19,6.57,124.79,13:17:17\n2024-02-17,Blue Pea Flower Tea,10,4.51,45.09,13:17:53\n2024-02-17,Sourdough Toast,16,6.16,98.62,13:18:30\n2024-02-17,Almond Butter Croissant,15,5.6,83.94,13:19:06\n2024-02-17,Vegan Morning Bun,11,5.74,63.17,13:19:43\n2024-02-18,Single-Origin Pour Over,9,5.9,53.06,13:20:19\n2024-02-18,Oat Milk Latte,5,5.95,29.74,13:20:55\n2024-02-18,Honey Lavender Latte,4,6.56,26.26,13:21:32\n2024-02-18,Turmeric Ginger Latte,11,6.62,72.81,13:22:08\n2024-02-18,Cold Brew Concentrate,11,5.9,64.91,13:22:45\n2024-02-18,Nitro Cold Brew,11,6.51,71.61,13:23:21\n2024-02-18,Matcha Espresso Fusion,8,6.73,53.88,13:23:57\n2024-02-18,Blue Pea Flower Tea,10,4.76,47.62,13:24:34\n2024-02-18,Sourdough Toast,10,6.2,62.04,13:25:10\n2024-02-18,Almond Butter Croissant,11,5.17,56.9,13:25:47\n2024-02-18,Vegan Morning Bun,1,5.63,5.63,13:26:23\n2024-02-19,Single-Origin Pour Over,19,5.51,104.63,13:26:59\n2024-02-19,Oat Milk Latte,13,5.85,76.02,13:27:36\n2024-02-19,Honey Lavender Latte,3,6.9,20.7,13:28:12\n2024-02-19,Turmeric Ginger Latte,14,6.16,86.28,13:28:49\n2024-02-19,Cold Brew Concentrate,15,6.12,91.79,13:29:25\n2024-02-19,Nitro Cold Brew,9,6.19,55.72,13:30:01\n2024-02-19,Matcha Espresso Fusion,10,7.01,70.14,13:30:38\n2024-02-19,Blue Pea Flower Tea,12,4.52,54.29,13:31:14\n2024-02-19,Sourdough Toast,13,6.23,81.03,13:31:51\n2024-02-19,Almond Butter Croissant,12,5.32,63.82,13:32:27\n2024-02-19,Vegan Morning Bun,17,5.76,97.97,13:33:03\n2024-02-20,Single-Origin Pour Over,2,5.33,10.65,13:33:40\n2024-02-20,Oat Milk Latte,2,6.36,12.71,13:34:16\n2024-02-20,Honey Lavender Latte,21,6.55,137.45,13:34:53\n2024-02-20,Turmeric Ginger Latte,13,6.51,84.6,13:35:29\n2024-02-20,Cold Brew Concentrate,14,6.12,85.72,13:36:05\n2024-02-20,Nitro Cold Brew,9,6.08,54.76,13:36:42\n2024-02-20,Matcha Espresso Fusion,9,7.0,63.04,13:37:18\n2024-02-20,Blue Pea Flower Tea,11,4.59,50.49,13:37:55\n2024-02-20,Sourdough Toast,11,6.23,68.54,13:38:31\n2024-02-20,Almond Butter Croissant,13,5.05,65.62,13:39:07\n2024-02-20,Vegan Morning Bun,5,5.52,27.58,13:39:44\n2024-02-21,Single-Origin Pour Over,17,5.45,92.61,13:40:20\n2024-02-21,Oat Milk Latte,9,6.32,56.89,13:40:57\n2024-02-21,Honey Lavender Latte,12,6.52,78.26,13:41:33\n2024-02-21,Turmeric Ginger Latte,14,6.6,92.46,13:42:09\n2024-02-21,Cold Brew Concentrate,12,5.97,71.61,13:42:46\n2024-02-21,Nitro Cold Brew,15,6.41,96.19,13:43:22\n2024-02-21,Matcha Espresso Fusion,14,6.89,96.52,13:43:59\n2024-02-21,Blue Pea Flower Tea,15,4.61,69.18,13:44:35\n2024-02-21,Sourdough Toast,5,6.11,30.53,13:45:11\n2024-02-21,Almond Butter Croissant,10,5.36,53.59,13:45:48\n2024-02-21,Vegan Morning Bun,9,5.73,51.61,13:46:24\n2024-02-22,Single-Origin Pour Over,6,5.27,31.6,13:47:01\n2024-02-22,Oat Milk Latte,21,6.26,131.54,13:47:37\n2024-02-22,Honey Lavender Latte,1,6.43,6.43,13:48:13\n2024-02-22,Turmeric Ginger Latte,12,6.56,78.77,13:48:50\n2024-02-22,Cold Brew Concentrate,8,5.76,46.06,13:49:26\n2024-02-22,Nitro Cold Brew,13,6.64,86.37,13:50:03\n2024-02-22,Matcha Espresso Fusion,9,6.54,58.9,13:50:39\n2024-02-22,Blue Pea Flower Tea,10,4.29,42.95,13:51:15\n2024-02-22,Sourdough Toast,11,6.34,69.73,13:51:52\n2024-02-22,Almond Butter Croissant,9,5.62,50.54,13:52:28\n2024-02-22,Vegan Morning Bun,10,5.95,59.46,13:53:05\n2024-02-23,Single-Origin Pour Over,15,5.29,79.34,13:53:41\n2024-02-23,Oat Milk Latte,8,6.18,49.42,13:54:17\n2024-02-23,Honey Lavender Latte,16,6.44,103.01,13:54:54\n2024-02-23,Turmeric Ginger Latte,1,6.4,6.4,13:55:30\n2024-02-23,Cold Brew Concentrate,7,5.71,39.99,13:56:07\n2024-02-23,Nitro Cold Brew,13,6.5,84.51,13:56:43\n2024-02-23,Matcha Espresso Fusion,5,6.75,33.75,13:57:19\n2024-02-23,Blue Pea Flower Tea,11,4.5,49.53,13:57:56\n2024-02-23,Sourdough Toast,14,6.0,84.04,13:58:32\n2024-02-23,Almond Butter Croissant,14,5.64,78.94,13:59:09\n2024-02-23,Vegan Morning Bun,23,5.53,127.17,13:59:45\n2024-02-24,Single-Origin Pour Over,9,5.71,51.42,14:00:21\n2024-02-24,Oat Milk Latte,14,5.97,83.52,14:00:58\n2024-02-24,Honey Lavender Latte,9,6.36,57.27,14:01:34\n2024-02-24,Turmeric Ginger Latte,9,6.59,59.33,14:02:11\n2024-02-24,Cold Brew Concentrate,2,6.03,12.06,14:02:47\n2024-02-24,Nitro Cold Brew,9,6.35,57.14,14:03:23\n2024-02-24,Matcha Espresso Fusion,5,6.63,33.13,14:04:00\n2024-02-24,Blue Pea Flower Tea,16,4.34,69.48,14:04:36\n2024-02-24,Sourdough Toast,7,6.17,43.17,14:05:13\n2024-02-24,Almond Butter Croissant,3,5.25,15.76,14:05:49\n2024-02-24,Vegan Morning Bun,5,5.76,28.78,14:06:25\n2024-02-25,Single-Origin Pour Over,9,5.61,50.48,14:07:02\n2024-02-25,Oat Milk Latte,13,6.35,82.49,14:07:38\n2024-02-25,Honey Lavender Latte,9,6.62,59.58,14:08:15\n2024-02-25,Turmeric Ginger Latte,10,6.5,65.0,14:08:51\n2024-02-25,Cold Brew Concentrate,10,6.03,60.26,14:09:27\n2024-02-25,Nitro Cold Brew,8,6.42,51.32,14:10:04\n2024-02-25,Matcha Espresso Fusion,10,6.72,67.23,14:10:40\n2024-02-25,Blue Pea Flower Tea,5,4.87,24.33,14:11:17\n2024-02-25,Sourdough Toast,12,6.38,76.59,14:11:53\n2024-02-25,Almond Butter Croissant,20,5.57,111.44,14:12:29\n2024-02-25,Vegan Morning Bun,15,6.09,91.3,14:13:06\n2024-02-26,Single-Origin Pour Over,10,5.76,57.65,14:13:42\n2024-02-26,Oat Milk Latte,8,5.93,47.43,14:14:19\n2024-02-26,Honey Lavender Latte,13,6.56,85.26,14:14:55\n2024-02-26,Turmeric Ginger Latte,11,6.37,70.11,14:15:31\n2024-02-26,Cold Brew Concentrate,9,6.09,54.8,14:16:08\n2024-02-26,Nitro Cold Brew,9,6.5,58.5,14:16:44\n2024-02-26,Matcha Espresso Fusion,10,7.07,70.72,14:17:21\n2024-02-26,Blue Pea Flower Tea,15,4.34,65.06,14:17:57\n2024-02-26,Sourdough Toast,14,6.09,85.29,14:18:33\n2024-02-26,Almond Butter Croissant,10,5.27,52.68,14:19:10\n2024-02-26,Vegan Morning Bun,7,5.62,39.31,14:19:46\n2024-02-27,Single-Origin Pour Over,8,5.54,44.35,14:20:23\n2024-02-27,Oat Milk Latte,7,6.23,43.59,14:20:59\n2024-02-27,Honey Lavender Latte,12,6.31,75.7,14:21:35\n2024-02-27,Turmeric Ginger Latte,7,6.26,43.79,14:22:12\n2024-02-27,Cold Brew Concentrate,10,5.61,56.11,14:22:48\n2024-02-27,Nitro Cold Brew,12,6.29,75.51,14:23:25\n2024-02-27,Matcha Espresso Fusion,10,6.65,66.49,14:24:01\n2024-02-27,Blue Pea Flower Tea,12,4.28,51.37,14:24:37\n2024-02-27,Sourdough Toast,17,6.0,101.98,14:25:14\n2024-02-27,Almond Butter Croissant,5,5.19,25.97,14:25:50\n2024-02-27,Vegan Morning Bun,21,5.71,119.98,14:26:27\n2024-02-28,Single-Origin Pour Over,10,5.9,58.98,14:27:03\n2024-02-28,Oat Milk Latte,2,6.35,12.7,14:27:39\n2024-02-28,Honey Lavender Latte,16,6.36,101.68,14:28:16\n2024-02-28,Turmeric Ginger Latte,12,6.41,76.91,14:28:52\n2024-02-28,Cold Brew Concentrate,9,5.86,52.78,14:29:29\n2024-02-28,Nitro Cold Brew,15,6.34,95.05,14:30:05\n2024-02-28,Matcha Espresso Fusion,17,6.52,110.76,14:30:41\n2024-02-28,Blue Pea Flower Tea,2,4.59,9.18,14:31:18\n2024-02-28,Sourdough Toast,17,5.79,98.5,14:31:54\n2024-02-28,Almond Butter Croissant,11,5.57,61.31,14:32:31\n2024-02-28,Vegan Morning Bun,14,6.0,83.95,14:33:07\n2024-02-29,Single-Origin Pour Over,10,5.64,56.42,14:33:43\n2024-02-29,Oat Milk Latte,8,6.19,49.49,14:34:20\n2024-02-29,Honey Lavender Latte,1,6.49,6.49,14:34:56\n2024-02-29,Turmeric Ginger Latte,12,6.46,77.54,14:35:33\n2024-02-29,Cold Brew Concentrate,10,5.68,56.85,14:36:09\n2024-02-29,Nitro Cold Brew,13,6.23,80.96,14:36:45\n2024-02-29,Matcha Espresso Fusion,11,6.55,72.02,14:37:22\n2024-02-29,Blue Pea Flower Tea,10,4.51,45.05,14:37:58\n2024-02-29,Sourdough Toast,14,6.12,85.64,14:38:35\n2024-02-29,Almond Butter Croissant,4,5.15,20.62,14:39:11\n2024-02-29,Vegan Morning Bun,11,5.83,64.11,14:39:47\n2024-03-01,Single-Origin Pour Over,8,5.37,42.95,14:40:24\n2024-03-01,Oat Milk Latte,9,5.88,52.89,14:41:00\n2024-03-01,Honey Lavender Latte,11,6.74,74.15,14:41:37\n2024-03-01,Turmeric Ginger Latte,16,6.54,104.58,14:42:13\n2024-03-01,Cold Brew Concentrate,13,6.03,78.44,14:42:49\n2024-03-01,Nitro Cold Brew,8,6.15,49.19,14:43:26\n2024-03-01,Matcha Espresso Fusion,12,6.84,82.04,14:44:02\n2024-03-01,Blue Pea Flower Tea,15,4.9,73.44,14:44:39\n2024-03-01,Sourdough Toast,13,5.8,75.4,14:45:15\n2024-03-01,Almond Butter Croissant,4,5.23,20.94,14:45:51\n2024-03-01,Vegan Morning Bun,15,6.14,92.15,14:46:28\n2024-03-02,Single-Origin Pour Over,8,5.35,42.79,14:47:04\n2024-03-02,Oat Milk Latte,12,6.39,76.63,14:47:41\n2024-03-02,Honey Lavender Latte,9,6.88,61.89,14:48:17\n2024-03-02,Turmeric Ginger Latte,14,6.38,89.27,14:48:53\n2024-03-02,Cold Brew Concentrate,15,5.51,82.65,14:49:30\n2024-03-02,Nitro Cold Brew,12,6.3,75.66,14:50:06\n2024-03-02,Matcha Espresso Fusion,15,6.51,97.69,14:50:43\n2024-03-02,Blue Pea Flower Tea,9,4.88,43.88,14:51:19\n2024-03-02,Sourdough Toast,6,6.17,36.99,14:51:55\n2024-03-02,Almond Butter Croissant,7,5.48,38.36,14:52:32\n2024-03-02,Vegan Morning Bun,19,5.64,107.07,14:53:08\n2024-03-03,Single-Origin Pour Over,13,5.36,69.71,14:53:45\n2024-03-03,Oat Milk Latte,3,6.32,18.97,14:54:21\n2024-03-03,Honey Lavender Latte,11,6.86,75.42,14:54:57\n2024-03-03,Turmeric Ginger Latte,3,6.24,18.72,14:55:34\n2024-03-03,Cold Brew Concentrate,20,5.78,115.66,14:56:10\n2024-03-03,Nitro Cold Brew,15,6.17,92.51,14:56:47\n2024-03-03,Matcha Espresso Fusion,19,6.77,128.57,14:57:23\n2024-03-03,Blue Pea Flower Tea,12,4.7,56.37,14:57:59\n2024-03-03,Sourdough Toast,8,6.36,50.9,14:58:36\n2024-03-03,Almond Butter Croissant,4,5.04,20.18,14:59:12\n2024-03-03,Vegan Morning Bun,9,5.96,53.6,14:59:49\n2024-03-04,Single-Origin Pour Over,17,5.4,91.8,15:00:25\n2024-03-04,Oat Milk Latte,13,6.02,78.29,15:01:01\n2024-03-04,Honey Lavender Latte,15,6.26,93.96,15:01:38\n2024-03-04,Turmeric Ginger Latte,22,6.48,142.58,15:02:14\n2024-03-04,Cold Brew Concentrate,5,5.9,29.49,15:02:51\n2024-03-04,Nitro Cold Brew,13,6.32,82.17,15:03:27\n2024-03-04,Matcha Espresso Fusion,19,6.79,129.1,15:04:03\n2024-03-04,Blue Pea Flower Tea,5,4.85,24.26,15:04:40\n2024-03-04,Sourdough Toast,9,5.94,53.43,15:05:16\n2024-03-04,Almond Butter Croissant,7,5.39,37.71,15:05:53\n2024-03-04,Vegan Morning Bun,15,5.71,85.59,15:06:29\n2024-03-05,Single-Origin Pour Over,10,5.54,55.36,15:07:05\n2024-03-05,Oat Milk Latte,2,6.04,12.07,15:07:42\n2024-03-05,Honey Lavender Latte,6,6.67,40.04,15:08:18\n2024-03-05,Turmeric Ginger Latte,12,6.5,78.0,15:08:55\n2024-03-05,Cold Brew Concentrate,4,5.58,22.32,15:09:31\n2024-03-05,Nitro Cold Brew,1,6.02,6.02,15:10:07\n2024-03-05,Matcha Espresso Fusion,9,6.57,59.15,15:10:44\n2024-03-05,Blue Pea Flower Tea,4,4.48,17.93,15:11:20\n2024-03-05,Sourdough Toast,24,6.23,149.44,15:11:57\n2024-03-05,Almond Butter Croissant,2,5.34,10.68,15:12:33\n2024-03-05,Vegan Morning Bun,9,5.78,52.06,15:13:09\n2024-03-06,Single-Origin Pour Over,7,5.6,39.22,15:13:46\n2024-03-06,Oat Milk Latte,2,6.34,12.68,15:14:22\n2024-03-06,Honey Lavender Latte,5,6.68,33.42,15:14:59\n2024-03-06,Turmeric Ginger Latte,10,6.21,62.08,15:15:35\n2024-03-06,Cold Brew Concentrate,22,5.53,121.74,15:16:11\n2024-03-06,Nitro Cold Brew,9,6.55,58.99,15:16:48\n2024-03-06,Matcha Espresso Fusion,17,6.52,110.87,15:17:24\n2024-03-06,Blue Pea Flower Tea,11,4.65,51.14,15:18:01\n2024-03-06,Sourdough Toast,9,6.17,55.56,15:18:37\n2024-03-06,Almond Butter Croissant,16,5.26,84.21,15:19:13\n2024-03-06,Vegan Morning Bun,5,5.61,28.06,15:19:50\n2024-03-07,Single-Origin Pour Over,10,5.83,58.3,15:20:26\n2024-03-07,Oat Milk Latte,9,5.93,53.38,15:21:03\n2024-03-07,Honey Lavender Latte,6,6.89,41.34,15:21:39\n2024-03-07,Turmeric Ginger Latte,12,6.58,78.98,15:22:15\n2024-03-07,Cold Brew Concentrate,9,6.07,54.65,15:22:52\n2024-03-07,Nitro Cold Brew,9,6.19,55.72,15:23:28\n2024-03-07,Matcha Espresso Fusion,13,6.6,85.75,15:24:05\n2024-03-07,Blue Pea Flower Tea,7,4.3,30.08,15:24:41\n2024-03-07,Sourdough Toast,13,5.87,76.35,15:25:17\n2024-03-07,Almond Butter Croissant,12,5.56,66.67,15:25:54\n2024-03-07,Vegan Morning Bun,16,5.72,91.45,15:26:30\n2024-03-08,Single-Origin Pour Over,13,5.48,71.2,15:27:07\n2024-03-08,Oat Milk Latte,4,5.95,23.79,15:27:43\n2024-03-08,Honey Lavender Latte,13,6.33,82.3,15:28:19\n2024-03-08,Turmeric Ginger Latte,11,6.09,67.03,15:28:56\n2024-03-08,Cold Brew Concentrate,18,6.09,109.65,15:29:32\n2024-03-08,Nitro Cold Brew,22,6.35,139.8,15:30:09\n2024-03-08,Matcha Espresso Fusion,11,6.93,76.27,15:30:45\n2024-03-08,Blue Pea Flower Tea,18,4.65,83.68,15:31:21\n2024-03-08,Sourdough Toast,10,5.88,58.82,15:31:58\n2024-03-08,Almond Butter Croissant,18,5.63,101.37,15:32:34\n2024-03-08,Vegan Morning Bun,4,5.73,22.92,15:33:11\n2024-03-09,Single-Origin Pour Over,14,5.78,80.94,15:33:47\n2024-03-09,Oat Milk Latte,6,5.95,35.7,15:34:23\n2024-03-09,Honey Lavender Latte,21,6.62,138.97,15:35:00\n2024-03-09,Turmeric Ginger Latte,12,6.58,78.9,15:35:36\n2024-03-09,Cold Brew Concentrate,14,5.55,77.72,15:36:13\n2024-03-09,Nitro Cold Brew,10,6.22,62.15,15:36:49\n2024-03-09,Matcha Espresso Fusion,12,7.1,85.24,15:37:25\n2024-03-09,Blue Pea Flower Tea,17,4.65,79.13,15:38:02\n2024-03-09,Sourdough Toast,8,6.07,48.55,15:38:38\n2024-03-09,Almond Butter Croissant,15,5.31,79.66,15:39:15\n2024-03-09,Vegan Morning Bun,10,5.93,59.25,15:39:51\n2024-03-10,Single-Origin Pour Over,2,5.85,11.71,15:40:27\n2024-03-10,Oat Milk Latte,7,6.0,41.99,15:41:04\n2024-03-10,Honey Lavender Latte,12,6.45,77.39,15:41:40\n2024-03-10,Turmeric Ginger Latte,10,6.21,62.05,15:42:17\n2024-03-10,Cold Brew Concentrate,3,6.01,18.03,15:42:53\n2024-03-10,Nitro Cold Brew,17,6.2,105.34,15:43:29\n2024-03-10,Matcha Espresso Fusion,11,7.14,78.52,15:44:06\n2024-03-10,Blue Pea Flower Tea,13,4.33,56.3,15:44:42\n2024-03-10,Sourdough Toast,7,5.9,41.27,15:45:19\n2024-03-10,Almond Butter Croissant,13,5.24,68.13,15:45:55\n2024-03-10,Vegan Morning Bun,18,5.54,99.71,15:46:31\n2024-03-11,Single-Origin Pour Over,13,5.28,68.59,15:47:08\n2024-03-11,Oat Milk Latte,16,5.99,95.78,15:47:44\n2024-03-11,Honey Lavender Latte,9,6.31,56.76,15:48:21\n2024-03-11,Turmeric Ginger Latte,12,6.42,77.02,15:48:57\n2024-03-11,Cold Brew Concentrate,10,5.53,55.26,15:49:33\n2024-03-11,Nitro Cold Brew,15,6.31,94.67,15:50:10\n2024-03-11,Matcha Espresso Fusion,15,7.02,105.3,15:50:46\n2024-03-11,Blue Pea Flower Tea,15,4.75,71.31,15:51:23\n2024-03-11,Sourdough Toast,10,6.19,61.89,15:51:59\n2024-03-11,Almond Butter Croissant,13,5.62,73.05,15:52:35\n2024-03-11,Vegan Morning Bun,3,6.07,18.2,15:53:12\n2024-03-12,Single-Origin Pour Over,11,5.75,63.21,15:53:48\n2024-03-12,Oat Milk Latte,10,6.02,60.23,15:54:25\n2024-03-12,Honey Lavender Latte,12,6.51,78.14,15:55:01\n2024-03-12,Turmeric Ginger Latte,1,6.38,6.38,15:55:37\n2024-03-12,Cold Brew Concentrate,10,5.88,58.78,15:56:14\n2024-03-12,Nitro Cold Brew,6,6.27,37.65,15:56:50\n2024-03-12,Matcha Espresso Fusion,15,7.03,105.49,15:57:27\n2024-03-12,Blue Pea Flower Tea,2,4.35,8.7,15:58:03\n2024-03-12,Sourdough Toast,19,5.87,111.55,15:58:39\n2024-03-12,Almond Butter Croissant,20,5.45,109.02,15:59:16\n2024-03-12,Vegan Morning Bun,14,5.89,82.48,15:59:52\n2024-03-13,Single-Origin Pour Over,11,5.45,59.96,16:00:29\n2024-03-13,Oat Milk Latte,7,5.75,40.27,16:01:05\n2024-03-13,Honey Lavender Latte,15,6.88,103.13,16:01:41\n2024-03-13,Turmeric Ginger Latte,12,6.08,72.95,16:02:18\n2024-03-13,Cold Brew Concentrate,15,5.85,87.69,16:02:54\n2024-03-13,Nitro Cold Brew,14,6.04,84.59,16:03:31\n2024-03-13,Matcha Espresso Fusion,10,7.14,71.38,16:04:07\n2024-03-13,Blue Pea Flower Tea,10,4.57,45.69,16:04:43\n2024-03-13,Sourdough Toast,13,5.91,76.89,16:05:20\n2024-03-13,Almond Butter Croissant,5,5.4,27.01,16:05:56\n2024-03-13,Vegan Morning Bun,23,6.03,138.6,16:06:33\n2024-03-14,Single-Origin Pour Over,8,5.57,44.58,16:07:09\n2024-03-14,Oat Milk Latte,11,6.12,67.32,16:07:45\n2024-03-14,Honey Lavender Latte,5,6.38,31.92,16:08:22\n2024-03-14,Turmeric Ginger Latte,14,6.08,85.13,16:08:58\n2024-03-14,Cold Brew Concentrate,16,6.0,96.04,16:09:35\n2024-03-14,Nitro Cold Brew,14,6.34,88.69,16:10:11\n2024-03-14,Matcha Espresso Fusion,19,6.82,129.63,16:10:47\n2024-03-14,Blue Pea Flower Tea,10,4.62,46.2,16:11:24\n2024-03-14,Sourdough Toast,18,6.17,110.98,16:12:00\n2024-03-14,Almond Butter Croissant,13,5.29,68.8,16:12:37\n2024-03-14,Vegan Morning Bun,15,5.84,87.64,16:13:13\n2024-03-15,Single-Origin Pour Over,14,5.64,79.01,16:13:49\n2024-03-15,Oat Milk Latte,10,5.79,57.93,16:14:26\n2024-03-15,Honey Lavender Latte,13,6.66,86.58,16:15:02\n2024-03-15,Turmeric Ginger Latte,14,6.64,93.02,16:15:39\n2024-03-15,Cold Brew Concentrate,9,6.06,54.58,16:16:15\n2024-03-15,Nitro Cold Brew,17,6.61,112.39,16:16:51\n2024-03-15,Matcha Espresso Fusion,1,6.85,6.85,16:17:28\n2024-03-15,Blue Pea Flower Tea,7,4.35,30.45,16:18:04\n2024-03-15,Sourdough Toast,9,6.23,56.09,16:18:41\n2024-03-15,Almond Butter Croissant,14,5.23,73.23,16:19:17\n2024-03-15,Vegan Morning Bun,15,6.14,92.05,16:19:53\n2024-03-16,Single-Origin Pour Over,9,5.48,49.28,16:20:30\n2024-03-16,Oat Milk Latte,3,6.15,18.45,16:21:06\n2024-03-16,Honey Lavender Latte,6,6.48,38.88,16:21:43\n2024-03-16,Turmeric Ginger Latte,15,6.3,94.57,16:22:19\n2024-03-16,Cold Brew Concentrate,5,5.95,29.77,16:22:55\n2024-03-16,Nitro Cold Brew,1,6.33,6.33,16:23:32\n2024-03-16,Matcha Espresso Fusion,17,7.04,119.63,16:24:08\n2024-03-16,Blue Pea Flower Tea,7,4.56,31.95,16:24:45\n2024-03-16,Sourdough Toast,18,5.77,103.87,16:25:21\n2024-03-16,Almond Butter Croissant,14,5.11,71.54,16:25:57\n2024-03-16,Vegan Morning Bun,13,5.73,74.49,16:26:34\n2024-03-17,Single-Origin Pour Over,15,5.77,86.57,16:27:10\n2024-03-17,Oat Milk Latte,1,6.32,6.32,16:27:47\n2024-03-17,Honey Lavender Latte,14,6.84,95.74,16:28:23\n2024-03-17,Turmeric Ginger Latte,10,6.4,63.99,16:28:59\n2024-03-17,Cold Brew Concentrate,6,5.62,33.74,16:29:36\n2024-03-17,Nitro Cold Brew,12,6.39,76.64,16:30:12\n2024-03-17,Matcha Espresso Fusion,7,6.7,46.9,16:30:49\n2024-03-17,Blue Pea Flower Tea,19,4.75,90.27,16:31:25\n2024-03-17,Sourdough Toast,15,6.16,92.47,16:32:01\n2024-03-17,Almond Butter Croissant,14,5.44,76.09,16:32:38\n2024-03-17,Vegan Morning Bun,1,5.9,5.9,16:33:14\n2024-03-18,Single-Origin Pour Over,10,5.64,56.41,16:33:51\n2024-03-18,Oat Milk Latte,8,5.81,46.46,16:34:27\n2024-03-18,Honey Lavender Latte,5,6.68,33.42,16:35:03\n2024-03-18,Turmeric Ginger Latte,11,6.64,73.03,16:35:40\n2024-03-18,Cold Brew Concentrate,6,6.09,36.52,16:36:16\n2024-03-18,Nitro Cold Brew,15,6.45,96.79,16:36:53\n2024-03-18,Matcha Espresso Fusion,14,7.13,99.81,16:37:29\n2024-03-18,Blue Pea Flower Tea,14,4.51,63.15,16:38:05\n2024-03-18,Sourdough Toast,6,5.99,35.94,16:38:42\n2024-03-18,Almond Butter Croissant,14,5.45,76.28,16:39:18\n2024-03-18,Vegan Morning Bun,3,5.87,17.61,16:39:55\n2024-03-19,Single-Origin Pour Over,8,5.72,45.72,16:40:31\n2024-03-19,Oat Milk Latte,11,6.23,68.48,16:41:07\n2024-03-19,Honey Lavender Latte,8,6.29,50.31,16:41:44\n2024-03-19,Turmeric Ginger Latte,11,6.46,71.11,16:42:20\n2024-03-19,Cold Brew Concentrate,14,5.74,80.42,16:42:57\n2024-03-19,Nitro Cold Brew,13,6.39,83.04,16:43:33\n2024-03-19,Matcha Espresso Fusion,17,7.12,121.07,16:44:09\n2024-03-19,Blue Pea Flower Tea,16,4.49,71.82,16:44:46\n2024-03-19,Sourdough Toast,16,6.32,101.09,16:45:22\n2024-03-19,Almond Butter Croissant,13,5.13,66.65,16:45:59\n2024-03-19,Vegan Morning Bun,8,5.67,45.37,16:46:35\n2024-03-20,Single-Origin Pour Over,5,5.4,27.0,16:47:11\n2024-03-20,Oat Milk Latte,13,6.26,81.36,16:47:48\n2024-03-20,Honey Lavender Latte,16,6.61,105.71,16:48:24\n2024-03-20,Turmeric Ginger Latte,11,6.14,67.56,16:49:01\n2024-03-20,Cold Brew Concentrate,8,5.68,45.42,16:49:37\n2024-03-20,Nitro Cold Brew,10,6.39,63.89,16:50:13\n2024-03-20,Matcha Espresso Fusion,18,6.66,119.89,16:50:50\n2024-03-20,Blue Pea Flower Tea,12,4.81,57.67,16:51:26\n2024-03-20,Sourdough Toast,16,5.94,95.02,16:52:03\n2024-03-20,Almond Butter Croissant,9,5.36,48.21,16:52:39\n2024-03-20,Vegan Morning Bun,15,5.71,85.64,16:53:15\n2024-03-21,Single-Origin Pour Over,15,5.42,81.33,16:53:52\n2024-03-21,Oat Milk Latte,4,6.2,24.8,16:54:28\n2024-03-21,Honey Lavender Latte,17,6.71,114.08,16:55:05\n2024-03-21,Turmeric Ginger Latte,12,6.56,78.72,16:55:41\n2024-03-21,Cold Brew Concentrate,6,5.72,34.33,16:56:17\n2024-03-21,Nitro Cold Brew,20,6.46,129.24,16:56:54\n2024-03-21,Matcha Espresso Fusion,15,6.63,99.41,16:57:30\n2024-03-21,Blue Pea Flower Tea,14,4.45,62.31,16:58:07\n2024-03-21,Sourdough Toast,18,6.36,114.42,16:58:43\n2024-03-21,Almond Butter Croissant,10,5.52,55.21,16:59:19\n2024-03-21,Vegan Morning Bun,16,5.62,89.84,16:59:56\n2024-03-22,Single-Origin Pour Over,21,5.72,120.12,17:00:32\n2024-03-22,Oat Milk Latte,17,6.1,103.74,17:01:09\n2024-03-22,Honey Lavender Latte,5,6.57,32.84,17:01:45\n2024-03-22,Turmeric Ginger Latte,8,6.31,50.51,17:02:21\n2024-03-22,Cold Brew Concentrate,14,5.57,77.98,17:02:58\n2024-03-22,Nitro Cold Brew,13,6.53,84.89,17:03:34\n2024-03-22,Matcha Espresso Fusion,1,6.66,6.66,17:04:11\n2024-03-22,Blue Pea Flower Tea,16,4.38,70.14,17:04:47\n2024-03-22,Sourdough Toast,14,5.8,81.17,17:05:23\n2024-03-22,Almond Butter Croissant,7,5.09,35.62,17:06:00\n2024-03-22,Vegan Morning Bun,14,5.68,79.57,17:06:36\n2024-03-23,Single-Origin Pour Over,12,5.43,65.13,17:07:13\n2024-03-23,Oat Milk Latte,23,5.78,132.9,17:07:49\n2024-03-23,Honey Lavender Latte,7,6.39,44.72,17:08:25\n2024-03-23,Turmeric Ginger Latte,17,6.37,108.25,17:09:02\n2024-03-23,Cold Brew Concentrate,7,5.64,39.46,17:09:38\n2024-03-23,Nitro Cold Brew,11,6.6,72.57,17:10:15\n2024-03-23,Matcha Espresso Fusion,9,6.68,60.08,17:10:51\n2024-03-23,Blue Pea Flower Tea,13,4.43,57.58,17:11:27\n2024-03-23,Sourdough Toast,17,6.1,103.65,17:12:04\n2024-03-23,Almond Butter Croissant,12,5.05,60.57,17:12:40\n2024-03-23,Vegan Morning Bun,21,5.91,124.16,17:13:17\n2024-03-24,Single-Origin Pour Over,9,5.45,49.05,17:13:53\n2024-03-24,Oat Milk Latte,22,5.79,127.43,17:14:29\n2024-03-24,Honey Lavender Latte,18,6.82,122.72,17:15:06\n2024-03-24,Turmeric Ginger Latte,5,6.3,31.52,17:15:42\n2024-03-24,Cold Brew Concentrate,1,6.03,6.03,17:16:19\n2024-03-24,Nitro Cold Brew,14,6.34,88.69,17:16:55\n2024-03-24,Matcha Espresso Fusion,11,6.98,76.76,17:17:31\n2024-03-24,Blue Pea Flower Tea,10,4.61,46.14,17:18:08\n2024-03-24,Sourdough Toast,12,5.85,70.19,17:18:44\n2024-03-24,Almond Butter Croissant,11,5.2,57.17,17:19:21\n2024-03-24,Vegan Morning Bun,1,6.15,6.15,17:19:57\n2024-03-25,Single-Origin Pour Over,6,5.62,33.69,17:20:33\n2024-03-25,Oat Milk Latte,5,5.91,29.54,17:21:10\n2024-03-25,Honey Lavender Latte,17,6.51,110.64,17:21:46\n2024-03-25,Turmeric Ginger Latte,13,6.27,81.51,17:22:23\n2024-03-25,Cold Brew Concentrate,15,6.01,90.22,17:22:59\n2024-03-25,Nitro Cold Brew,10,6.01,60.14,17:23:35\n2024-03-25,Matcha Espresso Fusion,11,6.85,75.35,17:24:12\n2024-03-25,Blue Pea Flower Tea,5,4.55,22.76,17:24:48\n2024-03-25,Sourdough Toast,8,5.88,47.02,17:25:25\n2024-03-25,Almond Butter Croissant,11,5.61,61.68,17:26:01\n2024-03-25,Vegan Morning Bun,6,5.69,34.15,17:26:37\n2024-03-26,Single-Origin Pour Over,19,5.29,100.57,17:27:14\n2024-03-26,Oat Milk Latte,12,6.01,72.08,17:27:50\n2024-03-26,Honey Lavender Latte,11,6.63,72.89,17:28:27\n2024-03-26,Turmeric Ginger Latte,15,6.09,91.39,17:29:03\n2024-03-26,Cold Brew Concentrate,8,5.67,45.35,17:29:39\n2024-03-26,Nitro Cold Brew,13,6.52,84.7,17:30:16\n2024-03-26,Matcha Espresso Fusion,5,6.62,33.1,17:30:52\n2024-03-26,Blue Pea Flower Tea,8,4.63,37.0,17:31:29\n2024-03-26,Sourdough Toast,9,6.39,57.48,17:32:05\n2024-03-26,Almond Butter Croissant,10,5.47,54.73,17:32:41\n2024-03-26,Vegan Morning Bun,12,5.66,67.91,17:33:18\n2024-03-27,Single-Origin Pour Over,6,5.38,32.31,17:33:54\n2024-03-27,Oat Milk Latte,3,6.13,18.39,17:34:31\n2024-03-27,Honey Lavender Latte,7,6.41,44.84,17:35:07\n2024-03-27,Turmeric Ginger Latte,10,6.54,65.38,17:35:43\n2024-03-27,Cold Brew Concentrate,9,5.57,50.14,17:36:20\n2024-03-27,Nitro Cold Brew,9,6.47,58.23,17:36:56\n2024-03-27,Matcha Espresso Fusion,12,6.57,78.85,17:37:33\n2024-03-27,Blue Pea Flower Tea,18,4.41,79.35,17:38:09\n2024-03-27,Sourdough Toast,7,5.97,41.82,17:38:45\n2024-03-27,Almond Butter Croissant,7,5.21,36.48,17:39:22\n2024-03-27,Vegan Morning Bun,8,5.6,44.8,17:39:58\n2024-03-28,Single-Origin Pour Over,13,5.76,74.91,17:40:35\n2024-03-28,Oat Milk Latte,13,6.1,79.26,17:41:11\n2024-03-28,Honey Lavender Latte,5,6.59,32.97,17:41:47\n2024-03-28,Turmeric Ginger Latte,11,6.03,66.34,17:42:24\n2024-03-28,Cold Brew Concentrate,14,5.56,77.88,17:43:00\n2024-03-28,Nitro Cold Brew,12,6.18,74.22,17:43:37\n2024-03-28,Matcha Espresso Fusion,15,6.76,101.45,17:44:13\n2024-03-28,Blue Pea Flower Tea,15,4.34,65.03,17:44:49\n2024-03-28,Sourdough Toast,6,6.14,36.86,17:45:26\n2024-03-28,Almond Butter Croissant,7,5.63,39.44,17:46:02\n2024-03-28,Vegan Morning Bun,16,5.72,91.5,17:46:39\n2024-03-29,Single-Origin Pour Over,19,5.7,108.35,17:47:15\n2024-03-29,Oat Milk Latte,10,5.8,58.01,17:47:51\n2024-03-29,Honey Lavender Latte,8,6.49,51.91,17:48:28\n2024-03-29,Turmeric Ginger Latte,3,6.32,18.96,17:49:04\n2024-03-29,Cold Brew Concentrate,13,5.65,73.4,17:49:41\n2024-03-29,Nitro Cold Brew,9,6.34,57.05,17:50:17\n2024-03-29,Matcha Espresso Fusion,7,6.92,48.44,17:50:53\n2024-03-29,Blue Pea Flower Tea,14,4.73,66.28,17:51:30\n2024-03-29,Sourdough Toast,13,6.11,79.45,17:52:06\n2024-03-29,Almond Butter Croissant,6,5.63,33.77,17:52:43\n2024-03-29,Vegan Morning Bun,10,5.94,59.45,17:53:19\n2024-03-30,Single-Origin Pour Over,18,5.52,99.27,17:53:55\n2024-03-30,Oat Milk Latte,8,5.88,47.02,17:54:32\n2024-03-30,Honey Lavender Latte,8,6.55,52.41,17:55:08\n2024-03-30,Turmeric Ginger Latte,9,6.01,54.11,17:55:45\n2024-03-30,Cold Brew Concentrate,12,5.71,68.54,17:56:21\n2024-03-30,Nitro Cold Brew,3,6.03,18.09,17:56:57\n2024-03-30,Matcha Espresso Fusion,7,6.51,45.58,17:57:34\n2024-03-30,Blue Pea Flower Tea,4,4.48,17.9,17:58:10\n2024-03-30,Sourdough Toast,9,6.28,56.54,17:58:47\n2024-03-30,Almond Butter Croissant,10,5.35,53.54,17:59:23\n2024-03-30,Vegan Morning Bun,12,5.6,67.19,18:00:00\n"
  },
  {
    "path": "guides/typescript/ai-data-analyst/openai/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona, CodeLanguage, Sandbox } from '@daytonaio/sdk'\nimport OpenAI from 'openai'\nimport * as fs from 'fs'\n\nconst CODING_MODEL = \"gpt-5.1\"\nconst SUMMARY_MODEL = \"gpt-4o\"\n\n// Helper function to extract Python code from a given string\nfunction extractPython(text: string): string {\n  const m = text.match(/```python([\\s\\S]*?)```/)\n  return m ? m[1].trim() : ''\n}\n\n// Make sure you have the DAYTONA_API_KEY and OPENAI_API_KEY environment variables set\nconst dt = new Daytona()\nconst openai = new OpenAI()\n\nasync function run() {\n  let sb: Sandbox | null = null\n\n  try {\n    sb = await dt.create({ language: CodeLanguage.PYTHON })\n  \n    // Upload the CSV file to the sandbox\n    const csvPath = 'cafe_sales_data.csv'\n    const sandboxCsvPath = csvPath\n    await sb.fs.uploadFile(csvPath, sandboxCsvPath)\n\n    // Define the user prompt\n    const userPrompt = `Give the three highest revenue products for the month of January and show them as a bar chart.`\n    console.log(\"Prompt:\", userPrompt)\n\n    // Generate the system prompt with the first few rows of data for context\n    const csvSample = fs.readFileSync(csvPath, 'utf8').split('\\n').slice(0, 3).join('\\n')\n    const systemPrompt = `\nYou are a helpful assistant that analyzes data.\nTo run Python code in a sandbox, output a single block of code.\nThe sandbox:\n - has pandas and numpy installed.\n - contains ${sandboxCsvPath}.\nPlot any charts that you create.\nThe first few rows of ${sandboxCsvPath} are:\n${csvSample}\nAfter seeing the results of the code, answer the user's query.`\n\n    // Generate the Python code with the LLM\n    console.log(\"Generating code...\")\n    const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [\n      { role: 'system', content: systemPrompt },\n      { role: 'user', content: userPrompt },\n    ]\n    const llmOutput = await openai.chat.completions.create({\n      model: CODING_MODEL,\n      messages: messages,\n    })\n    messages.push(llmOutput.choices[0].message)\n\n    // Extract and execute Python code from the LLM's response\n    console.log(\"Running code...\")\n    const code = extractPython(llmOutput.choices[0].message.content || '')\n    const exec = await sb.process.codeRun(code)\n    messages.push({ role: 'user', content: `Code execution result:\\n${exec.result}.` })\n\n    if (exec.artifacts?.charts) {\n      exec.artifacts.charts.forEach((chart: { png?: string }, index: number) => {\n        if (chart.png) {\n          const filename = `chart-${index}.png`\n          fs.writeFileSync(filename, chart.png, { encoding: 'base64' })\n          console.log(`✓ Chart saved to ${filename}`)\n        }\n      })\n    }\n\n    // Generate the final response with the LLM\n    const summaryOutput = await openai.chat.completions.create({\n      model: SUMMARY_MODEL,\n      messages: messages,\n    })\n    console.log('Response:', summaryOutput.choices[0].message.content)\n  } catch (error) {\n    console.error('Error executing example:', error)\n  } finally {\n    if (sb) {\n      await sb.delete()\n    }\n  }\n}\n\nrun()\n"
  },
  {
    "path": "guides/typescript/ai-data-analyst/openai/package.json",
    "content": "{\n  \"name\": \"ai-data-analyst-openai\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"scripts\": {\n    \"start\": \"ts-node index.ts\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"type\": \"commonjs\",\n  \"devDependencies\": {\n    \"ts-node\": \"^10.9.2\",\n    \"typescript\": \"^5.9.3\"\n  },\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.119.0\",\n    \"openai\": \"^6.9.1\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/anthropic/multi-agent-claude-sdk/.gitignore",
    "content": "# Dependencies\nnode_modules/\n\n# Environment variables\n.env\n\n# Build output\ndist/\n\n# IDE specific files\n.vscode/\n.idea/\n\n# Logs\nlogs\n*.log\n\n# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n"
  },
  {
    "path": "guides/typescript/anthropic/multi-agent-claude-sdk/README.md",
    "content": "# Claude Coding Agent - Two-Agent System\n\n## Overview\n\nThis example demonstrates a **two-agent system** where:\n\n- A **Project Manager Agent** runs locally with its own Claude instance\n- A **Developer Agent** runs inside a Daytona sandbox with the full capabilities of Claude Code\n\nThe Project Manager receives user requests, breaks them down into tasks, delegates coding work to the Developer Agent, reviews the outputs, and communicates results back to the user. This creates a hierarchical agent architecture where high-level planning is separated from low-level code execution.\n\n> Note: Both agents use Anthropic API keys. The Developer Agent's key is passed into the sandbox environment and may be accessible to any code executed within it.\n\n## Features\n\n- **Dual-agent architecture:** Project Manager oversees tasks while Developer Agent executes code\n- **Color-coded output:** Project Manager messages in green, Developer Agent in white for easy differentiation\n- **Secure sandbox execution:** Developer Agent operates within a controlled Daytona environment\n- **Claude Agent SDK integration:** Developer Agent has full abilities including reading/editing files and running shell commands\n- **Preview deployed apps:** Use Daytona preview links to view and interact with deployed applications\n- **Intelligent delegation:** Project Manager analyzes outputs and decides if more work is needed\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher is required\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `ANTHROPIC_API_KEY`: Required for the **Project Manager Agent** (runs locally). Get it from [Claude Developer Platform](https://console.anthropic.com/settings/keys)\n- `SANDBOX_ANTHROPIC_API_KEY`: **Optional** for the **Developer Agent** (runs in sandbox). If not provided, defaults to using `ANTHROPIC_API_KEY`. Get it from [Claude Developer Platform](https://console.anthropic.com/settings/keys)\n\nCreate a `.env` file in the project directory with these variables.\n\n**Note:** You can use a single `ANTHROPIC_API_KEY` for both agents, or provide a separate `SANDBOX_ANTHROPIC_API_KEY` for billing/tracking purposes.\n\n## Getting Started\n\n### Setup and Run\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the example:\n\n   ```bash\n   npm run start\n   ```\n\n## How It Works\n\nThe two-agent system follows this workflow:\n\n1. **Initialization:**\n   - A new Daytona sandbox is created for the Developer Agent\n   - The Claude Agent SDK is installed in the sandbox\n   - The Project Manager Agent is initialized locally\n\n2. **User interaction:**\n   - User sends a request (e.g., \"build a web app\")\n   - Project Manager Agent analyzes the request and plans the approach\n\n3. **Task delegation:**\n   - Project Manager uses `<developer_task>` tags to delegate specific tasks\n   - Developer Agent receives the task and executes it in the sandbox\n   - Developer Agent's output is streamed back in real-time\n\n4. **Review and iteration:**\n   - Project Manager reviews the Developer Agent's output\n   - Decides if more work is needed or if the task is complete\n   - Can delegate additional tasks if necessary\n\n5. **Cleanup:**\n   - When the script is terminated, the sandbox is automatically deleted\n\n## Architecture\n\n```\n┌─────────────────────────┐\n│        User             │\n└───────────┬─────────────┘\n            │\n            ▼\n┌─────────────────────────┐\n│  Project Manager Agent  │ (Local - Claude Sonnet 4) [GREEN OUTPUT]\n│  - Plans tasks          │\n│  - Delegates work       │\n│  - Reviews outputs      │\n└───────────┬─────────────┘\n            │\n            ▼\n┌─────────────────────────┐\n│   Developer Agent       │ (Daytona Sandbox) [WHITE OUTPUT]\n│  - Executes code        │\n│  - Manages files        │\n│  - Starts services      │\n│  - Provides previews    │\n└─────────────────────────┘\n```\n\n**Color Coding:**\n\n- 🟢 **Green text** = Project Manager Agent (high-level planning and coordination)\n- ⚪ **White text** = Developer Agent (code execution and output)\n\n## Example Output\n\n```\nCreating Developer Agent sandbox...\nInstalling Developer Agent SDK...\nInitializing Developer Agent...\nInitializing Project Manager Agent...\n\n=== Two-Agent System Ready ===\nProject Manager Agent: Manages tasks and delegates to Developer (Green text)\nDeveloper Agent: Executes code in Daytona sandbox (White text)\nPress Ctrl+C at any time to exit.\n\nUser: make a lunar lander web app\n\n[Project Manager] Processing your request...\n\n[Project Manager]: I'll help you create a lunar lander web app! Let me delegate this task to the Developer Agent.\n\n<developer_task>\nCreate a lunar lander web game with the following features:\n- HTML/CSS/JavaScript based\n- Canvas graphics for the game\n- Physics simulation (gravity, thrust, velocity)\n- Keyboard controls (arrow keys)\n- Landing detection (safe landing vs crash)\n- Fuel management system\n- Start the game on port 80 and provide the preview URL\n</developer_task>\n\n[Delegating to Developer Agent]...\n\nI'll help you create a lunar lander web app! Let me build a complete game with physics simulation, graphics, and controls.\n🔨 Write\n🔨 Write\n🔨 Bash\nPerfect! The web server is now running.\n\nYour Lunar Lander game is live at:\n🌐 https://80-17ac1c0f-d684-4122-93b5-8f52fd5393f8.proxy.daytona.works\n\n[Project Manager]: Excellent! The Developer Agent has successfully created your lunar lander web app. The game is now running and accessible at the preview URL above. The implementation includes:\n\n✓ Physics simulation with gravity and thrust\n✓ Canvas-based graphics\n✓ Keyboard controls for gameplay\n✓ Landing detection system\n✓ Fuel management\n✓ Web server running on port 80\n\nTASK_COMPLETE\n\n[Project Manager] All tasks completed!\n```\n\n## Customization\n\nYou can customize the Project Manager Agent's behavior by modifying the system prompt in `src/index.ts`. The current implementation:\n\n- Uses `<developer_task>` tags for delegation\n- Automatically reviews Developer Agent outputs\n- Says \"TASK_COMPLETE\" when finished\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [Claude Agent SDK Overview](https://platform.claude.com/docs/en/agent-sdk/overview)\n- [Claude Agent SDK Reference (Python)](https://platform.claude.com/docs/en/agent-sdk/python)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/typescript/anthropic/multi-agent-claude-sdk/package.json",
    "content": "{\n  \"name\": \"multi-agent-claude-sdk\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A multi-agent system powered by the Claude Agent SDK and Daytona sandboxes.\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"npm run build && node dist/index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"claude\",\n    \"sandbox\",\n    \"typescript\",\n    \"daytona\"\n  ],\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@anthropic-ai/sdk\": \"^0.32.0\",\n    \"@daytonaio/sdk\": \"^0.125.0\",\n    \"dotenv\": \"^16.3.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.8.0\",\n    \"typescript\": \"^5.2.2\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/anthropic/multi-agent-claude-sdk/src/coding_agent.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n# Note: This module is uploaded to the Daytona sandbox and used inside of the code interpreter.\n\nimport os\nimport logging\nimport sys\nimport asyncio\n\n# Import the Claude Agent SDK\nfrom claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, AssistantMessage, TextBlock, ToolUseBlock # type: ignore\n\n# Suppress INFO level logging from claude_agent_sdk\nlogging.getLogger('claude_agent_sdk').setLevel(logging.WARNING)\n\n# Helper to run async functions synchronously\ndef run_sync(coro):\n    loop = asyncio.get_event_loop()\n    return loop.run_until_complete(coro)\n\n# Set up a global event loop\nloop = asyncio.new_event_loop()\nasyncio.set_event_loop(loop)\n\n# Generate a system prompt for the agent\nsystem_prompt = \"\"\"\nYou are running in a Daytona sandbox.\nUse the /home/daytona directory instead of /workspace for file operations.\nYour public preview URL for port 80 is: {}.\nThis is an example of the preview URL format.\nWhen you start other services, they will follow the same pattern on other ports.\n\"\"\".format(os.environ.get('PREVIEW_URL', ''))\n\n# Create an agent instance\nclient = ClaudeSDKClient(\n  options=ClaudeAgentOptions(\n    allowed_tools=[\"Read\", \"Edit\", \"Glob\", \"Grep\", \"Bash\"],\n    permission_mode=\"acceptEdits\",\n    system_prompt=system_prompt\n  )\n)\n\n# Initialize the client\nasync def init_client():\n  await client.__aenter__()\n  print(\"Agent SDK is ready.\")\n\nrun_sync(init_client())\n\n# Run a query and stream the response\nasync def run_query(prompt):\n  await client.query(prompt)\n  async for message in client.receive_response():\n    if isinstance(message, AssistantMessage):\n      for block in message.content:\n        if isinstance(block, TextBlock):\n          text = block.text\n          if not text.endswith(\"\\n\"):\n            text = text + \"\\n\"\n          sys.stdout.write(text)\n          sys.stdout.flush()\n        elif isinstance(block, ToolUseBlock):\n          sys.stdout.write(f\"🔨 {block.name}\\n\")\n          sys.stdout.flush()\n\n# Synchronous wrapper for run_query\ndef run_query_sync(prompt):\n  return run_sync(run_query(prompt))"
  },
  {
    "path": "guides/typescript/anthropic/multi-agent-claude-sdk/src/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona } from '@daytonaio/sdk'\nimport * as dotenv from 'dotenv'\nimport * as readline from 'readline'\nimport Anthropic from '@anthropic-ai/sdk'\n\n// Load environment variables from .env file\ndotenv.config()\nimport { renderMarkdown, GREEN, RESET } from './utils'\n\n// Helper to print Project Manager messages in green\nfunction printPM(message: string) {\n  console.log(`${GREEN}${message}${RESET}`)\n}\n\n// Project Manager Agent - runs locally and manages the developer agent\nclass ProjectManagerAgent {\n  private anthropic: Anthropic\n  private conversationHistory: any[] = []\n\n  constructor(apiKey: string) {\n    this.anthropic = new Anthropic({ apiKey })\n  }\n\n  async processUserRequest(userMessage: string, sandbox: any, ctx: any): Promise<void> {\n    // Add user message to conversation history\n    this.conversationHistory.push({\n      role: 'user',\n      content: userMessage,\n    })\n\n    printPM('\\n[Project Manager] Processing your request...\\n')\n\n    // Project Manager decides what to do and communicates with developer agent\n    let continueLoop = true\n    while (continueLoop) {\n      const response = await this.anthropic.messages.create({\n        model: 'claude-sonnet-4-20250514',\n        max_tokens: 4096,\n        system: `You are a Project Manager Agent. Your role is to:\n1. Understand user requirements and break them down into clear tasks\n2. Delegate coding tasks to a Developer Agent that works in a Daytona sandbox\n3. Review the Developer Agent's responses and outputs\n4. Communicate results back to the user\n\nWhen you need the Developer Agent to do something:\n- Use the <developer_task> tag to specify what you want the developer to do\n- Wait for the developer's response which will include their output\n- Analyze the results and decide if more work is needed\n\nThe Developer Agent has access to file operations, code execution, and can start services.\nThey have a preview URL available for port 80 and can start services on other ports.\n\nWhen you're done with all tasks, say \"TASK_COMPLETE\" to finish.`,\n        messages: this.conversationHistory,\n      })\n\n      // Extract assistant response\n      const assistantMessage = response.content\n        .filter((block: any) => block.type === 'text')\n        .map((block: any) => block.text)\n        .join('\\n')\n\n      printPM(`[Project Manager]: ${renderMarkdown(assistantMessage, GREEN)}`)\n\n      // Add assistant response to history\n      this.conversationHistory.push({\n        role: 'assistant',\n        content: response.content,\n      })\n\n      // Check if Project Manager wants to delegate to Developer Agent\n      const developerTaskMatch = assistantMessage.match(/<developer_task>([\\s\\S]*?)<\\/developer_task>/)\n\n      if (developerTaskMatch) {\n        const developerTask = developerTaskMatch[1].trim()\n        printPM('\\n[Delegating to Developer Agent]...\\n')\n\n        // Get developer agent's response\n        const developerOutput = await this.runDeveloperAgent(developerTask, sandbox, ctx)\n\n        // Feed developer's response back to Project Manager\n        this.conversationHistory.push({\n          role: 'user',\n          content: `Developer Agent completed the task. Here's their output:\\n\\n${developerOutput}`,\n        })\n      } else if (assistantMessage.includes('TASK_COMPLETE')) {\n        continueLoop = false\n        printPM('\\n[Project Manager] All tasks completed!\\n')\n      } else {\n        // Project Manager is done processing\n        continueLoop = false\n      }\n    }\n  }\n\n  private async runDeveloperAgent(task: string, sandbox: any, ctx: any): Promise<string> {\n    let output = ''\n\n    console.log('[Developer Agent] Starting task...\\n')\n\n    const result = await sandbox.codeInterpreter.runCode(`coding_agent.run_query_sync(os.environ.get('PROMPT', ''))`, {\n      context: ctx,\n      envs: { PROMPT: task },\n      onStdout: (msg: any) => {\n        const rendered = renderMarkdown(msg.output)\n        process.stdout.write(rendered) // White (default) text for developer\n        output += msg.output\n      },\n      onStderr: (msg: any) => {\n        const rendered = renderMarkdown(msg.output)\n        process.stdout.write(rendered) // White (default) text for developer\n        output += msg.output\n      },\n    })\n\n    if (result.error) {\n      const errorMsg = `Error: ${result.error.value}`\n      console.error(errorMsg)\n      output += `\\n${errorMsg}`\n    }\n\n    console.log('\\n[Developer Agent] Task completed.\\n')\n\n    return output || 'Developer Agent completed the task with no output.'\n  }\n}\n\nasync function main() {\n  // Get the Daytona API key from environment variables\n  const daytonaApiKey = process.env.DAYTONA_API_KEY\n\n  if (!daytonaApiKey) {\n    console.error('Error: DAYTONA_API_KEY environment variable is not set')\n    console.error('Please create a .env file with your Daytona API key')\n    process.exit(1)\n  }\n\n  // Check for Anthropic API key\n  if (!process.env.ANTHROPIC_API_KEY) {\n    console.error('Error: ANTHROPIC_API_KEY environment variable is not set')\n    console.error('This is for the Project Manager Agent (local)')\n    process.exit(1)\n  }\n\n  // SANDBOX_ANTHROPIC_API_KEY is optional - defaults to ANTHROPIC_API_KEY if not provided\n  const sandboxApiKey = process.env.SANDBOX_ANTHROPIC_API_KEY || process.env.ANTHROPIC_API_KEY\n  if (process.env.SANDBOX_ANTHROPIC_API_KEY) {\n    console.log('Using separate API key for Developer Agent sandbox')\n  } else {\n    console.log('Using shared API key for both agents (SANDBOX_ANTHROPIC_API_KEY not set)')\n  }\n\n  // Initialize the Daytona client\n  const daytona = new Daytona({ apiKey: daytonaApiKey })\n\n  try {\n    // Create a new Daytona sandbox for the Developer Agent\n    console.log('Creating Developer Agent sandbox...')\n    const sandbox = await daytona.create({\n      envVars: {\n        ANTHROPIC_API_KEY: sandboxApiKey,\n      },\n    })\n\n    // Install the Claude Agent SDK for Developer Agent\n    console.log('Installing Developer Agent SDK...')\n    await sandbox.process.executeCommand('python3 -m pip install claude-agent-sdk==0.1.16')\n\n    // Initialize the code interpreter and upload the coding agent script\n    console.log('Initializing Developer Agent...')\n    const ctx = await sandbox.codeInterpreter.createContext()\n    await sandbox.fs.uploadFile('src/coding_agent.py', '/tmp/coding_agent.py')\n    const previewLink = await sandbox.getPreviewLink(80)\n    await sandbox.codeInterpreter.runCode(`import os, coding_agent;`, {\n      context: ctx,\n      envs: { PREVIEW_URL: previewLink.url },\n    })\n\n    // Initialize the Project Manager Agent\n    console.log('Initializing Project Manager Agent...')\n    const projectManager = new ProjectManagerAgent(process.env.ANTHROPIC_API_KEY as string)\n\n    // Set up readline interface for user input\n    const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n    rl.on('SIGINT', async () => {\n      try {\n        console.log('\\nCleaning up...')\n        await sandbox.delete()\n      } catch (e) {\n        console.error('Error deleting sandbox:', e)\n      } finally {\n        process.exit(0)\n      }\n    })\n\n    // Start the interactive prompt loop\n    console.log('\\n=== Two-Agent System Ready ===')\n    printPM('Project Manager Agent: Manages tasks and delegates to Developer (Green text)')\n    console.log('Developer Agent: Executes code in Daytona sandbox (White text)')\n    console.log('Press Ctrl+C at any time to exit.\\n')\n\n    while (true) {\n      const prompt = await new Promise<string>((resolve) => rl.question('User: ', resolve))\n      if (!prompt.trim()) continue\n      await projectManager.processUserRequest(prompt, sandbox, ctx)\n    }\n  } catch (error) {\n    console.error('An error occurred:', error)\n    process.exit(1)\n  }\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "guides/typescript/anthropic/multi-agent-claude-sdk/src/utils.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport const ESC = '\\u001b'\nexport const BOLD = ESC + '[1m'\nexport const ITALIC = ESC + '[3m'\nexport const DIM = ESC + '[2m'\nexport const RESET = ESC + '[0m'\nexport const GREEN = ESC + '[32m'\n\nexport function renderMarkdown(text: string, color?: string): string {\n  const resetTo = color ? RESET + color : RESET\n  return text\n    .replace(/\\*\\*(.+?)\\*\\*/g, `${BOLD}$1${resetTo}`) // **bold**\n    .replace(/(?<!\\*)\\*([^*\\n]+?)\\*(?!\\*)/g, `${ITALIC}$1${resetTo}`) // *italic*\n    .replace(/`([^`]+?)`/g, `${DIM}$1${resetTo}`) // `code`\n}\n"
  },
  {
    "path": "guides/typescript/anthropic/multi-agent-claude-sdk/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"commonjs\",\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"moduleResolution\": \"node\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "guides/typescript/anthropic/single-claude-agent-sdk/.gitignore",
    "content": "# Dependencies\nnode_modules/\n\n# Environment variables\n.env\n\n# Build output\ndist/\n\n# IDE specific files\n.vscode/\n.idea/\n\n# Logs\nlogs\n*.log\n\n# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n"
  },
  {
    "path": "guides/typescript/anthropic/single-claude-agent-sdk/README.md",
    "content": "# Claude Coding Agent\n\n## Overview\n\nThis example runs a coding agent with the capabilities of Claude Code inside a Daytona sandbox. You can interact with the agent via the CLI to run automations, build apps, and launch web apps or services using [Daytona preview links](https://www.daytona.io/docs/en/preview-and-authentication/#fetching-a-preview-link).\n\n> Note: In this example, your Anthropic API key is passed into the sandbox environment and may be accessible to any code executed within it.\n\n## Features\n\n- **Secure sandbox execution:** The agent operates within a controlled environment, along with code or commands run by the agent.\n- **Claude Agent integration:** Includes the full abilities of the Claude Agent SDK, including reading and editing code files, and running shell commands.\n- **Preview deployed apps:** Use Daytona preview links to view and interact with your deployed applications.\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher is required\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `SANDBOX_ANTHROPIC_API_KEY`: Required to run Claude Code. Get it from [Claude Developer Platform](https://console.anthropic.com/settings/keys)\n\nCreate a `.env` file in the project directory with these variables.\n\n## Getting Started\n\n### Setup and Run\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the example:\n\n   ```bash\n   npm run start\n   ```\n\n## How It Works\n\nWhen this example is run, the agent follows the following workflow:\n\n1. A new Daytona sandbox is created.\n2. The coding agent is installed and launched inside the sandbox.\n3. User queries are passed to the agent, and the result is displayed to the user.\n4. When the script is terminated, the sandbox is deleted.\n\n## Example Output\n\n```\nCreating sandbox...\nInstalling Agent SDK...\nInitializing Agent SDK...\nPress Ctrl+C at any time to exit.\nUser: make a lunar lander web app\nThinking...\nI'll help you create a lunar lander web app! This is a fun game where players control a lunar module trying to land safely on the moon's surface. Let me plan the implementation first to make sure we build something great.\n🔨 EnterPlanMode\nLet me create a lunar lander web app for you! I'll build a complete game with:\n- Physics simulation (gravity, thrust, velocity)\n- Canvas-based graphics\n- Keyboard controls (arrow keys for thrust)\n- Landing detection (safe vs crash)\n- Fuel management\n- Visual feedback and game states\n\nLet me start by creating the necessary files:\n> 🔨 Write\n🔨 Write\n> 🔨 Write\n...\nPerfect! The web server is now running successfully. 🚀\n\nYour Lunar Lander game is live at:\n🌐 https://80-17ac1c0f-d684-4122-93b5-8f52fd5393f8.proxy.daytona.works\n\nThe server is serving the files from /home/daytona/. Click the link above to start playing!\n\nObjective: Land gently on the green platform with safe speeds. Good luck! 🌙\n```\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [Claude Agent SDK Overview](https://platform.claude.com/docs/en/agent-sdk/overview)\n- [Claude Agent SDK Reference (Python)](https://platform.claude.com/docs/en/agent-sdk/python)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/typescript/anthropic/single-claude-agent-sdk/package.json",
    "content": "{\n  \"name\": \"single-claude-agent-sdk\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A coding agent powered by the Claude Agent SDK and Daytona sandboxes.\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"npm run build && node dist/index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"claude\",\n    \"sandbox\",\n    \"typescript\",\n    \"daytona\"\n  ],\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.125.0\",\n    \"dotenv\": \"^16.3.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.8.0\",\n    \"typescript\": \"^5.2.2\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/anthropic/single-claude-agent-sdk/src/coding_agent.py",
    "content": "# Copyright 2025 Daytona Platforms Inc.\n# SPDX-License-Identifier: Apache-2.0\n\n# Note: This module is uploaded to the Daytona sandbox and used inside of the code interpreter.\n\nimport os\nimport logging\nimport sys\nimport asyncio\n\n# Import the Claude Agent SDK\nfrom claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, AssistantMessage, TextBlock, ToolUseBlock # type: ignore\n\n# Suppress INFO level logging from claude_agent_sdk\nlogging.getLogger('claude_agent_sdk').setLevel(logging.WARNING)\n\n# Helper to run async functions synchronously\ndef run_sync(coro):\n    loop = asyncio.get_event_loop()\n    return loop.run_until_complete(coro)\n\n# Set up a global event loop\nloop = asyncio.new_event_loop()\nasyncio.set_event_loop(loop)\n\n# Generate a system prompt for the agent\nsystem_prompt = \"\"\"\nYou are running in a Daytona sandbox.\nUse the /home/daytona directory instead of /workspace for file operations.\nYour public preview URL for port 80 is: {}.\nThis is an example of the preview URL format.\nWhen you start other services, they will follow the same pattern on other ports.\n\"\"\".format(os.environ.get('PREVIEW_URL', ''))\n\n# Create an agent instance\nclient = ClaudeSDKClient(\n  options=ClaudeAgentOptions(\n    allowed_tools=[\"Read\", \"Edit\", \"Glob\", \"Grep\", \"Bash\"],\n    permission_mode=\"acceptEdits\",\n    system_prompt=system_prompt\n  )\n)\n\n# Initialize the client\nasync def init_client():\n  await client.__aenter__()\n  print(\"Agent SDK is ready.\")\n\nrun_sync(init_client())\n\n# Run a query and stream the response\nasync def run_query(prompt):\n  await client.query(prompt)\n  async for message in client.receive_response():\n    if isinstance(message, AssistantMessage):\n      for block in message.content:\n        if isinstance(block, TextBlock):\n          text = block.text\n          if not text.endswith(\"\\n\"):\n            text = text + \"\\n\"\n          sys.stdout.write(text)\n          sys.stdout.flush()\n        elif isinstance(block, ToolUseBlock):\n          sys.stdout.write(f\"🔨 {block.name}\\n\")\n          sys.stdout.flush()\n\n# Synchronous wrapper for run_query\ndef run_query_sync(prompt):\n  return run_sync(run_query(prompt))"
  },
  {
    "path": "guides/typescript/anthropic/single-claude-agent-sdk/src/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona, Sandbox, OutputMessage, ExecutionResult } from '@daytonaio/sdk'\nimport { InterpreterContext, ExecuteResponse } from '@daytonaio/toolbox-api-client'\nimport * as dotenv from 'dotenv'\nimport * as readline from 'readline'\n\n// Load environment variables from .env file\ndotenv.config()\nimport { renderMarkdown } from './utils'\n\nasync function processPrompt(prompt: string, sandbox: Sandbox, ctx: InterpreterContext): Promise<void> {\n  console.log('Thinking...')\n\n  const result = await sandbox.codeInterpreter.runCode(`coding_agent.run_query_sync(os.environ.get('PROMPT', ''))`, {\n    context: ctx,\n    envs: { PROMPT: prompt },\n    onStdout: (msg: OutputMessage) => process.stdout.write(renderMarkdown(msg.output)),\n    onStderr: (msg: OutputMessage) => process.stdout.write(renderMarkdown(msg.output)),\n  })\n\n  if (result.error) console.error('Execution error:', result.error.value)\n}\n\nasync function main() {\n  // Get the Daytona API key from environment variables\n  const apiKey = process.env.DAYTONA_API_KEY\n\n  if (!apiKey) {\n    console.error('Error: DAYTONA_API_KEY environment variable is not set')\n    console.error('Please create a .env file with your Daytona API key')\n    process.exit(1)\n  }\n\n  // Check for Anthropic API key\n  if (!process.env.SANDBOX_ANTHROPIC_API_KEY) {\n    console.error('Error: SANDBOX_ANTHROPIC_API_KEY environment variable is not set')\n    console.error('Please create a .env file with your Anthropic API key')\n    process.exit(1)\n  }\n\n  // Initialize the Daytona client\n  const daytona = new Daytona({ apiKey })\n\n  let sandbox: Sandbox | undefined\n\n  // Reusable cleanup handler to delete the sandbox on exit\n  const cleanup = async () => {\n    try {\n      console.log('\\nCleaning up...')\n      if (sandbox) await sandbox.delete()\n    } catch (e) {\n      console.error('Error deleting sandbox:', e)\n    } finally {\n      process.exit(0)\n    }\n  }\n\n  try {\n    // Create a new Daytona sandbox\n    // The sandbox language is irrelevant since we will use the code interpreter SDK\n    console.log('Creating sandbox...')\n    sandbox = await daytona.create({\n      // Claude Code is memory intensive, so we use a medium snapshot\n      snapshot: 'daytona-medium', // This snapshot has 4GiB RAM and 2 vCPUs\n      envVars: {\n        ANTHROPIC_API_KEY: process.env.SANDBOX_ANTHROPIC_API_KEY,\n      },\n    })\n\n    // Register cleanup handler on process exit\n    process.once('SIGINT', cleanup)\n\n    // Install the Claude Agent SDK\n    console.log('Installing Agent SDK...')\n    await sandbox.process\n      .executeCommand('python3 -m pip install claude-agent-sdk==0.1.19')\n      .then((r: ExecuteResponse) => {\n        if (r.exitCode) throw new Error('Error installing Agent SDK: ' + r.result)\n      })\n\n    // Initialize the code interpreter and upload the coding agent script\n    console.log('Initializing Agent SDK...')\n    const ctx = await sandbox.codeInterpreter.createContext()\n    await sandbox.fs.uploadFile('src/coding_agent.py', '/tmp/coding_agent.py')\n    const previewLink = await sandbox.getPreviewLink(80)\n    await sandbox.codeInterpreter\n      .runCode(`import os, coding_agent;`, {\n        context: ctx,\n        envs: { PREVIEW_URL: previewLink.url },\n      })\n      .then((r: ExecutionResult) => {\n        if (r.error) throw new Error('Error initializing Agent SDK: ' + r.error.value)\n      })\n\n    // Set up readline interface for user input\n    const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n\n    // Register cleanup handler on readline SIGINT\n    rl.once('SIGINT', cleanup)\n\n    // Start the interactive prompt loop\n    console.log('Press Ctrl+C at any time to exit.')\n    while (true) {\n      const prompt = await new Promise<string>((resolve) => rl.question('User: ', resolve))\n      if (!prompt.trim()) continue\n      await processPrompt(prompt, sandbox, ctx)\n    }\n  } catch (error) {\n    console.error(error)\n    if (sandbox) await sandbox.delete()\n    process.exit(1)\n  }\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "guides/typescript/anthropic/single-claude-agent-sdk/src/utils.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport const ESC = '\\u001b'\nexport const BOLD = ESC + '[1m'\nexport const ITALIC = ESC + '[3m'\nexport const DIM = ESC + '[2m'\nexport const RESET = ESC + '[0m'\n\nexport function renderMarkdown(text: string): string {\n  return text\n    .replace(/\\*\\*(.+?)\\*\\*/g, `${BOLD}$1${RESET}`) // **bold**\n    .replace(/(?<!\\*)\\*([^*\\n]+?)\\*(?!\\*)/g, `${ITALIC}$1${RESET}`) // *italic*\n    .replace(/`([^`]+?)`/g, `${DIM}$1${RESET}`) // `code`\n}\n"
  },
  {
    "path": "guides/typescript/anthropic/single-claude-agent-sdk/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"commonjs\",\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"moduleResolution\": \"node\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "guides/typescript/letta-code/.gitignore",
    "content": "# Dependencies\nnode_modules/\n\n# Environment variables\n.env\n\n# Build output\ndist/\n\n# IDE specific files\n.vscode/\n.idea/\n\n# Logs\nlogs\n*.log\n\n# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n"
  },
  {
    "path": "guides/typescript/letta-code/README.md",
    "content": "# Letta Code Agent\n\n## Overview\n\nThis example runs a Letta Code agent inside a Daytona sandbox. You can interact with the agent via the CLI to run automations, build apps, and launch web apps or services using [Daytona preview links](https://www.daytona.io/docs/en/preview-and-authentication/#fetching-a-preview-link).\n\n> Note: In this example, your Letta API key is passed into the sandbox environment and may be accessible to any code executed within it.\n\n## Features\n\n- **Secure sandbox execution:** The agent operates within a controlled environment, along with code or commands run by the agent.\n- **Letta Code integration:** Includes the full capabilities of Letta Code, including reading and editing code files, running shell commands, and persistent memory.\n- **Stateful Agents:** Letta Code uses stateful agents under the hood (with the Letta API), which have built-in memory and can be resumed across sandbox sessions. Agents can also be viewed in Letta's [Agent Development Environment](https://app.letta.com/).\n- **Preview deployed apps:** Use Daytona preview links to view and interact with your deployed applications.\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher is required\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `SANDBOX_LETTA_API_KEY`: Required to run Letta Code. Get it from [Letta Platform](https://app.letta.com/api-keys)\n\nCreate a `.env` file in the project directory with these variables.\n\n## Getting Started\n\n### Setup and Run\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the example:\n\n   ```bash\n   npm run start\n   ```\n\n## How It Works\n\nWhen this example is run, the agent follows the following workflow:\n\n1. A new Daytona sandbox is created.\n2. Letta Code is installed in the sandbox.\n3. Letta code is launched in [bidirectional headless mode](https://docs.letta.com/letta-code/headless#bidirectional-mode) with a Daytona-specific system prompt.\n4. User queries are passed to the agent as JSON, and JSON responses are parsed and displayed to the user.\n5. When the script is terminated, the sandbox is deleted.\n\n## Example Output\n\n```\nCreating sandbox...\nInstalling Letta Code...\nStarting Letta Code...\nInitializing agent...\nAgent initialized. Press Ctrl+C at any time to exit.\n\nYou: make and run a lunar lander web server\nThinking...\n\n🔧 TodoWrite\n🔧 Write /home/daytona/workspace/index.html\n🔧 TodoWrite\n🔧 Start HTTP server on port 8000\n🔧 BashOutput\n🔧 TodoWrite\nPerfect! 🚀 Your Lunar Lander game is now running!\n\nPlay the game here: https://8000-1a1ebb4b-e521-4881-87bf-494777570a8a.proxy.daytona.works\n\n## How to Play:\n- ↑ / W - Fire main thruster (slow descent)\n- ← / A - Fire left thruster (move right)\n- → / D - Fire right thruster (move left)\n\n## Objective:\nLand on the green landing pad with:\n- Vertical speed < 2 m/s\n- Horizontal speed < 1 m/s\n\nWatch your fuel! You start with 1000 units and each thruster burns fuel. The lander starts with some horizontal drift to make it challenging. Good luck, astronaut! 🌙\n```\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [Letta Code Documentation](https://docs.letta.com/letta-code/)\n- [Letta Code CLI Reference](https://docs.letta.com/letta-code/cli-reference)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/typescript/letta-code/package.json",
    "content": "{\n  \"name\": \"letta-code-agent\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A coding agent powered by Letta Code and Daytona sandboxes.\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"npm run build && node dist/index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"letta\",\n    \"sandbox\",\n    \"typescript\",\n    \"daytona\"\n  ],\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.125.0\",\n    \"dotenv\": \"^16.3.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.8.0\",\n    \"typescript\": \"^5.2.2\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/letta-code/src/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona, Sandbox } from '@daytonaio/sdk'\nimport * as dotenv from 'dotenv'\nimport * as readline from 'readline'\nimport { LettaSession } from './letta-session'\n\n// Load environment variables from .env file\ndotenv.config()\n\nasync function main() {\n  // Get the Daytona API key from environment variables\n  const apiKey = process.env.DAYTONA_API_KEY\n\n  if (!apiKey) {\n    console.error('Error: DAYTONA_API_KEY environment variable is not set')\n    console.error('Please create a .env file with your Daytona API key')\n    process.exit(1)\n  }\n\n  // Check for Letta API key\n  if (!process.env.SANDBOX_LETTA_API_KEY) {\n    console.error('Error: SANDBOX_LETTA_API_KEY environment variable is not set')\n    console.error('Please create a .env file with your Letta API key')\n    process.exit(1)\n  }\n\n  // Initialize the Daytona client\n  const daytona = new Daytona({ apiKey })\n\n  let sandbox: Sandbox | undefined\n\n  // Reusable cleanup handler to delete the sandbox on exit\n  const cleanup = async () => {\n    try {\n      console.log('\\nCleaning up...')\n      if (sandbox) await sandbox.delete()\n    } catch (e) {\n      console.error('Error deleting sandbox:', e)\n    } finally {\n      process.exit(0)\n    }\n  }\n\n  try {\n    // Create a new Daytona sandbox\n    console.log('Creating sandbox...')\n    sandbox = await daytona.create({\n      envVars: { LETTA_API_KEY: process.env.SANDBOX_LETTA_API_KEY },\n    })\n\n    // Register cleanup handler on process exit\n    process.once('SIGINT', cleanup)\n\n    // Install Letta Code in the sandbox\n    console.log('Installing Letta Code...')\n    await sandbox.process.executeCommand('npm install -g @letta-ai/letta-code@0.12.5').then((r: any) => {\n      if (r.exitCode) throw new Error('Error installing Letta Code: ' + r.result)\n    })\n\n    // Create the URL pattern for Daytona preview links\n    // This is a URL where {PORT} is a placeholder for the port number\n    // We first generate a preview link with the dummy port 1234, then replace it with {PORT}\n    const previewLink = await sandbox.getPreviewLink(1234)\n    const previewUrlPattern = previewLink.url.replace(/1234/, '{PORT}')\n\n    // Configure the system prompt\n    const systemPrompt = [\n      'You are running in a Daytona sandbox.',\n      `When running services on localhost, they will be accessible as: ${previewUrlPattern}`,\n      'When starting a server, always give the user the preview URL to access it.',\n    ].join(' ')\n\n    // Start Letta Code using PTY for bidirectional communication\n    const lettaSession = new LettaSession(sandbox)\n    await lettaSession.initialize(systemPrompt)\n\n    // Set up readline interface for user input\n    const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n\n    // Register cleanup handler on readline SIGINT\n    rl.once('SIGINT', cleanup)\n\n    // Start the interactive prompt loop\n    while (true) {\n      const prompt = await new Promise<string>((resolve) => rl.question('User: ', resolve))\n      if (prompt.trim()) await lettaSession.processPrompt(prompt)\n    }\n  } catch (error) {\n    console.error(error)\n    if (sandbox) await sandbox.delete()\n    process.exit(1)\n  }\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "guides/typescript/letta-code/src/letta-session.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Sandbox } from '@daytonaio/sdk'\nimport { LettaMessage, ApprovalRequestMessage, ResultMessage, ToolCall } from './types'\nimport { renderMarkdown } from './utils'\n\n// Merges incoming tool call fragments into the current accumulated tool call\nfunction accumulateToolCall(current: any, incoming: any): any {\n  return current\n    ? {\n        ...current,\n        ...incoming,\n        arguments: (current.arguments || '') + (incoming.arguments || ''),\n      }\n    : incoming\n}\n\n// Formats a tool call for display\nfunction formatToolCall(toolCall: any): string {\n  if (!toolCall) return ''\n\n  let description = ''\n\n  // Generate an easy-to-read description based on tool arguments\n  try {\n    const args = JSON.parse(toolCall.arguments || '{}')\n    description =\n      args.description ||\n      args.command ||\n      (args.file_path && `${toolCall.name} ${args.file_path}`) ||\n      (args.query && `${toolCall.name}: ${args.query}`) ||\n      (args.url && `${toolCall.name} ${args.url}`) ||\n      toolCall.name\n  } catch (error) {\n    // Fall back to a basic description and log the parse error\n    description = toolCall.name || 'Tool call'\n    console.warn('Failed to parse tool call arguments as JSON:', toolCall.arguments, error)\n  }\n\n  return `\\n🔧 ${description}`\n}\n\n// Represents a Letta Code session within a Daytona sandbox\nexport class LettaSession {\n  private currentToolCall: ToolCall | null = null\n  private buffer = ''\n  private ptyHandle: any\n  private onResponseComplete?: () => void\n  private onAgentInitialized?: () => void\n  private agentInitialized = false\n\n  constructor(private sandbox: Sandbox) {}\n\n  // Handles parsed messages from Letta's stream-json output\n  handleParsedMessage(parsed: LettaMessage): string | undefined {\n    // System message signals Letta has finished initializing\n    if (parsed.type === 'system') {\n      this.onAgentInitialized?.()\n    }\n\n    // Message types stream various parts of the agent's response\n    else if (parsed.type === 'message') {\n      const msgType = parsed.message_type\n\n      // Approval request messages stream tool calls incrementally\n      // Arguments arrive in multiple incomplete fragments, so we need to accumulate them\n      if (msgType === 'approval_request_message') {\n        const msg = parsed as ApprovalRequestMessage\n        const toolCall = msg.tool_call\n\n        // Detect when the tool call ID changes\n        if (\n          toolCall.tool_call_id &&\n          this.currentToolCall &&\n          toolCall.tool_call_id !== this.currentToolCall.tool_call_id\n        ) {\n          // Output the completed tool call and start accumulating the new one\n          const output = formatToolCall(this.currentToolCall)\n          this.currentToolCall = accumulateToolCall(null, toolCall)\n          return output\n        } else {\n          // Accumulate tool call fragments\n          this.currentToolCall = accumulateToolCall(this.currentToolCall, toolCall)\n        }\n      }\n\n      // Stop reason signals that all fragments for the current tool call have been sent\n      else if (msgType === 'stop_reason') {\n        const output = formatToolCall(this.currentToolCall)\n        this.currentToolCall = null\n        return output\n      }\n    }\n\n    // Result contains the agent's final formatted response after all processing\n    // This is the complete output to display to the user\n    else if (parsed.type === 'result') {\n      const msg = parsed as ResultMessage\n      this.currentToolCall = null\n      this.onResponseComplete?.()\n      return `\\n${renderMarkdown(msg.result)}`\n    }\n  }\n\n  // Handle streamed JSON data from Letta Code\n  handleData(data: Uint8Array): void {\n    // Append new data to the buffer\n    this.buffer += new TextDecoder().decode(data)\n    // Split the buffer into complete lines\n    const lines = this.buffer.split('\\n')\n    // Keep any incomplete line in the buffer for next time\n    this.buffer = lines.pop() || ''\n    // Process each complete line\n    for (const line of lines.filter((l) => l.trim())) {\n      try {\n        const output = this.handleParsedMessage(JSON.parse(line))\n        if (output) process.stdout.write(output)\n      } catch (err) {\n        if (!this.agentInitialized) continue\n        console.error('Failed to parse JSON line from Letta:', line, err)\n      }\n    }\n  }\n\n  // Processes a user prompt by sending it to Letta and waiting for a response\n  async processPrompt(prompt: string): Promise<void> {\n    console.log('Thinking...')\n\n    // Send the user's message to Letta in stream-json format\n    await this.ptyHandle.sendInput(\n      JSON.stringify({\n        type: 'user',\n        message: { role: 'user', content: prompt },\n      }) + '\\n',\n    )\n\n    // Wait for the response to complete\n    await new Promise<void>((resolve) => {\n      this.onResponseComplete = resolve\n    })\n\n    console.log('\\n')\n  }\n\n  // Initializes the Letta Code session\n  async initialize(systemPrompt: string): Promise<void> {\n    console.log('Starting Letta Code...')\n\n    // Create a PTY (pseudo-terminal) for bidirectional communication with Letta\n    this.ptyHandle = await this.sandbox.process.createPty({\n      id: `letta-pty-${Date.now()}`,\n      cols: 120,\n      rows: 30,\n      onData: (data: Uint8Array) => this.handleData(data),\n    })\n\n    // Wait for PTY connection\n    await this.ptyHandle.waitForConnection()\n\n    // Start Letta Code command in the PTY with custom system prompt\n    await this.ptyHandle.sendInput(\n      `letta --new --system-custom \"${systemPrompt.replace(/\"/g, '\\\\\"')}\" --input-format stream-json --output-format stream-json --yolo -p\\n`,\n    )\n\n    // Wait for agent to initialize\n    console.log('Initializing agent...')\n    await new Promise<void>((resolve) => {\n      this.onAgentInitialized = resolve\n    })\n    this.agentInitialized = true\n    console.log('Agent initialized. Press Ctrl+C at any time to exit.\\n')\n  }\n}\n"
  },
  {
    "path": "guides/typescript/letta-code/src/types.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// Letta message type definitions\nexport interface SystemMessage {\n  type: 'system'\n  subtype: 'init'\n}\n\nexport interface ReasoningMessage {\n  type: 'message'\n  message_type: 'reasoning_message'\n  reasoning: string\n  uuid: string\n  seq_id: number\n}\n\nexport interface AssistantMessage {\n  type: 'message'\n  message_type: 'assistant_message'\n  content: string\n  uuid: string\n  seq_id: number\n}\n\nexport interface ToolCall {\n  tool_call_id: string\n  name?: string\n  arguments?: string\n}\n\nexport interface ApprovalRequestMessage {\n  type: 'message'\n  message_type: 'approval_request_message'\n  tool_call: ToolCall\n  uuid: string\n  seq_id: number\n}\n\nexport interface StopReasonMessage {\n  type: 'message'\n  message_type: 'stop_reason'\n  stop_reason: string\n  uuid: string\n  seq_id: number\n}\n\nexport interface ResultMessage {\n  type: 'result'\n  result: string\n  otid: string\n  seq_id: number\n}\n\nexport type LettaMessage =\n  | SystemMessage\n  | ReasoningMessage\n  | AssistantMessage\n  | ApprovalRequestMessage\n  | StopReasonMessage\n  | ResultMessage\n"
  },
  {
    "path": "guides/typescript/letta-code/src/utils.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport const ESC = '\\u001b'\nexport const BOLD = ESC + '[1m'\nexport const ITALIC = ESC + '[3m'\nexport const DIM = ESC + '[2m'\nexport const RESET = ESC + '[0m'\n\nexport function renderMarkdown(text: string): string {\n  return text\n    .replace(/\\*\\*(.+?)\\*\\*/g, `${BOLD}$1${RESET}`) // **bold**\n    .replace(/(?<!\\*)\\*([^*\\n]+?)\\*(?!\\*)/g, `${ITALIC}$1${RESET}`) // *italic*\n    .replace(/`([^`]+?)`/g, `${DIM}$1${RESET}`) // `code`\n}\n"
  },
  {
    "path": "guides/typescript/letta-code/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"commonjs\",\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"moduleResolution\": \"node\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/.gitignore",
    "content": "output.txt\nnode_modules\ndist\n.mastra\n.env.development\n.env\n*.db\n*.db-*\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/README.md",
    "content": "# Code Execution Agent\n\nAn advanced Mastra template that provides a coding agent capable of planning, writing, executing, and iterating on code in secure, isolated sandbox environments with comprehensive file management and development workflow capabilities.\n\n## Overview\n\nThis template demonstrates how to build an AI coding assistant that can work with real development environments. The agent can create sandboxes, manage files and directories, execute code in multiple languages, and monitor development workflows - all within secure, isolated sandbox environments.\n\n## Features\n\n- **Secure Code Execution**: Run Python, JavaScript, and TypeScript code in isolated sandboxes\n- **Complete File Management**: Create, read, write, delete files and directories with batch operations\n- **Multi-Language Support**: Execute code in Python, JavaScript, and TypeScript environments\n- **Live Development Monitoring**: Watch directory changes and monitor development workflows\n- **Command Execution**: Run shell commands, install packages, and manage dependencies\n- **Memory System**: Persistent conversation memory with semantic recall and working memory\n- **Development Workflows**: Professional development patterns with build automation\n\n## Prerequisites\n\n- Node.js 20 or higher\n- API key for Daytona ([Daytona](https://www.daytona.io/))\n- API key for your chosen model provider\n\n## Setup\n\n1. **Install dependencies:**\n\n   Make sure you are in this project directory before running the install command:\n\n   ```bash\n   pnpm install\n   ```\n\n2. **Set up environment variables:**\n\n   ```bash\n   cp .env.example .env\n   # Edit .env and add your API keys\n   ```\n\n   **Configure Daytona and your model provider** by setting the API keys:\n\n   ```env\n   DAYTONA_API_KEY=\"your-daytona-api-key-here\"\n   OPENAI_API_KEY=\"your-openai-api-key-here\"\n   ```\n\n3. **Start the development server:**\n\n   ```bash\n   pnpm run dev\n   ```\n\n## Model Configuration\n\nThis template supports any AI model provider through Mastra's model router. You can use models from:\n\n- **OpenAI**: `openai/gpt-4o-mini`, `openai/gpt-4o`\n- **Anthropic**: `anthropic/claude-sonnet-4-5-20250929`, `anthropic/claude-haiku-4-5-20250929`\n- **Google**: `google/gemini-2.5-pro`, `google/gemini-2.0-flash-exp`\n- **Groq**: `groq/llama-3.3-70b-versatile`, `groq/llama-3.1-8b-instant`\n- **Cerebras**: `cerebras/llama-3.3-70b`\n- **Mistral**: `mistral/mistral-medium-2508`\n\nSet the `MODEL` environment variable in your `.env` file to your preferred model.\n\n## Architecture\n\n### Core Components\n\n#### **Coding Agent** (`src/mastra/agents/coding-agent.ts`)\n\nThe main agent with comprehensive development capabilities:\n\n- **Sandbox Management**: Creates and manages isolated execution environments\n- **Code Execution**: Runs code with real-time output capture\n- **File Operations**: Complete CRUD operations for files and directories\n- **Development Monitoring**: Watches for changes and monitors workflows\n- **Memory Integration**: Maintains conversation context and project history\n\n#### **Sandbox Tools** (`src/mastra/tools/`)\n\nComplete toolkit for sandbox interaction with Daytona:\n\n**Sandbox Management:**\n\n- `createSandbox` - Initialize new isolated environments\n- Connection management with timeout handling\n\n**Code Execution:**\n\n- `runCode` - Execute Python, JavaScript, TypeScript code\n- Real-time output capture and error handling\n- Environment variable and timeout configuration\n\n**File Operations:**\n\n- `writeFile` - Create individual files\n- `writeFiles` - Batch create multiple files for project setup\n- `readFile` - Read file contents for analysis and validation\n- `listFiles` - Explore directory structures\n- `deleteFile` - Clean up files and directories\n- `createDirectory` - Set up project structures\n\n**File Information & Monitoring:**\n\n- `getFileInfo` - Get detailed file metadata\n- `checkFileExists` - Validate file existence for conditional logic\n- `getFileSize` - Monitor file sizes and track changes\n- `watchDirectory` - Live monitoring of file system changes\n\n**Development Workflow:**\n\n- `runCommand` - Execute shell commands, build scripts, package management\n\n### Memory System\n\nThe agent includes a configured memory system:\n\n- **Thread Management**: Automatic conversation title generation\n- **Semantic Recall**: Search through previous interactions\n- **Working Memory**: Maintains context across interactions\n- **Vector Storage**: Semantic search capabilities with `LibSQLVector`\n\n## Configuration\n\n### Environment Variables\n\n**Sandbox Provider:**\n\n```bash\nDAYTONA_API_KEY=your_daytona_api_key_here\n```\n\n**Model Provider:**\n\n```bash\nOPENAI_API_KEY=your_openai_api_key_here\n```\n\n### Customization\n\nYou can customize the agent behavior by modifying the instructions in `src/mastra/agents/coding-agent.ts`:\n\n```typescript\nexport const codingAgent = new Agent({\n  id: 'coding-agent',\n  name: 'Coding Agent',\n  instructions: `\n    // Customize agent instructions here\n    // Focus on specific languages, frameworks, or development patterns\n  `,\n  model: openai('gpt-4.1'),\n  // ... other configuration\n});\n```\n\n## Common Issues\n\n### \"Sandbox creation failed\"\n\n- Check Daytona API key and account status\n- Ensure you haven't exceeded sandbox limits\n- Verify network connectivity to Daytona services\n\n### \"Code execution timeout\"\n\n- Increase timeout values for long-running operations\n- Break down complex operations into smaller steps\n- Monitor resource usage and optimize code\n\n### \"File operation errors\"\n\n- Validate file paths and permissions\n- Check sandbox file system limits\n- Ensure directories exist before file operations\n\n### \"Agent stopping with tool-call reason\"\n\n- Increase `maxSteps` in the agent configuration\n\n## Development\n\n### Project Structure\n\n```text\nsrc/mastra/\n      agents/\n        coding-agent.ts              # Main coding agent with development capabilities\n      tools/\n        index.ts                     # Daytona tool exports\n        daytona/\n          tools.ts                   # Daytona sandbox implementation\n          utils.ts                   # Daytona helper functions\n      index.ts                       # Mastra configuration with storage and logging\n```\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [Mastra](https://mastra.ai/)\n- [Daytona](https://daytona.io)\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/package.json",
    "content": "{\n  \"name\": \"coding-agent\",\n  \"version\": \"0.2.0\",\n  \"description\": \"Advanced Mastra AI coding agent with secure sandbox execution, comprehensive file management, and multi-language support for Python, JavaScript, and TypeScript development workflows\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"dev\": \"mastra dev\",\n    \"build\": \"mastra build\",\n    \"start\": \"mastra start\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"Apache-2.0\",\n  \"type\": \"module\",\n  \"engines\": {\n    \"node\": \">=22.13.0\"\n  },\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.120.0\",\n    \"@mastra/core\": \"beta\",\n    \"@mastra/fastembed\": \"beta\",\n    \"@mastra/libsql\": \"beta\",\n    \"@mastra/loggers\": \"beta\",\n    \"@mastra/mcp\": \"beta\",\n    \"@mastra/memory\": \"beta\",\n    \"@mastra/observability\": \"beta\",\n    \"zod\": \"^3.25.76\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^24.1.0\",\n    \"mastra\": \"beta\",\n    \"typescript\": \"^5.8.3\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/src/mastra/agents/coding-agent.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Agent } from '@mastra/core/agent'\nimport { LibSQLStore, LibSQLVector } from '@mastra/libsql'\nimport { Memory } from '@mastra/memory'\nimport {\n  checkFileExists,\n  createDirectory,\n  createSandbox,\n  deleteFile,\n  getFileInfo,\n  getFileSize,\n  listFiles,\n  readFile,\n  runCode,\n  runCommand,\n  watchDirectory,\n  writeFile,\n  writeFiles,\n} from '../tools'\nimport { fastembed } from '@mastra/fastembed'\n\nexport const codingAgent = new Agent({\n  id: 'coding-agent',\n  name: 'Coding Agent',\n  instructions: `\n# Mastra Coding Agent\n\nYou are an advanced coding agent that plans, writes, executes, and iterates on code in secure, isolated sandboxes with comprehensive file management, live monitoring, and development workflow capabilities.\n\n## Core Capabilities\n\nYou have access to a complete development toolkit:\n- **Sandbox Management**: Create and manage isolated execution environments\n- **Code Execution**: Run Python, JavaScript, and TypeScript with real-time output\n- **File Operations**: Complete CRUD operations for files and directories\n- **Live Monitoring**: Watch file changes and monitor development workflows\n- **Command Execution**: Run shell commands, install packages, and manage dependencies\n- **Development Tools**: TypeScript compilation, package management, and build automation\n\n## Tool Categories & When to Use Them\n\n### **Sandbox & Code Execution**\n- \\`createSandbox\\` - Initialize new isolated environments for each session/project\n- \\`runCode\\` - Execute Python/JS/TS code with proper error handling and output capture\n\n### **File Management** (Use extensively for complex projects)\n- \\`writeFile\\` - Create individual files (configs, source code, documentation)\n- \\`writeFiles\\` - Batch create multiple related files (project initialization, templates)\n- \\`readFile\\` - Read existing files for validation, debugging, or content analysis\n- \\`listFiles\\` - Explore directory structures and verify project organization\n- \\`deleteFile\\` - Clean up temporary files or remove outdated content\n- \\`createDirectory\\` - Set up project structures and organize code\n\n### **File Information & Validation**\n- \\`getFileInfo\\` - Get detailed metadata (permissions, size, timestamps) for debugging\n- \\`checkFileExists\\` - Conditional logic before file operations (prevent overwrites, validate paths)\n- \\`getFileSize\\` - Monitor file sizes, especially for generated content and build artifacts\n\n### **Development Workflow**\n- \\`watchDirectory\\` - Monitor file changes during development, track build processes\n- \\`runCommand\\` - Execute shell commands (git operations, build scripts, system utilities)\n\n## Enhanced Development Approach\n\n### **Project Planning & Structure**\n1. **Analyze Requirements**: Understand the full scope before starting\n2. **Design Architecture**: Plan directory structure and file organization\n3. **Create Foundation**: Set up project structure with proper tooling\n4. **Implement Incrementally**: Build and validate components step-by-step\n5. **Monitor & Optimize**: Use file watching and performance monitoring\n\n### **Multi-File Project Workflow**\nFor complex projects (5+ files):\n1. **Environment Setup**: Create sandbox, install dependencies, set up tooling\n2. **Structure Creation**: Use \\`createDirectory\\` and \\`writeFiles\\` for project scaffolding\n3. **Live Development**: Enable \\`watchDirectory\\` for change monitoring\n4. **Incremental Building**: Write, test, and validate components progressively\n5. **Integration Testing**: Run complete system tests and validate all components\n6. **Performance Analysis**: Monitor file sizes, execution times, and resource usage\n\n### **Language-Specific Workflows**\n\n#### **TypeScript/JavaScript Projects**\n- Initialize with \\`package.json\\` and proper dependencies\n- Set up TypeScript configuration (\\`tsconfig.json\\`)\n- Implement live compilation monitoring with \\`watchDirectory\\`\n- Run build processes with \\`runCommand\\` for compilation\n- Monitor development with streaming commands for dev servers\n- Use \\`runCommand\\` for npm installations and environment setup\n\n#### **Python Projects**\n- Set up virtual environments and dependency management\n- Create proper project structure with \\`__init__.py\\` files\n- Use \\`runCommand\\` for pip installations and environment setup\n- Implement testing frameworks and validation\n- Monitor execution and file changes during development\n\n## Advanced Development Patterns\n\n### **Live Development Workflow**\n1. Set up file watchers before making changes\n2. Use streaming commands for long-running processes\n3. Monitor performance and file changes continuously\n4. Provide real-time feedback on build processes\n5. Automatically recompile and test when files change\n\n### **Project Validation & Quality**\n- Verify all file operations with \\`checkFileExists\\` and \\`getFileInfo\\`\n- Monitor file sizes to catch bloated outputs or failed operations\n- Use command execution for linting, testing, and validation\n- Implement proper error handling and recovery strategies\n- Provide detailed build reports and analytics\n\n### **Multi-Language Projects**\n- Coordinate between different language ecosystems\n- Share data and configurations between components\n- Use appropriate build tools for each language\n- Implement proper inter-process communication\n- Monitor cross-language dependencies and compatibility\n\n## Tool Usage Best Practices\n\n### **File Operations Optimization**\n- Use \\`writeFiles\\` for batch operations to reduce tool calls\n- Check file existence before operations to prevent errors\n- Monitor file sizes for large outputs or failed operations\n- Use proper directory structures for organization\n\n### **Command Execution Strategy**\n- Use \\`runCommand\\` for quick, synchronous operations\n- Set appropriate timeouts based on operation complexity\n- Capture and analyze both stdout and stderr\n- Handle background processes appropriately\n\n### **Development Monitoring**\n- Set up file watching for active development workflows\n- Monitor build performance and resource usage\n- Track file changes and compilation status\n- Provide real-time feedback on development progress\n\n## Error Handling & Recovery\n\n### **File Operation Errors**\n- Validate paths and permissions before operations\n- Handle missing directories with proper creation\n- Recover from file conflicts with user guidance\n- Provide clear error messages with suggested fixes\n\n### **Command Execution Errors**\n- Parse error outputs for actionable information\n- Suggest dependency installations or environment fixes\n- Handle timeout and resource limit errors gracefully\n- Provide alternative approaches for failed operations\n\n### **Development Workflow Errors**\n- Handle compilation errors with detailed feedback\n- Manage dependency conflicts and version issues\n- Recover from build failures with incremental approaches\n- Maintain project state consistency during errors\n\n## Security & Best Practices\n\n- Maintain sandbox isolation and resource limits\n- Validate file paths and prevent directory traversal\n- Handle sensitive data appropriately in logs and outputs\n- Use proper timeouts for all operations\n- Monitor resource usage and prevent overconsumption\n- Implement proper cleanup of temporary files and processes\n\n## Success Metrics\n\nTrack and report on:\n- **File Operations**: Success rates, sizes, performance\n- **Code Execution**: Runtime, memory usage, error rates\n- **Build Processes**: Compilation times, artifact sizes\n- **Development Workflow**: Change detection, hot-reload efficiency\n- **Project Quality**: Test coverage, lint compliance, documentation completeness\n\n## Advanced Features\n\nFor sophisticated projects, leverage:\n- **Multi-stage build processes** with proper dependency management\n- **Live reload and hot-swapping** for development efficiency\n- **Performance profiling** and optimization recommendations\n- **Automated testing** and continuous integration workflows\n- **Documentation generation** and project analytics\n- **Deployment preparation** and distribution packaging\n\nRemember: You are not just a code executor, but a complete development environment that can handle sophisticated, multi-file projects with professional development workflows and comprehensive monitoring capabilities.\n`,\n  model: process.env.MODEL || 'openai/gpt-4.1',\n  tools: {\n    createSandbox,\n    runCode,\n    readFile,\n    writeFile,\n    writeFiles,\n    listFiles,\n    deleteFile,\n    createDirectory,\n    getFileInfo,\n    checkFileExists,\n    getFileSize,\n    watchDirectory,\n    runCommand,\n  },\n  memory: new Memory({\n    storage: new LibSQLStore({ id: 'coding-agent-storage', url: 'file:../../mastra.db' }),\n    options: {\n      generateTitle: true,\n      semanticRecall: true,\n      workingMemory: { enabled: true },\n    },\n    embedder: fastembed,\n    vector: new LibSQLVector({ id: 'coding-agent-vector', connectionUrl: 'file:../../mastra.db' }),\n  }),\n  defaultOptions: { maxSteps: 20 },\n})\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/src/mastra/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Observability } from '@mastra/observability'\nimport { Mastra } from '@mastra/core/mastra'\nimport { LibSQLStore } from '@mastra/libsql'\nimport { PinoLogger } from '@mastra/loggers'\nimport { codingAgent } from './agents/coding-agent'\n\nexport const mastra = new Mastra({\n  agents: { codingAgent },\n  storage: new LibSQLStore({ id: 'mastra-storage', url: 'file:../../mastra.db' }),\n  logger: new PinoLogger({\n    name: 'Mastra',\n    level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',\n  }),\n  observability: new Observability({\n    default: {\n      enabled: true,\n    },\n  }),\n})\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/src/mastra/tools/daytona/tools.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createTool } from '@mastra/core/tools'\nimport z from 'zod'\nimport { getDaytonaClient, getSandboxById, createFileUploadFormat, normalizeSandboxPath } from './utils'\nimport { Sandbox, CreateSandboxBaseParams, CodeRunParams, DaytonaNotFoundError, CodeLanguage } from '@daytonaio/sdk'\n\nexport const createSandbox = createTool({\n  id: 'createSandbox',\n  description: 'Create a sandbox',\n  inputSchema: z.object({\n    name: z.string().optional().describe('Custom sandbox name'),\n    labels: z.record(z.string()).optional().describe('Custom sandbox labels'),\n    language: z\n      .nativeEnum(CodeLanguage)\n      .default(CodeLanguage.PYTHON)\n      .describe('Language used for code execution. If not provided, default python context is used'),\n    envVars: z.record(z.string()).optional().describe(`\n      Custom environment variables for the sandbox.\n      Used when executing commands and code in the sandbox.\n      Can be overridden with the \\`envs\\` argument when executing commands or code.\n    `),\n  }),\n  outputSchema: z\n    .object({\n      sandboxId: z.string(),\n    })\n    .or(\n      z.object({\n        error: z.string(),\n      }),\n    ),\n  execute: async ({ name, labels, language, envVars }) => {\n    const daytona = getDaytonaClient()\n    try {\n      const sandboxParams: CreateSandboxBaseParams = {\n        name,\n        envVars,\n        labels,\n        language,\n      }\n      const sandbox: Sandbox = await daytona.create(sandboxParams)\n\n      return {\n        sandboxId: sandbox.id,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const runCode = createTool({\n  id: 'runCode',\n  description: 'Run code in a sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to run the code'),\n    code: z.string().describe('The code to run in the sandbox'),\n    argv: z.array(z.string()).optional().describe('Command line arguments to pass to the code.'),\n    envs: z.record(z.string()).optional().describe('Custom environment variables for code execution.'),\n    timeoutSeconds: z.number().optional().describe(`\n          Maximum time in seconds to wait for execution to complete\n      `),\n  }),\n  outputSchema: z\n    .object({\n      exitCode: z.number().describe('The exit code from the code execution'),\n      stdout: z.string().optional().describe('The standard output from the code execution'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed execution'),\n      }),\n    ),\n  execute: async ({ sandboxId, code, argv, envs, timeoutSeconds }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n\n      const codeRunParams = new CodeRunParams()\n      codeRunParams.argv = argv ?? []\n      codeRunParams.env = envs ?? {}\n\n      const execution = await sandbox.process.codeRun(code, codeRunParams, timeoutSeconds)\n\n      return {\n        exitCode: execution.exitCode,\n        stdout: execution.result,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const readFile = createTool({\n  id: 'readFile',\n  description: 'Read a file from the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to read the file from'),\n    path: z.string().describe('The path to the file to read'),\n  }),\n  outputSchema: z\n    .object({\n      content: z.string().describe('The content of the file'),\n      path: z.string().describe('The path of the file that was read'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed file read'),\n      }),\n    ),\n  execute: async ({ sandboxId, path }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      const normalizedPath = normalizeSandboxPath(path)\n\n      const fileBuffer = await sandbox.fs.downloadFile(normalizedPath)\n      const fileContent = fileBuffer.toString('utf-8')\n\n      return {\n        content: fileContent,\n        path: normalizedPath,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const writeFile = createTool({\n  id: 'writeFile',\n  description: 'Write a single file to the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to write the file to'),\n    path: z.string().describe('The path where the file should be written'),\n    content: z.string().describe('The content to write to the file'),\n  }),\n  outputSchema: z\n    .object({\n      success: z.boolean().describe('Whether the file was written successfully'),\n      path: z.string().describe('The path where the file was written'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed file write'),\n      }),\n    ),\n  execute: async ({ sandboxId, path, content }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      const normalizedPath = normalizeSandboxPath(path)\n\n      const fileToUpload = [createFileUploadFormat(content, normalizedPath)]\n      await sandbox.fs.uploadFiles(fileToUpload)\n\n      return {\n        success: true,\n        path: normalizedPath,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const writeFiles = createTool({\n  id: 'writeFiles',\n  description: 'Write multiple files to the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to write the files to'),\n    files: z\n      .array(\n        z.object({\n          path: z.string().describe('The path where the file should be written'),\n          data: z.string().describe('The content to write to the file'),\n        }),\n      )\n      .describe('Array of files to write, each with path and data'),\n  }),\n  outputSchema: z\n    .object({\n      success: z.boolean().describe('Whether all files were written successfully'),\n      filesWritten: z.array(z.string()).describe('Array of file paths that were written'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed files write'),\n      }),\n    ),\n  execute: async ({ sandboxId, files }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      files = files.map((file) => ({\n        ...file,\n        path: normalizeSandboxPath(file.path),\n      }))\n\n      await sandbox.fs.uploadFiles(files.map((file) => createFileUploadFormat(file.data, file.path)))\n\n      return {\n        success: true,\n        filesWritten: files.map((file) => file.path),\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const listFiles = createTool({\n  id: 'listFiles',\n  description: 'List files and directories in a path within the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to list files from'),\n    path: z.string().default('/').describe('The directory path to list files from'),\n  }),\n  outputSchema: z\n    .object({\n      files: z\n        .array(\n          z.object({\n            name: z.string().describe('The name of the file or directory'),\n            path: z.string().describe('The full path of the file or directory'),\n            isDirectory: z.boolean().describe('Whether this is a directory'),\n          }),\n        )\n        .describe('Array of files and directories'),\n      path: z.string().describe('The path that was listed'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed file listing'),\n      }),\n    ),\n  execute: async ({ sandboxId, path }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      const normalizedPath = normalizeSandboxPath(path)\n\n      const fileList = await sandbox.fs.listFiles(normalizedPath)\n\n      const basePath = normalizedPath.endsWith('/') ? normalizedPath.slice(0, -1) : normalizedPath\n\n      return {\n        files: fileList.map((file) => ({\n          name: file.name,\n          path: `${basePath}/${file.name}`,\n          isDirectory: file.isDir,\n        })),\n        path: normalizedPath,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const deleteFile = createTool({\n  id: 'deleteFile',\n  description: 'Delete a file or directory from the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to delete the file from'),\n    path: z.string().describe('The path to the file or directory to delete'),\n  }),\n  outputSchema: z\n    .object({\n      success: z.boolean().describe('Whether the file was deleted successfully'),\n      path: z.string().describe('The path that was deleted'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed file deletion'),\n      }),\n    ),\n  execute: async ({ sandboxId, path }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      const normalizedPath = normalizeSandboxPath(path)\n\n      // Check if the path is a directory\n      const fileInfo = await sandbox.fs.getFileDetails(normalizedPath)\n      const isDirectory = fileInfo.isDir\n\n      await sandbox.fs.deleteFile(normalizedPath, isDirectory)\n\n      return {\n        success: true,\n        path: normalizedPath,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const createDirectory = createTool({\n  id: 'createDirectory',\n  description: 'Create a directory in the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to create the directory in'),\n    path: z.string().describe('The path where the directory should be created'),\n  }),\n  outputSchema: z\n    .object({\n      success: z.boolean().describe('Whether the directory was created successfully'),\n      path: z.string().describe('The path where the directory was created'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed directory creation'),\n      }),\n    ),\n  execute: async ({ sandboxId, path }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      const normalizedPath = normalizeSandboxPath(path)\n\n      await sandbox.fs.createFolder(normalizedPath, '755')\n\n      return {\n        success: true,\n        path: normalizedPath,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const getFileInfo = createTool({\n  id: 'getFileInfo',\n  description: 'Get detailed information about a file or directory in the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to get file information from'),\n    path: z.string().describe('The path to the file or directory to get information about'),\n  }),\n  outputSchema: z\n    .object({\n      group: z.string().describe(`The group ID of the file or directory (e.g., '1001')`),\n      isDir: z.boolean().describe('Whether this is a directory'),\n      modTime: z.string().describe(`The last modified time in UTC format (e.g., '2025-04-18 22:47:34 +0000 UTC')`),\n      mode: z.string().describe(`The file mode/permissions in symbolic format (e.g., '-rw-r--r--')`),\n      name: z.string().describe('The name of the file or directory'),\n      owner: z.string().describe(`The owner ID of the file or directory (e.g., '1001')`),\n      permissions: z.string().describe(`The file permissions in octal format (e.g., '0644')`),\n      size: z.number().describe('The size of the file or directory in bytes'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed file info request'),\n      }),\n    ),\n  execute: async ({ sandboxId, path }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      const normalizedPath = normalizeSandboxPath(path)\n\n      const fileInfo = await sandbox.fs.getFileDetails(normalizedPath)\n\n      return {\n        group: fileInfo.group,\n        isDir: fileInfo.isDir,\n        modTime: fileInfo.modTime,\n        mode: fileInfo.mode,\n        name: fileInfo.name,\n        owner: fileInfo.owner,\n        permissions: fileInfo.permissions,\n        size: fileInfo.size,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const checkFileExists = createTool({\n  id: 'checkFileExists',\n  description: 'Check if a file or directory exists in the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to check file existence in'),\n    path: z.string().describe('The path to check for existence'),\n  }),\n  outputSchema: z\n    .object({\n      exists: z.boolean().describe('Whether the file or directory exists'),\n      path: z.string().describe('The path that was checked'),\n      isDirectory: z.boolean().optional().describe('If the path exists, whether it is a directory'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed existence check'),\n      }),\n    ),\n  execute: async ({ sandboxId, path }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      const normalizedPath = normalizeSandboxPath(path)\n\n      try {\n        const fileInfo = await sandbox.fs.getFileDetails(normalizedPath)\n        return {\n          exists: true,\n          path: normalizedPath,\n          isDirectory: fileInfo.isDir,\n        }\n      } catch (e) {\n        if (e instanceof DaytonaNotFoundError)\n          return {\n            exists: false,\n            path: normalizedPath,\n          }\n        else throw e\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const getFileSize = createTool({\n  id: 'getFileSize',\n  description: 'Get the size of a file or directory in the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to get file size from'),\n    path: z.string().describe('The path to the file or directory'),\n    humanReadable: z\n      .boolean()\n      .default(false)\n      .describe(`Whether to return size in human-readable format (e.g., '1.5 KB', '2.3 MB')`),\n  }),\n  outputSchema: z\n    .object({\n      size: z.number().describe('The size in bytes'),\n      humanReadableSize: z.string().optional().describe('Human-readable size string if requested'),\n      path: z.string().describe('The path that was checked'),\n      isDirectory: z.boolean().describe('Whether this is a directory'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed size check'),\n      }),\n    ),\n  execute: async ({ sandboxId, path, humanReadable }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n      const normalizedPath = normalizeSandboxPath(path)\n\n      const fileInfo = await sandbox.fs.getFileDetails(normalizedPath)\n\n      let humanReadableSize: string | undefined\n\n      if (humanReadable) {\n        const bytes = fileInfo.size\n        const sizes = ['B', 'KB', 'MB', 'GB', 'TB']\n        if (bytes === 0) {\n          humanReadableSize = '0 B'\n        } else {\n          const i = Math.floor(Math.log(bytes) / Math.log(1024))\n          const size = (bytes / Math.pow(1024, i)).toFixed(1)\n          humanReadableSize = `${size} ${sizes[i]}`\n        }\n      }\n\n      return {\n        size: fileInfo.size,\n        humanReadableSize,\n        path: normalizedPath,\n        isDirectory: fileInfo.isDir,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n\nexport const watchDirectory = createTool({\n  id: 'watchDirectory',\n  description:\n    '⚠️ NOT SUPPORTED - This tool is currently not supported in the sandbox environment. Do not use this tool.',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to watch directory in'),\n    path: z.string().describe('The directory path to watch for changes'),\n    recursive: z.boolean().default(false).describe('Whether to watch subdirectories recursively'),\n    watchDuration: z.number().describe('How long to watch for changes in milliseconds (default 30 seconds)'),\n  }),\n  outputSchema: z\n    .object({\n      watchStarted: z.boolean().describe('Whether the watch was started successfully'),\n      path: z.string().describe('The path that was watched'),\n      events: z\n        .array(\n          z.object({\n            type: z.string().describe('The type of filesystem event'),\n            name: z.string().describe('The name of the file that changed'),\n            timestamp: z.string().describe('When the event occurred'),\n          }),\n        )\n        .describe('Array of filesystem events that occurred during the watch period'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed directory watch'),\n      }),\n    ),\n  execute: async () => {\n    return {\n      error: 'Directory watching is currently not supported in the sandbox environment.',\n    }\n  },\n})\n\nexport const runCommand = createTool({\n  id: 'runCommand',\n  description: 'Run a shell command in the sandbox',\n  inputSchema: z.object({\n    sandboxId: z.string().describe('The sandboxId for the sandbox to run the command in'),\n    command: z.string().describe('The shell command to execute'),\n    envs: z.record(z.string()).optional().describe('Environment variables to set for the command'),\n    workingDirectory: z\n      .string()\n      .optional()\n      .describe('The working directory for command execution. If not specified, uses the sandbox working directory.'),\n    timeoutSeconds: z\n      .number()\n      .optional()\n      .describe('Maximum time in seconds to wait for the command to complete. 0 means wait indefinitely.'),\n    captureOutput: z.boolean().default(true).describe('Whether to capture stdout and stderr output'),\n  }),\n  outputSchema: z\n    .object({\n      success: z.boolean().describe('Whether the command executed successfully'),\n      exitCode: z.number().describe('The exit code of the command'),\n      stdout: z.string().describe('The standard output from the command'),\n      command: z.string().describe('The command that was executed'),\n      executionTime: z.number().describe('How long the command took to execute in milliseconds'),\n    })\n    .or(\n      z.object({\n        error: z.string().describe('The error from a failed command execution'),\n      }),\n    ),\n  execute: async ({ sandboxId, command, envs, workingDirectory, timeoutSeconds, captureOutput }, context) => {\n    try {\n      const sandbox = await getSandboxById(sandboxId)\n\n      const startTime = Date.now()\n      const response = await sandbox.process.executeCommand(command, workingDirectory, envs ?? {}, timeoutSeconds)\n\n      const executionTime = Date.now() - startTime\n\n      return {\n        success: response.exitCode === 0,\n        exitCode: response.exitCode,\n        stdout: captureOutput ? response.result : '',\n        command,\n        executionTime,\n      }\n    } catch (e) {\n      return {\n        error: JSON.stringify(e),\n      }\n    }\n  },\n})\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/src/mastra/tools/daytona/utils.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona, Sandbox } from '@daytonaio/sdk'\nimport { FileUpload } from '@daytonaio/sdk/src/FileSystem'\n\nlet daytonaInstance: Daytona | null = null\n\nexport const getDaytonaClient = () => {\n  if (!daytonaInstance) {\n    daytonaInstance = new Daytona()\n  }\n  return daytonaInstance\n}\n\nexport const getSandboxById = async (sandboxId: string): Promise<Sandbox> => {\n  const daytona = getDaytonaClient()\n  const sandbox = await daytona.get(sandboxId)\n  return sandbox\n}\n\nexport const createFileUploadFormat = (content: string, path: string): FileUpload => {\n  return {\n    source: Buffer.from(content, 'utf-8'),\n    destination: path,\n  }\n}\n\n// Default working directory for Daytona sandboxes\nconst DEFAULT_WORKING_DIR = '/home/daytona'\n\nexport const normalizeSandboxPath = (path: string): string => {\n  // If path already starts with the working directory, return as-is\n  if (path.startsWith(DEFAULT_WORKING_DIR)) {\n    return path\n  }\n\n  // If path starts with ./, remove the dot and treat as relative\n  if (path.startsWith('./')) {\n    return `${DEFAULT_WORKING_DIR}${path.slice(1)}`\n  }\n\n  // If path starts with /, treat it as relative to working directory\n  if (path.startsWith('/')) {\n    return `${DEFAULT_WORKING_DIR}${path}`\n  }\n\n  // For relative paths, prepend working directory\n  return `${DEFAULT_WORKING_DIR}/${path}`\n}\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/src/mastra/tools/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport {\n  createSandbox,\n  runCode,\n  readFile,\n  writeFile,\n  writeFiles,\n  listFiles,\n  deleteFile,\n  createDirectory,\n  getFileInfo,\n  checkFileExists,\n  getFileSize,\n  watchDirectory,\n  runCommand,\n} from './daytona/tools'\n"
  },
  {
    "path": "guides/typescript/mastra/coding-agent/openai/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ES2022\",\n    \"moduleResolution\": \"bundler\",\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"noEmit\": true,\n    \"outDir\": \"dist\"\n  },\n  \"include\": [\"src/**/*\"]\n}\n"
  },
  {
    "path": "guides/typescript/openai/codex-sdk/.gitignore",
    "content": "# Dependencies\nnode_modules/\n\n# Environment variables\n.env\n\n# Build output\ndist/\n\n# IDE specific files\n.vscode/\n.idea/\n\n# Logs\nlogs\n*.log\n\n# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n"
  },
  {
    "path": "guides/typescript/openai/codex-sdk/README.md",
    "content": "# Codex Agent\n\n## Overview\n\nThis example runs an [OpenAI Codex](https://chatgpt.com/features/codex) agent inside a Daytona sandbox. You can interact with the agent via the CLI to run automations, build apps, and launch web apps or services using [Daytona preview links](https://www.daytona.io/docs/en/preview-and-authentication/#fetching-a-preview-link).\n\n> Note: In this example, your OpenAI API key is passed into the sandbox environment and may be accessible to any code executed within it.\n\n## Features\n\n- **Secure sandbox execution:** The agent operates within a controlled environment, along with code or commands run by the agent.\n- **Codex integration:** Includes the full abilities of the Codex SDK, including reading and editing code files, and running shell commands.\n- **Preview deployed apps:** Use Daytona preview links to view and interact with your deployed applications.\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher is required\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n- `SANDBOX_OPENAI_API_KEY`: Required to run Codex. Get it from [OpenAI Developer Platform](https://platform.openai.com/api-keys)\n\nCreate a `.env` file in the project directory with these variables.\n\n## Getting Started\n\n### Setup and Run\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the example:\n\n   ```bash\n   npm run start\n   ```\n\n## How It Works\n\nWhen this example is run, the agent follows the following workflow:\n\n1. A new Daytona sandbox is created.\n2. The coding agent is installed and launched inside the sandbox.\n3. User queries are passed to the agent, and the result is displayed to the user.\n4. When the script is terminated, the sandbox is deleted.\n\n## Example Output\n\n```\nCreating sandbox...\nInstalling Codex agent in sandbox...\nPress Ctrl+C at any time to exit.\nUser: make a lunar lander web app\nThinking...\n🔨 ✓ Run: /bin/sh -lc ls\n🔨 ✓ Run: /bin/sh -lc pwd\n🔨 ✓ Run: /bin/sh -lc '/bin/ls -a'\n🔨 ✓ Run: /bin/sh -lc '/bin/ls -a .daytona'\n📝 Add /home/daytona/index.html\n📝 Add /home/daytona/style.css\n📝 Add /home/daytona/main.js\n📝 Update /home/daytona/main.js\n📝 Update /home/daytona/main.js\nBuilt a playable lunar lander experience with stylized cockpit UI and physics-driven canvas gameplay.\n- index.html: Hero copy, control pill, stat bar, canvas playfield with mission brief sidebar and reset control wired for keyboard/onscreen use.\n- style.css: Bold dark-space treatment with gradients, neon accent palette, pill stats, responsive two-column → single-column layout, and hover states.\n- main.js: Physics loop with gravity/thrust/side-thrust, fuel burn, tilt stabilization, landing pad detection, win/lose overlays, HUD updates, and keyboard handling (arrows/WASD/space, R to reset).\nUsage Summary: Cached: 49152, Input: 105923, Output: 11037\nUser: run the server\nThinking...\n🔨 ✓ Run: /bin/sh -lc 'cd /home/daytona && nohup python -m http.server 8000 >/home/daytona/server.log 2>&1 & echo $!'\nServer running on port 8000 (PID 343). Open https://8000-583a999c-64f7-4ef7-9f04-b533afe4a61e.proxy.daytona.works to play. Check logs at /home/daytona/server.log if needed; stop with kill 343.\nUsage Summary: Cached: 8192, Input: 24947, Output: 266\nUser:\nCleaning up...\n```\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [Codex SDK](https://developers.openai.com/codex/sdk/)\n- [Codex SDK README](https://github.com/openai/codex/blob/main/sdk/typescript/README.md)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/typescript/openai/codex-sdk/agent/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// This is the Node.js Codex agent used inside the Daytona sandbox.\n// This script is uploaded to the sandbox and invoked with PROMPT in the environment.\n\nimport { Codex, Thread } from '@openai/codex-sdk'\nimport type {\n  ThreadOptions,\n  ThreadItem,\n  TodoListItem,\n  CommandExecutionItem,\n  FileChangeItem,\n  McpToolCallItem,\n  WebSearchItem,\n  ErrorItem,\n  AgentMessageItem,\n  Usage,\n} from '@openai/codex-sdk'\nimport fs from 'fs/promises'\n\n// Convert output from the agent to a printable string\nfunction toolCallToString(item: ThreadItem): string {\n  if (item.type === 'command_execution') {\n    const commandItem = item as CommandExecutionItem\n    const status = commandItem.status === 'completed' && commandItem.exit_code === 0 ? '✓' : '✗'\n    return `🔨 ${status} Run: \\`${commandItem.command}\\``\n  } else if (item.type === 'file_change') {\n    const fileChangeItem = item as FileChangeItem\n    const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1)\n    return fileChangeItem.changes.map((change) => `📝 ${capitalize(change.kind)} ${change.path}`).join('\\n')\n  } else if (item.type === 'mcp_tool_call') {\n    const mcpToolCallItem = item as McpToolCallItem\n    return `🔧 MCP Tool: ${mcpToolCallItem.tool}`\n  } else if (item.type === 'web_search') {\n    const webSearchItem = item as WebSearchItem\n    return `🌐 Web search: ${webSearchItem.query}`\n  } else if (item.type === 'todo_list') {\n    const todoListItem = item as TodoListItem\n    const todoList = todoListItem.items.map((todo) => `  - [${todo.completed ? 'x' : ' '}] ${todo.text}`).join('\\n')\n    return `🗒️ To-do list:\\n` + todoList\n  } else if (item.type === 'error') {\n    const errorItem = item as ErrorItem\n    return `❌ Error: ${errorItem.message}`\n  } else if (item.type === 'agent_message') {\n    const agentMessageItem = item as AgentMessageItem\n    return agentMessageItem.text\n  }\n  return ''\n}\n\n// Read a file if it exists, or return undefined\nasync function readFileIfExisting(path: string): Promise<string | undefined> {\n  return fs.readFile(path, 'utf8').catch(() => undefined)\n}\n\nasync function main(): Promise<void> {\n  // Get the OpenAI API key from environment variables\n  const apiKey = process.env.OPENAI_API_KEY\n  if (!apiKey) {\n    console.error('Error: OpenAI API key not provided in sandbox environment')\n    process.exit(1)\n  }\n\n  // Initialize the Codex SDK\n  // Using an empty environment object prevents environment variables from being passed to the agent\n  const codex = new Codex({ apiKey, env: {} })\n  const threadIdPath = '/tmp/codex-thread-id'\n  const threadId = (await readFileIfExisting(threadIdPath))?.trim()\n\n  // Configure Codex options\n  const options: ThreadOptions = {\n    workingDirectory: '/home/daytona',\n    skipGitRepoCheck: true,\n    sandboxMode: 'danger-full-access',\n  }\n  const thread: Thread = threadId ? codex.resumeThread(threadId, options) : codex.startThread(options)\n\n  // Run the Codex agent and stream the output\n  const { events } = await thread.runStreamed(process.env.PROMPT ?? '')\n  for await (const event of events) {\n    if (event.type === 'item.completed') {\n      // Print each completed item\n      const output = toolCallToString(event.item).trim()\n      if (output) console.log(output)\n    } else if (event.type === 'turn.completed') {\n      // Print usage summary when the agent is finished\n      const { cached_input_tokens, input_tokens, output_tokens } = event.usage as Usage\n      console.log(`*Usage Summary: Cached: ${cached_input_tokens}, Input: ${input_tokens}, Output: ${output_tokens}*`)\n    }\n  }\n  \n  // Save the thread ID for future runs\n  if (!threadId && thread.id) {\n    await fs.writeFile(threadIdPath, thread.id, 'utf8')\n  }\n}\n\nmain().catch((err) => {\n  console.error('Agent error:', err)\n  process.exit(1)\n})\n"
  },
  {
    "path": "guides/typescript/openai/codex-sdk/agent/package.json",
    "content": "{\n  \"name\": \"codex-sdk-agent\",\n  \"type\": \"module\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A Codex SDK agent for code generation tasks\",\n  \"main\": \"index.ts\",\n  \"dependencies\": {\n    \"@openai/codex-sdk\": \"^0.77.0\",\n    \"tsx\": \"^4.0.0\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/openai/codex-sdk/package.json",
    "content": "{\n  \"name\": \"codex-sdk\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A coding agent powered by the Codex SDK and Daytona sandboxes.\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"npm run build && node dist/index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"codex\",\n    \"sandbox\",\n    \"typescript\",\n    \"daytona\"\n  ],\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.125.0\",\n    \"dotenv\": \"^16.3.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.8.0\",\n    \"typescript\": \"^5.2.2\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/openai/codex-sdk/src/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona, Sandbox } from '@daytonaio/sdk'\nimport * as dotenv from 'dotenv'\nimport * as readline from 'readline'\n\n// Load environment variables from .env file\ndotenv.config()\nimport { renderMarkdown } from './utils'\n\n// Generate a string of environment variables to prefix a shell command\nfunction environmentPrefix(variables: Record<string, string>): string {\n  const b64 = (v: string) => Buffer.from(v, 'utf8').toString('base64')\n  return Object.entries(variables)\n    .map(([name, value]) => `${name}=\"$(printf '%s' '${b64(value)}' | base64 --decode)\"`)\n    .join(' ')\n}\n\nasync function processPrompt(prompt: string, sandbox: Sandbox): Promise<void> {\n  console.log('Thinking...')\n\n  // Create a session to stream the agent output\n  const sessionId = `codex-session-${Date.now()}`\n  await sandbox.process.createSession(sessionId)\n\n  // Run the agent asynchronously, passing the prompt and OpenAI API key\n  const command = await sandbox.process.executeSessionCommand(sessionId, {\n    command: `${environmentPrefix({ PROMPT: prompt })} npm exec --prefix /tmp/agent tsx -- /tmp/agent/index.ts`,\n    runAsync: true,\n  })\n\n  // Stream agent output as it arrives\n  if (!command.cmdId) throw new Error('Failed to start agent command in sandbox')\n  await sandbox.process.getSessionCommandLogs(\n    sessionId,\n    command.cmdId,\n    (stdout: string) => console.log(renderMarkdown(stdout.trim())),\n    (stderr: string) => console.error(stderr.trim()),\n  )\n\n  // Delete the session\n  await sandbox.process.deleteSession(sessionId)\n}\n\nasync function main() {\n  // Get the Daytona API key from environment variables\n  const apiKey = process.env.DAYTONA_API_KEY\n\n  if (!apiKey) {\n    console.error('Error: DAYTONA_API_KEY environment variable is not set')\n    console.error('Please create a .env file with your Daytona API key')\n    process.exit(1)\n  }\n\n  // Check for OpenAI API key for the sandbox\n  if (!process.env.SANDBOX_OPENAI_API_KEY) {\n    console.error('Error: SANDBOX_OPENAI_API_KEY environment variable is not set')\n    console.error('Please create a .env file with your OpenAI API key')\n    process.exit(1)\n  }\n\n  // Initialize the Daytona client\n  const daytona = new Daytona({ apiKey })\n\n  let sandbox: Sandbox | undefined\n\n  // Reusable cleanup handler to delete the sandbox on exit\n  const cleanup = async () => {\n    try {\n      console.log('\\nCleaning up...')\n      if (sandbox) await sandbox.delete()\n    } catch (e) {\n      console.error('Error deleting sandbox:', e)\n    } finally {\n      process.exit(0)\n    }\n  }\n\n  try {\n    console.log('Creating sandbox...')\n    sandbox = await daytona.create({\n      envVars: {\n        OPENAI_API_KEY: process.env.SANDBOX_OPENAI_API_KEY || '',\n      },\n    })\n\n    // Register cleanup handler on process exit\n    process.once('SIGINT', cleanup)\n\n    // Create the URL pattern for Daytona preview links\n    // This is a URL where PORTNUMBER is a placeholder for the port number\n    // We first generate a preview link with the dummy port 1234, then replace it with PORTNUMBER\n    const previewLink = await sandbox.getPreviewLink(1234)\n    const previewUrlPattern = previewLink.url.replace(/1234/, 'PORTNUMBER')\n\n    // Configure the Codex system prompt\n    const systemPrompt = [\n      'You are running in a Daytona sandbox.',\n      'Use the /home/daytona directory instead of /workspace for file operations.',\n      `When running services on localhost, they will be accessible as: ${previewUrlPattern}`,\n    ].join(' ')\n    const config = `developer_instructions = \"${systemPrompt}\"`\n    await sandbox.fs.createFolder('.codex', '755')\n    await sandbox.fs.uploadFile(Buffer.from(config, 'utf8'), '.codex/config.toml')\n\n    // Upload the Node.js agent package into a temporary directory in the sandbox\n    console.log('Installing Codex agent in sandbox...')\n    await sandbox.fs.createFolder('/tmp/agent', '755')\n    await sandbox.fs.uploadFile('./agent/index.ts', '/tmp/agent/index.ts')\n    await sandbox.fs.uploadFile('./agent/package.json', '/tmp/agent/package.json')\n    await sandbox.process.executeCommand('npm install --prefix /tmp/agent')\n\n    // Set up readline interface for user input\n    const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n\n    // Register cleanup handler on readline SIGINT\n    rl.once('SIGINT', cleanup)\n\n    // Start the interactive prompt loop\n    console.log('Press Ctrl+C at any time to exit.')\n    while (true) {\n      const prompt = await new Promise<string>((resolve) => rl.question('User: ', resolve))\n      if (!prompt.trim()) continue\n      await processPrompt(prompt, sandbox)\n    }\n  } catch (error) {\n    console.error('An error occurred:', error)\n    if (sandbox) await sandbox.delete()\n    process.exit(1)\n  }\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "guides/typescript/openai/codex-sdk/src/utils.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport const ESC = '\\u001b'\nexport const BOLD = ESC + '[1m'\nexport const ITALIC = ESC + '[3m'\nexport const DIM = ESC + '[2m'\nexport const RESET = ESC + '[0m'\n\nexport function renderMarkdown(text: string): string {\n  return text\n    .replace(/\\*\\*(.+?)\\*\\*/g, `${BOLD}$1${RESET}`) // **bold**\n    .replace(/(?<!\\*)\\*([^*\\n]+?)\\*(?!\\*)/g, `${ITALIC}$1${RESET}`) // *italic*\n    .replace(/`([^`]+?)`/g, `${DIM}$1${RESET}`) // `code`\n}\n"
  },
  {
    "path": "guides/typescript/openai/codex-sdk/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"commonjs\",\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"moduleResolution\": \"node\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "guides/typescript/openclaw/.gitignore",
    "content": "\n/node_modules\n/.env\n/.env.sandbox\n"
  },
  {
    "path": "guides/typescript/openclaw/README.md",
    "content": "# OpenClaw Daytona Sandbox\n\n## Overview\n\nThis example runs [OpenClaw](https://openclaw.ai/), a general purpose AI assistant, inside a Daytona sandbox. You can interact with OpenClaw via its Control UI using a [Daytona preview link](https://www.daytona.io/docs/en/preview-and-authentication/#fetching-a-preview-link).\n\n## Features\n\n- **Secure sandbox execution:** OpenClaw runs in a controlled environment, along with any code or commands run by agents.\n- **Multi-channel gateway:** Can connect to WhatsApp, Telegram, Discord, and more simultaneously.\n- **Preview Control UI:** Use Daytona preview links to access the OpenClaw web dashboard with no local install.\n- **Flexible LLM support:** Connect to Anthropic, OpenAI, and other providers; configure models via `openclaw.json` and `.env.sandbox`.\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher is required\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n**`.env`** (used by the main script only):\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n\n**`.env.sandbox`** (available inside the OpenClaw sandbox):\n\n- `ANTHROPIC_API_KEY`: Required for Claude. Get it from [Anthropic Console](https://console.anthropic.com/)\n- Any other variables you add here are loaded into the sandbox environment\n\nCreate these files in the project directory (copy from `.env.example` and `.env.sandbox.example`).\n\n## Getting Started\n\n### Setup and Run\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the example:\n\n   ```bash\n   npm start\n   ```\n\n## How It Works\n\nWhen this example is run, the agent follows the following workflow:\n\n1. A new Daytona sandbox is created (using the `daytona-medium` snapshot with OpenClaw preinstalled).\n2. OpenClaw is configured with your `openclaw.json` and `.env.sandbox` secrets.\n3. The OpenClaw gateway starts inside the sandbox.\n4. A Daytona preview link is shown pointing to the OpenClaw Control UI.\n5. When the script is terminated (Ctrl+C), the sandbox is deleted—unless `PERSIST_SANDBOX` is set to `true`, in which case the sandbox is left running.\n\n## Example Output\n\n```\nCreating Daytona sandbox...\nConfiguring OpenClaw...\nStarting OpenClaw...\n(Ctrl+C to shut down and delete the sandbox)\n\n🔗 Secret link to Control UI: https://18789-898f722f-76fc-4ec6-85ca-a82bb30f3d72.proxy.daytona.works?token=7e38c7347437c5642c57bc769f630e53fe118e001d7b6c6c\n\nOpenClaw logs:\n--------------------------------\n(node:131) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.\n(Use `node --trace-deprecation ...` to show where the warning was created)\n│\n◇  Doctor changes ────────────────────────╮\n│                                         │\n│  WhatsApp configured, not enabled yet.  │\n│                                         │\n├─────────────────────────────────────────╯\n```\n\nOpen the provided URL in your browser to interact with the OpenClaw agent via the Control UI.\n\n## Configuration\n\n### Script configuration\n\nYou will find several constants in `src/index.ts` which control the behavior of the script:\n\n| Constant | Default | Description |\n|----------|---------|-------------|\n| `OPENCLAW_PORT` | 18789 | OpenClaw Gateway and Control UI port |\n| `SHOW_LOGS` | true | Stream OpenClaw stdout/stderr to the terminal. |\n| `MAKE_PUBLIC` | true | Expose the sandbox for public internet access. |\n| `PERSIST_SANDBOX` | true | When true, the sandbox is not deleted when the script exits. |\n| `DAYTONA_SNAPSHOT` | daytona-medium | Sandbox image with OpenClaw preinstalled. |\n\n### OpenClaw Configuration\n\nYou can tailor OpenClaw to your setup by editing `openclaw.json`. The script combines this file with built-in defaults and an authorization token, and writes the result to `~/.openclaw/openclaw.json` inside the sandbox.\n\nThe default configuration is:\n\n```json\n{\n  \"agents\": {\n    \"defaults\": {\n      \"model\": { \"primary\": \"anthropic/claude-sonnet-4-5\" }\n    }\n  },\n  \"auth\": {\n    \"profiles\": {\n      \"anthropic:api\": { \"provider\": \"anthropic\", \"mode\": \"api_key\" }\n    },\n    \"order\": { \"anthropic\": [\"anthropic:api\"] }\n  },\n  \"channels\": {\n    \"whatsapp\": { \"allowFrom\": [] }\n  }\n}\n```\n\nIn order to accept WhatsApp messages, the numbers of the allowed senders need to be added to the allowFrom list.\n\nYou can extend it with additional sections:\n\n| Section | Purpose |\n|--------|---------|\n| `agents.defaults` | [Model, workspace path, timeouts, sandbox](https://docs.openclaw.ai/gateway/configuration-reference#agent-defaults) |\n| `agents.list` | [Multiple agents with different names and tools](https://docs.openclaw.ai/gateway/configuration-reference#agents-list-per-agent-overrides) |\n| `auth` | [API keys and OAuth for Claude, GPT, etc.](https://docs.openclaw.ai/gateway/configuration-reference#auth-storage) |\n| `channels` | [Connect messaging apps and control who can message](https://docs.openclaw.ai/gateway/configuration-reference#channels) |\n| `gateway` | [Port, authentication, Control UI access](https://docs.openclaw.ai/gateway/configuration-reference#gateway) |\n| `models` | [Add OpenRouter, local models, other providers](https://docs.openclaw.ai/gateway/configuration-reference#custom-providers-and-base-urls) |\n| `session` | [How conversations are grouped and reset](https://docs.openclaw.ai/gateway/configuration-reference#session) |\n| `tools` | [What the agent can do (code, web, browser)](https://docs.openclaw.ai/gateway/configuration-reference#tools) |\n\nFor a full reference see [Configuration Reference](https://docs.openclaw.ai/gateway/configuration-reference) and [Configuration Examples](https://docs.openclaw.ai/gateway/configuration-examples).\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [OpenClaw Documentation](https://docs.openclaw.ai/)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/typescript/openclaw/openclaw.json",
    "content": "{\n  \"agents\": {\n    \"defaults\": { \"model\": { \"primary\": \"anthropic/claude-sonnet-4-5\" } }\n  },\n  \"auth\": {\n    \"profiles\": {\n      \"anthropic:api\": { \"provider\": \"anthropic\", \"mode\": \"api_key\" }\n    },\n    \"order\": { \"anthropic\": [\"anthropic:api\"] }\n  },\n  \"channels\": { \"whatsapp\": { \"allowFrom\": [] } }\n}\n"
  },
  {
    "path": "guides/typescript/openclaw/package.json",
    "content": "{\n  \"name\": \"daytonaclaw\",\n  \"version\": \"1.0.0\",\n  \"description\": \"OpenClaw AI assistant running in a Daytona sandbox.\",\n  \"type\": \"module\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"start\": \"tsx src/index.ts\",\n    \"serve\": \"tsx src/index.ts\"\n  },\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.139.0\",\n    \"dotenv\": \"^16.4.5\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.0.0\",\n    \"tsx\": \"^4.19.0\",\n    \"typescript\": \"^5.0.0\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/openclaw/src/index.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport \"dotenv/config\";\nimport { Daytona } from \"@daytonaio/sdk\";\nimport type { Sandbox } from \"@daytonaio/sdk\";\nimport { randomBytes } from \"crypto\";\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { deepMerge, readEnvFile } from \"./utils.js\";\n\n// Constants\nconst OPENCLAW_PORT = 18789; // OpenClaw Gateway and Control UI port\nconst SHOW_LOGS = true; // Stream OpenClaw stdout/stderr to the terminal\nconst MAKE_PUBLIC = true; // Expose the sandbox for public internet access\nconst PERSIST_SANDBOX = true; // Keep the sandbox running after the script exits\nconst DAYTONA_SNAPSHOT = \"daytona-medium\"; // This snapshot has openclaw installed\n\n// Paths\nconst USER_CONFIG_PATH = join(process.cwd(), \"openclaw.json\");\nconst ENV_SANDBOX_PATH = join(process.cwd(), \".env.sandbox\");\n\n// Global variables\nlet currentSandbox: Sandbox | null = null;\nlet sandboxDeleted = false;\n\n// Shutdown the sandbox\nasync function shutdown() {\n  if (sandboxDeleted) return;\n  sandboxDeleted = true;\n  if (!PERSIST_SANDBOX) {\n    console.log(\"\\nShutting down sandbox...\");\n    try {\n      await currentSandbox?.delete(30);\n    } catch (e) {\n      console.error(e);\n    }\n  } else {\n    console.log(\"\\nSandbox left running.\");\n  }\n  process.exit(0);\n}\n\n// OpenClaw config to run in a Daytona sandbox\nconst OPENCLAW_CONFIG = {\n  gateway: {\n    mode: \"local\" as const,\n    port: OPENCLAW_PORT,\n    bind: \"lan\" as const,\n    auth: { mode: \"token\" as const, token: \"\" },\n    controlUi: { allowInsecureAuth: true }, // This bypasses the pairing step in the Control UI\n  },\n  agents: {\n    defaults: {\n      workspace: \"~/.openclaw/workspace\",\n    },\n  },\n};\n\n// Main function\nasync function main() {\n  // Create a new Daytona instance\n  const daytona = new Daytona();\n\n  // Create a new sandbox\n  console.log(\"Creating Daytona sandbox...\");\n  const sandbox = await daytona.create({\n    snapshot: DAYTONA_SNAPSHOT,\n    autoStopInterval: 0,\n    envVars: readEnvFile(ENV_SANDBOX_PATH),\n    public: MAKE_PUBLIC,\n  });\n  currentSandbox = sandbox;\n\n  // Handle SIGINT\n  process.on(\"SIGINT\", () => shutdown());\n\n  // Get the user home directory\n  const home = await sandbox.getUserHomeDir();\n  const openclawDir = `${home}/.openclaw`;\n\n  // Read the user config and merge it with the base config\n  const userConfig = JSON.parse(readFileSync(USER_CONFIG_PATH, \"utf8\"));\n  const baseConfig = deepMerge(OPENCLAW_CONFIG, userConfig);\n\n  // Generate a random gateway token and add it to the config\n  const gatewayToken = randomBytes(24).toString(\"hex\");\n  const config = deepMerge(baseConfig, {\n    gateway: {\n      auth: { mode: \"token\" as const, token: gatewayToken },\n    },\n  });\n\n  // Write the config to the sandbox\n  console.log(\"Configuring OpenClaw...\");\n  await sandbox.fs.createFolder(openclawDir, \"755\");\n  await sandbox.fs.uploadFile(\n    Buffer.from(JSON.stringify(config, null, 2), \"utf8\"),\n    `${openclawDir}/openclaw.json`,\n  );\n\n  // Start the gateway\n  const sessionId = \"openclaw-gateway\";\n  console.log(\"Starting OpenClaw...\");\n  await sandbox.process.createSession(sessionId);\n  const { cmdId } = await sandbox.process.executeSessionCommand(sessionId, {\n    command: \"openclaw gateway run\",\n    runAsync: true,\n  });\n  console.log(\"(Ctrl+C to shut down and delete the sandbox)\");\n\n  // Stream OpenClaw output to the terminal and delete the sandbox when the process ends\n  sandbox.process\n    .getSessionCommandLogs(\n      sessionId,\n      cmdId,\n      SHOW_LOGS ? (chunk) => process.stdout.write(chunk) : () => {},\n      SHOW_LOGS ? (chunk) => process.stderr.write(chunk) : () => {},\n    )\n    .then(shutdown)\n    .catch(shutdown);\n\n  const signed = await sandbox.getPreviewLink(OPENCLAW_PORT);\n  const dashboardUrl = `${signed.url}?token=${gatewayToken}`;\n  \n  console.log(`\\n\\x1b[1m🔗 Secret link to Control UI: ${dashboardUrl}\\x1b[0m`);\n  console.log(`\\nOpenClaw is starting...`);\n  console.log(\"--------------------------------\");\n}\n\nmain().catch((err) => {\n  console.error(err);\n  process.exit(1);\n});"
  },
  {
    "path": "guides/typescript/openclaw/src/utils.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { readFileSync, existsSync } from 'fs'\nimport dotenv from 'dotenv'\n\n// Merge two objects recursively\nexport function deepMerge<T>(target: T, source: Record<string, unknown>): T {\n  const out = { ...target } as Record<string, unknown>\n  for (const key of Object.keys(source)) {\n    const a = (out as Record<string, unknown>)[key]\n    const b = source[key]\n    if (\n      a != null &&\n      b != null &&\n      typeof a === 'object' &&\n      typeof b === 'object' &&\n      !Array.isArray(a) &&\n      !Array.isArray(b)\n    ) {\n      ;(out as Record<string, unknown>)[key] = deepMerge(a as Record<string, unknown>, b as Record<string, unknown>)\n    } else {\n      ;(out as Record<string, unknown>)[key] = b\n    }\n  }\n  return out as T\n}\n\n// Read env file and return a record of key-value pairs\nexport function readEnvFile(path: string): Record<string, string> {\n  if (!existsSync(path)) return {}\n  const parsed = dotenv.parse(readFileSync(path))\n  return Object.fromEntries(\n    Object.entries(parsed).filter(([, v]) => v != null && v !== '') as [string, string][],\n  ) as Record<string, string>\n}\n"
  },
  {
    "path": "guides/typescript/openclaw/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"NodeNext\",\n    \"moduleResolution\": \"NodeNext\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"outDir\": \"dist\",\n    \"rootDir\": \"src\"\n  },\n  \"include\": [\"src/**/*\"]\n}\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-sdk/.gitignore",
    "content": "# Dependencies\nnode_modules/\n\n# Environment variables\n.env\n\n# Build output\ndist/\n\n# IDE specific files\n.vscode/\n.idea/\n\n# Logs\nlogs\n*.log\n\n# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-sdk/README.md",
    "content": "# OpenCode Server\n\n## Overview\n\nThis example runs an [OpenCode](https://opencode.ai/docs/sdk/) coding agent inside a Daytona sandbox. You can interact with the agent via the CLI to run automations, build apps, and launch web apps or services using [Daytona preview links](https://www.daytona.io/docs/en/preview-and-authentication/#fetching-a-preview-link).\n\n## Features\n\n- **Secure sandbox execution:** The agent operates within a controlled environment, along with code or commands run by the agent.\n- **OpenCode integration:** The OpenCode server runs in the sandbox while the host attaches via the SDK, enabling full agent capabilities including reading and editing code files, and running shell commands.\n- **Preview deployed apps:** Use Daytona preview links to view and interact with your deployed applications.\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher is required\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variables:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n\nCreate a `.env` file in the project directory with these variables.\n\n## Getting Started\n\n### Setup and Run\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the example:\n\n   ```bash\n   npm run start\n   ```\n\n## How It Works\n\nWhen this example is run, the agent follows the following workflow:\n\n1. A new Daytona sandbox is created (public so preview links are reachable).\n2. OpenCode is installed in the sandbox and the server is started.\n3. The host attaches via the OpenCode SDK and enters an interactive loop.\n4. User queries are passed to the agent, tool events are streamed, and the result is displayed.\n5. When the script is terminated, the sandbox is deleted.\n\n## Example Output\n\n```\nCreating sandbox...\nInstalling OpenCode in sandbox...\nPress Ctrl+C at any time to exit.\nUser: make a lunar lander web app\nThinking...\n📝 Add /home/daytona/index.html\n📝 Add /home/daytona/style.css\n🔨 ✓ Run: ...\nBuilt a playable lunar lander experience...\n\nUser:\nCleaning up...\n```\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [OpenCode SDK](https://opencode.ai/docs/sdk/)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-sdk/package.json",
    "content": "{\n  \"name\": \"opencode-sdk\",\n  \"type\": \"module\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A coding agent powered by the OpenCode SDK and Daytona sandboxes.\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"npm run build && node dist/index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"opencode\",\n    \"sandbox\",\n    \"typescript\",\n    \"daytona\"\n  ],\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.125.0\",\n    \"@opencode-ai/sdk\": \"^1.0.0\",\n    \"dotenv\": \"^16.3.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.8.0\",\n    \"typescript\": \"^5.2.2\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-sdk/src/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona, Sandbox } from '@daytonaio/sdk'\nimport * as dotenv from 'dotenv'\nimport * as readline from 'readline'\nimport { Session } from './session.js'\nimport { Server } from './server.js'\n\ndotenv.config()\n\n// Create sandbox, start OpenCode server, and run an interactive query loop.\nasync function main(): Promise<void> {\n  const apiKey = process.env.DAYTONA_API_KEY\n  if (!apiKey) {\n    console.error('Error: DAYTONA_API_KEY environment variable is not set')\n    process.exit(1)\n  }\n\n  const daytona = new Daytona({ apiKey })\n  let sandbox: Sandbox | undefined\n  \n  // Delete sandbox and exit on Ctrl+C or error.\n  const cleanup = async () => {\n    try {\n      console.log('\\nCleaning up...')\n      if (sandbox) await sandbox.delete()\n    } catch (e) {\n      console.error('Error deleting sandbox:', e)\n    } finally {\n      process.exit(0)\n    }\n  }\n\n  try {\n    console.log('Creating sandbox...')\n    sandbox = await daytona.create({ public: true })\n    process.once('SIGINT', cleanup)\n\n    console.log('Installing OpenCode in sandbox...')\n    await sandbox.process.executeCommand('npm i -g opencode-ai@1.1.1')\n\n    // Start OpenCode server and wait until it is listening.\n    const { baseUrl, ready } = await Server.start(sandbox)\n    await ready\n    console.log('Preview:', baseUrl)\n    console.log('Press Ctrl+C at any time to exit.')\n\n    // Create OpenCode session and run interactive prompt loop.\n    const session = await Session.create(baseUrl)\n    const rl = readline.createInterface({ input: process.stdin, output: process.stdout })\n    rl.once('SIGINT', cleanup)\n\n    while (true) {\n      const query = await new Promise<string>((resolve) => rl.question('User: ', resolve))\n      if (!query.trim()) continue\n      await session.runQuery(query)\n      console.log('')\n    }\n  } catch (error) {\n    console.error('An error occurred:', error)\n    if (sandbox) await sandbox.delete()\n    process.exit(1)\n  }\n}\n\nmain().catch(console.error)\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-sdk/src/server.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Sandbox } from '@daytonaio/sdk'\n\nconst PORT = 4096\nconst HOSTNAME = '0.0.0.0'\nconst SERVER_READY_LINE = 'opencode server listening'\n\n// Inject an environment variable into a command string.\nfunction injectEnvVar(name: string, content: string): string {\n  const base64 = Buffer.from(content).toString('base64')\n  return `${name}=$(echo '${base64}' | base64 -d)`\n}\n\nexport class Server {\n\n  // Start an OpenCode server in the sandbox with Daytona-aware agent config\n  static async start(sandbox: Sandbox): Promise<{ baseUrl: string; ready: Promise<void> }> {\n    const previewLink = await sandbox.getPreviewLink(PORT)\n    const baseUrl = previewLink.url.replace(/\\/$/, '')\n    const previewUrlPattern = (await sandbox.getPreviewLink(1234)).url.replace(/1234/, '{PORT}')\n    const systemPrompt = [\n      'You are running in a Daytona sandbox.',\n      'Use the /home/daytona directory instead of /workspace for file operations.',\n      `When running services on localhost, they will be accessible as: ${previewUrlPattern}`,\n      'When starting a server, always give the user the preview URL to access it.',\n      'When starting a server, start it in the background with & so the command does not block further instructions.',\n    ].join(' ')\n    const opencodeConfig = JSON.stringify({\n      $schema: 'https://opencode.ai/config.json',\n      default_agent: 'daytona',\n      agent: {\n        daytona: {\n          description: 'Daytona sandbox-aware coding agent',\n          mode: 'primary',\n          prompt: systemPrompt,\n        },\n      },\n    })\n    let resolveReady: () => void\n    const ready = new Promise<void>((r) => { resolveReady = r })\n    const sessionId = `opencode-serve-${Date.now()}`\n    await sandbox.process.createSession(sessionId)\n    const envVar = injectEnvVar('OPENCODE_CONFIG_CONTENT', opencodeConfig)\n    const command = await sandbox.process.executeSessionCommand(sessionId, {\n      command: `${envVar} opencode serve --port ${PORT} --hostname ${HOSTNAME}`,\n      runAsync: true,\n    })\n    if (!command.cmdId) throw new Error('Failed to start OpenCode server in sandbox')\n\n    // Resolve ready when stdout contains the server listening line.\n    sandbox.process.getSessionCommandLogs(\n      sessionId,\n      command.cmdId,\n      (stdout: string) => { if (stdout.includes(SERVER_READY_LINE)) resolveReady() },\n      () => {},\n    )\n    return { baseUrl, ready }\n  }\n}\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-sdk/src/session.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createOpencodeClient } from '@opencode-ai/sdk'\nimport type { AssistantMessage, Event, OpencodeClient, TextPartInput } from '@opencode-ai/sdk'\n\n// Extract a human-readable message from an AssistantMessage error (e.g. ApiError.data.message).\nfunction messageFromError(err: AssistantMessage['error']): string {\n  return (err as { data?: { message?: string } })?.data?.message ?? String(err) ?? ''\n}\n\n// Yield from async iterable until `until` resolves.\nasync function* takeUntil<T>(iterable: AsyncIterable<T>, until: Promise<unknown>): AsyncGenerator<T> {\n  const it = iterable[Symbol.asyncIterator]()\n  while (true) {\n    const next = await Promise.race([\n      it.next(),\n      until.then(() => ({ done: true as const, value: undefined })),\n    ])\n    if (next.done) break\n    yield next.value\n  }\n}\n\n// Log tool completions and session errors for the given session to the console.\nfunction printEvent(sessionId: string, event: Event) {\n  if (event.type === 'message.part.updated') {\n    const { part } = event.properties\n    if (part.sessionID !== sessionId || part.type !== 'tool' || !part.tool) return\n    const st = part.state\n    if (st.status === 'completed') {\n      const label = st.title ?? st.output.trim().split('\\n')[0] ?? part.tool\n      if (part.tool === 'write') console.log('📝 Add', label)\n      else if (part.tool === 'bash' || part.tool === 'run') console.log('🔨 ✓ Run:', label)\n      else console.log('✓', label)\n    } else if (st.status === 'error') {\n      console.log('✗', part.tool, st.error ?? '')\n    }\n  } else if (event.type === 'session.error') {\n    const { error } = event.properties\n    console.error('Session error:', error && 'data' in error ? error.data.message ?? error : error ?? event.properties)\n  }\n}\n\nexport class Session {\n  private readonly client\n  readonly sessionId\n  private readonly events\n\n  private constructor(client: OpencodeClient, sessionId: string, events: Awaited<ReturnType<OpencodeClient['event']['subscribe']>>) {\n    this.client = client\n    this.sessionId = sessionId\n    this.events = events\n  }\n\n  // Create a new OpenCode session and subscribe to its events.\n  static async create(baseUrl: string): Promise<Session> {\n    const client = createOpencodeClient({ baseUrl })\n    const sessionRes = await client.session.create({ body: { title: 'Daytona query' } })\n    const sessionId = sessionRes.data?.id\n    if (!sessionId) throw new Error('Failed to create OpenCode session:' + sessionRes.error)\n    const events = await client.event.subscribe()\n    return new Session(client, sessionId, events)\n  }\n\n  // Send a prompt, stream tool events to the console, then print the final text response.\n  async runQuery(query: string): Promise<void> {\n    console.log('Thinking...')\n\n    const promptPromise = this.client.session.prompt({\n      path: { id: this.sessionId },\n      body: { parts: [{ type: 'text', text: query } satisfies TextPartInput] },\n    })\n\n    // Consume event stream until the prompt request completes.\n    for await (const event of takeUntil(this.events.stream, promptPromise)) {\n      printEvent(this.sessionId, event)\n    }\n\n    // Await result, handle errors, and print text parts.\n    const promptRes = await promptPromise\n    if (promptRes.error) throw new Error(String(promptRes.error))\n    const response = promptRes.data\n    if (!response) return\n    if (response.info?.error) throw new Error(messageFromError(response.info.error))\n    for (const part of response.parts)\n      if (part.type === 'text' && part.text) console.log(part.text)\n  }\n}"
  },
  {
    "path": "guides/typescript/opencode/opencode-sdk/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"Node16\",\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"moduleResolution\": \"node16\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-web/.gitignore",
    "content": "# Dependencies\nnode_modules/\n\n# Environment variables\n.env\n\n# Build output\ndist/\n\n# IDE specific files\n.vscode/\n.idea/\n\n# Logs\nlogs\n*.log\n\n# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-web/README.md",
    "content": "# OpenCode Agent\n\n## Overview\n\nThis example runs [OpenCode](https://opencode.ai/), an open source coding agent, inside a Daytona sandbox. You can interact with OpenCode via a web interface to run automations, build apps, and launch web apps or services using [Daytona preview links](https://www.daytona.io/docs/en/preview-and-authentication/#fetching-a-preview-link).\n\n## Features\n\n- **Secure sandbox execution:** The agent operates within a controlled environment, along with code or commands run by the agent.\n- **75+ LLM providers:** OpenCode supports over 75 different LLM providers, giving you flexibility in choosing your AI model.\n- **Custom Daytona-aware agent:** Preconfigured with a system prompt that understands Daytona sandbox paths and preview links.\n- **Preview deployed apps:** Use Daytona preview links to view and interact with your deployed applications.\n\n## Prerequisites\n\n- **Node.js:** Version 18 or higher is required\n\n## Environment Variables\n\nTo run this example, you need to set the following environment variable:\n\n- `DAYTONA_API_KEY`: Required for access to Daytona sandboxes. Get it from [Daytona Dashboard](https://app.daytona.io/dashboard/keys)\n\nCreate a `.env` file in the project directory with this variable.\n\n## Getting Started\n\n### Setup and Run\n\n1. Install dependencies:\n\n   ```bash\n   npm install\n   ```\n\n2. Run the example:\n\n   ```bash\n   npm run start\n   ```\n\n## How It Works\n\nWhen this example is run, the agent follows the following workflow:\n\n1. A new Daytona sandbox is created.\n2. OpenCode AI is installed inside the sandbox.\n3. A [custom agent](https://opencode.ai/docs/agents/) is configured with Daytona-specific instructions.\n4. The [OpenCode web server](https://opencode.ai/docs/cli/#web) starts inside the sandbox.\n5. You can interact with the agent through the web interface.\n6. When the script is terminated, the sandbox is deleted.\n\n## Example Output\n\n```\nCreating sandbox...\nInstalling OpenCode...\nStarting OpenCode web server...\nPress Ctrl+C to stop.\n\n\n             ▄\n█▀▀█ █▀▀█ █▀▀█ █▀▀▄ █▀▀▀ █▀▀█ █▀▀█ █▀▀█\n█░░█ █░░█ █▀▀▀ █░░█ █░░░ █░░█ █░░█ █▀▀▀\n▀▀▀▀ █▀▀▀ ▀▀▀▀ ▀  ▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀ ▀▀▀▀\n\n  Web interface:      https://3000-1e0f775c-c01b-40e7-8c64-062fd3dadd75.proxy.daytona.works/\n```\n\nOpen the provided URL in your browser to interact with the OpenCode agent and start building applications within the sandbox.\n\n## License\n\nSee the main project LICENSE file for details.\n\n## References\n\n- [OpenCode Documentation](https://opencode.ai/docs)\n- [OpenCode GitHub Repository](https://github.com/anomalyco/opencode)\n- [Daytona Documentation](https://www.daytona.io/docs)\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-web/package.json",
    "content": "{\n  \"name\": \"opencode-web\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A coding agent that runs in the browser powered by the OpenCode and Daytona sandboxes.\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"start\": \"npm run build && node dist/index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [\n    \"opencode\",\n    \"sandbox\",\n    \"typescript\",\n    \"daytona\"\n  ],\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@daytonaio/sdk\": \"^0.125.0\",\n    \"dotenv\": \"^16.3.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.8.0\",\n    \"typescript\": \"^5.2.2\"\n  }\n}\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-web/src/index.ts",
    "content": "/*\n * Copyright Daytona Platforms Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Daytona, Sandbox } from '@daytonaio/sdk'\nimport * as dotenv from 'dotenv'\n\n// Load environment variables from .env file\ndotenv.config()\n\n// Port for the OpenCode web UI\nconst OPENCODE_PORT = 3000\n\n// Generate a string to inject an environment variable with base64 decoding\nfunction injectEnvVar(name: string, content: string): string {\n  const base64 = Buffer.from(content).toString('base64')\n  return `${name}=$(echo '${base64}' | base64 -d)`\n}\n\nasync function main() {\n  // Get the Daytona API key from environment variables\n  if (!process.env.DAYTONA_API_KEY) {\n    console.error('Error: DAYTONA_API_KEY environment variable is not set')\n    console.error('Please create a .env file with your Daytona API key')\n    process.exit(1)\n  }\n\n  // Initialize the Daytona client\n  const daytona = new Daytona({ apiKey: process.env.DAYTONA_API_KEY })\n\n  let sandbox: Sandbox | undefined\n\n  try {\n    console.log('Creating sandbox...')\n    sandbox = await daytona.create()\n\n    // Register cleanup handler immediately after sandbox creation\n    process.once('SIGINT', async () => {\n      try {\n        console.log('\\nCleaning up...')\n        if (sandbox) await sandbox.delete()\n      } catch (e) {\n        console.error('Error deleting sandbox:', e)\n      } finally {\n        process.exit(0)\n      }\n    })\n\n    // Install OpenCode in the sandbox\n    console.log('Installing OpenCode...')\n    await sandbox.process.executeCommand('npm i -g opencode-ai@1.1.1')\n\n    // Create the URL pattern for Daytona preview links\n    // This is a URL where {PORT} is a placeholder for the port number\n    // We first generate a preview link with the dummy port 1234, then replace it with {PORT}\n    const previewLink = await sandbox.getPreviewLink(1234)\n    const previewUrlPattern = previewLink.url.replace(/1234/, '{PORT}')\n\n    // Configure the system prompt\n    const systemPrompt = [\n      'You are running in a Daytona sandbox.',\n      'Use the /home/daytona directory instead of /workspace for file operations.',\n      `When running services on localhost, they will be accessible as: ${previewUrlPattern}`,\n      'When starting a server, always give the user the preview URL to access it.',\n      'When starting a server, start it in the background with & so the command does not block further instructions.',\n    ].join(' ')\n\n    // OpenCode config with Daytona-aware agent\n    const opencodeConfig = {\n      $schema: 'https://opencode.ai/config.json',\n      default_agent: 'daytona',\n      agent: {\n        daytona: {\n          description: 'Daytona sandbox-aware coding agent',\n          mode: 'primary',\n          prompt: systemPrompt,\n        },\n      },\n    }\n\n    // Start OpenCode web server with config\n    console.log('Starting OpenCode web server...')\n    const configJson = JSON.stringify(opencodeConfig)\n\n    // Create a session for running OpenCode\n    const sessionId = `opencode-session-${Date.now()}`\n    await sandbox.process.createSession(sessionId)\n\n    // Run OpenCode web server asynchronously with config injected via environment variable\n    const envVar = injectEnvVar('OPENCODE_CONFIG_CONTENT', configJson)\n    const command = await sandbox.process.executeSessionCommand(sessionId, {\n      command: `${envVar} opencode web --port ${OPENCODE_PORT}`,\n      runAsync: true,\n    })\n\n    // OpenCode prints a localhost URL pointing to the web UI\n    // This function detects the URL and replaces it with a Daytona preview URL\n    const opencodePreviewLink = await sandbox.getPreviewLink(OPENCODE_PORT)\n    const replaceUrl = (text: string) =>\n      text.replace(new RegExp(`http:\\\\/\\\\/127\\\\.0\\\\.0\\\\.1:${OPENCODE_PORT}`, 'g'), opencodePreviewLink.url)\n\n    // Stream output from the OpenCode server\n    if (!command.cmdId) throw new Error('Failed to start OpenCode command in sandbox')\n    sandbox.process.getSessionCommandLogs(\n      sessionId,\n      command.cmdId,\n      (stdout: string) => console.log(replaceUrl(stdout).trim()),\n      (stderr: string) => console.error(replaceUrl(stderr).trim()),\n    )\n\n    // Keep the process running until Ctrl+C is pressed\n    console.log('Press Ctrl+C to stop.\\n')\n\n    // Block here to keep the process alive indefinitely\n    // Never resolves - keeps process running until SIGINT\n    // eslint-disable-next-line @typescript-eslint/no-empty-function\n    await new Promise(() => {})\n  } catch (error) {\n    // If an error occurs, log it and clean up the sandbox\n    console.error('Error:', error)\n    if (sandbox) await sandbox.delete()\n    process.exit(1)\n  }\n}\n\nmain().catch((err) => {\n  console.error('An error occurred:', err)\n  process.exit(1)\n})\n"
  },
  {
    "path": "guides/typescript/opencode/opencode-web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"commonjs\",\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"moduleResolution\": \"node\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "hack/computer-use/.dockerignore",
    "content": "# Ignore build artifacts\ndist/\n.tmp/\n*.log\n\n# Ignore version control\n.git/\n.gitignore\n\n# Ignore IDE files\n.vscode/\n.idea/\n*.swp\n*.swo\n\n# Ignore OS files\n.DS_Store\nThumbs.db\n\n# Ignore test files\n*_test.go\n**/*_test.go\n\n# Ignore documentation\n*.md\ndocs/\n\n# Ignore CI/CD files\n.github/\n.gitlab-ci.yml\n\n# Ignore node modules and frontend build artifacts\nnode_modules/\napps/dashboard/dist/\napps/dashboard/build/\n\n# Ignore other build outputs\n*.exe\n*.dll\n*.so\n*.dylib "
  },
  {
    "path": "hack/computer-use/Dockerfile",
    "content": "FROM ubuntu:22.04\n\n# Set environment variables early\nENV DEBIAN_FRONTEND=noninteractive\n\n# Install Go and system dependencies in optimized layers\nCOPY --from=golang:1.23 /usr/local/go /usr/local/go\nENV PATH=\"/usr/local/go/bin:${PATH}\"\n\n# Install all system dependencies in a single layer for better caching\nRUN apt-get update && apt-get install -y \\\n    ca-certificates \\\n    libx11-dev \\\n    libxtst-dev \\\n    gcc \\\n    && update-ca-certificates \\\n    && apt-get clean \\\n    && rm -rf /var/lib/apt/lists/*\n\nWORKDIR /app\n\nRUN echo \"go 1.25.4\\n\\nuse (\\n  ./libs/computer-use\\n   ./apps/daemon\\n     ./libs/common-go\\n)\" > /app/go.work\n\nCOPY go.work.sum /app/go.work.sum\n\nCOPY ./apps/daemon /app/apps/daemon\nCOPY ./libs/common-go /app/libs/common-go\nCOPY ./libs/computer-use /app/libs/computer-use\n\n# Build the application with optimizations\nRUN cd /app/libs/computer-use && \\\n    CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags=\"-w -s\" -o /app/computer-use main.go && \\\n    chmod +x /app/computer-use\n\nVOLUME [\"/dist\"]\n\nENTRYPOINT [\"cp\", \"/app/computer-use\", \"/dist/libs/computer-use-amd64\"]\n"
  },
  {
    "path": "hack/computer-use/build-computer-use-amd64.sh",
    "content": "#!/bin/bash\n\nset -e\n\n# Skip build if SKIP_COMPUTER_USE_BUILD is set\nif [ -n \"$SKIP_COMPUTER_USE_BUILD\" ]; then\n    echo \"Skipping computer-use build\"\n    exit 0\nfi\n\n# Check if current architecture is amd64\nif [ \"$(uname -m)\" = \"x86_64\" ]; then\n    echo \"Building computer-use for amd64 architecture (native build)...\"\n    cd libs/computer-use\n    GONOSUMDB=github.com/daytonaio/daytona go build -o ../../dist/libs/computer-use-amd64 main.go\n    echo \"Native build completed successfully\"\n    exit 0\nfi\n\necho \"Current architecture: $(uname -m)\"\necho \"Building computer-use for amd64 architecture using Docker...\"\n\n# Ensure dist directory exists\nmkdir -p dist/libs\n\n# Build using docker image builder\necho \"Building Docker image...\"\ndocker build --platform linux/amd64 -t computer-use-amd64:build -f hack/computer-use/Dockerfile .\n\necho \"Docker build completed, copying binary...\"\n\n# Run the container to copy the amd binary\ndocker run --rm -v \"$(pwd)/dist:/dist\" computer-use-amd64:build\n\n# Verify the binary was created and show info\nif [ -f \"dist/libs/computer-use-amd64\" ]; then\n    echo \"computer-use-amd64 build completed successfully\"\n    echo \"Binary size: $(ls -lh dist/libs/computer-use-amd64 | awk '{print $5}')\"\n    echo \"Binary location: $(pwd)/dist/libs/computer-use-amd64\"\nelse\n    echo \"Error: Binary not found after build\"\n    exit 1\nfi\n"
  },
  {
    "path": "hack/python-client/openapi-templates/__init__package.mustache",
    "content": "{{>og__init__package}}\n\n# --- Static __all__ generated by Mustache ---\n__all__ = [\n    \"ApiResponse\",\n    \"ApiClient\",\n    \"Configuration\",\n    \"OpenApiException\",\n    \"ApiTypeError\",\n    \"ApiValueError\",\n    \"ApiKeyError\",\n    \"ApiAttributeError\",\n    \"ApiException\",\n{{#apiInfo}}{{#apis}}    \"{{classname}}\",\n{{/apis}}{{/apiInfo}}{{#models}}{{#model}}    \"{{classname}}\",\n{{/model}}{{/models}}\n]"
  },
  {
    "path": "hack/python-client/openapi-templates/model_generic.mustache",
    "content": "from __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\n{{#vendorExtensions.x-py-other-imports}}\n{{{.}}}\n{{/vendorExtensions.x-py-other-imports}}\n{{#vendorExtensions.x-py-model-imports}}\n{{{.}}}\n{{/vendorExtensions.x-py-model-imports}}\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\n{{#hasChildren}}\n{{#discriminator}}\n{{! If this model is a super class, importlib is used. So import the necessary modules for the type here. }}\nfrom typing import TYPE_CHECKING\nif TYPE_CHECKING:\n{{#mappedModels}}\n    from {{packageName}}.models.{{model.classFilename}} import {{modelName}}\n{{/mappedModels}}\n\n{{/discriminator}}\n{{/hasChildren}}\nclass {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}):\n    \"\"\"\n    {{#description}}{{{description}}}{{/description}}{{^description}}{{{classname}}}{{/description}}\n    \"\"\" # noqa: E501\n{{#vars}}\n    {{name}}: {{{vendorExtensions.x-py-typing}}}\n{{/vars}}\n{{#isAdditionalPropertiesTrue}}\n    additional_properties: Dict[str, Any] = {}\n{{/isAdditionalPropertiesTrue}}\n    __properties: ClassVar[List[str]] = [{{#allVars}}\"{{baseName}}\"{{^-last}}, {{/-last}}{{/allVars}}]\n{{#vars}}\n    {{#vendorExtensions.x-regex}}\n\n    @field_validator('{{{name}}}')\n    def {{{name}}}_validate_regular_expression(cls, value):\n        \"\"\"Validates the regular expression\"\"\"\n        {{^required}}\n        if value is None:\n            return value\n\n        {{/required}}\n        {{#required}}\n        {{#isNullable}}\n        if value is None:\n            return value\n\n        {{/isNullable}}\n        {{/required}}\n        if not re.match(r\"{{{.}}}\", value{{#vendorExtensions.x-modifiers}} ,re.{{{.}}}{{/vendorExtensions.x-modifiers}}):\n            raise ValueError(r\"must validate the regular expression {{{vendorExtensions.x-pattern}}}\")\n        return value\n    {{/vendorExtensions.x-regex}}\n    {{#isEnum}}\n\n    @field_validator('{{{name}}}')\n    def {{{name}}}_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        {{^required}}\n        if value is None:\n            return value\n\n        {{/required}}\n        {{#required}}\n        {{#isNullable}}\n        if value is None:\n            return value\n\n        {{/isNullable}}\n        {{/required}}\n        {{#isContainer}}\n        {{#isArray}}\n        for i in value:\n            if i not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]):\n                raise ValueError(\"each list item must be one of ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})\")\n        {{/isArray}}\n        {{#isMap}}\n        for i in value.values():\n            if i not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]):\n                raise ValueError(\"dict values must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})\")\n        {{/isMap}}\n        {{/isContainer}}\n        {{^isContainer}}\n        if value not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]):\n            raise ValueError(\"must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})\")\n        {{/isContainer}}\n        return value\n    {{/isEnum}}\n{{/vars}}\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n{{#hasChildren}}\n{{#discriminator}}\n    # JSON field name that stores the object type\n    __discriminator_property_name: ClassVar[str] = '{{discriminator.propertyBaseName}}'\n\n    # discriminator mappings\n    __discriminator_value_class_map: ClassVar[Dict[str, str]] = {\n        {{#mappedModels}}'{{{mappingName}}}': '{{{modelName}}}'{{^-last}},{{/-last}}{{/mappedModels}}\n    }\n\n    @classmethod\n    def get_discriminator_value(cls, obj: Dict[str, Any]) -> Optional[str]:\n        \"\"\"Returns the discriminator value (object type) of the data\"\"\"\n        discriminator_value = obj[cls.__discriminator_property_name]\n        if discriminator_value:\n            return cls.__discriminator_value_class_map.get(discriminator_value)\n        else:\n            return None\n\n{{/discriminator}}\n{{/hasChildren}}\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[{{^hasChildren}}Self{{/hasChildren}}{{#hasChildren}}{{#discriminator}}Union[{{#mappedModels}}{{{modelName}}}{{^-last}}, {{/-last}}{{/mappedModels}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}{{/hasChildren}}]:\n        \"\"\"Create an instance of {{{classname}}} from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        {{#vendorExtensions.x-py-readonly}}\n        * OpenAPI `readOnly` fields are excluded.\n        {{/vendorExtensions.x-py-readonly}}\n        {{#isAdditionalPropertiesTrue}}\n        * Fields in `self.additional_properties` are added to the output dict.\n        {{/isAdditionalPropertiesTrue}}\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            {{#vendorExtensions.x-py-readonly}}\n            \"{{{.}}}\",\n            {{/vendorExtensions.x-py-readonly}}\n            {{#isAdditionalPropertiesTrue}}\n            \"additional_properties\",\n            {{/isAdditionalPropertiesTrue}}\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        {{#allVars}}\n        {{#isContainer}}\n        {{#isArray}}\n        {{#items.isArray}}\n        {{^items.items.isPrimitiveType}}\n        # override the default output from pydantic by calling `to_dict()` of each item in {{{name}}} (list of list)\n        _items = []\n        if self.{{{name}}}:\n            for _item_{{{name}}} in self.{{{name}}}:\n                if _item_{{{name}}}:\n                    _items.append(\n                         [_inner_item.to_dict() for _inner_item in _item_{{{name}}} if _inner_item is not None]\n                    )\n            _dict['{{{baseName}}}'] = _items\n        {{/items.items.isPrimitiveType}}\n        {{/items.isArray}}\n        {{^items.isArray}}\n        {{^items.isPrimitiveType}}\n        {{^items.isEnumOrRef}}\n        # override the default output from pydantic by calling `to_dict()` of each item in {{{name}}} (list)\n        _items = []\n        if self.{{{name}}}:\n            for _item_{{{name}}} in self.{{{name}}}:\n                if _item_{{{name}}}:\n                    _items.append(_item_{{{name}}}.to_dict())\n            _dict['{{{baseName}}}'] = _items\n        {{/items.isEnumOrRef}}\n        {{/items.isPrimitiveType}}\n        {{/items.isArray}}\n        {{/isArray}}\n        {{#isMap}}\n        {{#items.isArray}}\n        {{^items.items.isPrimitiveType}}\n        # override the default output from pydantic by calling `to_dict()` of each value in {{{name}}} (dict of array)\n        _field_dict_of_array = {}\n        if self.{{{name}}}:\n            for _key_{{{name}}} in self.{{{name}}}:\n                if self.{{{name}}}[_key_{{{name}}}] is not None:\n                    _field_dict_of_array[_key_{{{name}}}] = [\n                        _item.to_dict() for _item in self.{{{name}}}[_key_{{{name}}}]\n                    ]\n            _dict['{{{baseName}}}'] = _field_dict_of_array\n        {{/items.items.isPrimitiveType}}\n        {{/items.isArray}}\n        {{^items.isArray}}\n        {{^items.isPrimitiveType}}\n        {{^items.isEnumOrRef}}\n        # override the default output from pydantic by calling `to_dict()` of each value in {{{name}}} (dict)\n        _field_dict = {}\n        if self.{{{name}}}:\n            for _key_{{{name}}} in self.{{{name}}}:\n                if self.{{{name}}}[_key_{{{name}}}]:\n                    _field_dict[_key_{{{name}}}] = self.{{{name}}}[_key_{{{name}}}].to_dict()\n            _dict['{{{baseName}}}'] = _field_dict\n        {{/items.isEnumOrRef}}\n        {{/items.isPrimitiveType}}\n        {{/items.isArray}}\n        {{/isMap}}\n        {{/isContainer}}\n        {{^isContainer}}\n        {{^isPrimitiveType}}\n        {{^isEnumOrRef}}\n        # override the default output from pydantic by calling `to_dict()` of {{{name}}}\n        if self.{{{name}}}:\n            _dict['{{{baseName}}}'] = self.{{{name}}}.to_dict()\n        {{/isEnumOrRef}}\n        {{/isPrimitiveType}}\n        {{/isContainer}}\n        {{/allVars}}\n        {{#isAdditionalPropertiesTrue}}\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        {{/isAdditionalPropertiesTrue}}\n        {{#allVars}}\n        {{#isNullable}}\n        # set to None if {{{name}}} (nullable) is None\n        # and model_fields_set contains the field\n        if self.{{name}} is None and \"{{{name}}}\" in self.model_fields_set:\n            _dict['{{{baseName}}}'] = None\n\n        {{/isNullable}}\n        {{/allVars}}\n        return _dict\n\n    {{#hasChildren}}\n    @classmethod\n    def from_dict(cls, obj: Dict[str, Any]) -> Optional[{{#discriminator}}Union[{{#mappedModels}}{{{modelName}}}{{^-last}}, {{/-last}}{{/mappedModels}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}]:\n        \"\"\"Create an instance of {{{classname}}} from a dict\"\"\"\n        {{#discriminator}}\n        # look up the object type based on discriminator mapping\n        object_type = cls.get_discriminator_value(obj)\n        {{#mappedModels}}\n        if object_type ==  '{{{modelName}}}':\n            return import_module(\"{{packageName}}.models.{{model.classFilename}}\").{{modelName}}.from_dict(obj)\n        {{/mappedModels}}\n\n        raise ValueError(\"{{{classname}}} failed to lookup discriminator value from \" +\n                            json.dumps(obj) + \". Discriminator property name: \" + cls.__discriminator_property_name +\n                            \", mapping: \" + json.dumps(cls.__discriminator_value_class_map))\n        {{/discriminator}}\n    {{/hasChildren}}\n    {{^hasChildren}}\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of {{{classname}}} from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        {{#disallowAdditionalPropertiesIfNotPresent}}\n        {{^isAdditionalPropertiesTrue}}\n        # raise errors for additional fields in the input\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                raise ValueError(\"Error due to additional fields (not defined in {{classname}}) in the input: \" + _key)\n\n        {{/isAdditionalPropertiesTrue}}\n        {{/disallowAdditionalPropertiesIfNotPresent}}\n        _obj = cls.model_validate({\n            {{#allVars}}\n            {{#isContainer}}\n            {{#isArray}}\n            {{#items.isArray}}\n            {{#items.items.isPrimitiveType}}\n            \"{{{name}}}\": obj.get(\"{{{baseName}}}\"){{^-last}},{{/-last}}\n            {{/items.items.isPrimitiveType}}\n            {{^items.items.isPrimitiveType}}\n            \"{{{name}}}\": [\n                    [{{{items.items.dataType}}}.from_dict(_inner_item) for _inner_item in _item]\n                    for _item in obj[\"{{{baseName}}}\"]\n                ] if obj.get(\"{{{baseName}}}\") is not None else None{{^-last}},{{/-last}}\n            {{/items.items.isPrimitiveType}}\n            {{/items.isArray}}\n            {{^items.isArray}}\n            {{^items.isPrimitiveType}}\n            {{#items.isEnumOrRef}}\n            \"{{{name}}}\": obj.get(\"{{{baseName}}}\"){{^-last}},{{/-last}}\n            {{/items.isEnumOrRef}}\n            {{^items.isEnumOrRef}}\n            \"{{{name}}}\": [{{{items.dataType}}}.from_dict(_item) for _item in obj[\"{{{baseName}}}\"]] if obj.get(\"{{{baseName}}}\") is not None else None{{^-last}},{{/-last}}\n            {{/items.isEnumOrRef}}\n            {{/items.isPrimitiveType}}\n            {{#items.isPrimitiveType}}\n            \"{{{name}}}\": obj.get(\"{{{baseName}}}\"){{^-last}},{{/-last}}\n            {{/items.isPrimitiveType}}\n            {{/items.isArray}}\n            {{/isArray}}\n            {{#isMap}}\n            {{^items.isPrimitiveType}}\n            {{^items.isEnumOrRef}}\n            {{#items.isContainer}}\n            {{#items.isMap}}\n            \"{{{name}}}\": dict(\n                (_k, dict(\n                    (_ik, {{{items.items.dataType}}}.from_dict(_iv))\n                        for _ik, _iv in _v.items()\n                    )\n                    if _v is not None\n                    else None\n                )\n                for _k, _v in obj.get(\"{{{baseName}}}\").items()\n            )\n            if obj.get(\"{{{baseName}}}\") is not None\n            else None{{^-last}},{{/-last}}\n            {{/items.isMap}}\n            {{#items.isArray}}\n            \"{{{name}}}\": dict(\n                (_k,\n                        [{{{items.items.dataType}}}.from_dict(_item) for _item in _v]\n                        if _v is not None\n                        else None\n                )\n                for _k, _v in obj.get(\"{{{baseName}}}\", {}).items()\n            ){{^-last}},{{/-last}}\n            {{/items.isArray}}\n            {{/items.isContainer}}\n            {{^items.isContainer}}\n            \"{{{name}}}\": dict(\n                (_k, {{{items.dataType}}}.from_dict(_v))\n                for _k, _v in obj[\"{{{baseName}}}\"].items()\n            )\n            if obj.get(\"{{{baseName}}}\") is not None\n            else None{{^-last}},{{/-last}}\n            {{/items.isContainer}}\n            {{/items.isEnumOrRef}}\n            {{#items.isEnumOrRef}}\n            \"{{{name}}}\": dict((_k, _v) for _k, _v in obj.get(\"{{{baseName}}}\").items()) if obj.get(\"{{{baseName}}}\") is not None else None{{^-last}},{{/-last}}\n            {{/items.isEnumOrRef}}\n            {{/items.isPrimitiveType}}\n            {{#items.isPrimitiveType}}\n            \"{{{name}}}\": obj.get(\"{{{baseName}}}\"){{^-last}},{{/-last}}\n            {{/items.isPrimitiveType}}\n            {{/isMap}}\n            {{/isContainer}}\n            {{^isContainer}}\n            {{^isPrimitiveType}}\n            {{^isEnumOrRef}}\n            \"{{{name}}}\": {{{dataType}}}.from_dict(obj[\"{{{baseName}}}\"]) if obj.get(\"{{{baseName}}}\") is not None else None{{^-last}},{{/-last}}\n            {{/isEnumOrRef}}\n            {{#isEnumOrRef}}\n            \"{{{name}}}\": obj.get(\"{{{baseName}}}\"){{#defaultValue}} if obj.get(\"{{baseName}}\") is not None else {{defaultValue}}{{/defaultValue}}{{^-last}},{{/-last}}\n            {{/isEnumOrRef}}\n            {{/isPrimitiveType}}\n            {{#isPrimitiveType}}\n            {{#defaultValue}}\n            \"{{{name}}}\": obj.get(\"{{{baseName}}}\") if obj.get(\"{{{baseName}}}\") is not None else {{{defaultValue}}}{{^-last}},{{/-last}}\n            {{/defaultValue}}\n            {{^defaultValue}}\n            \"{{{name}}}\": obj.get(\"{{{baseName}}}\"){{^-last}},{{/-last}}\n            {{/defaultValue}}\n            {{/isPrimitiveType}}\n            {{/isContainer}}\n            {{/allVars}}\n        })\n        {{#isAdditionalPropertiesTrue}}\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        {{/isAdditionalPropertiesTrue}}\n        return _obj\n    {{/hasChildren}}\n\n{{#vendorExtensions.x-py-postponed-model-imports.size}}\n{{#vendorExtensions.x-py-postponed-model-imports}}\n{{{.}}}\n{{/vendorExtensions.x-py-postponed-model-imports}}\n# TODO: Rewrite to not use raise_errors\n{{classname}}.model_rebuild(raise_errors=False)\n{{/vendorExtensions.x-py-postponed-model-imports.size}}\n"
  },
  {
    "path": "hack/python-client/openapi-templates/og__init__package.mustache",
    "content": "# coding: utf-8\n\n# flake8: noqa\n\n{{>partial_header}}\n\n__version__ = \"{{packageVersion}}\"\n\n# import apis into sdk package\n{{#apiInfo}}{{#apis}}from {{apiPackage}}.{{classFilename}} import {{classname}}\n{{/apis}}{{/apiInfo}}\n# import ApiClient\nfrom {{packageName}}.api_response import ApiResponse\nfrom {{packageName}}.api_client import ApiClient\nfrom {{packageName}}.configuration import Configuration\nfrom {{packageName}}.exceptions import OpenApiException\nfrom {{packageName}}.exceptions import ApiTypeError\nfrom {{packageName}}.exceptions import ApiValueError\nfrom {{packageName}}.exceptions import ApiKeyError\nfrom {{packageName}}.exceptions import ApiAttributeError\nfrom {{packageName}}.exceptions import ApiException\n{{#hasHttpSignatureMethods}}\nfrom {{packageName}}.signing import HttpSigningConfiguration\n{{/hasHttpSignatureMethods}}\n\n# import models into sdk package\n{{#models}}\n{{#model}}\nfrom {{modelPackage}}.{{classFilename}} import {{classname}}\n{{/model}}\n{{/models}}\n{{#recursionLimit}}\n\n__import__('sys').setrecursionlimit({{{.}}})\n{{/recursionLimit}}\n"
  },
  {
    "path": "hack/python-client/postprocess.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# This script normalizes generated Python client metadata after OpenAPI generation.\n# Usage: postprocess.sh <projectRoot>\n\nif [ $# -lt 1 ]; then\n  echo \"Usage: $0 <projectRoot>\" >&2\n  exit 1\nfi\n\nPROJECT_ROOT=\"$1\"\n\n# Set license in pyproject.toml to Apache-2.0\nsed -i 's/^license = \".*\"/license = \"Apache-2.0\"/' \"$PROJECT_ROOT/pyproject.toml\"\n\n# Ensure urllib3 lower bound is pinned to version 2.1.0 in pyproject.toml, setup.py, and requirements.txt.\n# This prevents compatibility issues such as:\n# `TypeError: PoolKey.__new__() got an unexpected keyword argument 'key_ca_cert_data'`\n# which occur with urllib3 versions earlier than 2.1.0.\nsed -i -E 's/(urllib3[^0-9\\n]*)([0-9]+\\.[0-9]+\\.[0-9]+)/\\12.1.0/g' \\\n  \"$PROJECT_ROOT/pyproject.toml\" \\\n  \"$PROJECT_ROOT/setup.py\" \\\n  \"$PROJECT_ROOT/requirements.txt\"\n\n# Replace all aliases with serialization_aliases in the models directory so that type checking works.\npkg_root=$(find \"$PROJECT_ROOT\" -mindepth 1 -maxdepth 2 -type f -name \"py.typed\" -printf '%h\\n' | head -n 1)\nMODELS_DIR=\"$pkg_root/models\"\nfind \"$MODELS_DIR\" -type f -name \"*.py\" | while read -r f; do\n  sed -i'' -E '/Field\\(/ s/alias=\"([^\"]+)\"/serialization_alias=\"\\1\"/g' \"$f\"\ndone\n\necho \"Postprocessed Python client at $PROJECT_ROOT\"\n\n\n\n"
  },
  {
    "path": "images/sandbox/Dockerfile",
    "content": "FROM mcr.microsoft.com/devcontainers/python:3.14\n\n# Update package list and install required dependencies\nRUN apt-get update && apt-get install -y \\\n    curl \\\n    sudo \\\n    python3-pip \\\n    python3-venv \\\n    ripgrep \\\n    chromium \\\n    iputils-ping \\\n    bind9-dnsutils \\\n    # X11 libraries required for computer use plugin\n    libx11-6 \\\n    libxrandr2 \\\n    libxext6 \\\n    libxrender1 \\\n    libxfixes3 \\\n    libxss1 \\\n    libxtst6 \\\n    libxi6 \\\n    # XCB libraries for screen recording\n    libxcb1 \\\n    libxcb-shm0 \\\n    libxcb-shape0 \\\n    libxcb-xfixes0 \\\n    # FFmpeg for screen recording\n    ffmpeg \\\n    # VNC and desktop environment for computer use\n    xvfb \\\n    x11vnc \\\n    novnc \\\n    xfce4 \\\n    xfce4-terminal \\\n    dbus-x11 \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Install pipx and uv\nRUN python3 -m pip install --no-cache-dir pipx==1.8.0 && pipx ensurepath && pipx install uv==0.9.26\n\n# Install the Python Language Server\nRUN python3 -m pip install --no-cache-dir python-lsp-server==1.14.0\n\n# Install common pip packages\nRUN python3 -m pip install --no-cache-dir \\\n    numpy==2.4.1 \\\n    pandas==2.3.3 \\\n    scikit-learn==1.8.0 \\\n    keras==3.13.0 \\\n    torch==2.10.0 \\\n    scipy==1.17.0 \\\n    seaborn==0.13.2 \\\n    matplotlib==3.10.8 \\\n    django==6.0.1 \\\n    flask==3.1.2 \\\n    beautifulsoup4==4.14.3 \\\n    requests==2.32.5 \\\n    opencv-python==4.13.0.90 \\\n    pillow==12.1.0 \\\n    sqlalchemy==2.0.46 \\\n    daytona==0.134.0 \\\n    pydantic-ai==1.47.0 \\\n    langchain==1.2.7 \\\n    transformers==4.57.6 \\\n    openai==2.15.0 \\\n    anthropic==0.76.0 \\\n    llama-index==0.14.13 \\\n    instructor==1.14.4 \\\n    huggingface-hub==0.36.0 \\\n    ollama==0.6.1 \\\n    claude-agent-sdk==0.1.22\n\n# Create the Daytona user and configure sudo access\nRUN useradd -m daytona && echo \"daytona ALL=(ALL) NOPASSWD:ALL\" > /etc/sudoers.d/91-daytona\n\n# Install latest Node.js using nvm\nRUN bash -c \"source /usr/local/share/nvm/nvm.sh && nvm install 25 && nvm use 25 && nvm alias default 25\" \\\n  && chown -R daytona:daytona /usr/local/share/nvm\n\nRUN npm install -g ts-node@10.9.2 typescript@5.9.3 typescript-language-server@5.1.3 bun@1.3.6 @anthropic-ai/claude-code@2.1.19 openclaw@2026.2.1 opencode-ai@1.1.35\n\n# Create directory for computer use plugin\nRUN mkdir -p /usr/local/lib && chown daytona:daytona /usr/local/lib\n\nENV LANG=en_US.UTF-8 \\\n    LC_ALL=en_US.UTF-8\n\n# Switch to Daytona user\nUSER daytona\n\n# Create .zshrc to suppress zsh-newuser-install prompt\nRUN touch ~/.zshrc\n\n# Keep the container running indefinitely\nENTRYPOINT [ \"sleep\", \"infinity\" ]\n"
  },
  {
    "path": "images/sandbox/README.md",
    "content": "# Daytona Sandbox Image\n\n[Dockerfile](./Dockerfile) contains the definition for [daytonaio/sandbox](https://hub.docker.com/r/daytonaio/sandbox) which is used as the default sandbox image in Daytona Cloud.\n\nThe default sandbox image contains Python, Node and their most popular dependencies, including:\n\n- pipx\n- uv\n- python-lsp-server\n- numpy\n- pandas\n- scikit-learn\n- keras\n- torch\n- scipy\n- seaborn\n- matplotlib\n- django\n- flask\n- beautifulsoup4\n- requests\n- opencv-python\n- pillow\n- sqlalchemy\n- daytona\n- pydantic-ai\n- langchain\n- transformers\n- openai\n- anthropic\n- llama-index\n- instructor\n- huggingface\n- ollama\n- claude-agent-sdk\n\n- ts-node\n- typescript\n- typescript-language-server\n- bun\n- @anthropic-ai/claude-code\n- openclaw\n- opencode-ai\n"
  },
  {
    "path": "images/sandbox-slim/Dockerfile",
    "content": "FROM python:3.11.14-slim\n\n# Update package list and install required dependencies\nRUN apt-get update && apt-get install -y \\\n    curl \\\n    sudo \\\n    bash \\\n    python3-pip \\\n    python3-venv \\\n    ripgrep \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Change default shell to bash\nRUN chsh -s /bin/bash\n\nSHELL [\"/bin/bash\", \"-c\"]\n\n# Install pipx and uv\nRUN python3 -m pip install --no-cache-dir pipx==1.8.0 && pipx ensurepath && pipx install uv==0.9.26\n\n# Install Python LSP, daytona and essential pip packages\nRUN python3 -m pip install --no-cache-dir \\\n    python-lsp-server==1.14.0 \\\n    daytona==0.22.0 \\\n    matplotlib==3.10.8 \\\n    pandas==2.2.3 \\\n    numpy==2.2.6\n\n# Create the Daytona user and configure sudo access\nRUN useradd -m daytona && echo \"daytona ALL=(ALL) NOPASSWD:ALL\" > /etc/sudoers.d/91-daytona\n\nENV NVM_DIR=/usr/local/nvm\nENV NODE_VERSION=22.14.0\nRUN mkdir -p $NVM_DIR\n\n# Install nvm with node and npm\nRUN curl https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash\n\n# install node and npm\nRUN source $NVM_DIR/nvm.sh \\\n    && nvm install $NODE_VERSION \\\n    && nvm alias default $NODE_VERSION \\\n    && nvm use default\n\n# add node and npm to path so the commands are available\nENV NODE_PATH=$NVM_DIR/v$NODE_VERSION/lib/node_modules\nENV PATH=$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH\n\nRUN npm install -g ts-node@10.9.2 typescript@5.9.3 typescript-language-server@5.1.3\n\n# Switch to Daytona user\nUSER daytona\n\n# Create directory for computer use plugin\nRUN mkdir -p /usr/local/lib && sudo chown daytona:daytona /usr/local/lib\n\n# Keep the container running indefinitely\nENTRYPOINT [ \"sleep\", \"infinity\" ]\n"
  },
  {
    "path": "images/sandbox-slim/README.md",
    "content": "# Daytona Sandbox Slim Image\n\n[Dockerfile](./Dockerfile) contains the definition for [daytonaio/sandbox](https://hub.docker.com/r/daytonaio/sandbox) slim images which are used as default snapshots in self-hosted environments.\n\nThe slim sandbox image contains Python, Node and some popular dependencies including:\n\n- pipx\n- uv\n- python-lsp-server\n- numpy\n- pandas\n- matplotlib\n\n- ts-node\n- typescript\n- typescript-language-server\n\n## NOTE\n\nThe slim image does not contain dependencies necessary for Daytona's VNC functionality.\nPlease use the base image for that.\n"
  },
  {
    "path": "jest.config.ts",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nimport { getJestProjectsAsync } from '@nx/jest'\n\nexport default async () => ({\n  projects: await getJestProjectsAsync(),\n})\n"
  },
  {
    "path": "jest.preset.js",
    "content": "/*\n * Copyright 2025 Daytona Platforms Inc.\n * SPDX-License-Identifier: AGPL-3.0\n */\n\nconst nxPreset = require('@nx/jest/preset').default\n\nmodule.exports = { ...nxPreset }\n"
  },
  {
    "path": "libs/analytics-api-client/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   Copyright 2025 Daytona\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License. "
  },
  {
    "path": "libs/analytics-api-client/package.json",
    "content": "{\n  \"name\": \"@daytonaio/analytics-api-client\",\n  \"version\": \"0.0.0-dev\",\n  \"description\": \"OpenAPI client for @daytonaio/analytics-api-client\",\n  \"author\": \"OpenAPI-Generator Contributors\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/daytonaio/daytona.git\"\n  },\n  \"keywords\": [\n    \"axios\",\n    \"typescript\",\n    \"openapi-client\",\n    \"openapi-generator\",\n    \"@daytonaio/analytics-api-client\"\n  ],\n  \"license\": \"Apache-2.0\",\n  \"main\": \"./src/index.js\",\n  \"types\": \"./src/index.d.ts\",\n  \"dependencies\": {\n    \"axios\": \"^1.6.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"12.11.5 - 12.20.42\",\n    \"typescript\": \"^4.0 || ^5.0\"\n  }\n}\n"
  },
  {
    "path": "libs/analytics-api-client/project.json",
    "content": "{\n  \"name\": \"analytics-api-client\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"sourceRoot\": \"libs/analytics-api-client\",\n  \"projectType\": \"library\",\n  \"targets\": {\n    \"build\": {\n      \"executor\": \"@nx/js:tsc\",\n      \"options\": {\n        \"outputPath\": \"dist/libs/analytics-api-client\",\n        \"tsConfig\": \"{projectRoot}/tsconfig.lib.json\",\n        \"packageJson\": \"{projectRoot}/package.json\",\n        \"main\": \"{projectRoot}/src/index.ts\",\n        \"updateBuildableProjectDepsInPackageJson\": true\n      },\n      \"dependsOn\": [\"set-version\"]\n    },\n    \"generate:api-client\": {\n      \"executor\": \"nx:run-commands\",\n      \"inputs\": [\"apiClient\"],\n      \"outputs\": [\"{projectRoot}/src\"],\n      \"options\": {\n        \"commands\": [\n          \"rm -rf {projectRoot}/src\",\n          \"yarn run openapi-generator-cli generate --git-repo-id=daytona --git-user-id=daytonaio -i tmp/swagger.json -g typescript-axios --additional-properties=supportsES6=true,typescriptThreePlus=true,withSeparateModelsAndApi=true,apiPackage=api,modelPackage=models,useTags=true,enumPropertyNaming=UPPERCASE --type-mappings=DateTime=Date -o libs/analytics-api-client/src\"\n        ],\n        \"parallel\": false\n      }\n    },\n    \"set-version\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"cwd\": \"{projectRoot}\",\n        \"command\": \"if [ -n \\\"$NPM_PKG_VERSION\\\" ] || [ -n \\\"$DEFAULT_PACKAGE_VERSION\\\" ]; then VER=${NPM_PKG_VERSION:-$DEFAULT_PACKAGE_VERSION}; npm version \\\"$VER\\\" --allow-same-version && echo \\\"Changed version to $VER\\\"; else echo \\\"Using version from package.json\\\"; fi\"\n      },\n      \"cache\": true,\n      \"inputs\": [\"{projectRoot}/package.json\", { \"env\": \"NPM_PKG_VERSION\" }, { \"env\": \"DEFAULT_PACKAGE_VERSION\" }],\n      \"outputs\": [\"{projectRoot}/package.json\"]\n    },\n    \"publish\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"cwd\": \"{workspaceRoot}/dist/libs/analytics-api-client\",\n        \"command\": \"npm publish --tag $NPM_TAG --access public --registry https://registry.npmjs.org/ --//registry.npmjs.org/:_authToken=$NPM_TOKEN\",\n        \"parallel\": false\n      },\n      \"dependsOn\": [\"build\"]\n    }\n  },\n  \"tags\": []\n}\n"
  },
  {
    "path": "libs/analytics-api-client/src/.gitignore",
    "content": "wwwroot/*.js\nnode_modules\ntypings\ndist\n"
  },
  {
    "path": "libs/analytics-api-client/src/.npmignore",
    "content": "# empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm"
  },
  {
    "path": "libs/analytics-api-client/src/.openapi-generator/FILES",
    "content": ".gitignore\n.npmignore\n.openapi-generator-ignore\napi.ts\napi/telemetry-api.ts\napi/usage-api.ts\nbase.ts\ncommon.ts\nconfiguration.ts\ngit_push.sh\nindex.ts\nmodels/index.ts\nmodels/models-aggregated-usage.ts\nmodels/models-log-entry.ts\nmodels/models-metric-point.ts\nmodels/models-sandbox-usage.ts\nmodels/models-span.ts\nmodels/models-trace-summary.ts\nmodels/models-usage-chart-point.ts\nmodels/models-usage-period.ts\n"
  },
  {
    "path": "libs/analytics-api-client/src/.openapi-generator/VERSION",
    "content": "7.12.0\n"
  },
  {
    "path": "libs/analytics-api-client/src/.openapi-generator-ignore",
    "content": "# OpenAPI Generator Ignore\n# Generated by openapi-generator https://github.com/openapitools/openapi-generator\n\n# Use this file to prevent files from being overwritten by the generator.\n# The patterns follow closely to .gitignore or .dockerignore.\n\n# As an example, the C# client generator defines ApiClient.cs.\n# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:\n#ApiClient.cs\n\n# You can match any string of characters against a directory, file or extension with a single asterisk (*):\n#foo/*/qux\n# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux\n\n# You can recursively match patterns against a directory, file or extension with a double asterisk (**):\n#foo/**/qux\n# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux\n\n# You can also negate patterns with an exclamation (!).\n# For example, you can ignore all files in a docs folder with the file extension .md:\n#docs/*.md\n# Then explicitly reverse the ignore rule for a single file:\n#!docs/README.md\n"
  },
  {
    "path": "libs/analytics-api-client/src/api/telemetry-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { ModelsLogEntry } from '../models';\n// @ts-ignore\nimport type { ModelsMetricPoint } from '../models';\n// @ts-ignore\nimport type { ModelsSpan } from '../models';\n// @ts-ignore\nimport type { ModelsTraceSummary } from '../models';\n/**\n * TelemetryApi - axios parameter creator\n * @export\n */\nexport const TelemetryApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * Returns paginated log entries with optional severity and search filters\n         * @summary Get sandbox logs\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [severity] Comma-separated severity levels\n         * @param {string} [search] Search text (ILIKE)\n         * @param {number} [limit] Page size\n         * @param {number} [offset] Offset\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet: async (organizationId: string, sandboxId: string, from: string, to: string, severity?: string, search?: string, limit?: number, offset?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet', 'organizationId', organizationId)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet', 'sandboxId', sandboxId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet', 'to', to)\n            const localVarPath = `/organization/{organizationId}/sandbox/{sandboxId}/telemetry/logs`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication Bearer required\n            await setApiKeyToObject(localVarHeaderParameter, \"Authorization\", configuration)\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = to;\n            }\n\n            if (severity !== undefined) {\n                localVarQueryParameter['severity'] = severity;\n            }\n\n            if (search !== undefined) {\n                localVarQueryParameter['search'] = search;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n            if (offset !== undefined) {\n                localVarQueryParameter['offset'] = offset;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Returns gauge metrics aggregated in 1-minute intervals\n         * @summary Get sandbox metrics\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [metricNames] Comma-separated metric names\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet: async (organizationId: string, sandboxId: string, from: string, to: string, metricNames?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet', 'organizationId', organizationId)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet', 'sandboxId', sandboxId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet', 'to', to)\n            const localVarPath = `/organization/{organizationId}/sandbox/{sandboxId}/telemetry/metrics`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication Bearer required\n            await setApiKeyToObject(localVarHeaderParameter, \"Authorization\", configuration)\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = to;\n            }\n\n            if (metricNames !== undefined) {\n                localVarQueryParameter['metricNames'] = metricNames;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Returns paginated trace summaries with span counts and root span info\n         * @summary Get sandbox traces\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {number} [limit] Page size\n         * @param {number} [offset] Offset\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet: async (organizationId: string, sandboxId: string, from: string, to: string, limit?: number, offset?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet', 'organizationId', organizationId)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet', 'sandboxId', sandboxId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet', 'to', to)\n            const localVarPath = `/organization/{organizationId}/sandbox/{sandboxId}/telemetry/traces`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication Bearer required\n            await setApiKeyToObject(localVarHeaderParameter, \"Authorization\", configuration)\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = to;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n            if (offset !== undefined) {\n                localVarQueryParameter['offset'] = offset;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Returns all spans belonging to a specific trace ID\n         * @summary Get trace spans\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} traceId Trace ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet: async (organizationId: string, sandboxId: string, traceId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet', 'organizationId', organizationId)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet', 'sandboxId', sandboxId)\n            // verify required parameter 'traceId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet', 'traceId', traceId)\n            const localVarPath = `/organization/{organizationId}/sandbox/{sandboxId}/telemetry/traces/{traceId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"traceId\"}}`, encodeURIComponent(String(traceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication Bearer required\n            await setApiKeyToObject(localVarHeaderParameter, \"Authorization\", configuration)\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * TelemetryApi - functional programming interface\n * @export\n */\nexport const TelemetryApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = TelemetryApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * Returns paginated log entries with optional severity and search filters\n         * @summary Get sandbox logs\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [severity] Comma-separated severity levels\n         * @param {string} [search] Search text (ILIKE)\n         * @param {number} [limit] Page size\n         * @param {number} [offset] Offset\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet(organizationId: string, sandboxId: string, from: string, to: string, severity?: string, search?: string, limit?: number, offset?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ModelsLogEntry>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet(organizationId, sandboxId, from, to, severity, search, limit, offset, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['TelemetryApi.organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Returns gauge metrics aggregated in 1-minute intervals\n         * @summary Get sandbox metrics\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [metricNames] Comma-separated metric names\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet(organizationId: string, sandboxId: string, from: string, to: string, metricNames?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ModelsMetricPoint>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet(organizationId, sandboxId, from, to, metricNames, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['TelemetryApi.organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Returns paginated trace summaries with span counts and root span info\n         * @summary Get sandbox traces\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {number} [limit] Page size\n         * @param {number} [offset] Offset\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet(organizationId: string, sandboxId: string, from: string, to: string, limit?: number, offset?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ModelsTraceSummary>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet(organizationId, sandboxId, from, to, limit, offset, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['TelemetryApi.organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Returns all spans belonging to a specific trace ID\n         * @summary Get trace spans\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} traceId Trace ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet(organizationId: string, sandboxId: string, traceId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ModelsSpan>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet(organizationId, sandboxId, traceId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['TelemetryApi.organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * TelemetryApi - factory interface\n * @export\n */\nexport const TelemetryApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = TelemetryApiFp(configuration)\n    return {\n        /**\n         * Returns paginated log entries with optional severity and search filters\n         * @summary Get sandbox logs\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [severity] Comma-separated severity levels\n         * @param {string} [search] Search text (ILIKE)\n         * @param {number} [limit] Page size\n         * @param {number} [offset] Offset\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet(organizationId: string, sandboxId: string, from: string, to: string, severity?: string, search?: string, limit?: number, offset?: number, options?: RawAxiosRequestConfig): AxiosPromise<Array<ModelsLogEntry>> {\n            return localVarFp.organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet(organizationId, sandboxId, from, to, severity, search, limit, offset, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Returns gauge metrics aggregated in 1-minute intervals\n         * @summary Get sandbox metrics\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [metricNames] Comma-separated metric names\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet(organizationId: string, sandboxId: string, from: string, to: string, metricNames?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<ModelsMetricPoint>> {\n            return localVarFp.organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet(organizationId, sandboxId, from, to, metricNames, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Returns paginated trace summaries with span counts and root span info\n         * @summary Get sandbox traces\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {number} [limit] Page size\n         * @param {number} [offset] Offset\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet(organizationId: string, sandboxId: string, from: string, to: string, limit?: number, offset?: number, options?: RawAxiosRequestConfig): AxiosPromise<Array<ModelsTraceSummary>> {\n            return localVarFp.organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet(organizationId, sandboxId, from, to, limit, offset, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Returns all spans belonging to a specific trace ID\n         * @summary Get trace spans\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} traceId Trace ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet(organizationId: string, sandboxId: string, traceId: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<ModelsSpan>> {\n            return localVarFp.organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet(organizationId, sandboxId, traceId, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * TelemetryApi - object-oriented interface\n * @export\n * @class TelemetryApi\n * @extends {BaseAPI}\n */\nexport class TelemetryApi extends BaseAPI {\n    /**\n     * Returns paginated log entries with optional severity and search filters\n     * @summary Get sandbox logs\n     * @param {string} organizationId Organization ID\n     * @param {string} sandboxId Sandbox ID\n     * @param {string} from Start time (RFC3339)\n     * @param {string} to End time (RFC3339)\n     * @param {string} [severity] Comma-separated severity levels\n     * @param {string} [search] Search text (ILIKE)\n     * @param {number} [limit] Page size\n     * @param {number} [offset] Offset\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof TelemetryApi\n     */\n    public organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet(organizationId: string, sandboxId: string, from: string, to: string, severity?: string, search?: string, limit?: number, offset?: number, options?: RawAxiosRequestConfig) {\n        return TelemetryApiFp(this.configuration).organizationOrganizationIdSandboxSandboxIdTelemetryLogsGet(organizationId, sandboxId, from, to, severity, search, limit, offset, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Returns gauge metrics aggregated in 1-minute intervals\n     * @summary Get sandbox metrics\n     * @param {string} organizationId Organization ID\n     * @param {string} sandboxId Sandbox ID\n     * @param {string} from Start time (RFC3339)\n     * @param {string} to End time (RFC3339)\n     * @param {string} [metricNames] Comma-separated metric names\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof TelemetryApi\n     */\n    public organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet(organizationId: string, sandboxId: string, from: string, to: string, metricNames?: string, options?: RawAxiosRequestConfig) {\n        return TelemetryApiFp(this.configuration).organizationOrganizationIdSandboxSandboxIdTelemetryMetricsGet(organizationId, sandboxId, from, to, metricNames, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Returns paginated trace summaries with span counts and root span info\n     * @summary Get sandbox traces\n     * @param {string} organizationId Organization ID\n     * @param {string} sandboxId Sandbox ID\n     * @param {string} from Start time (RFC3339)\n     * @param {string} to End time (RFC3339)\n     * @param {number} [limit] Page size\n     * @param {number} [offset] Offset\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof TelemetryApi\n     */\n    public organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet(organizationId: string, sandboxId: string, from: string, to: string, limit?: number, offset?: number, options?: RawAxiosRequestConfig) {\n        return TelemetryApiFp(this.configuration).organizationOrganizationIdSandboxSandboxIdTelemetryTracesGet(organizationId, sandboxId, from, to, limit, offset, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Returns all spans belonging to a specific trace ID\n     * @summary Get trace spans\n     * @param {string} organizationId Organization ID\n     * @param {string} sandboxId Sandbox ID\n     * @param {string} traceId Trace ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof TelemetryApi\n     */\n    public organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet(organizationId: string, sandboxId: string, traceId: string, options?: RawAxiosRequestConfig) {\n        return TelemetryApiFp(this.configuration).organizationOrganizationIdSandboxSandboxIdTelemetryTracesTraceIdGet(organizationId, sandboxId, traceId, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/api/usage-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { ModelsAggregatedUsage } from '../models';\n// @ts-ignore\nimport type { ModelsSandboxUsage } from '../models';\n// @ts-ignore\nimport type { ModelsUsageChartPoint } from '../models';\n// @ts-ignore\nimport type { ModelsUsagePeriod } from '../models';\n/**\n * UsageApi - axios parameter creator\n * @export\n */\nexport const UsageApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * Returns individual usage records for a specific sandbox within a time range\n         * @summary Get sandbox usage periods\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdUsageGet: async (organizationId: string, sandboxId: string, from: string, to: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdUsageGet', 'organizationId', organizationId)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdUsageGet', 'sandboxId', sandboxId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdUsageGet', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('organizationOrganizationIdSandboxSandboxIdUsageGet', 'to', to)\n            const localVarPath = `/organization/{organizationId}/sandbox/{sandboxId}/usage`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication Bearer required\n            await setApiKeyToObject(localVarHeaderParameter, \"Authorization\", configuration)\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = to;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Returns organization-level resource usage totals for a given time period\n         * @summary Get aggregated usage\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdUsageAggregatedGet: async (organizationId: string, from: string, to: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageAggregatedGet', 'organizationId', organizationId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageAggregatedGet', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageAggregatedGet', 'to', to)\n            const localVarPath = `/organization/{organizationId}/usage/aggregated`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication Bearer required\n            await setApiKeyToObject(localVarHeaderParameter, \"Authorization\", configuration)\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = to;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Returns per-minute resource usage data points for a given time period\n         * @summary Get usage chart data\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [region] Region filter\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdUsageChartGet: async (organizationId: string, from: string, to: string, region?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageChartGet', 'organizationId', organizationId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageChartGet', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageChartGet', 'to', to)\n            const localVarPath = `/organization/{organizationId}/usage/chart`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication Bearer required\n            await setApiKeyToObject(localVarHeaderParameter, \"Authorization\", configuration)\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = to;\n            }\n\n            if (region !== undefined) {\n                localVarQueryParameter['region'] = region;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Returns resource usage aggregated per sandbox for a given time period\n         * @summary Get per-sandbox usage\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdUsageSandboxGet: async (organizationId: string, from: string, to: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageSandboxGet', 'organizationId', organizationId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageSandboxGet', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('organizationOrganizationIdUsageSandboxGet', 'to', to)\n            const localVarPath = `/organization/{organizationId}/usage/sandbox`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication Bearer required\n            await setApiKeyToObject(localVarHeaderParameter, \"Authorization\", configuration)\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = to;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * UsageApi - functional programming interface\n * @export\n */\nexport const UsageApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = UsageApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * Returns individual usage records for a specific sandbox within a time range\n         * @summary Get sandbox usage periods\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async organizationOrganizationIdSandboxSandboxIdUsageGet(organizationId: string, sandboxId: string, from: string, to: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ModelsUsagePeriod>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.organizationOrganizationIdSandboxSandboxIdUsageGet(organizationId, sandboxId, from, to, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsageApi.organizationOrganizationIdSandboxSandboxIdUsageGet']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Returns organization-level resource usage totals for a given time period\n         * @summary Get aggregated usage\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async organizationOrganizationIdUsageAggregatedGet(organizationId: string, from: string, to: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ModelsAggregatedUsage>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.organizationOrganizationIdUsageAggregatedGet(organizationId, from, to, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsageApi.organizationOrganizationIdUsageAggregatedGet']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Returns per-minute resource usage data points for a given time period\n         * @summary Get usage chart data\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [region] Region filter\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async organizationOrganizationIdUsageChartGet(organizationId: string, from: string, to: string, region?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ModelsUsageChartPoint>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.organizationOrganizationIdUsageChartGet(organizationId, from, to, region, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsageApi.organizationOrganizationIdUsageChartGet']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Returns resource usage aggregated per sandbox for a given time period\n         * @summary Get per-sandbox usage\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async organizationOrganizationIdUsageSandboxGet(organizationId: string, from: string, to: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ModelsSandboxUsage>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.organizationOrganizationIdUsageSandboxGet(organizationId, from, to, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsageApi.organizationOrganizationIdUsageSandboxGet']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * UsageApi - factory interface\n * @export\n */\nexport const UsageApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = UsageApiFp(configuration)\n    return {\n        /**\n         * Returns individual usage records for a specific sandbox within a time range\n         * @summary Get sandbox usage periods\n         * @param {string} organizationId Organization ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdSandboxSandboxIdUsageGet(organizationId: string, sandboxId: string, from: string, to: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<ModelsUsagePeriod>> {\n            return localVarFp.organizationOrganizationIdSandboxSandboxIdUsageGet(organizationId, sandboxId, from, to, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Returns organization-level resource usage totals for a given time period\n         * @summary Get aggregated usage\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdUsageAggregatedGet(organizationId: string, from: string, to: string, options?: RawAxiosRequestConfig): AxiosPromise<ModelsAggregatedUsage> {\n            return localVarFp.organizationOrganizationIdUsageAggregatedGet(organizationId, from, to, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Returns per-minute resource usage data points for a given time period\n         * @summary Get usage chart data\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {string} [region] Region filter\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdUsageChartGet(organizationId: string, from: string, to: string, region?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<ModelsUsageChartPoint>> {\n            return localVarFp.organizationOrganizationIdUsageChartGet(organizationId, from, to, region, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Returns resource usage aggregated per sandbox for a given time period\n         * @summary Get per-sandbox usage\n         * @param {string} organizationId Organization ID\n         * @param {string} from Start time (RFC3339)\n         * @param {string} to End time (RFC3339)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        organizationOrganizationIdUsageSandboxGet(organizationId: string, from: string, to: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<ModelsSandboxUsage>> {\n            return localVarFp.organizationOrganizationIdUsageSandboxGet(organizationId, from, to, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * UsageApi - object-oriented interface\n * @export\n * @class UsageApi\n * @extends {BaseAPI}\n */\nexport class UsageApi extends BaseAPI {\n    /**\n     * Returns individual usage records for a specific sandbox within a time range\n     * @summary Get sandbox usage periods\n     * @param {string} organizationId Organization ID\n     * @param {string} sandboxId Sandbox ID\n     * @param {string} from Start time (RFC3339)\n     * @param {string} to End time (RFC3339)\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsageApi\n     */\n    public organizationOrganizationIdSandboxSandboxIdUsageGet(organizationId: string, sandboxId: string, from: string, to: string, options?: RawAxiosRequestConfig) {\n        return UsageApiFp(this.configuration).organizationOrganizationIdSandboxSandboxIdUsageGet(organizationId, sandboxId, from, to, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Returns organization-level resource usage totals for a given time period\n     * @summary Get aggregated usage\n     * @param {string} organizationId Organization ID\n     * @param {string} from Start time (RFC3339)\n     * @param {string} to End time (RFC3339)\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsageApi\n     */\n    public organizationOrganizationIdUsageAggregatedGet(organizationId: string, from: string, to: string, options?: RawAxiosRequestConfig) {\n        return UsageApiFp(this.configuration).organizationOrganizationIdUsageAggregatedGet(organizationId, from, to, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Returns per-minute resource usage data points for a given time period\n     * @summary Get usage chart data\n     * @param {string} organizationId Organization ID\n     * @param {string} from Start time (RFC3339)\n     * @param {string} to End time (RFC3339)\n     * @param {string} [region] Region filter\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsageApi\n     */\n    public organizationOrganizationIdUsageChartGet(organizationId: string, from: string, to: string, region?: string, options?: RawAxiosRequestConfig) {\n        return UsageApiFp(this.configuration).organizationOrganizationIdUsageChartGet(organizationId, from, to, region, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Returns resource usage aggregated per sandbox for a given time period\n     * @summary Get per-sandbox usage\n     * @param {string} organizationId Organization ID\n     * @param {string} from Start time (RFC3339)\n     * @param {string} to End time (RFC3339)\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsageApi\n     */\n    public organizationOrganizationIdUsageSandboxGet(organizationId: string, from: string, to: string, options?: RawAxiosRequestConfig) {\n        return UsageApiFp(this.configuration).organizationOrganizationIdUsageSandboxGet(organizationId, from, to, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\nexport * from './api/telemetry-api';\nexport * from './api/usage-api';\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/base.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from './configuration';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n\nexport const BASE_PATH = \"http://localhost:8080\".replace(/\\/+$/, \"\");\n\n/**\n *\n * @export\n */\nexport const COLLECTION_FORMATS = {\n    csv: \",\",\n    ssv: \" \",\n    tsv: \"\\t\",\n    pipes: \"|\",\n};\n\n/**\n *\n * @export\n * @interface RequestArgs\n */\nexport interface RequestArgs {\n    url: string;\n    options: RawAxiosRequestConfig;\n}\n\n/**\n *\n * @export\n * @class BaseAPI\n */\nexport class BaseAPI {\n    protected configuration: Configuration | undefined;\n\n    constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {\n        if (configuration) {\n            this.configuration = configuration;\n            this.basePath = configuration.basePath ?? basePath;\n        }\n    }\n};\n\n/**\n *\n * @export\n * @class RequiredError\n * @extends {Error}\n */\nexport class RequiredError extends Error {\n    constructor(public field: string, msg?: string) {\n        super(msg);\n        this.name = \"RequiredError\"\n    }\n}\n\ninterface ServerMap {\n    [key: string]: {\n        url: string,\n        description: string,\n    }[];\n}\n\n/**\n *\n * @export\n */\nexport const operationServerMap: ServerMap = {\n}\n"
  },
  {
    "path": "libs/analytics-api-client/src/common.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from \"./configuration\";\nimport type { RequestArgs } from \"./base\";\nimport type { AxiosInstance, AxiosResponse } from 'axios';\nimport { RequiredError } from \"./base\";\n\n/**\n *\n * @export\n */\nexport const DUMMY_BASE_URL = 'https://example.com'\n\n/**\n *\n * @throws {RequiredError}\n * @export\n */\nexport const assertParamExists = function (functionName: string, paramName: string, paramValue: unknown) {\n    if (paramValue === null || paramValue === undefined) {\n        throw new RequiredError(paramName, `Required parameter ${paramName} was null or undefined when calling ${functionName}.`);\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) {\n    if (configuration && configuration.apiKey) {\n        const localVarApiKeyValue = typeof configuration.apiKey === 'function'\n            ? await configuration.apiKey(keyParamName)\n            : await configuration.apiKey;\n        object[keyParamName] = localVarApiKeyValue;\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setBasicAuthToObject = function (object: any, configuration?: Configuration) {\n    if (configuration && (configuration.username || configuration.password)) {\n        object[\"auth\"] = { username: configuration.username, password: configuration.password };\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setBearerAuthToObject = async function (object: any, configuration?: Configuration) {\n    if (configuration && configuration.accessToken) {\n        const accessToken = typeof configuration.accessToken === 'function'\n            ? await configuration.accessToken()\n            : await configuration.accessToken;\n        object[\"Authorization\"] = \"Bearer \" + accessToken;\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) {\n    if (configuration && configuration.accessToken) {\n        const localVarAccessTokenValue = typeof configuration.accessToken === 'function'\n            ? await configuration.accessToken(name, scopes)\n            : await configuration.accessToken;\n        object[\"Authorization\"] = \"Bearer \" + localVarAccessTokenValue;\n    }\n}\n\nfunction setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = \"\"): void {\n    if (parameter == null) return;\n    if (typeof parameter === \"object\") {\n        if (Array.isArray(parameter)) {\n            (parameter as any[]).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key));\n        } \n        else {\n            Object.keys(parameter).forEach(currentKey => \n                setFlattenedQueryParams(urlSearchParams, parameter[currentKey], `${key}${key !== '' ? '.' : ''}${currentKey}`)\n            );\n        }\n    } \n    else {\n        if (urlSearchParams.has(key)) {\n            urlSearchParams.append(key, parameter);\n        } \n        else {\n            urlSearchParams.set(key, parameter);\n        }\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setSearchParams = function (url: URL, ...objects: any[]) {\n    const searchParams = new URLSearchParams(url.search);\n    setFlattenedQueryParams(searchParams, objects);\n    url.search = searchParams.toString();\n}\n\n/**\n *\n * @export\n */\nexport const serializeDataIfNeeded = function (value: any, requestOptions: any, configuration?: Configuration) {\n    const nonString = typeof value !== 'string';\n    const needsSerialization = nonString && configuration && configuration.isJsonMime\n        ? configuration.isJsonMime(requestOptions.headers['Content-Type'])\n        : nonString;\n    return needsSerialization\n        ? JSON.stringify(value !== undefined ? value : {})\n        : (value || \"\");\n}\n\n/**\n *\n * @export\n */\nexport const toPathString = function (url: URL) {\n    return url.pathname + url.search + url.hash\n}\n\n/**\n *\n * @export\n */\nexport const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) {\n    return <T = unknown, R = AxiosResponse<T>>(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {\n        const axiosRequestArgs = {...axiosArgs.options, url: (axios.defaults.baseURL ? '' : configuration?.basePath ?? basePath) + axiosArgs.url};\n        return axios.request<T, R>(axiosRequestArgs);\n    };\n}\n"
  },
  {
    "path": "libs/analytics-api-client/src/configuration.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nexport interface ConfigurationParameters {\n    apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);\n    username?: string;\n    password?: string;\n    accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);\n    basePath?: string;\n    serverIndex?: number;\n    baseOptions?: any;\n    formDataCtor?: new () => any;\n}\n\nexport class Configuration {\n    /**\n     * parameter for apiKey security\n     * @param name security name\n     * @memberof Configuration\n     */\n    apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);\n    /**\n     * parameter for basic security\n     *\n     * @type {string}\n     * @memberof Configuration\n     */\n    username?: string;\n    /**\n     * parameter for basic security\n     *\n     * @type {string}\n     * @memberof Configuration\n     */\n    password?: string;\n    /**\n     * parameter for oauth2 security\n     * @param name security name\n     * @param scopes oauth2 scope\n     * @memberof Configuration\n     */\n    accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);\n    /**\n     * override base path\n     *\n     * @type {string}\n     * @memberof Configuration\n     */\n    basePath?: string;\n    /**\n     * override server index\n     *\n     * @type {number}\n     * @memberof Configuration\n     */\n    serverIndex?: number;\n    /**\n     * base options for axios calls\n     *\n     * @type {any}\n     * @memberof Configuration\n     */\n    baseOptions?: any;\n    /**\n     * The FormData constructor that will be used to create multipart form data\n     * requests. You can inject this here so that execution environments that\n     * do not support the FormData class can still run the generated client.\n     *\n     * @type {new () => FormData}\n     */\n    formDataCtor?: new () => any;\n\n    constructor(param: ConfigurationParameters = {}) {\n        this.apiKey = param.apiKey;\n        this.username = param.username;\n        this.password = param.password;\n        this.accessToken = param.accessToken;\n        this.basePath = param.basePath;\n        this.serverIndex = param.serverIndex;\n        this.baseOptions = {\n            ...param.baseOptions,\n            headers: {\n                ...param.baseOptions?.headers,\n            },\n        };\n        this.formDataCtor = param.formDataCtor;\n    }\n\n    /**\n     * Check if the given MIME is a JSON MIME.\n     * JSON MIME examples:\n     *   application/json\n     *   application/json; charset=UTF8\n     *   APPLICATION/JSON\n     *   application/vnd.company+json\n     * @param mime - MIME (Multipurpose Internet Mail Extensions)\n     * @return True if the given MIME is JSON, false otherwise.\n     */\n    public isJsonMime(mime: string): boolean {\n        const jsonMime: RegExp = new RegExp('^(application\\/json|[^;/ \\t]+\\/[^;/ \\t]+[+]json)[ \\t]*(;.*)?$', 'i');\n        return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');\n    }\n}\n"
  },
  {
    "path": "libs/analytics-api-client/src/git_push.sh",
    "content": "#!/bin/sh\n# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/\n#\n# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl \"minor update\" \"gitlab.com\"\n\ngit_user_id=$1\ngit_repo_id=$2\nrelease_note=$3\ngit_host=$4\n\nif [ \"$git_host\" = \"\" ]; then\n    git_host=\"github.com\"\n    echo \"[INFO] No command line input provided. Set \\$git_host to $git_host\"\nfi\n\nif [ \"$git_user_id\" = \"\" ]; then\n    git_user_id=\"daytonaio\"\n    echo \"[INFO] No command line input provided. Set \\$git_user_id to $git_user_id\"\nfi\n\nif [ \"$git_repo_id\" = \"\" ]; then\n    git_repo_id=\"daytona\"\n    echo \"[INFO] No command line input provided. Set \\$git_repo_id to $git_repo_id\"\nfi\n\nif [ \"$release_note\" = \"\" ]; then\n    release_note=\"Minor update\"\n    echo \"[INFO] No command line input provided. Set \\$release_note to $release_note\"\nfi\n\n# Initialize the local directory as a Git repository\ngit init\n\n# Adds the files in the local repository and stages them for commit.\ngit add .\n\n# Commits the tracked changes and prepares them to be pushed to a remote repository.\ngit commit -m \"$release_note\"\n\n# Sets the new remote\ngit_remote=$(git remote)\nif [ \"$git_remote\" = \"\" ]; then # git remote not defined\n\n    if [ \"$GIT_TOKEN\" = \"\" ]; then\n        echo \"[INFO] \\$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment.\"\n        git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git\n    else\n        git remote add origin https://${git_user_id}:\"${GIT_TOKEN}\"@${git_host}/${git_user_id}/${git_repo_id}.git\n    fi\n\nfi\n\ngit pull origin master\n\n# Pushes (Forces) the changes in the local repository up to the remote repository\necho \"Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git\"\ngit push origin master 2>&1 | grep -v 'To https'\n"
  },
  {
    "path": "libs/analytics-api-client/src/index.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nexport * from \"./api\";\nexport * from \"./configuration\";\nexport * from \"./models\";\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/index.ts",
    "content": "export * from './models-aggregated-usage';\nexport * from './models-log-entry';\nexport * from './models-metric-point';\nexport * from './models-sandbox-usage';\nexport * from './models-span';\nexport * from './models-trace-summary';\nexport * from './models-usage-chart-point';\nexport * from './models-usage-period';\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/models-aggregated-usage.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ModelsAggregatedUsage\n */\nexport interface ModelsAggregatedUsage {\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsAggregatedUsage\n     */\n    'firstStart'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsAggregatedUsage\n     */\n    'lastEnd'?: string;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsAggregatedUsage\n     */\n    'sandboxCount'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsAggregatedUsage\n     */\n    'totalCPUSeconds'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsAggregatedUsage\n     */\n    'totalDiskGBSeconds'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsAggregatedUsage\n     */\n    'totalGPUSeconds'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsAggregatedUsage\n     */\n    'totalPrice'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsAggregatedUsage\n     */\n    'totalRAMGBSeconds'?: number;\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/models-log-entry.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ModelsLogEntry\n */\nexport interface ModelsLogEntry {\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsLogEntry\n     */\n    'body'?: string;\n    /**\n     * \n     * @type {{ [key: string]: string; }}\n     * @memberof ModelsLogEntry\n     */\n    'logAttributes'?: { [key: string]: string; };\n    /**\n     * \n     * @type {{ [key: string]: string; }}\n     * @memberof ModelsLogEntry\n     */\n    'resourceAttributes'?: { [key: string]: string; };\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsLogEntry\n     */\n    'serviceName'?: string;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsLogEntry\n     */\n    'severityNumber'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsLogEntry\n     */\n    'severityText'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsLogEntry\n     */\n    'spanId'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsLogEntry\n     */\n    'timestamp'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsLogEntry\n     */\n    'traceId'?: string;\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/models-metric-point.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ModelsMetricPoint\n */\nexport interface ModelsMetricPoint {\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsMetricPoint\n     */\n    'metricName'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsMetricPoint\n     */\n    'timestamp'?: string;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsMetricPoint\n     */\n    'value'?: number;\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/models-sandbox-usage.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ModelsSandboxUsage\n */\nexport interface ModelsSandboxUsage {\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSandboxUsage\n     */\n    'firstStart'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSandboxUsage\n     */\n    'lastEnd'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSandboxUsage\n     */\n    'sandboxId'?: string;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsSandboxUsage\n     */\n    'totalCPUSeconds'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsSandboxUsage\n     */\n    'totalDiskGBSeconds'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsSandboxUsage\n     */\n    'totalGPUSeconds'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsSandboxUsage\n     */\n    'totalPrice'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsSandboxUsage\n     */\n    'totalRAMGBSeconds'?: number;\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/models-span.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ModelsSpan\n */\nexport interface ModelsSpan {\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsSpan\n     */\n    'durationMs'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSpan\n     */\n    'parentSpanId'?: string;\n    /**\n     * \n     * @type {{ [key: string]: string; }}\n     * @memberof ModelsSpan\n     */\n    'spanAttributes'?: { [key: string]: string; };\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSpan\n     */\n    'spanId'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSpan\n     */\n    'spanName'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSpan\n     */\n    'statusCode'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSpan\n     */\n    'statusMessage'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSpan\n     */\n    'timestamp'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsSpan\n     */\n    'traceId'?: string;\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/models-trace-summary.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ModelsTraceSummary\n */\nexport interface ModelsTraceSummary {\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsTraceSummary\n     */\n    'endTime'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsTraceSummary\n     */\n    'rootSpanName'?: string;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsTraceSummary\n     */\n    'spanCount'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsTraceSummary\n     */\n    'startTime'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsTraceSummary\n     */\n    'statusCode'?: string;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsTraceSummary\n     */\n    'totalDurationMs'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsTraceSummary\n     */\n    'traceId'?: string;\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/models-usage-chart-point.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ModelsUsageChartPoint\n */\nexport interface ModelsUsageChartPoint {\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsageChartPoint\n     */\n    'cpu'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsageChartPoint\n     */\n    'cpuPrice'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsageChartPoint\n     */\n    'diskGB'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsageChartPoint\n     */\n    'diskPrice'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsageChartPoint\n     */\n    'ramGB'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsageChartPoint\n     */\n    'ramPrice'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsUsageChartPoint\n     */\n    'time'?: string;\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/src/models/models-usage-period.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona Analytics API\n * Daytona Analytics API - Read-only telemetry and usage data. Authenticated via Daytona API keys or JWT tokens.\n *\n * The version of the OpenAPI document: v0.0.0-dev\n * \n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ModelsUsagePeriod\n */\nexport interface ModelsUsagePeriod {\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsagePeriod\n     */\n    'cpu'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsagePeriod\n     */\n    'diskGB'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsUsagePeriod\n     */\n    'endAt'?: string;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsagePeriod\n     */\n    'gpu'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsagePeriod\n     */\n    'price'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof ModelsUsagePeriod\n     */\n    'ramGB'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof ModelsUsagePeriod\n     */\n    'startAt'?: string;\n}\n\n"
  },
  {
    "path": "libs/analytics-api-client/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"strict\": true,\n    \"importHelpers\": false,\n    \"noImplicitOverride\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noPropertyAccessFromIndexSignature\": true\n  },\n  \"files\": [],\n  \"include\": [],\n  \"references\": [\n    {\n      \"path\": \"./tsconfig.lib.json\"\n    }\n  ]\n}\n"
  },
  {
    "path": "libs/analytics-api-client/tsconfig.lib.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../../dist/out-tsc\",\n    \"declaration\": true,\n    \"types\": [\"node\"]\n  },\n  \"include\": [\"src/**/*.ts\"]\n}\n"
  },
  {
    "path": "libs/api-client/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   Copyright 2025 Daytona\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License. "
  },
  {
    "path": "libs/api-client/package.json",
    "content": "{\n  \"name\": \"@daytonaio/api-client\",\n  \"version\": \"0.0.0-dev\",\n  \"description\": \"OpenAPI client for @daytonaio/api-client\",\n  \"author\": \"OpenAPI-Generator Contributors\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/daytonaio/daytona.git\"\n  },\n  \"keywords\": [\n    \"axios\",\n    \"typescript\",\n    \"openapi-client\",\n    \"openapi-generator\",\n    \"@daytonaio/api-client\"\n  ],\n  \"license\": \"Apache-2.0\",\n  \"main\": \"./src/index.js\",\n  \"types\": \"./src/index.d.ts\",\n  \"dependencies\": {\n    \"axios\": \"^1.6.1\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"12.11.5 - 12.20.42\",\n    \"typescript\": \"^4.0 || ^5.0\"\n  }\n}\n"
  },
  {
    "path": "libs/api-client/project.json",
    "content": "{\n  \"name\": \"api-client\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"sourceRoot\": \"libs/api-client\",\n  \"projectType\": \"library\",\n  \"targets\": {\n    \"build\": {\n      \"executor\": \"@nx/js:tsc\",\n      \"options\": {\n        \"outputPath\": \"dist/libs/api-client\",\n        \"tsConfig\": \"{projectRoot}/tsconfig.lib.json\",\n        \"packageJson\": \"{projectRoot}/package.json\",\n        \"main\": \"{projectRoot}/src/index.ts\",\n        \"updateBuildableProjectDepsInPackageJson\": true\n      },\n      \"dependsOn\": [\"set-version\"]\n    },\n    \"generate:api-client\": {\n      \"executor\": \"nx:run-commands\",\n      \"inputs\": [\"apiClient\"],\n      \"outputs\": [\"{projectRoot}/src\"],\n      \"options\": {\n        \"commands\": [\n          \"rm -rf {projectRoot}/src\",\n          \"yarn run openapi-generator-cli generate --git-repo-id=daytona --git-user-id=daytonaio -i dist/apps/api/openapi.json -g typescript-axios --additional-properties=supportsES6=true,typescriptThreePlus=true,withSeparateModelsAndApi=true,apiPackage=api,modelPackage=models,useTags=true,enumPropertyNaming=UPPERCASE --type-mappings=DateTime=Date -o libs/api-client/src\"\n        ],\n        \"parallel\": false\n      },\n      \"dependsOn\": [\n        {\n          \"target\": \"openapi\",\n          \"projects\": \"api\"\n        }\n      ]\n    },\n    \"set-version\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"cwd\": \"{projectRoot}\",\n        \"command\": \"if [ -n \\\"$NPM_PKG_VERSION\\\" ] || [ -n \\\"$DEFAULT_PACKAGE_VERSION\\\" ]; then VER=${NPM_PKG_VERSION:-$DEFAULT_PACKAGE_VERSION}; npm version \\\"$VER\\\" --allow-same-version && echo \\\"Changed version to $VER\\\"; else echo \\\"Using version from package.json\\\"; fi\"\n      },\n      \"cache\": true,\n      \"inputs\": [\"{projectRoot}/package.json\", { \"env\": \"NPM_PKG_VERSION\" }, { \"env\": \"DEFAULT_PACKAGE_VERSION\" }],\n      \"outputs\": [\"{projectRoot}/package.json\"]\n    },\n    \"publish\": {\n      \"executor\": \"nx:run-commands\",\n      \"options\": {\n        \"cwd\": \"{workspaceRoot}/dist/libs/api-client\",\n        \"command\": \"npm publish --tag $NPM_TAG --access public --registry https://registry.npmjs.org/ --//registry.npmjs.org/:_authToken=$NPM_TOKEN\",\n        \"parallel\": false\n      },\n      \"dependsOn\": [\"build\"]\n    }\n  },\n  \"tags\": []\n}\n"
  },
  {
    "path": "libs/api-client/src/.gitignore",
    "content": "wwwroot/*.js\nnode_modules\ntypings\ndist\n"
  },
  {
    "path": "libs/api-client/src/.npmignore",
    "content": "# empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm"
  },
  {
    "path": "libs/api-client/src/.openapi-generator/FILES",
    "content": ".gitignore\n.npmignore\n.openapi-generator-ignore\napi.ts\napi/admin-api.ts\napi/api-keys-api.ts\napi/audit-api.ts\napi/config-api.ts\napi/docker-registry-api.ts\napi/health-api.ts\napi/jobs-api.ts\napi/object-storage-api.ts\napi/organizations-api.ts\napi/preview-api.ts\napi/regions-api.ts\napi/runners-api.ts\napi/sandbox-api.ts\napi/snapshots-api.ts\napi/toolbox-api.ts\napi/users-api.ts\napi/volumes-api.ts\napi/webhooks-api.ts\napi/workspace-api.ts\nbase.ts\ncommon.ts\nconfiguration.ts\ngit_push.sh\nindex.ts\nmodels/account-provider.ts\nmodels/admin-create-runner.ts\nmodels/announcement.ts\nmodels/api-key-list.ts\nmodels/api-key-response.ts\nmodels/audit-log.ts\nmodels/build-info.ts\nmodels/command.ts\nmodels/completion-context.ts\nmodels/completion-item.ts\nmodels/completion-list.ts\nmodels/compressed-screenshot-response.ts\nmodels/computer-use-start-response.ts\nmodels/computer-use-status-response.ts\nmodels/computer-use-stop-response.ts\nmodels/create-api-key.ts\nmodels/create-build-info.ts\nmodels/create-docker-registry.ts\nmodels/create-linked-account.ts\nmodels/create-organization-invitation.ts\nmodels/create-organization-quota.ts\nmodels/create-organization-role.ts\nmodels/create-organization.ts\nmodels/create-region-response.ts\nmodels/create-region.ts\nmodels/create-runner-response.ts\nmodels/create-runner.ts\nmodels/create-sandbox.ts\nmodels/create-session-request.ts\nmodels/create-snapshot.ts\nmodels/create-user.ts\nmodels/create-volume.ts\nmodels/create-workspace.ts\nmodels/daytona-configuration.ts\nmodels/display-info-response.ts\nmodels/docker-registry.ts\nmodels/download-files.ts\nmodels/execute-request.ts\nmodels/execute-response.ts\nmodels/file-info.ts\nmodels/file-status.ts\nmodels/git-add-request.ts\nmodels/git-branch-request.ts\nmodels/git-checkout-request.ts\nmodels/git-clone-request.ts\nmodels/git-commit-info.ts\nmodels/git-commit-request.ts\nmodels/git-commit-response.ts\nmodels/git-delete-branch-request.ts\nmodels/git-repo-request.ts\nmodels/git-status.ts\nmodels/health-controller-check200-response-info-value.ts\nmodels/health-controller-check200-response.ts\nmodels/health-controller-check503-response.ts\nmodels/index.ts\nmodels/job-status.ts\nmodels/job-type.ts\nmodels/job.ts\nmodels/keyboard-hotkey-request.ts\nmodels/keyboard-press-request.ts\nmodels/keyboard-type-request.ts\nmodels/list-branch-response.ts\nmodels/log-entry.ts\nmodels/lsp-completion-params.ts\nmodels/lsp-document-request.ts\nmodels/lsp-location.ts\nmodels/lsp-server-request.ts\nmodels/lsp-symbol.ts\nmodels/match.ts\nmodels/metric-data-point.ts\nmodels/metric-series.ts\nmodels/metrics-response.ts\nmodels/mouse-click-request.ts\nmodels/mouse-click-response.ts\nmodels/mouse-drag-request.ts\nmodels/mouse-drag-response.ts\nmodels/mouse-move-request.ts\nmodels/mouse-move-response.ts\nmodels/mouse-position.ts\nmodels/mouse-scroll-request.ts\nmodels/mouse-scroll-response.ts\nmodels/oidc-config.ts\nmodels/organization-invitation.ts\nmodels/organization-role.ts\nmodels/organization-sandbox-default-limited-network-egress.ts\nmodels/organization-suspension.ts\nmodels/organization-usage-overview.ts\nmodels/organization-user.ts\nmodels/organization.ts\nmodels/otel-config.ts\nmodels/paginated-audit-logs.ts\nmodels/paginated-jobs.ts\nmodels/paginated-logs.ts\nmodels/paginated-sandboxes.ts\nmodels/paginated-snapshots.ts\nmodels/paginated-traces.ts\nmodels/poll-jobs-response.ts\nmodels/port-preview-url.ts\nmodels/position.ts\nmodels/posthog-config.ts\nmodels/process-errors-response.ts\nmodels/process-logs-response.ts\nmodels/process-restart-response.ts\nmodels/process-status-response.ts\nmodels/project-dir-response.ts\nmodels/pty-create-request.ts\nmodels/pty-create-response.ts\nmodels/pty-list-response.ts\nmodels/pty-resize-request.ts\nmodels/pty-session-info.ts\nmodels/range.ts\nmodels/rate-limit-config.ts\nmodels/rate-limit-entry.ts\nmodels/regenerate-api-key-response.ts\nmodels/region-quota.ts\nmodels/region-screenshot-response.ts\nmodels/region-type.ts\nmodels/region-usage-overview.ts\nmodels/region.ts\nmodels/registry-push-access-dto.ts\nmodels/replace-request.ts\nmodels/replace-result.ts\nmodels/resize-sandbox.ts\nmodels/runner-full.ts\nmodels/runner-health-metrics.ts\nmodels/runner-healthcheck.ts\nmodels/runner-service-health.ts\nmodels/runner-snapshot-dto.ts\nmodels/runner-state.ts\nmodels/runner.ts\nmodels/sandbox-class.ts\nmodels/sandbox-desired-state.ts\nmodels/sandbox-info.ts\nmodels/sandbox-labels.ts\nmodels/sandbox-state.ts\nmodels/sandbox-volume.ts\nmodels/sandbox.ts\nmodels/screenshot-response.ts\nmodels/search-files-response.ts\nmodels/send-webhook-dto.ts\nmodels/session-execute-request.ts\nmodels/session-execute-response.ts\nmodels/session.ts\nmodels/set-snapshot-general-status-dto.ts\nmodels/signed-port-preview-url.ts\nmodels/snapshot-dto.ts\nmodels/snapshot-manager-credentials.ts\nmodels/snapshot-state.ts\nmodels/ssh-access-dto.ts\nmodels/ssh-access-validation-dto.ts\nmodels/storage-access-dto.ts\nmodels/toolbox-proxy-url.ts\nmodels/trace-span.ts\nmodels/trace-summary.ts\nmodels/update-docker-registry.ts\nmodels/update-job-status.ts\nmodels/update-organization-default-region.ts\nmodels/update-organization-invitation.ts\nmodels/update-organization-member-access.ts\nmodels/update-organization-quota.ts\nmodels/update-organization-region-quota.ts\nmodels/update-organization-role.ts\nmodels/update-region.ts\nmodels/update-sandbox-state-dto.ts\nmodels/url.ts\nmodels/user-home-dir-response.ts\nmodels/user-public-key.ts\nmodels/user.ts\nmodels/volume-dto.ts\nmodels/volume-state.ts\nmodels/webhook-app-portal-access.ts\nmodels/webhook-controller-get-status200-response.ts\nmodels/webhook-event.ts\nmodels/webhook-initialization-status.ts\nmodels/windows-response.ts\nmodels/work-dir-response.ts\nmodels/workspace-port-preview-url.ts\nmodels/workspace.ts\n"
  },
  {
    "path": "libs/api-client/src/.openapi-generator/VERSION",
    "content": "7.12.0\n"
  },
  {
    "path": "libs/api-client/src/.openapi-generator-ignore",
    "content": "# OpenAPI Generator Ignore\n# Generated by openapi-generator https://github.com/openapitools/openapi-generator\n\n# Use this file to prevent files from being overwritten by the generator.\n# The patterns follow closely to .gitignore or .dockerignore.\n\n# As an example, the C# client generator defines ApiClient.cs.\n# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:\n#ApiClient.cs\n\n# You can match any string of characters against a directory, file or extension with a single asterisk (*):\n#foo/*/qux\n# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux\n\n# You can recursively match patterns against a directory, file or extension with a double asterisk (**):\n#foo/**/qux\n# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux\n\n# You can also negate patterns with an exclamation (!).\n# For example, you can ignore all files in a docs folder with the file extension .md:\n#docs/*.md\n# Then explicitly reverse the ignore rule for a single file:\n#!docs/README.md\n"
  },
  {
    "path": "libs/api-client/src/api/admin-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { AdminCreateRunner } from '../models';\n// @ts-ignore\nimport type { CreateRunnerResponse } from '../models';\n// @ts-ignore\nimport type { RunnerFull } from '../models';\n// @ts-ignore\nimport type { Sandbox } from '../models';\n/**\n * AdminApi - axios parameter creator\n * @export\n */\nexport const AdminApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Create runner\n         * @param {AdminCreateRunner} adminCreateRunner \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminCreateRunner: async (adminCreateRunner: AdminCreateRunner, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'adminCreateRunner' is not null or undefined\n            assertParamExists('adminCreateRunner', 'adminCreateRunner', adminCreateRunner)\n            const localVarPath = `/admin/runners`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(adminCreateRunner, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete runner\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminDeleteRunner: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('adminDeleteRunner', 'id', id)\n            const localVarPath = `/admin/runners/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminGetRunnerById: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('adminGetRunnerById', 'id', id)\n            const localVarPath = `/admin/runners/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List all runners\n         * @param {string} [regionId] Filter runners by region ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminListRunners: async (regionId?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/admin/runners`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (regionId !== undefined) {\n                localVarQueryParameter['regionId'] = regionId;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Recover sandbox from error state as an admin\n         * @param {string} sandboxId ID of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminRecoverSandbox: async (sandboxId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('adminRecoverSandbox', 'sandboxId', sandboxId)\n            const localVarPath = `/admin/sandbox/{sandboxId}/recover`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update runner scheduling status\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminUpdateRunnerScheduling: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('adminUpdateRunnerScheduling', 'id', id)\n            const localVarPath = `/admin/runners/{id}/scheduling`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * AdminApi - functional programming interface\n * @export\n */\nexport const AdminApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = AdminApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Create runner\n         * @param {AdminCreateRunner} adminCreateRunner \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async adminCreateRunner(adminCreateRunner: AdminCreateRunner, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<CreateRunnerResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.adminCreateRunner(adminCreateRunner, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['AdminApi.adminCreateRunner']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete runner\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async adminDeleteRunner(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.adminDeleteRunner(id, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['AdminApi.adminDeleteRunner']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async adminGetRunnerById(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RunnerFull>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.adminGetRunnerById(id, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['AdminApi.adminGetRunnerById']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List all runners\n         * @param {string} [regionId] Filter runners by region ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async adminListRunners(regionId?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<RunnerFull>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.adminListRunners(regionId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['AdminApi.adminListRunners']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Recover sandbox from error state as an admin\n         * @param {string} sandboxId ID of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async adminRecoverSandbox(sandboxId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.adminRecoverSandbox(sandboxId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['AdminApi.adminRecoverSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update runner scheduling status\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async adminUpdateRunnerScheduling(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.adminUpdateRunnerScheduling(id, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['AdminApi.adminUpdateRunnerScheduling']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * AdminApi - factory interface\n * @export\n */\nexport const AdminApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = AdminApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Create runner\n         * @param {AdminCreateRunner} adminCreateRunner \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminCreateRunner(adminCreateRunner: AdminCreateRunner, options?: RawAxiosRequestConfig): AxiosPromise<CreateRunnerResponse> {\n            return localVarFp.adminCreateRunner(adminCreateRunner, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete runner\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminDeleteRunner(id: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.adminDeleteRunner(id, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminGetRunnerById(id: string, options?: RawAxiosRequestConfig): AxiosPromise<RunnerFull> {\n            return localVarFp.adminGetRunnerById(id, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List all runners\n         * @param {string} [regionId] Filter runners by region ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminListRunners(regionId?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<RunnerFull>> {\n            return localVarFp.adminListRunners(regionId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Recover sandbox from error state as an admin\n         * @param {string} sandboxId ID of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminRecoverSandbox(sandboxId: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.adminRecoverSandbox(sandboxId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update runner scheduling status\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        adminUpdateRunnerScheduling(id: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.adminUpdateRunnerScheduling(id, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * AdminApi - object-oriented interface\n * @export\n * @class AdminApi\n * @extends {BaseAPI}\n */\nexport class AdminApi extends BaseAPI {\n    /**\n     * \n     * @summary Create runner\n     * @param {AdminCreateRunner} adminCreateRunner \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof AdminApi\n     */\n    public adminCreateRunner(adminCreateRunner: AdminCreateRunner, options?: RawAxiosRequestConfig) {\n        return AdminApiFp(this.configuration).adminCreateRunner(adminCreateRunner, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete runner\n     * @param {string} id Runner ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof AdminApi\n     */\n    public adminDeleteRunner(id: string, options?: RawAxiosRequestConfig) {\n        return AdminApiFp(this.configuration).adminDeleteRunner(id, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get runner by ID\n     * @param {string} id Runner ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof AdminApi\n     */\n    public adminGetRunnerById(id: string, options?: RawAxiosRequestConfig) {\n        return AdminApiFp(this.configuration).adminGetRunnerById(id, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List all runners\n     * @param {string} [regionId] Filter runners by region ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof AdminApi\n     */\n    public adminListRunners(regionId?: string, options?: RawAxiosRequestConfig) {\n        return AdminApiFp(this.configuration).adminListRunners(regionId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Recover sandbox from error state as an admin\n     * @param {string} sandboxId ID of the sandbox\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof AdminApi\n     */\n    public adminRecoverSandbox(sandboxId: string, options?: RawAxiosRequestConfig) {\n        return AdminApiFp(this.configuration).adminRecoverSandbox(sandboxId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update runner scheduling status\n     * @param {string} id \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof AdminApi\n     */\n    public adminUpdateRunnerScheduling(id: string, options?: RawAxiosRequestConfig) {\n        return AdminApiFp(this.configuration).adminUpdateRunnerScheduling(id, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/api-keys-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { ApiKeyList } from '../models';\n// @ts-ignore\nimport type { ApiKeyResponse } from '../models';\n// @ts-ignore\nimport type { CreateApiKey } from '../models';\n/**\n * ApiKeysApi - axios parameter creator\n * @export\n */\nexport const ApiKeysApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Create API key\n         * @param {CreateApiKey} createApiKey \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createApiKey: async (createApiKey: CreateApiKey, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createApiKey' is not null or undefined\n            assertParamExists('createApiKey', 'createApiKey', createApiKey)\n            const localVarPath = `/api-keys`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createApiKey, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete API key\n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteApiKey: async (name: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'name' is not null or undefined\n            assertParamExists('deleteApiKey', 'name', name)\n            const localVarPath = `/api-keys/{name}`\n                .replace(`{${\"name\"}}`, encodeURIComponent(String(name)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete API key for user\n         * @param {string} userId \n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteApiKeyForUser: async (userId: string, name: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'userId' is not null or undefined\n            assertParamExists('deleteApiKeyForUser', 'userId', userId)\n            // verify required parameter 'name' is not null or undefined\n            assertParamExists('deleteApiKeyForUser', 'name', name)\n            const localVarPath = `/api-keys/{userId}/{name}`\n                .replace(`{${\"userId\"}}`, encodeURIComponent(String(userId)))\n                .replace(`{${\"name\"}}`, encodeURIComponent(String(name)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get API key\n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getApiKey: async (name: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'name' is not null or undefined\n            assertParamExists('getApiKey', 'name', name)\n            const localVarPath = `/api-keys/{name}`\n                .replace(`{${\"name\"}}`, encodeURIComponent(String(name)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get current API key\\'s details\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getCurrentApiKey: async (xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/api-keys/current`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List API keys\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listApiKeys: async (xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/api-keys`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * ApiKeysApi - functional programming interface\n * @export\n */\nexport const ApiKeysApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = ApiKeysApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Create API key\n         * @param {CreateApiKey} createApiKey \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createApiKey(createApiKey: CreateApiKey, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ApiKeyResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createApiKey(createApiKey, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ApiKeysApi.createApiKey']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete API key\n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteApiKey(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteApiKey(name, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ApiKeysApi.deleteApiKey']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete API key for user\n         * @param {string} userId \n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteApiKeyForUser(userId: string, name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteApiKeyForUser(userId, name, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ApiKeysApi.deleteApiKeyForUser']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get API key\n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getApiKey(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ApiKeyList>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getApiKey(name, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ApiKeysApi.getApiKey']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get current API key\\'s details\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getCurrentApiKey(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ApiKeyList>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getCurrentApiKey(xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ApiKeysApi.getCurrentApiKey']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List API keys\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listApiKeys(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ApiKeyList>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listApiKeys(xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ApiKeysApi.listApiKeys']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * ApiKeysApi - factory interface\n * @export\n */\nexport const ApiKeysApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = ApiKeysApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Create API key\n         * @param {CreateApiKey} createApiKey \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createApiKey(createApiKey: CreateApiKey, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ApiKeyResponse> {\n            return localVarFp.createApiKey(createApiKey, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete API key\n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteApiKey(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteApiKey(name, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete API key for user\n         * @param {string} userId \n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteApiKeyForUser(userId: string, name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteApiKeyForUser(userId, name, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get API key\n         * @param {string} name \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getApiKey(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ApiKeyList> {\n            return localVarFp.getApiKey(name, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get current API key\\'s details\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getCurrentApiKey(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ApiKeyList> {\n            return localVarFp.getCurrentApiKey(xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List API keys\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listApiKeys(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<ApiKeyList>> {\n            return localVarFp.listApiKeys(xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * ApiKeysApi - object-oriented interface\n * @export\n * @class ApiKeysApi\n * @extends {BaseAPI}\n */\nexport class ApiKeysApi extends BaseAPI {\n    /**\n     * \n     * @summary Create API key\n     * @param {CreateApiKey} createApiKey \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof ApiKeysApi\n     */\n    public createApiKey(createApiKey: CreateApiKey, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ApiKeysApiFp(this.configuration).createApiKey(createApiKey, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete API key\n     * @param {string} name \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof ApiKeysApi\n     */\n    public deleteApiKey(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ApiKeysApiFp(this.configuration).deleteApiKey(name, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete API key for user\n     * @param {string} userId \n     * @param {string} name \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof ApiKeysApi\n     */\n    public deleteApiKeyForUser(userId: string, name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ApiKeysApiFp(this.configuration).deleteApiKeyForUser(userId, name, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get API key\n     * @param {string} name \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof ApiKeysApi\n     */\n    public getApiKey(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ApiKeysApiFp(this.configuration).getApiKey(name, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get current API key\\'s details\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof ApiKeysApi\n     */\n    public getCurrentApiKey(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ApiKeysApiFp(this.configuration).getCurrentApiKey(xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List API keys\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof ApiKeysApi\n     */\n    public listApiKeys(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ApiKeysApiFp(this.configuration).listApiKeys(xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/audit-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { PaginatedAuditLogs } from '../models';\n/**\n * AuditApi - axios parameter creator\n * @export\n */\nexport const AuditApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Get all audit logs\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {Date} [from] From date (ISO 8601 format)\n         * @param {Date} [to] To date (ISO 8601 format)\n         * @param {string} [nextToken] Token for cursor-based pagination. When provided, takes precedence over page parameter.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getAllAuditLogs: async (page?: number, limit?: number, from?: Date, to?: Date, nextToken?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/audit`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (page !== undefined) {\n                localVarQueryParameter['page'] = page;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = (from as any instanceof Date) ?\n                    (from as any).toISOString() :\n                    from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = (to as any instanceof Date) ?\n                    (to as any).toISOString() :\n                    to;\n            }\n\n            if (nextToken !== undefined) {\n                localVarQueryParameter['nextToken'] = nextToken;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get audit logs for organization\n         * @param {string} organizationId Organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {Date} [from] From date (ISO 8601 format)\n         * @param {Date} [to] To date (ISO 8601 format)\n         * @param {string} [nextToken] Token for cursor-based pagination. When provided, takes precedence over page parameter.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationAuditLogs: async (organizationId: string, page?: number, limit?: number, from?: Date, to?: Date, nextToken?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('getOrganizationAuditLogs', 'organizationId', organizationId)\n            const localVarPath = `/audit/organizations/{organizationId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (page !== undefined) {\n                localVarQueryParameter['page'] = page;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = (from as any instanceof Date) ?\n                    (from as any).toISOString() :\n                    from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = (to as any instanceof Date) ?\n                    (to as any).toISOString() :\n                    to;\n            }\n\n            if (nextToken !== undefined) {\n                localVarQueryParameter['nextToken'] = nextToken;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * AuditApi - functional programming interface\n * @export\n */\nexport const AuditApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = AuditApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Get all audit logs\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {Date} [from] From date (ISO 8601 format)\n         * @param {Date} [to] To date (ISO 8601 format)\n         * @param {string} [nextToken] Token for cursor-based pagination. When provided, takes precedence over page parameter.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getAllAuditLogs(page?: number, limit?: number, from?: Date, to?: Date, nextToken?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedAuditLogs>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAuditLogs(page, limit, from, to, nextToken, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['AuditApi.getAllAuditLogs']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get audit logs for organization\n         * @param {string} organizationId Organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {Date} [from] From date (ISO 8601 format)\n         * @param {Date} [to] To date (ISO 8601 format)\n         * @param {string} [nextToken] Token for cursor-based pagination. When provided, takes precedence over page parameter.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getOrganizationAuditLogs(organizationId: string, page?: number, limit?: number, from?: Date, to?: Date, nextToken?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedAuditLogs>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getOrganizationAuditLogs(organizationId, page, limit, from, to, nextToken, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['AuditApi.getOrganizationAuditLogs']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * AuditApi - factory interface\n * @export\n */\nexport const AuditApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = AuditApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Get all audit logs\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {Date} [from] From date (ISO 8601 format)\n         * @param {Date} [to] To date (ISO 8601 format)\n         * @param {string} [nextToken] Token for cursor-based pagination. When provided, takes precedence over page parameter.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getAllAuditLogs(page?: number, limit?: number, from?: Date, to?: Date, nextToken?: string, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedAuditLogs> {\n            return localVarFp.getAllAuditLogs(page, limit, from, to, nextToken, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get audit logs for organization\n         * @param {string} organizationId Organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {Date} [from] From date (ISO 8601 format)\n         * @param {Date} [to] To date (ISO 8601 format)\n         * @param {string} [nextToken] Token for cursor-based pagination. When provided, takes precedence over page parameter.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationAuditLogs(organizationId: string, page?: number, limit?: number, from?: Date, to?: Date, nextToken?: string, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedAuditLogs> {\n            return localVarFp.getOrganizationAuditLogs(organizationId, page, limit, from, to, nextToken, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * AuditApi - object-oriented interface\n * @export\n * @class AuditApi\n * @extends {BaseAPI}\n */\nexport class AuditApi extends BaseAPI {\n    /**\n     * \n     * @summary Get all audit logs\n     * @param {number} [page] Page number of the results\n     * @param {number} [limit] Number of results per page\n     * @param {Date} [from] From date (ISO 8601 format)\n     * @param {Date} [to] To date (ISO 8601 format)\n     * @param {string} [nextToken] Token for cursor-based pagination. When provided, takes precedence over page parameter.\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof AuditApi\n     */\n    public getAllAuditLogs(page?: number, limit?: number, from?: Date, to?: Date, nextToken?: string, options?: RawAxiosRequestConfig) {\n        return AuditApiFp(this.configuration).getAllAuditLogs(page, limit, from, to, nextToken, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get audit logs for organization\n     * @param {string} organizationId Organization ID\n     * @param {number} [page] Page number of the results\n     * @param {number} [limit] Number of results per page\n     * @param {Date} [from] From date (ISO 8601 format)\n     * @param {Date} [to] To date (ISO 8601 format)\n     * @param {string} [nextToken] Token for cursor-based pagination. When provided, takes precedence over page parameter.\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof AuditApi\n     */\n    public getOrganizationAuditLogs(organizationId: string, page?: number, limit?: number, from?: Date, to?: Date, nextToken?: string, options?: RawAxiosRequestConfig) {\n        return AuditApiFp(this.configuration).getOrganizationAuditLogs(organizationId, page, limit, from, to, nextToken, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/config-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { DaytonaConfiguration } from '../models';\n/**\n * ConfigApi - axios parameter creator\n * @export\n */\nexport const ConfigApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Get config\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        configControllerGetConfig: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/config`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * ConfigApi - functional programming interface\n * @export\n */\nexport const ConfigApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = ConfigApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Get config\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async configControllerGetConfig(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<DaytonaConfiguration>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.configControllerGetConfig(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ConfigApi.configControllerGetConfig']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * ConfigApi - factory interface\n * @export\n */\nexport const ConfigApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = ConfigApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Get config\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        configControllerGetConfig(options?: RawAxiosRequestConfig): AxiosPromise<DaytonaConfiguration> {\n            return localVarFp.configControllerGetConfig(options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * ConfigApi - object-oriented interface\n * @export\n * @class ConfigApi\n * @extends {BaseAPI}\n */\nexport class ConfigApi extends BaseAPI {\n    /**\n     * \n     * @summary Get config\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof ConfigApi\n     */\n    public configControllerGetConfig(options?: RawAxiosRequestConfig) {\n        return ConfigApiFp(this.configuration).configControllerGetConfig(options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/docker-registry-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { CreateDockerRegistry } from '../models';\n// @ts-ignore\nimport type { DockerRegistry } from '../models';\n// @ts-ignore\nimport type { RegistryPushAccessDto } from '../models';\n// @ts-ignore\nimport type { UpdateDockerRegistry } from '../models';\n/**\n * DockerRegistryApi - axios parameter creator\n * @export\n */\nexport const DockerRegistryApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Create registry\n         * @param {CreateDockerRegistry} createDockerRegistry \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createRegistry: async (createDockerRegistry: CreateDockerRegistry, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createDockerRegistry' is not null or undefined\n            assertParamExists('createRegistry', 'createDockerRegistry', createDockerRegistry)\n            const localVarPath = `/docker-registry`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createDockerRegistry, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteRegistry: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('deleteRegistry', 'id', id)\n            const localVarPath = `/docker-registry/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRegistry: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('getRegistry', 'id', id)\n            const localVarPath = `/docker-registry/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get temporary registry access for pushing snapshots\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [regionId] ID of the region where the snapshot will be available (defaults to organization default region)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getTransientPushAccess: async (xDaytonaOrganizationID?: string, regionId?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/docker-registry/registry-push-access`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (regionId !== undefined) {\n                localVarQueryParameter['regionId'] = regionId;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List registries\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listRegistries: async (xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/docker-registry`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Set default registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setDefaultRegistry: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('setDefaultRegistry', 'id', id)\n            const localVarPath = `/docker-registry/{id}/set-default`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update registry\n         * @param {string} id ID of the docker registry\n         * @param {UpdateDockerRegistry} updateDockerRegistry \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateRegistry: async (id: string, updateDockerRegistry: UpdateDockerRegistry, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('updateRegistry', 'id', id)\n            // verify required parameter 'updateDockerRegistry' is not null or undefined\n            assertParamExists('updateRegistry', 'updateDockerRegistry', updateDockerRegistry)\n            const localVarPath = `/docker-registry/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateDockerRegistry, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * DockerRegistryApi - functional programming interface\n * @export\n */\nexport const DockerRegistryApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = DockerRegistryApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Create registry\n         * @param {CreateDockerRegistry} createDockerRegistry \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createRegistry(createDockerRegistry: CreateDockerRegistry, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<DockerRegistry>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createRegistry(createDockerRegistry, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['DockerRegistryApi.createRegistry']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteRegistry(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['DockerRegistryApi.deleteRegistry']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<DockerRegistry>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getRegistry(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['DockerRegistryApi.getRegistry']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get temporary registry access for pushing snapshots\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [regionId] ID of the region where the snapshot will be available (defaults to organization default region)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getTransientPushAccess(xDaytonaOrganizationID?: string, regionId?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RegistryPushAccessDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getTransientPushAccess(xDaytonaOrganizationID, regionId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['DockerRegistryApi.getTransientPushAccess']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List registries\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listRegistries(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<DockerRegistry>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listRegistries(xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['DockerRegistryApi.listRegistries']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Set default registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async setDefaultRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<DockerRegistry>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setDefaultRegistry(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['DockerRegistryApi.setDefaultRegistry']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update registry\n         * @param {string} id ID of the docker registry\n         * @param {UpdateDockerRegistry} updateDockerRegistry \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateRegistry(id: string, updateDockerRegistry: UpdateDockerRegistry, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<DockerRegistry>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateRegistry(id, updateDockerRegistry, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['DockerRegistryApi.updateRegistry']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * DockerRegistryApi - factory interface\n * @export\n */\nexport const DockerRegistryApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = DockerRegistryApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Create registry\n         * @param {CreateDockerRegistry} createDockerRegistry \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createRegistry(createDockerRegistry: CreateDockerRegistry, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<DockerRegistry> {\n            return localVarFp.createRegistry(createDockerRegistry, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteRegistry(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<DockerRegistry> {\n            return localVarFp.getRegistry(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get temporary registry access for pushing snapshots\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [regionId] ID of the region where the snapshot will be available (defaults to organization default region)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getTransientPushAccess(xDaytonaOrganizationID?: string, regionId?: string, options?: RawAxiosRequestConfig): AxiosPromise<RegistryPushAccessDto> {\n            return localVarFp.getTransientPushAccess(xDaytonaOrganizationID, regionId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List registries\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listRegistries(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<DockerRegistry>> {\n            return localVarFp.listRegistries(xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Set default registry\n         * @param {string} id ID of the docker registry\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setDefaultRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<DockerRegistry> {\n            return localVarFp.setDefaultRegistry(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update registry\n         * @param {string} id ID of the docker registry\n         * @param {UpdateDockerRegistry} updateDockerRegistry \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateRegistry(id: string, updateDockerRegistry: UpdateDockerRegistry, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<DockerRegistry> {\n            return localVarFp.updateRegistry(id, updateDockerRegistry, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * DockerRegistryApi - object-oriented interface\n * @export\n * @class DockerRegistryApi\n * @extends {BaseAPI}\n */\nexport class DockerRegistryApi extends BaseAPI {\n    /**\n     * \n     * @summary Create registry\n     * @param {CreateDockerRegistry} createDockerRegistry \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof DockerRegistryApi\n     */\n    public createRegistry(createDockerRegistry: CreateDockerRegistry, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return DockerRegistryApiFp(this.configuration).createRegistry(createDockerRegistry, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete registry\n     * @param {string} id ID of the docker registry\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof DockerRegistryApi\n     */\n    public deleteRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return DockerRegistryApiFp(this.configuration).deleteRegistry(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get registry\n     * @param {string} id ID of the docker registry\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof DockerRegistryApi\n     */\n    public getRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return DockerRegistryApiFp(this.configuration).getRegistry(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get temporary registry access for pushing snapshots\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {string} [regionId] ID of the region where the snapshot will be available (defaults to organization default region)\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof DockerRegistryApi\n     */\n    public getTransientPushAccess(xDaytonaOrganizationID?: string, regionId?: string, options?: RawAxiosRequestConfig) {\n        return DockerRegistryApiFp(this.configuration).getTransientPushAccess(xDaytonaOrganizationID, regionId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List registries\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof DockerRegistryApi\n     */\n    public listRegistries(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return DockerRegistryApiFp(this.configuration).listRegistries(xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Set default registry\n     * @param {string} id ID of the docker registry\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof DockerRegistryApi\n     */\n    public setDefaultRegistry(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return DockerRegistryApiFp(this.configuration).setDefaultRegistry(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update registry\n     * @param {string} id ID of the docker registry\n     * @param {UpdateDockerRegistry} updateDockerRegistry \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof DockerRegistryApi\n     */\n    public updateRegistry(id: string, updateDockerRegistry: UpdateDockerRegistry, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return DockerRegistryApiFp(this.configuration).updateRegistry(id, updateDockerRegistry, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/health-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { HealthControllerCheck200Response } from '../models';\n// @ts-ignore\nimport type { HealthControllerCheck503Response } from '../models';\n/**\n * HealthApi - axios parameter creator\n * @export\n */\nexport const HealthApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        healthControllerCheck: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/health/ready`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        healthControllerLive: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/health`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * HealthApi - functional programming interface\n * @export\n */\nexport const HealthApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = HealthApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async healthControllerCheck(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<HealthControllerCheck200Response>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.healthControllerCheck(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['HealthApi.healthControllerCheck']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async healthControllerLive(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.healthControllerLive(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['HealthApi.healthControllerLive']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * HealthApi - factory interface\n * @export\n */\nexport const HealthApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = HealthApiFp(configuration)\n    return {\n        /**\n         * \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        healthControllerCheck(options?: RawAxiosRequestConfig): AxiosPromise<HealthControllerCheck200Response> {\n            return localVarFp.healthControllerCheck(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        healthControllerLive(options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.healthControllerLive(options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * HealthApi - object-oriented interface\n * @export\n * @class HealthApi\n * @extends {BaseAPI}\n */\nexport class HealthApi extends BaseAPI {\n    /**\n     * \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof HealthApi\n     */\n    public healthControllerCheck(options?: RawAxiosRequestConfig) {\n        return HealthApiFp(this.configuration).healthControllerCheck(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof HealthApi\n     */\n    public healthControllerLive(options?: RawAxiosRequestConfig) {\n        return HealthApiFp(this.configuration).healthControllerLive(options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/jobs-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { Job } from '../models';\n// @ts-ignore\nimport type { JobStatus } from '../models';\n// @ts-ignore\nimport type { PaginatedJobs } from '../models';\n// @ts-ignore\nimport type { PollJobsResponse } from '../models';\n// @ts-ignore\nimport type { UpdateJobStatus } from '../models';\n/**\n * JobsApi - axios parameter creator\n * @export\n */\nexport const JobsApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Get job details\n         * @param {string} jobId ID of the job\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getJob: async (jobId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'jobId' is not null or undefined\n            assertParamExists('getJob', 'jobId', jobId)\n            const localVarPath = `/jobs/{jobId}`\n                .replace(`{${\"jobId\"}}`, encodeURIComponent(String(jobId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Returns a paginated list of jobs for the runner, optionally filtered by status.\n         * @summary List jobs for the runner\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Maximum number of jobs to return (default: 100, max: 500)\n         * @param {JobStatus} [status] Filter jobs by status\n         * @param {number} [offset] Number of jobs to skip for pagination (default: 0)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listJobs: async (page?: number, limit?: number, status?: JobStatus, offset?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/jobs`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (page !== undefined) {\n                localVarQueryParameter['page'] = page;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n            if (status !== undefined) {\n                localVarQueryParameter['status'] = status;\n            }\n\n            if (offset !== undefined) {\n                localVarQueryParameter['offset'] = offset;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Long poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n         * @summary Long poll for jobs\n         * @param {number} [timeout] Timeout in seconds for long polling (default: 30, max: 60)\n         * @param {number} [limit] Maximum number of jobs to return (default: 10, max: 100)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        pollJobs: async (timeout?: number, limit?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/jobs/poll`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (timeout !== undefined) {\n                localVarQueryParameter['timeout'] = timeout;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update job status\n         * @param {string} jobId ID of the job\n         * @param {UpdateJobStatus} updateJobStatus \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateJobStatus: async (jobId: string, updateJobStatus: UpdateJobStatus, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'jobId' is not null or undefined\n            assertParamExists('updateJobStatus', 'jobId', jobId)\n            // verify required parameter 'updateJobStatus' is not null or undefined\n            assertParamExists('updateJobStatus', 'updateJobStatus', updateJobStatus)\n            const localVarPath = `/jobs/{jobId}/status`\n                .replace(`{${\"jobId\"}}`, encodeURIComponent(String(jobId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateJobStatus, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * JobsApi - functional programming interface\n * @export\n */\nexport const JobsApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = JobsApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Get job details\n         * @param {string} jobId ID of the job\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getJob(jobId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Job>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getJob(jobId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['JobsApi.getJob']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Returns a paginated list of jobs for the runner, optionally filtered by status.\n         * @summary List jobs for the runner\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Maximum number of jobs to return (default: 100, max: 500)\n         * @param {JobStatus} [status] Filter jobs by status\n         * @param {number} [offset] Number of jobs to skip for pagination (default: 0)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listJobs(page?: number, limit?: number, status?: JobStatus, offset?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedJobs>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listJobs(page, limit, status, offset, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['JobsApi.listJobs']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Long poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n         * @summary Long poll for jobs\n         * @param {number} [timeout] Timeout in seconds for long polling (default: 30, max: 60)\n         * @param {number} [limit] Maximum number of jobs to return (default: 10, max: 100)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async pollJobs(timeout?: number, limit?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PollJobsResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.pollJobs(timeout, limit, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['JobsApi.pollJobs']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update job status\n         * @param {string} jobId ID of the job\n         * @param {UpdateJobStatus} updateJobStatus \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateJobStatus(jobId: string, updateJobStatus: UpdateJobStatus, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Job>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateJobStatus(jobId, updateJobStatus, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['JobsApi.updateJobStatus']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * JobsApi - factory interface\n * @export\n */\nexport const JobsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = JobsApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Get job details\n         * @param {string} jobId ID of the job\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getJob(jobId: string, options?: RawAxiosRequestConfig): AxiosPromise<Job> {\n            return localVarFp.getJob(jobId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Returns a paginated list of jobs for the runner, optionally filtered by status.\n         * @summary List jobs for the runner\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Maximum number of jobs to return (default: 100, max: 500)\n         * @param {JobStatus} [status] Filter jobs by status\n         * @param {number} [offset] Number of jobs to skip for pagination (default: 0)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listJobs(page?: number, limit?: number, status?: JobStatus, offset?: number, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedJobs> {\n            return localVarFp.listJobs(page, limit, status, offset, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Long poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n         * @summary Long poll for jobs\n         * @param {number} [timeout] Timeout in seconds for long polling (default: 30, max: 60)\n         * @param {number} [limit] Maximum number of jobs to return (default: 10, max: 100)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        pollJobs(timeout?: number, limit?: number, options?: RawAxiosRequestConfig): AxiosPromise<PollJobsResponse> {\n            return localVarFp.pollJobs(timeout, limit, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update job status\n         * @param {string} jobId ID of the job\n         * @param {UpdateJobStatus} updateJobStatus \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateJobStatus(jobId: string, updateJobStatus: UpdateJobStatus, options?: RawAxiosRequestConfig): AxiosPromise<Job> {\n            return localVarFp.updateJobStatus(jobId, updateJobStatus, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * JobsApi - object-oriented interface\n * @export\n * @class JobsApi\n * @extends {BaseAPI}\n */\nexport class JobsApi extends BaseAPI {\n    /**\n     * \n     * @summary Get job details\n     * @param {string} jobId ID of the job\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof JobsApi\n     */\n    public getJob(jobId: string, options?: RawAxiosRequestConfig) {\n        return JobsApiFp(this.configuration).getJob(jobId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Returns a paginated list of jobs for the runner, optionally filtered by status.\n     * @summary List jobs for the runner\n     * @param {number} [page] Page number of the results\n     * @param {number} [limit] Maximum number of jobs to return (default: 100, max: 500)\n     * @param {JobStatus} [status] Filter jobs by status\n     * @param {number} [offset] Number of jobs to skip for pagination (default: 0)\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof JobsApi\n     */\n    public listJobs(page?: number, limit?: number, status?: JobStatus, offset?: number, options?: RawAxiosRequestConfig) {\n        return JobsApiFp(this.configuration).listJobs(page, limit, status, offset, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Long poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n     * @summary Long poll for jobs\n     * @param {number} [timeout] Timeout in seconds for long polling (default: 30, max: 60)\n     * @param {number} [limit] Maximum number of jobs to return (default: 10, max: 100)\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof JobsApi\n     */\n    public pollJobs(timeout?: number, limit?: number, options?: RawAxiosRequestConfig) {\n        return JobsApiFp(this.configuration).pollJobs(timeout, limit, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update job status\n     * @param {string} jobId ID of the job\n     * @param {UpdateJobStatus} updateJobStatus \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof JobsApi\n     */\n    public updateJobStatus(jobId: string, updateJobStatus: UpdateJobStatus, options?: RawAxiosRequestConfig) {\n        return JobsApiFp(this.configuration).updateJobStatus(jobId, updateJobStatus, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/object-storage-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { StorageAccessDto } from '../models';\n/**\n * ObjectStorageApi - axios parameter creator\n * @export\n */\nexport const ObjectStorageApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Get temporary storage access for pushing objects\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getPushAccess: async (xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/object-storage/push-access`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * ObjectStorageApi - functional programming interface\n * @export\n */\nexport const ObjectStorageApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = ObjectStorageApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Get temporary storage access for pushing objects\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getPushAccess(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<StorageAccessDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getPushAccess(xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ObjectStorageApi.getPushAccess']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * ObjectStorageApi - factory interface\n * @export\n */\nexport const ObjectStorageApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = ObjectStorageApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Get temporary storage access for pushing objects\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getPushAccess(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<StorageAccessDto> {\n            return localVarFp.getPushAccess(xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * ObjectStorageApi - object-oriented interface\n * @export\n * @class ObjectStorageApi\n * @extends {BaseAPI}\n */\nexport class ObjectStorageApi extends BaseAPI {\n    /**\n     * \n     * @summary Get temporary storage access for pushing objects\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof ObjectStorageApi\n     */\n    public getPushAccess(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ObjectStorageApiFp(this.configuration).getPushAccess(xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/organizations-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { CreateOrganization } from '../models';\n// @ts-ignore\nimport type { CreateOrganizationInvitation } from '../models';\n// @ts-ignore\nimport type { CreateOrganizationRole } from '../models';\n// @ts-ignore\nimport type { CreateRegion } from '../models';\n// @ts-ignore\nimport type { CreateRegionResponse } from '../models';\n// @ts-ignore\nimport type { Organization } from '../models';\n// @ts-ignore\nimport type { OrganizationInvitation } from '../models';\n// @ts-ignore\nimport type { OrganizationRole } from '../models';\n// @ts-ignore\nimport type { OrganizationSandboxDefaultLimitedNetworkEgress } from '../models';\n// @ts-ignore\nimport type { OrganizationSuspension } from '../models';\n// @ts-ignore\nimport type { OrganizationUsageOverview } from '../models';\n// @ts-ignore\nimport type { OrganizationUser } from '../models';\n// @ts-ignore\nimport type { OtelConfig } from '../models';\n// @ts-ignore\nimport type { RegenerateApiKeyResponse } from '../models';\n// @ts-ignore\nimport type { Region } from '../models';\n// @ts-ignore\nimport type { RegionQuota } from '../models';\n// @ts-ignore\nimport type { SnapshotManagerCredentials } from '../models';\n// @ts-ignore\nimport type { UpdateOrganizationDefaultRegion } from '../models';\n// @ts-ignore\nimport type { UpdateOrganizationInvitation } from '../models';\n// @ts-ignore\nimport type { UpdateOrganizationMemberAccess } from '../models';\n// @ts-ignore\nimport type { UpdateOrganizationQuota } from '../models';\n// @ts-ignore\nimport type { UpdateOrganizationRegionQuota } from '../models';\n// @ts-ignore\nimport type { UpdateOrganizationRole } from '../models';\n// @ts-ignore\nimport type { UpdateRegion } from '../models';\n/**\n * OrganizationsApi - axios parameter creator\n * @export\n */\nexport const OrganizationsApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Accept organization invitation\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        acceptOrganizationInvitation: async (invitationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'invitationId' is not null or undefined\n            assertParamExists('acceptOrganizationInvitation', 'invitationId', invitationId)\n            const localVarPath = `/organizations/invitations/{invitationId}/accept`\n                .replace(`{${\"invitationId\"}}`, encodeURIComponent(String(invitationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Cancel organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        cancelOrganizationInvitation: async (organizationId: string, invitationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('cancelOrganizationInvitation', 'organizationId', organizationId)\n            // verify required parameter 'invitationId' is not null or undefined\n            assertParamExists('cancelOrganizationInvitation', 'invitationId', invitationId)\n            const localVarPath = `/organizations/{organizationId}/invitations/{invitationId}/cancel`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"invitationId\"}}`, encodeURIComponent(String(invitationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Create organization\n         * @param {CreateOrganization} createOrganization \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createOrganization: async (createOrganization: CreateOrganization, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createOrganization' is not null or undefined\n            assertParamExists('createOrganization', 'createOrganization', createOrganization)\n            const localVarPath = `/organizations`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createOrganization, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Create organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {CreateOrganizationInvitation} createOrganizationInvitation \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createOrganizationInvitation: async (organizationId: string, createOrganizationInvitation: CreateOrganizationInvitation, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('createOrganizationInvitation', 'organizationId', organizationId)\n            // verify required parameter 'createOrganizationInvitation' is not null or undefined\n            assertParamExists('createOrganizationInvitation', 'createOrganizationInvitation', createOrganizationInvitation)\n            const localVarPath = `/organizations/{organizationId}/invitations`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createOrganizationInvitation, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Create organization role\n         * @param {string} organizationId Organization ID\n         * @param {CreateOrganizationRole} createOrganizationRole \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createOrganizationRole: async (organizationId: string, createOrganizationRole: CreateOrganizationRole, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('createOrganizationRole', 'organizationId', organizationId)\n            // verify required parameter 'createOrganizationRole' is not null or undefined\n            assertParamExists('createOrganizationRole', 'createOrganizationRole', createOrganizationRole)\n            const localVarPath = `/organizations/{organizationId}/roles`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createOrganizationRole, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Create a new region\n         * @param {CreateRegion} createRegion \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createRegion: async (createRegion: CreateRegion, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createRegion' is not null or undefined\n            assertParamExists('createRegion', 'createRegion', createRegion)\n            const localVarPath = `/regions`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createRegion, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Decline organization invitation\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        declineOrganizationInvitation: async (invitationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'invitationId' is not null or undefined\n            assertParamExists('declineOrganizationInvitation', 'invitationId', invitationId)\n            const localVarPath = `/organizations/invitations/{invitationId}/decline`\n                .replace(`{${\"invitationId\"}}`, encodeURIComponent(String(invitationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteOrganization: async (organizationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('deleteOrganization', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete organization member\n         * @param {string} organizationId Organization ID\n         * @param {string} userId User ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteOrganizationMember: async (organizationId: string, userId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('deleteOrganizationMember', 'organizationId', organizationId)\n            // verify required parameter 'userId' is not null or undefined\n            assertParamExists('deleteOrganizationMember', 'userId', userId)\n            const localVarPath = `/organizations/{organizationId}/users/{userId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"userId\"}}`, encodeURIComponent(String(userId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete organization role\n         * @param {string} organizationId Organization ID\n         * @param {string} roleId Role ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteOrganizationRole: async (organizationId: string, roleId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('deleteOrganizationRole', 'organizationId', organizationId)\n            // verify required parameter 'roleId' is not null or undefined\n            assertParamExists('deleteOrganizationRole', 'roleId', roleId)\n            const localVarPath = `/organizations/{organizationId}/roles/{roleId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"roleId\"}}`, encodeURIComponent(String(roleId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteRegion: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('deleteRegion', 'id', id)\n            const localVarPath = `/regions/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get organization by ID\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganization: async (organizationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('getOrganization', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get organization by sandbox ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationBySandboxId: async (sandboxId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getOrganizationBySandboxId', 'sandboxId', sandboxId)\n            const localVarPath = `/organizations/by-sandbox-id/{sandboxId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get count of organization invitations for authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationInvitationsCountForAuthenticatedUser: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/organizations/invitations/count`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get organization OTEL config by sandbox auth token\n         * @param {string} authToken Sandbox Auth Token\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationOtelConfigBySandboxAuthToken: async (authToken: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'authToken' is not null or undefined\n            assertParamExists('getOrganizationOtelConfigBySandboxAuthToken', 'authToken', authToken)\n            const localVarPath = `/organizations/otel-config/by-sandbox-auth-token/{authToken}`\n                .replace(`{${\"authToken\"}}`, encodeURIComponent(String(authToken)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get organization current usage overview\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationUsageOverview: async (organizationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('getOrganizationUsageOverview', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}/usage`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get region by ID\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRegionById: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('getRegionById', 'id', id)\n            const localVarPath = `/regions/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get region quota by sandbox ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRegionQuotaBySandboxId: async (sandboxId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getRegionQuotaBySandboxId', 'sandboxId', sandboxId)\n            const localVarPath = `/organizations/region-quota/by-sandbox-id/{sandboxId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Leave organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        leaveOrganization: async (organizationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('leaveOrganization', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}/leave`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List all available regions for the organization\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listAvailableRegions: async (xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/regions`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List pending organization invitations\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizationInvitations: async (organizationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('listOrganizationInvitations', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}/invitations`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List organization invitations for authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizationInvitationsForAuthenticatedUser: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/organizations/invitations`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List organization members\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizationMembers: async (organizationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('listOrganizationMembers', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}/users`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List organization roles\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizationRoles: async (organizationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('listOrganizationRoles', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}/roles`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List organizations\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizations: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/organizations`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Regenerate proxy API key for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        regenerateProxyApiKey: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('regenerateProxyApiKey', 'id', id)\n            const localVarPath = `/regions/{id}/regenerate-proxy-api-key`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Regenerate snapshot manager credentials for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        regenerateSnapshotManagerCredentials: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('regenerateSnapshotManagerCredentials', 'id', id)\n            const localVarPath = `/regions/{id}/regenerate-snapshot-manager-credentials`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Regenerate SSH gateway API key for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        regenerateSshGatewayApiKey: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('regenerateSshGatewayApiKey', 'id', id)\n            const localVarPath = `/regions/{id}/regenerate-ssh-gateway-api-key`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Set default region for organization\n         * @param {string} organizationId Organization ID\n         * @param {UpdateOrganizationDefaultRegion} updateOrganizationDefaultRegion \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setOrganizationDefaultRegion: async (organizationId: string, updateOrganizationDefaultRegion: UpdateOrganizationDefaultRegion, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('setOrganizationDefaultRegion', 'organizationId', organizationId)\n            // verify required parameter 'updateOrganizationDefaultRegion' is not null or undefined\n            assertParamExists('setOrganizationDefaultRegion', 'updateOrganizationDefaultRegion', updateOrganizationDefaultRegion)\n            const localVarPath = `/organizations/{organizationId}/default-region`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateOrganizationDefaultRegion, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Suspend organization\n         * @param {string} organizationId Organization ID\n         * @param {OrganizationSuspension} [organizationSuspension] \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        suspendOrganization: async (organizationId: string, organizationSuspension?: OrganizationSuspension, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('suspendOrganization', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}/suspend`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(organizationSuspension, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Unsuspend organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        unsuspendOrganization: async (organizationId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('unsuspendOrganization', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}/unsuspend`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update access for organization member\n         * @param {string} organizationId Organization ID\n         * @param {string} userId User ID\n         * @param {UpdateOrganizationMemberAccess} updateOrganizationMemberAccess \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateAccessForOrganizationMember: async (organizationId: string, userId: string, updateOrganizationMemberAccess: UpdateOrganizationMemberAccess, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('updateAccessForOrganizationMember', 'organizationId', organizationId)\n            // verify required parameter 'userId' is not null or undefined\n            assertParamExists('updateAccessForOrganizationMember', 'userId', userId)\n            // verify required parameter 'updateOrganizationMemberAccess' is not null or undefined\n            assertParamExists('updateAccessForOrganizationMember', 'updateOrganizationMemberAccess', updateOrganizationMemberAccess)\n            const localVarPath = `/organizations/{organizationId}/users/{userId}/access`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"userId\"}}`, encodeURIComponent(String(userId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateOrganizationMemberAccess, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update experimental configuration\n         * @param {string} organizationId Organization ID\n         * @param {{ [key: string]: any; }} [requestBody] Experimental configuration as a JSON object. Set to null to clear the configuration.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateExperimentalConfig: async (organizationId: string, requestBody?: { [key: string]: any; }, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('updateExperimentalConfig', 'organizationId', organizationId)\n            const localVarPath = `/organizations/{organizationId}/experimental-config`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(requestBody, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {string} invitationId Invitation ID\n         * @param {UpdateOrganizationInvitation} updateOrganizationInvitation \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateOrganizationInvitation: async (organizationId: string, invitationId: string, updateOrganizationInvitation: UpdateOrganizationInvitation, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('updateOrganizationInvitation', 'organizationId', organizationId)\n            // verify required parameter 'invitationId' is not null or undefined\n            assertParamExists('updateOrganizationInvitation', 'invitationId', invitationId)\n            // verify required parameter 'updateOrganizationInvitation' is not null or undefined\n            assertParamExists('updateOrganizationInvitation', 'updateOrganizationInvitation', updateOrganizationInvitation)\n            const localVarPath = `/organizations/{organizationId}/invitations/{invitationId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"invitationId\"}}`, encodeURIComponent(String(invitationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateOrganizationInvitation, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update organization quota\n         * @param {string} organizationId Organization ID\n         * @param {UpdateOrganizationQuota} updateOrganizationQuota \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateOrganizationQuota: async (organizationId: string, updateOrganizationQuota: UpdateOrganizationQuota, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('updateOrganizationQuota', 'organizationId', organizationId)\n            // verify required parameter 'updateOrganizationQuota' is not null or undefined\n            assertParamExists('updateOrganizationQuota', 'updateOrganizationQuota', updateOrganizationQuota)\n            const localVarPath = `/organizations/{organizationId}/quota`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateOrganizationQuota, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update organization region quota\n         * @param {string} organizationId Organization ID\n         * @param {string} regionId ID of the region where the updated quota will be applied\n         * @param {UpdateOrganizationRegionQuota} updateOrganizationRegionQuota \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateOrganizationRegionQuota: async (organizationId: string, regionId: string, updateOrganizationRegionQuota: UpdateOrganizationRegionQuota, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('updateOrganizationRegionQuota', 'organizationId', organizationId)\n            // verify required parameter 'regionId' is not null or undefined\n            assertParamExists('updateOrganizationRegionQuota', 'regionId', regionId)\n            // verify required parameter 'updateOrganizationRegionQuota' is not null or undefined\n            assertParamExists('updateOrganizationRegionQuota', 'updateOrganizationRegionQuota', updateOrganizationRegionQuota)\n            const localVarPath = `/organizations/{organizationId}/quota/{regionId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"regionId\"}}`, encodeURIComponent(String(regionId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateOrganizationRegionQuota, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update organization role\n         * @param {string} organizationId Organization ID\n         * @param {string} roleId Role ID\n         * @param {UpdateOrganizationRole} updateOrganizationRole \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateOrganizationRole: async (organizationId: string, roleId: string, updateOrganizationRole: UpdateOrganizationRole, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('updateOrganizationRole', 'organizationId', organizationId)\n            // verify required parameter 'roleId' is not null or undefined\n            assertParamExists('updateOrganizationRole', 'roleId', roleId)\n            // verify required parameter 'updateOrganizationRole' is not null or undefined\n            assertParamExists('updateOrganizationRole', 'updateOrganizationRole', updateOrganizationRole)\n            const localVarPath = `/organizations/{organizationId}/roles/{roleId}`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"roleId\"}}`, encodeURIComponent(String(roleId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateOrganizationRole, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update region configuration\n         * @param {string} id Region ID\n         * @param {UpdateRegion} updateRegion \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateRegion: async (id: string, updateRegion: UpdateRegion, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('updateRegion', 'id', id)\n            // verify required parameter 'updateRegion' is not null or undefined\n            assertParamExists('updateRegion', 'updateRegion', updateRegion)\n            const localVarPath = `/regions/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateRegion, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update sandbox default limited network egress\n         * @param {string} organizationId Organization ID\n         * @param {OrganizationSandboxDefaultLimitedNetworkEgress} organizationSandboxDefaultLimitedNetworkEgress \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateSandboxDefaultLimitedNetworkEgress: async (organizationId: string, organizationSandboxDefaultLimitedNetworkEgress: OrganizationSandboxDefaultLimitedNetworkEgress, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('updateSandboxDefaultLimitedNetworkEgress', 'organizationId', organizationId)\n            // verify required parameter 'organizationSandboxDefaultLimitedNetworkEgress' is not null or undefined\n            assertParamExists('updateSandboxDefaultLimitedNetworkEgress', 'organizationSandboxDefaultLimitedNetworkEgress', organizationSandboxDefaultLimitedNetworkEgress)\n            const localVarPath = `/organizations/{organizationId}/sandbox-default-limited-network-egress`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(organizationSandboxDefaultLimitedNetworkEgress, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * OrganizationsApi - functional programming interface\n * @export\n */\nexport const OrganizationsApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = OrganizationsApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Accept organization invitation\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async acceptOrganizationInvitation(invitationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<OrganizationInvitation>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.acceptOrganizationInvitation(invitationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.acceptOrganizationInvitation']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Cancel organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async cancelOrganizationInvitation(organizationId: string, invitationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.cancelOrganizationInvitation(organizationId, invitationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.cancelOrganizationInvitation']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Create organization\n         * @param {CreateOrganization} createOrganization \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createOrganization(createOrganization: CreateOrganization, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Organization>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createOrganization(createOrganization, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.createOrganization']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Create organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {CreateOrganizationInvitation} createOrganizationInvitation \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createOrganizationInvitation(organizationId: string, createOrganizationInvitation: CreateOrganizationInvitation, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<OrganizationInvitation>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createOrganizationInvitation(organizationId, createOrganizationInvitation, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.createOrganizationInvitation']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Create organization role\n         * @param {string} organizationId Organization ID\n         * @param {CreateOrganizationRole} createOrganizationRole \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createOrganizationRole(organizationId: string, createOrganizationRole: CreateOrganizationRole, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<OrganizationRole>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createOrganizationRole(organizationId, createOrganizationRole, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.createOrganizationRole']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Create a new region\n         * @param {CreateRegion} createRegion \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createRegion(createRegion: CreateRegion, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<CreateRegionResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createRegion(createRegion, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.createRegion']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Decline organization invitation\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async declineOrganizationInvitation(invitationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.declineOrganizationInvitation(invitationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.declineOrganizationInvitation']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteOrganization(organizationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteOrganization(organizationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.deleteOrganization']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete organization member\n         * @param {string} organizationId Organization ID\n         * @param {string} userId User ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteOrganizationMember(organizationId: string, userId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteOrganizationMember(organizationId, userId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.deleteOrganizationMember']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete organization role\n         * @param {string} organizationId Organization ID\n         * @param {string} roleId Role ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteOrganizationRole(organizationId: string, roleId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteOrganizationRole(organizationId, roleId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.deleteOrganizationRole']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteRegion(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteRegion(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.deleteRegion']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get organization by ID\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getOrganization(organizationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Organization>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getOrganization(organizationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.getOrganization']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get organization by sandbox ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getOrganizationBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Organization>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getOrganizationBySandboxId(sandboxId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.getOrganizationBySandboxId']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get count of organization invitations for authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getOrganizationInvitationsCountForAuthenticatedUser(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<number>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getOrganizationInvitationsCountForAuthenticatedUser(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.getOrganizationInvitationsCountForAuthenticatedUser']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get organization OTEL config by sandbox auth token\n         * @param {string} authToken Sandbox Auth Token\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getOrganizationOtelConfigBySandboxAuthToken(authToken: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<OtelConfig>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getOrganizationOtelConfigBySandboxAuthToken(authToken, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.getOrganizationOtelConfigBySandboxAuthToken']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get organization current usage overview\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getOrganizationUsageOverview(organizationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<OrganizationUsageOverview>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getOrganizationUsageOverview(organizationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.getOrganizationUsageOverview']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get region by ID\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getRegionById(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Region>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getRegionById(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.getRegionById']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get region quota by sandbox ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getRegionQuotaBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RegionQuota>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getRegionQuotaBySandboxId(sandboxId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.getRegionQuotaBySandboxId']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Leave organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async leaveOrganization(organizationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.leaveOrganization(organizationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.leaveOrganization']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List all available regions for the organization\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listAvailableRegions(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Region>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listAvailableRegions(xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.listAvailableRegions']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List pending organization invitations\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listOrganizationInvitations(organizationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<OrganizationInvitation>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listOrganizationInvitations(organizationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.listOrganizationInvitations']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List organization invitations for authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listOrganizationInvitationsForAuthenticatedUser(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<OrganizationInvitation>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listOrganizationInvitationsForAuthenticatedUser(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.listOrganizationInvitationsForAuthenticatedUser']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List organization members\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listOrganizationMembers(organizationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<OrganizationUser>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listOrganizationMembers(organizationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.listOrganizationMembers']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List organization roles\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listOrganizationRoles(organizationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<OrganizationRole>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listOrganizationRoles(organizationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.listOrganizationRoles']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List organizations\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listOrganizations(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Organization>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listOrganizations(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.listOrganizations']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Regenerate proxy API key for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async regenerateProxyApiKey(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RegenerateApiKeyResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.regenerateProxyApiKey(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.regenerateProxyApiKey']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Regenerate snapshot manager credentials for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async regenerateSnapshotManagerCredentials(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SnapshotManagerCredentials>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.regenerateSnapshotManagerCredentials(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.regenerateSnapshotManagerCredentials']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Regenerate SSH gateway API key for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async regenerateSshGatewayApiKey(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RegenerateApiKeyResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.regenerateSshGatewayApiKey(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.regenerateSshGatewayApiKey']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Set default region for organization\n         * @param {string} organizationId Organization ID\n         * @param {UpdateOrganizationDefaultRegion} updateOrganizationDefaultRegion \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async setOrganizationDefaultRegion(organizationId: string, updateOrganizationDefaultRegion: UpdateOrganizationDefaultRegion, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setOrganizationDefaultRegion(organizationId, updateOrganizationDefaultRegion, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.setOrganizationDefaultRegion']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Suspend organization\n         * @param {string} organizationId Organization ID\n         * @param {OrganizationSuspension} [organizationSuspension] \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async suspendOrganization(organizationId: string, organizationSuspension?: OrganizationSuspension, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.suspendOrganization(organizationId, organizationSuspension, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.suspendOrganization']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Unsuspend organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async unsuspendOrganization(organizationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.unsuspendOrganization(organizationId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.unsuspendOrganization']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update access for organization member\n         * @param {string} organizationId Organization ID\n         * @param {string} userId User ID\n         * @param {UpdateOrganizationMemberAccess} updateOrganizationMemberAccess \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateAccessForOrganizationMember(organizationId: string, userId: string, updateOrganizationMemberAccess: UpdateOrganizationMemberAccess, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<OrganizationUser>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateAccessForOrganizationMember(organizationId, userId, updateOrganizationMemberAccess, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.updateAccessForOrganizationMember']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update experimental configuration\n         * @param {string} organizationId Organization ID\n         * @param {{ [key: string]: any; }} [requestBody] Experimental configuration as a JSON object. Set to null to clear the configuration.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateExperimentalConfig(organizationId: string, requestBody?: { [key: string]: any; }, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateExperimentalConfig(organizationId, requestBody, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.updateExperimentalConfig']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {string} invitationId Invitation ID\n         * @param {UpdateOrganizationInvitation} updateOrganizationInvitation \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateOrganizationInvitation(organizationId: string, invitationId: string, updateOrganizationInvitation: UpdateOrganizationInvitation, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<OrganizationInvitation>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateOrganizationInvitation(organizationId, invitationId, updateOrganizationInvitation, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.updateOrganizationInvitation']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update organization quota\n         * @param {string} organizationId Organization ID\n         * @param {UpdateOrganizationQuota} updateOrganizationQuota \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateOrganizationQuota(organizationId: string, updateOrganizationQuota: UpdateOrganizationQuota, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateOrganizationQuota(organizationId, updateOrganizationQuota, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.updateOrganizationQuota']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update organization region quota\n         * @param {string} organizationId Organization ID\n         * @param {string} regionId ID of the region where the updated quota will be applied\n         * @param {UpdateOrganizationRegionQuota} updateOrganizationRegionQuota \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateOrganizationRegionQuota(organizationId: string, regionId: string, updateOrganizationRegionQuota: UpdateOrganizationRegionQuota, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateOrganizationRegionQuota(organizationId, regionId, updateOrganizationRegionQuota, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.updateOrganizationRegionQuota']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update organization role\n         * @param {string} organizationId Organization ID\n         * @param {string} roleId Role ID\n         * @param {UpdateOrganizationRole} updateOrganizationRole \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateOrganizationRole(organizationId: string, roleId: string, updateOrganizationRole: UpdateOrganizationRole, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<OrganizationRole>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateOrganizationRole(organizationId, roleId, updateOrganizationRole, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.updateOrganizationRole']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update region configuration\n         * @param {string} id Region ID\n         * @param {UpdateRegion} updateRegion \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateRegion(id: string, updateRegion: UpdateRegion, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateRegion(id, updateRegion, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.updateRegion']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update sandbox default limited network egress\n         * @param {string} organizationId Organization ID\n         * @param {OrganizationSandboxDefaultLimitedNetworkEgress} organizationSandboxDefaultLimitedNetworkEgress \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateSandboxDefaultLimitedNetworkEgress(organizationId: string, organizationSandboxDefaultLimitedNetworkEgress: OrganizationSandboxDefaultLimitedNetworkEgress, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateSandboxDefaultLimitedNetworkEgress(organizationId, organizationSandboxDefaultLimitedNetworkEgress, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['OrganizationsApi.updateSandboxDefaultLimitedNetworkEgress']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * OrganizationsApi - factory interface\n * @export\n */\nexport const OrganizationsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = OrganizationsApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Accept organization invitation\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        acceptOrganizationInvitation(invitationId: string, options?: RawAxiosRequestConfig): AxiosPromise<OrganizationInvitation> {\n            return localVarFp.acceptOrganizationInvitation(invitationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Cancel organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        cancelOrganizationInvitation(organizationId: string, invitationId: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.cancelOrganizationInvitation(organizationId, invitationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Create organization\n         * @param {CreateOrganization} createOrganization \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createOrganization(createOrganization: CreateOrganization, options?: RawAxiosRequestConfig): AxiosPromise<Organization> {\n            return localVarFp.createOrganization(createOrganization, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Create organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {CreateOrganizationInvitation} createOrganizationInvitation \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createOrganizationInvitation(organizationId: string, createOrganizationInvitation: CreateOrganizationInvitation, options?: RawAxiosRequestConfig): AxiosPromise<OrganizationInvitation> {\n            return localVarFp.createOrganizationInvitation(organizationId, createOrganizationInvitation, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Create organization role\n         * @param {string} organizationId Organization ID\n         * @param {CreateOrganizationRole} createOrganizationRole \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createOrganizationRole(organizationId: string, createOrganizationRole: CreateOrganizationRole, options?: RawAxiosRequestConfig): AxiosPromise<OrganizationRole> {\n            return localVarFp.createOrganizationRole(organizationId, createOrganizationRole, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Create a new region\n         * @param {CreateRegion} createRegion \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createRegion(createRegion: CreateRegion, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<CreateRegionResponse> {\n            return localVarFp.createRegion(createRegion, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Decline organization invitation\n         * @param {string} invitationId Invitation ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        declineOrganizationInvitation(invitationId: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.declineOrganizationInvitation(invitationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteOrganization(organizationId: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteOrganization(organizationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete organization member\n         * @param {string} organizationId Organization ID\n         * @param {string} userId User ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteOrganizationMember(organizationId: string, userId: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteOrganizationMember(organizationId, userId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete organization role\n         * @param {string} organizationId Organization ID\n         * @param {string} roleId Role ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteOrganizationRole(organizationId: string, roleId: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteOrganizationRole(organizationId, roleId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteRegion(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteRegion(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get organization by ID\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganization(organizationId: string, options?: RawAxiosRequestConfig): AxiosPromise<Organization> {\n            return localVarFp.getOrganization(organizationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get organization by sandbox ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig): AxiosPromise<Organization> {\n            return localVarFp.getOrganizationBySandboxId(sandboxId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get count of organization invitations for authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationInvitationsCountForAuthenticatedUser(options?: RawAxiosRequestConfig): AxiosPromise<number> {\n            return localVarFp.getOrganizationInvitationsCountForAuthenticatedUser(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get organization OTEL config by sandbox auth token\n         * @param {string} authToken Sandbox Auth Token\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationOtelConfigBySandboxAuthToken(authToken: string, options?: RawAxiosRequestConfig): AxiosPromise<OtelConfig> {\n            return localVarFp.getOrganizationOtelConfigBySandboxAuthToken(authToken, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get organization current usage overview\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getOrganizationUsageOverview(organizationId: string, options?: RawAxiosRequestConfig): AxiosPromise<OrganizationUsageOverview> {\n            return localVarFp.getOrganizationUsageOverview(organizationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get region by ID\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRegionById(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Region> {\n            return localVarFp.getRegionById(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get region quota by sandbox ID\n         * @param {string} sandboxId Sandbox ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRegionQuotaBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig): AxiosPromise<RegionQuota> {\n            return localVarFp.getRegionQuotaBySandboxId(sandboxId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Leave organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        leaveOrganization(organizationId: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.leaveOrganization(organizationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List all available regions for the organization\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listAvailableRegions(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<Region>> {\n            return localVarFp.listAvailableRegions(xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List pending organization invitations\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizationInvitations(organizationId: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<OrganizationInvitation>> {\n            return localVarFp.listOrganizationInvitations(organizationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List organization invitations for authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizationInvitationsForAuthenticatedUser(options?: RawAxiosRequestConfig): AxiosPromise<Array<OrganizationInvitation>> {\n            return localVarFp.listOrganizationInvitationsForAuthenticatedUser(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List organization members\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizationMembers(organizationId: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<OrganizationUser>> {\n            return localVarFp.listOrganizationMembers(organizationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List organization roles\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizationRoles(organizationId: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<OrganizationRole>> {\n            return localVarFp.listOrganizationRoles(organizationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List organizations\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listOrganizations(options?: RawAxiosRequestConfig): AxiosPromise<Array<Organization>> {\n            return localVarFp.listOrganizations(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Regenerate proxy API key for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        regenerateProxyApiKey(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<RegenerateApiKeyResponse> {\n            return localVarFp.regenerateProxyApiKey(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Regenerate snapshot manager credentials for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        regenerateSnapshotManagerCredentials(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SnapshotManagerCredentials> {\n            return localVarFp.regenerateSnapshotManagerCredentials(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Regenerate SSH gateway API key for a region\n         * @param {string} id Region ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        regenerateSshGatewayApiKey(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<RegenerateApiKeyResponse> {\n            return localVarFp.regenerateSshGatewayApiKey(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Set default region for organization\n         * @param {string} organizationId Organization ID\n         * @param {UpdateOrganizationDefaultRegion} updateOrganizationDefaultRegion \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setOrganizationDefaultRegion(organizationId: string, updateOrganizationDefaultRegion: UpdateOrganizationDefaultRegion, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.setOrganizationDefaultRegion(organizationId, updateOrganizationDefaultRegion, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Suspend organization\n         * @param {string} organizationId Organization ID\n         * @param {OrganizationSuspension} [organizationSuspension] \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        suspendOrganization(organizationId: string, organizationSuspension?: OrganizationSuspension, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.suspendOrganization(organizationId, organizationSuspension, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Unsuspend organization\n         * @param {string} organizationId Organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        unsuspendOrganization(organizationId: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.unsuspendOrganization(organizationId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update access for organization member\n         * @param {string} organizationId Organization ID\n         * @param {string} userId User ID\n         * @param {UpdateOrganizationMemberAccess} updateOrganizationMemberAccess \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateAccessForOrganizationMember(organizationId: string, userId: string, updateOrganizationMemberAccess: UpdateOrganizationMemberAccess, options?: RawAxiosRequestConfig): AxiosPromise<OrganizationUser> {\n            return localVarFp.updateAccessForOrganizationMember(organizationId, userId, updateOrganizationMemberAccess, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update experimental configuration\n         * @param {string} organizationId Organization ID\n         * @param {{ [key: string]: any; }} [requestBody] Experimental configuration as a JSON object. Set to null to clear the configuration.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateExperimentalConfig(organizationId: string, requestBody?: { [key: string]: any; }, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.updateExperimentalConfig(organizationId, requestBody, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update organization invitation\n         * @param {string} organizationId Organization ID\n         * @param {string} invitationId Invitation ID\n         * @param {UpdateOrganizationInvitation} updateOrganizationInvitation \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateOrganizationInvitation(organizationId: string, invitationId: string, updateOrganizationInvitation: UpdateOrganizationInvitation, options?: RawAxiosRequestConfig): AxiosPromise<OrganizationInvitation> {\n            return localVarFp.updateOrganizationInvitation(organizationId, invitationId, updateOrganizationInvitation, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update organization quota\n         * @param {string} organizationId Organization ID\n         * @param {UpdateOrganizationQuota} updateOrganizationQuota \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateOrganizationQuota(organizationId: string, updateOrganizationQuota: UpdateOrganizationQuota, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.updateOrganizationQuota(organizationId, updateOrganizationQuota, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update organization region quota\n         * @param {string} organizationId Organization ID\n         * @param {string} regionId ID of the region where the updated quota will be applied\n         * @param {UpdateOrganizationRegionQuota} updateOrganizationRegionQuota \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateOrganizationRegionQuota(organizationId: string, regionId: string, updateOrganizationRegionQuota: UpdateOrganizationRegionQuota, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.updateOrganizationRegionQuota(organizationId, regionId, updateOrganizationRegionQuota, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update organization role\n         * @param {string} organizationId Organization ID\n         * @param {string} roleId Role ID\n         * @param {UpdateOrganizationRole} updateOrganizationRole \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateOrganizationRole(organizationId: string, roleId: string, updateOrganizationRole: UpdateOrganizationRole, options?: RawAxiosRequestConfig): AxiosPromise<OrganizationRole> {\n            return localVarFp.updateOrganizationRole(organizationId, roleId, updateOrganizationRole, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update region configuration\n         * @param {string} id Region ID\n         * @param {UpdateRegion} updateRegion \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateRegion(id: string, updateRegion: UpdateRegion, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.updateRegion(id, updateRegion, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update sandbox default limited network egress\n         * @param {string} organizationId Organization ID\n         * @param {OrganizationSandboxDefaultLimitedNetworkEgress} organizationSandboxDefaultLimitedNetworkEgress \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateSandboxDefaultLimitedNetworkEgress(organizationId: string, organizationSandboxDefaultLimitedNetworkEgress: OrganizationSandboxDefaultLimitedNetworkEgress, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.updateSandboxDefaultLimitedNetworkEgress(organizationId, organizationSandboxDefaultLimitedNetworkEgress, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * OrganizationsApi - object-oriented interface\n * @export\n * @class OrganizationsApi\n * @extends {BaseAPI}\n */\nexport class OrganizationsApi extends BaseAPI {\n    /**\n     * \n     * @summary Accept organization invitation\n     * @param {string} invitationId Invitation ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public acceptOrganizationInvitation(invitationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).acceptOrganizationInvitation(invitationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Cancel organization invitation\n     * @param {string} organizationId Organization ID\n     * @param {string} invitationId Invitation ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public cancelOrganizationInvitation(organizationId: string, invitationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).cancelOrganizationInvitation(organizationId, invitationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Create organization\n     * @param {CreateOrganization} createOrganization \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public createOrganization(createOrganization: CreateOrganization, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).createOrganization(createOrganization, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Create organization invitation\n     * @param {string} organizationId Organization ID\n     * @param {CreateOrganizationInvitation} createOrganizationInvitation \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public createOrganizationInvitation(organizationId: string, createOrganizationInvitation: CreateOrganizationInvitation, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).createOrganizationInvitation(organizationId, createOrganizationInvitation, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Create organization role\n     * @param {string} organizationId Organization ID\n     * @param {CreateOrganizationRole} createOrganizationRole \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public createOrganizationRole(organizationId: string, createOrganizationRole: CreateOrganizationRole, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).createOrganizationRole(organizationId, createOrganizationRole, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Create a new region\n     * @param {CreateRegion} createRegion \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public createRegion(createRegion: CreateRegion, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).createRegion(createRegion, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Decline organization invitation\n     * @param {string} invitationId Invitation ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public declineOrganizationInvitation(invitationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).declineOrganizationInvitation(invitationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete organization\n     * @param {string} organizationId Organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public deleteOrganization(organizationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).deleteOrganization(organizationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete organization member\n     * @param {string} organizationId Organization ID\n     * @param {string} userId User ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public deleteOrganizationMember(organizationId: string, userId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).deleteOrganizationMember(organizationId, userId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete organization role\n     * @param {string} organizationId Organization ID\n     * @param {string} roleId Role ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public deleteOrganizationRole(organizationId: string, roleId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).deleteOrganizationRole(organizationId, roleId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete a region\n     * @param {string} id Region ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public deleteRegion(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).deleteRegion(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get organization by ID\n     * @param {string} organizationId Organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public getOrganization(organizationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).getOrganization(organizationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get organization by sandbox ID\n     * @param {string} sandboxId Sandbox ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public getOrganizationBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).getOrganizationBySandboxId(sandboxId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get count of organization invitations for authenticated user\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public getOrganizationInvitationsCountForAuthenticatedUser(options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).getOrganizationInvitationsCountForAuthenticatedUser(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get organization OTEL config by sandbox auth token\n     * @param {string} authToken Sandbox Auth Token\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public getOrganizationOtelConfigBySandboxAuthToken(authToken: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).getOrganizationOtelConfigBySandboxAuthToken(authToken, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get organization current usage overview\n     * @param {string} organizationId Organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public getOrganizationUsageOverview(organizationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).getOrganizationUsageOverview(organizationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get region by ID\n     * @param {string} id Region ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public getRegionById(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).getRegionById(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get region quota by sandbox ID\n     * @param {string} sandboxId Sandbox ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public getRegionQuotaBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).getRegionQuotaBySandboxId(sandboxId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Leave organization\n     * @param {string} organizationId Organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public leaveOrganization(organizationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).leaveOrganization(organizationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List all available regions for the organization\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public listAvailableRegions(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).listAvailableRegions(xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List pending organization invitations\n     * @param {string} organizationId Organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public listOrganizationInvitations(organizationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).listOrganizationInvitations(organizationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List organization invitations for authenticated user\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public listOrganizationInvitationsForAuthenticatedUser(options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).listOrganizationInvitationsForAuthenticatedUser(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List organization members\n     * @param {string} organizationId Organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public listOrganizationMembers(organizationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).listOrganizationMembers(organizationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List organization roles\n     * @param {string} organizationId Organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public listOrganizationRoles(organizationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).listOrganizationRoles(organizationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List organizations\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public listOrganizations(options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).listOrganizations(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Regenerate proxy API key for a region\n     * @param {string} id Region ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public regenerateProxyApiKey(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).regenerateProxyApiKey(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Regenerate snapshot manager credentials for a region\n     * @param {string} id Region ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public regenerateSnapshotManagerCredentials(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).regenerateSnapshotManagerCredentials(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Regenerate SSH gateway API key for a region\n     * @param {string} id Region ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public regenerateSshGatewayApiKey(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).regenerateSshGatewayApiKey(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Set default region for organization\n     * @param {string} organizationId Organization ID\n     * @param {UpdateOrganizationDefaultRegion} updateOrganizationDefaultRegion \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public setOrganizationDefaultRegion(organizationId: string, updateOrganizationDefaultRegion: UpdateOrganizationDefaultRegion, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).setOrganizationDefaultRegion(organizationId, updateOrganizationDefaultRegion, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Suspend organization\n     * @param {string} organizationId Organization ID\n     * @param {OrganizationSuspension} [organizationSuspension] \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public suspendOrganization(organizationId: string, organizationSuspension?: OrganizationSuspension, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).suspendOrganization(organizationId, organizationSuspension, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Unsuspend organization\n     * @param {string} organizationId Organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public unsuspendOrganization(organizationId: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).unsuspendOrganization(organizationId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update access for organization member\n     * @param {string} organizationId Organization ID\n     * @param {string} userId User ID\n     * @param {UpdateOrganizationMemberAccess} updateOrganizationMemberAccess \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public updateAccessForOrganizationMember(organizationId: string, userId: string, updateOrganizationMemberAccess: UpdateOrganizationMemberAccess, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).updateAccessForOrganizationMember(organizationId, userId, updateOrganizationMemberAccess, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update experimental configuration\n     * @param {string} organizationId Organization ID\n     * @param {{ [key: string]: any; }} [requestBody] Experimental configuration as a JSON object. Set to null to clear the configuration.\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public updateExperimentalConfig(organizationId: string, requestBody?: { [key: string]: any; }, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).updateExperimentalConfig(organizationId, requestBody, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update organization invitation\n     * @param {string} organizationId Organization ID\n     * @param {string} invitationId Invitation ID\n     * @param {UpdateOrganizationInvitation} updateOrganizationInvitation \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public updateOrganizationInvitation(organizationId: string, invitationId: string, updateOrganizationInvitation: UpdateOrganizationInvitation, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).updateOrganizationInvitation(organizationId, invitationId, updateOrganizationInvitation, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update organization quota\n     * @param {string} organizationId Organization ID\n     * @param {UpdateOrganizationQuota} updateOrganizationQuota \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public updateOrganizationQuota(organizationId: string, updateOrganizationQuota: UpdateOrganizationQuota, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).updateOrganizationQuota(organizationId, updateOrganizationQuota, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update organization region quota\n     * @param {string} organizationId Organization ID\n     * @param {string} regionId ID of the region where the updated quota will be applied\n     * @param {UpdateOrganizationRegionQuota} updateOrganizationRegionQuota \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public updateOrganizationRegionQuota(organizationId: string, regionId: string, updateOrganizationRegionQuota: UpdateOrganizationRegionQuota, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).updateOrganizationRegionQuota(organizationId, regionId, updateOrganizationRegionQuota, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update organization role\n     * @param {string} organizationId Organization ID\n     * @param {string} roleId Role ID\n     * @param {UpdateOrganizationRole} updateOrganizationRole \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public updateOrganizationRole(organizationId: string, roleId: string, updateOrganizationRole: UpdateOrganizationRole, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).updateOrganizationRole(organizationId, roleId, updateOrganizationRole, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update region configuration\n     * @param {string} id Region ID\n     * @param {UpdateRegion} updateRegion \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public updateRegion(id: string, updateRegion: UpdateRegion, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).updateRegion(id, updateRegion, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update sandbox default limited network egress\n     * @param {string} organizationId Organization ID\n     * @param {OrganizationSandboxDefaultLimitedNetworkEgress} organizationSandboxDefaultLimitedNetworkEgress \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof OrganizationsApi\n     */\n    public updateSandboxDefaultLimitedNetworkEgress(organizationId: string, organizationSandboxDefaultLimitedNetworkEgress: OrganizationSandboxDefaultLimitedNetworkEgress, options?: RawAxiosRequestConfig) {\n        return OrganizationsApiFp(this.configuration).updateSandboxDefaultLimitedNetworkEgress(organizationId, organizationSandboxDefaultLimitedNetworkEgress, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/preview-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n/**\n * PreviewApi - axios parameter creator\n * @export\n */\nexport const PreviewApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Get sandbox ID from signed preview URL token\n         * @param {string} signedPreviewToken Signed preview URL token\n         * @param {number} port Port number to get sandbox ID from signed preview URL token\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxIdFromSignedPreviewUrlToken: async (signedPreviewToken: string, port: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'signedPreviewToken' is not null or undefined\n            assertParamExists('getSandboxIdFromSignedPreviewUrlToken', 'signedPreviewToken', signedPreviewToken)\n            // verify required parameter 'port' is not null or undefined\n            assertParamExists('getSandboxIdFromSignedPreviewUrlToken', 'port', port)\n            const localVarPath = `/preview/{signedPreviewToken}/{port}/sandbox-id`\n                .replace(`{${\"signedPreviewToken\"}}`, encodeURIComponent(String(signedPreviewToken)))\n                .replace(`{${\"port\"}}`, encodeURIComponent(String(port)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Check if user has access to the sandbox\n         * @param {string} sandboxId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        hasSandboxAccess: async (sandboxId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('hasSandboxAccess', 'sandboxId', sandboxId)\n            const localVarPath = `/preview/{sandboxId}/access`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Check if sandbox is public\n         * @param {string} sandboxId ID of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        isSandboxPublic: async (sandboxId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('isSandboxPublic', 'sandboxId', sandboxId)\n            const localVarPath = `/preview/{sandboxId}/public`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Check if sandbox auth token is valid\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} authToken Auth token of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        isValidAuthToken: async (sandboxId: string, authToken: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('isValidAuthToken', 'sandboxId', sandboxId)\n            // verify required parameter 'authToken' is not null or undefined\n            assertParamExists('isValidAuthToken', 'authToken', authToken)\n            const localVarPath = `/preview/{sandboxId}/validate/{authToken}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"authToken\"}}`, encodeURIComponent(String(authToken)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * PreviewApi - functional programming interface\n * @export\n */\nexport const PreviewApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = PreviewApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Get sandbox ID from signed preview URL token\n         * @param {string} signedPreviewToken Signed preview URL token\n         * @param {number} port Port number to get sandbox ID from signed preview URL token\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSandboxIdFromSignedPreviewUrlToken(signedPreviewToken: string, port: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<string>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSandboxIdFromSignedPreviewUrlToken(signedPreviewToken, port, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['PreviewApi.getSandboxIdFromSignedPreviewUrlToken']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Check if user has access to the sandbox\n         * @param {string} sandboxId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async hasSandboxAccess(sandboxId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<boolean>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.hasSandboxAccess(sandboxId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['PreviewApi.hasSandboxAccess']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Check if sandbox is public\n         * @param {string} sandboxId ID of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async isSandboxPublic(sandboxId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<boolean>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.isSandboxPublic(sandboxId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['PreviewApi.isSandboxPublic']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Check if sandbox auth token is valid\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} authToken Auth token of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async isValidAuthToken(sandboxId: string, authToken: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<boolean>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.isValidAuthToken(sandboxId, authToken, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['PreviewApi.isValidAuthToken']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * PreviewApi - factory interface\n * @export\n */\nexport const PreviewApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = PreviewApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Get sandbox ID from signed preview URL token\n         * @param {string} signedPreviewToken Signed preview URL token\n         * @param {number} port Port number to get sandbox ID from signed preview URL token\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxIdFromSignedPreviewUrlToken(signedPreviewToken: string, port: number, options?: RawAxiosRequestConfig): AxiosPromise<string> {\n            return localVarFp.getSandboxIdFromSignedPreviewUrlToken(signedPreviewToken, port, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Check if user has access to the sandbox\n         * @param {string} sandboxId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        hasSandboxAccess(sandboxId: string, options?: RawAxiosRequestConfig): AxiosPromise<boolean> {\n            return localVarFp.hasSandboxAccess(sandboxId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Check if sandbox is public\n         * @param {string} sandboxId ID of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        isSandboxPublic(sandboxId: string, options?: RawAxiosRequestConfig): AxiosPromise<boolean> {\n            return localVarFp.isSandboxPublic(sandboxId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Check if sandbox auth token is valid\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} authToken Auth token of the sandbox\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        isValidAuthToken(sandboxId: string, authToken: string, options?: RawAxiosRequestConfig): AxiosPromise<boolean> {\n            return localVarFp.isValidAuthToken(sandboxId, authToken, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * PreviewApi - object-oriented interface\n * @export\n * @class PreviewApi\n * @extends {BaseAPI}\n */\nexport class PreviewApi extends BaseAPI {\n    /**\n     * \n     * @summary Get sandbox ID from signed preview URL token\n     * @param {string} signedPreviewToken Signed preview URL token\n     * @param {number} port Port number to get sandbox ID from signed preview URL token\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof PreviewApi\n     */\n    public getSandboxIdFromSignedPreviewUrlToken(signedPreviewToken: string, port: number, options?: RawAxiosRequestConfig) {\n        return PreviewApiFp(this.configuration).getSandboxIdFromSignedPreviewUrlToken(signedPreviewToken, port, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Check if user has access to the sandbox\n     * @param {string} sandboxId \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof PreviewApi\n     */\n    public hasSandboxAccess(sandboxId: string, options?: RawAxiosRequestConfig) {\n        return PreviewApiFp(this.configuration).hasSandboxAccess(sandboxId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Check if sandbox is public\n     * @param {string} sandboxId ID of the sandbox\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof PreviewApi\n     */\n    public isSandboxPublic(sandboxId: string, options?: RawAxiosRequestConfig) {\n        return PreviewApiFp(this.configuration).isSandboxPublic(sandboxId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Check if sandbox auth token is valid\n     * @param {string} sandboxId ID of the sandbox\n     * @param {string} authToken Auth token of the sandbox\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof PreviewApi\n     */\n    public isValidAuthToken(sandboxId: string, authToken: string, options?: RawAxiosRequestConfig) {\n        return PreviewApiFp(this.configuration).isValidAuthToken(sandboxId, authToken, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/regions-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { Region } from '../models';\n/**\n * RegionsApi - axios parameter creator\n * @export\n */\nexport const RegionsApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary List all shared regions\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listSharedRegions: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/shared-regions`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * RegionsApi - functional programming interface\n * @export\n */\nexport const RegionsApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = RegionsApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary List all shared regions\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listSharedRegions(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Region>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listSharedRegions(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RegionsApi.listSharedRegions']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * RegionsApi - factory interface\n * @export\n */\nexport const RegionsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = RegionsApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary List all shared regions\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listSharedRegions(options?: RawAxiosRequestConfig): AxiosPromise<Array<Region>> {\n            return localVarFp.listSharedRegions(options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * RegionsApi - object-oriented interface\n * @export\n * @class RegionsApi\n * @extends {BaseAPI}\n */\nexport class RegionsApi extends BaseAPI {\n    /**\n     * \n     * @summary List all shared regions\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RegionsApi\n     */\n    public listSharedRegions(options?: RawAxiosRequestConfig) {\n        return RegionsApiFp(this.configuration).listSharedRegions(options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/runners-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { CreateRunner } from '../models';\n// @ts-ignore\nimport type { CreateRunnerResponse } from '../models';\n// @ts-ignore\nimport type { Runner } from '../models';\n// @ts-ignore\nimport type { RunnerFull } from '../models';\n// @ts-ignore\nimport type { RunnerHealthcheck } from '../models';\n// @ts-ignore\nimport type { RunnerSnapshotDto } from '../models';\n/**\n * RunnersApi - axios parameter creator\n * @export\n */\nexport const RunnersApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Create runner\n         * @param {CreateRunner} createRunner \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createRunner: async (createRunner: CreateRunner, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createRunner' is not null or undefined\n            assertParamExists('createRunner', 'createRunner', createRunner)\n            const localVarPath = `/runners`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createRunner, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete runner\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteRunner: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('deleteRunner', 'id', id)\n            const localVarPath = `/runners/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get info for authenticated runner\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getInfoForAuthenticatedRunner: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/runners/me`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRunnerById: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('getRunnerById', 'id', id)\n            const localVarPath = `/runners/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get runner by sandbox ID\n         * @param {string} sandboxId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRunnerBySandboxId: async (sandboxId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getRunnerBySandboxId', 'sandboxId', sandboxId)\n            const localVarPath = `/runners/by-sandbox/{sandboxId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRunnerFullById: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('getRunnerFullById', 'id', id)\n            const localVarPath = `/runners/{id}/full`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get runners by snapshot ref\n         * @param {string} ref Snapshot ref\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRunnersBySnapshotRef: async (ref: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'ref' is not null or undefined\n            assertParamExists('getRunnersBySnapshotRef', 'ref', ref)\n            const localVarPath = `/runners/by-snapshot-ref`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (ref !== undefined) {\n                localVarQueryParameter['ref'] = ref;\n            }\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List all runners\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listRunners: async (xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/runners`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Endpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n         * @summary Runner healthcheck\n         * @param {RunnerHealthcheck} runnerHealthcheck \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        runnerHealthcheck: async (runnerHealthcheck: RunnerHealthcheck, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'runnerHealthcheck' is not null or undefined\n            assertParamExists('runnerHealthcheck', 'runnerHealthcheck', runnerHealthcheck)\n            const localVarPath = `/runners/healthcheck`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(runnerHealthcheck, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update runner draining status\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateRunnerDraining: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('updateRunnerDraining', 'id', id)\n            const localVarPath = `/runners/{id}/draining`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update runner scheduling status\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateRunnerScheduling: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('updateRunnerScheduling', 'id', id)\n            const localVarPath = `/runners/{id}/scheduling`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * RunnersApi - functional programming interface\n * @export\n */\nexport const RunnersApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = RunnersApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Create runner\n         * @param {CreateRunner} createRunner \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createRunner(createRunner: CreateRunner, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<CreateRunnerResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createRunner(createRunner, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.createRunner']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete runner\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteRunner(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteRunner(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.deleteRunner']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get info for authenticated runner\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getInfoForAuthenticatedRunner(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RunnerFull>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getInfoForAuthenticatedRunner(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.getInfoForAuthenticatedRunner']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getRunnerById(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Runner>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getRunnerById(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.getRunnerById']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get runner by sandbox ID\n         * @param {string} sandboxId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getRunnerBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RunnerFull>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getRunnerBySandboxId(sandboxId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.getRunnerBySandboxId']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getRunnerFullById(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RunnerFull>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getRunnerFullById(id, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.getRunnerFullById']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get runners by snapshot ref\n         * @param {string} ref Snapshot ref\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getRunnersBySnapshotRef(ref: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<RunnerSnapshotDto>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getRunnersBySnapshotRef(ref, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.getRunnersBySnapshotRef']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List all runners\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listRunners(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Runner>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listRunners(xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.listRunners']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Endpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n         * @summary Runner healthcheck\n         * @param {RunnerHealthcheck} runnerHealthcheck \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async runnerHealthcheck(runnerHealthcheck: RunnerHealthcheck, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.runnerHealthcheck(runnerHealthcheck, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.runnerHealthcheck']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update runner draining status\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateRunnerDraining(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Runner>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateRunnerDraining(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.updateRunnerDraining']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update runner scheduling status\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateRunnerScheduling(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Runner>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateRunnerScheduling(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['RunnersApi.updateRunnerScheduling']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * RunnersApi - factory interface\n * @export\n */\nexport const RunnersApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = RunnersApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Create runner\n         * @param {CreateRunner} createRunner \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createRunner(createRunner: CreateRunner, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<CreateRunnerResponse> {\n            return localVarFp.createRunner(createRunner, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete runner\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteRunner(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteRunner(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get info for authenticated runner\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getInfoForAuthenticatedRunner(options?: RawAxiosRequestConfig): AxiosPromise<RunnerFull> {\n            return localVarFp.getInfoForAuthenticatedRunner(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRunnerById(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Runner> {\n            return localVarFp.getRunnerById(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get runner by sandbox ID\n         * @param {string} sandboxId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRunnerBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig): AxiosPromise<RunnerFull> {\n            return localVarFp.getRunnerBySandboxId(sandboxId, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get runner by ID\n         * @param {string} id Runner ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRunnerFullById(id: string, options?: RawAxiosRequestConfig): AxiosPromise<RunnerFull> {\n            return localVarFp.getRunnerFullById(id, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get runners by snapshot ref\n         * @param {string} ref Snapshot ref\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getRunnersBySnapshotRef(ref: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<RunnerSnapshotDto>> {\n            return localVarFp.getRunnersBySnapshotRef(ref, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List all runners\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listRunners(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<Runner>> {\n            return localVarFp.listRunners(xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Endpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n         * @summary Runner healthcheck\n         * @param {RunnerHealthcheck} runnerHealthcheck \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        runnerHealthcheck(runnerHealthcheck: RunnerHealthcheck, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.runnerHealthcheck(runnerHealthcheck, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update runner draining status\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateRunnerDraining(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Runner> {\n            return localVarFp.updateRunnerDraining(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update runner scheduling status\n         * @param {string} id Runner ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateRunnerScheduling(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Runner> {\n            return localVarFp.updateRunnerScheduling(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * RunnersApi - object-oriented interface\n * @export\n * @class RunnersApi\n * @extends {BaseAPI}\n */\nexport class RunnersApi extends BaseAPI {\n    /**\n     * \n     * @summary Create runner\n     * @param {CreateRunner} createRunner \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public createRunner(createRunner: CreateRunner, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).createRunner(createRunner, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete runner\n     * @param {string} id Runner ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public deleteRunner(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).deleteRunner(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get info for authenticated runner\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public getInfoForAuthenticatedRunner(options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).getInfoForAuthenticatedRunner(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get runner by ID\n     * @param {string} id Runner ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public getRunnerById(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).getRunnerById(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get runner by sandbox ID\n     * @param {string} sandboxId \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public getRunnerBySandboxId(sandboxId: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).getRunnerBySandboxId(sandboxId, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get runner by ID\n     * @param {string} id Runner ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public getRunnerFullById(id: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).getRunnerFullById(id, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get runners by snapshot ref\n     * @param {string} ref Snapshot ref\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public getRunnersBySnapshotRef(ref: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).getRunnersBySnapshotRef(ref, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List all runners\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public listRunners(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).listRunners(xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Endpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n     * @summary Runner healthcheck\n     * @param {RunnerHealthcheck} runnerHealthcheck \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public runnerHealthcheck(runnerHealthcheck: RunnerHealthcheck, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).runnerHealthcheck(runnerHealthcheck, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update runner draining status\n     * @param {string} id Runner ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public updateRunnerDraining(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).updateRunnerDraining(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update runner scheduling status\n     * @param {string} id Runner ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof RunnersApi\n     */\n    public updateRunnerScheduling(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return RunnersApiFp(this.configuration).updateRunnerScheduling(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/sandbox-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { CreateSandbox } from '../models';\n// @ts-ignore\nimport type { MetricsResponse } from '../models';\n// @ts-ignore\nimport type { PaginatedLogs } from '../models';\n// @ts-ignore\nimport type { PaginatedSandboxes } from '../models';\n// @ts-ignore\nimport type { PaginatedTraces } from '../models';\n// @ts-ignore\nimport type { PortPreviewUrl } from '../models';\n// @ts-ignore\nimport type { ResizeSandbox } from '../models';\n// @ts-ignore\nimport type { Sandbox } from '../models';\n// @ts-ignore\nimport type { SandboxLabels } from '../models';\n// @ts-ignore\nimport type { SignedPortPreviewUrl } from '../models';\n// @ts-ignore\nimport type { SshAccessDto } from '../models';\n// @ts-ignore\nimport type { SshAccessValidationDto } from '../models';\n// @ts-ignore\nimport type { ToolboxProxyUrl } from '../models';\n// @ts-ignore\nimport type { TraceSpan } from '../models';\n// @ts-ignore\nimport type { UpdateSandboxStateDto } from '../models';\n// @ts-ignore\nimport type { Url } from '../models';\n/**\n * SandboxApi - axios parameter creator\n * @export\n */\nexport const SandboxApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Archive sandbox\n         * @param {string} sandboxIdOrName \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        archiveSandbox: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('archiveSandbox', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/archive`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Create sandbox backup\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createBackup: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('createBackup', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/backup`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Create a new sandbox\n         * @param {CreateSandbox} createSandbox \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createSandbox: async (createSandbox: CreateSandbox, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createSandbox' is not null or undefined\n            assertParamExists('createSandbox', 'createSandbox', createSandbox)\n            const localVarPath = `/sandbox`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createSandbox, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Create SSH access for sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [expiresInMinutes] Expiration time in minutes (default: 60)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createSshAccess: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, expiresInMinutes?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('createSshAccess', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/ssh-access`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (expiresInMinutes !== undefined) {\n                localVarQueryParameter['expiresInMinutes'] = expiresInMinutes;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteSandbox: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('deleteSandbox', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Expire signed preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to expire signed preview URL for\n         * @param {string} token Token to expire signed preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        expireSignedPortPreviewUrl: async (sandboxIdOrName: string, port: number, token: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('expireSignedPortPreviewUrl', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'port' is not null or undefined\n            assertParamExists('expireSignedPortPreviewUrl', 'port', port)\n            // verify required parameter 'token' is not null or undefined\n            assertParamExists('expireSignedPortPreviewUrl', 'token', token)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url/{token}/expire`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)))\n                .replace(`{${\"port\"}}`, encodeURIComponent(String(port)))\n                .replace(`{${\"token\"}}`, encodeURIComponent(String(token)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * This endpoint is deprecated. Use `getBuildLogsUrl` instead.\n         * @summary Get build logs\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getBuildLogs: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, follow?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('getBuildLogs', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/build-logs`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (follow !== undefined) {\n                localVarQueryParameter['follow'] = follow;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get build logs URL\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getBuildLogsUrl: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('getBuildLogsUrl', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/build-logs-url`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to get preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getPortPreviewUrl: async (sandboxIdOrName: string, port: number, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('getPortPreviewUrl', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'port' is not null or undefined\n            assertParamExists('getPortPreviewUrl', 'port', port)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/ports/{port}/preview-url`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)))\n                .replace(`{${\"port\"}}`, encodeURIComponent(String(port)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get sandbox details\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandbox: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, verbose?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('getSandbox', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (verbose !== undefined) {\n                localVarQueryParameter['verbose'] = verbose;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Retrieve OTEL logs for a sandbox within a time range\n         * @summary Get sandbox logs\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number (1-indexed)\n         * @param {number} [limit] Number of items per page\n         * @param {Array<string>} [severities] Filter by severity levels (DEBUG, INFO, WARN, ERROR)\n         * @param {string} [search] Search in log body\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxLogs: async (sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, page?: number, limit?: number, severities?: Array<string>, search?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getSandboxLogs', 'sandboxId', sandboxId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('getSandboxLogs', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('getSandboxLogs', 'to', to)\n            const localVarPath = `/sandbox/{sandboxId}/telemetry/logs`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = (from as any instanceof Date) ?\n                    (from as any).toISOString() :\n                    from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = (to as any instanceof Date) ?\n                    (to as any).toISOString() :\n                    to;\n            }\n\n            if (page !== undefined) {\n                localVarQueryParameter['page'] = page;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n            if (severities) {\n                localVarQueryParameter['severities'] = severities;\n            }\n\n            if (search !== undefined) {\n                localVarQueryParameter['search'] = search;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Retrieve OTEL metrics for a sandbox within a time range\n         * @summary Get sandbox metrics\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {Array<string>} [metricNames] Filter by metric names\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxMetrics: async (sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, metricNames?: Array<string>, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getSandboxMetrics', 'sandboxId', sandboxId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('getSandboxMetrics', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('getSandboxMetrics', 'to', to)\n            const localVarPath = `/sandbox/{sandboxId}/telemetry/metrics`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = (from as any instanceof Date) ?\n                    (from as any).toISOString() :\n                    from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = (to as any instanceof Date) ?\n                    (to as any).toISOString() :\n                    to;\n            }\n\n            if (metricNames) {\n                localVarQueryParameter['metricNames'] = metricNames;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Retrieve all spans for a specific trace\n         * @summary Get trace spans\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} traceId ID of the trace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxTraceSpans: async (sandboxId: string, traceId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getSandboxTraceSpans', 'sandboxId', sandboxId)\n            // verify required parameter 'traceId' is not null or undefined\n            assertParamExists('getSandboxTraceSpans', 'traceId', traceId)\n            const localVarPath = `/sandbox/{sandboxId}/telemetry/traces/{traceId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"traceId\"}}`, encodeURIComponent(String(traceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Retrieve OTEL traces for a sandbox within a time range\n         * @summary Get sandbox traces\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number (1-indexed)\n         * @param {number} [limit] Number of items per page\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxTraces: async (sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, page?: number, limit?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getSandboxTraces', 'sandboxId', sandboxId)\n            // verify required parameter 'from' is not null or undefined\n            assertParamExists('getSandboxTraces', 'from', from)\n            // verify required parameter 'to' is not null or undefined\n            assertParamExists('getSandboxTraces', 'to', to)\n            const localVarPath = `/sandbox/{sandboxId}/telemetry/traces`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (from !== undefined) {\n                localVarQueryParameter['from'] = (from as any instanceof Date) ?\n                    (from as any).toISOString() :\n                    from;\n            }\n\n            if (to !== undefined) {\n                localVarQueryParameter['to'] = (to as any instanceof Date) ?\n                    (to as any).toISOString() :\n                    to;\n            }\n\n            if (page !== undefined) {\n                localVarQueryParameter['page'] = page;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get sandboxes for the authenticated runner\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [states] Comma-separated list of sandbox states to filter by\n         * @param {boolean} [skipReconcilingSandboxes] Skip sandboxes where state differs from desired state\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxesForRunner: async (xDaytonaOrganizationID?: string, states?: string, skipReconcilingSandboxes?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/sandbox/for-runner`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (states !== undefined) {\n                localVarQueryParameter['states'] = states;\n            }\n\n            if (skipReconcilingSandboxes !== undefined) {\n                localVarQueryParameter['skipReconcilingSandboxes'] = skipReconcilingSandboxes;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get signed preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to get signed preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [expiresInSeconds] Expiration time in seconds (default: 60 seconds)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSignedPortPreviewUrl: async (sandboxIdOrName: string, port: number, xDaytonaOrganizationID?: string, expiresInSeconds?: number, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('getSignedPortPreviewUrl', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'port' is not null or undefined\n            assertParamExists('getSignedPortPreviewUrl', 'port', port)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)))\n                .replace(`{${\"port\"}}`, encodeURIComponent(String(port)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (expiresInSeconds !== undefined) {\n                localVarQueryParameter['expiresInSeconds'] = expiresInSeconds;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get toolbox proxy URL for a sandbox\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getToolboxProxyUrl: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getToolboxProxyUrl', 'sandboxId', sandboxId)\n            const localVarPath = `/sandbox/{sandboxId}/toolbox-proxy-url`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List all sandboxes\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {boolean} [includeErroredDeleted] Include errored and deleted sandboxes\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listSandboxes: async (xDaytonaOrganizationID?: string, verbose?: boolean, labels?: string, includeErroredDeleted?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/sandbox`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (verbose !== undefined) {\n                localVarQueryParameter['verbose'] = verbose;\n            }\n\n            if (labels !== undefined) {\n                localVarQueryParameter['labels'] = labels;\n            }\n\n            if (includeErroredDeleted !== undefined) {\n                localVarQueryParameter['includeErroredDeleted'] = includeErroredDeleted;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List all sandboxes paginated\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {string} [id] Filter by partial ID match\n         * @param {string} [name] Filter by partial name match\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {boolean} [includeErroredDeleted] Include results with errored state and deleted desired state\n         * @param {Array<ListSandboxesPaginatedStatesEnum>} [states] List of states to filter by\n         * @param {Array<string>} [snapshots] List of snapshot names to filter by\n         * @param {Array<string>} [regions] List of regions to filter by\n         * @param {number} [minCpu] Minimum CPU\n         * @param {number} [maxCpu] Maximum CPU\n         * @param {number} [minMemoryGiB] Minimum memory in GiB\n         * @param {number} [maxMemoryGiB] Maximum memory in GiB\n         * @param {number} [minDiskGiB] Minimum disk space in GiB\n         * @param {number} [maxDiskGiB] Maximum disk space in GiB\n         * @param {Date} [lastEventAfter] Include items with last event after this timestamp\n         * @param {Date} [lastEventBefore] Include items with last event before this timestamp\n         * @param {ListSandboxesPaginatedSortEnum} [sort] Field to sort by\n         * @param {ListSandboxesPaginatedOrderEnum} [order] Direction to sort by\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listSandboxesPaginated: async (xDaytonaOrganizationID?: string, page?: number, limit?: number, id?: string, name?: string, labels?: string, includeErroredDeleted?: boolean, states?: Array<ListSandboxesPaginatedStatesEnum>, snapshots?: Array<string>, regions?: Array<string>, minCpu?: number, maxCpu?: number, minMemoryGiB?: number, maxMemoryGiB?: number, minDiskGiB?: number, maxDiskGiB?: number, lastEventAfter?: Date, lastEventBefore?: Date, sort?: ListSandboxesPaginatedSortEnum, order?: ListSandboxesPaginatedOrderEnum, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/sandbox/paginated`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (page !== undefined) {\n                localVarQueryParameter['page'] = page;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n            if (id !== undefined) {\n                localVarQueryParameter['id'] = id;\n            }\n\n            if (name !== undefined) {\n                localVarQueryParameter['name'] = name;\n            }\n\n            if (labels !== undefined) {\n                localVarQueryParameter['labels'] = labels;\n            }\n\n            if (includeErroredDeleted !== undefined) {\n                localVarQueryParameter['includeErroredDeleted'] = includeErroredDeleted;\n            }\n\n            if (states) {\n                localVarQueryParameter['states'] = states;\n            }\n\n            if (snapshots) {\n                localVarQueryParameter['snapshots'] = snapshots;\n            }\n\n            if (regions) {\n                localVarQueryParameter['regions'] = regions;\n            }\n\n            if (minCpu !== undefined) {\n                localVarQueryParameter['minCpu'] = minCpu;\n            }\n\n            if (maxCpu !== undefined) {\n                localVarQueryParameter['maxCpu'] = maxCpu;\n            }\n\n            if (minMemoryGiB !== undefined) {\n                localVarQueryParameter['minMemoryGiB'] = minMemoryGiB;\n            }\n\n            if (maxMemoryGiB !== undefined) {\n                localVarQueryParameter['maxMemoryGiB'] = maxMemoryGiB;\n            }\n\n            if (minDiskGiB !== undefined) {\n                localVarQueryParameter['minDiskGiB'] = minDiskGiB;\n            }\n\n            if (maxDiskGiB !== undefined) {\n                localVarQueryParameter['maxDiskGiB'] = maxDiskGiB;\n            }\n\n            if (lastEventAfter !== undefined) {\n                localVarQueryParameter['lastEventAfter'] = (lastEventAfter as any instanceof Date) ?\n                    (lastEventAfter as any).toISOString() :\n                    lastEventAfter;\n            }\n\n            if (lastEventBefore !== undefined) {\n                localVarQueryParameter['lastEventBefore'] = (lastEventBefore as any instanceof Date) ?\n                    (lastEventBefore as any).toISOString() :\n                    lastEventBefore;\n            }\n\n            if (sort !== undefined) {\n                localVarQueryParameter['sort'] = sort;\n            }\n\n            if (order !== undefined) {\n                localVarQueryParameter['order'] = order;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Recover sandbox from error state\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        recoverSandbox: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('recoverSandbox', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/recover`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Replace sandbox labels\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {SandboxLabels} sandboxLabels \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        replaceLabels: async (sandboxIdOrName: string, sandboxLabels: SandboxLabels, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('replaceLabels', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'sandboxLabels' is not null or undefined\n            assertParamExists('replaceLabels', 'sandboxLabels', sandboxLabels)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/labels`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(sandboxLabels, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Resize sandbox resources\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {ResizeSandbox} resizeSandbox \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        resizeSandbox: async (sandboxIdOrName: string, resizeSandbox: ResizeSandbox, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('resizeSandbox', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'resizeSandbox' is not null or undefined\n            assertParamExists('resizeSandbox', 'resizeSandbox', resizeSandbox)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/resize`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(resizeSandbox, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Revoke SSH access for sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [token] SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        revokeSshAccess: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, token?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('revokeSshAccess', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/ssh-access`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (token !== undefined) {\n                localVarQueryParameter['token'] = token;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Set sandbox auto-archive interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setAutoArchiveInterval: async (sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('setAutoArchiveInterval', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'interval' is not null or undefined\n            assertParamExists('setAutoArchiveInterval', 'interval', interval)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/autoarchive/{interval}`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)))\n                .replace(`{${\"interval\"}}`, encodeURIComponent(String(interval)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Set sandbox auto-delete interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setAutoDeleteInterval: async (sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('setAutoDeleteInterval', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'interval' is not null or undefined\n            assertParamExists('setAutoDeleteInterval', 'interval', interval)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/autodelete/{interval}`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)))\n                .replace(`{${\"interval\"}}`, encodeURIComponent(String(interval)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Set sandbox auto-stop interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-stop interval in minutes (0 to disable)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setAutostopInterval: async (sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('setAutostopInterval', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'interval' is not null or undefined\n            assertParamExists('setAutostopInterval', 'interval', interval)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/autostop/{interval}`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)))\n                .replace(`{${\"interval\"}}`, encodeURIComponent(String(interval)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Start sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        startSandbox: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('startSandbox', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/start`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Stop sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        stopSandbox: async (sandboxIdOrName: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('stopSandbox', 'sandboxIdOrName', sandboxIdOrName)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/stop`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update sandbox last activity\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateLastActivity: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('updateLastActivity', 'sandboxId', sandboxId)\n            const localVarPath = `/sandbox/{sandboxId}/last-activity`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update public status\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {boolean} isPublic Public status to set\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updatePublicStatus: async (sandboxIdOrName: string, isPublic: boolean, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxIdOrName' is not null or undefined\n            assertParamExists('updatePublicStatus', 'sandboxIdOrName', sandboxIdOrName)\n            // verify required parameter 'isPublic' is not null or undefined\n            assertParamExists('updatePublicStatus', 'isPublic', isPublic)\n            const localVarPath = `/sandbox/{sandboxIdOrName}/public/{isPublic}`\n                .replace(`{${\"sandboxIdOrName\"}}`, encodeURIComponent(String(sandboxIdOrName)))\n                .replace(`{${\"isPublic\"}}`, encodeURIComponent(String(isPublic)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Update sandbox state\n         * @param {string} sandboxId ID of the sandbox\n         * @param {UpdateSandboxStateDto} updateSandboxStateDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateSandboxState: async (sandboxId: string, updateSandboxStateDto: UpdateSandboxStateDto, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('updateSandboxState', 'sandboxId', sandboxId)\n            // verify required parameter 'updateSandboxStateDto' is not null or undefined\n            assertParamExists('updateSandboxState', 'updateSandboxStateDto', updateSandboxStateDto)\n            const localVarPath = `/sandbox/{sandboxId}/state`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(updateSandboxStateDto, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Validate SSH access for sandbox\n         * @param {string} token SSH access token to validate\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        validateSshAccess: async (token: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'token' is not null or undefined\n            assertParamExists('validateSshAccess', 'token', token)\n            const localVarPath = `/sandbox/ssh-access/validate`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (token !== undefined) {\n                localVarQueryParameter['token'] = token;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * SandboxApi - functional programming interface\n * @export\n */\nexport const SandboxApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = SandboxApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Archive sandbox\n         * @param {string} sandboxIdOrName \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async archiveSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.archiveSandbox(sandboxIdOrName, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.archiveSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Create sandbox backup\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createBackup(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createBackup(sandboxIdOrName, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.createBackup']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Create a new sandbox\n         * @param {CreateSandbox} createSandbox \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createSandbox(createSandbox: CreateSandbox, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createSandbox(createSandbox, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.createSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Create SSH access for sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [expiresInMinutes] Expiration time in minutes (default: 60)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createSshAccess(sandboxIdOrName: string, xDaytonaOrganizationID?: string, expiresInMinutes?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SshAccessDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createSshAccess(sandboxIdOrName, xDaytonaOrganizationID, expiresInMinutes, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.createSshAccess']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteSandbox(sandboxIdOrName, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.deleteSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Expire signed preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to expire signed preview URL for\n         * @param {string} token Token to expire signed preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async expireSignedPortPreviewUrl(sandboxIdOrName: string, port: number, token: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.expireSignedPortPreviewUrl(sandboxIdOrName, port, token, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.expireSignedPortPreviewUrl']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * This endpoint is deprecated. Use `getBuildLogsUrl` instead.\n         * @summary Get build logs\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getBuildLogs(sandboxIdOrName: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getBuildLogs(sandboxIdOrName, xDaytonaOrganizationID, follow, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getBuildLogs']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get build logs URL\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getBuildLogsUrl(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Url>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getBuildLogsUrl(sandboxIdOrName, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getBuildLogsUrl']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to get preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getPortPreviewUrl(sandboxIdOrName: string, port: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PortPreviewUrl>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getPortPreviewUrl(sandboxIdOrName, port, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getPortPreviewUrl']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get sandbox details\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, verbose?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSandbox(sandboxIdOrName, xDaytonaOrganizationID, verbose, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Retrieve OTEL logs for a sandbox within a time range\n         * @summary Get sandbox logs\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number (1-indexed)\n         * @param {number} [limit] Number of items per page\n         * @param {Array<string>} [severities] Filter by severity levels (DEBUG, INFO, WARN, ERROR)\n         * @param {string} [search] Search in log body\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSandboxLogs(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, page?: number, limit?: number, severities?: Array<string>, search?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedLogs>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSandboxLogs(sandboxId, from, to, xDaytonaOrganizationID, page, limit, severities, search, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getSandboxLogs']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Retrieve OTEL metrics for a sandbox within a time range\n         * @summary Get sandbox metrics\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {Array<string>} [metricNames] Filter by metric names\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSandboxMetrics(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, metricNames?: Array<string>, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MetricsResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSandboxMetrics(sandboxId, from, to, xDaytonaOrganizationID, metricNames, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getSandboxMetrics']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Retrieve all spans for a specific trace\n         * @summary Get trace spans\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} traceId ID of the trace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSandboxTraceSpans(sandboxId: string, traceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<TraceSpan>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSandboxTraceSpans(sandboxId, traceId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getSandboxTraceSpans']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Retrieve OTEL traces for a sandbox within a time range\n         * @summary Get sandbox traces\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number (1-indexed)\n         * @param {number} [limit] Number of items per page\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSandboxTraces(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, page?: number, limit?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedTraces>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSandboxTraces(sandboxId, from, to, xDaytonaOrganizationID, page, limit, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getSandboxTraces']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get sandboxes for the authenticated runner\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [states] Comma-separated list of sandbox states to filter by\n         * @param {boolean} [skipReconcilingSandboxes] Skip sandboxes where state differs from desired state\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSandboxesForRunner(xDaytonaOrganizationID?: string, states?: string, skipReconcilingSandboxes?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Sandbox>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSandboxesForRunner(xDaytonaOrganizationID, states, skipReconcilingSandboxes, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getSandboxesForRunner']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get signed preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to get signed preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [expiresInSeconds] Expiration time in seconds (default: 60 seconds)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSignedPortPreviewUrl(sandboxIdOrName: string, port: number, xDaytonaOrganizationID?: string, expiresInSeconds?: number, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SignedPortPreviewUrl>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSignedPortPreviewUrl(sandboxIdOrName, port, xDaytonaOrganizationID, expiresInSeconds, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getSignedPortPreviewUrl']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get toolbox proxy URL for a sandbox\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getToolboxProxyUrl(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ToolboxProxyUrl>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getToolboxProxyUrl(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.getToolboxProxyUrl']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List all sandboxes\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {boolean} [includeErroredDeleted] Include errored and deleted sandboxes\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listSandboxes(xDaytonaOrganizationID?: string, verbose?: boolean, labels?: string, includeErroredDeleted?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Sandbox>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listSandboxes(xDaytonaOrganizationID, verbose, labels, includeErroredDeleted, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.listSandboxes']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List all sandboxes paginated\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {string} [id] Filter by partial ID match\n         * @param {string} [name] Filter by partial name match\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {boolean} [includeErroredDeleted] Include results with errored state and deleted desired state\n         * @param {Array<ListSandboxesPaginatedStatesEnum>} [states] List of states to filter by\n         * @param {Array<string>} [snapshots] List of snapshot names to filter by\n         * @param {Array<string>} [regions] List of regions to filter by\n         * @param {number} [minCpu] Minimum CPU\n         * @param {number} [maxCpu] Maximum CPU\n         * @param {number} [minMemoryGiB] Minimum memory in GiB\n         * @param {number} [maxMemoryGiB] Maximum memory in GiB\n         * @param {number} [minDiskGiB] Minimum disk space in GiB\n         * @param {number} [maxDiskGiB] Maximum disk space in GiB\n         * @param {Date} [lastEventAfter] Include items with last event after this timestamp\n         * @param {Date} [lastEventBefore] Include items with last event before this timestamp\n         * @param {ListSandboxesPaginatedSortEnum} [sort] Field to sort by\n         * @param {ListSandboxesPaginatedOrderEnum} [order] Direction to sort by\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listSandboxesPaginated(xDaytonaOrganizationID?: string, page?: number, limit?: number, id?: string, name?: string, labels?: string, includeErroredDeleted?: boolean, states?: Array<ListSandboxesPaginatedStatesEnum>, snapshots?: Array<string>, regions?: Array<string>, minCpu?: number, maxCpu?: number, minMemoryGiB?: number, maxMemoryGiB?: number, minDiskGiB?: number, maxDiskGiB?: number, lastEventAfter?: Date, lastEventBefore?: Date, sort?: ListSandboxesPaginatedSortEnum, order?: ListSandboxesPaginatedOrderEnum, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedSandboxes>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listSandboxesPaginated(xDaytonaOrganizationID, page, limit, id, name, labels, includeErroredDeleted, states, snapshots, regions, minCpu, maxCpu, minMemoryGiB, maxMemoryGiB, minDiskGiB, maxDiskGiB, lastEventAfter, lastEventBefore, sort, order, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.listSandboxesPaginated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Recover sandbox from error state\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async recoverSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.recoverSandbox(sandboxIdOrName, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.recoverSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Replace sandbox labels\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {SandboxLabels} sandboxLabels \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async replaceLabels(sandboxIdOrName: string, sandboxLabels: SandboxLabels, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SandboxLabels>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.replaceLabels(sandboxIdOrName, sandboxLabels, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.replaceLabels']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Resize sandbox resources\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {ResizeSandbox} resizeSandbox \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async resizeSandbox(sandboxIdOrName: string, resizeSandbox: ResizeSandbox, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.resizeSandbox(sandboxIdOrName, resizeSandbox, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.resizeSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Revoke SSH access for sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [token] SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async revokeSshAccess(sandboxIdOrName: string, xDaytonaOrganizationID?: string, token?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.revokeSshAccess(sandboxIdOrName, xDaytonaOrganizationID, token, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.revokeSshAccess']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Set sandbox auto-archive interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async setAutoArchiveInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setAutoArchiveInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.setAutoArchiveInterval']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Set sandbox auto-delete interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async setAutoDeleteInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setAutoDeleteInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.setAutoDeleteInterval']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Set sandbox auto-stop interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-stop interval in minutes (0 to disable)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async setAutostopInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setAutostopInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.setAutostopInterval']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Start sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async startSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.startSandbox(sandboxIdOrName, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.startSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Stop sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async stopSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.stopSandbox(sandboxIdOrName, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.stopSandbox']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update sandbox last activity\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateLastActivity(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateLastActivity(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.updateLastActivity']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update public status\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {boolean} isPublic Public status to set\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updatePublicStatus(sandboxIdOrName: string, isPublic: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Sandbox>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updatePublicStatus(sandboxIdOrName, isPublic, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.updatePublicStatus']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Update sandbox state\n         * @param {string} sandboxId ID of the sandbox\n         * @param {UpdateSandboxStateDto} updateSandboxStateDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async updateSandboxState(sandboxId: string, updateSandboxStateDto: UpdateSandboxStateDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updateSandboxState(sandboxId, updateSandboxStateDto, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.updateSandboxState']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Validate SSH access for sandbox\n         * @param {string} token SSH access token to validate\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async validateSshAccess(token: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SshAccessValidationDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.validateSshAccess(token, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SandboxApi.validateSshAccess']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * SandboxApi - factory interface\n * @export\n */\nexport const SandboxApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = SandboxApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Archive sandbox\n         * @param {string} sandboxIdOrName \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        archiveSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.archiveSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Create sandbox backup\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createBackup(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.createBackup(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Create a new sandbox\n         * @param {CreateSandbox} createSandbox \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createSandbox(createSandbox: CreateSandbox, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.createSandbox(createSandbox, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Create SSH access for sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [expiresInMinutes] Expiration time in minutes (default: 60)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createSshAccess(sandboxIdOrName: string, xDaytonaOrganizationID?: string, expiresInMinutes?: number, options?: RawAxiosRequestConfig): AxiosPromise<SshAccessDto> {\n            return localVarFp.createSshAccess(sandboxIdOrName, xDaytonaOrganizationID, expiresInMinutes, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.deleteSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Expire signed preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to expire signed preview URL for\n         * @param {string} token Token to expire signed preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        expireSignedPortPreviewUrl(sandboxIdOrName: string, port: number, token: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.expireSignedPortPreviewUrl(sandboxIdOrName, port, token, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * This endpoint is deprecated. Use `getBuildLogsUrl` instead.\n         * @summary Get build logs\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getBuildLogs(sandboxIdOrName: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.getBuildLogs(sandboxIdOrName, xDaytonaOrganizationID, follow, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get build logs URL\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getBuildLogsUrl(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Url> {\n            return localVarFp.getBuildLogsUrl(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to get preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getPortPreviewUrl(sandboxIdOrName: string, port: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<PortPreviewUrl> {\n            return localVarFp.getPortPreviewUrl(sandboxIdOrName, port, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get sandbox details\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, verbose?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.getSandbox(sandboxIdOrName, xDaytonaOrganizationID, verbose, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Retrieve OTEL logs for a sandbox within a time range\n         * @summary Get sandbox logs\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number (1-indexed)\n         * @param {number} [limit] Number of items per page\n         * @param {Array<string>} [severities] Filter by severity levels (DEBUG, INFO, WARN, ERROR)\n         * @param {string} [search] Search in log body\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxLogs(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, page?: number, limit?: number, severities?: Array<string>, search?: string, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedLogs> {\n            return localVarFp.getSandboxLogs(sandboxId, from, to, xDaytonaOrganizationID, page, limit, severities, search, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Retrieve OTEL metrics for a sandbox within a time range\n         * @summary Get sandbox metrics\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {Array<string>} [metricNames] Filter by metric names\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxMetrics(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, metricNames?: Array<string>, options?: RawAxiosRequestConfig): AxiosPromise<MetricsResponse> {\n            return localVarFp.getSandboxMetrics(sandboxId, from, to, xDaytonaOrganizationID, metricNames, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Retrieve all spans for a specific trace\n         * @summary Get trace spans\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} traceId ID of the trace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxTraceSpans(sandboxId: string, traceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<TraceSpan>> {\n            return localVarFp.getSandboxTraceSpans(sandboxId, traceId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Retrieve OTEL traces for a sandbox within a time range\n         * @summary Get sandbox traces\n         * @param {string} sandboxId ID of the sandbox\n         * @param {Date} from Start of time range (ISO 8601)\n         * @param {Date} to End of time range (ISO 8601)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number (1-indexed)\n         * @param {number} [limit] Number of items per page\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxTraces(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, page?: number, limit?: number, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedTraces> {\n            return localVarFp.getSandboxTraces(sandboxId, from, to, xDaytonaOrganizationID, page, limit, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get sandboxes for the authenticated runner\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [states] Comma-separated list of sandbox states to filter by\n         * @param {boolean} [skipReconcilingSandboxes] Skip sandboxes where state differs from desired state\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSandboxesForRunner(xDaytonaOrganizationID?: string, states?: string, skipReconcilingSandboxes?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<Array<Sandbox>> {\n            return localVarFp.getSandboxesForRunner(xDaytonaOrganizationID, states, skipReconcilingSandboxes, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get signed preview URL for a sandbox port\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} port Port number to get signed preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [expiresInSeconds] Expiration time in seconds (default: 60 seconds)\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSignedPortPreviewUrl(sandboxIdOrName: string, port: number, xDaytonaOrganizationID?: string, expiresInSeconds?: number, options?: RawAxiosRequestConfig): AxiosPromise<SignedPortPreviewUrl> {\n            return localVarFp.getSignedPortPreviewUrl(sandboxIdOrName, port, xDaytonaOrganizationID, expiresInSeconds, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get toolbox proxy URL for a sandbox\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getToolboxProxyUrl(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ToolboxProxyUrl> {\n            return localVarFp.getToolboxProxyUrl(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List all sandboxes\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {boolean} [includeErroredDeleted] Include errored and deleted sandboxes\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listSandboxes(xDaytonaOrganizationID?: string, verbose?: boolean, labels?: string, includeErroredDeleted?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<Array<Sandbox>> {\n            return localVarFp.listSandboxes(xDaytonaOrganizationID, verbose, labels, includeErroredDeleted, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List all sandboxes paginated\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {string} [id] Filter by partial ID match\n         * @param {string} [name] Filter by partial name match\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {boolean} [includeErroredDeleted] Include results with errored state and deleted desired state\n         * @param {Array<ListSandboxesPaginatedStatesEnum>} [states] List of states to filter by\n         * @param {Array<string>} [snapshots] List of snapshot names to filter by\n         * @param {Array<string>} [regions] List of regions to filter by\n         * @param {number} [minCpu] Minimum CPU\n         * @param {number} [maxCpu] Maximum CPU\n         * @param {number} [minMemoryGiB] Minimum memory in GiB\n         * @param {number} [maxMemoryGiB] Maximum memory in GiB\n         * @param {number} [minDiskGiB] Minimum disk space in GiB\n         * @param {number} [maxDiskGiB] Maximum disk space in GiB\n         * @param {Date} [lastEventAfter] Include items with last event after this timestamp\n         * @param {Date} [lastEventBefore] Include items with last event before this timestamp\n         * @param {ListSandboxesPaginatedSortEnum} [sort] Field to sort by\n         * @param {ListSandboxesPaginatedOrderEnum} [order] Direction to sort by\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listSandboxesPaginated(xDaytonaOrganizationID?: string, page?: number, limit?: number, id?: string, name?: string, labels?: string, includeErroredDeleted?: boolean, states?: Array<ListSandboxesPaginatedStatesEnum>, snapshots?: Array<string>, regions?: Array<string>, minCpu?: number, maxCpu?: number, minMemoryGiB?: number, maxMemoryGiB?: number, minDiskGiB?: number, maxDiskGiB?: number, lastEventAfter?: Date, lastEventBefore?: Date, sort?: ListSandboxesPaginatedSortEnum, order?: ListSandboxesPaginatedOrderEnum, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedSandboxes> {\n            return localVarFp.listSandboxesPaginated(xDaytonaOrganizationID, page, limit, id, name, labels, includeErroredDeleted, states, snapshots, regions, minCpu, maxCpu, minMemoryGiB, maxMemoryGiB, minDiskGiB, maxDiskGiB, lastEventAfter, lastEventBefore, sort, order, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Recover sandbox from error state\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        recoverSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.recoverSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Replace sandbox labels\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {SandboxLabels} sandboxLabels \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        replaceLabels(sandboxIdOrName: string, sandboxLabels: SandboxLabels, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SandboxLabels> {\n            return localVarFp.replaceLabels(sandboxIdOrName, sandboxLabels, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Resize sandbox resources\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {ResizeSandbox} resizeSandbox \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        resizeSandbox(sandboxIdOrName: string, resizeSandbox: ResizeSandbox, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.resizeSandbox(sandboxIdOrName, resizeSandbox, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Revoke SSH access for sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [token] SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        revokeSshAccess(sandboxIdOrName: string, xDaytonaOrganizationID?: string, token?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.revokeSshAccess(sandboxIdOrName, xDaytonaOrganizationID, token, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Set sandbox auto-archive interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setAutoArchiveInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.setAutoArchiveInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Set sandbox auto-delete interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setAutoDeleteInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.setAutoDeleteInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Set sandbox auto-stop interval\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {number} interval Auto-stop interval in minutes (0 to disable)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setAutostopInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.setAutostopInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Start sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        startSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.startSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Stop sandbox\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        stopSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.stopSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update sandbox last activity\n         * @param {string} sandboxId ID of the sandbox\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateLastActivity(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.updateLastActivity(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update public status\n         * @param {string} sandboxIdOrName ID or name of the sandbox\n         * @param {boolean} isPublic Public status to set\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updatePublicStatus(sandboxIdOrName: string, isPublic: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Sandbox> {\n            return localVarFp.updatePublicStatus(sandboxIdOrName, isPublic, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Update sandbox state\n         * @param {string} sandboxId ID of the sandbox\n         * @param {UpdateSandboxStateDto} updateSandboxStateDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        updateSandboxState(sandboxId: string, updateSandboxStateDto: UpdateSandboxStateDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.updateSandboxState(sandboxId, updateSandboxStateDto, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Validate SSH access for sandbox\n         * @param {string} token SSH access token to validate\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        validateSshAccess(token: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SshAccessValidationDto> {\n            return localVarFp.validateSshAccess(token, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * SandboxApi - object-oriented interface\n * @export\n * @class SandboxApi\n * @extends {BaseAPI}\n */\nexport class SandboxApi extends BaseAPI {\n    /**\n     * \n     * @summary Archive sandbox\n     * @param {string} sandboxIdOrName \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public archiveSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).archiveSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Create sandbox backup\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public createBackup(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).createBackup(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Create a new sandbox\n     * @param {CreateSandbox} createSandbox \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public createSandbox(createSandbox: CreateSandbox, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).createSandbox(createSandbox, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Create SSH access for sandbox\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {number} [expiresInMinutes] Expiration time in minutes (default: 60)\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public createSshAccess(sandboxIdOrName: string, xDaytonaOrganizationID?: string, expiresInMinutes?: number, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).createSshAccess(sandboxIdOrName, xDaytonaOrganizationID, expiresInMinutes, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete sandbox\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public deleteSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).deleteSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Expire signed preview URL for a sandbox port\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {number} port Port number to expire signed preview URL for\n     * @param {string} token Token to expire signed preview URL for\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public expireSignedPortPreviewUrl(sandboxIdOrName: string, port: number, token: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).expireSignedPortPreviewUrl(sandboxIdOrName, port, token, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * This endpoint is deprecated. Use `getBuildLogsUrl` instead.\n     * @summary Get build logs\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [follow] Whether to follow the logs stream\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getBuildLogs(sandboxIdOrName: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getBuildLogs(sandboxIdOrName, xDaytonaOrganizationID, follow, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get build logs URL\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getBuildLogsUrl(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getBuildLogsUrl(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get preview URL for a sandbox port\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {number} port Port number to get preview URL for\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getPortPreviewUrl(sandboxIdOrName: string, port: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getPortPreviewUrl(sandboxIdOrName, port, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get sandbox details\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [verbose] Include verbose output\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, verbose?: boolean, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getSandbox(sandboxIdOrName, xDaytonaOrganizationID, verbose, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Retrieve OTEL logs for a sandbox within a time range\n     * @summary Get sandbox logs\n     * @param {string} sandboxId ID of the sandbox\n     * @param {Date} from Start of time range (ISO 8601)\n     * @param {Date} to End of time range (ISO 8601)\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {number} [page] Page number (1-indexed)\n     * @param {number} [limit] Number of items per page\n     * @param {Array<string>} [severities] Filter by severity levels (DEBUG, INFO, WARN, ERROR)\n     * @param {string} [search] Search in log body\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getSandboxLogs(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, page?: number, limit?: number, severities?: Array<string>, search?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getSandboxLogs(sandboxId, from, to, xDaytonaOrganizationID, page, limit, severities, search, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Retrieve OTEL metrics for a sandbox within a time range\n     * @summary Get sandbox metrics\n     * @param {string} sandboxId ID of the sandbox\n     * @param {Date} from Start of time range (ISO 8601)\n     * @param {Date} to End of time range (ISO 8601)\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {Array<string>} [metricNames] Filter by metric names\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getSandboxMetrics(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, metricNames?: Array<string>, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getSandboxMetrics(sandboxId, from, to, xDaytonaOrganizationID, metricNames, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Retrieve all spans for a specific trace\n     * @summary Get trace spans\n     * @param {string} sandboxId ID of the sandbox\n     * @param {string} traceId ID of the trace\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getSandboxTraceSpans(sandboxId: string, traceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getSandboxTraceSpans(sandboxId, traceId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Retrieve OTEL traces for a sandbox within a time range\n     * @summary Get sandbox traces\n     * @param {string} sandboxId ID of the sandbox\n     * @param {Date} from Start of time range (ISO 8601)\n     * @param {Date} to End of time range (ISO 8601)\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {number} [page] Page number (1-indexed)\n     * @param {number} [limit] Number of items per page\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getSandboxTraces(sandboxId: string, from: Date, to: Date, xDaytonaOrganizationID?: string, page?: number, limit?: number, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getSandboxTraces(sandboxId, from, to, xDaytonaOrganizationID, page, limit, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get sandboxes for the authenticated runner\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {string} [states] Comma-separated list of sandbox states to filter by\n     * @param {boolean} [skipReconcilingSandboxes] Skip sandboxes where state differs from desired state\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getSandboxesForRunner(xDaytonaOrganizationID?: string, states?: string, skipReconcilingSandboxes?: boolean, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getSandboxesForRunner(xDaytonaOrganizationID, states, skipReconcilingSandboxes, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get signed preview URL for a sandbox port\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {number} port Port number to get signed preview URL for\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {number} [expiresInSeconds] Expiration time in seconds (default: 60 seconds)\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getSignedPortPreviewUrl(sandboxIdOrName: string, port: number, xDaytonaOrganizationID?: string, expiresInSeconds?: number, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getSignedPortPreviewUrl(sandboxIdOrName, port, xDaytonaOrganizationID, expiresInSeconds, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get toolbox proxy URL for a sandbox\n     * @param {string} sandboxId ID of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public getToolboxProxyUrl(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).getToolboxProxyUrl(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List all sandboxes\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [verbose] Include verbose output\n     * @param {string} [labels] JSON encoded labels to filter by\n     * @param {boolean} [includeErroredDeleted] Include errored and deleted sandboxes\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public listSandboxes(xDaytonaOrganizationID?: string, verbose?: boolean, labels?: string, includeErroredDeleted?: boolean, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).listSandboxes(xDaytonaOrganizationID, verbose, labels, includeErroredDeleted, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List all sandboxes paginated\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {number} [page] Page number of the results\n     * @param {number} [limit] Number of results per page\n     * @param {string} [id] Filter by partial ID match\n     * @param {string} [name] Filter by partial name match\n     * @param {string} [labels] JSON encoded labels to filter by\n     * @param {boolean} [includeErroredDeleted] Include results with errored state and deleted desired state\n     * @param {Array<ListSandboxesPaginatedStatesEnum>} [states] List of states to filter by\n     * @param {Array<string>} [snapshots] List of snapshot names to filter by\n     * @param {Array<string>} [regions] List of regions to filter by\n     * @param {number} [minCpu] Minimum CPU\n     * @param {number} [maxCpu] Maximum CPU\n     * @param {number} [minMemoryGiB] Minimum memory in GiB\n     * @param {number} [maxMemoryGiB] Maximum memory in GiB\n     * @param {number} [minDiskGiB] Minimum disk space in GiB\n     * @param {number} [maxDiskGiB] Maximum disk space in GiB\n     * @param {Date} [lastEventAfter] Include items with last event after this timestamp\n     * @param {Date} [lastEventBefore] Include items with last event before this timestamp\n     * @param {ListSandboxesPaginatedSortEnum} [sort] Field to sort by\n     * @param {ListSandboxesPaginatedOrderEnum} [order] Direction to sort by\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public listSandboxesPaginated(xDaytonaOrganizationID?: string, page?: number, limit?: number, id?: string, name?: string, labels?: string, includeErroredDeleted?: boolean, states?: Array<ListSandboxesPaginatedStatesEnum>, snapshots?: Array<string>, regions?: Array<string>, minCpu?: number, maxCpu?: number, minMemoryGiB?: number, maxMemoryGiB?: number, minDiskGiB?: number, maxDiskGiB?: number, lastEventAfter?: Date, lastEventBefore?: Date, sort?: ListSandboxesPaginatedSortEnum, order?: ListSandboxesPaginatedOrderEnum, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).listSandboxesPaginated(xDaytonaOrganizationID, page, limit, id, name, labels, includeErroredDeleted, states, snapshots, regions, minCpu, maxCpu, minMemoryGiB, maxMemoryGiB, minDiskGiB, maxDiskGiB, lastEventAfter, lastEventBefore, sort, order, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Recover sandbox from error state\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public recoverSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).recoverSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Replace sandbox labels\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {SandboxLabels} sandboxLabels \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public replaceLabels(sandboxIdOrName: string, sandboxLabels: SandboxLabels, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).replaceLabels(sandboxIdOrName, sandboxLabels, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Resize sandbox resources\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {ResizeSandbox} resizeSandbox \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public resizeSandbox(sandboxIdOrName: string, resizeSandbox: ResizeSandbox, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).resizeSandbox(sandboxIdOrName, resizeSandbox, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Revoke SSH access for sandbox\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {string} [token] SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public revokeSshAccess(sandboxIdOrName: string, xDaytonaOrganizationID?: string, token?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).revokeSshAccess(sandboxIdOrName, xDaytonaOrganizationID, token, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Set sandbox auto-archive interval\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {number} interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public setAutoArchiveInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).setAutoArchiveInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Set sandbox auto-delete interval\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {number} interval Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public setAutoDeleteInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).setAutoDeleteInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Set sandbox auto-stop interval\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {number} interval Auto-stop interval in minutes (0 to disable)\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public setAutostopInterval(sandboxIdOrName: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).setAutostopInterval(sandboxIdOrName, interval, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Start sandbox\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public startSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).startSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Stop sandbox\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public stopSandbox(sandboxIdOrName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).stopSandbox(sandboxIdOrName, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update sandbox last activity\n     * @param {string} sandboxId ID of the sandbox\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public updateLastActivity(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).updateLastActivity(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update public status\n     * @param {string} sandboxIdOrName ID or name of the sandbox\n     * @param {boolean} isPublic Public status to set\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public updatePublicStatus(sandboxIdOrName: string, isPublic: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).updatePublicStatus(sandboxIdOrName, isPublic, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Update sandbox state\n     * @param {string} sandboxId ID of the sandbox\n     * @param {UpdateSandboxStateDto} updateSandboxStateDto \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public updateSandboxState(sandboxId: string, updateSandboxStateDto: UpdateSandboxStateDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).updateSandboxState(sandboxId, updateSandboxStateDto, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Validate SSH access for sandbox\n     * @param {string} token SSH access token to validate\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SandboxApi\n     */\n    public validateSshAccess(token: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SandboxApiFp(this.configuration).validateSshAccess(token, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n/**\n * @export\n */\nexport const ListSandboxesPaginatedStatesEnum = {\n    CREATING: 'creating',\n    RESTORING: 'restoring',\n    DESTROYING: 'destroying',\n    STARTED: 'started',\n    STOPPED: 'stopped',\n    STARTING: 'starting',\n    STOPPING: 'stopping',\n    ERROR: 'error',\n    BUILD_FAILED: 'build_failed',\n    PENDING_BUILD: 'pending_build',\n    BUILDING_SNAPSHOT: 'building_snapshot',\n    UNKNOWN: 'unknown',\n    PULLING_SNAPSHOT: 'pulling_snapshot',\n    ARCHIVED: 'archived',\n    ARCHIVING: 'archiving',\n    RESIZING: 'resizing'\n} as const;\nexport type ListSandboxesPaginatedStatesEnum = typeof ListSandboxesPaginatedStatesEnum[keyof typeof ListSandboxesPaginatedStatesEnum];\n/**\n * @export\n */\nexport const ListSandboxesPaginatedSortEnum = {\n    ID: 'id',\n    NAME: 'name',\n    STATE: 'state',\n    SNAPSHOT: 'snapshot',\n    REGION: 'region',\n    UPDATED_AT: 'updatedAt',\n    CREATED_AT: 'createdAt'\n} as const;\nexport type ListSandboxesPaginatedSortEnum = typeof ListSandboxesPaginatedSortEnum[keyof typeof ListSandboxesPaginatedSortEnum];\n/**\n * @export\n */\nexport const ListSandboxesPaginatedOrderEnum = {\n    ASC: 'asc',\n    DESC: 'desc'\n} as const;\nexport type ListSandboxesPaginatedOrderEnum = typeof ListSandboxesPaginatedOrderEnum[keyof typeof ListSandboxesPaginatedOrderEnum];\n"
  },
  {
    "path": "libs/api-client/src/api/snapshots-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { CreateSnapshot } from '../models';\n// @ts-ignore\nimport type { PaginatedSnapshots } from '../models';\n// @ts-ignore\nimport type { SetSnapshotGeneralStatusDto } from '../models';\n// @ts-ignore\nimport type { SnapshotDto } from '../models';\n// @ts-ignore\nimport type { Url } from '../models';\n/**\n * SnapshotsApi - axios parameter creator\n * @export\n */\nexport const SnapshotsApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Activate a snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        activateSnapshot: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('activateSnapshot', 'id', id)\n            const localVarPath = `/snapshots/{id}/activate`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Check if an image can be cleaned up\n         * @param {string} imageName Image name with tag to check\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        canCleanupImage: async (imageName: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'imageName' is not null or undefined\n            assertParamExists('canCleanupImage', 'imageName', imageName)\n            const localVarPath = `/snapshots/can-cleanup-image`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (imageName !== undefined) {\n                localVarQueryParameter['imageName'] = imageName;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Create a new snapshot\n         * @param {CreateSnapshot} createSnapshot \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createSnapshot: async (createSnapshot: CreateSnapshot, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createSnapshot' is not null or undefined\n            assertParamExists('createSnapshot', 'createSnapshot', createSnapshot)\n            const localVarPath = `/snapshots`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createSnapshot, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Deactivate a snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deactivateSnapshot: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('deactivateSnapshot', 'id', id)\n            const localVarPath = `/snapshots/{id}/deactivate`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List all snapshots\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {string} [name] Filter by partial name match\n         * @param {GetAllSnapshotsSortEnum} [sort] Field to sort by\n         * @param {GetAllSnapshotsOrderEnum} [order] Direction to sort by\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getAllSnapshots: async (xDaytonaOrganizationID?: string, page?: number, limit?: number, name?: string, sort?: GetAllSnapshotsSortEnum, order?: GetAllSnapshotsOrderEnum, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/snapshots`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (page !== undefined) {\n                localVarQueryParameter['page'] = page;\n            }\n\n            if (limit !== undefined) {\n                localVarQueryParameter['limit'] = limit;\n            }\n\n            if (name !== undefined) {\n                localVarQueryParameter['name'] = name;\n            }\n\n            if (sort !== undefined) {\n                localVarQueryParameter['sort'] = sort;\n            }\n\n            if (order !== undefined) {\n                localVarQueryParameter['order'] = order;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get snapshot by ID or name\n         * @param {string} id Snapshot ID or name\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSnapshot: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('getSnapshot', 'id', id)\n            const localVarPath = `/snapshots/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n         * @summary Get snapshot build logs\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getSnapshotBuildLogs: async (id: string, xDaytonaOrganizationID?: string, follow?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('getSnapshotBuildLogs', 'id', id)\n            const localVarPath = `/snapshots/{id}/build-logs`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (follow !== undefined) {\n                localVarQueryParameter['follow'] = follow;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get snapshot build logs URL\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSnapshotBuildLogsUrl: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('getSnapshotBuildLogsUrl', 'id', id)\n            const localVarPath = `/snapshots/{id}/build-logs-url`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        removeSnapshot: async (id: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('removeSnapshot', 'id', id)\n            const localVarPath = `/snapshots/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Set snapshot general status\n         * @param {string} id Snapshot ID\n         * @param {SetSnapshotGeneralStatusDto} setSnapshotGeneralStatusDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setSnapshotGeneralStatus: async (id: string, setSnapshotGeneralStatusDto: SetSnapshotGeneralStatusDto, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('setSnapshotGeneralStatus', 'id', id)\n            // verify required parameter 'setSnapshotGeneralStatusDto' is not null or undefined\n            assertParamExists('setSnapshotGeneralStatus', 'setSnapshotGeneralStatusDto', setSnapshotGeneralStatusDto)\n            const localVarPath = `/snapshots/{id}/general`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(setSnapshotGeneralStatusDto, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * SnapshotsApi - functional programming interface\n * @export\n */\nexport const SnapshotsApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = SnapshotsApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Activate a snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async activateSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SnapshotDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.activateSnapshot(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.activateSnapshot']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Check if an image can be cleaned up\n         * @param {string} imageName Image name with tag to check\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async canCleanupImage(imageName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<boolean>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.canCleanupImage(imageName, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.canCleanupImage']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Create a new snapshot\n         * @param {CreateSnapshot} createSnapshot \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createSnapshot(createSnapshot: CreateSnapshot, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SnapshotDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createSnapshot(createSnapshot, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.createSnapshot']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Deactivate a snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deactivateSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deactivateSnapshot(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.deactivateSnapshot']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List all snapshots\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {string} [name] Filter by partial name match\n         * @param {GetAllSnapshotsSortEnum} [sort] Field to sort by\n         * @param {GetAllSnapshotsOrderEnum} [order] Direction to sort by\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getAllSnapshots(xDaytonaOrganizationID?: string, page?: number, limit?: number, name?: string, sort?: GetAllSnapshotsSortEnum, order?: GetAllSnapshotsOrderEnum, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PaginatedSnapshots>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getAllSnapshots(xDaytonaOrganizationID, page, limit, name, sort, order, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.getAllSnapshots']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get snapshot by ID or name\n         * @param {string} id Snapshot ID or name\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SnapshotDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSnapshot(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.getSnapshot']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n         * @summary Get snapshot build logs\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getSnapshotBuildLogs(id: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSnapshotBuildLogs(id, xDaytonaOrganizationID, follow, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.getSnapshotBuildLogs']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get snapshot build logs URL\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getSnapshotBuildLogsUrl(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Url>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSnapshotBuildLogsUrl(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.getSnapshotBuildLogsUrl']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async removeSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.removeSnapshot(id, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.removeSnapshot']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Set snapshot general status\n         * @param {string} id Snapshot ID\n         * @param {SetSnapshotGeneralStatusDto} setSnapshotGeneralStatusDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async setSnapshotGeneralStatus(id: string, setSnapshotGeneralStatusDto: SetSnapshotGeneralStatusDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SnapshotDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setSnapshotGeneralStatus(id, setSnapshotGeneralStatusDto, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['SnapshotsApi.setSnapshotGeneralStatus']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * SnapshotsApi - factory interface\n * @export\n */\nexport const SnapshotsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = SnapshotsApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Activate a snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        activateSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SnapshotDto> {\n            return localVarFp.activateSnapshot(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Check if an image can be cleaned up\n         * @param {string} imageName Image name with tag to check\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        canCleanupImage(imageName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<boolean> {\n            return localVarFp.canCleanupImage(imageName, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Create a new snapshot\n         * @param {CreateSnapshot} createSnapshot \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createSnapshot(createSnapshot: CreateSnapshot, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SnapshotDto> {\n            return localVarFp.createSnapshot(createSnapshot, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Deactivate a snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deactivateSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deactivateSnapshot(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List all snapshots\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [page] Page number of the results\n         * @param {number} [limit] Number of results per page\n         * @param {string} [name] Filter by partial name match\n         * @param {GetAllSnapshotsSortEnum} [sort] Field to sort by\n         * @param {GetAllSnapshotsOrderEnum} [order] Direction to sort by\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getAllSnapshots(xDaytonaOrganizationID?: string, page?: number, limit?: number, name?: string, sort?: GetAllSnapshotsSortEnum, order?: GetAllSnapshotsOrderEnum, options?: RawAxiosRequestConfig): AxiosPromise<PaginatedSnapshots> {\n            return localVarFp.getAllSnapshots(xDaytonaOrganizationID, page, limit, name, sort, order, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get snapshot by ID or name\n         * @param {string} id Snapshot ID or name\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SnapshotDto> {\n            return localVarFp.getSnapshot(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n         * @summary Get snapshot build logs\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getSnapshotBuildLogs(id: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.getSnapshotBuildLogs(id, xDaytonaOrganizationID, follow, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get snapshot build logs URL\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getSnapshotBuildLogsUrl(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Url> {\n            return localVarFp.getSnapshotBuildLogsUrl(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete snapshot\n         * @param {string} id Snapshot ID\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        removeSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.removeSnapshot(id, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Set snapshot general status\n         * @param {string} id Snapshot ID\n         * @param {SetSnapshotGeneralStatusDto} setSnapshotGeneralStatusDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        setSnapshotGeneralStatus(id: string, setSnapshotGeneralStatusDto: SetSnapshotGeneralStatusDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SnapshotDto> {\n            return localVarFp.setSnapshotGeneralStatus(id, setSnapshotGeneralStatusDto, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * SnapshotsApi - object-oriented interface\n * @export\n * @class SnapshotsApi\n * @extends {BaseAPI}\n */\nexport class SnapshotsApi extends BaseAPI {\n    /**\n     * \n     * @summary Activate a snapshot\n     * @param {string} id Snapshot ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public activateSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).activateSnapshot(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Check if an image can be cleaned up\n     * @param {string} imageName Image name with tag to check\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public canCleanupImage(imageName: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).canCleanupImage(imageName, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Create a new snapshot\n     * @param {CreateSnapshot} createSnapshot \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public createSnapshot(createSnapshot: CreateSnapshot, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).createSnapshot(createSnapshot, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Deactivate a snapshot\n     * @param {string} id Snapshot ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public deactivateSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).deactivateSnapshot(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List all snapshots\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {number} [page] Page number of the results\n     * @param {number} [limit] Number of results per page\n     * @param {string} [name] Filter by partial name match\n     * @param {GetAllSnapshotsSortEnum} [sort] Field to sort by\n     * @param {GetAllSnapshotsOrderEnum} [order] Direction to sort by\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public getAllSnapshots(xDaytonaOrganizationID?: string, page?: number, limit?: number, name?: string, sort?: GetAllSnapshotsSortEnum, order?: GetAllSnapshotsOrderEnum, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).getAllSnapshots(xDaytonaOrganizationID, page, limit, name, sort, order, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get snapshot by ID or name\n     * @param {string} id Snapshot ID or name\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public getSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).getSnapshot(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n     * @summary Get snapshot build logs\n     * @param {string} id Snapshot ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [follow] Whether to follow the logs stream\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public getSnapshotBuildLogs(id: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).getSnapshotBuildLogs(id, xDaytonaOrganizationID, follow, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get snapshot build logs URL\n     * @param {string} id Snapshot ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public getSnapshotBuildLogsUrl(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).getSnapshotBuildLogsUrl(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete snapshot\n     * @param {string} id Snapshot ID\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public removeSnapshot(id: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).removeSnapshot(id, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Set snapshot general status\n     * @param {string} id Snapshot ID\n     * @param {SetSnapshotGeneralStatusDto} setSnapshotGeneralStatusDto \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof SnapshotsApi\n     */\n    public setSnapshotGeneralStatus(id: string, setSnapshotGeneralStatusDto: SetSnapshotGeneralStatusDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return SnapshotsApiFp(this.configuration).setSnapshotGeneralStatus(id, setSnapshotGeneralStatusDto, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n/**\n * @export\n */\nexport const GetAllSnapshotsSortEnum = {\n    NAME: 'name',\n    STATE: 'state',\n    LAST_USED_AT: 'lastUsedAt',\n    CREATED_AT: 'createdAt'\n} as const;\nexport type GetAllSnapshotsSortEnum = typeof GetAllSnapshotsSortEnum[keyof typeof GetAllSnapshotsSortEnum];\n/**\n * @export\n */\nexport const GetAllSnapshotsOrderEnum = {\n    ASC: 'asc',\n    DESC: 'desc'\n} as const;\nexport type GetAllSnapshotsOrderEnum = typeof GetAllSnapshotsOrderEnum[keyof typeof GetAllSnapshotsOrderEnum];\n"
  },
  {
    "path": "libs/api-client/src/api/toolbox-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { Command } from '../models';\n// @ts-ignore\nimport type { CompletionList } from '../models';\n// @ts-ignore\nimport type { CompressedScreenshotResponse } from '../models';\n// @ts-ignore\nimport type { ComputerUseStartResponse } from '../models';\n// @ts-ignore\nimport type { ComputerUseStatusResponse } from '../models';\n// @ts-ignore\nimport type { ComputerUseStopResponse } from '../models';\n// @ts-ignore\nimport type { CreateSessionRequest } from '../models';\n// @ts-ignore\nimport type { DisplayInfoResponse } from '../models';\n// @ts-ignore\nimport type { DownloadFiles } from '../models';\n// @ts-ignore\nimport type { ExecuteRequest } from '../models';\n// @ts-ignore\nimport type { ExecuteResponse } from '../models';\n// @ts-ignore\nimport type { FileInfo } from '../models';\n// @ts-ignore\nimport type { GitAddRequest } from '../models';\n// @ts-ignore\nimport type { GitBranchRequest } from '../models';\n// @ts-ignore\nimport type { GitCheckoutRequest } from '../models';\n// @ts-ignore\nimport type { GitCloneRequest } from '../models';\n// @ts-ignore\nimport type { GitCommitInfo } from '../models';\n// @ts-ignore\nimport type { GitCommitRequest } from '../models';\n// @ts-ignore\nimport type { GitCommitResponse } from '../models';\n// @ts-ignore\nimport type { GitDeleteBranchRequest } from '../models';\n// @ts-ignore\nimport type { GitRepoRequest } from '../models';\n// @ts-ignore\nimport type { GitStatus } from '../models';\n// @ts-ignore\nimport type { KeyboardHotkeyRequest } from '../models';\n// @ts-ignore\nimport type { KeyboardPressRequest } from '../models';\n// @ts-ignore\nimport type { KeyboardTypeRequest } from '../models';\n// @ts-ignore\nimport type { ListBranchResponse } from '../models';\n// @ts-ignore\nimport type { LspCompletionParams } from '../models';\n// @ts-ignore\nimport type { LspDocumentRequest } from '../models';\n// @ts-ignore\nimport type { LspServerRequest } from '../models';\n// @ts-ignore\nimport type { LspSymbol } from '../models';\n// @ts-ignore\nimport type { Match } from '../models';\n// @ts-ignore\nimport type { MouseClickRequest } from '../models';\n// @ts-ignore\nimport type { MouseClickResponse } from '../models';\n// @ts-ignore\nimport type { MouseDragRequest } from '../models';\n// @ts-ignore\nimport type { MouseDragResponse } from '../models';\n// @ts-ignore\nimport type { MouseMoveRequest } from '../models';\n// @ts-ignore\nimport type { MouseMoveResponse } from '../models';\n// @ts-ignore\nimport type { MousePosition } from '../models';\n// @ts-ignore\nimport type { MouseScrollRequest } from '../models';\n// @ts-ignore\nimport type { MouseScrollResponse } from '../models';\n// @ts-ignore\nimport type { ProcessErrorsResponse } from '../models';\n// @ts-ignore\nimport type { ProcessLogsResponse } from '../models';\n// @ts-ignore\nimport type { ProcessRestartResponse } from '../models';\n// @ts-ignore\nimport type { ProcessStatusResponse } from '../models';\n// @ts-ignore\nimport type { ProjectDirResponse } from '../models';\n// @ts-ignore\nimport type { PtyCreateRequest } from '../models';\n// @ts-ignore\nimport type { PtyCreateResponse } from '../models';\n// @ts-ignore\nimport type { PtyListResponse } from '../models';\n// @ts-ignore\nimport type { PtyResizeRequest } from '../models';\n// @ts-ignore\nimport type { PtySessionInfo } from '../models';\n// @ts-ignore\nimport type { RegionScreenshotResponse } from '../models';\n// @ts-ignore\nimport type { ReplaceRequest } from '../models';\n// @ts-ignore\nimport type { ReplaceResult } from '../models';\n// @ts-ignore\nimport type { ScreenshotResponse } from '../models';\n// @ts-ignore\nimport type { SearchFilesResponse } from '../models';\n// @ts-ignore\nimport type { Session } from '../models';\n// @ts-ignore\nimport type { SessionExecuteRequest } from '../models';\n// @ts-ignore\nimport type { SessionExecuteResponse } from '../models';\n// @ts-ignore\nimport type { UserHomeDirResponse } from '../models';\n// @ts-ignore\nimport type { WindowsResponse } from '../models';\n// @ts-ignore\nimport type { WorkDirResponse } from '../models';\n/**\n * ToolboxApi - axios parameter creator\n * @export\n */\nexport const ToolboxApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * Click mouse at specified coordinates\n         * @summary [DEPRECATED] Click mouse\n         * @param {string} sandboxId \n         * @param {MouseClickRequest} mouseClickRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        clickMouseDeprecated: async (sandboxId: string, mouseClickRequest: MouseClickRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('clickMouseDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'mouseClickRequest' is not null or undefined\n            assertParamExists('clickMouseDeprecated', 'mouseClickRequest', mouseClickRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/mouse/click`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(mouseClickRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Create folder inside sandbox\n         * @summary [DEPRECATED] Create folder\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} mode \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createFolderDeprecated: async (sandboxId: string, path: string, mode: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('createFolderDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('createFolderDeprecated', 'path', path)\n            // verify required parameter 'mode' is not null or undefined\n            assertParamExists('createFolderDeprecated', 'mode', mode)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/folder`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n            if (mode !== undefined) {\n                localVarQueryParameter['mode'] = mode;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Create a new PTY session in the sandbox\n         * @summary [DEPRECATED] Create PTY session\n         * @param {string} sandboxId \n         * @param {PtyCreateRequest} ptyCreateRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createPTYSessionDeprecated: async (sandboxId: string, ptyCreateRequest: PtyCreateRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('createPTYSessionDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'ptyCreateRequest' is not null or undefined\n            assertParamExists('createPTYSessionDeprecated', 'ptyCreateRequest', ptyCreateRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/pty`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(ptyCreateRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Create a new session in the sandbox\n         * @summary [DEPRECATED] Create session\n         * @param {string} sandboxId \n         * @param {CreateSessionRequest} createSessionRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createSessionDeprecated: async (sandboxId: string, createSessionRequest: CreateSessionRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('createSessionDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'createSessionRequest' is not null or undefined\n            assertParamExists('createSessionDeprecated', 'createSessionRequest', createSessionRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/session`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createSessionRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Delete file inside sandbox\n         * @summary [DEPRECATED] Delete file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [recursive] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        deleteFileDeprecated: async (sandboxId: string, path: string, xDaytonaOrganizationID?: string, recursive?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('deleteFileDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('deleteFileDeprecated', 'path', path)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (recursive !== undefined) {\n                localVarQueryParameter['recursive'] = recursive;\n            }\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Delete a PTY session and terminate the associated process\n         * @summary [DEPRECATED] Delete PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        deletePTYSessionDeprecated: async (sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('deletePTYSessionDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'sessionId' is not null or undefined\n            assertParamExists('deletePTYSessionDeprecated', 'sessionId', sessionId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"sessionId\"}}`, encodeURIComponent(String(sessionId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Delete a specific session\n         * @summary [DEPRECATED] Delete session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        deleteSessionDeprecated: async (sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('deleteSessionDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'sessionId' is not null or undefined\n            assertParamExists('deleteSessionDeprecated', 'sessionId', sessionId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/session/{sessionId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"sessionId\"}}`, encodeURIComponent(String(sessionId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Download file from sandbox\n         * @summary [DEPRECATED] Download file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        downloadFileDeprecated: async (sandboxId: string, path: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('downloadFileDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('downloadFileDeprecated', 'path', path)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/download`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Streams back a multipart/form-data bundle of the requested paths\n         * @summary [DEPRECATED] Download multiple files\n         * @param {string} sandboxId \n         * @param {DownloadFiles} downloadFiles \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        downloadFilesDeprecated: async (sandboxId: string, downloadFiles: DownloadFiles, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('downloadFilesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'downloadFiles' is not null or undefined\n            assertParamExists('downloadFilesDeprecated', 'downloadFiles', downloadFiles)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/bulk-download`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(downloadFiles, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Drag mouse from start to end coordinates\n         * @summary [DEPRECATED] Drag mouse\n         * @param {string} sandboxId \n         * @param {MouseDragRequest} mouseDragRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        dragMouseDeprecated: async (sandboxId: string, mouseDragRequest: MouseDragRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('dragMouseDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'mouseDragRequest' is not null or undefined\n            assertParamExists('dragMouseDeprecated', 'mouseDragRequest', mouseDragRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/mouse/drag`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(mouseDragRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Execute command synchronously inside sandbox\n         * @summary [DEPRECATED] Execute command\n         * @param {string} sandboxId \n         * @param {ExecuteRequest} executeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        executeCommandDeprecated: async (sandboxId: string, executeRequest: ExecuteRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('executeCommandDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'executeRequest' is not null or undefined\n            assertParamExists('executeCommandDeprecated', 'executeRequest', executeRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/execute`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(executeRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Execute a command in a specific session\n         * @summary [DEPRECATED] Execute command in session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {SessionExecuteRequest} sessionExecuteRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        executeSessionCommandDeprecated: async (sandboxId: string, sessionId: string, sessionExecuteRequest: SessionExecuteRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('executeSessionCommandDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'sessionId' is not null or undefined\n            assertParamExists('executeSessionCommandDeprecated', 'sessionId', sessionId)\n            // verify required parameter 'sessionExecuteRequest' is not null or undefined\n            assertParamExists('executeSessionCommandDeprecated', 'sessionExecuteRequest', sessionExecuteRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/exec`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"sessionId\"}}`, encodeURIComponent(String(sessionId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(sessionExecuteRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Search for text/pattern inside sandbox files\n         * @summary [DEPRECATED] Search for text/pattern in files\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} pattern \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        findInFilesDeprecated: async (sandboxId: string, path: string, pattern: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('findInFilesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('findInFilesDeprecated', 'path', path)\n            // verify required parameter 'pattern' is not null or undefined\n            assertParamExists('findInFilesDeprecated', 'pattern', pattern)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/find`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n            if (pattern !== undefined) {\n                localVarQueryParameter['pattern'] = pattern;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get status of all VNC desktop processes\n         * @summary [DEPRECATED] Get computer use status\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getComputerUseStatusDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getComputerUseStatusDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/status`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get information about displays\n         * @summary [DEPRECATED] Get display info\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getDisplayInfoDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getDisplayInfoDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/display/info`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get file info inside sandbox\n         * @summary [DEPRECATED] Get file info\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getFileInfoDeprecated: async (sandboxId: string, path: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getFileInfoDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('getFileInfoDeprecated', 'path', path)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/info`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get current mouse cursor position\n         * @summary [DEPRECATED] Get mouse position\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getMousePositionDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getMousePositionDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/mouse/position`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get PTY session information by ID\n         * @summary [DEPRECATED] Get PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getPTYSessionDeprecated: async (sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getPTYSessionDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'sessionId' is not null or undefined\n            assertParamExists('getPTYSessionDeprecated', 'sessionId', sessionId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"sessionId\"}}`, encodeURIComponent(String(sessionId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get error logs for a specific VNC process\n         * @summary [DEPRECATED] Get process errors\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getProcessErrorsDeprecated: async (processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'processName' is not null or undefined\n            assertParamExists('getProcessErrorsDeprecated', 'processName', processName)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getProcessErrorsDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/errors`\n                .replace(`{${\"processName\"}}`, encodeURIComponent(String(processName)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get logs for a specific VNC process\n         * @summary [DEPRECATED] Get process logs\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getProcessLogsDeprecated: async (processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'processName' is not null or undefined\n            assertParamExists('getProcessLogsDeprecated', 'processName', processName)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getProcessLogsDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/logs`\n                .replace(`{${\"processName\"}}`, encodeURIComponent(String(processName)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get status of a specific VNC process\n         * @summary [DEPRECATED] Get process status\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getProcessStatusDeprecated: async (processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'processName' is not null or undefined\n            assertParamExists('getProcessStatusDeprecated', 'processName', processName)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getProcessStatusDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/status`\n                .replace(`{${\"processName\"}}`, encodeURIComponent(String(processName)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox project dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getProjectDirDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getProjectDirDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/project-dir`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get session command by ID\n         * @summary [DEPRECATED] Get session command\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} commandId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getSessionCommandDeprecated: async (sandboxId: string, sessionId: string, commandId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getSessionCommandDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'sessionId' is not null or undefined\n            assertParamExists('getSessionCommandDeprecated', 'sessionId', sessionId)\n            // verify required parameter 'commandId' is not null or undefined\n            assertParamExists('getSessionCommandDeprecated', 'commandId', commandId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"sessionId\"}}`, encodeURIComponent(String(sessionId)))\n                .replace(`{${\"commandId\"}}`, encodeURIComponent(String(commandId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get logs for a specific command in a session\n         * @summary [DEPRECATED] Get command logs\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} commandId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to stream the logs\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getSessionCommandLogsDeprecated: async (sandboxId: string, sessionId: string, commandId: string, xDaytonaOrganizationID?: string, follow?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getSessionCommandLogsDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'sessionId' is not null or undefined\n            assertParamExists('getSessionCommandLogsDeprecated', 'sessionId', sessionId)\n            // verify required parameter 'commandId' is not null or undefined\n            assertParamExists('getSessionCommandLogsDeprecated', 'commandId', commandId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}/logs`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"sessionId\"}}`, encodeURIComponent(String(sessionId)))\n                .replace(`{${\"commandId\"}}`, encodeURIComponent(String(commandId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (follow !== undefined) {\n                localVarQueryParameter['follow'] = follow;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get session by ID\n         * @summary [DEPRECATED] Get session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getSessionDeprecated: async (sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getSessionDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'sessionId' is not null or undefined\n            assertParamExists('getSessionDeprecated', 'sessionId', sessionId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/session/{sessionId}`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"sessionId\"}}`, encodeURIComponent(String(sessionId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox user home dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getUserHomeDirDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getUserHomeDirDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/user-home-dir`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get list of open windows\n         * @summary [DEPRECATED] Get windows\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getWindowsDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getWindowsDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/display/windows`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox work-dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getWorkDirDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('getWorkDirDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/work-dir`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Add files to git commit\n         * @summary [DEPRECATED] Add files\n         * @param {string} sandboxId \n         * @param {GitAddRequest} gitAddRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitAddFilesDeprecated: async (sandboxId: string, gitAddRequest: GitAddRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitAddFilesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'gitAddRequest' is not null or undefined\n            assertParamExists('gitAddFilesDeprecated', 'gitAddRequest', gitAddRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/add`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(gitAddRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Checkout branch or commit in git repository\n         * @summary [DEPRECATED] Checkout branch\n         * @param {string} sandboxId \n         * @param {GitCheckoutRequest} gitCheckoutRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitCheckoutBranchDeprecated: async (sandboxId: string, gitCheckoutRequest: GitCheckoutRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitCheckoutBranchDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'gitCheckoutRequest' is not null or undefined\n            assertParamExists('gitCheckoutBranchDeprecated', 'gitCheckoutRequest', gitCheckoutRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/checkout`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(gitCheckoutRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Clone git repository\n         * @summary [DEPRECATED] Clone repository\n         * @param {string} sandboxId \n         * @param {GitCloneRequest} gitCloneRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitCloneRepositoryDeprecated: async (sandboxId: string, gitCloneRequest: GitCloneRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitCloneRepositoryDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'gitCloneRequest' is not null or undefined\n            assertParamExists('gitCloneRepositoryDeprecated', 'gitCloneRequest', gitCloneRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/clone`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(gitCloneRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Commit changes to git repository\n         * @summary [DEPRECATED] Commit changes\n         * @param {string} sandboxId \n         * @param {GitCommitRequest} gitCommitRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitCommitChangesDeprecated: async (sandboxId: string, gitCommitRequest: GitCommitRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitCommitChangesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'gitCommitRequest' is not null or undefined\n            assertParamExists('gitCommitChangesDeprecated', 'gitCommitRequest', gitCommitRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/commit`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(gitCommitRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Create branch on git repository\n         * @summary [DEPRECATED] Create branch\n         * @param {string} sandboxId \n         * @param {GitBranchRequest} gitBranchRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitCreateBranchDeprecated: async (sandboxId: string, gitBranchRequest: GitBranchRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitCreateBranchDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'gitBranchRequest' is not null or undefined\n            assertParamExists('gitCreateBranchDeprecated', 'gitBranchRequest', gitBranchRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/branches`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(gitBranchRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Delete branch on git repository\n         * @summary [DEPRECATED] Delete branch\n         * @param {string} sandboxId \n         * @param {GitDeleteBranchRequest} gitDeleteBranchRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitDeleteBranchDeprecated: async (sandboxId: string, gitDeleteBranchRequest: GitDeleteBranchRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitDeleteBranchDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'gitDeleteBranchRequest' is not null or undefined\n            assertParamExists('gitDeleteBranchDeprecated', 'gitDeleteBranchRequest', gitDeleteBranchRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/branches`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(gitDeleteBranchRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get commit history from git repository\n         * @summary [DEPRECATED] Get commit history\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitGetHistoryDeprecated: async (sandboxId: string, path: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitGetHistoryDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('gitGetHistoryDeprecated', 'path', path)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/history`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get status from git repository\n         * @summary [DEPRECATED] Get git status\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitGetStatusDeprecated: async (sandboxId: string, path: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitGetStatusDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('gitGetStatusDeprecated', 'path', path)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/status`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Get branch list from git repository\n         * @summary [DEPRECATED] Get branch list\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitListBranchesDeprecated: async (sandboxId: string, path: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitListBranchesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('gitListBranchesDeprecated', 'path', path)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/branches`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Pull changes from remote\n         * @summary [DEPRECATED] Pull changes\n         * @param {string} sandboxId \n         * @param {GitRepoRequest} gitRepoRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitPullChangesDeprecated: async (sandboxId: string, gitRepoRequest: GitRepoRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitPullChangesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'gitRepoRequest' is not null or undefined\n            assertParamExists('gitPullChangesDeprecated', 'gitRepoRequest', gitRepoRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/pull`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(gitRepoRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Push changes to remote\n         * @summary [DEPRECATED] Push changes\n         * @param {string} sandboxId \n         * @param {GitRepoRequest} gitRepoRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitPushChangesDeprecated: async (sandboxId: string, gitRepoRequest: GitRepoRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('gitPushChangesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'gitRepoRequest' is not null or undefined\n            assertParamExists('gitPushChangesDeprecated', 'gitRepoRequest', gitRepoRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/git/push`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(gitRepoRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] List files\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [path] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        listFilesDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, path?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('listFilesDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * List all active PTY sessions in the sandbox\n         * @summary [DEPRECATED] List PTY sessions\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        listPTYSessionsDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('listPTYSessionsDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/pty`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * List all active sessions in the sandbox\n         * @summary [DEPRECATED] List sessions\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        listSessionsDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('listSessionsDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/session`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * The Completion request is sent from the client to the server to compute completion items at a given cursor position.\n         * @summary [DEPRECATED] Get Lsp Completions\n         * @param {string} sandboxId \n         * @param {LspCompletionParams} lspCompletionParams \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspCompletionsDeprecated: async (sandboxId: string, lspCompletionParams: LspCompletionParams, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('lspCompletionsDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'lspCompletionParams' is not null or undefined\n            assertParamExists('lspCompletionsDeprecated', 'lspCompletionParams', lspCompletionParams)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/lsp/completions`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(lspCompletionParams, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * The document close notification is sent from the client to the server when the document got closed in the client.\n         * @summary [DEPRECATED] Call Lsp DidClose\n         * @param {string} sandboxId \n         * @param {LspDocumentRequest} lspDocumentRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspDidCloseDeprecated: async (sandboxId: string, lspDocumentRequest: LspDocumentRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('lspDidCloseDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'lspDocumentRequest' is not null or undefined\n            assertParamExists('lspDidCloseDeprecated', 'lspDocumentRequest', lspDocumentRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/lsp/did-close`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(lspDocumentRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * The document open notification is sent from the client to the server to signal newly opened text documents.\n         * @summary [DEPRECATED] Call Lsp DidOpen\n         * @param {string} sandboxId \n         * @param {LspDocumentRequest} lspDocumentRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspDidOpenDeprecated: async (sandboxId: string, lspDocumentRequest: LspDocumentRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('lspDidOpenDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'lspDocumentRequest' is not null or undefined\n            assertParamExists('lspDidOpenDeprecated', 'lspDocumentRequest', lspDocumentRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/lsp/did-open`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(lspDocumentRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * The document symbol request is sent from the client to the server.\n         * @summary [DEPRECATED] Call Lsp DocumentSymbols\n         * @param {string} sandboxId \n         * @param {string} languageId \n         * @param {string} pathToProject \n         * @param {string} uri \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspDocumentSymbolsDeprecated: async (sandboxId: string, languageId: string, pathToProject: string, uri: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('lspDocumentSymbolsDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'languageId' is not null or undefined\n            assertParamExists('lspDocumentSymbolsDeprecated', 'languageId', languageId)\n            // verify required parameter 'pathToProject' is not null or undefined\n            assertParamExists('lspDocumentSymbolsDeprecated', 'pathToProject', pathToProject)\n            // verify required parameter 'uri' is not null or undefined\n            assertParamExists('lspDocumentSymbolsDeprecated', 'uri', uri)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/lsp/document-symbols`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (languageId !== undefined) {\n                localVarQueryParameter['languageId'] = languageId;\n            }\n\n            if (pathToProject !== undefined) {\n                localVarQueryParameter['pathToProject'] = pathToProject;\n            }\n\n            if (uri !== undefined) {\n                localVarQueryParameter['uri'] = uri;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Start Lsp server process inside sandbox project\n         * @summary [DEPRECATED] Start Lsp server\n         * @param {string} sandboxId \n         * @param {LspServerRequest} lspServerRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspStartDeprecated: async (sandboxId: string, lspServerRequest: LspServerRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('lspStartDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'lspServerRequest' is not null or undefined\n            assertParamExists('lspStartDeprecated', 'lspServerRequest', lspServerRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/lsp/start`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(lspServerRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Stop Lsp server process inside sandbox project\n         * @summary [DEPRECATED] Stop Lsp server\n         * @param {string} sandboxId \n         * @param {LspServerRequest} lspServerRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspStopDeprecated: async (sandboxId: string, lspServerRequest: LspServerRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('lspStopDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'lspServerRequest' is not null or undefined\n            assertParamExists('lspStopDeprecated', 'lspServerRequest', lspServerRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/lsp/stop`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(lspServerRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n         * @summary [DEPRECATED] Call Lsp WorkspaceSymbols\n         * @param {string} sandboxId \n         * @param {string} languageId \n         * @param {string} pathToProject \n         * @param {string} query \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspWorkspaceSymbolsDeprecated: async (sandboxId: string, languageId: string, pathToProject: string, query: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('lspWorkspaceSymbolsDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'languageId' is not null or undefined\n            assertParamExists('lspWorkspaceSymbolsDeprecated', 'languageId', languageId)\n            // verify required parameter 'pathToProject' is not null or undefined\n            assertParamExists('lspWorkspaceSymbolsDeprecated', 'pathToProject', pathToProject)\n            // verify required parameter 'query' is not null or undefined\n            assertParamExists('lspWorkspaceSymbolsDeprecated', 'query', query)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/lsp/workspace-symbols`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (languageId !== undefined) {\n                localVarQueryParameter['languageId'] = languageId;\n            }\n\n            if (pathToProject !== undefined) {\n                localVarQueryParameter['pathToProject'] = pathToProject;\n            }\n\n            if (query !== undefined) {\n                localVarQueryParameter['query'] = query;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Move file inside sandbox\n         * @summary [DEPRECATED] Move file\n         * @param {string} sandboxId \n         * @param {string} source \n         * @param {string} destination \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        moveFileDeprecated: async (sandboxId: string, source: string, destination: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('moveFileDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'source' is not null or undefined\n            assertParamExists('moveFileDeprecated', 'source', source)\n            // verify required parameter 'destination' is not null or undefined\n            assertParamExists('moveFileDeprecated', 'destination', destination)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/move`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (source !== undefined) {\n                localVarQueryParameter['source'] = source;\n            }\n\n            if (destination !== undefined) {\n                localVarQueryParameter['destination'] = destination;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Move mouse cursor to specified coordinates\n         * @summary [DEPRECATED] Move mouse\n         * @param {string} sandboxId \n         * @param {MouseMoveRequest} mouseMoveRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        moveMouseDeprecated: async (sandboxId: string, mouseMoveRequest: MouseMoveRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('moveMouseDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'mouseMoveRequest' is not null or undefined\n            assertParamExists('moveMouseDeprecated', 'mouseMoveRequest', mouseMoveRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/mouse/move`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(mouseMoveRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Press a hotkey combination\n         * @summary [DEPRECATED] Press hotkey\n         * @param {string} sandboxId \n         * @param {KeyboardHotkeyRequest} keyboardHotkeyRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        pressHotkeyDeprecated: async (sandboxId: string, keyboardHotkeyRequest: KeyboardHotkeyRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('pressHotkeyDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'keyboardHotkeyRequest' is not null or undefined\n            assertParamExists('pressHotkeyDeprecated', 'keyboardHotkeyRequest', keyboardHotkeyRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/keyboard/hotkey`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(keyboardHotkeyRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Press a key with optional modifiers\n         * @summary [DEPRECATED] Press key\n         * @param {string} sandboxId \n         * @param {KeyboardPressRequest} keyboardPressRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        pressKeyDeprecated: async (sandboxId: string, keyboardPressRequest: KeyboardPressRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('pressKeyDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'keyboardPressRequest' is not null or undefined\n            assertParamExists('pressKeyDeprecated', 'keyboardPressRequest', keyboardPressRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/keyboard/key`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(keyboardPressRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Replace text/pattern in multiple files inside sandbox\n         * @summary [DEPRECATED] Replace in files\n         * @param {string} sandboxId \n         * @param {ReplaceRequest} replaceRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        replaceInFilesDeprecated: async (sandboxId: string, replaceRequest: ReplaceRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('replaceInFilesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'replaceRequest' is not null or undefined\n            assertParamExists('replaceInFilesDeprecated', 'replaceRequest', replaceRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/replace`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(replaceRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Resize a PTY session\n         * @summary [DEPRECATED] Resize PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {PtyResizeRequest} ptyResizeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        resizePTYSessionDeprecated: async (sandboxId: string, sessionId: string, ptyResizeRequest: PtyResizeRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('resizePTYSessionDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'sessionId' is not null or undefined\n            assertParamExists('resizePTYSessionDeprecated', 'sessionId', sessionId)\n            // verify required parameter 'ptyResizeRequest' is not null or undefined\n            assertParamExists('resizePTYSessionDeprecated', 'ptyResizeRequest', ptyResizeRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}/resize`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)))\n                .replace(`{${\"sessionId\"}}`, encodeURIComponent(String(sessionId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(ptyResizeRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Restart a specific VNC process\n         * @summary [DEPRECATED] Restart process\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        restartProcessDeprecated: async (processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'processName' is not null or undefined\n            assertParamExists('restartProcessDeprecated', 'processName', processName)\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('restartProcessDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/restart`\n                .replace(`{${\"processName\"}}`, encodeURIComponent(String(processName)))\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Scroll mouse at specified coordinates\n         * @summary [DEPRECATED] Scroll mouse\n         * @param {string} sandboxId \n         * @param {MouseScrollRequest} mouseScrollRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        scrollMouseDeprecated: async (sandboxId: string, mouseScrollRequest: MouseScrollRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('scrollMouseDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'mouseScrollRequest' is not null or undefined\n            assertParamExists('scrollMouseDeprecated', 'mouseScrollRequest', mouseScrollRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/mouse/scroll`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(mouseScrollRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Search for files inside sandbox\n         * @summary [DEPRECATED] Search files\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} pattern \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        searchFilesDeprecated: async (sandboxId: string, path: string, pattern: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('searchFilesDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('searchFilesDeprecated', 'path', path)\n            // verify required parameter 'pattern' is not null or undefined\n            assertParamExists('searchFilesDeprecated', 'pattern', pattern)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/search`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n            if (pattern !== undefined) {\n                localVarQueryParameter['pattern'] = pattern;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Set file owner/group/permissions inside sandbox\n         * @summary [DEPRECATED] Set file permissions\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [owner] \n         * @param {string} [group] \n         * @param {string} [mode] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        setFilePermissionsDeprecated: async (sandboxId: string, path: string, xDaytonaOrganizationID?: string, owner?: string, group?: string, mode?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('setFilePermissionsDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('setFilePermissionsDeprecated', 'path', path)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/permissions`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n            if (owner !== undefined) {\n                localVarQueryParameter['owner'] = owner;\n            }\n\n            if (group !== undefined) {\n                localVarQueryParameter['group'] = group;\n            }\n\n            if (mode !== undefined) {\n                localVarQueryParameter['mode'] = mode;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n         * @summary [DEPRECATED] Start computer use processes\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        startComputerUseDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('startComputerUseDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/start`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n         * @summary [DEPRECATED] Stop computer use processes\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        stopComputerUseDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('stopComputerUseDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/stop`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Take a compressed screenshot of a specific region\n         * @summary [DEPRECATED] Take compressed region screenshot\n         * @param {string} sandboxId \n         * @param {number} height \n         * @param {number} width \n         * @param {number} y \n         * @param {number} x \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [scale] \n         * @param {number} [quality] \n         * @param {string} [format] \n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        takeCompressedRegionScreenshotDeprecated: async (sandboxId: string, height: number, width: number, y: number, x: number, xDaytonaOrganizationID?: string, scale?: number, quality?: number, format?: string, showCursor?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('takeCompressedRegionScreenshotDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'height' is not null or undefined\n            assertParamExists('takeCompressedRegionScreenshotDeprecated', 'height', height)\n            // verify required parameter 'width' is not null or undefined\n            assertParamExists('takeCompressedRegionScreenshotDeprecated', 'width', width)\n            // verify required parameter 'y' is not null or undefined\n            assertParamExists('takeCompressedRegionScreenshotDeprecated', 'y', y)\n            // verify required parameter 'x' is not null or undefined\n            assertParamExists('takeCompressedRegionScreenshotDeprecated', 'x', x)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/screenshot/region/compressed`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (scale !== undefined) {\n                localVarQueryParameter['scale'] = scale;\n            }\n\n            if (quality !== undefined) {\n                localVarQueryParameter['quality'] = quality;\n            }\n\n            if (format !== undefined) {\n                localVarQueryParameter['format'] = format;\n            }\n\n            if (showCursor !== undefined) {\n                localVarQueryParameter['show_cursor'] = showCursor;\n            }\n\n            if (height !== undefined) {\n                localVarQueryParameter['height'] = height;\n            }\n\n            if (width !== undefined) {\n                localVarQueryParameter['width'] = width;\n            }\n\n            if (y !== undefined) {\n                localVarQueryParameter['y'] = y;\n            }\n\n            if (x !== undefined) {\n                localVarQueryParameter['x'] = x;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Take a compressed screenshot with format, quality, and scale options\n         * @summary [DEPRECATED] Take compressed screenshot\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [scale] \n         * @param {number} [quality] \n         * @param {string} [format] \n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        takeCompressedScreenshotDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, scale?: number, quality?: number, format?: string, showCursor?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('takeCompressedScreenshotDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/screenshot/compressed`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (scale !== undefined) {\n                localVarQueryParameter['scale'] = scale;\n            }\n\n            if (quality !== undefined) {\n                localVarQueryParameter['quality'] = quality;\n            }\n\n            if (format !== undefined) {\n                localVarQueryParameter['format'] = format;\n            }\n\n            if (showCursor !== undefined) {\n                localVarQueryParameter['show_cursor'] = showCursor;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Take a screenshot of a specific region\n         * @summary [DEPRECATED] Take region screenshot\n         * @param {string} sandboxId \n         * @param {number} height \n         * @param {number} width \n         * @param {number} y \n         * @param {number} x \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        takeRegionScreenshotDeprecated: async (sandboxId: string, height: number, width: number, y: number, x: number, xDaytonaOrganizationID?: string, showCursor?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('takeRegionScreenshotDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'height' is not null or undefined\n            assertParamExists('takeRegionScreenshotDeprecated', 'height', height)\n            // verify required parameter 'width' is not null or undefined\n            assertParamExists('takeRegionScreenshotDeprecated', 'width', width)\n            // verify required parameter 'y' is not null or undefined\n            assertParamExists('takeRegionScreenshotDeprecated', 'y', y)\n            // verify required parameter 'x' is not null or undefined\n            assertParamExists('takeRegionScreenshotDeprecated', 'x', x)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/screenshot/region`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (showCursor !== undefined) {\n                localVarQueryParameter['show_cursor'] = showCursor;\n            }\n\n            if (height !== undefined) {\n                localVarQueryParameter['height'] = height;\n            }\n\n            if (width !== undefined) {\n                localVarQueryParameter['width'] = width;\n            }\n\n            if (y !== undefined) {\n                localVarQueryParameter['y'] = y;\n            }\n\n            if (x !== undefined) {\n                localVarQueryParameter['x'] = x;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Take a screenshot of the entire screen\n         * @summary [DEPRECATED] Take screenshot\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        takeScreenshotDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, showCursor?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('takeScreenshotDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/screenshot`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (showCursor !== undefined) {\n                localVarQueryParameter['show_cursor'] = showCursor;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Type text using keyboard\n         * @summary [DEPRECATED] Type text\n         * @param {string} sandboxId \n         * @param {KeyboardTypeRequest} keyboardTypeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        typeTextDeprecated: async (sandboxId: string, keyboardTypeRequest: KeyboardTypeRequest, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('typeTextDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'keyboardTypeRequest' is not null or undefined\n            assertParamExists('typeTextDeprecated', 'keyboardTypeRequest', keyboardTypeRequest)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/computeruse/keyboard/type`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(keyboardTypeRequest, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Upload file inside sandbox\n         * @summary [DEPRECATED] Upload file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {File} [file] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        uploadFileDeprecated: async (sandboxId: string, path: string, xDaytonaOrganizationID?: string, file?: File, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('uploadFileDeprecated', 'sandboxId', sandboxId)\n            // verify required parameter 'path' is not null or undefined\n            assertParamExists('uploadFileDeprecated', 'path', path)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/upload`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n            const localVarFormParams = new ((configuration && configuration.formDataCtor) || FormData)();\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (path !== undefined) {\n                localVarQueryParameter['path'] = path;\n            }\n\n\n            if (file !== undefined) { \n                localVarFormParams.append('file', file as any);\n            }\n    \n    \n            localVarHeaderParameter['Content-Type'] = 'multipart/form-data';\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = localVarFormParams;\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * Upload multiple files inside sandbox\n         * @summary [DEPRECATED] Upload multiple files\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        uploadFilesDeprecated: async (sandboxId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'sandboxId' is not null or undefined\n            assertParamExists('uploadFilesDeprecated', 'sandboxId', sandboxId)\n            const localVarPath = `/toolbox/{sandboxId}/toolbox/files/bulk-upload`\n                .replace(`{${\"sandboxId\"}}`, encodeURIComponent(String(sandboxId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * ToolboxApi - functional programming interface\n * @export\n */\nexport const ToolboxApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = ToolboxApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * Click mouse at specified coordinates\n         * @summary [DEPRECATED] Click mouse\n         * @param {string} sandboxId \n         * @param {MouseClickRequest} mouseClickRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async clickMouseDeprecated(sandboxId: string, mouseClickRequest: MouseClickRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MouseClickResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.clickMouseDeprecated(sandboxId, mouseClickRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.clickMouseDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Create folder inside sandbox\n         * @summary [DEPRECATED] Create folder\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} mode \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async createFolderDeprecated(sandboxId: string, path: string, mode: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createFolderDeprecated(sandboxId, path, mode, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.createFolderDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Create a new PTY session in the sandbox\n         * @summary [DEPRECATED] Create PTY session\n         * @param {string} sandboxId \n         * @param {PtyCreateRequest} ptyCreateRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async createPTYSessionDeprecated(sandboxId: string, ptyCreateRequest: PtyCreateRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PtyCreateResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createPTYSessionDeprecated(sandboxId, ptyCreateRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.createPTYSessionDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Create a new session in the sandbox\n         * @summary [DEPRECATED] Create session\n         * @param {string} sandboxId \n         * @param {CreateSessionRequest} createSessionRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async createSessionDeprecated(sandboxId: string, createSessionRequest: CreateSessionRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createSessionDeprecated(sandboxId, createSessionRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.createSessionDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Delete file inside sandbox\n         * @summary [DEPRECATED] Delete file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [recursive] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async deleteFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, recursive?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteFileDeprecated(sandboxId, path, xDaytonaOrganizationID, recursive, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.deleteFileDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Delete a PTY session and terminate the associated process\n         * @summary [DEPRECATED] Delete PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async deletePTYSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deletePTYSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.deletePTYSessionDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Delete a specific session\n         * @summary [DEPRECATED] Delete session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async deleteSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.deleteSessionDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Download file from sandbox\n         * @summary [DEPRECATED] Download file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async downloadFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.downloadFileDeprecated(sandboxId, path, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.downloadFileDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Streams back a multipart/form-data bundle of the requested paths\n         * @summary [DEPRECATED] Download multiple files\n         * @param {string} sandboxId \n         * @param {DownloadFiles} downloadFiles \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async downloadFilesDeprecated(sandboxId: string, downloadFiles: DownloadFiles, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<File>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.downloadFilesDeprecated(sandboxId, downloadFiles, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.downloadFilesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Drag mouse from start to end coordinates\n         * @summary [DEPRECATED] Drag mouse\n         * @param {string} sandboxId \n         * @param {MouseDragRequest} mouseDragRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async dragMouseDeprecated(sandboxId: string, mouseDragRequest: MouseDragRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MouseDragResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.dragMouseDeprecated(sandboxId, mouseDragRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.dragMouseDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Execute command synchronously inside sandbox\n         * @summary [DEPRECATED] Execute command\n         * @param {string} sandboxId \n         * @param {ExecuteRequest} executeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async executeCommandDeprecated(sandboxId: string, executeRequest: ExecuteRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ExecuteResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.executeCommandDeprecated(sandboxId, executeRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.executeCommandDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Execute a command in a specific session\n         * @summary [DEPRECATED] Execute command in session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {SessionExecuteRequest} sessionExecuteRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async executeSessionCommandDeprecated(sandboxId: string, sessionId: string, sessionExecuteRequest: SessionExecuteRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SessionExecuteResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.executeSessionCommandDeprecated(sandboxId, sessionId, sessionExecuteRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.executeSessionCommandDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Search for text/pattern inside sandbox files\n         * @summary [DEPRECATED] Search for text/pattern in files\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} pattern \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async findInFilesDeprecated(sandboxId: string, path: string, pattern: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Match>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.findInFilesDeprecated(sandboxId, path, pattern, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.findInFilesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get status of all VNC desktop processes\n         * @summary [DEPRECATED] Get computer use status\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getComputerUseStatusDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ComputerUseStatusResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getComputerUseStatusDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getComputerUseStatusDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get information about displays\n         * @summary [DEPRECATED] Get display info\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getDisplayInfoDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<DisplayInfoResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getDisplayInfoDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getDisplayInfoDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get file info inside sandbox\n         * @summary [DEPRECATED] Get file info\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getFileInfoDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<FileInfo>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getFileInfoDeprecated(sandboxId, path, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getFileInfoDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get current mouse cursor position\n         * @summary [DEPRECATED] Get mouse position\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getMousePositionDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MousePosition>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getMousePositionDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getMousePositionDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get PTY session information by ID\n         * @summary [DEPRECATED] Get PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getPTYSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PtySessionInfo>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getPTYSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getPTYSessionDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get error logs for a specific VNC process\n         * @summary [DEPRECATED] Get process errors\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getProcessErrorsDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ProcessErrorsResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getProcessErrorsDeprecated(processName, sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getProcessErrorsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get logs for a specific VNC process\n         * @summary [DEPRECATED] Get process logs\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getProcessLogsDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ProcessLogsResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getProcessLogsDeprecated(processName, sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getProcessLogsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get status of a specific VNC process\n         * @summary [DEPRECATED] Get process status\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getProcessStatusDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ProcessStatusResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getProcessStatusDeprecated(processName, sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getProcessStatusDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox project dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getProjectDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ProjectDirResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getProjectDirDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getProjectDirDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get session command by ID\n         * @summary [DEPRECATED] Get session command\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} commandId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getSessionCommandDeprecated(sandboxId: string, sessionId: string, commandId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Command>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSessionCommandDeprecated(sandboxId, sessionId, commandId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getSessionCommandDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get logs for a specific command in a session\n         * @summary [DEPRECATED] Get command logs\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} commandId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to stream the logs\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getSessionCommandLogsDeprecated(sandboxId: string, sessionId: string, commandId: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<string>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSessionCommandLogsDeprecated(sandboxId, sessionId, commandId, xDaytonaOrganizationID, follow, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getSessionCommandLogsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get session by ID\n         * @summary [DEPRECATED] Get session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Session>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getSessionDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox user home dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getUserHomeDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<UserHomeDirResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getUserHomeDirDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getUserHomeDirDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get list of open windows\n         * @summary [DEPRECATED] Get windows\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getWindowsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<WindowsResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getWindowsDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getWindowsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox work-dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getWorkDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<WorkDirResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getWorkDirDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.getWorkDirDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Add files to git commit\n         * @summary [DEPRECATED] Add files\n         * @param {string} sandboxId \n         * @param {GitAddRequest} gitAddRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitAddFilesDeprecated(sandboxId: string, gitAddRequest: GitAddRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitAddFilesDeprecated(sandboxId, gitAddRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitAddFilesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Checkout branch or commit in git repository\n         * @summary [DEPRECATED] Checkout branch\n         * @param {string} sandboxId \n         * @param {GitCheckoutRequest} gitCheckoutRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitCheckoutBranchDeprecated(sandboxId: string, gitCheckoutRequest: GitCheckoutRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitCheckoutBranchDeprecated(sandboxId, gitCheckoutRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitCheckoutBranchDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Clone git repository\n         * @summary [DEPRECATED] Clone repository\n         * @param {string} sandboxId \n         * @param {GitCloneRequest} gitCloneRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitCloneRepositoryDeprecated(sandboxId: string, gitCloneRequest: GitCloneRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitCloneRepositoryDeprecated(sandboxId, gitCloneRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitCloneRepositoryDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Commit changes to git repository\n         * @summary [DEPRECATED] Commit changes\n         * @param {string} sandboxId \n         * @param {GitCommitRequest} gitCommitRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitCommitChangesDeprecated(sandboxId: string, gitCommitRequest: GitCommitRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<GitCommitResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitCommitChangesDeprecated(sandboxId, gitCommitRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitCommitChangesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Create branch on git repository\n         * @summary [DEPRECATED] Create branch\n         * @param {string} sandboxId \n         * @param {GitBranchRequest} gitBranchRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitCreateBranchDeprecated(sandboxId: string, gitBranchRequest: GitBranchRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitCreateBranchDeprecated(sandboxId, gitBranchRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitCreateBranchDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Delete branch on git repository\n         * @summary [DEPRECATED] Delete branch\n         * @param {string} sandboxId \n         * @param {GitDeleteBranchRequest} gitDeleteBranchRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitDeleteBranchDeprecated(sandboxId: string, gitDeleteBranchRequest: GitDeleteBranchRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitDeleteBranchDeprecated(sandboxId, gitDeleteBranchRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitDeleteBranchDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get commit history from git repository\n         * @summary [DEPRECATED] Get commit history\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitGetHistoryDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<GitCommitInfo>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitGetHistoryDeprecated(sandboxId, path, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitGetHistoryDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get status from git repository\n         * @summary [DEPRECATED] Get git status\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitGetStatusDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<GitStatus>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitGetStatusDeprecated(sandboxId, path, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitGetStatusDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Get branch list from git repository\n         * @summary [DEPRECATED] Get branch list\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitListBranchesDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ListBranchResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitListBranchesDeprecated(sandboxId, path, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitListBranchesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Pull changes from remote\n         * @summary [DEPRECATED] Pull changes\n         * @param {string} sandboxId \n         * @param {GitRepoRequest} gitRepoRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitPullChangesDeprecated(sandboxId: string, gitRepoRequest: GitRepoRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitPullChangesDeprecated(sandboxId, gitRepoRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitPullChangesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Push changes to remote\n         * @summary [DEPRECATED] Push changes\n         * @param {string} sandboxId \n         * @param {GitRepoRequest} gitRepoRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async gitPushChangesDeprecated(sandboxId: string, gitRepoRequest: GitRepoRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.gitPushChangesDeprecated(sandboxId, gitRepoRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.gitPushChangesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] List files\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [path] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async listFilesDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, path?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<FileInfo>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listFilesDeprecated(sandboxId, xDaytonaOrganizationID, path, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.listFilesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * List all active PTY sessions in the sandbox\n         * @summary [DEPRECATED] List PTY sessions\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async listPTYSessionsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PtyListResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listPTYSessionsDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.listPTYSessionsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * List all active sessions in the sandbox\n         * @summary [DEPRECATED] List sessions\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async listSessionsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Session>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listSessionsDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.listSessionsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * The Completion request is sent from the client to the server to compute completion items at a given cursor position.\n         * @summary [DEPRECATED] Get Lsp Completions\n         * @param {string} sandboxId \n         * @param {LspCompletionParams} lspCompletionParams \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async lspCompletionsDeprecated(sandboxId: string, lspCompletionParams: LspCompletionParams, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<CompletionList>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.lspCompletionsDeprecated(sandboxId, lspCompletionParams, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.lspCompletionsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * The document close notification is sent from the client to the server when the document got closed in the client.\n         * @summary [DEPRECATED] Call Lsp DidClose\n         * @param {string} sandboxId \n         * @param {LspDocumentRequest} lspDocumentRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async lspDidCloseDeprecated(sandboxId: string, lspDocumentRequest: LspDocumentRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.lspDidCloseDeprecated(sandboxId, lspDocumentRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.lspDidCloseDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * The document open notification is sent from the client to the server to signal newly opened text documents.\n         * @summary [DEPRECATED] Call Lsp DidOpen\n         * @param {string} sandboxId \n         * @param {LspDocumentRequest} lspDocumentRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async lspDidOpenDeprecated(sandboxId: string, lspDocumentRequest: LspDocumentRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.lspDidOpenDeprecated(sandboxId, lspDocumentRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.lspDidOpenDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * The document symbol request is sent from the client to the server.\n         * @summary [DEPRECATED] Call Lsp DocumentSymbols\n         * @param {string} sandboxId \n         * @param {string} languageId \n         * @param {string} pathToProject \n         * @param {string} uri \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async lspDocumentSymbolsDeprecated(sandboxId: string, languageId: string, pathToProject: string, uri: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<LspSymbol>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.lspDocumentSymbolsDeprecated(sandboxId, languageId, pathToProject, uri, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.lspDocumentSymbolsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Start Lsp server process inside sandbox project\n         * @summary [DEPRECATED] Start Lsp server\n         * @param {string} sandboxId \n         * @param {LspServerRequest} lspServerRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async lspStartDeprecated(sandboxId: string, lspServerRequest: LspServerRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.lspStartDeprecated(sandboxId, lspServerRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.lspStartDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Stop Lsp server process inside sandbox project\n         * @summary [DEPRECATED] Stop Lsp server\n         * @param {string} sandboxId \n         * @param {LspServerRequest} lspServerRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async lspStopDeprecated(sandboxId: string, lspServerRequest: LspServerRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.lspStopDeprecated(sandboxId, lspServerRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.lspStopDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n         * @summary [DEPRECATED] Call Lsp WorkspaceSymbols\n         * @param {string} sandboxId \n         * @param {string} languageId \n         * @param {string} pathToProject \n         * @param {string} query \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async lspWorkspaceSymbolsDeprecated(sandboxId: string, languageId: string, pathToProject: string, query: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<LspSymbol>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.lspWorkspaceSymbolsDeprecated(sandboxId, languageId, pathToProject, query, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.lspWorkspaceSymbolsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Move file inside sandbox\n         * @summary [DEPRECATED] Move file\n         * @param {string} sandboxId \n         * @param {string} source \n         * @param {string} destination \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async moveFileDeprecated(sandboxId: string, source: string, destination: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.moveFileDeprecated(sandboxId, source, destination, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.moveFileDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Move mouse cursor to specified coordinates\n         * @summary [DEPRECATED] Move mouse\n         * @param {string} sandboxId \n         * @param {MouseMoveRequest} mouseMoveRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async moveMouseDeprecated(sandboxId: string, mouseMoveRequest: MouseMoveRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MouseMoveResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.moveMouseDeprecated(sandboxId, mouseMoveRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.moveMouseDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Press a hotkey combination\n         * @summary [DEPRECATED] Press hotkey\n         * @param {string} sandboxId \n         * @param {KeyboardHotkeyRequest} keyboardHotkeyRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async pressHotkeyDeprecated(sandboxId: string, keyboardHotkeyRequest: KeyboardHotkeyRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.pressHotkeyDeprecated(sandboxId, keyboardHotkeyRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.pressHotkeyDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Press a key with optional modifiers\n         * @summary [DEPRECATED] Press key\n         * @param {string} sandboxId \n         * @param {KeyboardPressRequest} keyboardPressRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async pressKeyDeprecated(sandboxId: string, keyboardPressRequest: KeyboardPressRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.pressKeyDeprecated(sandboxId, keyboardPressRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.pressKeyDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Replace text/pattern in multiple files inside sandbox\n         * @summary [DEPRECATED] Replace in files\n         * @param {string} sandboxId \n         * @param {ReplaceRequest} replaceRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async replaceInFilesDeprecated(sandboxId: string, replaceRequest: ReplaceRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<ReplaceResult>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.replaceInFilesDeprecated(sandboxId, replaceRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.replaceInFilesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Resize a PTY session\n         * @summary [DEPRECATED] Resize PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {PtyResizeRequest} ptyResizeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async resizePTYSessionDeprecated(sandboxId: string, sessionId: string, ptyResizeRequest: PtyResizeRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PtySessionInfo>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.resizePTYSessionDeprecated(sandboxId, sessionId, ptyResizeRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.resizePTYSessionDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Restart a specific VNC process\n         * @summary [DEPRECATED] Restart process\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async restartProcessDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ProcessRestartResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.restartProcessDeprecated(processName, sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.restartProcessDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Scroll mouse at specified coordinates\n         * @summary [DEPRECATED] Scroll mouse\n         * @param {string} sandboxId \n         * @param {MouseScrollRequest} mouseScrollRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async scrollMouseDeprecated(sandboxId: string, mouseScrollRequest: MouseScrollRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<MouseScrollResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.scrollMouseDeprecated(sandboxId, mouseScrollRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.scrollMouseDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Search for files inside sandbox\n         * @summary [DEPRECATED] Search files\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} pattern \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async searchFilesDeprecated(sandboxId: string, path: string, pattern: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SearchFilesResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.searchFilesDeprecated(sandboxId, path, pattern, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.searchFilesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Set file owner/group/permissions inside sandbox\n         * @summary [DEPRECATED] Set file permissions\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [owner] \n         * @param {string} [group] \n         * @param {string} [mode] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async setFilePermissionsDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, owner?: string, group?: string, mode?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setFilePermissionsDeprecated(sandboxId, path, xDaytonaOrganizationID, owner, group, mode, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.setFilePermissionsDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n         * @summary [DEPRECATED] Start computer use processes\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async startComputerUseDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ComputerUseStartResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.startComputerUseDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.startComputerUseDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n         * @summary [DEPRECATED] Stop computer use processes\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async stopComputerUseDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ComputerUseStopResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.stopComputerUseDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.stopComputerUseDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Take a compressed screenshot of a specific region\n         * @summary [DEPRECATED] Take compressed region screenshot\n         * @param {string} sandboxId \n         * @param {number} height \n         * @param {number} width \n         * @param {number} y \n         * @param {number} x \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [scale] \n         * @param {number} [quality] \n         * @param {string} [format] \n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async takeCompressedRegionScreenshotDeprecated(sandboxId: string, height: number, width: number, y: number, x: number, xDaytonaOrganizationID?: string, scale?: number, quality?: number, format?: string, showCursor?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<CompressedScreenshotResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.takeCompressedRegionScreenshotDeprecated(sandboxId, height, width, y, x, xDaytonaOrganizationID, scale, quality, format, showCursor, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.takeCompressedRegionScreenshotDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Take a compressed screenshot with format, quality, and scale options\n         * @summary [DEPRECATED] Take compressed screenshot\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [scale] \n         * @param {number} [quality] \n         * @param {string} [format] \n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async takeCompressedScreenshotDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, scale?: number, quality?: number, format?: string, showCursor?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<CompressedScreenshotResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.takeCompressedScreenshotDeprecated(sandboxId, xDaytonaOrganizationID, scale, quality, format, showCursor, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.takeCompressedScreenshotDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Take a screenshot of a specific region\n         * @summary [DEPRECATED] Take region screenshot\n         * @param {string} sandboxId \n         * @param {number} height \n         * @param {number} width \n         * @param {number} y \n         * @param {number} x \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async takeRegionScreenshotDeprecated(sandboxId: string, height: number, width: number, y: number, x: number, xDaytonaOrganizationID?: string, showCursor?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<RegionScreenshotResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.takeRegionScreenshotDeprecated(sandboxId, height, width, y, x, xDaytonaOrganizationID, showCursor, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.takeRegionScreenshotDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Take a screenshot of the entire screen\n         * @summary [DEPRECATED] Take screenshot\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async takeScreenshotDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, showCursor?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ScreenshotResponse>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.takeScreenshotDeprecated(sandboxId, xDaytonaOrganizationID, showCursor, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.takeScreenshotDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Type text using keyboard\n         * @summary [DEPRECATED] Type text\n         * @param {string} sandboxId \n         * @param {KeyboardTypeRequest} keyboardTypeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async typeTextDeprecated(sandboxId: string, keyboardTypeRequest: KeyboardTypeRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.typeTextDeprecated(sandboxId, keyboardTypeRequest, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.typeTextDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Upload file inside sandbox\n         * @summary [DEPRECATED] Upload file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {File} [file] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async uploadFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, file?: File, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFileDeprecated(sandboxId, path, xDaytonaOrganizationID, file, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.uploadFileDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * Upload multiple files inside sandbox\n         * @summary [DEPRECATED] Upload multiple files\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async uploadFilesDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.uploadFilesDeprecated(sandboxId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['ToolboxApi.uploadFilesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * ToolboxApi - factory interface\n * @export\n */\nexport const ToolboxApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = ToolboxApiFp(configuration)\n    return {\n        /**\n         * Click mouse at specified coordinates\n         * @summary [DEPRECATED] Click mouse\n         * @param {string} sandboxId \n         * @param {MouseClickRequest} mouseClickRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        clickMouseDeprecated(sandboxId: string, mouseClickRequest: MouseClickRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<MouseClickResponse> {\n            return localVarFp.clickMouseDeprecated(sandboxId, mouseClickRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Create folder inside sandbox\n         * @summary [DEPRECATED] Create folder\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} mode \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createFolderDeprecated(sandboxId: string, path: string, mode: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.createFolderDeprecated(sandboxId, path, mode, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Create a new PTY session in the sandbox\n         * @summary [DEPRECATED] Create PTY session\n         * @param {string} sandboxId \n         * @param {PtyCreateRequest} ptyCreateRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createPTYSessionDeprecated(sandboxId: string, ptyCreateRequest: PtyCreateRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<PtyCreateResponse> {\n            return localVarFp.createPTYSessionDeprecated(sandboxId, ptyCreateRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Create a new session in the sandbox\n         * @summary [DEPRECATED] Create session\n         * @param {string} sandboxId \n         * @param {CreateSessionRequest} createSessionRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createSessionDeprecated(sandboxId: string, createSessionRequest: CreateSessionRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.createSessionDeprecated(sandboxId, createSessionRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Delete file inside sandbox\n         * @summary [DEPRECATED] Delete file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [recursive] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        deleteFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, recursive?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteFileDeprecated(sandboxId, path, xDaytonaOrganizationID, recursive, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Delete a PTY session and terminate the associated process\n         * @summary [DEPRECATED] Delete PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        deletePTYSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deletePTYSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Delete a specific session\n         * @summary [DEPRECATED] Delete session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        deleteSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Download file from sandbox\n         * @summary [DEPRECATED] Download file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        downloadFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<File> {\n            return localVarFp.downloadFileDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Streams back a multipart/form-data bundle of the requested paths\n         * @summary [DEPRECATED] Download multiple files\n         * @param {string} sandboxId \n         * @param {DownloadFiles} downloadFiles \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        downloadFilesDeprecated(sandboxId: string, downloadFiles: DownloadFiles, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<File> {\n            return localVarFp.downloadFilesDeprecated(sandboxId, downloadFiles, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Drag mouse from start to end coordinates\n         * @summary [DEPRECATED] Drag mouse\n         * @param {string} sandboxId \n         * @param {MouseDragRequest} mouseDragRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        dragMouseDeprecated(sandboxId: string, mouseDragRequest: MouseDragRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<MouseDragResponse> {\n            return localVarFp.dragMouseDeprecated(sandboxId, mouseDragRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Execute command synchronously inside sandbox\n         * @summary [DEPRECATED] Execute command\n         * @param {string} sandboxId \n         * @param {ExecuteRequest} executeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        executeCommandDeprecated(sandboxId: string, executeRequest: ExecuteRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ExecuteResponse> {\n            return localVarFp.executeCommandDeprecated(sandboxId, executeRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Execute a command in a specific session\n         * @summary [DEPRECATED] Execute command in session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {SessionExecuteRequest} sessionExecuteRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        executeSessionCommandDeprecated(sandboxId: string, sessionId: string, sessionExecuteRequest: SessionExecuteRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SessionExecuteResponse> {\n            return localVarFp.executeSessionCommandDeprecated(sandboxId, sessionId, sessionExecuteRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Search for text/pattern inside sandbox files\n         * @summary [DEPRECATED] Search for text/pattern in files\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} pattern \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        findInFilesDeprecated(sandboxId: string, path: string, pattern: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<Match>> {\n            return localVarFp.findInFilesDeprecated(sandboxId, path, pattern, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get status of all VNC desktop processes\n         * @summary [DEPRECATED] Get computer use status\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getComputerUseStatusDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ComputerUseStatusResponse> {\n            return localVarFp.getComputerUseStatusDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get information about displays\n         * @summary [DEPRECATED] Get display info\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getDisplayInfoDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<DisplayInfoResponse> {\n            return localVarFp.getDisplayInfoDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get file info inside sandbox\n         * @summary [DEPRECATED] Get file info\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getFileInfoDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<FileInfo> {\n            return localVarFp.getFileInfoDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get current mouse cursor position\n         * @summary [DEPRECATED] Get mouse position\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getMousePositionDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<MousePosition> {\n            return localVarFp.getMousePositionDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get PTY session information by ID\n         * @summary [DEPRECATED] Get PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getPTYSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<PtySessionInfo> {\n            return localVarFp.getPTYSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get error logs for a specific VNC process\n         * @summary [DEPRECATED] Get process errors\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getProcessErrorsDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ProcessErrorsResponse> {\n            return localVarFp.getProcessErrorsDeprecated(processName, sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get logs for a specific VNC process\n         * @summary [DEPRECATED] Get process logs\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getProcessLogsDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ProcessLogsResponse> {\n            return localVarFp.getProcessLogsDeprecated(processName, sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get status of a specific VNC process\n         * @summary [DEPRECATED] Get process status\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getProcessStatusDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ProcessStatusResponse> {\n            return localVarFp.getProcessStatusDeprecated(processName, sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox project dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getProjectDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ProjectDirResponse> {\n            return localVarFp.getProjectDirDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get session command by ID\n         * @summary [DEPRECATED] Get session command\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} commandId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getSessionCommandDeprecated(sandboxId: string, sessionId: string, commandId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Command> {\n            return localVarFp.getSessionCommandDeprecated(sandboxId, sessionId, commandId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get logs for a specific command in a session\n         * @summary [DEPRECATED] Get command logs\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} commandId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to stream the logs\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getSessionCommandLogsDeprecated(sandboxId: string, sessionId: string, commandId: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<string> {\n            return localVarFp.getSessionCommandLogsDeprecated(sandboxId, sessionId, commandId, xDaytonaOrganizationID, follow, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get session by ID\n         * @summary [DEPRECATED] Get session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Session> {\n            return localVarFp.getSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox user home dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getUserHomeDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<UserHomeDirResponse> {\n            return localVarFp.getUserHomeDirDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get list of open windows\n         * @summary [DEPRECATED] Get windows\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getWindowsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<WindowsResponse> {\n            return localVarFp.getWindowsDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get sandbox work-dir\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getWorkDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<WorkDirResponse> {\n            return localVarFp.getWorkDirDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Add files to git commit\n         * @summary [DEPRECATED] Add files\n         * @param {string} sandboxId \n         * @param {GitAddRequest} gitAddRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitAddFilesDeprecated(sandboxId: string, gitAddRequest: GitAddRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.gitAddFilesDeprecated(sandboxId, gitAddRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Checkout branch or commit in git repository\n         * @summary [DEPRECATED] Checkout branch\n         * @param {string} sandboxId \n         * @param {GitCheckoutRequest} gitCheckoutRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitCheckoutBranchDeprecated(sandboxId: string, gitCheckoutRequest: GitCheckoutRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.gitCheckoutBranchDeprecated(sandboxId, gitCheckoutRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Clone git repository\n         * @summary [DEPRECATED] Clone repository\n         * @param {string} sandboxId \n         * @param {GitCloneRequest} gitCloneRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitCloneRepositoryDeprecated(sandboxId: string, gitCloneRequest: GitCloneRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.gitCloneRepositoryDeprecated(sandboxId, gitCloneRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Commit changes to git repository\n         * @summary [DEPRECATED] Commit changes\n         * @param {string} sandboxId \n         * @param {GitCommitRequest} gitCommitRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitCommitChangesDeprecated(sandboxId: string, gitCommitRequest: GitCommitRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<GitCommitResponse> {\n            return localVarFp.gitCommitChangesDeprecated(sandboxId, gitCommitRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Create branch on git repository\n         * @summary [DEPRECATED] Create branch\n         * @param {string} sandboxId \n         * @param {GitBranchRequest} gitBranchRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitCreateBranchDeprecated(sandboxId: string, gitBranchRequest: GitBranchRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.gitCreateBranchDeprecated(sandboxId, gitBranchRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Delete branch on git repository\n         * @summary [DEPRECATED] Delete branch\n         * @param {string} sandboxId \n         * @param {GitDeleteBranchRequest} gitDeleteBranchRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitDeleteBranchDeprecated(sandboxId: string, gitDeleteBranchRequest: GitDeleteBranchRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.gitDeleteBranchDeprecated(sandboxId, gitDeleteBranchRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get commit history from git repository\n         * @summary [DEPRECATED] Get commit history\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitGetHistoryDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<GitCommitInfo>> {\n            return localVarFp.gitGetHistoryDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get status from git repository\n         * @summary [DEPRECATED] Get git status\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitGetStatusDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<GitStatus> {\n            return localVarFp.gitGetStatusDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Get branch list from git repository\n         * @summary [DEPRECATED] Get branch list\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitListBranchesDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ListBranchResponse> {\n            return localVarFp.gitListBranchesDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Pull changes from remote\n         * @summary [DEPRECATED] Pull changes\n         * @param {string} sandboxId \n         * @param {GitRepoRequest} gitRepoRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitPullChangesDeprecated(sandboxId: string, gitRepoRequest: GitRepoRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.gitPullChangesDeprecated(sandboxId, gitRepoRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Push changes to remote\n         * @summary [DEPRECATED] Push changes\n         * @param {string} sandboxId \n         * @param {GitRepoRequest} gitRepoRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        gitPushChangesDeprecated(sandboxId: string, gitRepoRequest: GitRepoRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.gitPushChangesDeprecated(sandboxId, gitRepoRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] List files\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [path] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        listFilesDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, path?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<FileInfo>> {\n            return localVarFp.listFilesDeprecated(sandboxId, xDaytonaOrganizationID, path, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * List all active PTY sessions in the sandbox\n         * @summary [DEPRECATED] List PTY sessions\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        listPTYSessionsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<PtyListResponse> {\n            return localVarFp.listPTYSessionsDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * List all active sessions in the sandbox\n         * @summary [DEPRECATED] List sessions\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        listSessionsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<Session>> {\n            return localVarFp.listSessionsDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * The Completion request is sent from the client to the server to compute completion items at a given cursor position.\n         * @summary [DEPRECATED] Get Lsp Completions\n         * @param {string} sandboxId \n         * @param {LspCompletionParams} lspCompletionParams \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspCompletionsDeprecated(sandboxId: string, lspCompletionParams: LspCompletionParams, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<CompletionList> {\n            return localVarFp.lspCompletionsDeprecated(sandboxId, lspCompletionParams, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * The document close notification is sent from the client to the server when the document got closed in the client.\n         * @summary [DEPRECATED] Call Lsp DidClose\n         * @param {string} sandboxId \n         * @param {LspDocumentRequest} lspDocumentRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspDidCloseDeprecated(sandboxId: string, lspDocumentRequest: LspDocumentRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.lspDidCloseDeprecated(sandboxId, lspDocumentRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * The document open notification is sent from the client to the server to signal newly opened text documents.\n         * @summary [DEPRECATED] Call Lsp DidOpen\n         * @param {string} sandboxId \n         * @param {LspDocumentRequest} lspDocumentRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspDidOpenDeprecated(sandboxId: string, lspDocumentRequest: LspDocumentRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.lspDidOpenDeprecated(sandboxId, lspDocumentRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * The document symbol request is sent from the client to the server.\n         * @summary [DEPRECATED] Call Lsp DocumentSymbols\n         * @param {string} sandboxId \n         * @param {string} languageId \n         * @param {string} pathToProject \n         * @param {string} uri \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspDocumentSymbolsDeprecated(sandboxId: string, languageId: string, pathToProject: string, uri: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<LspSymbol>> {\n            return localVarFp.lspDocumentSymbolsDeprecated(sandboxId, languageId, pathToProject, uri, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Start Lsp server process inside sandbox project\n         * @summary [DEPRECATED] Start Lsp server\n         * @param {string} sandboxId \n         * @param {LspServerRequest} lspServerRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspStartDeprecated(sandboxId: string, lspServerRequest: LspServerRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.lspStartDeprecated(sandboxId, lspServerRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Stop Lsp server process inside sandbox project\n         * @summary [DEPRECATED] Stop Lsp server\n         * @param {string} sandboxId \n         * @param {LspServerRequest} lspServerRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspStopDeprecated(sandboxId: string, lspServerRequest: LspServerRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.lspStopDeprecated(sandboxId, lspServerRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n         * @summary [DEPRECATED] Call Lsp WorkspaceSymbols\n         * @param {string} sandboxId \n         * @param {string} languageId \n         * @param {string} pathToProject \n         * @param {string} query \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        lspWorkspaceSymbolsDeprecated(sandboxId: string, languageId: string, pathToProject: string, query: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<LspSymbol>> {\n            return localVarFp.lspWorkspaceSymbolsDeprecated(sandboxId, languageId, pathToProject, query, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Move file inside sandbox\n         * @summary [DEPRECATED] Move file\n         * @param {string} sandboxId \n         * @param {string} source \n         * @param {string} destination \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        moveFileDeprecated(sandboxId: string, source: string, destination: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.moveFileDeprecated(sandboxId, source, destination, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Move mouse cursor to specified coordinates\n         * @summary [DEPRECATED] Move mouse\n         * @param {string} sandboxId \n         * @param {MouseMoveRequest} mouseMoveRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        moveMouseDeprecated(sandboxId: string, mouseMoveRequest: MouseMoveRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<MouseMoveResponse> {\n            return localVarFp.moveMouseDeprecated(sandboxId, mouseMoveRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Press a hotkey combination\n         * @summary [DEPRECATED] Press hotkey\n         * @param {string} sandboxId \n         * @param {KeyboardHotkeyRequest} keyboardHotkeyRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        pressHotkeyDeprecated(sandboxId: string, keyboardHotkeyRequest: KeyboardHotkeyRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.pressHotkeyDeprecated(sandboxId, keyboardHotkeyRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Press a key with optional modifiers\n         * @summary [DEPRECATED] Press key\n         * @param {string} sandboxId \n         * @param {KeyboardPressRequest} keyboardPressRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        pressKeyDeprecated(sandboxId: string, keyboardPressRequest: KeyboardPressRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.pressKeyDeprecated(sandboxId, keyboardPressRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Replace text/pattern in multiple files inside sandbox\n         * @summary [DEPRECATED] Replace in files\n         * @param {string} sandboxId \n         * @param {ReplaceRequest} replaceRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        replaceInFilesDeprecated(sandboxId: string, replaceRequest: ReplaceRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<ReplaceResult>> {\n            return localVarFp.replaceInFilesDeprecated(sandboxId, replaceRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Resize a PTY session\n         * @summary [DEPRECATED] Resize PTY session\n         * @param {string} sandboxId \n         * @param {string} sessionId \n         * @param {PtyResizeRequest} ptyResizeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        resizePTYSessionDeprecated(sandboxId: string, sessionId: string, ptyResizeRequest: PtyResizeRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<PtySessionInfo> {\n            return localVarFp.resizePTYSessionDeprecated(sandboxId, sessionId, ptyResizeRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Restart a specific VNC process\n         * @summary [DEPRECATED] Restart process\n         * @param {string} processName \n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        restartProcessDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ProcessRestartResponse> {\n            return localVarFp.restartProcessDeprecated(processName, sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Scroll mouse at specified coordinates\n         * @summary [DEPRECATED] Scroll mouse\n         * @param {string} sandboxId \n         * @param {MouseScrollRequest} mouseScrollRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        scrollMouseDeprecated(sandboxId: string, mouseScrollRequest: MouseScrollRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<MouseScrollResponse> {\n            return localVarFp.scrollMouseDeprecated(sandboxId, mouseScrollRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Search for files inside sandbox\n         * @summary [DEPRECATED] Search files\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} pattern \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        searchFilesDeprecated(sandboxId: string, path: string, pattern: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SearchFilesResponse> {\n            return localVarFp.searchFilesDeprecated(sandboxId, path, pattern, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Set file owner/group/permissions inside sandbox\n         * @summary [DEPRECATED] Set file permissions\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {string} [owner] \n         * @param {string} [group] \n         * @param {string} [mode] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        setFilePermissionsDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, owner?: string, group?: string, mode?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.setFilePermissionsDeprecated(sandboxId, path, xDaytonaOrganizationID, owner, group, mode, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n         * @summary [DEPRECATED] Start computer use processes\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        startComputerUseDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ComputerUseStartResponse> {\n            return localVarFp.startComputerUseDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n         * @summary [DEPRECATED] Stop computer use processes\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        stopComputerUseDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<ComputerUseStopResponse> {\n            return localVarFp.stopComputerUseDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Take a compressed screenshot of a specific region\n         * @summary [DEPRECATED] Take compressed region screenshot\n         * @param {string} sandboxId \n         * @param {number} height \n         * @param {number} width \n         * @param {number} y \n         * @param {number} x \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [scale] \n         * @param {number} [quality] \n         * @param {string} [format] \n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        takeCompressedRegionScreenshotDeprecated(sandboxId: string, height: number, width: number, y: number, x: number, xDaytonaOrganizationID?: string, scale?: number, quality?: number, format?: string, showCursor?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<CompressedScreenshotResponse> {\n            return localVarFp.takeCompressedRegionScreenshotDeprecated(sandboxId, height, width, y, x, xDaytonaOrganizationID, scale, quality, format, showCursor, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Take a compressed screenshot with format, quality, and scale options\n         * @summary [DEPRECATED] Take compressed screenshot\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {number} [scale] \n         * @param {number} [quality] \n         * @param {string} [format] \n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        takeCompressedScreenshotDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, scale?: number, quality?: number, format?: string, showCursor?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<CompressedScreenshotResponse> {\n            return localVarFp.takeCompressedScreenshotDeprecated(sandboxId, xDaytonaOrganizationID, scale, quality, format, showCursor, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Take a screenshot of a specific region\n         * @summary [DEPRECATED] Take region screenshot\n         * @param {string} sandboxId \n         * @param {number} height \n         * @param {number} width \n         * @param {number} y \n         * @param {number} x \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        takeRegionScreenshotDeprecated(sandboxId: string, height: number, width: number, y: number, x: number, xDaytonaOrganizationID?: string, showCursor?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<RegionScreenshotResponse> {\n            return localVarFp.takeRegionScreenshotDeprecated(sandboxId, height, width, y, x, xDaytonaOrganizationID, showCursor, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Take a screenshot of the entire screen\n         * @summary [DEPRECATED] Take screenshot\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [showCursor] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        takeScreenshotDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, showCursor?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<ScreenshotResponse> {\n            return localVarFp.takeScreenshotDeprecated(sandboxId, xDaytonaOrganizationID, showCursor, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Type text using keyboard\n         * @summary [DEPRECATED] Type text\n         * @param {string} sandboxId \n         * @param {KeyboardTypeRequest} keyboardTypeRequest \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        typeTextDeprecated(sandboxId: string, keyboardTypeRequest: KeyboardTypeRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.typeTextDeprecated(sandboxId, keyboardTypeRequest, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Upload file inside sandbox\n         * @summary [DEPRECATED] Upload file\n         * @param {string} sandboxId \n         * @param {string} path \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {File} [file] \n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        uploadFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, file?: File, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.uploadFileDeprecated(sandboxId, path, xDaytonaOrganizationID, file, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * Upload multiple files inside sandbox\n         * @summary [DEPRECATED] Upload multiple files\n         * @param {string} sandboxId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        uploadFilesDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.uploadFilesDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * ToolboxApi - object-oriented interface\n * @export\n * @class ToolboxApi\n * @extends {BaseAPI}\n */\nexport class ToolboxApi extends BaseAPI {\n    /**\n     * Click mouse at specified coordinates\n     * @summary [DEPRECATED] Click mouse\n     * @param {string} sandboxId \n     * @param {MouseClickRequest} mouseClickRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public clickMouseDeprecated(sandboxId: string, mouseClickRequest: MouseClickRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).clickMouseDeprecated(sandboxId, mouseClickRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Create folder inside sandbox\n     * @summary [DEPRECATED] Create folder\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} mode \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public createFolderDeprecated(sandboxId: string, path: string, mode: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).createFolderDeprecated(sandboxId, path, mode, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Create a new PTY session in the sandbox\n     * @summary [DEPRECATED] Create PTY session\n     * @param {string} sandboxId \n     * @param {PtyCreateRequest} ptyCreateRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public createPTYSessionDeprecated(sandboxId: string, ptyCreateRequest: PtyCreateRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).createPTYSessionDeprecated(sandboxId, ptyCreateRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Create a new session in the sandbox\n     * @summary [DEPRECATED] Create session\n     * @param {string} sandboxId \n     * @param {CreateSessionRequest} createSessionRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public createSessionDeprecated(sandboxId: string, createSessionRequest: CreateSessionRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).createSessionDeprecated(sandboxId, createSessionRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Delete file inside sandbox\n     * @summary [DEPRECATED] Delete file\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [recursive] \n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public deleteFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, recursive?: boolean, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).deleteFileDeprecated(sandboxId, path, xDaytonaOrganizationID, recursive, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Delete a PTY session and terminate the associated process\n     * @summary [DEPRECATED] Delete PTY session\n     * @param {string} sandboxId \n     * @param {string} sessionId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public deletePTYSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).deletePTYSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Delete a specific session\n     * @summary [DEPRECATED] Delete session\n     * @param {string} sandboxId \n     * @param {string} sessionId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public deleteSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).deleteSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Download file from sandbox\n     * @summary [DEPRECATED] Download file\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public downloadFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).downloadFileDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Streams back a multipart/form-data bundle of the requested paths\n     * @summary [DEPRECATED] Download multiple files\n     * @param {string} sandboxId \n     * @param {DownloadFiles} downloadFiles \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public downloadFilesDeprecated(sandboxId: string, downloadFiles: DownloadFiles, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).downloadFilesDeprecated(sandboxId, downloadFiles, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Drag mouse from start to end coordinates\n     * @summary [DEPRECATED] Drag mouse\n     * @param {string} sandboxId \n     * @param {MouseDragRequest} mouseDragRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public dragMouseDeprecated(sandboxId: string, mouseDragRequest: MouseDragRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).dragMouseDeprecated(sandboxId, mouseDragRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Execute command synchronously inside sandbox\n     * @summary [DEPRECATED] Execute command\n     * @param {string} sandboxId \n     * @param {ExecuteRequest} executeRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public executeCommandDeprecated(sandboxId: string, executeRequest: ExecuteRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).executeCommandDeprecated(sandboxId, executeRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Execute a command in a specific session\n     * @summary [DEPRECATED] Execute command in session\n     * @param {string} sandboxId \n     * @param {string} sessionId \n     * @param {SessionExecuteRequest} sessionExecuteRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public executeSessionCommandDeprecated(sandboxId: string, sessionId: string, sessionExecuteRequest: SessionExecuteRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).executeSessionCommandDeprecated(sandboxId, sessionId, sessionExecuteRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Search for text/pattern inside sandbox files\n     * @summary [DEPRECATED] Search for text/pattern in files\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} pattern \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public findInFilesDeprecated(sandboxId: string, path: string, pattern: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).findInFilesDeprecated(sandboxId, path, pattern, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get status of all VNC desktop processes\n     * @summary [DEPRECATED] Get computer use status\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getComputerUseStatusDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getComputerUseStatusDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get information about displays\n     * @summary [DEPRECATED] Get display info\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getDisplayInfoDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getDisplayInfoDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get file info inside sandbox\n     * @summary [DEPRECATED] Get file info\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getFileInfoDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getFileInfoDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get current mouse cursor position\n     * @summary [DEPRECATED] Get mouse position\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getMousePositionDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getMousePositionDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get PTY session information by ID\n     * @summary [DEPRECATED] Get PTY session\n     * @param {string} sandboxId \n     * @param {string} sessionId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getPTYSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getPTYSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get error logs for a specific VNC process\n     * @summary [DEPRECATED] Get process errors\n     * @param {string} processName \n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getProcessErrorsDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getProcessErrorsDeprecated(processName, sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get logs for a specific VNC process\n     * @summary [DEPRECATED] Get process logs\n     * @param {string} processName \n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getProcessLogsDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getProcessLogsDeprecated(processName, sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get status of a specific VNC process\n     * @summary [DEPRECATED] Get process status\n     * @param {string} processName \n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getProcessStatusDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getProcessStatusDeprecated(processName, sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Get sandbox project dir\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getProjectDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getProjectDirDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get session command by ID\n     * @summary [DEPRECATED] Get session command\n     * @param {string} sandboxId \n     * @param {string} sessionId \n     * @param {string} commandId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getSessionCommandDeprecated(sandboxId: string, sessionId: string, commandId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getSessionCommandDeprecated(sandboxId, sessionId, commandId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get logs for a specific command in a session\n     * @summary [DEPRECATED] Get command logs\n     * @param {string} sandboxId \n     * @param {string} sessionId \n     * @param {string} commandId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [follow] Whether to stream the logs\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getSessionCommandLogsDeprecated(sandboxId: string, sessionId: string, commandId: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getSessionCommandLogsDeprecated(sandboxId, sessionId, commandId, xDaytonaOrganizationID, follow, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get session by ID\n     * @summary [DEPRECATED] Get session\n     * @param {string} sandboxId \n     * @param {string} sessionId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getSessionDeprecated(sandboxId: string, sessionId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getSessionDeprecated(sandboxId, sessionId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Get sandbox user home dir\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getUserHomeDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getUserHomeDirDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get list of open windows\n     * @summary [DEPRECATED] Get windows\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getWindowsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getWindowsDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Get sandbox work-dir\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public getWorkDirDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).getWorkDirDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Add files to git commit\n     * @summary [DEPRECATED] Add files\n     * @param {string} sandboxId \n     * @param {GitAddRequest} gitAddRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitAddFilesDeprecated(sandboxId: string, gitAddRequest: GitAddRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitAddFilesDeprecated(sandboxId, gitAddRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Checkout branch or commit in git repository\n     * @summary [DEPRECATED] Checkout branch\n     * @param {string} sandboxId \n     * @param {GitCheckoutRequest} gitCheckoutRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitCheckoutBranchDeprecated(sandboxId: string, gitCheckoutRequest: GitCheckoutRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitCheckoutBranchDeprecated(sandboxId, gitCheckoutRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Clone git repository\n     * @summary [DEPRECATED] Clone repository\n     * @param {string} sandboxId \n     * @param {GitCloneRequest} gitCloneRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitCloneRepositoryDeprecated(sandboxId: string, gitCloneRequest: GitCloneRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitCloneRepositoryDeprecated(sandboxId, gitCloneRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Commit changes to git repository\n     * @summary [DEPRECATED] Commit changes\n     * @param {string} sandboxId \n     * @param {GitCommitRequest} gitCommitRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitCommitChangesDeprecated(sandboxId: string, gitCommitRequest: GitCommitRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitCommitChangesDeprecated(sandboxId, gitCommitRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Create branch on git repository\n     * @summary [DEPRECATED] Create branch\n     * @param {string} sandboxId \n     * @param {GitBranchRequest} gitBranchRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitCreateBranchDeprecated(sandboxId: string, gitBranchRequest: GitBranchRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitCreateBranchDeprecated(sandboxId, gitBranchRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Delete branch on git repository\n     * @summary [DEPRECATED] Delete branch\n     * @param {string} sandboxId \n     * @param {GitDeleteBranchRequest} gitDeleteBranchRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitDeleteBranchDeprecated(sandboxId: string, gitDeleteBranchRequest: GitDeleteBranchRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitDeleteBranchDeprecated(sandboxId, gitDeleteBranchRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get commit history from git repository\n     * @summary [DEPRECATED] Get commit history\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitGetHistoryDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitGetHistoryDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get status from git repository\n     * @summary [DEPRECATED] Get git status\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitGetStatusDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitGetStatusDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Get branch list from git repository\n     * @summary [DEPRECATED] Get branch list\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitListBranchesDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitListBranchesDeprecated(sandboxId, path, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Pull changes from remote\n     * @summary [DEPRECATED] Pull changes\n     * @param {string} sandboxId \n     * @param {GitRepoRequest} gitRepoRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitPullChangesDeprecated(sandboxId: string, gitRepoRequest: GitRepoRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitPullChangesDeprecated(sandboxId, gitRepoRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Push changes to remote\n     * @summary [DEPRECATED] Push changes\n     * @param {string} sandboxId \n     * @param {GitRepoRequest} gitRepoRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public gitPushChangesDeprecated(sandboxId: string, gitRepoRequest: GitRepoRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).gitPushChangesDeprecated(sandboxId, gitRepoRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] List files\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {string} [path] \n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public listFilesDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, path?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).listFilesDeprecated(sandboxId, xDaytonaOrganizationID, path, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * List all active PTY sessions in the sandbox\n     * @summary [DEPRECATED] List PTY sessions\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public listPTYSessionsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).listPTYSessionsDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * List all active sessions in the sandbox\n     * @summary [DEPRECATED] List sessions\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public listSessionsDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).listSessionsDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * The Completion request is sent from the client to the server to compute completion items at a given cursor position.\n     * @summary [DEPRECATED] Get Lsp Completions\n     * @param {string} sandboxId \n     * @param {LspCompletionParams} lspCompletionParams \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public lspCompletionsDeprecated(sandboxId: string, lspCompletionParams: LspCompletionParams, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).lspCompletionsDeprecated(sandboxId, lspCompletionParams, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * The document close notification is sent from the client to the server when the document got closed in the client.\n     * @summary [DEPRECATED] Call Lsp DidClose\n     * @param {string} sandboxId \n     * @param {LspDocumentRequest} lspDocumentRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public lspDidCloseDeprecated(sandboxId: string, lspDocumentRequest: LspDocumentRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).lspDidCloseDeprecated(sandboxId, lspDocumentRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * The document open notification is sent from the client to the server to signal newly opened text documents.\n     * @summary [DEPRECATED] Call Lsp DidOpen\n     * @param {string} sandboxId \n     * @param {LspDocumentRequest} lspDocumentRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public lspDidOpenDeprecated(sandboxId: string, lspDocumentRequest: LspDocumentRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).lspDidOpenDeprecated(sandboxId, lspDocumentRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * The document symbol request is sent from the client to the server.\n     * @summary [DEPRECATED] Call Lsp DocumentSymbols\n     * @param {string} sandboxId \n     * @param {string} languageId \n     * @param {string} pathToProject \n     * @param {string} uri \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public lspDocumentSymbolsDeprecated(sandboxId: string, languageId: string, pathToProject: string, uri: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).lspDocumentSymbolsDeprecated(sandboxId, languageId, pathToProject, uri, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Start Lsp server process inside sandbox project\n     * @summary [DEPRECATED] Start Lsp server\n     * @param {string} sandboxId \n     * @param {LspServerRequest} lspServerRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public lspStartDeprecated(sandboxId: string, lspServerRequest: LspServerRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).lspStartDeprecated(sandboxId, lspServerRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Stop Lsp server process inside sandbox project\n     * @summary [DEPRECATED] Stop Lsp server\n     * @param {string} sandboxId \n     * @param {LspServerRequest} lspServerRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public lspStopDeprecated(sandboxId: string, lspServerRequest: LspServerRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).lspStopDeprecated(sandboxId, lspServerRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n     * @summary [DEPRECATED] Call Lsp WorkspaceSymbols\n     * @param {string} sandboxId \n     * @param {string} languageId \n     * @param {string} pathToProject \n     * @param {string} query \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public lspWorkspaceSymbolsDeprecated(sandboxId: string, languageId: string, pathToProject: string, query: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).lspWorkspaceSymbolsDeprecated(sandboxId, languageId, pathToProject, query, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Move file inside sandbox\n     * @summary [DEPRECATED] Move file\n     * @param {string} sandboxId \n     * @param {string} source \n     * @param {string} destination \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public moveFileDeprecated(sandboxId: string, source: string, destination: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).moveFileDeprecated(sandboxId, source, destination, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Move mouse cursor to specified coordinates\n     * @summary [DEPRECATED] Move mouse\n     * @param {string} sandboxId \n     * @param {MouseMoveRequest} mouseMoveRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public moveMouseDeprecated(sandboxId: string, mouseMoveRequest: MouseMoveRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).moveMouseDeprecated(sandboxId, mouseMoveRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Press a hotkey combination\n     * @summary [DEPRECATED] Press hotkey\n     * @param {string} sandboxId \n     * @param {KeyboardHotkeyRequest} keyboardHotkeyRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public pressHotkeyDeprecated(sandboxId: string, keyboardHotkeyRequest: KeyboardHotkeyRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).pressHotkeyDeprecated(sandboxId, keyboardHotkeyRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Press a key with optional modifiers\n     * @summary [DEPRECATED] Press key\n     * @param {string} sandboxId \n     * @param {KeyboardPressRequest} keyboardPressRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public pressKeyDeprecated(sandboxId: string, keyboardPressRequest: KeyboardPressRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).pressKeyDeprecated(sandboxId, keyboardPressRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Replace text/pattern in multiple files inside sandbox\n     * @summary [DEPRECATED] Replace in files\n     * @param {string} sandboxId \n     * @param {ReplaceRequest} replaceRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public replaceInFilesDeprecated(sandboxId: string, replaceRequest: ReplaceRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).replaceInFilesDeprecated(sandboxId, replaceRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Resize a PTY session\n     * @summary [DEPRECATED] Resize PTY session\n     * @param {string} sandboxId \n     * @param {string} sessionId \n     * @param {PtyResizeRequest} ptyResizeRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public resizePTYSessionDeprecated(sandboxId: string, sessionId: string, ptyResizeRequest: PtyResizeRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).resizePTYSessionDeprecated(sandboxId, sessionId, ptyResizeRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Restart a specific VNC process\n     * @summary [DEPRECATED] Restart process\n     * @param {string} processName \n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public restartProcessDeprecated(processName: string, sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).restartProcessDeprecated(processName, sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Scroll mouse at specified coordinates\n     * @summary [DEPRECATED] Scroll mouse\n     * @param {string} sandboxId \n     * @param {MouseScrollRequest} mouseScrollRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public scrollMouseDeprecated(sandboxId: string, mouseScrollRequest: MouseScrollRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).scrollMouseDeprecated(sandboxId, mouseScrollRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Search for files inside sandbox\n     * @summary [DEPRECATED] Search files\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} pattern \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public searchFilesDeprecated(sandboxId: string, path: string, pattern: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).searchFilesDeprecated(sandboxId, path, pattern, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Set file owner/group/permissions inside sandbox\n     * @summary [DEPRECATED] Set file permissions\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {string} [owner] \n     * @param {string} [group] \n     * @param {string} [mode] \n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public setFilePermissionsDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, owner?: string, group?: string, mode?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).setFilePermissionsDeprecated(sandboxId, path, xDaytonaOrganizationID, owner, group, mode, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n     * @summary [DEPRECATED] Start computer use processes\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public startComputerUseDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).startComputerUseDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n     * @summary [DEPRECATED] Stop computer use processes\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public stopComputerUseDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).stopComputerUseDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Take a compressed screenshot of a specific region\n     * @summary [DEPRECATED] Take compressed region screenshot\n     * @param {string} sandboxId \n     * @param {number} height \n     * @param {number} width \n     * @param {number} y \n     * @param {number} x \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {number} [scale] \n     * @param {number} [quality] \n     * @param {string} [format] \n     * @param {boolean} [showCursor] \n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public takeCompressedRegionScreenshotDeprecated(sandboxId: string, height: number, width: number, y: number, x: number, xDaytonaOrganizationID?: string, scale?: number, quality?: number, format?: string, showCursor?: boolean, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).takeCompressedRegionScreenshotDeprecated(sandboxId, height, width, y, x, xDaytonaOrganizationID, scale, quality, format, showCursor, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Take a compressed screenshot with format, quality, and scale options\n     * @summary [DEPRECATED] Take compressed screenshot\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {number} [scale] \n     * @param {number} [quality] \n     * @param {string} [format] \n     * @param {boolean} [showCursor] \n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public takeCompressedScreenshotDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, scale?: number, quality?: number, format?: string, showCursor?: boolean, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).takeCompressedScreenshotDeprecated(sandboxId, xDaytonaOrganizationID, scale, quality, format, showCursor, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Take a screenshot of a specific region\n     * @summary [DEPRECATED] Take region screenshot\n     * @param {string} sandboxId \n     * @param {number} height \n     * @param {number} width \n     * @param {number} y \n     * @param {number} x \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [showCursor] \n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public takeRegionScreenshotDeprecated(sandboxId: string, height: number, width: number, y: number, x: number, xDaytonaOrganizationID?: string, showCursor?: boolean, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).takeRegionScreenshotDeprecated(sandboxId, height, width, y, x, xDaytonaOrganizationID, showCursor, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Take a screenshot of the entire screen\n     * @summary [DEPRECATED] Take screenshot\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [showCursor] \n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public takeScreenshotDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, showCursor?: boolean, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).takeScreenshotDeprecated(sandboxId, xDaytonaOrganizationID, showCursor, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Type text using keyboard\n     * @summary [DEPRECATED] Type text\n     * @param {string} sandboxId \n     * @param {KeyboardTypeRequest} keyboardTypeRequest \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public typeTextDeprecated(sandboxId: string, keyboardTypeRequest: KeyboardTypeRequest, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).typeTextDeprecated(sandboxId, keyboardTypeRequest, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Upload file inside sandbox\n     * @summary [DEPRECATED] Upload file\n     * @param {string} sandboxId \n     * @param {string} path \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {File} [file] \n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public uploadFileDeprecated(sandboxId: string, path: string, xDaytonaOrganizationID?: string, file?: File, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).uploadFileDeprecated(sandboxId, path, xDaytonaOrganizationID, file, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * Upload multiple files inside sandbox\n     * @summary [DEPRECATED] Upload multiple files\n     * @param {string} sandboxId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof ToolboxApi\n     */\n    public uploadFilesDeprecated(sandboxId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return ToolboxApiFp(this.configuration).uploadFilesDeprecated(sandboxId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/users-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { AccountProvider } from '../models';\n// @ts-ignore\nimport type { CreateLinkedAccount } from '../models';\n// @ts-ignore\nimport type { CreateUser } from '../models';\n// @ts-ignore\nimport type { User } from '../models';\n/**\n * UsersApi - axios parameter creator\n * @export\n */\nexport const UsersApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Create user\n         * @param {CreateUser} createUser \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createUser: async (createUser: CreateUser, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createUser' is not null or undefined\n            assertParamExists('createUser', 'createUser', createUser)\n            const localVarPath = `/users`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createUser, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Enroll in SMS MFA\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        enrollInSmsMfa: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/users/mfa/sms/enroll`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getAuthenticatedUser: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/users/me`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get available account providers\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getAvailableAccountProviders: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/users/account-providers`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get user by ID\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getUser: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('getUser', 'id', id)\n            const localVarPath = `/users/{id}`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Link account\n         * @param {CreateLinkedAccount} createLinkedAccount \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        linkAccount: async (createLinkedAccount: CreateLinkedAccount, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createLinkedAccount' is not null or undefined\n            assertParamExists('linkAccount', 'createLinkedAccount', createLinkedAccount)\n            const localVarPath = `/users/linked-accounts`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createLinkedAccount, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List all users\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listUsers: async (options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/users`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Regenerate user key pair\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        regenerateKeyPair: async (id: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'id' is not null or undefined\n            assertParamExists('regenerateKeyPair', 'id', id)\n            const localVarPath = `/users/{id}/regenerate-key-pair`\n                .replace(`{${\"id\"}}`, encodeURIComponent(String(id)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Unlink account\n         * @param {string} provider \n         * @param {string} providerUserId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        unlinkAccount: async (provider: string, providerUserId: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'provider' is not null or undefined\n            assertParamExists('unlinkAccount', 'provider', provider)\n            // verify required parameter 'providerUserId' is not null or undefined\n            assertParamExists('unlinkAccount', 'providerUserId', providerUserId)\n            const localVarPath = `/users/linked-accounts/{provider}/{providerUserId}`\n                .replace(`{${\"provider\"}}`, encodeURIComponent(String(provider)))\n                .replace(`{${\"providerUserId\"}}`, encodeURIComponent(String(providerUserId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * UsersApi - functional programming interface\n * @export\n */\nexport const UsersApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = UsersApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Create user\n         * @param {CreateUser} createUser \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createUser(createUser: CreateUser, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createUser(createUser, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.createUser']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Enroll in SMS MFA\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async enrollInSmsMfa(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<string>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.enrollInSmsMfa(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.enrollInSmsMfa']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getAuthenticatedUser(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<User>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getAuthenticatedUser(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.getAuthenticatedUser']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get available account providers\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getAvailableAccountProviders(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AccountProvider>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getAvailableAccountProviders(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.getAvailableAccountProviders']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get user by ID\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getUser(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<User>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getUser(id, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.getUser']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Link account\n         * @param {CreateLinkedAccount} createLinkedAccount \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async linkAccount(createLinkedAccount: CreateLinkedAccount, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.linkAccount(createLinkedAccount, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.linkAccount']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List all users\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listUsers(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listUsers(options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.listUsers']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Regenerate user key pair\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async regenerateKeyPair(id: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.regenerateKeyPair(id, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.regenerateKeyPair']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Unlink account\n         * @param {string} provider \n         * @param {string} providerUserId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async unlinkAccount(provider: string, providerUserId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.unlinkAccount(provider, providerUserId, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['UsersApi.unlinkAccount']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * UsersApi - factory interface\n * @export\n */\nexport const UsersApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = UsersApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Create user\n         * @param {CreateUser} createUser \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createUser(createUser: CreateUser, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.createUser(createUser, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Enroll in SMS MFA\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        enrollInSmsMfa(options?: RawAxiosRequestConfig): AxiosPromise<string> {\n            return localVarFp.enrollInSmsMfa(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get authenticated user\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getAuthenticatedUser(options?: RawAxiosRequestConfig): AxiosPromise<User> {\n            return localVarFp.getAuthenticatedUser(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get available account providers\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getAvailableAccountProviders(options?: RawAxiosRequestConfig): AxiosPromise<Array<AccountProvider>> {\n            return localVarFp.getAvailableAccountProviders(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get user by ID\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getUser(id: string, options?: RawAxiosRequestConfig): AxiosPromise<User> {\n            return localVarFp.getUser(id, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Link account\n         * @param {CreateLinkedAccount} createLinkedAccount \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        linkAccount(createLinkedAccount: CreateLinkedAccount, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.linkAccount(createLinkedAccount, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List all users\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listUsers(options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.listUsers(options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Regenerate user key pair\n         * @param {string} id \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        regenerateKeyPair(id: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.regenerateKeyPair(id, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Unlink account\n         * @param {string} provider \n         * @param {string} providerUserId \n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        unlinkAccount(provider: string, providerUserId: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.unlinkAccount(provider, providerUserId, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * UsersApi - object-oriented interface\n * @export\n * @class UsersApi\n * @extends {BaseAPI}\n */\nexport class UsersApi extends BaseAPI {\n    /**\n     * \n     * @summary Create user\n     * @param {CreateUser} createUser \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public createUser(createUser: CreateUser, options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).createUser(createUser, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Enroll in SMS MFA\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public enrollInSmsMfa(options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).enrollInSmsMfa(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get authenticated user\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public getAuthenticatedUser(options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).getAuthenticatedUser(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get available account providers\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public getAvailableAccountProviders(options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).getAvailableAccountProviders(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get user by ID\n     * @param {string} id \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public getUser(id: string, options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).getUser(id, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Link account\n     * @param {CreateLinkedAccount} createLinkedAccount \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public linkAccount(createLinkedAccount: CreateLinkedAccount, options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).linkAccount(createLinkedAccount, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List all users\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public listUsers(options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).listUsers(options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Regenerate user key pair\n     * @param {string} id \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public regenerateKeyPair(id: string, options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).regenerateKeyPair(id, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Unlink account\n     * @param {string} provider \n     * @param {string} providerUserId \n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof UsersApi\n     */\n    public unlinkAccount(provider: string, providerUserId: string, options?: RawAxiosRequestConfig) {\n        return UsersApiFp(this.configuration).unlinkAccount(provider, providerUserId, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/volumes-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { CreateVolume } from '../models';\n// @ts-ignore\nimport type { VolumeDto } from '../models';\n/**\n * VolumesApi - axios parameter creator\n * @export\n */\nexport const VolumesApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Create a new volume\n         * @param {CreateVolume} createVolume \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createVolume: async (createVolume: CreateVolume, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createVolume' is not null or undefined\n            assertParamExists('createVolume', 'createVolume', createVolume)\n            const localVarPath = `/volumes`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createVolume, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Delete volume\n         * @param {string} volumeId ID of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteVolume: async (volumeId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'volumeId' is not null or undefined\n            assertParamExists('deleteVolume', 'volumeId', volumeId)\n            const localVarPath = `/volumes/{volumeId}`\n                .replace(`{${\"volumeId\"}}`, encodeURIComponent(String(volumeId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get volume details\n         * @param {string} volumeId ID of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getVolume: async (volumeId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'volumeId' is not null or undefined\n            assertParamExists('getVolume', 'volumeId', volumeId)\n            const localVarPath = `/volumes/{volumeId}`\n                .replace(`{${\"volumeId\"}}`, encodeURIComponent(String(volumeId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get volume details by name\n         * @param {string} name Name of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getVolumeByName: async (name: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'name' is not null or undefined\n            assertParamExists('getVolumeByName', 'name', name)\n            const localVarPath = `/volumes/by-name/{name}`\n                .replace(`{${\"name\"}}`, encodeURIComponent(String(name)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary List all volumes\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [includeDeleted] Include deleted volumes in the response\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listVolumes: async (xDaytonaOrganizationID?: string, includeDeleted?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/volumes`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (includeDeleted !== undefined) {\n                localVarQueryParameter['includeDeleted'] = includeDeleted;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * VolumesApi - functional programming interface\n * @export\n */\nexport const VolumesApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = VolumesApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Create a new volume\n         * @param {CreateVolume} createVolume \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async createVolume(createVolume: CreateVolume, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<VolumeDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createVolume(createVolume, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['VolumesApi.createVolume']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Delete volume\n         * @param {string} volumeId ID of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async deleteVolume(volumeId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteVolume(volumeId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['VolumesApi.deleteVolume']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get volume details\n         * @param {string} volumeId ID of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getVolume(volumeId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<VolumeDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getVolume(volumeId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['VolumesApi.getVolume']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get volume details by name\n         * @param {string} name Name of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async getVolumeByName(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<VolumeDto>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getVolumeByName(name, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['VolumesApi.getVolumeByName']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary List all volumes\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [includeDeleted] Include deleted volumes in the response\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async listVolumes(xDaytonaOrganizationID?: string, includeDeleted?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<VolumeDto>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listVolumes(xDaytonaOrganizationID, includeDeleted, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['VolumesApi.listVolumes']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * VolumesApi - factory interface\n * @export\n */\nexport const VolumesApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = VolumesApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Create a new volume\n         * @param {CreateVolume} createVolume \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        createVolume(createVolume: CreateVolume, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<VolumeDto> {\n            return localVarFp.createVolume(createVolume, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Delete volume\n         * @param {string} volumeId ID of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        deleteVolume(volumeId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteVolume(volumeId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get volume details\n         * @param {string} volumeId ID of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getVolume(volumeId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<VolumeDto> {\n            return localVarFp.getVolume(volumeId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get volume details by name\n         * @param {string} name Name of the volume\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        getVolumeByName(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<VolumeDto> {\n            return localVarFp.getVolumeByName(name, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary List all volumes\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [includeDeleted] Include deleted volumes in the response\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        listVolumes(xDaytonaOrganizationID?: string, includeDeleted?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<Array<VolumeDto>> {\n            return localVarFp.listVolumes(xDaytonaOrganizationID, includeDeleted, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * VolumesApi - object-oriented interface\n * @export\n * @class VolumesApi\n * @extends {BaseAPI}\n */\nexport class VolumesApi extends BaseAPI {\n    /**\n     * \n     * @summary Create a new volume\n     * @param {CreateVolume} createVolume \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof VolumesApi\n     */\n    public createVolume(createVolume: CreateVolume, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return VolumesApiFp(this.configuration).createVolume(createVolume, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Delete volume\n     * @param {string} volumeId ID of the volume\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof VolumesApi\n     */\n    public deleteVolume(volumeId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return VolumesApiFp(this.configuration).deleteVolume(volumeId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get volume details\n     * @param {string} volumeId ID of the volume\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof VolumesApi\n     */\n    public getVolume(volumeId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return VolumesApiFp(this.configuration).getVolume(volumeId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get volume details by name\n     * @param {string} name Name of the volume\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof VolumesApi\n     */\n    public getVolumeByName(name: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return VolumesApiFp(this.configuration).getVolumeByName(name, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary List all volumes\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [includeDeleted] Include deleted volumes in the response\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof VolumesApi\n     */\n    public listVolumes(xDaytonaOrganizationID?: string, includeDeleted?: boolean, options?: RawAxiosRequestConfig) {\n        return VolumesApiFp(this.configuration).listVolumes(xDaytonaOrganizationID, includeDeleted, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/webhooks-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { SendWebhookDto } from '../models';\n// @ts-ignore\nimport type { WebhookAppPortalAccess } from '../models';\n// @ts-ignore\nimport type { WebhookControllerGetStatus200Response } from '../models';\n// @ts-ignore\nimport type { WebhookInitializationStatus } from '../models';\n/**\n * WebhooksApi - axios parameter creator\n * @export\n */\nexport const WebhooksApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary Get Svix Consumer App Portal access for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerGetAppPortalAccess: async (organizationId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('webhookControllerGetAppPortalAccess', 'organizationId', organizationId)\n            const localVarPath = `/webhooks/organizations/{organizationId}/app-portal-access`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get webhook initialization status for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerGetInitializationStatus: async (organizationId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('webhookControllerGetInitializationStatus', 'organizationId', organizationId)\n            const localVarPath = `/webhooks/organizations/{organizationId}/initialization-status`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get delivery attempts for a webhook message\n         * @param {string} organizationId \n         * @param {string} messageId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerGetMessageAttempts: async (organizationId: string, messageId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('webhookControllerGetMessageAttempts', 'organizationId', organizationId)\n            // verify required parameter 'messageId' is not null or undefined\n            assertParamExists('webhookControllerGetMessageAttempts', 'messageId', messageId)\n            const localVarPath = `/webhooks/organizations/{organizationId}/messages/{messageId}/attempts`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)))\n                .replace(`{${\"messageId\"}}`, encodeURIComponent(String(messageId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Get webhook service status\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerGetStatus: async (xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/webhooks/status`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Initialize webhooks for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerInitializeWebhooks: async (organizationId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('webhookControllerInitializeWebhooks', 'organizationId', organizationId)\n            const localVarPath = `/webhooks/organizations/{organizationId}/initialize`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary Send a webhook message to an organization\n         * @param {string} organizationId \n         * @param {SendWebhookDto} sendWebhookDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerSendWebhook: async (organizationId: string, sendWebhookDto: SendWebhookDto, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'organizationId' is not null or undefined\n            assertParamExists('webhookControllerSendWebhook', 'organizationId', organizationId)\n            // verify required parameter 'sendWebhookDto' is not null or undefined\n            assertParamExists('webhookControllerSendWebhook', 'sendWebhookDto', sendWebhookDto)\n            const localVarPath = `/webhooks/organizations/{organizationId}/send`\n                .replace(`{${\"organizationId\"}}`, encodeURIComponent(String(organizationId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(sendWebhookDto, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * WebhooksApi - functional programming interface\n * @export\n */\nexport const WebhooksApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = WebhooksApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary Get Svix Consumer App Portal access for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async webhookControllerGetAppPortalAccess(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<WebhookAppPortalAccess>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.webhookControllerGetAppPortalAccess(organizationId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WebhooksApi.webhookControllerGetAppPortalAccess']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get webhook initialization status for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async webhookControllerGetInitializationStatus(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<WebhookInitializationStatus>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.webhookControllerGetInitializationStatus(organizationId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WebhooksApi.webhookControllerGetInitializationStatus']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get delivery attempts for a webhook message\n         * @param {string} organizationId \n         * @param {string} messageId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async webhookControllerGetMessageAttempts(organizationId: string, messageId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<object>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.webhookControllerGetMessageAttempts(organizationId, messageId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WebhooksApi.webhookControllerGetMessageAttempts']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Get webhook service status\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async webhookControllerGetStatus(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<WebhookControllerGetStatus200Response>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.webhookControllerGetStatus(xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WebhooksApi.webhookControllerGetStatus']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Initialize webhooks for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async webhookControllerInitializeWebhooks(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.webhookControllerInitializeWebhooks(organizationId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WebhooksApi.webhookControllerInitializeWebhooks']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary Send a webhook message to an organization\n         * @param {string} organizationId \n         * @param {SendWebhookDto} sendWebhookDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        async webhookControllerSendWebhook(organizationId: string, sendWebhookDto: SendWebhookDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.webhookControllerSendWebhook(organizationId, sendWebhookDto, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WebhooksApi.webhookControllerSendWebhook']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * WebhooksApi - factory interface\n * @export\n */\nexport const WebhooksApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = WebhooksApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary Get Svix Consumer App Portal access for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerGetAppPortalAccess(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<WebhookAppPortalAccess> {\n            return localVarFp.webhookControllerGetAppPortalAccess(organizationId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get webhook initialization status for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerGetInitializationStatus(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<WebhookInitializationStatus> {\n            return localVarFp.webhookControllerGetInitializationStatus(organizationId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get delivery attempts for a webhook message\n         * @param {string} organizationId \n         * @param {string} messageId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerGetMessageAttempts(organizationId: string, messageId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<object>> {\n            return localVarFp.webhookControllerGetMessageAttempts(organizationId, messageId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Get webhook service status\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerGetStatus(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<WebhookControllerGetStatus200Response> {\n            return localVarFp.webhookControllerGetStatus(xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Initialize webhooks for an organization\n         * @param {string} organizationId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerInitializeWebhooks(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.webhookControllerInitializeWebhooks(organizationId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary Send a webhook message to an organization\n         * @param {string} organizationId \n         * @param {SendWebhookDto} sendWebhookDto \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @throws {RequiredError}\n         */\n        webhookControllerSendWebhook(organizationId: string, sendWebhookDto: SendWebhookDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.webhookControllerSendWebhook(organizationId, sendWebhookDto, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * WebhooksApi - object-oriented interface\n * @export\n * @class WebhooksApi\n * @extends {BaseAPI}\n */\nexport class WebhooksApi extends BaseAPI {\n    /**\n     * \n     * @summary Get Svix Consumer App Portal access for an organization\n     * @param {string} organizationId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof WebhooksApi\n     */\n    public webhookControllerGetAppPortalAccess(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WebhooksApiFp(this.configuration).webhookControllerGetAppPortalAccess(organizationId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get webhook initialization status for an organization\n     * @param {string} organizationId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof WebhooksApi\n     */\n    public webhookControllerGetInitializationStatus(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WebhooksApiFp(this.configuration).webhookControllerGetInitializationStatus(organizationId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get delivery attempts for a webhook message\n     * @param {string} organizationId \n     * @param {string} messageId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof WebhooksApi\n     */\n    public webhookControllerGetMessageAttempts(organizationId: string, messageId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WebhooksApiFp(this.configuration).webhookControllerGetMessageAttempts(organizationId, messageId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Get webhook service status\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof WebhooksApi\n     */\n    public webhookControllerGetStatus(xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WebhooksApiFp(this.configuration).webhookControllerGetStatus(xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Initialize webhooks for an organization\n     * @param {string} organizationId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof WebhooksApi\n     */\n    public webhookControllerInitializeWebhooks(organizationId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WebhooksApiFp(this.configuration).webhookControllerInitializeWebhooks(organizationId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary Send a webhook message to an organization\n     * @param {string} organizationId \n     * @param {SendWebhookDto} sendWebhookDto \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @throws {RequiredError}\n     * @memberof WebhooksApi\n     */\n    public webhookControllerSendWebhook(organizationId: string, sendWebhookDto: SendWebhookDto, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WebhooksApiFp(this.configuration).webhookControllerSendWebhook(organizationId, sendWebhookDto, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api/workspace-api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from '../configuration';\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '../common';\n// @ts-ignore\nimport { BASE_PATH, COLLECTION_FORMATS, type RequestArgs, BaseAPI, RequiredError, operationServerMap } from '../base';\n// @ts-ignore\nimport type { CreateWorkspace } from '../models';\n// @ts-ignore\nimport type { SandboxLabels } from '../models';\n// @ts-ignore\nimport type { Workspace } from '../models';\n// @ts-ignore\nimport type { WorkspacePortPreviewUrl } from '../models';\n/**\n * WorkspaceApi - axios parameter creator\n * @export\n */\nexport const WorkspaceApiAxiosParamCreator = function (configuration?: Configuration) {\n    return {\n        /**\n         * \n         * @summary [DEPRECATED] Archive workspace\n         * @param {string} workspaceId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        archiveWorkspaceDeprecated: async (workspaceId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('archiveWorkspaceDeprecated', 'workspaceId', workspaceId)\n            const localVarPath = `/workspace/{workspaceId}/archive`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Create workspace backup\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createBackupWorkspaceDeprecated: async (workspaceId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('createBackupWorkspaceDeprecated', 'workspaceId', workspaceId)\n            const localVarPath = `/workspace/{workspaceId}/backup`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Create a new workspace\n         * @param {CreateWorkspace} createWorkspace \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createWorkspaceDeprecated: async (createWorkspace: CreateWorkspace, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'createWorkspace' is not null or undefined\n            assertParamExists('createWorkspaceDeprecated', 'createWorkspace', createWorkspace)\n            const localVarPath = `/workspace`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(createWorkspace, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Delete workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {boolean} force \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        deleteWorkspaceDeprecated: async (workspaceId: string, force: boolean, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('deleteWorkspaceDeprecated', 'workspaceId', workspaceId)\n            // verify required parameter 'force' is not null or undefined\n            assertParamExists('deleteWorkspaceDeprecated', 'force', force)\n            const localVarPath = `/workspace/{workspaceId}`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'DELETE', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (force !== undefined) {\n                localVarQueryParameter['force'] = force;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get build logs\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getBuildLogsWorkspaceDeprecated: async (workspaceId: string, xDaytonaOrganizationID?: string, follow?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('getBuildLogsWorkspaceDeprecated', 'workspaceId', workspaceId)\n            const localVarPath = `/workspace/{workspaceId}/build-logs`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (follow !== undefined) {\n                localVarQueryParameter['follow'] = follow;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get preview URL for a workspace port\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} port Port number to get preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getPortPreviewUrlWorkspaceDeprecated: async (workspaceId: string, port: number, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('getPortPreviewUrlWorkspaceDeprecated', 'workspaceId', workspaceId)\n            // verify required parameter 'port' is not null or undefined\n            assertParamExists('getPortPreviewUrlWorkspaceDeprecated', 'port', port)\n            const localVarPath = `/workspace/{workspaceId}/ports/{port}/preview-url`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)))\n                .replace(`{${\"port\"}}`, encodeURIComponent(String(port)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get workspace details\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getWorkspaceDeprecated: async (workspaceId: string, xDaytonaOrganizationID?: string, verbose?: boolean, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('getWorkspaceDeprecated', 'workspaceId', workspaceId)\n            const localVarPath = `/workspace/{workspaceId}`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (verbose !== undefined) {\n                localVarQueryParameter['verbose'] = verbose;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] List all workspaces\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        listWorkspacesDeprecated: async (xDaytonaOrganizationID?: string, verbose?: boolean, labels?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            const localVarPath = `/workspace`;\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n            if (verbose !== undefined) {\n                localVarQueryParameter['verbose'] = verbose;\n            }\n\n            if (labels !== undefined) {\n                localVarQueryParameter['labels'] = labels;\n            }\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Replace workspace labels\n         * @param {string} workspaceId ID of the workspace\n         * @param {SandboxLabels} sandboxLabels \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        replaceLabelsWorkspaceDeprecated: async (workspaceId: string, sandboxLabels: SandboxLabels, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('replaceLabelsWorkspaceDeprecated', 'workspaceId', workspaceId)\n            // verify required parameter 'sandboxLabels' is not null or undefined\n            assertParamExists('replaceLabelsWorkspaceDeprecated', 'sandboxLabels', sandboxLabels)\n            const localVarPath = `/workspace/{workspaceId}/labels`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            localVarHeaderParameter['Content-Type'] = 'application/json';\n\n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n            localVarRequestOptions.data = serializeDataIfNeeded(sandboxLabels, localVarRequestOptions, configuration)\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Set workspace auto-archive interval\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        setAutoArchiveIntervalWorkspaceDeprecated: async (workspaceId: string, interval: number, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('setAutoArchiveIntervalWorkspaceDeprecated', 'workspaceId', workspaceId)\n            // verify required parameter 'interval' is not null or undefined\n            assertParamExists('setAutoArchiveIntervalWorkspaceDeprecated', 'interval', interval)\n            const localVarPath = `/workspace/{workspaceId}/autoarchive/{interval}`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)))\n                .replace(`{${\"interval\"}}`, encodeURIComponent(String(interval)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Set workspace auto-stop interval\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} interval Auto-stop interval in minutes (0 to disable)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        setAutostopIntervalWorkspaceDeprecated: async (workspaceId: string, interval: number, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('setAutostopIntervalWorkspaceDeprecated', 'workspaceId', workspaceId)\n            // verify required parameter 'interval' is not null or undefined\n            assertParamExists('setAutostopIntervalWorkspaceDeprecated', 'interval', interval)\n            const localVarPath = `/workspace/{workspaceId}/autostop/{interval}`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)))\n                .replace(`{${\"interval\"}}`, encodeURIComponent(String(interval)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Start workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        startWorkspaceDeprecated: async (workspaceId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('startWorkspaceDeprecated', 'workspaceId', workspaceId)\n            const localVarPath = `/workspace/{workspaceId}/start`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Stop workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        stopWorkspaceDeprecated: async (workspaceId: string, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('stopWorkspaceDeprecated', 'workspaceId', workspaceId)\n            const localVarPath = `/workspace/{workspaceId}/stop`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Update public status\n         * @param {string} workspaceId ID of the workspace\n         * @param {boolean} isPublic Public status to set\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        updatePublicStatusWorkspaceDeprecated: async (workspaceId: string, isPublic: boolean, xDaytonaOrganizationID?: string, options: RawAxiosRequestConfig = {}): Promise<RequestArgs> => {\n            // verify required parameter 'workspaceId' is not null or undefined\n            assertParamExists('updatePublicStatusWorkspaceDeprecated', 'workspaceId', workspaceId)\n            // verify required parameter 'isPublic' is not null or undefined\n            assertParamExists('updatePublicStatusWorkspaceDeprecated', 'isPublic', isPublic)\n            const localVarPath = `/workspace/{workspaceId}/public/{isPublic}`\n                .replace(`{${\"workspaceId\"}}`, encodeURIComponent(String(workspaceId)))\n                .replace(`{${\"isPublic\"}}`, encodeURIComponent(String(isPublic)));\n            // use dummy base URL string because the URL constructor only accepts absolute URLs.\n            const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);\n            let baseOptions;\n            if (configuration) {\n                baseOptions = configuration.baseOptions;\n            }\n\n            const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};\n            const localVarHeaderParameter = {} as any;\n            const localVarQueryParameter = {} as any;\n\n            // authentication bearer required\n            // http bearer authentication required\n            await setBearerAuthToObject(localVarHeaderParameter, configuration)\n\n            // authentication oauth2 required\n\n\n    \n            if (xDaytonaOrganizationID != null) {\n                localVarHeaderParameter['X-Daytona-Organization-ID'] = String(xDaytonaOrganizationID);\n            }\n            setSearchParams(localVarUrlObj, localVarQueryParameter);\n            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};\n            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};\n\n            return {\n                url: toPathString(localVarUrlObj),\n                options: localVarRequestOptions,\n            };\n        },\n    }\n};\n\n/**\n * WorkspaceApi - functional programming interface\n * @export\n */\nexport const WorkspaceApiFp = function(configuration?: Configuration) {\n    const localVarAxiosParamCreator = WorkspaceApiAxiosParamCreator(configuration)\n    return {\n        /**\n         * \n         * @summary [DEPRECATED] Archive workspace\n         * @param {string} workspaceId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async archiveWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.archiveWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.archiveWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Create workspace backup\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async createBackupWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Workspace>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createBackupWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.createBackupWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Create a new workspace\n         * @param {CreateWorkspace} createWorkspace \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async createWorkspaceDeprecated(createWorkspace: CreateWorkspace, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Workspace>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.createWorkspaceDeprecated(createWorkspace, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.createWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Delete workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {boolean} force \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async deleteWorkspaceDeprecated(workspaceId: string, force: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.deleteWorkspaceDeprecated(workspaceId, force, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.deleteWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get build logs\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getBuildLogsWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getBuildLogsWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, follow, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.getBuildLogsWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get preview URL for a workspace port\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} port Port number to get preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getPortPreviewUrlWorkspaceDeprecated(workspaceId: string, port: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<WorkspacePortPreviewUrl>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getPortPreviewUrlWorkspaceDeprecated(workspaceId, port, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.getPortPreviewUrlWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get workspace details\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async getWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, verbose?: boolean, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Workspace>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.getWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, verbose, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.getWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] List all workspaces\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async listWorkspacesDeprecated(xDaytonaOrganizationID?: string, verbose?: boolean, labels?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Workspace>>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.listWorkspacesDeprecated(xDaytonaOrganizationID, verbose, labels, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.listWorkspacesDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Replace workspace labels\n         * @param {string} workspaceId ID of the workspace\n         * @param {SandboxLabels} sandboxLabels \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async replaceLabelsWorkspaceDeprecated(workspaceId: string, sandboxLabels: SandboxLabels, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<SandboxLabels>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.replaceLabelsWorkspaceDeprecated(workspaceId, sandboxLabels, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.replaceLabelsWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Set workspace auto-archive interval\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async setAutoArchiveIntervalWorkspaceDeprecated(workspaceId: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setAutoArchiveIntervalWorkspaceDeprecated(workspaceId, interval, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.setAutoArchiveIntervalWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Set workspace auto-stop interval\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} interval Auto-stop interval in minutes (0 to disable)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async setAutostopIntervalWorkspaceDeprecated(workspaceId: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.setAutostopIntervalWorkspaceDeprecated(workspaceId, interval, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.setAutostopIntervalWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Start workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async startWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.startWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.startWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Stop workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async stopWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.stopWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.stopWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Update public status\n         * @param {string} workspaceId ID of the workspace\n         * @param {boolean} isPublic Public status to set\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        async updatePublicStatusWorkspaceDeprecated(workspaceId: string, isPublic: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {\n            const localVarAxiosArgs = await localVarAxiosParamCreator.updatePublicStatusWorkspaceDeprecated(workspaceId, isPublic, xDaytonaOrganizationID, options);\n            const localVarOperationServerIndex = configuration?.serverIndex ?? 0;\n            const localVarOperationServerBasePath = operationServerMap['WorkspaceApi.updatePublicStatusWorkspaceDeprecated']?.[localVarOperationServerIndex]?.url;\n            return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);\n        },\n    }\n};\n\n/**\n * WorkspaceApi - factory interface\n * @export\n */\nexport const WorkspaceApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) {\n    const localVarFp = WorkspaceApiFp(configuration)\n    return {\n        /**\n         * \n         * @summary [DEPRECATED] Archive workspace\n         * @param {string} workspaceId \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        archiveWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.archiveWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Create workspace backup\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createBackupWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Workspace> {\n            return localVarFp.createBackupWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Create a new workspace\n         * @param {CreateWorkspace} createWorkspace \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        createWorkspaceDeprecated(createWorkspace: CreateWorkspace, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<Workspace> {\n            return localVarFp.createWorkspaceDeprecated(createWorkspace, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Delete workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {boolean} force \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        deleteWorkspaceDeprecated(workspaceId: string, force: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.deleteWorkspaceDeprecated(workspaceId, force, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get build logs\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [follow] Whether to follow the logs stream\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getBuildLogsWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.getBuildLogsWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, follow, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get preview URL for a workspace port\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} port Port number to get preview URL for\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getPortPreviewUrlWorkspaceDeprecated(workspaceId: string, port: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<WorkspacePortPreviewUrl> {\n            return localVarFp.getPortPreviewUrlWorkspaceDeprecated(workspaceId, port, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Get workspace details\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        getWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, verbose?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<Workspace> {\n            return localVarFp.getWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, verbose, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] List all workspaces\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {boolean} [verbose] Include verbose output\n         * @param {string} [labels] JSON encoded labels to filter by\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        listWorkspacesDeprecated(xDaytonaOrganizationID?: string, verbose?: boolean, labels?: string, options?: RawAxiosRequestConfig): AxiosPromise<Array<Workspace>> {\n            return localVarFp.listWorkspacesDeprecated(xDaytonaOrganizationID, verbose, labels, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Replace workspace labels\n         * @param {string} workspaceId ID of the workspace\n         * @param {SandboxLabels} sandboxLabels \n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        replaceLabelsWorkspaceDeprecated(workspaceId: string, sandboxLabels: SandboxLabels, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<SandboxLabels> {\n            return localVarFp.replaceLabelsWorkspaceDeprecated(workspaceId, sandboxLabels, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Set workspace auto-archive interval\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        setAutoArchiveIntervalWorkspaceDeprecated(workspaceId: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.setAutoArchiveIntervalWorkspaceDeprecated(workspaceId, interval, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Set workspace auto-stop interval\n         * @param {string} workspaceId ID of the workspace\n         * @param {number} interval Auto-stop interval in minutes (0 to disable)\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        setAutostopIntervalWorkspaceDeprecated(workspaceId: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.setAutostopIntervalWorkspaceDeprecated(workspaceId, interval, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Start workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        startWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.startWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Stop workspace\n         * @param {string} workspaceId ID of the workspace\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        stopWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.stopWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n        /**\n         * \n         * @summary [DEPRECATED] Update public status\n         * @param {string} workspaceId ID of the workspace\n         * @param {boolean} isPublic Public status to set\n         * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n         * @param {*} [options] Override http request option.\n         * @deprecated\n         * @throws {RequiredError}\n         */\n        updatePublicStatusWorkspaceDeprecated(workspaceId: string, isPublic: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig): AxiosPromise<void> {\n            return localVarFp.updatePublicStatusWorkspaceDeprecated(workspaceId, isPublic, xDaytonaOrganizationID, options).then((request) => request(axios, basePath));\n        },\n    };\n};\n\n/**\n * WorkspaceApi - object-oriented interface\n * @export\n * @class WorkspaceApi\n * @extends {BaseAPI}\n */\nexport class WorkspaceApi extends BaseAPI {\n    /**\n     * \n     * @summary [DEPRECATED] Archive workspace\n     * @param {string} workspaceId \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public archiveWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).archiveWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Create workspace backup\n     * @param {string} workspaceId ID of the workspace\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public createBackupWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).createBackupWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Create a new workspace\n     * @param {CreateWorkspace} createWorkspace \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public createWorkspaceDeprecated(createWorkspace: CreateWorkspace, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).createWorkspaceDeprecated(createWorkspace, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Delete workspace\n     * @param {string} workspaceId ID of the workspace\n     * @param {boolean} force \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public deleteWorkspaceDeprecated(workspaceId: string, force: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).deleteWorkspaceDeprecated(workspaceId, force, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Get build logs\n     * @param {string} workspaceId ID of the workspace\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [follow] Whether to follow the logs stream\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public getBuildLogsWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, follow?: boolean, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).getBuildLogsWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, follow, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Get preview URL for a workspace port\n     * @param {string} workspaceId ID of the workspace\n     * @param {number} port Port number to get preview URL for\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public getPortPreviewUrlWorkspaceDeprecated(workspaceId: string, port: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).getPortPreviewUrlWorkspaceDeprecated(workspaceId, port, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Get workspace details\n     * @param {string} workspaceId ID of the workspace\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [verbose] Include verbose output\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public getWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, verbose?: boolean, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).getWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, verbose, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] List all workspaces\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {boolean} [verbose] Include verbose output\n     * @param {string} [labels] JSON encoded labels to filter by\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public listWorkspacesDeprecated(xDaytonaOrganizationID?: string, verbose?: boolean, labels?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).listWorkspacesDeprecated(xDaytonaOrganizationID, verbose, labels, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Replace workspace labels\n     * @param {string} workspaceId ID of the workspace\n     * @param {SandboxLabels} sandboxLabels \n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public replaceLabelsWorkspaceDeprecated(workspaceId: string, sandboxLabels: SandboxLabels, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).replaceLabelsWorkspaceDeprecated(workspaceId, sandboxLabels, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Set workspace auto-archive interval\n     * @param {string} workspaceId ID of the workspace\n     * @param {number} interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public setAutoArchiveIntervalWorkspaceDeprecated(workspaceId: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).setAutoArchiveIntervalWorkspaceDeprecated(workspaceId, interval, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Set workspace auto-stop interval\n     * @param {string} workspaceId ID of the workspace\n     * @param {number} interval Auto-stop interval in minutes (0 to disable)\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public setAutostopIntervalWorkspaceDeprecated(workspaceId: string, interval: number, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).setAutostopIntervalWorkspaceDeprecated(workspaceId, interval, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Start workspace\n     * @param {string} workspaceId ID of the workspace\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public startWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).startWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Stop workspace\n     * @param {string} workspaceId ID of the workspace\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public stopWorkspaceDeprecated(workspaceId: string, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).stopWorkspaceDeprecated(workspaceId, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n\n    /**\n     * \n     * @summary [DEPRECATED] Update public status\n     * @param {string} workspaceId ID of the workspace\n     * @param {boolean} isPublic Public status to set\n     * @param {string} [xDaytonaOrganizationID] Use with JWT to specify the organization ID\n     * @param {*} [options] Override http request option.\n     * @deprecated\n     * @throws {RequiredError}\n     * @memberof WorkspaceApi\n     */\n    public updatePublicStatusWorkspaceDeprecated(workspaceId: string, isPublic: boolean, xDaytonaOrganizationID?: string, options?: RawAxiosRequestConfig) {\n        return WorkspaceApiFp(this.configuration).updatePublicStatusWorkspaceDeprecated(workspaceId, isPublic, xDaytonaOrganizationID, options).then((request) => request(this.axios, this.basePath));\n    }\n}\n\n"
  },
  {
    "path": "libs/api-client/src/api.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\nexport * from './api/admin-api';\nexport * from './api/api-keys-api';\nexport * from './api/audit-api';\nexport * from './api/config-api';\nexport * from './api/docker-registry-api';\nexport * from './api/health-api';\nexport * from './api/jobs-api';\nexport * from './api/object-storage-api';\nexport * from './api/organizations-api';\nexport * from './api/preview-api';\nexport * from './api/regions-api';\nexport * from './api/runners-api';\nexport * from './api/sandbox-api';\nexport * from './api/snapshots-api';\nexport * from './api/toolbox-api';\nexport * from './api/users-api';\nexport * from './api/volumes-api';\nexport * from './api/webhooks-api';\nexport * from './api/workspace-api';\n\n"
  },
  {
    "path": "libs/api-client/src/base.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from './configuration';\n// Some imports not used depending on template conditions\n// @ts-ignore\nimport type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios';\nimport globalAxios from 'axios';\n\nexport const BASE_PATH = \"http://localhost:3000\".replace(/\\/+$/, \"\");\n\n/**\n *\n * @export\n */\nexport const COLLECTION_FORMATS = {\n    csv: \",\",\n    ssv: \" \",\n    tsv: \"\\t\",\n    pipes: \"|\",\n};\n\n/**\n *\n * @export\n * @interface RequestArgs\n */\nexport interface RequestArgs {\n    url: string;\n    options: RawAxiosRequestConfig;\n}\n\n/**\n *\n * @export\n * @class BaseAPI\n */\nexport class BaseAPI {\n    protected configuration: Configuration | undefined;\n\n    constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {\n        if (configuration) {\n            this.configuration = configuration;\n            this.basePath = configuration.basePath ?? basePath;\n        }\n    }\n};\n\n/**\n *\n * @export\n * @class RequiredError\n * @extends {Error}\n */\nexport class RequiredError extends Error {\n    constructor(public field: string, msg?: string) {\n        super(msg);\n        this.name = \"RequiredError\"\n    }\n}\n\ninterface ServerMap {\n    [key: string]: {\n        url: string,\n        description: string,\n    }[];\n}\n\n/**\n *\n * @export\n */\nexport const operationServerMap: ServerMap = {\n}\n"
  },
  {
    "path": "libs/api-client/src/common.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nimport type { Configuration } from \"./configuration\";\nimport type { RequestArgs } from \"./base\";\nimport type { AxiosInstance, AxiosResponse } from 'axios';\nimport { RequiredError } from \"./base\";\n\n/**\n *\n * @export\n */\nexport const DUMMY_BASE_URL = 'https://example.com'\n\n/**\n *\n * @throws {RequiredError}\n * @export\n */\nexport const assertParamExists = function (functionName: string, paramName: string, paramValue: unknown) {\n    if (paramValue === null || paramValue === undefined) {\n        throw new RequiredError(paramName, `Required parameter ${paramName} was null or undefined when calling ${functionName}.`);\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) {\n    if (configuration && configuration.apiKey) {\n        const localVarApiKeyValue = typeof configuration.apiKey === 'function'\n            ? await configuration.apiKey(keyParamName)\n            : await configuration.apiKey;\n        object[keyParamName] = localVarApiKeyValue;\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setBasicAuthToObject = function (object: any, configuration?: Configuration) {\n    if (configuration && (configuration.username || configuration.password)) {\n        object[\"auth\"] = { username: configuration.username, password: configuration.password };\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setBearerAuthToObject = async function (object: any, configuration?: Configuration) {\n    if (configuration && configuration.accessToken) {\n        const accessToken = typeof configuration.accessToken === 'function'\n            ? await configuration.accessToken()\n            : await configuration.accessToken;\n        object[\"Authorization\"] = \"Bearer \" + accessToken;\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) {\n    if (configuration && configuration.accessToken) {\n        const localVarAccessTokenValue = typeof configuration.accessToken === 'function'\n            ? await configuration.accessToken(name, scopes)\n            : await configuration.accessToken;\n        object[\"Authorization\"] = \"Bearer \" + localVarAccessTokenValue;\n    }\n}\n\nfunction setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = \"\"): void {\n    if (parameter == null) return;\n    if (typeof parameter === \"object\") {\n        if (Array.isArray(parameter)) {\n            (parameter as any[]).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key));\n        } \n        else {\n            Object.keys(parameter).forEach(currentKey => \n                setFlattenedQueryParams(urlSearchParams, parameter[currentKey], `${key}${key !== '' ? '.' : ''}${currentKey}`)\n            );\n        }\n    } \n    else {\n        if (urlSearchParams.has(key)) {\n            urlSearchParams.append(key, parameter);\n        } \n        else {\n            urlSearchParams.set(key, parameter);\n        }\n    }\n}\n\n/**\n *\n * @export\n */\nexport const setSearchParams = function (url: URL, ...objects: any[]) {\n    const searchParams = new URLSearchParams(url.search);\n    setFlattenedQueryParams(searchParams, objects);\n    url.search = searchParams.toString();\n}\n\n/**\n *\n * @export\n */\nexport const serializeDataIfNeeded = function (value: any, requestOptions: any, configuration?: Configuration) {\n    const nonString = typeof value !== 'string';\n    const needsSerialization = nonString && configuration && configuration.isJsonMime\n        ? configuration.isJsonMime(requestOptions.headers['Content-Type'])\n        : nonString;\n    return needsSerialization\n        ? JSON.stringify(value !== undefined ? value : {})\n        : (value || \"\");\n}\n\n/**\n *\n * @export\n */\nexport const toPathString = function (url: URL) {\n    return url.pathname + url.search + url.hash\n}\n\n/**\n *\n * @export\n */\nexport const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) {\n    return <T = unknown, R = AxiosResponse<T>>(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {\n        const axiosRequestArgs = {...axiosArgs.options, url: (axios.defaults.baseURL ? '' : configuration?.basePath ?? basePath) + axiosArgs.url};\n        return axios.request<T, R>(axiosRequestArgs);\n    };\n}\n"
  },
  {
    "path": "libs/api-client/src/configuration.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nexport interface ConfigurationParameters {\n    apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);\n    username?: string;\n    password?: string;\n    accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);\n    basePath?: string;\n    serverIndex?: number;\n    baseOptions?: any;\n    formDataCtor?: new () => any;\n}\n\nexport class Configuration {\n    /**\n     * parameter for apiKey security\n     * @param name security name\n     * @memberof Configuration\n     */\n    apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);\n    /**\n     * parameter for basic security\n     *\n     * @type {string}\n     * @memberof Configuration\n     */\n    username?: string;\n    /**\n     * parameter for basic security\n     *\n     * @type {string}\n     * @memberof Configuration\n     */\n    password?: string;\n    /**\n     * parameter for oauth2 security\n     * @param name security name\n     * @param scopes oauth2 scope\n     * @memberof Configuration\n     */\n    accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);\n    /**\n     * override base path\n     *\n     * @type {string}\n     * @memberof Configuration\n     */\n    basePath?: string;\n    /**\n     * override server index\n     *\n     * @type {number}\n     * @memberof Configuration\n     */\n    serverIndex?: number;\n    /**\n     * base options for axios calls\n     *\n     * @type {any}\n     * @memberof Configuration\n     */\n    baseOptions?: any;\n    /**\n     * The FormData constructor that will be used to create multipart form data\n     * requests. You can inject this here so that execution environments that\n     * do not support the FormData class can still run the generated client.\n     *\n     * @type {new () => FormData}\n     */\n    formDataCtor?: new () => any;\n\n    constructor(param: ConfigurationParameters = {}) {\n        this.apiKey = param.apiKey;\n        this.username = param.username;\n        this.password = param.password;\n        this.accessToken = param.accessToken;\n        this.basePath = param.basePath;\n        this.serverIndex = param.serverIndex;\n        this.baseOptions = {\n            ...param.baseOptions,\n            headers: {\n                ...param.baseOptions?.headers,\n            },\n        };\n        this.formDataCtor = param.formDataCtor;\n    }\n\n    /**\n     * Check if the given MIME is a JSON MIME.\n     * JSON MIME examples:\n     *   application/json\n     *   application/json; charset=UTF8\n     *   APPLICATION/JSON\n     *   application/vnd.company+json\n     * @param mime - MIME (Multipurpose Internet Mail Extensions)\n     * @return True if the given MIME is JSON, false otherwise.\n     */\n    public isJsonMime(mime: string): boolean {\n        const jsonMime: RegExp = new RegExp('^(application\\/json|[^;/ \\t]+\\/[^;/ \\t]+[+]json)[ \\t]*(;.*)?$', 'i');\n        return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');\n    }\n}\n"
  },
  {
    "path": "libs/api-client/src/git_push.sh",
    "content": "#!/bin/sh\n# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/\n#\n# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl \"minor update\" \"gitlab.com\"\n\ngit_user_id=$1\ngit_repo_id=$2\nrelease_note=$3\ngit_host=$4\n\nif [ \"$git_host\" = \"\" ]; then\n    git_host=\"github.com\"\n    echo \"[INFO] No command line input provided. Set \\$git_host to $git_host\"\nfi\n\nif [ \"$git_user_id\" = \"\" ]; then\n    git_user_id=\"daytonaio\"\n    echo \"[INFO] No command line input provided. Set \\$git_user_id to $git_user_id\"\nfi\n\nif [ \"$git_repo_id\" = \"\" ]; then\n    git_repo_id=\"daytona\"\n    echo \"[INFO] No command line input provided. Set \\$git_repo_id to $git_repo_id\"\nfi\n\nif [ \"$release_note\" = \"\" ]; then\n    release_note=\"Minor update\"\n    echo \"[INFO] No command line input provided. Set \\$release_note to $release_note\"\nfi\n\n# Initialize the local directory as a Git repository\ngit init\n\n# Adds the files in the local repository and stages them for commit.\ngit add .\n\n# Commits the tracked changes and prepares them to be pushed to a remote repository.\ngit commit -m \"$release_note\"\n\n# Sets the new remote\ngit_remote=$(git remote)\nif [ \"$git_remote\" = \"\" ]; then # git remote not defined\n\n    if [ \"$GIT_TOKEN\" = \"\" ]; then\n        echo \"[INFO] \\$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment.\"\n        git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git\n    else\n        git remote add origin https://${git_user_id}:\"${GIT_TOKEN}\"@${git_host}/${git_user_id}/${git_repo_id}.git\n    fi\n\nfi\n\ngit pull origin master\n\n# Pushes (Forces) the changes in the local repository up to the remote repository\necho \"Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git\"\ngit push origin master 2>&1 | grep -v 'To https'\n"
  },
  {
    "path": "libs/api-client/src/index.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\nexport * from \"./api\";\nexport * from \"./configuration\";\nexport * from \"./models\";\n"
  },
  {
    "path": "libs/api-client/src/models/account-provider.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface AccountProvider\n */\nexport interface AccountProvider {\n    /**\n     * \n     * @type {string}\n     * @memberof AccountProvider\n     */\n    'name': string;\n    /**\n     * \n     * @type {string}\n     * @memberof AccountProvider\n     */\n    'displayName': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/admin-create-runner.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface AdminCreateRunner\n */\nexport interface AdminCreateRunner {\n    /**\n     * \n     * @type {string}\n     * @memberof AdminCreateRunner\n     */\n    'regionId': string;\n    /**\n     * \n     * @type {string}\n     * @memberof AdminCreateRunner\n     */\n    'name': string;\n    /**\n     * \n     * @type {string}\n     * @memberof AdminCreateRunner\n     */\n    'apiKey': string;\n    /**\n     * The api version of the runner to create\n     * @type {string}\n     * @memberof AdminCreateRunner\n     */\n    'apiVersion': string;\n    /**\n     * The domain of the runner\n     * @type {string}\n     * @memberof AdminCreateRunner\n     */\n    'domain'?: string;\n    /**\n     * The API URL of the runner\n     * @type {string}\n     * @memberof AdminCreateRunner\n     */\n    'apiUrl'?: string;\n    /**\n     * The proxy URL of the runner\n     * @type {string}\n     * @memberof AdminCreateRunner\n     */\n    'proxyUrl'?: string;\n    /**\n     * The CPU capacity of the runner\n     * @type {number}\n     * @memberof AdminCreateRunner\n     */\n    'cpu'?: number;\n    /**\n     * The memory capacity of the runner in GiB\n     * @type {number}\n     * @memberof AdminCreateRunner\n     */\n    'memoryGiB'?: number;\n    /**\n     * The disk capacity of the runner in GiB\n     * @type {number}\n     * @memberof AdminCreateRunner\n     */\n    'diskGiB'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/announcement.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface Announcement\n */\nexport interface Announcement {\n    /**\n     * The announcement text\n     * @type {string}\n     * @memberof Announcement\n     */\n    'text': string;\n    /**\n     * URL to learn more about the announcement\n     * @type {string}\n     * @memberof Announcement\n     */\n    'learnMoreUrl'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/api-key-list.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ApiKeyList\n */\nexport interface ApiKeyList {\n    /**\n     * The name of the API key\n     * @type {string}\n     * @memberof ApiKeyList\n     */\n    'name': string;\n    /**\n     * The masked API key value\n     * @type {string}\n     * @memberof ApiKeyList\n     */\n    'value': string;\n    /**\n     * When the API key was created\n     * @type {Date}\n     * @memberof ApiKeyList\n     */\n    'createdAt': Date;\n    /**\n     * The list of organization resource permissions assigned to the API key\n     * @type {Array<string>}\n     * @memberof ApiKeyList\n     */\n    'permissions': Array<ApiKeyListPermissionsEnum>;\n    /**\n     * When the API key was last used\n     * @type {Date}\n     * @memberof ApiKeyList\n     */\n    'lastUsedAt': Date | null;\n    /**\n     * When the API key expires\n     * @type {Date}\n     * @memberof ApiKeyList\n     */\n    'expiresAt': Date | null;\n    /**\n     * The user ID of the user who created the API key\n     * @type {string}\n     * @memberof ApiKeyList\n     */\n    'userId': string;\n}\n\nexport const ApiKeyListPermissionsEnum = {\n    WRITE_REGISTRIES: 'write:registries',\n    DELETE_REGISTRIES: 'delete:registries',\n    WRITE_SNAPSHOTS: 'write:snapshots',\n    DELETE_SNAPSHOTS: 'delete:snapshots',\n    WRITE_SANDBOXES: 'write:sandboxes',\n    DELETE_SANDBOXES: 'delete:sandboxes',\n    READ_VOLUMES: 'read:volumes',\n    WRITE_VOLUMES: 'write:volumes',\n    DELETE_VOLUMES: 'delete:volumes',\n    WRITE_REGIONS: 'write:regions',\n    DELETE_REGIONS: 'delete:regions',\n    READ_RUNNERS: 'read:runners',\n    WRITE_RUNNERS: 'write:runners',\n    DELETE_RUNNERS: 'delete:runners',\n    READ_AUDIT_LOGS: 'read:audit_logs'\n} as const;\n\nexport type ApiKeyListPermissionsEnum = typeof ApiKeyListPermissionsEnum[keyof typeof ApiKeyListPermissionsEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/api-key-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ApiKeyResponse\n */\nexport interface ApiKeyResponse {\n    /**\n     * The name of the API key\n     * @type {string}\n     * @memberof ApiKeyResponse\n     */\n    'name': string;\n    /**\n     * The API key value\n     * @type {string}\n     * @memberof ApiKeyResponse\n     */\n    'value': string;\n    /**\n     * When the API key was created\n     * @type {Date}\n     * @memberof ApiKeyResponse\n     */\n    'createdAt': Date;\n    /**\n     * The list of organization resource permissions assigned to the API key\n     * @type {Array<string>}\n     * @memberof ApiKeyResponse\n     */\n    'permissions': Array<ApiKeyResponsePermissionsEnum>;\n    /**\n     * When the API key expires\n     * @type {Date}\n     * @memberof ApiKeyResponse\n     */\n    'expiresAt': Date | null;\n}\n\nexport const ApiKeyResponsePermissionsEnum = {\n    WRITE_REGISTRIES: 'write:registries',\n    DELETE_REGISTRIES: 'delete:registries',\n    WRITE_SNAPSHOTS: 'write:snapshots',\n    DELETE_SNAPSHOTS: 'delete:snapshots',\n    WRITE_SANDBOXES: 'write:sandboxes',\n    DELETE_SANDBOXES: 'delete:sandboxes',\n    READ_VOLUMES: 'read:volumes',\n    WRITE_VOLUMES: 'write:volumes',\n    DELETE_VOLUMES: 'delete:volumes',\n    WRITE_REGIONS: 'write:regions',\n    DELETE_REGIONS: 'delete:regions',\n    READ_RUNNERS: 'read:runners',\n    WRITE_RUNNERS: 'write:runners',\n    DELETE_RUNNERS: 'delete:runners',\n    READ_AUDIT_LOGS: 'read:audit_logs'\n} as const;\n\nexport type ApiKeyResponsePermissionsEnum = typeof ApiKeyResponsePermissionsEnum[keyof typeof ApiKeyResponsePermissionsEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/audit-log.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface AuditLog\n */\nexport interface AuditLog {\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'id': string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'actorId': string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'actorEmail': string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'organizationId'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'action': string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'targetType'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'targetId'?: string;\n    /**\n     * \n     * @type {number}\n     * @memberof AuditLog\n     */\n    'statusCode'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'errorMessage'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'ipAddress'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'userAgent'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof AuditLog\n     */\n    'source'?: string;\n    /**\n     * \n     * @type {{ [key: string]: any; }}\n     * @memberof AuditLog\n     */\n    'metadata'?: { [key: string]: any; };\n    /**\n     * \n     * @type {Date}\n     * @memberof AuditLog\n     */\n    'createdAt': Date;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/build-info.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface BuildInfo\n */\nexport interface BuildInfo {\n    /**\n     * The Dockerfile content used for the build\n     * @type {string}\n     * @memberof BuildInfo\n     */\n    'dockerfileContent'?: string;\n    /**\n     * The context hashes used for the build\n     * @type {Array<string>}\n     * @memberof BuildInfo\n     */\n    'contextHashes'?: Array<string>;\n    /**\n     * The creation timestamp\n     * @type {Date}\n     * @memberof BuildInfo\n     */\n    'createdAt': Date;\n    /**\n     * The last update timestamp\n     * @type {Date}\n     * @memberof BuildInfo\n     */\n    'updatedAt': Date;\n    /**\n     * The snapshot reference\n     * @type {string}\n     * @memberof BuildInfo\n     */\n    'snapshotRef': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/command.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface Command\n */\nexport interface Command {\n    /**\n     * The ID of the command\n     * @type {string}\n     * @memberof Command\n     */\n    'id': string;\n    /**\n     * The command that was executed\n     * @type {string}\n     * @memberof Command\n     */\n    'command': string;\n    /**\n     * The exit code of the command\n     * @type {number}\n     * @memberof Command\n     */\n    'exitCode'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/completion-context.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CompletionContext\n */\nexport interface CompletionContext {\n    /**\n     * \n     * @type {number}\n     * @memberof CompletionContext\n     */\n    'triggerKind': number;\n    /**\n     * \n     * @type {string}\n     * @memberof CompletionContext\n     */\n    'triggerCharacter'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/completion-item.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CompletionItem\n */\nexport interface CompletionItem {\n    /**\n     * \n     * @type {string}\n     * @memberof CompletionItem\n     */\n    'label': string;\n    /**\n     * \n     * @type {number}\n     * @memberof CompletionItem\n     */\n    'kind'?: number;\n    /**\n     * \n     * @type {string}\n     * @memberof CompletionItem\n     */\n    'detail'?: string;\n    /**\n     * \n     * @type {object}\n     * @memberof CompletionItem\n     */\n    'documentation'?: object;\n    /**\n     * \n     * @type {string}\n     * @memberof CompletionItem\n     */\n    'sortText'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof CompletionItem\n     */\n    'filterText'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof CompletionItem\n     */\n    'insertText'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/completion-list.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { CompletionItem } from './completion-item';\n\n/**\n * \n * @export\n * @interface CompletionList\n */\nexport interface CompletionList {\n    /**\n     * \n     * @type {boolean}\n     * @memberof CompletionList\n     */\n    'isIncomplete': boolean;\n    /**\n     * \n     * @type {Array<CompletionItem>}\n     * @memberof CompletionList\n     */\n    'items': Array<CompletionItem>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/compressed-screenshot-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CompressedScreenshotResponse\n */\nexport interface CompressedScreenshotResponse {\n    /**\n     * Base64 encoded compressed screenshot image data\n     * @type {string}\n     * @memberof CompressedScreenshotResponse\n     */\n    'screenshot': string;\n    /**\n     * The current cursor position when the compressed screenshot was taken\n     * @type {object}\n     * @memberof CompressedScreenshotResponse\n     */\n    'cursorPosition'?: object;\n    /**\n     * The size of the compressed screenshot data in bytes\n     * @type {number}\n     * @memberof CompressedScreenshotResponse\n     */\n    'sizeBytes'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/computer-use-start-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ComputerUseStartResponse\n */\nexport interface ComputerUseStartResponse {\n    /**\n     * A message indicating the result of starting computer use processes\n     * @type {string}\n     * @memberof ComputerUseStartResponse\n     */\n    'message': string;\n    /**\n     * Status information about all VNC desktop processes after starting\n     * @type {object}\n     * @memberof ComputerUseStartResponse\n     */\n    'status': object;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/computer-use-status-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ComputerUseStatusResponse\n */\nexport interface ComputerUseStatusResponse {\n    /**\n     * Status of computer use services (active, partial, inactive, error)\n     * @type {string}\n     * @memberof ComputerUseStatusResponse\n     */\n    'status': ComputerUseStatusResponseStatusEnum;\n}\n\nexport const ComputerUseStatusResponseStatusEnum = {\n    ACTIVE: 'active',\n    PARTIAL: 'partial',\n    INACTIVE: 'inactive',\n    ERROR: 'error'\n} as const;\n\nexport type ComputerUseStatusResponseStatusEnum = typeof ComputerUseStatusResponseStatusEnum[keyof typeof ComputerUseStatusResponseStatusEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/computer-use-stop-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ComputerUseStopResponse\n */\nexport interface ComputerUseStopResponse {\n    /**\n     * A message indicating the result of stopping computer use processes\n     * @type {string}\n     * @memberof ComputerUseStopResponse\n     */\n    'message': string;\n    /**\n     * Status information about all VNC desktop processes after stopping\n     * @type {object}\n     * @memberof ComputerUseStopResponse\n     */\n    'status': object;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-api-key.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateApiKey\n */\nexport interface CreateApiKey {\n    /**\n     * The name of the API key\n     * @type {string}\n     * @memberof CreateApiKey\n     */\n    'name': string;\n    /**\n     * The list of organization resource permissions explicitly assigned to the API key\n     * @type {Array<string>}\n     * @memberof CreateApiKey\n     */\n    'permissions': Array<CreateApiKeyPermissionsEnum>;\n    /**\n     * When the API key expires\n     * @type {Date}\n     * @memberof CreateApiKey\n     */\n    'expiresAt'?: Date | null;\n}\n\nexport const CreateApiKeyPermissionsEnum = {\n    WRITE_REGISTRIES: 'write:registries',\n    DELETE_REGISTRIES: 'delete:registries',\n    WRITE_SNAPSHOTS: 'write:snapshots',\n    DELETE_SNAPSHOTS: 'delete:snapshots',\n    WRITE_SANDBOXES: 'write:sandboxes',\n    DELETE_SANDBOXES: 'delete:sandboxes',\n    READ_VOLUMES: 'read:volumes',\n    WRITE_VOLUMES: 'write:volumes',\n    DELETE_VOLUMES: 'delete:volumes',\n    WRITE_REGIONS: 'write:regions',\n    DELETE_REGIONS: 'delete:regions',\n    READ_RUNNERS: 'read:runners',\n    WRITE_RUNNERS: 'write:runners',\n    DELETE_RUNNERS: 'delete:runners',\n    READ_AUDIT_LOGS: 'read:audit_logs'\n} as const;\n\nexport type CreateApiKeyPermissionsEnum = typeof CreateApiKeyPermissionsEnum[keyof typeof CreateApiKeyPermissionsEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-build-info.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateBuildInfo\n */\nexport interface CreateBuildInfo {\n    /**\n     * The Dockerfile content used for the build\n     * @type {string}\n     * @memberof CreateBuildInfo\n     */\n    'dockerfileContent': string;\n    /**\n     * The context hashes used for the build\n     * @type {Array<string>}\n     * @memberof CreateBuildInfo\n     */\n    'contextHashes'?: Array<string>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-docker-registry.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateDockerRegistry\n */\nexport interface CreateDockerRegistry {\n    /**\n     * Registry name\n     * @type {string}\n     * @memberof CreateDockerRegistry\n     */\n    'name': string;\n    /**\n     * Registry URL\n     * @type {string}\n     * @memberof CreateDockerRegistry\n     */\n    'url': string;\n    /**\n     * Registry username\n     * @type {string}\n     * @memberof CreateDockerRegistry\n     */\n    'username': string;\n    /**\n     * Registry password\n     * @type {string}\n     * @memberof CreateDockerRegistry\n     */\n    'password': string;\n    /**\n     * Registry project\n     * @type {string}\n     * @memberof CreateDockerRegistry\n     */\n    'project'?: string;\n    /**\n     * Registry type\n     * @type {string}\n     * @memberof CreateDockerRegistry\n     */\n    'registryType': CreateDockerRegistryRegistryTypeEnum;\n    /**\n     * Set as default registry\n     * @type {boolean}\n     * @memberof CreateDockerRegistry\n     */\n    'isDefault'?: boolean;\n}\n\nexport const CreateDockerRegistryRegistryTypeEnum = {\n    INTERNAL: 'internal',\n    ORGANIZATION: 'organization',\n    TRANSIENT: 'transient',\n    BACKUP: 'backup'\n} as const;\n\nexport type CreateDockerRegistryRegistryTypeEnum = typeof CreateDockerRegistryRegistryTypeEnum[keyof typeof CreateDockerRegistryRegistryTypeEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-linked-account.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateLinkedAccount\n */\nexport interface CreateLinkedAccount {\n    /**\n     * The authentication provider of the secondary account\n     * @type {string}\n     * @memberof CreateLinkedAccount\n     */\n    'provider': string;\n    /**\n     * The user ID of the secondary account\n     * @type {string}\n     * @memberof CreateLinkedAccount\n     */\n    'userId': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-organization-invitation.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateOrganizationInvitation\n */\nexport interface CreateOrganizationInvitation {\n    /**\n     * Email address of the invitee\n     * @type {string}\n     * @memberof CreateOrganizationInvitation\n     */\n    'email': string;\n    /**\n     * Organization member role for the invitee\n     * @type {string}\n     * @memberof CreateOrganizationInvitation\n     */\n    'role': CreateOrganizationInvitationRoleEnum;\n    /**\n     * Array of assigned role IDs for the invitee\n     * @type {Array<string>}\n     * @memberof CreateOrganizationInvitation\n     */\n    'assignedRoleIds': Array<string>;\n    /**\n     * Expiration date of the invitation\n     * @type {Date}\n     * @memberof CreateOrganizationInvitation\n     */\n    'expiresAt'?: Date;\n}\n\nexport const CreateOrganizationInvitationRoleEnum = {\n    OWNER: 'owner',\n    MEMBER: 'member'\n} as const;\n\nexport type CreateOrganizationInvitationRoleEnum = typeof CreateOrganizationInvitationRoleEnum[keyof typeof CreateOrganizationInvitationRoleEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-organization-quota.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateOrganizationQuota\n */\nexport interface CreateOrganizationQuota {\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'totalCpuQuota'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'totalMemoryQuota'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'totalDiskQuota'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'maxCpuPerSandbox'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'maxMemoryPerSandbox'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'maxDiskPerSandbox'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'snapshotQuota'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'maxSnapshotSize'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof CreateOrganizationQuota\n     */\n    'volumeQuota'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-organization-role.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateOrganizationRole\n */\nexport interface CreateOrganizationRole {\n    /**\n     * The name of the role\n     * @type {string}\n     * @memberof CreateOrganizationRole\n     */\n    'name': string;\n    /**\n     * The description of the role\n     * @type {string}\n     * @memberof CreateOrganizationRole\n     */\n    'description': string;\n    /**\n     * The list of permissions assigned to the role\n     * @type {Array<string>}\n     * @memberof CreateOrganizationRole\n     */\n    'permissions': Array<CreateOrganizationRolePermissionsEnum>;\n}\n\nexport const CreateOrganizationRolePermissionsEnum = {\n    WRITE_REGISTRIES: 'write:registries',\n    DELETE_REGISTRIES: 'delete:registries',\n    WRITE_SNAPSHOTS: 'write:snapshots',\n    DELETE_SNAPSHOTS: 'delete:snapshots',\n    WRITE_SANDBOXES: 'write:sandboxes',\n    DELETE_SANDBOXES: 'delete:sandboxes',\n    READ_VOLUMES: 'read:volumes',\n    WRITE_VOLUMES: 'write:volumes',\n    DELETE_VOLUMES: 'delete:volumes',\n    WRITE_REGIONS: 'write:regions',\n    DELETE_REGIONS: 'delete:regions',\n    READ_RUNNERS: 'read:runners',\n    WRITE_RUNNERS: 'write:runners',\n    DELETE_RUNNERS: 'delete:runners',\n    READ_AUDIT_LOGS: 'read:audit_logs'\n} as const;\n\nexport type CreateOrganizationRolePermissionsEnum = typeof CreateOrganizationRolePermissionsEnum[keyof typeof CreateOrganizationRolePermissionsEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-organization.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateOrganization\n */\nexport interface CreateOrganization {\n    /**\n     * The name of organization\n     * @type {string}\n     * @memberof CreateOrganization\n     */\n    'name': string;\n    /**\n     * The ID of the default region for the organization\n     * @type {string}\n     * @memberof CreateOrganization\n     */\n    'defaultRegionId': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-region-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateRegionResponse\n */\nexport interface CreateRegionResponse {\n    /**\n     * ID of the created region\n     * @type {string}\n     * @memberof CreateRegionResponse\n     */\n    'id': string;\n    /**\n     * Proxy API key for the region\n     * @type {string}\n     * @memberof CreateRegionResponse\n     */\n    'proxyApiKey'?: string | null;\n    /**\n     * SSH Gateway API key for the region\n     * @type {string}\n     * @memberof CreateRegionResponse\n     */\n    'sshGatewayApiKey'?: string | null;\n    /**\n     * Snapshot Manager username for the region\n     * @type {string}\n     * @memberof CreateRegionResponse\n     */\n    'snapshotManagerUsername'?: string | null;\n    /**\n     * Snapshot Manager password for the region\n     * @type {string}\n     * @memberof CreateRegionResponse\n     */\n    'snapshotManagerPassword'?: string | null;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-region.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateRegion\n */\nexport interface CreateRegion {\n    /**\n     * Region name\n     * @type {string}\n     * @memberof CreateRegion\n     */\n    'name': string;\n    /**\n     * Proxy URL for the region\n     * @type {string}\n     * @memberof CreateRegion\n     */\n    'proxyUrl'?: string | null;\n    /**\n     * SSH Gateway URL for the region\n     * @type {string}\n     * @memberof CreateRegion\n     */\n    'sshGatewayUrl'?: string | null;\n    /**\n     * Snapshot Manager URL for the region\n     * @type {string}\n     * @memberof CreateRegion\n     */\n    'snapshotManagerUrl'?: string | null;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-runner-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateRunnerResponse\n */\nexport interface CreateRunnerResponse {\n    /**\n     * The ID of the runner\n     * @type {string}\n     * @memberof CreateRunnerResponse\n     */\n    'id': string;\n    /**\n     * The API key for the runner\n     * @type {string}\n     * @memberof CreateRunnerResponse\n     */\n    'apiKey': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-runner.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateRunner\n */\nexport interface CreateRunner {\n    /**\n     * \n     * @type {string}\n     * @memberof CreateRunner\n     */\n    'regionId': string;\n    /**\n     * \n     * @type {string}\n     * @memberof CreateRunner\n     */\n    'name': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-sandbox.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { CreateBuildInfo } from './create-build-info';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxVolume } from './sandbox-volume';\n\n/**\n * \n * @export\n * @interface CreateSandbox\n */\nexport interface CreateSandbox {\n    /**\n     * The name of the sandbox. If not provided, the sandbox ID will be used as the name\n     * @type {string}\n     * @memberof CreateSandbox\n     */\n    'name'?: string;\n    /**\n     * The ID or name of the snapshot used for the sandbox\n     * @type {string}\n     * @memberof CreateSandbox\n     */\n    'snapshot'?: string;\n    /**\n     * The user associated with the project\n     * @type {string}\n     * @memberof CreateSandbox\n     */\n    'user'?: string;\n    /**\n     * Environment variables for the sandbox\n     * @type {{ [key: string]: string; }}\n     * @memberof CreateSandbox\n     */\n    'env'?: { [key: string]: string; };\n    /**\n     * Labels for the sandbox\n     * @type {{ [key: string]: string; }}\n     * @memberof CreateSandbox\n     */\n    'labels'?: { [key: string]: string; };\n    /**\n     * Whether the sandbox http preview is publicly accessible\n     * @type {boolean}\n     * @memberof CreateSandbox\n     */\n    'public'?: boolean;\n    /**\n     * Whether to block all network access for the sandbox\n     * @type {boolean}\n     * @memberof CreateSandbox\n     */\n    'networkBlockAll'?: boolean;\n    /**\n     * Comma-separated list of allowed CIDR network addresses for the sandbox\n     * @type {string}\n     * @memberof CreateSandbox\n     */\n    'networkAllowList'?: string;\n    /**\n     * The sandbox class type\n     * @type {string}\n     * @memberof CreateSandbox\n     */\n    'class'?: CreateSandboxClassEnum;\n    /**\n     * The target (region) where the sandbox will be created\n     * @type {string}\n     * @memberof CreateSandbox\n     */\n    'target'?: string;\n    /**\n     * CPU cores allocated to the sandbox\n     * @type {number}\n     * @memberof CreateSandbox\n     */\n    'cpu'?: number;\n    /**\n     * GPU units allocated to the sandbox\n     * @type {number}\n     * @memberof CreateSandbox\n     */\n    'gpu'?: number;\n    /**\n     * Memory allocated to the sandbox in GB\n     * @type {number}\n     * @memberof CreateSandbox\n     */\n    'memory'?: number;\n    /**\n     * Disk space allocated to the sandbox in GB\n     * @type {number}\n     * @memberof CreateSandbox\n     */\n    'disk'?: number;\n    /**\n     * Auto-stop interval in minutes (0 means disabled)\n     * @type {number}\n     * @memberof CreateSandbox\n     */\n    'autoStopInterval'?: number;\n    /**\n     * Auto-archive interval in minutes (0 means the maximum interval will be used)\n     * @type {number}\n     * @memberof CreateSandbox\n     */\n    'autoArchiveInterval'?: number;\n    /**\n     * Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n     * @type {number}\n     * @memberof CreateSandbox\n     */\n    'autoDeleteInterval'?: number;\n    /**\n     * Array of volumes to attach to the sandbox\n     * @type {Array<SandboxVolume>}\n     * @memberof CreateSandbox\n     */\n    'volumes'?: Array<SandboxVolume>;\n    /**\n     * Build information for the sandbox\n     * @type {CreateBuildInfo}\n     * @memberof CreateSandbox\n     */\n    'buildInfo'?: CreateBuildInfo;\n}\n\nexport const CreateSandboxClassEnum = {\n    SMALL: 'small',\n    MEDIUM: 'medium',\n    LARGE: 'large'\n} as const;\n\nexport type CreateSandboxClassEnum = typeof CreateSandboxClassEnum[keyof typeof CreateSandboxClassEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-session-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateSessionRequest\n */\nexport interface CreateSessionRequest {\n    /**\n     * The ID of the session\n     * @type {string}\n     * @memberof CreateSessionRequest\n     */\n    'sessionId': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-snapshot.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { CreateBuildInfo } from './create-build-info';\n\n/**\n * \n * @export\n * @interface CreateSnapshot\n */\nexport interface CreateSnapshot {\n    /**\n     * The name of the snapshot\n     * @type {string}\n     * @memberof CreateSnapshot\n     */\n    'name': string;\n    /**\n     * The image name of the snapshot\n     * @type {string}\n     * @memberof CreateSnapshot\n     */\n    'imageName'?: string;\n    /**\n     * The entrypoint command for the snapshot\n     * @type {Array<string>}\n     * @memberof CreateSnapshot\n     */\n    'entrypoint'?: Array<string>;\n    /**\n     * Whether the snapshot is general\n     * @type {boolean}\n     * @memberof CreateSnapshot\n     */\n    'general'?: boolean;\n    /**\n     * CPU cores allocated to the resulting sandbox\n     * @type {number}\n     * @memberof CreateSnapshot\n     */\n    'cpu'?: number;\n    /**\n     * GPU units allocated to the resulting sandbox\n     * @type {number}\n     * @memberof CreateSnapshot\n     */\n    'gpu'?: number;\n    /**\n     * Memory allocated to the resulting sandbox in GB\n     * @type {number}\n     * @memberof CreateSnapshot\n     */\n    'memory'?: number;\n    /**\n     * Disk space allocated to the sandbox in GB\n     * @type {number}\n     * @memberof CreateSnapshot\n     */\n    'disk'?: number;\n    /**\n     * Build information for the snapshot\n     * @type {CreateBuildInfo}\n     * @memberof CreateSnapshot\n     */\n    'buildInfo'?: CreateBuildInfo;\n    /**\n     * ID of the region where the snapshot will be available. Defaults to organization default region if not specified.\n     * @type {string}\n     * @memberof CreateSnapshot\n     */\n    'regionId'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-user.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { CreateOrganizationQuota } from './create-organization-quota';\n\n/**\n * \n * @export\n * @interface CreateUser\n */\nexport interface CreateUser {\n    /**\n     * \n     * @type {string}\n     * @memberof CreateUser\n     */\n    'id': string;\n    /**\n     * \n     * @type {string}\n     * @memberof CreateUser\n     */\n    'name': string;\n    /**\n     * \n     * @type {string}\n     * @memberof CreateUser\n     */\n    'email'?: string;\n    /**\n     * \n     * @type {CreateOrganizationQuota}\n     * @memberof CreateUser\n     */\n    'personalOrganizationQuota'?: CreateOrganizationQuota;\n    /**\n     * \n     * @type {string}\n     * @memberof CreateUser\n     */\n    'personalOrganizationDefaultRegionId'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof CreateUser\n     */\n    'role'?: CreateUserRoleEnum;\n    /**\n     * \n     * @type {boolean}\n     * @memberof CreateUser\n     */\n    'emailVerified'?: boolean;\n}\n\nexport const CreateUserRoleEnum = {\n    ADMIN: 'admin',\n    USER: 'user'\n} as const;\n\nexport type CreateUserRoleEnum = typeof CreateUserRoleEnum[keyof typeof CreateUserRoleEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-volume.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface CreateVolume\n */\nexport interface CreateVolume {\n    /**\n     * \n     * @type {string}\n     * @memberof CreateVolume\n     */\n    'name': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/create-workspace.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { CreateBuildInfo } from './create-build-info';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxVolume } from './sandbox-volume';\n\n/**\n * \n * @export\n * @interface CreateWorkspace\n */\nexport interface CreateWorkspace {\n    /**\n     * The image used for the workspace\n     * @type {string}\n     * @memberof CreateWorkspace\n     */\n    'image'?: string;\n    /**\n     * The user associated with the project\n     * @type {string}\n     * @memberof CreateWorkspace\n     */\n    'user'?: string;\n    /**\n     * Environment variables for the workspace\n     * @type {{ [key: string]: string; }}\n     * @memberof CreateWorkspace\n     */\n    'env'?: { [key: string]: string; };\n    /**\n     * Labels for the workspace\n     * @type {{ [key: string]: string; }}\n     * @memberof CreateWorkspace\n     */\n    'labels'?: { [key: string]: string; };\n    /**\n     * Whether the workspace http preview is publicly accessible\n     * @type {boolean}\n     * @memberof CreateWorkspace\n     */\n    'public'?: boolean;\n    /**\n     * The workspace class type\n     * @type {string}\n     * @memberof CreateWorkspace\n     */\n    'class'?: CreateWorkspaceClassEnum;\n    /**\n     * The target (region) where the workspace will be created\n     * @type {string}\n     * @memberof CreateWorkspace\n     */\n    'target'?: CreateWorkspaceTargetEnum;\n    /**\n     * CPU cores allocated to the workspace\n     * @type {number}\n     * @memberof CreateWorkspace\n     */\n    'cpu'?: number;\n    /**\n     * GPU units allocated to the workspace\n     * @type {number}\n     * @memberof CreateWorkspace\n     */\n    'gpu'?: number;\n    /**\n     * Memory allocated to the workspace in GB\n     * @type {number}\n     * @memberof CreateWorkspace\n     */\n    'memory'?: number;\n    /**\n     * Disk space allocated to the workspace in GB\n     * @type {number}\n     * @memberof CreateWorkspace\n     */\n    'disk'?: number;\n    /**\n     * Auto-stop interval in minutes (0 means disabled)\n     * @type {number}\n     * @memberof CreateWorkspace\n     */\n    'autoStopInterval'?: number;\n    /**\n     * Auto-archive interval in minutes (0 means the maximum interval will be used)\n     * @type {number}\n     * @memberof CreateWorkspace\n     */\n    'autoArchiveInterval'?: number;\n    /**\n     * Array of volumes to attach to the workspace\n     * @type {Array<SandboxVolume>}\n     * @memberof CreateWorkspace\n     */\n    'volumes'?: Array<SandboxVolume>;\n    /**\n     * Build information for the workspace\n     * @type {CreateBuildInfo}\n     * @memberof CreateWorkspace\n     */\n    'buildInfo'?: CreateBuildInfo;\n}\n\nexport const CreateWorkspaceClassEnum = {\n    SMALL: 'small',\n    MEDIUM: 'medium',\n    LARGE: 'large'\n} as const;\n\nexport type CreateWorkspaceClassEnum = typeof CreateWorkspaceClassEnum[keyof typeof CreateWorkspaceClassEnum];\nexport const CreateWorkspaceTargetEnum = {\n    EU: 'eu',\n    US: 'us',\n    ASIA: 'asia'\n} as const;\n\nexport type CreateWorkspaceTargetEnum = typeof CreateWorkspaceTargetEnum[keyof typeof CreateWorkspaceTargetEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/daytona-configuration.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { Announcement } from './announcement';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { OidcConfig } from './oidc-config';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { PosthogConfig } from './posthog-config';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RateLimitConfig } from './rate-limit-config';\n\n/**\n * \n * @export\n * @interface DaytonaConfiguration\n */\nexport interface DaytonaConfiguration {\n    /**\n     * Daytona version\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'version': string;\n    /**\n     * PostHog configuration\n     * @type {PosthogConfig}\n     * @memberof DaytonaConfiguration\n     */\n    'posthog'?: PosthogConfig;\n    /**\n     * OIDC configuration\n     * @type {OidcConfig}\n     * @memberof DaytonaConfiguration\n     */\n    'oidc': OidcConfig;\n    /**\n     * Whether linked accounts are enabled\n     * @type {boolean}\n     * @memberof DaytonaConfiguration\n     */\n    'linkedAccountsEnabled': boolean;\n    /**\n     * System announcements\n     * @type {{ [key: string]: Announcement; }}\n     * @memberof DaytonaConfiguration\n     */\n    'announcements': { [key: string]: Announcement; };\n    /**\n     * Pylon application ID\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'pylonAppId'?: string;\n    /**\n     * Proxy template URL\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'proxyTemplateUrl': string;\n    /**\n     * Toolbox template URL\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'proxyToolboxUrl': string;\n    /**\n     * Default snapshot for sandboxes\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'defaultSnapshot': string;\n    /**\n     * Dashboard URL\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'dashboardUrl': string;\n    /**\n     * Maximum auto-archive interval in minutes\n     * @type {number}\n     * @memberof DaytonaConfiguration\n     */\n    'maxAutoArchiveInterval': number;\n    /**\n     * Whether maintenance mode is enabled\n     * @type {boolean}\n     * @memberof DaytonaConfiguration\n     */\n    'maintananceMode': boolean;\n    /**\n     * Current environment\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'environment': string;\n    /**\n     * Billing API URL\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'billingApiUrl'?: string;\n    /**\n     * Analytics API URL\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'analyticsApiUrl'?: string;\n    /**\n     * SSH Gateway command\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'sshGatewayCommand'?: string;\n    /**\n     * Base64 encoded SSH Gateway public key\n     * @type {string}\n     * @memberof DaytonaConfiguration\n     */\n    'sshGatewayPublicKey'?: string;\n    /**\n     * Rate limit configuration\n     * @type {RateLimitConfig}\n     * @memberof DaytonaConfiguration\n     */\n    'rateLimit'?: RateLimitConfig;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/display-info-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface DisplayInfoResponse\n */\nexport interface DisplayInfoResponse {\n    /**\n     * Array of display information for all connected displays\n     * @type {Array<object>}\n     * @memberof DisplayInfoResponse\n     */\n    'displays': Array<object>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/docker-registry.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface DockerRegistry\n */\nexport interface DockerRegistry {\n    /**\n     * Registry ID\n     * @type {string}\n     * @memberof DockerRegistry\n     */\n    'id': string;\n    /**\n     * Registry name\n     * @type {string}\n     * @memberof DockerRegistry\n     */\n    'name': string;\n    /**\n     * Registry URL\n     * @type {string}\n     * @memberof DockerRegistry\n     */\n    'url': string;\n    /**\n     * Registry username\n     * @type {string}\n     * @memberof DockerRegistry\n     */\n    'username': string;\n    /**\n     * Registry project\n     * @type {string}\n     * @memberof DockerRegistry\n     */\n    'project': string;\n    /**\n     * Registry type\n     * @type {string}\n     * @memberof DockerRegistry\n     */\n    'registryType': DockerRegistryRegistryTypeEnum;\n    /**\n     * Creation timestamp\n     * @type {Date}\n     * @memberof DockerRegistry\n     */\n    'createdAt': Date;\n    /**\n     * Last update timestamp\n     * @type {Date}\n     * @memberof DockerRegistry\n     */\n    'updatedAt': Date;\n}\n\nexport const DockerRegistryRegistryTypeEnum = {\n    INTERNAL: 'internal',\n    ORGANIZATION: 'organization',\n    TRANSIENT: 'transient',\n    BACKUP: 'backup'\n} as const;\n\nexport type DockerRegistryRegistryTypeEnum = typeof DockerRegistryRegistryTypeEnum[keyof typeof DockerRegistryRegistryTypeEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/download-files.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface DownloadFiles\n */\nexport interface DownloadFiles {\n    /**\n     * List of remote file paths to download\n     * @type {Array<string>}\n     * @memberof DownloadFiles\n     */\n    'paths': Array<string>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/execute-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ExecuteRequest\n */\nexport interface ExecuteRequest {\n    /**\n     * \n     * @type {string}\n     * @memberof ExecuteRequest\n     */\n    'command': string;\n    /**\n     * Current working directory\n     * @type {string}\n     * @memberof ExecuteRequest\n     */\n    'cwd'?: string;\n    /**\n     * Timeout in seconds, defaults to 10 seconds\n     * @type {number}\n     * @memberof ExecuteRequest\n     */\n    'timeout'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/execute-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ExecuteResponse\n */\nexport interface ExecuteResponse {\n    /**\n     * Exit code\n     * @type {number}\n     * @memberof ExecuteResponse\n     */\n    'exitCode': number;\n    /**\n     * Command output\n     * @type {string}\n     * @memberof ExecuteResponse\n     */\n    'result': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/file-info.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface FileInfo\n */\nexport interface FileInfo {\n    /**\n     * \n     * @type {string}\n     * @memberof FileInfo\n     */\n    'name': string;\n    /**\n     * \n     * @type {boolean}\n     * @memberof FileInfo\n     */\n    'isDir': boolean;\n    /**\n     * \n     * @type {number}\n     * @memberof FileInfo\n     */\n    'size': number;\n    /**\n     * \n     * @type {string}\n     * @memberof FileInfo\n     */\n    'modTime': string;\n    /**\n     * \n     * @type {string}\n     * @memberof FileInfo\n     */\n    'mode': string;\n    /**\n     * \n     * @type {string}\n     * @memberof FileInfo\n     */\n    'permissions': string;\n    /**\n     * \n     * @type {string}\n     * @memberof FileInfo\n     */\n    'owner': string;\n    /**\n     * \n     * @type {string}\n     * @memberof FileInfo\n     */\n    'group': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/file-status.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface FileStatus\n */\nexport interface FileStatus {\n    /**\n     * \n     * @type {string}\n     * @memberof FileStatus\n     */\n    'name': string;\n    /**\n     * \n     * @type {string}\n     * @memberof FileStatus\n     */\n    'staging': string;\n    /**\n     * \n     * @type {string}\n     * @memberof FileStatus\n     */\n    'worktree': string;\n    /**\n     * \n     * @type {string}\n     * @memberof FileStatus\n     */\n    'extra': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-add-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitAddRequest\n */\nexport interface GitAddRequest {\n    /**\n     * \n     * @type {string}\n     * @memberof GitAddRequest\n     */\n    'path': string;\n    /**\n     * files to add (use . for all files)\n     * @type {Array<string>}\n     * @memberof GitAddRequest\n     */\n    'files': Array<string>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-branch-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitBranchRequest\n */\nexport interface GitBranchRequest {\n    /**\n     * \n     * @type {string}\n     * @memberof GitBranchRequest\n     */\n    'path': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitBranchRequest\n     */\n    'name': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-checkout-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitCheckoutRequest\n */\nexport interface GitCheckoutRequest {\n    /**\n     * \n     * @type {string}\n     * @memberof GitCheckoutRequest\n     */\n    'path': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCheckoutRequest\n     */\n    'branch': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-clone-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitCloneRequest\n */\nexport interface GitCloneRequest {\n    /**\n     * \n     * @type {string}\n     * @memberof GitCloneRequest\n     */\n    'url': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCloneRequest\n     */\n    'path': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCloneRequest\n     */\n    'username'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCloneRequest\n     */\n    'password'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCloneRequest\n     */\n    'branch'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCloneRequest\n     */\n    'commit_id'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-commit-info.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitCommitInfo\n */\nexport interface GitCommitInfo {\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitInfo\n     */\n    'hash': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitInfo\n     */\n    'message': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitInfo\n     */\n    'author': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitInfo\n     */\n    'email': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitInfo\n     */\n    'timestamp': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-commit-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitCommitRequest\n */\nexport interface GitCommitRequest {\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitRequest\n     */\n    'path': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitRequest\n     */\n    'message': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitRequest\n     */\n    'author': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitRequest\n     */\n    'email': string;\n    /**\n     * Allow creating an empty commit when no changes are staged\n     * @type {boolean}\n     * @memberof GitCommitRequest\n     */\n    'allow_empty'?: boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-commit-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitCommitResponse\n */\nexport interface GitCommitResponse {\n    /**\n     * \n     * @type {string}\n     * @memberof GitCommitResponse\n     */\n    'hash': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-delete-branch-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitDeleteBranchRequest\n */\nexport interface GitDeleteBranchRequest {\n    /**\n     * \n     * @type {string}\n     * @memberof GitDeleteBranchRequest\n     */\n    'path': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitDeleteBranchRequest\n     */\n    'name': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-repo-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface GitRepoRequest\n */\nexport interface GitRepoRequest {\n    /**\n     * \n     * @type {string}\n     * @memberof GitRepoRequest\n     */\n    'path': string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitRepoRequest\n     */\n    'username'?: string;\n    /**\n     * \n     * @type {string}\n     * @memberof GitRepoRequest\n     */\n    'password'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/git-status.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { FileStatus } from './file-status';\n\n/**\n * \n * @export\n * @interface GitStatus\n */\nexport interface GitStatus {\n    /**\n     * \n     * @type {string}\n     * @memberof GitStatus\n     */\n    'currentBranch': string;\n    /**\n     * \n     * @type {Array<FileStatus>}\n     * @memberof GitStatus\n     */\n    'fileStatus': Array<FileStatus>;\n    /**\n     * \n     * @type {number}\n     * @memberof GitStatus\n     */\n    'ahead'?: number;\n    /**\n     * \n     * @type {number}\n     * @memberof GitStatus\n     */\n    'behind'?: number;\n    /**\n     * \n     * @type {boolean}\n     * @memberof GitStatus\n     */\n    'branchPublished'?: boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/health-controller-check200-response-info-value.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface HealthControllerCheck200ResponseInfoValue\n */\nexport interface HealthControllerCheck200ResponseInfoValue {\n    [key: string]: any;\n\n    /**\n     * \n     * @type {string}\n     * @memberof HealthControllerCheck200ResponseInfoValue\n     */\n    'status': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/health-controller-check200-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { HealthControllerCheck200ResponseInfoValue } from './health-controller-check200-response-info-value';\n\n/**\n * \n * @export\n * @interface HealthControllerCheck200Response\n */\nexport interface HealthControllerCheck200Response {\n    /**\n     * \n     * @type {string}\n     * @memberof HealthControllerCheck200Response\n     */\n    'status'?: string;\n    /**\n     * \n     * @type {{ [key: string]: HealthControllerCheck200ResponseInfoValue; }}\n     * @memberof HealthControllerCheck200Response\n     */\n    'info'?: { [key: string]: HealthControllerCheck200ResponseInfoValue; } | null;\n    /**\n     * \n     * @type {{ [key: string]: HealthControllerCheck200ResponseInfoValue; }}\n     * @memberof HealthControllerCheck200Response\n     */\n    'error'?: { [key: string]: HealthControllerCheck200ResponseInfoValue; } | null;\n    /**\n     * \n     * @type {{ [key: string]: HealthControllerCheck200ResponseInfoValue; }}\n     * @memberof HealthControllerCheck200Response\n     */\n    'details'?: { [key: string]: HealthControllerCheck200ResponseInfoValue; };\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/health-controller-check503-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { HealthControllerCheck200ResponseInfoValue } from './health-controller-check200-response-info-value';\n\n/**\n * \n * @export\n * @interface HealthControllerCheck503Response\n */\nexport interface HealthControllerCheck503Response {\n    /**\n     * \n     * @type {string}\n     * @memberof HealthControllerCheck503Response\n     */\n    'status'?: string;\n    /**\n     * \n     * @type {{ [key: string]: HealthControllerCheck200ResponseInfoValue; }}\n     * @memberof HealthControllerCheck503Response\n     */\n    'info'?: { [key: string]: HealthControllerCheck200ResponseInfoValue; } | null;\n    /**\n     * \n     * @type {{ [key: string]: HealthControllerCheck200ResponseInfoValue; }}\n     * @memberof HealthControllerCheck503Response\n     */\n    'error'?: { [key: string]: HealthControllerCheck200ResponseInfoValue; } | null;\n    /**\n     * \n     * @type {{ [key: string]: HealthControllerCheck200ResponseInfoValue; }}\n     * @memberof HealthControllerCheck503Response\n     */\n    'details'?: { [key: string]: HealthControllerCheck200ResponseInfoValue; };\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/index.ts",
    "content": "export * from './account-provider';\nexport * from './admin-create-runner';\nexport * from './announcement';\nexport * from './api-key-list';\nexport * from './api-key-response';\nexport * from './audit-log';\nexport * from './build-info';\nexport * from './command';\nexport * from './completion-context';\nexport * from './completion-item';\nexport * from './completion-list';\nexport * from './compressed-screenshot-response';\nexport * from './computer-use-start-response';\nexport * from './computer-use-status-response';\nexport * from './computer-use-stop-response';\nexport * from './create-api-key';\nexport * from './create-build-info';\nexport * from './create-docker-registry';\nexport * from './create-linked-account';\nexport * from './create-organization';\nexport * from './create-organization-invitation';\nexport * from './create-organization-quota';\nexport * from './create-organization-role';\nexport * from './create-region';\nexport * from './create-region-response';\nexport * from './create-runner';\nexport * from './create-runner-response';\nexport * from './create-sandbox';\nexport * from './create-session-request';\nexport * from './create-snapshot';\nexport * from './create-user';\nexport * from './create-volume';\nexport * from './create-workspace';\nexport * from './daytona-configuration';\nexport * from './display-info-response';\nexport * from './docker-registry';\nexport * from './download-files';\nexport * from './execute-request';\nexport * from './execute-response';\nexport * from './file-info';\nexport * from './file-status';\nexport * from './git-add-request';\nexport * from './git-branch-request';\nexport * from './git-checkout-request';\nexport * from './git-clone-request';\nexport * from './git-commit-info';\nexport * from './git-commit-request';\nexport * from './git-commit-response';\nexport * from './git-delete-branch-request';\nexport * from './git-repo-request';\nexport * from './git-status';\nexport * from './health-controller-check200-response';\nexport * from './health-controller-check200-response-info-value';\nexport * from './health-controller-check503-response';\nexport * from './job';\nexport * from './job-status';\nexport * from './job-type';\nexport * from './keyboard-hotkey-request';\nexport * from './keyboard-press-request';\nexport * from './keyboard-type-request';\nexport * from './list-branch-response';\nexport * from './log-entry';\nexport * from './lsp-completion-params';\nexport * from './lsp-document-request';\nexport * from './lsp-location';\nexport * from './lsp-server-request';\nexport * from './lsp-symbol';\nexport * from './match';\nexport * from './metric-data-point';\nexport * from './metric-series';\nexport * from './metrics-response';\nexport * from './mouse-click-request';\nexport * from './mouse-click-response';\nexport * from './mouse-drag-request';\nexport * from './mouse-drag-response';\nexport * from './mouse-move-request';\nexport * from './mouse-move-response';\nexport * from './mouse-position';\nexport * from './mouse-scroll-request';\nexport * from './mouse-scroll-response';\nexport * from './oidc-config';\nexport * from './organization';\nexport * from './organization-invitation';\nexport * from './organization-role';\nexport * from './organization-sandbox-default-limited-network-egress';\nexport * from './organization-suspension';\nexport * from './organization-usage-overview';\nexport * from './organization-user';\nexport * from './otel-config';\nexport * from './paginated-audit-logs';\nexport * from './paginated-jobs';\nexport * from './paginated-logs';\nexport * from './paginated-sandboxes';\nexport * from './paginated-snapshots';\nexport * from './paginated-traces';\nexport * from './poll-jobs-response';\nexport * from './port-preview-url';\nexport * from './position';\nexport * from './posthog-config';\nexport * from './process-errors-response';\nexport * from './process-logs-response';\nexport * from './process-restart-response';\nexport * from './process-status-response';\nexport * from './project-dir-response';\nexport * from './pty-create-request';\nexport * from './pty-create-response';\nexport * from './pty-list-response';\nexport * from './pty-resize-request';\nexport * from './pty-session-info';\nexport * from './range';\nexport * from './rate-limit-config';\nexport * from './rate-limit-entry';\nexport * from './regenerate-api-key-response';\nexport * from './region';\nexport * from './region-quota';\nexport * from './region-screenshot-response';\nexport * from './region-type';\nexport * from './region-usage-overview';\nexport * from './registry-push-access-dto';\nexport * from './replace-request';\nexport * from './replace-result';\nexport * from './resize-sandbox';\nexport * from './runner';\nexport * from './runner-full';\nexport * from './runner-health-metrics';\nexport * from './runner-healthcheck';\nexport * from './runner-service-health';\nexport * from './runner-snapshot-dto';\nexport * from './runner-state';\nexport * from './sandbox';\nexport * from './sandbox-class';\nexport * from './sandbox-desired-state';\nexport * from './sandbox-info';\nexport * from './sandbox-labels';\nexport * from './sandbox-state';\nexport * from './sandbox-volume';\nexport * from './screenshot-response';\nexport * from './search-files-response';\nexport * from './send-webhook-dto';\nexport * from './session';\nexport * from './session-execute-request';\nexport * from './session-execute-response';\nexport * from './set-snapshot-general-status-dto';\nexport * from './signed-port-preview-url';\nexport * from './snapshot-dto';\nexport * from './snapshot-manager-credentials';\nexport * from './snapshot-state';\nexport * from './ssh-access-dto';\nexport * from './ssh-access-validation-dto';\nexport * from './storage-access-dto';\nexport * from './toolbox-proxy-url';\nexport * from './trace-span';\nexport * from './trace-summary';\nexport * from './update-docker-registry';\nexport * from './update-job-status';\nexport * from './update-organization-default-region';\nexport * from './update-organization-invitation';\nexport * from './update-organization-member-access';\nexport * from './update-organization-quota';\nexport * from './update-organization-region-quota';\nexport * from './update-organization-role';\nexport * from './update-region';\nexport * from './update-sandbox-state-dto';\nexport * from './url';\nexport * from './user';\nexport * from './user-home-dir-response';\nexport * from './user-public-key';\nexport * from './volume-dto';\nexport * from './volume-state';\nexport * from './webhook-app-portal-access';\nexport * from './webhook-controller-get-status200-response';\nexport * from './webhook-event';\nexport * from './webhook-initialization-status';\nexport * from './windows-response';\nexport * from './work-dir-response';\nexport * from './workspace';\nexport * from './workspace-port-preview-url';\n"
  },
  {
    "path": "libs/api-client/src/models/job-status.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @enum {string}\n */\n\nexport const JobStatus = {\n    PENDING: 'PENDING',\n    IN_PROGRESS: 'IN_PROGRESS',\n    COMPLETED: 'COMPLETED',\n    FAILED: 'FAILED'\n} as const;\n\nexport type JobStatus = typeof JobStatus[keyof typeof JobStatus];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/job-type.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * The type of the job\n * @export\n * @enum {string}\n */\n\nexport const JobType = {\n    CREATE_SANDBOX: 'CREATE_SANDBOX',\n    START_SANDBOX: 'START_SANDBOX',\n    STOP_SANDBOX: 'STOP_SANDBOX',\n    DESTROY_SANDBOX: 'DESTROY_SANDBOX',\n    RESIZE_SANDBOX: 'RESIZE_SANDBOX',\n    CREATE_BACKUP: 'CREATE_BACKUP',\n    BUILD_SNAPSHOT: 'BUILD_SNAPSHOT',\n    PULL_SNAPSHOT: 'PULL_SNAPSHOT',\n    RECOVER_SANDBOX: 'RECOVER_SANDBOX',\n    INSPECT_SNAPSHOT_IN_REGISTRY: 'INSPECT_SNAPSHOT_IN_REGISTRY',\n    REMOVE_SNAPSHOT: 'REMOVE_SNAPSHOT',\n    UPDATE_SANDBOX_NETWORK_SETTINGS: 'UPDATE_SANDBOX_NETWORK_SETTINGS'\n} as const;\n\nexport type JobType = typeof JobType[keyof typeof JobType];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/job.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { JobStatus } from './job-status';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { JobType } from './job-type';\n\n/**\n * \n * @export\n * @interface Job\n */\nexport interface Job {\n    /**\n     * The ID of the job\n     * @type {string}\n     * @memberof Job\n     */\n    'id': string;\n    /**\n     * The type of the job\n     * @type {JobType}\n     * @memberof Job\n     */\n    'type': JobType;\n    /**\n     * The status of the job\n     * @type {JobStatus}\n     * @memberof Job\n     */\n    'status': JobStatus;\n    /**\n     * The type of resource this job operates on\n     * @type {string}\n     * @memberof Job\n     */\n    'resourceType': JobResourceTypeEnum;\n    /**\n     * The ID of the resource this job operates on (sandboxId, snapshotRef, etc.)\n     * @type {string}\n     * @memberof Job\n     */\n    'resourceId': string;\n    /**\n     * Job-specific JSON-encoded payload data (operational metadata)\n     * @type {string}\n     * @memberof Job\n     */\n    'payload'?: string;\n    /**\n     * OpenTelemetry trace context for distributed tracing (W3C Trace Context format)\n     * @type {{ [key: string]: any; }}\n     * @memberof Job\n     */\n    'traceContext'?: { [key: string]: any; };\n    /**\n     * Error message if the job failed\n     * @type {string}\n     * @memberof Job\n     */\n    'errorMessage'?: string;\n    /**\n     * The creation timestamp of the job\n     * @type {string}\n     * @memberof Job\n     */\n    'createdAt': string;\n    /**\n     * The last update timestamp of the job\n     * @type {string}\n     * @memberof Job\n     */\n    'updatedAt'?: string;\n}\n\nexport const JobResourceTypeEnum = {\n    SANDBOX: 'SANDBOX',\n    SNAPSHOT: 'SNAPSHOT',\n    BACKUP: 'BACKUP'\n} as const;\n\nexport type JobResourceTypeEnum = typeof JobResourceTypeEnum[keyof typeof JobResourceTypeEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/keyboard-hotkey-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface KeyboardHotkeyRequest\n */\nexport interface KeyboardHotkeyRequest {\n    /**\n     * The hotkey combination to press (e.g., \\\"ctrl+c\\\", \\\"cmd+v\\\", \\\"alt+tab\\\")\n     * @type {string}\n     * @memberof KeyboardHotkeyRequest\n     */\n    'keys': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/keyboard-press-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface KeyboardPressRequest\n */\nexport interface KeyboardPressRequest {\n    /**\n     * The key to press (e.g., a, b, c, enter, space, etc.)\n     * @type {string}\n     * @memberof KeyboardPressRequest\n     */\n    'key': string;\n    /**\n     * Array of modifier keys to press along with the main key (ctrl, alt, shift, cmd)\n     * @type {Array<string>}\n     * @memberof KeyboardPressRequest\n     */\n    'modifiers'?: Array<string>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/keyboard-type-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface KeyboardTypeRequest\n */\nexport interface KeyboardTypeRequest {\n    /**\n     * The text to type using the keyboard\n     * @type {string}\n     * @memberof KeyboardTypeRequest\n     */\n    'text': string;\n    /**\n     * Delay in milliseconds between keystrokes. Defaults to 0\n     * @type {number}\n     * @memberof KeyboardTypeRequest\n     */\n    'delay'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/list-branch-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ListBranchResponse\n */\nexport interface ListBranchResponse {\n    /**\n     * \n     * @type {Array<string>}\n     * @memberof ListBranchResponse\n     */\n    'branches': Array<string>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/log-entry.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface LogEntry\n */\nexport interface LogEntry {\n    /**\n     * Timestamp of the log entry\n     * @type {string}\n     * @memberof LogEntry\n     */\n    'timestamp': string;\n    /**\n     * Log message body\n     * @type {string}\n     * @memberof LogEntry\n     */\n    'body': string;\n    /**\n     * Severity level text (e.g., INFO, WARN, ERROR)\n     * @type {string}\n     * @memberof LogEntry\n     */\n    'severityText': string;\n    /**\n     * Severity level number\n     * @type {number}\n     * @memberof LogEntry\n     */\n    'severityNumber'?: number;\n    /**\n     * Service name that generated the log\n     * @type {string}\n     * @memberof LogEntry\n     */\n    'serviceName': string;\n    /**\n     * Resource attributes from OTEL\n     * @type {{ [key: string]: string; }}\n     * @memberof LogEntry\n     */\n    'resourceAttributes': { [key: string]: string; };\n    /**\n     * Log-specific attributes\n     * @type {{ [key: string]: string; }}\n     * @memberof LogEntry\n     */\n    'logAttributes': { [key: string]: string; };\n    /**\n     * Associated trace ID if available\n     * @type {string}\n     * @memberof LogEntry\n     */\n    'traceId'?: string;\n    /**\n     * Associated span ID if available\n     * @type {string}\n     * @memberof LogEntry\n     */\n    'spanId'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/lsp-completion-params.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { CompletionContext } from './completion-context';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { Position } from './position';\n\n/**\n * \n * @export\n * @interface LspCompletionParams\n */\nexport interface LspCompletionParams {\n    /**\n     * Language identifier\n     * @type {string}\n     * @memberof LspCompletionParams\n     */\n    'languageId': string;\n    /**\n     * Path to the project\n     * @type {string}\n     * @memberof LspCompletionParams\n     */\n    'pathToProject': string;\n    /**\n     * Document URI\n     * @type {string}\n     * @memberof LspCompletionParams\n     */\n    'uri': string;\n    /**\n     * \n     * @type {Position}\n     * @memberof LspCompletionParams\n     */\n    'position': Position;\n    /**\n     * \n     * @type {CompletionContext}\n     * @memberof LspCompletionParams\n     */\n    'context'?: CompletionContext;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/lsp-document-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface LspDocumentRequest\n */\nexport interface LspDocumentRequest {\n    /**\n     * Language identifier\n     * @type {string}\n     * @memberof LspDocumentRequest\n     */\n    'languageId': string;\n    /**\n     * Path to the project\n     * @type {string}\n     * @memberof LspDocumentRequest\n     */\n    'pathToProject': string;\n    /**\n     * Document URI\n     * @type {string}\n     * @memberof LspDocumentRequest\n     */\n    'uri': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/lsp-location.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { Range } from './range';\n\n/**\n * \n * @export\n * @interface LspLocation\n */\nexport interface LspLocation {\n    /**\n     * \n     * @type {Range}\n     * @memberof LspLocation\n     */\n    'range': Range;\n    /**\n     * \n     * @type {string}\n     * @memberof LspLocation\n     */\n    'uri': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/lsp-server-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface LspServerRequest\n */\nexport interface LspServerRequest {\n    /**\n     * Language identifier\n     * @type {string}\n     * @memberof LspServerRequest\n     */\n    'languageId': string;\n    /**\n     * Path to the project\n     * @type {string}\n     * @memberof LspServerRequest\n     */\n    'pathToProject': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/lsp-symbol.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { LspLocation } from './lsp-location';\n\n/**\n * \n * @export\n * @interface LspSymbol\n */\nexport interface LspSymbol {\n    /**\n     * \n     * @type {number}\n     * @memberof LspSymbol\n     */\n    'kind': number;\n    /**\n     * \n     * @type {LspLocation}\n     * @memberof LspSymbol\n     */\n    'location': LspLocation;\n    /**\n     * \n     * @type {string}\n     * @memberof LspSymbol\n     */\n    'name': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/match.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface Match\n */\nexport interface Match {\n    /**\n     * \n     * @type {string}\n     * @memberof Match\n     */\n    'file': string;\n    /**\n     * \n     * @type {number}\n     * @memberof Match\n     */\n    'line': number;\n    /**\n     * \n     * @type {string}\n     * @memberof Match\n     */\n    'content': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/metric-data-point.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MetricDataPoint\n */\nexport interface MetricDataPoint {\n    /**\n     * Timestamp of the data point\n     * @type {string}\n     * @memberof MetricDataPoint\n     */\n    'timestamp': string;\n    /**\n     * Value at this timestamp\n     * @type {number}\n     * @memberof MetricDataPoint\n     */\n    'value': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/metric-series.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { MetricDataPoint } from './metric-data-point';\n\n/**\n * \n * @export\n * @interface MetricSeries\n */\nexport interface MetricSeries {\n    /**\n     * Name of the metric\n     * @type {string}\n     * @memberof MetricSeries\n     */\n    'metricName': string;\n    /**\n     * Data points for this metric\n     * @type {Array<MetricDataPoint>}\n     * @memberof MetricSeries\n     */\n    'dataPoints': Array<MetricDataPoint>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/metrics-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { MetricSeries } from './metric-series';\n\n/**\n * \n * @export\n * @interface MetricsResponse\n */\nexport interface MetricsResponse {\n    /**\n     * List of metric series\n     * @type {Array<MetricSeries>}\n     * @memberof MetricsResponse\n     */\n    'series': Array<MetricSeries>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-click-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MouseClickRequest\n */\nexport interface MouseClickRequest {\n    /**\n     * The X coordinate where to perform the mouse click\n     * @type {number}\n     * @memberof MouseClickRequest\n     */\n    'x': number;\n    /**\n     * The Y coordinate where to perform the mouse click\n     * @type {number}\n     * @memberof MouseClickRequest\n     */\n    'y': number;\n    /**\n     * The mouse button to click (left, right, middle). Defaults to left\n     * @type {string}\n     * @memberof MouseClickRequest\n     */\n    'button'?: string;\n    /**\n     * Whether to perform a double-click instead of a single click\n     * @type {boolean}\n     * @memberof MouseClickRequest\n     */\n    'double'?: boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-click-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MouseClickResponse\n */\nexport interface MouseClickResponse {\n    /**\n     * The actual X coordinate where the click occurred\n     * @type {number}\n     * @memberof MouseClickResponse\n     */\n    'x': number;\n    /**\n     * The actual Y coordinate where the click occurred\n     * @type {number}\n     * @memberof MouseClickResponse\n     */\n    'y': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-drag-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MouseDragRequest\n */\nexport interface MouseDragRequest {\n    /**\n     * The starting X coordinate for the drag operation\n     * @type {number}\n     * @memberof MouseDragRequest\n     */\n    'startX': number;\n    /**\n     * The starting Y coordinate for the drag operation\n     * @type {number}\n     * @memberof MouseDragRequest\n     */\n    'startY': number;\n    /**\n     * The ending X coordinate for the drag operation\n     * @type {number}\n     * @memberof MouseDragRequest\n     */\n    'endX': number;\n    /**\n     * The ending Y coordinate for the drag operation\n     * @type {number}\n     * @memberof MouseDragRequest\n     */\n    'endY': number;\n    /**\n     * The mouse button to use for dragging (left, right, middle). Defaults to left\n     * @type {string}\n     * @memberof MouseDragRequest\n     */\n    'button'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-drag-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MouseDragResponse\n */\nexport interface MouseDragResponse {\n    /**\n     * The actual X coordinate where the drag ended\n     * @type {number}\n     * @memberof MouseDragResponse\n     */\n    'x': number;\n    /**\n     * The actual Y coordinate where the drag ended\n     * @type {number}\n     * @memberof MouseDragResponse\n     */\n    'y': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-move-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MouseMoveRequest\n */\nexport interface MouseMoveRequest {\n    /**\n     * The target X coordinate to move the mouse cursor to\n     * @type {number}\n     * @memberof MouseMoveRequest\n     */\n    'x': number;\n    /**\n     * The target Y coordinate to move the mouse cursor to\n     * @type {number}\n     * @memberof MouseMoveRequest\n     */\n    'y': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-move-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MouseMoveResponse\n */\nexport interface MouseMoveResponse {\n    /**\n     * The actual X coordinate where the mouse cursor ended up\n     * @type {number}\n     * @memberof MouseMoveResponse\n     */\n    'x': number;\n    /**\n     * The actual Y coordinate where the mouse cursor ended up\n     * @type {number}\n     * @memberof MouseMoveResponse\n     */\n    'y': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-position.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MousePosition\n */\nexport interface MousePosition {\n    /**\n     * The X coordinate of the mouse cursor position\n     * @type {number}\n     * @memberof MousePosition\n     */\n    'x': number;\n    /**\n     * The Y coordinate of the mouse cursor position\n     * @type {number}\n     * @memberof MousePosition\n     */\n    'y': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-scroll-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MouseScrollRequest\n */\nexport interface MouseScrollRequest {\n    /**\n     * The X coordinate where to perform the scroll operation\n     * @type {number}\n     * @memberof MouseScrollRequest\n     */\n    'x': number;\n    /**\n     * The Y coordinate where to perform the scroll operation\n     * @type {number}\n     * @memberof MouseScrollRequest\n     */\n    'y': number;\n    /**\n     * The scroll direction (up, down)\n     * @type {string}\n     * @memberof MouseScrollRequest\n     */\n    'direction': string;\n    /**\n     * The number of scroll units to scroll. Defaults to 1\n     * @type {number}\n     * @memberof MouseScrollRequest\n     */\n    'amount'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/mouse-scroll-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface MouseScrollResponse\n */\nexport interface MouseScrollResponse {\n    /**\n     * Whether the mouse scroll operation was successful\n     * @type {boolean}\n     * @memberof MouseScrollResponse\n     */\n    'success': boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/oidc-config.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface OidcConfig\n */\nexport interface OidcConfig {\n    /**\n     * OIDC issuer\n     * @type {string}\n     * @memberof OidcConfig\n     */\n    'issuer': string;\n    /**\n     * OIDC client ID\n     * @type {string}\n     * @memberof OidcConfig\n     */\n    'clientId': string;\n    /**\n     * OIDC audience\n     * @type {string}\n     * @memberof OidcConfig\n     */\n    'audience': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/organization-invitation.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { OrganizationRole } from './organization-role';\n\n/**\n * \n * @export\n * @interface OrganizationInvitation\n */\nexport interface OrganizationInvitation {\n    /**\n     * Invitation ID\n     * @type {string}\n     * @memberof OrganizationInvitation\n     */\n    'id': string;\n    /**\n     * Email address of the invitee\n     * @type {string}\n     * @memberof OrganizationInvitation\n     */\n    'email': string;\n    /**\n     * Email address of the inviter\n     * @type {string}\n     * @memberof OrganizationInvitation\n     */\n    'invitedBy': string;\n    /**\n     * Organization ID\n     * @type {string}\n     * @memberof OrganizationInvitation\n     */\n    'organizationId': string;\n    /**\n     * Organization name\n     * @type {string}\n     * @memberof OrganizationInvitation\n     */\n    'organizationName': string;\n    /**\n     * Expiration date of the invitation\n     * @type {Date}\n     * @memberof OrganizationInvitation\n     */\n    'expiresAt': Date;\n    /**\n     * Invitation status\n     * @type {string}\n     * @memberof OrganizationInvitation\n     */\n    'status': OrganizationInvitationStatusEnum;\n    /**\n     * Member role\n     * @type {string}\n     * @memberof OrganizationInvitation\n     */\n    'role': OrganizationInvitationRoleEnum;\n    /**\n     * Assigned roles\n     * @type {Array<OrganizationRole>}\n     * @memberof OrganizationInvitation\n     */\n    'assignedRoles': Array<OrganizationRole>;\n    /**\n     * Creation timestamp\n     * @type {Date}\n     * @memberof OrganizationInvitation\n     */\n    'createdAt': Date;\n    /**\n     * Last update timestamp\n     * @type {Date}\n     * @memberof OrganizationInvitation\n     */\n    'updatedAt': Date;\n}\n\nexport const OrganizationInvitationStatusEnum = {\n    PENDING: 'pending',\n    ACCEPTED: 'accepted',\n    DECLINED: 'declined',\n    CANCELLED: 'cancelled'\n} as const;\n\nexport type OrganizationInvitationStatusEnum = typeof OrganizationInvitationStatusEnum[keyof typeof OrganizationInvitationStatusEnum];\nexport const OrganizationInvitationRoleEnum = {\n    OWNER: 'owner',\n    MEMBER: 'member'\n} as const;\n\nexport type OrganizationInvitationRoleEnum = typeof OrganizationInvitationRoleEnum[keyof typeof OrganizationInvitationRoleEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/organization-role.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface OrganizationRole\n */\nexport interface OrganizationRole {\n    /**\n     * Role ID\n     * @type {string}\n     * @memberof OrganizationRole\n     */\n    'id': string;\n    /**\n     * Role name\n     * @type {string}\n     * @memberof OrganizationRole\n     */\n    'name': string;\n    /**\n     * Role description\n     * @type {string}\n     * @memberof OrganizationRole\n     */\n    'description': string;\n    /**\n     * Roles assigned to the user\n     * @type {Array<string>}\n     * @memberof OrganizationRole\n     */\n    'permissions': Array<OrganizationRolePermissionsEnum>;\n    /**\n     * Global role flag\n     * @type {boolean}\n     * @memberof OrganizationRole\n     */\n    'isGlobal': boolean;\n    /**\n     * Creation timestamp\n     * @type {Date}\n     * @memberof OrganizationRole\n     */\n    'createdAt': Date;\n    /**\n     * Last update timestamp\n     * @type {Date}\n     * @memberof OrganizationRole\n     */\n    'updatedAt': Date;\n}\n\nexport const OrganizationRolePermissionsEnum = {\n    WRITE_REGISTRIES: 'write:registries',\n    DELETE_REGISTRIES: 'delete:registries',\n    WRITE_SNAPSHOTS: 'write:snapshots',\n    DELETE_SNAPSHOTS: 'delete:snapshots',\n    WRITE_SANDBOXES: 'write:sandboxes',\n    DELETE_SANDBOXES: 'delete:sandboxes',\n    READ_VOLUMES: 'read:volumes',\n    WRITE_VOLUMES: 'write:volumes',\n    DELETE_VOLUMES: 'delete:volumes',\n    WRITE_REGIONS: 'write:regions',\n    DELETE_REGIONS: 'delete:regions',\n    READ_RUNNERS: 'read:runners',\n    WRITE_RUNNERS: 'write:runners',\n    DELETE_RUNNERS: 'delete:runners',\n    READ_AUDIT_LOGS: 'read:audit_logs'\n} as const;\n\nexport type OrganizationRolePermissionsEnum = typeof OrganizationRolePermissionsEnum[keyof typeof OrganizationRolePermissionsEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/organization-sandbox-default-limited-network-egress.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface OrganizationSandboxDefaultLimitedNetworkEgress\n */\nexport interface OrganizationSandboxDefaultLimitedNetworkEgress {\n    /**\n     * Sandbox default limited network egress\n     * @type {boolean}\n     * @memberof OrganizationSandboxDefaultLimitedNetworkEgress\n     */\n    'sandboxDefaultLimitedNetworkEgress': boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/organization-suspension.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface OrganizationSuspension\n */\nexport interface OrganizationSuspension {\n    /**\n     * Suspension reason\n     * @type {string}\n     * @memberof OrganizationSuspension\n     */\n    'reason': string;\n    /**\n     * Suspension until\n     * @type {Date}\n     * @memberof OrganizationSuspension\n     */\n    'until': Date;\n    /**\n     * Suspension cleanup grace period hours\n     * @type {number}\n     * @memberof OrganizationSuspension\n     */\n    'suspensionCleanupGracePeriodHours'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/organization-usage-overview.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RegionUsageOverview } from './region-usage-overview';\n\n/**\n * \n * @export\n * @interface OrganizationUsageOverview\n */\nexport interface OrganizationUsageOverview {\n    /**\n     * \n     * @type {Array<RegionUsageOverview>}\n     * @memberof OrganizationUsageOverview\n     */\n    'regionUsage': Array<RegionUsageOverview>;\n    /**\n     * \n     * @type {number}\n     * @memberof OrganizationUsageOverview\n     */\n    'totalSnapshotQuota': number;\n    /**\n     * \n     * @type {number}\n     * @memberof OrganizationUsageOverview\n     */\n    'currentSnapshotUsage': number;\n    /**\n     * \n     * @type {number}\n     * @memberof OrganizationUsageOverview\n     */\n    'totalVolumeQuota': number;\n    /**\n     * \n     * @type {number}\n     * @memberof OrganizationUsageOverview\n     */\n    'currentVolumeUsage': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/organization-user.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { OrganizationRole } from './organization-role';\n\n/**\n * \n * @export\n * @interface OrganizationUser\n */\nexport interface OrganizationUser {\n    /**\n     * User ID\n     * @type {string}\n     * @memberof OrganizationUser\n     */\n    'userId': string;\n    /**\n     * Organization ID\n     * @type {string}\n     * @memberof OrganizationUser\n     */\n    'organizationId': string;\n    /**\n     * User name\n     * @type {string}\n     * @memberof OrganizationUser\n     */\n    'name': string;\n    /**\n     * User email\n     * @type {string}\n     * @memberof OrganizationUser\n     */\n    'email': string;\n    /**\n     * Member role\n     * @type {string}\n     * @memberof OrganizationUser\n     */\n    'role': OrganizationUserRoleEnum;\n    /**\n     * Roles assigned to the user\n     * @type {Array<OrganizationRole>}\n     * @memberof OrganizationUser\n     */\n    'assignedRoles': Array<OrganizationRole>;\n    /**\n     * Creation timestamp\n     * @type {Date}\n     * @memberof OrganizationUser\n     */\n    'createdAt': Date;\n    /**\n     * Last update timestamp\n     * @type {Date}\n     * @memberof OrganizationUser\n     */\n    'updatedAt': Date;\n}\n\nexport const OrganizationUserRoleEnum = {\n    OWNER: 'owner',\n    MEMBER: 'member'\n} as const;\n\nexport type OrganizationUserRoleEnum = typeof OrganizationUserRoleEnum[keyof typeof OrganizationUserRoleEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/organization.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface Organization\n */\nexport interface Organization {\n    /**\n     * Organization ID\n     * @type {string}\n     * @memberof Organization\n     */\n    'id': string;\n    /**\n     * Organization name\n     * @type {string}\n     * @memberof Organization\n     */\n    'name': string;\n    /**\n     * User ID of the organization creator\n     * @type {string}\n     * @memberof Organization\n     */\n    'createdBy': string;\n    /**\n     * Personal organization flag\n     * @type {boolean}\n     * @memberof Organization\n     */\n    'personal': boolean;\n    /**\n     * Creation timestamp\n     * @type {Date}\n     * @memberof Organization\n     */\n    'createdAt': Date;\n    /**\n     * Last update timestamp\n     * @type {Date}\n     * @memberof Organization\n     */\n    'updatedAt': Date;\n    /**\n     * Suspended flag\n     * @type {boolean}\n     * @memberof Organization\n     */\n    'suspended': boolean;\n    /**\n     * Suspended at\n     * @type {Date}\n     * @memberof Organization\n     */\n    'suspendedAt': Date;\n    /**\n     * Suspended reason\n     * @type {string}\n     * @memberof Organization\n     */\n    'suspensionReason': string;\n    /**\n     * Suspended until\n     * @type {Date}\n     * @memberof Organization\n     */\n    'suspendedUntil': Date;\n    /**\n     * Suspension cleanup grace period hours\n     * @type {number}\n     * @memberof Organization\n     */\n    'suspensionCleanupGracePeriodHours': number;\n    /**\n     * Max CPU per sandbox\n     * @type {number}\n     * @memberof Organization\n     */\n    'maxCpuPerSandbox': number;\n    /**\n     * Max memory per sandbox\n     * @type {number}\n     * @memberof Organization\n     */\n    'maxMemoryPerSandbox': number;\n    /**\n     * Max disk per sandbox\n     * @type {number}\n     * @memberof Organization\n     */\n    'maxDiskPerSandbox': number;\n    /**\n     * Time in minutes before an unused snapshot is deactivated\n     * @type {number}\n     * @memberof Organization\n     */\n    'snapshotDeactivationTimeoutMinutes': number;\n    /**\n     * Sandbox default network block all\n     * @type {boolean}\n     * @memberof Organization\n     */\n    'sandboxLimitedNetworkEgress': boolean;\n    /**\n     * Default region ID\n     * @type {string}\n     * @memberof Organization\n     */\n    'defaultRegionId'?: string;\n    /**\n     * Authenticated rate limit per minute\n     * @type {number}\n     * @memberof Organization\n     */\n    'authenticatedRateLimit': number | null;\n    /**\n     * Sandbox create rate limit per minute\n     * @type {number}\n     * @memberof Organization\n     */\n    'sandboxCreateRateLimit': number | null;\n    /**\n     * Sandbox lifecycle rate limit per minute\n     * @type {number}\n     * @memberof Organization\n     */\n    'sandboxLifecycleRateLimit': number | null;\n    /**\n     * Experimental configuration\n     * @type {object}\n     * @memberof Organization\n     */\n    'experimentalConfig': object;\n    /**\n     * Authenticated rate limit TTL in seconds\n     * @type {number}\n     * @memberof Organization\n     */\n    'authenticatedRateLimitTtlSeconds': number | null;\n    /**\n     * Sandbox create rate limit TTL in seconds\n     * @type {number}\n     * @memberof Organization\n     */\n    'sandboxCreateRateLimitTtlSeconds': number | null;\n    /**\n     * Sandbox lifecycle rate limit TTL in seconds\n     * @type {number}\n     * @memberof Organization\n     */\n    'sandboxLifecycleRateLimitTtlSeconds': number | null;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/otel-config.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface OtelConfig\n */\nexport interface OtelConfig {\n    /**\n     * Endpoint\n     * @type {string}\n     * @memberof OtelConfig\n     */\n    'endpoint': string;\n    /**\n     * Headers\n     * @type {{ [key: string]: string; }}\n     * @memberof OtelConfig\n     */\n    'headers'?: { [key: string]: string; } | null;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/paginated-audit-logs.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { AuditLog } from './audit-log';\n\n/**\n * \n * @export\n * @interface PaginatedAuditLogs\n */\nexport interface PaginatedAuditLogs {\n    /**\n     * \n     * @type {Array<AuditLog>}\n     * @memberof PaginatedAuditLogs\n     */\n    'items': Array<AuditLog>;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedAuditLogs\n     */\n    'total': number;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedAuditLogs\n     */\n    'page': number;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedAuditLogs\n     */\n    'totalPages': number;\n    /**\n     * Token for next page in cursor-based pagination\n     * @type {string}\n     * @memberof PaginatedAuditLogs\n     */\n    'nextToken'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/paginated-jobs.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { Job } from './job';\n\n/**\n * \n * @export\n * @interface PaginatedJobs\n */\nexport interface PaginatedJobs {\n    /**\n     * \n     * @type {Array<Job>}\n     * @memberof PaginatedJobs\n     */\n    'items': Array<Job>;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedJobs\n     */\n    'total': number;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedJobs\n     */\n    'page': number;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedJobs\n     */\n    'totalPages': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/paginated-logs.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { LogEntry } from './log-entry';\n\n/**\n * \n * @export\n * @interface PaginatedLogs\n */\nexport interface PaginatedLogs {\n    /**\n     * List of log entries\n     * @type {Array<LogEntry>}\n     * @memberof PaginatedLogs\n     */\n    'items': Array<LogEntry>;\n    /**\n     * Total number of log entries matching the query\n     * @type {number}\n     * @memberof PaginatedLogs\n     */\n    'total': number;\n    /**\n     * Current page number\n     * @type {number}\n     * @memberof PaginatedLogs\n     */\n    'page': number;\n    /**\n     * Total number of pages\n     * @type {number}\n     * @memberof PaginatedLogs\n     */\n    'totalPages': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/paginated-sandboxes.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { Sandbox } from './sandbox';\n\n/**\n * \n * @export\n * @interface PaginatedSandboxes\n */\nexport interface PaginatedSandboxes {\n    /**\n     * \n     * @type {Array<Sandbox>}\n     * @memberof PaginatedSandboxes\n     */\n    'items': Array<Sandbox>;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedSandboxes\n     */\n    'total': number;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedSandboxes\n     */\n    'page': number;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedSandboxes\n     */\n    'totalPages': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/paginated-snapshots.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SnapshotDto } from './snapshot-dto';\n\n/**\n * \n * @export\n * @interface PaginatedSnapshots\n */\nexport interface PaginatedSnapshots {\n    /**\n     * \n     * @type {Array<SnapshotDto>}\n     * @memberof PaginatedSnapshots\n     */\n    'items': Array<SnapshotDto>;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedSnapshots\n     */\n    'total': number;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedSnapshots\n     */\n    'page': number;\n    /**\n     * \n     * @type {number}\n     * @memberof PaginatedSnapshots\n     */\n    'totalPages': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/paginated-traces.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { TraceSummary } from './trace-summary';\n\n/**\n * \n * @export\n * @interface PaginatedTraces\n */\nexport interface PaginatedTraces {\n    /**\n     * List of trace summaries\n     * @type {Array<TraceSummary>}\n     * @memberof PaginatedTraces\n     */\n    'items': Array<TraceSummary>;\n    /**\n     * Total number of traces matching the query\n     * @type {number}\n     * @memberof PaginatedTraces\n     */\n    'total': number;\n    /**\n     * Current page number\n     * @type {number}\n     * @memberof PaginatedTraces\n     */\n    'page': number;\n    /**\n     * Total number of pages\n     * @type {number}\n     * @memberof PaginatedTraces\n     */\n    'totalPages': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/poll-jobs-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { Job } from './job';\n\n/**\n * \n * @export\n * @interface PollJobsResponse\n */\nexport interface PollJobsResponse {\n    /**\n     * List of jobs\n     * @type {Array<Job>}\n     * @memberof PollJobsResponse\n     */\n    'jobs': Array<Job>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/port-preview-url.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface PortPreviewUrl\n */\nexport interface PortPreviewUrl {\n    /**\n     * ID of the sandbox\n     * @type {string}\n     * @memberof PortPreviewUrl\n     */\n    'sandboxId': string;\n    /**\n     * Preview url\n     * @type {string}\n     * @memberof PortPreviewUrl\n     */\n    'url': string;\n    /**\n     * Access token\n     * @type {string}\n     * @memberof PortPreviewUrl\n     */\n    'token': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/position.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface Position\n */\nexport interface Position {\n    /**\n     * \n     * @type {number}\n     * @memberof Position\n     */\n    'line': number;\n    /**\n     * \n     * @type {number}\n     * @memberof Position\n     */\n    'character': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/posthog-config.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface PosthogConfig\n */\nexport interface PosthogConfig {\n    /**\n     * PostHog API key\n     * @type {string}\n     * @memberof PosthogConfig\n     */\n    'apiKey': string;\n    /**\n     * PostHog host URL\n     * @type {string}\n     * @memberof PosthogConfig\n     */\n    'host': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/process-errors-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ProcessErrorsResponse\n */\nexport interface ProcessErrorsResponse {\n    /**\n     * The name of the VNC process whose error logs were retrieved\n     * @type {string}\n     * @memberof ProcessErrorsResponse\n     */\n    'processName': string;\n    /**\n     * The error log output from the specified VNC process\n     * @type {string}\n     * @memberof ProcessErrorsResponse\n     */\n    'errors': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/process-logs-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ProcessLogsResponse\n */\nexport interface ProcessLogsResponse {\n    /**\n     * The name of the VNC process whose logs were retrieved\n     * @type {string}\n     * @memberof ProcessLogsResponse\n     */\n    'processName': string;\n    /**\n     * The log output from the specified VNC process\n     * @type {string}\n     * @memberof ProcessLogsResponse\n     */\n    'logs': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/process-restart-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ProcessRestartResponse\n */\nexport interface ProcessRestartResponse {\n    /**\n     * A message indicating the result of restarting the process\n     * @type {string}\n     * @memberof ProcessRestartResponse\n     */\n    'message': string;\n    /**\n     * The name of the VNC process that was restarted\n     * @type {string}\n     * @memberof ProcessRestartResponse\n     */\n    'processName': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/process-status-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ProcessStatusResponse\n */\nexport interface ProcessStatusResponse {\n    /**\n     * The name of the VNC process being checked\n     * @type {string}\n     * @memberof ProcessStatusResponse\n     */\n    'processName': string;\n    /**\n     * Whether the specified VNC process is currently running\n     * @type {boolean}\n     * @memberof ProcessStatusResponse\n     */\n    'running': boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/project-dir-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ProjectDirResponse\n */\nexport interface ProjectDirResponse {\n    /**\n     * \n     * @type {string}\n     * @memberof ProjectDirResponse\n     */\n    'dir'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/pty-create-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface PtyCreateRequest\n */\nexport interface PtyCreateRequest {\n    /**\n     * The unique identifier for the PTY session\n     * @type {string}\n     * @memberof PtyCreateRequest\n     */\n    'id': string;\n    /**\n     * Starting directory for the PTY session, defaults to the sandbox\\'s working directory\n     * @type {string}\n     * @memberof PtyCreateRequest\n     */\n    'cwd'?: string;\n    /**\n     * Environment variables for the PTY session\n     * @type {object}\n     * @memberof PtyCreateRequest\n     */\n    'envs'?: object;\n    /**\n     * Number of terminal columns\n     * @type {number}\n     * @memberof PtyCreateRequest\n     */\n    'cols'?: number;\n    /**\n     * Number of terminal rows\n     * @type {number}\n     * @memberof PtyCreateRequest\n     */\n    'rows'?: number;\n    /**\n     * Whether to start the PTY session lazily (only start when first client connects)\n     * @type {boolean}\n     * @memberof PtyCreateRequest\n     */\n    'lazyStart'?: boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/pty-create-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface PtyCreateResponse\n */\nexport interface PtyCreateResponse {\n    /**\n     * The unique identifier for the created PTY session\n     * @type {string}\n     * @memberof PtyCreateResponse\n     */\n    'sessionId': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/pty-list-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { PtySessionInfo } from './pty-session-info';\n\n/**\n * \n * @export\n * @interface PtyListResponse\n */\nexport interface PtyListResponse {\n    /**\n     * List of active PTY sessions\n     * @type {Array<PtySessionInfo>}\n     * @memberof PtyListResponse\n     */\n    'sessions': Array<PtySessionInfo>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/pty-resize-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface PtyResizeRequest\n */\nexport interface PtyResizeRequest {\n    /**\n     * Number of terminal columns\n     * @type {number}\n     * @memberof PtyResizeRequest\n     */\n    'cols': number;\n    /**\n     * Number of terminal rows\n     * @type {number}\n     * @memberof PtyResizeRequest\n     */\n    'rows': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/pty-session-info.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface PtySessionInfo\n */\nexport interface PtySessionInfo {\n    /**\n     * The unique identifier for the PTY session\n     * @type {string}\n     * @memberof PtySessionInfo\n     */\n    'id': string;\n    /**\n     * Starting directory for the PTY session, defaults to the sandbox\\'s working directory\n     * @type {string}\n     * @memberof PtySessionInfo\n     */\n    'cwd': string;\n    /**\n     * Environment variables for the PTY session\n     * @type {object}\n     * @memberof PtySessionInfo\n     */\n    'envs': object;\n    /**\n     * Number of terminal columns\n     * @type {number}\n     * @memberof PtySessionInfo\n     */\n    'cols': number;\n    /**\n     * Number of terminal rows\n     * @type {number}\n     * @memberof PtySessionInfo\n     */\n    'rows': number;\n    /**\n     * When the PTY session was created\n     * @type {string}\n     * @memberof PtySessionInfo\n     */\n    'createdAt': string;\n    /**\n     * Whether the PTY session is currently active\n     * @type {boolean}\n     * @memberof PtySessionInfo\n     */\n    'active': boolean;\n    /**\n     * Whether the PTY session uses lazy start (only start when first client connects)\n     * @type {boolean}\n     * @memberof PtySessionInfo\n     */\n    'lazyStart': boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/range.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { Position } from './position';\n\n/**\n * \n * @export\n * @interface Range\n */\nexport interface Range {\n    /**\n     * \n     * @type {Position}\n     * @memberof Range\n     */\n    'start': Position;\n    /**\n     * \n     * @type {Position}\n     * @memberof Range\n     */\n    'end': Position;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/rate-limit-config.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RateLimitEntry } from './rate-limit-entry';\n\n/**\n * \n * @export\n * @interface RateLimitConfig\n */\nexport interface RateLimitConfig {\n    /**\n     * Failed authentication rate limit\n     * @type {RateLimitEntry}\n     * @memberof RateLimitConfig\n     */\n    'failedAuth'?: RateLimitEntry;\n    /**\n     * Authenticated rate limit\n     * @type {RateLimitEntry}\n     * @memberof RateLimitConfig\n     */\n    'authenticated'?: RateLimitEntry;\n    /**\n     * Sandbox create rate limit\n     * @type {RateLimitEntry}\n     * @memberof RateLimitConfig\n     */\n    'sandboxCreate'?: RateLimitEntry;\n    /**\n     * Sandbox lifecycle rate limit\n     * @type {RateLimitEntry}\n     * @memberof RateLimitConfig\n     */\n    'sandboxLifecycle'?: RateLimitEntry;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/rate-limit-entry.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RateLimitEntry\n */\nexport interface RateLimitEntry {\n    /**\n     * Rate limit TTL in seconds\n     * @type {number}\n     * @memberof RateLimitEntry\n     */\n    'ttl'?: number;\n    /**\n     * Rate limit max requests\n     * @type {number}\n     * @memberof RateLimitEntry\n     */\n    'limit'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/regenerate-api-key-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RegenerateApiKeyResponse\n */\nexport interface RegenerateApiKeyResponse {\n    /**\n     * The newly generated API key\n     * @type {string}\n     * @memberof RegenerateApiKeyResponse\n     */\n    'apiKey': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/region-quota.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RegionQuota\n */\nexport interface RegionQuota {\n    /**\n     * \n     * @type {string}\n     * @memberof RegionQuota\n     */\n    'organizationId': string;\n    /**\n     * \n     * @type {string}\n     * @memberof RegionQuota\n     */\n    'regionId': string;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionQuota\n     */\n    'totalCpuQuota': number;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionQuota\n     */\n    'totalMemoryQuota': number;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionQuota\n     */\n    'totalDiskQuota': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/region-screenshot-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RegionScreenshotResponse\n */\nexport interface RegionScreenshotResponse {\n    /**\n     * Base64 encoded screenshot image data of the specified region\n     * @type {string}\n     * @memberof RegionScreenshotResponse\n     */\n    'screenshot': string;\n    /**\n     * The current cursor position when the region screenshot was taken\n     * @type {object}\n     * @memberof RegionScreenshotResponse\n     */\n    'cursorPosition'?: object;\n    /**\n     * The size of the screenshot data in bytes\n     * @type {number}\n     * @memberof RegionScreenshotResponse\n     */\n    'sizeBytes'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/region-type.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * The type of the region\n * @export\n * @enum {string}\n */\n\nexport const RegionType = {\n    SHARED: 'shared',\n    DEDICATED: 'dedicated',\n    CUSTOM: 'custom'\n} as const;\n\nexport type RegionType = typeof RegionType[keyof typeof RegionType];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/region-usage-overview.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RegionUsageOverview\n */\nexport interface RegionUsageOverview {\n    /**\n     * \n     * @type {string}\n     * @memberof RegionUsageOverview\n     */\n    'regionId': string;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionUsageOverview\n     */\n    'totalCpuQuota': number;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionUsageOverview\n     */\n    'currentCpuUsage': number;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionUsageOverview\n     */\n    'totalMemoryQuota': number;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionUsageOverview\n     */\n    'currentMemoryUsage': number;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionUsageOverview\n     */\n    'totalDiskQuota': number;\n    /**\n     * \n     * @type {number}\n     * @memberof RegionUsageOverview\n     */\n    'currentDiskUsage': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/region.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RegionType } from './region-type';\n\n/**\n * \n * @export\n * @interface Region\n */\nexport interface Region {\n    /**\n     * Region ID\n     * @type {string}\n     * @memberof Region\n     */\n    'id': string;\n    /**\n     * Region name\n     * @type {string}\n     * @memberof Region\n     */\n    'name': string;\n    /**\n     * Organization ID\n     * @type {string}\n     * @memberof Region\n     */\n    'organizationId'?: string | null;\n    /**\n     * The type of the region\n     * @type {RegionType}\n     * @memberof Region\n     */\n    'regionType': RegionType;\n    /**\n     * Creation timestamp\n     * @type {string}\n     * @memberof Region\n     */\n    'createdAt': string;\n    /**\n     * Last update timestamp\n     * @type {string}\n     * @memberof Region\n     */\n    'updatedAt': string;\n    /**\n     * Proxy URL for the region\n     * @type {string}\n     * @memberof Region\n     */\n    'proxyUrl'?: string | null;\n    /**\n     * SSH Gateway URL for the region\n     * @type {string}\n     * @memberof Region\n     */\n    'sshGatewayUrl'?: string | null;\n    /**\n     * Snapshot Manager URL for the region\n     * @type {string}\n     * @memberof Region\n     */\n    'snapshotManagerUrl'?: string | null;\n}\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/registry-push-access-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RegistryPushAccessDto\n */\nexport interface RegistryPushAccessDto {\n    /**\n     * Temporary username for registry authentication\n     * @type {string}\n     * @memberof RegistryPushAccessDto\n     */\n    'username': string;\n    /**\n     * Temporary secret for registry authentication\n     * @type {string}\n     * @memberof RegistryPushAccessDto\n     */\n    'secret': string;\n    /**\n     * Registry URL\n     * @type {string}\n     * @memberof RegistryPushAccessDto\n     */\n    'registryUrl': string;\n    /**\n     * Registry ID\n     * @type {string}\n     * @memberof RegistryPushAccessDto\n     */\n    'registryId': string;\n    /**\n     * Registry project ID\n     * @type {string}\n     * @memberof RegistryPushAccessDto\n     */\n    'project': string;\n    /**\n     * Token expiration time in ISO format\n     * @type {string}\n     * @memberof RegistryPushAccessDto\n     */\n    'expiresAt': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/replace-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ReplaceRequest\n */\nexport interface ReplaceRequest {\n    /**\n     * \n     * @type {Array<string>}\n     * @memberof ReplaceRequest\n     */\n    'files': Array<string>;\n    /**\n     * \n     * @type {string}\n     * @memberof ReplaceRequest\n     */\n    'pattern': string;\n    /**\n     * \n     * @type {string}\n     * @memberof ReplaceRequest\n     */\n    'newValue': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/replace-result.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ReplaceResult\n */\nexport interface ReplaceResult {\n    /**\n     * \n     * @type {string}\n     * @memberof ReplaceResult\n     */\n    'file'?: string;\n    /**\n     * \n     * @type {boolean}\n     * @memberof ReplaceResult\n     */\n    'success'?: boolean;\n    /**\n     * \n     * @type {string}\n     * @memberof ReplaceResult\n     */\n    'error'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/resize-sandbox.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ResizeSandbox\n */\nexport interface ResizeSandbox {\n    /**\n     * CPU cores to allocate to the sandbox (minimum: 1)\n     * @type {number}\n     * @memberof ResizeSandbox\n     */\n    'cpu'?: number;\n    /**\n     * Memory in GB to allocate to the sandbox (minimum: 1)\n     * @type {number}\n     * @memberof ResizeSandbox\n     */\n    'memory'?: number;\n    /**\n     * Disk space in GB to allocate to the sandbox (can only be increased)\n     * @type {number}\n     * @memberof ResizeSandbox\n     */\n    'disk'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/runner-full.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RegionType } from './region-type';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RunnerState } from './runner-state';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxClass } from './sandbox-class';\n\n/**\n * \n * @export\n * @interface RunnerFull\n */\nexport interface RunnerFull {\n    /**\n     * The ID of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'id': string;\n    /**\n     * The domain of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'domain'?: string;\n    /**\n     * The API URL of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'apiUrl'?: string;\n    /**\n     * The proxy URL of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'proxyUrl'?: string;\n    /**\n     * The CPU capacity of the runner\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'cpu': number;\n    /**\n     * The memory capacity of the runner in GiB\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'memory': number;\n    /**\n     * The disk capacity of the runner in GiB\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'disk': number;\n    /**\n     * The GPU capacity of the runner\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'gpu'?: number;\n    /**\n     * The type of GPU\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'gpuType'?: string;\n    /**\n     * The class of the runner\n     * @type {SandboxClass}\n     * @memberof RunnerFull\n     */\n    'class': SandboxClass;\n    /**\n     * Current CPU usage percentage\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'currentCpuUsagePercentage'?: number;\n    /**\n     * Current RAM usage percentage\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'currentMemoryUsagePercentage'?: number;\n    /**\n     * Current disk usage percentage\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'currentDiskUsagePercentage'?: number;\n    /**\n     * Current allocated CPU\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'currentAllocatedCpu'?: number;\n    /**\n     * Current allocated memory in GiB\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'currentAllocatedMemoryGiB'?: number;\n    /**\n     * Current allocated disk in GiB\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'currentAllocatedDiskGiB'?: number;\n    /**\n     * Current snapshot count\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'currentSnapshotCount'?: number;\n    /**\n     * Current number of started sandboxes\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'currentStartedSandboxes'?: number;\n    /**\n     * Runner availability score\n     * @type {number}\n     * @memberof RunnerFull\n     */\n    'availabilityScore'?: number;\n    /**\n     * The region of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'region': string;\n    /**\n     * The name of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'name': string;\n    /**\n     * The state of the runner\n     * @type {RunnerState}\n     * @memberof RunnerFull\n     */\n    'state': RunnerState;\n    /**\n     * The last time the runner was checked\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'lastChecked'?: string;\n    /**\n     * Whether the runner is unschedulable\n     * @type {boolean}\n     * @memberof RunnerFull\n     */\n    'unschedulable': boolean;\n    /**\n     * The creation timestamp of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'createdAt': string;\n    /**\n     * The last update timestamp of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'updatedAt': string;\n    /**\n     * The version of the runner (deprecated in favor of apiVersion)\n     * @type {string}\n     * @memberof RunnerFull\n     * @deprecated\n     */\n    'version': string;\n    /**\n     * The api version of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     * @deprecated\n     */\n    'apiVersion': string;\n    /**\n     * The app version of the runner\n     * @type {string}\n     * @memberof RunnerFull\n     * @deprecated\n     */\n    'appVersion'?: string;\n    /**\n     * The API key for the runner\n     * @type {string}\n     * @memberof RunnerFull\n     */\n    'apiKey': string;\n    /**\n     * The region type of the runner\n     * @type {RegionType}\n     * @memberof RunnerFull\n     */\n    'regionType'?: RegionType;\n}\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/runner-health-metrics.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RunnerHealthMetrics\n */\nexport interface RunnerHealthMetrics {\n    /**\n     * Current CPU load average\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentCpuLoadAverage': number;\n    /**\n     * Current CPU usage percentage\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentCpuUsagePercentage': number;\n    /**\n     * Current memory usage percentage\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentMemoryUsagePercentage': number;\n    /**\n     * Current disk usage percentage\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentDiskUsagePercentage': number;\n    /**\n     * Currently allocated CPU cores\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentAllocatedCpu': number;\n    /**\n     * Currently allocated memory in GiB\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentAllocatedMemoryGiB': number;\n    /**\n     * Currently allocated disk in GiB\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentAllocatedDiskGiB': number;\n    /**\n     * Number of snapshots currently stored\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentSnapshotCount': number;\n    /**\n     * Number of started sandboxes\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'currentStartedSandboxes': number;\n    /**\n     * Total CPU cores on the runner\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'cpu': number;\n    /**\n     * Total RAM in GiB on the runner\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'memoryGiB': number;\n    /**\n     * Total disk space in GiB on the runner\n     * @type {number}\n     * @memberof RunnerHealthMetrics\n     */\n    'diskGiB': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/runner-healthcheck.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RunnerHealthMetrics } from './runner-health-metrics';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RunnerServiceHealth } from './runner-service-health';\n\n/**\n * \n * @export\n * @interface RunnerHealthcheck\n */\nexport interface RunnerHealthcheck {\n    /**\n     * Runner metrics\n     * @type {RunnerHealthMetrics}\n     * @memberof RunnerHealthcheck\n     */\n    'metrics'?: RunnerHealthMetrics;\n    /**\n     * Health status of individual services on the runner\n     * @type {Array<RunnerServiceHealth>}\n     * @memberof RunnerHealthcheck\n     */\n    'serviceHealth'?: Array<RunnerServiceHealth>;\n    /**\n     * Runner domain\n     * @type {string}\n     * @memberof RunnerHealthcheck\n     */\n    'domain'?: string;\n    /**\n     * Runner proxy URL\n     * @type {string}\n     * @memberof RunnerHealthcheck\n     */\n    'proxyUrl'?: string;\n    /**\n     * Runner API URL\n     * @type {string}\n     * @memberof RunnerHealthcheck\n     */\n    'apiUrl'?: string;\n    /**\n     * Runner app version\n     * @type {string}\n     * @memberof RunnerHealthcheck\n     */\n    'appVersion': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/runner-service-health.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RunnerServiceHealth\n */\nexport interface RunnerServiceHealth {\n    /**\n     * Name of the service being checked\n     * @type {string}\n     * @memberof RunnerServiceHealth\n     */\n    'serviceName': string;\n    /**\n     * Whether the service is healthy\n     * @type {boolean}\n     * @memberof RunnerServiceHealth\n     */\n    'healthy': boolean;\n    /**\n     * Error reason if the service is unhealthy\n     * @type {string}\n     * @memberof RunnerServiceHealth\n     */\n    'errorReason'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/runner-snapshot-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface RunnerSnapshotDto\n */\nexport interface RunnerSnapshotDto {\n    /**\n     * Runner snapshot ID\n     * @type {string}\n     * @memberof RunnerSnapshotDto\n     */\n    'runnerSnapshotId': string;\n    /**\n     * Runner ID\n     * @type {string}\n     * @memberof RunnerSnapshotDto\n     */\n    'runnerId': string;\n    /**\n     * Runner domain\n     * @type {string}\n     * @memberof RunnerSnapshotDto\n     */\n    'runnerDomain'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/runner-state.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * The state of the runner\n * @export\n * @enum {string}\n */\n\nexport const RunnerState = {\n    INITIALIZING: 'initializing',\n    READY: 'ready',\n    DISABLED: 'disabled',\n    DECOMMISSIONED: 'decommissioned',\n    UNRESPONSIVE: 'unresponsive'\n} as const;\n\nexport type RunnerState = typeof RunnerState[keyof typeof RunnerState];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/runner.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { RunnerState } from './runner-state';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxClass } from './sandbox-class';\n\n/**\n * \n * @export\n * @interface Runner\n */\nexport interface Runner {\n    /**\n     * The ID of the runner\n     * @type {string}\n     * @memberof Runner\n     */\n    'id': string;\n    /**\n     * The domain of the runner\n     * @type {string}\n     * @memberof Runner\n     */\n    'domain'?: string;\n    /**\n     * The API URL of the runner\n     * @type {string}\n     * @memberof Runner\n     */\n    'apiUrl'?: string;\n    /**\n     * The proxy URL of the runner\n     * @type {string}\n     * @memberof Runner\n     */\n    'proxyUrl'?: string;\n    /**\n     * The CPU capacity of the runner\n     * @type {number}\n     * @memberof Runner\n     */\n    'cpu': number;\n    /**\n     * The memory capacity of the runner in GiB\n     * @type {number}\n     * @memberof Runner\n     */\n    'memory': number;\n    /**\n     * The disk capacity of the runner in GiB\n     * @type {number}\n     * @memberof Runner\n     */\n    'disk': number;\n    /**\n     * The GPU capacity of the runner\n     * @type {number}\n     * @memberof Runner\n     */\n    'gpu'?: number;\n    /**\n     * The type of GPU\n     * @type {string}\n     * @memberof Runner\n     */\n    'gpuType'?: string;\n    /**\n     * The class of the runner\n     * @type {SandboxClass}\n     * @memberof Runner\n     */\n    'class': SandboxClass;\n    /**\n     * Current CPU usage percentage\n     * @type {number}\n     * @memberof Runner\n     */\n    'currentCpuUsagePercentage'?: number;\n    /**\n     * Current RAM usage percentage\n     * @type {number}\n     * @memberof Runner\n     */\n    'currentMemoryUsagePercentage'?: number;\n    /**\n     * Current disk usage percentage\n     * @type {number}\n     * @memberof Runner\n     */\n    'currentDiskUsagePercentage'?: number;\n    /**\n     * Current allocated CPU\n     * @type {number}\n     * @memberof Runner\n     */\n    'currentAllocatedCpu'?: number;\n    /**\n     * Current allocated memory in GiB\n     * @type {number}\n     * @memberof Runner\n     */\n    'currentAllocatedMemoryGiB'?: number;\n    /**\n     * Current allocated disk in GiB\n     * @type {number}\n     * @memberof Runner\n     */\n    'currentAllocatedDiskGiB'?: number;\n    /**\n     * Current snapshot count\n     * @type {number}\n     * @memberof Runner\n     */\n    'currentSnapshotCount'?: number;\n    /**\n     * Current number of started sandboxes\n     * @type {number}\n     * @memberof Runner\n     */\n    'currentStartedSandboxes'?: number;\n    /**\n     * Runner availability score\n     * @type {number}\n     * @memberof Runner\n     */\n    'availabilityScore'?: number;\n    /**\n     * The region of the runner\n     * @type {string}\n     * @memberof Runner\n     */\n    'region': string;\n    /**\n     * The name of the runner\n     * @type {string}\n     * @memberof Runner\n     */\n    'name': string;\n    /**\n     * The state of the runner\n     * @type {RunnerState}\n     * @memberof Runner\n     */\n    'state': RunnerState;\n    /**\n     * The last time the runner was checked\n     * @type {string}\n     * @memberof Runner\n     */\n    'lastChecked'?: string;\n    /**\n     * Whether the runner is unschedulable\n     * @type {boolean}\n     * @memberof Runner\n     */\n    'unschedulable': boolean;\n    /**\n     * The creation timestamp of the runner\n     * @type {string}\n     * @memberof Runner\n     */\n    'createdAt': string;\n    /**\n     * The last update timestamp of the runner\n     * @type {string}\n     * @memberof Runner\n     */\n    'updatedAt': string;\n    /**\n     * The version of the runner (deprecated in favor of apiVersion)\n     * @type {string}\n     * @memberof Runner\n     * @deprecated\n     */\n    'version': string;\n    /**\n     * The api version of the runner\n     * @type {string}\n     * @memberof Runner\n     * @deprecated\n     */\n    'apiVersion': string;\n    /**\n     * The app version of the runner\n     * @type {string}\n     * @memberof Runner\n     * @deprecated\n     */\n    'appVersion'?: string;\n}\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/sandbox-class.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * The class of the runner\n * @export\n * @enum {string}\n */\n\nexport const SandboxClass = {\n    SMALL: 'small',\n    MEDIUM: 'medium',\n    LARGE: 'large'\n} as const;\n\nexport type SandboxClass = typeof SandboxClass[keyof typeof SandboxClass];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/sandbox-desired-state.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * The desired state of the sandbox\n * @export\n * @enum {string}\n */\n\nexport const SandboxDesiredState = {\n    DESTROYED: 'destroyed',\n    STARTED: 'started',\n    STOPPED: 'stopped',\n    RESIZED: 'resized',\n    ARCHIVED: 'archived'\n} as const;\n\nexport type SandboxDesiredState = typeof SandboxDesiredState[keyof typeof SandboxDesiredState];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/sandbox-info.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SandboxInfo\n */\nexport interface SandboxInfo {\n    /**\n     * The creation timestamp of the project\n     * @type {string}\n     * @memberof SandboxInfo\n     */\n    'created': string;\n    /**\n     * Deprecated: The name of the sandbox\n     * @type {string}\n     * @memberof SandboxInfo\n     * @deprecated\n     */\n    'name': string;\n    /**\n     * Additional metadata provided by the provider\n     * @type {string}\n     * @memberof SandboxInfo\n     */\n    'providerMetadata'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/sandbox-labels.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SandboxLabels\n */\nexport interface SandboxLabels {\n    /**\n     * Key-value pairs of labels\n     * @type {{ [key: string]: string; }}\n     * @memberof SandboxLabels\n     */\n    'labels': { [key: string]: string; };\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/sandbox-state.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * The state of the sandbox\n * @export\n * @enum {string}\n */\n\nexport const SandboxState = {\n    CREATING: 'creating',\n    RESTORING: 'restoring',\n    DESTROYED: 'destroyed',\n    DESTROYING: 'destroying',\n    STARTED: 'started',\n    STOPPED: 'stopped',\n    STARTING: 'starting',\n    STOPPING: 'stopping',\n    ERROR: 'error',\n    BUILD_FAILED: 'build_failed',\n    PENDING_BUILD: 'pending_build',\n    BUILDING_SNAPSHOT: 'building_snapshot',\n    UNKNOWN: 'unknown',\n    PULLING_SNAPSHOT: 'pulling_snapshot',\n    ARCHIVED: 'archived',\n    ARCHIVING: 'archiving',\n    RESIZING: 'resizing'\n} as const;\n\nexport type SandboxState = typeof SandboxState[keyof typeof SandboxState];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/sandbox-volume.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SandboxVolume\n */\nexport interface SandboxVolume {\n    /**\n     * The ID of the volume\n     * @type {string}\n     * @memberof SandboxVolume\n     */\n    'volumeId': string;\n    /**\n     * The mount path for the volume\n     * @type {string}\n     * @memberof SandboxVolume\n     */\n    'mountPath': string;\n    /**\n     * Optional subpath within the volume to mount. When specified, only this S3 prefix will be accessible. When omitted, the entire volume is mounted.\n     * @type {string}\n     * @memberof SandboxVolume\n     */\n    'subpath'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/sandbox.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { BuildInfo } from './build-info';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxDesiredState } from './sandbox-desired-state';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxState } from './sandbox-state';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxVolume } from './sandbox-volume';\n\n/**\n * \n * @export\n * @interface Sandbox\n */\nexport interface Sandbox {\n    /**\n     * The ID of the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'id': string;\n    /**\n     * The organization ID of the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'organizationId': string;\n    /**\n     * The name of the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'name': string;\n    /**\n     * The snapshot used for the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'snapshot'?: string;\n    /**\n     * The user associated with the project\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'user': string;\n    /**\n     * Environment variables for the sandbox\n     * @type {{ [key: string]: string; }}\n     * @memberof Sandbox\n     */\n    'env': { [key: string]: string; };\n    /**\n     * Labels for the sandbox\n     * @type {{ [key: string]: string; }}\n     * @memberof Sandbox\n     */\n    'labels': { [key: string]: string; };\n    /**\n     * Whether the sandbox http preview is public\n     * @type {boolean}\n     * @memberof Sandbox\n     */\n    'public': boolean;\n    /**\n     * Whether to block all network access for the sandbox\n     * @type {boolean}\n     * @memberof Sandbox\n     */\n    'networkBlockAll': boolean;\n    /**\n     * Comma-separated list of allowed CIDR network addresses for the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'networkAllowList'?: string;\n    /**\n     * The target environment for the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'target': string;\n    /**\n     * The CPU quota for the sandbox\n     * @type {number}\n     * @memberof Sandbox\n     */\n    'cpu': number;\n    /**\n     * The GPU quota for the sandbox\n     * @type {number}\n     * @memberof Sandbox\n     */\n    'gpu': number;\n    /**\n     * The memory quota for the sandbox\n     * @type {number}\n     * @memberof Sandbox\n     */\n    'memory': number;\n    /**\n     * The disk quota for the sandbox\n     * @type {number}\n     * @memberof Sandbox\n     */\n    'disk': number;\n    /**\n     * The state of the sandbox\n     * @type {SandboxState}\n     * @memberof Sandbox\n     */\n    'state'?: SandboxState;\n    /**\n     * The desired state of the sandbox\n     * @type {SandboxDesiredState}\n     * @memberof Sandbox\n     */\n    'desiredState'?: SandboxDesiredState;\n    /**\n     * The error reason of the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'errorReason'?: string;\n    /**\n     * Whether the sandbox error is recoverable.\n     * @type {boolean}\n     * @memberof Sandbox\n     */\n    'recoverable'?: boolean;\n    /**\n     * The state of the backup\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'backupState'?: SandboxBackupStateEnum;\n    /**\n     * The creation timestamp of the last backup\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'backupCreatedAt'?: string;\n    /**\n     * Auto-stop interval in minutes (0 means disabled)\n     * @type {number}\n     * @memberof Sandbox\n     */\n    'autoStopInterval'?: number;\n    /**\n     * Auto-archive interval in minutes\n     * @type {number}\n     * @memberof Sandbox\n     */\n    'autoArchiveInterval'?: number;\n    /**\n     * Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n     * @type {number}\n     * @memberof Sandbox\n     */\n    'autoDeleteInterval'?: number;\n    /**\n     * Array of volumes attached to the sandbox\n     * @type {Array<SandboxVolume>}\n     * @memberof Sandbox\n     */\n    'volumes'?: Array<SandboxVolume>;\n    /**\n     * Build information for the sandbox\n     * @type {BuildInfo}\n     * @memberof Sandbox\n     */\n    'buildInfo'?: BuildInfo;\n    /**\n     * The creation timestamp of the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'createdAt'?: string;\n    /**\n     * The last update timestamp of the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'updatedAt'?: string;\n    /**\n     * The class of the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     * @deprecated\n     */\n    'class'?: SandboxClassEnum;\n    /**\n     * The version of the daemon running in the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'daemonVersion'?: string;\n    /**\n     * The runner ID of the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'runnerId'?: string;\n    /**\n     * The toolbox proxy URL for the sandbox\n     * @type {string}\n     * @memberof Sandbox\n     */\n    'toolboxProxyUrl': string;\n}\n\nexport const SandboxBackupStateEnum = {\n    NONE: 'None',\n    PENDING: 'Pending',\n    IN_PROGRESS: 'InProgress',\n    COMPLETED: 'Completed',\n    ERROR: 'Error'\n} as const;\n\nexport type SandboxBackupStateEnum = typeof SandboxBackupStateEnum[keyof typeof SandboxBackupStateEnum];\nexport const SandboxClassEnum = {\n    SMALL: 'small',\n    MEDIUM: 'medium',\n    LARGE: 'large'\n} as const;\n\nexport type SandboxClassEnum = typeof SandboxClassEnum[keyof typeof SandboxClassEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/screenshot-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ScreenshotResponse\n */\nexport interface ScreenshotResponse {\n    /**\n     * Base64 encoded screenshot image data\n     * @type {string}\n     * @memberof ScreenshotResponse\n     */\n    'screenshot': string;\n    /**\n     * The current cursor position when the screenshot was taken\n     * @type {object}\n     * @memberof ScreenshotResponse\n     */\n    'cursorPosition'?: object;\n    /**\n     * The size of the screenshot data in bytes\n     * @type {number}\n     * @memberof ScreenshotResponse\n     */\n    'sizeBytes'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/search-files-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SearchFilesResponse\n */\nexport interface SearchFilesResponse {\n    /**\n     * \n     * @type {Array<string>}\n     * @memberof SearchFilesResponse\n     */\n    'files': Array<string>;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/send-webhook-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { WebhookEvent } from './webhook-event';\n\n/**\n * \n * @export\n * @interface SendWebhookDto\n */\nexport interface SendWebhookDto {\n    /**\n     * The type of event being sent\n     * @type {WebhookEvent}\n     * @memberof SendWebhookDto\n     */\n    'eventType': WebhookEvent;\n    /**\n     * The payload data to send\n     * @type {object}\n     * @memberof SendWebhookDto\n     */\n    'payload': object;\n    /**\n     * Optional event ID for idempotency\n     * @type {string}\n     * @memberof SendWebhookDto\n     */\n    'eventId'?: string;\n}\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/session-execute-request.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SessionExecuteRequest\n */\nexport interface SessionExecuteRequest {\n    /**\n     * The command to execute\n     * @type {string}\n     * @memberof SessionExecuteRequest\n     */\n    'command': string;\n    /**\n     * Whether to execute the command asynchronously\n     * @type {boolean}\n     * @memberof SessionExecuteRequest\n     */\n    'runAsync'?: boolean;\n    /**\n     * Deprecated: Use runAsync instead. Whether to execute the command asynchronously\n     * @type {boolean}\n     * @memberof SessionExecuteRequest\n     * @deprecated\n     */\n    'async'?: boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/session-execute-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SessionExecuteResponse\n */\nexport interface SessionExecuteResponse {\n    /**\n     * The ID of the executed command\n     * @type {string}\n     * @memberof SessionExecuteResponse\n     */\n    'cmdId'?: string;\n    /**\n     * The output of the executed command marked with stdout and stderr prefixes\n     * @type {string}\n     * @memberof SessionExecuteResponse\n     */\n    'output'?: string;\n    /**\n     * The exit code of the executed command\n     * @type {number}\n     * @memberof SessionExecuteResponse\n     */\n    'exitCode'?: number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/session.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { Command } from './command';\n\n/**\n * \n * @export\n * @interface Session\n */\nexport interface Session {\n    /**\n     * The ID of the session\n     * @type {string}\n     * @memberof Session\n     */\n    'sessionId': string;\n    /**\n     * The list of commands executed in this session\n     * @type {Array<Command>}\n     * @memberof Session\n     */\n    'commands': Array<Command> | null;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/set-snapshot-general-status-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SetSnapshotGeneralStatusDto\n */\nexport interface SetSnapshotGeneralStatusDto {\n    /**\n     * Whether the snapshot is general\n     * @type {boolean}\n     * @memberof SetSnapshotGeneralStatusDto\n     */\n    'general': boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/signed-port-preview-url.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SignedPortPreviewUrl\n */\nexport interface SignedPortPreviewUrl {\n    /**\n     * ID of the sandbox\n     * @type {string}\n     * @memberof SignedPortPreviewUrl\n     */\n    'sandboxId': string;\n    /**\n     * Port number of the signed preview URL\n     * @type {number}\n     * @memberof SignedPortPreviewUrl\n     */\n    'port': number;\n    /**\n     * Token of the signed preview URL\n     * @type {string}\n     * @memberof SignedPortPreviewUrl\n     */\n    'token': string;\n    /**\n     * Signed preview url\n     * @type {string}\n     * @memberof SignedPortPreviewUrl\n     */\n    'url': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/snapshot-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { BuildInfo } from './build-info';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SnapshotState } from './snapshot-state';\n\n/**\n * \n * @export\n * @interface SnapshotDto\n */\nexport interface SnapshotDto {\n    /**\n     * \n     * @type {string}\n     * @memberof SnapshotDto\n     */\n    'id': string;\n    /**\n     * \n     * @type {string}\n     * @memberof SnapshotDto\n     */\n    'organizationId'?: string;\n    /**\n     * \n     * @type {boolean}\n     * @memberof SnapshotDto\n     */\n    'general': boolean;\n    /**\n     * \n     * @type {string}\n     * @memberof SnapshotDto\n     */\n    'name': string;\n    /**\n     * \n     * @type {string}\n     * @memberof SnapshotDto\n     */\n    'imageName'?: string;\n    /**\n     * \n     * @type {SnapshotState}\n     * @memberof SnapshotDto\n     */\n    'state': SnapshotState;\n    /**\n     * \n     * @type {number}\n     * @memberof SnapshotDto\n     */\n    'size': number | null;\n    /**\n     * \n     * @type {Array<string>}\n     * @memberof SnapshotDto\n     */\n    'entrypoint': Array<string> | null;\n    /**\n     * \n     * @type {number}\n     * @memberof SnapshotDto\n     */\n    'cpu': number;\n    /**\n     * \n     * @type {number}\n     * @memberof SnapshotDto\n     */\n    'gpu': number;\n    /**\n     * \n     * @type {number}\n     * @memberof SnapshotDto\n     */\n    'mem': number;\n    /**\n     * \n     * @type {number}\n     * @memberof SnapshotDto\n     */\n    'disk': number;\n    /**\n     * \n     * @type {string}\n     * @memberof SnapshotDto\n     */\n    'errorReason': string | null;\n    /**\n     * \n     * @type {Date}\n     * @memberof SnapshotDto\n     */\n    'createdAt': Date;\n    /**\n     * \n     * @type {Date}\n     * @memberof SnapshotDto\n     */\n    'updatedAt': Date;\n    /**\n     * \n     * @type {Date}\n     * @memberof SnapshotDto\n     */\n    'lastUsedAt': Date | null;\n    /**\n     * Build information for the snapshot\n     * @type {BuildInfo}\n     * @memberof SnapshotDto\n     */\n    'buildInfo'?: BuildInfo;\n    /**\n     * IDs of regions where the snapshot is available\n     * @type {Array<string>}\n     * @memberof SnapshotDto\n     */\n    'regionIds'?: Array<string>;\n    /**\n     * The initial runner ID of the snapshot\n     * @type {string}\n     * @memberof SnapshotDto\n     */\n    'initialRunnerId'?: string;\n    /**\n     * The snapshot reference\n     * @type {string}\n     * @memberof SnapshotDto\n     */\n    'ref'?: string;\n}\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/snapshot-manager-credentials.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SnapshotManagerCredentials\n */\nexport interface SnapshotManagerCredentials {\n    /**\n     * Snapshot Manager username for the region\n     * @type {string}\n     * @memberof SnapshotManagerCredentials\n     */\n    'username': string;\n    /**\n     * Snapshot Manager password for the region\n     * @type {string}\n     * @memberof SnapshotManagerCredentials\n     */\n    'password': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/snapshot-state.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @enum {string}\n */\n\nexport const SnapshotState = {\n    BUILDING: 'building',\n    PENDING: 'pending',\n    PULLING: 'pulling',\n    ACTIVE: 'active',\n    INACTIVE: 'inactive',\n    ERROR: 'error',\n    BUILD_FAILED: 'build_failed',\n    REMOVING: 'removing'\n} as const;\n\nexport type SnapshotState = typeof SnapshotState[keyof typeof SnapshotState];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/ssh-access-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SshAccessDto\n */\nexport interface SshAccessDto {\n    /**\n     * Unique identifier for the SSH access\n     * @type {string}\n     * @memberof SshAccessDto\n     */\n    'id': string;\n    /**\n     * ID of the sandbox this SSH access is for\n     * @type {string}\n     * @memberof SshAccessDto\n     */\n    'sandboxId': string;\n    /**\n     * SSH access token\n     * @type {string}\n     * @memberof SshAccessDto\n     */\n    'token': string;\n    /**\n     * When the SSH access expires\n     * @type {Date}\n     * @memberof SshAccessDto\n     */\n    'expiresAt': Date;\n    /**\n     * When the SSH access was created\n     * @type {Date}\n     * @memberof SshAccessDto\n     */\n    'createdAt': Date;\n    /**\n     * When the SSH access was last updated\n     * @type {Date}\n     * @memberof SshAccessDto\n     */\n    'updatedAt': Date;\n    /**\n     * SSH command to connect to the sandbox\n     * @type {string}\n     * @memberof SshAccessDto\n     */\n    'sshCommand': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/ssh-access-validation-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface SshAccessValidationDto\n */\nexport interface SshAccessValidationDto {\n    /**\n     * Whether the SSH access token is valid\n     * @type {boolean}\n     * @memberof SshAccessValidationDto\n     */\n    'valid': boolean;\n    /**\n     * ID of the sandbox this SSH access is for\n     * @type {string}\n     * @memberof SshAccessValidationDto\n     */\n    'sandboxId': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/storage-access-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface StorageAccessDto\n */\nexport interface StorageAccessDto {\n    /**\n     * Access key for storage authentication\n     * @type {string}\n     * @memberof StorageAccessDto\n     */\n    'accessKey': string;\n    /**\n     * Secret key for storage authentication\n     * @type {string}\n     * @memberof StorageAccessDto\n     */\n    'secret': string;\n    /**\n     * Session token for storage authentication\n     * @type {string}\n     * @memberof StorageAccessDto\n     */\n    'sessionToken': string;\n    /**\n     * Storage URL\n     * @type {string}\n     * @memberof StorageAccessDto\n     */\n    'storageUrl': string;\n    /**\n     * Organization ID\n     * @type {string}\n     * @memberof StorageAccessDto\n     */\n    'organizationId': string;\n    /**\n     * S3 bucket name\n     * @type {string}\n     * @memberof StorageAccessDto\n     */\n    'bucket': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/toolbox-proxy-url.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface ToolboxProxyUrl\n */\nexport interface ToolboxProxyUrl {\n    /**\n     * The toolbox proxy URL for the sandbox\n     * @type {string}\n     * @memberof ToolboxProxyUrl\n     */\n    'url': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/trace-span.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface TraceSpan\n */\nexport interface TraceSpan {\n    /**\n     * Trace identifier\n     * @type {string}\n     * @memberof TraceSpan\n     */\n    'traceId': string;\n    /**\n     * Span identifier\n     * @type {string}\n     * @memberof TraceSpan\n     */\n    'spanId': string;\n    /**\n     * Parent span identifier\n     * @type {string}\n     * @memberof TraceSpan\n     */\n    'parentSpanId'?: string;\n    /**\n     * Span name\n     * @type {string}\n     * @memberof TraceSpan\n     */\n    'spanName': string;\n    /**\n     * Span start timestamp\n     * @type {string}\n     * @memberof TraceSpan\n     */\n    'timestamp': string;\n    /**\n     * Span duration in nanoseconds\n     * @type {number}\n     * @memberof TraceSpan\n     */\n    'durationNs': number;\n    /**\n     * Span attributes\n     * @type {{ [key: string]: string; }}\n     * @memberof TraceSpan\n     */\n    'spanAttributes': { [key: string]: string; };\n    /**\n     * Status code of the span\n     * @type {string}\n     * @memberof TraceSpan\n     */\n    'statusCode'?: string;\n    /**\n     * Status message\n     * @type {string}\n     * @memberof TraceSpan\n     */\n    'statusMessage'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/trace-summary.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface TraceSummary\n */\nexport interface TraceSummary {\n    /**\n     * Unique trace identifier\n     * @type {string}\n     * @memberof TraceSummary\n     */\n    'traceId': string;\n    /**\n     * Name of the root span\n     * @type {string}\n     * @memberof TraceSummary\n     */\n    'rootSpanName': string;\n    /**\n     * Trace start time\n     * @type {string}\n     * @memberof TraceSummary\n     */\n    'startTime': string;\n    /**\n     * Trace end time\n     * @type {string}\n     * @memberof TraceSummary\n     */\n    'endTime': string;\n    /**\n     * Total duration in milliseconds\n     * @type {number}\n     * @memberof TraceSummary\n     */\n    'durationMs': number;\n    /**\n     * Number of spans in this trace\n     * @type {number}\n     * @memberof TraceSummary\n     */\n    'spanCount': number;\n    /**\n     * Status code of the trace\n     * @type {string}\n     * @memberof TraceSummary\n     */\n    'statusCode'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-docker-registry.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateDockerRegistry\n */\nexport interface UpdateDockerRegistry {\n    /**\n     * Registry name\n     * @type {string}\n     * @memberof UpdateDockerRegistry\n     */\n    'name': string;\n    /**\n     * Registry URL\n     * @type {string}\n     * @memberof UpdateDockerRegistry\n     */\n    'url': string;\n    /**\n     * Registry username\n     * @type {string}\n     * @memberof UpdateDockerRegistry\n     */\n    'username': string;\n    /**\n     * Registry password\n     * @type {string}\n     * @memberof UpdateDockerRegistry\n     */\n    'password'?: string;\n    /**\n     * Registry project\n     * @type {string}\n     * @memberof UpdateDockerRegistry\n     */\n    'project'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-job-status.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { JobStatus } from './job-status';\n\n/**\n * \n * @export\n * @interface UpdateJobStatus\n */\nexport interface UpdateJobStatus {\n    /**\n     * The new status of the job\n     * @type {JobStatus}\n     * @memberof UpdateJobStatus\n     */\n    'status': JobStatus;\n    /**\n     * Error message if the job failed\n     * @type {string}\n     * @memberof UpdateJobStatus\n     */\n    'errorMessage'?: string;\n    /**\n     * Result metadata for the job\n     * @type {string}\n     * @memberof UpdateJobStatus\n     */\n    'resultMetadata'?: string;\n}\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-organization-default-region.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateOrganizationDefaultRegion\n */\nexport interface UpdateOrganizationDefaultRegion {\n    /**\n     * The ID of the default region for the organization\n     * @type {string}\n     * @memberof UpdateOrganizationDefaultRegion\n     */\n    'defaultRegionId': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-organization-invitation.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateOrganizationInvitation\n */\nexport interface UpdateOrganizationInvitation {\n    /**\n     * Organization member role\n     * @type {string}\n     * @memberof UpdateOrganizationInvitation\n     */\n    'role': UpdateOrganizationInvitationRoleEnum;\n    /**\n     * Array of role IDs\n     * @type {Array<string>}\n     * @memberof UpdateOrganizationInvitation\n     */\n    'assignedRoleIds': Array<string>;\n    /**\n     * Expiration date of the invitation\n     * @type {Date}\n     * @memberof UpdateOrganizationInvitation\n     */\n    'expiresAt'?: Date;\n}\n\nexport const UpdateOrganizationInvitationRoleEnum = {\n    OWNER: 'owner',\n    MEMBER: 'member'\n} as const;\n\nexport type UpdateOrganizationInvitationRoleEnum = typeof UpdateOrganizationInvitationRoleEnum[keyof typeof UpdateOrganizationInvitationRoleEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-organization-member-access.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateOrganizationMemberAccess\n */\nexport interface UpdateOrganizationMemberAccess {\n    /**\n     * Organization member role\n     * @type {string}\n     * @memberof UpdateOrganizationMemberAccess\n     */\n    'role': UpdateOrganizationMemberAccessRoleEnum;\n    /**\n     * Array of assigned role IDs\n     * @type {Array<string>}\n     * @memberof UpdateOrganizationMemberAccess\n     */\n    'assignedRoleIds': Array<string>;\n}\n\nexport const UpdateOrganizationMemberAccessRoleEnum = {\n    OWNER: 'owner',\n    MEMBER: 'member'\n} as const;\n\nexport type UpdateOrganizationMemberAccessRoleEnum = typeof UpdateOrganizationMemberAccessRoleEnum[keyof typeof UpdateOrganizationMemberAccessRoleEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-organization-quota.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateOrganizationQuota\n */\nexport interface UpdateOrganizationQuota {\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'maxCpuPerSandbox': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'maxMemoryPerSandbox': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'maxDiskPerSandbox': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'snapshotQuota': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'maxSnapshotSize': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'volumeQuota': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'authenticatedRateLimit': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'sandboxCreateRateLimit': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'sandboxLifecycleRateLimit': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'authenticatedRateLimitTtlSeconds': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'sandboxCreateRateLimitTtlSeconds': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'sandboxLifecycleRateLimitTtlSeconds': number | null;\n    /**\n     * Time in minutes before an unused snapshot is deactivated\n     * @type {number}\n     * @memberof UpdateOrganizationQuota\n     */\n    'snapshotDeactivationTimeoutMinutes': number | null;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-organization-region-quota.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateOrganizationRegionQuota\n */\nexport interface UpdateOrganizationRegionQuota {\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationRegionQuota\n     */\n    'totalCpuQuota': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationRegionQuota\n     */\n    'totalMemoryQuota': number | null;\n    /**\n     * \n     * @type {number}\n     * @memberof UpdateOrganizationRegionQuota\n     */\n    'totalDiskQuota': number | null;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-organization-role.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateOrganizationRole\n */\nexport interface UpdateOrganizationRole {\n    /**\n     * The name of the role\n     * @type {string}\n     * @memberof UpdateOrganizationRole\n     */\n    'name': string;\n    /**\n     * The description of the role\n     * @type {string}\n     * @memberof UpdateOrganizationRole\n     */\n    'description': string;\n    /**\n     * The list of permissions assigned to the role\n     * @type {Array<string>}\n     * @memberof UpdateOrganizationRole\n     */\n    'permissions': Array<UpdateOrganizationRolePermissionsEnum>;\n}\n\nexport const UpdateOrganizationRolePermissionsEnum = {\n    WRITE_REGISTRIES: 'write:registries',\n    DELETE_REGISTRIES: 'delete:registries',\n    WRITE_SNAPSHOTS: 'write:snapshots',\n    DELETE_SNAPSHOTS: 'delete:snapshots',\n    WRITE_SANDBOXES: 'write:sandboxes',\n    DELETE_SANDBOXES: 'delete:sandboxes',\n    READ_VOLUMES: 'read:volumes',\n    WRITE_VOLUMES: 'write:volumes',\n    DELETE_VOLUMES: 'delete:volumes',\n    WRITE_REGIONS: 'write:regions',\n    DELETE_REGIONS: 'delete:regions',\n    READ_RUNNERS: 'read:runners',\n    WRITE_RUNNERS: 'write:runners',\n    DELETE_RUNNERS: 'delete:runners',\n    READ_AUDIT_LOGS: 'read:audit_logs'\n} as const;\n\nexport type UpdateOrganizationRolePermissionsEnum = typeof UpdateOrganizationRolePermissionsEnum[keyof typeof UpdateOrganizationRolePermissionsEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-region.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateRegion\n */\nexport interface UpdateRegion {\n    /**\n     * Proxy URL for the region\n     * @type {string}\n     * @memberof UpdateRegion\n     */\n    'proxyUrl'?: string | null;\n    /**\n     * SSH Gateway URL for the region\n     * @type {string}\n     * @memberof UpdateRegion\n     */\n    'sshGatewayUrl'?: string | null;\n    /**\n     * Snapshot Manager URL for the region\n     * @type {string}\n     * @memberof UpdateRegion\n     */\n    'snapshotManagerUrl'?: string | null;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/update-sandbox-state-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UpdateSandboxStateDto\n */\nexport interface UpdateSandboxStateDto {\n    /**\n     * The new state for the sandbox\n     * @type {string}\n     * @memberof UpdateSandboxStateDto\n     */\n    'state': UpdateSandboxStateDtoStateEnum;\n    /**\n     * Optional error message when reporting an error state\n     * @type {string}\n     * @memberof UpdateSandboxStateDto\n     */\n    'errorReason'?: string;\n    /**\n     * Whether the sandbox is recoverable\n     * @type {boolean}\n     * @memberof UpdateSandboxStateDto\n     */\n    'recoverable'?: boolean;\n}\n\nexport const UpdateSandboxStateDtoStateEnum = {\n    CREATING: 'creating',\n    RESTORING: 'restoring',\n    DESTROYED: 'destroyed',\n    DESTROYING: 'destroying',\n    STARTED: 'started',\n    STOPPED: 'stopped',\n    STARTING: 'starting',\n    STOPPING: 'stopping',\n    ERROR: 'error',\n    BUILD_FAILED: 'build_failed',\n    PENDING_BUILD: 'pending_build',\n    BUILDING_SNAPSHOT: 'building_snapshot',\n    UNKNOWN: 'unknown',\n    PULLING_SNAPSHOT: 'pulling_snapshot',\n    ARCHIVED: 'archived',\n    ARCHIVING: 'archiving',\n    RESIZING: 'resizing'\n} as const;\n\nexport type UpdateSandboxStateDtoStateEnum = typeof UpdateSandboxStateDtoStateEnum[keyof typeof UpdateSandboxStateDtoStateEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/url.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface Url\n */\nexport interface Url {\n    /**\n     * URL response\n     * @type {string}\n     * @memberof Url\n     */\n    'url': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/user-home-dir-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UserHomeDirResponse\n */\nexport interface UserHomeDirResponse {\n    /**\n     * \n     * @type {string}\n     * @memberof UserHomeDirResponse\n     */\n    'dir'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/user-public-key.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface UserPublicKey\n */\nexport interface UserPublicKey {\n    /**\n     * Public key\n     * @type {string}\n     * @memberof UserPublicKey\n     */\n    'key': string;\n    /**\n     * Key name\n     * @type {string}\n     * @memberof UserPublicKey\n     */\n    'name': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/user.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { UserPublicKey } from './user-public-key';\n\n/**\n * \n * @export\n * @interface User\n */\nexport interface User {\n    /**\n     * User ID\n     * @type {string}\n     * @memberof User\n     */\n    'id': string;\n    /**\n     * User name\n     * @type {string}\n     * @memberof User\n     */\n    'name': string;\n    /**\n     * User email\n     * @type {string}\n     * @memberof User\n     */\n    'email': string;\n    /**\n     * User public keys\n     * @type {Array<UserPublicKey>}\n     * @memberof User\n     */\n    'publicKeys': Array<UserPublicKey>;\n    /**\n     * Creation timestamp\n     * @type {Date}\n     * @memberof User\n     */\n    'createdAt': Date;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/volume-dto.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { VolumeState } from './volume-state';\n\n/**\n * \n * @export\n * @interface VolumeDto\n */\nexport interface VolumeDto {\n    /**\n     * Volume ID\n     * @type {string}\n     * @memberof VolumeDto\n     */\n    'id': string;\n    /**\n     * Volume name\n     * @type {string}\n     * @memberof VolumeDto\n     */\n    'name': string;\n    /**\n     * Organization ID\n     * @type {string}\n     * @memberof VolumeDto\n     */\n    'organizationId': string;\n    /**\n     * Volume state\n     * @type {VolumeState}\n     * @memberof VolumeDto\n     */\n    'state': VolumeState;\n    /**\n     * Creation timestamp\n     * @type {string}\n     * @memberof VolumeDto\n     */\n    'createdAt': string;\n    /**\n     * Last update timestamp\n     * @type {string}\n     * @memberof VolumeDto\n     */\n    'updatedAt': string;\n    /**\n     * Last used timestamp\n     * @type {string}\n     * @memberof VolumeDto\n     */\n    'lastUsedAt'?: string | null;\n    /**\n     * The error reason of the volume\n     * @type {string}\n     * @memberof VolumeDto\n     */\n    'errorReason': string | null;\n}\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/volume-state.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * Volume state\n * @export\n * @enum {string}\n */\n\nexport const VolumeState = {\n    CREATING: 'creating',\n    READY: 'ready',\n    PENDING_CREATE: 'pending_create',\n    PENDING_DELETE: 'pending_delete',\n    DELETING: 'deleting',\n    DELETED: 'deleted',\n    ERROR: 'error'\n} as const;\n\nexport type VolumeState = typeof VolumeState[keyof typeof VolumeState];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/webhook-app-portal-access.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface WebhookAppPortalAccess\n */\nexport interface WebhookAppPortalAccess {\n    /**\n     * The authentication token for the Svix consumer app portal\n     * @type {string}\n     * @memberof WebhookAppPortalAccess\n     */\n    'token': string;\n    /**\n     * The URL to the webhook app portal\n     * @type {string}\n     * @memberof WebhookAppPortalAccess\n     */\n    'url': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/webhook-controller-get-status200-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface WebhookControllerGetStatus200Response\n */\nexport interface WebhookControllerGetStatus200Response {\n    /**\n     * \n     * @type {boolean}\n     * @memberof WebhookControllerGetStatus200Response\n     */\n    'enabled'?: boolean;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/webhook-event.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * The type of event being sent\n * @export\n * @enum {string}\n */\n\nexport const WebhookEvent = {\n    SANDBOX_CREATED: 'sandbox.created',\n    SANDBOX_STATE_UPDATED: 'sandbox.state.updated',\n    SNAPSHOT_CREATED: 'snapshot.created',\n    SNAPSHOT_STATE_UPDATED: 'snapshot.state.updated',\n    SNAPSHOT_REMOVED: 'snapshot.removed',\n    VOLUME_CREATED: 'volume.created',\n    VOLUME_STATE_UPDATED: 'volume.state.updated'\n} as const;\n\nexport type WebhookEvent = typeof WebhookEvent[keyof typeof WebhookEvent];\n\n\n\n"
  },
  {
    "path": "libs/api-client/src/models/webhook-initialization-status.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface WebhookInitializationStatus\n */\nexport interface WebhookInitializationStatus {\n    /**\n     * Organization ID\n     * @type {string}\n     * @memberof WebhookInitializationStatus\n     */\n    'organizationId': string;\n    /**\n     * The ID of the Svix application\n     * @type {string}\n     * @memberof WebhookInitializationStatus\n     */\n    'svixApplicationId': string | null;\n    /**\n     * The error reason for the last initialization attempt\n     * @type {string}\n     * @memberof WebhookInitializationStatus\n     */\n    'lastError': string | null;\n    /**\n     * The number of times the initialization has been attempted\n     * @type {number}\n     * @memberof WebhookInitializationStatus\n     */\n    'retryCount': number;\n    /**\n     * When the webhook initialization was created\n     * @type {string}\n     * @memberof WebhookInitializationStatus\n     */\n    'createdAt': string;\n    /**\n     * When the webhook initialization was last updated\n     * @type {string}\n     * @memberof WebhookInitializationStatus\n     */\n    'updatedAt': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/windows-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface WindowsResponse\n */\nexport interface WindowsResponse {\n    /**\n     * Array of window information for all visible windows\n     * @type {Array<object>}\n     * @memberof WindowsResponse\n     */\n    'windows': Array<object>;\n    /**\n     * The total number of windows found\n     * @type {number}\n     * @memberof WindowsResponse\n     */\n    'count': number;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/work-dir-response.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface WorkDirResponse\n */\nexport interface WorkDirResponse {\n    /**\n     * \n     * @type {string}\n     * @memberof WorkDirResponse\n     */\n    'dir'?: string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/workspace-port-preview-url.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n\n/**\n * \n * @export\n * @interface WorkspacePortPreviewUrl\n */\nexport interface WorkspacePortPreviewUrl {\n    /**\n     * Preview url\n     * @type {string}\n     * @memberof WorkspacePortPreviewUrl\n     */\n    'url': string;\n    /**\n     * Access token\n     * @type {string}\n     * @memberof WorkspacePortPreviewUrl\n     */\n    'token': string;\n}\n\n"
  },
  {
    "path": "libs/api-client/src/models/workspace.ts",
    "content": "/* tslint:disable */\n/* eslint-disable */\n/**\n * Daytona\n * Daytona AI platform API Docs\n *\n * The version of the OpenAPI document: 1.0\n * Contact: support@daytona.com\n *\n * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).\n * https://openapi-generator.tech\n * Do not edit the class manually.\n */\n\n\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { BuildInfo } from './build-info';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxDesiredState } from './sandbox-desired-state';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxInfo } from './sandbox-info';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxState } from './sandbox-state';\n// May contain unused imports in some cases\n// @ts-ignore\nimport type { SandboxVolume } from './sandbox-volume';\n\n/**\n * \n * @export\n * @interface Workspace\n */\nexport interface Workspace {\n    /**\n     * The ID of the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'id': string;\n    /**\n     * The organization ID of the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'organizationId': string;\n    /**\n     * The name of the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'name': string;\n    /**\n     * The snapshot used for the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'snapshot'?: string;\n    /**\n     * The user associated with the project\n     * @type {string}\n     * @memberof Workspace\n     */\n    'user': string;\n    /**\n     * Environment variables for the sandbox\n     * @type {{ [key: string]: string; }}\n     * @memberof Workspace\n     */\n    'env': { [key: string]: string; };\n    /**\n     * Labels for the sandbox\n     * @type {{ [key: string]: string; }}\n     * @memberof Workspace\n     */\n    'labels': { [key: string]: string; };\n    /**\n     * Whether the sandbox http preview is public\n     * @type {boolean}\n     * @memberof Workspace\n     */\n    'public': boolean;\n    /**\n     * Whether to block all network access for the sandbox\n     * @type {boolean}\n     * @memberof Workspace\n     */\n    'networkBlockAll': boolean;\n    /**\n     * Comma-separated list of allowed CIDR network addresses for the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'networkAllowList'?: string;\n    /**\n     * The target environment for the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'target': string;\n    /**\n     * The CPU quota for the sandbox\n     * @type {number}\n     * @memberof Workspace\n     */\n    'cpu': number;\n    /**\n     * The GPU quota for the sandbox\n     * @type {number}\n     * @memberof Workspace\n     */\n    'gpu': number;\n    /**\n     * The memory quota for the sandbox\n     * @type {number}\n     * @memberof Workspace\n     */\n    'memory': number;\n    /**\n     * The disk quota for the sandbox\n     * @type {number}\n     * @memberof Workspace\n     */\n    'disk': number;\n    /**\n     * The state of the sandbox\n     * @type {SandboxState}\n     * @memberof Workspace\n     */\n    'state'?: SandboxState;\n    /**\n     * The desired state of the sandbox\n     * @type {SandboxDesiredState}\n     * @memberof Workspace\n     */\n    'desiredState'?: SandboxDesiredState;\n    /**\n     * The error reason of the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'errorReason'?: string;\n    /**\n     * Whether the sandbox error is recoverable.\n     * @type {boolean}\n     * @memberof Workspace\n     */\n    'recoverable'?: boolean;\n    /**\n     * The state of the backup\n     * @type {string}\n     * @memberof Workspace\n     */\n    'backupState'?: WorkspaceBackupStateEnum;\n    /**\n     * The creation timestamp of the last backup\n     * @type {string}\n     * @memberof Workspace\n     */\n    'backupCreatedAt'?: string;\n    /**\n     * Auto-stop interval in minutes (0 means disabled)\n     * @type {number}\n     * @memberof Workspace\n     */\n    'autoStopInterval'?: number;\n    /**\n     * Auto-archive interval in minutes\n     * @type {number}\n     * @memberof Workspace\n     */\n    'autoArchiveInterval'?: number;\n    /**\n     * Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n     * @type {number}\n     * @memberof Workspace\n     */\n    'autoDeleteInterval'?: number;\n    /**\n     * Array of volumes attached to the sandbox\n     * @type {Array<SandboxVolume>}\n     * @memberof Workspace\n     */\n    'volumes'?: Array<SandboxVolume>;\n    /**\n     * Build information for the sandbox\n     * @type {BuildInfo}\n     * @memberof Workspace\n     */\n    'buildInfo'?: BuildInfo;\n    /**\n     * The creation timestamp of the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'createdAt'?: string;\n    /**\n     * The last update timestamp of the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'updatedAt'?: string;\n    /**\n     * The class of the sandbox\n     * @type {string}\n     * @memberof Workspace\n     * @deprecated\n     */\n    'class'?: WorkspaceClassEnum;\n    /**\n     * The version of the daemon running in the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'daemonVersion'?: string;\n    /**\n     * The runner ID of the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'runnerId'?: string;\n    /**\n     * The toolbox proxy URL for the sandbox\n     * @type {string}\n     * @memberof Workspace\n     */\n    'toolboxProxyUrl': string;\n    /**\n     * The image used for the workspace\n     * @type {string}\n     * @memberof Workspace\n     */\n    'image'?: string;\n    /**\n     * The state of the snapshot\n     * @type {string}\n     * @memberof Workspace\n     */\n    'snapshotState'?: WorkspaceSnapshotStateEnum;\n    /**\n     * The creation timestamp of the last snapshot\n     * @type {string}\n     * @memberof Workspace\n     */\n    'snapshotCreatedAt'?: string;\n    /**\n     * Additional information about the sandbox\n     * @type {SandboxInfo}\n     * @memberof Workspace\n     */\n    'info'?: SandboxInfo;\n}\n\nexport const WorkspaceBackupStateEnum = {\n    NONE: 'None',\n    PENDING: 'Pending',\n    IN_PROGRESS: 'InProgress',\n    COMPLETED: 'Completed',\n    ERROR: 'Error'\n} as const;\n\nexport type WorkspaceBackupStateEnum = typeof WorkspaceBackupStateEnum[keyof typeof WorkspaceBackupStateEnum];\nexport const WorkspaceClassEnum = {\n    SMALL: 'small',\n    MEDIUM: 'medium',\n    LARGE: 'large'\n} as const;\n\nexport type WorkspaceClassEnum = typeof WorkspaceClassEnum[keyof typeof WorkspaceClassEnum];\nexport const WorkspaceSnapshotStateEnum = {\n    NONE: 'None',\n    PENDING: 'Pending',\n    IN_PROGRESS: 'InProgress',\n    COMPLETED: 'Completed',\n    ERROR: 'Error'\n} as const;\n\nexport type WorkspaceSnapshotStateEnum = typeof WorkspaceSnapshotStateEnum[keyof typeof WorkspaceSnapshotStateEnum];\n\n\n"
  },
  {
    "path": "libs/api-client/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.base.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"strict\": true,\n    \"importHelpers\": false,\n    \"noImplicitOverride\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noPropertyAccessFromIndexSignature\": true\n  },\n  \"files\": [],\n  \"include\": [],\n  \"references\": [\n    {\n      \"path\": \"./tsconfig.lib.json\"\n    }\n  ]\n}\n"
  },
  {
    "path": "libs/api-client/tsconfig.lib.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"../../dist/out-tsc\",\n    \"declaration\": true,\n    \"types\": [\"node\"]\n  },\n  \"include\": [\"src/**/*.ts\"]\n}\n"
  },
  {
    "path": "libs/api-client-go/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n"
  },
  {
    "path": "libs/api-client-go/.openapi-generator/FILES",
    "content": ".gitignore\napi/openapi.yaml\napi_admin.go\napi_api_keys.go\napi_audit.go\napi_config.go\napi_docker_registry.go\napi_health.go\napi_jobs.go\napi_object_storage.go\napi_organizations.go\napi_preview.go\napi_regions.go\napi_runners.go\napi_sandbox.go\napi_snapshots.go\napi_toolbox.go\napi_users.go\napi_volumes.go\napi_webhooks.go\napi_workspace.go\nclient.go\nconfiguration.go\ngo.mod\ngo.sum\nmodel_account_provider.go\nmodel_admin_create_runner.go\nmodel_announcement.go\nmodel_api_key_list.go\nmodel_api_key_response.go\nmodel_audit_log.go\nmodel_build_info.go\nmodel_command.go\nmodel_completion_context.go\nmodel_completion_item.go\nmodel_completion_list.go\nmodel_compressed_screenshot_response.go\nmodel_computer_use_start_response.go\nmodel_computer_use_status_response.go\nmodel_computer_use_stop_response.go\nmodel_create_api_key.go\nmodel_create_build_info.go\nmodel_create_docker_registry.go\nmodel_create_linked_account.go\nmodel_create_organization.go\nmodel_create_organization_invitation.go\nmodel_create_organization_quota.go\nmodel_create_organization_role.go\nmodel_create_region.go\nmodel_create_region_response.go\nmodel_create_runner.go\nmodel_create_runner_response.go\nmodel_create_sandbox.go\nmodel_create_session_request.go\nmodel_create_snapshot.go\nmodel_create_user.go\nmodel_create_volume.go\nmodel_create_workspace.go\nmodel_daytona_configuration.go\nmodel_display_info_response.go\nmodel_docker_registry.go\nmodel_download_files.go\nmodel_execute_request.go\nmodel_execute_response.go\nmodel_file_info.go\nmodel_file_status.go\nmodel_git_add_request.go\nmodel_git_branch_request.go\nmodel_git_checkout_request.go\nmodel_git_clone_request.go\nmodel_git_commit_info.go\nmodel_git_commit_request.go\nmodel_git_commit_response.go\nmodel_git_delete_branch_request.go\nmodel_git_repo_request.go\nmodel_git_status.go\nmodel_health_controller_check_200_response.go\nmodel_health_controller_check_200_response_info_value.go\nmodel_health_controller_check_503_response.go\nmodel_job.go\nmodel_job_status.go\nmodel_job_type.go\nmodel_keyboard_hotkey_request.go\nmodel_keyboard_press_request.go\nmodel_keyboard_type_request.go\nmodel_list_branch_response.go\nmodel_log_entry.go\nmodel_lsp_completion_params.go\nmodel_lsp_document_request.go\nmodel_lsp_location.go\nmodel_lsp_server_request.go\nmodel_lsp_symbol.go\nmodel_match.go\nmodel_metric_data_point.go\nmodel_metric_series.go\nmodel_metrics_response.go\nmodel_mouse_click_request.go\nmodel_mouse_click_response.go\nmodel_mouse_drag_request.go\nmodel_mouse_drag_response.go\nmodel_mouse_move_request.go\nmodel_mouse_move_response.go\nmodel_mouse_position.go\nmodel_mouse_scroll_request.go\nmodel_mouse_scroll_response.go\nmodel_oidc_config.go\nmodel_organization.go\nmodel_organization_invitation.go\nmodel_organization_role.go\nmodel_organization_sandbox_default_limited_network_egress.go\nmodel_organization_suspension.go\nmodel_organization_usage_overview.go\nmodel_organization_user.go\nmodel_otel_config.go\nmodel_paginated_audit_logs.go\nmodel_paginated_jobs.go\nmodel_paginated_logs.go\nmodel_paginated_sandboxes.go\nmodel_paginated_snapshots.go\nmodel_paginated_traces.go\nmodel_poll_jobs_response.go\nmodel_port_preview_url.go\nmodel_position.go\nmodel_posthog_config.go\nmodel_process_errors_response.go\nmodel_process_logs_response.go\nmodel_process_restart_response.go\nmodel_process_status_response.go\nmodel_project_dir_response.go\nmodel_pty_create_request.go\nmodel_pty_create_response.go\nmodel_pty_list_response.go\nmodel_pty_resize_request.go\nmodel_pty_session_info.go\nmodel_range.go\nmodel_rate_limit_config.go\nmodel_rate_limit_entry.go\nmodel_regenerate_api_key_response.go\nmodel_region.go\nmodel_region_quota.go\nmodel_region_screenshot_response.go\nmodel_region_type.go\nmodel_region_usage_overview.go\nmodel_registry_push_access_dto.go\nmodel_replace_request.go\nmodel_replace_result.go\nmodel_resize_sandbox.go\nmodel_runner.go\nmodel_runner_full.go\nmodel_runner_health_metrics.go\nmodel_runner_healthcheck.go\nmodel_runner_service_health.go\nmodel_runner_snapshot_dto.go\nmodel_runner_state.go\nmodel_sandbox.go\nmodel_sandbox_class.go\nmodel_sandbox_desired_state.go\nmodel_sandbox_info.go\nmodel_sandbox_labels.go\nmodel_sandbox_state.go\nmodel_sandbox_volume.go\nmodel_screenshot_response.go\nmodel_search_files_response.go\nmodel_send_webhook_dto.go\nmodel_session.go\nmodel_session_execute_request.go\nmodel_session_execute_response.go\nmodel_set_snapshot_general_status_dto.go\nmodel_signed_port_preview_url.go\nmodel_snapshot_dto.go\nmodel_snapshot_manager_credentials.go\nmodel_snapshot_state.go\nmodel_ssh_access_dto.go\nmodel_ssh_access_validation_dto.go\nmodel_storage_access_dto.go\nmodel_toolbox_proxy_url.go\nmodel_trace_span.go\nmodel_trace_summary.go\nmodel_update_docker_registry.go\nmodel_update_job_status.go\nmodel_update_organization_default_region.go\nmodel_update_organization_invitation.go\nmodel_update_organization_member_access.go\nmodel_update_organization_quota.go\nmodel_update_organization_region_quota.go\nmodel_update_organization_role.go\nmodel_update_region.go\nmodel_update_sandbox_state_dto.go\nmodel_url.go\nmodel_user.go\nmodel_user_home_dir_response.go\nmodel_user_public_key.go\nmodel_volume_dto.go\nmodel_volume_state.go\nmodel_webhook_app_portal_access.go\nmodel_webhook_controller_get_status_200_response.go\nmodel_webhook_event.go\nmodel_webhook_initialization_status.go\nmodel_windows_response.go\nmodel_work_dir_response.go\nmodel_workspace.go\nmodel_workspace_port_preview_url.go\nresponse.go\nutils.go\n"
  },
  {
    "path": "libs/api-client-go/.openapi-generator/VERSION",
    "content": "7.12.0\n"
  },
  {
    "path": "libs/api-client-go/.openapi-generator-ignore",
    "content": "# OpenAPI Generator Ignore\n# Generated by openapi-generator https://github.com/openapitools/openapi-generator\n\n# Use this file to prevent files from being overwritten by the generator.\n# The patterns follow closely to .gitignore or .dockerignore.\n\n# As an example, the C# client generator defines ApiClient.cs.\n# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:\n#ApiClient.cs\n\n# You can match any string of characters against a directory, file or extension with a single asterisk (*):\n#foo/*/qux\n# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux\n\n# You can recursively match patterns against a directory, file or extension with a double asterisk (**):\n#foo/**/qux\n# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux\n\n# You can also negate patterns with an exclamation (!).\n# For example, you can ignore all files in a docs folder with the file extension .md:\n#docs/*.md\n# Then explicitly reverse the ignore rule for a single file:\n#!docs/README.md\n\ngit_push.sh\n.travis.yml\ntest/*\n.gitlab-ci.yml\ndocs/*\nREADME.md\n"
  },
  {
    "path": "libs/api-client-go/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   Copyright 2025 Daytona\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License. "
  },
  {
    "path": "libs/api-client-go/api/openapi.yaml",
    "content": "openapi: 3.0.0\ninfo:\n  contact:\n    email: support@daytona.com\n    name: Daytona Platforms Inc.\n    url: https://www.daytona.io\n  description: Daytona AI platform API Docs\n  title: Daytona\n  version: \"1.0\"\nservers:\n- url: http://localhost:3000\npaths:\n  /config:\n    get:\n      operationId: ConfigController_getConfig\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/DaytonaConfiguration'\n          description: Daytona configuration\n      summary: Get config\n      tags:\n      - config\n  /api-keys:\n    get:\n      operationId: listApiKeys\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/ApiKeyList'\n                type: array\n          description: API keys retrieved successfully.\n        \"500\":\n          description: Error fetching API keys.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List API keys\n      tags:\n      - api-keys\n    post:\n      operationId: createApiKey\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateApiKey'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ApiKeyResponse'\n          description: API key created successfully.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create API key\n      tags:\n      - api-keys\n  /api-keys/current:\n    get:\n      operationId: getCurrentApiKey\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ApiKeyList'\n          description: API key retrieved successfully.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get current API key's details\n      tags:\n      - api-keys\n  /api-keys/{name}:\n    delete:\n      operationId: deleteApiKey\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: name\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: API key deleted successfully.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete API key\n      tags:\n      - api-keys\n    get:\n      operationId: getApiKey\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: name\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ApiKeyList'\n          description: API key retrieved successfully.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get API key\n      tags:\n      - api-keys\n  /api-keys/{userId}/{name}:\n    delete:\n      operationId: deleteApiKeyForUser\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: userId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: name\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: API key deleted successfully.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete API key for user\n      tags:\n      - api-keys\n  /organizations/invitations:\n    get:\n      operationId: listOrganizationInvitationsForAuthenticatedUser\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/OrganizationInvitation'\n                type: array\n          description: List of organization invitations\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List organization invitations for authenticated user\n      tags:\n      - organizations\n  /organizations/invitations/count:\n    get:\n      operationId: getOrganizationInvitationsCountForAuthenticatedUser\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                type: number\n          description: Count of organization invitations\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get count of organization invitations for authenticated user\n      tags:\n      - organizations\n  /organizations/invitations/{invitationId}/accept:\n    post:\n      operationId: acceptOrganizationInvitation\n      parameters:\n      - description: Invitation ID\n        explode: false\n        in: path\n        name: invitationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrganizationInvitation'\n          description: Organization invitation accepted successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Accept organization invitation\n      tags:\n      - organizations\n  /organizations/invitations/{invitationId}/decline:\n    post:\n      operationId: declineOrganizationInvitation\n      parameters:\n      - description: Invitation ID\n        explode: false\n        in: path\n        name: invitationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: Organization invitation declined successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Decline organization invitation\n      tags:\n      - organizations\n  /organizations:\n    get:\n      operationId: listOrganizations\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Organization'\n                type: array\n          description: List of organizations\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List organizations\n      tags:\n      - organizations\n    post:\n      operationId: createOrganization\n      parameters: []\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateOrganization'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Organization'\n          description: Organization created successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create organization\n      tags:\n      - organizations\n  /organizations/{organizationId}/default-region:\n    patch:\n      operationId: setOrganizationDefaultRegion\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateOrganizationDefaultRegion'\n        required: true\n      responses:\n        \"204\":\n          description: Default region set successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Set default region for organization\n      tags:\n      - organizations\n  /organizations/{organizationId}:\n    delete:\n      operationId: deleteOrganization\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: Organization deleted successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete organization\n      tags:\n      - organizations\n    get:\n      operationId: getOrganization\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Organization'\n          description: Organization details\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get organization by ID\n      tags:\n      - organizations\n  /organizations/{organizationId}/usage:\n    get:\n      operationId: getOrganizationUsageOverview\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrganizationUsageOverview'\n          description: Current usage overview\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get organization current usage overview\n      tags:\n      - organizations\n  /organizations/{organizationId}/quota:\n    patch:\n      operationId: updateOrganizationQuota\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateOrganizationQuota'\n        required: true\n      responses:\n        \"204\":\n          description: Organization quota updated successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update organization quota\n      tags:\n      - organizations\n  /organizations/{organizationId}/quota/{regionId}:\n    patch:\n      operationId: updateOrganizationRegionQuota\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: ID of the region where the updated quota will be applied\n        explode: false\n        in: path\n        name: regionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateOrganizationRegionQuota'\n        required: true\n      responses:\n        \"204\":\n          description: Region quota updated successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update organization region quota\n      tags:\n      - organizations\n  /organizations/{organizationId}/leave:\n    post:\n      operationId: leaveOrganization\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: Organization left successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Leave organization\n      tags:\n      - organizations\n  /organizations/{organizationId}/suspend:\n    post:\n      operationId: suspendOrganization\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/OrganizationSuspension'\n        required: false\n      responses:\n        \"204\":\n          description: Organization suspended successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Suspend organization\n      tags:\n      - organizations\n  /organizations/{organizationId}/unsuspend:\n    post:\n      operationId: unsuspendOrganization\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: Organization unsuspended successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Unsuspend organization\n      tags:\n      - organizations\n  /organizations/by-sandbox-id/{sandboxId}:\n    get:\n      operationId: getOrganizationBySandboxId\n      parameters:\n      - description: Sandbox ID\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Organization'\n          description: Organization\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get organization by sandbox ID\n      tags:\n      - organizations\n  /organizations/region-quota/by-sandbox-id/{sandboxId}:\n    get:\n      operationId: getRegionQuotaBySandboxId\n      parameters:\n      - description: Sandbox ID\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RegionQuota'\n          description: Region quota\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get region quota by sandbox ID\n      tags:\n      - organizations\n  /organizations/otel-config/by-sandbox-auth-token/{authToken}:\n    get:\n      operationId: getOrganizationOtelConfigBySandboxAuthToken\n      parameters:\n      - description: Sandbox Auth Token\n        explode: false\n        in: path\n        name: authToken\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OtelConfig'\n          description: OTEL Config\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get organization OTEL config by sandbox auth token\n      tags:\n      - organizations\n  /organizations/{organizationId}/sandbox-default-limited-network-egress:\n    post:\n      operationId: updateSandboxDefaultLimitedNetworkEgress\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/OrganizationSandboxDefaultLimitedNetworkEgress'\n        required: true\n      responses:\n        \"204\":\n          description: Sandbox default limited network egress updated successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update sandbox default limited network egress\n      tags:\n      - organizations\n  /organizations/{organizationId}/experimental-config:\n    put:\n      operationId: updateExperimentalConfig\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              additionalProperties: true\n              example:\n                otel:\n                  endpoint: http://otel-collector:4317\n                  headers:\n                    api-key: XXX\n              type: object\n        description: Experimental configuration as a JSON object. Set to null to clear\n          the configuration.\n        required: false\n      responses:\n        \"200\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update experimental configuration\n      tags:\n      - organizations\n  /organizations/{organizationId}/roles:\n    get:\n      operationId: listOrganizationRoles\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/OrganizationRole'\n                type: array\n          description: List of organization roles\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List organization roles\n      tags:\n      - organizations\n    post:\n      operationId: createOrganizationRole\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateOrganizationRole'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrganizationRole'\n          description: Organization role created successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create organization role\n      tags:\n      - organizations\n  /organizations/{organizationId}/roles/{roleId}:\n    delete:\n      operationId: deleteOrganizationRole\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Role ID\n        explode: false\n        in: path\n        name: roleId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: Organization role deleted successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete organization role\n      tags:\n      - organizations\n    put:\n      operationId: updateOrganizationRole\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Role ID\n        explode: false\n        in: path\n        name: roleId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateOrganizationRole'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrganizationRole'\n          description: Role updated successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update organization role\n      tags:\n      - organizations\n  /organizations/{organizationId}/users:\n    get:\n      operationId: listOrganizationMembers\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/OrganizationUser'\n                type: array\n          description: List of organization members\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List organization members\n      tags:\n      - organizations\n  /organizations/{organizationId}/users/{userId}/access:\n    post:\n      operationId: updateAccessForOrganizationMember\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: User ID\n        explode: false\n        in: path\n        name: userId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateOrganizationMemberAccess'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrganizationUser'\n          description: Access updated successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update access for organization member\n      tags:\n      - organizations\n  /organizations/{organizationId}/users/{userId}:\n    delete:\n      operationId: deleteOrganizationMember\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: User ID\n        explode: false\n        in: path\n        name: userId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: User removed from organization successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete organization member\n      tags:\n      - organizations\n  /organizations/{organizationId}/invitations:\n    get:\n      operationId: listOrganizationInvitations\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/OrganizationInvitation'\n                type: array\n          description: List of pending organization invitations\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List pending organization invitations\n      tags:\n      - organizations\n    post:\n      operationId: createOrganizationInvitation\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateOrganizationInvitation'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrganizationInvitation'\n          description: Organization invitation created successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create organization invitation\n      tags:\n      - organizations\n  /organizations/{organizationId}/invitations/{invitationId}:\n    put:\n      operationId: updateOrganizationInvitation\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Invitation ID\n        explode: false\n        in: path\n        name: invitationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateOrganizationInvitation'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/OrganizationInvitation'\n          description: Organization invitation updated successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update organization invitation\n      tags:\n      - organizations\n  /organizations/{organizationId}/invitations/{invitationId}/cancel:\n    post:\n      operationId: cancelOrganizationInvitation\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Invitation ID\n        explode: false\n        in: path\n        name: invitationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: Organization invitation cancelled successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Cancel organization invitation\n      tags:\n      - organizations\n  /regions:\n    get:\n      operationId: listAvailableRegions\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Region'\n                type: array\n          description: List of all available regions\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all available regions for the organization\n      tags:\n      - organizations\n    post:\n      operationId: createRegion\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateRegion'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CreateRegionResponse'\n          description: The region has been successfully created.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create a new region\n      tags:\n      - organizations\n  /regions/{id}:\n    delete:\n      operationId: deleteRegion\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Region ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: The region has been successfully deleted.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete a region\n      tags:\n      - organizations\n    get:\n      operationId: getRegionById\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Region ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Region'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get region by ID\n      tags:\n      - organizations\n    patch:\n      operationId: updateRegion\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Region ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateRegion'\n        required: true\n      responses:\n        \"200\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update region configuration\n      tags:\n      - organizations\n  /regions/{id}/regenerate-proxy-api-key:\n    post:\n      operationId: regenerateProxyApiKey\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Region ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RegenerateApiKeyResponse'\n          description: The proxy API key has been successfully regenerated.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Regenerate proxy API key for a region\n      tags:\n      - organizations\n  /regions/{id}/regenerate-ssh-gateway-api-key:\n    post:\n      operationId: regenerateSshGatewayApiKey\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Region ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RegenerateApiKeyResponse'\n          description: The SSH gateway API key has been successfully regenerated.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Regenerate SSH gateway API key for a region\n      tags:\n      - organizations\n  /regions/{id}/regenerate-snapshot-manager-credentials:\n    post:\n      operationId: regenerateSnapshotManagerCredentials\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Region ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SnapshotManagerCredentials'\n          description: The snapshot manager credentials have been successfully regenerated.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Regenerate snapshot manager credentials for a region\n      tags:\n      - organizations\n  /users/me:\n    get:\n      operationId: getAuthenticatedUser\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/User'\n          description: User details\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get authenticated user\n      tags:\n      - users\n  /users:\n    get:\n      operationId: listUsers\n      parameters: []\n      responses:\n        \"200\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all users\n      tags:\n      - users\n    post:\n      operationId: createUser\n      parameters: []\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateUser'\n        required: true\n      responses:\n        \"201\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create user\n      tags:\n      - users\n  /users/{id}/regenerate-key-pair:\n    post:\n      operationId: regenerateKeyPair\n      parameters:\n      - explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"201\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Regenerate user key pair\n      tags:\n      - users\n  /users/account-providers:\n    get:\n      operationId: getAvailableAccountProviders\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/AccountProvider'\n                type: array\n          description: Available account providers\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get available account providers\n      tags:\n      - users\n  /users/linked-accounts:\n    post:\n      operationId: linkAccount\n      parameters: []\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateLinkedAccount'\n        required: true\n      responses:\n        \"204\":\n          description: Account linked successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Link account\n      tags:\n      - users\n  /users/linked-accounts/{provider}/{providerUserId}:\n    delete:\n      operationId: unlinkAccount\n      parameters:\n      - explode: false\n        in: path\n        name: provider\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: providerUserId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: Account unlinked successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Unlink account\n      tags:\n      - users\n  /users/mfa/sms/enroll:\n    post:\n      operationId: enrollInSmsMfa\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                type: string\n          description: SMS MFA enrollment URL\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Enroll in SMS MFA\n      tags:\n      - users\n  /users/{id}:\n    get:\n      operationId: getUser\n      parameters:\n      - explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/User'\n          description: User details\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get user by ID\n      tags:\n      - users\n  /shared-regions:\n    get:\n      operationId: listSharedRegions\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Region'\n                type: array\n          description: List of all shared regions\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all shared regions\n      tags:\n      - regions\n  /sandbox:\n    get:\n      operationId: listSandboxes\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Include verbose output\n        explode: true\n        in: query\n        name: verbose\n        required: false\n        schema:\n          type: boolean\n        style: form\n      - description: JSON encoded labels to filter by\n        explode: true\n        in: query\n        name: labels\n        required: false\n        schema:\n          example: \"{\\\"label1\\\": \\\"value1\\\", \\\"label2\\\": \\\"value2\\\"}\"\n          type: string\n        style: form\n      - description: Include errored and deleted sandboxes\n        explode: true\n        in: query\n        name: includeErroredDeleted\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Sandbox'\n                type: array\n          description: List of all sandboxes\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all sandboxes\n      tags:\n      - sandbox\n    post:\n      operationId: createSandbox\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateSandbox'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: The sandbox has been successfully created.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create a new sandbox\n      tags:\n      - sandbox\n  /sandbox/paginated:\n    get:\n      operationId: listSandboxesPaginated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Page number of the results\n        explode: true\n        in: query\n        name: page\n        required: false\n        schema:\n          default: 1\n          minimum: 1\n          type: number\n        style: form\n      - description: Number of results per page\n        explode: true\n        in: query\n        name: limit\n        required: false\n        schema:\n          default: 100\n          maximum: 200\n          minimum: 1\n          type: number\n        style: form\n      - description: Filter by partial ID match\n        explode: true\n        in: query\n        name: id\n        required: false\n        schema:\n          example: abc123\n          type: string\n        style: form\n      - description: Filter by partial name match\n        explode: true\n        in: query\n        name: name\n        required: false\n        schema:\n          example: abc123\n          type: string\n        style: form\n      - description: JSON encoded labels to filter by\n        explode: true\n        in: query\n        name: labels\n        required: false\n        schema:\n          example: \"{\\\"label1\\\": \\\"value1\\\", \\\"label2\\\": \\\"value2\\\"}\"\n          type: string\n        style: form\n      - description: Include results with errored state and deleted desired state\n        explode: true\n        in: query\n        name: includeErroredDeleted\n        required: false\n        schema:\n          default: false\n          type: boolean\n        style: form\n      - description: List of states to filter by\n        explode: true\n        in: query\n        name: states\n        required: false\n        schema:\n          items:\n            enum:\n            - creating\n            - restoring\n            - destroying\n            - started\n            - stopped\n            - starting\n            - stopping\n            - error\n            - build_failed\n            - pending_build\n            - building_snapshot\n            - unknown\n            - pulling_snapshot\n            - archived\n            - archiving\n            - resizing\n            type: string\n          type: array\n        style: form\n      - description: List of snapshot names to filter by\n        explode: true\n        in: query\n        name: snapshots\n        required: false\n        schema:\n          items:\n            type: string\n          type: array\n        style: form\n      - description: List of regions to filter by\n        explode: true\n        in: query\n        name: regions\n        required: false\n        schema:\n          items:\n            type: string\n          type: array\n        style: form\n      - description: Minimum CPU\n        explode: true\n        in: query\n        name: minCpu\n        required: false\n        schema:\n          minimum: 1\n          type: number\n        style: form\n      - description: Maximum CPU\n        explode: true\n        in: query\n        name: maxCpu\n        required: false\n        schema:\n          minimum: 1\n          type: number\n        style: form\n      - description: Minimum memory in GiB\n        explode: true\n        in: query\n        name: minMemoryGiB\n        required: false\n        schema:\n          minimum: 1\n          type: number\n        style: form\n      - description: Maximum memory in GiB\n        explode: true\n        in: query\n        name: maxMemoryGiB\n        required: false\n        schema:\n          minimum: 1\n          type: number\n        style: form\n      - description: Minimum disk space in GiB\n        explode: true\n        in: query\n        name: minDiskGiB\n        required: false\n        schema:\n          minimum: 1\n          type: number\n        style: form\n      - description: Maximum disk space in GiB\n        explode: true\n        in: query\n        name: maxDiskGiB\n        required: false\n        schema:\n          minimum: 1\n          type: number\n        style: form\n      - description: Include items with last event after this timestamp\n        explode: true\n        in: query\n        name: lastEventAfter\n        required: false\n        schema:\n          example: 2024-01-01T00:00:00Z\n          format: date-time\n          type: string\n        style: form\n      - description: Include items with last event before this timestamp\n        explode: true\n        in: query\n        name: lastEventBefore\n        required: false\n        schema:\n          example: 2024-12-31T23:59:59Z\n          format: date-time\n          type: string\n        style: form\n      - description: Field to sort by\n        explode: true\n        in: query\n        name: sort\n        required: false\n        schema:\n          default: createdAt\n          enum:\n          - id\n          - name\n          - state\n          - snapshot\n          - region\n          - updatedAt\n          - createdAt\n          type: string\n        style: form\n      - description: Direction to sort by\n        explode: true\n        in: query\n        name: order\n        required: false\n        schema:\n          default: desc\n          enum:\n          - asc\n          - desc\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PaginatedSandboxes'\n          description: Paginated list of all sandboxes\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all sandboxes paginated\n      tags:\n      - sandbox\n  /sandbox/for-runner:\n    get:\n      operationId: getSandboxesForRunner\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Comma-separated list of sandbox states to filter by\n        explode: true\n        in: query\n        name: states\n        required: false\n        schema:\n          type: string\n        style: form\n      - description: Skip sandboxes where state differs from desired state\n        explode: true\n        in: query\n        name: skipReconcilingSandboxes\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Sandbox'\n                type: array\n          description: List of sandboxes for the authenticated runner\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get sandboxes for the authenticated runner\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}:\n    delete:\n      operationId: deleteSandbox\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Sandbox has been deleted\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete sandbox\n      tags:\n      - sandbox\n    get:\n      operationId: getSandbox\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Include verbose output\n        explode: true\n        in: query\n        name: verbose\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Sandbox details\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get sandbox details\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/recover:\n    post:\n      operationId: recoverSandbox\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Recovery initiated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Recover sandbox from error state\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/start:\n    post:\n      operationId: startSandbox\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Sandbox has been started or is being restored from archived\n            state\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Start sandbox\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/stop:\n    post:\n      operationId: stopSandbox\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Sandbox has been stopped\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Stop sandbox\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/resize:\n    post:\n      operationId: resizeSandbox\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/ResizeSandbox'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Sandbox has been resized\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Resize sandbox resources\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/labels:\n    put:\n      operationId: replaceLabels\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/SandboxLabels'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SandboxLabels'\n          description: Labels have been successfully replaced\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Replace sandbox labels\n      tags:\n      - sandbox\n  /sandbox/{sandboxId}/state:\n    put:\n      operationId: updateSandboxState\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateSandboxStateDto'\n        required: true\n      responses:\n        \"200\":\n          description: Sandbox state has been successfully updated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update sandbox state\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/backup:\n    post:\n      operationId: createBackup\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Sandbox backup has been initiated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create sandbox backup\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/public/{isPublic}:\n    post:\n      operationId: updatePublicStatus\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Public status to set\n        explode: false\n        in: path\n        name: isPublic\n        required: true\n        schema:\n          type: boolean\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Public status has been successfully updated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update public status\n      tags:\n      - sandbox\n  /sandbox/{sandboxId}/last-activity:\n    post:\n      operationId: updateLastActivity\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"201\":\n          description: Last activity has been updated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update sandbox last activity\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/autostop/{interval}:\n    post:\n      operationId: setAutostopInterval\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Auto-stop interval in minutes (0 to disable)\n        explode: false\n        in: path\n        name: interval\n        required: true\n        schema:\n          type: number\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Auto-stop interval has been set\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Set sandbox auto-stop interval\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/autoarchive/{interval}:\n    post:\n      operationId: setAutoArchiveInterval\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Auto-archive interval in minutes (0 means the maximum interval\n          will be used)\n        explode: false\n        in: path\n        name: interval\n        required: true\n        schema:\n          type: number\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Auto-archive interval has been set\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Set sandbox auto-archive interval\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/autodelete/{interval}:\n    post:\n      operationId: setAutoDeleteInterval\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: \"Auto-delete interval in minutes (negative value means disabled,\\\n          \\ 0 means delete immediately upon stopping)\"\n        explode: false\n        in: path\n        name: interval\n        required: true\n        schema:\n          type: number\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Auto-delete interval has been set\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Set sandbox auto-delete interval\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/archive:\n    post:\n      operationId: archiveSandbox\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Sandbox has been archived\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Archive sandbox\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/ports/{port}/preview-url:\n    get:\n      operationId: getPortPreviewUrl\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Port number to get preview URL for\n        explode: false\n        in: path\n        name: port\n        required: true\n        schema:\n          type: number\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PortPreviewUrl'\n          description: Preview URL for the specified port\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get preview URL for a sandbox port\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url:\n    get:\n      operationId: getSignedPortPreviewUrl\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Port number to get signed preview URL for\n        explode: false\n        in: path\n        name: port\n        required: true\n        schema:\n          type: integer\n        style: simple\n      - description: \"Expiration time in seconds (default: 60 seconds)\"\n        explode: true\n        in: query\n        name: expiresInSeconds\n        required: false\n        schema:\n          type: integer\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SignedPortPreviewUrl'\n          description: Signed preview URL for the specified port\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get signed preview URL for a sandbox port\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url/{token}/expire:\n    post:\n      operationId: expireSignedPortPreviewUrl\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Port number to expire signed preview URL for\n        explode: false\n        in: path\n        name: port\n        required: true\n        schema:\n          type: integer\n        style: simple\n      - description: Token to expire signed preview URL for\n        explode: false\n        in: path\n        name: token\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: Signed preview URL has been expired\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Expire signed preview URL for a sandbox port\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/build-logs:\n    get:\n      deprecated: true\n      description: This endpoint is deprecated. Use `getBuildLogsUrl` instead.\n      operationId: getBuildLogs\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Whether to follow the logs stream\n        explode: true\n        in: query\n        name: follow\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          description: Build logs stream\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get build logs\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/build-logs-url:\n    get:\n      operationId: getBuildLogsUrl\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Url'\n          description: Build logs URL\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get build logs URL\n      tags:\n      - sandbox\n  /sandbox/{sandboxIdOrName}/ssh-access:\n    delete:\n      operationId: revokeSshAccess\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: \"SSH access token to revoke. If not provided, all SSH access\\\n          \\ for the sandbox will be revoked.\"\n        explode: true\n        in: query\n        name: token\n        required: false\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: SSH access has been revoked\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Revoke SSH access for sandbox\n      tags:\n      - sandbox\n    post:\n      operationId: createSshAccess\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID or name of the sandbox\n        explode: false\n        in: path\n        name: sandboxIdOrName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: \"Expiration time in minutes (default: 60)\"\n        explode: true\n        in: query\n        name: expiresInMinutes\n        required: false\n        schema:\n          type: number\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SshAccessDto'\n          description: SSH access has been created\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create SSH access for sandbox\n      tags:\n      - sandbox\n  /sandbox/ssh-access/validate:\n    get:\n      operationId: validateSshAccess\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: SSH access token to validate\n        explode: true\n        in: query\n        name: token\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SshAccessValidationDto'\n          description: SSH access validation result\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Validate SSH access for sandbox\n      tags:\n      - sandbox\n  /sandbox/{sandboxId}/toolbox-proxy-url:\n    get:\n      operationId: getToolboxProxyUrl\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ToolboxProxyUrl'\n          description: Toolbox proxy URL for the specified sandbox\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get toolbox proxy URL for a sandbox\n      tags:\n      - sandbox\n  /runners:\n    get:\n      operationId: listRunners\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Runner'\n                type: array\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all runners\n      tags:\n      - runners\n    post:\n      operationId: createRunner\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateRunner'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CreateRunnerResponse'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create runner\n      tags:\n      - runners\n  /runners/me:\n    get:\n      operationId: getInfoForAuthenticatedRunner\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RunnerFull'\n          description: Runner info\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get info for authenticated runner\n      tags:\n      - runners\n  /runners/{id}:\n    delete:\n      operationId: deleteRunner\n      parameters:\n      - description: Runner ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete runner\n      tags:\n      - runners\n    get:\n      operationId: getRunnerById\n      parameters:\n      - description: Runner ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Runner'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get runner by ID\n      tags:\n      - runners\n  /runners/{id}/full:\n    get:\n      operationId: getRunnerFullById\n      parameters:\n      - description: Runner ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RunnerFull'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get runner by ID\n      tags:\n      - runners\n  /runners/{id}/scheduling:\n    patch:\n      operationId: updateRunnerScheduling\n      parameters:\n      - description: Runner ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Runner'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update runner scheduling status\n      tags:\n      - runners\n  /runners/{id}/draining:\n    patch:\n      operationId: updateRunnerDraining\n      parameters:\n      - description: Runner ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Runner'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update runner draining status\n      tags:\n      - runners\n  /runners/by-sandbox/{sandboxId}:\n    get:\n      operationId: getRunnerBySandboxId\n      parameters:\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RunnerFull'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get runner by sandbox ID\n      tags:\n      - runners\n  /runners/by-snapshot-ref:\n    get:\n      operationId: getRunnersBySnapshotRef\n      parameters:\n      - description: Snapshot ref\n        explode: true\n        in: query\n        name: ref\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/RunnerSnapshotDto'\n                type: array\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get runners by snapshot ref\n      tags:\n      - runners\n  /runners/healthcheck:\n    post:\n      description: Endpoint for version 2 runners to send healthcheck and metrics.\n        Updates lastChecked timestamp and runner metrics.\n      operationId: runnerHealthcheck\n      parameters: []\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/RunnerHealthcheck'\n        required: true\n      responses:\n        \"200\":\n          description: Healthcheck received\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Runner healthcheck\n      tags:\n      - runners\n  /toolbox/{sandboxId}/toolbox/project-dir:\n    get:\n      deprecated: true\n      operationId: getProjectDir_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ProjectDirResponse'\n          description: Project directory retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get sandbox project dir\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/user-home-dir:\n    get:\n      deprecated: true\n      operationId: getUserHomeDir_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/UserHomeDirResponse'\n          description: User home directory retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get sandbox user home dir\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/work-dir:\n    get:\n      deprecated: true\n      operationId: getWorkDir_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/WorkDirResponse'\n          description: Work-dir retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get sandbox work-dir\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files:\n    delete:\n      deprecated: true\n      description: Delete file inside sandbox\n      operationId: deleteFile_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: recursive\n        required: false\n        schema:\n          type: boolean\n        style: form\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          description: File deleted successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Delete file\"\n      tags:\n      - toolbox\n    get:\n      deprecated: true\n      operationId: listFiles_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: false\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/FileInfo'\n                type: array\n          description: Files listed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] List files\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/download:\n    get:\n      deprecated: true\n      description: Download file from sandbox\n      operationId: downloadFile_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                format: binary\n                type: string\n          description: File downloaded successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Download file\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/bulk-download:\n    post:\n      deprecated: true\n      description: Streams back a multipart/form-data bundle of the requested paths\n      operationId: downloadFiles_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/DownloadFiles'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                format: binary\n                type: string\n          description: A multipart/form-data response with each file as a part\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Download multiple files\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/find:\n    get:\n      deprecated: true\n      description: Search for text/pattern inside sandbox files\n      operationId: findInFiles_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: pattern\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Match'\n                type: array\n          description: Search completed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Search for text/pattern in files\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/folder:\n    post:\n      deprecated: true\n      description: Create folder inside sandbox\n      operationId: createFolder_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: mode\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          description: Folder created successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Create folder\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/info:\n    get:\n      deprecated: true\n      description: Get file info inside sandbox\n      operationId: getFileInfo_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/FileInfo'\n          description: File info retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get file info\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/move:\n    post:\n      deprecated: true\n      description: Move file inside sandbox\n      operationId: moveFile_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: source\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: destination\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          description: File moved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Move file\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/permissions:\n    post:\n      deprecated: true\n      description: Set file owner/group/permissions inside sandbox\n      operationId: setFilePermissions_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: owner\n        required: false\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: group\n        required: false\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: mode\n        required: false\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          description: File permissions updated successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Set file permissions\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/replace:\n    post:\n      deprecated: true\n      description: Replace text/pattern in multiple files inside sandbox\n      operationId: replaceInFiles_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/ReplaceRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/ReplaceResult'\n                type: array\n          description: Text replaced successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Replace in files\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/search:\n    get:\n      deprecated: true\n      description: Search for files inside sandbox\n      operationId: searchFiles_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: pattern\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SearchFilesResponse'\n          description: Search completed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Search files\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/upload:\n    post:\n      deprecated: true\n      description: Upload file inside sandbox\n      operationId: uploadFile_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              $ref: '#/components/schemas/uploadFile_deprecated_request'\n        required: true\n      responses:\n        \"200\":\n          description: File uploaded successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Upload file\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/files/bulk-upload:\n    post:\n      deprecated: true\n      description: Upload multiple files inside sandbox\n      operationId: uploadFiles_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          multipart/form-data:\n            schema:\n              items:\n                $ref: '#/components/schemas/UploadFile'\n              type: array\n        required: true\n      responses:\n        \"200\":\n          description: Files uploaded successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Upload multiple files\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/add:\n    post:\n      deprecated: true\n      description: Add files to git commit\n      operationId: gitAddFiles_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/GitAddRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Files added to git successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Add files\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/branches:\n    delete:\n      deprecated: true\n      description: Delete branch on git repository\n      operationId: gitDeleteBranch_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/GitDeleteBranchRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Branch deleted successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Delete branch\"\n      tags:\n      - toolbox\n    get:\n      deprecated: true\n      description: Get branch list from git repository\n      operationId: gitListBranches_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ListBranchResponse'\n          description: Branch list retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get branch list\"\n      tags:\n      - toolbox\n    post:\n      deprecated: true\n      description: Create branch on git repository\n      operationId: gitCreateBranch_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/GitBranchRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Branch created successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Create branch\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/clone:\n    post:\n      deprecated: true\n      description: Clone git repository\n      operationId: gitCloneRepository_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/GitCloneRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Repository cloned successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Clone repository\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/commit:\n    post:\n      deprecated: true\n      description: Commit changes to git repository\n      operationId: gitCommitChanges_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/GitCommitRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GitCommitResponse'\n          description: Changes committed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Commit changes\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/history:\n    get:\n      deprecated: true\n      description: Get commit history from git repository\n      operationId: gitGetHistory_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/GitCommitInfo'\n                type: array\n          description: Commit history retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get commit history\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/pull:\n    post:\n      deprecated: true\n      description: Pull changes from remote\n      operationId: gitPullChanges_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/GitRepoRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Changes pulled successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Pull changes\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/push:\n    post:\n      deprecated: true\n      description: Push changes to remote\n      operationId: gitPushChanges_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/GitRepoRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Changes pushed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Push changes\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/checkout:\n    post:\n      deprecated: true\n      description: Checkout branch or commit in git repository\n      operationId: gitCheckoutBranch_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/GitCheckoutRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Branch checked out successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Checkout branch\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/git/status:\n    get:\n      deprecated: true\n      description: Get status from git repository\n      operationId: gitGetStatus_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: path\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/GitStatus'\n          description: Git status retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get git status\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/execute:\n    post:\n      deprecated: true\n      description: Execute command synchronously inside sandbox\n      operationId: executeCommand_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/ExecuteRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ExecuteResponse'\n          description: Command executed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Execute command\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/session:\n    get:\n      deprecated: true\n      description: List all active sessions in the sandbox\n      operationId: listSessions_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Session'\n                type: array\n          description: Sessions retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] List sessions\"\n      tags:\n      - toolbox\n    post:\n      deprecated: true\n      description: Create a new session in the sandbox\n      operationId: createSession_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateSessionRequest'\n        required: true\n      responses:\n        \"200\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Create session\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/session/{sessionId}:\n    delete:\n      deprecated: true\n      description: Delete a specific session\n      operationId: deleteSession_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sessionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: Session deleted successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Delete session\"\n      tags:\n      - toolbox\n    get:\n      deprecated: true\n      description: Get session by ID\n      operationId: getSession_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sessionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Session'\n          description: Session retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get session\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/exec:\n    post:\n      deprecated: true\n      description: Execute a command in a specific session\n      operationId: executeSessionCommand_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sessionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/SessionExecuteRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SessionExecuteResponse'\n          description: Command executed successfully\n        \"202\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SessionExecuteResponse'\n          description: Command accepted and is being processed\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Execute command in session\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}:\n    get:\n      deprecated: true\n      description: Get session command by ID\n      operationId: getSessionCommand_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sessionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: commandId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Command'\n          description: Session command retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get session command\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}/logs:\n    get:\n      deprecated: true\n      description: Get logs for a specific command in a session\n      operationId: getSessionCommandLogs_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sessionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: commandId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Whether to stream the logs\n        explode: true\n        in: query\n        name: follow\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          content:\n            text/plain:\n              schema:\n                type: string\n          description: Command log stream marked with stdout and stderr prefixes\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get command logs\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/pty:\n    get:\n      deprecated: true\n      description: List all active PTY sessions in the sandbox\n      operationId: listPTYSessions_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PtyListResponse'\n          description: PTY sessions retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] List PTY sessions\"\n      tags:\n      - toolbox\n    post:\n      deprecated: true\n      description: Create a new PTY session in the sandbox\n      operationId: createPTYSession_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/PtyCreateRequest'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PtyCreateResponse'\n          description: PTY session created successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Create PTY session\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/pty/{sessionId}:\n    delete:\n      deprecated: true\n      description: Delete a PTY session and terminate the associated process\n      operationId: deletePTYSession_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sessionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: PTY session deleted successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Delete PTY session\"\n      tags:\n      - toolbox\n    get:\n      deprecated: true\n      description: Get PTY session information by ID\n      operationId: getPTYSession_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sessionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PtySessionInfo'\n          description: PTY session retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get PTY session\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/process/pty/{sessionId}/resize:\n    post:\n      deprecated: true\n      description: Resize a PTY session\n      operationId: resizePTYSession_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sessionId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/PtyResizeRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PtySessionInfo'\n          description: PTY session resized successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Resize PTY session\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/lsp/completions:\n    post:\n      deprecated: true\n      description: The Completion request is sent from the client to the server to\n        compute completion items at a given cursor position.\n      operationId: LspCompletions_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/LspCompletionParams'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CompletionList'\n          description: OK\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get Lsp Completions\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/lsp/did-close:\n    post:\n      deprecated: true\n      description: The document close notification is sent from the client to the\n        server when the document got closed in the client.\n      operationId: LspDidClose_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/LspDocumentRequest'\n        required: true\n      responses:\n        \"200\":\n          description: OK\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Call Lsp DidClose\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/lsp/did-open:\n    post:\n      deprecated: true\n      description: The document open notification is sent from the client to the server\n        to signal newly opened text documents.\n      operationId: LspDidOpen_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/LspDocumentRequest'\n        required: true\n      responses:\n        \"200\":\n          description: OK\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Call Lsp DidOpen\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/lsp/document-symbols:\n    get:\n      deprecated: true\n      description: The document symbol request is sent from the client to the server.\n      operationId: LspDocumentSymbols_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: languageId\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: pathToProject\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: uri\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/LspSymbol'\n                type: array\n          description: OK\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Call Lsp DocumentSymbols\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/lsp/start:\n    post:\n      deprecated: true\n      description: Start Lsp server process inside sandbox project\n      operationId: LspStart_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/LspServerRequest'\n        required: true\n      responses:\n        \"200\":\n          description: OK\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Start Lsp server\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/lsp/stop:\n    post:\n      deprecated: true\n      description: Stop Lsp server process inside sandbox project\n      operationId: LspStop_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/LspServerRequest'\n        required: true\n      responses:\n        \"200\":\n          description: OK\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Stop Lsp server\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/lsp/workspace-symbols:\n    get:\n      deprecated: true\n      description: The workspace symbol request is sent from the client to the server\n        to list project-wide symbols matching the query string.\n      operationId: LspWorkspaceSymbols_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: languageId\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: pathToProject\n        required: true\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: query\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/LspSymbol'\n                type: array\n          description: OK\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Call Lsp WorkspaceSymbols\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/start:\n    post:\n      deprecated: true\n      description: \"Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\"\n      operationId: startComputerUse_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ComputerUseStartResponse'\n          description: Computer use processes started successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Start computer use processes\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/stop:\n    post:\n      deprecated: true\n      description: \"Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\"\n      operationId: stopComputerUse_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ComputerUseStopResponse'\n          description: Computer use processes stopped successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Stop computer use processes\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/status:\n    get:\n      deprecated: true\n      description: Get status of all VNC desktop processes\n      operationId: getComputerUseStatus_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ComputerUseStatusResponse'\n          description: Computer use status retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get computer use status\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/status:\n    get:\n      deprecated: true\n      description: Get status of a specific VNC process\n      operationId: getProcessStatus_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: processName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ProcessStatusResponse'\n          description: Process status retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get process status\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/restart:\n    post:\n      deprecated: true\n      description: Restart a specific VNC process\n      operationId: restartProcess_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: processName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ProcessRestartResponse'\n          description: Process restarted successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Restart process\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/logs:\n    get:\n      deprecated: true\n      description: Get logs for a specific VNC process\n      operationId: getProcessLogs_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: processName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ProcessLogsResponse'\n          description: Process logs retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get process logs\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/errors:\n    get:\n      deprecated: true\n      description: Get error logs for a specific VNC process\n      operationId: getProcessErrors_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: processName\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ProcessErrorsResponse'\n          description: Process errors retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get process errors\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/mouse/position:\n    get:\n      deprecated: true\n      description: Get current mouse cursor position\n      operationId: getMousePosition_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/MousePosition'\n          description: Mouse position retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get mouse position\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/mouse/move:\n    post:\n      deprecated: true\n      description: Move mouse cursor to specified coordinates\n      operationId: moveMouse_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/MouseMoveRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/MouseMoveResponse'\n          description: Mouse moved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Move mouse\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/mouse/click:\n    post:\n      deprecated: true\n      description: Click mouse at specified coordinates\n      operationId: clickMouse_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/MouseClickRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/MouseClickResponse'\n          description: Mouse clicked successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Click mouse\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/mouse/drag:\n    post:\n      deprecated: true\n      description: Drag mouse from start to end coordinates\n      operationId: dragMouse_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/MouseDragRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/MouseDragResponse'\n          description: Mouse dragged successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Drag mouse\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/mouse/scroll:\n    post:\n      deprecated: true\n      description: Scroll mouse at specified coordinates\n      operationId: scrollMouse_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/MouseScrollRequest'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/MouseScrollResponse'\n          description: Mouse scrolled successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Scroll mouse\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/keyboard/type:\n    post:\n      deprecated: true\n      description: Type text using keyboard\n      operationId: typeText_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/KeyboardTypeRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Text typed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Type text\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/keyboard/key:\n    post:\n      deprecated: true\n      description: Press a key with optional modifiers\n      operationId: pressKey_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/KeyboardPressRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Key pressed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Press key\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/keyboard/hotkey:\n    post:\n      deprecated: true\n      description: Press a hotkey combination\n      operationId: pressHotkey_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/KeyboardHotkeyRequest'\n        required: true\n      responses:\n        \"200\":\n          description: Hotkey pressed successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Press hotkey\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/screenshot:\n    get:\n      deprecated: true\n      description: Take a screenshot of the entire screen\n      operationId: takeScreenshot_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: show_cursor\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/ScreenshotResponse'\n          description: Screenshot taken successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Take screenshot\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/screenshot/region:\n    get:\n      deprecated: true\n      description: Take a screenshot of a specific region\n      operationId: takeRegionScreenshot_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: show_cursor\n        required: false\n        schema:\n          type: boolean\n        style: form\n      - explode: true\n        in: query\n        name: height\n        required: true\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: width\n        required: true\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: \"y\"\n        required: true\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: x\n        required: true\n        schema:\n          type: number\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RegionScreenshotResponse'\n          description: Region screenshot taken successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Take region screenshot\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/screenshot/compressed:\n    get:\n      deprecated: true\n      description: \"Take a compressed screenshot with format, quality, and scale options\"\n      operationId: takeCompressedScreenshot_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: scale\n        required: false\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: quality\n        required: false\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: format\n        required: false\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: show_cursor\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CompressedScreenshotResponse'\n          description: Compressed screenshot taken successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Take compressed screenshot\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/screenshot/region/compressed:\n    get:\n      deprecated: true\n      description: Take a compressed screenshot of a specific region\n      operationId: takeCompressedRegionScreenshot_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: scale\n        required: false\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: quality\n        required: false\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: format\n        required: false\n        schema:\n          type: string\n        style: form\n      - explode: true\n        in: query\n        name: show_cursor\n        required: false\n        schema:\n          type: boolean\n        style: form\n      - explode: true\n        in: query\n        name: height\n        required: true\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: width\n        required: true\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: \"y\"\n        required: true\n        schema:\n          type: number\n        style: form\n      - explode: true\n        in: query\n        name: x\n        required: true\n        schema:\n          type: number\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CompressedScreenshotResponse'\n          description: Compressed region screenshot taken successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Take compressed region screenshot\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/display/info:\n    get:\n      deprecated: true\n      description: Get information about displays\n      operationId: getDisplayInfo_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/DisplayInfoResponse'\n          description: Display info retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get display info\"\n      tags:\n      - toolbox\n  /toolbox/{sandboxId}/toolbox/computeruse/display/windows:\n    get:\n      deprecated: true\n      description: Get list of open windows\n      operationId: getWindows_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/WindowsResponse'\n          description: Windows list retrieved successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get windows\"\n      tags:\n      - toolbox\n  /snapshots:\n    get:\n      operationId: getAllSnapshots\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Page number of the results\n        explode: true\n        in: query\n        name: page\n        required: false\n        schema:\n          default: 1\n          minimum: 1\n          type: number\n        style: form\n      - description: Number of results per page\n        explode: true\n        in: query\n        name: limit\n        required: false\n        schema:\n          default: 100\n          maximum: 200\n          minimum: 1\n          type: number\n        style: form\n      - description: Filter by partial name match\n        explode: true\n        in: query\n        name: name\n        required: false\n        schema:\n          example: abc123\n          type: string\n        style: form\n      - description: Field to sort by\n        explode: true\n        in: query\n        name: sort\n        required: false\n        schema:\n          default: lastUsedAt\n          enum:\n          - name\n          - state\n          - lastUsedAt\n          - createdAt\n          type: string\n        style: form\n      - description: Direction to sort by\n        explode: true\n        in: query\n        name: order\n        required: false\n        schema:\n          default: desc\n          enum:\n          - asc\n          - desc\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PaginatedSnapshots'\n          description: Paginated list of all snapshots\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all snapshots\n      tags:\n      - snapshots\n    post:\n      operationId: createSnapshot\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateSnapshot'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SnapshotDto'\n          description: The snapshot has been successfully created.\n        \"400\":\n          description: Bad request - Snapshots with tag \":latest\" are not allowed\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create a new snapshot\n      tags:\n      - snapshots\n  /snapshots/can-cleanup-image:\n    get:\n      operationId: canCleanupImage\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Image name with tag to check\n        explode: true\n        in: query\n        name: imageName\n        required: true\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                type: boolean\n          description: Boolean indicating if image can be cleaned up\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Check if an image can be cleaned up\n      tags:\n      - snapshots\n  /snapshots/{id}:\n    delete:\n      operationId: removeSnapshot\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Snapshot ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: Snapshot has been deleted\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete snapshot\n      tags:\n      - snapshots\n    get:\n      operationId: getSnapshot\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Snapshot ID or name\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SnapshotDto'\n          description: The snapshot\n        \"404\":\n          description: Snapshot not found\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get snapshot by ID or name\n      tags:\n      - snapshots\n  /snapshots/{id}/general:\n    patch:\n      operationId: setSnapshotGeneralStatus\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Snapshot ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/SetSnapshotGeneralStatusDto'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SnapshotDto'\n          description: Snapshot general status has been set\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Set snapshot general status\n      tags:\n      - snapshots\n  /snapshots/{id}/build-logs:\n    get:\n      deprecated: true\n      description: This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n      operationId: getSnapshotBuildLogs\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Snapshot ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Whether to follow the logs stream\n        explode: true\n        in: query\n        name: follow\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get snapshot build logs\n      tags:\n      - snapshots\n  /snapshots/{id}/build-logs-url:\n    get:\n      operationId: getSnapshotBuildLogsUrl\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Snapshot ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Url'\n          description: The snapshot build logs URL\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get snapshot build logs URL\n      tags:\n      - snapshots\n  /snapshots/{id}/activate:\n    post:\n      operationId: activateSnapshot\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Snapshot ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SnapshotDto'\n          description: The snapshot has been successfully activated.\n        \"400\":\n          description: \"Bad request - Snapshot is already active, not in inactive\\\n            \\ state, or has associated snapshot runners\"\n        \"404\":\n          description: Snapshot not found\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Activate a snapshot\n      tags:\n      - snapshots\n  /snapshots/{id}/deactivate:\n    post:\n      operationId: deactivateSnapshot\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Snapshot ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: The snapshot has been successfully deactivated.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Deactivate a snapshot\n      tags:\n      - snapshots\n  /workspace:\n    get:\n      deprecated: true\n      operationId: listWorkspaces_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Include verbose output\n        explode: true\n        in: query\n        name: verbose\n        required: false\n        schema:\n          type: boolean\n        style: form\n      - description: JSON encoded labels to filter by\n        explode: true\n        in: query\n        name: labels\n        required: false\n        schema:\n          example: \"{\\\"label1\\\": \\\"value1\\\", \\\"label2\\\": \\\"value2\\\"}\"\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/Workspace'\n                type: array\n          description: List of all workspacees\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] List all workspaces\"\n      tags:\n      - workspace\n    post:\n      deprecated: true\n      operationId: createWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateWorkspace'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Workspace'\n          description: The workspace has been successfully created.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Create a new workspace\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}:\n    delete:\n      deprecated: true\n      operationId: deleteWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: true\n        in: query\n        name: force\n        required: true\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          description: Workspace has been deleted\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Delete workspace\"\n      tags:\n      - workspace\n    get:\n      deprecated: true\n      operationId: getWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Include verbose output\n        explode: true\n        in: query\n        name: verbose\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Workspace'\n          description: Workspace details\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get workspace details\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/start:\n    post:\n      deprecated: true\n      operationId: startWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: Workspace has been started\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Start workspace\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/stop:\n    post:\n      deprecated: true\n      operationId: stopWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: Workspace has been stopped\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Stop workspace\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/labels:\n    put:\n      deprecated: true\n      operationId: replaceLabelsWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/SandboxLabels'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/SandboxLabels'\n          description: Labels have been successfully replaced\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Replace workspace labels\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/backup:\n    post:\n      deprecated: true\n      operationId: createBackupWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Workspace'\n          description: Workspace backup has been initiated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Create workspace backup\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/public/{isPublic}:\n    post:\n      deprecated: true\n      operationId: updatePublicStatusWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Public status to set\n        explode: false\n        in: path\n        name: isPublic\n        required: true\n        schema:\n          type: boolean\n        style: simple\n      responses:\n        \"201\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Update public status\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/autostop/{interval}:\n    post:\n      deprecated: true\n      operationId: setAutostopIntervalWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Auto-stop interval in minutes (0 to disable)\n        explode: false\n        in: path\n        name: interval\n        required: true\n        schema:\n          type: number\n        style: simple\n      responses:\n        \"200\":\n          description: Auto-stop interval has been set\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Set workspace auto-stop interval\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/autoarchive/{interval}:\n    post:\n      deprecated: true\n      operationId: setAutoArchiveIntervalWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Auto-archive interval in minutes (0 means the maximum interval\n          will be used)\n        explode: false\n        in: path\n        name: interval\n        required: true\n        schema:\n          type: number\n        style: simple\n      responses:\n        \"200\":\n          description: Auto-archive interval has been set\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Set workspace auto-archive interval\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/archive:\n    post:\n      deprecated: true\n      operationId: archiveWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: Workspace has been archived\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Archive workspace\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/ports/{port}/preview-url:\n    get:\n      deprecated: true\n      operationId: getPortPreviewUrlWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Port number to get preview URL for\n        explode: false\n        in: path\n        name: port\n        required: true\n        schema:\n          type: number\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/WorkspacePortPreviewUrl'\n          description: Preview URL for the specified port\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get preview URL for a workspace port\"\n      tags:\n      - workspace\n  /workspace/{workspaceId}/build-logs:\n    get:\n      deprecated: true\n      operationId: getBuildLogsWorkspace_deprecated\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the workspace\n        explode: false\n        in: path\n        name: workspaceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Whether to follow the logs stream\n        explode: true\n        in: query\n        name: follow\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          description: Build logs stream\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: \"[DEPRECATED] Get build logs\"\n      tags:\n      - workspace\n  /preview/{sandboxId}/public:\n    get:\n      operationId: isSandboxPublic\n      parameters:\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                type: boolean\n          description: Public status of the sandbox\n      summary: Check if sandbox is public\n      tags:\n      - preview\n  /preview/{sandboxId}/validate/{authToken}:\n    get:\n      operationId: isValidAuthToken\n      parameters:\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Auth token of the sandbox\n        explode: false\n        in: path\n        name: authToken\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                type: boolean\n          description: Sandbox auth token validation status\n      summary: Check if sandbox auth token is valid\n      tags:\n      - preview\n  /preview/{sandboxId}/access:\n    get:\n      operationId: hasSandboxAccess\n      parameters:\n      - explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                type: boolean\n          description: User access status to the sandbox\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Check if user has access to the sandbox\n      tags:\n      - preview\n  /preview/{signedPreviewToken}/{port}/sandbox-id:\n    get:\n      operationId: getSandboxIdFromSignedPreviewUrlToken\n      parameters:\n      - description: Signed preview URL token\n        explode: false\n        in: path\n        name: signedPreviewToken\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Port number to get sandbox ID from signed preview URL token\n        explode: false\n        in: path\n        name: port\n        required: true\n        schema:\n          type: number\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                type: string\n          description: Sandbox ID from signed preview URL token\n      summary: Get sandbox ID from signed preview URL token\n      tags:\n      - preview\n  /volumes:\n    get:\n      operationId: listVolumes\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Include deleted volumes in the response\n        explode: true\n        in: query\n        name: includeDeleted\n        required: false\n        schema:\n          type: boolean\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/VolumeDto'\n                type: array\n          description: List of all volumes\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all volumes\n      tags:\n      - volumes\n    post:\n      operationId: createVolume\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateVolume'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/VolumeDto'\n          description: The volume has been successfully created.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create a new volume\n      tags:\n      - volumes\n  /volumes/{volumeId}:\n    delete:\n      operationId: deleteVolume\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the volume\n        explode: false\n        in: path\n        name: volumeId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          description: Volume has been marked for deletion\n        \"409\":\n          description: Volume is in use by one or more sandboxes\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete volume\n      tags:\n      - volumes\n    get:\n      operationId: getVolume\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the volume\n        explode: false\n        in: path\n        name: volumeId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/VolumeDto'\n          description: Volume details\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get volume details\n      tags:\n      - volumes\n  /volumes/by-name/{name}:\n    get:\n      operationId: getVolumeByName\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: Name of the volume\n        explode: false\n        in: path\n        name: name\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/VolumeDto'\n          description: Volume details\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get volume details by name\n      tags:\n      - volumes\n  /jobs:\n    get:\n      description: \"Returns a paginated list of jobs for the runner, optionally filtered\\\n        \\ by status.\"\n      operationId: listJobs\n      parameters:\n      - description: Page number of the results\n        explode: true\n        in: query\n        name: page\n        required: false\n        schema:\n          default: 1\n          minimum: 1\n          type: number\n        style: form\n      - description: \"Maximum number of jobs to return (default: 100, max: 500)\"\n        explode: true\n        in: query\n        name: limit\n        required: false\n        schema:\n          default: 100\n          maximum: 200\n          minimum: 1\n          type: number\n        style: form\n      - description: Filter jobs by status\n        explode: true\n        in: query\n        name: status\n        required: false\n        schema:\n          $ref: '#/components/schemas/JobStatus'\n        style: form\n      - description: \"Number of jobs to skip for pagination (default: 0)\"\n        explode: true\n        in: query\n        name: offset\n        required: false\n        schema:\n          type: number\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PaginatedJobs'\n          description: List of jobs for the runner\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List jobs for the runner\n      tags:\n      - jobs\n  /jobs/poll:\n    get:\n      description: \"Long poll endpoint for runners to fetch pending jobs. Returns\\\n        \\ immediately if jobs are available, otherwise waits up to timeout seconds.\"\n      operationId: pollJobs\n      parameters:\n      - description: \"Timeout in seconds for long polling (default: 30, max: 60)\"\n        explode: true\n        in: query\n        name: timeout\n        required: false\n        schema:\n          type: number\n        style: form\n      - description: \"Maximum number of jobs to return (default: 10, max: 100)\"\n        explode: true\n        in: query\n        name: limit\n        required: false\n        schema:\n          type: number\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PollJobsResponse'\n          description: List of jobs for the runner\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Long poll for jobs\n      tags:\n      - jobs\n  /jobs/{jobId}:\n    get:\n      operationId: getJob\n      parameters:\n      - description: ID of the job\n        explode: false\n        in: path\n        name: jobId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Job'\n          description: Job details\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get job details\n      tags:\n      - jobs\n  /jobs/{jobId}/status:\n    post:\n      operationId: updateJobStatus\n      parameters:\n      - description: ID of the job\n        explode: false\n        in: path\n        name: jobId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateJobStatus'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Job'\n          description: Job status updated successfully\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update job status\n      tags:\n      - jobs\n  /docker-registry:\n    get:\n      operationId: listRegistries\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/DockerRegistry'\n                type: array\n          description: List of all docker registries\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List registries\n      tags:\n      - docker-registry\n    post:\n      operationId: createRegistry\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/CreateDockerRegistry'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/DockerRegistry'\n          description: The docker registry has been successfully created.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create registry\n      tags:\n      - docker-registry\n  /docker-registry/registry-push-access:\n    get:\n      operationId: getTransientPushAccess\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the region where the snapshot will be available (defaults\n          to organization default region)\n        explode: true\n        in: query\n        name: regionId\n        required: false\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RegistryPushAccessDto'\n          description: Temporary registry access has been generated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get temporary registry access for pushing snapshots\n      tags:\n      - docker-registry\n  /docker-registry/{id}:\n    delete:\n      operationId: deleteRegistry\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the docker registry\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: The docker registry has been successfully deleted.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete registry\n      tags:\n      - docker-registry\n    get:\n      operationId: getRegistry\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the docker registry\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/DockerRegistry'\n          description: The docker registry\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get registry\n      tags:\n      - docker-registry\n    patch:\n      operationId: updateRegistry\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the docker registry\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/UpdateDockerRegistry'\n        required: true\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/DockerRegistry'\n          description: The docker registry has been successfully updated.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update registry\n      tags:\n      - docker-registry\n  /docker-registry/{id}/set-default:\n    post:\n      operationId: setDefaultRegistry\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the docker registry\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/DockerRegistry'\n          description: The docker registry has been set as default.\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Set default registry\n      tags:\n      - docker-registry\n  /admin/runners:\n    get:\n      operationId: adminListRunners\n      parameters:\n      - description: Filter runners by region ID\n        explode: true\n        in: query\n        name: regionId\n        required: false\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/RunnerFull'\n                type: array\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: List all runners\n      tags:\n      - admin\n    post:\n      operationId: adminCreateRunner\n      parameters: []\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/AdminCreateRunner'\n        required: true\n      responses:\n        \"201\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/CreateRunnerResponse'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Create runner\n      tags:\n      - admin\n  /admin/runners/{id}:\n    delete:\n      operationId: adminDeleteRunner\n      parameters:\n      - description: Runner ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Delete runner\n      tags:\n      - admin\n    get:\n      operationId: adminGetRunnerById\n      parameters:\n      - description: Runner ID\n        explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/RunnerFull'\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get runner by ID\n      tags:\n      - admin\n  /admin/runners/{id}/scheduling:\n    patch:\n      operationId: adminUpdateRunnerScheduling\n      parameters:\n      - explode: false\n        in: path\n        name: id\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"204\":\n          description: \"\"\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Update runner scheduling status\n      tags:\n      - admin\n  /admin/sandbox/{sandboxId}/recover:\n    post:\n      operationId: adminRecoverSandbox\n      parameters:\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/Sandbox'\n          description: Recovery initiated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Recover sandbox from error state as an admin\n      tags:\n      - admin\n  /webhooks/organizations/{organizationId}/app-portal-access:\n    post:\n      operationId: WebhookController_getAppPortalAccess\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/WebhookAppPortalAccess'\n          description: App Portal access generated successfully\n      security:\n      - bearer: []\n      summary: Get Svix Consumer App Portal access for an organization\n      tags:\n      - webhooks\n  /webhooks/organizations/{organizationId}/send:\n    post:\n      operationId: WebhookController_sendWebhook\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: '#/components/schemas/SendWebhookDto'\n        required: true\n      responses:\n        \"200\":\n          description: Webhook message sent successfully\n      security:\n      - bearer: []\n      summary: Send a webhook message to an organization\n      tags:\n      - webhooks\n  /webhooks/organizations/{organizationId}/messages/{messageId}/attempts:\n    get:\n      operationId: WebhookController_getMessageAttempts\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: messageId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  type: object\n                type: array\n          description: List of delivery attempts\n      security:\n      - bearer: []\n      summary: Get delivery attempts for a webhook message\n      tags:\n      - webhooks\n  /webhooks/status:\n    get:\n      operationId: WebhookController_getStatus\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/WebhookController_getStatus_200_response'\n          description: Webhook service status\n      security:\n      - bearer: []\n      summary: Get webhook service status\n      tags:\n      - webhooks\n  /webhooks/organizations/{organizationId}/initialization-status:\n    get:\n      operationId: WebhookController_getInitializationStatus\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/WebhookInitializationStatus'\n          description: Webhook initialization status\n        \"404\":\n          description: Webhook initialization status not found\n      security:\n      - bearer: []\n      summary: Get webhook initialization status for an organization\n      tags:\n      - webhooks\n  /webhooks/organizations/{organizationId}/initialize:\n    post:\n      operationId: WebhookController_initializeWebhooks\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"201\":\n          description: Webhooks initialized successfully\n        \"403\":\n          description: User does not have access to this organization\n        \"404\":\n          description: Organization not found\n      security:\n      - bearer: []\n      summary: Initialize webhooks for an organization\n      tags:\n      - webhooks\n  /object-storage/push-access:\n    get:\n      operationId: getPushAccess\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/StorageAccessDto'\n          description: Temporary storage access has been generated\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get temporary storage access for pushing objects\n      tags:\n      - object-storage\n  /audit:\n    get:\n      operationId: getAllAuditLogs\n      parameters:\n      - description: Page number of the results\n        explode: true\n        in: query\n        name: page\n        required: false\n        schema:\n          default: 1\n          minimum: 1\n          type: number\n        style: form\n      - description: Number of results per page\n        explode: true\n        in: query\n        name: limit\n        required: false\n        schema:\n          default: 100\n          maximum: 200\n          minimum: 1\n          type: number\n        style: form\n      - description: From date (ISO 8601 format)\n        explode: true\n        in: query\n        name: from\n        required: false\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: To date (ISO 8601 format)\n        explode: true\n        in: query\n        name: to\n        required: false\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: \"Token for cursor-based pagination. When provided, takes precedence\\\n          \\ over page parameter.\"\n        explode: true\n        in: query\n        name: nextToken\n        required: false\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PaginatedAuditLogs'\n          description: Paginated list of all audit logs\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get all audit logs\n      tags:\n      - audit\n  /audit/organizations/{organizationId}:\n    get:\n      operationId: getOrganizationAuditLogs\n      parameters:\n      - description: Organization ID\n        explode: false\n        in: path\n        name: organizationId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Page number of the results\n        explode: true\n        in: query\n        name: page\n        required: false\n        schema:\n          default: 1\n          minimum: 1\n          type: number\n        style: form\n      - description: Number of results per page\n        explode: true\n        in: query\n        name: limit\n        required: false\n        schema:\n          default: 100\n          maximum: 200\n          minimum: 1\n          type: number\n        style: form\n      - description: From date (ISO 8601 format)\n        explode: true\n        in: query\n        name: from\n        required: false\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: To date (ISO 8601 format)\n        explode: true\n        in: query\n        name: to\n        required: false\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: \"Token for cursor-based pagination. When provided, takes precedence\\\n          \\ over page parameter.\"\n        explode: true\n        in: query\n        name: nextToken\n        required: false\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PaginatedAuditLogs'\n          description: Paginated list of organization audit logs\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get audit logs for organization\n      tags:\n      - audit\n  /health:\n    get:\n      operationId: HealthController_live\n      parameters: []\n      responses:\n        \"200\":\n          description: \"\"\n      tags:\n      - Health\n  /health/ready:\n    get:\n      operationId: HealthController_check\n      parameters: []\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/HealthController_check_200_response'\n          description: The Health Check is successful\n        \"503\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/HealthController_check_503_response'\n          description: The Health Check is not successful\n      tags:\n      - Health\n  /sandbox/{sandboxId}/telemetry/logs:\n    get:\n      description: Retrieve OTEL logs for a sandbox within a time range\n      operationId: getSandboxLogs\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Start of time range (ISO 8601)\n        explode: true\n        in: query\n        name: from\n        required: true\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: End of time range (ISO 8601)\n        explode: true\n        in: query\n        name: to\n        required: true\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: Page number (1-indexed)\n        explode: true\n        in: query\n        name: page\n        required: false\n        schema:\n          default: 1\n          type: number\n        style: form\n      - description: Number of items per page\n        explode: true\n        in: query\n        name: limit\n        required: false\n        schema:\n          default: 100\n          type: number\n        style: form\n      - description: \"Filter by severity levels (DEBUG, INFO, WARN, ERROR)\"\n        explode: true\n        in: query\n        name: severities\n        required: false\n        schema:\n          items:\n            type: string\n          type: array\n        style: form\n      - description: Search in log body\n        explode: true\n        in: query\n        name: search\n        required: false\n        schema:\n          type: string\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PaginatedLogs'\n          description: Paginated list of log entries\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get sandbox logs\n      tags:\n      - sandbox\n  /sandbox/{sandboxId}/telemetry/traces:\n    get:\n      description: Retrieve OTEL traces for a sandbox within a time range\n      operationId: getSandboxTraces\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Start of time range (ISO 8601)\n        explode: true\n        in: query\n        name: from\n        required: true\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: End of time range (ISO 8601)\n        explode: true\n        in: query\n        name: to\n        required: true\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: Page number (1-indexed)\n        explode: true\n        in: query\n        name: page\n        required: false\n        schema:\n          default: 1\n          type: number\n        style: form\n      - description: Number of items per page\n        explode: true\n        in: query\n        name: limit\n        required: false\n        schema:\n          default: 100\n          type: number\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/PaginatedTraces'\n          description: Paginated list of trace summaries\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get sandbox traces\n      tags:\n      - sandbox\n  /sandbox/{sandboxId}/telemetry/traces/{traceId}:\n    get:\n      description: Retrieve all spans for a specific trace\n      operationId: getSandboxTraceSpans\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: ID of the trace\n        explode: false\n        in: path\n        name: traceId\n        required: true\n        schema:\n          type: string\n        style: simple\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                items:\n                  $ref: '#/components/schemas/TraceSpan'\n                type: array\n          description: List of spans in the trace\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get trace spans\n      tags:\n      - sandbox\n  /sandbox/{sandboxId}/telemetry/metrics:\n    get:\n      description: Retrieve OTEL metrics for a sandbox within a time range\n      operationId: getSandboxMetrics\n      parameters:\n      - description: Use with JWT to specify the organization ID\n        explode: false\n        in: header\n        name: X-Daytona-Organization-ID\n        required: false\n        schema:\n          type: string\n        style: simple\n      - description: ID of the sandbox\n        explode: false\n        in: path\n        name: sandboxId\n        required: true\n        schema:\n          type: string\n        style: simple\n      - description: Start of time range (ISO 8601)\n        explode: true\n        in: query\n        name: from\n        required: true\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: End of time range (ISO 8601)\n        explode: true\n        in: query\n        name: to\n        required: true\n        schema:\n          format: date-time\n          type: string\n        style: form\n      - description: Filter by metric names\n        explode: true\n        in: query\n        name: metricNames\n        required: false\n        schema:\n          items:\n            type: string\n          type: array\n        style: form\n      responses:\n        \"200\":\n          content:\n            application/json:\n              schema:\n                $ref: '#/components/schemas/MetricsResponse'\n          description: Metrics time series data\n      security:\n      - bearer: []\n      - oauth2:\n        - openid\n        - profile\n        - email\n      summary: Get sandbox metrics\n      tags:\n      - sandbox\ncomponents:\n  schemas:\n    Announcement:\n      properties:\n        text:\n          description: The announcement text\n          example: New feature available!\n          type: string\n        learnMoreUrl:\n          description: URL to learn more about the announcement\n          example: https://example.com/learn-more\n          type: string\n      required:\n      - text\n      type: object\n    PosthogConfig:\n      properties:\n        apiKey:\n          description: PostHog API key\n          example: phc_abc123\n          type: string\n        host:\n          description: PostHog host URL\n          example: https://app.posthog.com\n          type: string\n      required:\n      - apiKey\n      - host\n      type: object\n    OidcConfig:\n      properties:\n        issuer:\n          description: OIDC issuer\n          example: https://auth.example.com\n          type: string\n        clientId:\n          description: OIDC client ID\n          example: daytona-client\n          type: string\n        audience:\n          description: OIDC audience\n          example: daytona-api\n          type: string\n      required:\n      - audience\n      - clientId\n      - issuer\n      type: object\n    RateLimitEntry:\n      properties:\n        ttl:\n          description: Rate limit TTL in seconds\n          example: 60\n          type: number\n        limit:\n          description: Rate limit max requests\n          example: 100\n          type: number\n      type: object\n    RateLimitConfig:\n      properties:\n        failedAuth:\n          allOf:\n          - $ref: '#/components/schemas/RateLimitEntry'\n          description: Failed authentication rate limit\n        authenticated:\n          allOf:\n          - $ref: '#/components/schemas/RateLimitEntry'\n          description: Authenticated rate limit\n        sandboxCreate:\n          allOf:\n          - $ref: '#/components/schemas/RateLimitEntry'\n          description: Sandbox create rate limit\n        sandboxLifecycle:\n          allOf:\n          - $ref: '#/components/schemas/RateLimitEntry'\n          description: Sandbox lifecycle rate limit\n      type: object\n    DaytonaConfiguration:\n      example:\n        dashboardUrl: https://dashboard.example.com\n        rateLimit: \"\"\n        analyticsApiUrl: https://analytics.example.com\n        sshGatewayPublicKey: ssh-gateway-public-key\n        billingApiUrl: https://billing.example.com\n        linkedAccountsEnabled: true\n        version: 0.0.1\n        oidc: \"\"\n        proxyToolboxUrl: https://proxy.example.com/toolbox\n        posthog: \"\"\n        maxAutoArchiveInterval: 43200\n        pylonAppId: pylon-app-123\n        proxyTemplateUrl: \"https://{{PORT}}-{{sandboxId}}.proxy.example.com\"\n        maintananceMode: false\n        environment: production\n        defaultSnapshot: ubuntu:22.04\n        sshGatewayCommand: \"ssh -p 2222 {{TOKEN}}@localhost\"\n        announcements:\n          feature-update:\n            text: New feature available!\n            learnMoreUrl: https://example.com\n      properties:\n        version:\n          description: Daytona version\n          example: 0.0.1\n          type: string\n        posthog:\n          allOf:\n          - $ref: '#/components/schemas/PosthogConfig'\n          description: PostHog configuration\n        oidc:\n          allOf:\n          - $ref: '#/components/schemas/OidcConfig'\n          description: OIDC configuration\n        linkedAccountsEnabled:\n          description: Whether linked accounts are enabled\n          example: true\n          type: boolean\n        announcements:\n          additionalProperties:\n            $ref: '#/components/schemas/Announcement'\n          description: System announcements\n          example:\n            feature-update:\n              text: New feature available!\n              learnMoreUrl: https://example.com\n          type: object\n        pylonAppId:\n          description: Pylon application ID\n          example: pylon-app-123\n          type: string\n        proxyTemplateUrl:\n          description: Proxy template URL\n          example: \"https://{{PORT}}-{{sandboxId}}.proxy.example.com\"\n          type: string\n        proxyToolboxUrl:\n          description: Toolbox template URL\n          example: https://proxy.example.com/toolbox\n          type: string\n        defaultSnapshot:\n          description: Default snapshot for sandboxes\n          example: ubuntu:22.04\n          type: string\n        dashboardUrl:\n          description: Dashboard URL\n          example: https://dashboard.example.com\n          type: string\n        maxAutoArchiveInterval:\n          description: Maximum auto-archive interval in minutes\n          example: 43200\n          type: number\n        maintananceMode:\n          description: Whether maintenance mode is enabled\n          example: false\n          type: boolean\n        environment:\n          description: Current environment\n          example: production\n          type: string\n        billingApiUrl:\n          description: Billing API URL\n          example: https://billing.example.com\n          type: string\n        analyticsApiUrl:\n          description: Analytics API URL\n          example: https://analytics.example.com\n          type: string\n        sshGatewayCommand:\n          description: SSH Gateway command\n          example: \"ssh -p 2222 {{TOKEN}}@localhost\"\n          type: string\n        sshGatewayPublicKey:\n          description: Base64 encoded SSH Gateway public key\n          example: ssh-gateway-public-key\n          type: string\n        rateLimit:\n          allOf:\n          - $ref: '#/components/schemas/RateLimitConfig'\n          description: Rate limit configuration\n      required:\n      - announcements\n      - dashboardUrl\n      - defaultSnapshot\n      - environment\n      - linkedAccountsEnabled\n      - maintananceMode\n      - maxAutoArchiveInterval\n      - oidc\n      - proxyTemplateUrl\n      - proxyToolboxUrl\n      - version\n      type: object\n    CreateApiKey:\n      example:\n        permissions:\n        - write:registries\n        - write:registries\n        name: My API Key\n        expiresAt: 2025-06-09T12:00:00Z\n      properties:\n        name:\n          description: The name of the API key\n          example: My API Key\n          type: string\n        permissions:\n          description: The list of organization resource permissions explicitly assigned\n            to the API key\n          items:\n            enum:\n            - write:registries\n            - delete:registries\n            - write:snapshots\n            - delete:snapshots\n            - write:sandboxes\n            - delete:sandboxes\n            - read:volumes\n            - write:volumes\n            - delete:volumes\n            - write:regions\n            - delete:regions\n            - read:runners\n            - write:runners\n            - delete:runners\n            - read:audit_logs\n            type: string\n          type: array\n        expiresAt:\n          description: When the API key expires\n          example: 2025-06-09T12:00:00Z\n          format: date-time\n          nullable: true\n          type: string\n      required:\n      - name\n      - permissions\n      type: object\n    ApiKeyResponse:\n      example:\n        createdAt: 2024-03-14T12:00:00Z\n        permissions:\n        - write:registries\n        - write:registries\n        name: My API Key\n        value: bb_sk_1234567890abcdef\n        expiresAt: 2025-06-09T12:00:00Z\n      properties:\n        name:\n          description: The name of the API key\n          example: My API Key\n          type: string\n        value:\n          description: The API key value\n          example: bb_sk_1234567890abcdef\n          type: string\n        createdAt:\n          description: When the API key was created\n          example: 2024-03-14T12:00:00Z\n          format: date-time\n          type: string\n        permissions:\n          description: The list of organization resource permissions assigned to the\n            API key\n          items:\n            enum:\n            - write:registries\n            - delete:registries\n            - write:snapshots\n            - delete:snapshots\n            - write:sandboxes\n            - delete:sandboxes\n            - read:volumes\n            - write:volumes\n            - delete:volumes\n            - write:regions\n            - delete:regions\n            - read:runners\n            - write:runners\n            - delete:runners\n            - read:audit_logs\n            type: string\n          type: array\n        expiresAt:\n          description: When the API key expires\n          example: 2025-06-09T12:00:00Z\n          format: date-time\n          nullable: true\n          type: string\n      required:\n      - createdAt\n      - expiresAt\n      - name\n      - permissions\n      - value\n      type: object\n    ApiKeyList:\n      example:\n        createdAt: 2024-03-14T12:00:00Z\n        lastUsedAt: 2024-03-14T12:00:00Z\n        permissions:\n        - write:registries\n        - write:registries\n        name: My API Key\n        value: bb_********************def\n        userId: \"123\"\n        expiresAt: 2024-03-14T12:00:00Z\n      properties:\n        name:\n          description: The name of the API key\n          example: My API Key\n          type: string\n        value:\n          description: The masked API key value\n          example: bb_********************def\n          type: string\n        createdAt:\n          description: When the API key was created\n          example: 2024-03-14T12:00:00Z\n          format: date-time\n          type: string\n        permissions:\n          description: The list of organization resource permissions assigned to the\n            API key\n          items:\n            enum:\n            - write:registries\n            - delete:registries\n            - write:snapshots\n            - delete:snapshots\n            - write:sandboxes\n            - delete:sandboxes\n            - read:volumes\n            - write:volumes\n            - delete:volumes\n            - write:regions\n            - delete:regions\n            - read:runners\n            - write:runners\n            - delete:runners\n            - read:audit_logs\n            type: string\n          type: array\n        lastUsedAt:\n          description: When the API key was last used\n          example: 2024-03-14T12:00:00Z\n          format: date-time\n          nullable: true\n          type: string\n        expiresAt:\n          description: When the API key expires\n          example: 2024-03-14T12:00:00Z\n          format: date-time\n          nullable: true\n          type: string\n        userId:\n          description: The user ID of the user who created the API key\n          example: \"123\"\n          type: string\n      required:\n      - createdAt\n      - expiresAt\n      - lastUsedAt\n      - name\n      - permissions\n      - userId\n      - value\n      type: object\n    OrganizationRole:\n      example:\n        createdAt: 2000-01-23T04:56:07.000+00:00\n        permissions:\n        - write:registries\n        - write:registries\n        name: name\n        isGlobal: true\n        description: description\n        id: id\n        updatedAt: 2000-01-23T04:56:07.000+00:00\n      properties:\n        id:\n          description: Role ID\n          type: string\n        name:\n          description: Role name\n          type: string\n        description:\n          description: Role description\n          type: string\n        permissions:\n          description: Roles assigned to the user\n          items:\n            enum:\n            - write:registries\n            - delete:registries\n            - write:snapshots\n            - delete:snapshots\n            - write:sandboxes\n            - delete:sandboxes\n            - read:volumes\n            - write:volumes\n            - delete:volumes\n            - write:regions\n            - delete:regions\n            - read:runners\n            - write:runners\n            - delete:runners\n            - read:audit_logs\n            type: string\n          type: array\n        isGlobal:\n          description: Global role flag\n          type: boolean\n        createdAt:\n          description: Creation timestamp\n          format: date-time\n          type: string\n        updatedAt:\n          description: Last update timestamp\n          format: date-time\n          type: string\n      required:\n      - createdAt\n      - description\n      - id\n      - isGlobal\n      - name\n      - permissions\n      - updatedAt\n      type: object\n    OrganizationInvitation:\n      example:\n        organizationId: organizationId\n        createdAt: 2000-01-23T04:56:07.000+00:00\n        invitedBy: invitedBy\n        role: owner\n        organizationName: organizationName\n        assignedRoles:\n        - createdAt: 2000-01-23T04:56:07.000+00:00\n          permissions:\n          - write:registries\n          - write:registries\n          name: name\n          isGlobal: true\n          description: description\n          id: id\n          updatedAt: 2000-01-23T04:56:07.000+00:00\n        - createdAt: 2000-01-23T04:56:07.000+00:00\n          permissions:\n          - write:registries\n          - write:registries\n          name: name\n          isGlobal: true\n          description: description\n          id: id\n          updatedAt: 2000-01-23T04:56:07.000+00:00\n        id: id\n        email: email\n        expiresAt: 2000-01-23T04:56:07.000+00:00\n        status: pending\n        updatedAt: 2000-01-23T04:56:07.000+00:00\n      properties:\n        id:\n          description: Invitation ID\n          type: string\n        email:\n          description: Email address of the invitee\n          type: string\n        invitedBy:\n          description: Email address of the inviter\n          type: string\n        organizationId:\n          description: Organization ID\n          type: string\n        organizationName:\n          description: Organization name\n          type: string\n        expiresAt:\n          description: Expiration date of the invitation\n          format: date-time\n          type: string\n        status:\n          description: Invitation status\n          enum:\n          - pending\n          - accepted\n          - declined\n          - cancelled\n          type: string\n        role:\n          description: Member role\n          enum:\n          - owner\n          - member\n          type: string\n        assignedRoles:\n          description: Assigned roles\n          items:\n            $ref: '#/components/schemas/OrganizationRole'\n          type: array\n        createdAt:\n          description: Creation timestamp\n          format: date-time\n          type: string\n        updatedAt:\n          description: Last update timestamp\n          format: date-time\n          type: string\n      required:\n      - assignedRoles\n      - createdAt\n      - email\n      - expiresAt\n      - id\n      - invitedBy\n      - organizationId\n      - organizationName\n      - role\n      - status\n      - updatedAt\n      type: object\n    CreateOrganization:\n      example:\n        defaultRegionId: us\n        name: My Organization\n      properties:\n        name:\n          description: The name of organization\n          example: My Organization\n          type: string\n        defaultRegionId:\n          description: The ID of the default region for the organization\n          example: us\n          type: string\n      required:\n      - defaultRegionId\n      - name\n      type: object\n    Organization:\n      example:\n        defaultRegionId: defaultRegionId\n        sandboxCreateRateLimitTtlSeconds: 2.027123023002322\n        suspensionReason: suspensionReason\n        sandboxLifecycleRateLimit: 9.301444243932576\n        suspendedAt: 2000-01-23T04:56:07.000+00:00\n        personal: true\n        suspensionCleanupGracePeriodHours: 0.8008281904610115\n        authenticatedRateLimit: 2.3021358869347655\n        suspended: true\n        sandboxCreateRateLimit: 7.061401241503109\n        sandboxLifecycleRateLimitTtlSeconds: 4.145608029883936\n        createdAt: 2000-01-23T04:56:07.000+00:00\n        maxCpuPerSandbox: 6.027456183070403\n        sandboxLimitedNetworkEgress: true\n        suspendedUntil: 2000-01-23T04:56:07.000+00:00\n        maxDiskPerSandbox: 5.962133916683182\n        createdBy: createdBy\n        snapshotDeactivationTimeoutMinutes: 5.637376656633329\n        name: name\n        maxMemoryPerSandbox: 1.4658129805029452\n        authenticatedRateLimitTtlSeconds: 3.616076749251911\n        id: id\n        experimentalConfig: \"{}\"\n        updatedAt: 2000-01-23T04:56:07.000+00:00\n      properties:\n        id:\n          description: Organization ID\n          type: string\n        name:\n          description: Organization name\n          type: string\n        createdBy:\n          description: User ID of the organization creator\n          type: string\n        personal:\n          description: Personal organization flag\n          type: boolean\n        createdAt:\n          description: Creation timestamp\n          format: date-time\n          type: string\n        updatedAt:\n          description: Last update timestamp\n          format: date-time\n          type: string\n        suspended:\n          description: Suspended flag\n          type: boolean\n        suspendedAt:\n          description: Suspended at\n          format: date-time\n          type: string\n        suspensionReason:\n          description: Suspended reason\n          type: string\n        suspendedUntil:\n          description: Suspended until\n          format: date-time\n          type: string\n        suspensionCleanupGracePeriodHours:\n          description: Suspension cleanup grace period hours\n          type: number\n        maxCpuPerSandbox:\n          description: Max CPU per sandbox\n          type: number\n        maxMemoryPerSandbox:\n          description: Max memory per sandbox\n          type: number\n        maxDiskPerSandbox:\n          description: Max disk per sandbox\n          type: number\n        snapshotDeactivationTimeoutMinutes:\n          default: 20160\n          description: Time in minutes before an unused snapshot is deactivated\n          type: number\n        sandboxLimitedNetworkEgress:\n          description: Sandbox default network block all\n          type: boolean\n        defaultRegionId:\n          description: Default region ID\n          type: string\n        authenticatedRateLimit:\n          description: Authenticated rate limit per minute\n          nullable: true\n          type: number\n        sandboxCreateRateLimit:\n          description: Sandbox create rate limit per minute\n          nullable: true\n          type: number\n        sandboxLifecycleRateLimit:\n          description: Sandbox lifecycle rate limit per minute\n          nullable: true\n          type: number\n        experimentalConfig:\n          description: Experimental configuration\n          type: object\n        authenticatedRateLimitTtlSeconds:\n          description: Authenticated rate limit TTL in seconds\n          nullable: true\n          type: number\n        sandboxCreateRateLimitTtlSeconds:\n          description: Sandbox create rate limit TTL in seconds\n          nullable: true\n          type: number\n        sandboxLifecycleRateLimitTtlSeconds:\n          description: Sandbox lifecycle rate limit TTL in seconds\n          nullable: true\n          type: number\n      required:\n      - authenticatedRateLimit\n      - authenticatedRateLimitTtlSeconds\n      - createdAt\n      - createdBy\n      - experimentalConfig\n      - id\n      - maxCpuPerSandbox\n      - maxDiskPerSandbox\n      - maxMemoryPerSandbox\n      - name\n      - personal\n      - sandboxCreateRateLimit\n      - sandboxCreateRateLimitTtlSeconds\n      - sandboxLifecycleRateLimit\n      - sandboxLifecycleRateLimitTtlSeconds\n      - sandboxLimitedNetworkEgress\n      - snapshotDeactivationTimeoutMinutes\n      - suspended\n      - suspendedAt\n      - suspendedUntil\n      - suspensionCleanupGracePeriodHours\n      - suspensionReason\n      - updatedAt\n      type: object\n    UpdateOrganizationDefaultRegion:\n      example:\n        defaultRegionId: us\n      properties:\n        defaultRegionId:\n          description: The ID of the default region for the organization\n          example: us\n          type: string\n      required:\n      - defaultRegionId\n      type: object\n    RegionUsageOverview:\n      example:\n        totalCpuQuota: 0.8008281904610115\n        regionId: regionId\n        currentDiskUsage: 2.3021358869347655\n        currentMemoryUsage: 5.962133916683182\n        currentCpuUsage: 6.027456183070403\n        totalMemoryQuota: 1.4658129805029452\n        totalDiskQuota: 5.637376656633329\n      properties:\n        regionId:\n          type: string\n        totalCpuQuota:\n          type: number\n        currentCpuUsage:\n          type: number\n        totalMemoryQuota:\n          type: number\n        currentMemoryUsage:\n          type: number\n        totalDiskQuota:\n          type: number\n        currentDiskUsage:\n          type: number\n      required:\n      - currentCpuUsage\n      - currentDiskUsage\n      - currentMemoryUsage\n      - regionId\n      - totalCpuQuota\n      - totalDiskQuota\n      - totalMemoryQuota\n      type: object\n    OrganizationUsageOverview:\n      example:\n        totalSnapshotQuota: 7.061401241503109\n        currentVolumeUsage: 2.027123023002322\n        totalVolumeQuota: 3.616076749251911\n        currentSnapshotUsage: 9.301444243932576\n        regionUsage:\n        - totalCpuQuota: 0.8008281904610115\n          regionId: regionId\n          currentDiskUsage: 2.3021358869347655\n          currentMemoryUsage: 5.962133916683182\n          currentCpuUsage: 6.027456183070403\n          totalMemoryQuota: 1.4658129805029452\n          totalDiskQuota: 5.637376656633329\n        - totalCpuQuota: 0.8008281904610115\n          regionId: regionId\n          currentDiskUsage: 2.3021358869347655\n          currentMemoryUsage: 5.962133916683182\n          currentCpuUsage: 6.027456183070403\n          totalMemoryQuota: 1.4658129805029452\n          totalDiskQuota: 5.637376656633329\n      properties:\n        regionUsage:\n          items:\n            $ref: '#/components/schemas/RegionUsageOverview'\n          type: array\n        totalSnapshotQuota:\n          type: number\n        currentSnapshotUsage:\n          type: number\n        totalVolumeQuota:\n          type: number\n        currentVolumeUsage:\n          type: number\n      required:\n      - currentSnapshotUsage\n      - currentVolumeUsage\n      - regionUsage\n      - totalSnapshotQuota\n      - totalVolumeQuota\n      type: object\n    UpdateOrganizationQuota:\n      example:\n        sandboxCreateRateLimitTtlSeconds: 4.145608029883936\n        sandboxLifecycleRateLimit: 3.616076749251911\n        volumeQuota: 2.3021358869347655\n        maxSnapshotSize: 5.637376656633329\n        authenticatedRateLimit: 7.061401241503109\n        sandboxCreateRateLimit: 9.301444243932576\n        snapshotQuota: 5.962133916683182\n        sandboxLifecycleRateLimitTtlSeconds: 7.386281948385884\n        maxCpuPerSandbox: 0.8008281904610115\n        maxDiskPerSandbox: 1.4658129805029452\n        snapshotDeactivationTimeoutMinutes: 1.2315135367772556\n        maxMemoryPerSandbox: 6.027456183070403\n        authenticatedRateLimitTtlSeconds: 2.027123023002322\n      properties:\n        maxCpuPerSandbox:\n          nullable: true\n          type: number\n        maxMemoryPerSandbox:\n          nullable: true\n          type: number\n        maxDiskPerSandbox:\n          nullable: true\n          type: number\n        snapshotQuota:\n          nullable: true\n          type: number\n        maxSnapshotSize:\n          nullable: true\n          type: number\n        volumeQuota:\n          nullable: true\n          type: number\n        authenticatedRateLimit:\n          nullable: true\n          type: number\n        sandboxCreateRateLimit:\n          nullable: true\n          type: number\n        sandboxLifecycleRateLimit:\n          nullable: true\n          type: number\n        authenticatedRateLimitTtlSeconds:\n          nullable: true\n          type: number\n        sandboxCreateRateLimitTtlSeconds:\n          nullable: true\n          type: number\n        sandboxLifecycleRateLimitTtlSeconds:\n          nullable: true\n          type: number\n        snapshotDeactivationTimeoutMinutes:\n          description: Time in minutes before an unused snapshot is deactivated\n          nullable: true\n          type: number\n      required:\n      - authenticatedRateLimit\n      - authenticatedRateLimitTtlSeconds\n      - maxCpuPerSandbox\n      - maxDiskPerSandbox\n      - maxMemoryPerSandbox\n      - maxSnapshotSize\n      - sandboxCreateRateLimit\n      - sandboxCreateRateLimitTtlSeconds\n      - sandboxLifecycleRateLimit\n      - sandboxLifecycleRateLimitTtlSeconds\n      - snapshotDeactivationTimeoutMinutes\n      - snapshotQuota\n      - volumeQuota\n      type: object\n    UpdateOrganizationRegionQuota:\n      example:\n        totalCpuQuota: 0.8008281904610115\n        totalMemoryQuota: 6.027456183070403\n        totalDiskQuota: 1.4658129805029452\n      properties:\n        totalCpuQuota:\n          nullable: true\n          type: number\n        totalMemoryQuota:\n          nullable: true\n          type: number\n        totalDiskQuota:\n          nullable: true\n          type: number\n      required:\n      - totalCpuQuota\n      - totalDiskQuota\n      - totalMemoryQuota\n      type: object\n    OrganizationSuspension:\n      example:\n        reason: reason\n        until: 2000-01-23T04:56:07.000+00:00\n        suspensionCleanupGracePeriodHours: 0.08008281904610115\n      properties:\n        reason:\n          description: Suspension reason\n          type: string\n        until:\n          description: Suspension until\n          format: date-time\n          type: string\n        suspensionCleanupGracePeriodHours:\n          description: Suspension cleanup grace period hours\n          minimum: 0\n          type: number\n      required:\n      - reason\n      - until\n      type: object\n    RegionQuota:\n      example:\n        organizationId: organizationId\n        totalCpuQuota: 0.8008281904610115\n        regionId: regionId\n        totalMemoryQuota: 6.027456183070403\n        totalDiskQuota: 1.4658129805029452\n      properties:\n        organizationId:\n          type: string\n        regionId:\n          type: string\n        totalCpuQuota:\n          type: number\n        totalMemoryQuota:\n          type: number\n        totalDiskQuota:\n          type: number\n      required:\n      - organizationId\n      - regionId\n      - totalCpuQuota\n      - totalDiskQuota\n      - totalMemoryQuota\n      type: object\n    OtelConfig:\n      example:\n        headers:\n          x-api-key: my-api-key\n        endpoint: endpoint\n      properties:\n        endpoint:\n          description: Endpoint\n          type: string\n        headers:\n          additionalProperties:\n            type: string\n          description: Headers\n          example:\n            x-api-key: my-api-key\n          nullable: true\n          type: object\n      required:\n      - endpoint\n      type: object\n    OrganizationSandboxDefaultLimitedNetworkEgress:\n      example:\n        sandboxDefaultLimitedNetworkEgress: true\n      properties:\n        sandboxDefaultLimitedNetworkEgress:\n          description: Sandbox default limited network egress\n          type: boolean\n      required:\n      - sandboxDefaultLimitedNetworkEgress\n      type: object\n    CreateOrganizationRole:\n      example:\n        permissions:\n        - write:registries\n        - write:registries\n        name: Maintainer\n        description: Can manage all resources\n      properties:\n        name:\n          description: The name of the role\n          example: Maintainer\n          type: string\n        description:\n          description: The description of the role\n          example: Can manage all resources\n          type: string\n        permissions:\n          description: The list of permissions assigned to the role\n          items:\n            enum:\n            - write:registries\n            - delete:registries\n            - write:snapshots\n            - delete:snapshots\n            - write:sandboxes\n            - delete:sandboxes\n            - read:volumes\n            - write:volumes\n            - delete:volumes\n            - write:regions\n            - delete:regions\n            - read:runners\n            - write:runners\n            - delete:runners\n            - read:audit_logs\n            type: string\n          type: array\n      required:\n      - description\n      - name\n      - permissions\n      type: object\n    UpdateOrganizationRole:\n      example:\n        permissions:\n        - write:registries\n        - write:registries\n        name: Maintainer\n        description: Can manage all resources\n      properties:\n        name:\n          description: The name of the role\n          example: Maintainer\n          type: string\n        description:\n          description: The description of the role\n          example: Can manage all resources\n          type: string\n        permissions:\n          description: The list of permissions assigned to the role\n          items:\n            enum:\n            - write:registries\n            - delete:registries\n            - write:snapshots\n            - delete:snapshots\n            - write:sandboxes\n            - delete:sandboxes\n            - read:volumes\n            - write:volumes\n            - delete:volumes\n            - write:regions\n            - delete:regions\n            - read:runners\n            - write:runners\n            - delete:runners\n            - read:audit_logs\n            type: string\n          type: array\n      required:\n      - description\n      - name\n      - permissions\n      type: object\n    OrganizationUser:\n      example:\n        organizationId: organizationId\n        createdAt: 2000-01-23T04:56:07.000+00:00\n        role: owner\n        assignedRoles:\n        - createdAt: 2000-01-23T04:56:07.000+00:00\n          permissions:\n          - write:registries\n          - write:registries\n          name: name\n          isGlobal: true\n          description: description\n          id: id\n          updatedAt: 2000-01-23T04:56:07.000+00:00\n        - createdAt: 2000-01-23T04:56:07.000+00:00\n          permissions:\n          - write:registries\n          - write:registries\n          name: name\n          isGlobal: true\n          description: description\n          id: id\n          updatedAt: 2000-01-23T04:56:07.000+00:00\n        name: name\n        userId: userId\n        email: email\n        updatedAt: 2000-01-23T04:56:07.000+00:00\n      properties:\n        userId:\n          description: User ID\n          type: string\n        organizationId:\n          description: Organization ID\n          type: string\n        name:\n          description: User name\n          type: string\n        email:\n          description: User email\n          type: string\n        role:\n          description: Member role\n          enum:\n          - owner\n          - member\n          type: string\n        assignedRoles:\n          description: Roles assigned to the user\n          items:\n            $ref: '#/components/schemas/OrganizationRole'\n          type: array\n        createdAt:\n          description: Creation timestamp\n          format: date-time\n          type: string\n        updatedAt:\n          description: Last update timestamp\n          format: date-time\n          type: string\n      required:\n      - assignedRoles\n      - createdAt\n      - email\n      - name\n      - organizationId\n      - role\n      - updatedAt\n      - userId\n      type: object\n    UpdateOrganizationMemberAccess:\n      example:\n        role: member\n        assignedRoleIds:\n        - assignedRoleIds\n        - assignedRoleIds\n      properties:\n        role:\n          default: member\n          description: Organization member role\n          enum:\n          - owner\n          - member\n          type: string\n        assignedRoleIds:\n          default:\n          - 00000000-0000-0000-0000-000000000001\n          description: Array of assigned role IDs\n          items:\n            type: string\n          type: array\n      required:\n      - assignedRoleIds\n      - role\n      type: object\n    CreateOrganizationInvitation:\n      example:\n        role: member\n        assignedRoleIds:\n        - assignedRoleIds\n        - assignedRoleIds\n        email: mail@example.com\n        expiresAt: 2021-12-31T23:59:59Z\n      properties:\n        email:\n          description: Email address of the invitee\n          example: mail@example.com\n          type: string\n        role:\n          default: member\n          description: Organization member role for the invitee\n          enum:\n          - owner\n          - member\n          type: string\n        assignedRoleIds:\n          default:\n          - 00000000-0000-0000-0000-000000000001\n          description: Array of assigned role IDs for the invitee\n          items:\n            type: string\n          type: array\n        expiresAt:\n          description: Expiration date of the invitation\n          example: 2021-12-31T23:59:59Z\n          format: date-time\n          type: string\n      required:\n      - assignedRoleIds\n      - email\n      - role\n      type: object\n    UpdateOrganizationInvitation:\n      example:\n        role: owner\n        assignedRoleIds:\n        - assignedRoleIds\n        - assignedRoleIds\n        expiresAt: 2021-12-31T23:59:59Z\n      properties:\n        role:\n          description: Organization member role\n          enum:\n          - owner\n          - member\n          type: string\n        assignedRoleIds:\n          description: Array of role IDs\n          items:\n            type: string\n          type: array\n        expiresAt:\n          description: Expiration date of the invitation\n          example: 2021-12-31T23:59:59Z\n          format: date-time\n          type: string\n      required:\n      - assignedRoleIds\n      - role\n      type: object\n    RegionType:\n      description: The type of the region\n      enum:\n      - shared\n      - dedicated\n      - custom\n      type: string\n    Region:\n      example:\n        organizationId: 123e4567-e89b-12d3-a456-426614174000\n        createdAt: 2023-01-01T00:00:00.000Z\n        snapshotManagerUrl: http://snapshot-manager.example.com\n        regionType: shared\n        proxyUrl: https://proxy.example.com\n        name: us-east-1\n        sshGatewayUrl: http://ssh-gateway.example.com\n        id: \"123456789012\"\n        updatedAt: 2023-01-01T00:00:00.000Z\n      properties:\n        id:\n          description: Region ID\n          example: \"123456789012\"\n          type: string\n        name:\n          description: Region name\n          example: us-east-1\n          type: string\n        organizationId:\n          description: Organization ID\n          example: 123e4567-e89b-12d3-a456-426614174000\n          nullable: true\n          type: string\n        regionType:\n          allOf:\n          - $ref: '#/components/schemas/RegionType'\n          description: The type of the region\n          example: shared\n        createdAt:\n          description: Creation timestamp\n          example: 2023-01-01T00:00:00.000Z\n          type: string\n        updatedAt:\n          description: Last update timestamp\n          example: 2023-01-01T00:00:00.000Z\n          type: string\n        proxyUrl:\n          description: Proxy URL for the region\n          example: https://proxy.example.com\n          nullable: true\n          type: string\n        sshGatewayUrl:\n          description: SSH Gateway URL for the region\n          example: http://ssh-gateway.example.com\n          nullable: true\n          type: string\n        snapshotManagerUrl:\n          description: Snapshot Manager URL for the region\n          example: http://snapshot-manager.example.com\n          nullable: true\n          type: string\n      required:\n      - createdAt\n      - id\n      - name\n      - regionType\n      - updatedAt\n      type: object\n    CreateRegion:\n      example:\n        snapshotManagerUrl: https://snapshot-manager.example.com\n        proxyUrl: https://proxy.example.com\n        name: us-east-1\n        sshGatewayUrl: ssh://ssh-gateway.example.com\n      properties:\n        name:\n          description: Region name\n          example: us-east-1\n          type: string\n        proxyUrl:\n          description: Proxy URL for the region\n          example: https://proxy.example.com\n          nullable: true\n          type: string\n        sshGatewayUrl:\n          description: SSH Gateway URL for the region\n          example: ssh://ssh-gateway.example.com\n          nullable: true\n          type: string\n        snapshotManagerUrl:\n          description: Snapshot Manager URL for the region\n          example: https://snapshot-manager.example.com\n          nullable: true\n          type: string\n      required:\n      - name\n      type: object\n    CreateRegionResponse:\n      example:\n        proxyApiKey: proxy-api-key-xyz\n        snapshotManagerUsername: daytona\n        snapshotManagerPassword: snapshotManagerPassword\n        id: region_12345\n        sshGatewayApiKey: ssh-gateway-api-key-abc\n      properties:\n        id:\n          description: ID of the created region\n          example: region_12345\n          type: string\n        proxyApiKey:\n          description: Proxy API key for the region\n          example: proxy-api-key-xyz\n          nullable: true\n          type: string\n        sshGatewayApiKey:\n          description: SSH Gateway API key for the region\n          example: ssh-gateway-api-key-abc\n          nullable: true\n          type: string\n        snapshotManagerUsername:\n          description: Snapshot Manager username for the region\n          example: daytona\n          nullable: true\n          type: string\n        snapshotManagerPassword:\n          description: Snapshot Manager password for the region\n          nullable: true\n          type: string\n      required:\n      - id\n      type: object\n    RegenerateApiKeyResponse:\n      example:\n        apiKey: api-key-xyz123\n      properties:\n        apiKey:\n          description: The newly generated API key\n          example: api-key-xyz123\n          type: string\n      required:\n      - apiKey\n      type: object\n    UpdateRegion:\n      example:\n        snapshotManagerUrl: https://snapshot-manager.example.com\n        proxyUrl: https://proxy.example.com\n        sshGatewayUrl: ssh://ssh-gateway.example.com\n      properties:\n        proxyUrl:\n          description: Proxy URL for the region\n          example: https://proxy.example.com\n          nullable: true\n          type: string\n        sshGatewayUrl:\n          description: SSH Gateway URL for the region\n          example: ssh://ssh-gateway.example.com\n          nullable: true\n          type: string\n        snapshotManagerUrl:\n          description: Snapshot Manager URL for the region\n          example: https://snapshot-manager.example.com\n          nullable: true\n          type: string\n      type: object\n    SnapshotManagerCredentials:\n      example:\n        password: password\n        username: daytona\n      properties:\n        username:\n          description: Snapshot Manager username for the region\n          example: daytona\n          type: string\n        password:\n          description: Snapshot Manager password for the region\n          type: string\n      required:\n      - password\n      - username\n      type: object\n    UserPublicKey:\n      example:\n        name: name\n        key: key\n      properties:\n        key:\n          description: Public key\n          type: string\n        name:\n          description: Key name\n          type: string\n      required:\n      - key\n      - name\n      type: object\n    User:\n      example:\n        createdAt: 2000-01-23T04:56:07.000+00:00\n        publicKeys:\n        - name: name\n          key: key\n        - name: name\n          key: key\n        name: name\n        id: id\n        email: email\n      properties:\n        id:\n          description: User ID\n          type: string\n        name:\n          description: User name\n          type: string\n        email:\n          description: User email\n          type: string\n        publicKeys:\n          description: User public keys\n          items:\n            $ref: '#/components/schemas/UserPublicKey'\n          type: array\n        createdAt:\n          description: Creation timestamp\n          format: date-time\n          type: string\n      required:\n      - createdAt\n      - email\n      - id\n      - name\n      - publicKeys\n      type: object\n    CreateOrganizationQuota:\n      example:\n        snapshotQuota: 7.061401241503109\n        totalCpuQuota: 0.8008281904610115\n        maxCpuPerSandbox: 5.962133916683182\n        maxDiskPerSandbox: 2.3021358869347655\n        maxMemoryPerSandbox: 5.637376656633329\n        volumeQuota: 3.616076749251911\n        totalMemoryQuota: 6.027456183070403\n        maxSnapshotSize: 9.301444243932576\n        totalDiskQuota: 1.4658129805029452\n      properties:\n        totalCpuQuota:\n          type: number\n        totalMemoryQuota:\n          type: number\n        totalDiskQuota:\n          type: number\n        maxCpuPerSandbox:\n          type: number\n        maxMemoryPerSandbox:\n          type: number\n        maxDiskPerSandbox:\n          type: number\n        snapshotQuota:\n          type: number\n        maxSnapshotSize:\n          type: number\n        volumeQuota:\n          type: number\n      type: object\n    CreateUser:\n      example:\n        emailVerified: true\n        role: admin\n        name: name\n        personalOrganizationDefaultRegionId: personalOrganizationDefaultRegionId\n        id: id\n        personalOrganizationQuota:\n          snapshotQuota: 7.061401241503109\n          totalCpuQuota: 0.8008281904610115\n          maxCpuPerSandbox: 5.962133916683182\n          maxDiskPerSandbox: 2.3021358869347655\n          maxMemoryPerSandbox: 5.637376656633329\n          volumeQuota: 3.616076749251911\n          totalMemoryQuota: 6.027456183070403\n          maxSnapshotSize: 9.301444243932576\n          totalDiskQuota: 1.4658129805029452\n        email: email\n      properties:\n        id:\n          type: string\n        name:\n          type: string\n        email:\n          type: string\n        personalOrganizationQuota:\n          $ref: '#/components/schemas/CreateOrganizationQuota'\n        personalOrganizationDefaultRegionId:\n          type: string\n        role:\n          enum:\n          - admin\n          - user\n          type: string\n        emailVerified:\n          type: boolean\n      required:\n      - id\n      - name\n      type: object\n    AccountProvider:\n      example:\n        displayName: displayName\n        name: name\n      properties:\n        name:\n          type: string\n        displayName:\n          type: string\n      required:\n      - displayName\n      - name\n      type: object\n    CreateLinkedAccount:\n      example:\n        provider: provider\n        userId: userId\n      properties:\n        provider:\n          description: The authentication provider of the secondary account\n          type: string\n        userId:\n          description: The user ID of the secondary account\n          type: string\n      required:\n      - provider\n      - userId\n      type: object\n    SandboxState:\n      description: The state of the sandbox\n      enum:\n      - creating\n      - restoring\n      - destroyed\n      - destroying\n      - started\n      - stopped\n      - starting\n      - stopping\n      - error\n      - build_failed\n      - pending_build\n      - building_snapshot\n      - unknown\n      - pulling_snapshot\n      - archived\n      - archiving\n      - resizing\n      type: string\n    SandboxDesiredState:\n      description: The desired state of the sandbox\n      enum:\n      - destroyed\n      - started\n      - stopped\n      - resized\n      - archived\n      type: string\n    SandboxVolume:\n      example:\n        mountPath: /data\n        volumeId: volume123\n        subpath: users/alice\n      properties:\n        volumeId:\n          description: The ID of the volume\n          example: volume123\n          type: string\n        mountPath:\n          description: The mount path for the volume\n          example: /data\n          type: string\n        subpath:\n          description: \"Optional subpath within the volume to mount. When specified,\\\n            \\ only this S3 prefix will be accessible. When omitted, the entire volume\\\n            \\ is mounted.\"\n          example: users/alice\n          type: string\n      required:\n      - mountPath\n      - volumeId\n      type: object\n    BuildInfo:\n      properties:\n        dockerfileContent:\n          description: The Dockerfile content used for the build\n          example: |-\n            FROM node:14\n            WORKDIR /app\n            COPY . .\n            RUN npm install\n            CMD [\"npm\", \"start\"]\n          type: string\n        contextHashes:\n          description: The context hashes used for the build\n          example:\n          - hash1\n          - hash2\n          items:\n            type: string\n          type: array\n        createdAt:\n          description: The creation timestamp\n          format: date-time\n          type: string\n        updatedAt:\n          description: The last update timestamp\n          format: date-time\n          type: string\n        snapshotRef:\n          description: The snapshot reference\n          example: daytonaio/sandbox:latest\n          type: string\n      required:\n      - createdAt\n      - snapshotRef\n      - updatedAt\n      type: object\n    Sandbox:\n      example:\n        memory: 4\n        buildInfo: \"\"\n        toolboxProxyUrl: https://proxy.app.daytona.io/toolbox\n        autoStopInterval: 30\n        organizationId: organization123\n        createdAt: 2024-10-01T12:00:00Z\n        networkBlockAll: false\n        autoDeleteInterval: 30\n        public: false\n        errorReason: The sandbox is not running\n        runnerId: runner123\n        id: sandbox123\n        state: creating\n        class: small\n        updatedAt: 2024-10-01T12:00:00Z\n        desiredState: destroyed\n        networkAllowList: \"192.168.1.0/16,10.0.0.0/24\"\n        volumes:\n        - mountPath: /data\n          volumeId: volume123\n          subpath: users/alice\n        - mountPath: /data\n          volumeId: volume123\n          subpath: users/alice\n        cpu: 2\n        recoverable: true\n        env:\n          NODE_ENV: production\n        gpu: 0\n        daemonVersion: 1.0.0\n        backupCreatedAt: 2024-10-01T12:00:00Z\n        labels:\n          daytona.io/public: \"true\"\n        target: local\n        disk: 10\n        name: MySandbox\n        backupState: None\n        user: daytona\n        autoArchiveInterval: 10080\n        snapshot: daytonaio/sandbox:latest\n      properties:\n        id:\n          description: The ID of the sandbox\n          example: sandbox123\n          type: string\n        organizationId:\n          description: The organization ID of the sandbox\n          example: organization123\n          type: string\n        name:\n          description: The name of the sandbox\n          example: MySandbox\n          type: string\n        snapshot:\n          description: The snapshot used for the sandbox\n          example: daytonaio/sandbox:latest\n          type: string\n        user:\n          description: The user associated with the project\n          example: daytona\n          type: string\n        env:\n          additionalProperties:\n            type: string\n          description: Environment variables for the sandbox\n          example:\n            NODE_ENV: production\n          type: object\n        labels:\n          additionalProperties:\n            type: string\n          description: Labels for the sandbox\n          example:\n            daytona.io/public: \"true\"\n          type: object\n        public:\n          description: Whether the sandbox http preview is public\n          example: false\n          type: boolean\n        networkBlockAll:\n          description: Whether to block all network access for the sandbox\n          example: false\n          type: boolean\n        networkAllowList:\n          description: Comma-separated list of allowed CIDR network addresses for\n            the sandbox\n          example: \"192.168.1.0/16,10.0.0.0/24\"\n          type: string\n        target:\n          description: The target environment for the sandbox\n          example: local\n          type: string\n        cpu:\n          description: The CPU quota for the sandbox\n          example: 2\n          type: number\n        gpu:\n          description: The GPU quota for the sandbox\n          example: 0\n          type: number\n        memory:\n          description: The memory quota for the sandbox\n          example: 4\n          type: number\n        disk:\n          description: The disk quota for the sandbox\n          example: 10\n          type: number\n        state:\n          allOf:\n          - $ref: '#/components/schemas/SandboxState'\n          description: The state of the sandbox\n          example: creating\n        desiredState:\n          allOf:\n          - $ref: '#/components/schemas/SandboxDesiredState'\n          description: The desired state of the sandbox\n          example: destroyed\n        errorReason:\n          description: The error reason of the sandbox\n          example: The sandbox is not running\n          type: string\n        recoverable:\n          description: Whether the sandbox error is recoverable.\n          example: true\n          type: boolean\n        backupState:\n          description: The state of the backup\n          enum:\n          - None\n          - Pending\n          - InProgress\n          - Completed\n          - Error\n          example: None\n          type: string\n        backupCreatedAt:\n          description: The creation timestamp of the last backup\n          example: 2024-10-01T12:00:00Z\n          type: string\n        autoStopInterval:\n          description: Auto-stop interval in minutes (0 means disabled)\n          example: 30\n          type: number\n        autoArchiveInterval:\n          description: Auto-archive interval in minutes\n          example: 10080\n          type: number\n        autoDeleteInterval:\n          description: \"Auto-delete interval in minutes (negative value means disabled,\\\n            \\ 0 means delete immediately upon stopping)\"\n          example: 30\n          type: number\n        volumes:\n          description: Array of volumes attached to the sandbox\n          items:\n            $ref: '#/components/schemas/SandboxVolume'\n          type: array\n        buildInfo:\n          allOf:\n          - $ref: '#/components/schemas/BuildInfo'\n          description: Build information for the sandbox\n        createdAt:\n          description: The creation timestamp of the sandbox\n          example: 2024-10-01T12:00:00Z\n          type: string\n        updatedAt:\n          description: The last update timestamp of the sandbox\n          example: 2024-10-01T12:00:00Z\n          type: string\n        class:\n          deprecated: true\n          description: The class of the sandbox\n          enum:\n          - small\n          - medium\n          - large\n          example: small\n          type: string\n        daemonVersion:\n          description: The version of the daemon running in the sandbox\n          example: 1.0.0\n          type: string\n        runnerId:\n          description: The runner ID of the sandbox\n          example: runner123\n          type: string\n        toolboxProxyUrl:\n          description: The toolbox proxy URL for the sandbox\n          example: https://proxy.app.daytona.io/toolbox\n          type: string\n      required:\n      - cpu\n      - disk\n      - env\n      - gpu\n      - id\n      - labels\n      - memory\n      - name\n      - networkBlockAll\n      - organizationId\n      - public\n      - target\n      - toolboxProxyUrl\n      - user\n      type: object\n    PaginatedSandboxes:\n      example:\n        total: 0.8008281904610115\n        totalPages: 1.4658129805029452\n        page: 6.027456183070403\n        items:\n        - memory: 4\n          buildInfo: \"\"\n          toolboxProxyUrl: https://proxy.app.daytona.io/toolbox\n          autoStopInterval: 30\n          organizationId: organization123\n          createdAt: 2024-10-01T12:00:00Z\n          networkBlockAll: false\n          autoDeleteInterval: 30\n          public: false\n          errorReason: The sandbox is not running\n          runnerId: runner123\n          id: sandbox123\n          state: creating\n          class: small\n          updatedAt: 2024-10-01T12:00:00Z\n          desiredState: destroyed\n          networkAllowList: \"192.168.1.0/16,10.0.0.0/24\"\n          volumes:\n          - mountPath: /data\n            volumeId: volume123\n            subpath: users/alice\n          - mountPath: /data\n            volumeId: volume123\n            subpath: users/alice\n          cpu: 2\n          recoverable: true\n          env:\n            NODE_ENV: production\n          gpu: 0\n          daemonVersion: 1.0.0\n          backupCreatedAt: 2024-10-01T12:00:00Z\n          labels:\n            daytona.io/public: \"true\"\n          target: local\n          disk: 10\n          name: MySandbox\n          backupState: None\n          user: daytona\n          autoArchiveInterval: 10080\n          snapshot: daytonaio/sandbox:latest\n        - memory: 4\n          buildInfo: \"\"\n          toolboxProxyUrl: https://proxy.app.daytona.io/toolbox\n          autoStopInterval: 30\n          organizationId: organization123\n          createdAt: 2024-10-01T12:00:00Z\n          networkBlockAll: false\n          autoDeleteInterval: 30\n          public: false\n          errorReason: The sandbox is not running\n          runnerId: runner123\n          id: sandbox123\n          state: creating\n          class: small\n          updatedAt: 2024-10-01T12:00:00Z\n          desiredState: destroyed\n          networkAllowList: \"192.168.1.0/16,10.0.0.0/24\"\n          volumes:\n          - mountPath: /data\n            volumeId: volume123\n            subpath: users/alice\n          - mountPath: /data\n            volumeId: volume123\n            subpath: users/alice\n          cpu: 2\n          recoverable: true\n          env:\n            NODE_ENV: production\n          gpu: 0\n          daemonVersion: 1.0.0\n          backupCreatedAt: 2024-10-01T12:00:00Z\n          labels:\n            daytona.io/public: \"true\"\n          target: local\n          disk: 10\n          name: MySandbox\n          backupState: None\n          user: daytona\n          autoArchiveInterval: 10080\n          snapshot: daytonaio/sandbox:latest\n      properties:\n        items:\n          items:\n            $ref: '#/components/schemas/Sandbox'\n          type: array\n        total:\n          type: number\n        page:\n          type: number\n        totalPages:\n          type: number\n      required:\n      - items\n      - page\n      - total\n      - totalPages\n      type: object\n    CreateBuildInfo:\n      properties:\n        dockerfileContent:\n          description: The Dockerfile content used for the build\n          example: |-\n            FROM node:14\n            WORKDIR /app\n            COPY . .\n            RUN npm install\n            CMD [\"npm\", \"start\"]\n          type: string\n        contextHashes:\n          description: The context hashes used for the build\n          example:\n          - hash1\n          - hash2\n          items:\n            type: string\n          type: array\n      required:\n      - dockerfileContent\n      type: object\n    CreateSandbox:\n      example:\n        memory: 1\n        buildInfo: \"\"\n        networkAllowList: \"192.168.1.0/16,10.0.0.0/24\"\n        volumes:\n        - mountPath: /data\n          volumeId: volume123\n          subpath: users/alice\n        - mountPath: /data\n          volumeId: volume123\n          subpath: users/alice\n        cpu: 2\n        env:\n          NODE_ENV: production\n        gpu: 1\n        autoStopInterval: 30\n        labels:\n          daytona.io/public: \"true\"\n        target: us\n        networkBlockAll: false\n        disk: 3\n        autoDeleteInterval: 30\n        public: false\n        name: MySandbox\n        user: daytona\n        class: small\n        autoArchiveInterval: 10080\n        snapshot: ubuntu-4vcpu-8ram-100gb\n      properties:\n        name:\n          description: \"The name of the sandbox. If not provided, the sandbox ID will\\\n            \\ be used as the name\"\n          example: MySandbox\n          type: string\n        snapshot:\n          description: The ID or name of the snapshot used for the sandbox\n          example: ubuntu-4vcpu-8ram-100gb\n          type: string\n        user:\n          description: The user associated with the project\n          example: daytona\n          type: string\n        env:\n          additionalProperties:\n            type: string\n          description: Environment variables for the sandbox\n          example:\n            NODE_ENV: production\n          type: object\n        labels:\n          additionalProperties:\n            type: string\n          description: Labels for the sandbox\n          example:\n            daytona.io/public: \"true\"\n          type: object\n        public:\n          description: Whether the sandbox http preview is publicly accessible\n          example: false\n          type: boolean\n        networkBlockAll:\n          description: Whether to block all network access for the sandbox\n          example: false\n          type: boolean\n        networkAllowList:\n          description: Comma-separated list of allowed CIDR network addresses for\n            the sandbox\n          example: \"192.168.1.0/16,10.0.0.0/24\"\n          type: string\n        class:\n          description: The sandbox class type\n          enum:\n          - small\n          - medium\n          - large\n          example: small\n          type: string\n        target:\n          description: The target (region) where the sandbox will be created\n          example: us\n          type: string\n        cpu:\n          description: CPU cores allocated to the sandbox\n          example: 2\n          type: integer\n        gpu:\n          description: GPU units allocated to the sandbox\n          example: 1\n          type: integer\n        memory:\n          description: Memory allocated to the sandbox in GB\n          example: 1\n          type: integer\n        disk:\n          description: Disk space allocated to the sandbox in GB\n          example: 3\n          type: integer\n        autoStopInterval:\n          description: Auto-stop interval in minutes (0 means disabled)\n          example: 30\n          type: integer\n        autoArchiveInterval:\n          description: Auto-archive interval in minutes (0 means the maximum interval\n            will be used)\n          example: 10080\n          type: integer\n        autoDeleteInterval:\n          description: \"Auto-delete interval in minutes (negative value means disabled,\\\n            \\ 0 means delete immediately upon stopping)\"\n          example: 30\n          type: integer\n        volumes:\n          description: Array of volumes to attach to the sandbox\n          items:\n            $ref: '#/components/schemas/SandboxVolume'\n          type: array\n        buildInfo:\n          allOf:\n          - $ref: '#/components/schemas/CreateBuildInfo'\n          description: Build information for the sandbox\n      type: object\n    ResizeSandbox:\n      example:\n        disk: 20\n        memory: 4\n        cpu: 2\n      properties:\n        cpu:\n          description: \"CPU cores to allocate to the sandbox (minimum: 1)\"\n          example: 2\n          minimum: 1\n          type: integer\n        memory:\n          description: \"Memory in GB to allocate to the sandbox (minimum: 1)\"\n          example: 4\n          minimum: 1\n          type: integer\n        disk:\n          description: Disk space in GB to allocate to the sandbox (can only be increased)\n          example: 20\n          minimum: 1\n          type: integer\n      type: object\n    SandboxLabels:\n      example:\n        labels:\n          environment: dev\n          team: backend\n      properties:\n        labels:\n          additionalProperties:\n            type: string\n          description: Key-value pairs of labels\n          example:\n            environment: dev\n            team: backend\n          type: object\n      required:\n      - labels\n      type: object\n    UpdateSandboxStateDto:\n      example:\n        errorReason: Failed to pull snapshot image\n        recoverable: true\n        state: started\n      properties:\n        state:\n          description: The new state for the sandbox\n          enum:\n          - creating\n          - restoring\n          - destroyed\n          - destroying\n          - started\n          - stopped\n          - starting\n          - stopping\n          - error\n          - build_failed\n          - pending_build\n          - building_snapshot\n          - unknown\n          - pulling_snapshot\n          - archived\n          - archiving\n          - resizing\n          example: started\n          type: string\n        errorReason:\n          description: Optional error message when reporting an error state\n          example: Failed to pull snapshot image\n          type: string\n        recoverable:\n          description: Whether the sandbox is recoverable\n          example: true\n          type: boolean\n      required:\n      - state\n      type: object\n    PortPreviewUrl:\n      example:\n        sandboxId: \"123456\"\n        url: \"https://{port}-{sandboxId}.{proxyDomain}\"\n        token: ul67qtv-jl6wb9z5o3eii-ljqt9qed6l\n      properties:\n        sandboxId:\n          description: ID of the sandbox\n          example: \"123456\"\n          type: string\n        url:\n          description: Preview url\n          example: \"https://{port}-{sandboxId}.{proxyDomain}\"\n          type: string\n        token:\n          description: Access token\n          example: ul67qtv-jl6wb9z5o3eii-ljqt9qed6l\n          type: string\n      required:\n      - sandboxId\n      - token\n      - url\n      type: object\n    SignedPortPreviewUrl:\n      example:\n        port: 3000\n        sandboxId: \"123456\"\n        url: \"https://{port}-{token}.{proxyDomain}\"\n        token: jl6wb9z5o3eii\n      properties:\n        sandboxId:\n          description: ID of the sandbox\n          example: \"123456\"\n          type: string\n        port:\n          description: Port number of the signed preview URL\n          example: 3000\n          type: integer\n        token:\n          description: Token of the signed preview URL\n          example: jl6wb9z5o3eii\n          type: string\n        url:\n          description: Signed preview url\n          example: \"https://{port}-{token}.{proxyDomain}\"\n          type: string\n      required:\n      - port\n      - sandboxId\n      - token\n      - url\n      type: object\n    Url:\n      example:\n        url: url\n      properties:\n        url:\n          description: URL response\n          type: string\n      required:\n      - url\n      type: object\n    SshAccessDto:\n      example:\n        createdAt: 2025-01-01T11:00:00Z\n        sshCommand: ssh -p 2222 token@localhost\n        sandboxId: 123e4567-e89b-12d3-a456-426614174000\n        id: 123e4567-e89b-12d3-a456-426614174000\n        expiresAt: 2025-01-01T12:00:00Z\n        token: abc123def456ghi789jkl012mno345pqr678stu901vwx234yz\n        updatedAt: 2025-01-01T11:00:00Z\n      properties:\n        id:\n          description: Unique identifier for the SSH access\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        sandboxId:\n          description: ID of the sandbox this SSH access is for\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        token:\n          description: SSH access token\n          example: abc123def456ghi789jkl012mno345pqr678stu901vwx234yz\n          type: string\n        expiresAt:\n          description: When the SSH access expires\n          example: 2025-01-01T12:00:00Z\n          format: date-time\n          type: string\n        createdAt:\n          description: When the SSH access was created\n          example: 2025-01-01T11:00:00Z\n          format: date-time\n          type: string\n        updatedAt:\n          description: When the SSH access was last updated\n          example: 2025-01-01T11:00:00Z\n          format: date-time\n          type: string\n        sshCommand:\n          description: SSH command to connect to the sandbox\n          example: ssh -p 2222 token@localhost\n          type: string\n      required:\n      - createdAt\n      - expiresAt\n      - id\n      - sandboxId\n      - sshCommand\n      - token\n      - updatedAt\n      type: object\n    SshAccessValidationDto:\n      example:\n        valid: true\n        sandboxId: 123e4567-e89b-12d3-a456-426614174000\n      properties:\n        valid:\n          description: Whether the SSH access token is valid\n          example: true\n          type: boolean\n        sandboxId:\n          description: ID of the sandbox this SSH access is for\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n      required:\n      - sandboxId\n      - valid\n      type: object\n    ToolboxProxyUrl:\n      example:\n        url: https://proxy.app.daytona.io/toolbox\n      properties:\n        url:\n          description: The toolbox proxy URL for the sandbox\n          example: https://proxy.app.daytona.io/toolbox\n          type: string\n      required:\n      - url\n      type: object\n    CreateRunner:\n      example:\n        regionId: regionId\n        name: name\n      properties:\n        regionId:\n          type: string\n        name:\n          type: string\n      required:\n      - name\n      - regionId\n      type: object\n    CreateRunnerResponse:\n      example:\n        apiKey: dtn_1234567890\n        id: runner123\n      properties:\n        id:\n          description: The ID of the runner\n          example: runner123\n          type: string\n        apiKey:\n          description: The API key for the runner\n          example: dtn_1234567890\n          type: string\n      required:\n      - apiKey\n      - id\n      type: object\n    SandboxClass:\n      description: The class of the runner\n      enum:\n      - small\n      - medium\n      - large\n      type: string\n    RunnerState:\n      description: The state of the runner\n      enum:\n      - initializing\n      - ready\n      - disabled\n      - decommissioned\n      - unresponsive\n      type: string\n    RunnerFull:\n      example:\n        currentStartedSandboxes: 5\n        appVersion: v0.0.0-dev\n        memory: 16\n        currentMemoryUsagePercentage: 68.2\n        apiKey: dtn_1234567890\n        availabilityScore: 85\n        currentDiskUsagePercentage: 33.8\n        currentCpuUsagePercentage: 45.6\n        createdAt: 2023-10-01T12:00:00Z\n        apiVersion: \"0\"\n        apiUrl: https://api.runner1.example.com\n        regionType: shared\n        id: runner123\n        state: initializing\n        unschedulable: false\n        class: small\n        currentAllocatedDiskGiB: 50000\n        currentAllocatedMemoryGiB: 8000\n        gpuType: gpuType\n        currentAllocatedCpu: 4000\n        updatedAt: 2023-10-01T12:00:00Z\n        proxyUrl: https://proxy.runner1.example.com\n        cpu: 8\n        gpu: 1\n        currentSnapshotCount: 12\n        version: \"0\"\n        disk: 100\n        domain: runner1.example.com\n        name: runner1\n        region: us\n        lastChecked: 2024-10-01T12:00:00Z\n      properties:\n        id:\n          description: The ID of the runner\n          example: runner123\n          type: string\n        domain:\n          description: The domain of the runner\n          example: runner1.example.com\n          type: string\n        apiUrl:\n          description: The API URL of the runner\n          example: https://api.runner1.example.com\n          type: string\n        proxyUrl:\n          description: The proxy URL of the runner\n          example: https://proxy.runner1.example.com\n          type: string\n        cpu:\n          description: The CPU capacity of the runner\n          example: 8\n          type: number\n        memory:\n          description: The memory capacity of the runner in GiB\n          example: 16\n          type: number\n        disk:\n          description: The disk capacity of the runner in GiB\n          example: 100\n          type: number\n        gpu:\n          description: The GPU capacity of the runner\n          example: 1\n          type: number\n        gpuType:\n          description: The type of GPU\n          type: string\n        class:\n          allOf:\n          - $ref: '#/components/schemas/SandboxClass'\n          description: The class of the runner\n          example: small\n        currentCpuUsagePercentage:\n          description: Current CPU usage percentage\n          example: 45.6\n          type: number\n        currentMemoryUsagePercentage:\n          description: Current RAM usage percentage\n          example: 68.2\n          type: number\n        currentDiskUsagePercentage:\n          description: Current disk usage percentage\n          example: 33.8\n          type: number\n        currentAllocatedCpu:\n          description: Current allocated CPU\n          example: 4000\n          type: number\n        currentAllocatedMemoryGiB:\n          description: Current allocated memory in GiB\n          example: 8000\n          type: number\n        currentAllocatedDiskGiB:\n          description: Current allocated disk in GiB\n          example: 50000\n          type: number\n        currentSnapshotCount:\n          description: Current snapshot count\n          example: 12\n          type: number\n        currentStartedSandboxes:\n          description: Current number of started sandboxes\n          example: 5\n          type: number\n        availabilityScore:\n          description: Runner availability score\n          example: 85\n          type: number\n        region:\n          description: The region of the runner\n          example: us\n          type: string\n        name:\n          description: The name of the runner\n          example: runner1\n          type: string\n        state:\n          allOf:\n          - $ref: '#/components/schemas/RunnerState'\n          description: The state of the runner\n          example: initializing\n        lastChecked:\n          description: The last time the runner was checked\n          example: 2024-10-01T12:00:00Z\n          type: string\n        unschedulable:\n          description: Whether the runner is unschedulable\n          example: false\n          type: boolean\n        createdAt:\n          description: The creation timestamp of the runner\n          example: 2023-10-01T12:00:00Z\n          type: string\n        updatedAt:\n          description: The last update timestamp of the runner\n          example: 2023-10-01T12:00:00Z\n          type: string\n        version:\n          deprecated: true\n          description: The version of the runner (deprecated in favor of apiVersion)\n          example: \"0\"\n          type: string\n        apiVersion:\n          deprecated: true\n          description: The api version of the runner\n          example: \"0\"\n          type: string\n        appVersion:\n          deprecated: true\n          description: The app version of the runner\n          example: v0.0.0-dev\n          type: string\n        apiKey:\n          description: The API key for the runner\n          example: dtn_1234567890\n          type: string\n        regionType:\n          allOf:\n          - $ref: '#/components/schemas/RegionType'\n          description: The region type of the runner\n          example: shared\n      required:\n      - apiKey\n      - apiVersion\n      - class\n      - cpu\n      - createdAt\n      - disk\n      - id\n      - memory\n      - name\n      - region\n      - state\n      - unschedulable\n      - updatedAt\n      - version\n      type: object\n    Runner:\n      example:\n        currentStartedSandboxes: 5\n        appVersion: v0.0.0-dev\n        memory: 16\n        currentMemoryUsagePercentage: 68.2\n        availabilityScore: 85\n        currentDiskUsagePercentage: 33.8\n        currentCpuUsagePercentage: 45.6\n        createdAt: 2023-10-01T12:00:00Z\n        apiVersion: \"0\"\n        apiUrl: https://api.runner1.example.com\n        id: runner123\n        state: initializing\n        unschedulable: false\n        class: small\n        currentAllocatedDiskGiB: 50000\n        currentAllocatedMemoryGiB: 8000\n        gpuType: gpuType\n        currentAllocatedCpu: 4000\n        updatedAt: 2023-10-01T12:00:00Z\n        proxyUrl: https://proxy.runner1.example.com\n        cpu: 8\n        gpu: 1\n        currentSnapshotCount: 12\n        version: \"0\"\n        disk: 100\n        domain: runner1.example.com\n        name: runner1\n        region: us\n        lastChecked: 2024-10-01T12:00:00Z\n      properties:\n        id:\n          description: The ID of the runner\n          example: runner123\n          type: string\n        domain:\n          description: The domain of the runner\n          example: runner1.example.com\n          type: string\n        apiUrl:\n          description: The API URL of the runner\n          example: https://api.runner1.example.com\n          type: string\n        proxyUrl:\n          description: The proxy URL of the runner\n          example: https://proxy.runner1.example.com\n          type: string\n        cpu:\n          description: The CPU capacity of the runner\n          example: 8\n          type: number\n        memory:\n          description: The memory capacity of the runner in GiB\n          example: 16\n          type: number\n        disk:\n          description: The disk capacity of the runner in GiB\n          example: 100\n          type: number\n        gpu:\n          description: The GPU capacity of the runner\n          example: 1\n          type: number\n        gpuType:\n          description: The type of GPU\n          type: string\n        class:\n          allOf:\n          - $ref: '#/components/schemas/SandboxClass'\n          description: The class of the runner\n          example: small\n        currentCpuUsagePercentage:\n          description: Current CPU usage percentage\n          example: 45.6\n          type: number\n        currentMemoryUsagePercentage:\n          description: Current RAM usage percentage\n          example: 68.2\n          type: number\n        currentDiskUsagePercentage:\n          description: Current disk usage percentage\n          example: 33.8\n          type: number\n        currentAllocatedCpu:\n          description: Current allocated CPU\n          example: 4000\n          type: number\n        currentAllocatedMemoryGiB:\n          description: Current allocated memory in GiB\n          example: 8000\n          type: number\n        currentAllocatedDiskGiB:\n          description: Current allocated disk in GiB\n          example: 50000\n          type: number\n        currentSnapshotCount:\n          description: Current snapshot count\n          example: 12\n          type: number\n        currentStartedSandboxes:\n          description: Current number of started sandboxes\n          example: 5\n          type: number\n        availabilityScore:\n          description: Runner availability score\n          example: 85\n          type: number\n        region:\n          description: The region of the runner\n          example: us\n          type: string\n        name:\n          description: The name of the runner\n          example: runner1\n          type: string\n        state:\n          allOf:\n          - $ref: '#/components/schemas/RunnerState'\n          description: The state of the runner\n          example: initializing\n        lastChecked:\n          description: The last time the runner was checked\n          example: 2024-10-01T12:00:00Z\n          type: string\n        unschedulable:\n          description: Whether the runner is unschedulable\n          example: false\n          type: boolean\n        createdAt:\n          description: The creation timestamp of the runner\n          example: 2023-10-01T12:00:00Z\n          type: string\n        updatedAt:\n          description: The last update timestamp of the runner\n          example: 2023-10-01T12:00:00Z\n          type: string\n        version:\n          deprecated: true\n          description: The version of the runner (deprecated in favor of apiVersion)\n          example: \"0\"\n          type: string\n        apiVersion:\n          deprecated: true\n          description: The api version of the runner\n          example: \"0\"\n          type: string\n        appVersion:\n          deprecated: true\n          description: The app version of the runner\n          example: v0.0.0-dev\n          type: string\n      required:\n      - apiVersion\n      - class\n      - cpu\n      - createdAt\n      - disk\n      - id\n      - memory\n      - name\n      - region\n      - state\n      - unschedulable\n      - updatedAt\n      - version\n      type: object\n    RunnerSnapshotDto:\n      example:\n        runnerDomain: runner.example.com\n        runnerId: 123e4567-e89b-12d3-a456-426614174000\n        runnerSnapshotId: 123e4567-e89b-12d3-a456-426614174000\n      properties:\n        runnerSnapshotId:\n          description: Runner snapshot ID\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        runnerId:\n          description: Runner ID\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        runnerDomain:\n          description: Runner domain\n          example: runner.example.com\n          type: string\n      required:\n      - runnerId\n      - runnerSnapshotId\n      type: object\n    RunnerHealthMetrics:\n      properties:\n        currentCpuLoadAverage:\n          description: Current CPU load average\n          example: 0.98\n          type: number\n        currentCpuUsagePercentage:\n          description: Current CPU usage percentage\n          example: 45.5\n          type: number\n        currentMemoryUsagePercentage:\n          description: Current memory usage percentage\n          example: 60.2\n          type: number\n        currentDiskUsagePercentage:\n          description: Current disk usage percentage\n          example: 35.8\n          type: number\n        currentAllocatedCpu:\n          description: Currently allocated CPU cores\n          example: 8\n          type: number\n        currentAllocatedMemoryGiB:\n          description: Currently allocated memory in GiB\n          example: 16\n          type: number\n        currentAllocatedDiskGiB:\n          description: Currently allocated disk in GiB\n          example: 100\n          type: number\n        currentSnapshotCount:\n          description: Number of snapshots currently stored\n          example: 5\n          type: number\n        currentStartedSandboxes:\n          description: Number of started sandboxes\n          example: 10\n          type: number\n        cpu:\n          description: Total CPU cores on the runner\n          example: 8\n          type: number\n        memoryGiB:\n          description: Total RAM in GiB on the runner\n          example: 16\n          type: number\n        diskGiB:\n          description: Total disk space in GiB on the runner\n          example: 100\n          type: number\n      required:\n      - cpu\n      - currentAllocatedCpu\n      - currentAllocatedDiskGiB\n      - currentAllocatedMemoryGiB\n      - currentCpuLoadAverage\n      - currentCpuUsagePercentage\n      - currentDiskUsagePercentage\n      - currentMemoryUsagePercentage\n      - currentSnapshotCount\n      - currentStartedSandboxes\n      - diskGiB\n      - memoryGiB\n      type: object\n    RunnerServiceHealth:\n      example:\n        healthy: false\n        errorReason: Cannot connect to the runner\n        serviceName: runner\n      properties:\n        serviceName:\n          description: Name of the service being checked\n          example: runner\n          type: string\n        healthy:\n          description: Whether the service is healthy\n          example: false\n          type: boolean\n        errorReason:\n          description: Error reason if the service is unhealthy\n          example: Cannot connect to the runner\n          type: string\n      required:\n      - healthy\n      - serviceName\n      type: object\n    RunnerHealthcheck:\n      example:\n        appVersion: v0.0.0-dev\n        apiUrl: http://api.daytona.example.com:8080\n        proxyUrl: http://proxy.daytona.example.com:8080\n        domain: runner-123.daytona.example.com\n        serviceHealth:\n        - healthy: false\n          errorReason: Cannot connect to the runner\n          serviceName: runner\n        - healthy: false\n          errorReason: Cannot connect to the runner\n          serviceName: runner\n        metrics: \"\"\n      properties:\n        metrics:\n          allOf:\n          - $ref: '#/components/schemas/RunnerHealthMetrics'\n          description: Runner metrics\n        serviceHealth:\n          description: Health status of individual services on the runner\n          items:\n            $ref: '#/components/schemas/RunnerServiceHealth'\n          type: array\n        domain:\n          description: Runner domain\n          example: runner-123.daytona.example.com\n          type: string\n        proxyUrl:\n          description: Runner proxy URL\n          example: http://proxy.daytona.example.com:8080\n          type: string\n        apiUrl:\n          description: Runner API URL\n          example: http://api.daytona.example.com:8080\n          type: string\n        appVersion:\n          description: Runner app version\n          example: v0.0.0-dev\n          type: string\n      required:\n      - appVersion\n      type: object\n    ProjectDirResponse:\n      example:\n        dir: dir\n      properties:\n        dir:\n          type: string\n      type: object\n    UserHomeDirResponse:\n      example:\n        dir: dir\n      properties:\n        dir:\n          type: string\n      type: object\n    WorkDirResponse:\n      example:\n        dir: dir\n      properties:\n        dir:\n          type: string\n      type: object\n    FileInfo:\n      example:\n        mode: mode\n        owner: owner\n        size: 0.8008281904610115\n        modTime: modTime\n        permissions: permissions\n        name: name\n        isDir: true\n        group: group\n      properties:\n        name:\n          type: string\n        isDir:\n          type: boolean\n        size:\n          type: number\n        modTime:\n          type: string\n        mode:\n          type: string\n        permissions:\n          type: string\n        owner:\n          type: string\n        group:\n          type: string\n      required:\n      - group\n      - isDir\n      - modTime\n      - mode\n      - name\n      - owner\n      - permissions\n      - size\n      type: object\n    DownloadFiles:\n      example:\n        paths:\n        - paths\n        - paths\n      properties:\n        paths:\n          description: List of remote file paths to download\n          items:\n            type: string\n          type: array\n      required:\n      - paths\n      type: object\n    Match:\n      example:\n        file: file\n        line: 0.8008281904610115\n        content: content\n      properties:\n        file:\n          type: string\n        line:\n          type: number\n        content:\n          type: string\n      required:\n      - content\n      - file\n      - line\n      type: object\n    ReplaceRequest:\n      example:\n        newValue: newValue\n        pattern: pattern\n        files:\n        - files\n        - files\n      properties:\n        files:\n          items:\n            type: string\n          type: array\n        pattern:\n          type: string\n        newValue:\n          type: string\n      required:\n      - files\n      - newValue\n      - pattern\n      type: object\n    ReplaceResult:\n      example:\n        file: file\n        success: true\n        error: error\n      properties:\n        file:\n          type: string\n        success:\n          type: boolean\n        error:\n          type: string\n      type: object\n    SearchFilesResponse:\n      example:\n        files:\n        - files\n        - files\n      properties:\n        files:\n          items:\n            type: string\n          type: array\n      required:\n      - files\n      type: object\n    UploadFile:\n      properties:\n        file:\n          format: binary\n          type: string\n        path:\n          type: string\n      required:\n      - file\n      - path\n      type: object\n    GitAddRequest:\n      example:\n        path: path\n        files:\n        - files\n        - files\n      properties:\n        path:\n          type: string\n        files:\n          description: files to add (use . for all files)\n          items:\n            type: string\n          type: array\n      required:\n      - files\n      - path\n      type: object\n    ListBranchResponse:\n      example:\n        branches:\n        - branches\n        - branches\n      properties:\n        branches:\n          items:\n            type: string\n          type: array\n      required:\n      - branches\n      type: object\n    GitBranchRequest:\n      example:\n        path: path\n        name: name\n      properties:\n        path:\n          type: string\n        name:\n          type: string\n      required:\n      - name\n      - path\n      type: object\n    GitDeleteBranchRequest:\n      example:\n        path: path\n        name: name\n      properties:\n        path:\n          type: string\n        name:\n          type: string\n      required:\n      - name\n      - path\n      type: object\n    GitCloneRequest:\n      example:\n        path: path\n        password: password\n        branch: branch\n        commit_id: commit_id\n        url: url\n        username: username\n      properties:\n        url:\n          type: string\n        path:\n          type: string\n        username:\n          type: string\n        password:\n          type: string\n        branch:\n          type: string\n        commit_id:\n          type: string\n      required:\n      - path\n      - url\n      type: object\n    GitCommitRequest:\n      example:\n        path: path\n        author: author\n        message: message\n        email: email\n        allow_empty: false\n      properties:\n        path:\n          type: string\n        message:\n          type: string\n        author:\n          type: string\n        email:\n          type: string\n        allow_empty:\n          default: false\n          description: Allow creating an empty commit when no changes are staged\n          type: boolean\n      required:\n      - author\n      - email\n      - message\n      - path\n      type: object\n    GitCommitResponse:\n      example:\n        hash: hash\n      properties:\n        hash:\n          type: string\n      required:\n      - hash\n      type: object\n    GitCommitInfo:\n      example:\n        author: author\n        message: message\n        hash: hash\n        email: email\n        timestamp: timestamp\n      properties:\n        hash:\n          type: string\n        message:\n          type: string\n        author:\n          type: string\n        email:\n          type: string\n        timestamp:\n          type: string\n      required:\n      - author\n      - email\n      - hash\n      - message\n      - timestamp\n      type: object\n    GitRepoRequest:\n      example:\n        path: path\n        password: password\n        username: username\n      properties:\n        path:\n          type: string\n        username:\n          type: string\n        password:\n          type: string\n      required:\n      - path\n      type: object\n    GitCheckoutRequest:\n      example:\n        path: path\n        branch: branch\n      properties:\n        path:\n          type: string\n        branch:\n          type: string\n      required:\n      - branch\n      - path\n      type: object\n    FileStatus:\n      example:\n        extra: extra\n        name: name\n        staging: staging\n        worktree: worktree\n      properties:\n        name:\n          type: string\n        staging:\n          type: string\n        worktree:\n          type: string\n        extra:\n          type: string\n      required:\n      - extra\n      - name\n      - staging\n      - worktree\n      type: object\n    GitStatus:\n      example:\n        behind: 6.027456183070403\n        fileStatus:\n        - extra: extra\n          name: name\n          staging: staging\n          worktree: worktree\n        - extra: extra\n          name: name\n          staging: staging\n          worktree: worktree\n        ahead: 0.8008281904610115\n        branchPublished: true\n        currentBranch: currentBranch\n      properties:\n        currentBranch:\n          type: string\n        fileStatus:\n          items:\n            $ref: '#/components/schemas/FileStatus'\n          type: array\n        ahead:\n          type: number\n        behind:\n          type: number\n        branchPublished:\n          type: boolean\n      required:\n      - currentBranch\n      - fileStatus\n      type: object\n    ExecuteRequest:\n      example:\n        cwd: cwd\n        command: command\n        timeout: 0.8008281904610115\n      properties:\n        command:\n          type: string\n        cwd:\n          description: Current working directory\n          type: string\n        timeout:\n          description: \"Timeout in seconds, defaults to 10 seconds\"\n          type: number\n      required:\n      - command\n      type: object\n    ExecuteResponse:\n      example:\n        result: Command output here\n        exitCode: 0\n      properties:\n        exitCode:\n          description: Exit code\n          example: 0\n          type: number\n        result:\n          description: Command output\n          example: Command output here\n          type: string\n      required:\n      - exitCode\n      - result\n      type: object\n    Command:\n      example:\n        exitCode: 0\n        id: cmd-123\n        command: ls -la\n      properties:\n        id:\n          description: The ID of the command\n          example: cmd-123\n          type: string\n        command:\n          description: The command that was executed\n          example: ls -la\n          type: string\n        exitCode:\n          description: The exit code of the command\n          example: 0\n          type: number\n      required:\n      - command\n      - id\n      type: object\n    Session:\n      example:\n        sessionId: session-123\n        commands:\n        - exitCode: 0\n          id: cmd-123\n          command: ls -la\n        - exitCode: 0\n          id: cmd-123\n          command: ls -la\n      properties:\n        sessionId:\n          description: The ID of the session\n          example: session-123\n          type: string\n        commands:\n          description: The list of commands executed in this session\n          items:\n            $ref: '#/components/schemas/Command'\n          nullable: true\n          type: array\n      required:\n      - commands\n      - sessionId\n      type: object\n    CreateSessionRequest:\n      example:\n        sessionId: session-123\n      properties:\n        sessionId:\n          description: The ID of the session\n          example: session-123\n          type: string\n      required:\n      - sessionId\n      type: object\n    SessionExecuteRequest:\n      example:\n        async: false\n        command: ls -la\n        runAsync: false\n      properties:\n        command:\n          description: The command to execute\n          example: ls -la\n          type: string\n        runAsync:\n          description: Whether to execute the command asynchronously\n          example: false\n          type: boolean\n        async:\n          deprecated: true\n          description: \"Deprecated: Use runAsync instead. Whether to execute the command\\\n            \\ asynchronously\"\n          example: false\n          type: boolean\n      required:\n      - command\n      type: object\n    SessionExecuteResponse:\n      example:\n        output: |-\n          total 20\n          drwxr-xr-x  4 user group  128 Mar 15 10:30 .\n        cmdId: cmd-123\n        exitCode: 0\n      properties:\n        cmdId:\n          description: The ID of the executed command\n          example: cmd-123\n          type: string\n        output:\n          description: The output of the executed command marked with stdout and stderr\n            prefixes\n          example: |-\n            total 20\n            drwxr-xr-x  4 user group  128 Mar 15 10:30 .\n          type: string\n        exitCode:\n          description: The exit code of the executed command\n          example: 0\n          type: number\n      type: object\n    PtySessionInfo:\n      example:\n        cwd: /home/user\n        createdAt: 2024-01-15T10:30:45Z\n        lazyStart: false\n        envs:\n          TERM: xterm-256color\n          PS1: '\\u@daytona:\\w$ '\n        active: true\n        id: pty-session-12345\n        rows: 24\n        cols: 80\n      properties:\n        id:\n          description: The unique identifier for the PTY session\n          example: pty-session-12345\n          type: string\n        cwd:\n          description: \"Starting directory for the PTY session, defaults to the sandbox's\\\n            \\ working directory\"\n          example: /home/user\n          type: string\n        envs:\n          description: Environment variables for the PTY session\n          example:\n            TERM: xterm-256color\n            PS1: '\\u@daytona:\\w$ '\n          type: object\n        cols:\n          description: Number of terminal columns\n          example: 80\n          type: number\n        rows:\n          description: Number of terminal rows\n          example: 24\n          type: number\n        createdAt:\n          description: When the PTY session was created\n          example: 2024-01-15T10:30:45Z\n          type: string\n        active:\n          description: Whether the PTY session is currently active\n          example: true\n          type: boolean\n        lazyStart:\n          default: false\n          description: Whether the PTY session uses lazy start (only start when first\n            client connects)\n          example: false\n          type: boolean\n      required:\n      - active\n      - cols\n      - createdAt\n      - cwd\n      - envs\n      - id\n      - lazyStart\n      - rows\n      type: object\n    PtyListResponse:\n      example:\n        sessions:\n        - cwd: /home/user\n          createdAt: 2024-01-15T10:30:45Z\n          lazyStart: false\n          envs:\n            TERM: xterm-256color\n            PS1: '\\u@daytona:\\w$ '\n          active: true\n          id: pty-session-12345\n          rows: 24\n          cols: 80\n        - cwd: /home/user\n          createdAt: 2024-01-15T10:30:45Z\n          lazyStart: false\n          envs:\n            TERM: xterm-256color\n            PS1: '\\u@daytona:\\w$ '\n          active: true\n          id: pty-session-12345\n          rows: 24\n          cols: 80\n      properties:\n        sessions:\n          description: List of active PTY sessions\n          items:\n            $ref: '#/components/schemas/PtySessionInfo'\n          type: array\n      required:\n      - sessions\n      type: object\n    PtyCreateRequest:\n      example:\n        cwd: /home/user\n        lazyStart: false\n        envs:\n          TERM: xterm-256color\n          PS1: '\\u@daytona:\\w$ '\n        id: pty-session-12345\n        rows: 24\n        cols: 80\n      properties:\n        id:\n          description: The unique identifier for the PTY session\n          example: pty-session-12345\n          type: string\n        cwd:\n          description: \"Starting directory for the PTY session, defaults to the sandbox's\\\n            \\ working directory\"\n          example: /home/user\n          type: string\n        envs:\n          description: Environment variables for the PTY session\n          example:\n            TERM: xterm-256color\n            PS1: '\\u@daytona:\\w$ '\n          type: object\n        cols:\n          description: Number of terminal columns\n          example: 80\n          type: number\n        rows:\n          description: Number of terminal rows\n          example: 24\n          type: number\n        lazyStart:\n          default: false\n          description: Whether to start the PTY session lazily (only start when first\n            client connects)\n          example: false\n          type: boolean\n      required:\n      - id\n      type: object\n    PtyCreateResponse:\n      example:\n        sessionId: pty-session-12345\n      properties:\n        sessionId:\n          description: The unique identifier for the created PTY session\n          example: pty-session-12345\n          type: string\n      required:\n      - sessionId\n      type: object\n    PtyResizeRequest:\n      example:\n        rows: 24\n        cols: 80\n      properties:\n        cols:\n          description: Number of terminal columns\n          example: 80\n          type: number\n        rows:\n          description: Number of terminal rows\n          example: 24\n          type: number\n      required:\n      - cols\n      - rows\n      type: object\n    Position:\n      example:\n        character: 6.027456183070403\n        line: 0.8008281904610115\n      properties:\n        line:\n          type: number\n        character:\n          type: number\n      required:\n      - character\n      - line\n      type: object\n    CompletionContext:\n      example:\n        triggerCharacter: triggerCharacter\n        triggerKind: 1.4658129805029452\n      properties:\n        triggerKind:\n          type: number\n        triggerCharacter:\n          type: string\n      required:\n      - triggerKind\n      type: object\n    LspCompletionParams:\n      example:\n        pathToProject: pathToProject\n        languageId: languageId\n        context:\n          triggerCharacter: triggerCharacter\n          triggerKind: 1.4658129805029452\n        position:\n          character: 6.027456183070403\n          line: 0.8008281904610115\n        uri: uri\n      properties:\n        languageId:\n          description: Language identifier\n          type: string\n        pathToProject:\n          description: Path to the project\n          type: string\n        uri:\n          description: Document URI\n          type: string\n        position:\n          $ref: '#/components/schemas/Position'\n        context:\n          $ref: '#/components/schemas/CompletionContext'\n      required:\n      - languageId\n      - pathToProject\n      - position\n      - uri\n      type: object\n    CompletionItem:\n      example:\n        insertText: insertText\n        kind: 0.8008281904610115\n        sortText: sortText\n        documentation: \"{}\"\n        label: label\n        detail: detail\n        filterText: filterText\n      properties:\n        label:\n          type: string\n        kind:\n          type: number\n        detail:\n          type: string\n        documentation:\n          type: object\n        sortText:\n          type: string\n        filterText:\n          type: string\n        insertText:\n          type: string\n      required:\n      - label\n      type: object\n    CompletionList:\n      example:\n        items:\n        - insertText: insertText\n          kind: 0.8008281904610115\n          sortText: sortText\n          documentation: \"{}\"\n          label: label\n          detail: detail\n          filterText: filterText\n        - insertText: insertText\n          kind: 0.8008281904610115\n          sortText: sortText\n          documentation: \"{}\"\n          label: label\n          detail: detail\n          filterText: filterText\n        isIncomplete: true\n      properties:\n        isIncomplete:\n          type: boolean\n        items:\n          items:\n            $ref: '#/components/schemas/CompletionItem'\n          type: array\n      required:\n      - isIncomplete\n      - items\n      type: object\n    LspDocumentRequest:\n      example:\n        pathToProject: pathToProject\n        languageId: languageId\n        uri: uri\n      properties:\n        languageId:\n          description: Language identifier\n          type: string\n        pathToProject:\n          description: Path to the project\n          type: string\n        uri:\n          description: Document URI\n          type: string\n      required:\n      - languageId\n      - pathToProject\n      - uri\n      type: object\n    Range:\n      example:\n        start:\n          character: 6.027456183070403\n          line: 0.8008281904610115\n        end:\n          character: 6.027456183070403\n          line: 0.8008281904610115\n      properties:\n        start:\n          $ref: '#/components/schemas/Position'\n        end:\n          $ref: '#/components/schemas/Position'\n      required:\n      - end\n      - start\n      type: object\n    LspLocation:\n      example:\n        range:\n          start:\n            character: 6.027456183070403\n            line: 0.8008281904610115\n          end:\n            character: 6.027456183070403\n            line: 0.8008281904610115\n        uri: uri\n      properties:\n        range:\n          $ref: '#/components/schemas/Range'\n        uri:\n          type: string\n      required:\n      - range\n      - uri\n      type: object\n    LspSymbol:\n      example:\n        kind: 0.8008281904610115\n        name: name\n        location:\n          range:\n            start:\n              character: 6.027456183070403\n              line: 0.8008281904610115\n            end:\n              character: 6.027456183070403\n              line: 0.8008281904610115\n          uri: uri\n      properties:\n        kind:\n          type: number\n        location:\n          $ref: '#/components/schemas/LspLocation'\n        name:\n          type: string\n      required:\n      - kind\n      - location\n      - name\n      type: object\n    LspServerRequest:\n      example:\n        pathToProject: pathToProject\n        languageId: languageId\n      properties:\n        languageId:\n          description: Language identifier\n          type: string\n        pathToProject:\n          description: Path to the project\n          type: string\n      required:\n      - languageId\n      - pathToProject\n      type: object\n    ComputerUseStartResponse:\n      example:\n        message: Computer use processes started successfully\n        status:\n          xvfb:\n            running: true\n            priority: 100\n            autoRestart: true\n            pid: 12345\n          xfce4:\n            running: true\n            priority: 200\n            autoRestart: true\n            pid: 12346\n          x11vnc:\n            running: true\n            priority: 300\n            autoRestart: true\n            pid: 12347\n          novnc:\n            running: true\n            priority: 400\n            autoRestart: true\n            pid: 12348\n      properties:\n        message:\n          description: A message indicating the result of starting computer use processes\n          example: Computer use processes started successfully\n          type: string\n        status:\n          description: Status information about all VNC desktop processes after starting\n          example:\n            xvfb:\n              running: true\n              priority: 100\n              autoRestart: true\n              pid: 12345\n            xfce4:\n              running: true\n              priority: 200\n              autoRestart: true\n              pid: 12346\n            x11vnc:\n              running: true\n              priority: 300\n              autoRestart: true\n              pid: 12347\n            novnc:\n              running: true\n              priority: 400\n              autoRestart: true\n              pid: 12348\n          type: object\n      required:\n      - message\n      - status\n      type: object\n    ComputerUseStopResponse:\n      example:\n        message: Computer use processes stopped successfully\n        status:\n          xvfb:\n            running: false\n            priority: 100\n            autoRestart: true\n          xfce4:\n            running: false\n            priority: 200\n            autoRestart: true\n          x11vnc:\n            running: false\n            priority: 300\n            autoRestart: true\n          novnc:\n            running: false\n            priority: 400\n            autoRestart: true\n      properties:\n        message:\n          description: A message indicating the result of stopping computer use processes\n          example: Computer use processes stopped successfully\n          type: string\n        status:\n          description: Status information about all VNC desktop processes after stopping\n          example:\n            xvfb:\n              running: false\n              priority: 100\n              autoRestart: true\n            xfce4:\n              running: false\n              priority: 200\n              autoRestart: true\n            x11vnc:\n              running: false\n              priority: 300\n              autoRestart: true\n            novnc:\n              running: false\n              priority: 400\n              autoRestart: true\n          type: object\n      required:\n      - message\n      - status\n      type: object\n    ComputerUseStatusResponse:\n      example:\n        status: active\n      properties:\n        status:\n          description: \"Status of computer use services (active, partial, inactive,\\\n            \\ error)\"\n          enum:\n          - active\n          - partial\n          - inactive\n          - error\n          example: active\n          type: string\n      required:\n      - status\n      type: object\n    ProcessStatusResponse:\n      example:\n        running: true\n        processName: xfce4\n      properties:\n        processName:\n          description: The name of the VNC process being checked\n          example: xfce4\n          type: string\n        running:\n          description: Whether the specified VNC process is currently running\n          example: true\n          type: boolean\n      required:\n      - processName\n      - running\n      type: object\n    ProcessRestartResponse:\n      example:\n        processName: xfce4\n        message: Process xfce4 restarted successfully\n      properties:\n        message:\n          description: A message indicating the result of restarting the process\n          example: Process xfce4 restarted successfully\n          type: string\n        processName:\n          description: The name of the VNC process that was restarted\n          example: xfce4\n          type: string\n      required:\n      - message\n      - processName\n      type: object\n    ProcessLogsResponse:\n      example:\n        processName: novnc\n        logs: \"2024-01-15 10:30:45 [INFO] NoVNC server started on port 6080\"\n      properties:\n        processName:\n          description: The name of the VNC process whose logs were retrieved\n          example: novnc\n          type: string\n        logs:\n          description: The log output from the specified VNC process\n          example: \"2024-01-15 10:30:45 [INFO] NoVNC server started on port 6080\"\n          type: string\n      required:\n      - logs\n      - processName\n      type: object\n    ProcessErrorsResponse:\n      example:\n        processName: x11vnc\n        errors: \"2024-01-15 10:30:45 [ERROR] Failed to bind to port 5901\"\n      properties:\n        processName:\n          description: The name of the VNC process whose error logs were retrieved\n          example: x11vnc\n          type: string\n        errors:\n          description: The error log output from the specified VNC process\n          example: \"2024-01-15 10:30:45 [ERROR] Failed to bind to port 5901\"\n          type: string\n      required:\n      - errors\n      - processName\n      type: object\n    MousePosition:\n      example:\n        x: 100\n        \"y\": 200\n      properties:\n        x:\n          description: The X coordinate of the mouse cursor position\n          example: 100\n          type: number\n        \"y\":\n          description: The Y coordinate of the mouse cursor position\n          example: 200\n          type: number\n      required:\n      - x\n      - \"y\"\n      type: object\n    MouseMoveRequest:\n      example:\n        x: 150\n        \"y\": 250\n      properties:\n        x:\n          description: The target X coordinate to move the mouse cursor to\n          example: 150\n          type: number\n        \"y\":\n          description: The target Y coordinate to move the mouse cursor to\n          example: 250\n          type: number\n      required:\n      - x\n      - \"y\"\n      type: object\n    MouseMoveResponse:\n      example:\n        x: 150\n        \"y\": 250\n      properties:\n        x:\n          description: The actual X coordinate where the mouse cursor ended up\n          example: 150\n          type: number\n        \"y\":\n          description: The actual Y coordinate where the mouse cursor ended up\n          example: 250\n          type: number\n      required:\n      - x\n      - \"y\"\n      type: object\n    MouseClickRequest:\n      example:\n        button: left\n        double: false\n        x: 100\n        \"y\": 200\n      properties:\n        x:\n          description: The X coordinate where to perform the mouse click\n          example: 100\n          type: number\n        \"y\":\n          description: The Y coordinate where to perform the mouse click\n          example: 200\n          type: number\n        button:\n          description: \"The mouse button to click (left, right, middle). Defaults\\\n            \\ to left\"\n          example: left\n          type: string\n        double:\n          description: Whether to perform a double-click instead of a single click\n          example: false\n          type: boolean\n      required:\n      - x\n      - \"y\"\n      type: object\n    MouseClickResponse:\n      example:\n        x: 100\n        \"y\": 200\n      properties:\n        x:\n          description: The actual X coordinate where the click occurred\n          example: 100\n          type: number\n        \"y\":\n          description: The actual Y coordinate where the click occurred\n          example: 200\n          type: number\n      required:\n      - x\n      - \"y\"\n      type: object\n    MouseDragRequest:\n      example:\n        button: left\n        endY: 400\n        endX: 300\n        startY: 200\n        startX: 100\n      properties:\n        startX:\n          description: The starting X coordinate for the drag operation\n          example: 100\n          type: number\n        startY:\n          description: The starting Y coordinate for the drag operation\n          example: 200\n          type: number\n        endX:\n          description: The ending X coordinate for the drag operation\n          example: 300\n          type: number\n        endY:\n          description: The ending Y coordinate for the drag operation\n          example: 400\n          type: number\n        button:\n          description: \"The mouse button to use for dragging (left, right, middle).\\\n            \\ Defaults to left\"\n          example: left\n          type: string\n      required:\n      - endX\n      - endY\n      - startX\n      - startY\n      type: object\n    MouseDragResponse:\n      example:\n        x: 300\n        \"y\": 400\n      properties:\n        x:\n          description: The actual X coordinate where the drag ended\n          example: 300\n          type: number\n        \"y\":\n          description: The actual Y coordinate where the drag ended\n          example: 400\n          type: number\n      required:\n      - x\n      - \"y\"\n      type: object\n    MouseScrollRequest:\n      example:\n        amount: 3\n        x: 100\n        \"y\": 200\n        direction: down\n      properties:\n        x:\n          description: The X coordinate where to perform the scroll operation\n          example: 100\n          type: number\n        \"y\":\n          description: The Y coordinate where to perform the scroll operation\n          example: 200\n          type: number\n        direction:\n          description: \"The scroll direction (up, down)\"\n          example: down\n          type: string\n        amount:\n          description: The number of scroll units to scroll. Defaults to 1\n          example: 3\n          type: number\n      required:\n      - direction\n      - x\n      - \"y\"\n      type: object\n    MouseScrollResponse:\n      example:\n        success: true\n      properties:\n        success:\n          description: Whether the mouse scroll operation was successful\n          example: true\n          type: boolean\n      required:\n      - success\n      type: object\n    KeyboardTypeRequest:\n      example:\n        delay: 100\n        text: \"Hello, World!\"\n      properties:\n        text:\n          description: The text to type using the keyboard\n          example: \"Hello, World!\"\n          type: string\n        delay:\n          description: Delay in milliseconds between keystrokes. Defaults to 0\n          example: 100\n          type: number\n      required:\n      - text\n      type: object\n    KeyboardPressRequest:\n      example:\n        modifiers:\n        - ctrl\n        - shift\n        key: enter\n      properties:\n        key:\n          description: \"The key to press (e.g., a, b, c, enter, space, etc.)\"\n          example: enter\n          type: string\n        modifiers:\n          description: \"Array of modifier keys to press along with the main key (ctrl,\\\n            \\ alt, shift, cmd)\"\n          example:\n          - ctrl\n          - shift\n          items:\n            type: string\n          type: array\n      required:\n      - key\n      type: object\n    KeyboardHotkeyRequest:\n      example:\n        keys: ctrl+c\n      properties:\n        keys:\n          description: \"The hotkey combination to press (e.g., \\\"ctrl+c\\\", \\\"cmd+v\\\"\\\n            , \\\"alt+tab\\\")\"\n          example: ctrl+c\n          type: string\n      required:\n      - keys\n      type: object\n    ScreenshotResponse:\n      example:\n        cursorPosition:\n          x: 500\n          \"y\": 300\n        screenshot: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\n        sizeBytes: 24576\n      properties:\n        screenshot:\n          description: Base64 encoded screenshot image data\n          example: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\n          type: string\n        cursorPosition:\n          description: The current cursor position when the screenshot was taken\n          example:\n            x: 500\n            \"y\": 300\n          type: object\n        sizeBytes:\n          description: The size of the screenshot data in bytes\n          example: 24576\n          type: number\n      required:\n      - screenshot\n      type: object\n    RegionScreenshotResponse:\n      example:\n        cursorPosition:\n          x: 500\n          \"y\": 300\n        screenshot: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\n        sizeBytes: 24576\n      properties:\n        screenshot:\n          description: Base64 encoded screenshot image data of the specified region\n          example: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\n          type: string\n        cursorPosition:\n          description: The current cursor position when the region screenshot was\n            taken\n          example:\n            x: 500\n            \"y\": 300\n          type: object\n        sizeBytes:\n          description: The size of the screenshot data in bytes\n          example: 24576\n          type: number\n      required:\n      - screenshot\n      type: object\n    CompressedScreenshotResponse:\n      example:\n        cursorPosition:\n          x: 250\n          \"y\": 150\n        screenshot: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\n        sizeBytes: 12288\n      properties:\n        screenshot:\n          description: Base64 encoded compressed screenshot image data\n          example: iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\n          type: string\n        cursorPosition:\n          description: The current cursor position when the compressed screenshot\n            was taken\n          example:\n            x: 250\n            \"y\": 150\n          type: object\n        sizeBytes:\n          description: The size of the compressed screenshot data in bytes\n          example: 12288\n          type: number\n      required:\n      - screenshot\n      type: object\n    DisplayInfoResponse:\n      example:\n        displays:\n        - id: 0\n          x: 0\n          \"y\": 0\n          width: 1920\n          height: 1080\n          is_active: true\n      properties:\n        displays:\n          description: Array of display information for all connected displays\n          example:\n          - id: 0\n            x: 0\n            \"y\": 0\n            width: 1920\n            height: 1080\n            is_active: true\n          items:\n            type: object\n          type: array\n      required:\n      - displays\n      type: object\n    WindowsResponse:\n      example:\n        count: 5\n        windows:\n        - id: 12345\n          title: Terminal\n      properties:\n        windows:\n          description: Array of window information for all visible windows\n          example:\n          - id: 12345\n            title: Terminal\n          items:\n            type: object\n          type: array\n        count:\n          description: The total number of windows found\n          example: 5\n          type: number\n      required:\n      - count\n      - windows\n      type: object\n    CreateSnapshot:\n      example:\n        general: true\n        disk: 3\n        imageName: ubuntu:22.04\n        memory: 1\n        buildInfo: \"\"\n        regionId: regionId\n        entrypoint: sleep infinity\n        name: ubuntu-4vcpu-8ram-100gb\n        cpu: 1\n        gpu: 0\n      properties:\n        name:\n          description: The name of the snapshot\n          example: ubuntu-4vcpu-8ram-100gb\n          type: string\n        imageName:\n          description: The image name of the snapshot\n          example: ubuntu:22.04\n          type: string\n        entrypoint:\n          description: The entrypoint command for the snapshot\n          example: sleep infinity\n          items:\n            type: string\n          type: array\n        general:\n          description: Whether the snapshot is general\n          type: boolean\n        cpu:\n          description: CPU cores allocated to the resulting sandbox\n          example: 1\n          type: integer\n        gpu:\n          description: GPU units allocated to the resulting sandbox\n          example: 0\n          type: integer\n        memory:\n          description: Memory allocated to the resulting sandbox in GB\n          example: 1\n          type: integer\n        disk:\n          description: Disk space allocated to the sandbox in GB\n          example: 3\n          type: integer\n        buildInfo:\n          allOf:\n          - $ref: '#/components/schemas/CreateBuildInfo'\n          description: Build information for the snapshot\n        regionId:\n          description: ID of the region where the snapshot will be available. Defaults\n            to organization default region if not specified.\n          type: string\n      required:\n      - name\n      type: object\n    SnapshotState:\n      enum:\n      - building\n      - pending\n      - pulling\n      - active\n      - inactive\n      - error\n      - build_failed\n      - removing\n      type: string\n    SnapshotDto:\n      example:\n        imageName: imageName\n        buildInfo: \"\"\n        cpu: 6.027456183070403\n        regionIds:\n        - regionIds\n        - regionIds\n        gpu: 1.4658129805029452\n        organizationId: organizationId\n        general: true\n        createdAt: 2000-01-23T04:56:07.000+00:00\n        disk: 5.637376656633329\n        ref: daytonaio/sandbox:latest\n        size: 0.8008281904610115\n        mem: 5.962133916683182\n        lastUsedAt: 2000-01-23T04:56:07.000+00:00\n        entrypoint:\n        - entrypoint\n        - entrypoint\n        errorReason: errorReason\n        name: name\n        id: id\n        state: \"\"\n        initialRunnerId: runner123\n        updatedAt: 2000-01-23T04:56:07.000+00:00\n      properties:\n        id:\n          type: string\n        organizationId:\n          type: string\n        general:\n          type: boolean\n        name:\n          type: string\n        imageName:\n          type: string\n        state:\n          allOf:\n          - $ref: '#/components/schemas/SnapshotState'\n        size:\n          nullable: true\n          type: number\n        entrypoint:\n          items:\n            type: string\n          nullable: true\n          type: array\n        cpu:\n          type: number\n        gpu:\n          type: number\n        mem:\n          type: number\n        disk:\n          type: number\n        errorReason:\n          nullable: true\n          type: string\n        createdAt:\n          format: date-time\n          type: string\n        updatedAt:\n          format: date-time\n          type: string\n        lastUsedAt:\n          format: date-time\n          nullable: true\n          type: string\n        buildInfo:\n          allOf:\n          - $ref: '#/components/schemas/BuildInfo'\n          description: Build information for the snapshot\n        regionIds:\n          description: IDs of regions where the snapshot is available\n          items:\n            type: string\n          type: array\n        initialRunnerId:\n          description: The initial runner ID of the snapshot\n          example: runner123\n          type: string\n        ref:\n          description: The snapshot reference\n          example: daytonaio/sandbox:latest\n          type: string\n      required:\n      - cpu\n      - createdAt\n      - disk\n      - entrypoint\n      - errorReason\n      - general\n      - gpu\n      - id\n      - lastUsedAt\n      - mem\n      - name\n      - size\n      - state\n      - updatedAt\n      type: object\n    PaginatedSnapshots:\n      example:\n        total: 2.3021358869347655\n        totalPages: 9.301444243932576\n        page: 7.061401241503109\n        items:\n        - imageName: imageName\n          buildInfo: \"\"\n          cpu: 6.027456183070403\n          regionIds:\n          - regionIds\n          - regionIds\n          gpu: 1.4658129805029452\n          organizationId: organizationId\n          general: true\n          createdAt: 2000-01-23T04:56:07.000+00:00\n          disk: 5.637376656633329\n          ref: daytonaio/sandbox:latest\n          size: 0.8008281904610115\n          mem: 5.962133916683182\n          lastUsedAt: 2000-01-23T04:56:07.000+00:00\n          entrypoint:\n          - entrypoint\n          - entrypoint\n          errorReason: errorReason\n          name: name\n          id: id\n          state: \"\"\n          initialRunnerId: runner123\n          updatedAt: 2000-01-23T04:56:07.000+00:00\n        - imageName: imageName\n          buildInfo: \"\"\n          cpu: 6.027456183070403\n          regionIds:\n          - regionIds\n          - regionIds\n          gpu: 1.4658129805029452\n          organizationId: organizationId\n          general: true\n          createdAt: 2000-01-23T04:56:07.000+00:00\n          disk: 5.637376656633329\n          ref: daytonaio/sandbox:latest\n          size: 0.8008281904610115\n          mem: 5.962133916683182\n          lastUsedAt: 2000-01-23T04:56:07.000+00:00\n          entrypoint:\n          - entrypoint\n          - entrypoint\n          errorReason: errorReason\n          name: name\n          id: id\n          state: \"\"\n          initialRunnerId: runner123\n          updatedAt: 2000-01-23T04:56:07.000+00:00\n      properties:\n        items:\n          items:\n            $ref: '#/components/schemas/SnapshotDto'\n          type: array\n        total:\n          type: number\n        page:\n          type: number\n        totalPages:\n          type: number\n      required:\n      - items\n      - page\n      - total\n      - totalPages\n      type: object\n    SetSnapshotGeneralStatusDto:\n      example:\n        general: true\n      properties:\n        general:\n          description: Whether the snapshot is general\n          example: true\n          type: boolean\n      required:\n      - general\n      type: object\n    SandboxInfo:\n      properties:\n        created:\n          description: The creation timestamp of the project\n          example: 2023-10-01T12:00:00Z\n          type: string\n        name:\n          default: \"\"\n          deprecated: true\n          description: \"Deprecated: The name of the sandbox\"\n          example: MySandbox\n          type: string\n        providerMetadata:\n          description: Additional metadata provided by the provider\n          example: \"{\\\"key\\\": \\\"value\\\"}\"\n          type: string\n      required:\n      - created\n      - name\n      type: object\n    Workspace:\n      example:\n        memory: 4\n        buildInfo: \"\"\n        toolboxProxyUrl: https://proxy.app.daytona.io/toolbox\n        autoStopInterval: 30\n        organizationId: organization123\n        createdAt: 2024-10-01T12:00:00Z\n        networkBlockAll: false\n        autoDeleteInterval: 30\n        snapshotState: None\n        public: false\n        errorReason: The sandbox is not running\n        runnerId: runner123\n        id: sandbox123\n        state: creating\n        class: small\n        updatedAt: 2024-10-01T12:00:00Z\n        info: \"\"\n        desiredState: destroyed\n        image: daytonaio/workspace:latest\n        networkAllowList: \"192.168.1.0/16,10.0.0.0/24\"\n        volumes:\n        - mountPath: /data\n          volumeId: volume123\n          subpath: users/alice\n        - mountPath: /data\n          volumeId: volume123\n          subpath: users/alice\n        cpu: 2\n        recoverable: true\n        env:\n          NODE_ENV: production\n        snapshotCreatedAt: 2024-10-01T12:00:00Z\n        gpu: 0\n        daemonVersion: 1.0.0\n        backupCreatedAt: 2024-10-01T12:00:00Z\n        labels:\n          daytona.io/public: \"true\"\n        target: local\n        disk: 10\n        name: MySandbox\n        backupState: None\n        user: daytona\n        autoArchiveInterval: 10080\n        snapshot: daytonaio/sandbox:latest\n      properties:\n        id:\n          description: The ID of the sandbox\n          example: sandbox123\n          type: string\n        organizationId:\n          description: The organization ID of the sandbox\n          example: organization123\n          type: string\n        name:\n          description: The name of the sandbox\n          example: MySandbox\n          type: string\n        snapshot:\n          description: The snapshot used for the sandbox\n          example: daytonaio/sandbox:latest\n          type: string\n        user:\n          description: The user associated with the project\n          example: daytona\n          type: string\n        env:\n          additionalProperties:\n            type: string\n          description: Environment variables for the sandbox\n          example:\n            NODE_ENV: production\n          type: object\n        labels:\n          additionalProperties:\n            type: string\n          description: Labels for the sandbox\n          example:\n            daytona.io/public: \"true\"\n          type: object\n        public:\n          description: Whether the sandbox http preview is public\n          example: false\n          type: boolean\n        networkBlockAll:\n          description: Whether to block all network access for the sandbox\n          example: false\n          type: boolean\n        networkAllowList:\n          description: Comma-separated list of allowed CIDR network addresses for\n            the sandbox\n          example: \"192.168.1.0/16,10.0.0.0/24\"\n          type: string\n        target:\n          description: The target environment for the sandbox\n          example: local\n          type: string\n        cpu:\n          description: The CPU quota for the sandbox\n          example: 2\n          type: number\n        gpu:\n          description: The GPU quota for the sandbox\n          example: 0\n          type: number\n        memory:\n          description: The memory quota for the sandbox\n          example: 4\n          type: number\n        disk:\n          description: The disk quota for the sandbox\n          example: 10\n          type: number\n        state:\n          allOf:\n          - $ref: '#/components/schemas/SandboxState'\n          description: The state of the sandbox\n          example: creating\n        desiredState:\n          allOf:\n          - $ref: '#/components/schemas/SandboxDesiredState'\n          description: The desired state of the sandbox\n          example: destroyed\n        errorReason:\n          description: The error reason of the sandbox\n          example: The sandbox is not running\n          type: string\n        recoverable:\n          description: Whether the sandbox error is recoverable.\n          example: true\n          type: boolean\n        backupState:\n          description: The state of the backup\n          enum:\n          - None\n          - Pending\n          - InProgress\n          - Completed\n          - Error\n          example: None\n          type: string\n        backupCreatedAt:\n          description: The creation timestamp of the last backup\n          example: 2024-10-01T12:00:00Z\n          type: string\n        autoStopInterval:\n          description: Auto-stop interval in minutes (0 means disabled)\n          example: 30\n          type: number\n        autoArchiveInterval:\n          description: Auto-archive interval in minutes\n          example: 10080\n          type: number\n        autoDeleteInterval:\n          description: \"Auto-delete interval in minutes (negative value means disabled,\\\n            \\ 0 means delete immediately upon stopping)\"\n          example: 30\n          type: number\n        volumes:\n          description: Array of volumes attached to the sandbox\n          items:\n            $ref: '#/components/schemas/SandboxVolume'\n          type: array\n        buildInfo:\n          allOf:\n          - $ref: '#/components/schemas/BuildInfo'\n          description: Build information for the sandbox\n        createdAt:\n          description: The creation timestamp of the sandbox\n          example: 2024-10-01T12:00:00Z\n          type: string\n        updatedAt:\n          description: The last update timestamp of the sandbox\n          example: 2024-10-01T12:00:00Z\n          type: string\n        class:\n          deprecated: true\n          description: The class of the sandbox\n          enum:\n          - small\n          - medium\n          - large\n          example: small\n          type: string\n        daemonVersion:\n          description: The version of the daemon running in the sandbox\n          example: 1.0.0\n          type: string\n        runnerId:\n          description: The runner ID of the sandbox\n          example: runner123\n          type: string\n        toolboxProxyUrl:\n          description: The toolbox proxy URL for the sandbox\n          example: https://proxy.app.daytona.io/toolbox\n          type: string\n        image:\n          description: The image used for the workspace\n          example: daytonaio/workspace:latest\n          type: string\n        snapshotState:\n          description: The state of the snapshot\n          enum:\n          - None\n          - Pending\n          - InProgress\n          - Completed\n          - Error\n          example: None\n          type: string\n        snapshotCreatedAt:\n          description: The creation timestamp of the last snapshot\n          example: 2024-10-01T12:00:00Z\n          type: string\n        info:\n          allOf:\n          - $ref: '#/components/schemas/SandboxInfo'\n          description: Additional information about the sandbox\n      required:\n      - cpu\n      - disk\n      - env\n      - gpu\n      - id\n      - labels\n      - memory\n      - name\n      - networkBlockAll\n      - organizationId\n      - public\n      - target\n      - toolboxProxyUrl\n      - user\n      type: object\n    CreateWorkspace:\n      example:\n        image: daytonaio/workspace:latest\n        memory: 1\n        buildInfo: \"\"\n        volumes:\n        - mountPath: /data\n          volumeId: volume123\n          subpath: users/alice\n        - mountPath: /data\n          volumeId: volume123\n          subpath: users/alice\n        cpu: 2\n        env:\n          NODE_ENV: production\n        gpu: 1\n        autoStopInterval: 30\n        labels:\n          daytona.io/public: \"true\"\n        target: eu\n        disk: 3\n        public: false\n        user: daytona\n        class: small\n        autoArchiveInterval: 10080\n      properties:\n        image:\n          description: The image used for the workspace\n          example: daytonaio/workspace:latest\n          type: string\n        user:\n          description: The user associated with the project\n          example: daytona\n          type: string\n        env:\n          additionalProperties:\n            type: string\n          description: Environment variables for the workspace\n          example:\n            NODE_ENV: production\n          type: object\n        labels:\n          additionalProperties:\n            type: string\n          description: Labels for the workspace\n          example:\n            daytona.io/public: \"true\"\n          type: object\n        public:\n          description: Whether the workspace http preview is publicly accessible\n          example: false\n          type: boolean\n        class:\n          description: The workspace class type\n          enum:\n          - small\n          - medium\n          - large\n          example: small\n          type: string\n        target:\n          description: The target (region) where the workspace will be created\n          enum:\n          - eu\n          - us\n          - asia\n          example: eu\n          type: string\n        cpu:\n          description: CPU cores allocated to the workspace\n          example: 2\n          type: integer\n        gpu:\n          description: GPU units allocated to the workspace\n          example: 1\n          type: integer\n        memory:\n          description: Memory allocated to the workspace in GB\n          example: 1\n          type: integer\n        disk:\n          description: Disk space allocated to the workspace in GB\n          example: 3\n          type: integer\n        autoStopInterval:\n          description: Auto-stop interval in minutes (0 means disabled)\n          example: 30\n          type: integer\n        autoArchiveInterval:\n          description: Auto-archive interval in minutes (0 means the maximum interval\n            will be used)\n          example: 10080\n          type: integer\n        volumes:\n          description: Array of volumes to attach to the workspace\n          items:\n            $ref: '#/components/schemas/SandboxVolume'\n          type: array\n        buildInfo:\n          allOf:\n          - $ref: '#/components/schemas/CreateBuildInfo'\n          description: Build information for the workspace\n      type: object\n    WorkspacePortPreviewUrl:\n      example:\n        url: https://123456-mysandbox.runner.com\n        token: ul67qtv-jl6wb9z5o3eii-ljqt9qed6l\n      properties:\n        url:\n          description: Preview url\n          example: https://123456-mysandbox.runner.com\n          type: string\n        token:\n          description: Access token\n          example: ul67qtv-jl6wb9z5o3eii-ljqt9qed6l\n          type: string\n      required:\n      - token\n      - url\n      type: object\n    VolumeState:\n      description: Volume state\n      enum:\n      - creating\n      - ready\n      - pending_create\n      - pending_delete\n      - deleting\n      - deleted\n      - error\n      type: string\n    VolumeDto:\n      example:\n        organizationId: 123e4567-e89b-12d3-a456-426614174000\n        createdAt: 2023-01-01T00:00:00.000Z\n        lastUsedAt: 2023-01-01T00:00:00.000Z\n        errorReason: Error processing volume\n        name: my-volume\n        id: vol-12345678\n        state: ready\n        updatedAt: 2023-01-01T00:00:00.000Z\n      properties:\n        id:\n          description: Volume ID\n          example: vol-12345678\n          type: string\n        name:\n          description: Volume name\n          example: my-volume\n          type: string\n        organizationId:\n          description: Organization ID\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        state:\n          allOf:\n          - $ref: '#/components/schemas/VolumeState'\n          description: Volume state\n          example: ready\n        createdAt:\n          description: Creation timestamp\n          example: 2023-01-01T00:00:00.000Z\n          type: string\n        updatedAt:\n          description: Last update timestamp\n          example: 2023-01-01T00:00:00.000Z\n          type: string\n        lastUsedAt:\n          description: Last used timestamp\n          example: 2023-01-01T00:00:00.000Z\n          nullable: true\n          type: string\n        errorReason:\n          description: The error reason of the volume\n          example: Error processing volume\n          nullable: true\n          type: string\n      required:\n      - createdAt\n      - errorReason\n      - id\n      - name\n      - organizationId\n      - state\n      - updatedAt\n      type: object\n    CreateVolume:\n      example:\n        name: name\n      properties:\n        name:\n          type: string\n      required:\n      - name\n      type: object\n    JobStatus:\n      enum:\n      - PENDING\n      - IN_PROGRESS\n      - COMPLETED\n      - FAILED\n      type: string\n    JobType:\n      description: The type of the job\n      enum:\n      - CREATE_SANDBOX\n      - START_SANDBOX\n      - STOP_SANDBOX\n      - DESTROY_SANDBOX\n      - RESIZE_SANDBOX\n      - CREATE_BACKUP\n      - BUILD_SNAPSHOT\n      - PULL_SNAPSHOT\n      - RECOVER_SANDBOX\n      - INSPECT_SNAPSHOT_IN_REGISTRY\n      - REMOVE_SNAPSHOT\n      - UPDATE_SANDBOX_NETWORK_SETTINGS\n      type: string\n    Job:\n      example:\n        createdAt: 2024-10-01T12:00:00Z\n        resourceId: sandbox123\n        payload: payload\n        errorMessage: Failed to create sandbox\n        id: job123\n        type: CREATE_SANDBOX\n        traceContext:\n          traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\n        status: PENDING\n        resourceType: SANDBOX\n        updatedAt: 2024-10-01T12:00:00Z\n      properties:\n        id:\n          description: The ID of the job\n          example: job123\n          type: string\n        type:\n          allOf:\n          - $ref: '#/components/schemas/JobType'\n          description: The type of the job\n          example: CREATE_SANDBOX\n        status:\n          allOf:\n          - $ref: '#/components/schemas/JobStatus'\n          description: The status of the job\n          example: PENDING\n        resourceType:\n          description: The type of resource this job operates on\n          enum:\n          - SANDBOX\n          - SNAPSHOT\n          - BACKUP\n          example: SANDBOX\n          type: string\n        resourceId:\n          description: \"The ID of the resource this job operates on (sandboxId, snapshotRef,\\\n            \\ etc.)\"\n          example: sandbox123\n          type: string\n        payload:\n          description: Job-specific JSON-encoded payload data (operational metadata)\n          type: string\n        traceContext:\n          additionalProperties: true\n          description: OpenTelemetry trace context for distributed tracing (W3C Trace\n            Context format)\n          example:\n            traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\n          type: object\n        errorMessage:\n          description: Error message if the job failed\n          example: Failed to create sandbox\n          type: string\n        createdAt:\n          description: The creation timestamp of the job\n          example: 2024-10-01T12:00:00Z\n          type: string\n        updatedAt:\n          description: The last update timestamp of the job\n          example: 2024-10-01T12:00:00Z\n          type: string\n      required:\n      - createdAt\n      - id\n      - resourceId\n      - resourceType\n      - status\n      - type\n      type: object\n    PaginatedJobs:\n      example:\n        total: 0.8008281904610115\n        totalPages: 1.4658129805029452\n        page: 6.027456183070403\n        items:\n        - createdAt: 2024-10-01T12:00:00Z\n          resourceId: sandbox123\n          payload: payload\n          errorMessage: Failed to create sandbox\n          id: job123\n          type: CREATE_SANDBOX\n          traceContext:\n            traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\n          status: PENDING\n          resourceType: SANDBOX\n          updatedAt: 2024-10-01T12:00:00Z\n        - createdAt: 2024-10-01T12:00:00Z\n          resourceId: sandbox123\n          payload: payload\n          errorMessage: Failed to create sandbox\n          id: job123\n          type: CREATE_SANDBOX\n          traceContext:\n            traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\n          status: PENDING\n          resourceType: SANDBOX\n          updatedAt: 2024-10-01T12:00:00Z\n      properties:\n        items:\n          items:\n            $ref: '#/components/schemas/Job'\n          type: array\n        total:\n          type: number\n        page:\n          type: number\n        totalPages:\n          type: number\n      required:\n      - items\n      - page\n      - total\n      - totalPages\n      type: object\n    PollJobsResponse:\n      example:\n        jobs:\n        - createdAt: 2024-10-01T12:00:00Z\n          resourceId: sandbox123\n          payload: payload\n          errorMessage: Failed to create sandbox\n          id: job123\n          type: CREATE_SANDBOX\n          traceContext:\n            traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\n          status: PENDING\n          resourceType: SANDBOX\n          updatedAt: 2024-10-01T12:00:00Z\n        - createdAt: 2024-10-01T12:00:00Z\n          resourceId: sandbox123\n          payload: payload\n          errorMessage: Failed to create sandbox\n          id: job123\n          type: CREATE_SANDBOX\n          traceContext:\n            traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\n          status: PENDING\n          resourceType: SANDBOX\n          updatedAt: 2024-10-01T12:00:00Z\n      properties:\n        jobs:\n          description: List of jobs\n          items:\n            $ref: '#/components/schemas/Job'\n          type: array\n      required:\n      - jobs\n      type: object\n    UpdateJobStatus:\n      example:\n        resultMetadata: resultMetadata\n        errorMessage: Failed to create sandbox\n        status: IN_PROGRESS\n      properties:\n        status:\n          allOf:\n          - $ref: '#/components/schemas/JobStatus'\n          description: The new status of the job\n          example: IN_PROGRESS\n        errorMessage:\n          description: Error message if the job failed\n          example: Failed to create sandbox\n          type: string\n        resultMetadata:\n          description: Result metadata for the job\n          type: string\n      required:\n      - status\n      type: object\n    CreateDockerRegistry:\n      example:\n        registryType: organization\n        password: password\n        isDefault: true\n        name: name\n        project: project\n        url: url\n        username: username\n      properties:\n        name:\n          description: Registry name\n          type: string\n        url:\n          description: Registry URL\n          type: string\n        username:\n          description: Registry username\n          type: string\n        password:\n          description: Registry password\n          type: string\n        project:\n          description: Registry project\n          type: string\n        registryType:\n          default: organization\n          description: Registry type\n          enum:\n          - internal\n          - organization\n          - transient\n          - backup\n          type: string\n        isDefault:\n          description: Set as default registry\n          type: boolean\n      required:\n      - name\n      - password\n      - registryType\n      - url\n      - username\n      type: object\n    DockerRegistry:\n      example:\n        registryType: internal\n        createdAt: 2024-01-31T12:00:00Z\n        name: My Docker Hub\n        project: my-project\n        id: 123e4567-e89b-12d3-a456-426614174000\n        url: https://registry.hub.docker.com\n        username: username\n        updatedAt: 2024-01-31T12:00:00Z\n      properties:\n        id:\n          description: Registry ID\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        name:\n          description: Registry name\n          example: My Docker Hub\n          type: string\n        url:\n          description: Registry URL\n          example: https://registry.hub.docker.com\n          type: string\n        username:\n          description: Registry username\n          example: username\n          type: string\n        project:\n          description: Registry project\n          example: my-project\n          type: string\n        registryType:\n          description: Registry type\n          enum:\n          - internal\n          - organization\n          - transient\n          - backup\n          example: internal\n          type: string\n        createdAt:\n          description: Creation timestamp\n          example: 2024-01-31T12:00:00Z\n          format: date-time\n          type: string\n        updatedAt:\n          description: Last update timestamp\n          example: 2024-01-31T12:00:00Z\n          format: date-time\n          type: string\n      required:\n      - createdAt\n      - id\n      - name\n      - project\n      - registryType\n      - updatedAt\n      - url\n      - username\n      type: object\n    RegistryPushAccessDto:\n      example:\n        registryUrl: registry.example.com\n        registryId: 123e4567-e89b-12d3-a456-426614174000\n        project: library\n        secret: eyJhbGciOiJIUzI1NiIs...\n        expiresAt: 2023-12-31T23:59:59Z\n        username: temp-user-123\n      properties:\n        username:\n          description: Temporary username for registry authentication\n          example: temp-user-123\n          type: string\n        secret:\n          description: Temporary secret for registry authentication\n          example: eyJhbGciOiJIUzI1NiIs...\n          type: string\n        registryUrl:\n          description: Registry URL\n          example: registry.example.com\n          type: string\n        registryId:\n          description: Registry ID\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        project:\n          description: Registry project ID\n          example: library\n          type: string\n        expiresAt:\n          description: Token expiration time in ISO format\n          example: 2023-12-31T23:59:59Z\n          type: string\n      required:\n      - expiresAt\n      - project\n      - registryId\n      - registryUrl\n      - secret\n      - username\n      type: object\n    UpdateDockerRegistry:\n      example:\n        password: password\n        name: name\n        project: project\n        url: url\n        username: username\n      properties:\n        name:\n          description: Registry name\n          type: string\n        url:\n          description: Registry URL\n          type: string\n        username:\n          description: Registry username\n          type: string\n        password:\n          description: Registry password\n          type: string\n        project:\n          description: Registry project\n          type: string\n      required:\n      - name\n      - url\n      - username\n      type: object\n    AdminCreateRunner:\n      example:\n        diskGiB: 100\n        apiVersion: \"2\"\n        apiKey: apiKey\n        apiUrl: https://api.runner1.example.com\n        regionId: regionId\n        proxyUrl: https://proxy.runner1.example.com\n        memoryGiB: 16\n        domain: runner1.example.com\n        name: name\n        cpu: 8\n      properties:\n        regionId:\n          type: string\n        name:\n          type: string\n        apiKey:\n          type: string\n        apiVersion:\n          description: The api version of the runner to create\n          example: \"2\"\n          pattern: ^(0|2)$\n          type: string\n        domain:\n          description: The domain of the runner\n          example: runner1.example.com\n          type: string\n        apiUrl:\n          description: The API URL of the runner\n          example: https://api.runner1.example.com\n          type: string\n        proxyUrl:\n          description: The proxy URL of the runner\n          example: https://proxy.runner1.example.com\n          type: string\n        cpu:\n          description: The CPU capacity of the runner\n          example: 8\n          type: number\n        memoryGiB:\n          description: The memory capacity of the runner in GiB\n          example: 16\n          type: number\n        diskGiB:\n          description: The disk capacity of the runner in GiB\n          example: 100\n          type: number\n      required:\n      - apiKey\n      - apiVersion\n      - name\n      - regionId\n      type: object\n    WebhookAppPortalAccess:\n      example:\n        url: https://app.svix.com/app_1234567890\n        token: appsk_...\n      properties:\n        token:\n          description: The authentication token for the Svix consumer app portal\n          example: appsk_...\n          type: string\n        url:\n          description: The URL to the webhook app portal\n          example: https://app.svix.com/app_1234567890\n          type: string\n      required:\n      - token\n      - url\n      type: object\n    WebhookEvent:\n      description: The type of event being sent\n      enum:\n      - sandbox.created\n      - sandbox.state.updated\n      - snapshot.created\n      - snapshot.state.updated\n      - snapshot.removed\n      - volume.created\n      - volume.state.updated\n      type: string\n    SendWebhookDto:\n      example:\n        eventId: evt_1234567890abcdef\n        payload:\n          id: sandbox-123\n          name: My Sandbox\n        eventType: sandbox.created\n      properties:\n        eventType:\n          allOf:\n          - $ref: '#/components/schemas/WebhookEvent'\n          description: The type of event being sent\n          example: sandbox.created\n        payload:\n          description: The payload data to send\n          example:\n            id: sandbox-123\n            name: My Sandbox\n          type: object\n        eventId:\n          description: Optional event ID for idempotency\n          example: evt_1234567890abcdef\n          type: string\n      required:\n      - eventType\n      - payload\n      type: object\n    WebhookInitializationStatus:\n      example:\n        organizationId: 123e4567-e89b-12d3-a456-426614174000\n        createdAt: 2023-01-01T00:00:00.000Z\n        lastError: Failed to create Svix application\n        retryCount: 3\n        svixApplicationId: app_1234567890\n        updatedAt: 2023-01-01T00:00:00.000Z\n      properties:\n        organizationId:\n          description: Organization ID\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        svixApplicationId:\n          description: The ID of the Svix application\n          example: app_1234567890\n          nullable: true\n          type: string\n        lastError:\n          description: The error reason for the last initialization attempt\n          example: Failed to create Svix application\n          nullable: true\n          type: string\n        retryCount:\n          description: The number of times the initialization has been attempted\n          example: 3\n          type: number\n        createdAt:\n          description: When the webhook initialization was created\n          example: 2023-01-01T00:00:00.000Z\n          type: string\n        updatedAt:\n          description: When the webhook initialization was last updated\n          example: 2023-01-01T00:00:00.000Z\n          type: string\n      required:\n      - createdAt\n      - lastError\n      - organizationId\n      - retryCount\n      - svixApplicationId\n      - updatedAt\n      type: object\n    StorageAccessDto:\n      example:\n        organizationId: 123e4567-e89b-12d3-a456-426614174000\n        bucket: daytona\n        accessKey: temp-user-123\n        sessionToken: eyJhbGciOiJIUzI1NiIs...\n        secret: abchbGciOiJIUzI1NiIs...\n        storageUrl: storage.example.com\n      properties:\n        accessKey:\n          description: Access key for storage authentication\n          example: temp-user-123\n          type: string\n        secret:\n          description: Secret key for storage authentication\n          example: abchbGciOiJIUzI1NiIs...\n          type: string\n        sessionToken:\n          description: Session token for storage authentication\n          example: eyJhbGciOiJIUzI1NiIs...\n          type: string\n        storageUrl:\n          description: Storage URL\n          example: storage.example.com\n          type: string\n        organizationId:\n          description: Organization ID\n          example: 123e4567-e89b-12d3-a456-426614174000\n          type: string\n        bucket:\n          description: S3 bucket name\n          example: daytona\n          type: string\n      required:\n      - accessKey\n      - bucket\n      - organizationId\n      - secret\n      - sessionToken\n      - storageUrl\n      type: object\n    AuditLog:\n      example:\n        metadata:\n          key: \"\"\n        targetId: targetId\n        errorMessage: errorMessage\n        ipAddress: ipAddress\n        actorEmail: actorEmail\n        targetType: targetType\n        userAgent: userAgent\n        source: source\n        organizationId: organizationId\n        createdAt: 2000-01-23T04:56:07.000+00:00\n        actorId: actorId\n        action: action\n        id: id\n        statusCode: 0.8008281904610115\n      properties:\n        id:\n          type: string\n        actorId:\n          type: string\n        actorEmail:\n          type: string\n        organizationId:\n          type: string\n        action:\n          type: string\n        targetType:\n          type: string\n        targetId:\n          type: string\n        statusCode:\n          type: number\n        errorMessage:\n          type: string\n        ipAddress:\n          type: string\n        userAgent:\n          type: string\n        source:\n          type: string\n        metadata:\n          additionalProperties: true\n          type: object\n        createdAt:\n          format: date-time\n          type: string\n      required:\n      - action\n      - actorEmail\n      - actorId\n      - createdAt\n      - id\n      type: object\n    PaginatedAuditLogs:\n      example:\n        total: 6.027456183070403\n        nextToken: nextToken\n        totalPages: 5.962133916683182\n        page: 1.4658129805029452\n        items:\n        - metadata:\n            key: \"\"\n          targetId: targetId\n          errorMessage: errorMessage\n          ipAddress: ipAddress\n          actorEmail: actorEmail\n          targetType: targetType\n          userAgent: userAgent\n          source: source\n          organizationId: organizationId\n          createdAt: 2000-01-23T04:56:07.000+00:00\n          actorId: actorId\n          action: action\n          id: id\n          statusCode: 0.8008281904610115\n        - metadata:\n            key: \"\"\n          targetId: targetId\n          errorMessage: errorMessage\n          ipAddress: ipAddress\n          actorEmail: actorEmail\n          targetType: targetType\n          userAgent: userAgent\n          source: source\n          organizationId: organizationId\n          createdAt: 2000-01-23T04:56:07.000+00:00\n          actorId: actorId\n          action: action\n          id: id\n          statusCode: 0.8008281904610115\n      properties:\n        items:\n          items:\n            $ref: '#/components/schemas/AuditLog'\n          type: array\n        total:\n          type: number\n        page:\n          type: number\n        totalPages:\n          type: number\n        nextToken:\n          description: Token for next page in cursor-based pagination\n          type: string\n      required:\n      - items\n      - page\n      - total\n      - totalPages\n      type: object\n    LogEntry:\n      example:\n        traceId: traceId\n        spanId: spanId\n        severityText: severityText\n        severityNumber: 0.8008281904610115\n        logAttributes:\n          key: logAttributes\n        body: body\n        serviceName: serviceName\n        resourceAttributes:\n          key: resourceAttributes\n        timestamp: timestamp\n      properties:\n        timestamp:\n          description: Timestamp of the log entry\n          type: string\n        body:\n          description: Log message body\n          type: string\n        severityText:\n          description: \"Severity level text (e.g., INFO, WARN, ERROR)\"\n          type: string\n        severityNumber:\n          description: Severity level number\n          type: number\n        serviceName:\n          description: Service name that generated the log\n          type: string\n        resourceAttributes:\n          additionalProperties:\n            type: string\n          description: Resource attributes from OTEL\n          type: object\n        logAttributes:\n          additionalProperties:\n            type: string\n          description: Log-specific attributes\n          type: object\n        traceId:\n          description: Associated trace ID if available\n          type: string\n        spanId:\n          description: Associated span ID if available\n          type: string\n      required:\n      - body\n      - logAttributes\n      - resourceAttributes\n      - serviceName\n      - severityText\n      - timestamp\n      type: object\n    PaginatedLogs:\n      example:\n        total: 6.027456183070403\n        totalPages: 5.962133916683182\n        page: 1.4658129805029452\n        items:\n        - traceId: traceId\n          spanId: spanId\n          severityText: severityText\n          severityNumber: 0.8008281904610115\n          logAttributes:\n            key: logAttributes\n          body: body\n          serviceName: serviceName\n          resourceAttributes:\n            key: resourceAttributes\n          timestamp: timestamp\n        - traceId: traceId\n          spanId: spanId\n          severityText: severityText\n          severityNumber: 0.8008281904610115\n          logAttributes:\n            key: logAttributes\n          body: body\n          serviceName: serviceName\n          resourceAttributes:\n            key: resourceAttributes\n          timestamp: timestamp\n      properties:\n        items:\n          description: List of log entries\n          items:\n            $ref: '#/components/schemas/LogEntry'\n          type: array\n        total:\n          description: Total number of log entries matching the query\n          type: number\n        page:\n          description: Current page number\n          type: number\n        totalPages:\n          description: Total number of pages\n          type: number\n      required:\n      - items\n      - page\n      - total\n      - totalPages\n      type: object\n    TraceSummary:\n      example:\n        traceId: traceId\n        spanCount: 6.027456183070403\n        rootSpanName: rootSpanName\n        startTime: startTime\n        endTime: endTime\n        durationMs: 0.8008281904610115\n        statusCode: statusCode\n      properties:\n        traceId:\n          description: Unique trace identifier\n          type: string\n        rootSpanName:\n          description: Name of the root span\n          type: string\n        startTime:\n          description: Trace start time\n          type: string\n        endTime:\n          description: Trace end time\n          type: string\n        durationMs:\n          description: Total duration in milliseconds\n          type: number\n        spanCount:\n          description: Number of spans in this trace\n          type: number\n        statusCode:\n          description: Status code of the trace\n          type: string\n      required:\n      - durationMs\n      - endTime\n      - rootSpanName\n      - spanCount\n      - startTime\n      - traceId\n      type: object\n    PaginatedTraces:\n      example:\n        total: 1.4658129805029452\n        totalPages: 5.637376656633329\n        page: 5.962133916683182\n        items:\n        - traceId: traceId\n          spanCount: 6.027456183070403\n          rootSpanName: rootSpanName\n          startTime: startTime\n          endTime: endTime\n          durationMs: 0.8008281904610115\n          statusCode: statusCode\n        - traceId: traceId\n          spanCount: 6.027456183070403\n          rootSpanName: rootSpanName\n          startTime: startTime\n          endTime: endTime\n          durationMs: 0.8008281904610115\n          statusCode: statusCode\n      properties:\n        items:\n          description: List of trace summaries\n          items:\n            $ref: '#/components/schemas/TraceSummary'\n          type: array\n        total:\n          description: Total number of traces matching the query\n          type: number\n        page:\n          description: Current page number\n          type: number\n        totalPages:\n          description: Total number of pages\n          type: number\n      required:\n      - items\n      - page\n      - total\n      - totalPages\n      type: object\n    TraceSpan:\n      example:\n        traceId: traceId\n        spanId: spanId\n        spanAttributes:\n          key: spanAttributes\n        parentSpanId: parentSpanId\n        durationNs: 0.8008281904610115\n        statusMessage: statusMessage\n        spanName: spanName\n        timestamp: timestamp\n        statusCode: statusCode\n      properties:\n        traceId:\n          description: Trace identifier\n          type: string\n        spanId:\n          description: Span identifier\n          type: string\n        parentSpanId:\n          description: Parent span identifier\n          type: string\n        spanName:\n          description: Span name\n          type: string\n        timestamp:\n          description: Span start timestamp\n          type: string\n        durationNs:\n          description: Span duration in nanoseconds\n          type: number\n        spanAttributes:\n          additionalProperties:\n            type: string\n          description: Span attributes\n          type: object\n        statusCode:\n          description: Status code of the span\n          type: string\n        statusMessage:\n          description: Status message\n          type: string\n      required:\n      - durationNs\n      - spanAttributes\n      - spanId\n      - spanName\n      - timestamp\n      - traceId\n      type: object\n    MetricDataPoint:\n      example:\n        value: 0.8008281904610115\n        timestamp: timestamp\n      properties:\n        timestamp:\n          description: Timestamp of the data point\n          type: string\n        value:\n          description: Value at this timestamp\n          type: number\n      required:\n      - timestamp\n      - value\n      type: object\n    MetricSeries:\n      example:\n        metricName: metricName\n        dataPoints:\n        - value: 0.8008281904610115\n          timestamp: timestamp\n        - value: 0.8008281904610115\n          timestamp: timestamp\n      properties:\n        metricName:\n          description: Name of the metric\n          type: string\n        dataPoints:\n          description: Data points for this metric\n          items:\n            $ref: '#/components/schemas/MetricDataPoint'\n          type: array\n      required:\n      - dataPoints\n      - metricName\n      type: object\n    MetricsResponse:\n      example:\n        series:\n        - metricName: metricName\n          dataPoints:\n          - value: 0.8008281904610115\n            timestamp: timestamp\n          - value: 0.8008281904610115\n            timestamp: timestamp\n        - metricName: metricName\n          dataPoints:\n          - value: 0.8008281904610115\n            timestamp: timestamp\n          - value: 0.8008281904610115\n            timestamp: timestamp\n      properties:\n        series:\n          description: List of metric series\n          items:\n            $ref: '#/components/schemas/MetricSeries'\n          type: array\n      required:\n      - series\n      type: object\n    uploadFile_deprecated_request:\n      properties:\n        file:\n          format: binary\n          type: string\n      type: object\n    WebhookController_getStatus_200_response:\n      example:\n        enabled: true\n      properties:\n        enabled:\n          type: boolean\n      type: object\n    HealthController_check_200_response_info_value:\n      additionalProperties: true\n      properties:\n        status:\n          type: string\n      required:\n      - status\n      type: object\n    HealthController_check_200_response:\n      example:\n        details:\n          database:\n            status: up\n        error: {}\n        status: ok\n        info:\n          database:\n            status: up\n      properties:\n        status:\n          example: ok\n          type: string\n        info:\n          additionalProperties:\n            $ref: '#/components/schemas/HealthController_check_200_response_info_value'\n          example:\n            database:\n              status: up\n          nullable: true\n          type: object\n        error:\n          additionalProperties:\n            $ref: '#/components/schemas/HealthController_check_200_response_info_value'\n          example: {}\n          nullable: true\n          type: object\n        details:\n          additionalProperties:\n            $ref: '#/components/schemas/HealthController_check_200_response_info_value'\n          example:\n            database:\n              status: up\n          type: object\n      type: object\n    HealthController_check_503_response:\n      example:\n        details:\n          database:\n            status: up\n          redis:\n            status: down\n            message: Could not connect\n        error:\n          redis:\n            status: down\n            message: Could not connect\n        status: error\n        info:\n          database:\n            status: up\n      properties:\n        status:\n          example: error\n          type: string\n        info:\n          additionalProperties:\n            $ref: '#/components/schemas/HealthController_check_200_response_info_value'\n          example:\n            database:\n              status: up\n          nullable: true\n          type: object\n        error:\n          additionalProperties:\n            $ref: '#/components/schemas/HealthController_check_200_response_info_value'\n          example:\n            redis:\n              status: down\n              message: Could not connect\n          nullable: true\n          type: object\n        details:\n          additionalProperties:\n            $ref: '#/components/schemas/HealthController_check_200_response_info_value'\n          example:\n            database:\n              status: up\n            redis:\n              status: down\n              message: Could not connect\n          type: object\n      type: object\n  securitySchemes:\n    bearer:\n      bearerFormat: JWT\n      description: API Key access\n      scheme: bearer\n      type: http\n    oauth2:\n      openIdConnectUrl: http://localhost:3000/.well-known/openid-configuration\n      type: openIdConnect\n"
  },
  {
    "path": "libs/api-client-go/api_admin.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype AdminAPI interface {\n\n\t/*\n\tAdminCreateRunner Create runner\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return AdminAPIAdminCreateRunnerRequest\n\t*/\n\tAdminCreateRunner(ctx context.Context) AdminAPIAdminCreateRunnerRequest\n\n\t// AdminCreateRunnerExecute executes the request\n\t//  @return CreateRunnerResponse\n\tAdminCreateRunnerExecute(r AdminAPIAdminCreateRunnerRequest) (*CreateRunnerResponse, *http.Response, error)\n\n\t/*\n\tAdminDeleteRunner Delete runner\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Runner ID\n\t@return AdminAPIAdminDeleteRunnerRequest\n\t*/\n\tAdminDeleteRunner(ctx context.Context, id string) AdminAPIAdminDeleteRunnerRequest\n\n\t// AdminDeleteRunnerExecute executes the request\n\tAdminDeleteRunnerExecute(r AdminAPIAdminDeleteRunnerRequest) (*http.Response, error)\n\n\t/*\n\tAdminGetRunnerById Get runner by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Runner ID\n\t@return AdminAPIAdminGetRunnerByIdRequest\n\t*/\n\tAdminGetRunnerById(ctx context.Context, id string) AdminAPIAdminGetRunnerByIdRequest\n\n\t// AdminGetRunnerByIdExecute executes the request\n\t//  @return RunnerFull\n\tAdminGetRunnerByIdExecute(r AdminAPIAdminGetRunnerByIdRequest) (*RunnerFull, *http.Response, error)\n\n\t/*\n\tAdminListRunners List all runners\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return AdminAPIAdminListRunnersRequest\n\t*/\n\tAdminListRunners(ctx context.Context) AdminAPIAdminListRunnersRequest\n\n\t// AdminListRunnersExecute executes the request\n\t//  @return []RunnerFull\n\tAdminListRunnersExecute(r AdminAPIAdminListRunnersRequest) ([]RunnerFull, *http.Response, error)\n\n\t/*\n\tAdminRecoverSandbox Recover sandbox from error state as an admin\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@return AdminAPIAdminRecoverSandboxRequest\n\t*/\n\tAdminRecoverSandbox(ctx context.Context, sandboxId string) AdminAPIAdminRecoverSandboxRequest\n\n\t// AdminRecoverSandboxExecute executes the request\n\t//  @return Sandbox\n\tAdminRecoverSandboxExecute(r AdminAPIAdminRecoverSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tAdminUpdateRunnerScheduling Update runner scheduling status\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id\n\t@return AdminAPIAdminUpdateRunnerSchedulingRequest\n\t*/\n\tAdminUpdateRunnerScheduling(ctx context.Context, id string) AdminAPIAdminUpdateRunnerSchedulingRequest\n\n\t// AdminUpdateRunnerSchedulingExecute executes the request\n\tAdminUpdateRunnerSchedulingExecute(r AdminAPIAdminUpdateRunnerSchedulingRequest) (*http.Response, error)\n}\n\n// AdminAPIService AdminAPI service\ntype AdminAPIService service\n\ntype AdminAPIAdminCreateRunnerRequest struct {\n\tctx context.Context\n\tApiService AdminAPI\n\tadminCreateRunner *AdminCreateRunner\n}\n\nfunc (r AdminAPIAdminCreateRunnerRequest) AdminCreateRunner(adminCreateRunner AdminCreateRunner) AdminAPIAdminCreateRunnerRequest {\n\tr.adminCreateRunner = &adminCreateRunner\n\treturn r\n}\n\nfunc (r AdminAPIAdminCreateRunnerRequest) Execute() (*CreateRunnerResponse, *http.Response, error) {\n\treturn r.ApiService.AdminCreateRunnerExecute(r)\n}\n\n/*\nAdminCreateRunner Create runner\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return AdminAPIAdminCreateRunnerRequest\n*/\nfunc (a *AdminAPIService) AdminCreateRunner(ctx context.Context) AdminAPIAdminCreateRunnerRequest {\n\treturn AdminAPIAdminCreateRunnerRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return CreateRunnerResponse\nfunc (a *AdminAPIService) AdminCreateRunnerExecute(r AdminAPIAdminCreateRunnerRequest) (*CreateRunnerResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *CreateRunnerResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"AdminAPIService.AdminCreateRunner\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/admin/runners\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.adminCreateRunner == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"adminCreateRunner is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.adminCreateRunner\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype AdminAPIAdminDeleteRunnerRequest struct {\n\tctx context.Context\n\tApiService AdminAPI\n\tid string\n}\n\nfunc (r AdminAPIAdminDeleteRunnerRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.AdminDeleteRunnerExecute(r)\n}\n\n/*\nAdminDeleteRunner Delete runner\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Runner ID\n @return AdminAPIAdminDeleteRunnerRequest\n*/\nfunc (a *AdminAPIService) AdminDeleteRunner(ctx context.Context, id string) AdminAPIAdminDeleteRunnerRequest {\n\treturn AdminAPIAdminDeleteRunnerRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *AdminAPIService) AdminDeleteRunnerExecute(r AdminAPIAdminDeleteRunnerRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"AdminAPIService.AdminDeleteRunner\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/admin/runners/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype AdminAPIAdminGetRunnerByIdRequest struct {\n\tctx context.Context\n\tApiService AdminAPI\n\tid string\n}\n\nfunc (r AdminAPIAdminGetRunnerByIdRequest) Execute() (*RunnerFull, *http.Response, error) {\n\treturn r.ApiService.AdminGetRunnerByIdExecute(r)\n}\n\n/*\nAdminGetRunnerById Get runner by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Runner ID\n @return AdminAPIAdminGetRunnerByIdRequest\n*/\nfunc (a *AdminAPIService) AdminGetRunnerById(ctx context.Context, id string) AdminAPIAdminGetRunnerByIdRequest {\n\treturn AdminAPIAdminGetRunnerByIdRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return RunnerFull\nfunc (a *AdminAPIService) AdminGetRunnerByIdExecute(r AdminAPIAdminGetRunnerByIdRequest) (*RunnerFull, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RunnerFull\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"AdminAPIService.AdminGetRunnerById\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/admin/runners/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype AdminAPIAdminListRunnersRequest struct {\n\tctx context.Context\n\tApiService AdminAPI\n\tregionId *string\n}\n\n// Filter runners by region ID\nfunc (r AdminAPIAdminListRunnersRequest) RegionId(regionId string) AdminAPIAdminListRunnersRequest {\n\tr.regionId = &regionId\n\treturn r\n}\n\nfunc (r AdminAPIAdminListRunnersRequest) Execute() ([]RunnerFull, *http.Response, error) {\n\treturn r.ApiService.AdminListRunnersExecute(r)\n}\n\n/*\nAdminListRunners List all runners\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return AdminAPIAdminListRunnersRequest\n*/\nfunc (a *AdminAPIService) AdminListRunners(ctx context.Context) AdminAPIAdminListRunnersRequest {\n\treturn AdminAPIAdminListRunnersRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []RunnerFull\nfunc (a *AdminAPIService) AdminListRunnersExecute(r AdminAPIAdminListRunnersRequest) ([]RunnerFull, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []RunnerFull\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"AdminAPIService.AdminListRunners\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/admin/runners\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.regionId != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"regionId\", r.regionId, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype AdminAPIAdminRecoverSandboxRequest struct {\n\tctx context.Context\n\tApiService AdminAPI\n\tsandboxId string\n}\n\nfunc (r AdminAPIAdminRecoverSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.AdminRecoverSandboxExecute(r)\n}\n\n/*\nAdminRecoverSandbox Recover sandbox from error state as an admin\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @return AdminAPIAdminRecoverSandboxRequest\n*/\nfunc (a *AdminAPIService) AdminRecoverSandbox(ctx context.Context, sandboxId string) AdminAPIAdminRecoverSandboxRequest {\n\treturn AdminAPIAdminRecoverSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *AdminAPIService) AdminRecoverSandboxExecute(r AdminAPIAdminRecoverSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"AdminAPIService.AdminRecoverSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/admin/sandbox/{sandboxId}/recover\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype AdminAPIAdminUpdateRunnerSchedulingRequest struct {\n\tctx context.Context\n\tApiService AdminAPI\n\tid string\n}\n\nfunc (r AdminAPIAdminUpdateRunnerSchedulingRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.AdminUpdateRunnerSchedulingExecute(r)\n}\n\n/*\nAdminUpdateRunnerScheduling Update runner scheduling status\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id\n @return AdminAPIAdminUpdateRunnerSchedulingRequest\n*/\nfunc (a *AdminAPIService) AdminUpdateRunnerScheduling(ctx context.Context, id string) AdminAPIAdminUpdateRunnerSchedulingRequest {\n\treturn AdminAPIAdminUpdateRunnerSchedulingRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *AdminAPIService) AdminUpdateRunnerSchedulingExecute(r AdminAPIAdminUpdateRunnerSchedulingRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"AdminAPIService.AdminUpdateRunnerScheduling\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/admin/runners/{id}/scheduling\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_api_keys.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype ApiKeysAPI interface {\n\n\t/*\n\tCreateApiKey Create API key\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return ApiKeysAPICreateApiKeyRequest\n\t*/\n\tCreateApiKey(ctx context.Context) ApiKeysAPICreateApiKeyRequest\n\n\t// CreateApiKeyExecute executes the request\n\t//  @return ApiKeyResponse\n\tCreateApiKeyExecute(r ApiKeysAPICreateApiKeyRequest) (*ApiKeyResponse, *http.Response, error)\n\n\t/*\n\tDeleteApiKey Delete API key\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param name\n\t@return ApiKeysAPIDeleteApiKeyRequest\n\t*/\n\tDeleteApiKey(ctx context.Context, name string) ApiKeysAPIDeleteApiKeyRequest\n\n\t// DeleteApiKeyExecute executes the request\n\tDeleteApiKeyExecute(r ApiKeysAPIDeleteApiKeyRequest) (*http.Response, error)\n\n\t/*\n\tDeleteApiKeyForUser Delete API key for user\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param userId\n\t@param name\n\t@return ApiKeysAPIDeleteApiKeyForUserRequest\n\t*/\n\tDeleteApiKeyForUser(ctx context.Context, userId string, name string) ApiKeysAPIDeleteApiKeyForUserRequest\n\n\t// DeleteApiKeyForUserExecute executes the request\n\tDeleteApiKeyForUserExecute(r ApiKeysAPIDeleteApiKeyForUserRequest) (*http.Response, error)\n\n\t/*\n\tGetApiKey Get API key\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param name\n\t@return ApiKeysAPIGetApiKeyRequest\n\t*/\n\tGetApiKey(ctx context.Context, name string) ApiKeysAPIGetApiKeyRequest\n\n\t// GetApiKeyExecute executes the request\n\t//  @return ApiKeyList\n\tGetApiKeyExecute(r ApiKeysAPIGetApiKeyRequest) (*ApiKeyList, *http.Response, error)\n\n\t/*\n\tGetCurrentApiKey Get current API key's details\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return ApiKeysAPIGetCurrentApiKeyRequest\n\t*/\n\tGetCurrentApiKey(ctx context.Context) ApiKeysAPIGetCurrentApiKeyRequest\n\n\t// GetCurrentApiKeyExecute executes the request\n\t//  @return ApiKeyList\n\tGetCurrentApiKeyExecute(r ApiKeysAPIGetCurrentApiKeyRequest) (*ApiKeyList, *http.Response, error)\n\n\t/*\n\tListApiKeys List API keys\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return ApiKeysAPIListApiKeysRequest\n\t*/\n\tListApiKeys(ctx context.Context) ApiKeysAPIListApiKeysRequest\n\n\t// ListApiKeysExecute executes the request\n\t//  @return []ApiKeyList\n\tListApiKeysExecute(r ApiKeysAPIListApiKeysRequest) ([]ApiKeyList, *http.Response, error)\n}\n\n// ApiKeysAPIService ApiKeysAPI service\ntype ApiKeysAPIService service\n\ntype ApiKeysAPICreateApiKeyRequest struct {\n\tctx context.Context\n\tApiService ApiKeysAPI\n\tcreateApiKey *CreateApiKey\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ApiKeysAPICreateApiKeyRequest) CreateApiKey(createApiKey CreateApiKey) ApiKeysAPICreateApiKeyRequest {\n\tr.createApiKey = &createApiKey\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ApiKeysAPICreateApiKeyRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ApiKeysAPICreateApiKeyRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ApiKeysAPICreateApiKeyRequest) Execute() (*ApiKeyResponse, *http.Response, error) {\n\treturn r.ApiService.CreateApiKeyExecute(r)\n}\n\n/*\nCreateApiKey Create API key\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return ApiKeysAPICreateApiKeyRequest\n*/\nfunc (a *ApiKeysAPIService) CreateApiKey(ctx context.Context) ApiKeysAPICreateApiKeyRequest {\n\treturn ApiKeysAPICreateApiKeyRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return ApiKeyResponse\nfunc (a *ApiKeysAPIService) CreateApiKeyExecute(r ApiKeysAPICreateApiKeyRequest) (*ApiKeyResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ApiKeyResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ApiKeysAPIService.CreateApiKey\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/api-keys\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createApiKey == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createApiKey is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createApiKey\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ApiKeysAPIDeleteApiKeyRequest struct {\n\tctx context.Context\n\tApiService ApiKeysAPI\n\tname string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ApiKeysAPIDeleteApiKeyRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ApiKeysAPIDeleteApiKeyRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ApiKeysAPIDeleteApiKeyRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteApiKeyExecute(r)\n}\n\n/*\nDeleteApiKey Delete API key\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param name\n @return ApiKeysAPIDeleteApiKeyRequest\n*/\nfunc (a *ApiKeysAPIService) DeleteApiKey(ctx context.Context, name string) ApiKeysAPIDeleteApiKeyRequest {\n\treturn ApiKeysAPIDeleteApiKeyRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tname: name,\n\t}\n}\n\n// Execute executes the request\nfunc (a *ApiKeysAPIService) DeleteApiKeyExecute(r ApiKeysAPIDeleteApiKeyRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ApiKeysAPIService.DeleteApiKey\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/api-keys/{name}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"name\"+\"}\", url.PathEscape(parameterValueToString(r.name, \"name\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ApiKeysAPIDeleteApiKeyForUserRequest struct {\n\tctx context.Context\n\tApiService ApiKeysAPI\n\tuserId string\n\tname string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ApiKeysAPIDeleteApiKeyForUserRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ApiKeysAPIDeleteApiKeyForUserRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ApiKeysAPIDeleteApiKeyForUserRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteApiKeyForUserExecute(r)\n}\n\n/*\nDeleteApiKeyForUser Delete API key for user\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param userId\n @param name\n @return ApiKeysAPIDeleteApiKeyForUserRequest\n*/\nfunc (a *ApiKeysAPIService) DeleteApiKeyForUser(ctx context.Context, userId string, name string) ApiKeysAPIDeleteApiKeyForUserRequest {\n\treturn ApiKeysAPIDeleteApiKeyForUserRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tuserId: userId,\n\t\tname: name,\n\t}\n}\n\n// Execute executes the request\nfunc (a *ApiKeysAPIService) DeleteApiKeyForUserExecute(r ApiKeysAPIDeleteApiKeyForUserRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ApiKeysAPIService.DeleteApiKeyForUser\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/api-keys/{userId}/{name}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"userId\"+\"}\", url.PathEscape(parameterValueToString(r.userId, \"userId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"name\"+\"}\", url.PathEscape(parameterValueToString(r.name, \"name\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ApiKeysAPIGetApiKeyRequest struct {\n\tctx context.Context\n\tApiService ApiKeysAPI\n\tname string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ApiKeysAPIGetApiKeyRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ApiKeysAPIGetApiKeyRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ApiKeysAPIGetApiKeyRequest) Execute() (*ApiKeyList, *http.Response, error) {\n\treturn r.ApiService.GetApiKeyExecute(r)\n}\n\n/*\nGetApiKey Get API key\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param name\n @return ApiKeysAPIGetApiKeyRequest\n*/\nfunc (a *ApiKeysAPIService) GetApiKey(ctx context.Context, name string) ApiKeysAPIGetApiKeyRequest {\n\treturn ApiKeysAPIGetApiKeyRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tname: name,\n\t}\n}\n\n// Execute executes the request\n//  @return ApiKeyList\nfunc (a *ApiKeysAPIService) GetApiKeyExecute(r ApiKeysAPIGetApiKeyRequest) (*ApiKeyList, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ApiKeyList\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ApiKeysAPIService.GetApiKey\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/api-keys/{name}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"name\"+\"}\", url.PathEscape(parameterValueToString(r.name, \"name\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ApiKeysAPIGetCurrentApiKeyRequest struct {\n\tctx context.Context\n\tApiService ApiKeysAPI\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ApiKeysAPIGetCurrentApiKeyRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ApiKeysAPIGetCurrentApiKeyRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ApiKeysAPIGetCurrentApiKeyRequest) Execute() (*ApiKeyList, *http.Response, error) {\n\treturn r.ApiService.GetCurrentApiKeyExecute(r)\n}\n\n/*\nGetCurrentApiKey Get current API key's details\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return ApiKeysAPIGetCurrentApiKeyRequest\n*/\nfunc (a *ApiKeysAPIService) GetCurrentApiKey(ctx context.Context) ApiKeysAPIGetCurrentApiKeyRequest {\n\treturn ApiKeysAPIGetCurrentApiKeyRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return ApiKeyList\nfunc (a *ApiKeysAPIService) GetCurrentApiKeyExecute(r ApiKeysAPIGetCurrentApiKeyRequest) (*ApiKeyList, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ApiKeyList\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ApiKeysAPIService.GetCurrentApiKey\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/api-keys/current\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ApiKeysAPIListApiKeysRequest struct {\n\tctx context.Context\n\tApiService ApiKeysAPI\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ApiKeysAPIListApiKeysRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ApiKeysAPIListApiKeysRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ApiKeysAPIListApiKeysRequest) Execute() ([]ApiKeyList, *http.Response, error) {\n\treturn r.ApiService.ListApiKeysExecute(r)\n}\n\n/*\nListApiKeys List API keys\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return ApiKeysAPIListApiKeysRequest\n*/\nfunc (a *ApiKeysAPIService) ListApiKeys(ctx context.Context) ApiKeysAPIListApiKeysRequest {\n\treturn ApiKeysAPIListApiKeysRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []ApiKeyList\nfunc (a *ApiKeysAPIService) ListApiKeysExecute(r ApiKeysAPIListApiKeysRequest) ([]ApiKeyList, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []ApiKeyList\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ApiKeysAPIService.ListApiKeys\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/api-keys\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_audit.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n)\n\n\ntype AuditAPI interface {\n\n\t/*\n\tGetAllAuditLogs Get all audit logs\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return AuditAPIGetAllAuditLogsRequest\n\t*/\n\tGetAllAuditLogs(ctx context.Context) AuditAPIGetAllAuditLogsRequest\n\n\t// GetAllAuditLogsExecute executes the request\n\t//  @return PaginatedAuditLogs\n\tGetAllAuditLogsExecute(r AuditAPIGetAllAuditLogsRequest) (*PaginatedAuditLogs, *http.Response, error)\n\n\t/*\n\tGetOrganizationAuditLogs Get audit logs for organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return AuditAPIGetOrganizationAuditLogsRequest\n\t*/\n\tGetOrganizationAuditLogs(ctx context.Context, organizationId string) AuditAPIGetOrganizationAuditLogsRequest\n\n\t// GetOrganizationAuditLogsExecute executes the request\n\t//  @return PaginatedAuditLogs\n\tGetOrganizationAuditLogsExecute(r AuditAPIGetOrganizationAuditLogsRequest) (*PaginatedAuditLogs, *http.Response, error)\n}\n\n// AuditAPIService AuditAPI service\ntype AuditAPIService service\n\ntype AuditAPIGetAllAuditLogsRequest struct {\n\tctx context.Context\n\tApiService AuditAPI\n\tpage *float32\n\tlimit *float32\n\tfrom *time.Time\n\tto *time.Time\n\tnextToken *string\n}\n\n// Page number of the results\nfunc (r AuditAPIGetAllAuditLogsRequest) Page(page float32) AuditAPIGetAllAuditLogsRequest {\n\tr.page = &page\n\treturn r\n}\n\n// Number of results per page\nfunc (r AuditAPIGetAllAuditLogsRequest) Limit(limit float32) AuditAPIGetAllAuditLogsRequest {\n\tr.limit = &limit\n\treturn r\n}\n\n// From date (ISO 8601 format)\nfunc (r AuditAPIGetAllAuditLogsRequest) From(from time.Time) AuditAPIGetAllAuditLogsRequest {\n\tr.from = &from\n\treturn r\n}\n\n// To date (ISO 8601 format)\nfunc (r AuditAPIGetAllAuditLogsRequest) To(to time.Time) AuditAPIGetAllAuditLogsRequest {\n\tr.to = &to\n\treturn r\n}\n\n// Token for cursor-based pagination. When provided, takes precedence over page parameter.\nfunc (r AuditAPIGetAllAuditLogsRequest) NextToken(nextToken string) AuditAPIGetAllAuditLogsRequest {\n\tr.nextToken = &nextToken\n\treturn r\n}\n\nfunc (r AuditAPIGetAllAuditLogsRequest) Execute() (*PaginatedAuditLogs, *http.Response, error) {\n\treturn r.ApiService.GetAllAuditLogsExecute(r)\n}\n\n/*\nGetAllAuditLogs Get all audit logs\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return AuditAPIGetAllAuditLogsRequest\n*/\nfunc (a *AuditAPIService) GetAllAuditLogs(ctx context.Context) AuditAPIGetAllAuditLogsRequest {\n\treturn AuditAPIGetAllAuditLogsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return PaginatedAuditLogs\nfunc (a *AuditAPIService) GetAllAuditLogsExecute(r AuditAPIGetAllAuditLogsRequest) (*PaginatedAuditLogs, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PaginatedAuditLogs\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"AuditAPIService.GetAllAuditLogs\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/audit\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.page != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"page\", r.page, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 1\n\t\tr.page = &defaultValue\n\t}\n\tif r.limit != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"limit\", r.limit, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 100\n\t\tr.limit = &defaultValue\n\t}\n\tif r.from != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"from\", r.from, \"form\", \"\")\n\t}\n\tif r.to != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"to\", r.to, \"form\", \"\")\n\t}\n\tif r.nextToken != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"nextToken\", r.nextToken, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype AuditAPIGetOrganizationAuditLogsRequest struct {\n\tctx context.Context\n\tApiService AuditAPI\n\torganizationId string\n\tpage *float32\n\tlimit *float32\n\tfrom *time.Time\n\tto *time.Time\n\tnextToken *string\n}\n\n// Page number of the results\nfunc (r AuditAPIGetOrganizationAuditLogsRequest) Page(page float32) AuditAPIGetOrganizationAuditLogsRequest {\n\tr.page = &page\n\treturn r\n}\n\n// Number of results per page\nfunc (r AuditAPIGetOrganizationAuditLogsRequest) Limit(limit float32) AuditAPIGetOrganizationAuditLogsRequest {\n\tr.limit = &limit\n\treturn r\n}\n\n// From date (ISO 8601 format)\nfunc (r AuditAPIGetOrganizationAuditLogsRequest) From(from time.Time) AuditAPIGetOrganizationAuditLogsRequest {\n\tr.from = &from\n\treturn r\n}\n\n// To date (ISO 8601 format)\nfunc (r AuditAPIGetOrganizationAuditLogsRequest) To(to time.Time) AuditAPIGetOrganizationAuditLogsRequest {\n\tr.to = &to\n\treturn r\n}\n\n// Token for cursor-based pagination. When provided, takes precedence over page parameter.\nfunc (r AuditAPIGetOrganizationAuditLogsRequest) NextToken(nextToken string) AuditAPIGetOrganizationAuditLogsRequest {\n\tr.nextToken = &nextToken\n\treturn r\n}\n\nfunc (r AuditAPIGetOrganizationAuditLogsRequest) Execute() (*PaginatedAuditLogs, *http.Response, error) {\n\treturn r.ApiService.GetOrganizationAuditLogsExecute(r)\n}\n\n/*\nGetOrganizationAuditLogs Get audit logs for organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return AuditAPIGetOrganizationAuditLogsRequest\n*/\nfunc (a *AuditAPIService) GetOrganizationAuditLogs(ctx context.Context, organizationId string) AuditAPIGetOrganizationAuditLogsRequest {\n\treturn AuditAPIGetOrganizationAuditLogsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return PaginatedAuditLogs\nfunc (a *AuditAPIService) GetOrganizationAuditLogsExecute(r AuditAPIGetOrganizationAuditLogsRequest) (*PaginatedAuditLogs, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PaginatedAuditLogs\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"AuditAPIService.GetOrganizationAuditLogs\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/audit/organizations/{organizationId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.page != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"page\", r.page, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 1\n\t\tr.page = &defaultValue\n\t}\n\tif r.limit != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"limit\", r.limit, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 100\n\t\tr.limit = &defaultValue\n\t}\n\tif r.from != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"from\", r.from, \"form\", \"\")\n\t}\n\tif r.to != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"to\", r.to, \"form\", \"\")\n\t}\n\tif r.nextToken != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"nextToken\", r.nextToken, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_config.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n)\n\n\ntype ConfigAPI interface {\n\n\t/*\n\tConfigControllerGetConfig Get config\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return ConfigAPIConfigControllerGetConfigRequest\n\t*/\n\tConfigControllerGetConfig(ctx context.Context) ConfigAPIConfigControllerGetConfigRequest\n\n\t// ConfigControllerGetConfigExecute executes the request\n\t//  @return DaytonaConfiguration\n\tConfigControllerGetConfigExecute(r ConfigAPIConfigControllerGetConfigRequest) (*DaytonaConfiguration, *http.Response, error)\n}\n\n// ConfigAPIService ConfigAPI service\ntype ConfigAPIService service\n\ntype ConfigAPIConfigControllerGetConfigRequest struct {\n\tctx context.Context\n\tApiService ConfigAPI\n}\n\nfunc (r ConfigAPIConfigControllerGetConfigRequest) Execute() (*DaytonaConfiguration, *http.Response, error) {\n\treturn r.ApiService.ConfigControllerGetConfigExecute(r)\n}\n\n/*\nConfigControllerGetConfig Get config\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return ConfigAPIConfigControllerGetConfigRequest\n*/\nfunc (a *ConfigAPIService) ConfigControllerGetConfig(ctx context.Context) ConfigAPIConfigControllerGetConfigRequest {\n\treturn ConfigAPIConfigControllerGetConfigRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return DaytonaConfiguration\nfunc (a *ConfigAPIService) ConfigControllerGetConfigExecute(r ConfigAPIConfigControllerGetConfigRequest) (*DaytonaConfiguration, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *DaytonaConfiguration\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ConfigAPIService.ConfigControllerGetConfig\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/config\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_docker_registry.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype DockerRegistryAPI interface {\n\n\t/*\n\tCreateRegistry Create registry\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return DockerRegistryAPICreateRegistryRequest\n\t*/\n\tCreateRegistry(ctx context.Context) DockerRegistryAPICreateRegistryRequest\n\n\t// CreateRegistryExecute executes the request\n\t//  @return DockerRegistry\n\tCreateRegistryExecute(r DockerRegistryAPICreateRegistryRequest) (*DockerRegistry, *http.Response, error)\n\n\t/*\n\tDeleteRegistry Delete registry\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id ID of the docker registry\n\t@return DockerRegistryAPIDeleteRegistryRequest\n\t*/\n\tDeleteRegistry(ctx context.Context, id string) DockerRegistryAPIDeleteRegistryRequest\n\n\t// DeleteRegistryExecute executes the request\n\tDeleteRegistryExecute(r DockerRegistryAPIDeleteRegistryRequest) (*http.Response, error)\n\n\t/*\n\tGetRegistry Get registry\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id ID of the docker registry\n\t@return DockerRegistryAPIGetRegistryRequest\n\t*/\n\tGetRegistry(ctx context.Context, id string) DockerRegistryAPIGetRegistryRequest\n\n\t// GetRegistryExecute executes the request\n\t//  @return DockerRegistry\n\tGetRegistryExecute(r DockerRegistryAPIGetRegistryRequest) (*DockerRegistry, *http.Response, error)\n\n\t/*\n\tGetTransientPushAccess Get temporary registry access for pushing snapshots\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return DockerRegistryAPIGetTransientPushAccessRequest\n\t*/\n\tGetTransientPushAccess(ctx context.Context) DockerRegistryAPIGetTransientPushAccessRequest\n\n\t// GetTransientPushAccessExecute executes the request\n\t//  @return RegistryPushAccessDto\n\tGetTransientPushAccessExecute(r DockerRegistryAPIGetTransientPushAccessRequest) (*RegistryPushAccessDto, *http.Response, error)\n\n\t/*\n\tListRegistries List registries\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return DockerRegistryAPIListRegistriesRequest\n\t*/\n\tListRegistries(ctx context.Context) DockerRegistryAPIListRegistriesRequest\n\n\t// ListRegistriesExecute executes the request\n\t//  @return []DockerRegistry\n\tListRegistriesExecute(r DockerRegistryAPIListRegistriesRequest) ([]DockerRegistry, *http.Response, error)\n\n\t/*\n\tSetDefaultRegistry Set default registry\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id ID of the docker registry\n\t@return DockerRegistryAPISetDefaultRegistryRequest\n\t*/\n\tSetDefaultRegistry(ctx context.Context, id string) DockerRegistryAPISetDefaultRegistryRequest\n\n\t// SetDefaultRegistryExecute executes the request\n\t//  @return DockerRegistry\n\tSetDefaultRegistryExecute(r DockerRegistryAPISetDefaultRegistryRequest) (*DockerRegistry, *http.Response, error)\n\n\t/*\n\tUpdateRegistry Update registry\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id ID of the docker registry\n\t@return DockerRegistryAPIUpdateRegistryRequest\n\t*/\n\tUpdateRegistry(ctx context.Context, id string) DockerRegistryAPIUpdateRegistryRequest\n\n\t// UpdateRegistryExecute executes the request\n\t//  @return DockerRegistry\n\tUpdateRegistryExecute(r DockerRegistryAPIUpdateRegistryRequest) (*DockerRegistry, *http.Response, error)\n}\n\n// DockerRegistryAPIService DockerRegistryAPI service\ntype DockerRegistryAPIService service\n\ntype DockerRegistryAPICreateRegistryRequest struct {\n\tctx context.Context\n\tApiService DockerRegistryAPI\n\tcreateDockerRegistry *CreateDockerRegistry\n\txDaytonaOrganizationID *string\n}\n\nfunc (r DockerRegistryAPICreateRegistryRequest) CreateDockerRegistry(createDockerRegistry CreateDockerRegistry) DockerRegistryAPICreateRegistryRequest {\n\tr.createDockerRegistry = &createDockerRegistry\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r DockerRegistryAPICreateRegistryRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) DockerRegistryAPICreateRegistryRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r DockerRegistryAPICreateRegistryRequest) Execute() (*DockerRegistry, *http.Response, error) {\n\treturn r.ApiService.CreateRegistryExecute(r)\n}\n\n/*\nCreateRegistry Create registry\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return DockerRegistryAPICreateRegistryRequest\n*/\nfunc (a *DockerRegistryAPIService) CreateRegistry(ctx context.Context) DockerRegistryAPICreateRegistryRequest {\n\treturn DockerRegistryAPICreateRegistryRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return DockerRegistry\nfunc (a *DockerRegistryAPIService) CreateRegistryExecute(r DockerRegistryAPICreateRegistryRequest) (*DockerRegistry, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *DockerRegistry\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"DockerRegistryAPIService.CreateRegistry\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/docker-registry\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createDockerRegistry == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createDockerRegistry is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createDockerRegistry\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype DockerRegistryAPIDeleteRegistryRequest struct {\n\tctx context.Context\n\tApiService DockerRegistryAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r DockerRegistryAPIDeleteRegistryRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) DockerRegistryAPIDeleteRegistryRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r DockerRegistryAPIDeleteRegistryRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteRegistryExecute(r)\n}\n\n/*\nDeleteRegistry Delete registry\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id ID of the docker registry\n @return DockerRegistryAPIDeleteRegistryRequest\n*/\nfunc (a *DockerRegistryAPIService) DeleteRegistry(ctx context.Context, id string) DockerRegistryAPIDeleteRegistryRequest {\n\treturn DockerRegistryAPIDeleteRegistryRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *DockerRegistryAPIService) DeleteRegistryExecute(r DockerRegistryAPIDeleteRegistryRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"DockerRegistryAPIService.DeleteRegistry\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/docker-registry/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype DockerRegistryAPIGetRegistryRequest struct {\n\tctx context.Context\n\tApiService DockerRegistryAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r DockerRegistryAPIGetRegistryRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) DockerRegistryAPIGetRegistryRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r DockerRegistryAPIGetRegistryRequest) Execute() (*DockerRegistry, *http.Response, error) {\n\treturn r.ApiService.GetRegistryExecute(r)\n}\n\n/*\nGetRegistry Get registry\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id ID of the docker registry\n @return DockerRegistryAPIGetRegistryRequest\n*/\nfunc (a *DockerRegistryAPIService) GetRegistry(ctx context.Context, id string) DockerRegistryAPIGetRegistryRequest {\n\treturn DockerRegistryAPIGetRegistryRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return DockerRegistry\nfunc (a *DockerRegistryAPIService) GetRegistryExecute(r DockerRegistryAPIGetRegistryRequest) (*DockerRegistry, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *DockerRegistry\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"DockerRegistryAPIService.GetRegistry\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/docker-registry/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype DockerRegistryAPIGetTransientPushAccessRequest struct {\n\tctx context.Context\n\tApiService DockerRegistryAPI\n\txDaytonaOrganizationID *string\n\tregionId *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r DockerRegistryAPIGetTransientPushAccessRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) DockerRegistryAPIGetTransientPushAccessRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// ID of the region where the snapshot will be available (defaults to organization default region)\nfunc (r DockerRegistryAPIGetTransientPushAccessRequest) RegionId(regionId string) DockerRegistryAPIGetTransientPushAccessRequest {\n\tr.regionId = &regionId\n\treturn r\n}\n\nfunc (r DockerRegistryAPIGetTransientPushAccessRequest) Execute() (*RegistryPushAccessDto, *http.Response, error) {\n\treturn r.ApiService.GetTransientPushAccessExecute(r)\n}\n\n/*\nGetTransientPushAccess Get temporary registry access for pushing snapshots\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return DockerRegistryAPIGetTransientPushAccessRequest\n*/\nfunc (a *DockerRegistryAPIService) GetTransientPushAccess(ctx context.Context) DockerRegistryAPIGetTransientPushAccessRequest {\n\treturn DockerRegistryAPIGetTransientPushAccessRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return RegistryPushAccessDto\nfunc (a *DockerRegistryAPIService) GetTransientPushAccessExecute(r DockerRegistryAPIGetTransientPushAccessRequest) (*RegistryPushAccessDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RegistryPushAccessDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"DockerRegistryAPIService.GetTransientPushAccess\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/docker-registry/registry-push-access\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.regionId != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"regionId\", r.regionId, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype DockerRegistryAPIListRegistriesRequest struct {\n\tctx context.Context\n\tApiService DockerRegistryAPI\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r DockerRegistryAPIListRegistriesRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) DockerRegistryAPIListRegistriesRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r DockerRegistryAPIListRegistriesRequest) Execute() ([]DockerRegistry, *http.Response, error) {\n\treturn r.ApiService.ListRegistriesExecute(r)\n}\n\n/*\nListRegistries List registries\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return DockerRegistryAPIListRegistriesRequest\n*/\nfunc (a *DockerRegistryAPIService) ListRegistries(ctx context.Context) DockerRegistryAPIListRegistriesRequest {\n\treturn DockerRegistryAPIListRegistriesRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []DockerRegistry\nfunc (a *DockerRegistryAPIService) ListRegistriesExecute(r DockerRegistryAPIListRegistriesRequest) ([]DockerRegistry, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []DockerRegistry\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"DockerRegistryAPIService.ListRegistries\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/docker-registry\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype DockerRegistryAPISetDefaultRegistryRequest struct {\n\tctx context.Context\n\tApiService DockerRegistryAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r DockerRegistryAPISetDefaultRegistryRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) DockerRegistryAPISetDefaultRegistryRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r DockerRegistryAPISetDefaultRegistryRequest) Execute() (*DockerRegistry, *http.Response, error) {\n\treturn r.ApiService.SetDefaultRegistryExecute(r)\n}\n\n/*\nSetDefaultRegistry Set default registry\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id ID of the docker registry\n @return DockerRegistryAPISetDefaultRegistryRequest\n*/\nfunc (a *DockerRegistryAPIService) SetDefaultRegistry(ctx context.Context, id string) DockerRegistryAPISetDefaultRegistryRequest {\n\treturn DockerRegistryAPISetDefaultRegistryRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return DockerRegistry\nfunc (a *DockerRegistryAPIService) SetDefaultRegistryExecute(r DockerRegistryAPISetDefaultRegistryRequest) (*DockerRegistry, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *DockerRegistry\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"DockerRegistryAPIService.SetDefaultRegistry\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/docker-registry/{id}/set-default\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype DockerRegistryAPIUpdateRegistryRequest struct {\n\tctx context.Context\n\tApiService DockerRegistryAPI\n\tid string\n\tupdateDockerRegistry *UpdateDockerRegistry\n\txDaytonaOrganizationID *string\n}\n\nfunc (r DockerRegistryAPIUpdateRegistryRequest) UpdateDockerRegistry(updateDockerRegistry UpdateDockerRegistry) DockerRegistryAPIUpdateRegistryRequest {\n\tr.updateDockerRegistry = &updateDockerRegistry\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r DockerRegistryAPIUpdateRegistryRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) DockerRegistryAPIUpdateRegistryRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r DockerRegistryAPIUpdateRegistryRequest) Execute() (*DockerRegistry, *http.Response, error) {\n\treturn r.ApiService.UpdateRegistryExecute(r)\n}\n\n/*\nUpdateRegistry Update registry\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id ID of the docker registry\n @return DockerRegistryAPIUpdateRegistryRequest\n*/\nfunc (a *DockerRegistryAPIService) UpdateRegistry(ctx context.Context, id string) DockerRegistryAPIUpdateRegistryRequest {\n\treturn DockerRegistryAPIUpdateRegistryRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return DockerRegistry\nfunc (a *DockerRegistryAPIService) UpdateRegistryExecute(r DockerRegistryAPIUpdateRegistryRequest) (*DockerRegistry, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *DockerRegistry\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"DockerRegistryAPIService.UpdateRegistry\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/docker-registry/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateDockerRegistry == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"updateDockerRegistry is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateDockerRegistry\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_health.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n)\n\n\ntype HealthAPI interface {\n\n\t/*\n\tHealthControllerCheck Method for HealthControllerCheck\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return HealthAPIHealthControllerCheckRequest\n\t*/\n\tHealthControllerCheck(ctx context.Context) HealthAPIHealthControllerCheckRequest\n\n\t// HealthControllerCheckExecute executes the request\n\t//  @return HealthControllerCheck200Response\n\tHealthControllerCheckExecute(r HealthAPIHealthControllerCheckRequest) (*HealthControllerCheck200Response, *http.Response, error)\n\n\t/*\n\tHealthControllerLive Method for HealthControllerLive\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return HealthAPIHealthControllerLiveRequest\n\t*/\n\tHealthControllerLive(ctx context.Context) HealthAPIHealthControllerLiveRequest\n\n\t// HealthControllerLiveExecute executes the request\n\tHealthControllerLiveExecute(r HealthAPIHealthControllerLiveRequest) (*http.Response, error)\n}\n\n// HealthAPIService HealthAPI service\ntype HealthAPIService service\n\ntype HealthAPIHealthControllerCheckRequest struct {\n\tctx context.Context\n\tApiService HealthAPI\n}\n\nfunc (r HealthAPIHealthControllerCheckRequest) Execute() (*HealthControllerCheck200Response, *http.Response, error) {\n\treturn r.ApiService.HealthControllerCheckExecute(r)\n}\n\n/*\nHealthControllerCheck Method for HealthControllerCheck\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return HealthAPIHealthControllerCheckRequest\n*/\nfunc (a *HealthAPIService) HealthControllerCheck(ctx context.Context) HealthAPIHealthControllerCheckRequest {\n\treturn HealthAPIHealthControllerCheckRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return HealthControllerCheck200Response\nfunc (a *HealthAPIService) HealthControllerCheckExecute(r HealthAPIHealthControllerCheckRequest) (*HealthControllerCheck200Response, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *HealthControllerCheck200Response\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"HealthAPIService.HealthControllerCheck\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/health/ready\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\tif localVarHTTPResponse.StatusCode == 503 {\n\t\t\tvar v HealthControllerCheck503Response\n\t\t\terr = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\t\t\tif err != nil {\n\t\t\t\tnewErr.error = err.Error()\n\t\t\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t\t\t}\n\t\t\t\t\tnewErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)\n\t\t\t\t\tnewErr.model = v\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype HealthAPIHealthControllerLiveRequest struct {\n\tctx context.Context\n\tApiService HealthAPI\n}\n\nfunc (r HealthAPIHealthControllerLiveRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.HealthControllerLiveExecute(r)\n}\n\n/*\nHealthControllerLive Method for HealthControllerLive\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return HealthAPIHealthControllerLiveRequest\n*/\nfunc (a *HealthAPIService) HealthControllerLive(ctx context.Context) HealthAPIHealthControllerLiveRequest {\n\treturn HealthAPIHealthControllerLiveRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\nfunc (a *HealthAPIService) HealthControllerLiveExecute(r HealthAPIHealthControllerLiveRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"HealthAPIService.HealthControllerLive\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/health\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_jobs.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype JobsAPI interface {\n\n\t/*\n\tGetJob Get job details\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param jobId ID of the job\n\t@return JobsAPIGetJobRequest\n\t*/\n\tGetJob(ctx context.Context, jobId string) JobsAPIGetJobRequest\n\n\t// GetJobExecute executes the request\n\t//  @return Job\n\tGetJobExecute(r JobsAPIGetJobRequest) (*Job, *http.Response, error)\n\n\t/*\n\tListJobs List jobs for the runner\n\n\tReturns a paginated list of jobs for the runner, optionally filtered by status.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return JobsAPIListJobsRequest\n\t*/\n\tListJobs(ctx context.Context) JobsAPIListJobsRequest\n\n\t// ListJobsExecute executes the request\n\t//  @return PaginatedJobs\n\tListJobsExecute(r JobsAPIListJobsRequest) (*PaginatedJobs, *http.Response, error)\n\n\t/*\n\tPollJobs Long poll for jobs\n\n\tLong poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return JobsAPIPollJobsRequest\n\t*/\n\tPollJobs(ctx context.Context) JobsAPIPollJobsRequest\n\n\t// PollJobsExecute executes the request\n\t//  @return PollJobsResponse\n\tPollJobsExecute(r JobsAPIPollJobsRequest) (*PollJobsResponse, *http.Response, error)\n\n\t/*\n\tUpdateJobStatus Update job status\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param jobId ID of the job\n\t@return JobsAPIUpdateJobStatusRequest\n\t*/\n\tUpdateJobStatus(ctx context.Context, jobId string) JobsAPIUpdateJobStatusRequest\n\n\t// UpdateJobStatusExecute executes the request\n\t//  @return Job\n\tUpdateJobStatusExecute(r JobsAPIUpdateJobStatusRequest) (*Job, *http.Response, error)\n}\n\n// JobsAPIService JobsAPI service\ntype JobsAPIService service\n\ntype JobsAPIGetJobRequest struct {\n\tctx context.Context\n\tApiService JobsAPI\n\tjobId string\n}\n\nfunc (r JobsAPIGetJobRequest) Execute() (*Job, *http.Response, error) {\n\treturn r.ApiService.GetJobExecute(r)\n}\n\n/*\nGetJob Get job details\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param jobId ID of the job\n @return JobsAPIGetJobRequest\n*/\nfunc (a *JobsAPIService) GetJob(ctx context.Context, jobId string) JobsAPIGetJobRequest {\n\treturn JobsAPIGetJobRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tjobId: jobId,\n\t}\n}\n\n// Execute executes the request\n//  @return Job\nfunc (a *JobsAPIService) GetJobExecute(r JobsAPIGetJobRequest) (*Job, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Job\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"JobsAPIService.GetJob\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/jobs/{jobId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"jobId\"+\"}\", url.PathEscape(parameterValueToString(r.jobId, \"jobId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype JobsAPIListJobsRequest struct {\n\tctx context.Context\n\tApiService JobsAPI\n\tpage *float32\n\tlimit *float32\n\tstatus *JobStatus\n\toffset *float32\n}\n\n// Page number of the results\nfunc (r JobsAPIListJobsRequest) Page(page float32) JobsAPIListJobsRequest {\n\tr.page = &page\n\treturn r\n}\n\n// Maximum number of jobs to return (default: 100, max: 500)\nfunc (r JobsAPIListJobsRequest) Limit(limit float32) JobsAPIListJobsRequest {\n\tr.limit = &limit\n\treturn r\n}\n\n// Filter jobs by status\nfunc (r JobsAPIListJobsRequest) Status(status JobStatus) JobsAPIListJobsRequest {\n\tr.status = &status\n\treturn r\n}\n\n// Number of jobs to skip for pagination (default: 0)\nfunc (r JobsAPIListJobsRequest) Offset(offset float32) JobsAPIListJobsRequest {\n\tr.offset = &offset\n\treturn r\n}\n\nfunc (r JobsAPIListJobsRequest) Execute() (*PaginatedJobs, *http.Response, error) {\n\treturn r.ApiService.ListJobsExecute(r)\n}\n\n/*\nListJobs List jobs for the runner\n\nReturns a paginated list of jobs for the runner, optionally filtered by status.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return JobsAPIListJobsRequest\n*/\nfunc (a *JobsAPIService) ListJobs(ctx context.Context) JobsAPIListJobsRequest {\n\treturn JobsAPIListJobsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return PaginatedJobs\nfunc (a *JobsAPIService) ListJobsExecute(r JobsAPIListJobsRequest) (*PaginatedJobs, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PaginatedJobs\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"JobsAPIService.ListJobs\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/jobs\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.page != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"page\", r.page, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 1\n\t\tr.page = &defaultValue\n\t}\n\tif r.limit != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"limit\", r.limit, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 100\n\t\tr.limit = &defaultValue\n\t}\n\tif r.status != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"status\", r.status, \"form\", \"\")\n\t}\n\tif r.offset != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"offset\", r.offset, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype JobsAPIPollJobsRequest struct {\n\tctx context.Context\n\tApiService JobsAPI\n\ttimeout *float32\n\tlimit *float32\n}\n\n// Timeout in seconds for long polling (default: 30, max: 60)\nfunc (r JobsAPIPollJobsRequest) Timeout(timeout float32) JobsAPIPollJobsRequest {\n\tr.timeout = &timeout\n\treturn r\n}\n\n// Maximum number of jobs to return (default: 10, max: 100)\nfunc (r JobsAPIPollJobsRequest) Limit(limit float32) JobsAPIPollJobsRequest {\n\tr.limit = &limit\n\treturn r\n}\n\nfunc (r JobsAPIPollJobsRequest) Execute() (*PollJobsResponse, *http.Response, error) {\n\treturn r.ApiService.PollJobsExecute(r)\n}\n\n/*\nPollJobs Long poll for jobs\n\nLong poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return JobsAPIPollJobsRequest\n*/\nfunc (a *JobsAPIService) PollJobs(ctx context.Context) JobsAPIPollJobsRequest {\n\treturn JobsAPIPollJobsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return PollJobsResponse\nfunc (a *JobsAPIService) PollJobsExecute(r JobsAPIPollJobsRequest) (*PollJobsResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PollJobsResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"JobsAPIService.PollJobs\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/jobs/poll\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.timeout != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"timeout\", r.timeout, \"form\", \"\")\n\t}\n\tif r.limit != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"limit\", r.limit, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype JobsAPIUpdateJobStatusRequest struct {\n\tctx context.Context\n\tApiService JobsAPI\n\tjobId string\n\tupdateJobStatus *UpdateJobStatus\n}\n\nfunc (r JobsAPIUpdateJobStatusRequest) UpdateJobStatus(updateJobStatus UpdateJobStatus) JobsAPIUpdateJobStatusRequest {\n\tr.updateJobStatus = &updateJobStatus\n\treturn r\n}\n\nfunc (r JobsAPIUpdateJobStatusRequest) Execute() (*Job, *http.Response, error) {\n\treturn r.ApiService.UpdateJobStatusExecute(r)\n}\n\n/*\nUpdateJobStatus Update job status\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param jobId ID of the job\n @return JobsAPIUpdateJobStatusRequest\n*/\nfunc (a *JobsAPIService) UpdateJobStatus(ctx context.Context, jobId string) JobsAPIUpdateJobStatusRequest {\n\treturn JobsAPIUpdateJobStatusRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tjobId: jobId,\n\t}\n}\n\n// Execute executes the request\n//  @return Job\nfunc (a *JobsAPIService) UpdateJobStatusExecute(r JobsAPIUpdateJobStatusRequest) (*Job, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Job\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"JobsAPIService.UpdateJobStatus\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/jobs/{jobId}/status\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"jobId\"+\"}\", url.PathEscape(parameterValueToString(r.jobId, \"jobId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateJobStatus == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"updateJobStatus is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateJobStatus\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_object_storage.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n)\n\n\ntype ObjectStorageAPI interface {\n\n\t/*\n\tGetPushAccess Get temporary storage access for pushing objects\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return ObjectStorageAPIGetPushAccessRequest\n\t*/\n\tGetPushAccess(ctx context.Context) ObjectStorageAPIGetPushAccessRequest\n\n\t// GetPushAccessExecute executes the request\n\t//  @return StorageAccessDto\n\tGetPushAccessExecute(r ObjectStorageAPIGetPushAccessRequest) (*StorageAccessDto, *http.Response, error)\n}\n\n// ObjectStorageAPIService ObjectStorageAPI service\ntype ObjectStorageAPIService service\n\ntype ObjectStorageAPIGetPushAccessRequest struct {\n\tctx context.Context\n\tApiService ObjectStorageAPI\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ObjectStorageAPIGetPushAccessRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ObjectStorageAPIGetPushAccessRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ObjectStorageAPIGetPushAccessRequest) Execute() (*StorageAccessDto, *http.Response, error) {\n\treturn r.ApiService.GetPushAccessExecute(r)\n}\n\n/*\nGetPushAccess Get temporary storage access for pushing objects\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return ObjectStorageAPIGetPushAccessRequest\n*/\nfunc (a *ObjectStorageAPIService) GetPushAccess(ctx context.Context) ObjectStorageAPIGetPushAccessRequest {\n\treturn ObjectStorageAPIGetPushAccessRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return StorageAccessDto\nfunc (a *ObjectStorageAPIService) GetPushAccessExecute(r ObjectStorageAPIGetPushAccessRequest) (*StorageAccessDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *StorageAccessDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ObjectStorageAPIService.GetPushAccess\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/object-storage/push-access\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_organizations.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype OrganizationsAPI interface {\n\n\t/*\n\tAcceptOrganizationInvitation Accept organization invitation\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param invitationId Invitation ID\n\t@return OrganizationsAPIAcceptOrganizationInvitationRequest\n\t*/\n\tAcceptOrganizationInvitation(ctx context.Context, invitationId string) OrganizationsAPIAcceptOrganizationInvitationRequest\n\n\t// AcceptOrganizationInvitationExecute executes the request\n\t//  @return OrganizationInvitation\n\tAcceptOrganizationInvitationExecute(r OrganizationsAPIAcceptOrganizationInvitationRequest) (*OrganizationInvitation, *http.Response, error)\n\n\t/*\n\tCancelOrganizationInvitation Cancel organization invitation\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@param invitationId Invitation ID\n\t@return OrganizationsAPICancelOrganizationInvitationRequest\n\t*/\n\tCancelOrganizationInvitation(ctx context.Context, organizationId string, invitationId string) OrganizationsAPICancelOrganizationInvitationRequest\n\n\t// CancelOrganizationInvitationExecute executes the request\n\tCancelOrganizationInvitationExecute(r OrganizationsAPICancelOrganizationInvitationRequest) (*http.Response, error)\n\n\t/*\n\tCreateOrganization Create organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return OrganizationsAPICreateOrganizationRequest\n\t*/\n\tCreateOrganization(ctx context.Context) OrganizationsAPICreateOrganizationRequest\n\n\t// CreateOrganizationExecute executes the request\n\t//  @return Organization\n\tCreateOrganizationExecute(r OrganizationsAPICreateOrganizationRequest) (*Organization, *http.Response, error)\n\n\t/*\n\tCreateOrganizationInvitation Create organization invitation\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPICreateOrganizationInvitationRequest\n\t*/\n\tCreateOrganizationInvitation(ctx context.Context, organizationId string) OrganizationsAPICreateOrganizationInvitationRequest\n\n\t// CreateOrganizationInvitationExecute executes the request\n\t//  @return OrganizationInvitation\n\tCreateOrganizationInvitationExecute(r OrganizationsAPICreateOrganizationInvitationRequest) (*OrganizationInvitation, *http.Response, error)\n\n\t/*\n\tCreateOrganizationRole Create organization role\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPICreateOrganizationRoleRequest\n\t*/\n\tCreateOrganizationRole(ctx context.Context, organizationId string) OrganizationsAPICreateOrganizationRoleRequest\n\n\t// CreateOrganizationRoleExecute executes the request\n\t//  @return OrganizationRole\n\tCreateOrganizationRoleExecute(r OrganizationsAPICreateOrganizationRoleRequest) (*OrganizationRole, *http.Response, error)\n\n\t/*\n\tCreateRegion Create a new region\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return OrganizationsAPICreateRegionRequest\n\t*/\n\tCreateRegion(ctx context.Context) OrganizationsAPICreateRegionRequest\n\n\t// CreateRegionExecute executes the request\n\t//  @return CreateRegionResponse\n\tCreateRegionExecute(r OrganizationsAPICreateRegionRequest) (*CreateRegionResponse, *http.Response, error)\n\n\t/*\n\tDeclineOrganizationInvitation Decline organization invitation\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param invitationId Invitation ID\n\t@return OrganizationsAPIDeclineOrganizationInvitationRequest\n\t*/\n\tDeclineOrganizationInvitation(ctx context.Context, invitationId string) OrganizationsAPIDeclineOrganizationInvitationRequest\n\n\t// DeclineOrganizationInvitationExecute executes the request\n\tDeclineOrganizationInvitationExecute(r OrganizationsAPIDeclineOrganizationInvitationRequest) (*http.Response, error)\n\n\t/*\n\tDeleteOrganization Delete organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIDeleteOrganizationRequest\n\t*/\n\tDeleteOrganization(ctx context.Context, organizationId string) OrganizationsAPIDeleteOrganizationRequest\n\n\t// DeleteOrganizationExecute executes the request\n\tDeleteOrganizationExecute(r OrganizationsAPIDeleteOrganizationRequest) (*http.Response, error)\n\n\t/*\n\tDeleteOrganizationMember Delete organization member\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@param userId User ID\n\t@return OrganizationsAPIDeleteOrganizationMemberRequest\n\t*/\n\tDeleteOrganizationMember(ctx context.Context, organizationId string, userId string) OrganizationsAPIDeleteOrganizationMemberRequest\n\n\t// DeleteOrganizationMemberExecute executes the request\n\tDeleteOrganizationMemberExecute(r OrganizationsAPIDeleteOrganizationMemberRequest) (*http.Response, error)\n\n\t/*\n\tDeleteOrganizationRole Delete organization role\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@param roleId Role ID\n\t@return OrganizationsAPIDeleteOrganizationRoleRequest\n\t*/\n\tDeleteOrganizationRole(ctx context.Context, organizationId string, roleId string) OrganizationsAPIDeleteOrganizationRoleRequest\n\n\t// DeleteOrganizationRoleExecute executes the request\n\tDeleteOrganizationRoleExecute(r OrganizationsAPIDeleteOrganizationRoleRequest) (*http.Response, error)\n\n\t/*\n\tDeleteRegion Delete a region\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Region ID\n\t@return OrganizationsAPIDeleteRegionRequest\n\t*/\n\tDeleteRegion(ctx context.Context, id string) OrganizationsAPIDeleteRegionRequest\n\n\t// DeleteRegionExecute executes the request\n\tDeleteRegionExecute(r OrganizationsAPIDeleteRegionRequest) (*http.Response, error)\n\n\t/*\n\tGetOrganization Get organization by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIGetOrganizationRequest\n\t*/\n\tGetOrganization(ctx context.Context, organizationId string) OrganizationsAPIGetOrganizationRequest\n\n\t// GetOrganizationExecute executes the request\n\t//  @return Organization\n\tGetOrganizationExecute(r OrganizationsAPIGetOrganizationRequest) (*Organization, *http.Response, error)\n\n\t/*\n\tGetOrganizationBySandboxId Get organization by sandbox ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId Sandbox ID\n\t@return OrganizationsAPIGetOrganizationBySandboxIdRequest\n\t*/\n\tGetOrganizationBySandboxId(ctx context.Context, sandboxId string) OrganizationsAPIGetOrganizationBySandboxIdRequest\n\n\t// GetOrganizationBySandboxIdExecute executes the request\n\t//  @return Organization\n\tGetOrganizationBySandboxIdExecute(r OrganizationsAPIGetOrganizationBySandboxIdRequest) (*Organization, *http.Response, error)\n\n\t/*\n\tGetOrganizationInvitationsCountForAuthenticatedUser Get count of organization invitations for authenticated user\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest\n\t*/\n\tGetOrganizationInvitationsCountForAuthenticatedUser(ctx context.Context) OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest\n\n\t// GetOrganizationInvitationsCountForAuthenticatedUserExecute executes the request\n\t//  @return float32\n\tGetOrganizationInvitationsCountForAuthenticatedUserExecute(r OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest) (float32, *http.Response, error)\n\n\t/*\n\tGetOrganizationOtelConfigBySandboxAuthToken Get organization OTEL config by sandbox auth token\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param authToken Sandbox Auth Token\n\t@return OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest\n\t*/\n\tGetOrganizationOtelConfigBySandboxAuthToken(ctx context.Context, authToken string) OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest\n\n\t// GetOrganizationOtelConfigBySandboxAuthTokenExecute executes the request\n\t//  @return OtelConfig\n\tGetOrganizationOtelConfigBySandboxAuthTokenExecute(r OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest) (*OtelConfig, *http.Response, error)\n\n\t/*\n\tGetOrganizationUsageOverview Get organization current usage overview\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIGetOrganizationUsageOverviewRequest\n\t*/\n\tGetOrganizationUsageOverview(ctx context.Context, organizationId string) OrganizationsAPIGetOrganizationUsageOverviewRequest\n\n\t// GetOrganizationUsageOverviewExecute executes the request\n\t//  @return OrganizationUsageOverview\n\tGetOrganizationUsageOverviewExecute(r OrganizationsAPIGetOrganizationUsageOverviewRequest) (*OrganizationUsageOverview, *http.Response, error)\n\n\t/*\n\tGetRegionById Get region by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Region ID\n\t@return OrganizationsAPIGetRegionByIdRequest\n\t*/\n\tGetRegionById(ctx context.Context, id string) OrganizationsAPIGetRegionByIdRequest\n\n\t// GetRegionByIdExecute executes the request\n\t//  @return Region\n\tGetRegionByIdExecute(r OrganizationsAPIGetRegionByIdRequest) (*Region, *http.Response, error)\n\n\t/*\n\tGetRegionQuotaBySandboxId Get region quota by sandbox ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId Sandbox ID\n\t@return OrganizationsAPIGetRegionQuotaBySandboxIdRequest\n\t*/\n\tGetRegionQuotaBySandboxId(ctx context.Context, sandboxId string) OrganizationsAPIGetRegionQuotaBySandboxIdRequest\n\n\t// GetRegionQuotaBySandboxIdExecute executes the request\n\t//  @return RegionQuota\n\tGetRegionQuotaBySandboxIdExecute(r OrganizationsAPIGetRegionQuotaBySandboxIdRequest) (*RegionQuota, *http.Response, error)\n\n\t/*\n\tLeaveOrganization Leave organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPILeaveOrganizationRequest\n\t*/\n\tLeaveOrganization(ctx context.Context, organizationId string) OrganizationsAPILeaveOrganizationRequest\n\n\t// LeaveOrganizationExecute executes the request\n\tLeaveOrganizationExecute(r OrganizationsAPILeaveOrganizationRequest) (*http.Response, error)\n\n\t/*\n\tListAvailableRegions List all available regions for the organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return OrganizationsAPIListAvailableRegionsRequest\n\t*/\n\tListAvailableRegions(ctx context.Context) OrganizationsAPIListAvailableRegionsRequest\n\n\t// ListAvailableRegionsExecute executes the request\n\t//  @return []Region\n\tListAvailableRegionsExecute(r OrganizationsAPIListAvailableRegionsRequest) ([]Region, *http.Response, error)\n\n\t/*\n\tListOrganizationInvitations List pending organization invitations\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIListOrganizationInvitationsRequest\n\t*/\n\tListOrganizationInvitations(ctx context.Context, organizationId string) OrganizationsAPIListOrganizationInvitationsRequest\n\n\t// ListOrganizationInvitationsExecute executes the request\n\t//  @return []OrganizationInvitation\n\tListOrganizationInvitationsExecute(r OrganizationsAPIListOrganizationInvitationsRequest) ([]OrganizationInvitation, *http.Response, error)\n\n\t/*\n\tListOrganizationInvitationsForAuthenticatedUser List organization invitations for authenticated user\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest\n\t*/\n\tListOrganizationInvitationsForAuthenticatedUser(ctx context.Context) OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest\n\n\t// ListOrganizationInvitationsForAuthenticatedUserExecute executes the request\n\t//  @return []OrganizationInvitation\n\tListOrganizationInvitationsForAuthenticatedUserExecute(r OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest) ([]OrganizationInvitation, *http.Response, error)\n\n\t/*\n\tListOrganizationMembers List organization members\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIListOrganizationMembersRequest\n\t*/\n\tListOrganizationMembers(ctx context.Context, organizationId string) OrganizationsAPIListOrganizationMembersRequest\n\n\t// ListOrganizationMembersExecute executes the request\n\t//  @return []OrganizationUser\n\tListOrganizationMembersExecute(r OrganizationsAPIListOrganizationMembersRequest) ([]OrganizationUser, *http.Response, error)\n\n\t/*\n\tListOrganizationRoles List organization roles\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIListOrganizationRolesRequest\n\t*/\n\tListOrganizationRoles(ctx context.Context, organizationId string) OrganizationsAPIListOrganizationRolesRequest\n\n\t// ListOrganizationRolesExecute executes the request\n\t//  @return []OrganizationRole\n\tListOrganizationRolesExecute(r OrganizationsAPIListOrganizationRolesRequest) ([]OrganizationRole, *http.Response, error)\n\n\t/*\n\tListOrganizations List organizations\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return OrganizationsAPIListOrganizationsRequest\n\t*/\n\tListOrganizations(ctx context.Context) OrganizationsAPIListOrganizationsRequest\n\n\t// ListOrganizationsExecute executes the request\n\t//  @return []Organization\n\tListOrganizationsExecute(r OrganizationsAPIListOrganizationsRequest) ([]Organization, *http.Response, error)\n\n\t/*\n\tRegenerateProxyApiKey Regenerate proxy API key for a region\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Region ID\n\t@return OrganizationsAPIRegenerateProxyApiKeyRequest\n\t*/\n\tRegenerateProxyApiKey(ctx context.Context, id string) OrganizationsAPIRegenerateProxyApiKeyRequest\n\n\t// RegenerateProxyApiKeyExecute executes the request\n\t//  @return RegenerateApiKeyResponse\n\tRegenerateProxyApiKeyExecute(r OrganizationsAPIRegenerateProxyApiKeyRequest) (*RegenerateApiKeyResponse, *http.Response, error)\n\n\t/*\n\tRegenerateSnapshotManagerCredentials Regenerate snapshot manager credentials for a region\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Region ID\n\t@return OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest\n\t*/\n\tRegenerateSnapshotManagerCredentials(ctx context.Context, id string) OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest\n\n\t// RegenerateSnapshotManagerCredentialsExecute executes the request\n\t//  @return SnapshotManagerCredentials\n\tRegenerateSnapshotManagerCredentialsExecute(r OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest) (*SnapshotManagerCredentials, *http.Response, error)\n\n\t/*\n\tRegenerateSshGatewayApiKey Regenerate SSH gateway API key for a region\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Region ID\n\t@return OrganizationsAPIRegenerateSshGatewayApiKeyRequest\n\t*/\n\tRegenerateSshGatewayApiKey(ctx context.Context, id string) OrganizationsAPIRegenerateSshGatewayApiKeyRequest\n\n\t// RegenerateSshGatewayApiKeyExecute executes the request\n\t//  @return RegenerateApiKeyResponse\n\tRegenerateSshGatewayApiKeyExecute(r OrganizationsAPIRegenerateSshGatewayApiKeyRequest) (*RegenerateApiKeyResponse, *http.Response, error)\n\n\t/*\n\tSetOrganizationDefaultRegion Set default region for organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPISetOrganizationDefaultRegionRequest\n\t*/\n\tSetOrganizationDefaultRegion(ctx context.Context, organizationId string) OrganizationsAPISetOrganizationDefaultRegionRequest\n\n\t// SetOrganizationDefaultRegionExecute executes the request\n\tSetOrganizationDefaultRegionExecute(r OrganizationsAPISetOrganizationDefaultRegionRequest) (*http.Response, error)\n\n\t/*\n\tSuspendOrganization Suspend organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPISuspendOrganizationRequest\n\t*/\n\tSuspendOrganization(ctx context.Context, organizationId string) OrganizationsAPISuspendOrganizationRequest\n\n\t// SuspendOrganizationExecute executes the request\n\tSuspendOrganizationExecute(r OrganizationsAPISuspendOrganizationRequest) (*http.Response, error)\n\n\t/*\n\tUnsuspendOrganization Unsuspend organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIUnsuspendOrganizationRequest\n\t*/\n\tUnsuspendOrganization(ctx context.Context, organizationId string) OrganizationsAPIUnsuspendOrganizationRequest\n\n\t// UnsuspendOrganizationExecute executes the request\n\tUnsuspendOrganizationExecute(r OrganizationsAPIUnsuspendOrganizationRequest) (*http.Response, error)\n\n\t/*\n\tUpdateAccessForOrganizationMember Update access for organization member\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@param userId User ID\n\t@return OrganizationsAPIUpdateAccessForOrganizationMemberRequest\n\t*/\n\tUpdateAccessForOrganizationMember(ctx context.Context, organizationId string, userId string) OrganizationsAPIUpdateAccessForOrganizationMemberRequest\n\n\t// UpdateAccessForOrganizationMemberExecute executes the request\n\t//  @return OrganizationUser\n\tUpdateAccessForOrganizationMemberExecute(r OrganizationsAPIUpdateAccessForOrganizationMemberRequest) (*OrganizationUser, *http.Response, error)\n\n\t/*\n\tUpdateExperimentalConfig Update experimental configuration\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIUpdateExperimentalConfigRequest\n\t*/\n\tUpdateExperimentalConfig(ctx context.Context, organizationId string) OrganizationsAPIUpdateExperimentalConfigRequest\n\n\t// UpdateExperimentalConfigExecute executes the request\n\tUpdateExperimentalConfigExecute(r OrganizationsAPIUpdateExperimentalConfigRequest) (*http.Response, error)\n\n\t/*\n\tUpdateOrganizationInvitation Update organization invitation\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@param invitationId Invitation ID\n\t@return OrganizationsAPIUpdateOrganizationInvitationRequest\n\t*/\n\tUpdateOrganizationInvitation(ctx context.Context, organizationId string, invitationId string) OrganizationsAPIUpdateOrganizationInvitationRequest\n\n\t// UpdateOrganizationInvitationExecute executes the request\n\t//  @return OrganizationInvitation\n\tUpdateOrganizationInvitationExecute(r OrganizationsAPIUpdateOrganizationInvitationRequest) (*OrganizationInvitation, *http.Response, error)\n\n\t/*\n\tUpdateOrganizationQuota Update organization quota\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIUpdateOrganizationQuotaRequest\n\t*/\n\tUpdateOrganizationQuota(ctx context.Context, organizationId string) OrganizationsAPIUpdateOrganizationQuotaRequest\n\n\t// UpdateOrganizationQuotaExecute executes the request\n\tUpdateOrganizationQuotaExecute(r OrganizationsAPIUpdateOrganizationQuotaRequest) (*http.Response, error)\n\n\t/*\n\tUpdateOrganizationRegionQuota Update organization region quota\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@param regionId ID of the region where the updated quota will be applied\n\t@return OrganizationsAPIUpdateOrganizationRegionQuotaRequest\n\t*/\n\tUpdateOrganizationRegionQuota(ctx context.Context, organizationId string, regionId string) OrganizationsAPIUpdateOrganizationRegionQuotaRequest\n\n\t// UpdateOrganizationRegionQuotaExecute executes the request\n\tUpdateOrganizationRegionQuotaExecute(r OrganizationsAPIUpdateOrganizationRegionQuotaRequest) (*http.Response, error)\n\n\t/*\n\tUpdateOrganizationRole Update organization role\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@param roleId Role ID\n\t@return OrganizationsAPIUpdateOrganizationRoleRequest\n\t*/\n\tUpdateOrganizationRole(ctx context.Context, organizationId string, roleId string) OrganizationsAPIUpdateOrganizationRoleRequest\n\n\t// UpdateOrganizationRoleExecute executes the request\n\t//  @return OrganizationRole\n\tUpdateOrganizationRoleExecute(r OrganizationsAPIUpdateOrganizationRoleRequest) (*OrganizationRole, *http.Response, error)\n\n\t/*\n\tUpdateRegion Update region configuration\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Region ID\n\t@return OrganizationsAPIUpdateRegionRequest\n\t*/\n\tUpdateRegion(ctx context.Context, id string) OrganizationsAPIUpdateRegionRequest\n\n\t// UpdateRegionExecute executes the request\n\tUpdateRegionExecute(r OrganizationsAPIUpdateRegionRequest) (*http.Response, error)\n\n\t/*\n\tUpdateSandboxDefaultLimitedNetworkEgress Update sandbox default limited network egress\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId Organization ID\n\t@return OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest\n\t*/\n\tUpdateSandboxDefaultLimitedNetworkEgress(ctx context.Context, organizationId string) OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest\n\n\t// UpdateSandboxDefaultLimitedNetworkEgressExecute executes the request\n\tUpdateSandboxDefaultLimitedNetworkEgressExecute(r OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest) (*http.Response, error)\n}\n\n// OrganizationsAPIService OrganizationsAPI service\ntype OrganizationsAPIService service\n\ntype OrganizationsAPIAcceptOrganizationInvitationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tinvitationId string\n}\n\nfunc (r OrganizationsAPIAcceptOrganizationInvitationRequest) Execute() (*OrganizationInvitation, *http.Response, error) {\n\treturn r.ApiService.AcceptOrganizationInvitationExecute(r)\n}\n\n/*\nAcceptOrganizationInvitation Accept organization invitation\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param invitationId Invitation ID\n @return OrganizationsAPIAcceptOrganizationInvitationRequest\n*/\nfunc (a *OrganizationsAPIService) AcceptOrganizationInvitation(ctx context.Context, invitationId string) OrganizationsAPIAcceptOrganizationInvitationRequest {\n\treturn OrganizationsAPIAcceptOrganizationInvitationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tinvitationId: invitationId,\n\t}\n}\n\n// Execute executes the request\n//  @return OrganizationInvitation\nfunc (a *OrganizationsAPIService) AcceptOrganizationInvitationExecute(r OrganizationsAPIAcceptOrganizationInvitationRequest) (*OrganizationInvitation, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *OrganizationInvitation\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.AcceptOrganizationInvitation\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/invitations/{invitationId}/accept\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"invitationId\"+\"}\", url.PathEscape(parameterValueToString(r.invitationId, \"invitationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPICancelOrganizationInvitationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tinvitationId string\n}\n\nfunc (r OrganizationsAPICancelOrganizationInvitationRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.CancelOrganizationInvitationExecute(r)\n}\n\n/*\nCancelOrganizationInvitation Cancel organization invitation\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @param invitationId Invitation ID\n @return OrganizationsAPICancelOrganizationInvitationRequest\n*/\nfunc (a *OrganizationsAPIService) CancelOrganizationInvitation(ctx context.Context, organizationId string, invitationId string) OrganizationsAPICancelOrganizationInvitationRequest {\n\treturn OrganizationsAPICancelOrganizationInvitationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t\tinvitationId: invitationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) CancelOrganizationInvitationExecute(r OrganizationsAPICancelOrganizationInvitationRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.CancelOrganizationInvitation\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/invitations/{invitationId}/cancel\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"invitationId\"+\"}\", url.PathEscape(parameterValueToString(r.invitationId, \"invitationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPICreateOrganizationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tcreateOrganization *CreateOrganization\n}\n\nfunc (r OrganizationsAPICreateOrganizationRequest) CreateOrganization(createOrganization CreateOrganization) OrganizationsAPICreateOrganizationRequest {\n\tr.createOrganization = &createOrganization\n\treturn r\n}\n\nfunc (r OrganizationsAPICreateOrganizationRequest) Execute() (*Organization, *http.Response, error) {\n\treturn r.ApiService.CreateOrganizationExecute(r)\n}\n\n/*\nCreateOrganization Create organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return OrganizationsAPICreateOrganizationRequest\n*/\nfunc (a *OrganizationsAPIService) CreateOrganization(ctx context.Context) OrganizationsAPICreateOrganizationRequest {\n\treturn OrganizationsAPICreateOrganizationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return Organization\nfunc (a *OrganizationsAPIService) CreateOrganizationExecute(r OrganizationsAPICreateOrganizationRequest) (*Organization, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Organization\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.CreateOrganization\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createOrganization == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createOrganization is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.createOrganization\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPICreateOrganizationInvitationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tcreateOrganizationInvitation *CreateOrganizationInvitation\n}\n\nfunc (r OrganizationsAPICreateOrganizationInvitationRequest) CreateOrganizationInvitation(createOrganizationInvitation CreateOrganizationInvitation) OrganizationsAPICreateOrganizationInvitationRequest {\n\tr.createOrganizationInvitation = &createOrganizationInvitation\n\treturn r\n}\n\nfunc (r OrganizationsAPICreateOrganizationInvitationRequest) Execute() (*OrganizationInvitation, *http.Response, error) {\n\treturn r.ApiService.CreateOrganizationInvitationExecute(r)\n}\n\n/*\nCreateOrganizationInvitation Create organization invitation\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPICreateOrganizationInvitationRequest\n*/\nfunc (a *OrganizationsAPIService) CreateOrganizationInvitation(ctx context.Context, organizationId string) OrganizationsAPICreateOrganizationInvitationRequest {\n\treturn OrganizationsAPICreateOrganizationInvitationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return OrganizationInvitation\nfunc (a *OrganizationsAPIService) CreateOrganizationInvitationExecute(r OrganizationsAPICreateOrganizationInvitationRequest) (*OrganizationInvitation, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *OrganizationInvitation\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.CreateOrganizationInvitation\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/invitations\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createOrganizationInvitation == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createOrganizationInvitation is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.createOrganizationInvitation\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPICreateOrganizationRoleRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tcreateOrganizationRole *CreateOrganizationRole\n}\n\nfunc (r OrganizationsAPICreateOrganizationRoleRequest) CreateOrganizationRole(createOrganizationRole CreateOrganizationRole) OrganizationsAPICreateOrganizationRoleRequest {\n\tr.createOrganizationRole = &createOrganizationRole\n\treturn r\n}\n\nfunc (r OrganizationsAPICreateOrganizationRoleRequest) Execute() (*OrganizationRole, *http.Response, error) {\n\treturn r.ApiService.CreateOrganizationRoleExecute(r)\n}\n\n/*\nCreateOrganizationRole Create organization role\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPICreateOrganizationRoleRequest\n*/\nfunc (a *OrganizationsAPIService) CreateOrganizationRole(ctx context.Context, organizationId string) OrganizationsAPICreateOrganizationRoleRequest {\n\treturn OrganizationsAPICreateOrganizationRoleRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return OrganizationRole\nfunc (a *OrganizationsAPIService) CreateOrganizationRoleExecute(r OrganizationsAPICreateOrganizationRoleRequest) (*OrganizationRole, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *OrganizationRole\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.CreateOrganizationRole\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/roles\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createOrganizationRole == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createOrganizationRole is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.createOrganizationRole\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPICreateRegionRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tcreateRegion *CreateRegion\n\txDaytonaOrganizationID *string\n}\n\nfunc (r OrganizationsAPICreateRegionRequest) CreateRegion(createRegion CreateRegion) OrganizationsAPICreateRegionRequest {\n\tr.createRegion = &createRegion\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r OrganizationsAPICreateRegionRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) OrganizationsAPICreateRegionRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r OrganizationsAPICreateRegionRequest) Execute() (*CreateRegionResponse, *http.Response, error) {\n\treturn r.ApiService.CreateRegionExecute(r)\n}\n\n/*\nCreateRegion Create a new region\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return OrganizationsAPICreateRegionRequest\n*/\nfunc (a *OrganizationsAPIService) CreateRegion(ctx context.Context) OrganizationsAPICreateRegionRequest {\n\treturn OrganizationsAPICreateRegionRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return CreateRegionResponse\nfunc (a *OrganizationsAPIService) CreateRegionExecute(r OrganizationsAPICreateRegionRequest) (*CreateRegionResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *CreateRegionResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.CreateRegion\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/regions\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createRegion == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createRegion is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createRegion\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIDeclineOrganizationInvitationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tinvitationId string\n}\n\nfunc (r OrganizationsAPIDeclineOrganizationInvitationRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeclineOrganizationInvitationExecute(r)\n}\n\n/*\nDeclineOrganizationInvitation Decline organization invitation\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param invitationId Invitation ID\n @return OrganizationsAPIDeclineOrganizationInvitationRequest\n*/\nfunc (a *OrganizationsAPIService) DeclineOrganizationInvitation(ctx context.Context, invitationId string) OrganizationsAPIDeclineOrganizationInvitationRequest {\n\treturn OrganizationsAPIDeclineOrganizationInvitationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tinvitationId: invitationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) DeclineOrganizationInvitationExecute(r OrganizationsAPIDeclineOrganizationInvitationRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.DeclineOrganizationInvitation\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/invitations/{invitationId}/decline\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"invitationId\"+\"}\", url.PathEscape(parameterValueToString(r.invitationId, \"invitationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIDeleteOrganizationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n}\n\nfunc (r OrganizationsAPIDeleteOrganizationRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteOrganizationExecute(r)\n}\n\n/*\nDeleteOrganization Delete organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIDeleteOrganizationRequest\n*/\nfunc (a *OrganizationsAPIService) DeleteOrganization(ctx context.Context, organizationId string) OrganizationsAPIDeleteOrganizationRequest {\n\treturn OrganizationsAPIDeleteOrganizationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) DeleteOrganizationExecute(r OrganizationsAPIDeleteOrganizationRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.DeleteOrganization\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIDeleteOrganizationMemberRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tuserId string\n}\n\nfunc (r OrganizationsAPIDeleteOrganizationMemberRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteOrganizationMemberExecute(r)\n}\n\n/*\nDeleteOrganizationMember Delete organization member\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @param userId User ID\n @return OrganizationsAPIDeleteOrganizationMemberRequest\n*/\nfunc (a *OrganizationsAPIService) DeleteOrganizationMember(ctx context.Context, organizationId string, userId string) OrganizationsAPIDeleteOrganizationMemberRequest {\n\treturn OrganizationsAPIDeleteOrganizationMemberRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t\tuserId: userId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) DeleteOrganizationMemberExecute(r OrganizationsAPIDeleteOrganizationMemberRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.DeleteOrganizationMember\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/users/{userId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"userId\"+\"}\", url.PathEscape(parameterValueToString(r.userId, \"userId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIDeleteOrganizationRoleRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\troleId string\n}\n\nfunc (r OrganizationsAPIDeleteOrganizationRoleRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteOrganizationRoleExecute(r)\n}\n\n/*\nDeleteOrganizationRole Delete organization role\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @param roleId Role ID\n @return OrganizationsAPIDeleteOrganizationRoleRequest\n*/\nfunc (a *OrganizationsAPIService) DeleteOrganizationRole(ctx context.Context, organizationId string, roleId string) OrganizationsAPIDeleteOrganizationRoleRequest {\n\treturn OrganizationsAPIDeleteOrganizationRoleRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t\troleId: roleId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) DeleteOrganizationRoleExecute(r OrganizationsAPIDeleteOrganizationRoleRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.DeleteOrganizationRole\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/roles/{roleId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"roleId\"+\"}\", url.PathEscape(parameterValueToString(r.roleId, \"roleId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIDeleteRegionRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r OrganizationsAPIDeleteRegionRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) OrganizationsAPIDeleteRegionRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r OrganizationsAPIDeleteRegionRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteRegionExecute(r)\n}\n\n/*\nDeleteRegion Delete a region\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Region ID\n @return OrganizationsAPIDeleteRegionRequest\n*/\nfunc (a *OrganizationsAPIService) DeleteRegion(ctx context.Context, id string) OrganizationsAPIDeleteRegionRequest {\n\treturn OrganizationsAPIDeleteRegionRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) DeleteRegionExecute(r OrganizationsAPIDeleteRegionRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.DeleteRegion\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/regions/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIGetOrganizationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n}\n\nfunc (r OrganizationsAPIGetOrganizationRequest) Execute() (*Organization, *http.Response, error) {\n\treturn r.ApiService.GetOrganizationExecute(r)\n}\n\n/*\nGetOrganization Get organization by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIGetOrganizationRequest\n*/\nfunc (a *OrganizationsAPIService) GetOrganization(ctx context.Context, organizationId string) OrganizationsAPIGetOrganizationRequest {\n\treturn OrganizationsAPIGetOrganizationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return Organization\nfunc (a *OrganizationsAPIService) GetOrganizationExecute(r OrganizationsAPIGetOrganizationRequest) (*Organization, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Organization\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.GetOrganization\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIGetOrganizationBySandboxIdRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tsandboxId string\n}\n\nfunc (r OrganizationsAPIGetOrganizationBySandboxIdRequest) Execute() (*Organization, *http.Response, error) {\n\treturn r.ApiService.GetOrganizationBySandboxIdExecute(r)\n}\n\n/*\nGetOrganizationBySandboxId Get organization by sandbox ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId Sandbox ID\n @return OrganizationsAPIGetOrganizationBySandboxIdRequest\n*/\nfunc (a *OrganizationsAPIService) GetOrganizationBySandboxId(ctx context.Context, sandboxId string) OrganizationsAPIGetOrganizationBySandboxIdRequest {\n\treturn OrganizationsAPIGetOrganizationBySandboxIdRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return Organization\nfunc (a *OrganizationsAPIService) GetOrganizationBySandboxIdExecute(r OrganizationsAPIGetOrganizationBySandboxIdRequest) (*Organization, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Organization\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.GetOrganizationBySandboxId\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/by-sandbox-id/{sandboxId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n}\n\nfunc (r OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest) Execute() (float32, *http.Response, error) {\n\treturn r.ApiService.GetOrganizationInvitationsCountForAuthenticatedUserExecute(r)\n}\n\n/*\nGetOrganizationInvitationsCountForAuthenticatedUser Get count of organization invitations for authenticated user\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest\n*/\nfunc (a *OrganizationsAPIService) GetOrganizationInvitationsCountForAuthenticatedUser(ctx context.Context) OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest {\n\treturn OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return float32\nfunc (a *OrganizationsAPIService) GetOrganizationInvitationsCountForAuthenticatedUserExecute(r OrganizationsAPIGetOrganizationInvitationsCountForAuthenticatedUserRequest) (float32, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  float32\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.GetOrganizationInvitationsCountForAuthenticatedUser\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/invitations/count\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tauthToken string\n}\n\nfunc (r OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest) Execute() (*OtelConfig, *http.Response, error) {\n\treturn r.ApiService.GetOrganizationOtelConfigBySandboxAuthTokenExecute(r)\n}\n\n/*\nGetOrganizationOtelConfigBySandboxAuthToken Get organization OTEL config by sandbox auth token\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param authToken Sandbox Auth Token\n @return OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest\n*/\nfunc (a *OrganizationsAPIService) GetOrganizationOtelConfigBySandboxAuthToken(ctx context.Context, authToken string) OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest {\n\treturn OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tauthToken: authToken,\n\t}\n}\n\n// Execute executes the request\n//  @return OtelConfig\nfunc (a *OrganizationsAPIService) GetOrganizationOtelConfigBySandboxAuthTokenExecute(r OrganizationsAPIGetOrganizationOtelConfigBySandboxAuthTokenRequest) (*OtelConfig, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *OtelConfig\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.GetOrganizationOtelConfigBySandboxAuthToken\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/otel-config/by-sandbox-auth-token/{authToken}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"authToken\"+\"}\", url.PathEscape(parameterValueToString(r.authToken, \"authToken\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIGetOrganizationUsageOverviewRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n}\n\nfunc (r OrganizationsAPIGetOrganizationUsageOverviewRequest) Execute() (*OrganizationUsageOverview, *http.Response, error) {\n\treturn r.ApiService.GetOrganizationUsageOverviewExecute(r)\n}\n\n/*\nGetOrganizationUsageOverview Get organization current usage overview\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIGetOrganizationUsageOverviewRequest\n*/\nfunc (a *OrganizationsAPIService) GetOrganizationUsageOverview(ctx context.Context, organizationId string) OrganizationsAPIGetOrganizationUsageOverviewRequest {\n\treturn OrganizationsAPIGetOrganizationUsageOverviewRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return OrganizationUsageOverview\nfunc (a *OrganizationsAPIService) GetOrganizationUsageOverviewExecute(r OrganizationsAPIGetOrganizationUsageOverviewRequest) (*OrganizationUsageOverview, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *OrganizationUsageOverview\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.GetOrganizationUsageOverview\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/usage\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIGetRegionByIdRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r OrganizationsAPIGetRegionByIdRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) OrganizationsAPIGetRegionByIdRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r OrganizationsAPIGetRegionByIdRequest) Execute() (*Region, *http.Response, error) {\n\treturn r.ApiService.GetRegionByIdExecute(r)\n}\n\n/*\nGetRegionById Get region by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Region ID\n @return OrganizationsAPIGetRegionByIdRequest\n*/\nfunc (a *OrganizationsAPIService) GetRegionById(ctx context.Context, id string) OrganizationsAPIGetRegionByIdRequest {\n\treturn OrganizationsAPIGetRegionByIdRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return Region\nfunc (a *OrganizationsAPIService) GetRegionByIdExecute(r OrganizationsAPIGetRegionByIdRequest) (*Region, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Region\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.GetRegionById\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/regions/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIGetRegionQuotaBySandboxIdRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tsandboxId string\n}\n\nfunc (r OrganizationsAPIGetRegionQuotaBySandboxIdRequest) Execute() (*RegionQuota, *http.Response, error) {\n\treturn r.ApiService.GetRegionQuotaBySandboxIdExecute(r)\n}\n\n/*\nGetRegionQuotaBySandboxId Get region quota by sandbox ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId Sandbox ID\n @return OrganizationsAPIGetRegionQuotaBySandboxIdRequest\n*/\nfunc (a *OrganizationsAPIService) GetRegionQuotaBySandboxId(ctx context.Context, sandboxId string) OrganizationsAPIGetRegionQuotaBySandboxIdRequest {\n\treturn OrganizationsAPIGetRegionQuotaBySandboxIdRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return RegionQuota\nfunc (a *OrganizationsAPIService) GetRegionQuotaBySandboxIdExecute(r OrganizationsAPIGetRegionQuotaBySandboxIdRequest) (*RegionQuota, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RegionQuota\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.GetRegionQuotaBySandboxId\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/region-quota/by-sandbox-id/{sandboxId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPILeaveOrganizationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n}\n\nfunc (r OrganizationsAPILeaveOrganizationRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.LeaveOrganizationExecute(r)\n}\n\n/*\nLeaveOrganization Leave organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPILeaveOrganizationRequest\n*/\nfunc (a *OrganizationsAPIService) LeaveOrganization(ctx context.Context, organizationId string) OrganizationsAPILeaveOrganizationRequest {\n\treturn OrganizationsAPILeaveOrganizationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) LeaveOrganizationExecute(r OrganizationsAPILeaveOrganizationRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.LeaveOrganization\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/leave\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIListAvailableRegionsRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r OrganizationsAPIListAvailableRegionsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) OrganizationsAPIListAvailableRegionsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r OrganizationsAPIListAvailableRegionsRequest) Execute() ([]Region, *http.Response, error) {\n\treturn r.ApiService.ListAvailableRegionsExecute(r)\n}\n\n/*\nListAvailableRegions List all available regions for the organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return OrganizationsAPIListAvailableRegionsRequest\n*/\nfunc (a *OrganizationsAPIService) ListAvailableRegions(ctx context.Context) OrganizationsAPIListAvailableRegionsRequest {\n\treturn OrganizationsAPIListAvailableRegionsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []Region\nfunc (a *OrganizationsAPIService) ListAvailableRegionsExecute(r OrganizationsAPIListAvailableRegionsRequest) ([]Region, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Region\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.ListAvailableRegions\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/regions\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIListOrganizationInvitationsRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n}\n\nfunc (r OrganizationsAPIListOrganizationInvitationsRequest) Execute() ([]OrganizationInvitation, *http.Response, error) {\n\treturn r.ApiService.ListOrganizationInvitationsExecute(r)\n}\n\n/*\nListOrganizationInvitations List pending organization invitations\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIListOrganizationInvitationsRequest\n*/\nfunc (a *OrganizationsAPIService) ListOrganizationInvitations(ctx context.Context, organizationId string) OrganizationsAPIListOrganizationInvitationsRequest {\n\treturn OrganizationsAPIListOrganizationInvitationsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return []OrganizationInvitation\nfunc (a *OrganizationsAPIService) ListOrganizationInvitationsExecute(r OrganizationsAPIListOrganizationInvitationsRequest) ([]OrganizationInvitation, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []OrganizationInvitation\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.ListOrganizationInvitations\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/invitations\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n}\n\nfunc (r OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest) Execute() ([]OrganizationInvitation, *http.Response, error) {\n\treturn r.ApiService.ListOrganizationInvitationsForAuthenticatedUserExecute(r)\n}\n\n/*\nListOrganizationInvitationsForAuthenticatedUser List organization invitations for authenticated user\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest\n*/\nfunc (a *OrganizationsAPIService) ListOrganizationInvitationsForAuthenticatedUser(ctx context.Context) OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest {\n\treturn OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []OrganizationInvitation\nfunc (a *OrganizationsAPIService) ListOrganizationInvitationsForAuthenticatedUserExecute(r OrganizationsAPIListOrganizationInvitationsForAuthenticatedUserRequest) ([]OrganizationInvitation, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []OrganizationInvitation\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.ListOrganizationInvitationsForAuthenticatedUser\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/invitations\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIListOrganizationMembersRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n}\n\nfunc (r OrganizationsAPIListOrganizationMembersRequest) Execute() ([]OrganizationUser, *http.Response, error) {\n\treturn r.ApiService.ListOrganizationMembersExecute(r)\n}\n\n/*\nListOrganizationMembers List organization members\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIListOrganizationMembersRequest\n*/\nfunc (a *OrganizationsAPIService) ListOrganizationMembers(ctx context.Context, organizationId string) OrganizationsAPIListOrganizationMembersRequest {\n\treturn OrganizationsAPIListOrganizationMembersRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return []OrganizationUser\nfunc (a *OrganizationsAPIService) ListOrganizationMembersExecute(r OrganizationsAPIListOrganizationMembersRequest) ([]OrganizationUser, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []OrganizationUser\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.ListOrganizationMembers\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/users\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIListOrganizationRolesRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n}\n\nfunc (r OrganizationsAPIListOrganizationRolesRequest) Execute() ([]OrganizationRole, *http.Response, error) {\n\treturn r.ApiService.ListOrganizationRolesExecute(r)\n}\n\n/*\nListOrganizationRoles List organization roles\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIListOrganizationRolesRequest\n*/\nfunc (a *OrganizationsAPIService) ListOrganizationRoles(ctx context.Context, organizationId string) OrganizationsAPIListOrganizationRolesRequest {\n\treturn OrganizationsAPIListOrganizationRolesRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return []OrganizationRole\nfunc (a *OrganizationsAPIService) ListOrganizationRolesExecute(r OrganizationsAPIListOrganizationRolesRequest) ([]OrganizationRole, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []OrganizationRole\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.ListOrganizationRoles\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/roles\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIListOrganizationsRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n}\n\nfunc (r OrganizationsAPIListOrganizationsRequest) Execute() ([]Organization, *http.Response, error) {\n\treturn r.ApiService.ListOrganizationsExecute(r)\n}\n\n/*\nListOrganizations List organizations\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return OrganizationsAPIListOrganizationsRequest\n*/\nfunc (a *OrganizationsAPIService) ListOrganizations(ctx context.Context) OrganizationsAPIListOrganizationsRequest {\n\treturn OrganizationsAPIListOrganizationsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []Organization\nfunc (a *OrganizationsAPIService) ListOrganizationsExecute(r OrganizationsAPIListOrganizationsRequest) ([]Organization, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Organization\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.ListOrganizations\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIRegenerateProxyApiKeyRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r OrganizationsAPIRegenerateProxyApiKeyRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) OrganizationsAPIRegenerateProxyApiKeyRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r OrganizationsAPIRegenerateProxyApiKeyRequest) Execute() (*RegenerateApiKeyResponse, *http.Response, error) {\n\treturn r.ApiService.RegenerateProxyApiKeyExecute(r)\n}\n\n/*\nRegenerateProxyApiKey Regenerate proxy API key for a region\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Region ID\n @return OrganizationsAPIRegenerateProxyApiKeyRequest\n*/\nfunc (a *OrganizationsAPIService) RegenerateProxyApiKey(ctx context.Context, id string) OrganizationsAPIRegenerateProxyApiKeyRequest {\n\treturn OrganizationsAPIRegenerateProxyApiKeyRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return RegenerateApiKeyResponse\nfunc (a *OrganizationsAPIService) RegenerateProxyApiKeyExecute(r OrganizationsAPIRegenerateProxyApiKeyRequest) (*RegenerateApiKeyResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RegenerateApiKeyResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.RegenerateProxyApiKey\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/regions/{id}/regenerate-proxy-api-key\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest) Execute() (*SnapshotManagerCredentials, *http.Response, error) {\n\treturn r.ApiService.RegenerateSnapshotManagerCredentialsExecute(r)\n}\n\n/*\nRegenerateSnapshotManagerCredentials Regenerate snapshot manager credentials for a region\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Region ID\n @return OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest\n*/\nfunc (a *OrganizationsAPIService) RegenerateSnapshotManagerCredentials(ctx context.Context, id string) OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest {\n\treturn OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return SnapshotManagerCredentials\nfunc (a *OrganizationsAPIService) RegenerateSnapshotManagerCredentialsExecute(r OrganizationsAPIRegenerateSnapshotManagerCredentialsRequest) (*SnapshotManagerCredentials, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SnapshotManagerCredentials\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.RegenerateSnapshotManagerCredentials\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/regions/{id}/regenerate-snapshot-manager-credentials\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIRegenerateSshGatewayApiKeyRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r OrganizationsAPIRegenerateSshGatewayApiKeyRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) OrganizationsAPIRegenerateSshGatewayApiKeyRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r OrganizationsAPIRegenerateSshGatewayApiKeyRequest) Execute() (*RegenerateApiKeyResponse, *http.Response, error) {\n\treturn r.ApiService.RegenerateSshGatewayApiKeyExecute(r)\n}\n\n/*\nRegenerateSshGatewayApiKey Regenerate SSH gateway API key for a region\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Region ID\n @return OrganizationsAPIRegenerateSshGatewayApiKeyRequest\n*/\nfunc (a *OrganizationsAPIService) RegenerateSshGatewayApiKey(ctx context.Context, id string) OrganizationsAPIRegenerateSshGatewayApiKeyRequest {\n\treturn OrganizationsAPIRegenerateSshGatewayApiKeyRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return RegenerateApiKeyResponse\nfunc (a *OrganizationsAPIService) RegenerateSshGatewayApiKeyExecute(r OrganizationsAPIRegenerateSshGatewayApiKeyRequest) (*RegenerateApiKeyResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RegenerateApiKeyResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.RegenerateSshGatewayApiKey\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/regions/{id}/regenerate-ssh-gateway-api-key\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPISetOrganizationDefaultRegionRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tupdateOrganizationDefaultRegion *UpdateOrganizationDefaultRegion\n}\n\nfunc (r OrganizationsAPISetOrganizationDefaultRegionRequest) UpdateOrganizationDefaultRegion(updateOrganizationDefaultRegion UpdateOrganizationDefaultRegion) OrganizationsAPISetOrganizationDefaultRegionRequest {\n\tr.updateOrganizationDefaultRegion = &updateOrganizationDefaultRegion\n\treturn r\n}\n\nfunc (r OrganizationsAPISetOrganizationDefaultRegionRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.SetOrganizationDefaultRegionExecute(r)\n}\n\n/*\nSetOrganizationDefaultRegion Set default region for organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPISetOrganizationDefaultRegionRequest\n*/\nfunc (a *OrganizationsAPIService) SetOrganizationDefaultRegion(ctx context.Context, organizationId string) OrganizationsAPISetOrganizationDefaultRegionRequest {\n\treturn OrganizationsAPISetOrganizationDefaultRegionRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) SetOrganizationDefaultRegionExecute(r OrganizationsAPISetOrganizationDefaultRegionRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.SetOrganizationDefaultRegion\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/default-region\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateOrganizationDefaultRegion == nil {\n\t\treturn nil, reportError(\"updateOrganizationDefaultRegion is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateOrganizationDefaultRegion\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPISuspendOrganizationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\torganizationSuspension *OrganizationSuspension\n}\n\nfunc (r OrganizationsAPISuspendOrganizationRequest) OrganizationSuspension(organizationSuspension OrganizationSuspension) OrganizationsAPISuspendOrganizationRequest {\n\tr.organizationSuspension = &organizationSuspension\n\treturn r\n}\n\nfunc (r OrganizationsAPISuspendOrganizationRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.SuspendOrganizationExecute(r)\n}\n\n/*\nSuspendOrganization Suspend organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPISuspendOrganizationRequest\n*/\nfunc (a *OrganizationsAPIService) SuspendOrganization(ctx context.Context, organizationId string) OrganizationsAPISuspendOrganizationRequest {\n\treturn OrganizationsAPISuspendOrganizationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) SuspendOrganizationExecute(r OrganizationsAPISuspendOrganizationRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.SuspendOrganization\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/suspend\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.organizationSuspension\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUnsuspendOrganizationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n}\n\nfunc (r OrganizationsAPIUnsuspendOrganizationRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UnsuspendOrganizationExecute(r)\n}\n\n/*\nUnsuspendOrganization Unsuspend organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIUnsuspendOrganizationRequest\n*/\nfunc (a *OrganizationsAPIService) UnsuspendOrganization(ctx context.Context, organizationId string) OrganizationsAPIUnsuspendOrganizationRequest {\n\treturn OrganizationsAPIUnsuspendOrganizationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) UnsuspendOrganizationExecute(r OrganizationsAPIUnsuspendOrganizationRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UnsuspendOrganization\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/unsuspend\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUpdateAccessForOrganizationMemberRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tuserId string\n\tupdateOrganizationMemberAccess *UpdateOrganizationMemberAccess\n}\n\nfunc (r OrganizationsAPIUpdateAccessForOrganizationMemberRequest) UpdateOrganizationMemberAccess(updateOrganizationMemberAccess UpdateOrganizationMemberAccess) OrganizationsAPIUpdateAccessForOrganizationMemberRequest {\n\tr.updateOrganizationMemberAccess = &updateOrganizationMemberAccess\n\treturn r\n}\n\nfunc (r OrganizationsAPIUpdateAccessForOrganizationMemberRequest) Execute() (*OrganizationUser, *http.Response, error) {\n\treturn r.ApiService.UpdateAccessForOrganizationMemberExecute(r)\n}\n\n/*\nUpdateAccessForOrganizationMember Update access for organization member\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @param userId User ID\n @return OrganizationsAPIUpdateAccessForOrganizationMemberRequest\n*/\nfunc (a *OrganizationsAPIService) UpdateAccessForOrganizationMember(ctx context.Context, organizationId string, userId string) OrganizationsAPIUpdateAccessForOrganizationMemberRequest {\n\treturn OrganizationsAPIUpdateAccessForOrganizationMemberRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t\tuserId: userId,\n\t}\n}\n\n// Execute executes the request\n//  @return OrganizationUser\nfunc (a *OrganizationsAPIService) UpdateAccessForOrganizationMemberExecute(r OrganizationsAPIUpdateAccessForOrganizationMemberRequest) (*OrganizationUser, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *OrganizationUser\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UpdateAccessForOrganizationMember\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/users/{userId}/access\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"userId\"+\"}\", url.PathEscape(parameterValueToString(r.userId, \"userId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateOrganizationMemberAccess == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"updateOrganizationMemberAccess is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateOrganizationMemberAccess\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUpdateExperimentalConfigRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\trequestBody *map[string]interface{}\n}\n\n// Experimental configuration as a JSON object. Set to null to clear the configuration.\nfunc (r OrganizationsAPIUpdateExperimentalConfigRequest) RequestBody(requestBody map[string]interface{}) OrganizationsAPIUpdateExperimentalConfigRequest {\n\tr.requestBody = &requestBody\n\treturn r\n}\n\nfunc (r OrganizationsAPIUpdateExperimentalConfigRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UpdateExperimentalConfigExecute(r)\n}\n\n/*\nUpdateExperimentalConfig Update experimental configuration\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIUpdateExperimentalConfigRequest\n*/\nfunc (a *OrganizationsAPIService) UpdateExperimentalConfig(ctx context.Context, organizationId string) OrganizationsAPIUpdateExperimentalConfigRequest {\n\treturn OrganizationsAPIUpdateExperimentalConfigRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) UpdateExperimentalConfigExecute(r OrganizationsAPIUpdateExperimentalConfigRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPut\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UpdateExperimentalConfig\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/experimental-config\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.requestBody\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUpdateOrganizationInvitationRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tinvitationId string\n\tupdateOrganizationInvitation *UpdateOrganizationInvitation\n}\n\nfunc (r OrganizationsAPIUpdateOrganizationInvitationRequest) UpdateOrganizationInvitation(updateOrganizationInvitation UpdateOrganizationInvitation) OrganizationsAPIUpdateOrganizationInvitationRequest {\n\tr.updateOrganizationInvitation = &updateOrganizationInvitation\n\treturn r\n}\n\nfunc (r OrganizationsAPIUpdateOrganizationInvitationRequest) Execute() (*OrganizationInvitation, *http.Response, error) {\n\treturn r.ApiService.UpdateOrganizationInvitationExecute(r)\n}\n\n/*\nUpdateOrganizationInvitation Update organization invitation\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @param invitationId Invitation ID\n @return OrganizationsAPIUpdateOrganizationInvitationRequest\n*/\nfunc (a *OrganizationsAPIService) UpdateOrganizationInvitation(ctx context.Context, organizationId string, invitationId string) OrganizationsAPIUpdateOrganizationInvitationRequest {\n\treturn OrganizationsAPIUpdateOrganizationInvitationRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t\tinvitationId: invitationId,\n\t}\n}\n\n// Execute executes the request\n//  @return OrganizationInvitation\nfunc (a *OrganizationsAPIService) UpdateOrganizationInvitationExecute(r OrganizationsAPIUpdateOrganizationInvitationRequest) (*OrganizationInvitation, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPut\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *OrganizationInvitation\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UpdateOrganizationInvitation\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/invitations/{invitationId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"invitationId\"+\"}\", url.PathEscape(parameterValueToString(r.invitationId, \"invitationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateOrganizationInvitation == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"updateOrganizationInvitation is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateOrganizationInvitation\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUpdateOrganizationQuotaRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tupdateOrganizationQuota *UpdateOrganizationQuota\n}\n\nfunc (r OrganizationsAPIUpdateOrganizationQuotaRequest) UpdateOrganizationQuota(updateOrganizationQuota UpdateOrganizationQuota) OrganizationsAPIUpdateOrganizationQuotaRequest {\n\tr.updateOrganizationQuota = &updateOrganizationQuota\n\treturn r\n}\n\nfunc (r OrganizationsAPIUpdateOrganizationQuotaRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UpdateOrganizationQuotaExecute(r)\n}\n\n/*\nUpdateOrganizationQuota Update organization quota\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIUpdateOrganizationQuotaRequest\n*/\nfunc (a *OrganizationsAPIService) UpdateOrganizationQuota(ctx context.Context, organizationId string) OrganizationsAPIUpdateOrganizationQuotaRequest {\n\treturn OrganizationsAPIUpdateOrganizationQuotaRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) UpdateOrganizationQuotaExecute(r OrganizationsAPIUpdateOrganizationQuotaRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UpdateOrganizationQuota\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/quota\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateOrganizationQuota == nil {\n\t\treturn nil, reportError(\"updateOrganizationQuota is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateOrganizationQuota\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUpdateOrganizationRegionQuotaRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\tregionId string\n\tupdateOrganizationRegionQuota *UpdateOrganizationRegionQuota\n}\n\nfunc (r OrganizationsAPIUpdateOrganizationRegionQuotaRequest) UpdateOrganizationRegionQuota(updateOrganizationRegionQuota UpdateOrganizationRegionQuota) OrganizationsAPIUpdateOrganizationRegionQuotaRequest {\n\tr.updateOrganizationRegionQuota = &updateOrganizationRegionQuota\n\treturn r\n}\n\nfunc (r OrganizationsAPIUpdateOrganizationRegionQuotaRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UpdateOrganizationRegionQuotaExecute(r)\n}\n\n/*\nUpdateOrganizationRegionQuota Update organization region quota\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @param regionId ID of the region where the updated quota will be applied\n @return OrganizationsAPIUpdateOrganizationRegionQuotaRequest\n*/\nfunc (a *OrganizationsAPIService) UpdateOrganizationRegionQuota(ctx context.Context, organizationId string, regionId string) OrganizationsAPIUpdateOrganizationRegionQuotaRequest {\n\treturn OrganizationsAPIUpdateOrganizationRegionQuotaRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t\tregionId: regionId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) UpdateOrganizationRegionQuotaExecute(r OrganizationsAPIUpdateOrganizationRegionQuotaRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UpdateOrganizationRegionQuota\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/quota/{regionId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"regionId\"+\"}\", url.PathEscape(parameterValueToString(r.regionId, \"regionId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateOrganizationRegionQuota == nil {\n\t\treturn nil, reportError(\"updateOrganizationRegionQuota is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateOrganizationRegionQuota\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUpdateOrganizationRoleRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\troleId string\n\tupdateOrganizationRole *UpdateOrganizationRole\n}\n\nfunc (r OrganizationsAPIUpdateOrganizationRoleRequest) UpdateOrganizationRole(updateOrganizationRole UpdateOrganizationRole) OrganizationsAPIUpdateOrganizationRoleRequest {\n\tr.updateOrganizationRole = &updateOrganizationRole\n\treturn r\n}\n\nfunc (r OrganizationsAPIUpdateOrganizationRoleRequest) Execute() (*OrganizationRole, *http.Response, error) {\n\treturn r.ApiService.UpdateOrganizationRoleExecute(r)\n}\n\n/*\nUpdateOrganizationRole Update organization role\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @param roleId Role ID\n @return OrganizationsAPIUpdateOrganizationRoleRequest\n*/\nfunc (a *OrganizationsAPIService) UpdateOrganizationRole(ctx context.Context, organizationId string, roleId string) OrganizationsAPIUpdateOrganizationRoleRequest {\n\treturn OrganizationsAPIUpdateOrganizationRoleRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t\troleId: roleId,\n\t}\n}\n\n// Execute executes the request\n//  @return OrganizationRole\nfunc (a *OrganizationsAPIService) UpdateOrganizationRoleExecute(r OrganizationsAPIUpdateOrganizationRoleRequest) (*OrganizationRole, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPut\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *OrganizationRole\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UpdateOrganizationRole\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/roles/{roleId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"roleId\"+\"}\", url.PathEscape(parameterValueToString(r.roleId, \"roleId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateOrganizationRole == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"updateOrganizationRole is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateOrganizationRole\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUpdateRegionRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\tid string\n\tupdateRegion *UpdateRegion\n\txDaytonaOrganizationID *string\n}\n\nfunc (r OrganizationsAPIUpdateRegionRequest) UpdateRegion(updateRegion UpdateRegion) OrganizationsAPIUpdateRegionRequest {\n\tr.updateRegion = &updateRegion\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r OrganizationsAPIUpdateRegionRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) OrganizationsAPIUpdateRegionRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r OrganizationsAPIUpdateRegionRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UpdateRegionExecute(r)\n}\n\n/*\nUpdateRegion Update region configuration\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Region ID\n @return OrganizationsAPIUpdateRegionRequest\n*/\nfunc (a *OrganizationsAPIService) UpdateRegion(ctx context.Context, id string) OrganizationsAPIUpdateRegionRequest {\n\treturn OrganizationsAPIUpdateRegionRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) UpdateRegionExecute(r OrganizationsAPIUpdateRegionRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UpdateRegion\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/regions/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateRegion == nil {\n\t\treturn nil, reportError(\"updateRegion is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateRegion\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest struct {\n\tctx context.Context\n\tApiService OrganizationsAPI\n\torganizationId string\n\torganizationSandboxDefaultLimitedNetworkEgress *OrganizationSandboxDefaultLimitedNetworkEgress\n}\n\nfunc (r OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest) OrganizationSandboxDefaultLimitedNetworkEgress(organizationSandboxDefaultLimitedNetworkEgress OrganizationSandboxDefaultLimitedNetworkEgress) OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest {\n\tr.organizationSandboxDefaultLimitedNetworkEgress = &organizationSandboxDefaultLimitedNetworkEgress\n\treturn r\n}\n\nfunc (r OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UpdateSandboxDefaultLimitedNetworkEgressExecute(r)\n}\n\n/*\nUpdateSandboxDefaultLimitedNetworkEgress Update sandbox default limited network egress\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId Organization ID\n @return OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest\n*/\nfunc (a *OrganizationsAPIService) UpdateSandboxDefaultLimitedNetworkEgress(ctx context.Context, organizationId string) OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest {\n\treturn OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *OrganizationsAPIService) UpdateSandboxDefaultLimitedNetworkEgressExecute(r OrganizationsAPIUpdateSandboxDefaultLimitedNetworkEgressRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"OrganizationsAPIService.UpdateSandboxDefaultLimitedNetworkEgress\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/organizations/{organizationId}/sandbox-default-limited-network-egress\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.organizationSandboxDefaultLimitedNetworkEgress == nil {\n\t\treturn nil, reportError(\"organizationSandboxDefaultLimitedNetworkEgress is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.organizationSandboxDefaultLimitedNetworkEgress\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_preview.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype PreviewAPI interface {\n\n\t/*\n\tGetSandboxIdFromSignedPreviewUrlToken Get sandbox ID from signed preview URL token\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param signedPreviewToken Signed preview URL token\n\t@param port Port number to get sandbox ID from signed preview URL token\n\t@return PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest\n\t*/\n\tGetSandboxIdFromSignedPreviewUrlToken(ctx context.Context, signedPreviewToken string, port float32) PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest\n\n\t// GetSandboxIdFromSignedPreviewUrlTokenExecute executes the request\n\t//  @return string\n\tGetSandboxIdFromSignedPreviewUrlTokenExecute(r PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest) (string, *http.Response, error)\n\n\t/*\n\tHasSandboxAccess Check if user has access to the sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return PreviewAPIHasSandboxAccessRequest\n\t*/\n\tHasSandboxAccess(ctx context.Context, sandboxId string) PreviewAPIHasSandboxAccessRequest\n\n\t// HasSandboxAccessExecute executes the request\n\t//  @return bool\n\tHasSandboxAccessExecute(r PreviewAPIHasSandboxAccessRequest) (bool, *http.Response, error)\n\n\t/*\n\tIsSandboxPublic Check if sandbox is public\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@return PreviewAPIIsSandboxPublicRequest\n\t*/\n\tIsSandboxPublic(ctx context.Context, sandboxId string) PreviewAPIIsSandboxPublicRequest\n\n\t// IsSandboxPublicExecute executes the request\n\t//  @return bool\n\tIsSandboxPublicExecute(r PreviewAPIIsSandboxPublicRequest) (bool, *http.Response, error)\n\n\t/*\n\tIsValidAuthToken Check if sandbox auth token is valid\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@param authToken Auth token of the sandbox\n\t@return PreviewAPIIsValidAuthTokenRequest\n\t*/\n\tIsValidAuthToken(ctx context.Context, sandboxId string, authToken string) PreviewAPIIsValidAuthTokenRequest\n\n\t// IsValidAuthTokenExecute executes the request\n\t//  @return bool\n\tIsValidAuthTokenExecute(r PreviewAPIIsValidAuthTokenRequest) (bool, *http.Response, error)\n}\n\n// PreviewAPIService PreviewAPI service\ntype PreviewAPIService service\n\ntype PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest struct {\n\tctx context.Context\n\tApiService PreviewAPI\n\tsignedPreviewToken string\n\tport float32\n}\n\nfunc (r PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest) Execute() (string, *http.Response, error) {\n\treturn r.ApiService.GetSandboxIdFromSignedPreviewUrlTokenExecute(r)\n}\n\n/*\nGetSandboxIdFromSignedPreviewUrlToken Get sandbox ID from signed preview URL token\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param signedPreviewToken Signed preview URL token\n @param port Port number to get sandbox ID from signed preview URL token\n @return PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest\n*/\nfunc (a *PreviewAPIService) GetSandboxIdFromSignedPreviewUrlToken(ctx context.Context, signedPreviewToken string, port float32) PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest {\n\treturn PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsignedPreviewToken: signedPreviewToken,\n\t\tport: port,\n\t}\n}\n\n// Execute executes the request\n//  @return string\nfunc (a *PreviewAPIService) GetSandboxIdFromSignedPreviewUrlTokenExecute(r PreviewAPIGetSandboxIdFromSignedPreviewUrlTokenRequest) (string, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  string\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"PreviewAPIService.GetSandboxIdFromSignedPreviewUrlToken\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/preview/{signedPreviewToken}/{port}/sandbox-id\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"signedPreviewToken\"+\"}\", url.PathEscape(parameterValueToString(r.signedPreviewToken, \"signedPreviewToken\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"port\"+\"}\", url.PathEscape(parameterValueToString(r.port, \"port\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype PreviewAPIHasSandboxAccessRequest struct {\n\tctx context.Context\n\tApiService PreviewAPI\n\tsandboxId string\n}\n\nfunc (r PreviewAPIHasSandboxAccessRequest) Execute() (bool, *http.Response, error) {\n\treturn r.ApiService.HasSandboxAccessExecute(r)\n}\n\n/*\nHasSandboxAccess Check if user has access to the sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return PreviewAPIHasSandboxAccessRequest\n*/\nfunc (a *PreviewAPIService) HasSandboxAccess(ctx context.Context, sandboxId string) PreviewAPIHasSandboxAccessRequest {\n\treturn PreviewAPIHasSandboxAccessRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return bool\nfunc (a *PreviewAPIService) HasSandboxAccessExecute(r PreviewAPIHasSandboxAccessRequest) (bool, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  bool\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"PreviewAPIService.HasSandboxAccess\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/preview/{sandboxId}/access\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype PreviewAPIIsSandboxPublicRequest struct {\n\tctx context.Context\n\tApiService PreviewAPI\n\tsandboxId string\n}\n\nfunc (r PreviewAPIIsSandboxPublicRequest) Execute() (bool, *http.Response, error) {\n\treturn r.ApiService.IsSandboxPublicExecute(r)\n}\n\n/*\nIsSandboxPublic Check if sandbox is public\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @return PreviewAPIIsSandboxPublicRequest\n*/\nfunc (a *PreviewAPIService) IsSandboxPublic(ctx context.Context, sandboxId string) PreviewAPIIsSandboxPublicRequest {\n\treturn PreviewAPIIsSandboxPublicRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return bool\nfunc (a *PreviewAPIService) IsSandboxPublicExecute(r PreviewAPIIsSandboxPublicRequest) (bool, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  bool\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"PreviewAPIService.IsSandboxPublic\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/preview/{sandboxId}/public\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype PreviewAPIIsValidAuthTokenRequest struct {\n\tctx context.Context\n\tApiService PreviewAPI\n\tsandboxId string\n\tauthToken string\n}\n\nfunc (r PreviewAPIIsValidAuthTokenRequest) Execute() (bool, *http.Response, error) {\n\treturn r.ApiService.IsValidAuthTokenExecute(r)\n}\n\n/*\nIsValidAuthToken Check if sandbox auth token is valid\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @param authToken Auth token of the sandbox\n @return PreviewAPIIsValidAuthTokenRequest\n*/\nfunc (a *PreviewAPIService) IsValidAuthToken(ctx context.Context, sandboxId string, authToken string) PreviewAPIIsValidAuthTokenRequest {\n\treturn PreviewAPIIsValidAuthTokenRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tauthToken: authToken,\n\t}\n}\n\n// Execute executes the request\n//  @return bool\nfunc (a *PreviewAPIService) IsValidAuthTokenExecute(r PreviewAPIIsValidAuthTokenRequest) (bool, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  bool\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"PreviewAPIService.IsValidAuthToken\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/preview/{sandboxId}/validate/{authToken}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"authToken\"+\"}\", url.PathEscape(parameterValueToString(r.authToken, \"authToken\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_regions.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n)\n\n\ntype RegionsAPI interface {\n\n\t/*\n\tListSharedRegions List all shared regions\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return RegionsAPIListSharedRegionsRequest\n\t*/\n\tListSharedRegions(ctx context.Context) RegionsAPIListSharedRegionsRequest\n\n\t// ListSharedRegionsExecute executes the request\n\t//  @return []Region\n\tListSharedRegionsExecute(r RegionsAPIListSharedRegionsRequest) ([]Region, *http.Response, error)\n}\n\n// RegionsAPIService RegionsAPI service\ntype RegionsAPIService service\n\ntype RegionsAPIListSharedRegionsRequest struct {\n\tctx context.Context\n\tApiService RegionsAPI\n}\n\nfunc (r RegionsAPIListSharedRegionsRequest) Execute() ([]Region, *http.Response, error) {\n\treturn r.ApiService.ListSharedRegionsExecute(r)\n}\n\n/*\nListSharedRegions List all shared regions\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return RegionsAPIListSharedRegionsRequest\n*/\nfunc (a *RegionsAPIService) ListSharedRegions(ctx context.Context) RegionsAPIListSharedRegionsRequest {\n\treturn RegionsAPIListSharedRegionsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []Region\nfunc (a *RegionsAPIService) ListSharedRegionsExecute(r RegionsAPIListSharedRegionsRequest) ([]Region, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Region\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RegionsAPIService.ListSharedRegions\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/shared-regions\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_runners.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype RunnersAPI interface {\n\n\t/*\n\tCreateRunner Create runner\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return RunnersAPICreateRunnerRequest\n\t*/\n\tCreateRunner(ctx context.Context) RunnersAPICreateRunnerRequest\n\n\t// CreateRunnerExecute executes the request\n\t//  @return CreateRunnerResponse\n\tCreateRunnerExecute(r RunnersAPICreateRunnerRequest) (*CreateRunnerResponse, *http.Response, error)\n\n\t/*\n\tDeleteRunner Delete runner\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Runner ID\n\t@return RunnersAPIDeleteRunnerRequest\n\t*/\n\tDeleteRunner(ctx context.Context, id string) RunnersAPIDeleteRunnerRequest\n\n\t// DeleteRunnerExecute executes the request\n\tDeleteRunnerExecute(r RunnersAPIDeleteRunnerRequest) (*http.Response, error)\n\n\t/*\n\tGetInfoForAuthenticatedRunner Get info for authenticated runner\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return RunnersAPIGetInfoForAuthenticatedRunnerRequest\n\t*/\n\tGetInfoForAuthenticatedRunner(ctx context.Context) RunnersAPIGetInfoForAuthenticatedRunnerRequest\n\n\t// GetInfoForAuthenticatedRunnerExecute executes the request\n\t//  @return RunnerFull\n\tGetInfoForAuthenticatedRunnerExecute(r RunnersAPIGetInfoForAuthenticatedRunnerRequest) (*RunnerFull, *http.Response, error)\n\n\t/*\n\tGetRunnerById Get runner by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Runner ID\n\t@return RunnersAPIGetRunnerByIdRequest\n\t*/\n\tGetRunnerById(ctx context.Context, id string) RunnersAPIGetRunnerByIdRequest\n\n\t// GetRunnerByIdExecute executes the request\n\t//  @return Runner\n\tGetRunnerByIdExecute(r RunnersAPIGetRunnerByIdRequest) (*Runner, *http.Response, error)\n\n\t/*\n\tGetRunnerBySandboxId Get runner by sandbox ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return RunnersAPIGetRunnerBySandboxIdRequest\n\t*/\n\tGetRunnerBySandboxId(ctx context.Context, sandboxId string) RunnersAPIGetRunnerBySandboxIdRequest\n\n\t// GetRunnerBySandboxIdExecute executes the request\n\t//  @return RunnerFull\n\tGetRunnerBySandboxIdExecute(r RunnersAPIGetRunnerBySandboxIdRequest) (*RunnerFull, *http.Response, error)\n\n\t/*\n\tGetRunnerFullById Get runner by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Runner ID\n\t@return RunnersAPIGetRunnerFullByIdRequest\n\t*/\n\tGetRunnerFullById(ctx context.Context, id string) RunnersAPIGetRunnerFullByIdRequest\n\n\t// GetRunnerFullByIdExecute executes the request\n\t//  @return RunnerFull\n\tGetRunnerFullByIdExecute(r RunnersAPIGetRunnerFullByIdRequest) (*RunnerFull, *http.Response, error)\n\n\t/*\n\tGetRunnersBySnapshotRef Get runners by snapshot ref\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return RunnersAPIGetRunnersBySnapshotRefRequest\n\t*/\n\tGetRunnersBySnapshotRef(ctx context.Context) RunnersAPIGetRunnersBySnapshotRefRequest\n\n\t// GetRunnersBySnapshotRefExecute executes the request\n\t//  @return []RunnerSnapshotDto\n\tGetRunnersBySnapshotRefExecute(r RunnersAPIGetRunnersBySnapshotRefRequest) ([]RunnerSnapshotDto, *http.Response, error)\n\n\t/*\n\tListRunners List all runners\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return RunnersAPIListRunnersRequest\n\t*/\n\tListRunners(ctx context.Context) RunnersAPIListRunnersRequest\n\n\t// ListRunnersExecute executes the request\n\t//  @return []Runner\n\tListRunnersExecute(r RunnersAPIListRunnersRequest) ([]Runner, *http.Response, error)\n\n\t/*\n\tRunnerHealthcheck Runner healthcheck\n\n\tEndpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return RunnersAPIRunnerHealthcheckRequest\n\t*/\n\tRunnerHealthcheck(ctx context.Context) RunnersAPIRunnerHealthcheckRequest\n\n\t// RunnerHealthcheckExecute executes the request\n\tRunnerHealthcheckExecute(r RunnersAPIRunnerHealthcheckRequest) (*http.Response, error)\n\n\t/*\n\tUpdateRunnerDraining Update runner draining status\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Runner ID\n\t@return RunnersAPIUpdateRunnerDrainingRequest\n\t*/\n\tUpdateRunnerDraining(ctx context.Context, id string) RunnersAPIUpdateRunnerDrainingRequest\n\n\t// UpdateRunnerDrainingExecute executes the request\n\t//  @return Runner\n\tUpdateRunnerDrainingExecute(r RunnersAPIUpdateRunnerDrainingRequest) (*Runner, *http.Response, error)\n\n\t/*\n\tUpdateRunnerScheduling Update runner scheduling status\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Runner ID\n\t@return RunnersAPIUpdateRunnerSchedulingRequest\n\t*/\n\tUpdateRunnerScheduling(ctx context.Context, id string) RunnersAPIUpdateRunnerSchedulingRequest\n\n\t// UpdateRunnerSchedulingExecute executes the request\n\t//  @return Runner\n\tUpdateRunnerSchedulingExecute(r RunnersAPIUpdateRunnerSchedulingRequest) (*Runner, *http.Response, error)\n}\n\n// RunnersAPIService RunnersAPI service\ntype RunnersAPIService service\n\ntype RunnersAPICreateRunnerRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\tcreateRunner *CreateRunner\n\txDaytonaOrganizationID *string\n}\n\nfunc (r RunnersAPICreateRunnerRequest) CreateRunner(createRunner CreateRunner) RunnersAPICreateRunnerRequest {\n\tr.createRunner = &createRunner\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r RunnersAPICreateRunnerRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) RunnersAPICreateRunnerRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r RunnersAPICreateRunnerRequest) Execute() (*CreateRunnerResponse, *http.Response, error) {\n\treturn r.ApiService.CreateRunnerExecute(r)\n}\n\n/*\nCreateRunner Create runner\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return RunnersAPICreateRunnerRequest\n*/\nfunc (a *RunnersAPIService) CreateRunner(ctx context.Context) RunnersAPICreateRunnerRequest {\n\treturn RunnersAPICreateRunnerRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return CreateRunnerResponse\nfunc (a *RunnersAPIService) CreateRunnerExecute(r RunnersAPICreateRunnerRequest) (*CreateRunnerResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *CreateRunnerResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.CreateRunner\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createRunner == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createRunner is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createRunner\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype RunnersAPIDeleteRunnerRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r RunnersAPIDeleteRunnerRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) RunnersAPIDeleteRunnerRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r RunnersAPIDeleteRunnerRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteRunnerExecute(r)\n}\n\n/*\nDeleteRunner Delete runner\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Runner ID\n @return RunnersAPIDeleteRunnerRequest\n*/\nfunc (a *RunnersAPIService) DeleteRunner(ctx context.Context, id string) RunnersAPIDeleteRunnerRequest {\n\treturn RunnersAPIDeleteRunnerRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *RunnersAPIService) DeleteRunnerExecute(r RunnersAPIDeleteRunnerRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.DeleteRunner\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype RunnersAPIGetInfoForAuthenticatedRunnerRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n}\n\nfunc (r RunnersAPIGetInfoForAuthenticatedRunnerRequest) Execute() (*RunnerFull, *http.Response, error) {\n\treturn r.ApiService.GetInfoForAuthenticatedRunnerExecute(r)\n}\n\n/*\nGetInfoForAuthenticatedRunner Get info for authenticated runner\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return RunnersAPIGetInfoForAuthenticatedRunnerRequest\n*/\nfunc (a *RunnersAPIService) GetInfoForAuthenticatedRunner(ctx context.Context) RunnersAPIGetInfoForAuthenticatedRunnerRequest {\n\treturn RunnersAPIGetInfoForAuthenticatedRunnerRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return RunnerFull\nfunc (a *RunnersAPIService) GetInfoForAuthenticatedRunnerExecute(r RunnersAPIGetInfoForAuthenticatedRunnerRequest) (*RunnerFull, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RunnerFull\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.GetInfoForAuthenticatedRunner\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/me\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype RunnersAPIGetRunnerByIdRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r RunnersAPIGetRunnerByIdRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) RunnersAPIGetRunnerByIdRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r RunnersAPIGetRunnerByIdRequest) Execute() (*Runner, *http.Response, error) {\n\treturn r.ApiService.GetRunnerByIdExecute(r)\n}\n\n/*\nGetRunnerById Get runner by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Runner ID\n @return RunnersAPIGetRunnerByIdRequest\n*/\nfunc (a *RunnersAPIService) GetRunnerById(ctx context.Context, id string) RunnersAPIGetRunnerByIdRequest {\n\treturn RunnersAPIGetRunnerByIdRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return Runner\nfunc (a *RunnersAPIService) GetRunnerByIdExecute(r RunnersAPIGetRunnerByIdRequest) (*Runner, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Runner\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.GetRunnerById\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype RunnersAPIGetRunnerBySandboxIdRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\tsandboxId string\n}\n\nfunc (r RunnersAPIGetRunnerBySandboxIdRequest) Execute() (*RunnerFull, *http.Response, error) {\n\treturn r.ApiService.GetRunnerBySandboxIdExecute(r)\n}\n\n/*\nGetRunnerBySandboxId Get runner by sandbox ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return RunnersAPIGetRunnerBySandboxIdRequest\n*/\nfunc (a *RunnersAPIService) GetRunnerBySandboxId(ctx context.Context, sandboxId string) RunnersAPIGetRunnerBySandboxIdRequest {\n\treturn RunnersAPIGetRunnerBySandboxIdRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return RunnerFull\nfunc (a *RunnersAPIService) GetRunnerBySandboxIdExecute(r RunnersAPIGetRunnerBySandboxIdRequest) (*RunnerFull, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RunnerFull\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.GetRunnerBySandboxId\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/by-sandbox/{sandboxId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype RunnersAPIGetRunnerFullByIdRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\tid string\n}\n\nfunc (r RunnersAPIGetRunnerFullByIdRequest) Execute() (*RunnerFull, *http.Response, error) {\n\treturn r.ApiService.GetRunnerFullByIdExecute(r)\n}\n\n/*\nGetRunnerFullById Get runner by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Runner ID\n @return RunnersAPIGetRunnerFullByIdRequest\n*/\nfunc (a *RunnersAPIService) GetRunnerFullById(ctx context.Context, id string) RunnersAPIGetRunnerFullByIdRequest {\n\treturn RunnersAPIGetRunnerFullByIdRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return RunnerFull\nfunc (a *RunnersAPIService) GetRunnerFullByIdExecute(r RunnersAPIGetRunnerFullByIdRequest) (*RunnerFull, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RunnerFull\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.GetRunnerFullById\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/{id}/full\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype RunnersAPIGetRunnersBySnapshotRefRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\tref *string\n}\n\n// Snapshot ref\nfunc (r RunnersAPIGetRunnersBySnapshotRefRequest) Ref(ref string) RunnersAPIGetRunnersBySnapshotRefRequest {\n\tr.ref = &ref\n\treturn r\n}\n\nfunc (r RunnersAPIGetRunnersBySnapshotRefRequest) Execute() ([]RunnerSnapshotDto, *http.Response, error) {\n\treturn r.ApiService.GetRunnersBySnapshotRefExecute(r)\n}\n\n/*\nGetRunnersBySnapshotRef Get runners by snapshot ref\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return RunnersAPIGetRunnersBySnapshotRefRequest\n*/\nfunc (a *RunnersAPIService) GetRunnersBySnapshotRef(ctx context.Context) RunnersAPIGetRunnersBySnapshotRefRequest {\n\treturn RunnersAPIGetRunnersBySnapshotRefRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []RunnerSnapshotDto\nfunc (a *RunnersAPIService) GetRunnersBySnapshotRefExecute(r RunnersAPIGetRunnersBySnapshotRefRequest) ([]RunnerSnapshotDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []RunnerSnapshotDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.GetRunnersBySnapshotRef\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/by-snapshot-ref\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.ref == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"ref is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"ref\", r.ref, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype RunnersAPIListRunnersRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r RunnersAPIListRunnersRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) RunnersAPIListRunnersRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r RunnersAPIListRunnersRequest) Execute() ([]Runner, *http.Response, error) {\n\treturn r.ApiService.ListRunnersExecute(r)\n}\n\n/*\nListRunners List all runners\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return RunnersAPIListRunnersRequest\n*/\nfunc (a *RunnersAPIService) ListRunners(ctx context.Context) RunnersAPIListRunnersRequest {\n\treturn RunnersAPIListRunnersRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []Runner\nfunc (a *RunnersAPIService) ListRunnersExecute(r RunnersAPIListRunnersRequest) ([]Runner, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Runner\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.ListRunners\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype RunnersAPIRunnerHealthcheckRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\trunnerHealthcheck *RunnerHealthcheck\n}\n\nfunc (r RunnersAPIRunnerHealthcheckRequest) RunnerHealthcheck(runnerHealthcheck RunnerHealthcheck) RunnersAPIRunnerHealthcheckRequest {\n\tr.runnerHealthcheck = &runnerHealthcheck\n\treturn r\n}\n\nfunc (r RunnersAPIRunnerHealthcheckRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.RunnerHealthcheckExecute(r)\n}\n\n/*\nRunnerHealthcheck Runner healthcheck\n\nEndpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return RunnersAPIRunnerHealthcheckRequest\n*/\nfunc (a *RunnersAPIService) RunnerHealthcheck(ctx context.Context) RunnersAPIRunnerHealthcheckRequest {\n\treturn RunnersAPIRunnerHealthcheckRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\nfunc (a *RunnersAPIService) RunnerHealthcheckExecute(r RunnersAPIRunnerHealthcheckRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.RunnerHealthcheck\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/healthcheck\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.runnerHealthcheck == nil {\n\t\treturn nil, reportError(\"runnerHealthcheck is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.runnerHealthcheck\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype RunnersAPIUpdateRunnerDrainingRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r RunnersAPIUpdateRunnerDrainingRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) RunnersAPIUpdateRunnerDrainingRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r RunnersAPIUpdateRunnerDrainingRequest) Execute() (*Runner, *http.Response, error) {\n\treturn r.ApiService.UpdateRunnerDrainingExecute(r)\n}\n\n/*\nUpdateRunnerDraining Update runner draining status\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Runner ID\n @return RunnersAPIUpdateRunnerDrainingRequest\n*/\nfunc (a *RunnersAPIService) UpdateRunnerDraining(ctx context.Context, id string) RunnersAPIUpdateRunnerDrainingRequest {\n\treturn RunnersAPIUpdateRunnerDrainingRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return Runner\nfunc (a *RunnersAPIService) UpdateRunnerDrainingExecute(r RunnersAPIUpdateRunnerDrainingRequest) (*Runner, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Runner\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.UpdateRunnerDraining\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/{id}/draining\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype RunnersAPIUpdateRunnerSchedulingRequest struct {\n\tctx context.Context\n\tApiService RunnersAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r RunnersAPIUpdateRunnerSchedulingRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) RunnersAPIUpdateRunnerSchedulingRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r RunnersAPIUpdateRunnerSchedulingRequest) Execute() (*Runner, *http.Response, error) {\n\treturn r.ApiService.UpdateRunnerSchedulingExecute(r)\n}\n\n/*\nUpdateRunnerScheduling Update runner scheduling status\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Runner ID\n @return RunnersAPIUpdateRunnerSchedulingRequest\n*/\nfunc (a *RunnersAPIService) UpdateRunnerScheduling(ctx context.Context, id string) RunnersAPIUpdateRunnerSchedulingRequest {\n\treturn RunnersAPIUpdateRunnerSchedulingRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return Runner\nfunc (a *RunnersAPIService) UpdateRunnerSchedulingExecute(r RunnersAPIUpdateRunnerSchedulingRequest) (*Runner, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Runner\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"RunnersAPIService.UpdateRunnerScheduling\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/runners/{id}/scheduling\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_sandbox.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\t\"reflect\"\n)\n\n\ntype SandboxAPI interface {\n\n\t/*\n\tArchiveSandbox Archive sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName\n\t@return SandboxAPIArchiveSandboxRequest\n\t*/\n\tArchiveSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIArchiveSandboxRequest\n\n\t// ArchiveSandboxExecute executes the request\n\t//  @return Sandbox\n\tArchiveSandboxExecute(r SandboxAPIArchiveSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tCreateBackup Create sandbox backup\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPICreateBackupRequest\n\t*/\n\tCreateBackup(ctx context.Context, sandboxIdOrName string) SandboxAPICreateBackupRequest\n\n\t// CreateBackupExecute executes the request\n\t//  @return Sandbox\n\tCreateBackupExecute(r SandboxAPICreateBackupRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tCreateSandbox Create a new sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return SandboxAPICreateSandboxRequest\n\t*/\n\tCreateSandbox(ctx context.Context) SandboxAPICreateSandboxRequest\n\n\t// CreateSandboxExecute executes the request\n\t//  @return Sandbox\n\tCreateSandboxExecute(r SandboxAPICreateSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tCreateSshAccess Create SSH access for sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPICreateSshAccessRequest\n\t*/\n\tCreateSshAccess(ctx context.Context, sandboxIdOrName string) SandboxAPICreateSshAccessRequest\n\n\t// CreateSshAccessExecute executes the request\n\t//  @return SshAccessDto\n\tCreateSshAccessExecute(r SandboxAPICreateSshAccessRequest) (*SshAccessDto, *http.Response, error)\n\n\t/*\n\tDeleteSandbox Delete sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIDeleteSandboxRequest\n\t*/\n\tDeleteSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIDeleteSandboxRequest\n\n\t// DeleteSandboxExecute executes the request\n\t//  @return Sandbox\n\tDeleteSandboxExecute(r SandboxAPIDeleteSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tExpireSignedPortPreviewUrl Expire signed preview URL for a sandbox port\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@param port Port number to expire signed preview URL for\n\t@param token Token to expire signed preview URL for\n\t@return SandboxAPIExpireSignedPortPreviewUrlRequest\n\t*/\n\tExpireSignedPortPreviewUrl(ctx context.Context, sandboxIdOrName string, port int32, token string) SandboxAPIExpireSignedPortPreviewUrlRequest\n\n\t// ExpireSignedPortPreviewUrlExecute executes the request\n\tExpireSignedPortPreviewUrlExecute(r SandboxAPIExpireSignedPortPreviewUrlRequest) (*http.Response, error)\n\n\t/*\n\tGetBuildLogs Get build logs\n\n\tThis endpoint is deprecated. Use `getBuildLogsUrl` instead.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIGetBuildLogsRequest\n\n\tDeprecated\n\t*/\n\tGetBuildLogs(ctx context.Context, sandboxIdOrName string) SandboxAPIGetBuildLogsRequest\n\n\t// GetBuildLogsExecute executes the request\n\t// Deprecated\n\tGetBuildLogsExecute(r SandboxAPIGetBuildLogsRequest) (*http.Response, error)\n\n\t/*\n\tGetBuildLogsUrl Get build logs URL\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIGetBuildLogsUrlRequest\n\t*/\n\tGetBuildLogsUrl(ctx context.Context, sandboxIdOrName string) SandboxAPIGetBuildLogsUrlRequest\n\n\t// GetBuildLogsUrlExecute executes the request\n\t//  @return Url\n\tGetBuildLogsUrlExecute(r SandboxAPIGetBuildLogsUrlRequest) (*Url, *http.Response, error)\n\n\t/*\n\tGetPortPreviewUrl Get preview URL for a sandbox port\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@param port Port number to get preview URL for\n\t@return SandboxAPIGetPortPreviewUrlRequest\n\t*/\n\tGetPortPreviewUrl(ctx context.Context, sandboxIdOrName string, port float32) SandboxAPIGetPortPreviewUrlRequest\n\n\t// GetPortPreviewUrlExecute executes the request\n\t//  @return PortPreviewUrl\n\tGetPortPreviewUrlExecute(r SandboxAPIGetPortPreviewUrlRequest) (*PortPreviewUrl, *http.Response, error)\n\n\t/*\n\tGetSandbox Get sandbox details\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIGetSandboxRequest\n\t*/\n\tGetSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIGetSandboxRequest\n\n\t// GetSandboxExecute executes the request\n\t//  @return Sandbox\n\tGetSandboxExecute(r SandboxAPIGetSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tGetSandboxLogs Get sandbox logs\n\n\tRetrieve OTEL logs for a sandbox within a time range\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@return SandboxAPIGetSandboxLogsRequest\n\t*/\n\tGetSandboxLogs(ctx context.Context, sandboxId string) SandboxAPIGetSandboxLogsRequest\n\n\t// GetSandboxLogsExecute executes the request\n\t//  @return PaginatedLogs\n\tGetSandboxLogsExecute(r SandboxAPIGetSandboxLogsRequest) (*PaginatedLogs, *http.Response, error)\n\n\t/*\n\tGetSandboxMetrics Get sandbox metrics\n\n\tRetrieve OTEL metrics for a sandbox within a time range\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@return SandboxAPIGetSandboxMetricsRequest\n\t*/\n\tGetSandboxMetrics(ctx context.Context, sandboxId string) SandboxAPIGetSandboxMetricsRequest\n\n\t// GetSandboxMetricsExecute executes the request\n\t//  @return MetricsResponse\n\tGetSandboxMetricsExecute(r SandboxAPIGetSandboxMetricsRequest) (*MetricsResponse, *http.Response, error)\n\n\t/*\n\tGetSandboxTraceSpans Get trace spans\n\n\tRetrieve all spans for a specific trace\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@param traceId ID of the trace\n\t@return SandboxAPIGetSandboxTraceSpansRequest\n\t*/\n\tGetSandboxTraceSpans(ctx context.Context, sandboxId string, traceId string) SandboxAPIGetSandboxTraceSpansRequest\n\n\t// GetSandboxTraceSpansExecute executes the request\n\t//  @return []TraceSpan\n\tGetSandboxTraceSpansExecute(r SandboxAPIGetSandboxTraceSpansRequest) ([]TraceSpan, *http.Response, error)\n\n\t/*\n\tGetSandboxTraces Get sandbox traces\n\n\tRetrieve OTEL traces for a sandbox within a time range\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@return SandboxAPIGetSandboxTracesRequest\n\t*/\n\tGetSandboxTraces(ctx context.Context, sandboxId string) SandboxAPIGetSandboxTracesRequest\n\n\t// GetSandboxTracesExecute executes the request\n\t//  @return PaginatedTraces\n\tGetSandboxTracesExecute(r SandboxAPIGetSandboxTracesRequest) (*PaginatedTraces, *http.Response, error)\n\n\t/*\n\tGetSandboxesForRunner Get sandboxes for the authenticated runner\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return SandboxAPIGetSandboxesForRunnerRequest\n\t*/\n\tGetSandboxesForRunner(ctx context.Context) SandboxAPIGetSandboxesForRunnerRequest\n\n\t// GetSandboxesForRunnerExecute executes the request\n\t//  @return []Sandbox\n\tGetSandboxesForRunnerExecute(r SandboxAPIGetSandboxesForRunnerRequest) ([]Sandbox, *http.Response, error)\n\n\t/*\n\tGetSignedPortPreviewUrl Get signed preview URL for a sandbox port\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@param port Port number to get signed preview URL for\n\t@return SandboxAPIGetSignedPortPreviewUrlRequest\n\t*/\n\tGetSignedPortPreviewUrl(ctx context.Context, sandboxIdOrName string, port int32) SandboxAPIGetSignedPortPreviewUrlRequest\n\n\t// GetSignedPortPreviewUrlExecute executes the request\n\t//  @return SignedPortPreviewUrl\n\tGetSignedPortPreviewUrlExecute(r SandboxAPIGetSignedPortPreviewUrlRequest) (*SignedPortPreviewUrl, *http.Response, error)\n\n\t/*\n\tGetToolboxProxyUrl Get toolbox proxy URL for a sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@return SandboxAPIGetToolboxProxyUrlRequest\n\t*/\n\tGetToolboxProxyUrl(ctx context.Context, sandboxId string) SandboxAPIGetToolboxProxyUrlRequest\n\n\t// GetToolboxProxyUrlExecute executes the request\n\t//  @return ToolboxProxyUrl\n\tGetToolboxProxyUrlExecute(r SandboxAPIGetToolboxProxyUrlRequest) (*ToolboxProxyUrl, *http.Response, error)\n\n\t/*\n\tListSandboxes List all sandboxes\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return SandboxAPIListSandboxesRequest\n\t*/\n\tListSandboxes(ctx context.Context) SandboxAPIListSandboxesRequest\n\n\t// ListSandboxesExecute executes the request\n\t//  @return []Sandbox\n\tListSandboxesExecute(r SandboxAPIListSandboxesRequest) ([]Sandbox, *http.Response, error)\n\n\t/*\n\tListSandboxesPaginated List all sandboxes paginated\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return SandboxAPIListSandboxesPaginatedRequest\n\t*/\n\tListSandboxesPaginated(ctx context.Context) SandboxAPIListSandboxesPaginatedRequest\n\n\t// ListSandboxesPaginatedExecute executes the request\n\t//  @return PaginatedSandboxes\n\tListSandboxesPaginatedExecute(r SandboxAPIListSandboxesPaginatedRequest) (*PaginatedSandboxes, *http.Response, error)\n\n\t/*\n\tRecoverSandbox Recover sandbox from error state\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIRecoverSandboxRequest\n\t*/\n\tRecoverSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIRecoverSandboxRequest\n\n\t// RecoverSandboxExecute executes the request\n\t//  @return Sandbox\n\tRecoverSandboxExecute(r SandboxAPIRecoverSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tReplaceLabels Replace sandbox labels\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIReplaceLabelsRequest\n\t*/\n\tReplaceLabels(ctx context.Context, sandboxIdOrName string) SandboxAPIReplaceLabelsRequest\n\n\t// ReplaceLabelsExecute executes the request\n\t//  @return SandboxLabels\n\tReplaceLabelsExecute(r SandboxAPIReplaceLabelsRequest) (*SandboxLabels, *http.Response, error)\n\n\t/*\n\tResizeSandbox Resize sandbox resources\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIResizeSandboxRequest\n\t*/\n\tResizeSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIResizeSandboxRequest\n\n\t// ResizeSandboxExecute executes the request\n\t//  @return Sandbox\n\tResizeSandboxExecute(r SandboxAPIResizeSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tRevokeSshAccess Revoke SSH access for sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIRevokeSshAccessRequest\n\t*/\n\tRevokeSshAccess(ctx context.Context, sandboxIdOrName string) SandboxAPIRevokeSshAccessRequest\n\n\t// RevokeSshAccessExecute executes the request\n\t//  @return Sandbox\n\tRevokeSshAccessExecute(r SandboxAPIRevokeSshAccessRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tSetAutoArchiveInterval Set sandbox auto-archive interval\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@param interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n\t@return SandboxAPISetAutoArchiveIntervalRequest\n\t*/\n\tSetAutoArchiveInterval(ctx context.Context, sandboxIdOrName string, interval float32) SandboxAPISetAutoArchiveIntervalRequest\n\n\t// SetAutoArchiveIntervalExecute executes the request\n\t//  @return Sandbox\n\tSetAutoArchiveIntervalExecute(r SandboxAPISetAutoArchiveIntervalRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tSetAutoDeleteInterval Set sandbox auto-delete interval\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@param interval Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n\t@return SandboxAPISetAutoDeleteIntervalRequest\n\t*/\n\tSetAutoDeleteInterval(ctx context.Context, sandboxIdOrName string, interval float32) SandboxAPISetAutoDeleteIntervalRequest\n\n\t// SetAutoDeleteIntervalExecute executes the request\n\t//  @return Sandbox\n\tSetAutoDeleteIntervalExecute(r SandboxAPISetAutoDeleteIntervalRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tSetAutostopInterval Set sandbox auto-stop interval\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@param interval Auto-stop interval in minutes (0 to disable)\n\t@return SandboxAPISetAutostopIntervalRequest\n\t*/\n\tSetAutostopInterval(ctx context.Context, sandboxIdOrName string, interval float32) SandboxAPISetAutostopIntervalRequest\n\n\t// SetAutostopIntervalExecute executes the request\n\t//  @return Sandbox\n\tSetAutostopIntervalExecute(r SandboxAPISetAutostopIntervalRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tStartSandbox Start sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIStartSandboxRequest\n\t*/\n\tStartSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIStartSandboxRequest\n\n\t// StartSandboxExecute executes the request\n\t//  @return Sandbox\n\tStartSandboxExecute(r SandboxAPIStartSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tStopSandbox Stop sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@return SandboxAPIStopSandboxRequest\n\t*/\n\tStopSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIStopSandboxRequest\n\n\t// StopSandboxExecute executes the request\n\t//  @return Sandbox\n\tStopSandboxExecute(r SandboxAPIStopSandboxRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tUpdateLastActivity Update sandbox last activity\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@return SandboxAPIUpdateLastActivityRequest\n\t*/\n\tUpdateLastActivity(ctx context.Context, sandboxId string) SandboxAPIUpdateLastActivityRequest\n\n\t// UpdateLastActivityExecute executes the request\n\tUpdateLastActivityExecute(r SandboxAPIUpdateLastActivityRequest) (*http.Response, error)\n\n\t/*\n\tUpdatePublicStatus Update public status\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxIdOrName ID or name of the sandbox\n\t@param isPublic Public status to set\n\t@return SandboxAPIUpdatePublicStatusRequest\n\t*/\n\tUpdatePublicStatus(ctx context.Context, sandboxIdOrName string, isPublic bool) SandboxAPIUpdatePublicStatusRequest\n\n\t// UpdatePublicStatusExecute executes the request\n\t//  @return Sandbox\n\tUpdatePublicStatusExecute(r SandboxAPIUpdatePublicStatusRequest) (*Sandbox, *http.Response, error)\n\n\t/*\n\tUpdateSandboxState Update sandbox state\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId ID of the sandbox\n\t@return SandboxAPIUpdateSandboxStateRequest\n\t*/\n\tUpdateSandboxState(ctx context.Context, sandboxId string) SandboxAPIUpdateSandboxStateRequest\n\n\t// UpdateSandboxStateExecute executes the request\n\tUpdateSandboxStateExecute(r SandboxAPIUpdateSandboxStateRequest) (*http.Response, error)\n\n\t/*\n\tValidateSshAccess Validate SSH access for sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return SandboxAPIValidateSshAccessRequest\n\t*/\n\tValidateSshAccess(ctx context.Context) SandboxAPIValidateSshAccessRequest\n\n\t// ValidateSshAccessExecute executes the request\n\t//  @return SshAccessValidationDto\n\tValidateSshAccessExecute(r SandboxAPIValidateSshAccessRequest) (*SshAccessValidationDto, *http.Response, error)\n}\n\n// SandboxAPIService SandboxAPI service\ntype SandboxAPIService service\n\ntype SandboxAPIArchiveSandboxRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIArchiveSandboxRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIArchiveSandboxRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIArchiveSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.ArchiveSandboxExecute(r)\n}\n\n/*\nArchiveSandbox Archive sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName\n @return SandboxAPIArchiveSandboxRequest\n*/\nfunc (a *SandboxAPIService) ArchiveSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIArchiveSandboxRequest {\n\treturn SandboxAPIArchiveSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) ArchiveSandboxExecute(r SandboxAPIArchiveSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.ArchiveSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/archive\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPICreateBackupRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPICreateBackupRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPICreateBackupRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPICreateBackupRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.CreateBackupExecute(r)\n}\n\n/*\nCreateBackup Create sandbox backup\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPICreateBackupRequest\n*/\nfunc (a *SandboxAPIService) CreateBackup(ctx context.Context, sandboxIdOrName string) SandboxAPICreateBackupRequest {\n\treturn SandboxAPICreateBackupRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) CreateBackupExecute(r SandboxAPICreateBackupRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.CreateBackup\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/backup\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPICreateSandboxRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tcreateSandbox *CreateSandbox\n\txDaytonaOrganizationID *string\n}\n\nfunc (r SandboxAPICreateSandboxRequest) CreateSandbox(createSandbox CreateSandbox) SandboxAPICreateSandboxRequest {\n\tr.createSandbox = &createSandbox\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPICreateSandboxRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPICreateSandboxRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPICreateSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.CreateSandboxExecute(r)\n}\n\n/*\nCreateSandbox Create a new sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return SandboxAPICreateSandboxRequest\n*/\nfunc (a *SandboxAPIService) CreateSandbox(ctx context.Context) SandboxAPICreateSandboxRequest {\n\treturn SandboxAPICreateSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) CreateSandboxExecute(r SandboxAPICreateSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.CreateSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createSandbox == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createSandbox is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createSandbox\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPICreateSshAccessRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n\texpiresInMinutes *float32\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPICreateSshAccessRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPICreateSshAccessRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Expiration time in minutes (default: 60)\nfunc (r SandboxAPICreateSshAccessRequest) ExpiresInMinutes(expiresInMinutes float32) SandboxAPICreateSshAccessRequest {\n\tr.expiresInMinutes = &expiresInMinutes\n\treturn r\n}\n\nfunc (r SandboxAPICreateSshAccessRequest) Execute() (*SshAccessDto, *http.Response, error) {\n\treturn r.ApiService.CreateSshAccessExecute(r)\n}\n\n/*\nCreateSshAccess Create SSH access for sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPICreateSshAccessRequest\n*/\nfunc (a *SandboxAPIService) CreateSshAccess(ctx context.Context, sandboxIdOrName string) SandboxAPICreateSshAccessRequest {\n\treturn SandboxAPICreateSshAccessRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return SshAccessDto\nfunc (a *SandboxAPIService) CreateSshAccessExecute(r SandboxAPICreateSshAccessRequest) (*SshAccessDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SshAccessDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.CreateSshAccess\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/ssh-access\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.expiresInMinutes != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"expiresInMinutes\", r.expiresInMinutes, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIDeleteSandboxRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIDeleteSandboxRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIDeleteSandboxRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIDeleteSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.DeleteSandboxExecute(r)\n}\n\n/*\nDeleteSandbox Delete sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIDeleteSandboxRequest\n*/\nfunc (a *SandboxAPIService) DeleteSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIDeleteSandboxRequest {\n\treturn SandboxAPIDeleteSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) DeleteSandboxExecute(r SandboxAPIDeleteSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.DeleteSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIExpireSignedPortPreviewUrlRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tport int32\n\ttoken string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIExpireSignedPortPreviewUrlRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIExpireSignedPortPreviewUrlRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIExpireSignedPortPreviewUrlRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.ExpireSignedPortPreviewUrlExecute(r)\n}\n\n/*\nExpireSignedPortPreviewUrl Expire signed preview URL for a sandbox port\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @param port Port number to expire signed preview URL for\n @param token Token to expire signed preview URL for\n @return SandboxAPIExpireSignedPortPreviewUrlRequest\n*/\nfunc (a *SandboxAPIService) ExpireSignedPortPreviewUrl(ctx context.Context, sandboxIdOrName string, port int32, token string) SandboxAPIExpireSignedPortPreviewUrlRequest {\n\treturn SandboxAPIExpireSignedPortPreviewUrlRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t\tport: port,\n\t\ttoken: token,\n\t}\n}\n\n// Execute executes the request\nfunc (a *SandboxAPIService) ExpireSignedPortPreviewUrlExecute(r SandboxAPIExpireSignedPortPreviewUrlRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.ExpireSignedPortPreviewUrl\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url/{token}/expire\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"port\"+\"}\", url.PathEscape(parameterValueToString(r.port, \"port\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"token\"+\"}\", url.PathEscape(parameterValueToString(r.token, \"token\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetBuildLogsRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n\tfollow *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetBuildLogsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetBuildLogsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Whether to follow the logs stream\nfunc (r SandboxAPIGetBuildLogsRequest) Follow(follow bool) SandboxAPIGetBuildLogsRequest {\n\tr.follow = &follow\n\treturn r\n}\n\nfunc (r SandboxAPIGetBuildLogsRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GetBuildLogsExecute(r)\n}\n\n/*\nGetBuildLogs Get build logs\n\nThis endpoint is deprecated. Use `getBuildLogsUrl` instead.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIGetBuildLogsRequest\n\nDeprecated\n*/\nfunc (a *SandboxAPIService) GetBuildLogs(ctx context.Context, sandboxIdOrName string) SandboxAPIGetBuildLogsRequest {\n\treturn SandboxAPIGetBuildLogsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *SandboxAPIService) GetBuildLogsExecute(r SandboxAPIGetBuildLogsRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetBuildLogs\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/build-logs\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.follow != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"follow\", r.follow, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetBuildLogsUrlRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetBuildLogsUrlRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetBuildLogsUrlRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIGetBuildLogsUrlRequest) Execute() (*Url, *http.Response, error) {\n\treturn r.ApiService.GetBuildLogsUrlExecute(r)\n}\n\n/*\nGetBuildLogsUrl Get build logs URL\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIGetBuildLogsUrlRequest\n*/\nfunc (a *SandboxAPIService) GetBuildLogsUrl(ctx context.Context, sandboxIdOrName string) SandboxAPIGetBuildLogsUrlRequest {\n\treturn SandboxAPIGetBuildLogsUrlRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Url\nfunc (a *SandboxAPIService) GetBuildLogsUrlExecute(r SandboxAPIGetBuildLogsUrlRequest) (*Url, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Url\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetBuildLogsUrl\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/build-logs-url\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetPortPreviewUrlRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tport float32\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetPortPreviewUrlRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetPortPreviewUrlRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIGetPortPreviewUrlRequest) Execute() (*PortPreviewUrl, *http.Response, error) {\n\treturn r.ApiService.GetPortPreviewUrlExecute(r)\n}\n\n/*\nGetPortPreviewUrl Get preview URL for a sandbox port\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @param port Port number to get preview URL for\n @return SandboxAPIGetPortPreviewUrlRequest\n*/\nfunc (a *SandboxAPIService) GetPortPreviewUrl(ctx context.Context, sandboxIdOrName string, port float32) SandboxAPIGetPortPreviewUrlRequest {\n\treturn SandboxAPIGetPortPreviewUrlRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t\tport: port,\n\t}\n}\n\n// Execute executes the request\n//  @return PortPreviewUrl\nfunc (a *SandboxAPIService) GetPortPreviewUrlExecute(r SandboxAPIGetPortPreviewUrlRequest) (*PortPreviewUrl, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PortPreviewUrl\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetPortPreviewUrl\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/ports/{port}/preview-url\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"port\"+\"}\", url.PathEscape(parameterValueToString(r.port, \"port\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetSandboxRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n\tverbose *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetSandboxRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetSandboxRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Include verbose output\nfunc (r SandboxAPIGetSandboxRequest) Verbose(verbose bool) SandboxAPIGetSandboxRequest {\n\tr.verbose = &verbose\n\treturn r\n}\n\nfunc (r SandboxAPIGetSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.GetSandboxExecute(r)\n}\n\n/*\nGetSandbox Get sandbox details\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIGetSandboxRequest\n*/\nfunc (a *SandboxAPIService) GetSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIGetSandboxRequest {\n\treturn SandboxAPIGetSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) GetSandboxExecute(r SandboxAPIGetSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.verbose != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"verbose\", r.verbose, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetSandboxLogsRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxId string\n\tfrom *time.Time\n\tto *time.Time\n\txDaytonaOrganizationID *string\n\tpage *float32\n\tlimit *float32\n\tseverities *[]string\n\tsearch *string\n}\n\n// Start of time range (ISO 8601)\nfunc (r SandboxAPIGetSandboxLogsRequest) From(from time.Time) SandboxAPIGetSandboxLogsRequest {\n\tr.from = &from\n\treturn r\n}\n\n// End of time range (ISO 8601)\nfunc (r SandboxAPIGetSandboxLogsRequest) To(to time.Time) SandboxAPIGetSandboxLogsRequest {\n\tr.to = &to\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetSandboxLogsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetSandboxLogsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Page number (1-indexed)\nfunc (r SandboxAPIGetSandboxLogsRequest) Page(page float32) SandboxAPIGetSandboxLogsRequest {\n\tr.page = &page\n\treturn r\n}\n\n// Number of items per page\nfunc (r SandboxAPIGetSandboxLogsRequest) Limit(limit float32) SandboxAPIGetSandboxLogsRequest {\n\tr.limit = &limit\n\treturn r\n}\n\n// Filter by severity levels (DEBUG, INFO, WARN, ERROR)\nfunc (r SandboxAPIGetSandboxLogsRequest) Severities(severities []string) SandboxAPIGetSandboxLogsRequest {\n\tr.severities = &severities\n\treturn r\n}\n\n// Search in log body\nfunc (r SandboxAPIGetSandboxLogsRequest) Search(search string) SandboxAPIGetSandboxLogsRequest {\n\tr.search = &search\n\treturn r\n}\n\nfunc (r SandboxAPIGetSandboxLogsRequest) Execute() (*PaginatedLogs, *http.Response, error) {\n\treturn r.ApiService.GetSandboxLogsExecute(r)\n}\n\n/*\nGetSandboxLogs Get sandbox logs\n\nRetrieve OTEL logs for a sandbox within a time range\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @return SandboxAPIGetSandboxLogsRequest\n*/\nfunc (a *SandboxAPIService) GetSandboxLogs(ctx context.Context, sandboxId string) SandboxAPIGetSandboxLogsRequest {\n\treturn SandboxAPIGetSandboxLogsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return PaginatedLogs\nfunc (a *SandboxAPIService) GetSandboxLogsExecute(r SandboxAPIGetSandboxLogsRequest) (*PaginatedLogs, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PaginatedLogs\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetSandboxLogs\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxId}/telemetry/logs\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.from == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"from is required and must be specified\")\n\t}\n\tif r.to == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"to is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"from\", r.from, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"to\", r.to, \"form\", \"\")\n\tif r.page != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"page\", r.page, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 1\n\t\tr.page = &defaultValue\n\t}\n\tif r.limit != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"limit\", r.limit, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 100\n\t\tr.limit = &defaultValue\n\t}\n\tif r.severities != nil {\n\t\tt := *r.severities\n\t\tif reflect.TypeOf(t).Kind() == reflect.Slice {\n\t\t\ts := reflect.ValueOf(t)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"severities\", s.Index(i).Interface(), \"form\", \"multi\")\n\t\t\t}\n\t\t} else {\n\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"severities\", t, \"form\", \"multi\")\n\t\t}\n\t}\n\tif r.search != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"search\", r.search, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetSandboxMetricsRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxId string\n\tfrom *time.Time\n\tto *time.Time\n\txDaytonaOrganizationID *string\n\tmetricNames *[]string\n}\n\n// Start of time range (ISO 8601)\nfunc (r SandboxAPIGetSandboxMetricsRequest) From(from time.Time) SandboxAPIGetSandboxMetricsRequest {\n\tr.from = &from\n\treturn r\n}\n\n// End of time range (ISO 8601)\nfunc (r SandboxAPIGetSandboxMetricsRequest) To(to time.Time) SandboxAPIGetSandboxMetricsRequest {\n\tr.to = &to\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetSandboxMetricsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetSandboxMetricsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Filter by metric names\nfunc (r SandboxAPIGetSandboxMetricsRequest) MetricNames(metricNames []string) SandboxAPIGetSandboxMetricsRequest {\n\tr.metricNames = &metricNames\n\treturn r\n}\n\nfunc (r SandboxAPIGetSandboxMetricsRequest) Execute() (*MetricsResponse, *http.Response, error) {\n\treturn r.ApiService.GetSandboxMetricsExecute(r)\n}\n\n/*\nGetSandboxMetrics Get sandbox metrics\n\nRetrieve OTEL metrics for a sandbox within a time range\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @return SandboxAPIGetSandboxMetricsRequest\n*/\nfunc (a *SandboxAPIService) GetSandboxMetrics(ctx context.Context, sandboxId string) SandboxAPIGetSandboxMetricsRequest {\n\treturn SandboxAPIGetSandboxMetricsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return MetricsResponse\nfunc (a *SandboxAPIService) GetSandboxMetricsExecute(r SandboxAPIGetSandboxMetricsRequest) (*MetricsResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *MetricsResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetSandboxMetrics\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxId}/telemetry/metrics\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.from == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"from is required and must be specified\")\n\t}\n\tif r.to == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"to is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"from\", r.from, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"to\", r.to, \"form\", \"\")\n\tif r.metricNames != nil {\n\t\tt := *r.metricNames\n\t\tif reflect.TypeOf(t).Kind() == reflect.Slice {\n\t\t\ts := reflect.ValueOf(t)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"metricNames\", s.Index(i).Interface(), \"form\", \"multi\")\n\t\t\t}\n\t\t} else {\n\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"metricNames\", t, \"form\", \"multi\")\n\t\t}\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetSandboxTraceSpansRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxId string\n\ttraceId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetSandboxTraceSpansRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetSandboxTraceSpansRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIGetSandboxTraceSpansRequest) Execute() ([]TraceSpan, *http.Response, error) {\n\treturn r.ApiService.GetSandboxTraceSpansExecute(r)\n}\n\n/*\nGetSandboxTraceSpans Get trace spans\n\nRetrieve all spans for a specific trace\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @param traceId ID of the trace\n @return SandboxAPIGetSandboxTraceSpansRequest\n*/\nfunc (a *SandboxAPIService) GetSandboxTraceSpans(ctx context.Context, sandboxId string, traceId string) SandboxAPIGetSandboxTraceSpansRequest {\n\treturn SandboxAPIGetSandboxTraceSpansRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\ttraceId: traceId,\n\t}\n}\n\n// Execute executes the request\n//  @return []TraceSpan\nfunc (a *SandboxAPIService) GetSandboxTraceSpansExecute(r SandboxAPIGetSandboxTraceSpansRequest) ([]TraceSpan, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []TraceSpan\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetSandboxTraceSpans\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxId}/telemetry/traces/{traceId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"traceId\"+\"}\", url.PathEscape(parameterValueToString(r.traceId, \"traceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetSandboxTracesRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxId string\n\tfrom *time.Time\n\tto *time.Time\n\txDaytonaOrganizationID *string\n\tpage *float32\n\tlimit *float32\n}\n\n// Start of time range (ISO 8601)\nfunc (r SandboxAPIGetSandboxTracesRequest) From(from time.Time) SandboxAPIGetSandboxTracesRequest {\n\tr.from = &from\n\treturn r\n}\n\n// End of time range (ISO 8601)\nfunc (r SandboxAPIGetSandboxTracesRequest) To(to time.Time) SandboxAPIGetSandboxTracesRequest {\n\tr.to = &to\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetSandboxTracesRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetSandboxTracesRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Page number (1-indexed)\nfunc (r SandboxAPIGetSandboxTracesRequest) Page(page float32) SandboxAPIGetSandboxTracesRequest {\n\tr.page = &page\n\treturn r\n}\n\n// Number of items per page\nfunc (r SandboxAPIGetSandboxTracesRequest) Limit(limit float32) SandboxAPIGetSandboxTracesRequest {\n\tr.limit = &limit\n\treturn r\n}\n\nfunc (r SandboxAPIGetSandboxTracesRequest) Execute() (*PaginatedTraces, *http.Response, error) {\n\treturn r.ApiService.GetSandboxTracesExecute(r)\n}\n\n/*\nGetSandboxTraces Get sandbox traces\n\nRetrieve OTEL traces for a sandbox within a time range\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @return SandboxAPIGetSandboxTracesRequest\n*/\nfunc (a *SandboxAPIService) GetSandboxTraces(ctx context.Context, sandboxId string) SandboxAPIGetSandboxTracesRequest {\n\treturn SandboxAPIGetSandboxTracesRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return PaginatedTraces\nfunc (a *SandboxAPIService) GetSandboxTracesExecute(r SandboxAPIGetSandboxTracesRequest) (*PaginatedTraces, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PaginatedTraces\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetSandboxTraces\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxId}/telemetry/traces\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.from == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"from is required and must be specified\")\n\t}\n\tif r.to == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"to is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"from\", r.from, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"to\", r.to, \"form\", \"\")\n\tif r.page != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"page\", r.page, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 1\n\t\tr.page = &defaultValue\n\t}\n\tif r.limit != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"limit\", r.limit, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 100\n\t\tr.limit = &defaultValue\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetSandboxesForRunnerRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\txDaytonaOrganizationID *string\n\tstates *string\n\tskipReconcilingSandboxes *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetSandboxesForRunnerRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetSandboxesForRunnerRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Comma-separated list of sandbox states to filter by\nfunc (r SandboxAPIGetSandboxesForRunnerRequest) States(states string) SandboxAPIGetSandboxesForRunnerRequest {\n\tr.states = &states\n\treturn r\n}\n\n// Skip sandboxes where state differs from desired state\nfunc (r SandboxAPIGetSandboxesForRunnerRequest) SkipReconcilingSandboxes(skipReconcilingSandboxes bool) SandboxAPIGetSandboxesForRunnerRequest {\n\tr.skipReconcilingSandboxes = &skipReconcilingSandboxes\n\treturn r\n}\n\nfunc (r SandboxAPIGetSandboxesForRunnerRequest) Execute() ([]Sandbox, *http.Response, error) {\n\treturn r.ApiService.GetSandboxesForRunnerExecute(r)\n}\n\n/*\nGetSandboxesForRunner Get sandboxes for the authenticated runner\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return SandboxAPIGetSandboxesForRunnerRequest\n*/\nfunc (a *SandboxAPIService) GetSandboxesForRunner(ctx context.Context) SandboxAPIGetSandboxesForRunnerRequest {\n\treturn SandboxAPIGetSandboxesForRunnerRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []Sandbox\nfunc (a *SandboxAPIService) GetSandboxesForRunnerExecute(r SandboxAPIGetSandboxesForRunnerRequest) ([]Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetSandboxesForRunner\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/for-runner\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.states != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"states\", r.states, \"form\", \"\")\n\t}\n\tif r.skipReconcilingSandboxes != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"skipReconcilingSandboxes\", r.skipReconcilingSandboxes, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetSignedPortPreviewUrlRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tport int32\n\txDaytonaOrganizationID *string\n\texpiresInSeconds *int32\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetSignedPortPreviewUrlRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetSignedPortPreviewUrlRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Expiration time in seconds (default: 60 seconds)\nfunc (r SandboxAPIGetSignedPortPreviewUrlRequest) ExpiresInSeconds(expiresInSeconds int32) SandboxAPIGetSignedPortPreviewUrlRequest {\n\tr.expiresInSeconds = &expiresInSeconds\n\treturn r\n}\n\nfunc (r SandboxAPIGetSignedPortPreviewUrlRequest) Execute() (*SignedPortPreviewUrl, *http.Response, error) {\n\treturn r.ApiService.GetSignedPortPreviewUrlExecute(r)\n}\n\n/*\nGetSignedPortPreviewUrl Get signed preview URL for a sandbox port\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @param port Port number to get signed preview URL for\n @return SandboxAPIGetSignedPortPreviewUrlRequest\n*/\nfunc (a *SandboxAPIService) GetSignedPortPreviewUrl(ctx context.Context, sandboxIdOrName string, port int32) SandboxAPIGetSignedPortPreviewUrlRequest {\n\treturn SandboxAPIGetSignedPortPreviewUrlRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t\tport: port,\n\t}\n}\n\n// Execute executes the request\n//  @return SignedPortPreviewUrl\nfunc (a *SandboxAPIService) GetSignedPortPreviewUrlExecute(r SandboxAPIGetSignedPortPreviewUrlRequest) (*SignedPortPreviewUrl, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SignedPortPreviewUrl\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetSignedPortPreviewUrl\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"port\"+\"}\", url.PathEscape(parameterValueToString(r.port, \"port\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.expiresInSeconds != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"expiresInSeconds\", r.expiresInSeconds, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIGetToolboxProxyUrlRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIGetToolboxProxyUrlRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIGetToolboxProxyUrlRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIGetToolboxProxyUrlRequest) Execute() (*ToolboxProxyUrl, *http.Response, error) {\n\treturn r.ApiService.GetToolboxProxyUrlExecute(r)\n}\n\n/*\nGetToolboxProxyUrl Get toolbox proxy URL for a sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @return SandboxAPIGetToolboxProxyUrlRequest\n*/\nfunc (a *SandboxAPIService) GetToolboxProxyUrl(ctx context.Context, sandboxId string) SandboxAPIGetToolboxProxyUrlRequest {\n\treturn SandboxAPIGetToolboxProxyUrlRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ToolboxProxyUrl\nfunc (a *SandboxAPIService) GetToolboxProxyUrlExecute(r SandboxAPIGetToolboxProxyUrlRequest) (*ToolboxProxyUrl, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ToolboxProxyUrl\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.GetToolboxProxyUrl\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxId}/toolbox-proxy-url\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIListSandboxesRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\txDaytonaOrganizationID *string\n\tverbose *bool\n\tlabels *string\n\tincludeErroredDeleted *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIListSandboxesRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIListSandboxesRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Include verbose output\nfunc (r SandboxAPIListSandboxesRequest) Verbose(verbose bool) SandboxAPIListSandboxesRequest {\n\tr.verbose = &verbose\n\treturn r\n}\n\n// JSON encoded labels to filter by\nfunc (r SandboxAPIListSandboxesRequest) Labels(labels string) SandboxAPIListSandboxesRequest {\n\tr.labels = &labels\n\treturn r\n}\n\n// Include errored and deleted sandboxes\nfunc (r SandboxAPIListSandboxesRequest) IncludeErroredDeleted(includeErroredDeleted bool) SandboxAPIListSandboxesRequest {\n\tr.includeErroredDeleted = &includeErroredDeleted\n\treturn r\n}\n\nfunc (r SandboxAPIListSandboxesRequest) Execute() ([]Sandbox, *http.Response, error) {\n\treturn r.ApiService.ListSandboxesExecute(r)\n}\n\n/*\nListSandboxes List all sandboxes\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return SandboxAPIListSandboxesRequest\n*/\nfunc (a *SandboxAPIService) ListSandboxes(ctx context.Context) SandboxAPIListSandboxesRequest {\n\treturn SandboxAPIListSandboxesRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []Sandbox\nfunc (a *SandboxAPIService) ListSandboxesExecute(r SandboxAPIListSandboxesRequest) ([]Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.ListSandboxes\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.verbose != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"verbose\", r.verbose, \"form\", \"\")\n\t}\n\tif r.labels != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"labels\", r.labels, \"form\", \"\")\n\t}\n\tif r.includeErroredDeleted != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"includeErroredDeleted\", r.includeErroredDeleted, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIListSandboxesPaginatedRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\txDaytonaOrganizationID *string\n\tpage *float32\n\tlimit *float32\n\tid *string\n\tname *string\n\tlabels *string\n\tincludeErroredDeleted *bool\n\tstates *[]string\n\tsnapshots *[]string\n\tregions *[]string\n\tminCpu *float32\n\tmaxCpu *float32\n\tminMemoryGiB *float32\n\tmaxMemoryGiB *float32\n\tminDiskGiB *float32\n\tmaxDiskGiB *float32\n\tlastEventAfter *time.Time\n\tlastEventBefore *time.Time\n\tsort *string\n\torder *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIListSandboxesPaginatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Page number of the results\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Page(page float32) SandboxAPIListSandboxesPaginatedRequest {\n\tr.page = &page\n\treturn r\n}\n\n// Number of results per page\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Limit(limit float32) SandboxAPIListSandboxesPaginatedRequest {\n\tr.limit = &limit\n\treturn r\n}\n\n// Filter by partial ID match\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Id(id string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.id = &id\n\treturn r\n}\n\n// Filter by partial name match\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Name(name string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.name = &name\n\treturn r\n}\n\n// JSON encoded labels to filter by\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Labels(labels string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.labels = &labels\n\treturn r\n}\n\n// Include results with errored state and deleted desired state\nfunc (r SandboxAPIListSandboxesPaginatedRequest) IncludeErroredDeleted(includeErroredDeleted bool) SandboxAPIListSandboxesPaginatedRequest {\n\tr.includeErroredDeleted = &includeErroredDeleted\n\treturn r\n}\n\n// List of states to filter by\nfunc (r SandboxAPIListSandboxesPaginatedRequest) States(states []string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.states = &states\n\treturn r\n}\n\n// List of snapshot names to filter by\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Snapshots(snapshots []string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.snapshots = &snapshots\n\treturn r\n}\n\n// List of regions to filter by\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Regions(regions []string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.regions = &regions\n\treturn r\n}\n\n// Minimum CPU\nfunc (r SandboxAPIListSandboxesPaginatedRequest) MinCpu(minCpu float32) SandboxAPIListSandboxesPaginatedRequest {\n\tr.minCpu = &minCpu\n\treturn r\n}\n\n// Maximum CPU\nfunc (r SandboxAPIListSandboxesPaginatedRequest) MaxCpu(maxCpu float32) SandboxAPIListSandboxesPaginatedRequest {\n\tr.maxCpu = &maxCpu\n\treturn r\n}\n\n// Minimum memory in GiB\nfunc (r SandboxAPIListSandboxesPaginatedRequest) MinMemoryGiB(minMemoryGiB float32) SandboxAPIListSandboxesPaginatedRequest {\n\tr.minMemoryGiB = &minMemoryGiB\n\treturn r\n}\n\n// Maximum memory in GiB\nfunc (r SandboxAPIListSandboxesPaginatedRequest) MaxMemoryGiB(maxMemoryGiB float32) SandboxAPIListSandboxesPaginatedRequest {\n\tr.maxMemoryGiB = &maxMemoryGiB\n\treturn r\n}\n\n// Minimum disk space in GiB\nfunc (r SandboxAPIListSandboxesPaginatedRequest) MinDiskGiB(minDiskGiB float32) SandboxAPIListSandboxesPaginatedRequest {\n\tr.minDiskGiB = &minDiskGiB\n\treturn r\n}\n\n// Maximum disk space in GiB\nfunc (r SandboxAPIListSandboxesPaginatedRequest) MaxDiskGiB(maxDiskGiB float32) SandboxAPIListSandboxesPaginatedRequest {\n\tr.maxDiskGiB = &maxDiskGiB\n\treturn r\n}\n\n// Include items with last event after this timestamp\nfunc (r SandboxAPIListSandboxesPaginatedRequest) LastEventAfter(lastEventAfter time.Time) SandboxAPIListSandboxesPaginatedRequest {\n\tr.lastEventAfter = &lastEventAfter\n\treturn r\n}\n\n// Include items with last event before this timestamp\nfunc (r SandboxAPIListSandboxesPaginatedRequest) LastEventBefore(lastEventBefore time.Time) SandboxAPIListSandboxesPaginatedRequest {\n\tr.lastEventBefore = &lastEventBefore\n\treturn r\n}\n\n// Field to sort by\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Sort(sort string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.sort = &sort\n\treturn r\n}\n\n// Direction to sort by\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Order(order string) SandboxAPIListSandboxesPaginatedRequest {\n\tr.order = &order\n\treturn r\n}\n\nfunc (r SandboxAPIListSandboxesPaginatedRequest) Execute() (*PaginatedSandboxes, *http.Response, error) {\n\treturn r.ApiService.ListSandboxesPaginatedExecute(r)\n}\n\n/*\nListSandboxesPaginated List all sandboxes paginated\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return SandboxAPIListSandboxesPaginatedRequest\n*/\nfunc (a *SandboxAPIService) ListSandboxesPaginated(ctx context.Context) SandboxAPIListSandboxesPaginatedRequest {\n\treturn SandboxAPIListSandboxesPaginatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return PaginatedSandboxes\nfunc (a *SandboxAPIService) ListSandboxesPaginatedExecute(r SandboxAPIListSandboxesPaginatedRequest) (*PaginatedSandboxes, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PaginatedSandboxes\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.ListSandboxesPaginated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/paginated\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.page != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"page\", r.page, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 1\n\t\tr.page = &defaultValue\n\t}\n\tif r.limit != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"limit\", r.limit, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 100\n\t\tr.limit = &defaultValue\n\t}\n\tif r.id != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"id\", r.id, \"form\", \"\")\n\t}\n\tif r.name != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"name\", r.name, \"form\", \"\")\n\t}\n\tif r.labels != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"labels\", r.labels, \"form\", \"\")\n\t}\n\tif r.includeErroredDeleted != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"includeErroredDeleted\", r.includeErroredDeleted, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue bool = false\n\t\tr.includeErroredDeleted = &defaultValue\n\t}\n\tif r.states != nil {\n\t\tt := *r.states\n\t\tif reflect.TypeOf(t).Kind() == reflect.Slice {\n\t\t\ts := reflect.ValueOf(t)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"states\", s.Index(i).Interface(), \"form\", \"multi\")\n\t\t\t}\n\t\t} else {\n\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"states\", t, \"form\", \"multi\")\n\t\t}\n\t}\n\tif r.snapshots != nil {\n\t\tt := *r.snapshots\n\t\tif reflect.TypeOf(t).Kind() == reflect.Slice {\n\t\t\ts := reflect.ValueOf(t)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"snapshots\", s.Index(i).Interface(), \"form\", \"multi\")\n\t\t\t}\n\t\t} else {\n\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"snapshots\", t, \"form\", \"multi\")\n\t\t}\n\t}\n\tif r.regions != nil {\n\t\tt := *r.regions\n\t\tif reflect.TypeOf(t).Kind() == reflect.Slice {\n\t\t\ts := reflect.ValueOf(t)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"regions\", s.Index(i).Interface(), \"form\", \"multi\")\n\t\t\t}\n\t\t} else {\n\t\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"regions\", t, \"form\", \"multi\")\n\t\t}\n\t}\n\tif r.minCpu != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"minCpu\", r.minCpu, \"form\", \"\")\n\t}\n\tif r.maxCpu != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"maxCpu\", r.maxCpu, \"form\", \"\")\n\t}\n\tif r.minMemoryGiB != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"minMemoryGiB\", r.minMemoryGiB, \"form\", \"\")\n\t}\n\tif r.maxMemoryGiB != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"maxMemoryGiB\", r.maxMemoryGiB, \"form\", \"\")\n\t}\n\tif r.minDiskGiB != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"minDiskGiB\", r.minDiskGiB, \"form\", \"\")\n\t}\n\tif r.maxDiskGiB != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"maxDiskGiB\", r.maxDiskGiB, \"form\", \"\")\n\t}\n\tif r.lastEventAfter != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"lastEventAfter\", r.lastEventAfter, \"form\", \"\")\n\t}\n\tif r.lastEventBefore != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"lastEventBefore\", r.lastEventBefore, \"form\", \"\")\n\t}\n\tif r.sort != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"sort\", r.sort, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue string = \"createdAt\"\n\t\tr.sort = &defaultValue\n\t}\n\tif r.order != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"order\", r.order, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue string = \"desc\"\n\t\tr.order = &defaultValue\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIRecoverSandboxRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIRecoverSandboxRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIRecoverSandboxRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIRecoverSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.RecoverSandboxExecute(r)\n}\n\n/*\nRecoverSandbox Recover sandbox from error state\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIRecoverSandboxRequest\n*/\nfunc (a *SandboxAPIService) RecoverSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIRecoverSandboxRequest {\n\treturn SandboxAPIRecoverSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) RecoverSandboxExecute(r SandboxAPIRecoverSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.RecoverSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/recover\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIReplaceLabelsRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tsandboxLabels *SandboxLabels\n\txDaytonaOrganizationID *string\n}\n\nfunc (r SandboxAPIReplaceLabelsRequest) SandboxLabels(sandboxLabels SandboxLabels) SandboxAPIReplaceLabelsRequest {\n\tr.sandboxLabels = &sandboxLabels\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIReplaceLabelsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIReplaceLabelsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIReplaceLabelsRequest) Execute() (*SandboxLabels, *http.Response, error) {\n\treturn r.ApiService.ReplaceLabelsExecute(r)\n}\n\n/*\nReplaceLabels Replace sandbox labels\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIReplaceLabelsRequest\n*/\nfunc (a *SandboxAPIService) ReplaceLabels(ctx context.Context, sandboxIdOrName string) SandboxAPIReplaceLabelsRequest {\n\treturn SandboxAPIReplaceLabelsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return SandboxLabels\nfunc (a *SandboxAPIService) ReplaceLabelsExecute(r SandboxAPIReplaceLabelsRequest) (*SandboxLabels, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPut\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SandboxLabels\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.ReplaceLabels\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/labels\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.sandboxLabels == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"sandboxLabels is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.sandboxLabels\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIResizeSandboxRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tresizeSandbox *ResizeSandbox\n\txDaytonaOrganizationID *string\n}\n\nfunc (r SandboxAPIResizeSandboxRequest) ResizeSandbox(resizeSandbox ResizeSandbox) SandboxAPIResizeSandboxRequest {\n\tr.resizeSandbox = &resizeSandbox\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIResizeSandboxRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIResizeSandboxRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIResizeSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.ResizeSandboxExecute(r)\n}\n\n/*\nResizeSandbox Resize sandbox resources\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIResizeSandboxRequest\n*/\nfunc (a *SandboxAPIService) ResizeSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIResizeSandboxRequest {\n\treturn SandboxAPIResizeSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) ResizeSandboxExecute(r SandboxAPIResizeSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.ResizeSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/resize\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.resizeSandbox == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"resizeSandbox is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.resizeSandbox\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIRevokeSshAccessRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n\ttoken *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIRevokeSshAccessRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIRevokeSshAccessRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\nfunc (r SandboxAPIRevokeSshAccessRequest) Token(token string) SandboxAPIRevokeSshAccessRequest {\n\tr.token = &token\n\treturn r\n}\n\nfunc (r SandboxAPIRevokeSshAccessRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.RevokeSshAccessExecute(r)\n}\n\n/*\nRevokeSshAccess Revoke SSH access for sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIRevokeSshAccessRequest\n*/\nfunc (a *SandboxAPIService) RevokeSshAccess(ctx context.Context, sandboxIdOrName string) SandboxAPIRevokeSshAccessRequest {\n\treturn SandboxAPIRevokeSshAccessRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) RevokeSshAccessExecute(r SandboxAPIRevokeSshAccessRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.RevokeSshAccess\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/ssh-access\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.token != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"token\", r.token, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPISetAutoArchiveIntervalRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tinterval float32\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPISetAutoArchiveIntervalRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPISetAutoArchiveIntervalRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPISetAutoArchiveIntervalRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.SetAutoArchiveIntervalExecute(r)\n}\n\n/*\nSetAutoArchiveInterval Set sandbox auto-archive interval\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @param interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n @return SandboxAPISetAutoArchiveIntervalRequest\n*/\nfunc (a *SandboxAPIService) SetAutoArchiveInterval(ctx context.Context, sandboxIdOrName string, interval float32) SandboxAPISetAutoArchiveIntervalRequest {\n\treturn SandboxAPISetAutoArchiveIntervalRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t\tinterval: interval,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) SetAutoArchiveIntervalExecute(r SandboxAPISetAutoArchiveIntervalRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.SetAutoArchiveInterval\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/autoarchive/{interval}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"interval\"+\"}\", url.PathEscape(parameterValueToString(r.interval, \"interval\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPISetAutoDeleteIntervalRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tinterval float32\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPISetAutoDeleteIntervalRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPISetAutoDeleteIntervalRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPISetAutoDeleteIntervalRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.SetAutoDeleteIntervalExecute(r)\n}\n\n/*\nSetAutoDeleteInterval Set sandbox auto-delete interval\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @param interval Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n @return SandboxAPISetAutoDeleteIntervalRequest\n*/\nfunc (a *SandboxAPIService) SetAutoDeleteInterval(ctx context.Context, sandboxIdOrName string, interval float32) SandboxAPISetAutoDeleteIntervalRequest {\n\treturn SandboxAPISetAutoDeleteIntervalRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t\tinterval: interval,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) SetAutoDeleteIntervalExecute(r SandboxAPISetAutoDeleteIntervalRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.SetAutoDeleteInterval\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/autodelete/{interval}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"interval\"+\"}\", url.PathEscape(parameterValueToString(r.interval, \"interval\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPISetAutostopIntervalRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tinterval float32\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPISetAutostopIntervalRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPISetAutostopIntervalRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPISetAutostopIntervalRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.SetAutostopIntervalExecute(r)\n}\n\n/*\nSetAutostopInterval Set sandbox auto-stop interval\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @param interval Auto-stop interval in minutes (0 to disable)\n @return SandboxAPISetAutostopIntervalRequest\n*/\nfunc (a *SandboxAPIService) SetAutostopInterval(ctx context.Context, sandboxIdOrName string, interval float32) SandboxAPISetAutostopIntervalRequest {\n\treturn SandboxAPISetAutostopIntervalRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t\tinterval: interval,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) SetAutostopIntervalExecute(r SandboxAPISetAutostopIntervalRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.SetAutostopInterval\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/autostop/{interval}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"interval\"+\"}\", url.PathEscape(parameterValueToString(r.interval, \"interval\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIStartSandboxRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIStartSandboxRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIStartSandboxRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIStartSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.StartSandboxExecute(r)\n}\n\n/*\nStartSandbox Start sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIStartSandboxRequest\n*/\nfunc (a *SandboxAPIService) StartSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIStartSandboxRequest {\n\treturn SandboxAPIStartSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) StartSandboxExecute(r SandboxAPIStartSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.StartSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/start\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIStopSandboxRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIStopSandboxRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIStopSandboxRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIStopSandboxRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.StopSandboxExecute(r)\n}\n\n/*\nStopSandbox Stop sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @return SandboxAPIStopSandboxRequest\n*/\nfunc (a *SandboxAPIService) StopSandbox(ctx context.Context, sandboxIdOrName string) SandboxAPIStopSandboxRequest {\n\treturn SandboxAPIStopSandboxRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) StopSandboxExecute(r SandboxAPIStopSandboxRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.StopSandbox\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/stop\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIUpdateLastActivityRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIUpdateLastActivityRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIUpdateLastActivityRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIUpdateLastActivityRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UpdateLastActivityExecute(r)\n}\n\n/*\nUpdateLastActivity Update sandbox last activity\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @return SandboxAPIUpdateLastActivityRequest\n*/\nfunc (a *SandboxAPIService) UpdateLastActivity(ctx context.Context, sandboxId string) SandboxAPIUpdateLastActivityRequest {\n\treturn SandboxAPIUpdateLastActivityRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *SandboxAPIService) UpdateLastActivityExecute(r SandboxAPIUpdateLastActivityRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.UpdateLastActivity\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxId}/last-activity\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype SandboxAPIUpdatePublicStatusRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxIdOrName string\n\tisPublic bool\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIUpdatePublicStatusRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIUpdatePublicStatusRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIUpdatePublicStatusRequest) Execute() (*Sandbox, *http.Response, error) {\n\treturn r.ApiService.UpdatePublicStatusExecute(r)\n}\n\n/*\nUpdatePublicStatus Update public status\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxIdOrName ID or name of the sandbox\n @param isPublic Public status to set\n @return SandboxAPIUpdatePublicStatusRequest\n*/\nfunc (a *SandboxAPIService) UpdatePublicStatus(ctx context.Context, sandboxIdOrName string, isPublic bool) SandboxAPIUpdatePublicStatusRequest {\n\treturn SandboxAPIUpdatePublicStatusRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxIdOrName: sandboxIdOrName,\n\t\tisPublic: isPublic,\n\t}\n}\n\n// Execute executes the request\n//  @return Sandbox\nfunc (a *SandboxAPIService) UpdatePublicStatusExecute(r SandboxAPIUpdatePublicStatusRequest) (*Sandbox, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Sandbox\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.UpdatePublicStatus\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxIdOrName}/public/{isPublic}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxIdOrName\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxIdOrName, \"sandboxIdOrName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"isPublic\"+\"}\", url.PathEscape(parameterValueToString(r.isPublic, \"isPublic\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SandboxAPIUpdateSandboxStateRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\tsandboxId string\n\tupdateSandboxStateDto *UpdateSandboxStateDto\n\txDaytonaOrganizationID *string\n}\n\nfunc (r SandboxAPIUpdateSandboxStateRequest) UpdateSandboxStateDto(updateSandboxStateDto UpdateSandboxStateDto) SandboxAPIUpdateSandboxStateRequest {\n\tr.updateSandboxStateDto = &updateSandboxStateDto\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIUpdateSandboxStateRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIUpdateSandboxStateRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIUpdateSandboxStateRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UpdateSandboxStateExecute(r)\n}\n\n/*\nUpdateSandboxState Update sandbox state\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId ID of the sandbox\n @return SandboxAPIUpdateSandboxStateRequest\n*/\nfunc (a *SandboxAPIService) UpdateSandboxState(ctx context.Context, sandboxId string) SandboxAPIUpdateSandboxStateRequest {\n\treturn SandboxAPIUpdateSandboxStateRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *SandboxAPIService) UpdateSandboxStateExecute(r SandboxAPIUpdateSandboxStateRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPut\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.UpdateSandboxState\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/{sandboxId}/state\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.updateSandboxStateDto == nil {\n\t\treturn nil, reportError(\"updateSandboxStateDto is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.updateSandboxStateDto\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype SandboxAPIValidateSshAccessRequest struct {\n\tctx context.Context\n\tApiService SandboxAPI\n\ttoken *string\n\txDaytonaOrganizationID *string\n}\n\n// SSH access token to validate\nfunc (r SandboxAPIValidateSshAccessRequest) Token(token string) SandboxAPIValidateSshAccessRequest {\n\tr.token = &token\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SandboxAPIValidateSshAccessRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SandboxAPIValidateSshAccessRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SandboxAPIValidateSshAccessRequest) Execute() (*SshAccessValidationDto, *http.Response, error) {\n\treturn r.ApiService.ValidateSshAccessExecute(r)\n}\n\n/*\nValidateSshAccess Validate SSH access for sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return SandboxAPIValidateSshAccessRequest\n*/\nfunc (a *SandboxAPIService) ValidateSshAccess(ctx context.Context) SandboxAPIValidateSshAccessRequest {\n\treturn SandboxAPIValidateSshAccessRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return SshAccessValidationDto\nfunc (a *SandboxAPIService) ValidateSshAccessExecute(r SandboxAPIValidateSshAccessRequest) (*SshAccessValidationDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SshAccessValidationDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SandboxAPIService.ValidateSshAccess\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/sandbox/ssh-access/validate\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.token == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"token is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"token\", r.token, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_snapshots.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype SnapshotsAPI interface {\n\n\t/*\n\tActivateSnapshot Activate a snapshot\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Snapshot ID\n\t@return SnapshotsAPIActivateSnapshotRequest\n\t*/\n\tActivateSnapshot(ctx context.Context, id string) SnapshotsAPIActivateSnapshotRequest\n\n\t// ActivateSnapshotExecute executes the request\n\t//  @return SnapshotDto\n\tActivateSnapshotExecute(r SnapshotsAPIActivateSnapshotRequest) (*SnapshotDto, *http.Response, error)\n\n\t/*\n\tCanCleanupImage Check if an image can be cleaned up\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return SnapshotsAPICanCleanupImageRequest\n\t*/\n\tCanCleanupImage(ctx context.Context) SnapshotsAPICanCleanupImageRequest\n\n\t// CanCleanupImageExecute executes the request\n\t//  @return bool\n\tCanCleanupImageExecute(r SnapshotsAPICanCleanupImageRequest) (bool, *http.Response, error)\n\n\t/*\n\tCreateSnapshot Create a new snapshot\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return SnapshotsAPICreateSnapshotRequest\n\t*/\n\tCreateSnapshot(ctx context.Context) SnapshotsAPICreateSnapshotRequest\n\n\t// CreateSnapshotExecute executes the request\n\t//  @return SnapshotDto\n\tCreateSnapshotExecute(r SnapshotsAPICreateSnapshotRequest) (*SnapshotDto, *http.Response, error)\n\n\t/*\n\tDeactivateSnapshot Deactivate a snapshot\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Snapshot ID\n\t@return SnapshotsAPIDeactivateSnapshotRequest\n\t*/\n\tDeactivateSnapshot(ctx context.Context, id string) SnapshotsAPIDeactivateSnapshotRequest\n\n\t// DeactivateSnapshotExecute executes the request\n\tDeactivateSnapshotExecute(r SnapshotsAPIDeactivateSnapshotRequest) (*http.Response, error)\n\n\t/*\n\tGetAllSnapshots List all snapshots\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return SnapshotsAPIGetAllSnapshotsRequest\n\t*/\n\tGetAllSnapshots(ctx context.Context) SnapshotsAPIGetAllSnapshotsRequest\n\n\t// GetAllSnapshotsExecute executes the request\n\t//  @return PaginatedSnapshots\n\tGetAllSnapshotsExecute(r SnapshotsAPIGetAllSnapshotsRequest) (*PaginatedSnapshots, *http.Response, error)\n\n\t/*\n\tGetSnapshot Get snapshot by ID or name\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Snapshot ID or name\n\t@return SnapshotsAPIGetSnapshotRequest\n\t*/\n\tGetSnapshot(ctx context.Context, id string) SnapshotsAPIGetSnapshotRequest\n\n\t// GetSnapshotExecute executes the request\n\t//  @return SnapshotDto\n\tGetSnapshotExecute(r SnapshotsAPIGetSnapshotRequest) (*SnapshotDto, *http.Response, error)\n\n\t/*\n\tGetSnapshotBuildLogs Get snapshot build logs\n\n\tThis endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Snapshot ID\n\t@return SnapshotsAPIGetSnapshotBuildLogsRequest\n\n\tDeprecated\n\t*/\n\tGetSnapshotBuildLogs(ctx context.Context, id string) SnapshotsAPIGetSnapshotBuildLogsRequest\n\n\t// GetSnapshotBuildLogsExecute executes the request\n\t// Deprecated\n\tGetSnapshotBuildLogsExecute(r SnapshotsAPIGetSnapshotBuildLogsRequest) (*http.Response, error)\n\n\t/*\n\tGetSnapshotBuildLogsUrl Get snapshot build logs URL\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Snapshot ID\n\t@return SnapshotsAPIGetSnapshotBuildLogsUrlRequest\n\t*/\n\tGetSnapshotBuildLogsUrl(ctx context.Context, id string) SnapshotsAPIGetSnapshotBuildLogsUrlRequest\n\n\t// GetSnapshotBuildLogsUrlExecute executes the request\n\t//  @return Url\n\tGetSnapshotBuildLogsUrlExecute(r SnapshotsAPIGetSnapshotBuildLogsUrlRequest) (*Url, *http.Response, error)\n\n\t/*\n\tRemoveSnapshot Delete snapshot\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Snapshot ID\n\t@return SnapshotsAPIRemoveSnapshotRequest\n\t*/\n\tRemoveSnapshot(ctx context.Context, id string) SnapshotsAPIRemoveSnapshotRequest\n\n\t// RemoveSnapshotExecute executes the request\n\tRemoveSnapshotExecute(r SnapshotsAPIRemoveSnapshotRequest) (*http.Response, error)\n\n\t/*\n\tSetSnapshotGeneralStatus Set snapshot general status\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id Snapshot ID\n\t@return SnapshotsAPISetSnapshotGeneralStatusRequest\n\t*/\n\tSetSnapshotGeneralStatus(ctx context.Context, id string) SnapshotsAPISetSnapshotGeneralStatusRequest\n\n\t// SetSnapshotGeneralStatusExecute executes the request\n\t//  @return SnapshotDto\n\tSetSnapshotGeneralStatusExecute(r SnapshotsAPISetSnapshotGeneralStatusRequest) (*SnapshotDto, *http.Response, error)\n}\n\n// SnapshotsAPIService SnapshotsAPI service\ntype SnapshotsAPIService service\n\ntype SnapshotsAPIActivateSnapshotRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPIActivateSnapshotRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPIActivateSnapshotRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SnapshotsAPIActivateSnapshotRequest) Execute() (*SnapshotDto, *http.Response, error) {\n\treturn r.ApiService.ActivateSnapshotExecute(r)\n}\n\n/*\nActivateSnapshot Activate a snapshot\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Snapshot ID\n @return SnapshotsAPIActivateSnapshotRequest\n*/\nfunc (a *SnapshotsAPIService) ActivateSnapshot(ctx context.Context, id string) SnapshotsAPIActivateSnapshotRequest {\n\treturn SnapshotsAPIActivateSnapshotRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return SnapshotDto\nfunc (a *SnapshotsAPIService) ActivateSnapshotExecute(r SnapshotsAPIActivateSnapshotRequest) (*SnapshotDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SnapshotDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.ActivateSnapshot\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots/{id}/activate\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPICanCleanupImageRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\timageName *string\n\txDaytonaOrganizationID *string\n}\n\n// Image name with tag to check\nfunc (r SnapshotsAPICanCleanupImageRequest) ImageName(imageName string) SnapshotsAPICanCleanupImageRequest {\n\tr.imageName = &imageName\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPICanCleanupImageRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPICanCleanupImageRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SnapshotsAPICanCleanupImageRequest) Execute() (bool, *http.Response, error) {\n\treturn r.ApiService.CanCleanupImageExecute(r)\n}\n\n/*\nCanCleanupImage Check if an image can be cleaned up\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return SnapshotsAPICanCleanupImageRequest\n*/\nfunc (a *SnapshotsAPIService) CanCleanupImage(ctx context.Context) SnapshotsAPICanCleanupImageRequest {\n\treturn SnapshotsAPICanCleanupImageRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return bool\nfunc (a *SnapshotsAPIService) CanCleanupImageExecute(r SnapshotsAPICanCleanupImageRequest) (bool, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  bool\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.CanCleanupImage\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots/can-cleanup-image\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.imageName == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"imageName is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"imageName\", r.imageName, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPICreateSnapshotRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\tcreateSnapshot *CreateSnapshot\n\txDaytonaOrganizationID *string\n}\n\nfunc (r SnapshotsAPICreateSnapshotRequest) CreateSnapshot(createSnapshot CreateSnapshot) SnapshotsAPICreateSnapshotRequest {\n\tr.createSnapshot = &createSnapshot\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPICreateSnapshotRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPICreateSnapshotRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SnapshotsAPICreateSnapshotRequest) Execute() (*SnapshotDto, *http.Response, error) {\n\treturn r.ApiService.CreateSnapshotExecute(r)\n}\n\n/*\nCreateSnapshot Create a new snapshot\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return SnapshotsAPICreateSnapshotRequest\n*/\nfunc (a *SnapshotsAPIService) CreateSnapshot(ctx context.Context) SnapshotsAPICreateSnapshotRequest {\n\treturn SnapshotsAPICreateSnapshotRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return SnapshotDto\nfunc (a *SnapshotsAPIService) CreateSnapshotExecute(r SnapshotsAPICreateSnapshotRequest) (*SnapshotDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SnapshotDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.CreateSnapshot\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createSnapshot == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createSnapshot is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createSnapshot\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPIDeactivateSnapshotRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPIDeactivateSnapshotRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPIDeactivateSnapshotRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SnapshotsAPIDeactivateSnapshotRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeactivateSnapshotExecute(r)\n}\n\n/*\nDeactivateSnapshot Deactivate a snapshot\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Snapshot ID\n @return SnapshotsAPIDeactivateSnapshotRequest\n*/\nfunc (a *SnapshotsAPIService) DeactivateSnapshot(ctx context.Context, id string) SnapshotsAPIDeactivateSnapshotRequest {\n\treturn SnapshotsAPIDeactivateSnapshotRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *SnapshotsAPIService) DeactivateSnapshotExecute(r SnapshotsAPIDeactivateSnapshotRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.DeactivateSnapshot\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots/{id}/deactivate\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPIGetAllSnapshotsRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\txDaytonaOrganizationID *string\n\tpage *float32\n\tlimit *float32\n\tname *string\n\tsort *string\n\torder *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPIGetAllSnapshotsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPIGetAllSnapshotsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Page number of the results\nfunc (r SnapshotsAPIGetAllSnapshotsRequest) Page(page float32) SnapshotsAPIGetAllSnapshotsRequest {\n\tr.page = &page\n\treturn r\n}\n\n// Number of results per page\nfunc (r SnapshotsAPIGetAllSnapshotsRequest) Limit(limit float32) SnapshotsAPIGetAllSnapshotsRequest {\n\tr.limit = &limit\n\treturn r\n}\n\n// Filter by partial name match\nfunc (r SnapshotsAPIGetAllSnapshotsRequest) Name(name string) SnapshotsAPIGetAllSnapshotsRequest {\n\tr.name = &name\n\treturn r\n}\n\n// Field to sort by\nfunc (r SnapshotsAPIGetAllSnapshotsRequest) Sort(sort string) SnapshotsAPIGetAllSnapshotsRequest {\n\tr.sort = &sort\n\treturn r\n}\n\n// Direction to sort by\nfunc (r SnapshotsAPIGetAllSnapshotsRequest) Order(order string) SnapshotsAPIGetAllSnapshotsRequest {\n\tr.order = &order\n\treturn r\n}\n\nfunc (r SnapshotsAPIGetAllSnapshotsRequest) Execute() (*PaginatedSnapshots, *http.Response, error) {\n\treturn r.ApiService.GetAllSnapshotsExecute(r)\n}\n\n/*\nGetAllSnapshots List all snapshots\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return SnapshotsAPIGetAllSnapshotsRequest\n*/\nfunc (a *SnapshotsAPIService) GetAllSnapshots(ctx context.Context) SnapshotsAPIGetAllSnapshotsRequest {\n\treturn SnapshotsAPIGetAllSnapshotsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return PaginatedSnapshots\nfunc (a *SnapshotsAPIService) GetAllSnapshotsExecute(r SnapshotsAPIGetAllSnapshotsRequest) (*PaginatedSnapshots, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PaginatedSnapshots\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.GetAllSnapshots\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.page != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"page\", r.page, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 1\n\t\tr.page = &defaultValue\n\t}\n\tif r.limit != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"limit\", r.limit, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue float32 = 100\n\t\tr.limit = &defaultValue\n\t}\n\tif r.name != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"name\", r.name, \"form\", \"\")\n\t}\n\tif r.sort != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"sort\", r.sort, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue string = \"lastUsedAt\"\n\t\tr.sort = &defaultValue\n\t}\n\tif r.order != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"order\", r.order, \"form\", \"\")\n\t} else {\n\t\tvar defaultValue string = \"desc\"\n\t\tr.order = &defaultValue\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPIGetSnapshotRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPIGetSnapshotRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPIGetSnapshotRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SnapshotsAPIGetSnapshotRequest) Execute() (*SnapshotDto, *http.Response, error) {\n\treturn r.ApiService.GetSnapshotExecute(r)\n}\n\n/*\nGetSnapshot Get snapshot by ID or name\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Snapshot ID or name\n @return SnapshotsAPIGetSnapshotRequest\n*/\nfunc (a *SnapshotsAPIService) GetSnapshot(ctx context.Context, id string) SnapshotsAPIGetSnapshotRequest {\n\treturn SnapshotsAPIGetSnapshotRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return SnapshotDto\nfunc (a *SnapshotsAPIService) GetSnapshotExecute(r SnapshotsAPIGetSnapshotRequest) (*SnapshotDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SnapshotDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.GetSnapshot\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPIGetSnapshotBuildLogsRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\tid string\n\txDaytonaOrganizationID *string\n\tfollow *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPIGetSnapshotBuildLogsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPIGetSnapshotBuildLogsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Whether to follow the logs stream\nfunc (r SnapshotsAPIGetSnapshotBuildLogsRequest) Follow(follow bool) SnapshotsAPIGetSnapshotBuildLogsRequest {\n\tr.follow = &follow\n\treturn r\n}\n\nfunc (r SnapshotsAPIGetSnapshotBuildLogsRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GetSnapshotBuildLogsExecute(r)\n}\n\n/*\nGetSnapshotBuildLogs Get snapshot build logs\n\nThis endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Snapshot ID\n @return SnapshotsAPIGetSnapshotBuildLogsRequest\n\nDeprecated\n*/\nfunc (a *SnapshotsAPIService) GetSnapshotBuildLogs(ctx context.Context, id string) SnapshotsAPIGetSnapshotBuildLogsRequest {\n\treturn SnapshotsAPIGetSnapshotBuildLogsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *SnapshotsAPIService) GetSnapshotBuildLogsExecute(r SnapshotsAPIGetSnapshotBuildLogsRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.GetSnapshotBuildLogs\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots/{id}/build-logs\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.follow != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"follow\", r.follow, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPIGetSnapshotBuildLogsUrlRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPIGetSnapshotBuildLogsUrlRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPIGetSnapshotBuildLogsUrlRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SnapshotsAPIGetSnapshotBuildLogsUrlRequest) Execute() (*Url, *http.Response, error) {\n\treturn r.ApiService.GetSnapshotBuildLogsUrlExecute(r)\n}\n\n/*\nGetSnapshotBuildLogsUrl Get snapshot build logs URL\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Snapshot ID\n @return SnapshotsAPIGetSnapshotBuildLogsUrlRequest\n*/\nfunc (a *SnapshotsAPIService) GetSnapshotBuildLogsUrl(ctx context.Context, id string) SnapshotsAPIGetSnapshotBuildLogsUrlRequest {\n\treturn SnapshotsAPIGetSnapshotBuildLogsUrlRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return Url\nfunc (a *SnapshotsAPIService) GetSnapshotBuildLogsUrlExecute(r SnapshotsAPIGetSnapshotBuildLogsUrlRequest) (*Url, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Url\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.GetSnapshotBuildLogsUrl\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots/{id}/build-logs-url\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPIRemoveSnapshotRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\tid string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPIRemoveSnapshotRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPIRemoveSnapshotRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SnapshotsAPIRemoveSnapshotRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.RemoveSnapshotExecute(r)\n}\n\n/*\nRemoveSnapshot Delete snapshot\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Snapshot ID\n @return SnapshotsAPIRemoveSnapshotRequest\n*/\nfunc (a *SnapshotsAPIService) RemoveSnapshot(ctx context.Context, id string) SnapshotsAPIRemoveSnapshotRequest {\n\treturn SnapshotsAPIRemoveSnapshotRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *SnapshotsAPIService) RemoveSnapshotExecute(r SnapshotsAPIRemoveSnapshotRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.RemoveSnapshot\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype SnapshotsAPISetSnapshotGeneralStatusRequest struct {\n\tctx context.Context\n\tApiService SnapshotsAPI\n\tid string\n\tsetSnapshotGeneralStatusDto *SetSnapshotGeneralStatusDto\n\txDaytonaOrganizationID *string\n}\n\nfunc (r SnapshotsAPISetSnapshotGeneralStatusRequest) SetSnapshotGeneralStatusDto(setSnapshotGeneralStatusDto SetSnapshotGeneralStatusDto) SnapshotsAPISetSnapshotGeneralStatusRequest {\n\tr.setSnapshotGeneralStatusDto = &setSnapshotGeneralStatusDto\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r SnapshotsAPISetSnapshotGeneralStatusRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) SnapshotsAPISetSnapshotGeneralStatusRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r SnapshotsAPISetSnapshotGeneralStatusRequest) Execute() (*SnapshotDto, *http.Response, error) {\n\treturn r.ApiService.SetSnapshotGeneralStatusExecute(r)\n}\n\n/*\nSetSnapshotGeneralStatus Set snapshot general status\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id Snapshot ID\n @return SnapshotsAPISetSnapshotGeneralStatusRequest\n*/\nfunc (a *SnapshotsAPIService) SetSnapshotGeneralStatus(ctx context.Context, id string) SnapshotsAPISetSnapshotGeneralStatusRequest {\n\treturn SnapshotsAPISetSnapshotGeneralStatusRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return SnapshotDto\nfunc (a *SnapshotsAPIService) SetSnapshotGeneralStatusExecute(r SnapshotsAPISetSnapshotGeneralStatusRequest) (*SnapshotDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPatch\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SnapshotDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"SnapshotsAPIService.SetSnapshotGeneralStatus\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/snapshots/{id}/general\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.setSnapshotGeneralStatusDto == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"setSnapshotGeneralStatusDto is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.setSnapshotGeneralStatusDto\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_toolbox.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"os\"\n)\n\n\ntype ToolboxAPI interface {\n\n\t/*\n\tClickMouseDeprecated [DEPRECATED] Click mouse\n\n\tClick mouse at specified coordinates\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIClickMouseDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tClickMouseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIClickMouseDeprecatedRequest\n\n\t// ClickMouseDeprecatedExecute executes the request\n\t//  @return MouseClickResponse\n\t// Deprecated\n\tClickMouseDeprecatedExecute(r ToolboxAPIClickMouseDeprecatedRequest) (*MouseClickResponse, *http.Response, error)\n\n\t/*\n\tCreateFolderDeprecated [DEPRECATED] Create folder\n\n\tCreate folder inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPICreateFolderDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tCreateFolderDeprecated(ctx context.Context, sandboxId string) ToolboxAPICreateFolderDeprecatedRequest\n\n\t// CreateFolderDeprecatedExecute executes the request\n\t// Deprecated\n\tCreateFolderDeprecatedExecute(r ToolboxAPICreateFolderDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tCreatePTYSessionDeprecated [DEPRECATED] Create PTY session\n\n\tCreate a new PTY session in the sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPICreatePTYSessionDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tCreatePTYSessionDeprecated(ctx context.Context, sandboxId string) ToolboxAPICreatePTYSessionDeprecatedRequest\n\n\t// CreatePTYSessionDeprecatedExecute executes the request\n\t//  @return PtyCreateResponse\n\t// Deprecated\n\tCreatePTYSessionDeprecatedExecute(r ToolboxAPICreatePTYSessionDeprecatedRequest) (*PtyCreateResponse, *http.Response, error)\n\n\t/*\n\tCreateSessionDeprecated [DEPRECATED] Create session\n\n\tCreate a new session in the sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPICreateSessionDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tCreateSessionDeprecated(ctx context.Context, sandboxId string) ToolboxAPICreateSessionDeprecatedRequest\n\n\t// CreateSessionDeprecatedExecute executes the request\n\t// Deprecated\n\tCreateSessionDeprecatedExecute(r ToolboxAPICreateSessionDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tDeleteFileDeprecated [DEPRECATED] Delete file\n\n\tDelete file inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIDeleteFileDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tDeleteFileDeprecated(ctx context.Context, sandboxId string) ToolboxAPIDeleteFileDeprecatedRequest\n\n\t// DeleteFileDeprecatedExecute executes the request\n\t// Deprecated\n\tDeleteFileDeprecatedExecute(r ToolboxAPIDeleteFileDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tDeletePTYSessionDeprecated [DEPRECATED] Delete PTY session\n\n\tDelete a PTY session and terminate the associated process\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@param sessionId\n\t@return ToolboxAPIDeletePTYSessionDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tDeletePTYSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIDeletePTYSessionDeprecatedRequest\n\n\t// DeletePTYSessionDeprecatedExecute executes the request\n\t// Deprecated\n\tDeletePTYSessionDeprecatedExecute(r ToolboxAPIDeletePTYSessionDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tDeleteSessionDeprecated [DEPRECATED] Delete session\n\n\tDelete a specific session\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@param sessionId\n\t@return ToolboxAPIDeleteSessionDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tDeleteSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIDeleteSessionDeprecatedRequest\n\n\t// DeleteSessionDeprecatedExecute executes the request\n\t// Deprecated\n\tDeleteSessionDeprecatedExecute(r ToolboxAPIDeleteSessionDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tDownloadFileDeprecated [DEPRECATED] Download file\n\n\tDownload file from sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIDownloadFileDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tDownloadFileDeprecated(ctx context.Context, sandboxId string) ToolboxAPIDownloadFileDeprecatedRequest\n\n\t// DownloadFileDeprecatedExecute executes the request\n\t//  @return *os.File\n\t// Deprecated\n\tDownloadFileDeprecatedExecute(r ToolboxAPIDownloadFileDeprecatedRequest) (*os.File, *http.Response, error)\n\n\t/*\n\tDownloadFilesDeprecated [DEPRECATED] Download multiple files\n\n\tStreams back a multipart/form-data bundle of the requested paths\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIDownloadFilesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tDownloadFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIDownloadFilesDeprecatedRequest\n\n\t// DownloadFilesDeprecatedExecute executes the request\n\t//  @return *os.File\n\t// Deprecated\n\tDownloadFilesDeprecatedExecute(r ToolboxAPIDownloadFilesDeprecatedRequest) (*os.File, *http.Response, error)\n\n\t/*\n\tDragMouseDeprecated [DEPRECATED] Drag mouse\n\n\tDrag mouse from start to end coordinates\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIDragMouseDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tDragMouseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIDragMouseDeprecatedRequest\n\n\t// DragMouseDeprecatedExecute executes the request\n\t//  @return MouseDragResponse\n\t// Deprecated\n\tDragMouseDeprecatedExecute(r ToolboxAPIDragMouseDeprecatedRequest) (*MouseDragResponse, *http.Response, error)\n\n\t/*\n\tExecuteCommandDeprecated [DEPRECATED] Execute command\n\n\tExecute command synchronously inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIExecuteCommandDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tExecuteCommandDeprecated(ctx context.Context, sandboxId string) ToolboxAPIExecuteCommandDeprecatedRequest\n\n\t// ExecuteCommandDeprecatedExecute executes the request\n\t//  @return ExecuteResponse\n\t// Deprecated\n\tExecuteCommandDeprecatedExecute(r ToolboxAPIExecuteCommandDeprecatedRequest) (*ExecuteResponse, *http.Response, error)\n\n\t/*\n\tExecuteSessionCommandDeprecated [DEPRECATED] Execute command in session\n\n\tExecute a command in a specific session\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@param sessionId\n\t@return ToolboxAPIExecuteSessionCommandDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tExecuteSessionCommandDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIExecuteSessionCommandDeprecatedRequest\n\n\t// ExecuteSessionCommandDeprecatedExecute executes the request\n\t//  @return SessionExecuteResponse\n\t// Deprecated\n\tExecuteSessionCommandDeprecatedExecute(r ToolboxAPIExecuteSessionCommandDeprecatedRequest) (*SessionExecuteResponse, *http.Response, error)\n\n\t/*\n\tFindInFilesDeprecated [DEPRECATED] Search for text/pattern in files\n\n\tSearch for text/pattern inside sandbox files\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIFindInFilesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tFindInFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIFindInFilesDeprecatedRequest\n\n\t// FindInFilesDeprecatedExecute executes the request\n\t//  @return []Match\n\t// Deprecated\n\tFindInFilesDeprecatedExecute(r ToolboxAPIFindInFilesDeprecatedRequest) ([]Match, *http.Response, error)\n\n\t/*\n\tGetComputerUseStatusDeprecated [DEPRECATED] Get computer use status\n\n\tGet status of all VNC desktop processes\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGetComputerUseStatusDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetComputerUseStatusDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetComputerUseStatusDeprecatedRequest\n\n\t// GetComputerUseStatusDeprecatedExecute executes the request\n\t//  @return ComputerUseStatusResponse\n\t// Deprecated\n\tGetComputerUseStatusDeprecatedExecute(r ToolboxAPIGetComputerUseStatusDeprecatedRequest) (*ComputerUseStatusResponse, *http.Response, error)\n\n\t/*\n\tGetDisplayInfoDeprecated [DEPRECATED] Get display info\n\n\tGet information about displays\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGetDisplayInfoDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetDisplayInfoDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetDisplayInfoDeprecatedRequest\n\n\t// GetDisplayInfoDeprecatedExecute executes the request\n\t//  @return DisplayInfoResponse\n\t// Deprecated\n\tGetDisplayInfoDeprecatedExecute(r ToolboxAPIGetDisplayInfoDeprecatedRequest) (*DisplayInfoResponse, *http.Response, error)\n\n\t/*\n\tGetFileInfoDeprecated [DEPRECATED] Get file info\n\n\tGet file info inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGetFileInfoDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetFileInfoDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetFileInfoDeprecatedRequest\n\n\t// GetFileInfoDeprecatedExecute executes the request\n\t//  @return FileInfo\n\t// Deprecated\n\tGetFileInfoDeprecatedExecute(r ToolboxAPIGetFileInfoDeprecatedRequest) (*FileInfo, *http.Response, error)\n\n\t/*\n\tGetMousePositionDeprecated [DEPRECATED] Get mouse position\n\n\tGet current mouse cursor position\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGetMousePositionDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetMousePositionDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetMousePositionDeprecatedRequest\n\n\t// GetMousePositionDeprecatedExecute executes the request\n\t//  @return MousePosition\n\t// Deprecated\n\tGetMousePositionDeprecatedExecute(r ToolboxAPIGetMousePositionDeprecatedRequest) (*MousePosition, *http.Response, error)\n\n\t/*\n\tGetPTYSessionDeprecated [DEPRECATED] Get PTY session\n\n\tGet PTY session information by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@param sessionId\n\t@return ToolboxAPIGetPTYSessionDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetPTYSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIGetPTYSessionDeprecatedRequest\n\n\t// GetPTYSessionDeprecatedExecute executes the request\n\t//  @return PtySessionInfo\n\t// Deprecated\n\tGetPTYSessionDeprecatedExecute(r ToolboxAPIGetPTYSessionDeprecatedRequest) (*PtySessionInfo, *http.Response, error)\n\n\t/*\n\tGetProcessErrorsDeprecated [DEPRECATED] Get process errors\n\n\tGet error logs for a specific VNC process\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param processName\n\t@param sandboxId\n\t@return ToolboxAPIGetProcessErrorsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetProcessErrorsDeprecated(ctx context.Context, processName string, sandboxId string) ToolboxAPIGetProcessErrorsDeprecatedRequest\n\n\t// GetProcessErrorsDeprecatedExecute executes the request\n\t//  @return ProcessErrorsResponse\n\t// Deprecated\n\tGetProcessErrorsDeprecatedExecute(r ToolboxAPIGetProcessErrorsDeprecatedRequest) (*ProcessErrorsResponse, *http.Response, error)\n\n\t/*\n\tGetProcessLogsDeprecated [DEPRECATED] Get process logs\n\n\tGet logs for a specific VNC process\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param processName\n\t@param sandboxId\n\t@return ToolboxAPIGetProcessLogsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetProcessLogsDeprecated(ctx context.Context, processName string, sandboxId string) ToolboxAPIGetProcessLogsDeprecatedRequest\n\n\t// GetProcessLogsDeprecatedExecute executes the request\n\t//  @return ProcessLogsResponse\n\t// Deprecated\n\tGetProcessLogsDeprecatedExecute(r ToolboxAPIGetProcessLogsDeprecatedRequest) (*ProcessLogsResponse, *http.Response, error)\n\n\t/*\n\tGetProcessStatusDeprecated [DEPRECATED] Get process status\n\n\tGet status of a specific VNC process\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param processName\n\t@param sandboxId\n\t@return ToolboxAPIGetProcessStatusDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetProcessStatusDeprecated(ctx context.Context, processName string, sandboxId string) ToolboxAPIGetProcessStatusDeprecatedRequest\n\n\t// GetProcessStatusDeprecatedExecute executes the request\n\t//  @return ProcessStatusResponse\n\t// Deprecated\n\tGetProcessStatusDeprecatedExecute(r ToolboxAPIGetProcessStatusDeprecatedRequest) (*ProcessStatusResponse, *http.Response, error)\n\n\t/*\n\tGetProjectDirDeprecated [DEPRECATED] Get sandbox project dir\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGetProjectDirDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetProjectDirDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetProjectDirDeprecatedRequest\n\n\t// GetProjectDirDeprecatedExecute executes the request\n\t//  @return ProjectDirResponse\n\t// Deprecated\n\tGetProjectDirDeprecatedExecute(r ToolboxAPIGetProjectDirDeprecatedRequest) (*ProjectDirResponse, *http.Response, error)\n\n\t/*\n\tGetSessionCommandDeprecated [DEPRECATED] Get session command\n\n\tGet session command by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@param sessionId\n\t@param commandId\n\t@return ToolboxAPIGetSessionCommandDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetSessionCommandDeprecated(ctx context.Context, sandboxId string, sessionId string, commandId string) ToolboxAPIGetSessionCommandDeprecatedRequest\n\n\t// GetSessionCommandDeprecatedExecute executes the request\n\t//  @return Command\n\t// Deprecated\n\tGetSessionCommandDeprecatedExecute(r ToolboxAPIGetSessionCommandDeprecatedRequest) (*Command, *http.Response, error)\n\n\t/*\n\tGetSessionCommandLogsDeprecated [DEPRECATED] Get command logs\n\n\tGet logs for a specific command in a session\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@param sessionId\n\t@param commandId\n\t@return ToolboxAPIGetSessionCommandLogsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetSessionCommandLogsDeprecated(ctx context.Context, sandboxId string, sessionId string, commandId string) ToolboxAPIGetSessionCommandLogsDeprecatedRequest\n\n\t// GetSessionCommandLogsDeprecatedExecute executes the request\n\t//  @return string\n\t// Deprecated\n\tGetSessionCommandLogsDeprecatedExecute(r ToolboxAPIGetSessionCommandLogsDeprecatedRequest) (string, *http.Response, error)\n\n\t/*\n\tGetSessionDeprecated [DEPRECATED] Get session\n\n\tGet session by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@param sessionId\n\t@return ToolboxAPIGetSessionDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIGetSessionDeprecatedRequest\n\n\t// GetSessionDeprecatedExecute executes the request\n\t//  @return Session\n\t// Deprecated\n\tGetSessionDeprecatedExecute(r ToolboxAPIGetSessionDeprecatedRequest) (*Session, *http.Response, error)\n\n\t/*\n\tGetUserHomeDirDeprecated [DEPRECATED] Get sandbox user home dir\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGetUserHomeDirDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetUserHomeDirDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetUserHomeDirDeprecatedRequest\n\n\t// GetUserHomeDirDeprecatedExecute executes the request\n\t//  @return UserHomeDirResponse\n\t// Deprecated\n\tGetUserHomeDirDeprecatedExecute(r ToolboxAPIGetUserHomeDirDeprecatedRequest) (*UserHomeDirResponse, *http.Response, error)\n\n\t/*\n\tGetWindowsDeprecated [DEPRECATED] Get windows\n\n\tGet list of open windows\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGetWindowsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetWindowsDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetWindowsDeprecatedRequest\n\n\t// GetWindowsDeprecatedExecute executes the request\n\t//  @return WindowsResponse\n\t// Deprecated\n\tGetWindowsDeprecatedExecute(r ToolboxAPIGetWindowsDeprecatedRequest) (*WindowsResponse, *http.Response, error)\n\n\t/*\n\tGetWorkDirDeprecated [DEPRECATED] Get sandbox work-dir\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGetWorkDirDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetWorkDirDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetWorkDirDeprecatedRequest\n\n\t// GetWorkDirDeprecatedExecute executes the request\n\t//  @return WorkDirResponse\n\t// Deprecated\n\tGetWorkDirDeprecatedExecute(r ToolboxAPIGetWorkDirDeprecatedRequest) (*WorkDirResponse, *http.Response, error)\n\n\t/*\n\tGitAddFilesDeprecated [DEPRECATED] Add files\n\n\tAdd files to git commit\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitAddFilesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitAddFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitAddFilesDeprecatedRequest\n\n\t// GitAddFilesDeprecatedExecute executes the request\n\t// Deprecated\n\tGitAddFilesDeprecatedExecute(r ToolboxAPIGitAddFilesDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tGitCheckoutBranchDeprecated [DEPRECATED] Checkout branch\n\n\tCheckout branch or commit in git repository\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitCheckoutBranchDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitCheckoutBranchDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitCheckoutBranchDeprecatedRequest\n\n\t// GitCheckoutBranchDeprecatedExecute executes the request\n\t// Deprecated\n\tGitCheckoutBranchDeprecatedExecute(r ToolboxAPIGitCheckoutBranchDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tGitCloneRepositoryDeprecated [DEPRECATED] Clone repository\n\n\tClone git repository\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitCloneRepositoryDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitCloneRepositoryDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitCloneRepositoryDeprecatedRequest\n\n\t// GitCloneRepositoryDeprecatedExecute executes the request\n\t// Deprecated\n\tGitCloneRepositoryDeprecatedExecute(r ToolboxAPIGitCloneRepositoryDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tGitCommitChangesDeprecated [DEPRECATED] Commit changes\n\n\tCommit changes to git repository\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitCommitChangesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitCommitChangesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitCommitChangesDeprecatedRequest\n\n\t// GitCommitChangesDeprecatedExecute executes the request\n\t//  @return GitCommitResponse\n\t// Deprecated\n\tGitCommitChangesDeprecatedExecute(r ToolboxAPIGitCommitChangesDeprecatedRequest) (*GitCommitResponse, *http.Response, error)\n\n\t/*\n\tGitCreateBranchDeprecated [DEPRECATED] Create branch\n\n\tCreate branch on git repository\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitCreateBranchDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitCreateBranchDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitCreateBranchDeprecatedRequest\n\n\t// GitCreateBranchDeprecatedExecute executes the request\n\t// Deprecated\n\tGitCreateBranchDeprecatedExecute(r ToolboxAPIGitCreateBranchDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tGitDeleteBranchDeprecated [DEPRECATED] Delete branch\n\n\tDelete branch on git repository\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitDeleteBranchDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitDeleteBranchDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitDeleteBranchDeprecatedRequest\n\n\t// GitDeleteBranchDeprecatedExecute executes the request\n\t// Deprecated\n\tGitDeleteBranchDeprecatedExecute(r ToolboxAPIGitDeleteBranchDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tGitGetHistoryDeprecated [DEPRECATED] Get commit history\n\n\tGet commit history from git repository\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitGetHistoryDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitGetHistoryDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitGetHistoryDeprecatedRequest\n\n\t// GitGetHistoryDeprecatedExecute executes the request\n\t//  @return []GitCommitInfo\n\t// Deprecated\n\tGitGetHistoryDeprecatedExecute(r ToolboxAPIGitGetHistoryDeprecatedRequest) ([]GitCommitInfo, *http.Response, error)\n\n\t/*\n\tGitGetStatusDeprecated [DEPRECATED] Get git status\n\n\tGet status from git repository\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitGetStatusDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitGetStatusDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitGetStatusDeprecatedRequest\n\n\t// GitGetStatusDeprecatedExecute executes the request\n\t//  @return GitStatus\n\t// Deprecated\n\tGitGetStatusDeprecatedExecute(r ToolboxAPIGitGetStatusDeprecatedRequest) (*GitStatus, *http.Response, error)\n\n\t/*\n\tGitListBranchesDeprecated [DEPRECATED] Get branch list\n\n\tGet branch list from git repository\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitListBranchesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitListBranchesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitListBranchesDeprecatedRequest\n\n\t// GitListBranchesDeprecatedExecute executes the request\n\t//  @return ListBranchResponse\n\t// Deprecated\n\tGitListBranchesDeprecatedExecute(r ToolboxAPIGitListBranchesDeprecatedRequest) (*ListBranchResponse, *http.Response, error)\n\n\t/*\n\tGitPullChangesDeprecated [DEPRECATED] Pull changes\n\n\tPull changes from remote\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitPullChangesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitPullChangesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitPullChangesDeprecatedRequest\n\n\t// GitPullChangesDeprecatedExecute executes the request\n\t// Deprecated\n\tGitPullChangesDeprecatedExecute(r ToolboxAPIGitPullChangesDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tGitPushChangesDeprecated [DEPRECATED] Push changes\n\n\tPush changes to remote\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIGitPushChangesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGitPushChangesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitPushChangesDeprecatedRequest\n\n\t// GitPushChangesDeprecatedExecute executes the request\n\t// Deprecated\n\tGitPushChangesDeprecatedExecute(r ToolboxAPIGitPushChangesDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tListFilesDeprecated [DEPRECATED] List files\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIListFilesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tListFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIListFilesDeprecatedRequest\n\n\t// ListFilesDeprecatedExecute executes the request\n\t//  @return []FileInfo\n\t// Deprecated\n\tListFilesDeprecatedExecute(r ToolboxAPIListFilesDeprecatedRequest) ([]FileInfo, *http.Response, error)\n\n\t/*\n\tListPTYSessionsDeprecated [DEPRECATED] List PTY sessions\n\n\tList all active PTY sessions in the sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIListPTYSessionsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tListPTYSessionsDeprecated(ctx context.Context, sandboxId string) ToolboxAPIListPTYSessionsDeprecatedRequest\n\n\t// ListPTYSessionsDeprecatedExecute executes the request\n\t//  @return PtyListResponse\n\t// Deprecated\n\tListPTYSessionsDeprecatedExecute(r ToolboxAPIListPTYSessionsDeprecatedRequest) (*PtyListResponse, *http.Response, error)\n\n\t/*\n\tListSessionsDeprecated [DEPRECATED] List sessions\n\n\tList all active sessions in the sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIListSessionsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tListSessionsDeprecated(ctx context.Context, sandboxId string) ToolboxAPIListSessionsDeprecatedRequest\n\n\t// ListSessionsDeprecatedExecute executes the request\n\t//  @return []Session\n\t// Deprecated\n\tListSessionsDeprecatedExecute(r ToolboxAPIListSessionsDeprecatedRequest) ([]Session, *http.Response, error)\n\n\t/*\n\tLspCompletionsDeprecated [DEPRECATED] Get Lsp Completions\n\n\tThe Completion request is sent from the client to the server to compute completion items at a given cursor position.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPILspCompletionsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tLspCompletionsDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspCompletionsDeprecatedRequest\n\n\t// LspCompletionsDeprecatedExecute executes the request\n\t//  @return CompletionList\n\t// Deprecated\n\tLspCompletionsDeprecatedExecute(r ToolboxAPILspCompletionsDeprecatedRequest) (*CompletionList, *http.Response, error)\n\n\t/*\n\tLspDidCloseDeprecated [DEPRECATED] Call Lsp DidClose\n\n\tThe document close notification is sent from the client to the server when the document got closed in the client.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPILspDidCloseDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tLspDidCloseDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspDidCloseDeprecatedRequest\n\n\t// LspDidCloseDeprecatedExecute executes the request\n\t// Deprecated\n\tLspDidCloseDeprecatedExecute(r ToolboxAPILspDidCloseDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tLspDidOpenDeprecated [DEPRECATED] Call Lsp DidOpen\n\n\tThe document open notification is sent from the client to the server to signal newly opened text documents.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPILspDidOpenDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tLspDidOpenDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspDidOpenDeprecatedRequest\n\n\t// LspDidOpenDeprecatedExecute executes the request\n\t// Deprecated\n\tLspDidOpenDeprecatedExecute(r ToolboxAPILspDidOpenDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tLspDocumentSymbolsDeprecated [DEPRECATED] Call Lsp DocumentSymbols\n\n\tThe document symbol request is sent from the client to the server.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPILspDocumentSymbolsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tLspDocumentSymbolsDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspDocumentSymbolsDeprecatedRequest\n\n\t// LspDocumentSymbolsDeprecatedExecute executes the request\n\t//  @return []LspSymbol\n\t// Deprecated\n\tLspDocumentSymbolsDeprecatedExecute(r ToolboxAPILspDocumentSymbolsDeprecatedRequest) ([]LspSymbol, *http.Response, error)\n\n\t/*\n\tLspStartDeprecated [DEPRECATED] Start Lsp server\n\n\tStart Lsp server process inside sandbox project\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPILspStartDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tLspStartDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspStartDeprecatedRequest\n\n\t// LspStartDeprecatedExecute executes the request\n\t// Deprecated\n\tLspStartDeprecatedExecute(r ToolboxAPILspStartDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tLspStopDeprecated [DEPRECATED] Stop Lsp server\n\n\tStop Lsp server process inside sandbox project\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPILspStopDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tLspStopDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspStopDeprecatedRequest\n\n\t// LspStopDeprecatedExecute executes the request\n\t// Deprecated\n\tLspStopDeprecatedExecute(r ToolboxAPILspStopDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tLspWorkspaceSymbolsDeprecated [DEPRECATED] Call Lsp WorkspaceSymbols\n\n\tThe workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPILspWorkspaceSymbolsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tLspWorkspaceSymbolsDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspWorkspaceSymbolsDeprecatedRequest\n\n\t// LspWorkspaceSymbolsDeprecatedExecute executes the request\n\t//  @return []LspSymbol\n\t// Deprecated\n\tLspWorkspaceSymbolsDeprecatedExecute(r ToolboxAPILspWorkspaceSymbolsDeprecatedRequest) ([]LspSymbol, *http.Response, error)\n\n\t/*\n\tMoveFileDeprecated [DEPRECATED] Move file\n\n\tMove file inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIMoveFileDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tMoveFileDeprecated(ctx context.Context, sandboxId string) ToolboxAPIMoveFileDeprecatedRequest\n\n\t// MoveFileDeprecatedExecute executes the request\n\t// Deprecated\n\tMoveFileDeprecatedExecute(r ToolboxAPIMoveFileDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tMoveMouseDeprecated [DEPRECATED] Move mouse\n\n\tMove mouse cursor to specified coordinates\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIMoveMouseDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tMoveMouseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIMoveMouseDeprecatedRequest\n\n\t// MoveMouseDeprecatedExecute executes the request\n\t//  @return MouseMoveResponse\n\t// Deprecated\n\tMoveMouseDeprecatedExecute(r ToolboxAPIMoveMouseDeprecatedRequest) (*MouseMoveResponse, *http.Response, error)\n\n\t/*\n\tPressHotkeyDeprecated [DEPRECATED] Press hotkey\n\n\tPress a hotkey combination\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIPressHotkeyDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tPressHotkeyDeprecated(ctx context.Context, sandboxId string) ToolboxAPIPressHotkeyDeprecatedRequest\n\n\t// PressHotkeyDeprecatedExecute executes the request\n\t// Deprecated\n\tPressHotkeyDeprecatedExecute(r ToolboxAPIPressHotkeyDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tPressKeyDeprecated [DEPRECATED] Press key\n\n\tPress a key with optional modifiers\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIPressKeyDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tPressKeyDeprecated(ctx context.Context, sandboxId string) ToolboxAPIPressKeyDeprecatedRequest\n\n\t// PressKeyDeprecatedExecute executes the request\n\t// Deprecated\n\tPressKeyDeprecatedExecute(r ToolboxAPIPressKeyDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tReplaceInFilesDeprecated [DEPRECATED] Replace in files\n\n\tReplace text/pattern in multiple files inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIReplaceInFilesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tReplaceInFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIReplaceInFilesDeprecatedRequest\n\n\t// ReplaceInFilesDeprecatedExecute executes the request\n\t//  @return []ReplaceResult\n\t// Deprecated\n\tReplaceInFilesDeprecatedExecute(r ToolboxAPIReplaceInFilesDeprecatedRequest) ([]ReplaceResult, *http.Response, error)\n\n\t/*\n\tResizePTYSessionDeprecated [DEPRECATED] Resize PTY session\n\n\tResize a PTY session\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@param sessionId\n\t@return ToolboxAPIResizePTYSessionDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tResizePTYSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIResizePTYSessionDeprecatedRequest\n\n\t// ResizePTYSessionDeprecatedExecute executes the request\n\t//  @return PtySessionInfo\n\t// Deprecated\n\tResizePTYSessionDeprecatedExecute(r ToolboxAPIResizePTYSessionDeprecatedRequest) (*PtySessionInfo, *http.Response, error)\n\n\t/*\n\tRestartProcessDeprecated [DEPRECATED] Restart process\n\n\tRestart a specific VNC process\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param processName\n\t@param sandboxId\n\t@return ToolboxAPIRestartProcessDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tRestartProcessDeprecated(ctx context.Context, processName string, sandboxId string) ToolboxAPIRestartProcessDeprecatedRequest\n\n\t// RestartProcessDeprecatedExecute executes the request\n\t//  @return ProcessRestartResponse\n\t// Deprecated\n\tRestartProcessDeprecatedExecute(r ToolboxAPIRestartProcessDeprecatedRequest) (*ProcessRestartResponse, *http.Response, error)\n\n\t/*\n\tScrollMouseDeprecated [DEPRECATED] Scroll mouse\n\n\tScroll mouse at specified coordinates\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIScrollMouseDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tScrollMouseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIScrollMouseDeprecatedRequest\n\n\t// ScrollMouseDeprecatedExecute executes the request\n\t//  @return MouseScrollResponse\n\t// Deprecated\n\tScrollMouseDeprecatedExecute(r ToolboxAPIScrollMouseDeprecatedRequest) (*MouseScrollResponse, *http.Response, error)\n\n\t/*\n\tSearchFilesDeprecated [DEPRECATED] Search files\n\n\tSearch for files inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPISearchFilesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tSearchFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPISearchFilesDeprecatedRequest\n\n\t// SearchFilesDeprecatedExecute executes the request\n\t//  @return SearchFilesResponse\n\t// Deprecated\n\tSearchFilesDeprecatedExecute(r ToolboxAPISearchFilesDeprecatedRequest) (*SearchFilesResponse, *http.Response, error)\n\n\t/*\n\tSetFilePermissionsDeprecated [DEPRECATED] Set file permissions\n\n\tSet file owner/group/permissions inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPISetFilePermissionsDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tSetFilePermissionsDeprecated(ctx context.Context, sandboxId string) ToolboxAPISetFilePermissionsDeprecatedRequest\n\n\t// SetFilePermissionsDeprecatedExecute executes the request\n\t// Deprecated\n\tSetFilePermissionsDeprecatedExecute(r ToolboxAPISetFilePermissionsDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tStartComputerUseDeprecated [DEPRECATED] Start computer use processes\n\n\tStart all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIStartComputerUseDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tStartComputerUseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIStartComputerUseDeprecatedRequest\n\n\t// StartComputerUseDeprecatedExecute executes the request\n\t//  @return ComputerUseStartResponse\n\t// Deprecated\n\tStartComputerUseDeprecatedExecute(r ToolboxAPIStartComputerUseDeprecatedRequest) (*ComputerUseStartResponse, *http.Response, error)\n\n\t/*\n\tStopComputerUseDeprecated [DEPRECATED] Stop computer use processes\n\n\tStop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIStopComputerUseDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tStopComputerUseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIStopComputerUseDeprecatedRequest\n\n\t// StopComputerUseDeprecatedExecute executes the request\n\t//  @return ComputerUseStopResponse\n\t// Deprecated\n\tStopComputerUseDeprecatedExecute(r ToolboxAPIStopComputerUseDeprecatedRequest) (*ComputerUseStopResponse, *http.Response, error)\n\n\t/*\n\tTakeCompressedRegionScreenshotDeprecated [DEPRECATED] Take compressed region screenshot\n\n\tTake a compressed screenshot of a specific region\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tTakeCompressedRegionScreenshotDeprecated(ctx context.Context, sandboxId string) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest\n\n\t// TakeCompressedRegionScreenshotDeprecatedExecute executes the request\n\t//  @return CompressedScreenshotResponse\n\t// Deprecated\n\tTakeCompressedRegionScreenshotDeprecatedExecute(r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) (*CompressedScreenshotResponse, *http.Response, error)\n\n\t/*\n\tTakeCompressedScreenshotDeprecated [DEPRECATED] Take compressed screenshot\n\n\tTake a compressed screenshot with format, quality, and scale options\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPITakeCompressedScreenshotDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tTakeCompressedScreenshotDeprecated(ctx context.Context, sandboxId string) ToolboxAPITakeCompressedScreenshotDeprecatedRequest\n\n\t// TakeCompressedScreenshotDeprecatedExecute executes the request\n\t//  @return CompressedScreenshotResponse\n\t// Deprecated\n\tTakeCompressedScreenshotDeprecatedExecute(r ToolboxAPITakeCompressedScreenshotDeprecatedRequest) (*CompressedScreenshotResponse, *http.Response, error)\n\n\t/*\n\tTakeRegionScreenshotDeprecated [DEPRECATED] Take region screenshot\n\n\tTake a screenshot of a specific region\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPITakeRegionScreenshotDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tTakeRegionScreenshotDeprecated(ctx context.Context, sandboxId string) ToolboxAPITakeRegionScreenshotDeprecatedRequest\n\n\t// TakeRegionScreenshotDeprecatedExecute executes the request\n\t//  @return RegionScreenshotResponse\n\t// Deprecated\n\tTakeRegionScreenshotDeprecatedExecute(r ToolboxAPITakeRegionScreenshotDeprecatedRequest) (*RegionScreenshotResponse, *http.Response, error)\n\n\t/*\n\tTakeScreenshotDeprecated [DEPRECATED] Take screenshot\n\n\tTake a screenshot of the entire screen\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPITakeScreenshotDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tTakeScreenshotDeprecated(ctx context.Context, sandboxId string) ToolboxAPITakeScreenshotDeprecatedRequest\n\n\t// TakeScreenshotDeprecatedExecute executes the request\n\t//  @return ScreenshotResponse\n\t// Deprecated\n\tTakeScreenshotDeprecatedExecute(r ToolboxAPITakeScreenshotDeprecatedRequest) (*ScreenshotResponse, *http.Response, error)\n\n\t/*\n\tTypeTextDeprecated [DEPRECATED] Type text\n\n\tType text using keyboard\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPITypeTextDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tTypeTextDeprecated(ctx context.Context, sandboxId string) ToolboxAPITypeTextDeprecatedRequest\n\n\t// TypeTextDeprecatedExecute executes the request\n\t// Deprecated\n\tTypeTextDeprecatedExecute(r ToolboxAPITypeTextDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tUploadFileDeprecated [DEPRECATED] Upload file\n\n\tUpload file inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIUploadFileDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tUploadFileDeprecated(ctx context.Context, sandboxId string) ToolboxAPIUploadFileDeprecatedRequest\n\n\t// UploadFileDeprecatedExecute executes the request\n\t// Deprecated\n\tUploadFileDeprecatedExecute(r ToolboxAPIUploadFileDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tUploadFilesDeprecated [DEPRECATED] Upload multiple files\n\n\tUpload multiple files inside sandbox\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param sandboxId\n\t@return ToolboxAPIUploadFilesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tUploadFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIUploadFilesDeprecatedRequest\n\n\t// UploadFilesDeprecatedExecute executes the request\n\t// Deprecated\n\tUploadFilesDeprecatedExecute(r ToolboxAPIUploadFilesDeprecatedRequest) (*http.Response, error)\n}\n\n// ToolboxAPIService ToolboxAPI service\ntype ToolboxAPIService service\n\ntype ToolboxAPIClickMouseDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tmouseClickRequest *MouseClickRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIClickMouseDeprecatedRequest) MouseClickRequest(mouseClickRequest MouseClickRequest) ToolboxAPIClickMouseDeprecatedRequest {\n\tr.mouseClickRequest = &mouseClickRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIClickMouseDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIClickMouseDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIClickMouseDeprecatedRequest) Execute() (*MouseClickResponse, *http.Response, error) {\n\treturn r.ApiService.ClickMouseDeprecatedExecute(r)\n}\n\n/*\nClickMouseDeprecated [DEPRECATED] Click mouse\n\nClick mouse at specified coordinates\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIClickMouseDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ClickMouseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIClickMouseDeprecatedRequest {\n\treturn ToolboxAPIClickMouseDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return MouseClickResponse\n// Deprecated\nfunc (a *ToolboxAPIService) ClickMouseDeprecatedExecute(r ToolboxAPIClickMouseDeprecatedRequest) (*MouseClickResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *MouseClickResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ClickMouseDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/mouse/click\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.mouseClickRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"mouseClickRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.mouseClickRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPICreateFolderDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\tmode *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPICreateFolderDeprecatedRequest) Path(path string) ToolboxAPICreateFolderDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\nfunc (r ToolboxAPICreateFolderDeprecatedRequest) Mode(mode string) ToolboxAPICreateFolderDeprecatedRequest {\n\tr.mode = &mode\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPICreateFolderDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPICreateFolderDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPICreateFolderDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.CreateFolderDeprecatedExecute(r)\n}\n\n/*\nCreateFolderDeprecated [DEPRECATED] Create folder\n\nCreate folder inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPICreateFolderDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) CreateFolderDeprecated(ctx context.Context, sandboxId string) ToolboxAPICreateFolderDeprecatedRequest {\n\treturn ToolboxAPICreateFolderDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) CreateFolderDeprecatedExecute(r ToolboxAPICreateFolderDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.CreateFolderDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/folder\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn nil, reportError(\"path is required and must be specified\")\n\t}\n\tif r.mode == nil {\n\t\treturn nil, reportError(\"mode is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"mode\", r.mode, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPICreatePTYSessionDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tptyCreateRequest *PtyCreateRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPICreatePTYSessionDeprecatedRequest) PtyCreateRequest(ptyCreateRequest PtyCreateRequest) ToolboxAPICreatePTYSessionDeprecatedRequest {\n\tr.ptyCreateRequest = &ptyCreateRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPICreatePTYSessionDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPICreatePTYSessionDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPICreatePTYSessionDeprecatedRequest) Execute() (*PtyCreateResponse, *http.Response, error) {\n\treturn r.ApiService.CreatePTYSessionDeprecatedExecute(r)\n}\n\n/*\nCreatePTYSessionDeprecated [DEPRECATED] Create PTY session\n\nCreate a new PTY session in the sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPICreatePTYSessionDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) CreatePTYSessionDeprecated(ctx context.Context, sandboxId string) ToolboxAPICreatePTYSessionDeprecatedRequest {\n\treturn ToolboxAPICreatePTYSessionDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return PtyCreateResponse\n// Deprecated\nfunc (a *ToolboxAPIService) CreatePTYSessionDeprecatedExecute(r ToolboxAPICreatePTYSessionDeprecatedRequest) (*PtyCreateResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PtyCreateResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.CreatePTYSessionDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/pty\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.ptyCreateRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"ptyCreateRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.ptyCreateRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPICreateSessionDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tcreateSessionRequest *CreateSessionRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPICreateSessionDeprecatedRequest) CreateSessionRequest(createSessionRequest CreateSessionRequest) ToolboxAPICreateSessionDeprecatedRequest {\n\tr.createSessionRequest = &createSessionRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPICreateSessionDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPICreateSessionDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPICreateSessionDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.CreateSessionDeprecatedExecute(r)\n}\n\n/*\nCreateSessionDeprecated [DEPRECATED] Create session\n\nCreate a new session in the sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPICreateSessionDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) CreateSessionDeprecated(ctx context.Context, sandboxId string) ToolboxAPICreateSessionDeprecatedRequest {\n\treturn ToolboxAPICreateSessionDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) CreateSessionDeprecatedExecute(r ToolboxAPICreateSessionDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.CreateSessionDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/session\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createSessionRequest == nil {\n\t\treturn nil, reportError(\"createSessionRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createSessionRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIDeleteFileDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\txDaytonaOrganizationID *string\n\trecursive *bool\n}\n\nfunc (r ToolboxAPIDeleteFileDeprecatedRequest) Path(path string) ToolboxAPIDeleteFileDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIDeleteFileDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIDeleteFileDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIDeleteFileDeprecatedRequest) Recursive(recursive bool) ToolboxAPIDeleteFileDeprecatedRequest {\n\tr.recursive = &recursive\n\treturn r\n}\n\nfunc (r ToolboxAPIDeleteFileDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteFileDeprecatedExecute(r)\n}\n\n/*\nDeleteFileDeprecated [DEPRECATED] Delete file\n\nDelete file inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIDeleteFileDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) DeleteFileDeprecated(ctx context.Context, sandboxId string) ToolboxAPIDeleteFileDeprecatedRequest {\n\treturn ToolboxAPIDeleteFileDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) DeleteFileDeprecatedExecute(r ToolboxAPIDeleteFileDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.DeleteFileDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn nil, reportError(\"path is required and must be specified\")\n\t}\n\n\tif r.recursive != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"recursive\", r.recursive, \"form\", \"\")\n\t}\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIDeletePTYSessionDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsessionId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIDeletePTYSessionDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIDeletePTYSessionDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIDeletePTYSessionDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeletePTYSessionDeprecatedExecute(r)\n}\n\n/*\nDeletePTYSessionDeprecated [DEPRECATED] Delete PTY session\n\nDelete a PTY session and terminate the associated process\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @param sessionId\n @return ToolboxAPIDeletePTYSessionDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) DeletePTYSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIDeletePTYSessionDeprecatedRequest {\n\treturn ToolboxAPIDeletePTYSessionDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tsessionId: sessionId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) DeletePTYSessionDeprecatedExecute(r ToolboxAPIDeletePTYSessionDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.DeletePTYSessionDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sessionId\"+\"}\", url.PathEscape(parameterValueToString(r.sessionId, \"sessionId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIDeleteSessionDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsessionId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIDeleteSessionDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIDeleteSessionDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIDeleteSessionDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteSessionDeprecatedExecute(r)\n}\n\n/*\nDeleteSessionDeprecated [DEPRECATED] Delete session\n\nDelete a specific session\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @param sessionId\n @return ToolboxAPIDeleteSessionDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) DeleteSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIDeleteSessionDeprecatedRequest {\n\treturn ToolboxAPIDeleteSessionDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tsessionId: sessionId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) DeleteSessionDeprecatedExecute(r ToolboxAPIDeleteSessionDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.DeleteSessionDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/session/{sessionId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sessionId\"+\"}\", url.PathEscape(parameterValueToString(r.sessionId, \"sessionId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIDownloadFileDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIDownloadFileDeprecatedRequest) Path(path string) ToolboxAPIDownloadFileDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIDownloadFileDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIDownloadFileDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIDownloadFileDeprecatedRequest) Execute() (*os.File, *http.Response, error) {\n\treturn r.ApiService.DownloadFileDeprecatedExecute(r)\n}\n\n/*\nDownloadFileDeprecated [DEPRECATED] Download file\n\nDownload file from sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIDownloadFileDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) DownloadFileDeprecated(ctx context.Context, sandboxId string) ToolboxAPIDownloadFileDeprecatedRequest {\n\treturn ToolboxAPIDownloadFileDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return *os.File\n// Deprecated\nfunc (a *ToolboxAPIService) DownloadFileDeprecatedExecute(r ToolboxAPIDownloadFileDeprecatedRequest) (*os.File, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *os.File\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.DownloadFileDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/download\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"path is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIDownloadFilesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tdownloadFiles *DownloadFiles\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIDownloadFilesDeprecatedRequest) DownloadFiles(downloadFiles DownloadFiles) ToolboxAPIDownloadFilesDeprecatedRequest {\n\tr.downloadFiles = &downloadFiles\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIDownloadFilesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIDownloadFilesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIDownloadFilesDeprecatedRequest) Execute() (*os.File, *http.Response, error) {\n\treturn r.ApiService.DownloadFilesDeprecatedExecute(r)\n}\n\n/*\nDownloadFilesDeprecated [DEPRECATED] Download multiple files\n\nStreams back a multipart/form-data bundle of the requested paths\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIDownloadFilesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) DownloadFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIDownloadFilesDeprecatedRequest {\n\treturn ToolboxAPIDownloadFilesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return *os.File\n// Deprecated\nfunc (a *ToolboxAPIService) DownloadFilesDeprecatedExecute(r ToolboxAPIDownloadFilesDeprecatedRequest) (*os.File, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *os.File\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.DownloadFilesDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/bulk-download\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.downloadFiles == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"downloadFiles is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.downloadFiles\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIDragMouseDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tmouseDragRequest *MouseDragRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIDragMouseDeprecatedRequest) MouseDragRequest(mouseDragRequest MouseDragRequest) ToolboxAPIDragMouseDeprecatedRequest {\n\tr.mouseDragRequest = &mouseDragRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIDragMouseDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIDragMouseDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIDragMouseDeprecatedRequest) Execute() (*MouseDragResponse, *http.Response, error) {\n\treturn r.ApiService.DragMouseDeprecatedExecute(r)\n}\n\n/*\nDragMouseDeprecated [DEPRECATED] Drag mouse\n\nDrag mouse from start to end coordinates\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIDragMouseDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) DragMouseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIDragMouseDeprecatedRequest {\n\treturn ToolboxAPIDragMouseDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return MouseDragResponse\n// Deprecated\nfunc (a *ToolboxAPIService) DragMouseDeprecatedExecute(r ToolboxAPIDragMouseDeprecatedRequest) (*MouseDragResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *MouseDragResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.DragMouseDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/mouse/drag\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.mouseDragRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"mouseDragRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.mouseDragRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIExecuteCommandDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\texecuteRequest *ExecuteRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIExecuteCommandDeprecatedRequest) ExecuteRequest(executeRequest ExecuteRequest) ToolboxAPIExecuteCommandDeprecatedRequest {\n\tr.executeRequest = &executeRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIExecuteCommandDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIExecuteCommandDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIExecuteCommandDeprecatedRequest) Execute() (*ExecuteResponse, *http.Response, error) {\n\treturn r.ApiService.ExecuteCommandDeprecatedExecute(r)\n}\n\n/*\nExecuteCommandDeprecated [DEPRECATED] Execute command\n\nExecute command synchronously inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIExecuteCommandDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ExecuteCommandDeprecated(ctx context.Context, sandboxId string) ToolboxAPIExecuteCommandDeprecatedRequest {\n\treturn ToolboxAPIExecuteCommandDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ExecuteResponse\n// Deprecated\nfunc (a *ToolboxAPIService) ExecuteCommandDeprecatedExecute(r ToolboxAPIExecuteCommandDeprecatedRequest) (*ExecuteResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ExecuteResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ExecuteCommandDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/execute\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.executeRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"executeRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.executeRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIExecuteSessionCommandDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsessionId string\n\tsessionExecuteRequest *SessionExecuteRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIExecuteSessionCommandDeprecatedRequest) SessionExecuteRequest(sessionExecuteRequest SessionExecuteRequest) ToolboxAPIExecuteSessionCommandDeprecatedRequest {\n\tr.sessionExecuteRequest = &sessionExecuteRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIExecuteSessionCommandDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIExecuteSessionCommandDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIExecuteSessionCommandDeprecatedRequest) Execute() (*SessionExecuteResponse, *http.Response, error) {\n\treturn r.ApiService.ExecuteSessionCommandDeprecatedExecute(r)\n}\n\n/*\nExecuteSessionCommandDeprecated [DEPRECATED] Execute command in session\n\nExecute a command in a specific session\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @param sessionId\n @return ToolboxAPIExecuteSessionCommandDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ExecuteSessionCommandDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIExecuteSessionCommandDeprecatedRequest {\n\treturn ToolboxAPIExecuteSessionCommandDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tsessionId: sessionId,\n\t}\n}\n\n// Execute executes the request\n//  @return SessionExecuteResponse\n// Deprecated\nfunc (a *ToolboxAPIService) ExecuteSessionCommandDeprecatedExecute(r ToolboxAPIExecuteSessionCommandDeprecatedRequest) (*SessionExecuteResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SessionExecuteResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ExecuteSessionCommandDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/exec\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sessionId\"+\"}\", url.PathEscape(parameterValueToString(r.sessionId, \"sessionId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.sessionExecuteRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"sessionExecuteRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.sessionExecuteRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIFindInFilesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\tpattern *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIFindInFilesDeprecatedRequest) Path(path string) ToolboxAPIFindInFilesDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\nfunc (r ToolboxAPIFindInFilesDeprecatedRequest) Pattern(pattern string) ToolboxAPIFindInFilesDeprecatedRequest {\n\tr.pattern = &pattern\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIFindInFilesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIFindInFilesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIFindInFilesDeprecatedRequest) Execute() ([]Match, *http.Response, error) {\n\treturn r.ApiService.FindInFilesDeprecatedExecute(r)\n}\n\n/*\nFindInFilesDeprecated [DEPRECATED] Search for text/pattern in files\n\nSearch for text/pattern inside sandbox files\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIFindInFilesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) FindInFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIFindInFilesDeprecatedRequest {\n\treturn ToolboxAPIFindInFilesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return []Match\n// Deprecated\nfunc (a *ToolboxAPIService) FindInFilesDeprecatedExecute(r ToolboxAPIFindInFilesDeprecatedRequest) ([]Match, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Match\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.FindInFilesDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/find\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"path is required and must be specified\")\n\t}\n\tif r.pattern == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"pattern is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"pattern\", r.pattern, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetComputerUseStatusDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetComputerUseStatusDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetComputerUseStatusDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetComputerUseStatusDeprecatedRequest) Execute() (*ComputerUseStatusResponse, *http.Response, error) {\n\treturn r.ApiService.GetComputerUseStatusDeprecatedExecute(r)\n}\n\n/*\nGetComputerUseStatusDeprecated [DEPRECATED] Get computer use status\n\nGet status of all VNC desktop processes\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGetComputerUseStatusDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetComputerUseStatusDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetComputerUseStatusDeprecatedRequest {\n\treturn ToolboxAPIGetComputerUseStatusDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ComputerUseStatusResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetComputerUseStatusDeprecatedExecute(r ToolboxAPIGetComputerUseStatusDeprecatedRequest) (*ComputerUseStatusResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ComputerUseStatusResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetComputerUseStatusDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/status\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetDisplayInfoDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetDisplayInfoDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetDisplayInfoDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetDisplayInfoDeprecatedRequest) Execute() (*DisplayInfoResponse, *http.Response, error) {\n\treturn r.ApiService.GetDisplayInfoDeprecatedExecute(r)\n}\n\n/*\nGetDisplayInfoDeprecated [DEPRECATED] Get display info\n\nGet information about displays\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGetDisplayInfoDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetDisplayInfoDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetDisplayInfoDeprecatedRequest {\n\treturn ToolboxAPIGetDisplayInfoDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return DisplayInfoResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetDisplayInfoDeprecatedExecute(r ToolboxAPIGetDisplayInfoDeprecatedRequest) (*DisplayInfoResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *DisplayInfoResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetDisplayInfoDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/display/info\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetFileInfoDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGetFileInfoDeprecatedRequest) Path(path string) ToolboxAPIGetFileInfoDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetFileInfoDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetFileInfoDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetFileInfoDeprecatedRequest) Execute() (*FileInfo, *http.Response, error) {\n\treturn r.ApiService.GetFileInfoDeprecatedExecute(r)\n}\n\n/*\nGetFileInfoDeprecated [DEPRECATED] Get file info\n\nGet file info inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGetFileInfoDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetFileInfoDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetFileInfoDeprecatedRequest {\n\treturn ToolboxAPIGetFileInfoDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return FileInfo\n// Deprecated\nfunc (a *ToolboxAPIService) GetFileInfoDeprecatedExecute(r ToolboxAPIGetFileInfoDeprecatedRequest) (*FileInfo, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *FileInfo\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetFileInfoDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/info\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"path is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetMousePositionDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetMousePositionDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetMousePositionDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetMousePositionDeprecatedRequest) Execute() (*MousePosition, *http.Response, error) {\n\treturn r.ApiService.GetMousePositionDeprecatedExecute(r)\n}\n\n/*\nGetMousePositionDeprecated [DEPRECATED] Get mouse position\n\nGet current mouse cursor position\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGetMousePositionDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetMousePositionDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetMousePositionDeprecatedRequest {\n\treturn ToolboxAPIGetMousePositionDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return MousePosition\n// Deprecated\nfunc (a *ToolboxAPIService) GetMousePositionDeprecatedExecute(r ToolboxAPIGetMousePositionDeprecatedRequest) (*MousePosition, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *MousePosition\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetMousePositionDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/mouse/position\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetPTYSessionDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsessionId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetPTYSessionDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetPTYSessionDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetPTYSessionDeprecatedRequest) Execute() (*PtySessionInfo, *http.Response, error) {\n\treturn r.ApiService.GetPTYSessionDeprecatedExecute(r)\n}\n\n/*\nGetPTYSessionDeprecated [DEPRECATED] Get PTY session\n\nGet PTY session information by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @param sessionId\n @return ToolboxAPIGetPTYSessionDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetPTYSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIGetPTYSessionDeprecatedRequest {\n\treturn ToolboxAPIGetPTYSessionDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tsessionId: sessionId,\n\t}\n}\n\n// Execute executes the request\n//  @return PtySessionInfo\n// Deprecated\nfunc (a *ToolboxAPIService) GetPTYSessionDeprecatedExecute(r ToolboxAPIGetPTYSessionDeprecatedRequest) (*PtySessionInfo, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PtySessionInfo\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetPTYSessionDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sessionId\"+\"}\", url.PathEscape(parameterValueToString(r.sessionId, \"sessionId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetProcessErrorsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tprocessName string\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetProcessErrorsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetProcessErrorsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetProcessErrorsDeprecatedRequest) Execute() (*ProcessErrorsResponse, *http.Response, error) {\n\treturn r.ApiService.GetProcessErrorsDeprecatedExecute(r)\n}\n\n/*\nGetProcessErrorsDeprecated [DEPRECATED] Get process errors\n\nGet error logs for a specific VNC process\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param processName\n @param sandboxId\n @return ToolboxAPIGetProcessErrorsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetProcessErrorsDeprecated(ctx context.Context, processName string, sandboxId string) ToolboxAPIGetProcessErrorsDeprecatedRequest {\n\treturn ToolboxAPIGetProcessErrorsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tprocessName: processName,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ProcessErrorsResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetProcessErrorsDeprecatedExecute(r ToolboxAPIGetProcessErrorsDeprecatedRequest) (*ProcessErrorsResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ProcessErrorsResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetProcessErrorsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/errors\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"processName\"+\"}\", url.PathEscape(parameterValueToString(r.processName, \"processName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetProcessLogsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tprocessName string\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetProcessLogsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetProcessLogsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetProcessLogsDeprecatedRequest) Execute() (*ProcessLogsResponse, *http.Response, error) {\n\treturn r.ApiService.GetProcessLogsDeprecatedExecute(r)\n}\n\n/*\nGetProcessLogsDeprecated [DEPRECATED] Get process logs\n\nGet logs for a specific VNC process\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param processName\n @param sandboxId\n @return ToolboxAPIGetProcessLogsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetProcessLogsDeprecated(ctx context.Context, processName string, sandboxId string) ToolboxAPIGetProcessLogsDeprecatedRequest {\n\treturn ToolboxAPIGetProcessLogsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tprocessName: processName,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ProcessLogsResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetProcessLogsDeprecatedExecute(r ToolboxAPIGetProcessLogsDeprecatedRequest) (*ProcessLogsResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ProcessLogsResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetProcessLogsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/logs\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"processName\"+\"}\", url.PathEscape(parameterValueToString(r.processName, \"processName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetProcessStatusDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tprocessName string\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetProcessStatusDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetProcessStatusDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetProcessStatusDeprecatedRequest) Execute() (*ProcessStatusResponse, *http.Response, error) {\n\treturn r.ApiService.GetProcessStatusDeprecatedExecute(r)\n}\n\n/*\nGetProcessStatusDeprecated [DEPRECATED] Get process status\n\nGet status of a specific VNC process\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param processName\n @param sandboxId\n @return ToolboxAPIGetProcessStatusDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetProcessStatusDeprecated(ctx context.Context, processName string, sandboxId string) ToolboxAPIGetProcessStatusDeprecatedRequest {\n\treturn ToolboxAPIGetProcessStatusDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tprocessName: processName,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ProcessStatusResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetProcessStatusDeprecatedExecute(r ToolboxAPIGetProcessStatusDeprecatedRequest) (*ProcessStatusResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ProcessStatusResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetProcessStatusDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/status\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"processName\"+\"}\", url.PathEscape(parameterValueToString(r.processName, \"processName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetProjectDirDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetProjectDirDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetProjectDirDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetProjectDirDeprecatedRequest) Execute() (*ProjectDirResponse, *http.Response, error) {\n\treturn r.ApiService.GetProjectDirDeprecatedExecute(r)\n}\n\n/*\nGetProjectDirDeprecated [DEPRECATED] Get sandbox project dir\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGetProjectDirDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetProjectDirDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetProjectDirDeprecatedRequest {\n\treturn ToolboxAPIGetProjectDirDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ProjectDirResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetProjectDirDeprecatedExecute(r ToolboxAPIGetProjectDirDeprecatedRequest) (*ProjectDirResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ProjectDirResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetProjectDirDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/project-dir\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetSessionCommandDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsessionId string\n\tcommandId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetSessionCommandDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetSessionCommandDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetSessionCommandDeprecatedRequest) Execute() (*Command, *http.Response, error) {\n\treturn r.ApiService.GetSessionCommandDeprecatedExecute(r)\n}\n\n/*\nGetSessionCommandDeprecated [DEPRECATED] Get session command\n\nGet session command by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @param sessionId\n @param commandId\n @return ToolboxAPIGetSessionCommandDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetSessionCommandDeprecated(ctx context.Context, sandboxId string, sessionId string, commandId string) ToolboxAPIGetSessionCommandDeprecatedRequest {\n\treturn ToolboxAPIGetSessionCommandDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tsessionId: sessionId,\n\t\tcommandId: commandId,\n\t}\n}\n\n// Execute executes the request\n//  @return Command\n// Deprecated\nfunc (a *ToolboxAPIService) GetSessionCommandDeprecatedExecute(r ToolboxAPIGetSessionCommandDeprecatedRequest) (*Command, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Command\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetSessionCommandDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sessionId\"+\"}\", url.PathEscape(parameterValueToString(r.sessionId, \"sessionId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"commandId\"+\"}\", url.PathEscape(parameterValueToString(r.commandId, \"commandId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetSessionCommandLogsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsessionId string\n\tcommandId string\n\txDaytonaOrganizationID *string\n\tfollow *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetSessionCommandLogsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetSessionCommandLogsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Whether to stream the logs\nfunc (r ToolboxAPIGetSessionCommandLogsDeprecatedRequest) Follow(follow bool) ToolboxAPIGetSessionCommandLogsDeprecatedRequest {\n\tr.follow = &follow\n\treturn r\n}\n\nfunc (r ToolboxAPIGetSessionCommandLogsDeprecatedRequest) Execute() (string, *http.Response, error) {\n\treturn r.ApiService.GetSessionCommandLogsDeprecatedExecute(r)\n}\n\n/*\nGetSessionCommandLogsDeprecated [DEPRECATED] Get command logs\n\nGet logs for a specific command in a session\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @param sessionId\n @param commandId\n @return ToolboxAPIGetSessionCommandLogsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetSessionCommandLogsDeprecated(ctx context.Context, sandboxId string, sessionId string, commandId string) ToolboxAPIGetSessionCommandLogsDeprecatedRequest {\n\treturn ToolboxAPIGetSessionCommandLogsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tsessionId: sessionId,\n\t\tcommandId: commandId,\n\t}\n}\n\n// Execute executes the request\n//  @return string\n// Deprecated\nfunc (a *ToolboxAPIService) GetSessionCommandLogsDeprecatedExecute(r ToolboxAPIGetSessionCommandLogsDeprecatedRequest) (string, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  string\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetSessionCommandLogsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}/logs\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sessionId\"+\"}\", url.PathEscape(parameterValueToString(r.sessionId, \"sessionId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"commandId\"+\"}\", url.PathEscape(parameterValueToString(r.commandId, \"commandId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.follow != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"follow\", r.follow, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"text/plain\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetSessionDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsessionId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetSessionDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetSessionDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetSessionDeprecatedRequest) Execute() (*Session, *http.Response, error) {\n\treturn r.ApiService.GetSessionDeprecatedExecute(r)\n}\n\n/*\nGetSessionDeprecated [DEPRECATED] Get session\n\nGet session by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @param sessionId\n @return ToolboxAPIGetSessionDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIGetSessionDeprecatedRequest {\n\treturn ToolboxAPIGetSessionDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tsessionId: sessionId,\n\t}\n}\n\n// Execute executes the request\n//  @return Session\n// Deprecated\nfunc (a *ToolboxAPIService) GetSessionDeprecatedExecute(r ToolboxAPIGetSessionDeprecatedRequest) (*Session, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Session\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetSessionDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/session/{sessionId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sessionId\"+\"}\", url.PathEscape(parameterValueToString(r.sessionId, \"sessionId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetUserHomeDirDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetUserHomeDirDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetUserHomeDirDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetUserHomeDirDeprecatedRequest) Execute() (*UserHomeDirResponse, *http.Response, error) {\n\treturn r.ApiService.GetUserHomeDirDeprecatedExecute(r)\n}\n\n/*\nGetUserHomeDirDeprecated [DEPRECATED] Get sandbox user home dir\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGetUserHomeDirDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetUserHomeDirDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetUserHomeDirDeprecatedRequest {\n\treturn ToolboxAPIGetUserHomeDirDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return UserHomeDirResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetUserHomeDirDeprecatedExecute(r ToolboxAPIGetUserHomeDirDeprecatedRequest) (*UserHomeDirResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *UserHomeDirResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetUserHomeDirDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/user-home-dir\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetWindowsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetWindowsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetWindowsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetWindowsDeprecatedRequest) Execute() (*WindowsResponse, *http.Response, error) {\n\treturn r.ApiService.GetWindowsDeprecatedExecute(r)\n}\n\n/*\nGetWindowsDeprecated [DEPRECATED] Get windows\n\nGet list of open windows\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGetWindowsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetWindowsDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetWindowsDeprecatedRequest {\n\treturn ToolboxAPIGetWindowsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return WindowsResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetWindowsDeprecatedExecute(r ToolboxAPIGetWindowsDeprecatedRequest) (*WindowsResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *WindowsResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetWindowsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/display/windows\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGetWorkDirDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGetWorkDirDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGetWorkDirDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGetWorkDirDeprecatedRequest) Execute() (*WorkDirResponse, *http.Response, error) {\n\treturn r.ApiService.GetWorkDirDeprecatedExecute(r)\n}\n\n/*\nGetWorkDirDeprecated [DEPRECATED] Get sandbox work-dir\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGetWorkDirDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GetWorkDirDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGetWorkDirDeprecatedRequest {\n\treturn ToolboxAPIGetWorkDirDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return WorkDirResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GetWorkDirDeprecatedExecute(r ToolboxAPIGetWorkDirDeprecatedRequest) (*WorkDirResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *WorkDirResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GetWorkDirDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/work-dir\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitAddFilesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tgitAddRequest *GitAddRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitAddFilesDeprecatedRequest) GitAddRequest(gitAddRequest GitAddRequest) ToolboxAPIGitAddFilesDeprecatedRequest {\n\tr.gitAddRequest = &gitAddRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitAddFilesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitAddFilesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitAddFilesDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GitAddFilesDeprecatedExecute(r)\n}\n\n/*\nGitAddFilesDeprecated [DEPRECATED] Add files\n\nAdd files to git commit\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitAddFilesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitAddFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitAddFilesDeprecatedRequest {\n\treturn ToolboxAPIGitAddFilesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) GitAddFilesDeprecatedExecute(r ToolboxAPIGitAddFilesDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitAddFilesDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/add\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.gitAddRequest == nil {\n\t\treturn nil, reportError(\"gitAddRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.gitAddRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitCheckoutBranchDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tgitCheckoutRequest *GitCheckoutRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitCheckoutBranchDeprecatedRequest) GitCheckoutRequest(gitCheckoutRequest GitCheckoutRequest) ToolboxAPIGitCheckoutBranchDeprecatedRequest {\n\tr.gitCheckoutRequest = &gitCheckoutRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitCheckoutBranchDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitCheckoutBranchDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitCheckoutBranchDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GitCheckoutBranchDeprecatedExecute(r)\n}\n\n/*\nGitCheckoutBranchDeprecated [DEPRECATED] Checkout branch\n\nCheckout branch or commit in git repository\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitCheckoutBranchDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitCheckoutBranchDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitCheckoutBranchDeprecatedRequest {\n\treturn ToolboxAPIGitCheckoutBranchDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) GitCheckoutBranchDeprecatedExecute(r ToolboxAPIGitCheckoutBranchDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitCheckoutBranchDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/checkout\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.gitCheckoutRequest == nil {\n\t\treturn nil, reportError(\"gitCheckoutRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.gitCheckoutRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitCloneRepositoryDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tgitCloneRequest *GitCloneRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitCloneRepositoryDeprecatedRequest) GitCloneRequest(gitCloneRequest GitCloneRequest) ToolboxAPIGitCloneRepositoryDeprecatedRequest {\n\tr.gitCloneRequest = &gitCloneRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitCloneRepositoryDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitCloneRepositoryDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitCloneRepositoryDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GitCloneRepositoryDeprecatedExecute(r)\n}\n\n/*\nGitCloneRepositoryDeprecated [DEPRECATED] Clone repository\n\nClone git repository\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitCloneRepositoryDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitCloneRepositoryDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitCloneRepositoryDeprecatedRequest {\n\treturn ToolboxAPIGitCloneRepositoryDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) GitCloneRepositoryDeprecatedExecute(r ToolboxAPIGitCloneRepositoryDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitCloneRepositoryDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/clone\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.gitCloneRequest == nil {\n\t\treturn nil, reportError(\"gitCloneRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.gitCloneRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitCommitChangesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tgitCommitRequest *GitCommitRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitCommitChangesDeprecatedRequest) GitCommitRequest(gitCommitRequest GitCommitRequest) ToolboxAPIGitCommitChangesDeprecatedRequest {\n\tr.gitCommitRequest = &gitCommitRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitCommitChangesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitCommitChangesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitCommitChangesDeprecatedRequest) Execute() (*GitCommitResponse, *http.Response, error) {\n\treturn r.ApiService.GitCommitChangesDeprecatedExecute(r)\n}\n\n/*\nGitCommitChangesDeprecated [DEPRECATED] Commit changes\n\nCommit changes to git repository\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitCommitChangesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitCommitChangesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitCommitChangesDeprecatedRequest {\n\treturn ToolboxAPIGitCommitChangesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return GitCommitResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GitCommitChangesDeprecatedExecute(r ToolboxAPIGitCommitChangesDeprecatedRequest) (*GitCommitResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *GitCommitResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitCommitChangesDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/commit\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.gitCommitRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"gitCommitRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.gitCommitRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitCreateBranchDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tgitBranchRequest *GitBranchRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitCreateBranchDeprecatedRequest) GitBranchRequest(gitBranchRequest GitBranchRequest) ToolboxAPIGitCreateBranchDeprecatedRequest {\n\tr.gitBranchRequest = &gitBranchRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitCreateBranchDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitCreateBranchDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitCreateBranchDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GitCreateBranchDeprecatedExecute(r)\n}\n\n/*\nGitCreateBranchDeprecated [DEPRECATED] Create branch\n\nCreate branch on git repository\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitCreateBranchDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitCreateBranchDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitCreateBranchDeprecatedRequest {\n\treturn ToolboxAPIGitCreateBranchDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) GitCreateBranchDeprecatedExecute(r ToolboxAPIGitCreateBranchDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitCreateBranchDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/branches\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.gitBranchRequest == nil {\n\t\treturn nil, reportError(\"gitBranchRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.gitBranchRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitDeleteBranchDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tgitDeleteBranchRequest *GitDeleteBranchRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitDeleteBranchDeprecatedRequest) GitDeleteBranchRequest(gitDeleteBranchRequest GitDeleteBranchRequest) ToolboxAPIGitDeleteBranchDeprecatedRequest {\n\tr.gitDeleteBranchRequest = &gitDeleteBranchRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitDeleteBranchDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitDeleteBranchDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitDeleteBranchDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GitDeleteBranchDeprecatedExecute(r)\n}\n\n/*\nGitDeleteBranchDeprecated [DEPRECATED] Delete branch\n\nDelete branch on git repository\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitDeleteBranchDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitDeleteBranchDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitDeleteBranchDeprecatedRequest {\n\treturn ToolboxAPIGitDeleteBranchDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) GitDeleteBranchDeprecatedExecute(r ToolboxAPIGitDeleteBranchDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitDeleteBranchDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/branches\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.gitDeleteBranchRequest == nil {\n\t\treturn nil, reportError(\"gitDeleteBranchRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.gitDeleteBranchRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitGetHistoryDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitGetHistoryDeprecatedRequest) Path(path string) ToolboxAPIGitGetHistoryDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitGetHistoryDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitGetHistoryDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitGetHistoryDeprecatedRequest) Execute() ([]GitCommitInfo, *http.Response, error) {\n\treturn r.ApiService.GitGetHistoryDeprecatedExecute(r)\n}\n\n/*\nGitGetHistoryDeprecated [DEPRECATED] Get commit history\n\nGet commit history from git repository\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitGetHistoryDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitGetHistoryDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitGetHistoryDeprecatedRequest {\n\treturn ToolboxAPIGitGetHistoryDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return []GitCommitInfo\n// Deprecated\nfunc (a *ToolboxAPIService) GitGetHistoryDeprecatedExecute(r ToolboxAPIGitGetHistoryDeprecatedRequest) ([]GitCommitInfo, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []GitCommitInfo\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitGetHistoryDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/history\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"path is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitGetStatusDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitGetStatusDeprecatedRequest) Path(path string) ToolboxAPIGitGetStatusDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitGetStatusDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitGetStatusDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitGetStatusDeprecatedRequest) Execute() (*GitStatus, *http.Response, error) {\n\treturn r.ApiService.GitGetStatusDeprecatedExecute(r)\n}\n\n/*\nGitGetStatusDeprecated [DEPRECATED] Get git status\n\nGet status from git repository\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitGetStatusDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitGetStatusDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitGetStatusDeprecatedRequest {\n\treturn ToolboxAPIGitGetStatusDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return GitStatus\n// Deprecated\nfunc (a *ToolboxAPIService) GitGetStatusDeprecatedExecute(r ToolboxAPIGitGetStatusDeprecatedRequest) (*GitStatus, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *GitStatus\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitGetStatusDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/status\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"path is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitListBranchesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitListBranchesDeprecatedRequest) Path(path string) ToolboxAPIGitListBranchesDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitListBranchesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitListBranchesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitListBranchesDeprecatedRequest) Execute() (*ListBranchResponse, *http.Response, error) {\n\treturn r.ApiService.GitListBranchesDeprecatedExecute(r)\n}\n\n/*\nGitListBranchesDeprecated [DEPRECATED] Get branch list\n\nGet branch list from git repository\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitListBranchesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitListBranchesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitListBranchesDeprecatedRequest {\n\treturn ToolboxAPIGitListBranchesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ListBranchResponse\n// Deprecated\nfunc (a *ToolboxAPIService) GitListBranchesDeprecatedExecute(r ToolboxAPIGitListBranchesDeprecatedRequest) (*ListBranchResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ListBranchResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitListBranchesDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/branches\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"path is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitPullChangesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tgitRepoRequest *GitRepoRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitPullChangesDeprecatedRequest) GitRepoRequest(gitRepoRequest GitRepoRequest) ToolboxAPIGitPullChangesDeprecatedRequest {\n\tr.gitRepoRequest = &gitRepoRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitPullChangesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitPullChangesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitPullChangesDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GitPullChangesDeprecatedExecute(r)\n}\n\n/*\nGitPullChangesDeprecated [DEPRECATED] Pull changes\n\nPull changes from remote\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitPullChangesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitPullChangesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitPullChangesDeprecatedRequest {\n\treturn ToolboxAPIGitPullChangesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) GitPullChangesDeprecatedExecute(r ToolboxAPIGitPullChangesDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitPullChangesDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/pull\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.gitRepoRequest == nil {\n\t\treturn nil, reportError(\"gitRepoRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.gitRepoRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIGitPushChangesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tgitRepoRequest *GitRepoRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIGitPushChangesDeprecatedRequest) GitRepoRequest(gitRepoRequest GitRepoRequest) ToolboxAPIGitPushChangesDeprecatedRequest {\n\tr.gitRepoRequest = &gitRepoRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIGitPushChangesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIGitPushChangesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIGitPushChangesDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GitPushChangesDeprecatedExecute(r)\n}\n\n/*\nGitPushChangesDeprecated [DEPRECATED] Push changes\n\nPush changes to remote\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIGitPushChangesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) GitPushChangesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIGitPushChangesDeprecatedRequest {\n\treturn ToolboxAPIGitPushChangesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) GitPushChangesDeprecatedExecute(r ToolboxAPIGitPushChangesDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.GitPushChangesDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/git/push\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.gitRepoRequest == nil {\n\t\treturn nil, reportError(\"gitRepoRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.gitRepoRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIListFilesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n\tpath *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIListFilesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIListFilesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIListFilesDeprecatedRequest) Path(path string) ToolboxAPIListFilesDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\nfunc (r ToolboxAPIListFilesDeprecatedRequest) Execute() ([]FileInfo, *http.Response, error) {\n\treturn r.ApiService.ListFilesDeprecatedExecute(r)\n}\n\n/*\nListFilesDeprecated [DEPRECATED] List files\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIListFilesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ListFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIListFilesDeprecatedRequest {\n\treturn ToolboxAPIListFilesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return []FileInfo\n// Deprecated\nfunc (a *ToolboxAPIService) ListFilesDeprecatedExecute(r ToolboxAPIListFilesDeprecatedRequest) ([]FileInfo, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []FileInfo\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ListFilesDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.path != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIListPTYSessionsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIListPTYSessionsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIListPTYSessionsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIListPTYSessionsDeprecatedRequest) Execute() (*PtyListResponse, *http.Response, error) {\n\treturn r.ApiService.ListPTYSessionsDeprecatedExecute(r)\n}\n\n/*\nListPTYSessionsDeprecated [DEPRECATED] List PTY sessions\n\nList all active PTY sessions in the sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIListPTYSessionsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ListPTYSessionsDeprecated(ctx context.Context, sandboxId string) ToolboxAPIListPTYSessionsDeprecatedRequest {\n\treturn ToolboxAPIListPTYSessionsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return PtyListResponse\n// Deprecated\nfunc (a *ToolboxAPIService) ListPTYSessionsDeprecatedExecute(r ToolboxAPIListPTYSessionsDeprecatedRequest) (*PtyListResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PtyListResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ListPTYSessionsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/pty\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIListSessionsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIListSessionsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIListSessionsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIListSessionsDeprecatedRequest) Execute() ([]Session, *http.Response, error) {\n\treturn r.ApiService.ListSessionsDeprecatedExecute(r)\n}\n\n/*\nListSessionsDeprecated [DEPRECATED] List sessions\n\nList all active sessions in the sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIListSessionsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ListSessionsDeprecated(ctx context.Context, sandboxId string) ToolboxAPIListSessionsDeprecatedRequest {\n\treturn ToolboxAPIListSessionsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return []Session\n// Deprecated\nfunc (a *ToolboxAPIService) ListSessionsDeprecatedExecute(r ToolboxAPIListSessionsDeprecatedRequest) ([]Session, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Session\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ListSessionsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/session\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPILspCompletionsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tlspCompletionParams *LspCompletionParams\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPILspCompletionsDeprecatedRequest) LspCompletionParams(lspCompletionParams LspCompletionParams) ToolboxAPILspCompletionsDeprecatedRequest {\n\tr.lspCompletionParams = &lspCompletionParams\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPILspCompletionsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPILspCompletionsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPILspCompletionsDeprecatedRequest) Execute() (*CompletionList, *http.Response, error) {\n\treturn r.ApiService.LspCompletionsDeprecatedExecute(r)\n}\n\n/*\nLspCompletionsDeprecated [DEPRECATED] Get Lsp Completions\n\nThe Completion request is sent from the client to the server to compute completion items at a given cursor position.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPILspCompletionsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) LspCompletionsDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspCompletionsDeprecatedRequest {\n\treturn ToolboxAPILspCompletionsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return CompletionList\n// Deprecated\nfunc (a *ToolboxAPIService) LspCompletionsDeprecatedExecute(r ToolboxAPILspCompletionsDeprecatedRequest) (*CompletionList, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *CompletionList\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.LspCompletionsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/lsp/completions\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.lspCompletionParams == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"lspCompletionParams is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.lspCompletionParams\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPILspDidCloseDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tlspDocumentRequest *LspDocumentRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPILspDidCloseDeprecatedRequest) LspDocumentRequest(lspDocumentRequest LspDocumentRequest) ToolboxAPILspDidCloseDeprecatedRequest {\n\tr.lspDocumentRequest = &lspDocumentRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPILspDidCloseDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPILspDidCloseDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPILspDidCloseDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.LspDidCloseDeprecatedExecute(r)\n}\n\n/*\nLspDidCloseDeprecated [DEPRECATED] Call Lsp DidClose\n\nThe document close notification is sent from the client to the server when the document got closed in the client.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPILspDidCloseDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) LspDidCloseDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspDidCloseDeprecatedRequest {\n\treturn ToolboxAPILspDidCloseDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) LspDidCloseDeprecatedExecute(r ToolboxAPILspDidCloseDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.LspDidCloseDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/lsp/did-close\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.lspDocumentRequest == nil {\n\t\treturn nil, reportError(\"lspDocumentRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.lspDocumentRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPILspDidOpenDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tlspDocumentRequest *LspDocumentRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPILspDidOpenDeprecatedRequest) LspDocumentRequest(lspDocumentRequest LspDocumentRequest) ToolboxAPILspDidOpenDeprecatedRequest {\n\tr.lspDocumentRequest = &lspDocumentRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPILspDidOpenDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPILspDidOpenDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPILspDidOpenDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.LspDidOpenDeprecatedExecute(r)\n}\n\n/*\nLspDidOpenDeprecated [DEPRECATED] Call Lsp DidOpen\n\nThe document open notification is sent from the client to the server to signal newly opened text documents.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPILspDidOpenDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) LspDidOpenDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspDidOpenDeprecatedRequest {\n\treturn ToolboxAPILspDidOpenDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) LspDidOpenDeprecatedExecute(r ToolboxAPILspDidOpenDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.LspDidOpenDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/lsp/did-open\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.lspDocumentRequest == nil {\n\t\treturn nil, reportError(\"lspDocumentRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.lspDocumentRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPILspDocumentSymbolsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tlanguageId *string\n\tpathToProject *string\n\turi *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPILspDocumentSymbolsDeprecatedRequest) LanguageId(languageId string) ToolboxAPILspDocumentSymbolsDeprecatedRequest {\n\tr.languageId = &languageId\n\treturn r\n}\n\nfunc (r ToolboxAPILspDocumentSymbolsDeprecatedRequest) PathToProject(pathToProject string) ToolboxAPILspDocumentSymbolsDeprecatedRequest {\n\tr.pathToProject = &pathToProject\n\treturn r\n}\n\nfunc (r ToolboxAPILspDocumentSymbolsDeprecatedRequest) Uri(uri string) ToolboxAPILspDocumentSymbolsDeprecatedRequest {\n\tr.uri = &uri\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPILspDocumentSymbolsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPILspDocumentSymbolsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPILspDocumentSymbolsDeprecatedRequest) Execute() ([]LspSymbol, *http.Response, error) {\n\treturn r.ApiService.LspDocumentSymbolsDeprecatedExecute(r)\n}\n\n/*\nLspDocumentSymbolsDeprecated [DEPRECATED] Call Lsp DocumentSymbols\n\nThe document symbol request is sent from the client to the server.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPILspDocumentSymbolsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) LspDocumentSymbolsDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspDocumentSymbolsDeprecatedRequest {\n\treturn ToolboxAPILspDocumentSymbolsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return []LspSymbol\n// Deprecated\nfunc (a *ToolboxAPIService) LspDocumentSymbolsDeprecatedExecute(r ToolboxAPILspDocumentSymbolsDeprecatedRequest) ([]LspSymbol, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []LspSymbol\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.LspDocumentSymbolsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/lsp/document-symbols\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.languageId == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"languageId is required and must be specified\")\n\t}\n\tif r.pathToProject == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"pathToProject is required and must be specified\")\n\t}\n\tif r.uri == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"uri is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"languageId\", r.languageId, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"pathToProject\", r.pathToProject, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"uri\", r.uri, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPILspStartDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tlspServerRequest *LspServerRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPILspStartDeprecatedRequest) LspServerRequest(lspServerRequest LspServerRequest) ToolboxAPILspStartDeprecatedRequest {\n\tr.lspServerRequest = &lspServerRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPILspStartDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPILspStartDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPILspStartDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.LspStartDeprecatedExecute(r)\n}\n\n/*\nLspStartDeprecated [DEPRECATED] Start Lsp server\n\nStart Lsp server process inside sandbox project\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPILspStartDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) LspStartDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspStartDeprecatedRequest {\n\treturn ToolboxAPILspStartDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) LspStartDeprecatedExecute(r ToolboxAPILspStartDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.LspStartDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/lsp/start\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.lspServerRequest == nil {\n\t\treturn nil, reportError(\"lspServerRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.lspServerRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPILspStopDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tlspServerRequest *LspServerRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPILspStopDeprecatedRequest) LspServerRequest(lspServerRequest LspServerRequest) ToolboxAPILspStopDeprecatedRequest {\n\tr.lspServerRequest = &lspServerRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPILspStopDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPILspStopDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPILspStopDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.LspStopDeprecatedExecute(r)\n}\n\n/*\nLspStopDeprecated [DEPRECATED] Stop Lsp server\n\nStop Lsp server process inside sandbox project\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPILspStopDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) LspStopDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspStopDeprecatedRequest {\n\treturn ToolboxAPILspStopDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) LspStopDeprecatedExecute(r ToolboxAPILspStopDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.LspStopDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/lsp/stop\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.lspServerRequest == nil {\n\t\treturn nil, reportError(\"lspServerRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.lspServerRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPILspWorkspaceSymbolsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tlanguageId *string\n\tpathToProject *string\n\tquery *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPILspWorkspaceSymbolsDeprecatedRequest) LanguageId(languageId string) ToolboxAPILspWorkspaceSymbolsDeprecatedRequest {\n\tr.languageId = &languageId\n\treturn r\n}\n\nfunc (r ToolboxAPILspWorkspaceSymbolsDeprecatedRequest) PathToProject(pathToProject string) ToolboxAPILspWorkspaceSymbolsDeprecatedRequest {\n\tr.pathToProject = &pathToProject\n\treturn r\n}\n\nfunc (r ToolboxAPILspWorkspaceSymbolsDeprecatedRequest) Query(query string) ToolboxAPILspWorkspaceSymbolsDeprecatedRequest {\n\tr.query = &query\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPILspWorkspaceSymbolsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPILspWorkspaceSymbolsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPILspWorkspaceSymbolsDeprecatedRequest) Execute() ([]LspSymbol, *http.Response, error) {\n\treturn r.ApiService.LspWorkspaceSymbolsDeprecatedExecute(r)\n}\n\n/*\nLspWorkspaceSymbolsDeprecated [DEPRECATED] Call Lsp WorkspaceSymbols\n\nThe workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPILspWorkspaceSymbolsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) LspWorkspaceSymbolsDeprecated(ctx context.Context, sandboxId string) ToolboxAPILspWorkspaceSymbolsDeprecatedRequest {\n\treturn ToolboxAPILspWorkspaceSymbolsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return []LspSymbol\n// Deprecated\nfunc (a *ToolboxAPIService) LspWorkspaceSymbolsDeprecatedExecute(r ToolboxAPILspWorkspaceSymbolsDeprecatedRequest) ([]LspSymbol, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []LspSymbol\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.LspWorkspaceSymbolsDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/lsp/workspace-symbols\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.languageId == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"languageId is required and must be specified\")\n\t}\n\tif r.pathToProject == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"pathToProject is required and must be specified\")\n\t}\n\tif r.query == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"query is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"languageId\", r.languageId, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"pathToProject\", r.pathToProject, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"query\", r.query, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIMoveFileDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsource *string\n\tdestination *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIMoveFileDeprecatedRequest) Source(source string) ToolboxAPIMoveFileDeprecatedRequest {\n\tr.source = &source\n\treturn r\n}\n\nfunc (r ToolboxAPIMoveFileDeprecatedRequest) Destination(destination string) ToolboxAPIMoveFileDeprecatedRequest {\n\tr.destination = &destination\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIMoveFileDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIMoveFileDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIMoveFileDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.MoveFileDeprecatedExecute(r)\n}\n\n/*\nMoveFileDeprecated [DEPRECATED] Move file\n\nMove file inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIMoveFileDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) MoveFileDeprecated(ctx context.Context, sandboxId string) ToolboxAPIMoveFileDeprecatedRequest {\n\treturn ToolboxAPIMoveFileDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) MoveFileDeprecatedExecute(r ToolboxAPIMoveFileDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.MoveFileDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/move\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.source == nil {\n\t\treturn nil, reportError(\"source is required and must be specified\")\n\t}\n\tif r.destination == nil {\n\t\treturn nil, reportError(\"destination is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"source\", r.source, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"destination\", r.destination, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIMoveMouseDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tmouseMoveRequest *MouseMoveRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIMoveMouseDeprecatedRequest) MouseMoveRequest(mouseMoveRequest MouseMoveRequest) ToolboxAPIMoveMouseDeprecatedRequest {\n\tr.mouseMoveRequest = &mouseMoveRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIMoveMouseDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIMoveMouseDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIMoveMouseDeprecatedRequest) Execute() (*MouseMoveResponse, *http.Response, error) {\n\treturn r.ApiService.MoveMouseDeprecatedExecute(r)\n}\n\n/*\nMoveMouseDeprecated [DEPRECATED] Move mouse\n\nMove mouse cursor to specified coordinates\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIMoveMouseDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) MoveMouseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIMoveMouseDeprecatedRequest {\n\treturn ToolboxAPIMoveMouseDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return MouseMoveResponse\n// Deprecated\nfunc (a *ToolboxAPIService) MoveMouseDeprecatedExecute(r ToolboxAPIMoveMouseDeprecatedRequest) (*MouseMoveResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *MouseMoveResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.MoveMouseDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/mouse/move\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.mouseMoveRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"mouseMoveRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.mouseMoveRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIPressHotkeyDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tkeyboardHotkeyRequest *KeyboardHotkeyRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIPressHotkeyDeprecatedRequest) KeyboardHotkeyRequest(keyboardHotkeyRequest KeyboardHotkeyRequest) ToolboxAPIPressHotkeyDeprecatedRequest {\n\tr.keyboardHotkeyRequest = &keyboardHotkeyRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIPressHotkeyDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIPressHotkeyDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIPressHotkeyDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.PressHotkeyDeprecatedExecute(r)\n}\n\n/*\nPressHotkeyDeprecated [DEPRECATED] Press hotkey\n\nPress a hotkey combination\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIPressHotkeyDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) PressHotkeyDeprecated(ctx context.Context, sandboxId string) ToolboxAPIPressHotkeyDeprecatedRequest {\n\treturn ToolboxAPIPressHotkeyDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) PressHotkeyDeprecatedExecute(r ToolboxAPIPressHotkeyDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.PressHotkeyDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/keyboard/hotkey\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.keyboardHotkeyRequest == nil {\n\t\treturn nil, reportError(\"keyboardHotkeyRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.keyboardHotkeyRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIPressKeyDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tkeyboardPressRequest *KeyboardPressRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIPressKeyDeprecatedRequest) KeyboardPressRequest(keyboardPressRequest KeyboardPressRequest) ToolboxAPIPressKeyDeprecatedRequest {\n\tr.keyboardPressRequest = &keyboardPressRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIPressKeyDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIPressKeyDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIPressKeyDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.PressKeyDeprecatedExecute(r)\n}\n\n/*\nPressKeyDeprecated [DEPRECATED] Press key\n\nPress a key with optional modifiers\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIPressKeyDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) PressKeyDeprecated(ctx context.Context, sandboxId string) ToolboxAPIPressKeyDeprecatedRequest {\n\treturn ToolboxAPIPressKeyDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) PressKeyDeprecatedExecute(r ToolboxAPIPressKeyDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.PressKeyDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/keyboard/key\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.keyboardPressRequest == nil {\n\t\treturn nil, reportError(\"keyboardPressRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.keyboardPressRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIReplaceInFilesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\treplaceRequest *ReplaceRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIReplaceInFilesDeprecatedRequest) ReplaceRequest(replaceRequest ReplaceRequest) ToolboxAPIReplaceInFilesDeprecatedRequest {\n\tr.replaceRequest = &replaceRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIReplaceInFilesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIReplaceInFilesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIReplaceInFilesDeprecatedRequest) Execute() ([]ReplaceResult, *http.Response, error) {\n\treturn r.ApiService.ReplaceInFilesDeprecatedExecute(r)\n}\n\n/*\nReplaceInFilesDeprecated [DEPRECATED] Replace in files\n\nReplace text/pattern in multiple files inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIReplaceInFilesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ReplaceInFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIReplaceInFilesDeprecatedRequest {\n\treturn ToolboxAPIReplaceInFilesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return []ReplaceResult\n// Deprecated\nfunc (a *ToolboxAPIService) ReplaceInFilesDeprecatedExecute(r ToolboxAPIReplaceInFilesDeprecatedRequest) ([]ReplaceResult, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []ReplaceResult\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ReplaceInFilesDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/replace\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.replaceRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"replaceRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.replaceRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIResizePTYSessionDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tsessionId string\n\tptyResizeRequest *PtyResizeRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIResizePTYSessionDeprecatedRequest) PtyResizeRequest(ptyResizeRequest PtyResizeRequest) ToolboxAPIResizePTYSessionDeprecatedRequest {\n\tr.ptyResizeRequest = &ptyResizeRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIResizePTYSessionDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIResizePTYSessionDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIResizePTYSessionDeprecatedRequest) Execute() (*PtySessionInfo, *http.Response, error) {\n\treturn r.ApiService.ResizePTYSessionDeprecatedExecute(r)\n}\n\n/*\nResizePTYSessionDeprecated [DEPRECATED] Resize PTY session\n\nResize a PTY session\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @param sessionId\n @return ToolboxAPIResizePTYSessionDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ResizePTYSessionDeprecated(ctx context.Context, sandboxId string, sessionId string) ToolboxAPIResizePTYSessionDeprecatedRequest {\n\treturn ToolboxAPIResizePTYSessionDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t\tsessionId: sessionId,\n\t}\n}\n\n// Execute executes the request\n//  @return PtySessionInfo\n// Deprecated\nfunc (a *ToolboxAPIService) ResizePTYSessionDeprecatedExecute(r ToolboxAPIResizePTYSessionDeprecatedRequest) (*PtySessionInfo, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *PtySessionInfo\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ResizePTYSessionDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}/resize\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sessionId\"+\"}\", url.PathEscape(parameterValueToString(r.sessionId, \"sessionId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.ptyResizeRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"ptyResizeRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.ptyResizeRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIRestartProcessDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tprocessName string\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIRestartProcessDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIRestartProcessDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIRestartProcessDeprecatedRequest) Execute() (*ProcessRestartResponse, *http.Response, error) {\n\treturn r.ApiService.RestartProcessDeprecatedExecute(r)\n}\n\n/*\nRestartProcessDeprecated [DEPRECATED] Restart process\n\nRestart a specific VNC process\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param processName\n @param sandboxId\n @return ToolboxAPIRestartProcessDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) RestartProcessDeprecated(ctx context.Context, processName string, sandboxId string) ToolboxAPIRestartProcessDeprecatedRequest {\n\treturn ToolboxAPIRestartProcessDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tprocessName: processName,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ProcessRestartResponse\n// Deprecated\nfunc (a *ToolboxAPIService) RestartProcessDeprecatedExecute(r ToolboxAPIRestartProcessDeprecatedRequest) (*ProcessRestartResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ProcessRestartResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.RestartProcessDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/restart\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"processName\"+\"}\", url.PathEscape(parameterValueToString(r.processName, \"processName\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIScrollMouseDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tmouseScrollRequest *MouseScrollRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPIScrollMouseDeprecatedRequest) MouseScrollRequest(mouseScrollRequest MouseScrollRequest) ToolboxAPIScrollMouseDeprecatedRequest {\n\tr.mouseScrollRequest = &mouseScrollRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIScrollMouseDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIScrollMouseDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIScrollMouseDeprecatedRequest) Execute() (*MouseScrollResponse, *http.Response, error) {\n\treturn r.ApiService.ScrollMouseDeprecatedExecute(r)\n}\n\n/*\nScrollMouseDeprecated [DEPRECATED] Scroll mouse\n\nScroll mouse at specified coordinates\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIScrollMouseDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) ScrollMouseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIScrollMouseDeprecatedRequest {\n\treturn ToolboxAPIScrollMouseDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return MouseScrollResponse\n// Deprecated\nfunc (a *ToolboxAPIService) ScrollMouseDeprecatedExecute(r ToolboxAPIScrollMouseDeprecatedRequest) (*MouseScrollResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *MouseScrollResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.ScrollMouseDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/mouse/scroll\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.mouseScrollRequest == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"mouseScrollRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.mouseScrollRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPISearchFilesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\tpattern *string\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPISearchFilesDeprecatedRequest) Path(path string) ToolboxAPISearchFilesDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\nfunc (r ToolboxAPISearchFilesDeprecatedRequest) Pattern(pattern string) ToolboxAPISearchFilesDeprecatedRequest {\n\tr.pattern = &pattern\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPISearchFilesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPISearchFilesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPISearchFilesDeprecatedRequest) Execute() (*SearchFilesResponse, *http.Response, error) {\n\treturn r.ApiService.SearchFilesDeprecatedExecute(r)\n}\n\n/*\nSearchFilesDeprecated [DEPRECATED] Search files\n\nSearch for files inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPISearchFilesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) SearchFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPISearchFilesDeprecatedRequest {\n\treturn ToolboxAPISearchFilesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return SearchFilesResponse\n// Deprecated\nfunc (a *ToolboxAPIService) SearchFilesDeprecatedExecute(r ToolboxAPISearchFilesDeprecatedRequest) (*SearchFilesResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SearchFilesResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.SearchFilesDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/search\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"path is required and must be specified\")\n\t}\n\tif r.pattern == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"pattern is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"pattern\", r.pattern, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPISetFilePermissionsDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\txDaytonaOrganizationID *string\n\towner *string\n\tgroup *string\n\tmode *string\n}\n\nfunc (r ToolboxAPISetFilePermissionsDeprecatedRequest) Path(path string) ToolboxAPISetFilePermissionsDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPISetFilePermissionsDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPISetFilePermissionsDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPISetFilePermissionsDeprecatedRequest) Owner(owner string) ToolboxAPISetFilePermissionsDeprecatedRequest {\n\tr.owner = &owner\n\treturn r\n}\n\nfunc (r ToolboxAPISetFilePermissionsDeprecatedRequest) Group(group string) ToolboxAPISetFilePermissionsDeprecatedRequest {\n\tr.group = &group\n\treturn r\n}\n\nfunc (r ToolboxAPISetFilePermissionsDeprecatedRequest) Mode(mode string) ToolboxAPISetFilePermissionsDeprecatedRequest {\n\tr.mode = &mode\n\treturn r\n}\n\nfunc (r ToolboxAPISetFilePermissionsDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.SetFilePermissionsDeprecatedExecute(r)\n}\n\n/*\nSetFilePermissionsDeprecated [DEPRECATED] Set file permissions\n\nSet file owner/group/permissions inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPISetFilePermissionsDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) SetFilePermissionsDeprecated(ctx context.Context, sandboxId string) ToolboxAPISetFilePermissionsDeprecatedRequest {\n\treturn ToolboxAPISetFilePermissionsDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) SetFilePermissionsDeprecatedExecute(r ToolboxAPISetFilePermissionsDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.SetFilePermissionsDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/permissions\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn nil, reportError(\"path is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\tif r.owner != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"owner\", r.owner, \"form\", \"\")\n\t}\n\tif r.group != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"group\", r.group, \"form\", \"\")\n\t}\n\tif r.mode != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"mode\", r.mode, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIStartComputerUseDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIStartComputerUseDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIStartComputerUseDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIStartComputerUseDeprecatedRequest) Execute() (*ComputerUseStartResponse, *http.Response, error) {\n\treturn r.ApiService.StartComputerUseDeprecatedExecute(r)\n}\n\n/*\nStartComputerUseDeprecated [DEPRECATED] Start computer use processes\n\nStart all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIStartComputerUseDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) StartComputerUseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIStartComputerUseDeprecatedRequest {\n\treturn ToolboxAPIStartComputerUseDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ComputerUseStartResponse\n// Deprecated\nfunc (a *ToolboxAPIService) StartComputerUseDeprecatedExecute(r ToolboxAPIStartComputerUseDeprecatedRequest) (*ComputerUseStartResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ComputerUseStartResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.StartComputerUseDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/start\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIStopComputerUseDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIStopComputerUseDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIStopComputerUseDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIStopComputerUseDeprecatedRequest) Execute() (*ComputerUseStopResponse, *http.Response, error) {\n\treturn r.ApiService.StopComputerUseDeprecatedExecute(r)\n}\n\n/*\nStopComputerUseDeprecated [DEPRECATED] Stop computer use processes\n\nStop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIStopComputerUseDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) StopComputerUseDeprecated(ctx context.Context, sandboxId string) ToolboxAPIStopComputerUseDeprecatedRequest {\n\treturn ToolboxAPIStopComputerUseDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ComputerUseStopResponse\n// Deprecated\nfunc (a *ToolboxAPIService) StopComputerUseDeprecatedExecute(r ToolboxAPIStopComputerUseDeprecatedRequest) (*ComputerUseStopResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ComputerUseStopResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.StopComputerUseDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/stop\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\theight *float32\n\twidth *float32\n\ty *float32\n\tx *float32\n\txDaytonaOrganizationID *string\n\tscale *float32\n\tquality *float32\n\tformat *string\n\tshowCursor *bool\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) Height(height float32) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.height = &height\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) Width(width float32) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.width = &width\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) Y(y float32) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.y = &y\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) X(x float32) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.x = &x\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) Scale(scale float32) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.scale = &scale\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) Quality(quality float32) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.quality = &quality\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) Format(format string) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.format = &format\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) ShowCursor(showCursor bool) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\tr.showCursor = &showCursor\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) Execute() (*CompressedScreenshotResponse, *http.Response, error) {\n\treturn r.ApiService.TakeCompressedRegionScreenshotDeprecatedExecute(r)\n}\n\n/*\nTakeCompressedRegionScreenshotDeprecated [DEPRECATED] Take compressed region screenshot\n\nTake a compressed screenshot of a specific region\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) TakeCompressedRegionScreenshotDeprecated(ctx context.Context, sandboxId string) ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest {\n\treturn ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return CompressedScreenshotResponse\n// Deprecated\nfunc (a *ToolboxAPIService) TakeCompressedRegionScreenshotDeprecatedExecute(r ToolboxAPITakeCompressedRegionScreenshotDeprecatedRequest) (*CompressedScreenshotResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *CompressedScreenshotResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.TakeCompressedRegionScreenshotDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/screenshot/region/compressed\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.height == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"height is required and must be specified\")\n\t}\n\tif r.width == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"width is required and must be specified\")\n\t}\n\tif r.y == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"y is required and must be specified\")\n\t}\n\tif r.x == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"x is required and must be specified\")\n\t}\n\n\tif r.scale != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"scale\", r.scale, \"form\", \"\")\n\t}\n\tif r.quality != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"quality\", r.quality, \"form\", \"\")\n\t}\n\tif r.format != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"format\", r.format, \"form\", \"\")\n\t}\n\tif r.showCursor != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"show_cursor\", r.showCursor, \"form\", \"\")\n\t}\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"height\", r.height, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"width\", r.width, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"y\", r.y, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"x\", r.x, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPITakeCompressedScreenshotDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n\tscale *float32\n\tquality *float32\n\tformat *string\n\tshowCursor *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPITakeCompressedScreenshotDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPITakeCompressedScreenshotDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedScreenshotDeprecatedRequest) Scale(scale float32) ToolboxAPITakeCompressedScreenshotDeprecatedRequest {\n\tr.scale = &scale\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedScreenshotDeprecatedRequest) Quality(quality float32) ToolboxAPITakeCompressedScreenshotDeprecatedRequest {\n\tr.quality = &quality\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedScreenshotDeprecatedRequest) Format(format string) ToolboxAPITakeCompressedScreenshotDeprecatedRequest {\n\tr.format = &format\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedScreenshotDeprecatedRequest) ShowCursor(showCursor bool) ToolboxAPITakeCompressedScreenshotDeprecatedRequest {\n\tr.showCursor = &showCursor\n\treturn r\n}\n\nfunc (r ToolboxAPITakeCompressedScreenshotDeprecatedRequest) Execute() (*CompressedScreenshotResponse, *http.Response, error) {\n\treturn r.ApiService.TakeCompressedScreenshotDeprecatedExecute(r)\n}\n\n/*\nTakeCompressedScreenshotDeprecated [DEPRECATED] Take compressed screenshot\n\nTake a compressed screenshot with format, quality, and scale options\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPITakeCompressedScreenshotDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) TakeCompressedScreenshotDeprecated(ctx context.Context, sandboxId string) ToolboxAPITakeCompressedScreenshotDeprecatedRequest {\n\treturn ToolboxAPITakeCompressedScreenshotDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return CompressedScreenshotResponse\n// Deprecated\nfunc (a *ToolboxAPIService) TakeCompressedScreenshotDeprecatedExecute(r ToolboxAPITakeCompressedScreenshotDeprecatedRequest) (*CompressedScreenshotResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *CompressedScreenshotResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.TakeCompressedScreenshotDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/screenshot/compressed\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.scale != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"scale\", r.scale, \"form\", \"\")\n\t}\n\tif r.quality != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"quality\", r.quality, \"form\", \"\")\n\t}\n\tif r.format != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"format\", r.format, \"form\", \"\")\n\t}\n\tif r.showCursor != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"show_cursor\", r.showCursor, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPITakeRegionScreenshotDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\theight *float32\n\twidth *float32\n\ty *float32\n\tx *float32\n\txDaytonaOrganizationID *string\n\tshowCursor *bool\n}\n\nfunc (r ToolboxAPITakeRegionScreenshotDeprecatedRequest) Height(height float32) ToolboxAPITakeRegionScreenshotDeprecatedRequest {\n\tr.height = &height\n\treturn r\n}\n\nfunc (r ToolboxAPITakeRegionScreenshotDeprecatedRequest) Width(width float32) ToolboxAPITakeRegionScreenshotDeprecatedRequest {\n\tr.width = &width\n\treturn r\n}\n\nfunc (r ToolboxAPITakeRegionScreenshotDeprecatedRequest) Y(y float32) ToolboxAPITakeRegionScreenshotDeprecatedRequest {\n\tr.y = &y\n\treturn r\n}\n\nfunc (r ToolboxAPITakeRegionScreenshotDeprecatedRequest) X(x float32) ToolboxAPITakeRegionScreenshotDeprecatedRequest {\n\tr.x = &x\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPITakeRegionScreenshotDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPITakeRegionScreenshotDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPITakeRegionScreenshotDeprecatedRequest) ShowCursor(showCursor bool) ToolboxAPITakeRegionScreenshotDeprecatedRequest {\n\tr.showCursor = &showCursor\n\treturn r\n}\n\nfunc (r ToolboxAPITakeRegionScreenshotDeprecatedRequest) Execute() (*RegionScreenshotResponse, *http.Response, error) {\n\treturn r.ApiService.TakeRegionScreenshotDeprecatedExecute(r)\n}\n\n/*\nTakeRegionScreenshotDeprecated [DEPRECATED] Take region screenshot\n\nTake a screenshot of a specific region\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPITakeRegionScreenshotDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) TakeRegionScreenshotDeprecated(ctx context.Context, sandboxId string) ToolboxAPITakeRegionScreenshotDeprecatedRequest {\n\treturn ToolboxAPITakeRegionScreenshotDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return RegionScreenshotResponse\n// Deprecated\nfunc (a *ToolboxAPIService) TakeRegionScreenshotDeprecatedExecute(r ToolboxAPITakeRegionScreenshotDeprecatedRequest) (*RegionScreenshotResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *RegionScreenshotResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.TakeRegionScreenshotDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/screenshot/region\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.height == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"height is required and must be specified\")\n\t}\n\tif r.width == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"width is required and must be specified\")\n\t}\n\tif r.y == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"y is required and must be specified\")\n\t}\n\tif r.x == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"x is required and must be specified\")\n\t}\n\n\tif r.showCursor != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"show_cursor\", r.showCursor, \"form\", \"\")\n\t}\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"height\", r.height, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"width\", r.width, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"y\", r.y, \"form\", \"\")\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"x\", r.x, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPITakeScreenshotDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n\tshowCursor *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPITakeScreenshotDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPITakeScreenshotDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPITakeScreenshotDeprecatedRequest) ShowCursor(showCursor bool) ToolboxAPITakeScreenshotDeprecatedRequest {\n\tr.showCursor = &showCursor\n\treturn r\n}\n\nfunc (r ToolboxAPITakeScreenshotDeprecatedRequest) Execute() (*ScreenshotResponse, *http.Response, error) {\n\treturn r.ApiService.TakeScreenshotDeprecatedExecute(r)\n}\n\n/*\nTakeScreenshotDeprecated [DEPRECATED] Take screenshot\n\nTake a screenshot of the entire screen\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPITakeScreenshotDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) TakeScreenshotDeprecated(ctx context.Context, sandboxId string) ToolboxAPITakeScreenshotDeprecatedRequest {\n\treturn ToolboxAPITakeScreenshotDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n//  @return ScreenshotResponse\n// Deprecated\nfunc (a *ToolboxAPIService) TakeScreenshotDeprecatedExecute(r ToolboxAPITakeScreenshotDeprecatedRequest) (*ScreenshotResponse, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *ScreenshotResponse\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.TakeScreenshotDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/screenshot\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.showCursor != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"show_cursor\", r.showCursor, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype ToolboxAPITypeTextDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tkeyboardTypeRequest *KeyboardTypeRequest\n\txDaytonaOrganizationID *string\n}\n\nfunc (r ToolboxAPITypeTextDeprecatedRequest) KeyboardTypeRequest(keyboardTypeRequest KeyboardTypeRequest) ToolboxAPITypeTextDeprecatedRequest {\n\tr.keyboardTypeRequest = &keyboardTypeRequest\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPITypeTextDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPITypeTextDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPITypeTextDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.TypeTextDeprecatedExecute(r)\n}\n\n/*\nTypeTextDeprecated [DEPRECATED] Type text\n\nType text using keyboard\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPITypeTextDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) TypeTextDeprecated(ctx context.Context, sandboxId string) ToolboxAPITypeTextDeprecatedRequest {\n\treturn ToolboxAPITypeTextDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) TypeTextDeprecatedExecute(r ToolboxAPITypeTextDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.TypeTextDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/computeruse/keyboard/type\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.keyboardTypeRequest == nil {\n\t\treturn nil, reportError(\"keyboardTypeRequest is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.keyboardTypeRequest\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIUploadFileDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\tpath *string\n\txDaytonaOrganizationID *string\n\tfile *os.File\n}\n\nfunc (r ToolboxAPIUploadFileDeprecatedRequest) Path(path string) ToolboxAPIUploadFileDeprecatedRequest {\n\tr.path = &path\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIUploadFileDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIUploadFileDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIUploadFileDeprecatedRequest) File(file *os.File) ToolboxAPIUploadFileDeprecatedRequest {\n\tr.file = file\n\treturn r\n}\n\nfunc (r ToolboxAPIUploadFileDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UploadFileDeprecatedExecute(r)\n}\n\n/*\nUploadFileDeprecated [DEPRECATED] Upload file\n\nUpload file inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIUploadFileDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) UploadFileDeprecated(ctx context.Context, sandboxId string) ToolboxAPIUploadFileDeprecatedRequest {\n\treturn ToolboxAPIUploadFileDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) UploadFileDeprecatedExecute(r ToolboxAPIUploadFileDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.UploadFileDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/upload\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.path == nil {\n\t\treturn nil, reportError(\"path is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"path\", r.path, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"multipart/form-data\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\tvar fileLocalVarFormFileName string\n\tvar fileLocalVarFileName     string\n\tvar fileLocalVarFileBytes    []byte\n\n\tfileLocalVarFormFileName = \"file\"\n\tfileLocalVarFile := r.file\n\n\tif fileLocalVarFile != nil {\n\t\tfbs, _ := io.ReadAll(fileLocalVarFile)\n\n\t\tfileLocalVarFileBytes = fbs\n\t\tfileLocalVarFileName = fileLocalVarFile.Name()\n\t\tfileLocalVarFile.Close()\n\t\tformFiles = append(formFiles, formFile{fileBytes: fileLocalVarFileBytes, fileName: fileLocalVarFileName, formFileName: fileLocalVarFormFileName})\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype ToolboxAPIUploadFilesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService ToolboxAPI\n\tsandboxId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r ToolboxAPIUploadFilesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) ToolboxAPIUploadFilesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r ToolboxAPIUploadFilesDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UploadFilesDeprecatedExecute(r)\n}\n\n/*\nUploadFilesDeprecated [DEPRECATED] Upload multiple files\n\nUpload multiple files inside sandbox\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param sandboxId\n @return ToolboxAPIUploadFilesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *ToolboxAPIService) UploadFilesDeprecated(ctx context.Context, sandboxId string) ToolboxAPIUploadFilesDeprecatedRequest {\n\treturn ToolboxAPIUploadFilesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tsandboxId: sandboxId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *ToolboxAPIService) UploadFilesDeprecatedExecute(r ToolboxAPIUploadFilesDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"ToolboxAPIService.UploadFilesDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/toolbox/{sandboxId}/toolbox/files/bulk-upload\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"sandboxId\"+\"}\", url.PathEscape(parameterValueToString(r.sandboxId, \"sandboxId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"multipart/form-data\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_users.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype UsersAPI interface {\n\n\t/*\n\tCreateUser Create user\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return UsersAPICreateUserRequest\n\t*/\n\tCreateUser(ctx context.Context) UsersAPICreateUserRequest\n\n\t// CreateUserExecute executes the request\n\tCreateUserExecute(r UsersAPICreateUserRequest) (*http.Response, error)\n\n\t/*\n\tEnrollInSmsMfa Enroll in SMS MFA\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return UsersAPIEnrollInSmsMfaRequest\n\t*/\n\tEnrollInSmsMfa(ctx context.Context) UsersAPIEnrollInSmsMfaRequest\n\n\t// EnrollInSmsMfaExecute executes the request\n\t//  @return string\n\tEnrollInSmsMfaExecute(r UsersAPIEnrollInSmsMfaRequest) (string, *http.Response, error)\n\n\t/*\n\tGetAuthenticatedUser Get authenticated user\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return UsersAPIGetAuthenticatedUserRequest\n\t*/\n\tGetAuthenticatedUser(ctx context.Context) UsersAPIGetAuthenticatedUserRequest\n\n\t// GetAuthenticatedUserExecute executes the request\n\t//  @return User\n\tGetAuthenticatedUserExecute(r UsersAPIGetAuthenticatedUserRequest) (*User, *http.Response, error)\n\n\t/*\n\tGetAvailableAccountProviders Get available account providers\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return UsersAPIGetAvailableAccountProvidersRequest\n\t*/\n\tGetAvailableAccountProviders(ctx context.Context) UsersAPIGetAvailableAccountProvidersRequest\n\n\t// GetAvailableAccountProvidersExecute executes the request\n\t//  @return []AccountProvider\n\tGetAvailableAccountProvidersExecute(r UsersAPIGetAvailableAccountProvidersRequest) ([]AccountProvider, *http.Response, error)\n\n\t/*\n\tGetUser Get user by ID\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id\n\t@return UsersAPIGetUserRequest\n\t*/\n\tGetUser(ctx context.Context, id string) UsersAPIGetUserRequest\n\n\t// GetUserExecute executes the request\n\t//  @return User\n\tGetUserExecute(r UsersAPIGetUserRequest) (*User, *http.Response, error)\n\n\t/*\n\tLinkAccount Link account\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return UsersAPILinkAccountRequest\n\t*/\n\tLinkAccount(ctx context.Context) UsersAPILinkAccountRequest\n\n\t// LinkAccountExecute executes the request\n\tLinkAccountExecute(r UsersAPILinkAccountRequest) (*http.Response, error)\n\n\t/*\n\tListUsers List all users\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return UsersAPIListUsersRequest\n\t*/\n\tListUsers(ctx context.Context) UsersAPIListUsersRequest\n\n\t// ListUsersExecute executes the request\n\tListUsersExecute(r UsersAPIListUsersRequest) (*http.Response, error)\n\n\t/*\n\tRegenerateKeyPair Regenerate user key pair\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param id\n\t@return UsersAPIRegenerateKeyPairRequest\n\t*/\n\tRegenerateKeyPair(ctx context.Context, id string) UsersAPIRegenerateKeyPairRequest\n\n\t// RegenerateKeyPairExecute executes the request\n\tRegenerateKeyPairExecute(r UsersAPIRegenerateKeyPairRequest) (*http.Response, error)\n\n\t/*\n\tUnlinkAccount Unlink account\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param provider\n\t@param providerUserId\n\t@return UsersAPIUnlinkAccountRequest\n\t*/\n\tUnlinkAccount(ctx context.Context, provider string, providerUserId string) UsersAPIUnlinkAccountRequest\n\n\t// UnlinkAccountExecute executes the request\n\tUnlinkAccountExecute(r UsersAPIUnlinkAccountRequest) (*http.Response, error)\n}\n\n// UsersAPIService UsersAPI service\ntype UsersAPIService service\n\ntype UsersAPICreateUserRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n\tcreateUser *CreateUser\n}\n\nfunc (r UsersAPICreateUserRequest) CreateUser(createUser CreateUser) UsersAPICreateUserRequest {\n\tr.createUser = &createUser\n\treturn r\n}\n\nfunc (r UsersAPICreateUserRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.CreateUserExecute(r)\n}\n\n/*\nCreateUser Create user\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return UsersAPICreateUserRequest\n*/\nfunc (a *UsersAPIService) CreateUser(ctx context.Context) UsersAPICreateUserRequest {\n\treturn UsersAPICreateUserRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\nfunc (a *UsersAPIService) CreateUserExecute(r UsersAPICreateUserRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.CreateUser\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createUser == nil {\n\t\treturn nil, reportError(\"createUser is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.createUser\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype UsersAPIEnrollInSmsMfaRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n}\n\nfunc (r UsersAPIEnrollInSmsMfaRequest) Execute() (string, *http.Response, error) {\n\treturn r.ApiService.EnrollInSmsMfaExecute(r)\n}\n\n/*\nEnrollInSmsMfa Enroll in SMS MFA\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return UsersAPIEnrollInSmsMfaRequest\n*/\nfunc (a *UsersAPIService) EnrollInSmsMfa(ctx context.Context) UsersAPIEnrollInSmsMfaRequest {\n\treturn UsersAPIEnrollInSmsMfaRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return string\nfunc (a *UsersAPIService) EnrollInSmsMfaExecute(r UsersAPIEnrollInSmsMfaRequest) (string, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  string\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.EnrollInSmsMfa\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users/mfa/sms/enroll\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype UsersAPIGetAuthenticatedUserRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n}\n\nfunc (r UsersAPIGetAuthenticatedUserRequest) Execute() (*User, *http.Response, error) {\n\treturn r.ApiService.GetAuthenticatedUserExecute(r)\n}\n\n/*\nGetAuthenticatedUser Get authenticated user\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return UsersAPIGetAuthenticatedUserRequest\n*/\nfunc (a *UsersAPIService) GetAuthenticatedUser(ctx context.Context) UsersAPIGetAuthenticatedUserRequest {\n\treturn UsersAPIGetAuthenticatedUserRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return User\nfunc (a *UsersAPIService) GetAuthenticatedUserExecute(r UsersAPIGetAuthenticatedUserRequest) (*User, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *User\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.GetAuthenticatedUser\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users/me\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype UsersAPIGetAvailableAccountProvidersRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n}\n\nfunc (r UsersAPIGetAvailableAccountProvidersRequest) Execute() ([]AccountProvider, *http.Response, error) {\n\treturn r.ApiService.GetAvailableAccountProvidersExecute(r)\n}\n\n/*\nGetAvailableAccountProviders Get available account providers\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return UsersAPIGetAvailableAccountProvidersRequest\n*/\nfunc (a *UsersAPIService) GetAvailableAccountProviders(ctx context.Context) UsersAPIGetAvailableAccountProvidersRequest {\n\treturn UsersAPIGetAvailableAccountProvidersRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []AccountProvider\nfunc (a *UsersAPIService) GetAvailableAccountProvidersExecute(r UsersAPIGetAvailableAccountProvidersRequest) ([]AccountProvider, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []AccountProvider\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.GetAvailableAccountProviders\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users/account-providers\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype UsersAPIGetUserRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n\tid string\n}\n\nfunc (r UsersAPIGetUserRequest) Execute() (*User, *http.Response, error) {\n\treturn r.ApiService.GetUserExecute(r)\n}\n\n/*\nGetUser Get user by ID\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id\n @return UsersAPIGetUserRequest\n*/\nfunc (a *UsersAPIService) GetUser(ctx context.Context, id string) UsersAPIGetUserRequest {\n\treturn UsersAPIGetUserRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\n//  @return User\nfunc (a *UsersAPIService) GetUserExecute(r UsersAPIGetUserRequest) (*User, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *User\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.GetUser\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users/{id}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype UsersAPILinkAccountRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n\tcreateLinkedAccount *CreateLinkedAccount\n}\n\nfunc (r UsersAPILinkAccountRequest) CreateLinkedAccount(createLinkedAccount CreateLinkedAccount) UsersAPILinkAccountRequest {\n\tr.createLinkedAccount = &createLinkedAccount\n\treturn r\n}\n\nfunc (r UsersAPILinkAccountRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.LinkAccountExecute(r)\n}\n\n/*\nLinkAccount Link account\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return UsersAPILinkAccountRequest\n*/\nfunc (a *UsersAPIService) LinkAccount(ctx context.Context) UsersAPILinkAccountRequest {\n\treturn UsersAPILinkAccountRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\nfunc (a *UsersAPIService) LinkAccountExecute(r UsersAPILinkAccountRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.LinkAccount\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users/linked-accounts\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createLinkedAccount == nil {\n\t\treturn nil, reportError(\"createLinkedAccount is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\t// body params\n\tlocalVarPostBody = r.createLinkedAccount\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype UsersAPIListUsersRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n}\n\nfunc (r UsersAPIListUsersRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.ListUsersExecute(r)\n}\n\n/*\nListUsers List all users\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return UsersAPIListUsersRequest\n*/\nfunc (a *UsersAPIService) ListUsers(ctx context.Context) UsersAPIListUsersRequest {\n\treturn UsersAPIListUsersRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\nfunc (a *UsersAPIService) ListUsersExecute(r UsersAPIListUsersRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.ListUsers\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype UsersAPIRegenerateKeyPairRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n\tid string\n}\n\nfunc (r UsersAPIRegenerateKeyPairRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.RegenerateKeyPairExecute(r)\n}\n\n/*\nRegenerateKeyPair Regenerate user key pair\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param id\n @return UsersAPIRegenerateKeyPairRequest\n*/\nfunc (a *UsersAPIService) RegenerateKeyPair(ctx context.Context, id string) UsersAPIRegenerateKeyPairRequest {\n\treturn UsersAPIRegenerateKeyPairRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tid: id,\n\t}\n}\n\n// Execute executes the request\nfunc (a *UsersAPIService) RegenerateKeyPairExecute(r UsersAPIRegenerateKeyPairRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.RegenerateKeyPair\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users/{id}/regenerate-key-pair\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"id\"+\"}\", url.PathEscape(parameterValueToString(r.id, \"id\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype UsersAPIUnlinkAccountRequest struct {\n\tctx context.Context\n\tApiService UsersAPI\n\tprovider string\n\tproviderUserId string\n}\n\nfunc (r UsersAPIUnlinkAccountRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UnlinkAccountExecute(r)\n}\n\n/*\nUnlinkAccount Unlink account\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param provider\n @param providerUserId\n @return UsersAPIUnlinkAccountRequest\n*/\nfunc (a *UsersAPIService) UnlinkAccount(ctx context.Context, provider string, providerUserId string) UsersAPIUnlinkAccountRequest {\n\treturn UsersAPIUnlinkAccountRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tprovider: provider,\n\t\tproviderUserId: providerUserId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *UsersAPIService) UnlinkAccountExecute(r UsersAPIUnlinkAccountRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"UsersAPIService.UnlinkAccount\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/users/linked-accounts/{provider}/{providerUserId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"provider\"+\"}\", url.PathEscape(parameterValueToString(r.provider, \"provider\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"providerUserId\"+\"}\", url.PathEscape(parameterValueToString(r.providerUserId, \"providerUserId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_volumes.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype VolumesAPI interface {\n\n\t/*\n\tCreateVolume Create a new volume\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return VolumesAPICreateVolumeRequest\n\t*/\n\tCreateVolume(ctx context.Context) VolumesAPICreateVolumeRequest\n\n\t// CreateVolumeExecute executes the request\n\t//  @return VolumeDto\n\tCreateVolumeExecute(r VolumesAPICreateVolumeRequest) (*VolumeDto, *http.Response, error)\n\n\t/*\n\tDeleteVolume Delete volume\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param volumeId ID of the volume\n\t@return VolumesAPIDeleteVolumeRequest\n\t*/\n\tDeleteVolume(ctx context.Context, volumeId string) VolumesAPIDeleteVolumeRequest\n\n\t// DeleteVolumeExecute executes the request\n\tDeleteVolumeExecute(r VolumesAPIDeleteVolumeRequest) (*http.Response, error)\n\n\t/*\n\tGetVolume Get volume details\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param volumeId ID of the volume\n\t@return VolumesAPIGetVolumeRequest\n\t*/\n\tGetVolume(ctx context.Context, volumeId string) VolumesAPIGetVolumeRequest\n\n\t// GetVolumeExecute executes the request\n\t//  @return VolumeDto\n\tGetVolumeExecute(r VolumesAPIGetVolumeRequest) (*VolumeDto, *http.Response, error)\n\n\t/*\n\tGetVolumeByName Get volume details by name\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param name Name of the volume\n\t@return VolumesAPIGetVolumeByNameRequest\n\t*/\n\tGetVolumeByName(ctx context.Context, name string) VolumesAPIGetVolumeByNameRequest\n\n\t// GetVolumeByNameExecute executes the request\n\t//  @return VolumeDto\n\tGetVolumeByNameExecute(r VolumesAPIGetVolumeByNameRequest) (*VolumeDto, *http.Response, error)\n\n\t/*\n\tListVolumes List all volumes\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return VolumesAPIListVolumesRequest\n\t*/\n\tListVolumes(ctx context.Context) VolumesAPIListVolumesRequest\n\n\t// ListVolumesExecute executes the request\n\t//  @return []VolumeDto\n\tListVolumesExecute(r VolumesAPIListVolumesRequest) ([]VolumeDto, *http.Response, error)\n}\n\n// VolumesAPIService VolumesAPI service\ntype VolumesAPIService service\n\ntype VolumesAPICreateVolumeRequest struct {\n\tctx context.Context\n\tApiService VolumesAPI\n\tcreateVolume *CreateVolume\n\txDaytonaOrganizationID *string\n}\n\nfunc (r VolumesAPICreateVolumeRequest) CreateVolume(createVolume CreateVolume) VolumesAPICreateVolumeRequest {\n\tr.createVolume = &createVolume\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r VolumesAPICreateVolumeRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) VolumesAPICreateVolumeRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r VolumesAPICreateVolumeRequest) Execute() (*VolumeDto, *http.Response, error) {\n\treturn r.ApiService.CreateVolumeExecute(r)\n}\n\n/*\nCreateVolume Create a new volume\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return VolumesAPICreateVolumeRequest\n*/\nfunc (a *VolumesAPIService) CreateVolume(ctx context.Context) VolumesAPICreateVolumeRequest {\n\treturn VolumesAPICreateVolumeRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return VolumeDto\nfunc (a *VolumesAPIService) CreateVolumeExecute(r VolumesAPICreateVolumeRequest) (*VolumeDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *VolumeDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"VolumesAPIService.CreateVolume\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/volumes\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createVolume == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createVolume is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createVolume\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype VolumesAPIDeleteVolumeRequest struct {\n\tctx context.Context\n\tApiService VolumesAPI\n\tvolumeId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r VolumesAPIDeleteVolumeRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) VolumesAPIDeleteVolumeRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r VolumesAPIDeleteVolumeRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteVolumeExecute(r)\n}\n\n/*\nDeleteVolume Delete volume\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param volumeId ID of the volume\n @return VolumesAPIDeleteVolumeRequest\n*/\nfunc (a *VolumesAPIService) DeleteVolume(ctx context.Context, volumeId string) VolumesAPIDeleteVolumeRequest {\n\treturn VolumesAPIDeleteVolumeRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tvolumeId: volumeId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *VolumesAPIService) DeleteVolumeExecute(r VolumesAPIDeleteVolumeRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"VolumesAPIService.DeleteVolume\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/volumes/{volumeId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"volumeId\"+\"}\", url.PathEscape(parameterValueToString(r.volumeId, \"volumeId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype VolumesAPIGetVolumeRequest struct {\n\tctx context.Context\n\tApiService VolumesAPI\n\tvolumeId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r VolumesAPIGetVolumeRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) VolumesAPIGetVolumeRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r VolumesAPIGetVolumeRequest) Execute() (*VolumeDto, *http.Response, error) {\n\treturn r.ApiService.GetVolumeExecute(r)\n}\n\n/*\nGetVolume Get volume details\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param volumeId ID of the volume\n @return VolumesAPIGetVolumeRequest\n*/\nfunc (a *VolumesAPIService) GetVolume(ctx context.Context, volumeId string) VolumesAPIGetVolumeRequest {\n\treturn VolumesAPIGetVolumeRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tvolumeId: volumeId,\n\t}\n}\n\n// Execute executes the request\n//  @return VolumeDto\nfunc (a *VolumesAPIService) GetVolumeExecute(r VolumesAPIGetVolumeRequest) (*VolumeDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *VolumeDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"VolumesAPIService.GetVolume\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/volumes/{volumeId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"volumeId\"+\"}\", url.PathEscape(parameterValueToString(r.volumeId, \"volumeId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype VolumesAPIGetVolumeByNameRequest struct {\n\tctx context.Context\n\tApiService VolumesAPI\n\tname string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r VolumesAPIGetVolumeByNameRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) VolumesAPIGetVolumeByNameRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r VolumesAPIGetVolumeByNameRequest) Execute() (*VolumeDto, *http.Response, error) {\n\treturn r.ApiService.GetVolumeByNameExecute(r)\n}\n\n/*\nGetVolumeByName Get volume details by name\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param name Name of the volume\n @return VolumesAPIGetVolumeByNameRequest\n*/\nfunc (a *VolumesAPIService) GetVolumeByName(ctx context.Context, name string) VolumesAPIGetVolumeByNameRequest {\n\treturn VolumesAPIGetVolumeByNameRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tname: name,\n\t}\n}\n\n// Execute executes the request\n//  @return VolumeDto\nfunc (a *VolumesAPIService) GetVolumeByNameExecute(r VolumesAPIGetVolumeByNameRequest) (*VolumeDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *VolumeDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"VolumesAPIService.GetVolumeByName\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/volumes/by-name/{name}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"name\"+\"}\", url.PathEscape(parameterValueToString(r.name, \"name\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype VolumesAPIListVolumesRequest struct {\n\tctx context.Context\n\tApiService VolumesAPI\n\txDaytonaOrganizationID *string\n\tincludeDeleted *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r VolumesAPIListVolumesRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) VolumesAPIListVolumesRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Include deleted volumes in the response\nfunc (r VolumesAPIListVolumesRequest) IncludeDeleted(includeDeleted bool) VolumesAPIListVolumesRequest {\n\tr.includeDeleted = &includeDeleted\n\treturn r\n}\n\nfunc (r VolumesAPIListVolumesRequest) Execute() ([]VolumeDto, *http.Response, error) {\n\treturn r.ApiService.ListVolumesExecute(r)\n}\n\n/*\nListVolumes List all volumes\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return VolumesAPIListVolumesRequest\n*/\nfunc (a *VolumesAPIService) ListVolumes(ctx context.Context) VolumesAPIListVolumesRequest {\n\treturn VolumesAPIListVolumesRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []VolumeDto\nfunc (a *VolumesAPIService) ListVolumesExecute(r VolumesAPIListVolumesRequest) ([]VolumeDto, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []VolumeDto\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"VolumesAPIService.ListVolumes\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/volumes\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.includeDeleted != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"includeDeleted\", r.includeDeleted, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_webhooks.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype WebhooksAPI interface {\n\n\t/*\n\tWebhookControllerGetAppPortalAccess Get Svix Consumer App Portal access for an organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId\n\t@return WebhooksAPIWebhookControllerGetAppPortalAccessRequest\n\t*/\n\tWebhookControllerGetAppPortalAccess(ctx context.Context, organizationId string) WebhooksAPIWebhookControllerGetAppPortalAccessRequest\n\n\t// WebhookControllerGetAppPortalAccessExecute executes the request\n\t//  @return WebhookAppPortalAccess\n\tWebhookControllerGetAppPortalAccessExecute(r WebhooksAPIWebhookControllerGetAppPortalAccessRequest) (*WebhookAppPortalAccess, *http.Response, error)\n\n\t/*\n\tWebhookControllerGetInitializationStatus Get webhook initialization status for an organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId\n\t@return WebhooksAPIWebhookControllerGetInitializationStatusRequest\n\t*/\n\tWebhookControllerGetInitializationStatus(ctx context.Context, organizationId string) WebhooksAPIWebhookControllerGetInitializationStatusRequest\n\n\t// WebhookControllerGetInitializationStatusExecute executes the request\n\t//  @return WebhookInitializationStatus\n\tWebhookControllerGetInitializationStatusExecute(r WebhooksAPIWebhookControllerGetInitializationStatusRequest) (*WebhookInitializationStatus, *http.Response, error)\n\n\t/*\n\tWebhookControllerGetMessageAttempts Get delivery attempts for a webhook message\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId\n\t@param messageId\n\t@return WebhooksAPIWebhookControllerGetMessageAttemptsRequest\n\t*/\n\tWebhookControllerGetMessageAttempts(ctx context.Context, organizationId string, messageId string) WebhooksAPIWebhookControllerGetMessageAttemptsRequest\n\n\t// WebhookControllerGetMessageAttemptsExecute executes the request\n\t//  @return []map[string]interface{}\n\tWebhookControllerGetMessageAttemptsExecute(r WebhooksAPIWebhookControllerGetMessageAttemptsRequest) ([]map[string]interface{}, *http.Response, error)\n\n\t/*\n\tWebhookControllerGetStatus Get webhook service status\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return WebhooksAPIWebhookControllerGetStatusRequest\n\t*/\n\tWebhookControllerGetStatus(ctx context.Context) WebhooksAPIWebhookControllerGetStatusRequest\n\n\t// WebhookControllerGetStatusExecute executes the request\n\t//  @return WebhookControllerGetStatus200Response\n\tWebhookControllerGetStatusExecute(r WebhooksAPIWebhookControllerGetStatusRequest) (*WebhookControllerGetStatus200Response, *http.Response, error)\n\n\t/*\n\tWebhookControllerInitializeWebhooks Initialize webhooks for an organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId\n\t@return WebhooksAPIWebhookControllerInitializeWebhooksRequest\n\t*/\n\tWebhookControllerInitializeWebhooks(ctx context.Context, organizationId string) WebhooksAPIWebhookControllerInitializeWebhooksRequest\n\n\t// WebhookControllerInitializeWebhooksExecute executes the request\n\tWebhookControllerInitializeWebhooksExecute(r WebhooksAPIWebhookControllerInitializeWebhooksRequest) (*http.Response, error)\n\n\t/*\n\tWebhookControllerSendWebhook Send a webhook message to an organization\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param organizationId\n\t@return WebhooksAPIWebhookControllerSendWebhookRequest\n\t*/\n\tWebhookControllerSendWebhook(ctx context.Context, organizationId string) WebhooksAPIWebhookControllerSendWebhookRequest\n\n\t// WebhookControllerSendWebhookExecute executes the request\n\tWebhookControllerSendWebhookExecute(r WebhooksAPIWebhookControllerSendWebhookRequest) (*http.Response, error)\n}\n\n// WebhooksAPIService WebhooksAPI service\ntype WebhooksAPIService service\n\ntype WebhooksAPIWebhookControllerGetAppPortalAccessRequest struct {\n\tctx context.Context\n\tApiService WebhooksAPI\n\torganizationId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WebhooksAPIWebhookControllerGetAppPortalAccessRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WebhooksAPIWebhookControllerGetAppPortalAccessRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WebhooksAPIWebhookControllerGetAppPortalAccessRequest) Execute() (*WebhookAppPortalAccess, *http.Response, error) {\n\treturn r.ApiService.WebhookControllerGetAppPortalAccessExecute(r)\n}\n\n/*\nWebhookControllerGetAppPortalAccess Get Svix Consumer App Portal access for an organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId\n @return WebhooksAPIWebhookControllerGetAppPortalAccessRequest\n*/\nfunc (a *WebhooksAPIService) WebhookControllerGetAppPortalAccess(ctx context.Context, organizationId string) WebhooksAPIWebhookControllerGetAppPortalAccessRequest {\n\treturn WebhooksAPIWebhookControllerGetAppPortalAccessRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return WebhookAppPortalAccess\nfunc (a *WebhooksAPIService) WebhookControllerGetAppPortalAccessExecute(r WebhooksAPIWebhookControllerGetAppPortalAccessRequest) (*WebhookAppPortalAccess, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *WebhookAppPortalAccess\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WebhooksAPIService.WebhookControllerGetAppPortalAccess\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/webhooks/organizations/{organizationId}/app-portal-access\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WebhooksAPIWebhookControllerGetInitializationStatusRequest struct {\n\tctx context.Context\n\tApiService WebhooksAPI\n\torganizationId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WebhooksAPIWebhookControllerGetInitializationStatusRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WebhooksAPIWebhookControllerGetInitializationStatusRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WebhooksAPIWebhookControllerGetInitializationStatusRequest) Execute() (*WebhookInitializationStatus, *http.Response, error) {\n\treturn r.ApiService.WebhookControllerGetInitializationStatusExecute(r)\n}\n\n/*\nWebhookControllerGetInitializationStatus Get webhook initialization status for an organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId\n @return WebhooksAPIWebhookControllerGetInitializationStatusRequest\n*/\nfunc (a *WebhooksAPIService) WebhookControllerGetInitializationStatus(ctx context.Context, organizationId string) WebhooksAPIWebhookControllerGetInitializationStatusRequest {\n\treturn WebhooksAPIWebhookControllerGetInitializationStatusRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\n//  @return WebhookInitializationStatus\nfunc (a *WebhooksAPIService) WebhookControllerGetInitializationStatusExecute(r WebhooksAPIWebhookControllerGetInitializationStatusRequest) (*WebhookInitializationStatus, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *WebhookInitializationStatus\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WebhooksAPIService.WebhookControllerGetInitializationStatus\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/webhooks/organizations/{organizationId}/initialization-status\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WebhooksAPIWebhookControllerGetMessageAttemptsRequest struct {\n\tctx context.Context\n\tApiService WebhooksAPI\n\torganizationId string\n\tmessageId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WebhooksAPIWebhookControllerGetMessageAttemptsRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WebhooksAPIWebhookControllerGetMessageAttemptsRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WebhooksAPIWebhookControllerGetMessageAttemptsRequest) Execute() ([]map[string]interface{}, *http.Response, error) {\n\treturn r.ApiService.WebhookControllerGetMessageAttemptsExecute(r)\n}\n\n/*\nWebhookControllerGetMessageAttempts Get delivery attempts for a webhook message\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId\n @param messageId\n @return WebhooksAPIWebhookControllerGetMessageAttemptsRequest\n*/\nfunc (a *WebhooksAPIService) WebhookControllerGetMessageAttempts(ctx context.Context, organizationId string, messageId string) WebhooksAPIWebhookControllerGetMessageAttemptsRequest {\n\treturn WebhooksAPIWebhookControllerGetMessageAttemptsRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t\tmessageId: messageId,\n\t}\n}\n\n// Execute executes the request\n//  @return []map[string]interface{}\nfunc (a *WebhooksAPIService) WebhookControllerGetMessageAttemptsExecute(r WebhooksAPIWebhookControllerGetMessageAttemptsRequest) ([]map[string]interface{}, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []map[string]interface{}\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WebhooksAPIService.WebhookControllerGetMessageAttempts\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/webhooks/organizations/{organizationId}/messages/{messageId}/attempts\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"messageId\"+\"}\", url.PathEscape(parameterValueToString(r.messageId, \"messageId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WebhooksAPIWebhookControllerGetStatusRequest struct {\n\tctx context.Context\n\tApiService WebhooksAPI\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WebhooksAPIWebhookControllerGetStatusRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WebhooksAPIWebhookControllerGetStatusRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WebhooksAPIWebhookControllerGetStatusRequest) Execute() (*WebhookControllerGetStatus200Response, *http.Response, error) {\n\treturn r.ApiService.WebhookControllerGetStatusExecute(r)\n}\n\n/*\nWebhookControllerGetStatus Get webhook service status\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return WebhooksAPIWebhookControllerGetStatusRequest\n*/\nfunc (a *WebhooksAPIService) WebhookControllerGetStatus(ctx context.Context) WebhooksAPIWebhookControllerGetStatusRequest {\n\treturn WebhooksAPIWebhookControllerGetStatusRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return WebhookControllerGetStatus200Response\nfunc (a *WebhooksAPIService) WebhookControllerGetStatusExecute(r WebhooksAPIWebhookControllerGetStatusRequest) (*WebhookControllerGetStatus200Response, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *WebhookControllerGetStatus200Response\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WebhooksAPIService.WebhookControllerGetStatus\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/webhooks/status\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WebhooksAPIWebhookControllerInitializeWebhooksRequest struct {\n\tctx context.Context\n\tApiService WebhooksAPI\n\torganizationId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WebhooksAPIWebhookControllerInitializeWebhooksRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WebhooksAPIWebhookControllerInitializeWebhooksRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WebhooksAPIWebhookControllerInitializeWebhooksRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.WebhookControllerInitializeWebhooksExecute(r)\n}\n\n/*\nWebhookControllerInitializeWebhooks Initialize webhooks for an organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId\n @return WebhooksAPIWebhookControllerInitializeWebhooksRequest\n*/\nfunc (a *WebhooksAPIService) WebhookControllerInitializeWebhooks(ctx context.Context, organizationId string) WebhooksAPIWebhookControllerInitializeWebhooksRequest {\n\treturn WebhooksAPIWebhookControllerInitializeWebhooksRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *WebhooksAPIService) WebhookControllerInitializeWebhooksExecute(r WebhooksAPIWebhookControllerInitializeWebhooksRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WebhooksAPIService.WebhookControllerInitializeWebhooks\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/webhooks/organizations/{organizationId}/initialize\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype WebhooksAPIWebhookControllerSendWebhookRequest struct {\n\tctx context.Context\n\tApiService WebhooksAPI\n\torganizationId string\n\tsendWebhookDto *SendWebhookDto\n\txDaytonaOrganizationID *string\n}\n\nfunc (r WebhooksAPIWebhookControllerSendWebhookRequest) SendWebhookDto(sendWebhookDto SendWebhookDto) WebhooksAPIWebhookControllerSendWebhookRequest {\n\tr.sendWebhookDto = &sendWebhookDto\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WebhooksAPIWebhookControllerSendWebhookRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WebhooksAPIWebhookControllerSendWebhookRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WebhooksAPIWebhookControllerSendWebhookRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.WebhookControllerSendWebhookExecute(r)\n}\n\n/*\nWebhookControllerSendWebhook Send a webhook message to an organization\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param organizationId\n @return WebhooksAPIWebhookControllerSendWebhookRequest\n*/\nfunc (a *WebhooksAPIService) WebhookControllerSendWebhook(ctx context.Context, organizationId string) WebhooksAPIWebhookControllerSendWebhookRequest {\n\treturn WebhooksAPIWebhookControllerSendWebhookRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\torganizationId: organizationId,\n\t}\n}\n\n// Execute executes the request\nfunc (a *WebhooksAPIService) WebhookControllerSendWebhookExecute(r WebhooksAPIWebhookControllerSendWebhookRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WebhooksAPIService.WebhookControllerSendWebhook\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/webhooks/organizations/{organizationId}/send\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"organizationId\"+\"}\", url.PathEscape(parameterValueToString(r.organizationId, \"organizationId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.sendWebhookDto == nil {\n\t\treturn nil, reportError(\"sendWebhookDto is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.sendWebhookDto\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/api_workspace.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n\ntype WorkspaceAPI interface {\n\n\t/*\n\tArchiveWorkspaceDeprecated [DEPRECATED] Archive workspace\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId\n\t@return WorkspaceAPIArchiveWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tArchiveWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIArchiveWorkspaceDeprecatedRequest\n\n\t// ArchiveWorkspaceDeprecatedExecute executes the request\n\t// Deprecated\n\tArchiveWorkspaceDeprecatedExecute(r WorkspaceAPIArchiveWorkspaceDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tCreateBackupWorkspaceDeprecated [DEPRECATED] Create workspace backup\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@return WorkspaceAPICreateBackupWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tCreateBackupWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPICreateBackupWorkspaceDeprecatedRequest\n\n\t// CreateBackupWorkspaceDeprecatedExecute executes the request\n\t//  @return Workspace\n\t// Deprecated\n\tCreateBackupWorkspaceDeprecatedExecute(r WorkspaceAPICreateBackupWorkspaceDeprecatedRequest) (*Workspace, *http.Response, error)\n\n\t/*\n\tCreateWorkspaceDeprecated [DEPRECATED] Create a new workspace\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return WorkspaceAPICreateWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tCreateWorkspaceDeprecated(ctx context.Context) WorkspaceAPICreateWorkspaceDeprecatedRequest\n\n\t// CreateWorkspaceDeprecatedExecute executes the request\n\t//  @return Workspace\n\t// Deprecated\n\tCreateWorkspaceDeprecatedExecute(r WorkspaceAPICreateWorkspaceDeprecatedRequest) (*Workspace, *http.Response, error)\n\n\t/*\n\tDeleteWorkspaceDeprecated [DEPRECATED] Delete workspace\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@return WorkspaceAPIDeleteWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tDeleteWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIDeleteWorkspaceDeprecatedRequest\n\n\t// DeleteWorkspaceDeprecatedExecute executes the request\n\t// Deprecated\n\tDeleteWorkspaceDeprecatedExecute(r WorkspaceAPIDeleteWorkspaceDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tGetBuildLogsWorkspaceDeprecated [DEPRECATED] Get build logs\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@return WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetBuildLogsWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest\n\n\t// GetBuildLogsWorkspaceDeprecatedExecute executes the request\n\t// Deprecated\n\tGetBuildLogsWorkspaceDeprecatedExecute(r WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tGetPortPreviewUrlWorkspaceDeprecated [DEPRECATED] Get preview URL for a workspace port\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@param port Port number to get preview URL for\n\t@return WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetPortPreviewUrlWorkspaceDeprecated(ctx context.Context, workspaceId string, port float32) WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest\n\n\t// GetPortPreviewUrlWorkspaceDeprecatedExecute executes the request\n\t//  @return WorkspacePortPreviewUrl\n\t// Deprecated\n\tGetPortPreviewUrlWorkspaceDeprecatedExecute(r WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest) (*WorkspacePortPreviewUrl, *http.Response, error)\n\n\t/*\n\tGetWorkspaceDeprecated [DEPRECATED] Get workspace details\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@return WorkspaceAPIGetWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tGetWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIGetWorkspaceDeprecatedRequest\n\n\t// GetWorkspaceDeprecatedExecute executes the request\n\t//  @return Workspace\n\t// Deprecated\n\tGetWorkspaceDeprecatedExecute(r WorkspaceAPIGetWorkspaceDeprecatedRequest) (*Workspace, *http.Response, error)\n\n\t/*\n\tListWorkspacesDeprecated [DEPRECATED] List all workspaces\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@return WorkspaceAPIListWorkspacesDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tListWorkspacesDeprecated(ctx context.Context) WorkspaceAPIListWorkspacesDeprecatedRequest\n\n\t// ListWorkspacesDeprecatedExecute executes the request\n\t//  @return []Workspace\n\t// Deprecated\n\tListWorkspacesDeprecatedExecute(r WorkspaceAPIListWorkspacesDeprecatedRequest) ([]Workspace, *http.Response, error)\n\n\t/*\n\tReplaceLabelsWorkspaceDeprecated [DEPRECATED] Replace workspace labels\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@return WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tReplaceLabelsWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest\n\n\t// ReplaceLabelsWorkspaceDeprecatedExecute executes the request\n\t//  @return SandboxLabels\n\t// Deprecated\n\tReplaceLabelsWorkspaceDeprecatedExecute(r WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest) (*SandboxLabels, *http.Response, error)\n\n\t/*\n\tSetAutoArchiveIntervalWorkspaceDeprecated [DEPRECATED] Set workspace auto-archive interval\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@param interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n\t@return WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tSetAutoArchiveIntervalWorkspaceDeprecated(ctx context.Context, workspaceId string, interval float32) WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest\n\n\t// SetAutoArchiveIntervalWorkspaceDeprecatedExecute executes the request\n\t// Deprecated\n\tSetAutoArchiveIntervalWorkspaceDeprecatedExecute(r WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tSetAutostopIntervalWorkspaceDeprecated [DEPRECATED] Set workspace auto-stop interval\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@param interval Auto-stop interval in minutes (0 to disable)\n\t@return WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tSetAutostopIntervalWorkspaceDeprecated(ctx context.Context, workspaceId string, interval float32) WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest\n\n\t// SetAutostopIntervalWorkspaceDeprecatedExecute executes the request\n\t// Deprecated\n\tSetAutostopIntervalWorkspaceDeprecatedExecute(r WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tStartWorkspaceDeprecated [DEPRECATED] Start workspace\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@return WorkspaceAPIStartWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tStartWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIStartWorkspaceDeprecatedRequest\n\n\t// StartWorkspaceDeprecatedExecute executes the request\n\t// Deprecated\n\tStartWorkspaceDeprecatedExecute(r WorkspaceAPIStartWorkspaceDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tStopWorkspaceDeprecated [DEPRECATED] Stop workspace\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@return WorkspaceAPIStopWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tStopWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIStopWorkspaceDeprecatedRequest\n\n\t// StopWorkspaceDeprecatedExecute executes the request\n\t// Deprecated\n\tStopWorkspaceDeprecatedExecute(r WorkspaceAPIStopWorkspaceDeprecatedRequest) (*http.Response, error)\n\n\t/*\n\tUpdatePublicStatusWorkspaceDeprecated [DEPRECATED] Update public status\n\n\t@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n\t@param workspaceId ID of the workspace\n\t@param isPublic Public status to set\n\t@return WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest\n\n\tDeprecated\n\t*/\n\tUpdatePublicStatusWorkspaceDeprecated(ctx context.Context, workspaceId string, isPublic bool) WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest\n\n\t// UpdatePublicStatusWorkspaceDeprecatedExecute executes the request\n\t// Deprecated\n\tUpdatePublicStatusWorkspaceDeprecatedExecute(r WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest) (*http.Response, error)\n}\n\n// WorkspaceAPIService WorkspaceAPI service\ntype WorkspaceAPIService service\n\ntype WorkspaceAPIArchiveWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIArchiveWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIArchiveWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPIArchiveWorkspaceDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.ArchiveWorkspaceDeprecatedExecute(r)\n}\n\n/*\nArchiveWorkspaceDeprecated [DEPRECATED] Archive workspace\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId\n @return WorkspaceAPIArchiveWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) ArchiveWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIArchiveWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIArchiveWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *WorkspaceAPIService) ArchiveWorkspaceDeprecatedExecute(r WorkspaceAPIArchiveWorkspaceDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.ArchiveWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/archive\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPICreateBackupWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPICreateBackupWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPICreateBackupWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPICreateBackupWorkspaceDeprecatedRequest) Execute() (*Workspace, *http.Response, error) {\n\treturn r.ApiService.CreateBackupWorkspaceDeprecatedExecute(r)\n}\n\n/*\nCreateBackupWorkspaceDeprecated [DEPRECATED] Create workspace backup\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @return WorkspaceAPICreateBackupWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) CreateBackupWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPICreateBackupWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPICreateBackupWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t}\n}\n\n// Execute executes the request\n//  @return Workspace\n// Deprecated\nfunc (a *WorkspaceAPIService) CreateBackupWorkspaceDeprecatedExecute(r WorkspaceAPICreateBackupWorkspaceDeprecatedRequest) (*Workspace, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Workspace\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.CreateBackupWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/backup\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPICreateWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tcreateWorkspace *CreateWorkspace\n\txDaytonaOrganizationID *string\n}\n\nfunc (r WorkspaceAPICreateWorkspaceDeprecatedRequest) CreateWorkspace(createWorkspace CreateWorkspace) WorkspaceAPICreateWorkspaceDeprecatedRequest {\n\tr.createWorkspace = &createWorkspace\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPICreateWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPICreateWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPICreateWorkspaceDeprecatedRequest) Execute() (*Workspace, *http.Response, error) {\n\treturn r.ApiService.CreateWorkspaceDeprecatedExecute(r)\n}\n\n/*\nCreateWorkspaceDeprecated [DEPRECATED] Create a new workspace\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return WorkspaceAPICreateWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) CreateWorkspaceDeprecated(ctx context.Context) WorkspaceAPICreateWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPICreateWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return Workspace\n// Deprecated\nfunc (a *WorkspaceAPIService) CreateWorkspaceDeprecatedExecute(r WorkspaceAPICreateWorkspaceDeprecatedRequest) (*Workspace, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Workspace\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.CreateWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.createWorkspace == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"createWorkspace is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.createWorkspace\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIDeleteWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\tforce *bool\n\txDaytonaOrganizationID *string\n}\n\nfunc (r WorkspaceAPIDeleteWorkspaceDeprecatedRequest) Force(force bool) WorkspaceAPIDeleteWorkspaceDeprecatedRequest {\n\tr.force = &force\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIDeleteWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIDeleteWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPIDeleteWorkspaceDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.DeleteWorkspaceDeprecatedExecute(r)\n}\n\n/*\nDeleteWorkspaceDeprecated [DEPRECATED] Delete workspace\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @return WorkspaceAPIDeleteWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) DeleteWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIDeleteWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIDeleteWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *WorkspaceAPIService) DeleteWorkspaceDeprecatedExecute(r WorkspaceAPIDeleteWorkspaceDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodDelete\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.DeleteWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.force == nil {\n\t\treturn nil, reportError(\"force is required and must be specified\")\n\t}\n\n\tparameterAddToHeaderOrQuery(localVarQueryParams, \"force\", r.force, \"form\", \"\")\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\txDaytonaOrganizationID *string\n\tfollow *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Whether to follow the logs stream\nfunc (r WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest) Follow(follow bool) WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest {\n\tr.follow = &follow\n\treturn r\n}\n\nfunc (r WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.GetBuildLogsWorkspaceDeprecatedExecute(r)\n}\n\n/*\nGetBuildLogsWorkspaceDeprecated [DEPRECATED] Get build logs\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @return WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) GetBuildLogsWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *WorkspaceAPIService) GetBuildLogsWorkspaceDeprecatedExecute(r WorkspaceAPIGetBuildLogsWorkspaceDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.GetBuildLogsWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/build-logs\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.follow != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"follow\", r.follow, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\tport float32\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest) Execute() (*WorkspacePortPreviewUrl, *http.Response, error) {\n\treturn r.ApiService.GetPortPreviewUrlWorkspaceDeprecatedExecute(r)\n}\n\n/*\nGetPortPreviewUrlWorkspaceDeprecated [DEPRECATED] Get preview URL for a workspace port\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @param port Port number to get preview URL for\n @return WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) GetPortPreviewUrlWorkspaceDeprecated(ctx context.Context, workspaceId string, port float32) WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t\tport: port,\n\t}\n}\n\n// Execute executes the request\n//  @return WorkspacePortPreviewUrl\n// Deprecated\nfunc (a *WorkspaceAPIService) GetPortPreviewUrlWorkspaceDeprecatedExecute(r WorkspaceAPIGetPortPreviewUrlWorkspaceDeprecatedRequest) (*WorkspacePortPreviewUrl, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *WorkspacePortPreviewUrl\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.GetPortPreviewUrlWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/ports/{port}/preview-url\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"port\"+\"}\", url.PathEscape(parameterValueToString(r.port, \"port\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIGetWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\txDaytonaOrganizationID *string\n\tverbose *bool\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIGetWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIGetWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Include verbose output\nfunc (r WorkspaceAPIGetWorkspaceDeprecatedRequest) Verbose(verbose bool) WorkspaceAPIGetWorkspaceDeprecatedRequest {\n\tr.verbose = &verbose\n\treturn r\n}\n\nfunc (r WorkspaceAPIGetWorkspaceDeprecatedRequest) Execute() (*Workspace, *http.Response, error) {\n\treturn r.ApiService.GetWorkspaceDeprecatedExecute(r)\n}\n\n/*\nGetWorkspaceDeprecated [DEPRECATED] Get workspace details\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @return WorkspaceAPIGetWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) GetWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIGetWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIGetWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t}\n}\n\n// Execute executes the request\n//  @return Workspace\n// Deprecated\nfunc (a *WorkspaceAPIService) GetWorkspaceDeprecatedExecute(r WorkspaceAPIGetWorkspaceDeprecatedRequest) (*Workspace, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *Workspace\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.GetWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.verbose != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"verbose\", r.verbose, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIListWorkspacesDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\txDaytonaOrganizationID *string\n\tverbose *bool\n\tlabels *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIListWorkspacesDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIListWorkspacesDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\n// Include verbose output\nfunc (r WorkspaceAPIListWorkspacesDeprecatedRequest) Verbose(verbose bool) WorkspaceAPIListWorkspacesDeprecatedRequest {\n\tr.verbose = &verbose\n\treturn r\n}\n\n// JSON encoded labels to filter by\nfunc (r WorkspaceAPIListWorkspacesDeprecatedRequest) Labels(labels string) WorkspaceAPIListWorkspacesDeprecatedRequest {\n\tr.labels = &labels\n\treturn r\n}\n\nfunc (r WorkspaceAPIListWorkspacesDeprecatedRequest) Execute() ([]Workspace, *http.Response, error) {\n\treturn r.ApiService.ListWorkspacesDeprecatedExecute(r)\n}\n\n/*\nListWorkspacesDeprecated [DEPRECATED] List all workspaces\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @return WorkspaceAPIListWorkspacesDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) ListWorkspacesDeprecated(ctx context.Context) WorkspaceAPIListWorkspacesDeprecatedRequest {\n\treturn WorkspaceAPIListWorkspacesDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t}\n}\n\n// Execute executes the request\n//  @return []Workspace\n// Deprecated\nfunc (a *WorkspaceAPIService) ListWorkspacesDeprecatedExecute(r WorkspaceAPIListWorkspacesDeprecatedRequest) ([]Workspace, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodGet\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  []Workspace\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.ListWorkspacesDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace\"\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\tif r.verbose != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"verbose\", r.verbose, \"form\", \"\")\n\t}\n\tif r.labels != nil {\n\t\tparameterAddToHeaderOrQuery(localVarQueryParams, \"labels\", r.labels, \"form\", \"\")\n\t}\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\tsandboxLabels *SandboxLabels\n\txDaytonaOrganizationID *string\n}\n\nfunc (r WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest) SandboxLabels(sandboxLabels SandboxLabels) WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest {\n\tr.sandboxLabels = &sandboxLabels\n\treturn r\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest) Execute() (*SandboxLabels, *http.Response, error) {\n\treturn r.ApiService.ReplaceLabelsWorkspaceDeprecatedExecute(r)\n}\n\n/*\nReplaceLabelsWorkspaceDeprecated [DEPRECATED] Replace workspace labels\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @return WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) ReplaceLabelsWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t}\n}\n\n// Execute executes the request\n//  @return SandboxLabels\n// Deprecated\nfunc (a *WorkspaceAPIService) ReplaceLabelsWorkspaceDeprecatedExecute(r WorkspaceAPIReplaceLabelsWorkspaceDeprecatedRequest) (*SandboxLabels, *http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPut\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t\tlocalVarReturnValue  *SandboxLabels\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.ReplaceLabelsWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/labels\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\tif r.sandboxLabels == nil {\n\t\treturn localVarReturnValue, nil, reportError(\"sandboxLabels is required and must be specified\")\n\t}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{\"application/json\"}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{\"application/json\"}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\t// body params\n\tlocalVarPostBody = r.sandboxLabels\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn localVarReturnValue, nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarReturnValue, localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\terr = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: err.Error(),\n\t\t}\n\t\treturn localVarReturnValue, localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarReturnValue, localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\tinterval float32\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.SetAutoArchiveIntervalWorkspaceDeprecatedExecute(r)\n}\n\n/*\nSetAutoArchiveIntervalWorkspaceDeprecated [DEPRECATED] Set workspace auto-archive interval\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @param interval Auto-archive interval in minutes (0 means the maximum interval will be used)\n @return WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) SetAutoArchiveIntervalWorkspaceDeprecated(ctx context.Context, workspaceId string, interval float32) WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t\tinterval: interval,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *WorkspaceAPIService) SetAutoArchiveIntervalWorkspaceDeprecatedExecute(r WorkspaceAPISetAutoArchiveIntervalWorkspaceDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.SetAutoArchiveIntervalWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/autoarchive/{interval}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"interval\"+\"}\", url.PathEscape(parameterValueToString(r.interval, \"interval\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\tinterval float32\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.SetAutostopIntervalWorkspaceDeprecatedExecute(r)\n}\n\n/*\nSetAutostopIntervalWorkspaceDeprecated [DEPRECATED] Set workspace auto-stop interval\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @param interval Auto-stop interval in minutes (0 to disable)\n @return WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) SetAutostopIntervalWorkspaceDeprecated(ctx context.Context, workspaceId string, interval float32) WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t\tinterval: interval,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *WorkspaceAPIService) SetAutostopIntervalWorkspaceDeprecatedExecute(r WorkspaceAPISetAutostopIntervalWorkspaceDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.SetAutostopIntervalWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/autostop/{interval}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"interval\"+\"}\", url.PathEscape(parameterValueToString(r.interval, \"interval\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIStartWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIStartWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIStartWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPIStartWorkspaceDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.StartWorkspaceDeprecatedExecute(r)\n}\n\n/*\nStartWorkspaceDeprecated [DEPRECATED] Start workspace\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @return WorkspaceAPIStartWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) StartWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIStartWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIStartWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *WorkspaceAPIService) StartWorkspaceDeprecatedExecute(r WorkspaceAPIStartWorkspaceDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.StartWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/start\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIStopWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIStopWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIStopWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPIStopWorkspaceDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.StopWorkspaceDeprecatedExecute(r)\n}\n\n/*\nStopWorkspaceDeprecated [DEPRECATED] Stop workspace\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @return WorkspaceAPIStopWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) StopWorkspaceDeprecated(ctx context.Context, workspaceId string) WorkspaceAPIStopWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIStopWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *WorkspaceAPIService) StopWorkspaceDeprecatedExecute(r WorkspaceAPIStopWorkspaceDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.StopWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/stop\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n\ntype WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest struct {\n\tctx context.Context\n\tApiService WorkspaceAPI\n\tworkspaceId string\n\tisPublic bool\n\txDaytonaOrganizationID *string\n}\n\n// Use with JWT to specify the organization ID\nfunc (r WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest) XDaytonaOrganizationID(xDaytonaOrganizationID string) WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest {\n\tr.xDaytonaOrganizationID = &xDaytonaOrganizationID\n\treturn r\n}\n\nfunc (r WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest) Execute() (*http.Response, error) {\n\treturn r.ApiService.UpdatePublicStatusWorkspaceDeprecatedExecute(r)\n}\n\n/*\nUpdatePublicStatusWorkspaceDeprecated [DEPRECATED] Update public status\n\n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().\n @param workspaceId ID of the workspace\n @param isPublic Public status to set\n @return WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest\n\nDeprecated\n*/\nfunc (a *WorkspaceAPIService) UpdatePublicStatusWorkspaceDeprecated(ctx context.Context, workspaceId string, isPublic bool) WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest {\n\treturn WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest{\n\t\tApiService: a,\n\t\tctx: ctx,\n\t\tworkspaceId: workspaceId,\n\t\tisPublic: isPublic,\n\t}\n}\n\n// Execute executes the request\n// Deprecated\nfunc (a *WorkspaceAPIService) UpdatePublicStatusWorkspaceDeprecatedExecute(r WorkspaceAPIUpdatePublicStatusWorkspaceDeprecatedRequest) (*http.Response, error) {\n\tvar (\n\t\tlocalVarHTTPMethod   = http.MethodPost\n\t\tlocalVarPostBody     interface{}\n\t\tformFiles            []formFile\n\t)\n\n\tlocalBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, \"WorkspaceAPIService.UpdatePublicStatusWorkspaceDeprecated\")\n\tif err != nil {\n\t\treturn nil, &GenericOpenAPIError{error: err.Error()}\n\t}\n\n\tlocalVarPath := localBasePath + \"/workspace/{workspaceId}/public/{isPublic}\"\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"workspaceId\"+\"}\", url.PathEscape(parameterValueToString(r.workspaceId, \"workspaceId\")), -1)\n\tlocalVarPath = strings.Replace(localVarPath, \"{\"+\"isPublic\"+\"}\", url.PathEscape(parameterValueToString(r.isPublic, \"isPublic\")), -1)\n\n\tlocalVarHeaderParams := make(map[string]string)\n\tlocalVarQueryParams := url.Values{}\n\tlocalVarFormParams := url.Values{}\n\n\t// to determine the Content-Type header\n\tlocalVarHTTPContentTypes := []string{}\n\n\t// set Content-Type header\n\tlocalVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)\n\tif localVarHTTPContentType != \"\" {\n\t\tlocalVarHeaderParams[\"Content-Type\"] = localVarHTTPContentType\n\t}\n\n\t// to determine the Accept header\n\tlocalVarHTTPHeaderAccepts := []string{}\n\n\t// set Accept header\n\tlocalVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)\n\tif localVarHTTPHeaderAccept != \"\" {\n\t\tlocalVarHeaderParams[\"Accept\"] = localVarHTTPHeaderAccept\n\t}\n\tif r.xDaytonaOrganizationID != nil {\n\t\tparameterAddToHeaderOrQuery(localVarHeaderParams, \"X-Daytona-Organization-ID\", r.xDaytonaOrganizationID, \"simple\", \"\")\n\t}\n\treq, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlocalVarHTTPResponse, err := a.client.callAPI(req)\n\tif err != nil || localVarHTTPResponse == nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tlocalVarBody, err := io.ReadAll(localVarHTTPResponse.Body)\n\tlocalVarHTTPResponse.Body.Close()\n\tlocalVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))\n\tif err != nil {\n\t\treturn localVarHTTPResponse, err\n\t}\n\n\tif localVarHTTPResponse.StatusCode >= 300 {\n\t\tnewErr := &GenericOpenAPIError{\n\t\t\tbody:  localVarBody,\n\t\t\terror: localVarHTTPResponse.Status,\n\t\t}\n\t\treturn localVarHTTPResponse, newErr\n\t}\n\n\treturn localVarHTTPResponse, nil\n}\n"
  },
  {
    "path": "libs/api-client-go/client.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"encoding/xml\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n)\n\nvar (\n\tJsonCheck       = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\\+)?json)`)\n\tXmlCheck        = regexp.MustCompile(`(?i:(?:application|text)/(?:[^;]+\\+)?xml)`)\n\tqueryParamSplit = regexp.MustCompile(`(^|&)([^&]+)`)\n\tqueryDescape    = strings.NewReplacer( \"%5B\", \"[\", \"%5D\", \"]\" )\n)\n\n// APIClient manages communication with the Daytona API v1.0\n// In most cases there should be only one, shared, APIClient.\ntype APIClient struct {\n\tcfg    *Configuration\n\tcommon service // Reuse a single struct instead of allocating one for each service on the heap.\n\n\t// API Services\n\n\tAdminAPI AdminAPI\n\n\tApiKeysAPI ApiKeysAPI\n\n\tAuditAPI AuditAPI\n\n\tConfigAPI ConfigAPI\n\n\tDockerRegistryAPI DockerRegistryAPI\n\n\tHealthAPI HealthAPI\n\n\tJobsAPI JobsAPI\n\n\tObjectStorageAPI ObjectStorageAPI\n\n\tOrganizationsAPI OrganizationsAPI\n\n\tPreviewAPI PreviewAPI\n\n\tRegionsAPI RegionsAPI\n\n\tRunnersAPI RunnersAPI\n\n\tSandboxAPI SandboxAPI\n\n\tSnapshotsAPI SnapshotsAPI\n\n\tToolboxAPI ToolboxAPI\n\n\tUsersAPI UsersAPI\n\n\tVolumesAPI VolumesAPI\n\n\tWebhooksAPI WebhooksAPI\n\n\tWorkspaceAPI WorkspaceAPI\n}\n\ntype service struct {\n\tclient *APIClient\n}\n\n// NewAPIClient creates a new API client. Requires a userAgent string describing your application.\n// optionally a custom http.Client to allow for advanced features such as caching.\nfunc NewAPIClient(cfg *Configuration) *APIClient {\n\tif cfg.HTTPClient == nil {\n\t\tcfg.HTTPClient = http.DefaultClient\n\t}\n\n\tc := &APIClient{}\n\tc.cfg = cfg\n\tc.common.client = c\n\n\t// API Services\n\tc.AdminAPI = (*AdminAPIService)(&c.common)\n\tc.ApiKeysAPI = (*ApiKeysAPIService)(&c.common)\n\tc.AuditAPI = (*AuditAPIService)(&c.common)\n\tc.ConfigAPI = (*ConfigAPIService)(&c.common)\n\tc.DockerRegistryAPI = (*DockerRegistryAPIService)(&c.common)\n\tc.HealthAPI = (*HealthAPIService)(&c.common)\n\tc.JobsAPI = (*JobsAPIService)(&c.common)\n\tc.ObjectStorageAPI = (*ObjectStorageAPIService)(&c.common)\n\tc.OrganizationsAPI = (*OrganizationsAPIService)(&c.common)\n\tc.PreviewAPI = (*PreviewAPIService)(&c.common)\n\tc.RegionsAPI = (*RegionsAPIService)(&c.common)\n\tc.RunnersAPI = (*RunnersAPIService)(&c.common)\n\tc.SandboxAPI = (*SandboxAPIService)(&c.common)\n\tc.SnapshotsAPI = (*SnapshotsAPIService)(&c.common)\n\tc.ToolboxAPI = (*ToolboxAPIService)(&c.common)\n\tc.UsersAPI = (*UsersAPIService)(&c.common)\n\tc.VolumesAPI = (*VolumesAPIService)(&c.common)\n\tc.WebhooksAPI = (*WebhooksAPIService)(&c.common)\n\tc.WorkspaceAPI = (*WorkspaceAPIService)(&c.common)\n\n\treturn c\n}\n\nfunc atoi(in string) (int, error) {\n\treturn strconv.Atoi(in)\n}\n\n// selectHeaderContentType select a content type from the available list.\nfunc selectHeaderContentType(contentTypes []string) string {\n\tif len(contentTypes) == 0 {\n\t\treturn \"\"\n\t}\n\tif contains(contentTypes, \"application/json\") {\n\t\treturn \"application/json\"\n\t}\n\treturn contentTypes[0] // use the first content type specified in 'consumes'\n}\n\n// selectHeaderAccept join all accept types and return\nfunc selectHeaderAccept(accepts []string) string {\n\tif len(accepts) == 0 {\n\t\treturn \"\"\n\t}\n\n\tif contains(accepts, \"application/json\") {\n\t\treturn \"application/json\"\n\t}\n\n\treturn strings.Join(accepts, \",\")\n}\n\n// contains is a case insensitive match, finding needle in a haystack\nfunc contains(haystack []string, needle string) bool {\n\tfor _, a := range haystack {\n\t\tif strings.EqualFold(a, needle) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Verify optional parameters are of the correct type.\nfunc typeCheckParameter(obj interface{}, expected string, name string) error {\n\t// Make sure there is an object.\n\tif obj == nil {\n\t\treturn nil\n\t}\n\n\t// Check the type is as expected.\n\tif reflect.TypeOf(obj).String() != expected {\n\t\treturn fmt.Errorf(\"expected %s to be of type %s but received %s\", name, expected, reflect.TypeOf(obj).String())\n\t}\n\treturn nil\n}\n\nfunc parameterValueToString( obj interface{}, key string ) string {\n\tif reflect.TypeOf(obj).Kind() != reflect.Ptr {\n\t\tif actualObj, ok := obj.(interface{ GetActualInstanceValue() interface{} }); ok {\n\t\t\treturn fmt.Sprintf(\"%v\", actualObj.GetActualInstanceValue())\n\t\t}\n\n\t\treturn fmt.Sprintf(\"%v\", obj)\n\t}\n\tvar param,ok = obj.(MappedNullable)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\tdataMap,err := param.ToMap()\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\treturn fmt.Sprintf(\"%v\", dataMap[key])\n}\n\n// parameterAddToHeaderOrQuery adds the provided object to the request header or url query\n// supporting deep object syntax\nfunc parameterAddToHeaderOrQuery(headerOrQueryParams interface{}, keyPrefix string, obj interface{}, style string, collectionType string) {\n\tvar v = reflect.ValueOf(obj)\n\tvar value = \"\"\n\tif v == reflect.ValueOf(nil) {\n\t\tvalue = \"null\"\n\t} else {\n\t\tswitch v.Kind() {\n\t\t\tcase reflect.Invalid:\n\t\t\t\tvalue = \"invalid\"\n\n\t\t\tcase reflect.Struct:\n\t\t\t\tif t,ok := obj.(MappedNullable); ok {\n\t\t\t\t\tdataMap,err := t.ToMap()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tparameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, dataMap, style, collectionType)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif t, ok := obj.(time.Time); ok {\n\t\t\t\t\tparameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, t.Format(time.RFC3339Nano), style, collectionType)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tvalue = v.Type().String() + \" value\"\n\t\t\tcase reflect.Slice:\n\t\t\t\tvar indValue = reflect.ValueOf(obj)\n\t\t\t\tif indValue == reflect.ValueOf(nil) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tvar lenIndValue = indValue.Len()\n\t\t\t\tfor i:=0;i<lenIndValue;i++ {\n\t\t\t\t\tvar arrayValue = indValue.Index(i)\n\t\t\t\t\tvar keyPrefixForCollectionType = keyPrefix\n\t\t\t\t\tif style == \"deepObject\" {\n\t\t\t\t\t\tkeyPrefixForCollectionType = keyPrefix + \"[\" + strconv.Itoa(i) + \"]\"\n\t\t\t\t\t}\n\t\t\t\t\tparameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefixForCollectionType, arrayValue.Interface(), style, collectionType)\n\t\t\t\t}\n\t\t\t\treturn\n\n\t\t\tcase reflect.Map:\n\t\t\t\tvar indValue = reflect.ValueOf(obj)\n\t\t\t\tif indValue == reflect.ValueOf(nil) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\titer := indValue.MapRange()\n\t\t\t\tfor iter.Next() {\n\t\t\t\t\tk,v := iter.Key(), iter.Value()\n\t\t\t\t\tparameterAddToHeaderOrQuery(headerOrQueryParams, fmt.Sprintf(\"%s[%s]\", keyPrefix, k.String()), v.Interface(), style, collectionType)\n\t\t\t\t}\n\t\t\t\treturn\n\n\t\t\tcase reflect.Interface:\n\t\t\t\tfallthrough\n\t\t\tcase reflect.Ptr:\n\t\t\t\tparameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, v.Elem().Interface(), style, collectionType)\n\t\t\t\treturn\n\n\t\t\tcase reflect.Int, reflect.Int8, reflect.Int16,\n\t\t\t\treflect.Int32, reflect.Int64:\n\t\t\t\tvalue = strconv.FormatInt(v.Int(), 10)\n\t\t\tcase reflect.Uint, reflect.Uint8, reflect.Uint16,\n\t\t\t\treflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\t\t\tvalue = strconv.FormatUint(v.Uint(), 10)\n\t\t\tcase reflect.Float32, reflect.Float64:\n\t\t\t\tvalue = strconv.FormatFloat(v.Float(), 'g', -1, 32)\n\t\t\tcase reflect.Bool:\n\t\t\t\tvalue = strconv.FormatBool(v.Bool())\n\t\t\tcase reflect.String:\n\t\t\t\tvalue = v.String()\n\t\t\tdefault:\n\t\t\t\tvalue = v.Type().String() + \" value\"\n\t\t}\n\t}\n\n\tswitch valuesMap := headerOrQueryParams.(type) {\n\t\tcase url.Values:\n\t\t\tif collectionType == \"csv\" && valuesMap.Get(keyPrefix) != \"\" {\n\t\t\t\tvaluesMap.Set(keyPrefix, valuesMap.Get(keyPrefix) + \",\" + value)\n\t\t\t} else {\n\t\t\t\tvaluesMap.Add(keyPrefix, value)\n\t\t\t}\n\t\t\tbreak\n\t\tcase map[string]string:\n\t\t\tvaluesMap[keyPrefix] = value\n\t\t\tbreak\n\t}\n}\n\n// helper for converting interface{} parameters to json strings\nfunc parameterToJson(obj interface{}) (string, error) {\n\tjsonBuf, err := json.Marshal(obj)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(jsonBuf), err\n}\n\n// callAPI do the request.\nfunc (c *APIClient) callAPI(request *http.Request) (*http.Response, error) {\n\tif c.cfg.Debug {\n\t\tdump, err := httputil.DumpRequestOut(request, true)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlog.Printf(\"\\n%s\\n\", string(dump))\n\t}\n\n\tresp, err := c.cfg.HTTPClient.Do(request)\n\tif err != nil {\n\t\treturn resp, err\n\t}\n\n\tif c.cfg.Debug {\n\t\tdump, err := httputil.DumpResponse(resp, true)\n\t\tif err != nil {\n\t\t\treturn resp, err\n\t\t}\n\t\tlog.Printf(\"\\n%s\\n\", string(dump))\n\t}\n\treturn resp, err\n}\n\n// Allow modification of underlying config for alternate implementations and testing\n// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior\nfunc (c *APIClient) GetConfig() *Configuration {\n\treturn c.cfg\n}\n\ntype formFile struct {\n\t\tfileBytes []byte\n\t\tfileName string\n\t\tformFileName string\n}\n\n// prepareRequest build the request\nfunc (c *APIClient) prepareRequest(\n\tctx context.Context,\n\tpath string, method string,\n\tpostBody interface{},\n\theaderParams map[string]string,\n\tqueryParams url.Values,\n\tformParams url.Values,\n\tformFiles []formFile) (localVarRequest *http.Request, err error) {\n\n\tvar body *bytes.Buffer\n\n\t// Detect postBody type and post.\n\tif postBody != nil {\n\t\tcontentType := headerParams[\"Content-Type\"]\n\t\tif contentType == \"\" {\n\t\t\tcontentType = detectContentType(postBody)\n\t\t\theaderParams[\"Content-Type\"] = contentType\n\t\t}\n\n\t\tbody, err = setBody(postBody, contentType)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// add form parameters and file if available.\n\tif strings.HasPrefix(headerParams[\"Content-Type\"], \"multipart/form-data\") && len(formParams) > 0 || (len(formFiles) > 0) {\n\t\tif body != nil {\n\t\t\treturn nil, errors.New(\"Cannot specify postBody and multipart form at the same time.\")\n\t\t}\n\t\tbody = &bytes.Buffer{}\n\t\tw := multipart.NewWriter(body)\n\n\t\tfor k, v := range formParams {\n\t\t\tfor _, iv := range v {\n\t\t\t\tif strings.HasPrefix(k, \"@\") { // file\n\t\t\t\t\terr = addFile(w, k[1:], iv)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t} else { // form value\n\t\t\t\t\tw.WriteField(k, iv)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor _, formFile := range formFiles {\n\t\t\tif len(formFile.fileBytes) > 0 && formFile.fileName != \"\" {\n\t\t\t\tw.Boundary()\n\t\t\t\tpart, err := w.CreateFormFile(formFile.formFileName, filepath.Base(formFile.fileName))\n\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\t_, err = part.Write(formFile.fileBytes)\n\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Set the Boundary in the Content-Type\n\t\theaderParams[\"Content-Type\"] = w.FormDataContentType()\n\n\t\t// Set Content-Length\n\t\theaderParams[\"Content-Length\"] = fmt.Sprintf(\"%d\", body.Len())\n\t\tw.Close()\n\t}\n\n\tif strings.HasPrefix(headerParams[\"Content-Type\"], \"application/x-www-form-urlencoded\") && len(formParams) > 0 {\n\t\tif body != nil {\n\t\t\treturn nil, errors.New(\"Cannot specify postBody and x-www-form-urlencoded form at the same time.\")\n\t\t}\n\t\tbody = &bytes.Buffer{}\n\t\tbody.WriteString(formParams.Encode())\n\t\t// Set Content-Length\n\t\theaderParams[\"Content-Length\"] = fmt.Sprintf(\"%d\", body.Len())\n\t}\n\n\t// Setup path and query parameters\n\turl, err := url.Parse(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Override request host, if applicable\n\tif c.cfg.Host != \"\" {\n\t\turl.Host = c.cfg.Host\n\t}\n\n\t// Override request scheme, if applicable\n\tif c.cfg.Scheme != \"\" {\n\t\turl.Scheme = c.cfg.Scheme\n\t}\n\n\t// Adding Query Param\n\tquery := url.Query()\n\tfor k, v := range queryParams {\n\t\tfor _, iv := range v {\n\t\t\tquery.Add(k, iv)\n\t\t}\n\t}\n\n\t// Encode the parameters.\n\turl.RawQuery = queryParamSplit.ReplaceAllStringFunc(query.Encode(), func(s string) string {\n\t\tpieces := strings.Split(s, \"=\")\n\t\tpieces[0] = queryDescape.Replace(pieces[0])\n\t\treturn strings.Join(pieces, \"=\")\n\t})\n\n\t// Generate a new request\n\tif body != nil {\n\t\tlocalVarRequest, err = http.NewRequest(method, url.String(), body)\n\t} else {\n\t\tlocalVarRequest, err = http.NewRequest(method, url.String(), nil)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// add header parameters, if any\n\tif len(headerParams) > 0 {\n\t\theaders := http.Header{}\n\t\tfor h, v := range headerParams {\n\t\t\theaders[h] = []string{v}\n\t\t}\n\t\tlocalVarRequest.Header = headers\n\t}\n\n\t// Add the user agent to the request.\n\tlocalVarRequest.Header.Add(\"User-Agent\", c.cfg.UserAgent)\n\n\tif ctx != nil {\n\t\t// add context to the request\n\t\tlocalVarRequest = localVarRequest.WithContext(ctx)\n\n\t\t// Walk through any authentication.\n\n\t\t// AccessToken Authentication\n\t\tif auth, ok := ctx.Value(ContextAccessToken).(string); ok {\n\t\t\tlocalVarRequest.Header.Add(\"Authorization\", \"Bearer \"+auth)\n\t\t}\n\n\t}\n\n\tfor header, value := range c.cfg.DefaultHeader {\n\t\tlocalVarRequest.Header.Add(header, value)\n\t}\n\treturn localVarRequest, nil\n}\n\nfunc (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) {\n\tif len(b) == 0 {\n\t\treturn nil\n\t}\n\tif s, ok := v.(*string); ok {\n\t\t*s = string(b)\n\t\treturn nil\n\t}\n\tif f, ok := v.(*os.File); ok {\n\t\tf, err = os.CreateTemp(\"\", \"HttpClientFile\")\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\t_, err = f.Write(b)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\t_, err = f.Seek(0, io.SeekStart)\n\t\treturn\n\t}\n\tif f, ok := v.(**os.File); ok {\n\t\t*f, err = os.CreateTemp(\"\", \"HttpClientFile\")\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\t_, err = (*f).Write(b)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\t_, err = (*f).Seek(0, io.SeekStart)\n\t\treturn\n\t}\n\tif XmlCheck.MatchString(contentType) {\n\t\tif err = xml.Unmarshal(b, v); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\tif JsonCheck.MatchString(contentType) {\n\t\tif actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas\n\t\t\tif unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined\n\t\t\t\tif err = unmarshalObj.UnmarshalJSON(b); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn errors.New(\"Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined\")\n\t\t\t}\n\t\t} else if err = json.Unmarshal(b, v); err != nil { // simple model\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\treturn errors.New(\"undefined response type\")\n}\n\n// Add a file to the multipart request\nfunc addFile(w *multipart.Writer, fieldName, path string) error {\n\tfile, err := os.Open(filepath.Clean(path))\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = file.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpart, err := w.CreateFormFile(fieldName, filepath.Base(path))\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = io.Copy(part, file)\n\n\treturn err\n}\n\n// Set request body from an interface{}\nfunc setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) {\n\tif bodyBuf == nil {\n\t\tbodyBuf = &bytes.Buffer{}\n\t}\n\n\tif reader, ok := body.(io.Reader); ok {\n\t\t_, err = bodyBuf.ReadFrom(reader)\n\t} else if fp, ok := body.(*os.File); ok {\n\t\t_, err = bodyBuf.ReadFrom(fp)\n\t} else if b, ok := body.([]byte); ok {\n\t\t_, err = bodyBuf.Write(b)\n\t} else if s, ok := body.(string); ok {\n\t\t_, err = bodyBuf.WriteString(s)\n\t} else if s, ok := body.(*string); ok {\n\t\t_, err = bodyBuf.WriteString(*s)\n\t} else if JsonCheck.MatchString(contentType) {\n\t\terr = json.NewEncoder(bodyBuf).Encode(body)\n\t} else if XmlCheck.MatchString(contentType) {\n\t\tvar bs []byte\n\t\tbs, err = xml.Marshal(body)\n\t\tif err == nil {\n\t\t\tbodyBuf.Write(bs)\n\t\t}\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif bodyBuf.Len() == 0 {\n\t\terr = fmt.Errorf(\"invalid body type %s\\n\", contentType)\n\t\treturn nil, err\n\t}\n\treturn bodyBuf, nil\n}\n\n// detectContentType method is used to figure out `Request.Body` content type for request header\nfunc detectContentType(body interface{}) string {\n\tcontentType := \"text/plain; charset=utf-8\"\n\tkind := reflect.TypeOf(body).Kind()\n\n\tswitch kind {\n\tcase reflect.Struct, reflect.Map, reflect.Ptr:\n\t\tcontentType = \"application/json; charset=utf-8\"\n\tcase reflect.String:\n\t\tcontentType = \"text/plain; charset=utf-8\"\n\tdefault:\n\t\tif b, ok := body.([]byte); ok {\n\t\t\tcontentType = http.DetectContentType(b)\n\t\t} else if kind == reflect.Slice {\n\t\t\tcontentType = \"application/json; charset=utf-8\"\n\t\t}\n\t}\n\n\treturn contentType\n}\n\n// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go\ntype cacheControl map[string]string\n\nfunc parseCacheControl(headers http.Header) cacheControl {\n\tcc := cacheControl{}\n\tccHeader := headers.Get(\"Cache-Control\")\n\tfor _, part := range strings.Split(ccHeader, \",\") {\n\t\tpart = strings.Trim(part, \" \")\n\t\tif part == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.ContainsRune(part, '=') {\n\t\t\tkeyval := strings.Split(part, \"=\")\n\t\t\tcc[strings.Trim(keyval[0], \" \")] = strings.Trim(keyval[1], \",\")\n\t\t} else {\n\t\t\tcc[part] = \"\"\n\t\t}\n\t}\n\treturn cc\n}\n\n// CacheExpires helper function to determine remaining time before repeating a request.\nfunc CacheExpires(r *http.Response) time.Time {\n\t// Figure out when the cache expires.\n\tvar expires time.Time\n\tnow, err := time.Parse(time.RFC1123, r.Header.Get(\"date\"))\n\tif err != nil {\n\t\treturn time.Now()\n\t}\n\trespCacheControl := parseCacheControl(r.Header)\n\n\tif maxAge, ok := respCacheControl[\"max-age\"]; ok {\n\t\tlifetime, err := time.ParseDuration(maxAge + \"s\")\n\t\tif err != nil {\n\t\t\texpires = now\n\t\t} else {\n\t\t\texpires = now.Add(lifetime)\n\t\t}\n\t} else {\n\t\texpiresHeader := r.Header.Get(\"Expires\")\n\t\tif expiresHeader != \"\" {\n\t\t\texpires, err = time.Parse(time.RFC1123, expiresHeader)\n\t\t\tif err != nil {\n\t\t\t\texpires = now\n\t\t\t}\n\t\t}\n\t}\n\treturn expires\n}\n\nfunc strlen(s string) int {\n\treturn utf8.RuneCountInString(s)\n}\n\n// GenericOpenAPIError Provides access to the body, error and model on returned errors.\ntype GenericOpenAPIError struct {\n\tbody  []byte\n\terror string\n\tmodel interface{}\n}\n\n// Error returns non-empty string if there was an error.\nfunc (e GenericOpenAPIError) Error() string {\n\treturn e.error\n}\n\n// Body returns the raw bytes of the response\nfunc (e GenericOpenAPIError) Body() []byte {\n\treturn e.body\n}\n\n// Model returns the unpacked model of the error\nfunc (e GenericOpenAPIError) Model() interface{} {\n\treturn e.model\n}\n\n// format error message using title and detail when model implements rfc7807\nfunc formatErrorMessage(status string, v interface{}) string {\n\tstr := \"\"\n\tmetaValue := reflect.ValueOf(v).Elem()\n\n\tif metaValue.Kind() == reflect.Struct {\n\t\tfield := metaValue.FieldByName(\"Title\")\n\t\tif field != (reflect.Value{}) {\n\t\t\tstr = fmt.Sprintf(\"%s\", field.Interface())\n\t\t}\n\n\t\tfield = metaValue.FieldByName(\"Detail\")\n\t\tif field != (reflect.Value{}) {\n\t\t\tstr = fmt.Sprintf(\"%s (%s)\", str, field.Interface())\n\t\t}\n\t}\n\n\treturn strings.TrimSpace(fmt.Sprintf(\"%s %s\", status, str))\n}\n"
  },
  {
    "path": "libs/api-client-go/configuration.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// contextKeys are used to identify the type of value in the context.\n// Since these are string, it is possible to get a short description of the\n// context key for logging and debugging using key.String().\n\ntype contextKey string\n\nfunc (c contextKey) String() string {\n\treturn \"auth \" + string(c)\n}\n\nvar (\n\t// ContextAccessToken takes a string oauth2 access token as authentication for the request.\n\tContextAccessToken = contextKey(\"accesstoken\")\n\n\t// ContextServerIndex uses a server configuration from the index.\n\tContextServerIndex = contextKey(\"serverIndex\")\n\n\t// ContextOperationServerIndices uses a server configuration from the index mapping.\n\tContextOperationServerIndices = contextKey(\"serverOperationIndices\")\n\n\t// ContextServerVariables overrides a server configuration variables.\n\tContextServerVariables = contextKey(\"serverVariables\")\n\n\t// ContextOperationServerVariables overrides a server configuration variables using operation specific values.\n\tContextOperationServerVariables = contextKey(\"serverOperationVariables\")\n)\n\n// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth\ntype BasicAuth struct {\n\tUserName string `json:\"userName,omitempty\"`\n\tPassword string `json:\"password,omitempty\"`\n}\n\n// APIKey provides API key based authentication to a request passed via context using ContextAPIKey\ntype APIKey struct {\n\tKey    string\n\tPrefix string\n}\n\n// ServerVariable stores the information about a server variable\ntype ServerVariable struct {\n\tDescription  string\n\tDefaultValue string\n\tEnumValues   []string\n}\n\n// ServerConfiguration stores the information about a server\ntype ServerConfiguration struct {\n\tURL string\n\tDescription string\n\tVariables map[string]ServerVariable\n}\n\n// ServerConfigurations stores multiple ServerConfiguration items\ntype ServerConfigurations []ServerConfiguration\n\n// Configuration stores the configuration of the API client\ntype Configuration struct {\n\tHost             string            `json:\"host,omitempty\"`\n\tScheme           string            `json:\"scheme,omitempty\"`\n\tDefaultHeader    map[string]string `json:\"defaultHeader,omitempty\"`\n\tUserAgent        string            `json:\"userAgent,omitempty\"`\n\tDebug            bool              `json:\"debug,omitempty\"`\n\tServers          ServerConfigurations\n\tOperationServers map[string]ServerConfigurations\n\tHTTPClient       *http.Client\n}\n\n// NewConfiguration returns a new Configuration object\nfunc NewConfiguration() *Configuration {\n\tcfg := &Configuration{\n\t\tDefaultHeader:    make(map[string]string),\n\t\tUserAgent:        \"OpenAPI-Generator/1.0.0/go\",\n\t\tDebug:            false,\n\t\tServers:          ServerConfigurations{\n\t\t\t{\n\t\t\t\tURL: \"http://localhost:3000\",\n\t\t\t\tDescription: \"No description provided\",\n\t\t\t},\n\t\t},\n\t\tOperationServers: map[string]ServerConfigurations{\n\t\t},\n\t}\n\treturn cfg\n}\n\n// AddDefaultHeader adds a new HTTP header to the default header in the request\nfunc (c *Configuration) AddDefaultHeader(key string, value string) {\n\tc.DefaultHeader[key] = value\n}\n\n// URL formats template on a index using given variables\nfunc (sc ServerConfigurations) URL(index int, variables map[string]string) (string, error) {\n\tif index < 0 || len(sc) <= index {\n\t\treturn \"\", fmt.Errorf(\"index %v out of range %v\", index, len(sc)-1)\n\t}\n\tserver := sc[index]\n\turl := server.URL\n\n\t// go through variables and replace placeholders\n\tfor name, variable := range server.Variables {\n\t\tif value, ok := variables[name]; ok {\n\t\t\tfound := bool(len(variable.EnumValues) == 0)\n\t\t\tfor _, enumValue := range variable.EnumValues {\n\t\t\t\tif value == enumValue {\n\t\t\t\t\tfound = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !found {\n\t\t\t\treturn \"\", fmt.Errorf(\"the variable %s in the server URL has invalid value %v. Must be %v\", name, value, variable.EnumValues)\n\t\t\t}\n\t\t\turl = strings.Replace(url, \"{\"+name+\"}\", value, -1)\n\t\t} else {\n\t\t\turl = strings.Replace(url, \"{\"+name+\"}\", variable.DefaultValue, -1)\n\t\t}\n\t}\n\treturn url, nil\n}\n\n// ServerURL returns URL based on server settings\nfunc (c *Configuration) ServerURL(index int, variables map[string]string) (string, error) {\n\treturn c.Servers.URL(index, variables)\n}\n\nfunc getServerIndex(ctx context.Context) (int, error) {\n\tsi := ctx.Value(ContextServerIndex)\n\tif si != nil {\n\t\tif index, ok := si.(int); ok {\n\t\t\treturn index, nil\n\t\t}\n\t\treturn 0, reportError(\"Invalid type %T should be int\", si)\n\t}\n\treturn 0, nil\n}\n\nfunc getServerOperationIndex(ctx context.Context, endpoint string) (int, error) {\n\tosi := ctx.Value(ContextOperationServerIndices)\n\tif osi != nil {\n\t\tif operationIndices, ok := osi.(map[string]int); !ok {\n\t\t\treturn 0, reportError(\"Invalid type %T should be map[string]int\", osi)\n\t\t} else {\n\t\t\tindex, ok := operationIndices[endpoint]\n\t\t\tif ok {\n\t\t\t\treturn index, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn getServerIndex(ctx)\n}\n\nfunc getServerVariables(ctx context.Context) (map[string]string, error) {\n\tsv := ctx.Value(ContextServerVariables)\n\tif sv != nil {\n\t\tif variables, ok := sv.(map[string]string); ok {\n\t\t\treturn variables, nil\n\t\t}\n\t\treturn nil, reportError(\"ctx value of ContextServerVariables has invalid type %T should be map[string]string\", sv)\n\t}\n\treturn nil, nil\n}\n\nfunc getServerOperationVariables(ctx context.Context, endpoint string) (map[string]string, error) {\n\tosv := ctx.Value(ContextOperationServerVariables)\n\tif osv != nil {\n\t\tif operationVariables, ok := osv.(map[string]map[string]string); !ok {\n\t\t\treturn nil, reportError(\"ctx value of ContextOperationServerVariables has invalid type %T should be map[string]map[string]string\", osv)\n\t\t} else {\n\t\t\tvariables, ok := operationVariables[endpoint]\n\t\t\tif ok {\n\t\t\t\treturn variables, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn getServerVariables(ctx)\n}\n\n// ServerURLWithContext returns a new server URL given an endpoint\nfunc (c *Configuration) ServerURLWithContext(ctx context.Context, endpoint string) (string, error) {\n\tsc, ok := c.OperationServers[endpoint]\n\tif !ok {\n\t\tsc = c.Servers\n\t}\n\n\tif ctx == nil {\n\t\treturn sc.URL(0, nil)\n\t}\n\n\tindex, err := getServerOperationIndex(ctx, endpoint)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvariables, err := getServerOperationVariables(ctx, endpoint)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn sc.URL(index, variables)\n}\n"
  },
  {
    "path": "libs/api-client-go/go.mod",
    "content": "module github.com/daytonaio/daytona/libs/api-client-go\n\ngo 1.18\n\nrequire (\n)\n"
  },
  {
    "path": "libs/api-client-go/go.sum",
    "content": "cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngoogle.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\n"
  },
  {
    "path": "libs/api-client-go/model_account_provider.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the AccountProvider type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &AccountProvider{}\n\n// AccountProvider struct for AccountProvider\ntype AccountProvider struct {\n\tName string `json:\"name\"`\n\tDisplayName string `json:\"displayName\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _AccountProvider AccountProvider\n\n// NewAccountProvider instantiates a new AccountProvider object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewAccountProvider(name string, displayName string) *AccountProvider {\n\tthis := AccountProvider{}\n\tthis.Name = name\n\tthis.DisplayName = displayName\n\treturn &this\n}\n\n// NewAccountProviderWithDefaults instantiates a new AccountProvider object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewAccountProviderWithDefaults() *AccountProvider {\n\tthis := AccountProvider{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *AccountProvider) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *AccountProvider) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *AccountProvider) SetName(v string) {\n\to.Name = v\n}\n\n// GetDisplayName returns the DisplayName field value\nfunc (o *AccountProvider) GetDisplayName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.DisplayName\n}\n\n// GetDisplayNameOk returns a tuple with the DisplayName field value\n// and a boolean to check if the value has been set.\nfunc (o *AccountProvider) GetDisplayNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DisplayName, true\n}\n\n// SetDisplayName sets field value\nfunc (o *AccountProvider) SetDisplayName(v string) {\n\to.DisplayName = v\n}\n\nfunc (o AccountProvider) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o AccountProvider) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"displayName\"] = o.DisplayName\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *AccountProvider) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"displayName\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarAccountProvider := _AccountProvider{}\n\n\terr = json.Unmarshal(data, &varAccountProvider)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = AccountProvider(varAccountProvider)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"displayName\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableAccountProvider struct {\n\tvalue *AccountProvider\n\tisSet bool\n}\n\nfunc (v NullableAccountProvider) Get() *AccountProvider {\n\treturn v.value\n}\n\nfunc (v *NullableAccountProvider) Set(val *AccountProvider) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableAccountProvider) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableAccountProvider) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableAccountProvider(val *AccountProvider) *NullableAccountProvider {\n\treturn &NullableAccountProvider{value: val, isSet: true}\n}\n\nfunc (v NullableAccountProvider) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableAccountProvider) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_admin_create_runner.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the AdminCreateRunner type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &AdminCreateRunner{}\n\n// AdminCreateRunner struct for AdminCreateRunner\ntype AdminCreateRunner struct {\n\tRegionId string `json:\"regionId\"`\n\tName string `json:\"name\"`\n\tApiKey string `json:\"apiKey\"`\n\t// The api version of the runner to create\n\tApiVersion string `json:\"apiVersion\" validate:\"regexp=^(0|2)$\"`\n\t// The domain of the runner\n\tDomain *string `json:\"domain,omitempty\"`\n\t// The API URL of the runner\n\tApiUrl *string `json:\"apiUrl,omitempty\"`\n\t// The proxy URL of the runner\n\tProxyUrl *string `json:\"proxyUrl,omitempty\"`\n\t// The CPU capacity of the runner\n\tCpu *float32 `json:\"cpu,omitempty\"`\n\t// The memory capacity of the runner in GiB\n\tMemoryGiB *float32 `json:\"memoryGiB,omitempty\"`\n\t// The disk capacity of the runner in GiB\n\tDiskGiB *float32 `json:\"diskGiB,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _AdminCreateRunner AdminCreateRunner\n\n// NewAdminCreateRunner instantiates a new AdminCreateRunner object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewAdminCreateRunner(regionId string, name string, apiKey string, apiVersion string) *AdminCreateRunner {\n\tthis := AdminCreateRunner{}\n\tthis.RegionId = regionId\n\tthis.Name = name\n\tthis.ApiKey = apiKey\n\tthis.ApiVersion = apiVersion\n\treturn &this\n}\n\n// NewAdminCreateRunnerWithDefaults instantiates a new AdminCreateRunner object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewAdminCreateRunnerWithDefaults() *AdminCreateRunner {\n\tthis := AdminCreateRunner{}\n\treturn &this\n}\n\n// GetRegionId returns the RegionId field value\nfunc (o *AdminCreateRunner) GetRegionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RegionId\n}\n\n// GetRegionIdOk returns a tuple with the RegionId field value\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetRegionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegionId, true\n}\n\n// SetRegionId sets field value\nfunc (o *AdminCreateRunner) SetRegionId(v string) {\n\to.RegionId = v\n}\n\n// GetName returns the Name field value\nfunc (o *AdminCreateRunner) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *AdminCreateRunner) SetName(v string) {\n\to.Name = v\n}\n\n// GetApiKey returns the ApiKey field value\nfunc (o *AdminCreateRunner) GetApiKey() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ApiKey\n}\n\n// GetApiKeyOk returns a tuple with the ApiKey field value\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetApiKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ApiKey, true\n}\n\n// SetApiKey sets field value\nfunc (o *AdminCreateRunner) SetApiKey(v string) {\n\to.ApiKey = v\n}\n\n// GetApiVersion returns the ApiVersion field value\nfunc (o *AdminCreateRunner) GetApiVersion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ApiVersion\n}\n\n// GetApiVersionOk returns a tuple with the ApiVersion field value\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetApiVersionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ApiVersion, true\n}\n\n// SetApiVersion sets field value\nfunc (o *AdminCreateRunner) SetApiVersion(v string) {\n\to.ApiVersion = v\n}\n\n// GetDomain returns the Domain field value if set, zero value otherwise.\nfunc (o *AdminCreateRunner) GetDomain() string {\n\tif o == nil || IsNil(o.Domain) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Domain\n}\n\n// GetDomainOk returns a tuple with the Domain field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetDomainOk() (*string, bool) {\n\tif o == nil || IsNil(o.Domain) {\n\t\treturn nil, false\n\t}\n\treturn o.Domain, true\n}\n\n// HasDomain returns a boolean if a field has been set.\nfunc (o *AdminCreateRunner) HasDomain() bool {\n\tif o != nil && !IsNil(o.Domain) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDomain gets a reference to the given string and assigns it to the Domain field.\nfunc (o *AdminCreateRunner) SetDomain(v string) {\n\to.Domain = &v\n}\n\n// GetApiUrl returns the ApiUrl field value if set, zero value otherwise.\nfunc (o *AdminCreateRunner) GetApiUrl() string {\n\tif o == nil || IsNil(o.ApiUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ApiUrl\n}\n\n// GetApiUrlOk returns a tuple with the ApiUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetApiUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.ApiUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.ApiUrl, true\n}\n\n// HasApiUrl returns a boolean if a field has been set.\nfunc (o *AdminCreateRunner) HasApiUrl() bool {\n\tif o != nil && !IsNil(o.ApiUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetApiUrl gets a reference to the given string and assigns it to the ApiUrl field.\nfunc (o *AdminCreateRunner) SetApiUrl(v string) {\n\to.ApiUrl = &v\n}\n\n// GetProxyUrl returns the ProxyUrl field value if set, zero value otherwise.\nfunc (o *AdminCreateRunner) GetProxyUrl() string {\n\tif o == nil || IsNil(o.ProxyUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProxyUrl\n}\n\n// GetProxyUrlOk returns a tuple with the ProxyUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetProxyUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.ProxyUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.ProxyUrl, true\n}\n\n// HasProxyUrl returns a boolean if a field has been set.\nfunc (o *AdminCreateRunner) HasProxyUrl() bool {\n\tif o != nil && !IsNil(o.ProxyUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProxyUrl gets a reference to the given string and assigns it to the ProxyUrl field.\nfunc (o *AdminCreateRunner) SetProxyUrl(v string) {\n\to.ProxyUrl = &v\n}\n\n// GetCpu returns the Cpu field value if set, zero value otherwise.\nfunc (o *AdminCreateRunner) GetCpu() float32 {\n\tif o == nil || IsNil(o.Cpu) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetCpuOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Cpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Cpu, true\n}\n\n// HasCpu returns a boolean if a field has been set.\nfunc (o *AdminCreateRunner) HasCpu() bool {\n\tif o != nil && !IsNil(o.Cpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCpu gets a reference to the given float32 and assigns it to the Cpu field.\nfunc (o *AdminCreateRunner) SetCpu(v float32) {\n\to.Cpu = &v\n}\n\n// GetMemoryGiB returns the MemoryGiB field value if set, zero value otherwise.\nfunc (o *AdminCreateRunner) GetMemoryGiB() float32 {\n\tif o == nil || IsNil(o.MemoryGiB) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.MemoryGiB\n}\n\n// GetMemoryGiBOk returns a tuple with the MemoryGiB field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetMemoryGiBOk() (*float32, bool) {\n\tif o == nil || IsNil(o.MemoryGiB) {\n\t\treturn nil, false\n\t}\n\treturn o.MemoryGiB, true\n}\n\n// HasMemoryGiB returns a boolean if a field has been set.\nfunc (o *AdminCreateRunner) HasMemoryGiB() bool {\n\tif o != nil && !IsNil(o.MemoryGiB) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMemoryGiB gets a reference to the given float32 and assigns it to the MemoryGiB field.\nfunc (o *AdminCreateRunner) SetMemoryGiB(v float32) {\n\to.MemoryGiB = &v\n}\n\n// GetDiskGiB returns the DiskGiB field value if set, zero value otherwise.\nfunc (o *AdminCreateRunner) GetDiskGiB() float32 {\n\tif o == nil || IsNil(o.DiskGiB) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.DiskGiB\n}\n\n// GetDiskGiBOk returns a tuple with the DiskGiB field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AdminCreateRunner) GetDiskGiBOk() (*float32, bool) {\n\tif o == nil || IsNil(o.DiskGiB) {\n\t\treturn nil, false\n\t}\n\treturn o.DiskGiB, true\n}\n\n// HasDiskGiB returns a boolean if a field has been set.\nfunc (o *AdminCreateRunner) HasDiskGiB() bool {\n\tif o != nil && !IsNil(o.DiskGiB) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDiskGiB gets a reference to the given float32 and assigns it to the DiskGiB field.\nfunc (o *AdminCreateRunner) SetDiskGiB(v float32) {\n\to.DiskGiB = &v\n}\n\nfunc (o AdminCreateRunner) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o AdminCreateRunner) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"regionId\"] = o.RegionId\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"apiKey\"] = o.ApiKey\n\ttoSerialize[\"apiVersion\"] = o.ApiVersion\n\tif !IsNil(o.Domain) {\n\t\ttoSerialize[\"domain\"] = o.Domain\n\t}\n\tif !IsNil(o.ApiUrl) {\n\t\ttoSerialize[\"apiUrl\"] = o.ApiUrl\n\t}\n\tif !IsNil(o.ProxyUrl) {\n\t\ttoSerialize[\"proxyUrl\"] = o.ProxyUrl\n\t}\n\tif !IsNil(o.Cpu) {\n\t\ttoSerialize[\"cpu\"] = o.Cpu\n\t}\n\tif !IsNil(o.MemoryGiB) {\n\t\ttoSerialize[\"memoryGiB\"] = o.MemoryGiB\n\t}\n\tif !IsNil(o.DiskGiB) {\n\t\ttoSerialize[\"diskGiB\"] = o.DiskGiB\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *AdminCreateRunner) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"regionId\",\n\t\t\"name\",\n\t\t\"apiKey\",\n\t\t\"apiVersion\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarAdminCreateRunner := _AdminCreateRunner{}\n\n\terr = json.Unmarshal(data, &varAdminCreateRunner)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = AdminCreateRunner(varAdminCreateRunner)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"regionId\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"apiKey\")\n\t\tdelete(additionalProperties, \"apiVersion\")\n\t\tdelete(additionalProperties, \"domain\")\n\t\tdelete(additionalProperties, \"apiUrl\")\n\t\tdelete(additionalProperties, \"proxyUrl\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"memoryGiB\")\n\t\tdelete(additionalProperties, \"diskGiB\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableAdminCreateRunner struct {\n\tvalue *AdminCreateRunner\n\tisSet bool\n}\n\nfunc (v NullableAdminCreateRunner) Get() *AdminCreateRunner {\n\treturn v.value\n}\n\nfunc (v *NullableAdminCreateRunner) Set(val *AdminCreateRunner) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableAdminCreateRunner) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableAdminCreateRunner) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableAdminCreateRunner(val *AdminCreateRunner) *NullableAdminCreateRunner {\n\treturn &NullableAdminCreateRunner{value: val, isSet: true}\n}\n\nfunc (v NullableAdminCreateRunner) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableAdminCreateRunner) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_announcement.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Announcement type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Announcement{}\n\n// Announcement struct for Announcement\ntype Announcement struct {\n\t// The announcement text\n\tText string `json:\"text\"`\n\t// URL to learn more about the announcement\n\tLearnMoreUrl *string `json:\"learnMoreUrl,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Announcement Announcement\n\n// NewAnnouncement instantiates a new Announcement object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewAnnouncement(text string) *Announcement {\n\tthis := Announcement{}\n\tthis.Text = text\n\treturn &this\n}\n\n// NewAnnouncementWithDefaults instantiates a new Announcement object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewAnnouncementWithDefaults() *Announcement {\n\tthis := Announcement{}\n\treturn &this\n}\n\n// GetText returns the Text field value\nfunc (o *Announcement) GetText() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Text\n}\n\n// GetTextOk returns a tuple with the Text field value\n// and a boolean to check if the value has been set.\nfunc (o *Announcement) GetTextOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Text, true\n}\n\n// SetText sets field value\nfunc (o *Announcement) SetText(v string) {\n\to.Text = v\n}\n\n// GetLearnMoreUrl returns the LearnMoreUrl field value if set, zero value otherwise.\nfunc (o *Announcement) GetLearnMoreUrl() string {\n\tif o == nil || IsNil(o.LearnMoreUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.LearnMoreUrl\n}\n\n// GetLearnMoreUrlOk returns a tuple with the LearnMoreUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Announcement) GetLearnMoreUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.LearnMoreUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.LearnMoreUrl, true\n}\n\n// HasLearnMoreUrl returns a boolean if a field has been set.\nfunc (o *Announcement) HasLearnMoreUrl() bool {\n\tif o != nil && !IsNil(o.LearnMoreUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetLearnMoreUrl gets a reference to the given string and assigns it to the LearnMoreUrl field.\nfunc (o *Announcement) SetLearnMoreUrl(v string) {\n\to.LearnMoreUrl = &v\n}\n\nfunc (o Announcement) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Announcement) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"text\"] = o.Text\n\tif !IsNil(o.LearnMoreUrl) {\n\t\ttoSerialize[\"learnMoreUrl\"] = o.LearnMoreUrl\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Announcement) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"text\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarAnnouncement := _Announcement{}\n\n\terr = json.Unmarshal(data, &varAnnouncement)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Announcement(varAnnouncement)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"text\")\n\t\tdelete(additionalProperties, \"learnMoreUrl\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableAnnouncement struct {\n\tvalue *Announcement\n\tisSet bool\n}\n\nfunc (v NullableAnnouncement) Get() *Announcement {\n\treturn v.value\n}\n\nfunc (v *NullableAnnouncement) Set(val *Announcement) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableAnnouncement) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableAnnouncement) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableAnnouncement(val *Announcement) *NullableAnnouncement {\n\treturn &NullableAnnouncement{value: val, isSet: true}\n}\n\nfunc (v NullableAnnouncement) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableAnnouncement) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_api_key_list.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the ApiKeyList type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ApiKeyList{}\n\n// ApiKeyList struct for ApiKeyList\ntype ApiKeyList struct {\n\t// The name of the API key\n\tName string `json:\"name\"`\n\t// The masked API key value\n\tValue string `json:\"value\"`\n\t// When the API key was created\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// The list of organization resource permissions assigned to the API key\n\tPermissions []string `json:\"permissions\"`\n\t// When the API key was last used\n\tLastUsedAt NullableTime `json:\"lastUsedAt\"`\n\t// When the API key expires\n\tExpiresAt NullableTime `json:\"expiresAt\"`\n\t// The user ID of the user who created the API key\n\tUserId string `json:\"userId\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ApiKeyList ApiKeyList\n\n// NewApiKeyList instantiates a new ApiKeyList object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewApiKeyList(name string, value string, createdAt time.Time, permissions []string, lastUsedAt NullableTime, expiresAt NullableTime, userId string) *ApiKeyList {\n\tthis := ApiKeyList{}\n\tthis.Name = name\n\tthis.Value = value\n\tthis.CreatedAt = createdAt\n\tthis.Permissions = permissions\n\tthis.LastUsedAt = lastUsedAt\n\tthis.ExpiresAt = expiresAt\n\tthis.UserId = userId\n\treturn &this\n}\n\n// NewApiKeyListWithDefaults instantiates a new ApiKeyList object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewApiKeyListWithDefaults() *ApiKeyList {\n\tthis := ApiKeyList{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *ApiKeyList) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyList) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *ApiKeyList) SetName(v string) {\n\to.Name = v\n}\n\n// GetValue returns the Value field value\nfunc (o *ApiKeyList) GetValue() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Value\n}\n\n// GetValueOk returns a tuple with the Value field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyList) GetValueOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Value, true\n}\n\n// SetValue sets field value\nfunc (o *ApiKeyList) SetValue(v string) {\n\to.Value = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *ApiKeyList) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyList) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *ApiKeyList) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetPermissions returns the Permissions field value\nfunc (o *ApiKeyList) GetPermissions() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Permissions\n}\n\n// GetPermissionsOk returns a tuple with the Permissions field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyList) GetPermissionsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Permissions, true\n}\n\n// SetPermissions sets field value\nfunc (o *ApiKeyList) SetPermissions(v []string) {\n\to.Permissions = v\n}\n\n// GetLastUsedAt returns the LastUsedAt field value\n// If the value is explicit nil, the zero value for time.Time will be returned\nfunc (o *ApiKeyList) GetLastUsedAt() time.Time {\n\tif o == nil || o.LastUsedAt.Get() == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn *o.LastUsedAt.Get()\n}\n\n// GetLastUsedAtOk returns a tuple with the LastUsedAt field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *ApiKeyList) GetLastUsedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.LastUsedAt.Get(), o.LastUsedAt.IsSet()\n}\n\n// SetLastUsedAt sets field value\nfunc (o *ApiKeyList) SetLastUsedAt(v time.Time) {\n\to.LastUsedAt.Set(&v)\n}\n\n// GetExpiresAt returns the ExpiresAt field value\n// If the value is explicit nil, the zero value for time.Time will be returned\nfunc (o *ApiKeyList) GetExpiresAt() time.Time {\n\tif o == nil || o.ExpiresAt.Get() == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn *o.ExpiresAt.Get()\n}\n\n// GetExpiresAtOk returns a tuple with the ExpiresAt field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *ApiKeyList) GetExpiresAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ExpiresAt.Get(), o.ExpiresAt.IsSet()\n}\n\n// SetExpiresAt sets field value\nfunc (o *ApiKeyList) SetExpiresAt(v time.Time) {\n\to.ExpiresAt.Set(&v)\n}\n\n// GetUserId returns the UserId field value\nfunc (o *ApiKeyList) GetUserId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.UserId\n}\n\n// GetUserIdOk returns a tuple with the UserId field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyList) GetUserIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UserId, true\n}\n\n// SetUserId sets field value\nfunc (o *ApiKeyList) SetUserId(v string) {\n\to.UserId = v\n}\n\nfunc (o ApiKeyList) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ApiKeyList) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"value\"] = o.Value\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"permissions\"] = o.Permissions\n\ttoSerialize[\"lastUsedAt\"] = o.LastUsedAt.Get()\n\ttoSerialize[\"expiresAt\"] = o.ExpiresAt.Get()\n\ttoSerialize[\"userId\"] = o.UserId\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ApiKeyList) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"value\",\n\t\t\"createdAt\",\n\t\t\"permissions\",\n\t\t\"lastUsedAt\",\n\t\t\"expiresAt\",\n\t\t\"userId\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarApiKeyList := _ApiKeyList{}\n\n\terr = json.Unmarshal(data, &varApiKeyList)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ApiKeyList(varApiKeyList)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"value\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"permissions\")\n\t\tdelete(additionalProperties, \"lastUsedAt\")\n\t\tdelete(additionalProperties, \"expiresAt\")\n\t\tdelete(additionalProperties, \"userId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableApiKeyList struct {\n\tvalue *ApiKeyList\n\tisSet bool\n}\n\nfunc (v NullableApiKeyList) Get() *ApiKeyList {\n\treturn v.value\n}\n\nfunc (v *NullableApiKeyList) Set(val *ApiKeyList) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableApiKeyList) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableApiKeyList) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableApiKeyList(val *ApiKeyList) *NullableApiKeyList {\n\treturn &NullableApiKeyList{value: val, isSet: true}\n}\n\nfunc (v NullableApiKeyList) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableApiKeyList) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_api_key_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the ApiKeyResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ApiKeyResponse{}\n\n// ApiKeyResponse struct for ApiKeyResponse\ntype ApiKeyResponse struct {\n\t// The name of the API key\n\tName string `json:\"name\"`\n\t// The API key value\n\tValue string `json:\"value\"`\n\t// When the API key was created\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// The list of organization resource permissions assigned to the API key\n\tPermissions []string `json:\"permissions\"`\n\t// When the API key expires\n\tExpiresAt NullableTime `json:\"expiresAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ApiKeyResponse ApiKeyResponse\n\n// NewApiKeyResponse instantiates a new ApiKeyResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewApiKeyResponse(name string, value string, createdAt time.Time, permissions []string, expiresAt NullableTime) *ApiKeyResponse {\n\tthis := ApiKeyResponse{}\n\tthis.Name = name\n\tthis.Value = value\n\tthis.CreatedAt = createdAt\n\tthis.Permissions = permissions\n\tthis.ExpiresAt = expiresAt\n\treturn &this\n}\n\n// NewApiKeyResponseWithDefaults instantiates a new ApiKeyResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewApiKeyResponseWithDefaults() *ApiKeyResponse {\n\tthis := ApiKeyResponse{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *ApiKeyResponse) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyResponse) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *ApiKeyResponse) SetName(v string) {\n\to.Name = v\n}\n\n// GetValue returns the Value field value\nfunc (o *ApiKeyResponse) GetValue() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Value\n}\n\n// GetValueOk returns a tuple with the Value field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyResponse) GetValueOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Value, true\n}\n\n// SetValue sets field value\nfunc (o *ApiKeyResponse) SetValue(v string) {\n\to.Value = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *ApiKeyResponse) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyResponse) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *ApiKeyResponse) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetPermissions returns the Permissions field value\nfunc (o *ApiKeyResponse) GetPermissions() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Permissions\n}\n\n// GetPermissionsOk returns a tuple with the Permissions field value\n// and a boolean to check if the value has been set.\nfunc (o *ApiKeyResponse) GetPermissionsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Permissions, true\n}\n\n// SetPermissions sets field value\nfunc (o *ApiKeyResponse) SetPermissions(v []string) {\n\to.Permissions = v\n}\n\n// GetExpiresAt returns the ExpiresAt field value\n// If the value is explicit nil, the zero value for time.Time will be returned\nfunc (o *ApiKeyResponse) GetExpiresAt() time.Time {\n\tif o == nil || o.ExpiresAt.Get() == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn *o.ExpiresAt.Get()\n}\n\n// GetExpiresAtOk returns a tuple with the ExpiresAt field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *ApiKeyResponse) GetExpiresAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ExpiresAt.Get(), o.ExpiresAt.IsSet()\n}\n\n// SetExpiresAt sets field value\nfunc (o *ApiKeyResponse) SetExpiresAt(v time.Time) {\n\to.ExpiresAt.Set(&v)\n}\n\nfunc (o ApiKeyResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ApiKeyResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"value\"] = o.Value\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"permissions\"] = o.Permissions\n\ttoSerialize[\"expiresAt\"] = o.ExpiresAt.Get()\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ApiKeyResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"value\",\n\t\t\"createdAt\",\n\t\t\"permissions\",\n\t\t\"expiresAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarApiKeyResponse := _ApiKeyResponse{}\n\n\terr = json.Unmarshal(data, &varApiKeyResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ApiKeyResponse(varApiKeyResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"value\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"permissions\")\n\t\tdelete(additionalProperties, \"expiresAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableApiKeyResponse struct {\n\tvalue *ApiKeyResponse\n\tisSet bool\n}\n\nfunc (v NullableApiKeyResponse) Get() *ApiKeyResponse {\n\treturn v.value\n}\n\nfunc (v *NullableApiKeyResponse) Set(val *ApiKeyResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableApiKeyResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableApiKeyResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableApiKeyResponse(val *ApiKeyResponse) *NullableApiKeyResponse {\n\treturn &NullableApiKeyResponse{value: val, isSet: true}\n}\n\nfunc (v NullableApiKeyResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableApiKeyResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_audit_log.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the AuditLog type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &AuditLog{}\n\n// AuditLog struct for AuditLog\ntype AuditLog struct {\n\tId string `json:\"id\"`\n\tActorId string `json:\"actorId\"`\n\tActorEmail string `json:\"actorEmail\"`\n\tOrganizationId *string `json:\"organizationId,omitempty\"`\n\tAction string `json:\"action\"`\n\tTargetType *string `json:\"targetType,omitempty\"`\n\tTargetId *string `json:\"targetId,omitempty\"`\n\tStatusCode *float32 `json:\"statusCode,omitempty\"`\n\tErrorMessage *string `json:\"errorMessage,omitempty\"`\n\tIpAddress *string `json:\"ipAddress,omitempty\"`\n\tUserAgent *string `json:\"userAgent,omitempty\"`\n\tSource *string `json:\"source,omitempty\"`\n\tMetadata map[string]interface{} `json:\"metadata,omitempty\"`\n\tCreatedAt time.Time `json:\"createdAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _AuditLog AuditLog\n\n// NewAuditLog instantiates a new AuditLog object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewAuditLog(id string, actorId string, actorEmail string, action string, createdAt time.Time) *AuditLog {\n\tthis := AuditLog{}\n\tthis.Id = id\n\tthis.ActorId = actorId\n\tthis.ActorEmail = actorEmail\n\tthis.Action = action\n\tthis.CreatedAt = createdAt\n\treturn &this\n}\n\n// NewAuditLogWithDefaults instantiates a new AuditLog object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewAuditLogWithDefaults() *AuditLog {\n\tthis := AuditLog{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *AuditLog) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *AuditLog) SetId(v string) {\n\to.Id = v\n}\n\n// GetActorId returns the ActorId field value\nfunc (o *AuditLog) GetActorId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ActorId\n}\n\n// GetActorIdOk returns a tuple with the ActorId field value\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetActorIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ActorId, true\n}\n\n// SetActorId sets field value\nfunc (o *AuditLog) SetActorId(v string) {\n\to.ActorId = v\n}\n\n// GetActorEmail returns the ActorEmail field value\nfunc (o *AuditLog) GetActorEmail() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ActorEmail\n}\n\n// GetActorEmailOk returns a tuple with the ActorEmail field value\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetActorEmailOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ActorEmail, true\n}\n\n// SetActorEmail sets field value\nfunc (o *AuditLog) SetActorEmail(v string) {\n\to.ActorEmail = v\n}\n\n// GetOrganizationId returns the OrganizationId field value if set, zero value otherwise.\nfunc (o *AuditLog) GetOrganizationId() string {\n\tif o == nil || IsNil(o.OrganizationId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.OrganizationId) {\n\t\treturn nil, false\n\t}\n\treturn o.OrganizationId, true\n}\n\n// HasOrganizationId returns a boolean if a field has been set.\nfunc (o *AuditLog) HasOrganizationId() bool {\n\tif o != nil && !IsNil(o.OrganizationId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetOrganizationId gets a reference to the given string and assigns it to the OrganizationId field.\nfunc (o *AuditLog) SetOrganizationId(v string) {\n\to.OrganizationId = &v\n}\n\n// GetAction returns the Action field value\nfunc (o *AuditLog) GetAction() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Action\n}\n\n// GetActionOk returns a tuple with the Action field value\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetActionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Action, true\n}\n\n// SetAction sets field value\nfunc (o *AuditLog) SetAction(v string) {\n\to.Action = v\n}\n\n// GetTargetType returns the TargetType field value if set, zero value otherwise.\nfunc (o *AuditLog) GetTargetType() string {\n\tif o == nil || IsNil(o.TargetType) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.TargetType\n}\n\n// GetTargetTypeOk returns a tuple with the TargetType field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetTargetTypeOk() (*string, bool) {\n\tif o == nil || IsNil(o.TargetType) {\n\t\treturn nil, false\n\t}\n\treturn o.TargetType, true\n}\n\n// HasTargetType returns a boolean if a field has been set.\nfunc (o *AuditLog) HasTargetType() bool {\n\tif o != nil && !IsNil(o.TargetType) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTargetType gets a reference to the given string and assigns it to the TargetType field.\nfunc (o *AuditLog) SetTargetType(v string) {\n\to.TargetType = &v\n}\n\n// GetTargetId returns the TargetId field value if set, zero value otherwise.\nfunc (o *AuditLog) GetTargetId() string {\n\tif o == nil || IsNil(o.TargetId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.TargetId\n}\n\n// GetTargetIdOk returns a tuple with the TargetId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetTargetIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.TargetId) {\n\t\treturn nil, false\n\t}\n\treturn o.TargetId, true\n}\n\n// HasTargetId returns a boolean if a field has been set.\nfunc (o *AuditLog) HasTargetId() bool {\n\tif o != nil && !IsNil(o.TargetId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTargetId gets a reference to the given string and assigns it to the TargetId field.\nfunc (o *AuditLog) SetTargetId(v string) {\n\to.TargetId = &v\n}\n\n// GetStatusCode returns the StatusCode field value if set, zero value otherwise.\nfunc (o *AuditLog) GetStatusCode() float32 {\n\tif o == nil || IsNil(o.StatusCode) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.StatusCode\n}\n\n// GetStatusCodeOk returns a tuple with the StatusCode field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetStatusCodeOk() (*float32, bool) {\n\tif o == nil || IsNil(o.StatusCode) {\n\t\treturn nil, false\n\t}\n\treturn o.StatusCode, true\n}\n\n// HasStatusCode returns a boolean if a field has been set.\nfunc (o *AuditLog) HasStatusCode() bool {\n\tif o != nil && !IsNil(o.StatusCode) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetStatusCode gets a reference to the given float32 and assigns it to the StatusCode field.\nfunc (o *AuditLog) SetStatusCode(v float32) {\n\to.StatusCode = &v\n}\n\n// GetErrorMessage returns the ErrorMessage field value if set, zero value otherwise.\nfunc (o *AuditLog) GetErrorMessage() string {\n\tif o == nil || IsNil(o.ErrorMessage) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ErrorMessage\n}\n\n// GetErrorMessageOk returns a tuple with the ErrorMessage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetErrorMessageOk() (*string, bool) {\n\tif o == nil || IsNil(o.ErrorMessage) {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorMessage, true\n}\n\n// HasErrorMessage returns a boolean if a field has been set.\nfunc (o *AuditLog) HasErrorMessage() bool {\n\tif o != nil && !IsNil(o.ErrorMessage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetErrorMessage gets a reference to the given string and assigns it to the ErrorMessage field.\nfunc (o *AuditLog) SetErrorMessage(v string) {\n\to.ErrorMessage = &v\n}\n\n// GetIpAddress returns the IpAddress field value if set, zero value otherwise.\nfunc (o *AuditLog) GetIpAddress() string {\n\tif o == nil || IsNil(o.IpAddress) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.IpAddress\n}\n\n// GetIpAddressOk returns a tuple with the IpAddress field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetIpAddressOk() (*string, bool) {\n\tif o == nil || IsNil(o.IpAddress) {\n\t\treturn nil, false\n\t}\n\treturn o.IpAddress, true\n}\n\n// HasIpAddress returns a boolean if a field has been set.\nfunc (o *AuditLog) HasIpAddress() bool {\n\tif o != nil && !IsNil(o.IpAddress) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetIpAddress gets a reference to the given string and assigns it to the IpAddress field.\nfunc (o *AuditLog) SetIpAddress(v string) {\n\to.IpAddress = &v\n}\n\n// GetUserAgent returns the UserAgent field value if set, zero value otherwise.\nfunc (o *AuditLog) GetUserAgent() string {\n\tif o == nil || IsNil(o.UserAgent) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.UserAgent\n}\n\n// GetUserAgentOk returns a tuple with the UserAgent field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetUserAgentOk() (*string, bool) {\n\tif o == nil || IsNil(o.UserAgent) {\n\t\treturn nil, false\n\t}\n\treturn o.UserAgent, true\n}\n\n// HasUserAgent returns a boolean if a field has been set.\nfunc (o *AuditLog) HasUserAgent() bool {\n\tif o != nil && !IsNil(o.UserAgent) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetUserAgent gets a reference to the given string and assigns it to the UserAgent field.\nfunc (o *AuditLog) SetUserAgent(v string) {\n\to.UserAgent = &v\n}\n\n// GetSource returns the Source field value if set, zero value otherwise.\nfunc (o *AuditLog) GetSource() string {\n\tif o == nil || IsNil(o.Source) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Source\n}\n\n// GetSourceOk returns a tuple with the Source field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetSourceOk() (*string, bool) {\n\tif o == nil || IsNil(o.Source) {\n\t\treturn nil, false\n\t}\n\treturn o.Source, true\n}\n\n// HasSource returns a boolean if a field has been set.\nfunc (o *AuditLog) HasSource() bool {\n\tif o != nil && !IsNil(o.Source) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSource gets a reference to the given string and assigns it to the Source field.\nfunc (o *AuditLog) SetSource(v string) {\n\to.Source = &v\n}\n\n// GetMetadata returns the Metadata field value if set, zero value otherwise.\nfunc (o *AuditLog) GetMetadata() map[string]interface{} {\n\tif o == nil || IsNil(o.Metadata) {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\treturn o.Metadata\n}\n\n// GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetMetadataOk() (map[string]interface{}, bool) {\n\tif o == nil || IsNil(o.Metadata) {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.Metadata, true\n}\n\n// HasMetadata returns a boolean if a field has been set.\nfunc (o *AuditLog) HasMetadata() bool {\n\tif o != nil && !IsNil(o.Metadata) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMetadata gets a reference to the given map[string]interface{} and assigns it to the Metadata field.\nfunc (o *AuditLog) SetMetadata(v map[string]interface{}) {\n\to.Metadata = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *AuditLog) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *AuditLog) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *AuditLog) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\nfunc (o AuditLog) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o AuditLog) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"actorId\"] = o.ActorId\n\ttoSerialize[\"actorEmail\"] = o.ActorEmail\n\tif !IsNil(o.OrganizationId) {\n\t\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\t}\n\ttoSerialize[\"action\"] = o.Action\n\tif !IsNil(o.TargetType) {\n\t\ttoSerialize[\"targetType\"] = o.TargetType\n\t}\n\tif !IsNil(o.TargetId) {\n\t\ttoSerialize[\"targetId\"] = o.TargetId\n\t}\n\tif !IsNil(o.StatusCode) {\n\t\ttoSerialize[\"statusCode\"] = o.StatusCode\n\t}\n\tif !IsNil(o.ErrorMessage) {\n\t\ttoSerialize[\"errorMessage\"] = o.ErrorMessage\n\t}\n\tif !IsNil(o.IpAddress) {\n\t\ttoSerialize[\"ipAddress\"] = o.IpAddress\n\t}\n\tif !IsNil(o.UserAgent) {\n\t\ttoSerialize[\"userAgent\"] = o.UserAgent\n\t}\n\tif !IsNil(o.Source) {\n\t\ttoSerialize[\"source\"] = o.Source\n\t}\n\tif !IsNil(o.Metadata) {\n\t\ttoSerialize[\"metadata\"] = o.Metadata\n\t}\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *AuditLog) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"actorId\",\n\t\t\"actorEmail\",\n\t\t\"action\",\n\t\t\"createdAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarAuditLog := _AuditLog{}\n\n\terr = json.Unmarshal(data, &varAuditLog)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = AuditLog(varAuditLog)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"actorId\")\n\t\tdelete(additionalProperties, \"actorEmail\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"action\")\n\t\tdelete(additionalProperties, \"targetType\")\n\t\tdelete(additionalProperties, \"targetId\")\n\t\tdelete(additionalProperties, \"statusCode\")\n\t\tdelete(additionalProperties, \"errorMessage\")\n\t\tdelete(additionalProperties, \"ipAddress\")\n\t\tdelete(additionalProperties, \"userAgent\")\n\t\tdelete(additionalProperties, \"source\")\n\t\tdelete(additionalProperties, \"metadata\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableAuditLog struct {\n\tvalue *AuditLog\n\tisSet bool\n}\n\nfunc (v NullableAuditLog) Get() *AuditLog {\n\treturn v.value\n}\n\nfunc (v *NullableAuditLog) Set(val *AuditLog) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableAuditLog) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableAuditLog) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableAuditLog(val *AuditLog) *NullableAuditLog {\n\treturn &NullableAuditLog{value: val, isSet: true}\n}\n\nfunc (v NullableAuditLog) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableAuditLog) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_build_info.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the BuildInfo type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &BuildInfo{}\n\n// BuildInfo struct for BuildInfo\ntype BuildInfo struct {\n\t// The Dockerfile content used for the build\n\tDockerfileContent *string `json:\"dockerfileContent,omitempty\"`\n\t// The context hashes used for the build\n\tContextHashes []string `json:\"contextHashes,omitempty\"`\n\t// The creation timestamp\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// The last update timestamp\n\tUpdatedAt time.Time `json:\"updatedAt\"`\n\t// The snapshot reference\n\tSnapshotRef string `json:\"snapshotRef\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _BuildInfo BuildInfo\n\n// NewBuildInfo instantiates a new BuildInfo object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewBuildInfo(createdAt time.Time, updatedAt time.Time, snapshotRef string) *BuildInfo {\n\tthis := BuildInfo{}\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\tthis.SnapshotRef = snapshotRef\n\treturn &this\n}\n\n// NewBuildInfoWithDefaults instantiates a new BuildInfo object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewBuildInfoWithDefaults() *BuildInfo {\n\tthis := BuildInfo{}\n\treturn &this\n}\n\n// GetDockerfileContent returns the DockerfileContent field value if set, zero value otherwise.\nfunc (o *BuildInfo) GetDockerfileContent() string {\n\tif o == nil || IsNil(o.DockerfileContent) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.DockerfileContent\n}\n\n// GetDockerfileContentOk returns a tuple with the DockerfileContent field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *BuildInfo) GetDockerfileContentOk() (*string, bool) {\n\tif o == nil || IsNil(o.DockerfileContent) {\n\t\treturn nil, false\n\t}\n\treturn o.DockerfileContent, true\n}\n\n// HasDockerfileContent returns a boolean if a field has been set.\nfunc (o *BuildInfo) HasDockerfileContent() bool {\n\tif o != nil && !IsNil(o.DockerfileContent) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDockerfileContent gets a reference to the given string and assigns it to the DockerfileContent field.\nfunc (o *BuildInfo) SetDockerfileContent(v string) {\n\to.DockerfileContent = &v\n}\n\n// GetContextHashes returns the ContextHashes field value if set, zero value otherwise.\nfunc (o *BuildInfo) GetContextHashes() []string {\n\tif o == nil || IsNil(o.ContextHashes) {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\treturn o.ContextHashes\n}\n\n// GetContextHashesOk returns a tuple with the ContextHashes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *BuildInfo) GetContextHashesOk() ([]string, bool) {\n\tif o == nil || IsNil(o.ContextHashes) {\n\t\treturn nil, false\n\t}\n\treturn o.ContextHashes, true\n}\n\n// HasContextHashes returns a boolean if a field has been set.\nfunc (o *BuildInfo) HasContextHashes() bool {\n\tif o != nil && !IsNil(o.ContextHashes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetContextHashes gets a reference to the given []string and assigns it to the ContextHashes field.\nfunc (o *BuildInfo) SetContextHashes(v []string) {\n\to.ContextHashes = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *BuildInfo) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *BuildInfo) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *BuildInfo) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *BuildInfo) GetUpdatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *BuildInfo) GetUpdatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *BuildInfo) SetUpdatedAt(v time.Time) {\n\to.UpdatedAt = v\n}\n\n// GetSnapshotRef returns the SnapshotRef field value\nfunc (o *BuildInfo) GetSnapshotRef() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SnapshotRef\n}\n\n// GetSnapshotRefOk returns a tuple with the SnapshotRef field value\n// and a boolean to check if the value has been set.\nfunc (o *BuildInfo) GetSnapshotRefOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SnapshotRef, true\n}\n\n// SetSnapshotRef sets field value\nfunc (o *BuildInfo) SetSnapshotRef(v string) {\n\to.SnapshotRef = v\n}\n\nfunc (o BuildInfo) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o BuildInfo) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.DockerfileContent) {\n\t\ttoSerialize[\"dockerfileContent\"] = o.DockerfileContent\n\t}\n\tif !IsNil(o.ContextHashes) {\n\t\ttoSerialize[\"contextHashes\"] = o.ContextHashes\n\t}\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\ttoSerialize[\"snapshotRef\"] = o.SnapshotRef\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *BuildInfo) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t\t\"snapshotRef\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarBuildInfo := _BuildInfo{}\n\n\terr = json.Unmarshal(data, &varBuildInfo)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = BuildInfo(varBuildInfo)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"dockerfileContent\")\n\t\tdelete(additionalProperties, \"contextHashes\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"snapshotRef\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableBuildInfo struct {\n\tvalue *BuildInfo\n\tisSet bool\n}\n\nfunc (v NullableBuildInfo) Get() *BuildInfo {\n\treturn v.value\n}\n\nfunc (v *NullableBuildInfo) Set(val *BuildInfo) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableBuildInfo) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableBuildInfo) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableBuildInfo(val *BuildInfo) *NullableBuildInfo {\n\treturn &NullableBuildInfo{value: val, isSet: true}\n}\n\nfunc (v NullableBuildInfo) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableBuildInfo) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_command.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Command type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Command{}\n\n// Command struct for Command\ntype Command struct {\n\t// The ID of the command\n\tId string `json:\"id\"`\n\t// The command that was executed\n\tCommand string `json:\"command\"`\n\t// The exit code of the command\n\tExitCode *float32 `json:\"exitCode,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Command Command\n\n// NewCommand instantiates a new Command object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCommand(id string, command string) *Command {\n\tthis := Command{}\n\tthis.Id = id\n\tthis.Command = command\n\treturn &this\n}\n\n// NewCommandWithDefaults instantiates a new Command object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCommandWithDefaults() *Command {\n\tthis := Command{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *Command) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *Command) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *Command) SetId(v string) {\n\to.Id = v\n}\n\n// GetCommand returns the Command field value\nfunc (o *Command) GetCommand() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Command\n}\n\n// GetCommandOk returns a tuple with the Command field value\n// and a boolean to check if the value has been set.\nfunc (o *Command) GetCommandOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Command, true\n}\n\n// SetCommand sets field value\nfunc (o *Command) SetCommand(v string) {\n\to.Command = v\n}\n\n// GetExitCode returns the ExitCode field value if set, zero value otherwise.\nfunc (o *Command) GetExitCode() float32 {\n\tif o == nil || IsNil(o.ExitCode) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.ExitCode\n}\n\n// GetExitCodeOk returns a tuple with the ExitCode field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Command) GetExitCodeOk() (*float32, bool) {\n\tif o == nil || IsNil(o.ExitCode) {\n\t\treturn nil, false\n\t}\n\treturn o.ExitCode, true\n}\n\n// HasExitCode returns a boolean if a field has been set.\nfunc (o *Command) HasExitCode() bool {\n\tif o != nil && !IsNil(o.ExitCode) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetExitCode gets a reference to the given float32 and assigns it to the ExitCode field.\nfunc (o *Command) SetExitCode(v float32) {\n\to.ExitCode = &v\n}\n\nfunc (o Command) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Command) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"command\"] = o.Command\n\tif !IsNil(o.ExitCode) {\n\t\ttoSerialize[\"exitCode\"] = o.ExitCode\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Command) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"command\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCommand := _Command{}\n\n\terr = json.Unmarshal(data, &varCommand)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Command(varCommand)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"command\")\n\t\tdelete(additionalProperties, \"exitCode\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCommand struct {\n\tvalue *Command\n\tisSet bool\n}\n\nfunc (v NullableCommand) Get() *Command {\n\treturn v.value\n}\n\nfunc (v *NullableCommand) Set(val *Command) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCommand) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCommand) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCommand(val *Command) *NullableCommand {\n\treturn &NullableCommand{value: val, isSet: true}\n}\n\nfunc (v NullableCommand) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCommand) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_completion_context.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CompletionContext type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CompletionContext{}\n\n// CompletionContext struct for CompletionContext\ntype CompletionContext struct {\n\tTriggerKind float32 `json:\"triggerKind\"`\n\tTriggerCharacter *string `json:\"triggerCharacter,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CompletionContext CompletionContext\n\n// NewCompletionContext instantiates a new CompletionContext object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCompletionContext(triggerKind float32) *CompletionContext {\n\tthis := CompletionContext{}\n\tthis.TriggerKind = triggerKind\n\treturn &this\n}\n\n// NewCompletionContextWithDefaults instantiates a new CompletionContext object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCompletionContextWithDefaults() *CompletionContext {\n\tthis := CompletionContext{}\n\treturn &this\n}\n\n// GetTriggerKind returns the TriggerKind field value\nfunc (o *CompletionContext) GetTriggerKind() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TriggerKind\n}\n\n// GetTriggerKindOk returns a tuple with the TriggerKind field value\n// and a boolean to check if the value has been set.\nfunc (o *CompletionContext) GetTriggerKindOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TriggerKind, true\n}\n\n// SetTriggerKind sets field value\nfunc (o *CompletionContext) SetTriggerKind(v float32) {\n\to.TriggerKind = v\n}\n\n// GetTriggerCharacter returns the TriggerCharacter field value if set, zero value otherwise.\nfunc (o *CompletionContext) GetTriggerCharacter() string {\n\tif o == nil || IsNil(o.TriggerCharacter) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.TriggerCharacter\n}\n\n// GetTriggerCharacterOk returns a tuple with the TriggerCharacter field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompletionContext) GetTriggerCharacterOk() (*string, bool) {\n\tif o == nil || IsNil(o.TriggerCharacter) {\n\t\treturn nil, false\n\t}\n\treturn o.TriggerCharacter, true\n}\n\n// HasTriggerCharacter returns a boolean if a field has been set.\nfunc (o *CompletionContext) HasTriggerCharacter() bool {\n\tif o != nil && !IsNil(o.TriggerCharacter) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTriggerCharacter gets a reference to the given string and assigns it to the TriggerCharacter field.\nfunc (o *CompletionContext) SetTriggerCharacter(v string) {\n\to.TriggerCharacter = &v\n}\n\nfunc (o CompletionContext) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CompletionContext) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"triggerKind\"] = o.TriggerKind\n\tif !IsNil(o.TriggerCharacter) {\n\t\ttoSerialize[\"triggerCharacter\"] = o.TriggerCharacter\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CompletionContext) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"triggerKind\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCompletionContext := _CompletionContext{}\n\n\terr = json.Unmarshal(data, &varCompletionContext)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CompletionContext(varCompletionContext)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"triggerKind\")\n\t\tdelete(additionalProperties, \"triggerCharacter\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCompletionContext struct {\n\tvalue *CompletionContext\n\tisSet bool\n}\n\nfunc (v NullableCompletionContext) Get() *CompletionContext {\n\treturn v.value\n}\n\nfunc (v *NullableCompletionContext) Set(val *CompletionContext) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCompletionContext) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCompletionContext) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCompletionContext(val *CompletionContext) *NullableCompletionContext {\n\treturn &NullableCompletionContext{value: val, isSet: true}\n}\n\nfunc (v NullableCompletionContext) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCompletionContext) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_completion_item.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CompletionItem type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CompletionItem{}\n\n// CompletionItem struct for CompletionItem\ntype CompletionItem struct {\n\tLabel string `json:\"label\"`\n\tKind *float32 `json:\"kind,omitempty\"`\n\tDetail *string `json:\"detail,omitempty\"`\n\tDocumentation map[string]interface{} `json:\"documentation,omitempty\"`\n\tSortText *string `json:\"sortText,omitempty\"`\n\tFilterText *string `json:\"filterText,omitempty\"`\n\tInsertText *string `json:\"insertText,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CompletionItem CompletionItem\n\n// NewCompletionItem instantiates a new CompletionItem object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCompletionItem(label string) *CompletionItem {\n\tthis := CompletionItem{}\n\tthis.Label = label\n\treturn &this\n}\n\n// NewCompletionItemWithDefaults instantiates a new CompletionItem object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCompletionItemWithDefaults() *CompletionItem {\n\tthis := CompletionItem{}\n\treturn &this\n}\n\n// GetLabel returns the Label field value\nfunc (o *CompletionItem) GetLabel() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Label\n}\n\n// GetLabelOk returns a tuple with the Label field value\n// and a boolean to check if the value has been set.\nfunc (o *CompletionItem) GetLabelOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Label, true\n}\n\n// SetLabel sets field value\nfunc (o *CompletionItem) SetLabel(v string) {\n\to.Label = v\n}\n\n// GetKind returns the Kind field value if set, zero value otherwise.\nfunc (o *CompletionItem) GetKind() float32 {\n\tif o == nil || IsNil(o.Kind) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Kind\n}\n\n// GetKindOk returns a tuple with the Kind field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompletionItem) GetKindOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Kind) {\n\t\treturn nil, false\n\t}\n\treturn o.Kind, true\n}\n\n// HasKind returns a boolean if a field has been set.\nfunc (o *CompletionItem) HasKind() bool {\n\tif o != nil && !IsNil(o.Kind) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetKind gets a reference to the given float32 and assigns it to the Kind field.\nfunc (o *CompletionItem) SetKind(v float32) {\n\to.Kind = &v\n}\n\n// GetDetail returns the Detail field value if set, zero value otherwise.\nfunc (o *CompletionItem) GetDetail() string {\n\tif o == nil || IsNil(o.Detail) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Detail\n}\n\n// GetDetailOk returns a tuple with the Detail field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompletionItem) GetDetailOk() (*string, bool) {\n\tif o == nil || IsNil(o.Detail) {\n\t\treturn nil, false\n\t}\n\treturn o.Detail, true\n}\n\n// HasDetail returns a boolean if a field has been set.\nfunc (o *CompletionItem) HasDetail() bool {\n\tif o != nil && !IsNil(o.Detail) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDetail gets a reference to the given string and assigns it to the Detail field.\nfunc (o *CompletionItem) SetDetail(v string) {\n\to.Detail = &v\n}\n\n// GetDocumentation returns the Documentation field value if set, zero value otherwise.\nfunc (o *CompletionItem) GetDocumentation() map[string]interface{} {\n\tif o == nil || IsNil(o.Documentation) {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\treturn o.Documentation\n}\n\n// GetDocumentationOk returns a tuple with the Documentation field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompletionItem) GetDocumentationOk() (map[string]interface{}, bool) {\n\tif o == nil || IsNil(o.Documentation) {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.Documentation, true\n}\n\n// HasDocumentation returns a boolean if a field has been set.\nfunc (o *CompletionItem) HasDocumentation() bool {\n\tif o != nil && !IsNil(o.Documentation) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDocumentation gets a reference to the given map[string]interface{} and assigns it to the Documentation field.\nfunc (o *CompletionItem) SetDocumentation(v map[string]interface{}) {\n\to.Documentation = v\n}\n\n// GetSortText returns the SortText field value if set, zero value otherwise.\nfunc (o *CompletionItem) GetSortText() string {\n\tif o == nil || IsNil(o.SortText) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SortText\n}\n\n// GetSortTextOk returns a tuple with the SortText field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompletionItem) GetSortTextOk() (*string, bool) {\n\tif o == nil || IsNil(o.SortText) {\n\t\treturn nil, false\n\t}\n\treturn o.SortText, true\n}\n\n// HasSortText returns a boolean if a field has been set.\nfunc (o *CompletionItem) HasSortText() bool {\n\tif o != nil && !IsNil(o.SortText) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSortText gets a reference to the given string and assigns it to the SortText field.\nfunc (o *CompletionItem) SetSortText(v string) {\n\to.SortText = &v\n}\n\n// GetFilterText returns the FilterText field value if set, zero value otherwise.\nfunc (o *CompletionItem) GetFilterText() string {\n\tif o == nil || IsNil(o.FilterText) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.FilterText\n}\n\n// GetFilterTextOk returns a tuple with the FilterText field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompletionItem) GetFilterTextOk() (*string, bool) {\n\tif o == nil || IsNil(o.FilterText) {\n\t\treturn nil, false\n\t}\n\treturn o.FilterText, true\n}\n\n// HasFilterText returns a boolean if a field has been set.\nfunc (o *CompletionItem) HasFilterText() bool {\n\tif o != nil && !IsNil(o.FilterText) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetFilterText gets a reference to the given string and assigns it to the FilterText field.\nfunc (o *CompletionItem) SetFilterText(v string) {\n\to.FilterText = &v\n}\n\n// GetInsertText returns the InsertText field value if set, zero value otherwise.\nfunc (o *CompletionItem) GetInsertText() string {\n\tif o == nil || IsNil(o.InsertText) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.InsertText\n}\n\n// GetInsertTextOk returns a tuple with the InsertText field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompletionItem) GetInsertTextOk() (*string, bool) {\n\tif o == nil || IsNil(o.InsertText) {\n\t\treturn nil, false\n\t}\n\treturn o.InsertText, true\n}\n\n// HasInsertText returns a boolean if a field has been set.\nfunc (o *CompletionItem) HasInsertText() bool {\n\tif o != nil && !IsNil(o.InsertText) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetInsertText gets a reference to the given string and assigns it to the InsertText field.\nfunc (o *CompletionItem) SetInsertText(v string) {\n\to.InsertText = &v\n}\n\nfunc (o CompletionItem) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CompletionItem) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"label\"] = o.Label\n\tif !IsNil(o.Kind) {\n\t\ttoSerialize[\"kind\"] = o.Kind\n\t}\n\tif !IsNil(o.Detail) {\n\t\ttoSerialize[\"detail\"] = o.Detail\n\t}\n\tif !IsNil(o.Documentation) {\n\t\ttoSerialize[\"documentation\"] = o.Documentation\n\t}\n\tif !IsNil(o.SortText) {\n\t\ttoSerialize[\"sortText\"] = o.SortText\n\t}\n\tif !IsNil(o.FilterText) {\n\t\ttoSerialize[\"filterText\"] = o.FilterText\n\t}\n\tif !IsNil(o.InsertText) {\n\t\ttoSerialize[\"insertText\"] = o.InsertText\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CompletionItem) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"label\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCompletionItem := _CompletionItem{}\n\n\terr = json.Unmarshal(data, &varCompletionItem)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CompletionItem(varCompletionItem)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"label\")\n\t\tdelete(additionalProperties, \"kind\")\n\t\tdelete(additionalProperties, \"detail\")\n\t\tdelete(additionalProperties, \"documentation\")\n\t\tdelete(additionalProperties, \"sortText\")\n\t\tdelete(additionalProperties, \"filterText\")\n\t\tdelete(additionalProperties, \"insertText\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCompletionItem struct {\n\tvalue *CompletionItem\n\tisSet bool\n}\n\nfunc (v NullableCompletionItem) Get() *CompletionItem {\n\treturn v.value\n}\n\nfunc (v *NullableCompletionItem) Set(val *CompletionItem) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCompletionItem) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCompletionItem) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCompletionItem(val *CompletionItem) *NullableCompletionItem {\n\treturn &NullableCompletionItem{value: val, isSet: true}\n}\n\nfunc (v NullableCompletionItem) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCompletionItem) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_completion_list.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CompletionList type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CompletionList{}\n\n// CompletionList struct for CompletionList\ntype CompletionList struct {\n\tIsIncomplete bool `json:\"isIncomplete\"`\n\tItems []CompletionItem `json:\"items\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CompletionList CompletionList\n\n// NewCompletionList instantiates a new CompletionList object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCompletionList(isIncomplete bool, items []CompletionItem) *CompletionList {\n\tthis := CompletionList{}\n\tthis.IsIncomplete = isIncomplete\n\tthis.Items = items\n\treturn &this\n}\n\n// NewCompletionListWithDefaults instantiates a new CompletionList object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCompletionListWithDefaults() *CompletionList {\n\tthis := CompletionList{}\n\treturn &this\n}\n\n// GetIsIncomplete returns the IsIncomplete field value\nfunc (o *CompletionList) GetIsIncomplete() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.IsIncomplete\n}\n\n// GetIsIncompleteOk returns a tuple with the IsIncomplete field value\n// and a boolean to check if the value has been set.\nfunc (o *CompletionList) GetIsIncompleteOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.IsIncomplete, true\n}\n\n// SetIsIncomplete sets field value\nfunc (o *CompletionList) SetIsIncomplete(v bool) {\n\to.IsIncomplete = v\n}\n\n// GetItems returns the Items field value\nfunc (o *CompletionList) GetItems() []CompletionItem {\n\tif o == nil {\n\t\tvar ret []CompletionItem\n\t\treturn ret\n\t}\n\n\treturn o.Items\n}\n\n// GetItemsOk returns a tuple with the Items field value\n// and a boolean to check if the value has been set.\nfunc (o *CompletionList) GetItemsOk() ([]CompletionItem, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Items, true\n}\n\n// SetItems sets field value\nfunc (o *CompletionList) SetItems(v []CompletionItem) {\n\to.Items = v\n}\n\nfunc (o CompletionList) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CompletionList) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"isIncomplete\"] = o.IsIncomplete\n\ttoSerialize[\"items\"] = o.Items\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CompletionList) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"isIncomplete\",\n\t\t\"items\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCompletionList := _CompletionList{}\n\n\terr = json.Unmarshal(data, &varCompletionList)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CompletionList(varCompletionList)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"isIncomplete\")\n\t\tdelete(additionalProperties, \"items\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCompletionList struct {\n\tvalue *CompletionList\n\tisSet bool\n}\n\nfunc (v NullableCompletionList) Get() *CompletionList {\n\treturn v.value\n}\n\nfunc (v *NullableCompletionList) Set(val *CompletionList) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCompletionList) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCompletionList) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCompletionList(val *CompletionList) *NullableCompletionList {\n\treturn &NullableCompletionList{value: val, isSet: true}\n}\n\nfunc (v NullableCompletionList) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCompletionList) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_compressed_screenshot_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CompressedScreenshotResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CompressedScreenshotResponse{}\n\n// CompressedScreenshotResponse struct for CompressedScreenshotResponse\ntype CompressedScreenshotResponse struct {\n\t// Base64 encoded compressed screenshot image data\n\tScreenshot string `json:\"screenshot\"`\n\t// The current cursor position when the compressed screenshot was taken\n\tCursorPosition map[string]interface{} `json:\"cursorPosition,omitempty\"`\n\t// The size of the compressed screenshot data in bytes\n\tSizeBytes *float32 `json:\"sizeBytes,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CompressedScreenshotResponse CompressedScreenshotResponse\n\n// NewCompressedScreenshotResponse instantiates a new CompressedScreenshotResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCompressedScreenshotResponse(screenshot string) *CompressedScreenshotResponse {\n\tthis := CompressedScreenshotResponse{}\n\tthis.Screenshot = screenshot\n\treturn &this\n}\n\n// NewCompressedScreenshotResponseWithDefaults instantiates a new CompressedScreenshotResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCompressedScreenshotResponseWithDefaults() *CompressedScreenshotResponse {\n\tthis := CompressedScreenshotResponse{}\n\treturn &this\n}\n\n// GetScreenshot returns the Screenshot field value\nfunc (o *CompressedScreenshotResponse) GetScreenshot() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Screenshot\n}\n\n// GetScreenshotOk returns a tuple with the Screenshot field value\n// and a boolean to check if the value has been set.\nfunc (o *CompressedScreenshotResponse) GetScreenshotOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Screenshot, true\n}\n\n// SetScreenshot sets field value\nfunc (o *CompressedScreenshotResponse) SetScreenshot(v string) {\n\to.Screenshot = v\n}\n\n// GetCursorPosition returns the CursorPosition field value if set, zero value otherwise.\nfunc (o *CompressedScreenshotResponse) GetCursorPosition() map[string]interface{} {\n\tif o == nil || IsNil(o.CursorPosition) {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\treturn o.CursorPosition\n}\n\n// GetCursorPositionOk returns a tuple with the CursorPosition field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompressedScreenshotResponse) GetCursorPositionOk() (map[string]interface{}, bool) {\n\tif o == nil || IsNil(o.CursorPosition) {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.CursorPosition, true\n}\n\n// HasCursorPosition returns a boolean if a field has been set.\nfunc (o *CompressedScreenshotResponse) HasCursorPosition() bool {\n\tif o != nil && !IsNil(o.CursorPosition) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCursorPosition gets a reference to the given map[string]interface{} and assigns it to the CursorPosition field.\nfunc (o *CompressedScreenshotResponse) SetCursorPosition(v map[string]interface{}) {\n\to.CursorPosition = v\n}\n\n// GetSizeBytes returns the SizeBytes field value if set, zero value otherwise.\nfunc (o *CompressedScreenshotResponse) GetSizeBytes() float32 {\n\tif o == nil || IsNil(o.SizeBytes) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.SizeBytes\n}\n\n// GetSizeBytesOk returns a tuple with the SizeBytes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CompressedScreenshotResponse) GetSizeBytesOk() (*float32, bool) {\n\tif o == nil || IsNil(o.SizeBytes) {\n\t\treturn nil, false\n\t}\n\treturn o.SizeBytes, true\n}\n\n// HasSizeBytes returns a boolean if a field has been set.\nfunc (o *CompressedScreenshotResponse) HasSizeBytes() bool {\n\tif o != nil && !IsNil(o.SizeBytes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSizeBytes gets a reference to the given float32 and assigns it to the SizeBytes field.\nfunc (o *CompressedScreenshotResponse) SetSizeBytes(v float32) {\n\to.SizeBytes = &v\n}\n\nfunc (o CompressedScreenshotResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CompressedScreenshotResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"screenshot\"] = o.Screenshot\n\tif !IsNil(o.CursorPosition) {\n\t\ttoSerialize[\"cursorPosition\"] = o.CursorPosition\n\t}\n\tif !IsNil(o.SizeBytes) {\n\t\ttoSerialize[\"sizeBytes\"] = o.SizeBytes\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CompressedScreenshotResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"screenshot\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCompressedScreenshotResponse := _CompressedScreenshotResponse{}\n\n\terr = json.Unmarshal(data, &varCompressedScreenshotResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CompressedScreenshotResponse(varCompressedScreenshotResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"screenshot\")\n\t\tdelete(additionalProperties, \"cursorPosition\")\n\t\tdelete(additionalProperties, \"sizeBytes\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCompressedScreenshotResponse struct {\n\tvalue *CompressedScreenshotResponse\n\tisSet bool\n}\n\nfunc (v NullableCompressedScreenshotResponse) Get() *CompressedScreenshotResponse {\n\treturn v.value\n}\n\nfunc (v *NullableCompressedScreenshotResponse) Set(val *CompressedScreenshotResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCompressedScreenshotResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCompressedScreenshotResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCompressedScreenshotResponse(val *CompressedScreenshotResponse) *NullableCompressedScreenshotResponse {\n\treturn &NullableCompressedScreenshotResponse{value: val, isSet: true}\n}\n\nfunc (v NullableCompressedScreenshotResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCompressedScreenshotResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_computer_use_start_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ComputerUseStartResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ComputerUseStartResponse{}\n\n// ComputerUseStartResponse struct for ComputerUseStartResponse\ntype ComputerUseStartResponse struct {\n\t// A message indicating the result of starting computer use processes\n\tMessage string `json:\"message\"`\n\t// Status information about all VNC desktop processes after starting\n\tStatus map[string]interface{} `json:\"status\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ComputerUseStartResponse ComputerUseStartResponse\n\n// NewComputerUseStartResponse instantiates a new ComputerUseStartResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewComputerUseStartResponse(message string, status map[string]interface{}) *ComputerUseStartResponse {\n\tthis := ComputerUseStartResponse{}\n\tthis.Message = message\n\tthis.Status = status\n\treturn &this\n}\n\n// NewComputerUseStartResponseWithDefaults instantiates a new ComputerUseStartResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewComputerUseStartResponseWithDefaults() *ComputerUseStartResponse {\n\tthis := ComputerUseStartResponse{}\n\treturn &this\n}\n\n// GetMessage returns the Message field value\nfunc (o *ComputerUseStartResponse) GetMessage() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Message\n}\n\n// GetMessageOk returns a tuple with the Message field value\n// and a boolean to check if the value has been set.\nfunc (o *ComputerUseStartResponse) GetMessageOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Message, true\n}\n\n// SetMessage sets field value\nfunc (o *ComputerUseStartResponse) SetMessage(v string) {\n\to.Message = v\n}\n\n// GetStatus returns the Status field value\nfunc (o *ComputerUseStartResponse) GetStatus() map[string]interface{} {\n\tif o == nil {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\n\treturn o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value\n// and a boolean to check if the value has been set.\nfunc (o *ComputerUseStartResponse) GetStatusOk() (map[string]interface{}, bool) {\n\tif o == nil {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.Status, true\n}\n\n// SetStatus sets field value\nfunc (o *ComputerUseStartResponse) SetStatus(v map[string]interface{}) {\n\to.Status = v\n}\n\nfunc (o ComputerUseStartResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ComputerUseStartResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"message\"] = o.Message\n\ttoSerialize[\"status\"] = o.Status\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ComputerUseStartResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"message\",\n\t\t\"status\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarComputerUseStartResponse := _ComputerUseStartResponse{}\n\n\terr = json.Unmarshal(data, &varComputerUseStartResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ComputerUseStartResponse(varComputerUseStartResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"message\")\n\t\tdelete(additionalProperties, \"status\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableComputerUseStartResponse struct {\n\tvalue *ComputerUseStartResponse\n\tisSet bool\n}\n\nfunc (v NullableComputerUseStartResponse) Get() *ComputerUseStartResponse {\n\treturn v.value\n}\n\nfunc (v *NullableComputerUseStartResponse) Set(val *ComputerUseStartResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableComputerUseStartResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableComputerUseStartResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableComputerUseStartResponse(val *ComputerUseStartResponse) *NullableComputerUseStartResponse {\n\treturn &NullableComputerUseStartResponse{value: val, isSet: true}\n}\n\nfunc (v NullableComputerUseStartResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableComputerUseStartResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_computer_use_status_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ComputerUseStatusResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ComputerUseStatusResponse{}\n\n// ComputerUseStatusResponse struct for ComputerUseStatusResponse\ntype ComputerUseStatusResponse struct {\n\t// Status of computer use services (active, partial, inactive, error)\n\tStatus string `json:\"status\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ComputerUseStatusResponse ComputerUseStatusResponse\n\n// NewComputerUseStatusResponse instantiates a new ComputerUseStatusResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewComputerUseStatusResponse(status string) *ComputerUseStatusResponse {\n\tthis := ComputerUseStatusResponse{}\n\tthis.Status = status\n\treturn &this\n}\n\n// NewComputerUseStatusResponseWithDefaults instantiates a new ComputerUseStatusResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewComputerUseStatusResponseWithDefaults() *ComputerUseStatusResponse {\n\tthis := ComputerUseStatusResponse{}\n\treturn &this\n}\n\n// GetStatus returns the Status field value\nfunc (o *ComputerUseStatusResponse) GetStatus() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value\n// and a boolean to check if the value has been set.\nfunc (o *ComputerUseStatusResponse) GetStatusOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Status, true\n}\n\n// SetStatus sets field value\nfunc (o *ComputerUseStatusResponse) SetStatus(v string) {\n\to.Status = v\n}\n\nfunc (o ComputerUseStatusResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ComputerUseStatusResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"status\"] = o.Status\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ComputerUseStatusResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"status\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarComputerUseStatusResponse := _ComputerUseStatusResponse{}\n\n\terr = json.Unmarshal(data, &varComputerUseStatusResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ComputerUseStatusResponse(varComputerUseStatusResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"status\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableComputerUseStatusResponse struct {\n\tvalue *ComputerUseStatusResponse\n\tisSet bool\n}\n\nfunc (v NullableComputerUseStatusResponse) Get() *ComputerUseStatusResponse {\n\treturn v.value\n}\n\nfunc (v *NullableComputerUseStatusResponse) Set(val *ComputerUseStatusResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableComputerUseStatusResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableComputerUseStatusResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableComputerUseStatusResponse(val *ComputerUseStatusResponse) *NullableComputerUseStatusResponse {\n\treturn &NullableComputerUseStatusResponse{value: val, isSet: true}\n}\n\nfunc (v NullableComputerUseStatusResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableComputerUseStatusResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_computer_use_stop_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ComputerUseStopResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ComputerUseStopResponse{}\n\n// ComputerUseStopResponse struct for ComputerUseStopResponse\ntype ComputerUseStopResponse struct {\n\t// A message indicating the result of stopping computer use processes\n\tMessage string `json:\"message\"`\n\t// Status information about all VNC desktop processes after stopping\n\tStatus map[string]interface{} `json:\"status\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ComputerUseStopResponse ComputerUseStopResponse\n\n// NewComputerUseStopResponse instantiates a new ComputerUseStopResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewComputerUseStopResponse(message string, status map[string]interface{}) *ComputerUseStopResponse {\n\tthis := ComputerUseStopResponse{}\n\tthis.Message = message\n\tthis.Status = status\n\treturn &this\n}\n\n// NewComputerUseStopResponseWithDefaults instantiates a new ComputerUseStopResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewComputerUseStopResponseWithDefaults() *ComputerUseStopResponse {\n\tthis := ComputerUseStopResponse{}\n\treturn &this\n}\n\n// GetMessage returns the Message field value\nfunc (o *ComputerUseStopResponse) GetMessage() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Message\n}\n\n// GetMessageOk returns a tuple with the Message field value\n// and a boolean to check if the value has been set.\nfunc (o *ComputerUseStopResponse) GetMessageOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Message, true\n}\n\n// SetMessage sets field value\nfunc (o *ComputerUseStopResponse) SetMessage(v string) {\n\to.Message = v\n}\n\n// GetStatus returns the Status field value\nfunc (o *ComputerUseStopResponse) GetStatus() map[string]interface{} {\n\tif o == nil {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\n\treturn o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value\n// and a boolean to check if the value has been set.\nfunc (o *ComputerUseStopResponse) GetStatusOk() (map[string]interface{}, bool) {\n\tif o == nil {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.Status, true\n}\n\n// SetStatus sets field value\nfunc (o *ComputerUseStopResponse) SetStatus(v map[string]interface{}) {\n\to.Status = v\n}\n\nfunc (o ComputerUseStopResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ComputerUseStopResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"message\"] = o.Message\n\ttoSerialize[\"status\"] = o.Status\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ComputerUseStopResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"message\",\n\t\t\"status\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarComputerUseStopResponse := _ComputerUseStopResponse{}\n\n\terr = json.Unmarshal(data, &varComputerUseStopResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ComputerUseStopResponse(varComputerUseStopResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"message\")\n\t\tdelete(additionalProperties, \"status\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableComputerUseStopResponse struct {\n\tvalue *ComputerUseStopResponse\n\tisSet bool\n}\n\nfunc (v NullableComputerUseStopResponse) Get() *ComputerUseStopResponse {\n\treturn v.value\n}\n\nfunc (v *NullableComputerUseStopResponse) Set(val *ComputerUseStopResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableComputerUseStopResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableComputerUseStopResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableComputerUseStopResponse(val *ComputerUseStopResponse) *NullableComputerUseStopResponse {\n\treturn &NullableComputerUseStopResponse{value: val, isSet: true}\n}\n\nfunc (v NullableComputerUseStopResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableComputerUseStopResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_api_key.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the CreateApiKey type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateApiKey{}\n\n// CreateApiKey struct for CreateApiKey\ntype CreateApiKey struct {\n\t// The name of the API key\n\tName string `json:\"name\"`\n\t// The list of organization resource permissions explicitly assigned to the API key\n\tPermissions []string `json:\"permissions\"`\n\t// When the API key expires\n\tExpiresAt NullableTime `json:\"expiresAt,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateApiKey CreateApiKey\n\n// NewCreateApiKey instantiates a new CreateApiKey object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateApiKey(name string, permissions []string) *CreateApiKey {\n\tthis := CreateApiKey{}\n\tthis.Name = name\n\tthis.Permissions = permissions\n\treturn &this\n}\n\n// NewCreateApiKeyWithDefaults instantiates a new CreateApiKey object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateApiKeyWithDefaults() *CreateApiKey {\n\tthis := CreateApiKey{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *CreateApiKey) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateApiKey) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateApiKey) SetName(v string) {\n\to.Name = v\n}\n\n// GetPermissions returns the Permissions field value\nfunc (o *CreateApiKey) GetPermissions() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Permissions\n}\n\n// GetPermissionsOk returns a tuple with the Permissions field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateApiKey) GetPermissionsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Permissions, true\n}\n\n// SetPermissions sets field value\nfunc (o *CreateApiKey) SetPermissions(v []string) {\n\to.Permissions = v\n}\n\n// GetExpiresAt returns the ExpiresAt field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *CreateApiKey) GetExpiresAt() time.Time {\n\tif o == nil || IsNil(o.ExpiresAt.Get()) {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\treturn *o.ExpiresAt.Get()\n}\n\n// GetExpiresAtOk returns a tuple with the ExpiresAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *CreateApiKey) GetExpiresAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ExpiresAt.Get(), o.ExpiresAt.IsSet()\n}\n\n// HasExpiresAt returns a boolean if a field has been set.\nfunc (o *CreateApiKey) HasExpiresAt() bool {\n\tif o != nil && o.ExpiresAt.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetExpiresAt gets a reference to the given NullableTime and assigns it to the ExpiresAt field.\nfunc (o *CreateApiKey) SetExpiresAt(v time.Time) {\n\to.ExpiresAt.Set(&v)\n}\n// SetExpiresAtNil sets the value for ExpiresAt to be an explicit nil\nfunc (o *CreateApiKey) SetExpiresAtNil() {\n\to.ExpiresAt.Set(nil)\n}\n\n// UnsetExpiresAt ensures that no value is present for ExpiresAt, not even an explicit nil\nfunc (o *CreateApiKey) UnsetExpiresAt() {\n\to.ExpiresAt.Unset()\n}\n\nfunc (o CreateApiKey) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateApiKey) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"permissions\"] = o.Permissions\n\tif o.ExpiresAt.IsSet() {\n\t\ttoSerialize[\"expiresAt\"] = o.ExpiresAt.Get()\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateApiKey) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"permissions\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateApiKey := _CreateApiKey{}\n\n\terr = json.Unmarshal(data, &varCreateApiKey)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateApiKey(varCreateApiKey)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"permissions\")\n\t\tdelete(additionalProperties, \"expiresAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateApiKey struct {\n\tvalue *CreateApiKey\n\tisSet bool\n}\n\nfunc (v NullableCreateApiKey) Get() *CreateApiKey {\n\treturn v.value\n}\n\nfunc (v *NullableCreateApiKey) Set(val *CreateApiKey) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateApiKey) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateApiKey) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateApiKey(val *CreateApiKey) *NullableCreateApiKey {\n\treturn &NullableCreateApiKey{value: val, isSet: true}\n}\n\nfunc (v NullableCreateApiKey) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateApiKey) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_build_info.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateBuildInfo type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateBuildInfo{}\n\n// CreateBuildInfo struct for CreateBuildInfo\ntype CreateBuildInfo struct {\n\t// The Dockerfile content used for the build\n\tDockerfileContent string `json:\"dockerfileContent\"`\n\t// The context hashes used for the build\n\tContextHashes []string `json:\"contextHashes,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateBuildInfo CreateBuildInfo\n\n// NewCreateBuildInfo instantiates a new CreateBuildInfo object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateBuildInfo(dockerfileContent string) *CreateBuildInfo {\n\tthis := CreateBuildInfo{}\n\tthis.DockerfileContent = dockerfileContent\n\treturn &this\n}\n\n// NewCreateBuildInfoWithDefaults instantiates a new CreateBuildInfo object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateBuildInfoWithDefaults() *CreateBuildInfo {\n\tthis := CreateBuildInfo{}\n\treturn &this\n}\n\n// GetDockerfileContent returns the DockerfileContent field value\nfunc (o *CreateBuildInfo) GetDockerfileContent() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.DockerfileContent\n}\n\n// GetDockerfileContentOk returns a tuple with the DockerfileContent field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateBuildInfo) GetDockerfileContentOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DockerfileContent, true\n}\n\n// SetDockerfileContent sets field value\nfunc (o *CreateBuildInfo) SetDockerfileContent(v string) {\n\to.DockerfileContent = v\n}\n\n// GetContextHashes returns the ContextHashes field value if set, zero value otherwise.\nfunc (o *CreateBuildInfo) GetContextHashes() []string {\n\tif o == nil || IsNil(o.ContextHashes) {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\treturn o.ContextHashes\n}\n\n// GetContextHashesOk returns a tuple with the ContextHashes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateBuildInfo) GetContextHashesOk() ([]string, bool) {\n\tif o == nil || IsNil(o.ContextHashes) {\n\t\treturn nil, false\n\t}\n\treturn o.ContextHashes, true\n}\n\n// HasContextHashes returns a boolean if a field has been set.\nfunc (o *CreateBuildInfo) HasContextHashes() bool {\n\tif o != nil && !IsNil(o.ContextHashes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetContextHashes gets a reference to the given []string and assigns it to the ContextHashes field.\nfunc (o *CreateBuildInfo) SetContextHashes(v []string) {\n\to.ContextHashes = v\n}\n\nfunc (o CreateBuildInfo) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateBuildInfo) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"dockerfileContent\"] = o.DockerfileContent\n\tif !IsNil(o.ContextHashes) {\n\t\ttoSerialize[\"contextHashes\"] = o.ContextHashes\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateBuildInfo) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"dockerfileContent\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateBuildInfo := _CreateBuildInfo{}\n\n\terr = json.Unmarshal(data, &varCreateBuildInfo)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateBuildInfo(varCreateBuildInfo)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"dockerfileContent\")\n\t\tdelete(additionalProperties, \"contextHashes\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateBuildInfo struct {\n\tvalue *CreateBuildInfo\n\tisSet bool\n}\n\nfunc (v NullableCreateBuildInfo) Get() *CreateBuildInfo {\n\treturn v.value\n}\n\nfunc (v *NullableCreateBuildInfo) Set(val *CreateBuildInfo) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateBuildInfo) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateBuildInfo) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateBuildInfo(val *CreateBuildInfo) *NullableCreateBuildInfo {\n\treturn &NullableCreateBuildInfo{value: val, isSet: true}\n}\n\nfunc (v NullableCreateBuildInfo) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateBuildInfo) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_docker_registry.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateDockerRegistry type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateDockerRegistry{}\n\n// CreateDockerRegistry struct for CreateDockerRegistry\ntype CreateDockerRegistry struct {\n\t// Registry name\n\tName string `json:\"name\"`\n\t// Registry URL\n\tUrl string `json:\"url\"`\n\t// Registry username\n\tUsername string `json:\"username\"`\n\t// Registry password\n\tPassword string `json:\"password\"`\n\t// Registry project\n\tProject *string `json:\"project,omitempty\"`\n\t// Registry type\n\tRegistryType string `json:\"registryType\"`\n\t// Set as default registry\n\tIsDefault *bool `json:\"isDefault,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateDockerRegistry CreateDockerRegistry\n\n// NewCreateDockerRegistry instantiates a new CreateDockerRegistry object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateDockerRegistry(name string, url string, username string, password string, registryType string) *CreateDockerRegistry {\n\tthis := CreateDockerRegistry{}\n\tthis.Name = name\n\tthis.Url = url\n\tthis.Username = username\n\tthis.Password = password\n\tthis.RegistryType = registryType\n\treturn &this\n}\n\n// NewCreateDockerRegistryWithDefaults instantiates a new CreateDockerRegistry object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateDockerRegistryWithDefaults() *CreateDockerRegistry {\n\tthis := CreateDockerRegistry{}\n\tvar registryType string = \"organization\"\n\tthis.RegistryType = registryType\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *CreateDockerRegistry) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateDockerRegistry) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateDockerRegistry) SetName(v string) {\n\to.Name = v\n}\n\n// GetUrl returns the Url field value\nfunc (o *CreateDockerRegistry) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateDockerRegistry) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *CreateDockerRegistry) SetUrl(v string) {\n\to.Url = v\n}\n\n// GetUsername returns the Username field value\nfunc (o *CreateDockerRegistry) GetUsername() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Username\n}\n\n// GetUsernameOk returns a tuple with the Username field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateDockerRegistry) GetUsernameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Username, true\n}\n\n// SetUsername sets field value\nfunc (o *CreateDockerRegistry) SetUsername(v string) {\n\to.Username = v\n}\n\n// GetPassword returns the Password field value\nfunc (o *CreateDockerRegistry) GetPassword() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Password\n}\n\n// GetPasswordOk returns a tuple with the Password field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateDockerRegistry) GetPasswordOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Password, true\n}\n\n// SetPassword sets field value\nfunc (o *CreateDockerRegistry) SetPassword(v string) {\n\to.Password = v\n}\n\n// GetProject returns the Project field value if set, zero value otherwise.\nfunc (o *CreateDockerRegistry) GetProject() string {\n\tif o == nil || IsNil(o.Project) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Project\n}\n\n// GetProjectOk returns a tuple with the Project field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateDockerRegistry) GetProjectOk() (*string, bool) {\n\tif o == nil || IsNil(o.Project) {\n\t\treturn nil, false\n\t}\n\treturn o.Project, true\n}\n\n// HasProject returns a boolean if a field has been set.\nfunc (o *CreateDockerRegistry) HasProject() bool {\n\tif o != nil && !IsNil(o.Project) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProject gets a reference to the given string and assigns it to the Project field.\nfunc (o *CreateDockerRegistry) SetProject(v string) {\n\to.Project = &v\n}\n\n// GetRegistryType returns the RegistryType field value\nfunc (o *CreateDockerRegistry) GetRegistryType() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RegistryType\n}\n\n// GetRegistryTypeOk returns a tuple with the RegistryType field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateDockerRegistry) GetRegistryTypeOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegistryType, true\n}\n\n// SetRegistryType sets field value\nfunc (o *CreateDockerRegistry) SetRegistryType(v string) {\n\to.RegistryType = v\n}\n\n// GetIsDefault returns the IsDefault field value if set, zero value otherwise.\nfunc (o *CreateDockerRegistry) GetIsDefault() bool {\n\tif o == nil || IsNil(o.IsDefault) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.IsDefault\n}\n\n// GetIsDefaultOk returns a tuple with the IsDefault field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateDockerRegistry) GetIsDefaultOk() (*bool, bool) {\n\tif o == nil || IsNil(o.IsDefault) {\n\t\treturn nil, false\n\t}\n\treturn o.IsDefault, true\n}\n\n// HasIsDefault returns a boolean if a field has been set.\nfunc (o *CreateDockerRegistry) HasIsDefault() bool {\n\tif o != nil && !IsNil(o.IsDefault) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetIsDefault gets a reference to the given bool and assigns it to the IsDefault field.\nfunc (o *CreateDockerRegistry) SetIsDefault(v bool) {\n\to.IsDefault = &v\n}\n\nfunc (o CreateDockerRegistry) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateDockerRegistry) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"url\"] = o.Url\n\ttoSerialize[\"username\"] = o.Username\n\ttoSerialize[\"password\"] = o.Password\n\tif !IsNil(o.Project) {\n\t\ttoSerialize[\"project\"] = o.Project\n\t}\n\ttoSerialize[\"registryType\"] = o.RegistryType\n\tif !IsNil(o.IsDefault) {\n\t\ttoSerialize[\"isDefault\"] = o.IsDefault\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateDockerRegistry) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"url\",\n\t\t\"username\",\n\t\t\"password\",\n\t\t\"registryType\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateDockerRegistry := _CreateDockerRegistry{}\n\n\terr = json.Unmarshal(data, &varCreateDockerRegistry)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateDockerRegistry(varCreateDockerRegistry)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"url\")\n\t\tdelete(additionalProperties, \"username\")\n\t\tdelete(additionalProperties, \"password\")\n\t\tdelete(additionalProperties, \"project\")\n\t\tdelete(additionalProperties, \"registryType\")\n\t\tdelete(additionalProperties, \"isDefault\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateDockerRegistry struct {\n\tvalue *CreateDockerRegistry\n\tisSet bool\n}\n\nfunc (v NullableCreateDockerRegistry) Get() *CreateDockerRegistry {\n\treturn v.value\n}\n\nfunc (v *NullableCreateDockerRegistry) Set(val *CreateDockerRegistry) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateDockerRegistry) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateDockerRegistry) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateDockerRegistry(val *CreateDockerRegistry) *NullableCreateDockerRegistry {\n\treturn &NullableCreateDockerRegistry{value: val, isSet: true}\n}\n\nfunc (v NullableCreateDockerRegistry) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateDockerRegistry) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_linked_account.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateLinkedAccount type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateLinkedAccount{}\n\n// CreateLinkedAccount struct for CreateLinkedAccount\ntype CreateLinkedAccount struct {\n\t// The authentication provider of the secondary account\n\tProvider string `json:\"provider\"`\n\t// The user ID of the secondary account\n\tUserId string `json:\"userId\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateLinkedAccount CreateLinkedAccount\n\n// NewCreateLinkedAccount instantiates a new CreateLinkedAccount object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateLinkedAccount(provider string, userId string) *CreateLinkedAccount {\n\tthis := CreateLinkedAccount{}\n\tthis.Provider = provider\n\tthis.UserId = userId\n\treturn &this\n}\n\n// NewCreateLinkedAccountWithDefaults instantiates a new CreateLinkedAccount object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateLinkedAccountWithDefaults() *CreateLinkedAccount {\n\tthis := CreateLinkedAccount{}\n\treturn &this\n}\n\n// GetProvider returns the Provider field value\nfunc (o *CreateLinkedAccount) GetProvider() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Provider\n}\n\n// GetProviderOk returns a tuple with the Provider field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateLinkedAccount) GetProviderOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Provider, true\n}\n\n// SetProvider sets field value\nfunc (o *CreateLinkedAccount) SetProvider(v string) {\n\to.Provider = v\n}\n\n// GetUserId returns the UserId field value\nfunc (o *CreateLinkedAccount) GetUserId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.UserId\n}\n\n// GetUserIdOk returns a tuple with the UserId field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateLinkedAccount) GetUserIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UserId, true\n}\n\n// SetUserId sets field value\nfunc (o *CreateLinkedAccount) SetUserId(v string) {\n\to.UserId = v\n}\n\nfunc (o CreateLinkedAccount) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateLinkedAccount) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"provider\"] = o.Provider\n\ttoSerialize[\"userId\"] = o.UserId\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateLinkedAccount) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"provider\",\n\t\t\"userId\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateLinkedAccount := _CreateLinkedAccount{}\n\n\terr = json.Unmarshal(data, &varCreateLinkedAccount)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateLinkedAccount(varCreateLinkedAccount)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"provider\")\n\t\tdelete(additionalProperties, \"userId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateLinkedAccount struct {\n\tvalue *CreateLinkedAccount\n\tisSet bool\n}\n\nfunc (v NullableCreateLinkedAccount) Get() *CreateLinkedAccount {\n\treturn v.value\n}\n\nfunc (v *NullableCreateLinkedAccount) Set(val *CreateLinkedAccount) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateLinkedAccount) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateLinkedAccount) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateLinkedAccount(val *CreateLinkedAccount) *NullableCreateLinkedAccount {\n\treturn &NullableCreateLinkedAccount{value: val, isSet: true}\n}\n\nfunc (v NullableCreateLinkedAccount) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateLinkedAccount) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_organization.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateOrganization type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateOrganization{}\n\n// CreateOrganization struct for CreateOrganization\ntype CreateOrganization struct {\n\t// The name of organization\n\tName string `json:\"name\"`\n\t// The ID of the default region for the organization\n\tDefaultRegionId string `json:\"defaultRegionId\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateOrganization CreateOrganization\n\n// NewCreateOrganization instantiates a new CreateOrganization object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateOrganization(name string, defaultRegionId string) *CreateOrganization {\n\tthis := CreateOrganization{}\n\tthis.Name = name\n\tthis.DefaultRegionId = defaultRegionId\n\treturn &this\n}\n\n// NewCreateOrganizationWithDefaults instantiates a new CreateOrganization object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateOrganizationWithDefaults() *CreateOrganization {\n\tthis := CreateOrganization{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *CreateOrganization) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganization) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateOrganization) SetName(v string) {\n\to.Name = v\n}\n\n// GetDefaultRegionId returns the DefaultRegionId field value\nfunc (o *CreateOrganization) GetDefaultRegionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.DefaultRegionId\n}\n\n// GetDefaultRegionIdOk returns a tuple with the DefaultRegionId field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganization) GetDefaultRegionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DefaultRegionId, true\n}\n\n// SetDefaultRegionId sets field value\nfunc (o *CreateOrganization) SetDefaultRegionId(v string) {\n\to.DefaultRegionId = v\n}\n\nfunc (o CreateOrganization) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateOrganization) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"defaultRegionId\"] = o.DefaultRegionId\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateOrganization) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"defaultRegionId\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateOrganization := _CreateOrganization{}\n\n\terr = json.Unmarshal(data, &varCreateOrganization)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateOrganization(varCreateOrganization)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"defaultRegionId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateOrganization struct {\n\tvalue *CreateOrganization\n\tisSet bool\n}\n\nfunc (v NullableCreateOrganization) Get() *CreateOrganization {\n\treturn v.value\n}\n\nfunc (v *NullableCreateOrganization) Set(val *CreateOrganization) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateOrganization) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateOrganization) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateOrganization(val *CreateOrganization) *NullableCreateOrganization {\n\treturn &NullableCreateOrganization{value: val, isSet: true}\n}\n\nfunc (v NullableCreateOrganization) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateOrganization) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_organization_invitation.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the CreateOrganizationInvitation type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateOrganizationInvitation{}\n\n// CreateOrganizationInvitation struct for CreateOrganizationInvitation\ntype CreateOrganizationInvitation struct {\n\t// Email address of the invitee\n\tEmail string `json:\"email\"`\n\t// Organization member role for the invitee\n\tRole string `json:\"role\"`\n\t// Array of assigned role IDs for the invitee\n\tAssignedRoleIds []string `json:\"assignedRoleIds\"`\n\t// Expiration date of the invitation\n\tExpiresAt *time.Time `json:\"expiresAt,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateOrganizationInvitation CreateOrganizationInvitation\n\n// NewCreateOrganizationInvitation instantiates a new CreateOrganizationInvitation object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateOrganizationInvitation(email string, role string, assignedRoleIds []string) *CreateOrganizationInvitation {\n\tthis := CreateOrganizationInvitation{}\n\tthis.Email = email\n\tthis.Role = role\n\tthis.AssignedRoleIds = assignedRoleIds\n\treturn &this\n}\n\n// NewCreateOrganizationInvitationWithDefaults instantiates a new CreateOrganizationInvitation object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateOrganizationInvitationWithDefaults() *CreateOrganizationInvitation {\n\tthis := CreateOrganizationInvitation{}\n\tvar role string = \"member\"\n\tthis.Role = role\n\treturn &this\n}\n\n// GetEmail returns the Email field value\nfunc (o *CreateOrganizationInvitation) GetEmail() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Email\n}\n\n// GetEmailOk returns a tuple with the Email field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationInvitation) GetEmailOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Email, true\n}\n\n// SetEmail sets field value\nfunc (o *CreateOrganizationInvitation) SetEmail(v string) {\n\to.Email = v\n}\n\n// GetRole returns the Role field value\nfunc (o *CreateOrganizationInvitation) GetRole() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Role\n}\n\n// GetRoleOk returns a tuple with the Role field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationInvitation) GetRoleOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Role, true\n}\n\n// SetRole sets field value\nfunc (o *CreateOrganizationInvitation) SetRole(v string) {\n\to.Role = v\n}\n\n// GetAssignedRoleIds returns the AssignedRoleIds field value\nfunc (o *CreateOrganizationInvitation) GetAssignedRoleIds() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.AssignedRoleIds\n}\n\n// GetAssignedRoleIdsOk returns a tuple with the AssignedRoleIds field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationInvitation) GetAssignedRoleIdsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AssignedRoleIds, true\n}\n\n// SetAssignedRoleIds sets field value\nfunc (o *CreateOrganizationInvitation) SetAssignedRoleIds(v []string) {\n\to.AssignedRoleIds = v\n}\n\n// GetExpiresAt returns the ExpiresAt field value if set, zero value otherwise.\nfunc (o *CreateOrganizationInvitation) GetExpiresAt() time.Time {\n\tif o == nil || IsNil(o.ExpiresAt) {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\treturn *o.ExpiresAt\n}\n\n// GetExpiresAtOk returns a tuple with the ExpiresAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationInvitation) GetExpiresAtOk() (*time.Time, bool) {\n\tif o == nil || IsNil(o.ExpiresAt) {\n\t\treturn nil, false\n\t}\n\treturn o.ExpiresAt, true\n}\n\n// HasExpiresAt returns a boolean if a field has been set.\nfunc (o *CreateOrganizationInvitation) HasExpiresAt() bool {\n\tif o != nil && !IsNil(o.ExpiresAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetExpiresAt gets a reference to the given time.Time and assigns it to the ExpiresAt field.\nfunc (o *CreateOrganizationInvitation) SetExpiresAt(v time.Time) {\n\to.ExpiresAt = &v\n}\n\nfunc (o CreateOrganizationInvitation) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateOrganizationInvitation) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"email\"] = o.Email\n\ttoSerialize[\"role\"] = o.Role\n\ttoSerialize[\"assignedRoleIds\"] = o.AssignedRoleIds\n\tif !IsNil(o.ExpiresAt) {\n\t\ttoSerialize[\"expiresAt\"] = o.ExpiresAt\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateOrganizationInvitation) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"email\",\n\t\t\"role\",\n\t\t\"assignedRoleIds\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateOrganizationInvitation := _CreateOrganizationInvitation{}\n\n\terr = json.Unmarshal(data, &varCreateOrganizationInvitation)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateOrganizationInvitation(varCreateOrganizationInvitation)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"email\")\n\t\tdelete(additionalProperties, \"role\")\n\t\tdelete(additionalProperties, \"assignedRoleIds\")\n\t\tdelete(additionalProperties, \"expiresAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateOrganizationInvitation struct {\n\tvalue *CreateOrganizationInvitation\n\tisSet bool\n}\n\nfunc (v NullableCreateOrganizationInvitation) Get() *CreateOrganizationInvitation {\n\treturn v.value\n}\n\nfunc (v *NullableCreateOrganizationInvitation) Set(val *CreateOrganizationInvitation) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateOrganizationInvitation) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateOrganizationInvitation) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateOrganizationInvitation(val *CreateOrganizationInvitation) *NullableCreateOrganizationInvitation {\n\treturn &NullableCreateOrganizationInvitation{value: val, isSet: true}\n}\n\nfunc (v NullableCreateOrganizationInvitation) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateOrganizationInvitation) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_organization_quota.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the CreateOrganizationQuota type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateOrganizationQuota{}\n\n// CreateOrganizationQuota struct for CreateOrganizationQuota\ntype CreateOrganizationQuota struct {\n\tTotalCpuQuota *float32 `json:\"totalCpuQuota,omitempty\"`\n\tTotalMemoryQuota *float32 `json:\"totalMemoryQuota,omitempty\"`\n\tTotalDiskQuota *float32 `json:\"totalDiskQuota,omitempty\"`\n\tMaxCpuPerSandbox *float32 `json:\"maxCpuPerSandbox,omitempty\"`\n\tMaxMemoryPerSandbox *float32 `json:\"maxMemoryPerSandbox,omitempty\"`\n\tMaxDiskPerSandbox *float32 `json:\"maxDiskPerSandbox,omitempty\"`\n\tSnapshotQuota *float32 `json:\"snapshotQuota,omitempty\"`\n\tMaxSnapshotSize *float32 `json:\"maxSnapshotSize,omitempty\"`\n\tVolumeQuota *float32 `json:\"volumeQuota,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateOrganizationQuota CreateOrganizationQuota\n\n// NewCreateOrganizationQuota instantiates a new CreateOrganizationQuota object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateOrganizationQuota() *CreateOrganizationQuota {\n\tthis := CreateOrganizationQuota{}\n\treturn &this\n}\n\n// NewCreateOrganizationQuotaWithDefaults instantiates a new CreateOrganizationQuota object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateOrganizationQuotaWithDefaults() *CreateOrganizationQuota {\n\tthis := CreateOrganizationQuota{}\n\treturn &this\n}\n\n// GetTotalCpuQuota returns the TotalCpuQuota field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetTotalCpuQuota() float32 {\n\tif o == nil || IsNil(o.TotalCpuQuota) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.TotalCpuQuota\n}\n\n// GetTotalCpuQuotaOk returns a tuple with the TotalCpuQuota field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetTotalCpuQuotaOk() (*float32, bool) {\n\tif o == nil || IsNil(o.TotalCpuQuota) {\n\t\treturn nil, false\n\t}\n\treturn o.TotalCpuQuota, true\n}\n\n// HasTotalCpuQuota returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasTotalCpuQuota() bool {\n\tif o != nil && !IsNil(o.TotalCpuQuota) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTotalCpuQuota gets a reference to the given float32 and assigns it to the TotalCpuQuota field.\nfunc (o *CreateOrganizationQuota) SetTotalCpuQuota(v float32) {\n\to.TotalCpuQuota = &v\n}\n\n// GetTotalMemoryQuota returns the TotalMemoryQuota field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetTotalMemoryQuota() float32 {\n\tif o == nil || IsNil(o.TotalMemoryQuota) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.TotalMemoryQuota\n}\n\n// GetTotalMemoryQuotaOk returns a tuple with the TotalMemoryQuota field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetTotalMemoryQuotaOk() (*float32, bool) {\n\tif o == nil || IsNil(o.TotalMemoryQuota) {\n\t\treturn nil, false\n\t}\n\treturn o.TotalMemoryQuota, true\n}\n\n// HasTotalMemoryQuota returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasTotalMemoryQuota() bool {\n\tif o != nil && !IsNil(o.TotalMemoryQuota) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTotalMemoryQuota gets a reference to the given float32 and assigns it to the TotalMemoryQuota field.\nfunc (o *CreateOrganizationQuota) SetTotalMemoryQuota(v float32) {\n\to.TotalMemoryQuota = &v\n}\n\n// GetTotalDiskQuota returns the TotalDiskQuota field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetTotalDiskQuota() float32 {\n\tif o == nil || IsNil(o.TotalDiskQuota) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.TotalDiskQuota\n}\n\n// GetTotalDiskQuotaOk returns a tuple with the TotalDiskQuota field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetTotalDiskQuotaOk() (*float32, bool) {\n\tif o == nil || IsNil(o.TotalDiskQuota) {\n\t\treturn nil, false\n\t}\n\treturn o.TotalDiskQuota, true\n}\n\n// HasTotalDiskQuota returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasTotalDiskQuota() bool {\n\tif o != nil && !IsNil(o.TotalDiskQuota) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTotalDiskQuota gets a reference to the given float32 and assigns it to the TotalDiskQuota field.\nfunc (o *CreateOrganizationQuota) SetTotalDiskQuota(v float32) {\n\to.TotalDiskQuota = &v\n}\n\n// GetMaxCpuPerSandbox returns the MaxCpuPerSandbox field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetMaxCpuPerSandbox() float32 {\n\tif o == nil || IsNil(o.MaxCpuPerSandbox) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.MaxCpuPerSandbox\n}\n\n// GetMaxCpuPerSandboxOk returns a tuple with the MaxCpuPerSandbox field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetMaxCpuPerSandboxOk() (*float32, bool) {\n\tif o == nil || IsNil(o.MaxCpuPerSandbox) {\n\t\treturn nil, false\n\t}\n\treturn o.MaxCpuPerSandbox, true\n}\n\n// HasMaxCpuPerSandbox returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasMaxCpuPerSandbox() bool {\n\tif o != nil && !IsNil(o.MaxCpuPerSandbox) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMaxCpuPerSandbox gets a reference to the given float32 and assigns it to the MaxCpuPerSandbox field.\nfunc (o *CreateOrganizationQuota) SetMaxCpuPerSandbox(v float32) {\n\to.MaxCpuPerSandbox = &v\n}\n\n// GetMaxMemoryPerSandbox returns the MaxMemoryPerSandbox field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetMaxMemoryPerSandbox() float32 {\n\tif o == nil || IsNil(o.MaxMemoryPerSandbox) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.MaxMemoryPerSandbox\n}\n\n// GetMaxMemoryPerSandboxOk returns a tuple with the MaxMemoryPerSandbox field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetMaxMemoryPerSandboxOk() (*float32, bool) {\n\tif o == nil || IsNil(o.MaxMemoryPerSandbox) {\n\t\treturn nil, false\n\t}\n\treturn o.MaxMemoryPerSandbox, true\n}\n\n// HasMaxMemoryPerSandbox returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasMaxMemoryPerSandbox() bool {\n\tif o != nil && !IsNil(o.MaxMemoryPerSandbox) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMaxMemoryPerSandbox gets a reference to the given float32 and assigns it to the MaxMemoryPerSandbox field.\nfunc (o *CreateOrganizationQuota) SetMaxMemoryPerSandbox(v float32) {\n\to.MaxMemoryPerSandbox = &v\n}\n\n// GetMaxDiskPerSandbox returns the MaxDiskPerSandbox field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetMaxDiskPerSandbox() float32 {\n\tif o == nil || IsNil(o.MaxDiskPerSandbox) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.MaxDiskPerSandbox\n}\n\n// GetMaxDiskPerSandboxOk returns a tuple with the MaxDiskPerSandbox field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetMaxDiskPerSandboxOk() (*float32, bool) {\n\tif o == nil || IsNil(o.MaxDiskPerSandbox) {\n\t\treturn nil, false\n\t}\n\treturn o.MaxDiskPerSandbox, true\n}\n\n// HasMaxDiskPerSandbox returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasMaxDiskPerSandbox() bool {\n\tif o != nil && !IsNil(o.MaxDiskPerSandbox) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMaxDiskPerSandbox gets a reference to the given float32 and assigns it to the MaxDiskPerSandbox field.\nfunc (o *CreateOrganizationQuota) SetMaxDiskPerSandbox(v float32) {\n\to.MaxDiskPerSandbox = &v\n}\n\n// GetSnapshotQuota returns the SnapshotQuota field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetSnapshotQuota() float32 {\n\tif o == nil || IsNil(o.SnapshotQuota) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.SnapshotQuota\n}\n\n// GetSnapshotQuotaOk returns a tuple with the SnapshotQuota field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetSnapshotQuotaOk() (*float32, bool) {\n\tif o == nil || IsNil(o.SnapshotQuota) {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotQuota, true\n}\n\n// HasSnapshotQuota returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasSnapshotQuota() bool {\n\tif o != nil && !IsNil(o.SnapshotQuota) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshotQuota gets a reference to the given float32 and assigns it to the SnapshotQuota field.\nfunc (o *CreateOrganizationQuota) SetSnapshotQuota(v float32) {\n\to.SnapshotQuota = &v\n}\n\n// GetMaxSnapshotSize returns the MaxSnapshotSize field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetMaxSnapshotSize() float32 {\n\tif o == nil || IsNil(o.MaxSnapshotSize) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.MaxSnapshotSize\n}\n\n// GetMaxSnapshotSizeOk returns a tuple with the MaxSnapshotSize field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetMaxSnapshotSizeOk() (*float32, bool) {\n\tif o == nil || IsNil(o.MaxSnapshotSize) {\n\t\treturn nil, false\n\t}\n\treturn o.MaxSnapshotSize, true\n}\n\n// HasMaxSnapshotSize returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasMaxSnapshotSize() bool {\n\tif o != nil && !IsNil(o.MaxSnapshotSize) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMaxSnapshotSize gets a reference to the given float32 and assigns it to the MaxSnapshotSize field.\nfunc (o *CreateOrganizationQuota) SetMaxSnapshotSize(v float32) {\n\to.MaxSnapshotSize = &v\n}\n\n// GetVolumeQuota returns the VolumeQuota field value if set, zero value otherwise.\nfunc (o *CreateOrganizationQuota) GetVolumeQuota() float32 {\n\tif o == nil || IsNil(o.VolumeQuota) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.VolumeQuota\n}\n\n// GetVolumeQuotaOk returns a tuple with the VolumeQuota field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationQuota) GetVolumeQuotaOk() (*float32, bool) {\n\tif o == nil || IsNil(o.VolumeQuota) {\n\t\treturn nil, false\n\t}\n\treturn o.VolumeQuota, true\n}\n\n// HasVolumeQuota returns a boolean if a field has been set.\nfunc (o *CreateOrganizationQuota) HasVolumeQuota() bool {\n\tif o != nil && !IsNil(o.VolumeQuota) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetVolumeQuota gets a reference to the given float32 and assigns it to the VolumeQuota field.\nfunc (o *CreateOrganizationQuota) SetVolumeQuota(v float32) {\n\to.VolumeQuota = &v\n}\n\nfunc (o CreateOrganizationQuota) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateOrganizationQuota) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.TotalCpuQuota) {\n\t\ttoSerialize[\"totalCpuQuota\"] = o.TotalCpuQuota\n\t}\n\tif !IsNil(o.TotalMemoryQuota) {\n\t\ttoSerialize[\"totalMemoryQuota\"] = o.TotalMemoryQuota\n\t}\n\tif !IsNil(o.TotalDiskQuota) {\n\t\ttoSerialize[\"totalDiskQuota\"] = o.TotalDiskQuota\n\t}\n\tif !IsNil(o.MaxCpuPerSandbox) {\n\t\ttoSerialize[\"maxCpuPerSandbox\"] = o.MaxCpuPerSandbox\n\t}\n\tif !IsNil(o.MaxMemoryPerSandbox) {\n\t\ttoSerialize[\"maxMemoryPerSandbox\"] = o.MaxMemoryPerSandbox\n\t}\n\tif !IsNil(o.MaxDiskPerSandbox) {\n\t\ttoSerialize[\"maxDiskPerSandbox\"] = o.MaxDiskPerSandbox\n\t}\n\tif !IsNil(o.SnapshotQuota) {\n\t\ttoSerialize[\"snapshotQuota\"] = o.SnapshotQuota\n\t}\n\tif !IsNil(o.MaxSnapshotSize) {\n\t\ttoSerialize[\"maxSnapshotSize\"] = o.MaxSnapshotSize\n\t}\n\tif !IsNil(o.VolumeQuota) {\n\t\ttoSerialize[\"volumeQuota\"] = o.VolumeQuota\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateOrganizationQuota) UnmarshalJSON(data []byte) (err error) {\n\tvarCreateOrganizationQuota := _CreateOrganizationQuota{}\n\n\terr = json.Unmarshal(data, &varCreateOrganizationQuota)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateOrganizationQuota(varCreateOrganizationQuota)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"totalCpuQuota\")\n\t\tdelete(additionalProperties, \"totalMemoryQuota\")\n\t\tdelete(additionalProperties, \"totalDiskQuota\")\n\t\tdelete(additionalProperties, \"maxCpuPerSandbox\")\n\t\tdelete(additionalProperties, \"maxMemoryPerSandbox\")\n\t\tdelete(additionalProperties, \"maxDiskPerSandbox\")\n\t\tdelete(additionalProperties, \"snapshotQuota\")\n\t\tdelete(additionalProperties, \"maxSnapshotSize\")\n\t\tdelete(additionalProperties, \"volumeQuota\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateOrganizationQuota struct {\n\tvalue *CreateOrganizationQuota\n\tisSet bool\n}\n\nfunc (v NullableCreateOrganizationQuota) Get() *CreateOrganizationQuota {\n\treturn v.value\n}\n\nfunc (v *NullableCreateOrganizationQuota) Set(val *CreateOrganizationQuota) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateOrganizationQuota) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateOrganizationQuota) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateOrganizationQuota(val *CreateOrganizationQuota) *NullableCreateOrganizationQuota {\n\treturn &NullableCreateOrganizationQuota{value: val, isSet: true}\n}\n\nfunc (v NullableCreateOrganizationQuota) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateOrganizationQuota) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_organization_role.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateOrganizationRole type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateOrganizationRole{}\n\n// CreateOrganizationRole struct for CreateOrganizationRole\ntype CreateOrganizationRole struct {\n\t// The name of the role\n\tName string `json:\"name\"`\n\t// The description of the role\n\tDescription string `json:\"description\"`\n\t// The list of permissions assigned to the role\n\tPermissions []string `json:\"permissions\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateOrganizationRole CreateOrganizationRole\n\n// NewCreateOrganizationRole instantiates a new CreateOrganizationRole object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateOrganizationRole(name string, description string, permissions []string) *CreateOrganizationRole {\n\tthis := CreateOrganizationRole{}\n\tthis.Name = name\n\tthis.Description = description\n\tthis.Permissions = permissions\n\treturn &this\n}\n\n// NewCreateOrganizationRoleWithDefaults instantiates a new CreateOrganizationRole object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateOrganizationRoleWithDefaults() *CreateOrganizationRole {\n\tthis := CreateOrganizationRole{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *CreateOrganizationRole) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationRole) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateOrganizationRole) SetName(v string) {\n\to.Name = v\n}\n\n// GetDescription returns the Description field value\nfunc (o *CreateOrganizationRole) GetDescription() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Description\n}\n\n// GetDescriptionOk returns a tuple with the Description field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationRole) GetDescriptionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Description, true\n}\n\n// SetDescription sets field value\nfunc (o *CreateOrganizationRole) SetDescription(v string) {\n\to.Description = v\n}\n\n// GetPermissions returns the Permissions field value\nfunc (o *CreateOrganizationRole) GetPermissions() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Permissions\n}\n\n// GetPermissionsOk returns a tuple with the Permissions field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateOrganizationRole) GetPermissionsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Permissions, true\n}\n\n// SetPermissions sets field value\nfunc (o *CreateOrganizationRole) SetPermissions(v []string) {\n\to.Permissions = v\n}\n\nfunc (o CreateOrganizationRole) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateOrganizationRole) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"description\"] = o.Description\n\ttoSerialize[\"permissions\"] = o.Permissions\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateOrganizationRole) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"description\",\n\t\t\"permissions\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateOrganizationRole := _CreateOrganizationRole{}\n\n\terr = json.Unmarshal(data, &varCreateOrganizationRole)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateOrganizationRole(varCreateOrganizationRole)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"description\")\n\t\tdelete(additionalProperties, \"permissions\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateOrganizationRole struct {\n\tvalue *CreateOrganizationRole\n\tisSet bool\n}\n\nfunc (v NullableCreateOrganizationRole) Get() *CreateOrganizationRole {\n\treturn v.value\n}\n\nfunc (v *NullableCreateOrganizationRole) Set(val *CreateOrganizationRole) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateOrganizationRole) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateOrganizationRole) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateOrganizationRole(val *CreateOrganizationRole) *NullableCreateOrganizationRole {\n\treturn &NullableCreateOrganizationRole{value: val, isSet: true}\n}\n\nfunc (v NullableCreateOrganizationRole) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateOrganizationRole) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_region.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateRegion type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateRegion{}\n\n// CreateRegion struct for CreateRegion\ntype CreateRegion struct {\n\t// Region name\n\tName string `json:\"name\"`\n\t// Proxy URL for the region\n\tProxyUrl NullableString `json:\"proxyUrl,omitempty\"`\n\t// SSH Gateway URL for the region\n\tSshGatewayUrl NullableString `json:\"sshGatewayUrl,omitempty\"`\n\t// Snapshot Manager URL for the region\n\tSnapshotManagerUrl NullableString `json:\"snapshotManagerUrl,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateRegion CreateRegion\n\n// NewCreateRegion instantiates a new CreateRegion object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateRegion(name string) *CreateRegion {\n\tthis := CreateRegion{}\n\tthis.Name = name\n\treturn &this\n}\n\n// NewCreateRegionWithDefaults instantiates a new CreateRegion object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateRegionWithDefaults() *CreateRegion {\n\tthis := CreateRegion{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *CreateRegion) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateRegion) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateRegion) SetName(v string) {\n\to.Name = v\n}\n\n// GetProxyUrl returns the ProxyUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *CreateRegion) GetProxyUrl() string {\n\tif o == nil || IsNil(o.ProxyUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProxyUrl.Get()\n}\n\n// GetProxyUrlOk returns a tuple with the ProxyUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *CreateRegion) GetProxyUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ProxyUrl.Get(), o.ProxyUrl.IsSet()\n}\n\n// HasProxyUrl returns a boolean if a field has been set.\nfunc (o *CreateRegion) HasProxyUrl() bool {\n\tif o != nil && o.ProxyUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProxyUrl gets a reference to the given NullableString and assigns it to the ProxyUrl field.\nfunc (o *CreateRegion) SetProxyUrl(v string) {\n\to.ProxyUrl.Set(&v)\n}\n// SetProxyUrlNil sets the value for ProxyUrl to be an explicit nil\nfunc (o *CreateRegion) SetProxyUrlNil() {\n\to.ProxyUrl.Set(nil)\n}\n\n// UnsetProxyUrl ensures that no value is present for ProxyUrl, not even an explicit nil\nfunc (o *CreateRegion) UnsetProxyUrl() {\n\to.ProxyUrl.Unset()\n}\n\n// GetSshGatewayUrl returns the SshGatewayUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *CreateRegion) GetSshGatewayUrl() string {\n\tif o == nil || IsNil(o.SshGatewayUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SshGatewayUrl.Get()\n}\n\n// GetSshGatewayUrlOk returns a tuple with the SshGatewayUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *CreateRegion) GetSshGatewayUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SshGatewayUrl.Get(), o.SshGatewayUrl.IsSet()\n}\n\n// HasSshGatewayUrl returns a boolean if a field has been set.\nfunc (o *CreateRegion) HasSshGatewayUrl() bool {\n\tif o != nil && o.SshGatewayUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSshGatewayUrl gets a reference to the given NullableString and assigns it to the SshGatewayUrl field.\nfunc (o *CreateRegion) SetSshGatewayUrl(v string) {\n\to.SshGatewayUrl.Set(&v)\n}\n// SetSshGatewayUrlNil sets the value for SshGatewayUrl to be an explicit nil\nfunc (o *CreateRegion) SetSshGatewayUrlNil() {\n\to.SshGatewayUrl.Set(nil)\n}\n\n// UnsetSshGatewayUrl ensures that no value is present for SshGatewayUrl, not even an explicit nil\nfunc (o *CreateRegion) UnsetSshGatewayUrl() {\n\to.SshGatewayUrl.Unset()\n}\n\n// GetSnapshotManagerUrl returns the SnapshotManagerUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *CreateRegion) GetSnapshotManagerUrl() string {\n\tif o == nil || IsNil(o.SnapshotManagerUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SnapshotManagerUrl.Get()\n}\n\n// GetSnapshotManagerUrlOk returns a tuple with the SnapshotManagerUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *CreateRegion) GetSnapshotManagerUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotManagerUrl.Get(), o.SnapshotManagerUrl.IsSet()\n}\n\n// HasSnapshotManagerUrl returns a boolean if a field has been set.\nfunc (o *CreateRegion) HasSnapshotManagerUrl() bool {\n\tif o != nil && o.SnapshotManagerUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshotManagerUrl gets a reference to the given NullableString and assigns it to the SnapshotManagerUrl field.\nfunc (o *CreateRegion) SetSnapshotManagerUrl(v string) {\n\to.SnapshotManagerUrl.Set(&v)\n}\n// SetSnapshotManagerUrlNil sets the value for SnapshotManagerUrl to be an explicit nil\nfunc (o *CreateRegion) SetSnapshotManagerUrlNil() {\n\to.SnapshotManagerUrl.Set(nil)\n}\n\n// UnsetSnapshotManagerUrl ensures that no value is present for SnapshotManagerUrl, not even an explicit nil\nfunc (o *CreateRegion) UnsetSnapshotManagerUrl() {\n\to.SnapshotManagerUrl.Unset()\n}\n\nfunc (o CreateRegion) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateRegion) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\tif o.ProxyUrl.IsSet() {\n\t\ttoSerialize[\"proxyUrl\"] = o.ProxyUrl.Get()\n\t}\n\tif o.SshGatewayUrl.IsSet() {\n\t\ttoSerialize[\"sshGatewayUrl\"] = o.SshGatewayUrl.Get()\n\t}\n\tif o.SnapshotManagerUrl.IsSet() {\n\t\ttoSerialize[\"snapshotManagerUrl\"] = o.SnapshotManagerUrl.Get()\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateRegion) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateRegion := _CreateRegion{}\n\n\terr = json.Unmarshal(data, &varCreateRegion)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateRegion(varCreateRegion)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"proxyUrl\")\n\t\tdelete(additionalProperties, \"sshGatewayUrl\")\n\t\tdelete(additionalProperties, \"snapshotManagerUrl\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateRegion struct {\n\tvalue *CreateRegion\n\tisSet bool\n}\n\nfunc (v NullableCreateRegion) Get() *CreateRegion {\n\treturn v.value\n}\n\nfunc (v *NullableCreateRegion) Set(val *CreateRegion) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateRegion) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateRegion) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateRegion(val *CreateRegion) *NullableCreateRegion {\n\treturn &NullableCreateRegion{value: val, isSet: true}\n}\n\nfunc (v NullableCreateRegion) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateRegion) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_region_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateRegionResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateRegionResponse{}\n\n// CreateRegionResponse struct for CreateRegionResponse\ntype CreateRegionResponse struct {\n\t// ID of the created region\n\tId string `json:\"id\"`\n\t// Proxy API key for the region\n\tProxyApiKey NullableString `json:\"proxyApiKey,omitempty\"`\n\t// SSH Gateway API key for the region\n\tSshGatewayApiKey NullableString `json:\"sshGatewayApiKey,omitempty\"`\n\t// Snapshot Manager username for the region\n\tSnapshotManagerUsername NullableString `json:\"snapshotManagerUsername,omitempty\"`\n\t// Snapshot Manager password for the region\n\tSnapshotManagerPassword NullableString `json:\"snapshotManagerPassword,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateRegionResponse CreateRegionResponse\n\n// NewCreateRegionResponse instantiates a new CreateRegionResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateRegionResponse(id string) *CreateRegionResponse {\n\tthis := CreateRegionResponse{}\n\tthis.Id = id\n\treturn &this\n}\n\n// NewCreateRegionResponseWithDefaults instantiates a new CreateRegionResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateRegionResponseWithDefaults() *CreateRegionResponse {\n\tthis := CreateRegionResponse{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *CreateRegionResponse) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateRegionResponse) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *CreateRegionResponse) SetId(v string) {\n\to.Id = v\n}\n\n// GetProxyApiKey returns the ProxyApiKey field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *CreateRegionResponse) GetProxyApiKey() string {\n\tif o == nil || IsNil(o.ProxyApiKey.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProxyApiKey.Get()\n}\n\n// GetProxyApiKeyOk returns a tuple with the ProxyApiKey field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *CreateRegionResponse) GetProxyApiKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ProxyApiKey.Get(), o.ProxyApiKey.IsSet()\n}\n\n// HasProxyApiKey returns a boolean if a field has been set.\nfunc (o *CreateRegionResponse) HasProxyApiKey() bool {\n\tif o != nil && o.ProxyApiKey.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProxyApiKey gets a reference to the given NullableString and assigns it to the ProxyApiKey field.\nfunc (o *CreateRegionResponse) SetProxyApiKey(v string) {\n\to.ProxyApiKey.Set(&v)\n}\n// SetProxyApiKeyNil sets the value for ProxyApiKey to be an explicit nil\nfunc (o *CreateRegionResponse) SetProxyApiKeyNil() {\n\to.ProxyApiKey.Set(nil)\n}\n\n// UnsetProxyApiKey ensures that no value is present for ProxyApiKey, not even an explicit nil\nfunc (o *CreateRegionResponse) UnsetProxyApiKey() {\n\to.ProxyApiKey.Unset()\n}\n\n// GetSshGatewayApiKey returns the SshGatewayApiKey field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *CreateRegionResponse) GetSshGatewayApiKey() string {\n\tif o == nil || IsNil(o.SshGatewayApiKey.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SshGatewayApiKey.Get()\n}\n\n// GetSshGatewayApiKeyOk returns a tuple with the SshGatewayApiKey field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *CreateRegionResponse) GetSshGatewayApiKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SshGatewayApiKey.Get(), o.SshGatewayApiKey.IsSet()\n}\n\n// HasSshGatewayApiKey returns a boolean if a field has been set.\nfunc (o *CreateRegionResponse) HasSshGatewayApiKey() bool {\n\tif o != nil && o.SshGatewayApiKey.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSshGatewayApiKey gets a reference to the given NullableString and assigns it to the SshGatewayApiKey field.\nfunc (o *CreateRegionResponse) SetSshGatewayApiKey(v string) {\n\to.SshGatewayApiKey.Set(&v)\n}\n// SetSshGatewayApiKeyNil sets the value for SshGatewayApiKey to be an explicit nil\nfunc (o *CreateRegionResponse) SetSshGatewayApiKeyNil() {\n\to.SshGatewayApiKey.Set(nil)\n}\n\n// UnsetSshGatewayApiKey ensures that no value is present for SshGatewayApiKey, not even an explicit nil\nfunc (o *CreateRegionResponse) UnsetSshGatewayApiKey() {\n\to.SshGatewayApiKey.Unset()\n}\n\n// GetSnapshotManagerUsername returns the SnapshotManagerUsername field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *CreateRegionResponse) GetSnapshotManagerUsername() string {\n\tif o == nil || IsNil(o.SnapshotManagerUsername.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SnapshotManagerUsername.Get()\n}\n\n// GetSnapshotManagerUsernameOk returns a tuple with the SnapshotManagerUsername field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *CreateRegionResponse) GetSnapshotManagerUsernameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotManagerUsername.Get(), o.SnapshotManagerUsername.IsSet()\n}\n\n// HasSnapshotManagerUsername returns a boolean if a field has been set.\nfunc (o *CreateRegionResponse) HasSnapshotManagerUsername() bool {\n\tif o != nil && o.SnapshotManagerUsername.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshotManagerUsername gets a reference to the given NullableString and assigns it to the SnapshotManagerUsername field.\nfunc (o *CreateRegionResponse) SetSnapshotManagerUsername(v string) {\n\to.SnapshotManagerUsername.Set(&v)\n}\n// SetSnapshotManagerUsernameNil sets the value for SnapshotManagerUsername to be an explicit nil\nfunc (o *CreateRegionResponse) SetSnapshotManagerUsernameNil() {\n\to.SnapshotManagerUsername.Set(nil)\n}\n\n// UnsetSnapshotManagerUsername ensures that no value is present for SnapshotManagerUsername, not even an explicit nil\nfunc (o *CreateRegionResponse) UnsetSnapshotManagerUsername() {\n\to.SnapshotManagerUsername.Unset()\n}\n\n// GetSnapshotManagerPassword returns the SnapshotManagerPassword field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *CreateRegionResponse) GetSnapshotManagerPassword() string {\n\tif o == nil || IsNil(o.SnapshotManagerPassword.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SnapshotManagerPassword.Get()\n}\n\n// GetSnapshotManagerPasswordOk returns a tuple with the SnapshotManagerPassword field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *CreateRegionResponse) GetSnapshotManagerPasswordOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotManagerPassword.Get(), o.SnapshotManagerPassword.IsSet()\n}\n\n// HasSnapshotManagerPassword returns a boolean if a field has been set.\nfunc (o *CreateRegionResponse) HasSnapshotManagerPassword() bool {\n\tif o != nil && o.SnapshotManagerPassword.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshotManagerPassword gets a reference to the given NullableString and assigns it to the SnapshotManagerPassword field.\nfunc (o *CreateRegionResponse) SetSnapshotManagerPassword(v string) {\n\to.SnapshotManagerPassword.Set(&v)\n}\n// SetSnapshotManagerPasswordNil sets the value for SnapshotManagerPassword to be an explicit nil\nfunc (o *CreateRegionResponse) SetSnapshotManagerPasswordNil() {\n\to.SnapshotManagerPassword.Set(nil)\n}\n\n// UnsetSnapshotManagerPassword ensures that no value is present for SnapshotManagerPassword, not even an explicit nil\nfunc (o *CreateRegionResponse) UnsetSnapshotManagerPassword() {\n\to.SnapshotManagerPassword.Unset()\n}\n\nfunc (o CreateRegionResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateRegionResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\tif o.ProxyApiKey.IsSet() {\n\t\ttoSerialize[\"proxyApiKey\"] = o.ProxyApiKey.Get()\n\t}\n\tif o.SshGatewayApiKey.IsSet() {\n\t\ttoSerialize[\"sshGatewayApiKey\"] = o.SshGatewayApiKey.Get()\n\t}\n\tif o.SnapshotManagerUsername.IsSet() {\n\t\ttoSerialize[\"snapshotManagerUsername\"] = o.SnapshotManagerUsername.Get()\n\t}\n\tif o.SnapshotManagerPassword.IsSet() {\n\t\ttoSerialize[\"snapshotManagerPassword\"] = o.SnapshotManagerPassword.Get()\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateRegionResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateRegionResponse := _CreateRegionResponse{}\n\n\terr = json.Unmarshal(data, &varCreateRegionResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateRegionResponse(varCreateRegionResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"proxyApiKey\")\n\t\tdelete(additionalProperties, \"sshGatewayApiKey\")\n\t\tdelete(additionalProperties, \"snapshotManagerUsername\")\n\t\tdelete(additionalProperties, \"snapshotManagerPassword\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateRegionResponse struct {\n\tvalue *CreateRegionResponse\n\tisSet bool\n}\n\nfunc (v NullableCreateRegionResponse) Get() *CreateRegionResponse {\n\treturn v.value\n}\n\nfunc (v *NullableCreateRegionResponse) Set(val *CreateRegionResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateRegionResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateRegionResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateRegionResponse(val *CreateRegionResponse) *NullableCreateRegionResponse {\n\treturn &NullableCreateRegionResponse{value: val, isSet: true}\n}\n\nfunc (v NullableCreateRegionResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateRegionResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_runner.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateRunner type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateRunner{}\n\n// CreateRunner struct for CreateRunner\ntype CreateRunner struct {\n\tRegionId string `json:\"regionId\"`\n\tName string `json:\"name\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateRunner CreateRunner\n\n// NewCreateRunner instantiates a new CreateRunner object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateRunner(regionId string, name string) *CreateRunner {\n\tthis := CreateRunner{}\n\tthis.RegionId = regionId\n\tthis.Name = name\n\treturn &this\n}\n\n// NewCreateRunnerWithDefaults instantiates a new CreateRunner object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateRunnerWithDefaults() *CreateRunner {\n\tthis := CreateRunner{}\n\treturn &this\n}\n\n// GetRegionId returns the RegionId field value\nfunc (o *CreateRunner) GetRegionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RegionId\n}\n\n// GetRegionIdOk returns a tuple with the RegionId field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateRunner) GetRegionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegionId, true\n}\n\n// SetRegionId sets field value\nfunc (o *CreateRunner) SetRegionId(v string) {\n\to.RegionId = v\n}\n\n// GetName returns the Name field value\nfunc (o *CreateRunner) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateRunner) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateRunner) SetName(v string) {\n\to.Name = v\n}\n\nfunc (o CreateRunner) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateRunner) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"regionId\"] = o.RegionId\n\ttoSerialize[\"name\"] = o.Name\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateRunner) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"regionId\",\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateRunner := _CreateRunner{}\n\n\terr = json.Unmarshal(data, &varCreateRunner)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateRunner(varCreateRunner)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"regionId\")\n\t\tdelete(additionalProperties, \"name\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateRunner struct {\n\tvalue *CreateRunner\n\tisSet bool\n}\n\nfunc (v NullableCreateRunner) Get() *CreateRunner {\n\treturn v.value\n}\n\nfunc (v *NullableCreateRunner) Set(val *CreateRunner) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateRunner) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateRunner) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateRunner(val *CreateRunner) *NullableCreateRunner {\n\treturn &NullableCreateRunner{value: val, isSet: true}\n}\n\nfunc (v NullableCreateRunner) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateRunner) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_runner_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateRunnerResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateRunnerResponse{}\n\n// CreateRunnerResponse struct for CreateRunnerResponse\ntype CreateRunnerResponse struct {\n\t// The ID of the runner\n\tId string `json:\"id\"`\n\t// The API key for the runner\n\tApiKey string `json:\"apiKey\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateRunnerResponse CreateRunnerResponse\n\n// NewCreateRunnerResponse instantiates a new CreateRunnerResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateRunnerResponse(id string, apiKey string) *CreateRunnerResponse {\n\tthis := CreateRunnerResponse{}\n\tthis.Id = id\n\tthis.ApiKey = apiKey\n\treturn &this\n}\n\n// NewCreateRunnerResponseWithDefaults instantiates a new CreateRunnerResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateRunnerResponseWithDefaults() *CreateRunnerResponse {\n\tthis := CreateRunnerResponse{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *CreateRunnerResponse) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateRunnerResponse) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *CreateRunnerResponse) SetId(v string) {\n\to.Id = v\n}\n\n// GetApiKey returns the ApiKey field value\nfunc (o *CreateRunnerResponse) GetApiKey() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ApiKey\n}\n\n// GetApiKeyOk returns a tuple with the ApiKey field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateRunnerResponse) GetApiKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ApiKey, true\n}\n\n// SetApiKey sets field value\nfunc (o *CreateRunnerResponse) SetApiKey(v string) {\n\to.ApiKey = v\n}\n\nfunc (o CreateRunnerResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateRunnerResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"apiKey\"] = o.ApiKey\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateRunnerResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"apiKey\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateRunnerResponse := _CreateRunnerResponse{}\n\n\terr = json.Unmarshal(data, &varCreateRunnerResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateRunnerResponse(varCreateRunnerResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"apiKey\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateRunnerResponse struct {\n\tvalue *CreateRunnerResponse\n\tisSet bool\n}\n\nfunc (v NullableCreateRunnerResponse) Get() *CreateRunnerResponse {\n\treturn v.value\n}\n\nfunc (v *NullableCreateRunnerResponse) Set(val *CreateRunnerResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateRunnerResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateRunnerResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateRunnerResponse(val *CreateRunnerResponse) *NullableCreateRunnerResponse {\n\treturn &NullableCreateRunnerResponse{value: val, isSet: true}\n}\n\nfunc (v NullableCreateRunnerResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateRunnerResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_sandbox.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the CreateSandbox type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateSandbox{}\n\n// CreateSandbox struct for CreateSandbox\ntype CreateSandbox struct {\n\t// The name of the sandbox. If not provided, the sandbox ID will be used as the name\n\tName *string `json:\"name,omitempty\"`\n\t// The ID or name of the snapshot used for the sandbox\n\tSnapshot *string `json:\"snapshot,omitempty\"`\n\t// The user associated with the project\n\tUser *string `json:\"user,omitempty\"`\n\t// Environment variables for the sandbox\n\tEnv *map[string]string `json:\"env,omitempty\"`\n\t// Labels for the sandbox\n\tLabels *map[string]string `json:\"labels,omitempty\"`\n\t// Whether the sandbox http preview is publicly accessible\n\tPublic *bool `json:\"public,omitempty\"`\n\t// Whether to block all network access for the sandbox\n\tNetworkBlockAll *bool `json:\"networkBlockAll,omitempty\"`\n\t// Comma-separated list of allowed CIDR network addresses for the sandbox\n\tNetworkAllowList *string `json:\"networkAllowList,omitempty\"`\n\t// The sandbox class type\n\tClass *string `json:\"class,omitempty\"`\n\t// The target (region) where the sandbox will be created\n\tTarget *string `json:\"target,omitempty\"`\n\t// CPU cores allocated to the sandbox\n\tCpu *int32 `json:\"cpu,omitempty\"`\n\t// GPU units allocated to the sandbox\n\tGpu *int32 `json:\"gpu,omitempty\"`\n\t// Memory allocated to the sandbox in GB\n\tMemory *int32 `json:\"memory,omitempty\"`\n\t// Disk space allocated to the sandbox in GB\n\tDisk *int32 `json:\"disk,omitempty\"`\n\t// Auto-stop interval in minutes (0 means disabled)\n\tAutoStopInterval *int32 `json:\"autoStopInterval,omitempty\"`\n\t// Auto-archive interval in minutes (0 means the maximum interval will be used)\n\tAutoArchiveInterval *int32 `json:\"autoArchiveInterval,omitempty\"`\n\t// Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n\tAutoDeleteInterval *int32 `json:\"autoDeleteInterval,omitempty\"`\n\t// Array of volumes to attach to the sandbox\n\tVolumes []SandboxVolume `json:\"volumes,omitempty\"`\n\t// Build information for the sandbox\n\tBuildInfo *CreateBuildInfo `json:\"buildInfo,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateSandbox CreateSandbox\n\n// NewCreateSandbox instantiates a new CreateSandbox object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateSandbox() *CreateSandbox {\n\tthis := CreateSandbox{}\n\treturn &this\n}\n\n// NewCreateSandboxWithDefaults instantiates a new CreateSandbox object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateSandboxWithDefaults() *CreateSandbox {\n\tthis := CreateSandbox{}\n\treturn &this\n}\n\n// GetName returns the Name field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetName() string {\n\tif o == nil || IsNil(o.Name) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetNameOk() (*string, bool) {\n\tif o == nil || IsNil(o.Name) {\n\t\treturn nil, false\n\t}\n\treturn o.Name, true\n}\n\n// HasName returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasName() bool {\n\tif o != nil && !IsNil(o.Name) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetName gets a reference to the given string and assigns it to the Name field.\nfunc (o *CreateSandbox) SetName(v string) {\n\to.Name = &v\n}\n\n// GetSnapshot returns the Snapshot field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetSnapshot() string {\n\tif o == nil || IsNil(o.Snapshot) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Snapshot\n}\n\n// GetSnapshotOk returns a tuple with the Snapshot field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetSnapshotOk() (*string, bool) {\n\tif o == nil || IsNil(o.Snapshot) {\n\t\treturn nil, false\n\t}\n\treturn o.Snapshot, true\n}\n\n// HasSnapshot returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasSnapshot() bool {\n\tif o != nil && !IsNil(o.Snapshot) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshot gets a reference to the given string and assigns it to the Snapshot field.\nfunc (o *CreateSandbox) SetSnapshot(v string) {\n\to.Snapshot = &v\n}\n\n// GetUser returns the User field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetUser() string {\n\tif o == nil || IsNil(o.User) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.User\n}\n\n// GetUserOk returns a tuple with the User field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetUserOk() (*string, bool) {\n\tif o == nil || IsNil(o.User) {\n\t\treturn nil, false\n\t}\n\treturn o.User, true\n}\n\n// HasUser returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasUser() bool {\n\tif o != nil && !IsNil(o.User) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetUser gets a reference to the given string and assigns it to the User field.\nfunc (o *CreateSandbox) SetUser(v string) {\n\to.User = &v\n}\n\n// GetEnv returns the Env field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetEnv() map[string]string {\n\tif o == nil || IsNil(o.Env) {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\treturn *o.Env\n}\n\n// GetEnvOk returns a tuple with the Env field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetEnvOk() (*map[string]string, bool) {\n\tif o == nil || IsNil(o.Env) {\n\t\treturn nil, false\n\t}\n\treturn o.Env, true\n}\n\n// HasEnv returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasEnv() bool {\n\tif o != nil && !IsNil(o.Env) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetEnv gets a reference to the given map[string]string and assigns it to the Env field.\nfunc (o *CreateSandbox) SetEnv(v map[string]string) {\n\to.Env = &v\n}\n\n// GetLabels returns the Labels field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetLabels() map[string]string {\n\tif o == nil || IsNil(o.Labels) {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\treturn *o.Labels\n}\n\n// GetLabelsOk returns a tuple with the Labels field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetLabelsOk() (*map[string]string, bool) {\n\tif o == nil || IsNil(o.Labels) {\n\t\treturn nil, false\n\t}\n\treturn o.Labels, true\n}\n\n// HasLabels returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasLabels() bool {\n\tif o != nil && !IsNil(o.Labels) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetLabels gets a reference to the given map[string]string and assigns it to the Labels field.\nfunc (o *CreateSandbox) SetLabels(v map[string]string) {\n\to.Labels = &v\n}\n\n// GetPublic returns the Public field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetPublic() bool {\n\tif o == nil || IsNil(o.Public) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Public\n}\n\n// GetPublicOk returns a tuple with the Public field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetPublicOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Public) {\n\t\treturn nil, false\n\t}\n\treturn o.Public, true\n}\n\n// HasPublic returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasPublic() bool {\n\tif o != nil && !IsNil(o.Public) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPublic gets a reference to the given bool and assigns it to the Public field.\nfunc (o *CreateSandbox) SetPublic(v bool) {\n\to.Public = &v\n}\n\n// GetNetworkBlockAll returns the NetworkBlockAll field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetNetworkBlockAll() bool {\n\tif o == nil || IsNil(o.NetworkBlockAll) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.NetworkBlockAll\n}\n\n// GetNetworkBlockAllOk returns a tuple with the NetworkBlockAll field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetNetworkBlockAllOk() (*bool, bool) {\n\tif o == nil || IsNil(o.NetworkBlockAll) {\n\t\treturn nil, false\n\t}\n\treturn o.NetworkBlockAll, true\n}\n\n// HasNetworkBlockAll returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasNetworkBlockAll() bool {\n\tif o != nil && !IsNil(o.NetworkBlockAll) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetNetworkBlockAll gets a reference to the given bool and assigns it to the NetworkBlockAll field.\nfunc (o *CreateSandbox) SetNetworkBlockAll(v bool) {\n\to.NetworkBlockAll = &v\n}\n\n// GetNetworkAllowList returns the NetworkAllowList field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetNetworkAllowList() string {\n\tif o == nil || IsNil(o.NetworkAllowList) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.NetworkAllowList\n}\n\n// GetNetworkAllowListOk returns a tuple with the NetworkAllowList field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetNetworkAllowListOk() (*string, bool) {\n\tif o == nil || IsNil(o.NetworkAllowList) {\n\t\treturn nil, false\n\t}\n\treturn o.NetworkAllowList, true\n}\n\n// HasNetworkAllowList returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasNetworkAllowList() bool {\n\tif o != nil && !IsNil(o.NetworkAllowList) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetNetworkAllowList gets a reference to the given string and assigns it to the NetworkAllowList field.\nfunc (o *CreateSandbox) SetNetworkAllowList(v string) {\n\to.NetworkAllowList = &v\n}\n\n// GetClass returns the Class field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetClass() string {\n\tif o == nil || IsNil(o.Class) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Class\n}\n\n// GetClassOk returns a tuple with the Class field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetClassOk() (*string, bool) {\n\tif o == nil || IsNil(o.Class) {\n\t\treturn nil, false\n\t}\n\treturn o.Class, true\n}\n\n// HasClass returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasClass() bool {\n\tif o != nil && !IsNil(o.Class) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetClass gets a reference to the given string and assigns it to the Class field.\nfunc (o *CreateSandbox) SetClass(v string) {\n\to.Class = &v\n}\n\n// GetTarget returns the Target field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetTarget() string {\n\tif o == nil || IsNil(o.Target) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Target\n}\n\n// GetTargetOk returns a tuple with the Target field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetTargetOk() (*string, bool) {\n\tif o == nil || IsNil(o.Target) {\n\t\treturn nil, false\n\t}\n\treturn o.Target, true\n}\n\n// HasTarget returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasTarget() bool {\n\tif o != nil && !IsNil(o.Target) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTarget gets a reference to the given string and assigns it to the Target field.\nfunc (o *CreateSandbox) SetTarget(v string) {\n\to.Target = &v\n}\n\n// GetCpu returns the Cpu field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetCpu() int32 {\n\tif o == nil || IsNil(o.Cpu) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetCpuOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Cpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Cpu, true\n}\n\n// HasCpu returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasCpu() bool {\n\tif o != nil && !IsNil(o.Cpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCpu gets a reference to the given int32 and assigns it to the Cpu field.\nfunc (o *CreateSandbox) SetCpu(v int32) {\n\to.Cpu = &v\n}\n\n// GetGpu returns the Gpu field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetGpu() int32 {\n\tif o == nil || IsNil(o.Gpu) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Gpu\n}\n\n// GetGpuOk returns a tuple with the Gpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetGpuOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Gpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Gpu, true\n}\n\n// HasGpu returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasGpu() bool {\n\tif o != nil && !IsNil(o.Gpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetGpu gets a reference to the given int32 and assigns it to the Gpu field.\nfunc (o *CreateSandbox) SetGpu(v int32) {\n\to.Gpu = &v\n}\n\n// GetMemory returns the Memory field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetMemory() int32 {\n\tif o == nil || IsNil(o.Memory) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Memory\n}\n\n// GetMemoryOk returns a tuple with the Memory field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetMemoryOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Memory) {\n\t\treturn nil, false\n\t}\n\treturn o.Memory, true\n}\n\n// HasMemory returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasMemory() bool {\n\tif o != nil && !IsNil(o.Memory) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMemory gets a reference to the given int32 and assigns it to the Memory field.\nfunc (o *CreateSandbox) SetMemory(v int32) {\n\to.Memory = &v\n}\n\n// GetDisk returns the Disk field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetDisk() int32 {\n\tif o == nil || IsNil(o.Disk) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetDiskOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Disk) {\n\t\treturn nil, false\n\t}\n\treturn o.Disk, true\n}\n\n// HasDisk returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasDisk() bool {\n\tif o != nil && !IsNil(o.Disk) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDisk gets a reference to the given int32 and assigns it to the Disk field.\nfunc (o *CreateSandbox) SetDisk(v int32) {\n\to.Disk = &v\n}\n\n// GetAutoStopInterval returns the AutoStopInterval field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetAutoStopInterval() int32 {\n\tif o == nil || IsNil(o.AutoStopInterval) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.AutoStopInterval\n}\n\n// GetAutoStopIntervalOk returns a tuple with the AutoStopInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetAutoStopIntervalOk() (*int32, bool) {\n\tif o == nil || IsNil(o.AutoStopInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoStopInterval, true\n}\n\n// HasAutoStopInterval returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasAutoStopInterval() bool {\n\tif o != nil && !IsNil(o.AutoStopInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoStopInterval gets a reference to the given int32 and assigns it to the AutoStopInterval field.\nfunc (o *CreateSandbox) SetAutoStopInterval(v int32) {\n\to.AutoStopInterval = &v\n}\n\n// GetAutoArchiveInterval returns the AutoArchiveInterval field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetAutoArchiveInterval() int32 {\n\tif o == nil || IsNil(o.AutoArchiveInterval) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.AutoArchiveInterval\n}\n\n// GetAutoArchiveIntervalOk returns a tuple with the AutoArchiveInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetAutoArchiveIntervalOk() (*int32, bool) {\n\tif o == nil || IsNil(o.AutoArchiveInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoArchiveInterval, true\n}\n\n// HasAutoArchiveInterval returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasAutoArchiveInterval() bool {\n\tif o != nil && !IsNil(o.AutoArchiveInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoArchiveInterval gets a reference to the given int32 and assigns it to the AutoArchiveInterval field.\nfunc (o *CreateSandbox) SetAutoArchiveInterval(v int32) {\n\to.AutoArchiveInterval = &v\n}\n\n// GetAutoDeleteInterval returns the AutoDeleteInterval field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetAutoDeleteInterval() int32 {\n\tif o == nil || IsNil(o.AutoDeleteInterval) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.AutoDeleteInterval\n}\n\n// GetAutoDeleteIntervalOk returns a tuple with the AutoDeleteInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetAutoDeleteIntervalOk() (*int32, bool) {\n\tif o == nil || IsNil(o.AutoDeleteInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoDeleteInterval, true\n}\n\n// HasAutoDeleteInterval returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasAutoDeleteInterval() bool {\n\tif o != nil && !IsNil(o.AutoDeleteInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoDeleteInterval gets a reference to the given int32 and assigns it to the AutoDeleteInterval field.\nfunc (o *CreateSandbox) SetAutoDeleteInterval(v int32) {\n\to.AutoDeleteInterval = &v\n}\n\n// GetVolumes returns the Volumes field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetVolumes() []SandboxVolume {\n\tif o == nil || IsNil(o.Volumes) {\n\t\tvar ret []SandboxVolume\n\t\treturn ret\n\t}\n\treturn o.Volumes\n}\n\n// GetVolumesOk returns a tuple with the Volumes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetVolumesOk() ([]SandboxVolume, bool) {\n\tif o == nil || IsNil(o.Volumes) {\n\t\treturn nil, false\n\t}\n\treturn o.Volumes, true\n}\n\n// HasVolumes returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasVolumes() bool {\n\tif o != nil && !IsNil(o.Volumes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetVolumes gets a reference to the given []SandboxVolume and assigns it to the Volumes field.\nfunc (o *CreateSandbox) SetVolumes(v []SandboxVolume) {\n\to.Volumes = v\n}\n\n// GetBuildInfo returns the BuildInfo field value if set, zero value otherwise.\nfunc (o *CreateSandbox) GetBuildInfo() CreateBuildInfo {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\tvar ret CreateBuildInfo\n\t\treturn ret\n\t}\n\treturn *o.BuildInfo\n}\n\n// GetBuildInfoOk returns a tuple with the BuildInfo field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSandbox) GetBuildInfoOk() (*CreateBuildInfo, bool) {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\treturn nil, false\n\t}\n\treturn o.BuildInfo, true\n}\n\n// HasBuildInfo returns a boolean if a field has been set.\nfunc (o *CreateSandbox) HasBuildInfo() bool {\n\tif o != nil && !IsNil(o.BuildInfo) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBuildInfo gets a reference to the given CreateBuildInfo and assigns it to the BuildInfo field.\nfunc (o *CreateSandbox) SetBuildInfo(v CreateBuildInfo) {\n\to.BuildInfo = &v\n}\n\nfunc (o CreateSandbox) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateSandbox) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Name) {\n\t\ttoSerialize[\"name\"] = o.Name\n\t}\n\tif !IsNil(o.Snapshot) {\n\t\ttoSerialize[\"snapshot\"] = o.Snapshot\n\t}\n\tif !IsNil(o.User) {\n\t\ttoSerialize[\"user\"] = o.User\n\t}\n\tif !IsNil(o.Env) {\n\t\ttoSerialize[\"env\"] = o.Env\n\t}\n\tif !IsNil(o.Labels) {\n\t\ttoSerialize[\"labels\"] = o.Labels\n\t}\n\tif !IsNil(o.Public) {\n\t\ttoSerialize[\"public\"] = o.Public\n\t}\n\tif !IsNil(o.NetworkBlockAll) {\n\t\ttoSerialize[\"networkBlockAll\"] = o.NetworkBlockAll\n\t}\n\tif !IsNil(o.NetworkAllowList) {\n\t\ttoSerialize[\"networkAllowList\"] = o.NetworkAllowList\n\t}\n\tif !IsNil(o.Class) {\n\t\ttoSerialize[\"class\"] = o.Class\n\t}\n\tif !IsNil(o.Target) {\n\t\ttoSerialize[\"target\"] = o.Target\n\t}\n\tif !IsNil(o.Cpu) {\n\t\ttoSerialize[\"cpu\"] = o.Cpu\n\t}\n\tif !IsNil(o.Gpu) {\n\t\ttoSerialize[\"gpu\"] = o.Gpu\n\t}\n\tif !IsNil(o.Memory) {\n\t\ttoSerialize[\"memory\"] = o.Memory\n\t}\n\tif !IsNil(o.Disk) {\n\t\ttoSerialize[\"disk\"] = o.Disk\n\t}\n\tif !IsNil(o.AutoStopInterval) {\n\t\ttoSerialize[\"autoStopInterval\"] = o.AutoStopInterval\n\t}\n\tif !IsNil(o.AutoArchiveInterval) {\n\t\ttoSerialize[\"autoArchiveInterval\"] = o.AutoArchiveInterval\n\t}\n\tif !IsNil(o.AutoDeleteInterval) {\n\t\ttoSerialize[\"autoDeleteInterval\"] = o.AutoDeleteInterval\n\t}\n\tif !IsNil(o.Volumes) {\n\t\ttoSerialize[\"volumes\"] = o.Volumes\n\t}\n\tif !IsNil(o.BuildInfo) {\n\t\ttoSerialize[\"buildInfo\"] = o.BuildInfo\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateSandbox) UnmarshalJSON(data []byte) (err error) {\n\tvarCreateSandbox := _CreateSandbox{}\n\n\terr = json.Unmarshal(data, &varCreateSandbox)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateSandbox(varCreateSandbox)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"snapshot\")\n\t\tdelete(additionalProperties, \"user\")\n\t\tdelete(additionalProperties, \"env\")\n\t\tdelete(additionalProperties, \"labels\")\n\t\tdelete(additionalProperties, \"public\")\n\t\tdelete(additionalProperties, \"networkBlockAll\")\n\t\tdelete(additionalProperties, \"networkAllowList\")\n\t\tdelete(additionalProperties, \"class\")\n\t\tdelete(additionalProperties, \"target\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"gpu\")\n\t\tdelete(additionalProperties, \"memory\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\tdelete(additionalProperties, \"autoStopInterval\")\n\t\tdelete(additionalProperties, \"autoArchiveInterval\")\n\t\tdelete(additionalProperties, \"autoDeleteInterval\")\n\t\tdelete(additionalProperties, \"volumes\")\n\t\tdelete(additionalProperties, \"buildInfo\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateSandbox struct {\n\tvalue *CreateSandbox\n\tisSet bool\n}\n\nfunc (v NullableCreateSandbox) Get() *CreateSandbox {\n\treturn v.value\n}\n\nfunc (v *NullableCreateSandbox) Set(val *CreateSandbox) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateSandbox) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateSandbox) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateSandbox(val *CreateSandbox) *NullableCreateSandbox {\n\treturn &NullableCreateSandbox{value: val, isSet: true}\n}\n\nfunc (v NullableCreateSandbox) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateSandbox) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_session_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateSessionRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateSessionRequest{}\n\n// CreateSessionRequest struct for CreateSessionRequest\ntype CreateSessionRequest struct {\n\t// The ID of the session\n\tSessionId string `json:\"sessionId\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateSessionRequest CreateSessionRequest\n\n// NewCreateSessionRequest instantiates a new CreateSessionRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateSessionRequest(sessionId string) *CreateSessionRequest {\n\tthis := CreateSessionRequest{}\n\tthis.SessionId = sessionId\n\treturn &this\n}\n\n// NewCreateSessionRequestWithDefaults instantiates a new CreateSessionRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateSessionRequestWithDefaults() *CreateSessionRequest {\n\tthis := CreateSessionRequest{}\n\treturn &this\n}\n\n// GetSessionId returns the SessionId field value\nfunc (o *CreateSessionRequest) GetSessionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SessionId\n}\n\n// GetSessionIdOk returns a tuple with the SessionId field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateSessionRequest) GetSessionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SessionId, true\n}\n\n// SetSessionId sets field value\nfunc (o *CreateSessionRequest) SetSessionId(v string) {\n\to.SessionId = v\n}\n\nfunc (o CreateSessionRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateSessionRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"sessionId\"] = o.SessionId\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateSessionRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"sessionId\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateSessionRequest := _CreateSessionRequest{}\n\n\terr = json.Unmarshal(data, &varCreateSessionRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateSessionRequest(varCreateSessionRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"sessionId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateSessionRequest struct {\n\tvalue *CreateSessionRequest\n\tisSet bool\n}\n\nfunc (v NullableCreateSessionRequest) Get() *CreateSessionRequest {\n\treturn v.value\n}\n\nfunc (v *NullableCreateSessionRequest) Set(val *CreateSessionRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateSessionRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateSessionRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateSessionRequest(val *CreateSessionRequest) *NullableCreateSessionRequest {\n\treturn &NullableCreateSessionRequest{value: val, isSet: true}\n}\n\nfunc (v NullableCreateSessionRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateSessionRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_snapshot.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateSnapshot type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateSnapshot{}\n\n// CreateSnapshot struct for CreateSnapshot\ntype CreateSnapshot struct {\n\t// The name of the snapshot\n\tName string `json:\"name\"`\n\t// The image name of the snapshot\n\tImageName *string `json:\"imageName,omitempty\"`\n\t// The entrypoint command for the snapshot\n\tEntrypoint []string `json:\"entrypoint,omitempty\"`\n\t// Whether the snapshot is general\n\tGeneral *bool `json:\"general,omitempty\"`\n\t// CPU cores allocated to the resulting sandbox\n\tCpu *int32 `json:\"cpu,omitempty\"`\n\t// GPU units allocated to the resulting sandbox\n\tGpu *int32 `json:\"gpu,omitempty\"`\n\t// Memory allocated to the resulting sandbox in GB\n\tMemory *int32 `json:\"memory,omitempty\"`\n\t// Disk space allocated to the sandbox in GB\n\tDisk *int32 `json:\"disk,omitempty\"`\n\t// Build information for the snapshot\n\tBuildInfo *CreateBuildInfo `json:\"buildInfo,omitempty\"`\n\t// ID of the region where the snapshot will be available. Defaults to organization default region if not specified.\n\tRegionId *string `json:\"regionId,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateSnapshot CreateSnapshot\n\n// NewCreateSnapshot instantiates a new CreateSnapshot object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateSnapshot(name string) *CreateSnapshot {\n\tthis := CreateSnapshot{}\n\tthis.Name = name\n\treturn &this\n}\n\n// NewCreateSnapshotWithDefaults instantiates a new CreateSnapshot object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateSnapshotWithDefaults() *CreateSnapshot {\n\tthis := CreateSnapshot{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *CreateSnapshot) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateSnapshot) SetName(v string) {\n\to.Name = v\n}\n\n// GetImageName returns the ImageName field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetImageName() string {\n\tif o == nil || IsNil(o.ImageName) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ImageName\n}\n\n// GetImageNameOk returns a tuple with the ImageName field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetImageNameOk() (*string, bool) {\n\tif o == nil || IsNil(o.ImageName) {\n\t\treturn nil, false\n\t}\n\treturn o.ImageName, true\n}\n\n// HasImageName returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasImageName() bool {\n\tif o != nil && !IsNil(o.ImageName) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetImageName gets a reference to the given string and assigns it to the ImageName field.\nfunc (o *CreateSnapshot) SetImageName(v string) {\n\to.ImageName = &v\n}\n\n// GetEntrypoint returns the Entrypoint field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetEntrypoint() []string {\n\tif o == nil || IsNil(o.Entrypoint) {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\treturn o.Entrypoint\n}\n\n// GetEntrypointOk returns a tuple with the Entrypoint field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetEntrypointOk() ([]string, bool) {\n\tif o == nil || IsNil(o.Entrypoint) {\n\t\treturn nil, false\n\t}\n\treturn o.Entrypoint, true\n}\n\n// HasEntrypoint returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasEntrypoint() bool {\n\tif o != nil && !IsNil(o.Entrypoint) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetEntrypoint gets a reference to the given []string and assigns it to the Entrypoint field.\nfunc (o *CreateSnapshot) SetEntrypoint(v []string) {\n\to.Entrypoint = v\n}\n\n// GetGeneral returns the General field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetGeneral() bool {\n\tif o == nil || IsNil(o.General) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.General\n}\n\n// GetGeneralOk returns a tuple with the General field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetGeneralOk() (*bool, bool) {\n\tif o == nil || IsNil(o.General) {\n\t\treturn nil, false\n\t}\n\treturn o.General, true\n}\n\n// HasGeneral returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasGeneral() bool {\n\tif o != nil && !IsNil(o.General) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetGeneral gets a reference to the given bool and assigns it to the General field.\nfunc (o *CreateSnapshot) SetGeneral(v bool) {\n\to.General = &v\n}\n\n// GetCpu returns the Cpu field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetCpu() int32 {\n\tif o == nil || IsNil(o.Cpu) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetCpuOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Cpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Cpu, true\n}\n\n// HasCpu returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasCpu() bool {\n\tif o != nil && !IsNil(o.Cpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCpu gets a reference to the given int32 and assigns it to the Cpu field.\nfunc (o *CreateSnapshot) SetCpu(v int32) {\n\to.Cpu = &v\n}\n\n// GetGpu returns the Gpu field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetGpu() int32 {\n\tif o == nil || IsNil(o.Gpu) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Gpu\n}\n\n// GetGpuOk returns a tuple with the Gpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetGpuOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Gpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Gpu, true\n}\n\n// HasGpu returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasGpu() bool {\n\tif o != nil && !IsNil(o.Gpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetGpu gets a reference to the given int32 and assigns it to the Gpu field.\nfunc (o *CreateSnapshot) SetGpu(v int32) {\n\to.Gpu = &v\n}\n\n// GetMemory returns the Memory field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetMemory() int32 {\n\tif o == nil || IsNil(o.Memory) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Memory\n}\n\n// GetMemoryOk returns a tuple with the Memory field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetMemoryOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Memory) {\n\t\treturn nil, false\n\t}\n\treturn o.Memory, true\n}\n\n// HasMemory returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasMemory() bool {\n\tif o != nil && !IsNil(o.Memory) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMemory gets a reference to the given int32 and assigns it to the Memory field.\nfunc (o *CreateSnapshot) SetMemory(v int32) {\n\to.Memory = &v\n}\n\n// GetDisk returns the Disk field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetDisk() int32 {\n\tif o == nil || IsNil(o.Disk) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetDiskOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Disk) {\n\t\treturn nil, false\n\t}\n\treturn o.Disk, true\n}\n\n// HasDisk returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasDisk() bool {\n\tif o != nil && !IsNil(o.Disk) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDisk gets a reference to the given int32 and assigns it to the Disk field.\nfunc (o *CreateSnapshot) SetDisk(v int32) {\n\to.Disk = &v\n}\n\n// GetBuildInfo returns the BuildInfo field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetBuildInfo() CreateBuildInfo {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\tvar ret CreateBuildInfo\n\t\treturn ret\n\t}\n\treturn *o.BuildInfo\n}\n\n// GetBuildInfoOk returns a tuple with the BuildInfo field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetBuildInfoOk() (*CreateBuildInfo, bool) {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\treturn nil, false\n\t}\n\treturn o.BuildInfo, true\n}\n\n// HasBuildInfo returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasBuildInfo() bool {\n\tif o != nil && !IsNil(o.BuildInfo) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBuildInfo gets a reference to the given CreateBuildInfo and assigns it to the BuildInfo field.\nfunc (o *CreateSnapshot) SetBuildInfo(v CreateBuildInfo) {\n\to.BuildInfo = &v\n}\n\n// GetRegionId returns the RegionId field value if set, zero value otherwise.\nfunc (o *CreateSnapshot) GetRegionId() string {\n\tif o == nil || IsNil(o.RegionId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.RegionId\n}\n\n// GetRegionIdOk returns a tuple with the RegionId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateSnapshot) GetRegionIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.RegionId) {\n\t\treturn nil, false\n\t}\n\treturn o.RegionId, true\n}\n\n// HasRegionId returns a boolean if a field has been set.\nfunc (o *CreateSnapshot) HasRegionId() bool {\n\tif o != nil && !IsNil(o.RegionId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRegionId gets a reference to the given string and assigns it to the RegionId field.\nfunc (o *CreateSnapshot) SetRegionId(v string) {\n\to.RegionId = &v\n}\n\nfunc (o CreateSnapshot) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateSnapshot) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\tif !IsNil(o.ImageName) {\n\t\ttoSerialize[\"imageName\"] = o.ImageName\n\t}\n\tif !IsNil(o.Entrypoint) {\n\t\ttoSerialize[\"entrypoint\"] = o.Entrypoint\n\t}\n\tif !IsNil(o.General) {\n\t\ttoSerialize[\"general\"] = o.General\n\t}\n\tif !IsNil(o.Cpu) {\n\t\ttoSerialize[\"cpu\"] = o.Cpu\n\t}\n\tif !IsNil(o.Gpu) {\n\t\ttoSerialize[\"gpu\"] = o.Gpu\n\t}\n\tif !IsNil(o.Memory) {\n\t\ttoSerialize[\"memory\"] = o.Memory\n\t}\n\tif !IsNil(o.Disk) {\n\t\ttoSerialize[\"disk\"] = o.Disk\n\t}\n\tif !IsNil(o.BuildInfo) {\n\t\ttoSerialize[\"buildInfo\"] = o.BuildInfo\n\t}\n\tif !IsNil(o.RegionId) {\n\t\ttoSerialize[\"regionId\"] = o.RegionId\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateSnapshot) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateSnapshot := _CreateSnapshot{}\n\n\terr = json.Unmarshal(data, &varCreateSnapshot)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateSnapshot(varCreateSnapshot)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"imageName\")\n\t\tdelete(additionalProperties, \"entrypoint\")\n\t\tdelete(additionalProperties, \"general\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"gpu\")\n\t\tdelete(additionalProperties, \"memory\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\tdelete(additionalProperties, \"buildInfo\")\n\t\tdelete(additionalProperties, \"regionId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateSnapshot struct {\n\tvalue *CreateSnapshot\n\tisSet bool\n}\n\nfunc (v NullableCreateSnapshot) Get() *CreateSnapshot {\n\treturn v.value\n}\n\nfunc (v *NullableCreateSnapshot) Set(val *CreateSnapshot) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateSnapshot) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateSnapshot) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateSnapshot(val *CreateSnapshot) *NullableCreateSnapshot {\n\treturn &NullableCreateSnapshot{value: val, isSet: true}\n}\n\nfunc (v NullableCreateSnapshot) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateSnapshot) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_user.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateUser type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateUser{}\n\n// CreateUser struct for CreateUser\ntype CreateUser struct {\n\tId string `json:\"id\"`\n\tName string `json:\"name\"`\n\tEmail *string `json:\"email,omitempty\"`\n\tPersonalOrganizationQuota *CreateOrganizationQuota `json:\"personalOrganizationQuota,omitempty\"`\n\tPersonalOrganizationDefaultRegionId *string `json:\"personalOrganizationDefaultRegionId,omitempty\"`\n\tRole *string `json:\"role,omitempty\"`\n\tEmailVerified *bool `json:\"emailVerified,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateUser CreateUser\n\n// NewCreateUser instantiates a new CreateUser object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateUser(id string, name string) *CreateUser {\n\tthis := CreateUser{}\n\tthis.Id = id\n\tthis.Name = name\n\treturn &this\n}\n\n// NewCreateUserWithDefaults instantiates a new CreateUser object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateUserWithDefaults() *CreateUser {\n\tthis := CreateUser{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *CreateUser) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateUser) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *CreateUser) SetId(v string) {\n\to.Id = v\n}\n\n// GetName returns the Name field value\nfunc (o *CreateUser) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateUser) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateUser) SetName(v string) {\n\to.Name = v\n}\n\n// GetEmail returns the Email field value if set, zero value otherwise.\nfunc (o *CreateUser) GetEmail() string {\n\tif o == nil || IsNil(o.Email) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Email\n}\n\n// GetEmailOk returns a tuple with the Email field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateUser) GetEmailOk() (*string, bool) {\n\tif o == nil || IsNil(o.Email) {\n\t\treturn nil, false\n\t}\n\treturn o.Email, true\n}\n\n// HasEmail returns a boolean if a field has been set.\nfunc (o *CreateUser) HasEmail() bool {\n\tif o != nil && !IsNil(o.Email) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetEmail gets a reference to the given string and assigns it to the Email field.\nfunc (o *CreateUser) SetEmail(v string) {\n\to.Email = &v\n}\n\n// GetPersonalOrganizationQuota returns the PersonalOrganizationQuota field value if set, zero value otherwise.\nfunc (o *CreateUser) GetPersonalOrganizationQuota() CreateOrganizationQuota {\n\tif o == nil || IsNil(o.PersonalOrganizationQuota) {\n\t\tvar ret CreateOrganizationQuota\n\t\treturn ret\n\t}\n\treturn *o.PersonalOrganizationQuota\n}\n\n// GetPersonalOrganizationQuotaOk returns a tuple with the PersonalOrganizationQuota field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateUser) GetPersonalOrganizationQuotaOk() (*CreateOrganizationQuota, bool) {\n\tif o == nil || IsNil(o.PersonalOrganizationQuota) {\n\t\treturn nil, false\n\t}\n\treturn o.PersonalOrganizationQuota, true\n}\n\n// HasPersonalOrganizationQuota returns a boolean if a field has been set.\nfunc (o *CreateUser) HasPersonalOrganizationQuota() bool {\n\tif o != nil && !IsNil(o.PersonalOrganizationQuota) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPersonalOrganizationQuota gets a reference to the given CreateOrganizationQuota and assigns it to the PersonalOrganizationQuota field.\nfunc (o *CreateUser) SetPersonalOrganizationQuota(v CreateOrganizationQuota) {\n\to.PersonalOrganizationQuota = &v\n}\n\n// GetPersonalOrganizationDefaultRegionId returns the PersonalOrganizationDefaultRegionId field value if set, zero value otherwise.\nfunc (o *CreateUser) GetPersonalOrganizationDefaultRegionId() string {\n\tif o == nil || IsNil(o.PersonalOrganizationDefaultRegionId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.PersonalOrganizationDefaultRegionId\n}\n\n// GetPersonalOrganizationDefaultRegionIdOk returns a tuple with the PersonalOrganizationDefaultRegionId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateUser) GetPersonalOrganizationDefaultRegionIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.PersonalOrganizationDefaultRegionId) {\n\t\treturn nil, false\n\t}\n\treturn o.PersonalOrganizationDefaultRegionId, true\n}\n\n// HasPersonalOrganizationDefaultRegionId returns a boolean if a field has been set.\nfunc (o *CreateUser) HasPersonalOrganizationDefaultRegionId() bool {\n\tif o != nil && !IsNil(o.PersonalOrganizationDefaultRegionId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPersonalOrganizationDefaultRegionId gets a reference to the given string and assigns it to the PersonalOrganizationDefaultRegionId field.\nfunc (o *CreateUser) SetPersonalOrganizationDefaultRegionId(v string) {\n\to.PersonalOrganizationDefaultRegionId = &v\n}\n\n// GetRole returns the Role field value if set, zero value otherwise.\nfunc (o *CreateUser) GetRole() string {\n\tif o == nil || IsNil(o.Role) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Role\n}\n\n// GetRoleOk returns a tuple with the Role field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateUser) GetRoleOk() (*string, bool) {\n\tif o == nil || IsNil(o.Role) {\n\t\treturn nil, false\n\t}\n\treturn o.Role, true\n}\n\n// HasRole returns a boolean if a field has been set.\nfunc (o *CreateUser) HasRole() bool {\n\tif o != nil && !IsNil(o.Role) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRole gets a reference to the given string and assigns it to the Role field.\nfunc (o *CreateUser) SetRole(v string) {\n\to.Role = &v\n}\n\n// GetEmailVerified returns the EmailVerified field value if set, zero value otherwise.\nfunc (o *CreateUser) GetEmailVerified() bool {\n\tif o == nil || IsNil(o.EmailVerified) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.EmailVerified\n}\n\n// GetEmailVerifiedOk returns a tuple with the EmailVerified field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateUser) GetEmailVerifiedOk() (*bool, bool) {\n\tif o == nil || IsNil(o.EmailVerified) {\n\t\treturn nil, false\n\t}\n\treturn o.EmailVerified, true\n}\n\n// HasEmailVerified returns a boolean if a field has been set.\nfunc (o *CreateUser) HasEmailVerified() bool {\n\tif o != nil && !IsNil(o.EmailVerified) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetEmailVerified gets a reference to the given bool and assigns it to the EmailVerified field.\nfunc (o *CreateUser) SetEmailVerified(v bool) {\n\to.EmailVerified = &v\n}\n\nfunc (o CreateUser) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateUser) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"name\"] = o.Name\n\tif !IsNil(o.Email) {\n\t\ttoSerialize[\"email\"] = o.Email\n\t}\n\tif !IsNil(o.PersonalOrganizationQuota) {\n\t\ttoSerialize[\"personalOrganizationQuota\"] = o.PersonalOrganizationQuota\n\t}\n\tif !IsNil(o.PersonalOrganizationDefaultRegionId) {\n\t\ttoSerialize[\"personalOrganizationDefaultRegionId\"] = o.PersonalOrganizationDefaultRegionId\n\t}\n\tif !IsNil(o.Role) {\n\t\ttoSerialize[\"role\"] = o.Role\n\t}\n\tif !IsNil(o.EmailVerified) {\n\t\ttoSerialize[\"emailVerified\"] = o.EmailVerified\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateUser) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateUser := _CreateUser{}\n\n\terr = json.Unmarshal(data, &varCreateUser)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateUser(varCreateUser)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"email\")\n\t\tdelete(additionalProperties, \"personalOrganizationQuota\")\n\t\tdelete(additionalProperties, \"personalOrganizationDefaultRegionId\")\n\t\tdelete(additionalProperties, \"role\")\n\t\tdelete(additionalProperties, \"emailVerified\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateUser struct {\n\tvalue *CreateUser\n\tisSet bool\n}\n\nfunc (v NullableCreateUser) Get() *CreateUser {\n\treturn v.value\n}\n\nfunc (v *NullableCreateUser) Set(val *CreateUser) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateUser) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateUser) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateUser(val *CreateUser) *NullableCreateUser {\n\treturn &NullableCreateUser{value: val, isSet: true}\n}\n\nfunc (v NullableCreateUser) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateUser) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_volume.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the CreateVolume type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateVolume{}\n\n// CreateVolume struct for CreateVolume\ntype CreateVolume struct {\n\tName string `json:\"name\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateVolume CreateVolume\n\n// NewCreateVolume instantiates a new CreateVolume object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateVolume(name string) *CreateVolume {\n\tthis := CreateVolume{}\n\tthis.Name = name\n\treturn &this\n}\n\n// NewCreateVolumeWithDefaults instantiates a new CreateVolume object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateVolumeWithDefaults() *CreateVolume {\n\tthis := CreateVolume{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *CreateVolume) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *CreateVolume) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *CreateVolume) SetName(v string) {\n\to.Name = v\n}\n\nfunc (o CreateVolume) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateVolume) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateVolume) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarCreateVolume := _CreateVolume{}\n\n\terr = json.Unmarshal(data, &varCreateVolume)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateVolume(varCreateVolume)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateVolume struct {\n\tvalue *CreateVolume\n\tisSet bool\n}\n\nfunc (v NullableCreateVolume) Get() *CreateVolume {\n\treturn v.value\n}\n\nfunc (v *NullableCreateVolume) Set(val *CreateVolume) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateVolume) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateVolume) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateVolume(val *CreateVolume) *NullableCreateVolume {\n\treturn &NullableCreateVolume{value: val, isSet: true}\n}\n\nfunc (v NullableCreateVolume) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateVolume) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_create_workspace.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the CreateWorkspace type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &CreateWorkspace{}\n\n// CreateWorkspace struct for CreateWorkspace\ntype CreateWorkspace struct {\n\t// The image used for the workspace\n\tImage *string `json:\"image,omitempty\"`\n\t// The user associated with the project\n\tUser *string `json:\"user,omitempty\"`\n\t// Environment variables for the workspace\n\tEnv *map[string]string `json:\"env,omitempty\"`\n\t// Labels for the workspace\n\tLabels *map[string]string `json:\"labels,omitempty\"`\n\t// Whether the workspace http preview is publicly accessible\n\tPublic *bool `json:\"public,omitempty\"`\n\t// The workspace class type\n\tClass *string `json:\"class,omitempty\"`\n\t// The target (region) where the workspace will be created\n\tTarget *string `json:\"target,omitempty\"`\n\t// CPU cores allocated to the workspace\n\tCpu *int32 `json:\"cpu,omitempty\"`\n\t// GPU units allocated to the workspace\n\tGpu *int32 `json:\"gpu,omitempty\"`\n\t// Memory allocated to the workspace in GB\n\tMemory *int32 `json:\"memory,omitempty\"`\n\t// Disk space allocated to the workspace in GB\n\tDisk *int32 `json:\"disk,omitempty\"`\n\t// Auto-stop interval in minutes (0 means disabled)\n\tAutoStopInterval *int32 `json:\"autoStopInterval,omitempty\"`\n\t// Auto-archive interval in minutes (0 means the maximum interval will be used)\n\tAutoArchiveInterval *int32 `json:\"autoArchiveInterval,omitempty\"`\n\t// Array of volumes to attach to the workspace\n\tVolumes []SandboxVolume `json:\"volumes,omitempty\"`\n\t// Build information for the workspace\n\tBuildInfo *CreateBuildInfo `json:\"buildInfo,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _CreateWorkspace CreateWorkspace\n\n// NewCreateWorkspace instantiates a new CreateWorkspace object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewCreateWorkspace() *CreateWorkspace {\n\tthis := CreateWorkspace{}\n\treturn &this\n}\n\n// NewCreateWorkspaceWithDefaults instantiates a new CreateWorkspace object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewCreateWorkspaceWithDefaults() *CreateWorkspace {\n\tthis := CreateWorkspace{}\n\treturn &this\n}\n\n// GetImage returns the Image field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetImage() string {\n\tif o == nil || IsNil(o.Image) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Image\n}\n\n// GetImageOk returns a tuple with the Image field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetImageOk() (*string, bool) {\n\tif o == nil || IsNil(o.Image) {\n\t\treturn nil, false\n\t}\n\treturn o.Image, true\n}\n\n// HasImage returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasImage() bool {\n\tif o != nil && !IsNil(o.Image) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetImage gets a reference to the given string and assigns it to the Image field.\nfunc (o *CreateWorkspace) SetImage(v string) {\n\to.Image = &v\n}\n\n// GetUser returns the User field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetUser() string {\n\tif o == nil || IsNil(o.User) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.User\n}\n\n// GetUserOk returns a tuple with the User field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetUserOk() (*string, bool) {\n\tif o == nil || IsNil(o.User) {\n\t\treturn nil, false\n\t}\n\treturn o.User, true\n}\n\n// HasUser returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasUser() bool {\n\tif o != nil && !IsNil(o.User) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetUser gets a reference to the given string and assigns it to the User field.\nfunc (o *CreateWorkspace) SetUser(v string) {\n\to.User = &v\n}\n\n// GetEnv returns the Env field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetEnv() map[string]string {\n\tif o == nil || IsNil(o.Env) {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\treturn *o.Env\n}\n\n// GetEnvOk returns a tuple with the Env field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetEnvOk() (*map[string]string, bool) {\n\tif o == nil || IsNil(o.Env) {\n\t\treturn nil, false\n\t}\n\treturn o.Env, true\n}\n\n// HasEnv returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasEnv() bool {\n\tif o != nil && !IsNil(o.Env) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetEnv gets a reference to the given map[string]string and assigns it to the Env field.\nfunc (o *CreateWorkspace) SetEnv(v map[string]string) {\n\to.Env = &v\n}\n\n// GetLabels returns the Labels field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetLabels() map[string]string {\n\tif o == nil || IsNil(o.Labels) {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\treturn *o.Labels\n}\n\n// GetLabelsOk returns a tuple with the Labels field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetLabelsOk() (*map[string]string, bool) {\n\tif o == nil || IsNil(o.Labels) {\n\t\treturn nil, false\n\t}\n\treturn o.Labels, true\n}\n\n// HasLabels returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasLabels() bool {\n\tif o != nil && !IsNil(o.Labels) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetLabels gets a reference to the given map[string]string and assigns it to the Labels field.\nfunc (o *CreateWorkspace) SetLabels(v map[string]string) {\n\to.Labels = &v\n}\n\n// GetPublic returns the Public field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetPublic() bool {\n\tif o == nil || IsNil(o.Public) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Public\n}\n\n// GetPublicOk returns a tuple with the Public field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetPublicOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Public) {\n\t\treturn nil, false\n\t}\n\treturn o.Public, true\n}\n\n// HasPublic returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasPublic() bool {\n\tif o != nil && !IsNil(o.Public) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPublic gets a reference to the given bool and assigns it to the Public field.\nfunc (o *CreateWorkspace) SetPublic(v bool) {\n\to.Public = &v\n}\n\n// GetClass returns the Class field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetClass() string {\n\tif o == nil || IsNil(o.Class) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Class\n}\n\n// GetClassOk returns a tuple with the Class field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetClassOk() (*string, bool) {\n\tif o == nil || IsNil(o.Class) {\n\t\treturn nil, false\n\t}\n\treturn o.Class, true\n}\n\n// HasClass returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasClass() bool {\n\tif o != nil && !IsNil(o.Class) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetClass gets a reference to the given string and assigns it to the Class field.\nfunc (o *CreateWorkspace) SetClass(v string) {\n\to.Class = &v\n}\n\n// GetTarget returns the Target field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetTarget() string {\n\tif o == nil || IsNil(o.Target) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Target\n}\n\n// GetTargetOk returns a tuple with the Target field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetTargetOk() (*string, bool) {\n\tif o == nil || IsNil(o.Target) {\n\t\treturn nil, false\n\t}\n\treturn o.Target, true\n}\n\n// HasTarget returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasTarget() bool {\n\tif o != nil && !IsNil(o.Target) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTarget gets a reference to the given string and assigns it to the Target field.\nfunc (o *CreateWorkspace) SetTarget(v string) {\n\to.Target = &v\n}\n\n// GetCpu returns the Cpu field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetCpu() int32 {\n\tif o == nil || IsNil(o.Cpu) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetCpuOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Cpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Cpu, true\n}\n\n// HasCpu returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasCpu() bool {\n\tif o != nil && !IsNil(o.Cpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCpu gets a reference to the given int32 and assigns it to the Cpu field.\nfunc (o *CreateWorkspace) SetCpu(v int32) {\n\to.Cpu = &v\n}\n\n// GetGpu returns the Gpu field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetGpu() int32 {\n\tif o == nil || IsNil(o.Gpu) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Gpu\n}\n\n// GetGpuOk returns a tuple with the Gpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetGpuOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Gpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Gpu, true\n}\n\n// HasGpu returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasGpu() bool {\n\tif o != nil && !IsNil(o.Gpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetGpu gets a reference to the given int32 and assigns it to the Gpu field.\nfunc (o *CreateWorkspace) SetGpu(v int32) {\n\to.Gpu = &v\n}\n\n// GetMemory returns the Memory field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetMemory() int32 {\n\tif o == nil || IsNil(o.Memory) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Memory\n}\n\n// GetMemoryOk returns a tuple with the Memory field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetMemoryOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Memory) {\n\t\treturn nil, false\n\t}\n\treturn o.Memory, true\n}\n\n// HasMemory returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasMemory() bool {\n\tif o != nil && !IsNil(o.Memory) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMemory gets a reference to the given int32 and assigns it to the Memory field.\nfunc (o *CreateWorkspace) SetMemory(v int32) {\n\to.Memory = &v\n}\n\n// GetDisk returns the Disk field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetDisk() int32 {\n\tif o == nil || IsNil(o.Disk) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetDiskOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Disk) {\n\t\treturn nil, false\n\t}\n\treturn o.Disk, true\n}\n\n// HasDisk returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasDisk() bool {\n\tif o != nil && !IsNil(o.Disk) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDisk gets a reference to the given int32 and assigns it to the Disk field.\nfunc (o *CreateWorkspace) SetDisk(v int32) {\n\to.Disk = &v\n}\n\n// GetAutoStopInterval returns the AutoStopInterval field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetAutoStopInterval() int32 {\n\tif o == nil || IsNil(o.AutoStopInterval) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.AutoStopInterval\n}\n\n// GetAutoStopIntervalOk returns a tuple with the AutoStopInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetAutoStopIntervalOk() (*int32, bool) {\n\tif o == nil || IsNil(o.AutoStopInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoStopInterval, true\n}\n\n// HasAutoStopInterval returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasAutoStopInterval() bool {\n\tif o != nil && !IsNil(o.AutoStopInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoStopInterval gets a reference to the given int32 and assigns it to the AutoStopInterval field.\nfunc (o *CreateWorkspace) SetAutoStopInterval(v int32) {\n\to.AutoStopInterval = &v\n}\n\n// GetAutoArchiveInterval returns the AutoArchiveInterval field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetAutoArchiveInterval() int32 {\n\tif o == nil || IsNil(o.AutoArchiveInterval) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.AutoArchiveInterval\n}\n\n// GetAutoArchiveIntervalOk returns a tuple with the AutoArchiveInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetAutoArchiveIntervalOk() (*int32, bool) {\n\tif o == nil || IsNil(o.AutoArchiveInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoArchiveInterval, true\n}\n\n// HasAutoArchiveInterval returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasAutoArchiveInterval() bool {\n\tif o != nil && !IsNil(o.AutoArchiveInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoArchiveInterval gets a reference to the given int32 and assigns it to the AutoArchiveInterval field.\nfunc (o *CreateWorkspace) SetAutoArchiveInterval(v int32) {\n\to.AutoArchiveInterval = &v\n}\n\n// GetVolumes returns the Volumes field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetVolumes() []SandboxVolume {\n\tif o == nil || IsNil(o.Volumes) {\n\t\tvar ret []SandboxVolume\n\t\treturn ret\n\t}\n\treturn o.Volumes\n}\n\n// GetVolumesOk returns a tuple with the Volumes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetVolumesOk() ([]SandboxVolume, bool) {\n\tif o == nil || IsNil(o.Volumes) {\n\t\treturn nil, false\n\t}\n\treturn o.Volumes, true\n}\n\n// HasVolumes returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasVolumes() bool {\n\tif o != nil && !IsNil(o.Volumes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetVolumes gets a reference to the given []SandboxVolume and assigns it to the Volumes field.\nfunc (o *CreateWorkspace) SetVolumes(v []SandboxVolume) {\n\to.Volumes = v\n}\n\n// GetBuildInfo returns the BuildInfo field value if set, zero value otherwise.\nfunc (o *CreateWorkspace) GetBuildInfo() CreateBuildInfo {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\tvar ret CreateBuildInfo\n\t\treturn ret\n\t}\n\treturn *o.BuildInfo\n}\n\n// GetBuildInfoOk returns a tuple with the BuildInfo field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *CreateWorkspace) GetBuildInfoOk() (*CreateBuildInfo, bool) {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\treturn nil, false\n\t}\n\treturn o.BuildInfo, true\n}\n\n// HasBuildInfo returns a boolean if a field has been set.\nfunc (o *CreateWorkspace) HasBuildInfo() bool {\n\tif o != nil && !IsNil(o.BuildInfo) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBuildInfo gets a reference to the given CreateBuildInfo and assigns it to the BuildInfo field.\nfunc (o *CreateWorkspace) SetBuildInfo(v CreateBuildInfo) {\n\to.BuildInfo = &v\n}\n\nfunc (o CreateWorkspace) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o CreateWorkspace) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Image) {\n\t\ttoSerialize[\"image\"] = o.Image\n\t}\n\tif !IsNil(o.User) {\n\t\ttoSerialize[\"user\"] = o.User\n\t}\n\tif !IsNil(o.Env) {\n\t\ttoSerialize[\"env\"] = o.Env\n\t}\n\tif !IsNil(o.Labels) {\n\t\ttoSerialize[\"labels\"] = o.Labels\n\t}\n\tif !IsNil(o.Public) {\n\t\ttoSerialize[\"public\"] = o.Public\n\t}\n\tif !IsNil(o.Class) {\n\t\ttoSerialize[\"class\"] = o.Class\n\t}\n\tif !IsNil(o.Target) {\n\t\ttoSerialize[\"target\"] = o.Target\n\t}\n\tif !IsNil(o.Cpu) {\n\t\ttoSerialize[\"cpu\"] = o.Cpu\n\t}\n\tif !IsNil(o.Gpu) {\n\t\ttoSerialize[\"gpu\"] = o.Gpu\n\t}\n\tif !IsNil(o.Memory) {\n\t\ttoSerialize[\"memory\"] = o.Memory\n\t}\n\tif !IsNil(o.Disk) {\n\t\ttoSerialize[\"disk\"] = o.Disk\n\t}\n\tif !IsNil(o.AutoStopInterval) {\n\t\ttoSerialize[\"autoStopInterval\"] = o.AutoStopInterval\n\t}\n\tif !IsNil(o.AutoArchiveInterval) {\n\t\ttoSerialize[\"autoArchiveInterval\"] = o.AutoArchiveInterval\n\t}\n\tif !IsNil(o.Volumes) {\n\t\ttoSerialize[\"volumes\"] = o.Volumes\n\t}\n\tif !IsNil(o.BuildInfo) {\n\t\ttoSerialize[\"buildInfo\"] = o.BuildInfo\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *CreateWorkspace) UnmarshalJSON(data []byte) (err error) {\n\tvarCreateWorkspace := _CreateWorkspace{}\n\n\terr = json.Unmarshal(data, &varCreateWorkspace)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = CreateWorkspace(varCreateWorkspace)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"image\")\n\t\tdelete(additionalProperties, \"user\")\n\t\tdelete(additionalProperties, \"env\")\n\t\tdelete(additionalProperties, \"labels\")\n\t\tdelete(additionalProperties, \"public\")\n\t\tdelete(additionalProperties, \"class\")\n\t\tdelete(additionalProperties, \"target\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"gpu\")\n\t\tdelete(additionalProperties, \"memory\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\tdelete(additionalProperties, \"autoStopInterval\")\n\t\tdelete(additionalProperties, \"autoArchiveInterval\")\n\t\tdelete(additionalProperties, \"volumes\")\n\t\tdelete(additionalProperties, \"buildInfo\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableCreateWorkspace struct {\n\tvalue *CreateWorkspace\n\tisSet bool\n}\n\nfunc (v NullableCreateWorkspace) Get() *CreateWorkspace {\n\treturn v.value\n}\n\nfunc (v *NullableCreateWorkspace) Set(val *CreateWorkspace) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableCreateWorkspace) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableCreateWorkspace) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableCreateWorkspace(val *CreateWorkspace) *NullableCreateWorkspace {\n\treturn &NullableCreateWorkspace{value: val, isSet: true}\n}\n\nfunc (v NullableCreateWorkspace) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableCreateWorkspace) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_daytona_configuration.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the DaytonaConfiguration type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &DaytonaConfiguration{}\n\n// DaytonaConfiguration struct for DaytonaConfiguration\ntype DaytonaConfiguration struct {\n\t// Daytona version\n\tVersion string `json:\"version\"`\n\t// PostHog configuration\n\tPosthog *PosthogConfig `json:\"posthog,omitempty\"`\n\t// OIDC configuration\n\tOidc OidcConfig `json:\"oidc\"`\n\t// Whether linked accounts are enabled\n\tLinkedAccountsEnabled bool `json:\"linkedAccountsEnabled\"`\n\t// System announcements\n\tAnnouncements map[string]Announcement `json:\"announcements\"`\n\t// Pylon application ID\n\tPylonAppId *string `json:\"pylonAppId,omitempty\"`\n\t// Proxy template URL\n\tProxyTemplateUrl string `json:\"proxyTemplateUrl\"`\n\t// Toolbox template URL\n\tProxyToolboxUrl string `json:\"proxyToolboxUrl\"`\n\t// Default snapshot for sandboxes\n\tDefaultSnapshot string `json:\"defaultSnapshot\"`\n\t// Dashboard URL\n\tDashboardUrl string `json:\"dashboardUrl\"`\n\t// Maximum auto-archive interval in minutes\n\tMaxAutoArchiveInterval float32 `json:\"maxAutoArchiveInterval\"`\n\t// Whether maintenance mode is enabled\n\tMaintananceMode bool `json:\"maintananceMode\"`\n\t// Current environment\n\tEnvironment string `json:\"environment\"`\n\t// Billing API URL\n\tBillingApiUrl *string `json:\"billingApiUrl,omitempty\"`\n\t// Analytics API URL\n\tAnalyticsApiUrl *string `json:\"analyticsApiUrl,omitempty\"`\n\t// SSH Gateway command\n\tSshGatewayCommand *string `json:\"sshGatewayCommand,omitempty\"`\n\t// Base64 encoded SSH Gateway public key\n\tSshGatewayPublicKey *string `json:\"sshGatewayPublicKey,omitempty\"`\n\t// Rate limit configuration\n\tRateLimit *RateLimitConfig `json:\"rateLimit,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _DaytonaConfiguration DaytonaConfiguration\n\n// NewDaytonaConfiguration instantiates a new DaytonaConfiguration object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewDaytonaConfiguration(version string, oidc OidcConfig, linkedAccountsEnabled bool, announcements map[string]Announcement, proxyTemplateUrl string, proxyToolboxUrl string, defaultSnapshot string, dashboardUrl string, maxAutoArchiveInterval float32, maintananceMode bool, environment string) *DaytonaConfiguration {\n\tthis := DaytonaConfiguration{}\n\tthis.Version = version\n\tthis.Oidc = oidc\n\tthis.LinkedAccountsEnabled = linkedAccountsEnabled\n\tthis.Announcements = announcements\n\tthis.ProxyTemplateUrl = proxyTemplateUrl\n\tthis.ProxyToolboxUrl = proxyToolboxUrl\n\tthis.DefaultSnapshot = defaultSnapshot\n\tthis.DashboardUrl = dashboardUrl\n\tthis.MaxAutoArchiveInterval = maxAutoArchiveInterval\n\tthis.MaintananceMode = maintananceMode\n\tthis.Environment = environment\n\treturn &this\n}\n\n// NewDaytonaConfigurationWithDefaults instantiates a new DaytonaConfiguration object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewDaytonaConfigurationWithDefaults() *DaytonaConfiguration {\n\tthis := DaytonaConfiguration{}\n\treturn &this\n}\n\n// GetVersion returns the Version field value\nfunc (o *DaytonaConfiguration) GetVersion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Version\n}\n\n// GetVersionOk returns a tuple with the Version field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetVersionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Version, true\n}\n\n// SetVersion sets field value\nfunc (o *DaytonaConfiguration) SetVersion(v string) {\n\to.Version = v\n}\n\n// GetPosthog returns the Posthog field value if set, zero value otherwise.\nfunc (o *DaytonaConfiguration) GetPosthog() PosthogConfig {\n\tif o == nil || IsNil(o.Posthog) {\n\t\tvar ret PosthogConfig\n\t\treturn ret\n\t}\n\treturn *o.Posthog\n}\n\n// GetPosthogOk returns a tuple with the Posthog field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetPosthogOk() (*PosthogConfig, bool) {\n\tif o == nil || IsNil(o.Posthog) {\n\t\treturn nil, false\n\t}\n\treturn o.Posthog, true\n}\n\n// HasPosthog returns a boolean if a field has been set.\nfunc (o *DaytonaConfiguration) HasPosthog() bool {\n\tif o != nil && !IsNil(o.Posthog) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPosthog gets a reference to the given PosthogConfig and assigns it to the Posthog field.\nfunc (o *DaytonaConfiguration) SetPosthog(v PosthogConfig) {\n\to.Posthog = &v\n}\n\n// GetOidc returns the Oidc field value\nfunc (o *DaytonaConfiguration) GetOidc() OidcConfig {\n\tif o == nil {\n\t\tvar ret OidcConfig\n\t\treturn ret\n\t}\n\n\treturn o.Oidc\n}\n\n// GetOidcOk returns a tuple with the Oidc field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetOidcOk() (*OidcConfig, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Oidc, true\n}\n\n// SetOidc sets field value\nfunc (o *DaytonaConfiguration) SetOidc(v OidcConfig) {\n\to.Oidc = v\n}\n\n// GetLinkedAccountsEnabled returns the LinkedAccountsEnabled field value\nfunc (o *DaytonaConfiguration) GetLinkedAccountsEnabled() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.LinkedAccountsEnabled\n}\n\n// GetLinkedAccountsEnabledOk returns a tuple with the LinkedAccountsEnabled field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetLinkedAccountsEnabledOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.LinkedAccountsEnabled, true\n}\n\n// SetLinkedAccountsEnabled sets field value\nfunc (o *DaytonaConfiguration) SetLinkedAccountsEnabled(v bool) {\n\to.LinkedAccountsEnabled = v\n}\n\n// GetAnnouncements returns the Announcements field value\nfunc (o *DaytonaConfiguration) GetAnnouncements() map[string]Announcement {\n\tif o == nil {\n\t\tvar ret map[string]Announcement\n\t\treturn ret\n\t}\n\n\treturn o.Announcements\n}\n\n// GetAnnouncementsOk returns a tuple with the Announcements field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetAnnouncementsOk() (*map[string]Announcement, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Announcements, true\n}\n\n// SetAnnouncements sets field value\nfunc (o *DaytonaConfiguration) SetAnnouncements(v map[string]Announcement) {\n\to.Announcements = v\n}\n\n// GetPylonAppId returns the PylonAppId field value if set, zero value otherwise.\nfunc (o *DaytonaConfiguration) GetPylonAppId() string {\n\tif o == nil || IsNil(o.PylonAppId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.PylonAppId\n}\n\n// GetPylonAppIdOk returns a tuple with the PylonAppId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetPylonAppIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.PylonAppId) {\n\t\treturn nil, false\n\t}\n\treturn o.PylonAppId, true\n}\n\n// HasPylonAppId returns a boolean if a field has been set.\nfunc (o *DaytonaConfiguration) HasPylonAppId() bool {\n\tif o != nil && !IsNil(o.PylonAppId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPylonAppId gets a reference to the given string and assigns it to the PylonAppId field.\nfunc (o *DaytonaConfiguration) SetPylonAppId(v string) {\n\to.PylonAppId = &v\n}\n\n// GetProxyTemplateUrl returns the ProxyTemplateUrl field value\nfunc (o *DaytonaConfiguration) GetProxyTemplateUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ProxyTemplateUrl\n}\n\n// GetProxyTemplateUrlOk returns a tuple with the ProxyTemplateUrl field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetProxyTemplateUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ProxyTemplateUrl, true\n}\n\n// SetProxyTemplateUrl sets field value\nfunc (o *DaytonaConfiguration) SetProxyTemplateUrl(v string) {\n\to.ProxyTemplateUrl = v\n}\n\n// GetProxyToolboxUrl returns the ProxyToolboxUrl field value\nfunc (o *DaytonaConfiguration) GetProxyToolboxUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ProxyToolboxUrl\n}\n\n// GetProxyToolboxUrlOk returns a tuple with the ProxyToolboxUrl field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetProxyToolboxUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ProxyToolboxUrl, true\n}\n\n// SetProxyToolboxUrl sets field value\nfunc (o *DaytonaConfiguration) SetProxyToolboxUrl(v string) {\n\to.ProxyToolboxUrl = v\n}\n\n// GetDefaultSnapshot returns the DefaultSnapshot field value\nfunc (o *DaytonaConfiguration) GetDefaultSnapshot() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.DefaultSnapshot\n}\n\n// GetDefaultSnapshotOk returns a tuple with the DefaultSnapshot field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetDefaultSnapshotOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DefaultSnapshot, true\n}\n\n// SetDefaultSnapshot sets field value\nfunc (o *DaytonaConfiguration) SetDefaultSnapshot(v string) {\n\to.DefaultSnapshot = v\n}\n\n// GetDashboardUrl returns the DashboardUrl field value\nfunc (o *DaytonaConfiguration) GetDashboardUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.DashboardUrl\n}\n\n// GetDashboardUrlOk returns a tuple with the DashboardUrl field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetDashboardUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DashboardUrl, true\n}\n\n// SetDashboardUrl sets field value\nfunc (o *DaytonaConfiguration) SetDashboardUrl(v string) {\n\to.DashboardUrl = v\n}\n\n// GetMaxAutoArchiveInterval returns the MaxAutoArchiveInterval field value\nfunc (o *DaytonaConfiguration) GetMaxAutoArchiveInterval() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.MaxAutoArchiveInterval\n}\n\n// GetMaxAutoArchiveIntervalOk returns a tuple with the MaxAutoArchiveInterval field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetMaxAutoArchiveIntervalOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.MaxAutoArchiveInterval, true\n}\n\n// SetMaxAutoArchiveInterval sets field value\nfunc (o *DaytonaConfiguration) SetMaxAutoArchiveInterval(v float32) {\n\to.MaxAutoArchiveInterval = v\n}\n\n// GetMaintananceMode returns the MaintananceMode field value\nfunc (o *DaytonaConfiguration) GetMaintananceMode() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.MaintananceMode\n}\n\n// GetMaintananceModeOk returns a tuple with the MaintananceMode field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetMaintananceModeOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.MaintananceMode, true\n}\n\n// SetMaintananceMode sets field value\nfunc (o *DaytonaConfiguration) SetMaintananceMode(v bool) {\n\to.MaintananceMode = v\n}\n\n// GetEnvironment returns the Environment field value\nfunc (o *DaytonaConfiguration) GetEnvironment() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Environment\n}\n\n// GetEnvironmentOk returns a tuple with the Environment field value\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetEnvironmentOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Environment, true\n}\n\n// SetEnvironment sets field value\nfunc (o *DaytonaConfiguration) SetEnvironment(v string) {\n\to.Environment = v\n}\n\n// GetBillingApiUrl returns the BillingApiUrl field value if set, zero value otherwise.\nfunc (o *DaytonaConfiguration) GetBillingApiUrl() string {\n\tif o == nil || IsNil(o.BillingApiUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.BillingApiUrl\n}\n\n// GetBillingApiUrlOk returns a tuple with the BillingApiUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetBillingApiUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.BillingApiUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.BillingApiUrl, true\n}\n\n// HasBillingApiUrl returns a boolean if a field has been set.\nfunc (o *DaytonaConfiguration) HasBillingApiUrl() bool {\n\tif o != nil && !IsNil(o.BillingApiUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBillingApiUrl gets a reference to the given string and assigns it to the BillingApiUrl field.\nfunc (o *DaytonaConfiguration) SetBillingApiUrl(v string) {\n\to.BillingApiUrl = &v\n}\n\n// GetAnalyticsApiUrl returns the AnalyticsApiUrl field value if set, zero value otherwise.\nfunc (o *DaytonaConfiguration) GetAnalyticsApiUrl() string {\n\tif o == nil || IsNil(o.AnalyticsApiUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.AnalyticsApiUrl\n}\n\n// GetAnalyticsApiUrlOk returns a tuple with the AnalyticsApiUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetAnalyticsApiUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.AnalyticsApiUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.AnalyticsApiUrl, true\n}\n\n// HasAnalyticsApiUrl returns a boolean if a field has been set.\nfunc (o *DaytonaConfiguration) HasAnalyticsApiUrl() bool {\n\tif o != nil && !IsNil(o.AnalyticsApiUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAnalyticsApiUrl gets a reference to the given string and assigns it to the AnalyticsApiUrl field.\nfunc (o *DaytonaConfiguration) SetAnalyticsApiUrl(v string) {\n\to.AnalyticsApiUrl = &v\n}\n\n// GetSshGatewayCommand returns the SshGatewayCommand field value if set, zero value otherwise.\nfunc (o *DaytonaConfiguration) GetSshGatewayCommand() string {\n\tif o == nil || IsNil(o.SshGatewayCommand) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SshGatewayCommand\n}\n\n// GetSshGatewayCommandOk returns a tuple with the SshGatewayCommand field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetSshGatewayCommandOk() (*string, bool) {\n\tif o == nil || IsNil(o.SshGatewayCommand) {\n\t\treturn nil, false\n\t}\n\treturn o.SshGatewayCommand, true\n}\n\n// HasSshGatewayCommand returns a boolean if a field has been set.\nfunc (o *DaytonaConfiguration) HasSshGatewayCommand() bool {\n\tif o != nil && !IsNil(o.SshGatewayCommand) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSshGatewayCommand gets a reference to the given string and assigns it to the SshGatewayCommand field.\nfunc (o *DaytonaConfiguration) SetSshGatewayCommand(v string) {\n\to.SshGatewayCommand = &v\n}\n\n// GetSshGatewayPublicKey returns the SshGatewayPublicKey field value if set, zero value otherwise.\nfunc (o *DaytonaConfiguration) GetSshGatewayPublicKey() string {\n\tif o == nil || IsNil(o.SshGatewayPublicKey) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SshGatewayPublicKey\n}\n\n// GetSshGatewayPublicKeyOk returns a tuple with the SshGatewayPublicKey field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetSshGatewayPublicKeyOk() (*string, bool) {\n\tif o == nil || IsNil(o.SshGatewayPublicKey) {\n\t\treturn nil, false\n\t}\n\treturn o.SshGatewayPublicKey, true\n}\n\n// HasSshGatewayPublicKey returns a boolean if a field has been set.\nfunc (o *DaytonaConfiguration) HasSshGatewayPublicKey() bool {\n\tif o != nil && !IsNil(o.SshGatewayPublicKey) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSshGatewayPublicKey gets a reference to the given string and assigns it to the SshGatewayPublicKey field.\nfunc (o *DaytonaConfiguration) SetSshGatewayPublicKey(v string) {\n\to.SshGatewayPublicKey = &v\n}\n\n// GetRateLimit returns the RateLimit field value if set, zero value otherwise.\nfunc (o *DaytonaConfiguration) GetRateLimit() RateLimitConfig {\n\tif o == nil || IsNil(o.RateLimit) {\n\t\tvar ret RateLimitConfig\n\t\treturn ret\n\t}\n\treturn *o.RateLimit\n}\n\n// GetRateLimitOk returns a tuple with the RateLimit field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *DaytonaConfiguration) GetRateLimitOk() (*RateLimitConfig, bool) {\n\tif o == nil || IsNil(o.RateLimit) {\n\t\treturn nil, false\n\t}\n\treturn o.RateLimit, true\n}\n\n// HasRateLimit returns a boolean if a field has been set.\nfunc (o *DaytonaConfiguration) HasRateLimit() bool {\n\tif o != nil && !IsNil(o.RateLimit) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRateLimit gets a reference to the given RateLimitConfig and assigns it to the RateLimit field.\nfunc (o *DaytonaConfiguration) SetRateLimit(v RateLimitConfig) {\n\to.RateLimit = &v\n}\n\nfunc (o DaytonaConfiguration) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o DaytonaConfiguration) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"version\"] = o.Version\n\tif !IsNil(o.Posthog) {\n\t\ttoSerialize[\"posthog\"] = o.Posthog\n\t}\n\ttoSerialize[\"oidc\"] = o.Oidc\n\ttoSerialize[\"linkedAccountsEnabled\"] = o.LinkedAccountsEnabled\n\ttoSerialize[\"announcements\"] = o.Announcements\n\tif !IsNil(o.PylonAppId) {\n\t\ttoSerialize[\"pylonAppId\"] = o.PylonAppId\n\t}\n\ttoSerialize[\"proxyTemplateUrl\"] = o.ProxyTemplateUrl\n\ttoSerialize[\"proxyToolboxUrl\"] = o.ProxyToolboxUrl\n\ttoSerialize[\"defaultSnapshot\"] = o.DefaultSnapshot\n\ttoSerialize[\"dashboardUrl\"] = o.DashboardUrl\n\ttoSerialize[\"maxAutoArchiveInterval\"] = o.MaxAutoArchiveInterval\n\ttoSerialize[\"maintananceMode\"] = o.MaintananceMode\n\ttoSerialize[\"environment\"] = o.Environment\n\tif !IsNil(o.BillingApiUrl) {\n\t\ttoSerialize[\"billingApiUrl\"] = o.BillingApiUrl\n\t}\n\tif !IsNil(o.AnalyticsApiUrl) {\n\t\ttoSerialize[\"analyticsApiUrl\"] = o.AnalyticsApiUrl\n\t}\n\tif !IsNil(o.SshGatewayCommand) {\n\t\ttoSerialize[\"sshGatewayCommand\"] = o.SshGatewayCommand\n\t}\n\tif !IsNil(o.SshGatewayPublicKey) {\n\t\ttoSerialize[\"sshGatewayPublicKey\"] = o.SshGatewayPublicKey\n\t}\n\tif !IsNil(o.RateLimit) {\n\t\ttoSerialize[\"rateLimit\"] = o.RateLimit\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *DaytonaConfiguration) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"version\",\n\t\t\"oidc\",\n\t\t\"linkedAccountsEnabled\",\n\t\t\"announcements\",\n\t\t\"proxyTemplateUrl\",\n\t\t\"proxyToolboxUrl\",\n\t\t\"defaultSnapshot\",\n\t\t\"dashboardUrl\",\n\t\t\"maxAutoArchiveInterval\",\n\t\t\"maintananceMode\",\n\t\t\"environment\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarDaytonaConfiguration := _DaytonaConfiguration{}\n\n\terr = json.Unmarshal(data, &varDaytonaConfiguration)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = DaytonaConfiguration(varDaytonaConfiguration)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"version\")\n\t\tdelete(additionalProperties, \"posthog\")\n\t\tdelete(additionalProperties, \"oidc\")\n\t\tdelete(additionalProperties, \"linkedAccountsEnabled\")\n\t\tdelete(additionalProperties, \"announcements\")\n\t\tdelete(additionalProperties, \"pylonAppId\")\n\t\tdelete(additionalProperties, \"proxyTemplateUrl\")\n\t\tdelete(additionalProperties, \"proxyToolboxUrl\")\n\t\tdelete(additionalProperties, \"defaultSnapshot\")\n\t\tdelete(additionalProperties, \"dashboardUrl\")\n\t\tdelete(additionalProperties, \"maxAutoArchiveInterval\")\n\t\tdelete(additionalProperties, \"maintananceMode\")\n\t\tdelete(additionalProperties, \"environment\")\n\t\tdelete(additionalProperties, \"billingApiUrl\")\n\t\tdelete(additionalProperties, \"analyticsApiUrl\")\n\t\tdelete(additionalProperties, \"sshGatewayCommand\")\n\t\tdelete(additionalProperties, \"sshGatewayPublicKey\")\n\t\tdelete(additionalProperties, \"rateLimit\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableDaytonaConfiguration struct {\n\tvalue *DaytonaConfiguration\n\tisSet bool\n}\n\nfunc (v NullableDaytonaConfiguration) Get() *DaytonaConfiguration {\n\treturn v.value\n}\n\nfunc (v *NullableDaytonaConfiguration) Set(val *DaytonaConfiguration) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableDaytonaConfiguration) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableDaytonaConfiguration) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableDaytonaConfiguration(val *DaytonaConfiguration) *NullableDaytonaConfiguration {\n\treturn &NullableDaytonaConfiguration{value: val, isSet: true}\n}\n\nfunc (v NullableDaytonaConfiguration) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableDaytonaConfiguration) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_display_info_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the DisplayInfoResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &DisplayInfoResponse{}\n\n// DisplayInfoResponse struct for DisplayInfoResponse\ntype DisplayInfoResponse struct {\n\t// Array of display information for all connected displays\n\tDisplays []map[string]interface{} `json:\"displays\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _DisplayInfoResponse DisplayInfoResponse\n\n// NewDisplayInfoResponse instantiates a new DisplayInfoResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewDisplayInfoResponse(displays []map[string]interface{}) *DisplayInfoResponse {\n\tthis := DisplayInfoResponse{}\n\tthis.Displays = displays\n\treturn &this\n}\n\n// NewDisplayInfoResponseWithDefaults instantiates a new DisplayInfoResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewDisplayInfoResponseWithDefaults() *DisplayInfoResponse {\n\tthis := DisplayInfoResponse{}\n\treturn &this\n}\n\n// GetDisplays returns the Displays field value\nfunc (o *DisplayInfoResponse) GetDisplays() []map[string]interface{} {\n\tif o == nil {\n\t\tvar ret []map[string]interface{}\n\t\treturn ret\n\t}\n\n\treturn o.Displays\n}\n\n// GetDisplaysOk returns a tuple with the Displays field value\n// and a boolean to check if the value has been set.\nfunc (o *DisplayInfoResponse) GetDisplaysOk() ([]map[string]interface{}, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Displays, true\n}\n\n// SetDisplays sets field value\nfunc (o *DisplayInfoResponse) SetDisplays(v []map[string]interface{}) {\n\to.Displays = v\n}\n\nfunc (o DisplayInfoResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o DisplayInfoResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"displays\"] = o.Displays\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *DisplayInfoResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"displays\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarDisplayInfoResponse := _DisplayInfoResponse{}\n\n\terr = json.Unmarshal(data, &varDisplayInfoResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = DisplayInfoResponse(varDisplayInfoResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"displays\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableDisplayInfoResponse struct {\n\tvalue *DisplayInfoResponse\n\tisSet bool\n}\n\nfunc (v NullableDisplayInfoResponse) Get() *DisplayInfoResponse {\n\treturn v.value\n}\n\nfunc (v *NullableDisplayInfoResponse) Set(val *DisplayInfoResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableDisplayInfoResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableDisplayInfoResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableDisplayInfoResponse(val *DisplayInfoResponse) *NullableDisplayInfoResponse {\n\treturn &NullableDisplayInfoResponse{value: val, isSet: true}\n}\n\nfunc (v NullableDisplayInfoResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableDisplayInfoResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_docker_registry.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the DockerRegistry type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &DockerRegistry{}\n\n// DockerRegistry struct for DockerRegistry\ntype DockerRegistry struct {\n\t// Registry ID\n\tId string `json:\"id\"`\n\t// Registry name\n\tName string `json:\"name\"`\n\t// Registry URL\n\tUrl string `json:\"url\"`\n\t// Registry username\n\tUsername string `json:\"username\"`\n\t// Registry project\n\tProject string `json:\"project\"`\n\t// Registry type\n\tRegistryType string `json:\"registryType\"`\n\t// Creation timestamp\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// Last update timestamp\n\tUpdatedAt time.Time `json:\"updatedAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _DockerRegistry DockerRegistry\n\n// NewDockerRegistry instantiates a new DockerRegistry object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewDockerRegistry(id string, name string, url string, username string, project string, registryType string, createdAt time.Time, updatedAt time.Time) *DockerRegistry {\n\tthis := DockerRegistry{}\n\tthis.Id = id\n\tthis.Name = name\n\tthis.Url = url\n\tthis.Username = username\n\tthis.Project = project\n\tthis.RegistryType = registryType\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\treturn &this\n}\n\n// NewDockerRegistryWithDefaults instantiates a new DockerRegistry object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewDockerRegistryWithDefaults() *DockerRegistry {\n\tthis := DockerRegistry{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *DockerRegistry) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *DockerRegistry) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *DockerRegistry) SetId(v string) {\n\to.Id = v\n}\n\n// GetName returns the Name field value\nfunc (o *DockerRegistry) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *DockerRegistry) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *DockerRegistry) SetName(v string) {\n\to.Name = v\n}\n\n// GetUrl returns the Url field value\nfunc (o *DockerRegistry) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *DockerRegistry) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *DockerRegistry) SetUrl(v string) {\n\to.Url = v\n}\n\n// GetUsername returns the Username field value\nfunc (o *DockerRegistry) GetUsername() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Username\n}\n\n// GetUsernameOk returns a tuple with the Username field value\n// and a boolean to check if the value has been set.\nfunc (o *DockerRegistry) GetUsernameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Username, true\n}\n\n// SetUsername sets field value\nfunc (o *DockerRegistry) SetUsername(v string) {\n\to.Username = v\n}\n\n// GetProject returns the Project field value\nfunc (o *DockerRegistry) GetProject() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Project\n}\n\n// GetProjectOk returns a tuple with the Project field value\n// and a boolean to check if the value has been set.\nfunc (o *DockerRegistry) GetProjectOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Project, true\n}\n\n// SetProject sets field value\nfunc (o *DockerRegistry) SetProject(v string) {\n\to.Project = v\n}\n\n// GetRegistryType returns the RegistryType field value\nfunc (o *DockerRegistry) GetRegistryType() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RegistryType\n}\n\n// GetRegistryTypeOk returns a tuple with the RegistryType field value\n// and a boolean to check if the value has been set.\nfunc (o *DockerRegistry) GetRegistryTypeOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegistryType, true\n}\n\n// SetRegistryType sets field value\nfunc (o *DockerRegistry) SetRegistryType(v string) {\n\to.RegistryType = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *DockerRegistry) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *DockerRegistry) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *DockerRegistry) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *DockerRegistry) GetUpdatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *DockerRegistry) GetUpdatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *DockerRegistry) SetUpdatedAt(v time.Time) {\n\to.UpdatedAt = v\n}\n\nfunc (o DockerRegistry) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o DockerRegistry) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"url\"] = o.Url\n\ttoSerialize[\"username\"] = o.Username\n\ttoSerialize[\"project\"] = o.Project\n\ttoSerialize[\"registryType\"] = o.RegistryType\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *DockerRegistry) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"name\",\n\t\t\"url\",\n\t\t\"username\",\n\t\t\"project\",\n\t\t\"registryType\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarDockerRegistry := _DockerRegistry{}\n\n\terr = json.Unmarshal(data, &varDockerRegistry)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = DockerRegistry(varDockerRegistry)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"url\")\n\t\tdelete(additionalProperties, \"username\")\n\t\tdelete(additionalProperties, \"project\")\n\t\tdelete(additionalProperties, \"registryType\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableDockerRegistry struct {\n\tvalue *DockerRegistry\n\tisSet bool\n}\n\nfunc (v NullableDockerRegistry) Get() *DockerRegistry {\n\treturn v.value\n}\n\nfunc (v *NullableDockerRegistry) Set(val *DockerRegistry) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableDockerRegistry) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableDockerRegistry) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableDockerRegistry(val *DockerRegistry) *NullableDockerRegistry {\n\treturn &NullableDockerRegistry{value: val, isSet: true}\n}\n\nfunc (v NullableDockerRegistry) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableDockerRegistry) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_download_files.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the DownloadFiles type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &DownloadFiles{}\n\n// DownloadFiles struct for DownloadFiles\ntype DownloadFiles struct {\n\t// List of remote file paths to download\n\tPaths []string `json:\"paths\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _DownloadFiles DownloadFiles\n\n// NewDownloadFiles instantiates a new DownloadFiles object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewDownloadFiles(paths []string) *DownloadFiles {\n\tthis := DownloadFiles{}\n\tthis.Paths = paths\n\treturn &this\n}\n\n// NewDownloadFilesWithDefaults instantiates a new DownloadFiles object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewDownloadFilesWithDefaults() *DownloadFiles {\n\tthis := DownloadFiles{}\n\treturn &this\n}\n\n// GetPaths returns the Paths field value\nfunc (o *DownloadFiles) GetPaths() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Paths\n}\n\n// GetPathsOk returns a tuple with the Paths field value\n// and a boolean to check if the value has been set.\nfunc (o *DownloadFiles) GetPathsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Paths, true\n}\n\n// SetPaths sets field value\nfunc (o *DownloadFiles) SetPaths(v []string) {\n\to.Paths = v\n}\n\nfunc (o DownloadFiles) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o DownloadFiles) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"paths\"] = o.Paths\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *DownloadFiles) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"paths\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarDownloadFiles := _DownloadFiles{}\n\n\terr = json.Unmarshal(data, &varDownloadFiles)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = DownloadFiles(varDownloadFiles)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"paths\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableDownloadFiles struct {\n\tvalue *DownloadFiles\n\tisSet bool\n}\n\nfunc (v NullableDownloadFiles) Get() *DownloadFiles {\n\treturn v.value\n}\n\nfunc (v *NullableDownloadFiles) Set(val *DownloadFiles) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableDownloadFiles) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableDownloadFiles) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableDownloadFiles(val *DownloadFiles) *NullableDownloadFiles {\n\treturn &NullableDownloadFiles{value: val, isSet: true}\n}\n\nfunc (v NullableDownloadFiles) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableDownloadFiles) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_execute_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ExecuteRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ExecuteRequest{}\n\n// ExecuteRequest struct for ExecuteRequest\ntype ExecuteRequest struct {\n\tCommand string `json:\"command\"`\n\t// Current working directory\n\tCwd *string `json:\"cwd,omitempty\"`\n\t// Timeout in seconds, defaults to 10 seconds\n\tTimeout *float32 `json:\"timeout,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ExecuteRequest ExecuteRequest\n\n// NewExecuteRequest instantiates a new ExecuteRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewExecuteRequest(command string) *ExecuteRequest {\n\tthis := ExecuteRequest{}\n\tthis.Command = command\n\treturn &this\n}\n\n// NewExecuteRequestWithDefaults instantiates a new ExecuteRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewExecuteRequestWithDefaults() *ExecuteRequest {\n\tthis := ExecuteRequest{}\n\treturn &this\n}\n\n// GetCommand returns the Command field value\nfunc (o *ExecuteRequest) GetCommand() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Command\n}\n\n// GetCommandOk returns a tuple with the Command field value\n// and a boolean to check if the value has been set.\nfunc (o *ExecuteRequest) GetCommandOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Command, true\n}\n\n// SetCommand sets field value\nfunc (o *ExecuteRequest) SetCommand(v string) {\n\to.Command = v\n}\n\n// GetCwd returns the Cwd field value if set, zero value otherwise.\nfunc (o *ExecuteRequest) GetCwd() string {\n\tif o == nil || IsNil(o.Cwd) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Cwd\n}\n\n// GetCwdOk returns a tuple with the Cwd field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ExecuteRequest) GetCwdOk() (*string, bool) {\n\tif o == nil || IsNil(o.Cwd) {\n\t\treturn nil, false\n\t}\n\treturn o.Cwd, true\n}\n\n// HasCwd returns a boolean if a field has been set.\nfunc (o *ExecuteRequest) HasCwd() bool {\n\tif o != nil && !IsNil(o.Cwd) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCwd gets a reference to the given string and assigns it to the Cwd field.\nfunc (o *ExecuteRequest) SetCwd(v string) {\n\to.Cwd = &v\n}\n\n// GetTimeout returns the Timeout field value if set, zero value otherwise.\nfunc (o *ExecuteRequest) GetTimeout() float32 {\n\tif o == nil || IsNil(o.Timeout) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Timeout\n}\n\n// GetTimeoutOk returns a tuple with the Timeout field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ExecuteRequest) GetTimeoutOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Timeout) {\n\t\treturn nil, false\n\t}\n\treturn o.Timeout, true\n}\n\n// HasTimeout returns a boolean if a field has been set.\nfunc (o *ExecuteRequest) HasTimeout() bool {\n\tif o != nil && !IsNil(o.Timeout) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTimeout gets a reference to the given float32 and assigns it to the Timeout field.\nfunc (o *ExecuteRequest) SetTimeout(v float32) {\n\to.Timeout = &v\n}\n\nfunc (o ExecuteRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ExecuteRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"command\"] = o.Command\n\tif !IsNil(o.Cwd) {\n\t\ttoSerialize[\"cwd\"] = o.Cwd\n\t}\n\tif !IsNil(o.Timeout) {\n\t\ttoSerialize[\"timeout\"] = o.Timeout\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ExecuteRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"command\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarExecuteRequest := _ExecuteRequest{}\n\n\terr = json.Unmarshal(data, &varExecuteRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ExecuteRequest(varExecuteRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"command\")\n\t\tdelete(additionalProperties, \"cwd\")\n\t\tdelete(additionalProperties, \"timeout\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableExecuteRequest struct {\n\tvalue *ExecuteRequest\n\tisSet bool\n}\n\nfunc (v NullableExecuteRequest) Get() *ExecuteRequest {\n\treturn v.value\n}\n\nfunc (v *NullableExecuteRequest) Set(val *ExecuteRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableExecuteRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableExecuteRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableExecuteRequest(val *ExecuteRequest) *NullableExecuteRequest {\n\treturn &NullableExecuteRequest{value: val, isSet: true}\n}\n\nfunc (v NullableExecuteRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableExecuteRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_execute_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ExecuteResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ExecuteResponse{}\n\n// ExecuteResponse struct for ExecuteResponse\ntype ExecuteResponse struct {\n\t// Exit code\n\tExitCode float32 `json:\"exitCode\"`\n\t// Command output\n\tResult string `json:\"result\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ExecuteResponse ExecuteResponse\n\n// NewExecuteResponse instantiates a new ExecuteResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewExecuteResponse(exitCode float32, result string) *ExecuteResponse {\n\tthis := ExecuteResponse{}\n\tthis.ExitCode = exitCode\n\tthis.Result = result\n\treturn &this\n}\n\n// NewExecuteResponseWithDefaults instantiates a new ExecuteResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewExecuteResponseWithDefaults() *ExecuteResponse {\n\tthis := ExecuteResponse{}\n\treturn &this\n}\n\n// GetExitCode returns the ExitCode field value\nfunc (o *ExecuteResponse) GetExitCode() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.ExitCode\n}\n\n// GetExitCodeOk returns a tuple with the ExitCode field value\n// and a boolean to check if the value has been set.\nfunc (o *ExecuteResponse) GetExitCodeOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ExitCode, true\n}\n\n// SetExitCode sets field value\nfunc (o *ExecuteResponse) SetExitCode(v float32) {\n\to.ExitCode = v\n}\n\n// GetResult returns the Result field value\nfunc (o *ExecuteResponse) GetResult() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Result\n}\n\n// GetResultOk returns a tuple with the Result field value\n// and a boolean to check if the value has been set.\nfunc (o *ExecuteResponse) GetResultOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Result, true\n}\n\n// SetResult sets field value\nfunc (o *ExecuteResponse) SetResult(v string) {\n\to.Result = v\n}\n\nfunc (o ExecuteResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ExecuteResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"exitCode\"] = o.ExitCode\n\ttoSerialize[\"result\"] = o.Result\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ExecuteResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"exitCode\",\n\t\t\"result\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarExecuteResponse := _ExecuteResponse{}\n\n\terr = json.Unmarshal(data, &varExecuteResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ExecuteResponse(varExecuteResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"exitCode\")\n\t\tdelete(additionalProperties, \"result\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableExecuteResponse struct {\n\tvalue *ExecuteResponse\n\tisSet bool\n}\n\nfunc (v NullableExecuteResponse) Get() *ExecuteResponse {\n\treturn v.value\n}\n\nfunc (v *NullableExecuteResponse) Set(val *ExecuteResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableExecuteResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableExecuteResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableExecuteResponse(val *ExecuteResponse) *NullableExecuteResponse {\n\treturn &NullableExecuteResponse{value: val, isSet: true}\n}\n\nfunc (v NullableExecuteResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableExecuteResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_file_info.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the FileInfo type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &FileInfo{}\n\n// FileInfo struct for FileInfo\ntype FileInfo struct {\n\tName string `json:\"name\"`\n\tIsDir bool `json:\"isDir\"`\n\tSize float32 `json:\"size\"`\n\tModTime string `json:\"modTime\"`\n\tMode string `json:\"mode\"`\n\tPermissions string `json:\"permissions\"`\n\tOwner string `json:\"owner\"`\n\tGroup string `json:\"group\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _FileInfo FileInfo\n\n// NewFileInfo instantiates a new FileInfo object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewFileInfo(name string, isDir bool, size float32, modTime string, mode string, permissions string, owner string, group string) *FileInfo {\n\tthis := FileInfo{}\n\tthis.Name = name\n\tthis.IsDir = isDir\n\tthis.Size = size\n\tthis.ModTime = modTime\n\tthis.Mode = mode\n\tthis.Permissions = permissions\n\tthis.Owner = owner\n\tthis.Group = group\n\treturn &this\n}\n\n// NewFileInfoWithDefaults instantiates a new FileInfo object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewFileInfoWithDefaults() *FileInfo {\n\tthis := FileInfo{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *FileInfo) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *FileInfo) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *FileInfo) SetName(v string) {\n\to.Name = v\n}\n\n// GetIsDir returns the IsDir field value\nfunc (o *FileInfo) GetIsDir() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.IsDir\n}\n\n// GetIsDirOk returns a tuple with the IsDir field value\n// and a boolean to check if the value has been set.\nfunc (o *FileInfo) GetIsDirOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.IsDir, true\n}\n\n// SetIsDir sets field value\nfunc (o *FileInfo) SetIsDir(v bool) {\n\to.IsDir = v\n}\n\n// GetSize returns the Size field value\nfunc (o *FileInfo) GetSize() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Size\n}\n\n// GetSizeOk returns a tuple with the Size field value\n// and a boolean to check if the value has been set.\nfunc (o *FileInfo) GetSizeOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Size, true\n}\n\n// SetSize sets field value\nfunc (o *FileInfo) SetSize(v float32) {\n\to.Size = v\n}\n\n// GetModTime returns the ModTime field value\nfunc (o *FileInfo) GetModTime() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ModTime\n}\n\n// GetModTimeOk returns a tuple with the ModTime field value\n// and a boolean to check if the value has been set.\nfunc (o *FileInfo) GetModTimeOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ModTime, true\n}\n\n// SetModTime sets field value\nfunc (o *FileInfo) SetModTime(v string) {\n\to.ModTime = v\n}\n\n// GetMode returns the Mode field value\nfunc (o *FileInfo) GetMode() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Mode\n}\n\n// GetModeOk returns a tuple with the Mode field value\n// and a boolean to check if the value has been set.\nfunc (o *FileInfo) GetModeOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Mode, true\n}\n\n// SetMode sets field value\nfunc (o *FileInfo) SetMode(v string) {\n\to.Mode = v\n}\n\n// GetPermissions returns the Permissions field value\nfunc (o *FileInfo) GetPermissions() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Permissions\n}\n\n// GetPermissionsOk returns a tuple with the Permissions field value\n// and a boolean to check if the value has been set.\nfunc (o *FileInfo) GetPermissionsOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Permissions, true\n}\n\n// SetPermissions sets field value\nfunc (o *FileInfo) SetPermissions(v string) {\n\to.Permissions = v\n}\n\n// GetOwner returns the Owner field value\nfunc (o *FileInfo) GetOwner() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Owner\n}\n\n// GetOwnerOk returns a tuple with the Owner field value\n// and a boolean to check if the value has been set.\nfunc (o *FileInfo) GetOwnerOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Owner, true\n}\n\n// SetOwner sets field value\nfunc (o *FileInfo) SetOwner(v string) {\n\to.Owner = v\n}\n\n// GetGroup returns the Group field value\nfunc (o *FileInfo) GetGroup() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Group\n}\n\n// GetGroupOk returns a tuple with the Group field value\n// and a boolean to check if the value has been set.\nfunc (o *FileInfo) GetGroupOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Group, true\n}\n\n// SetGroup sets field value\nfunc (o *FileInfo) SetGroup(v string) {\n\to.Group = v\n}\n\nfunc (o FileInfo) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o FileInfo) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"isDir\"] = o.IsDir\n\ttoSerialize[\"size\"] = o.Size\n\ttoSerialize[\"modTime\"] = o.ModTime\n\ttoSerialize[\"mode\"] = o.Mode\n\ttoSerialize[\"permissions\"] = o.Permissions\n\ttoSerialize[\"owner\"] = o.Owner\n\ttoSerialize[\"group\"] = o.Group\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *FileInfo) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"isDir\",\n\t\t\"size\",\n\t\t\"modTime\",\n\t\t\"mode\",\n\t\t\"permissions\",\n\t\t\"owner\",\n\t\t\"group\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarFileInfo := _FileInfo{}\n\n\terr = json.Unmarshal(data, &varFileInfo)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = FileInfo(varFileInfo)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"isDir\")\n\t\tdelete(additionalProperties, \"size\")\n\t\tdelete(additionalProperties, \"modTime\")\n\t\tdelete(additionalProperties, \"mode\")\n\t\tdelete(additionalProperties, \"permissions\")\n\t\tdelete(additionalProperties, \"owner\")\n\t\tdelete(additionalProperties, \"group\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableFileInfo struct {\n\tvalue *FileInfo\n\tisSet bool\n}\n\nfunc (v NullableFileInfo) Get() *FileInfo {\n\treturn v.value\n}\n\nfunc (v *NullableFileInfo) Set(val *FileInfo) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableFileInfo) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableFileInfo) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableFileInfo(val *FileInfo) *NullableFileInfo {\n\treturn &NullableFileInfo{value: val, isSet: true}\n}\n\nfunc (v NullableFileInfo) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableFileInfo) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_file_status.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the FileStatus type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &FileStatus{}\n\n// FileStatus struct for FileStatus\ntype FileStatus struct {\n\tName string `json:\"name\"`\n\tStaging string `json:\"staging\"`\n\tWorktree string `json:\"worktree\"`\n\tExtra string `json:\"extra\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _FileStatus FileStatus\n\n// NewFileStatus instantiates a new FileStatus object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewFileStatus(name string, staging string, worktree string, extra string) *FileStatus {\n\tthis := FileStatus{}\n\tthis.Name = name\n\tthis.Staging = staging\n\tthis.Worktree = worktree\n\tthis.Extra = extra\n\treturn &this\n}\n\n// NewFileStatusWithDefaults instantiates a new FileStatus object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewFileStatusWithDefaults() *FileStatus {\n\tthis := FileStatus{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *FileStatus) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *FileStatus) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *FileStatus) SetName(v string) {\n\to.Name = v\n}\n\n// GetStaging returns the Staging field value\nfunc (o *FileStatus) GetStaging() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Staging\n}\n\n// GetStagingOk returns a tuple with the Staging field value\n// and a boolean to check if the value has been set.\nfunc (o *FileStatus) GetStagingOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Staging, true\n}\n\n// SetStaging sets field value\nfunc (o *FileStatus) SetStaging(v string) {\n\to.Staging = v\n}\n\n// GetWorktree returns the Worktree field value\nfunc (o *FileStatus) GetWorktree() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Worktree\n}\n\n// GetWorktreeOk returns a tuple with the Worktree field value\n// and a boolean to check if the value has been set.\nfunc (o *FileStatus) GetWorktreeOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Worktree, true\n}\n\n// SetWorktree sets field value\nfunc (o *FileStatus) SetWorktree(v string) {\n\to.Worktree = v\n}\n\n// GetExtra returns the Extra field value\nfunc (o *FileStatus) GetExtra() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Extra\n}\n\n// GetExtraOk returns a tuple with the Extra field value\n// and a boolean to check if the value has been set.\nfunc (o *FileStatus) GetExtraOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Extra, true\n}\n\n// SetExtra sets field value\nfunc (o *FileStatus) SetExtra(v string) {\n\to.Extra = v\n}\n\nfunc (o FileStatus) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o FileStatus) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"staging\"] = o.Staging\n\ttoSerialize[\"worktree\"] = o.Worktree\n\ttoSerialize[\"extra\"] = o.Extra\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *FileStatus) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"staging\",\n\t\t\"worktree\",\n\t\t\"extra\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarFileStatus := _FileStatus{}\n\n\terr = json.Unmarshal(data, &varFileStatus)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = FileStatus(varFileStatus)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"staging\")\n\t\tdelete(additionalProperties, \"worktree\")\n\t\tdelete(additionalProperties, \"extra\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableFileStatus struct {\n\tvalue *FileStatus\n\tisSet bool\n}\n\nfunc (v NullableFileStatus) Get() *FileStatus {\n\treturn v.value\n}\n\nfunc (v *NullableFileStatus) Set(val *FileStatus) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableFileStatus) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableFileStatus) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableFileStatus(val *FileStatus) *NullableFileStatus {\n\treturn &NullableFileStatus{value: val, isSet: true}\n}\n\nfunc (v NullableFileStatus) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableFileStatus) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_add_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitAddRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitAddRequest{}\n\n// GitAddRequest struct for GitAddRequest\ntype GitAddRequest struct {\n\tPath string `json:\"path\"`\n\t// files to add (use . for all files)\n\tFiles []string `json:\"files\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitAddRequest GitAddRequest\n\n// NewGitAddRequest instantiates a new GitAddRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitAddRequest(path string, files []string) *GitAddRequest {\n\tthis := GitAddRequest{}\n\tthis.Path = path\n\tthis.Files = files\n\treturn &this\n}\n\n// NewGitAddRequestWithDefaults instantiates a new GitAddRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitAddRequestWithDefaults() *GitAddRequest {\n\tthis := GitAddRequest{}\n\treturn &this\n}\n\n// GetPath returns the Path field value\nfunc (o *GitAddRequest) GetPath() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Path\n}\n\n// GetPathOk returns a tuple with the Path field value\n// and a boolean to check if the value has been set.\nfunc (o *GitAddRequest) GetPathOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Path, true\n}\n\n// SetPath sets field value\nfunc (o *GitAddRequest) SetPath(v string) {\n\to.Path = v\n}\n\n// GetFiles returns the Files field value\nfunc (o *GitAddRequest) GetFiles() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Files\n}\n\n// GetFilesOk returns a tuple with the Files field value\n// and a boolean to check if the value has been set.\nfunc (o *GitAddRequest) GetFilesOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Files, true\n}\n\n// SetFiles sets field value\nfunc (o *GitAddRequest) SetFiles(v []string) {\n\to.Files = v\n}\n\nfunc (o GitAddRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitAddRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"path\"] = o.Path\n\ttoSerialize[\"files\"] = o.Files\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitAddRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"path\",\n\t\t\"files\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitAddRequest := _GitAddRequest{}\n\n\terr = json.Unmarshal(data, &varGitAddRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitAddRequest(varGitAddRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"path\")\n\t\tdelete(additionalProperties, \"files\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitAddRequest struct {\n\tvalue *GitAddRequest\n\tisSet bool\n}\n\nfunc (v NullableGitAddRequest) Get() *GitAddRequest {\n\treturn v.value\n}\n\nfunc (v *NullableGitAddRequest) Set(val *GitAddRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitAddRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitAddRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitAddRequest(val *GitAddRequest) *NullableGitAddRequest {\n\treturn &NullableGitAddRequest{value: val, isSet: true}\n}\n\nfunc (v NullableGitAddRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitAddRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_branch_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitBranchRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitBranchRequest{}\n\n// GitBranchRequest struct for GitBranchRequest\ntype GitBranchRequest struct {\n\tPath string `json:\"path\"`\n\tName string `json:\"name\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitBranchRequest GitBranchRequest\n\n// NewGitBranchRequest instantiates a new GitBranchRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitBranchRequest(path string, name string) *GitBranchRequest {\n\tthis := GitBranchRequest{}\n\tthis.Path = path\n\tthis.Name = name\n\treturn &this\n}\n\n// NewGitBranchRequestWithDefaults instantiates a new GitBranchRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitBranchRequestWithDefaults() *GitBranchRequest {\n\tthis := GitBranchRequest{}\n\treturn &this\n}\n\n// GetPath returns the Path field value\nfunc (o *GitBranchRequest) GetPath() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Path\n}\n\n// GetPathOk returns a tuple with the Path field value\n// and a boolean to check if the value has been set.\nfunc (o *GitBranchRequest) GetPathOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Path, true\n}\n\n// SetPath sets field value\nfunc (o *GitBranchRequest) SetPath(v string) {\n\to.Path = v\n}\n\n// GetName returns the Name field value\nfunc (o *GitBranchRequest) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *GitBranchRequest) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *GitBranchRequest) SetName(v string) {\n\to.Name = v\n}\n\nfunc (o GitBranchRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitBranchRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"path\"] = o.Path\n\ttoSerialize[\"name\"] = o.Name\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitBranchRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"path\",\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitBranchRequest := _GitBranchRequest{}\n\n\terr = json.Unmarshal(data, &varGitBranchRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitBranchRequest(varGitBranchRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"path\")\n\t\tdelete(additionalProperties, \"name\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitBranchRequest struct {\n\tvalue *GitBranchRequest\n\tisSet bool\n}\n\nfunc (v NullableGitBranchRequest) Get() *GitBranchRequest {\n\treturn v.value\n}\n\nfunc (v *NullableGitBranchRequest) Set(val *GitBranchRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitBranchRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitBranchRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitBranchRequest(val *GitBranchRequest) *NullableGitBranchRequest {\n\treturn &NullableGitBranchRequest{value: val, isSet: true}\n}\n\nfunc (v NullableGitBranchRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitBranchRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_checkout_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitCheckoutRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitCheckoutRequest{}\n\n// GitCheckoutRequest struct for GitCheckoutRequest\ntype GitCheckoutRequest struct {\n\tPath string `json:\"path\"`\n\tBranch string `json:\"branch\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitCheckoutRequest GitCheckoutRequest\n\n// NewGitCheckoutRequest instantiates a new GitCheckoutRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitCheckoutRequest(path string, branch string) *GitCheckoutRequest {\n\tthis := GitCheckoutRequest{}\n\tthis.Path = path\n\tthis.Branch = branch\n\treturn &this\n}\n\n// NewGitCheckoutRequestWithDefaults instantiates a new GitCheckoutRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitCheckoutRequestWithDefaults() *GitCheckoutRequest {\n\tthis := GitCheckoutRequest{}\n\treturn &this\n}\n\n// GetPath returns the Path field value\nfunc (o *GitCheckoutRequest) GetPath() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Path\n}\n\n// GetPathOk returns a tuple with the Path field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCheckoutRequest) GetPathOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Path, true\n}\n\n// SetPath sets field value\nfunc (o *GitCheckoutRequest) SetPath(v string) {\n\to.Path = v\n}\n\n// GetBranch returns the Branch field value\nfunc (o *GitCheckoutRequest) GetBranch() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Branch\n}\n\n// GetBranchOk returns a tuple with the Branch field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCheckoutRequest) GetBranchOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Branch, true\n}\n\n// SetBranch sets field value\nfunc (o *GitCheckoutRequest) SetBranch(v string) {\n\to.Branch = v\n}\n\nfunc (o GitCheckoutRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitCheckoutRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"path\"] = o.Path\n\ttoSerialize[\"branch\"] = o.Branch\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitCheckoutRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"path\",\n\t\t\"branch\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitCheckoutRequest := _GitCheckoutRequest{}\n\n\terr = json.Unmarshal(data, &varGitCheckoutRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitCheckoutRequest(varGitCheckoutRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"path\")\n\t\tdelete(additionalProperties, \"branch\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitCheckoutRequest struct {\n\tvalue *GitCheckoutRequest\n\tisSet bool\n}\n\nfunc (v NullableGitCheckoutRequest) Get() *GitCheckoutRequest {\n\treturn v.value\n}\n\nfunc (v *NullableGitCheckoutRequest) Set(val *GitCheckoutRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitCheckoutRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitCheckoutRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitCheckoutRequest(val *GitCheckoutRequest) *NullableGitCheckoutRequest {\n\treturn &NullableGitCheckoutRequest{value: val, isSet: true}\n}\n\nfunc (v NullableGitCheckoutRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitCheckoutRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_clone_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitCloneRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitCloneRequest{}\n\n// GitCloneRequest struct for GitCloneRequest\ntype GitCloneRequest struct {\n\tUrl string `json:\"url\"`\n\tPath string `json:\"path\"`\n\tUsername *string `json:\"username,omitempty\"`\n\tPassword *string `json:\"password,omitempty\"`\n\tBranch *string `json:\"branch,omitempty\"`\n\tCommitId *string `json:\"commit_id,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitCloneRequest GitCloneRequest\n\n// NewGitCloneRequest instantiates a new GitCloneRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitCloneRequest(url string, path string) *GitCloneRequest {\n\tthis := GitCloneRequest{}\n\tthis.Url = url\n\tthis.Path = path\n\treturn &this\n}\n\n// NewGitCloneRequestWithDefaults instantiates a new GitCloneRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitCloneRequestWithDefaults() *GitCloneRequest {\n\tthis := GitCloneRequest{}\n\treturn &this\n}\n\n// GetUrl returns the Url field value\nfunc (o *GitCloneRequest) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCloneRequest) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *GitCloneRequest) SetUrl(v string) {\n\to.Url = v\n}\n\n// GetPath returns the Path field value\nfunc (o *GitCloneRequest) GetPath() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Path\n}\n\n// GetPathOk returns a tuple with the Path field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCloneRequest) GetPathOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Path, true\n}\n\n// SetPath sets field value\nfunc (o *GitCloneRequest) SetPath(v string) {\n\to.Path = v\n}\n\n// GetUsername returns the Username field value if set, zero value otherwise.\nfunc (o *GitCloneRequest) GetUsername() string {\n\tif o == nil || IsNil(o.Username) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Username\n}\n\n// GetUsernameOk returns a tuple with the Username field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitCloneRequest) GetUsernameOk() (*string, bool) {\n\tif o == nil || IsNil(o.Username) {\n\t\treturn nil, false\n\t}\n\treturn o.Username, true\n}\n\n// HasUsername returns a boolean if a field has been set.\nfunc (o *GitCloneRequest) HasUsername() bool {\n\tif o != nil && !IsNil(o.Username) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetUsername gets a reference to the given string and assigns it to the Username field.\nfunc (o *GitCloneRequest) SetUsername(v string) {\n\to.Username = &v\n}\n\n// GetPassword returns the Password field value if set, zero value otherwise.\nfunc (o *GitCloneRequest) GetPassword() string {\n\tif o == nil || IsNil(o.Password) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Password\n}\n\n// GetPasswordOk returns a tuple with the Password field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitCloneRequest) GetPasswordOk() (*string, bool) {\n\tif o == nil || IsNil(o.Password) {\n\t\treturn nil, false\n\t}\n\treturn o.Password, true\n}\n\n// HasPassword returns a boolean if a field has been set.\nfunc (o *GitCloneRequest) HasPassword() bool {\n\tif o != nil && !IsNil(o.Password) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPassword gets a reference to the given string and assigns it to the Password field.\nfunc (o *GitCloneRequest) SetPassword(v string) {\n\to.Password = &v\n}\n\n// GetBranch returns the Branch field value if set, zero value otherwise.\nfunc (o *GitCloneRequest) GetBranch() string {\n\tif o == nil || IsNil(o.Branch) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Branch\n}\n\n// GetBranchOk returns a tuple with the Branch field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitCloneRequest) GetBranchOk() (*string, bool) {\n\tif o == nil || IsNil(o.Branch) {\n\t\treturn nil, false\n\t}\n\treturn o.Branch, true\n}\n\n// HasBranch returns a boolean if a field has been set.\nfunc (o *GitCloneRequest) HasBranch() bool {\n\tif o != nil && !IsNil(o.Branch) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBranch gets a reference to the given string and assigns it to the Branch field.\nfunc (o *GitCloneRequest) SetBranch(v string) {\n\to.Branch = &v\n}\n\n// GetCommitId returns the CommitId field value if set, zero value otherwise.\nfunc (o *GitCloneRequest) GetCommitId() string {\n\tif o == nil || IsNil(o.CommitId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.CommitId\n}\n\n// GetCommitIdOk returns a tuple with the CommitId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitCloneRequest) GetCommitIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.CommitId) {\n\t\treturn nil, false\n\t}\n\treturn o.CommitId, true\n}\n\n// HasCommitId returns a boolean if a field has been set.\nfunc (o *GitCloneRequest) HasCommitId() bool {\n\tif o != nil && !IsNil(o.CommitId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCommitId gets a reference to the given string and assigns it to the CommitId field.\nfunc (o *GitCloneRequest) SetCommitId(v string) {\n\to.CommitId = &v\n}\n\nfunc (o GitCloneRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitCloneRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"url\"] = o.Url\n\ttoSerialize[\"path\"] = o.Path\n\tif !IsNil(o.Username) {\n\t\ttoSerialize[\"username\"] = o.Username\n\t}\n\tif !IsNil(o.Password) {\n\t\ttoSerialize[\"password\"] = o.Password\n\t}\n\tif !IsNil(o.Branch) {\n\t\ttoSerialize[\"branch\"] = o.Branch\n\t}\n\tif !IsNil(o.CommitId) {\n\t\ttoSerialize[\"commit_id\"] = o.CommitId\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitCloneRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"url\",\n\t\t\"path\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitCloneRequest := _GitCloneRequest{}\n\n\terr = json.Unmarshal(data, &varGitCloneRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitCloneRequest(varGitCloneRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"url\")\n\t\tdelete(additionalProperties, \"path\")\n\t\tdelete(additionalProperties, \"username\")\n\t\tdelete(additionalProperties, \"password\")\n\t\tdelete(additionalProperties, \"branch\")\n\t\tdelete(additionalProperties, \"commit_id\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitCloneRequest struct {\n\tvalue *GitCloneRequest\n\tisSet bool\n}\n\nfunc (v NullableGitCloneRequest) Get() *GitCloneRequest {\n\treturn v.value\n}\n\nfunc (v *NullableGitCloneRequest) Set(val *GitCloneRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitCloneRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitCloneRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitCloneRequest(val *GitCloneRequest) *NullableGitCloneRequest {\n\treturn &NullableGitCloneRequest{value: val, isSet: true}\n}\n\nfunc (v NullableGitCloneRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitCloneRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_commit_info.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitCommitInfo type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitCommitInfo{}\n\n// GitCommitInfo struct for GitCommitInfo\ntype GitCommitInfo struct {\n\tHash string `json:\"hash\"`\n\tMessage string `json:\"message\"`\n\tAuthor string `json:\"author\"`\n\tEmail string `json:\"email\"`\n\tTimestamp string `json:\"timestamp\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitCommitInfo GitCommitInfo\n\n// NewGitCommitInfo instantiates a new GitCommitInfo object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitCommitInfo(hash string, message string, author string, email string, timestamp string) *GitCommitInfo {\n\tthis := GitCommitInfo{}\n\tthis.Hash = hash\n\tthis.Message = message\n\tthis.Author = author\n\tthis.Email = email\n\tthis.Timestamp = timestamp\n\treturn &this\n}\n\n// NewGitCommitInfoWithDefaults instantiates a new GitCommitInfo object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitCommitInfoWithDefaults() *GitCommitInfo {\n\tthis := GitCommitInfo{}\n\treturn &this\n}\n\n// GetHash returns the Hash field value\nfunc (o *GitCommitInfo) GetHash() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Hash\n}\n\n// GetHashOk returns a tuple with the Hash field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitInfo) GetHashOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Hash, true\n}\n\n// SetHash sets field value\nfunc (o *GitCommitInfo) SetHash(v string) {\n\to.Hash = v\n}\n\n// GetMessage returns the Message field value\nfunc (o *GitCommitInfo) GetMessage() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Message\n}\n\n// GetMessageOk returns a tuple with the Message field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitInfo) GetMessageOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Message, true\n}\n\n// SetMessage sets field value\nfunc (o *GitCommitInfo) SetMessage(v string) {\n\to.Message = v\n}\n\n// GetAuthor returns the Author field value\nfunc (o *GitCommitInfo) GetAuthor() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Author\n}\n\n// GetAuthorOk returns a tuple with the Author field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitInfo) GetAuthorOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Author, true\n}\n\n// SetAuthor sets field value\nfunc (o *GitCommitInfo) SetAuthor(v string) {\n\to.Author = v\n}\n\n// GetEmail returns the Email field value\nfunc (o *GitCommitInfo) GetEmail() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Email\n}\n\n// GetEmailOk returns a tuple with the Email field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitInfo) GetEmailOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Email, true\n}\n\n// SetEmail sets field value\nfunc (o *GitCommitInfo) SetEmail(v string) {\n\to.Email = v\n}\n\n// GetTimestamp returns the Timestamp field value\nfunc (o *GitCommitInfo) GetTimestamp() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Timestamp\n}\n\n// GetTimestampOk returns a tuple with the Timestamp field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitInfo) GetTimestampOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Timestamp, true\n}\n\n// SetTimestamp sets field value\nfunc (o *GitCommitInfo) SetTimestamp(v string) {\n\to.Timestamp = v\n}\n\nfunc (o GitCommitInfo) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitCommitInfo) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"hash\"] = o.Hash\n\ttoSerialize[\"message\"] = o.Message\n\ttoSerialize[\"author\"] = o.Author\n\ttoSerialize[\"email\"] = o.Email\n\ttoSerialize[\"timestamp\"] = o.Timestamp\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitCommitInfo) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"hash\",\n\t\t\"message\",\n\t\t\"author\",\n\t\t\"email\",\n\t\t\"timestamp\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitCommitInfo := _GitCommitInfo{}\n\n\terr = json.Unmarshal(data, &varGitCommitInfo)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitCommitInfo(varGitCommitInfo)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"hash\")\n\t\tdelete(additionalProperties, \"message\")\n\t\tdelete(additionalProperties, \"author\")\n\t\tdelete(additionalProperties, \"email\")\n\t\tdelete(additionalProperties, \"timestamp\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitCommitInfo struct {\n\tvalue *GitCommitInfo\n\tisSet bool\n}\n\nfunc (v NullableGitCommitInfo) Get() *GitCommitInfo {\n\treturn v.value\n}\n\nfunc (v *NullableGitCommitInfo) Set(val *GitCommitInfo) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitCommitInfo) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitCommitInfo) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitCommitInfo(val *GitCommitInfo) *NullableGitCommitInfo {\n\treturn &NullableGitCommitInfo{value: val, isSet: true}\n}\n\nfunc (v NullableGitCommitInfo) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitCommitInfo) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_commit_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitCommitRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitCommitRequest{}\n\n// GitCommitRequest struct for GitCommitRequest\ntype GitCommitRequest struct {\n\tPath string `json:\"path\"`\n\tMessage string `json:\"message\"`\n\tAuthor string `json:\"author\"`\n\tEmail string `json:\"email\"`\n\t// Allow creating an empty commit when no changes are staged\n\tAllowEmpty *bool `json:\"allow_empty,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitCommitRequest GitCommitRequest\n\n// NewGitCommitRequest instantiates a new GitCommitRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitCommitRequest(path string, message string, author string, email string) *GitCommitRequest {\n\tthis := GitCommitRequest{}\n\tthis.Path = path\n\tthis.Message = message\n\tthis.Author = author\n\tthis.Email = email\n\tvar allowEmpty bool = false\n\tthis.AllowEmpty = &allowEmpty\n\treturn &this\n}\n\n// NewGitCommitRequestWithDefaults instantiates a new GitCommitRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitCommitRequestWithDefaults() *GitCommitRequest {\n\tthis := GitCommitRequest{}\n\tvar allowEmpty bool = false\n\tthis.AllowEmpty = &allowEmpty\n\treturn &this\n}\n\n// GetPath returns the Path field value\nfunc (o *GitCommitRequest) GetPath() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Path\n}\n\n// GetPathOk returns a tuple with the Path field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitRequest) GetPathOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Path, true\n}\n\n// SetPath sets field value\nfunc (o *GitCommitRequest) SetPath(v string) {\n\to.Path = v\n}\n\n// GetMessage returns the Message field value\nfunc (o *GitCommitRequest) GetMessage() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Message\n}\n\n// GetMessageOk returns a tuple with the Message field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitRequest) GetMessageOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Message, true\n}\n\n// SetMessage sets field value\nfunc (o *GitCommitRequest) SetMessage(v string) {\n\to.Message = v\n}\n\n// GetAuthor returns the Author field value\nfunc (o *GitCommitRequest) GetAuthor() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Author\n}\n\n// GetAuthorOk returns a tuple with the Author field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitRequest) GetAuthorOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Author, true\n}\n\n// SetAuthor sets field value\nfunc (o *GitCommitRequest) SetAuthor(v string) {\n\to.Author = v\n}\n\n// GetEmail returns the Email field value\nfunc (o *GitCommitRequest) GetEmail() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Email\n}\n\n// GetEmailOk returns a tuple with the Email field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitRequest) GetEmailOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Email, true\n}\n\n// SetEmail sets field value\nfunc (o *GitCommitRequest) SetEmail(v string) {\n\to.Email = v\n}\n\n// GetAllowEmpty returns the AllowEmpty field value if set, zero value otherwise.\nfunc (o *GitCommitRequest) GetAllowEmpty() bool {\n\tif o == nil || IsNil(o.AllowEmpty) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.AllowEmpty\n}\n\n// GetAllowEmptyOk returns a tuple with the AllowEmpty field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitRequest) GetAllowEmptyOk() (*bool, bool) {\n\tif o == nil || IsNil(o.AllowEmpty) {\n\t\treturn nil, false\n\t}\n\treturn o.AllowEmpty, true\n}\n\n// HasAllowEmpty returns a boolean if a field has been set.\nfunc (o *GitCommitRequest) HasAllowEmpty() bool {\n\tif o != nil && !IsNil(o.AllowEmpty) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAllowEmpty gets a reference to the given bool and assigns it to the AllowEmpty field.\nfunc (o *GitCommitRequest) SetAllowEmpty(v bool) {\n\to.AllowEmpty = &v\n}\n\nfunc (o GitCommitRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitCommitRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"path\"] = o.Path\n\ttoSerialize[\"message\"] = o.Message\n\ttoSerialize[\"author\"] = o.Author\n\ttoSerialize[\"email\"] = o.Email\n\tif !IsNil(o.AllowEmpty) {\n\t\ttoSerialize[\"allow_empty\"] = o.AllowEmpty\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitCommitRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"path\",\n\t\t\"message\",\n\t\t\"author\",\n\t\t\"email\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitCommitRequest := _GitCommitRequest{}\n\n\terr = json.Unmarshal(data, &varGitCommitRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitCommitRequest(varGitCommitRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"path\")\n\t\tdelete(additionalProperties, \"message\")\n\t\tdelete(additionalProperties, \"author\")\n\t\tdelete(additionalProperties, \"email\")\n\t\tdelete(additionalProperties, \"allow_empty\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitCommitRequest struct {\n\tvalue *GitCommitRequest\n\tisSet bool\n}\n\nfunc (v NullableGitCommitRequest) Get() *GitCommitRequest {\n\treturn v.value\n}\n\nfunc (v *NullableGitCommitRequest) Set(val *GitCommitRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitCommitRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitCommitRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitCommitRequest(val *GitCommitRequest) *NullableGitCommitRequest {\n\treturn &NullableGitCommitRequest{value: val, isSet: true}\n}\n\nfunc (v NullableGitCommitRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitCommitRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_commit_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitCommitResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitCommitResponse{}\n\n// GitCommitResponse struct for GitCommitResponse\ntype GitCommitResponse struct {\n\tHash string `json:\"hash\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitCommitResponse GitCommitResponse\n\n// NewGitCommitResponse instantiates a new GitCommitResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitCommitResponse(hash string) *GitCommitResponse {\n\tthis := GitCommitResponse{}\n\tthis.Hash = hash\n\treturn &this\n}\n\n// NewGitCommitResponseWithDefaults instantiates a new GitCommitResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitCommitResponseWithDefaults() *GitCommitResponse {\n\tthis := GitCommitResponse{}\n\treturn &this\n}\n\n// GetHash returns the Hash field value\nfunc (o *GitCommitResponse) GetHash() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Hash\n}\n\n// GetHashOk returns a tuple with the Hash field value\n// and a boolean to check if the value has been set.\nfunc (o *GitCommitResponse) GetHashOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Hash, true\n}\n\n// SetHash sets field value\nfunc (o *GitCommitResponse) SetHash(v string) {\n\to.Hash = v\n}\n\nfunc (o GitCommitResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitCommitResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"hash\"] = o.Hash\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitCommitResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"hash\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitCommitResponse := _GitCommitResponse{}\n\n\terr = json.Unmarshal(data, &varGitCommitResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitCommitResponse(varGitCommitResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"hash\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitCommitResponse struct {\n\tvalue *GitCommitResponse\n\tisSet bool\n}\n\nfunc (v NullableGitCommitResponse) Get() *GitCommitResponse {\n\treturn v.value\n}\n\nfunc (v *NullableGitCommitResponse) Set(val *GitCommitResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitCommitResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitCommitResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitCommitResponse(val *GitCommitResponse) *NullableGitCommitResponse {\n\treturn &NullableGitCommitResponse{value: val, isSet: true}\n}\n\nfunc (v NullableGitCommitResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitCommitResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_delete_branch_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitDeleteBranchRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitDeleteBranchRequest{}\n\n// GitDeleteBranchRequest struct for GitDeleteBranchRequest\ntype GitDeleteBranchRequest struct {\n\tPath string `json:\"path\"`\n\tName string `json:\"name\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitDeleteBranchRequest GitDeleteBranchRequest\n\n// NewGitDeleteBranchRequest instantiates a new GitDeleteBranchRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitDeleteBranchRequest(path string, name string) *GitDeleteBranchRequest {\n\tthis := GitDeleteBranchRequest{}\n\tthis.Path = path\n\tthis.Name = name\n\treturn &this\n}\n\n// NewGitDeleteBranchRequestWithDefaults instantiates a new GitDeleteBranchRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitDeleteBranchRequestWithDefaults() *GitDeleteBranchRequest {\n\tthis := GitDeleteBranchRequest{}\n\treturn &this\n}\n\n// GetPath returns the Path field value\nfunc (o *GitDeleteBranchRequest) GetPath() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Path\n}\n\n// GetPathOk returns a tuple with the Path field value\n// and a boolean to check if the value has been set.\nfunc (o *GitDeleteBranchRequest) GetPathOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Path, true\n}\n\n// SetPath sets field value\nfunc (o *GitDeleteBranchRequest) SetPath(v string) {\n\to.Path = v\n}\n\n// GetName returns the Name field value\nfunc (o *GitDeleteBranchRequest) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *GitDeleteBranchRequest) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *GitDeleteBranchRequest) SetName(v string) {\n\to.Name = v\n}\n\nfunc (o GitDeleteBranchRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitDeleteBranchRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"path\"] = o.Path\n\ttoSerialize[\"name\"] = o.Name\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitDeleteBranchRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"path\",\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitDeleteBranchRequest := _GitDeleteBranchRequest{}\n\n\terr = json.Unmarshal(data, &varGitDeleteBranchRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitDeleteBranchRequest(varGitDeleteBranchRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"path\")\n\t\tdelete(additionalProperties, \"name\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitDeleteBranchRequest struct {\n\tvalue *GitDeleteBranchRequest\n\tisSet bool\n}\n\nfunc (v NullableGitDeleteBranchRequest) Get() *GitDeleteBranchRequest {\n\treturn v.value\n}\n\nfunc (v *NullableGitDeleteBranchRequest) Set(val *GitDeleteBranchRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitDeleteBranchRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitDeleteBranchRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitDeleteBranchRequest(val *GitDeleteBranchRequest) *NullableGitDeleteBranchRequest {\n\treturn &NullableGitDeleteBranchRequest{value: val, isSet: true}\n}\n\nfunc (v NullableGitDeleteBranchRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitDeleteBranchRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_repo_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitRepoRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitRepoRequest{}\n\n// GitRepoRequest struct for GitRepoRequest\ntype GitRepoRequest struct {\n\tPath string `json:\"path\"`\n\tUsername *string `json:\"username,omitempty\"`\n\tPassword *string `json:\"password,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitRepoRequest GitRepoRequest\n\n// NewGitRepoRequest instantiates a new GitRepoRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitRepoRequest(path string) *GitRepoRequest {\n\tthis := GitRepoRequest{}\n\tthis.Path = path\n\treturn &this\n}\n\n// NewGitRepoRequestWithDefaults instantiates a new GitRepoRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitRepoRequestWithDefaults() *GitRepoRequest {\n\tthis := GitRepoRequest{}\n\treturn &this\n}\n\n// GetPath returns the Path field value\nfunc (o *GitRepoRequest) GetPath() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Path\n}\n\n// GetPathOk returns a tuple with the Path field value\n// and a boolean to check if the value has been set.\nfunc (o *GitRepoRequest) GetPathOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Path, true\n}\n\n// SetPath sets field value\nfunc (o *GitRepoRequest) SetPath(v string) {\n\to.Path = v\n}\n\n// GetUsername returns the Username field value if set, zero value otherwise.\nfunc (o *GitRepoRequest) GetUsername() string {\n\tif o == nil || IsNil(o.Username) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Username\n}\n\n// GetUsernameOk returns a tuple with the Username field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitRepoRequest) GetUsernameOk() (*string, bool) {\n\tif o == nil || IsNil(o.Username) {\n\t\treturn nil, false\n\t}\n\treturn o.Username, true\n}\n\n// HasUsername returns a boolean if a field has been set.\nfunc (o *GitRepoRequest) HasUsername() bool {\n\tif o != nil && !IsNil(o.Username) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetUsername gets a reference to the given string and assigns it to the Username field.\nfunc (o *GitRepoRequest) SetUsername(v string) {\n\to.Username = &v\n}\n\n// GetPassword returns the Password field value if set, zero value otherwise.\nfunc (o *GitRepoRequest) GetPassword() string {\n\tif o == nil || IsNil(o.Password) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Password\n}\n\n// GetPasswordOk returns a tuple with the Password field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitRepoRequest) GetPasswordOk() (*string, bool) {\n\tif o == nil || IsNil(o.Password) {\n\t\treturn nil, false\n\t}\n\treturn o.Password, true\n}\n\n// HasPassword returns a boolean if a field has been set.\nfunc (o *GitRepoRequest) HasPassword() bool {\n\tif o != nil && !IsNil(o.Password) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPassword gets a reference to the given string and assigns it to the Password field.\nfunc (o *GitRepoRequest) SetPassword(v string) {\n\to.Password = &v\n}\n\nfunc (o GitRepoRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitRepoRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"path\"] = o.Path\n\tif !IsNil(o.Username) {\n\t\ttoSerialize[\"username\"] = o.Username\n\t}\n\tif !IsNil(o.Password) {\n\t\ttoSerialize[\"password\"] = o.Password\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitRepoRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"path\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitRepoRequest := _GitRepoRequest{}\n\n\terr = json.Unmarshal(data, &varGitRepoRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitRepoRequest(varGitRepoRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"path\")\n\t\tdelete(additionalProperties, \"username\")\n\t\tdelete(additionalProperties, \"password\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitRepoRequest struct {\n\tvalue *GitRepoRequest\n\tisSet bool\n}\n\nfunc (v NullableGitRepoRequest) Get() *GitRepoRequest {\n\treturn v.value\n}\n\nfunc (v *NullableGitRepoRequest) Set(val *GitRepoRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitRepoRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitRepoRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitRepoRequest(val *GitRepoRequest) *NullableGitRepoRequest {\n\treturn &NullableGitRepoRequest{value: val, isSet: true}\n}\n\nfunc (v NullableGitRepoRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitRepoRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_git_status.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the GitStatus type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &GitStatus{}\n\n// GitStatus struct for GitStatus\ntype GitStatus struct {\n\tCurrentBranch string `json:\"currentBranch\"`\n\tFileStatus []FileStatus `json:\"fileStatus\"`\n\tAhead *float32 `json:\"ahead,omitempty\"`\n\tBehind *float32 `json:\"behind,omitempty\"`\n\tBranchPublished *bool `json:\"branchPublished,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _GitStatus GitStatus\n\n// NewGitStatus instantiates a new GitStatus object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewGitStatus(currentBranch string, fileStatus []FileStatus) *GitStatus {\n\tthis := GitStatus{}\n\tthis.CurrentBranch = currentBranch\n\tthis.FileStatus = fileStatus\n\treturn &this\n}\n\n// NewGitStatusWithDefaults instantiates a new GitStatus object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewGitStatusWithDefaults() *GitStatus {\n\tthis := GitStatus{}\n\treturn &this\n}\n\n// GetCurrentBranch returns the CurrentBranch field value\nfunc (o *GitStatus) GetCurrentBranch() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CurrentBranch\n}\n\n// GetCurrentBranchOk returns a tuple with the CurrentBranch field value\n// and a boolean to check if the value has been set.\nfunc (o *GitStatus) GetCurrentBranchOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentBranch, true\n}\n\n// SetCurrentBranch sets field value\nfunc (o *GitStatus) SetCurrentBranch(v string) {\n\to.CurrentBranch = v\n}\n\n// GetFileStatus returns the FileStatus field value\nfunc (o *GitStatus) GetFileStatus() []FileStatus {\n\tif o == nil {\n\t\tvar ret []FileStatus\n\t\treturn ret\n\t}\n\n\treturn o.FileStatus\n}\n\n// GetFileStatusOk returns a tuple with the FileStatus field value\n// and a boolean to check if the value has been set.\nfunc (o *GitStatus) GetFileStatusOk() ([]FileStatus, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.FileStatus, true\n}\n\n// SetFileStatus sets field value\nfunc (o *GitStatus) SetFileStatus(v []FileStatus) {\n\to.FileStatus = v\n}\n\n// GetAhead returns the Ahead field value if set, zero value otherwise.\nfunc (o *GitStatus) GetAhead() float32 {\n\tif o == nil || IsNil(o.Ahead) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Ahead\n}\n\n// GetAheadOk returns a tuple with the Ahead field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitStatus) GetAheadOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Ahead) {\n\t\treturn nil, false\n\t}\n\treturn o.Ahead, true\n}\n\n// HasAhead returns a boolean if a field has been set.\nfunc (o *GitStatus) HasAhead() bool {\n\tif o != nil && !IsNil(o.Ahead) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAhead gets a reference to the given float32 and assigns it to the Ahead field.\nfunc (o *GitStatus) SetAhead(v float32) {\n\to.Ahead = &v\n}\n\n// GetBehind returns the Behind field value if set, zero value otherwise.\nfunc (o *GitStatus) GetBehind() float32 {\n\tif o == nil || IsNil(o.Behind) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Behind\n}\n\n// GetBehindOk returns a tuple with the Behind field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitStatus) GetBehindOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Behind) {\n\t\treturn nil, false\n\t}\n\treturn o.Behind, true\n}\n\n// HasBehind returns a boolean if a field has been set.\nfunc (o *GitStatus) HasBehind() bool {\n\tif o != nil && !IsNil(o.Behind) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBehind gets a reference to the given float32 and assigns it to the Behind field.\nfunc (o *GitStatus) SetBehind(v float32) {\n\to.Behind = &v\n}\n\n// GetBranchPublished returns the BranchPublished field value if set, zero value otherwise.\nfunc (o *GitStatus) GetBranchPublished() bool {\n\tif o == nil || IsNil(o.BranchPublished) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.BranchPublished\n}\n\n// GetBranchPublishedOk returns a tuple with the BranchPublished field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *GitStatus) GetBranchPublishedOk() (*bool, bool) {\n\tif o == nil || IsNil(o.BranchPublished) {\n\t\treturn nil, false\n\t}\n\treturn o.BranchPublished, true\n}\n\n// HasBranchPublished returns a boolean if a field has been set.\nfunc (o *GitStatus) HasBranchPublished() bool {\n\tif o != nil && !IsNil(o.BranchPublished) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBranchPublished gets a reference to the given bool and assigns it to the BranchPublished field.\nfunc (o *GitStatus) SetBranchPublished(v bool) {\n\to.BranchPublished = &v\n}\n\nfunc (o GitStatus) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o GitStatus) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"currentBranch\"] = o.CurrentBranch\n\ttoSerialize[\"fileStatus\"] = o.FileStatus\n\tif !IsNil(o.Ahead) {\n\t\ttoSerialize[\"ahead\"] = o.Ahead\n\t}\n\tif !IsNil(o.Behind) {\n\t\ttoSerialize[\"behind\"] = o.Behind\n\t}\n\tif !IsNil(o.BranchPublished) {\n\t\ttoSerialize[\"branchPublished\"] = o.BranchPublished\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *GitStatus) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"currentBranch\",\n\t\t\"fileStatus\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarGitStatus := _GitStatus{}\n\n\terr = json.Unmarshal(data, &varGitStatus)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = GitStatus(varGitStatus)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"currentBranch\")\n\t\tdelete(additionalProperties, \"fileStatus\")\n\t\tdelete(additionalProperties, \"ahead\")\n\t\tdelete(additionalProperties, \"behind\")\n\t\tdelete(additionalProperties, \"branchPublished\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableGitStatus struct {\n\tvalue *GitStatus\n\tisSet bool\n}\n\nfunc (v NullableGitStatus) Get() *GitStatus {\n\treturn v.value\n}\n\nfunc (v *NullableGitStatus) Set(val *GitStatus) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableGitStatus) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableGitStatus) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableGitStatus(val *GitStatus) *NullableGitStatus {\n\treturn &NullableGitStatus{value: val, isSet: true}\n}\n\nfunc (v NullableGitStatus) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableGitStatus) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_health_controller_check_200_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the HealthControllerCheck200Response type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &HealthControllerCheck200Response{}\n\n// HealthControllerCheck200Response struct for HealthControllerCheck200Response\ntype HealthControllerCheck200Response struct {\n\tStatus *string `json:\"status,omitempty\"`\n\tInfo map[string]HealthControllerCheck200ResponseInfoValue `json:\"info,omitempty\"`\n\tError map[string]HealthControllerCheck200ResponseInfoValue `json:\"error,omitempty\"`\n\tDetails *map[string]HealthControllerCheck200ResponseInfoValue `json:\"details,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _HealthControllerCheck200Response HealthControllerCheck200Response\n\n// NewHealthControllerCheck200Response instantiates a new HealthControllerCheck200Response object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewHealthControllerCheck200Response() *HealthControllerCheck200Response {\n\tthis := HealthControllerCheck200Response{}\n\treturn &this\n}\n\n// NewHealthControllerCheck200ResponseWithDefaults instantiates a new HealthControllerCheck200Response object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewHealthControllerCheck200ResponseWithDefaults() *HealthControllerCheck200Response {\n\tthis := HealthControllerCheck200Response{}\n\treturn &this\n}\n\n// GetStatus returns the Status field value if set, zero value otherwise.\nfunc (o *HealthControllerCheck200Response) GetStatus() string {\n\tif o == nil || IsNil(o.Status) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *HealthControllerCheck200Response) GetStatusOk() (*string, bool) {\n\tif o == nil || IsNil(o.Status) {\n\t\treturn nil, false\n\t}\n\treturn o.Status, true\n}\n\n// HasStatus returns a boolean if a field has been set.\nfunc (o *HealthControllerCheck200Response) HasStatus() bool {\n\tif o != nil && !IsNil(o.Status) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetStatus gets a reference to the given string and assigns it to the Status field.\nfunc (o *HealthControllerCheck200Response) SetStatus(v string) {\n\to.Status = &v\n}\n\n// GetInfo returns the Info field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *HealthControllerCheck200Response) GetInfo() map[string]HealthControllerCheck200ResponseInfoValue {\n\tif o == nil {\n\t\tvar ret map[string]HealthControllerCheck200ResponseInfoValue\n\t\treturn ret\n\t}\n\treturn o.Info\n}\n\n// GetInfoOk returns a tuple with the Info field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *HealthControllerCheck200Response) GetInfoOk() (*map[string]HealthControllerCheck200ResponseInfoValue, bool) {\n\tif o == nil || IsNil(o.Info) {\n\t\treturn nil, false\n\t}\n\treturn &o.Info, true\n}\n\n// HasInfo returns a boolean if a field has been set.\nfunc (o *HealthControllerCheck200Response) HasInfo() bool {\n\tif o != nil && !IsNil(o.Info) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetInfo gets a reference to the given map[string]HealthControllerCheck200ResponseInfoValue and assigns it to the Info field.\nfunc (o *HealthControllerCheck200Response) SetInfo(v map[string]HealthControllerCheck200ResponseInfoValue) {\n\to.Info = v\n}\n\n// GetError returns the Error field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *HealthControllerCheck200Response) GetError() map[string]HealthControllerCheck200ResponseInfoValue {\n\tif o == nil {\n\t\tvar ret map[string]HealthControllerCheck200ResponseInfoValue\n\t\treturn ret\n\t}\n\treturn o.Error\n}\n\n// GetErrorOk returns a tuple with the Error field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *HealthControllerCheck200Response) GetErrorOk() (*map[string]HealthControllerCheck200ResponseInfoValue, bool) {\n\tif o == nil || IsNil(o.Error) {\n\t\treturn nil, false\n\t}\n\treturn &o.Error, true\n}\n\n// HasError returns a boolean if a field has been set.\nfunc (o *HealthControllerCheck200Response) HasError() bool {\n\tif o != nil && !IsNil(o.Error) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetError gets a reference to the given map[string]HealthControllerCheck200ResponseInfoValue and assigns it to the Error field.\nfunc (o *HealthControllerCheck200Response) SetError(v map[string]HealthControllerCheck200ResponseInfoValue) {\n\to.Error = v\n}\n\n// GetDetails returns the Details field value if set, zero value otherwise.\nfunc (o *HealthControllerCheck200Response) GetDetails() map[string]HealthControllerCheck200ResponseInfoValue {\n\tif o == nil || IsNil(o.Details) {\n\t\tvar ret map[string]HealthControllerCheck200ResponseInfoValue\n\t\treturn ret\n\t}\n\treturn *o.Details\n}\n\n// GetDetailsOk returns a tuple with the Details field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *HealthControllerCheck200Response) GetDetailsOk() (*map[string]HealthControllerCheck200ResponseInfoValue, bool) {\n\tif o == nil || IsNil(o.Details) {\n\t\treturn nil, false\n\t}\n\treturn o.Details, true\n}\n\n// HasDetails returns a boolean if a field has been set.\nfunc (o *HealthControllerCheck200Response) HasDetails() bool {\n\tif o != nil && !IsNil(o.Details) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDetails gets a reference to the given map[string]HealthControllerCheck200ResponseInfoValue and assigns it to the Details field.\nfunc (o *HealthControllerCheck200Response) SetDetails(v map[string]HealthControllerCheck200ResponseInfoValue) {\n\to.Details = &v\n}\n\nfunc (o HealthControllerCheck200Response) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o HealthControllerCheck200Response) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Status) {\n\t\ttoSerialize[\"status\"] = o.Status\n\t}\n\tif o.Info != nil {\n\t\ttoSerialize[\"info\"] = o.Info\n\t}\n\tif o.Error != nil {\n\t\ttoSerialize[\"error\"] = o.Error\n\t}\n\tif !IsNil(o.Details) {\n\t\ttoSerialize[\"details\"] = o.Details\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *HealthControllerCheck200Response) UnmarshalJSON(data []byte) (err error) {\n\tvarHealthControllerCheck200Response := _HealthControllerCheck200Response{}\n\n\terr = json.Unmarshal(data, &varHealthControllerCheck200Response)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = HealthControllerCheck200Response(varHealthControllerCheck200Response)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"status\")\n\t\tdelete(additionalProperties, \"info\")\n\t\tdelete(additionalProperties, \"error\")\n\t\tdelete(additionalProperties, \"details\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableHealthControllerCheck200Response struct {\n\tvalue *HealthControllerCheck200Response\n\tisSet bool\n}\n\nfunc (v NullableHealthControllerCheck200Response) Get() *HealthControllerCheck200Response {\n\treturn v.value\n}\n\nfunc (v *NullableHealthControllerCheck200Response) Set(val *HealthControllerCheck200Response) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableHealthControllerCheck200Response) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableHealthControllerCheck200Response) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableHealthControllerCheck200Response(val *HealthControllerCheck200Response) *NullableHealthControllerCheck200Response {\n\treturn &NullableHealthControllerCheck200Response{value: val, isSet: true}\n}\n\nfunc (v NullableHealthControllerCheck200Response) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableHealthControllerCheck200Response) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_health_controller_check_200_response_info_value.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the HealthControllerCheck200ResponseInfoValue type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &HealthControllerCheck200ResponseInfoValue{}\n\n// HealthControllerCheck200ResponseInfoValue struct for HealthControllerCheck200ResponseInfoValue\ntype HealthControllerCheck200ResponseInfoValue struct {\n\tStatus string `json:\"status\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _HealthControllerCheck200ResponseInfoValue HealthControllerCheck200ResponseInfoValue\n\n// NewHealthControllerCheck200ResponseInfoValue instantiates a new HealthControllerCheck200ResponseInfoValue object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewHealthControllerCheck200ResponseInfoValue(status string) *HealthControllerCheck200ResponseInfoValue {\n\tthis := HealthControllerCheck200ResponseInfoValue{}\n\tthis.Status = status\n\treturn &this\n}\n\n// NewHealthControllerCheck200ResponseInfoValueWithDefaults instantiates a new HealthControllerCheck200ResponseInfoValue object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewHealthControllerCheck200ResponseInfoValueWithDefaults() *HealthControllerCheck200ResponseInfoValue {\n\tthis := HealthControllerCheck200ResponseInfoValue{}\n\treturn &this\n}\n\n// GetStatus returns the Status field value\nfunc (o *HealthControllerCheck200ResponseInfoValue) GetStatus() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value\n// and a boolean to check if the value has been set.\nfunc (o *HealthControllerCheck200ResponseInfoValue) GetStatusOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Status, true\n}\n\n// SetStatus sets field value\nfunc (o *HealthControllerCheck200ResponseInfoValue) SetStatus(v string) {\n\to.Status = v\n}\n\nfunc (o HealthControllerCheck200ResponseInfoValue) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o HealthControllerCheck200ResponseInfoValue) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"status\"] = o.Status\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *HealthControllerCheck200ResponseInfoValue) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"status\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarHealthControllerCheck200ResponseInfoValue := _HealthControllerCheck200ResponseInfoValue{}\n\n\terr = json.Unmarshal(data, &varHealthControllerCheck200ResponseInfoValue)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = HealthControllerCheck200ResponseInfoValue(varHealthControllerCheck200ResponseInfoValue)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"status\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableHealthControllerCheck200ResponseInfoValue struct {\n\tvalue *HealthControllerCheck200ResponseInfoValue\n\tisSet bool\n}\n\nfunc (v NullableHealthControllerCheck200ResponseInfoValue) Get() *HealthControllerCheck200ResponseInfoValue {\n\treturn v.value\n}\n\nfunc (v *NullableHealthControllerCheck200ResponseInfoValue) Set(val *HealthControllerCheck200ResponseInfoValue) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableHealthControllerCheck200ResponseInfoValue) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableHealthControllerCheck200ResponseInfoValue) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableHealthControllerCheck200ResponseInfoValue(val *HealthControllerCheck200ResponseInfoValue) *NullableHealthControllerCheck200ResponseInfoValue {\n\treturn &NullableHealthControllerCheck200ResponseInfoValue{value: val, isSet: true}\n}\n\nfunc (v NullableHealthControllerCheck200ResponseInfoValue) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableHealthControllerCheck200ResponseInfoValue) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_health_controller_check_503_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the HealthControllerCheck503Response type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &HealthControllerCheck503Response{}\n\n// HealthControllerCheck503Response struct for HealthControllerCheck503Response\ntype HealthControllerCheck503Response struct {\n\tStatus *string `json:\"status,omitempty\"`\n\tInfo map[string]HealthControllerCheck200ResponseInfoValue `json:\"info,omitempty\"`\n\tError map[string]HealthControllerCheck200ResponseInfoValue `json:\"error,omitempty\"`\n\tDetails *map[string]HealthControllerCheck200ResponseInfoValue `json:\"details,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _HealthControllerCheck503Response HealthControllerCheck503Response\n\n// NewHealthControllerCheck503Response instantiates a new HealthControllerCheck503Response object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewHealthControllerCheck503Response() *HealthControllerCheck503Response {\n\tthis := HealthControllerCheck503Response{}\n\treturn &this\n}\n\n// NewHealthControllerCheck503ResponseWithDefaults instantiates a new HealthControllerCheck503Response object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewHealthControllerCheck503ResponseWithDefaults() *HealthControllerCheck503Response {\n\tthis := HealthControllerCheck503Response{}\n\treturn &this\n}\n\n// GetStatus returns the Status field value if set, zero value otherwise.\nfunc (o *HealthControllerCheck503Response) GetStatus() string {\n\tif o == nil || IsNil(o.Status) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *HealthControllerCheck503Response) GetStatusOk() (*string, bool) {\n\tif o == nil || IsNil(o.Status) {\n\t\treturn nil, false\n\t}\n\treturn o.Status, true\n}\n\n// HasStatus returns a boolean if a field has been set.\nfunc (o *HealthControllerCheck503Response) HasStatus() bool {\n\tif o != nil && !IsNil(o.Status) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetStatus gets a reference to the given string and assigns it to the Status field.\nfunc (o *HealthControllerCheck503Response) SetStatus(v string) {\n\to.Status = &v\n}\n\n// GetInfo returns the Info field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *HealthControllerCheck503Response) GetInfo() map[string]HealthControllerCheck200ResponseInfoValue {\n\tif o == nil {\n\t\tvar ret map[string]HealthControllerCheck200ResponseInfoValue\n\t\treturn ret\n\t}\n\treturn o.Info\n}\n\n// GetInfoOk returns a tuple with the Info field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *HealthControllerCheck503Response) GetInfoOk() (*map[string]HealthControllerCheck200ResponseInfoValue, bool) {\n\tif o == nil || IsNil(o.Info) {\n\t\treturn nil, false\n\t}\n\treturn &o.Info, true\n}\n\n// HasInfo returns a boolean if a field has been set.\nfunc (o *HealthControllerCheck503Response) HasInfo() bool {\n\tif o != nil && !IsNil(o.Info) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetInfo gets a reference to the given map[string]HealthControllerCheck200ResponseInfoValue and assigns it to the Info field.\nfunc (o *HealthControllerCheck503Response) SetInfo(v map[string]HealthControllerCheck200ResponseInfoValue) {\n\to.Info = v\n}\n\n// GetError returns the Error field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *HealthControllerCheck503Response) GetError() map[string]HealthControllerCheck200ResponseInfoValue {\n\tif o == nil {\n\t\tvar ret map[string]HealthControllerCheck200ResponseInfoValue\n\t\treturn ret\n\t}\n\treturn o.Error\n}\n\n// GetErrorOk returns a tuple with the Error field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *HealthControllerCheck503Response) GetErrorOk() (*map[string]HealthControllerCheck200ResponseInfoValue, bool) {\n\tif o == nil || IsNil(o.Error) {\n\t\treturn nil, false\n\t}\n\treturn &o.Error, true\n}\n\n// HasError returns a boolean if a field has been set.\nfunc (o *HealthControllerCheck503Response) HasError() bool {\n\tif o != nil && !IsNil(o.Error) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetError gets a reference to the given map[string]HealthControllerCheck200ResponseInfoValue and assigns it to the Error field.\nfunc (o *HealthControllerCheck503Response) SetError(v map[string]HealthControllerCheck200ResponseInfoValue) {\n\to.Error = v\n}\n\n// GetDetails returns the Details field value if set, zero value otherwise.\nfunc (o *HealthControllerCheck503Response) GetDetails() map[string]HealthControllerCheck200ResponseInfoValue {\n\tif o == nil || IsNil(o.Details) {\n\t\tvar ret map[string]HealthControllerCheck200ResponseInfoValue\n\t\treturn ret\n\t}\n\treturn *o.Details\n}\n\n// GetDetailsOk returns a tuple with the Details field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *HealthControllerCheck503Response) GetDetailsOk() (*map[string]HealthControllerCheck200ResponseInfoValue, bool) {\n\tif o == nil || IsNil(o.Details) {\n\t\treturn nil, false\n\t}\n\treturn o.Details, true\n}\n\n// HasDetails returns a boolean if a field has been set.\nfunc (o *HealthControllerCheck503Response) HasDetails() bool {\n\tif o != nil && !IsNil(o.Details) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDetails gets a reference to the given map[string]HealthControllerCheck200ResponseInfoValue and assigns it to the Details field.\nfunc (o *HealthControllerCheck503Response) SetDetails(v map[string]HealthControllerCheck200ResponseInfoValue) {\n\to.Details = &v\n}\n\nfunc (o HealthControllerCheck503Response) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o HealthControllerCheck503Response) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Status) {\n\t\ttoSerialize[\"status\"] = o.Status\n\t}\n\tif o.Info != nil {\n\t\ttoSerialize[\"info\"] = o.Info\n\t}\n\tif o.Error != nil {\n\t\ttoSerialize[\"error\"] = o.Error\n\t}\n\tif !IsNil(o.Details) {\n\t\ttoSerialize[\"details\"] = o.Details\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *HealthControllerCheck503Response) UnmarshalJSON(data []byte) (err error) {\n\tvarHealthControllerCheck503Response := _HealthControllerCheck503Response{}\n\n\terr = json.Unmarshal(data, &varHealthControllerCheck503Response)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = HealthControllerCheck503Response(varHealthControllerCheck503Response)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"status\")\n\t\tdelete(additionalProperties, \"info\")\n\t\tdelete(additionalProperties, \"error\")\n\t\tdelete(additionalProperties, \"details\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableHealthControllerCheck503Response struct {\n\tvalue *HealthControllerCheck503Response\n\tisSet bool\n}\n\nfunc (v NullableHealthControllerCheck503Response) Get() *HealthControllerCheck503Response {\n\treturn v.value\n}\n\nfunc (v *NullableHealthControllerCheck503Response) Set(val *HealthControllerCheck503Response) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableHealthControllerCheck503Response) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableHealthControllerCheck503Response) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableHealthControllerCheck503Response(val *HealthControllerCheck503Response) *NullableHealthControllerCheck503Response {\n\treturn &NullableHealthControllerCheck503Response{value: val, isSet: true}\n}\n\nfunc (v NullableHealthControllerCheck503Response) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableHealthControllerCheck503Response) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_job.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Job type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Job{}\n\n// Job struct for Job\ntype Job struct {\n\t// The ID of the job\n\tId string `json:\"id\"`\n\t// The type of the job\n\tType JobType `json:\"type\"`\n\t// The status of the job\n\tStatus JobStatus `json:\"status\"`\n\t// The type of resource this job operates on\n\tResourceType string `json:\"resourceType\"`\n\t// The ID of the resource this job operates on (sandboxId, snapshotRef, etc.)\n\tResourceId string `json:\"resourceId\"`\n\t// Job-specific JSON-encoded payload data (operational metadata)\n\tPayload *string `json:\"payload,omitempty\"`\n\t// OpenTelemetry trace context for distributed tracing (W3C Trace Context format)\n\tTraceContext map[string]interface{} `json:\"traceContext,omitempty\"`\n\t// Error message if the job failed\n\tErrorMessage *string `json:\"errorMessage,omitempty\"`\n\t// The creation timestamp of the job\n\tCreatedAt string `json:\"createdAt\"`\n\t// The last update timestamp of the job\n\tUpdatedAt *string `json:\"updatedAt,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Job Job\n\n// NewJob instantiates a new Job object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewJob(id string, type_ JobType, status JobStatus, resourceType string, resourceId string, createdAt string) *Job {\n\tthis := Job{}\n\tthis.Id = id\n\tthis.Type = type_\n\tthis.Status = status\n\tthis.ResourceType = resourceType\n\tthis.ResourceId = resourceId\n\tthis.CreatedAt = createdAt\n\treturn &this\n}\n\n// NewJobWithDefaults instantiates a new Job object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewJobWithDefaults() *Job {\n\tthis := Job{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *Job) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *Job) SetId(v string) {\n\to.Id = v\n}\n\n// GetType returns the Type field value\nfunc (o *Job) GetType() JobType {\n\tif o == nil {\n\t\tvar ret JobType\n\t\treturn ret\n\t}\n\n\treturn o.Type\n}\n\n// GetTypeOk returns a tuple with the Type field value\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetTypeOk() (*JobType, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Type, true\n}\n\n// SetType sets field value\nfunc (o *Job) SetType(v JobType) {\n\to.Type = v\n}\n\n// GetStatus returns the Status field value\nfunc (o *Job) GetStatus() JobStatus {\n\tif o == nil {\n\t\tvar ret JobStatus\n\t\treturn ret\n\t}\n\n\treturn o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetStatusOk() (*JobStatus, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Status, true\n}\n\n// SetStatus sets field value\nfunc (o *Job) SetStatus(v JobStatus) {\n\to.Status = v\n}\n\n// GetResourceType returns the ResourceType field value\nfunc (o *Job) GetResourceType() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ResourceType\n}\n\n// GetResourceTypeOk returns a tuple with the ResourceType field value\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetResourceTypeOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ResourceType, true\n}\n\n// SetResourceType sets field value\nfunc (o *Job) SetResourceType(v string) {\n\to.ResourceType = v\n}\n\n// GetResourceId returns the ResourceId field value\nfunc (o *Job) GetResourceId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ResourceId\n}\n\n// GetResourceIdOk returns a tuple with the ResourceId field value\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetResourceIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ResourceId, true\n}\n\n// SetResourceId sets field value\nfunc (o *Job) SetResourceId(v string) {\n\to.ResourceId = v\n}\n\n// GetPayload returns the Payload field value if set, zero value otherwise.\nfunc (o *Job) GetPayload() string {\n\tif o == nil || IsNil(o.Payload) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Payload\n}\n\n// GetPayloadOk returns a tuple with the Payload field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetPayloadOk() (*string, bool) {\n\tif o == nil || IsNil(o.Payload) {\n\t\treturn nil, false\n\t}\n\treturn o.Payload, true\n}\n\n// HasPayload returns a boolean if a field has been set.\nfunc (o *Job) HasPayload() bool {\n\tif o != nil && !IsNil(o.Payload) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPayload gets a reference to the given string and assigns it to the Payload field.\nfunc (o *Job) SetPayload(v string) {\n\to.Payload = &v\n}\n\n// GetTraceContext returns the TraceContext field value if set, zero value otherwise.\nfunc (o *Job) GetTraceContext() map[string]interface{} {\n\tif o == nil || IsNil(o.TraceContext) {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\treturn o.TraceContext\n}\n\n// GetTraceContextOk returns a tuple with the TraceContext field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetTraceContextOk() (map[string]interface{}, bool) {\n\tif o == nil || IsNil(o.TraceContext) {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.TraceContext, true\n}\n\n// HasTraceContext returns a boolean if a field has been set.\nfunc (o *Job) HasTraceContext() bool {\n\tif o != nil && !IsNil(o.TraceContext) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTraceContext gets a reference to the given map[string]interface{} and assigns it to the TraceContext field.\nfunc (o *Job) SetTraceContext(v map[string]interface{}) {\n\to.TraceContext = v\n}\n\n// GetErrorMessage returns the ErrorMessage field value if set, zero value otherwise.\nfunc (o *Job) GetErrorMessage() string {\n\tif o == nil || IsNil(o.ErrorMessage) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ErrorMessage\n}\n\n// GetErrorMessageOk returns a tuple with the ErrorMessage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetErrorMessageOk() (*string, bool) {\n\tif o == nil || IsNil(o.ErrorMessage) {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorMessage, true\n}\n\n// HasErrorMessage returns a boolean if a field has been set.\nfunc (o *Job) HasErrorMessage() bool {\n\tif o != nil && !IsNil(o.ErrorMessage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetErrorMessage gets a reference to the given string and assigns it to the ErrorMessage field.\nfunc (o *Job) SetErrorMessage(v string) {\n\to.ErrorMessage = &v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *Job) GetCreatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetCreatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *Job) SetCreatedAt(v string) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise.\nfunc (o *Job) GetUpdatedAt() string {\n\tif o == nil || IsNil(o.UpdatedAt) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Job) GetUpdatedAtOk() (*string, bool) {\n\tif o == nil || IsNil(o.UpdatedAt) {\n\t\treturn nil, false\n\t}\n\treturn o.UpdatedAt, true\n}\n\n// HasUpdatedAt returns a boolean if a field has been set.\nfunc (o *Job) HasUpdatedAt() bool {\n\tif o != nil && !IsNil(o.UpdatedAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetUpdatedAt gets a reference to the given string and assigns it to the UpdatedAt field.\nfunc (o *Job) SetUpdatedAt(v string) {\n\to.UpdatedAt = &v\n}\n\nfunc (o Job) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Job) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"type\"] = o.Type\n\ttoSerialize[\"status\"] = o.Status\n\ttoSerialize[\"resourceType\"] = o.ResourceType\n\ttoSerialize[\"resourceId\"] = o.ResourceId\n\tif !IsNil(o.Payload) {\n\t\ttoSerialize[\"payload\"] = o.Payload\n\t}\n\tif !IsNil(o.TraceContext) {\n\t\ttoSerialize[\"traceContext\"] = o.TraceContext\n\t}\n\tif !IsNil(o.ErrorMessage) {\n\t\ttoSerialize[\"errorMessage\"] = o.ErrorMessage\n\t}\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\tif !IsNil(o.UpdatedAt) {\n\t\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Job) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"type\",\n\t\t\"status\",\n\t\t\"resourceType\",\n\t\t\"resourceId\",\n\t\t\"createdAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarJob := _Job{}\n\n\terr = json.Unmarshal(data, &varJob)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Job(varJob)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"type\")\n\t\tdelete(additionalProperties, \"status\")\n\t\tdelete(additionalProperties, \"resourceType\")\n\t\tdelete(additionalProperties, \"resourceId\")\n\t\tdelete(additionalProperties, \"payload\")\n\t\tdelete(additionalProperties, \"traceContext\")\n\t\tdelete(additionalProperties, \"errorMessage\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableJob struct {\n\tvalue *Job\n\tisSet bool\n}\n\nfunc (v NullableJob) Get() *Job {\n\treturn v.value\n}\n\nfunc (v *NullableJob) Set(val *Job) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableJob) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableJob) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableJob(val *Job) *NullableJob {\n\treturn &NullableJob{value: val, isSet: true}\n}\n\nfunc (v NullableJob) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableJob) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_job_status.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// JobStatus the model 'JobStatus'\ntype JobStatus string\n\n// List of JobStatus\nconst (\n\tJOBSTATUS_PENDING JobStatus = \"PENDING\"\n\tJOBSTATUS_IN_PROGRESS JobStatus = \"IN_PROGRESS\"\n\tJOBSTATUS_COMPLETED JobStatus = \"COMPLETED\"\n\tJOBSTATUS_FAILED JobStatus = \"FAILED\"\n)\n\n// All allowed values of JobStatus enum\nvar AllowedJobStatusEnumValues = []JobStatus{\n\t\"PENDING\",\n\t\"IN_PROGRESS\",\n\t\"COMPLETED\",\n\t\"FAILED\",\n}\n\nfunc (v *JobStatus) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := JobStatus(value)\n\tfor _, existing := range AllowedJobStatusEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid JobStatus\", value)\n}\n\n// NewJobStatusFromValue returns a pointer to a valid JobStatus\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewJobStatusFromValue(v string) (*JobStatus, error) {\n\tev := JobStatus(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for JobStatus: valid values are %v\", v, AllowedJobStatusEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v JobStatus) IsValid() bool {\n\tfor _, existing := range AllowedJobStatusEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to JobStatus value\nfunc (v JobStatus) Ptr() *JobStatus {\n\treturn &v\n}\n\ntype NullableJobStatus struct {\n\tvalue *JobStatus\n\tisSet bool\n}\n\nfunc (v NullableJobStatus) Get() *JobStatus {\n\treturn v.value\n}\n\nfunc (v *NullableJobStatus) Set(val *JobStatus) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableJobStatus) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableJobStatus) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableJobStatus(val *JobStatus) *NullableJobStatus {\n\treturn &NullableJobStatus{value: val, isSet: true}\n}\n\nfunc (v NullableJobStatus) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableJobStatus) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_job_type.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// JobType The type of the job\ntype JobType string\n\n// List of JobType\nconst (\n\tJOBTYPE_CREATE_SANDBOX JobType = \"CREATE_SANDBOX\"\n\tJOBTYPE_START_SANDBOX JobType = \"START_SANDBOX\"\n\tJOBTYPE_STOP_SANDBOX JobType = \"STOP_SANDBOX\"\n\tJOBTYPE_DESTROY_SANDBOX JobType = \"DESTROY_SANDBOX\"\n\tJOBTYPE_RESIZE_SANDBOX JobType = \"RESIZE_SANDBOX\"\n\tJOBTYPE_CREATE_BACKUP JobType = \"CREATE_BACKUP\"\n\tJOBTYPE_BUILD_SNAPSHOT JobType = \"BUILD_SNAPSHOT\"\n\tJOBTYPE_PULL_SNAPSHOT JobType = \"PULL_SNAPSHOT\"\n\tJOBTYPE_RECOVER_SANDBOX JobType = \"RECOVER_SANDBOX\"\n\tJOBTYPE_INSPECT_SNAPSHOT_IN_REGISTRY JobType = \"INSPECT_SNAPSHOT_IN_REGISTRY\"\n\tJOBTYPE_REMOVE_SNAPSHOT JobType = \"REMOVE_SNAPSHOT\"\n\tJOBTYPE_UPDATE_SANDBOX_NETWORK_SETTINGS JobType = \"UPDATE_SANDBOX_NETWORK_SETTINGS\"\n)\n\n// All allowed values of JobType enum\nvar AllowedJobTypeEnumValues = []JobType{\n\t\"CREATE_SANDBOX\",\n\t\"START_SANDBOX\",\n\t\"STOP_SANDBOX\",\n\t\"DESTROY_SANDBOX\",\n\t\"RESIZE_SANDBOX\",\n\t\"CREATE_BACKUP\",\n\t\"BUILD_SNAPSHOT\",\n\t\"PULL_SNAPSHOT\",\n\t\"RECOVER_SANDBOX\",\n\t\"INSPECT_SNAPSHOT_IN_REGISTRY\",\n\t\"REMOVE_SNAPSHOT\",\n\t\"UPDATE_SANDBOX_NETWORK_SETTINGS\",\n}\n\nfunc (v *JobType) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := JobType(value)\n\tfor _, existing := range AllowedJobTypeEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid JobType\", value)\n}\n\n// NewJobTypeFromValue returns a pointer to a valid JobType\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewJobTypeFromValue(v string) (*JobType, error) {\n\tev := JobType(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for JobType: valid values are %v\", v, AllowedJobTypeEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v JobType) IsValid() bool {\n\tfor _, existing := range AllowedJobTypeEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to JobType value\nfunc (v JobType) Ptr() *JobType {\n\treturn &v\n}\n\ntype NullableJobType struct {\n\tvalue *JobType\n\tisSet bool\n}\n\nfunc (v NullableJobType) Get() *JobType {\n\treturn v.value\n}\n\nfunc (v *NullableJobType) Set(val *JobType) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableJobType) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableJobType) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableJobType(val *JobType) *NullableJobType {\n\treturn &NullableJobType{value: val, isSet: true}\n}\n\nfunc (v NullableJobType) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableJobType) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_keyboard_hotkey_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the KeyboardHotkeyRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &KeyboardHotkeyRequest{}\n\n// KeyboardHotkeyRequest struct for KeyboardHotkeyRequest\ntype KeyboardHotkeyRequest struct {\n\t// The hotkey combination to press (e.g., \\\"ctrl+c\\\", \\\"cmd+v\\\", \\\"alt+tab\\\")\n\tKeys string `json:\"keys\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _KeyboardHotkeyRequest KeyboardHotkeyRequest\n\n// NewKeyboardHotkeyRequest instantiates a new KeyboardHotkeyRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewKeyboardHotkeyRequest(keys string) *KeyboardHotkeyRequest {\n\tthis := KeyboardHotkeyRequest{}\n\tthis.Keys = keys\n\treturn &this\n}\n\n// NewKeyboardHotkeyRequestWithDefaults instantiates a new KeyboardHotkeyRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewKeyboardHotkeyRequestWithDefaults() *KeyboardHotkeyRequest {\n\tthis := KeyboardHotkeyRequest{}\n\treturn &this\n}\n\n// GetKeys returns the Keys field value\nfunc (o *KeyboardHotkeyRequest) GetKeys() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Keys\n}\n\n// GetKeysOk returns a tuple with the Keys field value\n// and a boolean to check if the value has been set.\nfunc (o *KeyboardHotkeyRequest) GetKeysOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Keys, true\n}\n\n// SetKeys sets field value\nfunc (o *KeyboardHotkeyRequest) SetKeys(v string) {\n\to.Keys = v\n}\n\nfunc (o KeyboardHotkeyRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o KeyboardHotkeyRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"keys\"] = o.Keys\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *KeyboardHotkeyRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"keys\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarKeyboardHotkeyRequest := _KeyboardHotkeyRequest{}\n\n\terr = json.Unmarshal(data, &varKeyboardHotkeyRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = KeyboardHotkeyRequest(varKeyboardHotkeyRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"keys\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableKeyboardHotkeyRequest struct {\n\tvalue *KeyboardHotkeyRequest\n\tisSet bool\n}\n\nfunc (v NullableKeyboardHotkeyRequest) Get() *KeyboardHotkeyRequest {\n\treturn v.value\n}\n\nfunc (v *NullableKeyboardHotkeyRequest) Set(val *KeyboardHotkeyRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableKeyboardHotkeyRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableKeyboardHotkeyRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableKeyboardHotkeyRequest(val *KeyboardHotkeyRequest) *NullableKeyboardHotkeyRequest {\n\treturn &NullableKeyboardHotkeyRequest{value: val, isSet: true}\n}\n\nfunc (v NullableKeyboardHotkeyRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableKeyboardHotkeyRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_keyboard_press_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the KeyboardPressRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &KeyboardPressRequest{}\n\n// KeyboardPressRequest struct for KeyboardPressRequest\ntype KeyboardPressRequest struct {\n\t// The key to press (e.g., a, b, c, enter, space, etc.)\n\tKey string `json:\"key\"`\n\t// Array of modifier keys to press along with the main key (ctrl, alt, shift, cmd)\n\tModifiers []string `json:\"modifiers,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _KeyboardPressRequest KeyboardPressRequest\n\n// NewKeyboardPressRequest instantiates a new KeyboardPressRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewKeyboardPressRequest(key string) *KeyboardPressRequest {\n\tthis := KeyboardPressRequest{}\n\tthis.Key = key\n\treturn &this\n}\n\n// NewKeyboardPressRequestWithDefaults instantiates a new KeyboardPressRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewKeyboardPressRequestWithDefaults() *KeyboardPressRequest {\n\tthis := KeyboardPressRequest{}\n\treturn &this\n}\n\n// GetKey returns the Key field value\nfunc (o *KeyboardPressRequest) GetKey() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Key\n}\n\n// GetKeyOk returns a tuple with the Key field value\n// and a boolean to check if the value has been set.\nfunc (o *KeyboardPressRequest) GetKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Key, true\n}\n\n// SetKey sets field value\nfunc (o *KeyboardPressRequest) SetKey(v string) {\n\to.Key = v\n}\n\n// GetModifiers returns the Modifiers field value if set, zero value otherwise.\nfunc (o *KeyboardPressRequest) GetModifiers() []string {\n\tif o == nil || IsNil(o.Modifiers) {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\treturn o.Modifiers\n}\n\n// GetModifiersOk returns a tuple with the Modifiers field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *KeyboardPressRequest) GetModifiersOk() ([]string, bool) {\n\tif o == nil || IsNil(o.Modifiers) {\n\t\treturn nil, false\n\t}\n\treturn o.Modifiers, true\n}\n\n// HasModifiers returns a boolean if a field has been set.\nfunc (o *KeyboardPressRequest) HasModifiers() bool {\n\tif o != nil && !IsNil(o.Modifiers) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetModifiers gets a reference to the given []string and assigns it to the Modifiers field.\nfunc (o *KeyboardPressRequest) SetModifiers(v []string) {\n\to.Modifiers = v\n}\n\nfunc (o KeyboardPressRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o KeyboardPressRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"key\"] = o.Key\n\tif !IsNil(o.Modifiers) {\n\t\ttoSerialize[\"modifiers\"] = o.Modifiers\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *KeyboardPressRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"key\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarKeyboardPressRequest := _KeyboardPressRequest{}\n\n\terr = json.Unmarshal(data, &varKeyboardPressRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = KeyboardPressRequest(varKeyboardPressRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"key\")\n\t\tdelete(additionalProperties, \"modifiers\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableKeyboardPressRequest struct {\n\tvalue *KeyboardPressRequest\n\tisSet bool\n}\n\nfunc (v NullableKeyboardPressRequest) Get() *KeyboardPressRequest {\n\treturn v.value\n}\n\nfunc (v *NullableKeyboardPressRequest) Set(val *KeyboardPressRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableKeyboardPressRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableKeyboardPressRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableKeyboardPressRequest(val *KeyboardPressRequest) *NullableKeyboardPressRequest {\n\treturn &NullableKeyboardPressRequest{value: val, isSet: true}\n}\n\nfunc (v NullableKeyboardPressRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableKeyboardPressRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_keyboard_type_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the KeyboardTypeRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &KeyboardTypeRequest{}\n\n// KeyboardTypeRequest struct for KeyboardTypeRequest\ntype KeyboardTypeRequest struct {\n\t// The text to type using the keyboard\n\tText string `json:\"text\"`\n\t// Delay in milliseconds between keystrokes. Defaults to 0\n\tDelay *float32 `json:\"delay,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _KeyboardTypeRequest KeyboardTypeRequest\n\n// NewKeyboardTypeRequest instantiates a new KeyboardTypeRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewKeyboardTypeRequest(text string) *KeyboardTypeRequest {\n\tthis := KeyboardTypeRequest{}\n\tthis.Text = text\n\treturn &this\n}\n\n// NewKeyboardTypeRequestWithDefaults instantiates a new KeyboardTypeRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewKeyboardTypeRequestWithDefaults() *KeyboardTypeRequest {\n\tthis := KeyboardTypeRequest{}\n\treturn &this\n}\n\n// GetText returns the Text field value\nfunc (o *KeyboardTypeRequest) GetText() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Text\n}\n\n// GetTextOk returns a tuple with the Text field value\n// and a boolean to check if the value has been set.\nfunc (o *KeyboardTypeRequest) GetTextOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Text, true\n}\n\n// SetText sets field value\nfunc (o *KeyboardTypeRequest) SetText(v string) {\n\to.Text = v\n}\n\n// GetDelay returns the Delay field value if set, zero value otherwise.\nfunc (o *KeyboardTypeRequest) GetDelay() float32 {\n\tif o == nil || IsNil(o.Delay) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Delay\n}\n\n// GetDelayOk returns a tuple with the Delay field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *KeyboardTypeRequest) GetDelayOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Delay) {\n\t\treturn nil, false\n\t}\n\treturn o.Delay, true\n}\n\n// HasDelay returns a boolean if a field has been set.\nfunc (o *KeyboardTypeRequest) HasDelay() bool {\n\tif o != nil && !IsNil(o.Delay) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDelay gets a reference to the given float32 and assigns it to the Delay field.\nfunc (o *KeyboardTypeRequest) SetDelay(v float32) {\n\to.Delay = &v\n}\n\nfunc (o KeyboardTypeRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o KeyboardTypeRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"text\"] = o.Text\n\tif !IsNil(o.Delay) {\n\t\ttoSerialize[\"delay\"] = o.Delay\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *KeyboardTypeRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"text\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarKeyboardTypeRequest := _KeyboardTypeRequest{}\n\n\terr = json.Unmarshal(data, &varKeyboardTypeRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = KeyboardTypeRequest(varKeyboardTypeRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"text\")\n\t\tdelete(additionalProperties, \"delay\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableKeyboardTypeRequest struct {\n\tvalue *KeyboardTypeRequest\n\tisSet bool\n}\n\nfunc (v NullableKeyboardTypeRequest) Get() *KeyboardTypeRequest {\n\treturn v.value\n}\n\nfunc (v *NullableKeyboardTypeRequest) Set(val *KeyboardTypeRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableKeyboardTypeRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableKeyboardTypeRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableKeyboardTypeRequest(val *KeyboardTypeRequest) *NullableKeyboardTypeRequest {\n\treturn &NullableKeyboardTypeRequest{value: val, isSet: true}\n}\n\nfunc (v NullableKeyboardTypeRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableKeyboardTypeRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_list_branch_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ListBranchResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ListBranchResponse{}\n\n// ListBranchResponse struct for ListBranchResponse\ntype ListBranchResponse struct {\n\tBranches []string `json:\"branches\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ListBranchResponse ListBranchResponse\n\n// NewListBranchResponse instantiates a new ListBranchResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewListBranchResponse(branches []string) *ListBranchResponse {\n\tthis := ListBranchResponse{}\n\tthis.Branches = branches\n\treturn &this\n}\n\n// NewListBranchResponseWithDefaults instantiates a new ListBranchResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewListBranchResponseWithDefaults() *ListBranchResponse {\n\tthis := ListBranchResponse{}\n\treturn &this\n}\n\n// GetBranches returns the Branches field value\nfunc (o *ListBranchResponse) GetBranches() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Branches\n}\n\n// GetBranchesOk returns a tuple with the Branches field value\n// and a boolean to check if the value has been set.\nfunc (o *ListBranchResponse) GetBranchesOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Branches, true\n}\n\n// SetBranches sets field value\nfunc (o *ListBranchResponse) SetBranches(v []string) {\n\to.Branches = v\n}\n\nfunc (o ListBranchResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ListBranchResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"branches\"] = o.Branches\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ListBranchResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"branches\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarListBranchResponse := _ListBranchResponse{}\n\n\terr = json.Unmarshal(data, &varListBranchResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ListBranchResponse(varListBranchResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"branches\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableListBranchResponse struct {\n\tvalue *ListBranchResponse\n\tisSet bool\n}\n\nfunc (v NullableListBranchResponse) Get() *ListBranchResponse {\n\treturn v.value\n}\n\nfunc (v *NullableListBranchResponse) Set(val *ListBranchResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableListBranchResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableListBranchResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableListBranchResponse(val *ListBranchResponse) *NullableListBranchResponse {\n\treturn &NullableListBranchResponse{value: val, isSet: true}\n}\n\nfunc (v NullableListBranchResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableListBranchResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_log_entry.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the LogEntry type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &LogEntry{}\n\n// LogEntry struct for LogEntry\ntype LogEntry struct {\n\t// Timestamp of the log entry\n\tTimestamp string `json:\"timestamp\"`\n\t// Log message body\n\tBody string `json:\"body\"`\n\t// Severity level text (e.g., INFO, WARN, ERROR)\n\tSeverityText string `json:\"severityText\"`\n\t// Severity level number\n\tSeverityNumber *float32 `json:\"severityNumber,omitempty\"`\n\t// Service name that generated the log\n\tServiceName string `json:\"serviceName\"`\n\t// Resource attributes from OTEL\n\tResourceAttributes map[string]string `json:\"resourceAttributes\"`\n\t// Log-specific attributes\n\tLogAttributes map[string]string `json:\"logAttributes\"`\n\t// Associated trace ID if available\n\tTraceId *string `json:\"traceId,omitempty\"`\n\t// Associated span ID if available\n\tSpanId *string `json:\"spanId,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _LogEntry LogEntry\n\n// NewLogEntry instantiates a new LogEntry object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewLogEntry(timestamp string, body string, severityText string, serviceName string, resourceAttributes map[string]string, logAttributes map[string]string) *LogEntry {\n\tthis := LogEntry{}\n\tthis.Timestamp = timestamp\n\tthis.Body = body\n\tthis.SeverityText = severityText\n\tthis.ServiceName = serviceName\n\tthis.ResourceAttributes = resourceAttributes\n\tthis.LogAttributes = logAttributes\n\treturn &this\n}\n\n// NewLogEntryWithDefaults instantiates a new LogEntry object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewLogEntryWithDefaults() *LogEntry {\n\tthis := LogEntry{}\n\treturn &this\n}\n\n// GetTimestamp returns the Timestamp field value\nfunc (o *LogEntry) GetTimestamp() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Timestamp\n}\n\n// GetTimestampOk returns a tuple with the Timestamp field value\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetTimestampOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Timestamp, true\n}\n\n// SetTimestamp sets field value\nfunc (o *LogEntry) SetTimestamp(v string) {\n\to.Timestamp = v\n}\n\n// GetBody returns the Body field value\nfunc (o *LogEntry) GetBody() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Body\n}\n\n// GetBodyOk returns a tuple with the Body field value\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetBodyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Body, true\n}\n\n// SetBody sets field value\nfunc (o *LogEntry) SetBody(v string) {\n\to.Body = v\n}\n\n// GetSeverityText returns the SeverityText field value\nfunc (o *LogEntry) GetSeverityText() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SeverityText\n}\n\n// GetSeverityTextOk returns a tuple with the SeverityText field value\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetSeverityTextOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SeverityText, true\n}\n\n// SetSeverityText sets field value\nfunc (o *LogEntry) SetSeverityText(v string) {\n\to.SeverityText = v\n}\n\n// GetSeverityNumber returns the SeverityNumber field value if set, zero value otherwise.\nfunc (o *LogEntry) GetSeverityNumber() float32 {\n\tif o == nil || IsNil(o.SeverityNumber) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.SeverityNumber\n}\n\n// GetSeverityNumberOk returns a tuple with the SeverityNumber field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetSeverityNumberOk() (*float32, bool) {\n\tif o == nil || IsNil(o.SeverityNumber) {\n\t\treturn nil, false\n\t}\n\treturn o.SeverityNumber, true\n}\n\n// HasSeverityNumber returns a boolean if a field has been set.\nfunc (o *LogEntry) HasSeverityNumber() bool {\n\tif o != nil && !IsNil(o.SeverityNumber) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSeverityNumber gets a reference to the given float32 and assigns it to the SeverityNumber field.\nfunc (o *LogEntry) SetSeverityNumber(v float32) {\n\to.SeverityNumber = &v\n}\n\n// GetServiceName returns the ServiceName field value\nfunc (o *LogEntry) GetServiceName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ServiceName\n}\n\n// GetServiceNameOk returns a tuple with the ServiceName field value\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetServiceNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ServiceName, true\n}\n\n// SetServiceName sets field value\nfunc (o *LogEntry) SetServiceName(v string) {\n\to.ServiceName = v\n}\n\n// GetResourceAttributes returns the ResourceAttributes field value\nfunc (o *LogEntry) GetResourceAttributes() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\n\treturn o.ResourceAttributes\n}\n\n// GetResourceAttributesOk returns a tuple with the ResourceAttributes field value\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetResourceAttributesOk() (*map[string]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ResourceAttributes, true\n}\n\n// SetResourceAttributes sets field value\nfunc (o *LogEntry) SetResourceAttributes(v map[string]string) {\n\to.ResourceAttributes = v\n}\n\n// GetLogAttributes returns the LogAttributes field value\nfunc (o *LogEntry) GetLogAttributes() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\n\treturn o.LogAttributes\n}\n\n// GetLogAttributesOk returns a tuple with the LogAttributes field value\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetLogAttributesOk() (*map[string]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.LogAttributes, true\n}\n\n// SetLogAttributes sets field value\nfunc (o *LogEntry) SetLogAttributes(v map[string]string) {\n\to.LogAttributes = v\n}\n\n// GetTraceId returns the TraceId field value if set, zero value otherwise.\nfunc (o *LogEntry) GetTraceId() string {\n\tif o == nil || IsNil(o.TraceId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.TraceId\n}\n\n// GetTraceIdOk returns a tuple with the TraceId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetTraceIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.TraceId) {\n\t\treturn nil, false\n\t}\n\treturn o.TraceId, true\n}\n\n// HasTraceId returns a boolean if a field has been set.\nfunc (o *LogEntry) HasTraceId() bool {\n\tif o != nil && !IsNil(o.TraceId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTraceId gets a reference to the given string and assigns it to the TraceId field.\nfunc (o *LogEntry) SetTraceId(v string) {\n\to.TraceId = &v\n}\n\n// GetSpanId returns the SpanId field value if set, zero value otherwise.\nfunc (o *LogEntry) GetSpanId() string {\n\tif o == nil || IsNil(o.SpanId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SpanId\n}\n\n// GetSpanIdOk returns a tuple with the SpanId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *LogEntry) GetSpanIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.SpanId) {\n\t\treturn nil, false\n\t}\n\treturn o.SpanId, true\n}\n\n// HasSpanId returns a boolean if a field has been set.\nfunc (o *LogEntry) HasSpanId() bool {\n\tif o != nil && !IsNil(o.SpanId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSpanId gets a reference to the given string and assigns it to the SpanId field.\nfunc (o *LogEntry) SetSpanId(v string) {\n\to.SpanId = &v\n}\n\nfunc (o LogEntry) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o LogEntry) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"timestamp\"] = o.Timestamp\n\ttoSerialize[\"body\"] = o.Body\n\ttoSerialize[\"severityText\"] = o.SeverityText\n\tif !IsNil(o.SeverityNumber) {\n\t\ttoSerialize[\"severityNumber\"] = o.SeverityNumber\n\t}\n\ttoSerialize[\"serviceName\"] = o.ServiceName\n\ttoSerialize[\"resourceAttributes\"] = o.ResourceAttributes\n\ttoSerialize[\"logAttributes\"] = o.LogAttributes\n\tif !IsNil(o.TraceId) {\n\t\ttoSerialize[\"traceId\"] = o.TraceId\n\t}\n\tif !IsNil(o.SpanId) {\n\t\ttoSerialize[\"spanId\"] = o.SpanId\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *LogEntry) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"timestamp\",\n\t\t\"body\",\n\t\t\"severityText\",\n\t\t\"serviceName\",\n\t\t\"resourceAttributes\",\n\t\t\"logAttributes\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarLogEntry := _LogEntry{}\n\n\terr = json.Unmarshal(data, &varLogEntry)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = LogEntry(varLogEntry)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"timestamp\")\n\t\tdelete(additionalProperties, \"body\")\n\t\tdelete(additionalProperties, \"severityText\")\n\t\tdelete(additionalProperties, \"severityNumber\")\n\t\tdelete(additionalProperties, \"serviceName\")\n\t\tdelete(additionalProperties, \"resourceAttributes\")\n\t\tdelete(additionalProperties, \"logAttributes\")\n\t\tdelete(additionalProperties, \"traceId\")\n\t\tdelete(additionalProperties, \"spanId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableLogEntry struct {\n\tvalue *LogEntry\n\tisSet bool\n}\n\nfunc (v NullableLogEntry) Get() *LogEntry {\n\treturn v.value\n}\n\nfunc (v *NullableLogEntry) Set(val *LogEntry) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableLogEntry) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableLogEntry) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableLogEntry(val *LogEntry) *NullableLogEntry {\n\treturn &NullableLogEntry{value: val, isSet: true}\n}\n\nfunc (v NullableLogEntry) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableLogEntry) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_lsp_completion_params.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the LspCompletionParams type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &LspCompletionParams{}\n\n// LspCompletionParams struct for LspCompletionParams\ntype LspCompletionParams struct {\n\t// Language identifier\n\tLanguageId string `json:\"languageId\"`\n\t// Path to the project\n\tPathToProject string `json:\"pathToProject\"`\n\t// Document URI\n\tUri string `json:\"uri\"`\n\tPosition Position `json:\"position\"`\n\tContext *CompletionContext `json:\"context,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _LspCompletionParams LspCompletionParams\n\n// NewLspCompletionParams instantiates a new LspCompletionParams object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewLspCompletionParams(languageId string, pathToProject string, uri string, position Position) *LspCompletionParams {\n\tthis := LspCompletionParams{}\n\tthis.LanguageId = languageId\n\tthis.PathToProject = pathToProject\n\tthis.Uri = uri\n\tthis.Position = position\n\treturn &this\n}\n\n// NewLspCompletionParamsWithDefaults instantiates a new LspCompletionParams object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewLspCompletionParamsWithDefaults() *LspCompletionParams {\n\tthis := LspCompletionParams{}\n\treturn &this\n}\n\n// GetLanguageId returns the LanguageId field value\nfunc (o *LspCompletionParams) GetLanguageId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.LanguageId\n}\n\n// GetLanguageIdOk returns a tuple with the LanguageId field value\n// and a boolean to check if the value has been set.\nfunc (o *LspCompletionParams) GetLanguageIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.LanguageId, true\n}\n\n// SetLanguageId sets field value\nfunc (o *LspCompletionParams) SetLanguageId(v string) {\n\to.LanguageId = v\n}\n\n// GetPathToProject returns the PathToProject field value\nfunc (o *LspCompletionParams) GetPathToProject() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.PathToProject\n}\n\n// GetPathToProjectOk returns a tuple with the PathToProject field value\n// and a boolean to check if the value has been set.\nfunc (o *LspCompletionParams) GetPathToProjectOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.PathToProject, true\n}\n\n// SetPathToProject sets field value\nfunc (o *LspCompletionParams) SetPathToProject(v string) {\n\to.PathToProject = v\n}\n\n// GetUri returns the Uri field value\nfunc (o *LspCompletionParams) GetUri() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Uri\n}\n\n// GetUriOk returns a tuple with the Uri field value\n// and a boolean to check if the value has been set.\nfunc (o *LspCompletionParams) GetUriOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Uri, true\n}\n\n// SetUri sets field value\nfunc (o *LspCompletionParams) SetUri(v string) {\n\to.Uri = v\n}\n\n// GetPosition returns the Position field value\nfunc (o *LspCompletionParams) GetPosition() Position {\n\tif o == nil {\n\t\tvar ret Position\n\t\treturn ret\n\t}\n\n\treturn o.Position\n}\n\n// GetPositionOk returns a tuple with the Position field value\n// and a boolean to check if the value has been set.\nfunc (o *LspCompletionParams) GetPositionOk() (*Position, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Position, true\n}\n\n// SetPosition sets field value\nfunc (o *LspCompletionParams) SetPosition(v Position) {\n\to.Position = v\n}\n\n// GetContext returns the Context field value if set, zero value otherwise.\nfunc (o *LspCompletionParams) GetContext() CompletionContext {\n\tif o == nil || IsNil(o.Context) {\n\t\tvar ret CompletionContext\n\t\treturn ret\n\t}\n\treturn *o.Context\n}\n\n// GetContextOk returns a tuple with the Context field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *LspCompletionParams) GetContextOk() (*CompletionContext, bool) {\n\tif o == nil || IsNil(o.Context) {\n\t\treturn nil, false\n\t}\n\treturn o.Context, true\n}\n\n// HasContext returns a boolean if a field has been set.\nfunc (o *LspCompletionParams) HasContext() bool {\n\tif o != nil && !IsNil(o.Context) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetContext gets a reference to the given CompletionContext and assigns it to the Context field.\nfunc (o *LspCompletionParams) SetContext(v CompletionContext) {\n\to.Context = &v\n}\n\nfunc (o LspCompletionParams) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o LspCompletionParams) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"languageId\"] = o.LanguageId\n\ttoSerialize[\"pathToProject\"] = o.PathToProject\n\ttoSerialize[\"uri\"] = o.Uri\n\ttoSerialize[\"position\"] = o.Position\n\tif !IsNil(o.Context) {\n\t\ttoSerialize[\"context\"] = o.Context\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *LspCompletionParams) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"languageId\",\n\t\t\"pathToProject\",\n\t\t\"uri\",\n\t\t\"position\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarLspCompletionParams := _LspCompletionParams{}\n\n\terr = json.Unmarshal(data, &varLspCompletionParams)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = LspCompletionParams(varLspCompletionParams)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"languageId\")\n\t\tdelete(additionalProperties, \"pathToProject\")\n\t\tdelete(additionalProperties, \"uri\")\n\t\tdelete(additionalProperties, \"position\")\n\t\tdelete(additionalProperties, \"context\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableLspCompletionParams struct {\n\tvalue *LspCompletionParams\n\tisSet bool\n}\n\nfunc (v NullableLspCompletionParams) Get() *LspCompletionParams {\n\treturn v.value\n}\n\nfunc (v *NullableLspCompletionParams) Set(val *LspCompletionParams) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableLspCompletionParams) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableLspCompletionParams) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableLspCompletionParams(val *LspCompletionParams) *NullableLspCompletionParams {\n\treturn &NullableLspCompletionParams{value: val, isSet: true}\n}\n\nfunc (v NullableLspCompletionParams) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableLspCompletionParams) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_lsp_document_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the LspDocumentRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &LspDocumentRequest{}\n\n// LspDocumentRequest struct for LspDocumentRequest\ntype LspDocumentRequest struct {\n\t// Language identifier\n\tLanguageId string `json:\"languageId\"`\n\t// Path to the project\n\tPathToProject string `json:\"pathToProject\"`\n\t// Document URI\n\tUri string `json:\"uri\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _LspDocumentRequest LspDocumentRequest\n\n// NewLspDocumentRequest instantiates a new LspDocumentRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewLspDocumentRequest(languageId string, pathToProject string, uri string) *LspDocumentRequest {\n\tthis := LspDocumentRequest{}\n\tthis.LanguageId = languageId\n\tthis.PathToProject = pathToProject\n\tthis.Uri = uri\n\treturn &this\n}\n\n// NewLspDocumentRequestWithDefaults instantiates a new LspDocumentRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewLspDocumentRequestWithDefaults() *LspDocumentRequest {\n\tthis := LspDocumentRequest{}\n\treturn &this\n}\n\n// GetLanguageId returns the LanguageId field value\nfunc (o *LspDocumentRequest) GetLanguageId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.LanguageId\n}\n\n// GetLanguageIdOk returns a tuple with the LanguageId field value\n// and a boolean to check if the value has been set.\nfunc (o *LspDocumentRequest) GetLanguageIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.LanguageId, true\n}\n\n// SetLanguageId sets field value\nfunc (o *LspDocumentRequest) SetLanguageId(v string) {\n\to.LanguageId = v\n}\n\n// GetPathToProject returns the PathToProject field value\nfunc (o *LspDocumentRequest) GetPathToProject() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.PathToProject\n}\n\n// GetPathToProjectOk returns a tuple with the PathToProject field value\n// and a boolean to check if the value has been set.\nfunc (o *LspDocumentRequest) GetPathToProjectOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.PathToProject, true\n}\n\n// SetPathToProject sets field value\nfunc (o *LspDocumentRequest) SetPathToProject(v string) {\n\to.PathToProject = v\n}\n\n// GetUri returns the Uri field value\nfunc (o *LspDocumentRequest) GetUri() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Uri\n}\n\n// GetUriOk returns a tuple with the Uri field value\n// and a boolean to check if the value has been set.\nfunc (o *LspDocumentRequest) GetUriOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Uri, true\n}\n\n// SetUri sets field value\nfunc (o *LspDocumentRequest) SetUri(v string) {\n\to.Uri = v\n}\n\nfunc (o LspDocumentRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o LspDocumentRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"languageId\"] = o.LanguageId\n\ttoSerialize[\"pathToProject\"] = o.PathToProject\n\ttoSerialize[\"uri\"] = o.Uri\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *LspDocumentRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"languageId\",\n\t\t\"pathToProject\",\n\t\t\"uri\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarLspDocumentRequest := _LspDocumentRequest{}\n\n\terr = json.Unmarshal(data, &varLspDocumentRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = LspDocumentRequest(varLspDocumentRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"languageId\")\n\t\tdelete(additionalProperties, \"pathToProject\")\n\t\tdelete(additionalProperties, \"uri\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableLspDocumentRequest struct {\n\tvalue *LspDocumentRequest\n\tisSet bool\n}\n\nfunc (v NullableLspDocumentRequest) Get() *LspDocumentRequest {\n\treturn v.value\n}\n\nfunc (v *NullableLspDocumentRequest) Set(val *LspDocumentRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableLspDocumentRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableLspDocumentRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableLspDocumentRequest(val *LspDocumentRequest) *NullableLspDocumentRequest {\n\treturn &NullableLspDocumentRequest{value: val, isSet: true}\n}\n\nfunc (v NullableLspDocumentRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableLspDocumentRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_lsp_location.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the LspLocation type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &LspLocation{}\n\n// LspLocation struct for LspLocation\ntype LspLocation struct {\n\tRange Range `json:\"range\"`\n\tUri string `json:\"uri\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _LspLocation LspLocation\n\n// NewLspLocation instantiates a new LspLocation object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewLspLocation(range_ Range, uri string) *LspLocation {\n\tthis := LspLocation{}\n\tthis.Range = range_\n\tthis.Uri = uri\n\treturn &this\n}\n\n// NewLspLocationWithDefaults instantiates a new LspLocation object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewLspLocationWithDefaults() *LspLocation {\n\tthis := LspLocation{}\n\treturn &this\n}\n\n// GetRange returns the Range field value\nfunc (o *LspLocation) GetRange() Range {\n\tif o == nil {\n\t\tvar ret Range\n\t\treturn ret\n\t}\n\n\treturn o.Range\n}\n\n// GetRangeOk returns a tuple with the Range field value\n// and a boolean to check if the value has been set.\nfunc (o *LspLocation) GetRangeOk() (*Range, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Range, true\n}\n\n// SetRange sets field value\nfunc (o *LspLocation) SetRange(v Range) {\n\to.Range = v\n}\n\n// GetUri returns the Uri field value\nfunc (o *LspLocation) GetUri() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Uri\n}\n\n// GetUriOk returns a tuple with the Uri field value\n// and a boolean to check if the value has been set.\nfunc (o *LspLocation) GetUriOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Uri, true\n}\n\n// SetUri sets field value\nfunc (o *LspLocation) SetUri(v string) {\n\to.Uri = v\n}\n\nfunc (o LspLocation) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o LspLocation) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"range\"] = o.Range\n\ttoSerialize[\"uri\"] = o.Uri\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *LspLocation) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"range\",\n\t\t\"uri\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarLspLocation := _LspLocation{}\n\n\terr = json.Unmarshal(data, &varLspLocation)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = LspLocation(varLspLocation)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"range\")\n\t\tdelete(additionalProperties, \"uri\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableLspLocation struct {\n\tvalue *LspLocation\n\tisSet bool\n}\n\nfunc (v NullableLspLocation) Get() *LspLocation {\n\treturn v.value\n}\n\nfunc (v *NullableLspLocation) Set(val *LspLocation) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableLspLocation) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableLspLocation) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableLspLocation(val *LspLocation) *NullableLspLocation {\n\treturn &NullableLspLocation{value: val, isSet: true}\n}\n\nfunc (v NullableLspLocation) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableLspLocation) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_lsp_server_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the LspServerRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &LspServerRequest{}\n\n// LspServerRequest struct for LspServerRequest\ntype LspServerRequest struct {\n\t// Language identifier\n\tLanguageId string `json:\"languageId\"`\n\t// Path to the project\n\tPathToProject string `json:\"pathToProject\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _LspServerRequest LspServerRequest\n\n// NewLspServerRequest instantiates a new LspServerRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewLspServerRequest(languageId string, pathToProject string) *LspServerRequest {\n\tthis := LspServerRequest{}\n\tthis.LanguageId = languageId\n\tthis.PathToProject = pathToProject\n\treturn &this\n}\n\n// NewLspServerRequestWithDefaults instantiates a new LspServerRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewLspServerRequestWithDefaults() *LspServerRequest {\n\tthis := LspServerRequest{}\n\treturn &this\n}\n\n// GetLanguageId returns the LanguageId field value\nfunc (o *LspServerRequest) GetLanguageId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.LanguageId\n}\n\n// GetLanguageIdOk returns a tuple with the LanguageId field value\n// and a boolean to check if the value has been set.\nfunc (o *LspServerRequest) GetLanguageIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.LanguageId, true\n}\n\n// SetLanguageId sets field value\nfunc (o *LspServerRequest) SetLanguageId(v string) {\n\to.LanguageId = v\n}\n\n// GetPathToProject returns the PathToProject field value\nfunc (o *LspServerRequest) GetPathToProject() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.PathToProject\n}\n\n// GetPathToProjectOk returns a tuple with the PathToProject field value\n// and a boolean to check if the value has been set.\nfunc (o *LspServerRequest) GetPathToProjectOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.PathToProject, true\n}\n\n// SetPathToProject sets field value\nfunc (o *LspServerRequest) SetPathToProject(v string) {\n\to.PathToProject = v\n}\n\nfunc (o LspServerRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o LspServerRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"languageId\"] = o.LanguageId\n\ttoSerialize[\"pathToProject\"] = o.PathToProject\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *LspServerRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"languageId\",\n\t\t\"pathToProject\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarLspServerRequest := _LspServerRequest{}\n\n\terr = json.Unmarshal(data, &varLspServerRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = LspServerRequest(varLspServerRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"languageId\")\n\t\tdelete(additionalProperties, \"pathToProject\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableLspServerRequest struct {\n\tvalue *LspServerRequest\n\tisSet bool\n}\n\nfunc (v NullableLspServerRequest) Get() *LspServerRequest {\n\treturn v.value\n}\n\nfunc (v *NullableLspServerRequest) Set(val *LspServerRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableLspServerRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableLspServerRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableLspServerRequest(val *LspServerRequest) *NullableLspServerRequest {\n\treturn &NullableLspServerRequest{value: val, isSet: true}\n}\n\nfunc (v NullableLspServerRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableLspServerRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_lsp_symbol.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the LspSymbol type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &LspSymbol{}\n\n// LspSymbol struct for LspSymbol\ntype LspSymbol struct {\n\tKind float32 `json:\"kind\"`\n\tLocation LspLocation `json:\"location\"`\n\tName string `json:\"name\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _LspSymbol LspSymbol\n\n// NewLspSymbol instantiates a new LspSymbol object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewLspSymbol(kind float32, location LspLocation, name string) *LspSymbol {\n\tthis := LspSymbol{}\n\tthis.Kind = kind\n\tthis.Location = location\n\tthis.Name = name\n\treturn &this\n}\n\n// NewLspSymbolWithDefaults instantiates a new LspSymbol object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewLspSymbolWithDefaults() *LspSymbol {\n\tthis := LspSymbol{}\n\treturn &this\n}\n\n// GetKind returns the Kind field value\nfunc (o *LspSymbol) GetKind() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Kind\n}\n\n// GetKindOk returns a tuple with the Kind field value\n// and a boolean to check if the value has been set.\nfunc (o *LspSymbol) GetKindOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Kind, true\n}\n\n// SetKind sets field value\nfunc (o *LspSymbol) SetKind(v float32) {\n\to.Kind = v\n}\n\n// GetLocation returns the Location field value\nfunc (o *LspSymbol) GetLocation() LspLocation {\n\tif o == nil {\n\t\tvar ret LspLocation\n\t\treturn ret\n\t}\n\n\treturn o.Location\n}\n\n// GetLocationOk returns a tuple with the Location field value\n// and a boolean to check if the value has been set.\nfunc (o *LspSymbol) GetLocationOk() (*LspLocation, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Location, true\n}\n\n// SetLocation sets field value\nfunc (o *LspSymbol) SetLocation(v LspLocation) {\n\to.Location = v\n}\n\n// GetName returns the Name field value\nfunc (o *LspSymbol) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *LspSymbol) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *LspSymbol) SetName(v string) {\n\to.Name = v\n}\n\nfunc (o LspSymbol) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o LspSymbol) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"kind\"] = o.Kind\n\ttoSerialize[\"location\"] = o.Location\n\ttoSerialize[\"name\"] = o.Name\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *LspSymbol) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"kind\",\n\t\t\"location\",\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarLspSymbol := _LspSymbol{}\n\n\terr = json.Unmarshal(data, &varLspSymbol)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = LspSymbol(varLspSymbol)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"kind\")\n\t\tdelete(additionalProperties, \"location\")\n\t\tdelete(additionalProperties, \"name\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableLspSymbol struct {\n\tvalue *LspSymbol\n\tisSet bool\n}\n\nfunc (v NullableLspSymbol) Get() *LspSymbol {\n\treturn v.value\n}\n\nfunc (v *NullableLspSymbol) Set(val *LspSymbol) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableLspSymbol) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableLspSymbol) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableLspSymbol(val *LspSymbol) *NullableLspSymbol {\n\treturn &NullableLspSymbol{value: val, isSet: true}\n}\n\nfunc (v NullableLspSymbol) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableLspSymbol) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_match.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Match type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Match{}\n\n// Match struct for Match\ntype Match struct {\n\tFile string `json:\"file\"`\n\tLine float32 `json:\"line\"`\n\tContent string `json:\"content\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Match Match\n\n// NewMatch instantiates a new Match object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMatch(file string, line float32, content string) *Match {\n\tthis := Match{}\n\tthis.File = file\n\tthis.Line = line\n\tthis.Content = content\n\treturn &this\n}\n\n// NewMatchWithDefaults instantiates a new Match object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMatchWithDefaults() *Match {\n\tthis := Match{}\n\treturn &this\n}\n\n// GetFile returns the File field value\nfunc (o *Match) GetFile() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.File\n}\n\n// GetFileOk returns a tuple with the File field value\n// and a boolean to check if the value has been set.\nfunc (o *Match) GetFileOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.File, true\n}\n\n// SetFile sets field value\nfunc (o *Match) SetFile(v string) {\n\to.File = v\n}\n\n// GetLine returns the Line field value\nfunc (o *Match) GetLine() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Line\n}\n\n// GetLineOk returns a tuple with the Line field value\n// and a boolean to check if the value has been set.\nfunc (o *Match) GetLineOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Line, true\n}\n\n// SetLine sets field value\nfunc (o *Match) SetLine(v float32) {\n\to.Line = v\n}\n\n// GetContent returns the Content field value\nfunc (o *Match) GetContent() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Content\n}\n\n// GetContentOk returns a tuple with the Content field value\n// and a boolean to check if the value has been set.\nfunc (o *Match) GetContentOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Content, true\n}\n\n// SetContent sets field value\nfunc (o *Match) SetContent(v string) {\n\to.Content = v\n}\n\nfunc (o Match) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Match) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"file\"] = o.File\n\ttoSerialize[\"line\"] = o.Line\n\ttoSerialize[\"content\"] = o.Content\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Match) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"file\",\n\t\t\"line\",\n\t\t\"content\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMatch := _Match{}\n\n\terr = json.Unmarshal(data, &varMatch)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Match(varMatch)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"file\")\n\t\tdelete(additionalProperties, \"line\")\n\t\tdelete(additionalProperties, \"content\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMatch struct {\n\tvalue *Match\n\tisSet bool\n}\n\nfunc (v NullableMatch) Get() *Match {\n\treturn v.value\n}\n\nfunc (v *NullableMatch) Set(val *Match) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMatch) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMatch) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMatch(val *Match) *NullableMatch {\n\treturn &NullableMatch{value: val, isSet: true}\n}\n\nfunc (v NullableMatch) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMatch) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_metric_data_point.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MetricDataPoint type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MetricDataPoint{}\n\n// MetricDataPoint struct for MetricDataPoint\ntype MetricDataPoint struct {\n\t// Timestamp of the data point\n\tTimestamp string `json:\"timestamp\"`\n\t// Value at this timestamp\n\tValue float32 `json:\"value\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MetricDataPoint MetricDataPoint\n\n// NewMetricDataPoint instantiates a new MetricDataPoint object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMetricDataPoint(timestamp string, value float32) *MetricDataPoint {\n\tthis := MetricDataPoint{}\n\tthis.Timestamp = timestamp\n\tthis.Value = value\n\treturn &this\n}\n\n// NewMetricDataPointWithDefaults instantiates a new MetricDataPoint object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMetricDataPointWithDefaults() *MetricDataPoint {\n\tthis := MetricDataPoint{}\n\treturn &this\n}\n\n// GetTimestamp returns the Timestamp field value\nfunc (o *MetricDataPoint) GetTimestamp() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Timestamp\n}\n\n// GetTimestampOk returns a tuple with the Timestamp field value\n// and a boolean to check if the value has been set.\nfunc (o *MetricDataPoint) GetTimestampOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Timestamp, true\n}\n\n// SetTimestamp sets field value\nfunc (o *MetricDataPoint) SetTimestamp(v string) {\n\to.Timestamp = v\n}\n\n// GetValue returns the Value field value\nfunc (o *MetricDataPoint) GetValue() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Value\n}\n\n// GetValueOk returns a tuple with the Value field value\n// and a boolean to check if the value has been set.\nfunc (o *MetricDataPoint) GetValueOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Value, true\n}\n\n// SetValue sets field value\nfunc (o *MetricDataPoint) SetValue(v float32) {\n\to.Value = v\n}\n\nfunc (o MetricDataPoint) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MetricDataPoint) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"timestamp\"] = o.Timestamp\n\ttoSerialize[\"value\"] = o.Value\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MetricDataPoint) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"timestamp\",\n\t\t\"value\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMetricDataPoint := _MetricDataPoint{}\n\n\terr = json.Unmarshal(data, &varMetricDataPoint)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MetricDataPoint(varMetricDataPoint)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"timestamp\")\n\t\tdelete(additionalProperties, \"value\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMetricDataPoint struct {\n\tvalue *MetricDataPoint\n\tisSet bool\n}\n\nfunc (v NullableMetricDataPoint) Get() *MetricDataPoint {\n\treturn v.value\n}\n\nfunc (v *NullableMetricDataPoint) Set(val *MetricDataPoint) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMetricDataPoint) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMetricDataPoint) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMetricDataPoint(val *MetricDataPoint) *NullableMetricDataPoint {\n\treturn &NullableMetricDataPoint{value: val, isSet: true}\n}\n\nfunc (v NullableMetricDataPoint) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMetricDataPoint) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_metric_series.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MetricSeries type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MetricSeries{}\n\n// MetricSeries struct for MetricSeries\ntype MetricSeries struct {\n\t// Name of the metric\n\tMetricName string `json:\"metricName\"`\n\t// Data points for this metric\n\tDataPoints []MetricDataPoint `json:\"dataPoints\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MetricSeries MetricSeries\n\n// NewMetricSeries instantiates a new MetricSeries object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMetricSeries(metricName string, dataPoints []MetricDataPoint) *MetricSeries {\n\tthis := MetricSeries{}\n\tthis.MetricName = metricName\n\tthis.DataPoints = dataPoints\n\treturn &this\n}\n\n// NewMetricSeriesWithDefaults instantiates a new MetricSeries object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMetricSeriesWithDefaults() *MetricSeries {\n\tthis := MetricSeries{}\n\treturn &this\n}\n\n// GetMetricName returns the MetricName field value\nfunc (o *MetricSeries) GetMetricName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.MetricName\n}\n\n// GetMetricNameOk returns a tuple with the MetricName field value\n// and a boolean to check if the value has been set.\nfunc (o *MetricSeries) GetMetricNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.MetricName, true\n}\n\n// SetMetricName sets field value\nfunc (o *MetricSeries) SetMetricName(v string) {\n\to.MetricName = v\n}\n\n// GetDataPoints returns the DataPoints field value\nfunc (o *MetricSeries) GetDataPoints() []MetricDataPoint {\n\tif o == nil {\n\t\tvar ret []MetricDataPoint\n\t\treturn ret\n\t}\n\n\treturn o.DataPoints\n}\n\n// GetDataPointsOk returns a tuple with the DataPoints field value\n// and a boolean to check if the value has been set.\nfunc (o *MetricSeries) GetDataPointsOk() ([]MetricDataPoint, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.DataPoints, true\n}\n\n// SetDataPoints sets field value\nfunc (o *MetricSeries) SetDataPoints(v []MetricDataPoint) {\n\to.DataPoints = v\n}\n\nfunc (o MetricSeries) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MetricSeries) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"metricName\"] = o.MetricName\n\ttoSerialize[\"dataPoints\"] = o.DataPoints\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MetricSeries) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"metricName\",\n\t\t\"dataPoints\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMetricSeries := _MetricSeries{}\n\n\terr = json.Unmarshal(data, &varMetricSeries)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MetricSeries(varMetricSeries)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"metricName\")\n\t\tdelete(additionalProperties, \"dataPoints\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMetricSeries struct {\n\tvalue *MetricSeries\n\tisSet bool\n}\n\nfunc (v NullableMetricSeries) Get() *MetricSeries {\n\treturn v.value\n}\n\nfunc (v *NullableMetricSeries) Set(val *MetricSeries) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMetricSeries) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMetricSeries) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMetricSeries(val *MetricSeries) *NullableMetricSeries {\n\treturn &NullableMetricSeries{value: val, isSet: true}\n}\n\nfunc (v NullableMetricSeries) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMetricSeries) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_metrics_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MetricsResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MetricsResponse{}\n\n// MetricsResponse struct for MetricsResponse\ntype MetricsResponse struct {\n\t// List of metric series\n\tSeries []MetricSeries `json:\"series\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MetricsResponse MetricsResponse\n\n// NewMetricsResponse instantiates a new MetricsResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMetricsResponse(series []MetricSeries) *MetricsResponse {\n\tthis := MetricsResponse{}\n\tthis.Series = series\n\treturn &this\n}\n\n// NewMetricsResponseWithDefaults instantiates a new MetricsResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMetricsResponseWithDefaults() *MetricsResponse {\n\tthis := MetricsResponse{}\n\treturn &this\n}\n\n// GetSeries returns the Series field value\nfunc (o *MetricsResponse) GetSeries() []MetricSeries {\n\tif o == nil {\n\t\tvar ret []MetricSeries\n\t\treturn ret\n\t}\n\n\treturn o.Series\n}\n\n// GetSeriesOk returns a tuple with the Series field value\n// and a boolean to check if the value has been set.\nfunc (o *MetricsResponse) GetSeriesOk() ([]MetricSeries, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Series, true\n}\n\n// SetSeries sets field value\nfunc (o *MetricsResponse) SetSeries(v []MetricSeries) {\n\to.Series = v\n}\n\nfunc (o MetricsResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MetricsResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"series\"] = o.Series\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MetricsResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"series\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMetricsResponse := _MetricsResponse{}\n\n\terr = json.Unmarshal(data, &varMetricsResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MetricsResponse(varMetricsResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"series\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMetricsResponse struct {\n\tvalue *MetricsResponse\n\tisSet bool\n}\n\nfunc (v NullableMetricsResponse) Get() *MetricsResponse {\n\treturn v.value\n}\n\nfunc (v *NullableMetricsResponse) Set(val *MetricsResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMetricsResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMetricsResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMetricsResponse(val *MetricsResponse) *NullableMetricsResponse {\n\treturn &NullableMetricsResponse{value: val, isSet: true}\n}\n\nfunc (v NullableMetricsResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMetricsResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_click_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MouseClickRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MouseClickRequest{}\n\n// MouseClickRequest struct for MouseClickRequest\ntype MouseClickRequest struct {\n\t// The X coordinate where to perform the mouse click\n\tX float32 `json:\"x\"`\n\t// The Y coordinate where to perform the mouse click\n\tY float32 `json:\"y\"`\n\t// The mouse button to click (left, right, middle). Defaults to left\n\tButton *string `json:\"button,omitempty\"`\n\t// Whether to perform a double-click instead of a single click\n\tDouble *bool `json:\"double,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MouseClickRequest MouseClickRequest\n\n// NewMouseClickRequest instantiates a new MouseClickRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMouseClickRequest(x float32, y float32) *MouseClickRequest {\n\tthis := MouseClickRequest{}\n\tthis.X = x\n\tthis.Y = y\n\treturn &this\n}\n\n// NewMouseClickRequestWithDefaults instantiates a new MouseClickRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMouseClickRequestWithDefaults() *MouseClickRequest {\n\tthis := MouseClickRequest{}\n\treturn &this\n}\n\n// GetX returns the X field value\nfunc (o *MouseClickRequest) GetX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.X\n}\n\n// GetXOk returns a tuple with the X field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseClickRequest) GetXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.X, true\n}\n\n// SetX sets field value\nfunc (o *MouseClickRequest) SetX(v float32) {\n\to.X = v\n}\n\n// GetY returns the Y field value\nfunc (o *MouseClickRequest) GetY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Y\n}\n\n// GetYOk returns a tuple with the Y field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseClickRequest) GetYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Y, true\n}\n\n// SetY sets field value\nfunc (o *MouseClickRequest) SetY(v float32) {\n\to.Y = v\n}\n\n// GetButton returns the Button field value if set, zero value otherwise.\nfunc (o *MouseClickRequest) GetButton() string {\n\tif o == nil || IsNil(o.Button) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Button\n}\n\n// GetButtonOk returns a tuple with the Button field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *MouseClickRequest) GetButtonOk() (*string, bool) {\n\tif o == nil || IsNil(o.Button) {\n\t\treturn nil, false\n\t}\n\treturn o.Button, true\n}\n\n// HasButton returns a boolean if a field has been set.\nfunc (o *MouseClickRequest) HasButton() bool {\n\tif o != nil && !IsNil(o.Button) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetButton gets a reference to the given string and assigns it to the Button field.\nfunc (o *MouseClickRequest) SetButton(v string) {\n\to.Button = &v\n}\n\n// GetDouble returns the Double field value if set, zero value otherwise.\nfunc (o *MouseClickRequest) GetDouble() bool {\n\tif o == nil || IsNil(o.Double) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Double\n}\n\n// GetDoubleOk returns a tuple with the Double field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *MouseClickRequest) GetDoubleOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Double) {\n\t\treturn nil, false\n\t}\n\treturn o.Double, true\n}\n\n// HasDouble returns a boolean if a field has been set.\nfunc (o *MouseClickRequest) HasDouble() bool {\n\tif o != nil && !IsNil(o.Double) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDouble gets a reference to the given bool and assigns it to the Double field.\nfunc (o *MouseClickRequest) SetDouble(v bool) {\n\to.Double = &v\n}\n\nfunc (o MouseClickRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MouseClickRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"x\"] = o.X\n\ttoSerialize[\"y\"] = o.Y\n\tif !IsNil(o.Button) {\n\t\ttoSerialize[\"button\"] = o.Button\n\t}\n\tif !IsNil(o.Double) {\n\t\ttoSerialize[\"double\"] = o.Double\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MouseClickRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"x\",\n\t\t\"y\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMouseClickRequest := _MouseClickRequest{}\n\n\terr = json.Unmarshal(data, &varMouseClickRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MouseClickRequest(varMouseClickRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"x\")\n\t\tdelete(additionalProperties, \"y\")\n\t\tdelete(additionalProperties, \"button\")\n\t\tdelete(additionalProperties, \"double\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMouseClickRequest struct {\n\tvalue *MouseClickRequest\n\tisSet bool\n}\n\nfunc (v NullableMouseClickRequest) Get() *MouseClickRequest {\n\treturn v.value\n}\n\nfunc (v *NullableMouseClickRequest) Set(val *MouseClickRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMouseClickRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMouseClickRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMouseClickRequest(val *MouseClickRequest) *NullableMouseClickRequest {\n\treturn &NullableMouseClickRequest{value: val, isSet: true}\n}\n\nfunc (v NullableMouseClickRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMouseClickRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_click_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MouseClickResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MouseClickResponse{}\n\n// MouseClickResponse struct for MouseClickResponse\ntype MouseClickResponse struct {\n\t// The actual X coordinate where the click occurred\n\tX float32 `json:\"x\"`\n\t// The actual Y coordinate where the click occurred\n\tY float32 `json:\"y\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MouseClickResponse MouseClickResponse\n\n// NewMouseClickResponse instantiates a new MouseClickResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMouseClickResponse(x float32, y float32) *MouseClickResponse {\n\tthis := MouseClickResponse{}\n\tthis.X = x\n\tthis.Y = y\n\treturn &this\n}\n\n// NewMouseClickResponseWithDefaults instantiates a new MouseClickResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMouseClickResponseWithDefaults() *MouseClickResponse {\n\tthis := MouseClickResponse{}\n\treturn &this\n}\n\n// GetX returns the X field value\nfunc (o *MouseClickResponse) GetX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.X\n}\n\n// GetXOk returns a tuple with the X field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseClickResponse) GetXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.X, true\n}\n\n// SetX sets field value\nfunc (o *MouseClickResponse) SetX(v float32) {\n\to.X = v\n}\n\n// GetY returns the Y field value\nfunc (o *MouseClickResponse) GetY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Y\n}\n\n// GetYOk returns a tuple with the Y field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseClickResponse) GetYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Y, true\n}\n\n// SetY sets field value\nfunc (o *MouseClickResponse) SetY(v float32) {\n\to.Y = v\n}\n\nfunc (o MouseClickResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MouseClickResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"x\"] = o.X\n\ttoSerialize[\"y\"] = o.Y\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MouseClickResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"x\",\n\t\t\"y\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMouseClickResponse := _MouseClickResponse{}\n\n\terr = json.Unmarshal(data, &varMouseClickResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MouseClickResponse(varMouseClickResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"x\")\n\t\tdelete(additionalProperties, \"y\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMouseClickResponse struct {\n\tvalue *MouseClickResponse\n\tisSet bool\n}\n\nfunc (v NullableMouseClickResponse) Get() *MouseClickResponse {\n\treturn v.value\n}\n\nfunc (v *NullableMouseClickResponse) Set(val *MouseClickResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMouseClickResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMouseClickResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMouseClickResponse(val *MouseClickResponse) *NullableMouseClickResponse {\n\treturn &NullableMouseClickResponse{value: val, isSet: true}\n}\n\nfunc (v NullableMouseClickResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMouseClickResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_drag_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MouseDragRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MouseDragRequest{}\n\n// MouseDragRequest struct for MouseDragRequest\ntype MouseDragRequest struct {\n\t// The starting X coordinate for the drag operation\n\tStartX float32 `json:\"startX\"`\n\t// The starting Y coordinate for the drag operation\n\tStartY float32 `json:\"startY\"`\n\t// The ending X coordinate for the drag operation\n\tEndX float32 `json:\"endX\"`\n\t// The ending Y coordinate for the drag operation\n\tEndY float32 `json:\"endY\"`\n\t// The mouse button to use for dragging (left, right, middle). Defaults to left\n\tButton *string `json:\"button,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MouseDragRequest MouseDragRequest\n\n// NewMouseDragRequest instantiates a new MouseDragRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMouseDragRequest(startX float32, startY float32, endX float32, endY float32) *MouseDragRequest {\n\tthis := MouseDragRequest{}\n\tthis.StartX = startX\n\tthis.StartY = startY\n\tthis.EndX = endX\n\tthis.EndY = endY\n\treturn &this\n}\n\n// NewMouseDragRequestWithDefaults instantiates a new MouseDragRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMouseDragRequestWithDefaults() *MouseDragRequest {\n\tthis := MouseDragRequest{}\n\treturn &this\n}\n\n// GetStartX returns the StartX field value\nfunc (o *MouseDragRequest) GetStartX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.StartX\n}\n\n// GetStartXOk returns a tuple with the StartX field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseDragRequest) GetStartXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.StartX, true\n}\n\n// SetStartX sets field value\nfunc (o *MouseDragRequest) SetStartX(v float32) {\n\to.StartX = v\n}\n\n// GetStartY returns the StartY field value\nfunc (o *MouseDragRequest) GetStartY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.StartY\n}\n\n// GetStartYOk returns a tuple with the StartY field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseDragRequest) GetStartYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.StartY, true\n}\n\n// SetStartY sets field value\nfunc (o *MouseDragRequest) SetStartY(v float32) {\n\to.StartY = v\n}\n\n// GetEndX returns the EndX field value\nfunc (o *MouseDragRequest) GetEndX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.EndX\n}\n\n// GetEndXOk returns a tuple with the EndX field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseDragRequest) GetEndXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.EndX, true\n}\n\n// SetEndX sets field value\nfunc (o *MouseDragRequest) SetEndX(v float32) {\n\to.EndX = v\n}\n\n// GetEndY returns the EndY field value\nfunc (o *MouseDragRequest) GetEndY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.EndY\n}\n\n// GetEndYOk returns a tuple with the EndY field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseDragRequest) GetEndYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.EndY, true\n}\n\n// SetEndY sets field value\nfunc (o *MouseDragRequest) SetEndY(v float32) {\n\to.EndY = v\n}\n\n// GetButton returns the Button field value if set, zero value otherwise.\nfunc (o *MouseDragRequest) GetButton() string {\n\tif o == nil || IsNil(o.Button) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Button\n}\n\n// GetButtonOk returns a tuple with the Button field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *MouseDragRequest) GetButtonOk() (*string, bool) {\n\tif o == nil || IsNil(o.Button) {\n\t\treturn nil, false\n\t}\n\treturn o.Button, true\n}\n\n// HasButton returns a boolean if a field has been set.\nfunc (o *MouseDragRequest) HasButton() bool {\n\tif o != nil && !IsNil(o.Button) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetButton gets a reference to the given string and assigns it to the Button field.\nfunc (o *MouseDragRequest) SetButton(v string) {\n\to.Button = &v\n}\n\nfunc (o MouseDragRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MouseDragRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"startX\"] = o.StartX\n\ttoSerialize[\"startY\"] = o.StartY\n\ttoSerialize[\"endX\"] = o.EndX\n\ttoSerialize[\"endY\"] = o.EndY\n\tif !IsNil(o.Button) {\n\t\ttoSerialize[\"button\"] = o.Button\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MouseDragRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"startX\",\n\t\t\"startY\",\n\t\t\"endX\",\n\t\t\"endY\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMouseDragRequest := _MouseDragRequest{}\n\n\terr = json.Unmarshal(data, &varMouseDragRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MouseDragRequest(varMouseDragRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"startX\")\n\t\tdelete(additionalProperties, \"startY\")\n\t\tdelete(additionalProperties, \"endX\")\n\t\tdelete(additionalProperties, \"endY\")\n\t\tdelete(additionalProperties, \"button\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMouseDragRequest struct {\n\tvalue *MouseDragRequest\n\tisSet bool\n}\n\nfunc (v NullableMouseDragRequest) Get() *MouseDragRequest {\n\treturn v.value\n}\n\nfunc (v *NullableMouseDragRequest) Set(val *MouseDragRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMouseDragRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMouseDragRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMouseDragRequest(val *MouseDragRequest) *NullableMouseDragRequest {\n\treturn &NullableMouseDragRequest{value: val, isSet: true}\n}\n\nfunc (v NullableMouseDragRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMouseDragRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_drag_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MouseDragResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MouseDragResponse{}\n\n// MouseDragResponse struct for MouseDragResponse\ntype MouseDragResponse struct {\n\t// The actual X coordinate where the drag ended\n\tX float32 `json:\"x\"`\n\t// The actual Y coordinate where the drag ended\n\tY float32 `json:\"y\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MouseDragResponse MouseDragResponse\n\n// NewMouseDragResponse instantiates a new MouseDragResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMouseDragResponse(x float32, y float32) *MouseDragResponse {\n\tthis := MouseDragResponse{}\n\tthis.X = x\n\tthis.Y = y\n\treturn &this\n}\n\n// NewMouseDragResponseWithDefaults instantiates a new MouseDragResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMouseDragResponseWithDefaults() *MouseDragResponse {\n\tthis := MouseDragResponse{}\n\treturn &this\n}\n\n// GetX returns the X field value\nfunc (o *MouseDragResponse) GetX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.X\n}\n\n// GetXOk returns a tuple with the X field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseDragResponse) GetXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.X, true\n}\n\n// SetX sets field value\nfunc (o *MouseDragResponse) SetX(v float32) {\n\to.X = v\n}\n\n// GetY returns the Y field value\nfunc (o *MouseDragResponse) GetY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Y\n}\n\n// GetYOk returns a tuple with the Y field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseDragResponse) GetYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Y, true\n}\n\n// SetY sets field value\nfunc (o *MouseDragResponse) SetY(v float32) {\n\to.Y = v\n}\n\nfunc (o MouseDragResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MouseDragResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"x\"] = o.X\n\ttoSerialize[\"y\"] = o.Y\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MouseDragResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"x\",\n\t\t\"y\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMouseDragResponse := _MouseDragResponse{}\n\n\terr = json.Unmarshal(data, &varMouseDragResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MouseDragResponse(varMouseDragResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"x\")\n\t\tdelete(additionalProperties, \"y\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMouseDragResponse struct {\n\tvalue *MouseDragResponse\n\tisSet bool\n}\n\nfunc (v NullableMouseDragResponse) Get() *MouseDragResponse {\n\treturn v.value\n}\n\nfunc (v *NullableMouseDragResponse) Set(val *MouseDragResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMouseDragResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMouseDragResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMouseDragResponse(val *MouseDragResponse) *NullableMouseDragResponse {\n\treturn &NullableMouseDragResponse{value: val, isSet: true}\n}\n\nfunc (v NullableMouseDragResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMouseDragResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_move_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MouseMoveRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MouseMoveRequest{}\n\n// MouseMoveRequest struct for MouseMoveRequest\ntype MouseMoveRequest struct {\n\t// The target X coordinate to move the mouse cursor to\n\tX float32 `json:\"x\"`\n\t// The target Y coordinate to move the mouse cursor to\n\tY float32 `json:\"y\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MouseMoveRequest MouseMoveRequest\n\n// NewMouseMoveRequest instantiates a new MouseMoveRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMouseMoveRequest(x float32, y float32) *MouseMoveRequest {\n\tthis := MouseMoveRequest{}\n\tthis.X = x\n\tthis.Y = y\n\treturn &this\n}\n\n// NewMouseMoveRequestWithDefaults instantiates a new MouseMoveRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMouseMoveRequestWithDefaults() *MouseMoveRequest {\n\tthis := MouseMoveRequest{}\n\treturn &this\n}\n\n// GetX returns the X field value\nfunc (o *MouseMoveRequest) GetX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.X\n}\n\n// GetXOk returns a tuple with the X field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseMoveRequest) GetXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.X, true\n}\n\n// SetX sets field value\nfunc (o *MouseMoveRequest) SetX(v float32) {\n\to.X = v\n}\n\n// GetY returns the Y field value\nfunc (o *MouseMoveRequest) GetY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Y\n}\n\n// GetYOk returns a tuple with the Y field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseMoveRequest) GetYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Y, true\n}\n\n// SetY sets field value\nfunc (o *MouseMoveRequest) SetY(v float32) {\n\to.Y = v\n}\n\nfunc (o MouseMoveRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MouseMoveRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"x\"] = o.X\n\ttoSerialize[\"y\"] = o.Y\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MouseMoveRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"x\",\n\t\t\"y\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMouseMoveRequest := _MouseMoveRequest{}\n\n\terr = json.Unmarshal(data, &varMouseMoveRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MouseMoveRequest(varMouseMoveRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"x\")\n\t\tdelete(additionalProperties, \"y\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMouseMoveRequest struct {\n\tvalue *MouseMoveRequest\n\tisSet bool\n}\n\nfunc (v NullableMouseMoveRequest) Get() *MouseMoveRequest {\n\treturn v.value\n}\n\nfunc (v *NullableMouseMoveRequest) Set(val *MouseMoveRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMouseMoveRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMouseMoveRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMouseMoveRequest(val *MouseMoveRequest) *NullableMouseMoveRequest {\n\treturn &NullableMouseMoveRequest{value: val, isSet: true}\n}\n\nfunc (v NullableMouseMoveRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMouseMoveRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_move_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MouseMoveResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MouseMoveResponse{}\n\n// MouseMoveResponse struct for MouseMoveResponse\ntype MouseMoveResponse struct {\n\t// The actual X coordinate where the mouse cursor ended up\n\tX float32 `json:\"x\"`\n\t// The actual Y coordinate where the mouse cursor ended up\n\tY float32 `json:\"y\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MouseMoveResponse MouseMoveResponse\n\n// NewMouseMoveResponse instantiates a new MouseMoveResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMouseMoveResponse(x float32, y float32) *MouseMoveResponse {\n\tthis := MouseMoveResponse{}\n\tthis.X = x\n\tthis.Y = y\n\treturn &this\n}\n\n// NewMouseMoveResponseWithDefaults instantiates a new MouseMoveResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMouseMoveResponseWithDefaults() *MouseMoveResponse {\n\tthis := MouseMoveResponse{}\n\treturn &this\n}\n\n// GetX returns the X field value\nfunc (o *MouseMoveResponse) GetX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.X\n}\n\n// GetXOk returns a tuple with the X field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseMoveResponse) GetXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.X, true\n}\n\n// SetX sets field value\nfunc (o *MouseMoveResponse) SetX(v float32) {\n\to.X = v\n}\n\n// GetY returns the Y field value\nfunc (o *MouseMoveResponse) GetY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Y\n}\n\n// GetYOk returns a tuple with the Y field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseMoveResponse) GetYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Y, true\n}\n\n// SetY sets field value\nfunc (o *MouseMoveResponse) SetY(v float32) {\n\to.Y = v\n}\n\nfunc (o MouseMoveResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MouseMoveResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"x\"] = o.X\n\ttoSerialize[\"y\"] = o.Y\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MouseMoveResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"x\",\n\t\t\"y\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMouseMoveResponse := _MouseMoveResponse{}\n\n\terr = json.Unmarshal(data, &varMouseMoveResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MouseMoveResponse(varMouseMoveResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"x\")\n\t\tdelete(additionalProperties, \"y\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMouseMoveResponse struct {\n\tvalue *MouseMoveResponse\n\tisSet bool\n}\n\nfunc (v NullableMouseMoveResponse) Get() *MouseMoveResponse {\n\treturn v.value\n}\n\nfunc (v *NullableMouseMoveResponse) Set(val *MouseMoveResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMouseMoveResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMouseMoveResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMouseMoveResponse(val *MouseMoveResponse) *NullableMouseMoveResponse {\n\treturn &NullableMouseMoveResponse{value: val, isSet: true}\n}\n\nfunc (v NullableMouseMoveResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMouseMoveResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_position.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MousePosition type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MousePosition{}\n\n// MousePosition struct for MousePosition\ntype MousePosition struct {\n\t// The X coordinate of the mouse cursor position\n\tX float32 `json:\"x\"`\n\t// The Y coordinate of the mouse cursor position\n\tY float32 `json:\"y\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MousePosition MousePosition\n\n// NewMousePosition instantiates a new MousePosition object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMousePosition(x float32, y float32) *MousePosition {\n\tthis := MousePosition{}\n\tthis.X = x\n\tthis.Y = y\n\treturn &this\n}\n\n// NewMousePositionWithDefaults instantiates a new MousePosition object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMousePositionWithDefaults() *MousePosition {\n\tthis := MousePosition{}\n\treturn &this\n}\n\n// GetX returns the X field value\nfunc (o *MousePosition) GetX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.X\n}\n\n// GetXOk returns a tuple with the X field value\n// and a boolean to check if the value has been set.\nfunc (o *MousePosition) GetXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.X, true\n}\n\n// SetX sets field value\nfunc (o *MousePosition) SetX(v float32) {\n\to.X = v\n}\n\n// GetY returns the Y field value\nfunc (o *MousePosition) GetY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Y\n}\n\n// GetYOk returns a tuple with the Y field value\n// and a boolean to check if the value has been set.\nfunc (o *MousePosition) GetYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Y, true\n}\n\n// SetY sets field value\nfunc (o *MousePosition) SetY(v float32) {\n\to.Y = v\n}\n\nfunc (o MousePosition) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MousePosition) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"x\"] = o.X\n\ttoSerialize[\"y\"] = o.Y\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MousePosition) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"x\",\n\t\t\"y\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMousePosition := _MousePosition{}\n\n\terr = json.Unmarshal(data, &varMousePosition)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MousePosition(varMousePosition)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"x\")\n\t\tdelete(additionalProperties, \"y\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMousePosition struct {\n\tvalue *MousePosition\n\tisSet bool\n}\n\nfunc (v NullableMousePosition) Get() *MousePosition {\n\treturn v.value\n}\n\nfunc (v *NullableMousePosition) Set(val *MousePosition) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMousePosition) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMousePosition) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMousePosition(val *MousePosition) *NullableMousePosition {\n\treturn &NullableMousePosition{value: val, isSet: true}\n}\n\nfunc (v NullableMousePosition) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMousePosition) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_scroll_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MouseScrollRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MouseScrollRequest{}\n\n// MouseScrollRequest struct for MouseScrollRequest\ntype MouseScrollRequest struct {\n\t// The X coordinate where to perform the scroll operation\n\tX float32 `json:\"x\"`\n\t// The Y coordinate where to perform the scroll operation\n\tY float32 `json:\"y\"`\n\t// The scroll direction (up, down)\n\tDirection string `json:\"direction\"`\n\t// The number of scroll units to scroll. Defaults to 1\n\tAmount *float32 `json:\"amount,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MouseScrollRequest MouseScrollRequest\n\n// NewMouseScrollRequest instantiates a new MouseScrollRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMouseScrollRequest(x float32, y float32, direction string) *MouseScrollRequest {\n\tthis := MouseScrollRequest{}\n\tthis.X = x\n\tthis.Y = y\n\tthis.Direction = direction\n\treturn &this\n}\n\n// NewMouseScrollRequestWithDefaults instantiates a new MouseScrollRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMouseScrollRequestWithDefaults() *MouseScrollRequest {\n\tthis := MouseScrollRequest{}\n\treturn &this\n}\n\n// GetX returns the X field value\nfunc (o *MouseScrollRequest) GetX() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.X\n}\n\n// GetXOk returns a tuple with the X field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseScrollRequest) GetXOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.X, true\n}\n\n// SetX sets field value\nfunc (o *MouseScrollRequest) SetX(v float32) {\n\to.X = v\n}\n\n// GetY returns the Y field value\nfunc (o *MouseScrollRequest) GetY() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Y\n}\n\n// GetYOk returns a tuple with the Y field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseScrollRequest) GetYOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Y, true\n}\n\n// SetY sets field value\nfunc (o *MouseScrollRequest) SetY(v float32) {\n\to.Y = v\n}\n\n// GetDirection returns the Direction field value\nfunc (o *MouseScrollRequest) GetDirection() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Direction\n}\n\n// GetDirectionOk returns a tuple with the Direction field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseScrollRequest) GetDirectionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Direction, true\n}\n\n// SetDirection sets field value\nfunc (o *MouseScrollRequest) SetDirection(v string) {\n\to.Direction = v\n}\n\n// GetAmount returns the Amount field value if set, zero value otherwise.\nfunc (o *MouseScrollRequest) GetAmount() float32 {\n\tif o == nil || IsNil(o.Amount) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Amount\n}\n\n// GetAmountOk returns a tuple with the Amount field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *MouseScrollRequest) GetAmountOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Amount) {\n\t\treturn nil, false\n\t}\n\treturn o.Amount, true\n}\n\n// HasAmount returns a boolean if a field has been set.\nfunc (o *MouseScrollRequest) HasAmount() bool {\n\tif o != nil && !IsNil(o.Amount) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAmount gets a reference to the given float32 and assigns it to the Amount field.\nfunc (o *MouseScrollRequest) SetAmount(v float32) {\n\to.Amount = &v\n}\n\nfunc (o MouseScrollRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MouseScrollRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"x\"] = o.X\n\ttoSerialize[\"y\"] = o.Y\n\ttoSerialize[\"direction\"] = o.Direction\n\tif !IsNil(o.Amount) {\n\t\ttoSerialize[\"amount\"] = o.Amount\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MouseScrollRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"x\",\n\t\t\"y\",\n\t\t\"direction\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMouseScrollRequest := _MouseScrollRequest{}\n\n\terr = json.Unmarshal(data, &varMouseScrollRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MouseScrollRequest(varMouseScrollRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"x\")\n\t\tdelete(additionalProperties, \"y\")\n\t\tdelete(additionalProperties, \"direction\")\n\t\tdelete(additionalProperties, \"amount\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMouseScrollRequest struct {\n\tvalue *MouseScrollRequest\n\tisSet bool\n}\n\nfunc (v NullableMouseScrollRequest) Get() *MouseScrollRequest {\n\treturn v.value\n}\n\nfunc (v *NullableMouseScrollRequest) Set(val *MouseScrollRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMouseScrollRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMouseScrollRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMouseScrollRequest(val *MouseScrollRequest) *NullableMouseScrollRequest {\n\treturn &NullableMouseScrollRequest{value: val, isSet: true}\n}\n\nfunc (v NullableMouseScrollRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMouseScrollRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_mouse_scroll_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the MouseScrollResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &MouseScrollResponse{}\n\n// MouseScrollResponse struct for MouseScrollResponse\ntype MouseScrollResponse struct {\n\t// Whether the mouse scroll operation was successful\n\tSuccess bool `json:\"success\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _MouseScrollResponse MouseScrollResponse\n\n// NewMouseScrollResponse instantiates a new MouseScrollResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewMouseScrollResponse(success bool) *MouseScrollResponse {\n\tthis := MouseScrollResponse{}\n\tthis.Success = success\n\treturn &this\n}\n\n// NewMouseScrollResponseWithDefaults instantiates a new MouseScrollResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewMouseScrollResponseWithDefaults() *MouseScrollResponse {\n\tthis := MouseScrollResponse{}\n\treturn &this\n}\n\n// GetSuccess returns the Success field value\nfunc (o *MouseScrollResponse) GetSuccess() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Success\n}\n\n// GetSuccessOk returns a tuple with the Success field value\n// and a boolean to check if the value has been set.\nfunc (o *MouseScrollResponse) GetSuccessOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Success, true\n}\n\n// SetSuccess sets field value\nfunc (o *MouseScrollResponse) SetSuccess(v bool) {\n\to.Success = v\n}\n\nfunc (o MouseScrollResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o MouseScrollResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"success\"] = o.Success\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *MouseScrollResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"success\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarMouseScrollResponse := _MouseScrollResponse{}\n\n\terr = json.Unmarshal(data, &varMouseScrollResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = MouseScrollResponse(varMouseScrollResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"success\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableMouseScrollResponse struct {\n\tvalue *MouseScrollResponse\n\tisSet bool\n}\n\nfunc (v NullableMouseScrollResponse) Get() *MouseScrollResponse {\n\treturn v.value\n}\n\nfunc (v *NullableMouseScrollResponse) Set(val *MouseScrollResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableMouseScrollResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableMouseScrollResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableMouseScrollResponse(val *MouseScrollResponse) *NullableMouseScrollResponse {\n\treturn &NullableMouseScrollResponse{value: val, isSet: true}\n}\n\nfunc (v NullableMouseScrollResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableMouseScrollResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_oidc_config.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the OidcConfig type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &OidcConfig{}\n\n// OidcConfig struct for OidcConfig\ntype OidcConfig struct {\n\t// OIDC issuer\n\tIssuer string `json:\"issuer\"`\n\t// OIDC client ID\n\tClientId string `json:\"clientId\"`\n\t// OIDC audience\n\tAudience string `json:\"audience\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _OidcConfig OidcConfig\n\n// NewOidcConfig instantiates a new OidcConfig object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOidcConfig(issuer string, clientId string, audience string) *OidcConfig {\n\tthis := OidcConfig{}\n\tthis.Issuer = issuer\n\tthis.ClientId = clientId\n\tthis.Audience = audience\n\treturn &this\n}\n\n// NewOidcConfigWithDefaults instantiates a new OidcConfig object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOidcConfigWithDefaults() *OidcConfig {\n\tthis := OidcConfig{}\n\treturn &this\n}\n\n// GetIssuer returns the Issuer field value\nfunc (o *OidcConfig) GetIssuer() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Issuer\n}\n\n// GetIssuerOk returns a tuple with the Issuer field value\n// and a boolean to check if the value has been set.\nfunc (o *OidcConfig) GetIssuerOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Issuer, true\n}\n\n// SetIssuer sets field value\nfunc (o *OidcConfig) SetIssuer(v string) {\n\to.Issuer = v\n}\n\n// GetClientId returns the ClientId field value\nfunc (o *OidcConfig) GetClientId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ClientId\n}\n\n// GetClientIdOk returns a tuple with the ClientId field value\n// and a boolean to check if the value has been set.\nfunc (o *OidcConfig) GetClientIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ClientId, true\n}\n\n// SetClientId sets field value\nfunc (o *OidcConfig) SetClientId(v string) {\n\to.ClientId = v\n}\n\n// GetAudience returns the Audience field value\nfunc (o *OidcConfig) GetAudience() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Audience\n}\n\n// GetAudienceOk returns a tuple with the Audience field value\n// and a boolean to check if the value has been set.\nfunc (o *OidcConfig) GetAudienceOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Audience, true\n}\n\n// SetAudience sets field value\nfunc (o *OidcConfig) SetAudience(v string) {\n\to.Audience = v\n}\n\nfunc (o OidcConfig) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o OidcConfig) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"issuer\"] = o.Issuer\n\ttoSerialize[\"clientId\"] = o.ClientId\n\ttoSerialize[\"audience\"] = o.Audience\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *OidcConfig) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"issuer\",\n\t\t\"clientId\",\n\t\t\"audience\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOidcConfig := _OidcConfig{}\n\n\terr = json.Unmarshal(data, &varOidcConfig)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = OidcConfig(varOidcConfig)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"issuer\")\n\t\tdelete(additionalProperties, \"clientId\")\n\t\tdelete(additionalProperties, \"audience\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOidcConfig struct {\n\tvalue *OidcConfig\n\tisSet bool\n}\n\nfunc (v NullableOidcConfig) Get() *OidcConfig {\n\treturn v.value\n}\n\nfunc (v *NullableOidcConfig) Set(val *OidcConfig) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOidcConfig) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOidcConfig) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOidcConfig(val *OidcConfig) *NullableOidcConfig {\n\treturn &NullableOidcConfig{value: val, isSet: true}\n}\n\nfunc (v NullableOidcConfig) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOidcConfig) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_organization.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the Organization type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Organization{}\n\n// Organization struct for Organization\ntype Organization struct {\n\t// Organization ID\n\tId string `json:\"id\"`\n\t// Organization name\n\tName string `json:\"name\"`\n\t// User ID of the organization creator\n\tCreatedBy string `json:\"createdBy\"`\n\t// Personal organization flag\n\tPersonal bool `json:\"personal\"`\n\t// Creation timestamp\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// Last update timestamp\n\tUpdatedAt time.Time `json:\"updatedAt\"`\n\t// Suspended flag\n\tSuspended bool `json:\"suspended\"`\n\t// Suspended at\n\tSuspendedAt time.Time `json:\"suspendedAt\"`\n\t// Suspended reason\n\tSuspensionReason string `json:\"suspensionReason\"`\n\t// Suspended until\n\tSuspendedUntil time.Time `json:\"suspendedUntil\"`\n\t// Suspension cleanup grace period hours\n\tSuspensionCleanupGracePeriodHours float32 `json:\"suspensionCleanupGracePeriodHours\"`\n\t// Max CPU per sandbox\n\tMaxCpuPerSandbox float32 `json:\"maxCpuPerSandbox\"`\n\t// Max memory per sandbox\n\tMaxMemoryPerSandbox float32 `json:\"maxMemoryPerSandbox\"`\n\t// Max disk per sandbox\n\tMaxDiskPerSandbox float32 `json:\"maxDiskPerSandbox\"`\n\t// Time in minutes before an unused snapshot is deactivated\n\tSnapshotDeactivationTimeoutMinutes float32 `json:\"snapshotDeactivationTimeoutMinutes\"`\n\t// Sandbox default network block all\n\tSandboxLimitedNetworkEgress bool `json:\"sandboxLimitedNetworkEgress\"`\n\t// Default region ID\n\tDefaultRegionId *string `json:\"defaultRegionId,omitempty\"`\n\t// Authenticated rate limit per minute\n\tAuthenticatedRateLimit NullableFloat32 `json:\"authenticatedRateLimit\"`\n\t// Sandbox create rate limit per minute\n\tSandboxCreateRateLimit NullableFloat32 `json:\"sandboxCreateRateLimit\"`\n\t// Sandbox lifecycle rate limit per minute\n\tSandboxLifecycleRateLimit NullableFloat32 `json:\"sandboxLifecycleRateLimit\"`\n\t// Experimental configuration\n\tExperimentalConfig map[string]interface{} `json:\"experimentalConfig\"`\n\t// Authenticated rate limit TTL in seconds\n\tAuthenticatedRateLimitTtlSeconds NullableFloat32 `json:\"authenticatedRateLimitTtlSeconds\"`\n\t// Sandbox create rate limit TTL in seconds\n\tSandboxCreateRateLimitTtlSeconds NullableFloat32 `json:\"sandboxCreateRateLimitTtlSeconds\"`\n\t// Sandbox lifecycle rate limit TTL in seconds\n\tSandboxLifecycleRateLimitTtlSeconds NullableFloat32 `json:\"sandboxLifecycleRateLimitTtlSeconds\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Organization Organization\n\n// NewOrganization instantiates a new Organization object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOrganization(id string, name string, createdBy string, personal bool, createdAt time.Time, updatedAt time.Time, suspended bool, suspendedAt time.Time, suspensionReason string, suspendedUntil time.Time, suspensionCleanupGracePeriodHours float32, maxCpuPerSandbox float32, maxMemoryPerSandbox float32, maxDiskPerSandbox float32, snapshotDeactivationTimeoutMinutes float32, sandboxLimitedNetworkEgress bool, authenticatedRateLimit NullableFloat32, sandboxCreateRateLimit NullableFloat32, sandboxLifecycleRateLimit NullableFloat32, experimentalConfig map[string]interface{}, authenticatedRateLimitTtlSeconds NullableFloat32, sandboxCreateRateLimitTtlSeconds NullableFloat32, sandboxLifecycleRateLimitTtlSeconds NullableFloat32) *Organization {\n\tthis := Organization{}\n\tthis.Id = id\n\tthis.Name = name\n\tthis.CreatedBy = createdBy\n\tthis.Personal = personal\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\tthis.Suspended = suspended\n\tthis.SuspendedAt = suspendedAt\n\tthis.SuspensionReason = suspensionReason\n\tthis.SuspendedUntil = suspendedUntil\n\tthis.SuspensionCleanupGracePeriodHours = suspensionCleanupGracePeriodHours\n\tthis.MaxCpuPerSandbox = maxCpuPerSandbox\n\tthis.MaxMemoryPerSandbox = maxMemoryPerSandbox\n\tthis.MaxDiskPerSandbox = maxDiskPerSandbox\n\tthis.SnapshotDeactivationTimeoutMinutes = snapshotDeactivationTimeoutMinutes\n\tthis.SandboxLimitedNetworkEgress = sandboxLimitedNetworkEgress\n\tthis.AuthenticatedRateLimit = authenticatedRateLimit\n\tthis.SandboxCreateRateLimit = sandboxCreateRateLimit\n\tthis.SandboxLifecycleRateLimit = sandboxLifecycleRateLimit\n\tthis.ExperimentalConfig = experimentalConfig\n\tthis.AuthenticatedRateLimitTtlSeconds = authenticatedRateLimitTtlSeconds\n\tthis.SandboxCreateRateLimitTtlSeconds = sandboxCreateRateLimitTtlSeconds\n\tthis.SandboxLifecycleRateLimitTtlSeconds = sandboxLifecycleRateLimitTtlSeconds\n\treturn &this\n}\n\n// NewOrganizationWithDefaults instantiates a new Organization object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOrganizationWithDefaults() *Organization {\n\tthis := Organization{}\n\tvar snapshotDeactivationTimeoutMinutes float32 = 20160\n\tthis.SnapshotDeactivationTimeoutMinutes = snapshotDeactivationTimeoutMinutes\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *Organization) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *Organization) SetId(v string) {\n\to.Id = v\n}\n\n// GetName returns the Name field value\nfunc (o *Organization) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *Organization) SetName(v string) {\n\to.Name = v\n}\n\n// GetCreatedBy returns the CreatedBy field value\nfunc (o *Organization) GetCreatedBy() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CreatedBy\n}\n\n// GetCreatedByOk returns a tuple with the CreatedBy field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetCreatedByOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedBy, true\n}\n\n// SetCreatedBy sets field value\nfunc (o *Organization) SetCreatedBy(v string) {\n\to.CreatedBy = v\n}\n\n// GetPersonal returns the Personal field value\nfunc (o *Organization) GetPersonal() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Personal\n}\n\n// GetPersonalOk returns a tuple with the Personal field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetPersonalOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Personal, true\n}\n\n// SetPersonal sets field value\nfunc (o *Organization) SetPersonal(v bool) {\n\to.Personal = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *Organization) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *Organization) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *Organization) GetUpdatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetUpdatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *Organization) SetUpdatedAt(v time.Time) {\n\to.UpdatedAt = v\n}\n\n// GetSuspended returns the Suspended field value\nfunc (o *Organization) GetSuspended() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Suspended\n}\n\n// GetSuspendedOk returns a tuple with the Suspended field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetSuspendedOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Suspended, true\n}\n\n// SetSuspended sets field value\nfunc (o *Organization) SetSuspended(v bool) {\n\to.Suspended = v\n}\n\n// GetSuspendedAt returns the SuspendedAt field value\nfunc (o *Organization) GetSuspendedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.SuspendedAt\n}\n\n// GetSuspendedAtOk returns a tuple with the SuspendedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetSuspendedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SuspendedAt, true\n}\n\n// SetSuspendedAt sets field value\nfunc (o *Organization) SetSuspendedAt(v time.Time) {\n\to.SuspendedAt = v\n}\n\n// GetSuspensionReason returns the SuspensionReason field value\nfunc (o *Organization) GetSuspensionReason() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SuspensionReason\n}\n\n// GetSuspensionReasonOk returns a tuple with the SuspensionReason field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetSuspensionReasonOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SuspensionReason, true\n}\n\n// SetSuspensionReason sets field value\nfunc (o *Organization) SetSuspensionReason(v string) {\n\to.SuspensionReason = v\n}\n\n// GetSuspendedUntil returns the SuspendedUntil field value\nfunc (o *Organization) GetSuspendedUntil() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.SuspendedUntil\n}\n\n// GetSuspendedUntilOk returns a tuple with the SuspendedUntil field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetSuspendedUntilOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SuspendedUntil, true\n}\n\n// SetSuspendedUntil sets field value\nfunc (o *Organization) SetSuspendedUntil(v time.Time) {\n\to.SuspendedUntil = v\n}\n\n// GetSuspensionCleanupGracePeriodHours returns the SuspensionCleanupGracePeriodHours field value\nfunc (o *Organization) GetSuspensionCleanupGracePeriodHours() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.SuspensionCleanupGracePeriodHours\n}\n\n// GetSuspensionCleanupGracePeriodHoursOk returns a tuple with the SuspensionCleanupGracePeriodHours field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetSuspensionCleanupGracePeriodHoursOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SuspensionCleanupGracePeriodHours, true\n}\n\n// SetSuspensionCleanupGracePeriodHours sets field value\nfunc (o *Organization) SetSuspensionCleanupGracePeriodHours(v float32) {\n\to.SuspensionCleanupGracePeriodHours = v\n}\n\n// GetMaxCpuPerSandbox returns the MaxCpuPerSandbox field value\nfunc (o *Organization) GetMaxCpuPerSandbox() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.MaxCpuPerSandbox\n}\n\n// GetMaxCpuPerSandboxOk returns a tuple with the MaxCpuPerSandbox field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetMaxCpuPerSandboxOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.MaxCpuPerSandbox, true\n}\n\n// SetMaxCpuPerSandbox sets field value\nfunc (o *Organization) SetMaxCpuPerSandbox(v float32) {\n\to.MaxCpuPerSandbox = v\n}\n\n// GetMaxMemoryPerSandbox returns the MaxMemoryPerSandbox field value\nfunc (o *Organization) GetMaxMemoryPerSandbox() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.MaxMemoryPerSandbox\n}\n\n// GetMaxMemoryPerSandboxOk returns a tuple with the MaxMemoryPerSandbox field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetMaxMemoryPerSandboxOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.MaxMemoryPerSandbox, true\n}\n\n// SetMaxMemoryPerSandbox sets field value\nfunc (o *Organization) SetMaxMemoryPerSandbox(v float32) {\n\to.MaxMemoryPerSandbox = v\n}\n\n// GetMaxDiskPerSandbox returns the MaxDiskPerSandbox field value\nfunc (o *Organization) GetMaxDiskPerSandbox() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.MaxDiskPerSandbox\n}\n\n// GetMaxDiskPerSandboxOk returns a tuple with the MaxDiskPerSandbox field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetMaxDiskPerSandboxOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.MaxDiskPerSandbox, true\n}\n\n// SetMaxDiskPerSandbox sets field value\nfunc (o *Organization) SetMaxDiskPerSandbox(v float32) {\n\to.MaxDiskPerSandbox = v\n}\n\n// GetSnapshotDeactivationTimeoutMinutes returns the SnapshotDeactivationTimeoutMinutes field value\nfunc (o *Organization) GetSnapshotDeactivationTimeoutMinutes() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.SnapshotDeactivationTimeoutMinutes\n}\n\n// GetSnapshotDeactivationTimeoutMinutesOk returns a tuple with the SnapshotDeactivationTimeoutMinutes field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetSnapshotDeactivationTimeoutMinutesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SnapshotDeactivationTimeoutMinutes, true\n}\n\n// SetSnapshotDeactivationTimeoutMinutes sets field value\nfunc (o *Organization) SetSnapshotDeactivationTimeoutMinutes(v float32) {\n\to.SnapshotDeactivationTimeoutMinutes = v\n}\n\n// GetSandboxLimitedNetworkEgress returns the SandboxLimitedNetworkEgress field value\nfunc (o *Organization) GetSandboxLimitedNetworkEgress() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.SandboxLimitedNetworkEgress\n}\n\n// GetSandboxLimitedNetworkEgressOk returns a tuple with the SandboxLimitedNetworkEgress field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetSandboxLimitedNetworkEgressOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SandboxLimitedNetworkEgress, true\n}\n\n// SetSandboxLimitedNetworkEgress sets field value\nfunc (o *Organization) SetSandboxLimitedNetworkEgress(v bool) {\n\to.SandboxLimitedNetworkEgress = v\n}\n\n// GetDefaultRegionId returns the DefaultRegionId field value if set, zero value otherwise.\nfunc (o *Organization) GetDefaultRegionId() string {\n\tif o == nil || IsNil(o.DefaultRegionId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.DefaultRegionId\n}\n\n// GetDefaultRegionIdOk returns a tuple with the DefaultRegionId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetDefaultRegionIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.DefaultRegionId) {\n\t\treturn nil, false\n\t}\n\treturn o.DefaultRegionId, true\n}\n\n// HasDefaultRegionId returns a boolean if a field has been set.\nfunc (o *Organization) HasDefaultRegionId() bool {\n\tif o != nil && !IsNil(o.DefaultRegionId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDefaultRegionId gets a reference to the given string and assigns it to the DefaultRegionId field.\nfunc (o *Organization) SetDefaultRegionId(v string) {\n\to.DefaultRegionId = &v\n}\n\n// GetAuthenticatedRateLimit returns the AuthenticatedRateLimit field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *Organization) GetAuthenticatedRateLimit() float32 {\n\tif o == nil || o.AuthenticatedRateLimit.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.AuthenticatedRateLimit.Get()\n}\n\n// GetAuthenticatedRateLimitOk returns a tuple with the AuthenticatedRateLimit field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Organization) GetAuthenticatedRateLimitOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AuthenticatedRateLimit.Get(), o.AuthenticatedRateLimit.IsSet()\n}\n\n// SetAuthenticatedRateLimit sets field value\nfunc (o *Organization) SetAuthenticatedRateLimit(v float32) {\n\to.AuthenticatedRateLimit.Set(&v)\n}\n\n// GetSandboxCreateRateLimit returns the SandboxCreateRateLimit field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *Organization) GetSandboxCreateRateLimit() float32 {\n\tif o == nil || o.SandboxCreateRateLimit.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SandboxCreateRateLimit.Get()\n}\n\n// GetSandboxCreateRateLimitOk returns a tuple with the SandboxCreateRateLimit field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Organization) GetSandboxCreateRateLimitOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxCreateRateLimit.Get(), o.SandboxCreateRateLimit.IsSet()\n}\n\n// SetSandboxCreateRateLimit sets field value\nfunc (o *Organization) SetSandboxCreateRateLimit(v float32) {\n\to.SandboxCreateRateLimit.Set(&v)\n}\n\n// GetSandboxLifecycleRateLimit returns the SandboxLifecycleRateLimit field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *Organization) GetSandboxLifecycleRateLimit() float32 {\n\tif o == nil || o.SandboxLifecycleRateLimit.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SandboxLifecycleRateLimit.Get()\n}\n\n// GetSandboxLifecycleRateLimitOk returns a tuple with the SandboxLifecycleRateLimit field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Organization) GetSandboxLifecycleRateLimitOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxLifecycleRateLimit.Get(), o.SandboxLifecycleRateLimit.IsSet()\n}\n\n// SetSandboxLifecycleRateLimit sets field value\nfunc (o *Organization) SetSandboxLifecycleRateLimit(v float32) {\n\to.SandboxLifecycleRateLimit.Set(&v)\n}\n\n// GetExperimentalConfig returns the ExperimentalConfig field value\nfunc (o *Organization) GetExperimentalConfig() map[string]interface{} {\n\tif o == nil {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\n\treturn o.ExperimentalConfig\n}\n\n// GetExperimentalConfigOk returns a tuple with the ExperimentalConfig field value\n// and a boolean to check if the value has been set.\nfunc (o *Organization) GetExperimentalConfigOk() (map[string]interface{}, bool) {\n\tif o == nil {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.ExperimentalConfig, true\n}\n\n// SetExperimentalConfig sets field value\nfunc (o *Organization) SetExperimentalConfig(v map[string]interface{}) {\n\to.ExperimentalConfig = v\n}\n\n// GetAuthenticatedRateLimitTtlSeconds returns the AuthenticatedRateLimitTtlSeconds field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *Organization) GetAuthenticatedRateLimitTtlSeconds() float32 {\n\tif o == nil || o.AuthenticatedRateLimitTtlSeconds.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.AuthenticatedRateLimitTtlSeconds.Get()\n}\n\n// GetAuthenticatedRateLimitTtlSecondsOk returns a tuple with the AuthenticatedRateLimitTtlSeconds field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Organization) GetAuthenticatedRateLimitTtlSecondsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AuthenticatedRateLimitTtlSeconds.Get(), o.AuthenticatedRateLimitTtlSeconds.IsSet()\n}\n\n// SetAuthenticatedRateLimitTtlSeconds sets field value\nfunc (o *Organization) SetAuthenticatedRateLimitTtlSeconds(v float32) {\n\to.AuthenticatedRateLimitTtlSeconds.Set(&v)\n}\n\n// GetSandboxCreateRateLimitTtlSeconds returns the SandboxCreateRateLimitTtlSeconds field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *Organization) GetSandboxCreateRateLimitTtlSeconds() float32 {\n\tif o == nil || o.SandboxCreateRateLimitTtlSeconds.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SandboxCreateRateLimitTtlSeconds.Get()\n}\n\n// GetSandboxCreateRateLimitTtlSecondsOk returns a tuple with the SandboxCreateRateLimitTtlSeconds field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Organization) GetSandboxCreateRateLimitTtlSecondsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxCreateRateLimitTtlSeconds.Get(), o.SandboxCreateRateLimitTtlSeconds.IsSet()\n}\n\n// SetSandboxCreateRateLimitTtlSeconds sets field value\nfunc (o *Organization) SetSandboxCreateRateLimitTtlSeconds(v float32) {\n\to.SandboxCreateRateLimitTtlSeconds.Set(&v)\n}\n\n// GetSandboxLifecycleRateLimitTtlSeconds returns the SandboxLifecycleRateLimitTtlSeconds field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *Organization) GetSandboxLifecycleRateLimitTtlSeconds() float32 {\n\tif o == nil || o.SandboxLifecycleRateLimitTtlSeconds.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SandboxLifecycleRateLimitTtlSeconds.Get()\n}\n\n// GetSandboxLifecycleRateLimitTtlSecondsOk returns a tuple with the SandboxLifecycleRateLimitTtlSeconds field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Organization) GetSandboxLifecycleRateLimitTtlSecondsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxLifecycleRateLimitTtlSeconds.Get(), o.SandboxLifecycleRateLimitTtlSeconds.IsSet()\n}\n\n// SetSandboxLifecycleRateLimitTtlSeconds sets field value\nfunc (o *Organization) SetSandboxLifecycleRateLimitTtlSeconds(v float32) {\n\to.SandboxLifecycleRateLimitTtlSeconds.Set(&v)\n}\n\nfunc (o Organization) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Organization) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"createdBy\"] = o.CreatedBy\n\ttoSerialize[\"personal\"] = o.Personal\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\ttoSerialize[\"suspended\"] = o.Suspended\n\ttoSerialize[\"suspendedAt\"] = o.SuspendedAt\n\ttoSerialize[\"suspensionReason\"] = o.SuspensionReason\n\ttoSerialize[\"suspendedUntil\"] = o.SuspendedUntil\n\ttoSerialize[\"suspensionCleanupGracePeriodHours\"] = o.SuspensionCleanupGracePeriodHours\n\ttoSerialize[\"maxCpuPerSandbox\"] = o.MaxCpuPerSandbox\n\ttoSerialize[\"maxMemoryPerSandbox\"] = o.MaxMemoryPerSandbox\n\ttoSerialize[\"maxDiskPerSandbox\"] = o.MaxDiskPerSandbox\n\ttoSerialize[\"snapshotDeactivationTimeoutMinutes\"] = o.SnapshotDeactivationTimeoutMinutes\n\ttoSerialize[\"sandboxLimitedNetworkEgress\"] = o.SandboxLimitedNetworkEgress\n\tif !IsNil(o.DefaultRegionId) {\n\t\ttoSerialize[\"defaultRegionId\"] = o.DefaultRegionId\n\t}\n\ttoSerialize[\"authenticatedRateLimit\"] = o.AuthenticatedRateLimit.Get()\n\ttoSerialize[\"sandboxCreateRateLimit\"] = o.SandboxCreateRateLimit.Get()\n\ttoSerialize[\"sandboxLifecycleRateLimit\"] = o.SandboxLifecycleRateLimit.Get()\n\ttoSerialize[\"experimentalConfig\"] = o.ExperimentalConfig\n\ttoSerialize[\"authenticatedRateLimitTtlSeconds\"] = o.AuthenticatedRateLimitTtlSeconds.Get()\n\ttoSerialize[\"sandboxCreateRateLimitTtlSeconds\"] = o.SandboxCreateRateLimitTtlSeconds.Get()\n\ttoSerialize[\"sandboxLifecycleRateLimitTtlSeconds\"] = o.SandboxLifecycleRateLimitTtlSeconds.Get()\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Organization) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"name\",\n\t\t\"createdBy\",\n\t\t\"personal\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t\t\"suspended\",\n\t\t\"suspendedAt\",\n\t\t\"suspensionReason\",\n\t\t\"suspendedUntil\",\n\t\t\"suspensionCleanupGracePeriodHours\",\n\t\t\"maxCpuPerSandbox\",\n\t\t\"maxMemoryPerSandbox\",\n\t\t\"maxDiskPerSandbox\",\n\t\t\"snapshotDeactivationTimeoutMinutes\",\n\t\t\"sandboxLimitedNetworkEgress\",\n\t\t\"authenticatedRateLimit\",\n\t\t\"sandboxCreateRateLimit\",\n\t\t\"sandboxLifecycleRateLimit\",\n\t\t\"experimentalConfig\",\n\t\t\"authenticatedRateLimitTtlSeconds\",\n\t\t\"sandboxCreateRateLimitTtlSeconds\",\n\t\t\"sandboxLifecycleRateLimitTtlSeconds\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOrganization := _Organization{}\n\n\terr = json.Unmarshal(data, &varOrganization)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Organization(varOrganization)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"createdBy\")\n\t\tdelete(additionalProperties, \"personal\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"suspended\")\n\t\tdelete(additionalProperties, \"suspendedAt\")\n\t\tdelete(additionalProperties, \"suspensionReason\")\n\t\tdelete(additionalProperties, \"suspendedUntil\")\n\t\tdelete(additionalProperties, \"suspensionCleanupGracePeriodHours\")\n\t\tdelete(additionalProperties, \"maxCpuPerSandbox\")\n\t\tdelete(additionalProperties, \"maxMemoryPerSandbox\")\n\t\tdelete(additionalProperties, \"maxDiskPerSandbox\")\n\t\tdelete(additionalProperties, \"snapshotDeactivationTimeoutMinutes\")\n\t\tdelete(additionalProperties, \"sandboxLimitedNetworkEgress\")\n\t\tdelete(additionalProperties, \"defaultRegionId\")\n\t\tdelete(additionalProperties, \"authenticatedRateLimit\")\n\t\tdelete(additionalProperties, \"sandboxCreateRateLimit\")\n\t\tdelete(additionalProperties, \"sandboxLifecycleRateLimit\")\n\t\tdelete(additionalProperties, \"experimentalConfig\")\n\t\tdelete(additionalProperties, \"authenticatedRateLimitTtlSeconds\")\n\t\tdelete(additionalProperties, \"sandboxCreateRateLimitTtlSeconds\")\n\t\tdelete(additionalProperties, \"sandboxLifecycleRateLimitTtlSeconds\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOrganization struct {\n\tvalue *Organization\n\tisSet bool\n}\n\nfunc (v NullableOrganization) Get() *Organization {\n\treturn v.value\n}\n\nfunc (v *NullableOrganization) Set(val *Organization) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOrganization) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOrganization) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOrganization(val *Organization) *NullableOrganization {\n\treturn &NullableOrganization{value: val, isSet: true}\n}\n\nfunc (v NullableOrganization) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOrganization) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_organization_invitation.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the OrganizationInvitation type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &OrganizationInvitation{}\n\n// OrganizationInvitation struct for OrganizationInvitation\ntype OrganizationInvitation struct {\n\t// Invitation ID\n\tId string `json:\"id\"`\n\t// Email address of the invitee\n\tEmail string `json:\"email\"`\n\t// Email address of the inviter\n\tInvitedBy string `json:\"invitedBy\"`\n\t// Organization ID\n\tOrganizationId string `json:\"organizationId\"`\n\t// Organization name\n\tOrganizationName string `json:\"organizationName\"`\n\t// Expiration date of the invitation\n\tExpiresAt time.Time `json:\"expiresAt\"`\n\t// Invitation status\n\tStatus string `json:\"status\"`\n\t// Member role\n\tRole string `json:\"role\"`\n\t// Assigned roles\n\tAssignedRoles []OrganizationRole `json:\"assignedRoles\"`\n\t// Creation timestamp\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// Last update timestamp\n\tUpdatedAt time.Time `json:\"updatedAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _OrganizationInvitation OrganizationInvitation\n\n// NewOrganizationInvitation instantiates a new OrganizationInvitation object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOrganizationInvitation(id string, email string, invitedBy string, organizationId string, organizationName string, expiresAt time.Time, status string, role string, assignedRoles []OrganizationRole, createdAt time.Time, updatedAt time.Time) *OrganizationInvitation {\n\tthis := OrganizationInvitation{}\n\tthis.Id = id\n\tthis.Email = email\n\tthis.InvitedBy = invitedBy\n\tthis.OrganizationId = organizationId\n\tthis.OrganizationName = organizationName\n\tthis.ExpiresAt = expiresAt\n\tthis.Status = status\n\tthis.Role = role\n\tthis.AssignedRoles = assignedRoles\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\treturn &this\n}\n\n// NewOrganizationInvitationWithDefaults instantiates a new OrganizationInvitation object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOrganizationInvitationWithDefaults() *OrganizationInvitation {\n\tthis := OrganizationInvitation{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *OrganizationInvitation) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *OrganizationInvitation) SetId(v string) {\n\to.Id = v\n}\n\n// GetEmail returns the Email field value\nfunc (o *OrganizationInvitation) GetEmail() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Email\n}\n\n// GetEmailOk returns a tuple with the Email field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetEmailOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Email, true\n}\n\n// SetEmail sets field value\nfunc (o *OrganizationInvitation) SetEmail(v string) {\n\to.Email = v\n}\n\n// GetInvitedBy returns the InvitedBy field value\nfunc (o *OrganizationInvitation) GetInvitedBy() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.InvitedBy\n}\n\n// GetInvitedByOk returns a tuple with the InvitedBy field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetInvitedByOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.InvitedBy, true\n}\n\n// SetInvitedBy sets field value\nfunc (o *OrganizationInvitation) SetInvitedBy(v string) {\n\to.InvitedBy = v\n}\n\n// GetOrganizationId returns the OrganizationId field value\nfunc (o *OrganizationInvitation) GetOrganizationId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationId, true\n}\n\n// SetOrganizationId sets field value\nfunc (o *OrganizationInvitation) SetOrganizationId(v string) {\n\to.OrganizationId = v\n}\n\n// GetOrganizationName returns the OrganizationName field value\nfunc (o *OrganizationInvitation) GetOrganizationName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationName\n}\n\n// GetOrganizationNameOk returns a tuple with the OrganizationName field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetOrganizationNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationName, true\n}\n\n// SetOrganizationName sets field value\nfunc (o *OrganizationInvitation) SetOrganizationName(v string) {\n\to.OrganizationName = v\n}\n\n// GetExpiresAt returns the ExpiresAt field value\nfunc (o *OrganizationInvitation) GetExpiresAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.ExpiresAt\n}\n\n// GetExpiresAtOk returns a tuple with the ExpiresAt field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetExpiresAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ExpiresAt, true\n}\n\n// SetExpiresAt sets field value\nfunc (o *OrganizationInvitation) SetExpiresAt(v time.Time) {\n\to.ExpiresAt = v\n}\n\n// GetStatus returns the Status field value\nfunc (o *OrganizationInvitation) GetStatus() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetStatusOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Status, true\n}\n\n// SetStatus sets field value\nfunc (o *OrganizationInvitation) SetStatus(v string) {\n\to.Status = v\n}\n\n// GetRole returns the Role field value\nfunc (o *OrganizationInvitation) GetRole() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Role\n}\n\n// GetRoleOk returns a tuple with the Role field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetRoleOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Role, true\n}\n\n// SetRole sets field value\nfunc (o *OrganizationInvitation) SetRole(v string) {\n\to.Role = v\n}\n\n// GetAssignedRoles returns the AssignedRoles field value\nfunc (o *OrganizationInvitation) GetAssignedRoles() []OrganizationRole {\n\tif o == nil {\n\t\tvar ret []OrganizationRole\n\t\treturn ret\n\t}\n\n\treturn o.AssignedRoles\n}\n\n// GetAssignedRolesOk returns a tuple with the AssignedRoles field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetAssignedRolesOk() ([]OrganizationRole, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AssignedRoles, true\n}\n\n// SetAssignedRoles sets field value\nfunc (o *OrganizationInvitation) SetAssignedRoles(v []OrganizationRole) {\n\to.AssignedRoles = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *OrganizationInvitation) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *OrganizationInvitation) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *OrganizationInvitation) GetUpdatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationInvitation) GetUpdatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *OrganizationInvitation) SetUpdatedAt(v time.Time) {\n\to.UpdatedAt = v\n}\n\nfunc (o OrganizationInvitation) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o OrganizationInvitation) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"email\"] = o.Email\n\ttoSerialize[\"invitedBy\"] = o.InvitedBy\n\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\ttoSerialize[\"organizationName\"] = o.OrganizationName\n\ttoSerialize[\"expiresAt\"] = o.ExpiresAt\n\ttoSerialize[\"status\"] = o.Status\n\ttoSerialize[\"role\"] = o.Role\n\ttoSerialize[\"assignedRoles\"] = o.AssignedRoles\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *OrganizationInvitation) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"email\",\n\t\t\"invitedBy\",\n\t\t\"organizationId\",\n\t\t\"organizationName\",\n\t\t\"expiresAt\",\n\t\t\"status\",\n\t\t\"role\",\n\t\t\"assignedRoles\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOrganizationInvitation := _OrganizationInvitation{}\n\n\terr = json.Unmarshal(data, &varOrganizationInvitation)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = OrganizationInvitation(varOrganizationInvitation)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"email\")\n\t\tdelete(additionalProperties, \"invitedBy\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"organizationName\")\n\t\tdelete(additionalProperties, \"expiresAt\")\n\t\tdelete(additionalProperties, \"status\")\n\t\tdelete(additionalProperties, \"role\")\n\t\tdelete(additionalProperties, \"assignedRoles\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOrganizationInvitation struct {\n\tvalue *OrganizationInvitation\n\tisSet bool\n}\n\nfunc (v NullableOrganizationInvitation) Get() *OrganizationInvitation {\n\treturn v.value\n}\n\nfunc (v *NullableOrganizationInvitation) Set(val *OrganizationInvitation) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOrganizationInvitation) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOrganizationInvitation) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOrganizationInvitation(val *OrganizationInvitation) *NullableOrganizationInvitation {\n\treturn &NullableOrganizationInvitation{value: val, isSet: true}\n}\n\nfunc (v NullableOrganizationInvitation) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOrganizationInvitation) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_organization_role.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the OrganizationRole type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &OrganizationRole{}\n\n// OrganizationRole struct for OrganizationRole\ntype OrganizationRole struct {\n\t// Role ID\n\tId string `json:\"id\"`\n\t// Role name\n\tName string `json:\"name\"`\n\t// Role description\n\tDescription string `json:\"description\"`\n\t// Roles assigned to the user\n\tPermissions []string `json:\"permissions\"`\n\t// Global role flag\n\tIsGlobal bool `json:\"isGlobal\"`\n\t// Creation timestamp\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// Last update timestamp\n\tUpdatedAt time.Time `json:\"updatedAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _OrganizationRole OrganizationRole\n\n// NewOrganizationRole instantiates a new OrganizationRole object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOrganizationRole(id string, name string, description string, permissions []string, isGlobal bool, createdAt time.Time, updatedAt time.Time) *OrganizationRole {\n\tthis := OrganizationRole{}\n\tthis.Id = id\n\tthis.Name = name\n\tthis.Description = description\n\tthis.Permissions = permissions\n\tthis.IsGlobal = isGlobal\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\treturn &this\n}\n\n// NewOrganizationRoleWithDefaults instantiates a new OrganizationRole object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOrganizationRoleWithDefaults() *OrganizationRole {\n\tthis := OrganizationRole{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *OrganizationRole) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationRole) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *OrganizationRole) SetId(v string) {\n\to.Id = v\n}\n\n// GetName returns the Name field value\nfunc (o *OrganizationRole) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationRole) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *OrganizationRole) SetName(v string) {\n\to.Name = v\n}\n\n// GetDescription returns the Description field value\nfunc (o *OrganizationRole) GetDescription() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Description\n}\n\n// GetDescriptionOk returns a tuple with the Description field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationRole) GetDescriptionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Description, true\n}\n\n// SetDescription sets field value\nfunc (o *OrganizationRole) SetDescription(v string) {\n\to.Description = v\n}\n\n// GetPermissions returns the Permissions field value\nfunc (o *OrganizationRole) GetPermissions() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Permissions\n}\n\n// GetPermissionsOk returns a tuple with the Permissions field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationRole) GetPermissionsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Permissions, true\n}\n\n// SetPermissions sets field value\nfunc (o *OrganizationRole) SetPermissions(v []string) {\n\to.Permissions = v\n}\n\n// GetIsGlobal returns the IsGlobal field value\nfunc (o *OrganizationRole) GetIsGlobal() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.IsGlobal\n}\n\n// GetIsGlobalOk returns a tuple with the IsGlobal field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationRole) GetIsGlobalOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.IsGlobal, true\n}\n\n// SetIsGlobal sets field value\nfunc (o *OrganizationRole) SetIsGlobal(v bool) {\n\to.IsGlobal = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *OrganizationRole) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationRole) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *OrganizationRole) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *OrganizationRole) GetUpdatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationRole) GetUpdatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *OrganizationRole) SetUpdatedAt(v time.Time) {\n\to.UpdatedAt = v\n}\n\nfunc (o OrganizationRole) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o OrganizationRole) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"description\"] = o.Description\n\ttoSerialize[\"permissions\"] = o.Permissions\n\ttoSerialize[\"isGlobal\"] = o.IsGlobal\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *OrganizationRole) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"name\",\n\t\t\"description\",\n\t\t\"permissions\",\n\t\t\"isGlobal\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOrganizationRole := _OrganizationRole{}\n\n\terr = json.Unmarshal(data, &varOrganizationRole)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = OrganizationRole(varOrganizationRole)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"description\")\n\t\tdelete(additionalProperties, \"permissions\")\n\t\tdelete(additionalProperties, \"isGlobal\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOrganizationRole struct {\n\tvalue *OrganizationRole\n\tisSet bool\n}\n\nfunc (v NullableOrganizationRole) Get() *OrganizationRole {\n\treturn v.value\n}\n\nfunc (v *NullableOrganizationRole) Set(val *OrganizationRole) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOrganizationRole) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOrganizationRole) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOrganizationRole(val *OrganizationRole) *NullableOrganizationRole {\n\treturn &NullableOrganizationRole{value: val, isSet: true}\n}\n\nfunc (v NullableOrganizationRole) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOrganizationRole) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_organization_sandbox_default_limited_network_egress.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the OrganizationSandboxDefaultLimitedNetworkEgress type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &OrganizationSandboxDefaultLimitedNetworkEgress{}\n\n// OrganizationSandboxDefaultLimitedNetworkEgress struct for OrganizationSandboxDefaultLimitedNetworkEgress\ntype OrganizationSandboxDefaultLimitedNetworkEgress struct {\n\t// Sandbox default limited network egress\n\tSandboxDefaultLimitedNetworkEgress bool `json:\"sandboxDefaultLimitedNetworkEgress\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _OrganizationSandboxDefaultLimitedNetworkEgress OrganizationSandboxDefaultLimitedNetworkEgress\n\n// NewOrganizationSandboxDefaultLimitedNetworkEgress instantiates a new OrganizationSandboxDefaultLimitedNetworkEgress object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOrganizationSandboxDefaultLimitedNetworkEgress(sandboxDefaultLimitedNetworkEgress bool) *OrganizationSandboxDefaultLimitedNetworkEgress {\n\tthis := OrganizationSandboxDefaultLimitedNetworkEgress{}\n\tthis.SandboxDefaultLimitedNetworkEgress = sandboxDefaultLimitedNetworkEgress\n\treturn &this\n}\n\n// NewOrganizationSandboxDefaultLimitedNetworkEgressWithDefaults instantiates a new OrganizationSandboxDefaultLimitedNetworkEgress object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOrganizationSandboxDefaultLimitedNetworkEgressWithDefaults() *OrganizationSandboxDefaultLimitedNetworkEgress {\n\tthis := OrganizationSandboxDefaultLimitedNetworkEgress{}\n\treturn &this\n}\n\n// GetSandboxDefaultLimitedNetworkEgress returns the SandboxDefaultLimitedNetworkEgress field value\nfunc (o *OrganizationSandboxDefaultLimitedNetworkEgress) GetSandboxDefaultLimitedNetworkEgress() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.SandboxDefaultLimitedNetworkEgress\n}\n\n// GetSandboxDefaultLimitedNetworkEgressOk returns a tuple with the SandboxDefaultLimitedNetworkEgress field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationSandboxDefaultLimitedNetworkEgress) GetSandboxDefaultLimitedNetworkEgressOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SandboxDefaultLimitedNetworkEgress, true\n}\n\n// SetSandboxDefaultLimitedNetworkEgress sets field value\nfunc (o *OrganizationSandboxDefaultLimitedNetworkEgress) SetSandboxDefaultLimitedNetworkEgress(v bool) {\n\to.SandboxDefaultLimitedNetworkEgress = v\n}\n\nfunc (o OrganizationSandboxDefaultLimitedNetworkEgress) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o OrganizationSandboxDefaultLimitedNetworkEgress) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"sandboxDefaultLimitedNetworkEgress\"] = o.SandboxDefaultLimitedNetworkEgress\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *OrganizationSandboxDefaultLimitedNetworkEgress) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"sandboxDefaultLimitedNetworkEgress\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOrganizationSandboxDefaultLimitedNetworkEgress := _OrganizationSandboxDefaultLimitedNetworkEgress{}\n\n\terr = json.Unmarshal(data, &varOrganizationSandboxDefaultLimitedNetworkEgress)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = OrganizationSandboxDefaultLimitedNetworkEgress(varOrganizationSandboxDefaultLimitedNetworkEgress)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"sandboxDefaultLimitedNetworkEgress\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOrganizationSandboxDefaultLimitedNetworkEgress struct {\n\tvalue *OrganizationSandboxDefaultLimitedNetworkEgress\n\tisSet bool\n}\n\nfunc (v NullableOrganizationSandboxDefaultLimitedNetworkEgress) Get() *OrganizationSandboxDefaultLimitedNetworkEgress {\n\treturn v.value\n}\n\nfunc (v *NullableOrganizationSandboxDefaultLimitedNetworkEgress) Set(val *OrganizationSandboxDefaultLimitedNetworkEgress) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOrganizationSandboxDefaultLimitedNetworkEgress) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOrganizationSandboxDefaultLimitedNetworkEgress) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOrganizationSandboxDefaultLimitedNetworkEgress(val *OrganizationSandboxDefaultLimitedNetworkEgress) *NullableOrganizationSandboxDefaultLimitedNetworkEgress {\n\treturn &NullableOrganizationSandboxDefaultLimitedNetworkEgress{value: val, isSet: true}\n}\n\nfunc (v NullableOrganizationSandboxDefaultLimitedNetworkEgress) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOrganizationSandboxDefaultLimitedNetworkEgress) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_organization_suspension.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the OrganizationSuspension type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &OrganizationSuspension{}\n\n// OrganizationSuspension struct for OrganizationSuspension\ntype OrganizationSuspension struct {\n\t// Suspension reason\n\tReason string `json:\"reason\"`\n\t// Suspension until\n\tUntil time.Time `json:\"until\"`\n\t// Suspension cleanup grace period hours\n\tSuspensionCleanupGracePeriodHours *float32 `json:\"suspensionCleanupGracePeriodHours,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _OrganizationSuspension OrganizationSuspension\n\n// NewOrganizationSuspension instantiates a new OrganizationSuspension object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOrganizationSuspension(reason string, until time.Time) *OrganizationSuspension {\n\tthis := OrganizationSuspension{}\n\tthis.Reason = reason\n\tthis.Until = until\n\treturn &this\n}\n\n// NewOrganizationSuspensionWithDefaults instantiates a new OrganizationSuspension object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOrganizationSuspensionWithDefaults() *OrganizationSuspension {\n\tthis := OrganizationSuspension{}\n\treturn &this\n}\n\n// GetReason returns the Reason field value\nfunc (o *OrganizationSuspension) GetReason() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Reason\n}\n\n// GetReasonOk returns a tuple with the Reason field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationSuspension) GetReasonOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Reason, true\n}\n\n// SetReason sets field value\nfunc (o *OrganizationSuspension) SetReason(v string) {\n\to.Reason = v\n}\n\n// GetUntil returns the Until field value\nfunc (o *OrganizationSuspension) GetUntil() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.Until\n}\n\n// GetUntilOk returns a tuple with the Until field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationSuspension) GetUntilOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Until, true\n}\n\n// SetUntil sets field value\nfunc (o *OrganizationSuspension) SetUntil(v time.Time) {\n\to.Until = v\n}\n\n// GetSuspensionCleanupGracePeriodHours returns the SuspensionCleanupGracePeriodHours field value if set, zero value otherwise.\nfunc (o *OrganizationSuspension) GetSuspensionCleanupGracePeriodHours() float32 {\n\tif o == nil || IsNil(o.SuspensionCleanupGracePeriodHours) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.SuspensionCleanupGracePeriodHours\n}\n\n// GetSuspensionCleanupGracePeriodHoursOk returns a tuple with the SuspensionCleanupGracePeriodHours field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationSuspension) GetSuspensionCleanupGracePeriodHoursOk() (*float32, bool) {\n\tif o == nil || IsNil(o.SuspensionCleanupGracePeriodHours) {\n\t\treturn nil, false\n\t}\n\treturn o.SuspensionCleanupGracePeriodHours, true\n}\n\n// HasSuspensionCleanupGracePeriodHours returns a boolean if a field has been set.\nfunc (o *OrganizationSuspension) HasSuspensionCleanupGracePeriodHours() bool {\n\tif o != nil && !IsNil(o.SuspensionCleanupGracePeriodHours) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSuspensionCleanupGracePeriodHours gets a reference to the given float32 and assigns it to the SuspensionCleanupGracePeriodHours field.\nfunc (o *OrganizationSuspension) SetSuspensionCleanupGracePeriodHours(v float32) {\n\to.SuspensionCleanupGracePeriodHours = &v\n}\n\nfunc (o OrganizationSuspension) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o OrganizationSuspension) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"reason\"] = o.Reason\n\ttoSerialize[\"until\"] = o.Until\n\tif !IsNil(o.SuspensionCleanupGracePeriodHours) {\n\t\ttoSerialize[\"suspensionCleanupGracePeriodHours\"] = o.SuspensionCleanupGracePeriodHours\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *OrganizationSuspension) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"reason\",\n\t\t\"until\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOrganizationSuspension := _OrganizationSuspension{}\n\n\terr = json.Unmarshal(data, &varOrganizationSuspension)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = OrganizationSuspension(varOrganizationSuspension)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"reason\")\n\t\tdelete(additionalProperties, \"until\")\n\t\tdelete(additionalProperties, \"suspensionCleanupGracePeriodHours\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOrganizationSuspension struct {\n\tvalue *OrganizationSuspension\n\tisSet bool\n}\n\nfunc (v NullableOrganizationSuspension) Get() *OrganizationSuspension {\n\treturn v.value\n}\n\nfunc (v *NullableOrganizationSuspension) Set(val *OrganizationSuspension) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOrganizationSuspension) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOrganizationSuspension) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOrganizationSuspension(val *OrganizationSuspension) *NullableOrganizationSuspension {\n\treturn &NullableOrganizationSuspension{value: val, isSet: true}\n}\n\nfunc (v NullableOrganizationSuspension) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOrganizationSuspension) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_organization_usage_overview.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the OrganizationUsageOverview type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &OrganizationUsageOverview{}\n\n// OrganizationUsageOverview struct for OrganizationUsageOverview\ntype OrganizationUsageOverview struct {\n\tRegionUsage []RegionUsageOverview `json:\"regionUsage\"`\n\tTotalSnapshotQuota float32 `json:\"totalSnapshotQuota\"`\n\tCurrentSnapshotUsage float32 `json:\"currentSnapshotUsage\"`\n\tTotalVolumeQuota float32 `json:\"totalVolumeQuota\"`\n\tCurrentVolumeUsage float32 `json:\"currentVolumeUsage\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _OrganizationUsageOverview OrganizationUsageOverview\n\n// NewOrganizationUsageOverview instantiates a new OrganizationUsageOverview object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOrganizationUsageOverview(regionUsage []RegionUsageOverview, totalSnapshotQuota float32, currentSnapshotUsage float32, totalVolumeQuota float32, currentVolumeUsage float32) *OrganizationUsageOverview {\n\tthis := OrganizationUsageOverview{}\n\tthis.RegionUsage = regionUsage\n\tthis.TotalSnapshotQuota = totalSnapshotQuota\n\tthis.CurrentSnapshotUsage = currentSnapshotUsage\n\tthis.TotalVolumeQuota = totalVolumeQuota\n\tthis.CurrentVolumeUsage = currentVolumeUsage\n\treturn &this\n}\n\n// NewOrganizationUsageOverviewWithDefaults instantiates a new OrganizationUsageOverview object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOrganizationUsageOverviewWithDefaults() *OrganizationUsageOverview {\n\tthis := OrganizationUsageOverview{}\n\treturn &this\n}\n\n// GetRegionUsage returns the RegionUsage field value\nfunc (o *OrganizationUsageOverview) GetRegionUsage() []RegionUsageOverview {\n\tif o == nil {\n\t\tvar ret []RegionUsageOverview\n\t\treturn ret\n\t}\n\n\treturn o.RegionUsage\n}\n\n// GetRegionUsageOk returns a tuple with the RegionUsage field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUsageOverview) GetRegionUsageOk() ([]RegionUsageOverview, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.RegionUsage, true\n}\n\n// SetRegionUsage sets field value\nfunc (o *OrganizationUsageOverview) SetRegionUsage(v []RegionUsageOverview) {\n\to.RegionUsage = v\n}\n\n// GetTotalSnapshotQuota returns the TotalSnapshotQuota field value\nfunc (o *OrganizationUsageOverview) GetTotalSnapshotQuota() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalSnapshotQuota\n}\n\n// GetTotalSnapshotQuotaOk returns a tuple with the TotalSnapshotQuota field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUsageOverview) GetTotalSnapshotQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalSnapshotQuota, true\n}\n\n// SetTotalSnapshotQuota sets field value\nfunc (o *OrganizationUsageOverview) SetTotalSnapshotQuota(v float32) {\n\to.TotalSnapshotQuota = v\n}\n\n// GetCurrentSnapshotUsage returns the CurrentSnapshotUsage field value\nfunc (o *OrganizationUsageOverview) GetCurrentSnapshotUsage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentSnapshotUsage\n}\n\n// GetCurrentSnapshotUsageOk returns a tuple with the CurrentSnapshotUsage field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUsageOverview) GetCurrentSnapshotUsageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentSnapshotUsage, true\n}\n\n// SetCurrentSnapshotUsage sets field value\nfunc (o *OrganizationUsageOverview) SetCurrentSnapshotUsage(v float32) {\n\to.CurrentSnapshotUsage = v\n}\n\n// GetTotalVolumeQuota returns the TotalVolumeQuota field value\nfunc (o *OrganizationUsageOverview) GetTotalVolumeQuota() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalVolumeQuota\n}\n\n// GetTotalVolumeQuotaOk returns a tuple with the TotalVolumeQuota field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUsageOverview) GetTotalVolumeQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalVolumeQuota, true\n}\n\n// SetTotalVolumeQuota sets field value\nfunc (o *OrganizationUsageOverview) SetTotalVolumeQuota(v float32) {\n\to.TotalVolumeQuota = v\n}\n\n// GetCurrentVolumeUsage returns the CurrentVolumeUsage field value\nfunc (o *OrganizationUsageOverview) GetCurrentVolumeUsage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentVolumeUsage\n}\n\n// GetCurrentVolumeUsageOk returns a tuple with the CurrentVolumeUsage field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUsageOverview) GetCurrentVolumeUsageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentVolumeUsage, true\n}\n\n// SetCurrentVolumeUsage sets field value\nfunc (o *OrganizationUsageOverview) SetCurrentVolumeUsage(v float32) {\n\to.CurrentVolumeUsage = v\n}\n\nfunc (o OrganizationUsageOverview) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o OrganizationUsageOverview) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"regionUsage\"] = o.RegionUsage\n\ttoSerialize[\"totalSnapshotQuota\"] = o.TotalSnapshotQuota\n\ttoSerialize[\"currentSnapshotUsage\"] = o.CurrentSnapshotUsage\n\ttoSerialize[\"totalVolumeQuota\"] = o.TotalVolumeQuota\n\ttoSerialize[\"currentVolumeUsage\"] = o.CurrentVolumeUsage\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *OrganizationUsageOverview) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"regionUsage\",\n\t\t\"totalSnapshotQuota\",\n\t\t\"currentSnapshotUsage\",\n\t\t\"totalVolumeQuota\",\n\t\t\"currentVolumeUsage\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOrganizationUsageOverview := _OrganizationUsageOverview{}\n\n\terr = json.Unmarshal(data, &varOrganizationUsageOverview)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = OrganizationUsageOverview(varOrganizationUsageOverview)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"regionUsage\")\n\t\tdelete(additionalProperties, \"totalSnapshotQuota\")\n\t\tdelete(additionalProperties, \"currentSnapshotUsage\")\n\t\tdelete(additionalProperties, \"totalVolumeQuota\")\n\t\tdelete(additionalProperties, \"currentVolumeUsage\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOrganizationUsageOverview struct {\n\tvalue *OrganizationUsageOverview\n\tisSet bool\n}\n\nfunc (v NullableOrganizationUsageOverview) Get() *OrganizationUsageOverview {\n\treturn v.value\n}\n\nfunc (v *NullableOrganizationUsageOverview) Set(val *OrganizationUsageOverview) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOrganizationUsageOverview) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOrganizationUsageOverview) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOrganizationUsageOverview(val *OrganizationUsageOverview) *NullableOrganizationUsageOverview {\n\treturn &NullableOrganizationUsageOverview{value: val, isSet: true}\n}\n\nfunc (v NullableOrganizationUsageOverview) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOrganizationUsageOverview) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_organization_user.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the OrganizationUser type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &OrganizationUser{}\n\n// OrganizationUser struct for OrganizationUser\ntype OrganizationUser struct {\n\t// User ID\n\tUserId string `json:\"userId\"`\n\t// Organization ID\n\tOrganizationId string `json:\"organizationId\"`\n\t// User name\n\tName string `json:\"name\"`\n\t// User email\n\tEmail string `json:\"email\"`\n\t// Member role\n\tRole string `json:\"role\"`\n\t// Roles assigned to the user\n\tAssignedRoles []OrganizationRole `json:\"assignedRoles\"`\n\t// Creation timestamp\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// Last update timestamp\n\tUpdatedAt time.Time `json:\"updatedAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _OrganizationUser OrganizationUser\n\n// NewOrganizationUser instantiates a new OrganizationUser object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOrganizationUser(userId string, organizationId string, name string, email string, role string, assignedRoles []OrganizationRole, createdAt time.Time, updatedAt time.Time) *OrganizationUser {\n\tthis := OrganizationUser{}\n\tthis.UserId = userId\n\tthis.OrganizationId = organizationId\n\tthis.Name = name\n\tthis.Email = email\n\tthis.Role = role\n\tthis.AssignedRoles = assignedRoles\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\treturn &this\n}\n\n// NewOrganizationUserWithDefaults instantiates a new OrganizationUser object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOrganizationUserWithDefaults() *OrganizationUser {\n\tthis := OrganizationUser{}\n\treturn &this\n}\n\n// GetUserId returns the UserId field value\nfunc (o *OrganizationUser) GetUserId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.UserId\n}\n\n// GetUserIdOk returns a tuple with the UserId field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUser) GetUserIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UserId, true\n}\n\n// SetUserId sets field value\nfunc (o *OrganizationUser) SetUserId(v string) {\n\to.UserId = v\n}\n\n// GetOrganizationId returns the OrganizationId field value\nfunc (o *OrganizationUser) GetOrganizationId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUser) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationId, true\n}\n\n// SetOrganizationId sets field value\nfunc (o *OrganizationUser) SetOrganizationId(v string) {\n\to.OrganizationId = v\n}\n\n// GetName returns the Name field value\nfunc (o *OrganizationUser) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUser) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *OrganizationUser) SetName(v string) {\n\to.Name = v\n}\n\n// GetEmail returns the Email field value\nfunc (o *OrganizationUser) GetEmail() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Email\n}\n\n// GetEmailOk returns a tuple with the Email field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUser) GetEmailOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Email, true\n}\n\n// SetEmail sets field value\nfunc (o *OrganizationUser) SetEmail(v string) {\n\to.Email = v\n}\n\n// GetRole returns the Role field value\nfunc (o *OrganizationUser) GetRole() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Role\n}\n\n// GetRoleOk returns a tuple with the Role field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUser) GetRoleOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Role, true\n}\n\n// SetRole sets field value\nfunc (o *OrganizationUser) SetRole(v string) {\n\to.Role = v\n}\n\n// GetAssignedRoles returns the AssignedRoles field value\nfunc (o *OrganizationUser) GetAssignedRoles() []OrganizationRole {\n\tif o == nil {\n\t\tvar ret []OrganizationRole\n\t\treturn ret\n\t}\n\n\treturn o.AssignedRoles\n}\n\n// GetAssignedRolesOk returns a tuple with the AssignedRoles field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUser) GetAssignedRolesOk() ([]OrganizationRole, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AssignedRoles, true\n}\n\n// SetAssignedRoles sets field value\nfunc (o *OrganizationUser) SetAssignedRoles(v []OrganizationRole) {\n\to.AssignedRoles = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *OrganizationUser) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUser) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *OrganizationUser) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *OrganizationUser) GetUpdatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *OrganizationUser) GetUpdatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *OrganizationUser) SetUpdatedAt(v time.Time) {\n\to.UpdatedAt = v\n}\n\nfunc (o OrganizationUser) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o OrganizationUser) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"userId\"] = o.UserId\n\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"email\"] = o.Email\n\ttoSerialize[\"role\"] = o.Role\n\ttoSerialize[\"assignedRoles\"] = o.AssignedRoles\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *OrganizationUser) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"userId\",\n\t\t\"organizationId\",\n\t\t\"name\",\n\t\t\"email\",\n\t\t\"role\",\n\t\t\"assignedRoles\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOrganizationUser := _OrganizationUser{}\n\n\terr = json.Unmarshal(data, &varOrganizationUser)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = OrganizationUser(varOrganizationUser)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"userId\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"email\")\n\t\tdelete(additionalProperties, \"role\")\n\t\tdelete(additionalProperties, \"assignedRoles\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOrganizationUser struct {\n\tvalue *OrganizationUser\n\tisSet bool\n}\n\nfunc (v NullableOrganizationUser) Get() *OrganizationUser {\n\treturn v.value\n}\n\nfunc (v *NullableOrganizationUser) Set(val *OrganizationUser) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOrganizationUser) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOrganizationUser) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOrganizationUser(val *OrganizationUser) *NullableOrganizationUser {\n\treturn &NullableOrganizationUser{value: val, isSet: true}\n}\n\nfunc (v NullableOrganizationUser) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOrganizationUser) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_otel_config.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the OtelConfig type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &OtelConfig{}\n\n// OtelConfig struct for OtelConfig\ntype OtelConfig struct {\n\t// Endpoint\n\tEndpoint string `json:\"endpoint\"`\n\t// Headers\n\tHeaders map[string]string `json:\"headers,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _OtelConfig OtelConfig\n\n// NewOtelConfig instantiates a new OtelConfig object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewOtelConfig(endpoint string) *OtelConfig {\n\tthis := OtelConfig{}\n\tthis.Endpoint = endpoint\n\treturn &this\n}\n\n// NewOtelConfigWithDefaults instantiates a new OtelConfig object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewOtelConfigWithDefaults() *OtelConfig {\n\tthis := OtelConfig{}\n\treturn &this\n}\n\n// GetEndpoint returns the Endpoint field value\nfunc (o *OtelConfig) GetEndpoint() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Endpoint\n}\n\n// GetEndpointOk returns a tuple with the Endpoint field value\n// and a boolean to check if the value has been set.\nfunc (o *OtelConfig) GetEndpointOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Endpoint, true\n}\n\n// SetEndpoint sets field value\nfunc (o *OtelConfig) SetEndpoint(v string) {\n\to.Endpoint = v\n}\n\n// GetHeaders returns the Headers field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *OtelConfig) GetHeaders() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\treturn o.Headers\n}\n\n// GetHeadersOk returns a tuple with the Headers field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *OtelConfig) GetHeadersOk() (*map[string]string, bool) {\n\tif o == nil || IsNil(o.Headers) {\n\t\treturn nil, false\n\t}\n\treturn &o.Headers, true\n}\n\n// HasHeaders returns a boolean if a field has been set.\nfunc (o *OtelConfig) HasHeaders() bool {\n\tif o != nil && !IsNil(o.Headers) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetHeaders gets a reference to the given map[string]string and assigns it to the Headers field.\nfunc (o *OtelConfig) SetHeaders(v map[string]string) {\n\to.Headers = v\n}\n\nfunc (o OtelConfig) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o OtelConfig) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"endpoint\"] = o.Endpoint\n\tif o.Headers != nil {\n\t\ttoSerialize[\"headers\"] = o.Headers\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *OtelConfig) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"endpoint\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarOtelConfig := _OtelConfig{}\n\n\terr = json.Unmarshal(data, &varOtelConfig)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = OtelConfig(varOtelConfig)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"endpoint\")\n\t\tdelete(additionalProperties, \"headers\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableOtelConfig struct {\n\tvalue *OtelConfig\n\tisSet bool\n}\n\nfunc (v NullableOtelConfig) Get() *OtelConfig {\n\treturn v.value\n}\n\nfunc (v *NullableOtelConfig) Set(val *OtelConfig) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableOtelConfig) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableOtelConfig) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableOtelConfig(val *OtelConfig) *NullableOtelConfig {\n\treturn &NullableOtelConfig{value: val, isSet: true}\n}\n\nfunc (v NullableOtelConfig) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableOtelConfig) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_paginated_audit_logs.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PaginatedAuditLogs type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PaginatedAuditLogs{}\n\n// PaginatedAuditLogs struct for PaginatedAuditLogs\ntype PaginatedAuditLogs struct {\n\tItems []AuditLog `json:\"items\"`\n\tTotal float32 `json:\"total\"`\n\tPage float32 `json:\"page\"`\n\tTotalPages float32 `json:\"totalPages\"`\n\t// Token for next page in cursor-based pagination\n\tNextToken *string `json:\"nextToken,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PaginatedAuditLogs PaginatedAuditLogs\n\n// NewPaginatedAuditLogs instantiates a new PaginatedAuditLogs object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPaginatedAuditLogs(items []AuditLog, total float32, page float32, totalPages float32) *PaginatedAuditLogs {\n\tthis := PaginatedAuditLogs{}\n\tthis.Items = items\n\tthis.Total = total\n\tthis.Page = page\n\tthis.TotalPages = totalPages\n\treturn &this\n}\n\n// NewPaginatedAuditLogsWithDefaults instantiates a new PaginatedAuditLogs object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPaginatedAuditLogsWithDefaults() *PaginatedAuditLogs {\n\tthis := PaginatedAuditLogs{}\n\treturn &this\n}\n\n// GetItems returns the Items field value\nfunc (o *PaginatedAuditLogs) GetItems() []AuditLog {\n\tif o == nil {\n\t\tvar ret []AuditLog\n\t\treturn ret\n\t}\n\n\treturn o.Items\n}\n\n// GetItemsOk returns a tuple with the Items field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedAuditLogs) GetItemsOk() ([]AuditLog, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Items, true\n}\n\n// SetItems sets field value\nfunc (o *PaginatedAuditLogs) SetItems(v []AuditLog) {\n\to.Items = v\n}\n\n// GetTotal returns the Total field value\nfunc (o *PaginatedAuditLogs) GetTotal() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Total\n}\n\n// GetTotalOk returns a tuple with the Total field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedAuditLogs) GetTotalOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Total, true\n}\n\n// SetTotal sets field value\nfunc (o *PaginatedAuditLogs) SetTotal(v float32) {\n\to.Total = v\n}\n\n// GetPage returns the Page field value\nfunc (o *PaginatedAuditLogs) GetPage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Page\n}\n\n// GetPageOk returns a tuple with the Page field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedAuditLogs) GetPageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Page, true\n}\n\n// SetPage sets field value\nfunc (o *PaginatedAuditLogs) SetPage(v float32) {\n\to.Page = v\n}\n\n// GetTotalPages returns the TotalPages field value\nfunc (o *PaginatedAuditLogs) GetTotalPages() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalPages\n}\n\n// GetTotalPagesOk returns a tuple with the TotalPages field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedAuditLogs) GetTotalPagesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalPages, true\n}\n\n// SetTotalPages sets field value\nfunc (o *PaginatedAuditLogs) SetTotalPages(v float32) {\n\to.TotalPages = v\n}\n\n// GetNextToken returns the NextToken field value if set, zero value otherwise.\nfunc (o *PaginatedAuditLogs) GetNextToken() string {\n\tif o == nil || IsNil(o.NextToken) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.NextToken\n}\n\n// GetNextTokenOk returns a tuple with the NextToken field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedAuditLogs) GetNextTokenOk() (*string, bool) {\n\tif o == nil || IsNil(o.NextToken) {\n\t\treturn nil, false\n\t}\n\treturn o.NextToken, true\n}\n\n// HasNextToken returns a boolean if a field has been set.\nfunc (o *PaginatedAuditLogs) HasNextToken() bool {\n\tif o != nil && !IsNil(o.NextToken) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetNextToken gets a reference to the given string and assigns it to the NextToken field.\nfunc (o *PaginatedAuditLogs) SetNextToken(v string) {\n\to.NextToken = &v\n}\n\nfunc (o PaginatedAuditLogs) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PaginatedAuditLogs) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"items\"] = o.Items\n\ttoSerialize[\"total\"] = o.Total\n\ttoSerialize[\"page\"] = o.Page\n\ttoSerialize[\"totalPages\"] = o.TotalPages\n\tif !IsNil(o.NextToken) {\n\t\ttoSerialize[\"nextToken\"] = o.NextToken\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PaginatedAuditLogs) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"items\",\n\t\t\"total\",\n\t\t\"page\",\n\t\t\"totalPages\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPaginatedAuditLogs := _PaginatedAuditLogs{}\n\n\terr = json.Unmarshal(data, &varPaginatedAuditLogs)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PaginatedAuditLogs(varPaginatedAuditLogs)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"items\")\n\t\tdelete(additionalProperties, \"total\")\n\t\tdelete(additionalProperties, \"page\")\n\t\tdelete(additionalProperties, \"totalPages\")\n\t\tdelete(additionalProperties, \"nextToken\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePaginatedAuditLogs struct {\n\tvalue *PaginatedAuditLogs\n\tisSet bool\n}\n\nfunc (v NullablePaginatedAuditLogs) Get() *PaginatedAuditLogs {\n\treturn v.value\n}\n\nfunc (v *NullablePaginatedAuditLogs) Set(val *PaginatedAuditLogs) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePaginatedAuditLogs) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePaginatedAuditLogs) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePaginatedAuditLogs(val *PaginatedAuditLogs) *NullablePaginatedAuditLogs {\n\treturn &NullablePaginatedAuditLogs{value: val, isSet: true}\n}\n\nfunc (v NullablePaginatedAuditLogs) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePaginatedAuditLogs) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_paginated_jobs.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PaginatedJobs type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PaginatedJobs{}\n\n// PaginatedJobs struct for PaginatedJobs\ntype PaginatedJobs struct {\n\tItems []Job `json:\"items\"`\n\tTotal float32 `json:\"total\"`\n\tPage float32 `json:\"page\"`\n\tTotalPages float32 `json:\"totalPages\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PaginatedJobs PaginatedJobs\n\n// NewPaginatedJobs instantiates a new PaginatedJobs object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPaginatedJobs(items []Job, total float32, page float32, totalPages float32) *PaginatedJobs {\n\tthis := PaginatedJobs{}\n\tthis.Items = items\n\tthis.Total = total\n\tthis.Page = page\n\tthis.TotalPages = totalPages\n\treturn &this\n}\n\n// NewPaginatedJobsWithDefaults instantiates a new PaginatedJobs object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPaginatedJobsWithDefaults() *PaginatedJobs {\n\tthis := PaginatedJobs{}\n\treturn &this\n}\n\n// GetItems returns the Items field value\nfunc (o *PaginatedJobs) GetItems() []Job {\n\tif o == nil {\n\t\tvar ret []Job\n\t\treturn ret\n\t}\n\n\treturn o.Items\n}\n\n// GetItemsOk returns a tuple with the Items field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedJobs) GetItemsOk() ([]Job, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Items, true\n}\n\n// SetItems sets field value\nfunc (o *PaginatedJobs) SetItems(v []Job) {\n\to.Items = v\n}\n\n// GetTotal returns the Total field value\nfunc (o *PaginatedJobs) GetTotal() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Total\n}\n\n// GetTotalOk returns a tuple with the Total field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedJobs) GetTotalOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Total, true\n}\n\n// SetTotal sets field value\nfunc (o *PaginatedJobs) SetTotal(v float32) {\n\to.Total = v\n}\n\n// GetPage returns the Page field value\nfunc (o *PaginatedJobs) GetPage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Page\n}\n\n// GetPageOk returns a tuple with the Page field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedJobs) GetPageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Page, true\n}\n\n// SetPage sets field value\nfunc (o *PaginatedJobs) SetPage(v float32) {\n\to.Page = v\n}\n\n// GetTotalPages returns the TotalPages field value\nfunc (o *PaginatedJobs) GetTotalPages() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalPages\n}\n\n// GetTotalPagesOk returns a tuple with the TotalPages field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedJobs) GetTotalPagesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalPages, true\n}\n\n// SetTotalPages sets field value\nfunc (o *PaginatedJobs) SetTotalPages(v float32) {\n\to.TotalPages = v\n}\n\nfunc (o PaginatedJobs) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PaginatedJobs) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"items\"] = o.Items\n\ttoSerialize[\"total\"] = o.Total\n\ttoSerialize[\"page\"] = o.Page\n\ttoSerialize[\"totalPages\"] = o.TotalPages\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PaginatedJobs) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"items\",\n\t\t\"total\",\n\t\t\"page\",\n\t\t\"totalPages\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPaginatedJobs := _PaginatedJobs{}\n\n\terr = json.Unmarshal(data, &varPaginatedJobs)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PaginatedJobs(varPaginatedJobs)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"items\")\n\t\tdelete(additionalProperties, \"total\")\n\t\tdelete(additionalProperties, \"page\")\n\t\tdelete(additionalProperties, \"totalPages\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePaginatedJobs struct {\n\tvalue *PaginatedJobs\n\tisSet bool\n}\n\nfunc (v NullablePaginatedJobs) Get() *PaginatedJobs {\n\treturn v.value\n}\n\nfunc (v *NullablePaginatedJobs) Set(val *PaginatedJobs) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePaginatedJobs) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePaginatedJobs) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePaginatedJobs(val *PaginatedJobs) *NullablePaginatedJobs {\n\treturn &NullablePaginatedJobs{value: val, isSet: true}\n}\n\nfunc (v NullablePaginatedJobs) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePaginatedJobs) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_paginated_logs.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PaginatedLogs type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PaginatedLogs{}\n\n// PaginatedLogs struct for PaginatedLogs\ntype PaginatedLogs struct {\n\t// List of log entries\n\tItems []LogEntry `json:\"items\"`\n\t// Total number of log entries matching the query\n\tTotal float32 `json:\"total\"`\n\t// Current page number\n\tPage float32 `json:\"page\"`\n\t// Total number of pages\n\tTotalPages float32 `json:\"totalPages\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PaginatedLogs PaginatedLogs\n\n// NewPaginatedLogs instantiates a new PaginatedLogs object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPaginatedLogs(items []LogEntry, total float32, page float32, totalPages float32) *PaginatedLogs {\n\tthis := PaginatedLogs{}\n\tthis.Items = items\n\tthis.Total = total\n\tthis.Page = page\n\tthis.TotalPages = totalPages\n\treturn &this\n}\n\n// NewPaginatedLogsWithDefaults instantiates a new PaginatedLogs object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPaginatedLogsWithDefaults() *PaginatedLogs {\n\tthis := PaginatedLogs{}\n\treturn &this\n}\n\n// GetItems returns the Items field value\nfunc (o *PaginatedLogs) GetItems() []LogEntry {\n\tif o == nil {\n\t\tvar ret []LogEntry\n\t\treturn ret\n\t}\n\n\treturn o.Items\n}\n\n// GetItemsOk returns a tuple with the Items field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedLogs) GetItemsOk() ([]LogEntry, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Items, true\n}\n\n// SetItems sets field value\nfunc (o *PaginatedLogs) SetItems(v []LogEntry) {\n\to.Items = v\n}\n\n// GetTotal returns the Total field value\nfunc (o *PaginatedLogs) GetTotal() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Total\n}\n\n// GetTotalOk returns a tuple with the Total field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedLogs) GetTotalOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Total, true\n}\n\n// SetTotal sets field value\nfunc (o *PaginatedLogs) SetTotal(v float32) {\n\to.Total = v\n}\n\n// GetPage returns the Page field value\nfunc (o *PaginatedLogs) GetPage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Page\n}\n\n// GetPageOk returns a tuple with the Page field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedLogs) GetPageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Page, true\n}\n\n// SetPage sets field value\nfunc (o *PaginatedLogs) SetPage(v float32) {\n\to.Page = v\n}\n\n// GetTotalPages returns the TotalPages field value\nfunc (o *PaginatedLogs) GetTotalPages() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalPages\n}\n\n// GetTotalPagesOk returns a tuple with the TotalPages field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedLogs) GetTotalPagesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalPages, true\n}\n\n// SetTotalPages sets field value\nfunc (o *PaginatedLogs) SetTotalPages(v float32) {\n\to.TotalPages = v\n}\n\nfunc (o PaginatedLogs) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PaginatedLogs) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"items\"] = o.Items\n\ttoSerialize[\"total\"] = o.Total\n\ttoSerialize[\"page\"] = o.Page\n\ttoSerialize[\"totalPages\"] = o.TotalPages\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PaginatedLogs) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"items\",\n\t\t\"total\",\n\t\t\"page\",\n\t\t\"totalPages\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPaginatedLogs := _PaginatedLogs{}\n\n\terr = json.Unmarshal(data, &varPaginatedLogs)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PaginatedLogs(varPaginatedLogs)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"items\")\n\t\tdelete(additionalProperties, \"total\")\n\t\tdelete(additionalProperties, \"page\")\n\t\tdelete(additionalProperties, \"totalPages\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePaginatedLogs struct {\n\tvalue *PaginatedLogs\n\tisSet bool\n}\n\nfunc (v NullablePaginatedLogs) Get() *PaginatedLogs {\n\treturn v.value\n}\n\nfunc (v *NullablePaginatedLogs) Set(val *PaginatedLogs) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePaginatedLogs) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePaginatedLogs) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePaginatedLogs(val *PaginatedLogs) *NullablePaginatedLogs {\n\treturn &NullablePaginatedLogs{value: val, isSet: true}\n}\n\nfunc (v NullablePaginatedLogs) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePaginatedLogs) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_paginated_sandboxes.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PaginatedSandboxes type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PaginatedSandboxes{}\n\n// PaginatedSandboxes struct for PaginatedSandboxes\ntype PaginatedSandboxes struct {\n\tItems []Sandbox `json:\"items\"`\n\tTotal float32 `json:\"total\"`\n\tPage float32 `json:\"page\"`\n\tTotalPages float32 `json:\"totalPages\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PaginatedSandboxes PaginatedSandboxes\n\n// NewPaginatedSandboxes instantiates a new PaginatedSandboxes object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPaginatedSandboxes(items []Sandbox, total float32, page float32, totalPages float32) *PaginatedSandboxes {\n\tthis := PaginatedSandboxes{}\n\tthis.Items = items\n\tthis.Total = total\n\tthis.Page = page\n\tthis.TotalPages = totalPages\n\treturn &this\n}\n\n// NewPaginatedSandboxesWithDefaults instantiates a new PaginatedSandboxes object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPaginatedSandboxesWithDefaults() *PaginatedSandboxes {\n\tthis := PaginatedSandboxes{}\n\treturn &this\n}\n\n// GetItems returns the Items field value\nfunc (o *PaginatedSandboxes) GetItems() []Sandbox {\n\tif o == nil {\n\t\tvar ret []Sandbox\n\t\treturn ret\n\t}\n\n\treturn o.Items\n}\n\n// GetItemsOk returns a tuple with the Items field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedSandboxes) GetItemsOk() ([]Sandbox, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Items, true\n}\n\n// SetItems sets field value\nfunc (o *PaginatedSandboxes) SetItems(v []Sandbox) {\n\to.Items = v\n}\n\n// GetTotal returns the Total field value\nfunc (o *PaginatedSandboxes) GetTotal() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Total\n}\n\n// GetTotalOk returns a tuple with the Total field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedSandboxes) GetTotalOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Total, true\n}\n\n// SetTotal sets field value\nfunc (o *PaginatedSandboxes) SetTotal(v float32) {\n\to.Total = v\n}\n\n// GetPage returns the Page field value\nfunc (o *PaginatedSandboxes) GetPage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Page\n}\n\n// GetPageOk returns a tuple with the Page field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedSandboxes) GetPageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Page, true\n}\n\n// SetPage sets field value\nfunc (o *PaginatedSandboxes) SetPage(v float32) {\n\to.Page = v\n}\n\n// GetTotalPages returns the TotalPages field value\nfunc (o *PaginatedSandboxes) GetTotalPages() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalPages\n}\n\n// GetTotalPagesOk returns a tuple with the TotalPages field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedSandboxes) GetTotalPagesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalPages, true\n}\n\n// SetTotalPages sets field value\nfunc (o *PaginatedSandboxes) SetTotalPages(v float32) {\n\to.TotalPages = v\n}\n\nfunc (o PaginatedSandboxes) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PaginatedSandboxes) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"items\"] = o.Items\n\ttoSerialize[\"total\"] = o.Total\n\ttoSerialize[\"page\"] = o.Page\n\ttoSerialize[\"totalPages\"] = o.TotalPages\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PaginatedSandboxes) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"items\",\n\t\t\"total\",\n\t\t\"page\",\n\t\t\"totalPages\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPaginatedSandboxes := _PaginatedSandboxes{}\n\n\terr = json.Unmarshal(data, &varPaginatedSandboxes)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PaginatedSandboxes(varPaginatedSandboxes)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"items\")\n\t\tdelete(additionalProperties, \"total\")\n\t\tdelete(additionalProperties, \"page\")\n\t\tdelete(additionalProperties, \"totalPages\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePaginatedSandboxes struct {\n\tvalue *PaginatedSandboxes\n\tisSet bool\n}\n\nfunc (v NullablePaginatedSandboxes) Get() *PaginatedSandboxes {\n\treturn v.value\n}\n\nfunc (v *NullablePaginatedSandboxes) Set(val *PaginatedSandboxes) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePaginatedSandboxes) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePaginatedSandboxes) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePaginatedSandboxes(val *PaginatedSandboxes) *NullablePaginatedSandboxes {\n\treturn &NullablePaginatedSandboxes{value: val, isSet: true}\n}\n\nfunc (v NullablePaginatedSandboxes) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePaginatedSandboxes) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_paginated_snapshots.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PaginatedSnapshots type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PaginatedSnapshots{}\n\n// PaginatedSnapshots struct for PaginatedSnapshots\ntype PaginatedSnapshots struct {\n\tItems []SnapshotDto `json:\"items\"`\n\tTotal float32 `json:\"total\"`\n\tPage float32 `json:\"page\"`\n\tTotalPages float32 `json:\"totalPages\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PaginatedSnapshots PaginatedSnapshots\n\n// NewPaginatedSnapshots instantiates a new PaginatedSnapshots object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPaginatedSnapshots(items []SnapshotDto, total float32, page float32, totalPages float32) *PaginatedSnapshots {\n\tthis := PaginatedSnapshots{}\n\tthis.Items = items\n\tthis.Total = total\n\tthis.Page = page\n\tthis.TotalPages = totalPages\n\treturn &this\n}\n\n// NewPaginatedSnapshotsWithDefaults instantiates a new PaginatedSnapshots object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPaginatedSnapshotsWithDefaults() *PaginatedSnapshots {\n\tthis := PaginatedSnapshots{}\n\treturn &this\n}\n\n// GetItems returns the Items field value\nfunc (o *PaginatedSnapshots) GetItems() []SnapshotDto {\n\tif o == nil {\n\t\tvar ret []SnapshotDto\n\t\treturn ret\n\t}\n\n\treturn o.Items\n}\n\n// GetItemsOk returns a tuple with the Items field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedSnapshots) GetItemsOk() ([]SnapshotDto, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Items, true\n}\n\n// SetItems sets field value\nfunc (o *PaginatedSnapshots) SetItems(v []SnapshotDto) {\n\to.Items = v\n}\n\n// GetTotal returns the Total field value\nfunc (o *PaginatedSnapshots) GetTotal() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Total\n}\n\n// GetTotalOk returns a tuple with the Total field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedSnapshots) GetTotalOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Total, true\n}\n\n// SetTotal sets field value\nfunc (o *PaginatedSnapshots) SetTotal(v float32) {\n\to.Total = v\n}\n\n// GetPage returns the Page field value\nfunc (o *PaginatedSnapshots) GetPage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Page\n}\n\n// GetPageOk returns a tuple with the Page field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedSnapshots) GetPageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Page, true\n}\n\n// SetPage sets field value\nfunc (o *PaginatedSnapshots) SetPage(v float32) {\n\to.Page = v\n}\n\n// GetTotalPages returns the TotalPages field value\nfunc (o *PaginatedSnapshots) GetTotalPages() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalPages\n}\n\n// GetTotalPagesOk returns a tuple with the TotalPages field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedSnapshots) GetTotalPagesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalPages, true\n}\n\n// SetTotalPages sets field value\nfunc (o *PaginatedSnapshots) SetTotalPages(v float32) {\n\to.TotalPages = v\n}\n\nfunc (o PaginatedSnapshots) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PaginatedSnapshots) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"items\"] = o.Items\n\ttoSerialize[\"total\"] = o.Total\n\ttoSerialize[\"page\"] = o.Page\n\ttoSerialize[\"totalPages\"] = o.TotalPages\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PaginatedSnapshots) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"items\",\n\t\t\"total\",\n\t\t\"page\",\n\t\t\"totalPages\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPaginatedSnapshots := _PaginatedSnapshots{}\n\n\terr = json.Unmarshal(data, &varPaginatedSnapshots)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PaginatedSnapshots(varPaginatedSnapshots)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"items\")\n\t\tdelete(additionalProperties, \"total\")\n\t\tdelete(additionalProperties, \"page\")\n\t\tdelete(additionalProperties, \"totalPages\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePaginatedSnapshots struct {\n\tvalue *PaginatedSnapshots\n\tisSet bool\n}\n\nfunc (v NullablePaginatedSnapshots) Get() *PaginatedSnapshots {\n\treturn v.value\n}\n\nfunc (v *NullablePaginatedSnapshots) Set(val *PaginatedSnapshots) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePaginatedSnapshots) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePaginatedSnapshots) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePaginatedSnapshots(val *PaginatedSnapshots) *NullablePaginatedSnapshots {\n\treturn &NullablePaginatedSnapshots{value: val, isSet: true}\n}\n\nfunc (v NullablePaginatedSnapshots) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePaginatedSnapshots) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_paginated_traces.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PaginatedTraces type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PaginatedTraces{}\n\n// PaginatedTraces struct for PaginatedTraces\ntype PaginatedTraces struct {\n\t// List of trace summaries\n\tItems []TraceSummary `json:\"items\"`\n\t// Total number of traces matching the query\n\tTotal float32 `json:\"total\"`\n\t// Current page number\n\tPage float32 `json:\"page\"`\n\t// Total number of pages\n\tTotalPages float32 `json:\"totalPages\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PaginatedTraces PaginatedTraces\n\n// NewPaginatedTraces instantiates a new PaginatedTraces object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPaginatedTraces(items []TraceSummary, total float32, page float32, totalPages float32) *PaginatedTraces {\n\tthis := PaginatedTraces{}\n\tthis.Items = items\n\tthis.Total = total\n\tthis.Page = page\n\tthis.TotalPages = totalPages\n\treturn &this\n}\n\n// NewPaginatedTracesWithDefaults instantiates a new PaginatedTraces object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPaginatedTracesWithDefaults() *PaginatedTraces {\n\tthis := PaginatedTraces{}\n\treturn &this\n}\n\n// GetItems returns the Items field value\nfunc (o *PaginatedTraces) GetItems() []TraceSummary {\n\tif o == nil {\n\t\tvar ret []TraceSummary\n\t\treturn ret\n\t}\n\n\treturn o.Items\n}\n\n// GetItemsOk returns a tuple with the Items field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedTraces) GetItemsOk() ([]TraceSummary, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Items, true\n}\n\n// SetItems sets field value\nfunc (o *PaginatedTraces) SetItems(v []TraceSummary) {\n\to.Items = v\n}\n\n// GetTotal returns the Total field value\nfunc (o *PaginatedTraces) GetTotal() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Total\n}\n\n// GetTotalOk returns a tuple with the Total field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedTraces) GetTotalOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Total, true\n}\n\n// SetTotal sets field value\nfunc (o *PaginatedTraces) SetTotal(v float32) {\n\to.Total = v\n}\n\n// GetPage returns the Page field value\nfunc (o *PaginatedTraces) GetPage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Page\n}\n\n// GetPageOk returns a tuple with the Page field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedTraces) GetPageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Page, true\n}\n\n// SetPage sets field value\nfunc (o *PaginatedTraces) SetPage(v float32) {\n\to.Page = v\n}\n\n// GetTotalPages returns the TotalPages field value\nfunc (o *PaginatedTraces) GetTotalPages() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalPages\n}\n\n// GetTotalPagesOk returns a tuple with the TotalPages field value\n// and a boolean to check if the value has been set.\nfunc (o *PaginatedTraces) GetTotalPagesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalPages, true\n}\n\n// SetTotalPages sets field value\nfunc (o *PaginatedTraces) SetTotalPages(v float32) {\n\to.TotalPages = v\n}\n\nfunc (o PaginatedTraces) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PaginatedTraces) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"items\"] = o.Items\n\ttoSerialize[\"total\"] = o.Total\n\ttoSerialize[\"page\"] = o.Page\n\ttoSerialize[\"totalPages\"] = o.TotalPages\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PaginatedTraces) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"items\",\n\t\t\"total\",\n\t\t\"page\",\n\t\t\"totalPages\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPaginatedTraces := _PaginatedTraces{}\n\n\terr = json.Unmarshal(data, &varPaginatedTraces)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PaginatedTraces(varPaginatedTraces)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"items\")\n\t\tdelete(additionalProperties, \"total\")\n\t\tdelete(additionalProperties, \"page\")\n\t\tdelete(additionalProperties, \"totalPages\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePaginatedTraces struct {\n\tvalue *PaginatedTraces\n\tisSet bool\n}\n\nfunc (v NullablePaginatedTraces) Get() *PaginatedTraces {\n\treturn v.value\n}\n\nfunc (v *NullablePaginatedTraces) Set(val *PaginatedTraces) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePaginatedTraces) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePaginatedTraces) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePaginatedTraces(val *PaginatedTraces) *NullablePaginatedTraces {\n\treturn &NullablePaginatedTraces{value: val, isSet: true}\n}\n\nfunc (v NullablePaginatedTraces) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePaginatedTraces) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_poll_jobs_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PollJobsResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PollJobsResponse{}\n\n// PollJobsResponse struct for PollJobsResponse\ntype PollJobsResponse struct {\n\t// List of jobs\n\tJobs []Job `json:\"jobs\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PollJobsResponse PollJobsResponse\n\n// NewPollJobsResponse instantiates a new PollJobsResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPollJobsResponse(jobs []Job) *PollJobsResponse {\n\tthis := PollJobsResponse{}\n\tthis.Jobs = jobs\n\treturn &this\n}\n\n// NewPollJobsResponseWithDefaults instantiates a new PollJobsResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPollJobsResponseWithDefaults() *PollJobsResponse {\n\tthis := PollJobsResponse{}\n\treturn &this\n}\n\n// GetJobs returns the Jobs field value\nfunc (o *PollJobsResponse) GetJobs() []Job {\n\tif o == nil {\n\t\tvar ret []Job\n\t\treturn ret\n\t}\n\n\treturn o.Jobs\n}\n\n// GetJobsOk returns a tuple with the Jobs field value\n// and a boolean to check if the value has been set.\nfunc (o *PollJobsResponse) GetJobsOk() ([]Job, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Jobs, true\n}\n\n// SetJobs sets field value\nfunc (o *PollJobsResponse) SetJobs(v []Job) {\n\to.Jobs = v\n}\n\nfunc (o PollJobsResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PollJobsResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"jobs\"] = o.Jobs\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PollJobsResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"jobs\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPollJobsResponse := _PollJobsResponse{}\n\n\terr = json.Unmarshal(data, &varPollJobsResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PollJobsResponse(varPollJobsResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"jobs\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePollJobsResponse struct {\n\tvalue *PollJobsResponse\n\tisSet bool\n}\n\nfunc (v NullablePollJobsResponse) Get() *PollJobsResponse {\n\treturn v.value\n}\n\nfunc (v *NullablePollJobsResponse) Set(val *PollJobsResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePollJobsResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePollJobsResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePollJobsResponse(val *PollJobsResponse) *NullablePollJobsResponse {\n\treturn &NullablePollJobsResponse{value: val, isSet: true}\n}\n\nfunc (v NullablePollJobsResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePollJobsResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_port_preview_url.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PortPreviewUrl type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PortPreviewUrl{}\n\n// PortPreviewUrl struct for PortPreviewUrl\ntype PortPreviewUrl struct {\n\t// ID of the sandbox\n\tSandboxId string `json:\"sandboxId\"`\n\t// Preview url\n\tUrl string `json:\"url\"`\n\t// Access token\n\tToken string `json:\"token\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PortPreviewUrl PortPreviewUrl\n\n// NewPortPreviewUrl instantiates a new PortPreviewUrl object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPortPreviewUrl(sandboxId string, url string, token string) *PortPreviewUrl {\n\tthis := PortPreviewUrl{}\n\tthis.SandboxId = sandboxId\n\tthis.Url = url\n\tthis.Token = token\n\treturn &this\n}\n\n// NewPortPreviewUrlWithDefaults instantiates a new PortPreviewUrl object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPortPreviewUrlWithDefaults() *PortPreviewUrl {\n\tthis := PortPreviewUrl{}\n\treturn &this\n}\n\n// GetSandboxId returns the SandboxId field value\nfunc (o *PortPreviewUrl) GetSandboxId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SandboxId\n}\n\n// GetSandboxIdOk returns a tuple with the SandboxId field value\n// and a boolean to check if the value has been set.\nfunc (o *PortPreviewUrl) GetSandboxIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SandboxId, true\n}\n\n// SetSandboxId sets field value\nfunc (o *PortPreviewUrl) SetSandboxId(v string) {\n\to.SandboxId = v\n}\n\n// GetUrl returns the Url field value\nfunc (o *PortPreviewUrl) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *PortPreviewUrl) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *PortPreviewUrl) SetUrl(v string) {\n\to.Url = v\n}\n\n// GetToken returns the Token field value\nfunc (o *PortPreviewUrl) GetToken() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Token\n}\n\n// GetTokenOk returns a tuple with the Token field value\n// and a boolean to check if the value has been set.\nfunc (o *PortPreviewUrl) GetTokenOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Token, true\n}\n\n// SetToken sets field value\nfunc (o *PortPreviewUrl) SetToken(v string) {\n\to.Token = v\n}\n\nfunc (o PortPreviewUrl) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PortPreviewUrl) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"sandboxId\"] = o.SandboxId\n\ttoSerialize[\"url\"] = o.Url\n\ttoSerialize[\"token\"] = o.Token\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PortPreviewUrl) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"sandboxId\",\n\t\t\"url\",\n\t\t\"token\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPortPreviewUrl := _PortPreviewUrl{}\n\n\terr = json.Unmarshal(data, &varPortPreviewUrl)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PortPreviewUrl(varPortPreviewUrl)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"sandboxId\")\n\t\tdelete(additionalProperties, \"url\")\n\t\tdelete(additionalProperties, \"token\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePortPreviewUrl struct {\n\tvalue *PortPreviewUrl\n\tisSet bool\n}\n\nfunc (v NullablePortPreviewUrl) Get() *PortPreviewUrl {\n\treturn v.value\n}\n\nfunc (v *NullablePortPreviewUrl) Set(val *PortPreviewUrl) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePortPreviewUrl) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePortPreviewUrl) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePortPreviewUrl(val *PortPreviewUrl) *NullablePortPreviewUrl {\n\treturn &NullablePortPreviewUrl{value: val, isSet: true}\n}\n\nfunc (v NullablePortPreviewUrl) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePortPreviewUrl) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_position.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Position type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Position{}\n\n// Position struct for Position\ntype Position struct {\n\tLine float32 `json:\"line\"`\n\tCharacter float32 `json:\"character\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Position Position\n\n// NewPosition instantiates a new Position object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPosition(line float32, character float32) *Position {\n\tthis := Position{}\n\tthis.Line = line\n\tthis.Character = character\n\treturn &this\n}\n\n// NewPositionWithDefaults instantiates a new Position object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPositionWithDefaults() *Position {\n\tthis := Position{}\n\treturn &this\n}\n\n// GetLine returns the Line field value\nfunc (o *Position) GetLine() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Line\n}\n\n// GetLineOk returns a tuple with the Line field value\n// and a boolean to check if the value has been set.\nfunc (o *Position) GetLineOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Line, true\n}\n\n// SetLine sets field value\nfunc (o *Position) SetLine(v float32) {\n\to.Line = v\n}\n\n// GetCharacter returns the Character field value\nfunc (o *Position) GetCharacter() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Character\n}\n\n// GetCharacterOk returns a tuple with the Character field value\n// and a boolean to check if the value has been set.\nfunc (o *Position) GetCharacterOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Character, true\n}\n\n// SetCharacter sets field value\nfunc (o *Position) SetCharacter(v float32) {\n\to.Character = v\n}\n\nfunc (o Position) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Position) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"line\"] = o.Line\n\ttoSerialize[\"character\"] = o.Character\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Position) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"line\",\n\t\t\"character\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPosition := _Position{}\n\n\terr = json.Unmarshal(data, &varPosition)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Position(varPosition)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"line\")\n\t\tdelete(additionalProperties, \"character\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePosition struct {\n\tvalue *Position\n\tisSet bool\n}\n\nfunc (v NullablePosition) Get() *Position {\n\treturn v.value\n}\n\nfunc (v *NullablePosition) Set(val *Position) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePosition) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePosition) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePosition(val *Position) *NullablePosition {\n\treturn &NullablePosition{value: val, isSet: true}\n}\n\nfunc (v NullablePosition) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePosition) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_posthog_config.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PosthogConfig type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PosthogConfig{}\n\n// PosthogConfig struct for PosthogConfig\ntype PosthogConfig struct {\n\t// PostHog API key\n\tApiKey string `json:\"apiKey\"`\n\t// PostHog host URL\n\tHost string `json:\"host\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PosthogConfig PosthogConfig\n\n// NewPosthogConfig instantiates a new PosthogConfig object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPosthogConfig(apiKey string, host string) *PosthogConfig {\n\tthis := PosthogConfig{}\n\tthis.ApiKey = apiKey\n\tthis.Host = host\n\treturn &this\n}\n\n// NewPosthogConfigWithDefaults instantiates a new PosthogConfig object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPosthogConfigWithDefaults() *PosthogConfig {\n\tthis := PosthogConfig{}\n\treturn &this\n}\n\n// GetApiKey returns the ApiKey field value\nfunc (o *PosthogConfig) GetApiKey() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ApiKey\n}\n\n// GetApiKeyOk returns a tuple with the ApiKey field value\n// and a boolean to check if the value has been set.\nfunc (o *PosthogConfig) GetApiKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ApiKey, true\n}\n\n// SetApiKey sets field value\nfunc (o *PosthogConfig) SetApiKey(v string) {\n\to.ApiKey = v\n}\n\n// GetHost returns the Host field value\nfunc (o *PosthogConfig) GetHost() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Host\n}\n\n// GetHostOk returns a tuple with the Host field value\n// and a boolean to check if the value has been set.\nfunc (o *PosthogConfig) GetHostOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Host, true\n}\n\n// SetHost sets field value\nfunc (o *PosthogConfig) SetHost(v string) {\n\to.Host = v\n}\n\nfunc (o PosthogConfig) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PosthogConfig) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"apiKey\"] = o.ApiKey\n\ttoSerialize[\"host\"] = o.Host\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PosthogConfig) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"apiKey\",\n\t\t\"host\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPosthogConfig := _PosthogConfig{}\n\n\terr = json.Unmarshal(data, &varPosthogConfig)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PosthogConfig(varPosthogConfig)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"apiKey\")\n\t\tdelete(additionalProperties, \"host\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePosthogConfig struct {\n\tvalue *PosthogConfig\n\tisSet bool\n}\n\nfunc (v NullablePosthogConfig) Get() *PosthogConfig {\n\treturn v.value\n}\n\nfunc (v *NullablePosthogConfig) Set(val *PosthogConfig) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePosthogConfig) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePosthogConfig) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePosthogConfig(val *PosthogConfig) *NullablePosthogConfig {\n\treturn &NullablePosthogConfig{value: val, isSet: true}\n}\n\nfunc (v NullablePosthogConfig) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePosthogConfig) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_process_errors_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ProcessErrorsResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ProcessErrorsResponse{}\n\n// ProcessErrorsResponse struct for ProcessErrorsResponse\ntype ProcessErrorsResponse struct {\n\t// The name of the VNC process whose error logs were retrieved\n\tProcessName string `json:\"processName\"`\n\t// The error log output from the specified VNC process\n\tErrors string `json:\"errors\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ProcessErrorsResponse ProcessErrorsResponse\n\n// NewProcessErrorsResponse instantiates a new ProcessErrorsResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewProcessErrorsResponse(processName string, errors string) *ProcessErrorsResponse {\n\tthis := ProcessErrorsResponse{}\n\tthis.ProcessName = processName\n\tthis.Errors = errors\n\treturn &this\n}\n\n// NewProcessErrorsResponseWithDefaults instantiates a new ProcessErrorsResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewProcessErrorsResponseWithDefaults() *ProcessErrorsResponse {\n\tthis := ProcessErrorsResponse{}\n\treturn &this\n}\n\n// GetProcessName returns the ProcessName field value\nfunc (o *ProcessErrorsResponse) GetProcessName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ProcessName\n}\n\n// GetProcessNameOk returns a tuple with the ProcessName field value\n// and a boolean to check if the value has been set.\nfunc (o *ProcessErrorsResponse) GetProcessNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ProcessName, true\n}\n\n// SetProcessName sets field value\nfunc (o *ProcessErrorsResponse) SetProcessName(v string) {\n\to.ProcessName = v\n}\n\n// GetErrors returns the Errors field value\nfunc (o *ProcessErrorsResponse) GetErrors() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Errors\n}\n\n// GetErrorsOk returns a tuple with the Errors field value\n// and a boolean to check if the value has been set.\nfunc (o *ProcessErrorsResponse) GetErrorsOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Errors, true\n}\n\n// SetErrors sets field value\nfunc (o *ProcessErrorsResponse) SetErrors(v string) {\n\to.Errors = v\n}\n\nfunc (o ProcessErrorsResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ProcessErrorsResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"processName\"] = o.ProcessName\n\ttoSerialize[\"errors\"] = o.Errors\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ProcessErrorsResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"processName\",\n\t\t\"errors\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarProcessErrorsResponse := _ProcessErrorsResponse{}\n\n\terr = json.Unmarshal(data, &varProcessErrorsResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ProcessErrorsResponse(varProcessErrorsResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"processName\")\n\t\tdelete(additionalProperties, \"errors\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableProcessErrorsResponse struct {\n\tvalue *ProcessErrorsResponse\n\tisSet bool\n}\n\nfunc (v NullableProcessErrorsResponse) Get() *ProcessErrorsResponse {\n\treturn v.value\n}\n\nfunc (v *NullableProcessErrorsResponse) Set(val *ProcessErrorsResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableProcessErrorsResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableProcessErrorsResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableProcessErrorsResponse(val *ProcessErrorsResponse) *NullableProcessErrorsResponse {\n\treturn &NullableProcessErrorsResponse{value: val, isSet: true}\n}\n\nfunc (v NullableProcessErrorsResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableProcessErrorsResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_process_logs_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ProcessLogsResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ProcessLogsResponse{}\n\n// ProcessLogsResponse struct for ProcessLogsResponse\ntype ProcessLogsResponse struct {\n\t// The name of the VNC process whose logs were retrieved\n\tProcessName string `json:\"processName\"`\n\t// The log output from the specified VNC process\n\tLogs string `json:\"logs\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ProcessLogsResponse ProcessLogsResponse\n\n// NewProcessLogsResponse instantiates a new ProcessLogsResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewProcessLogsResponse(processName string, logs string) *ProcessLogsResponse {\n\tthis := ProcessLogsResponse{}\n\tthis.ProcessName = processName\n\tthis.Logs = logs\n\treturn &this\n}\n\n// NewProcessLogsResponseWithDefaults instantiates a new ProcessLogsResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewProcessLogsResponseWithDefaults() *ProcessLogsResponse {\n\tthis := ProcessLogsResponse{}\n\treturn &this\n}\n\n// GetProcessName returns the ProcessName field value\nfunc (o *ProcessLogsResponse) GetProcessName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ProcessName\n}\n\n// GetProcessNameOk returns a tuple with the ProcessName field value\n// and a boolean to check if the value has been set.\nfunc (o *ProcessLogsResponse) GetProcessNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ProcessName, true\n}\n\n// SetProcessName sets field value\nfunc (o *ProcessLogsResponse) SetProcessName(v string) {\n\to.ProcessName = v\n}\n\n// GetLogs returns the Logs field value\nfunc (o *ProcessLogsResponse) GetLogs() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Logs\n}\n\n// GetLogsOk returns a tuple with the Logs field value\n// and a boolean to check if the value has been set.\nfunc (o *ProcessLogsResponse) GetLogsOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Logs, true\n}\n\n// SetLogs sets field value\nfunc (o *ProcessLogsResponse) SetLogs(v string) {\n\to.Logs = v\n}\n\nfunc (o ProcessLogsResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ProcessLogsResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"processName\"] = o.ProcessName\n\ttoSerialize[\"logs\"] = o.Logs\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ProcessLogsResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"processName\",\n\t\t\"logs\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarProcessLogsResponse := _ProcessLogsResponse{}\n\n\terr = json.Unmarshal(data, &varProcessLogsResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ProcessLogsResponse(varProcessLogsResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"processName\")\n\t\tdelete(additionalProperties, \"logs\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableProcessLogsResponse struct {\n\tvalue *ProcessLogsResponse\n\tisSet bool\n}\n\nfunc (v NullableProcessLogsResponse) Get() *ProcessLogsResponse {\n\treturn v.value\n}\n\nfunc (v *NullableProcessLogsResponse) Set(val *ProcessLogsResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableProcessLogsResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableProcessLogsResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableProcessLogsResponse(val *ProcessLogsResponse) *NullableProcessLogsResponse {\n\treturn &NullableProcessLogsResponse{value: val, isSet: true}\n}\n\nfunc (v NullableProcessLogsResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableProcessLogsResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_process_restart_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ProcessRestartResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ProcessRestartResponse{}\n\n// ProcessRestartResponse struct for ProcessRestartResponse\ntype ProcessRestartResponse struct {\n\t// A message indicating the result of restarting the process\n\tMessage string `json:\"message\"`\n\t// The name of the VNC process that was restarted\n\tProcessName string `json:\"processName\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ProcessRestartResponse ProcessRestartResponse\n\n// NewProcessRestartResponse instantiates a new ProcessRestartResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewProcessRestartResponse(message string, processName string) *ProcessRestartResponse {\n\tthis := ProcessRestartResponse{}\n\tthis.Message = message\n\tthis.ProcessName = processName\n\treturn &this\n}\n\n// NewProcessRestartResponseWithDefaults instantiates a new ProcessRestartResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewProcessRestartResponseWithDefaults() *ProcessRestartResponse {\n\tthis := ProcessRestartResponse{}\n\treturn &this\n}\n\n// GetMessage returns the Message field value\nfunc (o *ProcessRestartResponse) GetMessage() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Message\n}\n\n// GetMessageOk returns a tuple with the Message field value\n// and a boolean to check if the value has been set.\nfunc (o *ProcessRestartResponse) GetMessageOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Message, true\n}\n\n// SetMessage sets field value\nfunc (o *ProcessRestartResponse) SetMessage(v string) {\n\to.Message = v\n}\n\n// GetProcessName returns the ProcessName field value\nfunc (o *ProcessRestartResponse) GetProcessName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ProcessName\n}\n\n// GetProcessNameOk returns a tuple with the ProcessName field value\n// and a boolean to check if the value has been set.\nfunc (o *ProcessRestartResponse) GetProcessNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ProcessName, true\n}\n\n// SetProcessName sets field value\nfunc (o *ProcessRestartResponse) SetProcessName(v string) {\n\to.ProcessName = v\n}\n\nfunc (o ProcessRestartResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ProcessRestartResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"message\"] = o.Message\n\ttoSerialize[\"processName\"] = o.ProcessName\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ProcessRestartResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"message\",\n\t\t\"processName\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarProcessRestartResponse := _ProcessRestartResponse{}\n\n\terr = json.Unmarshal(data, &varProcessRestartResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ProcessRestartResponse(varProcessRestartResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"message\")\n\t\tdelete(additionalProperties, \"processName\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableProcessRestartResponse struct {\n\tvalue *ProcessRestartResponse\n\tisSet bool\n}\n\nfunc (v NullableProcessRestartResponse) Get() *ProcessRestartResponse {\n\treturn v.value\n}\n\nfunc (v *NullableProcessRestartResponse) Set(val *ProcessRestartResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableProcessRestartResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableProcessRestartResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableProcessRestartResponse(val *ProcessRestartResponse) *NullableProcessRestartResponse {\n\treturn &NullableProcessRestartResponse{value: val, isSet: true}\n}\n\nfunc (v NullableProcessRestartResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableProcessRestartResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_process_status_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ProcessStatusResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ProcessStatusResponse{}\n\n// ProcessStatusResponse struct for ProcessStatusResponse\ntype ProcessStatusResponse struct {\n\t// The name of the VNC process being checked\n\tProcessName string `json:\"processName\"`\n\t// Whether the specified VNC process is currently running\n\tRunning bool `json:\"running\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ProcessStatusResponse ProcessStatusResponse\n\n// NewProcessStatusResponse instantiates a new ProcessStatusResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewProcessStatusResponse(processName string, running bool) *ProcessStatusResponse {\n\tthis := ProcessStatusResponse{}\n\tthis.ProcessName = processName\n\tthis.Running = running\n\treturn &this\n}\n\n// NewProcessStatusResponseWithDefaults instantiates a new ProcessStatusResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewProcessStatusResponseWithDefaults() *ProcessStatusResponse {\n\tthis := ProcessStatusResponse{}\n\treturn &this\n}\n\n// GetProcessName returns the ProcessName field value\nfunc (o *ProcessStatusResponse) GetProcessName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ProcessName\n}\n\n// GetProcessNameOk returns a tuple with the ProcessName field value\n// and a boolean to check if the value has been set.\nfunc (o *ProcessStatusResponse) GetProcessNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ProcessName, true\n}\n\n// SetProcessName sets field value\nfunc (o *ProcessStatusResponse) SetProcessName(v string) {\n\to.ProcessName = v\n}\n\n// GetRunning returns the Running field value\nfunc (o *ProcessStatusResponse) GetRunning() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Running\n}\n\n// GetRunningOk returns a tuple with the Running field value\n// and a boolean to check if the value has been set.\nfunc (o *ProcessStatusResponse) GetRunningOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Running, true\n}\n\n// SetRunning sets field value\nfunc (o *ProcessStatusResponse) SetRunning(v bool) {\n\to.Running = v\n}\n\nfunc (o ProcessStatusResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ProcessStatusResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"processName\"] = o.ProcessName\n\ttoSerialize[\"running\"] = o.Running\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ProcessStatusResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"processName\",\n\t\t\"running\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarProcessStatusResponse := _ProcessStatusResponse{}\n\n\terr = json.Unmarshal(data, &varProcessStatusResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ProcessStatusResponse(varProcessStatusResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"processName\")\n\t\tdelete(additionalProperties, \"running\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableProcessStatusResponse struct {\n\tvalue *ProcessStatusResponse\n\tisSet bool\n}\n\nfunc (v NullableProcessStatusResponse) Get() *ProcessStatusResponse {\n\treturn v.value\n}\n\nfunc (v *NullableProcessStatusResponse) Set(val *ProcessStatusResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableProcessStatusResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableProcessStatusResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableProcessStatusResponse(val *ProcessStatusResponse) *NullableProcessStatusResponse {\n\treturn &NullableProcessStatusResponse{value: val, isSet: true}\n}\n\nfunc (v NullableProcessStatusResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableProcessStatusResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_project_dir_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the ProjectDirResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ProjectDirResponse{}\n\n// ProjectDirResponse struct for ProjectDirResponse\ntype ProjectDirResponse struct {\n\tDir *string `json:\"dir,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ProjectDirResponse ProjectDirResponse\n\n// NewProjectDirResponse instantiates a new ProjectDirResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewProjectDirResponse() *ProjectDirResponse {\n\tthis := ProjectDirResponse{}\n\treturn &this\n}\n\n// NewProjectDirResponseWithDefaults instantiates a new ProjectDirResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewProjectDirResponseWithDefaults() *ProjectDirResponse {\n\tthis := ProjectDirResponse{}\n\treturn &this\n}\n\n// GetDir returns the Dir field value if set, zero value otherwise.\nfunc (o *ProjectDirResponse) GetDir() string {\n\tif o == nil || IsNil(o.Dir) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Dir\n}\n\n// GetDirOk returns a tuple with the Dir field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ProjectDirResponse) GetDirOk() (*string, bool) {\n\tif o == nil || IsNil(o.Dir) {\n\t\treturn nil, false\n\t}\n\treturn o.Dir, true\n}\n\n// HasDir returns a boolean if a field has been set.\nfunc (o *ProjectDirResponse) HasDir() bool {\n\tif o != nil && !IsNil(o.Dir) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDir gets a reference to the given string and assigns it to the Dir field.\nfunc (o *ProjectDirResponse) SetDir(v string) {\n\to.Dir = &v\n}\n\nfunc (o ProjectDirResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ProjectDirResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Dir) {\n\t\ttoSerialize[\"dir\"] = o.Dir\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ProjectDirResponse) UnmarshalJSON(data []byte) (err error) {\n\tvarProjectDirResponse := _ProjectDirResponse{}\n\n\terr = json.Unmarshal(data, &varProjectDirResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ProjectDirResponse(varProjectDirResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"dir\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableProjectDirResponse struct {\n\tvalue *ProjectDirResponse\n\tisSet bool\n}\n\nfunc (v NullableProjectDirResponse) Get() *ProjectDirResponse {\n\treturn v.value\n}\n\nfunc (v *NullableProjectDirResponse) Set(val *ProjectDirResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableProjectDirResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableProjectDirResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableProjectDirResponse(val *ProjectDirResponse) *NullableProjectDirResponse {\n\treturn &NullableProjectDirResponse{value: val, isSet: true}\n}\n\nfunc (v NullableProjectDirResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableProjectDirResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_pty_create_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PtyCreateRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PtyCreateRequest{}\n\n// PtyCreateRequest struct for PtyCreateRequest\ntype PtyCreateRequest struct {\n\t// The unique identifier for the PTY session\n\tId string `json:\"id\"`\n\t// Starting directory for the PTY session, defaults to the sandbox's working directory\n\tCwd *string `json:\"cwd,omitempty\"`\n\t// Environment variables for the PTY session\n\tEnvs map[string]interface{} `json:\"envs,omitempty\"`\n\t// Number of terminal columns\n\tCols *float32 `json:\"cols,omitempty\"`\n\t// Number of terminal rows\n\tRows *float32 `json:\"rows,omitempty\"`\n\t// Whether to start the PTY session lazily (only start when first client connects)\n\tLazyStart *bool `json:\"lazyStart,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PtyCreateRequest PtyCreateRequest\n\n// NewPtyCreateRequest instantiates a new PtyCreateRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPtyCreateRequest(id string) *PtyCreateRequest {\n\tthis := PtyCreateRequest{}\n\tthis.Id = id\n\tvar lazyStart bool = false\n\tthis.LazyStart = &lazyStart\n\treturn &this\n}\n\n// NewPtyCreateRequestWithDefaults instantiates a new PtyCreateRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPtyCreateRequestWithDefaults() *PtyCreateRequest {\n\tthis := PtyCreateRequest{}\n\tvar lazyStart bool = false\n\tthis.LazyStart = &lazyStart\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *PtyCreateRequest) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *PtyCreateRequest) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *PtyCreateRequest) SetId(v string) {\n\to.Id = v\n}\n\n// GetCwd returns the Cwd field value if set, zero value otherwise.\nfunc (o *PtyCreateRequest) GetCwd() string {\n\tif o == nil || IsNil(o.Cwd) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Cwd\n}\n\n// GetCwdOk returns a tuple with the Cwd field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *PtyCreateRequest) GetCwdOk() (*string, bool) {\n\tif o == nil || IsNil(o.Cwd) {\n\t\treturn nil, false\n\t}\n\treturn o.Cwd, true\n}\n\n// HasCwd returns a boolean if a field has been set.\nfunc (o *PtyCreateRequest) HasCwd() bool {\n\tif o != nil && !IsNil(o.Cwd) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCwd gets a reference to the given string and assigns it to the Cwd field.\nfunc (o *PtyCreateRequest) SetCwd(v string) {\n\to.Cwd = &v\n}\n\n// GetEnvs returns the Envs field value if set, zero value otherwise.\nfunc (o *PtyCreateRequest) GetEnvs() map[string]interface{} {\n\tif o == nil || IsNil(o.Envs) {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\treturn o.Envs\n}\n\n// GetEnvsOk returns a tuple with the Envs field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *PtyCreateRequest) GetEnvsOk() (map[string]interface{}, bool) {\n\tif o == nil || IsNil(o.Envs) {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.Envs, true\n}\n\n// HasEnvs returns a boolean if a field has been set.\nfunc (o *PtyCreateRequest) HasEnvs() bool {\n\tif o != nil && !IsNil(o.Envs) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetEnvs gets a reference to the given map[string]interface{} and assigns it to the Envs field.\nfunc (o *PtyCreateRequest) SetEnvs(v map[string]interface{}) {\n\to.Envs = v\n}\n\n// GetCols returns the Cols field value if set, zero value otherwise.\nfunc (o *PtyCreateRequest) GetCols() float32 {\n\tif o == nil || IsNil(o.Cols) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Cols\n}\n\n// GetColsOk returns a tuple with the Cols field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *PtyCreateRequest) GetColsOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Cols) {\n\t\treturn nil, false\n\t}\n\treturn o.Cols, true\n}\n\n// HasCols returns a boolean if a field has been set.\nfunc (o *PtyCreateRequest) HasCols() bool {\n\tif o != nil && !IsNil(o.Cols) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCols gets a reference to the given float32 and assigns it to the Cols field.\nfunc (o *PtyCreateRequest) SetCols(v float32) {\n\to.Cols = &v\n}\n\n// GetRows returns the Rows field value if set, zero value otherwise.\nfunc (o *PtyCreateRequest) GetRows() float32 {\n\tif o == nil || IsNil(o.Rows) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Rows\n}\n\n// GetRowsOk returns a tuple with the Rows field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *PtyCreateRequest) GetRowsOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Rows) {\n\t\treturn nil, false\n\t}\n\treturn o.Rows, true\n}\n\n// HasRows returns a boolean if a field has been set.\nfunc (o *PtyCreateRequest) HasRows() bool {\n\tif o != nil && !IsNil(o.Rows) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRows gets a reference to the given float32 and assigns it to the Rows field.\nfunc (o *PtyCreateRequest) SetRows(v float32) {\n\to.Rows = &v\n}\n\n// GetLazyStart returns the LazyStart field value if set, zero value otherwise.\nfunc (o *PtyCreateRequest) GetLazyStart() bool {\n\tif o == nil || IsNil(o.LazyStart) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.LazyStart\n}\n\n// GetLazyStartOk returns a tuple with the LazyStart field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *PtyCreateRequest) GetLazyStartOk() (*bool, bool) {\n\tif o == nil || IsNil(o.LazyStart) {\n\t\treturn nil, false\n\t}\n\treturn o.LazyStart, true\n}\n\n// HasLazyStart returns a boolean if a field has been set.\nfunc (o *PtyCreateRequest) HasLazyStart() bool {\n\tif o != nil && !IsNil(o.LazyStart) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetLazyStart gets a reference to the given bool and assigns it to the LazyStart field.\nfunc (o *PtyCreateRequest) SetLazyStart(v bool) {\n\to.LazyStart = &v\n}\n\nfunc (o PtyCreateRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PtyCreateRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\tif !IsNil(o.Cwd) {\n\t\ttoSerialize[\"cwd\"] = o.Cwd\n\t}\n\tif !IsNil(o.Envs) {\n\t\ttoSerialize[\"envs\"] = o.Envs\n\t}\n\tif !IsNil(o.Cols) {\n\t\ttoSerialize[\"cols\"] = o.Cols\n\t}\n\tif !IsNil(o.Rows) {\n\t\ttoSerialize[\"rows\"] = o.Rows\n\t}\n\tif !IsNil(o.LazyStart) {\n\t\ttoSerialize[\"lazyStart\"] = o.LazyStart\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PtyCreateRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPtyCreateRequest := _PtyCreateRequest{}\n\n\terr = json.Unmarshal(data, &varPtyCreateRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PtyCreateRequest(varPtyCreateRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"cwd\")\n\t\tdelete(additionalProperties, \"envs\")\n\t\tdelete(additionalProperties, \"cols\")\n\t\tdelete(additionalProperties, \"rows\")\n\t\tdelete(additionalProperties, \"lazyStart\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePtyCreateRequest struct {\n\tvalue *PtyCreateRequest\n\tisSet bool\n}\n\nfunc (v NullablePtyCreateRequest) Get() *PtyCreateRequest {\n\treturn v.value\n}\n\nfunc (v *NullablePtyCreateRequest) Set(val *PtyCreateRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePtyCreateRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePtyCreateRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePtyCreateRequest(val *PtyCreateRequest) *NullablePtyCreateRequest {\n\treturn &NullablePtyCreateRequest{value: val, isSet: true}\n}\n\nfunc (v NullablePtyCreateRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePtyCreateRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_pty_create_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PtyCreateResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PtyCreateResponse{}\n\n// PtyCreateResponse struct for PtyCreateResponse\ntype PtyCreateResponse struct {\n\t// The unique identifier for the created PTY session\n\tSessionId string `json:\"sessionId\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PtyCreateResponse PtyCreateResponse\n\n// NewPtyCreateResponse instantiates a new PtyCreateResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPtyCreateResponse(sessionId string) *PtyCreateResponse {\n\tthis := PtyCreateResponse{}\n\tthis.SessionId = sessionId\n\treturn &this\n}\n\n// NewPtyCreateResponseWithDefaults instantiates a new PtyCreateResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPtyCreateResponseWithDefaults() *PtyCreateResponse {\n\tthis := PtyCreateResponse{}\n\treturn &this\n}\n\n// GetSessionId returns the SessionId field value\nfunc (o *PtyCreateResponse) GetSessionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SessionId\n}\n\n// GetSessionIdOk returns a tuple with the SessionId field value\n// and a boolean to check if the value has been set.\nfunc (o *PtyCreateResponse) GetSessionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SessionId, true\n}\n\n// SetSessionId sets field value\nfunc (o *PtyCreateResponse) SetSessionId(v string) {\n\to.SessionId = v\n}\n\nfunc (o PtyCreateResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PtyCreateResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"sessionId\"] = o.SessionId\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PtyCreateResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"sessionId\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPtyCreateResponse := _PtyCreateResponse{}\n\n\terr = json.Unmarshal(data, &varPtyCreateResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PtyCreateResponse(varPtyCreateResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"sessionId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePtyCreateResponse struct {\n\tvalue *PtyCreateResponse\n\tisSet bool\n}\n\nfunc (v NullablePtyCreateResponse) Get() *PtyCreateResponse {\n\treturn v.value\n}\n\nfunc (v *NullablePtyCreateResponse) Set(val *PtyCreateResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePtyCreateResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePtyCreateResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePtyCreateResponse(val *PtyCreateResponse) *NullablePtyCreateResponse {\n\treturn &NullablePtyCreateResponse{value: val, isSet: true}\n}\n\nfunc (v NullablePtyCreateResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePtyCreateResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_pty_list_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PtyListResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PtyListResponse{}\n\n// PtyListResponse struct for PtyListResponse\ntype PtyListResponse struct {\n\t// List of active PTY sessions\n\tSessions []PtySessionInfo `json:\"sessions\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PtyListResponse PtyListResponse\n\n// NewPtyListResponse instantiates a new PtyListResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPtyListResponse(sessions []PtySessionInfo) *PtyListResponse {\n\tthis := PtyListResponse{}\n\tthis.Sessions = sessions\n\treturn &this\n}\n\n// NewPtyListResponseWithDefaults instantiates a new PtyListResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPtyListResponseWithDefaults() *PtyListResponse {\n\tthis := PtyListResponse{}\n\treturn &this\n}\n\n// GetSessions returns the Sessions field value\nfunc (o *PtyListResponse) GetSessions() []PtySessionInfo {\n\tif o == nil {\n\t\tvar ret []PtySessionInfo\n\t\treturn ret\n\t}\n\n\treturn o.Sessions\n}\n\n// GetSessionsOk returns a tuple with the Sessions field value\n// and a boolean to check if the value has been set.\nfunc (o *PtyListResponse) GetSessionsOk() ([]PtySessionInfo, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Sessions, true\n}\n\n// SetSessions sets field value\nfunc (o *PtyListResponse) SetSessions(v []PtySessionInfo) {\n\to.Sessions = v\n}\n\nfunc (o PtyListResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PtyListResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"sessions\"] = o.Sessions\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PtyListResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"sessions\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPtyListResponse := _PtyListResponse{}\n\n\terr = json.Unmarshal(data, &varPtyListResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PtyListResponse(varPtyListResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"sessions\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePtyListResponse struct {\n\tvalue *PtyListResponse\n\tisSet bool\n}\n\nfunc (v NullablePtyListResponse) Get() *PtyListResponse {\n\treturn v.value\n}\n\nfunc (v *NullablePtyListResponse) Set(val *PtyListResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePtyListResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePtyListResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePtyListResponse(val *PtyListResponse) *NullablePtyListResponse {\n\treturn &NullablePtyListResponse{value: val, isSet: true}\n}\n\nfunc (v NullablePtyListResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePtyListResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_pty_resize_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PtyResizeRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PtyResizeRequest{}\n\n// PtyResizeRequest struct for PtyResizeRequest\ntype PtyResizeRequest struct {\n\t// Number of terminal columns\n\tCols float32 `json:\"cols\"`\n\t// Number of terminal rows\n\tRows float32 `json:\"rows\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PtyResizeRequest PtyResizeRequest\n\n// NewPtyResizeRequest instantiates a new PtyResizeRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPtyResizeRequest(cols float32, rows float32) *PtyResizeRequest {\n\tthis := PtyResizeRequest{}\n\tthis.Cols = cols\n\tthis.Rows = rows\n\treturn &this\n}\n\n// NewPtyResizeRequestWithDefaults instantiates a new PtyResizeRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPtyResizeRequestWithDefaults() *PtyResizeRequest {\n\tthis := PtyResizeRequest{}\n\treturn &this\n}\n\n// GetCols returns the Cols field value\nfunc (o *PtyResizeRequest) GetCols() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Cols\n}\n\n// GetColsOk returns a tuple with the Cols field value\n// and a boolean to check if the value has been set.\nfunc (o *PtyResizeRequest) GetColsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cols, true\n}\n\n// SetCols sets field value\nfunc (o *PtyResizeRequest) SetCols(v float32) {\n\to.Cols = v\n}\n\n// GetRows returns the Rows field value\nfunc (o *PtyResizeRequest) GetRows() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Rows\n}\n\n// GetRowsOk returns a tuple with the Rows field value\n// and a boolean to check if the value has been set.\nfunc (o *PtyResizeRequest) GetRowsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Rows, true\n}\n\n// SetRows sets field value\nfunc (o *PtyResizeRequest) SetRows(v float32) {\n\to.Rows = v\n}\n\nfunc (o PtyResizeRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PtyResizeRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"cols\"] = o.Cols\n\ttoSerialize[\"rows\"] = o.Rows\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PtyResizeRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"cols\",\n\t\t\"rows\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPtyResizeRequest := _PtyResizeRequest{}\n\n\terr = json.Unmarshal(data, &varPtyResizeRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PtyResizeRequest(varPtyResizeRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"cols\")\n\t\tdelete(additionalProperties, \"rows\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePtyResizeRequest struct {\n\tvalue *PtyResizeRequest\n\tisSet bool\n}\n\nfunc (v NullablePtyResizeRequest) Get() *PtyResizeRequest {\n\treturn v.value\n}\n\nfunc (v *NullablePtyResizeRequest) Set(val *PtyResizeRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePtyResizeRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePtyResizeRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePtyResizeRequest(val *PtyResizeRequest) *NullablePtyResizeRequest {\n\treturn &NullablePtyResizeRequest{value: val, isSet: true}\n}\n\nfunc (v NullablePtyResizeRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePtyResizeRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_pty_session_info.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the PtySessionInfo type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &PtySessionInfo{}\n\n// PtySessionInfo struct for PtySessionInfo\ntype PtySessionInfo struct {\n\t// The unique identifier for the PTY session\n\tId string `json:\"id\"`\n\t// Starting directory for the PTY session, defaults to the sandbox's working directory\n\tCwd string `json:\"cwd\"`\n\t// Environment variables for the PTY session\n\tEnvs map[string]interface{} `json:\"envs\"`\n\t// Number of terminal columns\n\tCols float32 `json:\"cols\"`\n\t// Number of terminal rows\n\tRows float32 `json:\"rows\"`\n\t// When the PTY session was created\n\tCreatedAt string `json:\"createdAt\"`\n\t// Whether the PTY session is currently active\n\tActive bool `json:\"active\"`\n\t// Whether the PTY session uses lazy start (only start when first client connects)\n\tLazyStart bool `json:\"lazyStart\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _PtySessionInfo PtySessionInfo\n\n// NewPtySessionInfo instantiates a new PtySessionInfo object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewPtySessionInfo(id string, cwd string, envs map[string]interface{}, cols float32, rows float32, createdAt string, active bool, lazyStart bool) *PtySessionInfo {\n\tthis := PtySessionInfo{}\n\tthis.Id = id\n\tthis.Cwd = cwd\n\tthis.Envs = envs\n\tthis.Cols = cols\n\tthis.Rows = rows\n\tthis.CreatedAt = createdAt\n\tthis.Active = active\n\tthis.LazyStart = lazyStart\n\treturn &this\n}\n\n// NewPtySessionInfoWithDefaults instantiates a new PtySessionInfo object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewPtySessionInfoWithDefaults() *PtySessionInfo {\n\tthis := PtySessionInfo{}\n\tvar lazyStart bool = false\n\tthis.LazyStart = lazyStart\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *PtySessionInfo) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *PtySessionInfo) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *PtySessionInfo) SetId(v string) {\n\to.Id = v\n}\n\n// GetCwd returns the Cwd field value\nfunc (o *PtySessionInfo) GetCwd() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Cwd\n}\n\n// GetCwdOk returns a tuple with the Cwd field value\n// and a boolean to check if the value has been set.\nfunc (o *PtySessionInfo) GetCwdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cwd, true\n}\n\n// SetCwd sets field value\nfunc (o *PtySessionInfo) SetCwd(v string) {\n\to.Cwd = v\n}\n\n// GetEnvs returns the Envs field value\nfunc (o *PtySessionInfo) GetEnvs() map[string]interface{} {\n\tif o == nil {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\n\treturn o.Envs\n}\n\n// GetEnvsOk returns a tuple with the Envs field value\n// and a boolean to check if the value has been set.\nfunc (o *PtySessionInfo) GetEnvsOk() (map[string]interface{}, bool) {\n\tif o == nil {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.Envs, true\n}\n\n// SetEnvs sets field value\nfunc (o *PtySessionInfo) SetEnvs(v map[string]interface{}) {\n\to.Envs = v\n}\n\n// GetCols returns the Cols field value\nfunc (o *PtySessionInfo) GetCols() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Cols\n}\n\n// GetColsOk returns a tuple with the Cols field value\n// and a boolean to check if the value has been set.\nfunc (o *PtySessionInfo) GetColsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cols, true\n}\n\n// SetCols sets field value\nfunc (o *PtySessionInfo) SetCols(v float32) {\n\to.Cols = v\n}\n\n// GetRows returns the Rows field value\nfunc (o *PtySessionInfo) GetRows() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Rows\n}\n\n// GetRowsOk returns a tuple with the Rows field value\n// and a boolean to check if the value has been set.\nfunc (o *PtySessionInfo) GetRowsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Rows, true\n}\n\n// SetRows sets field value\nfunc (o *PtySessionInfo) SetRows(v float32) {\n\to.Rows = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *PtySessionInfo) GetCreatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *PtySessionInfo) GetCreatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *PtySessionInfo) SetCreatedAt(v string) {\n\to.CreatedAt = v\n}\n\n// GetActive returns the Active field value\nfunc (o *PtySessionInfo) GetActive() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Active\n}\n\n// GetActiveOk returns a tuple with the Active field value\n// and a boolean to check if the value has been set.\nfunc (o *PtySessionInfo) GetActiveOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Active, true\n}\n\n// SetActive sets field value\nfunc (o *PtySessionInfo) SetActive(v bool) {\n\to.Active = v\n}\n\n// GetLazyStart returns the LazyStart field value\nfunc (o *PtySessionInfo) GetLazyStart() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.LazyStart\n}\n\n// GetLazyStartOk returns a tuple with the LazyStart field value\n// and a boolean to check if the value has been set.\nfunc (o *PtySessionInfo) GetLazyStartOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.LazyStart, true\n}\n\n// SetLazyStart sets field value\nfunc (o *PtySessionInfo) SetLazyStart(v bool) {\n\to.LazyStart = v\n}\n\nfunc (o PtySessionInfo) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o PtySessionInfo) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"cwd\"] = o.Cwd\n\ttoSerialize[\"envs\"] = o.Envs\n\ttoSerialize[\"cols\"] = o.Cols\n\ttoSerialize[\"rows\"] = o.Rows\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"active\"] = o.Active\n\ttoSerialize[\"lazyStart\"] = o.LazyStart\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *PtySessionInfo) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"cwd\",\n\t\t\"envs\",\n\t\t\"cols\",\n\t\t\"rows\",\n\t\t\"createdAt\",\n\t\t\"active\",\n\t\t\"lazyStart\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarPtySessionInfo := _PtySessionInfo{}\n\n\terr = json.Unmarshal(data, &varPtySessionInfo)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = PtySessionInfo(varPtySessionInfo)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"cwd\")\n\t\tdelete(additionalProperties, \"envs\")\n\t\tdelete(additionalProperties, \"cols\")\n\t\tdelete(additionalProperties, \"rows\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"active\")\n\t\tdelete(additionalProperties, \"lazyStart\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullablePtySessionInfo struct {\n\tvalue *PtySessionInfo\n\tisSet bool\n}\n\nfunc (v NullablePtySessionInfo) Get() *PtySessionInfo {\n\treturn v.value\n}\n\nfunc (v *NullablePtySessionInfo) Set(val *PtySessionInfo) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullablePtySessionInfo) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullablePtySessionInfo) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullablePtySessionInfo(val *PtySessionInfo) *NullablePtySessionInfo {\n\treturn &NullablePtySessionInfo{value: val, isSet: true}\n}\n\nfunc (v NullablePtySessionInfo) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullablePtySessionInfo) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_range.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Range type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Range{}\n\n// Range struct for Range\ntype Range struct {\n\tStart Position `json:\"start\"`\n\tEnd Position `json:\"end\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Range Range\n\n// NewRange instantiates a new Range object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRange(start Position, end Position) *Range {\n\tthis := Range{}\n\tthis.Start = start\n\tthis.End = end\n\treturn &this\n}\n\n// NewRangeWithDefaults instantiates a new Range object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRangeWithDefaults() *Range {\n\tthis := Range{}\n\treturn &this\n}\n\n// GetStart returns the Start field value\nfunc (o *Range) GetStart() Position {\n\tif o == nil {\n\t\tvar ret Position\n\t\treturn ret\n\t}\n\n\treturn o.Start\n}\n\n// GetStartOk returns a tuple with the Start field value\n// and a boolean to check if the value has been set.\nfunc (o *Range) GetStartOk() (*Position, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Start, true\n}\n\n// SetStart sets field value\nfunc (o *Range) SetStart(v Position) {\n\to.Start = v\n}\n\n// GetEnd returns the End field value\nfunc (o *Range) GetEnd() Position {\n\tif o == nil {\n\t\tvar ret Position\n\t\treturn ret\n\t}\n\n\treturn o.End\n}\n\n// GetEndOk returns a tuple with the End field value\n// and a boolean to check if the value has been set.\nfunc (o *Range) GetEndOk() (*Position, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.End, true\n}\n\n// SetEnd sets field value\nfunc (o *Range) SetEnd(v Position) {\n\to.End = v\n}\n\nfunc (o Range) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Range) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"start\"] = o.Start\n\ttoSerialize[\"end\"] = o.End\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Range) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"start\",\n\t\t\"end\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRange := _Range{}\n\n\terr = json.Unmarshal(data, &varRange)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Range(varRange)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"start\")\n\t\tdelete(additionalProperties, \"end\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRange struct {\n\tvalue *Range\n\tisSet bool\n}\n\nfunc (v NullableRange) Get() *Range {\n\treturn v.value\n}\n\nfunc (v *NullableRange) Set(val *Range) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRange) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRange) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRange(val *Range) *NullableRange {\n\treturn &NullableRange{value: val, isSet: true}\n}\n\nfunc (v NullableRange) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRange) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_rate_limit_config.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the RateLimitConfig type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RateLimitConfig{}\n\n// RateLimitConfig struct for RateLimitConfig\ntype RateLimitConfig struct {\n\t// Failed authentication rate limit\n\tFailedAuth *RateLimitEntry `json:\"failedAuth,omitempty\"`\n\t// Authenticated rate limit\n\tAuthenticated *RateLimitEntry `json:\"authenticated,omitempty\"`\n\t// Sandbox create rate limit\n\tSandboxCreate *RateLimitEntry `json:\"sandboxCreate,omitempty\"`\n\t// Sandbox lifecycle rate limit\n\tSandboxLifecycle *RateLimitEntry `json:\"sandboxLifecycle,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RateLimitConfig RateLimitConfig\n\n// NewRateLimitConfig instantiates a new RateLimitConfig object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRateLimitConfig() *RateLimitConfig {\n\tthis := RateLimitConfig{}\n\treturn &this\n}\n\n// NewRateLimitConfigWithDefaults instantiates a new RateLimitConfig object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRateLimitConfigWithDefaults() *RateLimitConfig {\n\tthis := RateLimitConfig{}\n\treturn &this\n}\n\n// GetFailedAuth returns the FailedAuth field value if set, zero value otherwise.\nfunc (o *RateLimitConfig) GetFailedAuth() RateLimitEntry {\n\tif o == nil || IsNil(o.FailedAuth) {\n\t\tvar ret RateLimitEntry\n\t\treturn ret\n\t}\n\treturn *o.FailedAuth\n}\n\n// GetFailedAuthOk returns a tuple with the FailedAuth field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RateLimitConfig) GetFailedAuthOk() (*RateLimitEntry, bool) {\n\tif o == nil || IsNil(o.FailedAuth) {\n\t\treturn nil, false\n\t}\n\treturn o.FailedAuth, true\n}\n\n// HasFailedAuth returns a boolean if a field has been set.\nfunc (o *RateLimitConfig) HasFailedAuth() bool {\n\tif o != nil && !IsNil(o.FailedAuth) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetFailedAuth gets a reference to the given RateLimitEntry and assigns it to the FailedAuth field.\nfunc (o *RateLimitConfig) SetFailedAuth(v RateLimitEntry) {\n\to.FailedAuth = &v\n}\n\n// GetAuthenticated returns the Authenticated field value if set, zero value otherwise.\nfunc (o *RateLimitConfig) GetAuthenticated() RateLimitEntry {\n\tif o == nil || IsNil(o.Authenticated) {\n\t\tvar ret RateLimitEntry\n\t\treturn ret\n\t}\n\treturn *o.Authenticated\n}\n\n// GetAuthenticatedOk returns a tuple with the Authenticated field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RateLimitConfig) GetAuthenticatedOk() (*RateLimitEntry, bool) {\n\tif o == nil || IsNil(o.Authenticated) {\n\t\treturn nil, false\n\t}\n\treturn o.Authenticated, true\n}\n\n// HasAuthenticated returns a boolean if a field has been set.\nfunc (o *RateLimitConfig) HasAuthenticated() bool {\n\tif o != nil && !IsNil(o.Authenticated) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAuthenticated gets a reference to the given RateLimitEntry and assigns it to the Authenticated field.\nfunc (o *RateLimitConfig) SetAuthenticated(v RateLimitEntry) {\n\to.Authenticated = &v\n}\n\n// GetSandboxCreate returns the SandboxCreate field value if set, zero value otherwise.\nfunc (o *RateLimitConfig) GetSandboxCreate() RateLimitEntry {\n\tif o == nil || IsNil(o.SandboxCreate) {\n\t\tvar ret RateLimitEntry\n\t\treturn ret\n\t}\n\treturn *o.SandboxCreate\n}\n\n// GetSandboxCreateOk returns a tuple with the SandboxCreate field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RateLimitConfig) GetSandboxCreateOk() (*RateLimitEntry, bool) {\n\tif o == nil || IsNil(o.SandboxCreate) {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxCreate, true\n}\n\n// HasSandboxCreate returns a boolean if a field has been set.\nfunc (o *RateLimitConfig) HasSandboxCreate() bool {\n\tif o != nil && !IsNil(o.SandboxCreate) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSandboxCreate gets a reference to the given RateLimitEntry and assigns it to the SandboxCreate field.\nfunc (o *RateLimitConfig) SetSandboxCreate(v RateLimitEntry) {\n\to.SandboxCreate = &v\n}\n\n// GetSandboxLifecycle returns the SandboxLifecycle field value if set, zero value otherwise.\nfunc (o *RateLimitConfig) GetSandboxLifecycle() RateLimitEntry {\n\tif o == nil || IsNil(o.SandboxLifecycle) {\n\t\tvar ret RateLimitEntry\n\t\treturn ret\n\t}\n\treturn *o.SandboxLifecycle\n}\n\n// GetSandboxLifecycleOk returns a tuple with the SandboxLifecycle field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RateLimitConfig) GetSandboxLifecycleOk() (*RateLimitEntry, bool) {\n\tif o == nil || IsNil(o.SandboxLifecycle) {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxLifecycle, true\n}\n\n// HasSandboxLifecycle returns a boolean if a field has been set.\nfunc (o *RateLimitConfig) HasSandboxLifecycle() bool {\n\tif o != nil && !IsNil(o.SandboxLifecycle) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSandboxLifecycle gets a reference to the given RateLimitEntry and assigns it to the SandboxLifecycle field.\nfunc (o *RateLimitConfig) SetSandboxLifecycle(v RateLimitEntry) {\n\to.SandboxLifecycle = &v\n}\n\nfunc (o RateLimitConfig) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RateLimitConfig) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.FailedAuth) {\n\t\ttoSerialize[\"failedAuth\"] = o.FailedAuth\n\t}\n\tif !IsNil(o.Authenticated) {\n\t\ttoSerialize[\"authenticated\"] = o.Authenticated\n\t}\n\tif !IsNil(o.SandboxCreate) {\n\t\ttoSerialize[\"sandboxCreate\"] = o.SandboxCreate\n\t}\n\tif !IsNil(o.SandboxLifecycle) {\n\t\ttoSerialize[\"sandboxLifecycle\"] = o.SandboxLifecycle\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RateLimitConfig) UnmarshalJSON(data []byte) (err error) {\n\tvarRateLimitConfig := _RateLimitConfig{}\n\n\terr = json.Unmarshal(data, &varRateLimitConfig)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RateLimitConfig(varRateLimitConfig)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"failedAuth\")\n\t\tdelete(additionalProperties, \"authenticated\")\n\t\tdelete(additionalProperties, \"sandboxCreate\")\n\t\tdelete(additionalProperties, \"sandboxLifecycle\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRateLimitConfig struct {\n\tvalue *RateLimitConfig\n\tisSet bool\n}\n\nfunc (v NullableRateLimitConfig) Get() *RateLimitConfig {\n\treturn v.value\n}\n\nfunc (v *NullableRateLimitConfig) Set(val *RateLimitConfig) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRateLimitConfig) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRateLimitConfig) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRateLimitConfig(val *RateLimitConfig) *NullableRateLimitConfig {\n\treturn &NullableRateLimitConfig{value: val, isSet: true}\n}\n\nfunc (v NullableRateLimitConfig) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRateLimitConfig) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_rate_limit_entry.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the RateLimitEntry type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RateLimitEntry{}\n\n// RateLimitEntry struct for RateLimitEntry\ntype RateLimitEntry struct {\n\t// Rate limit TTL in seconds\n\tTtl *float32 `json:\"ttl,omitempty\"`\n\t// Rate limit max requests\n\tLimit *float32 `json:\"limit,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RateLimitEntry RateLimitEntry\n\n// NewRateLimitEntry instantiates a new RateLimitEntry object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRateLimitEntry() *RateLimitEntry {\n\tthis := RateLimitEntry{}\n\treturn &this\n}\n\n// NewRateLimitEntryWithDefaults instantiates a new RateLimitEntry object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRateLimitEntryWithDefaults() *RateLimitEntry {\n\tthis := RateLimitEntry{}\n\treturn &this\n}\n\n// GetTtl returns the Ttl field value if set, zero value otherwise.\nfunc (o *RateLimitEntry) GetTtl() float32 {\n\tif o == nil || IsNil(o.Ttl) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Ttl\n}\n\n// GetTtlOk returns a tuple with the Ttl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RateLimitEntry) GetTtlOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Ttl) {\n\t\treturn nil, false\n\t}\n\treturn o.Ttl, true\n}\n\n// HasTtl returns a boolean if a field has been set.\nfunc (o *RateLimitEntry) HasTtl() bool {\n\tif o != nil && !IsNil(o.Ttl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetTtl gets a reference to the given float32 and assigns it to the Ttl field.\nfunc (o *RateLimitEntry) SetTtl(v float32) {\n\to.Ttl = &v\n}\n\n// GetLimit returns the Limit field value if set, zero value otherwise.\nfunc (o *RateLimitEntry) GetLimit() float32 {\n\tif o == nil || IsNil(o.Limit) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Limit\n}\n\n// GetLimitOk returns a tuple with the Limit field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RateLimitEntry) GetLimitOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Limit) {\n\t\treturn nil, false\n\t}\n\treturn o.Limit, true\n}\n\n// HasLimit returns a boolean if a field has been set.\nfunc (o *RateLimitEntry) HasLimit() bool {\n\tif o != nil && !IsNil(o.Limit) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetLimit gets a reference to the given float32 and assigns it to the Limit field.\nfunc (o *RateLimitEntry) SetLimit(v float32) {\n\to.Limit = &v\n}\n\nfunc (o RateLimitEntry) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RateLimitEntry) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Ttl) {\n\t\ttoSerialize[\"ttl\"] = o.Ttl\n\t}\n\tif !IsNil(o.Limit) {\n\t\ttoSerialize[\"limit\"] = o.Limit\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RateLimitEntry) UnmarshalJSON(data []byte) (err error) {\n\tvarRateLimitEntry := _RateLimitEntry{}\n\n\terr = json.Unmarshal(data, &varRateLimitEntry)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RateLimitEntry(varRateLimitEntry)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"ttl\")\n\t\tdelete(additionalProperties, \"limit\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRateLimitEntry struct {\n\tvalue *RateLimitEntry\n\tisSet bool\n}\n\nfunc (v NullableRateLimitEntry) Get() *RateLimitEntry {\n\treturn v.value\n}\n\nfunc (v *NullableRateLimitEntry) Set(val *RateLimitEntry) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRateLimitEntry) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRateLimitEntry) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRateLimitEntry(val *RateLimitEntry) *NullableRateLimitEntry {\n\treturn &NullableRateLimitEntry{value: val, isSet: true}\n}\n\nfunc (v NullableRateLimitEntry) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRateLimitEntry) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_regenerate_api_key_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RegenerateApiKeyResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RegenerateApiKeyResponse{}\n\n// RegenerateApiKeyResponse struct for RegenerateApiKeyResponse\ntype RegenerateApiKeyResponse struct {\n\t// The newly generated API key\n\tApiKey string `json:\"apiKey\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RegenerateApiKeyResponse RegenerateApiKeyResponse\n\n// NewRegenerateApiKeyResponse instantiates a new RegenerateApiKeyResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRegenerateApiKeyResponse(apiKey string) *RegenerateApiKeyResponse {\n\tthis := RegenerateApiKeyResponse{}\n\tthis.ApiKey = apiKey\n\treturn &this\n}\n\n// NewRegenerateApiKeyResponseWithDefaults instantiates a new RegenerateApiKeyResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRegenerateApiKeyResponseWithDefaults() *RegenerateApiKeyResponse {\n\tthis := RegenerateApiKeyResponse{}\n\treturn &this\n}\n\n// GetApiKey returns the ApiKey field value\nfunc (o *RegenerateApiKeyResponse) GetApiKey() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ApiKey\n}\n\n// GetApiKeyOk returns a tuple with the ApiKey field value\n// and a boolean to check if the value has been set.\nfunc (o *RegenerateApiKeyResponse) GetApiKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ApiKey, true\n}\n\n// SetApiKey sets field value\nfunc (o *RegenerateApiKeyResponse) SetApiKey(v string) {\n\to.ApiKey = v\n}\n\nfunc (o RegenerateApiKeyResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RegenerateApiKeyResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"apiKey\"] = o.ApiKey\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RegenerateApiKeyResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"apiKey\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRegenerateApiKeyResponse := _RegenerateApiKeyResponse{}\n\n\terr = json.Unmarshal(data, &varRegenerateApiKeyResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RegenerateApiKeyResponse(varRegenerateApiKeyResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"apiKey\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRegenerateApiKeyResponse struct {\n\tvalue *RegenerateApiKeyResponse\n\tisSet bool\n}\n\nfunc (v NullableRegenerateApiKeyResponse) Get() *RegenerateApiKeyResponse {\n\treturn v.value\n}\n\nfunc (v *NullableRegenerateApiKeyResponse) Set(val *RegenerateApiKeyResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRegenerateApiKeyResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRegenerateApiKeyResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRegenerateApiKeyResponse(val *RegenerateApiKeyResponse) *NullableRegenerateApiKeyResponse {\n\treturn &NullableRegenerateApiKeyResponse{value: val, isSet: true}\n}\n\nfunc (v NullableRegenerateApiKeyResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRegenerateApiKeyResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_region.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Region type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Region{}\n\n// Region struct for Region\ntype Region struct {\n\t// Region ID\n\tId string `json:\"id\"`\n\t// Region name\n\tName string `json:\"name\"`\n\t// Organization ID\n\tOrganizationId NullableString `json:\"organizationId,omitempty\"`\n\t// The type of the region\n\tRegionType RegionType `json:\"regionType\"`\n\t// Creation timestamp\n\tCreatedAt string `json:\"createdAt\"`\n\t// Last update timestamp\n\tUpdatedAt string `json:\"updatedAt\"`\n\t// Proxy URL for the region\n\tProxyUrl NullableString `json:\"proxyUrl,omitempty\"`\n\t// SSH Gateway URL for the region\n\tSshGatewayUrl NullableString `json:\"sshGatewayUrl,omitempty\"`\n\t// Snapshot Manager URL for the region\n\tSnapshotManagerUrl NullableString `json:\"snapshotManagerUrl,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Region Region\n\n// NewRegion instantiates a new Region object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRegion(id string, name string, regionType RegionType, createdAt string, updatedAt string) *Region {\n\tthis := Region{}\n\tthis.Id = id\n\tthis.Name = name\n\tthis.RegionType = regionType\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\treturn &this\n}\n\n// NewRegionWithDefaults instantiates a new Region object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRegionWithDefaults() *Region {\n\tthis := Region{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *Region) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *Region) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *Region) SetId(v string) {\n\to.Id = v\n}\n\n// GetName returns the Name field value\nfunc (o *Region) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *Region) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *Region) SetName(v string) {\n\to.Name = v\n}\n\n// GetOrganizationId returns the OrganizationId field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *Region) GetOrganizationId() string {\n\tif o == nil || IsNil(o.OrganizationId.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.OrganizationId.Get()\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Region) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.OrganizationId.Get(), o.OrganizationId.IsSet()\n}\n\n// HasOrganizationId returns a boolean if a field has been set.\nfunc (o *Region) HasOrganizationId() bool {\n\tif o != nil && o.OrganizationId.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetOrganizationId gets a reference to the given NullableString and assigns it to the OrganizationId field.\nfunc (o *Region) SetOrganizationId(v string) {\n\to.OrganizationId.Set(&v)\n}\n// SetOrganizationIdNil sets the value for OrganizationId to be an explicit nil\nfunc (o *Region) SetOrganizationIdNil() {\n\to.OrganizationId.Set(nil)\n}\n\n// UnsetOrganizationId ensures that no value is present for OrganizationId, not even an explicit nil\nfunc (o *Region) UnsetOrganizationId() {\n\to.OrganizationId.Unset()\n}\n\n// GetRegionType returns the RegionType field value\nfunc (o *Region) GetRegionType() RegionType {\n\tif o == nil {\n\t\tvar ret RegionType\n\t\treturn ret\n\t}\n\n\treturn o.RegionType\n}\n\n// GetRegionTypeOk returns a tuple with the RegionType field value\n// and a boolean to check if the value has been set.\nfunc (o *Region) GetRegionTypeOk() (*RegionType, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegionType, true\n}\n\n// SetRegionType sets field value\nfunc (o *Region) SetRegionType(v RegionType) {\n\to.RegionType = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *Region) GetCreatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *Region) GetCreatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *Region) SetCreatedAt(v string) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *Region) GetUpdatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *Region) GetUpdatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *Region) SetUpdatedAt(v string) {\n\to.UpdatedAt = v\n}\n\n// GetProxyUrl returns the ProxyUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *Region) GetProxyUrl() string {\n\tif o == nil || IsNil(o.ProxyUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProxyUrl.Get()\n}\n\n// GetProxyUrlOk returns a tuple with the ProxyUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Region) GetProxyUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ProxyUrl.Get(), o.ProxyUrl.IsSet()\n}\n\n// HasProxyUrl returns a boolean if a field has been set.\nfunc (o *Region) HasProxyUrl() bool {\n\tif o != nil && o.ProxyUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProxyUrl gets a reference to the given NullableString and assigns it to the ProxyUrl field.\nfunc (o *Region) SetProxyUrl(v string) {\n\to.ProxyUrl.Set(&v)\n}\n// SetProxyUrlNil sets the value for ProxyUrl to be an explicit nil\nfunc (o *Region) SetProxyUrlNil() {\n\to.ProxyUrl.Set(nil)\n}\n\n// UnsetProxyUrl ensures that no value is present for ProxyUrl, not even an explicit nil\nfunc (o *Region) UnsetProxyUrl() {\n\to.ProxyUrl.Unset()\n}\n\n// GetSshGatewayUrl returns the SshGatewayUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *Region) GetSshGatewayUrl() string {\n\tif o == nil || IsNil(o.SshGatewayUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SshGatewayUrl.Get()\n}\n\n// GetSshGatewayUrlOk returns a tuple with the SshGatewayUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Region) GetSshGatewayUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SshGatewayUrl.Get(), o.SshGatewayUrl.IsSet()\n}\n\n// HasSshGatewayUrl returns a boolean if a field has been set.\nfunc (o *Region) HasSshGatewayUrl() bool {\n\tif o != nil && o.SshGatewayUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSshGatewayUrl gets a reference to the given NullableString and assigns it to the SshGatewayUrl field.\nfunc (o *Region) SetSshGatewayUrl(v string) {\n\to.SshGatewayUrl.Set(&v)\n}\n// SetSshGatewayUrlNil sets the value for SshGatewayUrl to be an explicit nil\nfunc (o *Region) SetSshGatewayUrlNil() {\n\to.SshGatewayUrl.Set(nil)\n}\n\n// UnsetSshGatewayUrl ensures that no value is present for SshGatewayUrl, not even an explicit nil\nfunc (o *Region) UnsetSshGatewayUrl() {\n\to.SshGatewayUrl.Unset()\n}\n\n// GetSnapshotManagerUrl returns the SnapshotManagerUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *Region) GetSnapshotManagerUrl() string {\n\tif o == nil || IsNil(o.SnapshotManagerUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SnapshotManagerUrl.Get()\n}\n\n// GetSnapshotManagerUrlOk returns a tuple with the SnapshotManagerUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Region) GetSnapshotManagerUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotManagerUrl.Get(), o.SnapshotManagerUrl.IsSet()\n}\n\n// HasSnapshotManagerUrl returns a boolean if a field has been set.\nfunc (o *Region) HasSnapshotManagerUrl() bool {\n\tif o != nil && o.SnapshotManagerUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshotManagerUrl gets a reference to the given NullableString and assigns it to the SnapshotManagerUrl field.\nfunc (o *Region) SetSnapshotManagerUrl(v string) {\n\to.SnapshotManagerUrl.Set(&v)\n}\n// SetSnapshotManagerUrlNil sets the value for SnapshotManagerUrl to be an explicit nil\nfunc (o *Region) SetSnapshotManagerUrlNil() {\n\to.SnapshotManagerUrl.Set(nil)\n}\n\n// UnsetSnapshotManagerUrl ensures that no value is present for SnapshotManagerUrl, not even an explicit nil\nfunc (o *Region) UnsetSnapshotManagerUrl() {\n\to.SnapshotManagerUrl.Unset()\n}\n\nfunc (o Region) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Region) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"name\"] = o.Name\n\tif o.OrganizationId.IsSet() {\n\t\ttoSerialize[\"organizationId\"] = o.OrganizationId.Get()\n\t}\n\ttoSerialize[\"regionType\"] = o.RegionType\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\tif o.ProxyUrl.IsSet() {\n\t\ttoSerialize[\"proxyUrl\"] = o.ProxyUrl.Get()\n\t}\n\tif o.SshGatewayUrl.IsSet() {\n\t\ttoSerialize[\"sshGatewayUrl\"] = o.SshGatewayUrl.Get()\n\t}\n\tif o.SnapshotManagerUrl.IsSet() {\n\t\ttoSerialize[\"snapshotManagerUrl\"] = o.SnapshotManagerUrl.Get()\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Region) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"name\",\n\t\t\"regionType\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRegion := _Region{}\n\n\terr = json.Unmarshal(data, &varRegion)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Region(varRegion)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"regionType\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"proxyUrl\")\n\t\tdelete(additionalProperties, \"sshGatewayUrl\")\n\t\tdelete(additionalProperties, \"snapshotManagerUrl\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRegion struct {\n\tvalue *Region\n\tisSet bool\n}\n\nfunc (v NullableRegion) Get() *Region {\n\treturn v.value\n}\n\nfunc (v *NullableRegion) Set(val *Region) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRegion) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRegion) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRegion(val *Region) *NullableRegion {\n\treturn &NullableRegion{value: val, isSet: true}\n}\n\nfunc (v NullableRegion) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRegion) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_region_quota.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RegionQuota type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RegionQuota{}\n\n// RegionQuota struct for RegionQuota\ntype RegionQuota struct {\n\tOrganizationId string `json:\"organizationId\"`\n\tRegionId string `json:\"regionId\"`\n\tTotalCpuQuota float32 `json:\"totalCpuQuota\"`\n\tTotalMemoryQuota float32 `json:\"totalMemoryQuota\"`\n\tTotalDiskQuota float32 `json:\"totalDiskQuota\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RegionQuota RegionQuota\n\n// NewRegionQuota instantiates a new RegionQuota object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRegionQuota(organizationId string, regionId string, totalCpuQuota float32, totalMemoryQuota float32, totalDiskQuota float32) *RegionQuota {\n\tthis := RegionQuota{}\n\tthis.OrganizationId = organizationId\n\tthis.RegionId = regionId\n\tthis.TotalCpuQuota = totalCpuQuota\n\tthis.TotalMemoryQuota = totalMemoryQuota\n\tthis.TotalDiskQuota = totalDiskQuota\n\treturn &this\n}\n\n// NewRegionQuotaWithDefaults instantiates a new RegionQuota object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRegionQuotaWithDefaults() *RegionQuota {\n\tthis := RegionQuota{}\n\treturn &this\n}\n\n// GetOrganizationId returns the OrganizationId field value\nfunc (o *RegionQuota) GetOrganizationId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionQuota) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationId, true\n}\n\n// SetOrganizationId sets field value\nfunc (o *RegionQuota) SetOrganizationId(v string) {\n\to.OrganizationId = v\n}\n\n// GetRegionId returns the RegionId field value\nfunc (o *RegionQuota) GetRegionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RegionId\n}\n\n// GetRegionIdOk returns a tuple with the RegionId field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionQuota) GetRegionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegionId, true\n}\n\n// SetRegionId sets field value\nfunc (o *RegionQuota) SetRegionId(v string) {\n\to.RegionId = v\n}\n\n// GetTotalCpuQuota returns the TotalCpuQuota field value\nfunc (o *RegionQuota) GetTotalCpuQuota() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalCpuQuota\n}\n\n// GetTotalCpuQuotaOk returns a tuple with the TotalCpuQuota field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionQuota) GetTotalCpuQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalCpuQuota, true\n}\n\n// SetTotalCpuQuota sets field value\nfunc (o *RegionQuota) SetTotalCpuQuota(v float32) {\n\to.TotalCpuQuota = v\n}\n\n// GetTotalMemoryQuota returns the TotalMemoryQuota field value\nfunc (o *RegionQuota) GetTotalMemoryQuota() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalMemoryQuota\n}\n\n// GetTotalMemoryQuotaOk returns a tuple with the TotalMemoryQuota field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionQuota) GetTotalMemoryQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalMemoryQuota, true\n}\n\n// SetTotalMemoryQuota sets field value\nfunc (o *RegionQuota) SetTotalMemoryQuota(v float32) {\n\to.TotalMemoryQuota = v\n}\n\n// GetTotalDiskQuota returns the TotalDiskQuota field value\nfunc (o *RegionQuota) GetTotalDiskQuota() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalDiskQuota\n}\n\n// GetTotalDiskQuotaOk returns a tuple with the TotalDiskQuota field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionQuota) GetTotalDiskQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalDiskQuota, true\n}\n\n// SetTotalDiskQuota sets field value\nfunc (o *RegionQuota) SetTotalDiskQuota(v float32) {\n\to.TotalDiskQuota = v\n}\n\nfunc (o RegionQuota) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RegionQuota) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\ttoSerialize[\"regionId\"] = o.RegionId\n\ttoSerialize[\"totalCpuQuota\"] = o.TotalCpuQuota\n\ttoSerialize[\"totalMemoryQuota\"] = o.TotalMemoryQuota\n\ttoSerialize[\"totalDiskQuota\"] = o.TotalDiskQuota\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RegionQuota) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"organizationId\",\n\t\t\"regionId\",\n\t\t\"totalCpuQuota\",\n\t\t\"totalMemoryQuota\",\n\t\t\"totalDiskQuota\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRegionQuota := _RegionQuota{}\n\n\terr = json.Unmarshal(data, &varRegionQuota)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RegionQuota(varRegionQuota)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"regionId\")\n\t\tdelete(additionalProperties, \"totalCpuQuota\")\n\t\tdelete(additionalProperties, \"totalMemoryQuota\")\n\t\tdelete(additionalProperties, \"totalDiskQuota\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRegionQuota struct {\n\tvalue *RegionQuota\n\tisSet bool\n}\n\nfunc (v NullableRegionQuota) Get() *RegionQuota {\n\treturn v.value\n}\n\nfunc (v *NullableRegionQuota) Set(val *RegionQuota) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRegionQuota) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRegionQuota) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRegionQuota(val *RegionQuota) *NullableRegionQuota {\n\treturn &NullableRegionQuota{value: val, isSet: true}\n}\n\nfunc (v NullableRegionQuota) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRegionQuota) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_region_screenshot_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RegionScreenshotResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RegionScreenshotResponse{}\n\n// RegionScreenshotResponse struct for RegionScreenshotResponse\ntype RegionScreenshotResponse struct {\n\t// Base64 encoded screenshot image data of the specified region\n\tScreenshot string `json:\"screenshot\"`\n\t// The current cursor position when the region screenshot was taken\n\tCursorPosition map[string]interface{} `json:\"cursorPosition,omitempty\"`\n\t// The size of the screenshot data in bytes\n\tSizeBytes *float32 `json:\"sizeBytes,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RegionScreenshotResponse RegionScreenshotResponse\n\n// NewRegionScreenshotResponse instantiates a new RegionScreenshotResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRegionScreenshotResponse(screenshot string) *RegionScreenshotResponse {\n\tthis := RegionScreenshotResponse{}\n\tthis.Screenshot = screenshot\n\treturn &this\n}\n\n// NewRegionScreenshotResponseWithDefaults instantiates a new RegionScreenshotResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRegionScreenshotResponseWithDefaults() *RegionScreenshotResponse {\n\tthis := RegionScreenshotResponse{}\n\treturn &this\n}\n\n// GetScreenshot returns the Screenshot field value\nfunc (o *RegionScreenshotResponse) GetScreenshot() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Screenshot\n}\n\n// GetScreenshotOk returns a tuple with the Screenshot field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionScreenshotResponse) GetScreenshotOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Screenshot, true\n}\n\n// SetScreenshot sets field value\nfunc (o *RegionScreenshotResponse) SetScreenshot(v string) {\n\to.Screenshot = v\n}\n\n// GetCursorPosition returns the CursorPosition field value if set, zero value otherwise.\nfunc (o *RegionScreenshotResponse) GetCursorPosition() map[string]interface{} {\n\tif o == nil || IsNil(o.CursorPosition) {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\treturn o.CursorPosition\n}\n\n// GetCursorPositionOk returns a tuple with the CursorPosition field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RegionScreenshotResponse) GetCursorPositionOk() (map[string]interface{}, bool) {\n\tif o == nil || IsNil(o.CursorPosition) {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.CursorPosition, true\n}\n\n// HasCursorPosition returns a boolean if a field has been set.\nfunc (o *RegionScreenshotResponse) HasCursorPosition() bool {\n\tif o != nil && !IsNil(o.CursorPosition) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCursorPosition gets a reference to the given map[string]interface{} and assigns it to the CursorPosition field.\nfunc (o *RegionScreenshotResponse) SetCursorPosition(v map[string]interface{}) {\n\to.CursorPosition = v\n}\n\n// GetSizeBytes returns the SizeBytes field value if set, zero value otherwise.\nfunc (o *RegionScreenshotResponse) GetSizeBytes() float32 {\n\tif o == nil || IsNil(o.SizeBytes) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.SizeBytes\n}\n\n// GetSizeBytesOk returns a tuple with the SizeBytes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RegionScreenshotResponse) GetSizeBytesOk() (*float32, bool) {\n\tif o == nil || IsNil(o.SizeBytes) {\n\t\treturn nil, false\n\t}\n\treturn o.SizeBytes, true\n}\n\n// HasSizeBytes returns a boolean if a field has been set.\nfunc (o *RegionScreenshotResponse) HasSizeBytes() bool {\n\tif o != nil && !IsNil(o.SizeBytes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSizeBytes gets a reference to the given float32 and assigns it to the SizeBytes field.\nfunc (o *RegionScreenshotResponse) SetSizeBytes(v float32) {\n\to.SizeBytes = &v\n}\n\nfunc (o RegionScreenshotResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RegionScreenshotResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"screenshot\"] = o.Screenshot\n\tif !IsNil(o.CursorPosition) {\n\t\ttoSerialize[\"cursorPosition\"] = o.CursorPosition\n\t}\n\tif !IsNil(o.SizeBytes) {\n\t\ttoSerialize[\"sizeBytes\"] = o.SizeBytes\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RegionScreenshotResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"screenshot\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRegionScreenshotResponse := _RegionScreenshotResponse{}\n\n\terr = json.Unmarshal(data, &varRegionScreenshotResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RegionScreenshotResponse(varRegionScreenshotResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"screenshot\")\n\t\tdelete(additionalProperties, \"cursorPosition\")\n\t\tdelete(additionalProperties, \"sizeBytes\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRegionScreenshotResponse struct {\n\tvalue *RegionScreenshotResponse\n\tisSet bool\n}\n\nfunc (v NullableRegionScreenshotResponse) Get() *RegionScreenshotResponse {\n\treturn v.value\n}\n\nfunc (v *NullableRegionScreenshotResponse) Set(val *RegionScreenshotResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRegionScreenshotResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRegionScreenshotResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRegionScreenshotResponse(val *RegionScreenshotResponse) *NullableRegionScreenshotResponse {\n\treturn &NullableRegionScreenshotResponse{value: val, isSet: true}\n}\n\nfunc (v NullableRegionScreenshotResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRegionScreenshotResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_region_type.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// RegionType The type of the region\ntype RegionType string\n\n// List of RegionType\nconst (\n\tREGIONTYPE_SHARED RegionType = \"shared\"\n\tREGIONTYPE_DEDICATED RegionType = \"dedicated\"\n\tREGIONTYPE_CUSTOM RegionType = \"custom\"\n)\n\n// All allowed values of RegionType enum\nvar AllowedRegionTypeEnumValues = []RegionType{\n\t\"shared\",\n\t\"dedicated\",\n\t\"custom\",\n}\n\nfunc (v *RegionType) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := RegionType(value)\n\tfor _, existing := range AllowedRegionTypeEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid RegionType\", value)\n}\n\n// NewRegionTypeFromValue returns a pointer to a valid RegionType\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewRegionTypeFromValue(v string) (*RegionType, error) {\n\tev := RegionType(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for RegionType: valid values are %v\", v, AllowedRegionTypeEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v RegionType) IsValid() bool {\n\tfor _, existing := range AllowedRegionTypeEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to RegionType value\nfunc (v RegionType) Ptr() *RegionType {\n\treturn &v\n}\n\ntype NullableRegionType struct {\n\tvalue *RegionType\n\tisSet bool\n}\n\nfunc (v NullableRegionType) Get() *RegionType {\n\treturn v.value\n}\n\nfunc (v *NullableRegionType) Set(val *RegionType) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRegionType) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRegionType) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRegionType(val *RegionType) *NullableRegionType {\n\treturn &NullableRegionType{value: val, isSet: true}\n}\n\nfunc (v NullableRegionType) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRegionType) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_region_usage_overview.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RegionUsageOverview type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RegionUsageOverview{}\n\n// RegionUsageOverview struct for RegionUsageOverview\ntype RegionUsageOverview struct {\n\tRegionId string `json:\"regionId\"`\n\tTotalCpuQuota float32 `json:\"totalCpuQuota\"`\n\tCurrentCpuUsage float32 `json:\"currentCpuUsage\"`\n\tTotalMemoryQuota float32 `json:\"totalMemoryQuota\"`\n\tCurrentMemoryUsage float32 `json:\"currentMemoryUsage\"`\n\tTotalDiskQuota float32 `json:\"totalDiskQuota\"`\n\tCurrentDiskUsage float32 `json:\"currentDiskUsage\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RegionUsageOverview RegionUsageOverview\n\n// NewRegionUsageOverview instantiates a new RegionUsageOverview object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRegionUsageOverview(regionId string, totalCpuQuota float32, currentCpuUsage float32, totalMemoryQuota float32, currentMemoryUsage float32, totalDiskQuota float32, currentDiskUsage float32) *RegionUsageOverview {\n\tthis := RegionUsageOverview{}\n\tthis.RegionId = regionId\n\tthis.TotalCpuQuota = totalCpuQuota\n\tthis.CurrentCpuUsage = currentCpuUsage\n\tthis.TotalMemoryQuota = totalMemoryQuota\n\tthis.CurrentMemoryUsage = currentMemoryUsage\n\tthis.TotalDiskQuota = totalDiskQuota\n\tthis.CurrentDiskUsage = currentDiskUsage\n\treturn &this\n}\n\n// NewRegionUsageOverviewWithDefaults instantiates a new RegionUsageOverview object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRegionUsageOverviewWithDefaults() *RegionUsageOverview {\n\tthis := RegionUsageOverview{}\n\treturn &this\n}\n\n// GetRegionId returns the RegionId field value\nfunc (o *RegionUsageOverview) GetRegionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RegionId\n}\n\n// GetRegionIdOk returns a tuple with the RegionId field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionUsageOverview) GetRegionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegionId, true\n}\n\n// SetRegionId sets field value\nfunc (o *RegionUsageOverview) SetRegionId(v string) {\n\to.RegionId = v\n}\n\n// GetTotalCpuQuota returns the TotalCpuQuota field value\nfunc (o *RegionUsageOverview) GetTotalCpuQuota() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalCpuQuota\n}\n\n// GetTotalCpuQuotaOk returns a tuple with the TotalCpuQuota field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionUsageOverview) GetTotalCpuQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalCpuQuota, true\n}\n\n// SetTotalCpuQuota sets field value\nfunc (o *RegionUsageOverview) SetTotalCpuQuota(v float32) {\n\to.TotalCpuQuota = v\n}\n\n// GetCurrentCpuUsage returns the CurrentCpuUsage field value\nfunc (o *RegionUsageOverview) GetCurrentCpuUsage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentCpuUsage\n}\n\n// GetCurrentCpuUsageOk returns a tuple with the CurrentCpuUsage field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionUsageOverview) GetCurrentCpuUsageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentCpuUsage, true\n}\n\n// SetCurrentCpuUsage sets field value\nfunc (o *RegionUsageOverview) SetCurrentCpuUsage(v float32) {\n\to.CurrentCpuUsage = v\n}\n\n// GetTotalMemoryQuota returns the TotalMemoryQuota field value\nfunc (o *RegionUsageOverview) GetTotalMemoryQuota() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalMemoryQuota\n}\n\n// GetTotalMemoryQuotaOk returns a tuple with the TotalMemoryQuota field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionUsageOverview) GetTotalMemoryQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalMemoryQuota, true\n}\n\n// SetTotalMemoryQuota sets field value\nfunc (o *RegionUsageOverview) SetTotalMemoryQuota(v float32) {\n\to.TotalMemoryQuota = v\n}\n\n// GetCurrentMemoryUsage returns the CurrentMemoryUsage field value\nfunc (o *RegionUsageOverview) GetCurrentMemoryUsage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentMemoryUsage\n}\n\n// GetCurrentMemoryUsageOk returns a tuple with the CurrentMemoryUsage field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionUsageOverview) GetCurrentMemoryUsageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentMemoryUsage, true\n}\n\n// SetCurrentMemoryUsage sets field value\nfunc (o *RegionUsageOverview) SetCurrentMemoryUsage(v float32) {\n\to.CurrentMemoryUsage = v\n}\n\n// GetTotalDiskQuota returns the TotalDiskQuota field value\nfunc (o *RegionUsageOverview) GetTotalDiskQuota() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.TotalDiskQuota\n}\n\n// GetTotalDiskQuotaOk returns a tuple with the TotalDiskQuota field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionUsageOverview) GetTotalDiskQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TotalDiskQuota, true\n}\n\n// SetTotalDiskQuota sets field value\nfunc (o *RegionUsageOverview) SetTotalDiskQuota(v float32) {\n\to.TotalDiskQuota = v\n}\n\n// GetCurrentDiskUsage returns the CurrentDiskUsage field value\nfunc (o *RegionUsageOverview) GetCurrentDiskUsage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentDiskUsage\n}\n\n// GetCurrentDiskUsageOk returns a tuple with the CurrentDiskUsage field value\n// and a boolean to check if the value has been set.\nfunc (o *RegionUsageOverview) GetCurrentDiskUsageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentDiskUsage, true\n}\n\n// SetCurrentDiskUsage sets field value\nfunc (o *RegionUsageOverview) SetCurrentDiskUsage(v float32) {\n\to.CurrentDiskUsage = v\n}\n\nfunc (o RegionUsageOverview) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RegionUsageOverview) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"regionId\"] = o.RegionId\n\ttoSerialize[\"totalCpuQuota\"] = o.TotalCpuQuota\n\ttoSerialize[\"currentCpuUsage\"] = o.CurrentCpuUsage\n\ttoSerialize[\"totalMemoryQuota\"] = o.TotalMemoryQuota\n\ttoSerialize[\"currentMemoryUsage\"] = o.CurrentMemoryUsage\n\ttoSerialize[\"totalDiskQuota\"] = o.TotalDiskQuota\n\ttoSerialize[\"currentDiskUsage\"] = o.CurrentDiskUsage\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RegionUsageOverview) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"regionId\",\n\t\t\"totalCpuQuota\",\n\t\t\"currentCpuUsage\",\n\t\t\"totalMemoryQuota\",\n\t\t\"currentMemoryUsage\",\n\t\t\"totalDiskQuota\",\n\t\t\"currentDiskUsage\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRegionUsageOverview := _RegionUsageOverview{}\n\n\terr = json.Unmarshal(data, &varRegionUsageOverview)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RegionUsageOverview(varRegionUsageOverview)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"regionId\")\n\t\tdelete(additionalProperties, \"totalCpuQuota\")\n\t\tdelete(additionalProperties, \"currentCpuUsage\")\n\t\tdelete(additionalProperties, \"totalMemoryQuota\")\n\t\tdelete(additionalProperties, \"currentMemoryUsage\")\n\t\tdelete(additionalProperties, \"totalDiskQuota\")\n\t\tdelete(additionalProperties, \"currentDiskUsage\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRegionUsageOverview struct {\n\tvalue *RegionUsageOverview\n\tisSet bool\n}\n\nfunc (v NullableRegionUsageOverview) Get() *RegionUsageOverview {\n\treturn v.value\n}\n\nfunc (v *NullableRegionUsageOverview) Set(val *RegionUsageOverview) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRegionUsageOverview) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRegionUsageOverview) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRegionUsageOverview(val *RegionUsageOverview) *NullableRegionUsageOverview {\n\treturn &NullableRegionUsageOverview{value: val, isSet: true}\n}\n\nfunc (v NullableRegionUsageOverview) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRegionUsageOverview) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_registry_push_access_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RegistryPushAccessDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RegistryPushAccessDto{}\n\n// RegistryPushAccessDto struct for RegistryPushAccessDto\ntype RegistryPushAccessDto struct {\n\t// Temporary username for registry authentication\n\tUsername string `json:\"username\"`\n\t// Temporary secret for registry authentication\n\tSecret string `json:\"secret\"`\n\t// Registry URL\n\tRegistryUrl string `json:\"registryUrl\"`\n\t// Registry ID\n\tRegistryId string `json:\"registryId\"`\n\t// Registry project ID\n\tProject string `json:\"project\"`\n\t// Token expiration time in ISO format\n\tExpiresAt string `json:\"expiresAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RegistryPushAccessDto RegistryPushAccessDto\n\n// NewRegistryPushAccessDto instantiates a new RegistryPushAccessDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRegistryPushAccessDto(username string, secret string, registryUrl string, registryId string, project string, expiresAt string) *RegistryPushAccessDto {\n\tthis := RegistryPushAccessDto{}\n\tthis.Username = username\n\tthis.Secret = secret\n\tthis.RegistryUrl = registryUrl\n\tthis.RegistryId = registryId\n\tthis.Project = project\n\tthis.ExpiresAt = expiresAt\n\treturn &this\n}\n\n// NewRegistryPushAccessDtoWithDefaults instantiates a new RegistryPushAccessDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRegistryPushAccessDtoWithDefaults() *RegistryPushAccessDto {\n\tthis := RegistryPushAccessDto{}\n\treturn &this\n}\n\n// GetUsername returns the Username field value\nfunc (o *RegistryPushAccessDto) GetUsername() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Username\n}\n\n// GetUsernameOk returns a tuple with the Username field value\n// and a boolean to check if the value has been set.\nfunc (o *RegistryPushAccessDto) GetUsernameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Username, true\n}\n\n// SetUsername sets field value\nfunc (o *RegistryPushAccessDto) SetUsername(v string) {\n\to.Username = v\n}\n\n// GetSecret returns the Secret field value\nfunc (o *RegistryPushAccessDto) GetSecret() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Secret\n}\n\n// GetSecretOk returns a tuple with the Secret field value\n// and a boolean to check if the value has been set.\nfunc (o *RegistryPushAccessDto) GetSecretOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Secret, true\n}\n\n// SetSecret sets field value\nfunc (o *RegistryPushAccessDto) SetSecret(v string) {\n\to.Secret = v\n}\n\n// GetRegistryUrl returns the RegistryUrl field value\nfunc (o *RegistryPushAccessDto) GetRegistryUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RegistryUrl\n}\n\n// GetRegistryUrlOk returns a tuple with the RegistryUrl field value\n// and a boolean to check if the value has been set.\nfunc (o *RegistryPushAccessDto) GetRegistryUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegistryUrl, true\n}\n\n// SetRegistryUrl sets field value\nfunc (o *RegistryPushAccessDto) SetRegistryUrl(v string) {\n\to.RegistryUrl = v\n}\n\n// GetRegistryId returns the RegistryId field value\nfunc (o *RegistryPushAccessDto) GetRegistryId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RegistryId\n}\n\n// GetRegistryIdOk returns a tuple with the RegistryId field value\n// and a boolean to check if the value has been set.\nfunc (o *RegistryPushAccessDto) GetRegistryIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RegistryId, true\n}\n\n// SetRegistryId sets field value\nfunc (o *RegistryPushAccessDto) SetRegistryId(v string) {\n\to.RegistryId = v\n}\n\n// GetProject returns the Project field value\nfunc (o *RegistryPushAccessDto) GetProject() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Project\n}\n\n// GetProjectOk returns a tuple with the Project field value\n// and a boolean to check if the value has been set.\nfunc (o *RegistryPushAccessDto) GetProjectOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Project, true\n}\n\n// SetProject sets field value\nfunc (o *RegistryPushAccessDto) SetProject(v string) {\n\to.Project = v\n}\n\n// GetExpiresAt returns the ExpiresAt field value\nfunc (o *RegistryPushAccessDto) GetExpiresAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ExpiresAt\n}\n\n// GetExpiresAtOk returns a tuple with the ExpiresAt field value\n// and a boolean to check if the value has been set.\nfunc (o *RegistryPushAccessDto) GetExpiresAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ExpiresAt, true\n}\n\n// SetExpiresAt sets field value\nfunc (o *RegistryPushAccessDto) SetExpiresAt(v string) {\n\to.ExpiresAt = v\n}\n\nfunc (o RegistryPushAccessDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RegistryPushAccessDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"username\"] = o.Username\n\ttoSerialize[\"secret\"] = o.Secret\n\ttoSerialize[\"registryUrl\"] = o.RegistryUrl\n\ttoSerialize[\"registryId\"] = o.RegistryId\n\ttoSerialize[\"project\"] = o.Project\n\ttoSerialize[\"expiresAt\"] = o.ExpiresAt\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RegistryPushAccessDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"username\",\n\t\t\"secret\",\n\t\t\"registryUrl\",\n\t\t\"registryId\",\n\t\t\"project\",\n\t\t\"expiresAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRegistryPushAccessDto := _RegistryPushAccessDto{}\n\n\terr = json.Unmarshal(data, &varRegistryPushAccessDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RegistryPushAccessDto(varRegistryPushAccessDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"username\")\n\t\tdelete(additionalProperties, \"secret\")\n\t\tdelete(additionalProperties, \"registryUrl\")\n\t\tdelete(additionalProperties, \"registryId\")\n\t\tdelete(additionalProperties, \"project\")\n\t\tdelete(additionalProperties, \"expiresAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRegistryPushAccessDto struct {\n\tvalue *RegistryPushAccessDto\n\tisSet bool\n}\n\nfunc (v NullableRegistryPushAccessDto) Get() *RegistryPushAccessDto {\n\treturn v.value\n}\n\nfunc (v *NullableRegistryPushAccessDto) Set(val *RegistryPushAccessDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRegistryPushAccessDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRegistryPushAccessDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRegistryPushAccessDto(val *RegistryPushAccessDto) *NullableRegistryPushAccessDto {\n\treturn &NullableRegistryPushAccessDto{value: val, isSet: true}\n}\n\nfunc (v NullableRegistryPushAccessDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRegistryPushAccessDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_replace_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ReplaceRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ReplaceRequest{}\n\n// ReplaceRequest struct for ReplaceRequest\ntype ReplaceRequest struct {\n\tFiles []string `json:\"files\"`\n\tPattern string `json:\"pattern\"`\n\tNewValue string `json:\"newValue\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ReplaceRequest ReplaceRequest\n\n// NewReplaceRequest instantiates a new ReplaceRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewReplaceRequest(files []string, pattern string, newValue string) *ReplaceRequest {\n\tthis := ReplaceRequest{}\n\tthis.Files = files\n\tthis.Pattern = pattern\n\tthis.NewValue = newValue\n\treturn &this\n}\n\n// NewReplaceRequestWithDefaults instantiates a new ReplaceRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewReplaceRequestWithDefaults() *ReplaceRequest {\n\tthis := ReplaceRequest{}\n\treturn &this\n}\n\n// GetFiles returns the Files field value\nfunc (o *ReplaceRequest) GetFiles() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Files\n}\n\n// GetFilesOk returns a tuple with the Files field value\n// and a boolean to check if the value has been set.\nfunc (o *ReplaceRequest) GetFilesOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Files, true\n}\n\n// SetFiles sets field value\nfunc (o *ReplaceRequest) SetFiles(v []string) {\n\to.Files = v\n}\n\n// GetPattern returns the Pattern field value\nfunc (o *ReplaceRequest) GetPattern() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Pattern\n}\n\n// GetPatternOk returns a tuple with the Pattern field value\n// and a boolean to check if the value has been set.\nfunc (o *ReplaceRequest) GetPatternOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Pattern, true\n}\n\n// SetPattern sets field value\nfunc (o *ReplaceRequest) SetPattern(v string) {\n\to.Pattern = v\n}\n\n// GetNewValue returns the NewValue field value\nfunc (o *ReplaceRequest) GetNewValue() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.NewValue\n}\n\n// GetNewValueOk returns a tuple with the NewValue field value\n// and a boolean to check if the value has been set.\nfunc (o *ReplaceRequest) GetNewValueOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.NewValue, true\n}\n\n// SetNewValue sets field value\nfunc (o *ReplaceRequest) SetNewValue(v string) {\n\to.NewValue = v\n}\n\nfunc (o ReplaceRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ReplaceRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"files\"] = o.Files\n\ttoSerialize[\"pattern\"] = o.Pattern\n\ttoSerialize[\"newValue\"] = o.NewValue\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ReplaceRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"files\",\n\t\t\"pattern\",\n\t\t\"newValue\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarReplaceRequest := _ReplaceRequest{}\n\n\terr = json.Unmarshal(data, &varReplaceRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ReplaceRequest(varReplaceRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"files\")\n\t\tdelete(additionalProperties, \"pattern\")\n\t\tdelete(additionalProperties, \"newValue\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableReplaceRequest struct {\n\tvalue *ReplaceRequest\n\tisSet bool\n}\n\nfunc (v NullableReplaceRequest) Get() *ReplaceRequest {\n\treturn v.value\n}\n\nfunc (v *NullableReplaceRequest) Set(val *ReplaceRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableReplaceRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableReplaceRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableReplaceRequest(val *ReplaceRequest) *NullableReplaceRequest {\n\treturn &NullableReplaceRequest{value: val, isSet: true}\n}\n\nfunc (v NullableReplaceRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableReplaceRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_replace_result.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the ReplaceResult type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ReplaceResult{}\n\n// ReplaceResult struct for ReplaceResult\ntype ReplaceResult struct {\n\tFile *string `json:\"file,omitempty\"`\n\tSuccess *bool `json:\"success,omitempty\"`\n\tError *string `json:\"error,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ReplaceResult ReplaceResult\n\n// NewReplaceResult instantiates a new ReplaceResult object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewReplaceResult() *ReplaceResult {\n\tthis := ReplaceResult{}\n\treturn &this\n}\n\n// NewReplaceResultWithDefaults instantiates a new ReplaceResult object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewReplaceResultWithDefaults() *ReplaceResult {\n\tthis := ReplaceResult{}\n\treturn &this\n}\n\n// GetFile returns the File field value if set, zero value otherwise.\nfunc (o *ReplaceResult) GetFile() string {\n\tif o == nil || IsNil(o.File) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.File\n}\n\n// GetFileOk returns a tuple with the File field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ReplaceResult) GetFileOk() (*string, bool) {\n\tif o == nil || IsNil(o.File) {\n\t\treturn nil, false\n\t}\n\treturn o.File, true\n}\n\n// HasFile returns a boolean if a field has been set.\nfunc (o *ReplaceResult) HasFile() bool {\n\tif o != nil && !IsNil(o.File) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetFile gets a reference to the given string and assigns it to the File field.\nfunc (o *ReplaceResult) SetFile(v string) {\n\to.File = &v\n}\n\n// GetSuccess returns the Success field value if set, zero value otherwise.\nfunc (o *ReplaceResult) GetSuccess() bool {\n\tif o == nil || IsNil(o.Success) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Success\n}\n\n// GetSuccessOk returns a tuple with the Success field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ReplaceResult) GetSuccessOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Success) {\n\t\treturn nil, false\n\t}\n\treturn o.Success, true\n}\n\n// HasSuccess returns a boolean if a field has been set.\nfunc (o *ReplaceResult) HasSuccess() bool {\n\tif o != nil && !IsNil(o.Success) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSuccess gets a reference to the given bool and assigns it to the Success field.\nfunc (o *ReplaceResult) SetSuccess(v bool) {\n\to.Success = &v\n}\n\n// GetError returns the Error field value if set, zero value otherwise.\nfunc (o *ReplaceResult) GetError() string {\n\tif o == nil || IsNil(o.Error) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Error\n}\n\n// GetErrorOk returns a tuple with the Error field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ReplaceResult) GetErrorOk() (*string, bool) {\n\tif o == nil || IsNil(o.Error) {\n\t\treturn nil, false\n\t}\n\treturn o.Error, true\n}\n\n// HasError returns a boolean if a field has been set.\nfunc (o *ReplaceResult) HasError() bool {\n\tif o != nil && !IsNil(o.Error) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetError gets a reference to the given string and assigns it to the Error field.\nfunc (o *ReplaceResult) SetError(v string) {\n\to.Error = &v\n}\n\nfunc (o ReplaceResult) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ReplaceResult) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.File) {\n\t\ttoSerialize[\"file\"] = o.File\n\t}\n\tif !IsNil(o.Success) {\n\t\ttoSerialize[\"success\"] = o.Success\n\t}\n\tif !IsNil(o.Error) {\n\t\ttoSerialize[\"error\"] = o.Error\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ReplaceResult) UnmarshalJSON(data []byte) (err error) {\n\tvarReplaceResult := _ReplaceResult{}\n\n\terr = json.Unmarshal(data, &varReplaceResult)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ReplaceResult(varReplaceResult)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"file\")\n\t\tdelete(additionalProperties, \"success\")\n\t\tdelete(additionalProperties, \"error\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableReplaceResult struct {\n\tvalue *ReplaceResult\n\tisSet bool\n}\n\nfunc (v NullableReplaceResult) Get() *ReplaceResult {\n\treturn v.value\n}\n\nfunc (v *NullableReplaceResult) Set(val *ReplaceResult) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableReplaceResult) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableReplaceResult) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableReplaceResult(val *ReplaceResult) *NullableReplaceResult {\n\treturn &NullableReplaceResult{value: val, isSet: true}\n}\n\nfunc (v NullableReplaceResult) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableReplaceResult) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_resize_sandbox.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the ResizeSandbox type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ResizeSandbox{}\n\n// ResizeSandbox struct for ResizeSandbox\ntype ResizeSandbox struct {\n\t// CPU cores to allocate to the sandbox (minimum: 1)\n\tCpu *int32 `json:\"cpu,omitempty\"`\n\t// Memory in GB to allocate to the sandbox (minimum: 1)\n\tMemory *int32 `json:\"memory,omitempty\"`\n\t// Disk space in GB to allocate to the sandbox (can only be increased)\n\tDisk *int32 `json:\"disk,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ResizeSandbox ResizeSandbox\n\n// NewResizeSandbox instantiates a new ResizeSandbox object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewResizeSandbox() *ResizeSandbox {\n\tthis := ResizeSandbox{}\n\treturn &this\n}\n\n// NewResizeSandboxWithDefaults instantiates a new ResizeSandbox object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewResizeSandboxWithDefaults() *ResizeSandbox {\n\tthis := ResizeSandbox{}\n\treturn &this\n}\n\n// GetCpu returns the Cpu field value if set, zero value otherwise.\nfunc (o *ResizeSandbox) GetCpu() int32 {\n\tif o == nil || IsNil(o.Cpu) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ResizeSandbox) GetCpuOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Cpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Cpu, true\n}\n\n// HasCpu returns a boolean if a field has been set.\nfunc (o *ResizeSandbox) HasCpu() bool {\n\tif o != nil && !IsNil(o.Cpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCpu gets a reference to the given int32 and assigns it to the Cpu field.\nfunc (o *ResizeSandbox) SetCpu(v int32) {\n\to.Cpu = &v\n}\n\n// GetMemory returns the Memory field value if set, zero value otherwise.\nfunc (o *ResizeSandbox) GetMemory() int32 {\n\tif o == nil || IsNil(o.Memory) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Memory\n}\n\n// GetMemoryOk returns a tuple with the Memory field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ResizeSandbox) GetMemoryOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Memory) {\n\t\treturn nil, false\n\t}\n\treturn o.Memory, true\n}\n\n// HasMemory returns a boolean if a field has been set.\nfunc (o *ResizeSandbox) HasMemory() bool {\n\tif o != nil && !IsNil(o.Memory) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMemory gets a reference to the given int32 and assigns it to the Memory field.\nfunc (o *ResizeSandbox) SetMemory(v int32) {\n\to.Memory = &v\n}\n\n// GetDisk returns the Disk field value if set, zero value otherwise.\nfunc (o *ResizeSandbox) GetDisk() int32 {\n\tif o == nil || IsNil(o.Disk) {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\treturn *o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ResizeSandbox) GetDiskOk() (*int32, bool) {\n\tif o == nil || IsNil(o.Disk) {\n\t\treturn nil, false\n\t}\n\treturn o.Disk, true\n}\n\n// HasDisk returns a boolean if a field has been set.\nfunc (o *ResizeSandbox) HasDisk() bool {\n\tif o != nil && !IsNil(o.Disk) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDisk gets a reference to the given int32 and assigns it to the Disk field.\nfunc (o *ResizeSandbox) SetDisk(v int32) {\n\to.Disk = &v\n}\n\nfunc (o ResizeSandbox) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ResizeSandbox) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Cpu) {\n\t\ttoSerialize[\"cpu\"] = o.Cpu\n\t}\n\tif !IsNil(o.Memory) {\n\t\ttoSerialize[\"memory\"] = o.Memory\n\t}\n\tif !IsNil(o.Disk) {\n\t\ttoSerialize[\"disk\"] = o.Disk\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ResizeSandbox) UnmarshalJSON(data []byte) (err error) {\n\tvarResizeSandbox := _ResizeSandbox{}\n\n\terr = json.Unmarshal(data, &varResizeSandbox)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ResizeSandbox(varResizeSandbox)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"memory\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableResizeSandbox struct {\n\tvalue *ResizeSandbox\n\tisSet bool\n}\n\nfunc (v NullableResizeSandbox) Get() *ResizeSandbox {\n\treturn v.value\n}\n\nfunc (v *NullableResizeSandbox) Set(val *ResizeSandbox) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableResizeSandbox) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableResizeSandbox) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableResizeSandbox(val *ResizeSandbox) *NullableResizeSandbox {\n\treturn &NullableResizeSandbox{value: val, isSet: true}\n}\n\nfunc (v NullableResizeSandbox) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableResizeSandbox) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_runner.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Runner type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Runner{}\n\n// Runner struct for Runner\ntype Runner struct {\n\t// The ID of the runner\n\tId string `json:\"id\"`\n\t// The domain of the runner\n\tDomain *string `json:\"domain,omitempty\"`\n\t// The API URL of the runner\n\tApiUrl *string `json:\"apiUrl,omitempty\"`\n\t// The proxy URL of the runner\n\tProxyUrl *string `json:\"proxyUrl,omitempty\"`\n\t// The CPU capacity of the runner\n\tCpu float32 `json:\"cpu\"`\n\t// The memory capacity of the runner in GiB\n\tMemory float32 `json:\"memory\"`\n\t// The disk capacity of the runner in GiB\n\tDisk float32 `json:\"disk\"`\n\t// The GPU capacity of the runner\n\tGpu *float32 `json:\"gpu,omitempty\"`\n\t// The type of GPU\n\tGpuType *string `json:\"gpuType,omitempty\"`\n\t// The class of the runner\n\tClass SandboxClass `json:\"class\"`\n\t// Current CPU usage percentage\n\tCurrentCpuUsagePercentage *float32 `json:\"currentCpuUsagePercentage,omitempty\"`\n\t// Current RAM usage percentage\n\tCurrentMemoryUsagePercentage *float32 `json:\"currentMemoryUsagePercentage,omitempty\"`\n\t// Current disk usage percentage\n\tCurrentDiskUsagePercentage *float32 `json:\"currentDiskUsagePercentage,omitempty\"`\n\t// Current allocated CPU\n\tCurrentAllocatedCpu *float32 `json:\"currentAllocatedCpu,omitempty\"`\n\t// Current allocated memory in GiB\n\tCurrentAllocatedMemoryGiB *float32 `json:\"currentAllocatedMemoryGiB,omitempty\"`\n\t// Current allocated disk in GiB\n\tCurrentAllocatedDiskGiB *float32 `json:\"currentAllocatedDiskGiB,omitempty\"`\n\t// Current snapshot count\n\tCurrentSnapshotCount *float32 `json:\"currentSnapshotCount,omitempty\"`\n\t// Current number of started sandboxes\n\tCurrentStartedSandboxes *float32 `json:\"currentStartedSandboxes,omitempty\"`\n\t// Runner availability score\n\tAvailabilityScore *float32 `json:\"availabilityScore,omitempty\"`\n\t// The region of the runner\n\tRegion string `json:\"region\"`\n\t// The name of the runner\n\tName string `json:\"name\"`\n\t// The state of the runner\n\tState RunnerState `json:\"state\"`\n\t// The last time the runner was checked\n\tLastChecked *string `json:\"lastChecked,omitempty\"`\n\t// Whether the runner is unschedulable\n\tUnschedulable bool `json:\"unschedulable\"`\n\t// The creation timestamp of the runner\n\tCreatedAt string `json:\"createdAt\"`\n\t// The last update timestamp of the runner\n\tUpdatedAt string `json:\"updatedAt\"`\n\t// The version of the runner (deprecated in favor of apiVersion)\n\t// Deprecated\n\tVersion string `json:\"version\"`\n\t// The api version of the runner\n\t// Deprecated\n\tApiVersion string `json:\"apiVersion\"`\n\t// The app version of the runner\n\t// Deprecated\n\tAppVersion *string `json:\"appVersion,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Runner Runner\n\n// NewRunner instantiates a new Runner object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRunner(id string, cpu float32, memory float32, disk float32, class SandboxClass, region string, name string, state RunnerState, unschedulable bool, createdAt string, updatedAt string, version string, apiVersion string) *Runner {\n\tthis := Runner{}\n\tthis.Id = id\n\tthis.Cpu = cpu\n\tthis.Memory = memory\n\tthis.Disk = disk\n\tthis.Class = class\n\tthis.Region = region\n\tthis.Name = name\n\tthis.State = state\n\tthis.Unschedulable = unschedulable\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\tthis.Version = version\n\tthis.ApiVersion = apiVersion\n\treturn &this\n}\n\n// NewRunnerWithDefaults instantiates a new Runner object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRunnerWithDefaults() *Runner {\n\tthis := Runner{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *Runner) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *Runner) SetId(v string) {\n\to.Id = v\n}\n\n// GetDomain returns the Domain field value if set, zero value otherwise.\nfunc (o *Runner) GetDomain() string {\n\tif o == nil || IsNil(o.Domain) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Domain\n}\n\n// GetDomainOk returns a tuple with the Domain field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetDomainOk() (*string, bool) {\n\tif o == nil || IsNil(o.Domain) {\n\t\treturn nil, false\n\t}\n\treturn o.Domain, true\n}\n\n// HasDomain returns a boolean if a field has been set.\nfunc (o *Runner) HasDomain() bool {\n\tif o != nil && !IsNil(o.Domain) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDomain gets a reference to the given string and assigns it to the Domain field.\nfunc (o *Runner) SetDomain(v string) {\n\to.Domain = &v\n}\n\n// GetApiUrl returns the ApiUrl field value if set, zero value otherwise.\nfunc (o *Runner) GetApiUrl() string {\n\tif o == nil || IsNil(o.ApiUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ApiUrl\n}\n\n// GetApiUrlOk returns a tuple with the ApiUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetApiUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.ApiUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.ApiUrl, true\n}\n\n// HasApiUrl returns a boolean if a field has been set.\nfunc (o *Runner) HasApiUrl() bool {\n\tif o != nil && !IsNil(o.ApiUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetApiUrl gets a reference to the given string and assigns it to the ApiUrl field.\nfunc (o *Runner) SetApiUrl(v string) {\n\to.ApiUrl = &v\n}\n\n// GetProxyUrl returns the ProxyUrl field value if set, zero value otherwise.\nfunc (o *Runner) GetProxyUrl() string {\n\tif o == nil || IsNil(o.ProxyUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProxyUrl\n}\n\n// GetProxyUrlOk returns a tuple with the ProxyUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetProxyUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.ProxyUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.ProxyUrl, true\n}\n\n// HasProxyUrl returns a boolean if a field has been set.\nfunc (o *Runner) HasProxyUrl() bool {\n\tif o != nil && !IsNil(o.ProxyUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProxyUrl gets a reference to the given string and assigns it to the ProxyUrl field.\nfunc (o *Runner) SetProxyUrl(v string) {\n\to.ProxyUrl = &v\n}\n\n// GetCpu returns the Cpu field value\nfunc (o *Runner) GetCpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cpu, true\n}\n\n// SetCpu sets field value\nfunc (o *Runner) SetCpu(v float32) {\n\to.Cpu = v\n}\n\n// GetMemory returns the Memory field value\nfunc (o *Runner) GetMemory() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Memory\n}\n\n// GetMemoryOk returns a tuple with the Memory field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetMemoryOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Memory, true\n}\n\n// SetMemory sets field value\nfunc (o *Runner) SetMemory(v float32) {\n\to.Memory = v\n}\n\n// GetDisk returns the Disk field value\nfunc (o *Runner) GetDisk() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetDiskOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Disk, true\n}\n\n// SetDisk sets field value\nfunc (o *Runner) SetDisk(v float32) {\n\to.Disk = v\n}\n\n// GetGpu returns the Gpu field value if set, zero value otherwise.\nfunc (o *Runner) GetGpu() float32 {\n\tif o == nil || IsNil(o.Gpu) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Gpu\n}\n\n// GetGpuOk returns a tuple with the Gpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetGpuOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Gpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Gpu, true\n}\n\n// HasGpu returns a boolean if a field has been set.\nfunc (o *Runner) HasGpu() bool {\n\tif o != nil && !IsNil(o.Gpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetGpu gets a reference to the given float32 and assigns it to the Gpu field.\nfunc (o *Runner) SetGpu(v float32) {\n\to.Gpu = &v\n}\n\n// GetGpuType returns the GpuType field value if set, zero value otherwise.\nfunc (o *Runner) GetGpuType() string {\n\tif o == nil || IsNil(o.GpuType) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.GpuType\n}\n\n// GetGpuTypeOk returns a tuple with the GpuType field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetGpuTypeOk() (*string, bool) {\n\tif o == nil || IsNil(o.GpuType) {\n\t\treturn nil, false\n\t}\n\treturn o.GpuType, true\n}\n\n// HasGpuType returns a boolean if a field has been set.\nfunc (o *Runner) HasGpuType() bool {\n\tif o != nil && !IsNil(o.GpuType) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetGpuType gets a reference to the given string and assigns it to the GpuType field.\nfunc (o *Runner) SetGpuType(v string) {\n\to.GpuType = &v\n}\n\n// GetClass returns the Class field value\nfunc (o *Runner) GetClass() SandboxClass {\n\tif o == nil {\n\t\tvar ret SandboxClass\n\t\treturn ret\n\t}\n\n\treturn o.Class\n}\n\n// GetClassOk returns a tuple with the Class field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetClassOk() (*SandboxClass, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Class, true\n}\n\n// SetClass sets field value\nfunc (o *Runner) SetClass(v SandboxClass) {\n\to.Class = v\n}\n\n// GetCurrentCpuUsagePercentage returns the CurrentCpuUsagePercentage field value if set, zero value otherwise.\nfunc (o *Runner) GetCurrentCpuUsagePercentage() float32 {\n\tif o == nil || IsNil(o.CurrentCpuUsagePercentage) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentCpuUsagePercentage\n}\n\n// GetCurrentCpuUsagePercentageOk returns a tuple with the CurrentCpuUsagePercentage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCurrentCpuUsagePercentageOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentCpuUsagePercentage) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentCpuUsagePercentage, true\n}\n\n// HasCurrentCpuUsagePercentage returns a boolean if a field has been set.\nfunc (o *Runner) HasCurrentCpuUsagePercentage() bool {\n\tif o != nil && !IsNil(o.CurrentCpuUsagePercentage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentCpuUsagePercentage gets a reference to the given float32 and assigns it to the CurrentCpuUsagePercentage field.\nfunc (o *Runner) SetCurrentCpuUsagePercentage(v float32) {\n\to.CurrentCpuUsagePercentage = &v\n}\n\n// GetCurrentMemoryUsagePercentage returns the CurrentMemoryUsagePercentage field value if set, zero value otherwise.\nfunc (o *Runner) GetCurrentMemoryUsagePercentage() float32 {\n\tif o == nil || IsNil(o.CurrentMemoryUsagePercentage) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentMemoryUsagePercentage\n}\n\n// GetCurrentMemoryUsagePercentageOk returns a tuple with the CurrentMemoryUsagePercentage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCurrentMemoryUsagePercentageOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentMemoryUsagePercentage) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentMemoryUsagePercentage, true\n}\n\n// HasCurrentMemoryUsagePercentage returns a boolean if a field has been set.\nfunc (o *Runner) HasCurrentMemoryUsagePercentage() bool {\n\tif o != nil && !IsNil(o.CurrentMemoryUsagePercentage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentMemoryUsagePercentage gets a reference to the given float32 and assigns it to the CurrentMemoryUsagePercentage field.\nfunc (o *Runner) SetCurrentMemoryUsagePercentage(v float32) {\n\to.CurrentMemoryUsagePercentage = &v\n}\n\n// GetCurrentDiskUsagePercentage returns the CurrentDiskUsagePercentage field value if set, zero value otherwise.\nfunc (o *Runner) GetCurrentDiskUsagePercentage() float32 {\n\tif o == nil || IsNil(o.CurrentDiskUsagePercentage) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentDiskUsagePercentage\n}\n\n// GetCurrentDiskUsagePercentageOk returns a tuple with the CurrentDiskUsagePercentage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCurrentDiskUsagePercentageOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentDiskUsagePercentage) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentDiskUsagePercentage, true\n}\n\n// HasCurrentDiskUsagePercentage returns a boolean if a field has been set.\nfunc (o *Runner) HasCurrentDiskUsagePercentage() bool {\n\tif o != nil && !IsNil(o.CurrentDiskUsagePercentage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentDiskUsagePercentage gets a reference to the given float32 and assigns it to the CurrentDiskUsagePercentage field.\nfunc (o *Runner) SetCurrentDiskUsagePercentage(v float32) {\n\to.CurrentDiskUsagePercentage = &v\n}\n\n// GetCurrentAllocatedCpu returns the CurrentAllocatedCpu field value if set, zero value otherwise.\nfunc (o *Runner) GetCurrentAllocatedCpu() float32 {\n\tif o == nil || IsNil(o.CurrentAllocatedCpu) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentAllocatedCpu\n}\n\n// GetCurrentAllocatedCpuOk returns a tuple with the CurrentAllocatedCpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCurrentAllocatedCpuOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentAllocatedCpu) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentAllocatedCpu, true\n}\n\n// HasCurrentAllocatedCpu returns a boolean if a field has been set.\nfunc (o *Runner) HasCurrentAllocatedCpu() bool {\n\tif o != nil && !IsNil(o.CurrentAllocatedCpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentAllocatedCpu gets a reference to the given float32 and assigns it to the CurrentAllocatedCpu field.\nfunc (o *Runner) SetCurrentAllocatedCpu(v float32) {\n\to.CurrentAllocatedCpu = &v\n}\n\n// GetCurrentAllocatedMemoryGiB returns the CurrentAllocatedMemoryGiB field value if set, zero value otherwise.\nfunc (o *Runner) GetCurrentAllocatedMemoryGiB() float32 {\n\tif o == nil || IsNil(o.CurrentAllocatedMemoryGiB) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentAllocatedMemoryGiB\n}\n\n// GetCurrentAllocatedMemoryGiBOk returns a tuple with the CurrentAllocatedMemoryGiB field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCurrentAllocatedMemoryGiBOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentAllocatedMemoryGiB) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentAllocatedMemoryGiB, true\n}\n\n// HasCurrentAllocatedMemoryGiB returns a boolean if a field has been set.\nfunc (o *Runner) HasCurrentAllocatedMemoryGiB() bool {\n\tif o != nil && !IsNil(o.CurrentAllocatedMemoryGiB) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentAllocatedMemoryGiB gets a reference to the given float32 and assigns it to the CurrentAllocatedMemoryGiB field.\nfunc (o *Runner) SetCurrentAllocatedMemoryGiB(v float32) {\n\to.CurrentAllocatedMemoryGiB = &v\n}\n\n// GetCurrentAllocatedDiskGiB returns the CurrentAllocatedDiskGiB field value if set, zero value otherwise.\nfunc (o *Runner) GetCurrentAllocatedDiskGiB() float32 {\n\tif o == nil || IsNil(o.CurrentAllocatedDiskGiB) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentAllocatedDiskGiB\n}\n\n// GetCurrentAllocatedDiskGiBOk returns a tuple with the CurrentAllocatedDiskGiB field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCurrentAllocatedDiskGiBOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentAllocatedDiskGiB) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentAllocatedDiskGiB, true\n}\n\n// HasCurrentAllocatedDiskGiB returns a boolean if a field has been set.\nfunc (o *Runner) HasCurrentAllocatedDiskGiB() bool {\n\tif o != nil && !IsNil(o.CurrentAllocatedDiskGiB) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentAllocatedDiskGiB gets a reference to the given float32 and assigns it to the CurrentAllocatedDiskGiB field.\nfunc (o *Runner) SetCurrentAllocatedDiskGiB(v float32) {\n\to.CurrentAllocatedDiskGiB = &v\n}\n\n// GetCurrentSnapshotCount returns the CurrentSnapshotCount field value if set, zero value otherwise.\nfunc (o *Runner) GetCurrentSnapshotCount() float32 {\n\tif o == nil || IsNil(o.CurrentSnapshotCount) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentSnapshotCount\n}\n\n// GetCurrentSnapshotCountOk returns a tuple with the CurrentSnapshotCount field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCurrentSnapshotCountOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentSnapshotCount) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentSnapshotCount, true\n}\n\n// HasCurrentSnapshotCount returns a boolean if a field has been set.\nfunc (o *Runner) HasCurrentSnapshotCount() bool {\n\tif o != nil && !IsNil(o.CurrentSnapshotCount) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentSnapshotCount gets a reference to the given float32 and assigns it to the CurrentSnapshotCount field.\nfunc (o *Runner) SetCurrentSnapshotCount(v float32) {\n\to.CurrentSnapshotCount = &v\n}\n\n// GetCurrentStartedSandboxes returns the CurrentStartedSandboxes field value if set, zero value otherwise.\nfunc (o *Runner) GetCurrentStartedSandboxes() float32 {\n\tif o == nil || IsNil(o.CurrentStartedSandboxes) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentStartedSandboxes\n}\n\n// GetCurrentStartedSandboxesOk returns a tuple with the CurrentStartedSandboxes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCurrentStartedSandboxesOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentStartedSandboxes) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentStartedSandboxes, true\n}\n\n// HasCurrentStartedSandboxes returns a boolean if a field has been set.\nfunc (o *Runner) HasCurrentStartedSandboxes() bool {\n\tif o != nil && !IsNil(o.CurrentStartedSandboxes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentStartedSandboxes gets a reference to the given float32 and assigns it to the CurrentStartedSandboxes field.\nfunc (o *Runner) SetCurrentStartedSandboxes(v float32) {\n\to.CurrentStartedSandboxes = &v\n}\n\n// GetAvailabilityScore returns the AvailabilityScore field value if set, zero value otherwise.\nfunc (o *Runner) GetAvailabilityScore() float32 {\n\tif o == nil || IsNil(o.AvailabilityScore) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.AvailabilityScore\n}\n\n// GetAvailabilityScoreOk returns a tuple with the AvailabilityScore field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetAvailabilityScoreOk() (*float32, bool) {\n\tif o == nil || IsNil(o.AvailabilityScore) {\n\t\treturn nil, false\n\t}\n\treturn o.AvailabilityScore, true\n}\n\n// HasAvailabilityScore returns a boolean if a field has been set.\nfunc (o *Runner) HasAvailabilityScore() bool {\n\tif o != nil && !IsNil(o.AvailabilityScore) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAvailabilityScore gets a reference to the given float32 and assigns it to the AvailabilityScore field.\nfunc (o *Runner) SetAvailabilityScore(v float32) {\n\to.AvailabilityScore = &v\n}\n\n// GetRegion returns the Region field value\nfunc (o *Runner) GetRegion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Region\n}\n\n// GetRegionOk returns a tuple with the Region field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetRegionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Region, true\n}\n\n// SetRegion sets field value\nfunc (o *Runner) SetRegion(v string) {\n\to.Region = v\n}\n\n// GetName returns the Name field value\nfunc (o *Runner) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *Runner) SetName(v string) {\n\to.Name = v\n}\n\n// GetState returns the State field value\nfunc (o *Runner) GetState() RunnerState {\n\tif o == nil {\n\t\tvar ret RunnerState\n\t\treturn ret\n\t}\n\n\treturn o.State\n}\n\n// GetStateOk returns a tuple with the State field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetStateOk() (*RunnerState, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.State, true\n}\n\n// SetState sets field value\nfunc (o *Runner) SetState(v RunnerState) {\n\to.State = v\n}\n\n// GetLastChecked returns the LastChecked field value if set, zero value otherwise.\nfunc (o *Runner) GetLastChecked() string {\n\tif o == nil || IsNil(o.LastChecked) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.LastChecked\n}\n\n// GetLastCheckedOk returns a tuple with the LastChecked field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetLastCheckedOk() (*string, bool) {\n\tif o == nil || IsNil(o.LastChecked) {\n\t\treturn nil, false\n\t}\n\treturn o.LastChecked, true\n}\n\n// HasLastChecked returns a boolean if a field has been set.\nfunc (o *Runner) HasLastChecked() bool {\n\tif o != nil && !IsNil(o.LastChecked) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetLastChecked gets a reference to the given string and assigns it to the LastChecked field.\nfunc (o *Runner) SetLastChecked(v string) {\n\to.LastChecked = &v\n}\n\n// GetUnschedulable returns the Unschedulable field value\nfunc (o *Runner) GetUnschedulable() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Unschedulable\n}\n\n// GetUnschedulableOk returns a tuple with the Unschedulable field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetUnschedulableOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Unschedulable, true\n}\n\n// SetUnschedulable sets field value\nfunc (o *Runner) SetUnschedulable(v bool) {\n\to.Unschedulable = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *Runner) GetCreatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetCreatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *Runner) SetCreatedAt(v string) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *Runner) GetUpdatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *Runner) GetUpdatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *Runner) SetUpdatedAt(v string) {\n\to.UpdatedAt = v\n}\n\n// GetVersion returns the Version field value\n// Deprecated\nfunc (o *Runner) GetVersion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Version\n}\n\n// GetVersionOk returns a tuple with the Version field value\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *Runner) GetVersionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Version, true\n}\n\n// SetVersion sets field value\n// Deprecated\nfunc (o *Runner) SetVersion(v string) {\n\to.Version = v\n}\n\n// GetApiVersion returns the ApiVersion field value\n// Deprecated\nfunc (o *Runner) GetApiVersion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ApiVersion\n}\n\n// GetApiVersionOk returns a tuple with the ApiVersion field value\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *Runner) GetApiVersionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ApiVersion, true\n}\n\n// SetApiVersion sets field value\n// Deprecated\nfunc (o *Runner) SetApiVersion(v string) {\n\to.ApiVersion = v\n}\n\n// GetAppVersion returns the AppVersion field value if set, zero value otherwise.\n// Deprecated\nfunc (o *Runner) GetAppVersion() string {\n\tif o == nil || IsNil(o.AppVersion) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.AppVersion\n}\n\n// GetAppVersionOk returns a tuple with the AppVersion field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *Runner) GetAppVersionOk() (*string, bool) {\n\tif o == nil || IsNil(o.AppVersion) {\n\t\treturn nil, false\n\t}\n\treturn o.AppVersion, true\n}\n\n// HasAppVersion returns a boolean if a field has been set.\nfunc (o *Runner) HasAppVersion() bool {\n\tif o != nil && !IsNil(o.AppVersion) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAppVersion gets a reference to the given string and assigns it to the AppVersion field.\n// Deprecated\nfunc (o *Runner) SetAppVersion(v string) {\n\to.AppVersion = &v\n}\n\nfunc (o Runner) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Runner) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\tif !IsNil(o.Domain) {\n\t\ttoSerialize[\"domain\"] = o.Domain\n\t}\n\tif !IsNil(o.ApiUrl) {\n\t\ttoSerialize[\"apiUrl\"] = o.ApiUrl\n\t}\n\tif !IsNil(o.ProxyUrl) {\n\t\ttoSerialize[\"proxyUrl\"] = o.ProxyUrl\n\t}\n\ttoSerialize[\"cpu\"] = o.Cpu\n\ttoSerialize[\"memory\"] = o.Memory\n\ttoSerialize[\"disk\"] = o.Disk\n\tif !IsNil(o.Gpu) {\n\t\ttoSerialize[\"gpu\"] = o.Gpu\n\t}\n\tif !IsNil(o.GpuType) {\n\t\ttoSerialize[\"gpuType\"] = o.GpuType\n\t}\n\ttoSerialize[\"class\"] = o.Class\n\tif !IsNil(o.CurrentCpuUsagePercentage) {\n\t\ttoSerialize[\"currentCpuUsagePercentage\"] = o.CurrentCpuUsagePercentage\n\t}\n\tif !IsNil(o.CurrentMemoryUsagePercentage) {\n\t\ttoSerialize[\"currentMemoryUsagePercentage\"] = o.CurrentMemoryUsagePercentage\n\t}\n\tif !IsNil(o.CurrentDiskUsagePercentage) {\n\t\ttoSerialize[\"currentDiskUsagePercentage\"] = o.CurrentDiskUsagePercentage\n\t}\n\tif !IsNil(o.CurrentAllocatedCpu) {\n\t\ttoSerialize[\"currentAllocatedCpu\"] = o.CurrentAllocatedCpu\n\t}\n\tif !IsNil(o.CurrentAllocatedMemoryGiB) {\n\t\ttoSerialize[\"currentAllocatedMemoryGiB\"] = o.CurrentAllocatedMemoryGiB\n\t}\n\tif !IsNil(o.CurrentAllocatedDiskGiB) {\n\t\ttoSerialize[\"currentAllocatedDiskGiB\"] = o.CurrentAllocatedDiskGiB\n\t}\n\tif !IsNil(o.CurrentSnapshotCount) {\n\t\ttoSerialize[\"currentSnapshotCount\"] = o.CurrentSnapshotCount\n\t}\n\tif !IsNil(o.CurrentStartedSandboxes) {\n\t\ttoSerialize[\"currentStartedSandboxes\"] = o.CurrentStartedSandboxes\n\t}\n\tif !IsNil(o.AvailabilityScore) {\n\t\ttoSerialize[\"availabilityScore\"] = o.AvailabilityScore\n\t}\n\ttoSerialize[\"region\"] = o.Region\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"state\"] = o.State\n\tif !IsNil(o.LastChecked) {\n\t\ttoSerialize[\"lastChecked\"] = o.LastChecked\n\t}\n\ttoSerialize[\"unschedulable\"] = o.Unschedulable\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\ttoSerialize[\"version\"] = o.Version\n\ttoSerialize[\"apiVersion\"] = o.ApiVersion\n\tif !IsNil(o.AppVersion) {\n\t\ttoSerialize[\"appVersion\"] = o.AppVersion\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Runner) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"cpu\",\n\t\t\"memory\",\n\t\t\"disk\",\n\t\t\"class\",\n\t\t\"region\",\n\t\t\"name\",\n\t\t\"state\",\n\t\t\"unschedulable\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t\t\"version\",\n\t\t\"apiVersion\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRunner := _Runner{}\n\n\terr = json.Unmarshal(data, &varRunner)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Runner(varRunner)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"domain\")\n\t\tdelete(additionalProperties, \"apiUrl\")\n\t\tdelete(additionalProperties, \"proxyUrl\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"memory\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\tdelete(additionalProperties, \"gpu\")\n\t\tdelete(additionalProperties, \"gpuType\")\n\t\tdelete(additionalProperties, \"class\")\n\t\tdelete(additionalProperties, \"currentCpuUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentMemoryUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentDiskUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentAllocatedCpu\")\n\t\tdelete(additionalProperties, \"currentAllocatedMemoryGiB\")\n\t\tdelete(additionalProperties, \"currentAllocatedDiskGiB\")\n\t\tdelete(additionalProperties, \"currentSnapshotCount\")\n\t\tdelete(additionalProperties, \"currentStartedSandboxes\")\n\t\tdelete(additionalProperties, \"availabilityScore\")\n\t\tdelete(additionalProperties, \"region\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"state\")\n\t\tdelete(additionalProperties, \"lastChecked\")\n\t\tdelete(additionalProperties, \"unschedulable\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"version\")\n\t\tdelete(additionalProperties, \"apiVersion\")\n\t\tdelete(additionalProperties, \"appVersion\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRunner struct {\n\tvalue *Runner\n\tisSet bool\n}\n\nfunc (v NullableRunner) Get() *Runner {\n\treturn v.value\n}\n\nfunc (v *NullableRunner) Set(val *Runner) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRunner) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRunner) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRunner(val *Runner) *NullableRunner {\n\treturn &NullableRunner{value: val, isSet: true}\n}\n\nfunc (v NullableRunner) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRunner) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_runner_full.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RunnerFull type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RunnerFull{}\n\n// RunnerFull struct for RunnerFull\ntype RunnerFull struct {\n\t// The ID of the runner\n\tId string `json:\"id\"`\n\t// The domain of the runner\n\tDomain *string `json:\"domain,omitempty\"`\n\t// The API URL of the runner\n\tApiUrl *string `json:\"apiUrl,omitempty\"`\n\t// The proxy URL of the runner\n\tProxyUrl *string `json:\"proxyUrl,omitempty\"`\n\t// The CPU capacity of the runner\n\tCpu float32 `json:\"cpu\"`\n\t// The memory capacity of the runner in GiB\n\tMemory float32 `json:\"memory\"`\n\t// The disk capacity of the runner in GiB\n\tDisk float32 `json:\"disk\"`\n\t// The GPU capacity of the runner\n\tGpu *float32 `json:\"gpu,omitempty\"`\n\t// The type of GPU\n\tGpuType *string `json:\"gpuType,omitempty\"`\n\t// The class of the runner\n\tClass SandboxClass `json:\"class\"`\n\t// Current CPU usage percentage\n\tCurrentCpuUsagePercentage *float32 `json:\"currentCpuUsagePercentage,omitempty\"`\n\t// Current RAM usage percentage\n\tCurrentMemoryUsagePercentage *float32 `json:\"currentMemoryUsagePercentage,omitempty\"`\n\t// Current disk usage percentage\n\tCurrentDiskUsagePercentage *float32 `json:\"currentDiskUsagePercentage,omitempty\"`\n\t// Current allocated CPU\n\tCurrentAllocatedCpu *float32 `json:\"currentAllocatedCpu,omitempty\"`\n\t// Current allocated memory in GiB\n\tCurrentAllocatedMemoryGiB *float32 `json:\"currentAllocatedMemoryGiB,omitempty\"`\n\t// Current allocated disk in GiB\n\tCurrentAllocatedDiskGiB *float32 `json:\"currentAllocatedDiskGiB,omitempty\"`\n\t// Current snapshot count\n\tCurrentSnapshotCount *float32 `json:\"currentSnapshotCount,omitempty\"`\n\t// Current number of started sandboxes\n\tCurrentStartedSandboxes *float32 `json:\"currentStartedSandboxes,omitempty\"`\n\t// Runner availability score\n\tAvailabilityScore *float32 `json:\"availabilityScore,omitempty\"`\n\t// The region of the runner\n\tRegion string `json:\"region\"`\n\t// The name of the runner\n\tName string `json:\"name\"`\n\t// The state of the runner\n\tState RunnerState `json:\"state\"`\n\t// The last time the runner was checked\n\tLastChecked *string `json:\"lastChecked,omitempty\"`\n\t// Whether the runner is unschedulable\n\tUnschedulable bool `json:\"unschedulable\"`\n\t// The creation timestamp of the runner\n\tCreatedAt string `json:\"createdAt\"`\n\t// The last update timestamp of the runner\n\tUpdatedAt string `json:\"updatedAt\"`\n\t// The version of the runner (deprecated in favor of apiVersion)\n\t// Deprecated\n\tVersion string `json:\"version\"`\n\t// The api version of the runner\n\t// Deprecated\n\tApiVersion string `json:\"apiVersion\"`\n\t// The app version of the runner\n\t// Deprecated\n\tAppVersion *string `json:\"appVersion,omitempty\"`\n\t// The API key for the runner\n\tApiKey string `json:\"apiKey\"`\n\t// The region type of the runner\n\tRegionType *RegionType `json:\"regionType,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RunnerFull RunnerFull\n\n// NewRunnerFull instantiates a new RunnerFull object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRunnerFull(id string, cpu float32, memory float32, disk float32, class SandboxClass, region string, name string, state RunnerState, unschedulable bool, createdAt string, updatedAt string, version string, apiVersion string, apiKey string) *RunnerFull {\n\tthis := RunnerFull{}\n\tthis.Id = id\n\tthis.Cpu = cpu\n\tthis.Memory = memory\n\tthis.Disk = disk\n\tthis.Class = class\n\tthis.Region = region\n\tthis.Name = name\n\tthis.State = state\n\tthis.Unschedulable = unschedulable\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\tthis.Version = version\n\tthis.ApiVersion = apiVersion\n\tthis.ApiKey = apiKey\n\treturn &this\n}\n\n// NewRunnerFullWithDefaults instantiates a new RunnerFull object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRunnerFullWithDefaults() *RunnerFull {\n\tthis := RunnerFull{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *RunnerFull) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *RunnerFull) SetId(v string) {\n\to.Id = v\n}\n\n// GetDomain returns the Domain field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetDomain() string {\n\tif o == nil || IsNil(o.Domain) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Domain\n}\n\n// GetDomainOk returns a tuple with the Domain field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetDomainOk() (*string, bool) {\n\tif o == nil || IsNil(o.Domain) {\n\t\treturn nil, false\n\t}\n\treturn o.Domain, true\n}\n\n// HasDomain returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasDomain() bool {\n\tif o != nil && !IsNil(o.Domain) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDomain gets a reference to the given string and assigns it to the Domain field.\nfunc (o *RunnerFull) SetDomain(v string) {\n\to.Domain = &v\n}\n\n// GetApiUrl returns the ApiUrl field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetApiUrl() string {\n\tif o == nil || IsNil(o.ApiUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ApiUrl\n}\n\n// GetApiUrlOk returns a tuple with the ApiUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetApiUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.ApiUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.ApiUrl, true\n}\n\n// HasApiUrl returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasApiUrl() bool {\n\tif o != nil && !IsNil(o.ApiUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetApiUrl gets a reference to the given string and assigns it to the ApiUrl field.\nfunc (o *RunnerFull) SetApiUrl(v string) {\n\to.ApiUrl = &v\n}\n\n// GetProxyUrl returns the ProxyUrl field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetProxyUrl() string {\n\tif o == nil || IsNil(o.ProxyUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProxyUrl\n}\n\n// GetProxyUrlOk returns a tuple with the ProxyUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetProxyUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.ProxyUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.ProxyUrl, true\n}\n\n// HasProxyUrl returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasProxyUrl() bool {\n\tif o != nil && !IsNil(o.ProxyUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProxyUrl gets a reference to the given string and assigns it to the ProxyUrl field.\nfunc (o *RunnerFull) SetProxyUrl(v string) {\n\to.ProxyUrl = &v\n}\n\n// GetCpu returns the Cpu field value\nfunc (o *RunnerFull) GetCpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cpu, true\n}\n\n// SetCpu sets field value\nfunc (o *RunnerFull) SetCpu(v float32) {\n\to.Cpu = v\n}\n\n// GetMemory returns the Memory field value\nfunc (o *RunnerFull) GetMemory() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Memory\n}\n\n// GetMemoryOk returns a tuple with the Memory field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetMemoryOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Memory, true\n}\n\n// SetMemory sets field value\nfunc (o *RunnerFull) SetMemory(v float32) {\n\to.Memory = v\n}\n\n// GetDisk returns the Disk field value\nfunc (o *RunnerFull) GetDisk() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetDiskOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Disk, true\n}\n\n// SetDisk sets field value\nfunc (o *RunnerFull) SetDisk(v float32) {\n\to.Disk = v\n}\n\n// GetGpu returns the Gpu field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetGpu() float32 {\n\tif o == nil || IsNil(o.Gpu) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.Gpu\n}\n\n// GetGpuOk returns a tuple with the Gpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetGpuOk() (*float32, bool) {\n\tif o == nil || IsNil(o.Gpu) {\n\t\treturn nil, false\n\t}\n\treturn o.Gpu, true\n}\n\n// HasGpu returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasGpu() bool {\n\tif o != nil && !IsNil(o.Gpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetGpu gets a reference to the given float32 and assigns it to the Gpu field.\nfunc (o *RunnerFull) SetGpu(v float32) {\n\to.Gpu = &v\n}\n\n// GetGpuType returns the GpuType field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetGpuType() string {\n\tif o == nil || IsNil(o.GpuType) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.GpuType\n}\n\n// GetGpuTypeOk returns a tuple with the GpuType field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetGpuTypeOk() (*string, bool) {\n\tif o == nil || IsNil(o.GpuType) {\n\t\treturn nil, false\n\t}\n\treturn o.GpuType, true\n}\n\n// HasGpuType returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasGpuType() bool {\n\tif o != nil && !IsNil(o.GpuType) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetGpuType gets a reference to the given string and assigns it to the GpuType field.\nfunc (o *RunnerFull) SetGpuType(v string) {\n\to.GpuType = &v\n}\n\n// GetClass returns the Class field value\nfunc (o *RunnerFull) GetClass() SandboxClass {\n\tif o == nil {\n\t\tvar ret SandboxClass\n\t\treturn ret\n\t}\n\n\treturn o.Class\n}\n\n// GetClassOk returns a tuple with the Class field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetClassOk() (*SandboxClass, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Class, true\n}\n\n// SetClass sets field value\nfunc (o *RunnerFull) SetClass(v SandboxClass) {\n\to.Class = v\n}\n\n// GetCurrentCpuUsagePercentage returns the CurrentCpuUsagePercentage field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetCurrentCpuUsagePercentage() float32 {\n\tif o == nil || IsNil(o.CurrentCpuUsagePercentage) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentCpuUsagePercentage\n}\n\n// GetCurrentCpuUsagePercentageOk returns a tuple with the CurrentCpuUsagePercentage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCurrentCpuUsagePercentageOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentCpuUsagePercentage) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentCpuUsagePercentage, true\n}\n\n// HasCurrentCpuUsagePercentage returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasCurrentCpuUsagePercentage() bool {\n\tif o != nil && !IsNil(o.CurrentCpuUsagePercentage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentCpuUsagePercentage gets a reference to the given float32 and assigns it to the CurrentCpuUsagePercentage field.\nfunc (o *RunnerFull) SetCurrentCpuUsagePercentage(v float32) {\n\to.CurrentCpuUsagePercentage = &v\n}\n\n// GetCurrentMemoryUsagePercentage returns the CurrentMemoryUsagePercentage field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetCurrentMemoryUsagePercentage() float32 {\n\tif o == nil || IsNil(o.CurrentMemoryUsagePercentage) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentMemoryUsagePercentage\n}\n\n// GetCurrentMemoryUsagePercentageOk returns a tuple with the CurrentMemoryUsagePercentage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCurrentMemoryUsagePercentageOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentMemoryUsagePercentage) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentMemoryUsagePercentage, true\n}\n\n// HasCurrentMemoryUsagePercentage returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasCurrentMemoryUsagePercentage() bool {\n\tif o != nil && !IsNil(o.CurrentMemoryUsagePercentage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentMemoryUsagePercentage gets a reference to the given float32 and assigns it to the CurrentMemoryUsagePercentage field.\nfunc (o *RunnerFull) SetCurrentMemoryUsagePercentage(v float32) {\n\to.CurrentMemoryUsagePercentage = &v\n}\n\n// GetCurrentDiskUsagePercentage returns the CurrentDiskUsagePercentage field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetCurrentDiskUsagePercentage() float32 {\n\tif o == nil || IsNil(o.CurrentDiskUsagePercentage) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentDiskUsagePercentage\n}\n\n// GetCurrentDiskUsagePercentageOk returns a tuple with the CurrentDiskUsagePercentage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCurrentDiskUsagePercentageOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentDiskUsagePercentage) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentDiskUsagePercentage, true\n}\n\n// HasCurrentDiskUsagePercentage returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasCurrentDiskUsagePercentage() bool {\n\tif o != nil && !IsNil(o.CurrentDiskUsagePercentage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentDiskUsagePercentage gets a reference to the given float32 and assigns it to the CurrentDiskUsagePercentage field.\nfunc (o *RunnerFull) SetCurrentDiskUsagePercentage(v float32) {\n\to.CurrentDiskUsagePercentage = &v\n}\n\n// GetCurrentAllocatedCpu returns the CurrentAllocatedCpu field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetCurrentAllocatedCpu() float32 {\n\tif o == nil || IsNil(o.CurrentAllocatedCpu) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentAllocatedCpu\n}\n\n// GetCurrentAllocatedCpuOk returns a tuple with the CurrentAllocatedCpu field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCurrentAllocatedCpuOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentAllocatedCpu) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentAllocatedCpu, true\n}\n\n// HasCurrentAllocatedCpu returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasCurrentAllocatedCpu() bool {\n\tif o != nil && !IsNil(o.CurrentAllocatedCpu) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentAllocatedCpu gets a reference to the given float32 and assigns it to the CurrentAllocatedCpu field.\nfunc (o *RunnerFull) SetCurrentAllocatedCpu(v float32) {\n\to.CurrentAllocatedCpu = &v\n}\n\n// GetCurrentAllocatedMemoryGiB returns the CurrentAllocatedMemoryGiB field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetCurrentAllocatedMemoryGiB() float32 {\n\tif o == nil || IsNil(o.CurrentAllocatedMemoryGiB) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentAllocatedMemoryGiB\n}\n\n// GetCurrentAllocatedMemoryGiBOk returns a tuple with the CurrentAllocatedMemoryGiB field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCurrentAllocatedMemoryGiBOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentAllocatedMemoryGiB) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentAllocatedMemoryGiB, true\n}\n\n// HasCurrentAllocatedMemoryGiB returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasCurrentAllocatedMemoryGiB() bool {\n\tif o != nil && !IsNil(o.CurrentAllocatedMemoryGiB) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentAllocatedMemoryGiB gets a reference to the given float32 and assigns it to the CurrentAllocatedMemoryGiB field.\nfunc (o *RunnerFull) SetCurrentAllocatedMemoryGiB(v float32) {\n\to.CurrentAllocatedMemoryGiB = &v\n}\n\n// GetCurrentAllocatedDiskGiB returns the CurrentAllocatedDiskGiB field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetCurrentAllocatedDiskGiB() float32 {\n\tif o == nil || IsNil(o.CurrentAllocatedDiskGiB) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentAllocatedDiskGiB\n}\n\n// GetCurrentAllocatedDiskGiBOk returns a tuple with the CurrentAllocatedDiskGiB field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCurrentAllocatedDiskGiBOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentAllocatedDiskGiB) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentAllocatedDiskGiB, true\n}\n\n// HasCurrentAllocatedDiskGiB returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasCurrentAllocatedDiskGiB() bool {\n\tif o != nil && !IsNil(o.CurrentAllocatedDiskGiB) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentAllocatedDiskGiB gets a reference to the given float32 and assigns it to the CurrentAllocatedDiskGiB field.\nfunc (o *RunnerFull) SetCurrentAllocatedDiskGiB(v float32) {\n\to.CurrentAllocatedDiskGiB = &v\n}\n\n// GetCurrentSnapshotCount returns the CurrentSnapshotCount field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetCurrentSnapshotCount() float32 {\n\tif o == nil || IsNil(o.CurrentSnapshotCount) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentSnapshotCount\n}\n\n// GetCurrentSnapshotCountOk returns a tuple with the CurrentSnapshotCount field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCurrentSnapshotCountOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentSnapshotCount) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentSnapshotCount, true\n}\n\n// HasCurrentSnapshotCount returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasCurrentSnapshotCount() bool {\n\tif o != nil && !IsNil(o.CurrentSnapshotCount) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentSnapshotCount gets a reference to the given float32 and assigns it to the CurrentSnapshotCount field.\nfunc (o *RunnerFull) SetCurrentSnapshotCount(v float32) {\n\to.CurrentSnapshotCount = &v\n}\n\n// GetCurrentStartedSandboxes returns the CurrentStartedSandboxes field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetCurrentStartedSandboxes() float32 {\n\tif o == nil || IsNil(o.CurrentStartedSandboxes) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.CurrentStartedSandboxes\n}\n\n// GetCurrentStartedSandboxesOk returns a tuple with the CurrentStartedSandboxes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCurrentStartedSandboxesOk() (*float32, bool) {\n\tif o == nil || IsNil(o.CurrentStartedSandboxes) {\n\t\treturn nil, false\n\t}\n\treturn o.CurrentStartedSandboxes, true\n}\n\n// HasCurrentStartedSandboxes returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasCurrentStartedSandboxes() bool {\n\tif o != nil && !IsNil(o.CurrentStartedSandboxes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCurrentStartedSandboxes gets a reference to the given float32 and assigns it to the CurrentStartedSandboxes field.\nfunc (o *RunnerFull) SetCurrentStartedSandboxes(v float32) {\n\to.CurrentStartedSandboxes = &v\n}\n\n// GetAvailabilityScore returns the AvailabilityScore field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetAvailabilityScore() float32 {\n\tif o == nil || IsNil(o.AvailabilityScore) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.AvailabilityScore\n}\n\n// GetAvailabilityScoreOk returns a tuple with the AvailabilityScore field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetAvailabilityScoreOk() (*float32, bool) {\n\tif o == nil || IsNil(o.AvailabilityScore) {\n\t\treturn nil, false\n\t}\n\treturn o.AvailabilityScore, true\n}\n\n// HasAvailabilityScore returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasAvailabilityScore() bool {\n\tif o != nil && !IsNil(o.AvailabilityScore) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAvailabilityScore gets a reference to the given float32 and assigns it to the AvailabilityScore field.\nfunc (o *RunnerFull) SetAvailabilityScore(v float32) {\n\to.AvailabilityScore = &v\n}\n\n// GetRegion returns the Region field value\nfunc (o *RunnerFull) GetRegion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Region\n}\n\n// GetRegionOk returns a tuple with the Region field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetRegionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Region, true\n}\n\n// SetRegion sets field value\nfunc (o *RunnerFull) SetRegion(v string) {\n\to.Region = v\n}\n\n// GetName returns the Name field value\nfunc (o *RunnerFull) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *RunnerFull) SetName(v string) {\n\to.Name = v\n}\n\n// GetState returns the State field value\nfunc (o *RunnerFull) GetState() RunnerState {\n\tif o == nil {\n\t\tvar ret RunnerState\n\t\treturn ret\n\t}\n\n\treturn o.State\n}\n\n// GetStateOk returns a tuple with the State field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetStateOk() (*RunnerState, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.State, true\n}\n\n// SetState sets field value\nfunc (o *RunnerFull) SetState(v RunnerState) {\n\to.State = v\n}\n\n// GetLastChecked returns the LastChecked field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetLastChecked() string {\n\tif o == nil || IsNil(o.LastChecked) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.LastChecked\n}\n\n// GetLastCheckedOk returns a tuple with the LastChecked field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetLastCheckedOk() (*string, bool) {\n\tif o == nil || IsNil(o.LastChecked) {\n\t\treturn nil, false\n\t}\n\treturn o.LastChecked, true\n}\n\n// HasLastChecked returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasLastChecked() bool {\n\tif o != nil && !IsNil(o.LastChecked) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetLastChecked gets a reference to the given string and assigns it to the LastChecked field.\nfunc (o *RunnerFull) SetLastChecked(v string) {\n\to.LastChecked = &v\n}\n\n// GetUnschedulable returns the Unschedulable field value\nfunc (o *RunnerFull) GetUnschedulable() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Unschedulable\n}\n\n// GetUnschedulableOk returns a tuple with the Unschedulable field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetUnschedulableOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Unschedulable, true\n}\n\n// SetUnschedulable sets field value\nfunc (o *RunnerFull) SetUnschedulable(v bool) {\n\to.Unschedulable = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *RunnerFull) GetCreatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetCreatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *RunnerFull) SetCreatedAt(v string) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *RunnerFull) GetUpdatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetUpdatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *RunnerFull) SetUpdatedAt(v string) {\n\to.UpdatedAt = v\n}\n\n// GetVersion returns the Version field value\n// Deprecated\nfunc (o *RunnerFull) GetVersion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Version\n}\n\n// GetVersionOk returns a tuple with the Version field value\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *RunnerFull) GetVersionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Version, true\n}\n\n// SetVersion sets field value\n// Deprecated\nfunc (o *RunnerFull) SetVersion(v string) {\n\to.Version = v\n}\n\n// GetApiVersion returns the ApiVersion field value\n// Deprecated\nfunc (o *RunnerFull) GetApiVersion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ApiVersion\n}\n\n// GetApiVersionOk returns a tuple with the ApiVersion field value\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *RunnerFull) GetApiVersionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ApiVersion, true\n}\n\n// SetApiVersion sets field value\n// Deprecated\nfunc (o *RunnerFull) SetApiVersion(v string) {\n\to.ApiVersion = v\n}\n\n// GetAppVersion returns the AppVersion field value if set, zero value otherwise.\n// Deprecated\nfunc (o *RunnerFull) GetAppVersion() string {\n\tif o == nil || IsNil(o.AppVersion) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.AppVersion\n}\n\n// GetAppVersionOk returns a tuple with the AppVersion field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *RunnerFull) GetAppVersionOk() (*string, bool) {\n\tif o == nil || IsNil(o.AppVersion) {\n\t\treturn nil, false\n\t}\n\treturn o.AppVersion, true\n}\n\n// HasAppVersion returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasAppVersion() bool {\n\tif o != nil && !IsNil(o.AppVersion) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAppVersion gets a reference to the given string and assigns it to the AppVersion field.\n// Deprecated\nfunc (o *RunnerFull) SetAppVersion(v string) {\n\to.AppVersion = &v\n}\n\n// GetApiKey returns the ApiKey field value\nfunc (o *RunnerFull) GetApiKey() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ApiKey\n}\n\n// GetApiKeyOk returns a tuple with the ApiKey field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetApiKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ApiKey, true\n}\n\n// SetApiKey sets field value\nfunc (o *RunnerFull) SetApiKey(v string) {\n\to.ApiKey = v\n}\n\n// GetRegionType returns the RegionType field value if set, zero value otherwise.\nfunc (o *RunnerFull) GetRegionType() RegionType {\n\tif o == nil || IsNil(o.RegionType) {\n\t\tvar ret RegionType\n\t\treturn ret\n\t}\n\treturn *o.RegionType\n}\n\n// GetRegionTypeOk returns a tuple with the RegionType field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerFull) GetRegionTypeOk() (*RegionType, bool) {\n\tif o == nil || IsNil(o.RegionType) {\n\t\treturn nil, false\n\t}\n\treturn o.RegionType, true\n}\n\n// HasRegionType returns a boolean if a field has been set.\nfunc (o *RunnerFull) HasRegionType() bool {\n\tif o != nil && !IsNil(o.RegionType) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRegionType gets a reference to the given RegionType and assigns it to the RegionType field.\nfunc (o *RunnerFull) SetRegionType(v RegionType) {\n\to.RegionType = &v\n}\n\nfunc (o RunnerFull) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RunnerFull) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\tif !IsNil(o.Domain) {\n\t\ttoSerialize[\"domain\"] = o.Domain\n\t}\n\tif !IsNil(o.ApiUrl) {\n\t\ttoSerialize[\"apiUrl\"] = o.ApiUrl\n\t}\n\tif !IsNil(o.ProxyUrl) {\n\t\ttoSerialize[\"proxyUrl\"] = o.ProxyUrl\n\t}\n\ttoSerialize[\"cpu\"] = o.Cpu\n\ttoSerialize[\"memory\"] = o.Memory\n\ttoSerialize[\"disk\"] = o.Disk\n\tif !IsNil(o.Gpu) {\n\t\ttoSerialize[\"gpu\"] = o.Gpu\n\t}\n\tif !IsNil(o.GpuType) {\n\t\ttoSerialize[\"gpuType\"] = o.GpuType\n\t}\n\ttoSerialize[\"class\"] = o.Class\n\tif !IsNil(o.CurrentCpuUsagePercentage) {\n\t\ttoSerialize[\"currentCpuUsagePercentage\"] = o.CurrentCpuUsagePercentage\n\t}\n\tif !IsNil(o.CurrentMemoryUsagePercentage) {\n\t\ttoSerialize[\"currentMemoryUsagePercentage\"] = o.CurrentMemoryUsagePercentage\n\t}\n\tif !IsNil(o.CurrentDiskUsagePercentage) {\n\t\ttoSerialize[\"currentDiskUsagePercentage\"] = o.CurrentDiskUsagePercentage\n\t}\n\tif !IsNil(o.CurrentAllocatedCpu) {\n\t\ttoSerialize[\"currentAllocatedCpu\"] = o.CurrentAllocatedCpu\n\t}\n\tif !IsNil(o.CurrentAllocatedMemoryGiB) {\n\t\ttoSerialize[\"currentAllocatedMemoryGiB\"] = o.CurrentAllocatedMemoryGiB\n\t}\n\tif !IsNil(o.CurrentAllocatedDiskGiB) {\n\t\ttoSerialize[\"currentAllocatedDiskGiB\"] = o.CurrentAllocatedDiskGiB\n\t}\n\tif !IsNil(o.CurrentSnapshotCount) {\n\t\ttoSerialize[\"currentSnapshotCount\"] = o.CurrentSnapshotCount\n\t}\n\tif !IsNil(o.CurrentStartedSandboxes) {\n\t\ttoSerialize[\"currentStartedSandboxes\"] = o.CurrentStartedSandboxes\n\t}\n\tif !IsNil(o.AvailabilityScore) {\n\t\ttoSerialize[\"availabilityScore\"] = o.AvailabilityScore\n\t}\n\ttoSerialize[\"region\"] = o.Region\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"state\"] = o.State\n\tif !IsNil(o.LastChecked) {\n\t\ttoSerialize[\"lastChecked\"] = o.LastChecked\n\t}\n\ttoSerialize[\"unschedulable\"] = o.Unschedulable\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\ttoSerialize[\"version\"] = o.Version\n\ttoSerialize[\"apiVersion\"] = o.ApiVersion\n\tif !IsNil(o.AppVersion) {\n\t\ttoSerialize[\"appVersion\"] = o.AppVersion\n\t}\n\ttoSerialize[\"apiKey\"] = o.ApiKey\n\tif !IsNil(o.RegionType) {\n\t\ttoSerialize[\"regionType\"] = o.RegionType\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RunnerFull) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"cpu\",\n\t\t\"memory\",\n\t\t\"disk\",\n\t\t\"class\",\n\t\t\"region\",\n\t\t\"name\",\n\t\t\"state\",\n\t\t\"unschedulable\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t\t\"version\",\n\t\t\"apiVersion\",\n\t\t\"apiKey\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRunnerFull := _RunnerFull{}\n\n\terr = json.Unmarshal(data, &varRunnerFull)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RunnerFull(varRunnerFull)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"domain\")\n\t\tdelete(additionalProperties, \"apiUrl\")\n\t\tdelete(additionalProperties, \"proxyUrl\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"memory\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\tdelete(additionalProperties, \"gpu\")\n\t\tdelete(additionalProperties, \"gpuType\")\n\t\tdelete(additionalProperties, \"class\")\n\t\tdelete(additionalProperties, \"currentCpuUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentMemoryUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentDiskUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentAllocatedCpu\")\n\t\tdelete(additionalProperties, \"currentAllocatedMemoryGiB\")\n\t\tdelete(additionalProperties, \"currentAllocatedDiskGiB\")\n\t\tdelete(additionalProperties, \"currentSnapshotCount\")\n\t\tdelete(additionalProperties, \"currentStartedSandboxes\")\n\t\tdelete(additionalProperties, \"availabilityScore\")\n\t\tdelete(additionalProperties, \"region\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"state\")\n\t\tdelete(additionalProperties, \"lastChecked\")\n\t\tdelete(additionalProperties, \"unschedulable\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"version\")\n\t\tdelete(additionalProperties, \"apiVersion\")\n\t\tdelete(additionalProperties, \"appVersion\")\n\t\tdelete(additionalProperties, \"apiKey\")\n\t\tdelete(additionalProperties, \"regionType\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRunnerFull struct {\n\tvalue *RunnerFull\n\tisSet bool\n}\n\nfunc (v NullableRunnerFull) Get() *RunnerFull {\n\treturn v.value\n}\n\nfunc (v *NullableRunnerFull) Set(val *RunnerFull) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRunnerFull) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRunnerFull) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRunnerFull(val *RunnerFull) *NullableRunnerFull {\n\treturn &NullableRunnerFull{value: val, isSet: true}\n}\n\nfunc (v NullableRunnerFull) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRunnerFull) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_runner_health_metrics.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RunnerHealthMetrics type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RunnerHealthMetrics{}\n\n// RunnerHealthMetrics struct for RunnerHealthMetrics\ntype RunnerHealthMetrics struct {\n\t// Current CPU load average\n\tCurrentCpuLoadAverage float32 `json:\"currentCpuLoadAverage\"`\n\t// Current CPU usage percentage\n\tCurrentCpuUsagePercentage float32 `json:\"currentCpuUsagePercentage\"`\n\t// Current memory usage percentage\n\tCurrentMemoryUsagePercentage float32 `json:\"currentMemoryUsagePercentage\"`\n\t// Current disk usage percentage\n\tCurrentDiskUsagePercentage float32 `json:\"currentDiskUsagePercentage\"`\n\t// Currently allocated CPU cores\n\tCurrentAllocatedCpu float32 `json:\"currentAllocatedCpu\"`\n\t// Currently allocated memory in GiB\n\tCurrentAllocatedMemoryGiB float32 `json:\"currentAllocatedMemoryGiB\"`\n\t// Currently allocated disk in GiB\n\tCurrentAllocatedDiskGiB float32 `json:\"currentAllocatedDiskGiB\"`\n\t// Number of snapshots currently stored\n\tCurrentSnapshotCount float32 `json:\"currentSnapshotCount\"`\n\t// Number of started sandboxes\n\tCurrentStartedSandboxes float32 `json:\"currentStartedSandboxes\"`\n\t// Total CPU cores on the runner\n\tCpu float32 `json:\"cpu\"`\n\t// Total RAM in GiB on the runner\n\tMemoryGiB float32 `json:\"memoryGiB\"`\n\t// Total disk space in GiB on the runner\n\tDiskGiB float32 `json:\"diskGiB\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RunnerHealthMetrics RunnerHealthMetrics\n\n// NewRunnerHealthMetrics instantiates a new RunnerHealthMetrics object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRunnerHealthMetrics(currentCpuLoadAverage float32, currentCpuUsagePercentage float32, currentMemoryUsagePercentage float32, currentDiskUsagePercentage float32, currentAllocatedCpu float32, currentAllocatedMemoryGiB float32, currentAllocatedDiskGiB float32, currentSnapshotCount float32, currentStartedSandboxes float32, cpu float32, memoryGiB float32, diskGiB float32) *RunnerHealthMetrics {\n\tthis := RunnerHealthMetrics{}\n\tthis.CurrentCpuLoadAverage = currentCpuLoadAverage\n\tthis.CurrentCpuUsagePercentage = currentCpuUsagePercentage\n\tthis.CurrentMemoryUsagePercentage = currentMemoryUsagePercentage\n\tthis.CurrentDiskUsagePercentage = currentDiskUsagePercentage\n\tthis.CurrentAllocatedCpu = currentAllocatedCpu\n\tthis.CurrentAllocatedMemoryGiB = currentAllocatedMemoryGiB\n\tthis.CurrentAllocatedDiskGiB = currentAllocatedDiskGiB\n\tthis.CurrentSnapshotCount = currentSnapshotCount\n\tthis.CurrentStartedSandboxes = currentStartedSandboxes\n\tthis.Cpu = cpu\n\tthis.MemoryGiB = memoryGiB\n\tthis.DiskGiB = diskGiB\n\treturn &this\n}\n\n// NewRunnerHealthMetricsWithDefaults instantiates a new RunnerHealthMetrics object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRunnerHealthMetricsWithDefaults() *RunnerHealthMetrics {\n\tthis := RunnerHealthMetrics{}\n\treturn &this\n}\n\n// GetCurrentCpuLoadAverage returns the CurrentCpuLoadAverage field value\nfunc (o *RunnerHealthMetrics) GetCurrentCpuLoadAverage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentCpuLoadAverage\n}\n\n// GetCurrentCpuLoadAverageOk returns a tuple with the CurrentCpuLoadAverage field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentCpuLoadAverageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentCpuLoadAverage, true\n}\n\n// SetCurrentCpuLoadAverage sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentCpuLoadAverage(v float32) {\n\to.CurrentCpuLoadAverage = v\n}\n\n// GetCurrentCpuUsagePercentage returns the CurrentCpuUsagePercentage field value\nfunc (o *RunnerHealthMetrics) GetCurrentCpuUsagePercentage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentCpuUsagePercentage\n}\n\n// GetCurrentCpuUsagePercentageOk returns a tuple with the CurrentCpuUsagePercentage field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentCpuUsagePercentageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentCpuUsagePercentage, true\n}\n\n// SetCurrentCpuUsagePercentage sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentCpuUsagePercentage(v float32) {\n\to.CurrentCpuUsagePercentage = v\n}\n\n// GetCurrentMemoryUsagePercentage returns the CurrentMemoryUsagePercentage field value\nfunc (o *RunnerHealthMetrics) GetCurrentMemoryUsagePercentage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentMemoryUsagePercentage\n}\n\n// GetCurrentMemoryUsagePercentageOk returns a tuple with the CurrentMemoryUsagePercentage field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentMemoryUsagePercentageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentMemoryUsagePercentage, true\n}\n\n// SetCurrentMemoryUsagePercentage sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentMemoryUsagePercentage(v float32) {\n\to.CurrentMemoryUsagePercentage = v\n}\n\n// GetCurrentDiskUsagePercentage returns the CurrentDiskUsagePercentage field value\nfunc (o *RunnerHealthMetrics) GetCurrentDiskUsagePercentage() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentDiskUsagePercentage\n}\n\n// GetCurrentDiskUsagePercentageOk returns a tuple with the CurrentDiskUsagePercentage field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentDiskUsagePercentageOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentDiskUsagePercentage, true\n}\n\n// SetCurrentDiskUsagePercentage sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentDiskUsagePercentage(v float32) {\n\to.CurrentDiskUsagePercentage = v\n}\n\n// GetCurrentAllocatedCpu returns the CurrentAllocatedCpu field value\nfunc (o *RunnerHealthMetrics) GetCurrentAllocatedCpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentAllocatedCpu\n}\n\n// GetCurrentAllocatedCpuOk returns a tuple with the CurrentAllocatedCpu field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentAllocatedCpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentAllocatedCpu, true\n}\n\n// SetCurrentAllocatedCpu sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentAllocatedCpu(v float32) {\n\to.CurrentAllocatedCpu = v\n}\n\n// GetCurrentAllocatedMemoryGiB returns the CurrentAllocatedMemoryGiB field value\nfunc (o *RunnerHealthMetrics) GetCurrentAllocatedMemoryGiB() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentAllocatedMemoryGiB\n}\n\n// GetCurrentAllocatedMemoryGiBOk returns a tuple with the CurrentAllocatedMemoryGiB field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentAllocatedMemoryGiBOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentAllocatedMemoryGiB, true\n}\n\n// SetCurrentAllocatedMemoryGiB sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentAllocatedMemoryGiB(v float32) {\n\to.CurrentAllocatedMemoryGiB = v\n}\n\n// GetCurrentAllocatedDiskGiB returns the CurrentAllocatedDiskGiB field value\nfunc (o *RunnerHealthMetrics) GetCurrentAllocatedDiskGiB() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentAllocatedDiskGiB\n}\n\n// GetCurrentAllocatedDiskGiBOk returns a tuple with the CurrentAllocatedDiskGiB field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentAllocatedDiskGiBOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentAllocatedDiskGiB, true\n}\n\n// SetCurrentAllocatedDiskGiB sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentAllocatedDiskGiB(v float32) {\n\to.CurrentAllocatedDiskGiB = v\n}\n\n// GetCurrentSnapshotCount returns the CurrentSnapshotCount field value\nfunc (o *RunnerHealthMetrics) GetCurrentSnapshotCount() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentSnapshotCount\n}\n\n// GetCurrentSnapshotCountOk returns a tuple with the CurrentSnapshotCount field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentSnapshotCountOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentSnapshotCount, true\n}\n\n// SetCurrentSnapshotCount sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentSnapshotCount(v float32) {\n\to.CurrentSnapshotCount = v\n}\n\n// GetCurrentStartedSandboxes returns the CurrentStartedSandboxes field value\nfunc (o *RunnerHealthMetrics) GetCurrentStartedSandboxes() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.CurrentStartedSandboxes\n}\n\n// GetCurrentStartedSandboxesOk returns a tuple with the CurrentStartedSandboxes field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCurrentStartedSandboxesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CurrentStartedSandboxes, true\n}\n\n// SetCurrentStartedSandboxes sets field value\nfunc (o *RunnerHealthMetrics) SetCurrentStartedSandboxes(v float32) {\n\to.CurrentStartedSandboxes = v\n}\n\n// GetCpu returns the Cpu field value\nfunc (o *RunnerHealthMetrics) GetCpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetCpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cpu, true\n}\n\n// SetCpu sets field value\nfunc (o *RunnerHealthMetrics) SetCpu(v float32) {\n\to.Cpu = v\n}\n\n// GetMemoryGiB returns the MemoryGiB field value\nfunc (o *RunnerHealthMetrics) GetMemoryGiB() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.MemoryGiB\n}\n\n// GetMemoryGiBOk returns a tuple with the MemoryGiB field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetMemoryGiBOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.MemoryGiB, true\n}\n\n// SetMemoryGiB sets field value\nfunc (o *RunnerHealthMetrics) SetMemoryGiB(v float32) {\n\to.MemoryGiB = v\n}\n\n// GetDiskGiB returns the DiskGiB field value\nfunc (o *RunnerHealthMetrics) GetDiskGiB() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.DiskGiB\n}\n\n// GetDiskGiBOk returns a tuple with the DiskGiB field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthMetrics) GetDiskGiBOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DiskGiB, true\n}\n\n// SetDiskGiB sets field value\nfunc (o *RunnerHealthMetrics) SetDiskGiB(v float32) {\n\to.DiskGiB = v\n}\n\nfunc (o RunnerHealthMetrics) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RunnerHealthMetrics) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"currentCpuLoadAverage\"] = o.CurrentCpuLoadAverage\n\ttoSerialize[\"currentCpuUsagePercentage\"] = o.CurrentCpuUsagePercentage\n\ttoSerialize[\"currentMemoryUsagePercentage\"] = o.CurrentMemoryUsagePercentage\n\ttoSerialize[\"currentDiskUsagePercentage\"] = o.CurrentDiskUsagePercentage\n\ttoSerialize[\"currentAllocatedCpu\"] = o.CurrentAllocatedCpu\n\ttoSerialize[\"currentAllocatedMemoryGiB\"] = o.CurrentAllocatedMemoryGiB\n\ttoSerialize[\"currentAllocatedDiskGiB\"] = o.CurrentAllocatedDiskGiB\n\ttoSerialize[\"currentSnapshotCount\"] = o.CurrentSnapshotCount\n\ttoSerialize[\"currentStartedSandboxes\"] = o.CurrentStartedSandboxes\n\ttoSerialize[\"cpu\"] = o.Cpu\n\ttoSerialize[\"memoryGiB\"] = o.MemoryGiB\n\ttoSerialize[\"diskGiB\"] = o.DiskGiB\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RunnerHealthMetrics) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"currentCpuLoadAverage\",\n\t\t\"currentCpuUsagePercentage\",\n\t\t\"currentMemoryUsagePercentage\",\n\t\t\"currentDiskUsagePercentage\",\n\t\t\"currentAllocatedCpu\",\n\t\t\"currentAllocatedMemoryGiB\",\n\t\t\"currentAllocatedDiskGiB\",\n\t\t\"currentSnapshotCount\",\n\t\t\"currentStartedSandboxes\",\n\t\t\"cpu\",\n\t\t\"memoryGiB\",\n\t\t\"diskGiB\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRunnerHealthMetrics := _RunnerHealthMetrics{}\n\n\terr = json.Unmarshal(data, &varRunnerHealthMetrics)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RunnerHealthMetrics(varRunnerHealthMetrics)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"currentCpuLoadAverage\")\n\t\tdelete(additionalProperties, \"currentCpuUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentMemoryUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentDiskUsagePercentage\")\n\t\tdelete(additionalProperties, \"currentAllocatedCpu\")\n\t\tdelete(additionalProperties, \"currentAllocatedMemoryGiB\")\n\t\tdelete(additionalProperties, \"currentAllocatedDiskGiB\")\n\t\tdelete(additionalProperties, \"currentSnapshotCount\")\n\t\tdelete(additionalProperties, \"currentStartedSandboxes\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"memoryGiB\")\n\t\tdelete(additionalProperties, \"diskGiB\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRunnerHealthMetrics struct {\n\tvalue *RunnerHealthMetrics\n\tisSet bool\n}\n\nfunc (v NullableRunnerHealthMetrics) Get() *RunnerHealthMetrics {\n\treturn v.value\n}\n\nfunc (v *NullableRunnerHealthMetrics) Set(val *RunnerHealthMetrics) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRunnerHealthMetrics) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRunnerHealthMetrics) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRunnerHealthMetrics(val *RunnerHealthMetrics) *NullableRunnerHealthMetrics {\n\treturn &NullableRunnerHealthMetrics{value: val, isSet: true}\n}\n\nfunc (v NullableRunnerHealthMetrics) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRunnerHealthMetrics) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_runner_healthcheck.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RunnerHealthcheck type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RunnerHealthcheck{}\n\n// RunnerHealthcheck struct for RunnerHealthcheck\ntype RunnerHealthcheck struct {\n\t// Runner metrics\n\tMetrics *RunnerHealthMetrics `json:\"metrics,omitempty\"`\n\t// Health status of individual services on the runner\n\tServiceHealth []RunnerServiceHealth `json:\"serviceHealth,omitempty\"`\n\t// Runner domain\n\tDomain *string `json:\"domain,omitempty\"`\n\t// Runner proxy URL\n\tProxyUrl *string `json:\"proxyUrl,omitempty\"`\n\t// Runner API URL\n\tApiUrl *string `json:\"apiUrl,omitempty\"`\n\t// Runner app version\n\tAppVersion string `json:\"appVersion\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RunnerHealthcheck RunnerHealthcheck\n\n// NewRunnerHealthcheck instantiates a new RunnerHealthcheck object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRunnerHealthcheck(appVersion string) *RunnerHealthcheck {\n\tthis := RunnerHealthcheck{}\n\tthis.AppVersion = appVersion\n\treturn &this\n}\n\n// NewRunnerHealthcheckWithDefaults instantiates a new RunnerHealthcheck object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRunnerHealthcheckWithDefaults() *RunnerHealthcheck {\n\tthis := RunnerHealthcheck{}\n\treturn &this\n}\n\n// GetMetrics returns the Metrics field value if set, zero value otherwise.\nfunc (o *RunnerHealthcheck) GetMetrics() RunnerHealthMetrics {\n\tif o == nil || IsNil(o.Metrics) {\n\t\tvar ret RunnerHealthMetrics\n\t\treturn ret\n\t}\n\treturn *o.Metrics\n}\n\n// GetMetricsOk returns a tuple with the Metrics field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthcheck) GetMetricsOk() (*RunnerHealthMetrics, bool) {\n\tif o == nil || IsNil(o.Metrics) {\n\t\treturn nil, false\n\t}\n\treturn o.Metrics, true\n}\n\n// HasMetrics returns a boolean if a field has been set.\nfunc (o *RunnerHealthcheck) HasMetrics() bool {\n\tif o != nil && !IsNil(o.Metrics) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetMetrics gets a reference to the given RunnerHealthMetrics and assigns it to the Metrics field.\nfunc (o *RunnerHealthcheck) SetMetrics(v RunnerHealthMetrics) {\n\to.Metrics = &v\n}\n\n// GetServiceHealth returns the ServiceHealth field value if set, zero value otherwise.\nfunc (o *RunnerHealthcheck) GetServiceHealth() []RunnerServiceHealth {\n\tif o == nil || IsNil(o.ServiceHealth) {\n\t\tvar ret []RunnerServiceHealth\n\t\treturn ret\n\t}\n\treturn o.ServiceHealth\n}\n\n// GetServiceHealthOk returns a tuple with the ServiceHealth field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthcheck) GetServiceHealthOk() ([]RunnerServiceHealth, bool) {\n\tif o == nil || IsNil(o.ServiceHealth) {\n\t\treturn nil, false\n\t}\n\treturn o.ServiceHealth, true\n}\n\n// HasServiceHealth returns a boolean if a field has been set.\nfunc (o *RunnerHealthcheck) HasServiceHealth() bool {\n\tif o != nil && !IsNil(o.ServiceHealth) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetServiceHealth gets a reference to the given []RunnerServiceHealth and assigns it to the ServiceHealth field.\nfunc (o *RunnerHealthcheck) SetServiceHealth(v []RunnerServiceHealth) {\n\to.ServiceHealth = v\n}\n\n// GetDomain returns the Domain field value if set, zero value otherwise.\nfunc (o *RunnerHealthcheck) GetDomain() string {\n\tif o == nil || IsNil(o.Domain) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Domain\n}\n\n// GetDomainOk returns a tuple with the Domain field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthcheck) GetDomainOk() (*string, bool) {\n\tif o == nil || IsNil(o.Domain) {\n\t\treturn nil, false\n\t}\n\treturn o.Domain, true\n}\n\n// HasDomain returns a boolean if a field has been set.\nfunc (o *RunnerHealthcheck) HasDomain() bool {\n\tif o != nil && !IsNil(o.Domain) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDomain gets a reference to the given string and assigns it to the Domain field.\nfunc (o *RunnerHealthcheck) SetDomain(v string) {\n\to.Domain = &v\n}\n\n// GetProxyUrl returns the ProxyUrl field value if set, zero value otherwise.\nfunc (o *RunnerHealthcheck) GetProxyUrl() string {\n\tif o == nil || IsNil(o.ProxyUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProxyUrl\n}\n\n// GetProxyUrlOk returns a tuple with the ProxyUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthcheck) GetProxyUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.ProxyUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.ProxyUrl, true\n}\n\n// HasProxyUrl returns a boolean if a field has been set.\nfunc (o *RunnerHealthcheck) HasProxyUrl() bool {\n\tif o != nil && !IsNil(o.ProxyUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProxyUrl gets a reference to the given string and assigns it to the ProxyUrl field.\nfunc (o *RunnerHealthcheck) SetProxyUrl(v string) {\n\to.ProxyUrl = &v\n}\n\n// GetApiUrl returns the ApiUrl field value if set, zero value otherwise.\nfunc (o *RunnerHealthcheck) GetApiUrl() string {\n\tif o == nil || IsNil(o.ApiUrl) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ApiUrl\n}\n\n// GetApiUrlOk returns a tuple with the ApiUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthcheck) GetApiUrlOk() (*string, bool) {\n\tif o == nil || IsNil(o.ApiUrl) {\n\t\treturn nil, false\n\t}\n\treturn o.ApiUrl, true\n}\n\n// HasApiUrl returns a boolean if a field has been set.\nfunc (o *RunnerHealthcheck) HasApiUrl() bool {\n\tif o != nil && !IsNil(o.ApiUrl) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetApiUrl gets a reference to the given string and assigns it to the ApiUrl field.\nfunc (o *RunnerHealthcheck) SetApiUrl(v string) {\n\to.ApiUrl = &v\n}\n\n// GetAppVersion returns the AppVersion field value\nfunc (o *RunnerHealthcheck) GetAppVersion() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.AppVersion\n}\n\n// GetAppVersionOk returns a tuple with the AppVersion field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerHealthcheck) GetAppVersionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.AppVersion, true\n}\n\n// SetAppVersion sets field value\nfunc (o *RunnerHealthcheck) SetAppVersion(v string) {\n\to.AppVersion = v\n}\n\nfunc (o RunnerHealthcheck) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RunnerHealthcheck) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Metrics) {\n\t\ttoSerialize[\"metrics\"] = o.Metrics\n\t}\n\tif !IsNil(o.ServiceHealth) {\n\t\ttoSerialize[\"serviceHealth\"] = o.ServiceHealth\n\t}\n\tif !IsNil(o.Domain) {\n\t\ttoSerialize[\"domain\"] = o.Domain\n\t}\n\tif !IsNil(o.ProxyUrl) {\n\t\ttoSerialize[\"proxyUrl\"] = o.ProxyUrl\n\t}\n\tif !IsNil(o.ApiUrl) {\n\t\ttoSerialize[\"apiUrl\"] = o.ApiUrl\n\t}\n\ttoSerialize[\"appVersion\"] = o.AppVersion\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RunnerHealthcheck) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"appVersion\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRunnerHealthcheck := _RunnerHealthcheck{}\n\n\terr = json.Unmarshal(data, &varRunnerHealthcheck)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RunnerHealthcheck(varRunnerHealthcheck)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"metrics\")\n\t\tdelete(additionalProperties, \"serviceHealth\")\n\t\tdelete(additionalProperties, \"domain\")\n\t\tdelete(additionalProperties, \"proxyUrl\")\n\t\tdelete(additionalProperties, \"apiUrl\")\n\t\tdelete(additionalProperties, \"appVersion\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRunnerHealthcheck struct {\n\tvalue *RunnerHealthcheck\n\tisSet bool\n}\n\nfunc (v NullableRunnerHealthcheck) Get() *RunnerHealthcheck {\n\treturn v.value\n}\n\nfunc (v *NullableRunnerHealthcheck) Set(val *RunnerHealthcheck) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRunnerHealthcheck) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRunnerHealthcheck) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRunnerHealthcheck(val *RunnerHealthcheck) *NullableRunnerHealthcheck {\n\treturn &NullableRunnerHealthcheck{value: val, isSet: true}\n}\n\nfunc (v NullableRunnerHealthcheck) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRunnerHealthcheck) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_runner_service_health.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RunnerServiceHealth type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RunnerServiceHealth{}\n\n// RunnerServiceHealth struct for RunnerServiceHealth\ntype RunnerServiceHealth struct {\n\t// Name of the service being checked\n\tServiceName string `json:\"serviceName\"`\n\t// Whether the service is healthy\n\tHealthy bool `json:\"healthy\"`\n\t// Error reason if the service is unhealthy\n\tErrorReason *string `json:\"errorReason,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RunnerServiceHealth RunnerServiceHealth\n\n// NewRunnerServiceHealth instantiates a new RunnerServiceHealth object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRunnerServiceHealth(serviceName string, healthy bool) *RunnerServiceHealth {\n\tthis := RunnerServiceHealth{}\n\tthis.ServiceName = serviceName\n\tthis.Healthy = healthy\n\treturn &this\n}\n\n// NewRunnerServiceHealthWithDefaults instantiates a new RunnerServiceHealth object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRunnerServiceHealthWithDefaults() *RunnerServiceHealth {\n\tthis := RunnerServiceHealth{}\n\treturn &this\n}\n\n// GetServiceName returns the ServiceName field value\nfunc (o *RunnerServiceHealth) GetServiceName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ServiceName\n}\n\n// GetServiceNameOk returns a tuple with the ServiceName field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerServiceHealth) GetServiceNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ServiceName, true\n}\n\n// SetServiceName sets field value\nfunc (o *RunnerServiceHealth) SetServiceName(v string) {\n\to.ServiceName = v\n}\n\n// GetHealthy returns the Healthy field value\nfunc (o *RunnerServiceHealth) GetHealthy() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Healthy\n}\n\n// GetHealthyOk returns a tuple with the Healthy field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerServiceHealth) GetHealthyOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Healthy, true\n}\n\n// SetHealthy sets field value\nfunc (o *RunnerServiceHealth) SetHealthy(v bool) {\n\to.Healthy = v\n}\n\n// GetErrorReason returns the ErrorReason field value if set, zero value otherwise.\nfunc (o *RunnerServiceHealth) GetErrorReason() string {\n\tif o == nil || IsNil(o.ErrorReason) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ErrorReason\n}\n\n// GetErrorReasonOk returns a tuple with the ErrorReason field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerServiceHealth) GetErrorReasonOk() (*string, bool) {\n\tif o == nil || IsNil(o.ErrorReason) {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorReason, true\n}\n\n// HasErrorReason returns a boolean if a field has been set.\nfunc (o *RunnerServiceHealth) HasErrorReason() bool {\n\tif o != nil && !IsNil(o.ErrorReason) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetErrorReason gets a reference to the given string and assigns it to the ErrorReason field.\nfunc (o *RunnerServiceHealth) SetErrorReason(v string) {\n\to.ErrorReason = &v\n}\n\nfunc (o RunnerServiceHealth) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RunnerServiceHealth) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"serviceName\"] = o.ServiceName\n\ttoSerialize[\"healthy\"] = o.Healthy\n\tif !IsNil(o.ErrorReason) {\n\t\ttoSerialize[\"errorReason\"] = o.ErrorReason\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RunnerServiceHealth) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"serviceName\",\n\t\t\"healthy\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRunnerServiceHealth := _RunnerServiceHealth{}\n\n\terr = json.Unmarshal(data, &varRunnerServiceHealth)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RunnerServiceHealth(varRunnerServiceHealth)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"serviceName\")\n\t\tdelete(additionalProperties, \"healthy\")\n\t\tdelete(additionalProperties, \"errorReason\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRunnerServiceHealth struct {\n\tvalue *RunnerServiceHealth\n\tisSet bool\n}\n\nfunc (v NullableRunnerServiceHealth) Get() *RunnerServiceHealth {\n\treturn v.value\n}\n\nfunc (v *NullableRunnerServiceHealth) Set(val *RunnerServiceHealth) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRunnerServiceHealth) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRunnerServiceHealth) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRunnerServiceHealth(val *RunnerServiceHealth) *NullableRunnerServiceHealth {\n\treturn &NullableRunnerServiceHealth{value: val, isSet: true}\n}\n\nfunc (v NullableRunnerServiceHealth) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRunnerServiceHealth) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_runner_snapshot_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the RunnerSnapshotDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &RunnerSnapshotDto{}\n\n// RunnerSnapshotDto struct for RunnerSnapshotDto\ntype RunnerSnapshotDto struct {\n\t// Runner snapshot ID\n\tRunnerSnapshotId string `json:\"runnerSnapshotId\"`\n\t// Runner ID\n\tRunnerId string `json:\"runnerId\"`\n\t// Runner domain\n\tRunnerDomain *string `json:\"runnerDomain,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _RunnerSnapshotDto RunnerSnapshotDto\n\n// NewRunnerSnapshotDto instantiates a new RunnerSnapshotDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewRunnerSnapshotDto(runnerSnapshotId string, runnerId string) *RunnerSnapshotDto {\n\tthis := RunnerSnapshotDto{}\n\tthis.RunnerSnapshotId = runnerSnapshotId\n\tthis.RunnerId = runnerId\n\treturn &this\n}\n\n// NewRunnerSnapshotDtoWithDefaults instantiates a new RunnerSnapshotDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewRunnerSnapshotDtoWithDefaults() *RunnerSnapshotDto {\n\tthis := RunnerSnapshotDto{}\n\treturn &this\n}\n\n// GetRunnerSnapshotId returns the RunnerSnapshotId field value\nfunc (o *RunnerSnapshotDto) GetRunnerSnapshotId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RunnerSnapshotId\n}\n\n// GetRunnerSnapshotIdOk returns a tuple with the RunnerSnapshotId field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerSnapshotDto) GetRunnerSnapshotIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RunnerSnapshotId, true\n}\n\n// SetRunnerSnapshotId sets field value\nfunc (o *RunnerSnapshotDto) SetRunnerSnapshotId(v string) {\n\to.RunnerSnapshotId = v\n}\n\n// GetRunnerId returns the RunnerId field value\nfunc (o *RunnerSnapshotDto) GetRunnerId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RunnerId\n}\n\n// GetRunnerIdOk returns a tuple with the RunnerId field value\n// and a boolean to check if the value has been set.\nfunc (o *RunnerSnapshotDto) GetRunnerIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RunnerId, true\n}\n\n// SetRunnerId sets field value\nfunc (o *RunnerSnapshotDto) SetRunnerId(v string) {\n\to.RunnerId = v\n}\n\n// GetRunnerDomain returns the RunnerDomain field value if set, zero value otherwise.\nfunc (o *RunnerSnapshotDto) GetRunnerDomain() string {\n\tif o == nil || IsNil(o.RunnerDomain) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.RunnerDomain\n}\n\n// GetRunnerDomainOk returns a tuple with the RunnerDomain field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *RunnerSnapshotDto) GetRunnerDomainOk() (*string, bool) {\n\tif o == nil || IsNil(o.RunnerDomain) {\n\t\treturn nil, false\n\t}\n\treturn o.RunnerDomain, true\n}\n\n// HasRunnerDomain returns a boolean if a field has been set.\nfunc (o *RunnerSnapshotDto) HasRunnerDomain() bool {\n\tif o != nil && !IsNil(o.RunnerDomain) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRunnerDomain gets a reference to the given string and assigns it to the RunnerDomain field.\nfunc (o *RunnerSnapshotDto) SetRunnerDomain(v string) {\n\to.RunnerDomain = &v\n}\n\nfunc (o RunnerSnapshotDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o RunnerSnapshotDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"runnerSnapshotId\"] = o.RunnerSnapshotId\n\ttoSerialize[\"runnerId\"] = o.RunnerId\n\tif !IsNil(o.RunnerDomain) {\n\t\ttoSerialize[\"runnerDomain\"] = o.RunnerDomain\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *RunnerSnapshotDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"runnerSnapshotId\",\n\t\t\"runnerId\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarRunnerSnapshotDto := _RunnerSnapshotDto{}\n\n\terr = json.Unmarshal(data, &varRunnerSnapshotDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = RunnerSnapshotDto(varRunnerSnapshotDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"runnerSnapshotId\")\n\t\tdelete(additionalProperties, \"runnerId\")\n\t\tdelete(additionalProperties, \"runnerDomain\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableRunnerSnapshotDto struct {\n\tvalue *RunnerSnapshotDto\n\tisSet bool\n}\n\nfunc (v NullableRunnerSnapshotDto) Get() *RunnerSnapshotDto {\n\treturn v.value\n}\n\nfunc (v *NullableRunnerSnapshotDto) Set(val *RunnerSnapshotDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRunnerSnapshotDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRunnerSnapshotDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRunnerSnapshotDto(val *RunnerSnapshotDto) *NullableRunnerSnapshotDto {\n\treturn &NullableRunnerSnapshotDto{value: val, isSet: true}\n}\n\nfunc (v NullableRunnerSnapshotDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRunnerSnapshotDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_runner_state.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// RunnerState The state of the runner\ntype RunnerState string\n\n// List of RunnerState\nconst (\n\tRUNNERSTATE_INITIALIZING RunnerState = \"initializing\"\n\tRUNNERSTATE_READY RunnerState = \"ready\"\n\tRUNNERSTATE_DISABLED RunnerState = \"disabled\"\n\tRUNNERSTATE_DECOMMISSIONED RunnerState = \"decommissioned\"\n\tRUNNERSTATE_UNRESPONSIVE RunnerState = \"unresponsive\"\n)\n\n// All allowed values of RunnerState enum\nvar AllowedRunnerStateEnumValues = []RunnerState{\n\t\"initializing\",\n\t\"ready\",\n\t\"disabled\",\n\t\"decommissioned\",\n\t\"unresponsive\",\n}\n\nfunc (v *RunnerState) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := RunnerState(value)\n\tfor _, existing := range AllowedRunnerStateEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid RunnerState\", value)\n}\n\n// NewRunnerStateFromValue returns a pointer to a valid RunnerState\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewRunnerStateFromValue(v string) (*RunnerState, error) {\n\tev := RunnerState(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for RunnerState: valid values are %v\", v, AllowedRunnerStateEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v RunnerState) IsValid() bool {\n\tfor _, existing := range AllowedRunnerStateEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to RunnerState value\nfunc (v RunnerState) Ptr() *RunnerState {\n\treturn &v\n}\n\ntype NullableRunnerState struct {\n\tvalue *RunnerState\n\tisSet bool\n}\n\nfunc (v NullableRunnerState) Get() *RunnerState {\n\treturn v.value\n}\n\nfunc (v *NullableRunnerState) Set(val *RunnerState) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableRunnerState) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableRunnerState) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableRunnerState(val *RunnerState) *NullableRunnerState {\n\treturn &NullableRunnerState{value: val, isSet: true}\n}\n\nfunc (v NullableRunnerState) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableRunnerState) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_sandbox.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Sandbox type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Sandbox{}\n\n// Sandbox struct for Sandbox\ntype Sandbox struct {\n\t// The ID of the sandbox\n\tId string `json:\"id\"`\n\t// The organization ID of the sandbox\n\tOrganizationId string `json:\"organizationId\"`\n\t// The name of the sandbox\n\tName string `json:\"name\"`\n\t// The snapshot used for the sandbox\n\tSnapshot *string `json:\"snapshot,omitempty\"`\n\t// The user associated with the project\n\tUser string `json:\"user\"`\n\t// Environment variables for the sandbox\n\tEnv map[string]string `json:\"env\"`\n\t// Labels for the sandbox\n\tLabels map[string]string `json:\"labels\"`\n\t// Whether the sandbox http preview is public\n\tPublic bool `json:\"public\"`\n\t// Whether to block all network access for the sandbox\n\tNetworkBlockAll bool `json:\"networkBlockAll\"`\n\t// Comma-separated list of allowed CIDR network addresses for the sandbox\n\tNetworkAllowList *string `json:\"networkAllowList,omitempty\"`\n\t// The target environment for the sandbox\n\tTarget string `json:\"target\"`\n\t// The CPU quota for the sandbox\n\tCpu float32 `json:\"cpu\"`\n\t// The GPU quota for the sandbox\n\tGpu float32 `json:\"gpu\"`\n\t// The memory quota for the sandbox\n\tMemory float32 `json:\"memory\"`\n\t// The disk quota for the sandbox\n\tDisk float32 `json:\"disk\"`\n\t// The state of the sandbox\n\tState *SandboxState `json:\"state,omitempty\"`\n\t// The desired state of the sandbox\n\tDesiredState *SandboxDesiredState `json:\"desiredState,omitempty\"`\n\t// The error reason of the sandbox\n\tErrorReason *string `json:\"errorReason,omitempty\"`\n\t// Whether the sandbox error is recoverable.\n\tRecoverable *bool `json:\"recoverable,omitempty\"`\n\t// The state of the backup\n\tBackupState *string `json:\"backupState,omitempty\"`\n\t// The creation timestamp of the last backup\n\tBackupCreatedAt *string `json:\"backupCreatedAt,omitempty\"`\n\t// Auto-stop interval in minutes (0 means disabled)\n\tAutoStopInterval *float32 `json:\"autoStopInterval,omitempty\"`\n\t// Auto-archive interval in minutes\n\tAutoArchiveInterval *float32 `json:\"autoArchiveInterval,omitempty\"`\n\t// Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n\tAutoDeleteInterval *float32 `json:\"autoDeleteInterval,omitempty\"`\n\t// Array of volumes attached to the sandbox\n\tVolumes []SandboxVolume `json:\"volumes,omitempty\"`\n\t// Build information for the sandbox\n\tBuildInfo *BuildInfo `json:\"buildInfo,omitempty\"`\n\t// The creation timestamp of the sandbox\n\tCreatedAt *string `json:\"createdAt,omitempty\"`\n\t// The last update timestamp of the sandbox\n\tUpdatedAt *string `json:\"updatedAt,omitempty\"`\n\t// The class of the sandbox\n\t// Deprecated\n\tClass *string `json:\"class,omitempty\"`\n\t// The version of the daemon running in the sandbox\n\tDaemonVersion *string `json:\"daemonVersion,omitempty\"`\n\t// The runner ID of the sandbox\n\tRunnerId *string `json:\"runnerId,omitempty\"`\n\t// The toolbox proxy URL for the sandbox\n\tToolboxProxyUrl string `json:\"toolboxProxyUrl\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Sandbox Sandbox\n\n// NewSandbox instantiates a new Sandbox object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSandbox(id string, organizationId string, name string, user string, env map[string]string, labels map[string]string, public bool, networkBlockAll bool, target string, cpu float32, gpu float32, memory float32, disk float32, toolboxProxyUrl string) *Sandbox {\n\tthis := Sandbox{}\n\tthis.Id = id\n\tthis.OrganizationId = organizationId\n\tthis.Name = name\n\tthis.User = user\n\tthis.Env = env\n\tthis.Labels = labels\n\tthis.Public = public\n\tthis.NetworkBlockAll = networkBlockAll\n\tthis.Target = target\n\tthis.Cpu = cpu\n\tthis.Gpu = gpu\n\tthis.Memory = memory\n\tthis.Disk = disk\n\tthis.ToolboxProxyUrl = toolboxProxyUrl\n\treturn &this\n}\n\n// NewSandboxWithDefaults instantiates a new Sandbox object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSandboxWithDefaults() *Sandbox {\n\tthis := Sandbox{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *Sandbox) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *Sandbox) SetId(v string) {\n\to.Id = v\n}\n\n// GetOrganizationId returns the OrganizationId field value\nfunc (o *Sandbox) GetOrganizationId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationId, true\n}\n\n// SetOrganizationId sets field value\nfunc (o *Sandbox) SetOrganizationId(v string) {\n\to.OrganizationId = v\n}\n\n// GetName returns the Name field value\nfunc (o *Sandbox) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *Sandbox) SetName(v string) {\n\to.Name = v\n}\n\n// GetSnapshot returns the Snapshot field value if set, zero value otherwise.\nfunc (o *Sandbox) GetSnapshot() string {\n\tif o == nil || IsNil(o.Snapshot) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Snapshot\n}\n\n// GetSnapshotOk returns a tuple with the Snapshot field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetSnapshotOk() (*string, bool) {\n\tif o == nil || IsNil(o.Snapshot) {\n\t\treturn nil, false\n\t}\n\treturn o.Snapshot, true\n}\n\n// HasSnapshot returns a boolean if a field has been set.\nfunc (o *Sandbox) HasSnapshot() bool {\n\tif o != nil && !IsNil(o.Snapshot) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshot gets a reference to the given string and assigns it to the Snapshot field.\nfunc (o *Sandbox) SetSnapshot(v string) {\n\to.Snapshot = &v\n}\n\n// GetUser returns the User field value\nfunc (o *Sandbox) GetUser() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.User\n}\n\n// GetUserOk returns a tuple with the User field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetUserOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.User, true\n}\n\n// SetUser sets field value\nfunc (o *Sandbox) SetUser(v string) {\n\to.User = v\n}\n\n// GetEnv returns the Env field value\nfunc (o *Sandbox) GetEnv() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\n\treturn o.Env\n}\n\n// GetEnvOk returns a tuple with the Env field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetEnvOk() (*map[string]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Env, true\n}\n\n// SetEnv sets field value\nfunc (o *Sandbox) SetEnv(v map[string]string) {\n\to.Env = v\n}\n\n// GetLabels returns the Labels field value\nfunc (o *Sandbox) GetLabels() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\n\treturn o.Labels\n}\n\n// GetLabelsOk returns a tuple with the Labels field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetLabelsOk() (*map[string]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Labels, true\n}\n\n// SetLabels sets field value\nfunc (o *Sandbox) SetLabels(v map[string]string) {\n\to.Labels = v\n}\n\n// GetPublic returns the Public field value\nfunc (o *Sandbox) GetPublic() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Public\n}\n\n// GetPublicOk returns a tuple with the Public field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetPublicOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Public, true\n}\n\n// SetPublic sets field value\nfunc (o *Sandbox) SetPublic(v bool) {\n\to.Public = v\n}\n\n// GetNetworkBlockAll returns the NetworkBlockAll field value\nfunc (o *Sandbox) GetNetworkBlockAll() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.NetworkBlockAll\n}\n\n// GetNetworkBlockAllOk returns a tuple with the NetworkBlockAll field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetNetworkBlockAllOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.NetworkBlockAll, true\n}\n\n// SetNetworkBlockAll sets field value\nfunc (o *Sandbox) SetNetworkBlockAll(v bool) {\n\to.NetworkBlockAll = v\n}\n\n// GetNetworkAllowList returns the NetworkAllowList field value if set, zero value otherwise.\nfunc (o *Sandbox) GetNetworkAllowList() string {\n\tif o == nil || IsNil(o.NetworkAllowList) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.NetworkAllowList\n}\n\n// GetNetworkAllowListOk returns a tuple with the NetworkAllowList field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetNetworkAllowListOk() (*string, bool) {\n\tif o == nil || IsNil(o.NetworkAllowList) {\n\t\treturn nil, false\n\t}\n\treturn o.NetworkAllowList, true\n}\n\n// HasNetworkAllowList returns a boolean if a field has been set.\nfunc (o *Sandbox) HasNetworkAllowList() bool {\n\tif o != nil && !IsNil(o.NetworkAllowList) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetNetworkAllowList gets a reference to the given string and assigns it to the NetworkAllowList field.\nfunc (o *Sandbox) SetNetworkAllowList(v string) {\n\to.NetworkAllowList = &v\n}\n\n// GetTarget returns the Target field value\nfunc (o *Sandbox) GetTarget() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Target\n}\n\n// GetTargetOk returns a tuple with the Target field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetTargetOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Target, true\n}\n\n// SetTarget sets field value\nfunc (o *Sandbox) SetTarget(v string) {\n\to.Target = v\n}\n\n// GetCpu returns the Cpu field value\nfunc (o *Sandbox) GetCpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetCpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cpu, true\n}\n\n// SetCpu sets field value\nfunc (o *Sandbox) SetCpu(v float32) {\n\to.Cpu = v\n}\n\n// GetGpu returns the Gpu field value\nfunc (o *Sandbox) GetGpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Gpu\n}\n\n// GetGpuOk returns a tuple with the Gpu field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetGpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Gpu, true\n}\n\n// SetGpu sets field value\nfunc (o *Sandbox) SetGpu(v float32) {\n\to.Gpu = v\n}\n\n// GetMemory returns the Memory field value\nfunc (o *Sandbox) GetMemory() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Memory\n}\n\n// GetMemoryOk returns a tuple with the Memory field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetMemoryOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Memory, true\n}\n\n// SetMemory sets field value\nfunc (o *Sandbox) SetMemory(v float32) {\n\to.Memory = v\n}\n\n// GetDisk returns the Disk field value\nfunc (o *Sandbox) GetDisk() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetDiskOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Disk, true\n}\n\n// SetDisk sets field value\nfunc (o *Sandbox) SetDisk(v float32) {\n\to.Disk = v\n}\n\n// GetState returns the State field value if set, zero value otherwise.\nfunc (o *Sandbox) GetState() SandboxState {\n\tif o == nil || IsNil(o.State) {\n\t\tvar ret SandboxState\n\t\treturn ret\n\t}\n\treturn *o.State\n}\n\n// GetStateOk returns a tuple with the State field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetStateOk() (*SandboxState, bool) {\n\tif o == nil || IsNil(o.State) {\n\t\treturn nil, false\n\t}\n\treturn o.State, true\n}\n\n// HasState returns a boolean if a field has been set.\nfunc (o *Sandbox) HasState() bool {\n\tif o != nil && !IsNil(o.State) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetState gets a reference to the given SandboxState and assigns it to the State field.\nfunc (o *Sandbox) SetState(v SandboxState) {\n\to.State = &v\n}\n\n// GetDesiredState returns the DesiredState field value if set, zero value otherwise.\nfunc (o *Sandbox) GetDesiredState() SandboxDesiredState {\n\tif o == nil || IsNil(o.DesiredState) {\n\t\tvar ret SandboxDesiredState\n\t\treturn ret\n\t}\n\treturn *o.DesiredState\n}\n\n// GetDesiredStateOk returns a tuple with the DesiredState field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetDesiredStateOk() (*SandboxDesiredState, bool) {\n\tif o == nil || IsNil(o.DesiredState) {\n\t\treturn nil, false\n\t}\n\treturn o.DesiredState, true\n}\n\n// HasDesiredState returns a boolean if a field has been set.\nfunc (o *Sandbox) HasDesiredState() bool {\n\tif o != nil && !IsNil(o.DesiredState) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDesiredState gets a reference to the given SandboxDesiredState and assigns it to the DesiredState field.\nfunc (o *Sandbox) SetDesiredState(v SandboxDesiredState) {\n\to.DesiredState = &v\n}\n\n// GetErrorReason returns the ErrorReason field value if set, zero value otherwise.\nfunc (o *Sandbox) GetErrorReason() string {\n\tif o == nil || IsNil(o.ErrorReason) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ErrorReason\n}\n\n// GetErrorReasonOk returns a tuple with the ErrorReason field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetErrorReasonOk() (*string, bool) {\n\tif o == nil || IsNil(o.ErrorReason) {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorReason, true\n}\n\n// HasErrorReason returns a boolean if a field has been set.\nfunc (o *Sandbox) HasErrorReason() bool {\n\tif o != nil && !IsNil(o.ErrorReason) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetErrorReason gets a reference to the given string and assigns it to the ErrorReason field.\nfunc (o *Sandbox) SetErrorReason(v string) {\n\to.ErrorReason = &v\n}\n\n// GetRecoverable returns the Recoverable field value if set, zero value otherwise.\nfunc (o *Sandbox) GetRecoverable() bool {\n\tif o == nil || IsNil(o.Recoverable) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Recoverable\n}\n\n// GetRecoverableOk returns a tuple with the Recoverable field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetRecoverableOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Recoverable) {\n\t\treturn nil, false\n\t}\n\treturn o.Recoverable, true\n}\n\n// HasRecoverable returns a boolean if a field has been set.\nfunc (o *Sandbox) HasRecoverable() bool {\n\tif o != nil && !IsNil(o.Recoverable) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRecoverable gets a reference to the given bool and assigns it to the Recoverable field.\nfunc (o *Sandbox) SetRecoverable(v bool) {\n\to.Recoverable = &v\n}\n\n// GetBackupState returns the BackupState field value if set, zero value otherwise.\nfunc (o *Sandbox) GetBackupState() string {\n\tif o == nil || IsNil(o.BackupState) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.BackupState\n}\n\n// GetBackupStateOk returns a tuple with the BackupState field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetBackupStateOk() (*string, bool) {\n\tif o == nil || IsNil(o.BackupState) {\n\t\treturn nil, false\n\t}\n\treturn o.BackupState, true\n}\n\n// HasBackupState returns a boolean if a field has been set.\nfunc (o *Sandbox) HasBackupState() bool {\n\tif o != nil && !IsNil(o.BackupState) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBackupState gets a reference to the given string and assigns it to the BackupState field.\nfunc (o *Sandbox) SetBackupState(v string) {\n\to.BackupState = &v\n}\n\n// GetBackupCreatedAt returns the BackupCreatedAt field value if set, zero value otherwise.\nfunc (o *Sandbox) GetBackupCreatedAt() string {\n\tif o == nil || IsNil(o.BackupCreatedAt) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.BackupCreatedAt\n}\n\n// GetBackupCreatedAtOk returns a tuple with the BackupCreatedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetBackupCreatedAtOk() (*string, bool) {\n\tif o == nil || IsNil(o.BackupCreatedAt) {\n\t\treturn nil, false\n\t}\n\treturn o.BackupCreatedAt, true\n}\n\n// HasBackupCreatedAt returns a boolean if a field has been set.\nfunc (o *Sandbox) HasBackupCreatedAt() bool {\n\tif o != nil && !IsNil(o.BackupCreatedAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBackupCreatedAt gets a reference to the given string and assigns it to the BackupCreatedAt field.\nfunc (o *Sandbox) SetBackupCreatedAt(v string) {\n\to.BackupCreatedAt = &v\n}\n\n// GetAutoStopInterval returns the AutoStopInterval field value if set, zero value otherwise.\nfunc (o *Sandbox) GetAutoStopInterval() float32 {\n\tif o == nil || IsNil(o.AutoStopInterval) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.AutoStopInterval\n}\n\n// GetAutoStopIntervalOk returns a tuple with the AutoStopInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetAutoStopIntervalOk() (*float32, bool) {\n\tif o == nil || IsNil(o.AutoStopInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoStopInterval, true\n}\n\n// HasAutoStopInterval returns a boolean if a field has been set.\nfunc (o *Sandbox) HasAutoStopInterval() bool {\n\tif o != nil && !IsNil(o.AutoStopInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoStopInterval gets a reference to the given float32 and assigns it to the AutoStopInterval field.\nfunc (o *Sandbox) SetAutoStopInterval(v float32) {\n\to.AutoStopInterval = &v\n}\n\n// GetAutoArchiveInterval returns the AutoArchiveInterval field value if set, zero value otherwise.\nfunc (o *Sandbox) GetAutoArchiveInterval() float32 {\n\tif o == nil || IsNil(o.AutoArchiveInterval) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.AutoArchiveInterval\n}\n\n// GetAutoArchiveIntervalOk returns a tuple with the AutoArchiveInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetAutoArchiveIntervalOk() (*float32, bool) {\n\tif o == nil || IsNil(o.AutoArchiveInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoArchiveInterval, true\n}\n\n// HasAutoArchiveInterval returns a boolean if a field has been set.\nfunc (o *Sandbox) HasAutoArchiveInterval() bool {\n\tif o != nil && !IsNil(o.AutoArchiveInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoArchiveInterval gets a reference to the given float32 and assigns it to the AutoArchiveInterval field.\nfunc (o *Sandbox) SetAutoArchiveInterval(v float32) {\n\to.AutoArchiveInterval = &v\n}\n\n// GetAutoDeleteInterval returns the AutoDeleteInterval field value if set, zero value otherwise.\nfunc (o *Sandbox) GetAutoDeleteInterval() float32 {\n\tif o == nil || IsNil(o.AutoDeleteInterval) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.AutoDeleteInterval\n}\n\n// GetAutoDeleteIntervalOk returns a tuple with the AutoDeleteInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetAutoDeleteIntervalOk() (*float32, bool) {\n\tif o == nil || IsNil(o.AutoDeleteInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoDeleteInterval, true\n}\n\n// HasAutoDeleteInterval returns a boolean if a field has been set.\nfunc (o *Sandbox) HasAutoDeleteInterval() bool {\n\tif o != nil && !IsNil(o.AutoDeleteInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoDeleteInterval gets a reference to the given float32 and assigns it to the AutoDeleteInterval field.\nfunc (o *Sandbox) SetAutoDeleteInterval(v float32) {\n\to.AutoDeleteInterval = &v\n}\n\n// GetVolumes returns the Volumes field value if set, zero value otherwise.\nfunc (o *Sandbox) GetVolumes() []SandboxVolume {\n\tif o == nil || IsNil(o.Volumes) {\n\t\tvar ret []SandboxVolume\n\t\treturn ret\n\t}\n\treturn o.Volumes\n}\n\n// GetVolumesOk returns a tuple with the Volumes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetVolumesOk() ([]SandboxVolume, bool) {\n\tif o == nil || IsNil(o.Volumes) {\n\t\treturn nil, false\n\t}\n\treturn o.Volumes, true\n}\n\n// HasVolumes returns a boolean if a field has been set.\nfunc (o *Sandbox) HasVolumes() bool {\n\tif o != nil && !IsNil(o.Volumes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetVolumes gets a reference to the given []SandboxVolume and assigns it to the Volumes field.\nfunc (o *Sandbox) SetVolumes(v []SandboxVolume) {\n\to.Volumes = v\n}\n\n// GetBuildInfo returns the BuildInfo field value if set, zero value otherwise.\nfunc (o *Sandbox) GetBuildInfo() BuildInfo {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\tvar ret BuildInfo\n\t\treturn ret\n\t}\n\treturn *o.BuildInfo\n}\n\n// GetBuildInfoOk returns a tuple with the BuildInfo field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetBuildInfoOk() (*BuildInfo, bool) {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\treturn nil, false\n\t}\n\treturn o.BuildInfo, true\n}\n\n// HasBuildInfo returns a boolean if a field has been set.\nfunc (o *Sandbox) HasBuildInfo() bool {\n\tif o != nil && !IsNil(o.BuildInfo) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBuildInfo gets a reference to the given BuildInfo and assigns it to the BuildInfo field.\nfunc (o *Sandbox) SetBuildInfo(v BuildInfo) {\n\to.BuildInfo = &v\n}\n\n// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise.\nfunc (o *Sandbox) GetCreatedAt() string {\n\tif o == nil || IsNil(o.CreatedAt) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetCreatedAtOk() (*string, bool) {\n\tif o == nil || IsNil(o.CreatedAt) {\n\t\treturn nil, false\n\t}\n\treturn o.CreatedAt, true\n}\n\n// HasCreatedAt returns a boolean if a field has been set.\nfunc (o *Sandbox) HasCreatedAt() bool {\n\tif o != nil && !IsNil(o.CreatedAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCreatedAt gets a reference to the given string and assigns it to the CreatedAt field.\nfunc (o *Sandbox) SetCreatedAt(v string) {\n\to.CreatedAt = &v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise.\nfunc (o *Sandbox) GetUpdatedAt() string {\n\tif o == nil || IsNil(o.UpdatedAt) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetUpdatedAtOk() (*string, bool) {\n\tif o == nil || IsNil(o.UpdatedAt) {\n\t\treturn nil, false\n\t}\n\treturn o.UpdatedAt, true\n}\n\n// HasUpdatedAt returns a boolean if a field has been set.\nfunc (o *Sandbox) HasUpdatedAt() bool {\n\tif o != nil && !IsNil(o.UpdatedAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetUpdatedAt gets a reference to the given string and assigns it to the UpdatedAt field.\nfunc (o *Sandbox) SetUpdatedAt(v string) {\n\to.UpdatedAt = &v\n}\n\n// GetClass returns the Class field value if set, zero value otherwise.\n// Deprecated\nfunc (o *Sandbox) GetClass() string {\n\tif o == nil || IsNil(o.Class) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Class\n}\n\n// GetClassOk returns a tuple with the Class field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *Sandbox) GetClassOk() (*string, bool) {\n\tif o == nil || IsNil(o.Class) {\n\t\treturn nil, false\n\t}\n\treturn o.Class, true\n}\n\n// HasClass returns a boolean if a field has been set.\nfunc (o *Sandbox) HasClass() bool {\n\tif o != nil && !IsNil(o.Class) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetClass gets a reference to the given string and assigns it to the Class field.\n// Deprecated\nfunc (o *Sandbox) SetClass(v string) {\n\to.Class = &v\n}\n\n// GetDaemonVersion returns the DaemonVersion field value if set, zero value otherwise.\nfunc (o *Sandbox) GetDaemonVersion() string {\n\tif o == nil || IsNil(o.DaemonVersion) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.DaemonVersion\n}\n\n// GetDaemonVersionOk returns a tuple with the DaemonVersion field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetDaemonVersionOk() (*string, bool) {\n\tif o == nil || IsNil(o.DaemonVersion) {\n\t\treturn nil, false\n\t}\n\treturn o.DaemonVersion, true\n}\n\n// HasDaemonVersion returns a boolean if a field has been set.\nfunc (o *Sandbox) HasDaemonVersion() bool {\n\tif o != nil && !IsNil(o.DaemonVersion) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDaemonVersion gets a reference to the given string and assigns it to the DaemonVersion field.\nfunc (o *Sandbox) SetDaemonVersion(v string) {\n\to.DaemonVersion = &v\n}\n\n// GetRunnerId returns the RunnerId field value if set, zero value otherwise.\nfunc (o *Sandbox) GetRunnerId() string {\n\tif o == nil || IsNil(o.RunnerId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.RunnerId\n}\n\n// GetRunnerIdOk returns a tuple with the RunnerId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetRunnerIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.RunnerId) {\n\t\treturn nil, false\n\t}\n\treturn o.RunnerId, true\n}\n\n// HasRunnerId returns a boolean if a field has been set.\nfunc (o *Sandbox) HasRunnerId() bool {\n\tif o != nil && !IsNil(o.RunnerId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRunnerId gets a reference to the given string and assigns it to the RunnerId field.\nfunc (o *Sandbox) SetRunnerId(v string) {\n\to.RunnerId = &v\n}\n\n// GetToolboxProxyUrl returns the ToolboxProxyUrl field value\nfunc (o *Sandbox) GetToolboxProxyUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ToolboxProxyUrl\n}\n\n// GetToolboxProxyUrlOk returns a tuple with the ToolboxProxyUrl field value\n// and a boolean to check if the value has been set.\nfunc (o *Sandbox) GetToolboxProxyUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ToolboxProxyUrl, true\n}\n\n// SetToolboxProxyUrl sets field value\nfunc (o *Sandbox) SetToolboxProxyUrl(v string) {\n\to.ToolboxProxyUrl = v\n}\n\nfunc (o Sandbox) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Sandbox) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\ttoSerialize[\"name\"] = o.Name\n\tif !IsNil(o.Snapshot) {\n\t\ttoSerialize[\"snapshot\"] = o.Snapshot\n\t}\n\ttoSerialize[\"user\"] = o.User\n\ttoSerialize[\"env\"] = o.Env\n\ttoSerialize[\"labels\"] = o.Labels\n\ttoSerialize[\"public\"] = o.Public\n\ttoSerialize[\"networkBlockAll\"] = o.NetworkBlockAll\n\tif !IsNil(o.NetworkAllowList) {\n\t\ttoSerialize[\"networkAllowList\"] = o.NetworkAllowList\n\t}\n\ttoSerialize[\"target\"] = o.Target\n\ttoSerialize[\"cpu\"] = o.Cpu\n\ttoSerialize[\"gpu\"] = o.Gpu\n\ttoSerialize[\"memory\"] = o.Memory\n\ttoSerialize[\"disk\"] = o.Disk\n\tif !IsNil(o.State) {\n\t\ttoSerialize[\"state\"] = o.State\n\t}\n\tif !IsNil(o.DesiredState) {\n\t\ttoSerialize[\"desiredState\"] = o.DesiredState\n\t}\n\tif !IsNil(o.ErrorReason) {\n\t\ttoSerialize[\"errorReason\"] = o.ErrorReason\n\t}\n\tif !IsNil(o.Recoverable) {\n\t\ttoSerialize[\"recoverable\"] = o.Recoverable\n\t}\n\tif !IsNil(o.BackupState) {\n\t\ttoSerialize[\"backupState\"] = o.BackupState\n\t}\n\tif !IsNil(o.BackupCreatedAt) {\n\t\ttoSerialize[\"backupCreatedAt\"] = o.BackupCreatedAt\n\t}\n\tif !IsNil(o.AutoStopInterval) {\n\t\ttoSerialize[\"autoStopInterval\"] = o.AutoStopInterval\n\t}\n\tif !IsNil(o.AutoArchiveInterval) {\n\t\ttoSerialize[\"autoArchiveInterval\"] = o.AutoArchiveInterval\n\t}\n\tif !IsNil(o.AutoDeleteInterval) {\n\t\ttoSerialize[\"autoDeleteInterval\"] = o.AutoDeleteInterval\n\t}\n\tif !IsNil(o.Volumes) {\n\t\ttoSerialize[\"volumes\"] = o.Volumes\n\t}\n\tif !IsNil(o.BuildInfo) {\n\t\ttoSerialize[\"buildInfo\"] = o.BuildInfo\n\t}\n\tif !IsNil(o.CreatedAt) {\n\t\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\t}\n\tif !IsNil(o.UpdatedAt) {\n\t\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\t}\n\tif !IsNil(o.Class) {\n\t\ttoSerialize[\"class\"] = o.Class\n\t}\n\tif !IsNil(o.DaemonVersion) {\n\t\ttoSerialize[\"daemonVersion\"] = o.DaemonVersion\n\t}\n\tif !IsNil(o.RunnerId) {\n\t\ttoSerialize[\"runnerId\"] = o.RunnerId\n\t}\n\ttoSerialize[\"toolboxProxyUrl\"] = o.ToolboxProxyUrl\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Sandbox) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"organizationId\",\n\t\t\"name\",\n\t\t\"user\",\n\t\t\"env\",\n\t\t\"labels\",\n\t\t\"public\",\n\t\t\"networkBlockAll\",\n\t\t\"target\",\n\t\t\"cpu\",\n\t\t\"gpu\",\n\t\t\"memory\",\n\t\t\"disk\",\n\t\t\"toolboxProxyUrl\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSandbox := _Sandbox{}\n\n\terr = json.Unmarshal(data, &varSandbox)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Sandbox(varSandbox)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"snapshot\")\n\t\tdelete(additionalProperties, \"user\")\n\t\tdelete(additionalProperties, \"env\")\n\t\tdelete(additionalProperties, \"labels\")\n\t\tdelete(additionalProperties, \"public\")\n\t\tdelete(additionalProperties, \"networkBlockAll\")\n\t\tdelete(additionalProperties, \"networkAllowList\")\n\t\tdelete(additionalProperties, \"target\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"gpu\")\n\t\tdelete(additionalProperties, \"memory\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\tdelete(additionalProperties, \"state\")\n\t\tdelete(additionalProperties, \"desiredState\")\n\t\tdelete(additionalProperties, \"errorReason\")\n\t\tdelete(additionalProperties, \"recoverable\")\n\t\tdelete(additionalProperties, \"backupState\")\n\t\tdelete(additionalProperties, \"backupCreatedAt\")\n\t\tdelete(additionalProperties, \"autoStopInterval\")\n\t\tdelete(additionalProperties, \"autoArchiveInterval\")\n\t\tdelete(additionalProperties, \"autoDeleteInterval\")\n\t\tdelete(additionalProperties, \"volumes\")\n\t\tdelete(additionalProperties, \"buildInfo\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"class\")\n\t\tdelete(additionalProperties, \"daemonVersion\")\n\t\tdelete(additionalProperties, \"runnerId\")\n\t\tdelete(additionalProperties, \"toolboxProxyUrl\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSandbox struct {\n\tvalue *Sandbox\n\tisSet bool\n}\n\nfunc (v NullableSandbox) Get() *Sandbox {\n\treturn v.value\n}\n\nfunc (v *NullableSandbox) Set(val *Sandbox) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSandbox) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSandbox) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSandbox(val *Sandbox) *NullableSandbox {\n\treturn &NullableSandbox{value: val, isSet: true}\n}\n\nfunc (v NullableSandbox) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSandbox) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_sandbox_class.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// SandboxClass The class of the runner\ntype SandboxClass string\n\n// List of SandboxClass\nconst (\n\tSANDBOXCLASS_SMALL SandboxClass = \"small\"\n\tSANDBOXCLASS_MEDIUM SandboxClass = \"medium\"\n\tSANDBOXCLASS_LARGE SandboxClass = \"large\"\n)\n\n// All allowed values of SandboxClass enum\nvar AllowedSandboxClassEnumValues = []SandboxClass{\n\t\"small\",\n\t\"medium\",\n\t\"large\",\n}\n\nfunc (v *SandboxClass) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := SandboxClass(value)\n\tfor _, existing := range AllowedSandboxClassEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid SandboxClass\", value)\n}\n\n// NewSandboxClassFromValue returns a pointer to a valid SandboxClass\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewSandboxClassFromValue(v string) (*SandboxClass, error) {\n\tev := SandboxClass(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for SandboxClass: valid values are %v\", v, AllowedSandboxClassEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v SandboxClass) IsValid() bool {\n\tfor _, existing := range AllowedSandboxClassEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to SandboxClass value\nfunc (v SandboxClass) Ptr() *SandboxClass {\n\treturn &v\n}\n\ntype NullableSandboxClass struct {\n\tvalue *SandboxClass\n\tisSet bool\n}\n\nfunc (v NullableSandboxClass) Get() *SandboxClass {\n\treturn v.value\n}\n\nfunc (v *NullableSandboxClass) Set(val *SandboxClass) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSandboxClass) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSandboxClass) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSandboxClass(val *SandboxClass) *NullableSandboxClass {\n\treturn &NullableSandboxClass{value: val, isSet: true}\n}\n\nfunc (v NullableSandboxClass) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSandboxClass) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_sandbox_desired_state.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// SandboxDesiredState The desired state of the sandbox\ntype SandboxDesiredState string\n\n// List of SandboxDesiredState\nconst (\n\tSANDBOXDESIREDSTATE_DESTROYED SandboxDesiredState = \"destroyed\"\n\tSANDBOXDESIREDSTATE_STARTED SandboxDesiredState = \"started\"\n\tSANDBOXDESIREDSTATE_STOPPED SandboxDesiredState = \"stopped\"\n\tSANDBOXDESIREDSTATE_RESIZED SandboxDesiredState = \"resized\"\n\tSANDBOXDESIREDSTATE_ARCHIVED SandboxDesiredState = \"archived\"\n)\n\n// All allowed values of SandboxDesiredState enum\nvar AllowedSandboxDesiredStateEnumValues = []SandboxDesiredState{\n\t\"destroyed\",\n\t\"started\",\n\t\"stopped\",\n\t\"resized\",\n\t\"archived\",\n}\n\nfunc (v *SandboxDesiredState) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := SandboxDesiredState(value)\n\tfor _, existing := range AllowedSandboxDesiredStateEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid SandboxDesiredState\", value)\n}\n\n// NewSandboxDesiredStateFromValue returns a pointer to a valid SandboxDesiredState\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewSandboxDesiredStateFromValue(v string) (*SandboxDesiredState, error) {\n\tev := SandboxDesiredState(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for SandboxDesiredState: valid values are %v\", v, AllowedSandboxDesiredStateEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v SandboxDesiredState) IsValid() bool {\n\tfor _, existing := range AllowedSandboxDesiredStateEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to SandboxDesiredState value\nfunc (v SandboxDesiredState) Ptr() *SandboxDesiredState {\n\treturn &v\n}\n\ntype NullableSandboxDesiredState struct {\n\tvalue *SandboxDesiredState\n\tisSet bool\n}\n\nfunc (v NullableSandboxDesiredState) Get() *SandboxDesiredState {\n\treturn v.value\n}\n\nfunc (v *NullableSandboxDesiredState) Set(val *SandboxDesiredState) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSandboxDesiredState) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSandboxDesiredState) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSandboxDesiredState(val *SandboxDesiredState) *NullableSandboxDesiredState {\n\treturn &NullableSandboxDesiredState{value: val, isSet: true}\n}\n\nfunc (v NullableSandboxDesiredState) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSandboxDesiredState) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_sandbox_info.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SandboxInfo type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SandboxInfo{}\n\n// SandboxInfo struct for SandboxInfo\ntype SandboxInfo struct {\n\t// The creation timestamp of the project\n\tCreated string `json:\"created\"`\n\t// Deprecated: The name of the sandbox\n\t// Deprecated\n\tName string `json:\"name\"`\n\t// Additional metadata provided by the provider\n\tProviderMetadata *string `json:\"providerMetadata,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SandboxInfo SandboxInfo\n\n// NewSandboxInfo instantiates a new SandboxInfo object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSandboxInfo(created string, name string) *SandboxInfo {\n\tthis := SandboxInfo{}\n\tthis.Created = created\n\tthis.Name = name\n\treturn &this\n}\n\n// NewSandboxInfoWithDefaults instantiates a new SandboxInfo object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSandboxInfoWithDefaults() *SandboxInfo {\n\tthis := SandboxInfo{}\n\tvar name string = \"\"\n\tthis.Name = name\n\treturn &this\n}\n\n// GetCreated returns the Created field value\nfunc (o *SandboxInfo) GetCreated() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Created\n}\n\n// GetCreatedOk returns a tuple with the Created field value\n// and a boolean to check if the value has been set.\nfunc (o *SandboxInfo) GetCreatedOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Created, true\n}\n\n// SetCreated sets field value\nfunc (o *SandboxInfo) SetCreated(v string) {\n\to.Created = v\n}\n\n// GetName returns the Name field value\n// Deprecated\nfunc (o *SandboxInfo) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *SandboxInfo) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\n// Deprecated\nfunc (o *SandboxInfo) SetName(v string) {\n\to.Name = v\n}\n\n// GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise.\nfunc (o *SandboxInfo) GetProviderMetadata() string {\n\tif o == nil || IsNil(o.ProviderMetadata) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProviderMetadata\n}\n\n// GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SandboxInfo) GetProviderMetadataOk() (*string, bool) {\n\tif o == nil || IsNil(o.ProviderMetadata) {\n\t\treturn nil, false\n\t}\n\treturn o.ProviderMetadata, true\n}\n\n// HasProviderMetadata returns a boolean if a field has been set.\nfunc (o *SandboxInfo) HasProviderMetadata() bool {\n\tif o != nil && !IsNil(o.ProviderMetadata) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field.\nfunc (o *SandboxInfo) SetProviderMetadata(v string) {\n\to.ProviderMetadata = &v\n}\n\nfunc (o SandboxInfo) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SandboxInfo) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"created\"] = o.Created\n\ttoSerialize[\"name\"] = o.Name\n\tif !IsNil(o.ProviderMetadata) {\n\t\ttoSerialize[\"providerMetadata\"] = o.ProviderMetadata\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SandboxInfo) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"created\",\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSandboxInfo := _SandboxInfo{}\n\n\terr = json.Unmarshal(data, &varSandboxInfo)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SandboxInfo(varSandboxInfo)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"created\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"providerMetadata\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSandboxInfo struct {\n\tvalue *SandboxInfo\n\tisSet bool\n}\n\nfunc (v NullableSandboxInfo) Get() *SandboxInfo {\n\treturn v.value\n}\n\nfunc (v *NullableSandboxInfo) Set(val *SandboxInfo) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSandboxInfo) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSandboxInfo) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSandboxInfo(val *SandboxInfo) *NullableSandboxInfo {\n\treturn &NullableSandboxInfo{value: val, isSet: true}\n}\n\nfunc (v NullableSandboxInfo) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSandboxInfo) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_sandbox_labels.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SandboxLabels type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SandboxLabels{}\n\n// SandboxLabels struct for SandboxLabels\ntype SandboxLabels struct {\n\t// Key-value pairs of labels\n\tLabels map[string]string `json:\"labels\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SandboxLabels SandboxLabels\n\n// NewSandboxLabels instantiates a new SandboxLabels object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSandboxLabels(labels map[string]string) *SandboxLabels {\n\tthis := SandboxLabels{}\n\tthis.Labels = labels\n\treturn &this\n}\n\n// NewSandboxLabelsWithDefaults instantiates a new SandboxLabels object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSandboxLabelsWithDefaults() *SandboxLabels {\n\tthis := SandboxLabels{}\n\treturn &this\n}\n\n// GetLabels returns the Labels field value\nfunc (o *SandboxLabels) GetLabels() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\n\treturn o.Labels\n}\n\n// GetLabelsOk returns a tuple with the Labels field value\n// and a boolean to check if the value has been set.\nfunc (o *SandboxLabels) GetLabelsOk() (*map[string]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Labels, true\n}\n\n// SetLabels sets field value\nfunc (o *SandboxLabels) SetLabels(v map[string]string) {\n\to.Labels = v\n}\n\nfunc (o SandboxLabels) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SandboxLabels) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"labels\"] = o.Labels\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SandboxLabels) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"labels\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSandboxLabels := _SandboxLabels{}\n\n\terr = json.Unmarshal(data, &varSandboxLabels)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SandboxLabels(varSandboxLabels)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"labels\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSandboxLabels struct {\n\tvalue *SandboxLabels\n\tisSet bool\n}\n\nfunc (v NullableSandboxLabels) Get() *SandboxLabels {\n\treturn v.value\n}\n\nfunc (v *NullableSandboxLabels) Set(val *SandboxLabels) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSandboxLabels) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSandboxLabels) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSandboxLabels(val *SandboxLabels) *NullableSandboxLabels {\n\treturn &NullableSandboxLabels{value: val, isSet: true}\n}\n\nfunc (v NullableSandboxLabels) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSandboxLabels) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_sandbox_state.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// SandboxState The state of the sandbox\ntype SandboxState string\n\n// List of SandboxState\nconst (\n\tSANDBOXSTATE_CREATING SandboxState = \"creating\"\n\tSANDBOXSTATE_RESTORING SandboxState = \"restoring\"\n\tSANDBOXSTATE_DESTROYED SandboxState = \"destroyed\"\n\tSANDBOXSTATE_DESTROYING SandboxState = \"destroying\"\n\tSANDBOXSTATE_STARTED SandboxState = \"started\"\n\tSANDBOXSTATE_STOPPED SandboxState = \"stopped\"\n\tSANDBOXSTATE_STARTING SandboxState = \"starting\"\n\tSANDBOXSTATE_STOPPING SandboxState = \"stopping\"\n\tSANDBOXSTATE_ERROR SandboxState = \"error\"\n\tSANDBOXSTATE_BUILD_FAILED SandboxState = \"build_failed\"\n\tSANDBOXSTATE_PENDING_BUILD SandboxState = \"pending_build\"\n\tSANDBOXSTATE_BUILDING_SNAPSHOT SandboxState = \"building_snapshot\"\n\tSANDBOXSTATE_UNKNOWN SandboxState = \"unknown\"\n\tSANDBOXSTATE_PULLING_SNAPSHOT SandboxState = \"pulling_snapshot\"\n\tSANDBOXSTATE_ARCHIVED SandboxState = \"archived\"\n\tSANDBOXSTATE_ARCHIVING SandboxState = \"archiving\"\n\tSANDBOXSTATE_RESIZING SandboxState = \"resizing\"\n)\n\n// All allowed values of SandboxState enum\nvar AllowedSandboxStateEnumValues = []SandboxState{\n\t\"creating\",\n\t\"restoring\",\n\t\"destroyed\",\n\t\"destroying\",\n\t\"started\",\n\t\"stopped\",\n\t\"starting\",\n\t\"stopping\",\n\t\"error\",\n\t\"build_failed\",\n\t\"pending_build\",\n\t\"building_snapshot\",\n\t\"unknown\",\n\t\"pulling_snapshot\",\n\t\"archived\",\n\t\"archiving\",\n\t\"resizing\",\n}\n\nfunc (v *SandboxState) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := SandboxState(value)\n\tfor _, existing := range AllowedSandboxStateEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid SandboxState\", value)\n}\n\n// NewSandboxStateFromValue returns a pointer to a valid SandboxState\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewSandboxStateFromValue(v string) (*SandboxState, error) {\n\tev := SandboxState(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for SandboxState: valid values are %v\", v, AllowedSandboxStateEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v SandboxState) IsValid() bool {\n\tfor _, existing := range AllowedSandboxStateEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to SandboxState value\nfunc (v SandboxState) Ptr() *SandboxState {\n\treturn &v\n}\n\ntype NullableSandboxState struct {\n\tvalue *SandboxState\n\tisSet bool\n}\n\nfunc (v NullableSandboxState) Get() *SandboxState {\n\treturn v.value\n}\n\nfunc (v *NullableSandboxState) Set(val *SandboxState) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSandboxState) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSandboxState) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSandboxState(val *SandboxState) *NullableSandboxState {\n\treturn &NullableSandboxState{value: val, isSet: true}\n}\n\nfunc (v NullableSandboxState) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSandboxState) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_sandbox_volume.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SandboxVolume type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SandboxVolume{}\n\n// SandboxVolume struct for SandboxVolume\ntype SandboxVolume struct {\n\t// The ID of the volume\n\tVolumeId string `json:\"volumeId\"`\n\t// The mount path for the volume\n\tMountPath string `json:\"mountPath\"`\n\t// Optional subpath within the volume to mount. When specified, only this S3 prefix will be accessible. When omitted, the entire volume is mounted.\n\tSubpath *string `json:\"subpath,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SandboxVolume SandboxVolume\n\n// NewSandboxVolume instantiates a new SandboxVolume object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSandboxVolume(volumeId string, mountPath string) *SandboxVolume {\n\tthis := SandboxVolume{}\n\tthis.VolumeId = volumeId\n\tthis.MountPath = mountPath\n\treturn &this\n}\n\n// NewSandboxVolumeWithDefaults instantiates a new SandboxVolume object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSandboxVolumeWithDefaults() *SandboxVolume {\n\tthis := SandboxVolume{}\n\treturn &this\n}\n\n// GetVolumeId returns the VolumeId field value\nfunc (o *SandboxVolume) GetVolumeId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.VolumeId\n}\n\n// GetVolumeIdOk returns a tuple with the VolumeId field value\n// and a boolean to check if the value has been set.\nfunc (o *SandboxVolume) GetVolumeIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.VolumeId, true\n}\n\n// SetVolumeId sets field value\nfunc (o *SandboxVolume) SetVolumeId(v string) {\n\to.VolumeId = v\n}\n\n// GetMountPath returns the MountPath field value\nfunc (o *SandboxVolume) GetMountPath() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.MountPath\n}\n\n// GetMountPathOk returns a tuple with the MountPath field value\n// and a boolean to check if the value has been set.\nfunc (o *SandboxVolume) GetMountPathOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.MountPath, true\n}\n\n// SetMountPath sets field value\nfunc (o *SandboxVolume) SetMountPath(v string) {\n\to.MountPath = v\n}\n\n// GetSubpath returns the Subpath field value if set, zero value otherwise.\nfunc (o *SandboxVolume) GetSubpath() string {\n\tif o == nil || IsNil(o.Subpath) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Subpath\n}\n\n// GetSubpathOk returns a tuple with the Subpath field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SandboxVolume) GetSubpathOk() (*string, bool) {\n\tif o == nil || IsNil(o.Subpath) {\n\t\treturn nil, false\n\t}\n\treturn o.Subpath, true\n}\n\n// HasSubpath returns a boolean if a field has been set.\nfunc (o *SandboxVolume) HasSubpath() bool {\n\tif o != nil && !IsNil(o.Subpath) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSubpath gets a reference to the given string and assigns it to the Subpath field.\nfunc (o *SandboxVolume) SetSubpath(v string) {\n\to.Subpath = &v\n}\n\nfunc (o SandboxVolume) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SandboxVolume) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"volumeId\"] = o.VolumeId\n\ttoSerialize[\"mountPath\"] = o.MountPath\n\tif !IsNil(o.Subpath) {\n\t\ttoSerialize[\"subpath\"] = o.Subpath\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SandboxVolume) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"volumeId\",\n\t\t\"mountPath\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSandboxVolume := _SandboxVolume{}\n\n\terr = json.Unmarshal(data, &varSandboxVolume)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SandboxVolume(varSandboxVolume)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"volumeId\")\n\t\tdelete(additionalProperties, \"mountPath\")\n\t\tdelete(additionalProperties, \"subpath\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSandboxVolume struct {\n\tvalue *SandboxVolume\n\tisSet bool\n}\n\nfunc (v NullableSandboxVolume) Get() *SandboxVolume {\n\treturn v.value\n}\n\nfunc (v *NullableSandboxVolume) Set(val *SandboxVolume) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSandboxVolume) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSandboxVolume) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSandboxVolume(val *SandboxVolume) *NullableSandboxVolume {\n\treturn &NullableSandboxVolume{value: val, isSet: true}\n}\n\nfunc (v NullableSandboxVolume) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSandboxVolume) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_screenshot_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ScreenshotResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ScreenshotResponse{}\n\n// ScreenshotResponse struct for ScreenshotResponse\ntype ScreenshotResponse struct {\n\t// Base64 encoded screenshot image data\n\tScreenshot string `json:\"screenshot\"`\n\t// The current cursor position when the screenshot was taken\n\tCursorPosition map[string]interface{} `json:\"cursorPosition,omitempty\"`\n\t// The size of the screenshot data in bytes\n\tSizeBytes *float32 `json:\"sizeBytes,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ScreenshotResponse ScreenshotResponse\n\n// NewScreenshotResponse instantiates a new ScreenshotResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewScreenshotResponse(screenshot string) *ScreenshotResponse {\n\tthis := ScreenshotResponse{}\n\tthis.Screenshot = screenshot\n\treturn &this\n}\n\n// NewScreenshotResponseWithDefaults instantiates a new ScreenshotResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewScreenshotResponseWithDefaults() *ScreenshotResponse {\n\tthis := ScreenshotResponse{}\n\treturn &this\n}\n\n// GetScreenshot returns the Screenshot field value\nfunc (o *ScreenshotResponse) GetScreenshot() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Screenshot\n}\n\n// GetScreenshotOk returns a tuple with the Screenshot field value\n// and a boolean to check if the value has been set.\nfunc (o *ScreenshotResponse) GetScreenshotOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Screenshot, true\n}\n\n// SetScreenshot sets field value\nfunc (o *ScreenshotResponse) SetScreenshot(v string) {\n\to.Screenshot = v\n}\n\n// GetCursorPosition returns the CursorPosition field value if set, zero value otherwise.\nfunc (o *ScreenshotResponse) GetCursorPosition() map[string]interface{} {\n\tif o == nil || IsNil(o.CursorPosition) {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\treturn o.CursorPosition\n}\n\n// GetCursorPositionOk returns a tuple with the CursorPosition field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ScreenshotResponse) GetCursorPositionOk() (map[string]interface{}, bool) {\n\tif o == nil || IsNil(o.CursorPosition) {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.CursorPosition, true\n}\n\n// HasCursorPosition returns a boolean if a field has been set.\nfunc (o *ScreenshotResponse) HasCursorPosition() bool {\n\tif o != nil && !IsNil(o.CursorPosition) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCursorPosition gets a reference to the given map[string]interface{} and assigns it to the CursorPosition field.\nfunc (o *ScreenshotResponse) SetCursorPosition(v map[string]interface{}) {\n\to.CursorPosition = v\n}\n\n// GetSizeBytes returns the SizeBytes field value if set, zero value otherwise.\nfunc (o *ScreenshotResponse) GetSizeBytes() float32 {\n\tif o == nil || IsNil(o.SizeBytes) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.SizeBytes\n}\n\n// GetSizeBytesOk returns a tuple with the SizeBytes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *ScreenshotResponse) GetSizeBytesOk() (*float32, bool) {\n\tif o == nil || IsNil(o.SizeBytes) {\n\t\treturn nil, false\n\t}\n\treturn o.SizeBytes, true\n}\n\n// HasSizeBytes returns a boolean if a field has been set.\nfunc (o *ScreenshotResponse) HasSizeBytes() bool {\n\tif o != nil && !IsNil(o.SizeBytes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSizeBytes gets a reference to the given float32 and assigns it to the SizeBytes field.\nfunc (o *ScreenshotResponse) SetSizeBytes(v float32) {\n\to.SizeBytes = &v\n}\n\nfunc (o ScreenshotResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ScreenshotResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"screenshot\"] = o.Screenshot\n\tif !IsNil(o.CursorPosition) {\n\t\ttoSerialize[\"cursorPosition\"] = o.CursorPosition\n\t}\n\tif !IsNil(o.SizeBytes) {\n\t\ttoSerialize[\"sizeBytes\"] = o.SizeBytes\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ScreenshotResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"screenshot\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarScreenshotResponse := _ScreenshotResponse{}\n\n\terr = json.Unmarshal(data, &varScreenshotResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ScreenshotResponse(varScreenshotResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"screenshot\")\n\t\tdelete(additionalProperties, \"cursorPosition\")\n\t\tdelete(additionalProperties, \"sizeBytes\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableScreenshotResponse struct {\n\tvalue *ScreenshotResponse\n\tisSet bool\n}\n\nfunc (v NullableScreenshotResponse) Get() *ScreenshotResponse {\n\treturn v.value\n}\n\nfunc (v *NullableScreenshotResponse) Set(val *ScreenshotResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableScreenshotResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableScreenshotResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableScreenshotResponse(val *ScreenshotResponse) *NullableScreenshotResponse {\n\treturn &NullableScreenshotResponse{value: val, isSet: true}\n}\n\nfunc (v NullableScreenshotResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableScreenshotResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_search_files_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SearchFilesResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SearchFilesResponse{}\n\n// SearchFilesResponse struct for SearchFilesResponse\ntype SearchFilesResponse struct {\n\tFiles []string `json:\"files\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SearchFilesResponse SearchFilesResponse\n\n// NewSearchFilesResponse instantiates a new SearchFilesResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSearchFilesResponse(files []string) *SearchFilesResponse {\n\tthis := SearchFilesResponse{}\n\tthis.Files = files\n\treturn &this\n}\n\n// NewSearchFilesResponseWithDefaults instantiates a new SearchFilesResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSearchFilesResponseWithDefaults() *SearchFilesResponse {\n\tthis := SearchFilesResponse{}\n\treturn &this\n}\n\n// GetFiles returns the Files field value\nfunc (o *SearchFilesResponse) GetFiles() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Files\n}\n\n// GetFilesOk returns a tuple with the Files field value\n// and a boolean to check if the value has been set.\nfunc (o *SearchFilesResponse) GetFilesOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Files, true\n}\n\n// SetFiles sets field value\nfunc (o *SearchFilesResponse) SetFiles(v []string) {\n\to.Files = v\n}\n\nfunc (o SearchFilesResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SearchFilesResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"files\"] = o.Files\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SearchFilesResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"files\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSearchFilesResponse := _SearchFilesResponse{}\n\n\terr = json.Unmarshal(data, &varSearchFilesResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SearchFilesResponse(varSearchFilesResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"files\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSearchFilesResponse struct {\n\tvalue *SearchFilesResponse\n\tisSet bool\n}\n\nfunc (v NullableSearchFilesResponse) Get() *SearchFilesResponse {\n\treturn v.value\n}\n\nfunc (v *NullableSearchFilesResponse) Set(val *SearchFilesResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSearchFilesResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSearchFilesResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSearchFilesResponse(val *SearchFilesResponse) *NullableSearchFilesResponse {\n\treturn &NullableSearchFilesResponse{value: val, isSet: true}\n}\n\nfunc (v NullableSearchFilesResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSearchFilesResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_send_webhook_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SendWebhookDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SendWebhookDto{}\n\n// SendWebhookDto struct for SendWebhookDto\ntype SendWebhookDto struct {\n\t// The type of event being sent\n\tEventType WebhookEvent `json:\"eventType\"`\n\t// The payload data to send\n\tPayload map[string]interface{} `json:\"payload\"`\n\t// Optional event ID for idempotency\n\tEventId *string `json:\"eventId,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SendWebhookDto SendWebhookDto\n\n// NewSendWebhookDto instantiates a new SendWebhookDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSendWebhookDto(eventType WebhookEvent, payload map[string]interface{}) *SendWebhookDto {\n\tthis := SendWebhookDto{}\n\tthis.EventType = eventType\n\tthis.Payload = payload\n\treturn &this\n}\n\n// NewSendWebhookDtoWithDefaults instantiates a new SendWebhookDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSendWebhookDtoWithDefaults() *SendWebhookDto {\n\tthis := SendWebhookDto{}\n\treturn &this\n}\n\n// GetEventType returns the EventType field value\nfunc (o *SendWebhookDto) GetEventType() WebhookEvent {\n\tif o == nil {\n\t\tvar ret WebhookEvent\n\t\treturn ret\n\t}\n\n\treturn o.EventType\n}\n\n// GetEventTypeOk returns a tuple with the EventType field value\n// and a boolean to check if the value has been set.\nfunc (o *SendWebhookDto) GetEventTypeOk() (*WebhookEvent, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.EventType, true\n}\n\n// SetEventType sets field value\nfunc (o *SendWebhookDto) SetEventType(v WebhookEvent) {\n\to.EventType = v\n}\n\n// GetPayload returns the Payload field value\nfunc (o *SendWebhookDto) GetPayload() map[string]interface{} {\n\tif o == nil {\n\t\tvar ret map[string]interface{}\n\t\treturn ret\n\t}\n\n\treturn o.Payload\n}\n\n// GetPayloadOk returns a tuple with the Payload field value\n// and a boolean to check if the value has been set.\nfunc (o *SendWebhookDto) GetPayloadOk() (map[string]interface{}, bool) {\n\tif o == nil {\n\t\treturn map[string]interface{}{}, false\n\t}\n\treturn o.Payload, true\n}\n\n// SetPayload sets field value\nfunc (o *SendWebhookDto) SetPayload(v map[string]interface{}) {\n\to.Payload = v\n}\n\n// GetEventId returns the EventId field value if set, zero value otherwise.\nfunc (o *SendWebhookDto) GetEventId() string {\n\tif o == nil || IsNil(o.EventId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.EventId\n}\n\n// GetEventIdOk returns a tuple with the EventId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SendWebhookDto) GetEventIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.EventId) {\n\t\treturn nil, false\n\t}\n\treturn o.EventId, true\n}\n\n// HasEventId returns a boolean if a field has been set.\nfunc (o *SendWebhookDto) HasEventId() bool {\n\tif o != nil && !IsNil(o.EventId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetEventId gets a reference to the given string and assigns it to the EventId field.\nfunc (o *SendWebhookDto) SetEventId(v string) {\n\to.EventId = &v\n}\n\nfunc (o SendWebhookDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SendWebhookDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"eventType\"] = o.EventType\n\ttoSerialize[\"payload\"] = o.Payload\n\tif !IsNil(o.EventId) {\n\t\ttoSerialize[\"eventId\"] = o.EventId\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SendWebhookDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"eventType\",\n\t\t\"payload\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSendWebhookDto := _SendWebhookDto{}\n\n\terr = json.Unmarshal(data, &varSendWebhookDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SendWebhookDto(varSendWebhookDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"eventType\")\n\t\tdelete(additionalProperties, \"payload\")\n\t\tdelete(additionalProperties, \"eventId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSendWebhookDto struct {\n\tvalue *SendWebhookDto\n\tisSet bool\n}\n\nfunc (v NullableSendWebhookDto) Get() *SendWebhookDto {\n\treturn v.value\n}\n\nfunc (v *NullableSendWebhookDto) Set(val *SendWebhookDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSendWebhookDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSendWebhookDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSendWebhookDto(val *SendWebhookDto) *NullableSendWebhookDto {\n\treturn &NullableSendWebhookDto{value: val, isSet: true}\n}\n\nfunc (v NullableSendWebhookDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSendWebhookDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_session.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Session type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Session{}\n\n// Session struct for Session\ntype Session struct {\n\t// The ID of the session\n\tSessionId string `json:\"sessionId\"`\n\t// The list of commands executed in this session\n\tCommands []Command `json:\"commands\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Session Session\n\n// NewSession instantiates a new Session object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSession(sessionId string, commands []Command) *Session {\n\tthis := Session{}\n\tthis.SessionId = sessionId\n\tthis.Commands = commands\n\treturn &this\n}\n\n// NewSessionWithDefaults instantiates a new Session object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSessionWithDefaults() *Session {\n\tthis := Session{}\n\treturn &this\n}\n\n// GetSessionId returns the SessionId field value\nfunc (o *Session) GetSessionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SessionId\n}\n\n// GetSessionIdOk returns a tuple with the SessionId field value\n// and a boolean to check if the value has been set.\nfunc (o *Session) GetSessionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SessionId, true\n}\n\n// SetSessionId sets field value\nfunc (o *Session) SetSessionId(v string) {\n\to.SessionId = v\n}\n\n// GetCommands returns the Commands field value\n// If the value is explicit nil, the zero value for []Command will be returned\nfunc (o *Session) GetCommands() []Command {\n\tif o == nil {\n\t\tvar ret []Command\n\t\treturn ret\n\t}\n\n\treturn o.Commands\n}\n\n// GetCommandsOk returns a tuple with the Commands field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *Session) GetCommandsOk() ([]Command, bool) {\n\tif o == nil || IsNil(o.Commands) {\n\t\treturn nil, false\n\t}\n\treturn o.Commands, true\n}\n\n// SetCommands sets field value\nfunc (o *Session) SetCommands(v []Command) {\n\to.Commands = v\n}\n\nfunc (o Session) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Session) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"sessionId\"] = o.SessionId\n\tif o.Commands != nil {\n\t\ttoSerialize[\"commands\"] = o.Commands\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Session) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"sessionId\",\n\t\t\"commands\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSession := _Session{}\n\n\terr = json.Unmarshal(data, &varSession)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Session(varSession)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"sessionId\")\n\t\tdelete(additionalProperties, \"commands\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSession struct {\n\tvalue *Session\n\tisSet bool\n}\n\nfunc (v NullableSession) Get() *Session {\n\treturn v.value\n}\n\nfunc (v *NullableSession) Set(val *Session) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSession) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSession) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSession(val *Session) *NullableSession {\n\treturn &NullableSession{value: val, isSet: true}\n}\n\nfunc (v NullableSession) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSession) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_session_execute_request.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SessionExecuteRequest type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SessionExecuteRequest{}\n\n// SessionExecuteRequest struct for SessionExecuteRequest\ntype SessionExecuteRequest struct {\n\t// The command to execute\n\tCommand string `json:\"command\"`\n\t// Whether to execute the command asynchronously\n\tRunAsync *bool `json:\"runAsync,omitempty\"`\n\t// Deprecated: Use runAsync instead. Whether to execute the command asynchronously\n\t// Deprecated\n\tAsync *bool `json:\"async,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SessionExecuteRequest SessionExecuteRequest\n\n// NewSessionExecuteRequest instantiates a new SessionExecuteRequest object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSessionExecuteRequest(command string) *SessionExecuteRequest {\n\tthis := SessionExecuteRequest{}\n\tthis.Command = command\n\treturn &this\n}\n\n// NewSessionExecuteRequestWithDefaults instantiates a new SessionExecuteRequest object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSessionExecuteRequestWithDefaults() *SessionExecuteRequest {\n\tthis := SessionExecuteRequest{}\n\treturn &this\n}\n\n// GetCommand returns the Command field value\nfunc (o *SessionExecuteRequest) GetCommand() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Command\n}\n\n// GetCommandOk returns a tuple with the Command field value\n// and a boolean to check if the value has been set.\nfunc (o *SessionExecuteRequest) GetCommandOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Command, true\n}\n\n// SetCommand sets field value\nfunc (o *SessionExecuteRequest) SetCommand(v string) {\n\to.Command = v\n}\n\n// GetRunAsync returns the RunAsync field value if set, zero value otherwise.\nfunc (o *SessionExecuteRequest) GetRunAsync() bool {\n\tif o == nil || IsNil(o.RunAsync) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.RunAsync\n}\n\n// GetRunAsyncOk returns a tuple with the RunAsync field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SessionExecuteRequest) GetRunAsyncOk() (*bool, bool) {\n\tif o == nil || IsNil(o.RunAsync) {\n\t\treturn nil, false\n\t}\n\treturn o.RunAsync, true\n}\n\n// HasRunAsync returns a boolean if a field has been set.\nfunc (o *SessionExecuteRequest) HasRunAsync() bool {\n\tif o != nil && !IsNil(o.RunAsync) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRunAsync gets a reference to the given bool and assigns it to the RunAsync field.\nfunc (o *SessionExecuteRequest) SetRunAsync(v bool) {\n\to.RunAsync = &v\n}\n\n// GetAsync returns the Async field value if set, zero value otherwise.\n// Deprecated\nfunc (o *SessionExecuteRequest) GetAsync() bool {\n\tif o == nil || IsNil(o.Async) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Async\n}\n\n// GetAsyncOk returns a tuple with the Async field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *SessionExecuteRequest) GetAsyncOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Async) {\n\t\treturn nil, false\n\t}\n\treturn o.Async, true\n}\n\n// HasAsync returns a boolean if a field has been set.\nfunc (o *SessionExecuteRequest) HasAsync() bool {\n\tif o != nil && !IsNil(o.Async) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAsync gets a reference to the given bool and assigns it to the Async field.\n// Deprecated\nfunc (o *SessionExecuteRequest) SetAsync(v bool) {\n\to.Async = &v\n}\n\nfunc (o SessionExecuteRequest) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SessionExecuteRequest) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"command\"] = o.Command\n\tif !IsNil(o.RunAsync) {\n\t\ttoSerialize[\"runAsync\"] = o.RunAsync\n\t}\n\tif !IsNil(o.Async) {\n\t\ttoSerialize[\"async\"] = o.Async\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SessionExecuteRequest) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"command\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSessionExecuteRequest := _SessionExecuteRequest{}\n\n\terr = json.Unmarshal(data, &varSessionExecuteRequest)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SessionExecuteRequest(varSessionExecuteRequest)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"command\")\n\t\tdelete(additionalProperties, \"runAsync\")\n\t\tdelete(additionalProperties, \"async\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSessionExecuteRequest struct {\n\tvalue *SessionExecuteRequest\n\tisSet bool\n}\n\nfunc (v NullableSessionExecuteRequest) Get() *SessionExecuteRequest {\n\treturn v.value\n}\n\nfunc (v *NullableSessionExecuteRequest) Set(val *SessionExecuteRequest) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSessionExecuteRequest) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSessionExecuteRequest) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSessionExecuteRequest(val *SessionExecuteRequest) *NullableSessionExecuteRequest {\n\treturn &NullableSessionExecuteRequest{value: val, isSet: true}\n}\n\nfunc (v NullableSessionExecuteRequest) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSessionExecuteRequest) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_session_execute_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the SessionExecuteResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SessionExecuteResponse{}\n\n// SessionExecuteResponse struct for SessionExecuteResponse\ntype SessionExecuteResponse struct {\n\t// The ID of the executed command\n\tCmdId *string `json:\"cmdId,omitempty\"`\n\t// The output of the executed command marked with stdout and stderr prefixes\n\tOutput *string `json:\"output,omitempty\"`\n\t// The exit code of the executed command\n\tExitCode *float32 `json:\"exitCode,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SessionExecuteResponse SessionExecuteResponse\n\n// NewSessionExecuteResponse instantiates a new SessionExecuteResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSessionExecuteResponse() *SessionExecuteResponse {\n\tthis := SessionExecuteResponse{}\n\treturn &this\n}\n\n// NewSessionExecuteResponseWithDefaults instantiates a new SessionExecuteResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSessionExecuteResponseWithDefaults() *SessionExecuteResponse {\n\tthis := SessionExecuteResponse{}\n\treturn &this\n}\n\n// GetCmdId returns the CmdId field value if set, zero value otherwise.\nfunc (o *SessionExecuteResponse) GetCmdId() string {\n\tif o == nil || IsNil(o.CmdId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.CmdId\n}\n\n// GetCmdIdOk returns a tuple with the CmdId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SessionExecuteResponse) GetCmdIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.CmdId) {\n\t\treturn nil, false\n\t}\n\treturn o.CmdId, true\n}\n\n// HasCmdId returns a boolean if a field has been set.\nfunc (o *SessionExecuteResponse) HasCmdId() bool {\n\tif o != nil && !IsNil(o.CmdId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCmdId gets a reference to the given string and assigns it to the CmdId field.\nfunc (o *SessionExecuteResponse) SetCmdId(v string) {\n\to.CmdId = &v\n}\n\n// GetOutput returns the Output field value if set, zero value otherwise.\nfunc (o *SessionExecuteResponse) GetOutput() string {\n\tif o == nil || IsNil(o.Output) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Output\n}\n\n// GetOutputOk returns a tuple with the Output field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SessionExecuteResponse) GetOutputOk() (*string, bool) {\n\tif o == nil || IsNil(o.Output) {\n\t\treturn nil, false\n\t}\n\treturn o.Output, true\n}\n\n// HasOutput returns a boolean if a field has been set.\nfunc (o *SessionExecuteResponse) HasOutput() bool {\n\tif o != nil && !IsNil(o.Output) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetOutput gets a reference to the given string and assigns it to the Output field.\nfunc (o *SessionExecuteResponse) SetOutput(v string) {\n\to.Output = &v\n}\n\n// GetExitCode returns the ExitCode field value if set, zero value otherwise.\nfunc (o *SessionExecuteResponse) GetExitCode() float32 {\n\tif o == nil || IsNil(o.ExitCode) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.ExitCode\n}\n\n// GetExitCodeOk returns a tuple with the ExitCode field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SessionExecuteResponse) GetExitCodeOk() (*float32, bool) {\n\tif o == nil || IsNil(o.ExitCode) {\n\t\treturn nil, false\n\t}\n\treturn o.ExitCode, true\n}\n\n// HasExitCode returns a boolean if a field has been set.\nfunc (o *SessionExecuteResponse) HasExitCode() bool {\n\tif o != nil && !IsNil(o.ExitCode) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetExitCode gets a reference to the given float32 and assigns it to the ExitCode field.\nfunc (o *SessionExecuteResponse) SetExitCode(v float32) {\n\to.ExitCode = &v\n}\n\nfunc (o SessionExecuteResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SessionExecuteResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.CmdId) {\n\t\ttoSerialize[\"cmdId\"] = o.CmdId\n\t}\n\tif !IsNil(o.Output) {\n\t\ttoSerialize[\"output\"] = o.Output\n\t}\n\tif !IsNil(o.ExitCode) {\n\t\ttoSerialize[\"exitCode\"] = o.ExitCode\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SessionExecuteResponse) UnmarshalJSON(data []byte) (err error) {\n\tvarSessionExecuteResponse := _SessionExecuteResponse{}\n\n\terr = json.Unmarshal(data, &varSessionExecuteResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SessionExecuteResponse(varSessionExecuteResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"cmdId\")\n\t\tdelete(additionalProperties, \"output\")\n\t\tdelete(additionalProperties, \"exitCode\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSessionExecuteResponse struct {\n\tvalue *SessionExecuteResponse\n\tisSet bool\n}\n\nfunc (v NullableSessionExecuteResponse) Get() *SessionExecuteResponse {\n\treturn v.value\n}\n\nfunc (v *NullableSessionExecuteResponse) Set(val *SessionExecuteResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSessionExecuteResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSessionExecuteResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSessionExecuteResponse(val *SessionExecuteResponse) *NullableSessionExecuteResponse {\n\treturn &NullableSessionExecuteResponse{value: val, isSet: true}\n}\n\nfunc (v NullableSessionExecuteResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSessionExecuteResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_set_snapshot_general_status_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SetSnapshotGeneralStatusDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SetSnapshotGeneralStatusDto{}\n\n// SetSnapshotGeneralStatusDto struct for SetSnapshotGeneralStatusDto\ntype SetSnapshotGeneralStatusDto struct {\n\t// Whether the snapshot is general\n\tGeneral bool `json:\"general\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SetSnapshotGeneralStatusDto SetSnapshotGeneralStatusDto\n\n// NewSetSnapshotGeneralStatusDto instantiates a new SetSnapshotGeneralStatusDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSetSnapshotGeneralStatusDto(general bool) *SetSnapshotGeneralStatusDto {\n\tthis := SetSnapshotGeneralStatusDto{}\n\tthis.General = general\n\treturn &this\n}\n\n// NewSetSnapshotGeneralStatusDtoWithDefaults instantiates a new SetSnapshotGeneralStatusDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSetSnapshotGeneralStatusDtoWithDefaults() *SetSnapshotGeneralStatusDto {\n\tthis := SetSnapshotGeneralStatusDto{}\n\treturn &this\n}\n\n// GetGeneral returns the General field value\nfunc (o *SetSnapshotGeneralStatusDto) GetGeneral() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.General\n}\n\n// GetGeneralOk returns a tuple with the General field value\n// and a boolean to check if the value has been set.\nfunc (o *SetSnapshotGeneralStatusDto) GetGeneralOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.General, true\n}\n\n// SetGeneral sets field value\nfunc (o *SetSnapshotGeneralStatusDto) SetGeneral(v bool) {\n\to.General = v\n}\n\nfunc (o SetSnapshotGeneralStatusDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SetSnapshotGeneralStatusDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"general\"] = o.General\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SetSnapshotGeneralStatusDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"general\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSetSnapshotGeneralStatusDto := _SetSnapshotGeneralStatusDto{}\n\n\terr = json.Unmarshal(data, &varSetSnapshotGeneralStatusDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SetSnapshotGeneralStatusDto(varSetSnapshotGeneralStatusDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"general\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSetSnapshotGeneralStatusDto struct {\n\tvalue *SetSnapshotGeneralStatusDto\n\tisSet bool\n}\n\nfunc (v NullableSetSnapshotGeneralStatusDto) Get() *SetSnapshotGeneralStatusDto {\n\treturn v.value\n}\n\nfunc (v *NullableSetSnapshotGeneralStatusDto) Set(val *SetSnapshotGeneralStatusDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSetSnapshotGeneralStatusDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSetSnapshotGeneralStatusDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSetSnapshotGeneralStatusDto(val *SetSnapshotGeneralStatusDto) *NullableSetSnapshotGeneralStatusDto {\n\treturn &NullableSetSnapshotGeneralStatusDto{value: val, isSet: true}\n}\n\nfunc (v NullableSetSnapshotGeneralStatusDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSetSnapshotGeneralStatusDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_signed_port_preview_url.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SignedPortPreviewUrl type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SignedPortPreviewUrl{}\n\n// SignedPortPreviewUrl struct for SignedPortPreviewUrl\ntype SignedPortPreviewUrl struct {\n\t// ID of the sandbox\n\tSandboxId string `json:\"sandboxId\"`\n\t// Port number of the signed preview URL\n\tPort int32 `json:\"port\"`\n\t// Token of the signed preview URL\n\tToken string `json:\"token\"`\n\t// Signed preview url\n\tUrl string `json:\"url\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SignedPortPreviewUrl SignedPortPreviewUrl\n\n// NewSignedPortPreviewUrl instantiates a new SignedPortPreviewUrl object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSignedPortPreviewUrl(sandboxId string, port int32, token string, url string) *SignedPortPreviewUrl {\n\tthis := SignedPortPreviewUrl{}\n\tthis.SandboxId = sandboxId\n\tthis.Port = port\n\tthis.Token = token\n\tthis.Url = url\n\treturn &this\n}\n\n// NewSignedPortPreviewUrlWithDefaults instantiates a new SignedPortPreviewUrl object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSignedPortPreviewUrlWithDefaults() *SignedPortPreviewUrl {\n\tthis := SignedPortPreviewUrl{}\n\treturn &this\n}\n\n// GetSandboxId returns the SandboxId field value\nfunc (o *SignedPortPreviewUrl) GetSandboxId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SandboxId\n}\n\n// GetSandboxIdOk returns a tuple with the SandboxId field value\n// and a boolean to check if the value has been set.\nfunc (o *SignedPortPreviewUrl) GetSandboxIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SandboxId, true\n}\n\n// SetSandboxId sets field value\nfunc (o *SignedPortPreviewUrl) SetSandboxId(v string) {\n\to.SandboxId = v\n}\n\n// GetPort returns the Port field value\nfunc (o *SignedPortPreviewUrl) GetPort() int32 {\n\tif o == nil {\n\t\tvar ret int32\n\t\treturn ret\n\t}\n\n\treturn o.Port\n}\n\n// GetPortOk returns a tuple with the Port field value\n// and a boolean to check if the value has been set.\nfunc (o *SignedPortPreviewUrl) GetPortOk() (*int32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Port, true\n}\n\n// SetPort sets field value\nfunc (o *SignedPortPreviewUrl) SetPort(v int32) {\n\to.Port = v\n}\n\n// GetToken returns the Token field value\nfunc (o *SignedPortPreviewUrl) GetToken() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Token\n}\n\n// GetTokenOk returns a tuple with the Token field value\n// and a boolean to check if the value has been set.\nfunc (o *SignedPortPreviewUrl) GetTokenOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Token, true\n}\n\n// SetToken sets field value\nfunc (o *SignedPortPreviewUrl) SetToken(v string) {\n\to.Token = v\n}\n\n// GetUrl returns the Url field value\nfunc (o *SignedPortPreviewUrl) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *SignedPortPreviewUrl) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *SignedPortPreviewUrl) SetUrl(v string) {\n\to.Url = v\n}\n\nfunc (o SignedPortPreviewUrl) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SignedPortPreviewUrl) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"sandboxId\"] = o.SandboxId\n\ttoSerialize[\"port\"] = o.Port\n\ttoSerialize[\"token\"] = o.Token\n\ttoSerialize[\"url\"] = o.Url\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SignedPortPreviewUrl) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"sandboxId\",\n\t\t\"port\",\n\t\t\"token\",\n\t\t\"url\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSignedPortPreviewUrl := _SignedPortPreviewUrl{}\n\n\terr = json.Unmarshal(data, &varSignedPortPreviewUrl)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SignedPortPreviewUrl(varSignedPortPreviewUrl)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"sandboxId\")\n\t\tdelete(additionalProperties, \"port\")\n\t\tdelete(additionalProperties, \"token\")\n\t\tdelete(additionalProperties, \"url\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSignedPortPreviewUrl struct {\n\tvalue *SignedPortPreviewUrl\n\tisSet bool\n}\n\nfunc (v NullableSignedPortPreviewUrl) Get() *SignedPortPreviewUrl {\n\treturn v.value\n}\n\nfunc (v *NullableSignedPortPreviewUrl) Set(val *SignedPortPreviewUrl) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSignedPortPreviewUrl) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSignedPortPreviewUrl) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSignedPortPreviewUrl(val *SignedPortPreviewUrl) *NullableSignedPortPreviewUrl {\n\treturn &NullableSignedPortPreviewUrl{value: val, isSet: true}\n}\n\nfunc (v NullableSignedPortPreviewUrl) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSignedPortPreviewUrl) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_snapshot_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the SnapshotDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SnapshotDto{}\n\n// SnapshotDto struct for SnapshotDto\ntype SnapshotDto struct {\n\tId string `json:\"id\"`\n\tOrganizationId *string `json:\"organizationId,omitempty\"`\n\tGeneral bool `json:\"general\"`\n\tName string `json:\"name\"`\n\tImageName *string `json:\"imageName,omitempty\"`\n\tState SnapshotState `json:\"state\"`\n\tSize NullableFloat32 `json:\"size\"`\n\tEntrypoint []string `json:\"entrypoint\"`\n\tCpu float32 `json:\"cpu\"`\n\tGpu float32 `json:\"gpu\"`\n\tMem float32 `json:\"mem\"`\n\tDisk float32 `json:\"disk\"`\n\tErrorReason NullableString `json:\"errorReason\"`\n\tCreatedAt time.Time `json:\"createdAt\"`\n\tUpdatedAt time.Time `json:\"updatedAt\"`\n\tLastUsedAt NullableTime `json:\"lastUsedAt\"`\n\t// Build information for the snapshot\n\tBuildInfo *BuildInfo `json:\"buildInfo,omitempty\"`\n\t// IDs of regions where the snapshot is available\n\tRegionIds []string `json:\"regionIds,omitempty\"`\n\t// The initial runner ID of the snapshot\n\tInitialRunnerId *string `json:\"initialRunnerId,omitempty\"`\n\t// The snapshot reference\n\tRef *string `json:\"ref,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SnapshotDto SnapshotDto\n\n// NewSnapshotDto instantiates a new SnapshotDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSnapshotDto(id string, general bool, name string, state SnapshotState, size NullableFloat32, entrypoint []string, cpu float32, gpu float32, mem float32, disk float32, errorReason NullableString, createdAt time.Time, updatedAt time.Time, lastUsedAt NullableTime) *SnapshotDto {\n\tthis := SnapshotDto{}\n\tthis.Id = id\n\tthis.General = general\n\tthis.Name = name\n\tthis.State = state\n\tthis.Size = size\n\tthis.Entrypoint = entrypoint\n\tthis.Cpu = cpu\n\tthis.Gpu = gpu\n\tthis.Mem = mem\n\tthis.Disk = disk\n\tthis.ErrorReason = errorReason\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\tthis.LastUsedAt = lastUsedAt\n\treturn &this\n}\n\n// NewSnapshotDtoWithDefaults instantiates a new SnapshotDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSnapshotDtoWithDefaults() *SnapshotDto {\n\tthis := SnapshotDto{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *SnapshotDto) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *SnapshotDto) SetId(v string) {\n\to.Id = v\n}\n\n// GetOrganizationId returns the OrganizationId field value if set, zero value otherwise.\nfunc (o *SnapshotDto) GetOrganizationId() string {\n\tif o == nil || IsNil(o.OrganizationId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.OrganizationId) {\n\t\treturn nil, false\n\t}\n\treturn o.OrganizationId, true\n}\n\n// HasOrganizationId returns a boolean if a field has been set.\nfunc (o *SnapshotDto) HasOrganizationId() bool {\n\tif o != nil && !IsNil(o.OrganizationId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetOrganizationId gets a reference to the given string and assigns it to the OrganizationId field.\nfunc (o *SnapshotDto) SetOrganizationId(v string) {\n\to.OrganizationId = &v\n}\n\n// GetGeneral returns the General field value\nfunc (o *SnapshotDto) GetGeneral() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.General\n}\n\n// GetGeneralOk returns a tuple with the General field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetGeneralOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.General, true\n}\n\n// SetGeneral sets field value\nfunc (o *SnapshotDto) SetGeneral(v bool) {\n\to.General = v\n}\n\n// GetName returns the Name field value\nfunc (o *SnapshotDto) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *SnapshotDto) SetName(v string) {\n\to.Name = v\n}\n\n// GetImageName returns the ImageName field value if set, zero value otherwise.\nfunc (o *SnapshotDto) GetImageName() string {\n\tif o == nil || IsNil(o.ImageName) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ImageName\n}\n\n// GetImageNameOk returns a tuple with the ImageName field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetImageNameOk() (*string, bool) {\n\tif o == nil || IsNil(o.ImageName) {\n\t\treturn nil, false\n\t}\n\treturn o.ImageName, true\n}\n\n// HasImageName returns a boolean if a field has been set.\nfunc (o *SnapshotDto) HasImageName() bool {\n\tif o != nil && !IsNil(o.ImageName) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetImageName gets a reference to the given string and assigns it to the ImageName field.\nfunc (o *SnapshotDto) SetImageName(v string) {\n\to.ImageName = &v\n}\n\n// GetState returns the State field value\nfunc (o *SnapshotDto) GetState() SnapshotState {\n\tif o == nil {\n\t\tvar ret SnapshotState\n\t\treturn ret\n\t}\n\n\treturn o.State\n}\n\n// GetStateOk returns a tuple with the State field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetStateOk() (*SnapshotState, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.State, true\n}\n\n// SetState sets field value\nfunc (o *SnapshotDto) SetState(v SnapshotState) {\n\to.State = v\n}\n\n// GetSize returns the Size field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *SnapshotDto) GetSize() float32 {\n\tif o == nil || o.Size.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.Size.Get()\n}\n\n// GetSizeOk returns a tuple with the Size field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *SnapshotDto) GetSizeOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Size.Get(), o.Size.IsSet()\n}\n\n// SetSize sets field value\nfunc (o *SnapshotDto) SetSize(v float32) {\n\to.Size.Set(&v)\n}\n\n// GetEntrypoint returns the Entrypoint field value\n// If the value is explicit nil, the zero value for []string will be returned\nfunc (o *SnapshotDto) GetEntrypoint() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Entrypoint\n}\n\n// GetEntrypointOk returns a tuple with the Entrypoint field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *SnapshotDto) GetEntrypointOk() ([]string, bool) {\n\tif o == nil || IsNil(o.Entrypoint) {\n\t\treturn nil, false\n\t}\n\treturn o.Entrypoint, true\n}\n\n// SetEntrypoint sets field value\nfunc (o *SnapshotDto) SetEntrypoint(v []string) {\n\to.Entrypoint = v\n}\n\n// GetCpu returns the Cpu field value\nfunc (o *SnapshotDto) GetCpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetCpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cpu, true\n}\n\n// SetCpu sets field value\nfunc (o *SnapshotDto) SetCpu(v float32) {\n\to.Cpu = v\n}\n\n// GetGpu returns the Gpu field value\nfunc (o *SnapshotDto) GetGpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Gpu\n}\n\n// GetGpuOk returns a tuple with the Gpu field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetGpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Gpu, true\n}\n\n// SetGpu sets field value\nfunc (o *SnapshotDto) SetGpu(v float32) {\n\to.Gpu = v\n}\n\n// GetMem returns the Mem field value\nfunc (o *SnapshotDto) GetMem() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Mem\n}\n\n// GetMemOk returns a tuple with the Mem field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetMemOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Mem, true\n}\n\n// SetMem sets field value\nfunc (o *SnapshotDto) SetMem(v float32) {\n\to.Mem = v\n}\n\n// GetDisk returns the Disk field value\nfunc (o *SnapshotDto) GetDisk() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetDiskOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Disk, true\n}\n\n// SetDisk sets field value\nfunc (o *SnapshotDto) SetDisk(v float32) {\n\to.Disk = v\n}\n\n// GetErrorReason returns the ErrorReason field value\n// If the value is explicit nil, the zero value for string will be returned\nfunc (o *SnapshotDto) GetErrorReason() string {\n\tif o == nil || o.ErrorReason.Get() == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn *o.ErrorReason.Get()\n}\n\n// GetErrorReasonOk returns a tuple with the ErrorReason field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *SnapshotDto) GetErrorReasonOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorReason.Get(), o.ErrorReason.IsSet()\n}\n\n// SetErrorReason sets field value\nfunc (o *SnapshotDto) SetErrorReason(v string) {\n\to.ErrorReason.Set(&v)\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *SnapshotDto) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *SnapshotDto) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *SnapshotDto) GetUpdatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetUpdatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *SnapshotDto) SetUpdatedAt(v time.Time) {\n\to.UpdatedAt = v\n}\n\n// GetLastUsedAt returns the LastUsedAt field value\n// If the value is explicit nil, the zero value for time.Time will be returned\nfunc (o *SnapshotDto) GetLastUsedAt() time.Time {\n\tif o == nil || o.LastUsedAt.Get() == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn *o.LastUsedAt.Get()\n}\n\n// GetLastUsedAtOk returns a tuple with the LastUsedAt field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *SnapshotDto) GetLastUsedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.LastUsedAt.Get(), o.LastUsedAt.IsSet()\n}\n\n// SetLastUsedAt sets field value\nfunc (o *SnapshotDto) SetLastUsedAt(v time.Time) {\n\to.LastUsedAt.Set(&v)\n}\n\n// GetBuildInfo returns the BuildInfo field value if set, zero value otherwise.\nfunc (o *SnapshotDto) GetBuildInfo() BuildInfo {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\tvar ret BuildInfo\n\t\treturn ret\n\t}\n\treturn *o.BuildInfo\n}\n\n// GetBuildInfoOk returns a tuple with the BuildInfo field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetBuildInfoOk() (*BuildInfo, bool) {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\treturn nil, false\n\t}\n\treturn o.BuildInfo, true\n}\n\n// HasBuildInfo returns a boolean if a field has been set.\nfunc (o *SnapshotDto) HasBuildInfo() bool {\n\tif o != nil && !IsNil(o.BuildInfo) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBuildInfo gets a reference to the given BuildInfo and assigns it to the BuildInfo field.\nfunc (o *SnapshotDto) SetBuildInfo(v BuildInfo) {\n\to.BuildInfo = &v\n}\n\n// GetRegionIds returns the RegionIds field value if set, zero value otherwise.\nfunc (o *SnapshotDto) GetRegionIds() []string {\n\tif o == nil || IsNil(o.RegionIds) {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\treturn o.RegionIds\n}\n\n// GetRegionIdsOk returns a tuple with the RegionIds field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetRegionIdsOk() ([]string, bool) {\n\tif o == nil || IsNil(o.RegionIds) {\n\t\treturn nil, false\n\t}\n\treturn o.RegionIds, true\n}\n\n// HasRegionIds returns a boolean if a field has been set.\nfunc (o *SnapshotDto) HasRegionIds() bool {\n\tif o != nil && !IsNil(o.RegionIds) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRegionIds gets a reference to the given []string and assigns it to the RegionIds field.\nfunc (o *SnapshotDto) SetRegionIds(v []string) {\n\to.RegionIds = v\n}\n\n// GetInitialRunnerId returns the InitialRunnerId field value if set, zero value otherwise.\nfunc (o *SnapshotDto) GetInitialRunnerId() string {\n\tif o == nil || IsNil(o.InitialRunnerId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.InitialRunnerId\n}\n\n// GetInitialRunnerIdOk returns a tuple with the InitialRunnerId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetInitialRunnerIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.InitialRunnerId) {\n\t\treturn nil, false\n\t}\n\treturn o.InitialRunnerId, true\n}\n\n// HasInitialRunnerId returns a boolean if a field has been set.\nfunc (o *SnapshotDto) HasInitialRunnerId() bool {\n\tif o != nil && !IsNil(o.InitialRunnerId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetInitialRunnerId gets a reference to the given string and assigns it to the InitialRunnerId field.\nfunc (o *SnapshotDto) SetInitialRunnerId(v string) {\n\to.InitialRunnerId = &v\n}\n\n// GetRef returns the Ref field value if set, zero value otherwise.\nfunc (o *SnapshotDto) GetRef() string {\n\tif o == nil || IsNil(o.Ref) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Ref\n}\n\n// GetRefOk returns a tuple with the Ref field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotDto) GetRefOk() (*string, bool) {\n\tif o == nil || IsNil(o.Ref) {\n\t\treturn nil, false\n\t}\n\treturn o.Ref, true\n}\n\n// HasRef returns a boolean if a field has been set.\nfunc (o *SnapshotDto) HasRef() bool {\n\tif o != nil && !IsNil(o.Ref) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRef gets a reference to the given string and assigns it to the Ref field.\nfunc (o *SnapshotDto) SetRef(v string) {\n\to.Ref = &v\n}\n\nfunc (o SnapshotDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SnapshotDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\tif !IsNil(o.OrganizationId) {\n\t\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\t}\n\ttoSerialize[\"general\"] = o.General\n\ttoSerialize[\"name\"] = o.Name\n\tif !IsNil(o.ImageName) {\n\t\ttoSerialize[\"imageName\"] = o.ImageName\n\t}\n\ttoSerialize[\"state\"] = o.State\n\ttoSerialize[\"size\"] = o.Size.Get()\n\tif o.Entrypoint != nil {\n\t\ttoSerialize[\"entrypoint\"] = o.Entrypoint\n\t}\n\ttoSerialize[\"cpu\"] = o.Cpu\n\ttoSerialize[\"gpu\"] = o.Gpu\n\ttoSerialize[\"mem\"] = o.Mem\n\ttoSerialize[\"disk\"] = o.Disk\n\ttoSerialize[\"errorReason\"] = o.ErrorReason.Get()\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\ttoSerialize[\"lastUsedAt\"] = o.LastUsedAt.Get()\n\tif !IsNil(o.BuildInfo) {\n\t\ttoSerialize[\"buildInfo\"] = o.BuildInfo\n\t}\n\tif !IsNil(o.RegionIds) {\n\t\ttoSerialize[\"regionIds\"] = o.RegionIds\n\t}\n\tif !IsNil(o.InitialRunnerId) {\n\t\ttoSerialize[\"initialRunnerId\"] = o.InitialRunnerId\n\t}\n\tif !IsNil(o.Ref) {\n\t\ttoSerialize[\"ref\"] = o.Ref\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SnapshotDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"general\",\n\t\t\"name\",\n\t\t\"state\",\n\t\t\"size\",\n\t\t\"entrypoint\",\n\t\t\"cpu\",\n\t\t\"gpu\",\n\t\t\"mem\",\n\t\t\"disk\",\n\t\t\"errorReason\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t\t\"lastUsedAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSnapshotDto := _SnapshotDto{}\n\n\terr = json.Unmarshal(data, &varSnapshotDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SnapshotDto(varSnapshotDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"general\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"imageName\")\n\t\tdelete(additionalProperties, \"state\")\n\t\tdelete(additionalProperties, \"size\")\n\t\tdelete(additionalProperties, \"entrypoint\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"gpu\")\n\t\tdelete(additionalProperties, \"mem\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\tdelete(additionalProperties, \"errorReason\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"lastUsedAt\")\n\t\tdelete(additionalProperties, \"buildInfo\")\n\t\tdelete(additionalProperties, \"regionIds\")\n\t\tdelete(additionalProperties, \"initialRunnerId\")\n\t\tdelete(additionalProperties, \"ref\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSnapshotDto struct {\n\tvalue *SnapshotDto\n\tisSet bool\n}\n\nfunc (v NullableSnapshotDto) Get() *SnapshotDto {\n\treturn v.value\n}\n\nfunc (v *NullableSnapshotDto) Set(val *SnapshotDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSnapshotDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSnapshotDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSnapshotDto(val *SnapshotDto) *NullableSnapshotDto {\n\treturn &NullableSnapshotDto{value: val, isSet: true}\n}\n\nfunc (v NullableSnapshotDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSnapshotDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_snapshot_manager_credentials.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SnapshotManagerCredentials type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SnapshotManagerCredentials{}\n\n// SnapshotManagerCredentials struct for SnapshotManagerCredentials\ntype SnapshotManagerCredentials struct {\n\t// Snapshot Manager username for the region\n\tUsername string `json:\"username\"`\n\t// Snapshot Manager password for the region\n\tPassword string `json:\"password\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SnapshotManagerCredentials SnapshotManagerCredentials\n\n// NewSnapshotManagerCredentials instantiates a new SnapshotManagerCredentials object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSnapshotManagerCredentials(username string, password string) *SnapshotManagerCredentials {\n\tthis := SnapshotManagerCredentials{}\n\tthis.Username = username\n\tthis.Password = password\n\treturn &this\n}\n\n// NewSnapshotManagerCredentialsWithDefaults instantiates a new SnapshotManagerCredentials object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSnapshotManagerCredentialsWithDefaults() *SnapshotManagerCredentials {\n\tthis := SnapshotManagerCredentials{}\n\treturn &this\n}\n\n// GetUsername returns the Username field value\nfunc (o *SnapshotManagerCredentials) GetUsername() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Username\n}\n\n// GetUsernameOk returns a tuple with the Username field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotManagerCredentials) GetUsernameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Username, true\n}\n\n// SetUsername sets field value\nfunc (o *SnapshotManagerCredentials) SetUsername(v string) {\n\to.Username = v\n}\n\n// GetPassword returns the Password field value\nfunc (o *SnapshotManagerCredentials) GetPassword() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Password\n}\n\n// GetPasswordOk returns a tuple with the Password field value\n// and a boolean to check if the value has been set.\nfunc (o *SnapshotManagerCredentials) GetPasswordOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Password, true\n}\n\n// SetPassword sets field value\nfunc (o *SnapshotManagerCredentials) SetPassword(v string) {\n\to.Password = v\n}\n\nfunc (o SnapshotManagerCredentials) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SnapshotManagerCredentials) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"username\"] = o.Username\n\ttoSerialize[\"password\"] = o.Password\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SnapshotManagerCredentials) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"username\",\n\t\t\"password\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSnapshotManagerCredentials := _SnapshotManagerCredentials{}\n\n\terr = json.Unmarshal(data, &varSnapshotManagerCredentials)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SnapshotManagerCredentials(varSnapshotManagerCredentials)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"username\")\n\t\tdelete(additionalProperties, \"password\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSnapshotManagerCredentials struct {\n\tvalue *SnapshotManagerCredentials\n\tisSet bool\n}\n\nfunc (v NullableSnapshotManagerCredentials) Get() *SnapshotManagerCredentials {\n\treturn v.value\n}\n\nfunc (v *NullableSnapshotManagerCredentials) Set(val *SnapshotManagerCredentials) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSnapshotManagerCredentials) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSnapshotManagerCredentials) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSnapshotManagerCredentials(val *SnapshotManagerCredentials) *NullableSnapshotManagerCredentials {\n\treturn &NullableSnapshotManagerCredentials{value: val, isSet: true}\n}\n\nfunc (v NullableSnapshotManagerCredentials) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSnapshotManagerCredentials) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_snapshot_state.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// SnapshotState the model 'SnapshotState'\ntype SnapshotState string\n\n// List of SnapshotState\nconst (\n\tSNAPSHOTSTATE_BUILDING SnapshotState = \"building\"\n\tSNAPSHOTSTATE_PENDING SnapshotState = \"pending\"\n\tSNAPSHOTSTATE_PULLING SnapshotState = \"pulling\"\n\tSNAPSHOTSTATE_ACTIVE SnapshotState = \"active\"\n\tSNAPSHOTSTATE_INACTIVE SnapshotState = \"inactive\"\n\tSNAPSHOTSTATE_ERROR SnapshotState = \"error\"\n\tSNAPSHOTSTATE_BUILD_FAILED SnapshotState = \"build_failed\"\n\tSNAPSHOTSTATE_REMOVING SnapshotState = \"removing\"\n)\n\n// All allowed values of SnapshotState enum\nvar AllowedSnapshotStateEnumValues = []SnapshotState{\n\t\"building\",\n\t\"pending\",\n\t\"pulling\",\n\t\"active\",\n\t\"inactive\",\n\t\"error\",\n\t\"build_failed\",\n\t\"removing\",\n}\n\nfunc (v *SnapshotState) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := SnapshotState(value)\n\tfor _, existing := range AllowedSnapshotStateEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid SnapshotState\", value)\n}\n\n// NewSnapshotStateFromValue returns a pointer to a valid SnapshotState\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewSnapshotStateFromValue(v string) (*SnapshotState, error) {\n\tev := SnapshotState(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for SnapshotState: valid values are %v\", v, AllowedSnapshotStateEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v SnapshotState) IsValid() bool {\n\tfor _, existing := range AllowedSnapshotStateEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to SnapshotState value\nfunc (v SnapshotState) Ptr() *SnapshotState {\n\treturn &v\n}\n\ntype NullableSnapshotState struct {\n\tvalue *SnapshotState\n\tisSet bool\n}\n\nfunc (v NullableSnapshotState) Get() *SnapshotState {\n\treturn v.value\n}\n\nfunc (v *NullableSnapshotState) Set(val *SnapshotState) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSnapshotState) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSnapshotState) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSnapshotState(val *SnapshotState) *NullableSnapshotState {\n\treturn &NullableSnapshotState{value: val, isSet: true}\n}\n\nfunc (v NullableSnapshotState) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSnapshotState) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_ssh_access_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the SshAccessDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SshAccessDto{}\n\n// SshAccessDto struct for SshAccessDto\ntype SshAccessDto struct {\n\t// Unique identifier for the SSH access\n\tId string `json:\"id\"`\n\t// ID of the sandbox this SSH access is for\n\tSandboxId string `json:\"sandboxId\"`\n\t// SSH access token\n\tToken string `json:\"token\"`\n\t// When the SSH access expires\n\tExpiresAt time.Time `json:\"expiresAt\"`\n\t// When the SSH access was created\n\tCreatedAt time.Time `json:\"createdAt\"`\n\t// When the SSH access was last updated\n\tUpdatedAt time.Time `json:\"updatedAt\"`\n\t// SSH command to connect to the sandbox\n\tSshCommand string `json:\"sshCommand\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SshAccessDto SshAccessDto\n\n// NewSshAccessDto instantiates a new SshAccessDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSshAccessDto(id string, sandboxId string, token string, expiresAt time.Time, createdAt time.Time, updatedAt time.Time, sshCommand string) *SshAccessDto {\n\tthis := SshAccessDto{}\n\tthis.Id = id\n\tthis.SandboxId = sandboxId\n\tthis.Token = token\n\tthis.ExpiresAt = expiresAt\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\tthis.SshCommand = sshCommand\n\treturn &this\n}\n\n// NewSshAccessDtoWithDefaults instantiates a new SshAccessDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSshAccessDtoWithDefaults() *SshAccessDto {\n\tthis := SshAccessDto{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *SshAccessDto) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessDto) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *SshAccessDto) SetId(v string) {\n\to.Id = v\n}\n\n// GetSandboxId returns the SandboxId field value\nfunc (o *SshAccessDto) GetSandboxId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SandboxId\n}\n\n// GetSandboxIdOk returns a tuple with the SandboxId field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessDto) GetSandboxIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SandboxId, true\n}\n\n// SetSandboxId sets field value\nfunc (o *SshAccessDto) SetSandboxId(v string) {\n\to.SandboxId = v\n}\n\n// GetToken returns the Token field value\nfunc (o *SshAccessDto) GetToken() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Token\n}\n\n// GetTokenOk returns a tuple with the Token field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessDto) GetTokenOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Token, true\n}\n\n// SetToken sets field value\nfunc (o *SshAccessDto) SetToken(v string) {\n\to.Token = v\n}\n\n// GetExpiresAt returns the ExpiresAt field value\nfunc (o *SshAccessDto) GetExpiresAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.ExpiresAt\n}\n\n// GetExpiresAtOk returns a tuple with the ExpiresAt field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessDto) GetExpiresAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ExpiresAt, true\n}\n\n// SetExpiresAt sets field value\nfunc (o *SshAccessDto) SetExpiresAt(v time.Time) {\n\to.ExpiresAt = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *SshAccessDto) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessDto) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *SshAccessDto) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *SshAccessDto) GetUpdatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessDto) GetUpdatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *SshAccessDto) SetUpdatedAt(v time.Time) {\n\to.UpdatedAt = v\n}\n\n// GetSshCommand returns the SshCommand field value\nfunc (o *SshAccessDto) GetSshCommand() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SshCommand\n}\n\n// GetSshCommandOk returns a tuple with the SshCommand field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessDto) GetSshCommandOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SshCommand, true\n}\n\n// SetSshCommand sets field value\nfunc (o *SshAccessDto) SetSshCommand(v string) {\n\to.SshCommand = v\n}\n\nfunc (o SshAccessDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SshAccessDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"sandboxId\"] = o.SandboxId\n\ttoSerialize[\"token\"] = o.Token\n\ttoSerialize[\"expiresAt\"] = o.ExpiresAt\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\ttoSerialize[\"sshCommand\"] = o.SshCommand\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SshAccessDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"sandboxId\",\n\t\t\"token\",\n\t\t\"expiresAt\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t\t\"sshCommand\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSshAccessDto := _SshAccessDto{}\n\n\terr = json.Unmarshal(data, &varSshAccessDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SshAccessDto(varSshAccessDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"sandboxId\")\n\t\tdelete(additionalProperties, \"token\")\n\t\tdelete(additionalProperties, \"expiresAt\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"sshCommand\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSshAccessDto struct {\n\tvalue *SshAccessDto\n\tisSet bool\n}\n\nfunc (v NullableSshAccessDto) Get() *SshAccessDto {\n\treturn v.value\n}\n\nfunc (v *NullableSshAccessDto) Set(val *SshAccessDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSshAccessDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSshAccessDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSshAccessDto(val *SshAccessDto) *NullableSshAccessDto {\n\treturn &NullableSshAccessDto{value: val, isSet: true}\n}\n\nfunc (v NullableSshAccessDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSshAccessDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_ssh_access_validation_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the SshAccessValidationDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &SshAccessValidationDto{}\n\n// SshAccessValidationDto struct for SshAccessValidationDto\ntype SshAccessValidationDto struct {\n\t// Whether the SSH access token is valid\n\tValid bool `json:\"valid\"`\n\t// ID of the sandbox this SSH access is for\n\tSandboxId string `json:\"sandboxId\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _SshAccessValidationDto SshAccessValidationDto\n\n// NewSshAccessValidationDto instantiates a new SshAccessValidationDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewSshAccessValidationDto(valid bool, sandboxId string) *SshAccessValidationDto {\n\tthis := SshAccessValidationDto{}\n\tthis.Valid = valid\n\tthis.SandboxId = sandboxId\n\treturn &this\n}\n\n// NewSshAccessValidationDtoWithDefaults instantiates a new SshAccessValidationDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewSshAccessValidationDtoWithDefaults() *SshAccessValidationDto {\n\tthis := SshAccessValidationDto{}\n\treturn &this\n}\n\n// GetValid returns the Valid field value\nfunc (o *SshAccessValidationDto) GetValid() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Valid\n}\n\n// GetValidOk returns a tuple with the Valid field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessValidationDto) GetValidOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Valid, true\n}\n\n// SetValid sets field value\nfunc (o *SshAccessValidationDto) SetValid(v bool) {\n\to.Valid = v\n}\n\n// GetSandboxId returns the SandboxId field value\nfunc (o *SshAccessValidationDto) GetSandboxId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SandboxId\n}\n\n// GetSandboxIdOk returns a tuple with the SandboxId field value\n// and a boolean to check if the value has been set.\nfunc (o *SshAccessValidationDto) GetSandboxIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SandboxId, true\n}\n\n// SetSandboxId sets field value\nfunc (o *SshAccessValidationDto) SetSandboxId(v string) {\n\to.SandboxId = v\n}\n\nfunc (o SshAccessValidationDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o SshAccessValidationDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"valid\"] = o.Valid\n\ttoSerialize[\"sandboxId\"] = o.SandboxId\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *SshAccessValidationDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"valid\",\n\t\t\"sandboxId\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarSshAccessValidationDto := _SshAccessValidationDto{}\n\n\terr = json.Unmarshal(data, &varSshAccessValidationDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = SshAccessValidationDto(varSshAccessValidationDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"valid\")\n\t\tdelete(additionalProperties, \"sandboxId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableSshAccessValidationDto struct {\n\tvalue *SshAccessValidationDto\n\tisSet bool\n}\n\nfunc (v NullableSshAccessValidationDto) Get() *SshAccessValidationDto {\n\treturn v.value\n}\n\nfunc (v *NullableSshAccessValidationDto) Set(val *SshAccessValidationDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableSshAccessValidationDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableSshAccessValidationDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableSshAccessValidationDto(val *SshAccessValidationDto) *NullableSshAccessValidationDto {\n\treturn &NullableSshAccessValidationDto{value: val, isSet: true}\n}\n\nfunc (v NullableSshAccessValidationDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableSshAccessValidationDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_storage_access_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the StorageAccessDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &StorageAccessDto{}\n\n// StorageAccessDto struct for StorageAccessDto\ntype StorageAccessDto struct {\n\t// Access key for storage authentication\n\tAccessKey string `json:\"accessKey\"`\n\t// Secret key for storage authentication\n\tSecret string `json:\"secret\"`\n\t// Session token for storage authentication\n\tSessionToken string `json:\"sessionToken\"`\n\t// Storage URL\n\tStorageUrl string `json:\"storageUrl\"`\n\t// Organization ID\n\tOrganizationId string `json:\"organizationId\"`\n\t// S3 bucket name\n\tBucket string `json:\"bucket\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _StorageAccessDto StorageAccessDto\n\n// NewStorageAccessDto instantiates a new StorageAccessDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewStorageAccessDto(accessKey string, secret string, sessionToken string, storageUrl string, organizationId string, bucket string) *StorageAccessDto {\n\tthis := StorageAccessDto{}\n\tthis.AccessKey = accessKey\n\tthis.Secret = secret\n\tthis.SessionToken = sessionToken\n\tthis.StorageUrl = storageUrl\n\tthis.OrganizationId = organizationId\n\tthis.Bucket = bucket\n\treturn &this\n}\n\n// NewStorageAccessDtoWithDefaults instantiates a new StorageAccessDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewStorageAccessDtoWithDefaults() *StorageAccessDto {\n\tthis := StorageAccessDto{}\n\treturn &this\n}\n\n// GetAccessKey returns the AccessKey field value\nfunc (o *StorageAccessDto) GetAccessKey() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.AccessKey\n}\n\n// GetAccessKeyOk returns a tuple with the AccessKey field value\n// and a boolean to check if the value has been set.\nfunc (o *StorageAccessDto) GetAccessKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.AccessKey, true\n}\n\n// SetAccessKey sets field value\nfunc (o *StorageAccessDto) SetAccessKey(v string) {\n\to.AccessKey = v\n}\n\n// GetSecret returns the Secret field value\nfunc (o *StorageAccessDto) GetSecret() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Secret\n}\n\n// GetSecretOk returns a tuple with the Secret field value\n// and a boolean to check if the value has been set.\nfunc (o *StorageAccessDto) GetSecretOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Secret, true\n}\n\n// SetSecret sets field value\nfunc (o *StorageAccessDto) SetSecret(v string) {\n\to.Secret = v\n}\n\n// GetSessionToken returns the SessionToken field value\nfunc (o *StorageAccessDto) GetSessionToken() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SessionToken\n}\n\n// GetSessionTokenOk returns a tuple with the SessionToken field value\n// and a boolean to check if the value has been set.\nfunc (o *StorageAccessDto) GetSessionTokenOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SessionToken, true\n}\n\n// SetSessionToken sets field value\nfunc (o *StorageAccessDto) SetSessionToken(v string) {\n\to.SessionToken = v\n}\n\n// GetStorageUrl returns the StorageUrl field value\nfunc (o *StorageAccessDto) GetStorageUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.StorageUrl\n}\n\n// GetStorageUrlOk returns a tuple with the StorageUrl field value\n// and a boolean to check if the value has been set.\nfunc (o *StorageAccessDto) GetStorageUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.StorageUrl, true\n}\n\n// SetStorageUrl sets field value\nfunc (o *StorageAccessDto) SetStorageUrl(v string) {\n\to.StorageUrl = v\n}\n\n// GetOrganizationId returns the OrganizationId field value\nfunc (o *StorageAccessDto) GetOrganizationId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value\n// and a boolean to check if the value has been set.\nfunc (o *StorageAccessDto) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationId, true\n}\n\n// SetOrganizationId sets field value\nfunc (o *StorageAccessDto) SetOrganizationId(v string) {\n\to.OrganizationId = v\n}\n\n// GetBucket returns the Bucket field value\nfunc (o *StorageAccessDto) GetBucket() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Bucket\n}\n\n// GetBucketOk returns a tuple with the Bucket field value\n// and a boolean to check if the value has been set.\nfunc (o *StorageAccessDto) GetBucketOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Bucket, true\n}\n\n// SetBucket sets field value\nfunc (o *StorageAccessDto) SetBucket(v string) {\n\to.Bucket = v\n}\n\nfunc (o StorageAccessDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o StorageAccessDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"accessKey\"] = o.AccessKey\n\ttoSerialize[\"secret\"] = o.Secret\n\ttoSerialize[\"sessionToken\"] = o.SessionToken\n\ttoSerialize[\"storageUrl\"] = o.StorageUrl\n\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\ttoSerialize[\"bucket\"] = o.Bucket\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *StorageAccessDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"accessKey\",\n\t\t\"secret\",\n\t\t\"sessionToken\",\n\t\t\"storageUrl\",\n\t\t\"organizationId\",\n\t\t\"bucket\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarStorageAccessDto := _StorageAccessDto{}\n\n\terr = json.Unmarshal(data, &varStorageAccessDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = StorageAccessDto(varStorageAccessDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"accessKey\")\n\t\tdelete(additionalProperties, \"secret\")\n\t\tdelete(additionalProperties, \"sessionToken\")\n\t\tdelete(additionalProperties, \"storageUrl\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"bucket\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableStorageAccessDto struct {\n\tvalue *StorageAccessDto\n\tisSet bool\n}\n\nfunc (v NullableStorageAccessDto) Get() *StorageAccessDto {\n\treturn v.value\n}\n\nfunc (v *NullableStorageAccessDto) Set(val *StorageAccessDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableStorageAccessDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableStorageAccessDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableStorageAccessDto(val *StorageAccessDto) *NullableStorageAccessDto {\n\treturn &NullableStorageAccessDto{value: val, isSet: true}\n}\n\nfunc (v NullableStorageAccessDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableStorageAccessDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_toolbox_proxy_url.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the ToolboxProxyUrl type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &ToolboxProxyUrl{}\n\n// ToolboxProxyUrl struct for ToolboxProxyUrl\ntype ToolboxProxyUrl struct {\n\t// The toolbox proxy URL for the sandbox\n\tUrl string `json:\"url\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _ToolboxProxyUrl ToolboxProxyUrl\n\n// NewToolboxProxyUrl instantiates a new ToolboxProxyUrl object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewToolboxProxyUrl(url string) *ToolboxProxyUrl {\n\tthis := ToolboxProxyUrl{}\n\tthis.Url = url\n\treturn &this\n}\n\n// NewToolboxProxyUrlWithDefaults instantiates a new ToolboxProxyUrl object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewToolboxProxyUrlWithDefaults() *ToolboxProxyUrl {\n\tthis := ToolboxProxyUrl{}\n\treturn &this\n}\n\n// GetUrl returns the Url field value\nfunc (o *ToolboxProxyUrl) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *ToolboxProxyUrl) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *ToolboxProxyUrl) SetUrl(v string) {\n\to.Url = v\n}\n\nfunc (o ToolboxProxyUrl) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o ToolboxProxyUrl) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"url\"] = o.Url\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *ToolboxProxyUrl) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"url\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarToolboxProxyUrl := _ToolboxProxyUrl{}\n\n\terr = json.Unmarshal(data, &varToolboxProxyUrl)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = ToolboxProxyUrl(varToolboxProxyUrl)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"url\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableToolboxProxyUrl struct {\n\tvalue *ToolboxProxyUrl\n\tisSet bool\n}\n\nfunc (v NullableToolboxProxyUrl) Get() *ToolboxProxyUrl {\n\treturn v.value\n}\n\nfunc (v *NullableToolboxProxyUrl) Set(val *ToolboxProxyUrl) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableToolboxProxyUrl) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableToolboxProxyUrl) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableToolboxProxyUrl(val *ToolboxProxyUrl) *NullableToolboxProxyUrl {\n\treturn &NullableToolboxProxyUrl{value: val, isSet: true}\n}\n\nfunc (v NullableToolboxProxyUrl) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableToolboxProxyUrl) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_trace_span.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the TraceSpan type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &TraceSpan{}\n\n// TraceSpan struct for TraceSpan\ntype TraceSpan struct {\n\t// Trace identifier\n\tTraceId string `json:\"traceId\"`\n\t// Span identifier\n\tSpanId string `json:\"spanId\"`\n\t// Parent span identifier\n\tParentSpanId *string `json:\"parentSpanId,omitempty\"`\n\t// Span name\n\tSpanName string `json:\"spanName\"`\n\t// Span start timestamp\n\tTimestamp string `json:\"timestamp\"`\n\t// Span duration in nanoseconds\n\tDurationNs float32 `json:\"durationNs\"`\n\t// Span attributes\n\tSpanAttributes map[string]string `json:\"spanAttributes\"`\n\t// Status code of the span\n\tStatusCode *string `json:\"statusCode,omitempty\"`\n\t// Status message\n\tStatusMessage *string `json:\"statusMessage,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _TraceSpan TraceSpan\n\n// NewTraceSpan instantiates a new TraceSpan object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewTraceSpan(traceId string, spanId string, spanName string, timestamp string, durationNs float32, spanAttributes map[string]string) *TraceSpan {\n\tthis := TraceSpan{}\n\tthis.TraceId = traceId\n\tthis.SpanId = spanId\n\tthis.SpanName = spanName\n\tthis.Timestamp = timestamp\n\tthis.DurationNs = durationNs\n\tthis.SpanAttributes = spanAttributes\n\treturn &this\n}\n\n// NewTraceSpanWithDefaults instantiates a new TraceSpan object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewTraceSpanWithDefaults() *TraceSpan {\n\tthis := TraceSpan{}\n\treturn &this\n}\n\n// GetTraceId returns the TraceId field value\nfunc (o *TraceSpan) GetTraceId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.TraceId\n}\n\n// GetTraceIdOk returns a tuple with the TraceId field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetTraceIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TraceId, true\n}\n\n// SetTraceId sets field value\nfunc (o *TraceSpan) SetTraceId(v string) {\n\to.TraceId = v\n}\n\n// GetSpanId returns the SpanId field value\nfunc (o *TraceSpan) GetSpanId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SpanId\n}\n\n// GetSpanIdOk returns a tuple with the SpanId field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetSpanIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SpanId, true\n}\n\n// SetSpanId sets field value\nfunc (o *TraceSpan) SetSpanId(v string) {\n\to.SpanId = v\n}\n\n// GetParentSpanId returns the ParentSpanId field value if set, zero value otherwise.\nfunc (o *TraceSpan) GetParentSpanId() string {\n\tif o == nil || IsNil(o.ParentSpanId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ParentSpanId\n}\n\n// GetParentSpanIdOk returns a tuple with the ParentSpanId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetParentSpanIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.ParentSpanId) {\n\t\treturn nil, false\n\t}\n\treturn o.ParentSpanId, true\n}\n\n// HasParentSpanId returns a boolean if a field has been set.\nfunc (o *TraceSpan) HasParentSpanId() bool {\n\tif o != nil && !IsNil(o.ParentSpanId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetParentSpanId gets a reference to the given string and assigns it to the ParentSpanId field.\nfunc (o *TraceSpan) SetParentSpanId(v string) {\n\to.ParentSpanId = &v\n}\n\n// GetSpanName returns the SpanName field value\nfunc (o *TraceSpan) GetSpanName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.SpanName\n}\n\n// GetSpanNameOk returns a tuple with the SpanName field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetSpanNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SpanName, true\n}\n\n// SetSpanName sets field value\nfunc (o *TraceSpan) SetSpanName(v string) {\n\to.SpanName = v\n}\n\n// GetTimestamp returns the Timestamp field value\nfunc (o *TraceSpan) GetTimestamp() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Timestamp\n}\n\n// GetTimestampOk returns a tuple with the Timestamp field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetTimestampOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Timestamp, true\n}\n\n// SetTimestamp sets field value\nfunc (o *TraceSpan) SetTimestamp(v string) {\n\to.Timestamp = v\n}\n\n// GetDurationNs returns the DurationNs field value\nfunc (o *TraceSpan) GetDurationNs() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.DurationNs\n}\n\n// GetDurationNsOk returns a tuple with the DurationNs field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetDurationNsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DurationNs, true\n}\n\n// SetDurationNs sets field value\nfunc (o *TraceSpan) SetDurationNs(v float32) {\n\to.DurationNs = v\n}\n\n// GetSpanAttributes returns the SpanAttributes field value\nfunc (o *TraceSpan) GetSpanAttributes() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\n\treturn o.SpanAttributes\n}\n\n// GetSpanAttributesOk returns a tuple with the SpanAttributes field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetSpanAttributesOk() (*map[string]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SpanAttributes, true\n}\n\n// SetSpanAttributes sets field value\nfunc (o *TraceSpan) SetSpanAttributes(v map[string]string) {\n\to.SpanAttributes = v\n}\n\n// GetStatusCode returns the StatusCode field value if set, zero value otherwise.\nfunc (o *TraceSpan) GetStatusCode() string {\n\tif o == nil || IsNil(o.StatusCode) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.StatusCode\n}\n\n// GetStatusCodeOk returns a tuple with the StatusCode field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetStatusCodeOk() (*string, bool) {\n\tif o == nil || IsNil(o.StatusCode) {\n\t\treturn nil, false\n\t}\n\treturn o.StatusCode, true\n}\n\n// HasStatusCode returns a boolean if a field has been set.\nfunc (o *TraceSpan) HasStatusCode() bool {\n\tif o != nil && !IsNil(o.StatusCode) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetStatusCode gets a reference to the given string and assigns it to the StatusCode field.\nfunc (o *TraceSpan) SetStatusCode(v string) {\n\to.StatusCode = &v\n}\n\n// GetStatusMessage returns the StatusMessage field value if set, zero value otherwise.\nfunc (o *TraceSpan) GetStatusMessage() string {\n\tif o == nil || IsNil(o.StatusMessage) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.StatusMessage\n}\n\n// GetStatusMessageOk returns a tuple with the StatusMessage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *TraceSpan) GetStatusMessageOk() (*string, bool) {\n\tif o == nil || IsNil(o.StatusMessage) {\n\t\treturn nil, false\n\t}\n\treturn o.StatusMessage, true\n}\n\n// HasStatusMessage returns a boolean if a field has been set.\nfunc (o *TraceSpan) HasStatusMessage() bool {\n\tif o != nil && !IsNil(o.StatusMessage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetStatusMessage gets a reference to the given string and assigns it to the StatusMessage field.\nfunc (o *TraceSpan) SetStatusMessage(v string) {\n\to.StatusMessage = &v\n}\n\nfunc (o TraceSpan) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o TraceSpan) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"traceId\"] = o.TraceId\n\ttoSerialize[\"spanId\"] = o.SpanId\n\tif !IsNil(o.ParentSpanId) {\n\t\ttoSerialize[\"parentSpanId\"] = o.ParentSpanId\n\t}\n\ttoSerialize[\"spanName\"] = o.SpanName\n\ttoSerialize[\"timestamp\"] = o.Timestamp\n\ttoSerialize[\"durationNs\"] = o.DurationNs\n\ttoSerialize[\"spanAttributes\"] = o.SpanAttributes\n\tif !IsNil(o.StatusCode) {\n\t\ttoSerialize[\"statusCode\"] = o.StatusCode\n\t}\n\tif !IsNil(o.StatusMessage) {\n\t\ttoSerialize[\"statusMessage\"] = o.StatusMessage\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *TraceSpan) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"traceId\",\n\t\t\"spanId\",\n\t\t\"spanName\",\n\t\t\"timestamp\",\n\t\t\"durationNs\",\n\t\t\"spanAttributes\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarTraceSpan := _TraceSpan{}\n\n\terr = json.Unmarshal(data, &varTraceSpan)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = TraceSpan(varTraceSpan)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"traceId\")\n\t\tdelete(additionalProperties, \"spanId\")\n\t\tdelete(additionalProperties, \"parentSpanId\")\n\t\tdelete(additionalProperties, \"spanName\")\n\t\tdelete(additionalProperties, \"timestamp\")\n\t\tdelete(additionalProperties, \"durationNs\")\n\t\tdelete(additionalProperties, \"spanAttributes\")\n\t\tdelete(additionalProperties, \"statusCode\")\n\t\tdelete(additionalProperties, \"statusMessage\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableTraceSpan struct {\n\tvalue *TraceSpan\n\tisSet bool\n}\n\nfunc (v NullableTraceSpan) Get() *TraceSpan {\n\treturn v.value\n}\n\nfunc (v *NullableTraceSpan) Set(val *TraceSpan) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableTraceSpan) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableTraceSpan) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableTraceSpan(val *TraceSpan) *NullableTraceSpan {\n\treturn &NullableTraceSpan{value: val, isSet: true}\n}\n\nfunc (v NullableTraceSpan) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableTraceSpan) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_trace_summary.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the TraceSummary type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &TraceSummary{}\n\n// TraceSummary struct for TraceSummary\ntype TraceSummary struct {\n\t// Unique trace identifier\n\tTraceId string `json:\"traceId\"`\n\t// Name of the root span\n\tRootSpanName string `json:\"rootSpanName\"`\n\t// Trace start time\n\tStartTime string `json:\"startTime\"`\n\t// Trace end time\n\tEndTime string `json:\"endTime\"`\n\t// Total duration in milliseconds\n\tDurationMs float32 `json:\"durationMs\"`\n\t// Number of spans in this trace\n\tSpanCount float32 `json:\"spanCount\"`\n\t// Status code of the trace\n\tStatusCode *string `json:\"statusCode,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _TraceSummary TraceSummary\n\n// NewTraceSummary instantiates a new TraceSummary object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewTraceSummary(traceId string, rootSpanName string, startTime string, endTime string, durationMs float32, spanCount float32) *TraceSummary {\n\tthis := TraceSummary{}\n\tthis.TraceId = traceId\n\tthis.RootSpanName = rootSpanName\n\tthis.StartTime = startTime\n\tthis.EndTime = endTime\n\tthis.DurationMs = durationMs\n\tthis.SpanCount = spanCount\n\treturn &this\n}\n\n// NewTraceSummaryWithDefaults instantiates a new TraceSummary object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewTraceSummaryWithDefaults() *TraceSummary {\n\tthis := TraceSummary{}\n\treturn &this\n}\n\n// GetTraceId returns the TraceId field value\nfunc (o *TraceSummary) GetTraceId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.TraceId\n}\n\n// GetTraceIdOk returns a tuple with the TraceId field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSummary) GetTraceIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.TraceId, true\n}\n\n// SetTraceId sets field value\nfunc (o *TraceSummary) SetTraceId(v string) {\n\to.TraceId = v\n}\n\n// GetRootSpanName returns the RootSpanName field value\nfunc (o *TraceSummary) GetRootSpanName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.RootSpanName\n}\n\n// GetRootSpanNameOk returns a tuple with the RootSpanName field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSummary) GetRootSpanNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RootSpanName, true\n}\n\n// SetRootSpanName sets field value\nfunc (o *TraceSummary) SetRootSpanName(v string) {\n\to.RootSpanName = v\n}\n\n// GetStartTime returns the StartTime field value\nfunc (o *TraceSummary) GetStartTime() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.StartTime\n}\n\n// GetStartTimeOk returns a tuple with the StartTime field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSummary) GetStartTimeOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.StartTime, true\n}\n\n// SetStartTime sets field value\nfunc (o *TraceSummary) SetStartTime(v string) {\n\to.StartTime = v\n}\n\n// GetEndTime returns the EndTime field value\nfunc (o *TraceSummary) GetEndTime() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.EndTime\n}\n\n// GetEndTimeOk returns a tuple with the EndTime field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSummary) GetEndTimeOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.EndTime, true\n}\n\n// SetEndTime sets field value\nfunc (o *TraceSummary) SetEndTime(v string) {\n\to.EndTime = v\n}\n\n// GetDurationMs returns the DurationMs field value\nfunc (o *TraceSummary) GetDurationMs() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.DurationMs\n}\n\n// GetDurationMsOk returns a tuple with the DurationMs field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSummary) GetDurationMsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DurationMs, true\n}\n\n// SetDurationMs sets field value\nfunc (o *TraceSummary) SetDurationMs(v float32) {\n\to.DurationMs = v\n}\n\n// GetSpanCount returns the SpanCount field value\nfunc (o *TraceSummary) GetSpanCount() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.SpanCount\n}\n\n// GetSpanCountOk returns a tuple with the SpanCount field value\n// and a boolean to check if the value has been set.\nfunc (o *TraceSummary) GetSpanCountOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.SpanCount, true\n}\n\n// SetSpanCount sets field value\nfunc (o *TraceSummary) SetSpanCount(v float32) {\n\to.SpanCount = v\n}\n\n// GetStatusCode returns the StatusCode field value if set, zero value otherwise.\nfunc (o *TraceSummary) GetStatusCode() string {\n\tif o == nil || IsNil(o.StatusCode) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.StatusCode\n}\n\n// GetStatusCodeOk returns a tuple with the StatusCode field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *TraceSummary) GetStatusCodeOk() (*string, bool) {\n\tif o == nil || IsNil(o.StatusCode) {\n\t\treturn nil, false\n\t}\n\treturn o.StatusCode, true\n}\n\n// HasStatusCode returns a boolean if a field has been set.\nfunc (o *TraceSummary) HasStatusCode() bool {\n\tif o != nil && !IsNil(o.StatusCode) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetStatusCode gets a reference to the given string and assigns it to the StatusCode field.\nfunc (o *TraceSummary) SetStatusCode(v string) {\n\to.StatusCode = &v\n}\n\nfunc (o TraceSummary) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o TraceSummary) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"traceId\"] = o.TraceId\n\ttoSerialize[\"rootSpanName\"] = o.RootSpanName\n\ttoSerialize[\"startTime\"] = o.StartTime\n\ttoSerialize[\"endTime\"] = o.EndTime\n\ttoSerialize[\"durationMs\"] = o.DurationMs\n\ttoSerialize[\"spanCount\"] = o.SpanCount\n\tif !IsNil(o.StatusCode) {\n\t\ttoSerialize[\"statusCode\"] = o.StatusCode\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *TraceSummary) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"traceId\",\n\t\t\"rootSpanName\",\n\t\t\"startTime\",\n\t\t\"endTime\",\n\t\t\"durationMs\",\n\t\t\"spanCount\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarTraceSummary := _TraceSummary{}\n\n\terr = json.Unmarshal(data, &varTraceSummary)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = TraceSummary(varTraceSummary)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"traceId\")\n\t\tdelete(additionalProperties, \"rootSpanName\")\n\t\tdelete(additionalProperties, \"startTime\")\n\t\tdelete(additionalProperties, \"endTime\")\n\t\tdelete(additionalProperties, \"durationMs\")\n\t\tdelete(additionalProperties, \"spanCount\")\n\t\tdelete(additionalProperties, \"statusCode\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableTraceSummary struct {\n\tvalue *TraceSummary\n\tisSet bool\n}\n\nfunc (v NullableTraceSummary) Get() *TraceSummary {\n\treturn v.value\n}\n\nfunc (v *NullableTraceSummary) Set(val *TraceSummary) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableTraceSummary) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableTraceSummary) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableTraceSummary(val *TraceSummary) *NullableTraceSummary {\n\treturn &NullableTraceSummary{value: val, isSet: true}\n}\n\nfunc (v NullableTraceSummary) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableTraceSummary) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_docker_registry.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UpdateDockerRegistry type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateDockerRegistry{}\n\n// UpdateDockerRegistry struct for UpdateDockerRegistry\ntype UpdateDockerRegistry struct {\n\t// Registry name\n\tName string `json:\"name\"`\n\t// Registry URL\n\tUrl string `json:\"url\"`\n\t// Registry username\n\tUsername string `json:\"username\"`\n\t// Registry password\n\tPassword *string `json:\"password,omitempty\"`\n\t// Registry project\n\tProject *string `json:\"project,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateDockerRegistry UpdateDockerRegistry\n\n// NewUpdateDockerRegistry instantiates a new UpdateDockerRegistry object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateDockerRegistry(name string, url string, username string) *UpdateDockerRegistry {\n\tthis := UpdateDockerRegistry{}\n\tthis.Name = name\n\tthis.Url = url\n\tthis.Username = username\n\treturn &this\n}\n\n// NewUpdateDockerRegistryWithDefaults instantiates a new UpdateDockerRegistry object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateDockerRegistryWithDefaults() *UpdateDockerRegistry {\n\tthis := UpdateDockerRegistry{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *UpdateDockerRegistry) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateDockerRegistry) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *UpdateDockerRegistry) SetName(v string) {\n\to.Name = v\n}\n\n// GetUrl returns the Url field value\nfunc (o *UpdateDockerRegistry) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateDockerRegistry) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *UpdateDockerRegistry) SetUrl(v string) {\n\to.Url = v\n}\n\n// GetUsername returns the Username field value\nfunc (o *UpdateDockerRegistry) GetUsername() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Username\n}\n\n// GetUsernameOk returns a tuple with the Username field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateDockerRegistry) GetUsernameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Username, true\n}\n\n// SetUsername sets field value\nfunc (o *UpdateDockerRegistry) SetUsername(v string) {\n\to.Username = v\n}\n\n// GetPassword returns the Password field value if set, zero value otherwise.\nfunc (o *UpdateDockerRegistry) GetPassword() string {\n\tif o == nil || IsNil(o.Password) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Password\n}\n\n// GetPasswordOk returns a tuple with the Password field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *UpdateDockerRegistry) GetPasswordOk() (*string, bool) {\n\tif o == nil || IsNil(o.Password) {\n\t\treturn nil, false\n\t}\n\treturn o.Password, true\n}\n\n// HasPassword returns a boolean if a field has been set.\nfunc (o *UpdateDockerRegistry) HasPassword() bool {\n\tif o != nil && !IsNil(o.Password) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetPassword gets a reference to the given string and assigns it to the Password field.\nfunc (o *UpdateDockerRegistry) SetPassword(v string) {\n\to.Password = &v\n}\n\n// GetProject returns the Project field value if set, zero value otherwise.\nfunc (o *UpdateDockerRegistry) GetProject() string {\n\tif o == nil || IsNil(o.Project) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Project\n}\n\n// GetProjectOk returns a tuple with the Project field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *UpdateDockerRegistry) GetProjectOk() (*string, bool) {\n\tif o == nil || IsNil(o.Project) {\n\t\treturn nil, false\n\t}\n\treturn o.Project, true\n}\n\n// HasProject returns a boolean if a field has been set.\nfunc (o *UpdateDockerRegistry) HasProject() bool {\n\tif o != nil && !IsNil(o.Project) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProject gets a reference to the given string and assigns it to the Project field.\nfunc (o *UpdateDockerRegistry) SetProject(v string) {\n\to.Project = &v\n}\n\nfunc (o UpdateDockerRegistry) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateDockerRegistry) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"url\"] = o.Url\n\ttoSerialize[\"username\"] = o.Username\n\tif !IsNil(o.Password) {\n\t\ttoSerialize[\"password\"] = o.Password\n\t}\n\tif !IsNil(o.Project) {\n\t\ttoSerialize[\"project\"] = o.Project\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateDockerRegistry) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"url\",\n\t\t\"username\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateDockerRegistry := _UpdateDockerRegistry{}\n\n\terr = json.Unmarshal(data, &varUpdateDockerRegistry)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateDockerRegistry(varUpdateDockerRegistry)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"url\")\n\t\tdelete(additionalProperties, \"username\")\n\t\tdelete(additionalProperties, \"password\")\n\t\tdelete(additionalProperties, \"project\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateDockerRegistry struct {\n\tvalue *UpdateDockerRegistry\n\tisSet bool\n}\n\nfunc (v NullableUpdateDockerRegistry) Get() *UpdateDockerRegistry {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateDockerRegistry) Set(val *UpdateDockerRegistry) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateDockerRegistry) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateDockerRegistry) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateDockerRegistry(val *UpdateDockerRegistry) *NullableUpdateDockerRegistry {\n\treturn &NullableUpdateDockerRegistry{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateDockerRegistry) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateDockerRegistry) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_job_status.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UpdateJobStatus type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateJobStatus{}\n\n// UpdateJobStatus struct for UpdateJobStatus\ntype UpdateJobStatus struct {\n\t// The new status of the job\n\tStatus JobStatus `json:\"status\"`\n\t// Error message if the job failed\n\tErrorMessage *string `json:\"errorMessage,omitempty\"`\n\t// Result metadata for the job\n\tResultMetadata *string `json:\"resultMetadata,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateJobStatus UpdateJobStatus\n\n// NewUpdateJobStatus instantiates a new UpdateJobStatus object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateJobStatus(status JobStatus) *UpdateJobStatus {\n\tthis := UpdateJobStatus{}\n\tthis.Status = status\n\treturn &this\n}\n\n// NewUpdateJobStatusWithDefaults instantiates a new UpdateJobStatus object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateJobStatusWithDefaults() *UpdateJobStatus {\n\tthis := UpdateJobStatus{}\n\treturn &this\n}\n\n// GetStatus returns the Status field value\nfunc (o *UpdateJobStatus) GetStatus() JobStatus {\n\tif o == nil {\n\t\tvar ret JobStatus\n\t\treturn ret\n\t}\n\n\treturn o.Status\n}\n\n// GetStatusOk returns a tuple with the Status field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateJobStatus) GetStatusOk() (*JobStatus, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Status, true\n}\n\n// SetStatus sets field value\nfunc (o *UpdateJobStatus) SetStatus(v JobStatus) {\n\to.Status = v\n}\n\n// GetErrorMessage returns the ErrorMessage field value if set, zero value otherwise.\nfunc (o *UpdateJobStatus) GetErrorMessage() string {\n\tif o == nil || IsNil(o.ErrorMessage) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ErrorMessage\n}\n\n// GetErrorMessageOk returns a tuple with the ErrorMessage field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *UpdateJobStatus) GetErrorMessageOk() (*string, bool) {\n\tif o == nil || IsNil(o.ErrorMessage) {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorMessage, true\n}\n\n// HasErrorMessage returns a boolean if a field has been set.\nfunc (o *UpdateJobStatus) HasErrorMessage() bool {\n\tif o != nil && !IsNil(o.ErrorMessage) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetErrorMessage gets a reference to the given string and assigns it to the ErrorMessage field.\nfunc (o *UpdateJobStatus) SetErrorMessage(v string) {\n\to.ErrorMessage = &v\n}\n\n// GetResultMetadata returns the ResultMetadata field value if set, zero value otherwise.\nfunc (o *UpdateJobStatus) GetResultMetadata() string {\n\tif o == nil || IsNil(o.ResultMetadata) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ResultMetadata\n}\n\n// GetResultMetadataOk returns a tuple with the ResultMetadata field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *UpdateJobStatus) GetResultMetadataOk() (*string, bool) {\n\tif o == nil || IsNil(o.ResultMetadata) {\n\t\treturn nil, false\n\t}\n\treturn o.ResultMetadata, true\n}\n\n// HasResultMetadata returns a boolean if a field has been set.\nfunc (o *UpdateJobStatus) HasResultMetadata() bool {\n\tif o != nil && !IsNil(o.ResultMetadata) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetResultMetadata gets a reference to the given string and assigns it to the ResultMetadata field.\nfunc (o *UpdateJobStatus) SetResultMetadata(v string) {\n\to.ResultMetadata = &v\n}\n\nfunc (o UpdateJobStatus) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateJobStatus) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"status\"] = o.Status\n\tif !IsNil(o.ErrorMessage) {\n\t\ttoSerialize[\"errorMessage\"] = o.ErrorMessage\n\t}\n\tif !IsNil(o.ResultMetadata) {\n\t\ttoSerialize[\"resultMetadata\"] = o.ResultMetadata\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateJobStatus) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"status\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateJobStatus := _UpdateJobStatus{}\n\n\terr = json.Unmarshal(data, &varUpdateJobStatus)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateJobStatus(varUpdateJobStatus)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"status\")\n\t\tdelete(additionalProperties, \"errorMessage\")\n\t\tdelete(additionalProperties, \"resultMetadata\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateJobStatus struct {\n\tvalue *UpdateJobStatus\n\tisSet bool\n}\n\nfunc (v NullableUpdateJobStatus) Get() *UpdateJobStatus {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateJobStatus) Set(val *UpdateJobStatus) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateJobStatus) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateJobStatus) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateJobStatus(val *UpdateJobStatus) *NullableUpdateJobStatus {\n\treturn &NullableUpdateJobStatus{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateJobStatus) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateJobStatus) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_organization_default_region.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UpdateOrganizationDefaultRegion type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateOrganizationDefaultRegion{}\n\n// UpdateOrganizationDefaultRegion struct for UpdateOrganizationDefaultRegion\ntype UpdateOrganizationDefaultRegion struct {\n\t// The ID of the default region for the organization\n\tDefaultRegionId string `json:\"defaultRegionId\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateOrganizationDefaultRegion UpdateOrganizationDefaultRegion\n\n// NewUpdateOrganizationDefaultRegion instantiates a new UpdateOrganizationDefaultRegion object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateOrganizationDefaultRegion(defaultRegionId string) *UpdateOrganizationDefaultRegion {\n\tthis := UpdateOrganizationDefaultRegion{}\n\tthis.DefaultRegionId = defaultRegionId\n\treturn &this\n}\n\n// NewUpdateOrganizationDefaultRegionWithDefaults instantiates a new UpdateOrganizationDefaultRegion object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateOrganizationDefaultRegionWithDefaults() *UpdateOrganizationDefaultRegion {\n\tthis := UpdateOrganizationDefaultRegion{}\n\treturn &this\n}\n\n// GetDefaultRegionId returns the DefaultRegionId field value\nfunc (o *UpdateOrganizationDefaultRegion) GetDefaultRegionId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.DefaultRegionId\n}\n\n// GetDefaultRegionIdOk returns a tuple with the DefaultRegionId field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationDefaultRegion) GetDefaultRegionIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.DefaultRegionId, true\n}\n\n// SetDefaultRegionId sets field value\nfunc (o *UpdateOrganizationDefaultRegion) SetDefaultRegionId(v string) {\n\to.DefaultRegionId = v\n}\n\nfunc (o UpdateOrganizationDefaultRegion) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateOrganizationDefaultRegion) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"defaultRegionId\"] = o.DefaultRegionId\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateOrganizationDefaultRegion) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"defaultRegionId\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateOrganizationDefaultRegion := _UpdateOrganizationDefaultRegion{}\n\n\terr = json.Unmarshal(data, &varUpdateOrganizationDefaultRegion)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateOrganizationDefaultRegion(varUpdateOrganizationDefaultRegion)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"defaultRegionId\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateOrganizationDefaultRegion struct {\n\tvalue *UpdateOrganizationDefaultRegion\n\tisSet bool\n}\n\nfunc (v NullableUpdateOrganizationDefaultRegion) Get() *UpdateOrganizationDefaultRegion {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateOrganizationDefaultRegion) Set(val *UpdateOrganizationDefaultRegion) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateOrganizationDefaultRegion) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateOrganizationDefaultRegion) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateOrganizationDefaultRegion(val *UpdateOrganizationDefaultRegion) *NullableUpdateOrganizationDefaultRegion {\n\treturn &NullableUpdateOrganizationDefaultRegion{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateOrganizationDefaultRegion) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateOrganizationDefaultRegion) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_organization_invitation.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the UpdateOrganizationInvitation type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateOrganizationInvitation{}\n\n// UpdateOrganizationInvitation struct for UpdateOrganizationInvitation\ntype UpdateOrganizationInvitation struct {\n\t// Organization member role\n\tRole string `json:\"role\"`\n\t// Array of role IDs\n\tAssignedRoleIds []string `json:\"assignedRoleIds\"`\n\t// Expiration date of the invitation\n\tExpiresAt *time.Time `json:\"expiresAt,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateOrganizationInvitation UpdateOrganizationInvitation\n\n// NewUpdateOrganizationInvitation instantiates a new UpdateOrganizationInvitation object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateOrganizationInvitation(role string, assignedRoleIds []string) *UpdateOrganizationInvitation {\n\tthis := UpdateOrganizationInvitation{}\n\tthis.Role = role\n\tthis.AssignedRoleIds = assignedRoleIds\n\treturn &this\n}\n\n// NewUpdateOrganizationInvitationWithDefaults instantiates a new UpdateOrganizationInvitation object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateOrganizationInvitationWithDefaults() *UpdateOrganizationInvitation {\n\tthis := UpdateOrganizationInvitation{}\n\treturn &this\n}\n\n// GetRole returns the Role field value\nfunc (o *UpdateOrganizationInvitation) GetRole() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Role\n}\n\n// GetRoleOk returns a tuple with the Role field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationInvitation) GetRoleOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Role, true\n}\n\n// SetRole sets field value\nfunc (o *UpdateOrganizationInvitation) SetRole(v string) {\n\to.Role = v\n}\n\n// GetAssignedRoleIds returns the AssignedRoleIds field value\nfunc (o *UpdateOrganizationInvitation) GetAssignedRoleIds() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.AssignedRoleIds\n}\n\n// GetAssignedRoleIdsOk returns a tuple with the AssignedRoleIds field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationInvitation) GetAssignedRoleIdsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AssignedRoleIds, true\n}\n\n// SetAssignedRoleIds sets field value\nfunc (o *UpdateOrganizationInvitation) SetAssignedRoleIds(v []string) {\n\to.AssignedRoleIds = v\n}\n\n// GetExpiresAt returns the ExpiresAt field value if set, zero value otherwise.\nfunc (o *UpdateOrganizationInvitation) GetExpiresAt() time.Time {\n\tif o == nil || IsNil(o.ExpiresAt) {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\treturn *o.ExpiresAt\n}\n\n// GetExpiresAtOk returns a tuple with the ExpiresAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationInvitation) GetExpiresAtOk() (*time.Time, bool) {\n\tif o == nil || IsNil(o.ExpiresAt) {\n\t\treturn nil, false\n\t}\n\treturn o.ExpiresAt, true\n}\n\n// HasExpiresAt returns a boolean if a field has been set.\nfunc (o *UpdateOrganizationInvitation) HasExpiresAt() bool {\n\tif o != nil && !IsNil(o.ExpiresAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetExpiresAt gets a reference to the given time.Time and assigns it to the ExpiresAt field.\nfunc (o *UpdateOrganizationInvitation) SetExpiresAt(v time.Time) {\n\to.ExpiresAt = &v\n}\n\nfunc (o UpdateOrganizationInvitation) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateOrganizationInvitation) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"role\"] = o.Role\n\ttoSerialize[\"assignedRoleIds\"] = o.AssignedRoleIds\n\tif !IsNil(o.ExpiresAt) {\n\t\ttoSerialize[\"expiresAt\"] = o.ExpiresAt\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateOrganizationInvitation) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"role\",\n\t\t\"assignedRoleIds\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateOrganizationInvitation := _UpdateOrganizationInvitation{}\n\n\terr = json.Unmarshal(data, &varUpdateOrganizationInvitation)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateOrganizationInvitation(varUpdateOrganizationInvitation)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"role\")\n\t\tdelete(additionalProperties, \"assignedRoleIds\")\n\t\tdelete(additionalProperties, \"expiresAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateOrganizationInvitation struct {\n\tvalue *UpdateOrganizationInvitation\n\tisSet bool\n}\n\nfunc (v NullableUpdateOrganizationInvitation) Get() *UpdateOrganizationInvitation {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateOrganizationInvitation) Set(val *UpdateOrganizationInvitation) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateOrganizationInvitation) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateOrganizationInvitation) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateOrganizationInvitation(val *UpdateOrganizationInvitation) *NullableUpdateOrganizationInvitation {\n\treturn &NullableUpdateOrganizationInvitation{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateOrganizationInvitation) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateOrganizationInvitation) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_organization_member_access.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UpdateOrganizationMemberAccess type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateOrganizationMemberAccess{}\n\n// UpdateOrganizationMemberAccess struct for UpdateOrganizationMemberAccess\ntype UpdateOrganizationMemberAccess struct {\n\t// Organization member role\n\tRole string `json:\"role\"`\n\t// Array of assigned role IDs\n\tAssignedRoleIds []string `json:\"assignedRoleIds\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateOrganizationMemberAccess UpdateOrganizationMemberAccess\n\n// NewUpdateOrganizationMemberAccess instantiates a new UpdateOrganizationMemberAccess object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateOrganizationMemberAccess(role string, assignedRoleIds []string) *UpdateOrganizationMemberAccess {\n\tthis := UpdateOrganizationMemberAccess{}\n\tthis.Role = role\n\tthis.AssignedRoleIds = assignedRoleIds\n\treturn &this\n}\n\n// NewUpdateOrganizationMemberAccessWithDefaults instantiates a new UpdateOrganizationMemberAccess object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateOrganizationMemberAccessWithDefaults() *UpdateOrganizationMemberAccess {\n\tthis := UpdateOrganizationMemberAccess{}\n\tvar role string = \"member\"\n\tthis.Role = role\n\treturn &this\n}\n\n// GetRole returns the Role field value\nfunc (o *UpdateOrganizationMemberAccess) GetRole() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Role\n}\n\n// GetRoleOk returns a tuple with the Role field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationMemberAccess) GetRoleOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Role, true\n}\n\n// SetRole sets field value\nfunc (o *UpdateOrganizationMemberAccess) SetRole(v string) {\n\to.Role = v\n}\n\n// GetAssignedRoleIds returns the AssignedRoleIds field value\nfunc (o *UpdateOrganizationMemberAccess) GetAssignedRoleIds() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.AssignedRoleIds\n}\n\n// GetAssignedRoleIdsOk returns a tuple with the AssignedRoleIds field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationMemberAccess) GetAssignedRoleIdsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AssignedRoleIds, true\n}\n\n// SetAssignedRoleIds sets field value\nfunc (o *UpdateOrganizationMemberAccess) SetAssignedRoleIds(v []string) {\n\to.AssignedRoleIds = v\n}\n\nfunc (o UpdateOrganizationMemberAccess) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateOrganizationMemberAccess) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"role\"] = o.Role\n\ttoSerialize[\"assignedRoleIds\"] = o.AssignedRoleIds\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateOrganizationMemberAccess) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"role\",\n\t\t\"assignedRoleIds\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateOrganizationMemberAccess := _UpdateOrganizationMemberAccess{}\n\n\terr = json.Unmarshal(data, &varUpdateOrganizationMemberAccess)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateOrganizationMemberAccess(varUpdateOrganizationMemberAccess)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"role\")\n\t\tdelete(additionalProperties, \"assignedRoleIds\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateOrganizationMemberAccess struct {\n\tvalue *UpdateOrganizationMemberAccess\n\tisSet bool\n}\n\nfunc (v NullableUpdateOrganizationMemberAccess) Get() *UpdateOrganizationMemberAccess {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateOrganizationMemberAccess) Set(val *UpdateOrganizationMemberAccess) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateOrganizationMemberAccess) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateOrganizationMemberAccess) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateOrganizationMemberAccess(val *UpdateOrganizationMemberAccess) *NullableUpdateOrganizationMemberAccess {\n\treturn &NullableUpdateOrganizationMemberAccess{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateOrganizationMemberAccess) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateOrganizationMemberAccess) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_organization_quota.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UpdateOrganizationQuota type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateOrganizationQuota{}\n\n// UpdateOrganizationQuota struct for UpdateOrganizationQuota\ntype UpdateOrganizationQuota struct {\n\tMaxCpuPerSandbox NullableFloat32 `json:\"maxCpuPerSandbox\"`\n\tMaxMemoryPerSandbox NullableFloat32 `json:\"maxMemoryPerSandbox\"`\n\tMaxDiskPerSandbox NullableFloat32 `json:\"maxDiskPerSandbox\"`\n\tSnapshotQuota NullableFloat32 `json:\"snapshotQuota\"`\n\tMaxSnapshotSize NullableFloat32 `json:\"maxSnapshotSize\"`\n\tVolumeQuota NullableFloat32 `json:\"volumeQuota\"`\n\tAuthenticatedRateLimit NullableFloat32 `json:\"authenticatedRateLimit\"`\n\tSandboxCreateRateLimit NullableFloat32 `json:\"sandboxCreateRateLimit\"`\n\tSandboxLifecycleRateLimit NullableFloat32 `json:\"sandboxLifecycleRateLimit\"`\n\tAuthenticatedRateLimitTtlSeconds NullableFloat32 `json:\"authenticatedRateLimitTtlSeconds\"`\n\tSandboxCreateRateLimitTtlSeconds NullableFloat32 `json:\"sandboxCreateRateLimitTtlSeconds\"`\n\tSandboxLifecycleRateLimitTtlSeconds NullableFloat32 `json:\"sandboxLifecycleRateLimitTtlSeconds\"`\n\t// Time in minutes before an unused snapshot is deactivated\n\tSnapshotDeactivationTimeoutMinutes NullableFloat32 `json:\"snapshotDeactivationTimeoutMinutes\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateOrganizationQuota UpdateOrganizationQuota\n\n// NewUpdateOrganizationQuota instantiates a new UpdateOrganizationQuota object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateOrganizationQuota(maxCpuPerSandbox NullableFloat32, maxMemoryPerSandbox NullableFloat32, maxDiskPerSandbox NullableFloat32, snapshotQuota NullableFloat32, maxSnapshotSize NullableFloat32, volumeQuota NullableFloat32, authenticatedRateLimit NullableFloat32, sandboxCreateRateLimit NullableFloat32, sandboxLifecycleRateLimit NullableFloat32, authenticatedRateLimitTtlSeconds NullableFloat32, sandboxCreateRateLimitTtlSeconds NullableFloat32, sandboxLifecycleRateLimitTtlSeconds NullableFloat32, snapshotDeactivationTimeoutMinutes NullableFloat32) *UpdateOrganizationQuota {\n\tthis := UpdateOrganizationQuota{}\n\tthis.MaxCpuPerSandbox = maxCpuPerSandbox\n\tthis.MaxMemoryPerSandbox = maxMemoryPerSandbox\n\tthis.MaxDiskPerSandbox = maxDiskPerSandbox\n\tthis.SnapshotQuota = snapshotQuota\n\tthis.MaxSnapshotSize = maxSnapshotSize\n\tthis.VolumeQuota = volumeQuota\n\tthis.AuthenticatedRateLimit = authenticatedRateLimit\n\tthis.SandboxCreateRateLimit = sandboxCreateRateLimit\n\tthis.SandboxLifecycleRateLimit = sandboxLifecycleRateLimit\n\tthis.AuthenticatedRateLimitTtlSeconds = authenticatedRateLimitTtlSeconds\n\tthis.SandboxCreateRateLimitTtlSeconds = sandboxCreateRateLimitTtlSeconds\n\tthis.SandboxLifecycleRateLimitTtlSeconds = sandboxLifecycleRateLimitTtlSeconds\n\tthis.SnapshotDeactivationTimeoutMinutes = snapshotDeactivationTimeoutMinutes\n\treturn &this\n}\n\n// NewUpdateOrganizationQuotaWithDefaults instantiates a new UpdateOrganizationQuota object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateOrganizationQuotaWithDefaults() *UpdateOrganizationQuota {\n\tthis := UpdateOrganizationQuota{}\n\treturn &this\n}\n\n// GetMaxCpuPerSandbox returns the MaxCpuPerSandbox field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetMaxCpuPerSandbox() float32 {\n\tif o == nil || o.MaxCpuPerSandbox.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.MaxCpuPerSandbox.Get()\n}\n\n// GetMaxCpuPerSandboxOk returns a tuple with the MaxCpuPerSandbox field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetMaxCpuPerSandboxOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.MaxCpuPerSandbox.Get(), o.MaxCpuPerSandbox.IsSet()\n}\n\n// SetMaxCpuPerSandbox sets field value\nfunc (o *UpdateOrganizationQuota) SetMaxCpuPerSandbox(v float32) {\n\to.MaxCpuPerSandbox.Set(&v)\n}\n\n// GetMaxMemoryPerSandbox returns the MaxMemoryPerSandbox field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetMaxMemoryPerSandbox() float32 {\n\tif o == nil || o.MaxMemoryPerSandbox.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.MaxMemoryPerSandbox.Get()\n}\n\n// GetMaxMemoryPerSandboxOk returns a tuple with the MaxMemoryPerSandbox field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetMaxMemoryPerSandboxOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.MaxMemoryPerSandbox.Get(), o.MaxMemoryPerSandbox.IsSet()\n}\n\n// SetMaxMemoryPerSandbox sets field value\nfunc (o *UpdateOrganizationQuota) SetMaxMemoryPerSandbox(v float32) {\n\to.MaxMemoryPerSandbox.Set(&v)\n}\n\n// GetMaxDiskPerSandbox returns the MaxDiskPerSandbox field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetMaxDiskPerSandbox() float32 {\n\tif o == nil || o.MaxDiskPerSandbox.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.MaxDiskPerSandbox.Get()\n}\n\n// GetMaxDiskPerSandboxOk returns a tuple with the MaxDiskPerSandbox field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetMaxDiskPerSandboxOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.MaxDiskPerSandbox.Get(), o.MaxDiskPerSandbox.IsSet()\n}\n\n// SetMaxDiskPerSandbox sets field value\nfunc (o *UpdateOrganizationQuota) SetMaxDiskPerSandbox(v float32) {\n\to.MaxDiskPerSandbox.Set(&v)\n}\n\n// GetSnapshotQuota returns the SnapshotQuota field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetSnapshotQuota() float32 {\n\tif o == nil || o.SnapshotQuota.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SnapshotQuota.Get()\n}\n\n// GetSnapshotQuotaOk returns a tuple with the SnapshotQuota field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetSnapshotQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotQuota.Get(), o.SnapshotQuota.IsSet()\n}\n\n// SetSnapshotQuota sets field value\nfunc (o *UpdateOrganizationQuota) SetSnapshotQuota(v float32) {\n\to.SnapshotQuota.Set(&v)\n}\n\n// GetMaxSnapshotSize returns the MaxSnapshotSize field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetMaxSnapshotSize() float32 {\n\tif o == nil || o.MaxSnapshotSize.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.MaxSnapshotSize.Get()\n}\n\n// GetMaxSnapshotSizeOk returns a tuple with the MaxSnapshotSize field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetMaxSnapshotSizeOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.MaxSnapshotSize.Get(), o.MaxSnapshotSize.IsSet()\n}\n\n// SetMaxSnapshotSize sets field value\nfunc (o *UpdateOrganizationQuota) SetMaxSnapshotSize(v float32) {\n\to.MaxSnapshotSize.Set(&v)\n}\n\n// GetVolumeQuota returns the VolumeQuota field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetVolumeQuota() float32 {\n\tif o == nil || o.VolumeQuota.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.VolumeQuota.Get()\n}\n\n// GetVolumeQuotaOk returns a tuple with the VolumeQuota field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetVolumeQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.VolumeQuota.Get(), o.VolumeQuota.IsSet()\n}\n\n// SetVolumeQuota sets field value\nfunc (o *UpdateOrganizationQuota) SetVolumeQuota(v float32) {\n\to.VolumeQuota.Set(&v)\n}\n\n// GetAuthenticatedRateLimit returns the AuthenticatedRateLimit field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetAuthenticatedRateLimit() float32 {\n\tif o == nil || o.AuthenticatedRateLimit.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.AuthenticatedRateLimit.Get()\n}\n\n// GetAuthenticatedRateLimitOk returns a tuple with the AuthenticatedRateLimit field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetAuthenticatedRateLimitOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AuthenticatedRateLimit.Get(), o.AuthenticatedRateLimit.IsSet()\n}\n\n// SetAuthenticatedRateLimit sets field value\nfunc (o *UpdateOrganizationQuota) SetAuthenticatedRateLimit(v float32) {\n\to.AuthenticatedRateLimit.Set(&v)\n}\n\n// GetSandboxCreateRateLimit returns the SandboxCreateRateLimit field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetSandboxCreateRateLimit() float32 {\n\tif o == nil || o.SandboxCreateRateLimit.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SandboxCreateRateLimit.Get()\n}\n\n// GetSandboxCreateRateLimitOk returns a tuple with the SandboxCreateRateLimit field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetSandboxCreateRateLimitOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxCreateRateLimit.Get(), o.SandboxCreateRateLimit.IsSet()\n}\n\n// SetSandboxCreateRateLimit sets field value\nfunc (o *UpdateOrganizationQuota) SetSandboxCreateRateLimit(v float32) {\n\to.SandboxCreateRateLimit.Set(&v)\n}\n\n// GetSandboxLifecycleRateLimit returns the SandboxLifecycleRateLimit field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetSandboxLifecycleRateLimit() float32 {\n\tif o == nil || o.SandboxLifecycleRateLimit.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SandboxLifecycleRateLimit.Get()\n}\n\n// GetSandboxLifecycleRateLimitOk returns a tuple with the SandboxLifecycleRateLimit field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetSandboxLifecycleRateLimitOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxLifecycleRateLimit.Get(), o.SandboxLifecycleRateLimit.IsSet()\n}\n\n// SetSandboxLifecycleRateLimit sets field value\nfunc (o *UpdateOrganizationQuota) SetSandboxLifecycleRateLimit(v float32) {\n\to.SandboxLifecycleRateLimit.Set(&v)\n}\n\n// GetAuthenticatedRateLimitTtlSeconds returns the AuthenticatedRateLimitTtlSeconds field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetAuthenticatedRateLimitTtlSeconds() float32 {\n\tif o == nil || o.AuthenticatedRateLimitTtlSeconds.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.AuthenticatedRateLimitTtlSeconds.Get()\n}\n\n// GetAuthenticatedRateLimitTtlSecondsOk returns a tuple with the AuthenticatedRateLimitTtlSeconds field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetAuthenticatedRateLimitTtlSecondsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.AuthenticatedRateLimitTtlSeconds.Get(), o.AuthenticatedRateLimitTtlSeconds.IsSet()\n}\n\n// SetAuthenticatedRateLimitTtlSeconds sets field value\nfunc (o *UpdateOrganizationQuota) SetAuthenticatedRateLimitTtlSeconds(v float32) {\n\to.AuthenticatedRateLimitTtlSeconds.Set(&v)\n}\n\n// GetSandboxCreateRateLimitTtlSeconds returns the SandboxCreateRateLimitTtlSeconds field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetSandboxCreateRateLimitTtlSeconds() float32 {\n\tif o == nil || o.SandboxCreateRateLimitTtlSeconds.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SandboxCreateRateLimitTtlSeconds.Get()\n}\n\n// GetSandboxCreateRateLimitTtlSecondsOk returns a tuple with the SandboxCreateRateLimitTtlSeconds field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetSandboxCreateRateLimitTtlSecondsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxCreateRateLimitTtlSeconds.Get(), o.SandboxCreateRateLimitTtlSeconds.IsSet()\n}\n\n// SetSandboxCreateRateLimitTtlSeconds sets field value\nfunc (o *UpdateOrganizationQuota) SetSandboxCreateRateLimitTtlSeconds(v float32) {\n\to.SandboxCreateRateLimitTtlSeconds.Set(&v)\n}\n\n// GetSandboxLifecycleRateLimitTtlSeconds returns the SandboxLifecycleRateLimitTtlSeconds field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetSandboxLifecycleRateLimitTtlSeconds() float32 {\n\tif o == nil || o.SandboxLifecycleRateLimitTtlSeconds.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SandboxLifecycleRateLimitTtlSeconds.Get()\n}\n\n// GetSandboxLifecycleRateLimitTtlSecondsOk returns a tuple with the SandboxLifecycleRateLimitTtlSeconds field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetSandboxLifecycleRateLimitTtlSecondsOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SandboxLifecycleRateLimitTtlSeconds.Get(), o.SandboxLifecycleRateLimitTtlSeconds.IsSet()\n}\n\n// SetSandboxLifecycleRateLimitTtlSeconds sets field value\nfunc (o *UpdateOrganizationQuota) SetSandboxLifecycleRateLimitTtlSeconds(v float32) {\n\to.SandboxLifecycleRateLimitTtlSeconds.Set(&v)\n}\n\n// GetSnapshotDeactivationTimeoutMinutes returns the SnapshotDeactivationTimeoutMinutes field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationQuota) GetSnapshotDeactivationTimeoutMinutes() float32 {\n\tif o == nil || o.SnapshotDeactivationTimeoutMinutes.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.SnapshotDeactivationTimeoutMinutes.Get()\n}\n\n// GetSnapshotDeactivationTimeoutMinutesOk returns a tuple with the SnapshotDeactivationTimeoutMinutes field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationQuota) GetSnapshotDeactivationTimeoutMinutesOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotDeactivationTimeoutMinutes.Get(), o.SnapshotDeactivationTimeoutMinutes.IsSet()\n}\n\n// SetSnapshotDeactivationTimeoutMinutes sets field value\nfunc (o *UpdateOrganizationQuota) SetSnapshotDeactivationTimeoutMinutes(v float32) {\n\to.SnapshotDeactivationTimeoutMinutes.Set(&v)\n}\n\nfunc (o UpdateOrganizationQuota) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateOrganizationQuota) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"maxCpuPerSandbox\"] = o.MaxCpuPerSandbox.Get()\n\ttoSerialize[\"maxMemoryPerSandbox\"] = o.MaxMemoryPerSandbox.Get()\n\ttoSerialize[\"maxDiskPerSandbox\"] = o.MaxDiskPerSandbox.Get()\n\ttoSerialize[\"snapshotQuota\"] = o.SnapshotQuota.Get()\n\ttoSerialize[\"maxSnapshotSize\"] = o.MaxSnapshotSize.Get()\n\ttoSerialize[\"volumeQuota\"] = o.VolumeQuota.Get()\n\ttoSerialize[\"authenticatedRateLimit\"] = o.AuthenticatedRateLimit.Get()\n\ttoSerialize[\"sandboxCreateRateLimit\"] = o.SandboxCreateRateLimit.Get()\n\ttoSerialize[\"sandboxLifecycleRateLimit\"] = o.SandboxLifecycleRateLimit.Get()\n\ttoSerialize[\"authenticatedRateLimitTtlSeconds\"] = o.AuthenticatedRateLimitTtlSeconds.Get()\n\ttoSerialize[\"sandboxCreateRateLimitTtlSeconds\"] = o.SandboxCreateRateLimitTtlSeconds.Get()\n\ttoSerialize[\"sandboxLifecycleRateLimitTtlSeconds\"] = o.SandboxLifecycleRateLimitTtlSeconds.Get()\n\ttoSerialize[\"snapshotDeactivationTimeoutMinutes\"] = o.SnapshotDeactivationTimeoutMinutes.Get()\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateOrganizationQuota) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"maxCpuPerSandbox\",\n\t\t\"maxMemoryPerSandbox\",\n\t\t\"maxDiskPerSandbox\",\n\t\t\"snapshotQuota\",\n\t\t\"maxSnapshotSize\",\n\t\t\"volumeQuota\",\n\t\t\"authenticatedRateLimit\",\n\t\t\"sandboxCreateRateLimit\",\n\t\t\"sandboxLifecycleRateLimit\",\n\t\t\"authenticatedRateLimitTtlSeconds\",\n\t\t\"sandboxCreateRateLimitTtlSeconds\",\n\t\t\"sandboxLifecycleRateLimitTtlSeconds\",\n\t\t\"snapshotDeactivationTimeoutMinutes\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateOrganizationQuota := _UpdateOrganizationQuota{}\n\n\terr = json.Unmarshal(data, &varUpdateOrganizationQuota)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateOrganizationQuota(varUpdateOrganizationQuota)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"maxCpuPerSandbox\")\n\t\tdelete(additionalProperties, \"maxMemoryPerSandbox\")\n\t\tdelete(additionalProperties, \"maxDiskPerSandbox\")\n\t\tdelete(additionalProperties, \"snapshotQuota\")\n\t\tdelete(additionalProperties, \"maxSnapshotSize\")\n\t\tdelete(additionalProperties, \"volumeQuota\")\n\t\tdelete(additionalProperties, \"authenticatedRateLimit\")\n\t\tdelete(additionalProperties, \"sandboxCreateRateLimit\")\n\t\tdelete(additionalProperties, \"sandboxLifecycleRateLimit\")\n\t\tdelete(additionalProperties, \"authenticatedRateLimitTtlSeconds\")\n\t\tdelete(additionalProperties, \"sandboxCreateRateLimitTtlSeconds\")\n\t\tdelete(additionalProperties, \"sandboxLifecycleRateLimitTtlSeconds\")\n\t\tdelete(additionalProperties, \"snapshotDeactivationTimeoutMinutes\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateOrganizationQuota struct {\n\tvalue *UpdateOrganizationQuota\n\tisSet bool\n}\n\nfunc (v NullableUpdateOrganizationQuota) Get() *UpdateOrganizationQuota {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateOrganizationQuota) Set(val *UpdateOrganizationQuota) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateOrganizationQuota) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateOrganizationQuota) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateOrganizationQuota(val *UpdateOrganizationQuota) *NullableUpdateOrganizationQuota {\n\treturn &NullableUpdateOrganizationQuota{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateOrganizationQuota) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateOrganizationQuota) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_organization_region_quota.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UpdateOrganizationRegionQuota type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateOrganizationRegionQuota{}\n\n// UpdateOrganizationRegionQuota struct for UpdateOrganizationRegionQuota\ntype UpdateOrganizationRegionQuota struct {\n\tTotalCpuQuota NullableFloat32 `json:\"totalCpuQuota\"`\n\tTotalMemoryQuota NullableFloat32 `json:\"totalMemoryQuota\"`\n\tTotalDiskQuota NullableFloat32 `json:\"totalDiskQuota\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateOrganizationRegionQuota UpdateOrganizationRegionQuota\n\n// NewUpdateOrganizationRegionQuota instantiates a new UpdateOrganizationRegionQuota object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateOrganizationRegionQuota(totalCpuQuota NullableFloat32, totalMemoryQuota NullableFloat32, totalDiskQuota NullableFloat32) *UpdateOrganizationRegionQuota {\n\tthis := UpdateOrganizationRegionQuota{}\n\tthis.TotalCpuQuota = totalCpuQuota\n\tthis.TotalMemoryQuota = totalMemoryQuota\n\tthis.TotalDiskQuota = totalDiskQuota\n\treturn &this\n}\n\n// NewUpdateOrganizationRegionQuotaWithDefaults instantiates a new UpdateOrganizationRegionQuota object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateOrganizationRegionQuotaWithDefaults() *UpdateOrganizationRegionQuota {\n\tthis := UpdateOrganizationRegionQuota{}\n\treturn &this\n}\n\n// GetTotalCpuQuota returns the TotalCpuQuota field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationRegionQuota) GetTotalCpuQuota() float32 {\n\tif o == nil || o.TotalCpuQuota.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.TotalCpuQuota.Get()\n}\n\n// GetTotalCpuQuotaOk returns a tuple with the TotalCpuQuota field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationRegionQuota) GetTotalCpuQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.TotalCpuQuota.Get(), o.TotalCpuQuota.IsSet()\n}\n\n// SetTotalCpuQuota sets field value\nfunc (o *UpdateOrganizationRegionQuota) SetTotalCpuQuota(v float32) {\n\to.TotalCpuQuota.Set(&v)\n}\n\n// GetTotalMemoryQuota returns the TotalMemoryQuota field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationRegionQuota) GetTotalMemoryQuota() float32 {\n\tif o == nil || o.TotalMemoryQuota.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.TotalMemoryQuota.Get()\n}\n\n// GetTotalMemoryQuotaOk returns a tuple with the TotalMemoryQuota field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationRegionQuota) GetTotalMemoryQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.TotalMemoryQuota.Get(), o.TotalMemoryQuota.IsSet()\n}\n\n// SetTotalMemoryQuota sets field value\nfunc (o *UpdateOrganizationRegionQuota) SetTotalMemoryQuota(v float32) {\n\to.TotalMemoryQuota.Set(&v)\n}\n\n// GetTotalDiskQuota returns the TotalDiskQuota field value\n// If the value is explicit nil, the zero value for float32 will be returned\nfunc (o *UpdateOrganizationRegionQuota) GetTotalDiskQuota() float32 {\n\tif o == nil || o.TotalDiskQuota.Get() == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn *o.TotalDiskQuota.Get()\n}\n\n// GetTotalDiskQuotaOk returns a tuple with the TotalDiskQuota field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateOrganizationRegionQuota) GetTotalDiskQuotaOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.TotalDiskQuota.Get(), o.TotalDiskQuota.IsSet()\n}\n\n// SetTotalDiskQuota sets field value\nfunc (o *UpdateOrganizationRegionQuota) SetTotalDiskQuota(v float32) {\n\to.TotalDiskQuota.Set(&v)\n}\n\nfunc (o UpdateOrganizationRegionQuota) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateOrganizationRegionQuota) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"totalCpuQuota\"] = o.TotalCpuQuota.Get()\n\ttoSerialize[\"totalMemoryQuota\"] = o.TotalMemoryQuota.Get()\n\ttoSerialize[\"totalDiskQuota\"] = o.TotalDiskQuota.Get()\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateOrganizationRegionQuota) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"totalCpuQuota\",\n\t\t\"totalMemoryQuota\",\n\t\t\"totalDiskQuota\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateOrganizationRegionQuota := _UpdateOrganizationRegionQuota{}\n\n\terr = json.Unmarshal(data, &varUpdateOrganizationRegionQuota)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateOrganizationRegionQuota(varUpdateOrganizationRegionQuota)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"totalCpuQuota\")\n\t\tdelete(additionalProperties, \"totalMemoryQuota\")\n\t\tdelete(additionalProperties, \"totalDiskQuota\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateOrganizationRegionQuota struct {\n\tvalue *UpdateOrganizationRegionQuota\n\tisSet bool\n}\n\nfunc (v NullableUpdateOrganizationRegionQuota) Get() *UpdateOrganizationRegionQuota {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateOrganizationRegionQuota) Set(val *UpdateOrganizationRegionQuota) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateOrganizationRegionQuota) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateOrganizationRegionQuota) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateOrganizationRegionQuota(val *UpdateOrganizationRegionQuota) *NullableUpdateOrganizationRegionQuota {\n\treturn &NullableUpdateOrganizationRegionQuota{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateOrganizationRegionQuota) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateOrganizationRegionQuota) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_organization_role.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UpdateOrganizationRole type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateOrganizationRole{}\n\n// UpdateOrganizationRole struct for UpdateOrganizationRole\ntype UpdateOrganizationRole struct {\n\t// The name of the role\n\tName string `json:\"name\"`\n\t// The description of the role\n\tDescription string `json:\"description\"`\n\t// The list of permissions assigned to the role\n\tPermissions []string `json:\"permissions\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateOrganizationRole UpdateOrganizationRole\n\n// NewUpdateOrganizationRole instantiates a new UpdateOrganizationRole object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateOrganizationRole(name string, description string, permissions []string) *UpdateOrganizationRole {\n\tthis := UpdateOrganizationRole{}\n\tthis.Name = name\n\tthis.Description = description\n\tthis.Permissions = permissions\n\treturn &this\n}\n\n// NewUpdateOrganizationRoleWithDefaults instantiates a new UpdateOrganizationRole object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateOrganizationRoleWithDefaults() *UpdateOrganizationRole {\n\tthis := UpdateOrganizationRole{}\n\treturn &this\n}\n\n// GetName returns the Name field value\nfunc (o *UpdateOrganizationRole) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationRole) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *UpdateOrganizationRole) SetName(v string) {\n\to.Name = v\n}\n\n// GetDescription returns the Description field value\nfunc (o *UpdateOrganizationRole) GetDescription() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Description\n}\n\n// GetDescriptionOk returns a tuple with the Description field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationRole) GetDescriptionOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Description, true\n}\n\n// SetDescription sets field value\nfunc (o *UpdateOrganizationRole) SetDescription(v string) {\n\to.Description = v\n}\n\n// GetPermissions returns the Permissions field value\nfunc (o *UpdateOrganizationRole) GetPermissions() []string {\n\tif o == nil {\n\t\tvar ret []string\n\t\treturn ret\n\t}\n\n\treturn o.Permissions\n}\n\n// GetPermissionsOk returns a tuple with the Permissions field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateOrganizationRole) GetPermissionsOk() ([]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Permissions, true\n}\n\n// SetPermissions sets field value\nfunc (o *UpdateOrganizationRole) SetPermissions(v []string) {\n\to.Permissions = v\n}\n\nfunc (o UpdateOrganizationRole) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateOrganizationRole) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"description\"] = o.Description\n\ttoSerialize[\"permissions\"] = o.Permissions\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateOrganizationRole) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"name\",\n\t\t\"description\",\n\t\t\"permissions\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateOrganizationRole := _UpdateOrganizationRole{}\n\n\terr = json.Unmarshal(data, &varUpdateOrganizationRole)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateOrganizationRole(varUpdateOrganizationRole)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"description\")\n\t\tdelete(additionalProperties, \"permissions\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateOrganizationRole struct {\n\tvalue *UpdateOrganizationRole\n\tisSet bool\n}\n\nfunc (v NullableUpdateOrganizationRole) Get() *UpdateOrganizationRole {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateOrganizationRole) Set(val *UpdateOrganizationRole) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateOrganizationRole) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateOrganizationRole) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateOrganizationRole(val *UpdateOrganizationRole) *NullableUpdateOrganizationRole {\n\treturn &NullableUpdateOrganizationRole{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateOrganizationRole) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateOrganizationRole) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_region.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the UpdateRegion type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateRegion{}\n\n// UpdateRegion struct for UpdateRegion\ntype UpdateRegion struct {\n\t// Proxy URL for the region\n\tProxyUrl NullableString `json:\"proxyUrl,omitempty\"`\n\t// SSH Gateway URL for the region\n\tSshGatewayUrl NullableString `json:\"sshGatewayUrl,omitempty\"`\n\t// Snapshot Manager URL for the region\n\tSnapshotManagerUrl NullableString `json:\"snapshotManagerUrl,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateRegion UpdateRegion\n\n// NewUpdateRegion instantiates a new UpdateRegion object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateRegion() *UpdateRegion {\n\tthis := UpdateRegion{}\n\treturn &this\n}\n\n// NewUpdateRegionWithDefaults instantiates a new UpdateRegion object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateRegionWithDefaults() *UpdateRegion {\n\tthis := UpdateRegion{}\n\treturn &this\n}\n\n// GetProxyUrl returns the ProxyUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *UpdateRegion) GetProxyUrl() string {\n\tif o == nil || IsNil(o.ProxyUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ProxyUrl.Get()\n}\n\n// GetProxyUrlOk returns a tuple with the ProxyUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateRegion) GetProxyUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ProxyUrl.Get(), o.ProxyUrl.IsSet()\n}\n\n// HasProxyUrl returns a boolean if a field has been set.\nfunc (o *UpdateRegion) HasProxyUrl() bool {\n\tif o != nil && o.ProxyUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetProxyUrl gets a reference to the given NullableString and assigns it to the ProxyUrl field.\nfunc (o *UpdateRegion) SetProxyUrl(v string) {\n\to.ProxyUrl.Set(&v)\n}\n// SetProxyUrlNil sets the value for ProxyUrl to be an explicit nil\nfunc (o *UpdateRegion) SetProxyUrlNil() {\n\to.ProxyUrl.Set(nil)\n}\n\n// UnsetProxyUrl ensures that no value is present for ProxyUrl, not even an explicit nil\nfunc (o *UpdateRegion) UnsetProxyUrl() {\n\to.ProxyUrl.Unset()\n}\n\n// GetSshGatewayUrl returns the SshGatewayUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *UpdateRegion) GetSshGatewayUrl() string {\n\tif o == nil || IsNil(o.SshGatewayUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SshGatewayUrl.Get()\n}\n\n// GetSshGatewayUrlOk returns a tuple with the SshGatewayUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateRegion) GetSshGatewayUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SshGatewayUrl.Get(), o.SshGatewayUrl.IsSet()\n}\n\n// HasSshGatewayUrl returns a boolean if a field has been set.\nfunc (o *UpdateRegion) HasSshGatewayUrl() bool {\n\tif o != nil && o.SshGatewayUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSshGatewayUrl gets a reference to the given NullableString and assigns it to the SshGatewayUrl field.\nfunc (o *UpdateRegion) SetSshGatewayUrl(v string) {\n\to.SshGatewayUrl.Set(&v)\n}\n// SetSshGatewayUrlNil sets the value for SshGatewayUrl to be an explicit nil\nfunc (o *UpdateRegion) SetSshGatewayUrlNil() {\n\to.SshGatewayUrl.Set(nil)\n}\n\n// UnsetSshGatewayUrl ensures that no value is present for SshGatewayUrl, not even an explicit nil\nfunc (o *UpdateRegion) UnsetSshGatewayUrl() {\n\to.SshGatewayUrl.Unset()\n}\n\n// GetSnapshotManagerUrl returns the SnapshotManagerUrl field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *UpdateRegion) GetSnapshotManagerUrl() string {\n\tif o == nil || IsNil(o.SnapshotManagerUrl.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SnapshotManagerUrl.Get()\n}\n\n// GetSnapshotManagerUrlOk returns a tuple with the SnapshotManagerUrl field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *UpdateRegion) GetSnapshotManagerUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotManagerUrl.Get(), o.SnapshotManagerUrl.IsSet()\n}\n\n// HasSnapshotManagerUrl returns a boolean if a field has been set.\nfunc (o *UpdateRegion) HasSnapshotManagerUrl() bool {\n\tif o != nil && o.SnapshotManagerUrl.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshotManagerUrl gets a reference to the given NullableString and assigns it to the SnapshotManagerUrl field.\nfunc (o *UpdateRegion) SetSnapshotManagerUrl(v string) {\n\to.SnapshotManagerUrl.Set(&v)\n}\n// SetSnapshotManagerUrlNil sets the value for SnapshotManagerUrl to be an explicit nil\nfunc (o *UpdateRegion) SetSnapshotManagerUrlNil() {\n\to.SnapshotManagerUrl.Set(nil)\n}\n\n// UnsetSnapshotManagerUrl ensures that no value is present for SnapshotManagerUrl, not even an explicit nil\nfunc (o *UpdateRegion) UnsetSnapshotManagerUrl() {\n\to.SnapshotManagerUrl.Unset()\n}\n\nfunc (o UpdateRegion) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateRegion) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif o.ProxyUrl.IsSet() {\n\t\ttoSerialize[\"proxyUrl\"] = o.ProxyUrl.Get()\n\t}\n\tif o.SshGatewayUrl.IsSet() {\n\t\ttoSerialize[\"sshGatewayUrl\"] = o.SshGatewayUrl.Get()\n\t}\n\tif o.SnapshotManagerUrl.IsSet() {\n\t\ttoSerialize[\"snapshotManagerUrl\"] = o.SnapshotManagerUrl.Get()\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateRegion) UnmarshalJSON(data []byte) (err error) {\n\tvarUpdateRegion := _UpdateRegion{}\n\n\terr = json.Unmarshal(data, &varUpdateRegion)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateRegion(varUpdateRegion)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"proxyUrl\")\n\t\tdelete(additionalProperties, \"sshGatewayUrl\")\n\t\tdelete(additionalProperties, \"snapshotManagerUrl\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateRegion struct {\n\tvalue *UpdateRegion\n\tisSet bool\n}\n\nfunc (v NullableUpdateRegion) Get() *UpdateRegion {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateRegion) Set(val *UpdateRegion) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateRegion) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateRegion) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateRegion(val *UpdateRegion) *NullableUpdateRegion {\n\treturn &NullableUpdateRegion{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateRegion) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateRegion) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_update_sandbox_state_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UpdateSandboxStateDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UpdateSandboxStateDto{}\n\n// UpdateSandboxStateDto struct for UpdateSandboxStateDto\ntype UpdateSandboxStateDto struct {\n\t// The new state for the sandbox\n\tState string `json:\"state\"`\n\t// Optional error message when reporting an error state\n\tErrorReason *string `json:\"errorReason,omitempty\"`\n\t// Whether the sandbox is recoverable\n\tRecoverable *bool `json:\"recoverable,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UpdateSandboxStateDto UpdateSandboxStateDto\n\n// NewUpdateSandboxStateDto instantiates a new UpdateSandboxStateDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUpdateSandboxStateDto(state string) *UpdateSandboxStateDto {\n\tthis := UpdateSandboxStateDto{}\n\tthis.State = state\n\treturn &this\n}\n\n// NewUpdateSandboxStateDtoWithDefaults instantiates a new UpdateSandboxStateDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUpdateSandboxStateDtoWithDefaults() *UpdateSandboxStateDto {\n\tthis := UpdateSandboxStateDto{}\n\treturn &this\n}\n\n// GetState returns the State field value\nfunc (o *UpdateSandboxStateDto) GetState() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.State\n}\n\n// GetStateOk returns a tuple with the State field value\n// and a boolean to check if the value has been set.\nfunc (o *UpdateSandboxStateDto) GetStateOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.State, true\n}\n\n// SetState sets field value\nfunc (o *UpdateSandboxStateDto) SetState(v string) {\n\to.State = v\n}\n\n// GetErrorReason returns the ErrorReason field value if set, zero value otherwise.\nfunc (o *UpdateSandboxStateDto) GetErrorReason() string {\n\tif o == nil || IsNil(o.ErrorReason) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ErrorReason\n}\n\n// GetErrorReasonOk returns a tuple with the ErrorReason field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *UpdateSandboxStateDto) GetErrorReasonOk() (*string, bool) {\n\tif o == nil || IsNil(o.ErrorReason) {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorReason, true\n}\n\n// HasErrorReason returns a boolean if a field has been set.\nfunc (o *UpdateSandboxStateDto) HasErrorReason() bool {\n\tif o != nil && !IsNil(o.ErrorReason) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetErrorReason gets a reference to the given string and assigns it to the ErrorReason field.\nfunc (o *UpdateSandboxStateDto) SetErrorReason(v string) {\n\to.ErrorReason = &v\n}\n\n// GetRecoverable returns the Recoverable field value if set, zero value otherwise.\nfunc (o *UpdateSandboxStateDto) GetRecoverable() bool {\n\tif o == nil || IsNil(o.Recoverable) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Recoverable\n}\n\n// GetRecoverableOk returns a tuple with the Recoverable field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *UpdateSandboxStateDto) GetRecoverableOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Recoverable) {\n\t\treturn nil, false\n\t}\n\treturn o.Recoverable, true\n}\n\n// HasRecoverable returns a boolean if a field has been set.\nfunc (o *UpdateSandboxStateDto) HasRecoverable() bool {\n\tif o != nil && !IsNil(o.Recoverable) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRecoverable gets a reference to the given bool and assigns it to the Recoverable field.\nfunc (o *UpdateSandboxStateDto) SetRecoverable(v bool) {\n\to.Recoverable = &v\n}\n\nfunc (o UpdateSandboxStateDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UpdateSandboxStateDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"state\"] = o.State\n\tif !IsNil(o.ErrorReason) {\n\t\ttoSerialize[\"errorReason\"] = o.ErrorReason\n\t}\n\tif !IsNil(o.Recoverable) {\n\t\ttoSerialize[\"recoverable\"] = o.Recoverable\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UpdateSandboxStateDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"state\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUpdateSandboxStateDto := _UpdateSandboxStateDto{}\n\n\terr = json.Unmarshal(data, &varUpdateSandboxStateDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UpdateSandboxStateDto(varUpdateSandboxStateDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"state\")\n\t\tdelete(additionalProperties, \"errorReason\")\n\t\tdelete(additionalProperties, \"recoverable\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUpdateSandboxStateDto struct {\n\tvalue *UpdateSandboxStateDto\n\tisSet bool\n}\n\nfunc (v NullableUpdateSandboxStateDto) Get() *UpdateSandboxStateDto {\n\treturn v.value\n}\n\nfunc (v *NullableUpdateSandboxStateDto) Set(val *UpdateSandboxStateDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUpdateSandboxStateDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUpdateSandboxStateDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUpdateSandboxStateDto(val *UpdateSandboxStateDto) *NullableUpdateSandboxStateDto {\n\treturn &NullableUpdateSandboxStateDto{value: val, isSet: true}\n}\n\nfunc (v NullableUpdateSandboxStateDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUpdateSandboxStateDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_url.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Url type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Url{}\n\n// Url struct for Url\ntype Url struct {\n\t// URL response\n\tUrl string `json:\"url\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Url Url\n\n// NewUrl instantiates a new Url object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUrl(url string) *Url {\n\tthis := Url{}\n\tthis.Url = url\n\treturn &this\n}\n\n// NewUrlWithDefaults instantiates a new Url object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUrlWithDefaults() *Url {\n\tthis := Url{}\n\treturn &this\n}\n\n// GetUrl returns the Url field value\nfunc (o *Url) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *Url) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *Url) SetUrl(v string) {\n\to.Url = v\n}\n\nfunc (o Url) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Url) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"url\"] = o.Url\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Url) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"url\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUrl := _Url{}\n\n\terr = json.Unmarshal(data, &varUrl)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Url(varUrl)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"url\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUrl struct {\n\tvalue *Url\n\tisSet bool\n}\n\nfunc (v NullableUrl) Get() *Url {\n\treturn v.value\n}\n\nfunc (v *NullableUrl) Set(val *Url) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUrl) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUrl) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUrl(val *Url) *NullableUrl {\n\treturn &NullableUrl{value: val, isSet: true}\n}\n\nfunc (v NullableUrl) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUrl) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_user.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\t\"fmt\"\n)\n\n// checks if the User type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &User{}\n\n// User struct for User\ntype User struct {\n\t// User ID\n\tId string `json:\"id\"`\n\t// User name\n\tName string `json:\"name\"`\n\t// User email\n\tEmail string `json:\"email\"`\n\t// User public keys\n\tPublicKeys []UserPublicKey `json:\"publicKeys\"`\n\t// Creation timestamp\n\tCreatedAt time.Time `json:\"createdAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _User User\n\n// NewUser instantiates a new User object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUser(id string, name string, email string, publicKeys []UserPublicKey, createdAt time.Time) *User {\n\tthis := User{}\n\tthis.Id = id\n\tthis.Name = name\n\tthis.Email = email\n\tthis.PublicKeys = publicKeys\n\tthis.CreatedAt = createdAt\n\treturn &this\n}\n\n// NewUserWithDefaults instantiates a new User object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUserWithDefaults() *User {\n\tthis := User{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *User) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *User) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *User) SetId(v string) {\n\to.Id = v\n}\n\n// GetName returns the Name field value\nfunc (o *User) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *User) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *User) SetName(v string) {\n\to.Name = v\n}\n\n// GetEmail returns the Email field value\nfunc (o *User) GetEmail() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Email\n}\n\n// GetEmailOk returns a tuple with the Email field value\n// and a boolean to check if the value has been set.\nfunc (o *User) GetEmailOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Email, true\n}\n\n// SetEmail sets field value\nfunc (o *User) SetEmail(v string) {\n\to.Email = v\n}\n\n// GetPublicKeys returns the PublicKeys field value\nfunc (o *User) GetPublicKeys() []UserPublicKey {\n\tif o == nil {\n\t\tvar ret []UserPublicKey\n\t\treturn ret\n\t}\n\n\treturn o.PublicKeys\n}\n\n// GetPublicKeysOk returns a tuple with the PublicKeys field value\n// and a boolean to check if the value has been set.\nfunc (o *User) GetPublicKeysOk() ([]UserPublicKey, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.PublicKeys, true\n}\n\n// SetPublicKeys sets field value\nfunc (o *User) SetPublicKeys(v []UserPublicKey) {\n\to.PublicKeys = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *User) GetCreatedAt() time.Time {\n\tif o == nil {\n\t\tvar ret time.Time\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *User) GetCreatedAtOk() (*time.Time, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *User) SetCreatedAt(v time.Time) {\n\to.CreatedAt = v\n}\n\nfunc (o User) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o User) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"email\"] = o.Email\n\ttoSerialize[\"publicKeys\"] = o.PublicKeys\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *User) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"name\",\n\t\t\"email\",\n\t\t\"publicKeys\",\n\t\t\"createdAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUser := _User{}\n\n\terr = json.Unmarshal(data, &varUser)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = User(varUser)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"email\")\n\t\tdelete(additionalProperties, \"publicKeys\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUser struct {\n\tvalue *User\n\tisSet bool\n}\n\nfunc (v NullableUser) Get() *User {\n\treturn v.value\n}\n\nfunc (v *NullableUser) Set(val *User) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUser) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUser) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUser(val *User) *NullableUser {\n\treturn &NullableUser{value: val, isSet: true}\n}\n\nfunc (v NullableUser) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUser) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_user_home_dir_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the UserHomeDirResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UserHomeDirResponse{}\n\n// UserHomeDirResponse struct for UserHomeDirResponse\ntype UserHomeDirResponse struct {\n\tDir *string `json:\"dir,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UserHomeDirResponse UserHomeDirResponse\n\n// NewUserHomeDirResponse instantiates a new UserHomeDirResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUserHomeDirResponse() *UserHomeDirResponse {\n\tthis := UserHomeDirResponse{}\n\treturn &this\n}\n\n// NewUserHomeDirResponseWithDefaults instantiates a new UserHomeDirResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUserHomeDirResponseWithDefaults() *UserHomeDirResponse {\n\tthis := UserHomeDirResponse{}\n\treturn &this\n}\n\n// GetDir returns the Dir field value if set, zero value otherwise.\nfunc (o *UserHomeDirResponse) GetDir() string {\n\tif o == nil || IsNil(o.Dir) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Dir\n}\n\n// GetDirOk returns a tuple with the Dir field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *UserHomeDirResponse) GetDirOk() (*string, bool) {\n\tif o == nil || IsNil(o.Dir) {\n\t\treturn nil, false\n\t}\n\treturn o.Dir, true\n}\n\n// HasDir returns a boolean if a field has been set.\nfunc (o *UserHomeDirResponse) HasDir() bool {\n\tif o != nil && !IsNil(o.Dir) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDir gets a reference to the given string and assigns it to the Dir field.\nfunc (o *UserHomeDirResponse) SetDir(v string) {\n\to.Dir = &v\n}\n\nfunc (o UserHomeDirResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UserHomeDirResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Dir) {\n\t\ttoSerialize[\"dir\"] = o.Dir\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UserHomeDirResponse) UnmarshalJSON(data []byte) (err error) {\n\tvarUserHomeDirResponse := _UserHomeDirResponse{}\n\n\terr = json.Unmarshal(data, &varUserHomeDirResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UserHomeDirResponse(varUserHomeDirResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"dir\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUserHomeDirResponse struct {\n\tvalue *UserHomeDirResponse\n\tisSet bool\n}\n\nfunc (v NullableUserHomeDirResponse) Get() *UserHomeDirResponse {\n\treturn v.value\n}\n\nfunc (v *NullableUserHomeDirResponse) Set(val *UserHomeDirResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUserHomeDirResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUserHomeDirResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUserHomeDirResponse(val *UserHomeDirResponse) *NullableUserHomeDirResponse {\n\treturn &NullableUserHomeDirResponse{value: val, isSet: true}\n}\n\nfunc (v NullableUserHomeDirResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUserHomeDirResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_user_public_key.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the UserPublicKey type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &UserPublicKey{}\n\n// UserPublicKey struct for UserPublicKey\ntype UserPublicKey struct {\n\t// Public key\n\tKey string `json:\"key\"`\n\t// Key name\n\tName string `json:\"name\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _UserPublicKey UserPublicKey\n\n// NewUserPublicKey instantiates a new UserPublicKey object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewUserPublicKey(key string, name string) *UserPublicKey {\n\tthis := UserPublicKey{}\n\tthis.Key = key\n\tthis.Name = name\n\treturn &this\n}\n\n// NewUserPublicKeyWithDefaults instantiates a new UserPublicKey object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewUserPublicKeyWithDefaults() *UserPublicKey {\n\tthis := UserPublicKey{}\n\treturn &this\n}\n\n// GetKey returns the Key field value\nfunc (o *UserPublicKey) GetKey() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Key\n}\n\n// GetKeyOk returns a tuple with the Key field value\n// and a boolean to check if the value has been set.\nfunc (o *UserPublicKey) GetKeyOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Key, true\n}\n\n// SetKey sets field value\nfunc (o *UserPublicKey) SetKey(v string) {\n\to.Key = v\n}\n\n// GetName returns the Name field value\nfunc (o *UserPublicKey) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *UserPublicKey) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *UserPublicKey) SetName(v string) {\n\to.Name = v\n}\n\nfunc (o UserPublicKey) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o UserPublicKey) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"key\"] = o.Key\n\ttoSerialize[\"name\"] = o.Name\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *UserPublicKey) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"key\",\n\t\t\"name\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarUserPublicKey := _UserPublicKey{}\n\n\terr = json.Unmarshal(data, &varUserPublicKey)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = UserPublicKey(varUserPublicKey)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"key\")\n\t\tdelete(additionalProperties, \"name\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableUserPublicKey struct {\n\tvalue *UserPublicKey\n\tisSet bool\n}\n\nfunc (v NullableUserPublicKey) Get() *UserPublicKey {\n\treturn v.value\n}\n\nfunc (v *NullableUserPublicKey) Set(val *UserPublicKey) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableUserPublicKey) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableUserPublicKey) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableUserPublicKey(val *UserPublicKey) *NullableUserPublicKey {\n\treturn &NullableUserPublicKey{value: val, isSet: true}\n}\n\nfunc (v NullableUserPublicKey) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableUserPublicKey) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_volume_dto.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the VolumeDto type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &VolumeDto{}\n\n// VolumeDto struct for VolumeDto\ntype VolumeDto struct {\n\t// Volume ID\n\tId string `json:\"id\"`\n\t// Volume name\n\tName string `json:\"name\"`\n\t// Organization ID\n\tOrganizationId string `json:\"organizationId\"`\n\t// Volume state\n\tState VolumeState `json:\"state\"`\n\t// Creation timestamp\n\tCreatedAt string `json:\"createdAt\"`\n\t// Last update timestamp\n\tUpdatedAt string `json:\"updatedAt\"`\n\t// Last used timestamp\n\tLastUsedAt NullableString `json:\"lastUsedAt,omitempty\"`\n\t// The error reason of the volume\n\tErrorReason NullableString `json:\"errorReason\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _VolumeDto VolumeDto\n\n// NewVolumeDto instantiates a new VolumeDto object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewVolumeDto(id string, name string, organizationId string, state VolumeState, createdAt string, updatedAt string, errorReason NullableString) *VolumeDto {\n\tthis := VolumeDto{}\n\tthis.Id = id\n\tthis.Name = name\n\tthis.OrganizationId = organizationId\n\tthis.State = state\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\tthis.ErrorReason = errorReason\n\treturn &this\n}\n\n// NewVolumeDtoWithDefaults instantiates a new VolumeDto object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewVolumeDtoWithDefaults() *VolumeDto {\n\tthis := VolumeDto{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *VolumeDto) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *VolumeDto) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *VolumeDto) SetId(v string) {\n\to.Id = v\n}\n\n// GetName returns the Name field value\nfunc (o *VolumeDto) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *VolumeDto) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *VolumeDto) SetName(v string) {\n\to.Name = v\n}\n\n// GetOrganizationId returns the OrganizationId field value\nfunc (o *VolumeDto) GetOrganizationId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value\n// and a boolean to check if the value has been set.\nfunc (o *VolumeDto) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationId, true\n}\n\n// SetOrganizationId sets field value\nfunc (o *VolumeDto) SetOrganizationId(v string) {\n\to.OrganizationId = v\n}\n\n// GetState returns the State field value\nfunc (o *VolumeDto) GetState() VolumeState {\n\tif o == nil {\n\t\tvar ret VolumeState\n\t\treturn ret\n\t}\n\n\treturn o.State\n}\n\n// GetStateOk returns a tuple with the State field value\n// and a boolean to check if the value has been set.\nfunc (o *VolumeDto) GetStateOk() (*VolumeState, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.State, true\n}\n\n// SetState sets field value\nfunc (o *VolumeDto) SetState(v VolumeState) {\n\to.State = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *VolumeDto) GetCreatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *VolumeDto) GetCreatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *VolumeDto) SetCreatedAt(v string) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *VolumeDto) GetUpdatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *VolumeDto) GetUpdatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *VolumeDto) SetUpdatedAt(v string) {\n\to.UpdatedAt = v\n}\n\n// GetLastUsedAt returns the LastUsedAt field value if set, zero value otherwise (both if not set or set to explicit null).\nfunc (o *VolumeDto) GetLastUsedAt() string {\n\tif o == nil || IsNil(o.LastUsedAt.Get()) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.LastUsedAt.Get()\n}\n\n// GetLastUsedAtOk returns a tuple with the LastUsedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *VolumeDto) GetLastUsedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.LastUsedAt.Get(), o.LastUsedAt.IsSet()\n}\n\n// HasLastUsedAt returns a boolean if a field has been set.\nfunc (o *VolumeDto) HasLastUsedAt() bool {\n\tif o != nil && o.LastUsedAt.IsSet() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetLastUsedAt gets a reference to the given NullableString and assigns it to the LastUsedAt field.\nfunc (o *VolumeDto) SetLastUsedAt(v string) {\n\to.LastUsedAt.Set(&v)\n}\n// SetLastUsedAtNil sets the value for LastUsedAt to be an explicit nil\nfunc (o *VolumeDto) SetLastUsedAtNil() {\n\to.LastUsedAt.Set(nil)\n}\n\n// UnsetLastUsedAt ensures that no value is present for LastUsedAt, not even an explicit nil\nfunc (o *VolumeDto) UnsetLastUsedAt() {\n\to.LastUsedAt.Unset()\n}\n\n// GetErrorReason returns the ErrorReason field value\n// If the value is explicit nil, the zero value for string will be returned\nfunc (o *VolumeDto) GetErrorReason() string {\n\tif o == nil || o.ErrorReason.Get() == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn *o.ErrorReason.Get()\n}\n\n// GetErrorReasonOk returns a tuple with the ErrorReason field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *VolumeDto) GetErrorReasonOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorReason.Get(), o.ErrorReason.IsSet()\n}\n\n// SetErrorReason sets field value\nfunc (o *VolumeDto) SetErrorReason(v string) {\n\to.ErrorReason.Set(&v)\n}\n\nfunc (o VolumeDto) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o VolumeDto) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"name\"] = o.Name\n\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\ttoSerialize[\"state\"] = o.State\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\tif o.LastUsedAt.IsSet() {\n\t\ttoSerialize[\"lastUsedAt\"] = o.LastUsedAt.Get()\n\t}\n\ttoSerialize[\"errorReason\"] = o.ErrorReason.Get()\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *VolumeDto) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"name\",\n\t\t\"organizationId\",\n\t\t\"state\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t\t\"errorReason\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarVolumeDto := _VolumeDto{}\n\n\terr = json.Unmarshal(data, &varVolumeDto)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = VolumeDto(varVolumeDto)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"state\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"lastUsedAt\")\n\t\tdelete(additionalProperties, \"errorReason\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableVolumeDto struct {\n\tvalue *VolumeDto\n\tisSet bool\n}\n\nfunc (v NullableVolumeDto) Get() *VolumeDto {\n\treturn v.value\n}\n\nfunc (v *NullableVolumeDto) Set(val *VolumeDto) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableVolumeDto) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableVolumeDto) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableVolumeDto(val *VolumeDto) *NullableVolumeDto {\n\treturn &NullableVolumeDto{value: val, isSet: true}\n}\n\nfunc (v NullableVolumeDto) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableVolumeDto) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_volume_state.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// VolumeState Volume state\ntype VolumeState string\n\n// List of VolumeState\nconst (\n\tVOLUMESTATE_CREATING VolumeState = \"creating\"\n\tVOLUMESTATE_READY VolumeState = \"ready\"\n\tVOLUMESTATE_PENDING_CREATE VolumeState = \"pending_create\"\n\tVOLUMESTATE_PENDING_DELETE VolumeState = \"pending_delete\"\n\tVOLUMESTATE_DELETING VolumeState = \"deleting\"\n\tVOLUMESTATE_DELETED VolumeState = \"deleted\"\n\tVOLUMESTATE_ERROR VolumeState = \"error\"\n)\n\n// All allowed values of VolumeState enum\nvar AllowedVolumeStateEnumValues = []VolumeState{\n\t\"creating\",\n\t\"ready\",\n\t\"pending_create\",\n\t\"pending_delete\",\n\t\"deleting\",\n\t\"deleted\",\n\t\"error\",\n}\n\nfunc (v *VolumeState) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := VolumeState(value)\n\tfor _, existing := range AllowedVolumeStateEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid VolumeState\", value)\n}\n\n// NewVolumeStateFromValue returns a pointer to a valid VolumeState\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewVolumeStateFromValue(v string) (*VolumeState, error) {\n\tev := VolumeState(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for VolumeState: valid values are %v\", v, AllowedVolumeStateEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v VolumeState) IsValid() bool {\n\tfor _, existing := range AllowedVolumeStateEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to VolumeState value\nfunc (v VolumeState) Ptr() *VolumeState {\n\treturn &v\n}\n\ntype NullableVolumeState struct {\n\tvalue *VolumeState\n\tisSet bool\n}\n\nfunc (v NullableVolumeState) Get() *VolumeState {\n\treturn v.value\n}\n\nfunc (v *NullableVolumeState) Set(val *VolumeState) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableVolumeState) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableVolumeState) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableVolumeState(val *VolumeState) *NullableVolumeState {\n\treturn &NullableVolumeState{value: val, isSet: true}\n}\n\nfunc (v NullableVolumeState) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableVolumeState) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_webhook_app_portal_access.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the WebhookAppPortalAccess type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &WebhookAppPortalAccess{}\n\n// WebhookAppPortalAccess struct for WebhookAppPortalAccess\ntype WebhookAppPortalAccess struct {\n\t// The authentication token for the Svix consumer app portal\n\tToken string `json:\"token\"`\n\t// The URL to the webhook app portal\n\tUrl string `json:\"url\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _WebhookAppPortalAccess WebhookAppPortalAccess\n\n// NewWebhookAppPortalAccess instantiates a new WebhookAppPortalAccess object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewWebhookAppPortalAccess(token string, url string) *WebhookAppPortalAccess {\n\tthis := WebhookAppPortalAccess{}\n\tthis.Token = token\n\tthis.Url = url\n\treturn &this\n}\n\n// NewWebhookAppPortalAccessWithDefaults instantiates a new WebhookAppPortalAccess object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewWebhookAppPortalAccessWithDefaults() *WebhookAppPortalAccess {\n\tthis := WebhookAppPortalAccess{}\n\treturn &this\n}\n\n// GetToken returns the Token field value\nfunc (o *WebhookAppPortalAccess) GetToken() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Token\n}\n\n// GetTokenOk returns a tuple with the Token field value\n// and a boolean to check if the value has been set.\nfunc (o *WebhookAppPortalAccess) GetTokenOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Token, true\n}\n\n// SetToken sets field value\nfunc (o *WebhookAppPortalAccess) SetToken(v string) {\n\to.Token = v\n}\n\n// GetUrl returns the Url field value\nfunc (o *WebhookAppPortalAccess) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *WebhookAppPortalAccess) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *WebhookAppPortalAccess) SetUrl(v string) {\n\to.Url = v\n}\n\nfunc (o WebhookAppPortalAccess) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o WebhookAppPortalAccess) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"token\"] = o.Token\n\ttoSerialize[\"url\"] = o.Url\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *WebhookAppPortalAccess) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"token\",\n\t\t\"url\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarWebhookAppPortalAccess := _WebhookAppPortalAccess{}\n\n\terr = json.Unmarshal(data, &varWebhookAppPortalAccess)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = WebhookAppPortalAccess(varWebhookAppPortalAccess)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"token\")\n\t\tdelete(additionalProperties, \"url\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableWebhookAppPortalAccess struct {\n\tvalue *WebhookAppPortalAccess\n\tisSet bool\n}\n\nfunc (v NullableWebhookAppPortalAccess) Get() *WebhookAppPortalAccess {\n\treturn v.value\n}\n\nfunc (v *NullableWebhookAppPortalAccess) Set(val *WebhookAppPortalAccess) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableWebhookAppPortalAccess) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableWebhookAppPortalAccess) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableWebhookAppPortalAccess(val *WebhookAppPortalAccess) *NullableWebhookAppPortalAccess {\n\treturn &NullableWebhookAppPortalAccess{value: val, isSet: true}\n}\n\nfunc (v NullableWebhookAppPortalAccess) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableWebhookAppPortalAccess) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_webhook_controller_get_status_200_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the WebhookControllerGetStatus200Response type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &WebhookControllerGetStatus200Response{}\n\n// WebhookControllerGetStatus200Response struct for WebhookControllerGetStatus200Response\ntype WebhookControllerGetStatus200Response struct {\n\tEnabled *bool `json:\"enabled,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _WebhookControllerGetStatus200Response WebhookControllerGetStatus200Response\n\n// NewWebhookControllerGetStatus200Response instantiates a new WebhookControllerGetStatus200Response object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewWebhookControllerGetStatus200Response() *WebhookControllerGetStatus200Response {\n\tthis := WebhookControllerGetStatus200Response{}\n\treturn &this\n}\n\n// NewWebhookControllerGetStatus200ResponseWithDefaults instantiates a new WebhookControllerGetStatus200Response object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewWebhookControllerGetStatus200ResponseWithDefaults() *WebhookControllerGetStatus200Response {\n\tthis := WebhookControllerGetStatus200Response{}\n\treturn &this\n}\n\n// GetEnabled returns the Enabled field value if set, zero value otherwise.\nfunc (o *WebhookControllerGetStatus200Response) GetEnabled() bool {\n\tif o == nil || IsNil(o.Enabled) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Enabled\n}\n\n// GetEnabledOk returns a tuple with the Enabled field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *WebhookControllerGetStatus200Response) GetEnabledOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Enabled) {\n\t\treturn nil, false\n\t}\n\treturn o.Enabled, true\n}\n\n// HasEnabled returns a boolean if a field has been set.\nfunc (o *WebhookControllerGetStatus200Response) HasEnabled() bool {\n\tif o != nil && !IsNil(o.Enabled) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetEnabled gets a reference to the given bool and assigns it to the Enabled field.\nfunc (o *WebhookControllerGetStatus200Response) SetEnabled(v bool) {\n\to.Enabled = &v\n}\n\nfunc (o WebhookControllerGetStatus200Response) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o WebhookControllerGetStatus200Response) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Enabled) {\n\t\ttoSerialize[\"enabled\"] = o.Enabled\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *WebhookControllerGetStatus200Response) UnmarshalJSON(data []byte) (err error) {\n\tvarWebhookControllerGetStatus200Response := _WebhookControllerGetStatus200Response{}\n\n\terr = json.Unmarshal(data, &varWebhookControllerGetStatus200Response)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = WebhookControllerGetStatus200Response(varWebhookControllerGetStatus200Response)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"enabled\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableWebhookControllerGetStatus200Response struct {\n\tvalue *WebhookControllerGetStatus200Response\n\tisSet bool\n}\n\nfunc (v NullableWebhookControllerGetStatus200Response) Get() *WebhookControllerGetStatus200Response {\n\treturn v.value\n}\n\nfunc (v *NullableWebhookControllerGetStatus200Response) Set(val *WebhookControllerGetStatus200Response) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableWebhookControllerGetStatus200Response) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableWebhookControllerGetStatus200Response) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableWebhookControllerGetStatus200Response(val *WebhookControllerGetStatus200Response) *NullableWebhookControllerGetStatus200Response {\n\treturn &NullableWebhookControllerGetStatus200Response{value: val, isSet: true}\n}\n\nfunc (v NullableWebhookControllerGetStatus200Response) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableWebhookControllerGetStatus200Response) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_webhook_event.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// WebhookEvent The type of event being sent\ntype WebhookEvent string\n\n// List of WebhookEvent\nconst (\n\tWEBHOOKEVENT_SANDBOX_CREATED WebhookEvent = \"sandbox.created\"\n\tWEBHOOKEVENT_SANDBOX_STATE_UPDATED WebhookEvent = \"sandbox.state.updated\"\n\tWEBHOOKEVENT_SNAPSHOT_CREATED WebhookEvent = \"snapshot.created\"\n\tWEBHOOKEVENT_SNAPSHOT_STATE_UPDATED WebhookEvent = \"snapshot.state.updated\"\n\tWEBHOOKEVENT_SNAPSHOT_REMOVED WebhookEvent = \"snapshot.removed\"\n\tWEBHOOKEVENT_VOLUME_CREATED WebhookEvent = \"volume.created\"\n\tWEBHOOKEVENT_VOLUME_STATE_UPDATED WebhookEvent = \"volume.state.updated\"\n)\n\n// All allowed values of WebhookEvent enum\nvar AllowedWebhookEventEnumValues = []WebhookEvent{\n\t\"sandbox.created\",\n\t\"sandbox.state.updated\",\n\t\"snapshot.created\",\n\t\"snapshot.state.updated\",\n\t\"snapshot.removed\",\n\t\"volume.created\",\n\t\"volume.state.updated\",\n}\n\nfunc (v *WebhookEvent) UnmarshalJSON(src []byte) error {\n\tvar value string\n\terr := json.Unmarshal(src, &value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenumTypeValue := WebhookEvent(value)\n\tfor _, existing := range AllowedWebhookEventEnumValues {\n\t\tif existing == enumTypeValue {\n\t\t\t*v = enumTypeValue\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"%+v is not a valid WebhookEvent\", value)\n}\n\n// NewWebhookEventFromValue returns a pointer to a valid WebhookEvent\n// for the value passed as argument, or an error if the value passed is not allowed by the enum\nfunc NewWebhookEventFromValue(v string) (*WebhookEvent, error) {\n\tev := WebhookEvent(v)\n\tif ev.IsValid() {\n\t\treturn &ev, nil\n\t} else {\n\t\treturn nil, fmt.Errorf(\"invalid value '%v' for WebhookEvent: valid values are %v\", v, AllowedWebhookEventEnumValues)\n\t}\n}\n\n// IsValid return true if the value is valid for the enum, false otherwise\nfunc (v WebhookEvent) IsValid() bool {\n\tfor _, existing := range AllowedWebhookEventEnumValues {\n\t\tif existing == v {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Ptr returns reference to WebhookEvent value\nfunc (v WebhookEvent) Ptr() *WebhookEvent {\n\treturn &v\n}\n\ntype NullableWebhookEvent struct {\n\tvalue *WebhookEvent\n\tisSet bool\n}\n\nfunc (v NullableWebhookEvent) Get() *WebhookEvent {\n\treturn v.value\n}\n\nfunc (v *NullableWebhookEvent) Set(val *WebhookEvent) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableWebhookEvent) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableWebhookEvent) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableWebhookEvent(val *WebhookEvent) *NullableWebhookEvent {\n\treturn &NullableWebhookEvent{value: val, isSet: true}\n}\n\nfunc (v NullableWebhookEvent) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableWebhookEvent) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n"
  },
  {
    "path": "libs/api-client-go/model_webhook_initialization_status.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the WebhookInitializationStatus type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &WebhookInitializationStatus{}\n\n// WebhookInitializationStatus struct for WebhookInitializationStatus\ntype WebhookInitializationStatus struct {\n\t// Organization ID\n\tOrganizationId string `json:\"organizationId\"`\n\t// The ID of the Svix application\n\tSvixApplicationId NullableString `json:\"svixApplicationId\"`\n\t// The error reason for the last initialization attempt\n\tLastError NullableString `json:\"lastError\"`\n\t// The number of times the initialization has been attempted\n\tRetryCount float32 `json:\"retryCount\"`\n\t// When the webhook initialization was created\n\tCreatedAt string `json:\"createdAt\"`\n\t// When the webhook initialization was last updated\n\tUpdatedAt string `json:\"updatedAt\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _WebhookInitializationStatus WebhookInitializationStatus\n\n// NewWebhookInitializationStatus instantiates a new WebhookInitializationStatus object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewWebhookInitializationStatus(organizationId string, svixApplicationId NullableString, lastError NullableString, retryCount float32, createdAt string, updatedAt string) *WebhookInitializationStatus {\n\tthis := WebhookInitializationStatus{}\n\tthis.OrganizationId = organizationId\n\tthis.SvixApplicationId = svixApplicationId\n\tthis.LastError = lastError\n\tthis.RetryCount = retryCount\n\tthis.CreatedAt = createdAt\n\tthis.UpdatedAt = updatedAt\n\treturn &this\n}\n\n// NewWebhookInitializationStatusWithDefaults instantiates a new WebhookInitializationStatus object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewWebhookInitializationStatusWithDefaults() *WebhookInitializationStatus {\n\tthis := WebhookInitializationStatus{}\n\treturn &this\n}\n\n// GetOrganizationId returns the OrganizationId field value\nfunc (o *WebhookInitializationStatus) GetOrganizationId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value\n// and a boolean to check if the value has been set.\nfunc (o *WebhookInitializationStatus) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationId, true\n}\n\n// SetOrganizationId sets field value\nfunc (o *WebhookInitializationStatus) SetOrganizationId(v string) {\n\to.OrganizationId = v\n}\n\n// GetSvixApplicationId returns the SvixApplicationId field value\n// If the value is explicit nil, the zero value for string will be returned\nfunc (o *WebhookInitializationStatus) GetSvixApplicationId() string {\n\tif o == nil || o.SvixApplicationId.Get() == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn *o.SvixApplicationId.Get()\n}\n\n// GetSvixApplicationIdOk returns a tuple with the SvixApplicationId field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *WebhookInitializationStatus) GetSvixApplicationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.SvixApplicationId.Get(), o.SvixApplicationId.IsSet()\n}\n\n// SetSvixApplicationId sets field value\nfunc (o *WebhookInitializationStatus) SetSvixApplicationId(v string) {\n\to.SvixApplicationId.Set(&v)\n}\n\n// GetLastError returns the LastError field value\n// If the value is explicit nil, the zero value for string will be returned\nfunc (o *WebhookInitializationStatus) GetLastError() string {\n\tif o == nil || o.LastError.Get() == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn *o.LastError.Get()\n}\n\n// GetLastErrorOk returns a tuple with the LastError field value\n// and a boolean to check if the value has been set.\n// NOTE: If the value is an explicit nil, `nil, true` will be returned\nfunc (o *WebhookInitializationStatus) GetLastErrorOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.LastError.Get(), o.LastError.IsSet()\n}\n\n// SetLastError sets field value\nfunc (o *WebhookInitializationStatus) SetLastError(v string) {\n\to.LastError.Set(&v)\n}\n\n// GetRetryCount returns the RetryCount field value\nfunc (o *WebhookInitializationStatus) GetRetryCount() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.RetryCount\n}\n\n// GetRetryCountOk returns a tuple with the RetryCount field value\n// and a boolean to check if the value has been set.\nfunc (o *WebhookInitializationStatus) GetRetryCountOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.RetryCount, true\n}\n\n// SetRetryCount sets field value\nfunc (o *WebhookInitializationStatus) SetRetryCount(v float32) {\n\to.RetryCount = v\n}\n\n// GetCreatedAt returns the CreatedAt field value\nfunc (o *WebhookInitializationStatus) GetCreatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *WebhookInitializationStatus) GetCreatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.CreatedAt, true\n}\n\n// SetCreatedAt sets field value\nfunc (o *WebhookInitializationStatus) SetCreatedAt(v string) {\n\to.CreatedAt = v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value\nfunc (o *WebhookInitializationStatus) GetUpdatedAt() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value\n// and a boolean to check if the value has been set.\nfunc (o *WebhookInitializationStatus) GetUpdatedAtOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.UpdatedAt, true\n}\n\n// SetUpdatedAt sets field value\nfunc (o *WebhookInitializationStatus) SetUpdatedAt(v string) {\n\to.UpdatedAt = v\n}\n\nfunc (o WebhookInitializationStatus) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o WebhookInitializationStatus) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\ttoSerialize[\"svixApplicationId\"] = o.SvixApplicationId.Get()\n\ttoSerialize[\"lastError\"] = o.LastError.Get()\n\ttoSerialize[\"retryCount\"] = o.RetryCount\n\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *WebhookInitializationStatus) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"organizationId\",\n\t\t\"svixApplicationId\",\n\t\t\"lastError\",\n\t\t\"retryCount\",\n\t\t\"createdAt\",\n\t\t\"updatedAt\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarWebhookInitializationStatus := _WebhookInitializationStatus{}\n\n\terr = json.Unmarshal(data, &varWebhookInitializationStatus)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = WebhookInitializationStatus(varWebhookInitializationStatus)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"svixApplicationId\")\n\t\tdelete(additionalProperties, \"lastError\")\n\t\tdelete(additionalProperties, \"retryCount\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableWebhookInitializationStatus struct {\n\tvalue *WebhookInitializationStatus\n\tisSet bool\n}\n\nfunc (v NullableWebhookInitializationStatus) Get() *WebhookInitializationStatus {\n\treturn v.value\n}\n\nfunc (v *NullableWebhookInitializationStatus) Set(val *WebhookInitializationStatus) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableWebhookInitializationStatus) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableWebhookInitializationStatus) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableWebhookInitializationStatus(val *WebhookInitializationStatus) *NullableWebhookInitializationStatus {\n\treturn &NullableWebhookInitializationStatus{value: val, isSet: true}\n}\n\nfunc (v NullableWebhookInitializationStatus) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableWebhookInitializationStatus) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_windows_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the WindowsResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &WindowsResponse{}\n\n// WindowsResponse struct for WindowsResponse\ntype WindowsResponse struct {\n\t// Array of window information for all visible windows\n\tWindows []map[string]interface{} `json:\"windows\"`\n\t// The total number of windows found\n\tCount float32 `json:\"count\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _WindowsResponse WindowsResponse\n\n// NewWindowsResponse instantiates a new WindowsResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewWindowsResponse(windows []map[string]interface{}, count float32) *WindowsResponse {\n\tthis := WindowsResponse{}\n\tthis.Windows = windows\n\tthis.Count = count\n\treturn &this\n}\n\n// NewWindowsResponseWithDefaults instantiates a new WindowsResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewWindowsResponseWithDefaults() *WindowsResponse {\n\tthis := WindowsResponse{}\n\treturn &this\n}\n\n// GetWindows returns the Windows field value\nfunc (o *WindowsResponse) GetWindows() []map[string]interface{} {\n\tif o == nil {\n\t\tvar ret []map[string]interface{}\n\t\treturn ret\n\t}\n\n\treturn o.Windows\n}\n\n// GetWindowsOk returns a tuple with the Windows field value\n// and a boolean to check if the value has been set.\nfunc (o *WindowsResponse) GetWindowsOk() ([]map[string]interface{}, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn o.Windows, true\n}\n\n// SetWindows sets field value\nfunc (o *WindowsResponse) SetWindows(v []map[string]interface{}) {\n\to.Windows = v\n}\n\n// GetCount returns the Count field value\nfunc (o *WindowsResponse) GetCount() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Count\n}\n\n// GetCountOk returns a tuple with the Count field value\n// and a boolean to check if the value has been set.\nfunc (o *WindowsResponse) GetCountOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Count, true\n}\n\n// SetCount sets field value\nfunc (o *WindowsResponse) SetCount(v float32) {\n\to.Count = v\n}\n\nfunc (o WindowsResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o WindowsResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"windows\"] = o.Windows\n\ttoSerialize[\"count\"] = o.Count\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *WindowsResponse) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"windows\",\n\t\t\"count\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarWindowsResponse := _WindowsResponse{}\n\n\terr = json.Unmarshal(data, &varWindowsResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = WindowsResponse(varWindowsResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"windows\")\n\t\tdelete(additionalProperties, \"count\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableWindowsResponse struct {\n\tvalue *WindowsResponse\n\tisSet bool\n}\n\nfunc (v NullableWindowsResponse) Get() *WindowsResponse {\n\treturn v.value\n}\n\nfunc (v *NullableWindowsResponse) Set(val *WindowsResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableWindowsResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableWindowsResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableWindowsResponse(val *WindowsResponse) *NullableWindowsResponse {\n\treturn &NullableWindowsResponse{value: val, isSet: true}\n}\n\nfunc (v NullableWindowsResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableWindowsResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_work_dir_response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n)\n\n// checks if the WorkDirResponse type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &WorkDirResponse{}\n\n// WorkDirResponse struct for WorkDirResponse\ntype WorkDirResponse struct {\n\tDir *string `json:\"dir,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _WorkDirResponse WorkDirResponse\n\n// NewWorkDirResponse instantiates a new WorkDirResponse object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewWorkDirResponse() *WorkDirResponse {\n\tthis := WorkDirResponse{}\n\treturn &this\n}\n\n// NewWorkDirResponseWithDefaults instantiates a new WorkDirResponse object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewWorkDirResponseWithDefaults() *WorkDirResponse {\n\tthis := WorkDirResponse{}\n\treturn &this\n}\n\n// GetDir returns the Dir field value if set, zero value otherwise.\nfunc (o *WorkDirResponse) GetDir() string {\n\tif o == nil || IsNil(o.Dir) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Dir\n}\n\n// GetDirOk returns a tuple with the Dir field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *WorkDirResponse) GetDirOk() (*string, bool) {\n\tif o == nil || IsNil(o.Dir) {\n\t\treturn nil, false\n\t}\n\treturn o.Dir, true\n}\n\n// HasDir returns a boolean if a field has been set.\nfunc (o *WorkDirResponse) HasDir() bool {\n\tif o != nil && !IsNil(o.Dir) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDir gets a reference to the given string and assigns it to the Dir field.\nfunc (o *WorkDirResponse) SetDir(v string) {\n\to.Dir = &v\n}\n\nfunc (o WorkDirResponse) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o WorkDirResponse) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\tif !IsNil(o.Dir) {\n\t\ttoSerialize[\"dir\"] = o.Dir\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *WorkDirResponse) UnmarshalJSON(data []byte) (err error) {\n\tvarWorkDirResponse := _WorkDirResponse{}\n\n\terr = json.Unmarshal(data, &varWorkDirResponse)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = WorkDirResponse(varWorkDirResponse)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"dir\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableWorkDirResponse struct {\n\tvalue *WorkDirResponse\n\tisSet bool\n}\n\nfunc (v NullableWorkDirResponse) Get() *WorkDirResponse {\n\treturn v.value\n}\n\nfunc (v *NullableWorkDirResponse) Set(val *WorkDirResponse) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableWorkDirResponse) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableWorkDirResponse) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableWorkDirResponse(val *WorkDirResponse) *NullableWorkDirResponse {\n\treturn &NullableWorkDirResponse{value: val, isSet: true}\n}\n\nfunc (v NullableWorkDirResponse) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableWorkDirResponse) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_workspace.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the Workspace type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &Workspace{}\n\n// Workspace struct for Workspace\ntype Workspace struct {\n\t// The ID of the sandbox\n\tId string `json:\"id\"`\n\t// The organization ID of the sandbox\n\tOrganizationId string `json:\"organizationId\"`\n\t// The name of the sandbox\n\tName string `json:\"name\"`\n\t// The snapshot used for the sandbox\n\tSnapshot *string `json:\"snapshot,omitempty\"`\n\t// The user associated with the project\n\tUser string `json:\"user\"`\n\t// Environment variables for the sandbox\n\tEnv map[string]string `json:\"env\"`\n\t// Labels for the sandbox\n\tLabels map[string]string `json:\"labels\"`\n\t// Whether the sandbox http preview is public\n\tPublic bool `json:\"public\"`\n\t// Whether to block all network access for the sandbox\n\tNetworkBlockAll bool `json:\"networkBlockAll\"`\n\t// Comma-separated list of allowed CIDR network addresses for the sandbox\n\tNetworkAllowList *string `json:\"networkAllowList,omitempty\"`\n\t// The target environment for the sandbox\n\tTarget string `json:\"target\"`\n\t// The CPU quota for the sandbox\n\tCpu float32 `json:\"cpu\"`\n\t// The GPU quota for the sandbox\n\tGpu float32 `json:\"gpu\"`\n\t// The memory quota for the sandbox\n\tMemory float32 `json:\"memory\"`\n\t// The disk quota for the sandbox\n\tDisk float32 `json:\"disk\"`\n\t// The state of the sandbox\n\tState *SandboxState `json:\"state,omitempty\"`\n\t// The desired state of the sandbox\n\tDesiredState *SandboxDesiredState `json:\"desiredState,omitempty\"`\n\t// The error reason of the sandbox\n\tErrorReason *string `json:\"errorReason,omitempty\"`\n\t// Whether the sandbox error is recoverable.\n\tRecoverable *bool `json:\"recoverable,omitempty\"`\n\t// The state of the backup\n\tBackupState *string `json:\"backupState,omitempty\"`\n\t// The creation timestamp of the last backup\n\tBackupCreatedAt *string `json:\"backupCreatedAt,omitempty\"`\n\t// Auto-stop interval in minutes (0 means disabled)\n\tAutoStopInterval *float32 `json:\"autoStopInterval,omitempty\"`\n\t// Auto-archive interval in minutes\n\tAutoArchiveInterval *float32 `json:\"autoArchiveInterval,omitempty\"`\n\t// Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\n\tAutoDeleteInterval *float32 `json:\"autoDeleteInterval,omitempty\"`\n\t// Array of volumes attached to the sandbox\n\tVolumes []SandboxVolume `json:\"volumes,omitempty\"`\n\t// Build information for the sandbox\n\tBuildInfo *BuildInfo `json:\"buildInfo,omitempty\"`\n\t// The creation timestamp of the sandbox\n\tCreatedAt *string `json:\"createdAt,omitempty\"`\n\t// The last update timestamp of the sandbox\n\tUpdatedAt *string `json:\"updatedAt,omitempty\"`\n\t// The class of the sandbox\n\t// Deprecated\n\tClass *string `json:\"class,omitempty\"`\n\t// The version of the daemon running in the sandbox\n\tDaemonVersion *string `json:\"daemonVersion,omitempty\"`\n\t// The runner ID of the sandbox\n\tRunnerId *string `json:\"runnerId,omitempty\"`\n\t// The toolbox proxy URL for the sandbox\n\tToolboxProxyUrl string `json:\"toolboxProxyUrl\"`\n\t// The image used for the workspace\n\tImage *string `json:\"image,omitempty\"`\n\t// The state of the snapshot\n\tSnapshotState *string `json:\"snapshotState,omitempty\"`\n\t// The creation timestamp of the last snapshot\n\tSnapshotCreatedAt *string `json:\"snapshotCreatedAt,omitempty\"`\n\t// Additional information about the sandbox\n\tInfo *SandboxInfo `json:\"info,omitempty\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _Workspace Workspace\n\n// NewWorkspace instantiates a new Workspace object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewWorkspace(id string, organizationId string, name string, user string, env map[string]string, labels map[string]string, public bool, networkBlockAll bool, target string, cpu float32, gpu float32, memory float32, disk float32, toolboxProxyUrl string) *Workspace {\n\tthis := Workspace{}\n\tthis.Id = id\n\tthis.OrganizationId = organizationId\n\tthis.Name = name\n\tthis.User = user\n\tthis.Env = env\n\tthis.Labels = labels\n\tthis.Public = public\n\tthis.NetworkBlockAll = networkBlockAll\n\tthis.Target = target\n\tthis.Cpu = cpu\n\tthis.Gpu = gpu\n\tthis.Memory = memory\n\tthis.Disk = disk\n\tthis.ToolboxProxyUrl = toolboxProxyUrl\n\treturn &this\n}\n\n// NewWorkspaceWithDefaults instantiates a new Workspace object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewWorkspaceWithDefaults() *Workspace {\n\tthis := Workspace{}\n\treturn &this\n}\n\n// GetId returns the Id field value\nfunc (o *Workspace) GetId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Id\n}\n\n// GetIdOk returns a tuple with the Id field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Id, true\n}\n\n// SetId sets field value\nfunc (o *Workspace) SetId(v string) {\n\to.Id = v\n}\n\n// GetOrganizationId returns the OrganizationId field value\nfunc (o *Workspace) GetOrganizationId() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.OrganizationId\n}\n\n// GetOrganizationIdOk returns a tuple with the OrganizationId field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetOrganizationIdOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.OrganizationId, true\n}\n\n// SetOrganizationId sets field value\nfunc (o *Workspace) SetOrganizationId(v string) {\n\to.OrganizationId = v\n}\n\n// GetName returns the Name field value\nfunc (o *Workspace) GetName() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Name\n}\n\n// GetNameOk returns a tuple with the Name field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetNameOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Name, true\n}\n\n// SetName sets field value\nfunc (o *Workspace) SetName(v string) {\n\to.Name = v\n}\n\n// GetSnapshot returns the Snapshot field value if set, zero value otherwise.\nfunc (o *Workspace) GetSnapshot() string {\n\tif o == nil || IsNil(o.Snapshot) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Snapshot\n}\n\n// GetSnapshotOk returns a tuple with the Snapshot field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetSnapshotOk() (*string, bool) {\n\tif o == nil || IsNil(o.Snapshot) {\n\t\treturn nil, false\n\t}\n\treturn o.Snapshot, true\n}\n\n// HasSnapshot returns a boolean if a field has been set.\nfunc (o *Workspace) HasSnapshot() bool {\n\tif o != nil && !IsNil(o.Snapshot) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshot gets a reference to the given string and assigns it to the Snapshot field.\nfunc (o *Workspace) SetSnapshot(v string) {\n\to.Snapshot = &v\n}\n\n// GetUser returns the User field value\nfunc (o *Workspace) GetUser() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.User\n}\n\n// GetUserOk returns a tuple with the User field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetUserOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.User, true\n}\n\n// SetUser sets field value\nfunc (o *Workspace) SetUser(v string) {\n\to.User = v\n}\n\n// GetEnv returns the Env field value\nfunc (o *Workspace) GetEnv() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\n\treturn o.Env\n}\n\n// GetEnvOk returns a tuple with the Env field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetEnvOk() (*map[string]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Env, true\n}\n\n// SetEnv sets field value\nfunc (o *Workspace) SetEnv(v map[string]string) {\n\to.Env = v\n}\n\n// GetLabels returns the Labels field value\nfunc (o *Workspace) GetLabels() map[string]string {\n\tif o == nil {\n\t\tvar ret map[string]string\n\t\treturn ret\n\t}\n\n\treturn o.Labels\n}\n\n// GetLabelsOk returns a tuple with the Labels field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetLabelsOk() (*map[string]string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Labels, true\n}\n\n// SetLabels sets field value\nfunc (o *Workspace) SetLabels(v map[string]string) {\n\to.Labels = v\n}\n\n// GetPublic returns the Public field value\nfunc (o *Workspace) GetPublic() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.Public\n}\n\n// GetPublicOk returns a tuple with the Public field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetPublicOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Public, true\n}\n\n// SetPublic sets field value\nfunc (o *Workspace) SetPublic(v bool) {\n\to.Public = v\n}\n\n// GetNetworkBlockAll returns the NetworkBlockAll field value\nfunc (o *Workspace) GetNetworkBlockAll() bool {\n\tif o == nil {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\n\treturn o.NetworkBlockAll\n}\n\n// GetNetworkBlockAllOk returns a tuple with the NetworkBlockAll field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetNetworkBlockAllOk() (*bool, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.NetworkBlockAll, true\n}\n\n// SetNetworkBlockAll sets field value\nfunc (o *Workspace) SetNetworkBlockAll(v bool) {\n\to.NetworkBlockAll = v\n}\n\n// GetNetworkAllowList returns the NetworkAllowList field value if set, zero value otherwise.\nfunc (o *Workspace) GetNetworkAllowList() string {\n\tif o == nil || IsNil(o.NetworkAllowList) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.NetworkAllowList\n}\n\n// GetNetworkAllowListOk returns a tuple with the NetworkAllowList field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetNetworkAllowListOk() (*string, bool) {\n\tif o == nil || IsNil(o.NetworkAllowList) {\n\t\treturn nil, false\n\t}\n\treturn o.NetworkAllowList, true\n}\n\n// HasNetworkAllowList returns a boolean if a field has been set.\nfunc (o *Workspace) HasNetworkAllowList() bool {\n\tif o != nil && !IsNil(o.NetworkAllowList) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetNetworkAllowList gets a reference to the given string and assigns it to the NetworkAllowList field.\nfunc (o *Workspace) SetNetworkAllowList(v string) {\n\to.NetworkAllowList = &v\n}\n\n// GetTarget returns the Target field value\nfunc (o *Workspace) GetTarget() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Target\n}\n\n// GetTargetOk returns a tuple with the Target field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetTargetOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Target, true\n}\n\n// SetTarget sets field value\nfunc (o *Workspace) SetTarget(v string) {\n\to.Target = v\n}\n\n// GetCpu returns the Cpu field value\nfunc (o *Workspace) GetCpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Cpu\n}\n\n// GetCpuOk returns a tuple with the Cpu field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetCpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Cpu, true\n}\n\n// SetCpu sets field value\nfunc (o *Workspace) SetCpu(v float32) {\n\to.Cpu = v\n}\n\n// GetGpu returns the Gpu field value\nfunc (o *Workspace) GetGpu() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Gpu\n}\n\n// GetGpuOk returns a tuple with the Gpu field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetGpuOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Gpu, true\n}\n\n// SetGpu sets field value\nfunc (o *Workspace) SetGpu(v float32) {\n\to.Gpu = v\n}\n\n// GetMemory returns the Memory field value\nfunc (o *Workspace) GetMemory() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Memory\n}\n\n// GetMemoryOk returns a tuple with the Memory field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetMemoryOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Memory, true\n}\n\n// SetMemory sets field value\nfunc (o *Workspace) SetMemory(v float32) {\n\to.Memory = v\n}\n\n// GetDisk returns the Disk field value\nfunc (o *Workspace) GetDisk() float32 {\n\tif o == nil {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\n\treturn o.Disk\n}\n\n// GetDiskOk returns a tuple with the Disk field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetDiskOk() (*float32, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Disk, true\n}\n\n// SetDisk sets field value\nfunc (o *Workspace) SetDisk(v float32) {\n\to.Disk = v\n}\n\n// GetState returns the State field value if set, zero value otherwise.\nfunc (o *Workspace) GetState() SandboxState {\n\tif o == nil || IsNil(o.State) {\n\t\tvar ret SandboxState\n\t\treturn ret\n\t}\n\treturn *o.State\n}\n\n// GetStateOk returns a tuple with the State field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetStateOk() (*SandboxState, bool) {\n\tif o == nil || IsNil(o.State) {\n\t\treturn nil, false\n\t}\n\treturn o.State, true\n}\n\n// HasState returns a boolean if a field has been set.\nfunc (o *Workspace) HasState() bool {\n\tif o != nil && !IsNil(o.State) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetState gets a reference to the given SandboxState and assigns it to the State field.\nfunc (o *Workspace) SetState(v SandboxState) {\n\to.State = &v\n}\n\n// GetDesiredState returns the DesiredState field value if set, zero value otherwise.\nfunc (o *Workspace) GetDesiredState() SandboxDesiredState {\n\tif o == nil || IsNil(o.DesiredState) {\n\t\tvar ret SandboxDesiredState\n\t\treturn ret\n\t}\n\treturn *o.DesiredState\n}\n\n// GetDesiredStateOk returns a tuple with the DesiredState field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetDesiredStateOk() (*SandboxDesiredState, bool) {\n\tif o == nil || IsNil(o.DesiredState) {\n\t\treturn nil, false\n\t}\n\treturn o.DesiredState, true\n}\n\n// HasDesiredState returns a boolean if a field has been set.\nfunc (o *Workspace) HasDesiredState() bool {\n\tif o != nil && !IsNil(o.DesiredState) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDesiredState gets a reference to the given SandboxDesiredState and assigns it to the DesiredState field.\nfunc (o *Workspace) SetDesiredState(v SandboxDesiredState) {\n\to.DesiredState = &v\n}\n\n// GetErrorReason returns the ErrorReason field value if set, zero value otherwise.\nfunc (o *Workspace) GetErrorReason() string {\n\tif o == nil || IsNil(o.ErrorReason) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.ErrorReason\n}\n\n// GetErrorReasonOk returns a tuple with the ErrorReason field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetErrorReasonOk() (*string, bool) {\n\tif o == nil || IsNil(o.ErrorReason) {\n\t\treturn nil, false\n\t}\n\treturn o.ErrorReason, true\n}\n\n// HasErrorReason returns a boolean if a field has been set.\nfunc (o *Workspace) HasErrorReason() bool {\n\tif o != nil && !IsNil(o.ErrorReason) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetErrorReason gets a reference to the given string and assigns it to the ErrorReason field.\nfunc (o *Workspace) SetErrorReason(v string) {\n\to.ErrorReason = &v\n}\n\n// GetRecoverable returns the Recoverable field value if set, zero value otherwise.\nfunc (o *Workspace) GetRecoverable() bool {\n\tif o == nil || IsNil(o.Recoverable) {\n\t\tvar ret bool\n\t\treturn ret\n\t}\n\treturn *o.Recoverable\n}\n\n// GetRecoverableOk returns a tuple with the Recoverable field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetRecoverableOk() (*bool, bool) {\n\tif o == nil || IsNil(o.Recoverable) {\n\t\treturn nil, false\n\t}\n\treturn o.Recoverable, true\n}\n\n// HasRecoverable returns a boolean if a field has been set.\nfunc (o *Workspace) HasRecoverable() bool {\n\tif o != nil && !IsNil(o.Recoverable) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRecoverable gets a reference to the given bool and assigns it to the Recoverable field.\nfunc (o *Workspace) SetRecoverable(v bool) {\n\to.Recoverable = &v\n}\n\n// GetBackupState returns the BackupState field value if set, zero value otherwise.\nfunc (o *Workspace) GetBackupState() string {\n\tif o == nil || IsNil(o.BackupState) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.BackupState\n}\n\n// GetBackupStateOk returns a tuple with the BackupState field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetBackupStateOk() (*string, bool) {\n\tif o == nil || IsNil(o.BackupState) {\n\t\treturn nil, false\n\t}\n\treturn o.BackupState, true\n}\n\n// HasBackupState returns a boolean if a field has been set.\nfunc (o *Workspace) HasBackupState() bool {\n\tif o != nil && !IsNil(o.BackupState) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBackupState gets a reference to the given string and assigns it to the BackupState field.\nfunc (o *Workspace) SetBackupState(v string) {\n\to.BackupState = &v\n}\n\n// GetBackupCreatedAt returns the BackupCreatedAt field value if set, zero value otherwise.\nfunc (o *Workspace) GetBackupCreatedAt() string {\n\tif o == nil || IsNil(o.BackupCreatedAt) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.BackupCreatedAt\n}\n\n// GetBackupCreatedAtOk returns a tuple with the BackupCreatedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetBackupCreatedAtOk() (*string, bool) {\n\tif o == nil || IsNil(o.BackupCreatedAt) {\n\t\treturn nil, false\n\t}\n\treturn o.BackupCreatedAt, true\n}\n\n// HasBackupCreatedAt returns a boolean if a field has been set.\nfunc (o *Workspace) HasBackupCreatedAt() bool {\n\tif o != nil && !IsNil(o.BackupCreatedAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBackupCreatedAt gets a reference to the given string and assigns it to the BackupCreatedAt field.\nfunc (o *Workspace) SetBackupCreatedAt(v string) {\n\to.BackupCreatedAt = &v\n}\n\n// GetAutoStopInterval returns the AutoStopInterval field value if set, zero value otherwise.\nfunc (o *Workspace) GetAutoStopInterval() float32 {\n\tif o == nil || IsNil(o.AutoStopInterval) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.AutoStopInterval\n}\n\n// GetAutoStopIntervalOk returns a tuple with the AutoStopInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetAutoStopIntervalOk() (*float32, bool) {\n\tif o == nil || IsNil(o.AutoStopInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoStopInterval, true\n}\n\n// HasAutoStopInterval returns a boolean if a field has been set.\nfunc (o *Workspace) HasAutoStopInterval() bool {\n\tif o != nil && !IsNil(o.AutoStopInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoStopInterval gets a reference to the given float32 and assigns it to the AutoStopInterval field.\nfunc (o *Workspace) SetAutoStopInterval(v float32) {\n\to.AutoStopInterval = &v\n}\n\n// GetAutoArchiveInterval returns the AutoArchiveInterval field value if set, zero value otherwise.\nfunc (o *Workspace) GetAutoArchiveInterval() float32 {\n\tif o == nil || IsNil(o.AutoArchiveInterval) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.AutoArchiveInterval\n}\n\n// GetAutoArchiveIntervalOk returns a tuple with the AutoArchiveInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetAutoArchiveIntervalOk() (*float32, bool) {\n\tif o == nil || IsNil(o.AutoArchiveInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoArchiveInterval, true\n}\n\n// HasAutoArchiveInterval returns a boolean if a field has been set.\nfunc (o *Workspace) HasAutoArchiveInterval() bool {\n\tif o != nil && !IsNil(o.AutoArchiveInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoArchiveInterval gets a reference to the given float32 and assigns it to the AutoArchiveInterval field.\nfunc (o *Workspace) SetAutoArchiveInterval(v float32) {\n\to.AutoArchiveInterval = &v\n}\n\n// GetAutoDeleteInterval returns the AutoDeleteInterval field value if set, zero value otherwise.\nfunc (o *Workspace) GetAutoDeleteInterval() float32 {\n\tif o == nil || IsNil(o.AutoDeleteInterval) {\n\t\tvar ret float32\n\t\treturn ret\n\t}\n\treturn *o.AutoDeleteInterval\n}\n\n// GetAutoDeleteIntervalOk returns a tuple with the AutoDeleteInterval field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetAutoDeleteIntervalOk() (*float32, bool) {\n\tif o == nil || IsNil(o.AutoDeleteInterval) {\n\t\treturn nil, false\n\t}\n\treturn o.AutoDeleteInterval, true\n}\n\n// HasAutoDeleteInterval returns a boolean if a field has been set.\nfunc (o *Workspace) HasAutoDeleteInterval() bool {\n\tif o != nil && !IsNil(o.AutoDeleteInterval) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetAutoDeleteInterval gets a reference to the given float32 and assigns it to the AutoDeleteInterval field.\nfunc (o *Workspace) SetAutoDeleteInterval(v float32) {\n\to.AutoDeleteInterval = &v\n}\n\n// GetVolumes returns the Volumes field value if set, zero value otherwise.\nfunc (o *Workspace) GetVolumes() []SandboxVolume {\n\tif o == nil || IsNil(o.Volumes) {\n\t\tvar ret []SandboxVolume\n\t\treturn ret\n\t}\n\treturn o.Volumes\n}\n\n// GetVolumesOk returns a tuple with the Volumes field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetVolumesOk() ([]SandboxVolume, bool) {\n\tif o == nil || IsNil(o.Volumes) {\n\t\treturn nil, false\n\t}\n\treturn o.Volumes, true\n}\n\n// HasVolumes returns a boolean if a field has been set.\nfunc (o *Workspace) HasVolumes() bool {\n\tif o != nil && !IsNil(o.Volumes) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetVolumes gets a reference to the given []SandboxVolume and assigns it to the Volumes field.\nfunc (o *Workspace) SetVolumes(v []SandboxVolume) {\n\to.Volumes = v\n}\n\n// GetBuildInfo returns the BuildInfo field value if set, zero value otherwise.\nfunc (o *Workspace) GetBuildInfo() BuildInfo {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\tvar ret BuildInfo\n\t\treturn ret\n\t}\n\treturn *o.BuildInfo\n}\n\n// GetBuildInfoOk returns a tuple with the BuildInfo field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetBuildInfoOk() (*BuildInfo, bool) {\n\tif o == nil || IsNil(o.BuildInfo) {\n\t\treturn nil, false\n\t}\n\treturn o.BuildInfo, true\n}\n\n// HasBuildInfo returns a boolean if a field has been set.\nfunc (o *Workspace) HasBuildInfo() bool {\n\tif o != nil && !IsNil(o.BuildInfo) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetBuildInfo gets a reference to the given BuildInfo and assigns it to the BuildInfo field.\nfunc (o *Workspace) SetBuildInfo(v BuildInfo) {\n\to.BuildInfo = &v\n}\n\n// GetCreatedAt returns the CreatedAt field value if set, zero value otherwise.\nfunc (o *Workspace) GetCreatedAt() string {\n\tif o == nil || IsNil(o.CreatedAt) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.CreatedAt\n}\n\n// GetCreatedAtOk returns a tuple with the CreatedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetCreatedAtOk() (*string, bool) {\n\tif o == nil || IsNil(o.CreatedAt) {\n\t\treturn nil, false\n\t}\n\treturn o.CreatedAt, true\n}\n\n// HasCreatedAt returns a boolean if a field has been set.\nfunc (o *Workspace) HasCreatedAt() bool {\n\tif o != nil && !IsNil(o.CreatedAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetCreatedAt gets a reference to the given string and assigns it to the CreatedAt field.\nfunc (o *Workspace) SetCreatedAt(v string) {\n\to.CreatedAt = &v\n}\n\n// GetUpdatedAt returns the UpdatedAt field value if set, zero value otherwise.\nfunc (o *Workspace) GetUpdatedAt() string {\n\tif o == nil || IsNil(o.UpdatedAt) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.UpdatedAt\n}\n\n// GetUpdatedAtOk returns a tuple with the UpdatedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetUpdatedAtOk() (*string, bool) {\n\tif o == nil || IsNil(o.UpdatedAt) {\n\t\treturn nil, false\n\t}\n\treturn o.UpdatedAt, true\n}\n\n// HasUpdatedAt returns a boolean if a field has been set.\nfunc (o *Workspace) HasUpdatedAt() bool {\n\tif o != nil && !IsNil(o.UpdatedAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetUpdatedAt gets a reference to the given string and assigns it to the UpdatedAt field.\nfunc (o *Workspace) SetUpdatedAt(v string) {\n\to.UpdatedAt = &v\n}\n\n// GetClass returns the Class field value if set, zero value otherwise.\n// Deprecated\nfunc (o *Workspace) GetClass() string {\n\tif o == nil || IsNil(o.Class) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Class\n}\n\n// GetClassOk returns a tuple with the Class field value if set, nil otherwise\n// and a boolean to check if the value has been set.\n// Deprecated\nfunc (o *Workspace) GetClassOk() (*string, bool) {\n\tif o == nil || IsNil(o.Class) {\n\t\treturn nil, false\n\t}\n\treturn o.Class, true\n}\n\n// HasClass returns a boolean if a field has been set.\nfunc (o *Workspace) HasClass() bool {\n\tif o != nil && !IsNil(o.Class) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetClass gets a reference to the given string and assigns it to the Class field.\n// Deprecated\nfunc (o *Workspace) SetClass(v string) {\n\to.Class = &v\n}\n\n// GetDaemonVersion returns the DaemonVersion field value if set, zero value otherwise.\nfunc (o *Workspace) GetDaemonVersion() string {\n\tif o == nil || IsNil(o.DaemonVersion) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.DaemonVersion\n}\n\n// GetDaemonVersionOk returns a tuple with the DaemonVersion field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetDaemonVersionOk() (*string, bool) {\n\tif o == nil || IsNil(o.DaemonVersion) {\n\t\treturn nil, false\n\t}\n\treturn o.DaemonVersion, true\n}\n\n// HasDaemonVersion returns a boolean if a field has been set.\nfunc (o *Workspace) HasDaemonVersion() bool {\n\tif o != nil && !IsNil(o.DaemonVersion) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetDaemonVersion gets a reference to the given string and assigns it to the DaemonVersion field.\nfunc (o *Workspace) SetDaemonVersion(v string) {\n\to.DaemonVersion = &v\n}\n\n// GetRunnerId returns the RunnerId field value if set, zero value otherwise.\nfunc (o *Workspace) GetRunnerId() string {\n\tif o == nil || IsNil(o.RunnerId) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.RunnerId\n}\n\n// GetRunnerIdOk returns a tuple with the RunnerId field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetRunnerIdOk() (*string, bool) {\n\tif o == nil || IsNil(o.RunnerId) {\n\t\treturn nil, false\n\t}\n\treturn o.RunnerId, true\n}\n\n// HasRunnerId returns a boolean if a field has been set.\nfunc (o *Workspace) HasRunnerId() bool {\n\tif o != nil && !IsNil(o.RunnerId) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetRunnerId gets a reference to the given string and assigns it to the RunnerId field.\nfunc (o *Workspace) SetRunnerId(v string) {\n\to.RunnerId = &v\n}\n\n// GetToolboxProxyUrl returns the ToolboxProxyUrl field value\nfunc (o *Workspace) GetToolboxProxyUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.ToolboxProxyUrl\n}\n\n// GetToolboxProxyUrlOk returns a tuple with the ToolboxProxyUrl field value\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetToolboxProxyUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.ToolboxProxyUrl, true\n}\n\n// SetToolboxProxyUrl sets field value\nfunc (o *Workspace) SetToolboxProxyUrl(v string) {\n\to.ToolboxProxyUrl = v\n}\n\n// GetImage returns the Image field value if set, zero value otherwise.\nfunc (o *Workspace) GetImage() string {\n\tif o == nil || IsNil(o.Image) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.Image\n}\n\n// GetImageOk returns a tuple with the Image field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetImageOk() (*string, bool) {\n\tif o == nil || IsNil(o.Image) {\n\t\treturn nil, false\n\t}\n\treturn o.Image, true\n}\n\n// HasImage returns a boolean if a field has been set.\nfunc (o *Workspace) HasImage() bool {\n\tif o != nil && !IsNil(o.Image) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetImage gets a reference to the given string and assigns it to the Image field.\nfunc (o *Workspace) SetImage(v string) {\n\to.Image = &v\n}\n\n// GetSnapshotState returns the SnapshotState field value if set, zero value otherwise.\nfunc (o *Workspace) GetSnapshotState() string {\n\tif o == nil || IsNil(o.SnapshotState) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SnapshotState\n}\n\n// GetSnapshotStateOk returns a tuple with the SnapshotState field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetSnapshotStateOk() (*string, bool) {\n\tif o == nil || IsNil(o.SnapshotState) {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotState, true\n}\n\n// HasSnapshotState returns a boolean if a field has been set.\nfunc (o *Workspace) HasSnapshotState() bool {\n\tif o != nil && !IsNil(o.SnapshotState) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshotState gets a reference to the given string and assigns it to the SnapshotState field.\nfunc (o *Workspace) SetSnapshotState(v string) {\n\to.SnapshotState = &v\n}\n\n// GetSnapshotCreatedAt returns the SnapshotCreatedAt field value if set, zero value otherwise.\nfunc (o *Workspace) GetSnapshotCreatedAt() string {\n\tif o == nil || IsNil(o.SnapshotCreatedAt) {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\treturn *o.SnapshotCreatedAt\n}\n\n// GetSnapshotCreatedAtOk returns a tuple with the SnapshotCreatedAt field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetSnapshotCreatedAtOk() (*string, bool) {\n\tif o == nil || IsNil(o.SnapshotCreatedAt) {\n\t\treturn nil, false\n\t}\n\treturn o.SnapshotCreatedAt, true\n}\n\n// HasSnapshotCreatedAt returns a boolean if a field has been set.\nfunc (o *Workspace) HasSnapshotCreatedAt() bool {\n\tif o != nil && !IsNil(o.SnapshotCreatedAt) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetSnapshotCreatedAt gets a reference to the given string and assigns it to the SnapshotCreatedAt field.\nfunc (o *Workspace) SetSnapshotCreatedAt(v string) {\n\to.SnapshotCreatedAt = &v\n}\n\n// GetInfo returns the Info field value if set, zero value otherwise.\nfunc (o *Workspace) GetInfo() SandboxInfo {\n\tif o == nil || IsNil(o.Info) {\n\t\tvar ret SandboxInfo\n\t\treturn ret\n\t}\n\treturn *o.Info\n}\n\n// GetInfoOk returns a tuple with the Info field value if set, nil otherwise\n// and a boolean to check if the value has been set.\nfunc (o *Workspace) GetInfoOk() (*SandboxInfo, bool) {\n\tif o == nil || IsNil(o.Info) {\n\t\treturn nil, false\n\t}\n\treturn o.Info, true\n}\n\n// HasInfo returns a boolean if a field has been set.\nfunc (o *Workspace) HasInfo() bool {\n\tif o != nil && !IsNil(o.Info) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// SetInfo gets a reference to the given SandboxInfo and assigns it to the Info field.\nfunc (o *Workspace) SetInfo(v SandboxInfo) {\n\to.Info = &v\n}\n\nfunc (o Workspace) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o Workspace) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"id\"] = o.Id\n\ttoSerialize[\"organizationId\"] = o.OrganizationId\n\ttoSerialize[\"name\"] = o.Name\n\tif !IsNil(o.Snapshot) {\n\t\ttoSerialize[\"snapshot\"] = o.Snapshot\n\t}\n\ttoSerialize[\"user\"] = o.User\n\ttoSerialize[\"env\"] = o.Env\n\ttoSerialize[\"labels\"] = o.Labels\n\ttoSerialize[\"public\"] = o.Public\n\ttoSerialize[\"networkBlockAll\"] = o.NetworkBlockAll\n\tif !IsNil(o.NetworkAllowList) {\n\t\ttoSerialize[\"networkAllowList\"] = o.NetworkAllowList\n\t}\n\ttoSerialize[\"target\"] = o.Target\n\ttoSerialize[\"cpu\"] = o.Cpu\n\ttoSerialize[\"gpu\"] = o.Gpu\n\ttoSerialize[\"memory\"] = o.Memory\n\ttoSerialize[\"disk\"] = o.Disk\n\tif !IsNil(o.State) {\n\t\ttoSerialize[\"state\"] = o.State\n\t}\n\tif !IsNil(o.DesiredState) {\n\t\ttoSerialize[\"desiredState\"] = o.DesiredState\n\t}\n\tif !IsNil(o.ErrorReason) {\n\t\ttoSerialize[\"errorReason\"] = o.ErrorReason\n\t}\n\tif !IsNil(o.Recoverable) {\n\t\ttoSerialize[\"recoverable\"] = o.Recoverable\n\t}\n\tif !IsNil(o.BackupState) {\n\t\ttoSerialize[\"backupState\"] = o.BackupState\n\t}\n\tif !IsNil(o.BackupCreatedAt) {\n\t\ttoSerialize[\"backupCreatedAt\"] = o.BackupCreatedAt\n\t}\n\tif !IsNil(o.AutoStopInterval) {\n\t\ttoSerialize[\"autoStopInterval\"] = o.AutoStopInterval\n\t}\n\tif !IsNil(o.AutoArchiveInterval) {\n\t\ttoSerialize[\"autoArchiveInterval\"] = o.AutoArchiveInterval\n\t}\n\tif !IsNil(o.AutoDeleteInterval) {\n\t\ttoSerialize[\"autoDeleteInterval\"] = o.AutoDeleteInterval\n\t}\n\tif !IsNil(o.Volumes) {\n\t\ttoSerialize[\"volumes\"] = o.Volumes\n\t}\n\tif !IsNil(o.BuildInfo) {\n\t\ttoSerialize[\"buildInfo\"] = o.BuildInfo\n\t}\n\tif !IsNil(o.CreatedAt) {\n\t\ttoSerialize[\"createdAt\"] = o.CreatedAt\n\t}\n\tif !IsNil(o.UpdatedAt) {\n\t\ttoSerialize[\"updatedAt\"] = o.UpdatedAt\n\t}\n\tif !IsNil(o.Class) {\n\t\ttoSerialize[\"class\"] = o.Class\n\t}\n\tif !IsNil(o.DaemonVersion) {\n\t\ttoSerialize[\"daemonVersion\"] = o.DaemonVersion\n\t}\n\tif !IsNil(o.RunnerId) {\n\t\ttoSerialize[\"runnerId\"] = o.RunnerId\n\t}\n\ttoSerialize[\"toolboxProxyUrl\"] = o.ToolboxProxyUrl\n\tif !IsNil(o.Image) {\n\t\ttoSerialize[\"image\"] = o.Image\n\t}\n\tif !IsNil(o.SnapshotState) {\n\t\ttoSerialize[\"snapshotState\"] = o.SnapshotState\n\t}\n\tif !IsNil(o.SnapshotCreatedAt) {\n\t\ttoSerialize[\"snapshotCreatedAt\"] = o.SnapshotCreatedAt\n\t}\n\tif !IsNil(o.Info) {\n\t\ttoSerialize[\"info\"] = o.Info\n\t}\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *Workspace) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"id\",\n\t\t\"organizationId\",\n\t\t\"name\",\n\t\t\"user\",\n\t\t\"env\",\n\t\t\"labels\",\n\t\t\"public\",\n\t\t\"networkBlockAll\",\n\t\t\"target\",\n\t\t\"cpu\",\n\t\t\"gpu\",\n\t\t\"memory\",\n\t\t\"disk\",\n\t\t\"toolboxProxyUrl\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarWorkspace := _Workspace{}\n\n\terr = json.Unmarshal(data, &varWorkspace)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = Workspace(varWorkspace)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"id\")\n\t\tdelete(additionalProperties, \"organizationId\")\n\t\tdelete(additionalProperties, \"name\")\n\t\tdelete(additionalProperties, \"snapshot\")\n\t\tdelete(additionalProperties, \"user\")\n\t\tdelete(additionalProperties, \"env\")\n\t\tdelete(additionalProperties, \"labels\")\n\t\tdelete(additionalProperties, \"public\")\n\t\tdelete(additionalProperties, \"networkBlockAll\")\n\t\tdelete(additionalProperties, \"networkAllowList\")\n\t\tdelete(additionalProperties, \"target\")\n\t\tdelete(additionalProperties, \"cpu\")\n\t\tdelete(additionalProperties, \"gpu\")\n\t\tdelete(additionalProperties, \"memory\")\n\t\tdelete(additionalProperties, \"disk\")\n\t\tdelete(additionalProperties, \"state\")\n\t\tdelete(additionalProperties, \"desiredState\")\n\t\tdelete(additionalProperties, \"errorReason\")\n\t\tdelete(additionalProperties, \"recoverable\")\n\t\tdelete(additionalProperties, \"backupState\")\n\t\tdelete(additionalProperties, \"backupCreatedAt\")\n\t\tdelete(additionalProperties, \"autoStopInterval\")\n\t\tdelete(additionalProperties, \"autoArchiveInterval\")\n\t\tdelete(additionalProperties, \"autoDeleteInterval\")\n\t\tdelete(additionalProperties, \"volumes\")\n\t\tdelete(additionalProperties, \"buildInfo\")\n\t\tdelete(additionalProperties, \"createdAt\")\n\t\tdelete(additionalProperties, \"updatedAt\")\n\t\tdelete(additionalProperties, \"class\")\n\t\tdelete(additionalProperties, \"daemonVersion\")\n\t\tdelete(additionalProperties, \"runnerId\")\n\t\tdelete(additionalProperties, \"toolboxProxyUrl\")\n\t\tdelete(additionalProperties, \"image\")\n\t\tdelete(additionalProperties, \"snapshotState\")\n\t\tdelete(additionalProperties, \"snapshotCreatedAt\")\n\t\tdelete(additionalProperties, \"info\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableWorkspace struct {\n\tvalue *Workspace\n\tisSet bool\n}\n\nfunc (v NullableWorkspace) Get() *Workspace {\n\treturn v.value\n}\n\nfunc (v *NullableWorkspace) Set(val *Workspace) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableWorkspace) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableWorkspace) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableWorkspace(val *Workspace) *NullableWorkspace {\n\treturn &NullableWorkspace{value: val, isSet: true}\n}\n\nfunc (v NullableWorkspace) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableWorkspace) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/model_workspace_port_preview_url.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// checks if the WorkspacePortPreviewUrl type satisfies the MappedNullable interface at compile time\nvar _ MappedNullable = &WorkspacePortPreviewUrl{}\n\n// WorkspacePortPreviewUrl struct for WorkspacePortPreviewUrl\ntype WorkspacePortPreviewUrl struct {\n\t// Preview url\n\tUrl string `json:\"url\"`\n\t// Access token\n\tToken string `json:\"token\"`\n\tAdditionalProperties map[string]interface{}\n}\n\ntype _WorkspacePortPreviewUrl WorkspacePortPreviewUrl\n\n// NewWorkspacePortPreviewUrl instantiates a new WorkspacePortPreviewUrl object\n// This constructor will assign default values to properties that have it defined,\n// and makes sure properties required by API are set, but the set of arguments\n// will change when the set of required properties is changed\nfunc NewWorkspacePortPreviewUrl(url string, token string) *WorkspacePortPreviewUrl {\n\tthis := WorkspacePortPreviewUrl{}\n\tthis.Url = url\n\tthis.Token = token\n\treturn &this\n}\n\n// NewWorkspacePortPreviewUrlWithDefaults instantiates a new WorkspacePortPreviewUrl object\n// This constructor will only assign default values to properties that have it defined,\n// but it doesn't guarantee that properties required by API are set\nfunc NewWorkspacePortPreviewUrlWithDefaults() *WorkspacePortPreviewUrl {\n\tthis := WorkspacePortPreviewUrl{}\n\treturn &this\n}\n\n// GetUrl returns the Url field value\nfunc (o *WorkspacePortPreviewUrl) GetUrl() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Url\n}\n\n// GetUrlOk returns a tuple with the Url field value\n// and a boolean to check if the value has been set.\nfunc (o *WorkspacePortPreviewUrl) GetUrlOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Url, true\n}\n\n// SetUrl sets field value\nfunc (o *WorkspacePortPreviewUrl) SetUrl(v string) {\n\to.Url = v\n}\n\n// GetToken returns the Token field value\nfunc (o *WorkspacePortPreviewUrl) GetToken() string {\n\tif o == nil {\n\t\tvar ret string\n\t\treturn ret\n\t}\n\n\treturn o.Token\n}\n\n// GetTokenOk returns a tuple with the Token field value\n// and a boolean to check if the value has been set.\nfunc (o *WorkspacePortPreviewUrl) GetTokenOk() (*string, bool) {\n\tif o == nil {\n\t\treturn nil, false\n\t}\n\treturn &o.Token, true\n}\n\n// SetToken sets field value\nfunc (o *WorkspacePortPreviewUrl) SetToken(v string) {\n\to.Token = v\n}\n\nfunc (o WorkspacePortPreviewUrl) MarshalJSON() ([]byte, error) {\n\ttoSerialize,err := o.ToMap()\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn json.Marshal(toSerialize)\n}\n\nfunc (o WorkspacePortPreviewUrl) ToMap() (map[string]interface{}, error) {\n\ttoSerialize := map[string]interface{}{}\n\ttoSerialize[\"url\"] = o.Url\n\ttoSerialize[\"token\"] = o.Token\n\n\tfor key, value := range o.AdditionalProperties {\n\t\ttoSerialize[key] = value\n\t}\n\n\treturn toSerialize, nil\n}\n\nfunc (o *WorkspacePortPreviewUrl) UnmarshalJSON(data []byte) (err error) {\n\t// This validates that all required properties are included in the JSON object\n\t// by unmarshalling the object into a generic map with string keys and checking\n\t// that every required field exists as a key in the generic map.\n\trequiredProperties := []string{\n\t\t\"url\",\n\t\t\"token\",\n\t}\n\n\tallProperties := make(map[string]interface{})\n\n\terr = json.Unmarshal(data, &allProperties)\n\n\tif err != nil {\n\t\treturn err;\n\t}\n\n\tfor _, requiredProperty := range(requiredProperties) {\n\t\tif _, exists := allProperties[requiredProperty]; !exists {\n\t\t\treturn fmt.Errorf(\"no value given for required property %v\", requiredProperty)\n\t\t}\n\t}\n\n\tvarWorkspacePortPreviewUrl := _WorkspacePortPreviewUrl{}\n\n\terr = json.Unmarshal(data, &varWorkspacePortPreviewUrl)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*o = WorkspacePortPreviewUrl(varWorkspacePortPreviewUrl)\n\n\tadditionalProperties := make(map[string]interface{})\n\n\tif err = json.Unmarshal(data, &additionalProperties); err == nil {\n\t\tdelete(additionalProperties, \"url\")\n\t\tdelete(additionalProperties, \"token\")\n\t\to.AdditionalProperties = additionalProperties\n\t}\n\n\treturn err\n}\n\ntype NullableWorkspacePortPreviewUrl struct {\n\tvalue *WorkspacePortPreviewUrl\n\tisSet bool\n}\n\nfunc (v NullableWorkspacePortPreviewUrl) Get() *WorkspacePortPreviewUrl {\n\treturn v.value\n}\n\nfunc (v *NullableWorkspacePortPreviewUrl) Set(val *WorkspacePortPreviewUrl) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableWorkspacePortPreviewUrl) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableWorkspacePortPreviewUrl) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableWorkspacePortPreviewUrl(val *WorkspacePortPreviewUrl) *NullableWorkspacePortPreviewUrl {\n\treturn &NullableWorkspacePortPreviewUrl{value: val, isSet: true}\n}\n\nfunc (v NullableWorkspacePortPreviewUrl) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableWorkspacePortPreviewUrl) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n\n"
  },
  {
    "path": "libs/api-client-go/project.json",
    "content": "{\n  \"name\": \"api-client-go\",\n  \"$schema\": \"../../node_modules/nx/schemas/project-schema.json\",\n  \"projectType\": \"library\",\n  \"sourceRoot\": \"libs/api-client-go\",\n  \"tags\": [],\n  \"targets\": {\n    \"test\": {\n      \"executor\": \"@nx-go/nx-go:test\"\n    },\n    \"build\": {\n      \"executor\": \"@nx-go/nx-go:build\",\n      \"inputs\": [\"goProduction\"],\n      \"options\": {\n        \"main\": \"./{projectRoot}\",\n        \"outputPath\": \"dist/libs/api-client-go\"\n      }\n    },\n    \"lint\": {\n      \"executor\": \"@nx-go/nx-go:lint\"\n    },\n    \"generate:api-client\": {\n      \"executor\": \"nx:run-commands\",\n      \"cache\": true,\n      \"inputs\": [\"apiClient\"],\n      \"outputs\": [\n        \"{projectRoot}/*.go\",\n        \"{projectRoot}/go.mod\",\n        \"{projectRoot}/go.sum\",\n        \"{projectRoot}/api/openapi.yaml\"\n      ],\n      \"options\": {\n        \"commands\": [\n          \"rm -f {projectRoot}/*.go\",\n          \"yarn run openapi-generator-cli generate --git-repo-id=daytona/libs/api-client-go --git-user-id=daytonaio -i dist/apps/api/openapi.json -g go --additional-properties=disallowAdditionalPropertiesIfNotPresent=false,packageName=apiclient,moduleVersion=$DEFAULT_PACKAGE_VERSION,generateInterfaces=true,enumClassPrefix=true,structPrefix=true -o libs/api-client-go\"\n        ],\n        \"parallel\": false\n      },\n      \"dependsOn\": [\n        {\n          \"target\": \"openapi\",\n          \"projects\": \"api\"\n        }\n      ]\n    },\n    \"tidy\": {\n      \"executor\": \"@nx-go/nx-go:tidy\"\n    },\n    \"check-version-env\": {},\n    \"set-version\": {\n      \"executor\": \"nx:run-commands\",\n      \"cache\": true,\n      \"inputs\": [\n        \"{workspaceRoot}/apps/cli/go.mod\",\n        \"{workspaceRoot}/libs/sdk-go/go.mod\",\n        { \"env\": \"VERSION\" },\n        { \"dependentTasksOutputFiles\": \"**/*\", \"transitive\": true }\n      ],\n      \"outputs\": [\"{workspaceRoot}/apps/cli/go.mod\", \"{workspaceRoot}/libs/sdk-go/go.mod\"],\n      \"options\": {\n        \"cwd\": \"{workspaceRoot}\",\n        \"commands\": [\n          \"cd apps/cli && go mod edit -require=github.com/daytonaio/daytona/libs/api-client-go@$VERSION\",\n          \"cd libs/sdk-go && go mod edit -require=github.com/daytonaio/daytona/libs/api-client-go@$VERSION\",\n          \"cd apps/otel-collector/exporter && go mod edit -require=github.com/daytonaio/daytona/libs/api-client-go@$VERSION\"\n        ],\n        \"parallel\": false\n      },\n      \"dependsOn\": [\"check-version-env\"]\n    }\n  }\n}\n"
  },
  {
    "path": "libs/api-client-go/response.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"net/http\"\n)\n\n// APIResponse stores the API response returned by the server.\ntype APIResponse struct {\n\t*http.Response `json:\"-\"`\n\tMessage        string `json:\"message,omitempty\"`\n\t// Operation is the name of the OpenAPI operation.\n\tOperation string `json:\"operation,omitempty\"`\n\t// RequestURL is the request URL. This value is always available, even if the\n\t// embedded *http.Response is nil.\n\tRequestURL string `json:\"url,omitempty\"`\n\t// Method is the HTTP method used for the request.  This value is always\n\t// available, even if the embedded *http.Response is nil.\n\tMethod string `json:\"method,omitempty\"`\n\t// Payload holds the contents of the response body (which may be nil or empty).\n\t// This is provided here as the raw response.Body() reader will have already\n\t// been drained.\n\tPayload []byte `json:\"-\"`\n}\n\n// NewAPIResponse returns a new APIResponse object.\nfunc NewAPIResponse(r *http.Response) *APIResponse {\n\n\tresponse := &APIResponse{Response: r}\n\treturn response\n}\n\n// NewAPIResponseWithError returns a new APIResponse object with the provided error message.\nfunc NewAPIResponseWithError(errorMessage string) *APIResponse {\n\n\tresponse := &APIResponse{Message: errorMessage}\n\treturn response\n}\n"
  },
  {
    "path": "libs/api-client-go/utils.go",
    "content": "/*\nDaytona\n\nDaytona AI platform API Docs\n\nAPI version: 1.0\nContact: support@daytona.com\n*/\n\n// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.\n\npackage apiclient\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"time\"\n)\n\n// PtrBool is a helper routine that returns a pointer to given boolean value.\nfunc PtrBool(v bool) *bool { return &v }\n\n// PtrInt is a helper routine that returns a pointer to given integer value.\nfunc PtrInt(v int) *int { return &v }\n\n// PtrInt32 is a helper routine that returns a pointer to given integer value.\nfunc PtrInt32(v int32) *int32 { return &v }\n\n// PtrInt64 is a helper routine that returns a pointer to given integer value.\nfunc PtrInt64(v int64) *int64 { return &v }\n\n// PtrFloat32 is a helper routine that returns a pointer to given float value.\nfunc PtrFloat32(v float32) *float32 { return &v }\n\n// PtrFloat64 is a helper routine that returns a pointer to given float value.\nfunc PtrFloat64(v float64) *float64 { return &v }\n\n// PtrString is a helper routine that returns a pointer to given string value.\nfunc PtrString(v string) *string { return &v }\n\n// PtrTime is helper routine that returns a pointer to given Time value.\nfunc PtrTime(v time.Time) *time.Time { return &v }\n\ntype NullableBool struct {\n\tvalue *bool\n\tisSet bool\n}\n\nfunc (v NullableBool) Get() *bool {\n\treturn v.value\n}\n\nfunc (v *NullableBool) Set(val *bool) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableBool) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableBool) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableBool(val *bool) *NullableBool {\n\treturn &NullableBool{value: val, isSet: true}\n}\n\nfunc (v NullableBool) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableBool) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\ntype NullableInt struct {\n\tvalue *int\n\tisSet bool\n}\n\nfunc (v NullableInt) Get() *int {\n\treturn v.value\n}\n\nfunc (v *NullableInt) Set(val *int) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableInt) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableInt) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableInt(val *int) *NullableInt {\n\treturn &NullableInt{value: val, isSet: true}\n}\n\nfunc (v NullableInt) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableInt) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\ntype NullableInt32 struct {\n\tvalue *int32\n\tisSet bool\n}\n\nfunc (v NullableInt32) Get() *int32 {\n\treturn v.value\n}\n\nfunc (v *NullableInt32) Set(val *int32) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableInt32) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableInt32) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableInt32(val *int32) *NullableInt32 {\n\treturn &NullableInt32{value: val, isSet: true}\n}\n\nfunc (v NullableInt32) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableInt32) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\ntype NullableInt64 struct {\n\tvalue *int64\n\tisSet bool\n}\n\nfunc (v NullableInt64) Get() *int64 {\n\treturn v.value\n}\n\nfunc (v *NullableInt64) Set(val *int64) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableInt64) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableInt64) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableInt64(val *int64) *NullableInt64 {\n\treturn &NullableInt64{value: val, isSet: true}\n}\n\nfunc (v NullableInt64) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableInt64) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\ntype NullableFloat32 struct {\n\tvalue *float32\n\tisSet bool\n}\n\nfunc (v NullableFloat32) Get() *float32 {\n\treturn v.value\n}\n\nfunc (v *NullableFloat32) Set(val *float32) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableFloat32) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableFloat32) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableFloat32(val *float32) *NullableFloat32 {\n\treturn &NullableFloat32{value: val, isSet: true}\n}\n\nfunc (v NullableFloat32) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableFloat32) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\ntype NullableFloat64 struct {\n\tvalue *float64\n\tisSet bool\n}\n\nfunc (v NullableFloat64) Get() *float64 {\n\treturn v.value\n}\n\nfunc (v *NullableFloat64) Set(val *float64) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableFloat64) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableFloat64) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableFloat64(val *float64) *NullableFloat64 {\n\treturn &NullableFloat64{value: val, isSet: true}\n}\n\nfunc (v NullableFloat64) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableFloat64) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\ntype NullableString struct {\n\tvalue *string\n\tisSet bool\n}\n\nfunc (v NullableString) Get() *string {\n\treturn v.value\n}\n\nfunc (v *NullableString) Set(val *string) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableString) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableString) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableString(val *string) *NullableString {\n\treturn &NullableString{value: val, isSet: true}\n}\n\nfunc (v NullableString) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableString) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\ntype NullableTime struct {\n\tvalue *time.Time\n\tisSet bool\n}\n\nfunc (v NullableTime) Get() *time.Time {\n\treturn v.value\n}\n\nfunc (v *NullableTime) Set(val *time.Time) {\n\tv.value = val\n\tv.isSet = true\n}\n\nfunc (v NullableTime) IsSet() bool {\n\treturn v.isSet\n}\n\nfunc (v *NullableTime) Unset() {\n\tv.value = nil\n\tv.isSet = false\n}\n\nfunc NewNullableTime(val *time.Time) *NullableTime {\n\treturn &NullableTime{value: val, isSet: true}\n}\n\nfunc (v NullableTime) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(v.value)\n}\n\nfunc (v *NullableTime) UnmarshalJSON(src []byte) error {\n\tv.isSet = true\n\treturn json.Unmarshal(src, &v.value)\n}\n\n// IsNil checks if an input is nil\nfunc IsNil(i interface{}) bool {\n\tif i == nil {\n\t\treturn true\n\t}\n\tswitch reflect.TypeOf(i).Kind() {\n\tcase reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice:\n\t\treturn reflect.ValueOf(i).IsNil()\n\tcase reflect.Array:\n\t\treturn reflect.ValueOf(i).IsZero()\n\t}\n\treturn false\n}\n\ntype MappedNullable interface {\n\tToMap() (map[string]interface{}, error)\n}\n\n// A wrapper for strict JSON decoding\nfunc newStrictDecoder(data []byte) *json.Decoder {\n\tdec := json.NewDecoder(bytes.NewBuffer(data))\n\tdec.DisallowUnknownFields()\n\treturn dec\n}\n\n// Prevent trying to import \"fmt\"\nfunc reportError(format string, a ...interface{}) error {\n\treturn fmt.Errorf(format, a...)\n}"
  },
  {
    "path": "libs/api-client-python/.gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*,cover\n.hypothesis/\nvenv/\n.venv/\n.python-version\n.pytest_cache\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n#Ipython Notebook\n.ipynb_checkpoints\n"
  },
  {
    "path": "libs/api-client-python/.openapi-generator/FILES",
    "content": ".gitignore\ndaytona_api_client/__init__.py\ndaytona_api_client/api/__init__.py\ndaytona_api_client/api/admin_api.py\ndaytona_api_client/api/api_keys_api.py\ndaytona_api_client/api/audit_api.py\ndaytona_api_client/api/config_api.py\ndaytona_api_client/api/docker_registry_api.py\ndaytona_api_client/api/health_api.py\ndaytona_api_client/api/jobs_api.py\ndaytona_api_client/api/object_storage_api.py\ndaytona_api_client/api/organizations_api.py\ndaytona_api_client/api/preview_api.py\ndaytona_api_client/api/regions_api.py\ndaytona_api_client/api/runners_api.py\ndaytona_api_client/api/sandbox_api.py\ndaytona_api_client/api/snapshots_api.py\ndaytona_api_client/api/toolbox_api.py\ndaytona_api_client/api/users_api.py\ndaytona_api_client/api/volumes_api.py\ndaytona_api_client/api/webhooks_api.py\ndaytona_api_client/api/workspace_api.py\ndaytona_api_client/api_client.py\ndaytona_api_client/api_response.py\ndaytona_api_client/configuration.py\ndaytona_api_client/exceptions.py\ndaytona_api_client/models/__init__.py\ndaytona_api_client/models/account_provider.py\ndaytona_api_client/models/admin_create_runner.py\ndaytona_api_client/models/announcement.py\ndaytona_api_client/models/api_key_list.py\ndaytona_api_client/models/api_key_response.py\ndaytona_api_client/models/audit_log.py\ndaytona_api_client/models/build_info.py\ndaytona_api_client/models/command.py\ndaytona_api_client/models/completion_context.py\ndaytona_api_client/models/completion_item.py\ndaytona_api_client/models/completion_list.py\ndaytona_api_client/models/compressed_screenshot_response.py\ndaytona_api_client/models/computer_use_start_response.py\ndaytona_api_client/models/computer_use_status_response.py\ndaytona_api_client/models/computer_use_stop_response.py\ndaytona_api_client/models/create_api_key.py\ndaytona_api_client/models/create_build_info.py\ndaytona_api_client/models/create_docker_registry.py\ndaytona_api_client/models/create_linked_account.py\ndaytona_api_client/models/create_organization.py\ndaytona_api_client/models/create_organization_invitation.py\ndaytona_api_client/models/create_organization_quota.py\ndaytona_api_client/models/create_organization_role.py\ndaytona_api_client/models/create_region.py\ndaytona_api_client/models/create_region_response.py\ndaytona_api_client/models/create_runner.py\ndaytona_api_client/models/create_runner_response.py\ndaytona_api_client/models/create_sandbox.py\ndaytona_api_client/models/create_session_request.py\ndaytona_api_client/models/create_snapshot.py\ndaytona_api_client/models/create_user.py\ndaytona_api_client/models/create_volume.py\ndaytona_api_client/models/create_workspace.py\ndaytona_api_client/models/daytona_configuration.py\ndaytona_api_client/models/display_info_response.py\ndaytona_api_client/models/docker_registry.py\ndaytona_api_client/models/download_files.py\ndaytona_api_client/models/execute_request.py\ndaytona_api_client/models/execute_response.py\ndaytona_api_client/models/file_info.py\ndaytona_api_client/models/file_status.py\ndaytona_api_client/models/git_add_request.py\ndaytona_api_client/models/git_branch_request.py\ndaytona_api_client/models/git_checkout_request.py\ndaytona_api_client/models/git_clone_request.py\ndaytona_api_client/models/git_commit_info.py\ndaytona_api_client/models/git_commit_request.py\ndaytona_api_client/models/git_commit_response.py\ndaytona_api_client/models/git_delete_branch_request.py\ndaytona_api_client/models/git_repo_request.py\ndaytona_api_client/models/git_status.py\ndaytona_api_client/models/health_controller_check200_response.py\ndaytona_api_client/models/health_controller_check200_response_info_value.py\ndaytona_api_client/models/health_controller_check503_response.py\ndaytona_api_client/models/job.py\ndaytona_api_client/models/job_status.py\ndaytona_api_client/models/job_type.py\ndaytona_api_client/models/keyboard_hotkey_request.py\ndaytona_api_client/models/keyboard_press_request.py\ndaytona_api_client/models/keyboard_type_request.py\ndaytona_api_client/models/list_branch_response.py\ndaytona_api_client/models/log_entry.py\ndaytona_api_client/models/lsp_completion_params.py\ndaytona_api_client/models/lsp_document_request.py\ndaytona_api_client/models/lsp_location.py\ndaytona_api_client/models/lsp_server_request.py\ndaytona_api_client/models/lsp_symbol.py\ndaytona_api_client/models/match.py\ndaytona_api_client/models/metric_data_point.py\ndaytona_api_client/models/metric_series.py\ndaytona_api_client/models/metrics_response.py\ndaytona_api_client/models/mouse_click_request.py\ndaytona_api_client/models/mouse_click_response.py\ndaytona_api_client/models/mouse_drag_request.py\ndaytona_api_client/models/mouse_drag_response.py\ndaytona_api_client/models/mouse_move_request.py\ndaytona_api_client/models/mouse_move_response.py\ndaytona_api_client/models/mouse_position.py\ndaytona_api_client/models/mouse_scroll_request.py\ndaytona_api_client/models/mouse_scroll_response.py\ndaytona_api_client/models/oidc_config.py\ndaytona_api_client/models/organization.py\ndaytona_api_client/models/organization_invitation.py\ndaytona_api_client/models/organization_role.py\ndaytona_api_client/models/organization_sandbox_default_limited_network_egress.py\ndaytona_api_client/models/organization_suspension.py\ndaytona_api_client/models/organization_usage_overview.py\ndaytona_api_client/models/organization_user.py\ndaytona_api_client/models/otel_config.py\ndaytona_api_client/models/paginated_audit_logs.py\ndaytona_api_client/models/paginated_jobs.py\ndaytona_api_client/models/paginated_logs.py\ndaytona_api_client/models/paginated_sandboxes.py\ndaytona_api_client/models/paginated_snapshots.py\ndaytona_api_client/models/paginated_traces.py\ndaytona_api_client/models/poll_jobs_response.py\ndaytona_api_client/models/port_preview_url.py\ndaytona_api_client/models/position.py\ndaytona_api_client/models/posthog_config.py\ndaytona_api_client/models/process_errors_response.py\ndaytona_api_client/models/process_logs_response.py\ndaytona_api_client/models/process_restart_response.py\ndaytona_api_client/models/process_status_response.py\ndaytona_api_client/models/project_dir_response.py\ndaytona_api_client/models/pty_create_request.py\ndaytona_api_client/models/pty_create_response.py\ndaytona_api_client/models/pty_list_response.py\ndaytona_api_client/models/pty_resize_request.py\ndaytona_api_client/models/pty_session_info.py\ndaytona_api_client/models/range.py\ndaytona_api_client/models/rate_limit_config.py\ndaytona_api_client/models/rate_limit_entry.py\ndaytona_api_client/models/regenerate_api_key_response.py\ndaytona_api_client/models/region.py\ndaytona_api_client/models/region_quota.py\ndaytona_api_client/models/region_screenshot_response.py\ndaytona_api_client/models/region_type.py\ndaytona_api_client/models/region_usage_overview.py\ndaytona_api_client/models/registry_push_access_dto.py\ndaytona_api_client/models/replace_request.py\ndaytona_api_client/models/replace_result.py\ndaytona_api_client/models/resize_sandbox.py\ndaytona_api_client/models/runner.py\ndaytona_api_client/models/runner_full.py\ndaytona_api_client/models/runner_health_metrics.py\ndaytona_api_client/models/runner_healthcheck.py\ndaytona_api_client/models/runner_service_health.py\ndaytona_api_client/models/runner_snapshot_dto.py\ndaytona_api_client/models/runner_state.py\ndaytona_api_client/models/sandbox.py\ndaytona_api_client/models/sandbox_class.py\ndaytona_api_client/models/sandbox_desired_state.py\ndaytona_api_client/models/sandbox_info.py\ndaytona_api_client/models/sandbox_labels.py\ndaytona_api_client/models/sandbox_state.py\ndaytona_api_client/models/sandbox_volume.py\ndaytona_api_client/models/screenshot_response.py\ndaytona_api_client/models/search_files_response.py\ndaytona_api_client/models/send_webhook_dto.py\ndaytona_api_client/models/session.py\ndaytona_api_client/models/session_execute_request.py\ndaytona_api_client/models/session_execute_response.py\ndaytona_api_client/models/set_snapshot_general_status_dto.py\ndaytona_api_client/models/signed_port_preview_url.py\ndaytona_api_client/models/snapshot_dto.py\ndaytona_api_client/models/snapshot_manager_credentials.py\ndaytona_api_client/models/snapshot_state.py\ndaytona_api_client/models/ssh_access_dto.py\ndaytona_api_client/models/ssh_access_validation_dto.py\ndaytona_api_client/models/storage_access_dto.py\ndaytona_api_client/models/toolbox_proxy_url.py\ndaytona_api_client/models/trace_span.py\ndaytona_api_client/models/trace_summary.py\ndaytona_api_client/models/update_docker_registry.py\ndaytona_api_client/models/update_job_status.py\ndaytona_api_client/models/update_organization_default_region.py\ndaytona_api_client/models/update_organization_invitation.py\ndaytona_api_client/models/update_organization_member_access.py\ndaytona_api_client/models/update_organization_quota.py\ndaytona_api_client/models/update_organization_region_quota.py\ndaytona_api_client/models/update_organization_role.py\ndaytona_api_client/models/update_region.py\ndaytona_api_client/models/update_sandbox_state_dto.py\ndaytona_api_client/models/url.py\ndaytona_api_client/models/user.py\ndaytona_api_client/models/user_home_dir_response.py\ndaytona_api_client/models/user_public_key.py\ndaytona_api_client/models/volume_dto.py\ndaytona_api_client/models/volume_state.py\ndaytona_api_client/models/webhook_app_portal_access.py\ndaytona_api_client/models/webhook_controller_get_status200_response.py\ndaytona_api_client/models/webhook_event.py\ndaytona_api_client/models/webhook_initialization_status.py\ndaytona_api_client/models/windows_response.py\ndaytona_api_client/models/work_dir_response.py\ndaytona_api_client/models/workspace.py\ndaytona_api_client/models/workspace_port_preview_url.py\ndaytona_api_client/py.typed\ndaytona_api_client/rest.py\npyproject.toml\nrequirements.txt\nsetup.py\ntest-requirements.txt\ntox.ini\n"
  },
  {
    "path": "libs/api-client-python/.openapi-generator/VERSION",
    "content": "7.12.0\n"
  },
  {
    "path": "libs/api-client-python/.openapi-generator-ignore",
    "content": "# OpenAPI Generator Ignore\n# Generated by openapi-generator https://github.com/openapitools/openapi-generator\n\n# Use this file to prevent files from being overwritten by the generator.\n# The patterns follow closely to .gitignore or .dockerignore.\n\n# As an example, the C# client generator defines ApiClient.cs.\n# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:\n#ApiClient.cs\n\n# You can match any string of characters against a directory, file or extension with a single asterisk (*):\n#foo/*/qux\n# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux\n\n# You can recursively match patterns against a directory, file or extension with a double asterisk (**):\n#foo/**/qux\n# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux\n\n# You can also negate patterns with an exclamation (!).\n# For example, you can ignore all files in a docs folder with the file extension .md:\n#docs/*.md\n# Then explicitly reverse the ignore rule for a single file:\n#!docs/README.md\n\ngit_push.sh\n.travis.yml\ngo.mod\ngo.sum\ntest/*\n.gitlab-ci.yml\n.github/**\ndocs/*\nREADME.md\nsetup.cfg"
  },
  {
    "path": "libs/api-client-python/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   Copyright 2025 Daytona\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License. "
  },
  {
    "path": "libs/api-client-python/README.md",
    "content": ""
  },
  {
    "path": "libs/api-client-python/daytona_api_client/__init__.py",
    "content": "# coding: utf-8\n\n# flake8: noqa\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\n__version__ = \"0.0.0-dev\"\n\n# import apis into sdk package\nfrom daytona_api_client.api.health_api import HealthApi\nfrom daytona_api_client.api.admin_api import AdminApi\nfrom daytona_api_client.api.api_keys_api import ApiKeysApi\nfrom daytona_api_client.api.audit_api import AuditApi\nfrom daytona_api_client.api.config_api import ConfigApi\nfrom daytona_api_client.api.docker_registry_api import DockerRegistryApi\nfrom daytona_api_client.api.jobs_api import JobsApi\nfrom daytona_api_client.api.object_storage_api import ObjectStorageApi\nfrom daytona_api_client.api.organizations_api import OrganizationsApi\nfrom daytona_api_client.api.preview_api import PreviewApi\nfrom daytona_api_client.api.regions_api import RegionsApi\nfrom daytona_api_client.api.runners_api import RunnersApi\nfrom daytona_api_client.api.sandbox_api import SandboxApi\nfrom daytona_api_client.api.snapshots_api import SnapshotsApi\nfrom daytona_api_client.api.toolbox_api import ToolboxApi\nfrom daytona_api_client.api.users_api import UsersApi\nfrom daytona_api_client.api.volumes_api import VolumesApi\nfrom daytona_api_client.api.webhooks_api import WebhooksApi\nfrom daytona_api_client.api.workspace_api import WorkspaceApi\n\n# import ApiClient\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.api_client import ApiClient\nfrom daytona_api_client.configuration import Configuration\nfrom daytona_api_client.exceptions import OpenApiException\nfrom daytona_api_client.exceptions import ApiTypeError\nfrom daytona_api_client.exceptions import ApiValueError\nfrom daytona_api_client.exceptions import ApiKeyError\nfrom daytona_api_client.exceptions import ApiAttributeError\nfrom daytona_api_client.exceptions import ApiException\n\n# import models into sdk package\nfrom daytona_api_client.models.account_provider import AccountProvider\nfrom daytona_api_client.models.admin_create_runner import AdminCreateRunner\nfrom daytona_api_client.models.announcement import Announcement\nfrom daytona_api_client.models.api_key_list import ApiKeyList\nfrom daytona_api_client.models.api_key_response import ApiKeyResponse\nfrom daytona_api_client.models.audit_log import AuditLog\nfrom daytona_api_client.models.build_info import BuildInfo\nfrom daytona_api_client.models.command import Command\nfrom daytona_api_client.models.completion_context import CompletionContext\nfrom daytona_api_client.models.completion_item import CompletionItem\nfrom daytona_api_client.models.completion_list import CompletionList\nfrom daytona_api_client.models.compressed_screenshot_response import CompressedScreenshotResponse\nfrom daytona_api_client.models.computer_use_start_response import ComputerUseStartResponse\nfrom daytona_api_client.models.computer_use_status_response import ComputerUseStatusResponse\nfrom daytona_api_client.models.computer_use_stop_response import ComputerUseStopResponse\nfrom daytona_api_client.models.create_api_key import CreateApiKey\nfrom daytona_api_client.models.create_build_info import CreateBuildInfo\nfrom daytona_api_client.models.create_docker_registry import CreateDockerRegistry\nfrom daytona_api_client.models.create_linked_account import CreateLinkedAccount\nfrom daytona_api_client.models.create_organization import CreateOrganization\nfrom daytona_api_client.models.create_organization_invitation import CreateOrganizationInvitation\nfrom daytona_api_client.models.create_organization_quota import CreateOrganizationQuota\nfrom daytona_api_client.models.create_organization_role import CreateOrganizationRole\nfrom daytona_api_client.models.create_region import CreateRegion\nfrom daytona_api_client.models.create_region_response import CreateRegionResponse\nfrom daytona_api_client.models.create_runner import CreateRunner\nfrom daytona_api_client.models.create_runner_response import CreateRunnerResponse\nfrom daytona_api_client.models.create_sandbox import CreateSandbox\nfrom daytona_api_client.models.create_session_request import CreateSessionRequest\nfrom daytona_api_client.models.create_snapshot import CreateSnapshot\nfrom daytona_api_client.models.create_user import CreateUser\nfrom daytona_api_client.models.create_volume import CreateVolume\nfrom daytona_api_client.models.create_workspace import CreateWorkspace\nfrom daytona_api_client.models.daytona_configuration import DaytonaConfiguration\nfrom daytona_api_client.models.display_info_response import DisplayInfoResponse\nfrom daytona_api_client.models.docker_registry import DockerRegistry\nfrom daytona_api_client.models.download_files import DownloadFiles\nfrom daytona_api_client.models.execute_request import ExecuteRequest\nfrom daytona_api_client.models.execute_response import ExecuteResponse\nfrom daytona_api_client.models.file_info import FileInfo\nfrom daytona_api_client.models.file_status import FileStatus\nfrom daytona_api_client.models.git_add_request import GitAddRequest\nfrom daytona_api_client.models.git_branch_request import GitBranchRequest\nfrom daytona_api_client.models.git_checkout_request import GitCheckoutRequest\nfrom daytona_api_client.models.git_clone_request import GitCloneRequest\nfrom daytona_api_client.models.git_commit_info import GitCommitInfo\nfrom daytona_api_client.models.git_commit_request import GitCommitRequest\nfrom daytona_api_client.models.git_commit_response import GitCommitResponse\nfrom daytona_api_client.models.git_delete_branch_request import GitDeleteBranchRequest\nfrom daytona_api_client.models.git_repo_request import GitRepoRequest\nfrom daytona_api_client.models.git_status import GitStatus\nfrom daytona_api_client.models.health_controller_check200_response import HealthControllerCheck200Response\nfrom daytona_api_client.models.health_controller_check200_response_info_value import HealthControllerCheck200ResponseInfoValue\nfrom daytona_api_client.models.health_controller_check503_response import HealthControllerCheck503Response\nfrom daytona_api_client.models.job import Job\nfrom daytona_api_client.models.job_status import JobStatus\nfrom daytona_api_client.models.job_type import JobType\nfrom daytona_api_client.models.keyboard_hotkey_request import KeyboardHotkeyRequest\nfrom daytona_api_client.models.keyboard_press_request import KeyboardPressRequest\nfrom daytona_api_client.models.keyboard_type_request import KeyboardTypeRequest\nfrom daytona_api_client.models.list_branch_response import ListBranchResponse\nfrom daytona_api_client.models.log_entry import LogEntry\nfrom daytona_api_client.models.lsp_completion_params import LspCompletionParams\nfrom daytona_api_client.models.lsp_document_request import LspDocumentRequest\nfrom daytona_api_client.models.lsp_location import LspLocation\nfrom daytona_api_client.models.lsp_server_request import LspServerRequest\nfrom daytona_api_client.models.lsp_symbol import LspSymbol\nfrom daytona_api_client.models.match import Match\nfrom daytona_api_client.models.metric_data_point import MetricDataPoint\nfrom daytona_api_client.models.metric_series import MetricSeries\nfrom daytona_api_client.models.metrics_response import MetricsResponse\nfrom daytona_api_client.models.mouse_click_request import MouseClickRequest\nfrom daytona_api_client.models.mouse_click_response import MouseClickResponse\nfrom daytona_api_client.models.mouse_drag_request import MouseDragRequest\nfrom daytona_api_client.models.mouse_drag_response import MouseDragResponse\nfrom daytona_api_client.models.mouse_move_request import MouseMoveRequest\nfrom daytona_api_client.models.mouse_move_response import MouseMoveResponse\nfrom daytona_api_client.models.mouse_position import MousePosition\nfrom daytona_api_client.models.mouse_scroll_request import MouseScrollRequest\nfrom daytona_api_client.models.mouse_scroll_response import MouseScrollResponse\nfrom daytona_api_client.models.oidc_config import OidcConfig\nfrom daytona_api_client.models.organization import Organization\nfrom daytona_api_client.models.organization_invitation import OrganizationInvitation\nfrom daytona_api_client.models.organization_role import OrganizationRole\nfrom daytona_api_client.models.organization_sandbox_default_limited_network_egress import OrganizationSandboxDefaultLimitedNetworkEgress\nfrom daytona_api_client.models.organization_suspension import OrganizationSuspension\nfrom daytona_api_client.models.organization_usage_overview import OrganizationUsageOverview\nfrom daytona_api_client.models.organization_user import OrganizationUser\nfrom daytona_api_client.models.otel_config import OtelConfig\nfrom daytona_api_client.models.paginated_audit_logs import PaginatedAuditLogs\nfrom daytona_api_client.models.paginated_jobs import PaginatedJobs\nfrom daytona_api_client.models.paginated_logs import PaginatedLogs\nfrom daytona_api_client.models.paginated_sandboxes import PaginatedSandboxes\nfrom daytona_api_client.models.paginated_snapshots import PaginatedSnapshots\nfrom daytona_api_client.models.paginated_traces import PaginatedTraces\nfrom daytona_api_client.models.poll_jobs_response import PollJobsResponse\nfrom daytona_api_client.models.port_preview_url import PortPreviewUrl\nfrom daytona_api_client.models.position import Position\nfrom daytona_api_client.models.posthog_config import PosthogConfig\nfrom daytona_api_client.models.process_errors_response import ProcessErrorsResponse\nfrom daytona_api_client.models.process_logs_response import ProcessLogsResponse\nfrom daytona_api_client.models.process_restart_response import ProcessRestartResponse\nfrom daytona_api_client.models.process_status_response import ProcessStatusResponse\nfrom daytona_api_client.models.project_dir_response import ProjectDirResponse\nfrom daytona_api_client.models.pty_create_request import PtyCreateRequest\nfrom daytona_api_client.models.pty_create_response import PtyCreateResponse\nfrom daytona_api_client.models.pty_list_response import PtyListResponse\nfrom daytona_api_client.models.pty_resize_request import PtyResizeRequest\nfrom daytona_api_client.models.pty_session_info import PtySessionInfo\nfrom daytona_api_client.models.range import Range\nfrom daytona_api_client.models.rate_limit_config import RateLimitConfig\nfrom daytona_api_client.models.rate_limit_entry import RateLimitEntry\nfrom daytona_api_client.models.regenerate_api_key_response import RegenerateApiKeyResponse\nfrom daytona_api_client.models.region import Region\nfrom daytona_api_client.models.region_quota import RegionQuota\nfrom daytona_api_client.models.region_screenshot_response import RegionScreenshotResponse\nfrom daytona_api_client.models.region_type import RegionType\nfrom daytona_api_client.models.region_usage_overview import RegionUsageOverview\nfrom daytona_api_client.models.registry_push_access_dto import RegistryPushAccessDto\nfrom daytona_api_client.models.replace_request import ReplaceRequest\nfrom daytona_api_client.models.replace_result import ReplaceResult\nfrom daytona_api_client.models.resize_sandbox import ResizeSandbox\nfrom daytona_api_client.models.runner import Runner\nfrom daytona_api_client.models.runner_full import RunnerFull\nfrom daytona_api_client.models.runner_health_metrics import RunnerHealthMetrics\nfrom daytona_api_client.models.runner_healthcheck import RunnerHealthcheck\nfrom daytona_api_client.models.runner_service_health import RunnerServiceHealth\nfrom daytona_api_client.models.runner_snapshot_dto import RunnerSnapshotDto\nfrom daytona_api_client.models.runner_state import RunnerState\nfrom daytona_api_client.models.sandbox import Sandbox\nfrom daytona_api_client.models.sandbox_class import SandboxClass\nfrom daytona_api_client.models.sandbox_desired_state import SandboxDesiredState\nfrom daytona_api_client.models.sandbox_info import SandboxInfo\nfrom daytona_api_client.models.sandbox_labels import SandboxLabels\nfrom daytona_api_client.models.sandbox_state import SandboxState\nfrom daytona_api_client.models.sandbox_volume import SandboxVolume\nfrom daytona_api_client.models.screenshot_response import ScreenshotResponse\nfrom daytona_api_client.models.search_files_response import SearchFilesResponse\nfrom daytona_api_client.models.send_webhook_dto import SendWebhookDto\nfrom daytona_api_client.models.session import Session\nfrom daytona_api_client.models.session_execute_request import SessionExecuteRequest\nfrom daytona_api_client.models.session_execute_response import SessionExecuteResponse\nfrom daytona_api_client.models.set_snapshot_general_status_dto import SetSnapshotGeneralStatusDto\nfrom daytona_api_client.models.signed_port_preview_url import SignedPortPreviewUrl\nfrom daytona_api_client.models.snapshot_dto import SnapshotDto\nfrom daytona_api_client.models.snapshot_manager_credentials import SnapshotManagerCredentials\nfrom daytona_api_client.models.snapshot_state import SnapshotState\nfrom daytona_api_client.models.ssh_access_dto import SshAccessDto\nfrom daytona_api_client.models.ssh_access_validation_dto import SshAccessValidationDto\nfrom daytona_api_client.models.storage_access_dto import StorageAccessDto\nfrom daytona_api_client.models.toolbox_proxy_url import ToolboxProxyUrl\nfrom daytona_api_client.models.trace_span import TraceSpan\nfrom daytona_api_client.models.trace_summary import TraceSummary\nfrom daytona_api_client.models.update_docker_registry import UpdateDockerRegistry\nfrom daytona_api_client.models.update_job_status import UpdateJobStatus\nfrom daytona_api_client.models.update_organization_default_region import UpdateOrganizationDefaultRegion\nfrom daytona_api_client.models.update_organization_invitation import UpdateOrganizationInvitation\nfrom daytona_api_client.models.update_organization_member_access import UpdateOrganizationMemberAccess\nfrom daytona_api_client.models.update_organization_quota import UpdateOrganizationQuota\nfrom daytona_api_client.models.update_organization_region_quota import UpdateOrganizationRegionQuota\nfrom daytona_api_client.models.update_organization_role import UpdateOrganizationRole\nfrom daytona_api_client.models.update_region import UpdateRegion\nfrom daytona_api_client.models.update_sandbox_state_dto import UpdateSandboxStateDto\nfrom daytona_api_client.models.url import Url\nfrom daytona_api_client.models.user import User\nfrom daytona_api_client.models.user_home_dir_response import UserHomeDirResponse\nfrom daytona_api_client.models.user_public_key import UserPublicKey\nfrom daytona_api_client.models.volume_dto import VolumeDto\nfrom daytona_api_client.models.volume_state import VolumeState\nfrom daytona_api_client.models.webhook_app_portal_access import WebhookAppPortalAccess\nfrom daytona_api_client.models.webhook_controller_get_status200_response import WebhookControllerGetStatus200Response\nfrom daytona_api_client.models.webhook_event import WebhookEvent\nfrom daytona_api_client.models.webhook_initialization_status import WebhookInitializationStatus\nfrom daytona_api_client.models.windows_response import WindowsResponse\nfrom daytona_api_client.models.work_dir_response import WorkDirResponse\nfrom daytona_api_client.models.workspace import Workspace\nfrom daytona_api_client.models.workspace_port_preview_url import WorkspacePortPreviewUrl\n\n\n# --- Static __all__ generated by Mustache ---\n__all__ = [\n    \"ApiResponse\",\n    \"ApiClient\",\n    \"Configuration\",\n    \"OpenApiException\",\n    \"ApiTypeError\",\n    \"ApiValueError\",\n    \"ApiKeyError\",\n    \"ApiAttributeError\",\n    \"ApiException\",\n    \"HealthApi\",\n    \"AdminApi\",\n    \"ApiKeysApi\",\n    \"AuditApi\",\n    \"ConfigApi\",\n    \"DockerRegistryApi\",\n    \"JobsApi\",\n    \"ObjectStorageApi\",\n    \"OrganizationsApi\",\n    \"PreviewApi\",\n    \"RegionsApi\",\n    \"RunnersApi\",\n    \"SandboxApi\",\n    \"SnapshotsApi\",\n    \"ToolboxApi\",\n    \"UsersApi\",\n    \"VolumesApi\",\n    \"WebhooksApi\",\n    \"WorkspaceApi\",\n    \"AccountProvider\",\n    \"AdminCreateRunner\",\n    \"Announcement\",\n    \"ApiKeyList\",\n    \"ApiKeyResponse\",\n    \"AuditLog\",\n    \"BuildInfo\",\n    \"Command\",\n    \"CompletionContext\",\n    \"CompletionItem\",\n    \"CompletionList\",\n    \"CompressedScreenshotResponse\",\n    \"ComputerUseStartResponse\",\n    \"ComputerUseStatusResponse\",\n    \"ComputerUseStopResponse\",\n    \"CreateApiKey\",\n    \"CreateBuildInfo\",\n    \"CreateDockerRegistry\",\n    \"CreateLinkedAccount\",\n    \"CreateOrganization\",\n    \"CreateOrganizationInvitation\",\n    \"CreateOrganizationQuota\",\n    \"CreateOrganizationRole\",\n    \"CreateRegion\",\n    \"CreateRegionResponse\",\n    \"CreateRunner\",\n    \"CreateRunnerResponse\",\n    \"CreateSandbox\",\n    \"CreateSessionRequest\",\n    \"CreateSnapshot\",\n    \"CreateUser\",\n    \"CreateVolume\",\n    \"CreateWorkspace\",\n    \"DaytonaConfiguration\",\n    \"DisplayInfoResponse\",\n    \"DockerRegistry\",\n    \"DownloadFiles\",\n    \"ExecuteRequest\",\n    \"ExecuteResponse\",\n    \"FileInfo\",\n    \"FileStatus\",\n    \"GitAddRequest\",\n    \"GitBranchRequest\",\n    \"GitCheckoutRequest\",\n    \"GitCloneRequest\",\n    \"GitCommitInfo\",\n    \"GitCommitRequest\",\n    \"GitCommitResponse\",\n    \"GitDeleteBranchRequest\",\n    \"GitRepoRequest\",\n    \"GitStatus\",\n    \"HealthControllerCheck200Response\",\n    \"HealthControllerCheck200ResponseInfoValue\",\n    \"HealthControllerCheck503Response\",\n    \"Job\",\n    \"JobStatus\",\n    \"JobType\",\n    \"KeyboardHotkeyRequest\",\n    \"KeyboardPressRequest\",\n    \"KeyboardTypeRequest\",\n    \"ListBranchResponse\",\n    \"LogEntry\",\n    \"LspCompletionParams\",\n    \"LspDocumentRequest\",\n    \"LspLocation\",\n    \"LspServerRequest\",\n    \"LspSymbol\",\n    \"Match\",\n    \"MetricDataPoint\",\n    \"MetricSeries\",\n    \"MetricsResponse\",\n    \"MouseClickRequest\",\n    \"MouseClickResponse\",\n    \"MouseDragRequest\",\n    \"MouseDragResponse\",\n    \"MouseMoveRequest\",\n    \"MouseMoveResponse\",\n    \"MousePosition\",\n    \"MouseScrollRequest\",\n    \"MouseScrollResponse\",\n    \"OidcConfig\",\n    \"Organization\",\n    \"OrganizationInvitation\",\n    \"OrganizationRole\",\n    \"OrganizationSandboxDefaultLimitedNetworkEgress\",\n    \"OrganizationSuspension\",\n    \"OrganizationUsageOverview\",\n    \"OrganizationUser\",\n    \"OtelConfig\",\n    \"PaginatedAuditLogs\",\n    \"PaginatedJobs\",\n    \"PaginatedLogs\",\n    \"PaginatedSandboxes\",\n    \"PaginatedSnapshots\",\n    \"PaginatedTraces\",\n    \"PollJobsResponse\",\n    \"PortPreviewUrl\",\n    \"Position\",\n    \"PosthogConfig\",\n    \"ProcessErrorsResponse\",\n    \"ProcessLogsResponse\",\n    \"ProcessRestartResponse\",\n    \"ProcessStatusResponse\",\n    \"ProjectDirResponse\",\n    \"PtyCreateRequest\",\n    \"PtyCreateResponse\",\n    \"PtyListResponse\",\n    \"PtyResizeRequest\",\n    \"PtySessionInfo\",\n    \"Range\",\n    \"RateLimitConfig\",\n    \"RateLimitEntry\",\n    \"RegenerateApiKeyResponse\",\n    \"Region\",\n    \"RegionQuota\",\n    \"RegionScreenshotResponse\",\n    \"RegionType\",\n    \"RegionUsageOverview\",\n    \"RegistryPushAccessDto\",\n    \"ReplaceRequest\",\n    \"ReplaceResult\",\n    \"ResizeSandbox\",\n    \"Runner\",\n    \"RunnerFull\",\n    \"RunnerHealthMetrics\",\n    \"RunnerHealthcheck\",\n    \"RunnerServiceHealth\",\n    \"RunnerSnapshotDto\",\n    \"RunnerState\",\n    \"Sandbox\",\n    \"SandboxClass\",\n    \"SandboxDesiredState\",\n    \"SandboxInfo\",\n    \"SandboxLabels\",\n    \"SandboxState\",\n    \"SandboxVolume\",\n    \"ScreenshotResponse\",\n    \"SearchFilesResponse\",\n    \"SendWebhookDto\",\n    \"Session\",\n    \"SessionExecuteRequest\",\n    \"SessionExecuteResponse\",\n    \"SetSnapshotGeneralStatusDto\",\n    \"SignedPortPreviewUrl\",\n    \"SnapshotDto\",\n    \"SnapshotManagerCredentials\",\n    \"SnapshotState\",\n    \"SshAccessDto\",\n    \"SshAccessValidationDto\",\n    \"StorageAccessDto\",\n    \"ToolboxProxyUrl\",\n    \"TraceSpan\",\n    \"TraceSummary\",\n    \"UpdateDockerRegistry\",\n    \"UpdateJobStatus\",\n    \"UpdateOrganizationDefaultRegion\",\n    \"UpdateOrganizationInvitation\",\n    \"UpdateOrganizationMemberAccess\",\n    \"UpdateOrganizationQuota\",\n    \"UpdateOrganizationRegionQuota\",\n    \"UpdateOrganizationRole\",\n    \"UpdateRegion\",\n    \"UpdateSandboxStateDto\",\n    \"Url\",\n    \"User\",\n    \"UserHomeDirResponse\",\n    \"UserPublicKey\",\n    \"VolumeDto\",\n    \"VolumeState\",\n    \"WebhookAppPortalAccess\",\n    \"WebhookControllerGetStatus200Response\",\n    \"WebhookEvent\",\n    \"WebhookInitializationStatus\",\n    \"WindowsResponse\",\n    \"WorkDirResponse\",\n    \"Workspace\",\n    \"WorkspacePortPreviewUrl\",\n\n]"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/__init__.py",
    "content": "# flake8: noqa\n\n# import apis into api package\nfrom daytona_api_client.api.health_api import HealthApi\nfrom daytona_api_client.api.admin_api import AdminApi\nfrom daytona_api_client.api.api_keys_api import ApiKeysApi\nfrom daytona_api_client.api.audit_api import AuditApi\nfrom daytona_api_client.api.config_api import ConfigApi\nfrom daytona_api_client.api.docker_registry_api import DockerRegistryApi\nfrom daytona_api_client.api.jobs_api import JobsApi\nfrom daytona_api_client.api.object_storage_api import ObjectStorageApi\nfrom daytona_api_client.api.organizations_api import OrganizationsApi\nfrom daytona_api_client.api.preview_api import PreviewApi\nfrom daytona_api_client.api.regions_api import RegionsApi\nfrom daytona_api_client.api.runners_api import RunnersApi\nfrom daytona_api_client.api.sandbox_api import SandboxApi\nfrom daytona_api_client.api.snapshots_api import SnapshotsApi\nfrom daytona_api_client.api.toolbox_api import ToolboxApi\nfrom daytona_api_client.api.users_api import UsersApi\nfrom daytona_api_client.api.volumes_api import VolumesApi\nfrom daytona_api_client.api.webhooks_api import WebhooksApi\nfrom daytona_api_client.api.workspace_api import WorkspaceApi\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/admin_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictStr\nfrom typing import List, Optional\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.admin_create_runner import AdminCreateRunner\nfrom daytona_api_client.models.create_runner_response import CreateRunnerResponse\nfrom daytona_api_client.models.runner_full import RunnerFull\nfrom daytona_api_client.models.sandbox import Sandbox\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass AdminApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def admin_create_runner(\n        self,\n        admin_create_runner: AdminCreateRunner,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> CreateRunnerResponse:\n        \"\"\"Create runner\n\n\n        :param admin_create_runner: (required)\n        :type admin_create_runner: AdminCreateRunner\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_create_runner_serialize(\n            admin_create_runner=admin_create_runner,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRunnerResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def admin_create_runner_with_http_info(\n        self,\n        admin_create_runner: AdminCreateRunner,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[CreateRunnerResponse]:\n        \"\"\"Create runner\n\n\n        :param admin_create_runner: (required)\n        :type admin_create_runner: AdminCreateRunner\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_create_runner_serialize(\n            admin_create_runner=admin_create_runner,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRunnerResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def admin_create_runner_without_preload_content(\n        self,\n        admin_create_runner: AdminCreateRunner,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create runner\n\n\n        :param admin_create_runner: (required)\n        :type admin_create_runner: AdminCreateRunner\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_create_runner_serialize(\n            admin_create_runner=admin_create_runner,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRunnerResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _admin_create_runner_serialize(\n        self,\n        admin_create_runner,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if admin_create_runner is not None:\n            _body_params = admin_create_runner\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/admin/runners',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def admin_delete_runner(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete runner\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_delete_runner_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def admin_delete_runner_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete runner\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_delete_runner_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def admin_delete_runner_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete runner\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_delete_runner_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _admin_delete_runner_serialize(\n        self,\n        id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/admin/runners/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def admin_get_runner_by_id(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RunnerFull:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_get_runner_by_id_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def admin_get_runner_by_id_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RunnerFull]:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_get_runner_by_id_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def admin_get_runner_by_id_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_get_runner_by_id_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _admin_get_runner_by_id_serialize(\n        self,\n        id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/admin/runners/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def admin_list_runners(\n        self,\n        region_id: Annotated[Optional[StrictStr], Field(description=\"Filter runners by region ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[RunnerFull]:\n        \"\"\"List all runners\n\n\n        :param region_id: Filter runners by region ID\n        :type region_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_list_runners_serialize(\n            region_id=region_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[RunnerFull]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def admin_list_runners_with_http_info(\n        self,\n        region_id: Annotated[Optional[StrictStr], Field(description=\"Filter runners by region ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[RunnerFull]]:\n        \"\"\"List all runners\n\n\n        :param region_id: Filter runners by region ID\n        :type region_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_list_runners_serialize(\n            region_id=region_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[RunnerFull]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def admin_list_runners_without_preload_content(\n        self,\n        region_id: Annotated[Optional[StrictStr], Field(description=\"Filter runners by region ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all runners\n\n\n        :param region_id: Filter runners by region ID\n        :type region_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_list_runners_serialize(\n            region_id=region_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[RunnerFull]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _admin_list_runners_serialize(\n        self,\n        region_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if region_id is not None:\n            \n            _query_params.append(('regionId', region_id))\n            \n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/admin/runners',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def admin_recover_sandbox(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Recover sandbox from error state as an admin\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_recover_sandbox_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def admin_recover_sandbox_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Recover sandbox from error state as an admin\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_recover_sandbox_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def admin_recover_sandbox_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Recover sandbox from error state as an admin\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_recover_sandbox_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _admin_recover_sandbox_serialize(\n        self,\n        sandbox_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/admin/sandbox/{sandboxId}/recover',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def admin_update_runner_scheduling(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Update runner scheduling status\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_update_runner_scheduling_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def admin_update_runner_scheduling_with_http_info(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Update runner scheduling status\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_update_runner_scheduling_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def admin_update_runner_scheduling_without_preload_content(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update runner scheduling status\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._admin_update_runner_scheduling_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _admin_update_runner_scheduling_serialize(\n        self,\n        id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/admin/runners/{id}/scheduling',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/api_keys_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictStr\nfrom typing import List, Optional\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.api_key_list import ApiKeyList\nfrom daytona_api_client.models.api_key_response import ApiKeyResponse\nfrom daytona_api_client.models.create_api_key import CreateApiKey\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass ApiKeysApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def create_api_key(\n        self,\n        create_api_key: CreateApiKey,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiKeyResponse:\n        \"\"\"Create API key\n\n\n        :param create_api_key: (required)\n        :type create_api_key: CreateApiKey\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_api_key_serialize(\n            create_api_key=create_api_key,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"ApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_api_key_with_http_info(\n        self,\n        create_api_key: CreateApiKey,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ApiKeyResponse]:\n        \"\"\"Create API key\n\n\n        :param create_api_key: (required)\n        :type create_api_key: CreateApiKey\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_api_key_serialize(\n            create_api_key=create_api_key,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"ApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_api_key_without_preload_content(\n        self,\n        create_api_key: CreateApiKey,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create API key\n\n\n        :param create_api_key: (required)\n        :type create_api_key: CreateApiKey\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_api_key_serialize(\n            create_api_key=create_api_key,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"ApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_api_key_serialize(\n        self,\n        create_api_key,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_api_key is not None:\n            _body_params = create_api_key\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/api-keys',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_api_key(\n        self,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete API key\n\n\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_api_key_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_api_key_with_http_info(\n        self,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete API key\n\n\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_api_key_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_api_key_without_preload_content(\n        self,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete API key\n\n\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_api_key_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_api_key_serialize(\n        self,\n        name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if name is not None:\n            _path_params['name'] = name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/api-keys/{name}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_api_key_for_user(\n        self,\n        user_id: StrictStr,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete API key for user\n\n\n        :param user_id: (required)\n        :type user_id: str\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_api_key_for_user_serialize(\n            user_id=user_id,\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_api_key_for_user_with_http_info(\n        self,\n        user_id: StrictStr,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete API key for user\n\n\n        :param user_id: (required)\n        :type user_id: str\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_api_key_for_user_serialize(\n            user_id=user_id,\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_api_key_for_user_without_preload_content(\n        self,\n        user_id: StrictStr,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete API key for user\n\n\n        :param user_id: (required)\n        :type user_id: str\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_api_key_for_user_serialize(\n            user_id=user_id,\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_api_key_for_user_serialize(\n        self,\n        user_id,\n        name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if user_id is not None:\n            _path_params['userId'] = user_id\n        if name is not None:\n            _path_params['name'] = name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/api-keys/{userId}/{name}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_api_key(\n        self,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiKeyList:\n        \"\"\"Get API key\n\n\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_api_key_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ApiKeyList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_api_key_with_http_info(\n        self,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ApiKeyList]:\n        \"\"\"Get API key\n\n\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_api_key_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ApiKeyList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_api_key_without_preload_content(\n        self,\n        name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get API key\n\n\n        :param name: (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_api_key_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ApiKeyList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_api_key_serialize(\n        self,\n        name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if name is not None:\n            _path_params['name'] = name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/api-keys/{name}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_current_api_key(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiKeyList:\n        \"\"\"Get current API key's details\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_current_api_key_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ApiKeyList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_current_api_key_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ApiKeyList]:\n        \"\"\"Get current API key's details\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_current_api_key_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ApiKeyList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_current_api_key_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get current API key's details\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_current_api_key_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ApiKeyList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_current_api_key_serialize(\n        self,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/api-keys/current',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_api_keys(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[ApiKeyList]:\n        \"\"\"List API keys\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_api_keys_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[ApiKeyList]\",\n            '500': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_api_keys_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[ApiKeyList]]:\n        \"\"\"List API keys\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_api_keys_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[ApiKeyList]\",\n            '500': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_api_keys_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List API keys\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_api_keys_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[ApiKeyList]\",\n            '500': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_api_keys_serialize(\n        self,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/api-keys',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/audit_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom datetime import datetime\nfrom pydantic import Field, StrictStr\nfrom typing import Optional, Union\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.paginated_audit_logs import PaginatedAuditLogs\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass AuditApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def get_all_audit_logs(\n        self,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        var_from: Annotated[Optional[datetime], Field(description=\"From date (ISO 8601 format)\")] = None,\n        to: Annotated[Optional[datetime], Field(description=\"To date (ISO 8601 format)\")] = None,\n        next_token: Annotated[Optional[StrictStr], Field(description=\"Token for cursor-based pagination. When provided, takes precedence over page parameter.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PaginatedAuditLogs:\n        \"\"\"Get all audit logs\n\n\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param var_from: From date (ISO 8601 format)\n        :type var_from: datetime\n        :param to: To date (ISO 8601 format)\n        :type to: datetime\n        :param next_token: Token for cursor-based pagination. When provided, takes precedence over page parameter.\n        :type next_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_all_audit_logs_serialize(\n            page=page,\n            limit=limit,\n            var_from=var_from,\n            to=to,\n            next_token=next_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedAuditLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_all_audit_logs_with_http_info(\n        self,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        var_from: Annotated[Optional[datetime], Field(description=\"From date (ISO 8601 format)\")] = None,\n        to: Annotated[Optional[datetime], Field(description=\"To date (ISO 8601 format)\")] = None,\n        next_token: Annotated[Optional[StrictStr], Field(description=\"Token for cursor-based pagination. When provided, takes precedence over page parameter.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PaginatedAuditLogs]:\n        \"\"\"Get all audit logs\n\n\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param var_from: From date (ISO 8601 format)\n        :type var_from: datetime\n        :param to: To date (ISO 8601 format)\n        :type to: datetime\n        :param next_token: Token for cursor-based pagination. When provided, takes precedence over page parameter.\n        :type next_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_all_audit_logs_serialize(\n            page=page,\n            limit=limit,\n            var_from=var_from,\n            to=to,\n            next_token=next_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedAuditLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_all_audit_logs_without_preload_content(\n        self,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        var_from: Annotated[Optional[datetime], Field(description=\"From date (ISO 8601 format)\")] = None,\n        to: Annotated[Optional[datetime], Field(description=\"To date (ISO 8601 format)\")] = None,\n        next_token: Annotated[Optional[StrictStr], Field(description=\"Token for cursor-based pagination. When provided, takes precedence over page parameter.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get all audit logs\n\n\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param var_from: From date (ISO 8601 format)\n        :type var_from: datetime\n        :param to: To date (ISO 8601 format)\n        :type to: datetime\n        :param next_token: Token for cursor-based pagination. When provided, takes precedence over page parameter.\n        :type next_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_all_audit_logs_serialize(\n            page=page,\n            limit=limit,\n            var_from=var_from,\n            to=to,\n            next_token=next_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedAuditLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_all_audit_logs_serialize(\n        self,\n        page,\n        limit,\n        var_from,\n        to,\n        next_token,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if page is not None:\n            \n            _query_params.append(('page', page))\n            \n        if limit is not None:\n            \n            _query_params.append(('limit', limit))\n            \n        if var_from is not None:\n            if isinstance(var_from, datetime):\n                _query_params.append(\n                    (\n                        'from',\n                        var_from.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('from', var_from))\n            \n        if to is not None:\n            if isinstance(to, datetime):\n                _query_params.append(\n                    (\n                        'to',\n                        to.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('to', to))\n            \n        if next_token is not None:\n            \n            _query_params.append(('nextToken', next_token))\n            \n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/audit',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_organization_audit_logs(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        var_from: Annotated[Optional[datetime], Field(description=\"From date (ISO 8601 format)\")] = None,\n        to: Annotated[Optional[datetime], Field(description=\"To date (ISO 8601 format)\")] = None,\n        next_token: Annotated[Optional[StrictStr], Field(description=\"Token for cursor-based pagination. When provided, takes precedence over page parameter.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PaginatedAuditLogs:\n        \"\"\"Get audit logs for organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param var_from: From date (ISO 8601 format)\n        :type var_from: datetime\n        :param to: To date (ISO 8601 format)\n        :type to: datetime\n        :param next_token: Token for cursor-based pagination. When provided, takes precedence over page parameter.\n        :type next_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_audit_logs_serialize(\n            organization_id=organization_id,\n            page=page,\n            limit=limit,\n            var_from=var_from,\n            to=to,\n            next_token=next_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedAuditLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_organization_audit_logs_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        var_from: Annotated[Optional[datetime], Field(description=\"From date (ISO 8601 format)\")] = None,\n        to: Annotated[Optional[datetime], Field(description=\"To date (ISO 8601 format)\")] = None,\n        next_token: Annotated[Optional[StrictStr], Field(description=\"Token for cursor-based pagination. When provided, takes precedence over page parameter.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PaginatedAuditLogs]:\n        \"\"\"Get audit logs for organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param var_from: From date (ISO 8601 format)\n        :type var_from: datetime\n        :param to: To date (ISO 8601 format)\n        :type to: datetime\n        :param next_token: Token for cursor-based pagination. When provided, takes precedence over page parameter.\n        :type next_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_audit_logs_serialize(\n            organization_id=organization_id,\n            page=page,\n            limit=limit,\n            var_from=var_from,\n            to=to,\n            next_token=next_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedAuditLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_organization_audit_logs_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        var_from: Annotated[Optional[datetime], Field(description=\"From date (ISO 8601 format)\")] = None,\n        to: Annotated[Optional[datetime], Field(description=\"To date (ISO 8601 format)\")] = None,\n        next_token: Annotated[Optional[StrictStr], Field(description=\"Token for cursor-based pagination. When provided, takes precedence over page parameter.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get audit logs for organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param var_from: From date (ISO 8601 format)\n        :type var_from: datetime\n        :param to: To date (ISO 8601 format)\n        :type to: datetime\n        :param next_token: Token for cursor-based pagination. When provided, takes precedence over page parameter.\n        :type next_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_audit_logs_serialize(\n            organization_id=organization_id,\n            page=page,\n            limit=limit,\n            var_from=var_from,\n            to=to,\n            next_token=next_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedAuditLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_organization_audit_logs_serialize(\n        self,\n        organization_id,\n        page,\n        limit,\n        var_from,\n        to,\n        next_token,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        if page is not None:\n            \n            _query_params.append(('page', page))\n            \n        if limit is not None:\n            \n            _query_params.append(('limit', limit))\n            \n        if var_from is not None:\n            if isinstance(var_from, datetime):\n                _query_params.append(\n                    (\n                        'from',\n                        var_from.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('from', var_from))\n            \n        if to is not None:\n            if isinstance(to, datetime):\n                _query_params.append(\n                    (\n                        'to',\n                        to.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('to', to))\n            \n        if next_token is not None:\n            \n            _query_params.append(('nextToken', next_token))\n            \n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/audit/organizations/{organizationId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/config_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom daytona_api_client.models.daytona_configuration import DaytonaConfiguration\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass ConfigApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def config_controller_get_config(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> DaytonaConfiguration:\n        \"\"\"Get config\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._config_controller_get_config_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DaytonaConfiguration\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def config_controller_get_config_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[DaytonaConfiguration]:\n        \"\"\"Get config\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._config_controller_get_config_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DaytonaConfiguration\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def config_controller_get_config_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get config\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._config_controller_get_config_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DaytonaConfiguration\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _config_controller_get_config_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/config',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/docker_registry_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictStr\nfrom typing import List, Optional\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.create_docker_registry import CreateDockerRegistry\nfrom daytona_api_client.models.docker_registry import DockerRegistry\nfrom daytona_api_client.models.registry_push_access_dto import RegistryPushAccessDto\nfrom daytona_api_client.models.update_docker_registry import UpdateDockerRegistry\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass DockerRegistryApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def create_registry(\n        self,\n        create_docker_registry: CreateDockerRegistry,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> DockerRegistry:\n        \"\"\"Create registry\n\n\n        :param create_docker_registry: (required)\n        :type create_docker_registry: CreateDockerRegistry\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_registry_serialize(\n            create_docker_registry=create_docker_registry,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_registry_with_http_info(\n        self,\n        create_docker_registry: CreateDockerRegistry,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[DockerRegistry]:\n        \"\"\"Create registry\n\n\n        :param create_docker_registry: (required)\n        :type create_docker_registry: CreateDockerRegistry\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_registry_serialize(\n            create_docker_registry=create_docker_registry,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_registry_without_preload_content(\n        self,\n        create_docker_registry: CreateDockerRegistry,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create registry\n\n\n        :param create_docker_registry: (required)\n        :type create_docker_registry: CreateDockerRegistry\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_registry_serialize(\n            create_docker_registry=create_docker_registry,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_registry_serialize(\n        self,\n        create_docker_registry,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_docker_registry is not None:\n            _body_params = create_docker_registry\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/docker-registry',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_registry(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_registry_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_registry_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_registry_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/docker-registry/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_registry(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> DockerRegistry:\n        \"\"\"Get registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_registry_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[DockerRegistry]:\n        \"\"\"Get registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_registry_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_registry_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/docker-registry/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_transient_push_access(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        region_id: Annotated[Optional[StrictStr], Field(description=\"ID of the region where the snapshot will be available (defaults to organization default region)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RegistryPushAccessDto:\n        \"\"\"Get temporary registry access for pushing snapshots\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param region_id: ID of the region where the snapshot will be available (defaults to organization default region)\n        :type region_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_transient_push_access_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            region_id=region_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegistryPushAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_transient_push_access_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        region_id: Annotated[Optional[StrictStr], Field(description=\"ID of the region where the snapshot will be available (defaults to organization default region)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RegistryPushAccessDto]:\n        \"\"\"Get temporary registry access for pushing snapshots\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param region_id: ID of the region where the snapshot will be available (defaults to organization default region)\n        :type region_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_transient_push_access_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            region_id=region_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegistryPushAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_transient_push_access_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        region_id: Annotated[Optional[StrictStr], Field(description=\"ID of the region where the snapshot will be available (defaults to organization default region)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get temporary registry access for pushing snapshots\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param region_id: ID of the region where the snapshot will be available (defaults to organization default region)\n        :type region_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_transient_push_access_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            region_id=region_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegistryPushAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_transient_push_access_serialize(\n        self,\n        x_daytona_organization_id,\n        region_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if region_id is not None:\n            \n            _query_params.append(('regionId', region_id))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/docker-registry/registry-push-access',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_registries(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[DockerRegistry]:\n        \"\"\"List registries\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_registries_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[DockerRegistry]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_registries_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[DockerRegistry]]:\n        \"\"\"List registries\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_registries_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[DockerRegistry]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_registries_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List registries\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_registries_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[DockerRegistry]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_registries_serialize(\n        self,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/docker-registry',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_default_registry(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> DockerRegistry:\n        \"\"\"Set default registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_default_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_default_registry_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[DockerRegistry]:\n        \"\"\"Set default registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_default_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_default_registry_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Set default registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_default_registry_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_default_registry_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/docker-registry/{id}/set-default',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_registry(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        update_docker_registry: UpdateDockerRegistry,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> DockerRegistry:\n        \"\"\"Update registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param update_docker_registry: (required)\n        :type update_docker_registry: UpdateDockerRegistry\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_registry_serialize(\n            id=id,\n            update_docker_registry=update_docker_registry,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_registry_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        update_docker_registry: UpdateDockerRegistry,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[DockerRegistry]:\n        \"\"\"Update registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param update_docker_registry: (required)\n        :type update_docker_registry: UpdateDockerRegistry\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_registry_serialize(\n            id=id,\n            update_docker_registry=update_docker_registry,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_registry_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"ID of the docker registry\")],\n        update_docker_registry: UpdateDockerRegistry,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update registry\n\n\n        :param id: ID of the docker registry (required)\n        :type id: str\n        :param update_docker_registry: (required)\n        :type update_docker_registry: UpdateDockerRegistry\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_registry_serialize(\n            id=id,\n            update_docker_registry=update_docker_registry,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DockerRegistry\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_registry_serialize(\n        self,\n        id,\n        update_docker_registry,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if update_docker_registry is not None:\n            _body_params = update_docker_registry\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/docker-registry/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/health_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom daytona_api_client.models.health_controller_check200_response import HealthControllerCheck200Response\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass HealthApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def health_controller_check(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> HealthControllerCheck200Response:\n        \"\"\"health_controller_check\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._health_controller_check_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"HealthControllerCheck200Response\",\n            '503': \"HealthControllerCheck503Response\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def health_controller_check_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[HealthControllerCheck200Response]:\n        \"\"\"health_controller_check\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._health_controller_check_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"HealthControllerCheck200Response\",\n            '503': \"HealthControllerCheck503Response\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def health_controller_check_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"health_controller_check\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._health_controller_check_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"HealthControllerCheck200Response\",\n            '503': \"HealthControllerCheck503Response\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _health_controller_check_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/health/ready',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def health_controller_live(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"health_controller_live\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._health_controller_live_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def health_controller_live_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"health_controller_live\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._health_controller_live_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def health_controller_live_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"health_controller_live\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._health_controller_live_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _health_controller_live_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/health',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/jobs_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Optional, Union\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.job import Job\nfrom daytona_api_client.models.job_status import JobStatus\nfrom daytona_api_client.models.paginated_jobs import PaginatedJobs\nfrom daytona_api_client.models.poll_jobs_response import PollJobsResponse\nfrom daytona_api_client.models.update_job_status import UpdateJobStatus\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass JobsApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def get_job(\n        self,\n        job_id: Annotated[StrictStr, Field(description=\"ID of the job\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Job:\n        \"\"\"Get job details\n\n\n        :param job_id: ID of the job (required)\n        :type job_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_job_serialize(\n            job_id=job_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Job\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_job_with_http_info(\n        self,\n        job_id: Annotated[StrictStr, Field(description=\"ID of the job\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Job]:\n        \"\"\"Get job details\n\n\n        :param job_id: ID of the job (required)\n        :type job_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_job_serialize(\n            job_id=job_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Job\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_job_without_preload_content(\n        self,\n        job_id: Annotated[StrictStr, Field(description=\"ID of the job\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get job details\n\n\n        :param job_id: ID of the job (required)\n        :type job_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_job_serialize(\n            job_id=job_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Job\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_job_serialize(\n        self,\n        job_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if job_id is not None:\n            _path_params['jobId'] = job_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/jobs/{jobId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_jobs(\n        self,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Maximum number of jobs to return (default: 100, max: 500)\")] = None,\n        status: Annotated[Optional[JobStatus], Field(description=\"Filter jobs by status\")] = None,\n        offset: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of jobs to skip for pagination (default: 0)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PaginatedJobs:\n        \"\"\"List jobs for the runner\n\n        Returns a paginated list of jobs for the runner, optionally filtered by status.\n\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Maximum number of jobs to return (default: 100, max: 500)\n        :type limit: float\n        :param status: Filter jobs by status\n        :type status: JobStatus\n        :param offset: Number of jobs to skip for pagination (default: 0)\n        :type offset: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_jobs_serialize(\n            page=page,\n            limit=limit,\n            status=status,\n            offset=offset,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedJobs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_jobs_with_http_info(\n        self,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Maximum number of jobs to return (default: 100, max: 500)\")] = None,\n        status: Annotated[Optional[JobStatus], Field(description=\"Filter jobs by status\")] = None,\n        offset: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of jobs to skip for pagination (default: 0)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PaginatedJobs]:\n        \"\"\"List jobs for the runner\n\n        Returns a paginated list of jobs for the runner, optionally filtered by status.\n\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Maximum number of jobs to return (default: 100, max: 500)\n        :type limit: float\n        :param status: Filter jobs by status\n        :type status: JobStatus\n        :param offset: Number of jobs to skip for pagination (default: 0)\n        :type offset: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_jobs_serialize(\n            page=page,\n            limit=limit,\n            status=status,\n            offset=offset,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedJobs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_jobs_without_preload_content(\n        self,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Maximum number of jobs to return (default: 100, max: 500)\")] = None,\n        status: Annotated[Optional[JobStatus], Field(description=\"Filter jobs by status\")] = None,\n        offset: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of jobs to skip for pagination (default: 0)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List jobs for the runner\n\n        Returns a paginated list of jobs for the runner, optionally filtered by status.\n\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Maximum number of jobs to return (default: 100, max: 500)\n        :type limit: float\n        :param status: Filter jobs by status\n        :type status: JobStatus\n        :param offset: Number of jobs to skip for pagination (default: 0)\n        :type offset: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_jobs_serialize(\n            page=page,\n            limit=limit,\n            status=status,\n            offset=offset,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedJobs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_jobs_serialize(\n        self,\n        page,\n        limit,\n        status,\n        offset,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if page is not None:\n            \n            _query_params.append(('page', page))\n            \n        if limit is not None:\n            \n            _query_params.append(('limit', limit))\n            \n        if status is not None:\n            \n            _query_params.append(('status', status.value))\n            \n        if offset is not None:\n            \n            _query_params.append(('offset', offset))\n            \n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/jobs',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def poll_jobs(\n        self,\n        timeout: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Timeout in seconds for long polling (default: 30, max: 60)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Maximum number of jobs to return (default: 10, max: 100)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PollJobsResponse:\n        \"\"\"Long poll for jobs\n\n        Long poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n\n        :param timeout: Timeout in seconds for long polling (default: 30, max: 60)\n        :type timeout: float\n        :param limit: Maximum number of jobs to return (default: 10, max: 100)\n        :type limit: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._poll_jobs_serialize(\n            timeout=timeout,\n            limit=limit,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PollJobsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def poll_jobs_with_http_info(\n        self,\n        timeout: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Timeout in seconds for long polling (default: 30, max: 60)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Maximum number of jobs to return (default: 10, max: 100)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PollJobsResponse]:\n        \"\"\"Long poll for jobs\n\n        Long poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n\n        :param timeout: Timeout in seconds for long polling (default: 30, max: 60)\n        :type timeout: float\n        :param limit: Maximum number of jobs to return (default: 10, max: 100)\n        :type limit: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._poll_jobs_serialize(\n            timeout=timeout,\n            limit=limit,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PollJobsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def poll_jobs_without_preload_content(\n        self,\n        timeout: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Timeout in seconds for long polling (default: 30, max: 60)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Maximum number of jobs to return (default: 10, max: 100)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Long poll for jobs\n\n        Long poll endpoint for runners to fetch pending jobs. Returns immediately if jobs are available, otherwise waits up to timeout seconds.\n\n        :param timeout: Timeout in seconds for long polling (default: 30, max: 60)\n        :type timeout: float\n        :param limit: Maximum number of jobs to return (default: 10, max: 100)\n        :type limit: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._poll_jobs_serialize(\n            timeout=timeout,\n            limit=limit,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PollJobsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _poll_jobs_serialize(\n        self,\n        timeout,\n        limit,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if timeout is not None:\n            \n            _query_params.append(('timeout', timeout))\n            \n        if limit is not None:\n            \n            _query_params.append(('limit', limit))\n            \n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/jobs/poll',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_job_status(\n        self,\n        job_id: Annotated[StrictStr, Field(description=\"ID of the job\")],\n        update_job_status: UpdateJobStatus,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Job:\n        \"\"\"Update job status\n\n\n        :param job_id: ID of the job (required)\n        :type job_id: str\n        :param update_job_status: (required)\n        :type update_job_status: UpdateJobStatus\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_job_status_serialize(\n            job_id=job_id,\n            update_job_status=update_job_status,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Job\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_job_status_with_http_info(\n        self,\n        job_id: Annotated[StrictStr, Field(description=\"ID of the job\")],\n        update_job_status: UpdateJobStatus,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Job]:\n        \"\"\"Update job status\n\n\n        :param job_id: ID of the job (required)\n        :type job_id: str\n        :param update_job_status: (required)\n        :type update_job_status: UpdateJobStatus\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_job_status_serialize(\n            job_id=job_id,\n            update_job_status=update_job_status,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Job\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_job_status_without_preload_content(\n        self,\n        job_id: Annotated[StrictStr, Field(description=\"ID of the job\")],\n        update_job_status: UpdateJobStatus,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update job status\n\n\n        :param job_id: ID of the job (required)\n        :type job_id: str\n        :param update_job_status: (required)\n        :type update_job_status: UpdateJobStatus\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_job_status_serialize(\n            job_id=job_id,\n            update_job_status=update_job_status,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Job\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_job_status_serialize(\n        self,\n        job_id,\n        update_job_status,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if job_id is not None:\n            _path_params['jobId'] = job_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if update_job_status is not None:\n            _body_params = update_job_status\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/jobs/{jobId}/status',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/object_storage_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictStr\nfrom typing import Optional\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.storage_access_dto import StorageAccessDto\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass ObjectStorageApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def get_push_access(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> StorageAccessDto:\n        \"\"\"Get temporary storage access for pushing objects\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_push_access_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"StorageAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_push_access_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[StorageAccessDto]:\n        \"\"\"Get temporary storage access for pushing objects\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_push_access_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"StorageAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_push_access_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get temporary storage access for pushing objects\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_push_access_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"StorageAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_push_access_serialize(\n        self,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/object-storage/push-access',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/organizations_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, Dict, List, Optional, Union\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.create_organization import CreateOrganization\nfrom daytona_api_client.models.create_organization_invitation import CreateOrganizationInvitation\nfrom daytona_api_client.models.create_organization_role import CreateOrganizationRole\nfrom daytona_api_client.models.create_region import CreateRegion\nfrom daytona_api_client.models.create_region_response import CreateRegionResponse\nfrom daytona_api_client.models.organization import Organization\nfrom daytona_api_client.models.organization_invitation import OrganizationInvitation\nfrom daytona_api_client.models.organization_role import OrganizationRole\nfrom daytona_api_client.models.organization_sandbox_default_limited_network_egress import OrganizationSandboxDefaultLimitedNetworkEgress\nfrom daytona_api_client.models.organization_suspension import OrganizationSuspension\nfrom daytona_api_client.models.organization_usage_overview import OrganizationUsageOverview\nfrom daytona_api_client.models.organization_user import OrganizationUser\nfrom daytona_api_client.models.otel_config import OtelConfig\nfrom daytona_api_client.models.regenerate_api_key_response import RegenerateApiKeyResponse\nfrom daytona_api_client.models.region import Region\nfrom daytona_api_client.models.region_quota import RegionQuota\nfrom daytona_api_client.models.snapshot_manager_credentials import SnapshotManagerCredentials\nfrom daytona_api_client.models.update_organization_default_region import UpdateOrganizationDefaultRegion\nfrom daytona_api_client.models.update_organization_invitation import UpdateOrganizationInvitation\nfrom daytona_api_client.models.update_organization_member_access import UpdateOrganizationMemberAccess\nfrom daytona_api_client.models.update_organization_quota import UpdateOrganizationQuota\nfrom daytona_api_client.models.update_organization_region_quota import UpdateOrganizationRegionQuota\nfrom daytona_api_client.models.update_organization_role import UpdateOrganizationRole\nfrom daytona_api_client.models.update_region import UpdateRegion\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass OrganizationsApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def accept_organization_invitation(\n        self,\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> OrganizationInvitation:\n        \"\"\"Accept organization invitation\n\n\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._accept_organization_invitation_serialize(\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def accept_organization_invitation_with_http_info(\n        self,\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[OrganizationInvitation]:\n        \"\"\"Accept organization invitation\n\n\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._accept_organization_invitation_serialize(\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def accept_organization_invitation_without_preload_content(\n        self,\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Accept organization invitation\n\n\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._accept_organization_invitation_serialize(\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _accept_organization_invitation_serialize(\n        self,\n        invitation_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if invitation_id is not None:\n            _path_params['invitationId'] = invitation_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/invitations/{invitationId}/accept',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def cancel_organization_invitation(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Cancel organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._cancel_organization_invitation_serialize(\n            organization_id=organization_id,\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def cancel_organization_invitation_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Cancel organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._cancel_organization_invitation_serialize(\n            organization_id=organization_id,\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def cancel_organization_invitation_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Cancel organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._cancel_organization_invitation_serialize(\n            organization_id=organization_id,\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _cancel_organization_invitation_serialize(\n        self,\n        organization_id,\n        invitation_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        if invitation_id is not None:\n            _path_params['invitationId'] = invitation_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/{organizationId}/invitations/{invitationId}/cancel',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_organization(\n        self,\n        create_organization: CreateOrganization,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Organization:\n        \"\"\"Create organization\n\n\n        :param create_organization: (required)\n        :type create_organization: CreateOrganization\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_serialize(\n            create_organization=create_organization,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_organization_with_http_info(\n        self,\n        create_organization: CreateOrganization,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Organization]:\n        \"\"\"Create organization\n\n\n        :param create_organization: (required)\n        :type create_organization: CreateOrganization\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_serialize(\n            create_organization=create_organization,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_organization_without_preload_content(\n        self,\n        create_organization: CreateOrganization,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create organization\n\n\n        :param create_organization: (required)\n        :type create_organization: CreateOrganization\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_serialize(\n            create_organization=create_organization,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_organization_serialize(\n        self,\n        create_organization,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if create_organization is not None:\n            _body_params = create_organization\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_organization_invitation(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        create_organization_invitation: CreateOrganizationInvitation,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> OrganizationInvitation:\n        \"\"\"Create organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param create_organization_invitation: (required)\n        :type create_organization_invitation: CreateOrganizationInvitation\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_invitation_serialize(\n            organization_id=organization_id,\n            create_organization_invitation=create_organization_invitation,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_organization_invitation_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        create_organization_invitation: CreateOrganizationInvitation,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[OrganizationInvitation]:\n        \"\"\"Create organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param create_organization_invitation: (required)\n        :type create_organization_invitation: CreateOrganizationInvitation\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_invitation_serialize(\n            organization_id=organization_id,\n            create_organization_invitation=create_organization_invitation,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_organization_invitation_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        create_organization_invitation: CreateOrganizationInvitation,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param create_organization_invitation: (required)\n        :type create_organization_invitation: CreateOrganizationInvitation\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_invitation_serialize(\n            organization_id=organization_id,\n            create_organization_invitation=create_organization_invitation,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_organization_invitation_serialize(\n        self,\n        organization_id,\n        create_organization_invitation,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if create_organization_invitation is not None:\n            _body_params = create_organization_invitation\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/{organizationId}/invitations',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_organization_role(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        create_organization_role: CreateOrganizationRole,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> OrganizationRole:\n        \"\"\"Create organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param create_organization_role: (required)\n        :type create_organization_role: CreateOrganizationRole\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_role_serialize(\n            organization_id=organization_id,\n            create_organization_role=create_organization_role,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"OrganizationRole\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_organization_role_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        create_organization_role: CreateOrganizationRole,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[OrganizationRole]:\n        \"\"\"Create organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param create_organization_role: (required)\n        :type create_organization_role: CreateOrganizationRole\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_role_serialize(\n            organization_id=organization_id,\n            create_organization_role=create_organization_role,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"OrganizationRole\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_organization_role_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        create_organization_role: CreateOrganizationRole,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param create_organization_role: (required)\n        :type create_organization_role: CreateOrganizationRole\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_organization_role_serialize(\n            organization_id=organization_id,\n            create_organization_role=create_organization_role,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"OrganizationRole\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_organization_role_serialize(\n        self,\n        organization_id,\n        create_organization_role,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if create_organization_role is not None:\n            _body_params = create_organization_role\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/{organizationId}/roles',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_region(\n        self,\n        create_region: CreateRegion,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> CreateRegionResponse:\n        \"\"\"Create a new region\n\n\n        :param create_region: (required)\n        :type create_region: CreateRegion\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_region_serialize(\n            create_region=create_region,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRegionResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_region_with_http_info(\n        self,\n        create_region: CreateRegion,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[CreateRegionResponse]:\n        \"\"\"Create a new region\n\n\n        :param create_region: (required)\n        :type create_region: CreateRegion\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_region_serialize(\n            create_region=create_region,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRegionResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_region_without_preload_content(\n        self,\n        create_region: CreateRegion,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create a new region\n\n\n        :param create_region: (required)\n        :type create_region: CreateRegion\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_region_serialize(\n            create_region=create_region,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRegionResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_region_serialize(\n        self,\n        create_region,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_region is not None:\n            _body_params = create_region\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/regions',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def decline_organization_invitation(\n        self,\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Decline organization invitation\n\n\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._decline_organization_invitation_serialize(\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def decline_organization_invitation_with_http_info(\n        self,\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Decline organization invitation\n\n\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._decline_organization_invitation_serialize(\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def decline_organization_invitation_without_preload_content(\n        self,\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Decline organization invitation\n\n\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._decline_organization_invitation_serialize(\n            invitation_id=invitation_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _decline_organization_invitation_serialize(\n        self,\n        invitation_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if invitation_id is not None:\n            _path_params['invitationId'] = invitation_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/invitations/{invitationId}/decline',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_organization(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_organization_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_organization_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_organization_serialize(\n        self,\n        organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/organizations/{organizationId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_organization_member(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        user_id: Annotated[StrictStr, Field(description=\"User ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete organization member\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param user_id: User ID (required)\n        :type user_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_member_serialize(\n            organization_id=organization_id,\n            user_id=user_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_organization_member_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        user_id: Annotated[StrictStr, Field(description=\"User ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete organization member\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param user_id: User ID (required)\n        :type user_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_member_serialize(\n            organization_id=organization_id,\n            user_id=user_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_organization_member_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        user_id: Annotated[StrictStr, Field(description=\"User ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete organization member\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param user_id: User ID (required)\n        :type user_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_member_serialize(\n            organization_id=organization_id,\n            user_id=user_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_organization_member_serialize(\n        self,\n        organization_id,\n        user_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        if user_id is not None:\n            _path_params['userId'] = user_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/organizations/{organizationId}/users/{userId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_organization_role(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        role_id: Annotated[StrictStr, Field(description=\"Role ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param role_id: Role ID (required)\n        :type role_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_role_serialize(\n            organization_id=organization_id,\n            role_id=role_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_organization_role_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        role_id: Annotated[StrictStr, Field(description=\"Role ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param role_id: Role ID (required)\n        :type role_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_role_serialize(\n            organization_id=organization_id,\n            role_id=role_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_organization_role_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        role_id: Annotated[StrictStr, Field(description=\"Role ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param role_id: Role ID (required)\n        :type role_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_organization_role_serialize(\n            organization_id=organization_id,\n            role_id=role_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_organization_role_serialize(\n        self,\n        organization_id,\n        role_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        if role_id is not None:\n            _path_params['roleId'] = role_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/organizations/{organizationId}/roles/{roleId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_region(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_region_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_region_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_region_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_region_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_region_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_region_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/regions/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_organization(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Organization:\n        \"\"\"Get organization by ID\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_organization_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Organization]:\n        \"\"\"Get organization by ID\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_organization_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get organization by ID\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_organization_serialize(\n        self,\n        organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/{organizationId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_organization_by_sandbox_id(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"Sandbox ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Organization:\n        \"\"\"Get organization by sandbox ID\n\n\n        :param sandbox_id: Sandbox ID (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_organization_by_sandbox_id_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"Sandbox ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Organization]:\n        \"\"\"Get organization by sandbox ID\n\n\n        :param sandbox_id: Sandbox ID (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_organization_by_sandbox_id_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"Sandbox ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get organization by sandbox ID\n\n\n        :param sandbox_id: Sandbox ID (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Organization\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_organization_by_sandbox_id_serialize(\n        self,\n        sandbox_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/by-sandbox-id/{sandboxId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_organization_invitations_count_for_authenticated_user(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> float:\n        \"\"\"Get count of organization invitations for authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_invitations_count_for_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"float\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_organization_invitations_count_for_authenticated_user_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[float]:\n        \"\"\"Get count of organization invitations for authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_invitations_count_for_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"float\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_organization_invitations_count_for_authenticated_user_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get count of organization invitations for authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_invitations_count_for_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"float\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_organization_invitations_count_for_authenticated_user_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/invitations/count',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_organization_otel_config_by_sandbox_auth_token(\n        self,\n        auth_token: Annotated[StrictStr, Field(description=\"Sandbox Auth Token\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> OtelConfig:\n        \"\"\"Get organization OTEL config by sandbox auth token\n\n\n        :param auth_token: Sandbox Auth Token (required)\n        :type auth_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_otel_config_by_sandbox_auth_token_serialize(\n            auth_token=auth_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OtelConfig\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_organization_otel_config_by_sandbox_auth_token_with_http_info(\n        self,\n        auth_token: Annotated[StrictStr, Field(description=\"Sandbox Auth Token\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[OtelConfig]:\n        \"\"\"Get organization OTEL config by sandbox auth token\n\n\n        :param auth_token: Sandbox Auth Token (required)\n        :type auth_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_otel_config_by_sandbox_auth_token_serialize(\n            auth_token=auth_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OtelConfig\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_organization_otel_config_by_sandbox_auth_token_without_preload_content(\n        self,\n        auth_token: Annotated[StrictStr, Field(description=\"Sandbox Auth Token\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get organization OTEL config by sandbox auth token\n\n\n        :param auth_token: Sandbox Auth Token (required)\n        :type auth_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_otel_config_by_sandbox_auth_token_serialize(\n            auth_token=auth_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OtelConfig\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_organization_otel_config_by_sandbox_auth_token_serialize(\n        self,\n        auth_token,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if auth_token is not None:\n            _path_params['authToken'] = auth_token\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/otel-config/by-sandbox-auth-token/{authToken}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_organization_usage_overview(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> OrganizationUsageOverview:\n        \"\"\"Get organization current usage overview\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_usage_overview_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationUsageOverview\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_organization_usage_overview_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[OrganizationUsageOverview]:\n        \"\"\"Get organization current usage overview\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_usage_overview_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationUsageOverview\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_organization_usage_overview_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get organization current usage overview\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_organization_usage_overview_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationUsageOverview\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_organization_usage_overview_serialize(\n        self,\n        organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/{organizationId}/usage',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_region_by_id(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Region:\n        \"\"\"Get region by ID\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_region_by_id_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Region\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_region_by_id_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Region]:\n        \"\"\"Get region by ID\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_region_by_id_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Region\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_region_by_id_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get region by ID\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_region_by_id_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Region\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_region_by_id_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/regions/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_region_quota_by_sandbox_id(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"Sandbox ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RegionQuota:\n        \"\"\"Get region quota by sandbox ID\n\n\n        :param sandbox_id: Sandbox ID (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_region_quota_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegionQuota\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_region_quota_by_sandbox_id_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"Sandbox ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RegionQuota]:\n        \"\"\"Get region quota by sandbox ID\n\n\n        :param sandbox_id: Sandbox ID (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_region_quota_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegionQuota\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_region_quota_by_sandbox_id_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"Sandbox ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get region quota by sandbox ID\n\n\n        :param sandbox_id: Sandbox ID (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_region_quota_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegionQuota\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_region_quota_by_sandbox_id_serialize(\n        self,\n        sandbox_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/region-quota/by-sandbox-id/{sandboxId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def leave_organization(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Leave organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._leave_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def leave_organization_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Leave organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._leave_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def leave_organization_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Leave organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._leave_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _leave_organization_serialize(\n        self,\n        organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/{organizationId}/leave',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_available_regions(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Region]:\n        \"\"\"List all available regions for the organization\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_available_regions_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Region]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_available_regions_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Region]]:\n        \"\"\"List all available regions for the organization\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_available_regions_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Region]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_available_regions_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all available regions for the organization\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_available_regions_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Region]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_available_regions_serialize(\n        self,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/regions',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_organization_invitations(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[OrganizationInvitation]:\n        \"\"\"List pending organization invitations\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_invitations_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationInvitation]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_organization_invitations_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[OrganizationInvitation]]:\n        \"\"\"List pending organization invitations\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_invitations_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationInvitation]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_organization_invitations_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List pending organization invitations\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_invitations_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationInvitation]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_organization_invitations_serialize(\n        self,\n        organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/{organizationId}/invitations',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_organization_invitations_for_authenticated_user(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[OrganizationInvitation]:\n        \"\"\"List organization invitations for authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_invitations_for_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationInvitation]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_organization_invitations_for_authenticated_user_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[OrganizationInvitation]]:\n        \"\"\"List organization invitations for authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_invitations_for_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationInvitation]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_organization_invitations_for_authenticated_user_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List organization invitations for authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_invitations_for_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationInvitation]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_organization_invitations_for_authenticated_user_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/invitations',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_organization_members(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[OrganizationUser]:\n        \"\"\"List organization members\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_members_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationUser]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_organization_members_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[OrganizationUser]]:\n        \"\"\"List organization members\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_members_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationUser]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_organization_members_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List organization members\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_members_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationUser]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_organization_members_serialize(\n        self,\n        organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/{organizationId}/users',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_organization_roles(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[OrganizationRole]:\n        \"\"\"List organization roles\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_roles_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationRole]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_organization_roles_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[OrganizationRole]]:\n        \"\"\"List organization roles\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_roles_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationRole]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_organization_roles_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List organization roles\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organization_roles_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[OrganizationRole]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_organization_roles_serialize(\n        self,\n        organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations/{organizationId}/roles',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_organizations(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Organization]:\n        \"\"\"List organizations\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organizations_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Organization]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_organizations_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Organization]]:\n        \"\"\"List organizations\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organizations_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Organization]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_organizations_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List organizations\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_organizations_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Organization]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_organizations_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/organizations',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def regenerate_proxy_api_key(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RegenerateApiKeyResponse:\n        \"\"\"Regenerate proxy API key for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_proxy_api_key_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegenerateApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def regenerate_proxy_api_key_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RegenerateApiKeyResponse]:\n        \"\"\"Regenerate proxy API key for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_proxy_api_key_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegenerateApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def regenerate_proxy_api_key_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Regenerate proxy API key for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_proxy_api_key_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegenerateApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _regenerate_proxy_api_key_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/regions/{id}/regenerate-proxy-api-key',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def regenerate_snapshot_manager_credentials(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SnapshotManagerCredentials:\n        \"\"\"Regenerate snapshot manager credentials for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_snapshot_manager_credentials_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotManagerCredentials\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def regenerate_snapshot_manager_credentials_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SnapshotManagerCredentials]:\n        \"\"\"Regenerate snapshot manager credentials for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_snapshot_manager_credentials_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotManagerCredentials\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def regenerate_snapshot_manager_credentials_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Regenerate snapshot manager credentials for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_snapshot_manager_credentials_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotManagerCredentials\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _regenerate_snapshot_manager_credentials_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/regions/{id}/regenerate-snapshot-manager-credentials',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def regenerate_ssh_gateway_api_key(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RegenerateApiKeyResponse:\n        \"\"\"Regenerate SSH gateway API key for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_ssh_gateway_api_key_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegenerateApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def regenerate_ssh_gateway_api_key_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RegenerateApiKeyResponse]:\n        \"\"\"Regenerate SSH gateway API key for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_ssh_gateway_api_key_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegenerateApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def regenerate_ssh_gateway_api_key_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Regenerate SSH gateway API key for a region\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_ssh_gateway_api_key_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegenerateApiKeyResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _regenerate_ssh_gateway_api_key_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/regions/{id}/regenerate-ssh-gateway-api-key',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_organization_default_region(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        update_organization_default_region: UpdateOrganizationDefaultRegion,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Set default region for organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param update_organization_default_region: (required)\n        :type update_organization_default_region: UpdateOrganizationDefaultRegion\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_organization_default_region_serialize(\n            organization_id=organization_id,\n            update_organization_default_region=update_organization_default_region,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_organization_default_region_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        update_organization_default_region: UpdateOrganizationDefaultRegion,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Set default region for organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param update_organization_default_region: (required)\n        :type update_organization_default_region: UpdateOrganizationDefaultRegion\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_organization_default_region_serialize(\n            organization_id=organization_id,\n            update_organization_default_region=update_organization_default_region,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_organization_default_region_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        update_organization_default_region: UpdateOrganizationDefaultRegion,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Set default region for organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param update_organization_default_region: (required)\n        :type update_organization_default_region: UpdateOrganizationDefaultRegion\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_organization_default_region_serialize(\n            organization_id=organization_id,\n            update_organization_default_region=update_organization_default_region,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_organization_default_region_serialize(\n        self,\n        organization_id,\n        update_organization_default_region,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if update_organization_default_region is not None:\n            _body_params = update_organization_default_region\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/organizations/{organizationId}/default-region',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def suspend_organization(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        organization_suspension: Optional[OrganizationSuspension] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Suspend organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param organization_suspension:\n        :type organization_suspension: OrganizationSuspension\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._suspend_organization_serialize(\n            organization_id=organization_id,\n            organization_suspension=organization_suspension,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def suspend_organization_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        organization_suspension: Optional[OrganizationSuspension] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Suspend organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param organization_suspension:\n        :type organization_suspension: OrganizationSuspension\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._suspend_organization_serialize(\n            organization_id=organization_id,\n            organization_suspension=organization_suspension,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def suspend_organization_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        organization_suspension: Optional[OrganizationSuspension] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Suspend organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param organization_suspension:\n        :type organization_suspension: OrganizationSuspension\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._suspend_organization_serialize(\n            organization_id=organization_id,\n            organization_suspension=organization_suspension,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _suspend_organization_serialize(\n        self,\n        organization_id,\n        organization_suspension,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if organization_suspension is not None:\n            _body_params = organization_suspension\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/{organizationId}/suspend',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def unsuspend_organization(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Unsuspend organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._unsuspend_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def unsuspend_organization_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Unsuspend organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._unsuspend_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def unsuspend_organization_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Unsuspend organization\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._unsuspend_organization_serialize(\n            organization_id=organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _unsuspend_organization_serialize(\n        self,\n        organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/{organizationId}/unsuspend',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_access_for_organization_member(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        user_id: Annotated[StrictStr, Field(description=\"User ID\")],\n        update_organization_member_access: UpdateOrganizationMemberAccess,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> OrganizationUser:\n        \"\"\"Update access for organization member\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param user_id: User ID (required)\n        :type user_id: str\n        :param update_organization_member_access: (required)\n        :type update_organization_member_access: UpdateOrganizationMemberAccess\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_access_for_organization_member_serialize(\n            organization_id=organization_id,\n            user_id=user_id,\n            update_organization_member_access=update_organization_member_access,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationUser\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_access_for_organization_member_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        user_id: Annotated[StrictStr, Field(description=\"User ID\")],\n        update_organization_member_access: UpdateOrganizationMemberAccess,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[OrganizationUser]:\n        \"\"\"Update access for organization member\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param user_id: User ID (required)\n        :type user_id: str\n        :param update_organization_member_access: (required)\n        :type update_organization_member_access: UpdateOrganizationMemberAccess\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_access_for_organization_member_serialize(\n            organization_id=organization_id,\n            user_id=user_id,\n            update_organization_member_access=update_organization_member_access,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationUser\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_access_for_organization_member_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        user_id: Annotated[StrictStr, Field(description=\"User ID\")],\n        update_organization_member_access: UpdateOrganizationMemberAccess,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update access for organization member\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param user_id: User ID (required)\n        :type user_id: str\n        :param update_organization_member_access: (required)\n        :type update_organization_member_access: UpdateOrganizationMemberAccess\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_access_for_organization_member_serialize(\n            organization_id=organization_id,\n            user_id=user_id,\n            update_organization_member_access=update_organization_member_access,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationUser\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_access_for_organization_member_serialize(\n        self,\n        organization_id,\n        user_id,\n        update_organization_member_access,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        if user_id is not None:\n            _path_params['userId'] = user_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if update_organization_member_access is not None:\n            _body_params = update_organization_member_access\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/{organizationId}/users/{userId}/access',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_experimental_config(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        request_body: Annotated[Optional[Dict[str, Any]], Field(description=\"Experimental configuration as a JSON object. Set to null to clear the configuration.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Update experimental configuration\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param request_body: Experimental configuration as a JSON object. Set to null to clear the configuration.\n        :type request_body: Dict[str, object]\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_experimental_config_serialize(\n            organization_id=organization_id,\n            request_body=request_body,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_experimental_config_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        request_body: Annotated[Optional[Dict[str, Any]], Field(description=\"Experimental configuration as a JSON object. Set to null to clear the configuration.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Update experimental configuration\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param request_body: Experimental configuration as a JSON object. Set to null to clear the configuration.\n        :type request_body: Dict[str, object]\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_experimental_config_serialize(\n            organization_id=organization_id,\n            request_body=request_body,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_experimental_config_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        request_body: Annotated[Optional[Dict[str, Any]], Field(description=\"Experimental configuration as a JSON object. Set to null to clear the configuration.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update experimental configuration\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param request_body: Experimental configuration as a JSON object. Set to null to clear the configuration.\n        :type request_body: Dict[str, object]\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_experimental_config_serialize(\n            organization_id=organization_id,\n            request_body=request_body,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_experimental_config_serialize(\n        self,\n        organization_id,\n        request_body,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if request_body is not None:\n            _body_params = request_body\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PUT',\n            resource_path='/organizations/{organizationId}/experimental-config',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_organization_invitation(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        update_organization_invitation: UpdateOrganizationInvitation,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> OrganizationInvitation:\n        \"\"\"Update organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param update_organization_invitation: (required)\n        :type update_organization_invitation: UpdateOrganizationInvitation\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_invitation_serialize(\n            organization_id=organization_id,\n            invitation_id=invitation_id,\n            update_organization_invitation=update_organization_invitation,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_organization_invitation_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        update_organization_invitation: UpdateOrganizationInvitation,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[OrganizationInvitation]:\n        \"\"\"Update organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param update_organization_invitation: (required)\n        :type update_organization_invitation: UpdateOrganizationInvitation\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_invitation_serialize(\n            organization_id=organization_id,\n            invitation_id=invitation_id,\n            update_organization_invitation=update_organization_invitation,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_organization_invitation_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        invitation_id: Annotated[StrictStr, Field(description=\"Invitation ID\")],\n        update_organization_invitation: UpdateOrganizationInvitation,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update organization invitation\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param invitation_id: Invitation ID (required)\n        :type invitation_id: str\n        :param update_organization_invitation: (required)\n        :type update_organization_invitation: UpdateOrganizationInvitation\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_invitation_serialize(\n            organization_id=organization_id,\n            invitation_id=invitation_id,\n            update_organization_invitation=update_organization_invitation,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationInvitation\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_organization_invitation_serialize(\n        self,\n        organization_id,\n        invitation_id,\n        update_organization_invitation,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        if invitation_id is not None:\n            _path_params['invitationId'] = invitation_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if update_organization_invitation is not None:\n            _body_params = update_organization_invitation\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PUT',\n            resource_path='/organizations/{organizationId}/invitations/{invitationId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_organization_quota(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        update_organization_quota: UpdateOrganizationQuota,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Update organization quota\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param update_organization_quota: (required)\n        :type update_organization_quota: UpdateOrganizationQuota\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_quota_serialize(\n            organization_id=organization_id,\n            update_organization_quota=update_organization_quota,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_organization_quota_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        update_organization_quota: UpdateOrganizationQuota,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Update organization quota\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param update_organization_quota: (required)\n        :type update_organization_quota: UpdateOrganizationQuota\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_quota_serialize(\n            organization_id=organization_id,\n            update_organization_quota=update_organization_quota,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_organization_quota_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        update_organization_quota: UpdateOrganizationQuota,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update organization quota\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param update_organization_quota: (required)\n        :type update_organization_quota: UpdateOrganizationQuota\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_quota_serialize(\n            organization_id=organization_id,\n            update_organization_quota=update_organization_quota,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_organization_quota_serialize(\n        self,\n        organization_id,\n        update_organization_quota,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if update_organization_quota is not None:\n            _body_params = update_organization_quota\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/organizations/{organizationId}/quota',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_organization_region_quota(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        region_id: Annotated[StrictStr, Field(description=\"ID of the region where the updated quota will be applied\")],\n        update_organization_region_quota: UpdateOrganizationRegionQuota,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Update organization region quota\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param region_id: ID of the region where the updated quota will be applied (required)\n        :type region_id: str\n        :param update_organization_region_quota: (required)\n        :type update_organization_region_quota: UpdateOrganizationRegionQuota\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_region_quota_serialize(\n            organization_id=organization_id,\n            region_id=region_id,\n            update_organization_region_quota=update_organization_region_quota,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_organization_region_quota_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        region_id: Annotated[StrictStr, Field(description=\"ID of the region where the updated quota will be applied\")],\n        update_organization_region_quota: UpdateOrganizationRegionQuota,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Update organization region quota\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param region_id: ID of the region where the updated quota will be applied (required)\n        :type region_id: str\n        :param update_organization_region_quota: (required)\n        :type update_organization_region_quota: UpdateOrganizationRegionQuota\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_region_quota_serialize(\n            organization_id=organization_id,\n            region_id=region_id,\n            update_organization_region_quota=update_organization_region_quota,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_organization_region_quota_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        region_id: Annotated[StrictStr, Field(description=\"ID of the region where the updated quota will be applied\")],\n        update_organization_region_quota: UpdateOrganizationRegionQuota,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update organization region quota\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param region_id: ID of the region where the updated quota will be applied (required)\n        :type region_id: str\n        :param update_organization_region_quota: (required)\n        :type update_organization_region_quota: UpdateOrganizationRegionQuota\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_region_quota_serialize(\n            organization_id=organization_id,\n            region_id=region_id,\n            update_organization_region_quota=update_organization_region_quota,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_organization_region_quota_serialize(\n        self,\n        organization_id,\n        region_id,\n        update_organization_region_quota,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        if region_id is not None:\n            _path_params['regionId'] = region_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if update_organization_region_quota is not None:\n            _body_params = update_organization_region_quota\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/organizations/{organizationId}/quota/{regionId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_organization_role(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        role_id: Annotated[StrictStr, Field(description=\"Role ID\")],\n        update_organization_role: UpdateOrganizationRole,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> OrganizationRole:\n        \"\"\"Update organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param role_id: Role ID (required)\n        :type role_id: str\n        :param update_organization_role: (required)\n        :type update_organization_role: UpdateOrganizationRole\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_role_serialize(\n            organization_id=organization_id,\n            role_id=role_id,\n            update_organization_role=update_organization_role,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationRole\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_organization_role_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        role_id: Annotated[StrictStr, Field(description=\"Role ID\")],\n        update_organization_role: UpdateOrganizationRole,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[OrganizationRole]:\n        \"\"\"Update organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param role_id: Role ID (required)\n        :type role_id: str\n        :param update_organization_role: (required)\n        :type update_organization_role: UpdateOrganizationRole\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_role_serialize(\n            organization_id=organization_id,\n            role_id=role_id,\n            update_organization_role=update_organization_role,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationRole\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_organization_role_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        role_id: Annotated[StrictStr, Field(description=\"Role ID\")],\n        update_organization_role: UpdateOrganizationRole,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update organization role\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param role_id: Role ID (required)\n        :type role_id: str\n        :param update_organization_role: (required)\n        :type update_organization_role: UpdateOrganizationRole\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_organization_role_serialize(\n            organization_id=organization_id,\n            role_id=role_id,\n            update_organization_role=update_organization_role,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"OrganizationRole\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_organization_role_serialize(\n        self,\n        organization_id,\n        role_id,\n        update_organization_role,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        if role_id is not None:\n            _path_params['roleId'] = role_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if update_organization_role is not None:\n            _body_params = update_organization_role\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PUT',\n            resource_path='/organizations/{organizationId}/roles/{roleId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_region(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        update_region: UpdateRegion,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Update region configuration\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param update_region: (required)\n        :type update_region: UpdateRegion\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_region_serialize(\n            id=id,\n            update_region=update_region,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_region_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        update_region: UpdateRegion,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Update region configuration\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param update_region: (required)\n        :type update_region: UpdateRegion\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_region_serialize(\n            id=id,\n            update_region=update_region,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_region_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Region ID\")],\n        update_region: UpdateRegion,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update region configuration\n\n\n        :param id: Region ID (required)\n        :type id: str\n        :param update_region: (required)\n        :type update_region: UpdateRegion\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_region_serialize(\n            id=id,\n            update_region=update_region,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_region_serialize(\n        self,\n        id,\n        update_region,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if update_region is not None:\n            _body_params = update_region\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/regions/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_sandbox_default_limited_network_egress(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        organization_sandbox_default_limited_network_egress: OrganizationSandboxDefaultLimitedNetworkEgress,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Update sandbox default limited network egress\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param organization_sandbox_default_limited_network_egress: (required)\n        :type organization_sandbox_default_limited_network_egress: OrganizationSandboxDefaultLimitedNetworkEgress\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_sandbox_default_limited_network_egress_serialize(\n            organization_id=organization_id,\n            organization_sandbox_default_limited_network_egress=organization_sandbox_default_limited_network_egress,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_sandbox_default_limited_network_egress_with_http_info(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        organization_sandbox_default_limited_network_egress: OrganizationSandboxDefaultLimitedNetworkEgress,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Update sandbox default limited network egress\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param organization_sandbox_default_limited_network_egress: (required)\n        :type organization_sandbox_default_limited_network_egress: OrganizationSandboxDefaultLimitedNetworkEgress\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_sandbox_default_limited_network_egress_serialize(\n            organization_id=organization_id,\n            organization_sandbox_default_limited_network_egress=organization_sandbox_default_limited_network_egress,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_sandbox_default_limited_network_egress_without_preload_content(\n        self,\n        organization_id: Annotated[StrictStr, Field(description=\"Organization ID\")],\n        organization_sandbox_default_limited_network_egress: OrganizationSandboxDefaultLimitedNetworkEgress,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update sandbox default limited network egress\n\n\n        :param organization_id: Organization ID (required)\n        :type organization_id: str\n        :param organization_sandbox_default_limited_network_egress: (required)\n        :type organization_sandbox_default_limited_network_egress: OrganizationSandboxDefaultLimitedNetworkEgress\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_sandbox_default_limited_network_egress_serialize(\n            organization_id=organization_id,\n            organization_sandbox_default_limited_network_egress=organization_sandbox_default_limited_network_egress,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_sandbox_default_limited_network_egress_serialize(\n        self,\n        organization_id,\n        organization_sandbox_default_limited_network_egress,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if organization_sandbox_default_limited_network_egress is not None:\n            _body_params = organization_sandbox_default_limited_network_egress\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/organizations/{organizationId}/sandbox-default-limited-network-egress',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/preview_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictBool, StrictFloat, StrictInt, StrictStr\nfrom typing import Union\nfrom typing_extensions import Annotated\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass PreviewApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def get_sandbox_id_from_signed_preview_url_token(\n        self,\n        signed_preview_token: Annotated[StrictStr, Field(description=\"Signed preview URL token\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get sandbox ID from signed preview URL token\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> str:\n        \"\"\"Get sandbox ID from signed preview URL token\n\n\n        :param signed_preview_token: Signed preview URL token (required)\n        :type signed_preview_token: str\n        :param port: Port number to get sandbox ID from signed preview URL token (required)\n        :type port: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_id_from_signed_preview_url_token_serialize(\n            signed_preview_token=signed_preview_token,\n            port=port,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_sandbox_id_from_signed_preview_url_token_with_http_info(\n        self,\n        signed_preview_token: Annotated[StrictStr, Field(description=\"Signed preview URL token\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get sandbox ID from signed preview URL token\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[str]:\n        \"\"\"Get sandbox ID from signed preview URL token\n\n\n        :param signed_preview_token: Signed preview URL token (required)\n        :type signed_preview_token: str\n        :param port: Port number to get sandbox ID from signed preview URL token (required)\n        :type port: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_id_from_signed_preview_url_token_serialize(\n            signed_preview_token=signed_preview_token,\n            port=port,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_sandbox_id_from_signed_preview_url_token_without_preload_content(\n        self,\n        signed_preview_token: Annotated[StrictStr, Field(description=\"Signed preview URL token\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get sandbox ID from signed preview URL token\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get sandbox ID from signed preview URL token\n\n\n        :param signed_preview_token: Signed preview URL token (required)\n        :type signed_preview_token: str\n        :param port: Port number to get sandbox ID from signed preview URL token (required)\n        :type port: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_id_from_signed_preview_url_token_serialize(\n            signed_preview_token=signed_preview_token,\n            port=port,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_sandbox_id_from_signed_preview_url_token_serialize(\n        self,\n        signed_preview_token,\n        port,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if signed_preview_token is not None:\n            _path_params['signedPreviewToken'] = signed_preview_token\n        if port is not None:\n            _path_params['port'] = port\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/preview/{signedPreviewToken}/{port}/sandbox-id',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def has_sandbox_access(\n        self,\n        sandbox_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> bool:\n        \"\"\"Check if user has access to the sandbox\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._has_sandbox_access_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def has_sandbox_access_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[bool]:\n        \"\"\"Check if user has access to the sandbox\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._has_sandbox_access_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def has_sandbox_access_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Check if user has access to the sandbox\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._has_sandbox_access_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _has_sandbox_access_serialize(\n        self,\n        sandbox_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/preview/{sandboxId}/access',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def is_sandbox_public(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> bool:\n        \"\"\"Check if sandbox is public\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._is_sandbox_public_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def is_sandbox_public_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[bool]:\n        \"\"\"Check if sandbox is public\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._is_sandbox_public_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def is_sandbox_public_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Check if sandbox is public\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._is_sandbox_public_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _is_sandbox_public_serialize(\n        self,\n        sandbox_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/preview/{sandboxId}/public',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def is_valid_auth_token(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        auth_token: Annotated[StrictStr, Field(description=\"Auth token of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> bool:\n        \"\"\"Check if sandbox auth token is valid\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param auth_token: Auth token of the sandbox (required)\n        :type auth_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._is_valid_auth_token_serialize(\n            sandbox_id=sandbox_id,\n            auth_token=auth_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def is_valid_auth_token_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        auth_token: Annotated[StrictStr, Field(description=\"Auth token of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[bool]:\n        \"\"\"Check if sandbox auth token is valid\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param auth_token: Auth token of the sandbox (required)\n        :type auth_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._is_valid_auth_token_serialize(\n            sandbox_id=sandbox_id,\n            auth_token=auth_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def is_valid_auth_token_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        auth_token: Annotated[StrictStr, Field(description=\"Auth token of the sandbox\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Check if sandbox auth token is valid\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param auth_token: Auth token of the sandbox (required)\n        :type auth_token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._is_valid_auth_token_serialize(\n            sandbox_id=sandbox_id,\n            auth_token=auth_token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _is_valid_auth_token_serialize(\n        self,\n        sandbox_id,\n        auth_token,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if auth_token is not None:\n            _path_params['authToken'] = auth_token\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/preview/{sandboxId}/validate/{authToken}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/regions_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom typing import List\nfrom daytona_api_client.models.region import Region\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass RegionsApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def list_shared_regions(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Region]:\n        \"\"\"List all shared regions\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_shared_regions_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Region]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_shared_regions_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Region]]:\n        \"\"\"List all shared regions\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_shared_regions_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Region]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_shared_regions_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all shared regions\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_shared_regions_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Region]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_shared_regions_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/shared-regions',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/runners_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictStr\nfrom typing import List, Optional\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.create_runner import CreateRunner\nfrom daytona_api_client.models.create_runner_response import CreateRunnerResponse\nfrom daytona_api_client.models.runner import Runner\nfrom daytona_api_client.models.runner_full import RunnerFull\nfrom daytona_api_client.models.runner_healthcheck import RunnerHealthcheck\nfrom daytona_api_client.models.runner_snapshot_dto import RunnerSnapshotDto\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass RunnersApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def create_runner(\n        self,\n        create_runner: CreateRunner,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> CreateRunnerResponse:\n        \"\"\"Create runner\n\n\n        :param create_runner: (required)\n        :type create_runner: CreateRunner\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_runner_serialize(\n            create_runner=create_runner,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRunnerResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_runner_with_http_info(\n        self,\n        create_runner: CreateRunner,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[CreateRunnerResponse]:\n        \"\"\"Create runner\n\n\n        :param create_runner: (required)\n        :type create_runner: CreateRunner\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_runner_serialize(\n            create_runner=create_runner,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRunnerResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_runner_without_preload_content(\n        self,\n        create_runner: CreateRunner,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create runner\n\n\n        :param create_runner: (required)\n        :type create_runner: CreateRunner\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_runner_serialize(\n            create_runner=create_runner,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"CreateRunnerResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_runner_serialize(\n        self,\n        create_runner,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_runner is not None:\n            _body_params = create_runner\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/runners',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_runner(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete runner\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_runner_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_runner_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete runner\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_runner_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_runner_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete runner\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_runner_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_runner_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/runners/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_info_for_authenticated_runner(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RunnerFull:\n        \"\"\"Get info for authenticated runner\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_info_for_authenticated_runner_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_info_for_authenticated_runner_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RunnerFull]:\n        \"\"\"Get info for authenticated runner\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_info_for_authenticated_runner_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_info_for_authenticated_runner_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get info for authenticated runner\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_info_for_authenticated_runner_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_info_for_authenticated_runner_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/runners/me',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_runner_by_id(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Runner:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_by_id_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_runner_by_id_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Runner]:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_by_id_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_runner_by_id_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_by_id_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_runner_by_id_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/runners/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_runner_by_sandbox_id(\n        self,\n        sandbox_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RunnerFull:\n        \"\"\"Get runner by sandbox ID\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_runner_by_sandbox_id_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RunnerFull]:\n        \"\"\"Get runner by sandbox ID\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_runner_by_sandbox_id_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get runner by sandbox ID\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_by_sandbox_id_serialize(\n            sandbox_id=sandbox_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_runner_by_sandbox_id_serialize(\n        self,\n        sandbox_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/runners/by-sandbox/{sandboxId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_runner_full_by_id(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RunnerFull:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_full_by_id_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_runner_full_by_id_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RunnerFull]:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_full_by_id_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_runner_full_by_id_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get runner by ID\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runner_full_by_id_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RunnerFull\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_runner_full_by_id_serialize(\n        self,\n        id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/runners/{id}/full',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_runners_by_snapshot_ref(\n        self,\n        ref: Annotated[StrictStr, Field(description=\"Snapshot ref\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[RunnerSnapshotDto]:\n        \"\"\"Get runners by snapshot ref\n\n\n        :param ref: Snapshot ref (required)\n        :type ref: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runners_by_snapshot_ref_serialize(\n            ref=ref,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[RunnerSnapshotDto]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_runners_by_snapshot_ref_with_http_info(\n        self,\n        ref: Annotated[StrictStr, Field(description=\"Snapshot ref\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[RunnerSnapshotDto]]:\n        \"\"\"Get runners by snapshot ref\n\n\n        :param ref: Snapshot ref (required)\n        :type ref: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runners_by_snapshot_ref_serialize(\n            ref=ref,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[RunnerSnapshotDto]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_runners_by_snapshot_ref_without_preload_content(\n        self,\n        ref: Annotated[StrictStr, Field(description=\"Snapshot ref\")],\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get runners by snapshot ref\n\n\n        :param ref: Snapshot ref (required)\n        :type ref: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_runners_by_snapshot_ref_serialize(\n            ref=ref,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[RunnerSnapshotDto]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_runners_by_snapshot_ref_serialize(\n        self,\n        ref,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if ref is not None:\n            \n            _query_params.append(('ref', ref))\n            \n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/runners/by-snapshot-ref',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_runners(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Runner]:\n        \"\"\"List all runners\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_runners_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Runner]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_runners_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Runner]]:\n        \"\"\"List all runners\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_runners_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Runner]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_runners_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all runners\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_runners_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Runner]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_runners_serialize(\n        self,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/runners',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def runner_healthcheck(\n        self,\n        runner_healthcheck: RunnerHealthcheck,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Runner healthcheck\n\n        Endpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n\n        :param runner_healthcheck: (required)\n        :type runner_healthcheck: RunnerHealthcheck\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._runner_healthcheck_serialize(\n            runner_healthcheck=runner_healthcheck,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def runner_healthcheck_with_http_info(\n        self,\n        runner_healthcheck: RunnerHealthcheck,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Runner healthcheck\n\n        Endpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n\n        :param runner_healthcheck: (required)\n        :type runner_healthcheck: RunnerHealthcheck\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._runner_healthcheck_serialize(\n            runner_healthcheck=runner_healthcheck,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def runner_healthcheck_without_preload_content(\n        self,\n        runner_healthcheck: RunnerHealthcheck,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Runner healthcheck\n\n        Endpoint for version 2 runners to send healthcheck and metrics. Updates lastChecked timestamp and runner metrics.\n\n        :param runner_healthcheck: (required)\n        :type runner_healthcheck: RunnerHealthcheck\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._runner_healthcheck_serialize(\n            runner_healthcheck=runner_healthcheck,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _runner_healthcheck_serialize(\n        self,\n        runner_healthcheck,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if runner_healthcheck is not None:\n            _body_params = runner_healthcheck\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/runners/healthcheck',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_runner_draining(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Runner:\n        \"\"\"Update runner draining status\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_runner_draining_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_runner_draining_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Runner]:\n        \"\"\"Update runner draining status\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_runner_draining_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_runner_draining_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update runner draining status\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_runner_draining_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_runner_draining_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/runners/{id}/draining',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_runner_scheduling(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Runner:\n        \"\"\"Update runner scheduling status\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_runner_scheduling_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_runner_scheduling_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Runner]:\n        \"\"\"Update runner scheduling status\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_runner_scheduling_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_runner_scheduling_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Runner ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update runner scheduling status\n\n\n        :param id: Runner ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_runner_scheduling_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Runner\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_runner_scheduling_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/runners/{id}/scheduling',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/sandbox_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom datetime import datetime\nfrom pydantic import Field, StrictBool, StrictFloat, StrictInt, StrictStr, field_validator\nfrom typing import List, Optional, Union\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.create_sandbox import CreateSandbox\nfrom daytona_api_client.models.metrics_response import MetricsResponse\nfrom daytona_api_client.models.paginated_logs import PaginatedLogs\nfrom daytona_api_client.models.paginated_sandboxes import PaginatedSandboxes\nfrom daytona_api_client.models.paginated_traces import PaginatedTraces\nfrom daytona_api_client.models.port_preview_url import PortPreviewUrl\nfrom daytona_api_client.models.resize_sandbox import ResizeSandbox\nfrom daytona_api_client.models.sandbox import Sandbox\nfrom daytona_api_client.models.sandbox_labels import SandboxLabels\nfrom daytona_api_client.models.signed_port_preview_url import SignedPortPreviewUrl\nfrom daytona_api_client.models.ssh_access_dto import SshAccessDto\nfrom daytona_api_client.models.ssh_access_validation_dto import SshAccessValidationDto\nfrom daytona_api_client.models.toolbox_proxy_url import ToolboxProxyUrl\nfrom daytona_api_client.models.trace_span import TraceSpan\nfrom daytona_api_client.models.update_sandbox_state_dto import UpdateSandboxStateDto\nfrom daytona_api_client.models.url import Url\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass SandboxApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def archive_sandbox(\n        self,\n        sandbox_id_or_name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Archive sandbox\n\n\n        :param sandbox_id_or_name: (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._archive_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def archive_sandbox_with_http_info(\n        self,\n        sandbox_id_or_name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Archive sandbox\n\n\n        :param sandbox_id_or_name: (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._archive_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def archive_sandbox_without_preload_content(\n        self,\n        sandbox_id_or_name: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Archive sandbox\n\n\n        :param sandbox_id_or_name: (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._archive_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _archive_sandbox_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/archive',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_backup(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Create sandbox backup\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_backup_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_backup_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Create sandbox backup\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_backup_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_backup_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create sandbox backup\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_backup_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_backup_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/backup',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_sandbox(\n        self,\n        create_sandbox: CreateSandbox,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Create a new sandbox\n\n\n        :param create_sandbox: (required)\n        :type create_sandbox: CreateSandbox\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_sandbox_serialize(\n            create_sandbox=create_sandbox,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_sandbox_with_http_info(\n        self,\n        create_sandbox: CreateSandbox,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Create a new sandbox\n\n\n        :param create_sandbox: (required)\n        :type create_sandbox: CreateSandbox\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_sandbox_serialize(\n            create_sandbox=create_sandbox,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_sandbox_without_preload_content(\n        self,\n        create_sandbox: CreateSandbox,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create a new sandbox\n\n\n        :param create_sandbox: (required)\n        :type create_sandbox: CreateSandbox\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_sandbox_serialize(\n            create_sandbox=create_sandbox,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_sandbox_serialize(\n        self,\n        create_sandbox,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_sandbox is not None:\n            _body_params = create_sandbox\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_ssh_access(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        expires_in_minutes: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Expiration time in minutes (default: 60)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SshAccessDto:\n        \"\"\"Create SSH access for sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param expires_in_minutes: Expiration time in minutes (default: 60)\n        :type expires_in_minutes: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_ssh_access_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            expires_in_minutes=expires_in_minutes,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SshAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_ssh_access_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        expires_in_minutes: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Expiration time in minutes (default: 60)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SshAccessDto]:\n        \"\"\"Create SSH access for sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param expires_in_minutes: Expiration time in minutes (default: 60)\n        :type expires_in_minutes: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_ssh_access_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            expires_in_minutes=expires_in_minutes,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SshAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_ssh_access_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        expires_in_minutes: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Expiration time in minutes (default: 60)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create SSH access for sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param expires_in_minutes: Expiration time in minutes (default: 60)\n        :type expires_in_minutes: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_ssh_access_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            expires_in_minutes=expires_in_minutes,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SshAccessDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_ssh_access_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        expires_in_minutes,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        if expires_in_minutes is not None:\n            \n            _query_params.append(('expiresInMinutes', expires_in_minutes))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/ssh-access',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_sandbox(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Delete sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_sandbox_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Delete sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_sandbox_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_sandbox_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/sandbox/{sandboxIdOrName}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def expire_signed_port_preview_url(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[StrictInt, Field(description=\"Port number to expire signed preview URL for\")],\n        token: Annotated[StrictStr, Field(description=\"Token to expire signed preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Expire signed preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to expire signed preview URL for (required)\n        :type port: int\n        :param token: Token to expire signed preview URL for (required)\n        :type token: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._expire_signed_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            token=token,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def expire_signed_port_preview_url_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[StrictInt, Field(description=\"Port number to expire signed preview URL for\")],\n        token: Annotated[StrictStr, Field(description=\"Token to expire signed preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Expire signed preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to expire signed preview URL for (required)\n        :type port: int\n        :param token: Token to expire signed preview URL for (required)\n        :type token: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._expire_signed_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            token=token,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def expire_signed_port_preview_url_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[StrictInt, Field(description=\"Port number to expire signed preview URL for\")],\n        token: Annotated[StrictStr, Field(description=\"Token to expire signed preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Expire signed preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to expire signed preview URL for (required)\n        :type port: int\n        :param token: Token to expire signed preview URL for (required)\n        :type token: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._expire_signed_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            token=token,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _expire_signed_port_preview_url_serialize(\n        self,\n        sandbox_id_or_name,\n        port,\n        token,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        if port is not None:\n            _path_params['port'] = port\n        if token is not None:\n            _path_params['token'] = token\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url/{token}/expire',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_build_logs(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) Get build logs\n\n        This endpoint is deprecated. Use `getBuildLogsUrl` instead.\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /sandbox/{sandboxIdOrName}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_build_logs_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_build_logs_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) Get build logs\n\n        This endpoint is deprecated. Use `getBuildLogsUrl` instead.\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /sandbox/{sandboxIdOrName}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_build_logs_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_build_logs_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) Get build logs\n\n        This endpoint is deprecated. Use `getBuildLogsUrl` instead.\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /sandbox/{sandboxIdOrName}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_build_logs_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_build_logs_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        follow,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        if follow is not None:\n            \n            _query_params.append(('follow', follow))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxIdOrName}/build-logs',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_build_logs_url(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Url:\n        \"\"\"Get build logs URL\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_build_logs_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Url\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_build_logs_url_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Url]:\n        \"\"\"Get build logs URL\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_build_logs_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Url\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_build_logs_url_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get build logs URL\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_build_logs_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Url\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_build_logs_url_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxIdOrName}/build-logs-url',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_port_preview_url(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PortPreviewUrl:\n        \"\"\"Get preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to get preview URL for (required)\n        :type port: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_port_preview_url_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PortPreviewUrl]:\n        \"\"\"Get preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to get preview URL for (required)\n        :type port: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_port_preview_url_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to get preview URL for (required)\n        :type port: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_port_preview_url_serialize(\n        self,\n        sandbox_id_or_name,\n        port,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        if port is not None:\n            _path_params['port'] = port\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxIdOrName}/ports/{port}/preview-url',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_sandbox(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Get sandbox details\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_sandbox_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Get sandbox details\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_sandbox_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get sandbox details\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_sandbox_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        verbose,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        if verbose is not None:\n            \n            _query_params.append(('verbose', verbose))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxIdOrName}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_sandbox_logs(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Page number (1-indexed)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of items per page\")] = None,\n        severities: Annotated[Optional[List[StrictStr]], Field(description=\"Filter by severity levels (DEBUG, INFO, WARN, ERROR)\")] = None,\n        search: Annotated[Optional[StrictStr], Field(description=\"Search in log body\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PaginatedLogs:\n        \"\"\"Get sandbox logs\n\n        Retrieve OTEL logs for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number (1-indexed)\n        :type page: float\n        :param limit: Number of items per page\n        :type limit: float\n        :param severities: Filter by severity levels (DEBUG, INFO, WARN, ERROR)\n        :type severities: List[str]\n        :param search: Search in log body\n        :type search: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_logs_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            severities=severities,\n            search=search,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_sandbox_logs_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Page number (1-indexed)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of items per page\")] = None,\n        severities: Annotated[Optional[List[StrictStr]], Field(description=\"Filter by severity levels (DEBUG, INFO, WARN, ERROR)\")] = None,\n        search: Annotated[Optional[StrictStr], Field(description=\"Search in log body\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PaginatedLogs]:\n        \"\"\"Get sandbox logs\n\n        Retrieve OTEL logs for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number (1-indexed)\n        :type page: float\n        :param limit: Number of items per page\n        :type limit: float\n        :param severities: Filter by severity levels (DEBUG, INFO, WARN, ERROR)\n        :type severities: List[str]\n        :param search: Search in log body\n        :type search: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_logs_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            severities=severities,\n            search=search,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_sandbox_logs_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Page number (1-indexed)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of items per page\")] = None,\n        severities: Annotated[Optional[List[StrictStr]], Field(description=\"Filter by severity levels (DEBUG, INFO, WARN, ERROR)\")] = None,\n        search: Annotated[Optional[StrictStr], Field(description=\"Search in log body\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get sandbox logs\n\n        Retrieve OTEL logs for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number (1-indexed)\n        :type page: float\n        :param limit: Number of items per page\n        :type limit: float\n        :param severities: Filter by severity levels (DEBUG, INFO, WARN, ERROR)\n        :type severities: List[str]\n        :param search: Search in log body\n        :type search: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_logs_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            severities=severities,\n            search=search,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedLogs\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_sandbox_logs_serialize(\n        self,\n        sandbox_id,\n        var_from,\n        to,\n        x_daytona_organization_id,\n        page,\n        limit,\n        severities,\n        search,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n            'severities': 'multi',\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if var_from is not None:\n            if isinstance(var_from, datetime):\n                _query_params.append(\n                    (\n                        'from',\n                        var_from.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('from', var_from))\n            \n        if to is not None:\n            if isinstance(to, datetime):\n                _query_params.append(\n                    (\n                        'to',\n                        to.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('to', to))\n            \n        if page is not None:\n            \n            _query_params.append(('page', page))\n            \n        if limit is not None:\n            \n            _query_params.append(('limit', limit))\n            \n        if severities is not None:\n            \n            _query_params.append(('severities', severities))\n            \n        if search is not None:\n            \n            _query_params.append(('search', search))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxId}/telemetry/logs',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_sandbox_metrics(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        metric_names: Annotated[Optional[List[StrictStr]], Field(description=\"Filter by metric names\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> MetricsResponse:\n        \"\"\"Get sandbox metrics\n\n        Retrieve OTEL metrics for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param metric_names: Filter by metric names\n        :type metric_names: List[str]\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_metrics_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            metric_names=metric_names,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MetricsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_sandbox_metrics_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        metric_names: Annotated[Optional[List[StrictStr]], Field(description=\"Filter by metric names\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[MetricsResponse]:\n        \"\"\"Get sandbox metrics\n\n        Retrieve OTEL metrics for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param metric_names: Filter by metric names\n        :type metric_names: List[str]\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_metrics_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            metric_names=metric_names,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MetricsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_sandbox_metrics_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        metric_names: Annotated[Optional[List[StrictStr]], Field(description=\"Filter by metric names\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get sandbox metrics\n\n        Retrieve OTEL metrics for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param metric_names: Filter by metric names\n        :type metric_names: List[str]\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_metrics_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            metric_names=metric_names,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MetricsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_sandbox_metrics_serialize(\n        self,\n        sandbox_id,\n        var_from,\n        to,\n        x_daytona_organization_id,\n        metric_names,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n            'metricNames': 'multi',\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if var_from is not None:\n            if isinstance(var_from, datetime):\n                _query_params.append(\n                    (\n                        'from',\n                        var_from.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('from', var_from))\n            \n        if to is not None:\n            if isinstance(to, datetime):\n                _query_params.append(\n                    (\n                        'to',\n                        to.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('to', to))\n            \n        if metric_names is not None:\n            \n            _query_params.append(('metricNames', metric_names))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxId}/telemetry/metrics',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_sandbox_trace_spans(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        trace_id: Annotated[StrictStr, Field(description=\"ID of the trace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[TraceSpan]:\n        \"\"\"Get trace spans\n\n        Retrieve all spans for a specific trace\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param trace_id: ID of the trace (required)\n        :type trace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_trace_spans_serialize(\n            sandbox_id=sandbox_id,\n            trace_id=trace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[TraceSpan]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_sandbox_trace_spans_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        trace_id: Annotated[StrictStr, Field(description=\"ID of the trace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[TraceSpan]]:\n        \"\"\"Get trace spans\n\n        Retrieve all spans for a specific trace\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param trace_id: ID of the trace (required)\n        :type trace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_trace_spans_serialize(\n            sandbox_id=sandbox_id,\n            trace_id=trace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[TraceSpan]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_sandbox_trace_spans_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        trace_id: Annotated[StrictStr, Field(description=\"ID of the trace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get trace spans\n\n        Retrieve all spans for a specific trace\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param trace_id: ID of the trace (required)\n        :type trace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_trace_spans_serialize(\n            sandbox_id=sandbox_id,\n            trace_id=trace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[TraceSpan]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_sandbox_trace_spans_serialize(\n        self,\n        sandbox_id,\n        trace_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if trace_id is not None:\n            _path_params['traceId'] = trace_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxId}/telemetry/traces/{traceId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_sandbox_traces(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Page number (1-indexed)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of items per page\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PaginatedTraces:\n        \"\"\"Get sandbox traces\n\n        Retrieve OTEL traces for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number (1-indexed)\n        :type page: float\n        :param limit: Number of items per page\n        :type limit: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_traces_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedTraces\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_sandbox_traces_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Page number (1-indexed)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of items per page\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PaginatedTraces]:\n        \"\"\"Get sandbox traces\n\n        Retrieve OTEL traces for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number (1-indexed)\n        :type page: float\n        :param limit: Number of items per page\n        :type limit: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_traces_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedTraces\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_sandbox_traces_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        var_from: Annotated[datetime, Field(description=\"Start of time range (ISO 8601)\")],\n        to: Annotated[datetime, Field(description=\"End of time range (ISO 8601)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Page number (1-indexed)\")] = None,\n        limit: Annotated[Optional[Union[StrictFloat, StrictInt]], Field(description=\"Number of items per page\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get sandbox traces\n\n        Retrieve OTEL traces for a sandbox within a time range\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param var_from: Start of time range (ISO 8601) (required)\n        :type var_from: datetime\n        :param to: End of time range (ISO 8601) (required)\n        :type to: datetime\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number (1-indexed)\n        :type page: float\n        :param limit: Number of items per page\n        :type limit: float\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandbox_traces_serialize(\n            sandbox_id=sandbox_id,\n            var_from=var_from,\n            to=to,\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedTraces\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_sandbox_traces_serialize(\n        self,\n        sandbox_id,\n        var_from,\n        to,\n        x_daytona_organization_id,\n        page,\n        limit,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if var_from is not None:\n            if isinstance(var_from, datetime):\n                _query_params.append(\n                    (\n                        'from',\n                        var_from.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('from', var_from))\n            \n        if to is not None:\n            if isinstance(to, datetime):\n                _query_params.append(\n                    (\n                        'to',\n                        to.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('to', to))\n            \n        if page is not None:\n            \n            _query_params.append(('page', page))\n            \n        if limit is not None:\n            \n            _query_params.append(('limit', limit))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxId}/telemetry/traces',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_sandboxes_for_runner(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        states: Annotated[Optional[StrictStr], Field(description=\"Comma-separated list of sandbox states to filter by\")] = None,\n        skip_reconciling_sandboxes: Annotated[Optional[StrictBool], Field(description=\"Skip sandboxes where state differs from desired state\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Sandbox]:\n        \"\"\"Get sandboxes for the authenticated runner\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param states: Comma-separated list of sandbox states to filter by\n        :type states: str\n        :param skip_reconciling_sandboxes: Skip sandboxes where state differs from desired state\n        :type skip_reconciling_sandboxes: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandboxes_for_runner_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            states=states,\n            skip_reconciling_sandboxes=skip_reconciling_sandboxes,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Sandbox]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_sandboxes_for_runner_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        states: Annotated[Optional[StrictStr], Field(description=\"Comma-separated list of sandbox states to filter by\")] = None,\n        skip_reconciling_sandboxes: Annotated[Optional[StrictBool], Field(description=\"Skip sandboxes where state differs from desired state\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Sandbox]]:\n        \"\"\"Get sandboxes for the authenticated runner\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param states: Comma-separated list of sandbox states to filter by\n        :type states: str\n        :param skip_reconciling_sandboxes: Skip sandboxes where state differs from desired state\n        :type skip_reconciling_sandboxes: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandboxes_for_runner_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            states=states,\n            skip_reconciling_sandboxes=skip_reconciling_sandboxes,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Sandbox]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_sandboxes_for_runner_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        states: Annotated[Optional[StrictStr], Field(description=\"Comma-separated list of sandbox states to filter by\")] = None,\n        skip_reconciling_sandboxes: Annotated[Optional[StrictBool], Field(description=\"Skip sandboxes where state differs from desired state\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get sandboxes for the authenticated runner\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param states: Comma-separated list of sandbox states to filter by\n        :type states: str\n        :param skip_reconciling_sandboxes: Skip sandboxes where state differs from desired state\n        :type skip_reconciling_sandboxes: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_sandboxes_for_runner_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            states=states,\n            skip_reconciling_sandboxes=skip_reconciling_sandboxes,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Sandbox]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_sandboxes_for_runner_serialize(\n        self,\n        x_daytona_organization_id,\n        states,\n        skip_reconciling_sandboxes,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if states is not None:\n            \n            _query_params.append(('states', states))\n            \n        if skip_reconciling_sandboxes is not None:\n            \n            _query_params.append(('skipReconcilingSandboxes', skip_reconciling_sandboxes))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/for-runner',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_signed_port_preview_url(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[StrictInt, Field(description=\"Port number to get signed preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        expires_in_seconds: Annotated[Optional[StrictInt], Field(description=\"Expiration time in seconds (default: 60 seconds)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SignedPortPreviewUrl:\n        \"\"\"Get signed preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to get signed preview URL for (required)\n        :type port: int\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param expires_in_seconds: Expiration time in seconds (default: 60 seconds)\n        :type expires_in_seconds: int\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_signed_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            expires_in_seconds=expires_in_seconds,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SignedPortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_signed_port_preview_url_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[StrictInt, Field(description=\"Port number to get signed preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        expires_in_seconds: Annotated[Optional[StrictInt], Field(description=\"Expiration time in seconds (default: 60 seconds)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SignedPortPreviewUrl]:\n        \"\"\"Get signed preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to get signed preview URL for (required)\n        :type port: int\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param expires_in_seconds: Expiration time in seconds (default: 60 seconds)\n        :type expires_in_seconds: int\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_signed_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            expires_in_seconds=expires_in_seconds,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SignedPortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_signed_port_preview_url_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        port: Annotated[StrictInt, Field(description=\"Port number to get signed preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        expires_in_seconds: Annotated[Optional[StrictInt], Field(description=\"Expiration time in seconds (default: 60 seconds)\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get signed preview URL for a sandbox port\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param port: Port number to get signed preview URL for (required)\n        :type port: int\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param expires_in_seconds: Expiration time in seconds (default: 60 seconds)\n        :type expires_in_seconds: int\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_signed_port_preview_url_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            expires_in_seconds=expires_in_seconds,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SignedPortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_signed_port_preview_url_serialize(\n        self,\n        sandbox_id_or_name,\n        port,\n        x_daytona_organization_id,\n        expires_in_seconds,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        if port is not None:\n            _path_params['port'] = port\n        # process the query parameters\n        if expires_in_seconds is not None:\n            \n            _query_params.append(('expiresInSeconds', expires_in_seconds))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxIdOrName}/ports/{port}/signed-preview-url',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_toolbox_proxy_url(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ToolboxProxyUrl:\n        \"\"\"Get toolbox proxy URL for a sandbox\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_toolbox_proxy_url_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ToolboxProxyUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_toolbox_proxy_url_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ToolboxProxyUrl]:\n        \"\"\"Get toolbox proxy URL for a sandbox\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_toolbox_proxy_url_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ToolboxProxyUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_toolbox_proxy_url_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get toolbox proxy URL for a sandbox\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_toolbox_proxy_url_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ToolboxProxyUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_toolbox_proxy_url_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/{sandboxId}/toolbox-proxy-url',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_sandboxes(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        include_errored_deleted: Annotated[Optional[StrictBool], Field(description=\"Include errored and deleted sandboxes\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Sandbox]:\n        \"\"\"List all sandboxes\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param include_errored_deleted: Include errored and deleted sandboxes\n        :type include_errored_deleted: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_sandboxes_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            labels=labels,\n            include_errored_deleted=include_errored_deleted,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Sandbox]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_sandboxes_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        include_errored_deleted: Annotated[Optional[StrictBool], Field(description=\"Include errored and deleted sandboxes\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Sandbox]]:\n        \"\"\"List all sandboxes\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param include_errored_deleted: Include errored and deleted sandboxes\n        :type include_errored_deleted: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_sandboxes_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            labels=labels,\n            include_errored_deleted=include_errored_deleted,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Sandbox]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_sandboxes_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        include_errored_deleted: Annotated[Optional[StrictBool], Field(description=\"Include errored and deleted sandboxes\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all sandboxes\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param include_errored_deleted: Include errored and deleted sandboxes\n        :type include_errored_deleted: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_sandboxes_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            labels=labels,\n            include_errored_deleted=include_errored_deleted,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Sandbox]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_sandboxes_serialize(\n        self,\n        x_daytona_organization_id,\n        verbose,\n        labels,\n        include_errored_deleted,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if verbose is not None:\n            \n            _query_params.append(('verbose', verbose))\n            \n        if labels is not None:\n            \n            _query_params.append(('labels', labels))\n            \n        if include_errored_deleted is not None:\n            \n            _query_params.append(('includeErroredDeleted', include_errored_deleted))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_sandboxes_paginated(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        id: Annotated[Optional[StrictStr], Field(description=\"Filter by partial ID match\")] = None,\n        name: Annotated[Optional[StrictStr], Field(description=\"Filter by partial name match\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        include_errored_deleted: Annotated[Optional[StrictBool], Field(description=\"Include results with errored state and deleted desired state\")] = None,\n        states: Annotated[Optional[List[StrictStr]], Field(description=\"List of states to filter by\")] = None,\n        snapshots: Annotated[Optional[List[StrictStr]], Field(description=\"List of snapshot names to filter by\")] = None,\n        regions: Annotated[Optional[List[StrictStr]], Field(description=\"List of regions to filter by\")] = None,\n        min_cpu: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum CPU\")] = None,\n        max_cpu: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum CPU\")] = None,\n        min_memory_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum memory in GiB\")] = None,\n        max_memory_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum memory in GiB\")] = None,\n        min_disk_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum disk space in GiB\")] = None,\n        max_disk_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum disk space in GiB\")] = None,\n        last_event_after: Annotated[Optional[datetime], Field(description=\"Include items with last event after this timestamp\")] = None,\n        last_event_before: Annotated[Optional[datetime], Field(description=\"Include items with last event before this timestamp\")] = None,\n        sort: Annotated[Optional[StrictStr], Field(description=\"Field to sort by\")] = None,\n        order: Annotated[Optional[StrictStr], Field(description=\"Direction to sort by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PaginatedSandboxes:\n        \"\"\"List all sandboxes paginated\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param id: Filter by partial ID match\n        :type id: str\n        :param name: Filter by partial name match\n        :type name: str\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param include_errored_deleted: Include results with errored state and deleted desired state\n        :type include_errored_deleted: bool\n        :param states: List of states to filter by\n        :type states: List[str]\n        :param snapshots: List of snapshot names to filter by\n        :type snapshots: List[str]\n        :param regions: List of regions to filter by\n        :type regions: List[str]\n        :param min_cpu: Minimum CPU\n        :type min_cpu: float\n        :param max_cpu: Maximum CPU\n        :type max_cpu: float\n        :param min_memory_gi_b: Minimum memory in GiB\n        :type min_memory_gi_b: float\n        :param max_memory_gi_b: Maximum memory in GiB\n        :type max_memory_gi_b: float\n        :param min_disk_gi_b: Minimum disk space in GiB\n        :type min_disk_gi_b: float\n        :param max_disk_gi_b: Maximum disk space in GiB\n        :type max_disk_gi_b: float\n        :param last_event_after: Include items with last event after this timestamp\n        :type last_event_after: datetime\n        :param last_event_before: Include items with last event before this timestamp\n        :type last_event_before: datetime\n        :param sort: Field to sort by\n        :type sort: str\n        :param order: Direction to sort by\n        :type order: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_sandboxes_paginated_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            id=id,\n            name=name,\n            labels=labels,\n            include_errored_deleted=include_errored_deleted,\n            states=states,\n            snapshots=snapshots,\n            regions=regions,\n            min_cpu=min_cpu,\n            max_cpu=max_cpu,\n            min_memory_gi_b=min_memory_gi_b,\n            max_memory_gi_b=max_memory_gi_b,\n            min_disk_gi_b=min_disk_gi_b,\n            max_disk_gi_b=max_disk_gi_b,\n            last_event_after=last_event_after,\n            last_event_before=last_event_before,\n            sort=sort,\n            order=order,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedSandboxes\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_sandboxes_paginated_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        id: Annotated[Optional[StrictStr], Field(description=\"Filter by partial ID match\")] = None,\n        name: Annotated[Optional[StrictStr], Field(description=\"Filter by partial name match\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        include_errored_deleted: Annotated[Optional[StrictBool], Field(description=\"Include results with errored state and deleted desired state\")] = None,\n        states: Annotated[Optional[List[StrictStr]], Field(description=\"List of states to filter by\")] = None,\n        snapshots: Annotated[Optional[List[StrictStr]], Field(description=\"List of snapshot names to filter by\")] = None,\n        regions: Annotated[Optional[List[StrictStr]], Field(description=\"List of regions to filter by\")] = None,\n        min_cpu: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum CPU\")] = None,\n        max_cpu: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum CPU\")] = None,\n        min_memory_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum memory in GiB\")] = None,\n        max_memory_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum memory in GiB\")] = None,\n        min_disk_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum disk space in GiB\")] = None,\n        max_disk_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum disk space in GiB\")] = None,\n        last_event_after: Annotated[Optional[datetime], Field(description=\"Include items with last event after this timestamp\")] = None,\n        last_event_before: Annotated[Optional[datetime], Field(description=\"Include items with last event before this timestamp\")] = None,\n        sort: Annotated[Optional[StrictStr], Field(description=\"Field to sort by\")] = None,\n        order: Annotated[Optional[StrictStr], Field(description=\"Direction to sort by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PaginatedSandboxes]:\n        \"\"\"List all sandboxes paginated\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param id: Filter by partial ID match\n        :type id: str\n        :param name: Filter by partial name match\n        :type name: str\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param include_errored_deleted: Include results with errored state and deleted desired state\n        :type include_errored_deleted: bool\n        :param states: List of states to filter by\n        :type states: List[str]\n        :param snapshots: List of snapshot names to filter by\n        :type snapshots: List[str]\n        :param regions: List of regions to filter by\n        :type regions: List[str]\n        :param min_cpu: Minimum CPU\n        :type min_cpu: float\n        :param max_cpu: Maximum CPU\n        :type max_cpu: float\n        :param min_memory_gi_b: Minimum memory in GiB\n        :type min_memory_gi_b: float\n        :param max_memory_gi_b: Maximum memory in GiB\n        :type max_memory_gi_b: float\n        :param min_disk_gi_b: Minimum disk space in GiB\n        :type min_disk_gi_b: float\n        :param max_disk_gi_b: Maximum disk space in GiB\n        :type max_disk_gi_b: float\n        :param last_event_after: Include items with last event after this timestamp\n        :type last_event_after: datetime\n        :param last_event_before: Include items with last event before this timestamp\n        :type last_event_before: datetime\n        :param sort: Field to sort by\n        :type sort: str\n        :param order: Direction to sort by\n        :type order: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_sandboxes_paginated_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            id=id,\n            name=name,\n            labels=labels,\n            include_errored_deleted=include_errored_deleted,\n            states=states,\n            snapshots=snapshots,\n            regions=regions,\n            min_cpu=min_cpu,\n            max_cpu=max_cpu,\n            min_memory_gi_b=min_memory_gi_b,\n            max_memory_gi_b=max_memory_gi_b,\n            min_disk_gi_b=min_disk_gi_b,\n            max_disk_gi_b=max_disk_gi_b,\n            last_event_after=last_event_after,\n            last_event_before=last_event_before,\n            sort=sort,\n            order=order,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedSandboxes\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_sandboxes_paginated_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        id: Annotated[Optional[StrictStr], Field(description=\"Filter by partial ID match\")] = None,\n        name: Annotated[Optional[StrictStr], Field(description=\"Filter by partial name match\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        include_errored_deleted: Annotated[Optional[StrictBool], Field(description=\"Include results with errored state and deleted desired state\")] = None,\n        states: Annotated[Optional[List[StrictStr]], Field(description=\"List of states to filter by\")] = None,\n        snapshots: Annotated[Optional[List[StrictStr]], Field(description=\"List of snapshot names to filter by\")] = None,\n        regions: Annotated[Optional[List[StrictStr]], Field(description=\"List of regions to filter by\")] = None,\n        min_cpu: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum CPU\")] = None,\n        max_cpu: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum CPU\")] = None,\n        min_memory_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum memory in GiB\")] = None,\n        max_memory_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum memory in GiB\")] = None,\n        min_disk_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Minimum disk space in GiB\")] = None,\n        max_disk_gi_b: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Maximum disk space in GiB\")] = None,\n        last_event_after: Annotated[Optional[datetime], Field(description=\"Include items with last event after this timestamp\")] = None,\n        last_event_before: Annotated[Optional[datetime], Field(description=\"Include items with last event before this timestamp\")] = None,\n        sort: Annotated[Optional[StrictStr], Field(description=\"Field to sort by\")] = None,\n        order: Annotated[Optional[StrictStr], Field(description=\"Direction to sort by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all sandboxes paginated\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param id: Filter by partial ID match\n        :type id: str\n        :param name: Filter by partial name match\n        :type name: str\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param include_errored_deleted: Include results with errored state and deleted desired state\n        :type include_errored_deleted: bool\n        :param states: List of states to filter by\n        :type states: List[str]\n        :param snapshots: List of snapshot names to filter by\n        :type snapshots: List[str]\n        :param regions: List of regions to filter by\n        :type regions: List[str]\n        :param min_cpu: Minimum CPU\n        :type min_cpu: float\n        :param max_cpu: Maximum CPU\n        :type max_cpu: float\n        :param min_memory_gi_b: Minimum memory in GiB\n        :type min_memory_gi_b: float\n        :param max_memory_gi_b: Maximum memory in GiB\n        :type max_memory_gi_b: float\n        :param min_disk_gi_b: Minimum disk space in GiB\n        :type min_disk_gi_b: float\n        :param max_disk_gi_b: Maximum disk space in GiB\n        :type max_disk_gi_b: float\n        :param last_event_after: Include items with last event after this timestamp\n        :type last_event_after: datetime\n        :param last_event_before: Include items with last event before this timestamp\n        :type last_event_before: datetime\n        :param sort: Field to sort by\n        :type sort: str\n        :param order: Direction to sort by\n        :type order: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_sandboxes_paginated_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            id=id,\n            name=name,\n            labels=labels,\n            include_errored_deleted=include_errored_deleted,\n            states=states,\n            snapshots=snapshots,\n            regions=regions,\n            min_cpu=min_cpu,\n            max_cpu=max_cpu,\n            min_memory_gi_b=min_memory_gi_b,\n            max_memory_gi_b=max_memory_gi_b,\n            min_disk_gi_b=min_disk_gi_b,\n            max_disk_gi_b=max_disk_gi_b,\n            last_event_after=last_event_after,\n            last_event_before=last_event_before,\n            sort=sort,\n            order=order,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedSandboxes\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_sandboxes_paginated_serialize(\n        self,\n        x_daytona_organization_id,\n        page,\n        limit,\n        id,\n        name,\n        labels,\n        include_errored_deleted,\n        states,\n        snapshots,\n        regions,\n        min_cpu,\n        max_cpu,\n        min_memory_gi_b,\n        max_memory_gi_b,\n        min_disk_gi_b,\n        max_disk_gi_b,\n        last_event_after,\n        last_event_before,\n        sort,\n        order,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n            'states': 'multi',\n            'snapshots': 'multi',\n            'regions': 'multi',\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if page is not None:\n            \n            _query_params.append(('page', page))\n            \n        if limit is not None:\n            \n            _query_params.append(('limit', limit))\n            \n        if id is not None:\n            \n            _query_params.append(('id', id))\n            \n        if name is not None:\n            \n            _query_params.append(('name', name))\n            \n        if labels is not None:\n            \n            _query_params.append(('labels', labels))\n            \n        if include_errored_deleted is not None:\n            \n            _query_params.append(('includeErroredDeleted', include_errored_deleted))\n            \n        if states is not None:\n            \n            _query_params.append(('states', states))\n            \n        if snapshots is not None:\n            \n            _query_params.append(('snapshots', snapshots))\n            \n        if regions is not None:\n            \n            _query_params.append(('regions', regions))\n            \n        if min_cpu is not None:\n            \n            _query_params.append(('minCpu', min_cpu))\n            \n        if max_cpu is not None:\n            \n            _query_params.append(('maxCpu', max_cpu))\n            \n        if min_memory_gi_b is not None:\n            \n            _query_params.append(('minMemoryGiB', min_memory_gi_b))\n            \n        if max_memory_gi_b is not None:\n            \n            _query_params.append(('maxMemoryGiB', max_memory_gi_b))\n            \n        if min_disk_gi_b is not None:\n            \n            _query_params.append(('minDiskGiB', min_disk_gi_b))\n            \n        if max_disk_gi_b is not None:\n            \n            _query_params.append(('maxDiskGiB', max_disk_gi_b))\n            \n        if last_event_after is not None:\n            if isinstance(last_event_after, datetime):\n                _query_params.append(\n                    (\n                        'lastEventAfter',\n                        last_event_after.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('lastEventAfter', last_event_after))\n            \n        if last_event_before is not None:\n            if isinstance(last_event_before, datetime):\n                _query_params.append(\n                    (\n                        'lastEventBefore',\n                        last_event_before.strftime(\n                            self.api_client.configuration.datetime_format\n                        )\n                    )\n                )\n            else:\n                _query_params.append(('lastEventBefore', last_event_before))\n            \n        if sort is not None:\n            \n            _query_params.append(('sort', sort))\n            \n        if order is not None:\n            \n            _query_params.append(('order', order))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/paginated',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def recover_sandbox(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Recover sandbox from error state\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._recover_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def recover_sandbox_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Recover sandbox from error state\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._recover_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def recover_sandbox_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Recover sandbox from error state\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._recover_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _recover_sandbox_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/recover',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def replace_labels(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        sandbox_labels: SandboxLabels,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SandboxLabels:\n        \"\"\"Replace sandbox labels\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param sandbox_labels: (required)\n        :type sandbox_labels: SandboxLabels\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._replace_labels_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            sandbox_labels=sandbox_labels,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SandboxLabels\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def replace_labels_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        sandbox_labels: SandboxLabels,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SandboxLabels]:\n        \"\"\"Replace sandbox labels\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param sandbox_labels: (required)\n        :type sandbox_labels: SandboxLabels\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._replace_labels_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            sandbox_labels=sandbox_labels,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SandboxLabels\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def replace_labels_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        sandbox_labels: SandboxLabels,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Replace sandbox labels\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param sandbox_labels: (required)\n        :type sandbox_labels: SandboxLabels\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._replace_labels_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            sandbox_labels=sandbox_labels,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SandboxLabels\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _replace_labels_serialize(\n        self,\n        sandbox_id_or_name,\n        sandbox_labels,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if sandbox_labels is not None:\n            _body_params = sandbox_labels\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PUT',\n            resource_path='/sandbox/{sandboxIdOrName}/labels',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def resize_sandbox(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        resize_sandbox: ResizeSandbox,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Resize sandbox resources\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param resize_sandbox: (required)\n        :type resize_sandbox: ResizeSandbox\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._resize_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            resize_sandbox=resize_sandbox,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def resize_sandbox_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        resize_sandbox: ResizeSandbox,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Resize sandbox resources\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param resize_sandbox: (required)\n        :type resize_sandbox: ResizeSandbox\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._resize_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            resize_sandbox=resize_sandbox,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def resize_sandbox_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        resize_sandbox: ResizeSandbox,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Resize sandbox resources\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param resize_sandbox: (required)\n        :type resize_sandbox: ResizeSandbox\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._resize_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            resize_sandbox=resize_sandbox,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _resize_sandbox_serialize(\n        self,\n        sandbox_id_or_name,\n        resize_sandbox,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if resize_sandbox is not None:\n            _body_params = resize_sandbox\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/resize',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def revoke_ssh_access(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        token: Annotated[Optional[StrictStr], Field(description=\"SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Revoke SSH access for sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param token: SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\n        :type token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._revoke_ssh_access_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            token=token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def revoke_ssh_access_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        token: Annotated[Optional[StrictStr], Field(description=\"SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Revoke SSH access for sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param token: SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\n        :type token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._revoke_ssh_access_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            token=token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def revoke_ssh_access_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        token: Annotated[Optional[StrictStr], Field(description=\"SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Revoke SSH access for sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param token: SSH access token to revoke. If not provided, all SSH access for the sandbox will be revoked.\n        :type token: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._revoke_ssh_access_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            token=token,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _revoke_ssh_access_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        token,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        if token is not None:\n            \n            _query_params.append(('token', token))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/sandbox/{sandboxIdOrName}/ssh-access',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_auto_archive_interval(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-archive interval in minutes (0 means the maximum interval will be used)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Set sandbox auto-archive interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-archive interval in minutes (0 means the maximum interval will be used) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_auto_archive_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_auto_archive_interval_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-archive interval in minutes (0 means the maximum interval will be used)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Set sandbox auto-archive interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-archive interval in minutes (0 means the maximum interval will be used) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_auto_archive_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_auto_archive_interval_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-archive interval in minutes (0 means the maximum interval will be used)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Set sandbox auto-archive interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-archive interval in minutes (0 means the maximum interval will be used) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_auto_archive_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_auto_archive_interval_serialize(\n        self,\n        sandbox_id_or_name,\n        interval,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        if interval is not None:\n            _path_params['interval'] = interval\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/autoarchive/{interval}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_auto_delete_interval(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Set sandbox auto-delete interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_auto_delete_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_auto_delete_interval_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Set sandbox auto-delete interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_auto_delete_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_auto_delete_interval_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Set sandbox auto-delete interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_auto_delete_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_auto_delete_interval_serialize(\n        self,\n        sandbox_id_or_name,\n        interval,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        if interval is not None:\n            _path_params['interval'] = interval\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/autodelete/{interval}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_autostop_interval(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-stop interval in minutes (0 to disable)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Set sandbox auto-stop interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-stop interval in minutes (0 to disable) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_autostop_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_autostop_interval_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-stop interval in minutes (0 to disable)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Set sandbox auto-stop interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-stop interval in minutes (0 to disable) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_autostop_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_autostop_interval_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-stop interval in minutes (0 to disable)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Set sandbox auto-stop interval\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param interval: Auto-stop interval in minutes (0 to disable) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_autostop_interval_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_autostop_interval_serialize(\n        self,\n        sandbox_id_or_name,\n        interval,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        if interval is not None:\n            _path_params['interval'] = interval\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/autostop/{interval}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def start_sandbox(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Start sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._start_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def start_sandbox_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Start sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._start_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def start_sandbox_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Start sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._start_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _start_sandbox_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/start',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def stop_sandbox(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Stop sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._stop_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def stop_sandbox_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Stop sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._stop_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def stop_sandbox_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Stop sandbox\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._stop_sandbox_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _stop_sandbox_serialize(\n        self,\n        sandbox_id_or_name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/stop',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_last_activity(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Update sandbox last activity\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_last_activity_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_last_activity_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Update sandbox last activity\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_last_activity_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_last_activity_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update sandbox last activity\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_last_activity_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_last_activity_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxId}/last-activity',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_public_status(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        is_public: Annotated[StrictBool, Field(description=\"Public status to set\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Sandbox:\n        \"\"\"Update public status\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param is_public: Public status to set (required)\n        :type is_public: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_public_status_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            is_public=is_public,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_public_status_with_http_info(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        is_public: Annotated[StrictBool, Field(description=\"Public status to set\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Sandbox]:\n        \"\"\"Update public status\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param is_public: Public status to set (required)\n        :type is_public: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_public_status_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            is_public=is_public,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_public_status_without_preload_content(\n        self,\n        sandbox_id_or_name: Annotated[StrictStr, Field(description=\"ID or name of the sandbox\")],\n        is_public: Annotated[StrictBool, Field(description=\"Public status to set\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update public status\n\n\n        :param sandbox_id_or_name: ID or name of the sandbox (required)\n        :type sandbox_id_or_name: str\n        :param is_public: Public status to set (required)\n        :type is_public: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_public_status_serialize(\n            sandbox_id_or_name=sandbox_id_or_name,\n            is_public=is_public,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Sandbox\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_public_status_serialize(\n        self,\n        sandbox_id_or_name,\n        is_public,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id_or_name is not None:\n            _path_params['sandboxIdOrName'] = sandbox_id_or_name\n        if is_public is not None:\n            _path_params['isPublic'] = is_public\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/sandbox/{sandboxIdOrName}/public/{isPublic}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_sandbox_state(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        update_sandbox_state_dto: UpdateSandboxStateDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Update sandbox state\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param update_sandbox_state_dto: (required)\n        :type update_sandbox_state_dto: UpdateSandboxStateDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_sandbox_state_serialize(\n            sandbox_id=sandbox_id,\n            update_sandbox_state_dto=update_sandbox_state_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_sandbox_state_with_http_info(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        update_sandbox_state_dto: UpdateSandboxStateDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Update sandbox state\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param update_sandbox_state_dto: (required)\n        :type update_sandbox_state_dto: UpdateSandboxStateDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_sandbox_state_serialize(\n            sandbox_id=sandbox_id,\n            update_sandbox_state_dto=update_sandbox_state_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_sandbox_state_without_preload_content(\n        self,\n        sandbox_id: Annotated[StrictStr, Field(description=\"ID of the sandbox\")],\n        update_sandbox_state_dto: UpdateSandboxStateDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Update sandbox state\n\n\n        :param sandbox_id: ID of the sandbox (required)\n        :type sandbox_id: str\n        :param update_sandbox_state_dto: (required)\n        :type update_sandbox_state_dto: UpdateSandboxStateDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._update_sandbox_state_serialize(\n            sandbox_id=sandbox_id,\n            update_sandbox_state_dto=update_sandbox_state_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_sandbox_state_serialize(\n        self,\n        sandbox_id,\n        update_sandbox_state_dto,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if update_sandbox_state_dto is not None:\n            _body_params = update_sandbox_state_dto\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PUT',\n            resource_path='/sandbox/{sandboxId}/state',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def validate_ssh_access(\n        self,\n        token: Annotated[StrictStr, Field(description=\"SSH access token to validate\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SshAccessValidationDto:\n        \"\"\"Validate SSH access for sandbox\n\n\n        :param token: SSH access token to validate (required)\n        :type token: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._validate_ssh_access_serialize(\n            token=token,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SshAccessValidationDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def validate_ssh_access_with_http_info(\n        self,\n        token: Annotated[StrictStr, Field(description=\"SSH access token to validate\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SshAccessValidationDto]:\n        \"\"\"Validate SSH access for sandbox\n\n\n        :param token: SSH access token to validate (required)\n        :type token: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._validate_ssh_access_serialize(\n            token=token,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SshAccessValidationDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def validate_ssh_access_without_preload_content(\n        self,\n        token: Annotated[StrictStr, Field(description=\"SSH access token to validate\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Validate SSH access for sandbox\n\n\n        :param token: SSH access token to validate (required)\n        :type token: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._validate_ssh_access_serialize(\n            token=token,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SshAccessValidationDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _validate_ssh_access_serialize(\n        self,\n        token,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if token is not None:\n            \n            _query_params.append(('token', token))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/sandbox/ssh-access/validate',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/snapshots_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictBool, StrictStr, field_validator\nfrom typing import Optional, Union\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.create_snapshot import CreateSnapshot\nfrom daytona_api_client.models.paginated_snapshots import PaginatedSnapshots\nfrom daytona_api_client.models.set_snapshot_general_status_dto import SetSnapshotGeneralStatusDto\nfrom daytona_api_client.models.snapshot_dto import SnapshotDto\nfrom daytona_api_client.models.url import Url\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass SnapshotsApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def activate_snapshot(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SnapshotDto:\n        \"\"\"Activate a snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._activate_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '400': None,\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def activate_snapshot_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SnapshotDto]:\n        \"\"\"Activate a snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._activate_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '400': None,\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def activate_snapshot_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Activate a snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._activate_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '400': None,\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _activate_snapshot_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/snapshots/{id}/activate',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def can_cleanup_image(\n        self,\n        image_name: Annotated[StrictStr, Field(description=\"Image name with tag to check\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> bool:\n        \"\"\"Check if an image can be cleaned up\n\n\n        :param image_name: Image name with tag to check (required)\n        :type image_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._can_cleanup_image_serialize(\n            image_name=image_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def can_cleanup_image_with_http_info(\n        self,\n        image_name: Annotated[StrictStr, Field(description=\"Image name with tag to check\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[bool]:\n        \"\"\"Check if an image can be cleaned up\n\n\n        :param image_name: Image name with tag to check (required)\n        :type image_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._can_cleanup_image_serialize(\n            image_name=image_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def can_cleanup_image_without_preload_content(\n        self,\n        image_name: Annotated[StrictStr, Field(description=\"Image name with tag to check\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Check if an image can be cleaned up\n\n\n        :param image_name: Image name with tag to check (required)\n        :type image_name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._can_cleanup_image_serialize(\n            image_name=image_name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bool\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _can_cleanup_image_serialize(\n        self,\n        image_name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if image_name is not None:\n            \n            _query_params.append(('imageName', image_name))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/snapshots/can-cleanup-image',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_snapshot(\n        self,\n        create_snapshot: CreateSnapshot,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SnapshotDto:\n        \"\"\"Create a new snapshot\n\n\n        :param create_snapshot: (required)\n        :type create_snapshot: CreateSnapshot\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_snapshot_serialize(\n            create_snapshot=create_snapshot,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '400': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_snapshot_with_http_info(\n        self,\n        create_snapshot: CreateSnapshot,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SnapshotDto]:\n        \"\"\"Create a new snapshot\n\n\n        :param create_snapshot: (required)\n        :type create_snapshot: CreateSnapshot\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_snapshot_serialize(\n            create_snapshot=create_snapshot,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '400': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_snapshot_without_preload_content(\n        self,\n        create_snapshot: CreateSnapshot,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create a new snapshot\n\n\n        :param create_snapshot: (required)\n        :type create_snapshot: CreateSnapshot\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_snapshot_serialize(\n            create_snapshot=create_snapshot,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '400': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_snapshot_serialize(\n        self,\n        create_snapshot,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_snapshot is not None:\n            _body_params = create_snapshot\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/snapshots',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def deactivate_snapshot(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Deactivate a snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._deactivate_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def deactivate_snapshot_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Deactivate a snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._deactivate_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def deactivate_snapshot_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Deactivate a snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._deactivate_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _deactivate_snapshot_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/snapshots/{id}/deactivate',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_all_snapshots(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        name: Annotated[Optional[StrictStr], Field(description=\"Filter by partial name match\")] = None,\n        sort: Annotated[Optional[StrictStr], Field(description=\"Field to sort by\")] = None,\n        order: Annotated[Optional[StrictStr], Field(description=\"Direction to sort by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PaginatedSnapshots:\n        \"\"\"List all snapshots\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param name: Filter by partial name match\n        :type name: str\n        :param sort: Field to sort by\n        :type sort: str\n        :param order: Direction to sort by\n        :type order: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_all_snapshots_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            name=name,\n            sort=sort,\n            order=order,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedSnapshots\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_all_snapshots_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        name: Annotated[Optional[StrictStr], Field(description=\"Filter by partial name match\")] = None,\n        sort: Annotated[Optional[StrictStr], Field(description=\"Field to sort by\")] = None,\n        order: Annotated[Optional[StrictStr], Field(description=\"Direction to sort by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PaginatedSnapshots]:\n        \"\"\"List all snapshots\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param name: Filter by partial name match\n        :type name: str\n        :param sort: Field to sort by\n        :type sort: str\n        :param order: Direction to sort by\n        :type order: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_all_snapshots_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            name=name,\n            sort=sort,\n            order=order,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedSnapshots\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_all_snapshots_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        page: Annotated[Optional[Union[Annotated[float, Field(strict=True, ge=1)], Annotated[int, Field(strict=True, ge=1)]]], Field(description=\"Page number of the results\")] = None,\n        limit: Annotated[Optional[Union[Annotated[float, Field(le=200, strict=True, ge=1)], Annotated[int, Field(le=200, strict=True, ge=1)]]], Field(description=\"Number of results per page\")] = None,\n        name: Annotated[Optional[StrictStr], Field(description=\"Filter by partial name match\")] = None,\n        sort: Annotated[Optional[StrictStr], Field(description=\"Field to sort by\")] = None,\n        order: Annotated[Optional[StrictStr], Field(description=\"Direction to sort by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all snapshots\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param page: Page number of the results\n        :type page: float\n        :param limit: Number of results per page\n        :type limit: float\n        :param name: Filter by partial name match\n        :type name: str\n        :param sort: Field to sort by\n        :type sort: str\n        :param order: Direction to sort by\n        :type order: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_all_snapshots_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            page=page,\n            limit=limit,\n            name=name,\n            sort=sort,\n            order=order,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PaginatedSnapshots\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_all_snapshots_serialize(\n        self,\n        x_daytona_organization_id,\n        page,\n        limit,\n        name,\n        sort,\n        order,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if page is not None:\n            \n            _query_params.append(('page', page))\n            \n        if limit is not None:\n            \n            _query_params.append(('limit', limit))\n            \n        if name is not None:\n            \n            _query_params.append(('name', name))\n            \n        if sort is not None:\n            \n            _query_params.append(('sort', sort))\n            \n        if order is not None:\n            \n            _query_params.append(('order', order))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/snapshots',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_snapshot(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID or name\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SnapshotDto:\n        \"\"\"Get snapshot by ID or name\n\n\n        :param id: Snapshot ID or name (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_snapshot_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID or name\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SnapshotDto]:\n        \"\"\"Get snapshot by ID or name\n\n\n        :param id: Snapshot ID or name (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_snapshot_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID or name\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get snapshot by ID or name\n\n\n        :param id: Snapshot ID or name (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_snapshot_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/snapshots/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_snapshot_build_logs(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) Get snapshot build logs\n\n        This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /snapshots/{id}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_snapshot_build_logs_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_snapshot_build_logs_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) Get snapshot build logs\n\n        This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /snapshots/{id}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_snapshot_build_logs_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_snapshot_build_logs_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) Get snapshot build logs\n\n        This endpoint is deprecated. Use `getSnapshotBuildLogsUrl` instead.\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /snapshots/{id}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_snapshot_build_logs_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_snapshot_build_logs_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        follow,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        if follow is not None:\n            \n            _query_params.append(('follow', follow))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/snapshots/{id}/build-logs',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_snapshot_build_logs_url(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Url:\n        \"\"\"Get snapshot build logs URL\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_snapshot_build_logs_url_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Url\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_snapshot_build_logs_url_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Url]:\n        \"\"\"Get snapshot build logs URL\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_snapshot_build_logs_url_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Url\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_snapshot_build_logs_url_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get snapshot build logs URL\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_snapshot_build_logs_url_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Url\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_snapshot_build_logs_url_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/snapshots/{id}/build-logs-url',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def remove_snapshot(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._remove_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def remove_snapshot_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._remove_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def remove_snapshot_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete snapshot\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._remove_snapshot_serialize(\n            id=id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _remove_snapshot_serialize(\n        self,\n        id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/snapshots/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_snapshot_general_status(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        set_snapshot_general_status_dto: SetSnapshotGeneralStatusDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SnapshotDto:\n        \"\"\"Set snapshot general status\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param set_snapshot_general_status_dto: (required)\n        :type set_snapshot_general_status_dto: SetSnapshotGeneralStatusDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_snapshot_general_status_serialize(\n            id=id,\n            set_snapshot_general_status_dto=set_snapshot_general_status_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_snapshot_general_status_with_http_info(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        set_snapshot_general_status_dto: SetSnapshotGeneralStatusDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SnapshotDto]:\n        \"\"\"Set snapshot general status\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param set_snapshot_general_status_dto: (required)\n        :type set_snapshot_general_status_dto: SetSnapshotGeneralStatusDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_snapshot_general_status_serialize(\n            id=id,\n            set_snapshot_general_status_dto=set_snapshot_general_status_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_snapshot_general_status_without_preload_content(\n        self,\n        id: Annotated[StrictStr, Field(description=\"Snapshot ID\")],\n        set_snapshot_general_status_dto: SetSnapshotGeneralStatusDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Set snapshot general status\n\n\n        :param id: Snapshot ID (required)\n        :type id: str\n        :param set_snapshot_general_status_dto: (required)\n        :type set_snapshot_general_status_dto: SetSnapshotGeneralStatusDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._set_snapshot_general_status_serialize(\n            id=id,\n            set_snapshot_general_status_dto=set_snapshot_general_status_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SnapshotDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_snapshot_general_status_serialize(\n        self,\n        id,\n        set_snapshot_general_status_dto,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if set_snapshot_general_status_dto is not None:\n            _body_params = set_snapshot_general_status_dto\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PATCH',\n            resource_path='/snapshots/{id}/general',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/toolbox_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictBool, StrictBytes, StrictFloat, StrictInt, StrictStr\nfrom typing import List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.command import Command\nfrom daytona_api_client.models.completion_list import CompletionList\nfrom daytona_api_client.models.compressed_screenshot_response import CompressedScreenshotResponse\nfrom daytona_api_client.models.computer_use_start_response import ComputerUseStartResponse\nfrom daytona_api_client.models.computer_use_status_response import ComputerUseStatusResponse\nfrom daytona_api_client.models.computer_use_stop_response import ComputerUseStopResponse\nfrom daytona_api_client.models.create_session_request import CreateSessionRequest\nfrom daytona_api_client.models.display_info_response import DisplayInfoResponse\nfrom daytona_api_client.models.download_files import DownloadFiles\nfrom daytona_api_client.models.execute_request import ExecuteRequest\nfrom daytona_api_client.models.execute_response import ExecuteResponse\nfrom daytona_api_client.models.file_info import FileInfo\nfrom daytona_api_client.models.git_add_request import GitAddRequest\nfrom daytona_api_client.models.git_branch_request import GitBranchRequest\nfrom daytona_api_client.models.git_checkout_request import GitCheckoutRequest\nfrom daytona_api_client.models.git_clone_request import GitCloneRequest\nfrom daytona_api_client.models.git_commit_info import GitCommitInfo\nfrom daytona_api_client.models.git_commit_request import GitCommitRequest\nfrom daytona_api_client.models.git_commit_response import GitCommitResponse\nfrom daytona_api_client.models.git_delete_branch_request import GitDeleteBranchRequest\nfrom daytona_api_client.models.git_repo_request import GitRepoRequest\nfrom daytona_api_client.models.git_status import GitStatus\nfrom daytona_api_client.models.keyboard_hotkey_request import KeyboardHotkeyRequest\nfrom daytona_api_client.models.keyboard_press_request import KeyboardPressRequest\nfrom daytona_api_client.models.keyboard_type_request import KeyboardTypeRequest\nfrom daytona_api_client.models.list_branch_response import ListBranchResponse\nfrom daytona_api_client.models.lsp_completion_params import LspCompletionParams\nfrom daytona_api_client.models.lsp_document_request import LspDocumentRequest\nfrom daytona_api_client.models.lsp_server_request import LspServerRequest\nfrom daytona_api_client.models.lsp_symbol import LspSymbol\nfrom daytona_api_client.models.match import Match\nfrom daytona_api_client.models.mouse_click_request import MouseClickRequest\nfrom daytona_api_client.models.mouse_click_response import MouseClickResponse\nfrom daytona_api_client.models.mouse_drag_request import MouseDragRequest\nfrom daytona_api_client.models.mouse_drag_response import MouseDragResponse\nfrom daytona_api_client.models.mouse_move_request import MouseMoveRequest\nfrom daytona_api_client.models.mouse_move_response import MouseMoveResponse\nfrom daytona_api_client.models.mouse_position import MousePosition\nfrom daytona_api_client.models.mouse_scroll_request import MouseScrollRequest\nfrom daytona_api_client.models.mouse_scroll_response import MouseScrollResponse\nfrom daytona_api_client.models.process_errors_response import ProcessErrorsResponse\nfrom daytona_api_client.models.process_logs_response import ProcessLogsResponse\nfrom daytona_api_client.models.process_restart_response import ProcessRestartResponse\nfrom daytona_api_client.models.process_status_response import ProcessStatusResponse\nfrom daytona_api_client.models.project_dir_response import ProjectDirResponse\nfrom daytona_api_client.models.pty_create_request import PtyCreateRequest\nfrom daytona_api_client.models.pty_create_response import PtyCreateResponse\nfrom daytona_api_client.models.pty_list_response import PtyListResponse\nfrom daytona_api_client.models.pty_resize_request import PtyResizeRequest\nfrom daytona_api_client.models.pty_session_info import PtySessionInfo\nfrom daytona_api_client.models.region_screenshot_response import RegionScreenshotResponse\nfrom daytona_api_client.models.replace_request import ReplaceRequest\nfrom daytona_api_client.models.replace_result import ReplaceResult\nfrom daytona_api_client.models.screenshot_response import ScreenshotResponse\nfrom daytona_api_client.models.search_files_response import SearchFilesResponse\nfrom daytona_api_client.models.session import Session\nfrom daytona_api_client.models.session_execute_request import SessionExecuteRequest\nfrom daytona_api_client.models.session_execute_response import SessionExecuteResponse\nfrom daytona_api_client.models.user_home_dir_response import UserHomeDirResponse\nfrom daytona_api_client.models.windows_response import WindowsResponse\nfrom daytona_api_client.models.work_dir_response import WorkDirResponse\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass ToolboxApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def click_mouse_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        mouse_click_request: MouseClickRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> MouseClickResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Click mouse\n\n        Click mouse at specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_click_request: (required)\n        :type mouse_click_request: MouseClickRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/click is deprecated.\", DeprecationWarning)\n\n        _param = self._click_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_click_request=mouse_click_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseClickResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def click_mouse_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        mouse_click_request: MouseClickRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[MouseClickResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Click mouse\n\n        Click mouse at specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_click_request: (required)\n        :type mouse_click_request: MouseClickRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/click is deprecated.\", DeprecationWarning)\n\n        _param = self._click_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_click_request=mouse_click_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseClickResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def click_mouse_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        mouse_click_request: MouseClickRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Click mouse\n\n        Click mouse at specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_click_request: (required)\n        :type mouse_click_request: MouseClickRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/click is deprecated.\", DeprecationWarning)\n\n        _param = self._click_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_click_request=mouse_click_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseClickResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _click_mouse_deprecated_serialize(\n        self,\n        sandbox_id,\n        mouse_click_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if mouse_click_request is not None:\n            _body_params = mouse_click_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/mouse/click',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_folder_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        mode: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Create folder\n\n        Create folder inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param mode: (required)\n        :type mode: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/folder is deprecated.\", DeprecationWarning)\n\n        _param = self._create_folder_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            mode=mode,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_folder_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        mode: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Create folder\n\n        Create folder inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param mode: (required)\n        :type mode: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/folder is deprecated.\", DeprecationWarning)\n\n        _param = self._create_folder_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            mode=mode,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_folder_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        mode: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Create folder\n\n        Create folder inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param mode: (required)\n        :type mode: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/folder is deprecated.\", DeprecationWarning)\n\n        _param = self._create_folder_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            mode=mode,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_folder_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        mode,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        if mode is not None:\n            \n            _query_params.append(('mode', mode))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/folder',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_pty_session_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        pty_create_request: PtyCreateRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PtyCreateResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Create PTY session\n\n        Create a new PTY session in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param pty_create_request: (required)\n        :type pty_create_request: PtyCreateRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/pty is deprecated.\", DeprecationWarning)\n\n        _param = self._create_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            pty_create_request=pty_create_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"PtyCreateResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_pty_session_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        pty_create_request: PtyCreateRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PtyCreateResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Create PTY session\n\n        Create a new PTY session in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param pty_create_request: (required)\n        :type pty_create_request: PtyCreateRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/pty is deprecated.\", DeprecationWarning)\n\n        _param = self._create_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            pty_create_request=pty_create_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"PtyCreateResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_pty_session_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        pty_create_request: PtyCreateRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Create PTY session\n\n        Create a new PTY session in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param pty_create_request: (required)\n        :type pty_create_request: PtyCreateRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/pty is deprecated.\", DeprecationWarning)\n\n        _param = self._create_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            pty_create_request=pty_create_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': \"PtyCreateResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_pty_session_deprecated_serialize(\n        self,\n        sandbox_id,\n        pty_create_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if pty_create_request is not None:\n            _body_params = pty_create_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/pty',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_session_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        create_session_request: CreateSessionRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Create session\n\n        Create a new session in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param create_session_request: (required)\n        :type create_session_request: CreateSessionRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/session is deprecated.\", DeprecationWarning)\n\n        _param = self._create_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            create_session_request=create_session_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_session_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        create_session_request: CreateSessionRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Create session\n\n        Create a new session in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param create_session_request: (required)\n        :type create_session_request: CreateSessionRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/session is deprecated.\", DeprecationWarning)\n\n        _param = self._create_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            create_session_request=create_session_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_session_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        create_session_request: CreateSessionRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Create session\n\n        Create a new session in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param create_session_request: (required)\n        :type create_session_request: CreateSessionRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/session is deprecated.\", DeprecationWarning)\n\n        _param = self._create_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            create_session_request=create_session_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_session_deprecated_serialize(\n        self,\n        sandbox_id,\n        create_session_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_session_request is not None:\n            _body_params = create_session_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/session',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_file_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        recursive: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Delete file\n\n        Delete file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param recursive:\n        :type recursive: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/files is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            recursive=recursive,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_file_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        recursive: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Delete file\n\n        Delete file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param recursive:\n        :type recursive: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/files is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            recursive=recursive,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_file_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        recursive: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Delete file\n\n        Delete file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param recursive:\n        :type recursive: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/files is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            recursive=recursive,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_file_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        x_daytona_organization_id,\n        recursive,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if recursive is not None:\n            \n            _query_params.append(('recursive', recursive))\n            \n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/toolbox/{sandboxId}/toolbox/files',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_pty_session_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Delete PTY session\n\n        Delete a PTY session and terminate the associated process\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/process/pty/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_pty_session_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Delete PTY session\n\n        Delete a PTY session and terminate the associated process\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/process/pty/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_pty_session_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Delete PTY session\n\n        Delete a PTY session and terminate the associated process\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/process/pty/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_pty_session_deprecated_serialize(\n        self,\n        sandbox_id,\n        session_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if session_id is not None:\n            _path_params['sessionId'] = session_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_session_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Delete session\n\n        Delete a specific session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/process/session/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_session_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Delete session\n\n        Delete a specific session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/process/session/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_session_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Delete session\n\n        Delete a specific session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/process/session/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_session_deprecated_serialize(\n        self,\n        sandbox_id,\n        session_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if session_id is not None:\n            _path_params['sessionId'] = session_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/session/{sessionId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def download_file_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> bytearray:\n        \"\"\"(Deprecated) [DEPRECATED] Download file\n\n        Download file from sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/download is deprecated.\", DeprecationWarning)\n\n        _param = self._download_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bytearray\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def download_file_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[bytearray]:\n        \"\"\"(Deprecated) [DEPRECATED] Download file\n\n        Download file from sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/download is deprecated.\", DeprecationWarning)\n\n        _param = self._download_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bytearray\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def download_file_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Download file\n\n        Download file from sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/download is deprecated.\", DeprecationWarning)\n\n        _param = self._download_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bytearray\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _download_file_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/download',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def download_files_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        download_files: DownloadFiles,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> bytearray:\n        \"\"\"(Deprecated) [DEPRECATED] Download multiple files\n\n        Streams back a multipart/form-data bundle of the requested paths\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param download_files: (required)\n        :type download_files: DownloadFiles\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/bulk-download is deprecated.\", DeprecationWarning)\n\n        _param = self._download_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            download_files=download_files,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bytearray\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def download_files_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        download_files: DownloadFiles,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[bytearray]:\n        \"\"\"(Deprecated) [DEPRECATED] Download multiple files\n\n        Streams back a multipart/form-data bundle of the requested paths\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param download_files: (required)\n        :type download_files: DownloadFiles\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/bulk-download is deprecated.\", DeprecationWarning)\n\n        _param = self._download_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            download_files=download_files,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bytearray\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def download_files_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        download_files: DownloadFiles,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Download multiple files\n\n        Streams back a multipart/form-data bundle of the requested paths\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param download_files: (required)\n        :type download_files: DownloadFiles\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/bulk-download is deprecated.\", DeprecationWarning)\n\n        _param = self._download_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            download_files=download_files,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"bytearray\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _download_files_deprecated_serialize(\n        self,\n        sandbox_id,\n        download_files,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if download_files is not None:\n            _body_params = download_files\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/bulk-download',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def drag_mouse_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        mouse_drag_request: MouseDragRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> MouseDragResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Drag mouse\n\n        Drag mouse from start to end coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_drag_request: (required)\n        :type mouse_drag_request: MouseDragRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/drag is deprecated.\", DeprecationWarning)\n\n        _param = self._drag_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_drag_request=mouse_drag_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseDragResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def drag_mouse_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        mouse_drag_request: MouseDragRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[MouseDragResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Drag mouse\n\n        Drag mouse from start to end coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_drag_request: (required)\n        :type mouse_drag_request: MouseDragRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/drag is deprecated.\", DeprecationWarning)\n\n        _param = self._drag_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_drag_request=mouse_drag_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseDragResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def drag_mouse_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        mouse_drag_request: MouseDragRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Drag mouse\n\n        Drag mouse from start to end coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_drag_request: (required)\n        :type mouse_drag_request: MouseDragRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/drag is deprecated.\", DeprecationWarning)\n\n        _param = self._drag_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_drag_request=mouse_drag_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseDragResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _drag_mouse_deprecated_serialize(\n        self,\n        sandbox_id,\n        mouse_drag_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if mouse_drag_request is not None:\n            _body_params = mouse_drag_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/mouse/drag',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def execute_command_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        execute_request: ExecuteRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ExecuteResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Execute command\n\n        Execute command synchronously inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param execute_request: (required)\n        :type execute_request: ExecuteRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/execute is deprecated.\", DeprecationWarning)\n\n        _param = self._execute_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            execute_request=execute_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ExecuteResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def execute_command_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        execute_request: ExecuteRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ExecuteResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Execute command\n\n        Execute command synchronously inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param execute_request: (required)\n        :type execute_request: ExecuteRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/execute is deprecated.\", DeprecationWarning)\n\n        _param = self._execute_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            execute_request=execute_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ExecuteResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def execute_command_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        execute_request: ExecuteRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Execute command\n\n        Execute command synchronously inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param execute_request: (required)\n        :type execute_request: ExecuteRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/execute is deprecated.\", DeprecationWarning)\n\n        _param = self._execute_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            execute_request=execute_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ExecuteResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _execute_command_deprecated_serialize(\n        self,\n        sandbox_id,\n        execute_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if execute_request is not None:\n            _body_params = execute_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/execute',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def execute_session_command_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        session_execute_request: SessionExecuteRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SessionExecuteResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Execute command in session\n\n        Execute a command in a specific session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param session_execute_request: (required)\n        :type session_execute_request: SessionExecuteRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/exec is deprecated.\", DeprecationWarning)\n\n        _param = self._execute_session_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            session_execute_request=session_execute_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SessionExecuteResponse\",\n            '202': \"SessionExecuteResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def execute_session_command_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        session_execute_request: SessionExecuteRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SessionExecuteResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Execute command in session\n\n        Execute a command in a specific session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param session_execute_request: (required)\n        :type session_execute_request: SessionExecuteRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/exec is deprecated.\", DeprecationWarning)\n\n        _param = self._execute_session_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            session_execute_request=session_execute_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SessionExecuteResponse\",\n            '202': \"SessionExecuteResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def execute_session_command_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        session_execute_request: SessionExecuteRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Execute command in session\n\n        Execute a command in a specific session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param session_execute_request: (required)\n        :type session_execute_request: SessionExecuteRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/exec is deprecated.\", DeprecationWarning)\n\n        _param = self._execute_session_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            session_execute_request=session_execute_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SessionExecuteResponse\",\n            '202': \"SessionExecuteResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _execute_session_command_deprecated_serialize(\n        self,\n        sandbox_id,\n        session_id,\n        session_execute_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if session_id is not None:\n            _path_params['sessionId'] = session_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if session_execute_request is not None:\n            _body_params = session_execute_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/exec',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def find_in_files_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        pattern: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Match]:\n        \"\"\"(Deprecated) [DEPRECATED] Search for text/pattern in files\n\n        Search for text/pattern inside sandbox files\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param pattern: (required)\n        :type pattern: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/find is deprecated.\", DeprecationWarning)\n\n        _param = self._find_in_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            pattern=pattern,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Match]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def find_in_files_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        pattern: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Match]]:\n        \"\"\"(Deprecated) [DEPRECATED] Search for text/pattern in files\n\n        Search for text/pattern inside sandbox files\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param pattern: (required)\n        :type pattern: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/find is deprecated.\", DeprecationWarning)\n\n        _param = self._find_in_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            pattern=pattern,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Match]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def find_in_files_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        pattern: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Search for text/pattern in files\n\n        Search for text/pattern inside sandbox files\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param pattern: (required)\n        :type pattern: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/find is deprecated.\", DeprecationWarning)\n\n        _param = self._find_in_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            pattern=pattern,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Match]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _find_in_files_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        pattern,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        if pattern is not None:\n            \n            _query_params.append(('pattern', pattern))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/find',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_computer_use_status_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ComputerUseStatusResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get computer use status\n\n        Get status of all VNC desktop processes\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/status is deprecated.\", DeprecationWarning)\n\n        _param = self._get_computer_use_status_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStatusResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_computer_use_status_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ComputerUseStatusResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get computer use status\n\n        Get status of all VNC desktop processes\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/status is deprecated.\", DeprecationWarning)\n\n        _param = self._get_computer_use_status_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStatusResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_computer_use_status_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get computer use status\n\n        Get status of all VNC desktop processes\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/status is deprecated.\", DeprecationWarning)\n\n        _param = self._get_computer_use_status_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStatusResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_computer_use_status_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/status',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_display_info_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> DisplayInfoResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get display info\n\n        Get information about displays\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/display/info is deprecated.\", DeprecationWarning)\n\n        _param = self._get_display_info_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DisplayInfoResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_display_info_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[DisplayInfoResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get display info\n\n        Get information about displays\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/display/info is deprecated.\", DeprecationWarning)\n\n        _param = self._get_display_info_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DisplayInfoResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_display_info_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get display info\n\n        Get information about displays\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/display/info is deprecated.\", DeprecationWarning)\n\n        _param = self._get_display_info_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"DisplayInfoResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_display_info_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/display/info',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_file_info_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> FileInfo:\n        \"\"\"(Deprecated) [DEPRECATED] Get file info\n\n        Get file info inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/info is deprecated.\", DeprecationWarning)\n\n        _param = self._get_file_info_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"FileInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_file_info_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[FileInfo]:\n        \"\"\"(Deprecated) [DEPRECATED] Get file info\n\n        Get file info inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/info is deprecated.\", DeprecationWarning)\n\n        _param = self._get_file_info_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"FileInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_file_info_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get file info\n\n        Get file info inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/info is deprecated.\", DeprecationWarning)\n\n        _param = self._get_file_info_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"FileInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_file_info_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/info',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_mouse_position_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> MousePosition:\n        \"\"\"(Deprecated) [DEPRECATED] Get mouse position\n\n        Get current mouse cursor position\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/mouse/position is deprecated.\", DeprecationWarning)\n\n        _param = self._get_mouse_position_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MousePosition\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_mouse_position_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[MousePosition]:\n        \"\"\"(Deprecated) [DEPRECATED] Get mouse position\n\n        Get current mouse cursor position\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/mouse/position is deprecated.\", DeprecationWarning)\n\n        _param = self._get_mouse_position_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MousePosition\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_mouse_position_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get mouse position\n\n        Get current mouse cursor position\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/mouse/position is deprecated.\", DeprecationWarning)\n\n        _param = self._get_mouse_position_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MousePosition\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_mouse_position_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/mouse/position',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_process_errors_deprecated(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ProcessErrorsResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get process errors\n\n        Get error logs for a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/errors is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_errors_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessErrorsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_process_errors_deprecated_with_http_info(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ProcessErrorsResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get process errors\n\n        Get error logs for a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/errors is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_errors_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessErrorsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_process_errors_deprecated_without_preload_content(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get process errors\n\n        Get error logs for a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/errors is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_errors_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessErrorsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_process_errors_deprecated_serialize(\n        self,\n        process_name,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if process_name is not None:\n            _path_params['processName'] = process_name\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/errors',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_process_logs_deprecated(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ProcessLogsResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get process logs\n\n        Get logs for a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_logs_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessLogsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_process_logs_deprecated_with_http_info(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ProcessLogsResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get process logs\n\n        Get logs for a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_logs_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessLogsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_process_logs_deprecated_without_preload_content(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get process logs\n\n        Get logs for a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_logs_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessLogsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_process_logs_deprecated_serialize(\n        self,\n        process_name,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if process_name is not None:\n            _path_params['processName'] = process_name\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/logs',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_process_status_deprecated(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ProcessStatusResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get process status\n\n        Get status of a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/status is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_status_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessStatusResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_process_status_deprecated_with_http_info(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ProcessStatusResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get process status\n\n        Get status of a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/status is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_status_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessStatusResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_process_status_deprecated_without_preload_content(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get process status\n\n        Get status of a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/status is deprecated.\", DeprecationWarning)\n\n        _param = self._get_process_status_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessStatusResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_process_status_deprecated_serialize(\n        self,\n        process_name,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if process_name is not None:\n            _path_params['processName'] = process_name\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/status',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_project_dir_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ProjectDirResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox project dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/project-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_project_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProjectDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_project_dir_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ProjectDirResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox project dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/project-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_project_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProjectDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_project_dir_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox project dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/project-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_project_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProjectDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_project_dir_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/project-dir',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_pty_session_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PtySessionInfo:\n        \"\"\"(Deprecated) [DEPRECATED] Get PTY session\n\n        Get PTY session information by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/pty/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtySessionInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_pty_session_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PtySessionInfo]:\n        \"\"\"(Deprecated) [DEPRECATED] Get PTY session\n\n        Get PTY session information by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/pty/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtySessionInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_pty_session_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get PTY session\n\n        Get PTY session information by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/pty/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtySessionInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_pty_session_deprecated_serialize(\n        self,\n        sandbox_id,\n        session_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if session_id is not None:\n            _path_params['sessionId'] = session_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_session_command_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        command_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Command:\n        \"\"\"(Deprecated) [DEPRECATED] Get session command\n\n        Get session command by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param command_id: (required)\n        :type command_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            command_id=command_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Command\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_session_command_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        command_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Command]:\n        \"\"\"(Deprecated) [DEPRECATED] Get session command\n\n        Get session command by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param command_id: (required)\n        :type command_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            command_id=command_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Command\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_session_command_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        command_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get session command\n\n        Get session command by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param command_id: (required)\n        :type command_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_command_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            command_id=command_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Command\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_session_command_deprecated_serialize(\n        self,\n        sandbox_id,\n        session_id,\n        command_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if session_id is not None:\n            _path_params['sessionId'] = session_id\n        if command_id is not None:\n            _path_params['commandId'] = command_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_session_command_logs_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        command_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to stream the logs\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> str:\n        \"\"\"(Deprecated) [DEPRECATED] Get command logs\n\n        Get logs for a specific command in a session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param command_id: (required)\n        :type command_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to stream the logs\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}/logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_command_logs_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            command_id=command_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_session_command_logs_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        command_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to stream the logs\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[str]:\n        \"\"\"(Deprecated) [DEPRECATED] Get command logs\n\n        Get logs for a specific command in a session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param command_id: (required)\n        :type command_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to stream the logs\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}/logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_command_logs_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            command_id=command_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_session_command_logs_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        command_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to stream the logs\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get command logs\n\n        Get logs for a specific command in a session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param command_id: (required)\n        :type command_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to stream the logs\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}/logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_command_logs_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            command_id=command_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_session_command_logs_deprecated_serialize(\n        self,\n        sandbox_id,\n        session_id,\n        command_id,\n        x_daytona_organization_id,\n        follow,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if session_id is not None:\n            _path_params['sessionId'] = session_id\n        if command_id is not None:\n            _path_params['commandId'] = command_id\n        # process the query parameters\n        if follow is not None:\n            \n            _query_params.append(('follow', follow))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'text/plain'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/session/{sessionId}/command/{commandId}/logs',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_session_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Session:\n        \"\"\"(Deprecated) [DEPRECATED] Get session\n\n        Get session by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Session\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_session_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Session]:\n        \"\"\"(Deprecated) [DEPRECATED] Get session\n\n        Get session by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Session\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_session_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get session\n\n        Get session by ID\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session/{sessionId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Session\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_session_deprecated_serialize(\n        self,\n        sandbox_id,\n        session_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if session_id is not None:\n            _path_params['sessionId'] = session_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/session/{sessionId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_user_home_dir_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> UserHomeDirResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox user home dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/user-home-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_user_home_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"UserHomeDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_user_home_dir_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[UserHomeDirResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox user home dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/user-home-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_user_home_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"UserHomeDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_user_home_dir_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox user home dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/user-home-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_user_home_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"UserHomeDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_user_home_dir_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/user-home-dir',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_windows_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> WindowsResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get windows\n\n        Get list of open windows\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/display/windows is deprecated.\", DeprecationWarning)\n\n        _param = self._get_windows_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WindowsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_windows_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[WindowsResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get windows\n\n        Get list of open windows\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/display/windows is deprecated.\", DeprecationWarning)\n\n        _param = self._get_windows_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WindowsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_windows_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get windows\n\n        Get list of open windows\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/display/windows is deprecated.\", DeprecationWarning)\n\n        _param = self._get_windows_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WindowsResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_windows_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/display/windows',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_work_dir_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> WorkDirResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox work-dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/work-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_work_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WorkDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_work_dir_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[WorkDirResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox work-dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/work-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_work_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WorkDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_work_dir_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get sandbox work-dir\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/work-dir is deprecated.\", DeprecationWarning)\n\n        _param = self._get_work_dir_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WorkDirResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_work_dir_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/work-dir',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_add_files_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        git_add_request: GitAddRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Add files\n\n        Add files to git commit\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_add_request: (required)\n        :type git_add_request: GitAddRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/add is deprecated.\", DeprecationWarning)\n\n        _param = self._git_add_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_add_request=git_add_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_add_files_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        git_add_request: GitAddRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Add files\n\n        Add files to git commit\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_add_request: (required)\n        :type git_add_request: GitAddRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/add is deprecated.\", DeprecationWarning)\n\n        _param = self._git_add_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_add_request=git_add_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_add_files_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        git_add_request: GitAddRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Add files\n\n        Add files to git commit\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_add_request: (required)\n        :type git_add_request: GitAddRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/add is deprecated.\", DeprecationWarning)\n\n        _param = self._git_add_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_add_request=git_add_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_add_files_deprecated_serialize(\n        self,\n        sandbox_id,\n        git_add_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if git_add_request is not None:\n            _body_params = git_add_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/add',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_checkout_branch_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        git_checkout_request: GitCheckoutRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Checkout branch\n\n        Checkout branch or commit in git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_checkout_request: (required)\n        :type git_checkout_request: GitCheckoutRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/checkout is deprecated.\", DeprecationWarning)\n\n        _param = self._git_checkout_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_checkout_request=git_checkout_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_checkout_branch_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        git_checkout_request: GitCheckoutRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Checkout branch\n\n        Checkout branch or commit in git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_checkout_request: (required)\n        :type git_checkout_request: GitCheckoutRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/checkout is deprecated.\", DeprecationWarning)\n\n        _param = self._git_checkout_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_checkout_request=git_checkout_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_checkout_branch_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        git_checkout_request: GitCheckoutRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Checkout branch\n\n        Checkout branch or commit in git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_checkout_request: (required)\n        :type git_checkout_request: GitCheckoutRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/checkout is deprecated.\", DeprecationWarning)\n\n        _param = self._git_checkout_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_checkout_request=git_checkout_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_checkout_branch_deprecated_serialize(\n        self,\n        sandbox_id,\n        git_checkout_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if git_checkout_request is not None:\n            _body_params = git_checkout_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/checkout',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_clone_repository_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        git_clone_request: GitCloneRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Clone repository\n\n        Clone git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_clone_request: (required)\n        :type git_clone_request: GitCloneRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/clone is deprecated.\", DeprecationWarning)\n\n        _param = self._git_clone_repository_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_clone_request=git_clone_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_clone_repository_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        git_clone_request: GitCloneRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Clone repository\n\n        Clone git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_clone_request: (required)\n        :type git_clone_request: GitCloneRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/clone is deprecated.\", DeprecationWarning)\n\n        _param = self._git_clone_repository_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_clone_request=git_clone_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_clone_repository_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        git_clone_request: GitCloneRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Clone repository\n\n        Clone git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_clone_request: (required)\n        :type git_clone_request: GitCloneRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/clone is deprecated.\", DeprecationWarning)\n\n        _param = self._git_clone_repository_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_clone_request=git_clone_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_clone_repository_deprecated_serialize(\n        self,\n        sandbox_id,\n        git_clone_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if git_clone_request is not None:\n            _body_params = git_clone_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/clone',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_commit_changes_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        git_commit_request: GitCommitRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> GitCommitResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Commit changes\n\n        Commit changes to git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_commit_request: (required)\n        :type git_commit_request: GitCommitRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/commit is deprecated.\", DeprecationWarning)\n\n        _param = self._git_commit_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_commit_request=git_commit_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"GitCommitResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_commit_changes_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        git_commit_request: GitCommitRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[GitCommitResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Commit changes\n\n        Commit changes to git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_commit_request: (required)\n        :type git_commit_request: GitCommitRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/commit is deprecated.\", DeprecationWarning)\n\n        _param = self._git_commit_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_commit_request=git_commit_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"GitCommitResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_commit_changes_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        git_commit_request: GitCommitRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Commit changes\n\n        Commit changes to git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_commit_request: (required)\n        :type git_commit_request: GitCommitRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/commit is deprecated.\", DeprecationWarning)\n\n        _param = self._git_commit_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_commit_request=git_commit_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"GitCommitResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_commit_changes_deprecated_serialize(\n        self,\n        sandbox_id,\n        git_commit_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if git_commit_request is not None:\n            _body_params = git_commit_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/commit',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_create_branch_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        git_branch_request: GitBranchRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Create branch\n\n        Create branch on git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_branch_request: (required)\n        :type git_branch_request: GitBranchRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_create_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_branch_request=git_branch_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_create_branch_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        git_branch_request: GitBranchRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Create branch\n\n        Create branch on git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_branch_request: (required)\n        :type git_branch_request: GitBranchRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_create_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_branch_request=git_branch_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_create_branch_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        git_branch_request: GitBranchRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Create branch\n\n        Create branch on git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_branch_request: (required)\n        :type git_branch_request: GitBranchRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_create_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_branch_request=git_branch_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_create_branch_deprecated_serialize(\n        self,\n        sandbox_id,\n        git_branch_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if git_branch_request is not None:\n            _body_params = git_branch_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/branches',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_delete_branch_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        git_delete_branch_request: GitDeleteBranchRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Delete branch\n\n        Delete branch on git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_delete_branch_request: (required)\n        :type git_delete_branch_request: GitDeleteBranchRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_delete_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_delete_branch_request=git_delete_branch_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_delete_branch_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        git_delete_branch_request: GitDeleteBranchRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Delete branch\n\n        Delete branch on git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_delete_branch_request: (required)\n        :type git_delete_branch_request: GitDeleteBranchRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_delete_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_delete_branch_request=git_delete_branch_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_delete_branch_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        git_delete_branch_request: GitDeleteBranchRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Delete branch\n\n        Delete branch on git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_delete_branch_request: (required)\n        :type git_delete_branch_request: GitDeleteBranchRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_delete_branch_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_delete_branch_request=git_delete_branch_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_delete_branch_deprecated_serialize(\n        self,\n        sandbox_id,\n        git_delete_branch_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if git_delete_branch_request is not None:\n            _body_params = git_delete_branch_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/branches',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_get_history_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[GitCommitInfo]:\n        \"\"\"(Deprecated) [DEPRECATED] Get commit history\n\n        Get commit history from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/history is deprecated.\", DeprecationWarning)\n\n        _param = self._git_get_history_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[GitCommitInfo]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_get_history_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[GitCommitInfo]]:\n        \"\"\"(Deprecated) [DEPRECATED] Get commit history\n\n        Get commit history from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/history is deprecated.\", DeprecationWarning)\n\n        _param = self._git_get_history_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[GitCommitInfo]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_get_history_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get commit history\n\n        Get commit history from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/history is deprecated.\", DeprecationWarning)\n\n        _param = self._git_get_history_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[GitCommitInfo]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_get_history_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/history',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_get_status_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> GitStatus:\n        \"\"\"(Deprecated) [DEPRECATED] Get git status\n\n        Get status from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/status is deprecated.\", DeprecationWarning)\n\n        _param = self._git_get_status_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"GitStatus\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_get_status_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[GitStatus]:\n        \"\"\"(Deprecated) [DEPRECATED] Get git status\n\n        Get status from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/status is deprecated.\", DeprecationWarning)\n\n        _param = self._git_get_status_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"GitStatus\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_get_status_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get git status\n\n        Get status from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/status is deprecated.\", DeprecationWarning)\n\n        _param = self._git_get_status_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"GitStatus\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_get_status_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/status',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_list_branches_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ListBranchResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Get branch list\n\n        Get branch list from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_list_branches_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ListBranchResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_list_branches_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ListBranchResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Get branch list\n\n        Get branch list from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_list_branches_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ListBranchResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_list_branches_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get branch list\n\n        Get branch list from git repository\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/git/branches is deprecated.\", DeprecationWarning)\n\n        _param = self._git_list_branches_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ListBranchResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_list_branches_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/branches',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_pull_changes_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        git_repo_request: GitRepoRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Pull changes\n\n        Pull changes from remote\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_repo_request: (required)\n        :type git_repo_request: GitRepoRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/pull is deprecated.\", DeprecationWarning)\n\n        _param = self._git_pull_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_repo_request=git_repo_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_pull_changes_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        git_repo_request: GitRepoRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Pull changes\n\n        Pull changes from remote\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_repo_request: (required)\n        :type git_repo_request: GitRepoRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/pull is deprecated.\", DeprecationWarning)\n\n        _param = self._git_pull_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_repo_request=git_repo_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_pull_changes_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        git_repo_request: GitRepoRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Pull changes\n\n        Pull changes from remote\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_repo_request: (required)\n        :type git_repo_request: GitRepoRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/pull is deprecated.\", DeprecationWarning)\n\n        _param = self._git_pull_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_repo_request=git_repo_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_pull_changes_deprecated_serialize(\n        self,\n        sandbox_id,\n        git_repo_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if git_repo_request is not None:\n            _body_params = git_repo_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/pull',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def git_push_changes_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        git_repo_request: GitRepoRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Push changes\n\n        Push changes to remote\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_repo_request: (required)\n        :type git_repo_request: GitRepoRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/push is deprecated.\", DeprecationWarning)\n\n        _param = self._git_push_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_repo_request=git_repo_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def git_push_changes_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        git_repo_request: GitRepoRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Push changes\n\n        Push changes to remote\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_repo_request: (required)\n        :type git_repo_request: GitRepoRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/push is deprecated.\", DeprecationWarning)\n\n        _param = self._git_push_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_repo_request=git_repo_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def git_push_changes_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        git_repo_request: GitRepoRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Push changes\n\n        Push changes to remote\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param git_repo_request: (required)\n        :type git_repo_request: GitRepoRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/git/push is deprecated.\", DeprecationWarning)\n\n        _param = self._git_push_changes_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            git_repo_request=git_repo_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _git_push_changes_deprecated_serialize(\n        self,\n        sandbox_id,\n        git_repo_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if git_repo_request is not None:\n            _body_params = git_repo_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/git/push',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_files_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        path: Optional[StrictStr] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[FileInfo]:\n        \"\"\"(Deprecated) [DEPRECATED] List files\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param path:\n        :type path: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files is deprecated.\", DeprecationWarning)\n\n        _param = self._list_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            path=path,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[FileInfo]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_files_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        path: Optional[StrictStr] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[FileInfo]]:\n        \"\"\"(Deprecated) [DEPRECATED] List files\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param path:\n        :type path: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files is deprecated.\", DeprecationWarning)\n\n        _param = self._list_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            path=path,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[FileInfo]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_files_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        path: Optional[StrictStr] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] List files\n\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param path:\n        :type path: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files is deprecated.\", DeprecationWarning)\n\n        _param = self._list_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            path=path,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[FileInfo]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_files_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        path,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/files',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_pty_sessions_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PtyListResponse:\n        \"\"\"(Deprecated) [DEPRECATED] List PTY sessions\n\n        List all active PTY sessions in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/pty is deprecated.\", DeprecationWarning)\n\n        _param = self._list_pty_sessions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtyListResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_pty_sessions_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PtyListResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] List PTY sessions\n\n        List all active PTY sessions in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/pty is deprecated.\", DeprecationWarning)\n\n        _param = self._list_pty_sessions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtyListResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_pty_sessions_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] List PTY sessions\n\n        List all active PTY sessions in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/pty is deprecated.\", DeprecationWarning)\n\n        _param = self._list_pty_sessions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtyListResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_pty_sessions_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/pty',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_sessions_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Session]:\n        \"\"\"(Deprecated) [DEPRECATED] List sessions\n\n        List all active sessions in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session is deprecated.\", DeprecationWarning)\n\n        _param = self._list_sessions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Session]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_sessions_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Session]]:\n        \"\"\"(Deprecated) [DEPRECATED] List sessions\n\n        List all active sessions in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session is deprecated.\", DeprecationWarning)\n\n        _param = self._list_sessions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Session]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_sessions_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] List sessions\n\n        List all active sessions in the sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/process/session is deprecated.\", DeprecationWarning)\n\n        _param = self._list_sessions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Session]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_sessions_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/session',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def lsp_completions_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        lsp_completion_params: LspCompletionParams,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> CompletionList:\n        \"\"\"(Deprecated) [DEPRECATED] Get Lsp Completions\n\n        The Completion request is sent from the client to the server to compute completion items at a given cursor position.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_completion_params: (required)\n        :type lsp_completion_params: LspCompletionParams\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/completions is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_completions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_completion_params=lsp_completion_params,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompletionList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def lsp_completions_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        lsp_completion_params: LspCompletionParams,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[CompletionList]:\n        \"\"\"(Deprecated) [DEPRECATED] Get Lsp Completions\n\n        The Completion request is sent from the client to the server to compute completion items at a given cursor position.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_completion_params: (required)\n        :type lsp_completion_params: LspCompletionParams\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/completions is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_completions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_completion_params=lsp_completion_params,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompletionList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def lsp_completions_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        lsp_completion_params: LspCompletionParams,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get Lsp Completions\n\n        The Completion request is sent from the client to the server to compute completion items at a given cursor position.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_completion_params: (required)\n        :type lsp_completion_params: LspCompletionParams\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/completions is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_completions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_completion_params=lsp_completion_params,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompletionList\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _lsp_completions_deprecated_serialize(\n        self,\n        sandbox_id,\n        lsp_completion_params,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if lsp_completion_params is not None:\n            _body_params = lsp_completion_params\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/lsp/completions',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def lsp_did_close_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        lsp_document_request: LspDocumentRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DidClose\n\n        The document close notification is sent from the client to the server when the document got closed in the client.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_document_request: (required)\n        :type lsp_document_request: LspDocumentRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/did-close is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_did_close_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_document_request=lsp_document_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def lsp_did_close_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        lsp_document_request: LspDocumentRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DidClose\n\n        The document close notification is sent from the client to the server when the document got closed in the client.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_document_request: (required)\n        :type lsp_document_request: LspDocumentRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/did-close is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_did_close_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_document_request=lsp_document_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def lsp_did_close_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        lsp_document_request: LspDocumentRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DidClose\n\n        The document close notification is sent from the client to the server when the document got closed in the client.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_document_request: (required)\n        :type lsp_document_request: LspDocumentRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/did-close is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_did_close_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_document_request=lsp_document_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _lsp_did_close_deprecated_serialize(\n        self,\n        sandbox_id,\n        lsp_document_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if lsp_document_request is not None:\n            _body_params = lsp_document_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/lsp/did-close',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def lsp_did_open_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        lsp_document_request: LspDocumentRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DidOpen\n\n        The document open notification is sent from the client to the server to signal newly opened text documents.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_document_request: (required)\n        :type lsp_document_request: LspDocumentRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/did-open is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_did_open_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_document_request=lsp_document_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def lsp_did_open_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        lsp_document_request: LspDocumentRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DidOpen\n\n        The document open notification is sent from the client to the server to signal newly opened text documents.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_document_request: (required)\n        :type lsp_document_request: LspDocumentRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/did-open is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_did_open_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_document_request=lsp_document_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def lsp_did_open_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        lsp_document_request: LspDocumentRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DidOpen\n\n        The document open notification is sent from the client to the server to signal newly opened text documents.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_document_request: (required)\n        :type lsp_document_request: LspDocumentRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/did-open is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_did_open_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_document_request=lsp_document_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _lsp_did_open_deprecated_serialize(\n        self,\n        sandbox_id,\n        lsp_document_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if lsp_document_request is not None:\n            _body_params = lsp_document_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/lsp/did-open',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def lsp_document_symbols_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        language_id: StrictStr,\n        path_to_project: StrictStr,\n        uri: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[LspSymbol]:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DocumentSymbols\n\n        The document symbol request is sent from the client to the server.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param language_id: (required)\n        :type language_id: str\n        :param path_to_project: (required)\n        :type path_to_project: str\n        :param uri: (required)\n        :type uri: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/lsp/document-symbols is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_document_symbols_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            language_id=language_id,\n            path_to_project=path_to_project,\n            uri=uri,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[LspSymbol]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def lsp_document_symbols_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        language_id: StrictStr,\n        path_to_project: StrictStr,\n        uri: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[LspSymbol]]:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DocumentSymbols\n\n        The document symbol request is sent from the client to the server.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param language_id: (required)\n        :type language_id: str\n        :param path_to_project: (required)\n        :type path_to_project: str\n        :param uri: (required)\n        :type uri: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/lsp/document-symbols is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_document_symbols_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            language_id=language_id,\n            path_to_project=path_to_project,\n            uri=uri,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[LspSymbol]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def lsp_document_symbols_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        language_id: StrictStr,\n        path_to_project: StrictStr,\n        uri: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp DocumentSymbols\n\n        The document symbol request is sent from the client to the server.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param language_id: (required)\n        :type language_id: str\n        :param path_to_project: (required)\n        :type path_to_project: str\n        :param uri: (required)\n        :type uri: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/lsp/document-symbols is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_document_symbols_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            language_id=language_id,\n            path_to_project=path_to_project,\n            uri=uri,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[LspSymbol]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _lsp_document_symbols_deprecated_serialize(\n        self,\n        sandbox_id,\n        language_id,\n        path_to_project,\n        uri,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if language_id is not None:\n            \n            _query_params.append(('languageId', language_id))\n            \n        if path_to_project is not None:\n            \n            _query_params.append(('pathToProject', path_to_project))\n            \n        if uri is not None:\n            \n            _query_params.append(('uri', uri))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/lsp/document-symbols',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def lsp_start_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        lsp_server_request: LspServerRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Start Lsp server\n\n        Start Lsp server process inside sandbox project\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_server_request: (required)\n        :type lsp_server_request: LspServerRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/start is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_start_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_server_request=lsp_server_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def lsp_start_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        lsp_server_request: LspServerRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Start Lsp server\n\n        Start Lsp server process inside sandbox project\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_server_request: (required)\n        :type lsp_server_request: LspServerRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/start is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_start_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_server_request=lsp_server_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def lsp_start_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        lsp_server_request: LspServerRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Start Lsp server\n\n        Start Lsp server process inside sandbox project\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_server_request: (required)\n        :type lsp_server_request: LspServerRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/start is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_start_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_server_request=lsp_server_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _lsp_start_deprecated_serialize(\n        self,\n        sandbox_id,\n        lsp_server_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if lsp_server_request is not None:\n            _body_params = lsp_server_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/lsp/start',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def lsp_stop_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        lsp_server_request: LspServerRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Stop Lsp server\n\n        Stop Lsp server process inside sandbox project\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_server_request: (required)\n        :type lsp_server_request: LspServerRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_stop_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_server_request=lsp_server_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def lsp_stop_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        lsp_server_request: LspServerRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Stop Lsp server\n\n        Stop Lsp server process inside sandbox project\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_server_request: (required)\n        :type lsp_server_request: LspServerRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_stop_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_server_request=lsp_server_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def lsp_stop_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        lsp_server_request: LspServerRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Stop Lsp server\n\n        Stop Lsp server process inside sandbox project\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param lsp_server_request: (required)\n        :type lsp_server_request: LspServerRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/lsp/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_stop_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            lsp_server_request=lsp_server_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _lsp_stop_deprecated_serialize(\n        self,\n        sandbox_id,\n        lsp_server_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if lsp_server_request is not None:\n            _body_params = lsp_server_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/lsp/stop',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def lsp_workspace_symbols_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        language_id: StrictStr,\n        path_to_project: StrictStr,\n        query: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[LspSymbol]:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp WorkspaceSymbols\n\n        The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param language_id: (required)\n        :type language_id: str\n        :param path_to_project: (required)\n        :type path_to_project: str\n        :param query: (required)\n        :type query: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/lsp/workspace-symbols is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_workspace_symbols_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            language_id=language_id,\n            path_to_project=path_to_project,\n            query=query,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[LspSymbol]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def lsp_workspace_symbols_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        language_id: StrictStr,\n        path_to_project: StrictStr,\n        query: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[LspSymbol]]:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp WorkspaceSymbols\n\n        The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param language_id: (required)\n        :type language_id: str\n        :param path_to_project: (required)\n        :type path_to_project: str\n        :param query: (required)\n        :type query: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/lsp/workspace-symbols is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_workspace_symbols_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            language_id=language_id,\n            path_to_project=path_to_project,\n            query=query,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[LspSymbol]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def lsp_workspace_symbols_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        language_id: StrictStr,\n        path_to_project: StrictStr,\n        query: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Call Lsp WorkspaceSymbols\n\n        The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param language_id: (required)\n        :type language_id: str\n        :param path_to_project: (required)\n        :type path_to_project: str\n        :param query: (required)\n        :type query: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/lsp/workspace-symbols is deprecated.\", DeprecationWarning)\n\n        _param = self._lsp_workspace_symbols_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            language_id=language_id,\n            path_to_project=path_to_project,\n            query=query,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[LspSymbol]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _lsp_workspace_symbols_deprecated_serialize(\n        self,\n        sandbox_id,\n        language_id,\n        path_to_project,\n        query,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if language_id is not None:\n            \n            _query_params.append(('languageId', language_id))\n            \n        if path_to_project is not None:\n            \n            _query_params.append(('pathToProject', path_to_project))\n            \n        if query is not None:\n            \n            _query_params.append(('query', query))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/lsp/workspace-symbols',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def move_file_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        source: StrictStr,\n        destination: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Move file\n\n        Move file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param source: (required)\n        :type source: str\n        :param destination: (required)\n        :type destination: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/move is deprecated.\", DeprecationWarning)\n\n        _param = self._move_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            source=source,\n            destination=destination,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def move_file_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        source: StrictStr,\n        destination: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Move file\n\n        Move file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param source: (required)\n        :type source: str\n        :param destination: (required)\n        :type destination: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/move is deprecated.\", DeprecationWarning)\n\n        _param = self._move_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            source=source,\n            destination=destination,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def move_file_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        source: StrictStr,\n        destination: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Move file\n\n        Move file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param source: (required)\n        :type source: str\n        :param destination: (required)\n        :type destination: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/move is deprecated.\", DeprecationWarning)\n\n        _param = self._move_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            source=source,\n            destination=destination,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _move_file_deprecated_serialize(\n        self,\n        sandbox_id,\n        source,\n        destination,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if source is not None:\n            \n            _query_params.append(('source', source))\n            \n        if destination is not None:\n            \n            _query_params.append(('destination', destination))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/move',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def move_mouse_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        mouse_move_request: MouseMoveRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> MouseMoveResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Move mouse\n\n        Move mouse cursor to specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_move_request: (required)\n        :type mouse_move_request: MouseMoveRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/move is deprecated.\", DeprecationWarning)\n\n        _param = self._move_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_move_request=mouse_move_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseMoveResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def move_mouse_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        mouse_move_request: MouseMoveRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[MouseMoveResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Move mouse\n\n        Move mouse cursor to specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_move_request: (required)\n        :type mouse_move_request: MouseMoveRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/move is deprecated.\", DeprecationWarning)\n\n        _param = self._move_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_move_request=mouse_move_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseMoveResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def move_mouse_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        mouse_move_request: MouseMoveRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Move mouse\n\n        Move mouse cursor to specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_move_request: (required)\n        :type mouse_move_request: MouseMoveRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/move is deprecated.\", DeprecationWarning)\n\n        _param = self._move_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_move_request=mouse_move_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseMoveResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _move_mouse_deprecated_serialize(\n        self,\n        sandbox_id,\n        mouse_move_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if mouse_move_request is not None:\n            _body_params = mouse_move_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/mouse/move',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def press_hotkey_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_hotkey_request: KeyboardHotkeyRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Press hotkey\n\n        Press a hotkey combination\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_hotkey_request: (required)\n        :type keyboard_hotkey_request: KeyboardHotkeyRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/hotkey is deprecated.\", DeprecationWarning)\n\n        _param = self._press_hotkey_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_hotkey_request=keyboard_hotkey_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def press_hotkey_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_hotkey_request: KeyboardHotkeyRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Press hotkey\n\n        Press a hotkey combination\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_hotkey_request: (required)\n        :type keyboard_hotkey_request: KeyboardHotkeyRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/hotkey is deprecated.\", DeprecationWarning)\n\n        _param = self._press_hotkey_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_hotkey_request=keyboard_hotkey_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def press_hotkey_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_hotkey_request: KeyboardHotkeyRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Press hotkey\n\n        Press a hotkey combination\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_hotkey_request: (required)\n        :type keyboard_hotkey_request: KeyboardHotkeyRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/hotkey is deprecated.\", DeprecationWarning)\n\n        _param = self._press_hotkey_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_hotkey_request=keyboard_hotkey_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _press_hotkey_deprecated_serialize(\n        self,\n        sandbox_id,\n        keyboard_hotkey_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if keyboard_hotkey_request is not None:\n            _body_params = keyboard_hotkey_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/keyboard/hotkey',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def press_key_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_press_request: KeyboardPressRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Press key\n\n        Press a key with optional modifiers\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_press_request: (required)\n        :type keyboard_press_request: KeyboardPressRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/key is deprecated.\", DeprecationWarning)\n\n        _param = self._press_key_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_press_request=keyboard_press_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def press_key_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_press_request: KeyboardPressRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Press key\n\n        Press a key with optional modifiers\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_press_request: (required)\n        :type keyboard_press_request: KeyboardPressRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/key is deprecated.\", DeprecationWarning)\n\n        _param = self._press_key_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_press_request=keyboard_press_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def press_key_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_press_request: KeyboardPressRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Press key\n\n        Press a key with optional modifiers\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_press_request: (required)\n        :type keyboard_press_request: KeyboardPressRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/key is deprecated.\", DeprecationWarning)\n\n        _param = self._press_key_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_press_request=keyboard_press_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _press_key_deprecated_serialize(\n        self,\n        sandbox_id,\n        keyboard_press_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if keyboard_press_request is not None:\n            _body_params = keyboard_press_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/keyboard/key',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def replace_in_files_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        replace_request: ReplaceRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[ReplaceResult]:\n        \"\"\"(Deprecated) [DEPRECATED] Replace in files\n\n        Replace text/pattern in multiple files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param replace_request: (required)\n        :type replace_request: ReplaceRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/replace is deprecated.\", DeprecationWarning)\n\n        _param = self._replace_in_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            replace_request=replace_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[ReplaceResult]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def replace_in_files_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        replace_request: ReplaceRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[ReplaceResult]]:\n        \"\"\"(Deprecated) [DEPRECATED] Replace in files\n\n        Replace text/pattern in multiple files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param replace_request: (required)\n        :type replace_request: ReplaceRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/replace is deprecated.\", DeprecationWarning)\n\n        _param = self._replace_in_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            replace_request=replace_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[ReplaceResult]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def replace_in_files_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        replace_request: ReplaceRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Replace in files\n\n        Replace text/pattern in multiple files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param replace_request: (required)\n        :type replace_request: ReplaceRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/replace is deprecated.\", DeprecationWarning)\n\n        _param = self._replace_in_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            replace_request=replace_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[ReplaceResult]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _replace_in_files_deprecated_serialize(\n        self,\n        sandbox_id,\n        replace_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if replace_request is not None:\n            _body_params = replace_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/replace',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def resize_pty_session_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        pty_resize_request: PtyResizeRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> PtySessionInfo:\n        \"\"\"(Deprecated) [DEPRECATED] Resize PTY session\n\n        Resize a PTY session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param pty_resize_request: (required)\n        :type pty_resize_request: PtyResizeRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/pty/{sessionId}/resize is deprecated.\", DeprecationWarning)\n\n        _param = self._resize_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            pty_resize_request=pty_resize_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtySessionInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def resize_pty_session_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        pty_resize_request: PtyResizeRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[PtySessionInfo]:\n        \"\"\"(Deprecated) [DEPRECATED] Resize PTY session\n\n        Resize a PTY session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param pty_resize_request: (required)\n        :type pty_resize_request: PtyResizeRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/pty/{sessionId}/resize is deprecated.\", DeprecationWarning)\n\n        _param = self._resize_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            pty_resize_request=pty_resize_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtySessionInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def resize_pty_session_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        session_id: StrictStr,\n        pty_resize_request: PtyResizeRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Resize PTY session\n\n        Resize a PTY session\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param session_id: (required)\n        :type session_id: str\n        :param pty_resize_request: (required)\n        :type pty_resize_request: PtyResizeRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/process/pty/{sessionId}/resize is deprecated.\", DeprecationWarning)\n\n        _param = self._resize_pty_session_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            session_id=session_id,\n            pty_resize_request=pty_resize_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"PtySessionInfo\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _resize_pty_session_deprecated_serialize(\n        self,\n        sandbox_id,\n        session_id,\n        pty_resize_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        if session_id is not None:\n            _path_params['sessionId'] = session_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if pty_resize_request is not None:\n            _body_params = pty_resize_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/process/pty/{sessionId}/resize',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def restart_process_deprecated(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ProcessRestartResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Restart process\n\n        Restart a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/restart is deprecated.\", DeprecationWarning)\n\n        _param = self._restart_process_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessRestartResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def restart_process_deprecated_with_http_info(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ProcessRestartResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Restart process\n\n        Restart a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/restart is deprecated.\", DeprecationWarning)\n\n        _param = self._restart_process_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessRestartResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def restart_process_deprecated_without_preload_content(\n        self,\n        process_name: StrictStr,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Restart process\n\n        Restart a specific VNC process\n\n        :param process_name: (required)\n        :type process_name: str\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/restart is deprecated.\", DeprecationWarning)\n\n        _param = self._restart_process_deprecated_serialize(\n            process_name=process_name,\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ProcessRestartResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _restart_process_deprecated_serialize(\n        self,\n        process_name,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if process_name is not None:\n            _path_params['processName'] = process_name\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/process/{processName}/restart',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def scroll_mouse_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        mouse_scroll_request: MouseScrollRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> MouseScrollResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Scroll mouse\n\n        Scroll mouse at specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_scroll_request: (required)\n        :type mouse_scroll_request: MouseScrollRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/scroll is deprecated.\", DeprecationWarning)\n\n        _param = self._scroll_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_scroll_request=mouse_scroll_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseScrollResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def scroll_mouse_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        mouse_scroll_request: MouseScrollRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[MouseScrollResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Scroll mouse\n\n        Scroll mouse at specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_scroll_request: (required)\n        :type mouse_scroll_request: MouseScrollRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/scroll is deprecated.\", DeprecationWarning)\n\n        _param = self._scroll_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_scroll_request=mouse_scroll_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseScrollResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def scroll_mouse_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        mouse_scroll_request: MouseScrollRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Scroll mouse\n\n        Scroll mouse at specified coordinates\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param mouse_scroll_request: (required)\n        :type mouse_scroll_request: MouseScrollRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/mouse/scroll is deprecated.\", DeprecationWarning)\n\n        _param = self._scroll_mouse_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            mouse_scroll_request=mouse_scroll_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"MouseScrollResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _scroll_mouse_deprecated_serialize(\n        self,\n        sandbox_id,\n        mouse_scroll_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if mouse_scroll_request is not None:\n            _body_params = mouse_scroll_request\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/mouse/scroll',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def search_files_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        pattern: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SearchFilesResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Search files\n\n        Search for files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param pattern: (required)\n        :type pattern: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/search is deprecated.\", DeprecationWarning)\n\n        _param = self._search_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            pattern=pattern,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SearchFilesResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def search_files_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        pattern: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SearchFilesResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Search files\n\n        Search for files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param pattern: (required)\n        :type pattern: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/search is deprecated.\", DeprecationWarning)\n\n        _param = self._search_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            pattern=pattern,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SearchFilesResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def search_files_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        pattern: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Search files\n\n        Search for files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param pattern: (required)\n        :type pattern: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/files/search is deprecated.\", DeprecationWarning)\n\n        _param = self._search_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            pattern=pattern,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SearchFilesResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _search_files_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        pattern,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        if pattern is not None:\n            \n            _query_params.append(('pattern', pattern))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/search',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_file_permissions_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        owner: Optional[StrictStr] = None,\n        group: Optional[StrictStr] = None,\n        mode: Optional[StrictStr] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Set file permissions\n\n        Set file owner/group/permissions inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param owner:\n        :type owner: str\n        :param group:\n        :type group: str\n        :param mode:\n        :type mode: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/permissions is deprecated.\", DeprecationWarning)\n\n        _param = self._set_file_permissions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            owner=owner,\n            group=group,\n            mode=mode,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_file_permissions_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        owner: Optional[StrictStr] = None,\n        group: Optional[StrictStr] = None,\n        mode: Optional[StrictStr] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Set file permissions\n\n        Set file owner/group/permissions inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param owner:\n        :type owner: str\n        :param group:\n        :type group: str\n        :param mode:\n        :type mode: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/permissions is deprecated.\", DeprecationWarning)\n\n        _param = self._set_file_permissions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            owner=owner,\n            group=group,\n            mode=mode,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_file_permissions_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        owner: Optional[StrictStr] = None,\n        group: Optional[StrictStr] = None,\n        mode: Optional[StrictStr] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Set file permissions\n\n        Set file owner/group/permissions inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param owner:\n        :type owner: str\n        :param group:\n        :type group: str\n        :param mode:\n        :type mode: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/permissions is deprecated.\", DeprecationWarning)\n\n        _param = self._set_file_permissions_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            owner=owner,\n            group=group,\n            mode=mode,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_file_permissions_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        x_daytona_organization_id,\n        owner,\n        group,\n        mode,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        if owner is not None:\n            \n            _query_params.append(('owner', owner))\n            \n        if group is not None:\n            \n            _query_params.append(('group', group))\n            \n        if mode is not None:\n            \n            _query_params.append(('mode', mode))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/permissions',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def start_computer_use_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ComputerUseStartResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Start computer use processes\n\n        Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/start is deprecated.\", DeprecationWarning)\n\n        _param = self._start_computer_use_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStartResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def start_computer_use_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ComputerUseStartResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Start computer use processes\n\n        Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/start is deprecated.\", DeprecationWarning)\n\n        _param = self._start_computer_use_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStartResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def start_computer_use_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Start computer use processes\n\n        Start all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/start is deprecated.\", DeprecationWarning)\n\n        _param = self._start_computer_use_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStartResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _start_computer_use_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/start',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def stop_computer_use_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ComputerUseStopResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Stop computer use processes\n\n        Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._stop_computer_use_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStopResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def stop_computer_use_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ComputerUseStopResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Stop computer use processes\n\n        Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._stop_computer_use_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStopResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def stop_computer_use_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Stop computer use processes\n\n        Stop all VNC desktop processes (Xvfb, xfce4, x11vnc, novnc)\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._stop_computer_use_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ComputerUseStopResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _stop_computer_use_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/stop',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def take_compressed_region_screenshot_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        height: Union[StrictFloat, StrictInt],\n        width: Union[StrictFloat, StrictInt],\n        y: Union[StrictFloat, StrictInt],\n        x: Union[StrictFloat, StrictInt],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        scale: Optional[Union[StrictFloat, StrictInt]] = None,\n        quality: Optional[Union[StrictFloat, StrictInt]] = None,\n        format: Optional[StrictStr] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> CompressedScreenshotResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Take compressed region screenshot\n\n        Take a compressed screenshot of a specific region\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param height: (required)\n        :type height: float\n        :param width: (required)\n        :type width: float\n        :param y: (required)\n        :type y: float\n        :param x: (required)\n        :type x: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param scale:\n        :type scale: float\n        :param quality:\n        :type quality: float\n        :param format:\n        :type format: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/region/compressed is deprecated.\", DeprecationWarning)\n\n        _param = self._take_compressed_region_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            height=height,\n            width=width,\n            y=y,\n            x=x,\n            x_daytona_organization_id=x_daytona_organization_id,\n            scale=scale,\n            quality=quality,\n            format=format,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompressedScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def take_compressed_region_screenshot_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        height: Union[StrictFloat, StrictInt],\n        width: Union[StrictFloat, StrictInt],\n        y: Union[StrictFloat, StrictInt],\n        x: Union[StrictFloat, StrictInt],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        scale: Optional[Union[StrictFloat, StrictInt]] = None,\n        quality: Optional[Union[StrictFloat, StrictInt]] = None,\n        format: Optional[StrictStr] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[CompressedScreenshotResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Take compressed region screenshot\n\n        Take a compressed screenshot of a specific region\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param height: (required)\n        :type height: float\n        :param width: (required)\n        :type width: float\n        :param y: (required)\n        :type y: float\n        :param x: (required)\n        :type x: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param scale:\n        :type scale: float\n        :param quality:\n        :type quality: float\n        :param format:\n        :type format: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/region/compressed is deprecated.\", DeprecationWarning)\n\n        _param = self._take_compressed_region_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            height=height,\n            width=width,\n            y=y,\n            x=x,\n            x_daytona_organization_id=x_daytona_organization_id,\n            scale=scale,\n            quality=quality,\n            format=format,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompressedScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def take_compressed_region_screenshot_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        height: Union[StrictFloat, StrictInt],\n        width: Union[StrictFloat, StrictInt],\n        y: Union[StrictFloat, StrictInt],\n        x: Union[StrictFloat, StrictInt],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        scale: Optional[Union[StrictFloat, StrictInt]] = None,\n        quality: Optional[Union[StrictFloat, StrictInt]] = None,\n        format: Optional[StrictStr] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Take compressed region screenshot\n\n        Take a compressed screenshot of a specific region\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param height: (required)\n        :type height: float\n        :param width: (required)\n        :type width: float\n        :param y: (required)\n        :type y: float\n        :param x: (required)\n        :type x: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param scale:\n        :type scale: float\n        :param quality:\n        :type quality: float\n        :param format:\n        :type format: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/region/compressed is deprecated.\", DeprecationWarning)\n\n        _param = self._take_compressed_region_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            height=height,\n            width=width,\n            y=y,\n            x=x,\n            x_daytona_organization_id=x_daytona_organization_id,\n            scale=scale,\n            quality=quality,\n            format=format,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompressedScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _take_compressed_region_screenshot_deprecated_serialize(\n        self,\n        sandbox_id,\n        height,\n        width,\n        y,\n        x,\n        x_daytona_organization_id,\n        scale,\n        quality,\n        format,\n        show_cursor,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if scale is not None:\n            \n            _query_params.append(('scale', scale))\n            \n        if quality is not None:\n            \n            _query_params.append(('quality', quality))\n            \n        if format is not None:\n            \n            _query_params.append(('format', format))\n            \n        if show_cursor is not None:\n            \n            _query_params.append(('show_cursor', show_cursor))\n            \n        if height is not None:\n            \n            _query_params.append(('height', height))\n            \n        if width is not None:\n            \n            _query_params.append(('width', width))\n            \n        if y is not None:\n            \n            _query_params.append(('y', y))\n            \n        if x is not None:\n            \n            _query_params.append(('x', x))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/screenshot/region/compressed',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def take_compressed_screenshot_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        scale: Optional[Union[StrictFloat, StrictInt]] = None,\n        quality: Optional[Union[StrictFloat, StrictInt]] = None,\n        format: Optional[StrictStr] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> CompressedScreenshotResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Take compressed screenshot\n\n        Take a compressed screenshot with format, quality, and scale options\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param scale:\n        :type scale: float\n        :param quality:\n        :type quality: float\n        :param format:\n        :type format: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/compressed is deprecated.\", DeprecationWarning)\n\n        _param = self._take_compressed_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            scale=scale,\n            quality=quality,\n            format=format,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompressedScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def take_compressed_screenshot_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        scale: Optional[Union[StrictFloat, StrictInt]] = None,\n        quality: Optional[Union[StrictFloat, StrictInt]] = None,\n        format: Optional[StrictStr] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[CompressedScreenshotResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Take compressed screenshot\n\n        Take a compressed screenshot with format, quality, and scale options\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param scale:\n        :type scale: float\n        :param quality:\n        :type quality: float\n        :param format:\n        :type format: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/compressed is deprecated.\", DeprecationWarning)\n\n        _param = self._take_compressed_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            scale=scale,\n            quality=quality,\n            format=format,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompressedScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def take_compressed_screenshot_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        scale: Optional[Union[StrictFloat, StrictInt]] = None,\n        quality: Optional[Union[StrictFloat, StrictInt]] = None,\n        format: Optional[StrictStr] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Take compressed screenshot\n\n        Take a compressed screenshot with format, quality, and scale options\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param scale:\n        :type scale: float\n        :param quality:\n        :type quality: float\n        :param format:\n        :type format: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/compressed is deprecated.\", DeprecationWarning)\n\n        _param = self._take_compressed_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            scale=scale,\n            quality=quality,\n            format=format,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"CompressedScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _take_compressed_screenshot_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        scale,\n        quality,\n        format,\n        show_cursor,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if scale is not None:\n            \n            _query_params.append(('scale', scale))\n            \n        if quality is not None:\n            \n            _query_params.append(('quality', quality))\n            \n        if format is not None:\n            \n            _query_params.append(('format', format))\n            \n        if show_cursor is not None:\n            \n            _query_params.append(('show_cursor', show_cursor))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/screenshot/compressed',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def take_region_screenshot_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        height: Union[StrictFloat, StrictInt],\n        width: Union[StrictFloat, StrictInt],\n        y: Union[StrictFloat, StrictInt],\n        x: Union[StrictFloat, StrictInt],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RegionScreenshotResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Take region screenshot\n\n        Take a screenshot of a specific region\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param height: (required)\n        :type height: float\n        :param width: (required)\n        :type width: float\n        :param y: (required)\n        :type y: float\n        :param x: (required)\n        :type x: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/region is deprecated.\", DeprecationWarning)\n\n        _param = self._take_region_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            height=height,\n            width=width,\n            y=y,\n            x=x,\n            x_daytona_organization_id=x_daytona_organization_id,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegionScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def take_region_screenshot_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        height: Union[StrictFloat, StrictInt],\n        width: Union[StrictFloat, StrictInt],\n        y: Union[StrictFloat, StrictInt],\n        x: Union[StrictFloat, StrictInt],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[RegionScreenshotResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Take region screenshot\n\n        Take a screenshot of a specific region\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param height: (required)\n        :type height: float\n        :param width: (required)\n        :type width: float\n        :param y: (required)\n        :type y: float\n        :param x: (required)\n        :type x: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/region is deprecated.\", DeprecationWarning)\n\n        _param = self._take_region_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            height=height,\n            width=width,\n            y=y,\n            x=x,\n            x_daytona_organization_id=x_daytona_organization_id,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegionScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def take_region_screenshot_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        height: Union[StrictFloat, StrictInt],\n        width: Union[StrictFloat, StrictInt],\n        y: Union[StrictFloat, StrictInt],\n        x: Union[StrictFloat, StrictInt],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Take region screenshot\n\n        Take a screenshot of a specific region\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param height: (required)\n        :type height: float\n        :param width: (required)\n        :type width: float\n        :param y: (required)\n        :type y: float\n        :param x: (required)\n        :type x: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot/region is deprecated.\", DeprecationWarning)\n\n        _param = self._take_region_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            height=height,\n            width=width,\n            y=y,\n            x=x,\n            x_daytona_organization_id=x_daytona_organization_id,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"RegionScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _take_region_screenshot_deprecated_serialize(\n        self,\n        sandbox_id,\n        height,\n        width,\n        y,\n        x,\n        x_daytona_organization_id,\n        show_cursor,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if show_cursor is not None:\n            \n            _query_params.append(('show_cursor', show_cursor))\n            \n        if height is not None:\n            \n            _query_params.append(('height', height))\n            \n        if width is not None:\n            \n            _query_params.append(('width', width))\n            \n        if y is not None:\n            \n            _query_params.append(('y', y))\n            \n        if x is not None:\n            \n            _query_params.append(('x', x))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/screenshot/region',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def take_screenshot_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ScreenshotResponse:\n        \"\"\"(Deprecated) [DEPRECATED] Take screenshot\n\n        Take a screenshot of the entire screen\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot is deprecated.\", DeprecationWarning)\n\n        _param = self._take_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def take_screenshot_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[ScreenshotResponse]:\n        \"\"\"(Deprecated) [DEPRECATED] Take screenshot\n\n        Take a screenshot of the entire screen\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot is deprecated.\", DeprecationWarning)\n\n        _param = self._take_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def take_screenshot_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        show_cursor: Optional[StrictBool] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Take screenshot\n\n        Take a screenshot of the entire screen\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param show_cursor:\n        :type show_cursor: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /toolbox/{sandboxId}/toolbox/computeruse/screenshot is deprecated.\", DeprecationWarning)\n\n        _param = self._take_screenshot_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            show_cursor=show_cursor,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"ScreenshotResponse\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _take_screenshot_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        show_cursor,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if show_cursor is not None:\n            \n            _query_params.append(('show_cursor', show_cursor))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/screenshot',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def type_text_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_type_request: KeyboardTypeRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Type text\n\n        Type text using keyboard\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_type_request: (required)\n        :type keyboard_type_request: KeyboardTypeRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/type is deprecated.\", DeprecationWarning)\n\n        _param = self._type_text_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_type_request=keyboard_type_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def type_text_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_type_request: KeyboardTypeRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Type text\n\n        Type text using keyboard\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_type_request: (required)\n        :type keyboard_type_request: KeyboardTypeRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/type is deprecated.\", DeprecationWarning)\n\n        _param = self._type_text_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_type_request=keyboard_type_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def type_text_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        keyboard_type_request: KeyboardTypeRequest,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Type text\n\n        Type text using keyboard\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param keyboard_type_request: (required)\n        :type keyboard_type_request: KeyboardTypeRequest\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/computeruse/keyboard/type is deprecated.\", DeprecationWarning)\n\n        _param = self._type_text_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            keyboard_type_request=keyboard_type_request,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _type_text_deprecated_serialize(\n        self,\n        sandbox_id,\n        keyboard_type_request,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if keyboard_type_request is not None:\n            _body_params = keyboard_type_request\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/computeruse/keyboard/type',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def upload_file_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        file: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Upload file\n\n        Upload file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param file:\n        :type file: bytearray\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/upload is deprecated.\", DeprecationWarning)\n\n        _param = self._upload_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            file=file,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def upload_file_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        file: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Upload file\n\n        Upload file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param file:\n        :type file: bytearray\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/upload is deprecated.\", DeprecationWarning)\n\n        _param = self._upload_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            file=file,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def upload_file_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        path: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        file: Optional[Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Upload file\n\n        Upload file inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param path: (required)\n        :type path: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param file:\n        :type file: bytearray\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/upload is deprecated.\", DeprecationWarning)\n\n        _param = self._upload_file_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            path=path,\n            x_daytona_organization_id=x_daytona_organization_id,\n            file=file,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _upload_file_deprecated_serialize(\n        self,\n        sandbox_id,\n        path,\n        x_daytona_organization_id,\n        file,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        if path is not None:\n            \n            _query_params.append(('path', path))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        if file is not None:\n            _files['file'] = file\n        # process the body parameter\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'multipart/form-data'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/upload',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def upload_files_deprecated(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Upload multiple files\n\n        Upload multiple files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/bulk-upload is deprecated.\", DeprecationWarning)\n\n        _param = self._upload_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def upload_files_deprecated_with_http_info(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Upload multiple files\n\n        Upload multiple files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/bulk-upload is deprecated.\", DeprecationWarning)\n\n        _param = self._upload_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def upload_files_deprecated_without_preload_content(\n        self,\n        sandbox_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Upload multiple files\n\n        Upload multiple files inside sandbox\n\n        :param sandbox_id: (required)\n        :type sandbox_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /toolbox/{sandboxId}/toolbox/files/bulk-upload is deprecated.\", DeprecationWarning)\n\n        _param = self._upload_files_deprecated_serialize(\n            sandbox_id=sandbox_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _upload_files_deprecated_serialize(\n        self,\n        sandbox_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if sandbox_id is not None:\n            _path_params['sandboxId'] = sandbox_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'multipart/form-data'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/toolbox/{sandboxId}/toolbox/files/bulk-upload',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/users_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import StrictStr\nfrom typing import List\nfrom daytona_api_client.models.account_provider import AccountProvider\nfrom daytona_api_client.models.create_linked_account import CreateLinkedAccount\nfrom daytona_api_client.models.create_user import CreateUser\nfrom daytona_api_client.models.user import User\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass UsersApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def create_user(\n        self,\n        create_user: CreateUser,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Create user\n\n\n        :param create_user: (required)\n        :type create_user: CreateUser\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_user_serialize(\n            create_user=create_user,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_user_with_http_info(\n        self,\n        create_user: CreateUser,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Create user\n\n\n        :param create_user: (required)\n        :type create_user: CreateUser\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_user_serialize(\n            create_user=create_user,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_user_without_preload_content(\n        self,\n        create_user: CreateUser,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create user\n\n\n        :param create_user: (required)\n        :type create_user: CreateUser\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_user_serialize(\n            create_user=create_user,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_user_serialize(\n        self,\n        create_user,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if create_user is not None:\n            _body_params = create_user\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/users',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def enroll_in_sms_mfa(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> str:\n        \"\"\"Enroll in SMS MFA\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._enroll_in_sms_mfa_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def enroll_in_sms_mfa_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[str]:\n        \"\"\"Enroll in SMS MFA\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._enroll_in_sms_mfa_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def enroll_in_sms_mfa_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Enroll in SMS MFA\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._enroll_in_sms_mfa_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"str\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _enroll_in_sms_mfa_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/users/mfa/sms/enroll',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_authenticated_user(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> User:\n        \"\"\"Get authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"User\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_authenticated_user_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[User]:\n        \"\"\"Get authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"User\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_authenticated_user_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get authenticated user\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_authenticated_user_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"User\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_authenticated_user_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/users/me',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_available_account_providers(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[AccountProvider]:\n        \"\"\"Get available account providers\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_available_account_providers_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[AccountProvider]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_available_account_providers_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[AccountProvider]]:\n        \"\"\"Get available account providers\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_available_account_providers_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[AccountProvider]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_available_account_providers_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get available account providers\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_available_account_providers_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[AccountProvider]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_available_account_providers_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/users/account-providers',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_user(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> User:\n        \"\"\"Get user by ID\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_user_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"User\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_user_with_http_info(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[User]:\n        \"\"\"Get user by ID\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_user_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"User\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_user_without_preload_content(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get user by ID\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_user_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"User\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_user_serialize(\n        self,\n        id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/users/{id}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def link_account(\n        self,\n        create_linked_account: CreateLinkedAccount,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Link account\n\n\n        :param create_linked_account: (required)\n        :type create_linked_account: CreateLinkedAccount\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._link_account_serialize(\n            create_linked_account=create_linked_account,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def link_account_with_http_info(\n        self,\n        create_linked_account: CreateLinkedAccount,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Link account\n\n\n        :param create_linked_account: (required)\n        :type create_linked_account: CreateLinkedAccount\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._link_account_serialize(\n            create_linked_account=create_linked_account,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def link_account_without_preload_content(\n        self,\n        create_linked_account: CreateLinkedAccount,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Link account\n\n\n        :param create_linked_account: (required)\n        :type create_linked_account: CreateLinkedAccount\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._link_account_serialize(\n            create_linked_account=create_linked_account,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _link_account_serialize(\n        self,\n        create_linked_account,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n        if create_linked_account is not None:\n            _body_params = create_linked_account\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/users/linked-accounts',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_users(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"List all users\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_users_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_users_with_http_info(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"List all users\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_users_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_users_without_preload_content(\n        self,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all users\n\n\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_users_serialize(\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_users_serialize(\n        self,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/users',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def regenerate_key_pair(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Regenerate user key pair\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_key_pair_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def regenerate_key_pair_with_http_info(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Regenerate user key pair\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_key_pair_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def regenerate_key_pair_without_preload_content(\n        self,\n        id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Regenerate user key pair\n\n\n        :param id: (required)\n        :type id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._regenerate_key_pair_serialize(\n            id=id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _regenerate_key_pair_serialize(\n        self,\n        id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if id is not None:\n            _path_params['id'] = id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/users/{id}/regenerate-key-pair',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def unlink_account(\n        self,\n        provider: StrictStr,\n        provider_user_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Unlink account\n\n\n        :param provider: (required)\n        :type provider: str\n        :param provider_user_id: (required)\n        :type provider_user_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._unlink_account_serialize(\n            provider=provider,\n            provider_user_id=provider_user_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def unlink_account_with_http_info(\n        self,\n        provider: StrictStr,\n        provider_user_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Unlink account\n\n\n        :param provider: (required)\n        :type provider: str\n        :param provider_user_id: (required)\n        :type provider_user_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._unlink_account_serialize(\n            provider=provider,\n            provider_user_id=provider_user_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def unlink_account_without_preload_content(\n        self,\n        provider: StrictStr,\n        provider_user_id: StrictStr,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Unlink account\n\n\n        :param provider: (required)\n        :type provider: str\n        :param provider_user_id: (required)\n        :type provider_user_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._unlink_account_serialize(\n            provider=provider,\n            provider_user_id=provider_user_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '204': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _unlink_account_serialize(\n        self,\n        provider,\n        provider_user_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if provider is not None:\n            _path_params['provider'] = provider\n        if provider_user_id is not None:\n            _path_params['providerUserId'] = provider_user_id\n        # process the query parameters\n        # process the header parameters\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/users/linked-accounts/{provider}/{providerUserId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/volumes_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictBool, StrictStr\nfrom typing import List, Optional\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.create_volume import CreateVolume\nfrom daytona_api_client.models.volume_dto import VolumeDto\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass VolumesApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def create_volume(\n        self,\n        create_volume: CreateVolume,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> VolumeDto:\n        \"\"\"Create a new volume\n\n\n        :param create_volume: (required)\n        :type create_volume: CreateVolume\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_volume_serialize(\n            create_volume=create_volume,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_volume_with_http_info(\n        self,\n        create_volume: CreateVolume,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[VolumeDto]:\n        \"\"\"Create a new volume\n\n\n        :param create_volume: (required)\n        :type create_volume: CreateVolume\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_volume_serialize(\n            create_volume=create_volume,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_volume_without_preload_content(\n        self,\n        create_volume: CreateVolume,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Create a new volume\n\n\n        :param create_volume: (required)\n        :type create_volume: CreateVolume\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._create_volume_serialize(\n            create_volume=create_volume,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_volume_serialize(\n        self,\n        create_volume,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_volume is not None:\n            _body_params = create_volume\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/volumes',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_volume(\n        self,\n        volume_id: Annotated[StrictStr, Field(description=\"ID of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Delete volume\n\n\n        :param volume_id: ID of the volume (required)\n        :type volume_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_volume_serialize(\n            volume_id=volume_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n            '409': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_volume_with_http_info(\n        self,\n        volume_id: Annotated[StrictStr, Field(description=\"ID of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Delete volume\n\n\n        :param volume_id: ID of the volume (required)\n        :type volume_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_volume_serialize(\n            volume_id=volume_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n            '409': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_volume_without_preload_content(\n        self,\n        volume_id: Annotated[StrictStr, Field(description=\"ID of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Delete volume\n\n\n        :param volume_id: ID of the volume (required)\n        :type volume_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._delete_volume_serialize(\n            volume_id=volume_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n            '409': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_volume_serialize(\n        self,\n        volume_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if volume_id is not None:\n            _path_params['volumeId'] = volume_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/volumes/{volumeId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_volume(\n        self,\n        volume_id: Annotated[StrictStr, Field(description=\"ID of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> VolumeDto:\n        \"\"\"Get volume details\n\n\n        :param volume_id: ID of the volume (required)\n        :type volume_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_volume_serialize(\n            volume_id=volume_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_volume_with_http_info(\n        self,\n        volume_id: Annotated[StrictStr, Field(description=\"ID of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[VolumeDto]:\n        \"\"\"Get volume details\n\n\n        :param volume_id: ID of the volume (required)\n        :type volume_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_volume_serialize(\n            volume_id=volume_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_volume_without_preload_content(\n        self,\n        volume_id: Annotated[StrictStr, Field(description=\"ID of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get volume details\n\n\n        :param volume_id: ID of the volume (required)\n        :type volume_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_volume_serialize(\n            volume_id=volume_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_volume_serialize(\n        self,\n        volume_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if volume_id is not None:\n            _path_params['volumeId'] = volume_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/volumes/{volumeId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_volume_by_name(\n        self,\n        name: Annotated[StrictStr, Field(description=\"Name of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> VolumeDto:\n        \"\"\"Get volume details by name\n\n\n        :param name: Name of the volume (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_volume_by_name_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_volume_by_name_with_http_info(\n        self,\n        name: Annotated[StrictStr, Field(description=\"Name of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[VolumeDto]:\n        \"\"\"Get volume details by name\n\n\n        :param name: Name of the volume (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_volume_by_name_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_volume_by_name_without_preload_content(\n        self,\n        name: Annotated[StrictStr, Field(description=\"Name of the volume\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get volume details by name\n\n\n        :param name: Name of the volume (required)\n        :type name: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._get_volume_by_name_serialize(\n            name=name,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"VolumeDto\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_volume_by_name_serialize(\n        self,\n        name,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if name is not None:\n            _path_params['name'] = name\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/volumes/by-name/{name}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_volumes(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        include_deleted: Annotated[Optional[StrictBool], Field(description=\"Include deleted volumes in the response\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[VolumeDto]:\n        \"\"\"List all volumes\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param include_deleted: Include deleted volumes in the response\n        :type include_deleted: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_volumes_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            include_deleted=include_deleted,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[VolumeDto]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_volumes_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        include_deleted: Annotated[Optional[StrictBool], Field(description=\"Include deleted volumes in the response\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[VolumeDto]]:\n        \"\"\"List all volumes\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param include_deleted: Include deleted volumes in the response\n        :type include_deleted: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_volumes_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            include_deleted=include_deleted,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[VolumeDto]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_volumes_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        include_deleted: Annotated[Optional[StrictBool], Field(description=\"Include deleted volumes in the response\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"List all volumes\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param include_deleted: Include deleted volumes in the response\n        :type include_deleted: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._list_volumes_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            include_deleted=include_deleted,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[VolumeDto]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_volumes_serialize(\n        self,\n        x_daytona_organization_id,\n        include_deleted,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if include_deleted is not None:\n            \n            _query_params.append(('includeDeleted', include_deleted))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/volumes',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/webhooks_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictStr\nfrom typing import Any, Dict, List, Optional\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.send_webhook_dto import SendWebhookDto\nfrom daytona_api_client.models.webhook_app_portal_access import WebhookAppPortalAccess\nfrom daytona_api_client.models.webhook_controller_get_status200_response import WebhookControllerGetStatus200Response\nfrom daytona_api_client.models.webhook_initialization_status import WebhookInitializationStatus\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass WebhooksApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def webhook_controller_get_app_portal_access(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> WebhookAppPortalAccess:\n        \"\"\"Get Svix Consumer App Portal access for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_app_portal_access_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookAppPortalAccess\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def webhook_controller_get_app_portal_access_with_http_info(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[WebhookAppPortalAccess]:\n        \"\"\"Get Svix Consumer App Portal access for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_app_portal_access_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookAppPortalAccess\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def webhook_controller_get_app_portal_access_without_preload_content(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get Svix Consumer App Portal access for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_app_portal_access_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookAppPortalAccess\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _webhook_controller_get_app_portal_access_serialize(\n        self,\n        organization_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/webhooks/organizations/{organizationId}/app-portal-access',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def webhook_controller_get_initialization_status(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> WebhookInitializationStatus:\n        \"\"\"Get webhook initialization status for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_initialization_status_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookInitializationStatus\",\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def webhook_controller_get_initialization_status_with_http_info(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[WebhookInitializationStatus]:\n        \"\"\"Get webhook initialization status for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_initialization_status_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookInitializationStatus\",\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def webhook_controller_get_initialization_status_without_preload_content(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get webhook initialization status for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_initialization_status_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookInitializationStatus\",\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _webhook_controller_get_initialization_status_serialize(\n        self,\n        organization_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/webhooks/organizations/{organizationId}/initialization-status',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def webhook_controller_get_message_attempts(\n        self,\n        organization_id: StrictStr,\n        message_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[object]:\n        \"\"\"Get delivery attempts for a webhook message\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param message_id: (required)\n        :type message_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_message_attempts_serialize(\n            organization_id=organization_id,\n            message_id=message_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[object]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def webhook_controller_get_message_attempts_with_http_info(\n        self,\n        organization_id: StrictStr,\n        message_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[object]]:\n        \"\"\"Get delivery attempts for a webhook message\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param message_id: (required)\n        :type message_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_message_attempts_serialize(\n            organization_id=organization_id,\n            message_id=message_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[object]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def webhook_controller_get_message_attempts_without_preload_content(\n        self,\n        organization_id: StrictStr,\n        message_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get delivery attempts for a webhook message\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param message_id: (required)\n        :type message_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_message_attempts_serialize(\n            organization_id=organization_id,\n            message_id=message_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[object]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _webhook_controller_get_message_attempts_serialize(\n        self,\n        organization_id,\n        message_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        if message_id is not None:\n            _path_params['messageId'] = message_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/webhooks/organizations/{organizationId}/messages/{messageId}/attempts',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def webhook_controller_get_status(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> WebhookControllerGetStatus200Response:\n        \"\"\"Get webhook service status\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_status_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookControllerGetStatus200Response\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def webhook_controller_get_status_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[WebhookControllerGetStatus200Response]:\n        \"\"\"Get webhook service status\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_status_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookControllerGetStatus200Response\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def webhook_controller_get_status_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Get webhook service status\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_get_status_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WebhookControllerGetStatus200Response\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _webhook_controller_get_status_serialize(\n        self,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/webhooks/status',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def webhook_controller_initialize_webhooks(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Initialize webhooks for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_initialize_webhooks_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n            '403': None,\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def webhook_controller_initialize_webhooks_with_http_info(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Initialize webhooks for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_initialize_webhooks_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n            '403': None,\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def webhook_controller_initialize_webhooks_without_preload_content(\n        self,\n        organization_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Initialize webhooks for an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_initialize_webhooks_serialize(\n            organization_id=organization_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n            '403': None,\n            '404': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _webhook_controller_initialize_webhooks_serialize(\n        self,\n        organization_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/webhooks/organizations/{organizationId}/initialize',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def webhook_controller_send_webhook(\n        self,\n        organization_id: StrictStr,\n        send_webhook_dto: SendWebhookDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"Send a webhook message to an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param send_webhook_dto: (required)\n        :type send_webhook_dto: SendWebhookDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_send_webhook_serialize(\n            organization_id=organization_id,\n            send_webhook_dto=send_webhook_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def webhook_controller_send_webhook_with_http_info(\n        self,\n        organization_id: StrictStr,\n        send_webhook_dto: SendWebhookDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"Send a webhook message to an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param send_webhook_dto: (required)\n        :type send_webhook_dto: SendWebhookDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_send_webhook_serialize(\n            organization_id=organization_id,\n            send_webhook_dto=send_webhook_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def webhook_controller_send_webhook_without_preload_content(\n        self,\n        organization_id: StrictStr,\n        send_webhook_dto: SendWebhookDto,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"Send a webhook message to an organization\n\n\n        :param organization_id: (required)\n        :type organization_id: str\n        :param send_webhook_dto: (required)\n        :type send_webhook_dto: SendWebhookDto\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n\n        _param = self._webhook_controller_send_webhook_serialize(\n            organization_id=organization_id,\n            send_webhook_dto=send_webhook_dto,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _webhook_controller_send_webhook_serialize(\n        self,\n        organization_id,\n        send_webhook_dto,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if organization_id is not None:\n            _path_params['organizationId'] = organization_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if send_webhook_dto is not None:\n            _body_params = send_webhook_dto\n\n\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/webhooks/organizations/{organizationId}/send',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api/workspace_api.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nimport warnings\nfrom pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt\nfrom typing import Any, Dict, List, Optional, Tuple, Union\nfrom typing_extensions import Annotated\n\nfrom pydantic import Field, StrictBool, StrictFloat, StrictInt, StrictStr\nfrom typing import List, Optional, Union\nfrom typing_extensions import Annotated\nfrom daytona_api_client.models.create_workspace import CreateWorkspace\nfrom daytona_api_client.models.sandbox_labels import SandboxLabels\nfrom daytona_api_client.models.workspace import Workspace\nfrom daytona_api_client.models.workspace_port_preview_url import WorkspacePortPreviewUrl\n\nfrom daytona_api_client.api_client import ApiClient, RequestSerialized\nfrom daytona_api_client.api_response import ApiResponse\nfrom daytona_api_client.rest import RESTResponseType\n\n\nclass WorkspaceApi:\n    \"\"\"NOTE: This class is auto generated by OpenAPI Generator\n    Ref: https://openapi-generator.tech\n\n    Do not edit the class manually.\n    \"\"\"\n\n    def __init__(self, api_client=None) -> None:\n        if api_client is None:\n            api_client = ApiClient.get_default()\n        self.api_client = api_client\n\n\n    @validate_call\n    def archive_workspace_deprecated(\n        self,\n        workspace_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Archive workspace\n\n\n        :param workspace_id: (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/archive is deprecated.\", DeprecationWarning)\n\n        _param = self._archive_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def archive_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Archive workspace\n\n\n        :param workspace_id: (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/archive is deprecated.\", DeprecationWarning)\n\n        _param = self._archive_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def archive_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: StrictStr,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Archive workspace\n\n\n        :param workspace_id: (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/archive is deprecated.\", DeprecationWarning)\n\n        _param = self._archive_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _archive_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/workspace/{workspaceId}/archive',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_backup_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Workspace:\n        \"\"\"(Deprecated) [DEPRECATED] Create workspace backup\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/backup is deprecated.\", DeprecationWarning)\n\n        _param = self._create_backup_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_backup_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Workspace]:\n        \"\"\"(Deprecated) [DEPRECATED] Create workspace backup\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/backup is deprecated.\", DeprecationWarning)\n\n        _param = self._create_backup_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_backup_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Create workspace backup\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/backup is deprecated.\", DeprecationWarning)\n\n        _param = self._create_backup_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_backup_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/workspace/{workspaceId}/backup',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def create_workspace_deprecated(\n        self,\n        create_workspace: CreateWorkspace,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Workspace:\n        \"\"\"(Deprecated) [DEPRECATED] Create a new workspace\n\n\n        :param create_workspace: (required)\n        :type create_workspace: CreateWorkspace\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace is deprecated.\", DeprecationWarning)\n\n        _param = self._create_workspace_deprecated_serialize(\n            create_workspace=create_workspace,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def create_workspace_deprecated_with_http_info(\n        self,\n        create_workspace: CreateWorkspace,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Workspace]:\n        \"\"\"(Deprecated) [DEPRECATED] Create a new workspace\n\n\n        :param create_workspace: (required)\n        :type create_workspace: CreateWorkspace\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace is deprecated.\", DeprecationWarning)\n\n        _param = self._create_workspace_deprecated_serialize(\n            create_workspace=create_workspace,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def create_workspace_deprecated_without_preload_content(\n        self,\n        create_workspace: CreateWorkspace,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Create a new workspace\n\n\n        :param create_workspace: (required)\n        :type create_workspace: CreateWorkspace\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace is deprecated.\", DeprecationWarning)\n\n        _param = self._create_workspace_deprecated_serialize(\n            create_workspace=create_workspace,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _create_workspace_deprecated_serialize(\n        self,\n        create_workspace,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if create_workspace is not None:\n            _body_params = create_workspace\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/workspace',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def delete_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        force: StrictBool,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Delete workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param force: (required)\n        :type force: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /workspace/{workspaceId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            force=force,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def delete_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        force: StrictBool,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Delete workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param force: (required)\n        :type force: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /workspace/{workspaceId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            force=force,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def delete_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        force: StrictBool,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Delete workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param force: (required)\n        :type force: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"DELETE /workspace/{workspaceId} is deprecated.\", DeprecationWarning)\n\n        _param = self._delete_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            force=force,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _delete_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        force,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        # process the query parameters\n        if force is not None:\n            \n            _query_params.append(('force', force))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='DELETE',\n            resource_path='/workspace/{workspaceId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_build_logs_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Get build logs\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_build_logs_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_build_logs_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Get build logs\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_build_logs_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_build_logs_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        follow: Annotated[Optional[StrictBool], Field(description=\"Whether to follow the logs stream\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get build logs\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param follow: Whether to follow the logs stream\n        :type follow: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId}/build-logs is deprecated.\", DeprecationWarning)\n\n        _param = self._get_build_logs_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            follow=follow,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_build_logs_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        x_daytona_organization_id,\n        follow,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        # process the query parameters\n        if follow is not None:\n            \n            _query_params.append(('follow', follow))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/workspace/{workspaceId}/build-logs',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_port_preview_url_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> WorkspacePortPreviewUrl:\n        \"\"\"(Deprecated) [DEPRECATED] Get preview URL for a workspace port\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param port: Port number to get preview URL for (required)\n        :type port: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId}/ports/{port}/preview-url is deprecated.\", DeprecationWarning)\n\n        _param = self._get_port_preview_url_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WorkspacePortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_port_preview_url_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[WorkspacePortPreviewUrl]:\n        \"\"\"(Deprecated) [DEPRECATED] Get preview URL for a workspace port\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param port: Port number to get preview URL for (required)\n        :type port: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId}/ports/{port}/preview-url is deprecated.\", DeprecationWarning)\n\n        _param = self._get_port_preview_url_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WorkspacePortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_port_preview_url_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        port: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Port number to get preview URL for\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get preview URL for a workspace port\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param port: Port number to get preview URL for (required)\n        :type port: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId}/ports/{port}/preview-url is deprecated.\", DeprecationWarning)\n\n        _param = self._get_port_preview_url_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            port=port,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"WorkspacePortPreviewUrl\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_port_preview_url_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        port,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        if port is not None:\n            _path_params['port'] = port\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/workspace/{workspaceId}/ports/{port}/preview-url',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def get_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> Workspace:\n        \"\"\"(Deprecated) [DEPRECATED] Get workspace details\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def get_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[Workspace]:\n        \"\"\"(Deprecated) [DEPRECATED] Get workspace details\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def get_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Get workspace details\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace/{workspaceId} is deprecated.\", DeprecationWarning)\n\n        _param = self._get_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"Workspace\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _get_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        x_daytona_organization_id,\n        verbose,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        # process the query parameters\n        if verbose is not None:\n            \n            _query_params.append(('verbose', verbose))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/workspace/{workspaceId}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def list_workspaces_deprecated(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> List[Workspace]:\n        \"\"\"(Deprecated) [DEPRECATED] List all workspaces\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace is deprecated.\", DeprecationWarning)\n\n        _param = self._list_workspaces_deprecated_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            labels=labels,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Workspace]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def list_workspaces_deprecated_with_http_info(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[List[Workspace]]:\n        \"\"\"(Deprecated) [DEPRECATED] List all workspaces\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace is deprecated.\", DeprecationWarning)\n\n        _param = self._list_workspaces_deprecated_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            labels=labels,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Workspace]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def list_workspaces_deprecated_without_preload_content(\n        self,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        verbose: Annotated[Optional[StrictBool], Field(description=\"Include verbose output\")] = None,\n        labels: Annotated[Optional[StrictStr], Field(description=\"JSON encoded labels to filter by\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] List all workspaces\n\n\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param verbose: Include verbose output\n        :type verbose: bool\n        :param labels: JSON encoded labels to filter by\n        :type labels: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"GET /workspace is deprecated.\", DeprecationWarning)\n\n        _param = self._list_workspaces_deprecated_serialize(\n            x_daytona_organization_id=x_daytona_organization_id,\n            verbose=verbose,\n            labels=labels,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"List[Workspace]\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _list_workspaces_deprecated_serialize(\n        self,\n        x_daytona_organization_id,\n        verbose,\n        labels,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        # process the query parameters\n        if verbose is not None:\n            \n            _query_params.append(('verbose', verbose))\n            \n        if labels is not None:\n            \n            _query_params.append(('labels', labels))\n            \n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='GET',\n            resource_path='/workspace',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def replace_labels_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        sandbox_labels: SandboxLabels,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> SandboxLabels:\n        \"\"\"(Deprecated) [DEPRECATED] Replace workspace labels\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param sandbox_labels: (required)\n        :type sandbox_labels: SandboxLabels\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"PUT /workspace/{workspaceId}/labels is deprecated.\", DeprecationWarning)\n\n        _param = self._replace_labels_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            sandbox_labels=sandbox_labels,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SandboxLabels\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def replace_labels_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        sandbox_labels: SandboxLabels,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[SandboxLabels]:\n        \"\"\"(Deprecated) [DEPRECATED] Replace workspace labels\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param sandbox_labels: (required)\n        :type sandbox_labels: SandboxLabels\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"PUT /workspace/{workspaceId}/labels is deprecated.\", DeprecationWarning)\n\n        _param = self._replace_labels_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            sandbox_labels=sandbox_labels,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SandboxLabels\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def replace_labels_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        sandbox_labels: SandboxLabels,\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Replace workspace labels\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param sandbox_labels: (required)\n        :type sandbox_labels: SandboxLabels\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"PUT /workspace/{workspaceId}/labels is deprecated.\", DeprecationWarning)\n\n        _param = self._replace_labels_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            sandbox_labels=sandbox_labels,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': \"SandboxLabels\",\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _replace_labels_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        sandbox_labels,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n        if sandbox_labels is not None:\n            _body_params = sandbox_labels\n\n\n        # set the HTTP header `Accept`\n        if 'Accept' not in _header_params:\n            _header_params['Accept'] = self.api_client.select_header_accept(\n                [\n                    'application/json'\n                ]\n            )\n\n        # set the HTTP header `Content-Type`\n        if _content_type:\n            _header_params['Content-Type'] = _content_type\n        else:\n            _default_content_type = (\n                self.api_client.select_header_content_type(\n                    [\n                        'application/json'\n                    ]\n                )\n            )\n            if _default_content_type is not None:\n                _header_params['Content-Type'] = _default_content_type\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='PUT',\n            resource_path='/workspace/{workspaceId}/labels',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_auto_archive_interval_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-archive interval in minutes (0 means the maximum interval will be used)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Set workspace auto-archive interval\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param interval: Auto-archive interval in minutes (0 means the maximum interval will be used) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/autoarchive/{interval} is deprecated.\", DeprecationWarning)\n\n        _param = self._set_auto_archive_interval_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_auto_archive_interval_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-archive interval in minutes (0 means the maximum interval will be used)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Set workspace auto-archive interval\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param interval: Auto-archive interval in minutes (0 means the maximum interval will be used) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/autoarchive/{interval} is deprecated.\", DeprecationWarning)\n\n        _param = self._set_auto_archive_interval_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_auto_archive_interval_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-archive interval in minutes (0 means the maximum interval will be used)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Set workspace auto-archive interval\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param interval: Auto-archive interval in minutes (0 means the maximum interval will be used) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/autoarchive/{interval} is deprecated.\", DeprecationWarning)\n\n        _param = self._set_auto_archive_interval_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_auto_archive_interval_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        interval,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        if interval is not None:\n            _path_params['interval'] = interval\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/workspace/{workspaceId}/autoarchive/{interval}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def set_autostop_interval_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-stop interval in minutes (0 to disable)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Set workspace auto-stop interval\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param interval: Auto-stop interval in minutes (0 to disable) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/autostop/{interval} is deprecated.\", DeprecationWarning)\n\n        _param = self._set_autostop_interval_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def set_autostop_interval_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-stop interval in minutes (0 to disable)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Set workspace auto-stop interval\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param interval: Auto-stop interval in minutes (0 to disable) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/autostop/{interval} is deprecated.\", DeprecationWarning)\n\n        _param = self._set_autostop_interval_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def set_autostop_interval_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        interval: Annotated[Union[StrictFloat, StrictInt], Field(description=\"Auto-stop interval in minutes (0 to disable)\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Set workspace auto-stop interval\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param interval: Auto-stop interval in minutes (0 to disable) (required)\n        :type interval: float\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/autostop/{interval} is deprecated.\", DeprecationWarning)\n\n        _param = self._set_autostop_interval_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            interval=interval,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _set_autostop_interval_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        interval,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        if interval is not None:\n            _path_params['interval'] = interval\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/workspace/{workspaceId}/autostop/{interval}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def start_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Start workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/start is deprecated.\", DeprecationWarning)\n\n        _param = self._start_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def start_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Start workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/start is deprecated.\", DeprecationWarning)\n\n        _param = self._start_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def start_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Start workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/start is deprecated.\", DeprecationWarning)\n\n        _param = self._start_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _start_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/workspace/{workspaceId}/start',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def stop_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Stop workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._stop_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def stop_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Stop workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._stop_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def stop_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Stop workspace\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/stop is deprecated.\", DeprecationWarning)\n\n        _param = self._stop_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '200': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _stop_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/workspace/{workspaceId}/stop',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n\n\n    @validate_call\n    def update_public_status_workspace_deprecated(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        is_public: Annotated[StrictBool, Field(description=\"Public status to set\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> None:\n        \"\"\"(Deprecated) [DEPRECATED] Update public status\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param is_public: Public status to set (required)\n        :type is_public: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/public/{isPublic} is deprecated.\", DeprecationWarning)\n\n        _param = self._update_public_status_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            is_public=is_public,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        ).data\n\n\n    @validate_call\n    def update_public_status_workspace_deprecated_with_http_info(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        is_public: Annotated[StrictBool, Field(description=\"Public status to set\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> ApiResponse[None]:\n        \"\"\"(Deprecated) [DEPRECATED] Update public status\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param is_public: Public status to set (required)\n        :type is_public: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/public/{isPublic} is deprecated.\", DeprecationWarning)\n\n        _param = self._update_public_status_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            is_public=is_public,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        response_data.read()\n        return self.api_client.response_deserialize(\n            response_data=response_data,\n            response_types_map=_response_types_map,\n        )\n\n\n    @validate_call\n    def update_public_status_workspace_deprecated_without_preload_content(\n        self,\n        workspace_id: Annotated[StrictStr, Field(description=\"ID of the workspace\")],\n        is_public: Annotated[StrictBool, Field(description=\"Public status to set\")],\n        x_daytona_organization_id: Annotated[Optional[StrictStr], Field(description=\"Use with JWT to specify the organization ID\")] = None,\n        _request_timeout: Union[\n            None,\n            Annotated[StrictFloat, Field(gt=0)],\n            Tuple[\n                Annotated[StrictFloat, Field(gt=0)],\n                Annotated[StrictFloat, Field(gt=0)]\n            ]\n        ] = None,\n        _request_auth: Optional[Dict[StrictStr, Any]] = None,\n        _content_type: Optional[StrictStr] = None,\n        _headers: Optional[Dict[StrictStr, Any]] = None,\n        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,\n    ) -> RESTResponseType:\n        \"\"\"(Deprecated) [DEPRECATED] Update public status\n\n\n        :param workspace_id: ID of the workspace (required)\n        :type workspace_id: str\n        :param is_public: Public status to set (required)\n        :type is_public: bool\n        :param x_daytona_organization_id: Use with JWT to specify the organization ID\n        :type x_daytona_organization_id: str\n        :param _request_timeout: timeout setting for this request. If one\n                                 number provided, it will be total request\n                                 timeout. It can also be a pair (tuple) of\n                                 (connection, read) timeouts.\n        :type _request_timeout: int, tuple(int, int), optional\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the\n                              authentication in the spec for a single request.\n        :type _request_auth: dict, optional\n        :param _content_type: force content-type for the request.\n        :type _content_type: str, Optional\n        :param _headers: set to override the headers for a single\n                         request; this effectively ignores the headers\n                         in the spec for a single request.\n        :type _headers: dict, optional\n        :param _host_index: set to override the host_index for a single\n                            request; this effectively ignores the host_index\n                            in the spec for a single request.\n        :type _host_index: int, optional\n        :return: Returns the result object.\n        \"\"\" # noqa: E501\n        warnings.warn(\"POST /workspace/{workspaceId}/public/{isPublic} is deprecated.\", DeprecationWarning)\n\n        _param = self._update_public_status_workspace_deprecated_serialize(\n            workspace_id=workspace_id,\n            is_public=is_public,\n            x_daytona_organization_id=x_daytona_organization_id,\n            _request_auth=_request_auth,\n            _content_type=_content_type,\n            _headers=_headers,\n            _host_index=_host_index\n        )\n\n        _response_types_map: Dict[str, Optional[str]] = {\n            '201': None,\n        }\n        response_data = self.api_client.call_api(\n            *_param,\n            _request_timeout=_request_timeout\n        )\n        return response_data.response\n\n\n    def _update_public_status_workspace_deprecated_serialize(\n        self,\n        workspace_id,\n        is_public,\n        x_daytona_organization_id,\n        _request_auth,\n        _content_type,\n        _headers,\n        _host_index,\n    ) -> RequestSerialized:\n\n        _host = None\n\n        _collection_formats: Dict[str, str] = {\n        }\n\n        _path_params: Dict[str, str] = {}\n        _query_params: List[Tuple[str, str]] = []\n        _header_params: Dict[str, Optional[str]] = _headers or {}\n        _form_params: List[Tuple[str, str]] = []\n        _files: Dict[\n            str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]\n        ] = {}\n        _body_params: Optional[bytes] = None\n\n        # process the path parameters\n        if workspace_id is not None:\n            _path_params['workspaceId'] = workspace_id\n        if is_public is not None:\n            _path_params['isPublic'] = is_public\n        # process the query parameters\n        # process the header parameters\n        if x_daytona_organization_id is not None:\n            _header_params['X-Daytona-Organization-ID'] = x_daytona_organization_id\n        # process the form parameters\n        # process the body parameter\n\n\n\n\n        # authentication setting\n        _auth_settings: List[str] = [\n            'bearer', \n            'oauth2'\n        ]\n\n        return self.api_client.param_serialize(\n            method='POST',\n            resource_path='/workspace/{workspaceId}/public/{isPublic}',\n            path_params=_path_params,\n            query_params=_query_params,\n            header_params=_header_params,\n            body=_body_params,\n            post_params=_form_params,\n            files=_files,\n            auth_settings=_auth_settings,\n            collection_formats=_collection_formats,\n            _host=_host,\n            _request_auth=_request_auth\n        )\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api_client.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nimport datetime\nfrom dateutil.parser import parse\nfrom enum import Enum\nimport decimal\nimport json\nimport mimetypes\nimport os\nimport re\nimport tempfile\n\nfrom urllib.parse import quote\nfrom typing import Tuple, Optional, List, Dict, Union\nfrom pydantic import SecretStr\n\nfrom daytona_api_client.configuration import Configuration\nfrom daytona_api_client.api_response import ApiResponse, T as ApiResponseT\nimport daytona_api_client.models\nfrom daytona_api_client import rest\nfrom daytona_api_client.exceptions import (\n    ApiValueError,\n    ApiException,\n    BadRequestException,\n    UnauthorizedException,\n    ForbiddenException,\n    NotFoundException,\n    ServiceException\n)\n\nRequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]]\n\nclass ApiClient:\n    \"\"\"Generic API client for OpenAPI client library builds.\n\n    OpenAPI generic API client. This client handles the client-\n    server communication, and is invariant across implementations. Specifics of\n    the methods and models for each application are generated from the OpenAPI\n    templates.\n\n    :param configuration: .Configuration object for this client\n    :param header_name: a header to pass when making calls to the API.\n    :param header_value: a header value to pass when making calls to\n        the API.\n    :param cookie: a cookie to include in the header when making calls\n        to the API\n    \"\"\"\n\n    PRIMITIVE_TYPES = (float, bool, bytes, str, int)\n    NATIVE_TYPES_MAPPING = {\n        'int': int,\n        'long': int, # TODO remove as only py3 is supported?\n        'float': float,\n        'str': str,\n        'bool': bool,\n        'date': datetime.date,\n        'datetime': datetime.datetime,\n        'decimal': decimal.Decimal,\n        'object': object,\n    }\n    _pool = None\n\n    def __init__(\n        self,\n        configuration=None,\n        header_name=None,\n        header_value=None,\n        cookie=None\n    ) -> None:\n        # use default configuration if none is provided\n        if configuration is None:\n            configuration = Configuration.get_default()\n        self.configuration = configuration\n\n        self.rest_client = rest.RESTClientObject(configuration)\n        self.default_headers = {}\n        if header_name is not None:\n            self.default_headers[header_name] = header_value\n        self.cookie = cookie\n        # Set default User-Agent.\n        self.user_agent = 'OpenAPI-Generator/0.0.0-dev/python'\n        self.client_side_validation = configuration.client_side_validation\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        pass\n\n    @property\n    def user_agent(self):\n        \"\"\"User agent for this API client\"\"\"\n        return self.default_headers['User-Agent']\n\n    @user_agent.setter\n    def user_agent(self, value):\n        self.default_headers['User-Agent'] = value\n\n    def set_default_header(self, header_name, header_value):\n        self.default_headers[header_name] = header_value\n\n\n    _default = None\n\n    @classmethod\n    def get_default(cls):\n        \"\"\"Return new instance of ApiClient.\n\n        This method returns newly created, based on default constructor,\n        object of ApiClient class or returns a copy of default\n        ApiClient.\n\n        :return: The ApiClient object.\n        \"\"\"\n        if cls._default is None:\n            cls._default = ApiClient()\n        return cls._default\n\n    @classmethod\n    def set_default(cls, default):\n        \"\"\"Set default instance of ApiClient.\n\n        It stores default ApiClient.\n\n        :param default: object of ApiClient.\n        \"\"\"\n        cls._default = default\n\n    def param_serialize(\n        self,\n        method,\n        resource_path,\n        path_params=None,\n        query_params=None,\n        header_params=None,\n        body=None,\n        post_params=None,\n        files=None, auth_settings=None,\n        collection_formats=None,\n        _host=None,\n        _request_auth=None\n    ) -> RequestSerialized:\n\n        \"\"\"Builds the HTTP request params needed by the request.\n        :param method: Method to call.\n        :param resource_path: Path to method endpoint.\n        :param path_params: Path parameters in the url.\n        :param query_params: Query parameters in the url.\n        :param header_params: Header parameters to be\n            placed in the request header.\n        :param body: Request body.\n        :param post_params dict: Request post form parameters,\n            for `application/x-www-form-urlencoded`, `multipart/form-data`.\n        :param auth_settings list: Auth Settings names for the request.\n        :param files dict: key -> filename, value -> filepath,\n            for `multipart/form-data`.\n        :param collection_formats: dict of collection formats for path, query,\n            header, and post parameters.\n        :param _request_auth: set to override the auth_settings for an a single\n                              request; this effectively ignores the authentication\n                              in the spec for a single request.\n        :return: tuple of form (path, http_method, query_params, header_params,\n            body, post_params, files)\n        \"\"\"\n\n        config = self.configuration\n\n        # header parameters\n        header_params = header_params or {}\n        header_params.update(self.default_headers)\n        if self.cookie:\n            header_params['Cookie'] = self.cookie\n        if header_params:\n            header_params = self.sanitize_for_serialization(header_params)\n            header_params = dict(\n                self.parameters_to_tuples(header_params,collection_formats)\n            )\n\n        # path parameters\n        if path_params:\n            path_params = self.sanitize_for_serialization(path_params)\n            path_params = self.parameters_to_tuples(\n                path_params,\n                collection_formats\n            )\n            for k, v in path_params:\n                # specified safe chars, encode everything\n                resource_path = resource_path.replace(\n                    '{%s}' % k,\n                    quote(str(v), safe=config.safe_chars_for_path_param)\n                )\n\n        # post parameters\n        if post_params or files:\n            post_params = post_params if post_params else []\n            post_params = self.sanitize_for_serialization(post_params)\n            post_params = self.parameters_to_tuples(\n                post_params,\n                collection_formats\n            )\n            if files:\n                post_params.extend(self.files_parameters(files))\n\n        # auth setting\n        self.update_params_for_auth(\n            header_params,\n            query_params,\n            auth_settings,\n            resource_path,\n            method,\n            body,\n            request_auth=_request_auth\n        )\n\n        # body\n        if body:\n            body = self.sanitize_for_serialization(body)\n\n        # request url\n        if _host is None or self.configuration.ignore_operation_servers:\n            url = self.configuration.host + resource_path\n        else:\n            # use server/host defined in path or operation instead\n            url = _host + resource_path\n\n        # query parameters\n        if query_params:\n            query_params = self.sanitize_for_serialization(query_params)\n            url_query = self.parameters_to_url_query(\n                query_params,\n                collection_formats\n            )\n            url += \"?\" + url_query\n\n        return method, url, header_params, body, post_params\n\n\n    def call_api(\n        self,\n        method,\n        url,\n        header_params=None,\n        body=None,\n        post_params=None,\n        _request_timeout=None\n    ) -> rest.RESTResponse:\n        \"\"\"Makes the HTTP request (synchronous)\n        :param method: Method to call.\n        :param url: Path to method endpoint.\n        :param header_params: Header parameters to be\n            placed in the request header.\n        :param body: Request body.\n        :param post_params dict: Request post form parameters,\n            for `application/x-www-form-urlencoded`, `multipart/form-data`.\n        :param _request_timeout: timeout setting for this request.\n        :return: RESTResponse\n        \"\"\"\n\n        try:\n            # perform request and return response\n            response_data = self.rest_client.request(\n                method, url,\n                headers=header_params,\n                body=body, post_params=post_params,\n                _request_timeout=_request_timeout\n            )\n\n        except ApiException as e:\n            raise e\n\n        return response_data\n\n    def response_deserialize(\n        self,\n        response_data: rest.RESTResponse,\n        response_types_map: Optional[Dict[str, ApiResponseT]]=None\n    ) -> ApiResponse[ApiResponseT]:\n        \"\"\"Deserializes response into an object.\n        :param response_data: RESTResponse object to be deserialized.\n        :param response_types_map: dict of response types.\n        :return: ApiResponse\n        \"\"\"\n\n        msg = \"RESTResponse.read() must be called before passing it to response_deserialize()\"\n        assert response_data.data is not None, msg\n\n        response_type = response_types_map.get(str(response_data.status), None)\n        if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599:\n            # if not found, look for '1XX', '2XX', etc.\n            response_type = response_types_map.get(str(response_data.status)[0] + \"XX\", None)\n\n        # deserialize response data\n        response_text = None\n        return_data = None\n        try:\n            if response_type == \"bytearray\":\n                return_data = response_data.data\n            elif response_type == \"file\":\n                return_data = self.__deserialize_file(response_data)\n            elif response_type is not None:\n                match = None\n                content_type = response_data.getheader('content-type')\n                if content_type is not None:\n                    match = re.search(r\"charset=([a-zA-Z\\-\\d]+)[\\s;]?\", content_type)\n                encoding = match.group(1) if match else \"utf-8\"\n                response_text = response_data.data.decode(encoding)\n                return_data = self.deserialize(response_text, response_type, content_type)\n        finally:\n            if not 200 <= response_data.status <= 299:\n                raise ApiException.from_response(\n                    http_resp=response_data,\n                    body=response_text,\n                    data=return_data,\n                )\n\n        return ApiResponse(\n            status_code = response_data.status,\n            data = return_data,\n            headers = response_data.getheaders(),\n            raw_data = response_data.data\n        )\n\n    def sanitize_for_serialization(self, obj):\n        \"\"\"Builds a JSON POST object.\n\n        If obj is None, return None.\n        If obj is SecretStr, return obj.get_secret_value()\n        If obj is str, int, long, float, bool, return directly.\n        If obj is datetime.datetime, datetime.date\n            convert to string in iso8601 format.\n        If obj is decimal.Decimal return string representation.\n        If obj is list, sanitize each element in the list.\n        If obj is dict, return the dict.\n        If obj is OpenAPI model, return the properties dict.\n\n        :param obj: The data to serialize.\n        :return: The serialized form of data.\n        \"\"\"\n        if obj is None:\n            return None\n        elif isinstance(obj, Enum):\n            return obj.value\n        elif isinstance(obj, SecretStr):\n            return obj.get_secret_value()\n        elif isinstance(obj, self.PRIMITIVE_TYPES):\n            return obj\n        elif isinstance(obj, list):\n            return [\n                self.sanitize_for_serialization(sub_obj) for sub_obj in obj\n            ]\n        elif isinstance(obj, tuple):\n            return tuple(\n                self.sanitize_for_serialization(sub_obj) for sub_obj in obj\n            )\n        elif isinstance(obj, (datetime.datetime, datetime.date)):\n            return obj.isoformat()\n        elif isinstance(obj, decimal.Decimal):\n            return str(obj)\n\n        elif isinstance(obj, dict):\n            obj_dict = obj\n        else:\n            # Convert model obj to dict except\n            # attributes `openapi_types`, `attribute_map`\n            # and attributes which value is not None.\n            # Convert attribute name to json key in\n            # model definition for request.\n            if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')):\n                obj_dict = obj.to_dict()\n            else:\n                obj_dict = obj.__dict__\n\n        return {\n            key: self.sanitize_for_serialization(val)\n            for key, val in obj_dict.items()\n        }\n\n    def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]):\n        \"\"\"Deserializes response into an object.\n\n        :param response: RESTResponse object to be deserialized.\n        :param response_type: class literal for\n            deserialized object, or string of class name.\n        :param content_type: content type of response.\n\n        :return: deserialized object.\n        \"\"\"\n\n        # fetch data from response object\n        if content_type is None:\n            try:\n                data = json.loads(response_text)\n            except ValueError:\n                data = response_text\n        elif re.match(r'^application/(json|[\\w!#$&.+-^_]+\\+json)\\s*(;|$)', content_type, re.IGNORECASE):\n            if response_text == \"\":\n                data = \"\"\n            else:\n                data = json.loads(response_text)\n        elif re.match(r'^text\\/[a-z.+-]+\\s*(;|$)', content_type, re.IGNORECASE):\n            data = response_text\n        else:\n            raise ApiException(\n                status=0,\n                reason=\"Unsupported content type: {0}\".format(content_type)\n            )\n\n        return self.__deserialize(data, response_type)\n\n    def __deserialize(self, data, klass):\n        \"\"\"Deserializes dict, list, str into an object.\n\n        :param data: dict, list or str.\n        :param klass: class literal, or string of class name.\n\n        :return: object.\n        \"\"\"\n        if data is None:\n            return None\n\n        if isinstance(klass, str):\n            if klass.startswith('List['):\n                m = re.match(r'List\\[(.*)]', klass)\n                assert m is not None, \"Malformed List type definition\"\n                sub_kls = m.group(1)\n                return [self.__deserialize(sub_data, sub_kls)\n                        for sub_data in data]\n\n            if klass.startswith('Dict['):\n                m = re.match(r'Dict\\[([^,]*), (.*)]', klass)\n                assert m is not None, \"Malformed Dict type definition\"\n                sub_kls = m.group(2)\n                return {k: self.__deserialize(v, sub_kls)\n                        for k, v in data.items()}\n\n            # convert str to class\n            if klass in self.NATIVE_TYPES_MAPPING:\n                klass = self.NATIVE_TYPES_MAPPING[klass]\n            else:\n                klass = getattr(daytona_api_client.models, klass)\n\n        if klass in self.PRIMITIVE_TYPES:\n            return self.__deserialize_primitive(data, klass)\n        elif klass == object:\n            return self.__deserialize_object(data)\n        elif klass == datetime.date:\n            return self.__deserialize_date(data)\n        elif klass == datetime.datetime:\n            return self.__deserialize_datetime(data)\n        elif klass == decimal.Decimal:\n            return decimal.Decimal(data)\n        elif issubclass(klass, Enum):\n            return self.__deserialize_enum(data, klass)\n        else:\n            return self.__deserialize_model(data, klass)\n\n    def parameters_to_tuples(self, params, collection_formats):\n        \"\"\"Get parameters as list of tuples, formatting collections.\n\n        :param params: Parameters as dict or list of two-tuples\n        :param dict collection_formats: Parameter collection formats\n        :return: Parameters as list of tuples, collections formatted\n        \"\"\"\n        new_params: List[Tuple[str, str]] = []\n        if collection_formats is None:\n            collection_formats = {}\n        for k, v in params.items() if isinstance(params, dict) else params:\n            if k in collection_formats:\n                collection_format = collection_formats[k]\n                if collection_format == 'multi':\n                    new_params.extend((k, value) for value in v)\n                else:\n                    if collection_format == 'ssv':\n                        delimiter = ' '\n                    elif collection_format == 'tsv':\n                        delimiter = '\\t'\n                    elif collection_format == 'pipes':\n                        delimiter = '|'\n                    else:  # csv is the default\n                        delimiter = ','\n                    new_params.append(\n                        (k, delimiter.join(str(value) for value in v)))\n            else:\n                new_params.append((k, v))\n        return new_params\n\n    def parameters_to_url_query(self, params, collection_formats):\n        \"\"\"Get parameters as list of tuples, formatting collections.\n\n        :param params: Parameters as dict or list of two-tuples\n        :param dict collection_formats: Parameter collection formats\n        :return: URL query string (e.g. a=Hello%20World&b=123)\n        \"\"\"\n        new_params: List[Tuple[str, str]] = []\n        if collection_formats is None:\n            collection_formats = {}\n        for k, v in params.items() if isinstance(params, dict) else params:\n            if isinstance(v, bool):\n                v = str(v).lower()\n            if isinstance(v, (int, float)):\n                v = str(v)\n            if isinstance(v, dict):\n                v = json.dumps(v)\n\n            if k in collection_formats:\n                collection_format = collection_formats[k]\n                if collection_format == 'multi':\n                    new_params.extend((k, quote(str(value))) for value in v)\n                else:\n                    if collection_format == 'ssv':\n                        delimiter = ' '\n                    elif collection_format == 'tsv':\n                        delimiter = '\\t'\n                    elif collection_format == 'pipes':\n                        delimiter = '|'\n                    else:  # csv is the default\n                        delimiter = ','\n                    new_params.append(\n                        (k, delimiter.join(quote(str(value)) for value in v))\n                    )\n            else:\n                new_params.append((k, quote(str(v))))\n\n        return \"&\".join([\"=\".join(map(str, item)) for item in new_params])\n\n    def files_parameters(\n        self,\n        files: Dict[str, Union[str, bytes, List[str], List[bytes], Tuple[str, bytes]]],\n    ):\n        \"\"\"Builds form parameters.\n\n        :param files: File parameters.\n        :return: Form parameters with files.\n        \"\"\"\n        params = []\n        for k, v in files.items():\n            if isinstance(v, str):\n                with open(v, 'rb') as f:\n                    filename = os.path.basename(f.name)\n                    filedata = f.read()\n            elif isinstance(v, bytes):\n                filename = k\n                filedata = v\n            elif isinstance(v, tuple):\n                filename, filedata = v\n            elif isinstance(v, list):\n                for file_param in v:\n                    params.extend(self.files_parameters({k: file_param}))\n                continue\n            else:\n                raise ValueError(\"Unsupported file value\")\n            mimetype = (\n                mimetypes.guess_type(filename)[0]\n                or 'application/octet-stream'\n            )\n            params.append(\n                tuple([k, tuple([filename, filedata, mimetype])])\n            )\n        return params\n\n    def select_header_accept(self, accepts: List[str]) -> Optional[str]:\n        \"\"\"Returns `Accept` based on an array of accepts provided.\n\n        :param accepts: List of headers.\n        :return: Accept (e.g. application/json).\n        \"\"\"\n        if not accepts:\n            return None\n\n        for accept in accepts:\n            if re.search('json', accept, re.IGNORECASE):\n                return accept\n\n        return accepts[0]\n\n    def select_header_content_type(self, content_types):\n        \"\"\"Returns `Content-Type` based on an array of content_types provided.\n\n        :param content_types: List of content-types.\n        :return: Content-Type (e.g. application/json).\n        \"\"\"\n        if not content_types:\n            return None\n\n        for content_type in content_types:\n            if re.search('json', content_type, re.IGNORECASE):\n                return content_type\n\n        return content_types[0]\n\n    def update_params_for_auth(\n        self,\n        headers,\n        queries,\n        auth_settings,\n        resource_path,\n        method,\n        body,\n        request_auth=None\n    ) -> None:\n        \"\"\"Updates header and query params based on authentication setting.\n\n        :param headers: Header parameters dict to be updated.\n        :param queries: Query parameters tuple list to be updated.\n        :param auth_settings: Authentication setting identifiers list.\n        :resource_path: A string representation of the HTTP request resource path.\n        :method: A string representation of the HTTP request method.\n        :body: A object representing the body of the HTTP request.\n        The object type is the return value of sanitize_for_serialization().\n        :param request_auth: if set, the provided settings will\n                             override the token in the configuration.\n        \"\"\"\n        if not auth_settings:\n            return\n\n        if request_auth:\n            self._apply_auth_params(\n                headers,\n                queries,\n                resource_path,\n                method,\n                body,\n                request_auth\n            )\n        else:\n            for auth in auth_settings:\n                auth_setting = self.configuration.auth_settings().get(auth)\n                if auth_setting:\n                    self._apply_auth_params(\n                        headers,\n                        queries,\n                        resource_path,\n                        method,\n                        body,\n                        auth_setting\n                    )\n\n    def _apply_auth_params(\n        self,\n        headers,\n        queries,\n        resource_path,\n        method,\n        body,\n        auth_setting\n    ) -> None:\n        \"\"\"Updates the request parameters based on a single auth_setting\n\n        :param headers: Header parameters dict to be updated.\n        :param queries: Query parameters tuple list to be updated.\n        :resource_path: A string representation of the HTTP request resource path.\n        :method: A string representation of the HTTP request method.\n        :body: A object representing the body of the HTTP request.\n        The object type is the return value of sanitize_for_serialization().\n        :param auth_setting: auth settings for the endpoint\n        \"\"\"\n        if auth_setting['in'] == 'cookie':\n            headers['Cookie'] = auth_setting['value']\n        elif auth_setting['in'] == 'header':\n            if auth_setting['type'] != 'http-signature':\n                headers[auth_setting['key']] = auth_setting['value']\n        elif auth_setting['in'] == 'query':\n            queries.append((auth_setting['key'], auth_setting['value']))\n        else:\n            raise ApiValueError(\n                'Authentication token must be in `query` or `header`'\n            )\n\n    def __deserialize_file(self, response):\n        \"\"\"Deserializes body to file\n\n        Saves response body into a file in a temporary folder,\n        using the filename from the `Content-Disposition` header if provided.\n\n        handle file downloading\n        save response body into a tmp file and return the instance\n\n        :param response:  RESTResponse.\n        :return: file path.\n        \"\"\"\n        fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)\n        os.close(fd)\n        os.remove(path)\n\n        content_disposition = response.getheader(\"Content-Disposition\")\n        if content_disposition:\n            m = re.search(\n                r'filename=[\\'\"]?([^\\'\"\\s]+)[\\'\"]?',\n                content_disposition\n            )\n            assert m is not None, \"Unexpected 'content-disposition' header value\"\n            filename = m.group(1)\n            path = os.path.join(os.path.dirname(path), filename)\n\n        with open(path, \"wb\") as f:\n            f.write(response.data)\n\n        return path\n\n    def __deserialize_primitive(self, data, klass):\n        \"\"\"Deserializes string to primitive type.\n\n        :param data: str.\n        :param klass: class literal.\n\n        :return: int, long, float, str, bool.\n        \"\"\"\n        try:\n            return klass(data)\n        except UnicodeEncodeError:\n            return str(data)\n        except TypeError:\n            return data\n\n    def __deserialize_object(self, value):\n        \"\"\"Return an original value.\n\n        :return: object.\n        \"\"\"\n        return value\n\n    def __deserialize_date(self, string):\n        \"\"\"Deserializes string to date.\n\n        :param string: str.\n        :return: date.\n        \"\"\"\n        try:\n            return parse(string).date()\n        except ImportError:\n            return string\n        except ValueError:\n            raise rest.ApiException(\n                status=0,\n                reason=\"Failed to parse `{0}` as date object\".format(string)\n            )\n\n    def __deserialize_datetime(self, string):\n        \"\"\"Deserializes string to datetime.\n\n        The string should be in iso8601 datetime format.\n\n        :param string: str.\n        :return: datetime.\n        \"\"\"\n        try:\n            return parse(string)\n        except ImportError:\n            return string\n        except ValueError:\n            raise rest.ApiException(\n                status=0,\n                reason=(\n                    \"Failed to parse `{0}` as datetime object\"\n                    .format(string)\n                )\n            )\n\n    def __deserialize_enum(self, data, klass):\n        \"\"\"Deserializes primitive type to enum.\n\n        :param data: primitive type.\n        :param klass: class literal.\n        :return: enum value.\n        \"\"\"\n        try:\n            return klass(data)\n        except ValueError:\n            raise rest.ApiException(\n                status=0,\n                reason=(\n                    \"Failed to parse `{0}` as `{1}`\"\n                    .format(data, klass)\n                )\n            )\n\n    def __deserialize_model(self, data, klass):\n        \"\"\"Deserializes list or dict to model.\n\n        :param data: dict, list.\n        :param klass: class literal.\n        :return: model object.\n        \"\"\"\n\n        return klass.from_dict(data)\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/api_response.py",
    "content": "\"\"\"API response object.\"\"\"\n\nfrom __future__ import annotations\nfrom typing import Optional, Generic, Mapping, TypeVar\nfrom pydantic import Field, StrictInt, StrictBytes, BaseModel\n\nT = TypeVar(\"T\")\n\nclass ApiResponse(BaseModel, Generic[T]):\n    \"\"\"\n    API response object\n    \"\"\"\n\n    status_code: StrictInt = Field(description=\"HTTP status code\")\n    headers: Optional[Mapping[str, str]] = Field(None, description=\"HTTP headers\")\n    data: T = Field(description=\"Deserialized data given the data type\")\n    raw_data: StrictBytes = Field(description=\"Raw data (HTTP response body)\")\n\n    model_config = {\n        \"arbitrary_types_allowed\": True\n    }\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/configuration.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nimport copy\nimport http.client as httplib\nimport logging\nfrom logging import FileHandler\nimport multiprocessing\nimport sys\nfrom typing import Any, ClassVar, Dict, List, Literal, Optional, TypedDict, Union\nfrom typing_extensions import NotRequired, Self\n\nimport urllib3\n\n\nJSON_SCHEMA_VALIDATION_KEYWORDS = {\n    'multipleOf', 'maximum', 'exclusiveMaximum',\n    'minimum', 'exclusiveMinimum', 'maxLength',\n    'minLength', 'pattern', 'maxItems', 'minItems'\n}\n\nServerVariablesT = Dict[str, str]\n\nGenericAuthSetting = TypedDict(\n    \"GenericAuthSetting\",\n    {\n        \"type\": str,\n        \"in\": str,\n        \"key\": str,\n        \"value\": str,\n    },\n)\n\n\nOAuth2AuthSetting = TypedDict(\n    \"OAuth2AuthSetting\",\n    {\n        \"type\": Literal[\"oauth2\"],\n        \"in\": Literal[\"header\"],\n        \"key\": Literal[\"Authorization\"],\n        \"value\": str,\n    },\n)\n\n\nAPIKeyAuthSetting = TypedDict(\n    \"APIKeyAuthSetting\",\n    {\n        \"type\": Literal[\"api_key\"],\n        \"in\": str,\n        \"key\": str,\n        \"value\": Optional[str],\n    },\n)\n\n\nBasicAuthSetting = TypedDict(\n    \"BasicAuthSetting\",\n    {\n        \"type\": Literal[\"basic\"],\n        \"in\": Literal[\"header\"],\n        \"key\": Literal[\"Authorization\"],\n        \"value\": Optional[str],\n    },\n)\n\n\nBearerFormatAuthSetting = TypedDict(\n    \"BearerFormatAuthSetting\",\n    {\n        \"type\": Literal[\"bearer\"],\n        \"in\": Literal[\"header\"],\n        \"format\": Literal[\"JWT\"],\n        \"key\": Literal[\"Authorization\"],\n        \"value\": str,\n    },\n)\n\n\nBearerAuthSetting = TypedDict(\n    \"BearerAuthSetting\",\n    {\n        \"type\": Literal[\"bearer\"],\n        \"in\": Literal[\"header\"],\n        \"key\": Literal[\"Authorization\"],\n        \"value\": str,\n    },\n)\n\n\nHTTPSignatureAuthSetting = TypedDict(\n    \"HTTPSignatureAuthSetting\",\n    {\n        \"type\": Literal[\"http-signature\"],\n        \"in\": Literal[\"header\"],\n        \"key\": Literal[\"Authorization\"],\n        \"value\": None,\n    },\n)\n\n\nAuthSettings = TypedDict(\n    \"AuthSettings\",\n    {\n        \"bearer\": BearerFormatAuthSetting,\n    },\n    total=False,\n)\n\n\nclass HostSettingVariable(TypedDict):\n    description: str\n    default_value: str\n    enum_values: List[str]\n\n\nclass HostSetting(TypedDict):\n    url: str\n    description: str\n    variables: NotRequired[Dict[str, HostSettingVariable]]\n\n\nclass Configuration:\n    \"\"\"This class contains various settings of the API client.\n\n    :param host: Base url.\n    :param ignore_operation_servers\n      Boolean to ignore operation servers for the API client.\n      Config will use `host` as the base url regardless of the operation servers.\n    :param api_key: Dict to store API key(s).\n      Each entry in the dict specifies an API key.\n      The dict key is the name of the security scheme in the OAS specification.\n      The dict value is the API key secret.\n    :param api_key_prefix: Dict to store API prefix (e.g. Bearer).\n      The dict key is the name of the security scheme in the OAS specification.\n      The dict value is an API key prefix when generating the auth data.\n    :param username: Username for HTTP basic authentication.\n    :param password: Password for HTTP basic authentication.\n    :param access_token: Access token.\n    :param server_index: Index to servers configuration.\n    :param server_variables: Mapping with string values to replace variables in\n      templated server configuration. The validation of enums is performed for\n      variables with defined enum values before.\n    :param server_operation_index: Mapping from operation ID to an index to server\n      configuration.\n    :param server_operation_variables: Mapping from operation ID to a mapping with\n      string values to replace variables in templated server configuration.\n      The validation of enums is performed for variables with defined enum\n      values before.\n    :param ssl_ca_cert: str - the path to a file of concatenated CA certificates\n      in PEM format.\n    :param retries: Number of retries for API requests.\n    :param ca_cert_data: verify the peer using concatenated CA certificate data\n      in PEM (str) or DER (bytes) format.\n\n    :Example:\n    \"\"\"\n\n    _default: ClassVar[Optional[Self]] = None\n\n    def __init__(\n        self,\n        host: Optional[str]=None,\n        api_key: Optional[Dict[str, str]]=None,\n        api_key_prefix: Optional[Dict[str, str]]=None,\n        username: Optional[str]=None,\n        password: Optional[str]=None,\n        access_token: Optional[str]=None,\n        server_index: Optional[int]=None,\n        server_variables: Optional[ServerVariablesT]=None,\n        server_operation_index: Optional[Dict[int, int]]=None,\n        server_operation_variables: Optional[Dict[int, ServerVariablesT]]=None,\n        ignore_operation_servers: bool=False,\n        ssl_ca_cert: Optional[str]=None,\n        retries: Optional[int] = None,\n        ca_cert_data: Optional[Union[str, bytes]] = None,\n        *,\n        debug: Optional[bool] = None,\n    ) -> None:\n        \"\"\"Constructor\n        \"\"\"\n        self._base_path = \"http://localhost:3000\" if host is None else host\n        \"\"\"Default Base url\n        \"\"\"\n        self.server_index = 0 if server_index is None and host is None else server_index\n        self.server_operation_index = server_operation_index or {}\n        \"\"\"Default server index\n        \"\"\"\n        self.server_variables = server_variables or {}\n        self.server_operation_variables = server_operation_variables or {}\n        \"\"\"Default server variables\n        \"\"\"\n        self.ignore_operation_servers = ignore_operation_servers\n        \"\"\"Ignore operation servers\n        \"\"\"\n        self.temp_folder_path = None\n        \"\"\"Temp file folder for downloading files\n        \"\"\"\n        # Authentication Settings\n        self.api_key = {}\n        if api_key:\n            self.api_key = api_key\n        \"\"\"dict to store API key(s)\n        \"\"\"\n        self.api_key_prefix = {}\n        if api_key_prefix:\n            self.api_key_prefix = api_key_prefix\n        \"\"\"dict to store API prefix (e.g. Bearer)\n        \"\"\"\n        self.refresh_api_key_hook = None\n        \"\"\"function hook to refresh API key if expired\n        \"\"\"\n        self.username = username\n        \"\"\"Username for HTTP basic authentication\n        \"\"\"\n        self.password = password\n        \"\"\"Password for HTTP basic authentication\n        \"\"\"\n        self.access_token = access_token\n        \"\"\"Access token\n        \"\"\"\n        self.logger = {}\n        \"\"\"Logging Settings\n        \"\"\"\n        self.logger[\"package_logger\"] = logging.getLogger(\"daytona_api_client\")\n        self.logger[\"urllib3_logger\"] = logging.getLogger(\"urllib3\")\n        self.logger_format = '%(asctime)s %(levelname)s %(message)s'\n        \"\"\"Log format\n        \"\"\"\n        self.logger_stream_handler = None\n        \"\"\"Log stream handler\n        \"\"\"\n        self.logger_file_handler: Optional[FileHandler] = None\n        \"\"\"Log file handler\n        \"\"\"\n        self.logger_file = None\n        \"\"\"Debug file location\n        \"\"\"\n        if debug is not None:\n            self.debug = debug\n        else:\n            self.__debug = False\n        \"\"\"Debug switch\n        \"\"\"\n\n        self.verify_ssl = True\n        \"\"\"SSL/TLS verification\n           Set this to false to skip verifying SSL certificate when calling API\n           from https server.\n        \"\"\"\n        self.ssl_ca_cert = ssl_ca_cert\n        \"\"\"Set this to customize the certificate file to verify the peer.\n        \"\"\"\n        self.ca_cert_data = ca_cert_data\n        \"\"\"Set this to verify the peer using PEM (str) or DER (bytes)\n           certificate data.\n        \"\"\"\n        self.cert_file = None\n        \"\"\"client certificate file\n        \"\"\"\n        self.key_file = None\n        \"\"\"client key file\n        \"\"\"\n        self.assert_hostname = None\n        \"\"\"Set this to True/False to enable/disable SSL hostname verification.\n        \"\"\"\n        self.tls_server_name = None\n        \"\"\"SSL/TLS Server Name Indication (SNI)\n           Set this to the SNI value expected by the server.\n        \"\"\"\n\n        self.connection_pool_maxsize = multiprocessing.cpu_count() * 5\n        \"\"\"urllib3 connection pool's maximum number of connections saved\n           per pool. urllib3 uses 1 connection as default value, but this is\n           not the best value when you are making a lot of possibly parallel\n           requests to the same host, which is often the case here.\n           cpu_count * 5 is used as default value to increase performance.\n        \"\"\"\n\n        self.proxy: Optional[str] = None\n        \"\"\"Proxy URL\n        \"\"\"\n        self.proxy_headers = None\n        \"\"\"Proxy headers\n        \"\"\"\n        self.safe_chars_for_path_param = ''\n        \"\"\"Safe chars for path_param\n        \"\"\"\n        self.retries = retries\n        \"\"\"Adding retries to override urllib3 default value 3\n        \"\"\"\n        # Enable client side validation\n        self.client_side_validation = True\n\n        self.socket_options = None\n        \"\"\"Options to pass down to the underlying urllib3 socket\n        \"\"\"\n\n        self.datetime_format = \"%Y-%m-%dT%H:%M:%S.%f%z\"\n        \"\"\"datetime format\n        \"\"\"\n\n        self.date_format = \"%Y-%m-%d\"\n        \"\"\"date format\n        \"\"\"\n\n    def __deepcopy__(self, memo:  Dict[int, Any]) -> Self:\n        cls = self.__class__\n        result = cls.__new__(cls)\n        memo[id(self)] = result\n        for k, v in self.__dict__.items():\n            if k not in ('logger', 'logger_file_handler'):\n                setattr(result, k, copy.deepcopy(v, memo))\n        # shallow copy of loggers\n        result.logger = copy.copy(self.logger)\n        # use setters to configure loggers\n        result.logger_file = self.logger_file\n        result.debug = self.debug\n        return result\n\n    def __setattr__(self, name: str, value: Any) -> None:\n        object.__setattr__(self, name, value)\n\n    @classmethod\n    def set_default(cls, default: Optional[Self]) -> None:\n        \"\"\"Set default instance of configuration.\n\n        It stores default configuration, which can be\n        returned by get_default_copy method.\n\n        :param default: object of Configuration\n        \"\"\"\n        cls._default = default\n\n    @classmethod\n    def get_default_copy(cls) -> Self:\n        \"\"\"Deprecated. Please use `get_default` instead.\n\n        Deprecated. Please use `get_default` instead.\n\n        :return: The configuration object.\n        \"\"\"\n        return cls.get_default()\n\n    @classmethod\n    def get_default(cls) -> Self:\n        \"\"\"Return the default configuration.\n\n        This method returns newly created, based on default constructor,\n        object of Configuration class or returns a copy of default\n        configuration.\n\n        :return: The configuration object.\n        \"\"\"\n        if cls._default is None:\n            cls._default = cls()\n        return cls._default\n\n    @property\n    def logger_file(self) -> Optional[str]:\n        \"\"\"The logger file.\n\n        If the logger_file is None, then add stream handler and remove file\n        handler. Otherwise, add file handler and remove stream handler.\n\n        :param value: The logger_file path.\n        :type: str\n        \"\"\"\n        return self.__logger_file\n\n    @logger_file.setter\n    def logger_file(self, value: Optional[str]) -> None:\n        \"\"\"The logger file.\n\n        If the logger_file is None, then add stream handler and remove file\n        handler. Otherwise, add file handler and remove stream handler.\n\n        :param value: The logger_file path.\n        :type: str\n        \"\"\"\n        self.__logger_file = value\n        if self.__logger_file:\n            # If set logging file,\n            # then add file handler and remove stream handler.\n            self.logger_file_handler = logging.FileHandler(self.__logger_file)\n            self.logger_file_handler.setFormatter(self.logger_formatter)\n            for _, logger in self.logger.items():\n                logger.addHandler(self.logger_file_handler)\n\n    @property\n    def debug(self) -> bool:\n        \"\"\"Debug status\n\n        :param value: The debug status, True or False.\n        :type: bool\n        \"\"\"\n        return self.__debug\n\n    @debug.setter\n    def debug(self, value: bool) -> None:\n        \"\"\"Debug status\n\n        :param value: The debug status, True or False.\n        :type: bool\n        \"\"\"\n        self.__debug = value\n        if self.__debug:\n            # if debug status is True, turn on debug logging\n            for _, logger in self.logger.items():\n                logger.setLevel(logging.DEBUG)\n            # turn on httplib debug\n            httplib.HTTPConnection.debuglevel = 1\n        else:\n            # if debug status is False, turn off debug logging,\n            # setting log level to default `logging.WARNING`\n            for _, logger in self.logger.items():\n                logger.setLevel(logging.WARNING)\n            # turn off httplib debug\n            httplib.HTTPConnection.debuglevel = 0\n\n    @property\n    def logger_format(self) -> str:\n        \"\"\"The logger format.\n\n        The logger_formatter will be updated when sets logger_format.\n\n        :param value: The format string.\n        :type: str\n        \"\"\"\n        return self.__logger_format\n\n    @logger_format.setter\n    def logger_format(self, value: str) -> None:\n        \"\"\"The logger format.\n\n        The logger_formatter will be updated when sets logger_format.\n\n        :param value: The format string.\n        :type: str\n        \"\"\"\n        self.__logger_format = value\n        self.logger_formatter = logging.Formatter(self.__logger_format)\n\n    def get_api_key_with_prefix(self, identifier: str, alias: Optional[str]=None) -> Optional[str]:\n        \"\"\"Gets API key (with prefix if set).\n\n        :param identifier: The identifier of apiKey.\n        :param alias: The alternative identifier of apiKey.\n        :return: The token for api key authentication.\n        \"\"\"\n        if self.refresh_api_key_hook is not None:\n            self.refresh_api_key_hook(self)\n        key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None)\n        if key:\n            prefix = self.api_key_prefix.get(identifier)\n            if prefix:\n                return \"%s %s\" % (prefix, key)\n            else:\n                return key\n\n        return None\n\n    def get_basic_auth_token(self) -> Optional[str]:\n        \"\"\"Gets HTTP basic authentication header (string).\n\n        :return: The token for basic HTTP authentication.\n        \"\"\"\n        username = \"\"\n        if self.username is not None:\n            username = self.username\n        password = \"\"\n        if self.password is not None:\n            password = self.password\n        return urllib3.util.make_headers(\n            basic_auth=username + ':' + password\n        ).get('authorization')\n\n    def auth_settings(self)-> AuthSettings:\n        \"\"\"Gets Auth Settings dict for api client.\n\n        :return: The Auth Settings information dict.\n        \"\"\"\n        auth: AuthSettings = {}\n        if self.access_token is not None:\n            auth['bearer'] = {\n                'type': 'bearer',\n                'in': 'header',\n                'format': 'JWT',\n                'key': 'Authorization',\n                'value': 'Bearer ' + self.access_token\n            }\n        return auth\n\n    def to_debug_report(self) -> str:\n        \"\"\"Gets the essential information for debugging.\n\n        :return: The report for debugging.\n        \"\"\"\n        return \"Python SDK Debug Report:\\n\"\\\n               \"OS: {env}\\n\"\\\n               \"Python Version: {pyversion}\\n\"\\\n               \"Version of the API: 1.0\\n\"\\\n               \"SDK Package Version: 0.0.0-dev\".\\\n               format(env=sys.platform, pyversion=sys.version)\n\n    def get_host_settings(self) -> List[HostSetting]:\n        \"\"\"Gets an array of host settings\n\n        :return: An array of host settings\n        \"\"\"\n        return [\n            {\n                'url': \"http://localhost:3000\",\n                'description': \"No description provided\",\n            }\n        ]\n\n    def get_host_from_settings(\n        self,\n        index: Optional[int],\n        variables: Optional[ServerVariablesT]=None,\n        servers: Optional[List[HostSetting]]=None,\n    ) -> str:\n        \"\"\"Gets host URL based on the index and variables\n        :param index: array index of the host settings\n        :param variables: hash of variable and the corresponding value\n        :param servers: an array of host settings or None\n        :return: URL based on host settings\n        \"\"\"\n        if index is None:\n            return self._base_path\n\n        variables = {} if variables is None else variables\n        servers = self.get_host_settings() if servers is None else servers\n\n        try:\n            server = servers[index]\n        except IndexError:\n            raise ValueError(\n                \"Invalid index {0} when selecting the host settings. \"\n                \"Must be less than {1}\".format(index, len(servers)))\n\n        url = server['url']\n\n        # go through variables and replace placeholders\n        for variable_name, variable in server.get('variables', {}).items():\n            used_value = variables.get(\n                variable_name, variable['default_value'])\n\n            if 'enum_values' in variable \\\n                    and used_value not in variable['enum_values']:\n                raise ValueError(\n                    \"The variable `{0}` in the host URL has invalid value \"\n                    \"{1}. Must be {2}.\".format(\n                        variable_name, variables[variable_name],\n                        variable['enum_values']))\n\n            url = url.replace(\"{\" + variable_name + \"}\", used_value)\n\n        return url\n\n    @property\n    def host(self) -> str:\n        \"\"\"Return generated host.\"\"\"\n        return self.get_host_from_settings(self.server_index, variables=self.server_variables)\n\n    @host.setter\n    def host(self, value: str) -> None:\n        \"\"\"Fix base path.\"\"\"\n        self._base_path = value\n        self.server_index = None\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/exceptions.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\nfrom typing import Any, Optional\nfrom typing_extensions import Self\n\nclass OpenApiException(Exception):\n    \"\"\"The base exception class for all OpenAPIExceptions\"\"\"\n\n\nclass ApiTypeError(OpenApiException, TypeError):\n    def __init__(self, msg, path_to_item=None, valid_classes=None,\n                 key_type=None) -> None:\n        \"\"\" Raises an exception for TypeErrors\n\n        Args:\n            msg (str): the exception message\n\n        Keyword Args:\n            path_to_item (list): a list of keys an indices to get to the\n                                 current_item\n                                 None if unset\n            valid_classes (tuple): the primitive classes that current item\n                                   should be an instance of\n                                   None if unset\n            key_type (bool): False if our value is a value in a dict\n                             True if it is a key in a dict\n                             False if our item is an item in a list\n                             None if unset\n        \"\"\"\n        self.path_to_item = path_to_item\n        self.valid_classes = valid_classes\n        self.key_type = key_type\n        full_msg = msg\n        if path_to_item:\n            full_msg = \"{0} at {1}\".format(msg, render_path(path_to_item))\n        super(ApiTypeError, self).__init__(full_msg)\n\n\nclass ApiValueError(OpenApiException, ValueError):\n    def __init__(self, msg, path_to_item=None) -> None:\n        \"\"\"\n        Args:\n            msg (str): the exception message\n\n        Keyword Args:\n            path_to_item (list) the path to the exception in the\n                received_data dict. None if unset\n        \"\"\"\n\n        self.path_to_item = path_to_item\n        full_msg = msg\n        if path_to_item:\n            full_msg = \"{0} at {1}\".format(msg, render_path(path_to_item))\n        super(ApiValueError, self).__init__(full_msg)\n\n\nclass ApiAttributeError(OpenApiException, AttributeError):\n    def __init__(self, msg, path_to_item=None) -> None:\n        \"\"\"\n        Raised when an attribute reference or assignment fails.\n\n        Args:\n            msg (str): the exception message\n\n        Keyword Args:\n            path_to_item (None/list) the path to the exception in the\n                received_data dict\n        \"\"\"\n        self.path_to_item = path_to_item\n        full_msg = msg\n        if path_to_item:\n            full_msg = \"{0} at {1}\".format(msg, render_path(path_to_item))\n        super(ApiAttributeError, self).__init__(full_msg)\n\n\nclass ApiKeyError(OpenApiException, KeyError):\n    def __init__(self, msg, path_to_item=None) -> None:\n        \"\"\"\n        Args:\n            msg (str): the exception message\n\n        Keyword Args:\n            path_to_item (None/list) the path to the exception in the\n                received_data dict\n        \"\"\"\n        self.path_to_item = path_to_item\n        full_msg = msg\n        if path_to_item:\n            full_msg = \"{0} at {1}\".format(msg, render_path(path_to_item))\n        super(ApiKeyError, self).__init__(full_msg)\n\n\nclass ApiException(OpenApiException):\n\n    def __init__(\n        self, \n        status=None, \n        reason=None, \n        http_resp=None,\n        *,\n        body: Optional[str] = None,\n        data: Optional[Any] = None,\n    ) -> None:\n        self.status = status\n        self.reason = reason\n        self.body = body\n        self.data = data\n        self.headers = None\n\n        if http_resp:\n            if self.status is None:\n                self.status = http_resp.status\n            if self.reason is None:\n                self.reason = http_resp.reason\n            if self.body is None:\n                try:\n                    self.body = http_resp.data.decode('utf-8')\n                except Exception:\n                    pass\n            self.headers = http_resp.getheaders()\n\n    @classmethod\n    def from_response(\n        cls, \n        *, \n        http_resp, \n        body: Optional[str], \n        data: Optional[Any],\n    ) -> Self:\n        if http_resp.status == 400:\n            raise BadRequestException(http_resp=http_resp, body=body, data=data)\n\n        if http_resp.status == 401:\n            raise UnauthorizedException(http_resp=http_resp, body=body, data=data)\n\n        if http_resp.status == 403:\n            raise ForbiddenException(http_resp=http_resp, body=body, data=data)\n\n        if http_resp.status == 404:\n            raise NotFoundException(http_resp=http_resp, body=body, data=data)\n\n        # Added new conditions for 409 and 422\n        if http_resp.status == 409:\n            raise ConflictException(http_resp=http_resp, body=body, data=data)\n\n        if http_resp.status == 422:\n            raise UnprocessableEntityException(http_resp=http_resp, body=body, data=data)\n\n        if 500 <= http_resp.status <= 599:\n            raise ServiceException(http_resp=http_resp, body=body, data=data)\n        raise ApiException(http_resp=http_resp, body=body, data=data)\n\n    def __str__(self):\n        \"\"\"Custom error messages for exception\"\"\"\n        error_message = \"({0})\\n\"\\\n                        \"Reason: {1}\\n\".format(self.status, self.reason)\n        if self.headers:\n            error_message += \"HTTP response headers: {0}\\n\".format(\n                self.headers)\n\n        if self.data or self.body:\n            error_message += \"HTTP response body: {0}\\n\".format(self.data or self.body)\n\n        return error_message\n\n\nclass BadRequestException(ApiException):\n    pass\n\n\nclass NotFoundException(ApiException):\n    pass\n\n\nclass UnauthorizedException(ApiException):\n    pass\n\n\nclass ForbiddenException(ApiException):\n    pass\n\n\nclass ServiceException(ApiException):\n    pass\n\n\nclass ConflictException(ApiException):\n    \"\"\"Exception for HTTP 409 Conflict.\"\"\"\n    pass\n\n\nclass UnprocessableEntityException(ApiException):\n    \"\"\"Exception for HTTP 422 Unprocessable Entity.\"\"\"\n    pass\n\n\ndef render_path(path_to_item):\n    \"\"\"Returns a string representation of a path\"\"\"\n    result = \"\"\n    for pth in path_to_item:\n        if isinstance(pth, int):\n            result += \"[{0}]\".format(pth)\n        else:\n            result += \"['{0}']\".format(pth)\n    return result\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/__init__.py",
    "content": "# coding: utf-8\n\n# flake8: noqa\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\n# import models into model package\nfrom daytona_api_client.models.account_provider import AccountProvider\nfrom daytona_api_client.models.admin_create_runner import AdminCreateRunner\nfrom daytona_api_client.models.announcement import Announcement\nfrom daytona_api_client.models.api_key_list import ApiKeyList\nfrom daytona_api_client.models.api_key_response import ApiKeyResponse\nfrom daytona_api_client.models.audit_log import AuditLog\nfrom daytona_api_client.models.build_info import BuildInfo\nfrom daytona_api_client.models.command import Command\nfrom daytona_api_client.models.completion_context import CompletionContext\nfrom daytona_api_client.models.completion_item import CompletionItem\nfrom daytona_api_client.models.completion_list import CompletionList\nfrom daytona_api_client.models.compressed_screenshot_response import CompressedScreenshotResponse\nfrom daytona_api_client.models.computer_use_start_response import ComputerUseStartResponse\nfrom daytona_api_client.models.computer_use_status_response import ComputerUseStatusResponse\nfrom daytona_api_client.models.computer_use_stop_response import ComputerUseStopResponse\nfrom daytona_api_client.models.create_api_key import CreateApiKey\nfrom daytona_api_client.models.create_build_info import CreateBuildInfo\nfrom daytona_api_client.models.create_docker_registry import CreateDockerRegistry\nfrom daytona_api_client.models.create_linked_account import CreateLinkedAccount\nfrom daytona_api_client.models.create_organization import CreateOrganization\nfrom daytona_api_client.models.create_organization_invitation import CreateOrganizationInvitation\nfrom daytona_api_client.models.create_organization_quota import CreateOrganizationQuota\nfrom daytona_api_client.models.create_organization_role import CreateOrganizationRole\nfrom daytona_api_client.models.create_region import CreateRegion\nfrom daytona_api_client.models.create_region_response import CreateRegionResponse\nfrom daytona_api_client.models.create_runner import CreateRunner\nfrom daytona_api_client.models.create_runner_response import CreateRunnerResponse\nfrom daytona_api_client.models.create_sandbox import CreateSandbox\nfrom daytona_api_client.models.create_session_request import CreateSessionRequest\nfrom daytona_api_client.models.create_snapshot import CreateSnapshot\nfrom daytona_api_client.models.create_user import CreateUser\nfrom daytona_api_client.models.create_volume import CreateVolume\nfrom daytona_api_client.models.create_workspace import CreateWorkspace\nfrom daytona_api_client.models.daytona_configuration import DaytonaConfiguration\nfrom daytona_api_client.models.display_info_response import DisplayInfoResponse\nfrom daytona_api_client.models.docker_registry import DockerRegistry\nfrom daytona_api_client.models.download_files import DownloadFiles\nfrom daytona_api_client.models.execute_request import ExecuteRequest\nfrom daytona_api_client.models.execute_response import ExecuteResponse\nfrom daytona_api_client.models.file_info import FileInfo\nfrom daytona_api_client.models.file_status import FileStatus\nfrom daytona_api_client.models.git_add_request import GitAddRequest\nfrom daytona_api_client.models.git_branch_request import GitBranchRequest\nfrom daytona_api_client.models.git_checkout_request import GitCheckoutRequest\nfrom daytona_api_client.models.git_clone_request import GitCloneRequest\nfrom daytona_api_client.models.git_commit_info import GitCommitInfo\nfrom daytona_api_client.models.git_commit_request import GitCommitRequest\nfrom daytona_api_client.models.git_commit_response import GitCommitResponse\nfrom daytona_api_client.models.git_delete_branch_request import GitDeleteBranchRequest\nfrom daytona_api_client.models.git_repo_request import GitRepoRequest\nfrom daytona_api_client.models.git_status import GitStatus\nfrom daytona_api_client.models.health_controller_check200_response import HealthControllerCheck200Response\nfrom daytona_api_client.models.health_controller_check200_response_info_value import HealthControllerCheck200ResponseInfoValue\nfrom daytona_api_client.models.health_controller_check503_response import HealthControllerCheck503Response\nfrom daytona_api_client.models.job import Job\nfrom daytona_api_client.models.job_status import JobStatus\nfrom daytona_api_client.models.job_type import JobType\nfrom daytona_api_client.models.keyboard_hotkey_request import KeyboardHotkeyRequest\nfrom daytona_api_client.models.keyboard_press_request import KeyboardPressRequest\nfrom daytona_api_client.models.keyboard_type_request import KeyboardTypeRequest\nfrom daytona_api_client.models.list_branch_response import ListBranchResponse\nfrom daytona_api_client.models.log_entry import LogEntry\nfrom daytona_api_client.models.lsp_completion_params import LspCompletionParams\nfrom daytona_api_client.models.lsp_document_request import LspDocumentRequest\nfrom daytona_api_client.models.lsp_location import LspLocation\nfrom daytona_api_client.models.lsp_server_request import LspServerRequest\nfrom daytona_api_client.models.lsp_symbol import LspSymbol\nfrom daytona_api_client.models.match import Match\nfrom daytona_api_client.models.metric_data_point import MetricDataPoint\nfrom daytona_api_client.models.metric_series import MetricSeries\nfrom daytona_api_client.models.metrics_response import MetricsResponse\nfrom daytona_api_client.models.mouse_click_request import MouseClickRequest\nfrom daytona_api_client.models.mouse_click_response import MouseClickResponse\nfrom daytona_api_client.models.mouse_drag_request import MouseDragRequest\nfrom daytona_api_client.models.mouse_drag_response import MouseDragResponse\nfrom daytona_api_client.models.mouse_move_request import MouseMoveRequest\nfrom daytona_api_client.models.mouse_move_response import MouseMoveResponse\nfrom daytona_api_client.models.mouse_position import MousePosition\nfrom daytona_api_client.models.mouse_scroll_request import MouseScrollRequest\nfrom daytona_api_client.models.mouse_scroll_response import MouseScrollResponse\nfrom daytona_api_client.models.oidc_config import OidcConfig\nfrom daytona_api_client.models.organization import Organization\nfrom daytona_api_client.models.organization_invitation import OrganizationInvitation\nfrom daytona_api_client.models.organization_role import OrganizationRole\nfrom daytona_api_client.models.organization_sandbox_default_limited_network_egress import OrganizationSandboxDefaultLimitedNetworkEgress\nfrom daytona_api_client.models.organization_suspension import OrganizationSuspension\nfrom daytona_api_client.models.organization_usage_overview import OrganizationUsageOverview\nfrom daytona_api_client.models.organization_user import OrganizationUser\nfrom daytona_api_client.models.otel_config import OtelConfig\nfrom daytona_api_client.models.paginated_audit_logs import PaginatedAuditLogs\nfrom daytona_api_client.models.paginated_jobs import PaginatedJobs\nfrom daytona_api_client.models.paginated_logs import PaginatedLogs\nfrom daytona_api_client.models.paginated_sandboxes import PaginatedSandboxes\nfrom daytona_api_client.models.paginated_snapshots import PaginatedSnapshots\nfrom daytona_api_client.models.paginated_traces import PaginatedTraces\nfrom daytona_api_client.models.poll_jobs_response import PollJobsResponse\nfrom daytona_api_client.models.port_preview_url import PortPreviewUrl\nfrom daytona_api_client.models.position import Position\nfrom daytona_api_client.models.posthog_config import PosthogConfig\nfrom daytona_api_client.models.process_errors_response import ProcessErrorsResponse\nfrom daytona_api_client.models.process_logs_response import ProcessLogsResponse\nfrom daytona_api_client.models.process_restart_response import ProcessRestartResponse\nfrom daytona_api_client.models.process_status_response import ProcessStatusResponse\nfrom daytona_api_client.models.project_dir_response import ProjectDirResponse\nfrom daytona_api_client.models.pty_create_request import PtyCreateRequest\nfrom daytona_api_client.models.pty_create_response import PtyCreateResponse\nfrom daytona_api_client.models.pty_list_response import PtyListResponse\nfrom daytona_api_client.models.pty_resize_request import PtyResizeRequest\nfrom daytona_api_client.models.pty_session_info import PtySessionInfo\nfrom daytona_api_client.models.range import Range\nfrom daytona_api_client.models.rate_limit_config import RateLimitConfig\nfrom daytona_api_client.models.rate_limit_entry import RateLimitEntry\nfrom daytona_api_client.models.regenerate_api_key_response import RegenerateApiKeyResponse\nfrom daytona_api_client.models.region import Region\nfrom daytona_api_client.models.region_quota import RegionQuota\nfrom daytona_api_client.models.region_screenshot_response import RegionScreenshotResponse\nfrom daytona_api_client.models.region_type import RegionType\nfrom daytona_api_client.models.region_usage_overview import RegionUsageOverview\nfrom daytona_api_client.models.registry_push_access_dto import RegistryPushAccessDto\nfrom daytona_api_client.models.replace_request import ReplaceRequest\nfrom daytona_api_client.models.replace_result import ReplaceResult\nfrom daytona_api_client.models.resize_sandbox import ResizeSandbox\nfrom daytona_api_client.models.runner import Runner\nfrom daytona_api_client.models.runner_full import RunnerFull\nfrom daytona_api_client.models.runner_health_metrics import RunnerHealthMetrics\nfrom daytona_api_client.models.runner_healthcheck import RunnerHealthcheck\nfrom daytona_api_client.models.runner_service_health import RunnerServiceHealth\nfrom daytona_api_client.models.runner_snapshot_dto import RunnerSnapshotDto\nfrom daytona_api_client.models.runner_state import RunnerState\nfrom daytona_api_client.models.sandbox import Sandbox\nfrom daytona_api_client.models.sandbox_class import SandboxClass\nfrom daytona_api_client.models.sandbox_desired_state import SandboxDesiredState\nfrom daytona_api_client.models.sandbox_info import SandboxInfo\nfrom daytona_api_client.models.sandbox_labels import SandboxLabels\nfrom daytona_api_client.models.sandbox_state import SandboxState\nfrom daytona_api_client.models.sandbox_volume import SandboxVolume\nfrom daytona_api_client.models.screenshot_response import ScreenshotResponse\nfrom daytona_api_client.models.search_files_response import SearchFilesResponse\nfrom daytona_api_client.models.send_webhook_dto import SendWebhookDto\nfrom daytona_api_client.models.session import Session\nfrom daytona_api_client.models.session_execute_request import SessionExecuteRequest\nfrom daytona_api_client.models.session_execute_response import SessionExecuteResponse\nfrom daytona_api_client.models.set_snapshot_general_status_dto import SetSnapshotGeneralStatusDto\nfrom daytona_api_client.models.signed_port_preview_url import SignedPortPreviewUrl\nfrom daytona_api_client.models.snapshot_dto import SnapshotDto\nfrom daytona_api_client.models.snapshot_manager_credentials import SnapshotManagerCredentials\nfrom daytona_api_client.models.snapshot_state import SnapshotState\nfrom daytona_api_client.models.ssh_access_dto import SshAccessDto\nfrom daytona_api_client.models.ssh_access_validation_dto import SshAccessValidationDto\nfrom daytona_api_client.models.storage_access_dto import StorageAccessDto\nfrom daytona_api_client.models.toolbox_proxy_url import ToolboxProxyUrl\nfrom daytona_api_client.models.trace_span import TraceSpan\nfrom daytona_api_client.models.trace_summary import TraceSummary\nfrom daytona_api_client.models.update_docker_registry import UpdateDockerRegistry\nfrom daytona_api_client.models.update_job_status import UpdateJobStatus\nfrom daytona_api_client.models.update_organization_default_region import UpdateOrganizationDefaultRegion\nfrom daytona_api_client.models.update_organization_invitation import UpdateOrganizationInvitation\nfrom daytona_api_client.models.update_organization_member_access import UpdateOrganizationMemberAccess\nfrom daytona_api_client.models.update_organization_quota import UpdateOrganizationQuota\nfrom daytona_api_client.models.update_organization_region_quota import UpdateOrganizationRegionQuota\nfrom daytona_api_client.models.update_organization_role import UpdateOrganizationRole\nfrom daytona_api_client.models.update_region import UpdateRegion\nfrom daytona_api_client.models.update_sandbox_state_dto import UpdateSandboxStateDto\nfrom daytona_api_client.models.url import Url\nfrom daytona_api_client.models.user import User\nfrom daytona_api_client.models.user_home_dir_response import UserHomeDirResponse\nfrom daytona_api_client.models.user_public_key import UserPublicKey\nfrom daytona_api_client.models.volume_dto import VolumeDto\nfrom daytona_api_client.models.volume_state import VolumeState\nfrom daytona_api_client.models.webhook_app_portal_access import WebhookAppPortalAccess\nfrom daytona_api_client.models.webhook_controller_get_status200_response import WebhookControllerGetStatus200Response\nfrom daytona_api_client.models.webhook_event import WebhookEvent\nfrom daytona_api_client.models.webhook_initialization_status import WebhookInitializationStatus\nfrom daytona_api_client.models.windows_response import WindowsResponse\nfrom daytona_api_client.models.work_dir_response import WorkDirResponse\nfrom daytona_api_client.models.workspace import Workspace\nfrom daytona_api_client.models.workspace_port_preview_url import WorkspacePortPreviewUrl\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/account_provider.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass AccountProvider(BaseModel):\n    \"\"\"\n    AccountProvider\n    \"\"\" # noqa: E501\n    name: StrictStr\n    display_name: StrictStr = Field(serialization_alias=\"displayName\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"displayName\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of AccountProvider from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of AccountProvider from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"display_name\": obj.get(\"displayName\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/admin_create_runner.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing_extensions import Annotated\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass AdminCreateRunner(BaseModel):\n    \"\"\"\n    AdminCreateRunner\n    \"\"\" # noqa: E501\n    region_id: StrictStr = Field(serialization_alias=\"regionId\")\n    name: StrictStr\n    api_key: StrictStr = Field(serialization_alias=\"apiKey\")\n    api_version: Annotated[str, Field(strict=True)] = Field(description=\"The api version of the runner to create\", serialization_alias=\"apiVersion\")\n    domain: Optional[StrictStr] = Field(default=None, description=\"The domain of the runner\")\n    api_url: Optional[StrictStr] = Field(default=None, description=\"The API URL of the runner\", serialization_alias=\"apiUrl\")\n    proxy_url: Optional[StrictStr] = Field(default=None, description=\"The proxy URL of the runner\", serialization_alias=\"proxyUrl\")\n    cpu: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"The CPU capacity of the runner\")\n    memory_gi_b: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"The memory capacity of the runner in GiB\", serialization_alias=\"memoryGiB\")\n    disk_gi_b: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"The disk capacity of the runner in GiB\", serialization_alias=\"diskGiB\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"regionId\", \"name\", \"apiKey\", \"apiVersion\", \"domain\", \"apiUrl\", \"proxyUrl\", \"cpu\", \"memoryGiB\", \"diskGiB\"]\n\n    @field_validator('api_version')\n    def api_version_validate_regular_expression(cls, value):\n        \"\"\"Validates the regular expression\"\"\"\n        if not re.match(r\"^(0|2)$\", value):\n            raise ValueError(r\"must validate the regular expression /^(0|2)$/\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of AdminCreateRunner from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of AdminCreateRunner from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"region_id\": obj.get(\"regionId\"),\n            \"name\": obj.get(\"name\"),\n            \"api_key\": obj.get(\"apiKey\"),\n            \"api_version\": obj.get(\"apiVersion\"),\n            \"domain\": obj.get(\"domain\"),\n            \"api_url\": obj.get(\"apiUrl\"),\n            \"proxy_url\": obj.get(\"proxyUrl\"),\n            \"cpu\": obj.get(\"cpu\"),\n            \"memory_gi_b\": obj.get(\"memoryGiB\"),\n            \"disk_gi_b\": obj.get(\"diskGiB\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/announcement.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass Announcement(BaseModel):\n    \"\"\"\n    Announcement\n    \"\"\" # noqa: E501\n    text: StrictStr = Field(description=\"The announcement text\")\n    learn_more_url: Optional[StrictStr] = Field(default=None, description=\"URL to learn more about the announcement\", serialization_alias=\"learnMoreUrl\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"text\", \"learnMoreUrl\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of Announcement from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of Announcement from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"text\": obj.get(\"text\"),\n            \"learn_more_url\": obj.get(\"learnMoreUrl\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/api_key_list.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ApiKeyList(BaseModel):\n    \"\"\"\n    ApiKeyList\n    \"\"\" # noqa: E501\n    name: StrictStr = Field(description=\"The name of the API key\")\n    value: StrictStr = Field(description=\"The masked API key value\")\n    created_at: datetime = Field(description=\"When the API key was created\", serialization_alias=\"createdAt\")\n    permissions: List[StrictStr] = Field(description=\"The list of organization resource permissions assigned to the API key\")\n    last_used_at: Optional[datetime] = Field(description=\"When the API key was last used\", serialization_alias=\"lastUsedAt\")\n    expires_at: Optional[datetime] = Field(description=\"When the API key expires\", serialization_alias=\"expiresAt\")\n    user_id: StrictStr = Field(description=\"The user ID of the user who created the API key\", serialization_alias=\"userId\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"value\", \"createdAt\", \"permissions\", \"lastUsedAt\", \"expiresAt\", \"userId\"]\n\n    @field_validator('permissions')\n    def permissions_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        for i in value:\n            if i not in set(['write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs']):\n                raise ValueError(\"each list item must be one of ('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ApiKeyList from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if last_used_at (nullable) is None\n        # and model_fields_set contains the field\n        if self.last_used_at is None and \"last_used_at\" in self.model_fields_set:\n            _dict['lastUsedAt'] = None\n\n        # set to None if expires_at (nullable) is None\n        # and model_fields_set contains the field\n        if self.expires_at is None and \"expires_at\" in self.model_fields_set:\n            _dict['expiresAt'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ApiKeyList from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"value\": obj.get(\"value\"),\n            \"created_at\": obj.get(\"createdAt\"),\n            \"permissions\": obj.get(\"permissions\"),\n            \"last_used_at\": obj.get(\"lastUsedAt\"),\n            \"expires_at\": obj.get(\"expiresAt\"),\n            \"user_id\": obj.get(\"userId\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/api_key_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ApiKeyResponse(BaseModel):\n    \"\"\"\n    ApiKeyResponse\n    \"\"\" # noqa: E501\n    name: StrictStr = Field(description=\"The name of the API key\")\n    value: StrictStr = Field(description=\"The API key value\")\n    created_at: datetime = Field(description=\"When the API key was created\", serialization_alias=\"createdAt\")\n    permissions: List[StrictStr] = Field(description=\"The list of organization resource permissions assigned to the API key\")\n    expires_at: Optional[datetime] = Field(description=\"When the API key expires\", serialization_alias=\"expiresAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"value\", \"createdAt\", \"permissions\", \"expiresAt\"]\n\n    @field_validator('permissions')\n    def permissions_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        for i in value:\n            if i not in set(['write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs']):\n                raise ValueError(\"each list item must be one of ('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ApiKeyResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if expires_at (nullable) is None\n        # and model_fields_set contains the field\n        if self.expires_at is None and \"expires_at\" in self.model_fields_set:\n            _dict['expiresAt'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ApiKeyResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"value\": obj.get(\"value\"),\n            \"created_at\": obj.get(\"createdAt\"),\n            \"permissions\": obj.get(\"permissions\"),\n            \"expires_at\": obj.get(\"expiresAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/audit_log.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass AuditLog(BaseModel):\n    \"\"\"\n    AuditLog\n    \"\"\" # noqa: E501\n    id: StrictStr\n    actor_id: StrictStr = Field(serialization_alias=\"actorId\")\n    actor_email: StrictStr = Field(serialization_alias=\"actorEmail\")\n    organization_id: Optional[StrictStr] = Field(default=None, serialization_alias=\"organizationId\")\n    action: StrictStr\n    target_type: Optional[StrictStr] = Field(default=None, serialization_alias=\"targetType\")\n    target_id: Optional[StrictStr] = Field(default=None, serialization_alias=\"targetId\")\n    status_code: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"statusCode\")\n    error_message: Optional[StrictStr] = Field(default=None, serialization_alias=\"errorMessage\")\n    ip_address: Optional[StrictStr] = Field(default=None, serialization_alias=\"ipAddress\")\n    user_agent: Optional[StrictStr] = Field(default=None, serialization_alias=\"userAgent\")\n    source: Optional[StrictStr] = None\n    metadata: Optional[Dict[str, Any]] = None\n    created_at: datetime = Field(serialization_alias=\"createdAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"actorId\", \"actorEmail\", \"organizationId\", \"action\", \"targetType\", \"targetId\", \"statusCode\", \"errorMessage\", \"ipAddress\", \"userAgent\", \"source\", \"metadata\", \"createdAt\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of AuditLog from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of AuditLog from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"actor_id\": obj.get(\"actorId\"),\n            \"actor_email\": obj.get(\"actorEmail\"),\n            \"organization_id\": obj.get(\"organizationId\"),\n            \"action\": obj.get(\"action\"),\n            \"target_type\": obj.get(\"targetType\"),\n            \"target_id\": obj.get(\"targetId\"),\n            \"status_code\": obj.get(\"statusCode\"),\n            \"error_message\": obj.get(\"errorMessage\"),\n            \"ip_address\": obj.get(\"ipAddress\"),\n            \"user_agent\": obj.get(\"userAgent\"),\n            \"source\": obj.get(\"source\"),\n            \"metadata\": obj.get(\"metadata\"),\n            \"created_at\": obj.get(\"createdAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/build_info.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass BuildInfo(BaseModel):\n    \"\"\"\n    BuildInfo\n    \"\"\" # noqa: E501\n    dockerfile_content: Optional[StrictStr] = Field(default=None, description=\"The Dockerfile content used for the build\", serialization_alias=\"dockerfileContent\")\n    context_hashes: Optional[List[StrictStr]] = Field(default=None, description=\"The context hashes used for the build\", serialization_alias=\"contextHashes\")\n    created_at: datetime = Field(description=\"The creation timestamp\", serialization_alias=\"createdAt\")\n    updated_at: datetime = Field(description=\"The last update timestamp\", serialization_alias=\"updatedAt\")\n    snapshot_ref: StrictStr = Field(description=\"The snapshot reference\", serialization_alias=\"snapshotRef\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"dockerfileContent\", \"contextHashes\", \"createdAt\", \"updatedAt\", \"snapshotRef\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of BuildInfo from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of BuildInfo from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"dockerfile_content\": obj.get(\"dockerfileContent\"),\n            \"context_hashes\": obj.get(\"contextHashes\"),\n            \"created_at\": obj.get(\"createdAt\"),\n            \"updated_at\": obj.get(\"updatedAt\"),\n            \"snapshot_ref\": obj.get(\"snapshotRef\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/command.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass Command(BaseModel):\n    \"\"\"\n    Command\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"The ID of the command\")\n    command: StrictStr = Field(description=\"The command that was executed\")\n    exit_code: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"The exit code of the command\", serialization_alias=\"exitCode\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"command\", \"exitCode\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of Command from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of Command from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"command\": obj.get(\"command\"),\n            \"exit_code\": obj.get(\"exitCode\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/completion_context.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CompletionContext(BaseModel):\n    \"\"\"\n    CompletionContext\n    \"\"\" # noqa: E501\n    trigger_kind: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"triggerKind\")\n    trigger_character: Optional[StrictStr] = Field(default=None, serialization_alias=\"triggerCharacter\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"triggerKind\", \"triggerCharacter\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CompletionContext from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CompletionContext from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"trigger_kind\": obj.get(\"triggerKind\"),\n            \"trigger_character\": obj.get(\"triggerCharacter\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/completion_item.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CompletionItem(BaseModel):\n    \"\"\"\n    CompletionItem\n    \"\"\" # noqa: E501\n    label: StrictStr\n    kind: Optional[Union[StrictFloat, StrictInt]] = None\n    detail: Optional[StrictStr] = None\n    documentation: Optional[Dict[str, Any]] = None\n    sort_text: Optional[StrictStr] = Field(default=None, serialization_alias=\"sortText\")\n    filter_text: Optional[StrictStr] = Field(default=None, serialization_alias=\"filterText\")\n    insert_text: Optional[StrictStr] = Field(default=None, serialization_alias=\"insertText\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"label\", \"kind\", \"detail\", \"documentation\", \"sortText\", \"filterText\", \"insertText\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CompletionItem from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CompletionItem from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"label\": obj.get(\"label\"),\n            \"kind\": obj.get(\"kind\"),\n            \"detail\": obj.get(\"detail\"),\n            \"documentation\": obj.get(\"documentation\"),\n            \"sort_text\": obj.get(\"sortText\"),\n            \"filter_text\": obj.get(\"filterText\"),\n            \"insert_text\": obj.get(\"insertText\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/completion_list.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.completion_item import CompletionItem\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CompletionList(BaseModel):\n    \"\"\"\n    CompletionList\n    \"\"\" # noqa: E501\n    is_incomplete: StrictBool = Field(serialization_alias=\"isIncomplete\")\n    items: List[CompletionItem]\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"isIncomplete\", \"items\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CompletionList from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in items (list)\n        _items = []\n        if self.items:\n            for _item_items in self.items:\n                if _item_items:\n                    _items.append(_item_items.to_dict())\n            _dict['items'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CompletionList from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"is_incomplete\": obj.get(\"isIncomplete\"),\n            \"items\": [CompletionItem.from_dict(_item) for _item in obj[\"items\"]] if obj.get(\"items\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/compressed_screenshot_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CompressedScreenshotResponse(BaseModel):\n    \"\"\"\n    CompressedScreenshotResponse\n    \"\"\" # noqa: E501\n    screenshot: StrictStr = Field(description=\"Base64 encoded compressed screenshot image data\")\n    cursor_position: Optional[Dict[str, Any]] = Field(default=None, description=\"The current cursor position when the compressed screenshot was taken\", serialization_alias=\"cursorPosition\")\n    size_bytes: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"The size of the compressed screenshot data in bytes\", serialization_alias=\"sizeBytes\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"screenshot\", \"cursorPosition\", \"sizeBytes\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CompressedScreenshotResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CompressedScreenshotResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"screenshot\": obj.get(\"screenshot\"),\n            \"cursor_position\": obj.get(\"cursorPosition\"),\n            \"size_bytes\": obj.get(\"sizeBytes\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/computer_use_start_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ComputerUseStartResponse(BaseModel):\n    \"\"\"\n    ComputerUseStartResponse\n    \"\"\" # noqa: E501\n    message: StrictStr = Field(description=\"A message indicating the result of starting computer use processes\")\n    status: Dict[str, Any] = Field(description=\"Status information about all VNC desktop processes after starting\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"message\", \"status\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ComputerUseStartResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ComputerUseStartResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"message\": obj.get(\"message\"),\n            \"status\": obj.get(\"status\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/computer_use_status_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ComputerUseStatusResponse(BaseModel):\n    \"\"\"\n    ComputerUseStatusResponse\n    \"\"\" # noqa: E501\n    status: StrictStr = Field(description=\"Status of computer use services (active, partial, inactive, error)\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"status\"]\n\n    @field_validator('status')\n    def status_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value not in set(['active', 'partial', 'inactive', 'error']):\n            raise ValueError(\"must be one of enum values ('active', 'partial', 'inactive', 'error')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ComputerUseStatusResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ComputerUseStatusResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"status\": obj.get(\"status\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/computer_use_stop_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ComputerUseStopResponse(BaseModel):\n    \"\"\"\n    ComputerUseStopResponse\n    \"\"\" # noqa: E501\n    message: StrictStr = Field(description=\"A message indicating the result of stopping computer use processes\")\n    status: Dict[str, Any] = Field(description=\"Status information about all VNC desktop processes after stopping\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"message\", \"status\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ComputerUseStopResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ComputerUseStopResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"message\": obj.get(\"message\"),\n            \"status\": obj.get(\"status\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_api_key.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateApiKey(BaseModel):\n    \"\"\"\n    CreateApiKey\n    \"\"\" # noqa: E501\n    name: StrictStr = Field(description=\"The name of the API key\")\n    permissions: List[StrictStr] = Field(description=\"The list of organization resource permissions explicitly assigned to the API key\")\n    expires_at: Optional[datetime] = Field(default=None, description=\"When the API key expires\", serialization_alias=\"expiresAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"permissions\", \"expiresAt\"]\n\n    @field_validator('permissions')\n    def permissions_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        for i in value:\n            if i not in set(['write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs']):\n                raise ValueError(\"each list item must be one of ('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateApiKey from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if expires_at (nullable) is None\n        # and model_fields_set contains the field\n        if self.expires_at is None and \"expires_at\" in self.model_fields_set:\n            _dict['expiresAt'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateApiKey from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"permissions\": obj.get(\"permissions\"),\n            \"expires_at\": obj.get(\"expiresAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_build_info.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateBuildInfo(BaseModel):\n    \"\"\"\n    CreateBuildInfo\n    \"\"\" # noqa: E501\n    dockerfile_content: StrictStr = Field(description=\"The Dockerfile content used for the build\", serialization_alias=\"dockerfileContent\")\n    context_hashes: Optional[List[StrictStr]] = Field(default=None, description=\"The context hashes used for the build\", serialization_alias=\"contextHashes\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"dockerfileContent\", \"contextHashes\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateBuildInfo from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateBuildInfo from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"dockerfile_content\": obj.get(\"dockerfileContent\"),\n            \"context_hashes\": obj.get(\"contextHashes\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_docker_registry.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateDockerRegistry(BaseModel):\n    \"\"\"\n    CreateDockerRegistry\n    \"\"\" # noqa: E501\n    name: StrictStr = Field(description=\"Registry name\")\n    url: StrictStr = Field(description=\"Registry URL\")\n    username: StrictStr = Field(description=\"Registry username\")\n    password: StrictStr = Field(description=\"Registry password\")\n    project: Optional[StrictStr] = Field(default=None, description=\"Registry project\")\n    registry_type: StrictStr = Field(description=\"Registry type\", serialization_alias=\"registryType\")\n    is_default: Optional[StrictBool] = Field(default=None, description=\"Set as default registry\", serialization_alias=\"isDefault\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"url\", \"username\", \"password\", \"project\", \"registryType\", \"isDefault\"]\n\n    @field_validator('registry_type')\n    def registry_type_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value not in set(['internal', 'organization', 'transient', 'backup']):\n            raise ValueError(\"must be one of enum values ('internal', 'organization', 'transient', 'backup')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateDockerRegistry from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateDockerRegistry from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"url\": obj.get(\"url\"),\n            \"username\": obj.get(\"username\"),\n            \"password\": obj.get(\"password\"),\n            \"project\": obj.get(\"project\"),\n            \"registry_type\": obj.get(\"registryType\") if obj.get(\"registryType\") is not None else 'organization',\n            \"is_default\": obj.get(\"isDefault\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_linked_account.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateLinkedAccount(BaseModel):\n    \"\"\"\n    CreateLinkedAccount\n    \"\"\" # noqa: E501\n    provider: StrictStr = Field(description=\"The authentication provider of the secondary account\")\n    user_id: StrictStr = Field(description=\"The user ID of the secondary account\", serialization_alias=\"userId\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"provider\", \"userId\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateLinkedAccount from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateLinkedAccount from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"provider\": obj.get(\"provider\"),\n            \"user_id\": obj.get(\"userId\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_organization.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateOrganization(BaseModel):\n    \"\"\"\n    CreateOrganization\n    \"\"\" # noqa: E501\n    name: StrictStr = Field(description=\"The name of organization\")\n    default_region_id: StrictStr = Field(description=\"The ID of the default region for the organization\", serialization_alias=\"defaultRegionId\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"defaultRegionId\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateOrganization from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateOrganization from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"default_region_id\": obj.get(\"defaultRegionId\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_organization_invitation.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateOrganizationInvitation(BaseModel):\n    \"\"\"\n    CreateOrganizationInvitation\n    \"\"\" # noqa: E501\n    email: StrictStr = Field(description=\"Email address of the invitee\")\n    role: StrictStr = Field(description=\"Organization member role for the invitee\")\n    assigned_role_ids: List[StrictStr] = Field(description=\"Array of assigned role IDs for the invitee\", serialization_alias=\"assignedRoleIds\")\n    expires_at: Optional[datetime] = Field(default=None, description=\"Expiration date of the invitation\", serialization_alias=\"expiresAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"email\", \"role\", \"assignedRoleIds\", \"expiresAt\"]\n\n    @field_validator('role')\n    def role_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value not in set(['owner', 'member']):\n            raise ValueError(\"must be one of enum values ('owner', 'member')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateOrganizationInvitation from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateOrganizationInvitation from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"email\": obj.get(\"email\"),\n            \"role\": obj.get(\"role\") if obj.get(\"role\") is not None else 'member',\n            \"assigned_role_ids\": obj.get(\"assignedRoleIds\"),\n            \"expires_at\": obj.get(\"expiresAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_organization_quota.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateOrganizationQuota(BaseModel):\n    \"\"\"\n    CreateOrganizationQuota\n    \"\"\" # noqa: E501\n    total_cpu_quota: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"totalCpuQuota\")\n    total_memory_quota: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"totalMemoryQuota\")\n    total_disk_quota: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"totalDiskQuota\")\n    max_cpu_per_sandbox: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"maxCpuPerSandbox\")\n    max_memory_per_sandbox: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"maxMemoryPerSandbox\")\n    max_disk_per_sandbox: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"maxDiskPerSandbox\")\n    snapshot_quota: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"snapshotQuota\")\n    max_snapshot_size: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"maxSnapshotSize\")\n    volume_quota: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, serialization_alias=\"volumeQuota\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"totalCpuQuota\", \"totalMemoryQuota\", \"totalDiskQuota\", \"maxCpuPerSandbox\", \"maxMemoryPerSandbox\", \"maxDiskPerSandbox\", \"snapshotQuota\", \"maxSnapshotSize\", \"volumeQuota\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateOrganizationQuota from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateOrganizationQuota from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"total_cpu_quota\": obj.get(\"totalCpuQuota\"),\n            \"total_memory_quota\": obj.get(\"totalMemoryQuota\"),\n            \"total_disk_quota\": obj.get(\"totalDiskQuota\"),\n            \"max_cpu_per_sandbox\": obj.get(\"maxCpuPerSandbox\"),\n            \"max_memory_per_sandbox\": obj.get(\"maxMemoryPerSandbox\"),\n            \"max_disk_per_sandbox\": obj.get(\"maxDiskPerSandbox\"),\n            \"snapshot_quota\": obj.get(\"snapshotQuota\"),\n            \"max_snapshot_size\": obj.get(\"maxSnapshotSize\"),\n            \"volume_quota\": obj.get(\"volumeQuota\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_organization_role.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateOrganizationRole(BaseModel):\n    \"\"\"\n    CreateOrganizationRole\n    \"\"\" # noqa: E501\n    name: StrictStr = Field(description=\"The name of the role\")\n    description: StrictStr = Field(description=\"The description of the role\")\n    permissions: List[StrictStr] = Field(description=\"The list of permissions assigned to the role\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"description\", \"permissions\"]\n\n    @field_validator('permissions')\n    def permissions_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        for i in value:\n            if i not in set(['write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs']):\n                raise ValueError(\"each list item must be one of ('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateOrganizationRole from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateOrganizationRole from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"description\": obj.get(\"description\"),\n            \"permissions\": obj.get(\"permissions\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_region.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateRegion(BaseModel):\n    \"\"\"\n    CreateRegion\n    \"\"\" # noqa: E501\n    name: StrictStr = Field(description=\"Region name\")\n    proxy_url: Optional[StrictStr] = Field(default=None, description=\"Proxy URL for the region\", serialization_alias=\"proxyUrl\")\n    ssh_gateway_url: Optional[StrictStr] = Field(default=None, description=\"SSH Gateway URL for the region\", serialization_alias=\"sshGatewayUrl\")\n    snapshot_manager_url: Optional[StrictStr] = Field(default=None, description=\"Snapshot Manager URL for the region\", serialization_alias=\"snapshotManagerUrl\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"proxyUrl\", \"sshGatewayUrl\", \"snapshotManagerUrl\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateRegion from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if proxy_url (nullable) is None\n        # and model_fields_set contains the field\n        if self.proxy_url is None and \"proxy_url\" in self.model_fields_set:\n            _dict['proxyUrl'] = None\n\n        # set to None if ssh_gateway_url (nullable) is None\n        # and model_fields_set contains the field\n        if self.ssh_gateway_url is None and \"ssh_gateway_url\" in self.model_fields_set:\n            _dict['sshGatewayUrl'] = None\n\n        # set to None if snapshot_manager_url (nullable) is None\n        # and model_fields_set contains the field\n        if self.snapshot_manager_url is None and \"snapshot_manager_url\" in self.model_fields_set:\n            _dict['snapshotManagerUrl'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateRegion from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"proxy_url\": obj.get(\"proxyUrl\"),\n            \"ssh_gateway_url\": obj.get(\"sshGatewayUrl\"),\n            \"snapshot_manager_url\": obj.get(\"snapshotManagerUrl\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_region_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateRegionResponse(BaseModel):\n    \"\"\"\n    CreateRegionResponse\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"ID of the created region\")\n    proxy_api_key: Optional[StrictStr] = Field(default=None, description=\"Proxy API key for the region\", serialization_alias=\"proxyApiKey\")\n    ssh_gateway_api_key: Optional[StrictStr] = Field(default=None, description=\"SSH Gateway API key for the region\", serialization_alias=\"sshGatewayApiKey\")\n    snapshot_manager_username: Optional[StrictStr] = Field(default=None, description=\"Snapshot Manager username for the region\", serialization_alias=\"snapshotManagerUsername\")\n    snapshot_manager_password: Optional[StrictStr] = Field(default=None, description=\"Snapshot Manager password for the region\", serialization_alias=\"snapshotManagerPassword\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"proxyApiKey\", \"sshGatewayApiKey\", \"snapshotManagerUsername\", \"snapshotManagerPassword\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateRegionResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if proxy_api_key (nullable) is None\n        # and model_fields_set contains the field\n        if self.proxy_api_key is None and \"proxy_api_key\" in self.model_fields_set:\n            _dict['proxyApiKey'] = None\n\n        # set to None if ssh_gateway_api_key (nullable) is None\n        # and model_fields_set contains the field\n        if self.ssh_gateway_api_key is None and \"ssh_gateway_api_key\" in self.model_fields_set:\n            _dict['sshGatewayApiKey'] = None\n\n        # set to None if snapshot_manager_username (nullable) is None\n        # and model_fields_set contains the field\n        if self.snapshot_manager_username is None and \"snapshot_manager_username\" in self.model_fields_set:\n            _dict['snapshotManagerUsername'] = None\n\n        # set to None if snapshot_manager_password (nullable) is None\n        # and model_fields_set contains the field\n        if self.snapshot_manager_password is None and \"snapshot_manager_password\" in self.model_fields_set:\n            _dict['snapshotManagerPassword'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateRegionResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"proxy_api_key\": obj.get(\"proxyApiKey\"),\n            \"ssh_gateway_api_key\": obj.get(\"sshGatewayApiKey\"),\n            \"snapshot_manager_username\": obj.get(\"snapshotManagerUsername\"),\n            \"snapshot_manager_password\": obj.get(\"snapshotManagerPassword\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_runner.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateRunner(BaseModel):\n    \"\"\"\n    CreateRunner\n    \"\"\" # noqa: E501\n    region_id: StrictStr = Field(serialization_alias=\"regionId\")\n    name: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"regionId\", \"name\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateRunner from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateRunner from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"region_id\": obj.get(\"regionId\"),\n            \"name\": obj.get(\"name\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_runner_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateRunnerResponse(BaseModel):\n    \"\"\"\n    CreateRunnerResponse\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"The ID of the runner\")\n    api_key: StrictStr = Field(description=\"The API key for the runner\", serialization_alias=\"apiKey\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"apiKey\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateRunnerResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateRunnerResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"api_key\": obj.get(\"apiKey\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_sandbox.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom daytona_api_client.models.create_build_info import CreateBuildInfo\nfrom daytona_api_client.models.sandbox_volume import SandboxVolume\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateSandbox(BaseModel):\n    \"\"\"\n    CreateSandbox\n    \"\"\" # noqa: E501\n    name: Optional[StrictStr] = Field(default=None, description=\"The name of the sandbox. If not provided, the sandbox ID will be used as the name\")\n    snapshot: Optional[StrictStr] = Field(default=None, description=\"The ID or name of the snapshot used for the sandbox\")\n    user: Optional[StrictStr] = Field(default=None, description=\"The user associated with the project\")\n    env: Optional[Dict[str, StrictStr]] = Field(default=None, description=\"Environment variables for the sandbox\")\n    labels: Optional[Dict[str, StrictStr]] = Field(default=None, description=\"Labels for the sandbox\")\n    public: Optional[StrictBool] = Field(default=None, description=\"Whether the sandbox http preview is publicly accessible\")\n    network_block_all: Optional[StrictBool] = Field(default=None, description=\"Whether to block all network access for the sandbox\", serialization_alias=\"networkBlockAll\")\n    network_allow_list: Optional[StrictStr] = Field(default=None, description=\"Comma-separated list of allowed CIDR network addresses for the sandbox\", serialization_alias=\"networkAllowList\")\n    var_class: Optional[StrictStr] = Field(default=None, description=\"The sandbox class type\", serialization_alias=\"class\")\n    target: Optional[StrictStr] = Field(default=None, description=\"The target (region) where the sandbox will be created\")\n    cpu: Optional[StrictInt] = Field(default=None, description=\"CPU cores allocated to the sandbox\")\n    gpu: Optional[StrictInt] = Field(default=None, description=\"GPU units allocated to the sandbox\")\n    memory: Optional[StrictInt] = Field(default=None, description=\"Memory allocated to the sandbox in GB\")\n    disk: Optional[StrictInt] = Field(default=None, description=\"Disk space allocated to the sandbox in GB\")\n    auto_stop_interval: Optional[StrictInt] = Field(default=None, description=\"Auto-stop interval in minutes (0 means disabled)\", serialization_alias=\"autoStopInterval\")\n    auto_archive_interval: Optional[StrictInt] = Field(default=None, description=\"Auto-archive interval in minutes (0 means the maximum interval will be used)\", serialization_alias=\"autoArchiveInterval\")\n    auto_delete_interval: Optional[StrictInt] = Field(default=None, description=\"Auto-delete interval in minutes (negative value means disabled, 0 means delete immediately upon stopping)\", serialization_alias=\"autoDeleteInterval\")\n    volumes: Optional[List[SandboxVolume]] = Field(default=None, description=\"Array of volumes to attach to the sandbox\")\n    build_info: Optional[CreateBuildInfo] = Field(default=None, description=\"Build information for the sandbox\", serialization_alias=\"buildInfo\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"snapshot\", \"user\", \"env\", \"labels\", \"public\", \"networkBlockAll\", \"networkAllowList\", \"class\", \"target\", \"cpu\", \"gpu\", \"memory\", \"disk\", \"autoStopInterval\", \"autoArchiveInterval\", \"autoDeleteInterval\", \"volumes\", \"buildInfo\"]\n\n    @field_validator('var_class')\n    def var_class_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value is None:\n            return value\n\n        if value not in set(['small', 'medium', 'large']):\n            raise ValueError(\"must be one of enum values ('small', 'medium', 'large')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateSandbox from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in volumes (list)\n        _items = []\n        if self.volumes:\n            for _item_volumes in self.volumes:\n                if _item_volumes:\n                    _items.append(_item_volumes.to_dict())\n            _dict['volumes'] = _items\n        # override the default output from pydantic by calling `to_dict()` of build_info\n        if self.build_info:\n            _dict['buildInfo'] = self.build_info.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateSandbox from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"snapshot\": obj.get(\"snapshot\"),\n            \"user\": obj.get(\"user\"),\n            \"env\": obj.get(\"env\"),\n            \"labels\": obj.get(\"labels\"),\n            \"public\": obj.get(\"public\"),\n            \"network_block_all\": obj.get(\"networkBlockAll\"),\n            \"network_allow_list\": obj.get(\"networkAllowList\"),\n            \"var_class\": obj.get(\"class\"),\n            \"target\": obj.get(\"target\"),\n            \"cpu\": obj.get(\"cpu\"),\n            \"gpu\": obj.get(\"gpu\"),\n            \"memory\": obj.get(\"memory\"),\n            \"disk\": obj.get(\"disk\"),\n            \"auto_stop_interval\": obj.get(\"autoStopInterval\"),\n            \"auto_archive_interval\": obj.get(\"autoArchiveInterval\"),\n            \"auto_delete_interval\": obj.get(\"autoDeleteInterval\"),\n            \"volumes\": [SandboxVolume.from_dict(_item) for _item in obj[\"volumes\"]] if obj.get(\"volumes\") is not None else None,\n            \"build_info\": CreateBuildInfo.from_dict(obj[\"buildInfo\"]) if obj.get(\"buildInfo\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_session_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateSessionRequest(BaseModel):\n    \"\"\"\n    CreateSessionRequest\n    \"\"\" # noqa: E501\n    session_id: StrictStr = Field(description=\"The ID of the session\", serialization_alias=\"sessionId\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"sessionId\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateSessionRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateSessionRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"session_id\": obj.get(\"sessionId\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_snapshot.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom daytona_api_client.models.create_build_info import CreateBuildInfo\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateSnapshot(BaseModel):\n    \"\"\"\n    CreateSnapshot\n    \"\"\" # noqa: E501\n    name: StrictStr = Field(description=\"The name of the snapshot\")\n    image_name: Optional[StrictStr] = Field(default=None, description=\"The image name of the snapshot\", serialization_alias=\"imageName\")\n    entrypoint: Optional[List[StrictStr]] = Field(default=None, description=\"The entrypoint command for the snapshot\")\n    general: Optional[StrictBool] = Field(default=None, description=\"Whether the snapshot is general\")\n    cpu: Optional[StrictInt] = Field(default=None, description=\"CPU cores allocated to the resulting sandbox\")\n    gpu: Optional[StrictInt] = Field(default=None, description=\"GPU units allocated to the resulting sandbox\")\n    memory: Optional[StrictInt] = Field(default=None, description=\"Memory allocated to the resulting sandbox in GB\")\n    disk: Optional[StrictInt] = Field(default=None, description=\"Disk space allocated to the sandbox in GB\")\n    build_info: Optional[CreateBuildInfo] = Field(default=None, description=\"Build information for the snapshot\", serialization_alias=\"buildInfo\")\n    region_id: Optional[StrictStr] = Field(default=None, description=\"ID of the region where the snapshot will be available. Defaults to organization default region if not specified.\", serialization_alias=\"regionId\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"imageName\", \"entrypoint\", \"general\", \"cpu\", \"gpu\", \"memory\", \"disk\", \"buildInfo\", \"regionId\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateSnapshot from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of build_info\n        if self.build_info:\n            _dict['buildInfo'] = self.build_info.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateSnapshot from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"image_name\": obj.get(\"imageName\"),\n            \"entrypoint\": obj.get(\"entrypoint\"),\n            \"general\": obj.get(\"general\"),\n            \"cpu\": obj.get(\"cpu\"),\n            \"gpu\": obj.get(\"gpu\"),\n            \"memory\": obj.get(\"memory\"),\n            \"disk\": obj.get(\"disk\"),\n            \"build_info\": CreateBuildInfo.from_dict(obj[\"buildInfo\"]) if obj.get(\"buildInfo\") is not None else None,\n            \"region_id\": obj.get(\"regionId\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_user.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom daytona_api_client.models.create_organization_quota import CreateOrganizationQuota\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateUser(BaseModel):\n    \"\"\"\n    CreateUser\n    \"\"\" # noqa: E501\n    id: StrictStr\n    name: StrictStr\n    email: Optional[StrictStr] = None\n    personal_organization_quota: Optional[CreateOrganizationQuota] = Field(default=None, serialization_alias=\"personalOrganizationQuota\")\n    personal_organization_default_region_id: Optional[StrictStr] = Field(default=None, serialization_alias=\"personalOrganizationDefaultRegionId\")\n    role: Optional[StrictStr] = None\n    email_verified: Optional[StrictBool] = Field(default=None, serialization_alias=\"emailVerified\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"name\", \"email\", \"personalOrganizationQuota\", \"personalOrganizationDefaultRegionId\", \"role\", \"emailVerified\"]\n\n    @field_validator('role')\n    def role_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value is None:\n            return value\n\n        if value not in set(['admin', 'user']):\n            raise ValueError(\"must be one of enum values ('admin', 'user')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateUser from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of personal_organization_quota\n        if self.personal_organization_quota:\n            _dict['personalOrganizationQuota'] = self.personal_organization_quota.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateUser from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"name\": obj.get(\"name\"),\n            \"email\": obj.get(\"email\"),\n            \"personal_organization_quota\": CreateOrganizationQuota.from_dict(obj[\"personalOrganizationQuota\"]) if obj.get(\"personalOrganizationQuota\") is not None else None,\n            \"personal_organization_default_region_id\": obj.get(\"personalOrganizationDefaultRegionId\"),\n            \"role\": obj.get(\"role\"),\n            \"email_verified\": obj.get(\"emailVerified\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_volume.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateVolume(BaseModel):\n    \"\"\"\n    CreateVolume\n    \"\"\" # noqa: E501\n    name: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateVolume from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateVolume from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/create_workspace.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom daytona_api_client.models.create_build_info import CreateBuildInfo\nfrom daytona_api_client.models.sandbox_volume import SandboxVolume\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass CreateWorkspace(BaseModel):\n    \"\"\"\n    CreateWorkspace\n    \"\"\" # noqa: E501\n    image: Optional[StrictStr] = Field(default=None, description=\"The image used for the workspace\")\n    user: Optional[StrictStr] = Field(default=None, description=\"The user associated with the project\")\n    env: Optional[Dict[str, StrictStr]] = Field(default=None, description=\"Environment variables for the workspace\")\n    labels: Optional[Dict[str, StrictStr]] = Field(default=None, description=\"Labels for the workspace\")\n    public: Optional[StrictBool] = Field(default=None, description=\"Whether the workspace http preview is publicly accessible\")\n    var_class: Optional[StrictStr] = Field(default=None, description=\"The workspace class type\", serialization_alias=\"class\")\n    target: Optional[StrictStr] = Field(default=None, description=\"The target (region) where the workspace will be created\")\n    cpu: Optional[StrictInt] = Field(default=None, description=\"CPU cores allocated to the workspace\")\n    gpu: Optional[StrictInt] = Field(default=None, description=\"GPU units allocated to the workspace\")\n    memory: Optional[StrictInt] = Field(default=None, description=\"Memory allocated to the workspace in GB\")\n    disk: Optional[StrictInt] = Field(default=None, description=\"Disk space allocated to the workspace in GB\")\n    auto_stop_interval: Optional[StrictInt] = Field(default=None, description=\"Auto-stop interval in minutes (0 means disabled)\", serialization_alias=\"autoStopInterval\")\n    auto_archive_interval: Optional[StrictInt] = Field(default=None, description=\"Auto-archive interval in minutes (0 means the maximum interval will be used)\", serialization_alias=\"autoArchiveInterval\")\n    volumes: Optional[List[SandboxVolume]] = Field(default=None, description=\"Array of volumes to attach to the workspace\")\n    build_info: Optional[CreateBuildInfo] = Field(default=None, description=\"Build information for the workspace\", serialization_alias=\"buildInfo\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"image\", \"user\", \"env\", \"labels\", \"public\", \"class\", \"target\", \"cpu\", \"gpu\", \"memory\", \"disk\", \"autoStopInterval\", \"autoArchiveInterval\", \"volumes\", \"buildInfo\"]\n\n    @field_validator('var_class')\n    def var_class_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value is None:\n            return value\n\n        if value not in set(['small', 'medium', 'large']):\n            raise ValueError(\"must be one of enum values ('small', 'medium', 'large')\")\n        return value\n\n    @field_validator('target')\n    def target_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value is None:\n            return value\n\n        if value not in set(['eu', 'us', 'asia']):\n            raise ValueError(\"must be one of enum values ('eu', 'us', 'asia')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of CreateWorkspace from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in volumes (list)\n        _items = []\n        if self.volumes:\n            for _item_volumes in self.volumes:\n                if _item_volumes:\n                    _items.append(_item_volumes.to_dict())\n            _dict['volumes'] = _items\n        # override the default output from pydantic by calling `to_dict()` of build_info\n        if self.build_info:\n            _dict['buildInfo'] = self.build_info.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of CreateWorkspace from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"image\": obj.get(\"image\"),\n            \"user\": obj.get(\"user\"),\n            \"env\": obj.get(\"env\"),\n            \"labels\": obj.get(\"labels\"),\n            \"public\": obj.get(\"public\"),\n            \"var_class\": obj.get(\"class\"),\n            \"target\": obj.get(\"target\"),\n            \"cpu\": obj.get(\"cpu\"),\n            \"gpu\": obj.get(\"gpu\"),\n            \"memory\": obj.get(\"memory\"),\n            \"disk\": obj.get(\"disk\"),\n            \"auto_stop_interval\": obj.get(\"autoStopInterval\"),\n            \"auto_archive_interval\": obj.get(\"autoArchiveInterval\"),\n            \"volumes\": [SandboxVolume.from_dict(_item) for _item in obj[\"volumes\"]] if obj.get(\"volumes\") is not None else None,\n            \"build_info\": CreateBuildInfo.from_dict(obj[\"buildInfo\"]) if obj.get(\"buildInfo\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/daytona_configuration.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom daytona_api_client.models.announcement import Announcement\nfrom daytona_api_client.models.oidc_config import OidcConfig\nfrom daytona_api_client.models.posthog_config import PosthogConfig\nfrom daytona_api_client.models.rate_limit_config import RateLimitConfig\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass DaytonaConfiguration(BaseModel):\n    \"\"\"\n    DaytonaConfiguration\n    \"\"\" # noqa: E501\n    version: StrictStr = Field(description=\"Daytona version\")\n    posthog: Optional[PosthogConfig] = Field(default=None, description=\"PostHog configuration\")\n    oidc: OidcConfig = Field(description=\"OIDC configuration\")\n    linked_accounts_enabled: StrictBool = Field(description=\"Whether linked accounts are enabled\", serialization_alias=\"linkedAccountsEnabled\")\n    announcements: Dict[str, Announcement] = Field(description=\"System announcements\")\n    pylon_app_id: Optional[StrictStr] = Field(default=None, description=\"Pylon application ID\", serialization_alias=\"pylonAppId\")\n    proxy_template_url: StrictStr = Field(description=\"Proxy template URL\", serialization_alias=\"proxyTemplateUrl\")\n    proxy_toolbox_url: StrictStr = Field(description=\"Toolbox template URL\", serialization_alias=\"proxyToolboxUrl\")\n    default_snapshot: StrictStr = Field(description=\"Default snapshot for sandboxes\", serialization_alias=\"defaultSnapshot\")\n    dashboard_url: StrictStr = Field(description=\"Dashboard URL\", serialization_alias=\"dashboardUrl\")\n    max_auto_archive_interval: Union[StrictFloat, StrictInt] = Field(description=\"Maximum auto-archive interval in minutes\", serialization_alias=\"maxAutoArchiveInterval\")\n    maintanance_mode: StrictBool = Field(description=\"Whether maintenance mode is enabled\", serialization_alias=\"maintananceMode\")\n    environment: StrictStr = Field(description=\"Current environment\")\n    billing_api_url: Optional[StrictStr] = Field(default=None, description=\"Billing API URL\", serialization_alias=\"billingApiUrl\")\n    analytics_api_url: Optional[StrictStr] = Field(default=None, description=\"Analytics API URL\", serialization_alias=\"analyticsApiUrl\")\n    ssh_gateway_command: Optional[StrictStr] = Field(default=None, description=\"SSH Gateway command\", serialization_alias=\"sshGatewayCommand\")\n    ssh_gateway_public_key: Optional[StrictStr] = Field(default=None, description=\"Base64 encoded SSH Gateway public key\", serialization_alias=\"sshGatewayPublicKey\")\n    rate_limit: Optional[RateLimitConfig] = Field(default=None, description=\"Rate limit configuration\", serialization_alias=\"rateLimit\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"version\", \"posthog\", \"oidc\", \"linkedAccountsEnabled\", \"announcements\", \"pylonAppId\", \"proxyTemplateUrl\", \"proxyToolboxUrl\", \"defaultSnapshot\", \"dashboardUrl\", \"maxAutoArchiveInterval\", \"maintananceMode\", \"environment\", \"billingApiUrl\", \"analyticsApiUrl\", \"sshGatewayCommand\", \"sshGatewayPublicKey\", \"rateLimit\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of DaytonaConfiguration from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of posthog\n        if self.posthog:\n            _dict['posthog'] = self.posthog.to_dict()\n        # override the default output from pydantic by calling `to_dict()` of oidc\n        if self.oidc:\n            _dict['oidc'] = self.oidc.to_dict()\n        # override the default output from pydantic by calling `to_dict()` of each value in announcements (dict)\n        _field_dict = {}\n        if self.announcements:\n            for _key_announcements in self.announcements:\n                if self.announcements[_key_announcements]:\n                    _field_dict[_key_announcements] = self.announcements[_key_announcements].to_dict()\n            _dict['announcements'] = _field_dict\n        # override the default output from pydantic by calling `to_dict()` of rate_limit\n        if self.rate_limit:\n            _dict['rateLimit'] = self.rate_limit.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of DaytonaConfiguration from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"version\": obj.get(\"version\"),\n            \"posthog\": PosthogConfig.from_dict(obj[\"posthog\"]) if obj.get(\"posthog\") is not None else None,\n            \"oidc\": OidcConfig.from_dict(obj[\"oidc\"]) if obj.get(\"oidc\") is not None else None,\n            \"linked_accounts_enabled\": obj.get(\"linkedAccountsEnabled\"),\n            \"announcements\": dict(\n                (_k, Announcement.from_dict(_v))\n                for _k, _v in obj[\"announcements\"].items()\n            )\n            if obj.get(\"announcements\") is not None\n            else None,\n            \"pylon_app_id\": obj.get(\"pylonAppId\"),\n            \"proxy_template_url\": obj.get(\"proxyTemplateUrl\"),\n            \"proxy_toolbox_url\": obj.get(\"proxyToolboxUrl\"),\n            \"default_snapshot\": obj.get(\"defaultSnapshot\"),\n            \"dashboard_url\": obj.get(\"dashboardUrl\"),\n            \"max_auto_archive_interval\": obj.get(\"maxAutoArchiveInterval\"),\n            \"maintanance_mode\": obj.get(\"maintananceMode\"),\n            \"environment\": obj.get(\"environment\"),\n            \"billing_api_url\": obj.get(\"billingApiUrl\"),\n            \"analytics_api_url\": obj.get(\"analyticsApiUrl\"),\n            \"ssh_gateway_command\": obj.get(\"sshGatewayCommand\"),\n            \"ssh_gateway_public_key\": obj.get(\"sshGatewayPublicKey\"),\n            \"rate_limit\": RateLimitConfig.from_dict(obj[\"rateLimit\"]) if obj.get(\"rateLimit\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/display_info_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass DisplayInfoResponse(BaseModel):\n    \"\"\"\n    DisplayInfoResponse\n    \"\"\" # noqa: E501\n    displays: List[Dict[str, Any]] = Field(description=\"Array of display information for all connected displays\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"displays\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of DisplayInfoResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of DisplayInfoResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"displays\": obj.get(\"displays\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/docker_registry.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass DockerRegistry(BaseModel):\n    \"\"\"\n    DockerRegistry\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"Registry ID\")\n    name: StrictStr = Field(description=\"Registry name\")\n    url: StrictStr = Field(description=\"Registry URL\")\n    username: StrictStr = Field(description=\"Registry username\")\n    project: StrictStr = Field(description=\"Registry project\")\n    registry_type: StrictStr = Field(description=\"Registry type\", serialization_alias=\"registryType\")\n    created_at: datetime = Field(description=\"Creation timestamp\", serialization_alias=\"createdAt\")\n    updated_at: datetime = Field(description=\"Last update timestamp\", serialization_alias=\"updatedAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"name\", \"url\", \"username\", \"project\", \"registryType\", \"createdAt\", \"updatedAt\"]\n\n    @field_validator('registry_type')\n    def registry_type_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value not in set(['internal', 'organization', 'transient', 'backup']):\n            raise ValueError(\"must be one of enum values ('internal', 'organization', 'transient', 'backup')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of DockerRegistry from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of DockerRegistry from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"name\": obj.get(\"name\"),\n            \"url\": obj.get(\"url\"),\n            \"username\": obj.get(\"username\"),\n            \"project\": obj.get(\"project\"),\n            \"registry_type\": obj.get(\"registryType\"),\n            \"created_at\": obj.get(\"createdAt\"),\n            \"updated_at\": obj.get(\"updatedAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/download_files.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass DownloadFiles(BaseModel):\n    \"\"\"\n    DownloadFiles\n    \"\"\" # noqa: E501\n    paths: List[StrictStr] = Field(description=\"List of remote file paths to download\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"paths\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of DownloadFiles from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of DownloadFiles from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"paths\": obj.get(\"paths\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/execute_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ExecuteRequest(BaseModel):\n    \"\"\"\n    ExecuteRequest\n    \"\"\" # noqa: E501\n    command: StrictStr\n    cwd: Optional[StrictStr] = Field(default=None, description=\"Current working directory\")\n    timeout: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"Timeout in seconds, defaults to 10 seconds\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"command\", \"cwd\", \"timeout\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ExecuteRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ExecuteRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"command\": obj.get(\"command\"),\n            \"cwd\": obj.get(\"cwd\"),\n            \"timeout\": obj.get(\"timeout\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/execute_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ExecuteResponse(BaseModel):\n    \"\"\"\n    ExecuteResponse\n    \"\"\" # noqa: E501\n    exit_code: Union[StrictFloat, StrictInt] = Field(description=\"Exit code\", serialization_alias=\"exitCode\")\n    result: StrictStr = Field(description=\"Command output\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"exitCode\", \"result\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ExecuteResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ExecuteResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"exit_code\": obj.get(\"exitCode\"),\n            \"result\": obj.get(\"result\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/file_info.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass FileInfo(BaseModel):\n    \"\"\"\n    FileInfo\n    \"\"\" # noqa: E501\n    name: StrictStr\n    is_dir: StrictBool = Field(serialization_alias=\"isDir\")\n    size: Union[StrictFloat, StrictInt]\n    mod_time: StrictStr = Field(serialization_alias=\"modTime\")\n    mode: StrictStr\n    permissions: StrictStr\n    owner: StrictStr\n    group: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"isDir\", \"size\", \"modTime\", \"mode\", \"permissions\", \"owner\", \"group\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of FileInfo from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of FileInfo from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"is_dir\": obj.get(\"isDir\"),\n            \"size\": obj.get(\"size\"),\n            \"mod_time\": obj.get(\"modTime\"),\n            \"mode\": obj.get(\"mode\"),\n            \"permissions\": obj.get(\"permissions\"),\n            \"owner\": obj.get(\"owner\"),\n            \"group\": obj.get(\"group\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/file_status.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass FileStatus(BaseModel):\n    \"\"\"\n    FileStatus\n    \"\"\" # noqa: E501\n    name: StrictStr\n    staging: StrictStr\n    worktree: StrictStr\n    extra: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"name\", \"staging\", \"worktree\", \"extra\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of FileStatus from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of FileStatus from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"name\": obj.get(\"name\"),\n            \"staging\": obj.get(\"staging\"),\n            \"worktree\": obj.get(\"worktree\"),\n            \"extra\": obj.get(\"extra\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_add_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitAddRequest(BaseModel):\n    \"\"\"\n    GitAddRequest\n    \"\"\" # noqa: E501\n    path: StrictStr\n    files: List[StrictStr] = Field(description=\"files to add (use . for all files)\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"path\", \"files\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitAddRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitAddRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"path\": obj.get(\"path\"),\n            \"files\": obj.get(\"files\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_branch_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitBranchRequest(BaseModel):\n    \"\"\"\n    GitBranchRequest\n    \"\"\" # noqa: E501\n    path: StrictStr\n    name: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"path\", \"name\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitBranchRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitBranchRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"path\": obj.get(\"path\"),\n            \"name\": obj.get(\"name\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_checkout_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitCheckoutRequest(BaseModel):\n    \"\"\"\n    GitCheckoutRequest\n    \"\"\" # noqa: E501\n    path: StrictStr\n    branch: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"path\", \"branch\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitCheckoutRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitCheckoutRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"path\": obj.get(\"path\"),\n            \"branch\": obj.get(\"branch\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_clone_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitCloneRequest(BaseModel):\n    \"\"\"\n    GitCloneRequest\n    \"\"\" # noqa: E501\n    url: StrictStr\n    path: StrictStr\n    username: Optional[StrictStr] = None\n    password: Optional[StrictStr] = None\n    branch: Optional[StrictStr] = None\n    commit_id: Optional[StrictStr] = None\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"url\", \"path\", \"username\", \"password\", \"branch\", \"commit_id\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitCloneRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitCloneRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"url\": obj.get(\"url\"),\n            \"path\": obj.get(\"path\"),\n            \"username\": obj.get(\"username\"),\n            \"password\": obj.get(\"password\"),\n            \"branch\": obj.get(\"branch\"),\n            \"commit_id\": obj.get(\"commit_id\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_commit_info.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitCommitInfo(BaseModel):\n    \"\"\"\n    GitCommitInfo\n    \"\"\" # noqa: E501\n    hash: StrictStr\n    message: StrictStr\n    author: StrictStr\n    email: StrictStr\n    timestamp: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"hash\", \"message\", \"author\", \"email\", \"timestamp\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitCommitInfo from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitCommitInfo from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"hash\": obj.get(\"hash\"),\n            \"message\": obj.get(\"message\"),\n            \"author\": obj.get(\"author\"),\n            \"email\": obj.get(\"email\"),\n            \"timestamp\": obj.get(\"timestamp\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_commit_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitCommitRequest(BaseModel):\n    \"\"\"\n    GitCommitRequest\n    \"\"\" # noqa: E501\n    path: StrictStr\n    message: StrictStr\n    author: StrictStr\n    email: StrictStr\n    allow_empty: Optional[StrictBool] = Field(default=False, description=\"Allow creating an empty commit when no changes are staged\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"path\", \"message\", \"author\", \"email\", \"allow_empty\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitCommitRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitCommitRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"path\": obj.get(\"path\"),\n            \"message\": obj.get(\"message\"),\n            \"author\": obj.get(\"author\"),\n            \"email\": obj.get(\"email\"),\n            \"allow_empty\": obj.get(\"allow_empty\") if obj.get(\"allow_empty\") is not None else False\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_commit_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitCommitResponse(BaseModel):\n    \"\"\"\n    GitCommitResponse\n    \"\"\" # noqa: E501\n    hash: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"hash\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitCommitResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitCommitResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"hash\": obj.get(\"hash\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_delete_branch_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitDeleteBranchRequest(BaseModel):\n    \"\"\"\n    GitDeleteBranchRequest\n    \"\"\" # noqa: E501\n    path: StrictStr\n    name: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"path\", \"name\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitDeleteBranchRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitDeleteBranchRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"path\": obj.get(\"path\"),\n            \"name\": obj.get(\"name\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_repo_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitRepoRequest(BaseModel):\n    \"\"\"\n    GitRepoRequest\n    \"\"\" # noqa: E501\n    path: StrictStr\n    username: Optional[StrictStr] = None\n    password: Optional[StrictStr] = None\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"path\", \"username\", \"password\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitRepoRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitRepoRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"path\": obj.get(\"path\"),\n            \"username\": obj.get(\"username\"),\n            \"password\": obj.get(\"password\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/git_status.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom daytona_api_client.models.file_status import FileStatus\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass GitStatus(BaseModel):\n    \"\"\"\n    GitStatus\n    \"\"\" # noqa: E501\n    current_branch: StrictStr = Field(serialization_alias=\"currentBranch\")\n    file_status: List[FileStatus] = Field(serialization_alias=\"fileStatus\")\n    ahead: Optional[Union[StrictFloat, StrictInt]] = None\n    behind: Optional[Union[StrictFloat, StrictInt]] = None\n    branch_published: Optional[StrictBool] = Field(default=None, serialization_alias=\"branchPublished\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"currentBranch\", \"fileStatus\", \"ahead\", \"behind\", \"branchPublished\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of GitStatus from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in file_status (list)\n        _items = []\n        if self.file_status:\n            for _item_file_status in self.file_status:\n                if _item_file_status:\n                    _items.append(_item_file_status.to_dict())\n            _dict['fileStatus'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of GitStatus from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"current_branch\": obj.get(\"currentBranch\"),\n            \"file_status\": [FileStatus.from_dict(_item) for _item in obj[\"fileStatus\"]] if obj.get(\"fileStatus\") is not None else None,\n            \"ahead\": obj.get(\"ahead\"),\n            \"behind\": obj.get(\"behind\"),\n            \"branch_published\": obj.get(\"branchPublished\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/health_controller_check200_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom daytona_api_client.models.health_controller_check200_response_info_value import HealthControllerCheck200ResponseInfoValue\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass HealthControllerCheck200Response(BaseModel):\n    \"\"\"\n    HealthControllerCheck200Response\n    \"\"\" # noqa: E501\n    status: Optional[StrictStr] = None\n    info: Optional[Dict[str, HealthControllerCheck200ResponseInfoValue]] = None\n    error: Optional[Dict[str, HealthControllerCheck200ResponseInfoValue]] = None\n    details: Optional[Dict[str, HealthControllerCheck200ResponseInfoValue]] = None\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"status\", \"info\", \"error\", \"details\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of HealthControllerCheck200Response from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each value in info (dict)\n        _field_dict = {}\n        if self.info:\n            for _key_info in self.info:\n                if self.info[_key_info]:\n                    _field_dict[_key_info] = self.info[_key_info].to_dict()\n            _dict['info'] = _field_dict\n        # override the default output from pydantic by calling `to_dict()` of each value in error (dict)\n        _field_dict = {}\n        if self.error:\n            for _key_error in self.error:\n                if self.error[_key_error]:\n                    _field_dict[_key_error] = self.error[_key_error].to_dict()\n            _dict['error'] = _field_dict\n        # override the default output from pydantic by calling `to_dict()` of each value in details (dict)\n        _field_dict = {}\n        if self.details:\n            for _key_details in self.details:\n                if self.details[_key_details]:\n                    _field_dict[_key_details] = self.details[_key_details].to_dict()\n            _dict['details'] = _field_dict\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if info (nullable) is None\n        # and model_fields_set contains the field\n        if self.info is None and \"info\" in self.model_fields_set:\n            _dict['info'] = None\n\n        # set to None if error (nullable) is None\n        # and model_fields_set contains the field\n        if self.error is None and \"error\" in self.model_fields_set:\n            _dict['error'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of HealthControllerCheck200Response from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"status\": obj.get(\"status\"),\n            \"info\": dict(\n                (_k, HealthControllerCheck200ResponseInfoValue.from_dict(_v))\n                for _k, _v in obj[\"info\"].items()\n            )\n            if obj.get(\"info\") is not None\n            else None,\n            \"error\": dict(\n                (_k, HealthControllerCheck200ResponseInfoValue.from_dict(_v))\n                for _k, _v in obj[\"error\"].items()\n            )\n            if obj.get(\"error\") is not None\n            else None,\n            \"details\": dict(\n                (_k, HealthControllerCheck200ResponseInfoValue.from_dict(_v))\n                for _k, _v in obj[\"details\"].items()\n            )\n            if obj.get(\"details\") is not None\n            else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/health_controller_check200_response_info_value.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass HealthControllerCheck200ResponseInfoValue(BaseModel):\n    \"\"\"\n    HealthControllerCheck200ResponseInfoValue\n    \"\"\" # noqa: E501\n    status: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"status\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of HealthControllerCheck200ResponseInfoValue from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of HealthControllerCheck200ResponseInfoValue from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"status\": obj.get(\"status\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/health_controller_check503_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom daytona_api_client.models.health_controller_check200_response_info_value import HealthControllerCheck200ResponseInfoValue\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass HealthControllerCheck503Response(BaseModel):\n    \"\"\"\n    HealthControllerCheck503Response\n    \"\"\" # noqa: E501\n    status: Optional[StrictStr] = None\n    info: Optional[Dict[str, HealthControllerCheck200ResponseInfoValue]] = None\n    error: Optional[Dict[str, HealthControllerCheck200ResponseInfoValue]] = None\n    details: Optional[Dict[str, HealthControllerCheck200ResponseInfoValue]] = None\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"status\", \"info\", \"error\", \"details\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of HealthControllerCheck503Response from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each value in info (dict)\n        _field_dict = {}\n        if self.info:\n            for _key_info in self.info:\n                if self.info[_key_info]:\n                    _field_dict[_key_info] = self.info[_key_info].to_dict()\n            _dict['info'] = _field_dict\n        # override the default output from pydantic by calling `to_dict()` of each value in error (dict)\n        _field_dict = {}\n        if self.error:\n            for _key_error in self.error:\n                if self.error[_key_error]:\n                    _field_dict[_key_error] = self.error[_key_error].to_dict()\n            _dict['error'] = _field_dict\n        # override the default output from pydantic by calling `to_dict()` of each value in details (dict)\n        _field_dict = {}\n        if self.details:\n            for _key_details in self.details:\n                if self.details[_key_details]:\n                    _field_dict[_key_details] = self.details[_key_details].to_dict()\n            _dict['details'] = _field_dict\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if info (nullable) is None\n        # and model_fields_set contains the field\n        if self.info is None and \"info\" in self.model_fields_set:\n            _dict['info'] = None\n\n        # set to None if error (nullable) is None\n        # and model_fields_set contains the field\n        if self.error is None and \"error\" in self.model_fields_set:\n            _dict['error'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of HealthControllerCheck503Response from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"status\": obj.get(\"status\"),\n            \"info\": dict(\n                (_k, HealthControllerCheck200ResponseInfoValue.from_dict(_v))\n                for _k, _v in obj[\"info\"].items()\n            )\n            if obj.get(\"info\") is not None\n            else None,\n            \"error\": dict(\n                (_k, HealthControllerCheck200ResponseInfoValue.from_dict(_v))\n                for _k, _v in obj[\"error\"].items()\n            )\n            if obj.get(\"error\") is not None\n            else None,\n            \"details\": dict(\n                (_k, HealthControllerCheck200ResponseInfoValue.from_dict(_v))\n                for _k, _v in obj[\"details\"].items()\n            )\n            if obj.get(\"details\") is not None\n            else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/job.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom daytona_api_client.models.job_status import JobStatus\nfrom daytona_api_client.models.job_type import JobType\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass Job(BaseModel):\n    \"\"\"\n    Job\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"The ID of the job\")\n    type: JobType = Field(description=\"The type of the job\")\n    status: JobStatus = Field(description=\"The status of the job\")\n    resource_type: StrictStr = Field(description=\"The type of resource this job operates on\", serialization_alias=\"resourceType\")\n    resource_id: StrictStr = Field(description=\"The ID of the resource this job operates on (sandboxId, snapshotRef, etc.)\", serialization_alias=\"resourceId\")\n    payload: Optional[StrictStr] = Field(default=None, description=\"Job-specific JSON-encoded payload data (operational metadata)\")\n    trace_context: Optional[Dict[str, Any]] = Field(default=None, description=\"OpenTelemetry trace context for distributed tracing (W3C Trace Context format)\", serialization_alias=\"traceContext\")\n    error_message: Optional[StrictStr] = Field(default=None, description=\"Error message if the job failed\", serialization_alias=\"errorMessage\")\n    created_at: StrictStr = Field(description=\"The creation timestamp of the job\", serialization_alias=\"createdAt\")\n    updated_at: Optional[StrictStr] = Field(default=None, description=\"The last update timestamp of the job\", serialization_alias=\"updatedAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"type\", \"status\", \"resourceType\", \"resourceId\", \"payload\", \"traceContext\", \"errorMessage\", \"createdAt\", \"updatedAt\"]\n\n    @field_validator('resource_type')\n    def resource_type_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value not in set(['SANDBOX', 'SNAPSHOT', 'BACKUP']):\n            raise ValueError(\"must be one of enum values ('SANDBOX', 'SNAPSHOT', 'BACKUP')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of Job from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of Job from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"type\": obj.get(\"type\"),\n            \"status\": obj.get(\"status\"),\n            \"resource_type\": obj.get(\"resourceType\"),\n            \"resource_id\": obj.get(\"resourceId\"),\n            \"payload\": obj.get(\"payload\"),\n            \"trace_context\": obj.get(\"traceContext\"),\n            \"error_message\": obj.get(\"errorMessage\"),\n            \"created_at\": obj.get(\"createdAt\"),\n            \"updated_at\": obj.get(\"updatedAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/job_status.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport json\nfrom enum import Enum\nfrom typing_extensions import Self\n\n\nclass JobStatus(str, Enum):\n    \"\"\"\n    JobStatus\n    \"\"\"\n\n    \"\"\"\n    allowed enum values\n    \"\"\"\n    PENDING = 'PENDING'\n    IN_PROGRESS = 'IN_PROGRESS'\n    COMPLETED = 'COMPLETED'\n    FAILED = 'FAILED'\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Self:\n        \"\"\"Create an instance of JobStatus from a JSON string\"\"\"\n        return cls(json.loads(json_str))\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/job_type.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport json\nfrom enum import Enum\nfrom typing_extensions import Self\n\n\nclass JobType(str, Enum):\n    \"\"\"\n    The type of the job\n    \"\"\"\n\n    \"\"\"\n    allowed enum values\n    \"\"\"\n    CREATE_SANDBOX = 'CREATE_SANDBOX'\n    START_SANDBOX = 'START_SANDBOX'\n    STOP_SANDBOX = 'STOP_SANDBOX'\n    DESTROY_SANDBOX = 'DESTROY_SANDBOX'\n    RESIZE_SANDBOX = 'RESIZE_SANDBOX'\n    CREATE_BACKUP = 'CREATE_BACKUP'\n    BUILD_SNAPSHOT = 'BUILD_SNAPSHOT'\n    PULL_SNAPSHOT = 'PULL_SNAPSHOT'\n    RECOVER_SANDBOX = 'RECOVER_SANDBOX'\n    INSPECT_SNAPSHOT_IN_REGISTRY = 'INSPECT_SNAPSHOT_IN_REGISTRY'\n    REMOVE_SNAPSHOT = 'REMOVE_SNAPSHOT'\n    UPDATE_SANDBOX_NETWORK_SETTINGS = 'UPDATE_SANDBOX_NETWORK_SETTINGS'\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Self:\n        \"\"\"Create an instance of JobType from a JSON string\"\"\"\n        return cls(json.loads(json_str))\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/keyboard_hotkey_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass KeyboardHotkeyRequest(BaseModel):\n    \"\"\"\n    KeyboardHotkeyRequest\n    \"\"\" # noqa: E501\n    keys: StrictStr = Field(description=\"The hotkey combination to press (e.g., \\\"ctrl+c\\\", \\\"cmd+v\\\", \\\"alt+tab\\\")\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"keys\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of KeyboardHotkeyRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of KeyboardHotkeyRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"keys\": obj.get(\"keys\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/keyboard_press_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass KeyboardPressRequest(BaseModel):\n    \"\"\"\n    KeyboardPressRequest\n    \"\"\" # noqa: E501\n    key: StrictStr = Field(description=\"The key to press (e.g., a, b, c, enter, space, etc.)\")\n    modifiers: Optional[List[StrictStr]] = Field(default=None, description=\"Array of modifier keys to press along with the main key (ctrl, alt, shift, cmd)\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"key\", \"modifiers\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of KeyboardPressRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of KeyboardPressRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"key\": obj.get(\"key\"),\n            \"modifiers\": obj.get(\"modifiers\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/keyboard_type_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass KeyboardTypeRequest(BaseModel):\n    \"\"\"\n    KeyboardTypeRequest\n    \"\"\" # noqa: E501\n    text: StrictStr = Field(description=\"The text to type using the keyboard\")\n    delay: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"Delay in milliseconds between keystrokes. Defaults to 0\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"text\", \"delay\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of KeyboardTypeRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of KeyboardTypeRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"text\": obj.get(\"text\"),\n            \"delay\": obj.get(\"delay\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/list_branch_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ListBranchResponse(BaseModel):\n    \"\"\"\n    ListBranchResponse\n    \"\"\" # noqa: E501\n    branches: List[StrictStr]\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"branches\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ListBranchResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ListBranchResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"branches\": obj.get(\"branches\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/log_entry.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass LogEntry(BaseModel):\n    \"\"\"\n    LogEntry\n    \"\"\" # noqa: E501\n    timestamp: StrictStr = Field(description=\"Timestamp of the log entry\")\n    body: StrictStr = Field(description=\"Log message body\")\n    severity_text: StrictStr = Field(description=\"Severity level text (e.g., INFO, WARN, ERROR)\", serialization_alias=\"severityText\")\n    severity_number: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"Severity level number\", serialization_alias=\"severityNumber\")\n    service_name: StrictStr = Field(description=\"Service name that generated the log\", serialization_alias=\"serviceName\")\n    resource_attributes: Dict[str, StrictStr] = Field(description=\"Resource attributes from OTEL\", serialization_alias=\"resourceAttributes\")\n    log_attributes: Dict[str, StrictStr] = Field(description=\"Log-specific attributes\", serialization_alias=\"logAttributes\")\n    trace_id: Optional[StrictStr] = Field(default=None, description=\"Associated trace ID if available\", serialization_alias=\"traceId\")\n    span_id: Optional[StrictStr] = Field(default=None, description=\"Associated span ID if available\", serialization_alias=\"spanId\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"timestamp\", \"body\", \"severityText\", \"severityNumber\", \"serviceName\", \"resourceAttributes\", \"logAttributes\", \"traceId\", \"spanId\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of LogEntry from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of LogEntry from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"timestamp\": obj.get(\"timestamp\"),\n            \"body\": obj.get(\"body\"),\n            \"severity_text\": obj.get(\"severityText\"),\n            \"severity_number\": obj.get(\"severityNumber\"),\n            \"service_name\": obj.get(\"serviceName\"),\n            \"resource_attributes\": obj.get(\"resourceAttributes\"),\n            \"log_attributes\": obj.get(\"logAttributes\"),\n            \"trace_id\": obj.get(\"traceId\"),\n            \"span_id\": obj.get(\"spanId\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/lsp_completion_params.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom daytona_api_client.models.completion_context import CompletionContext\nfrom daytona_api_client.models.position import Position\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass LspCompletionParams(BaseModel):\n    \"\"\"\n    LspCompletionParams\n    \"\"\" # noqa: E501\n    language_id: StrictStr = Field(description=\"Language identifier\", serialization_alias=\"languageId\")\n    path_to_project: StrictStr = Field(description=\"Path to the project\", serialization_alias=\"pathToProject\")\n    uri: StrictStr = Field(description=\"Document URI\")\n    position: Position\n    context: Optional[CompletionContext] = None\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"languageId\", \"pathToProject\", \"uri\", \"position\", \"context\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of LspCompletionParams from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of position\n        if self.position:\n            _dict['position'] = self.position.to_dict()\n        # override the default output from pydantic by calling `to_dict()` of context\n        if self.context:\n            _dict['context'] = self.context.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of LspCompletionParams from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"language_id\": obj.get(\"languageId\"),\n            \"path_to_project\": obj.get(\"pathToProject\"),\n            \"uri\": obj.get(\"uri\"),\n            \"position\": Position.from_dict(obj[\"position\"]) if obj.get(\"position\") is not None else None,\n            \"context\": CompletionContext.from_dict(obj[\"context\"]) if obj.get(\"context\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/lsp_document_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass LspDocumentRequest(BaseModel):\n    \"\"\"\n    LspDocumentRequest\n    \"\"\" # noqa: E501\n    language_id: StrictStr = Field(description=\"Language identifier\", serialization_alias=\"languageId\")\n    path_to_project: StrictStr = Field(description=\"Path to the project\", serialization_alias=\"pathToProject\")\n    uri: StrictStr = Field(description=\"Document URI\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"languageId\", \"pathToProject\", \"uri\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of LspDocumentRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of LspDocumentRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"language_id\": obj.get(\"languageId\"),\n            \"path_to_project\": obj.get(\"pathToProject\"),\n            \"uri\": obj.get(\"uri\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/lsp_location.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.range import Range\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass LspLocation(BaseModel):\n    \"\"\"\n    LspLocation\n    \"\"\" # noqa: E501\n    range: Range\n    uri: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"range\", \"uri\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of LspLocation from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of range\n        if self.range:\n            _dict['range'] = self.range.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of LspLocation from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"range\": Range.from_dict(obj[\"range\"]) if obj.get(\"range\") is not None else None,\n            \"uri\": obj.get(\"uri\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/lsp_server_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass LspServerRequest(BaseModel):\n    \"\"\"\n    LspServerRequest\n    \"\"\" # noqa: E501\n    language_id: StrictStr = Field(description=\"Language identifier\", serialization_alias=\"languageId\")\n    path_to_project: StrictStr = Field(description=\"Path to the project\", serialization_alias=\"pathToProject\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"languageId\", \"pathToProject\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of LspServerRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of LspServerRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"language_id\": obj.get(\"languageId\"),\n            \"path_to_project\": obj.get(\"pathToProject\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/lsp_symbol.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom daytona_api_client.models.lsp_location import LspLocation\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass LspSymbol(BaseModel):\n    \"\"\"\n    LspSymbol\n    \"\"\" # noqa: E501\n    kind: Union[StrictFloat, StrictInt]\n    location: LspLocation\n    name: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"kind\", \"location\", \"name\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of LspSymbol from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of location\n        if self.location:\n            _dict['location'] = self.location.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of LspSymbol from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"kind\": obj.get(\"kind\"),\n            \"location\": LspLocation.from_dict(obj[\"location\"]) if obj.get(\"location\") is not None else None,\n            \"name\": obj.get(\"name\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/match.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass Match(BaseModel):\n    \"\"\"\n    Match\n    \"\"\" # noqa: E501\n    file: StrictStr\n    line: Union[StrictFloat, StrictInt]\n    content: StrictStr\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"file\", \"line\", \"content\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of Match from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of Match from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"file\": obj.get(\"file\"),\n            \"line\": obj.get(\"line\"),\n            \"content\": obj.get(\"content\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/metric_data_point.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MetricDataPoint(BaseModel):\n    \"\"\"\n    MetricDataPoint\n    \"\"\" # noqa: E501\n    timestamp: StrictStr = Field(description=\"Timestamp of the data point\")\n    value: Union[StrictFloat, StrictInt] = Field(description=\"Value at this timestamp\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"timestamp\", \"value\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MetricDataPoint from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MetricDataPoint from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"timestamp\": obj.get(\"timestamp\"),\n            \"value\": obj.get(\"value\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/metric_series.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.metric_data_point import MetricDataPoint\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MetricSeries(BaseModel):\n    \"\"\"\n    MetricSeries\n    \"\"\" # noqa: E501\n    metric_name: StrictStr = Field(description=\"Name of the metric\", serialization_alias=\"metricName\")\n    data_points: List[MetricDataPoint] = Field(description=\"Data points for this metric\", serialization_alias=\"dataPoints\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"metricName\", \"dataPoints\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MetricSeries from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in data_points (list)\n        _items = []\n        if self.data_points:\n            for _item_data_points in self.data_points:\n                if _item_data_points:\n                    _items.append(_item_data_points.to_dict())\n            _dict['dataPoints'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MetricSeries from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"metric_name\": obj.get(\"metricName\"),\n            \"data_points\": [MetricDataPoint.from_dict(_item) for _item in obj[\"dataPoints\"]] if obj.get(\"dataPoints\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/metrics_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.metric_series import MetricSeries\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MetricsResponse(BaseModel):\n    \"\"\"\n    MetricsResponse\n    \"\"\" # noqa: E501\n    series: List[MetricSeries] = Field(description=\"List of metric series\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"series\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MetricsResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in series (list)\n        _items = []\n        if self.series:\n            for _item_series in self.series:\n                if _item_series:\n                    _items.append(_item_series.to_dict())\n            _dict['series'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MetricsResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"series\": [MetricSeries.from_dict(_item) for _item in obj[\"series\"]] if obj.get(\"series\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_click_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MouseClickRequest(BaseModel):\n    \"\"\"\n    MouseClickRequest\n    \"\"\" # noqa: E501\n    x: Union[StrictFloat, StrictInt] = Field(description=\"The X coordinate where to perform the mouse click\")\n    y: Union[StrictFloat, StrictInt] = Field(description=\"The Y coordinate where to perform the mouse click\")\n    button: Optional[StrictStr] = Field(default=None, description=\"The mouse button to click (left, right, middle). Defaults to left\")\n    double: Optional[StrictBool] = Field(default=None, description=\"Whether to perform a double-click instead of a single click\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"x\", \"y\", \"button\", \"double\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MouseClickRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MouseClickRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"x\": obj.get(\"x\"),\n            \"y\": obj.get(\"y\"),\n            \"button\": obj.get(\"button\"),\n            \"double\": obj.get(\"double\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_click_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MouseClickResponse(BaseModel):\n    \"\"\"\n    MouseClickResponse\n    \"\"\" # noqa: E501\n    x: Union[StrictFloat, StrictInt] = Field(description=\"The actual X coordinate where the click occurred\")\n    y: Union[StrictFloat, StrictInt] = Field(description=\"The actual Y coordinate where the click occurred\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"x\", \"y\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MouseClickResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MouseClickResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"x\": obj.get(\"x\"),\n            \"y\": obj.get(\"y\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_drag_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MouseDragRequest(BaseModel):\n    \"\"\"\n    MouseDragRequest\n    \"\"\" # noqa: E501\n    start_x: Union[StrictFloat, StrictInt] = Field(description=\"The starting X coordinate for the drag operation\", serialization_alias=\"startX\")\n    start_y: Union[StrictFloat, StrictInt] = Field(description=\"The starting Y coordinate for the drag operation\", serialization_alias=\"startY\")\n    end_x: Union[StrictFloat, StrictInt] = Field(description=\"The ending X coordinate for the drag operation\", serialization_alias=\"endX\")\n    end_y: Union[StrictFloat, StrictInt] = Field(description=\"The ending Y coordinate for the drag operation\", serialization_alias=\"endY\")\n    button: Optional[StrictStr] = Field(default=None, description=\"The mouse button to use for dragging (left, right, middle). Defaults to left\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"startX\", \"startY\", \"endX\", \"endY\", \"button\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MouseDragRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MouseDragRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"start_x\": obj.get(\"startX\"),\n            \"start_y\": obj.get(\"startY\"),\n            \"end_x\": obj.get(\"endX\"),\n            \"end_y\": obj.get(\"endY\"),\n            \"button\": obj.get(\"button\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_drag_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MouseDragResponse(BaseModel):\n    \"\"\"\n    MouseDragResponse\n    \"\"\" # noqa: E501\n    x: Union[StrictFloat, StrictInt] = Field(description=\"The actual X coordinate where the drag ended\")\n    y: Union[StrictFloat, StrictInt] = Field(description=\"The actual Y coordinate where the drag ended\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"x\", \"y\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MouseDragResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MouseDragResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"x\": obj.get(\"x\"),\n            \"y\": obj.get(\"y\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_move_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MouseMoveRequest(BaseModel):\n    \"\"\"\n    MouseMoveRequest\n    \"\"\" # noqa: E501\n    x: Union[StrictFloat, StrictInt] = Field(description=\"The target X coordinate to move the mouse cursor to\")\n    y: Union[StrictFloat, StrictInt] = Field(description=\"The target Y coordinate to move the mouse cursor to\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"x\", \"y\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MouseMoveRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MouseMoveRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"x\": obj.get(\"x\"),\n            \"y\": obj.get(\"y\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_move_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MouseMoveResponse(BaseModel):\n    \"\"\"\n    MouseMoveResponse\n    \"\"\" # noqa: E501\n    x: Union[StrictFloat, StrictInt] = Field(description=\"The actual X coordinate where the mouse cursor ended up\")\n    y: Union[StrictFloat, StrictInt] = Field(description=\"The actual Y coordinate where the mouse cursor ended up\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"x\", \"y\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MouseMoveResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MouseMoveResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"x\": obj.get(\"x\"),\n            \"y\": obj.get(\"y\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_position.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MousePosition(BaseModel):\n    \"\"\"\n    MousePosition\n    \"\"\" # noqa: E501\n    x: Union[StrictFloat, StrictInt] = Field(description=\"The X coordinate of the mouse cursor position\")\n    y: Union[StrictFloat, StrictInt] = Field(description=\"The Y coordinate of the mouse cursor position\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"x\", \"y\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MousePosition from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MousePosition from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"x\": obj.get(\"x\"),\n            \"y\": obj.get(\"y\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_scroll_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MouseScrollRequest(BaseModel):\n    \"\"\"\n    MouseScrollRequest\n    \"\"\" # noqa: E501\n    x: Union[StrictFloat, StrictInt] = Field(description=\"The X coordinate where to perform the scroll operation\")\n    y: Union[StrictFloat, StrictInt] = Field(description=\"The Y coordinate where to perform the scroll operation\")\n    direction: StrictStr = Field(description=\"The scroll direction (up, down)\")\n    amount: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"The number of scroll units to scroll. Defaults to 1\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"x\", \"y\", \"direction\", \"amount\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MouseScrollRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MouseScrollRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"x\": obj.get(\"x\"),\n            \"y\": obj.get(\"y\"),\n            \"direction\": obj.get(\"direction\"),\n            \"amount\": obj.get(\"amount\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/mouse_scroll_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass MouseScrollResponse(BaseModel):\n    \"\"\"\n    MouseScrollResponse\n    \"\"\" # noqa: E501\n    success: StrictBool = Field(description=\"Whether the mouse scroll operation was successful\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"success\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of MouseScrollResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of MouseScrollResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"success\": obj.get(\"success\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/oidc_config.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass OidcConfig(BaseModel):\n    \"\"\"\n    OidcConfig\n    \"\"\" # noqa: E501\n    issuer: StrictStr = Field(description=\"OIDC issuer\")\n    client_id: StrictStr = Field(description=\"OIDC client ID\", serialization_alias=\"clientId\")\n    audience: StrictStr = Field(description=\"OIDC audience\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"issuer\", \"clientId\", \"audience\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of OidcConfig from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of OidcConfig from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"issuer\": obj.get(\"issuer\"),\n            \"client_id\": obj.get(\"clientId\"),\n            \"audience\": obj.get(\"audience\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/organization.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass Organization(BaseModel):\n    \"\"\"\n    Organization\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"Organization ID\")\n    name: StrictStr = Field(description=\"Organization name\")\n    created_by: StrictStr = Field(description=\"User ID of the organization creator\", serialization_alias=\"createdBy\")\n    personal: StrictBool = Field(description=\"Personal organization flag\")\n    created_at: datetime = Field(description=\"Creation timestamp\", serialization_alias=\"createdAt\")\n    updated_at: datetime = Field(description=\"Last update timestamp\", serialization_alias=\"updatedAt\")\n    suspended: StrictBool = Field(description=\"Suspended flag\")\n    suspended_at: datetime = Field(description=\"Suspended at\", serialization_alias=\"suspendedAt\")\n    suspension_reason: StrictStr = Field(description=\"Suspended reason\", serialization_alias=\"suspensionReason\")\n    suspended_until: datetime = Field(description=\"Suspended until\", serialization_alias=\"suspendedUntil\")\n    suspension_cleanup_grace_period_hours: Union[StrictFloat, StrictInt] = Field(description=\"Suspension cleanup grace period hours\", serialization_alias=\"suspensionCleanupGracePeriodHours\")\n    max_cpu_per_sandbox: Union[StrictFloat, StrictInt] = Field(description=\"Max CPU per sandbox\", serialization_alias=\"maxCpuPerSandbox\")\n    max_memory_per_sandbox: Union[StrictFloat, StrictInt] = Field(description=\"Max memory per sandbox\", serialization_alias=\"maxMemoryPerSandbox\")\n    max_disk_per_sandbox: Union[StrictFloat, StrictInt] = Field(description=\"Max disk per sandbox\", serialization_alias=\"maxDiskPerSandbox\")\n    snapshot_deactivation_timeout_minutes: Union[StrictFloat, StrictInt] = Field(description=\"Time in minutes before an unused snapshot is deactivated\", serialization_alias=\"snapshotDeactivationTimeoutMinutes\")\n    sandbox_limited_network_egress: StrictBool = Field(description=\"Sandbox default network block all\", serialization_alias=\"sandboxLimitedNetworkEgress\")\n    default_region_id: Optional[StrictStr] = Field(default=None, description=\"Default region ID\", serialization_alias=\"defaultRegionId\")\n    authenticated_rate_limit: Optional[Union[StrictFloat, StrictInt]] = Field(description=\"Authenticated rate limit per minute\", serialization_alias=\"authenticatedRateLimit\")\n    sandbox_create_rate_limit: Optional[Union[StrictFloat, StrictInt]] = Field(description=\"Sandbox create rate limit per minute\", serialization_alias=\"sandboxCreateRateLimit\")\n    sandbox_lifecycle_rate_limit: Optional[Union[StrictFloat, StrictInt]] = Field(description=\"Sandbox lifecycle rate limit per minute\", serialization_alias=\"sandboxLifecycleRateLimit\")\n    experimental_config: Dict[str, Any] = Field(description=\"Experimental configuration\", serialization_alias=\"experimentalConfig\")\n    authenticated_rate_limit_ttl_seconds: Optional[Union[StrictFloat, StrictInt]] = Field(description=\"Authenticated rate limit TTL in seconds\", serialization_alias=\"authenticatedRateLimitTtlSeconds\")\n    sandbox_create_rate_limit_ttl_seconds: Optional[Union[StrictFloat, StrictInt]] = Field(description=\"Sandbox create rate limit TTL in seconds\", serialization_alias=\"sandboxCreateRateLimitTtlSeconds\")\n    sandbox_lifecycle_rate_limit_ttl_seconds: Optional[Union[StrictFloat, StrictInt]] = Field(description=\"Sandbox lifecycle rate limit TTL in seconds\", serialization_alias=\"sandboxLifecycleRateLimitTtlSeconds\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"name\", \"createdBy\", \"personal\", \"createdAt\", \"updatedAt\", \"suspended\", \"suspendedAt\", \"suspensionReason\", \"suspendedUntil\", \"suspensionCleanupGracePeriodHours\", \"maxCpuPerSandbox\", \"maxMemoryPerSandbox\", \"maxDiskPerSandbox\", \"snapshotDeactivationTimeoutMinutes\", \"sandboxLimitedNetworkEgress\", \"defaultRegionId\", \"authenticatedRateLimit\", \"sandboxCreateRateLimit\", \"sandboxLifecycleRateLimit\", \"experimentalConfig\", \"authenticatedRateLimitTtlSeconds\", \"sandboxCreateRateLimitTtlSeconds\", \"sandboxLifecycleRateLimitTtlSeconds\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of Organization from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if authenticated_rate_limit (nullable) is None\n        # and model_fields_set contains the field\n        if self.authenticated_rate_limit is None and \"authenticated_rate_limit\" in self.model_fields_set:\n            _dict['authenticatedRateLimit'] = None\n\n        # set to None if sandbox_create_rate_limit (nullable) is None\n        # and model_fields_set contains the field\n        if self.sandbox_create_rate_limit is None and \"sandbox_create_rate_limit\" in self.model_fields_set:\n            _dict['sandboxCreateRateLimit'] = None\n\n        # set to None if sandbox_lifecycle_rate_limit (nullable) is None\n        # and model_fields_set contains the field\n        if self.sandbox_lifecycle_rate_limit is None and \"sandbox_lifecycle_rate_limit\" in self.model_fields_set:\n            _dict['sandboxLifecycleRateLimit'] = None\n\n        # set to None if authenticated_rate_limit_ttl_seconds (nullable) is None\n        # and model_fields_set contains the field\n        if self.authenticated_rate_limit_ttl_seconds is None and \"authenticated_rate_limit_ttl_seconds\" in self.model_fields_set:\n            _dict['authenticatedRateLimitTtlSeconds'] = None\n\n        # set to None if sandbox_create_rate_limit_ttl_seconds (nullable) is None\n        # and model_fields_set contains the field\n        if self.sandbox_create_rate_limit_ttl_seconds is None and \"sandbox_create_rate_limit_ttl_seconds\" in self.model_fields_set:\n            _dict['sandboxCreateRateLimitTtlSeconds'] = None\n\n        # set to None if sandbox_lifecycle_rate_limit_ttl_seconds (nullable) is None\n        # and model_fields_set contains the field\n        if self.sandbox_lifecycle_rate_limit_ttl_seconds is None and \"sandbox_lifecycle_rate_limit_ttl_seconds\" in self.model_fields_set:\n            _dict['sandboxLifecycleRateLimitTtlSeconds'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of Organization from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"name\": obj.get(\"name\"),\n            \"created_by\": obj.get(\"createdBy\"),\n            \"personal\": obj.get(\"personal\"),\n            \"created_at\": obj.get(\"createdAt\"),\n            \"updated_at\": obj.get(\"updatedAt\"),\n            \"suspended\": obj.get(\"suspended\"),\n            \"suspended_at\": obj.get(\"suspendedAt\"),\n            \"suspension_reason\": obj.get(\"suspensionReason\"),\n            \"suspended_until\": obj.get(\"suspendedUntil\"),\n            \"suspension_cleanup_grace_period_hours\": obj.get(\"suspensionCleanupGracePeriodHours\"),\n            \"max_cpu_per_sandbox\": obj.get(\"maxCpuPerSandbox\"),\n            \"max_memory_per_sandbox\": obj.get(\"maxMemoryPerSandbox\"),\n            \"max_disk_per_sandbox\": obj.get(\"maxDiskPerSandbox\"),\n            \"snapshot_deactivation_timeout_minutes\": obj.get(\"snapshotDeactivationTimeoutMinutes\") if obj.get(\"snapshotDeactivationTimeoutMinutes\") is not None else 20160,\n            \"sandbox_limited_network_egress\": obj.get(\"sandboxLimitedNetworkEgress\"),\n            \"default_region_id\": obj.get(\"defaultRegionId\"),\n            \"authenticated_rate_limit\": obj.get(\"authenticatedRateLimit\"),\n            \"sandbox_create_rate_limit\": obj.get(\"sandboxCreateRateLimit\"),\n            \"sandbox_lifecycle_rate_limit\": obj.get(\"sandboxLifecycleRateLimit\"),\n            \"experimental_config\": obj.get(\"experimentalConfig\"),\n            \"authenticated_rate_limit_ttl_seconds\": obj.get(\"authenticatedRateLimitTtlSeconds\"),\n            \"sandbox_create_rate_limit_ttl_seconds\": obj.get(\"sandboxCreateRateLimitTtlSeconds\"),\n            \"sandbox_lifecycle_rate_limit_ttl_seconds\": obj.get(\"sandboxLifecycleRateLimitTtlSeconds\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/organization_invitation.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.organization_role import OrganizationRole\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass OrganizationInvitation(BaseModel):\n    \"\"\"\n    OrganizationInvitation\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"Invitation ID\")\n    email: StrictStr = Field(description=\"Email address of the invitee\")\n    invited_by: StrictStr = Field(description=\"Email address of the inviter\", serialization_alias=\"invitedBy\")\n    organization_id: StrictStr = Field(description=\"Organization ID\", serialization_alias=\"organizationId\")\n    organization_name: StrictStr = Field(description=\"Organization name\", serialization_alias=\"organizationName\")\n    expires_at: datetime = Field(description=\"Expiration date of the invitation\", serialization_alias=\"expiresAt\")\n    status: StrictStr = Field(description=\"Invitation status\")\n    role: StrictStr = Field(description=\"Member role\")\n    assigned_roles: List[OrganizationRole] = Field(description=\"Assigned roles\", serialization_alias=\"assignedRoles\")\n    created_at: datetime = Field(description=\"Creation timestamp\", serialization_alias=\"createdAt\")\n    updated_at: datetime = Field(description=\"Last update timestamp\", serialization_alias=\"updatedAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"email\", \"invitedBy\", \"organizationId\", \"organizationName\", \"expiresAt\", \"status\", \"role\", \"assignedRoles\", \"createdAt\", \"updatedAt\"]\n\n    @field_validator('status')\n    def status_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value not in set(['pending', 'accepted', 'declined', 'cancelled']):\n            raise ValueError(\"must be one of enum values ('pending', 'accepted', 'declined', 'cancelled')\")\n        return value\n\n    @field_validator('role')\n    def role_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value not in set(['owner', 'member']):\n            raise ValueError(\"must be one of enum values ('owner', 'member')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationInvitation from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in assigned_roles (list)\n        _items = []\n        if self.assigned_roles:\n            for _item_assigned_roles in self.assigned_roles:\n                if _item_assigned_roles:\n                    _items.append(_item_assigned_roles.to_dict())\n            _dict['assignedRoles'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationInvitation from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"email\": obj.get(\"email\"),\n            \"invited_by\": obj.get(\"invitedBy\"),\n            \"organization_id\": obj.get(\"organizationId\"),\n            \"organization_name\": obj.get(\"organizationName\"),\n            \"expires_at\": obj.get(\"expiresAt\"),\n            \"status\": obj.get(\"status\"),\n            \"role\": obj.get(\"role\"),\n            \"assigned_roles\": [OrganizationRole.from_dict(_item) for _item in obj[\"assignedRoles\"]] if obj.get(\"assignedRoles\") is not None else None,\n            \"created_at\": obj.get(\"createdAt\"),\n            \"updated_at\": obj.get(\"updatedAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/organization_role.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass OrganizationRole(BaseModel):\n    \"\"\"\n    OrganizationRole\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"Role ID\")\n    name: StrictStr = Field(description=\"Role name\")\n    description: StrictStr = Field(description=\"Role description\")\n    permissions: List[StrictStr] = Field(description=\"Roles assigned to the user\")\n    is_global: StrictBool = Field(description=\"Global role flag\", serialization_alias=\"isGlobal\")\n    created_at: datetime = Field(description=\"Creation timestamp\", serialization_alias=\"createdAt\")\n    updated_at: datetime = Field(description=\"Last update timestamp\", serialization_alias=\"updatedAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"name\", \"description\", \"permissions\", \"isGlobal\", \"createdAt\", \"updatedAt\"]\n\n    @field_validator('permissions')\n    def permissions_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        for i in value:\n            if i not in set(['write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs']):\n                raise ValueError(\"each list item must be one of ('write:registries', 'delete:registries', 'write:snapshots', 'delete:snapshots', 'write:sandboxes', 'delete:sandboxes', 'read:volumes', 'write:volumes', 'delete:volumes', 'write:regions', 'delete:regions', 'read:runners', 'write:runners', 'delete:runners', 'read:audit_logs')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationRole from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationRole from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"name\": obj.get(\"name\"),\n            \"description\": obj.get(\"description\"),\n            \"permissions\": obj.get(\"permissions\"),\n            \"is_global\": obj.get(\"isGlobal\"),\n            \"created_at\": obj.get(\"createdAt\"),\n            \"updated_at\": obj.get(\"updatedAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/organization_sandbox_default_limited_network_egress.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass OrganizationSandboxDefaultLimitedNetworkEgress(BaseModel):\n    \"\"\"\n    OrganizationSandboxDefaultLimitedNetworkEgress\n    \"\"\" # noqa: E501\n    sandbox_default_limited_network_egress: StrictBool = Field(description=\"Sandbox default limited network egress\", serialization_alias=\"sandboxDefaultLimitedNetworkEgress\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"sandboxDefaultLimitedNetworkEgress\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationSandboxDefaultLimitedNetworkEgress from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationSandboxDefaultLimitedNetworkEgress from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"sandbox_default_limited_network_egress\": obj.get(\"sandboxDefaultLimitedNetworkEgress\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/organization_suspension.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing_extensions import Annotated\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass OrganizationSuspension(BaseModel):\n    \"\"\"\n    OrganizationSuspension\n    \"\"\" # noqa: E501\n    reason: StrictStr = Field(description=\"Suspension reason\")\n    until: datetime = Field(description=\"Suspension until\")\n    suspension_cleanup_grace_period_hours: Optional[Union[Annotated[float, Field(strict=True, ge=0)], Annotated[int, Field(strict=True, ge=0)]]] = Field(default=None, description=\"Suspension cleanup grace period hours\", serialization_alias=\"suspensionCleanupGracePeriodHours\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"reason\", \"until\", \"suspensionCleanupGracePeriodHours\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationSuspension from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationSuspension from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"reason\": obj.get(\"reason\"),\n            \"until\": obj.get(\"until\"),\n            \"suspension_cleanup_grace_period_hours\": obj.get(\"suspensionCleanupGracePeriodHours\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/organization_usage_overview.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom daytona_api_client.models.region_usage_overview import RegionUsageOverview\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass OrganizationUsageOverview(BaseModel):\n    \"\"\"\n    OrganizationUsageOverview\n    \"\"\" # noqa: E501\n    region_usage: List[RegionUsageOverview] = Field(serialization_alias=\"regionUsage\")\n    total_snapshot_quota: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalSnapshotQuota\")\n    current_snapshot_usage: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"currentSnapshotUsage\")\n    total_volume_quota: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalVolumeQuota\")\n    current_volume_usage: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"currentVolumeUsage\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"regionUsage\", \"totalSnapshotQuota\", \"currentSnapshotUsage\", \"totalVolumeQuota\", \"currentVolumeUsage\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationUsageOverview from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in region_usage (list)\n        _items = []\n        if self.region_usage:\n            for _item_region_usage in self.region_usage:\n                if _item_region_usage:\n                    _items.append(_item_region_usage.to_dict())\n            _dict['regionUsage'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationUsageOverview from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"region_usage\": [RegionUsageOverview.from_dict(_item) for _item in obj[\"regionUsage\"]] if obj.get(\"regionUsage\") is not None else None,\n            \"total_snapshot_quota\": obj.get(\"totalSnapshotQuota\"),\n            \"current_snapshot_usage\": obj.get(\"currentSnapshotUsage\"),\n            \"total_volume_quota\": obj.get(\"totalVolumeQuota\"),\n            \"current_volume_usage\": obj.get(\"currentVolumeUsage\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/organization_user.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom datetime import datetime\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.organization_role import OrganizationRole\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass OrganizationUser(BaseModel):\n    \"\"\"\n    OrganizationUser\n    \"\"\" # noqa: E501\n    user_id: StrictStr = Field(description=\"User ID\", serialization_alias=\"userId\")\n    organization_id: StrictStr = Field(description=\"Organization ID\", serialization_alias=\"organizationId\")\n    name: StrictStr = Field(description=\"User name\")\n    email: StrictStr = Field(description=\"User email\")\n    role: StrictStr = Field(description=\"Member role\")\n    assigned_roles: List[OrganizationRole] = Field(description=\"Roles assigned to the user\", serialization_alias=\"assignedRoles\")\n    created_at: datetime = Field(description=\"Creation timestamp\", serialization_alias=\"createdAt\")\n    updated_at: datetime = Field(description=\"Last update timestamp\", serialization_alias=\"updatedAt\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"userId\", \"organizationId\", \"name\", \"email\", \"role\", \"assignedRoles\", \"createdAt\", \"updatedAt\"]\n\n    @field_validator('role')\n    def role_validate_enum(cls, value):\n        \"\"\"Validates the enum\"\"\"\n        if value not in set(['owner', 'member']):\n            raise ValueError(\"must be one of enum values ('owner', 'member')\")\n        return value\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationUser from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in assigned_roles (list)\n        _items = []\n        if self.assigned_roles:\n            for _item_assigned_roles in self.assigned_roles:\n                if _item_assigned_roles:\n                    _items.append(_item_assigned_roles.to_dict())\n            _dict['assignedRoles'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of OrganizationUser from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"user_id\": obj.get(\"userId\"),\n            \"organization_id\": obj.get(\"organizationId\"),\n            \"name\": obj.get(\"name\"),\n            \"email\": obj.get(\"email\"),\n            \"role\": obj.get(\"role\"),\n            \"assigned_roles\": [OrganizationRole.from_dict(_item) for _item in obj[\"assignedRoles\"]] if obj.get(\"assignedRoles\") is not None else None,\n            \"created_at\": obj.get(\"createdAt\"),\n            \"updated_at\": obj.get(\"updatedAt\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/otel_config.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass OtelConfig(BaseModel):\n    \"\"\"\n    OtelConfig\n    \"\"\" # noqa: E501\n    endpoint: StrictStr = Field(description=\"Endpoint\")\n    headers: Optional[Dict[str, StrictStr]] = Field(default=None, description=\"Headers\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"endpoint\", \"headers\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of OtelConfig from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        # set to None if headers (nullable) is None\n        # and model_fields_set contains the field\n        if self.headers is None and \"headers\" in self.model_fields_set:\n            _dict['headers'] = None\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of OtelConfig from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"endpoint\": obj.get(\"endpoint\"),\n            \"headers\": obj.get(\"headers\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/paginated_audit_logs.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom daytona_api_client.models.audit_log import AuditLog\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PaginatedAuditLogs(BaseModel):\n    \"\"\"\n    PaginatedAuditLogs\n    \"\"\" # noqa: E501\n    items: List[AuditLog]\n    total: Union[StrictFloat, StrictInt]\n    page: Union[StrictFloat, StrictInt]\n    total_pages: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalPages\")\n    next_token: Optional[StrictStr] = Field(default=None, description=\"Token for next page in cursor-based pagination\", serialization_alias=\"nextToken\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"items\", \"total\", \"page\", \"totalPages\", \"nextToken\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedAuditLogs from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in items (list)\n        _items = []\n        if self.items:\n            for _item_items in self.items:\n                if _item_items:\n                    _items.append(_item_items.to_dict())\n            _dict['items'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedAuditLogs from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"items\": [AuditLog.from_dict(_item) for _item in obj[\"items\"]] if obj.get(\"items\") is not None else None,\n            \"total\": obj.get(\"total\"),\n            \"page\": obj.get(\"page\"),\n            \"total_pages\": obj.get(\"totalPages\"),\n            \"next_token\": obj.get(\"nextToken\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/paginated_jobs.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom daytona_api_client.models.job import Job\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PaginatedJobs(BaseModel):\n    \"\"\"\n    PaginatedJobs\n    \"\"\" # noqa: E501\n    items: List[Job]\n    total: Union[StrictFloat, StrictInt]\n    page: Union[StrictFloat, StrictInt]\n    total_pages: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalPages\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"items\", \"total\", \"page\", \"totalPages\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedJobs from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in items (list)\n        _items = []\n        if self.items:\n            for _item_items in self.items:\n                if _item_items:\n                    _items.append(_item_items.to_dict())\n            _dict['items'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedJobs from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"items\": [Job.from_dict(_item) for _item in obj[\"items\"]] if obj.get(\"items\") is not None else None,\n            \"total\": obj.get(\"total\"),\n            \"page\": obj.get(\"page\"),\n            \"total_pages\": obj.get(\"totalPages\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/paginated_logs.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom daytona_api_client.models.log_entry import LogEntry\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PaginatedLogs(BaseModel):\n    \"\"\"\n    PaginatedLogs\n    \"\"\" # noqa: E501\n    items: List[LogEntry] = Field(description=\"List of log entries\")\n    total: Union[StrictFloat, StrictInt] = Field(description=\"Total number of log entries matching the query\")\n    page: Union[StrictFloat, StrictInt] = Field(description=\"Current page number\")\n    total_pages: Union[StrictFloat, StrictInt] = Field(description=\"Total number of pages\", serialization_alias=\"totalPages\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"items\", \"total\", \"page\", \"totalPages\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedLogs from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in items (list)\n        _items = []\n        if self.items:\n            for _item_items in self.items:\n                if _item_items:\n                    _items.append(_item_items.to_dict())\n            _dict['items'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedLogs from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"items\": [LogEntry.from_dict(_item) for _item in obj[\"items\"]] if obj.get(\"items\") is not None else None,\n            \"total\": obj.get(\"total\"),\n            \"page\": obj.get(\"page\"),\n            \"total_pages\": obj.get(\"totalPages\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/paginated_sandboxes.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom daytona_api_client.models.sandbox import Sandbox\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PaginatedSandboxes(BaseModel):\n    \"\"\"\n    PaginatedSandboxes\n    \"\"\" # noqa: E501\n    items: List[Sandbox]\n    total: Union[StrictFloat, StrictInt]\n    page: Union[StrictFloat, StrictInt]\n    total_pages: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalPages\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"items\", \"total\", \"page\", \"totalPages\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedSandboxes from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in items (list)\n        _items = []\n        if self.items:\n            for _item_items in self.items:\n                if _item_items:\n                    _items.append(_item_items.to_dict())\n            _dict['items'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedSandboxes from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"items\": [Sandbox.from_dict(_item) for _item in obj[\"items\"]] if obj.get(\"items\") is not None else None,\n            \"total\": obj.get(\"total\"),\n            \"page\": obj.get(\"page\"),\n            \"total_pages\": obj.get(\"totalPages\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/paginated_snapshots.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom daytona_api_client.models.snapshot_dto import SnapshotDto\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PaginatedSnapshots(BaseModel):\n    \"\"\"\n    PaginatedSnapshots\n    \"\"\" # noqa: E501\n    items: List[SnapshotDto]\n    total: Union[StrictFloat, StrictInt]\n    page: Union[StrictFloat, StrictInt]\n    total_pages: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalPages\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"items\", \"total\", \"page\", \"totalPages\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedSnapshots from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in items (list)\n        _items = []\n        if self.items:\n            for _item_items in self.items:\n                if _item_items:\n                    _items.append(_item_items.to_dict())\n            _dict['items'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedSnapshots from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"items\": [SnapshotDto.from_dict(_item) for _item in obj[\"items\"]] if obj.get(\"items\") is not None else None,\n            \"total\": obj.get(\"total\"),\n            \"page\": obj.get(\"page\"),\n            \"total_pages\": obj.get(\"totalPages\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/paginated_traces.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom daytona_api_client.models.trace_summary import TraceSummary\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PaginatedTraces(BaseModel):\n    \"\"\"\n    PaginatedTraces\n    \"\"\" # noqa: E501\n    items: List[TraceSummary] = Field(description=\"List of trace summaries\")\n    total: Union[StrictFloat, StrictInt] = Field(description=\"Total number of traces matching the query\")\n    page: Union[StrictFloat, StrictInt] = Field(description=\"Current page number\")\n    total_pages: Union[StrictFloat, StrictInt] = Field(description=\"Total number of pages\", serialization_alias=\"totalPages\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"items\", \"total\", \"page\", \"totalPages\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedTraces from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in items (list)\n        _items = []\n        if self.items:\n            for _item_items in self.items:\n                if _item_items:\n                    _items.append(_item_items.to_dict())\n            _dict['items'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PaginatedTraces from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"items\": [TraceSummary.from_dict(_item) for _item in obj[\"items\"]] if obj.get(\"items\") is not None else None,\n            \"total\": obj.get(\"total\"),\n            \"page\": obj.get(\"page\"),\n            \"total_pages\": obj.get(\"totalPages\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/poll_jobs_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.job import Job\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PollJobsResponse(BaseModel):\n    \"\"\"\n    PollJobsResponse\n    \"\"\" # noqa: E501\n    jobs: List[Job] = Field(description=\"List of jobs\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"jobs\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PollJobsResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in jobs (list)\n        _items = []\n        if self.jobs:\n            for _item_jobs in self.jobs:\n                if _item_jobs:\n                    _items.append(_item_jobs.to_dict())\n            _dict['jobs'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PollJobsResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"jobs\": [Job.from_dict(_item) for _item in obj[\"jobs\"]] if obj.get(\"jobs\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/port_preview_url.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PortPreviewUrl(BaseModel):\n    \"\"\"\n    PortPreviewUrl\n    \"\"\" # noqa: E501\n    sandbox_id: StrictStr = Field(description=\"ID of the sandbox\", serialization_alias=\"sandboxId\")\n    url: StrictStr = Field(description=\"Preview url\")\n    token: StrictStr = Field(description=\"Access token\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"sandboxId\", \"url\", \"token\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PortPreviewUrl from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PortPreviewUrl from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"sandbox_id\": obj.get(\"sandboxId\"),\n            \"url\": obj.get(\"url\"),\n            \"token\": obj.get(\"token\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/position.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass Position(BaseModel):\n    \"\"\"\n    Position\n    \"\"\" # noqa: E501\n    line: Union[StrictFloat, StrictInt]\n    character: Union[StrictFloat, StrictInt]\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"line\", \"character\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of Position from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of Position from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"line\": obj.get(\"line\"),\n            \"character\": obj.get(\"character\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/posthog_config.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PosthogConfig(BaseModel):\n    \"\"\"\n    PosthogConfig\n    \"\"\" # noqa: E501\n    api_key: StrictStr = Field(description=\"PostHog API key\", serialization_alias=\"apiKey\")\n    host: StrictStr = Field(description=\"PostHog host URL\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"apiKey\", \"host\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PosthogConfig from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PosthogConfig from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"api_key\": obj.get(\"apiKey\"),\n            \"host\": obj.get(\"host\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/process_errors_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ProcessErrorsResponse(BaseModel):\n    \"\"\"\n    ProcessErrorsResponse\n    \"\"\" # noqa: E501\n    process_name: StrictStr = Field(description=\"The name of the VNC process whose error logs were retrieved\", serialization_alias=\"processName\")\n    errors: StrictStr = Field(description=\"The error log output from the specified VNC process\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"processName\", \"errors\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ProcessErrorsResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ProcessErrorsResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"process_name\": obj.get(\"processName\"),\n            \"errors\": obj.get(\"errors\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/process_logs_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ProcessLogsResponse(BaseModel):\n    \"\"\"\n    ProcessLogsResponse\n    \"\"\" # noqa: E501\n    process_name: StrictStr = Field(description=\"The name of the VNC process whose logs were retrieved\", serialization_alias=\"processName\")\n    logs: StrictStr = Field(description=\"The log output from the specified VNC process\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"processName\", \"logs\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ProcessLogsResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ProcessLogsResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"process_name\": obj.get(\"processName\"),\n            \"logs\": obj.get(\"logs\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/process_status_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr\nfrom typing import Any, ClassVar, Dict, List\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass ProcessStatusResponse(BaseModel):\n    \"\"\"\n    ProcessStatusResponse\n    \"\"\" # noqa: E501\n    process_name: StrictStr = Field(description=\"The name of the VNC process being checked\", serialization_alias=\"processName\")\n    running: StrictBool = Field(description=\"Whether the specified VNC process is currently running\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"processName\", \"running\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of ProcessStatusResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of ProcessStatusResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"process_name\": obj.get(\"processName\"),\n            \"running\": obj.get(\"running\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/pty_list_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.pty_session_info import PtySessionInfo\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PtyListResponse(BaseModel):\n    \"\"\"\n    PtyListResponse\n    \"\"\" # noqa: E501\n    sessions: List[PtySessionInfo] = Field(description=\"List of active PTY sessions\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"sessions\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PtyListResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of each item in sessions (list)\n        _items = []\n        if self.sessions:\n            for _item_sessions in self.sessions:\n                if _item_sessions:\n                    _items.append(_item_sessions.to_dict())\n            _dict['sessions'] = _items\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PtyListResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"sessions\": [PtySessionInfo.from_dict(_item) for _item in obj[\"sessions\"]] if obj.get(\"sessions\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/pty_resize_request.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PtyResizeRequest(BaseModel):\n    \"\"\"\n    PtyResizeRequest\n    \"\"\" # noqa: E501\n    cols: Union[StrictFloat, StrictInt] = Field(description=\"Number of terminal columns\")\n    rows: Union[StrictFloat, StrictInt] = Field(description=\"Number of terminal rows\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"cols\", \"rows\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PtyResizeRequest from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PtyResizeRequest from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"cols\": obj.get(\"cols\"),\n            \"rows\": obj.get(\"rows\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/pty_session_info.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass PtySessionInfo(BaseModel):\n    \"\"\"\n    PtySessionInfo\n    \"\"\" # noqa: E501\n    id: StrictStr = Field(description=\"The unique identifier for the PTY session\")\n    cwd: StrictStr = Field(description=\"Starting directory for the PTY session, defaults to the sandbox's working directory\")\n    envs: Dict[str, Any] = Field(description=\"Environment variables for the PTY session\")\n    cols: Union[StrictFloat, StrictInt] = Field(description=\"Number of terminal columns\")\n    rows: Union[StrictFloat, StrictInt] = Field(description=\"Number of terminal rows\")\n    created_at: StrictStr = Field(description=\"When the PTY session was created\", serialization_alias=\"createdAt\")\n    active: StrictBool = Field(description=\"Whether the PTY session is currently active\")\n    lazy_start: StrictBool = Field(description=\"Whether the PTY session uses lazy start (only start when first client connects)\", serialization_alias=\"lazyStart\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"id\", \"cwd\", \"envs\", \"cols\", \"rows\", \"createdAt\", \"active\", \"lazyStart\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of PtySessionInfo from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of PtySessionInfo from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"id\": obj.get(\"id\"),\n            \"cwd\": obj.get(\"cwd\"),\n            \"envs\": obj.get(\"envs\"),\n            \"cols\": obj.get(\"cols\"),\n            \"rows\": obj.get(\"rows\"),\n            \"created_at\": obj.get(\"createdAt\"),\n            \"active\": obj.get(\"active\"),\n            \"lazy_start\": obj.get(\"lazyStart\") if obj.get(\"lazyStart\") is not None else False\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/range.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict\nfrom typing import Any, ClassVar, Dict, List\nfrom daytona_api_client.models.position import Position\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass Range(BaseModel):\n    \"\"\"\n    Range\n    \"\"\" # noqa: E501\n    start: Position\n    end: Position\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"start\", \"end\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of Range from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # override the default output from pydantic by calling `to_dict()` of start\n        if self.start:\n            _dict['start'] = self.start.to_dict()\n        # override the default output from pydantic by calling `to_dict()` of end\n        if self.end:\n            _dict['end'] = self.end.to_dict()\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of Range from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"start\": Position.from_dict(obj[\"start\"]) if obj.get(\"start\") is not None else None,\n            \"end\": Position.from_dict(obj[\"end\"]) if obj.get(\"end\") is not None else None\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/region_quota.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass RegionQuota(BaseModel):\n    \"\"\"\n    RegionQuota\n    \"\"\" # noqa: E501\n    organization_id: StrictStr = Field(serialization_alias=\"organizationId\")\n    region_id: StrictStr = Field(serialization_alias=\"regionId\")\n    total_cpu_quota: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalCpuQuota\")\n    total_memory_quota: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalMemoryQuota\")\n    total_disk_quota: Union[StrictFloat, StrictInt] = Field(serialization_alias=\"totalDiskQuota\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"organizationId\", \"regionId\", \"totalCpuQuota\", \"totalMemoryQuota\", \"totalDiskQuota\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of RegionQuota from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of RegionQuota from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"organization_id\": obj.get(\"organizationId\"),\n            \"region_id\": obj.get(\"regionId\"),\n            \"total_cpu_quota\": obj.get(\"totalCpuQuota\"),\n            \"total_memory_quota\": obj.get(\"totalMemoryQuota\"),\n            \"total_disk_quota\": obj.get(\"totalDiskQuota\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/models/region_screenshot_response.py",
    "content": "# coding: utf-8\n\n\"\"\"\n    Daytona\n\n    Daytona AI platform API Docs\n\n    The version of the OpenAPI document: 1.0\n    Contact: support@daytona.com\n    Generated by OpenAPI Generator (https://openapi-generator.tech)\n\n    Do not edit the class manually.\n\"\"\"  # noqa: E501\n\n\nfrom __future__ import annotations\nimport pprint\nimport re  # noqa: F401\nimport json\n\nfrom pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr\nfrom typing import Any, ClassVar, Dict, List, Optional, Union\nfrom typing import Optional, Set\nfrom typing_extensions import Self\n\nclass RegionScreenshotResponse(BaseModel):\n    \"\"\"\n    RegionScreenshotResponse\n    \"\"\" # noqa: E501\n    screenshot: StrictStr = Field(description=\"Base64 encoded screenshot image data of the specified region\")\n    cursor_position: Optional[Dict[str, Any]] = Field(default=None, description=\"The current cursor position when the region screenshot was taken\", serialization_alias=\"cursorPosition\")\n    size_bytes: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description=\"The size of the screenshot data in bytes\", serialization_alias=\"sizeBytes\")\n    additional_properties: Dict[str, Any] = {}\n    __properties: ClassVar[List[str]] = [\"screenshot\", \"cursorPosition\", \"sizeBytes\"]\n\n    model_config = ConfigDict(\n        populate_by_name=True,\n        validate_assignment=True,\n        protected_namespaces=(),\n    )\n\n\n    def to_str(self) -> str:\n        \"\"\"Returns the string representation of the model using alias\"\"\"\n        return pprint.pformat(self.model_dump(by_alias=True))\n\n    def to_json(self) -> str:\n        \"\"\"Returns the JSON representation of the model using alias\"\"\"\n        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead\n        return json.dumps(self.to_dict())\n\n    @classmethod\n    def from_json(cls, json_str: str) -> Optional[Self]:\n        \"\"\"Create an instance of RegionScreenshotResponse from a JSON string\"\"\"\n        return cls.from_dict(json.loads(json_str))\n\n    def to_dict(self) -> Dict[str, Any]:\n        \"\"\"Return the dictionary representation of the model using alias.\n\n        This has the following differences from calling pydantic's\n        `self.model_dump(by_alias=True)`:\n\n        * `None` is only added to the output dict for nullable fields that\n          were set at model initialization. Other fields with value `None`\n          are ignored.\n        * Fields in `self.additional_properties` are added to the output dict.\n        \"\"\"\n        excluded_fields: Set[str] = set([\n            \"additional_properties\",\n        ])\n\n        _dict = self.model_dump(\n            by_alias=True,\n            exclude=excluded_fields,\n            exclude_none=True,\n        )\n        # puts key-value pairs in additional_properties in the top level\n        if self.additional_properties is not None:\n            for _key, _value in self.additional_properties.items():\n                _dict[_key] = _value\n\n        return _dict\n\n    @classmethod\n    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:\n        \"\"\"Create an instance of RegionScreenshotResponse from a dict\"\"\"\n        if obj is None:\n            return None\n\n        if not isinstance(obj, dict):\n            return cls.model_validate(obj)\n\n        _obj = cls.model_validate({\n            \"screenshot\": obj.get(\"screenshot\"),\n            \"cursor_position\": obj.get(\"cursorPosition\"),\n            \"size_bytes\": obj.get(\"sizeBytes\")\n        })\n        # store additional fields in additional_properties\n        for _key in obj.keys():\n            if _key not in cls.__properties:\n                _obj.additional_properties[_key] = obj.get(_key)\n\n        return _obj\n\n\n"
  },
  {
    "path": "libs/api-client-python/daytona_api_client/py.typed",
    "content": ""
  },
  {
    "path": "libs/api-client-python-async/README.md",
    "content": ""
  },
  {
    "path": "libs/api-client-python-async/daytona_api_client_async/py.typed",
    "content": ""
  },
  {
    "path": "libs/sdk-python/src/daytona/py.typed",
    "content": ""
  },
  {
    "path": "libs/toolbox-api-client-python/daytona_toolbox_api_client/py.typed",
    "content": ""
  },
  {
    "path": "libs/toolbox-api-client-python-async/README.md",
    "content": ""
  },
  {
    "path": "libs/toolbox-api-client-python-async/daytona_toolbox_api_client_async/py.typed",
    "content": ""
  }
]